I wanted to share a quick little setup to get up and running quickly with vim as an IDE. I don't really like vim and IDE in the same sentence, but I do have to admit that having an IDE that runs in the terminal and loads fast is pretty sweet.
header image
~/.vimrc
~/.vim
├── _lsp.vim
├── _options.vim
├── _plugins.vim
├── _theme.vim
Requirements
create ~/.vim directory
First we need a place to store a few files. I am going to put them in ${HOME}/.vim/
so I will make that directory.
_theme.vim (optional)
Lets create a file to store theme settings. I am going to put it in ${HOME}/.vim/_theme.vim
.
syntax enable
" set t_Co=16 " uncomment to force ANSI 16 colors
if has('gui_running')
set background=light
else
set background=dark
endif
colorscheme gruvbox8
_options.vim (optional)
Lets create a file to store vim options. I am going to put it in ${HOME}/.vim/_options.vim
. I tried to document the options below. These are optional, I borrowed some of this information from LunarVims default settings. Most options can be prefixed with no
to disable the behavior.
let mapleader="\ " " set leader key to space
set clipboard="" " don't use clipboard
set cmdheight=1 " more space in the neovim command line for
set colorcolumn="99999" " fixes indentline for now
set completeopt=menuone,noselect
set conceallevel=0 " so that `` is visible in markdown files
set cursorline " highlight the current line
set expandtab " convert tabs to spaces
set fileencoding="utf-8" " the encoding written to a file
set foldexpr="" " set to "nvim_treesitter#foldexpr()" for treesitter based folding
set hidden " required to keep multiple buffers and open multiple buffers
set hlsearch " highlight all matches on previous search pattern
set ignorecase " ignore case in search patterns
set laststatus=2 " hide statusline
set list " show hidden chars
set listchars=tab:│\ ,trail:·,nbsp:+
set nobackup " creates a backup file
set norelativenumber " set relative numbered lines
set nospell " disable spell checking
set noswapfile " creates a swapfile
set nowritebackup " if a file is being edited by another program (or was written to file while editing with another program) it is not allowed to be edited
set number " set numbered lines
set numberwidth=1 " set number column width to 2 {default 4}
set pumheight=10 " pop up menu height
set scrolloff=4 " is one of my fav
set shiftwidth=2 " the number of spaces inserted for each indentation
set showmode " shows " INSERT " in cmdline
set showtabline=2 " always show tabs
set sidescrolloff=4
set signcolumn="yes" " always show the sign column otherwise it would shift the text each time
set smartcase " smart case
set smartindent " make indenting smarter again
set spelllang="en" " language for spell checking
set splitbelow " force all horizontal splits to go below current window
set splitright " force all vertical splits to go to the right of current window
set tabstop=2 " insert 2 spaces for a tab
set timeoutlen=500 " timeout length
set title " set the title of window to the value of the titlestring
set titlestring="%<%F - vim" " what the title of the window will be set to
set undodir="/undo" .. "/undo"
set undofile " enable persistent undo
set updatetime=300 " faster completion
set wrap " display lines as one long line
_plugins.vim
Lets create a file to manage vim plugins. I am going to put it in ${HOME}/.vim/_plugins.vim
. For this tutorial we are using vim-plug.
Note fancy things are happening in the first 2 blocks of code that will auto install
vim-plug
and auto install missing plugins. (curl
is required for this magic to happen)-
Note 3 plugins are being installed here:
- coc.nvim (LSP IDE magic)
- vim-gruvbox8 (colorscheme)
- vim-commentary (nice shortcuts for code commenting)
" https://github.com/junegunn/vim-plug/wiki/tips#automatic-installation
" Install vim-plug if not found
if empty(glob('~/.vim/autoload/plug.vim'))
silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
\ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
endif
" Run PlugInstall if there are missing plugins
autocmd VimEnter * if len(filter(values(g:plugs), '!isdirectory(v:val.dir)'))
\| PlugInstall --sync | source $MYVIMRC
\| endif
" Plugins
call plug#begin()
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'lifepillar/vim-gruvbox8'
Plug 'tpope/vim-commentary'
call plug#end()
Most used shortcut key for vim-commentary
Shortcut | Description |
---|---|
gcc |
comment / uncomment |
_lsp.vim
Lets create a file to manage vim lsp servers. I am going to put it in ${HOME}/.vim/_lsp.vim
. This is where we will configure coc.nvim.
From the example. The following has been slightly modified moving some options to _options.vim, and configuring the statusline to be as close to vanilla vim with some lsp information.
" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
" Use <c-space> to trigger completion.
if has('nvim')
inoremap <silent><expr> <c-space> coc#refresh()
else
inoremap <silent><expr> <c-@> coc#refresh()
endif
" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>
function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('<cword>')
elseif (coc#rpc#ready())
call CocActionAsync('doHover')
else
execute '!' . &keywordprg . " " . expand('<cword>')
endif
endfunction
" Highlight the symbol and its references when holding the cursor.
" autocmd CursorHold * silent call CocActionAsync('highlight')
" Symbol renaming.
nmap <leader>rn <Plug>(coc-rename)
" Formatting selected code.
xmap <leader>f <Plug>(coc-format-selected)
nmap <leader>f <Plug>(coc-format-selected)
augroup mygroup
autocmd!
" Setup formatexpr specified filetype(s).
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
" Update signature help on jump placeholder.
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end
" Applying codeAction to the selected region.
" Example: `<leader>aap` for current paragraph
xmap <leader>a <Plug>(coc-codeaction-selected)
nmap <leader>a <Plug>(coc-codeaction-selected)
" Remap keys for applying codeAction to the current buffer.
nmap <leader>ac <Plug>(coc-codeaction)
" Apply AutoFix to problem on the current line.
nmap <leader>qf <Plug>(coc-fix-current)
" Run the Code Lens action on the current line.
nmap <leader>cl <Plug>(coc-codelens-action)
" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
xmap if <Plug>(coc-funcobj-i)
omap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap af <Plug>(coc-funcobj-a)
xmap ic <Plug>(coc-classobj-i)
omap ic <Plug>(coc-classobj-i)
xmap ac <Plug>(coc-classobj-a)
omap ac <Plug>(coc-classobj-a)
" Remap <C-f> and <C-b> for scroll float windows/popups.
if has('nvim-0.4.0') || has('patch-8.2.0750')
nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
endif
" Use CTRL-S for selections ranges.
" Requires 'textDocument/selectionRange' support of language server.
nmap <silent> <C-s> <Plug>(coc-range-select)
xmap <silent> <C-s> <Plug>(coc-range-select)
" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')
" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call CocAction('fold', <f-args>)
" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR :call CocActionAsync('runCommand', 'editor.action.organizeImport')
" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
set statusline=\ %<%f\ %h%m%r
set statusline+=%=%-10.50{ShowCocStatus()}\ %-.(%l,%c%V%)\ %P
function! ShowCocStatus()
return get(g:, 'coc_status', '')
endfunc
" Mappings for CoCList
" Show all diagnostics.
nnoremap <silent><nowait> <space>a :<C-u>CocList diagnostics<cr>
" Manage extensions.
nnoremap <silent><nowait> <space>e :<C-u>CocList extensions<cr>
" Show commands.
nnoremap <silent><nowait> <space>c :<C-u>CocList commands<cr>
" Find symbol of current document.
nnoremap <silent><nowait> <space>o :<C-u>CocList outline<cr>
" Search workspace symbols.
nnoremap <silent><nowait> <space>s :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent><nowait> <space>j :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent><nowait> <space>k :<C-u>CocPrev<CR>
" Resume latest coc list.
nnoremap <silent><nowait> <space>p :<C-u>CocListResume<CR>
There is a lot going on in there. This makes it so we get (tab) completion on typing, and setups tons of shortcuts for quickly doing things. Look for nmap
for all the settings. Here are a few of the very basics.
Shortcut | Description |
---|---|
gd |
go to def |
K |
show hover |
leader rn |
rename |
leader f |
call format |
- Note some languages require formatters to be installed first. As an example in
python
the default formatter usingcoc-pyright
server isautopep8
. In order to use this formatterpip install autopep8
etc...
vimrc
Now lets bring it all together. Open ${HOME}/.vimrc
(I am not sure where this lives in windows sorry) and add the following.
source ~/.vim/_options.vim
source ~/.vim/_plugins.vim
source ~/.vim/_lsp.vim
source ~/.vim/_theme.vim
Installing servers
Lets try installing a coc.nvim
extension. Quick link to some extenstions. For the purpose of this post lets install coc-pyright
and try it out with a python file.
Install extenstion
Lets create a simple python file. vim main.py
- Note line 4 has an error, and once we are setup with
coc.nvim
we should see it.
#!/usr/bin/env python
def echo(msg):
print msg
if __name__ == "__main__":
echo("Hello World!")
- Install
coc-pyright
:CocInstall coc-pyright
- Save the file
:wq
Next time the file is open it is expected to see an error indicated in line 4. Move the cursor to msg and the following should pop up.
Conclusion
If everything is working as planned you have successfully setup coc.nvim
and are now off to the races to further configure things. Happy hacking.
Top comments (0)