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