vim 8

17 Feb 2017 (Updated 31 May 2017)

I decided to custom-compile vim 8 so that I could reduce my plugins down to just one: vim-go. Vim no longer needs a plugin manager!

Of course, I went down a rabbit hole (as often happens when upgrading to a major new version of one's favourite text editor) and decided to focus on getting better at buffer management in vim. I decided I wanted to get better at switching between buffers, which resulted in me writing a few functions for my .vimrc.

After experimenting with :Explore, I decided that the shell is still the best way to navigate the filesystem, and that what I really needed was a way to just "throw" files into an already-running vim, from the command line. I needed to get vim's client/server mode working.

Here's what client/server mode vim looks like in action. Launch vim with this argument:

vim --servername VIM

Then, from another terminal, find some files you want to open, and throw them into buffers in vim, like so:

vim --remote a_file_i_want_to_edit.txt another_file.txt

Here's how I downloaded and compiled vim 8 for my system so that it would work with client/server mode.

First, I had to be sure I had all the right dev tools installed. Running this apt-get command will pull in lots of other dependencies; just say yes to them all.

# sudo apt-get install git libncurses5-dev \
    libgtk-3-dev \
    libx11-dev libxpm-dev libxt-dev

Then, run as root:

# cd /usr/local/src
# git clone https://github.com/vim/vim.git
# cd vim
# ./configure --prefix=/usr/local/vim8 \
            --with-features=huge \
            --enable-gui=gtk3 \
            --enable-multibyte
# make
# make install

It turns out that compiling in X11/gtk3 support enables the client/server features to work, even when running plain vim from a terminal.

NOTE that if you do as I did above, you will want /usr/local/vim8/bin in your PATH.

You may not need to do this step, but I had my old vim 7 plugin dir structure, so I cleaned that up. (Run as non-root user):

$ rm -rf ~/.vim/autoload
$ rm -rf ~/.vim/plugged
$ mkdir -p ~/.vim/pack/plugins/start
$ git clone https://github.com/fatih/vim-go.git ~/.vim/pack/plugins/start/vim-go

I ended up with the following tree structor for my vim config:

$ tree -L 4 ~/.vim
/home/mwood/.vim
├── colors
│   └── manni.vim
└── pack
    └── plugins
        └── start
            └── vim-go

My vim colors file looks like this, and is optimized for the light grey backgrounds I like:

set background=light

let colors_name = "manni"

hi TabLine      NONE
hi link TabLine TabLinefill
hi Normal       cterm=none ctermbg=White ctermfg=Black
hi Error        cterm=none ctermbg=Red   ctermfg=Black
hi StatusLine   cterm=none ctermfg=White ctermbg=Black
hi StatusLineNC cterm=none ctermfg=Grey  ctermbg=Black
hi LineNr       cterm=none ctermfg=Black ctermbg=LightGrey

hi diffFile     cterm=bold
hi diffLine     ctermfg=DarkCyan
hi diffAdded    ctermfg=DarkGreen
hi diffRemoved  ctermfg=DarkRed

hi Normal     term=none      cterm=none   ctermfg=0   ctermbg=255
hi Comment    term=bold      cterm=italic ctermfg=244
hi Constant   term=underline cterm=none   ctermfg=124
hi Label      term=underline cterm=none   ctermfg=124
hi Special    term=bold      cterm=none   ctermfg=0
hi Identifier term=underline cterm=none   ctermfg=0
hi Statement  term=bold      cterm=none   ctermfg=22
hi PreProc    term=underline cterm=none   ctermfg=94
hi Type       term=underline cterm=none   ctermfg=89
hi Number     term=bold      cterm=none   ctermfg=124
hi Visual     term=bold      cterm=none   ctermbg=251
hi Search     term=bold      cterm=none   ctermbg=224
hi CursorLine term=none      cterm=none   ctermbg=253
hi Title      term=none      cterm=none   ctermfg=4
hi Function   term=none      cterm=none   ctermfg=18
hi NonText    term=none      cterm=none   ctermfg=250
hi SpecialKey term=none      cterm=none   ctermfg=250

And my latest vimrc, with a spiffy :Buf buffer switching command:

" enable vim features instead of strict vi compatibility
set nocompatible
" do not wrap long lines; have them scroll off the side
set nowrap
" try to detect the filetype
filetype on
" enable syntax highlighting
syntax on
" enable loading the plugin file for specific file types
filetype plugin on
" enable loading the indent file for specific file types
filetype indent on
" tell vim it's OK to use 256 colors at the terminal
set t_Co=256
" show matching brackets and parens
set showmatch
" sync syntax highlighting in a 5000-line window
" syntax sync minlines=5000
" sync syntax highlighting from the start of the file
syntax sync fromstart
" do not make backup~ files
set nobackup
" do not make backup~ files
set nowritebackup
" set character encoding to UTF-8
set encoding=utf-8
" show 3 lines above or below cursor when scrolling
set scrolloff=3
" show insert, replace, or visual mode in last line
set showmode
" show command in last line
set showcmd
" flash screen on bell
set visualbell
" assumes fast connection
set ttyfast
" show line and column number
set ruler
" every window gets a status line
set laststatus=2
" show spaces and tabs; to turn off for copying, use `:set nolist`
set list
set listchars=tab:→\ ,space:·,trail:·,nbsp:·
" switch off search pattern highlighting
set nohlsearch
" make command line one line high
set ch=1
" turn off mouse pointer when typing begins
set mousehide
" put mouse in command-line mode, so mouse clicks don't move cursor
set mouse=c
" set manni color scheme
colorscheme manni
" set leader to comma
let mapleader = ","
" local leader to backslash. (local leader is used for only specific file
" types)
let maplocalleader = "\\"

" Status Line
" ------------
" %< means truncate on the left if too long
" %F is full path to the file we are editing
set statusline=%<%F
" %m shows [+] if the file is modified but not saved
set statusline+=%m
" %r shows [RO] if a file is read-only
set statusline+=%r
" %h shows [Help] if we are in a help buffer
set statusline+=%h
" %w shows [Preview] if we are in a preview window
set statusline+=%w
" separation point between the left and right items
set statusline+=%=
" prints the fileformat; that is, the kind of newline (one of unix, dos or mac)
" (If you type `:set fileformat?`, vim will tell you the current file format)
set statusline+=%{&fileformat}
" a literal forward slash
set statusline+=/
" %Y shows the filetype, such as VIM or HTML or GO
set statusline+=%Y
" %l shows the line number, and %8l uses 8 left-padded spaces to do so
set statusline+=%8l
" a literal comma
set statusline+=,
" %v shows the virtual column number;
" instead of counting a tab as one char, it counts it as the number
" of spaces it uses in the display
" %-8v leaves 8 spaces to the right to do so
set statusline+=%-8v
" disable recording macros: I hit this key accidentally too often
nnoremap q 

" Window Manipulation
" -------------------
" Note to self:
" :resize will resize a horizontal split, *and* you can give it
" relative lines, like :resize +5 or :resize -5
" :vertical resize can be used for vertical splits.

" remap window switching to leader then navigation letter
nnoremap j 
nnoremap k 
nnoremap l 
nnoremap h 
" remap window equal resizing to leader equals
nnoremap = 
" when opening horizontal splits, place cursor in new split
set splitbelow
" when opening vertical splits, place cursor in new split
set splitright

function DestroyButKeepWindow()
  " get the number of the buffer we will close
  let l:current_bufnum = bufnr('%')
  " open a new empty buffer in this window
  enew
  " destroy the original buffer
  execute "bdelete " . l:current_bufnum
endfunction

" Make :Bd call the window closer
command Bd call DestroyButKeepWindow()

" Explore
" -------
" Note to self:
" :Explore brings up explorer
" :Sexplore brings up explorer in a horizontal split
" :Vexplore brings up explorer in a vertical split

" Remove explorer banner
let g:netrw_banner = 0

" Ruby
" ----
augroup filetype_ruby
  autocmd!
  autocmd FileType ruby setlocal shiftwidth=2
  autocmd FileType ruby setlocal softtabstop=2
  autocmd FileType ruby setlocal expandtab
augroup END

" Golang
" ------
augroup filetype_golang
  autocmd!
  autocmd FileType go setlocal shiftwidth=2
  autocmd FileType go setlocal tabstop=2
  autocmd FileType go setlocal softtabstop=0
  autocmd FileType go setlocal noexpandtab
  "autocmd FileType go nmap d (go-def-vertical)
  "autocmd FileType go nmap D (go-doc-vertical)
  "autocmd FileType go nmap b (go-doc-browser)
  "autocmd FileType go nmap i (go-implements)
  "autocmd FileType go nmap n (go-info)
  "autocmd FileType go nmap r (go-rename)
augroup END
let g:go_highlight_functions = 1
let g:go_highlight_methods = 1
let g:go_highlight_structs = 1
let g:go_highlight_operators = 1
let g:go_highlight_build_constraints = 1
let g:go_fmt_command = "goimports"