2

SHORT STORY:

the following works...

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

...but I get the following when I close vim:

zsh: permission denied: src/findPathBFS.js

LONG VERSION:

I find myself doing the same thing over and over again:

I type CTRL-t for fzf find file under current directory. Then I press enter and fzf inserts this filename on the cursor position. This is great. sometimes I'm grepping on this file, or catting or git-checkouting or whatever. may times though I'm opening in vim and didn't start by vim CTRL-t. What I must do now is CTRL-a to go to start of line in my terminal and then type vim <​cr>.

The problem is many times I don't even notice that I didn't already type this vim before CTRL-t... you can see the problem.

My zsh with AUTO_CD will cd into a directory if I type a directory name without prepending it with cd, I want it to do something similar: If I type a filename without prepending it with anything just open it in vim.

Preexec hook works but don't like the error message.

It would be nice if I could cancel the command but it doesn't seem that zsh allows me to cancel command from preexec hook (maybe it does and I don't know about it or how to do it?)

I have tried using command_not_found_handler documented in man zshmisc but doesn't help when "the command" is a valid filename.

1

This does work:

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

I find it rather dangerous though, you're likely to execute something by mistake. For example, if you try to edit a file in the current directory that has the same name as a command in the path, the command in the path is executed. This is not a problem with command_not_found_handler, it's a problem with your requirement. Another problem is if you type something like foo/bar, it means editing the file if the file is not executable, and executing it if it is executable.

If you want files in the current directory to take precedence over commands in the PATH, you could use the DEBUG trap or overload the accept-line editing command. That wouldn't solve the second problem though.

I recommend a different user interface. Don't mess with command execution. Instead of pressing Return to edit, press a different key, and configure that key to insert vim in front of the line. This has some nice bonuses, including retaining the call to vim in the shell history.

zle -N edit-file
edit-file () {
  BUFFER="vim $BUFFER"
  zle accept-line "$@"
}
  • As I mentioned in my question the command_not_found_handler doesn't get called when I type and existing filename+<cr> - I've retried following your answer. Don't know if it's related, zsh --version outputs zsh 5.3.1 (x86_64-apple-darwin16.3.0). Binding a key would be a possible solution if it weren't for the fact that I normally don't even notice that $BUFFER matches ^\s*some_filename\s*$ and that's exactly what annoys me. – sudavid4 Mar 5 '18 at 21:49
  • About "you're likely to execute something by mistake" - The point is not to always omit the vim command, it's just a fallback cuz I often forget it - so you see I would execute something by mistake anyway. I see your point on the pitfalls with my current approach though. I could(maybe should) run which $1 before I decide to open in vim to give real commands precedence over "open in vim fallback". – sudavid4 Mar 5 '18 at 21:51
  • Strange. Works for me with zsh 5.1.1 on Ubuntu 16.04. I don't understand why you don't want to press a different key: you don't need to look at what the command line contains, you select which key to press based on whether you want to run or edit. – Gilles Mar 5 '18 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.