Reconfiguring Vim

As I’ve talked about plenty of times before, I tend to use a lot of different text editors when writing code. Lately, I’ve been using VS Code for most of my development needs, mixed with IntelliJ IDEA when I need to write Groovy code since I haven’t found literally any way to get half-decent Groovy support with another editor. However, I often still need to use an editor from the CLI. For one, I frequently need to just pop into a file for a project to either check something or make a super quick edit. I also like having a CLI editor set as my $EDITOR value for things like git commit messages. I exclusively use git from the CLI — I’ve never found the integration with GUI editors or standalone GUI git clients to be particularly good when I have a solid familiarity with the CLI — and keeping in the same context is useful to me.

Considering that I’ve posted before about things like Neovim and Helix, it may be easy to think I would just use those… and I did for a very long time when I was already doing basically everything in Neovim. Since I’ve started using some other editors, though, I found my Neovim setup would occasionally complicate things. The biggest problem is that it uses different LSPs for various things than other editors do. So when I opened a file in Neovim from one of my Java projects that I had been working on in VS Code, for example, CoC‘s implementation of JDTLS added a bunch of stuff to my project that I didn’t need. It wasn’t a huge issue, but it was enough to be annoying.

For these reasons, I decided to go back to vanilla Vim as my CLI editor. I didn’t need an LSP or anything fancy with it; I just wanted something light and fast for quick edits, checks to see how on Earth I accomplished something in another project so I could emulate it elsewhere, etc. However, I did want some quality of life improvements. I wanted to ensure I had decent syntax highlighting, a theme that didn’t look horrible, support for opening and managing multiple files, etc. As a result, I still wanted to have some plugins.

Back in the day before I started using Neovim, I used Pathogen for managing plugins. This worked fine but was a bit of a manual process. I had to manually clone new packages into the appropriate directory, for example. If I wanted to update those packages, I’d have to go to where the local copy of the repo lived and git pull origin main each of them. With Neovim I started using vim-plug, and I knew it worked with regular Vim as well. Ultimately, I ended up with the following content for my .vimrc file.

call plug#begin()
Plug 'catppuccin/vim', { 'as': 'catppuccin' }
Plug 'https://github.com/vim-airline/vim-airline'
Plug 'https://github.com/tpope/vim-fugitive'
Plug 'https://github.com/wakatime/vim-wakatime'
Plug 'https://github.com/preservim/nerdtree'
Plug 'https://github.com/sheerun/vim-polyglot'
Plug 'https://github.com/rodjek/vim-puppet'
Plug 'https://github.com/ryanoasis/vim-devicons'
call plug#end()

set hlsearch ignorecase smartcase incsearch number relativenumber
set tabstop=4 shiftwidth=4 expandtab notitle ruler laststatus=2
set autoindent smartindent re=0 scrolloff=8 nocompatible colorcolumn=80
if has('termguicolors')
    set termguicolors
endif

syntax on
colorscheme catppuccin_macchiato
filetype plugin indent on

map gn :bnext<cr>
map gp :bpreviou<cr>
map gd :bdelete<cr>
let g:airline#extensions#tabline#enabled = 1 " Enable the list of buffers
let g:airline#extensions#tabline#formatter = 'unique_tail_improved'
let g:airline#extensions#tabline#left_sep = ' '
let g:airline#extensions#tabline#left_alt_sep = '|'
let g:airline_theme = 'catppuccin_macchiato'

let NERDTreeQuitOnOpen=1
let g:NERDTreeDirArrowExpandable="+"
let g:NERDTreeDirArrowCollapsible="~"
nnoremap <C-t> :NERDTreeToggle<CR>

It’s also available as a Gist. (If you’re curious for the sake of comparison, this is my Neovim config.) Noteworthy configurations are vim-airline for showing me useful information about whatever project I have open along with giving me a nicer means by which to see and manage my buffers. I added some custom key maps so that in Vim’s normal mode I can use gn to go to the next buffer, gp to go to the previous buffer, and gd to destroy the current buffer. I just find this a lot quicker and easier than using the commands to swap buffers. I also included NERDTree as a file explorer. Unlike a lot of people, I don’t want to keep it open on the side of my editor all the time. While I like that in graphical editors, I don’t want it cluttering up my terminal, especially since I find with terminal-based editors I don’t use it nearly as often versus just typing :e path/to/file for a new buffer. The configuration I have will keep it closed when I open a new Vim instance. Ctrl + t will allow me pop it open quickly, and then when anything from it is opened it’ll automatically close again.

One thing you may see in the Gist that I didn’t include here are the following remaps:

inoremap kj <esc>
vnoremap kj <esc>
cnoremap kj <C-C>

I don’t normally use these, but they’re in the Gist so that I don’t forget them. These make it so that hitting kj in any mode acts as Escape. I use these in Vim running on a VPS I have that runs a few small websites that I occasionally need to make minor updates to directly. I sometimes do that from my iPad, and the keyboard I normally use with my iPad doesn’t have an Escape key. This allows me to still effectively use Vim since I literally never type the letter k followed by the letter j for any reason. I also chose to use this instead of something like jj or kk because I’m the type of person who tends to absentmindedly tap Escape a few times to “ensure” I’m in normal mode before doing something. kj ends up being movement neutral if I’m already in normal mode when I do it.

I’ve been using this setup for about a week now, and it’s been working well for me. VS Code is what I normally operate in for most of my code, but whenever I need to quickly check something in another project, Vim does a good job of allowing me to quickly open and find what I need with nice syntax highlighting but without the potential for sowing havoc within the project itself due to conflicting plugins or language servers. I think I’m too spoiled these days to go back to writing code without a language server the majority of the time, but for this particular use case it works great.