8

I have a bunch of really useful terminal programs which I use often while I am editing or writing. For example, dictionary is a popular one and I have aliased its usage to single character d in .zshrc file to save time.

While I am editing documentation pages in VIM, is there a way I can use .zshrc aliases in vim command mode and everything still works? Something like:

# alias defined in .zshrc
alias d="dictionary-program"

# VIM command mode
:!d <some_word>

How can I tell vim to lookup alias in .zshrc file before executing terminal commands from command mode?

0

3 Answers 3

2

One possible workaround is to move these things out of .zshrc. .zshrc is only sourced for interactive terminals, but .zshenv is sourced for any invocation of zsh (except with -f). Creating aliases in .zshenv will allow them to work when zsh is called by vim.

I wouldn't necessarily recommend this approach, because again - now any and every invocation of zsh has these aliases set. But, depending on how many tools you use that invoke zsh, how likely you think an unexpected collision is to happen with your aliases, how concerned you are about startup times for noninteractive shells, etc., it could be an acceptable workaround (and it does work).

This is briefly documented in the documentation under Startup Files.

2
  • Excellent (Y) it works. Should I include sourcing .zshenv in .zshrc file? or it's automatically picked up at shell invocation time? May 9, 2018 at 17:48
  • 1
    @AviMehenwal It's always sourced, and it's the first (user) dotfile to be sourced, so there's no need to source it again in .zshrc. I'll add a link to relevant documentation into my answer, which is worth taking a look at.
    – brhfl
    May 9, 2018 at 17:53
5

The question originally asked about a solution for bash. I answered before I discovered that it was subsequently changed to be all about zsh. Fortunately, that original answer is very similar to the answer for zsh. And because several people found value in that answer (based on their upvotes) I've decided to address both shells rather than totally overwrite the bash information.

The 'shell' setting can be used to tell Vim how to start the shell used in terminal commands. The default value is the value of environment variable $SHELL or, if that's not found, just sh.

If you just set it to, say, /bin/zsh your startup file won't be picked up. You can tell the shell which startup file to use with the --rcs flag (bash: --rcfile). Alternatively, if you specify -i (for "interactive" shell) then the shell will read $ZDOTDIR/.zshrc or $HOME/.zshrc if ZDOTDIR is not set (for bash it's always $HOME/.bashrc). As it happens, you also need -i if you want to pick up aliases so that makes the choice clear.

Putting it all together, you can add something like this to your vimrc file:

" zsh
let &shell='/bin/zsh -i'

" bash
let &shell='/bin/bash -i'

However, something strange happens with zsh (bash works fine). Vim gets put in the background and you are dropped at your zsh prompt with this message:

zsh: suspended (tty output) vim

The workaround I came up with is to defer the setting of 'shell' by adding this to vimrc instead of the line above:

autocmd vimenter * let &shell='/bin/zsh -i'

Hopefully no other strange things happen but so far the testing I've done has gone well.

5
  • 1
    There's two more solutions for Bash users experiencing this problem on this question that is no longer a duplicate.
    – Rich
    May 9, 2018 at 13:05
  • 1
    @BLayer Thx for the answer, BUT adding let &shell="/bin/zsh -i" at the end of .vimrc exits vim and starts new zsh session! I am trying other options as suggested by @Rich and other, but so far I am not able to do so May 9, 2018 at 14:34
  • :!foo form. Thanks for taking time to address my issue, for time being I am using @brhfl approach and also check the cool stuff I found from vim documentation to run shell programs without losing VIM context in teh answer. Great day May 9, 2018 at 20:42
  • 1
    Actually, I put this in my vimrc autocmd vimenter * let &shell='/bin/zsh -i' and it works. Try it out.
    – B Layer
    May 10, 2018 at 1:04
  • Thx @BLayer yes it works. May 10, 2018 at 6:23
1

Not exactly what is asked in question but I found an amazing workaround from VIM documentation. No extra setup or whatsoever required.

1. Suspend and resume

Like most Unix programs Vim can be suspended by pressing CTRL-Z. This stops Vim and takes you back to the shell it was started in. You can then do any other commands until you are bored with them. Then bring back Vim with the "fg" command.

CTRL-Z
{any sequence of shell commands}
fg

You are right back where you left Vim, nothing has changed. In case pressing CTRL-Z doesn't work, you can also use ":suspend". Don't forget to bring Vim back to the foreground, you would lose any changes that you made!

Only Unix has support for this. On other systems Vim will start a shell for you. This also has the functionality of being able to execute shell commands. But it's a new shell, not the one that you started Vim from. When you are running the GUI you can't go back to the shell where Vim was started. CTRL-Z will minimize the Vim window instead.

2. Starting new shell

You can start a new shell this way:

:shell

This is similar to using CTRL-Z to suspend Vim. The difference is that a newnshell is started. Exit back to vim hitting CTRL+D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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