diff --git a/book/line_editor.md b/book/line_editor.md index d050653f875..cb69373c981 100644 --- a/book/line_editor.md +++ b/book/line_editor.md @@ -1,124 +1,207 @@ # Reedline, Nu's Line Editor -Nushell's line editor [Reedline](https://github.com/nushell/reedline) is a -cross-platform line reader designed to be modular and flexible. The engine is -in charge of controlling the command history, validations, completions, hints -and screen paint. +Nushell's line-editor [Reedline](https://github.com/nushell/reedline) is +cross-platform and designed to be modular and flexible. The line-editor is +in charge of controlling the command history, validations, completions, hints, +screen paint, and more. -## Configuration +[[toc]] -### Editing Mode +## Multi-line Editing -Reedline allows you to edit text using two modes: vi and emacs. If not -specified, the default edit mode is emacs mode. In order to select your -favorite you need to modify your config file and write down your preferred -mode. +Reedline allows Nushell commandlines to extend across multiple lines. This can be accomplished using several methods: -For example: +1. Pressing Enter when a bracketed expression is open. + + For example: + + ```nu + def my-command [] { + ``` + + Pressing Enter after the open-bracket will insert a newline. This will also occur with opening (and valid) `(` and `[` expressions. + + This is commonly used to create blocks and closures (as above), but also list, record, and table literals: + + ```nu + let file = { + name: 'repos.sqlite' + hash: 'b939a3fa4ca011ca1aa3548420e78cee' + version: '1.4.2' + } + ``` + + It can even be used to continue a single command across multiple lines: + + ::: details Example + + ```nu + ( + tar + -cvz + -f archive.tgz + --exclude='*.temp' + --directory=../project/ + ./ + ) + ``` + + ::: + +2. Pressing Enter at the end of a line with a trailing pipe-symbol (`|`). + + ```nu + ls | + where name =~ '^[0-9]' | # Comments after a trailing pipe are okay + get name | + mv ...$in ./backups/ + ``` + +3. Manually insert a newline using Alt+Enter or Shift+Enter. + + This can be used to create a somewhat more readable version of the previous commandline: + + ```nu + ls + | where name =~ '^[0-9]' # Files starting with a digit + | get name + | mv ...$in ./backups/ + ``` + + ::: tip + It's possible that one or both of these keybindings may be intercepted by the terminal application or window-manager. For instance, Windows Terminal (and most other terminal applications on Windows) assign Alt+Enter to expand the terminal to full-screen. If neither of the above keybindings work in your terminal, you can assign a different keybinding to: + + ```nu + event: { edit: insertnewline } + ``` + + See [Keybindings](#keybindings) below for more details. + + ::: + +4. Pressing Ctrl+O opens the current commandline in your editor. Saving the resulting file and exiting the editor will update the commandline with the results. + +## Setting the Editing Mode + +Reedline allows you to edit text using two modes — Vi and Emacs. If not +specified, the default mode is Emacs. To change the mode, use the +`edit_mode` setting. ```nu - $env.config = { - ... - edit_mode: emacs - ... - } +$env.config.edit_mode = 'vi' ``` -#### Default Keybindings - -Each edit mode comes with the usual keybinding for vi and emacs text editing. - -Emacs and Vi Insert keybindings - -| Key | Event | -| ----------- | --------------------- | -| Esc | Esc | -| Backspace | Backspace | -| End | Move to end of line | -| End | Complete history hint | -| Home | Move to line start | -| Ctr + c | Cancel current line | -| Ctr + l | Clear screen | -| Ctr + r | Search history | -| Ctr + Right | Complete history word | -| Ctr + Right | Move word right | -| Ctr + Left | Move word left | -| Up | Move menu up | -| Up | Move up | -| Down | Move menu down | -| Down | Move down | -| Left | Move menu left | -| Left | Move left | -| Right | History hint complete | -| Right | Move menu right | -| Right | Move right | -| Ctr + b | Move menu left | -| Ctr + b | Move left | -| Ctr + f | History hint complete | -| Ctr + f | Move menu right | -| Ctr + f | Move right | -| Ctr + p | Move menu up | -| Ctr + p | Move up | -| Ctr + n | Move menu down | -| Ctr + n | Move down | - -Vi Normal keybindings - -| Key | Event | -| ------- | ------------------- | -| Ctr + c | Cancel current line | -| Ctr + l | Clear screen | -| Up | Move menu up | -| Up | Move up | -| Down | Move menu down | -| Down | Move down | -| Left | Move menu left | -| Left | Move left | -| Right | Move menu right | -| Right | Move right | - -Besides the previous keybindings, while in Vi normal mode you can use the classic -vi mode of executing actions by selecting a motion or an action. The available -options for the combinations are: - -Vi Normal motions - -| Key | motion | -| --- | ----------------- | -| w | Word | -| 0 | Line start | -| $ | Line end | -| f | Right until char | -| t | Right before char | -| F | Left until char | -| T | Left before char | - -Vi Normal actions - -| Key | action | -| --- | ------------------------------- | -| d | Delete | -| p | Paste after | -| P | Paste before | -| h | Move left | -| l | Move right | -| j | Move down | -| k | Move up | -| w | Move word right | -| b | Move word left | -| i | Enter Vi insert at current char | -| a | Enter Vi insert after char | -| 0 | Move to start of line | -| ^ | Move to start of line | -| $ | Move to end of line | -| u | Undo | -| c | Change | -| x | Delete char | -| s | History search | -| D | Delete to end | -| A | Append to end | - -### Command History +This can be changed at the commandline or persisted in `config.nu`. + +::: note +Vi is a "modal" editor with "normal" mode and an "insert" mode. We recommend +becoming familiar with these modes through the use of the Vim or Neovim editors +before using Vi mode in Nushell. Each has a built-in tutorial covering the basics +(and more) of modal editing. +::: + +## Default Keybindings + +Each edit mode comes with common keybindings for Vi and Emacs text editing. + +### Emacs and Vi-insert Keybindings + +These keybinding events apply to both Emacs and Vi-insert mode: + +| Key | Event | +| ------------------------------------------ | ----------------------------------- | +| Shift+Enter | Insert newline | +| Alt+Enter | Insert newline | +| Backspace | Backspace | +| End | Move to end of line | +| End | Complete history hint | +| Home | Move to line start | +| Ctrl+C | Cancel current line | +| Ctrl+L | Clear screen | +| Ctrl+R | Search history | +| Ctrl+ (Right Arrow) | Complete history word | +| Ctrl+ (Right Arrow) | Move word right | +| Ctrl+ (Left Arrow) | Move word left | +| (Up Arrow) | Move up | +| (Down Arrow) | Move down | +| (Left Arrow) | Move left | +| (Right Arrow) | Move right | +| Ctrl+P | Move up | +| Ctrl+N | Move down | +| Ctrl+B | Move left | +| Ctrl+F | Move right | +| (Right Arrow) | History-hint complete | +| Ctrl+F | History-hint complete | +| Alt+F | History-hint complete one word | +| Alt+ (Left Arrow) | History-hint complete one word less | + +### Vi-insert Keybindings + +These keybinding events apply only to Vi-insert mode: + +| Key | Event | +| -------------- | ------------------------ | +| Esc | Switch to Vi-normal mode | + +### Vi-normal Keybindings + +These keybinding events apply only to Vi-normal mode: + +| Key | Event | +| ------------------------------------------- | ------------------- | +| Ctrl+C | Cancel current line | +| Ctrl+L | Clear screen | +| (Up Arrow) | Move up | +| (Down Arrow) | Move down | +| (Left Arrow) | Move left | +| (Right Arrow) | Move right | +| Ctrl>+ (Right Arrow) | Move right one word | +| Ctrl>+ (Left Arrow) | Move left one word | + +### Vi-normal Motions + +As with Vi, many motions and actions can be combined with an optional count in normal-mode. For example, 3dw deletes the next three words. + +| Key | Motion | +| -------------------------------------- | --------------------------------------------- | +| w | Move to beginning of next word | +| e | Move to end of current or next word | +| b | Move to beginning of current or previous word | +| 0 | Move to start of line | +| $ | Move to end of line | +| h | Move left | +| l | Move right | +| j | Move down | +| k | Move up | +| f+\ | Move right to \ | +| t+\ | Move right to before \ | +| Shift+F+\ | Move left to \ | +| Shift+T+\ | Move left to after \ | + +### Vi-normal Actions + +These actions can be combined with many of the [motions above](#vi-normal-motions). + +| Key | Action | +| ----------------------------- | -------------------------------------------------- | +| d | Delete | +| Shift+D | Delete to end of line | +| p | Paste after current character | +| Shift+P | Paste before current character | +| i | Enter Vi insert-mode (append) at current character | +| Shift+I | Enter insert-mode at beginning of line | +| a | Append after current character | +| Shift+A | Append to end of line | +| 0 | Move to start of line | +| ^ | Move to start of line | +| $ | Move to end of line | +| c | Change | +| r | Replace | +| s | Substitute character(s) | +| x | Delete character | +| u | Undo | + +## Command History As mentioned before, Reedline manages and stores all the commands that are edited and sent to Nushell. To configure the max number of records that @@ -136,50 +219,9 @@ Reedline should store you will need to adjust this value in your config file: } ``` -### Customizing your Prompt - -Reedline prompt is also highly customizable. In order to construct your perfect -prompt, you could define the next environment variables in your config file: - -```nu -# Use nushell functions to define your right and left prompt -def create_left_prompt [] { - let path_segment = ($env.PWD) - - $path_segment -} +## Customizing the Prompt -def create_right_prompt [] { - let time_segment = ([ - (date now | format date '%m/%d/%Y %r') - ] | str join) - - $time_segment -} - -$env.PROMPT_COMMAND = { create_left_prompt } -$env.PROMPT_COMMAND_RIGHT = { create_right_prompt } -``` - -::: tip -You don't have to define the environment variables using Nushell -functions. You can use simple strings to define them. -::: - -You can also customize the prompt indicator for the line editor by modifying -the next env variables. - -```nu -$env.PROMPT_INDICATOR = "〉" -$env.PROMPT_INDICATOR_VI_INSERT = ": " -$env.PROMPT_INDICATOR_VI_NORMAL = "〉" -$env.PROMPT_MULTILINE_INDICATOR = "::: " -``` - -::: tip -The prompt indicators are environment variables that represent the -state of the prompt -::: +The Reedline prompt is configured using a number of environment variables. See [Prompt Configuration](./configuration.md#prompt-configuration) for details. ## Keybindings @@ -538,8 +580,7 @@ e.g. to disable screen clearing with `Ctrl + l` for all edit modes ### Troubleshooting Keybinding Problems -Your terminal environment may not always propagate your key combinations on to nushell the way you expect it to. -You can use the command [`keybindings listen`](/commands/docs/keybindings_listen.md) to figure out if certain keypresses are actually received by nushell, and how. +Your terminal environment may not always propagate your key combinations on to Nushell the way you expect it to. You can use the command [`keybindings listen`](/commands/docs/keybindings_listen.md) to determine if certain keypresses are actually received by Nushell, and how. ## Menus @@ -547,6 +588,30 @@ Thanks to Reedline, Nushell has menus that can help you with your day to day shell scripting. Next we present the default menus that are always available when using Nushell +### Menu Keybindings + +When a menu is active, some keybindings change based on the keybinding [`until` specifier](#until-type) discussed above. Common keybindings for menus are: + +| Key | Event | +| ------------------------------- | -------------------- | +| Tab | Select next item | +| Shift+Tab | Select previous item | +| Enter | Accept selection | +| (Up Arrow) | Move menu up | +| (Down Arrow) | Move menu down | +| (Left Arrow) | Move menu left | +| (Right Arrow) | Move menu right | +| Ctrl+P | Move menu up | +| Ctrl+N | Move menu down | +| Ctrl+B | Move menu left | +| Ctrl+F | Move menu right | + +::: note +Menu direction behavior varies based on the menu type (see below). For example, +in a `description` menu, "Up" and "Down" apply to the "Extra" list, but in a +`list` menu the directions apply to the selection. +::: + ### Help Menu The help menu is there to ease your transition into Nushell. Say you are diff --git a/book/quick_tour.md b/book/quick_tour.md index e0b3267d385..7d68e530187 100644 --- a/book/quick_tour.md +++ b/book/quick_tour.md @@ -155,6 +155,7 @@ Nushell commands can extend across multiple lines for readability. The above is ls | sort-by size | reverse | first | get name | cp $in ~ ``` +See Also: [Multi-line Editing](./line_editor.md#multi-line-editing) ::: The first three lines are the same commands we used in the second example above, so let's examine the last three: diff --git a/book/thinking_in_nu.md b/book/thinking_in_nu.md index 24c675f1af3..898d4054bc1 100644 --- a/book/thinking_in_nu.md +++ b/book/thinking_in_nu.md @@ -162,6 +162,7 @@ echo 50 echo 60 ``` +See Also: [Multi-line Editing](./line_editor.md#multi-line-editing) ::: In all of the above: