5

I have recently upgraded to Vim 8 using Homebrew, but my vi commands still load the OS-provided version 7.4 of Vim. I could add an alias to vi, but is there another way?

  • if you just want to go with vim 8, then you can simply remove vim 7.4 from your system. It will automatically solve your problem. – user10940 Jan 21 '17 at 10:56
9

This is happening because the OS's vi is ahead of Homebrew vi in the PATH.

While you could fix it by putting /usr/local/bin ahead of /usr/bin in the PATH, that would be a security hole since Homebrew gives ownership of that directory to your user. That permission change from the macOS default means that even an extremely unsophisticated malware could use this hole to get root privileges. All they'd have to do is add some other common command here like ls, then pass the commands through to /bin/ls until they see you've run it through sudo, then they take over.

This is a general principle, not specific to Vi, Macs, or Homebrew at all: never place user-writeable PATH elements ahead of those that can only be modified by root.

There are several ways to solve this problem:

  1. Replace the OS's vi and vim binaries with symlinks to the Homebrew versions:

    $ cd /bin
    $ sudo mv vi vi-7.4
    $ sudo ln -s /usr/local/bin/vi .
    $ cd /usr/bin
    $ sudo mv vim vim-7.4
    $ sudo ln -s /usr/local/bin/vim .
    

    I do not recommend this solution, but it is what the original version of the question asked for, so there it is.

    Notice that this doesn't delete the OS-provided versions, just renames them so you still have access to them by appending -7.4 if you need to later.

  2. Since all three of the directories in the prior solution are in the default user PATH on macOS, you don't actually need the symlinks unless you have local software that has hardcoded /bin or /usr/bin paths to vi or vim. Just move the system versions shadowing Homebrew's versions out of the way:

    $ sudo mv /bin/vi /bin/vi-7.4
    $ sudo mv /usr/bin/vim /usr/bin/vim-7.4
    

    That causes vi and vim commands to fall through to the Homebrew versions in /usr/local/bin.

  3. Both solutions above will break the next time you upgrade macOS because the OS installer will put the Apple-provided versions back in /bin and /usr/bin, so the solution I actually recommend is to add aliases to your ~/.bashrc file:

    alias vi=/usr/local/bin/vim
    alias vim=/usr/local/bin/vim
    

    This lets you switch back to the OS-provided version of Vim easily by quoting the alias:

    $ 'vi' somefile.txt         # forces use of /bin/vi
    

    You might also want to add this to ~/.bash_profile:

    export EDITOR=/usr/local/bin/vim
    

    Several commands use $EDITOR instead of hard-coding a call to vi.

  4. Another option you have is to remove the Homebrew build of Vim and install MacVim instead. It also installs to /usr/local/bin, but unlike Homebrew Vim, it installs a command that isn't shadowed by the OS version, mvim. By default, that command launches the GUI MacVim editor, but with this alias, you can have your vi and your Terminal editor, too:

    alias vi='mvim -v'
    

    The -v flag tells it not to launch the GUI, but to edit in the Terminal instead.

    If you choose this option, make a similar change to the EDITOR definition.

    Among the many nice features you get with MacVim is integration with the OS clipboard: pasting from the OS clipboard into Terminal.app running stock or Homebrew Vim you already have, but I find it nice to go the other direction as well: "yank" commands in mvim -v under Terminal.app also sends the yanked text to the OS clipboard so I can paste it into some other program.

6

Homebrew has an option --with-override-system-vi that can be used with brew install vim to do this.

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.