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?
-
1I 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 DulacCommented Jan 16, 2014 at 9:58
-
Related stackoverflow.com/questions/16073807/…– user13107Commented Jan 16, 2014 at 12:18
-
1It 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.– nuoritoveriCommented Jan 16, 2014 at 12:51
-
1With 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.– mkingstonCommented Jan 16, 2014 at 17:25
-
3How does this happen?– jfaCommented Jan 16, 2014 at 20:27
4 Answers
With the assumption that you call vi
with the directory as the last argument:
vi() {
if [[ -d ${!#} ]]; then
cd "$@"
else
command vi "$@"
fi
}
-
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 "${!#}" ...] Commented Jan 16, 2014 at 9:08
-
5@OlivierDulac Agreed -- similarly dangerous is aliasing
rm
torm -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. Commented Jan 16, 2014 at 9:11 -
3@OlivierDulac aliasing
rm
torm -i
might have saved you some trouble in the past but might (and probably will) get you in much more trouble in the future ...– jlliagreCommented Jan 16, 2014 at 11:25 -
1
-
2@crisron:
${!#}
indirectly references the final argument, andcommand
is only necessary to avoid function recursion in this instance. Commented Jan 28, 2014 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.
-
1note:
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). Commented Jan 16, 2014 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 Commented Jan 16, 2014 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 "$@" ?] Commented Jan 16, 2014 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
}
Use alias feature in Unix. Once you alias cd to vi, the problem will be resolved.
-
5...this would mean that one cannot use
vi
without manually overriding the alias, which seems highly undesirable. Commented Jan 16, 2014 at 9:58 -
3This 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.– gerritCommented Jan 16, 2014 at 9:59
-
1@ChrisDown Or this would teach you to use the proper
vim
instead.– KevinCommented Jan 16, 2014 at 19:00 -
@Kevin vim is not more "proper" than vi -- on many systems, vi is all that is available. Commented Jan 21, 2014 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, usevi
and expect the more limited feature set.– KevinCommented Jan 21, 2014 at 3:41