Plugins
Everything you see in Greed comes from these plugins, each a folder of Luau you can read, change or replace. Unload one with greed.plugin.unload(name) in your config.
acp
Agents in Greed over the Agent Client Protocol: Claude Code, Gemini, Codex or any agent that speaks ACP, each in a transcript buffer you write to and read from, working in the project or in a workspace of its own.
space i n start an agent: pick which, and where it works
space i l the sessions, running and kept: show, take up, review or bring them in
space i m move this session's transcript to a pane, tab, float or panel
In a transcript, alt-enter sends what’s in the box at the bottom and ctrl-c stops the agent’s turn. A question the agent asks shows as a row of choices in the box, answered with enter or a choice’s letter in any mode (question.luau).
Agents are registered by name with the commands that run them; the first one installed is used. Add your own in init.luau:
require("@acp").register({ name = "mine", commands = { { "my-agent", "--acp" } } })
Uses: core, picker, statusline, vcs, agent, models, panes, markdown.
| Command | Keys | What it does |
|---|---|---|
agent | Show the latest agent session, or start one when none runs | |
agent-answer | alt-q (in agent-transcript buffers), enter (every style’s command mode; in agent-transcript buffers) | Show the question the agent waits on in the box, to answer it there; on a button, like a code block’s run, press it |
agent-choice-click | Answer the agent’s question with the choice under the cursor | |
agent-choice-hide | Hide the agent’s question from the box; it still waits in the transcript | |
agent-choice-key | Answer the agent’s question with the choice of the key pressed | |
agent-choice-next | Highlight the next choice of the agent’s question | |
agent-choice-pick | Answer the agent’s question with the highlighted choice | |
agent-choice-prev | Highlight the previous choice of the agent’s question | |
agent-code-copy | Copy the shell code block at the cursor | |
agent-code-prompt | Put the shell code block at the cursor at this project’s shell’s prompt, to look over before running it | |
agent-code-run | Run the shell code block at the cursor in this project’s shell, as a block there; one that destroys something asks first | |
agent-compact | Compact the conversation with Greed’s own agent: the model summarises all but the last few turns | |
agent-drop-images | alt-x (in agent-transcript buffers) | Drop the images pasted for your next message to the agent |
agent-fold | tab (every style’s command mode; in agent-transcript buffers) | Show all of the output of the tool call under the cursor, or fold it again |
agent-fork | f (in agents buffers) | Fork the agent: a new session that starts with everything said so far |
agent-list | esc, q (in agents buffers), i l (after the leader) | List the agent sessions, running and kept, to show, take up, move, review or close them |
agent-mode | alt-m (in agent-transcript buffers) | Pick the mode the agent works in, like plan or accept edits |
agent-model | alt-M (in agent-transcript buffers) | Pick the model the agent uses, from those it offers |
agent-move | i m (after the leader) | Move the session’s transcript to a pane, a tab, a float or a panel: the next key says which |
agent-new | n (in agents buffers), i n (after the leader) | Start an agent: Greed’s own, or Claude Code, Gemini or Codex over ACP; pick which, and where it works |
agent-resume | The same as agent-list | |
agent-send | alt-enter (in agent-transcript buffers) | Send what’s in the transcript’s box to its agent |
agent-show-float | w (in agents buffers) | Show the session (the transcript’s, or those chosen in the list) in a floating view |
agent-show-pane | p (in agents buffers) | Show the session (the transcript’s, or those chosen in the list) in a pane of the tab |
agent-show-panel | s (in agents buffers) | Show the session (the transcript’s, or those chosen in the list) in a panel on the right |
agent-show-tab | t (in agents buffers) | Show the session (the transcript’s, or those chosen in the list) in a tab of its own |
agent-stop | ctrl-c (every style’s command mode; in agents, agent-transcript buffers) | Stop the agent’s turn |
agents | The same as agent-list | |
agents-bring | b (in agents buffers) | Bring what the agent under the cursor changed into your working copy |
agents-close | x (in agents buffers) | Close the sessions marked in the list, or the one under the cursor: stop and forget them and remove their workspaces, asking first for those running or with a workspace |
agents-diff | d (in agents buffers) | Show what the agent under the cursor changed in its workspace |
agents-filter | / (in agents buffers) | Narrow the list to the sessions with the text typed |
agents-mark | m (in agents buffers) | Mark the session under the cursor in the list, or unmark it, to act on several |
agents-resume | r (in agents buffers) | Take up the sessions marked in the list, or the one under the cursor, without showing them |
agents-resume-here | h (in agents buffers) | Take up Greed’s own sessions marked in the list, or the one under the cursor, in this workspace |
agents-review | R (in agents buffers) | Review what the agent under the cursor changed as proposals on your files |
agents-show | enter (in agents buffers) | Show the sessions marked in the list, or the one under the cursor, taking them up if they’re kept |
| Option | Default | What it does |
|---|---|---|
agent-editor-context | true | Send agents the file you’re in, the cursor, the selection and the other files on screen with each message |
agent-greed-tools | true | Give agents Greed’s own tools (buffers, diagnostics, syntax queries, proposals) through greed mcp |
agent-sessions-kept | 50 | How many sessions with Greed’s own agent are kept per repository to take up again; older ones are deleted |
agent-workspace-edits | true | Let agents in a workspace of their own edit, move and delete files there without asking |
agent
Lets agents and scripts use the editor: greed ctl from a shell, and MCP
clients like Claude Code through greed mcp.
Requests come in on the session socket. registry.luau answers MCP’s
methods (initialize, tools/list, tools/call), so the tools are the same
for an agent and for greed ctl TOOL. Add your own with
require("@agent").tool { ... }; tools.luau has the built-in ones, and
proposals.luau the review of edits agents propose.
Uses: core, picker, terminal, operations, approvals, describe, markdown, models.
| Command | Keys | What it does |
|---|---|---|
ask-cancel | Answer none of these questions, telling the agent you didn’t | |
ask-enter | On a page of questions: pick the choice under the cursor and go on to the next question, start typing an answer, or go on; on the last line, send | |
ask-send | Send your answers to the agent that asked these questions | |
claude | i C (after the leader) | Go to the Claude Code pane, or open one |
eval-allow-session | Let the agent’s code run, and every run until the editor quits | |
eval-deny | Don’t let the agent’s code run | |
eval-log | Show each run of an agent’s code past the sandbox, with who let it | |
eval-run | Let the agent’s code run, this once | |
ide-mention | o m (after the leader) | Mention the selected lines to Claude Code, like @file#L1-5 |
memory-edit | Open your personal memories: standing preferences agents follow | |
memory-edit-project | Open your private memories of this project, the same in all its workspaces | |
memory-edit-shared | Open this project’s shared memories, .greed/memory.md in the repository | |
plugin-review-accept | a (in plugin-review buffers) | Install, approve and load the plugin under review |
plugin-review-reject | esc, q, r (in plugin-review buffers) | Reject the plugin under review |
proposal-accept | o a (after the leader) | Accept the proposed changes your selections touch |
proposal-accept-all | o A (after the leader) | Accept every proposed change in this file |
proposal-compare | o d (after the leader) | Show the file with its proposed changes in, side by side |
proposal-next | ] o (every style’s command mode) | Select the next proposed change |
proposal-note | o n (after the leader) | Reject the proposed changes your selections touch, telling the agent what to do instead |
proposal-prev | [ o (every style’s command mode) | Select the previous proposed change |
proposal-reject | o r (after the leader) | Reject the proposed changes your selections touch |
proposal-reject-all | o R (after the leader) | Reject every proposed change in this file |
proposals | o o (after the leader) | Pick a proposed change to review |
repo-map | Show the repo map agents get: the functions and types that matter most, ranked toward the open files | |
working-set | Show the files you’ve been working in lately, the way agents see them |
| Option | Default | What it does |
|---|---|---|
agent-eval | "auto" | How Luau from agents runs: “auto” (sandboxed, a reviewer or you for more), “ask”, “allow” or “off” |
agent-tool-groups | "plan" | The tool groups agents get from the start, besides those they switch on: names with spaces between, or “all” |
claude-command | "claude" | How the Claude pane starts Claude Code, e.g. “claude –continue” |
web-search | "" | The search service agents search the web with: “brave”, “exa”, “tavily” or “searxng”; empty for none |
web-search-url | "" | Where your SearXNG is, for web-search searxng |
approvals
Approving plugins. A plugin that isn’t one of Greed’s own and declares capabilities (running programs, files by path, the network, …) waits until you approve them, and again if it later asks for more.
:plugins-approve review the waiting plugins and approve one
:plugins every plugin, where it comes from and what it may use
:plugin-reload NAME load a plugin again from its folder
Uses: core, picker.
| Command | Keys | What it does |
|---|---|---|
plugin-reload | Load a plugin again from its folder, as after changing its code | |
plugins | List the plugins, where each comes from and what it may use; enter opens one | |
plugins-approve | Review the plugins waiting for approval of what they use, and approve one |
assist
Commands that ask a language model, in the roles :models shows, with what you pinned to the context (space i p, see the context plugin):
space i e explain the selection, in a panel as the answer arrives
space i a ask something about the selection
space i f fix the problem under the cursor, as changes to review
space i c draft a description of the changes in progress
Fixes come as proposed changes (] o, space o a, space o r), which undo as one operation. In the description buffer, a applies it (jj describe, or a git commit of what’s staged).
Uses: core, models, agent, vcs, context.
| Command | Keys | What it does |
|---|---|---|
ask-about | i a (after the leader) | Ask a language model something about the selection (or the line) |
assist-close | q (in answer, commit-message buffers) | Close the answer panel |
commit-message | i c (after the leader) | Draft a description of the changes in progress, from their diff |
commit-message-apply | a (in commit-message buffers) | Use the drafted description: jj describe, or a git commit of what’s staged |
explain | i e (after the leader) | Explain the selection (or the line), in a panel as the answer arrives |
fix | i f (after the leader) | Ask a language model to fix the problem under the cursor, as changes to review |
| Option | Default | What it does |
|---|---|---|
assist-role | "fast" | The model role assist’s commands ask; see :models |
blocks
Runnable blocks in Markdown: a fenced block whose language has a runner
(```sh, ```python, ```luau, ```http)
runs when you ask, and its output is saved in a result block right
under it, so the file shows it anywhere and a diff shows what changed.
Running it again replaces the result.
space m r run the block under the cursor (enter on its fence too)
space m R run every block in the file, in order
space m c clear the block's result; :blocks-results-clear for all
space m s stop the block running under the cursor
Nothing runs when a file opens. The first time you run a block in a file
Greed asks whether to: y for now, a to always trust that file. Files you
trust, and those whose front matter says greed: run, show a run button
on each block. Agents run blocks only in files you trust, and only as
they were when you last ran them or trusted the file, so a block an
agent rewrote waits for you to run it first.
Options go in the info string: id=NAME names a block’s result, and
input=NAME gives another block that result (on stdin, or as input in
Luau), running the named block first if it has no result yet, or every
time with rerun=true. dir=PATH runs a program elsewhere than the
file’s folder, and timeout=SECONDS stops it after that long. Add a
language from Luau:
require("@blocks").runner("lua", require("@blocks").program({ "lua", "-e" }))
Uses: core, agent, markdown.
| Command | Keys | What it does |
|---|---|---|
block-result-clear | m c (after the leader) | Remove the result under the code block at the cursor |
block-run | m r (after the leader) | Run the code block under the cursor and save its output in a result block under it |
block-stop | m s (after the leader) | Stop the code block running under the cursor |
blocks-results-clear | Remove every code block’s result in the file | |
blocks-run-all | m R (after the leader) | Run every code block in the file, in order, saving each one’s result |
blocks-trust | Always let this file’s code blocks run, without asking | |
blocks-untrust | Ask again before this file’s code blocks run |
| Option | Default | What it does |
|---|---|---|
blocks-max-lines | 1000 | The most lines of output a block’s result keeps; the rest is cut |
cli
Greed’s command line commands that are only Luau: greed ls, greed new,
greed bring and greed reference. Plugins add their own the same way:
greed.cli({
name = "hello",
doc = "Say hello",
usage = "[NAME]",
run = function(args)
return `hello {args[1] or "there"}`
end,
})
greed hello world then prints “hello world”.
cmdline
The command line: press “:” (alt-x in the vscode style) and type a command, like in Vim or Helix.
Every command can be run by name (:save, :pick-file), and the short
names Vim and Helix users know are aliases (:w, :q, :wq, :e).
Words after the command are its arguments (:open src/main.rs), and a
trailing “!” forces it (:q! quits with unsaved changes). :lua runs
Luau and := shows the value of an expression. A line range in front
(:%s/a/b/g, :5,10d) selects those lines first; ex.luau has Vim’s
line commands, and :g/regex/command is here.
Matches show above the prompt as you type. Tab and shift-tab go through them, up and down go through earlier command lines starting with what’s typed, enter runs and esc closes.
Other plugins add aliases and argument completion through
require("@cmdline"):
local cmdline = require("@cmdline")
cmdline.alias("gs", "git-status")
cmdline.completer("branch", function(word)
return { { text = "main" }, { text = "dev" } }
end)
A command then uses args = { { name = "branch", complete = "branch" } }.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
command-line | : (read, every style’s command mode), ctrl-g (vscode), alt-x (vscode’s typing mode) | Type a command to run, with completion, starting with the text given |
command-line-close | ctrl-c, esc (in cmdline buffers) | Close the command line without running anything |
command-line-newer | ctrl-n, down (in cmdline buffers) | Show the next command line that starts with what’s typed |
command-line-next | tab (in cmdline buffers) | Fill in the next match on the command line |
command-line-older | ctrl-p, up (in cmdline buffers) | Show the previous command line that starts with what’s typed |
command-line-prev | shift-tab (in cmdline buffers) | Fill in the previous match on the command line |
command-line-run | enter (in cmdline buffers) | Run what’s typed on the command line |
copy-lines | Copy the selected lines below a line, 0 for the top (:t) | |
delete-lines | Delete the selected lines, copying them (:d) | |
eval-selection | l e (after the leader) | Run the selected Luau, or the line, and show what it returns at the end of it |
get-option | Show an option’s value | |
move-lines | Move the selected lines below a line, 0 for the top (:m) | |
normal | Type keys in normal mode on each selected line (:norm) | |
set | Set an option: NAME VALUE; for a yes-or-no one, NAME, noNAME or NAME! as in Vim; NAME? shows it | |
sort-lines | Sort the selected lines (:sort): ! reverses, u keeps one of each, i ignores case, n sorts by the first number | |
substitute | Replace a regex with text on the selected lines (:s/regex/text/flags) | |
toggle-option | Turn a yes-or-no option on or off | |
yank-lines | Copy the selected lines (:y) |
| Option | Default | What it does |
|---|---|---|
substitute-preview | true | Show what :s will change as you type it, before it runs |
context
The context: what you’ve pinned for models and agents to see, as live references read fresh each time they’re sent.
space i p pin the selection, or the file when nothing is selected
space i i show the pinned items, one a line with its size; delete a
line (x d) to drop the item
:context-add-problems pins this file’s problems, :context-add-diff the
changes in progress, :context-clear drops everything. Assist commands
send the context with each question, and agents read it with the
context_get tool. It’s kept per project.
A plugin adds items that are worked out when sent:
require("@context").define("todos", function()
return "the TODO lines of the project ..."
end)
require("@context").add({ kind = "computed", name = "todos" })
Uses: core, agent, vcs.
| Command | Keys | What it does |
|---|---|---|
context | i i (after the leader) | Show what’s pinned for models and agents, with sizes; delete a line to drop it |
context-add | i p (after the leader) | Pin the selection to the context, or the file when nothing is selected |
context-add-diff | Pin the changes in progress to the context | |
context-add-problems | Pin this file’s problems to the context | |
context-clear | Drop everything pinned to the context | |
context-close | esc, q (in context buffers) | Close the context list |
core
Greed’s editing engine: the commands, motions, text objects, registers, floats, prompts and the editing styles registry, written against the same API any plugin uses. The editing styles themselves, like Helix and Vim, are plugins that give these commands keys.
| Command | Keys | What it does |
|---|---|---|
add-newline-above | [ space (helix, vim) | Add an empty line above each selection, staying put |
add-newline-below | ] space (helix, vim) | Add an empty line below each selection, staying put |
align-selections | & (helix) | Line the selections up at one column, with spaces before them |
align-view-bottom | z b (helix, vim), b (view) | Scroll so the cursor’s line is at the bottom of the screen |
align-view-top | z t (helix, vim), t (view) | Scroll so the cursor’s line is at the top of the screen |
append-line-end | A (helix) | Insert at the end of each line |
append-mode | a (helix) | Insert after each selection |
big-word-end | E (helix) | Select to the end of the WORD |
buffer | Show an open file by its name or part of it, as Vim’s :b does; # is the one you were in before | |
buffer-close | ctrl-w (vscode) | Close this buffer, showing another file in its place; refuses with unsaved changes (force closes anyway) |
buffer-close-others | Close every file but this one; refuses if one has unsaved changes (force closes anyway) | |
buffer-next | g n (helix) | Show the next open file |
buffer-prev | g p (helix) | Show the previous open file |
center-view | z c (helix), z z (helix, vim), c, z (view) | Scroll so the cursor’s line is in the middle of the screen |
change | c (helix) | Copy each selection, delete it and switch to insert mode |
change-without-copy | alt-c (helix) | Delete each selection and switch to insert mode, leaving the clipboard alone |
client-follow | Have this client show the project, tabs and panes the other clients follow, closing the panes it had on its own (their buffers stay open) | |
client-independent | Lay this client out on its own, starting from what it shows now: its tabs, panes and project no longer follow the other clients | |
collapse | ; (helix), esc (vscode) | Collapse each selection to its cursor |
config-open | Open your config, init.luau, to change it; it runs again when saved | |
config-reload | Run your config again, as saving it does | |
copy | space Y, space y, y (helix) | Copy each selection to the clipboard |
copy-lines-down | alt-shift-down (vscode) | Copy the cursors’ lines below them |
copy-lines-up | alt-shift-up (vscode) | Copy the cursors’ lines above them |
copy-or-line | ctrl-c (vscode) | Copy the selection, or the line when nothing is selected |
copy-selection-down | C (helix), ctrl-alt-down (vscode) | Add a selection on the next line, at the same columns |
copy-selection-up | alt-C (helix), ctrl-alt-up (vscode) | Add a selection on the line above, at the same columns |
cut | Copy each selection to the clipboard and delete it | |
cut-or-line | ctrl-x (vscode) | Cut the selection, or the line when nothing is selected |
decrement | ctrl-x (helix) | Subtract the count (or 1) from the number at each cursor |
dedent | < (helix), ctrl-d (vim-insert), shift-tab (vscode) | Take one level of indent off the lines of each selection |
delete | d (helix) | Copy each selection and delete it |
delete-back | backspace (every style’s typing mode) | Delete the character before each cursor |
delete-forward | delete (every style’s typing mode) | Delete the character after each cursor |
delete-lines-at-cursor | ctrl-K (vscode) | Delete the lines the cursors are on |
delete-to-line-end | ctrl-k (every style’s typing mode) | Delete to the end of the line from each cursor |
delete-to-line-start | ctrl-u (every style’s typing mode) | Delete back to the start of the line from each cursor |
delete-without-copy | alt-d (helix) | Delete each selection, leaving the clipboard alone |
delete-word-back | alt-backspace, ctrl-w (every style’s typing mode), ctrl-backspace (vscode) | Delete back to the start of the word before each cursor |
delete-word-forward | alt-d (every style’s typing mode), ctrl-delete (vscode) | Delete to the start of the next word after each cursor |
detach | Leave the editor running in the background; greed attach comes back | |
earlier | alt-u (helix), g - (vim) | Go back to the state of the text made before this one, on any undo branch |
erase-back | backspace (vscode) | Delete the selection, or the character before the cursor |
erase-forward | delete (vscode) | Delete the selection, or the character after the cursor |
errors | List errors from plugin code that nothing caught, with the plugin, what it ran and where it failed | |
expand-selection | alt-o (helix) | Grow each selection to the syntax node around it |
extend-big-word-end | E (helix-select) | Extend the selection to the end of the WORD |
extend-big-word-left | B (helix-select) | Extend the selection to the previous WORD |
extend-big-word-right | W (helix-select) | Extend the selection to the next WORD |
extend-down | down, j (helix-select), shift-down (vscode) | Extend the selection one line down |
extend-end | g e (helix-select), ctrl-shift-end (vscode) | Extend the selection to the end of the buffer |
extend-find-next-char | f (helix-select) | Extend to and including the next character typed |
extend-find-prev-char | F (helix-select) | Extend back to the previous character typed |
extend-first-non-blank | g s (helix-select) | Extend the selection to the first character that isn’t a space |
extend-goto-line | G (helix-select) | Extend the selection to the line given as a count, or the last line |
extend-left | h, left (helix-select), shift-left (vscode) | Extend the selection one character left |
extend-line-end | end, g l (helix-select), shift-end (vscode) | Extend the selection to the end of the line |
extend-line-start | g h, home (helix-select) | Extend the selection to the start of the line |
extend-right | l, right (helix-select), shift-right (vscode) | Extend the selection one character right |
extend-smart-home | shift-home (vscode) | Select to the first non-blank of the line, or to its start |
extend-start | g g (helix-select), ctrl-shift-home (vscode) | Extend the selection to the start of the buffer |
extend-till-next-char | t (helix-select) | Extend up to the next character typed |
extend-till-prev-char | T (helix-select) | Extend back to just after the previous character typed |
extend-to-line-bounds | X (helix) | Extend each selection to whole lines |
extend-up | k, up (helix-select), shift-up (vscode) | Extend the selection one line up |
extend-word-end | e (helix-select) | Extend the selection to the end of the word |
extend-word-left | b (helix-select), ctrl-shift-left (vscode) | Extend the selection to the previous word |
extend-word-right | w (helix-select), ctrl-shift-right (vscode) | Extend the selection to the next word |
file-delete | Delete this file from the disk, after you press y, and close it | |
file-rename | Rename or move this file: a name alone keeps it in its folder, a path is from the project | |
find | ctrl-f (vscode) | Find text in the file as you type, as VS Code’s ctrl-f does: enter and shift-enter go to the next and previous match, esc closes |
find-next | enter, f3 (in find buffers) | Go to the next match with the find bar open |
find-next-char | f (helix) | Select up to and including the next character typed |
find-prev | shift-enter, shift-f3 (in find buffers) | Go to the previous match with the find bar open |
find-prev-char | F (helix) | Select back to the previous character typed |
first-non-blank | g s (helix) | Move to the first character on the line that isn’t a space |
flip | alt-; (helix) | Swap the anchor and head of each selection |
fold-close | z C (helix), z c (vim) | Fold the block the cursor is in under its first line |
fold-close-all | z M (vim), ctrl-k ctrl-0 (vscode) | Fold every outermost block in the buffer |
fold-next | z j (vim) | Go to the start of the block below the cursor |
fold-open | z o (helix, vim), z d (vim) | Unfold the folds the cursor is in |
fold-open-all | z R (helix, vim), z E (vim), ctrl-k ctrl-j (vscode) | Unfold everything in the buffer |
fold-prev | z k (vim) | Go to the end of the block above the cursor |
fold-selection | Fold the selected lines under the first | |
fold-toggle | tab, z a (helix, vim), ctrl-k ctrl-l (vscode) | Fold the block the cursor is in, or unfold it |
fold-toggle-all | shift-tab (helix) | Unfold everything when anything is folded, or else fold every outermost block |
font-bigger | ctrl-+, ctrl-= (global) | Make the window’s text bigger |
font-reset | ctrl-0 (global) | Put the window’s text back to its size before zooming |
font-smaller | ctrl-- (global) | Make the window’s text smaller |
goto-column | g | (helix) | Move to the column given as a count, on each cursor’s line |
goto-definition | g d (every style’s command mode), f12 (vscode) | Go to where the thing under the cursor is defined |
goto-end | ctrl-end (vscode) | Move to the end of the buffer |
goto-file | g f (helix) | Open the file named under the cursor or in the selection |
goto-last-accessed-file | g a (helix), ctrl-6, ctrl-^ (every style’s command mode) | Show the file you were in before this one |
goto-last-line | g e (helix) | Move to the start of the last line |
goto-last-modification | g . (helix), ctrl-k ctrl-q (vscode) | Move to where this file was last changed |
goto-last-modified-file | g m (helix) | Show the file you changed last, other than this one |
goto-line | G (helix) | Move to the line given as a count, or the last line |
goto-parent-end | alt-e (helix) | Move to the end of the syntax node around each selection’s |
goto-parent-start | alt-b (helix) | Move to the start of the syntax node around each selection’s |
goto-start | g g (helix), ctrl-home (vscode) | Move to the start of the buffer, or with a count, to that line |
goto-window-bottom | g b (helix) | Move to the bottom line on the screen |
goto-window-center | g c (helix) | Move to the middle line on the screen |
goto-window-top | g t (helix) | Move to the top line on the screen |
half-page-down | ctrl-d (helix, read, view, vim), z ctrl-d (helix) | Move half a screen down |
half-page-up | ctrl-u (helix, read, view, vim), z ctrl-u (helix) | Move half a screen up |
hover | k (after the leader), K (vim), ctrl-k ctrl-i (vscode) | Show what’s under the cursor, and any problems there |
increment | ctrl-a (helix) | Add the count (or 1) to the number at each cursor |
indent | > (helix), ctrl-t (vim-insert), ctrl-] (vscode) | Indent the lines of each selection |
insert-char | Insert the typed character at each cursor | |
insert-line-above | ctrl-shift-enter (vscode) | Start a new line above this one |
insert-line-below | ctrl-enter (vscode) | Start a new line below this one |
insert-line-start | I (helix) | Insert at the start of each line, after its indent |
insert-mode | i (helix) | Insert before each selection |
insert-newline | enter (every style’s typing mode), alt-enter (every style’s typing mode; in shell buffers) | Insert a line break at each cursor, starting the new line at its indent |
insert-register | ctrl-r (every style’s typing mode) | Insert what the register typed next holds at each cursor |
insert-tab | tab (every style’s typing mode) | Insert a level of indent at each cursor |
join-lines | J (helix) | Join the next line onto each cursor’s, or the lines of each selection, with one space |
jump-back | ctrl-o (helix, vim), alt-left (vscode) | Go back to where the last jump started |
jump-forward | ctrl-i (helix, vim), alt-right (vscode) | Go forward again after jumping back |
jump-to-word | g w (helix) | Label the words on screen and select the one whose label is typed |
keep-matching | K (helix) | Keep the selections that match a regex |
keep-primary | , (helix) | Keep only the primary selection |
later | alt-U (helix), g + (vim) | Go on to the state of the text made after this one, on any undo branch |
line-end | end (helix, every style’s typing mode, vscode), g l (helix) | Move to the end of the line |
line-start | g h (helix), home (helix, every style’s typing mode) | Move to the start of the line |
lowercase | ``` (helix) | Make the selections lowercase |
macro-save | Save the last macro (or the one in a register) as a command you can run and edit | |
match-bracket | m m (helix) | Move to the matching bracket, or the closing one of the pair around the cursor |
merge-consecutive-selections | alt-_ (helix) | Merge selections that touch or overlap |
merge-selections | Merge all selections into one, from the first to the last | |
motion-hint-1 | Do the last motion 1 more times | |
motion-hint-2 | Do the last motion 2 more times | |
motion-hint-3 | Do the last motion 3 more times | |
motion-hint-4 | Do the last motion 4 more times | |
motion-hint-5 | Do the last motion 5 more times | |
motion-hint-6 | Do the last motion 6 more times | |
motion-hint-7 | Do the last motion 7 more times | |
motion-hint-8 | Do the last motion 8 more times | |
motion-hint-9 | Do the last motion 9 more times | |
move-down | down (helix, read, every style’s typing mode, vscode), j (helix, read) | Move one line down |
move-left | h (helix, read), left (helix, read, every style’s typing mode, vscode) | Move one character left |
move-lines-down | alt-down (vscode) | Move the cursors’ lines down one |
move-lines-up | alt-up (vscode) | Move the cursors’ lines up one |
move-right | l (helix, read), right (helix, read, every style’s typing mode, vscode) | Move one character right |
move-up | k (helix, read), up (helix, read, every style’s typing mode, vscode) | Move one line up |
move-word-left | ctrl-left (vscode) | Move to the start of the previous word |
move-word-right | ctrl-right (vscode) | Move to the start of the next word |
next-big-word | W (helix) | Select to the start of the next WORD (punctuation included) |
next-comment | ] c (helix, vim) | Select the next comment |
next-entry | ] e (helix, vim) | Select the next entry |
next-function | ] f (helix, vim) | Select the next function |
next-parameter | ] a (helix, vim) | Select the next parameter |
next-test | ] T (helix, vim) | Select the next test |
next-type | ] t (helix, vim) | Select the next type |
next-word | w (helix) | Select to the start of the next word |
normal-mode | esc (every style’s typing mode) | Back to the editing style’s own mode (normal, in Helix’s) |
open | Open a file in the main view | |
open-above | O (helix) | Open a new line above each cursor and insert there |
open-below | o (helix) | Open a new line below each cursor and insert there |
page-down | ctrl-f (helix, read, view, vim), pagedown (helix, read, every style’s typing mode, vim, vscode), z ctrl-f (helix) | Move a screen down |
page-up | ctrl-b (helix, read, view, vim), pageup (helix, read, every style’s typing mode, vim, vscode), z ctrl-b (helix) | Move a screen up |
paste-after | p, space p (helix) | Paste after each selection |
paste-before | P (helix) | Paste before each selection |
paste-image | alt-v (in agent-transcript buffers) | Paste the image on your clipboard into what you’re in, like an agent’s box |
paste-over | ctrl-v (vscode) | Paste, replacing each selection; whole lines go above the cursor’s line |
play-macro | q (helix) | Play the macro in @, or the register picked |
press-button | enter (helix, read, vim) | Run the button under the cursor, as clicking it does |
prev-big-word | B (helix) | Select to the start of the previous WORD |
prev-comment | [ c (helix, vim) | Select the previous comment |
prev-entry | [ e (helix, vim) | Select the previous entry |
prev-function | [ f (helix, vim) | Select the previous function |
prev-parameter | [ a (helix, vim) | Select the previous parameter |
prev-test | [ T (helix, vim) | Select the previous test |
prev-type | [ t (helix, vim) | Select the previous type |
prev-word | b (helix) | Select to the start of the previous word |
profile | Start counting where the editor’s time goes; again, stop and show it, the most time first | |
project | Open a project, or switch to it if it’s open | |
project-close | Close the shown project, unless it has unsaved changes (force closes anyway) | |
project-config | Run the shown project’s own config in .greed/, if you trusted it | |
prompt-cancel | ctrl-c, esc (in find, prompt buffers) | Close the prompt without accepting |
prompt-submit | enter (in prompt buffers) | Accept what’s typed in the prompt |
quit | ctrl-q (global) | Close this pane when there are others; otherwise close the project and leave, or exit the editor if it’s the last one, refusing with unsaved changes (force goes anyway) |
quit-abort | In a file a program waits on, like git commit’s message, stop the program with an error, as Vim’s :cq does; whatever was written is left as it is | |
quit-all | End the session and every project in it, whatever runs, unless files have unsaved changes (force ends it anyway) | |
quit-ask | ctrl-q (vscode) | Leave the project, or exit the editor, from any pane, as VS Code’s ctrl-q does; asks whether to save unsaved files first rather than refusing |
quit-session | End the session, whatever runs in it, unless files have unsaved changes (force ends it anyway); terminals, shells and agents never count as unsaved | |
record-macro | Q (helix) | Start recording keys into a macro (@, or the register picked), or stop |
redo | U (helix), ctrl-Z, ctrl-y (vscode) | Redo the last undone change |
reflow | Rewrap the lines of each selection to the text width, or the width given | |
reindent-lines | Indent each selected line as its language and the lines around it say | |
reload | Load the file again from disk, as an edit undo can take back | |
reload-all | Load every open file again from disk, as edits undo can take back | |
remove-matching | alt-K (helix) | Remove the selections that match a regex |
remove-primary | alt-, (helix) | Remove the primary selection |
repeat-change | . (helix, vim) | Repeat the last change, at the cursors; a count replaces the one it had |
repeat-find | alt-. (helix) | Do the last f, t, F or T again; in select mode, extending |
replace-char | r (helix) | Replace every selected character with the next one typed |
replace-in-file | ctrl-h (vscode) | Replace text everywhere in the file, as VS Code’s ctrl-h does: what to find, with its matches lit and counted, then what to put instead |
replace-with-copy | R, space R (helix) | Replace each selection with what was copied |
rotate-contents | alt-) (helix) | Move each selection’s text to the selection after it, the last’s to the first |
rotate-contents-back | alt-( (helix) | Move each selection’s text to the selection before it, the first’s to the last |
rotate-primary | ) (helix) | Make the next selection the primary one |
rotate-primary-back | ( (helix) | Make the previous selection the primary one |
save | ctrl-s (global) | Write the buffer to its file, or to a new one |
save-all | ctrl-k s (vscode) | Write every file with unsaved changes |
save-quit | Z Z (vim) | Write the buffer to its file if it changed, then quit |
save-quit-all | Write every file with unsaved changes, then end the session | |
scroll-down | z down, z j (helix), down, j (view), ctrl-e (vim) | Scroll the view a line down |
scroll-up | z k, z up (helix), k, up (view), ctrl-y (vim) | Scroll the view a line up |
search | / (helix, read, vim) | Search forward for a regex as you type |
search-back | ? (helix, vim) | Search backward for a regex as you type |
search-clear | Take away the search’s match highlights, as Vim’s :noh does | |
search-next | n (helix, read, vim), f3 (vscode) | Select the next match of the last search |
search-next-add | n (helix-select) | Add the next match of the last search as another selection |
search-prev | N (helix, read, vim), shift-f3 (vscode) | Select the previous match of the last search |
search-prev-add | N (helix-select) | Add the previous match of the last search as another selection |
search-selection | * (helix) | Search for the selected text, as whole words where it starts or ends one |
search-selection-anywhere | alt-* (helix) | Search for the selected text, also inside longer words |
secret-set | Keep a secret, like an API key, in the system keyring (or Greed’s secrets file) | |
select-all | % (helix), ctrl-a (vscode) | Select the whole buffer |
select-all-children | alt-I (helix) | Select every syntax node inside each selection’s |
select-all-matches | ctrl-L (vscode) | Select every match of the selected text (or the word at the cursor) |
select-all-siblings | alt-a (helix) | Select every syntax node beside each selection’s, its own included |
select-around-angles | m a <, m a > (helix) | Select around the angles |
select-around-backticks | `m a `` (helix) | Select around the backticks |
select-around-big-word | m a W (helix) | Select the WORD and the space after it |
select-around-braces | m a {, m a } (helix) | Select around the braces |
select-around-brackets | m a [, m a ] (helix) | Select around the brackets |
select-around-comment | m a c (helix) | Select around the comment at each selection |
select-around-double-quotes | m a " (helix) | Select around the double-quotes |
select-around-entry | m a e (helix) | Select around the entry at each selection |
select-around-function | m a f (helix) | Select around the function at each selection |
select-around-indent | m a i (helix) | Select the lines indented as far as this one, and the one above |
select-around-last | m a l (helix) | Select around the last pair of the bracket or quote typed next |
select-around-next | m a n (helix) | Select around the next pair of the bracket or quote typed next |
select-around-number | m a d (helix) | Select the number at or after the cursor, with its sign |
select-around-pair | m a m (helix) | Select around the nearest brackets or quotes |
select-around-parameter | m a a (helix) | Select around the parameter at each selection |
select-around-parens | m a (, m a ) (helix) | Select around the parens |
select-around-quotes | m a ' (helix) | Select around the quotes |
select-around-tag | m a x (helix) | Select around the XML or HTML element |
select-around-test | m a T (helix) | Select around the test at each selection |
select-around-type | m a t (helix) | Select around the type at each selection |
select-around-word | m a w (helix) | Select the word and the space after it |
select-inside-angles | m i <, m i > (helix) | Select inside the angles |
select-inside-backticks | `m i `` (helix) | Select inside the backticks |
select-inside-big-word | m i W (helix) | Select the WORD |
select-inside-braces | m i {, m i } (helix) | Select inside the braces |
select-inside-brackets | m i [, m i ] (helix) | Select inside the brackets |
select-inside-comment | m i c (helix) | Select inside the comment at each selection |
select-inside-double-quotes | m i " (helix) | Select inside the double-quotes |
select-inside-entry | m i e (helix) | Select inside the entry at each selection |
select-inside-function | m i f (helix) | Select inside the function at each selection |
select-inside-indent | m i i (helix) | Select the lines indented as far as this one |
select-inside-last | m i l (helix) | Select inside the last pair of the bracket or quote typed next |
select-inside-next | m i n (helix) | Select inside the next pair of the bracket or quote typed next |
select-inside-number | m i d (helix) | Select the number at or after the cursor |
select-inside-pair | m i m (helix) | Select inside the nearest brackets or quotes |
select-inside-parameter | m i a (helix) | Select inside the parameter at each selection |
select-inside-parens | m i (, m i ) (helix) | Select inside the parens |
select-inside-quotes | m i ' (helix) | Select inside the quotes |
select-inside-tag | m i x (helix) | Select inside the XML or HTML element |
select-inside-test | m i T (helix) | Select inside the test at each selection |
select-inside-type | m i t (helix) | Select inside the type at each selection |
select-inside-word | m i w (helix) | Select the word |
select-line | x (helix) | Select the whole line, including its line break; again, the next line too |
select-lines | ctrl-l (vscode) | Select the cursor’s line, or the next one too when whole lines are selected |
select-next-match | ctrl-d (vscode) | Select the word at the cursor, then add the next match of it as another selection |
select-next-sibling | ] n (helix, vim) | Select the next syntax node beside each selection |
select-prev-sibling | [ n (helix, vim) | Select the previous syntax node beside each selection |
select-regex | s (helix) | Select every match of a regex inside the selections |
select-register | " (helix, vim) | Pick a register, by the next key typed, for the next copy, paste or macro |
selection-redo | ctrl-k (helix), ctrl-U (vscode) | Go forward to the selection selection-undo went back from |
selection-undo | ctrl-h (helix), ctrl-u (vscode) | Go back to the selection before the last command |
session | Go to another session: a running one by name, or a project’s (started if needed) | |
shrink-selection | alt-i (helix) | Shrink each selection back, or to the first syntax node inside it |
shrink-to-line-bounds | alt-x (helix) | Shrink each selection to the whole lines inside it |
smart-home | home (vscode) | Go to the first non-blank of the line, or to its start |
split-lines | alt-s (helix) | Split the selections into lines |
split-regex | S (helix) | Split the selections at every match of a regex |
stalls | List the times plugin code held the editor up, with the plugin and what it ran | |
style | Switch editing style, or pick one | |
surround-add | m s (helix) | Wrap each selection in the pair of the next character typed |
surround-delete | m d (helix) | Take away the pair of the next character typed from around each selection |
surround-replace | m r (helix) | Swap the pair of the next character typed around each selection for another’s |
swap-node-next | alt-shift-right (helix, vim, vim-visual) | Move the syntax node selected past the one after it |
swap-node-prev | alt-shift-left (helix, vim, vim-visual) | Move the syntax node selected past the one before it |
switch-case | ~ (helix) | Switch the case of each selected letter |
text-float-close | Close the float showing text | |
till-next-char | t (helix) | Select up to the next character typed |
till-prev-char | T (helix) | Select back to just after the previous character typed |
toggle-comment | ctrl-c, space c (helix), ctrl-/, ctrl-_ (vscode) | Comment the lines of each selection, or uncomment them if they all are |
trim-selections | _ (helix) | Trim the spaces and line breaks off both ends of each selection |
trust | Trust the shown project’s own config in .greed/, and run it now and whenever it opens | |
type-char | Type the pressed character, replacing any selection | |
type-newline | enter (vscode) | Type a line break, replacing any selection, and start the new line at its indent |
type-tab | tab (vscode) | Indent the selected lines when a selection spans lines, otherwise type a level of indent |
undo | u (helix), ctrl-z (vscode) | Undo the last change |
uppercase | `alt-`` (helix) | Make the selections uppercase |
view-mode | Z (helix) | Keys for the view until esc: center, top, bottom, scroll |
view-mode-leave | esc (view) | Back from the view mode |
word-end | e (helix) | Select to the end of the word |
| Option | Default | What it does |
|---|---|---|
auto-reload | true | Load files changed on disk into their buffers, unless they have unsaved changes |
auto-save | false | Save files on their own a moment after their edits stop |
auto-save-delay | 1000 | How long after the last edit auto-save saves, in milliseconds |
editing-style | "helix" | How editing works: helix, vim, vscode or another style a plugin adds (see :style) |
effects | false | Small animations, like a wave of light through the status line when you switch files |
gui-font | "" | The font the window draws text in, by family name; empty for the system’s monospaced font |
gui-font-prose | "" | The proportional font the window draws prose in (styles with font = “prose”, like Markdown’s text), by family name; empty for the system’s sans-serif |
gui-font-size | 15 | The size of the window’s text in pixels, before the screen’s scale; zooming gives a window a size of its own |
indent | " " | One level of indent, spaces or a tab, in languages that don’t set their own |
jump-label-alphabet | "abcdefghijklmnopqrstuvwxyz" | The letters jump labels are made of, most comfortable first |
line-numbers | "absolute" | How line numbers count: “absolute”, “relative” to the cursor’s line, or “hybrid” (relative, with the cursor’s line its own number) |
link-opener | "" | What opens a link, e.g. “firefox”; empty for xdg-open, or open on macOS |
motion-hints | false | Number the next places a word motion would go, and go there on a digit |
notes-search-case | "ignore" | How searching notes minds case: “smart” (only when what you type has a capital letter), “ignore”, “match”, or “default” for as search-case says |
on-quit | "auto" | What :q on the last project does to the session: “auto” ends it unless something is running (a command in a terminal, an agent at work) and keeps it then, “end” always ends it, “keep” always leaves it running to attach to again |
on-quit-remote | "keep" | Like on-quit, when you’re attached over greed ssh |
search-case | "smart" | How searches you type mind case, unless their kind says otherwise: “smart” (only when what you type has a capital letter), “ignore” or “match” |
session-idle-hours | 24 | A session nothing is attached to, with nothing running and nothing unsaved, ends after this many hours; 0 keeps it |
shell-filter-search-case | "ignore" | How filtering a shell block with / minds case: “smart” (only when what you type has a capital letter), “ignore”, “match”, or “default” for as search-case says |
substitute-search-case | "match" | How :s minds case: “smart” (only when what you type has a capital letter), “ignore”, “match”, or “default” for as search-case says |
text-width | 80 | How wide :reflow (and Vim’s gq) makes lines |
describe
Help: describe anything the editor is made of, to see what it does, who defined it and where. In the help window, enter jumps to the definition and esc (or q) closes it.
space h h describe anything: commands, options, events, the API,
plugins and modes, in one picker
space h c a command space h o an option
space h e an event space h a a function of the API
space h p a plugin space h m a mode and its keys
space h k press a key to see what it runs
Agents get the same through the describe tool, from text.
Uses: core, picker.
| Command | Keys | What it does |
|---|---|---|
describe | h h (after the leader) | Describe anything: a command, option, event, API function, plugin or mode |
describe-api | h a (after the leader) | Describe a function or type of the plugin API |
describe-command | h c (after the leader) | Describe a command |
describe-event | h e (after the leader) | Describe an event |
describe-key | h k (after the leader) | Press keys to see what command they run |
describe-mode | h m (after the leader) | Describe a mode |
describe-option | h o (after the leader) | Describe an option |
describe-plugin | h p (after the leader) | Describe a plugin |
describe-style | h s (after the leader) | Describe a style |
help-close | esc, q (in help buffers) | Close the help window |
help-goto | enter (in help buffers) | Open the file what’s described is defined in, at its definition |
flash
Flashes text as it’s copied, so you can see what went to the clipboard.
With a “#rrggbb” background for “ui.flash” in the theme it fades out; with the 16 terminal colors it shows briefly and goes. Either way it’s a decoration and a theme entry changing over time, which is all an animation is.
To change how long it lasts, set “flash-duration” from your config:
require("@greed").option.set("flash-duration", 150)
Uses: core.
| Option | Default | What it does |
|---|---|---|
flash-duration | 300 | How long copied text flashes, in milliseconds |
format
Formatting: :format, and on every save unless format-on-save is off.
A language’s formatter program (see the languages plugin) is used when
it’s installed; otherwise the language server is asked. Only what changed
is replaced, so the cursor and selections stay where they were.
To stop formatting on save:
require("@greed").option.set("format-on-save", false)
Uses: core, languages.
| Command | Keys | What it does |
|---|---|---|
format | = (helix’s command mode) | Format the buffer with its language’s formatter or language server |
| Option | Default | What it does |
|---|---|---|
format-on-save | true | Format files when they’re saved |
grep
Search the whole project, and replace by editing what was found.
space / search the project for a regex as you type
ctrl-e in that picker: put the matches in a results panel
:grep PATTERN DIR? put the matches in a results panel straight away
The results panel is a multibuffer: each matching line under its file’s name. Edit the lines with anything (s to select the matches and c to change them all works well) and the files change as you type; :w saves them, enter opens the match under the cursor, and q closes the panel.
Patterns are regexes; ones in lowercase ignore case. The project is the folder holding .jj or .git (see core’s project.luau).
Uses: picker, multibuffer.
| Command | Keys | What it does |
|---|---|---|
grep | Put the lines matching a regex in a panel, to go to them or edit them | |
grep-close | Close the search results | |
search-project | / (after the leader) | Search the project for a regex as you type, and go to a match |
helix
Helix’s editing style, the default: select text, then say what to do with
it. Its modes are helix (normal), helix-insert and helix-select;
the status line shows them as NORMAL, INSERT and SELECT. The commands
are core’s; this plugin gives them Helix’s keys. Copy any part of it
into your own config to change it.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
select-mode | v (helix, helix-select), esc (helix-select) | Start select mode, where moves extend the selection, or leave it |
hints
Key hints: after a key that starts longer sequences, like “space”, show
what can come next and what each key does. f1 shows the keys of the mode
you’re in, and the first time you’re in a mode listed in intro (like
typing into a terminal), a line in the status line says how to get out.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
keys-help | f1 (global, pane, resize, tab, terminal) | Show the keys of the mode you’re in and what each does |
hosts
Connecting to another machine from inside Greed: space C (:connect)
lists the hosts you connected to lately and those in ~/.ssh/config, and
going to one shows its session here, as greed ssh HOST would, starting
one there if none is running. Typing a host that isn’t listed connects
to it too.
Uses: core, picker.
| Command | Keys | What it does |
|---|---|---|
connect | C (after the leader) | Show a session on another machine here, as greed ssh does: pick a host, or type one |
image
Image files open as the image: PNG, JPEG and GIF, drawn as wide as the view at most (in the window, and in terminals that show images), under a line with its name, size and zoom.
+ - bigger, smaller
= as wide as the view, or its own size when it's smaller
0 its own size
Uses: core.
| Command | Keys | What it does |
|---|---|---|
image-zoom-actual | 0 (in image buffers) | Draw the image at its own size |
image-zoom-fit | = (in image buffers) | Draw the image as wide as the view, or at its own size when it’s smaller |
image-zoom-in | + (in image buffers) | Draw the image bigger |
image-zoom-out | - (in image buffers) | Draw the image smaller |
languages
Languages, batteries included: which files are in which language, their
language servers and how they’re commented and indented. The table is in
languages.luau. A server only starts if it’s installed, so nothing needs
setting up; :health shows what’s found and what’s missing.
Change an entry from your config. Fields you give replace those fields:
local languages = require("@languages")
languages.set("python", { servers = { { "pylsp" } } })
languages.set("odin", { extensions = { "odin" }, servers = { { "ols" } } })
Uses: core.
| Command | Keys | What it does |
|---|---|---|
grammar-fetch | Download a grammar Greed knows where to get, ahead of opening a file in it | |
health | Show each language’s highlighting and servers, and which are installed |
| Option | Default | What it does |
|---|---|---|
grammar-download | true | Download the grammar for a language Greed has none for when a file in it opens |
lsp
Language servers: hover, definitions, references, rename, code actions
and diagnostics. Lines with problems get a sign, and the worst problem’s
message shows after the line (turn that off with
:set diagnostic-messages false).
space k show what's under the cursor, with any problems there
g d go to the definition
g r pick a place it's used
space r rename it everywhere
space a pick a fix or refactor
space d pick a problem in this file
space D pick a problem in any file
] d / [ d next / previous problem
Servers start the first time a file of their language is open, if one is
installed; the languages plugin says which (see :health).
Uses: core, picker, multibuffer, statusline.
| Command | Keys | What it does |
|---|---|---|
code-action | a (after the leader), g r a (vim), ctrl-. (vscode) | Pick a fix or refactor for the cursor or the selection |
completion-accept | enter (completion-helix-insert, completion-vim-insert, completion-vscode; in shell buffers) | Put the current completion in place of the word being typed; with none chosen, close the menu and do what enter does |
completion-ask | ctrl-x (helix’s typing mode), ctrl-space (every style’s typing mode), tab (every style’s typing mode; in shell buffers) | Ask what could go at the cursor: a source like the shell’s, or the language server |
completion-close | esc (completion-helix-insert, completion-vim-insert, completion-vscode; in shell buffers) | Close the completion menu and do what esc does where you were typing |
completion-down | down (completion-helix-insert, completion-vim-insert, completion-vscode; in shell buffers) | Move to the next completion, or in a shell’s menu that opened by itself, the command after |
completion-next | ctrl-n (completion-helix-insert, completion-vim-insert, completion-vscode; in shell buffers) | Move to the next completion |
completion-prev | ctrl-p, shift-tab (completion-helix-insert, completion-vim-insert, completion-vscode; in shell buffers) | Move to the previous completion |
completion-tab | tab (completion-helix-insert, completion-vim-insert, completion-vscode; in shell buffers) | Move to the next completion; where tab completes in place, as in a shell, first put in what every match starts with |
completion-up | up (completion-helix-insert, completion-vim-insert, completion-vscode; in shell buffers) | Move to the previous completion, or in a shell’s menu that opened by itself, the command before |
completion-words | ctrl-n (vim-insert) | Complete the word being typed from words in open files |
completion-words-back | ctrl-p (vim-insert) | Complete the word being typed from words in open files, starting with the last |
first-diagnostic | [ D (every style’s command mode) | Go to the first problem in this file |
goto-declaration | g D (every style’s command mode) | Go to where the thing under the cursor is declared |
goto-implementation | g i (every style’s command mode), g r i (vim) | Go to where the thing under the cursor is implemented |
goto-references | g r (every style’s command mode), g r r (vim), shift-f12 (vscode) | Pick a place where the thing under the cursor is used, and go there |
goto-type-definition | g y (every style’s command mode), g r t (vim) | Go to where the type of the thing under the cursor is defined |
last-diagnostic | ] D (every style’s command mode) | Go to the last problem in this file |
lsp-restart | Start this file’s language server again, as when it’s stuck; with all, every server | |
next-diagnostic | ] d (every style’s command mode), f8 (vscode) | Go to the next problem in this file |
pick-diagnostic | d (after the leader) | Pick a problem in this file and go to it |
pick-problem | D (after the leader), ctrl-M (vscode) | Pick a problem in any file, open or not, and go to it |
pick-workspace-symbol | S (after the leader), ctrl-t (vscode) | Pick a function, type or other symbol anywhere in the project, as the language server knows them |
prev-diagnostic | [ d (every style’s command mode), shift-f8 (vscode) | Go to the previous problem in this file |
rename | r (after the leader), g r n (vim), f2 (vscode) | Rename the thing under the cursor everywhere it’s used |
select-references | H (after the leader) | Select every place in this file where the thing under the cursor is used |
signature-help | While typing, show what the function being called takes |
| Option | Default | What it does |
|---|---|---|
completion-delay | 150 | Milliseconds of no typing before a completion menu opens by itself; 0 opens it only when asked |
completion-enter | "auto" | What enter does in a completion menu: “first” puts in the first item, “selected” only one moved to with tab or the arrows (otherwise enter does what it does without a menu, like running a shell’s line), “auto” lets each source say: the shell “selected”, language servers “first” |
diagnostic-messages | true | Show each line’s worst problem after the end of the line |
markdown
Markdown as a document: headings without their hashes (the top level
twice the size), bold, italic, struck and code without their
markers, links as their text, fenced code on a background of its own,
quotes with a bar, --- as a line, list dashes as bullets and tables in
columns with borders (tables.luau). The file stays plain Markdown:
typing on a line shows it as written (see core.reveal). Turn it off
with :set markdown-look false, or for one file with
markdown-look-toggle. tab folds the section, list item or code block
around the cursor (folds.luau).
The reading view (markdown-read) shows the file read-only with no
markup at all, images in place and links to follow (links.luau), in the
“read” mode; esc goes back to editing at the same place.
Other plugins can draw some parts their own way: notes draws headings and
bullets as symbols, and claims them with require("@markdown").claim.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
choice-pick | Pick the choice under the cursor, unpicking the others in its group | |
markdown-follow | Follow the Markdown link under the cursor: to a heading, another file or a web page | |
markdown-look-toggle | m l (after the leader), alt-V (vscode’s typing mode) | Show this Markdown file as a document or as written, whatever markdown-look says |
markdown-read | m v (after the leader), alt-v (read, vscode’s typing mode), esc, q, space m v (read) | Read this Markdown file as a document, with images and links to follow; again or esc to edit |
| Option | Default | What it does |
|---|---|---|
markdown-look | true | Show Markdown with its markup hidden and its headings, code and quotes drawn as such |
models
Language models by role. Plugins ask for a role, like “fast” or “reasoning”, and your config says which provider and model plays it, so no plugin hard-codes a provider and switching to a local model is one line.
:models each role's provider and model and whether its key is found;
enter changes a role, k sets a key, l signs in
What you pick in :models (or the setup page) is kept in Greed’s data folder and read before your config, which has the last word.
In your config:
local models = require("@models")
models.roles.fast = { provider = "ollama", model = "llama3.2" }
models.providers.work = { kind = "openai", url = "https://llm.example.com/v1", secret = "work" }
Keys come from greed.secrets (:models, :secret-set anthropic, or
ANTHROPIC_API_KEY).
Uses: core, picker.
| Command | Keys | What it does |
|---|---|---|
login | Sign in to a provider whose plan comes with an account, like Berget Code, instead of using an API key | |
logout | Forget the sign-in kept for a provider | |
models | Show and change which model plays each role, set API keys and sign in | |
models-change | On the :models page, pick the provider and model that play the role under the cursor | |
models-close | Close the :models page | |
models-key | On the :models page, set the API key of the provider of the role under the cursor | |
models-login | On the :models page, sign in to the provider of the role under the cursor | |
usage | How many tokens the models were sent and wrote today and over the last week |
multibuffer
Multibuffers: one buffer made of excerpts from many files, edited in place. Typing in an excerpt edits its file as you go (the file opens in Greed the first time one of its excerpts changes), and a change made to the file anywhere else shows in the excerpt. :w saves every file changed this way, enter goes to the line under the cursor and q closes the view.
Search results open in one. A plugin makes its own with
require("@multibuffer").open({ { path = "/src/main.rs", from = 9, to = 12 } },
{ summary = "1 place" })
Each file’s name shows above its excerpts and its line numbers beside them; neither is text you can edit. Excerpts that overlap or touch are joined.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
multibuffer-close | q (every style’s command mode; in staged-diff, why, multibuffer buffers) | Close the view showing the multibuffer |
multibuffer-open | enter (every style’s command mode; in multibuffer buffers) | Go to the line under the cursor in its file |
multibuffer-revert | g r (after the leader; in multibuffer buffers) | Put the change under the cursor back the way it was, in a view of changes |
notes
Notes: a folder of plain Markdown files, linked with [[note]], with todos and an agenda. It’s only files, so git or Syncthing can carry them to other machines and a phone.
space n d today's note space n f find a note
space n c capture a todo space n / search the notes
space n a the agenda: open todos, soonest due first
space n x tick a todo, or untick it
space n t jot a thought down in the inbox
space n r dismiss the reminders notice
space n l have Greed's agent link the inbox to your other notes
space k on a due date or a reminder, say when it is in words
g d follow the [[link]] under the cursor (making the note)
tab, z a fold the section, list item or code block under the cursor,
or unfold it (Markdown's folds)
In notes (Markdown files in the notes folder, or every Markdown file with
notes-everywhere), links show without their brackets, markup shows as
symbols (look.luau), and each note lists the notes linking to it at its
end. Todos and lines can carry reminders (reminders.luau).
local greed = require("@greed")
greed.option.set("notes-folder", "~/Documents/notes")
Uses: core, picker, agent, markdown, statusline, acp.
| Command | Keys | What it does |
|---|---|---|
notes-agenda | n a (after the leader) | Pick from the open todos in every note, soonest due first |
notes-capture | n c (after the leader) | Add a todo to the inbox note, from wherever you are: the project’s when it keeps notes |
notes-capture-mine | Add a todo to your own inbox note, even in a project that keeps notes | |
notes-connect | n l (after the leader) | Have Greed’s agent go through the inbox (or the note you’re in), link it to your other notes and add context, as changes you review |
notes-daily | n d (after the leader) | Open today’s note, making it if there isn’t one |
notes-find | n f (after the leader) | Open a note by name |
notes-reminder-open | Open the first reminder in the notice, and close the notice | |
notes-reminders-dismiss | n r (after the leader) | Close the reminders notice |
notes-search | n / (after the leader) | Search every note as you type |
notes-thought | n t (after the leader) | Jot a thought or an idea down in the inbox note, with today’s date, from wherever you are |
todo-toggle | n x (after the leader) | Tick the todo on each selected line, or untick it; a plain line becomes a todo |
| Option | Default | What it does |
|---|---|---|
notes-conceal | true | Show links in notes without their brackets, and markup as symbols |
notes-everywhere | false | Treat every Markdown file as a note: concealed links and backlinks |
notes-folder | "~/notes" | The folder notes live in; ~ is your home folder |
notes-project-folder | ".greed/notes" | Where a project keeps its notes, in the project: they’re named project:NAME, and the plan and decisions you share with agents are among them |
notes-remind-desktop | true | Show reminders as desktop notifications with notify-send or osascript, where installed |
notes-remind-time | "09:00" | When a reminder with a date and no time goes off, as HH:MM |
operations
Operations: work across files taken as one thing. An operation groups the edits it makes in every buffer and the programs it runs, so you can review it in one view and undo it in one step.
space u o recent operations, to review one
space u u undo the latest operation (in a review, that one)
In a review, space g r puts back the change under the cursor.
A plugin or agent makes one with
local operations = require("@operations")
operations.run("rename parse to parse_line", function(op)
-- edit buffers, then
operations.exec(op, { "cargo", "test" })
end)
Uses: core, picker, multibuffer.
| Command | Keys | What it does |
|---|---|---|
operation-undo | u u (after the leader) | Undo the latest operation, or the one being reviewed, in every file at once |
operations | u o (after the leader) | Pick a recent operation to review: its changes across files and the programs it ran |
panes
Panes and tabs, the way a terminal multiplexer has them: split the screen between files and terminals, move between them, give a pane more room, keep tabs of layouts (arranged by the layout managers in layouts.luau). The keys follow zellij’s where they can:
- alt keys work everywhere, in every editing style and in terminals:
alt-h/j/k/l move between panes (and to the next tab at the edge),
alt-n opens a terminal pane (a floating one while floats are shown),
alt-f shows or hides the tab's floating views (opening a floating
terminal when there are none), alt-F floats this file, alt-= and
alt-- resize, alt-< and alt-> (alt-[ and alt-] too) or alt-1..9
change tabs. alt-w changes how the tab lays out its floats (see
floats.luau), alt-{ and alt-} cycle through them and alt-W picks one
from the dock.
- alt-p and alt-t open the pane and tab modes, where single keys act until
esc.
- In normal mode, ctrl-w (and the leader’s w) is the window prefix Vim and Helix
users know, and in Vim, g t and g T change tabs.
Every key is in M.keys; rebind or unbind them from your config like any
other (see docs/keys.md).
Uses: core, picker, terminal, statusline.
| Command | Keys | What it does |
|---|---|---|
float-dock | Show the dock of this tab’s floating views, or hide it | |
float-dock-pick | alt-W (global, terminal) | Pick a floating view from the dock: 1 to 9, or the arrows and enter |
float-file | alt-F (global, terminal), E (pane) | Open a file (this one if none is given) in a new floating view |
float-flip | F, e (pane) | Take this pane out to float over the tab, or put a floating view back in as a pane |
float-go | Bring this tab’s floating view number N to the front, as the dots on its border count | |
float-layout-next | alt-w (global, terminal) | Lay this tab’s floating views out with the next float layout |
float-layout-pick | Y (pane) | Pick how this tab lays out its floating views |
float-move-down | down (resize) | Move the floating view down |
float-move-left | left (resize) | Move the floating view left |
float-move-right | right (resize) | Move the floating view right |
float-move-up | up (resize) | Move the floating view up |
float-next | alt-} (global, terminal), } (pane) | Bring the next floating view in this tab to the front |
float-previous | alt-{ (global, terminal), { (pane) | Bring the floating view before in this tab to the front |
float-terminal-new | W (pane) | Open another floating terminal in this tab |
floats-cascade | C (pane) | Stack this tab’s floating views in a cascade, from now on |
floats-one | O (pane) | Show this tab’s floating views one at a time, like tabs, all in the same place, from now on |
floats-tile | T (pane) | Lay this tab’s floating views out side by side, from now on |
floats-toggle | alt-f (global, terminal), w, z (pane) | Hide this tab’s floating views or show them again; with none, open a floating terminal |
layout-main-grow | ] (pane) | Give the main pane more room |
layout-main-shrink | [ (pane) | Give the main pane less room |
layout-next | alt-space (global, terminal), space (pane) | Arrange this tab with the next layout |
layout-open | Open a saved layout as a new tab | |
layout-pick | y (pane) | Pick how this tab arranges its panes |
layout-rotate | o (pane) | Move every pane one place along |
layout-save | Save this tab’s panes, and what they show, as a layout of the project | |
layout-save-mine | Save this tab’s panes, and what they show, as a layout for any project | |
layout-swap-main | alt-m (global, terminal), m (pane) | Swap this pane with the main one |
pane-close | w c, w q (after the leader), ctrl-w c, ctrl-w q (every style’s command mode) | Close this pane |
pane-close-done | x (pane) | pane-close, then back from the mode |
pane-down | alt-down, alt-j (global, terminal), w j (after the leader), down, j (pane), ctrl-w j (every style’s command mode) | Move to the pane below |
pane-file-down | w f (after the leader), ctrl-w f (every style’s command mode) | Open the file named under the cursor in a pane below |
pane-file-right | w F (after the leader), ctrl-w F (every style’s command mode) | Open the file named under the cursor in a pane on the right |
pane-grow | alt-+, alt-= (global, terminal), +, = (pane, resize) | Give this pane more room |
pane-left | alt-h, alt-left (global, terminal), w h (after the leader), h, left (pane), ctrl-w h (every style’s command mode) | Move to the pane on the left, or the tab before |
pane-mode | alt-p (global, terminal) | Keys for panes until esc: move, split, resize, close |
pane-mode-leave | alt-p (pane), enter, esc (pane, resize, tab), alt-r (resize), alt-t (tab) | Back from the pane or tab mode |
pane-new-down | w n s (after the leader), ctrl-w n s (every style’s command mode) | Open a pane below with a new, empty buffer |
pane-new-right | w n v (after the leader), ctrl-w n v (every style’s command mode) | Open a pane on the right with a new, empty buffer |
pane-next | w w (after the leader), tab (pane), ctrl-w w (every style’s command mode) | Move to the next pane |
pane-only | w o (after the leader), ctrl-w o (every style’s command mode) | Close every other pane in the tab |
pane-pick | w g (after the leader), g (pane), ctrl-w g (every style’s command mode) | Label the panes and go to the one whose label you type next; esc leaves the pane mode |
pane-place | p (pane) | Show where a new pane would go, to move it and open it there |
pane-place-cancel | esc (pane-place) | Put things back without a new pane |
pane-place-down | down, j (pane-place) | Move the new pane’s frame down |
pane-place-here | enter (pane-place) | Open a pane with this file where the frame is |
pane-place-left | h, left (pane-place) | Move the new pane’s frame left |
pane-place-right | l, right (pane-place) | Move the new pane’s frame right |
pane-place-terminal | t (pane-place) | Open a terminal where the frame is |
pane-place-up | k, up (pane-place) | Move the new pane’s frame up |
pane-resize-down | J (pane), j (resize) | Make this pane bigger by moving its bottom edge down, or the other edge at the screen’s edge |
pane-resize-left | H (pane), h (resize) | Make this pane bigger by moving its left edge out, or the other edge at the screen’s edge |
pane-resize-right | L (pane), l (resize) | Make this pane bigger by moving its right edge out, or the other edge at the screen’s edge |
pane-resize-up | K (pane), k (resize) | Make this pane bigger by moving its top edge up, or the other edge at the screen’s edge |
pane-right | alt-l, alt-right (global, terminal), w l (after the leader), l, right (pane), ctrl-w l (every style’s command mode) | Move to the pane on the right, or the tab after |
pane-shrink | alt-- (global, terminal), - (pane, resize) | Give this pane less room |
pane-shrink-down | J (resize) | Make this pane smaller by moving its bottom edge up, or the other edge at the screen’s edge |
pane-shrink-left | H (resize) | Make this pane smaller by moving its left edge in, or the other edge at the screen’s edge |
pane-shrink-right | L (resize) | Make this pane smaller by moving its right edge in, or the other edge at the screen’s edge |
pane-shrink-up | K (resize) | Make this pane smaller by moving its top edge down, or the other edge at the screen’s edge |
pane-split-down | w s (after the leader), s (pane), ctrl-w s (every style’s command mode) | Show this pane’s file in a new pane below |
pane-split-right | w v (after the leader), v (pane), ctrl-w v (every style’s command mode), ctrl-\ (vscode) | Show this pane’s file in a new pane on the right |
pane-swap-down | w J (after the leader), ctrl-w J (every style’s command mode) | Swap this pane with the one below |
pane-swap-left | w H (after the leader), ctrl-w H (every style’s command mode) | Swap this pane with the one on its left |
pane-swap-right | w L (after the leader), ctrl-w L (every style’s command mode) | Swap this pane with the one on its right |
pane-swap-up | w K (after the leader), ctrl-w K (every style’s command mode) | Swap this pane with the one above |
pane-terminal | alt-n (global, terminal), w t (after the leader), ctrl-w t (every style’s command mode) | Open a terminal in a new pane, or a floating one while floating views are shown |
pane-terminal-done | n (pane) | pane-terminal, then back from the mode |
pane-terminal-down | d (pane) | Open a terminal in a new pane below |
pane-terminal-right | r (pane) | Open a terminal in a new pane on the right |
pane-to-new-tab | Move this pane (or panel, or floating view) to a new tab | |
pane-to-new-tab-done | b (pane) | pane-to-new-tab, then back from the mode |
pane-to-panel | Move this pane (or floating view) into a panel on the right | |
pane-to-panel-done | P (pane) | pane-to-panel, then back from the mode |
pane-to-tab | Move this pane (or panel, or floating view) to a tab you pick, or a new one | |
pane-to-tab-done | t (pane) | pane-to-tab, then back from the mode |
pane-up | alt-k, alt-up (global, terminal), w k (after the leader), k, up (pane), ctrl-w k (every style’s command mode) | Move to the pane above |
pane-zoom | w z (after the leader), f (pane), ctrl-w z (every style’s command mode) | Show only this pane, or all of them again |
resize-mode | alt-r (global, terminal), R (pane) | Keys for resizing the pane or floating view until esc, and moving a float |
tab-close | Close this tab and its panes | |
tab-close-done | x (tab) | tab-close, then back from the mode |
tab-go | alt-1, alt-2, alt-3, alt-4, alt-5, alt-6, alt-7, alt-8, alt-9 (global, terminal) | Show tab N |
tab-mode | alt-t (global, terminal) | Keys for tabs until esc: new, close, switch, rename |
tab-new | Open a new tab | |
tab-new-done | n (tab) | tab-new, then back from the mode |
tab-next | alt->, alt-] (global, terminal), ], l, right (tab), g t (vim’s command mode) | Show the next tab; with a count, tab N, as Vim’s 3gt |
tab-previous | alt-<, alt-[ (global, terminal), [, h, left (tab), g T (vim’s command mode) | Show the tab before; with a count, that many tabs back |
tab-rename | Name this tab | |
tab-rename-done | r (tab) | tab-rename, then back from the mode |
tab-terminal | Open a new tab with a terminal | |
tab-terminal-done | t (tab) | tab-terminal, then back from the mode |
terminal-float | Show the floating terminal, or hide it |
| Option | Default | What it does |
|---|---|---|
float-layout | "free" | How new tabs lay out their floating views: “free”, “one”, “tiled”, “cascade” or your own |
pane-layout | "manual" | How new tabs arrange their panes: “manual”, “main-stack”, “columns”, “spiral” or your own |
PDF files open as their pages: one page at a time, drawn as wide as the
view (in terminals that show images, and in the window), or as the text
on every page, which reads anywhere and searches with /.
] [ next and previous page
+ - = bigger, smaller, as wide as the view
t pages or text
Uses: core.
| Command | Keys | What it does |
|---|---|---|
pdf-next-page | ] (in pdf buffers) | Show the next page of the PDF |
pdf-previous-page | [ (in pdf buffers) | Show the previous page of the PDF |
pdf-text | t (in pdf buffers) | Switch between the PDF’s pages and the text on them |
pdf-zoom-fit | = (in pdf buffers) | Draw the PDF’s page as wide as the view |
pdf-zoom-in | + (in pdf buffers) | Draw the PDF’s page bigger |
pdf-zoom-out | - (in pdf buffers) | Draw the PDF’s page smaller |
picker
Pickers: type to narrow a list down, then choose an item.
A picker is one floating buffer. Its first line is what you type; the lines below are the items that match, best first, with the current one highlighted. Move with up/down (or ctrl-n/ctrl-p), choose with enter, close with esc.
Other plugins open one with require("@self/picker").pick(...); see
pickers.luau for examples.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
act | . (after the leader), alt-. (vscode’s typing mode) | List what you can do with what’s under the cursor (a file, link, symbol, problem, change or the selection), and do it |
command-palette | ? (after the leader), ctrl-P (vscode) | Run any command by name |
pick-buffer | b (after the leader), ctrl-b (vscode) | Switch to an open file |
pick-file | f (after the leader), ctrl-p (vscode) | Open a file in the project, skipping ignored files |
pick-file-here | F (after the leader) | Open a file under the folder Greed was started in, skipping ignored files |
pick-jump | j (after the leader) | Pick a place from the jumplist and go there |
pick-outline | s (after the leader), g O (vim), ctrl-O (vscode) | Jump to a function or type in the file, from its syntax tree |
pick-style | Pick an editing style | |
picker-act | alt-. (in picker buffers) | List what you can do with the current item, and do it |
picker-choose | enter (in picker buffers) | Choose the current item and close the picker |
picker-close | esc (in picker buffers) | Close the picker without choosing |
picker-complete | tab (in picker buffers) | Put the current path in the picker’s query, to go on from there |
picker-key | Run what the open picker does for the key pressed | |
picker-next | ctrl-n, down (in picker buffers) | Move to the next item in the picker |
picker-prev | ctrl-p, up (in picker buffers) | Move to the previous item in the picker |
picker-resume | ' (after the leader) | Open the last picker again |
pipe
Pipe each selection through something and put back what comes out:
| ask what to pipe through
:pipe TARGET the same, from the command line
The target says what it is:
sort -u a shell command, given the selection as input
luau: snake_case a Luau function (see pipe.define)
model: use the new client API a language model, in the pipe-model role
Every selection gets its own result, and they all go in as one change, so one undo takes them back. A model’s changes are an operation too, to review with space u o; each result lands in its place even if you edit while the model works.
Uses: core, models, operations.
| Command | Keys | What it does |
|---|---|---|
append-output | alt-! (helix’s command mode) | Insert what a shell command prints after each selection |
insert-output | ! (helix’s command mode) | Insert what a shell command prints before each selection |
keep-pipe | $ (helix’s command mode) | Keep the selections a shell command succeeds on, given each as input |
pipe | | (helix’s command mode) | Pipe each selection through a shell command, a Luau filter (luau: name) or a model (model: what to do) |
pipe-to | alt-| (helix’s command mode) | Give each selection to a shell command as input, leaving the text as it is |
| Option | Default | What it does |
|---|---|---|
pipe-model-role | "fast" | The model role | model: ... asks; see :models |
plan
A plan and decisions you share with agents, as notes in the project’s
notes folder (.greed/notes, see the notes plugin), so they’re searched,
linked and in the agenda like any note.
The plan (project:plan) is an agent’s checklist where you can see and
change it: tick, reorder, add or delete items, and the agent reads what
you did. An agent replaces the whole plan when it writes, giving the
version it read, so it can’t write over changes you made since.
Decisions (project:decisions/*) are what you settled, kept across
sessions: “use sqlite”, “never touch the generated code”. Ones an agent
adds stay proposed until you accept them, and agents are told so, so an
agent can’t make itself rules the next one follows.
Uses: core, agent, picker, notes.
| Command | Keys | What it does |
|---|---|---|
decision-accept | Accept the proposed decision you’re in, so agents follow it | |
decision-new | Write down a decision for this project, kept for you and agents | |
decisions | Pick a decision kept for this project to open it | |
plan | Open the plan you share with agents, in the project’s notes |
projects
Projects: space P lists, in one picker, the projects open here, the
sessions running on this machine, recent projects, and the projects your
sources find. enter goes to one: it switches to it if it’s open or has a
session, and opens it in a session of its own if not. alt-enter opens it
in a new session even when one is running for it. A typed folder opens
too.
Sources are folders to look in and commands that print paths:
require("@projects").sources({
-- every folder one level under these
{ dirs = { "~/Development", "~/Work" } },
-- deeper, but only folders that look like projects
{ dirs = { "~/src" }, depth = 3, markers = { ".jj", ".git" } },
-- any command that prints one path per line
{ command = { "zoxide", "query", "-l" } },
})
Sources are looked at in the background, when the editor starts and each time the picker opens, and what they found last is kept, so the picker opens at once.
Uses: core, picker.
| Command | Keys | What it does |
|---|---|---|
pick-project | P (after the leader) | Go to a project: one open here, a running session, a recent one or one your sources find; or type a folder to open |
prose
Text objects for prose: select or move by sentence, paragraph and Markdown section.
m i p / m a p select the paragraph (a: with the blank lines after it)
m i s / m a s select the sentence (a: with the spaces after it)
m i h / m a h select the section under a heading (a: with the heading)
] p / [ p next / previous paragraph
] s / [ s next / previous sentence
Uses: core, markdown.
| Command | Keys | What it does |
|---|---|---|
next-paragraph | ] p (every style’s command mode) | Move to the start of the next paragraph |
next-sentence | ] s (every style’s command mode) | Move to the start of the next sentence |
prev-paragraph | [ p (every style’s command mode) | Move to the start of the paragraph, or the one before |
prev-sentence | [ s (every style’s command mode) | Move to the start of the sentence, or the one before |
select-paragraph | m i p (helix’s command mode) | Select the paragraph |
select-paragraph-around | m a p (helix’s command mode) | Select the paragraph and the blank lines after it |
select-section | m i h (helix’s command mode) | Select the text under the Markdown heading |
select-section-around | m a h (helix’s command mode) | Select the Markdown section, heading included |
select-sentence | m i s (helix’s command mode) | Select the sentence |
select-sentence-around | m a s (helix’s command mode) | Select the sentence and the spaces after it |
restore
Session restore: a session remembers its projects, the files open in
each and where the cursor was, and opens them again when it starts.
Written down when it quits and when a file is saved, per session name in
the cache, so it only works for editors running as a session (which
greed is, unless GREED_NO_SESSION is set).
Uses: core.
| Option | Default | What it does |
|---|---|---|
restore-session | true | Open the files a session had open when it starts again |
setup
Setting Greed up: the first time you start it without a config, a page
asks how you like to edit, which theme, whether your font has icons,
whether you use Claude Code and which language model to use. The page
is setup.md, a questionnaire in Markdown (see the markdown and blocks
plugins): a style or theme picked switches at once, and Save writes a
config from the answers and opens it, and has the model’s roles use the
provider picked. :setup brings the page back any time.
tab and shift-tab go from choice to choice and button to button, enter (or space) or a click picks one or presses it, and esc or q closes it as “Not now”.
Uses: core, theme, models, markdown, blocks.
| Command | Keys | What it does |
|---|---|---|
config-types | Set up type checking for your config: a .luaurc beside it that knows @greed and the plugins | |
setup | Answer a few questions to set Greed up: editing style, theme, icons, Claude Code, a model | |
setup-close | Close the setup page without saving; :setup brings it back | |
setup-next | Go to the next choice or button on the setup page | |
setup-prev | Go to the previous choice or button on the setup page | |
setup-save | Save the setup page’s answers as your config, and open it |
| Option | Default | What it does |
|---|---|---|
setup-first-start | true | Show the setup page the first time a terminal or window attaches without a config |
shell
A shell in a buffer: type a command at the prompt at the bottom, enter runs it, and it becomes a block above: the command, what it printed, and how it ended. Blocks stay to read, search, fold, copy and run again.
space o s switch to a shell, or open one (:shell opens a new one)
enter run what's at the prompt; on a block, edit its command
[ p ] p the block before or after the cursor
g o select the block's output
] e [ e the next or previous file:line the output names; enter opens it
ctrl-c interrupt the running block (vscode style: copy a selection)
ctrl-t type into the running block's program, in a terminal
space r run the block again, as it ran; space R here and now
space y/Y copy its output / its command
space x stop it; space v opens its whole output; space c clears
The shell runs cd, export, unset, env, history, clear,
open and help itself; every other line goes to a real shell, yours
(sh for an agent), whose cd and export carry over (fallback.luau). It
runs in a pseudo terminal (pty.luau), handed to a terminal when a
program wants one; an agent’s run through a pipe. Each shell has its own
folder and variables, and a project can have several.
$3 | sort, buf:NAME | ..., @sel | ... and @file | ... send block
3’s output, a buffer, the selection or the file you’re in to a command,
and ... > buf:NAME (>> adds) sends its output to a buffer
(data.luau). Output that’s JSON is kept as a value on the block, and a
table (kubectl get, docker ps, ps) as a table, which $3 | where ...,
select and sort work on (tables.luau). / filters what a block
shows, and space s sorts a table (rows.luau).
Agents run commands with shell_run and read blocks with shell_read (tools.luau).
Uses: core, picker, terminal.
| Command | Keys | What it does |
|---|---|---|
pick-running | o w (after the leader) | Pick among what runs in every shell, its output beside: enter opens it in a float, ctrl-o goes to it, ctrl-x stops it |
pick-shell | o s (after the leader) | Switch to a shell of this project, or open a new one |
shell | Open a new shell: a buffer of commands and what they printed | |
shell-accept-or-end | ctrl-e, end (every style’s typing mode; in shell buffers) | At the end of the prompt, take the rest of the command it suggests; elsewhere go to the end of the line |
shell-accept-or-right | right (every style’s typing mode; in shell buffers) | At the end of the prompt, take the rest of the command it suggests; elsewhere move right |
shell-clear | c (after the leader; in shell buffers) | Take the finished blocks out of the shell |
shell-copy-command | Y (after the leader; in shell buffers) | Copy the block’s command |
shell-copy-or-interrupt | ctrl-c (vscode’s typing mode; in shell buffers) | Copy the selection, or with nothing selected interrupt the running block |
shell-copy-output | y (after the leader; in shell buffers) | Copy what the block printed |
shell-edit | Put the block’s command at the prompt, to change and run again | |
shell-enter | enter (every style’s command mode, every style’s typing mode; in shell buffers) | Run what’s at the prompt; on a block, put its command at the prompt to edit, or on a row that’s a file or a pod, open or describe it |
shell-filter | / (every style’s command mode; in shell buffers), ctrl-f (vscode’s typing mode; in shell buffers) | Keep the lines of the block at the cursor with what’s typed in them (/ for a regex), or a table’s rows (COL=VALUE, COL~TEXT, COL>N); elsewhere, search |
shell-handoff | ctrl-t (every style’s command mode, every style’s typing mode; in shell buffers) | Show the running block’s program in a terminal, to type into it |
shell-history | ctrl-r (every style’s command mode, every style’s typing mode; in shell buffers) | Pick a command typed before, in any shell, to put at the prompt |
shell-history-back | up (every style’s typing mode; in shell buffers) | Put the command typed before at the prompt, one starting with what’s typed there |
shell-history-forward | down (every style’s typing mode; in shell buffers) | Put the command typed after at the prompt, or back to what was typed |
shell-interrupt | ctrl-c (every style’s command mode, every style’s typing mode; in shell buffers) | Interrupt the running block at the cursor, or the latest one, as ctrl-c does |
shell-kill | x (after the leader; in shell buffers) | Stop the running block at the cursor, or the latest one, for good |
shell-line | Run a command line in this project’s shell, opening one if there’s none, as :!cmd does | |
shell-next-block | ] p (every style’s command mode; in shell buffers), ctrl-down (vscode’s typing mode; in shell buffers) | Go to the block after the cursor, or the prompt |
shell-next-reference | ] e (every style’s command mode; in shell buffers), f8 (vscode’s typing mode; in shell buffers) | Go to the next file and line a block’s output names, like an error’s place; enter opens it |
shell-notify | Send a notification each time a watch’s rows change, saying how, while Greed isn’t focused; again to stop | |
shell-output-open | v (after the leader; in shell buffers) | Open the block’s whole output in a buffer of its own |
shell-peek | Open the block in a float, to filter it, act on its rows or stop it, and close it again with esc | |
shell-prev-block | [ p (every style’s command mode; in shell buffers), ctrl-up (vscode’s typing mode; in shell buffers) | Go to the block before the cursor |
shell-prev-reference | [ e (every style’s command mode; in shell buffers), shift-f8 (vscode’s typing mode; in shell buffers) | Go to the file and line a block’s output names before the cursor |
shell-rerun | r (after the leader; in shell buffers) | Run the block’s command again, in the folder and with the variables it had |
shell-rerun-here | R (after the leader; in shell buffers) | Run the block’s command again in the shell’s folder now |
shell-run | Run what’s at the prompt | |
shell-select-output | g o (every style’s command mode; in shell buffers) | Select the block’s output, to copy or search |
shell-show-all | S (after the leader; in shell buffers) | Show the block at the cursor’s output as it came, without a filter or a sort |
shell-sort | s (after the leader; in shell buffers) | Sort the table at the cursor by the column under it; again to reverse, a third time as it came |
shell-unfilter | esc (every style’s command mode; in shell buffers) | Show every line, or row, of the filtered block at the cursor again, keeping its sort; in a block’s float, close it |
| Option | Default | What it does |
|---|---|---|
shell-agent-max-output | 30000 | How many bytes of a command’s output and of its errors the shell tools give an agent: the start and the end, with what’s between left out |
shell-aliases | true | Whether a line can start with one of your shell’s aliases, read once from its startup files |
shell-ask-role | "fast" | The model role a line ending or starting with ? asks for a command; see :models |
shell-completion-sources | "cobra fish carapace man help" | Where a shell completes a program’s arguments from, in order: cobra, fish, carapace, man, help |
shell-completion-timeout | 2000 | Milliseconds a program asked for completions (kubectl, fish, carapace, –help) gets to answer |
shell-confirm-lines | 5 | Running a prompt of more lines than this asks first, as after pasting a transcript |
shell-editor | true | Whether programs you run in a shell, like git commit, open files to edit in Greed: $EDITOR, $VISUAL, $GIT_EDITOR, $JJ_EDITOR and $KUBE_EDITOR are greed edit –wait |
shell-environments | "devenv direnv" | Which environments a shell loads in folders that bring one, in order, the first that applies winning: devenv, direnv, and those plugins add; empty for none |
shell-fallback | "" | The shell that runs lines with pipes, globs and the like, e.g. “bash”; empty for your $SHELL (sh unless it’s sh, bash, zsh, dash, ksh, fish or nu) |
shell-fallback-rc | false | Whether the shell running those lines reads its startup files (-i), for your aliases and functions |
shell-fold-lines | 0 | A block that printed more lines than this folds as it ends, unless it failed; 0 never |
shell-fold-older | false | Running a command folds the finished blocks above it, except those that failed |
shell-help-completion | "on-flag" | When a shell runs a program with –help to complete its flags: on-flag (when you press tab on one) or never |
shell-help-never | "reboot shutdown halt poweroff init telinit kill killall pkill" | Programs a shell never runs with –help to complete their flags |
shell-history-size | 5000 | How many commands typed at shells are kept |
shell-icons | "plain" | The icons of a shell’s own segments: “plain” ones any font has, or “nerd” ones a Nerd Font has |
shell-max-lines | 5000 | How many lines of a block’s output a shell shows: the first half and the latest half |
shell-max-record | 8388608 | How many bytes of a block’s output its record keeps; the rest goes to a file in the cache folder |
shell-production-contexts | "prod" | Patterns for kubernetes contexts a shell’s prompt warns about, like prod; space between them |
shell-prompt | "greed" | What draws a shell’s prompt before its ❯: “greed” (its own segments and folder) or “starship” (your starship prompt, when starship is installed) |
shell-suggestions | true | Whether a shell’s prompt suggests the rest of a command typed before, after the cursor |
shell-watch-minutes | 60 | How long a shell’s watch runs before it stops by itself, in minutes; 0 for until it’s stopped |
statusline
The status line: on the left the mode, the tab, the file (or the latest message) and whether keys are being recorded; on the right the branch, problems, the language and its server, the editing style (dim), anything unusual about the file, how many selections there are, where the cursor is, the machine and the session. With the statusline-pills option some are pills, with rounded ends drawn in the theme’s colors, and with the effects option light goes through the tab or the file when you go to another, and the mode when it changes.
Add to it from your config, or take a piece away:
local statusline = require("@statusline")
statusline.add("right", "clock", function() return os.date("%H:%M") end)
statusline.remove("host")
greed.statusline with a function of your own replaces it all; the last
one set wins.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
messages | Show the last messages in full, newest last |
| Option | Default | What it does |
|---|---|---|
statusline-caps | "round" | The ends of status line pills: “round” (needs a Nerd Font) or “none” |
statusline-pills | false | Show the mode, tab, machine and session in the status line as pills in their colors |
terminal
Terminals: a shell, or any program, in a buffer. :terminal [command]
opens one in the main view and sends it every key; ctrl-\ goes back to
the editing style’s mode, where the output is text to select, search
and copy, and i or enter types into the program again.
The buffer holds the lines that scrolled off the top, then the screen. Output replaces the screen part and adds what scrolled off above it.
Uses: core, picker.
| Command | Keys | What it does |
|---|---|---|
open-link | g x (in terminal buffers) | Open the link under the cursor, or the file it names, at the line it says |
pick-terminal | t (after the leader) | Switch to a terminal, or open a new one |
task | o t (after the leader) | Run a task, like the project’s build or tests, in a terminal that stays open; without a name, pick one |
terminal | Open a terminal running a command, or your shell | |
terminal-close | End the terminal’s program and close it | |
terminal-esc | esc (terminal) | Send esc to the terminal’s program; a second one quickly after stops typing into it |
terminal-input | a, enter, i (in terminal buffers) | Type into the terminal’s program |
terminal-key | Send the key to the terminal’s program | |
terminal-leader | ctrl-space (terminal) | Stop typing into the terminal and open the leader, for the keys after it |
terminal-leave | ctrl-\ (terminal) | Stop typing into the terminal, to move around its output |
terminal-next-command | ] p (in terminal buffers) | Go to the command after the cursor in a terminal, where its shell marks commands |
terminal-next-reference | ] e (in terminal buffers) | Go to the next file and line the output names, like an error’s place; g x opens it |
terminal-paste | p (in terminal buffers) | Paste the latest copy into the terminal’s program |
terminal-prev-command | [ p (in terminal buffers) | Go to the command before the cursor in a terminal, where its shell marks commands |
terminal-prev-reference | [ e (in terminal buffers) | Go to the file and line the output names before the cursor |
terminal-references | d (after the leader; in terminal buffers) | Pick from the files and lines the output names, like a compiler’s errors, to open one |
terminal-select-output | g o (in terminal buffers) | Select the output of the command at the cursor in a terminal, to copy or search |
terminal-send | T (after the leader) | Send the selection, or the cursor’s line, to the terminal you used last, and run it |
| Option | Default | What it does |
|---|---|---|
terminal-scrollback | 10000 | How many lines that scrolled off a terminal’s screen are kept |
terminal-shell | "" | What a new terminal runs, e.g. “fish -l”; empty for your $SHELL |
theme
Themes: what every style name looks like. Greed comes with the default (the terminal’s 16 colors) and the usual ones from other editors: Nord, Dracula, Catppuccin, Gruvbox, Tokyo Night, One Dark and more.
:theme NAME switch to a theme
:theme pick one, trying each as you move; esc goes back
The theme picked is remembered (in the cache folder) until you pick another. To set it from your config, or define your own:
local theme = require("@theme")
theme.use("nord")
theme.define("mine", {
palette = { bg = "#101418", ... }, -- see palette.luau
styles = { comment = { fg = "#5c6773" } },
})
theme.define("nord-bold", { inherits = "nord", styles = { keyword = { bold = true } } })
A theme is the base under greed.theme.set: entries set that way, from
your config or a plugin, stay on top whichever theme is in use.
Uses: picker, cmdline.
| Command | Keys | What it does |
|---|---|---|
theme | ctrl-k ctrl-t (vscode) | Switch to a theme, or pick one trying each as you move |
tree
A file tree in a side panel. space e opens it (or moves to it, or closes
it if you’re in it). In the tree: enter or l opens a file or folds a
folder, h folds the folder you’re in, r reads the disk again, q closes;
a makes a file (or a folder, ending in /), R renames, d deletes.
Hidden and ignored files are left out, like in the file picker.
It’s only a plugin: to turn it off, greed.plugin.unload("tree") from your
config.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
tree | e (after the leader) | Open the file tree, move to it, or close it if you’re in it |
tree-add | a (in tree buffers) | Make a file in the folder on the cursor, or a folder with a / at the end |
tree-close | q (in tree buffers) | Close the file tree |
tree-delete | d (in tree buffers) | Delete the file or folder on the cursor, after you press y |
tree-fold | h (in tree buffers) | Fold the folder on the cursor, or the one it’s in |
tree-open | enter, l (in tree buffers) | Open the file on the cursor, or fold or unfold the folder |
tree-refresh | r (in tree buffers) | Read the tree from the disk again |
tree-rename | R (in tree buffers) | Rename or move the file or folder on the cursor; open files go along |
| Option | Default | What it does |
|---|---|---|
tree-icons | "none" | Icons by the names in the file tree: “none”, or “nerd” for a Nerd Font’s |
tutor
The tutor: :tutor opens tutor.md, a page to read and edit with the
keys of your editing style. It asks which style first, switches to the one
picked, and shows each lesson’s keys for it, with <!-- if style=... -->
parts (see the markdown plugin’s questions).
A lesson’s exercise is a practice block followed by a want block, the
text it should become. The tutor hides the want block and marks the
practice block done once its text matches. The want block’s options give
each style’s keys for it (vim="w d w"); the tests press them, so the
keys the page teaches are known to work.
Uses: core, markdown, blocks.
| Command | Keys | What it does |
|---|---|---|
tutor | Learn to edit with your editing style’s keys, and get around Greed |
undo-tree
The undo tree, like Emacs’s vundo: every state the text has been in, the
branches an undo followed by an edit left behind included. space u t
shows it; moving up and down takes the text to that state as you go,
enter keeps it, and esc goes back to where you were.
○ 0 loaded
○ 1 3m
│ ○ 2 2m a branch left behind
● 3 now where the text is
The newest branch of each state carries on below it; older ones are indented under it.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
undo-tree | u t (after the leader) | Show every state the file has been in, branches included, and go to one |
undo-tree-cancel | esc (in undo-tree buffers) | Close the undo tree and put the text back as it was |
undo-tree-down | down, j (in undo-tree buffers) | Go to the next state down the undo tree |
undo-tree-keep | enter, q (in undo-tree buffers) | Close the undo tree, keeping the text as it is |
undo-tree-up | k, up (in undo-tree buffers) | Go to the next state up the undo tree |
vcs
Version control: signs beside lines added (+), changed (~) and removed (-) since the last commit, with jj, or git where there’s no .jj.
] g / [ g next / previous change; ] G / [ G the last and first
m i g the change under the cursor; m a g its lines
space g r put the change under the cursor back the way it was
space g b who last changed this line, and when
space g s every change since the last commit, in one multibuffer
space u c commit just the latest operation's files, named after it
space g a stage the change under the cursor (git)
space g S what's staged (git), to unstage hunks and commit
With jj the comparison is with the working copy’s parent (@-), so the signs show what the change you’re working on does to the file. With git it’s with what’s staged, so staged changes lose their signs.
Uses: core, agent, multibuffer, operations, picker, statusline.
| Command | Keys | What it does |
|---|---|---|
blame-line | g b (after the leader) | Show who last changed the line under the cursor, and when |
change-diff-close | q (in change-diff buffers) | Go back to the change stack |
change-stack | g l (after the leader) | Show the changes from the last pushed one to the working copy, to describe, squash, move or abandon |
change-stack-abandon | a (in change-stack buffers) | Abandon it, after asking |
change-stack-close | q (in change-stack buffers) | Close the stack and go back to what was shown before |
change-stack-describe | d (in change-stack buffers) | Describe the change |
change-stack-down | alt-j (in change-stack buffers) | Move it below the change below it |
change-stack-edit | e (in change-stack buffers) | Make it the working copy, to edit it |
change-stack-menu | ? (in change-stack buffers) | List the change stack’s keys and pick one |
change-stack-new | n (in change-stack buffers) | Start a new change on top of it |
change-stack-refresh | r (in change-stack buffers) | Read the stack again |
change-stack-show | enter (in change-stack buffers) | Show the change’s diff |
change-stack-split | S (in change-stack buffers) | Split it: pick the hunks that go in a change of their own before it |
change-stack-squash | s (in change-stack buffers) | Squash it into its parent, keeping the parent’s description |
change-stack-undo | u (in change-stack buffers) | Undo the last jj operation |
change-stack-up | alt-k (in change-stack buffers) | Move it above the change above it |
changes | g s (after the leader) | Show every change since the last commit in one buffer, to read, edit or put back |
first-change | [ G (every style’s command mode) | Go to the first change since the last commit |
hunk-picker-all | a (in hunk-picker buffers) | Pick every hunk, or none if all are picked |
hunk-picker-cancel | esc, q (in hunk-picker buffers) | Put back what was shown, picking nothing |
hunk-picker-done | enter (in hunk-picker buffers) | Go on with the hunks picked |
hunk-picker-toggle | space (in hunk-picker buffers) | Pick the hunk under the cursor, or put it back, and go to the next |
last-change | ] G (every style’s command mode) | Go to the last change since the last commit |
next-change | ] g (every style’s command mode) | Go to the next change since the last commit |
operation-commit | u c (after the leader) | Save the files of the latest operation (or the one being reviewed) and commit just them, named after it |
pick-changed-file | g g (after the leader) | Open a file changed since the last commit |
prev-change | [ g (every style’s command mode) | Go to the previous change since the last commit |
revert-change | g r (after the leader) | Put the change under the cursor back the way it was at the last commit |
select-around-change | m a g (helix’s command mode) | Select the lines of the change since the last commit under the cursor |
select-inside-change | m i g (helix’s command mode) | Select the text of the change since the last commit under the cursor |
stage-change | g a (after the leader) | Stage the change under the cursor for the next git commit, leaving the rest |
staged | g S (after the leader) | Show what’s staged for the next git commit, to unstage hunks or commit |
staged-commit | c (in staged-diff buffers) | Commit what’s staged |
staged-refresh | r (in staged-diff buffers) | Read what’s staged again |
staged-unstage | u (in staged-diff buffers) | Unstage the hunk under the cursor |
why-lines | g w (after the leader) | Show how the selected lines came to be: each change that made them, with its description and diff |
| Option | Default | What it does |
|---|---|---|
vcs-signs | true | Show signs beside lines changed since the last commit |
vim
Vim-style editing, written only against the plugin API. It has modes of
its own (vim, vim-insert, vim-replace and the three visual modes), beside
Helix’s, and says which plays each role: keys other plugins bind for the
command role (the language server’s, the next change) and the leader
(space) work here as in every style.
Switch to it with :style vim, or put this in ~/.config/greed/init.luau:
require("@greed").option.set("editing-style", "vim")
It reads in this order: common.luau, text helpers; motions.luau, the
motions (one table, each saying how an operator takes its range) and
marks; objects.luau, ranges and text objects; operators.luau, operators
applied through apply and the line and case tables; visual.luau, the
visual modes (block mode keeps a selection per line), with the commands
for motions and operators; then this file, with insert, replace, the
change list and U; keys.luau last. Ex commands (:s, :g, ranges) are the
command line plugin’s, and . is core’s.
Uses: core.
| Command | Keys | What it does |
|---|---|---|
vim-append | a (vim) | Insert after the cursor |
vim-append-line-end | A (vim) | Insert at the end of the line |
vim-block-append | A (vim-visual-block) | Type after the block on each of its lines |
vim-block-insert | I (vim-visual-block) | Type before the block on each of its lines |
vim-change-line | S (vim) | Change the whole line |
vim-change-newer | g , (vim) | Go to a newer place in the change list |
vim-change-older | g ; (vim) | Go to an older place in the change list |
vim-change-to-end | C (vim) | Change to the end of the line |
vim-command-line | : (vim, vim-visual) | Open the command line, with the selected lines (or the count’s) as its range |
vim-decrement | ctrl-x (vim) | Subtract the count (or 1) from the number at or after the cursor |
vim-delete-char | x (vim) | Delete the character under the cursor |
vim-delete-char-before | X (vim) | Delete the character before the cursor |
vim-delete-to-end | D (vim) | Delete to the end of the line |
vim-expand-selection | alt-o (vim, vim-visual) | Select the syntax node around the cursor or selection, in visual mode |
vim-increment | ctrl-a (vim) | Add the count (or 1) to the number at or after the cursor |
vim-insert | i (vim) | Insert before the cursor |
vim-insert-last | g i (vim) | Insert where insert mode was last left |
vim-insert-line-start | I (vim) | Insert at the first non-blank of the line |
vim-insert-one | ctrl-o (vim-insert) | Run one normal mode command, then go on typing |
vim-join | J (vim) | Join the next line onto this one, with one space |
vim-join-raw | g J (vim) | Join the next line onto this one as it is |
vim-jump-to-word | g s (vim) | Label every word on screen and jump to the one typed |
vim-macro | q (vim) | Record a macro into the register typed next, or stop recording |
vim-mark | m (vim) | Set the mark typed next (a to z here, A to Z across files) at the cursor |
vim-motion-$ | $ (vim, vim-visual) | Vim motion $ |
vim-motion-% | % (vim, vim-visual) | Vim motion % |
vim-motion-' | ' (vim, vim-visual) | Vim motion ’ |
vim-motion-( | ( (vim, vim-visual) | Vim motion ( |
vim-motion-) | ) (vim, vim-visual) | Vim motion ) |
vim-motion-+ | + (vim, vim-visual) | Vim motion + |
vim-motion-, | , (vim, vim-visual) | Vim motion , |
vim-motion-- | - (vim, vim-visual) | Vim motion - |
vim-motion-0 | 0 (vim, vim-visual) | Vim motion 0 |
vim-motion-; | ; (vim, vim-visual) | Vim motion ; |
vim-motion-B | B (vim, vim-visual) | Vim motion B |
vim-motion-E | E (vim, vim-visual) | Vim motion E |
vim-motion-F | F (vim, vim-visual) | Vim motion F |
vim-motion-G | G (vim, vim-visual) | Vim motion G |
vim-motion-H | H (vim, vim-visual) | Vim motion H |
vim-motion-L | L (vim, vim-visual) | Vim motion L |
vim-motion-M | M (vim, vim-visual) | Vim motion M |
vim-motion-T | T (vim, vim-visual) | Vim motion T |
vim-motion-W | W (vim, vim-visual) | Vim motion W |
vim-motion-^ | ^ (vim, vim-visual) | Vim motion ^ |
vim-motion-_ | _ (vim, vim-visual) | Vim motion _ |
| `vim-motion-`` | ``` (vim, vim-visual) | Vim motion ` |
vim-motion-b | b (vim, vim-visual) | Vim motion b |
vim-motion-e | e (vim, vim-visual) | Vim motion e |
vim-motion-f | f (vim, vim-visual) | Vim motion f |
vim-motion-gE | g E (vim, vim-visual) | Vim motion g E |
vim-motion-g_ | g _ (vim, vim-visual) | Vim motion g _ |
vim-motion-ge | g e (vim, vim-visual) | Vim motion g e |
vim-motion-gg | g g (vim, vim-visual) | Vim motion g g |
vim-motion-h | h (vim, vim-visual) | Vim motion h |
vim-motion-j | j (vim, vim-visual) | Vim motion j |
vim-motion-k | k (vim, vim-visual) | Vim motion k |
vim-motion-l | l (vim, vim-visual) | Vim motion l |
vim-motion-t | t (vim, vim-visual) | Vim motion t |
vim-motion-w | w (vim, vim-visual) | Vim motion w |
vim-motion-{ | { (vim, vim-visual) | Vim motion { |
| `vim-motion- | ` | | (vim, vim-visual) |
vim-motion-} | } (vim, vim-visual) | Vim motion } |
vim-multi-append | A, a (vim-multi) | Type after every selection |
vim-multi-back | ctrl-p (vim-multi) | Drop the match added last |
vim-multi-change | c, s (vim-multi) | Delete every selection and type in each place |
vim-multi-copy | y (vim-multi) | Copy every selection |
vim-multi-delete | d, x (vim-multi) | Delete every selection |
vim-multi-insert | I, i (vim-multi) | Type before every selection |
vim-multi-next | ctrl-n (vim, vim-multi) | Select the word under the cursor, or add its next match |
vim-multi-skip | ctrl-x (vim-multi) | Drop this match and add the next one instead |
vim-normal | esc (vim-insert, vim-multi, vim-visual), V, v (vim-visual), ctrl-v (vim-visual-block) | Back to normal mode |
vim-open-above | O (vim) | Open a line above and insert |
vim-open-below | o (vim) | Open a line below and insert |
vim-operator-! | ! (vim, vim-visual) | Vim operator !, followed by a motion |
vim-operator-< | < (vim, vim-visual) | Vim operator <, followed by a motion |
vim-operator-= | = (vim, vim-visual) | Vim operator =, followed by a motion |
vim-operator-> | > (vim, vim-visual) | Vim operator >, followed by a motion |
vim-operator-c | c (vim, vim-visual) | Vim operator c, followed by a motion |
vim-operator-d | d (vim, vim-visual), x (vim-visual) | Vim operator d, followed by a motion |
vim-operator-g? | g ? (vim, vim-visual) | Vim operator g?, followed by a motion |
vim-operator-gU | g U (vim), U (vim-visual) | Vim operator gU, followed by a motion |
vim-operator-gc | g c (vim, vim-visual) | Vim operator gc, followed by a motion |
vim-operator-gq | g q (vim, vim-visual) | Vim operator gq, followed by a motion |
vim-operator-gu | g u (vim), u (vim-visual) | Vim operator gu, followed by a motion |
vim-operator-gw | g w (vim) | Vim operator gw, followed by a motion |
vim-operator-g~ | g ~ (vim, vim-visual), ~ (vim-visual) | Vim operator g~, followed by a motion |
vim-operator-y | y (vim, vim-visual) | Vim operator y, followed by a motion |
vim-operator-zf | z f (vim, vim-visual) | Vim operator zf, followed by a motion |
vim-paste-after | p (vim) | Paste after the cursor, or below the line |
vim-paste-before | P (vim) | Paste before the cursor, or above the line |
vim-play-macro | @ (vim) | Play the macro in the register typed next; @@ plays the last one again |
vim-quit-unsaved | Z Q (vim) | Close without saving (ZQ) |
vim-redo | ctrl-r (vim) | Redo |
vim-replace-back | backspace (vim-replace) | Put back the character typed over last, or move left |
vim-replace-char | r (vim) | Replace the character under the cursor with the next one typed |
vim-replace-mode | R (vim) | Type over the text |
vim-replace-typed | Type over the character under the cursor | |
vim-reselect | g v (vim) | Select the last visual selection again |
vim-search-word | * (vim) | Search for the word under the cursor |
vim-search-word-back | # (vim) | Search for the word under the cursor |
vim-select-match | g n (vim) | Select the search match under the cursor, or the next one |
vim-shrink-selection | alt-i (vim, vim-visual) | Shrink the selection back, or to the first syntax node inside it |
vim-substitute | s (vim) | Change the character under the cursor |
vim-switch-case | ~ (vim) | Switch the case of the character under the cursor and move on |
vim-undo | u (vim) | Undo |
vim-undo-line | U (vim) | Put back the line last changed as it was before (U) |
vim-visual | v (vim) | Select characters, starting here |
vim-visual-around | a (vim-visual) | Select around the text object typed next |
vim-visual-block | ctrl-v (vim, vim-visual) | Select a block of columns across lines |
vim-visual-inside | i (vim-visual) | Select inside the text object typed next |
vim-visual-join | J (vim-visual) | Join the selected lines, with one space |
vim-visual-line | V (vim) | Select whole lines, starting with this one |
vim-visual-paste | P, p (vim-visual) | Replace the selection with what’s in the register |
vim-visual-replace | r (vim-visual) | Replace every selected character with the next one typed |
vim-visual-surround | S (vim-visual) | Wrap the selection in the pair typed next |
vim-visual-swap | o (vim-visual) | Go to the other end of the selection |
vscode
The vscode style: no modes, VS Code’s keys. Typing inserts text (replacing any selection), arrows move, shift and the arrows select, and the usual ctrl shortcuts do the usual things. The editing itself is core’s (core/modeless.luau), shared with any other style without modes; this plugin gives it VS Code’s keys.
Switch to it with :style vscode, or to use it all the time, put this in
~/.config/greed/init.luau:
require("@greed").option.set("editing-style", "vscode")
Uses: core, picker.