我的命令行现代化历程 - 持续更新中

基于 POSIX 的 Shell,包含 bash、zsh 的历史都太悠久了,有点不向前兼容的 fish 也不敢做颠覆性的革新。一提到命令行的编辑器必谈 vi/vim/emacs,但它们的整个快捷键、操作方式也和现代 GUI 模式下的编辑器差异太大。都什么年代了,干嘛还要死守着这些老古董不放呢。

前一阵看了一下 powershell 给我了我一些启发,原来管道之间还可以传对象,让后续的数据处理更加简单方便。

所以我打算将我的命令行系统现代化一下,抛弃一些历史悠久的东西,诚然这会有额外的学习成本,不过持续学习是程序员的基本素质了。

Shell - nushell

Powershell 虽好,但是它启动得太慢了,无意间我发现了 nushell,这熟悉的面向对象的管道、结构化的数据存储和传输、二十毫秒左右的启动速度,简直不要太棒了。

具体安装流程什么的看官网吧,我只贴一下我首次安装后的配置流程。安装后执行 nu 命令就可以进入 nushell。

我只使用 nushell 自己的配置能力,所以看着会有点绕。但好处是不受配置文件路径配置不同的影响,可以照抄。

1. 配置默认编辑器

nushell 自己的配置能力需要 $env.config.buffer_editor 获取编辑器,它的默认值是 null 意味着当你直接执行 config env 的时候它会报错:

Error:   × No editor configured
   ╭─[entry #18:1:1]
 1 │ config env
   · ─────┬────
   ·      ╰── Please specify one via `$env.config.buffer_editor` or `$env.EDITOR`/`$env.VISUAL`
   ╰────
  help: Nushell's config file can be found with the command: $nu.config-path. For more help: (https://nushell.sh/book/configuration.html#configurations-with-built-
        in-commands)

所以这里需要手工改一下,$env 的具体说明请参考官方文档。

$env.config.buffer_editor = vim  # 这里暂时修改为 vim,也可以选择自己称手的编辑器

将默认编辑器配置持久化

执行 config nu 打开 nushell 的配置文件,并找到 buffer_editor 这行,将原来的 null 改为自己的编辑器

    buffer_editor: vim # command that will be used to edit the current line buffer with ctrl+o, if unset fallback to $env.EDITOR and $env.VISUAL

2. 还原环境变量

需要特别说明的是 nushell 的环境变量和 POSIX Shell 差异巨大,它是结构化的存储,如果使用 echo $PATH 会报错告诉你根本不支持:

Error: nu::parser::env_var_not_var

  × Use $env.PATH instead of $PATH.
   ╭─[entry #6:1:6]
 1 │ echo $PATH
   ·      ──┬──
   ·        ╰── use $env.PATH instead of $PATH
   ╰────

要访问环境变量直接使用 $env.[ENVIRONMENT_VARIABLE] 即可。上一章节中的 config 也是以环境变量存储,但是是一个嵌套的对象。 -- 这才是我想要的命令行环境。

$PATH

nushell 的 $PATH 默认只有 /usr/bin/bin 两个,对于装了 brew 的我来说是不可接受的。

首先要在原来的 Shell 中通过 echo $PATH 获取原来的环境变量,我这里是:

/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/opt/homebrew/sbin:/usr/local/sbin:/usr/sbin:/sbin

而在 nushell 中 $env.PATH 是这样的:

╭───┬────────────────────╮
│ 0 │ /usr/bin           │
│ 1 │ /bin               │
╰───┴────────────────────╯

其实我没有找到 nushell 的 PATH 在哪里初始化,但是按照官方文档 的说明,目前 nushell 中的路径在整个路径列表中是在中间的,这也就意味着需要在前面添几个,后面添几个才可以。

执行 config env,进入环境变量编辑界面,找到 $env.PATH 段,改成下面这样,prepend 表示在数组前面添加路径,append 表示在后面添加路径:

# To add entries to PATH (on Windows you might use Path), you can use the following pattern:
# $env.PATH = ($env.PATH | split row (char esep) | prepend '/some/path')
# An alternate way to add entries to $env.PATH is to use the custom command `path add`
# which is built into the nushell stdlib:
# use std "path add"
# $env.PATH = ($env.PATH | split row (char esep))
# path add /some/path
# path add ($env.CARGO_HOME | path join "bin")
# path add ($env.HOME | path join ".local" "bin")
# $env.PATH = ($env.PATH | uniq)
    
$env.PATH = ( 
  $env.PATH |
  prepend /usr/local/bin |
  prepend /opt/homebrew/bin |
  append /opt/homebrew/sbin |
  append /usr/local/sbin |
  append /usr/sbin |
  append /sbin
) 

保存后,重启 nushell,再执行 $env.PATH 就会输出成这样,即为正常 ,通过 brew 安装的所有命令行工具就回来了:

╭───┬────────────────────╮
│ 0 │ /opt/homebrew/bin  │
│ 1 │ /usr/local/bin     │
│ 2 │ /usr/bin           │
│ 3 │ /bin               │
│ 4 │ /opt/homebrew/sbin │
│ 5 │ /usr/local/sbin    │
│ 6 │ /usr/sbin          │
│ 7 │ /sbin              │
╰───┴────────────────────╯

其他资料

  1. 推荐从别的 Bash 迁移过来的参考一下,方便理解它的概念和差异 -Coming from Bash
  2. nushell 的第三方扩展 - nu_scripts,有一个 nupm 项目貌似可以用来下载安装,我还在测试中。

编辑器 - Micro

其实绝大多数情况下我们在命令行下只需要一个简单的文本编辑工具,传统的编辑器学习成本太高了,vim、emacs 只留如果不看文档进入后都不知道该如何退出来,即使是足够简化的 nano 也需要重新学习。所以我换成 micro 了,快捷键和 GUI 下的编辑器基本相同:

  1. 关闭 Ctrl + Q
  2. 保存 Ctrl + S
  3. 查找 Ctrl + F
  4. 撤销 Ctrl + Z

更多请参考官方的 keybindings.md。另外,它还有一些不错的插件

编辑器 - Helix

vim 的最大问题是在于它本身过于简单,但如果要让它能用起来还得加上一堆插件。Helix 就比较简单了,基本开箱即用。

TODO: 这个我还得多用用再来写。

版权所有丨转载请注明出处:https://kxq.io/archives/my-journey-to-modernize-cli