-
-
Notifications
You must be signed in to change notification settings - Fork 62
vimrc tips
In this wiki we cover a bit more detail on what needs to be in your .vimrc
/.gvimrc
, followed by a number of tips and tricks with your configuration.
If you have a .vimrc
file, minimal.vimrc
shows the bare bones required in order to get govim
up and running.
If you only have a .gvimrc
file (i.e. you do not have a .vimrc
file and only use GVim), then the minimal.vimrc
settings should be superfluous; gvim
is more "modern" out of the box. But if you are having issues, be sure to check you aren't unsetting/overriding the required values in minimal.vimrc
.
To turn on syntax highlighting for *.go
files:
syntax on
The GOVIMHover
function triggers hover information to be shown for the identifier under the cursor as opposed to the mouse. This is very useful for people who tend to use the keyboard as much (if not more) than the mouse.
You can create a mapping to call this function, by adding something like the following:
" $HOME/.vim/ftplugin/go.vim
nmap <silent> <buffer> <Leader>h : <C-u>call GOVIMHover()<CR>
(See :help mapleader
for details on the special <Leader>
key)
govim
defines some default key mappings within Go files. To override these, create an after-directory ftplugin:
" $HOME/.vim/after/ftplugin/go.vim
nnoremap <buffer> <silent> <C-]> :hide GOVIMGoToDef<cr>
@mvdan tracked down this article which explains the reason behind the delay and also a simple fix by adding the following to your .vimrc
:
" $HOME/.vimrc
set timeoutlen=1000 ttimeoutlen=0
The following mappings map the <F2>
key to open the quickfix window if there are errors but does not shift focus to the quickfix window (unlike the :cw
command):
" $HOME/.vim/after/ftplugin/go.vim
nmap <silent> <buffer> <F2> :execute "GOVIMQuickfixDiagnostics" ^V| cw ^V| if len(getqflist()) > 0 && getwininfo(win_getid())[0].quickfix == 1 ^V| :wincmd p ^V| endif<CR>
imap <silent> <buffer> <F2> <C-O>:execute "GOVIMQuickfixDiagnostics" ^V| cw ^V| if len(getqflist()) > 0 && getwininfo(win_getid())[0].quickfix == 1 ^V| :wincmd p ^V| endif<CR>
Note: ^V|
is achieved by typing <C-v>v|
. Or in long form: hold down left control, press v
, press v
again, release left control, then press |
As noted in the comment, these mappings should be added to the $HOME/.vim/after/ftplugin/go.vim
file, not your .vimrc
(or equivalent).
#277 is tracking the ability to automatically open/close the quickfix window as and when there are errors/not.
If you use Vim8 packages to load govim
and have calls to govim#config#Set
in your .vimrc
, you will see errors like:
Error detected while processing /home/myitcv/.vimrc:
E117: Unknown function: govim#config#Set
Vim8 packages get loaded after the user's .vimrc
. Hence the config autoload functions will not yet be available.
As a workaround, put all the calls to govim#config#Set
at the end of your .vimrc
and simply preface them as follows:
" $HOME/.vimrc
...
" force load Vim8 packages early
packadd govim
call govim#config#Set("FormatOnSave", "")
If you already have line numbers shown, having an additional gutter to the left for error signs (markers which correspond to errors in the quickfix window) can take up valuable screen real estate. Instead, configure Vim to show signs in the number column via:
" $HOME/.vimrc
set signcolumn=number
This requires Vim >= v8.1.1564
The current default of placing hover popups above-and-to-the-right might not be to your taste; you might prefer the old Vim "balloon" default of below-and-to-the-right. If that is the case, you can configure things differently. Add something like this to your .vimrc
:
" $HOME/.vimrc
call govim#config#Set("ExperimentalMouseTriggeredHoverPopupOptions", {
\ "mousemoved": "any",
\ "pos": "topleft",
\ "line": +1,
\ "col": 0,
\ "moved": "any",
\ "wrap": v:false,
\ "close": "click",
\ "padding": [0, 1, 0, 1],
\})
See :help popup_create-arguments
for details of the various options that can be set for ExperimentalMouseTriggeredHoverPopupOptions
and ExperimentalCursorTriggeredHoverPopupOptions
. The only difference is that "line"
and "col"
are interpreted as values relative to the mouse/cursor position.
Vim does not have such a feature by default, but the excellent https://github.com/jiangmiao/auto-pairs plugin does. In the future we may look to distribute this with govim
for a nice out-of-the-box experience.
By default, govim
automatically populates the quickfix window with diagnostic errors reported by gopls
. But it's easy to turn this off and only have it populate the quickfix window on demand. Simply add the following to your .vimrc
(or equivalent):
call govim#config#Set("QuickfixAutoDiagnostics", 0)
Then use :GOVIMQuickfixDiagnostics
to populate the quickfix window with diagnostics.
There are four different highlights for signs defined by govim
:
- GOVIMSignErr
- GOVIMSignWarn
- GOVIMSignInfo
- GOVIMSignHint
The default values can be overridden in .vimrc
to get custom colors that matches your theme, e.g.:
highlight GOVIMSignErr ctermfg=15 ctermbg=1 guisp=Blue guifg=Blue
If you would like to change the what is shown in the gutter from the default >>
it is possible to override the sign definition in .vimrc
, e.g. where warnings are changed to !!
:
call sign_define("GOVIMSignWarn", {"text":"!!","texthl":"GOVIMSignWarn"})
There are a number of plugins that enable autocompletion. With thanks to @mcesar, here is one such way:
- Add https://github.com/prabirshrestha/asyncomplete.vim as a plugin
- Add https://github.com/yami-beta/asyncomplete-omni.vim as a plugin
- Add the following to the bottom of your
.vimrc
:
function! Omni()
call asyncomplete#register_source(asyncomplete#sources#omni#get_source_options({
\ 'name': 'omni',
\ 'whitelist': ['go'],
\ 'completor': function('asyncomplete#sources#omni#completor')
\ }))
endfunction
au VimEnter * :call Omni()
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<cr>"
Then you should find that autocompletion works as you type.
Vim has a helpful command :cbelow
which will go to the next error in the current buffer below the cursor location, but it will not wrap around to the top of the file. If you would like to have a shortcut which goes to the next error in the file and wraps around to the top, you can define a command and bind it to a keystroke with something like this in your .vimrc
:
command! Cnext try | cbelow | catch | cabove 9999 | catch | endtry
nnoremap <leader>m :Cnext<CR>
π‘ Tip: use fzf
with workspace symbol search
fzf
is a popular fuzzy finding implementation and interface for Vim. fzf
can
be configured with various sources: file hierarchies, process lists, git grep
results... the list
can (and does) go on.
Workspace symbol search however is slightly different, because the search results
can (and do) change with each refinement of the search query, especially with
fuzzy matching. Hence a slightly different approach is required when it
comes to using gopls
' workspace symbol method as an fzf
source.
The following configuration, placed in your .vimrc
, will map \s
(or whatever <Leader>s
is configured as) to start an fzf
workspace symbol search. When you have found and selected the result you want:
-
Enter
will jump to that result in the current window -
<Ctrl-s>
will open open a split and jump to the result -
<Ctrl-v>
will open a vertical split and jump to the result -
<Ctrl-t>
will open a new tab and jump to the result
" GovimFZFSymbol is a user-defined function that can be called to start fzf in
" a mode whereby it uses govim's new child-parent capabilities to query the
" parent govim instance for gopls Symbol method results that then are used to
" drive fzf.
function GovimFZFSymbol(queryAddition)
let l:expect_keys = join(keys(s:symbolActions), ',')
let l:source = join(GOVIMParentCommand(), " ").' gopls Symbol -quickfix'
let l:reload = l:source." {q}"
call fzf#run(fzf#wrap({
\ 'source': l:source,
\ 'sink*': function('s:handleSymbol'),
\ 'options': [
\ '--with-nth', '2..',
\ '--expect='.l:expect_keys,
\ '--phony',
\ '--bind', 'change:reload:'.l:reload
\ ]}))
endfunction
" Map \s to start a symbol search
"
" Once you have found the symbol you want:
"
" * Enter will open that result in the current window
" * Ctrl-s will open that result in a split
" * Ctrl-v will open that result in a vertical split
" * Ctrl-t will open that result in a new tab
"
nmap <Leader>s :call GovimFZFSymbol('')<CR>
" s:symbolActions are the actions that, in addition to plain <Enter>,
" we want to be able to fire from fzf. Here we map them to the corresponding
" command in VimScript.
let s:symbolActions = {
\ 'ctrl-t': 'tab split',
\ 'ctrl-s': 'split',
\ 'ctrl-v': 'vsplit',
\ }
" With thanks and reference to github.com/junegunn/fzf.vim/issues/948 which
" inspired the following
function! s:handleSymbol(sym) abort
" a:sym is a [2]string array where the first element is the
" key pressed (or empty if simply Enter), and the second element
" is the entry selected in fzf, i.e. the match.
"
" The match will be of the form:
"
" $filename:$line:$col: $match
"
if len(a:sym) == 0
return
endif
let l:cmd = get(s:symbolActions, a:sym[0], "")
let l:match = a:sym[1]
let l:parts = split(l:match, ":")
execute 'silent' l:cmd
execute 'buffer' bufnr(l:parts[0], 1)
set buflisted
call cursor(l:parts[1], l:parts[2])
normal! zz
endfunction