5

The problem:

Sometimes, when I try to do things in zsh, it won't complete the filenames I want because they don't apply to the current context. Two examples:

  1. I want to force-add a file which is currently ignored in hg or git. oh-my-zsh tries to help me by only completing non-ignored files, but in this case it is a hindrance. I'm forced to type the full path to the file manually.
  2. I want to use git diff to diff two arbitrary files on my hard drive. These files do not reside in any repository, but who cares?! git diff --no-index is a really nice way to diff any two files. But because they aren't in a repo, zsh won't complete them.

The proposed solution:

I could simply edit the source control context to complete all filenames, regardless of their source control status. But there are a couple limitations:

  1. I don't know how to do that.
  2. It might be nice to have an "escape hatch" whereby I could force file completion, no matter what the context.

So, I decided instead to bind a key shortcut to force normal, context-free file completion.

What I have so far:

Zsh apparently has an easy way of doing this, as detailed in this question. So I've added the following lines to my .zshrc:

zle -C complete complete-word complete-files
bindkey '^[[Z' complete
complete-files () { compadd - $PREFIX* }

This causes shift-tab to initiate file completion. It works beautifully in standard zsh! But boo-hoo, for some reason it doesn't work when I source oh-my-zsh. :-(

So is there a way to get this to work with oh-my-zsh, or is there an alternative solution I might find satisfying?

Community
  • 1
  • 1
Neil Traft
  • 18,367
  • 15
  • 63
  • 70
  • 1
    At some point oh-my-zsh may remove previous bindings. You can check if the binding is still present in the running shell with `bindkey | grep '^[[Z'`. You also can check if the zle setting is correct with `zle -lL complete` and the function definition with `whence -c complete-files`. – Adaephon Aug 21 '14 at 08:49
  • You're completely right! As long as I call `bindkey` _after_ sourcing `oh-my-zsh.sh`, it's all good. (oh-my-zsh binds it to `reverse-menu-complete`) If you want to add an answer I'll mark it correct. – Neil Traft Aug 22 '14 at 20:11

1 Answers1

1

My way of doing exactly that (replacing the default diff command with the one from git) was pretty straightforward.

Add this to your ~/.zshrc:

diff() {
    git diff --no-index "$@"
}

Before I was using an alias, but since zsh can "solve" them, it was then using the autocompletion functions from git diff, which inadvertently led to the same problem as you.

Using a function solves this issue as zsh reverts to the classic "files only" completion.

Antoine
  • 3,880
  • 2
  • 26
  • 44