Find out your internal IP address by using Terminal. This method is easier and faster for Mac users who are familiar with a command line program called Terminal. Even if you have not used Terminal before, just follow the instructions and you will find the internal IP address. First, use spotlight by pressing Command and Spacebar and type Terminal. Vi is a terminal application, so you’ll have to start it from a terminal window. Use the vi /path/to/file command to open an existing file with Vi. The vi /path/to/file command also works if the file doesn’t exist yet; Vi will create a new file and write it to the specified location when you save. Visual mode happens when you use a v, V, and Ctrl-v commands from Normal mode. In Visual mode, you can select text. As you use a navigation command, the area from the beginning of Visual mode to when you exit Visual mode is the selected text. Anytime you use the: command in Normal mode, you will enter into Command mode.
By following the hot keys setup in this article, we can make terminal Vim/Neovim feel just like any native app, or working in an editor like VS Code. You’ll be able to use Vim in iTerm2, Kitty, or Alacritty—or your terminal of choice—while still keeping your standard hot keys for copy, paste, switching tabs (this guide will focus on binding command key, but you can substitute with control key.) By running your Vim in a terminal, you get features like collaborative editing for free (through Teleconsole).
Pair it with my recommended Vim config for a fully loaded yet blazing fast IDE experience:
Running Vim in the terminal opens you up to the terminal ecosystem, including tools like TMUX or Teleconsole, which lets you share your terminal session with a remote user for real-time live collaboration. It’s also one less app to open.
You can either bring Vim to VS Code or bring VS Code to Vim. I’ve found Vim emulation in VS Code to be too slow and unresponsive. But most importantly, I lose out on the Vim plugin ecosystem. Getting most of the VS Code features in Vim is actually quite easy. It’s a well covered topic. You can install a fully configured Vim setup like Spacevim (or even Spacemacs), or install the individual plugins yourself using a plugin manager like vim-plug (easier) or dein.vim (harder) and configure your vimrc file to suit your exact needs. If you want something lighter and easier to customize, you can try using my vim config that’s already configured with the features mentioned above. Clone it and make it your own (that’s what did from the last guy).
The rest of the guide will mainly be about making Vim/Neovim feel like a native dedicated app by running it in a blazing fast terminal emulator called Kitty with configured hot keys.
CMD+C
or V
, CMD+W
, CMD+{
or }
tab switching, etc.Kitty can be launched with the special key profile we’ll be using so it doesn’t interfere with your regular terminal activities. If you plan to just use iTerm2, you can skip this section and just grab the GeoVim key profile config for your terminal. I’m calling my Neovim inside Kitty setup “GeoVim.” Kitty is a super-fast terminal emulator that uses your GPU to render at 100 FPS (configurable based on your needs). Kitty is fast. The speed I’m talking about is not how fast it prints text on the screen, but how responsive the feedback is on screen. On a standard 60hz inch Macbook screen typing is noticeably more responsive than iTerm2. The effect is even more noticeable if you try to scroll up and down really fast. Humans do not need to consciously perceive fast refresh rates in order to benefit from them. You can maximize the responsiveness by using it with a 144hz monitor. The developer has claimed that his goals are still to keep the terminal energy and resource efficient though, something I will be thoroughly benchmarking in the future.
Install Kitty with Homebrew, which includes macOS GUI integration out of the box.
Linux Users: Linux support is untested, but should work.
Make sure to install ruby and tmux (if you want tmux enabled).
Either clone my Neovim repo into ~/.config/nvim
, or just grab the folder below and place it somewhere. I recommend placing it in ~/.config/geovim
if you don’t plan on using my Vim config.
GeoVim files: https://github.com/chrischen/vim-config/tree/master/geovim
Add this to your .zshrc
or .bashrc
, and modify GEOVIM_PATH
accordingly.
The gvim
command now lets you open somefile.txt
and have Kitty -> TMUX -> Vim open up automatically with the file you specified.
You can also switch out Kitty for Alacritty. Open launch_geovim.sh
to change the options:
I highly recommend Neovim instead of regular Vim 8, as I’ve found some UI blocking behavior happens when typing with live code completion and syntax checking. It’s mostly a drop-in replacement so if you want to use Vim you still can. It may just be better plugins, but in Neovim I’ve never encountered any freezing while typing. Neovim does have a bug when scrolling, but only if you scroll really really fast.
Getting Vim to receive and use special keys like Command and Control key will require getting the terminal to send custom key sequences and Vim to receive and map those sequences.
The GeoVim launcher script will use the bundled Kitty config file. These are preconfigured for standard macOS shortcuts, so you’ll need to edit the file if you want to change the key bindings. The config file is located at geovim/conf/kitty.conf
. These keybindings will only be used in your GeoVim instance, so if you plan on using Kitty as your terminal, they won’t interfere with standard hot keys for your terminal shell.
Linux users: replace with your preferred hotkey instead of Command. Cmd should map to the Windows key though. If you plan to use the Kitty as your primary terminal, it also has a handy Ctrl+C smart mode that operates as both interrupt and copy. You’ll want to put those key bindings in ~/.config/kitty/kitty.conf
instead.
Alacritty is also a GPU-powered terminal emulator. It’s barebones, and does not have features like tabs, windows, or any UI apart from the terminal window itself. TMUX is required to make it practical. It’s an alternative to Kitty, but I’ve found Kitty to feel more responsive and be better adapted to our setup (for example, shift+select with mouse doesn’t work in Alacritty).
The GeoVim launcher will also take care of loading hot key configs for Alacritty. But if you use Linux you may want to remap the Command key to Ctrl or something else. Just open geovim/conf/alacritty.yml
and edit the key_bindings:
section.
If you want to bind other custom keys, try using xxd -psd
in your terminal to get the hex codes. You can also use Key Codes.app, type Ctrl+V
in your terminal followed by the key combo, or run cat
and then type your key combo. Certain key combos won’t work this way, such as Ctrl+C
, but if I type Ctrl+V
followed by Ctrl+Shift+(up arrow key)
I’d get ^[[1;6A
which is the escape sequence to use. ^[
is the ESC (hex 0x1b) key (which is the same as pressing Ctrl+[
), followed by a string of [1;6A
. This is sent by the terminal as sequential key presses.
iTerm2 has a nifty automatic profile switching feature that allows it to activate our custom key bindings only if Vim or Neovim is open, so it won’t interfere with your normal shell usage. If you aren’t using TMUX with this setup, you may want to edit the profile in iTerm2 to not trigger when TMUX is run. You can edit this in Advanced -> Automatic Profile Switching
after loading the profile. Because the profile can be automatically activated, you won’t need to use the GeoVim launcher for Vim in iTerm2.
Note: my default config overrides new tab/switch tab hot keys to work in the Vim window. If you don’t want that, make sure to delete or re-map the Cmd+T
and Cmd+Shift+[
or ]
hot keys.
Grab the iTerm2 profile from geovim/conf/iTerm2.json
. In the menu bar click on iTerm2 -> Preferences
and then click on the Profiles
tab.
The next step is to take these key combos sent from your terminal and trigger the right actions in Vim. The Command ⌘<D-..>
(“super” key) Vim key binding only works in MacVim. We still won’t be able to use it, but we’re getting around that by taking advantage of escape sequences.
In recent versions of terminal Vim you may notice that CMD+V may actually work—at least slightly. This is because your terminal is sending a bracketed paste. Vim still knows nothing of the command key, but is just handling a special string sent from the terminal app. Terminals actually send a string with an escape sequence surrounding your clipboard contents (sort of like HTML tags) which is parsed by Vim, or your shell, to trigger a paste action. This allows apps running in your terminal, such as Zsh, to know that this content is pasted, and treat it in special ways such as not executing it automatically.
However as of the time of this writing, there are still quirks to this behavior in Neovim which means we’ll have to re-implement this functionality to get it working perfectly. Plus, CMD+C copying still won’t work if you have mouse support enabled in Vim because text selection triggers a visual selection in Vim, preventing your terminal from highlighting it (you can still yank with y
though).
Add the following to your ~/.vimrc
or ~/.config/nvim/init.vim
(neovim) config file.
Now when you press CMD+V Vim will will paste correctly whether in insert, visual, select, or command mode. CMD+C will trigger a yank, and CMD+A will select all. The goal is to mimic the behavior in GUI Vim like MacVim. You may also want add this to your .vimrc
to sync your clipboard with your OS clipboard. The +
clipboard register is shared between macOS and Vim. Disable it if you do not want copy or paste to replace the contents of the OS clipboard.
There are keybindings that work in GUI apps but not in terminal Vim, such as Ctrl+Enter. Most terminals won’t be able to distinguish between Enter and Ctrl+Enter. I’ve pre-added bindings for these modifiers if you want to use them.
Pro Tip: To figure out if your terminal is actually sending certain key combos to Vim, go in insert mode and press Ctrl+V, followed by your key combo. If it doesn’t seem to distinguish the added modifiers, you’ll need to define custom key sequences and receive them in Vim like above.
Install https://github.com/tpope/vim-obsession using your preferred vim plugin manager. I recommend Vim-Plug (easier to use) or Dein (harder to use). No further configuration is necessary as the GeoVim launcher will take care of starting sessions.
TMUX is used to primarily allows us to open multiple Vim sessions rooted in different project directories without having to launch multiple instances of the terminal. It’s also remotely scriptable, which allows the launcher to do smart file opens (for example it will open a file in an existing project into a new Vim tab if the project is open). TMUX is optional, and can be disabled in launch_geovim.sh
. If disabled, Vim sessions will still function (restoring your Vim tabs), but new files will have to be launched in separate terminal windows unless you open them from within Vim.
Install TMUX plugin manager if you haven’t already. If you are using Prezto, you’ll need to initialize plugins in .tmux.conf
exactly as shown below, instead of what it tells you in the default instructions.
Add this to the end of your tmux.conf
or tmux.conf.user
file.
The TMUX plugins will periodically save the state of your TMUX windows, while vim-obsession will save your Vim tabs on changes (new tab, close tab, etc). The GeoVim launcher will automagically resume all the open files and terminals from your last session—even when you restart your computer or recover from a crash. You can manually save/restore your TMUX windows with the following key combos:
Wps mathtype. Save: Ctrl-A followed by Ctrl-S
Restore: Ctrl-A followed by Ctrl-R
If you disable TMUX, you can still get Vim session save/restore by manually triggering it. You only have to do this once in any given project directory as it will detect and read the created Session.vim on subsequent opens. Vim session tracking also needs to be turned on manually if you open a specific file to edit as ingvim someFile.ts
as opposed to just launchinggvim
with no arguments. This is to prevent it from littering random directories with Vim session files.
I haven’t fully evaluated the energy impact of this setup yet. In a future post I will be reporting back on detailed energy consumption stats.
Because Vim is now running inside the terminal, we can take advantage of utilities made for the terminal such as Teleconsole, which allows a remote user share control of your terminal and collaborate live. Now we have a VS Code style IDE with real time collaborative editing for free! Important: turn off TMUX or just run Vim by itself for this.