Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Title says it all. About 5 times a day, I type "vi" when I meant "cd", and end up opening a directory in vi. It's making me NUTS. It seems like there should be a way to detect when I type in "vi + directory" and automatically change it to "cd + directory". Thoughts?

share|improve this question
1  
I gave an alternative that you may find interresting as well ^^ (one that let you correct the source of the problem, while avoiding getting irritated until then ^^) –  Olivier Dulac Jan 16 at 9:58
    
Related stackoverflow.com/questions/16073807/… –  user13107 Jan 16 at 12:18
1  
It also frustrated me a lot, till I discovered that you can use Enter and arrows to navigate to the file inside the folder. When you click Enter while being on it it opens. –  nuoritoveri Jan 16 at 12:51
1  
With only a small amount of facetiousness: change to zsh. Set it up so that when you type a directory name it changes into that directory. Use suffix aliases so that when you type *.sh, *.c, *.config whatever it opens the relevant file in vi. The caveat here is of course that you may find yourself omitting "vi" or "cd" in an unfamiliar shell. –  mkingston Jan 16 at 17:25
3  
How does this happen? –  JFA Jan 16 at 20:27

4 Answers 4

up vote 38 down vote accepted

With the assumption that you call vi with the directory as the last argument:

vi() {
    if [[ -d ${!#} ]]; then
        cd "$@"
    else 
        command vi "$@"
    fi
}
share|improve this answer
2  
@Alex I guess this is both perfect for the rare cases you typed "vi" incorrectly instead of "cd", while at the same time teach you to always type "vi" now ;) [ie, I hope you don't often have to use another server/machine where that function will not be there to save you stress...] [+1 for that answer, though, it's what I wanted to answer as well, except I'd just test for "${1}" [and then cd "${1}"] instead of "${!#}" ...] –  Olivier Dulac Jan 16 at 9:08
5  
@OlivierDulac Agreed -- similarly dangerous is aliasing rm to rm -i, which is the default in many distributions. I generally think that the best way to solve problems is to solve the user rather than to work around them. –  Chris Down Jan 16 at 9:11
3  
@OlivierDulac aliasing rm to rm -i might have saved you some trouble in the past but might (and probably will) get you in much more trouble in the future ... –  jlliagre Jan 16 at 11:25
1  
@Alex Well, you did say vi in the question... –  Chris Down Jan 20 at 6:38
2  
@crisron: ${!#} indirectly references the final argument, and command is only necessary to avoid function recursion in this instance. –  Chris Down Jan 28 at 2:28

Apart from @ChrisDown answer, here is another approach: bypass directories

With this approach, you can :

vi ./*

and it will start vi on all the files in the current directory even if it contains subdirs, bypassing those subdirs

vi() {
  for arg do
    [ -d "$arg" ] || set -- "$@" "$arg"
    shift
  done
  [ "$#" -gt 0 ] && command vi "$@"
}

This one just do vi, on any argument that are not directories... Hence it won't teach you to use "vi" for "cd" ;)

And it will not call vi if you just did: vi somedirectory (ie, mistyped vi instead of cd). But it will not cd there automatically then, so you still remember you have to type cd ^^

I used a "compatible" way to change the arguments lists, so that it's portable to many platforms.

share|improve this answer
1  
note: command something : starts the "something" command (ie, the first occurence of "something" found using $PATH) instead of any alias OR function named "something". \something would only bypasses the alias, but would still the function if it existed (and here, that would mean the function "vi" would call itself, and loop). –  Olivier Dulac Jan 16 at 9:55
    
@ChrisDown: we are talking an aid to a user, which I hope won't try to hack himself ^^ . And that eval is to set a new set of arguments (set -- ... ), so it's less dangerous in itself –  Olivier Dulac Jan 16 at 10:01
    
@StephaneChazelas: thanks for the edit! I tried to write it that way, but I was worried about looping infinitely [I trust you it won't loop, though!. The 'for arg' is being evaluated before the inner treatment starts, and therefore its "$@" list is 'saved' and iterated over, and not changed even though the inner treatment changes "$@" ?] –  Olivier Dulac Jan 16 at 10:15

One solution is to stop using cd altogether. Put shopt -s autocd in your .bashrc or setopt autocd in your .zshrc. Then to change to a different directory, type the directory name, without any command.

Don't forget to type vi if you want to edit a file.

If you really want a single command to either change to a directory or edit a file, you can make it a function:

vi () {
  if [ $# -eq 1 ] && [ -d "$1" ]; then
    cd -- "$1"
  else
    command vi "$@"
  fi
}
share|improve this answer

Use alias feature in Unix. Once you alias cd to vi, the problem will be resolved.

share|improve this answer
5  
...this would mean that one cannot use vi without manually overriding the alias, which seems highly undesirable. –  Chris Down Jan 16 at 9:58
3  
This answer comes across as slightly trollish. It does answer the original question, as the OP did not specify they ever needed vi on a file. The answer, although somewhat fun, is certainly not useful. –  gerrit Jan 16 at 9:59
1  
@ChrisDown Or this would teach you to use the proper vim instead. –  Kevin Jan 16 at 19:00
    
@Kevin vim is not more "proper" than vi -- on many systems, vi is all that is available. –  Chris Down Jan 21 at 3:28
1  
@ChrisDown I'd argue it's better to know what to expect. If you expect to use vim features, use vim. If it's not available, use vi and expect the more limited feature set. –  Kevin Jan 21 at 3:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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