From 08ed20668603a3e2286151d99cbeaa4412e48c8b Mon Sep 17 00:00:00 2001 From: NotTheDr01ds <32344964+NotTheDr01ds@users.noreply.github.com> Date: Sat, 21 Dec 2024 00:45:08 -0500 Subject: [PATCH] Multi-line editing and other updates --- book/line_editor.md | 355 +++++++++++++++++++++++------------------ book/quick_tour.md | 1 + book/thinking_in_nu.md | 1 + 3 files changed, 203 insertions(+), 154 deletions(-) diff --git a/book/line_editor.md b/book/line_editor.md index d050653f875..466d7b5409d 100644 --- a/book/line_editor.md +++ b/book/line_editor.md @@ -1,124 +1,212 @@ # 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: + + ```nu + ( + ffmpeg + -i input.mp4 + -vf "scale=1280:720,setsar=1:1" + -b:v 1500k + -preset veryfast + -crf 23 + -c:a aac + -b:a 192k + -movflags +faststart + -y + output.mp4 + ) + ``` + +2. Pressing Enter at the end of a line with a trailing pipe-symbol (`|`). + + ```nu + ls | + where name =~ '^[0-9]' | # filenames starting with a digit + get name | # get the filenames + mv ...$in ./backups/ # and move to backups folder + ``` + +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]' # filenames starting with a digit + | get name # get the filenames + | mv ...$in ./backups/ # and move to backups folder + ``` + + ::: 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 + +| 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 | +| Ctrl+P | Move up | +| (Up Arrow) | Move menu up | +| Ctrl+P | Move menu up | +| (Down Arrow) | Move down | +| Ctrl+N | Move down | +| (Down Arrow) | Move menu down | +| Ctrl+N | Move menu down | +| (Left Arrow) | Move left | +| Ctrl+B | Move left | +| (Left Arrow) | Move menu left | +| Ctrl+B | Move menu left | +| (Right Arrow) | Move right | +| Ctrl+F | Move right | +| (Right Arrow) | Move menu right | +| Ctrl+F | Move menu 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 + +| Key | Event | +| -------------- | ------------------------ | +| Esc | Switch to Vi-normal mode | + +### Vi-normal Keybindings + +| Key | Event | +| ------------------------------------------- | ------------------- | +| Ctrl+C | Cancel current line | +| Ctrl+L | Clear screen | +| (Up Arrow) | Move menu up | +| (Up Arrow) | Move up | +| (Down Arrow) | Move menu down | +| (Down Arrow) | Move down | +| (Left Arrow) | Move menu left | +| (Left Arrow) | Move left | +| (Right Arrow) | Move menu right | +| (Right Arrow) | Move right | +| Ctrl>+ (Right Arrow) | Move right one word | +| Ctrl>+ (Left Arrow) | Move left one word | + +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. + +### Vi-normal Motions + +| 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 + +| 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 +224,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 -} - -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. +## Customizing the Prompt -```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 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: