- Overview
- Variables
- $edit:-dot
- $edit:-instant:binding
- $edit:-prompt-eagerness
- $edit:-rprompt-eagerness
- $edit:abbr
- $edit:add-cmd-filters
- $edit:after-command
- $edit:after-readline
- $edit:before-readline
- $edit:command-abbr
- $edit:command-duration
- $edit:command:binding
- $edit:completion:arg-completer
- $edit:completion:binding
- $edit:completion:matcher
- $edit:current-command
- $edit:exceptions
- $edit:global-binding
- $edit:histlist:binding
- $edit:history:binding
- $edit:insert:binding
- $edit:insert:quote-paste
- $edit:lastcmd:binding
- $edit:listing:binding
- $edit:location:binding
- $edit:location:hidden
- $edit:location:pinned
- $edit:location:workspaces
- $edit:max-height
- $edit:navigation:binding
- $edit:navigation:selected-file
- $edit:navigation:width-ratio
- $edit:prompt
- $edit:prompt-stale-threshold
- $edit:prompt-stale-transformer.
- $edit:rprompt
- $edit:rprompt-persistent
- $edit:rprompt-stale-threshold
- $edit:rprompt-stale-transformer.
- $edit:small-word-abbr
- Functions
- edit:-instant:start
- edit:add-var
- edit:add-vars
- edit:apply-autofix
- edit:binding-table
- edit:clear
- edit:close-mode
- edit:command-history
- edit:command:start
- edit:complete-dirname
- edit:complete-filename
- edit:complete-getopt
- edit:completion:smart-start
- edit:completion:start
- edit:complex-candidate
- edit:del-var
- edit:del-vars
- edit:end-of-history
- edit:histlist:start
- edit:histlist:toggle-dedup
- edit:history:accept
- edit:history:down
- edit:history:down-or-quit
- edit:history:fast-forward
- edit:history:start
- edit:history:up
- edit:insert-at-dot
- edit:insert-last-word
- edit:insert-raw
- edit:key
- edit:kill-alnum-word-left
- edit:kill-alnum-word-right
- edit:kill-line-left
- edit:kill-line-right
- edit:kill-rune-left
- edit:kill-rune-left
- edit:kill-small-word-left
- edit:kill-small-word-right
- edit:kill-word-left
- edit:kill-word-right
- edit:lastcmd:start
- edit:listing:accept
- edit:listing:down
- edit:listing:down-cycle
- edit:listing:page-down
- edit:listing:page-up
- edit:listing:start-custom
- edit:listing:up
- edit:listing:up-cycle
- edit:match-prefix
- edit:match-subseq
- edit:match-substr
- edit:move-dot-down
- edit:move-dot-eol
- edit:move-dot-left
- edit:move-dot-left-alnum-word
- edit:move-dot-left-small-word
- edit:move-dot-left-word
- edit:move-dot-right
- edit:move-dot-right-alnum-word
- edit:move-dot-right-small-word
- edit:move-dot-right-word
- edit:move-dot-sol
- edit:move-dot-up
- edit:navigation:insert-selected
- edit:navigation:insert-selected-and-quit
- edit:navigation:start
- edit:navigation:trigger-filter
- edit:navigation:trigger-shown-hidden
- edit:notify
- edit:redraw
- edit:replace-input
- edit:return-eof
- edit:return-line
- edit:smart-enter
- edit:toggle-quote-paste
- edit:transpose-alnum-word
- edit:transpose-rune
- edit:transpose-small-word
- edit:transpose-word
- edit:wordify
The edit:
module is the interface to the Elvish editor.
Function usages are given in the same format as in the reference for the builtin module.
This document is incomplete.
Overview
Modes and Submodules
The Elvish editor has different modes, and exactly one mode is active at the same time. Each mode has its own UI and keybindings. For instance, the default insert mode lets you modify the current command. The completion mode (triggered by Tab by default) shows you all candidates for completion, and you can use arrow keys to navigate those candidates.
~/elvish> vim 1.0-release.md elf@host
COMPLETING argument
1.0-release.md README.md syntaxes/
CONTRIBUTING.md SECURITY.md tools/
Dockerfile cmd/ vscode/
LICENSE go.mod website/
Makefile go.sum
PACKAGING.md pkg/
Each mode has its own submodule under edit:
. For instance, builtin functions
and configuration variables for the completion mode can be found in the
edit:completion:
module.
The primary modes supported now are insert
, command
, completion
,
navigation
, history
, histlist
, location
, and lastcmd
. The last 4 are
“listing modes”, and their particularity is documented below.
Prompts
Elvish has two prompts: the (normal) left-hand prompt and the right-side prompt
(rprompt). Most of this section only documents the left-hand prompt, but API for
rprompt is the same other than the variable name: just replace prompt
with
rprompt
.
To customize the prompt, assign a function to edit:prompt
. The function may
write value outputs or byte outputs:
-
Value outputs may be either strings or
styled
values; they are joiend with no spaces in between. -
Byte outputs are output as-is, including any newlines. Any SGR escape sequences included in the byte outputs will be parsed, but any other escape sequences or control character will be removed.
If you mix value and byte outputs, the order in which they appear is non-deterministic.
Prefer using styled
to output styled text; the support for SGR escape
sequences is mostly for compatibility with external cross-shell prompts.
The default prompt and rprompt are equivalent to:
set edit:prompt = { tilde-abbr $pwd; put '> ' }
set edit:rprompt = (constantly (styled (whoami)@(hostname) inverse))
Some more examples:
~> set edit:prompt = { tilde-abbr $pwd; styled '> ' green }
~> # ">" is now green
~> set edit:prompt = { echo '$' }
$
# Cursor will be on the next line as `echo` outputs a trailing newline
Stale Prompt
Elvish never waits for the prompt function to finish. Instead, the prompt function is always executed on a separate thread, and Elvish updates the screen when the function finishes.
However, this can be misleading when the function is slow: this means that the prompt on the screen may not contain the latest information. To deal with this, if the prompt function does not finish within a certain threshold - by default 0.2 seconds, Elvish marks the prompt as stale: it still shows the old stale prompt content, but transforms it using a stale transformer. The default stale transformer applies reverse-video to the whole prompt.
The threshold is customizable with $edit:prompt-stale-threshold
; it specifies
the threshold in seconds.
The transformer is customizable with $edit:prompt-stale-transform
. It is a
function; the function is called with one argument, a styled
text, and the
output is interpreted in the same way as prompt functions. Some examples are:
# The following effectively disables marking of stale prompt.
set edit:prompt-stale-transform = {|x| put $x }
# Show stale prompts in inverse; equivalent to the default.
set edit:prompt-stale-transform = {|x| styled $x inverse }
# Gray out stale prompts.
set edit:prompt-stale-transform = {|x| styled $x bright-black }
To see the transformer in action, try the following example (assuming default
$edit:prompt-stale-transform
):
var n = 0
set edit:prompt = { sleep 2; put $n; set n = (+ $n 1); put ': ' }
set edit:-prompt-eagerness = 10 # update prompt on each keystroke
set edit:prompt-stale-threshold = 0.5
And then start typing. Type one character; the prompt becomes inverse after 0.5 second: this is when Elvish starts to consider the prompt as stale. The prompt will return normal after 2 seconds, and the counter in the prompt is updated: this is when the prompt function finishes.
Another thing you will notice is that, if you type a few characters quickly (in less than 2 seconds, to be precise), the prompt is only updated twice. This is because Elvish never does two prompt updates in parallel: prompt updates are serialized. If a prompt update is required when the prompt function is still running, Elvish simply queues another update. If an update is already queued, Elvish does not queue another update. The reason why exactly two updates happen in this case, and how this algorithm ensures freshness of the prompt is left as an exercise to the reader.
Prompt Eagerness
The occasions when the prompt should get updated can be controlled with
$edit:-prompt-eagerness
:
-
The prompt is always updated when the editor becomes active – when Elvish starts, or a command finishes execution, or when the user presses Enter.
-
If
$edit:-prompt-eagerness
>= 5, it is updated when the working directory changes. -
If
$edit:-prompt-eagerness
>= 10, it is updated on each keystroke.
The default value is 5.
RPrompt Persistency
By default, the rprompt is only shown while the editor is active: as soon as you
press Enter, it is erased. If you want to keep it, simply set
$edit:rprompt-persistent
to $true
:
set edit:rprompt-persistent = $true
Keybindings
Each mode has its own keybinding, accessible as the binding
variable in its
module. For instance, the binding table for insert mode is
$edit:insert:binding
. To see current bindings, simply print the binding table:
pprint $edit:insert:binding
(replace insert
with any other mode).
The global key binding table, $edit:global-binding
is consulted when a key is
not handled by the active mode.
A binding tables is simply a map that maps keys to functions. For instance, to
bind Alt-x
in insert mode to exit Elvish, simply do:
set edit:insert:binding[Alt-x] = { exit }
Outputs from a bound function always appear above the Elvish prompt. You can see this by doing the following:
set edit:insert:binding[Alt-x] = { echo 'output from a bound function!' }
and press Alt-x in insert mode. It allows you to put debugging outputs in bound functions without messing up the terminal.
Internally, this is implemented by connecting their output to a pipe. This does
the correct thing in most cases, but if you are sure you want to do something to
the terminal, redirect the output to /dev/tty
. Since this will break Elvish’s
internal tracking of the terminal state, you should also do a full redraw with
edit:redraw &full=$true
. For instance, the following binds Ctrl-L
to clearing the terminal:
set edit:insert:binding[Ctrl-L] = { clear > /dev/tty; edit:redraw &full=$true }
(The same functionality is already available as a builtin, edit:clear
.)
Bound functions have their inputs redirected to /dev/null.
Format of Keys
A key consists of a key name, preceded by zero or more key modifiers. Both are case-sensitive.
The key name may be either:
-
A simple character, such as
x
.Most of the time you should use the lower-case form of letters, except for Ctrl- bindings, which usually require the upper-case form (so
Alt-x
butCtrl-X
). This quirk may go away in future. -
A function key from these symbols:
F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Up Down Right Left Home Insert Delete End PageUp PageDown Tab Enter Backspace
Among these,
Tab
andEnter
are equivalent to their ASCII counterparts"\t"
and"\n"
.
Key modifiers are one of the following:
A Alt
C Ctrl
M Meta
S Shift
Modifiers end with either a -
or +
, and can be stacked. Examples:
-
S-F1
-
Ctrl-X
or -
Alt+Enter
-
C+A-X
.
Note: The Shift
modifier is only applicable to function keys such as F1
.
You cannot write Shift-m
as a synonym for M
.
You may not actually be able to use the full range of possible keys for several reasons:
-
Some
Ctrl-[letter]
keys have special functions, likeCtrl-C
,Ctrl-Z
,Ctrl-S
andCtrl-Z
. -
Some
Ctrl-[letter]
keys are equivalent to single keypresses, likeCtrl-J
(equivalent toEnter
) andCtrl-I
(equivalent toTab
). -
Keys involving multiple modifiers may not be supported by the terminal emulator, especially when the base key is a function key.
Listing Modes
The modes histlist
, location
and lastcmd
are all listing modes: They
all show a list, and you can filter items and accept items.
Because they are very similar, you may want to change their bindings at the same
time. This is made possible by the $edit:listing:binding
binding table
(listing
is not a “real” mode but an “abstract” mode). These modes still have
their own binding tables like $edit:histlist:binding
, and bindings there have
higher precedence over those in the shared $edit:listing:binding
table.
Moreover, there are a lot of builtin functions in the edit:listing
module like
edit:listing:down
(for moving down selection). They always apply to whichever
listing mode is active.
Caveat: Bindings to Start Modes
Note that keybindings to start modes live in the binding table of the insert
mode, not the target mode. For instance, if you want to be able to use
Alt-l to start location mode, you should modify
$edit:insert:binding[Alt-l]
:
set edit:insert:binding[Alt-l] = { edit:location:start }
One tricky case is the history mode. You can press ▲︎ to start
searching for history, and continue pressing it to search further. However, when
the first press happens, the editor is in insert mode, while with subsequent
presses, the editor is in history mode. Hence this binding actually relies on
two entries, $edit:insert:binding[Up]
and $edit:history:binding[Up]
.
So for instance if you want to be able to use Ctrl-P for this, you need to modify both bindings:
set edit:insert:binding[Ctrl-P] = { edit:history:start }
set edit:history:binding[Ctrl-P] = { edit:history:up }
Filter DSL
The completion, history listing, location and navigation modes all support filtering the items to show using a filter DSL. It uses a small subset of Elvish’s expression syntax, and can be any of the following:
-
A literal string (barewords and single-quoted or double-quoted strings all work) matches items containing the string. If the string is all lower case, the match is done case-insensitively; otherwise the match is case-sensitive.
-
A list
[re $string]
matches items matching the regular expression$string
. The$string
must be a literal string. -
A list
[and $expr...]
matches items matching all of the$expr
s. -
A list
[or $expr...]
matches items matching any of the$expr
s.
If the filter contains multiple expressions, they are ANDed, as if surrounded by
an implicit [and ...]
.
Completion API
Argument Completer
There are two types of completions in Elvish: completion for internal data and
completion for command arguments. The former includes completion for variable
names (e.g. echo $
Tab) and indices (e.g.
echo $edit:insert:binding[
Tab). These are the completions that
Elvish can provide itself because they only depend on the internal state of
Elvish.
The latter, in turn, is what happens when you type e.g. cat
Tab.
Elvish cannot provide completions for them without full knowledge of the
command.
Command argument completions are programmable via the
$edit:completion:arg-completer
variable. When Elvish is completing an argument
of command $x
, it will call the value stored in
$edit:completion:arg-completer[$x]
, with all the existing arguments, plus the
command name in the front.
For example, if the user types man 1
Tab, Elvish will call:
$edit:completion:arg-completer[man] man 1
If the user is starting a new argument when hitting Tab, Elvish will
call the completer with a trailing empty string. For instance, if you do
man 1
SpaceTab, Elvish will call:
$edit:completion:arg-completer[man] man 1 ""
The output of this call becomes candidates. There are several ways of outputting candidates:
-
Writing byte output, e.g. “echo cand1; echo cand2”. Each line becomes a candidate. This has the drawback that you cannot put newlines in candidates. Only use this if you are sure that you candidates will not contain newlines – e.g. package names, usernames, but not file names, etc..
-
Write strings to value output, e.g. “put cand1 cand2”. Each string output becomes a candidate.
-
Use the
edit:complex-candidate
command, e.g.:edit:complex-candidate &code-suffix='' &display=$stem' ('$description')' $stem
See
edit:complex-candidate
for the full description of the arguments is accepts.
After receiving your candidates, Elvish will match your candidates against what the user has typed. Hence, normally you don’t need to (and shouldn’t) do any matching yourself.
That means that in many cases you can (and should) simply ignore the last
argument to your completer. However, they can be useful for deciding what
kind of things to complete. For instance, if you are to write a completer
for ls
, you want to see whether the last argument starts with -
or not: if
it does, complete an option; and if not, complete a filename.
Here is a very basic example of configuring a completer for the apt
command.
It only supports completing the install
and remove
command and package names
after that:
use re
var all-packages = [(apt-cache search '' | re:awk {|0 1 @rest| put $1 })]
set edit:completion:arg-completer[apt] = {|@args|
var n = (count $args)
if (== $n 2) {
# apt x<Tab> -- complete a subcommand name
put install uninstall
} elif (== $n 3) {
put $@all-packages
}
}
Here is another slightly more complex example for the git
command. It supports
completing some common subcommands and then branch names after that:
use re
fn all-git-branches {
# Note: this assumes a recent version of git that supports the format
# string used.
git branch -a --format="%(refname:strip=2)" | re:awk {|0 1 @rest| put $1 }
}
var common-git-commands = [
add branch checkout clone commit diff init log merge
pull push rebase reset revert show stash status
]
set edit:completion:arg-completer[git] = {|@args|
var n = (count $args)
if (== $n 2) {
put $@common-git-commands
} elif (>= $n 3) {
all-git-branches
}
}
Matcher
As stated above, after the completer outputs candidates, Elvish matches them
with them with what the user has typed. For clarity, the part of the user input
that is relevant to tab completion is called for the seed of the completion.
For instance, in echo x
Tab, the seed is x
.
Elvish first indexes the matcher table – $edit:completion:matcher
– with the
completion type to find a matcher. The completion type is currently one
of variable
, index
, command
, redir
or argument
. If the
$edit:completion:matcher
lacks the suitable key,
$edit:completion:matcher['']
is used.
Elvish then calls the matcher with one argument – the seed, and feeds the text of all candidates to the input. The mather must output an identical number of booleans, indicating whether the candidate should be kept.
As an example, the following code configures a prefix matcher for all completion types:
set edit:completion:matcher[''] = {|seed| each {|cand| has-prefix $cand $seed } }
Elvish provides three builtin matchers, edit:match-prefix
, edit:match-substr
and edit:match-subseq
. In addition to conforming to the matcher protocol, they
accept two options &ignore-case
and &smart-case
. For example, if you want
completion of arguments to use prefix matching and ignore case, use:
set edit:completion:matcher[argument] = {|seed| edit:match-prefix $seed &ignore-case=$true }
The default value of $edit:completion:matcher
is [&''=$edit:match-prefix~]
,
hence that candidates for all completion types are matched by prefix.
Hooks
Hooks are functions that are executed at certain points in time. In Elvish this functionality is provided by variables that are a list of functions.
NOTE: Hook variables may be initialized with a non-empty list, and you may
have modules that add their own hooks. In general you should append to a hook
variable rather than assign a list of functions to it. That is, rather than
doing set edit:some-hook = [ { put 'I ran' } ]
you should do
set edit:some-hook = [ $@hook-var { put 'I ran' } ]
.
These are the editor/REPL hooks:
-
$edit:before-readline
: The functions are called before the editor runs. Each function is called with no arguments. -
$edit:after-readline
: The functions are called after the editor accepts a command for execution. Each function is called with a sole argument: the line just read. -
$edit:after-command
: The functions are called after the shell executes the command you entered (typically by pressing theEnter
key). Each function is called with a sole argument: a map that provides information about the executed command. This hook is also called after your interactive RC file is executed and before the first prompt is output.
Example usage:
set edit:before-readline = [{ echo 'going to read' }]
set edit:after-readline = [{|line| echo 'just read '$line }]
set edit:after-command = [{|m| echo 'command took '$m[duration]' seconds' }]
Given the above hooks…
-
Every time you accept a chunk of code (normally by pressing Enter)
just read
is printed. -
At the very beginning of an Elvish session, or after a chunk of code is handled,
going to read
is printed. -
After each non empty chunk of code is accepted and executed the string “command took … seconds` is output.
Word types
The editor supports operating on entire “words”. As intuitive as the concept of “word” is, there is actually no single definition for the concept. The editor supports the following three definitions of words:
-
A big word, or simply word, is a sequence of non-whitespace characters. This definition corresponds to the concept of “WORD” in vi.
-
A small word is a sequence of alphanumerical characters (”alnum small word”), or a sequence of non-alphanumerical, non-whitespace characters (”punctuation small word”). This definition corresponds to the concept of “word” in vi and zsh.
-
An alphanumerical word is a sequence of alphanumerical characters. This definition corresponds to the concept of “word” in bash.
Whitespace characters are those with the Unicode Whitespace property. Alphanumerical characters are those in the Unicode Letter or Number category.
A word boundary is an imaginary zero-length boundary around a word.
To see the difference between these definitions, consider the following string:
abc++ /* xyz
:
-
It contains three (big) words:
abc++
,/*
andxyz
. -
It contains four small words,
abc
,++
,/*
andxyz
. Among them,abc
andxyz
are alnum small words, while++
and/*
are punctuation small words. -
It contains two alnum words,
abc
andxyz
.
Autofix
The editor can identify autofix commands to fix some errors in the code.
For example, if you try to use a command from the str:
module
without importing it, the editor will offer use str
as an autofix command:
~> str: elf@host
Ctrl-A autofix: use str Tab Enter autofix first
As seen above, autofixes are also applied automatically by
edit:completion:smart-start
(the default binding for Tab) and
edit:smart-enter
(the default binding for Enter).
Variables
$edit:-dot
Contains the current position of the cursor, as a byte position within
$edit:current-command
.
$edit:-instant:binding
Binding for the instant mode.
$edit:-prompt-eagerness
See Prompt Eagerness.
$edit:-rprompt-eagerness
See Prompt Eagerness.
$edit:abbr
A map from simple abbreviations to their expansions.
An abbreviation is replaced by its expansion when it is typed in full and consecutively, without being interrupted by the use of other editing functionalities, such as cursor movements.
If more than one abbreviations would match, the longest one is used.
Examples:
set edit:abbr['||'] = '| less'
set edit:abbr['>dn'] = '2>/dev/null'
With the definitions above, typing ||
anywhere expands to | less
, and
typing >dn
anywhere expands to 2>/dev/null
. However, typing a |
, moving
the cursor left, and typing another |
does not expand to | less
,
since the abbreviation ||
was not typed consecutively.
See also $edit:command-abbr
and $edit:small-word-abbr
.
$edit:add-cmd-filters
List of filters to run before adding a command to history.
A filter is a function that takes a command as argument and outputs
a boolean value. If any of the filters outputs $false
, the
command is not saved to history, and the rest of the filters are
not run. The default value of this list contains a filter which
ignores command starts with space.
$edit:after-command
A list of functions to call after each interactive command completes. There is one pre-defined
function used to populate the $edit:command-duration
variable. Each function is called with a single map
argument containing the following keys:
-
src
: Information about the source that was executed, same as whatsrc
would output inside the code. -
duration
: A floating-point number representing the command execution duration in seconds. -
error
: An exception object if the command terminated with an exception, else$nil
.
See also $edit:command-duration
.
$edit:after-readline
A list of functions to call after each readline cycle. Each function is called with a single string argument containing the code that has been read.
$edit:before-readline
A list of functions to call before each readline cycle. Each function is called without any arguments.
$edit:command-abbr
A map from command abbreviations to their expansions.
A command abbreviation is replaced by its expansion when seen in the command position followed by a whitespace. This is similar to the Fish shell’s abbreviations, but does not trigger when executing a command with Enter – you must type a space first.
Examples:
set edit:command-abbr['l'] = 'less'
set edit:command-abbr['gc'] = 'git commit'
See also $edit:abbr
and $edit:small-word-abbr
.
$edit:command-duration
Duration, in seconds, of the most recent interactive command. This can be useful in your prompt
to provide feedback on how long a command took to run. The initial value of this variable is the
time to evaluate your rc.elv
before printing the first prompt.
See also $edit:after-command
.
$edit:command:binding
Key bindings for command mode. This is currently a very small subset of Vi command mode bindings.
See also edit:command:start
.
$edit:completion:arg-completer
A map containing argument completers.
$edit:completion:binding
Keybinding for the completion mode.
$edit:completion:matcher
A map mapping from context names to matcher functions. See the Matcher section.
$edit:current-command
Contains the content of the current input. Setting the variable will
cause the cursor to move to the very end, as if edit-dot = (count $edit:current-command)
has been invoked.
This API is subject to change.
$edit:exceptions
A list of exceptions thrown from callbacks such as prompts. Useful for examining tracebacks and other metadata.
$edit:global-binding
Global keybindings, consulted for keys not handled by mode-specific bindings.
See Keybindings.
$edit:histlist:binding
Keybinding for the history listing mode.
Keys bound to edit:histlist:toggle-dedup (Ctrl-D by default) will be shown in the history listing UI.
$edit:history:binding
edit:history:binding
Binding table for the history mode.
$edit:insert:binding
Binding map for the insert mode.
The key bound to edit:apply-autofix
will be shown when an
autofix is available.
$edit:insert:quote-paste
A boolean used to control whether text pasted using
bracketed paste
in the terminal should be quoted as a string. Defaults to $false
.
$edit:lastcmd:binding
Keybinding for the last command mode.
$edit:listing:binding
Common binding table for listing modes.
$edit:location:binding
Keybinding for the location mode.
$edit:location:hidden
A list of directories to hide in the location addon.
$edit:location:pinned
A list of directories to always show at the top of the list of the location addon.
$edit:location:workspaces
A map mapping types of workspaces to their patterns.
$edit:max-height
Maximum height the editor is allowed to use, defaults to +Inf
.
By default, the height of the editor is only restricted by the terminal height. Some modes like location mode can use a lot of lines; as a result, it can often occupy the entire terminal, and push up your scrollback buffer. Change this variable to a finite number to restrict the height of the editor.
$edit:navigation:binding
Keybinding for the navigation mode.
Keys bound to edit:navigation:trigger-filter (Ctrl-F by default) and edit:navigation:trigger-shown-hidden (Ctrl-H by default) will be shown in the navigation mode UI.
$edit:navigation:selected-file
Name of the currently selected file in navigation mode. $nil if not in navigation mode.
$edit:navigation:width-ratio
A list of 3 integers, used for specifying the width ratio of the 3 columns in navigation mode.
$edit:prompt
See Prompts.
$edit:prompt-stale-threshold
See Stale Prompt.
$edit:prompt-stale-transformer.
See Stale Prompt.
$edit:rprompt
See Prompts.
$edit:rprompt-persistent
See RPrompt Persistency.
$edit:rprompt-stale-threshold
See Stale Prompt.
$edit:rprompt-stale-transformer.
See Stale Prompt.
$edit:small-word-abbr
A map from small-word abbreviations to their expansions.
A small-word abbreviation is replaced by its expansion after it is typed in full and consecutively, and followed by another character (the trigger character). Furthermore, the expansion requires the following conditions to be satisfied:
-
The end of the abbreviation must be adjacent to a small-word boundary, i.e. the last character of the abbreviation and the trigger character must be from two different small-word categories.
-
The start of the abbreviation must also be adjacent to a small-word boundary, unless it appears at the beginning of the code buffer.
-
The cursor must be at the end of the buffer.
If more than one abbreviations would match, the longest one is used. See the description of small words for more information.
As an example, with the following configuration:
set edit:small-word-abbr['gcm'] = 'git checkout master'
In the following scenarios, the gcm
abbreviation is expanded:
-
With an empty buffer, typing
gcm
and a space or semicolon; -
When the buffer ends with a space, typing
gcm
and a space or semicolon.
The space or semicolon after gcm
is preserved in both cases.
In the following scenarios, the gcm
abbreviation is not expanded:
-
With an empty buffer, typing
Xgcm
and a space or semicolon (start of abbreviation is not adjacent to a small-word boundary); -
When the buffer ends with
X
, typinggcm
and a space or semicolon (end of abbreviation is not adjacent to a small-word boundary); -
When the buffer is non-empty, move the cursor to the beginning, and typing
gcm
and a space (cursor not at the end of the buffer).
This example shows the case where the abbreviation consists of a single small word of alphanumerical characters, but that doesn’t have to be the case. For example, with the following configuration:
set edit:small-word-abbr['>dn'] = ' 2>/dev/null'
The abbreviation >dn
starts with a punctuation character, and ends with an
alphanumerical character. This means that it is expanded when it borders
a whitespace or alphanumerical character to the left, and a whitespace or
punctuation to the right; for example, typing ls>dn;
will expand it.
Some extra examples of small-word abbreviations:
set edit:small-word-abbr['gcp'] = 'git cherry-pick -x'
set edit:small-word-abbr['ll'] = 'ls -ltr'
If both a simple abbreviation and a small-word abbreviation can be expanded, the simple abbreviation has priority.
See also $edit:abbr
$edit:command-abbr
.
Functions
edit:-instant:start
edit:-instant:start
Starts the instant mode. In instant mode, any text entered at the command line is evaluated immediately, with the output displayed.
WARNING: Beware of unintended consequences when using destructive
commands. For example, if you type sudo rm -rf /tmp/*
in the instant mode,
Elvish will attempt to evaluate sudo rm -rf /
when you typed that far.
edit:add-var
edit:add-var $name $init
Defines a new variable in the interactive REPL with an initial value. The new variable becomes available during the next REPL cycle.
Equivalent to running var $name = $init
at a REPL prompt, but $name
can be
dynamic.
This is most useful for modules to modify the REPL namespace. Example:
~> cat .config/elvish/lib/a.elv
for i [(range 10)] {
edit:add-var foo$i $i
}
~> use a
~> put $foo1 $foo2
▶ (num 1)
▶ (num 2)
Note that if you use a variable as the $init
argument, edit:add-var
doesn’t add the variable “itself” to the REPL namespace. The variable in the
REPL namespace will have the initial value set to the variable’s value, but
it is not an alias of the original variable:
~> cat .config/elvish/lib/b.elv
var foo = foo
edit:add-var foo $foo
~> use b
~> put $foo
▶ foo
~> set foo = bar
~> echo $b:foo
foo
Importing definition from a module into the REPL
One common use of this command is to put the definitions of functions intended for REPL use in a
module instead of your rc.elv
. For example, if you want to define ll
as ls -l
, you can do so in your rc.elv
directly:
fn ll {|@a| ls -l $@a }
But if you move the definition into a module (say util.elv
in one of the
module search directories, this
function can only be used as util:ll
(after use util
). To make it usable
directly as ll
, you can add the following to util.elv
:
edit:add-var ll~ $ll~
Conditionally importing a module
Another use case is to add a module or function to the REPL namespace
conditionally. For example, to only import the unix
module
when actually running on Unix, a straightforward solution is to do the
following in rc.elv
:
use platform
if $platform:is-unix {
use unix
}
This doesn’t work however, since what use
does is introducing a variable
named $unix:
. Since all variables in Elvish are lexically scoped, the
$unix:
variable is only valid inside the if
block.
This can be fixed by explicitly introducing the $unix:
variable to the REPL
namespace. The following works both from rc.elv
and from a module:
use platform
if $platform:is-unix {
use unix
edit:add-var unix: $unix:
}
edit:add-vars
edit:add-vars $map
Takes a map from strings to arbitrary values. Equivalent to calling
edit:add-var
for each key-value pair in the map, but guarantees that all the
names will be added at the same time.
edit:apply-autofix
edit:apply-autofix
Executes the currently suggested autofix.
edit:binding-table
edit:binding-table $map
Converts a normal map into a binding map.
edit:clear
edit:clear
Clears the screen.
This command should be used in place of the external clear
command to clear
the screen.
edit:close-mode
edit:close-mode
Closes the current active mode.
edit:command-history
edit:command-history &cmd-only=$false &dedup=$false &newest-first
Outputs the command history.
By default, each entry is represented as a map, with an id
key key for the
sequence number of the command, and a cmd
key for the text of the command.
If &cmd-only
is $true
, only the text of each command is output.
All entries are output by default. If &dedup
is $true
, only the most
recent instance of each command (when comparing just the cmd
key) is
output.
Commands are are output in oldest to newest order by default. If
&newest-first
is $true
the output is in newest to oldest order instead.
As an example, either of the following extracts the text of the most recent command:
edit:command-history | put [(all)][-1][cmd]
edit:command-history &cmd-only &newest-first | take 1
edit:command:start
edit:command:start
Enter command mode. This mode is intended to emulate Vi’s command mode, but it is very incomplete right now.
See also $edit:command:binding
.
edit:complete-dirnameadded in 0.21
edit:complete-dirname $args...
Like edit:complete-filename
, but only generates directories.
edit:complete-filename
edit:complete-filename $args...
Produces a list of filenames that are suitable for completing the last argument, ignoring all other arguments. The last argument is used in the following ways:
-
The directory determines which directory to complete.
-
If the base name starts with
.
, it completes all files whose names start with.
(hidden files); otherwise it completes filenames that don’t start with.
(non-hidden files).The rest of the base name is ignored; filtering is left to the matcher.
The outputs are edit:complex-candidate
objects, with styles determined
by $E:LSCOLOR
. Directories have a trailing /
in the stem; non-directory
files have a space as their code suffix.
This function is the default handler for any commands without explicit
handlers in $edit:completion:arg-completer
. See Argument
Completer.
Example:
~> ls -AR
~/tmp/example> ls -AR
.ipsum .lorem bar d foo
./d:
bar foo
~> edit:complete-filename '' # non-hidden files in working directory
▶ (edit:complex-candidate bar &code-suffix=' ' &display=[^styled bar])
▶ (edit:complex-candidate d/ &code-suffix='' &display=[^styled (styled-segment d/ &fg-color=blue &bold)])
▶ (edit:complex-candidate foo &code-suffix=' ' &display=[^styled foo])
~> edit:complete-filename '.f' # hidden files in working directory
▶ (edit:complex-candidate .ipsum &code-suffix=' ' &display=[^styled .ipsum])
▶ (edit:complex-candidate .lorem &code-suffix=' ' &display=[^styled .lorem])
~> edit:complete-filename ./d/f # non-hidden files in ./d
▶ (edit:complex-candidate ./d/bar &code-suffix=' ' &display=[^styled ./d/bar])
▶ (edit:complex-candidate ./d/foo &code-suffix=' ' &display=[^styled ./d/foo])
edit:complete-getopt
edit:complete-getopt $args $opt-specs $arg-handlers
Produces completions according to a specification of accepted command-line options (both short and long options are handled), positional handler functions for each command position, and the current arguments in the command line. The arguments are as follows:
-
$args
is an array containing the current arguments in the command line (without the command itself). These are the arguments as passed to the Argument Completer function. -
$opt-specs
is an array of maps, each one containing the definition of one possible command-line option. Matching options will be provided as completions when the last element of$args
starts with a dash, but not otherwise. Each map can contain the following keys (at least one ofshort
orlong
needs to be specified):-
short
contains the one-letter short option, if any, without the dash. -
long
contains the long option name, if any, without the initial two dashes. -
arg-optional
, if set to$true
, specifies that the option receives an optional argument. -
arg-required
, if set to$true
, specifies that the option receives a mandatory argument. Only one ofarg-optional
orarg-required
can be set to$true
. -
desc
can be set to a human-readable description of the option which will be displayed in the completion menu. -
completer
can be set to a function to generate possible completions for the option argument. The function receives as argument the element at that position and return zero or more candidates.
-
-
$arg-handlers
is an array of functions, each one returning the possible completions for that position in the arguments. Each function receives as argument the last element of$args
, and should return zero or more possible values for the completions at that point. The returned values can be plain strings or the output ofedit:complex-candidate
. If the last element of the list is the string...
, then the last handler is reused for all following arguments.
Example:
~> fn complete {|@args|
opt-specs = [ [&short=a &long=all &desc="Show all"]
[&short=n &desc="Set name" &arg-required=$true
&completer= {|_| put name1 name2 }] ]
arg-handlers = [ {|_| put first1 first2 }
{|_| put second1 second2 } ... ]
edit:complete-getopt $args $opt-specs $arg-handlers
}
~> complete ''
▶ first1
▶ first2
~> complete '-'
▶ (edit:complex-candidate -a &display='-a (Show all)')
▶ (edit:complex-candidate --all &display='--all (Show all)')
▶ (edit:complex-candidate -n &display='-n (Set name)')
~> complete -n ''
▶ name1
▶ name2
~> complete -a ''
▶ first1
▶ first2
~> complete arg1 ''
▶ second1
▶ second2
~> complete arg1 arg2 ''
▶ second1
▶ second2
See also flag:parse-getopt
.
edit:completion:smart-start
edit:completion:smart-start
Starts the completion mode after accepting any pending autofix.
If all the candidates share a non-empty prefix and that prefix starts with the seed, inserts the prefix instead.
edit:completion:start
edit:completion:start
Start the completion mode.
edit:complex-candidate
edit:complex-candidate $stem &display='' &code-suffix=''
Builds a complex candidate. This is mainly useful in argument completers.
The &display
option controls how the candidate is shown in the UI. It can
be a string or a styled text. If it is empty, $stem
is used.
The &code-suffix
option affects how the candidate is inserted into the code
when it is accepted. By default, a quoted version of $stem
is inserted. If
$code-suffix
is non-empty, it is added to that text, and the suffix is not
quoted.
edit:del-var
edit:del-var $name
Deletes a variable from the interactive REPL if it exists.
Equivalent to running del $name
at a REPL prompt, but $name
can be
dynamic, and it is not an error to delete a non-existing variable.
edit:del-vars
edit:del-vars $list
Deletes variables from the interactive REPL.
Equivalent to calling edit:del-var
for each element of the list, but
guarantees that all the variables will be deleted at the same time.
edit:end-of-history
edit:end-of-history
Adds a notification saying “End of history”.
edit:histlist:start
edit:histlist:start
Starts the history listing mode.
edit:histlist:toggle-dedup
edit:histlist:toggle-dedup
Toggles deduplication in history listing mode.
When deduplication is on (the default), only the last occurrence of the same command is shown.
edit:history:accept
edit:history:accept
Replaces the content of the buffer with the current history mode entry, and closes history mode.
edit:history:down
edit:history:down
Walks to the next entry in history mode.
edit:history:down-or-quit
edit:history:down-or-quit
Walks to the next entry in history mode, or quit the history mode if already at the newest entry.
edit:history:fast-forward
edit:history:fast-forward
Import command history entries that happened after the current session started.
edit:history:start
edit:history:start
Starts the history mode.
edit:history:up
edit:history:up
Walks to the previous entry in history mode.
edit:insert-at-dot
edit:insert-at-dot $text
Inserts the given text at the dot, moving the dot after the newly inserted text.
edit:insert-last-word
edit:insert-last-word
Inserts the last word of the last command.
edit:insert-raw
edit:insert-raw
Requests the next terminal input to be inserted uninterpreted.
edit:key
edit:key $string
Parses a string into a key.
edit:kill-alnum-word-left
edit:kill-alnum-word-left
Deletes the last alnum word to the left of the dot.
edit:kill-alnum-word-right
edit:kill-alnum-word-right
Deletes the first alnum word to the right of the dot.
edit:kill-line-left
edit:kill-line-left
Deletes the text between the dot and the start of the current line.
edit:kill-line-right
edit:kill-line-right
Deletes the text between the dot and the end of the current line.
edit:kill-rune-left
edit:kill-rune-left
Kills one rune left of the dot. Does nothing if the dot is at the beginning of the buffer.
edit:kill-rune-left
edit:kill-rune-left
Kills one rune right of the dot. Does nothing if the dot is at the end of the buffer.
edit:kill-small-word-left
edit:kill-small-word-left
Deletes the last small word to the left of the dot.
edit:kill-small-word-right
edit:kill-small-word-right
Deletes the first small word to the right of the dot.
edit:kill-word-left
edit:kill-word-left
Deletes the last word to the left of the dot.
edit:kill-word-right
edit:kill-word-right
Deletes the first word to the right of the dot.
edit:lastcmd:start
edit:lastcmd:start
Starts the last command mode.
edit:listing:accept
edit:listing:accept
Accepts the current selected listing item.
edit:listing:down
edit:listing:down
Moves the cursor down in listing mode.
edit:listing:down-cycle
edit:listing:down-cycle
Moves the cursor down in listing mode, or to the first item if the last item is currently selected.
edit:listing:page-down
edit:listing:page-down
Moves the cursor down one page.
edit:listing:page-up
edit:listing:page-up
Moves the cursor up one page.
edit:listing:start-custom
edit:listing:start-custom $items &binding=$nil &caption='' &keep-bottom=$false &accept=$nil &auto-accept=$false
Starts custom listing mode.
The $items
argument can be as a list of maps, each map representing one item
and having the following keys:
-
The value of the
to-show
key must be a string or a styled text. It is used in the listing UI. -
The value of the
to-filter
key must be a string. It is used when filtering the item. -
The value of the
to-accept
key must be a string. It is passed to the accept callback (see below).
Alternatively, the $items
argument can be a function taking one argument. It
will be called with the value of the filter (initially an empty string), and
can output any number of maps containing the to-show
and to-accept
keys,
with the same semantics as above. Any other key is ignored.
The &binding
option, if specified, should be a binding map to use in the
custom listing mode. Bindings from $edit:listing:binding
are also used,
after this map if it is specified.
The &caption
option changes the caption of the mode. If empty, the caption
defaults to ' LISTING '
.
The &keep-bottom
option, if true, makes the last item to get selected
initially or when the filter changes.
The &accept
option specifies a function to call when an item is accepted. It
is passed the value of the to-accept
key of the item.
The &auto-accept
option, if true, accepts an item automatically when there
is only one item being shown.
edit:listing:up
edit:listing:up
Moves the cursor up in listing mode.
edit:listing:up-cycle
edit:listing:up-cycle
Moves the cursor up in listing mode, or to the last item if the first item is currently selected.
edit:match-prefix
edit:match-prefix $seed $inputs?
For each input, outputs whether the input has $seed as a prefix. Uses the
result of to-string
for non-string inputs.
Roughly equivalent to the following Elvish function, but more efficient:
use str
fn match-prefix {|seed @input|
each {|x| str:has-prefix (to-string $x) $seed } $@input
}
edit:match-subseq
edit:match-subseq $seed $inputs?
For each input, outputs whether the input has $seed as a
subsequence. Uses the result of
to-string
for non-string inputs.
edit:match-substr
edit:match-substr $seed $inputs?
For each input, outputs whether the input has $seed as a substring. Uses the
result of to-string
for non-string inputs.
Roughly equivalent to the following Elvish function, but more efficient:
use str
fn match-substr {|seed @input|
each {|x| str:has-contains (to-string $x) $seed } $@input
}
edit:move-dot-down
edit:move-dot-down
Moves the dot down one line, trying to preserve the visual horizontal position. Does nothing if dot is already on the last line of the buffer.
edit:move-dot-eol
edit:move-dot-eol
Moves the dot to the end of the current line.
edit:move-dot-left
edit:move-dot-left
Moves the dot left one rune. Does nothing if the dot is at the beginning of the buffer.
edit:move-dot-left-alnum-word
edit:move-dot-left-alnum-word
Moves the dot to the beginning of the last alnum word to the left of the dot.
edit:move-dot-left-small-word
edit:move-dot-left-small-word
Moves the dot to the beginning of the last small word to the left of the dot.
edit:move-dot-left-word
edit:move-dot-left-word
Moves the dot to the beginning of the last word to the left of the dot.
edit:move-dot-right
edit:move-dot-right
Moves the dot right one rune. Does nothing if the dot is at the end of the buffer.
edit:move-dot-right-alnum-word
edit:move-dot-right-alnum-word
Moves the dot to the beginning of the first alnum word to the right of the dot.
edit:move-dot-right-small-word
edit:move-dot-right-small-word
Moves the dot to the beginning of the first small word to the right of the dot.
edit:move-dot-right-word
edit:move-dot-right-word
Moves the dot to the beginning of the first word to the right of the dot.
edit:move-dot-sol
edit:move-dot-sol
Moves the dot to the start of the current line.
edit:move-dot-up
edit:move-dot-up
Moves the dot up one line, trying to preserve the visual horizontal position. Does nothing if dot is already on the first line of the buffer.
edit:navigation:insert-selected
edit:navigation:insert-selected
Inserts the selected filename.
edit:navigation:insert-selected-and-quit
edit:navigation:insert-selected-and-quit
Inserts the selected filename and closes the navigation addon.
edit:navigation:start
edit:navigation:start
Start the navigation mode.
edit:navigation:trigger-filter
edit:navigation:trigger-filter
Toggles the filtering status of the navigation addon.
edit:navigation:trigger-shown-hidden
edit:navigation:trigger-shown-hidden
Toggles whether the navigation addon should be showing hidden files.
edit:notify
edit:notify $message
Prints a notification message. The argument may be a string or a styled text.
If called while the editor is active, this will print the message above the editor, and redraw the editor.
If called while the editor is inactive, the message will be queued, and shown once the editor becomes active.
edit:redraw
edit:redraw &full=$false
Triggers a redraw.
The &full
option controls whether to do a full redraw. By default, all
redraws performed by the line editor are incremental redraws, updating only
the part of the screen that has changed from the last redraw. A full redraw
updates the entire command line.
edit:replace-input
edit:replace-input $text
Equivalent to assigning $text
to $edit:current-command
.
edit:return-eof
edit:return-eof
Causes the Elvish REPL to terminate. If called from a key binding, takes effect after the key binding returns.
edit:return-line
edit:return-line
Causes the Elvish REPL to end the current read iteration and evaluate the code it just read. If called from a key binding, takes effect after the key binding returns.
edit:smart-enter
edit:smart-enter
If the current code is syntactically incomplete (like echo [
), inserts a
literal newline.
Otherwise, applies any pending autofixes and accepts the current line.
edit:toggle-quote-paste
edit:toggle-quote-paste
Toggles the value of [$edit:insert:quote-paste].
edit:transpose-alnum-word
edit:transpose-alnum-word
Swaps the alnum words to the left and right of the dot. If the dot is at the beginning of the buffer, it swaps the first two alnum words, and if the dot is at the end, it swaps the last two.
edit:transpose-rune
edit:transpose-rune
Swaps the runes to the left and right of the dot. If the dot is at the beginning of the buffer, swaps the first two runes, and if the dot is at the end, it swaps the last two.
edit:transpose-small-word
edit:transpose-small-word
Swaps the small words to the left and right of the dot. If the dot is at the beginning of the buffer, it swaps the first two small words, and if the dot is at the end, it swaps the last two.
edit:transpose-word
edit:transpose-word
Swaps the words to the left and right of the dot. If the dot is at the beginning of the buffer, swaps the first two words, and the dot is at the end, it swaps the last two.
edit:wordify
edit:wordify $code
Breaks Elvish code into words.