我大量使用命令行,多年来已从 迁移bash到zsh作为日常驱动程序外壳。我通常使用稍微定制的 oh-my-zsh 环境,但有些系统在 prezto 上;差异并不大。
我一直在为 zsh 使用的最高效的插件是zsh-syntax-highlighting和history-substring-search,最近我一直在使用非常强大的fzf插件来提取历史记录。
现在,我发现命令行中对我来说最大的痛点之一是命令参数重新排序。我经常尝试运行命令
command very/long/filesystem/path/to/argumentA another/filesystem/or/network/path/argumentB
Run Code Online (Sandbox Code Playgroud)
并意识到我已经把订单倒过来了。
另一种更常见的情况是当我们执行任何“手动部署”工作流程时:首先将新内容与真实内容进行比较,例如
diff /opt/app/static/www/a.html /home/user/docs/dev/src/a.html
cp /home/user/docs/dev/src/a.html /opt/app/static/www/a.html
Run Code Online (Sandbox Code Playgroud)
好的,好的,最后一个例子(这个有几个步骤),我不再保证。完美的现实世界示例就在这里。让我们用一些可爱的人类大小的文件列表来破解:
find /pool/backups -type f -print0 | xargs -0 ls -lh > filelisting
Run Code Online (Sandbox Code Playgroud)
我想以交互方式排序和挑选一些大小:
sort -rhk5 filelisting | fzf -m > /these/are/the_chosen
Run Code Online (Sandbox Code Playgroud)
不错,有效!哦,但我现在只需要路径,但不想重新运行find:
cut -d ' ' -f 10 /these/are/the_chosen
Run Code Online (Sandbox Code Playgroud)
输出是垃圾,因为我们遇到了ls -lh对空格变得活泼的挫折。但我有一个策略:加入连续的空间。让我们选择tr -s挤压空格字符,这里不需要正则表达式。虽然,tr需要标准输入:
cat /these/are/the_chosen | tr -s ' ' | cut -d ' ' -f 9- > filelist
Run Code Online (Sandbox Code Playgroud)
至此,我们感受到了在命令中剪切和粘贴参数的痛苦。我在这里的选择总是在尴尬的选择之间:我可以移动长路径或我可以移动命令。无论是哪种移动,我都必须伸手让鼠标复制它,或者我必须在新位置再次键入它。我赢不了。使用命令行,即使导航也很麻烦,而且在没有设置跳字热键的情况下非常麻烦。
我什至不能用我的鼠标在 shell 提示下快速跳转!(嘿,有人知道支持鼠标事件的外壳吗?)所以,这是我想消除的低效率。我想消除抓取外壳对象(例如有效路径字符串)的摩擦,并在我制作怪物管道原型时自由左右移动它。如果我有这个功能,我可以发送 5 次垃圾邮件以将路径推到cut& 标志的左侧,然后有机地构建管道的其余部分。
我相信缺乏行编辑能力是问题所在。在我想转置前 2 个参数的第一个示例中,我可以创建一个简单的 shell 脚本,我可能会调用cpto它来反转参数和委托给cp命令。但我不想这样做,在一般情况下它对我没有帮助,就像在第三个例子中一样。
我希望能够使用简单的组合键重新排列我输入的参数,就像我在 Vim 中使用sideways 等插件时可以对各种类型的列表进行排序一样。
zsh 有这样的插件吗?任何其他外壳都存在这样的插件吗?
如果不是,那么为 zsh 实现会有多困难?我认为 zsh-syntax-highlighting 插件证明应该可以标记参数。实际上,shell 知道如何从历史记录中获取单个参数:https : //stackoverflow.com/a/21439621/340947
痛点是如此严重和普遍,以至于我可能会编写一个简单的脚本来绑定到一个热键,该热键获取历史记录中的最后一个条目并为我交换最后 2 个参数,然后运行它。但这并不像行编辑器操作那样理想,这样交换可以交互地完成,而不是承诺运行命令。
也许对此的改进可能是注入!:0 !:2 !:1(zsh 很好地为我自动扩展),但这也存在很多问题:(1)如果没有尝试运行错误的命令,它将无法工作。超过一半的时间我想在输入错误命令后发现自己后交换 args,并且 (2) 经常有使用的标志,该代码段无法解释。
我还看到了这里显示的方法,这很好,但仍然非常不令人满意,因为对于长路径需要多次重复击键,并且 Ctrl+Y 行为只回忆最近被剪切的项目,而不是保持堆栈其中。很高兴知道,但对我来说几乎没用。
为了完整起见,现在采取的策略是使用任何合适的组合键来删除单词以删除较短的命令以重新排序,重新定位光标,使用鼠标从终端输出中复制已删除的参数,然后将其粘贴回. 普通人对此不以为然,但每次这样做都会让我感到有点死亡,因为我无法停止思考计算机为我完成这项任务是多么容易,以及我感到的不公正不得不将我的手伸向鼠标。
Sté*_*las 12
在 中zsh,默认情况下,所有对单词进行操作的小部件,包括transpose-words默认绑定到Alt+Tinemacs模式的小部件,都可以处理定义为 alnum+$WORDCHARS字符序列的单词。
$WORDCHARShas的默认值*?_-.[]~=/&;!#$%^(){}<>,所以包含/,所以只要这些路径不包含除此之外的字符,您就可以转置路径。这不适用于包含:, @, ,... 或被引用的路径。
但是您可以使用该select-word-style框架来更改按需一词的定义。
如果添加:
autoload -U select-word-style
zle -N select-word-style
bindkey '\ez' select-word-style
Run Code Online (Sandbox Code Playgroud)
给你~/.zshrc,然后按下Alt+Z,你会得到选择:
Word styles (hit return for more detail):
(b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit
(B), (N), (S), (W) as above with subword matching
?
Run Code Online (Sandbox Code Playgroud)
按“返回以获取更多详细信息”后:
(b)ash: Word characters are alphanumerics only
(n)ormal: Word characters are alphanumerics plus $WORDCHARS
(s)hell: Words are command arguments using shell syntax
(w)hitespace: Words are whitespace-delimited
(d)efault: Use default, no special handling (usually same as `n')
(q)uit: Quit without setting a new style
Run Code Online (Sandbox Code Playgroud)
所以按下S将允许您转置两个 shell 单词(因此包括那些包含引号空格或命令替换...) with Alt+T(或删除一个 with Ctrl+W,移回一个 withAlt+B等)。
看
info zsh select-word-style
Run Code Online (Sandbox Code Playgroud)
有关详细信息(假设您的系统上已安装 zsh 文档(zsh-docDebian 和衍生产品上的软件包))。
您会在那里找到一个部分,它看起来像是专门为您编写的,您可以调整以指定transpose-words当光标位于文件名或中间词等时您想要的行为方式:
下面是一些使用 word-context 样式来扩展上下文的示例。
Run Code Online (Sandbox Code Playgroud)zstyle ':zle:*' word-context \ "*/*" filename "[[:space:]]" whitespace zstyle ':zle:transpose-words:whitespace' word-style shell zstyle ':zle:transpose-words:filename' word-style normal zstyle ':zle:transpose-words:filename' word-chars ''这提供了两种不同的使用转置词的方法,具体取决于光标是在单词之间的空格上还是在文件名上,这里是任何包含 / 的单词。在空格上,标准 shell 规则定义的完整参数将被转置。在文件名中,只会转置字母数字。在其他地方,单词将使用 的默认样式转置
:zle:transpose-words。
例如,与:
autoload -U select-word-style
zle -N select-word-style
bindkey '\ez' select-word-style
select-word-style normal
zstyle :zle:transpose-words word-style shell
Run Code Online (Sandbox Code Playgroud)
transpose-words将与合作壳的话总是而所有其他字小部件会使用正常的定义字,你可以仍然使用Alt+Z去改变它(比其它部件transpose-words)。