github.com/xiaq/elvish@v0.12.0/website/src/ref/edit.md (about) 1 <!-- toc --> 2 3 The `edit:` module is the interface to the Elvish editor. 4 5 Function usages are given in the same format as in the [reference for the 6 builtin module](/ref/builtin.html). 7 8 *This document is incomplete.* 9 10 # Overview 11 12 ## Modes and Submodules 13 14 The Elvish editor has different **modes**, and exactly one mode is active at 15 the same time. Each mode has its own UI and keybindings. For instance, the 16 default **insert mode** lets you modify the current command. The **completion 17 mode** (triggered by <span class="key">Tab</span> by default) shows you all 18 candidates for completion, and you can use arrow keys to navigate those 19 candidates. 20 21 $ttyshot completion-mode 22 23 Each mode has its own submodule under `edit:`. For instance, builtin functions 24 and configuration variables for the completion mode can be found in the 25 `edit:completion:` module. 26 27 The primary modes supported now are `insert`, `completion`, `navigation`, 28 `history`, `histlist`, `location`, and `lastcmd`. The last 4 are "listing 29 modes", and their particularity is documented below. 30 31 32 # Prompts 33 34 Elvish has two prompts: the (normal) left-hand prompt and the right-side 35 prompt (rprompt). Most of this section only documents the left-hand prompt, 36 but API for rprompt is the same other than the variable name: just replace 37 `prompt` with `rprompt`. 38 39 To customize the prompt, assign a function to `edit:prompt`. The function may 40 write value outputs or byte outputs. Value outputs may be either strings or 41 `edit:styled` values; they are joiend with no spaces in between. Byte outputs 42 are output as-is, including any newlines, but control characters will be 43 escaped: you should use `edit:styled` to output styled text. If you mix value 44 and byte outputs, the order in which they appear is non-deterministic. 45 46 The default prompt and rprompt are equivalent to: 47 48 ```elvish 49 edit:prompt = { tilde-abbr $pwd; put '> ' } 50 edit:rprompt = (constantly (edit:styled (whoami)@(hostname) inverse)) 51 ``` 52 53 More prompt functions: 54 55 ```elvish-transcript 56 ~> edit:prompt = { tilde-abbr $pwd; edit:styled '> ' green } 57 ~> # ">" is now green 58 ~> edit:prompt = { echo '$' } 59 $ 60 # Cursor will be on the next line as `echo` outputs a trailing newline 61 ``` 62 63 ## Stale Prompt 64 65 Elvish never waits for the prompt function to finish. Instead, the prompt 66 function is always executed on a separate thread, and Elvish updates the 67 screen when the function finishes. 68 69 However, this can be misleading when the function is slow: this means that the 70 prompt on the screen may not contain the latest information. To deal with 71 this, if the prompt function does not finish within a certain threshold - by 72 default 0.2 seconds, Elvish marks the prompt as **stale**: it still shows the 73 old stale prompt content, but transforms it using a **stale transformer**. The 74 default stale transformer applies reverse-video to the whole prompt. 75 76 The threshold is customizable with `$edit:prompt-stale-threshold`; it 77 specifies the threshold in seconds. 78 79 The transformer is customizable with `$edit:prompt-stale-transform`. It is a 80 function; the function is called with no arguments, and `styled` values as 81 inputs, and the output is interpreted in the same way as prompt functions. 82 Since `styled` values can be used as outputs in prompt functions, a function 83 that simply passes all the input values through as outputs is a valid stale 84 transformer. 85 86 As an example, try running following code: 87 88 ```elvish 89 n = 0 90 edit:prompt = { sleep 2; put $n; n = (+ $n 1); put ': ' } 91 edit:-prompt-eagerness = 10 # update prompt on each keystroke 92 edit:prompt-stale-threshold = 0.5 93 ``` 94 95 And then start typing. Type one character; the prompt becomes inverse after 96 0.5 second: this is when Elvish starts to consider the prompt as stale. The 97 prompt will return normal after 2 seconds, and the counter in the prompt is 98 updated: this is when the prompt function finishes. 99 100 Another thing you will notice is that, if you type a few characters quickly 101 (in less than 2 seconds, to be precise), the prompt is only updated twice. 102 This is because Elvish never does two prompt updates in parallel: prompt 103 updates are serialized. If a prompt update is required when the prompt 104 function is still running, Elvish simply queues another update. If an update 105 is already queued, Elvish does not queue another update. The reason why 106 exactly two updates happen in this case, and how this algorithm ensures 107 freshness of the prompt is left as an exercise to the reader. 108 109 110 ## Prompt Eagerness 111 112 The occassions when the prompt should get updated can be controlled with 113 `$edit:-prompt-eagerness`: 114 115 * The prompt is always updated when the editor becomes active -- when Elvish 116 starts, or a command finishes execution, or when the user presses Enter. 117 118 * If `$edit-prompt-eagerness` >= 5, it is updated when the working directory 119 changes. 120 121 * If `$edit-prompt-eagerness` >= 10, it is updated on each keystroke. 122 123 The default value is 5. 124 125 126 ## RPrompt Persistency 127 128 By default, the rprompt is only shown while the editor is active: as soon as 129 you press Enter, it is erased. If you want to keep it, simply set 130 `$edit:rprompt-persistent` to `$true`: 131 132 ```elvish 133 edit:rprompt-persistent = $true 134 ``` 135 136 137 # Keybindings 138 139 Each mode has its own keybinding, accessible as the `binding` variable in its 140 module. For instance, the binding table for insert mode is 141 `$edit:insert:binding`. To see current bindings, simply print the binding 142 table: `pprint $edit:insert:binding` (replace `insert` with any other mode). 143 144 A binding tables is simply a map that maps keys to functions. For instance, to 145 bind `Alt-x` in insert mode to exit Elvish, simply do: 146 147 ```elvish 148 edit:insert:binding[Alt-x] = { exit } 149 ``` 150 151 Outputs from a bound function always appear above the Elvish prompt. You can see this by doing the following: 152 153 ```elvish 154 edit:insert:binding[Alt-x] = { echo 'output from a bound function!' } 155 ``` 156 157 and press <span class="key">Alt-x</span> in insert mode. It allows you to put 158 debugging outputs in bound functions without messing up the terminal. 159 160 Internally, this is implemented by connecting their output to a pipe. 161 This does the correct thing in most cases, but if you are sure you want to do 162 something to the terminal, redirect the output to `/dev/tty`. For instance, the 163 following binds <span class="key">Ctrl-L</span> to clearing the terminal: 164 165 ```elvish 166 edit:insert:binding[Ctrl-L] = { clear > /dev/tty } 167 ``` 168 169 Bound functions have their inputs redirected to /dev/null. 170 171 172 ## Format of Keys 173 174 TBD 175 176 ## Listing Modes 177 178 The modes `histlist`, `loc` and `lastcmd` are all **listing modes**: They all 179 show a list, and you can filter items and accept items. 180 181 Because they are very similar, you may want to change their bindings at the 182 same time. This is made possible by the `$edit:listing:binding` binding table 183 (`listing` is not a "real" mode but an "abstract" mode). These modes still have 184 their own binding tables like `$edit:histlist:binding`, and bindings there have 185 highter precedence over those in the shared `$edit:listing:binding` table. 186 187 Moreover, there are a lot of builtin functions in the `edit:listing` module 188 like `edit:listing:down` (for moving down selection). They always apply to 189 whichever listing mode is active. 190 191 192 ## Caveat: Bindings to Start Modes 193 194 Note that keybindings to **start** modes live in the binding table of the 195 insert mode, not the target mode. For instance, if you want to be able to use 196 <span class="key">Alt-l</span> to start location mode, you should modify 197 `$edit:insert:binding[Alt-l]`: 198 199 ```elvish 200 edit:insert:binding[Alt-l] = { edit:location:start } 201 ``` 202 203 One tricky case is the history mode. You can press 204 <span class="key">▲︎</span> to start searching for history, and continue 205 pressing it to search further. However, when the first press happens, the 206 editor is in insert mode, while with subsequent presses, the editor is in 207 history mode. Hence this binding actually relies on two entries, 208 `$edit:insert:binding[Up]` and `$edit:history:binding[Up]`. 209 210 So for instance if you want to be able to use 211 <span class="key">Ctrl-P</span> for this, you need to modify both bindings: 212 213 ```elvish 214 edit:insert:binding[Up] = { edit:history:start } 215 edit:history:binding[Up] = { edit:history:up } 216 ``` 217 218 219 # Completion API 220 221 ## Argument Completer 222 223 There are two types of completions in Elvish: completion for internal data and 224 completion for command arguments. The former includes completion for variable 225 names (e.g. `echo $`<span class="key">Tab</span>) and indicies (e.g. `echo 226 $edit:insert:binding[`<span class="key">Tab</span>). These are the completions 227 that Elvish can provide itself because they only depend on the internal state 228 of Elvish. 229 230 The latter, in turn, is what happens when you type e.g. `cat `<span 231 class="key">Tab</span>. Elvish cannot provide completions for them without full 232 knowledge of the command. 233 234 Command argument completions are programmable via the `$edit:completion:arg-completer` 235 variable. When Elvish is completing an argument of command `$x`, it will call 236 the value stored in `$edit:completion:arg-completer[$x]`, with all the existing arguments, 237 plus the command name in the front. 238 239 For example, if the user types `man 1`<span class="key">Tab</span>, Elvish will call: 240 241 ```elvish 242 $edit:completion:arg-completer[man] man 1 243 ``` 244 245 If the user is starting a new argument when hitting <span 246 class="key">Tab</span>, Elvish will call the completer with a trailing empty 247 string. For instance, if you do `man 1`<span class="key">Space</span><span 248 class="key">Tab</span>, Elvish will call: 249 250 ```elvish 251 $edit:completion:arg-completer[man] man 1 "" 252 ``` 253 254 The output of this call becomes candidates. There are several ways of 255 outputting candidates: 256 257 * Writing byte output, e.g. "echo cand1; echo cand2". Each line becomes a 258 candidate. This has the drawback that you cannot put newlines in 259 candidates. Only use this if you are sure that you candidates will not 260 contain newlines -- e.g. package names, usernames, but **not** file names, 261 etc.. 262 263 * Write strings to value output, e.g. "put cand1 cand2". Each string output 264 becomes a candidate. 265 266 * Use the `edit:complex-candidate` command: 267 268 ```elvish 269 edit:complex-candidate &code-suffix='' &display-suffix='' &style='' $stem 270 ``` 271 272 **TODO**: Document this. 273 274 After receiving your candidates, Elvish will match your candidates against what 275 the user has typed. Hence, normally you don't need to (and shouldn't) do any 276 matching yourself. 277 278 That means that in many cases you can (and should) simpy ignore the last 279 argument to your completer. However, they can be useful for deciding what 280 **kind** of things to complete. For instance, if you are to write a completer 281 for `ls`, you want to see whether the last argument starts with `-` or not: if 282 it does, complete an option; and if not, complete a filename. 283 284 Here is a very basic example of configuring a completer for the `apt` command. 285 It only supports completing the `install` and `remove` command and package 286 names after that: 287 288 ```elvish 289 all-packages = [(apt-cache search '' | eawk [0 1 @rest]{ put $1 })] 290 291 edit:completion:arg-completer[apt] = [@args]{ 292 n = (count $args) 293 if (== $n 2) { 294 # apt x<Tab> -- complete a subcommand name 295 put install uninstall 296 } elif (== $n 3) { 297 put $@all-packages 298 } 299 } 300 ``` 301 302 Here is another slightly more complex example for the `git` command. It 303 supports completing some common subcommands and then branch names after that: 304 305 ```elvish 306 fn all-git-branches { 307 # Note: this assumes a recent version of git that supports the format 308 # string used. 309 git branch -a --format="%(refname:strip=2)" | eawk [0 1 @rest]{ put $1 } 310 } 311 312 common-git-commands = [ 313 add branch checkout clone commit diff init log merge 314 pull push rebase reset revert show stash status 315 ] 316 317 edit:arg-completer[git] = [@args]{ 318 n = (count $args) 319 if (== $n 2) { 320 put $@common-git-commands 321 } elif (>= $n 3) { 322 all-git-branches 323 } 324 } 325 ``` 326 327 328 ## Matcher 329 330 As stated above, after the completer outputs candidates, Elvish matches them 331 with them with what the user has typed. For clarity, the part of the user input 332 that is relevant to tab completion is called for the **seed** of the 333 completion. For instance, in `echo x`<span class="key">Tab</span>, the seed is 334 `x`. 335 336 Elvish first indexes the matcher table -- `$edit:completion:matcher` -- with the 337 completion type to find a **matcher**. The **completion type** is currently one 338 of `variable`, `index`, `command`, `redir` or `argument`. If the 339 `$edit:completion:matcher` lacks the suitable key, `$edit:completion:matcher['']` is used. 340 341 342 Elvish then calls the matcher with one argument -- the seed, and feeds 343 the *text* of all candidates to the input. The mather must output an identical 344 number of booleans, indicating whether the candidate should be kept. 345 346 As an example, the following code configures a prefix matcher for all 347 completion types: 348 349 ```elvish 350 edit:completion:matcher[''] = [seed]{ each [cand]{ has-prefix $cand $seed } } 351 ``` 352 353 Elvish provides three builtin matchers, `edit:match-prefix`, 354 `edit:match-substr` and `edit:match-subseq`. In addition to conforming to the 355 matcher protocol, they accept two options `&ignore-case` and `&smart-case`. 356 For example, if you want completion of arguments to use prefix matching and 357 ignore case, use: 358 359 ```elvish 360 edit:completion:matcher[argument] = [seed]{ edit:match-prefix $seed &ignore-case=$true } 361 ``` 362 363 The default value of `$edit:completion:matcher` is `[&''=$edit:match-prefix~]`, hence 364 that candidates for all completion types are matched by prefix. 365 366 367 # Hooks 368 369 Hooks are functions that are executed at certain points in time. In Elvish, 370 this functionality is provided by lists of functions. 371 372 There are current two hooks: 373 374 * `$edit:before-readline`, whose elements are called before the editor reads 375 code, with no arguments. 376 377 * `$edit:after-readline`, whose elements are called, after the editor reads 378 code, with a sole element -- the line just read. 379 380 Example usage: 381 382 ```elvish 383 edit:before-readline = [{ echo 'going to read' }] 384 edit:after-readline = [[line]{ echo 'just read '$line }] 385 ``` 386 387 Then every time you accept a chunk of code (and thus leaving the editor), 388 `just read ` followed by the code is printed; and at the very beginning of an 389 Elvish session, or after a chunk of code is executed, `going to read` is 390 printed. 391 392 393 # Functions and Variables 394 395 Functions and variables who name start with `-` are experimental, will have 396 their names or behaviors changed in the near future. Others are more stable 397 (unless noted explicitly) but are also subject to change before the 1.0 398 release. 399 400 ## edit:-dump-buf 401 402 Dump the content of onscreen buffer as HTML. This command is used to generate 403 "ttyshots" on [the homepage](/). 404 405 Example: 406 407 ```elvish 408 ttyshot = ~/a.html 409 edit:insert:binding[Ctrl-X] = { edit:-dump-buf > $tty } 410 ``` 411 412 413 ## edit:complete-filename 414 415 ```elvish 416 edit:complete-filename @args 417 ``` 418 419 Produces a list of filenames found in the directory of the last argument. All other arguments are ignored. If the last argument does not contain a path (either absolute or relative to the current directory), then the current directory is used. Relevant files are output as `edit:complex-candidate` objects. 420 421 This function is the default handler for any commands without explicit handlers in `$edit:completion:arg-completer`. See [Argument Completer](#argument-completer). 422 423 Example: 424 425 ```elvish-transcript 426 ~> edit:complete-filename '' 427 ▶ (edit:complex-candidate Applications &code-suffix=/ &display-suffix='' &style='01;34') 428 ▶ (edit:complex-candidate Books &code-suffix=/ &display-suffix='' &style='01;34') 429 ▶ (edit:complex-candidate Desktop &code-suffix=/ &display-suffix='' &style='01;34') 430 ▶ (edit:complex-candidate Docsafe &code-suffix=/ &display-suffix='' &style='01;34') 431 ▶ (edit:complex-candidate Documents &code-suffix=/ &display-suffix='' &style='01;34') 432 ... 433 ~> edit:complete-filename .elvish/ 434 ▶ (edit:complex-candidate .elvish/aliases &code-suffix=/ &display-suffix='' &style='01;34') 435 ▶ (edit:complex-candidate .elvish/db &code-suffix=' ' &display-suffix='' &style='') 436 ▶ (edit:complex-candidate .elvish/epm-installed &code-suffix=' ' &display-suffix='' &style='') 437 ▶ (edit:complex-candidate .elvish/lib &code-suffix=/ &display-suffix='' &style='01;34') 438 ▶ (edit:complex-candidate .elvish/rc.elv &code-suffix=' ' &display-suffix='' &style='') 439 ``` 440 441 ## edit:complete-getopt 442 443 ```elvish 444 edit:complete-getopt $args $opts $handlers 445 ``` 446 447 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: 448 449 - `$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](#argument-completer) function. 450 - `$opts` 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 of `short` or `long` needs to be specified): 451 - `short` contains the one-letter short option, if any, without the dash. 452 - `long` contains the long option name, if any, without the initial two dashes. 453 - `arg-optional`, if set to `$true`, specifies that the option receives an optional argument. 454 - `arg-mandatory`, if set to `$true`, specifies that the option receives a mandatory argument. Only one of `arg-optional` or `arg-mandatory` can be set to `$true`. 455 - `desc` can be set to a human-readable description of the option which will be displayed in the completion menu. 456 - `$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 of `edit:complex-candidate`. If the last element of the list is the string `...`, then the last handler is reused for all following arguments. 457 458 Example: 459 460 ```elvish-transcript 461 ~> for args [ [''] ['-'] ['-a' ''] [ arg1 '' ] [ arg1 arg2 '']] { 462 echo "args = "(to-string $args) 463 edit:complete-getopt $args [ [&short=a &long=all &desc="Show all"] ] [ [_]{ put first1 first2 } [_]{ put second1 second2 } ... ] 464 } 465 args = [''] 466 ▶ first1 467 ▶ first2 468 args = [-] 469 ▶ (edit:complex-candidate -a &code-suffix='' &display-suffix=' (Show all)' &style='') 470 ▶ (edit:complex-candidate --all &code-suffix='' &display-suffix=' (Show all)' &style='') 471 args = [-a ''] 472 ▶ first1 473 ▶ first2 474 args = [arg1 ''] 475 ▶ second1 476 ▶ second2 477 args = [arg1 arg2 ''] 478 ▶ second1 479 ▶ second2 480 ``` 481 482 ## edit:styled 483 484 ```elvish 485 edit:styled $text $styles 486 ``` 487 488 Construct an abstract styled text. The `$text` argument can be an arbitrary 489 string, while the `$styles` argument is a list or semicolon-delimited string 490 of the following styles: 491 492 * Text styles: `bold`, `dim`, `italic`, `underlined`, `blink`, `inverse`. 493 494 * Text colors: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, 495 `lightgray`, and their corresponding light colors: `gray`, `lightred`, 496 `lightgreen`, `lightyellow`, `lightblue`, `lightmagenta`, `lightcyan` and 497 `white`. 498 499 * Background colors: any of the text colors with a `bg-` prefix (e.g. `bg-red` 500 for red background), plus `bg-default` for default background color. 501 502 * An [ANSI SGR 503 parameter](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_.28Select_Graphic_Rendition.29_parameters) 504 code (e.g. `1` for bold), subject to terminal support. 505 506 Note that the result of `edit:styled` is an abstract data structure, not an 507 ANSI sequence. However, it stringifies to an ANSI sequence, so you rarely have 508 to convert it. To force a conversion, use `to-string`: 509 510 ```elvish-transcript 511 ~> edit:styled haha green 512 ▶ (edit:styled haha [green]) 513 ~> echo (edit:styled haha green) # output is green 514 haha 515 ~> to-string (edit:styled haha green) 516 ▶ "\e[32mhaha\e[m" 517 ``` 518 519 The forced conversion is useful when e.g. assigning to `$value-out-indicator`: 520 521 ```elvish-transcript 522 ~> value-out-indicator = (to-string (edit:styled '> ' green)) 523 ~> put lorem ipsum # leading '> ' is green 524 > lorem 525 > ipsum 526 ``` 527 528 The styled text can be inspected by indexing: 529 530 ```elvish-transcript 531 ~> s = (edit:styled haha green) 532 ~> put $s[text] $s[styles] 533 ▶ haha 534 ▶ [green] 535 ``` 536 537 538 ## $edit:current-command 539 540 Contains the content of the current input. Setting the variable will cause the 541 cursor to move to the very end, as if 542 `edit-dot = (count $edit:current-command)` has been invoked. 543 544 This API is subject to change. 545 546 547 ## $edit:-dot 548 549 Contains the current position of the curosr, as a byte position within 550 `$edit:current-command`. 551 552 553 ## $edit:max-height 554 555 Maximum height the editor is allowed to use, defaults to `+Inf`. 556 557 By default, the height of the editor is only restricted by the terminal 558 height. Some modes like location mode can use a lot of lines; as a result, it 559 can often occupy the entire terminal, and push up your scrollback buffer. 560 Change this variable to a finite number to restrict the height of the editor. 561 562 563 ## $edit:completion:matcher 564 565 See [the Matcher section](#matcher). 566 567 568 ## $edit:prompt 569 570 See [Prompts](#prompts). 571 572 573 ## $edit:-prompt-eagerness 574 575 See [Prompt Eagerness](#prompt-eagerness). 576 577 578 ## $edit:prompt-stale-threshold 579 580 See [Stale Prompt](#stale-prompt). 581 582 583 ## $edit:prompt-stale-transformer 584 585 See [Stale Prompt](#stale-prompt). 586 587 588 ## $edit:rprompt 589 590 See [Prompts](#prompts). 591 592 593 ## $edit:-rprompt-eagerness 594 595 See [Prompt Eagerness](#prompt-eagerness). 596 597 598 ## $edit:rprompt-persistent 599 600 See [RPrompt Persistency](#rprompt-persistency). 601 602 603 ## $edit:rprompt-stale-threshold 604 605 See [Stale Prompt](#stale-prompt). 606 607 608 ## $edit:rprompt-stale-transformer 609 610 See [Stale Prompt](#stale-prompt).