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: