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 1/2] 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: From c5e46499b340d829affa1e4794d4fb414e697d45 Mon Sep 17 00:00:00 2001 From: NotTheDr01ds <32344964+NotTheDr01ds@users.noreply.github.com> Date: Sat, 21 Dec 2024 11:32:44 -0500 Subject: [PATCH 2/2] Feedback from review --- book/line_editor.md | 90 +++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/book/line_editor.md b/book/line_editor.md index 466d7b5409d..cb69373c981 100644 --- a/book/line_editor.md +++ b/book/line_editor.md @@ -33,29 +33,28 @@ Reedline allows Nushell commandlines to extend across multiple lines. This can b It can even be used to continue a single command across multiple lines: + ::: details Example + ```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 + 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]' | # filenames starting with a digit - get name | # get the filenames - mv ...$in ./backups/ # and move to backups folder + 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. @@ -64,9 +63,9 @@ Reedline allows Nushell commandlines to extend across multiple lines. This can b ```nu ls - | where name =~ '^[0-9]' # filenames starting with a digit - | get name # get the filenames - | mv ...$in ./backups/ # and move to backups folder + | where name =~ '^[0-9]' # Files starting with a digit + | get name + | mv ...$in ./backups/ ``` ::: tip @@ -107,6 +106,8 @@ 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 | @@ -122,21 +123,13 @@ Each edit mode comes with common keybindings for Vi and Emacs text editing. | 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+P | Move up | +| Ctrl+N | Move down | +| Ctrl+B | Move left | | 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 | @@ -144,31 +137,31 @@ Each edit mode comes with common keybindings for Vi and Emacs text editing. ### 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 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 +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 | @@ -187,6 +180,8 @@ As with Vi, many motions and actions can be combined with an optional count in n ### Vi-normal Actions +These actions can be combined with many of the [motions above](#vi-normal-motions). + | Key | Action | | ----------------------------- | -------------------------------------------------- | | d | Delete | @@ -585,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 @@ -594,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