﻿---
title: Shell Inline Editing & Vim/Emacs 快捷键
date: 2025-08-14
excerpt: 深入解析终端的行内编辑技巧，通过配置 Vi 和 Emacs 风格快捷键，以及使用外部编辑器（Line Editor）提升工作流效率。
tags:
  - Terminal
  - Shell
  - Workflow
  - Linux
  - Nushell
  - Vim
cover: https://assets.vluv.space/cover/inline-editing.avif
---

## Inline Edit Mode: Emacs or Vim

Shell 一般都是以 `emacs` 做为默认的快捷键；此外，还可以为Shell设置Vim风格的快捷键:

- **Bash**: `{bash} set -o vi`
- **Zsh**: `{zsh} bindkey -v`
- **Nushell**: `{nu} $env.config.edit_mode = vi`
- **Fish**: `{fish} fish_vi_key_bindings`

![shell_emacs_shortcut|700](https://assets.vluv.space/piclist-clipboard-images-20260206183527683.avif)

## Vim Tricks

### Text Objects

Text Objects[^1] 是 Vim 最吸引我的一个 feature，允许以语义为单位操作文本；删除括号(bracket)或引号(quote)内的内容，都可以很流畅的完成。例如，在 **NORMAL 模式**下将光标移至括号内，键入 `di(` 或 `dib` (delete inside bracket)即可删除括号内的 Text

```nushell
$env.LS_COLORS = (vivid generate catppuccin-mocha)
# press `dib` inside bracket
$env.LS_COLORS = ()
```

### Cursor Jump

在长命令中快速移动时，使用Vim的快捷键会非常高效

| 按键      | 跳转逻辑                        |
| --------- | ------------------------------- |
| `w` / `b` | 下一个单词 / 上一个单词         |
| `I` / `A` | 跳转至行首插入 / 跳转至行尾插入 |
| `F<char>` | 向前搜索字符 `<char>` 并跳转    |
| `f<char>` | 向后搜索字符 `<char>` 并跳转    |

当编辑 `UNIX` 和 `GNU` 风格的命令行参数时，这种情况下用 `F/f` 将在不同参数之间切换还是很流畅的

| 风格类型    | 前缀 | 格式   | 示例                   | 跳转策略               |
| ----------- | ---- | ------ | ---------------------- | ---------------------- |
| **Unix**    | `-`  | 单字母 | `{shell} ls -la`       | 使用 `f-` 快速跳至选项 |
| **GNU**     | `--` | 单词   | `{shell} grep --color` | 使用 `f-`              |
| **Windows** | `/`  | 单词   | `{shell} DIR /W`       | 使用 `f/`              |

## Line Editor

许多 Shell 也支持使用命令外部编辑器中对命令进行编辑，这样就可以使用 NeoVim, Helix 来编辑命令了 🤓，如果不在乎启动速度，甚至可以用 VSCode。

| Shell   | Vi 模式             | Emacs 模式      |
| ------- | ------------------- | --------------- |
| Bash    | Normal 模式下按 `v` | `Ctrl+x Ctrl+e` |
| Zsh     | 不知道喵 `චᆽච`      | 不知道喵 `චᆽච`  |
| Fish    | `Alt+e`             | `Alt+e`         |
| Nushell | `Ctrl+o`            | `Ctrl+o`        |

下面简单演示一下，假如要使用 `scp` 将 remote machine 上的文件复制到本地，但是 remote machine 的 host name 写错了

<video autoplay loop muted playsinline>
    <source src="https://assets.vluv.space/inline-editing.mp4" type="video/mp4" alt="demo">
</video>

**不觉得这很酷吗，作为一名理工男我觉得这太酷了** 🤓🤓🤓

### Change Default Editor

如何指定编辑命令的编辑器？

一般来说，Shell 会读取 `VISUAL` 或 `EDITOR` 环境变量，决定使用哪个编辑器。像 NuShell 的话也可以设置 `$env.config.buffer_editor` 变量

```shell
# ----------------------------------------
# For Nushell (config.nu)
# ----------------------------------------
$env.config = {
   # 推荐使用启动速度快的编辑器，如 Helix/Neovim/Vim
   buffer_editor: "helix"  # [!code ++]
}

# ----------------------------------------
# For Bash / Zsh (.bashrc or .zshrc)
# ----------------------------------------
# VISUAL 优先级通常高于 EDITOR
export VISUAL=nvim  # [!code ++]
export EDITOR=nvim

# ----------------------------------------
# For Fish (config.fish)
# ----------------------------------------
set -gx VISUAL nvim  # [!code ++]
```

Unix 设置系统环境变量，也可以参考这篇文章的方式 👉 [[unix_environment_variables|Set System Env-Vars in UNIX]]

[^1]: Text Object可以是引号，括号，单词，句子，段落等。更多信息可以参考 [Motion#text-objects - Neovim docs](https://neovim.io/doc/user/motion.html#text-objects)