从 zsh 在 vi​​m 中打开 `filename`,也许是 preexec 钩子?

从 zsh 在 vi​​m 中打开 `filename`,也许是 preexec 钩子?

短篇故事:

以下作品...

function default_open_in_vim () {
    filename=$(echo -e "$1" | tr -d '[:space:]')
    if [[ -f $filename ]]; then
        vim $filename
    fi
}

autoload -Uz  add-zsh-hook
add-zsh-hook preexec default_open_in_vim

...但是当我关闭 vim 时我得到以下信息:

zsh: permission denied: src/findPathBFS.js

长版:

我发现自己一遍又一遍地做同样的事情:

我输入 CTRL-t 来 fzf 在当前目录下查找文件。然后我按 Enter 键,fzf 会在光标位置插入该文件名。这很棒。有时我会 grep 这个文件,或者 catting 或 git-checkouting 或其他什么。可能有时我在 vim 中打开,但不是通过 vim CTRL-t 启动。我现在必须做的是按 CTRL-a 转到终端中的行首,然后输入 vim <​cr>。

问题是很多时候我什至没有注意到我在 CTRL-t 之前没有输入这个 vim...你可以看到问题。

如果我键入一个目录名而不在其前面加上 cd,我的 zsh 与 AUTO_CD 将会 cd 进入一个目录,我希望它执行类似的操作:如果我键入一个文件名而不在其前面加上任何内容,只需在 vim 中打开它。

Preexec 挂钩可以工作,但不喜欢错误消息。

如果我可以取消该命令,那就太好了,但 zsh 似乎不允许我从 preexec 挂钩取消命令(也许可以,但我不知道它或如何做到这一点?)

我尝试过使用command_not_found_handlerman zshmisc 中记录的内容,但当“命令”是有效的文件名时没有帮助。

答案1

这确实有效:

command_not_found_handler () {
    if [[ $# -eq 1 && -f $1 ]]; then
      vim "$1"
    else
      exit 127
    fi
}

但我发现它相当危险,你可能会错误地执行某些操作。例如,如果您尝试编辑当前目录中与路径中的命令同名的文件,则将执行路径中的命令。这不是你的问题command_not_found_handler,而是你的要求有问题。另一个问题是,如果您输入类似 的内容foo/bar,则意味着如果文件不可执行则编辑该文件,如果可执行则执行它。

如果您希望当前目录中的文件优先于 PATH 中的命令,您可以使用DEBUG陷阱或者重载accept-line编辑命令。但这并不能解决第二个问题。

我推荐不同的用户界面。不要扰乱命令执行。不要按 Return 进行编辑,而是按不同的键,并将该键配置为插入vim到该行前面。这有一些不错的好处,包括vim在 shell 历史记录中保留对 的调用。

zle -N edit-file
edit-file () {
  BUFFER="vim $BUFFER"
  zle accept-line "$@"
}

相关内容