zsh command line editting

2024-08-14 2024-08-19 Mon 08:21

Table of Contents

1. 前言

zsh 在提供了很多的内置命令以及自己一套的配置系统之外还提供了非常方便的命令行编 辑功能. 所谓的命令行编辑, 就是可以在命令行中以 Emacs 或者 VIM 的 keymap 去进行编辑. 此外 zsh 还提供了一些可以自定义 keymap 的命令, 比如 keybind 等

2. zsh 的 keymap

在 zsh 中所谓的 keymap 是按键序列和 zsh 命令行编辑命令的一个映射.

zsh 一共提供了 8 个内置的 keymap, 分别是

  • emacs EMACS emulation
  • viins vi emulation - insert mode
  • vicmd vi emulation - command mode
  • viopp vi emulation - operator pending
  • visual vi emulation - selection active
  • isearch incremental search mode
  • command read a command name
  • .safe fallback keymap

其中, emacs keymap 为对 Emacs 的命令的一个模拟, 比如 C-f 会让光标向前移动 一格, C-b 会让光标向后移动一格. viins vincmd viopp visual 这些都是为了模拟 VIM 的不同模式, 而不得不生成的 keymap. 个人建议纯用 emacs 的 keymap 就够 了. zsh 默认状态下是启用 Emacs 模式的, 只有在 VISUAL 或者 EDITOR 这两个 环境变量中包含有 vi 才会启用 VIM 模式. .safe keymap 为后备模式, 即只有在无法进入 viins 等 VIM keymap 或者 emacs keymap 才会进入 .safe keymap. 在这个 keymap 中, 每个按键的意义 (除了 ^J 和 ^M 外) 都只是插入自身 (self-insert). 在 emacs keymap 下按 M-x 可以进入 command keymap, 按 C-s 或者 C-r 可以 进入 isearch keymap.

3. zsh 自定义 keymap

zsh 提供了工具 bindkey 可以让用户对 keymap 进行操作, 比如在特定的 keymap 中添加新的按键顺序与编辑命令的映射. 如果想要在 emacs keymap 中加入 C-g 对应 光标向前移动可以在命令行中或者 zsh 的配置文件中加入 bindkey -e ^G forward-char. 其中 forward-char 是一个内置的 widget, 所谓的 widget 是 zsh 当中实现了一 些小功能的一个单位, 在 kepmap 中和按键顺序对应的只能是 widget. 用 emacs 中 的术语来解释的话就是类似 interactive function 的东西.

4. 后记

这里只是对于 zsh command line editing 做了一个比较简略的介绍, 如果对这一部分比 较有兴趣可以通过 man zshzle 来阅读很多的资料.


Author: Harumi Kiyama (lucius0720@hotmail.com) Create Date: 2024-08-14 Last modified: 2024-08-19 Mon 08:21 Creator: Emacs 31.0.50 (Org mode 9.7.9)