Skip to content

Instantly share code, notes, and snippets.

@avegancafe
Created December 20, 2021 18:34
Show Gist options
  • Save avegancafe/919ddd0a078673abcfec8480aa20c104 to your computer and use it in GitHub Desktop.
Save avegancafe/919ddd0a078673abcfec8480aa20c104 to your computer and use it in GitHub Desktop.
vim-go issue reproduction
This file has been truncated, but you can view the full file.
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/dashboard-nvim/autoload/sessions/session.vim
Sourced 1 time
Total time: 0.001254
Self time: 0.001254
count total (s) self (s)
" Plugin: https://github.com/hardcoreplayers/dashboard-nvim
" Description: A fancy start screen for Vim.
" Maintainer: Glepnir <http://github.com/glepnir>
1 0.000007 function! sessions#session#session_save(name)
if ! isdirectory(g:session_directory)
call mkdir(g:session_directory, 'p')
endif
let file_name = empty(a:name) ? s:project_name() : a:name
let file_path = g:session_directory.'/'.file_name.'.vim'
execute 'mksession! '.fnameescape(file_path)
let v:this_session = file_path
echohl MoreMsg
echo 'Session `'.file_name.'` is now persistent'
echohl None
endfunction
1 0.000003 function! sessions#session#session_load(name)
let file_name = empty(a:name) ? s:project_name() : a:name
let file_path = g:session_directory.'/'.file_name.'.vim'
if ! empty(v:this_session) && ! exists('g:SessionLoad')
\ | execute 'mksession! '.fnameescape(v:this_session)
\ | endif
if filereadable(file_path)
noautocmd silent! %bwipeout!
execute 'silent! source '.file_path
if &laststatus == 0
set laststatus=2
endif
echomsg 'Loaded "'.file_path.'" session'
else
echohl ErrorMsg
echomsg 'The session "'.file_path.'" doesn''t exist'
echohl None
endif
endfunction
1 0.000003 function! sessions#session#session_list(A, C, P)
return map(
\ split(glob(g:session_directory.'/*.vim'), '\n'),
\ "fnamemodify(v:val, ':t:r')"
\ )
endfunction
1 0.000003 function! s:project_name()
let l:cwd = resolve(getcwd())
let l:cwd = substitute(l:cwd, '^'.$HOME.'/', '', '')
let l:cwd = fnamemodify(l:cwd, ':p:gs?/?_?')
let l:cwd = substitute(l:cwd, '^\.', '', '')
return l:cwd
endfunction
" vim: et sw=2 sts=2
SCRIPT /Users/kyle/.cache/vim/session/workspace_api-v2-backend.vim
Sourced 1 time
Total time: 0.496258
Self time: 0.059121
count total (s) self (s)
1 0.000022 let SessionLoad = 1
1 0.000119 0.000050 let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1
1 0.000022 let v:this_session=expand("<sfile>:p")
1 0.000019 silent only
1 0.000006 silent tabonly
1 0.001135 0.000812 cd ~/workspace/api-v2-backend
1 0.000024 if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''
1 0.000008 let s:wipebuf = bufnr('%')
1 0.000001 endif
1 0.000025 0.000016 set shortmess=aoO
1 0.001586 badd +159 apps/parking/web/reservations.go
1 0.000007 argglobal
1 0.000004 %argdel
1 0.462601 0.026069 edit apps/parking/web/reservations.go
1 0.000005 argglobal
1 0.000015 0.000011 setlocal fdm=syntax
1 0.000003 0.000002 setlocal fde=0
1 0.000003 0.000002 setlocal fmr={{{,}}}
1 0.000002 0.000002 setlocal fdi=#
1 0.012575 0.012573 setlocal fdl=20
1 0.000010 0.000009 setlocal fml=1
1 0.000003 0.000002 setlocal fdn=20
1 0.000003 0.000002 setlocal fen
1 0.000009 let s:l = 165 - ((28 * winheight(0) + 21) / 43)
1 0.000003 if s:l < 1 | let s:l = 1 | endif
1 0.000009 keepjumps exe s:l
1 0.017227 normal! zt
1 0.000005 keepjumps 165
1 0.000016 normal! 03|
1 0.000002 tabnext 1
1 0.000014 if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0&& getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
1 0.000195 0.000094 silent exe 'bwipe ' . s:wipebuf
1 0.000001 endif
1 0.000003 unlet! s:wipebuf
1 0.000014 0.000011 set winheight=1 winwidth=20 shortmess=filnxtToOFIs
1 0.000028 let s:sx = expand("<sfile>:p:r")."x.vim"
1 0.000349 if filereadable(s:sx)
exe "source " . fnameescape(s:sx)
1 0.000001 endif
1 0.000035 0.000029 let &g:so = s:so_save | let &g:siso = s:siso_save
1 0.000011 0.000010 set hlsearch
1 0.000001 nohlsearch
1 0.000090 0.000007 doautoall SessionLoadPost
1 0.000008 unlet SessionLoad
" vim: set ft=vim :
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/ftplugin/go.vim
Sourced 2 times
Total time: 0.007462
Self time: 0.006547
count total (s) self (s)
" Copyright 2013 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" go.vim: Vim filetype plugin for Go.
2 0.000012 if exists("b:did_ftplugin")
1 0.000000 finish
1 0.000001 endif
1 0.000004 let b:did_ftplugin = 1
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000009 let s:cpo_save = &cpo
1 0.000014 set cpo&vim
1 0.000007 let b:undo_ftplugin = "setl fo< com< cms<"
\ . "| exe 'au! vim-go-buffer * <buffer>'"
1 0.000005 setlocal formatoptions-=t
1 0.000005 setlocal comments=s1:/*,mb:*,ex:*/,://
1 0.000002 setlocal commentstring=//\ %s
1 0.000006 setlocal noexpandtab
1 0.006612 0.005714 compiler go
1 0.000033 0.000024 if go#config#CodeCompletionEnabled()
" Set autocompletion
1 0.000005 setlocal omnifunc=go#complete#Complete
1 0.000001 endif
1 0.000004 if get(g:, "go_doc_keywordprg_enabled", 1)
" keywordprg doesn't allow to use vim commands, override it
1 0.000023 nnoremap <buffer> <silent> K :GoDoc<cr>
1 0.000001 endif
1 0.000002 if get(g:, "go_def_mapping_enabled", 1)
" these are default Vim mappings, we're overriding them to make them
" useful again for Go source code
1 0.000008 nnoremap <buffer> <silent> gd :GoDef<cr>
1 0.000007 nnoremap <buffer> <silent> <C-]> :GoDef<cr>
1 0.000009 nnoremap <buffer> <silent> <C-LeftMouse> <LeftMouse>:GoDef<cr>
1 0.000007 nnoremap <buffer> <silent> g<LeftMouse> <LeftMouse>:GoDef<cr>
1 0.000008 nnoremap <buffer> <silent> <C-w><C-]> :<C-u>call go#def#Jump("split", 0)<CR>
1 0.000006 nnoremap <buffer> <silent> <C-w>] :<C-u>call go#def#Jump("split", 0)<CR>
1 0.000007 nnoremap <buffer> <silent> <C-t> :<C-U>call go#def#StackPop(v:count1)<cr>
1 0.000001 endif
1 0.000003 if get(g:, "go_textobj_enabled", 1)
1 0.000008 onoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr>
1 0.000007 xnoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr>
1 0.000006 onoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr>
1 0.000006 xnoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr>
1 0.000006 onoremap <buffer> <silent> ac :<c-u>call go#textobj#Comment('a')<cr>
1 0.000005 xnoremap <buffer> <silent> ac :<c-u>call go#textobj#Comment('a')<cr>
1 0.000005 onoremap <buffer> <silent> ic :<c-u>call go#textobj#Comment('i')<cr>
1 0.000005 xnoremap <buffer> <silent> ic :<c-u>call go#textobj#Comment('i')<cr>
" Remap ]] and [[ to jump betweeen functions as they are useless in Go
1 0.000011 nnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('n', 'next')<cr>
1 0.000007 nnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('n', 'prev')<cr>
1 0.000007 onoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('o', 'next')<cr>
1 0.000006 onoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('o', 'prev')<cr>
1 0.000006 xnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('v', 'next')<cr>
1 0.000006 xnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('v', 'prev')<cr>
1 0.000001 endif
" Autocommands
" ============================================================================
"
1 0.000010 augroup vim-go-buffer
1 0.000108 autocmd! * <buffer>
" The file is registered (textDocument/DidOpen) with gopls in plugin/go.vim
" on the FileType event.
1 0.000017 0.000008 if go#util#has_job()
1 0.000009 autocmd BufWritePost,FileChangedShellPost <buffer> call go#lsp#DidChange(expand('<afile>:p'))
1 0.000003 autocmd BufDelete <buffer> call go#lsp#DidClose(expand('<afile>:p'))
1 0.000001 endif
" send the textDocument/didChange notification when idle. go#lsp#DidChange
" will not send an event if the buffer hasn't changed since the last
" notification.
1 0.000004 autocmd CursorHold,CursorHoldI <buffer> call go#lsp#DidChange(expand('<afile>:p'))
1 0.000003 autocmd BufEnter,CursorHold <buffer> call go#auto#update_autocmd()
" Echo the identifier information when completion is done. Useful to see
" the signature of a function, etc...
1 0.000002 if exists('##CompleteDone')
1 0.000003 autocmd CompleteDone <buffer> call go#auto#complete_done()
1 0.000001 endif
1 0.000003 autocmd BufWritePre <buffer> call go#auto#fmt_autosave()
1 0.000002 autocmd BufWritePost <buffer> call go#auto#metalinter_autosave()
" TODO(bc): autocmd BufWinLeave call go#lsp#DidChange(expand('<afile>:p'))
1 0.000003 if !has('textprop')
"TODO(bc): how to clear sameids and diagnostics when a non-go buffer is
" loaded into a window and the previously loaded buffer is still loaded in
" another window?
" TODO(bc): only clear when the new buffer isn't the old buffer
" clear SameIds when the buffer is unloaded from its last window so that
" loading another buffer (especially of a different filetype) in the same
" window doesn't highlight the most recently matched identifier's positions.
1 0.000003 autocmd BufWinLeave <buffer> call go#guru#ClearSameIds()
" clear SameIds when a new buffer is loaded in the window so that the
" previous buffer's highlighting isn't used.
1 0.000002 autocmd BufWinEnter <buffer> call go#guru#ClearSameIds()
" clear diagnostics when the buffer is unloaded from its last window so that
" loading another buffer (especially of a different filetype) in the same
" window doesn't highlight the previously loaded buffer's diagnostics.
1 0.000002 autocmd BufWinLeave <buffer> call go#lsp#ClearDiagnosticHighlights()
" clear diagnostics when a new buffer is loaded in the window so that the
" previous buffer's diagnostics aren't used.
"autocmd BufWinEnter <buffer> call go#lsp#ClearDiagnosticHighlights()
1 0.000001 endif
1 0.000001 augroup end
" restore Vi compatibility settings
1 0.000008 let &cpo = s:cpo_save
1 0.000002 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/compiler/go.vim
Sourced 1 time
Total time: 0.000363
Self time: 0.000363
count total (s) self (s)
" Copyright 2013 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" compiler/go.vim: Vim compiler file for Go.
1 0.000006 if exists("g:current_compiler")
finish
1 0.000001 endif
1 0.000003 let g:current_compiler = "go"
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000005 let s:cpo_save = &cpo
1 0.000007 set cpo&vim
1 0.000005 if exists(":CompilerSet") != 2
command -nargs=* CompilerSet setlocal <args>
1 0.000001 endif
1 0.000004 let s:save_cpo = &cpo
1 0.000005 set cpo-=C
1 0.000053 if filereadable("makefile") || filereadable("Makefile")
CompilerSet makeprg=make
1 0.000001 else
1 0.000008 CompilerSet makeprg=go\ build
1 0.000001 endif
" Define the patterns that will be recognized by QuickFix when parsing the
" output of Go command that use this errorforamt (when called make, cexpr or
" lmake, lexpr). This is the global errorformat, however some command might
" use a different output, for those we define them directly and modify the
" errorformat ourselves. More information at:
" http://vimdoc.sourceforge.net/htmldoc/quickfix.html#errorformat
1 0.000011 CompilerSet errorformat =%-G#\ %.%# " Ignore lines beginning with '#' ('# command-line-arguments' line sometimes appears?)
1 0.000006 CompilerSet errorformat+=%-G%.%#panic:\ %m " Ignore lines containing 'panic: message'
1 0.000006 CompilerSet errorformat+=%Ecan\'t\ load\ package:\ %m " Start of multiline error string is 'can\'t load package'
1 0.000006 CompilerSet errorformat+=%A%\\%%(%[%^:]%\\+:\ %\\)%\\?%f:%l:%c:\ %m " Start of multiline unspecified string is 'filename:linenumber:columnnumber:'
1 0.000005 CompilerSet errorformat+=%A%\\%%(%[%^:]%\\+:\ %\\)%\\?%f:%l:\ %m " Start of multiline unspecified string is 'filename:linenumber:'
1 0.000004 CompilerSet errorformat+=%C%*\\s%m " Continuation of multiline error message is indented
1 0.000004 CompilerSet errorformat+=%-G%.%# " All lines not matching any of the above patterns are ignored
1 0.000005 let &cpo = s:save_cpo
1 0.000003 unlet s:save_cpo
" restore Vi compatibility settings
1 0.000004 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /opt/homebrew/Cellar/neovim/0.5.1_1/share/nvim/runtime/compiler/go.vim
Sourced 1 time
Total time: 0.000396
Self time: 0.000396
count total (s) self (s)
" Vim compiler file
" Compiler: Go
" Maintainer: David Barnett (https://github.com/google/vim-ft-go)
" Last Change: 2014 Aug 16
1 0.000005 if exists('current_compiler')
1 0.000002 finish
endif
let current_compiler = 'go'
if exists(':CompilerSet') != 2
command -nargs=* CompilerSet setlocal <args>
endif
let s:save_cpo = &cpo
set cpo-=C
CompilerSet makeprg=go\ build
CompilerSet errorformat=
\%-G#\ %.%#,
\%A%f:%l:%c:\ %m,
\%A%f:%l:\ %m,
\%C%*\\s%m,
\%-G%.%#
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: sw=2 sts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/ftplugin/go/commands.vim
Sourced 1 time
Total time: 0.286915
Self time: 0.002260
count total (s) self (s)
" -- gorename
1 0.000012 command! -nargs=? -complete=customlist,go#rename#Complete GoRename call go#rename#Rename(<bang>0, <f-args>)
" -- guru
" do not configure commands that _require_ guru when not in GOPATH mode.
"if go#package#InGOPATH()
1 0.000006 command! -nargs=* -complete=customlist,go#package#Complete GoGuruScope call go#guru#Scope(<f-args>)
1 0.000005 command! -range=% GoPointsTo call go#guru#PointsTo(<count>)
1 0.000004 command! -range=% GoWhicherrs call go#guru#Whicherrs(<count>)
1 0.000004 command! -range=% GoCallees call go#guru#Callees(<count>)
1 0.000004 command! -range=% GoDescribe call go#guru#Describe(<count>)
1 0.000004 command! -range=% GoCallstack call go#guru#Callstack(<count>)
1 0.000004 command! -range=% GoFreevars call go#guru#Freevars(<count>)
1 0.000004 command! -range=% GoChannelPeers call go#guru#ChannelPeers(<count>)
"endif
1 0.000004 command! -range=% GoImplements call go#implements#Implements(<count>)
1 0.000005 command! -range=% GoReferrers call go#referrers#Referrers(<count>)
1 0.000004 command! -range=0 GoSameIds call go#guru#SameIds(1)
1 0.000003 command! -range=0 GoSameIdsClear call go#guru#ClearSameIds()
1 0.000007 command! -range=0 GoSameIdsToggle call go#guru#ToggleSameIds()
1 0.000004 command! -range=0 GoSameIdsAutoToggle call go#guru#AutoToggleSameIds()
" -- calls
1 0.000003 command! -nargs=0 GoCallers call go#calls#Callers()
" -- tags
1 0.000018 command! -nargs=* -range GoAddTags call go#tags#Add(<line1>, <line2>, <count>, <f-args>)
1 0.000007 command! -nargs=* -range GoRemoveTags call go#tags#Remove(<line1>, <line2>, <count>, <f-args>)
" -- mod
1 0.000003 command! -nargs=0 -range GoModFmt call go#mod#Format()
" -- tool
1 0.000004 command! -nargs=* -complete=customlist,go#tool#ValidFiles GoFiles echo go#tool#Files(<f-args>)
1 0.000003 command! -nargs=0 GoDeps echo go#tool#Deps()
1 0.000003 command! -nargs=0 GoInfo call go#tool#Info(1)
1 0.000004 command! -nargs=0 GoAutoTypeInfoToggle call go#complete#ToggleAutoTypeInfo()
" -- cmd
1 0.000005 command! -nargs=* -bang GoBuild call go#cmd#Build(<bang>0,<f-args>)
1 0.000005 command! -nargs=? -bang GoBuildTags call go#cmd#BuildTags(<bang>0, <f-args>)
1 0.000005 command! -nargs=* -bang GoGenerate call go#cmd#Generate(<bang>0,<f-args>)
1 0.000005 command! -nargs=* -bang -complete=file GoRun call go#cmd#Run(<bang>0,<f-args>)
1 0.000005 command! -nargs=* -bang GoInstall call go#cmd#Install(<bang>0, <f-args>)
" -- test
1 0.000005 command! -nargs=* -bang GoTest call go#test#Test(<bang>0, 0, <f-args>)
1 0.000005 command! -nargs=* -bang GoTestFunc call go#test#Func(<bang>0, <f-args>)
1 0.000005 command! -nargs=* -bang GoTestCompile call go#test#Test(<bang>0, 1, <f-args>)
" -- cover
1 0.000004 command! -nargs=* -bang GoCoverage call go#coverage#Buffer(<bang>0, <f-args>)
1 0.000003 command! -nargs=* -bang GoCoverageClear call go#coverage#Clear()
1 0.000005 command! -nargs=* -bang GoCoverageToggle call go#coverage#BufferToggle(<bang>0, <f-args>)
1 0.000020 command! -nargs=* -bang GoCoverageBrowser call go#coverage#Browser(<bang>0, <f-args>)
" -- play
1 0.000007 command! -nargs=0 -range=% GoPlay call go#play#Share(<count>, <line1>, <line2>)
" -- def
1 0.000003 command! -nargs=* -range GoDef :call go#def#Jump('', 0)
1 0.000003 command! -nargs=* -range GoDefType :call go#def#Jump('', 1)
1 0.000003 command! -nargs=? GoDefPop :call go#def#StackPop(<f-args>)
1 0.000003 command! -nargs=? GoDefStack :call go#def#Stack(<f-args>)
1 0.000004 command! -nargs=? GoDefStackClear :call go#def#StackClear(<f-args>)
" -- doc
1 0.000005 command! -nargs=* -range -complete=customlist,go#package#Complete GoDoc call go#doc#Open('new', 'split', <f-args>)
1 0.000004 command! -nargs=* -range -complete=customlist,go#package#Complete GoDocBrowser call go#doc#OpenBrowser(<f-args>)
" -- fmt
1 0.000003 command! -nargs=0 GoFmt call go#fmt#Format(0)
1 0.000004 command! -nargs=0 GoFmtAutoSaveToggle call go#fmt#ToggleFmtAutoSave()
1 0.000003 command! -nargs=0 GoImports call go#fmt#Format(1)
" -- asmfmt
1 0.000004 command! -nargs=0 GoAsmFmtAutoSaveToggle call go#asmfmt#ToggleAsmFmtAutoSave()
" -- import
1 0.000006 command! -nargs=? -complete=customlist,go#package#Complete GoDrop call go#import#SwitchImport(0, '', <f-args>, '')
1 0.000007 command! -nargs=1 -bang -complete=customlist,go#package#Complete GoImport call go#import#SwitchImport(1, '', <f-args>, '<bang>')
1 0.000006 command! -nargs=* -bang -complete=customlist,go#package#Complete GoImportAs call go#import#SwitchImport(1, <f-args>, '<bang>')
" -- linters
1 0.000005 command! -nargs=* -bang GoMetaLinter call go#lint#Gometa(<bang>0, 0, <f-args>)
1 0.000005 command! -nargs=0 GoMetaLinterAutoSaveToggle call go#lint#ToggleMetaLinterAutoSave()
1 0.000005 command! -nargs=* -bang GoLint call go#lint#Golint(<bang>0, <f-args>)
1 0.000005 command! -nargs=* -bang GoVet call go#lint#Vet(<bang>0, <f-args>)
1 0.000005 command! -nargs=* -bang -complete=customlist,go#package#Complete GoErrCheck call go#lint#Errcheck(<bang>0, <f-args>)
" -- alternate
1 0.000005 command! -bang GoAlternate call go#alternate#Switch(<bang>0, '')
" -- decls
1 0.000004 command! -nargs=? -complete=file GoDecls call go#decls#Decls(0, <q-args>)
1 0.000005 command! -nargs=? -complete=dir GoDeclsDir call go#decls#Decls(1, <q-args>)
" -- impl
1 0.000004 command! -nargs=* -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl(<f-args>)
" -- template
1 0.000004 command! -nargs=0 GoTemplateAutoCreateToggle call go#template#ToggleAutoCreate()
" -- keyify
1 0.286353 0.001698 if go#package#InGOPATH()
command! -nargs=0 GoKeyify call go#keyify#Keyify()
1 0.000000 endif
" -- fillstruct
1 0.000006 command! -nargs=0 GoFillStruct call go#fillstruct#FillStruct()
" -- debug
1 0.000003 if !exists(':GoDebugStart')
1 0.000004 command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start('debug', <f-args>)
1 0.000004 command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start('test', <f-args>)
1 0.000003 command! -nargs=* GoDebugTestFunc call go#debug#TestFunc(<f-args>)
1 0.000002 command! -nargs=1 GoDebugAttach call go#debug#Start('attach', <f-args>)
1 0.000002 command! -nargs=? GoDebugConnect call go#debug#Start('connect', <f-args>)
1 0.000002 command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint(<f-args>)
1 0.000000 endif
" -- issue
1 0.000002 command! -nargs=0 GoReportGitHubIssue call go#issue#New()
" -- iferr
1 0.000003 command! -nargs=0 GoIfErr call go#iferr#Generate()
" -- lsp
1 0.000006 command! -nargs=+ -complete=dir GoAddWorkspace call go#lsp#AddWorkspaceDirectory(<f-args>)
1 0.000002 command! -nargs=0 GoLSPDebugBrowser call go#lsp#DebugBrowser()
1 0.000003 command! -nargs=* -bang GoDiagnostics call go#lint#Diagnostics(<bang>0, <f-args>)
" -- term
1 0.000002 command! GoToggleTermCloseOnExit call go#term#ToggleCloseOnExit()
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/package.vim
Sourced 1 time
Total time: 0.000565
Self time: 0.000565
count total (s) self (s)
" Copyright 2011 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" This file provides a utility function that performs auto-completion of
" package names, for use by other commands.
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000006 let s:cpo_save = &cpo
1 0.000005 set cpo&vim
1 0.000007 let s:goos = $GOOS
1 0.000003 let s:goarch = $GOARCH
1 0.000004 if len(s:goos) == 0
1 0.000003 if exists('g:golang_goos')
let s:goos = g:golang_goos
1 0.000005 elseif has('win32') || has('win64')
let s:goos = 'windows'
1 0.000002 elseif has('macunix')
1 0.000002 let s:goos = 'darwin'
else
let s:goos = '*'
1 0.000001 endif
1 0.000001 endif
1 0.000002 if len(s:goarch) == 0
1 0.000002 if exists('g:golang_goarch')
let s:goarch = g:golang_goarch
1 0.000001 else
1 0.000001 let s:goarch = '*'
1 0.000001 endif
1 0.000001 endif
1 0.000005 function! s:paths() abort
let dirs = []
if !exists("s:goroot")
if executable('go')
let s:goroot = go#util#env("goroot")
if go#util#ShellError() != 0
call go#util#EchoError('`go env GOROOT` failed')
endif
else
let s:goroot = $GOROOT
endif
endif
if len(s:goroot) != 0 && isdirectory(s:goroot)
let dirs += [s:goroot]
endif
let workspaces = split(go#path#Default(), go#util#PathListSep())
if workspaces != []
let dirs += workspaces
endif
return dirs
endfunction
1 0.000001 function! s:module() abort
let [l:out, l:err] = go#util#ExecInDir(['go', 'list', '-m', '-f', '{{.Dir}}'])
if l:err != 0
return {}
endif
let l:dir = split(l:out, '\n')[0]
let [l:out, l:err] = go#util#ExecInDir(['go', 'list', '-m', '-f', '{{.Path}}'])
if l:err != 0
return {}
endif
let l:path = split(l:out, '\n')[0]
return {'dir': l:dir, 'path': l:path}
endfunction
1 0.000002 function! s:vendordirs() abort
let l:vendorsuffix = go#util#PathSep() . 'vendor'
let l:module = s:module()
if empty(l:module)
let [l:root, l:err] = go#util#ExecInDir(['go', 'list', '-f', '{{.Root}}'])
if l:err != 0
return []
endif
if empty(l:root)
return []
endif
let l:root = split(l:root, '\n')[0] . go#util#PathSep() . 'src'
let [l:dir, l:err] = go#util#ExecInDir(['go', 'list', '-f', '{{.Dir}}'])
if l:err != 0
return []
endif
let l:dir = split(l:dir, '\n')[0]
let l:vendordirs = []
while l:dir != l:root
let l:vendordir = l:dir . l:vendorsuffix
if isdirectory(l:vendordir)
let l:vendordirs = add(l:vendordirs, l:vendordir)
endif
let l:dir = fnamemodify(l:dir, ':h')
endwhile
return l:vendordirs
endif
let l:vendordir = l:module.dir . l:vendorsuffix
if !isdirectory(l:vendordir)
return []
endif
return [l:vendordir]
endfunction
1 0.000003 let s:import_paths = {}
" ImportPath returns the import path of the package for current buffer. It
" returns -1 if the import path cannot be determined.
1 0.000002 function! go#package#ImportPath() abort
let l:dir = expand("%:p:h")
if has_key(s:import_paths, dir)
return s:import_paths[l:dir]
endif
let l:importpath = go#package#FromPath(l:dir)
if type(l:importpath) == type(0)
return -1
endif
let s:import_paths[l:dir] = l:importpath
return l:importpath
endfunction
1 0.000002 let s:in_gopath = {}
" InGOPATH returns TRUE when the package of the current buffer is within
" GOPATH.
1 0.000002 function! go#package#InGOPATH() abort
let l:dir = expand("%:p:h")
if has_key(s:in_gopath, dir)
return s:in_gopath[l:dir][0] !=# '_'
endif
try
" turn off module support so that `go list` will report the package name
" with a leading '_' when the current buffer is not within GOPATH.
let Restore_modules = go#util#SetEnv('GO111MODULE', 'off')
let [l:out, l:err] = go#util#ExecInDir(['go', 'list'])
if l:err != 0
return 0
endif
let l:importpath = split(l:out, '\n')[0]
if len(l:importpath) > 0
let s:in_gopath[l:dir] = l:importpath
endif
finally
call call(Restore_modules, [])
endtry
return len(l:importpath) > 0 && l:importpath[0] !=# '_'
endfunction
" go#package#FromPath returns the import path of arg. -1 is returned when arg
" does not specify a package. -2 is returned when arg is a relative path
" outside of GOPATH, not in a module, and not below the current working
" directory. A relative path is returned when in a null module at or below the
" current working directory..
1 0.000002 function! go#package#FromPath(arg) abort
let l:path = fnamemodify(a:arg, ':p')
if !isdirectory(l:path)
let l:path = fnamemodify(l:path, ':h')
endif
let l:dir = go#util#Chdir(l:path)
try
if glob("*.go") == ""
" There's no Go code in this directory. We might be in a module directory
" which doesn't have any code at this level. To avoid `go list` making a
" bunch of HTTP requests to fetch dependencies, short-circuit `go list`
" and return -1 immediately.
if !empty(s:module())
return -1
endif
endif
let [l:out, l:err] = go#util#Exec(['go', 'list'])
if l:err != 0
return -1
endif
let l:importpath = split(l:out, '\n')[0]
finally
call go#util#Chdir(l:dir)
endtry
" go list returns '_CURRENTDIRECTORY' if the directory is in a null module
" (i.e. neither in GOPATH nor in a module). Return a relative import path
" if possible or an error if that is the case.
if l:importpath[0] ==# '_'
let l:relativeimportpath = fnamemodify(l:importpath[1:], ':.')
if go#util#IsWin()
let l:relativeimportpath = substitute(l:relativeimportpath, '\\', '/', 'g')
endif
if l:relativeimportpath == l:importpath[1:]
return '.'
endif
if l:relativeimportpath[0] == '/'
return -2
endif
let l:importpath= printf('./%s', l:relativeimportpath)
endif
return l:importpath
endfunction
1 0.000003 function! go#package#CompleteMembers(package, member) abort
let [l:content, l:err] = go#util#Exec(['go', 'doc', a:package])
if l:err || !len(content)
return []
endif
let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'")
try
let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*'
let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*'
let candidates = map(filter(copy(lines), 'v:val =~ mx1'),
\ 'substitute(v:val, mx1, "\\1", "")')
\ + map(filter(copy(lines), 'v:val =~ mx2'),
\ 'substitute(v:val, mx2, "\\1", "")')
return filter(candidates, '!stridx(v:val, a:member)')
catch
return []
endtry
endfunction
1 0.000003 function! go#package#Complete(ArgLead, CmdLine, CursorPos) abort
let words = split(a:CmdLine, '\s\+', 1)
" do not complete package members for these commands
let neglect_commands = ["GoImportAs", "GoGuruScope"]
if len(words) > 2 && index(neglect_commands, words[0]) == -1
" Complete package members
return go#package#CompleteMembers(words[1], words[2])
endif
let dirs = s:paths()
let module = s:module()
if len(dirs) == 0 && empty(module)
" should not happen
return []
endif
let vendordirs = s:vendordirs()
let l:modcache = go#util#env('gomodcache')
let ret = {}
for dir in dirs
" this may expand to multiple lines
let root = split(expand(dir . '/pkg/' . s:goos . '_' . s:goarch), "\n")
if l:modcache != ''
let root = add(root, l:modcache)
else
let root = add(root, expand(dir . '/pkg/mod'))
endif
let root = add(root, expand(dir . '/src'), )
let root = extend(root, vendordirs)
let root = add(root, module)
for item in root
" item may be a dictionary when operating in a module.
if type(item) == type({})
if empty(item)
continue
endif
let dir = item.dir
let path = item.path
else
let dir = item
let path = item
endif
if !empty(module) && dir ==# module.dir
if stridx(a:ArgLead, module.path) == 0
if len(a:ArgLead) != len(module.path)
let glob = globpath(module.dir, substitute(a:ArgLead, module.path . '/\?', '', '').'*')
else
let glob = module.dir
endif
elseif stridx(module.path, a:ArgLead) == 0 && stridx(module.path, '/', len(a:ArgLead)) < 0
" use the module directory when module.path begins wih a:ArgLead and
" module.path does not have any path segments after a:ArgLead.
let glob = module.dir
else
continue
endif
else
let glob = globpath(dir, a:ArgLead.'*')
endif
for candidate in split(glob)
if isdirectory(candidate)
" TODO(bc): use wildignore instead of filtering out vendor
" directories manually?
if fnamemodify(candidate, ':t') == 'vendor'
continue
endif
" if path contains version info, strip it out
let vidx = strridx(candidate, '@')
if vidx >= 0
let candidate = strpart(candidate, 0, vidx)
endif
let candidate .= '/'
elseif candidate !~ '\.a$'
continue
endif
if dir !=# path
let candidate = substitute(candidate, '^' . dir, path, 'g')
else
let candidate = candidate[len(dir)+1:]
endif
" replace a backslash with a forward slash and drop .a suffixes
let candidate = substitute(substitute(candidate, '[\\]', '/', 'g'),
\ '\.a$', '', 'g')
" without this the result can have duplicates in form of
" 'encoding/json' and '/encoding/json/'
let candidate = go#util#StripPathSep(candidate)
let ret[candidate] = candidate
endfor
endfor
endfor
return sort(keys(ret))
endfunction
" restore Vi compatibility settings
1 0.000005 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/path.vim
Sourced 1 time
Total time: 0.000306
Self time: 0.000306
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000003 let s:cpo_save = &cpo
1 0.000003 set cpo&vim
" initial_go_path is used to store the initial GOPATH that was set when Vim
" was started. It's used with :GoPathClear to restore the GOPATH when the user
" changed it explicitly via :GoPath. Initially it's empty. It's being set when
" :GoPath is used
1 0.000001 let s:initial_go_path = ""
" GoPath sets or echos the current GOPATH. If no arguments are passed it
" echoes the current GOPATH, if an argument is passed it replaces the current
" GOPATH with it. If two double quotes are passed (the empty string in go),
" it'll clear the GOPATH and will restore to the initial GOPATH.
1 0.000001 function! go#path#GoPath(...) abort
" no argument, show GOPATH
if len(a:000) == 0
echo go#path#Default()
return
endif
" we have an argument, replace GOPATH
" clears the current manually set GOPATH and restores it to the
" initial GOPATH, which was set when Vim was started.
if len(a:000) == 1 && a:1 == '""'
if !empty(s:initial_go_path)
let $GOPATH = s:initial_go_path
let s:initial_go_path = ""
endif
call go#util#EchoInfo("GOPATH restored to ". $GOPATH)
return
endif
call go#util#EchoInfo("GOPATH changed to ". a:1)
let s:initial_go_path = $GOPATH
let $GOPATH = a:1
endfunction
" Default returns the default GOPATH. If GOPATH is not set, it uses the
" default GOPATH set starting with Go 1.8. This GOPATH can be retrieved via
" 'go env GOPATH'
1 0.000002 function! go#path#Default() abort
if $GOPATH == ""
" use default GOPATH via go env
return go#util#env("gopath")
endif
return $GOPATH
endfunction
" s:HasPath checks whether the given path exists in GOPATH environment variable
" or not
1 0.000001 function! s:HasPath(path) abort
let go_paths = split(go#path#Default(), go#util#PathListSep())
let last_char = strlen(a:path) - 1
" check cases of '/foo/bar/' and '/foo/bar'
if a:path[last_char] == go#util#PathSep()
let withSep = a:path
let noSep = strpart(a:path, 0, last_char)
else
let withSep = a:path . go#util#PathSep()
let noSep = a:path
endif
let hasA = index(go_paths, withSep) != -1
let hasB = index(go_paths, noSep) != -1
return hasA || hasB
endfunction
" BinPath returns the binary path of installed go tools.
1 0.000002 function! go#path#BinPath() abort
let l:bin_path = go#config#BinPath()
if l:bin_path isnot ""
return l:bin_path
endif
" check if our global custom path is set, if not check if GOBIN is set so
" we can use it, otherwise use default GOPATH
let l:bin_path = go#util#env('gobin')
if l:bin_path isnot ''
let l:bin_path = $GOBIN
else
let l:go_paths = split(go#path#Default(), go#util#PathListSep())
if len(l:go_paths) == 0
return '' "nothing found
endif
let l:bin_path = expand(l:go_paths[0] . '/bin/')
endif
return l:bin_path
endfunction
" CheckBinPath checks whether the given binary exists or not and returns the
" path of the binary, respecting the go_bin_path and go_search_bin_path_first
" settings. It returns an empty string if the binary doesn't exist.
1 0.000001 function! go#path#CheckBinPath(binpath) abort
" remove whitespaces if user applied something like 'goimports '
let binpath = substitute(a:binpath, '^\s*\(.\{-}\)\s*$', '\1', '')
" save original path
let old_path = $PATH
" check if we have an appropriate bin_path
let go_bin_path = go#path#BinPath()
if !empty(go_bin_path)
" append our GOBIN and GOPATH paths and be sure they can be found there...
" let us search in our GOBIN and GOPATH paths
" respect the ordering specified by go_search_bin_path_first
if go#config#SearchBinPathFirst()
let $PATH = go_bin_path . go#util#PathListSep() . $PATH
else
let $PATH = $PATH . go#util#PathListSep() . go_bin_path
endif
endif
" if it's in PATH just return it
if executable(binpath)
if exists('*exepath')
let binpath = exepath(binpath)
endif
let $PATH = old_path
if go#util#IsUsingCygwinShell() == 1
return s:CygwinPath(binpath)
endif
return binpath
endif
" just get the basename
let basename = fnamemodify(binpath, ":t")
if !executable(basename)
call go#util#EchoError(printf("could not find '%s'. Run :GoInstallBinaries to fix it", basename))
" restore back!
let $PATH = old_path
return ""
endif
let $PATH = old_path
if go#util#IsUsingCygwinShell() == 1
return s:CygwinPath(a:binpath)
endif
return go_bin_path . go#util#PathSep() . basename
endfunction
1 0.000001 function! s:CygwinPath(path)
return substitute(a:path, '\\', '/', "g")
endfunction
" go#path#ToURI converts path to a file URI. path should be an absolute path.
" Relative paths cannot be properly converted to a URI; when path is a
" relative path, the file scheme will not be prepended.
1 0.000001 function! go#path#ToURI(path)
let l:absolute = !go#util#IsWin() && a:path[0] is# '/'
let l:prefix = ''
let l:path = a:path
if go#util#IsWin() && l:path[1:2] is# ':\'
let l:absolute = 1
let l:prefix = '/' . l:path[0:1]
let l:path = l:path[2:]
endif
return substitute(
\ (l:absolute ? 'file://' : '') . l:prefix . go#uri#EncodePath(l:path),
\ '\\',
\ '/',
\ 'g',
\)
endfunction
1 0.000001 function! go#path#FromURI(uri) abort
let l:i = len('file://')
let l:encoded_path = a:uri[: l:i - 1] is# 'file://' ? a:uri[l:i :] : a:uri
let l:path = go#uri#Decode(l:encoded_path)
" If the path is like /C:/foo/bar, it should be C:\foo\bar instead.
if go#util#IsWin() && l:path =~# '^/[a-zA-Z]:'
let l:path = substitute(l:path[1:], '/', '\\', 'g')
endif
return l:path
endfunction
" restore Vi compatibility settings
1 0.000003 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/ftplugin/go/mappings.vim
Sourced 1 time
Total time: 0.000499
Self time: 0.000499
count total (s) self (s)
" go_jump_to_error defines whether we should pass the bang attribute to the
" command or not. This is only used for mappings, because the user can't pass
" the bang attribute to the plug mappings below. So instead of hardcoding it
" as 0 (no '!' attribute) or 1 (with '!' attribute) we pass the user setting,
" which by default is enabled. For commands the user has the ability to pass
" the '!', such as :GoBuild or :GoBuild!
1 0.000006 if !exists("g:go_jump_to_error")
1 0.000003 let g:go_jump_to_error = 1
1 0.000001 endif
" Some handy plug mappings
1 0.000014 nnoremap <silent> <Plug>(go-run) :<C-u>call go#cmd#Run(!g:go_jump_to_error)<CR>
1 0.000002 if has("nvim") || has("terminal")
1 0.000007 nnoremap <silent> <Plug>(go-run-vertical) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'vsplit', [])<CR>
1 0.000005 nnoremap <silent> <Plug>(go-run-split) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'split', [])<CR>
1 0.000005 nnoremap <silent> <Plug>(go-run-tab) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'tabe', [])<CR>
1 0.000000 endif
1 0.000003 nnoremap <silent> <Plug>(go-build) :<C-u>call go#cmd#Build(!g:go_jump_to_error)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-generate) :<C-u>call go#cmd#Generate(!g:go_jump_to_error)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-install) :<C-u>call go#cmd#Install(!g:go_jump_to_error)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-test) :<C-u>call go#test#Test(!g:go_jump_to_error, 0)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-test-func) :<C-u>call go#test#Func(!g:go_jump_to_error)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-test-compile) :<C-u>call go#test#Test(!g:go_jump_to_error, 1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-coverage) :<C-u>call go#coverage#Buffer(!g:go_jump_to_error)<CR>
1 0.000012 nnoremap <silent> <Plug>(go-coverage-clear) :<C-u>call go#coverage#Clear()<CR>
1 0.000004 nnoremap <silent> <Plug>(go-coverage-toggle) :<C-u>call go#coverage#BufferToggle(!g:go_jump_to_error)<CR>
1 0.000005 nnoremap <silent> <Plug>(go-coverage-browser) :<C-u>call go#coverage#Browser(!g:go_jump_to_error)<CR>
1 0.000004 nnoremap <silent> <Plug>(go-files) :<C-u>call go#tool#Files()<CR>
1 0.000003 nnoremap <silent> <Plug>(go-deps) :<C-u>call go#tool#Deps()<CR>
1 0.000003 nnoremap <silent> <Plug>(go-info) :<C-u>call go#tool#Info(1)<CR>
1 0.000004 nnoremap <silent> <Plug>(go-import) :<C-u>call go#import#SwitchImport(1, '', expand('<cword>'), '')<CR>
1 0.000003 nnoremap <silent> <Plug>(go-imports) :<C-u>call go#fmt#Format(1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-fmt) :<C-u>call go#fmt#Format(0)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-implements) :<C-u>call go#implements#Implements(-1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-callees) :<C-u>call go#guru#Callees(-1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-callers) :<C-u>call go#calls#Callers()<CR>
1 0.000004 nnoremap <silent> <Plug>(go-describe) :<C-u>call go#guru#Describe(-1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-callstack) :<C-u>call go#guru#Callstack(-1)<CR>
1 0.000003 xnoremap <silent> <Plug>(go-freevars) :<C-u>call go#guru#Freevars(0)<CR>
1 0.000004 nnoremap <silent> <Plug>(go-channelpeers) :<C-u>call go#guru#ChannelPeers(-1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-referrers) :<C-u>call go#referrers#Referrers(-1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-sameids) :<C-u>call go#guru#SameIds(1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-pointsto) :<C-u>call go#guru#PointsTo(-1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-whicherrs) :<C-u>call go#guru#Whicherrs(-1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-sameids-toggle) :<C-u>call go#guru#ToggleSameIds()<CR>
1 0.000003 nnoremap <silent> <Plug>(go-rename) :<C-u>call go#rename#Rename(!g:go_jump_to_error)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-decls) :<C-u>call go#decls#Decls(0, '')<CR>
1 0.000003 nnoremap <silent> <Plug>(go-decls-dir) :<C-u>call go#decls#Decls(1, '')<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def) :<C-u>call go#def#Jump('', 0)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-vertical) :<C-u>call go#def#Jump("vsplit", 0)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-split) :<C-u>call go#def#Jump("split", 0)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-tab) :<C-u>call go#def#Jump("tab", 0)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-type) :<C-u>call go#def#Jump('', 1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-type-vertical) :<C-u>call go#def#Jump("vsplit", 1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-type-split) :<C-u>call go#def#Jump("split", 1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-type-tab) :<C-u>call go#def#Jump("tab", 1)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-pop) :<C-u>call go#def#StackPop()<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-stack) :<C-u>call go#def#Stack()<CR>
1 0.000003 nnoremap <silent> <Plug>(go-def-stack-clear) :<C-u>call go#def#StackClear()<CR>
1 0.000003 nnoremap <silent> <Plug>(go-doc) :<C-u>call go#doc#Open("new", "split")<CR>
1 0.000003 nnoremap <silent> <Plug>(go-doc-tab) :<C-u>call go#doc#Open("tabnew", "tabe")<CR>
1 0.000003 nnoremap <silent> <Plug>(go-doc-vertical) :<C-u>call go#doc#Open("vnew", "vsplit")<CR>
1 0.000003 nnoremap <silent> <Plug>(go-doc-split) :<C-u>call go#doc#Open("new", "split")<CR>
1 0.000003 nnoremap <silent> <Plug>(go-doc-browser) :<C-u>call go#doc#OpenBrowser()<CR>
1 0.000003 nnoremap <silent> <Plug>(go-metalinter) :<C-u>call go#lint#Gometa(!g:go_jump_to_error, 0)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-lint) :<C-u>call go#lint#Golint(!g:go_jump_to_error)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-vet) :<C-u>call go#lint#Vet(!g:go_jump_to_error)<CR>
1 0.000003 nnoremap <silent> <Plug>(go-alternate-edit) :<C-u>call go#alternate#Switch(0, "edit")<CR>
1 0.000003 nnoremap <silent> <Plug>(go-alternate-vertical) :<C-u>call go#alternate#Switch(0, "vsplit")<CR>
1 0.000003 nnoremap <silent> <Plug>(go-alternate-split) :<C-u>call go#alternate#Switch(0, "split")<CR>
1 0.000003 nnoremap <silent> <Plug>(go-iferr) :<C-u>call go#iferr#Generate()<CR>
1 0.000004 nnoremap <silent> <Plug>(go-diagnostics) :<C-u>call go#lint#Diagnostics(!g:go_jump_to_error)<CR>
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/ftplugin/go/snippets.vim
Sourced 1 time
Total time: 0.000171
Self time: 0.000161
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000004 let s:cpo_save = &cpo
1 0.000005 set cpo&vim
1 0.000002 if exists("g:go_loaded_gosnippets")
finish
1 0.000000 endif
1 0.000001 let g:go_loaded_gosnippets = 1
1 0.000002 function! s:GoUltiSnips() abort
if get(g:, 'did_plugin_ultisnips') isnot 1
return
endif
if !exists("g:UltiSnipsSnippetDirectories")
let g:UltiSnipsSnippetDirectories = ["gosnippets/UltiSnips"]
else
let g:UltiSnipsSnippetDirectories += ["gosnippets/UltiSnips"]
endif
endfunction
1 0.000001 function! s:GoNeosnippet() abort
if get(g:, 'loaded_neosnippet') isnot 1
return
endif
let g:neosnippet#enable_snipmate_compatibility = 1
let l:gosnippets_dir = globpath(&rtp, 'gosnippets/snippets')
if type(g:neosnippet#snippets_directory) == type([])
let g:neosnippet#snippets_directory += [l:gosnippets_dir]
elseif type(g:neosnippet#snippets_directory) == type("")
if strlen(g:neosnippet#snippets_directory) > 0
let g:neosnippet#snippets_directory = g:neosnippet#snippets_directory . "," . l:gosnippets_dir
else
let g:neosnippet#snippets_directory = l:gosnippets_dir
endif
endif
endfunction
1 0.000001 function! s:GoMinisnip() abort
if get(g:, 'loaded_minisnip') isnot 1
return
endif
if exists('g:minisnip_dir')
let g:minisnip_dir .= go#util#PathListSep() . globpath(&rtp, 'gosnippets/minisnip')
else
let g:minisnip_dir = globpath(&rtp, 'gosnippets/minisnip')
endif
endfunction
1 0.000016 0.000006 let s:engine = go#config#SnippetEngine()
1 0.000001 if s:engine is? 'ultisnips'
call s:GoUltiSnips()
1 0.000001 elseif s:engine is? 'neosnippet'
call s:GoNeosnippet()
1 0.000001 elseif s:engine is? 'minisnip'
call s:GoMinisnip()
1 0.000000 endif
" restore Vi compatibility settings
1 0.000002 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/ftplugin/go/tagbar.vim
Sourced 1 time
Total time: 0.000755
Self time: 0.000755
count total (s) self (s)
" Check if tagbar is installed under plugins or is directly under rtp
" this covers pathogen + Vundle/Bundle
"
" Also make sure the ctags command exists
"
1 0.000263 if !executable('ctags')
finish
1 0.000461 elseif globpath(&rtp, 'plugin/tagbar.vim') == ""
1 0.000001 finish
endif
" don't spam the user when Vim is started in Vi compatibility mode
let s:cpo_save = &cpo
set cpo&vim
if !exists("g:go_gotags_bin")
let g:go_gotags_bin = "gotags"
endif
function! s:SetTagbar()
let bin_path = go#path#CheckBinPath(g:go_gotags_bin)
if empty(bin_path)
return
endif
if !exists("g:tagbar_type_go")
let g:tagbar_type_go = {
\ 'ctagstype' : 'go',
\ 'kinds' : [
\ 'p:package',
\ 'i:imports',
\ 'c:constants',
\ 'v:variables',
\ 't:types',
\ 'n:interfaces',
\ 'w:fields',
\ 'e:embedded',
\ 'm:methods',
\ 'r:constructor',
\ 'f:functions'
\ ],
\ 'sro' : '.',
\ 'kind2scope' : {
\ 't' : 'ctype',
\ 'n' : 'ntype'
\ },
\ 'scope2kind' : {
\ 'ctype' : 't',
\ 'ntype' : 'n'
\ },
\ 'ctagsbin' : bin_path,
\ 'ctagsargs' : '-sort -silent'
\ }
endif
endfunction
call s:SetTagbar()
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /opt/homebrew/Cellar/neovim/0.5.1_1/share/nvim/runtime/ftplugin/go.vim
Sourced 1 time
Total time: 0.000246
Self time: 0.000246
count total (s) self (s)
" Vim filetype plugin file
" Language: Go
" Maintainer: David Barnett (https://github.com/google/vim-ft-go)
" Last Change: 2014 Aug 16
1 0.000002 if exists('b:did_ftplugin')
1 0.000000 finish
endif
let b:did_ftplugin = 1
setlocal formatoptions-=t
setlocal comments=s1:/*,mb:*,ex:*/,://
setlocal commentstring=//\ %s
let b:undo_ftplugin = 'setl fo< com< cms<'
" vim: sw=2 sts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/indent/go.vim
Sourced 2 times
Total time: 0.000213
Self time: 0.000213
count total (s) self (s)
" Copyright 2011 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" indent/go.vim: Vim indent file for Go.
"
" TODO:
" - function invocations split across lines
" - general line splits (line ends in an operator)
2 0.000004 if exists("b:did_indent")
1 0.000001 finish
1 0.000000 endif
1 0.000001 let b:did_indent = 1
" C indentation is too far off useful, mainly due to Go's := operator.
" Let's just define our own.
1 0.000014 setlocal nolisp
1 0.000001 setlocal autoindent
1 0.000003 setlocal indentexpr=GoIndent(v:lnum)
1 0.000003 setlocal indentkeys+=<:>,0=},0=)
1 0.000001 if exists("*GoIndent")
finish
1 0.000000 endif
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000002 let s:cpo_save = &cpo
1 0.000002 set cpo&vim
1 0.000001 function! GoIndent(lnum) abort
let prevlnum = prevnonblank(a:lnum-1)
if prevlnum == 0
" top of file
return 0
endif
" grab the previous and current line, stripping comments.
let prevl = substitute(getline(prevlnum), '//.*$', '', '')
let thisl = substitute(getline(a:lnum), '//.*$', '', '')
let previ = indent(prevlnum)
let ind = previ
for synid in synstack(a:lnum, 1)
if synIDattr(synid, 'name') == 'goRawString'
if prevl =~ '\%(\%(:\?=\)\|(\|,\)\s*`[^`]*$'
" previous line started a multi-line raw string
return 0
endif
" return -1 to keep the current indent.
return -1
endif
endfor
if prevl =~ '[({]\s*$'
" previous line opened a block
let ind += shiftwidth()
endif
if prevl =~# '^\s*\(case .*\|default\):$'
" previous line is part of a switch statement
let ind += shiftwidth()
endif
" TODO: handle if the previous line is a label.
if thisl =~ '^\s*[)}]'
" this line closed a block
let ind -= shiftwidth()
endif
" Colons are tricky.
" We want to outdent if it's part of a switch ("case foo:" or "default:").
" We ignore trying to deal with jump labels because (a) they're rare, and
" (b) they're hard to disambiguate from a composite literal key.
if thisl =~# '^\s*\(case .*\|default\):$'
let ind -= shiftwidth()
endif
return ind
endfunction
" restore Vi compatibility settings
1 0.000002 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /opt/homebrew/Cellar/neovim/0.5.1_1/share/nvim/runtime/indent/go.vim
Sourced 1 time
Total time: 0.000145
Self time: 0.000145
count total (s) self (s)
" Vim indent file
" Language: Go
" Maintainer: David Barnett (https://github.com/google/vim-ft-go)
" Last Change: 2017 Jun 13
"
" TODO:
" - function invocations split across lines
" - general line splits (line ends in an operator)
1 0.000002 if exists('b:did_indent')
1 0.000000 finish
endif
let b:did_indent = 1
" C indentation is too far off useful, mainly due to Go's := operator.
" Let's just define our own.
setlocal nolisp
setlocal autoindent
setlocal indentexpr=GoIndent(v:lnum)
setlocal indentkeys+=<:>,0=},0=)
if exists('*GoIndent')
finish
endif
function! GoIndent(lnum)
let l:prevlnum = prevnonblank(a:lnum-1)
if l:prevlnum == 0
" top of file
return 0
endif
" grab the previous and current line, stripping comments.
let l:prevl = substitute(getline(l:prevlnum), '//.*$', '', '')
let l:thisl = substitute(getline(a:lnum), '//.*$', '', '')
let l:previ = indent(l:prevlnum)
let l:ind = l:previ
if l:prevl =~ '[({]\s*$'
" previous line opened a block
let l:ind += shiftwidth()
endif
if l:prevl =~# '^\s*\(case .*\|default\):$'
" previous line is part of a switch statement
let l:ind += shiftwidth()
endif
" TODO: handle if the previous line is a label.
if l:thisl =~ '^\s*[)}]'
" this line closed a block
let l:ind -= shiftwidth()
endif
" Colons are tricky.
" We want to outdent if it's part of a switch ("case foo:" or "default:").
" We ignore trying to deal with jump labels because (a) they're rare, and
" (b) they're hard to disambiguate from a composite literal key.
if l:thisl =~# '^\s*\(case .*\|default\):$'
let l:ind -= shiftwidth()
endif
return l:ind
endfunction
" vim: sw=2 sts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/syntax/go.vim
Sourced 2 times
Total time: 0.001445
Self time: 0.001282
count total (s) self (s)
" Copyright 2009 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" go.vim: Vim syntax file for Go.
" Quit when a (custom) syntax file was already loaded
2 0.000003 if exists("b:current_syntax")
1 0.000001 finish
1 0.000000 endif
1 0.000001 syn case match
1 0.000017 syn keyword goPackage package
1 0.000004 syn keyword goImport import contained
1 0.000004 syn keyword goVar var contained
1 0.000004 syn keyword goConst const contained
1 0.000004 hi def link goPackage Statement
1 0.000003 hi def link goImport Statement
1 0.000003 hi def link goVar Keyword
1 0.000003 hi def link goConst Keyword
1 0.000006 hi def link goDeclaration Keyword
" Keywords within functions
1 0.000005 syn keyword goStatement defer go goto return break continue fallthrough
1 0.000004 syn keyword goConditional if else switch select
1 0.000004 syn keyword goLabel case default
1 0.000004 syn keyword goRepeat for range
1 0.000003 hi def link goStatement Statement
1 0.000003 hi def link goConditional Conditional
1 0.000003 hi def link goLabel Label
1 0.000003 hi def link goRepeat Repeat
" Predefined types
1 0.000004 syn keyword goType chan map bool string error
1 0.000005 syn keyword goSignedInts int int8 int16 int32 int64 rune
1 0.000004 syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr
1 0.000004 syn keyword goFloats float32 float64
1 0.000004 syn keyword goComplexes complex64 complex128
1 0.000003 hi def link goType Type
1 0.000003 hi def link goSignedInts Type
1 0.000003 hi def link goUnsignedInts Type
1 0.000003 hi def link goFloats Type
1 0.000003 hi def link goComplexes Type
" Predefined functions and values
1 0.000007 syn keyword goBuiltins append cap close complex copy delete imag len
1 0.000003 syn keyword goBuiltins make new panic print println real recover
1 0.000004 syn keyword goBoolean true false
1 0.000007 syn keyword goPredefinedIdentifiers nil iota
1 0.000005 hi def link goBuiltins Identifier
1 0.000003 hi def link goBoolean Boolean
1 0.000001 hi def link goPredefinedIdentifiers goBoolean
" Comments; their contents
1 0.000004 syn keyword goTodo contained TODO FIXME XXX BUG
1 0.000002 syn cluster goCommentGroup contains=goTodo
1 0.000011 syn region goComment start="//" end="$" contains=goGenerate,@goCommentGroup,@Spell
1 0.000018 0.000008 if go#config#FoldEnable('comment')
syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell fold
syn match goComment "\v(^\s*//.*\n)+" contains=goGenerate,@goCommentGroup,@Spell fold
1 0.000000 else
1 0.000002 syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell
1 0.000000 endif
1 0.000003 hi def link goComment Comment
1 0.000003 hi def link goTodo Todo
1 0.000006 0.000004 if go#config#HighlightGenerateTags()
syn match goGenerateVariables contained /\%(\$GOARCH\|\$GOOS\|\$GOFILE\|\$GOLINE\|\$GOPACKAGE\|\$DOLLAR\)\>/
syn region goGenerate start="^\s*//go:generate" end="$" contains=goGenerateVariables
hi def link goGenerate PreProc
hi def link goGenerateVariables Special
1 0.000000 endif
" Go escapes
1 0.000005 syn match goEscapeOctal display contained "\\[0-7]\{3}"
1 0.000005 syn match goEscapeC display contained +\\[abfnrtv\\'"]+
1 0.000004 syn match goEscapeX display contained "\\x\x\{2}"
1 0.000004 syn match goEscapeU display contained "\\u\x\{4}"
1 0.000004 syn match goEscapeBigU display contained "\\U\x\{8}"
1 0.000005 syn match goEscapeError display contained +\\[^0-7xuUabfnrtv\\'"]+
1 0.000004 hi def link goEscapeOctal goSpecialString
1 0.000001 hi def link goEscapeC goSpecialString
1 0.000001 hi def link goEscapeX goSpecialString
1 0.000001 hi def link goEscapeU goSpecialString
1 0.000001 hi def link goEscapeBigU goSpecialString
1 0.000003 hi def link goSpecialString Special
1 0.000003 hi def link goEscapeError Error
" Strings and their contents
1 0.000004 syn cluster goStringGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU,goEscapeError
1 0.000006 0.000004 if go#config#HighlightStringSpellcheck()
1 0.000007 syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup,@Spell
1 0.000005 syn region goRawString start=+`+ end=+`+ contains=@Spell
else
syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup
syn region goRawString start=+`+ end=+`+
1 0.000000 endif
1 0.000007 syn match goImportString /^\%(\s\+\|import \)\(\h\w* \)\?\zs"[^"]\+"$/ contained containedin=goImport
1 0.000005 0.000004 if go#config#HighlightFormatStrings()
" [n] notation is valid for specifying explicit argument indexes
" 1. Match a literal % not preceded by a %.
" 2. Match any number of -, #, 0, space, or +
" 3. Match * or [n]* or any number or nothing before a .
" 4. Match * or [n]* or any number or nothing after a .
" 5. Match [n] or nothing before a verb
" 6. Match a formatting verb
1 0.000011 syn match goFormatSpecifier /\
\%([^%]\%(%%\)*\)\
\@<=%[-#0 +]*\
\%(\%(\%(\[\d\+\]\)\=\*\)\|\d\+\)\=\
\%(\.\%(\%(\%(\[\d\+\]\)\=\*\)\|\d\+\)\=\)\=\
\%(\[\d\+\]\)\=[vTtbcdoqxXUeEfFgGspw]/ contained containedin=goString,goRawString
1 0.000001 hi def link goFormatSpecifier goSpecialString
1 0.000000 endif
1 0.000003 hi def link goImportString String
1 0.000003 hi def link goString String
1 0.000003 hi def link goRawString String
" Characters; their contents
1 0.000003 syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU
1 0.000006 syn region goCharacter start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=@goCharacterGroup
1 0.000003 hi def link goCharacter Character
" Regions
1 0.000004 syn region goParen start='(' end=')' transparent
1 0.000009 0.000003 if go#config#FoldEnable('block')
1 0.000004 syn region goBlock start="{" end="}" transparent fold
else
syn region goBlock start="{" end="}" transparent
1 0.000000 endif
" import
1 0.000008 0.000003 if go#config#FoldEnable('import')
1 0.000004 syn region goImport start='import (' end=')' transparent fold contains=goImport,goImportString,goComment
else
syn region goImport start='import (' end=')' transparent contains=goImport,goImportString,goComment
1 0.000000 endif
" var, const
1 0.000007 0.000002 if go#config#FoldEnable('varconst')
1 0.000031 syn region goVar start='var (' end='^\s*)$' transparent fold
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goParamName,goParamType,goSimpleParams,goPointerOperator
1 0.000007 syn region goConst start='const (' end='^\s*)$' transparent fold
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goParamName,goParamType,goSimpleParams,goPointerOperator
else
syn region goVar start='var (' end='^\s*)$' transparent
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goParamName,goParamType,goSimpleParams,goPointerOperator
syn region goConst start='const (' end='^\s*)$' transparent
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goParamName,goParamType,goSimpleParams,goPointerOperator
1 0.000000 endif
" Single-line var, const, and import.
1 0.000007 syn match goSingleDecl /\%(import\|var\|const\) [^(]\@=/ contains=goImport,goVar,goConst
" Integers
1 0.000007 syn match goDecimalInt "\<-\=\(0\|[1-9]_\?\(\d\|\d\+_\?\d\+\)*\)\%([Ee][-+]\=\d\+\)\=\>"
1 0.000008 syn match goDecimalError "\<-\=\(_\(\d\+_*\)\+\|\([1-9]\d*_*\)\+__\(\d\+_*\)\+\|\([1-9]\d*_*\)\+_\+\)\%([Ee][-+]\=\d\+\)\=\>"
1 0.000005 syn match goHexadecimalInt "\<-\=0[xX]_\?\(\x\+_\?\)\+\>"
1 0.000006 syn match goHexadecimalError "\<-\=0[xX]_\?\(\x\+_\?\)*\(\([^ \t0-9A-Fa-f_)]\|__\)\S*\|_\)\>"
1 0.000005 syn match goOctalInt "\<-\=0[oO]\?_\?\(\o\+_\?\)\+\>"
1 0.000008 syn match goOctalError "\<-\=0[0-7oO_]*\(\([^ \t0-7oOxX_/)\]\}\:;]\|[oO]\{2,\}\|__\)\S*\|_\|[oOxX]\)\>"
1 0.000005 syn match goBinaryInt "\<-\=0[bB]_\?\([01]\+_\?\)\+\>"
1 0.000006 syn match goBinaryError "\<-\=0[bB]_\?[01_]*\([^ \t01_)]\S*\|__\S*\|_\)\>"
1 0.000004 hi def link goDecimalInt Integer
1 0.000003 hi def link goDecimalError Error
1 0.000001 hi def link goHexadecimalInt Integer
1 0.000003 hi def link goHexadecimalError Error
1 0.000001 hi def link goOctalInt Integer
1 0.000003 hi def link goOctalError Error
1 0.000001 hi def link goBinaryInt Integer
1 0.000003 hi def link goBinaryError Error
1 0.000003 hi def link Integer Number
" Floating point
1 0.000005 syn match goFloat "\<-\=\d\+\.\d*\%([Ee][-+]\=\d\+\)\=\>"
1 0.000002 syn match goFloat "\<-\=\.\d\+\%([Ee][-+]\=\d\+\)\=\>"
1 0.000003 hi def link goFloat Float
" Imaginary literals
1 0.000004 syn match goImaginary "\<-\=\d\+i\>"
1 0.000002 syn match goImaginary "\<-\=\d\+[Ee][-+]\=\d\+i\>"
1 0.000005 syn match goImaginaryFloat "\<-\=\d\+\.\d*\%([Ee][-+]\=\d\+\)\=i\>"
1 0.000002 syn match goImaginaryFloat "\<-\=\.\d\+\%([Ee][-+]\=\d\+\)\=i\>"
1 0.000003 hi def link goImaginary Number
1 0.000003 hi def link goImaginaryFloat Float
" Spaces after "[]"
1 0.000006 0.000004 if go#config#HighlightArrayWhitespaceError()
syn match goSpaceError display "\%(\[\]\)\@<=\s\+"
1 0.000000 endif
" Spacing errors around the 'chan' keyword
1 0.000005 0.000004 if go#config#HighlightChanWhitespaceError()
" receive-only annotation on chan type
"
" \(\<chan\>\)\@<!<- (only pick arrow when it doesn't come after a chan)
" this prevents picking up 'chan<- chan<-' but not '<- chan'
syn match goSpaceError display "\%(\%(\<chan\>\)\@<!<-\)\@<=\s\+\%(\<chan\>\)\@="
" send-only annotation on chan type
"
" \(<-\)\@<!\<chan\> (only pick chan when it doesn't come after an arrow)
" this prevents picking up '<-chan <-chan' but not 'chan <-'
syn match goSpaceError display "\%(\%(<-\)\@<!\<chan\>\)\@<=\s\+\%(<-\)\@="
" value-ignoring receives in a few contexts
syn match goSpaceError display "\%(\%(^\|[={(,;]\)\s*<-\)\@<=\s\+"
1 0.000000 endif
" Extra types commonly seen
1 0.000004 0.000003 if go#config#HighlightExtraTypes()
syn match goExtraType /\<bytes\.\%(Buffer\)\>/
syn match goExtraType /\<context\.\%(Context\)\>/
syn match goExtraType /\<io\.\%(Reader\|ReadSeeker\|ReadWriter\|ReadCloser\|ReadWriteCloser\|Writer\|WriteCloser\|Seeker\)\>/
syn match goExtraType /\<reflect\.\%(Kind\|Type\|Value\)\>/
syn match goExtraType /\<unsafe\.Pointer\>/
1 0.000000 endif
" Space-tab error
1 0.000017 0.000015 if go#config#HighlightSpaceTabError()
syn match goSpaceError display " \+\t"me=e-1
1 0.000000 endif
" Trailing white space error
1 0.000005 0.000004 if go#config#HighlightTrailingWhitespaceError()
syn match goSpaceError display excludenl "\s\+$"
1 0.000000 endif
1 0.000006 hi def link goExtraType Type
1 0.000006 hi def link goSpaceError Error
" included from: https://github.com/athom/more-colorful.vim/blob/master/after/syntax/go.vim
"
" Comments; their contents
1 0.000001 syn keyword goTodo contained NOTE
1 0.000003 hi def link goTodo Todo
1 0.000005 syn match goVarArgs /\.\.\./
" Operators;
1 0.000004 0.000003 if go#config#HighlightOperators()
" match single-char operators: - + % < > ! & | ^ * =
" and corresponding two-char operators: -= += %= <= >= != &= |= ^= *= ==
syn match goOperator /[-+%<>!&|^*=]=\?/
" match / and /=
syn match goOperator /\/\%(=\|\ze[^/*]\)/
" match two-char operators: << >> &^
" and corresponding three-char operators: <<= >>= &^=
syn match goOperator /\%(<<\|>>\|&^\)=\?/
" match remaining two-char operators: := && || <- ++ --
syn match goOperator /:=\|||\|<-\|++\|--/
" match ...
hi def link goPointerOperator goOperator
hi def link goVarArgs goOperator
1 0.000000 endif
1 0.000006 hi def link goOperator Operator
" Functions;
1 0.000010 0.000007 if go#config#HighlightFunctions() || go#config#HighlightFunctionParameters()
syn match goDeclaration /\<func\>/ nextgroup=goReceiver,goFunction,goSimpleParams skipwhite skipnl
syn match goReceiverDecl /(\s*\zs\%(\%(\w\+\s\+\)\?\*\?\w\+\)\ze\s*)/ contained contains=goReceiverVar,goReceiverType,goPointerOperator
syn match goReceiverVar /\w\+\ze\s\+\%(\w\|\*\)/ nextgroup=goPointerOperator,goReceiverType skipwhite skipnl contained
syn match goPointerOperator /\*/ nextgroup=goReceiverType contained skipwhite skipnl
syn match goFunction /\w\+/ nextgroup=goSimpleParams contained skipwhite skipnl
syn match goReceiverType /\w\+\ze\s*)/ contained
if go#config#HighlightFunctionParameters()
syn match goSimpleParams /(\%(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goParamName,goType nextgroup=goFunctionReturn skipwhite skipnl
syn match goFunctionReturn /(\%(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goParamName,goType skipwhite skipnl
syn match goParamName /\w\+\%(\s*,\s*\w\+\)*\ze\s\+\%(\w\|\.\|\*\|\[\)/ contained nextgroup=goParamType skipwhite skipnl
syn match goParamType /\%([^,)]\|\_s\)\+,\?/ contained nextgroup=goParamName skipwhite skipnl
\ contains=goVarArgs,goType,goSignedInts,goUnsignedInts,goFloats,goComplexes,goDeclType,goBlock
hi def link goReceiverVar goParamName
hi def link goParamName Identifier
endif
syn match goReceiver /(\s*\%(\w\+\s\+\)\?\*\?\s*\w\+\s*)\ze\s*\w/ contained nextgroup=goFunction contains=goReceiverDecl skipwhite skipnl
1 0.000000 else
1 0.000002 syn keyword goDeclaration func
1 0.000000 endif
1 0.000003 hi def link goFunction Function
" Function calls;
1 0.000005 0.000003 if go#config#HighlightFunctionCalls()
syn match goFunctionCall /\w\+\ze(/ contains=goBuiltins,goDeclaration
1 0.000000 endif
1 0.000006 hi def link goFunctionCall Type
" Fields;
1 0.000004 0.000003 if go#config#HighlightFields()
" 1. Match a sequence of word characters coming after a '.'
" 2. Require the following but dont match it: ( \@= see :h E59)
" - The symbols: / - + * % OR
" - The symbols: [] {} <> ) OR
" - The symbols: \n \r space OR
" - The symbols: , : .
" 3. Have the start of highlight (hs) be the start of matched
" pattern (s) offsetted one to the right (+1) (see :h E401)
syn match goField /\.\w\+\
\%(\%([\/\-\+*%]\)\|\
\%([\[\]{}<\>\)]\)\|\
\%([\!=\^|&]\)\|\
\%([\n\r\ ]\)\|\
\%([,\:.]\)\)\@=/hs=s+1
1 0.000000 endif
1 0.000006 hi def link goField Identifier
" Structs & Interfaces;
1 0.000004 0.000003 if go#config#HighlightTypes()
syn match goTypeConstructor /\<\w\+{\@=/
syn match goTypeDecl /\<type\>/ nextgroup=goTypeName skipwhite skipnl
syn match goTypeName /\w\+/ contained nextgroup=goDeclType skipwhite skipnl
syn match goDeclType /\<\%(interface\|struct\)\>/ skipwhite skipnl
hi def link goReceiverType Type
1 0.000000 else
1 0.000003 syn keyword goDeclType struct interface
1 0.000002 syn keyword goDeclaration type
1 0.000000 endif
1 0.000006 hi def link goTypeConstructor Type
1 0.000003 hi def link goTypeName Type
1 0.000006 hi def link goTypeDecl Keyword
1 0.000005 hi def link goDeclType Keyword
" Variable Assignments
1 0.000005 0.000004 if go#config#HighlightVariableAssignments()
syn match goVarAssign /\v[_.[:alnum:]]+(,\s*[_.[:alnum:]]+)*\ze(\s*([-^+|^\/%&]|\*|\<\<|\>\>|\&\^)?\=[^=])/
hi def link goVarAssign Special
1 0.000000 endif
" Variable Declarations
1 0.000005 0.000004 if go#config#HighlightVariableDeclarations()
syn match goVarDefs /\v\w+(,\s*\w+)*\ze(\s*:\=)/
hi def link goVarDefs Special
1 0.000000 endif
" Build Constraints
1 0.000005 0.000003 if go#config#HighlightBuildConstraints()
syn match goBuildKeyword display contained "+build\|go:build"
" Highlight the known values of GOOS, GOARCH, and other +build options.
syn keyword goBuildDirectives contained
\ android darwin dragonfly freebsd linux nacl netbsd openbsd plan9
\ solaris windows 386 amd64 amd64p32 arm armbe arm64 arm64be ppc64
\ ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc
\ s390 s390x sparc sparc64 cgo ignore race
" Other words in the build directive are build tags not listed above, so
" avoid highlighting them as comments by using a matchgroup just for the
" start of the comment.
" The rs=s+2 option lets the \s*+build portion be part of the inner region
" instead of the matchgroup so it will be highlighted as a goBuildKeyword.
syn region goBuildComment matchgroup=goBuildCommentStart
\ start="//\(\s*+build\s\|go:build\)"rs=s+2 end="$"
\ contains=goBuildKeyword,goBuildDirectives
hi def link goBuildCommentStart Comment
hi def link goBuildDirectives Type
hi def link goBuildKeyword PreProc
1 0.000000 endif
1 0.000013 0.000006 if go#config#HighlightBuildConstraints() || go#config#FoldEnable('package_comment')
" One or more line comments that are followed immediately by a "package"
" declaration are treated like package documentation, so these must be
" matched as comments to avoid looking like working build constraints.
" The he, me, and re options let the "package" itself be highlighted by
" the usual rules.
1 0.000018 0.000013 exe 'syn region goPackageComment start=/\v(\/\/.*\n)+\s*package/'
\ . ' end=/\v\n\s*package/he=e-7,me=e-7,re=e-7'
\ . ' contains=@goCommentGroup,@Spell'
\ . (go#config#FoldEnable('package_comment') ? ' fold' : '')
1 0.000015 0.000010 exe 'syn region goPackageComment start=/\v^\s*\/\*.*\n(.*\n)*\s*\*\/\npackage/'
\ . ' end=/\v\*\/\n\s*package/he=e-7,me=e-7,re=e-7'
\ . ' contains=@goCommentGroup,@Spell'
\ . (go#config#FoldEnable('package_comment') ? ' fold' : '')
1 0.000003 hi def link goPackageComment Comment
1 0.000000 endif
" :GoCoverage commands
1 0.000006 hi def link goCoverageNormalText Comment
1 0.000001 function! s:hi()
hi def link goSameId Search
hi def link goDiagnosticError SpellBad
hi def link goDiagnosticWarning SpellRare
" TODO(bc): is it appropriate to define text properties in a syntax file?
" The highlight groups need to be defined before the text properties types
" are added, and when users have syntax enabled in their vimrc after
" filetype plugin on, the highlight groups won't be defined when
" ftplugin/go.vim is executed when the first go file is opened.
" See https://github.com/fatih/vim-go/issues/2658.
if has('textprop')
if empty(prop_type_get('goSameId'))
call prop_type_add('goSameId', {'highlight': 'goSameId'})
endif
if empty(prop_type_get('goDiagnosticError'))
call prop_type_add('goDiagnosticError', {'highlight': 'goDiagnosticError'})
endif
if empty(prop_type_get('goDiagnosticWarning'))
call prop_type_add('goDiagnosticWarning', {'highlight': 'goDiagnosticWarning'})
endif
endif
hi def link goDeclsFzfKeyword Keyword
hi def link goDeclsFzfFunction Function
hi def link goDeclsFzfSpecialComment SpecialComment
hi def link goDeclsFzfComment Comment
" :GoCoverage commands
hi def goCoverageCovered ctermfg=green guifg=#A6E22E
hi def goCoverageUncover ctermfg=red guifg=#F92672
" :GoDebug commands
if go#config#HighlightDebug()
hi def GoDebugBreakpoint term=standout ctermbg=117 ctermfg=0 guibg=#BAD4F5 guifg=Black
hi def GoDebugCurrent term=reverse ctermbg=12 ctermfg=7 guibg=DarkBlue guifg=White
endif
endfunction
1 0.000002 augroup vim-go-hi
1 0.000032 autocmd!
1 0.000002 autocmd ColorScheme * call s:hi()
1 0.000000 augroup end
1 0.000101 0.000002 call s:hi()
" Search backwards for a global declaration to start processing the syntax.
"syn sync match goSync grouphere NONE /^\(const\|var\|type\|func\)\>/
" There's a bug in the implementation of grouphere. For now, use the
" following as a more expensive/less precise workaround.
1 0.000001 syn sync minlines=500
1 0.000001 let b:current_syntax = "go"
" vim: sw=2 ts=2 et
SCRIPT /opt/homebrew/Cellar/neovim/0.5.1_1/share/nvim/runtime/syntax/go.vim
Sourced 1 time
Total time: 0.000270
Self time: 0.000270
count total (s) self (s)
" Vim syntax file
" Language: Go
" Maintainer: David Barnett (https://github.com/google/vim-ft-go)
" Last Change: 2014 Aug 16
" Options:
" There are some options for customizing the highlighting; the recommended
" settings are the default values, but you can write:
" let OPTION_NAME = 0
" in your ~/.vimrc file to disable particular options. You can also write:
" let OPTION_NAME = 1
" to enable particular options. At present, all options default to on.
"
" - g:go_highlight_array_whitespace_error
" Highlights white space after "[]".
" - g:go_highlight_chan_whitespace_error
" Highlights white space around the communications operator that don't
" follow the standard style.
" - g:go_highlight_extra_types
" Highlights commonly used library types (io.Reader, etc.).
" - g:go_highlight_space_tab_error
" Highlights instances of tabs following spaces.
" - g:go_highlight_trailing_whitespace_error
" Highlights trailing white space.
" Quit when a (custom) syntax file was already loaded
1 0.000002 if exists('b:current_syntax')
1 0.000001 finish
endif
if !exists('g:go_highlight_array_whitespace_error')
let g:go_highlight_array_whitespace_error = 1
endif
if !exists('g:go_highlight_chan_whitespace_error')
let g:go_highlight_chan_whitespace_error = 1
endif
if !exists('g:go_highlight_extra_types')
let g:go_highlight_extra_types = 1
endif
if !exists('g:go_highlight_space_tab_error')
let g:go_highlight_space_tab_error = 1
endif
if !exists('g:go_highlight_trailing_whitespace_error')
let g:go_highlight_trailing_whitespace_error = 1
endif
syn case match
syn keyword goDirective package import
syn keyword goDeclaration var const type
syn keyword goDeclType struct interface
hi def link goDirective Statement
hi def link goDeclaration Keyword
hi def link goDeclType Keyword
" Keywords within functions
syn keyword goStatement defer go goto return break continue fallthrough
syn keyword goConditional if else switch select
syn keyword goLabel case default
syn keyword goRepeat for range
hi def link goStatement Statement
hi def link goConditional Conditional
hi def link goLabel Label
hi def link goRepeat Repeat
" Predefined types
syn keyword goType chan map bool string error
syn keyword goSignedInts int int8 int16 int32 int64 rune
syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr
syn keyword goFloats float32 float64
syn keyword goComplexes complex64 complex128
hi def link goType Type
hi def link goSignedInts Type
hi def link goUnsignedInts Type
hi def link goFloats Type
hi def link goComplexes Type
" Treat func specially: it's a declaration at the start of a line, but a type
" elsewhere. Order matters here.
syn match goType /\<func\>/
syn match goDeclaration /^func\>/
" Predefined functions and values
syn keyword goBuiltins append cap close complex copy delete imag len
syn keyword goBuiltins make new panic print println real recover
syn keyword goConstants iota true false nil
hi def link goBuiltins Keyword
hi def link goConstants Keyword
" Comments; their contents
syn keyword goTodo contained TODO FIXME XXX BUG
syn cluster goCommentGroup contains=goTodo
syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell
syn region goComment start="//" end="$" contains=@goCommentGroup,@Spell
hi def link goComment Comment
hi def link goTodo Todo
" Go escapes
syn match goEscapeOctal display contained "\\[0-7]\{3}"
syn match goEscapeC display contained +\\[abfnrtv\\'"]+
syn match goEscapeX display contained "\\x\x\{2}"
syn match goEscapeU display contained "\\u\x\{4}"
syn match goEscapeBigU display contained "\\U\x\{8}"
syn match goEscapeError display contained +\\[^0-7xuUabfnrtv\\'"]+
hi def link goEscapeOctal goSpecialString
hi def link goEscapeC goSpecialString
hi def link goEscapeX goSpecialString
hi def link goEscapeU goSpecialString
hi def link goEscapeBigU goSpecialString
hi def link goSpecialString Special
hi def link goEscapeError Error
" Strings and their contents
syn cluster goStringGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU,goEscapeError
syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup
syn region goRawString start=+`+ end=+`+
hi def link goString String
hi def link goRawString String
" Characters; their contents
syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU
syn region goCharacter start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=@goCharacterGroup
hi def link goCharacter Character
" Regions
syn region goBlock start="{" end="}" transparent fold
syn region goParen start='(' end=')' transparent
" Integers
syn match goDecimalInt "\<\d\+\([Ee]\d\+\)\?\>"
syn match goHexadecimalInt "\<0x\x\+\>"
syn match goOctalInt "\<0\o\+\>"
syn match goOctalError "\<0\o*[89]\d*\>"
hi def link goDecimalInt Integer
hi def link goHexadecimalInt Integer
hi def link goOctalInt Integer
hi def link Integer Number
" Floating point
syn match goFloat "\<\d\+\.\d*\([Ee][-+]\d\+\)\?\>"
syn match goFloat "\<\.\d\+\([Ee][-+]\d\+\)\?\>"
syn match goFloat "\<\d\+[Ee][-+]\d\+\>"
hi def link goFloat Float
" Imaginary literals
syn match goImaginary "\<\d\+i\>"
syn match goImaginary "\<\d\+\.\d*\([Ee][-+]\d\+\)\?i\>"
syn match goImaginary "\<\.\d\+\([Ee][-+]\d\+\)\?i\>"
syn match goImaginary "\<\d\+[Ee][-+]\d\+i\>"
hi def link goImaginary Number
" Spaces after "[]"
if go_highlight_array_whitespace_error != 0
syn match goSpaceError display "\(\[\]\)\@<=\s\+"
endif
" Spacing errors around the 'chan' keyword
if go_highlight_chan_whitespace_error != 0
" receive-only annotation on chan type
syn match goSpaceError display "\(<-\)\@<=\s\+\(chan\>\)\@="
" send-only annotation on chan type
syn match goSpaceError display "\(\<chan\)\@<=\s\+\(<-\)\@="
" value-ignoring receives in a few contexts
syn match goSpaceError display "\(\(^\|[={(,;]\)\s*<-\)\@<=\s\+"
endif
" Extra types commonly seen
if go_highlight_extra_types != 0
syn match goExtraType /\<bytes\.\(Buffer\)\>/
syn match goExtraType /\<io\.\(Reader\|Writer\|ReadWriter\|ReadWriteCloser\)\>/
syn match goExtraType /\<reflect\.\(Kind\|Type\|Value\)\>/
syn match goExtraType /\<unsafe\.Pointer\>/
endif
" Space-tab error
if go_highlight_space_tab_error != 0
syn match goSpaceError display " \+\t"me=e-1
endif
" Trailing white space error
if go_highlight_trailing_whitespace_error != 0
syn match goSpaceError display excludenl "\s\+$"
endif
hi def link goExtraType Type
hi def link goSpaceError Error
" Search backwards for a global declaration to start processing the syntax.
"syn sync match goSync grouphere NONE /^\(const\|var\|type\|func\)\>/
" There's a bug in the implementation of grouphere. For now, use the
" following as a more expensive/less precise workaround.
syn sync minlines=500
let b:current_syntax = 'go'
" vim: sw=2 sts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim
Sourced 1 time
Total time: 0.000890
Self time: 0.000890
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000003 let s:cpo_save = &cpo
1 0.000003 set cpo&vim
1 0.000001 scriptencoding utf-8
1 0.000001 let s:lspfactory = {}
1 0.000001 function! s:lspfactory.get() dict abort
if empty(get(self, 'current', {})) || empty(get(self.current, 'job', {}))
let self.current = s:newlsp()
endif
return self.current
endfunction
1 0.000001 function! s:lspfactory.reset() dict abort
if has_key(self, 'current')
call remove(self, 'current')
endif
endfunction
1 0.000001 function! s:newlsp() abort
" job is the job used to talk to the backing instance of gopls.
" ready is 0 until the initialize response has been received. 1 afterwards.
" queue is messages to send after initialization
" last_request_id is id of the most recently sent request.
" buf is unprocessed/incomplete responses
" handlers is a mapping of request ids to dictionaries of functions.
" request id -> {start, requestComplete, handleResult, error}
" * start is a function that takes no arguments
" * requestComplete is a function that takes 1 argument. The parameter will be 1
" if the call was succesful.
" * handleResult takes a single argument, the result message received from gopls
" * error takes a single argument, the error message received from gopls.
" The error method is optional.
" workspaceDirectories is an array of named workspaces.
" wd is the working directory for gopls
" diagnostics is a dictionary whose keys are filenames and each value is a
" list of diagnostic messages for the file.
" diagnosticsQueue is a queue of diagnostics notifications that have been
" received, but not yet processed.
" fileVersions is a dictionary of filenames to versions.
" notificationQueue is a dictionary of filenames to functions. For a given
" filename, each notification will call the first function in the list of
" function values and remove it from the list. The functions should accept
" two arguments: an absolute path and a list of diagnotics messages for
" the file.
let l:lsp = {
\ 'job': '',
\ 'ready': 0,
\ 'queue': [],
\ 'last_request_id': 0,
\ 'buf': '',
\ 'handlers': {},
\ 'workspaceDirectories': [],
\ 'wd' : '',
\ 'diagnosticsQueue': [],
\ 'diagnostics': {},
\ 'fileVersions': {},
\ 'notificationQueue': {},
\ }
if !go#config#GoplsEnabled()
let l:lsp.sendMessage = funcref('s:noop')
return l:lsp
endif
if !go#util#has_job()
let l:oldshortmess=&shortmess
if has('nvim')
set shortmess-=F
endif
call go#util#EchoWarning('Features that rely on gopls will not work without either Vim 8.0.0087 or newer with +job or Neovim')
" Sleep one second to make sure people see the message. Otherwise it is
" often immediately overwritten by an async message.
sleep 1
let &shortmess=l:oldshortmess
return l:lsp
endif
function! l:lsp.readMessage(data) dict abort
let l:responses = []
let l:rest = a:data
while 1
" Look for the end of the HTTP headers
let l:body_start_idx = matchend(l:rest, "\r\n\r\n")
if l:body_start_idx < 0
" incomplete header
break
endif
" Parse the Content-Length header.
let l:header = l:rest[:l:body_start_idx - 4]
let l:length_match = matchlist(
\ l:header,
\ '\vContent-Length: *(\d+)'
\)
if empty(l:length_match)
" TODO(bc): shutdown gopls?
throw "invalid JSON-RPC header:\n" . l:header
endif
" get the start of the rest
let l:next_start_idx = l:body_start_idx + str2nr(l:length_match[1])
if len(l:rest) < l:next_start_idx
" incomplete response body
break
endif
call s:debug('received', l:rest[:l:next_start_idx - 1])
let l:body = l:rest[l:body_start_idx : l:next_start_idx - 1]
let l:rest = l:rest[l:next_start_idx :]
try
" add the json body to the list.
call add(l:responses, json_decode(l:body))
catch
" TODO(bc): log the message and/or show an error message.
finally
" intentionally left blank.
endtry
endwhile
return [l:rest, l:responses]
endfunction
function! l:lsp.handleMessage(ch, data) dict abort
let self.buf .= a:data
let [self.buf, l:messages] = self.readMessage(self.buf)
for l:message in l:messages
if has_key(l:message, 'method')
if has_key(l:message, 'id')
call self.handleRequest(l:message)
else
call self.handleNotification(l:message)
endif
elseif has_key(l:message, 'result') || has_key(l:message, 'error')
call self.handleResponse(l:message)
endif
endfor
endfunction
function! l:lsp.handleRequest(req) dict abort
if a:req.method == 'workspace/workspaceFolders'
let l:resp = go#lsp#message#WorkspaceFoldersResult(self.workspaceDirectories)
elseif a:req.method == 'workspace/configuration' && has_key(a:req, 'params') && has_key(a:req.params, 'items')
let l:resp = go#lsp#message#ConfigurationResult(a:req.params.items)
elseif a:req.method == 'client/registerCapability' && has_key(a:req, 'params') && has_key(a:req.params, 'registrations')
let l:resp = v:null
elseif a:req.method == 'workspace/applyEdit'
try
let l:ok = v:true
for l:change in a:req.params.edit.documentChanges
call s:applyDocumentChanges(a:req.params.edit.documentChanges)
endfor
catch
call go#util#EchoError(printf('could not apply edit: %s', v:exception))
let l:ok = v:false
endtry
let l:resp = go#lsp#message#ApplyWorkspaceEditResponse(l:ok)
else
return
endif
if get(self, 'exited', 0)
return
endif
let l:msg = self.newResponse(a:req.id, l:resp)
call self.write(l:msg)
endfunction
function! l:lsp.handleResponse(resp) dict abort
if has_key(a:resp, 'id') && has_key(self.handlers, a:resp.id)
try
let l:handler = self.handlers[a:resp.id]
let l:winid = win_getid(winnr())
" Always set the active window to the window that was active when
" the request was sent. Among other things, this makes sure that
" the correct window's location list will be populated when the
" list type is 'location' and the user has moved windows since
" sending the request.
call win_gotoid(l:handler.winid)
if has_key(a:resp, 'error')
call l:handler.requestComplete(0)
if has_key(l:handler, 'error')
call call(l:handler.error, [a:resp.error.message])
else
call go#util#EchoError(a:resp.error.message)
endif
call win_gotoid(l:winid)
return
endif
call l:handler.requestComplete(1)
let l:winidBeforeHandler = l:handler.winid
call call(l:handler.handleResult, [a:resp.result])
" change the window back to the window that was active when
" starting to handle the message _only_ if the handler didn't
" update the winid, so that handlers can set the winid if needed
" (e.g. :GoDef).
if l:handler.winid == l:winidBeforeHandler
call win_gotoid(l:winid)
endif
finally
call remove(self.handlers, a:resp.id)
endtry
endif
endfunction
function! l:lsp.handleNotification(req) dict abort
" TODO(bc): handle more notifications (e.g. window/showMessage).
if a:req.method == 'textDocument/publishDiagnostics'
call self.handleDiagnostics(a:req.params)
elseif a:req.method == 'window/showMessage'
call self.showMessage(a:req.params)
endif
endfunction
function! l:lsp.handleDiagnostics(data) dict abort
let self.diagnosticsQueue = add(self.diagnosticsQueue, a:data)
call self.updateDiagnostics()
endfunction
function! l:lsp.showMessage(data) dict abort
let l:msg = a:data.message
if a:data.type == 1
call go#util#EchoError(l:msg)
elseif a:data.type == 2
call go#util#EchoWarning(l:msg)
elseif a:data.type == 3
call go#util#EchoInfo(l:msg)
elseif a:data.type == 4
" do nothing for Log messages
endif
endfunction
" TODO(bc): process the queue asynchronously
function! l:lsp.updateDiagnostics() dict abort
let l:level = go#config#DiagnosticsLevel()
for l:data in self.diagnosticsQueue
call remove(self.diagnosticsQueue, 0)
try
let l:diagnostics = []
let l:errorMatches = []
let l:warningMatches = []
let l:fname = go#path#FromURI(l:data.uri)
" get the buffer name relative to the current directory, because
" Vim says that a buffer name can't be an absolute path.
let l:bufname = fnamemodify(l:fname, ':.')
if len(l:data.diagnostics) > 0 && (l:level > 0 || bufnr(l:bufname) == bufnr(''))
" make sure the buffer is listed and loaded before calling getbufline() on it
if !bufexists(l:bufname)
call bufadd(l:bufname)
endif
if !bufloaded(l:bufname)
call bufload(l:bufname)
endif
for l:diag in l:data.diagnostics
if l:level < l:diag.severity
continue
endif
let [l:error, l:matchpos] = s:errorFromDiagnostic(l:diag, l:bufname, l:fname)
let l:diagnostics = add(l:diagnostics, l:error)
if empty(l:matchpos)
continue
endif
if l:diag.severity == 1
let l:errorMatches = add(l:errorMatches, l:matchpos)
elseif l:diag.severity == 2
let l:warningMatches = add(l:warningMatches, l:matchpos)
endif
endfor
endif
if bufnr(l:bufname) == bufnr('')
" only apply highlighting when the diagnostics are for the current
" version.
let l:lsp = s:lspfactory.get()
let l:version = get(l:lsp.fileVersions, l:fname, 0)
" it's tempting to only highlight matches when they are for the
" current version of the buffer, but that causes problems when the
" version number has been updated and the content has not. In such a
" case, the diagnostics may not be sent for later versions.
call s:highlightMatches(l:errorMatches, l:warningMatches)
endif
let self.diagnostics[l:fname] = l:diagnostics
if has_key(self.notificationQueue, l:fname) && len(self.notificationQueue[l:fname]) > 0
call call(self.notificationQueue[l:fname][0], copy(l:diagnostics))
call remove(self.notificationQueue[l:fname], 0)
endif
catch
"call go#util#EchoError(printf('%s: %s', v:throwpoint, v:exception))
endtry
endfor
endfunction
function! l:lsp.handleInitializeResult(result) dict abort
if go#config#EchoCommandInfo()
call go#util#EchoProgress("initialized gopls")
endif
let status = {
\ 'desc': '',
\ 'type': 'gopls',
\ 'state': 'initialized',
\ }
call go#statusline#Update(self.wd, status)
let self.ready = 1
let l:msg = self.newMessage(go#lsp#message#Initialized())
call self.write(l:msg)
" send messages queued while waiting for ready.
for l:item in self.queue
call self.sendMessage(l:item.data, l:item.handler)
endfor
" reset the queue
let self.queue = []
endfunction
function! l:lsp.sendMessage(data, handler) dict abort
if !self.last_request_id
let l:wd = go#util#ModuleRoot()
if l:wd == -1
call go#util#EchoError('could not determine appropriate working directory for gopls')
return -1
endif
if l:wd == ''
let l:wd = getcwd()
endif
let self.wd = l:wd
if go#config#EchoCommandInfo()
call go#util#EchoProgress("initializing gopls")
endif
let l:status = {
\ 'desc': '',
\ 'type': 'gopls',
\ 'state': 'initializing',
\ }
call go#statusline#Update(l:wd, l:status)
let self.workspaceDirectories = add(self.workspaceDirectories, l:wd)
let l:msg = self.newMessage(go#lsp#message#Initialize(l:wd))
let l:state = s:newHandlerState('')
let l:state.handleResult = funcref('self.handleInitializeResult', [], l:self)
let self.handlers[l:msg.id] = l:state
call l:state.start()
call self.write(l:msg)
endif
if !self.ready
call add(self.queue, {'data': a:data, 'handler': a:handler})
return
endif
let l:msg = self.newMessage(a:data)
if has_key(l:msg, 'id')
let self.handlers[l:msg.id] = a:handler
endif
call a:handler.start()
call self.write(l:msg)
endfunction
" newMessage returns a message constructed from data. data should be a dict
" with 2 or 3 keys: notification, method, and optionally params.
function! l:lsp.newMessage(data) dict abort
let l:msg = {
\ 'method': a:data.method,
\ 'jsonrpc': '2.0',
\ }
if !a:data.notification
let self.last_request_id += 1
let l:msg.id = self.last_request_id
endif
if has_key(a:data, 'params')
let l:msg.params = a:data.params
endif
return l:msg
endfunction
function l:lsp.newResponse(id, result) dict abort
let l:msg = {
\ 'jsonrpc': '2.0',
\ 'id': a:id,
\ 'result': a:result,
\ }
return l:msg
endfunction
function! l:lsp.write(msg) dict abort
if empty(get(self, 'job', {}))
return
endif
let l:body = json_encode(a:msg)
let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
call s:debug('sent', l:data)
if has('nvim')
call chansend(self.job, l:data)
return
endif
try
call ch_sendraw(self.job, l:data)
catch
call go#util#EchoError(printf('could not send message: %s', v:exception))
endtry
endfunction
function! l:lsp.exit_cb(job, exit_status) dict
let self.exited = 1
if !get(self, 'restarting', 0)
return
endif
let l:queue = self.queue
let l:workspaces = self.workspaceDirectories
call s:lspfactory.reset()
let l:lsp = s:lspfactory.get()
" restore workspaces
call call('go#lsp#AddWorkspaceDirectory', l:workspaces)
" * send DidOpen messages for all buffers that have b:did_lsp_open set
" TODO(bc): check modifiable and filetype, too?
bufdo if get(b:, 'go_lsp_did_open', 0) | if &modified | call go#lsp#DidOpen(expand('%:p')) | else | call go#lsp#DidChange(expand('%:p')) | endif | endif
let l:lsp.queue = extend(l:lsp.queue, l:queue)
return
endfunction
function! l:lsp.close_cb(ch) dict abort
" TODO(bc): remove the buffer variables that indicate that gopls has been
" informed that the file is open
endfunction
function! l:lsp.err_cb(ch, msg) dict abort
if a:msg =~ '^\d\{4}/\d\d/\d\d\ \d\d:\d\d:\d\d debug server listening on port \d\+$' && !get(self, 'debugport', 0)
let self.debugport = substitute(a:msg, '\d\{4}/\d\d/\d\d\ \d\d:\d\d:\d\d debug server listening on port \(\d\+\).*$', '\1', '')
endif
call s:debug('stderr', a:msg)
endfunction
" explicitly bind callbacks to l:lsp so that within it, self will always refer
" to l:lsp instead of l:opts. See :help Partial for more information.
let l:opts = {
\ 'in_mode': 'raw',
\ 'out_mode': 'raw',
\ 'err_mode': 'nl',
\ 'noblock': 1,
\ 'err_cb': funcref('l:lsp.err_cb', [], l:lsp),
\ 'out_cb': funcref('l:lsp.handleMessage', [], l:lsp),
\ 'close_cb': funcref('l:lsp.close_cb', [], l:lsp),
\ 'exit_cb': funcref('l:lsp.exit_cb', [], l:lsp),
\ 'cwd': getcwd(),
\}
let l:bin_path = go#path#CheckBinPath("gopls")
if empty(l:bin_path)
let l:lsp.sendMessage = funcref('s:noop')
return l:lsp
endif
let l:cmd = [l:bin_path]
let l:cmdopts = go#config#GoplsOptions()
if go#util#HasDebug('lsp')
" debugging can be enabled either with g:go_debug or with
" g:go_gopls_options; use g:go_gopls_options if it's given in case users
" are running the gopls debug server on a known port.
let l:needsDebug = 1
for l:item in l:cmdopts
let l:idx = stridx(l:item, '-debug')
if l:idx == 0 || l:idx == 1
let l:needsDebug = 0
endif
endfor
if l:needsDebug
let l:cmd = extend(l:cmd, ['-debug', 'localhost:0'])
endif
endif
let l:lsp.job = go#job#Start(l:cmd+l:cmdopts, l:opts)
return l:lsp
endfunction
1 0.000001 function! s:noop(...) abort
endfunction
1 0.000003 function! s:newHandlerState(statustype) abort
let l:state = {
\ 'winid': win_getid(winnr()),
\ 'statustype': a:statustype,
\ 'jobdir': getcwd(),
\ 'handleResult': funcref('s:noop'),
\ }
" explicitly bind requestComplete to state so that within it, self will
" always refer to state. See :help Partial for more information.
let l:state.requestComplete = funcref('s:requestComplete', [], l:state)
" explicitly bind start to state so that within it, self will
" always refer to state. See :help Partial for more information.
let l:state.start = funcref('s:start', [], l:state)
return l:state
endfunction
1 0.000001 function! s:requestComplete(ok) abort dict
if self.statustype == ''
return
endif
if go#config#EchoCommandInfo()
" redraw to avoid messages piling up
redraw
let prefix = '[' . self.statustype . '] '
if a:ok
call go#util#EchoSuccess(prefix . "SUCCESS")
else
call go#util#EchoError(prefix . "FAIL")
endif
endif
let status = {
\ 'desc': 'last status',
\ 'type': self.statustype,
\ 'state': "success",
\ }
if !a:ok
let status.state = "failed"
endif
if has_key(self, 'started_at')
let elapsed_time = reltimestr(reltime(self.started_at))
" strip whitespace
let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
let status.state .= printf(" (%ss)", elapsed_time)
endif
call go#statusline#Update(self.jobdir, status)
endfunction
1 0.000001 function! s:start() abort dict
let self.started_at = reltime()
if self.statustype == ''
return
endif
let status = {
\ 'desc': 'current status',
\ 'type': self.statustype,
\ 'state': "started",
\ }
call go#statusline#Update(self.jobdir, status)
endfunction
" go#lsp#Definition calls gopls to get the definition of the identifier at
" line and col in fname. handler should be a dictionary function that takes a
" list of strings in the form 'file:line:col: message'. handler will be
" attached to a dictionary that manages state (statuslines, sets the winid,
" etc.)
1 0.000002 function! go#lsp#Definition(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('definition')
let l:state.handleResult = funcref('s:definitionHandler', [function(a:handler, [], l:state)], l:state)
let l:msg = go#lsp#message#Definition(fnamemodify(a:fname, ':p'), a:line, a:col)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:definitionHandler(next, msg) abort dict
if a:msg is v:null || len(a:msg) == 0
return
endif
" gopls returns a []Location; just take the first one.
let l:msg = a:msg[0]
let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(getline(l:msg.range.start.line+1), l:msg.range.start.character), 'lsp does not supply a description')]]
call call(a:next, l:args)
endfunction
" go#lsp#Type calls gopls to get the type definition of the identifier at
" line and col in fname. handler should be a dictionary function that takes a
" list of strings in the form 'file:line:col: message'. handler will be
" attached to a dictionary that manages state (statuslines, sets the winid,
" etc.)
1 0.000001 function! go#lsp#TypeDef(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('type definition')
let l:msg = go#lsp#message#TypeDefinition(fnamemodify(a:fname, ':p'), a:line, a:col)
let l:state.handleResult = funcref('s:typeDefinitionHandler', [function(a:handler, [], l:state)], l:state)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:typeDefinitionHandler(next, msg) abort dict
if a:msg is v:null || len(a:msg) == 0
return
endif
" gopls returns a []Location; just take the first one.
let l:msg = a:msg[0]
let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(getline(l:msg.range.start.line+1), l:msg.range.start.character), 'lsp does not supply a description')]]
call call(a:next, l:args)
endfunction
" go#lsp#Callers calls gopls to get callers of the identifier at
" line and col in fname. handler should be a dictionary function that takes a
" list of strings in the form 'file:line:col: message'. handler will be
" attached to a dictionary that manages state (statuslines, sets the winid,
" etc.)
1 0.000001 function! go#lsp#Callers(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('callers')
let l:msg = go#lsp#message#PrepareCallHierarchy(fnamemodify(a:fname, ':p'), a:line, a:col)
let l:state.handleResult = funcref('s:prepareCallHierarchyHandler', [function(a:handler, [], l:state)], l:state)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:prepareCallHierarchyHandler(next, msg) abort dict
if a:msg is v:null || len(a:msg) == 0
return
endif
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('callers')
let l:msg = go#lsp#message#IncomingCalls(a:msg[0])
let l:state.handleResult = funcref('s:incomingCallsHandler', [function(a:next, [], l:state)], l:state)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000002 function! s:incomingCallsHandler(next, msg) abort dict
if a:msg is v:null || len(a:msg) == 0
return
endif
let l:locations = []
for l:item in a:msg
try
let l:fname = go#path#FromURI(l:item.from.uri)
for l:fromRange in l:item.fromRanges
let l:line = l:fromRange.start.line+1
let l:content = s:lineinfile(l:fname, l:line)
if l:content is -1
continue
endif
let l:locations = add(l:locations, printf('%s:%s:%s: %s', l:fname, l:line, go#lsp#lsp#PositionOf(content, l:fromRange.start.character), l:item.from.name))
endfor
catch
endtry
endfor
call call(a:next, [l:locations])
return
endfunction
1 0.000001 function! go#lsp#DidOpen(fname) abort
if get(b:, 'go_lsp_did_open', 0)
return
endif
let l:fname = fnamemodify(a:fname, ':p')
if !isdirectory(fnamemodify(l:fname, ':h'))
return
endif
let l:lsp = s:lspfactory.get()
if !has_key(l:lsp.notificationQueue, l:fname)
let l:lsp.notificationQueue[l:fname] = []
endif
call s:ensureWorkspace(fnamemodify(l:fname, ':h'))
let l:lsp.fileVersions[l:fname] = getbufvar(l:fname, 'changedtick')
let l:msg = go#lsp#message#DidOpen(l:fname, join(go#util#GetLines(), "\n") . "\n", l:lsp.fileVersions[l:fname])
let l:state = s:newHandlerState('')
" TODO(bc): setting a buffer level variable here assumes that a:fname is the
" current buffer. Change to a:fname first before setting it and then change
" back to active buffer.
let b:go_lsp_did_open = 1
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! go#lsp#DidChange(fname) abort
" DidChange is called even when fname isn't open in a buffer (e.g. via
" go#lsp#Info); don't report the file as open or as having changed when it's
" not actually a buffer.
if bufnr(a:fname) == -1
return
endif
let l:fname = fnamemodify(a:fname, ':p')
if !isdirectory(fnamemodify(l:fname, ':h'))
return
endif
call go#lsp#DidOpen(a:fname)
let l:lsp = s:lspfactory.get()
let l:version = getbufvar(l:fname, 'changedtick')
if has_key(l:lsp.fileVersions, l:fname) && l:lsp.fileVersions[l:fname] == l:version
return
endif
let l:lsp.fileVersions[l:fname] = l:version
let l:msg = go#lsp#message#DidChange(l:fname, join(go#util#GetLines(), "\n") . "\n", l:lsp.fileVersions[l:fname])
let l:state = s:newHandlerState('')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! go#lsp#DidClose(fname) abort
let l:fname = fnamemodify(a:fname, ':p')
if !isdirectory(fnamemodify(l:fname, ':h'))
return
endif
if !get(b:, 'go_lsp_did_open', 0)
return
endif
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#DidClose(l:fname)
let l:state = s:newHandlerState('')
" TODO(bc): setting a buffer level variable here assumes that a:fname is the
" current buffer. Change to a:fname first before setting it and then change
" back to active buffer.
let b:go_lsp_did_open = 0
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! go#lsp#Completion(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#Completion(a:fname, a:line, a:col)
let l:state = s:newHandlerState('completion')
let l:state.handleResult = funcref('s:completionHandler', [function(a:handler, [], l:state)], l:state)
let l:state.error = funcref('s:completionErrorHandler', [function(a:handler, [], l:state)], l:state)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:completionHandler(next, msg) abort dict
" gopls returns a CompletionList.
let l:matches = []
let l:start = -1
for l:item in a:msg.items
let l:start = l:item.textEdit.range.start.character
let l:match = {'abbr': l:item.label, 'word': l:item.textEdit.newText, 'info': '', 'kind': go#lsp#completionitemkind#Vim(l:item.kind), 'user_data': '', 'icase': go#config#CodeCompletionIcase()}
if has_key(l:item, 'detail')
let l:match.menu = l:item.detail
if go#lsp#completionitemkind#IsFunction(l:item.kind) || go#lsp#completionitemkind#IsMethod(l:item.kind)
let l:match.info = printf('%s %s', l:item.label, l:item.detail)
" The detail provided by gopls hasn't always provided the the full
" signature including the return value. The label used to be the
" function signature and the detail was the return value. Handle
" that case for backward compatibility. This can be removed in the
" future once it's likely that the majority of users are on a recent
" version of gopls.
if l:item.detail !~ '^func'
let l:match.info = printf('func %s %s', l:item.label, l:item.detail)
endif
endif
endif
let l:match.user_data = l:match.info
if has_key(l:item, 'documentation')
let l:match.info .= "\n\n" . l:item.documentation
endif
let l:matches = add(l:matches, l:match)
endfor
let l:args = [l:start, l:matches]
call call(a:next, l:args)
endfunction
1 0.000001 function! s:completionErrorHandler(next, error) abort dict
call call(a:next, [-1, []])
endfunction
" go#lsp#SameIDs calls gopls to get the references to the identifier at line
" and col in fname. handler should be a dictionary function that takes a list
" of strings in the form 'file:line:col: message'. handler will be attached to
" a dictionary that manages state (statuslines, sets the winid, etc.). handler
" should take three arguments: an exit_code, a JSON object encoded to a string
" that mimics guru's ouput for `what`, and third mode parameter that only
" exists for compatibility with the guru implementation of SameIDs.
" TODO(bc): refactor to not need the guru adapter.
1 0.000001 function! go#lsp#SameIDs(showstatus, fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#References(a:fname, a:line, a:col)
if a:showstatus
let l:state = s:newHandlerState('same ids')
else
let l:state = s:newHandlerState('')
endif
let l:state.handleResult = funcref('s:sameIDsHandler', [function(a:handler, [], l:state)], l:state)
let l:state.error = funcref('s:noop')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:sameIDsHandler(next, msg) abort dict
let l:furi = go#path#ToURI(expand('%:p'))
let l:result = {
\ 'sameids': [],
\ 'enclosing': [],
\ }
let l:msg = a:msg
if a:msg is v:null
let l:msg = []
endif
for l:loc in l:msg
if l:loc.uri !=# l:furi
continue
endif
if len(l:result.enclosing) == 0
let l:result.enclosing = [{
\ 'desc': 'identifier',
\ 'start': l:loc.range.start.character+1,
\ 'end': l:loc.range.end.character+1,
\ }]
endif
let l:result.sameids = add(l:result.sameids, printf('%s:%s:%s', go#path#FromURI(l:loc.uri), l:loc.range.start.line+1, l:loc.range.start.character+1))
endfor
call call(a:next, [0, json_encode(l:result), ''])
endfunction
" go#lsp#Referrers calls gopls to get the references to the identifier at line
" and col in fname. handler should be a dictionary function that takes a list
" of strings in the form 'file:line:col: message'. handler will be attached to
" a dictionary that manages state (statuslines, sets the winid, etc.). handler
" should take three arguments: an exit_code, a JSON object encoded to a string
" that mimics guru's ouput for `what`, and third mode parameter that only
" exists for compatibility with the guru implementation of SameIDs.
" TODO(bc): refactor to not need the guru adapter.
1 0.000001 function! go#lsp#Referrers(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#References(a:fname, a:line, a:col)
let l:state = s:newHandlerState('referrers')
let l:state.handleResult = funcref('s:handleReferences', [function(a:handler, [], l:state)], l:state)
let l:state.error = funcref('s:noop')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:handleReferences(next, msg) abort dict
call s:handleLocations(a:next, a:msg)
endfunction
1 0.000001 function! s:handleLocations(next, msg) abort
let l:result = []
let l:msg = a:msg
if l:msg is v:null
let l:msg = []
endif
call sort(l:msg, funcref('s:compareLocations'))
for l:loc in l:msg
let l:fname = go#path#FromURI(l:loc.uri)
let l:line = l:loc.range.start.line+1
let l:content = s:lineinfile(l:fname, l:line)
if l:content is -1
continue
endif
let l:item = printf('%s:%s:%s: %s', l:fname, l:line, go#lsp#lsp#PositionOf(l:content, l:loc.range.start.character), l:content)
let l:result = add(l:result, l:item)
endfor
call call(a:next, [0, l:result, ''])
endfunction
" go#lsp#Implementations calls gopls to get the implementations to the
" identifier at line and col in fname. handler should be a dictionary function
" that takes a list of strings in the form 'file:line:col: message'. handler
" will be attached to a dictionary that manages state (statuslines, sets the
" winid, etc.). handler should take three arguments: an exit_code, a JSON
" object encoded to a string that mimics guru's ouput for guru implements, and
" a third parameter that only exists for compatibility with guru implements.
1 0.000001 function! go#lsp#Implements(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#Implementation(a:fname, a:line, a:col)
let l:state = s:newHandlerState('implements')
let l:state.handleResult = funcref('s:handleImplements', [function(a:handler, [], l:state)], l:state)
let l:state.error = funcref('s:handleImplementsError', [function(a:handler, [], l:state)], l:state)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:handleImplements(next, msg) abort dict
call s:handleLocations(a:next, a:msg)
endfunction
1 0.000001 function! s:handleImplementsError(next, error) abort dict
call call(a:next, [1, [a:error], ''])
endfunction
1 0.000001 function! go#lsp#Hover(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#Hover(a:fname, a:line, a:col)
let l:state = s:newHandlerState('')
let l:state.handleResult = funcref('s:hoverHandler', [function(a:handler, [], l:state)], l:state)
let l:state.error = funcref('s:noop')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:hoverHandler(next, msg) abort dict
if a:msg is v:null || !has_key(a:msg, 'contents')
return
endif
try
let l:value = json_decode(a:msg.contents.value)
let l:signature = split(l:value.signature, "\n")
let l:msg = l:signature
if go#config#DocBalloon()
" use synopsis instead of fullDocumentation to keep the hover window
" small.
let l:doc = l:value.synopsis
if len(l:doc) isnot 0
let l:msg = l:signature + ['', l:doc]
endif
endif
call call(a:next, [l:msg])
catch
" TODO(bc): log the message and/or show an error message.
endtry
endfunction
1 0.000001 function! go#lsp#Doc() abort
let l:fname = expand('%:p')
let [l:line, l:col] = go#lsp#lsp#Position()
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#Hover(l:fname, l:line, l:col)
let l:state = s:newHandlerState('doc')
let l:resultHandler = go#promise#New(function('s:docFromHoverResult', [], l:state), 10000, '')
let l:state.handleResult = l:resultHandler.wrapper
let l:state.error = l:resultHandler.wrapper
call l:lsp.sendMessage(l:msg, l:state)
return l:resultHandler.await()
endfunction
1 0.000001 function! s:docFromHoverResult(msg) abort dict
if type(a:msg) is type('')
return [a:msg, 1]
endif
if a:msg is v:null || !has_key(a:msg, 'contents')
return ['Undocumented', 0]
endif
let l:value = json_decode(a:msg.contents.value)
let l:doc = l:value.fullDocumentation
if len(l:doc) is 0
let l:doc = 'Undocumented'
endif
let l:content = printf("%s\n\n%s", l:value.signature, l:doc)
return [l:content, 0]
endfunction
1 0.000000 function! go#lsp#DocLink() abort
let l:fname = expand('%:p')
let [l:line, l:col] = go#lsp#lsp#Position()
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#Hover(l:fname, l:line, l:col)
let l:state = s:newHandlerState('doc url')
let l:resultHandler = go#promise#New(function('s:docLinkFromHoverResult', [], l:state), 10000, '')
let l:state.handleResult = l:resultHandler.wrapper
let l:state.error = l:resultHandler.wrapper
call l:lsp.sendMessage(l:msg, l:state)
return l:resultHandler.await()
endfunction
1 0.000001 function! s:docLinkFromHoverResult(msg) abort dict
if type(a:msg) is type('')
return [a:msg, 1]
endif
if a:msg is v:null || !has_key(a:msg, 'contents')
return ['', 0]
endif
let l:doc = json_decode(a:msg.contents.value)
" for backward compatibility with older gopls
if has_key(l:doc, 'link')
let l:link = l:doc.link
return [l:doc.link, 0]
endif
if !has_key(l:doc, 'linkPath') || empty(l:doc.linkPath)
return ['', 0]
endif
let l:link = l:doc.linkPath . "#" . l:doc.linkAnchor
return [l:link, 0]
endfunction
1 0.000001 function! go#lsp#Info(showstatus)
let l:fname = expand('%:p')
let [l:line, l:col] = go#lsp#lsp#Position()
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
if a:showstatus
let l:state = s:newHandlerState('info')
else
let l:state = s:newHandlerState('')
endif
let l:state.handleResult = funcref('s:infoDefinitionHandler', [function('s:info', [1], l:state), a:showstatus], l:state)
let l:state.error = funcref('s:noop')
let l:msg = go#lsp#message#Definition(l:fname, l:line, l:col)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000000 function! go#lsp#GetInfo()
let l:fname = expand('%:p')
let [l:line, l:col] = go#lsp#lsp#Position()
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:info = go#promise#New(function('s:info', [0], l:state), 10000, '')
let l:state.handleResult = funcref('s:infoDefinitionHandler', [l:info.wrapper, 0], l:state)
let l:state.error = funcref('s:noop')
let l:msg = go#lsp#message#Definition(l:fname, l:line, l:col)
call l:lsp.sendMessage(l:msg, l:state)
return l:info.await()
endfunction
1 0.000001 function! s:infoDefinitionHandler(next, showstatus, msg) abort dict
" gopls returns a []Location; just take the first one.
if a:msg is v:null || len(a:msg) == 0
return
endif
let l:msg = a:msg[0]
let l:fname = go#path#FromURI(l:msg.uri)
let l:line = l:msg.range.start.line
let l:col = l:msg.range.start.character
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#Hover(l:fname, l:line, l:col)
if a:showstatus
let l:state = s:newHandlerState('info')
else
let l:state = s:newHandlerState('')
endif
let l:state.handleResult = a:next
let l:state.error = funcref('s:noop')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:info(show, msg) abort dict
if a:msg is v:null || !has_key(a:msg, 'contents')
return
endif
let l:value = json_decode(a:msg.contents.value)
let l:content = [l:value.singleLine]
let l:content = s:infoFromHoverContent(l:content)
if a:show
call go#util#ShowInfo(l:content)
endif
return l:content
endfunction
1 0.000001 function! s:infoFromHoverContent(content) abort
if len(a:content) < 1
return ''
endif
let l:content = a:content[0]
" strip off the method set and fields of structs and interfaces.
if l:content =~# '^\(type \)\?[^ ]\+ \(struct\|interface\)'
let l:content = substitute(l:content, '{.*', '', '')
endif
return l:content
endfunction
1 0.000001 function! go#lsp#AddWorkspaceDirectory(...) abort
if a:0 == 0
return
endif
call go#lsp#CleanWorkspaces()
let l:workspaces = []
for l:dir in a:000
let l:dir = fnamemodify(l:dir, ':p')
if len(l:dir) > 1 && l:dir[-1:] == '/'
let l:dir = l:dir[:-2]
endif
if !isdirectory(l:dir)
continue
endif
let l:workspaces = add(l:workspaces, l:dir)
endfor
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:lsp.workspaceDirectories = s:dedup(extend(l:lsp.workspaceDirectories, l:workspaces))
let l:msg = go#lsp#message#ChangeWorkspaceFolders(l:workspaces, [])
call l:lsp.sendMessage(l:msg, l:state)
return 0
endfunction
1 0.000001 function! go#lsp#CleanWorkspaces() abort
let l:workspaces = []
let l:lsp = s:lspfactory.get()
let l:i = 0
let l:missing = []
for l:dir in l:lsp.workspaceDirectories
if !isdirectory(l:dir)
let l:missing = add(l:missing, l:dir)
call remove(l:lsp.workspaceDirectories, l:i)
continue
endif
let l:i += 1
endfor
if len(l:missing) == 0
return 0
endif
let l:state = s:newHandlerState('')
let l:msg = go#lsp#message#ChangeWorkspaceFolders([], s:dedup(l:missing))
call l:lsp.sendMessage(l:msg, l:state)
return 0
endfunction
" go#lsp#ResetWorkspaceDiretories removes and then re-adds all workspace
" folders to cause gopls to send configuration requests for all of them again.
" This is useful, for instance, when build tags have been added and gopls
" needs to use them.
1 0.000001 function! go#lsp#ResetWorkspaceDirectories() abort
call go#lsp#CleanWorkspaces()
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:msg = go#lsp#message#ChangeWorkspaceFolders(s:dedup(l:lsp.workspaceDirectories), s:dedup(l:lsp.workspaceDirectories))
call l:lsp.sendMessage(l:msg, l:state)
return 0
endfunction
1 0.000000 function! go#lsp#DebugBrowser() abort
let l:lsp = s:lspfactory.get()
let l:port = get(l:lsp, 'debugport', 0)
if !l:port
call go#util#EchoError("gopls was not started with debugging enabled. See :help g:go_debug.")
return
endif
call go#util#OpenBrowser(printf('http://localhost:%d', l:port))
endfunction
1 0.000000 function! go#lsp#Exit() abort
call s:exit(0)
endfunction
1 0.000000 function! go#lsp#Restart() abort
call s:exit(1)
endfunction
1 0.000001 function! s:exit(restart) abort
if !go#util#has_job() || len(s:lspfactory) == 0 || !has_key(s:lspfactory, 'current')
return
endif
let l:lsp = s:lspfactory.get()
" reset the factory so that future requests don't use the same instance of
" gopls.
call s:lspfactory.reset()
let l:lsp.restarting = a:restart
let l:state = s:newHandlerState('exit')
let l:msg = go#lsp#message#Shutdown()
let l:retval = l:lsp.sendMessage(l:msg, l:state)
let l:msg = go#lsp#message#Exit()
let l:retval = l:lsp.sendMessage(l:msg, l:state)
return l:retval
endfunction
1 0.000001 let s:log = []
1 0.000001 function! s:debugasync(timer) abort
if !go#util#HasDebug('lsp')
let s:log = []
return
endif
let l:winid = win_getid()
let l:name = '__GOLSP_LOG__'
let l:log_winid = bufwinid(l:name)
if l:log_winid == -1
silent keepalt botright 10new
silent file `='__GOLSP_LOG__'`
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
setlocal filetype=golsplog
else
call win_gotoid(l:log_winid)
endif
try
setlocal modifiable
for [l:event, l:data] in s:log
call remove(s:log, 0)
if getline(1) == ''
call setline('$', printf('===== %s =====', l:event))
else
call append('$', printf('===== %s =====', l:event))
endif
call append('$', split(l:data, "\r\n"))
endfor
normal! G
setlocal nomodifiable
finally
call win_gotoid(l:winid)
endtry
endfunction
1 0.000001 function! s:debug(event, data) abort
let l:shouldStart = len(s:log) == 0
let s:log = add(s:log, [a:event, a:data])
if l:shouldStart
call timer_start(10, function('s:debugasync', []))
endif
endfunction
1 0.000001 function! s:compareLocations(left, right) abort
if a:left.uri < a:right.uri
return -1
endif
if a:left.uri == a:right.uri && a:left.range.start.line < a:right.range.start.line
return -1
endif
if a:left.uri == a:right.uri && a:left.range.start.line == a:right.range.start.line && a:left.range.start.character < a:right.range.start.character
return -1
endif
if a:left.uri == a:right.uri && a:left.range.start.line == a:right.range.start.line && a:left.range.start.character == a:right.range.start.character
return 0
endif
return 1
endfunction
1 0.000000 function! go#lsp#Diagnostics(...) abort
if a:0 == 0
return []
endif
let l:dirsToPackages = {}
let l:lsp = s:lspfactory.get()
let l:diagnostics = []
for [l:key, l:val] in items(l:lsp.diagnostics)
let l:dir = fnamemodify(l:key, ':h')
if !has_key(l:dirsToPackages, l:dir)
let l:pkg = go#package#FromPath(l:dir)
let l:dirsToPackages[l:dir] = l:pkg
else
let l:pkg = l:dirsToPackages[l:dir]
endif
if type(l:pkg) == type(0)
continue
endif
for l:arg in a:000
if l:arg == l:pkg || l:arg == 'all'
let l:diagnostics = extend(l:diagnostics, l:val)
endif
endfor
endfor
return sort(l:diagnostics)
endfunction
1 0.000001 function! go#lsp#AnalyzeFile(fname) abort
let l:fname = fnamemodify(a:fname, ':p')
if !isdirectory(fnamemodify(l:fname, ':h'))
return []
endif
let l:lsp = s:lspfactory.get()
let l:lastdiagnostics = get(l:lsp.diagnostics, l:fname, [])
let l:version = get(l:lsp.fileVersions, a:fname, 0)
if l:version == getbufvar(a:fname, 'changedtick')
return l:lastdiagnostics
endif
call go#lsp#DidChange(a:fname)
let l:diagnostics = go#promise#New(function('s:setDiagnostics', []), 10000, l:lastdiagnostics)
let l:lsp.notificationQueue[l:fname] = add(get(l:lsp.notificationQueue, l:fname, []), l:diagnostics.wrapper)
return l:diagnostics.await()
endfunction
1 0.000001 function! s:setDiagnostics(...) abort
return a:000
endfunction
" s:processDiagnostic converts a diagnostic into an error string. It returns
" the errors string and the match position described in the diagnostic. The
" match position will be an empty list when bufname is not a valid name for
" the current buffer.
1 0.000001 function! s:errorFromDiagnostic(diagnostic, bufname, fname) abort
let l:range = a:diagnostic.range
let l:line = l:range.start.line + 1
let l:buflines = getbufline(a:bufname, l:line)
let l:col = ''
if len(l:buflines) > 0
let l:col = go#lsp#lsp#PositionOf(l:buflines[0], l:range.start.character)
endif
let l:error = printf('%s:%s:%s:%s: %s', a:fname, l:line, l:col, go#lsp#lsp#SeverityToErrorType(a:diagnostic.severity), a:diagnostic.message)
if !(a:diagnostic.severity == 1 || a:diagnostic.severity == 2)
return [l:error, []]
endif
" return when the diagnostic is not for the current buffer.
if bufnr(a:bufname) != bufnr('')
return [l:error, []]
end
let l:endline = l:range.end.line + 1
" don't bother trying to highlight errors or warnings that span
" the whole file (e.g when there's missing package documentation).
if l:line == 1 && (l:endline) == line('$')
return [l:error, []]
endif
let l:endcol = go#lsp#lsp#PositionOf(getline(l:endline), l:range.end.character)
" the length of the match is the number of bytes between the start of
" the match and the end of the match.
let l:matchLength = line2byte(l:endline) + l:endcol - (line2byte(l:line) + l:col)
let l:pos = [l:line, l:col, l:matchLength]
return [l:error, l:pos]
endfunction
1 0.000001 function! s:highlightMatches(errorMatches, warningMatches) abort
" set buffer variables for errors and warnings to zero values
let b:go_diagnostic_matches = {'errors': [], 'warnings': []}
if hlexists('goDiagnosticError')
" clear the old matches just before adding the new ones to keep flicker
" to a minimum and clear before checking the level so that if the user
" changed the level since the last highlighting, the highlighting will be
" be properly cleared.
call go#util#ClearHighlights('goDiagnosticError')
if go#config#DiagnosticsLevel() >= 2
let b:go_diagnostic_matches.errors = copy(a:errorMatches)
if go#config#HighlightDiagnosticErrors()
call go#util#HighlightPositions('goDiagnosticError', a:errorMatches)
endif
endif
endif
if hlexists('goDiagnosticWarning')
" clear the old matches just before adding the new ones to keep flicker
" to a minimum and clear before checking the level so that if the user
" changed the level since the last highlighting, the highlighting will be
" be properly cleared.
call go#util#ClearHighlights('goDiagnosticWarning')
if go#config#DiagnosticsLevel() >= 2
let b:go_diagnostic_matches.warnings = copy(a:warningMatches)
if go#config#HighlightDiagnosticWarnings()
call go#util#HighlightPositions('goDiagnosticWarning', a:warningMatches)
endif
endif
endif
" re-apply matches at the time the buffer is displayed in a new window or
" redisplayed in an existing window: e.g. :edit,
augroup vim-go-diagnostics
autocmd! * <buffer>
autocmd BufDelete <buffer> autocmd! vim-go-diagnostics * <buffer=abuf>
if has('textprop')
autocmd BufReadPost <buffer> nested call s:highlightMatches(b:go_diagnostic_matches.errors, b:go_diagnostic_matches.warnings)
else
autocmd BufWinEnter <buffer> nested call s:highlightMatches(b:go_diagnostic_matches.errors, b:go_diagnostic_matches.warnings)
endif
augroup end
endfunction
" ClearDiagnosticHighlights removes all goDiagnosticError and
" goDiagnosticWarning matches.
1 0.000001 function! go#lsp#ClearDiagnosticHighlights() abort
call go#util#ClearHighlights('goDiagnosticError')
call go#util#ClearHighlights('goDiagnosticWarning')
endfunction
" Format formats the current buffer.
1 0.000000 function! go#lsp#Format() abort
let l:fname = expand('%:p')
" send the current file so that TextEdits will be relative to the current
" state of the buffer.
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:handleFormat = go#promise#New(function('s:handleFormat', [], l:state), 10000, '')
let l:state.handleResult = l:handleFormat.wrapper
let l:state.error = l:handleFormat.wrapper
let l:state.handleError = function('s:handleFormatError', [l:fname], l:state)
let l:msg = go#lsp#message#Format(l:fname)
call l:lsp.sendMessage(l:msg, l:state)
call go#fmt#CleanErrors()
" await the result to avoid any race conditions among autocmds (e.g.
" BufWritePre and BufWritePost)
call l:handleFormat.await()
endfunction
" Imports executes the source.organizeImports code action for the current
" buffer.
1 0.000000 function! go#lsp#Imports() abort
let l:fname = expand('%:p')
" send the current file so that TextEdits will be relative to the current
" state of the buffer.
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:handler = go#promise#New(function('s:handleCodeAction', ['source.organizeImports', ''], l:state), 10000, '')
let l:state.handleResult = l:handler.wrapper
let l:state.error = l:handler.wrapper
let l:state.handleError = function('s:handleCodeActionError', [l:fname], l:state)
let l:msg = go#lsp#message#CodeActionImports(l:fname)
call l:lsp.sendMessage(l:msg, l:state)
" await the result to avoid any race conditions among autocmds (e.g.
" BufWritePre and BufWritePost)
call l:handler.await()
endfunction
" FillStruct executes the refactor.rewrite code action for the current buffer
" and configures the handler to only apply the fillstruct command for the
" current location.
1 0.000001 function! go#lsp#FillStruct() abort
let l:fname = expand('%:p')
" send the current file so that TextEdits will be relative to the current
" state of the buffer.
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:handler = go#promise#New(function('s:handleCodeAction', ['refactor.rewrite', 'apply_fix'], l:state), 10000, '')
let l:state.handleResult = l:handler.wrapper
let l:state.error = l:handler.wrapper
let l:state.handleError = function('s:handleCodeActionError', [l:fname], l:state)
let [l:line, l:col] = go#lsp#lsp#Position()
let l:msg = go#lsp#message#CodeActionFillStruct(l:fname, l:line, l:col)
call l:lsp.sendMessage(l:msg, l:state)
" await the result to avoid any race conditions among autocmds (e.g.
" BufWritePre and BufWritePost)
call l:handler.await()
endfunction
1 0.000000 function! go#lsp#Rename(newName) abort
let l:fname = expand('%:p')
let [l:line, l:col] = go#lsp#lsp#Position()
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#PrepareRename(l:fname, l:line, l:col)
let l:state = s:newHandlerState('rename')
let l:resultHandler = go#promise#New(function('s:rename', [l:fname, l:line, l:col, a:newName], l:state), 10000, '')
let l:state.handleResult = l:resultHandler.wrapper
let l:state.error = l:resultHandler.wrapper
let l:state.handleError = function('s:handleRenameError', [], l:state)
call l:lsp.sendMessage(l:msg, l:state)
return l:resultHandler.await()
endfunction
1 0.000001 function! s:rename(fname, line, col, newName, msg) abort dict
if type(a:msg) is type('')
call self.handleError(a:msg)
return
endif
if a:msg is v:null
call go#util#EchoWarning('cannot rename the identifier at the requested position')
return
endif
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#Rename(a:fname, a:line, a:col, a:newName)
let l:state = s:newHandlerState('rename')
let l:resultHandler = go#promise#New(function('s:handleRename', [], l:state), 10000, '')
let l:state.handleResult = l:resultHandler.wrapper
let l:state.error = l:resultHandler.wrapper
let l:state.handleError = function('s:handleRenameError', [], l:state)
call l:lsp.sendMessage(l:msg, l:state)
return l:resultHandler.await()
endfunction
1 0.000001 function! s:handleRename(msg) abort dict
if type(a:msg) is type('')
call self.handleError(a:msg)
return
endif
if a:msg is v:null
return
endif
call s:applyDocumentChanges(a:msg.documentChanges)
endfunction
1 0.000001 function! s:executeCommand(cmd, args) abort
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:msg = go#lsp#message#ExecuteCommand(a:cmd, a:args)
call l:lsp.sendMessage(l:msg, l:state)
endfunction
1 0.000001 function! s:handleFormat(msg) abort dict
call go#fmt#CleanErrors()
if type(a:msg) is type('')
call self.handleError(a:msg)
return
endif
call s:applyTextEdits(bufnr(''), a:msg)
endfunction
1 0.000001 function! s:handleCodeAction(kind, cmd, msg) abort dict
if type(a:msg) is type('')
call self.handleError(a:msg)
return
endif
if a:msg is v:null
return
endif
for l:item in a:msg
if get(l:item, 'kind', '') is a:kind
if !has_key(l:item, 'edit')
continue
endif
if has_key(l:item, 'disabled') && get(l:item.disabled, 'reason', '') isnot ''
call go#util#EchoWarning(printf('code action is disabled: %s', l:item.disabled.reason))
continue
endif
if has_key(l:item, 'command')
if has_key(l:item.command, 'command') && (l:item.command.command is a:cmd || l:item.command.command is printf('gopls.%s', a:cmd))
call s:executeCommand(l:item.command.command, l:item.command.arguments)
continue
endif
endif
if !has_key(l:item.edit, 'documentChanges')
continue
endif
call s:applyDocumentChanges(l:item.edit.documentChanges)
endif
endfor
endfunction
1 0.000001 function s:applyDocumentChanges(changes)
let l:bufnr = bufnr('')
for l:change in a:changes
if !has_key(l:change, 'edits')
continue
endif
let l:fname = go#path#FromURI(l:change.textDocument.uri)
" get the buffer name relative to the current directory, because
" Vim says that a buffer name can't be an absolute path.
let l:bufname = fnamemodify(l:fname, ':.')
let l:bufadded = 0
let l:bufloaded = 0
let l:editbufnr = bufnr(l:bufname)
if l:editbufnr != bufnr('')
" make sure the buffer is listed and loaded before applying text edits
if !bufexists(l:bufname)
call bufadd(l:bufname)
let l:bufadded = 1
endif
if !bufloaded(l:bufname)
call bufload(l:bufname)
let l:bufloaded = 1
endif
let l:editbufnr = bufnr(l:bufname)
if l:editbufnr == -1
call go#util#EchoWarn(printf('could not apply changes to %s', l:fname))
continue
endif
" TODO(bc): do not edit the buffer when vim-go drops support for Vim
" 8.0. Instead, use the functions to modify a buffer (e.g.
" appendbufline, getbufline, deletebufline).
execute printf('keepalt keepjumps buffer! %d', l:editbufnr)
endif
call s:applyTextEdits(l:editbufnr, l:change.edits)
" TODO(bc): save the buffer?
" TODO(bc): unload and/or delete a buffer that was loaded or added,
" respectively?
endfor
if bufnr('') != l:bufnr
execute printf('keepalt keepjumps buffer! %d', l:bufnr)
endif
endfunction
" s:applyTextEdit applies the list of WorkspaceEdit values in msg.
1 0.000001 function s:applyTextEdits(bufnr, msg) abort
if a:msg is v:null
return
endif
" TODO(bc): start using the functions to modify a buffer (e.g. appendbufline,
" deletebufline, etc) instead of operating on the current buffer when vim-go
" drops support from Vim 8.0.
" process the TextEdit list in reverse order, because the positions are
" based on the current line numbers; processing in forward order would
" require keeping track of how the proper position of each TextEdit would be
" affected by all the TextEdits that came before.
call reverse(sort(a:msg, function('s:textEditLess')))
for l:msg in a:msg
let l:startline = l:msg.range.start.line+1
let l:endline = l:msg.range.end.line+1
let l:text = l:msg.newText
" handle the deletion of whole lines
if len(l:text) == 0 && l:msg.range.start.character == 0 && l:msg.range.end.character == 0 && l:startline < l:endline
call s:deleteline(l:startline, l:endline-1)
continue
endif
" Assume that l:startcontent will be an empty string. When the replacement
" is not at the beginning of the line, then l:startcontent must be what
" comes before the start position on the start line.
let l:startcontent = ''
if l:msg.range.start.character > 0
let l:startcontent = getline(l:startline)
let l:preSliceEnd = go#lsp#lsp#PositionOf(l:startcontent, l:msg.range.start.character-1) - 1
let l:startcontent = l:startcontent[:l:preSliceEnd]
endif
let l:endcontent = getline(l:endline)
let l:postSliceStart = 0
if l:msg.range.end.character > 0
let l:postSliceStart = go#lsp#lsp#PositionOf(l:endcontent, l:msg.range.end.character-1)
let l:endcontent = l:endcontent[(l:postSliceStart):]
endif
" There isn't an easy way to replace the text in a byte or character
" range, so append to l:text any text on l:endline starting from
" l:postSliceStart and prepend to l:text any text on l:startline prior to
" l:preSliceEnd, and finally replace the lines with a delete followed by
" and append.
let l:text = printf('%s%s%s', l:startcontent, l:text, l:endcontent)
" TODO(bc): deal with the undo file
" TODO(bc): deal with folds
" TODO(bc): can we use appendbufline instead of deleting and appending?
call s:deleteline(l:startline, l:endline)
for l:line in split(l:text, "\n", 1)
call append(l:startline-1, l:line)
let l:startline += 1
endfor
endfor
call go#lsp#DidChange(expand('%:p'))
return
endfunction
1 0.000001 function! s:handleFormatError(filename, msg) abort dict
if go#config#FmtFailSilently()
return
endif
let l:errors = split(a:msg, '\n')
let l:errors = map(l:errors, printf('substitute(v:val, ''^'', ''%s:'', '''')', a:filename))
let l:errors = join(l:errors, "\n")
call go#fmt#ShowErrors(l:errors)
endfunction
1 0.000001 function! s:handleCodeActionError(filename, msg) abort dict
" TODO(bc): handle the error?
endfunction
1 0.000001 function! s:handleRenameError(msg) abort dict
call go#util#EchoError(a:msg)
endfunction
1 0.000001 function! s:textEditLess(left, right) abort
" TextEdits in a TextEdit[] never overlap and Vim's sort() is stable.
if a:left.range.start.line < a:right.range.start.line
return -1
endif
if a:left.range.start.line > a:right.range.start.line
return 1
endif
if a:left.range.start.line == a:right.range.start.line
if a:left.range.start.character < a:right.range.start.character
return -1
endif
if a:left.range.start.character > a:right.range.start.character
return 1
endif
endif
" return 0, because a:left and a:right refer to the same position.
return 0
endfunction
1 0.000001 function! s:deleteline(start, end) abort
if exists('*deletebufline')
call deletebufline('', a:start, a:end)
else
call execute(printf('%d,%d d_', a:start, a:end))
endif
endfunction
1 0.000001 function! s:ensureWorkspace(dir)
let l:modroot = go#util#ModuleRoot(a:dir)
if l:modroot is -1 || l:modroot is ''
return
endif
let l:lsp = s:lspfactory.get()
for l:dir in l:lsp.workspaceDirectories
if l:dir == l:modroot
return
endif
endfor
call go#lsp#AddWorkspaceDirectory(l:modroot)
endfunction
1 0.000001 function! s:dedup(list)
let l:dict = {}
for l:item in a:list
let l:dict[l:item] = 1
endfor
return sort(keys(l:dict))
endfunction
1 0.000001 function! s:lineinfile(fname, line) abort
let l:bufnr = bufnr(a:fname)
let l:bufinfo = getbufinfo(a:fname)
try
if l:bufnr == -1 || len(l:bufinfo) == 0 || l:bufinfo[0].loaded == 0
let l:filecontents = readfile(a:fname, '', a:line)
else
let l:filecontents = getbufline(a:fname, a:line)
endif
if len(l:filecontents) == 0
return -1
endif
return l:filecontents[-1]
catch
"call go#util#EchoError(printf('%s (line %s): %s at %s', a:fname, a:line, v:exception, v:throwpoint))
return -1
endtry
endfunction
" restore Vi compatibility settings
1 0.000003 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/job.vim
Sourced 1 time
Total time: 0.000507
Self time: 0.000507
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000003 let s:cpo_save = &cpo
1 0.000003 set cpo&vim
" Spawn starts an asynchronous job. See the description of go#job#Options to
" understand the args parameter.
"
" Spawn returns a job.
1 0.000001 function! go#job#Spawn(cmd, args)
let l:options = go#job#Options(a:args)
return go#job#Start(a:cmd, l:options)
endfunction
" Options returns callbacks to be used with job_start. It is abstracted to be
" used with various go commands, such as build, test, install, etc.. This
" allows us to avoid writing the same callback over and over for some
" commands. It's fully customizable so each command can change it to its own
" logic.
"
" args is a dictionary with the these keys:
" 'bang':
" Set to 0 to jump to the first error in the error list.
" Defaults to 0.
" 'statustype':
" The status type to use when updating the status.
" See statusline.vim.
" 'for':
" The g:go_list_type_command key to use to get the error list type to use.
" Errors will not be handled when the value is '_'.
" Defaults to '_job'
" 'errorformat':
" The errorformat string to use when parsing errors. Defaults to
" &errorformat.
" See :help 'errorformat'.
" 'complete':
" A function to call after the job exits and the channel is closed. The
" function will be passed three arguments: the job, its exit code, and the
" list of messages received from the channel. The default is a no-op. A
" custom value can modify the messages before they are processed by the
" returned exit_cb and close_cb callbacks. When the function is called,
" the current window will be the window that was hosting the buffer when
" the job was started. After it returns, the current window will be
" restored to what it was before the function was called.
" 'preserveerrors':
" A function that will be passed one value, the list type. It should
" return a boolean value that indicates whether any errors encountered
" should be consider additive to the existing set of errors. This is
" mostly useful for a set of commands that are run via autocmds.
"
" The return value is a dictionary with these keys:
" 'callback':
" A function suitable to be passed as a job callback handler. See
" job-callback.
" 'exit_cb':
" A function suitable to be passed as a job exit_cb handler. See
" job-exit_cb.
" 'close_cb':
" A function suitable to be passed as a job close_cb handler. See
" job-close_cb.
" 'cwd':
" The path to the directory which contains the current buffer. The
" callbacks are configured to expect this directory is the working
" directory for the job; it should not be modified by callers.
1 0.000001 function! go#job#Options(args)
let cbs = {}
let state = {
\ 'winid': win_getid(winnr()),
\ 'dir': getcwd(),
\ 'jobdir': expand("%:p:h"),
\ 'messages': [],
\ 'bang': 0,
\ 'for': "_job",
\ 'exited': 0,
\ 'exit_status': 0,
\ 'closed': 0,
\ 'errorformat': &errorformat,
\ 'statustype' : '',
\ }
let cbs.cwd = state.jobdir
if has_key(a:args, 'bang')
let state.bang = a:args.bang
endif
if has_key(a:args, 'for')
let state.for = a:args.for
endif
if has_key(a:args, 'statustype')
let state.statustype = a:args.statustype
endif
if has_key(a:args, 'errorformat')
let state.errorformat = a:args.errorformat
endif
if has_key(a:args, 'preserveerrors')
let state.preserveerrors = a:args.preserveerrors
endif
function state.complete(job, exit_status, data)
if has_key(self, 'custom_complete')
let l:winid = win_getid(winnr())
" Always set the active window to the window that was active when the job
" was started. Among other things, this makes sure that the correct
" window's location list will be populated when the list type is
" 'location' and the user has moved windows since starting the job.
call win_gotoid(self.winid)
call self.custom_complete(a:job, a:exit_status, a:data)
call win_gotoid(l:winid)
endif
call self.show_errors(a:job, a:exit_status, a:data)
endfunction
function state.show_status(job, exit_status) dict
if self.statustype == ''
return
endif
if go#config#EchoCommandInfo()
let prefix = '[' . self.statustype . '] '
if a:exit_status == 0
call go#util#EchoSuccess(prefix . "SUCCESS")
else
call go#util#EchoError(prefix . "FAIL")
endif
endif
let status = {
\ 'desc': 'last status',
\ 'type': self.statustype,
\ 'state': "success",
\ }
if a:exit_status
let status.state = "failed"
endif
if has_key(self, 'started_at')
let elapsed_time = reltimestr(reltime(self.started_at))
" strip whitespace
let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
let status.state .= printf(" (%ss)", elapsed_time)
endif
call go#statusline#Update(self.jobdir, status)
endfunction
if has_key(a:args, 'complete')
let state.custom_complete = a:args.complete
endif
" explicitly bind _start to state so that within it, self will
" always refer to state. See :help Partial for more information.
"
" _start is intended only for internal use and should not be referenced
" outside of this file.
let cbs._start = function('s:start', [''], state)
" explicitly bind callback to state so that within it, self will
" always refer to state. See :help Partial for more information.
let cbs.callback = function('s:callback', [], state)
" explicitly bind exit_cb to state so that within it, self will always refer
" to state. See :help Partial for more information.
let cbs.exit_cb = function('s:exit_cb', [], state)
" explicitly bind close_cb to state so that within it, self will
" always refer to state. See :help Partial for more information.
let cbs.close_cb = function('s:close_cb', [], state)
function state.show_errors(job, exit_status, data)
if self.for == '_'
return
endif
let l:winid = win_getid(winnr())
" Always set the active window to the window that was active when the job
" was started. Among other things, this makes sure that the correct
" window's location list will be populated when the list type is
" 'location' and the user has moved windows since starting the job.
call win_gotoid(self.winid)
let l:listtype = go#list#Type(self.for)
let l:preserveerrors = 0
if has_key(self, 'preserveerrors')
let l:preserveerrors = self.preserveerrors(l:listtype)
endif
if a:exit_status == 0
if !l:preserveerrors
call go#list#Clean(l:listtype)
call win_gotoid(l:winid)
endif
return
endif
let l:listtype = go#list#Type(self.for)
if len(a:data) == 0
if !l:preserveerrors
call go#list#Clean(l:listtype)
call win_gotoid(l:winid)
endif
return
endif
let out = join(self.messages, "\n")
try
" parse the errors relative to self.jobdir
call go#util#Chdir(self.jobdir)
call go#list#ParseFormat(l:listtype, self.errorformat, out, self.for, l:preserveerrors)
let errors = go#list#Get(l:listtype)
finally
call go#util#Chdir(self.dir)
endtry
if empty(errors)
" failed to parse errors, output the original content
call go#util#EchoError([self.dir] + self.messages)
call win_gotoid(l:winid)
return
endif
" only open the error window if user was still in the window from which
" the job was started.
if self.winid == l:winid
call go#list#Window(l:listtype, len(errors))
if self.bang
call win_gotoid(l:winid)
else
call go#list#JumpToFirst(l:listtype)
endif
endif
endfunction
return cbs
endfunction
1 0.000001 function! s:start(args) dict
if go#config#EchoCommandInfo() && self.statustype != ""
let prefix = '[' . self.statustype . '] '
call go#util#EchoSuccess(prefix . "dispatched")
endif
if self.statustype != ''
let status = {
\ 'desc': 'current status',
\ 'type': self.statustype,
\ 'state': "started",
\ }
call go#statusline#Update(self.jobdir, status)
endif
let self.started_at = reltime()
endfunction
1 0.000001 function! s:callback(chan, msg) dict
call add(self.messages, a:msg)
endfunction
1 0.000001 function! s:exit_cb(job, exitval) dict
let self.exit_status = a:exitval
let self.exited = 1
call self.show_status(a:job, a:exitval)
if self.closed || has('nvim')
call self.complete(a:job, self.exit_status, self.messages)
endif
endfunction
1 0.000001 function! s:close_cb(ch) dict
let self.closed = 1
if self.exited
let job = ch_getjob(a:ch)
call self.complete(job, self.exit_status, self.messages)
endif
endfunction
" go#job#Start runs a job. The options are expected to be the options
" suitable for Vim8 jobs. When called from Neovim, Vim8 options will be
" transformed to their Neovim equivalents.
1 0.000001 function! go#job#Start(cmd, options)
let l:options = copy(a:options)
if has('nvim')
let l:options = s:neooptions(l:options)
endif
" Verify that the working directory for the job actually exists. Return
" early if the directory does not exist. This helps avoid errors when
" working with plugins that use virtual files that don't actually exist on
" the file system.
let l:filedir = expand("%:p:h")
if has_key(l:options, 'cwd') && !isdirectory(l:options.cwd)
return
elseif !isdirectory(l:filedir)
return
endif
let l:manualcd = 0
if !has_key(l:options, 'cwd')
" pre start
let l:manualcd = 1
let l:dir = go#util#Chdir(filedir)
endif
if has_key(l:options, '_start')
call l:options._start()
" remove _start to play nicely with vim (when vim encounters an unexpected
" job option it reports an "E475: invalid argument" error).
unlet l:options._start
endif
" noblock was added in 8.1.350; remove it if it's not supported.
if has_key(l:options, 'noblock') && (has('nvim') || !has("patch-8.1.350"))
call remove(l:options, 'noblock')
endif
if go#util#HasDebug('shell-commands')
call go#util#EchoInfo('job command: ' . string(a:cmd))
endif
if has('nvim')
let l:input = []
if has_key(a:options, 'in_io') && a:options.in_io ==# 'file' && !empty(a:options.in_name)
let l:input = readfile(a:options.in_name, "b")
endif
let job = jobstart(a:cmd, l:options)
if len(l:input) > 0
call chansend(job, l:input)
" close stdin to signal that no more bytes will be sent.
call chanclose(job, 'stdin')
endif
else
let l:cmd = a:cmd
if go#util#IsWin()
let l:cmd = join(map(copy(a:cmd), function('s:winjobarg')), " ")
endif
let job = job_start(l:cmd, l:options)
endif
if l:manualcd
" post start
call go#util#Chdir(l:dir)
endif
return job
endfunction
" s:neooptions returns a dictionary of job options suitable for use by Neovim
" based on a dictionary of job options suitable for Vim8.
1 0.000001 function! s:neooptions(options)
let l:options = {}
let l:options['stdout_buf'] = ''
let l:options['stderr_buf'] = ''
let l:err_mode = get(a:options, 'err_mode', get(a:options, 'mode', ''))
let l:out_mode = get(a:options, 'out_mode', get(a:options, 'mode', ''))
for key in keys(a:options)
if key == 'cwd'
let l:options['cwd'] = a:options['cwd']
continue
endif
if key == 'callback'
let l:options['callback'] = a:options['callback']
if !has_key(a:options, 'out_cb')
let l:options['on_stdout'] = function('s:callback2on_stdout', [l:out_mode], l:options)
endif
if !has_key(a:options, 'err_cb')
let l:options['on_stderr'] = function('s:callback2on_stderr', [l:err_mode], l:options)
endif
continue
endif
if key == 'out_cb'
let l:options['out_cb'] = a:options['out_cb']
let l:options['on_stdout'] = function('s:on_stdout', [l:out_mode], l:options)
continue
endif
if key == 'err_cb'
let l:options['err_cb'] = a:options['err_cb']
let l:options['on_stderr'] = function('s:on_stderr', [l:err_mode], l:options)
continue
endif
if key == 'exit_cb'
let l:options['exit_cb'] = a:options['exit_cb']
let l:options['on_exit'] = function('s:on_exit', [], l:options)
continue
endif
if key == 'close_cb'
continue
endif
if key == 'stoponexit'
if a:options['stoponexit'] == ''
let l:options['detach'] = 1
endif
continue
endif
endfor
return l:options
endfunction
1 0.000001 function! s:callback2on_stdout(mode, ch, data, event) dict
let self.stdout_buf = s:neocb(a:mode, a:ch, self.stdout_buf, a:data, self.callback)
endfunction
1 0.000001 function! s:callback2on_stderr(mode, ch, data, event) dict
let self.stderr_buf = s:neocb(a:mode, a:ch, self.stderr_buf, a:data, self.callback)
endfunction
1 0.000001 function! s:on_stdout(mode, ch, data, event) dict
let self.stdout_buf = s:neocb(a:mode, a:ch, self.stdout_buf, a:data, self.out_cb)
endfunction
1 0.000001 function! s:on_stderr(mode, ch, data, event) dict
let self.stderr_buf = s:neocb(a:mode, a:ch, self.stderr_buf, a:data, self.err_cb )
endfunction
1 0.000001 function! s:on_exit(jobid, exitval, event) dict
call self.exit_cb(a:jobid, a:exitval)
endfunction
1 0.000001 function! go#job#Stop(job) abort
if has('nvim')
call jobstop(a:job)
return
endif
call job_stop(a:job)
call go#job#Wait(a:job)
return
endfunction
1 0.000001 function! go#job#Wait(job) abort
if has('nvim')
call jobwait([a:job])
return
endif
while job_status(a:job) is# 'run'
sleep 50m
endwhile
endfunction
1 0.000001 function! s:winjobarg(idx, val) abort
if empty(a:val)
return '""'
endif
return a:val
endfunction
1 0.000001 function! s:neocb(mode, ch, buf, data, callback)
" dealing with the channel lines of Neovim is awful. The docs (:help
" channel-lines) say:
" stream event handlers may receive partial (incomplete) lines. For a
" given invocation of on_stdout etc, `a:data` is not guaranteed to end
" with a newline.
" - `abcdefg` may arrive as `['abc']`, `['defg']`.
" - `abc\nefg` may arrive as `['abc', '']`, `['efg']` or `['abc']`,
" `['','efg']`, or even `['ab']`, `['c','efg']`.
"
" Thankfully, though, this is explained a bit better in an issue:
" https://github.com/neovim/neovim/issues/3555. Specifically in these two
" comments:
" * https://github.com/neovim/neovim/issues/3555#issuecomment-152290804
" * https://github.com/neovim/neovim/issues/3555#issuecomment-152588749
"
" The key is
" Every item in the list passed to job control callbacks represents a
" string after a newline(Except the first, of course). If the program
" outputs: "hello\nworld" the corresponding list is ["hello", "world"].
" If the program outputs "hello\nworld\n", the corresponding list is
" ["hello", "world", ""]. In other words, you can always determine if
" the last line received is complete or not.
" and
" for every list you receive in a callback, all items except the first
" represent newlines.
let l:buf = ''
" A single empty string means EOF was reached. The first item will never be
" an empty string except for when it's the only item and is signaling that
" EOF was reached.
if len(a:data) == 1 && a:data[0] == ''
" when there's nothing buffered, return early so that an
" erroneous message will not be added.
if a:buf == ''
return ''
endif
let l:data = [a:buf]
else
let l:data = copy(a:data)
let l:data[0] = a:buf . l:data[0]
" The last element may be a partial line; save it for next time.
if a:mode != 'raw'
let l:buf = l:data[-1]
let l:data = l:data[:-2]
endif
endif
let l:i = 0
let l:last = len(l:data) - 1
while l:i <= l:last
let l:msg = l:data[l:i]
if a:mode == 'raw' && l:i < l:last
let l:msg = l:msg . "\n"
endif
call a:callback(a:ch, l:msg)
let l:i += 1
endwhile
return l:buf
endfunction
" restore Vi compatibility settings
1 0.000002 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp/message.vim
Sourced 1 time
Total time: 0.000426
Self time: 0.000426
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000008 let s:cpo_save = &cpo
1 0.000005 set cpo&vim
1 0.000002 function! go#lsp#message#Initialize(wd) abort
return {
\ 'notification': 0,
\ 'method': 'initialize',
\ 'params': {
\ 'processId': getpid(),
\ 'rootUri': go#path#ToURI(a:wd),
\ 'capabilities': {
\ 'workspace': {
\ 'workspaceFolders': v:true,
\ 'didChangeConfiguration': {
\ 'dynamicRegistration': v:true,
\ },
\ 'workspaceEdit': {
\ 'documentChanges': v:true,
\ },
\ 'configuration': v:true,
\ },
\ 'textDocument': {
\ 'hover': {
\ 'contentFormat': ['plaintext'],
\ },
\ 'completion': {
\ 'completionItem': {
\ 'snippetSupport': go#config#GoplsUsePlaceholders() ? v:true : v:false,
\ },
\ },
\ 'codeAction': {
\ 'codeActionLiteralSupport': {
\ 'codeActionKind': {
\ 'valueSet': ['source.organizeImports', 'refactor.rewrite'],
\ },
\ },
\ },
\ }
\ },
\ 'workspaceFolders': [s:workspaceFolder(0, a:wd)],
\ }
\ }
endfunction
1 0.000002 function! go#lsp#message#Initialized() abort
return {
\ 'notification': 1,
\ 'method': 'initialized',
\ 'params': {},
\ }
endfunction
1 0.000001 function! go#lsp#message#Shutdown() abort
return {
\ 'notification': 0,
\ 'method': 'shutdown',
\ }
endfunction
1 0.000001 function! go#lsp#message#Format(file) abort
return {
\ 'notification': 0,
\ 'method': 'textDocument/formatting',
\ 'params': {
\ 'textDocument': {
\ 'uri': go#path#ToURI(a:file)
\ },
\ 'options': {
\ 'insertSpaces': v:false,
\ },
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#CodeActionImports(file) abort
return s:codeAction('source.organizeImports', a:file)
endfunction
1 0.000001 function! go#lsp#message#CodeActionFillStruct(file, line, col) abort
return go#lsp#message#CodeActionRefactorRewrite(a:file, a:line, a:col, a:line, a:col)
endfunction
1 0.000002 function! go#lsp#message#CodeActionRefactorRewrite(file, startline, startcol, endline, endcol) abort
let l:startpos = s:position(a:startline, a:startcol)
let l:endpos = s:position(a:endline, a:endcol)
let l:request = s:codeAction('refactor.rewrite', a:file)
let l:request.params = extend(l:request.params,
\ {
\ 'range': {
\ 'start': l:startpos,
\ 'end': l:endpos,
\ }
\ })
return l:request
endfunction
1 0.000002 function! s:codeAction(name, file) abort
return {
\ 'notification': 0,
\ 'method': 'textDocument/codeAction',
\ 'params': {
\ 'textDocument': {
\ 'uri': go#path#ToURI(a:file)
\ },
\ 'range': {
\ 'start': s:position(0, 0),
\ 'end': s:position(line('$'), 0),
\ },
\ 'context': {
\ 'only': [a:name],
\ },
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#Exit() abort
return {
\ 'notification': 1,
\ 'method': 'exit',
\ }
endfunction
1 0.000002 function! go#lsp#message#WorkspaceFoldersResult(dirs) abort
return map(copy(a:dirs), function('s:workspaceFolder', []))
endfunction
1 0.000002 function! go#lsp#message#Definition(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
return {
\ 'notification': 0,
\ 'method': 'textDocument/definition',
\ 'params': l:params,
\ }
endfunction
1 0.000005 function! go#lsp#message#TypeDefinition(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
return {
\ 'notification': 0,
\ 'method': 'textDocument/typeDefinition',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! go#lsp#message#Implementation(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
return {
\ 'notification': 0,
\ 'method': 'textDocument/implementation',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! go#lsp#message#DidOpen(file, content, version) abort
return {
\ 'notification': 1,
\ 'method': 'textDocument/didOpen',
\ 'params': {
\ 'textDocument': {
\ 'uri': go#path#ToURI(a:file),
\ 'languageId': 'go',
\ 'text': a:content,
\ 'version': a:version,
\ }
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#DidChange(file, content, version) abort
return {
\ 'notification': 1,
\ 'method': 'textDocument/didChange',
\ 'params': {
\ 'textDocument': {
\ 'uri': go#path#ToURI(a:file),
\ 'version': a:version,
\ },
\ 'contentChanges': [
\ {
\ 'text': a:content,
\ }
\ ]
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#DidClose(file) abort
return {
\ 'notification': 1,
\ 'method': 'textDocument/didClose',
\ 'params': {
\ 'textDocument': {
\ 'uri': go#path#ToURI(a:file),
\ }
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#Completion(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
return {
\ 'notification': 0,
\ 'method': 'textDocument/completion',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! go#lsp#message#References(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
let l:params.context = {'includeDeclaration': v:true}
return {
\ 'notification': 0,
\ 'method': 'textDocument/references',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! go#lsp#message#PrepareCallHierarchy(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
return {
\ 'notification': 0,
\ 'method': 'textDocument/prepareCallHierarchy',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! go#lsp#message#IncomingCalls(item) abort
return {
\ 'notification': 0,
\ 'method': 'callHierarchy/incomingCalls',
\ 'params': {
\ 'item': a:item,
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#Hover(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
return {
\ 'notification': 0,
\ 'method': 'textDocument/hover',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! go#lsp#message#Rename(file, line, col, newName) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
let l:params.newName = a:newName
return {
\ 'notification': 0,
\ 'method': 'textDocument/rename',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! go#lsp#message#ChangeWorkspaceFolders(add, remove) abort
let l:addDirs = map(copy(a:add), function('s:workspaceFolder', []))
let l:removeDirs = map(copy(a:remove), function('s:workspaceFolder', []))
return {
\ 'notification': 1,
\ 'method': 'workspace/didChangeWorkspaceFolders',
\ 'params': {
\ 'event': {
\ 'removed': l:removeDirs,
\ 'added': l:addDirs,
\ },
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#ConfigurationResult(items) abort
let l:result = []
" results must be in the same order as the items
for l:item in a:items
let l:workspace = go#path#FromURI(l:item.scopeUri)
let l:config = {
\ 'buildFlags': [],
\ 'hoverKind': 'Structured',
\ }
let l:buildtags = go#config#BuildTags()
if buildtags isnot ''
let l:config.buildFlags = extend(l:config.buildFlags, ['-tags', go#config#BuildTags()])
endif
let l:deepCompletion = go#config#GoplsDeepCompletion()
let l:matcher = go#config#GoplsMatcher()
let l:completeUnimported = go#config#GoplsCompleteUnimported()
let l:staticcheck = go#config#GoplsStaticCheck()
let l:usePlaceholder = go#config#GoplsUsePlaceholders()
let l:tempModfile = go#config#GoplsTempModfile()
let l:analyses = go#config#GoplsAnalyses()
let l:local = go#config#GoplsLocal()
if type(l:local) is v:t_dict
let l:local = get(l:local, l:workspace, v:null)
endif
let l:gofumpt = go#config#GoplsGofumpt()
let l:settings = go#config#GoplsSettings()
if l:deepCompletion isnot v:null
if l:deepCompletion
let l:config.deepCompletion = v:true
else
let l:config.deepCompletion = v:false
endif
endif
if l:matcher isnot v:null
let l:config.matcher = l:matcher
endif
if l:completeUnimported isnot v:null
if l:completeUnimported
let l:config.completeUnimported = v:true
else
let l:config.completeUnimported = v:false
endif
endif
if l:staticcheck isnot v:null
if l:staticcheck
let l:config.staticcheck = v:true
else
let l:config.staticcheck = v:false
endif
endif
if l:usePlaceholder isnot v:null
if l:usePlaceholder
let l:config.usePlaceholders = v:true
else
let l:config.usePlaceholders = v:false
endif
endif
if l:tempModfile isnot v:null
if l:tempModfile
let l:config.tempModfile = v:true
else
let l:config.tempModfile = v:false
endif
endif
if l:analyses isnot v:null
let l:config.analyses = l:analyses
endif
if l:local isnot v:null
let l:config.local = l:local
endif
if l:gofumpt isnot v:null
if l:gofumpt
let l:config.gofumpt = v:true
else
let l:config.gofumpt = v:false
endif
endif
if l:settings isnot v:null
let l:config = extend(l:config, l:settings, 'keep')
endif
let l:result = add(l:result, deepcopy(l:config))
endfor
return l:result
endfunction
1 0.000001 function! go#lsp#message#ExecuteCommand(cmd, args) abort
return {
\ 'notification': 0,
\ 'method': 'workspace/executeCommand',
\ 'params': {
\ 'command': a:cmd,
\ 'arguments': a:args,
\ }
\ }
endfunction
1 0.000001 function! go#lsp#message#ApplyWorkspaceEditResponse(ok) abort
return {
\ 'applied': a:ok,
\ }
endfunction
1 0.000001 function! go#lsp#message#PrepareRename(file, line, col) abort
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
return {
\ 'notification': 0,
\ 'method': 'textDocument/prepareRename',
\ 'params': l:params,
\ }
endfunction
1 0.000001 function! s:workspaceFolder(key, val) abort
return {'uri': go#path#ToURI(a:val), 'name': a:val}
endfunction
1 0.000001 function! s:position(line, col) abort
return {'line': a:line, 'character': a:col}
endfunction
1 0.000001 function! s:textDocumentPositionParams(fname, line, col) abort
return {
\ 'textDocument': {
\ 'uri': go#path#ToURI(a:fname)
\ },
\ 'position': s:position(a:line, a:col),
\ }
endfunction
" restore Vi compatibility settings
1 0.000003 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/uri.vim
Sourced 1 time
Total time: 0.000334
Self time: 0.000334
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000003 let s:cpo_save = &cpo
1 0.000003 set cpo&vim
1 0.000001 function! go#uri#Encode(value) abort
return s:encode(a:value, '[^A-Za-z0-9_.~-]')
endfunction
1 0.000001 function! go#uri#EncodePath(value) abort
let l:separator = '/'
if go#util#IsWin()
let l:separator = '\\'
endif
return s:encode(a:value, '[^' . l:separator . 'A-Za-z0-9_.~-]')
endfunction
1 0.000001 function! s:encode(value, unreserved)
return substitute(
\ a:value,
\ a:unreserved,
\ '\=s:encodechar(submatch(0))',
\ 'g'
\)
endfunction
1 0.000001 function! go#uri#Decode(value) abort
return substitute(
\ a:value,
\ '%\(\x\x\)',
\ '\=s:decodehex(submatch(1))',
\ 'g'
\)
endfunction
1 0.000001 function! s:encodechar(value)
let l:idx = 0
let l:encoded = ''
while l:idx < strlen(a:value)
let l:byte = strpart(a:value, l:idx, 1)
let l:encoded = printf('%s%%%02X', l:encoded, char2nr(l:byte))
let l:idx += 1
endwhile
return l:encoded
endfunction
1 0.000001 function! s:decodehex(value)
return eval(printf('"\x%s"', a:value))
endfunction
" restore Vi compatibility settings
1 0.000003 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/statusline.vim
Sourced 1 time
Total time: 0.000356
Self time: 0.000356
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000006 let s:cpo_save = &cpo
1 0.000011 set cpo&vim
" Statusline
""""""""""""""""""""""""""""""""
" s:statuses is a global reference to all statuses. It stores the statuses per
" import paths (map[string]status), where each status is unique per its
" type. Current status dict is in form:
" {
" 'desc' : 'Job description',
" 'state' : 'Job state, such as success, failure, etc..',
" 'type' : 'Job type, such as build, test, etc..'
" 'created_at' : 'Time it was created as seconds since 1st Jan 1970'
" }
1 0.000001 let s:statuses = {}
" timer_id for cleaner
1 0.000001 let s:timer_id = 0
" last_status stores the last generated text per status
1 0.000001 let s:last_status = ""
" Show returns the current status of the job for 20 seconds (configurable). It
" displays it in form of 'desc: [type|state]' if there is any state available,
" if not it returns an empty string. This function should be plugged directly
" into the statusline.
1 0.000002 function! go#statusline#Show() abort
" lazy initialization of the cleaner
if !s:timer_id
let interval = go#config#StatuslineDuration()
let s:timer_id = timer_start(interval, function('go#statusline#Clear'), {'repeat': -1})
endif
" nothing to show
if empty(s:statuses)
return ''
endif
let status_dir = expand('%:p:h')
if !has_key(s:statuses, status_dir)
return ''
endif
let status = s:statuses[status_dir]
if !has_key(status, 'desc') || !has_key(status, 'state') || !has_key(status, 'type')
return ''
endif
let status_text = printf("[%s|%s]", status.type, status.state)
if empty(status_text)
return ''
endif
" only update highlight if status has changed.
if status_text != s:last_status
if status.state =~ "success" || status.state =~ "finished" || status.state =~ "pass" || status.state =~ 'initialized'
hi goStatusLineColor cterm=bold ctermbg=76 ctermfg=22 guibg=#5fd700 guifg=#005f00
elseif status.state =~ "started" || status.state =~ "analysing" || status.state =~ "compiling" || status.state =~ 'initializing'
hi goStatusLineColor cterm=bold ctermbg=208 ctermfg=88 guibg=#ff8700 guifg=#870000
elseif status.state =~ "failed"
hi goStatusLineColor cterm=bold ctermbg=196 ctermfg=52 guibg=#ff0000 guifg=#5f0000
endif
endif
let s:last_status = status_text
return status_text
endfunction
" Update updates (adds) the statusline for the given status_dir with the
" given status dict. It overrides any previously set status.
1 0.000002 function! go#statusline#Update(status_dir, status) abort
let a:status.created_at = reltime()
let s:statuses[a:status_dir] = a:status
" force to update the statusline, otherwise the user needs to move the
" cursor
exe 'let &ro = &ro'
" before we stop the timer, check if we have any previous jobs to be cleaned
" up. Otherwise every job will reset the timer when this function is called
" and thus old jobs will never be cleaned
call s:clear()
" also reset the timer, so the user has time to see it in the statusline.
" Setting the timer_id to 0 will cause a new timer to be created the next
" time the go#statusline#Show() is called.
call timer_stop(s:timer_id)
let s:timer_id = 0
endfunction
" Clear clears all currently stored statusline data. The timer_id argument is
" just a placeholder so we can pass it to a timer_start() function if needed.
1 0.000001 function! go#statusline#Clear(timer_id) abort
call s:clear()
endfunction
1 0.000001 function! s:clear()
for [status_dir, status] in items(s:statuses)
let elapsed_time = reltimestr(reltime(status.created_at))
" strip whitespace
let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
if str2nr(elapsed_time) > 10
call remove(s:statuses, status_dir)
endif
endfor
if len(s:statuses) == 0
let s:statuses = {}
endif
" force to update the statusline, otherwise the user needs to move the
" cursor
exe 'let &ro = &ro'
endfunction
" restore Vi compatibility settings
1 0.000003 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/auto.vim
Sourced 1 time
Total time: 0.000242
Self time: 0.000242
count total (s) self (s)
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000007 let s:cpo_save = &cpo
1 0.000006 set cpo&vim
1 0.000002 function! go#auto#template_autocreate()
if !go#config#TemplateAutocreate() || !&modifiable
return
endif
" create new template from scratch
call go#template#create()
endfunction
1 0.000001 function! go#auto#complete_done()
if &omnifunc isnot 'go#complete#Complete'
return
endif
call s:echo_go_info()
call s:ExpandSnippet()
endfunction
1 0.000001 function! s:ExpandSnippet() abort
if !exists('v:completed_item') || empty(v:completed_item) || !go#config#GoplsUsePlaceholders()
return
endif
let l:engine = go#config#SnippetEngine()
if l:engine is 'ultisnips'
if !get(g:, 'did_plugin_ultisnips', 0)
return
endif
" the snippet may have a '{\}' in it. For UltiSnips, that should be spelled
" \{}. fmt.Printf is such a snippet that can be used to demonstrate.
let l:snippet = substitute(v:completed_item.word, '{\\}', '\{}', 'g')
call UltiSnips#Anon(l:snippet, v:completed_item.word, '', 'i')
" elseif l:engine is 'neosnippet'
" " TODO(bc): make the anonymous expansion for neosnippet work
"
" if !get(g:, 'loaded_neosnippet') is 1
" return
" endif
"
" " neosnippet#anonymous doesn't need a trigger, so replace the
" " completed_item.word with an empty string before calling neosnippet#anonymous
" let l:snippet = substitute(v:completed_item.word, '{\\}', '\{\}', 'g')
" call setline('.', substitute(getline('.'), substitute(v:completed_item.word, '\', '\\', 'g'), '', ''))
" call neosnippet#anonymous(l:snippet)
endif
endfunction
1 0.000001 function! s:echo_go_info()
if !go#config#EchoGoInfo()
return
endif
if !exists('v:completed_item') || empty(v:completed_item)
return
endif
let item = v:completed_item
if !has_key(item, "user_data")
return
endif
if empty(item.user_data)
return
endif
redraws! | echo "vim-go: " | echohl Function | echon item.user_data | echohl None
endfunction
1 0.000001 let s:timer_id = 0
" go#auto#update_autocmd() will be called on BufEnter,CursorHold. This
" configures the augroup according to conditions below.
"
" | # | has_timer | should_enable | do |
" |---|-----------|---------------|------------------------------------|
" | 1 | false | false | return early |
" | 2 | true | true | return early |
" | 3 | true | false | clear the group and stop the timer |
" | 4 | false | true | configure the group |
1 0.000001 function! go#auto#update_autocmd()
let has_timer = get(b:, 'has_timer')
let should_enable = go#config#AutoTypeInfo() || go#config#AutoSameids()
if (!has_timer && !should_enable) || (has_timer && should_enable)
return
endif
if has_timer
augroup vim-go-buffer-auto
autocmd! * <buffer>
augroup END
let b:has_timer = 0
call s:timer_stop()
return
endif
augroup vim-go-buffer-auto
autocmd! * <buffer>
autocmd CursorMoved <buffer> call s:timer_restart()
autocmd BufLeave <buffer> call s:timer_stop()
augroup END
let b:has_timer = 1
call s:timer_start()
endfunction
1 0.000001 function! s:timer_restart()
if isdirectory(expand('%:p:h'))
call s:timer_stop()
call s:timer_start()
endif
endfunction
1 0.000000 function! s:timer_stop()
if s:timer_id
call timer_stop(s:timer_id)
let s:timer_id = 0
endif
endfunction
1 0.000001 function! s:timer_start()
let s:timer_id = timer_start(go#config#Updatetime(), function('s:handler'))
endfunction
1 0.000001 function! s:handler(timer_id)
if go#config#AutoTypeInfo()
call go#tool#Info(0)
endif
if go#config#AutoSameids()
call go#guru#SameIds(0)
endif
let s:timer_id = 0
endfunction
1 0.000001 function! go#auto#fmt_autosave()
if !(isdirectory(expand('%:p:h')) && expand('<afile>:p') == expand('%:p'))
return
endif
if !(go#config#FmtAutosave() || go#config#ImportsAutosave())
return
endif
" Order matters when formatting and adjusting imports, because of gopls'
" support for gofumpt. Gofumpt formatting will group all imports that look
" like a stdlib package (e.g. there's no '.' in the package path) together.
" When the local setting is provided, the only way to get the local imports
" grouped separately when gofumpt is used to format is to format first and
" then organize imports.
if go#config#FmtAutosave() && !(go#config#ImportsAutosave() && go#config#ImportsMode() == 'goimports')
call go#fmt#Format(0)
" return early when the imports mode is goimports, because there's no need
" to format again when goimports was run
if go#config#FmtCommand() == 'goimports'
return
endif
endif
if !go#config#ImportsAutosave()
return
endif
call go#fmt#Format(1)
endfunction
1 0.000001 function! go#auto#metalinter_autosave()
if !go#config#MetalinterAutosave() || !isdirectory(expand('%:p:h'))
return
endif
" run gometalinter on save
call go#lint#Gometa(!g:go_jump_to_error, 1)
endfunction
1 0.000001 function! go#auto#modfmt_autosave()
if !(go#config#ModFmtAutosave() && isdirectory(expand('%:p:h')) && expand('<afile>:p') == expand('%:p'))
return
endif
" go.mod code formatting on save
call go#mod#Format()
endfunction
1 0.000000 function! go#auto#asmfmt_autosave()
if !(go#config#AsmfmtAutosave() && isdirectory(expand('%:p:h')) && expand('<afile>:p') == expand('%:p'))
return
endif
" Go asm formatting on save
call go#asmfmt#Format()
endfunction
" restore Vi compatibility settings
1 0.000003 let &cpo = s:cpo_save
1 0.000001 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/bingo.vim
Sourced 2 times
Total time: 0.000490
Self time: 0.000234
count total (s) self (s)
" Author: Jerko Steiner <https://github.com/jeremija>
" Description: https://github.com/saibing/bingo
2 0.000026 0.000013 call ale#Set('go_bingo_executable', 'bingo')
2 0.000012 0.000005 call ale#Set('go_bingo_options', '--mode stdio')
2 0.000003 function! ale_linters#go#bingo#GetCommand(buffer) abort
return ale#go#EnvString(a:buffer) . '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
endfunction
2 0.000002 function! ale_linters#go#bingo#FindProjectRoot(buffer) abort
let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
let l:project_root = l:go_modules_off ?
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:mods = ':h'
if empty(l:project_root)
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
let l:mods = ':h:h'
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : ''
endfunction
2 0.000267 0.000030 call ale#linter#Define('go', {
\ 'name': 'bingo',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'go_bingo_executable')},
\ 'command': function('ale_linters#go#bingo#GetCommand'),
\ 'project_root': function('ale_linters#go#bingo#FindProjectRoot'),
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/cspell.vim
Sourced 2 times
Total time: 0.001478
Self time: 0.000786
count total (s) self (s)
2 0.000005 scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: cspell support for Go files.
2 0.001376 0.000684 call ale#handlers#cspell#DefineLinter('go')
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/handlers/cspell.vim
Sourced 1 time
Total time: 0.000341
Self time: 0.000341
count total (s) self (s)
1 0.000002 scriptencoding utf-8
" Author: David Houston <houstdav000>
" Description: Define a handler function for cspell's output
1 0.000002 function! ale#handlers#cspell#GetExecutable(buffer) abort
return ale#path#FindExecutable(a:buffer,
\ 'cspell', [
\ 'node_modules/.bin/cspell',
\ 'node_modules/cspell/bin.js',
\ ]
\)
endfunction
1 0.000001 function! ale#handlers#cspell#GetCommand(buffer) abort
let l:executable = ale#handlers#cspell#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'cspell_options')
return ale#node#Executable(a:buffer, l:executable)
\ . ' lint --no-color --no-progress --no-summary'
\ . ale#Pad(l:options)
\ . ' -- stdin'
endfunction
1 0.000001 function! ale#handlers#cspell#Handle(buffer, lines) abort
" Look for lines like the following:
"
" /home/user/repos/ale/README.md:723:48 - Unknown word (stylelint)
let l:pattern = '\v^.*:(\d+):(\d+) - (.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': 'W',
\})
endfor
return l:output
endfunction
1 0.000001 function! ale#handlers#cspell#DefineLinter(filetype) abort
call ale#Set('cspell_executable', 'cspell')
call ale#Set('cspell_options', '')
call ale#Set('cspell_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#linter#Define(a:filetype, {
\ 'name': 'cspell',
\ 'executable': function('ale#handlers#cspell#GetExecutable'),
\ 'command': function('ale#handlers#cspell#GetCommand'),
\ 'callback': 'ale#handlers#cspell#Handle',
\})
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gobuild.vim
Sourced 2 times
Total time: 0.000434
Self time: 0.000183
count total (s) self (s)
" Author: Joshua Rubin <joshua@rubixconsulting.com>, Ben Reedy <https://github.com/breed808>,
" Jeff Willette <jrwillette88@gmail.com>
" Description: go build for Go files
" inspired by work from dzhou121 <dzhou121@gmail.com>
2 0.000020 0.000010 call ale#Set('go_go_executable', 'go')
2 0.000011 0.000004 call ale#Set('go_gobuild_options', '')
2 0.000003 function! ale_linters#go#gobuild#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_gobuild_options')
" Run go test in local directory with relative path
return ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' test'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -c -o /dev/null ./'
endfunction
2 0.000002 function! ale_linters#go#gobuild#GetMatches(lines) abort
" Matches patterns like the following:
"
" file.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args
" file.go:53:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
" file.go:5:2: expected declaration, found 'STRING' "log"
" go test returns relative paths so use tail of filename as part of pattern matcher
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? (.+)$'
return ale#util#GetMatches(a:lines, l:pattern)
endfunction
2 0.000002 function! ale_linters#go#gobuild#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = []
for l:match in ale_linters#go#gobuild#GetMatches(a:lines)
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4],
\ 'type': 'E',
\})
endfor
return l:output
endfunction
2 0.000262 0.000028 call ale#linter#Define('go', {
\ 'name': 'gobuild',
\ 'aliases': ['go build'],
\ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#gobuild#GetCommand'),
\ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#go#gobuild#Handler',
\ 'lint_file': 1,
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gofmt.vim
Sourced 2 times
Total time: 0.000332
Self time: 0.000113
count total (s) self (s)
" Author: neersighted <bjorn@neersighted.com>
" Description: gofmt for Go files
2 0.000006 function! ale_linters#go#gofmt#GetCommand(buffer) abort
return ale#go#EnvString(a:buffer)
\ . '%e -e %t'
endfunction
2 0.000240 0.000022 call ale#linter#Define('go', {
\ 'name': 'gofmt',
\ 'output_stream': 'stderr',
\ 'executable': 'gofmt',
\ 'command': function('ale_linters#go#gofmt#GetCommand'),
\ 'callback': 'ale#handlers#unix#HandleAsError',
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/golangci_lint.vim
Sourced 2 times
Total time: 0.000506
Self time: 0.000167
count total (s) self (s)
" Author: Sascha Grunert <mail@saschagrunert.de>
" Description: Adds support of golangci-lint
2 0.000046 0.000015 call ale#Set('go_golangci_lint_options', '--enable-all')
2 0.000012 0.000005 call ale#Set('go_golangci_lint_executable', 'golangci-lint')
2 0.000013 0.000004 call ale#Set('go_golangci_lint_package', 0)
2 0.000003 function! ale_linters#go#golangci_lint#GetCommand(buffer) abort
let l:filename = expand('#' . a:buffer . ':t')
let l:options = ale#Var(a:buffer, 'go_golangci_lint_options')
let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package')
if l:lint_package
return ale#go#EnvString(a:buffer)
\ . '%e run '
\ . l:options
endif
return ale#go#EnvString(a:buffer)
\ . '%e run '
\ . ale#Escape(l:filename)
\ . ' ' . l:options
endfunction
2 0.000002 function! ale_linters#go#golangci_lint#GetMatches(lines) abort
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:?:?:?\s\*?(.+)$'
return ale#util#GetMatches(a:lines, l:pattern)
endfunction
2 0.000002 function! ale_linters#go#golangci_lint#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = []
for l:match in ale_linters#go#golangci_lint#GetMatches(a:lines)
" l:match[1] will already be an absolute path, output from
" golangci_lint
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': 'E',
\ 'text': l:match[4],
\})
endfor
return l:output
endfunction
2 0.000319 0.000027 call ale#linter#Define('go', {
\ 'name': 'golangci-lint',
\ 'executable': {b -> ale#Var(b, 'go_golangci_lint_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#golangci_lint#GetCommand'),
\ 'callback': 'ale_linters#go#golangci_lint#Handler',
\ 'lint_file': 1,
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/golint.vim
Sourced 2 times
Total time: 0.000500
Self time: 0.000271
count total (s) self (s)
" Author: neersighted <bjorn@neersighted.com>
" Description: golint for Go files
2 0.000182 0.000172 call ale#Set('go_golint_executable', 'golint')
2 0.000010 0.000004 call ale#Set('go_golint_options', '')
2 0.000003 function! ale_linters#go#golint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_golint_options')
return ale#go#EnvString(a:buffer) . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t'
endfunction
2 0.000235 0.000021 call ale#linter#Define('go', {
\ 'name': 'golint',
\ 'output_stream': 'both',
\ 'executable': {b -> ale#Var(b, 'go_golint_executable')},
\ 'command': function('ale_linters#go#golint#GetCommand'),
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gometalinter.vim
Sourced 2 times
Total time: 0.000396
Self time: 0.000133
count total (s) self (s)
" Author: Ben Reedy <https://github.com/breed808>, Jeff Willette <jrwillette88@gmail.com>
" Description: Adds support for the gometalinter suite for Go files
2 0.000020 0.000010 call ale#Set('go_gometalinter_options', '')
2 0.000014 0.000007 call ale#Set('go_gometalinter_executable', 'gometalinter')
2 0.000010 0.000004 call ale#Set('go_gometalinter_lint_package', 0)
2 0.000003 function! ale_linters#go#gometalinter#GetCommand(buffer) abort
let l:filename = expand('#' . a:buffer . ':t')
let l:options = ale#Var(a:buffer, 'go_gometalinter_options')
let l:lint_package = ale#Var(a:buffer, 'go_gometalinter_lint_package')
" BufferCdString is used so that we can be sure the paths output from gometalinter can
" be calculated to absolute paths in the Handler
if l:lint_package
return ale#go#EnvString(a:buffer)
\ . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif
return ale#go#EnvString(a:buffer)
\ . '%e'
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endfunction
2 0.000002 function! ale_linters#go#gometalinter#GetMatches(lines) abort
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:?:?(warning|error):?\s\*?(.+)$'
return ale#util#GetMatches(a:lines, l:pattern)
endfunction
2 0.000002 function! ale_linters#go#gometalinter#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = []
for l:match in ale_linters#go#gometalinter#GetMatches(a:lines)
" l:match[1] will already be an absolute path, output from gometalinter
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': tolower(l:match[4]) is# 'warning' ? 'W' : 'E',
\ 'text': l:match[5],
\})
endfor
return l:output
endfunction
2 0.000263 0.000022 call ale#linter#Define('go', {
\ 'name': 'gometalinter',
\ 'executable': {b -> ale#Var(b, 'go_gometalinter_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#gometalinter#GetCommand'),
\ 'callback': 'ale_linters#go#gometalinter#Handler',
\ 'lint_file': 1,
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gopls.vim
Sourced 2 times
Total time: 0.000408
Self time: 0.000159
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Author: Jerko Steiner <https://github.com/jeremija>
" Description: https://github.com/saibing/gopls
2 0.000030 0.000021 call ale#Set('go_gopls_executable', 'gopls')
2 0.000011 0.000005 call ale#Set('go_gopls_options', '--mode stdio')
2 0.000010 0.000005 call ale#Set('go_gopls_init_options', {})
2 0.000011 0.000005 call ale#Set('go_gopls_use_global', get(g:, 'ale_use_global_executables', 0))
2 0.000002 function! ale_linters#go#gopls#GetCommand(buffer) abort
return ale#go#EnvString(a:buffer)
\ . '%e'
\ . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
endfunction
2 0.000002 function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
let l:project_root = l:go_modules_off ?
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:mods = ':h'
if empty(l:project_root)
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
let l:mods = ':h:h'
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : ''
endfunction
2 0.000253 0.000030 call ale#linter#Define('go', {
\ 'name': 'gopls',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#path#FindExecutable(b, 'go_gopls', [
\ ale#go#GetGoPathExecutable('bin/gopls'),
\ ])},
\ 'command': function('ale_linters#go#gopls#GetCommand'),
\ 'project_root': function('ale_linters#go#gopls#FindProjectRoot'),
\ 'initialization_options': {b -> ale#Var(b, 'go_gopls_init_options')},
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gosimple.vim
Sourced 2 times
Total time: 0.000344
Self time: 0.000119
count total (s) self (s)
" Author: Ben Reedy <https://github.com/breed808>
" Description: gosimple for Go files
2 0.000276 0.000052 call ale#linter#Define('go', {
\ 'name': 'gosimple',
\ 'executable': 'gosimple',
\ 'cwd': '%s:h',
\ 'command': {b -> ale#go#EnvString(b) . 'gosimple .'},
\ 'callback': 'ale#handlers#go#Handler',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gotype.vim
Sourced 2 times
Total time: 0.000341
Self time: 0.000099
count total (s) self (s)
" Author: Jelte Fennema <github-public@jeltef.nl>
" Description: gotype for Go files
2 0.000004 function! ale_linters#go#gotype#GetExecutable(buffer) abort
if expand('#' . a:buffer . ':p') =~# '_test\.go$'
return ''
endif
return 'gotype'
endfunction
2 0.000002 function! ale_linters#go#gotype#GetCommand(buffer) abort
return ale#go#EnvString(a:buffer) . 'gotype -e .'
endfunction
2 0.000266 0.000024 call ale#linter#Define('go', {
\ 'name': 'gotype',
\ 'output_stream': 'stderr',
\ 'executable': function('ale_linters#go#gotype#GetExecutable'),
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#gotype#GetCommand'),
\ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1,
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/govet.vim
Sourced 2 times
Total time: 0.000329
Self time: 0.000093
count total (s) self (s)
" Author: neersighted <bjorn@neersighted.com>
" Description: go vet for Go files
"
" Author: John Eikenberry <jae@zhar.net>
" Description: updated to work with go1.10
2 0.000019 0.000010 call ale#Set('go_go_executable', 'go')
2 0.000011 0.000004 call ale#Set('go_govet_options', '')
2 0.000003 function! ale_linters#go#govet#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_govet_options')
return ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' vet '
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' .'
endfunction
2 0.000244 0.000025 call ale#linter#Define('go', {
\ 'name': 'govet',
\ 'aliases': ['go vet'],
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#govet#GetCommand'),
\ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1,
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/langserver.vim
Sourced 2 times
Total time: 0.000330
Self time: 0.000098
count total (s) self (s)
" Author: Horacio Sanson <https://github.com/hsanson>
" Description: Support for go-langserver https://github.com/sourcegraph/go-langserver
2 0.000017 0.000008 call ale#Set('go_langserver_executable', 'go-langserver')
2 0.000010 0.000004 call ale#Set('go_langserver_options', '')
2 0.000002 function! ale_linters#go#langserver#GetCommand(buffer) abort
let l:executable = [ale#Escape(ale#Var(a:buffer, 'go_langserver_executable'))]
let l:options = ale#Var(a:buffer, 'go_langserver_options')
let l:options = substitute(l:options, '-gocodecompletion', '', 'g')
let l:options = filter(split(l:options, ' '), 'empty(v:val) != 1')
if ale#Var(a:buffer, 'completion_enabled')
call add(l:options, '-gocodecompletion')
endif
let l:options = uniq(sort(l:options))
let l:env = ale#go#EnvString(a:buffer)
return l:env . join(extend(l:executable, l:options), ' ')
endfunction
2 0.000238 0.000021 call ale#linter#Define('go', {
\ 'name': 'golangserver',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'go_langserver_executable')},
\ 'command': function('ale_linters#go#langserver#GetCommand'),
\ 'project_root': function('ale#go#FindProjectRoot'),
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/revive.vim
Sourced 2 times
Total time: 0.000356
Self time: 0.000109
count total (s) self (s)
" Author: Penghui Liao <liaoishere@gmail.com>
" Description: Adds support for revive
2 0.000020 0.000010 call ale#Set('go_revive_executable', 'revive')
2 0.000010 0.000004 call ale#Set('go_revive_options', '')
2 0.000003 function! ale_linters#go#revive#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_revive_options')
return ale#go#EnvString(a:buffer) . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t'
endfunction
2 0.000252 0.000021 call ale#linter#Define('go', {
\ 'name': 'revive',
\ 'output_stream': 'both',
\ 'executable': {b -> ale#Var(b, 'go_revive_executable')},
\ 'command': function('ale_linters#go#revive#GetCommand'),
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/staticcheck.vim
Sourced 2 times
Total time: 0.000379
Self time: 0.000144
count total (s) self (s)
" Author: Ben Reedy <https://github.com/breed808>
" Description: staticcheck for Go files
2 0.000025 0.000010 call ale#Set('go_staticcheck_executable', 'staticcheck')
2 0.000012 0.000006 call ale#Set('go_staticcheck_options', '')
2 0.000010 0.000004 call ale#Set('go_staticcheck_lint_package', 1)
2 0.000011 0.000006 call ale#Set('go_staticcheck_use_global', get(g:, 'ale_use_global_executables', 0))
2 0.000002 function! ale_linters#go#staticcheck#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
let l:env = ale#go#EnvString(a:buffer)
if l:lint_package
return l:env . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif
return l:env . '%e'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %s:t'
endfunction
2 0.000228 0.000025 call ale#linter#Define('go', {
\ 'name': 'staticcheck',
\ 'executable': {b -> ale#path#FindExecutable(b, 'go_staticcheck', [
\ ale#go#GetGoPathExecutable('bin/staticcheck'),
\ ])},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#staticcheck#GetCommand'),
\ 'callback': 'ale#handlers#go#Handler',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim
Sourced 1 time
Total time: 0.000612
Self time: 0.000612
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Backend execution and job management
" Executes linters in the background, using NeoVim or Vim 8 jobs
" Remapping of linter problems.
1 0.000003 let g:ale_type_map = get(g:, 'ale_type_map', {})
1 0.000003 let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {})
1 0.000001 if !has_key(s:, 'executable_cache_map')
1 0.000001 let s:executable_cache_map = {}
1 0.000000 endif
1 0.000001 function! ale#engine#CleanupEveryBuffer() abort
for l:key in keys(g:ale_buffer_info)
" The key could be a filename or a buffer number, so try and
" convert it to a number. We need a number for the other
" functions.
let l:buffer = str2nr(l:key)
if l:buffer > 0
" Stop all jobs and clear the results for everything, and delete
" all of the data we stored for the buffer.
call ale#engine#Cleanup(l:buffer)
endif
endfor
endfunction
1 0.000001 function! ale#engine#MarkLinterActive(info, linter) abort
let l:found = 0
for l:other_linter in a:info.active_linter_list
if l:other_linter.name is# a:linter.name
let l:found = 1
break
endif
endfor
if !l:found
call add(a:info.active_linter_list, a:linter)
endif
endfunction
1 0.000001 function! ale#engine#MarkLinterInactive(info, linter_name) abort
call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter_name')
endfunction
1 0.000001 function! ale#engine#ResetExecutableCache() abort
let s:executable_cache_map = {}
endfunction
" Check if files are executable, and if they are, remember that they are
" for subsequent calls. We'll keep checking until programs can be executed.
1 0.000001 function! ale#engine#IsExecutable(buffer, executable) abort
if empty(a:executable)
" Don't log the executable check if the executable string is empty.
return 0
endif
" Check for a cached executable() check.
let l:result = get(s:executable_cache_map, a:executable, v:null)
if l:result isnot v:null
return l:result
endif
" Check if the file is executable, and convert -1 to 1.
let l:result = executable(a:executable) isnot 0
" Cache the executable check if we found it, or if the option to cache
" failing checks is on.
if l:result || get(g:, 'ale_cache_executable_check_failures', 0)
let s:executable_cache_map[a:executable] = l:result
endif
if g:ale_history_enabled
call ale#history#Add(a:buffer, l:result, 'executable', a:executable)
endif
return l:result
endfunction
1 0.000001 function! ale#engine#InitBufferInfo(buffer) abort
if !has_key(g:ale_buffer_info, a:buffer)
" active_linter_list will hold the list of active linter names
" loclist holds the loclist items after all jobs have completed.
let g:ale_buffer_info[a:buffer] = {
\ 'active_linter_list': [],
\ 'active_other_sources_list': [],
\ 'loclist': [],
\}
return 1
endif
return 0
endfunction
" This function is documented and part of the public API.
"
" Return 1 if ALE is busy checking a given buffer
1 0.000001 function! ale#engine#IsCheckingBuffer(buffer) abort
let l:info = get(g:ale_buffer_info, a:buffer, {})
return !empty(get(l:info, 'active_linter_list', []))
\ || !empty(get(l:info, 'active_other_sources_list', []))
endfunction
1 0.000001 function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort
let l:info = get(g:ale_buffer_info, a:buffer, {})
if empty(l:info)
return
endif
if !a:from_other_source
" Remove this linter from the list of active linters.
" This may have already been done when the job exits.
call filter(l:info.active_linter_list, 'v:val.name isnot# a:linter_name')
endif
" Make some adjustments to the loclists to fix common problems, and also
" to set default values for loclist items.
let l:linter_loclist = ale#engine#FixLocList(
\ a:buffer,
\ a:linter_name,
\ a:from_other_source,
\ a:loclist,
\)
" Remove previous items for this linter.
call filter(l:info.loclist, 'v:val.linter_name isnot# a:linter_name')
" We don't need to add items or sort the list when this list is empty.
if !empty(l:linter_loclist)
" Add the new items.
call extend(l:info.loclist, l:linter_loclist)
" Sort the loclist again.
" We need a sorted list so we can run a binary search against it
" for efficient lookup of the messages in the cursor handler.
call sort(l:info.loclist, 'ale#util#LocItemCompare')
endif
if ale#ShouldDoNothing(a:buffer)
return
endif
call ale#engine#SetResults(a:buffer, l:info.loclist)
endfunction
1 0.000001 function! s:HandleExit(job_info, buffer, output, data) abort
let l:buffer_info = get(g:ale_buffer_info, a:buffer)
if empty(l:buffer_info)
return
endif
let l:linter = a:job_info.linter
let l:executable = a:job_info.executable
" Remove this job from the list.
call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name)
" Stop here if we land in the handle for a job completing if we're in
" a sandbox.
if ale#util#InSandbox()
return
endif
if has('nvim') && !empty(a:output) && empty(a:output[-1])
call remove(a:output, -1)
endif
try
let l:loclist = ale#util#GetFunction(l:linter.callback)(a:buffer, a:output)
" Handle the function being unknown, or being deleted.
catch /E700/
let l:loclist = []
endtry
call ale#engine#HandleLoclist(l:linter.name, a:buffer, l:loclist, 0)
endfunction
1 0.000001 function! ale#engine#SetResults(buffer, loclist) abort
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
" Set signs first. This could potentially fix some line numbers.
" The List could be sorted again here by SetSigns.
if g:ale_set_signs
call ale#sign#SetSigns(a:buffer, a:loclist)
endif
if g:ale_set_quickfix || g:ale_set_loclist
call ale#list#SetLists(a:buffer, a:loclist)
endif
if exists('*ale#statusline#Update')
" Don't load/run if not already loaded.
call ale#statusline#Update(a:buffer, a:loclist)
endif
if g:ale_set_highlights
call ale#highlight#SetHighlights(a:buffer, a:loclist)
endif
if l:linting_is_done
if g:ale_echo_cursor
" Try and echo the warning now.
" This will only do something meaningful if we're in normal mode.
call ale#cursor#EchoCursorWarning()
endif
if g:ale_virtualtext_cursor
" Try and show the warning now.
" This will only do something meaningful if we're in normal mode.
call ale#virtualtext#ShowCursorWarning()
endif
" Reset the save event marker, used for opening windows, etc.
call setbufvar(a:buffer, 'ale_save_event_fired', 0)
" Set a marker showing how many times a buffer has been checked.
call setbufvar(
\ a:buffer,
\ 'ale_linted',
\ getbufvar(a:buffer, 'ale_linted', 0) + 1
\)
" Automatically remove all managed temporary files and directories
" now that all jobs have completed.
call ale#command#RemoveManagedFiles(a:buffer)
" Call user autocommands. This allows users to hook into ALE's lint cycle.
silent doautocmd <nomodeline> User ALELintPost
endif
endfunction
1 0.000001 function! s:RemapItemTypes(type_map, loclist) abort
for l:item in a:loclist
let l:key = l:item.type
\ . (get(l:item, 'sub_type', '') is# 'style' ? 'S' : '')
let l:new_key = get(a:type_map, l:key, '')
if l:new_key is# 'E'
\|| l:new_key is# 'ES'
\|| l:new_key is# 'W'
\|| l:new_key is# 'WS'
\|| l:new_key is# 'I'
let l:item.type = l:new_key[0]
if l:new_key is# 'ES' || l:new_key is# 'WS'
let l:item.sub_type = 'style'
elseif has_key(l:item, 'sub_type')
call remove(l:item, 'sub_type')
endif
endif
endfor
endfunction
1 0.000001 function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) abort
let l:mappings = ale#GetFilenameMappings(a:buffer, a:linter_name)
if !empty(l:mappings)
" We need to apply reverse filename mapping here.
let l:mappings = ale#filename_mapping#Invert(l:mappings)
endif
let l:bufnr_map = {}
let l:new_loclist = []
" Some errors have line numbers beyond the end of the file,
" so we need to adjust them so they set the error at the last line
" of the file instead.
let l:last_line_number = ale#util#GetLineCount(a:buffer)
for l:old_item in a:loclist
" Copy the loclist item with some default values and corrections.
"
" line and column numbers will be converted to numbers.
" The buffer will default to the buffer being checked.
" The vcol setting will default to 0, a byte index.
" The error type will default to 'E' for errors.
" The error number will default to -1.
"
" The line number and text are the only required keys.
"
" The linter_name will be set on the errors so it can be used in
" output, filtering, etc..
let l:item = {
\ 'bufnr': a:buffer,
\ 'text': l:old_item.text,
\ 'lnum': str2nr(l:old_item.lnum),
\ 'col': str2nr(get(l:old_item, 'col', 0)),
\ 'vcol': 0,
\ 'type': get(l:old_item, 'type', 'E'),
\ 'nr': get(l:old_item, 'nr', -1),
\ 'linter_name': a:linter_name,
\}
if a:from_other_source
let l:item.from_other_source = 1
endif
if has_key(l:old_item, 'code')
let l:item.code = l:old_item.code
endif
let l:old_name = get(l:old_item, 'filename', '')
" Map parsed from output to local filesystem files.
if !empty(l:old_name) && !empty(l:mappings)
let l:old_name = ale#filename_mapping#Map(l:old_name, l:mappings)
endif
if !empty(l:old_name) && !ale#path#IsTempName(l:old_name)
" Use the filename given.
" Temporary files are assumed to be for this buffer,
" and the filename is not included then, because it looks bad
" in the loclist window.
let l:filename = l:old_name
let l:item.filename = l:filename
if has_key(l:old_item, 'bufnr')
" If a buffer number is also given, include that too.
" If Vim detects that he buffer number is valid, it will
" be used instead of the filename.
let l:item.bufnr = l:old_item.bufnr
elseif has_key(l:bufnr_map, l:filename)
" Get the buffer number from the map, which can be faster.
let l:item.bufnr = l:bufnr_map[l:filename]
else
" Look up the buffer number.
let l:item.bufnr = bufnr(l:filename)
let l:bufnr_map[l:filename] = l:item.bufnr
endif
elseif has_key(l:old_item, 'bufnr')
let l:item.bufnr = l:old_item.bufnr
endif
if has_key(l:old_item, 'detail')
let l:item.detail = l:old_item.detail
endif
" Pass on a end_col key if set, used for highlights.
if has_key(l:old_item, 'end_col')
let l:item.end_col = str2nr(l:old_item.end_col)
endif
if has_key(l:old_item, 'end_lnum')
let l:item.end_lnum = str2nr(l:old_item.end_lnum)
endif
if has_key(l:old_item, 'sub_type')
let l:item.sub_type = l:old_item.sub_type
endif
if l:item.lnum < 1
" When errors appear before line 1, put them at line 1.
let l:item.lnum = 1
elseif l:item.bufnr == a:buffer && l:item.lnum > l:last_line_number
" When errors go beyond the end of the file, put them at the end.
" This is only done for the current buffer.
let l:item.lnum = l:last_line_number
elseif get(l:old_item, 'vcol', 0)
" Convert virtual column positions to byte positions.
" The positions will be off if the buffer has changed recently.
let l:line = getbufline(a:buffer, l:item.lnum)[0]
let l:item.col = ale#util#Col(l:line, l:item.col)
if has_key(l:item, 'end_col')
let l:end_line = get(l:item, 'end_lnum', l:line) != l:line
\ ? getbufline(a:buffer, l:item.end_lnum)[0]
\ : l:line
let l:item.end_col = ale#util#Col(l:end_line, l:item.end_col)
endif
endif
call add(l:new_loclist, l:item)
endfor
let l:type_map = get(ale#Var(a:buffer, 'type_map'), a:linter_name, {})
if !empty(l:type_map)
call s:RemapItemTypes(l:type_map, l:new_loclist)
endif
return l:new_loclist
endfunction
" Given part of a command, replace any % with %%, so that no characters in
" the string will be replaced with filenames, etc.
1 0.000001 function! ale#engine#EscapeCommandPart(command_part) abort
" TODO: Emit deprecation warning here later.
return ale#command#EscapeCommandPart(a:command_part)
endfunction
" Run a job.
"
" Returns 1 when a job was started successfully.
1 0.000001 function! s:RunJob(command, options) abort
if ale#command#IsDeferred(a:command)
let a:command.result_callback = {
\ command -> s:RunJob(command, a:options)
\}
return 1
endif
let l:command = a:command
if empty(l:command)
return 0
endif
let l:cwd = a:options.cwd
let l:executable = a:options.executable
let l:buffer = a:options.buffer
let l:linter = a:options.linter
let l:output_stream = a:options.output_stream
let l:read_buffer = a:options.read_buffer && !a:options.lint_file
let l:info = g:ale_buffer_info[l:buffer]
let l:Callback = function('s:HandleExit', [{
\ 'linter': l:linter,
\ 'executable': l:executable,
\}])
let l:result = ale#command#Run(l:buffer, l:command, l:Callback, {
\ 'cwd': l:cwd,
\ 'output_stream': l:output_stream,
\ 'executable': l:executable,
\ 'read_buffer': l:read_buffer,
\ 'log_output': 1,
\ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:linter.name),
\})
" Only proceed if the job is being run.
if empty(l:result)
return 0
endif
call ale#engine#MarkLinterActive(l:info, l:linter)
silent doautocmd <nomodeline> User ALEJobStarted
return 1
endfunction
1 0.000001 function! s:StopCurrentJobs(buffer, clear_lint_file_jobs, linter_slots) abort
let l:info = get(g:ale_buffer_info, a:buffer, {})
call ale#command#StopJobs(a:buffer, 'linter')
" Update the active linter list, clearing out anything not running.
if a:clear_lint_file_jobs
call ale#command#StopJobs(a:buffer, 'file_linter')
let l:info.active_linter_list = []
else
let l:lint_file_map = {}
" Use a previously computed map of `lint_file` values to find
" linters that are used for linting files.
for [l:lint_file, l:linter] in a:linter_slots
if l:lint_file is 1
let l:lint_file_map[l:linter.name] = 1
endif
endfor
" Keep jobs for linting files when we're only linting buffers.
call filter(l:info.active_linter_list, 'get(l:lint_file_map, v:val.name)')
endif
endfunction
1 0.000001 function! ale#engine#Stop(buffer) abort
call s:StopCurrentJobs(a:buffer, 1, [])
endfunction
1 0.000001 function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
" Figure out which linters are still enabled, and remove
" problems for linters which are no longer enabled.
" Problems from other sources will be kept.
let l:name_map = {}
for l:linter in a:linters
let l:name_map[l:linter.name] = 1
endfor
call filter(
\ get(g:ale_buffer_info[a:buffer], 'loclist', []),
\ 'get(v:val, ''from_other_source'') || get(l:name_map, get(v:val, ''linter_name''))',
\)
endfunction
1 0.000114 function! s:AddProblemsFromOtherBuffers(buffer, linters) abort
let l:filename = expand('#' . a:buffer . ':p')
let l:loclist = []
let l:name_map = {}
" Build a map of the active linters.
for l:linter in a:linters
let l:name_map[l:linter.name] = 1
endfor
" Find the items from other buffers, for the linters that are enabled.
for l:info in values(g:ale_buffer_info)
for l:item in l:info.loclist
if has_key(l:item, 'filename')
\&& l:item.filename is# l:filename
\&& has_key(l:name_map, l:item.linter_name)
" Copy the items and set the buffer numbers to this one.
let l:new_item = copy(l:item)
let l:new_item.bufnr = a:buffer
call add(l:loclist, l:new_item)
endif
endfor
endfor
if !empty(l:loclist)
call sort(l:loclist, function('ale#util#LocItemCompareWithText'))
call uniq(l:loclist, function('ale#util#LocItemCompareWithText'))
" Set the loclist variable, used by some parts of ALE.
let g:ale_buffer_info[a:buffer].loclist = l:loclist
call ale#engine#SetResults(a:buffer, l:loclist)
endif
endfunction
1 0.000001 function! s:RunIfExecutable(buffer, linter, lint_file, executable) abort
if ale#command#IsDeferred(a:executable)
let a:executable.result_callback = {
\ executable -> s:RunIfExecutable(
\ a:buffer,
\ a:linter,
\ a:lint_file,
\ executable
\ )
\}
return 1
endif
if ale#engine#IsExecutable(a:buffer, a:executable)
" Use different job types for file or linter jobs.
let l:job_type = a:lint_file ? 'file_linter' : 'linter'
call setbufvar(a:buffer, 'ale_job_type', l:job_type)
" Get the cwd for the linter and set it before we call GetCommand.
" This will ensure that ale#command#Run uses it by default.
let l:cwd = ale#linter#GetCwd(a:buffer, a:linter)
if l:cwd isnot v:null
call ale#command#SetCwd(a:buffer, l:cwd)
endif
let l:command = ale#linter#GetCommand(a:buffer, a:linter)
if l:cwd isnot v:null
call ale#command#ResetCwd(a:buffer)
endif
let l:options = {
\ 'cwd': l:cwd,
\ 'executable': a:executable,
\ 'buffer': a:buffer,
\ 'linter': a:linter,
\ 'output_stream': get(a:linter, 'output_stream', 'stdout'),
\ 'read_buffer': a:linter.read_buffer,
\ 'lint_file': a:lint_file,
\}
return s:RunJob(l:command, l:options)
endif
return 0
endfunction
" Run a linter for a buffer.
"
" Returns 1 if the linter was successfully run.
1 0.000001 function! s:RunLinter(buffer, linter, lint_file) abort
if !empty(a:linter.lsp)
return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter)
else
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
return s:RunIfExecutable(a:buffer, a:linter, a:lint_file, l:executable)
endif
return 0
endfunction
1 0.000001 function! s:GetLintFileSlots(buffer, linters) abort
let l:linter_slots = []
for l:linter in a:linters
let l:LintFile = l:linter.lint_file
if type(l:LintFile) is v:t_func
let l:LintFile = l:LintFile(a:buffer)
endif
call add(l:linter_slots, [l:LintFile, l:linter])
endfor
return l:linter_slots
endfunction
1 0.000001 function! s:GetLintFileValues(slots, Callback) abort
let l:deferred_list = []
let l:new_slots = []
for [l:lint_file, l:linter] in a:slots
while ale#command#IsDeferred(l:lint_file) && has_key(l:lint_file, 'value')
" If we've already computed the return value, use it.
let l:lint_file = l:lint_file.value
endwhile
if ale#command#IsDeferred(l:lint_file)
" If we are going to return the result later, wait for it.
call add(l:deferred_list, l:lint_file)
else
" If we have the value now, coerce it to 0 or 1.
let l:lint_file = l:lint_file is 1
endif
call add(l:new_slots, [l:lint_file, l:linter])
endfor
if !empty(l:deferred_list)
for l:deferred in l:deferred_list
let l:deferred.result_callback =
\ {-> s:GetLintFileValues(l:new_slots, a:Callback)}
endfor
else
call a:Callback(l:new_slots)
endif
endfunction
1 0.000002 function! s:RunLinters(
\ buffer,
\ linters,
\ slots,
\ should_lint_file,
\ new_buffer,
\) abort
call s:StopCurrentJobs(a:buffer, a:should_lint_file, a:slots)
call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
" We can only clear the results if we aren't checking the buffer.
let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer)
silent doautocmd <nomodeline> User ALELintPre
for [l:lint_file, l:linter] in a:slots
" Only run lint_file linters if we should.
if !l:lint_file || a:should_lint_file
if s:RunLinter(a:buffer, l:linter, l:lint_file)
" If a single linter ran, we shouldn't clear everything.
let l:can_clear_results = 0
endif
else
" If we skipped running a lint_file linter still in the list,
" we shouldn't clear everything.
let l:can_clear_results = 0
endif
endfor
" Clear the results if we can. This needs to be done when linters are
" disabled, or ALE itself is disabled.
if l:can_clear_results
call ale#engine#SetResults(a:buffer, [])
elseif a:new_buffer
call s:AddProblemsFromOtherBuffers(
\ a:buffer,
\ map(copy(a:slots), 'v:val[1]')
\)
endif
endfunction
1 0.000001 function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
" Initialise the buffer information if needed.
let l:new_buffer = ale#engine#InitBufferInfo(a:buffer)
call s:GetLintFileValues(
\ s:GetLintFileSlots(a:buffer, a:linters),
\ {
\ slots -> s:RunLinters(
\ a:buffer,
\ a:linters,
\ slots,
\ a:should_lint_file,
\ l:new_buffer,
\ )
\ }
\)
endfunction
" Clean up a buffer.
"
" This function will stop all current jobs for the buffer,
" clear the state of everything, and remove the Dictionary for managing
" the buffer.
1 0.000001 function! ale#engine#Cleanup(buffer) abort
" Don't bother with cleanup code when newer NeoVim versions are exiting.
if get(v:, 'exiting', v:null) isnot v:null
return
endif
if exists('*ale#lsp#CloseDocument')
call ale#lsp#CloseDocument(a:buffer)
endif
if !has_key(g:ale_buffer_info, a:buffer)
return
endif
call ale#engine#RunLinters(a:buffer, [], 1)
call remove(g:ale_buffer_info, a:buffer)
endfunction
" Given a buffer number, return the warnings and errors for a given buffer.
1 0.000001 function! ale#engine#GetLoclist(buffer) abort
if !has_key(g:ale_buffer_info, a:buffer)
return []
endif
return g:ale_buffer_info[a:buffer].loclist
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim
Sourced 1 time
Total time: 0.000283
Self time: 0.000283
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Functions for formatting command strings, running commands, and
" managing files during linting and fixing cycles.
" This dictionary holds lists of files and directories to remove later.
1 0.000002 if !exists('s:buffer_data')
1 0.000001 let s:buffer_data = {}
1 0.000000 endif
" The regular expression used for formatting filenames with modifiers.
1 0.000001 let s:path_format_regex = '\v\%s(%(:h|:t|:r|:e)*)'
" Used to get the data in tests.
1 0.000001 function! ale#command#GetData() abort
return deepcopy(s:buffer_data)
endfunction
1 0.000001 function! ale#command#ClearData() abort
let s:buffer_data = {}
endfunction
1 0.000001 function! ale#command#InitData(buffer) abort
if !has_key(s:buffer_data, a:buffer)
let s:buffer_data[a:buffer] = {
\ 'jobs': {},
\ 'file_list': [],
\ 'directory_list': [],
\}
endif
endfunction
" Set the cwd for commands that are about to run.
" Used internally.
1 0.000001 function! ale#command#SetCwd(buffer, cwd) abort
call ale#command#InitData(a:buffer)
let s:buffer_data[a:buffer].cwd = a:cwd
endfunction
1 0.000000 function! ale#command#ResetCwd(buffer) abort
if has_key(s:buffer_data, a:buffer)
let s:buffer_data[a:buffer].cwd = v:null
endif
endfunction
1 0.000001 function! ale#command#ManageFile(buffer, file) abort
call ale#command#InitData(a:buffer)
call add(s:buffer_data[a:buffer].file_list, a:file)
endfunction
1 0.000001 function! ale#command#ManageDirectory(buffer, directory) abort
call ale#command#InitData(a:buffer)
call add(s:buffer_data[a:buffer].directory_list, a:directory)
endfunction
1 0.000001 function! ale#command#CreateFile(buffer) abort
" This variable can be set to 1 in tests to stub this out.
if get(g:, 'ale_create_dummy_temporary_file')
return 'TEMP'
endif
let l:temporary_file = ale#util#Tempname()
call ale#command#ManageFile(a:buffer, l:temporary_file)
return l:temporary_file
endfunction
" Create a new temporary directory and manage it in one go.
1 0.000001 function! ale#command#CreateDirectory(buffer) abort
" This variable can be set to 1 in tests to stub this out.
if get(g:, 'ale_create_dummy_temporary_file')
return 'TEMP_DIR'
endif
let l:temporary_directory = ale#util#Tempname()
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:temporary_directory, '', 0750)
call ale#command#ManageDirectory(a:buffer, l:temporary_directory)
return l:temporary_directory
endfunction
1 0.000001 function! ale#command#RemoveManagedFiles(buffer) abort
let l:info = get(s:buffer_data, a:buffer, {})
if !empty(l:info) && empty(l:info.jobs)
" We can't delete anything in a sandbox, so wait until we escape from
" it to delete temporary files and directories.
if ale#util#InSandbox()
return
endif
" Delete files with a call akin to a plan `rm` command.
for l:filename in l:info.file_list
call delete(l:filename)
endfor
" Delete directories like `rm -rf`.
" Directories are handled differently from files, so paths that are
" intended to be single files can be set up for automatic deletion
" without accidentally deleting entire directories.
for l:directory in l:info.directory_list
call delete(l:directory, 'rf')
endfor
call remove(s:buffer_data, a:buffer)
endif
endfunction
1 0.000001 function! ale#command#CreateTempFile(buffer, temporary_file, input) abort
if empty(a:temporary_file)
" There is no file, so we didn't create anything.
return 0
endif
" Use an existing list of lines of input if we have it, or get the lines
" from the file.
let l:lines = a:input isnot v:null ? a:input : getbufline(a:buffer, 1, '$')
let l:temporary_directory = fnamemodify(a:temporary_file, ':h')
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:temporary_directory, '', 0750)
" Automatically delete the directory later.
call ale#command#ManageDirectory(a:buffer, l:temporary_directory)
" Write the buffer out to a file.
call ale#util#Writefile(a:buffer, l:lines, a:temporary_file)
return 1
endfunction
1 0.000001 function! s:TemporaryFilename(buffer) abort
let l:filename = fnamemodify(bufname(a:buffer), ':t')
if empty(l:filename)
" If the buffer's filename is empty, create a dummy filename.
let l:ft = getbufvar(a:buffer, '&filetype')
let l:filename = 'file' . ale#filetypes#GuessExtension(l:ft)
endif
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
return ale#util#Tempname() . (has('win32') ? '\' : '/') . l:filename
endfunction
" Given part of a command, replace any % with %%, so that no characters in
" the string will be replaced with filenames, etc.
1 0.000001 function! ale#command#EscapeCommandPart(command_part) abort
return substitute(a:command_part, '%', '%%', 'g')
endfunction
" Format a filename, converting it with filename mappings, if non-empty,
" and escaping it for putting into a command string.
"
" The filename can be modified.
1 0.000001 function! s:FormatFilename(filename, mappings, modifiers) abort
let l:filename = a:filename
if !empty(a:mappings)
let l:filename = ale#filename_mapping#Map(l:filename, a:mappings)
endif
if !empty(a:modifiers)
let l:filename = fnamemodify(l:filename, a:modifiers)
endif
return ale#Escape(l:filename)
endfunction
" Produce a command prefix to check to a particular directory for a command.
" %s format markers with filename-modifiers can be used as the directory, and
" will be returned verbatim for formatting in paths relative to files.
1 0.000001 function! ale#command#CdString(directory) abort
let l:match = matchstrpos(a:directory, s:path_format_regex)
" Do not escape the directory here if it's a valid format string.
" This allows us to use sequences like %s:h, %s:h:h, etc.
let l:directory = l:match[1:] == [0, len(a:directory)]
\ ? a:directory
\ : ale#Escape(a:directory)
if has('win32')
return 'cd /d ' . l:directory . ' && '
endif
return 'cd ' . l:directory . ' && '
endfunction
" Given a command string, replace every...
" %s -> with the current filename
" %t -> with the name of an unused file in a temporary directory
" %% -> with a literal %
1 0.000003 function! ale#command#FormatCommand(
\ buffer,
\ executable,
\ command,
\ pipe_file_if_needed,
\ input,
\ cwd,
\ mappings,
\) abort
let l:temporary_file = ''
let l:command = a:command
if !empty(a:cwd)
let l:command = ale#command#CdString(a:cwd) . l:command
endif
" First replace all uses of %%, used for literal percent characters,
" with an ugly string.
let l:command = substitute(l:command, '%%', '<<PERCENTS>>', 'g')
" Replace %e with the escaped executable, if available.
if !empty(a:executable) && l:command =~# '%e'
let l:command = substitute(l:command, '%e', '\=ale#Escape(a:executable)', 'g')
endif
" Replace all %s occurrences in the string with the name of the current
" file.
if l:command =~# '%s'
let l:filename = fnamemodify(bufname(a:buffer), ':p')
let l:command = substitute(
\ l:command,
\ s:path_format_regex,
\ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))',
\ 'g'
\)
endif
if a:input isnot v:false && l:command =~# '%t'
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
let l:temporary_file = s:TemporaryFilename(a:buffer)
let l:command = substitute(
\ l:command,
\ '\v\%t(%(:h|:t|:r|:e)*)',
\ '\=s:FormatFilename(l:temporary_file, a:mappings, submatch(1))',
\ 'g'
\)
endif
" Finish formatting so %% becomes %.
let l:command = substitute(l:command, '<<PERCENTS>>', '%', 'g')
if a:pipe_file_if_needed && empty(l:temporary_file)
" If we are to send the Vim buffer to a command, we'll do it
" in the shell. We'll write out the file to a temporary file,
" and then read it back in, in the shell.
let l:temporary_file = s:TemporaryFilename(a:buffer)
let l:command = l:command . ' < ' . ale#Escape(l:temporary_file)
endif
let l:file_created = ale#command#CreateTempFile(
\ a:buffer,
\ l:temporary_file,
\ a:input,
\)
return [l:temporary_file, l:command, l:file_created]
endfunction
1 0.000001 function! ale#command#StopJobs(buffer, job_type) abort
let l:info = get(s:buffer_data, a:buffer, {})
if !empty(l:info)
let l:new_map = {}
for [l:job_id, l:job_type] in items(l:info.jobs)
let l:job_id = str2nr(l:job_id)
if a:job_type is# 'all' || a:job_type is# l:job_type
call ale#job#Stop(l:job_id)
else
let l:new_map[l:job_id] = l:job_type
endif
endfor
let l:info.jobs = l:new_map
endif
endfunction
1 0.000001 function! s:GatherOutput(line_list, job_id, line) abort
call add(a:line_list, a:line)
endfunction
1 0.000001 function! s:ExitCallback(buffer, line_list, Callback, data) abort
if !has_key(s:buffer_data, a:buffer)
return
endif
let l:jobs = s:buffer_data[a:buffer].jobs
if !has_key(l:jobs, a:data.job_id)
return
endif
let l:job_type = remove(l:jobs, a:data.job_id)
if g:ale_history_enabled
call ale#history#SetExitCode(a:buffer, a:data.job_id, a:data.exit_code)
" Log the output of the command for ALEInfo if we should.
if g:ale_history_log_output && a:data.log_output is 1
call ale#history#RememberOutput(
\ a:buffer,
\ a:data.job_id,
\ a:line_list[:]
\)
endif
endif
" If the callback starts any new jobs, use the same job type for them.
call setbufvar(a:buffer, 'ale_job_type', l:job_type)
let l:value = a:Callback(a:buffer, a:line_list, {
\ 'exit_code': a:data.exit_code,
\ 'temporary_file': a:data.temporary_file,
\})
let l:result = a:data.result
let l:result.value = l:value
" Set the default cwd for this buffer in this call stack.
call ale#command#SetCwd(a:buffer, l:result.cwd)
try
if get(l:result, 'result_callback', v:null) isnot v:null
call call(l:result.result_callback, [l:value])
endif
finally
call ale#command#ResetCwd(a:buffer)
endtry
endfunction
1 0.000001 function! ale#command#Run(buffer, command, Callback, ...) abort
let l:options = get(a:000, 0, {})
if len(a:000) > 1
throw 'Too many arguments!'
endif
let l:output_stream = get(l:options, 'output_stream', 'stdout')
let l:line_list = []
let l:cwd = get(l:options, 'cwd', v:null)
if l:cwd is v:null
" Default the working directory to whatever it was for the last
" command run in the chain.
let l:cwd = get(get(s:buffer_data, a:buffer, {}), 'cwd', v:null)
endif
let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand(
\ a:buffer,
\ get(l:options, 'executable', ''),
\ a:command,
\ get(l:options, 'read_buffer', 0),
\ get(l:options, 'input', v:null),
\ l:cwd,
\ get(l:options, 'filename_mappings', []),
\)
let l:command = ale#job#PrepareCommand(a:buffer, l:command)
let l:job_options = {
\ 'exit_cb': {job_id, exit_code -> s:ExitCallback(
\ a:buffer,
\ l:line_list,
\ a:Callback,
\ {
\ 'job_id': job_id,
\ 'exit_code': exit_code,
\ 'temporary_file': l:temporary_file,
\ 'log_output': get(l:options, 'log_output', 1),
\ 'result': l:result,
\ }
\ )},
\ 'mode': 'nl',
\}
if l:output_stream is# 'stdout'
let l:job_options.out_cb = function('s:GatherOutput', [l:line_list])
elseif l:output_stream is# 'stderr'
let l:job_options.err_cb = function('s:GatherOutput', [l:line_list])
elseif l:output_stream is# 'both'
let l:job_options.out_cb = function('s:GatherOutput', [l:line_list])
let l:job_options.err_cb = function('s:GatherOutput', [l:line_list])
endif
let l:status = 'failed'
if get(g:, 'ale_run_synchronously') == 1
if get(g:, 'ale_emulate_job_failure') == 1
let l:job_id = 0
else
" Generate a fake job ID for tests.
let s:fake_job_id = get(s:, 'fake_job_id', 0) + 1
let l:job_id = s:fake_job_id
endif
elseif has('win32')
let l:job_id = ale#job#StartWithCmd(l:command, l:job_options)
else
let l:job_id = ale#job#Start(l:command, l:job_options)
endif
if l:job_id
let l:status = 'started'
let l:job_type = getbufvar(a:buffer, 'ale_job_type', 'all')
call ale#command#InitData(a:buffer)
let s:buffer_data[a:buffer].jobs[l:job_id] = l:job_type
endif
if g:ale_history_enabled
call ale#history#Add(a:buffer, l:status, l:job_id, l:command)
endif
if !l:job_id
return 0
endif
" We'll return this Dictionary. A `result_callback` can be assigned to it
" later for capturing the result of a:Callback.
"
" The `_deferred_job_id` is used for both checking the type of object, and
" for checking the job ID and status.
"
" The cwd is kept and used as the default value for the next command in
" the chain.
"
" The original command here is used in tests.
let l:result = {
\ '_deferred_job_id': l:job_id,
\ 'executable': get(l:options, 'executable', ''),
\ 'cwd': l:cwd,
\ 'command': a:command,
\}
if get(g:, 'ale_run_synchronously') == 1 && l:job_id
if !exists('g:ale_run_synchronously_callbacks')
let g:ale_run_synchronously_callbacks = []
endif
if get(g:, 'ale_run_synchronously_emulate_commands', 0)
call add(
\ g:ale_run_synchronously_callbacks,
\ {exit_code, output -> [
\ extend(l:line_list, output),
\ l:job_options.exit_cb(l:job_id, exit_code),
\ ]}
\)
else
" Run a command synchronously if this test option is set.
call extend(l:line_list, systemlist(
\ type(l:command) is v:t_list
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
\ : l:command
\))
" Don't capture output when the callbacks aren't set.
if !has_key(l:job_options, 'out_cb')
\&& !has_key(l:job_options, 'err_cb')
let l:line_list = []
endif
call add(
\ g:ale_run_synchronously_callbacks,
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)}
\)
endif
endif
return l:result
endfunction
1 0.000001 function! ale#command#IsDeferred(value) abort
return type(a:value) is v:t_dict && has_key(a:value, '_deferred_job_id')
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/history.vim
Sourced 1 time
Total time: 0.000169
Self time: 0.000169
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Tools for managing command history
" A flag for controlling the maximum size of the command history to store.
1 0.000003 let g:ale_max_buffer_history_size = get(g:, 'ale_max_buffer_history_size', 20)
" Return a shallow copy of the command history for a given buffer number.
1 0.000001 function! ale#history#Get(buffer) abort
return copy(getbufvar(a:buffer, 'ale_history', []))
endfunction
1 0.000001 function! ale#history#Add(buffer, status, job_id, command) abort
if g:ale_max_buffer_history_size <= 0
" Don't save anything if the history isn't a positive number.
call setbufvar(a:buffer, 'ale_history', [])
return
endif
let l:history = getbufvar(a:buffer, 'ale_history', [])
" Remove the first item if we hit the max history size.
if len(l:history) >= g:ale_max_buffer_history_size
let l:history = l:history[1:]
endif
call add(l:history, {
\ 'status': a:status,
\ 'job_id': a:job_id,
\ 'command': a:command,
\})
call setbufvar(a:buffer, 'ale_history', l:history)
endfunction
1 0.000001 function! s:FindHistoryItem(buffer, job_id) abort
" Search backwards to find a matching job ID. IDs might be recycled,
" so finding the last one should be good enough.
for l:obj in reverse(ale#history#Get(a:buffer))
if l:obj.job_id == a:job_id
return l:obj
endif
endfor
return {}
endfunction
" Set an exit code for a command which finished.
1 0.000001 function! ale#history#SetExitCode(buffer, job_id, exit_code) abort
let l:obj = s:FindHistoryItem(a:buffer, a:job_id)
" If we find a match, then set the code and status.
let l:obj.exit_code = a:exit_code
let l:obj.status = 'finished'
endfunction
" Set the output for a command which finished.
1 0.000001 function! ale#history#RememberOutput(buffer, job_id, output) abort
let l:obj = s:FindHistoryItem(a:buffer, a:job_id)
let l:obj.output = a:output
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/go.vim
Sourced 1 time
Total time: 0.000281
Self time: 0.000276
count total (s) self (s)
" Author: Horacio Sanson https://github.com/hsanson
" Description: Functions for integrating with Go tools
" Find the nearest dir listed in GOPATH and assume it the root of the go
" project.
1 0.000001 function! ale#go#FindProjectRoot(buffer) abort
let l:sep = has('win32') ? ';' : ':'
let l:filename = ale#path#Simplify(expand('#' . a:buffer . ':p'))
for l:name in split($GOPATH, l:sep)
let l:path_dir = ale#path#Simplify(l:name)
" Use the directory from GOPATH if the current filename starts with it.
if l:filename[: len(l:path_dir) - 1] is? l:path_dir
return l:path_dir
endif
endfor
let l:default_go_path = ale#path#Simplify(expand('~/go'))
if isdirectory(l:default_go_path)
return l:default_go_path
endif
return ''
endfunction
1 0.000011 0.000007 call ale#Set('go_go111module', '')
" Return a string setting Go-specific environment variables
1 0.000001 function! ale#go#EnvString(buffer) abort
let l:env = ''
" GO111MODULE - turn go modules behavior on/off
let l:go111module = ale#Var(a:buffer, 'go_go111module')
if !empty(l:go111module)
let l:env = ale#Env('GO111MODULE', l:go111module) . l:env
endif
return l:env
endfunction
1 0.000001 function! ale#go#GetGoPathExecutable(suffix) abort
let l:prefix = $GOPATH
if !empty($GOPATH)
let l:prefix = $GOPATH
elseif has('win32')
let l:prefix = $USERPROFILE . '/go'
else
let l:prefix = $HOME . '/go'
endif
return ale#path#Simplify(l:prefix . '/' . a:suffix)
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/job.vim
Sourced 1 time
Total time: 0.000267
Self time: 0.000267
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: APIs for working with Asynchronous jobs, with an API normalised
" between Vim 8 and NeoVim.
"
" Important functions are described below. They are:
"
" ale#job#Start(command, options) -> job_id
" ale#job#IsRunning(job_id) -> 1 if running, 0 otherwise.
" ale#job#Stop(job_id)
" A setting for wrapping commands.
1 0.000003 let g:ale_command_wrapper = get(g:, 'ale_command_wrapper', '')
1 0.000001 if !has_key(s:, 'job_map')
1 0.000001 let s:job_map = {}
1 0.000000 endif
" A map from timer IDs to jobs, for tracking jobs that need to be killed
" with SIGKILL if they don't terminate right away.
1 0.000001 if !has_key(s:, 'job_kill_timers')
1 0.000001 let s:job_kill_timers = {}
1 0.000000 endif
1 0.000001 function! s:KillHandler(timer) abort
let l:job = remove(s:job_kill_timers, a:timer)
call job_stop(l:job, 'kill')
endfunction
1 0.000001 function! s:NeoVimCallback(job, data, event) abort
let l:info = s:job_map[a:job]
if a:event is# 'stdout'
let l:info.out_cb_line = ale#util#JoinNeovimOutput(
\ a:job,
\ l:info.out_cb_line,
\ a:data,
\ l:info.mode,
\ ale#util#GetFunction(l:info.out_cb),
\)
elseif a:event is# 'stderr'
let l:info.err_cb_line = ale#util#JoinNeovimOutput(
\ a:job,
\ l:info.err_cb_line,
\ a:data,
\ l:info.mode,
\ ale#util#GetFunction(l:info.err_cb),
\)
else
if has_key(l:info, 'out_cb') && !empty(l:info.out_cb_line)
call ale#util#GetFunction(l:info.out_cb)(a:job, l:info.out_cb_line)
endif
if has_key(l:info, 'err_cb') && !empty(l:info.err_cb_line)
call ale#util#GetFunction(l:info.err_cb)(a:job, l:info.err_cb_line)
endif
try
call ale#util#GetFunction(l:info.exit_cb)(a:job, a:data)
finally
" Automatically forget about the job after it's done.
if has_key(s:job_map, a:job)
call remove(s:job_map, a:job)
endif
endtry
endif
endfunction
1 0.000001 function! s:VimOutputCallback(channel, data) abort
let l:job = ch_getjob(a:channel)
let l:job_id = ale#job#ParseVim8ProcessID(string(l:job))
" Only call the callbacks for jobs which are valid.
if l:job_id > 0 && has_key(s:job_map, l:job_id)
call ale#util#GetFunction(s:job_map[l:job_id].out_cb)(l:job_id, a:data)
endif
endfunction
1 0.000001 function! s:VimErrorCallback(channel, data) abort
let l:job = ch_getjob(a:channel)
let l:job_id = ale#job#ParseVim8ProcessID(string(l:job))
" Only call the callbacks for jobs which are valid.
if l:job_id > 0 && has_key(s:job_map, l:job_id)
call ale#util#GetFunction(s:job_map[l:job_id].err_cb)(l:job_id, a:data)
endif
endfunction
1 0.000001 function! s:VimCloseCallback(channel) abort
let l:job = ch_getjob(a:channel)
let l:job_id = ale#job#ParseVim8ProcessID(string(l:job))
let l:info = get(s:job_map, l:job_id, {})
if empty(l:info)
return
endif
" job_status() can trigger the exit handler.
" The channel can close before the job has exited.
if job_status(l:job) is# 'dead'
try
if !empty(l:info) && has_key(l:info, 'exit_cb')
" We have to remove the callback, so we don't call it twice.
call ale#util#GetFunction(remove(l:info, 'exit_cb'))(l:job_id, get(l:info, 'exit_code', 1))
endif
finally
" Automatically forget about the job after it's done.
if has_key(s:job_map, l:job_id)
call remove(s:job_map, l:job_id)
endif
endtry
endif
endfunction
1 0.000001 function! s:VimExitCallback(job, exit_code) abort
let l:job_id = ale#job#ParseVim8ProcessID(string(a:job))
let l:info = get(s:job_map, l:job_id, {})
if empty(l:info)
return
endif
let l:info.exit_code = a:exit_code
" The program can exit before the data has finished being read.
if ch_status(job_getchannel(a:job)) is# 'closed'
try
if !empty(l:info) && has_key(l:info, 'exit_cb')
" We have to remove the callback, so we don't call it twice.
call ale#util#GetFunction(remove(l:info, 'exit_cb'))(l:job_id, a:exit_code)
endif
finally
" Automatically forget about the job after it's done.
if has_key(s:job_map, l:job_id)
call remove(s:job_map, l:job_id)
endif
endtry
endif
endfunction
1 0.000001 function! ale#job#ParseVim8ProcessID(job_string) abort
return matchstr(a:job_string, '\d\+') + 0
endfunction
1 0.000001 function! ale#job#ValidateArguments(command, options) abort
if a:options.mode isnot# 'nl' && a:options.mode isnot# 'raw'
throw 'Invalid mode: ' . a:options.mode
endif
endfunction
1 0.000001 function! s:PrepareWrappedCommand(original_wrapper, command) abort
let l:match = matchlist(a:command, '\v^(.*(\&\&|;)) *(.*)$')
let l:prefix = ''
let l:command = a:command
if !empty(l:match)
let l:prefix = l:match[1] . ' '
let l:command = l:match[3]
endif
let l:format = a:original_wrapper
if l:format =~# '%@'
let l:wrapped = substitute(l:format, '%@', ale#Escape(l:command), '')
else
if l:format !~# '%\*'
let l:format .= ' %*'
endif
let l:wrapped = substitute(l:format, '%\*', l:command, '')
endif
return l:prefix . l:wrapped
endfunction
1 0.000001 function! ale#job#PrepareCommand(buffer, command) abort
let l:wrapper = ale#Var(a:buffer, 'command_wrapper')
" The command will be executed in a subshell. This fixes a number of
" issues, including reading the PATH variables correctly, %PATHEXT%
" expansion on Windows, etc.
"
" NeoVim handles this issue automatically if the command is a String,
" but we'll do this explicitly, so we use the same exact command for both
" versions.
let l:command = !empty(l:wrapper)
\ ? s:PrepareWrappedCommand(l:wrapper, a:command)
\ : a:command
" If a custom shell is specified, use that.
if exists('g:ale_shell')
let l:shell_arguments = get(g:, 'ale_shell_arguments', &shellcmdflag)
return split(g:ale_shell) + split(l:shell_arguments) + [l:command]
endif
if has('win32')
return 'cmd /s/c "' . l:command . '"'
endif
if &shell =~? 'fish$\|pwsh$'
return ['/bin/sh', '-c', l:command]
endif
return split(&shell) + split(&shellcmdflag) + [l:command]
endfunction
" Start a job with options which are agnostic to Vim and NeoVim.
"
" The following options are accepted:
"
" out_cb - A callback for receiving stdin. Arguments: (job_id, data)
" err_cb - A callback for receiving stderr. Arguments: (job_id, data)
" exit_cb - A callback for program exit. Arguments: (job_id, status_code)
" mode - A mode for I/O. Can be 'nl' for split lines or 'raw'.
1 0.000001 function! ale#job#Start(command, options) abort
call ale#job#ValidateArguments(a:command, a:options)
let l:job_info = copy(a:options)
let l:job_options = {}
if has('nvim')
if has_key(a:options, 'out_cb')
let l:job_options.on_stdout = function('s:NeoVimCallback')
let l:job_info.out_cb_line = ''
endif
if has_key(a:options, 'err_cb')
let l:job_options.on_stderr = function('s:NeoVimCallback')
let l:job_info.err_cb_line = ''
endif
if has_key(a:options, 'exit_cb')
let l:job_options.on_exit = function('s:NeoVimCallback')
endif
let l:job_info.job = jobstart(a:command, l:job_options)
let l:job_id = l:job_info.job
else
let l:job_options = {
\ 'in_mode': l:job_info.mode,
\ 'out_mode': l:job_info.mode,
\ 'err_mode': l:job_info.mode,
\}
if has_key(a:options, 'out_cb')
let l:job_options.out_cb = function('s:VimOutputCallback')
endif
if has_key(a:options, 'err_cb')
let l:job_options.err_cb = function('s:VimErrorCallback')
endif
if has_key(a:options, 'exit_cb')
" Set a close callback to which simply calls job_status()
" when the channel is closed, which can trigger the exit callback
" earlier on.
let l:job_options.close_cb = function('s:VimCloseCallback')
let l:job_options.exit_cb = function('s:VimExitCallback')
endif
" Use non-blocking writes for Vim versions that support the option.
if has('patch-8.1.350')
let l:job_options.noblock = 1
endif
" Vim 8 will read the stdin from the file's buffer.
let l:job_info.job = job_start(a:command, l:job_options)
let l:job_id = ale#job#ParseVim8ProcessID(string(l:job_info.job))
endif
if l:job_id > 0
" Store the job in the map for later only if we can get the ID.
let s:job_map[l:job_id] = l:job_info
endif
return l:job_id
endfunction
" Force running commands in a Windows CMD command line.
" This means the same command syntax works everywhere.
1 0.000001 function! ale#job#StartWithCmd(command, options) abort
let l:shell = &l:shell
let l:shellcmdflag = &l:shellcmdflag
let &l:shell = 'cmd'
let &l:shellcmdflag = '/c'
try
let l:job_id = ale#job#Start(a:command, a:options)
finally
let &l:shell = l:shell
let &l:shellcmdflag = l:shellcmdflag
endtry
return l:job_id
endfunction
" Send raw data to the job.
1 0.000001 function! ale#job#SendRaw(job_id, string) abort
if has('nvim')
call jobsend(a:job_id, a:string)
else
let l:job = s:job_map[a:job_id].job
if ch_status(l:job) is# 'open'
call ch_sendraw(job_getchannel(l:job), a:string)
endif
endif
endfunction
" Given a job ID, return 1 if the job is currently running.
" Invalid job IDs will be ignored.
1 0.000001 function! ale#job#IsRunning(job_id) abort
if has('nvim')
try
" In NeoVim, if the job isn't running, jobpid() will throw.
call jobpid(a:job_id)
return 1
catch
endtry
elseif has_key(s:job_map, a:job_id)
let l:job = s:job_map[a:job_id].job
return job_status(l:job) is# 'run'
endif
return 0
endfunction
1 0.000001 function! ale#job#HasOpenChannel(job_id) abort
if ale#job#IsRunning(a:job_id)
if has('nvim')
" TODO: Implement a check for NeoVim.
return 1
endif
" Check if the Job's channel can be written to.
return ch_status(s:job_map[a:job_id].job) is# 'open'
endif
return 0
endfunction
" Given a Job ID, stop that job.
" Invalid job IDs will be ignored.
1 0.000001 function! ale#job#Stop(job_id) abort
if !has_key(s:job_map, a:job_id)
return
endif
if has('nvim')
" FIXME: NeoVim kills jobs on a timer, but will not kill any processes
" which are child processes on Unix. Some work needs to be done to
" kill child processes to stop long-running processes like pylint.
silent! call jobstop(a:job_id)
else
let l:job = s:job_map[a:job_id].job
" We must close the channel for reading the buffer if it is open
" when stopping a job. Otherwise, we will get errors in the status line.
if ch_status(job_getchannel(l:job)) is# 'open'
call ch_close_in(job_getchannel(l:job))
endif
" Ask nicely for the job to stop.
call job_stop(l:job)
if ale#job#IsRunning(l:job)
" Set a 100ms delay for killing the job with SIGKILL.
let s:job_kill_timers[timer_start(100, function('s:KillHandler'))] = l:job
endif
endif
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_linter.vim
Sourced 1 time
Total time: 0.000629
Self time: 0.000629
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Integration between linters and LSP/tsserver.
" This code isn't loaded if a user never users LSP features or linters.
" Associates LSP connection IDs with linter names.
1 0.000006 if !has_key(s:, 'lsp_linter_map')
1 0.000002 let s:lsp_linter_map = {}
1 0.000001 endif
" A Dictionary to track one-shot handlers for custom LSP requests
1 0.000005 let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
" Check if diagnostics for a particular linter should be ignored.
1 0.000002 function! s:ShouldIgnore(buffer, linter_name) abort
" Ignore all diagnostics if LSP integration is disabled.
if ale#Var(a:buffer, 'disable_lsp')
return 1
endif
let l:config = ale#Var(a:buffer, 'linters_ignore')
" Don't load code for ignoring diagnostics if there's nothing to ignore.
if empty(l:config)
return 0
endif
let l:filetype = getbufvar(a:buffer, '&filetype')
let l:ignore_list = ale#engine#ignore#GetList(l:filetype, l:config)
return index(l:ignore_list, a:linter_name) >= 0
endfunction
1 0.000001 function! s:HandleLSPDiagnostics(conn_id, response) abort
let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:filename = ale#path#FromURI(a:response.params.uri)
let l:escaped_name = escape(
\ fnameescape(l:filename),
\ has('win32') ? '^' : '^,}]'
\)
let l:buffer = bufnr('^' . l:escaped_name . '$')
let l:info = get(g:ale_buffer_info, l:buffer, {})
if empty(l:info)
return
endif
if s:ShouldIgnore(l:buffer, l:linter_name)
return
endif
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
endfunction
1 0.000001 function! s:HandleTSServerDiagnostics(response, error_type) abort
let l:linter_name = 'tsserver'
let l:escaped_name = escape(
\ fnameescape(a:response.body.file),
\ has('win32') ? '^' : '^,}]'
\)
let l:buffer = bufnr('^' . l:escaped_name . '$')
let l:info = get(g:ale_buffer_info, l:buffer, {})
if empty(l:info)
return
endif
call ale#engine#MarkLinterInactive(l:info, l:linter_name)
if s:ShouldIgnore(l:buffer, l:linter_name)
return
endif
let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
let l:no_changes = 0
" tsserver sends syntax and semantic errors in separate messages, so we
" have to collect the messages separately for each buffer and join them
" back together again.
if a:error_type is# 'syntax'
if len(l:thislist) is 0 && len(get(l:info, 'syntax_loclist', [])) is 0
let l:no_changes = 1
endif
let l:info.syntax_loclist = l:thislist
elseif a:error_type is# 'semantic'
if len(l:thislist) is 0 && len(get(l:info, 'semantic_loclist', [])) is 0
let l:no_changes = 1
endif
let l:info.semantic_loclist = l:thislist
else
if len(l:thislist) is 0 && len(get(l:info, 'suggestion_loclist', [])) is 0
let l:no_changes = 1
endif
let l:info.suggestion_loclist = l:thislist
endif
if l:no_changes
return
endif
let l:loclist = get(l:info, 'semantic_loclist', [])
\ + get(l:info, 'suggestion_loclist', [])
\ + get(l:info, 'syntax_loclist', [])
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
endfunction
1 0.000001 function! s:HandleLSPErrorMessage(linter_name, response) abort
if !g:ale_history_enabled || !g:ale_history_log_output
return
endif
if empty(a:linter_name)
return
endif
let l:message = ale#lsp#response#GetErrorMessage(a:response)
if empty(l:message)
return
endif
" This global variable is set here so we don't load the debugging.vim file
" until someone uses :ALEInfo.
let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
if !has_key(g:ale_lsp_error_messages, a:linter_name)
let g:ale_lsp_error_messages[a:linter_name] = []
endif
call add(g:ale_lsp_error_messages[a:linter_name], l:message)
endfunction
1 0.000001 function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
let l:method = get(a:response, 'method', '')
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
call s:HandleLSPErrorMessage(l:linter_name, a:response)
elseif l:method is# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:conn_id, a:response)
elseif l:method is# 'window/showMessage'
call ale#lsp_window#HandleShowMessage(
\ s:lsp_linter_map[a:conn_id],
\ g:ale_lsp_show_message_format,
\ a:response.params
\)
elseif get(a:response, 'type', '') is# 'event'
\&& get(a:response, 'event', '') is# 'semanticDiag'
call s:HandleTSServerDiagnostics(a:response, 'semantic')
elseif get(a:response, 'type', '') is# 'event'
\&& get(a:response, 'event', '') is# 'syntaxDiag'
call s:HandleTSServerDiagnostics(a:response, 'syntax')
elseif get(a:response, 'type', '') is# 'event'
\&& get(a:response, 'event', '') is# 'suggestionDiag'
\&& get(g:, 'ale_lsp_suggestions', '1') == 1
call s:HandleTSServerDiagnostics(a:response, 'suggestion')
endif
endfunction
1 0.000001 function! ale#lsp_linter#GetOptions(buffer, linter) abort
if has_key(a:linter, 'initialization_options_callback')
return ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
endif
if has_key(a:linter, 'initialization_options')
let l:Options = a:linter.initialization_options
if type(l:Options) is v:t_func
let l:Options = l:Options(a:buffer)
endif
return l:Options
endif
return {}
endfunction
1 0.000001 function! ale#lsp_linter#GetConfig(buffer, linter) abort
if has_key(a:linter, 'lsp_config_callback')
return ale#util#GetFunction(a:linter.lsp_config_callback)(a:buffer)
endif
if has_key(a:linter, 'lsp_config')
let l:Config = a:linter.lsp_config
if type(l:Config) is v:t_func
let l:Config = l:Config(a:buffer)
endif
return l:Config
endif
return {}
endfunction
1 0.000001 function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
let l:buffer_ale_root = getbufvar(
\ a:buffer,
\ 'ale_root',
\ getbufvar(a:buffer, 'ale_lsp_root', {})
\)
if type(l:buffer_ale_root) is v:t_string
return l:buffer_ale_root
endif
" Try to get a buffer-local setting for the root
if has_key(l:buffer_ale_root, a:linter.name)
let l:Root = l:buffer_ale_root[a:linter.name]
if type(l:Root) is v:t_func
return l:Root(a:buffer)
else
return l:Root
endif
endif
let l:global_root = g:ale_root
if empty(g:ale_root) && exists('g:ale_lsp_root')
let l:global_root = g:ale_lsp_root
endif
" Try to get a global setting for the root
if has_key(l:global_root, a:linter.name)
let l:Root = l:global_root[a:linter.name]
if type(l:Root) is v:t_func
return l:Root(a:buffer)
else
return l:Root
endif
endif
" Fall back to the linter-specific configuration
if has_key(a:linter, 'project_root')
let l:Root = a:linter.project_root
return type(l:Root) is v:t_func ? l:Root(a:buffer) : l:Root
endif
return ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
endfunction
" This function is accessible so tests can call it.
1 0.000001 function! ale#lsp_linter#OnInit(linter, details, Callback) abort
let l:buffer = a:details.buffer
let l:conn_id = a:details.connection_id
let l:command = a:details.command
let l:config = ale#lsp_linter#GetConfig(l:buffer, a:linter)
let l:language_id = ale#linter#GetLanguage(l:buffer, a:linter)
call ale#lsp#UpdateConfig(l:conn_id, l:buffer, l:config)
if ale#lsp#OpenDocument(l:conn_id, l:buffer, l:language_id)
if g:ale_history_enabled && !empty(l:command)
call ale#history#Add(l:buffer, 'started', l:conn_id, l:command)
endif
endif
" The change message needs to be sent for tsserver before doing anything.
if a:linter.lsp is# 'tsserver'
call ale#lsp#NotifyForChanges(l:conn_id, l:buffer)
endif
" Tell the relevant buffer that the LSP has started via an autocmd.
if l:buffer > 0
if l:buffer == bufnr('')
silent doautocmd <nomodeline> User ALELSPStarted
else
execute 'augroup ALELSPStartedGroup' . l:buffer
autocmd!
execute printf(
\ 'autocmd BufEnter <buffer=%d>'
\ . ' doautocmd <nomodeline> User ALELSPStarted',
\ l:buffer
\)
" Replicate ++once behavior for backwards compatibility.
execute printf(
\ 'autocmd BufEnter <buffer=%d>'
\ . ' autocmd! ALELSPStartedGroup%d',
\ l:buffer, l:buffer
\)
augroup END
endif
endif
call a:Callback(a:linter, a:details)
endfunction
1 0.000001 function! s:StartLSP(options, address, executable, command) abort
let l:buffer = a:options.buffer
let l:linter = a:options.linter
let l:root = a:options.root
let l:Callback = a:options.callback
let l:init_options = ale#lsp_linter#GetOptions(l:buffer, l:linter)
if l:linter.lsp is# 'socket'
let l:conn_id = ale#lsp#Register(a:address, l:root, l:init_options)
let l:ready = ale#lsp#ConnectToAddress(l:conn_id, a:address)
let l:command = ''
else
let l:conn_id = ale#lsp#Register(a:executable, l:root, l:init_options)
" tsserver behaves differently, so tell the LSP API that it is tsserver.
if l:linter.lsp is# 'tsserver'
call ale#lsp#MarkConnectionAsTsserver(l:conn_id)
endif
let l:cwd = ale#linter#GetCwd(l:buffer, l:linter)
let l:command = ale#command#FormatCommand(
\ l:buffer,
\ a:executable,
\ a:command,
\ 0,
\ v:false,
\ l:cwd,
\ ale#GetFilenameMappings(l:buffer, l:linter.name),
\)[1]
let l:command = ale#job#PrepareCommand(l:buffer, l:command)
let l:ready = ale#lsp#StartProgram(l:conn_id, a:executable, l:command)
endif
if !l:ready
if g:ale_history_enabled && !empty(a:command)
call ale#history#Add(l:buffer, 'failed', l:conn_id, a:command)
endif
return 0
endif
let l:details = {
\ 'buffer': l:buffer,
\ 'connection_id': l:conn_id,
\ 'command': l:command,
\ 'project_root': l:root,
\}
call ale#lsp#OnInit(l:conn_id, {->
\ ale#lsp_linter#OnInit(l:linter, l:details, l:Callback)
\})
return 1
endfunction
1 0.000001 function! s:StartWithAddress(options, address) abort
if ale#command#IsDeferred(a:address)
let a:address.result_callback = {
\ address -> s:StartWithAddress(a:options, address)
\}
return 1
endif
if empty(a:address)
return 0
endif
return s:StartLSP(a:options, a:address, '', '')
endfunction
1 0.000001 function! s:StartWithCommand(options, executable, command) abort
if ale#command#IsDeferred(a:command)
let a:command.result_callback = {
\ command -> s:StartWithCommand(a:options, a:executable, command)
\}
return 1
endif
if empty(a:command)
return 0
endif
return s:StartLSP(a:options, '', a:executable, a:command)
endfunction
1 0.000001 function! s:StartIfExecutable(options, executable) abort
if ale#command#IsDeferred(a:executable)
let a:executable.result_callback = {
\ executable -> s:StartIfExecutable(a:options, executable)
\}
return 1
endif
if !ale#engine#IsExecutable(a:options.buffer, a:executable)
return 0
endif
let l:command = ale#linter#GetCommand(a:options.buffer, a:options.linter)
return s:StartWithCommand(a:options, a:executable, l:command)
endfunction
" Given a buffer, an LSP linter, start up an LSP linter and get ready to
" receive messages for the document.
1 0.000001 function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
let l:command = ''
let l:address = ''
let l:root = ale#lsp_linter#FindProjectRoot(a:buffer, a:linter)
if empty(l:root) && a:linter.lsp isnot# 'tsserver'
" If there's no project root, then we can't check files with LSP,
" unless we are using tsserver, which doesn't use project roots.
return 0
endif
let l:options = {
\ 'buffer': a:buffer,
\ 'linter': a:linter,
\ 'callback': a:Callback,
\ 'root': l:root,
\}
if a:linter.lsp is# 'socket'
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
return s:StartWithAddress(l:options, l:address)
endif
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
return s:StartIfExecutable(l:options, l:executable)
endfunction
1 0.000001 function! s:CheckWithLSP(linter, details) abort
let l:buffer = a:details.buffer
let l:info = get(g:ale_buffer_info, l:buffer)
if empty(l:info)
return
endif
let l:id = a:details.connection_id
" Register a callback now for handling errors now.
let l:Callback = function('ale#lsp_linter#HandleLSPResponse')
call ale#lsp#RegisterCallback(l:id, l:Callback)
" Remember the linter this connection is for.
let s:lsp_linter_map[l:id] = a:linter.name
if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:message) != 0
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
else
let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer)
endif
" If this was a file save event, also notify the server of that.
if a:linter.lsp isnot# 'tsserver'
\&& getbufvar(l:buffer, 'ale_save_event_fired', 0)
\&& ale#lsp#HasCapability(l:buffer, 'did_save')
let l:include_text = ale#lsp#HasCapability(l:buffer, 'includeText')
let l:save_message = ale#lsp#message#DidSave(l:buffer, l:include_text)
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
endif
endfunction
1 0.000001 function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
return ale#lsp_linter#StartLSP(a:buffer, a:linter, function('s:CheckWithLSP'))
endfunction
" Clear LSP linter data for the linting engine.
1 0.000001 function! ale#lsp_linter#ClearLSPData() abort
let s:lsp_linter_map = {}
let s:custom_handlers_map = {}
endfunction
" Just for tests.
1 0.000001 function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
let s:lsp_linter_map = a:replacement_map
endfunction
1 0.000001 function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:custom_handlers_map, a:response.id)
let l:Handler = remove(s:custom_handlers_map, a:response.id)
call l:Handler(a:response)
endif
endfunction
1 0.000001 function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
let l:request_id = ale#lsp#Send(l:id, a:args.message)
if l:request_id > 0 && has_key(a:args, 'handler')
let l:Callback = function('s:HandleLSPResponseToCustomRequests')
call ale#lsp#RegisterCallback(l:id, l:Callback)
let s:custom_handlers_map[l:request_id] = a:args.handler
endif
endfunction
" Send a custom request to an LSP linter.
1 0.000001 function! ale#lsp_linter#SendRequest(buffer, linter_name, message, ...) abort
let l:filetype = ale#linter#ResolveFiletype(getbufvar(a:buffer, '&filetype'))
let l:linter_list = ale#linter#GetAll(l:filetype)
let l:linter_list = filter(l:linter_list, {_, v -> v.name is# a:linter_name})
if len(l:linter_list) < 1
throw 'Linter "' . a:linter_name . '" not found!'
endif
let l:linter = l:linter_list[0]
if empty(l:linter.lsp)
throw 'Linter "' . a:linter_name . '" does not support LSP!'
endif
let l:is_notification = a:message[0]
let l:callback_args = {'message': a:message}
if !l:is_notification && a:0
let l:callback_args.handler = a:1
endif
let l:Callback = function('s:OnReadyForCustomRequests', [l:callback_args])
return ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/path.vim
Sourced 1 time
Total time: 0.000277
Self time: 0.000246
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Functions for working with paths in the filesystem.
" simplify a path, and fix annoying issues with paths on Windows.
"
" Forward slashes are changed to back slashes so path equality works better
" on Windows. Back slashes are changed to forward slashes on Unix.
"
" Unix paths can technically contain back slashes, but in practice no path
" should, and replacing back slashes with forward slashes makes linters work
" in environments like MSYS.
"
" Paths starting with more than one forward slash are changed to only one
" forward slash, to prevent the paths being treated as special MSYS paths.
1 0.000002 function! ale#path#Simplify(path) abort
if has('unix')
let l:unix_path = substitute(a:path, '\\', '/', 'g')
return substitute(simplify(l:unix_path), '^//\+', '/', 'g') " no-custom-checks
endif
let l:win_path = substitute(a:path, '/', '\\', 'g')
return substitute(simplify(l:win_path), '^\\\+', '\', 'g') " no-custom-checks
endfunction
" Simplify a path without a Windows drive letter.
" This function can be used for checking if paths are equal.
1 0.000001 function! ale#path#RemoveDriveLetter(path) abort
return has('win32') && a:path[1:2] is# ':\'
\ ? ale#path#Simplify(a:path[2:])
\ : ale#path#Simplify(a:path)
endfunction
" Given a buffer and a filename, find the nearest file by searching upwards
" through the paths relative to the given buffer.
1 0.000001 function! ale#path#FindNearestFile(buffer, filename) abort
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p')
let l:buffer_filename = fnameescape(l:buffer_filename)
let l:relative_path = findfile(a:filename, l:buffer_filename . ';')
if !empty(l:relative_path)
return fnamemodify(l:relative_path, ':p')
endif
return ''
endfunction
" Given a buffer and a directory name, find the nearest directory by searching upwards
" through the paths relative to the given buffer.
1 0.000002 function! ale#path#FindNearestDirectory(buffer, directory_name) abort
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p')
let l:buffer_filename = fnameescape(l:buffer_filename)
let l:relative_path = finddir(a:directory_name, l:buffer_filename . ';')
if !empty(l:relative_path)
return fnamemodify(l:relative_path, ':p')
endif
return ''
endfunction
" Given a buffer, a string to search for, and a global fallback for when
" the search fails, look for a file in parent paths, and if that fails,
" use the global fallback path instead.
1 0.000001 function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort
" Search for a locally installed file first.
let l:path = ale#path#FindNearestFile(a:buffer, a:search_string)
" If the search fails, try the global executable instead.
if empty(l:path)
let l:path = a:global_fallback
endif
return l:path
endfunction
" Given a buffer number, a base variable name, and a list of paths to search
" for in ancestor directories, detect the executable path for a program.
1 0.000001 function! ale#path#FindNearestExecutable(buffer, path_list) abort
for l:path in a:path_list
if ale#path#IsAbsolute(l:path)
let l:executable = filereadable(l:path) ? l:path : ''
else
let l:executable = ale#path#FindNearestFile(a:buffer, l:path)
endif
if !empty(l:executable)
return l:executable
endif
endfor
return ''
endfunction
" Given a buffer number, a base variable name, and a list of paths to search
" for in ancestor directories, detect the executable path for a program.
"
" The use_global and executable options for the relevant program will be used.
1 0.000001 function! ale#path#FindExecutable(buffer, base_var_name, path_list) abort
if ale#Var(a:buffer, a:base_var_name . '_use_global')
return ale#Var(a:buffer, a:base_var_name . '_executable')
endif
let l:nearest = ale#path#FindNearestExecutable(a:buffer, a:path_list)
if !empty(l:nearest)
return l:nearest
endif
return ale#Var(a:buffer, a:base_var_name . '_executable')
endfunction
" Return 1 if a path is an absolute path.
1 0.000001 function! ale#path#IsAbsolute(filename) abort
if has('win32') && a:filename[:0] is# '\'
return 1
endif
" Check for /foo and C:\foo, etc.
return a:filename[:0] is# '/' || a:filename[1:2] is# ':\'
endfunction
1 0.000042 0.000011 let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h:h'))
" Given a filename, return 1 if the file represents some temporary file
" created by Vim.
1 0.000001 function! ale#path#IsTempName(filename) abort
return ale#path#Simplify(a:filename)[:len(s:temp_dir) - 1] is# s:temp_dir
endfunction
" Given a base directory, which must not have a trailing slash, and a
" filename, which may have an absolute path a path relative to the base
" directory, return the absolute path to the file.
1 0.000001 function! ale#path#GetAbsPath(base_directory, filename) abort
if ale#path#IsAbsolute(a:filename)
return ale#path#Simplify(a:filename)
endif
let l:sep = has('win32') ? '\' : '/'
return ale#path#Simplify(a:base_directory . l:sep . a:filename)
endfunction
" Given a path, return the directory name for that path, with no trailing
" slashes. If the argument is empty(), return an empty string.
1 0.000001 function! ale#path#Dirname(path) abort
if empty(a:path)
return ''
endif
" For /foo/bar/ we need :h:h to get /foo
if a:path[-1:] is# '/' || (has('win32') && a:path[-1:] is# '\')
return fnamemodify(a:path, ':h:h')
endif
return fnamemodify(a:path, ':h')
endfunction
" Given a buffer number and a relative or absolute path, return 1 if the
" two paths represent the same file on disk.
1 0.000001 function! ale#path#IsBufferPath(buffer, complex_filename) abort
" If the path is one of many different names for stdin, we have a match.
if a:complex_filename is# '-'
\|| a:complex_filename is# 'stdin'
\|| a:complex_filename[:0] is# '<'
return 1
endif
let l:test_filename = ale#path#Simplify(a:complex_filename)
if l:test_filename[:1] is# './'
let l:test_filename = l:test_filename[2:]
endif
if l:test_filename[:1] is# '..'
" Remove ../../ etc. from the front of the path.
let l:test_filename = substitute(l:test_filename, '\v^(\.\.[/\\])+', '/', '')
endif
" Use the basename for temporary files, as they are likely our files.
if ale#path#IsTempName(l:test_filename)
let l:test_filename = fnamemodify(l:test_filename, ':t')
endif
let l:buffer_filename = expand('#' . a:buffer . ':p')
return l:buffer_filename is# l:test_filename
\ || l:buffer_filename[-len(l:test_filename):] is# l:test_filename
endfunction
" Given a path, return every component of the path, moving upwards.
1 0.000001 function! ale#path#Upwards(path) abort
let l:pattern = has('win32') ? '\v/+|\\+' : '\v/+'
let l:sep = has('win32') ? '\' : '/'
let l:parts = split(ale#path#Simplify(a:path), l:pattern)
let l:path_list = []
while !empty(l:parts)
call add(l:path_list, join(l:parts, l:sep))
let l:parts = l:parts[:-2]
endwhile
if has('win32') && a:path =~# '^[a-zA-z]:\'
" Add \ to C: for C:\, etc.
let l:path_list[-1] .= '\'
elseif a:path[0] is# '/'
" If the path starts with /, even on Windows, add / and / to all paths.
call map(l:path_list, '''/'' . v:val')
call add(l:path_list, '/')
endif
return l:path_list
endfunction
" Convert a filesystem path to a file:// URI
" relatives paths will not be prefixed with the protocol.
" For Windows paths, the `:` in C:\ etc. will not be percent-encoded.
1 0.000001 function! ale#path#ToURI(path) abort
let l:has_drive_letter = a:path[1:2] is# ':\'
return substitute(
\ ((l:has_drive_letter || a:path[:0] is# '/') ? 'file://' : '')
\ . (l:has_drive_letter ? '/' . a:path[:2] : '')
\ . ale#uri#Encode(l:has_drive_letter ? a:path[3:] : a:path),
\ '\\',
\ '/',
\ 'g',
\)
endfunction
1 0.000001 function! ale#path#FromURI(uri) abort
if a:uri[:6] is? 'file://'
let l:encoded_path = a:uri[7:]
elseif a:uri[:4] is? 'file:'
let l:encoded_path = a:uri[5:]
else
let l:encoded_path = a:uri
endif
let l:path = ale#uri#Decode(l:encoded_path)
" If the path is like /C:/foo/bar, it should be C:\foo\bar instead.
if has('win32') && l:path =~# '^/[a-zA-Z][:|]'
let l:path = substitute(l:path[1:], '/', '\\', 'g')
let l:path = l:path[0] . ':' . l:path[2:]
endif
return l:path
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp.vim
Sourced 1 time
Total time: 0.000458
Self time: 0.000458
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Language Server Protocol client code
" A Dictionary for tracking connections.
1 0.000006 let s:connections = get(s:, 'connections', {})
1 0.000004 let g:ale_lsp_next_message_id = 1
" Given an id, which can be an executable or address, and a project path,
" create a new connection if needed. Return a unique ID for the connection.
1 0.000002 function! ale#lsp#Register(executable_or_address, project, init_options) abort
let l:conn_id = a:executable_or_address . ':' . a:project
if !has_key(s:connections, l:conn_id)
" is_tsserver: 1 if the connection is for tsserver.
" data: The message data received so far.
" root: The project root.
" open_documents: A Dictionary mapping buffers to b:changedtick, keeping
" track of when documents were opened, and when we last changed them.
" initialized: 0 if the connection is ready, 1 otherwise.
" init_request_id: The ID for the init request.
" init_options: Options to send to the server.
" config: Configuration settings to send to the server.
" callback_list: A list of callbacks for handling LSP responses.
" capabilities_queue: The list of callbacks to call with capabilities.
" capabilities: Features the server supports.
let s:connections[l:conn_id] = {
\ 'id': l:conn_id,
\ 'is_tsserver': 0,
\ 'data': '',
\ 'root': a:project,
\ 'open_documents': {},
\ 'initialized': 0,
\ 'init_request_id': 0,
\ 'init_options': a:init_options,
\ 'config': {},
\ 'callback_list': [],
\ 'init_queue': [],
\ 'capabilities': {
\ 'hover': 0,
\ 'rename': 0,
\ 'references': 0,
\ 'completion': 0,
\ 'completion_trigger_characters': [],
\ 'definition': 0,
\ 'typeDefinition': 0,
\ 'symbol_search': 0,
\ 'code_actions': 0,
\ 'did_save': 0,
\ 'includeText': 0,
\ },
\}
endif
return l:conn_id
endfunction
" Remove an LSP connection with a given ID. This is only for tests.
1 0.000001 function! ale#lsp#RemoveConnectionWithID(id) abort
if has_key(s:connections, a:id)
call remove(s:connections, a:id)
endif
endfunction
1 0.000001 function! ale#lsp#ResetConnections() abort
let s:connections = {}
endfunction
" Used only in tests.
1 0.000001 function! ale#lsp#GetConnections() abort
" This command will throw from the sandbox.
let &l:equalprg=&l:equalprg
return s:connections
endfunction
" This is only needed for tests
1 0.000001 function! ale#lsp#MarkDocumentAsOpen(id, buffer) abort
let l:conn = get(s:connections, a:id, {})
if !empty(l:conn)
let l:conn.open_documents[a:buffer] = -1
endif
endfunction
1 0.000001 function! ale#lsp#GetNextMessageID() abort
" Use the current ID
let l:id = g:ale_lsp_next_message_id
" Increment the ID variable.
let g:ale_lsp_next_message_id += 1
" When the ID overflows, reset it to 1. By the time we hit the initial ID
" again, the messages will be long gone.
if g:ale_lsp_next_message_id < 1
let g:ale_lsp_next_message_id = 1
endif
return l:id
endfunction
" TypeScript messages use a different format.
1 0.000001 function! s:CreateTSServerMessageData(message) abort
let l:is_notification = a:message[0]
let l:obj = {
\ 'seq': v:null,
\ 'type': 'request',
\ 'command': a:message[1][3:],
\}
if !l:is_notification
let l:obj.seq = ale#lsp#GetNextMessageID()
endif
if len(a:message) > 2
let l:obj.arguments = a:message[2]
endif
let l:data = json_encode(l:obj) . "\n"
return [l:is_notification ? 0 : l:obj.seq, l:data]
endfunction
" Given a List of one or two items, [method_name] or [method_name, params],
" return a List containing [message_id, message_data]
1 0.000001 function! ale#lsp#CreateMessageData(message) abort
if a:message[1][:2] is# 'ts@'
return s:CreateTSServerMessageData(a:message)
endif
let l:is_notification = a:message[0]
let l:obj = {
\ 'method': a:message[1],
\ 'jsonrpc': '2.0',
\}
if !l:is_notification
let l:obj.id = ale#lsp#GetNextMessageID()
endif
if len(a:message) > 2
let l:obj.params = a:message[2]
endif
let l:body = json_encode(l:obj)
let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
return [l:is_notification ? 0 : l:obj.id, l:data]
endfunction
1 0.000001 function! ale#lsp#ReadMessageData(data) abort
let l:response_list = []
let l:remainder = a:data
while 1
" Look for the end of the HTTP headers
let l:body_start_index = matchend(l:remainder, "\r\n\r\n")
if l:body_start_index < 0
" No header end was found yet.
break
endif
" Parse the Content-Length header.
let l:header_data = l:remainder[:l:body_start_index - 4]
let l:length_match = matchlist(
\ l:header_data,
\ '\vContent-Length: *(\d+)'
\)
if empty(l:length_match)
throw "Invalid JSON-RPC header:\n" . l:header_data
endif
" Split the body and the remainder of the text.
let l:remainder_start_index = l:body_start_index + str2nr(l:length_match[1])
if len(l:remainder) < l:remainder_start_index
" We don't have enough data yet.
break
endif
let l:body = l:remainder[l:body_start_index : l:remainder_start_index - 1]
let l:remainder = l:remainder[l:remainder_start_index :]
" Parse the JSON object and add it to the list.
call add(l:response_list, json_decode(l:body))
endwhile
return [l:remainder, l:response_list]
endfunction
" Update capabilities from the server, so we know which features the server
" supports.
1 0.000001 function! s:UpdateCapabilities(conn, capabilities) abort
if type(a:capabilities) isnot v:t_dict
return
endif
if get(a:capabilities, 'hoverProvider') is v:true
let a:conn.capabilities.hover = 1
endif
if type(get(a:capabilities, 'hoverProvider')) is v:t_dict
let a:conn.capabilities.hover = 1
endif
if get(a:capabilities, 'referencesProvider') is v:true
let a:conn.capabilities.references = 1
endif
if type(get(a:capabilities, 'referencesProvider')) is v:t_dict
let a:conn.capabilities.references = 1
endif
if get(a:capabilities, 'renameProvider') is v:true
let a:conn.capabilities.rename = 1
endif
if type(get(a:capabilities, 'renameProvider')) is v:t_dict
let a:conn.capabilities.rename = 1
endif
if get(a:capabilities, 'codeActionProvider') is v:true
let a:conn.capabilities.code_actions = 1
endif
if type(get(a:capabilities, 'codeActionProvider')) is v:t_dict
let a:conn.capabilities.code_actions = 1
endif
if !empty(get(a:capabilities, 'completionProvider'))
let a:conn.capabilities.completion = 1
endif
if type(get(a:capabilities, 'completionProvider')) is v:t_dict
let l:chars = get(a:capabilities.completionProvider, 'triggerCharacters')
if type(l:chars) is v:t_list
let a:conn.capabilities.completion_trigger_characters = l:chars
endif
endif
if get(a:capabilities, 'definitionProvider') is v:true
let a:conn.capabilities.definition = 1
endif
if type(get(a:capabilities, 'definitionProvider')) is v:t_dict
let a:conn.capabilities.definition = 1
endif
if get(a:capabilities, 'typeDefinitionProvider') is v:true
let a:conn.capabilities.typeDefinition = 1
endif
if type(get(a:capabilities, 'typeDefinitionProvider')) is v:t_dict
let a:conn.capabilities.typeDefinition = 1
endif
if get(a:capabilities, 'workspaceSymbolProvider') is v:true
let a:conn.capabilities.symbol_search = 1
endif
if type(get(a:capabilities, 'workspaceSymbolProvider')) is v:t_dict
let a:conn.capabilities.symbol_search = 1
endif
if type(get(a:capabilities, 'textDocumentSync')) is v:t_dict
let l:syncOptions = get(a:capabilities, 'textDocumentSync')
if get(l:syncOptions, 'save') is v:true
let a:conn.capabilities.did_save = 1
endif
if type(get(l:syncOptions, 'save')) is v:t_dict
let a:conn.capabilities.did_save = 1
let l:saveOptions = get(l:syncOptions, 'save')
if get(l:saveOptions, 'includeText') is v:true
let a:conn.capabilities.includeText = 1
endif
endif
endif
endfunction
" Update a connection's configuration dictionary and notify LSP servers
" of any changes since the last update. Returns 1 if a configuration
" update was sent; otherwise 0 will be returned.
1 0.000001 function! ale#lsp#UpdateConfig(conn_id, buffer, config) abort
let l:conn = get(s:connections, a:conn_id, {})
if empty(l:conn) || a:config ==# l:conn.config " no-custom-checks
return 0
endif
let l:conn.config = a:config
let l:message = ale#lsp#message#DidChangeConfiguration(a:buffer, a:config)
call ale#lsp#Send(a:conn_id, l:message)
return 1
endfunction
1 0.000001 function! ale#lsp#HandleInitResponse(conn, response) abort
if get(a:response, 'method', '') is# 'initialize'
let a:conn.initialized = 1
elseif type(get(a:response, 'result')) is v:t_dict
\&& has_key(a:response.result, 'capabilities')
call s:UpdateCapabilities(a:conn, a:response.result.capabilities)
let a:conn.initialized = 1
endif
if !a:conn.initialized
return
endif
" The initialized message must be sent before everything else.
call ale#lsp#Send(a:conn.id, ale#lsp#message#Initialized())
" Call capabilities callbacks queued for the project.
for l:Callback in a:conn.init_queue
call l:Callback()
endfor
let a:conn.init_queue = []
endfunction
1 0.000001 function! ale#lsp#HandleMessage(conn_id, message) abort
let l:conn = get(s:connections, a:conn_id, {})
if empty(l:conn)
return
endif
if type(a:message) isnot v:t_string
" Ignore messages that aren't strings.
return
endif
let l:conn.data .= a:message
" Parse the objects now if we can, and keep the remaining text.
let [l:conn.data, l:response_list] = ale#lsp#ReadMessageData(l:conn.data)
" Look for initialize responses first.
if !l:conn.initialized
for l:response in l:response_list
call ale#lsp#HandleInitResponse(l:conn, l:response)
endfor
endif
" If the connection is marked as initialized, call the callbacks with the
" responses.
if l:conn.initialized
for l:response in l:response_list
" Call all of the registered handlers with the response.
for l:Callback in l:conn.callback_list
call ale#util#GetFunction(l:Callback)(a:conn_id, l:response)
endfor
endfor
endif
endfunction
" Given a connection ID, mark it as a tsserver connection, so it will be
" handled that way.
1 0.000001 function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort
let l:conn = s:connections[a:conn_id]
let l:conn.is_tsserver = 1
let l:conn.initialized = 1
" Set capabilities which are supported by tsserver.
let l:conn.capabilities.hover = 1
let l:conn.capabilities.references = 1
let l:conn.capabilities.completion = 1
let l:conn.capabilities.completion_trigger_characters = ['.']
let l:conn.capabilities.definition = 1
let l:conn.capabilities.typeDefinition = 1
let l:conn.capabilities.symbol_search = 1
let l:conn.capabilities.rename = 1
let l:conn.capabilities.code_actions = 1
endfunction
1 0.000001 function! s:SendInitMessage(conn) abort
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
\ ale#lsp#message#Initialize(
\ a:conn.root,
\ a:conn.init_options,
\ {
\ 'workspace': {
\ 'applyEdit': v:false,
\ 'didChangeConfiguration': {
\ 'dynamicRegistration': v:false,
\ },
\ 'symbol': {
\ 'dynamicRegistration': v:false,
\ },
\ 'workspaceFolders': v:false,
\ 'configuration': v:false,
\ },
\ 'textDocument': {
\ 'synchronization': {
\ 'dynamicRegistration': v:false,
\ 'willSave': v:false,
\ 'willSaveWaitUntil': v:false,
\ 'didSave': v:true,
\ },
\ 'completion': {
\ 'dynamicRegistration': v:false,
\ 'completionItem': {
\ 'snippetSupport': v:false,
\ 'commitCharactersSupport': v:false,
\ 'documentationFormat': ['plaintext'],
\ 'deprecatedSupport': v:false,
\ 'preselectSupport': v:false,
\ },
\ 'contextSupport': v:false,
\ },
\ 'hover': {
\ 'dynamicRegistration': v:false,
\ 'contentFormat': ['plaintext'],
\ },
\ 'references': {
\ 'dynamicRegistration': v:false,
\ },
\ 'documentSymbol': {
\ 'dynamicRegistration': v:false,
\ 'hierarchicalDocumentSymbolSupport': v:false,
\ },
\ 'definition': {
\ 'dynamicRegistration': v:false,
\ 'linkSupport': v:false,
\ },
\ 'typeDefinition': {
\ 'dynamicRegistration': v:false,
\ },
\ 'publishDiagnostics': {
\ 'relatedInformation': v:true,
\ },
\ 'codeAction': {
\ 'dynamicRegistration': v:false,
\ },
\ 'rename': {
\ 'dynamicRegistration': v:false,
\ },
\ },
\ },
\ ),
\)
let a:conn.init_request_id = l:init_id
call s:SendMessageData(a:conn, l:init_data)
endfunction
" Start a program for LSP servers.
"
" 1 will be returned if the program is running, or 0 if the program could
" not be started.
1 0.000002 function! ale#lsp#StartProgram(conn_id, executable, command) abort
let l:conn = s:connections[a:conn_id]
let l:started = 0
if !has_key(l:conn, 'job_id') || !ale#job#HasOpenChannel(l:conn.job_id)
let l:options = {
\ 'mode': 'raw',
\ 'out_cb': {_, message -> ale#lsp#HandleMessage(a:conn_id, message)},
\}
if has('win32')
let l:job_id = ale#job#StartWithCmd(a:command, l:options)
else
let l:job_id = ale#job#Start(a:command, l:options)
endif
let l:started = 1
else
let l:job_id = l:conn.job_id
endif
if l:job_id > 0
let l:conn.job_id = l:job_id
endif
if l:started && !l:conn.is_tsserver
let l:conn.initialized = 0
call s:SendInitMessage(l:conn)
endif
return l:job_id > 0
endfunction
" Connect to an LSP server via TCP.
"
" 1 will be returned if the connection is running, or 0 if the connection could
" not be opened.
1 0.000001 function! ale#lsp#ConnectToAddress(conn_id, address) abort
let l:conn = s:connections[a:conn_id]
let l:started = 0
if !has_key(l:conn, 'channel_id') || !ale#socket#IsOpen(l:conn.channel_id)
let l:channel_id = ale#socket#Open(a:address, {
\ 'callback': {_, mess -> ale#lsp#HandleMessage(a:conn_id, mess)},
\})
let l:started = 1
else
let l:channel_id = l:conn.channel_id
endif
if l:channel_id >= 0
let l:conn.channel_id = l:channel_id
endif
if l:started
call s:SendInitMessage(l:conn)
endif
return l:channel_id >= 0
endfunction
" Given a connection ID and a callback, register that callback for handling
" messages if the connection exists.
1 0.000001 function! ale#lsp#RegisterCallback(conn_id, callback) abort
let l:conn = get(s:connections, a:conn_id, {})
if !empty(l:conn)
" Add the callback to the List if it's not there already.
call uniq(sort(add(l:conn.callback_list, a:callback)))
endif
endfunction
" Stop a single LSP connection.
1 0.000001 function! ale#lsp#Stop(conn_id) abort
if has_key(s:connections, a:conn_id)
let l:conn = remove(s:connections, a:conn_id)
if has_key(l:conn, 'channel_id')
call ale#socket#Close(l:conn.channel_id)
elseif has_key(l:conn, 'job_id')
call ale#job#Stop(l:conn.job_id)
endif
endif
endfunction
1 0.000001 function! ale#lsp#CloseDocument(conn_id) abort
endfunction
" Stop all LSP connections, closing all jobs and channels, and removing any
" queued messages.
1 0.000001 function! ale#lsp#StopAll() abort
for l:conn_id in keys(s:connections)
call ale#lsp#Stop(l:conn_id)
endfor
endfunction
1 0.000001 function! s:SendMessageData(conn, data) abort
if has_key(a:conn, 'job_id')
call ale#job#SendRaw(a:conn.job_id, a:data)
elseif has_key(a:conn, 'channel_id') && ale#socket#IsOpen(a:conn.channel_id)
" Send the message to the server
call ale#socket#Send(a:conn.channel_id, a:data)
else
return 0
endif
return 1
endfunction
" Send a message to an LSP server.
" Notifications do not need to be handled.
"
" Returns -1 when a message is sent, but no response is expected
" 0 when the message is not sent and
" >= 1 with the message ID when a response is expected.
1 0.000001 function! ale#lsp#Send(conn_id, message) abort
let l:conn = get(s:connections, a:conn_id, {})
if empty(l:conn)
return 0
endif
if !l:conn.initialized
throw 'LSP server not initialized yet!'
endif
let [l:id, l:data] = ale#lsp#CreateMessageData(a:message)
call s:SendMessageData(l:conn, l:data)
return l:id == 0 ? -1 : l:id
endfunction
" Notify LSP servers or tsserver if a document is opened, if needed.
" If a document is opened, 1 will be returned, otherwise 0 will be returned.
1 0.000001 function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort
let l:conn = get(s:connections, a:conn_id, {})
let l:opened = 0
if !empty(l:conn) && !has_key(l:conn.open_documents, a:buffer)
if l:conn.is_tsserver
let l:message = ale#lsp#tsserver_message#Open(a:buffer)
else
let l:message = ale#lsp#message#DidOpen(a:buffer, a:language_id)
endif
call ale#lsp#Send(a:conn_id, l:message)
let l:conn.open_documents[a:buffer] = getbufvar(a:buffer, 'changedtick')
let l:opened = 1
endif
return l:opened
endfunction
" Notify LSP servers or tsserver that a document is closed, if opened before.
" If a document is closed, 1 will be returned, otherwise 0 will be returned.
"
" Only the buffer number is required here. A message will be sent to every
" language server that was notified previously of the document being opened.
1 0.000001 function! ale#lsp#CloseDocument(buffer) abort
let l:closed = 0
" The connection keys are sorted so the messages are easier to test, and
" so messages are sent in a consistent order.
for l:conn_id in sort(keys(s:connections))
let l:conn = s:connections[l:conn_id]
if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
if l:conn.is_tsserver
let l:message = ale#lsp#tsserver_message#Close(a:buffer)
else
let l:message = ale#lsp#message#DidClose(a:buffer)
endif
call ale#lsp#Send(l:conn_id, l:message)
call remove(l:conn.open_documents, a:buffer)
let l:closed = 1
endif
endfor
return l:closed
endfunction
" Notify LSP servers or tsserver that a document has changed, if needed.
" If a notification is sent, 1 will be returned, otherwise 0 will be returned.
1 0.000003 function! ale#lsp#NotifyForChanges(conn_id, buffer) abort
let l:conn = get(s:connections, a:conn_id, {})
let l:notified = 0
if !empty(l:conn) && has_key(l:conn.open_documents, a:buffer)
let l:new_tick = getbufvar(a:buffer, 'changedtick')
if l:conn.open_documents[a:buffer] < l:new_tick
if l:conn.is_tsserver
let l:message = ale#lsp#tsserver_message#Change(a:buffer)
else
let l:message = ale#lsp#message#DidChange(a:buffer)
endif
call ale#lsp#Send(a:conn_id, l:message)
let l:conn.open_documents[a:buffer] = l:new_tick
let l:notified = 1
endif
endif
return l:notified
endfunction
" Wait for an LSP server to be initialized.
1 0.000001 function! ale#lsp#OnInit(conn_id, Callback) abort
let l:conn = get(s:connections, a:conn_id, {})
if empty(l:conn)
return
endif
if l:conn.initialized
call a:Callback()
else
call add(l:conn.init_queue, a:Callback)
endif
endfunction
" Check if an LSP has a given capability.
1 0.000001 function! ale#lsp#HasCapability(conn_id, capability) abort
let l:conn = get(s:connections, a:conn_id, {})
if empty(l:conn)
return 0
endif
if type(get(l:conn.capabilities, a:capability, v:null)) isnot v:t_number
throw 'Invalid capability ' . a:capability
endif
return l:conn.capabilities[a:capability]
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp/message.vim
Sourced 1 time
Total time: 0.000308
Self time: 0.000308
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Language Server Protocol message implementations
"
" Messages in this movie will be returned in the format
" [is_notification, method_name, params?]
"
" All functions which accept line and column arguments expect them to be 1-based
" (the same format as being returned by getpos() and friends), those then
" will be converted to 0-based as specified by LSP.
1 0.000005 let g:ale_lsp_next_version_id = 1
" The LSP protocols demands that we send every change to a document, including
" undo, with incrementing version numbers, so we'll just use one incrementing
" ID for everything.
1 0.000001 function! ale#lsp#message#GetNextVersionID() abort
" Use the current ID
let l:id = g:ale_lsp_next_version_id
" Increment the ID variable.
let g:ale_lsp_next_version_id += 1
" When the ID overflows, reset it to 1. By the time we hit the initial ID
" again, the messages will be long gone.
if g:ale_lsp_next_version_id < 1
let g:ale_lsp_next_version_id = 1
endif
return l:id
endfunction
1 0.000001 function! ale#lsp#message#Initialize(root_path, options, capabilities) abort
" NOTE: rootPath is deprecated in favour of rootUri
return [0, 'initialize', {
\ 'processId': getpid(),
\ 'rootPath': a:root_path,
\ 'capabilities': a:capabilities,
\ 'initializationOptions': a:options,
\ 'rootUri': ale#path#ToURI(a:root_path),
\}]
endfunction
1 0.000001 function! ale#lsp#message#Initialized() abort
return [1, 'initialized', {}]
endfunction
1 0.000001 function! ale#lsp#message#Shutdown() abort
return [0, 'shutdown']
endfunction
1 0.000001 function! ale#lsp#message#Exit() abort
return [1, 'exit']
endfunction
1 0.000001 function! ale#lsp#message#DidOpen(buffer, language_id) abort
let l:lines = getbufline(a:buffer, 1, '$')
return [1, 'textDocument/didOpen', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'languageId': a:language_id,
\ 'version': ale#lsp#message#GetNextVersionID(),
\ 'text': join(l:lines, "\n") . "\n",
\ },
\}]
endfunction
1 0.000001 function! ale#lsp#message#DidChange(buffer) abort
let l:lines = getbufline(a:buffer, 1, '$')
" For changes, we simply send the full text of the document to the server.
return [1, 'textDocument/didChange', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'version': ale#lsp#message#GetNextVersionID(),
\ },
\ 'contentChanges': [{'text': join(l:lines, "\n") . "\n"}]
\}]
endfunction
1 0.000001 function! ale#lsp#message#DidSave(buffer, includeText) abort
let l:response = [1, 'textDocument/didSave', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\}]
if a:includeText
let l:response[2].textDocument.version = ale#lsp#message#GetNextVersionID()
let l:response[2].text = ale#util#GetBufferContents(a:buffer)
endif
return l:response
endfunction
1 0.000001 function! ale#lsp#message#DidClose(buffer) abort
return [1, 'textDocument/didClose', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\}]
endfunction
1 0.000001 let s:COMPLETION_TRIGGER_INVOKED = 1
1 0.000001 let s:COMPLETION_TRIGGER_CHARACTER = 2
1 0.000001 function! ale#lsp#message#Completion(buffer, line, column, trigger_character) abort
let l:message = [0, 'textDocument/completion', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
if !empty(a:trigger_character)
let l:message[2].context = {
\ 'triggerKind': s:COMPLETION_TRIGGER_CHARACTER,
\ 'triggerCharacter': a:trigger_character,
\}
endif
return l:message
endfunction
1 0.000001 function! ale#lsp#message#Definition(buffer, line, column) abort
return [0, 'textDocument/definition', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
endfunction
1 0.000001 function! ale#lsp#message#TypeDefinition(buffer, line, column) abort
return [0, 'textDocument/typeDefinition', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
endfunction
1 0.000001 function! ale#lsp#message#References(buffer, line, column) abort
return [0, 'textDocument/references', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\ 'context': {'includeDeclaration': v:false},
\}]
endfunction
1 0.000001 function! ale#lsp#message#Symbol(query) abort
return [0, 'workspace/symbol', {
\ 'query': a:query,
\}]
endfunction
1 0.000001 function! ale#lsp#message#Hover(buffer, line, column) abort
return [0, 'textDocument/hover', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\}]
endfunction
1 0.000001 function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
return [1, 'workspace/didChangeConfiguration', {
\ 'settings': a:config,
\}]
endfunction
1 0.000001 function! ale#lsp#message#Rename(buffer, line, column, new_name) abort
return [0, 'textDocument/rename', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\ 'newName': a:new_name,
\}]
endfunction
1 0.000004 function! ale#lsp#message#CodeAction(buffer, line, column, end_line, end_column, diagnostics) abort
return [0, 'textDocument/codeAction', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'range': {
\ 'start': {'line': a:line - 1, 'character': a:column - 1},
\ 'end': {'line': a:end_line - 1, 'character': a:end_column},
\ },
\ 'context': {
\ 'diagnostics': a:diagnostics
\ },
\}]
endfunction
1 0.000001 function! ale#lsp#message#ExecuteCommand(command, arguments) abort
return [0, 'workspace/executeCommand', {
\ 'command': a:command,
\ 'arguments': a:arguments,
\}]
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/uri.vim
Sourced 1 time
Total time: 0.000183
Self time: 0.000183
count total (s) self (s)
1 0.000004 function! s:EncodeChar(char) abort
let l:result = ''
for l:index in range(strlen(a:char))
let l:result .= printf('%%%02x', char2nr(a:char[l:index]))
endfor
return l:result
endfunction
1 0.000001 function! ale#uri#Encode(value) abort
return substitute(
\ a:value,
\ '\([^a-zA-Z0-9\\/$\-_.!*''(),]\)',
\ '\=s:EncodeChar(submatch(1))',
\ 'g'
\)
endfunction
1 0.000001 function! ale#uri#Decode(value) abort
return substitute(
\ a:value,
\ '%\(\x\x\)',
\ '\=printf("%c", str2nr(submatch(1), 16))',
\ 'g'
\)
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/guru.vim
Sourced 1 time
Total time: 0.000267
Self time: 0.000267
count total (s) self (s)
" guru.vim -- Vim integration for the Go guru.
" don't spam the user when Vim is started in Vi compatibility mode
1 0.000007 let s:cpo_save = &cpo
1 0.000005 set cpo&vim
" guru_cmd returns a dict that contains the command to execute guru. args
" is dict with following options:
" mode : guru mode, such as 'implements'
" format : output format, either 'plain' or 'json'
" needs_scope : if 1, adds the current package to the scope
" selected : if 1, means it's a range of selection, otherwise it picks up the
" offset under the cursor
" example output:
" {'cmd' : ['guru', '-json', 'implements', 'demo/demo.go:#66']}
1 0.000002 function! s:guru_cmd(args) range abort
"if !go#package#InGOPATH()
"return {'err': 'guru only supports packages within GOPATH'}
"endif
let mode = a:args.mode
let format = a:args.format
let needs_scope = a:args.needs_scope
let selected = a:args.selected
let postype = get(a:args, 'postype', 'cursor')
let result = {}
"return with a warning if the binary doesn't exist
let bin_path = go#path#CheckBinPath("guru")
if empty(bin_path)
return {'err': "bin path not found"}
endif
" start constructing the command
let cmd = [bin_path, '-tags', go#config#BuildTags()]
if &modified
let result.stdin_content = go#util#archive()
call add(cmd, "-modified")
endif
" enable outputting in json format
if format == "json"
call add(cmd, "-json")
endif
let scopes = go#config#GuruScope()
if empty(scopes)
" some modes require scope to be defined (such as callers). For these we
" choose a sensible setting, which is using the current file's package
if needs_scope
let pkg = go#package#ImportPath()
if pkg == -1
return {'err': "current directory is not inside of a valid GOPATH"}
endif
let scopes = [pkg]
endif
endif
" Add the scope.
if !empty(scopes)
" guru expect a comma-separated list of patterns.
let l:scope = join(scopes, ",")
let result.scope = l:scope
call extend(cmd, ["-scope", l:scope])
endif
if postype == 'balloon'
let pos = printf("#%s", go#util#Offset(v:beval_lnum, v:beval_col))
else
let pos = printf("#%s", go#util#OffsetCursor())
if selected != -1
" means we have a range, get it
let pos1 = go#util#Offset(line("'<"), col("'<"))
let pos2 = go#util#Offset(line("'>"), col("'>"))
let pos = printf("#%s,#%s", pos1, pos2)
endif
endif
let l:filename = fnamemodify(expand("%"), ':p:gs?\\?/?') . ':' . pos
call extend(cmd, [mode, l:filename])
let result.cmd = cmd
return result
endfunction
" sync_guru runs guru in sync mode with the given arguments
1 0.000001 function! s:sync_guru(args) abort
let result = s:guru_cmd(a:args)
if has_key(result, 'err')
call go#util#EchoError(result.err)
return -1
endif
if !has_key(a:args, 'disable_progress')
if a:args.needs_scope
call go#util#EchoProgress("analysing with scope ". result.scope .
\ " (see ':help go-guru-scope' if this doesn't work)...")
elseif a:args.mode !=# 'what'
" the query might take time, let us give some feedback
call go#util#EchoProgress("analysing ...")
endif
endif
" run, forrest run!!!
if has_key(l:result, 'stdin_content')
let [l:out, l:err] = go#util#Exec(l:result.cmd, l:result.stdin_content)
else
let [l:out, l:err] = go#util#Exec(l:result.cmd)
endif
if has_key(a:args, 'custom_parse')
call a:args.custom_parse(l:err, l:out, a:args.mode)
else
call s:parse_guru_output(l:err, l:out, a:args.mode)
endif
return l:out
endfunc
" async_guru runs guru in async mode with the given arguments
1 0.000001 function! s:async_guru(args) abort
let result = s:guru_cmd(a:args)
if has_key(result, 'err')
call go#util#EchoError(result.err)
return
endif
let state = {
\ 'mode': a:args.mode,
\ 'parse' : get(a:args, 'custom_parse', funcref("s:parse_guru_output"))
\ }
" explicitly bind complete to state so that within it, self will
" always refer to state. See :help Partial for more information.
let state.complete = function('s:complete', [], state)
let opts = {
\ 'statustype': get(a:args, 'statustype', a:args.mode),
\ 'for': '_',
\ 'errorformat': "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m",
\ 'complete': state.complete,
\ }
if has_key(a:args, 'disable_progress')
let opts.statustype = ''
endif
let opts = go#job#Options(l:opts)
if has_key(result, 'stdin_content')
let l:tmpname = tempname()
call writefile(split(result.stdin_content, "\n"), l:tmpname, "b")
let l:opts.in_io = "file"
let l:opts.in_name = l:tmpname
endif
call go#job#Start(result.cmd, opts)
if a:args.needs_scope && go#config#EchoCommandInfo() && !has_key(a:args, 'disable_progress')
call go#util#EchoProgress("analysing with scope " . result.scope .
\ " (see ':help go-guru-scope' if this doesn't work)...")
endif
endfunc
1 0.000001 function! s:complete(job, exit_status, messages) dict abort
let output = join(a:messages, "\n")
call self.parse(a:exit_status, output, self.mode)
endfunction
" run_guru runs the given guru argument
1 0.000001 function! s:run_guru(args) abort
if go#util#has_job()
let res = s:async_guru(a:args)
else
let res = s:sync_guru(a:args)
endif
return res
endfunction
" Show 'implements' relation for selected package
1 0.000001 function! go#guru#Implements(selected) abort
let args = {
\ 'mode': 'implements',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 1,
\ }
call s:run_guru(args)
endfunction
" Shows the set of possible objects to which a pointer may point.
1 0.000001 function! go#guru#PointsTo(selected) abort
let l:args = {
\ 'mode': 'pointsto',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 1,
\ }
call s:run_guru(l:args)
endfunction
" Report the possible constants, global variables, and concrete types that may
" appear in a value of type error
1 0.000001 function! go#guru#Whicherrs(selected) abort
let args = {
\ 'mode': 'whicherrs',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 1,
\ }
" TODO(arslan): handle empty case for both sync/async
" if empty(out.out)
" call go#util#EchoSuccess("no error variables found. Try to change the scope with :GoGuruScope")
" return
" endif
call s:run_guru(args)
endfunction
" Describe selected syntax: definition, methods, etc
1 0.000001 function! go#guru#Describe(selected) abort
let args = {
\ 'mode': 'describe',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 1,
\ }
call s:run_guru(args)
endfunction
1 0.000001 function! go#guru#DescribeInfo(showstatus) abort
" check if the version of Vim being tested supports json_decode()
if !exists("*json_decode")
call go#util#EchoError("GoDescribeInfo requires 'json_decode'. Update your Vim/Neovim version.")
return
endif
let args = {
\ 'mode': 'describe',
\ 'format': 'json',
\ 'selected': -1,
\ 'needs_scope': 0,
\ 'custom_parse': function('s:info'),
\ 'disable_progress': a:showstatus == 0,
\ }
call s:run_guru(args)
endfunction
1 0.000001 function! s:info(exit_val, output, mode)
if a:exit_val != 0
return
endif
if a:output[0] !=# '{'
return
endif
if empty(a:output) || type(a:output) != type("")
return
endif
let result = json_decode(a:output)
if type(result) != type({})
call go#util#EchoError(printf("malformed output from guru: %s", a:output))
return
endif
if !has_key(result, 'detail')
" if there is no detail check if there is a description and print it
if has_key(result, "desc")
call go#util#EchoInfo(result["desc"])
return
endif
call go#util#EchoError("detail key is missing. Please open a bug report on vim-go repo.")
return
endif
let detail = result['detail']
let info = ""
" guru gives different information based on the detail mode. Let try to
" extract the most useful information
if detail == "value"
if !has_key(result, 'value')
call go#util#EchoError("value key is missing. Please open a bug report on vim-go repo.")
return
endif
let val = result["value"]
if !has_key(val, 'type')
call go#util#EchoError("type key is missing (value.type). Please open a bug report on vim-go repo.")
return
endif
let info = val["type"]
elseif detail == "type"
if !has_key(result, 'type')
call go#util#EchoError("type key is missing. Please open a bug report on vim-go repo.")
return
endif
let type = result["type"]
if !has_key(type, 'type')
call go#util#EchoError("type key is missing (type.type). Please open a bug report on vim-go repo.")
return
endif
let info = type["type"]
elseif detail == "package"
if !has_key(result, 'package')
call go#util#EchoError("package key is missing. Please open a bug report on vim-go repo.")
return
endif
let package = result["package"]
if !has_key(package, 'path')
call go#util#EchoError("path key is missing (package.path). Please open a bug report on vim-go repo.")
return
endif
let info = printf("package %s", package["path"])
elseif detail == "unknown"
let info = result["desc"]
else
call go#util#EchoError(printf("unknown detail mode found '%s'. Please open a bug report on vim-go repo", detail))
return
endif
call go#util#ShowInfo(info)
endfunction
" Show possible targets of selected function call
1 0.000001 function! go#guru#Callees(selected) abort
let args = {
\ 'mode': 'callees',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 1,
\ }
call s:run_guru(args)
endfunction
" Show path from callgraph root to selected function
1 0.000001 function! go#guru#Callstack(selected) abort
let args = {
\ 'mode': 'callstack',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 1,
\ }
call s:run_guru(args)
endfunction
" Show free variables of selection
1 0.000000 function! go#guru#Freevars(selected) abort
" Freevars requires a selection
if a:selected == -1
call go#util#EchoError("GoFreevars requires a selection (range) of code")
return
endif
let args = {
\ 'mode': 'freevars',
\ 'format': 'plain',
\ 'selected': 1,
\ 'needs_scope': 0,
\ }
call s:run_guru(args)
endfunction
" Show send/receive corresponding to selected channel op
1 0.000001 function! go#guru#ChannelPeers(selected) abort
let args = {
\ 'mode': 'peers',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 1,
\ }
call s:run_guru(args)
endfunction
" Show all refs to entity denoted by selected identifier
1 0.000001 function! go#guru#Referrers(selected) abort
let args = {
\ 'mode': 'referrers',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 0,
\ }
call s:run_guru(args)
endfunction
" TODO(bc) factor into a new file, sameids.vim and get rid of the guru adapter
" in lsp.vim.
1 0.000001 function! go#guru#SameIds(showstatus) abort
" check if the version of Vim being tested supports matchaddpos()
if !exists("*matchaddpos")
call go#util#EchoError("GoSameIds requires 'matchaddpos'. Update your Vim/Neovim version.")
return
endif
" check if the version of Vim being tested supports json_decode()
if !exists("*json_decode")
call go#util#EchoError("GoSameIds requires 'json_decode'. Update your Vim/Neovim version.")
return
endif
let [l:line, l:col] = getpos('.')[1:2]
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
call go#lsp#SameIDs(0, expand('%:p'), l:line, l:col, funcref('s:same_ids_highlight'))
endfunction
1 0.000001 function! s:same_ids_highlight(exit_val, output, mode) abort
call go#guru#ClearSameIds() " run after calling guru to reduce flicker.
if a:output[0] !=# '{'
if !go#config#AutoSameids()
call go#util#EchoError(a:output)
endif
return
endif
let result = json_decode(a:output)
if type(result) != type({}) && !go#config#AutoSameids()
call go#util#EchoError("malformed output from guru")
return
endif
if !has_key(result, 'sameids')
if !go#config#AutoSameids()
call go#util#EchoError("no same_ids founds for the given identifier")
endif
return
endif
let poslen = 0
for enclosing in result['enclosing']
if enclosing['desc'] == 'identifier'
let poslen = enclosing['end'] - enclosing['start']
break
endif
endfor
" return when there's no identifier to highlight.
if poslen == 0
return
endif
let same_ids = result['sameids']
" highlight the lines
let l:matches = []
for item in same_ids
let pos = split(item, ':')
let l:matches = add(l:matches, [str2nr(pos[-2]), str2nr(pos[-1]), str2nr(poslen)])
endfor
call go#util#HighlightPositions('goSameId', l:matches)
if go#config#AutoSameids()
" re-apply SameIds at the current cursor position at the time the buffer
" is redisplayed: e.g. :edit, :GoRename, etc.
augroup vim-go-sameids
autocmd! * <buffer>
if has('textprop')
autocmd BufReadPost <buffer> nested call go#guru#SameIds(0)
else
autocmd BufWinEnter <buffer> nested call go#guru#SameIds(0)
endif
augroup end
endif
endfunction
" ClearSameIds returns 0 when it removes goSameId groups and non-zero if no
" goSameId groups are found.
1 0.000001 function! go#guru#ClearSameIds() abort
let l:cleared = go#util#ClearHighlights('goSameId')
if !l:cleared
return 1
endif
" remove the autocmds we defined
augroup vim-go-sameids
autocmd! * <buffer>
augroup end
return 0
endfunction
1 0.000001 function! go#guru#ToggleSameIds() abort
if go#guru#ClearSameIds() != 0
call go#guru#SameIds(1)
endif
endfunction
1 0.000001 function! go#guru#AutoToggleSameIds() abort
if go#config#AutoSameids()
call go#util#EchoProgress("sameids auto highlighting disabled")
call go#guru#ClearSameIds()
call go#config#SetAutoSameids(0)
else
call go#util#EchoSuccess("sameids auto highlighting enabled")
call go#config#SetAutoSameids(1)
endif
call go#auto#update_autocmd()
endfunction
""""""""""""""""""""""""""""""""""""""""
"" HELPER FUNCTIONS
""""""""""""""""""""""""""""""""""""""""
" This uses Vim's errorformat to parse the output from Guru's 'plain output
" and put it into location list. I believe using errorformat is much more
" easier to use. If we need more power we can always switch back to parse it
" via regex. Match two possible styles of errorformats:
"
" 'file:line.col-line2.col2: message'
" 'file:line:col: message'
"
" We discard line2 and col2 for the first errorformat, because it's not
" useful and location only has the ability to show one line and column
" number
1 0.000001 function! s:parse_guru_output(exit_val, output, title) abort
if a:exit_val
call go#util#EchoError(a:output)
return
endif
let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
let l:listtype = go#list#Type("_guru")
call go#list#ParseFormat(l:listtype, errformat, a:output, a:title, 0)
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
endfunction
1 0.000001 function! go#guru#Scope(...) abort
if a:0
let scope = a:000
if a:0 == 1 && a:1 == '""'
let scope = []
endif
call go#config#SetGuruScope(scope)
if empty(scope)
call go#util#EchoSuccess("guru scope is cleared")
else
call go#util#EchoSuccess("guru scope changed to: ". join(a:000, ","))
endif
return
endif
let scope = go#config#GuruScope()
if empty(scope)
call go#util#EchoError("guru scope is not set")
else
call go#util#EchoSuccess("current guru scope: ". join(scope, ","))
endif
endfunction
" restore Vi compatibility settings
1 0.000003 let &cpo = s:cpo_save
1 0.000002 unlet s:cpo_save
" vim: sw=2 ts=2 et
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/cursor.vim
Sourced 1 time
Total time: 0.000142
Self time: 0.000142
count total (s) self (s)
1 0.000020 scriptencoding utf-8
" Author: w0rp <devw0rp@gmail.com>
" Author: João Paulo S. de Souza <joao.paulo.silvasouza@hotmail.com>
" Description: Echoes lint message for the current line, if any
" Controls the milliseconds delay before echoing a message.
1 0.000006 let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10)
" A string format for the echoed message.
1 0.000003 let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s')
1 0.000001 let s:cursor_timer = -1
1 0.000003 function! ale#cursor#TruncatedEcho(original_message) abort
let l:message = a:original_message
" Change tabs to spaces.
let l:message = substitute(l:message, "\t", ' ', 'g')
" Remove any newlines in the message.
let l:message = substitute(l:message, "\n", '', 'g')
" We need to remember the setting for shortmess and reset it again.
let l:shortmess_options = &l:shortmess
try
let l:cursor_position = getpos('.')
" The message is truncated and saved to the history.
silent! setlocal shortmess+=T
try
exec "norm! :echomsg l:message\n"
catch /^Vim\%((\a\+)\)\=:E523/
" Fallback into manual truncate (#1987)
let l:winwidth = winwidth(0)
if l:winwidth < strdisplaywidth(l:message)
" Truncate message longer than window width with trailing '...'
let l:message = l:message[:l:winwidth - 4] . '...'
endif
exec 'echomsg l:message'
catch /E481/
" Do nothing if running from a visual selection.
endtry
" Reset the cursor position if we moved off the end of the line.
" Using :norm and :echomsg can move the cursor off the end of the
" line.
if l:cursor_position != getpos('.')
call setpos('.', l:cursor_position)
endif
finally
let &l:shortmess = l:shortmess_options
endtry
endfunction
1 0.000001 function! s:StopCursorTimer() abort
if s:cursor_timer != -1
call timer_stop(s:cursor_timer)
let s:cursor_timer = -1
endif
endfunction
1 0.000001 function! ale#cursor#EchoCursorWarning(...) abort
let l:buffer = bufnr('')
if !g:ale_echo_cursor && !g:ale_cursor_detail
return
endif
" Only echo the warnings in normal mode, otherwise we will get problems.
if mode(1) isnot# 'n'
return
endif
if ale#ShouldDoNothing(l:buffer)
return
endif
let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
if g:ale_echo_cursor
if !empty(l:loc)
let l:format = ale#Var(l:buffer, 'echo_msg_format')
let l:msg = ale#GetLocItemMessage(l:loc, l:format)
call ale#cursor#TruncatedEcho(l:msg)
let l:info.echoed = 1
elseif get(l:info, 'echoed')
" We'll only clear the echoed message when moving off errors once,
" so we don't continually clear the echo line.
execute 'echo'
let l:info.echoed = 0
endif
endif
if g:ale_cursor_detail
if !empty(l:loc)
call s:ShowCursorDetailForItem(l:loc, {'stay_here': 1})
else
call ale#preview#CloseIfTypeMatches('ale-preview')
endif
endif
endfunction
1 0.000001 function! ale#cursor#EchoCursorWarningWithDelay() abort
let l:buffer = bufnr('')
if !g:ale_echo_cursor && !g:ale_cursor_detail
return
endif
" Only echo the warnings in normal mode, otherwise we will get problems.
if mode(1) isnot# 'n'
return
endif
call s:StopCursorTimer()
let l:pos = getpos('.')[0:2]
if !exists('w:last_pos')
let w:last_pos = [0, 0, 0]
endif
" Check the current buffer, line, and column number against the last
" recorded position. If the position has actually changed, *then*
" we should echo something. Otherwise we can end up doing processing
" the echo message far too frequently.
if l:pos != w:last_pos
let l:delay = ale#Var(l:buffer, 'echo_delay')
let w:last_pos = l:pos
let s:cursor_timer = timer_start(
\ l:delay,
\ function('ale#cursor#EchoCursorWarning')
\)
endif
endfunction
1 0.000001 function! s:ShowCursorDetailForItem(loc, options) abort
let l:stay_here = get(a:options, 'stay_here', 0)
let s:last_detailed_line = line('.')
let l:message = get(a:loc, 'detail', a:loc.text)
let l:lines = split(l:message, "\n")
if g:ale_floating_preview || g:ale_detail_to_floating_preview
call ale#floating_preview#Show(l:lines)
else
call ale#preview#Show(l:lines, {'stay_here': l:stay_here})
" Clear the echo message if we manually displayed details.
if !l:stay_here
execute 'echo'
endif
endif
endfunction
1 0.000001 function! ale#cursor#ShowCursorDetail() abort
let l:buffer = bufnr('')
" Only echo the warnings in normal mode, otherwise we will get problems.
if mode() isnot# 'n'
return
endif
if ale#ShouldDoNothing(l:buffer)
return
endif
call s:StopCursorTimer()
let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
if !empty(l:loc)
call s:ShowCursorDetailForItem(l:loc, {'stay_here': 0})
endif
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_window.vim
Sourced 1 time
Total time: 0.000206
Self time: 0.000206
count total (s) self (s)
" Author: suoto <andre820@gmail.com>
" Description: Handling of window/* LSP methods, although right now only
" handles window/showMessage
" Constants for message type codes
1 0.000005 let s:LSP_MESSAGE_TYPE_DISABLED = 0
1 0.000001 let s:LSP_MESSAGE_TYPE_ERROR = 1
1 0.000001 let s:LSP_MESSAGE_TYPE_WARNING = 2
1 0.000001 let s:LSP_MESSAGE_TYPE_INFORMATION = 3
1 0.000001 let s:LSP_MESSAGE_TYPE_LOG = 4
" Translate strings from the user config to a number so we can check
" severities
1 0.000007 let s:CFG_TO_LSP_SEVERITY = {
\ 'disabled': s:LSP_MESSAGE_TYPE_DISABLED,
\ 'error': s:LSP_MESSAGE_TYPE_ERROR,
\ 'warning': s:LSP_MESSAGE_TYPE_WARNING,
\ 'information': s:LSP_MESSAGE_TYPE_INFORMATION,
\ 'info': s:LSP_MESSAGE_TYPE_INFORMATION,
\ 'log': s:LSP_MESSAGE_TYPE_LOG
\}
" Handle window/showMessage response.
" - details: dict containing linter name and format (g:ale_lsp_show_message_format)
" - params: dict with the params for the call in the form of {type: number, message: string}
1 0.000002 function! ale#lsp_window#HandleShowMessage(linter_name, format, params) abort
let l:message = a:params.message
let l:type = a:params.type
" Get the configured severity level threshold and check if the message
" should be displayed or not
let l:configured_severity = tolower(get(g:, 'ale_lsp_show_message_severity', 'error'))
" If the user has configured with a value we can't find on the conversion
" dict, fall back to warning
let l:cfg_severity_threshold = get(s:CFG_TO_LSP_SEVERITY, l:configured_severity, s:LSP_MESSAGE_TYPE_WARNING)
if l:type > l:cfg_severity_threshold
return
endif
" Severity will depend on the message type
if l:type is# s:LSP_MESSAGE_TYPE_ERROR
let l:severity = g:ale_echo_msg_error_str
elseif l:type is# s:LSP_MESSAGE_TYPE_INFORMATION
let l:severity = g:ale_echo_msg_info_str
elseif l:type is# s:LSP_MESSAGE_TYPE_LOG
let l:severity = g:ale_echo_msg_log_str
else
" Default to warning just in case
let l:severity = g:ale_echo_msg_warning_str
endif
let l:string = substitute(a:format, '\V%severity%', l:severity, 'g')
let l:string = substitute(l:string, '\V%linter%', a:linter_name, 'g')
let l:string = substitute(l:string, '\V%s\>', l:message, 'g')
call ale#util#ShowMessage(l:string)
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/handlers/unix.vim
Sourced 1 time
Total time: 0.000206
Self time: 0.000206
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Error handling for errors in a Unix format.
1 0.000003 function! s:HandleUnixFormat(buffer, lines, type) abort
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):?(\d+)?:? ?(.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': a:type,
\})
endfor
return l:output
endfunction
1 0.000003 function! ale#handlers#unix#HandleAsError(buffer, lines) abort
return s:HandleUnixFormat(a:buffer, a:lines, 'E')
endfunction
1 0.000001 function! ale#handlers#unix#HandleAsWarning(buffer, lines) abort
return s:HandleUnixFormat(a:buffer, a:lines, 'W')
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim
Sourced 1 time
Total time: 0.008833
Self time: 0.008698
count total (s) self (s)
1 0.000006 scriptencoding utf8
" Author: w0rp <devw0rp@gmail.com>
" Description: Draws error and warning signs into signcolumn
" This flag can be set to some integer to control the maximum number of signs
" that ALE will set.
1 0.000009 let g:ale_max_signs = get(g:, 'ale_max_signs', -1)
" This flag can be set to 1 to enable changing the sign column colors when
" there are errors.
1 0.000002 let g:ale_change_sign_column_color = get(g:, 'ale_change_sign_column_color', 0)
" These variables dictate what signs are used to indicate errors and warnings.
1 0.000002 let g:ale_sign_error = get(g:, 'ale_sign_error', '>>')
1 0.000002 let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error)
1 0.000003 let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--')
1 0.000002 let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning)
1 0.000002 let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
1 0.000001 let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
" This variable sets an offset which can be set for sign IDs.
" This ID can be changed depending on what IDs are set for other plugins.
" The dummy sign will use the ID exactly equal to the offset.
1 0.000001 let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
" This flag can be set to 1 to keep sign gutter always open
1 0.000001 let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
1 0.000002 let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0)
1 0.000003 let s:supports_sign_groups = has('nvim-0.4.2') || has('patch-8.1.614')
1 0.000008 if !hlexists('ALEErrorSign')
highlight link ALEErrorSign error
1 0.000001 endif
1 0.000009 if !hlexists('ALEStyleErrorSign')
1 0.000010 highlight link ALEStyleErrorSign ALEErrorSign
1 0.000000 endif
1 0.000002 if !hlexists('ALEWarningSign')
highlight link ALEWarningSign todo
1 0.000000 endif
1 0.000004 if !hlexists('ALEStyleWarningSign')
1 0.000005 highlight link ALEStyleWarningSign ALEWarningSign
1 0.000000 endif
1 0.000002 if !hlexists('ALEInfoSign')
highlight link ALEInfoSign ALEWarningSign
1 0.000000 endif
1 0.000004 if !hlexists('ALESignColumnWithErrors')
1 0.000007 highlight link ALESignColumnWithErrors error
1 0.000000 endif
1 0.000002 function! ale#sign#SetUpDefaultColumnWithoutErrorsHighlight() abort
let l:verbose = &verbose
set verbose=0
let l:output = execute('highlight SignColumn', 'silent')
let &verbose = l:verbose
let l:highlight_syntax = join(split(l:output)[2:])
let l:match = matchlist(l:highlight_syntax, '\vlinks to (.+)$')
if !empty(l:match)
execute 'highlight link ALESignColumnWithoutErrors ' . l:match[1]
elseif l:highlight_syntax isnot# 'cleared'
execute 'highlight ALESignColumnWithoutErrors ' . l:highlight_syntax
endif
endfunction
1 0.000004 if !hlexists('ALESignColumnWithoutErrors')
1 0.008115 0.008001 call ale#sign#SetUpDefaultColumnWithoutErrorsHighlight()
1 0.000001 endif
" Spaces and backslashes need to be escaped for signs.
1 0.000003 function! s:EscapeSignText(sign_text) abort
return substitute(substitute(a:sign_text, ' *$', '', ''), '\\\| ', '\\\0', 'g')
endfunction
" Signs show up on the left for error markers.
1 0.000024 0.000017 execute 'sign define ALEErrorSign text=' . s:EscapeSignText(g:ale_sign_error)
\ . ' texthl=ALEErrorSign linehl=ALEErrorLine'
1 0.000011 0.000007 execute 'sign define ALEStyleErrorSign text=' . s:EscapeSignText(g:ale_sign_style_error)
\ . ' texthl=ALEStyleErrorSign linehl=ALEErrorLine'
1 0.000013 0.000010 execute 'sign define ALEWarningSign text=' . s:EscapeSignText(g:ale_sign_warning)
\ . ' texthl=ALEWarningSign linehl=ALEWarningLine'
1 0.000009 0.000006 execute 'sign define ALEStyleWarningSign text=' . s:EscapeSignText(g:ale_sign_style_warning)
\ . ' texthl=ALEStyleWarningSign linehl=ALEWarningLine'
1 0.000096 0.000092 execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
1 0.000015 sign define ALEDummySign text=\ texthl=SignColumn
1 0.000005 if g:ale_sign_highlight_linenrs && has('nvim-0.3.2')
if !hlexists('ALEErrorSignLineNr')
highlight link ALEErrorSignLineNr CursorLineNr
endif
if !hlexists('ALEStyleErrorSignLineNr')
highlight link ALEStyleErrorSignLineNr CursorLineNr
endif
if !hlexists('ALEWarningSignLineNr')
highlight link ALEWarningSignLineNr CursorLineNr
endif
if !hlexists('ALEStyleWarningSignLineNr')
highlight link ALEStyleWarningSignLineNr CursorLineNr
endif
if !hlexists('ALEInfoSignLineNr')
highlight link ALEInfoSignLineNr CursorLineNr
endif
sign define ALEErrorSign numhl=ALEErrorSignLineNr
sign define ALEStyleErrorSign numhl=ALEStyleErrorSignLineNr
sign define ALEWarningSign numhl=ALEWarningSignLineNr
sign define ALEStyleWarningSign numhl=ALEStyleWarningSignLineNr
sign define ALEInfoSign numhl=ALEInfoSignLineNr
1 0.000000 endif
1 0.000003 function! ale#sign#GetSignName(sublist) abort
let l:priority = g:ale#util#style_warning_priority
" Determine the highest priority item for the line.
for l:item in a:sublist
let l:item_priority = ale#util#GetItemPriority(l:item)
if l:item_priority > l:priority
let l:priority = l:item_priority
endif
endfor
if l:priority is# g:ale#util#error_priority
return 'ALEErrorSign'
endif
if l:priority is# g:ale#util#warning_priority
return 'ALEWarningSign'
endif
if l:priority is# g:ale#util#style_error_priority
return 'ALEStyleErrorSign'
endif
if l:priority is# g:ale#util#style_warning_priority
return 'ALEStyleWarningSign'
endif
if l:priority is# g:ale#util#info_priority
return 'ALEInfoSign'
endif
" Use the error sign for invalid severities.
return 'ALEErrorSign'
endfunction
1 0.000001 function! s:PriorityCmd() abort
if s:supports_sign_groups
return ' priority=' . g:ale_sign_priority . ' '
else
return ''
endif
endfunction
1 0.000001 function! s:GroupCmd() abort
if s:supports_sign_groups
return ' group=ale '
else
return ' '
endif
endfunction
" Read sign data for a buffer to a list of lines.
1 0.000001 function! ale#sign#ReadSigns(buffer) abort
let l:output = execute(
\ 'sign place ' . s:GroupCmd() . s:PriorityCmd()
\ . ' buffer=' . a:buffer
\ )
return split(l:output, "\n")
endfunction
1 0.000001 function! ale#sign#ParsePattern() abort
if s:supports_sign_groups
" Matches output like :
" line=4 id=1 group=ale name=ALEErrorSign
" строка=1 id=1000001 группа=ale имя=ALEErrorSign
" 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign
" línea=12 id=1000001 grupo=ale nombre=ALEWarningSign
" riga=1 id=1000001 gruppo=ale nome=ALEWarningSign
" Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)'
else
" Matches output like :
" line=4 id=1 name=ALEErrorSign
" строка=1 id=1000001 имя=ALEErrorSign
" 行=1 識別子=1000001 名前=ALEWarningSign
" línea=12 id=1000001 nombre=ALEWarningSign
" riga=1 id=1000001 nome=ALEWarningSign
" Zeile=235 id=1000001 Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)'
endif
return l:pattern
endfunction
" Given a buffer number, return a List of placed signs [line, id, group]
1 0.000001 function! ale#sign#ParseSignsWithGetPlaced(buffer) abort
let l:signs = sign_getplaced(a:buffer, { 'group': s:supports_sign_groups ? 'ale' : '' })[0].signs
let l:result = []
let l:is_dummy_sign_set = 0
for l:sign in l:signs
if l:sign['name'] is# 'ALEDummySign'
let l:is_dummy_sign_set = 1
else
call add(l:result, [
\ str2nr(l:sign['lnum']),
\ str2nr(l:sign['id']),
\ l:sign['name'],
\])
endif
endfor
return [l:is_dummy_sign_set, l:result]
endfunction
" Given a list of lines for sign output, return a List of [line, id, group]
1 0.000001 function! ale#sign#ParseSigns(line_list) abort
let l:pattern =ale#sign#ParsePattern()
let l:result = []
let l:is_dummy_sign_set = 0
for l:line in a:line_list
let l:match = matchlist(l:line, l:pattern)
if len(l:match) > 0
if l:match[3] is# 'ALEDummySign'
let l:is_dummy_sign_set = 1
else
call add(l:result, [
\ str2nr(l:match[1]),
\ str2nr(l:match[2]),
\ l:match[3],
\])
endif
endif
endfor
return [l:is_dummy_sign_set, l:result]
endfunction
1 0.000002 function! ale#sign#FindCurrentSigns(buffer) abort
if exists('*sign_getplaced')
return ale#sign#ParseSignsWithGetPlaced(a:buffer)
else
let l:line_list = ale#sign#ReadSigns(a:buffer)
return ale#sign#ParseSigns(l:line_list)
endif
endfunction
" Given a loclist, group the List into with one List per line.
1 0.000001 function! s:GroupLoclistItems(buffer, loclist) abort
let l:grouped_items = []
let l:last_lnum = -1
for l:obj in a:loclist
if l:obj.bufnr != a:buffer
continue
endif
" Create a new sub-List when we hit a new line.
if l:obj.lnum != l:last_lnum
call add(l:grouped_items, [])
endif
call add(l:grouped_items[-1], l:obj)
let l:last_lnum = l:obj.lnum
endfor
return l:grouped_items
endfunction
1 0.000001 function! s:UpdateLineNumbers(buffer, current_sign_list, loclist) abort
let l:line_map = {}
let l:line_numbers_changed = 0
for [l:line, l:sign_id, l:name] in a:current_sign_list
let l:line_map[l:sign_id] = l:line
endfor
for l:item in a:loclist
if l:item.bufnr == a:buffer
let l:lnum = get(l:line_map, get(l:item, 'sign_id', 0), 0)
if l:lnum && l:item.lnum != l:lnum
let l:item.lnum = l:lnum
let l:line_numbers_changed = 1
endif
endif
endfor
" When the line numbers change, sort the list again
if l:line_numbers_changed
call sort(a:loclist, 'ale#util#LocItemCompare')
endif
endfunction
1 0.000001 function! s:BuildSignMap(buffer, current_sign_list, grouped_items) abort
let l:max_signs = ale#Var(a:buffer, 'max_signs')
if l:max_signs is 0
let l:selected_grouped_items = []
elseif type(l:max_signs) is v:t_number && l:max_signs > 0
let l:selected_grouped_items = a:grouped_items[:l:max_signs - 1]
else
let l:selected_grouped_items = a:grouped_items
endif
let l:sign_map = {}
let l:sign_offset = g:ale_sign_offset
for [l:line, l:sign_id, l:name] in a:current_sign_list
let l:sign_info = get(l:sign_map, l:line, {
\ 'current_id_list': [],
\ 'current_name_list': [],
\ 'new_id': 0,
\ 'new_name': '',
\ 'items': [],
\})
" Increment the sign offset for new signs, by the maximum sign ID.
if l:sign_id > l:sign_offset
let l:sign_offset = l:sign_id
endif
" Remember the sign names and IDs in separate Lists, so they are easy
" to work with.
call add(l:sign_info.current_id_list, l:sign_id)
call add(l:sign_info.current_name_list, l:name)
let l:sign_map[l:line] = l:sign_info
endfor
for l:group in l:selected_grouped_items
let l:line = l:group[0].lnum
let l:sign_info = get(l:sign_map, l:line, {
\ 'current_id_list': [],
\ 'current_name_list': [],
\ 'new_id': 0,
\ 'new_name': '',
\ 'items': [],
\})
let l:sign_info.new_name = ale#sign#GetSignName(l:group)
let l:sign_info.items = l:group
let l:index = index(
\ l:sign_info.current_name_list,
\ l:sign_info.new_name
\)
if l:index >= 0
" We have a sign with this name already, so use the same ID.
let l:sign_info.new_id = l:sign_info.current_id_list[l:index]
else
" This sign name replaces the previous name, so use a new ID.
let l:sign_info.new_id = l:sign_offset + 1
let l:sign_offset += 1
endif
let l:sign_map[l:line] = l:sign_info
endfor
return l:sign_map
endfunction
1 0.000001 function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
let l:command_list = []
let l:is_dummy_sign_set = a:was_sign_set
" Set the dummy sign if we need to.
" The dummy sign is needed to keep the sign column open while we add
" and remove signs.
if !l:is_dummy_sign_set && (!empty(a:sign_map) || g:ale_sign_column_always)
call add(l:command_list, 'sign place '
\ . g:ale_sign_offset
\ . s:GroupCmd()
\ . s:PriorityCmd()
\ . ' line=1 name=ALEDummySign '
\ . ' buffer=' . a:buffer
\)
let l:is_dummy_sign_set = 1
endif
" Place new items first.
for [l:line_str, l:info] in items(a:sign_map)
if l:info.new_id
" Save the sign IDs we are setting back on our loclist objects.
" These IDs will be used to preserve items which are set many times.
for l:item in l:info.items
let l:item.sign_id = l:info.new_id
endfor
if index(l:info.current_id_list, l:info.new_id) < 0
call add(l:command_list, 'sign place '
\ . (l:info.new_id)
\ . s:GroupCmd()
\ . s:PriorityCmd()
\ . ' line=' . l:line_str
\ . ' name=' . (l:info.new_name)
\ . ' buffer=' . a:buffer
\)
endif
endif
endfor
" Remove signs without new IDs.
for l:info in values(a:sign_map)
for l:current_id in l:info.current_id_list
if l:current_id isnot l:info.new_id
call add(l:command_list, 'sign unplace '
\ . l:current_id
\ . s:GroupCmd()
\ . ' buffer=' . a:buffer
\)
endif
endfor
endfor
" Remove the dummy sign to close the sign column if we need to.
if l:is_dummy_sign_set && !g:ale_sign_column_always
call add(l:command_list, 'sign unplace '
\ . g:ale_sign_offset
\ . s:GroupCmd()
\ . ' buffer=' . a:buffer
\)
endif
return l:command_list
endfunction
" This function will set the signs which show up on the left.
1 0.000001 function! ale#sign#SetSigns(buffer, loclist) abort
if !bufexists(str2nr(a:buffer))
" Stop immediately when attempting to set signs for a buffer which
" does not exist.
return
endif
" Find the current markers
let [l:is_dummy_sign_set, l:current_sign_list] =
\ ale#sign#FindCurrentSigns(a:buffer)
" Update the line numbers for items from before which may have moved.
call s:UpdateLineNumbers(a:buffer, l:current_sign_list, a:loclist)
" Group items after updating the line numbers.
let l:grouped_items = s:GroupLoclistItems(a:buffer, a:loclist)
" Build a map of current and new signs, with the lines as the keys.
let l:sign_map = s:BuildSignMap(
\ a:buffer,
\ l:current_sign_list,
\ l:grouped_items,
\)
let l:command_list = ale#sign#GetSignCommands(
\ a:buffer,
\ l:is_dummy_sign_set,
\ l:sign_map,
\)
" Change the sign column color if the option is on.
if g:ale_change_sign_column_color && !empty(a:loclist)
highlight clear SignColumn
highlight link SignColumn ALESignColumnWithErrors
endif
for l:command in l:command_list
silent! execute l:command
endfor
" Reset the sign column color when there are no more errors.
if g:ale_change_sign_column_color && empty(a:loclist)
highlight clear SignColumn
highlight link SignColumn ALESignColumnWithoutErrors
endif
endfunction
" Remove all signs.
1 0.000001 function! ale#sign#Clear() abort
if s:supports_sign_groups
sign unplace group=ale *
else
sign unplace *
endif
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/list.vim
Sourced 1 time
Total time: 0.000344
Self time: 0.000344
count total (s) self (s)
" Author: Bjorn Neergaard <bjorn@neersighted.com>, modified by Yann fery <yann@fery.me>
" Description: Manages the loclist and quickfix lists
" This flag dictates if ale open the configured loclist
1 0.000011 let g:ale_open_list = get(g:, 'ale_open_list', 0)
" This flag dictates if ale keeps open loclist even if there is no error in loclist
1 0.000002 let g:ale_keep_list_window_open = get(g:, 'ale_keep_list_window_open', 0)
" This flag dictates that quickfix windows should be opened vertically
1 0.000003 let g:ale_list_vertical = get(g:, 'ale_list_vertical', 0)
" The window size to set for the quickfix and loclist windows
1 0.000001 let g:ale_list_window_size = get(g:, 'ale_list_window_size', 10)
" A string format for the loclist messages.
1 0.000004 let g:ale_loclist_msg_format = get(g:, 'ale_loclist_msg_format',
\ get(g:, 'ale_echo_msg_format', '%code: %%s')
\)
1 0.000002 if !exists('s:timer_args')
1 0.000001 let s:timer_args = {}
1 0.000000 endif
" Return 1 if there is a buffer with buftype == 'quickfix' in bufffer list
1 0.000001 function! ale#list#IsQuickfixOpen() abort
let l:res = getqflist({ 'winid' : winnr() })
if has_key(l:res, 'winid') && l:res.winid > 0
return 1
endif
let l:res = getloclist(0, { 'winid' : winnr() })
if has_key(l:res, 'winid') && l:res.winid > 0
return 1
endif
return 0
endfunction
" Check if we should open the list, based on the save event being fired, and
" that setting being on, or the setting just being set to `1`.
1 0.000001 function! s:ShouldOpen(buffer) abort
let l:val = ale#Var(a:buffer, 'open_list')
let l:saved = getbufvar(a:buffer, 'ale_save_event_fired', 0)
return l:val is 1 || (l:val is# 'on_save' && l:saved)
endfunction
1 0.000001 function! s:Deduplicate(list) abort
let l:list = a:list
call sort(l:list, function('ale#util#LocItemCompareWithText'))
call uniq(l:list, function('ale#util#LocItemCompareWithText'))
return l:list
endfunction
1 0.000001 function! ale#list#GetCombinedList() abort
let l:list = []
for l:info in values(g:ale_buffer_info)
call extend(l:list, l:info.loclist)
endfor
return s:Deduplicate(l:list)
endfunction
1 0.000001 function! s:FixList(buffer, list) abort
let l:format = ale#Var(a:buffer, 'loclist_msg_format')
let l:new_list = []
for l:item in a:list
let l:fixed_item = copy(l:item)
let l:fixed_item.text = ale#GetLocItemMessage(l:item, l:format)
if l:item.bufnr == -1
" If the buffer number is invalid, remove it.
call remove(l:fixed_item, 'bufnr')
endif
call add(l:new_list, l:fixed_item)
endfor
return l:new_list
endfunction
1 0.000001 function! s:WinFindBuf(buffer) abort
return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0]
endfunction
1 0.000001 function! s:SetListsImpl(timer_id, buffer, loclist) abort
let l:title = expand('#' . a:buffer . ':p')
if g:ale_set_quickfix
let l:quickfix_list = ale#list#GetCombinedList()
if has('nvim')
call setqflist(s:FixList(a:buffer, l:quickfix_list), ' ', l:title)
else
call setqflist(s:FixList(a:buffer, l:quickfix_list))
call setqflist([], 'r', {'title': l:title})
endif
elseif g:ale_set_loclist
" If windows support is off, win_findbuf() may not exist.
" We'll set result in the current window, which might not be correct,
" but it's better than nothing.
let l:ids = s:WinFindBuf(a:buffer)
let l:loclist = s:Deduplicate(a:loclist)
for l:id in l:ids
if has('nvim')
call setloclist(l:id, s:FixList(a:buffer, l:loclist), ' ', l:title)
else
call setloclist(l:id, s:FixList(a:buffer, l:loclist))
call setloclist(l:id, [], 'r', {'title': l:title})
endif
endfor
endif
" Save the current view before opening/closing any window
call setbufvar(a:buffer, 'ale_winview', winsaveview())
" Open a window to show the problems if we need to.
"
" We'll check if the current buffer's List is not empty here, so the
" window will only be opened if the current buffer has problems.
if s:ShouldOpen(a:buffer) && !empty(a:loclist)
let l:winnr = winnr()
let l:mode = mode()
" open windows vertically instead of default horizontally
let l:open_type = ''
if ale#Var(a:buffer, 'list_vertical') == 1
let l:open_type = 'vert rightbelow '
endif
if g:ale_set_quickfix
if !ale#list#IsQuickfixOpen()
silent! execute l:open_type . 'copen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
endif
elseif g:ale_set_loclist
silent! execute l:open_type . 'lopen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
endif
" If focus changed, restore it (jump to the last window).
if l:winnr isnot# winnr()
wincmd p
endif
" Return to original mode when applicable
if mode() != l:mode
if l:mode is? 'v' || l:mode is# "\<c-v>"
" Reset our last visual selection
normal! gv
elseif l:mode is? 's' || l:mode is# "\<c-s>"
" Reset our last character selection
normal! "\<c-g>"
endif
endif
call s:RestoreViewIfNeeded(a:buffer)
endif
" If ALE isn't currently checking for more problems, close the window if
" needed now. This check happens inside of this timer function, so
" the window can be closed reliably.
if !ale#engine#IsCheckingBuffer(a:buffer)
call s:CloseWindowIfNeeded(a:buffer)
endif
endfunction
" Try to restore the window view after closing any of the lists to avoid making
" the it moving around, especially useful when on insert mode
1 0.000002 function! s:RestoreViewIfNeeded(buffer) abort
let l:saved_view = getbufvar(a:buffer, 'ale_winview', {})
" Saved view is empty, can't do anything
if empty(l:saved_view)
return
endif
" Check wether the cursor has moved since linting was actually requested. If
" the user has indeed moved lines, do nothing
let l:current_view = winsaveview()
if l:current_view['lnum'] != l:saved_view['lnum']
return
endif
" Anchor view by topline if the list is set to open horizontally
if ale#Var(a:buffer, 'list_vertical') == 0
call winrestview({'topline': l:saved_view['topline']})
endif
endfunction
1 0.000001 function! ale#list#SetLists(buffer, loclist) abort
if get(g:, 'ale_set_lists_synchronously') == 1
\|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
" Update lists immediately if running a test synchronously, or if the
" buffer was saved.
"
" The lists need to be updated immediately when saving a buffer so
" that we can reliably close window automatically, if so configured.
call s:SetListsImpl(-1, a:buffer, a:loclist)
else
call ale#util#StartPartialTimer(
\ 0,
\ function('s:SetListsImpl'),
\ [a:buffer, a:loclist],
\)
endif
endfunction
1 0.000001 function! s:CloseWindowIfNeeded(buffer) abort
if ale#Var(a:buffer, 'keep_list_window_open') || !s:ShouldOpen(a:buffer)
return
endif
let l:did_close_any_list = 0
try
" Only close windows if the quickfix list or loclist is completely empty,
" including errors set through other means.
if g:ale_set_quickfix
if empty(getqflist())
cclose
let l:did_close_any_list = 1
endif
else
let l:win_ids = s:WinFindBuf(a:buffer)
for l:win_id in l:win_ids
if g:ale_set_loclist && empty(getloclist(l:win_id))
lclose
let l:did_close_any_list = 1
endif
endfor
endif
" Ignore 'Cannot close last window' errors.
catch /E444/
endtry
if l:did_close_any_list
call s:RestoreViewIfNeeded(a:buffer)
endif
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/highlight.vim
Sourced 1 time
Total time: 0.000371
Self time: 0.000371
count total (s) self (s)
1 0.000020 scriptencoding utf8
" Author: w0rp <devw0rp@gmail.com>
" Description: This module implements error/warning highlighting.
1 0.000010 if !hlexists('ALEError')
highlight link ALEError SpellBad
1 0.000000 endif
1 0.000005 if !hlexists('ALEStyleError')
1 0.000008 highlight link ALEStyleError ALEError
1 0.000000 endif
1 0.000003 if !hlexists('ALEWarning')
highlight link ALEWarning SpellCap
1 0.000000 endif
1 0.000004 if !hlexists('ALEStyleWarning')
1 0.000007 highlight link ALEStyleWarning ALEWarning
1 0.000000 endif
1 0.000002 if !hlexists('ALEInfo')
highlight link ALEInfo ALEWarning
1 0.000000 endif
" The maximum number of items for the second argument of matchaddpos()
1 0.000001 let s:MAX_POS_VALUES = 8
1 0.000005 let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
1 0.000003 let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
1 0.000001 if s:has_nvim_highlight
1 0.000009 let s:ns_id = nvim_create_namespace('ale_highlight')
1 0.000000 endif
" Wrappers are necessary to test this functionality by faking the calls in tests.
1 0.000002 function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
" Ignore all errors for adding highlights.
try
call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
catch
endtry
endfunction
1 0.000002 function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end)
endfunction
1 0.000001 function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
if a:line >= a:end_line
" For single lines, just return the one position.
return [[[a:line, a:col, a:end_col - a:col + 1]]]
endif
" Get positions from the first line at the first column, up to a large
" integer for highlighting up to the end of the line, followed by
" the lines in-between, for highlighting entire lines, and
" a highlight for the last line, up to the end column.
let l:all_positions =
\ [[a:line, a:col, s:MAX_COL_SIZE]]
\ + range(a:line + 1, a:end_line - 1)
\ + [[a:end_line, 1, a:end_col]]
return map(
\ range(0, len(l:all_positions) - 1, s:MAX_POS_VALUES),
\ 'l:all_positions[v:val : v:val + s:MAX_POS_VALUES - 1]',
\)
endfunction
" Given a loclist for current items to highlight, remove all highlights
" except these which have matching loclist item entries.
1 0.000001 function! ale#highlight#RemoveHighlights() abort
if s:has_nvim_highlight
call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
else
for l:match in getmatches()
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
call matchdelete(l:match.id)
endif
endfor
endif
endfunction
" Same semantics of matchaddpos but will use nvim_buf_add_highlight if
" available. This involves iterating over the position list, switching from
" 1-based indexing to 0-based indexing, and translating the multiple ways
" that position can be specified for matchaddpos into line + col_start +
" col_end.
1 0.000001 function! s:matchaddpos(group, pos_list) abort
if s:has_nvim_highlight
for l:pos in a:pos_list
let l:line = type(l:pos) == v:t_number
\ ? l:pos - 1
\ : l:pos[0] - 1
if type(l:pos) == v:t_number || len(l:pos) == 1
let l:col_start = 0
let l:col_end = s:MAX_COL_SIZE
else
let l:col_start = l:pos[1] - 1
let l:col_end = l:col_start + get(l:pos, 2, 1)
endif
call ale#highlight#nvim_buf_add_highlight(
\ bufnr(''),
\ s:ns_id,
\ a:group,
\ l:line,
\ l:col_start,
\ l:col_end,
\)
endfor
else
call matchaddpos(a:group, a:pos_list)
endif
endfunction
1 0.000001 function! s:highlight_line(bufnr, lnum, group) abort
call s:matchaddpos(a:group, [a:lnum])
endfunction
1 0.000001 function! s:highlight_range(bufnr, range, group) abort
" Set all of the positions, which are chunked into Lists which
" are as large as will be accepted by matchaddpos.
call map(
\ ale#highlight#CreatePositions(
\ a:range.lnum,
\ a:range.col,
\ a:range.end_lnum,
\ a:range.end_col
\ ),
\ 's:matchaddpos(a:group, v:val)'
\)
endfunction
1 0.000001 function! ale#highlight#UpdateHighlights() abort
let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled
\ ? get(b:, 'ale_highlight_items', [])
\ : []
call ale#highlight#RemoveHighlights()
for l:item in l:item_list
if l:item.type is# 'W'
if get(l:item, 'sub_type', '') is# 'style'
let l:group = 'ALEStyleWarning'
else
let l:group = 'ALEWarning'
endif
elseif l:item.type is# 'I'
let l:group = 'ALEInfo'
elseif get(l:item, 'sub_type', '') is# 'style'
let l:group = 'ALEStyleError'
else
let l:group = 'ALEError'
endif
let l:range = {
\ 'lnum': l:item.lnum,
\ 'col': l:item.col,
\ 'end_lnum': get(l:item, 'end_lnum', l:item.lnum),
\ 'end_col': get(l:item, 'end_col', l:item.col)
\}
call s:highlight_range(l:item.bufnr, l:range, l:group)
endfor
" If highlights are enabled and signs are not enabled, we should still
" offer line highlights by adding a separate set of highlights.
if !g:ale_set_signs
let l:available_groups = {
\ 'ALEWarningLine': hlexists('ALEWarningLine'),
\ 'ALEInfoLine': hlexists('ALEInfoLine'),
\ 'ALEErrorLine': hlexists('ALEErrorLine'),
\}
for l:item in l:item_list
if l:item.type is# 'W'
let l:group = 'ALEWarningLine'
elseif l:item.type is# 'I'
let l:group = 'ALEInfoLine'
else
let l:group = 'ALEErrorLine'
endif
if l:available_groups[l:group]
call s:highlight_line(l:item.bufnr, l:item.lnum, l:group)
endif
endfor
endif
endfunction
1 0.000001 function! ale#highlight#BufferHidden(buffer) abort
" Remove highlights right away when buffers are hidden.
" They will be restored later when buffers are entered.
call ale#highlight#RemoveHighlights()
endfunction
1 0.000004 augroup ALEHighlightBufferGroup
1 0.000058 autocmd!
1 0.000023 autocmd BufEnter * call ale#highlight#UpdateHighlights()
1 0.000003 autocmd BufHidden * call ale#highlight#BufferHidden(expand('<abuf>'))
1 0.000001 augroup END
1 0.000002 function! ale#highlight#SetHighlights(buffer, loclist) abort
let l:new_list = getbufvar(a:buffer, 'ale_enabled', 1) && g:ale_enabled
\ ? filter(copy(a:loclist), 'v:val.bufnr == a:buffer && v:val.col > 0')
\ : []
" Set the list in the buffer variable.
call setbufvar(str2nr(a:buffer), 'ale_highlight_items', l:new_list)
let l:exclude_list = ale#Var(a:buffer, 'exclude_highlights')
if !empty(l:exclude_list)
call filter(l:new_list, 'empty(ale#util#GetMatches(v:val.text, l:exclude_list))')
endif
" Update highlights for the current buffer, which may or may not
" be the buffer we just set highlights for.
call ale#highlight#UpdateHighlights()
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/hover.vim
Sourced 1 time
Total time: 0.000346
Self time: 0.000346
count total (s) self (s)
" Author: w0rp <devw0rp@gmail.com>
" Description: Hover support for LSP linters.
1 0.000009 let s:hover_map = {}
" Used to get the hover map in tests.
1 0.000004 function! ale#hover#GetMap() abort
return deepcopy(s:hover_map)
endfunction
" Used to set the hover map in tests.
1 0.000002 function! ale#hover#SetMap(map) abort
let s:hover_map = a:map
endfunction
1 0.000001 function! ale#hover#ClearLSPData() abort
let s:hover_map = {}
endfunction
1 0.000001 function! ale#hover#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'quickinfo'
\&& has_key(s:hover_map, a:response.request_seq)
let l:options = remove(s:hover_map, a:response.request_seq)
if get(a:response, 'success', v:false) is v:true
\&& get(a:response, 'body', v:null) isnot v:null
let l:set_balloons = ale#Var(l:options.buffer, 'set_balloons')
" If we pass the show_documentation flag, we should show the full
" documentation, and always in the preview window.
if get(l:options, 'show_documentation', 0)
let l:documentation = get(a:response.body, 'documentation', '')
" displayString is not included here, because it can be very
" noisy and run on for many lines for complex types. A less
" verbose alternative may be nice in future.
if !empty(l:documentation)
call ale#preview#Show(split(l:documentation, "\n"), {
\ 'filetype': 'ale-preview.message',
\ 'stay_here': 1,
\})
endif
elseif get(l:options, 'hover_from_balloonexpr', 0)
\&& exists('*balloon_show')
\&& (l:set_balloons is 1 || l:set_balloons is# 'hover')
call balloon_show(a:response.body.displayString)
elseif get(l:options, 'truncated_echo', 0)
if !empty(a:response.body.displayString)
call ale#cursor#TruncatedEcho(split(a:response.body.displayString, "\n")[0])
endif
elseif g:ale_hover_to_floating_preview || g:ale_floating_preview
call ale#floating_preview#Show(split(a:response.body.displayString, "\n"), {
\ 'filetype': 'ale-preview.message',
\})
elseif g:ale_hover_to_preview
call ale#preview#Show(split(a:response.body.displayString, "\n"), {
\ 'filetype': 'ale-preview.message',
\ 'stay_here': 1,
\})
else
call ale#util#ShowMessage(a:response.body.displayString)
endif
endif
endif
endfunction
" Convert a language name to another one.
" The language name could be an empty string or v:null
1 0.000002 function! s:ConvertLanguageName(language) abort
return a:language
endfunction
1 0.000001 function! ale#hover#ParseLSPResult(contents) abort
let l:includes = {}
let l:highlights = []
let l:lines = []
let l:list = type(a:contents) is v:t_list ? a:contents : [a:contents]
let l:region_index = 0
for l:item in l:list
if !empty(l:lines)
call add(l:lines, '')
endif
if type(l:item) is v:t_dict && has_key(l:item, 'kind')
if l:item.kind is# 'markdown'
" Handle markdown values as we handle strings below.
let l:item = get(l:item, 'value', '')
elseif l:item.kind is# 'plaintext'
" We shouldn't try to parse plaintext as markdown.
" Pass the lines on and skip parsing them.
call extend(l:lines, split(get(l:item, 'value', ''), "\n"))
continue
endif
endif
let l:marked_list = []
" If the item is a string, then we should parse it as Markdown text.
if type(l:item) is v:t_string
let l:fence_language = v:null
let l:fence_lines = []
for l:line in split(l:item, "\n")
if l:fence_language is v:null
" Look for the start of a code fence. (```python, etc.)
let l:match = matchlist(l:line, '^```\(.*\)$')
if !empty(l:match)
let l:fence_language = l:match[1]
if !empty(l:marked_list)
call add(l:fence_lines, '')
endif
else
if !empty(l:marked_list)
\&& l:marked_list[-1][0] isnot v:null
call add(l:marked_list, [v:null, ['']])
endif
call add(l:marked_list, [v:null, [l:line]])
endif
elseif l:line =~# '^```$'
" When we hit the end of a code fence, pass the fenced
" lines on to the next steps below.
call add(l:marked_list, [l:fence_language, l:fence_lines])
let l:fence_language = v:null
let l:fence_lines = []
else
" Gather lines inside of a code fence.
call add(l:fence_lines, l:line)
endif
endfor
" If the result from the LSP server is a {language: ..., value: ...}
" Dictionary, then that should be interpreted as if it was:
"
" ```${language}
" ${value}
" ```
elseif type(l:item) is v:t_dict
\&& has_key(l:item, 'language')
\&& type(l:item.language) is v:t_string
\&& has_key(l:item, 'value')
\&& type(l:item.value) is v:t_string
call add(
\ l:marked_list,
\ [l:item.language, split(l:item.value, "\n")],
\)
endif
for [l:language, l:marked_lines] in l:marked_list
if l:language is v:null
" NOTE: We could handle other Markdown formatting here.
call map(
\ l:marked_lines,
\ 'substitute(v:val, ''\\_'', ''_'', ''g'')',
\)
else
let l:language = s:ConvertLanguageName(l:language)
if !empty(l:language)
let l:includes[l:language] = printf(
\ 'syntax/%s.vim',
\ l:language,
\)
let l:start = len(l:lines) + 1
let l:end = l:start + len(l:marked_lines)
let l:region_index += 1
call add(l:highlights, 'syntax region'
\ . ' ALE_hover_' . l:region_index
\ . ' start=/\%' . l:start . 'l/'
\ . ' end=/\%' . l:end . 'l/'
\ . ' contains=@ALE_hover_' . l:language
\)
endif
endif
call extend(l:lines, l:marked_lines)
endfor
endfor
let l:include_commands = []
for [l:language, l:lang_path] in sort(items(l:includes))
call add(l:include_commands, 'unlet! b:current_syntax')
call add(
\ l:include_commands,
\ printf('syntax include @ALE_hover_%s %s', l:language, l:lang_path),
\)
endfor
return [l:include_commands + l:highlights, l:lines]
endfunction
1 0.000001 function! ale#hover#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:hover_map, a:response.id)
let l:options = remove(s:hover_map, a:response.id)
" If the call did __not__ come from balloonexpr...
if !get(l:options, 'hover_from_balloonexpr', 0)
let l:buffer = bufnr('')
let [l:line, l:column] = getpos('.')[1:2]
let l:end = len(getline(l:line))
if l:buffer isnot l:options.buffer
\|| l:line isnot l:options.line
\|| min([l:column, l:end]) isnot min([l:options.column, l:end])
" ... Cancel display the message if the cursor has moved.
return
endif
endif
" The result can be a Dictionary item, a List of the same, or null.
let l:result = get(a:response, 'result', v:null)
if l:result is v:null
return
endif
let [l:commands, l:lines] = ale#hover#ParseLSPResult(l:result.contents)
if !empty(l:lines)
let l:set_balloons = ale#Var(l:options.buffer, 'set_balloons')
if get(l:options, 'hover_from_balloonexpr', 0)
\&& exists('*balloon_show')
\&& (l:set_balloons is 1 || l:set_balloons is# 'hover')
call balloon_show(join(l:lines, "\n"))
elseif get(l:options, 'truncated_echo', 0)
call ale#cursor#TruncatedEcho(l:lines[0])
elseif g:ale_hover_to_floating_preview || g:ale_floating_preview
call ale#floating_preview#Show(l:lines, {
\ 'filetype': 'ale-preview.message',
\ 'commands': l:commands,
\})
elseif g:ale_hover_to_preview
call ale#preview#Show(l:lines, {
\ 'filetype': 'ale-preview.message',
\ 'stay_here': 1,
\ 'commands': l:commands,
\})
else
call ale#util#ShowMessage(join(l:lines, "\n"), {
\ 'commands': l:commands,
\})
endif
endif
endif
endfunction
1 0.000002 function! s:OnReady(line, column, opt, linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
if !ale#lsp#HasCapability(l:id, 'hover')
return
endif
let l:buffer = a:lsp_details.buffer
let l:Callback = a:linter.lsp is# 'tsserver'
\ ? function('ale#hover#HandleTSServerResponse')
\ : function('ale#hover#HandleLSPResponse')
call ale#lsp#RegisterCallback(l:id, l:Callback)
if a:linter.lsp is# 'tsserver'
let l:column = a:column
let l:message = ale#lsp#tsserver_message#Quickinfo(
\ l:buffer,
\ a:line,
\ l:column
\)
else
" Send a message saying the buffer has changed first, or the
" hover position probably won't make sense.
call ale#lsp#NotifyForChanges(l:id, l:buffer)
let l:column = max([
\ min([a:column, len(getbufline(l:buffer, a:line)[0])]),
\ 1,
\])
let l:message = ale#lsp#message#Hover(l:buffer, a:line, l:column)
endif
let l:request_id = ale#lsp#Send(l:id, l:message)
let s:hover_map[l:request_id] = {
\ 'buffer': l:buffer,
\ 'line': a:line,
\ 'column': l:column,
\ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0),
\ 'show_documentation': get(a:opt, 'show_documentation', 0),
\ 'truncated_echo': get(a:opt, 'truncated_echo', 0),
\}
endfunction
" Obtain Hover information for the specified position
" Pass optional arguments in the dictionary opt.
" Currently, only one key/value is useful:
" - called_from_balloonexpr, this flag marks if we want the result from this
" ale#hover#Show to display in a balloon if possible
"
" Currently, the callbacks displays the info from hover :
" - in the balloon if opt.called_from_balloonexpr and balloon_show is detected
" - as status message otherwise
1 0.000002 function! ale#hover#Show(buffer, line, col, opt) abort
let l:show_documentation = get(a:opt, 'show_documentation', 0)
let l:Callback = function('s:OnReady', [a:line, a:col, a:opt])
for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype'))
" Only tsserver supports documentation requests at the moment.
if !empty(l:linter.lsp)
\&& (!l:show_documentation || l:linter.lsp is# 'tsserver')
call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
endif
endfor
endfunction
1 0.000002 let s:last_pos = [0, 0, 0]
" This function implements the :ALEHover command.
1 0.000001 function! ale#hover#ShowAtCursor() abort
let l:buffer = bufnr('')
let l:pos = getpos('.')
call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {})
endfunction
1 0.000001 function! ale#hover#ShowTruncatedMessageAtCursor() abort
let l:buffer = bufnr('')
let l:pos = getpos('.')[0:2]
if l:pos != s:last_pos
let s:last_pos = l:pos
let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
if empty(l:loc)
call ale#hover#Show(
\ l:buffer,
\ l:pos[1],
\ l:pos[2],
\ {'truncated_echo': 1},
\)
endif
endif
endfunction
" This function implements the :ALEDocumentation command.
1 0.000001 function! ale#hover#ShowDocumentationAtCursor() abort
let l:buffer = bufnr('')
let l:pos = getpos('.')
let l:options = {'show_documentation': 1}
call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], l:options)
endfunction
SCRIPT /Users/kyle/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/handlers/go.vim
Sourced 1 time
Total time: 0.000237
Self time: 0.000237
count total (s) self (s)
" Author: neersighted <bjorn@neersighted.com>
" Description: go vet for Go files
"
" Author: John Eikenberry <jae@zhar.net>
" Description: updated to work with go1.10
"
" Author: Ben Paxton <ben@gn32.uk>
" Description: moved to generic Golang file from govet
"
" Author: mostfunkyduck <mostfunkyduck@protonmail.com>
" Description: updated to work with go 1.14
1 0.000005 function! ale#handlers#go#Handler(buffer, lines) abort
let l:pattern = '\v^%(vet: )?([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:? ?(.+)$'
let l:output = []
let l:dir = expand('#' . a:buffer . ':p:h')
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4],
\ 'type': 'E',
\})
endfor
return l:output
endfunction
FUNCTION go#lsp#DidOpen()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:701
Called 2 times
Total time: 0.046444
Self time: 0.000164
count total (s) self (s)
2 0.000006 if get(b:, 'go_lsp_did_open', 0)
1 0.000000 return
1 0.000000 endif
1 0.000006 let l:fname = fnamemodify(a:fname, ':p')
1 0.000004 if !isdirectory(fnamemodify(l:fname, ':h'))
return
1 0.000000 endif
1 0.003106 0.000005 let l:lsp = s:lspfactory.get()
1 0.000002 if !has_key(l:lsp.notificationQueue, l:fname)
1 0.000003 let l:lsp.notificationQueue[l:fname] = []
1 0.000000 endif
1 0.042994 0.000030 call s:ensureWorkspace(fnamemodify(l:fname, ':h'))
1 0.000011 let l:lsp.fileVersions[l:fname] = getbufvar(l:fname, 'changedtick')
1 0.000163 0.000079 let l:msg = go#lsp#message#DidOpen(l:fname, join(go#util#GetLines(), "\n") . "\n", l:lsp.fileVersions[l:fname])
1 0.000112 0.000004 let l:state = s:newHandlerState('')
" TODO(bc): setting a buffer level variable here assumes that a:fname is the
" current buffer. Change to a:fname first before setting it and then change
" back to active buffer.
1 0.000001 let b:go_lsp_did_open = 1
1 0.000024 0.000003 return l:lsp.sendMessage(l:msg, l:state)
FUNCTION go#config#HighlightExtraTypes()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:424
Called 1 time
Total time: 0.000001
Self time: 0.000001
count total (s) self (s)
1 0.000001 return get(g:, 'go_highlight_extra_types', 0)
FUNCTION go#util#ExecInWorkDir()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:246
Called 3 times
Total time: 0.300170
Self time: 0.000167
count total (s) self (s)
3 0.000028 if !isdirectory(a:wd)
return ['', 1]
3 0.000001 endif
3 0.001136 0.000015 let l:dir = go#util#Chdir(a:wd)
3 0.000001 try
3 0.297247 0.000076 let [l:out, l:err] = call('go#util#Exec', [a:cmd] + a:000)
3 0.000001 finally
3 0.001732 0.000021 call go#util#Chdir(l:dir)
3 0.000002 endtry
3 0.000008 return [l:out, l:err]
FUNCTION <SNR>119_Lint()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale.vim:99
Called 1 time
Total time: 0.049268
Self time: 0.001142
count total (s) self (s)
" Use the filetype from the buffer
1 0.000001 let l:filetype = getbufvar(a:buffer, '&filetype')
1 0.023494 0.000006 let l:linters = ale#linter#Get(l:filetype)
1 0.000027 0.000006 let l:linters = ale#linter#RemoveIgnored(a:buffer, l:filetype, l:linters)
" Tell other sources that they can start checking the buffer now.
1 0.000001 let g:ale_want_results_buffer = a:buffer
1 0.000161 0.000152 silent doautocmd <nomodeline> User ALEWantResults
1 0.000002 unlet! g:ale_want_results_buffer
" Don't set up buffer data and so on if there are no linters to run.
1 0.000003 if !has_key(g:ale_buffer_info, a:buffer) && empty(l:linters)
return
1 0.000000 endif
" Clear lint_file linters, or only run them if the file exists.
1 0.000248 let l:lint_file = empty(l:linters) || (a:should_lint_file && filereadable(expand('#' . a:buffer . ':p')))
1 0.025325 0.000717 call ale#engine#RunLinters(a:buffer, l:linters, l:lint_file)
FUNCTION ale#events#LintOnEnter()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/events.vim:42
Called 1 time
Total time: 0.049390
Self time: 0.000022
count total (s) self (s)
" Unmark a file as being changed outside of Vim after we try to check it.
1 0.000002 call setbufvar(a:buffer, 'ale_file_changed', 0)
1 0.000014 0.000007 if ale#Var(a:buffer, 'enabled') && g:ale_lint_on_enter
1 0.049372 0.000010 call ale#Queue(0, 'lint_file', a:buffer)
1 0.000000 endif
FUNCTION <SNR>118_IndentLinesEnable()
Defined: ~/.local/share/nvim/site/pack/packer/start/indentLine/after/plugin/indentLine.vim:148
Called 1 time
Total time: 0.000235
Self time: 0.000212
count total (s) self (s)
1 0.000001 if g:indentLine_newVersion
1 0.000001 if exists("b:indentLine_enabled") && b:indentLine_enabled == 0
return
1 0.000000 endif
1 0.000001 if !exists("w:indentLine_indentLineId")
let w:indentLine_indentLineId = []
1 0.000000 endif
1 0.000026 0.000003 call s:SetConcealOption()
1 0.000001 if g:indentLine_showFirstIndentLevel
call add(w:indentLine_indentLineId, matchadd('Conceal', '^ ', 0, -1, {'conceal': g:indentLine_first_char}))
1 0.000000 endif
1 0.000002 let space = &l:shiftwidth == 0 ? &l:tabstop : &l:shiftwidth
1 0.000001 let n = len(g:indentLine_char_list)
1 0.000001 let level = 0
21 0.000009 for i in range(space+1, space * g:indentLine_indentLevel + 1, space)
20 0.000006 if n > 0
20 0.000016 let char = g:indentLine_char_list[level % n]
20 0.000008 let level += 1
else
let char = g:indentLine_char
20 0.000004 endif
20 0.000132 call add(w:indentLine_indentLineId, matchadd('Conceal', '^\s\+\zs\%'.i.'v ', 0, -1, {'conceal': char}))
21 0.000004 endfor
1 0.000000 return
endif
if exists("b:indentLine_enabled") && b:indentLine_enabled
return
else
let b:indentLine_enabled = 1
endif
call s:SetConcealOption()
let g:mysyntaxfile = g:indentLine_mysyntaxfile
let space = &l:shiftwidth == 0 ? &l:tabstop : &l:shiftwidth
if g:indentLine_showFirstIndentLevel
execute 'syntax match IndentLine /^ / containedin=ALL conceal cchar=' . g:indentLine_first_char
endif
if g:indentLine_faster
execute 'syntax match IndentLineSpace /^\s\+/ containedin=ALL contains=IndentLine'
execute 'syntax match IndentLine / \{'.(space-1).'}\zs / contained conceal cchar=' . g:indentLine_char
execute 'syntax match IndentLine /\t\zs / contained conceal cchar=' . g:indentLine_char
else
let pattern = line('$') < g:indentLine_maxLines ? 'v' : 'c'
for i in range(space+1, space * g:indentLine_indentLevel + 1, space)
execute 'syntax match IndentLine /\%(^\s\+\)\@<=\%'.i.pattern.' / containedin=ALL conceal cchar=' . g:indentLine_char
endfor
endif
FUNCTION <SNR>176_StopCursorTimer()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/cursor.vim:56
Called 2 times
Total time: 0.000028
Self time: 0.000028
count total (s) self (s)
2 0.000005 if s:cursor_timer != -1
1 0.000008 call timer_stop(s:cursor_timer)
1 0.000003 let s:cursor_timer = -1
2 0.000001 endif
FUNCTION ale#lsp#RegisterCallback()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp.vim:524
Called 1 time
Total time: 0.000082
Self time: 0.000082
count total (s) self (s)
1 0.000012 let l:conn = get(s:connections, a:conn_id, {})
1 0.000065 if !empty(l:conn)
" Add the callback to the List if it's not there already.
1 0.000003 call uniq(sort(add(l:conn.callback_list, a:callback)))
1 0.000000 endif
FUNCTION <SNR>180_SetListsImpl()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/list.vim:90
Called 3 times
Total time: 0.021357
Self time: 0.002002
count total (s) self (s)
3 0.001477 let l:title = expand('#' . a:buffer . ':p')
3 0.000004 if g:ale_set_quickfix
let l:quickfix_list = ale#list#GetCombinedList()
if has('nvim')
call setqflist(s:FixList(a:buffer, l:quickfix_list), ' ', l:title)
else
call setqflist(s:FixList(a:buffer, l:quickfix_list))
call setqflist([], 'r', {'title': l:title})
endif
3 0.000003 elseif g:ale_set_loclist
" If windows support is off, win_findbuf() may not exist.
" We'll set result in the current window, which might not be correct,
" but it's better than nothing.
3 0.000073 0.000059 let l:ids = s:WinFindBuf(a:buffer)
3 0.014058 0.000016 let l:loclist = s:Deduplicate(a:loclist)
6 0.000007 for l:id in l:ids
3 0.000008 if has('nvim')
3 0.005267 0.000112 call setloclist(l:id, s:FixList(a:buffer, l:loclist), ' ', l:title)
else
call setloclist(l:id, s:FixList(a:buffer, l:loclist))
call setloclist(l:id, [], 'r', {'title': l:title})
3 0.000001 endif
6 0.000002 endfor
3 0.000001 endif
" Save the current view before opening/closing any window
3 0.000117 call setbufvar(a:buffer, 'ale_winview', winsaveview())
" Open a window to show the problems if we need to.
"
" We'll check if the current buffer's List is not empty here, so the
" window will only be opened if the current buffer has problems.
3 0.000051 0.000014 if s:ShouldOpen(a:buffer) && !empty(a:loclist)
let l:winnr = winnr()
let l:mode = mode()
" open windows vertically instead of default horizontally
let l:open_type = ''
if ale#Var(a:buffer, 'list_vertical') == 1
let l:open_type = 'vert rightbelow '
endif
if g:ale_set_quickfix
if !ale#list#IsQuickfixOpen()
silent! execute l:open_type . 'copen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
endif
elseif g:ale_set_loclist
silent! execute l:open_type . 'lopen ' . str2nr(ale#Var(a:buffer, 'list_window_size'))
endif
" If focus changed, restore it (jump to the last window).
if l:winnr isnot# winnr()
wincmd p
endif
" Return to original mode when applicable
if mode() != l:mode
if l:mode is? 'v' || l:mode is# "\<c-v>"
" Reset our last visual selection
normal! gv
elseif l:mode is? 's' || l:mode is# "\<c-s>"
" Reset our last character selection
normal! "\<c-g>"
endif
endif
call s:RestoreViewIfNeeded(a:buffer)
3 0.000001 endif
" If ALE isn't currently checking for more problems, close the window if
" needed now. This check happens inside of this timer function, so
" the window can be closed reliably.
3 0.000030 0.000011 if !ale#engine#IsCheckingBuffer(a:buffer)
1 0.000094 0.000006 call s:CloseWindowIfNeeded(a:buffer)
3 0.000001 endif
FUNCTION <SNR>144_debug()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:1327
Called 40 times
Total time: 0.000417
Self time: 0.000417
count total (s) self (s)
40 0.000082 let l:shouldStart = len(s:log) == 0
40 0.000088 let s:log = add(s:log, [a:event, a:data])
40 0.000025 if l:shouldStart
18 0.000135 call timer_start(10, function('s:debugasync', []))
40 0.000016 endif
FUNCTION <SNR>165_GetLintFileSlots()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:591
Called 1 time
Total time: 0.000045
Self time: 0.000045
count total (s) self (s)
1 0.000001 let l:linter_slots = []
5 0.000004 for l:linter in a:linters
4 0.000004 let l:LintFile = l:linter.lint_file
4 0.000004 if type(l:LintFile) is v:t_func
let l:LintFile = l:LintFile(a:buffer)
4 0.000001 endif
4 0.000006 call add(l:linter_slots, [l:LintFile, l:linter])
5 0.000016 endfor
1 0.000001 return l:linter_slots
FUNCTION go#config#AutoSameids()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:246
Called 2 times
Total time: 0.000003
Self time: 0.000003
count total (s) self (s)
2 0.000002 return get(g:, 'go_auto_sameids', 0)
FUNCTION ale#linter#Get()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/linter.vim:367
Called 1 time
Total time: 0.023488
Self time: 0.000154
count total (s) self (s)
1 0.000001 let l:possibly_duplicated_linters = []
" Handle dot-separated filetypes.
2 0.000005 for l:original_filetype in split(a:original_filetypes, '\.')
1 0.000032 0.000007 let l:filetype = ale#linter#ResolveFiletype(l:original_filetype)
1 0.000019 0.000006 let l:linter_names = s:GetLinterNames(l:original_filetype)
1 0.023300 0.000005 let l:all_linters = ale#linter#GetAll(l:filetype)
1 0.000001 let l:filetype_linters = []
1 0.000002 if type(l:linter_names) is v:t_string && l:linter_names is# 'all'
let l:filetype_linters = l:all_linters
1 0.000001 elseif type(l:linter_names) is v:t_list
" Select only the linters we or the user has specified.
15 0.000005 for l:linter in l:all_linters
14 0.000017 let l:name_list = [l:linter.name] + l:linter.aliases
25 0.000010 for l:name in l:name_list
15 0.000012 if index(l:linter_names, l:name) >= 0
4 0.000003 call add(l:filetype_linters, l:linter)
4 0.000002 break
11 0.000002 endif
25 0.000005 endfor
15 0.000003 endfor
1 0.000001 endif
1 0.000001 call extend(l:possibly_duplicated_linters, l:filetype_linters)
2 0.000001 endfor
1 0.000001 let l:name_list = []
1 0.000001 let l:combined_linters = []
" Make sure we override linters so we don't get two with the same name,
" like 'eslint' for both 'javascript' and 'typescript'
"
" Note that the reverse calls here modify the List variables.
5 0.000003 for l:linter in reverse(l:possibly_duplicated_linters)
4 0.000003 if index(l:name_list, l:linter.name) < 0
4 0.000004 call add(l:name_list, l:linter.name)
4 0.000003 call add(l:combined_linters, l:linter)
4 0.000001 endif
5 0.000001 endfor
1 0.000001 return reverse(l:combined_linters)
FUNCTION <SNR>179_UpdateLineNumbers()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:282
Called 3 times
Total time: 0.000304
Self time: 0.000304
count total (s) self (s)
3 0.000004 let l:line_map = {}
3 0.000003 let l:line_numbers_changed = 0
23 0.000015 for [l:line, l:sign_id, l:name] in a:current_sign_list
20 0.000017 let l:line_map[l:sign_id] = l:line
23 0.000005 endfor
59 0.000017 for l:item in a:loclist
56 0.000025 if l:item.bufnr == a:buffer
56 0.000082 let l:lnum = get(l:line_map, get(l:item, 'sign_id', 0), 0)
56 0.000030 if l:lnum && l:item.lnum != l:lnum
let l:item.lnum = l:lnum
let l:line_numbers_changed = 1
56 0.000010 endif
56 0.000009 endif
59 0.000011 endfor
" When the line numbers change, sort the list again
3 0.000002 if l:line_numbers_changed
call sort(a:loclist, 'ale#util#LocItemCompare')
3 0.000001 endif
FUNCTION <SNR>179_EscapeSignText()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:73
Called 5 times
Total time: 0.000020
Self time: 0.000020
count total (s) self (s)
5 0.000019 return substitute(substitute(a:sign_text, ' *$', '', ''), '\\\| ', '\\\0', 'g')
FUNCTION ale#lsp#CloseDocument()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp.vim:619
Called 1 time
Total time: 0.000030
Self time: 0.000030
count total (s) self (s)
1 0.000002 let l:closed = 0
" The connection keys are sorted so the messages are easier to test, and
" so messages are sent in a consistent order.
2 0.000005 for l:conn_id in sort(keys(s:connections))
1 0.000002 let l:conn = s:connections[l:conn_id]
1 0.000002 if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
if l:conn.is_tsserver
let l:message = ale#lsp#tsserver_message#Close(a:buffer)
else
let l:message = ale#lsp#message#DidClose(a:buffer)
endif
call ale#lsp#Send(l:conn_id, l:message)
call remove(l:conn.open_documents, a:buffer)
let l:closed = 1
1 0.000000 endif
2 0.000001 endfor
1 0.000001 return l:closed
FUNCTION ale#hover#ShowTruncatedMessageAtCursor()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/hover.vim:334
Called 1 time
Total time: 0.000089
Self time: 0.000025
count total (s) self (s)
1 0.000004 let l:buffer = bufnr('')
1 0.000004 let l:pos = getpos('.')[0:2]
1 0.000002 if l:pos != s:last_pos
1 0.000001 let s:last_pos = l:pos
1 0.000073 0.000008 let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
1 0.000002 if empty(l:loc)
call ale#hover#Show( l:buffer, l:pos[1], l:pos[2], {'truncated_echo': 1},)
1 0.000000 endif
1 0.000000 endif
FUNCTION go#config#HighlightVariableAssignments()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:477
Called 1 time
Total time: 0.000001
Self time: 0.000001
count total (s) self (s)
1 0.000001 return get(g:, 'go_highlight_variable_assignments', 0)
FUNCTION go#config#HighlightBuildConstraints()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:461
Called 2 times
Total time: 0.000002
Self time: 0.000002
count total (s) self (s)
2 0.000002 return get(g:, 'go_highlight_build_constraints', 0)
FUNCTION <SNR>118_IndentLinesDisable()
Defined: ~/.local/share/nvim/site/pack/packer/start/indentLine/after/plugin/indentLine.vim:209
Called 1 time
Total time: 0.000020
Self time: 0.000015
count total (s) self (s)
1 0.000001 if g:indentLine_newVersion
1 0.000004 if exists("w:indentLine_indentLineId") && ! empty(w:indentLine_indentLineId)
for id in w:indentLine_indentLineId
try
call matchdelete(id)
catch /^Vim\%((\a\+)\)\=:E80[23]/
endtry
endfor
let w:indentLine_indentLineId = []
1 0.000000 endif
1 0.000009 0.000003 call s:ResetConcealOption()
1 0.000000 return
endif
let b:indentLine_enabled = 0
try
syntax clear IndentLine
syntax clear IndentLineSpace
catch /^Vim\%((\a\+)\)\=:E28/ " catch error E28
endtry
FUNCTION go#config#GoplsAnalyses()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:560
Called 2 times
Total time: 0.000016
Self time: 0.000016
count total (s) self (s)
2 0.000012 return get(g:, 'go_gopls_analyses', v:null)
FUNCTION <SNR>179_BuildSignMap()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:307
Called 3 times
Total time: 0.003615
Self time: 0.002214
count total (s) self (s)
3 0.000036 0.000013 let l:max_signs = ale#Var(a:buffer, 'max_signs')
3 0.000002 if l:max_signs is 0
let l:selected_grouped_items = []
3 0.000006 elseif type(l:max_signs) is v:t_number && l:max_signs > 0
let l:selected_grouped_items = a:grouped_items[:l:max_signs - 1]
3 0.000001 else
3 0.000003 let l:selected_grouped_items = a:grouped_items
3 0.000001 endif
3 0.000002 let l:sign_map = {}
3 0.000003 let l:sign_offset = g:ale_sign_offset
23 0.000014 for [l:line, l:sign_id, l:name] in a:current_sign_list
20 0.000048 let l:sign_info = get(l:sign_map, l:line, { 'current_id_list': [], 'current_name_list': [], 'new_id': 0, 'new_name': '', 'items': [],})
" Increment the sign offset for new signs, by the maximum sign ID.
20 0.000010 if l:sign_id > l:sign_offset
20 0.000010 let l:sign_offset = l:sign_id
20 0.000003 endif
" Remember the sign names and IDs in separate Lists, so they are easy
" to work with.
20 0.000016 call add(l:sign_info.current_id_list, l:sign_id)
20 0.000015 call add(l:sign_info.current_name_list, l:name)
20 0.000016 let l:sign_map[l:line] = l:sign_info
23 0.000005 endfor
43 0.000020 for l:group in l:selected_grouped_items
40 0.000033 let l:line = l:group[0].lnum
40 0.001315 let l:sign_info = get(l:sign_map, l:line, { 'current_id_list': [], 'current_name_list': [], 'new_id': 0, 'new_name': '', 'items': [],})
40 0.001621 0.000242 let l:sign_info.new_name = ale#sign#GetSignName(l:group)
40 0.000031 let l:sign_info.items = l:group
40 0.000081 let l:index = index( l:sign_info.current_name_list, l:sign_info.new_name)
40 0.000021 if l:index >= 0
" We have a sign with this name already, so use the same ID.
20 0.000024 let l:sign_info.new_id = l:sign_info.current_id_list[l:index]
20 0.000004 else
" This sign name replaces the previous name, so use a new ID.
20 0.000029 let l:sign_info.new_id = l:sign_offset + 1
20 0.000014 let l:sign_offset += 1
40 0.000009 endif
40 0.000047 let l:sign_map[l:line] = l:sign_info
43 0.000012 endfor
3 0.000001 return l:sign_map
FUNCTION <SNR>142_hi()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/syntax/go.vim:395
Called 1 time
Total time: 0.000098
Self time: 0.000097
count total (s) self (s)
1 0.000006 hi def link goSameId Search
1 0.000006 hi def link goDiagnosticError SpellBad
1 0.000006 hi def link goDiagnosticWarning SpellRare
" TODO(bc): is it appropriate to define text properties in a syntax file?
" The highlight groups need to be defined before the text properties types
" are added, and when users have syntax enabled in their vimrc after
" filetype plugin on, the highlight groups won't be defined when
" ftplugin/go.vim is executed when the first go file is opened.
" See https://github.com/fatih/vim-go/issues/2658.
1 0.000002 if has('textprop')
if empty(prop_type_get('goSameId'))
call prop_type_add('goSameId', {'highlight': 'goSameId'})
endif
if empty(prop_type_get('goDiagnosticError'))
call prop_type_add('goDiagnosticError', {'highlight': 'goDiagnosticError'})
endif
if empty(prop_type_get('goDiagnosticWarning'))
call prop_type_add('goDiagnosticWarning', {'highlight': 'goDiagnosticWarning'})
endif
1 0.000000 endif
1 0.000006 hi def link goDeclsFzfKeyword Keyword
1 0.000006 hi def link goDeclsFzfFunction Function
1 0.000006 hi def link goDeclsFzfSpecialComment SpecialComment
1 0.000006 hi def link goDeclsFzfComment Comment
" :GoCoverage commands
1 0.000015 hi def goCoverageCovered ctermfg=green guifg=#A6E22E
1 0.000005 hi def goCoverageUncover ctermfg=red guifg=#F92672
" :GoDebug commands
1 0.000004 0.000003 if go#config#HighlightDebug()
1 0.000010 hi def GoDebugBreakpoint term=standout ctermbg=117 ctermfg=0 guibg=#BAD4F5 guifg=Black
1 0.000010 hi def GoDebugCurrent term=reverse ctermbg=12 ctermfg=7 guibg=DarkBlue guifg=White
1 0.000000 endif
FUNCTION go#util#has_job()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:64
Called 2 times
Total time: 0.000010
Self time: 0.000010
count total (s) self (s)
2 0.000010 return has('job') || has('nvim')
FUNCTION <SNR>144_dedup()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:1876
Called 1 time
Total time: 0.000017
Self time: 0.000017
count total (s) self (s)
1 0.000009 let l:dict = {}
2 0.000002 for l:item in a:list
1 0.000001 let l:dict[l:item] = 1
2 0.000001 endfor
1 0.000002 return sort(keys(l:dict))
FUNCTION 9()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:9
Called 5 times
Total time: 0.003132
Self time: 0.000051
count total (s) self (s)
5 0.000023 if empty(get(self, 'current', {})) || empty(get(self.current, 'job', {}))
1 0.003096 0.000015 let self.current = s:newlsp()
5 0.000001 endif
5 0.000003 return self.current
FUNCTION <SNR>165_GetLintFileValues()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:607
Called 1 time
Total time: 0.023860
Self time: 0.000876
count total (s) self (s)
1 0.000001 let l:deferred_list = []
1 0.000001 let l:new_slots = []
5 0.000004 for [l:lint_file, l:linter] in a:slots
4 0.001128 0.000798 while ale#command#IsDeferred(l:lint_file) && has_key(l:lint_file, 'value')
" If we've already computed the return value, use it.
let l:lint_file = l:lint_file.value
4 0.000002 endwhile
4 0.000030 0.000021 if ale#command#IsDeferred(l:lint_file)
" If we are going to return the result later, wait for it.
call add(l:deferred_list, l:lint_file)
4 0.000001 else
" If we have the value now, coerce it to 0 or 1.
4 0.000003 let l:lint_file = l:lint_file is 1
4 0.000001 endif
4 0.000006 call add(l:new_slots, [l:lint_file, l:linter])
5 0.000003 endfor
1 0.000001 if !empty(l:deferred_list)
for l:deferred in l:deferred_list
let l:deferred.result_callback = {-> s:GetLintFileValues(l:new_slots, a:Callback)}
endfor
1 0.000000 else
1 0.022655 0.000009 call a:Callback(l:new_slots)
1 0.000000 endif
FUNCTION ale#lsp#UpdateConfig()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp.vim:291
Called 1 time
Total time: 0.000005
Self time: 0.000005
count total (s) self (s)
1 0.000002 let l:conn = get(s:connections, a:conn_id, {})
1 0.000002 if empty(l:conn) || a:config ==# l:conn.config " no-custom-checks
1 0.000000 return 0
endif
let l:conn.config = a:config
let l:message = ale#lsp#message#DidChangeConfiguration(a:buffer, a:config)
call ale#lsp#Send(a:conn_id, l:message)
return 1
FUNCTION <SNR>145_neooptions()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/job.vim:361
Called 1 time
Total time: 0.000137
Self time: 0.000137
count total (s) self (s)
1 0.000001 let l:options = {}
1 0.000001 let l:options['stdout_buf'] = ''
1 0.000001 let l:options['stderr_buf'] = ''
1 0.000002 let l:err_mode = get(a:options, 'err_mode', get(a:options, 'mode', ''))
1 0.000001 let l:out_mode = get(a:options, 'out_mode', get(a:options, 'mode', ''))
10 0.000005 for key in keys(a:options)
9 0.000004 if key == 'cwd'
1 0.000001 let l:options['cwd'] = a:options['cwd']
1 0.000001 continue
8 0.000001 endif
8 0.000003 if key == 'callback'
let l:options['callback'] = a:options['callback']
if !has_key(a:options, 'out_cb')
let l:options['on_stdout'] = function('s:callback2on_stdout', [l:out_mode], l:options)
endif
if !has_key(a:options, 'err_cb')
let l:options['on_stderr'] = function('s:callback2on_stderr', [l:err_mode], l:options)
endif
continue
8 0.000001 endif
8 0.000003 if key == 'out_cb'
1 0.000001 let l:options['out_cb'] = a:options['out_cb']
1 0.000003 let l:options['on_stdout'] = function('s:on_stdout', [l:out_mode], l:options)
1 0.000000 continue
7 0.000001 endif
7 0.000003 if key == 'err_cb'
1 0.000001 let l:options['err_cb'] = a:options['err_cb']
1 0.000002 let l:options['on_stderr'] = function('s:on_stderr', [l:err_mode], l:options)
1 0.000000 continue
6 0.000001 endif
6 0.000002 if key == 'exit_cb'
1 0.000001 let l:options['exit_cb'] = a:options['exit_cb']
1 0.000003 let l:options['on_exit'] = function('s:on_exit', [], l:options)
1 0.000000 continue
5 0.000001 endif
5 0.000002 if key == 'close_cb'
1 0.000000 continue
4 0.000001 endif
4 0.000002 if key == 'stoponexit'
if a:options['stoponexit'] == ''
let l:options['detach'] = 1
endif
continue
4 0.000001 endif
5 0.000002 endfor
1 0.000001 return l:options
FUNCTION ale#highlight#RemoveHighlights()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/highlight.vim:72
Called 3 times
Total time: 0.000177
Self time: 0.000155
count total (s) self (s)
3 0.000003 if s:has_nvim_highlight
3 0.000159 0.000137 call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
else
for l:match in getmatches()
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
call matchdelete(l:match.id)
endif
endfor
3 0.000001 endif
FUNCTION ale#command#CdString()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim:173
Called 1 time
Total time: 0.000018
Self time: 0.000018
count total (s) self (s)
1 0.000009 let l:match = matchstrpos(a:directory, s:path_format_regex)
" Do not escape the directory here if it's a valid format string.
" This allows us to use sequences like %s:h, %s:h:h, etc.
1 0.000004 let l:directory = l:match[1:] == [0, len(a:directory)] ? a:directory : ale#Escape(a:directory)
1 0.000002 if has('win32')
return 'cd /d ' . l:directory . ' && '
1 0.000000 endif
1 0.000001 return 'cd ' . l:directory . ' && '
FUNCTION <SNR>144_start()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:582
Called 4 times
Total time: 0.000018
Self time: 0.000018
count total (s) self (s)
4 0.000009 let self.started_at = reltime()
4 0.000004 if self.statustype == ''
4 0.000002 return
endif
let status = { 'desc': 'current status', 'type': self.statustype, 'state': "started", }
call go#statusline#Update(self.jobdir, status)
FUNCTION ale#handlers#unix#HandleAsWarning()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/handlers/unix.vim:24
Called 1 time
Total time: 0.001613
Self time: 0.000016
count total (s) self (s)
1 0.001606 0.000009 return s:HandleUnixFormat(a:buffer, a:lines, 'W')
FUNCTION ale#sign#FindCurrentSigns()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:250
Called 3 times
Total time: 0.000430
Self time: 0.000220
count total (s) self (s)
3 0.000004 if exists('*sign_getplaced')
3 0.000424 0.000215 return ale#sign#ParseSignsWithGetPlaced(a:buffer)
else
let l:line_list = ale#sign#ReadSigns(a:buffer)
return ale#sign#ParseSigns(l:line_list)
endif
FUNCTION ale#command#ManageDirectory()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim:50
Called 2 times
Total time: 0.000023
Self time: 0.000014
count total (s) self (s)
2 0.000016 0.000007 call ale#command#InitData(a:buffer)
2 0.000006 call add(s:buffer_data[a:buffer].directory_list, a:directory)
FUNCTION ale#lsp#message#Initialize()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp/message.vim:31
Called 1 time
Total time: 0.001084
Self time: 0.000015
count total (s) self (s)
" NOTE: rootPath is deprecated in favour of rootUri
1 0.001081 0.000013 return [0, 'initialize', { 'processId': getpid(), 'rootPath': a:root_path, 'capabilities': a:capabilities, 'initializationOptions': a:options, 'rootUri': ale#path#ToURI(a:root_path),}]
FUNCTION ale#highlight#nvim_buf_add_highlight()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/highlight.vim:36
Called 56 times
Total time: 0.000873
Self time: 0.000873
count total (s) self (s)
" Ignore all errors for adding highlights.
56 0.000028 try
56 0.000725 call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
catch
56 0.000025 endtry
FUNCTION go#config#HighlightTypes()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:457
Called 1 time
Total time: 0.000001
Self time: 0.000001
count total (s) self (s)
1 0.000001 return get(g:, 'go_highlight_types', 0)
FUNCTION go#config#Debug()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:199
Called 24 times
Total time: 0.000076
Self time: 0.000076
count total (s) self (s)
24 0.000061 return get(g:, 'go_debug', [])
FUNCTION go#lsp#DidChange()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:732
Called 1 time
Total time: 0.003400
Self time: 0.001953
count total (s) self (s)
" DidChange is called even when fname isn't open in a buffer (e.g. via
" go#lsp#Info); don't report the file as open or as having changed when it's
" not actually a buffer.
1 0.001669 if bufnr(a:fname) == -1
return
1 0.000001 endif
1 0.000032 let l:fname = fnamemodify(a:fname, ':p')
1 0.000011 if !isdirectory(fnamemodify(l:fname, ':h'))
return
1 0.000000 endif
1 0.000020 0.000012 call go#lsp#DidOpen(a:fname)
1 0.000014 0.000004 let l:lsp = s:lspfactory.get()
1 0.000009 let l:version = getbufvar(l:fname, 'changedtick')
1 0.000003 if has_key(l:lsp.fileVersions, l:fname) && l:lsp.fileVersions[l:fname] == l:version
return
1 0.000000 endif
1 0.000002 let l:lsp.fileVersions[l:fname] = l:version
1 0.000192 0.000092 let l:msg = go#lsp#message#DidChange(l:fname, join(go#util#GetLines(), "\n") . "\n", l:lsp.fileVersions[l:fname])
1 0.000112 0.000056 let l:state = s:newHandlerState('')
1 0.001323 0.000051 return l:lsp.sendMessage(l:msg, l:state)
FUNCTION ale#sign#GetSignName()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:118
Called 40 times
Total time: 0.001379
Self time: 0.000992
count total (s) self (s)
40 0.000044 let l:priority = g:ale#util#style_warning_priority
" Determine the highest priority item for the line.
96 0.000063 for l:item in a:sublist
56 0.000840 0.000453 let l:item_priority = ale#util#GetItemPriority(l:item)
56 0.000039 if l:item_priority > l:priority
40 0.000027 let l:priority = l:item_priority
56 0.000037 endif
96 0.000034 endfor
40 0.000031 if l:priority is# g:ale#util#error_priority
return 'ALEErrorSign'
40 0.000008 endif
40 0.000033 if l:priority is# g:ale#util#warning_priority
40 0.000019 return 'ALEWarningSign'
endif
if l:priority is# g:ale#util#style_error_priority
return 'ALEStyleErrorSign'
endif
if l:priority is# g:ale#util#style_warning_priority
return 'ALEStyleWarningSign'
endif
if l:priority is# g:ale#util#info_priority
return 'ALEInfoSign'
endif
" Use the error sign for invalid severities.
return 'ALEErrorSign'
FUNCTION go#config#AutoTypeInfo()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:345
Called 2 times
Total time: 0.000004
Self time: 0.000004
count total (s) self (s)
2 0.000003 return get(g:, "go_auto_type_info", 0)
FUNCTION ale#GetFilenameMappings()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale.vim:269
Called 7 times
Total time: 0.000180
Self time: 0.000120
count total (s) self (s)
7 0.000107 0.000047 let l:linter_mappings = ale#Var(a:buffer, 'filename_mappings')
7 0.000011 if type(l:linter_mappings) is v:t_list
return l:linter_mappings
7 0.000003 endif
7 0.000005 let l:name = a:name
7 0.000010 if !has_key(l:linter_mappings, l:name)
" Use * as a default setting for all tools.
7 0.000005 let l:name = '*'
7 0.000002 endif
7 0.000009 return get(l:linter_mappings, l:name, [])
FUNCTION <SNR>98_register()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/plugin/go.vim:243
Called 1 time
Total time: 0.048086
Self time: 0.000727
count total (s) self (s)
1 0.000002 if !(&modifiable && expand('<amatch>') ==# 'go')
return
1 0.000000 endif
1 0.048083 0.000724 call go#lsp#DidOpen(expand('<afile>:p'))
FUNCTION ale_linters#go#gopls#GetCommand()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gopls.vim:10
Called 1 time
Total time: 0.000025
Self time: 0.000007
count total (s) self (s)
1 0.000025 0.000007 return ale#go#EnvString(a:buffer) . '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
FUNCTION go#config#SearchBinPathFirst()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:412
Called 4 times
Total time: 0.000012
Self time: 0.000012
count total (s) self (s)
4 0.000010 return get(g:, 'go_search_bin_path_first', 1)
FUNCTION ale#lsp#HandleMessage()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp.vim:332
Called 18 times
Total time: 0.008885
Self time: 0.001689
count total (s) self (s)
18 0.000082 let l:conn = get(s:connections, a:conn_id, {})
18 0.000021 if empty(l:conn)
return
18 0.000006 endif
18 0.000025 if type(a:message) isnot v:t_string
" Ignore messages that aren't strings.
return
18 0.000004 endif
18 0.000036 let l:conn.data .= a:message
" Parse the objects now if we can, and keep the remaining text.
18 0.002081 0.000596 let [l:conn.data, l:response_list] = ale#lsp#ReadMessageData(l:conn.data)
" Look for initialize responses first.
18 0.000015 if !l:conn.initialized
2 0.000002 for l:response in l:response_list
1 0.001597 0.000014 call ale#lsp#HandleInitResponse(l:conn, l:response)
2 0.000001 endfor
18 0.000005 endif
" If the connection is marked as initialized, call the callbacks with the
" responses.
18 0.000010 if l:conn.initialized
45 0.000030 for l:response in l:response_list
" Call all of the registered handlers with the response.
54 0.000051 for l:Callback in l:conn.callback_list
27 0.004633 0.000507 call ale#util#GetFunction(l:Callback)(a:conn_id, l:response)
54 0.000020 endfor
45 0.000017 endfor
18 0.000005 endif
FUNCTION ale#highlight#UpdateHighlights()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/highlight.vim:136
Called 3 times
Total time: 0.007154
Self time: 0.001617
count total (s) self (s)
3 0.000010 let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled ? get(b:, 'ale_highlight_items', []) : []
3 0.000209 0.000032 call ale#highlight#RemoveHighlights()
59 0.000034 for l:item in l:item_list
56 0.000051 if l:item.type is# 'W'
56 0.000077 if get(l:item, 'sub_type', '') is# 'style'
let l:group = 'ALEStyleWarning'
56 0.000014 else
56 0.000037 let l:group = 'ALEWarning'
56 0.000013 endif
elseif l:item.type is# 'I'
let l:group = 'ALEInfo'
elseif get(l:item, 'sub_type', '') is# 'style'
let l:group = 'ALEStyleError'
else
let l:group = 'ALEError'
56 0.000016 endif
56 0.000308 let l:range = { 'lnum': l:item.lnum, 'col': l:item.col, 'end_lnum': get(l:item, 'end_lnum', l:item.lnum), 'end_col': get(l:item, 'end_col', l:item.col)}
56 0.005994 0.000634 call s:highlight_range(l:item.bufnr, l:range, l:group)
59 0.000020 endfor
" If highlights are enabled and signs are not enabled, we should still
" offer line highlights by adding a separate set of highlights.
3 0.000003 if !g:ale_set_signs
let l:available_groups = { 'ALEWarningLine': hlexists('ALEWarningLine'), 'ALEInfoLine': hlexists('ALEInfoLine'), 'ALEErrorLine': hlexists('ALEErrorLine'),}
for l:item in l:item_list
if l:item.type is# 'W'
let l:group = 'ALEWarningLine'
elseif l:item.type is# 'I'
let l:group = 'ALEInfoLine'
else
let l:group = 'ALEErrorLine'
endif
if l:available_groups[l:group]
call s:highlight_line(l:item.bufnr, l:item.lnum, l:group)
endif
endfor
3 0.000001 endif
FUNCTION ale#job#Start()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/job.vim:215
Called 4 times
Total time: 0.007283
Self time: 0.007268
count total (s) self (s)
4 0.000054 0.000039 call ale#job#ValidateArguments(a:command, a:options)
4 0.000009 let l:job_info = copy(a:options)
4 0.000003 let l:job_options = {}
4 0.000007 if has('nvim')
4 0.000004 if has_key(a:options, 'out_cb')
2 0.000006 let l:job_options.on_stdout = function('s:NeoVimCallback')
2 0.000002 let l:job_info.out_cb_line = ''
4 0.000001 endif
4 0.000003 if has_key(a:options, 'err_cb')
3 0.000006 let l:job_options.on_stderr = function('s:NeoVimCallback')
3 0.000002 let l:job_info.err_cb_line = ''
4 0.000001 endif
4 0.000003 if has_key(a:options, 'exit_cb')
3 0.000004 let l:job_options.on_exit = function('s:NeoVimCallback')
4 0.000001 endif
4 0.007012 let l:job_info.job = jobstart(a:command, l:job_options)
4 0.000009 let l:job_id = l:job_info.job
else
let l:job_options = { 'in_mode': l:job_info.mode, 'out_mode': l:job_info.mode, 'err_mode': l:job_info.mode,}
if has_key(a:options, 'out_cb')
let l:job_options.out_cb = function('s:VimOutputCallback')
endif
if has_key(a:options, 'err_cb')
let l:job_options.err_cb = function('s:VimErrorCallback')
endif
if has_key(a:options, 'exit_cb')
" Set a close callback to which simply calls job_status()
" when the channel is closed, which can trigger the exit callback
" earlier on.
let l:job_options.close_cb = function('s:VimCloseCallback')
let l:job_options.exit_cb = function('s:VimExitCallback')
endif
" Use non-blocking writes for Vim versions that support the option.
if has('patch-8.1.350')
let l:job_options.noblock = 1
endif
" Vim 8 will read the stdin from the file's buffer.
let l:job_info.job = job_start(a:command, l:job_options)
let l:job_id = ale#job#ParseVim8ProcessID(string(l:job_info.job))
4 0.000001 endif
4 0.000003 if l:job_id > 0
" Store the job in the map for later only if we can get the ID.
4 0.000014 let s:job_map[l:job_id] = l:job_info
4 0.000001 endif
4 0.000031 return l:job_id
FUNCTION <SNR>165_RunLinters()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:638
Called 1 time
Total time: 0.022630
Self time: 0.000285
count total (s) self (s)
1 0.000041 0.000006 call s:StopCurrentJobs(a:buffer, a:should_lint_file, a:slots)
1 0.000018 0.000005 call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
" We can only clear the results if we aren't checking the buffer.
1 0.000009 0.000004 let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer)
1 0.000097 0.000091 silent doautocmd <nomodeline> User ALELintPre
5 0.000008 for [l:lint_file, l:linter] in a:slots
" Only run lint_file linters if we should.
4 0.000004 if !l:lint_file || a:should_lint_file
4 0.022042 0.000049 if s:RunLinter(a:buffer, l:linter, l:lint_file)
" If a single linter ran, we shouldn't clear everything.
4 0.000012 let l:can_clear_results = 0
4 0.000005 endif
else
" If we skipped running a lint_file linter still in the list,
" we shouldn't clear everything.
let l:can_clear_results = 0
4 0.000001 endif
5 0.000029 endfor
" Clear the results if we can. This needs to be done when linters are
" disabled, or ALE itself is disabled.
1 0.000001 if l:can_clear_results
call ale#engine#SetResults(a:buffer, [])
1 0.000001 elseif a:new_buffer
1 0.000315 0.000022 call s:AddProblemsFromOtherBuffers( a:buffer, map(copy(a:slots), 'v:val[1]'))
1 0.000000 endif
FUNCTION go#uri#Decode()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/uri.vim:26
Called 2 times
Total time: 0.000007
Self time: 0.000007
count total (s) self (s)
2 0.000006 return substitute( a:value, '%\(\x\x\)', '\=s:decodehex(submatch(1))', 'g')
FUNCTION ale#command#SetCwd()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim:34
Called 4 times
Total time: 0.000037
Self time: 0.000019
count total (s) self (s)
4 0.000030 0.000011 call ale#command#InitData(a:buffer)
4 0.000007 let s:buffer_data[a:buffer].cwd = a:cwd
FUNCTION go#config#HighlightFormatStrings()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:469
Called 1 time
Total time: 0.000001
Self time: 0.000001
count total (s) self (s)
1 0.000001 return get(g:, 'go_highlight_format_strings', 1)
FUNCTION ale#lsp_linter#StartLSP()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_linter.vim:409
Called 1 time
Total time: 0.007813
Self time: 0.000038
count total (s) self (s)
1 0.000001 let l:command = ''
1 0.000000 let l:address = ''
1 0.001793 0.000005 let l:root = ale#lsp_linter#FindProjectRoot(a:buffer, a:linter)
1 0.000001 if empty(l:root) && a:linter.lsp isnot# 'tsserver'
" If there's no project root, then we can't check files with LSP,
" unless we are using tsserver, which doesn't use project roots.
return 0
1 0.000000 endif
1 0.000003 let l:options = { 'buffer': a:buffer, 'linter': a:linter, 'callback': a:Callback, 'root': l:root,}
1 0.000001 if a:linter.lsp is# 'socket'
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
return s:StartWithAddress(l:options, l:address)
1 0.000000 endif
1 0.000084 0.000005 let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
1 0.005923 0.000015 return s:StartIfExecutable(l:options, l:executable)
FUNCTION ale#lsp#message#Initialized()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp/message.vim:42
Called 1 time
Total time: 0.000001
Self time: 0.000001
count total (s) self (s)
1 0.000001 return [1, 'initialized', {}]
FUNCTION ale#linter#GetLanguage()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/linter.vim:452
Called 1 time
Total time: 0.000004
Self time: 0.000004
count total (s) self (s)
1 0.000001 let l:Language = a:linter.language
1 0.000002 return type(l:Language) is v:t_func ? l:Language(a:buffer) : l:Language
FUNCTION go#util#IsUsingCygwinShell()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:56
Called 4 times
Total time: 0.000023
Self time: 0.000017
count total (s) self (s)
4 0.000021 0.000015 return go#util#IsWin() && executable('cygpath') && &shell =~ '.*sh.*'
FUNCTION <SNR>170_StartLSP()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_linter.vim:301
Called 1 time
Total time: 0.005732
Self time: 0.000877
count total (s) self (s)
1 0.000001 let l:buffer = a:options.buffer
1 0.000001 let l:linter = a:options.linter
1 0.000001 let l:root = a:options.root
1 0.000001 let l:Callback = a:options.callback
1 0.000021 0.000004 let l:init_options = ale#lsp_linter#GetOptions(l:buffer, l:linter)
1 0.000001 if l:linter.lsp is# 'socket'
let l:conn_id = ale#lsp#Register(a:address, l:root, l:init_options)
let l:ready = ale#lsp#ConnectToAddress(l:conn_id, a:address)
let l:command = ''
1 0.000000 else
1 0.001337 0.000802 let l:conn_id = ale#lsp#Register(a:executable, l:root, l:init_options)
" tsserver behaves differently, so tell the LSP API that it is tsserver.
1 0.000001 if l:linter.lsp is# 'tsserver'
call ale#lsp#MarkConnectionAsTsserver(l:conn_id)
1 0.000000 endif
1 0.000008 0.000004 let l:cwd = ale#linter#GetCwd(l:buffer, l:linter)
1 0.000107 0.000029 let l:command = ale#command#FormatCommand( l:buffer, a:executable, a:command, 0, v:false, l:cwd, ale#GetFilenameMappings(l:buffer, l:linter.name),)[1]
1 0.000027 0.000004 let l:command = ale#job#PrepareCommand(l:buffer, l:command)
1 0.004200 0.000009 let l:ready = ale#lsp#StartProgram(l:conn_id, a:executable, l:command)
1 0.000000 endif
1 0.000000 if !l:ready
if g:ale_history_enabled && !empty(a:command)
call ale#history#Add(l:buffer, 'failed', l:conn_id, a:command)
endif
return 0
1 0.000000 endif
1 0.000003 let l:details = { 'buffer': l:buffer, 'connection_id': l:conn_id, 'command': l:command, 'project_root': l:root,}
1 0.000012 0.000005 call ale#lsp#OnInit(l:conn_id, {-> ale#lsp_linter#OnInit(l:linter, l:details, l:Callback)})
1 0.000000 return 1
FUNCTION go#util#HasDebug()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:501
Called 24 times
Total time: 0.000238
Self time: 0.000161
count total (s) self (s)
24 0.000226 0.000150 return index(go#config#Debug(), a:flag) >= 0
FUNCTION <SNR>82_sortByLength()
Defined: ~/.local/share/nvim/site/pack/packer/start/auto-pairs/plugin/auto-pairs.vim:467
Called 24 times
Total time: 0.000049
Self time: 0.000049
count total (s) self (s)
24 0.000042 return len(a:i2[0])-len(a:i1[0])
FUNCTION go#util#Shelljoin()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:294
Called 4 times
Total time: 0.000103
Self time: 0.000103
count total (s) self (s)
4 0.000004 try
4 0.000007 let ssl_save = &shellslash
4 0.000004 set noshellslash
4 0.000002 if a:0
return join(map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')'), ' ')
4 0.000001 endif
4 0.000059 return join(map(copy(a:arglist), 'shellescape(v:val)'), ' ')
4 0.000003 finally
4 0.000005 let &shellslash = ssl_save
4 0.000003 endtry
FUNCTION ale#events#ReadOrEnterEvent()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/events.vim:51
Called 2 times
Total time: 0.000046
Self time: 0.000046
count total (s) self (s)
" Apply pattern options if the variable is set.
2 0.000009 if get(g:, 'ale_pattern_options_enabled', 1)&& !empty(get(g:, 'ale_pattern_options'))
call ale#pattern_options#SetOptions(a:buffer)
2 0.000001 endif
" When entering a buffer, we are no longer quitting it.
2 0.000010 call setbufvar(a:buffer, 'ale_quitting', 0)
2 0.000006 let l:filetype = getbufvar(a:buffer, '&filetype')
2 0.000005 call setbufvar(a:buffer, 'ale_original_filetype', l:filetype)
" If the file changed outside of Vim, check it on BufEnter,BufRead
2 0.000002 if getbufvar(a:buffer, 'ale_file_changed')
call ale#events#LintOnEnter(a:buffer)
2 0.000000 endif
FUNCTION go#config#FoldEnable()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:501
Called 14 times
Total time: 0.000064
Self time: 0.000042
count total (s) self (s)
14 0.000005 if a:0 > 0
7 0.000008 return index(go#config#FoldEnable(), a:1) > -1
7 0.000001 endif
7 0.000010 return get(g:, 'go_fold_enable', ['block', 'import', 'varconst', 'package_comment'])
FUNCTION ale#path#ToURI()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/path.vim:221
Called 2 times
Total time: 0.001098
Self time: 0.000833
count total (s) self (s)
2 0.000005 let l:has_drive_letter = a:path[1:2] is# ':\'
2 0.001090 0.000824 return substitute( ((l:has_drive_letter || a:path[:0] is# '/') ? 'file://' : '') . (l:has_drive_letter ? '/' . a:path[:2] : '') . ale#uri#Encode(l:has_drive_letter ? a:path[3:] : a:path), '\\', '/', 'g',)
FUNCTION go#config#GoplsLocal()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:564
Called 2 times
Total time: 0.000003
Self time: 0.000003
count total (s) self (s)
2 0.000003 return get(g:, 'go_gopls_local', v:null)
FUNCTION <SNR>180_Deduplicate()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/list.vim:47
Called 3 times
Total time: 0.014042
Self time: 0.003381
count total (s) self (s)
3 0.000002 let l:list = a:list
3 0.009497 0.001798 call sort(l:list, function('ale#util#LocItemCompareWithText'))
3 0.004521 0.001559 call uniq(l:list, function('ale#util#LocItemCompareWithText'))
3 0.000002 return l:list
FUNCTION <SNR>125_ApplyPartialTimer()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/util.vim:446
Called 3 times
Total time: 0.021437
Self time: 0.000081
count total (s) self (s)
3 0.000016 if has_key(s:partial_timers, a:timer_id)
3 0.000018 let [l:Callback, l:args] = remove(s:partial_timers, a:timer_id)
3 0.021398 0.000041 call call(l:Callback, [a:timer_id] + l:args)
3 0.000001 endif
FUNCTION loupe#private#very_magic_slash()
Defined: ~/.local/share/nvim/site/pack/packer/start/loupe/autoload/loupe/private.vim:26
Called 1 time
Total time: 0.000464
Self time: 0.000244
count total (s) self (s)
1 0.000035 if getcmdtype() != ':'
return a:slash
1 0.000005 endif
" For simplicity, only consider a slash typed at the end of the command-line.
1 0.000018 let l:pos=getcmdpos()
1 0.000008 let l:cmd=getcmdline()
1 0.000009 if len(l:cmd) + 1 != l:pos
return a:slash
1 0.000001 endif
" Skip over ranges
1 0.000006 while 1
1 0.000265 0.000045 let l:stripped=s:strip_ranges(l:cmd)
1 0.000004 if l:stripped ==# l:cmd
1 0.000004 break
else
let l:cmd=l:stripped
endif
1 0.000003 endwhile
" We special case `:g!` (and `gl!`, `glo!`, `glob!`, `globa!`, `global!`).
" All of those commands are equivalent to `:v` (ie. `!` is not being used as a
" slash). Using `!` with `:v` (etc) is an error (`:h E477`). Using it with `:s`
" is ok (it _is_ treated as a delimiter there). Fun fact: `:g!!foo!d` is a
" legitmate command.
1 0.000019 if index(['g', 'gl', 'glo', 'glob', 'globa', 'global'], l:cmd != 1) && a:slash == '!'
return a:slash
1 0.000032 elseif index([ 'g', 'gl', 'glo', 'glob', 'globa', 'global', 'g!', 'gl!', 'glo!', 'glob!', 'globa!', 'global!', 's', 'su', 'sub', 'subs', 'subst', 'substi', 'substit', 'substitu', 'substitut', 'substitute', 'v', 'vg', 'vgl', 'vglo', 'vglob', 'vgloba', 'vglobal', ], l:cmd) != -1
return loupe#private#prepare_highlight(a:slash . '\v')
1 0.000001 endif
1 0.000002 return a:slash
FUNCTION go#config#HighlightSpaceTabError()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:428
Called 1 time
Total time: 0.000001
Self time: 0.000001
count total (s) self (s)
1 0.000001 return get(g:, 'go_highlight_space_tab_error', 0)
FUNCTION go#config#GoplsUsePlaceholders()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:552
Called 3 times
Total time: 0.000007
Self time: 0.000007
count total (s) self (s)
3 0.000006 return get(g:, 'go_gopls_use_placeholders', v:null)
FUNCTION <SNR>118_Setup()
Defined: ~/.local/share/nvim/site/pack/packer/start/indentLine/after/plugin/indentLine.vim:317
Called 1 time
Total time: 0.000277
Self time: 0.000018
count total (s) self (s)
1 0.000002 if &filetype ==# ""
call s:InitColor()
1 0.000000 endif
1 0.000019 0.000004 if s:Filter() && g:indentLine_enabled || exists("b:indentLine_enabled") && b:indentLine_enabled
1 0.000240 0.000005 call s:IndentLinesEnable()
1 0.000000 endif
1 0.000013 0.000004 if s:Filter() && g:indentLine_leadingSpaceEnabled || exists("b:indentLine_leadingSpaceEnabled") && b:indentLine_leadingSpaceEnabled
call s:LeadingSpaceEnable()
1 0.000000 endif
FUNCTION 11()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:82
Called 90 times
Total time: 0.005373
Self time: 0.005006
count total (s) self (s)
90 0.000086 let l:responses = []
90 0.000079 let l:rest = a:data
122 0.000069 while 1
" Look for the end of the HTTP headers
122 0.000448 let l:body_start_idx = matchend(l:rest, "\r\n\r\n")
122 0.000094 if l:body_start_idx < 0
" incomplete header
56 0.000029 break
66 0.000018 endif
" Parse the Content-Length header.
66 0.000113 let l:header = l:rest[:l:body_start_idx - 4]
66 0.000747 let l:length_match = matchlist( l:header, '\vContent-Length: *(\d+)')
66 0.000081 if empty(l:length_match)
" TODO(bc): shutdown gopls?
throw "invalid JSON-RPC header:\n" . l:header
66 0.000019 endif
" get the start of the rest
66 0.000156 let l:next_start_idx = l:body_start_idx + str2nr(l:length_match[1])
66 0.000142 if len(l:rest) < l:next_start_idx
" incomplete response body
34 0.000011 break
32 0.000009 endif
32 0.000601 0.000235 call s:debug('received', l:rest[:l:next_start_idx - 1])
32 0.000064 let l:body = l:rest[l:body_start_idx : l:next_start_idx - 1]
32 0.000051 let l:rest = l:rest[l:next_start_idx :]
32 0.000012 try
" add the json body to the list.
32 0.000273 call add(l:responses, json_decode(l:body))
catch
" TODO(bc): log the message and/or show an error message.
32 0.000016 finally
" intentionally left blank.
32 0.000015 endtry
122 0.000141 endwhile
90 0.000113 return [l:rest, l:responses]
FUNCTION go#config#GoplsOptions()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:595
Called 1 time
Total time: 0.000002
Self time: 0.000002
count total (s) self (s)
1 0.000001 return get(g:, 'go_gopls_options', ['-remote=auto'])
FUNCTION 13()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:151
Called 3 times
Total time: 0.001839
Self time: 0.000097
count total (s) self (s)
3 0.000003 if a:req.method == 'workspace/workspaceFolders'
let l:resp = go#lsp#message#WorkspaceFoldersResult(self.workspaceDirectories)
3 0.000007 elseif a:req.method == 'workspace/configuration' && has_key(a:req, 'params') && has_key(a:req.params, 'items')
2 0.001609 0.000014 let l:resp = go#lsp#message#ConfigurationResult(a:req.params.items)
1 0.000002 elseif a:req.method == 'client/registerCapability' && has_key(a:req, 'params') && has_key(a:req.params, 'registrations')
1 0.000001 let l:resp = v:null
elseif a:req.method == 'workspace/applyEdit'
try
let l:ok = v:true
for l:change in a:req.params.edit.documentChanges
call s:applyDocumentChanges(a:req.params.edit.documentChanges)
endfor
catch
call go#util#EchoError(printf('could not apply edit: %s', v:exception))
let l:ok = v:false
endtry
let l:resp = go#lsp#message#ApplyWorkspaceEditResponse(l:ok)
else
return
3 0.000001 endif
3 0.000003 if get(self, 'exited', 0)
return
3 0.000000 endif
3 0.000020 0.000011 let l:msg = self.newResponse(a:req.id, l:resp)
3 0.000149 0.000011 call self.write(l:msg)
FUNCTION 14()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:181
Called 1 time
Total time: 0.005171
Self time: 0.000035
count total (s) self (s)
1 0.000002 if has_key(a:resp, 'id') && has_key(self.handlers, a:resp.id)
1 0.000000 try
1 0.000001 let l:handler = self.handlers[a:resp.id]
1 0.000002 let l:winid = win_getid(winnr())
" Always set the active window to the window that was active when
" the request was sent. Among other things, this makes sure that
" the correct window's location list will be populated when the
" list type is 'location' and the user has moved windows since
" sending the request.
1 0.000002 call win_gotoid(l:handler.winid)
1 0.000001 if has_key(a:resp, 'error')
call l:handler.requestComplete(0)
if has_key(l:handler, 'error')
call call(l:handler.error, [a:resp.error.message])
else
call go#util#EchoError(a:resp.error.message)
endif
call win_gotoid(l:winid)
return
1 0.000000 endif
1 0.000005 0.000003 call l:handler.requestComplete(1)
1 0.000001 let l:winidBeforeHandler = l:handler.winid
1 0.005143 0.000008 call call(l:handler.handleResult, [a:resp.result])
" change the window back to the window that was active when
" starting to handle the message _only_ if the handler didn't
" update the winid, so that handlers can set the winid if needed
" (e.g. :GoDef).
1 0.000001 if l:handler.winid == l:winidBeforeHandler
1 0.000001 call win_gotoid(l:winid)
1 0.000000 endif
1 0.000001 finally
1 0.000002 call remove(self.handlers, a:resp.id)
1 0.000000 endtry
1 0.000000 endif
FUNCTION 15()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:222
Called 28 times
Total time: 0.000283
Self time: 0.000204
count total (s) self (s)
" TODO(bc): handle more notifications (e.g. window/showMessage).
28 0.000057 if a:req.method == 'textDocument/publishDiagnostics'
call self.handleDiagnostics(a:req.params)
28 0.000034 elseif a:req.method == 'window/showMessage'
3 0.000088 0.000008 call self.showMessage(a:req.params)
28 0.000010 endif
FUNCTION 17()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:236
Called 3 times
Total time: 0.000080
Self time: 0.000021
count total (s) self (s)
3 0.000003 let l:msg = a:data.message
3 0.000002 if a:data.type == 1
call go#util#EchoError(l:msg)
3 0.000002 elseif a:data.type == 2
call go#util#EchoWarning(l:msg)
3 0.000001 elseif a:data.type == 3
1 0.000062 0.000004 call go#util#EchoInfo(l:msg)
2 0.000001 elseif a:data.type == 4
" do nothing for Log messages
3 0.000001 endif
FUNCTION 19()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:318
Called 1 time
Total time: 0.005134
Self time: 0.000048
count total (s) self (s)
1 0.000008 0.000006 if go#config#EchoCommandInfo()
1 0.004783 0.000004 call go#util#EchoProgress("initialized gopls")
1 0.000002 endif
1 0.000003 let status = { 'desc': '', 'type': 'gopls', 'state': 'initialized', }
1 0.000073 0.000007 call go#statusline#Update(self.wd, status)
1 0.000001 let self.ready = 1
1 0.000018 0.000007 let l:msg = self.newMessage(go#lsp#message#Initialized())
1 0.000028 0.000002 call self.write(l:msg)
" send messages queued while waiting for ready.
3 0.000002 for l:item in self.queue
2 0.000209 0.000005 call self.sendMessage(l:item.data, l:item.handler)
3 0.000001 endfor
" reset the queue
1 0.000003 let self.queue = []
FUNCTION <SNR>144_newHandlerState()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:527
Called 4 times
Total time: 0.000398
Self time: 0.000398
count total (s) self (s)
4 0.000363 let l:state = { 'winid': win_getid(winnr()), 'statustype': a:statustype, 'jobdir': getcwd(), 'handleResult': funcref('s:noop'), }
" explicitly bind requestComplete to state so that within it, self will
" always refer to state. See :help Partial for more information.
4 0.000014 let l:state.requestComplete = funcref('s:requestComplete', [], l:state)
" explicitly bind start to state so that within it, self will
" always refer to state. See :help Partial for more information.
4 0.000008 let l:state.start = funcref('s:start', [], l:state)
4 0.000003 return l:state
FUNCTION ale#history#RememberOutput()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/history.vim:58
Called 3 times
Total time: 0.000363
Self time: 0.000026
count total (s) self (s)
3 0.000356 0.000019 let l:obj = s:FindHistoryItem(a:buffer, a:job_id)
3 0.000005 let l:obj.output = a:output
FUNCTION <SNR>165_AddProblemsFromOtherBuffers()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:493
Called 1 time
Total time: 0.000294
Self time: 0.000294
count total (s) self (s)
1 0.000258 let l:filename = expand('#' . a:buffer . ':p')
1 0.000001 let l:loclist = []
1 0.000001 let l:name_map = {}
" Build a map of the active linters.
5 0.000003 for l:linter in a:linters
4 0.000004 let l:name_map[l:linter.name] = 1
5 0.000001 endfor
" Find the items from other buffers, for the linters that are enabled.
2 0.000005 for l:info in values(g:ale_buffer_info)
1 0.000001 for l:item in l:info.loclist
if has_key(l:item, 'filename')&& l:item.filename is# l:filename&& has_key(l:name_map, l:item.linter_name)
" Copy the items and set the buffer numbers to this one.
let l:new_item = copy(l:item)
let l:new_item.bufnr = a:buffer
call add(l:loclist, l:new_item)
endif
1 0.000000 endfor
2 0.000000 endfor
1 0.000001 if !empty(l:loclist)
call sort(l:loclist, function('ale#util#LocItemCompareWithText'))
call uniq(l:loclist, function('ale#util#LocItemCompareWithText'))
" Set the loclist variable, used by some parts of ALE.
let g:ale_buffer_info[a:buffer].loclist = l:loclist
call ale#engine#SetResults(a:buffer, l:loclist)
1 0.000000 endif
FUNCTION ale#Var()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale.vim:180
Called 46 times
Total time: 0.000347
Self time: 0.000347
count total (s) self (s)
46 0.000070 let l:full_name = 'ale_' . a:variable_name
46 0.000140 let l:vars = getbufvar(str2nr(a:buffer), '', {})
46 0.000109 return get(l:vars, l:full_name, g:[l:full_name])
FUNCTION <SNR>100_system()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:181
Called 4 times
Total time: 0.294607
Self time: 0.000421
count total (s) self (s)
" Preserve original shell, shellredir and shellcmdflag values
4 0.000004 let l:shell = &shell
4 0.000004 let l:shellredir = &shellredir
4 0.000004 let l:shellcmdflag = &shellcmdflag
4 0.000129 0.000118 if !go#util#IsWin() && executable('/bin/sh')
4 0.000029 set shell=/bin/sh shellredir=>%s\ 2>&1 shellcmdflag=-c
4 0.000001 endif
4 0.000019 0.000013 if go#util#IsWin()
if executable($COMSPEC)
let &shell = $COMSPEC
set shellcmdflag=/C
endif
4 0.000001 endif
4 0.000001 try
4 0.294314 0.000146 return call('system', [a:cmd] + a:000)
4 0.000013 finally
" Restore original values
4 0.000033 let &shell = l:shell
4 0.000007 let &shellredir = l:shellredir
4 0.000006 let &shellcmdflag = l:shellcmdflag
4 0.000005 endtry
FUNCTION ale#ShouldDoNothing()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale.vim:32
Called 6 times
Total time: 0.000507
Self time: 0.000397
count total (s) self (s)
" The checks are split into separate if statements to make it possible to
" profile each check individually with Vim's profiling tools.
"
" Do nothing if ALE is disabled.
6 0.000034 if !getbufvar(a:buffer, 'ale_enabled', get(g:, 'ale_enabled', 0))
return 1
6 0.000001 endif
" Don't perform any checks when newer NeoVim versions are exiting.
6 0.000013 if get(v:, 'exiting', v:null) isnot v:null
return 1
6 0.000001 endif
6 0.000015 let l:filetype = getbufvar(a:buffer, '&filetype')
" Do nothing when there's no filetype.
6 0.000005 if l:filetype is# ''
return 1
6 0.000001 endif
" Do nothing for diff buffers.
6 0.000009 if getbufvar(a:buffer, '&diff')
return 1
6 0.000001 endif
" Do nothing for blacklisted files.
6 0.000025 if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0
return 1
6 0.000001 endif
" Do nothing if running from command mode.
6 0.000012 if s:getcmdwintype_exists && !empty(getcmdwintype())
return 1
6 0.000001 endif
6 0.000017 let l:filename = fnamemodify(bufname(a:buffer), ':t')
" Do nothing for directories.
6 0.000004 if l:filename is# '.'
return 1
6 0.000001 endif
" Don't start linting and so on when an operator is pending.
6 0.000059 0.000042 if ale#util#Mode(1) is# 'no'
return 1
6 0.000001 endif
" Do nothing if running in the sandbox.
6 0.000079 0.000019 if ale#util#InSandbox()
return 1
6 0.000001 endif
" Do nothing if the file is too large.
6 0.000052 0.000019 if ale#FileTooLarge(a:buffer)
return 1
6 0.000001 endif
" Do nothing from CtrlP buffers with CtrlP-funky.
6 0.000048 if exists(':CtrlPFunky') is 2&& getbufvar(a:buffer, '&l:statusline') =~# 'CtrlPMode.*funky'
return 1
6 0.000002 endif
6 0.000003 return 0
FUNCTION go#util#gobin()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:95
Called 1 time
Total time: 0.021516
Self time: 0.000029
count total (s) self (s)
1 0.021516 0.000029 return substitute(s:exec(['go', 'env', 'GOBIN'])[0], '\n', '', 'g')
FUNCTION <SNR>165_RemoveProblemsForDisabledLinters()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:477
Called 1 time
Total time: 0.000013
Self time: 0.000013
count total (s) self (s)
" Figure out which linters are still enabled, and remove
" problems for linters which are no longer enabled.
" Problems from other sources will be kept.
1 0.000001 let l:name_map = {}
5 0.000002 for l:linter in a:linters
4 0.000004 let l:name_map[l:linter.name] = 1
5 0.000001 endfor
1 0.000004 call filter( get(g:ale_buffer_info[a:buffer], 'loclist', []), 'get(v:val, ''from_other_source'') || get(l:name_map, get(v:val, ''linter_name''))',)
FUNCTION go#config#CodeCompletionEnabled()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:512
Called 1 time
Total time: 0.000009
Self time: 0.000009
count total (s) self (s)
1 0.000007 return get(g:, "go_code_completion_enabled", 1)
FUNCTION <SNR>180_FixList()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/list.vim:66
Called 3 times
Total time: 0.005155
Self time: 0.001886
count total (s) self (s)
3 0.000043 0.000013 let l:format = ale#Var(a:buffer, 'loclist_msg_format')
3 0.000003 let l:new_list = []
87 0.000045 for l:item in a:list
84 0.000292 let l:fixed_item = copy(l:item)
84 0.004388 0.001150 let l:fixed_item.text = ale#GetLocItemMessage(l:item, l:format)
84 0.000055 if l:item.bufnr == -1
" If the buffer number is invalid, remove it.
call remove(l:fixed_item, 'bufnr')
84 0.000023 endif
84 0.000103 call add(l:new_list, l:fixed_item)
87 0.000029 endfor
3 0.000001 return l:new_list
FUNCTION ale#path#FindExecutable()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/path.vim:102
Called 1 time
Total time: 0.000047
Self time: 0.000011
count total (s) self (s)
1 0.000009 0.000003 if ale#Var(a:buffer, a:base_var_name . '_use_global')
return ale#Var(a:buffer, a:base_var_name . '_executable')
1 0.000000 endif
1 0.000036 0.000005 let l:nearest = ale#path#FindNearestExecutable(a:buffer, a:path_list)
1 0.000001 if !empty(l:nearest)
1 0.000000 return l:nearest
endif
return ale#Var(a:buffer, a:base_var_name . '_executable')
FUNCTION go#util#Chdir()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:721
Called 8 times
Total time: 0.003630
Self time: 0.003630
count total (s) self (s)
8 0.000016 if !exists('*chdir')
8 0.001080 let l:olddir = getcwd()
8 0.000033 let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
8 0.002475 execute printf('%s %s', cd, fnameescape(a:dir))
8 0.000013 return l:olddir
endif
return chdir(a:dir)
FUNCTION go#util#PathListSep()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:14
Called 8 times
Total time: 0.000047
Self time: 0.000032
count total (s) self (s)
8 0.000036 0.000020 if go#util#IsWin()
return ";"
8 0.000002 endif
8 0.000003 return ":"
FUNCTION 20()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:342
Called 5 times
Total time: 0.030273
Self time: 0.001999
count total (s) self (s)
5 0.000005 if !self.last_request_id
1 0.011365 0.000029 let l:wd = go#util#ModuleRoot()
1 0.000001 if l:wd == -1
call go#util#EchoError('could not determine appropriate working directory for gopls')
return -1
1 0.000000 endif
1 0.000000 if l:wd == ''
let l:wd = getcwd()
1 0.000000 endif
1 0.000003 let self.wd = l:wd
1 0.000008 0.000006 if go#config#EchoCommandInfo()
1 0.015827 0.000004 call go#util#EchoProgress("initializing gopls")
1 0.000000 endif
1 0.000002 let l:status = { 'desc': '', 'type': 'gopls', 'state': 'initializing', }
1 0.001232 0.000732 call go#statusline#Update(l:wd, l:status)
1 0.000004 let self.workspaceDirectories = add(self.workspaceDirectories, l:wd)
1 0.000129 0.000007 let l:msg = self.newMessage(go#lsp#message#Initialize(l:wd))
1 0.000132 0.000004 let l:state = s:newHandlerState('')
1 0.000003 let l:state.handleResult = funcref('self.handleInitializeResult', [], l:self)
1 0.000002 let self.handlers[l:msg.id] = l:state
1 0.000007 0.000004 call l:state.start()
1 0.000048 0.000002 call self.write(l:msg)
5 0.000001 endif
5 0.000002 if !self.ready
2 0.000006 call add(self.queue, {'data': a:data, 'handler': a:handler})
2 0.000001 return
3 0.000001 endif
3 0.000028 0.000007 let l:msg = self.newMessage(a:data)
3 0.000002 if has_key(l:msg, 'id')
let self.handlers[l:msg.id] = a:handler
3 0.000000 endif
3 0.001093 0.001079 call a:handler.start()
3 0.000287 0.000008 call self.write(l:msg)
FUNCTION 21()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:394
Called 5 times
Total time: 0.000040
Self time: 0.000040
count total (s) self (s)
5 0.000009 let l:msg = { 'method': a:data.method, 'jsonrpc': '2.0', }
5 0.000002 if !a:data.notification
1 0.000001 let self.last_request_id += 1
1 0.000001 let l:msg.id = self.last_request_id
5 0.000001 endif
5 0.000008 if has_key(a:data, 'params')
5 0.000004 let l:msg.params = a:data.params
5 0.000001 endif
5 0.000002 return l:msg
FUNCTION 22()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:412
Called 3 times
Total time: 0.000009
Self time: 0.000009
count total (s) self (s)
3 0.000007 let l:msg = { 'jsonrpc': '2.0', 'id': a:id, 'result': a:result, }
3 0.000001 return l:msg
FUNCTION 23()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:422
Called 8 times
Total time: 0.000488
Self time: 0.000437
count total (s) self (s)
8 0.000017 if empty(get(self, 'job', {}))
return
8 0.000002 endif
8 0.000224 let l:body = json_encode(a:msg)
8 0.000024 let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
8 0.000095 0.000044 call s:debug('sent', l:data)
8 0.000010 if has('nvim')
8 0.000093 call chansend(self.job, l:data)
8 0.000009 return
endif
try
call ch_sendraw(self.job, l:data)
catch
call go#util#EchoError(printf('could not send message: %s', v:exception))
endtry
FUNCTION go#util#ExecInDir()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:239
Called 3 times
Total time: 0.304865
Self time: 0.004695
count total (s) self (s)
3 0.004642 let l:wd = expand('%:p:h')
3 0.300222 0.000052 return call('go#util#ExecInWorkDir', [a:cmd, l:wd] + a:000)
FUNCTION <SNR>126_IsCallback()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/linter.vim:75
Called 22 times
Total time: 0.000046
Self time: 0.000046
count total (s) self (s)
22 0.000041 return type(a:value) is v:t_string || type(a:value) is v:t_func
FUNCTION ale#path#FindNearestFile()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/path.vim:37
Called 1 time
Total time: 0.000680
Self time: 0.000680
count total (s) self (s)
1 0.000283 let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p')
1 0.000006 let l:buffer_filename = fnameescape(l:buffer_filename)
1 0.000299 let l:relative_path = findfile(a:filename, l:buffer_filename . ';')
1 0.000002 if !empty(l:relative_path)
1 0.000089 return fnamemodify(l:relative_path, ':p')
endif
return ''
FUNCTION <SNR>57_LoadIndent()
Defined: /opt/homebrew/Cellar/neovim/0.5.1_1/share/nvim/runtime/indent.vim:13
Called 1 time
Total time: 0.003015
Self time: 0.002609
count total (s) self (s)
1 0.000002 if exists("b:undo_indent")
exe b:undo_indent
unlet! b:undo_indent b:did_indent
1 0.000000 endif
1 0.000002 let s = expand("<amatch>")
1 0.000001 if s != ""
1 0.000001 if exists("b:did_indent")
unlet b:did_indent
1 0.000000 endif
" When there is a dot it is used to separate filetype names. Thus for
" "aaa.bbb" load "indent/aaa.vim" and then "indent/bbb.vim".
2 0.000003 for name in split(s, '\.')
1 0.002251 0.001846 exe 'runtime! indent/' . name . '.vim'
1 0.000747 exe 'runtime! indent/' . name . '.lua'
2 0.000001 endfor
1 0.000000 endif
FUNCTION <SNR>144_newlsp()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:23
Called 1 time
Total time: 0.003081
Self time: 0.000783
count total (s) self (s)
" job is the job used to talk to the backing instance of gopls.
" ready is 0 until the initialize response has been received. 1 afterwards.
" queue is messages to send after initialization
" last_request_id is id of the most recently sent request.
" buf is unprocessed/incomplete responses
" handlers is a mapping of request ids to dictionaries of functions.
" request id -> {start, requestComplete, handleResult, error}
" * start is a function that takes no arguments
" * requestComplete is a function that takes 1 argument. The parameter will be 1
" if the call was succesful.
" * handleResult takes a single argument, the result message received from gopls
" * error takes a single argument, the error message received from gopls.
" The error method is optional.
" workspaceDirectories is an array of named workspaces.
" wd is the working directory for gopls
" diagnostics is a dictionary whose keys are filenames and each value is a
" list of diagnostic messages for the file.
" diagnosticsQueue is a queue of diagnostics notifications that have been
" received, but not yet processed.
" fileVersions is a dictionary of filenames to versions.
" notificationQueue is a dictionary of filenames to functions. For a given
" filename, each notification will call the first function in the list of
" function values and remove it from the list. The functions should accept
" two arguments: an absolute path and a list of diagnotics messages for
" the file.
1 0.000008 let l:lsp = { 'job': '', 'ready': 0, 'queue': [], 'last_request_id': 0, 'buf': '', 'handlers': {}, 'workspaceDirectories': [], 'wd' : '', 'diagnosticsQueue': [], 'diagnostics': {}, 'fileVersions': {}, 'notificationQueue': {}, }
1 0.000005 0.000003 if !go#config#GoplsEnabled()
let l:lsp.sendMessage = funcref('s:noop')
return l:lsp
1 0.000000 endif
1 0.000005 0.000002 if !go#util#has_job()
let l:oldshortmess=&shortmess
if has('nvim')
set shortmess-=F
endif
call go#util#EchoWarning('Features that rely on gopls will not work without either Vim 8.0.0087 or newer with +job or Neovim')
" Sleep one second to make sure people see the message. Otherwise it is
" often immediately overwritten by an async message.
sleep 1
let &shortmess=l:oldshortmess
return l:lsp
1 0.000000 endif
1 0.000001 function! l:lsp.readMessage(data) dict abort
let l:responses = []
let l:rest = a:data
while 1
" Look for the end of the HTTP headers
let l:body_start_idx = matchend(l:rest, "\r\n\r\n")
if l:body_start_idx < 0
" incomplete header
break
endif
" Parse the Content-Length header.
let l:header = l:rest[:l:body_start_idx - 4]
let l:length_match = matchlist( l:header, '\vContent-Length: *(\d+)')
if empty(l:length_match)
" TODO(bc): shutdown gopls?
throw "invalid JSON-RPC header:\n" . l:header
endif
" get the start of the rest
let l:next_start_idx = l:body_start_idx + str2nr(l:length_match[1])
if len(l:rest) < l:next_start_idx
" incomplete response body
break
endif
call s:debug('received', l:rest[:l:next_start_idx - 1])
let l:body = l:rest[l:body_start_idx : l:next_start_idx - 1]
let l:rest = l:rest[l:next_start_idx :]
try
" add the json body to the list.
call add(l:responses, json_decode(l:body))
catch
" TODO(bc): log the message and/or show an error message.
finally
" intentionally left blank.
endtry
endwhile
return [l:rest, l:responses]
endfunction
1 0.000001 function! l:lsp.handleMessage(ch, data) dict abort
let self.buf .= a:data
let [self.buf, l:messages] = self.readMessage(self.buf)
for l:message in l:messages
if has_key(l:message, 'method')
if has_key(l:message, 'id')
call self.handleRequest(l:message)
else
call self.handleNotification(l:message)
endif
elseif has_key(l:message, 'result') || has_key(l:message, 'error')
call self.handleResponse(l:message)
endif
endfor
endfunction
1 0.000001 function! l:lsp.handleRequest(req) dict abort
if a:req.method == 'workspace/workspaceFolders'
let l:resp = go#lsp#message#WorkspaceFoldersResult(self.workspaceDirectories)
elseif a:req.method == 'workspace/configuration' && has_key(a:req, 'params') && has_key(a:req.params, 'items')
let l:resp = go#lsp#message#ConfigurationResult(a:req.params.items)
elseif a:req.method == 'client/registerCapability' && has_key(a:req, 'params') && has_key(a:req.params, 'registrations')
let l:resp = v:null
elseif a:req.method == 'workspace/applyEdit'
try
let l:ok = v:true
for l:change in a:req.params.edit.documentChanges
call s:applyDocumentChanges(a:req.params.edit.documentChanges)
endfor
catch
call go#util#EchoError(printf('could not apply edit: %s', v:exception))
let l:ok = v:false
endtry
let l:resp = go#lsp#message#ApplyWorkspaceEditResponse(l:ok)
else
return
endif
if get(self, 'exited', 0)
return
endif
let l:msg = self.newResponse(a:req.id, l:resp)
call self.write(l:msg)
endfunction
1 0.000001 function! l:lsp.handleResponse(resp) dict abort
if has_key(a:resp, 'id') && has_key(self.handlers, a:resp.id)
try
let l:handler = self.handlers[a:resp.id]
let l:winid = win_getid(winnr())
" Always set the active window to the window that was active when
" the request was sent. Among other things, this makes sure that
" the correct window's location list will be populated when the
" list type is 'location' and the user has moved windows since
" sending the request.
call win_gotoid(l:handler.winid)
if has_key(a:resp, 'error')
call l:handler.requestComplete(0)
if has_key(l:handler, 'error')
call call(l:handler.error, [a:resp.error.message])
else
call go#util#EchoError(a:resp.error.message)
endif
call win_gotoid(l:winid)
return
endif
call l:handler.requestComplete(1)
let l:winidBeforeHandler = l:handler.winid
call call(l:handler.handleResult, [a:resp.result])
" change the window back to the window that was active when
" starting to handle the message _only_ if the handler didn't
" update the winid, so that handlers can set the winid if needed
" (e.g. :GoDef).
if l:handler.winid == l:winidBeforeHandler
call win_gotoid(l:winid)
endif
finally
call remove(self.handlers, a:resp.id)
endtry
endif
endfunction
1 0.000000 function! l:lsp.handleNotification(req) dict abort
" TODO(bc): handle more notifications (e.g. window/showMessage).
if a:req.method == 'textDocument/publishDiagnostics'
call self.handleDiagnostics(a:req.params)
elseif a:req.method == 'window/showMessage'
call self.showMessage(a:req.params)
endif
endfunction
1 0.000000 function! l:lsp.handleDiagnostics(data) dict abort
let self.diagnosticsQueue = add(self.diagnosticsQueue, a:data)
call self.updateDiagnostics()
endfunction
1 0.000000 function! l:lsp.showMessage(data) dict abort
let l:msg = a:data.message
if a:data.type == 1
call go#util#EchoError(l:msg)
elseif a:data.type == 2
call go#util#EchoWarning(l:msg)
elseif a:data.type == 3
call go#util#EchoInfo(l:msg)
elseif a:data.type == 4
" do nothing for Log messages
endif
endfunction
" TODO(bc): process the queue asynchronously
1 0.000000 function! l:lsp.updateDiagnostics() dict abort
let l:level = go#config#DiagnosticsLevel()
for l:data in self.diagnosticsQueue
call remove(self.diagnosticsQueue, 0)
try
let l:diagnostics = []
let l:errorMatches = []
let l:warningMatches = []
let l:fname = go#path#FromURI(l:data.uri)
" get the buffer name relative to the current directory, because
" Vim says that a buffer name can't be an absolute path.
let l:bufname = fnamemodify(l:fname, ':.')
if len(l:data.diagnostics) > 0 && (l:level > 0 || bufnr(l:bufname) == bufnr(''))
" make sure the buffer is listed and loaded before calling getbufline() on it
if !bufexists(l:bufname)
call bufadd(l:bufname)
endif
if !bufloaded(l:bufname)
call bufload(l:bufname)
endif
for l:diag in l:data.diagnostics
if l:level < l:diag.severity
continue
endif
let [l:error, l:matchpos] = s:errorFromDiagnostic(l:diag, l:bufname, l:fname)
let l:diagnostics = add(l:diagnostics, l:error)
if empty(l:matchpos)
continue
endif
if l:diag.severity == 1
let l:errorMatches = add(l:errorMatches, l:matchpos)
elseif l:diag.severity == 2
let l:warningMatches = add(l:warningMatches, l:matchpos)
endif
endfor
endif
if bufnr(l:bufname) == bufnr('')
" only apply highlighting when the diagnostics are for the current
" version.
let l:lsp = s:lspfactory.get()
let l:version = get(l:lsp.fileVersions, l:fname, 0)
" it's tempting to only highlight matches when they are for the
" current version of the buffer, but that causes problems when the
" version number has been updated and the content has not. In such a
" case, the diagnostics may not be sent for later versions.
call s:highlightMatches(l:errorMatches, l:warningMatches)
endif
let self.diagnostics[l:fname] = l:diagnostics
if has_key(self.notificationQueue, l:fname) && len(self.notificationQueue[l:fname]) > 0
call call(self.notificationQueue[l:fname][0], copy(l:diagnostics))
call remove(self.notificationQueue[l:fname], 0)
endif
catch
"call go#util#EchoError(printf('%s: %s', v:throwpoint, v:exception))
endtry
endfor
endfunction
1 0.000000 function! l:lsp.handleInitializeResult(result) dict abort
if go#config#EchoCommandInfo()
call go#util#EchoProgress("initialized gopls")
endif
let status = { 'desc': '', 'type': 'gopls', 'state': 'initialized', }
call go#statusline#Update(self.wd, status)
let self.ready = 1
let l:msg = self.newMessage(go#lsp#message#Initialized())
call self.write(l:msg)
" send messages queued while waiting for ready.
for l:item in self.queue
call self.sendMessage(l:item.data, l:item.handler)
endfor
" reset the queue
let self.queue = []
endfunction
1 0.000000 function! l:lsp.sendMessage(data, handler) dict abort
if !self.last_request_id
let l:wd = go#util#ModuleRoot()
if l:wd == -1
call go#util#EchoError('could not determine appropriate working directory for gopls')
return -1
endif
if l:wd == ''
let l:wd = getcwd()
endif
let self.wd = l:wd
if go#config#EchoCommandInfo()
call go#util#EchoProgress("initializing gopls")
endif
let l:status = { 'desc': '', 'type': 'gopls', 'state': 'initializing', }
call go#statusline#Update(l:wd, l:status)
let self.workspaceDirectories = add(self.workspaceDirectories, l:wd)
let l:msg = self.newMessage(go#lsp#message#Initialize(l:wd))
let l:state = s:newHandlerState('')
let l:state.handleResult = funcref('self.handleInitializeResult', [], l:self)
let self.handlers[l:msg.id] = l:state
call l:state.start()
call self.write(l:msg)
endif
if !self.ready
call add(self.queue, {'data': a:data, 'handler': a:handler})
return
endif
let l:msg = self.newMessage(a:data)
if has_key(l:msg, 'id')
let self.handlers[l:msg.id] = a:handler
endif
call a:handler.start()
call self.write(l:msg)
endfunction
" newMessage returns a message constructed from data. data should be a dict
" with 2 or 3 keys: notification, method, and optionally params.
1 0.000000 function! l:lsp.newMessage(data) dict abort
let l:msg = { 'method': a:data.method, 'jsonrpc': '2.0', }
if !a:data.notification
let self.last_request_id += 1
let l:msg.id = self.last_request_id
endif
if has_key(a:data, 'params')
let l:msg.params = a:data.params
endif
return l:msg
endfunction
1 0.000001 function l:lsp.newResponse(id, result) dict abort
let l:msg = { 'jsonrpc': '2.0', 'id': a:id, 'result': a:result, }
return l:msg
endfunction
1 0.000000 function! l:lsp.write(msg) dict abort
if empty(get(self, 'job', {}))
return
endif
let l:body = json_encode(a:msg)
let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
call s:debug('sent', l:data)
if has('nvim')
call chansend(self.job, l:data)
return
endif
try
call ch_sendraw(self.job, l:data)
catch
call go#util#EchoError(printf('could not send message: %s', v:exception))
endtry
endfunction
1 0.000001 function! l:lsp.exit_cb(job, exit_status) dict
let self.exited = 1
if !get(self, 'restarting', 0)
return
endif
let l:queue = self.queue
let l:workspaces = self.workspaceDirectories
call s:lspfactory.reset()
let l:lsp = s:lspfactory.get()
" restore workspaces
call call('go#lsp#AddWorkspaceDirectory', l:workspaces)
" * send DidOpen messages for all buffers that have b:did_lsp_open set
" TODO(bc): check modifiable and filetype, too?
bufdo if get(b:, 'go_lsp_did_open', 0) | if &modified | call go#lsp#DidOpen(expand('%:p')) | else | call go#lsp#DidChange(expand('%:p')) | endif | endif
let l:lsp.queue = extend(l:lsp.queue, l:queue)
return
endfunction
1 0.000000 function! l:lsp.close_cb(ch) dict abort
" TODO(bc): remove the buffer variables that indicate that gopls has been
" informed that the file is open
endfunction
1 0.000000 function! l:lsp.err_cb(ch, msg) dict abort
if a:msg =~ '^\d\{4}/\d\d/\d\d\ \d\d:\d\d:\d\d debug server listening on port \d\+$' && !get(self, 'debugport', 0)
let self.debugport = substitute(a:msg, '\d\{4}/\d\d/\d\d\ \d\d:\d\d:\d\d debug server listening on port \(\d\+\).*$', '\1', '')
endif
call s:debug('stderr', a:msg)
endfunction
" explicitly bind callbacks to l:lsp so that within it, self will always refer
" to l:lsp instead of l:opts. See :help Partial for more information.
1 0.000085 let l:opts = { 'in_mode': 'raw', 'out_mode': 'raw', 'err_mode': 'nl', 'noblock': 1, 'err_cb': funcref('l:lsp.err_cb', [], l:lsp), 'out_cb': funcref('l:lsp.handleMessage', [], l:lsp), 'close_cb': funcref('l:lsp.close_cb', [], l:lsp), 'exit_cb': funcref('l:lsp.exit_cb', [], l:lsp), 'cwd': getcwd(),}
1 0.000133 0.000007 let l:bin_path = go#path#CheckBinPath("gopls")
1 0.000001 if empty(l:bin_path)
let l:lsp.sendMessage = funcref('s:noop')
return l:lsp
1 0.000000 endif
1 0.000001 let l:cmd = [l:bin_path]
1 0.000005 0.000003 let l:cmdopts = go#config#GoplsOptions()
1 0.000007 0.000003 if go#util#HasDebug('lsp')
" debugging can be enabled either with g:go_debug or with
" g:go_gopls_options; use g:go_gopls_options if it's given in case users
" are running the gopls debug server on a known port.
let l:needsDebug = 1
for l:item in l:cmdopts
let l:idx = stridx(l:item, '-debug')
if l:idx == 0 || l:idx == 1
let l:needsDebug = 0
endif
endfor
if l:needsDebug
let l:cmd = extend(l:cmd, ['-debug', 'localhost:0'])
endif
1 0.000000 endif
1 0.002726 0.000564 let l:lsp.job = go#job#Start(l:cmd+l:cmdopts, l:opts)
1 0.000003 return l:lsp
FUNCTION dashboard#change_to_dir()
Defined: ~/.local/share/nvim/site/pack/packer/start/dashboard-nvim/autoload/dashboard.vim:216
Called 1 time
Total time: 0.000006
Self time: 0.000006
count total (s) self (s)
1 0.000002 if get(g:, 'dashboard_change_to_dir', 0)
let dir = fnamemodify(a:path, ':h')
if isdirectory(dir)
echom "test"
execute 'lcd' dir
else
" Do nothing. E.g. a:path == `scp://foo/bar`
endif
1 0.000000 endif
FUNCTION ale#history#SetExitCode()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/history.vim:49
Called 3 times
Total time: 0.000141
Self time: 0.000034
count total (s) self (s)
3 0.000130 0.000023 let l:obj = s:FindHistoryItem(a:buffer, a:job_id)
" If we find a match, then set the code and status.
3 0.000005 let l:obj.exit_code = a:exit_code
3 0.000003 let l:obj.status = 'finished'
FUNCTION <SNR>126_GetLinterNames()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/linter.vim:330
Called 1 time
Total time: 0.000013
Self time: 0.000013
count total (s) self (s)
1 0.000001 let l:buffer_ale_linters = get(b:, 'ale_linters', {})
" b:ale_linters can be set to 'all'
1 0.000001 if l:buffer_ale_linters is# 'all'
return 'all'
1 0.000000 endif
" b:ale_linters can be set to a List.
1 0.000001 if type(l:buffer_ale_linters) is v:t_list
return l:buffer_ale_linters
1 0.000000 endif
" Try to get a buffer-local setting for the filetype
1 0.000001 if has_key(l:buffer_ale_linters, a:original_filetype)
return l:buffer_ale_linters[a:original_filetype]
1 0.000000 endif
" Try to get a global setting for the filetype
1 0.000001 if has_key(g:ale_linters, a:original_filetype)
return g:ale_linters[a:original_filetype]
1 0.000000 endif
" If the user has configured ALE to only enable linters explicitly, then
" don't enable any linters by default.
1 0.000001 if g:ale_linters_explicit
return []
1 0.000000 endif
" Try to get a default setting for the filetype
1 0.000001 if has_key(s:default_ale_linters, a:original_filetype)
1 0.000001 return s:default_ale_linters[a:original_filetype]
endif
return 'all'
FUNCTION ale#Pad()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale.vim:202
Called 1 time
Total time: 0.000001
Self time: 0.000001
count total (s) self (s)
1 0.000001 return !empty(a:string) ? ' ' . a:string : ''
FUNCTION ale#util#Writefile()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/util.vim:431
Called 2 times
Total time: 0.000934
Self time: 0.000934
count total (s) self (s)
2 0.000009 let l:corrected_lines = getbufvar(a:buffer, '&fileformat') is# 'dos' ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')') : a:lines
" Set binary flag if buffer doesn't have eol and nofixeol to avoid appending newline
2 0.000008 let l:flags = !getbufvar(a:buffer, '&eol') && exists('+fixeol') && !&fixeol ? 'bS' : 'S'
2 0.000914 call writefile(l:corrected_lines, a:filename, l:flags) " no-custom-checks
FUNCTION go#util#env()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:73
Called 4 times
Total time: 0.021679
Self time: 0.000162
count total (s) self (s)
4 0.000007 let l:key = tolower(a:key)
4 0.000006 if has_key(s:env_cache, l:key)
3 0.000003 return s:env_cache[l:key]
1 0.000000 endif
1 0.000097 if executable('go')
1 0.021530 0.000015 let l:var = call('go#util#'.l:key, [])
1 0.000016 0.000014 if go#util#ShellError() != 0
call go#util#EchoError(printf("'go env %s' failed", toupper(l:key)))
return ''
1 0.000001 endif
else
let l:var = eval("$".toupper(a:key))
1 0.000001 endif
1 0.000004 let s:env_cache[l:key] = l:var
1 0.000001 return l:var
FUNCTION ale_linters#go#gofmt#GetCommand()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gofmt.vim:4
Called 1 time
Total time: 0.000851
Self time: 0.000505
count total (s) self (s)
1 0.000851 0.000505 return ale#go#EnvString(a:buffer) . '%e -e %t'
FUNCTION <SNR>165_RunJob()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:401
Called 3 times
Total time: 0.010244
Self time: 0.000559
count total (s) self (s)
3 0.000035 0.000029 if ale#command#IsDeferred(a:command)
let a:command.result_callback = { command -> s:RunJob(command, a:options)}
return 1
3 0.000000 endif
3 0.000002 let l:command = a:command
3 0.000002 if empty(l:command)
return 0
3 0.000000 endif
3 0.000002 let l:cwd = a:options.cwd
3 0.000002 let l:executable = a:options.executable
3 0.000002 let l:buffer = a:options.buffer
3 0.000002 let l:linter = a:options.linter
3 0.000003 let l:output_stream = a:options.output_stream
3 0.000004 let l:read_buffer = a:options.read_buffer && !a:options.lint_file
3 0.000007 let l:info = g:ale_buffer_info[l:buffer]
3 0.000014 let l:Callback = function('s:HandleExit', [{ 'linter': l:linter, 'executable': l:executable,}])
3 0.009578 0.000050 let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { 'cwd': l:cwd, 'output_stream': l:output_stream, 'executable': l:executable, 'read_buffer': l:read_buffer, 'log_output': 1, 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:linter.name),})
" Only proceed if the job is being run.
3 0.000003 if empty(l:result)
return 0
3 0.000000 endif
3 0.000067 0.000024 call ale#engine#MarkLinterActive(l:info, l:linter)
3 0.000488 0.000380 silent doautocmd <nomodeline> User ALEJobStarted
3 0.000008 return 1
FUNCTION ale#lsp_linter#GetOptions()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_linter.vim:167
Called 1 time
Total time: 0.000017
Self time: 0.000010
count total (s) self (s)
1 0.000001 if has_key(a:linter, 'initialization_options_callback')
return ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
1 0.000000 endif
1 0.000001 if has_key(a:linter, 'initialization_options')
1 0.000001 let l:Options = a:linter.initialization_options
1 0.000001 if type(l:Options) is v:t_func
1 0.000009 0.000003 let l:Options = l:Options(a:buffer)
1 0.000000 endif
1 0.000000 return l:Options
endif
return {}
FUNCTION go#lsp#message#ChangeWorkspaceFolders()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp/message.vim:260
Called 1 time
Total time: 0.001126
Self time: 0.000022
count total (s) self (s)
1 0.001117 0.000012 let l:addDirs = map(copy(a:add), function('s:workspaceFolder', []))
1 0.000004 let l:removeDirs = map(copy(a:remove), function('s:workspaceFolder', []))
1 0.000003 return { 'notification': 1, 'method': 'workspace/didChangeWorkspaceFolders', 'params': { 'event': { 'removed': l:removeDirs, 'added': l:addDirs, }, } }
FUNCTION ale#lsp#Register()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp.vim:10
Called 1 time
Total time: 0.000021
Self time: 0.000021
count total (s) self (s)
1 0.000003 let l:conn_id = a:executable_or_address . ':' . a:project
1 0.000002 if !has_key(s:connections, l:conn_id)
" is_tsserver: 1 if the connection is for tsserver.
" data: The message data received so far.
" root: The project root.
" open_documents: A Dictionary mapping buffers to b:changedtick, keeping
" track of when documents were opened, and when we last changed them.
" initialized: 0 if the connection is ready, 1 otherwise.
" init_request_id: The ID for the init request.
" init_options: Options to send to the server.
" config: Configuration settings to send to the server.
" callback_list: A list of callbacks for handling LSP responses.
" capabilities_queue: The list of callbacks to call with capabilities.
" capabilities: Features the server supports.
1 0.000012 let s:connections[l:conn_id] = { 'id': l:conn_id, 'is_tsserver': 0, 'data': '', 'root': a:project, 'open_documents': {}, 'initialized': 0, 'init_request_id': 0, 'init_options': a:init_options, 'config': {}, 'callback_list': [], 'init_queue': [], 'capabilities': { 'hover': 0, 'rename': 0, 'references': 0, 'completion': 0, 'completion_trigger_characters': [], 'definition': 0, 'typeDefinition': 0, 'symbol_search': 0, 'code_actions': 0, 'did_save': 0, 'includeText': 0, },}
1 0.000001 endif
1 0.000001 return l:conn_id
FUNCTION ale#lsp_linter#HandleLSPResponse()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_linter.vim:139
Called 27 times
Total time: 0.003120
Self time: 0.002619
count total (s) self (s)
27 0.000073 let l:method = get(a:response, 'method', '')
27 0.000093 if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
call s:HandleLSPErrorMessage(l:linter_name, a:response)
27 0.000028 elseif l:method is# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:conn_id, a:response)
27 0.000020 elseif l:method is# 'window/showMessage'
2 0.002253 0.001752 call ale#lsp_window#HandleShowMessage( s:lsp_linter_map[a:conn_id], g:ale_lsp_show_message_format, a:response.params)
25 0.000054 elseif get(a:response, 'type', '') is# 'event'&& get(a:response, 'event', '') is# 'semanticDiag'
call s:HandleTSServerDiagnostics(a:response, 'semantic')
25 0.000124 elseif get(a:response, 'type', '') is# 'event'&& get(a:response, 'event', '') is# 'syntaxDiag'
call s:HandleTSServerDiagnostics(a:response, 'syntax')
25 0.000073 elseif get(a:response, 'type', '') is# 'event'&& get(a:response, 'event', '') is# 'suggestionDiag'&& get(g:, 'ale_lsp_suggestions', '1') == 1
call s:HandleTSServerDiagnostics(a:response, 'suggestion')
27 0.000009 endif
FUNCTION <SNR>100_echo()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:407
Called 3 times
Total time: 0.000225
Self time: 0.000225
count total (s) self (s)
3 0.000007 let l:msg = []
3 0.000006 if type(a:msg) != type([])
3 0.000008 let l:msg = split(a:msg, "\n")
else
let l:msg = a:msg
3 0.000001 endif
" Tabs display as ^I or <09>, so manually expand them.
3 0.000014 let l:msg = map(l:msg, 'substitute(v:val, "\t", " ", "")')
3 0.000029 exe 'echohl ' . a:hi
6 0.000006 for line in l:msg
3 0.000088 echom "vim-go: " . line
6 0.000008 endfor
3 0.000038 echohl None
FUNCTION go#lsp#message#Initialize()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp/message.vim:5
Called 1 time
Total time: 0.000111
Self time: 0.000040
count total (s) self (s)
1 0.000110 0.000040 return { 'notification': 0, 'method': 'initialize', 'params': { 'processId': getpid(), 'rootUri': go#path#ToURI(a:wd), 'capabilities': { 'workspace': { 'workspaceFolders': v:true, 'didChangeConfiguration': { 'dynamicRegistration': v:true, }, 'workspaceEdit': { 'documentChanges': v:true, }, 'configuration': v:true, }, 'textDocument': { 'hover': { 'contentFormat': ['plaintext'], }, 'completion': { 'completionItem': { 'snippetSupport': go#config#GoplsUsePlaceholders() ? v:true : v:false, }, }, 'codeAction': { 'codeActionLiteralSupport': { 'codeActionKind': { 'valueSet': ['source.organizeImports', 'refactor.rewrite'], }, }, }, } }, 'workspaceFolders': [s:workspaceFolder(0, a:wd)], } }
FUNCTION <SNR>180_CloseWindowIfNeeded()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/list.vim:215
Called 1 time
Total time: 0.000088
Self time: 0.000042
count total (s) self (s)
1 0.000086 0.000040 if ale#Var(a:buffer, 'keep_list_window_open') || !s:ShouldOpen(a:buffer)
1 0.000001 return
endif
let l:did_close_any_list = 0
try
" Only close windows if the quickfix list or loclist is completely empty,
" including errors set through other means.
if g:ale_set_quickfix
if empty(getqflist())
cclose
let l:did_close_any_list = 1
endif
else
let l:win_ids = s:WinFindBuf(a:buffer)
for l:win_id in l:win_ids
if g:ale_set_loclist && empty(getloclist(l:win_id))
lclose
let l:did_close_any_list = 1
endif
endfor
endif
" Ignore 'Cannot close last window' errors.
catch /E444/
endtry
if l:did_close_any_list
call s:RestoreViewIfNeeded(a:buffer)
endif
FUNCTION <SNR>180_ShouldOpen()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/list.vim:40
Called 4 times
Total time: 0.000061
Self time: 0.000034
count total (s) self (s)
4 0.000044 0.000016 let l:val = ale#Var(a:buffer, 'open_list')
4 0.000008 let l:saved = getbufvar(a:buffer, 'ale_save_event_fired', 0)
4 0.000006 return l:val is 1 || (l:val is# 'on_save' && l:saved)
FUNCTION ale#linter#Define()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/linter.vim:251
Called 28 times
Total time: 0.003219
Self time: 0.000515
count total (s) self (s)
" This command will throw from the sandbox.
28 0.000062 let &l:equalprg=&l:equalprg
28 0.002846 0.000142 let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
28 0.000028 if !has_key(s:linters, a:filetype)
1 0.000001 let s:linters[a:filetype] = []
28 0.000004 endif
" Remove previously defined linters with the same name.
28 0.000188 call filter(s:linters[a:filetype], 'v:val.name isnot# a:linter.name')
28 0.000037 call add(s:linters[a:filetype], l:new_linter)
FUNCTION go#lsp#AddWorkspaceDirectory()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:1174
Called 1 time
Total time: 0.031196
Self time: 0.000639
count total (s) self (s)
1 0.000001 if a:0 == 0
return
1 0.000000 endif
1 0.000023 0.000006 call go#lsp#CleanWorkspaces()
1 0.000000 let l:workspaces = []
2 0.000001 for l:dir in a:000
1 0.000008 let l:dir = fnamemodify(l:dir, ':p')
1 0.000002 if len(l:dir) > 1 && l:dir[-1:] == '/'
1 0.000001 let l:dir = l:dir[:-2]
1 0.000000 endif
1 0.000003 if !isdirectory(l:dir)
continue
1 0.000000 endif
1 0.000004 let l:workspaces = add(l:workspaces, l:dir)
2 0.000001 endfor
1 0.000006 0.000002 let l:lsp = s:lspfactory.get()
1 0.000110 0.000005 let l:state = s:newHandlerState('')
1 0.000027 0.000011 let l:lsp.workspaceDirectories = s:dedup(extend(l:lsp.workspaceDirectories, l:workspaces))
1 0.002210 0.000573 let l:msg = go#lsp#message#ChangeWorkspaceFolders(l:workspaces, [])
1 0.028788 0.000011 call l:lsp.sendMessage(l:msg, l:state)
1 0.000000 return 0
FUNCTION <SNR>118_InitColor()
Defined: ~/.local/share/nvim/site/pack/packer/start/indentLine/after/plugin/indentLine.vim:35
Called 2 times
Total time: 0.000116
Self time: 0.000116
count total (s) self (s)
2 0.000003 if !g:indentLine_setColors
return
2 0.000000 endif
2 0.000002 let default_term_bg = "NONE"
2 0.000001 let default_gui_bg = "NONE"
2 0.000002 if &background ==# "light"
let default_term_fg = 249
let default_gui_fg = "Grey70"
2 0.000001 else
2 0.000001 let default_term_fg = 239
2 0.000001 let default_gui_fg = "Grey30"
2 0.000000 endif
2 0.000002 if g:indentLine_defaultGroup != ""
let default_id = synIDtrans(hlID(g:indentLine_defaultGroup))
let default_term_fg = synIDattr(default_id, "fg", "cterm") == "" ? default_term_fg : synIDattr(default_id, "fg", "cterm")
let default_term_bg = synIDattr(default_id, "bg", "cterm") == "" ? default_term_bg : synIDattr(default_id, "bg", "cterm")
let default_gui_fg = synIDattr(default_id, "fg", "gui") == "" ? default_gui_fg : synIDattr(default_id, "fg", "gui")
let default_gui_bg = synIDattr(default_id, "bg", "gui") == "" ? default_gui_bg : synIDattr(default_id, "bg", "gui")
2 0.000000 endif
2 0.000003 if !exists("g:indentLine_color_term")
2 0.000002 let term_color = default_term_fg
else
let term_color = g:indentLine_color_term
2 0.000000 endif
2 0.000002 if !exists("g:indentLine_bgcolor_term")
2 0.000001 let term_bgcolor = default_term_bg
else
let term_bgcolor = g:indentLine_bgcolor_term
2 0.000000 endif
2 0.000002 if !exists("g:indentLine_color_gui")
2 0.000001 let gui_color = default_gui_fg
else
let gui_color = g:indentLine_color_gui
2 0.000000 endif
2 0.000002 if !exists("g:indentLine_bgcolor_gui")
2 0.000001 let gui_bgcolor = default_gui_bg
else
let gui_bgcolor = g:indentLine_bgcolor_gui
2 0.000000 endif
2 0.000026 execute "highlight Conceal cterm=NONE ctermfg=" . term_color . " ctermbg=" . term_bgcolor
2 0.000012 execute "highlight Conceal gui=NONE guifg=" . gui_color . " guibg=" . gui_bgcolor
2 0.000001 if &term ==# "linux"
if &background ==# "light"
let tty_color = exists("g:indentLine_color_tty_light") ? g:indentLine_color_tty_light : 4
else
let tty_color = exists("g:indentLine_color_tty_dark") ? g:indentLine_color_tty_dark : 2
endif
execute "highlight Conceal cterm=bold ctermfg=" . tty_color . " ctermbg=NONE"
2 0.000000 endif
FUNCTION 12()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp.vim:133
Called 90 times
Total time: 0.014810
Self time: 0.002144
count total (s) self (s)
90 0.000140 let self.buf .= a:data
90 0.005899 0.000527 let [self.buf, l:messages] = self.readMessage(self.buf)
122 0.000126 for l:message in l:messages
32 0.000072 if has_key(l:message, 'method')
31 0.000031 if has_key(l:message, 'id')
3 0.001852 0.000013 call self.handleRequest(l:message)
28 0.000011 else
28 0.000441 0.000157 call self.handleNotification(l:message)
31 0.000010 endif
1 0.000001 elseif has_key(l:message, 'result') || has_key(l:message, 'error')
1 0.005174 0.000003 call self.handleResponse(l:message)
32 0.000009 endif
122 0.000107 endfor
FUNCTION <SNR>100_clear_group_from_matches()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:611
Called 1 time
Total time: 0.000076
Self time: 0.000076
count total (s) self (s)
1 0.000001 let l:cleared = 0
1 0.000025 let m = getmatches()
21 0.000009 for item in m
20 0.000012 if item['group'] == a:group
call matchdelete(item['id'])
let l:cleared = 1
20 0.000004 endif
21 0.000004 endfor
1 0.000001 return l:cleared
FUNCTION ale_linters#go#gopls#FindProjectRoot()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gopls.vim:16
Called 1 time
Total time: 0.001754
Self time: 0.000725
count total (s) self (s)
1 0.000012 0.000005 let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
1 0.001734 0.000713 let l:project_root = l:go_modules_off ? '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
1 0.000001 let l:mods = ':h'
1 0.000001 if empty(l:project_root)
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
let l:mods = ':h:h'
1 0.000000 endif
1 0.000002 return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : ''
FUNCTION <SNR>127_strip_ranges()
Defined: ~/.local/share/nvim/site/pack/packer/start/loupe/autoload/loupe/private.vim:67
Called 1 time
Total time: 0.000221
Self time: 0.000221
count total (s) self (s)
1 0.000004 let l:cmdline=a:cmdline
" All the range tokens may be followed (several times) by '+' or '-' and an
" optional number.
1 0.000003 let l:modifier='\([+-]\d*\)*'
" Range tokens as specified in `:h cmdline-ranges`.
1 0.000047 let l:cmdline=substitute(l:cmdline, '^\d\+' . l:modifier, '', '') " line number
1 0.000016 let l:cmdline=substitute(l:cmdline, '^\.' . l:modifier, '', '') " current line
1 0.000011 let l:cmdline=substitute(l:cmdline, '^$' . l:modifier, '', '') " last line in file
1 0.000011 let l:cmdline=substitute(l:cmdline, '^%' . l:modifier, '', '') " entire file
1 0.000016 let l:cmdline=substitute(l:cmdline, "^'[a-z]\\c" . l:modifier, '', '') " mark t (or T)
1 0.000012 let l:cmdline=substitute(l:cmdline, "^'[<>]" . l:modifier, '', '') " visual selection marks
1 0.000013 let l:cmdline=substitute(l:cmdline, '^/[^/]\+/' . l:modifier, '', '') " /{pattern}/
1 0.000011 let l:cmdline=substitute(l:cmdline, '^?[^?]\+?' . l:modifier, '', '') " ?{pattern}?
1 0.000012 let l:cmdline=substitute(l:cmdline, '^\\/' . l:modifier, '', '') " \/ (next match of previous pattern)
1 0.000010 let l:cmdline=substitute(l:cmdline, '^\\?' . l:modifier, '', '') " \? (last match of previous pattern)
1 0.000010 let l:cmdline=substitute(l:cmdline, '^\\&' . l:modifier, '', '') " \& (last match of previous substitution)
" Separators (see: `:h :,` and `:h :;`).
1 0.000009 let l:cmdline=substitute(l:cmdline, '^,', '', '') " , (separator)
1 0.000008 let l:cmdline=substitute(l:cmdline, '^;', '', '') " ; (separator)
1 0.000004 return l:cmdline
FUNCTION ale#sign#SetSigns()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:442
Called 3 times
Total time: 0.005932
Self time: 0.000352
count total (s) self (s)
3 0.000009 if !bufexists(str2nr(a:buffer))
" Stop immediately when attempting to set signs for a buffer which
" does not exist.
return
3 0.000001 endif
" Find the current markers
3 0.000472 0.000042 let [l:is_dummy_sign_set, l:current_sign_list] = ale#sign#FindCurrentSigns(a:buffer)
" Update the line numbers for items from before which may have moved.
3 0.000399 0.000095 call s:UpdateLineNumbers(a:buffer, l:current_sign_list, a:loclist)
" Group items after updating the line numbers.
3 0.000404 0.000089 let l:grouped_items = s:GroupLoclistItems(a:buffer, a:loclist)
" Build a map of current and new signs, with the lines as the keys.
3 0.003632 0.000017 let l:sign_map = s:BuildSignMap( a:buffer, l:current_sign_list, l:grouped_items,)
3 0.000934 0.000017 let l:command_list = ale#sign#GetSignCommands( a:buffer, l:is_dummy_sign_set, l:sign_map,)
" Change the sign column color if the option is on.
3 0.000003 if g:ale_change_sign_column_color && !empty(a:loclist)
highlight clear SignColumn
highlight link SignColumn ALESignColumnWithErrors
3 0.000001 endif
27 0.000010 for l:command in l:command_list
24 0.000031 silent! execute l:command
27 0.000005 endfor
" Reset the sign column color when there are no more errors.
3 0.000003 if g:ale_change_sign_column_color && empty(a:loclist)
highlight clear SignColumn
highlight link SignColumn ALESignColumnWithoutErrors
3 0.000001 endif
FUNCTION <SNR>165_RunIfExecutable()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:527
Called 3 times
Total time: 0.012452
Self time: 0.000174
count total (s) self (s)
3 0.000020 0.000013 if ale#command#IsDeferred(a:executable)
let a:executable.result_callback = { executable -> s:RunIfExecutable( a:buffer, a:linter, a:lint_file, executable )}
return 1
3 0.000002 endif
3 0.001036 0.000013 if ale#engine#IsExecutable(a:buffer, a:executable)
" Use different job types for file or linter jobs.
3 0.000003 let l:job_type = a:lint_file ? 'file_linter' : 'linter'
3 0.000015 call setbufvar(a:buffer, 'ale_job_type', l:job_type)
" Get the cwd for the linter and set it before we call GetCommand.
" This will ensure that ale#command#Run uses it by default.
3 0.000023 0.000010 let l:cwd = ale#linter#GetCwd(a:buffer, a:linter)
3 0.000002 if l:cwd isnot v:null
1 0.000012 0.000003 call ale#command#SetCwd(a:buffer, l:cwd)
3 0.000001 endif
3 0.000991 0.000011 let l:command = ale#linter#GetCommand(a:buffer, a:linter)
3 0.000002 if l:cwd isnot v:null
1 0.000005 0.000003 call ale#command#ResetCwd(a:buffer)
3 0.000001 endif
3 0.000016 let l:options = { 'cwd': l:cwd, 'executable': a:executable, 'buffer': a:buffer, 'linter': a:linter, 'output_stream': get(a:linter, 'output_stream', 'stdout'), 'read_buffer': a:linter.read_buffer, 'lint_file': a:lint_file,}
3 0.010296 0.000052 return s:RunJob(l:command, l:options)
endif
return 0
FUNCTION ale#lsp#OnInit()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp.vim:669
Called 1 time
Total time: 0.000007
Self time: 0.000007
count total (s) self (s)
1 0.000002 let l:conn = get(s:connections, a:conn_id, {})
1 0.000001 if empty(l:conn)
return
1 0.000000 endif
1 0.000000 if l:conn.initialized
call a:Callback()
1 0.000000 else
1 0.000001 call add(l:conn.init_queue, a:Callback)
1 0.000000 endif
FUNCTION ale#engine#InitBufferInfo()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:82
Called 1 time
Total time: 0.000006
Self time: 0.000006
count total (s) self (s)
1 0.000001 if !has_key(g:ale_buffer_info, a:buffer)
" active_linter_list will hold the list of active linter names
" loclist holds the loclist items after all jobs have completed.
1 0.000003 let g:ale_buffer_info[a:buffer] = { 'active_linter_list': [], 'active_other_sources_list': [], 'loclist': [],}
1 0.000001 return 1
endif
return 0
FUNCTION ale_linters#go#govet#GetCommand()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/govet.vim:10
Called 1 time
Total time: 0.000030
Self time: 0.000010
count total (s) self (s)
1 0.000008 0.000003 let l:options = ale#Var(a:buffer, 'go_govet_options')
1 0.000022 0.000007 return ale#go#EnvString(a:buffer) . ale#Var(a:buffer, 'go_go_executable') . ' vet ' . (!empty(l:options) ? ' ' . l:options : '') . ' .'
FUNCTION <SNR>170_CheckWithLSP()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_linter.vim:438
Called 1 time
Total time: 0.000154
Self time: 0.000057
count total (s) self (s)
1 0.000002 let l:buffer = a:details.buffer
1 0.000003 let l:info = get(g:ale_buffer_info, l:buffer)
1 0.000001 if empty(l:info)
return
1 0.000000 endif
1 0.000001 let l:id = a:details.connection_id
" Register a callback now for handling errors now.
1 0.000002 let l:Callback = function('ale#lsp_linter#HandleLSPResponse')
1 0.000107 0.000025 call ale#lsp#RegisterCallback(l:id, l:Callback)
" Remember the linter this connection is for.
1 0.000002 let s:lsp_linter_map[l:id] = a:linter.name
1 0.000001 if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:message) != 0
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
1 0.000000 else
1 0.000020 0.000005 let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer)
1 0.000000 endif
" If this was a file save event, also notify the server of that.
1 0.000003 if a:linter.lsp isnot# 'tsserver'&& getbufvar(l:buffer, 'ale_save_event_fired', 0)&& ale#lsp#HasCapability(l:buffer, 'did_save')
let l:include_text = ale#lsp#HasCapability(l:buffer, 'includeText')
let l:save_message = ale#lsp#message#DidSave(l:buffer, l:include_text)
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
1 0.000000 endif
FUNCTION go#lsp#message#DidChange()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp/message.vim:173
Called 1 time
Total time: 0.000062
Self time: 0.000012
count total (s) self (s)
1 0.000061 0.000011 return { 'notification': 1, 'method': 'textDocument/didChange', 'params': { 'textDocument': { 'uri': go#path#ToURI(a:file), 'version': a:version, }, 'contentChanges': [ { 'text': a:content, } ] } }
FUNCTION <SNR>165_RunLinter()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:579
Called 4 times
Total time: 0.021993
Self time: 0.000899
count total (s) self (s)
4 0.000007 if !empty(a:linter.lsp)
1 0.009357 0.000779 return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter)
3 0.000001 else
3 0.000124 0.000060 let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
3 0.012497 0.000045 return s:RunIfExecutable(a:buffer, a:linter, a:lint_file, l:executable)
endif
return 0
FUNCTION <SNR>178_HandleUnixFormat()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/handlers/unix.vim:4
Called 2 times
Total time: 0.001622
Self time: 0.000300
count total (s) self (s)
2 0.000003 let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):?(\d+)?:? ?(.+)$'
2 0.000001 let l:output = []
30 0.001356 0.000034 for l:match in ale#util#GetMatches(a:lines, l:pattern)
28 0.000242 call add(l:output, { 'lnum': l:match[1] + 0, 'col': l:match[2] + 0, 'text': l:match[3], 'type': a:type,})
30 0.000007 endfor
2 0.000001 return l:output
FUNCTION go#config#HighlightFunctionCalls()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/config.vim:449
Called 1 time
Total time: 0.000002
Self time: 0.000002
count total (s) self (s)
1 0.000001 return get(g:, 'go_highlight_function_calls', 0)
FUNCTION go#util#ClearHighlights()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:594
Called 1 time
Total time: 0.000100
Self time: 0.000024
count total (s) self (s)
1 0.000002 if has('textprop')
" the property type may not exist when syntax highlighting is not enabled.
if empty(prop_type_get(a:group))
return
endif
if !has('patch-8.1.1035')
return prop_remove({'type': a:group, 'all': 1}, 1, line('$'))
endif
return prop_remove({'type': a:group, 'all': 1})
1 0.000000 endif
1 0.000002 if exists("*matchaddpos")
1 0.000089 0.000013 return s:clear_group_from_matches(a:group)
endif
FUNCTION go#util#Exec()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/util.vim:217
Called 3 times
Total time: 0.297171
Self time: 0.000786
count total (s) self (s)
3 0.000004 if len(a:cmd) == 0
call go#util#EchoError("go#util#Exec() called with empty a:cmd")
return ['', 1]
3 0.000001 endif
3 0.000004 let l:bin = a:cmd[0]
" Lookup the full path, respecting settings such as 'go_bin_path'. On errors,
" CheckBinPath will show a warning for us.
3 0.023522 0.000695 let l:bin = go#path#CheckBinPath(l:bin)
3 0.000005 if empty(l:bin)
return ['', 1]
3 0.000001 endif
" Finally execute the command using the full, resolved path. Do not pass the
" unmodified command as the correct program might not exist in $PATH.
3 0.273616 0.000057 return call('s:exec', [[l:bin] + a:cmd[1:]] + a:000)
FUNCTION ale#FileTooLarge()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale.vim:24
Called 6 times
Total time: 0.000033
Self time: 0.000033
count total (s) self (s)
6 0.000017 let l:max = getbufvar(a:buffer, 'ale_maximum_file_size', get(g:, 'ale_maximum_file_size', 0))
6 0.000013 return l:max > 0 ? (line2byte(line('$') + 1) > l:max) : 0
FUNCTION ale#engine#MarkLinterInactive()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:43
Called 3 times
Total time: 0.000024
Self time: 0.000024
count total (s) self (s)
3 0.000023 call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter_name')
FUNCTION ale_linters#go#golint#GetCommand()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/golint.vim:7
Called 1 time
Total time: 0.000079
Self time: 0.000037
count total (s) self (s)
1 0.000008 0.000003 let l:options = ale#Var(a:buffer, 'go_golint_options')
1 0.000068 0.000031 return ale#go#EnvString(a:buffer) . '%e' . (!empty(l:options) ? ' ' . l:options : '') . ' %t'
FUNCTION ale#engine#IsCheckingBuffer()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:101
Called 7 times
Total time: 0.000040
Self time: 0.000040
count total (s) self (s)
7 0.000014 let l:info = get(g:ale_buffer_info, a:buffer, {})
7 0.000022 return !empty(get(l:info, 'active_linter_list', [])) || !empty(get(l:info, 'active_other_sources_list', []))
FUNCTION ale#job#ValidateArguments()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/job.vim:144
Called 4 times
Total time: 0.000015
Self time: 0.000015
count total (s) self (s)
4 0.000008 if a:options.mode isnot# 'nl' && a:options.mode isnot# 'raw'
throw 'Invalid mode: ' . a:options.mode
4 0.000001 endif
FUNCTION ale#engine#MarkLinterActive()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:28
Called 3 times
Total time: 0.000043
Self time: 0.000043
count total (s) self (s)
3 0.000002 let l:found = 0
6 0.000018 for l:other_linter in a:info.active_linter_list
3 0.000004 if l:other_linter.name is# a:linter.name
let l:found = 1
break
3 0.000001 endif
6 0.000002 endfor
3 0.000002 if !l:found
3 0.000003 call add(a:info.active_linter_list, a:linter)
3 0.000001 endif
FUNCTION ale#command#ResetCwd()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim:39
Called 4 times
Total time: 0.000010
Self time: 0.000010
count total (s) self (s)
4 0.000004 if has_key(s:buffer_data, a:buffer)
4 0.000004 let s:buffer_data[a:buffer].cwd = v:null
4 0.000001 endif
FUNCTION ale#sign#ParseSignsWithGetPlaced()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:205
Called 3 times
Total time: 0.000209
Self time: 0.000209
count total (s) self (s)
3 0.000041 let l:signs = sign_getplaced(a:buffer, { 'group': s:supports_sign_groups ? 'ale' : '' })[0].signs
3 0.000003 let l:result = []
3 0.000003 let l:is_dummy_sign_set = 0
23 0.000009 for l:sign in l:signs
20 0.000012 if l:sign['name'] is# 'ALEDummySign'
let l:is_dummy_sign_set = 1
20 0.000003 else
20 0.000038 call add(l:result, [ str2nr(l:sign['lnum']), str2nr(l:sign['id']), l:sign['name'],])
20 0.000003 endif
23 0.000006 endfor
3 0.000008 return [l:is_dummy_sign_set, l:result]
FUNCTION ale#command#FormatCommand()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim:192
Called 4 times
Total time: 0.002308
Self time: 0.000488
count total (s) self (s)
4 0.000007 let l:temporary_file = ''
4 0.000003 let l:command = a:command
4 0.000003 if !empty(a:cwd)
1 0.000022 0.000004 let l:command = ale#command#CdString(a:cwd) . l:command
4 0.000001 endif
" First replace all uses of %%, used for literal percent characters,
" with an ugly string.
4 0.000014 let l:command = substitute(l:command, '%%', '<<PERCENTS>>', 'g')
" Replace %e with the escaped executable, if available.
4 0.000008 if !empty(a:executable) && l:command =~# '%e'
3 0.000049 0.000020 let l:command = substitute(l:command, '%e', '\=ale#Escape(a:executable)', 'g')
4 0.000001 endif
" Replace all %s occurrences in the string with the name of the current
" file.
4 0.000004 if l:command =~# '%s'
1 0.000242 let l:filename = fnamemodify(bufname(a:buffer), ':p')
1 0.000048 0.000024 let l:command = substitute( l:command, s:path_format_regex, '\=s:FormatFilename(l:filename, a:mappings, submatch(1))', 'g')
4 0.000001 endif
4 0.000006 if a:input isnot v:false && l:command =~# '%t'
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
2 0.000059 0.000008 let l:temporary_file = s:TemporaryFilename(a:buffer)
2 0.000050 0.000023 let l:command = substitute( l:command, '\v\%t(%(:h|:t|:r|:e)*)', '\=s:FormatFilename(l:temporary_file, a:mappings, submatch(1))', 'g')
4 0.000001 endif
" Finish formatting so %% becomes %.
4 0.000011 let l:command = substitute(l:command, '<<PERCENTS>>', '%', 'g')
4 0.000004 if a:pipe_file_if_needed && empty(l:temporary_file)
" If we are to send the Vim buffer to a command, we'll do it
" in the shell. We'll write out the file to a temporary file,
" and then read it back in, in the shell.
let l:temporary_file = s:TemporaryFilename(a:buffer)
let l:command = l:command . ' < ' . ale#Escape(l:temporary_file)
4 0.000001 endif
4 0.001713 0.000043 let l:file_created = ale#command#CreateTempFile( a:buffer, l:temporary_file, a:input,)
4 0.000005 return [l:temporary_file, l:command, l:file_created]
FUNCTION <SNR>118_Disable()
Defined: ~/.local/share/nvim/site/pack/packer/start/indentLine/after/plugin/indentLine.vim:309
Called 1 time
Total time: 0.000023
Self time: 0.000005
count total (s) self (s)
1 0.000021 0.000003 if s:Filter() == 0
call s:IndentLinesDisable()
call s:LeadingSpaceDisable()
1 0.000000 endif
FUNCTION ale#command#Run()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim:333
Called 3 times
Total time: 0.009483
Self time: 0.001029
count total (s) self (s)
3 0.000004 let l:options = get(a:000, 0, {})
3 0.000003 if len(a:000) > 1
throw 'Too many arguments!'
3 0.000000 endif
3 0.000004 let l:output_stream = get(l:options, 'output_stream', 'stdout')
3 0.000002 let l:line_list = []
3 0.000003 let l:cwd = get(l:options, 'cwd', v:null)
3 0.000002 if l:cwd is v:null
" Default the working directory to whatever it was for the last
" command run in the chain.
2 0.000004 let l:cwd = get(get(s:buffer_data, a:buffer, {}), 'cwd', v:null)
3 0.000001 endif
3 0.002280 0.000029 let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand( a:buffer, get(l:options, 'executable', ''), a:command, get(l:options, 'read_buffer', 0), get(l:options, 'input', v:null), l:cwd, get(l:options, 'filename_mappings', []),)
3 0.000954 0.000566 let l:command = ale#job#PrepareCommand(a:buffer, l:command)
3 0.000026 let l:job_options = { 'exit_cb': {job_id, exit_code -> s:ExitCallback( a:buffer, l:line_list, a:Callback, { 'job_id': job_id, 'exit_code': exit_code, 'temporary_file': l:temporary_file, 'log_output': get(l:options, 'log_output', 1), 'result': l:result, } )}, 'mode': 'nl',}
3 0.000002 if l:output_stream is# 'stdout'
let l:job_options.out_cb = function('s:GatherOutput', [l:line_list])
3 0.000002 elseif l:output_stream is# 'stderr'
2 0.000006 let l:job_options.err_cb = function('s:GatherOutput', [l:line_list])
1 0.000000 elseif l:output_stream is# 'both'
1 0.000003 let l:job_options.out_cb = function('s:GatherOutput', [l:line_list])
1 0.000002 let l:job_options.err_cb = function('s:GatherOutput', [l:line_list])
3 0.000001 endif
3 0.000002 let l:status = 'failed'
3 0.000003 if get(g:, 'ale_run_synchronously') == 1
if get(g:, 'ale_emulate_job_failure') == 1
let l:job_id = 0
else
" Generate a fake job ID for tests.
let s:fake_job_id = get(s:, 'fake_job_id', 0) + 1
let l:job_id = s:fake_job_id
endif
3 0.000005 elseif has('win32')
let l:job_id = ale#job#StartWithCmd(l:command, l:job_options)
3 0.000001 else
3 0.005813 0.000082 let l:job_id = ale#job#Start(l:command, l:job_options)
3 0.000001 endif
3 0.000001 if l:job_id
3 0.000005 let l:status = 'started'
3 0.000008 let l:job_type = getbufvar(a:buffer, 'ale_job_type', 'all')
3 0.000079 0.000052 call ale#command#InitData(a:buffer)
3 0.000028 let s:buffer_data[a:buffer].jobs[l:job_id] = l:job_type
3 0.000001 endif
3 0.000002 if g:ale_history_enabled
3 0.000071 0.000012 call ale#history#Add(a:buffer, l:status, l:job_id, l:command)
3 0.000001 endif
3 0.000001 if !l:job_id
return 0
3 0.000000 endif
" We'll return this Dictionary. A `result_callback` can be assigned to it
" later for capturing the result of a:Callback.
"
" The `_deferred_job_id` is used for both checking the type of object, and
" for checking the job ID and status.
"
" The cwd is kept and used as the default value for the next command in
" the chain.
"
" The original command here is used in tests.
3 0.000017 let l:result = { '_deferred_job_id': l:job_id, 'executable': get(l:options, 'executable', ''), 'cwd': l:cwd, 'command': a:command,}
3 0.000004 if get(g:, 'ale_run_synchronously') == 1 && l:job_id
if !exists('g:ale_run_synchronously_callbacks')
let g:ale_run_synchronously_callbacks = []
endif
if get(g:, 'ale_run_synchronously_emulate_commands', 0)
call add( g:ale_run_synchronously_callbacks, {exit_code, output -> [ extend(l:line_list, output), l:job_options.exit_cb(l:job_id, exit_code), ]})
else
" Run a command synchronously if this test option is set.
call extend(l:line_list, systemlist( type(l:command) is v:t_list ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2]) : l:command))
" Don't capture output when the callbacks aren't set.
if !has_key(l:job_options, 'out_cb')&& !has_key(l:job_options, 'err_cb')
let l:line_list = []
endif
call add( g:ale_run_synchronously_callbacks, {-> l:job_options.exit_cb(l:job_id, v:shell_error)})
endif
3 0.000000 endif
3 0.000002 return l:result
FUNCTION go#auto#update_autocmd()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/auto.vim:86
Called 2 times
Total time: 0.000052
Self time: 0.000045
count total (s) self (s)
2 0.000004 let has_timer = get(b:, 'has_timer')
2 0.000043 0.000036 let should_enable = go#config#AutoTypeInfo() || go#config#AutoSameids()
2 0.000003 if (!has_timer && !should_enable) || (has_timer && should_enable)
2 0.000001 return
endif
if has_timer
augroup vim-go-buffer-auto
autocmd! * <buffer>
augroup END
let b:has_timer = 0
call s:timer_stop()
return
endif
augroup vim-go-buffer-auto
autocmd! * <buffer>
autocmd CursorMoved <buffer> call s:timer_restart()
autocmd BufLeave <buffer> call s:timer_stop()
augroup END
let b:has_timer = 1
call s:timer_start()
FUNCTION ale#events#FileTypeEvent()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/events.vim:69
Called 1 time
Total time: 0.000011
Self time: 0.000011
count total (s) self (s)
" The old filetype will be set to an empty string by the BuFEnter event,
" and not linting when the old filetype hasn't been set yet prevents
" buffers being checked when you enter them when linting on enter is off.
1 0.000003 let l:old_filetype = getbufvar(a:buffer, 'ale_original_filetype', v:null)
1 0.000002 if l:old_filetype isnot v:null&& !empty(a:new_filetype)&& a:new_filetype isnot# l:old_filetype
" Remember what the new filetype is.
call setbufvar(a:buffer, 'ale_original_filetype', a:new_filetype)
if g:ale_lint_on_filetype_changed
call ale#Queue(300, 'lint_file', a:buffer)
endif
1 0.000000 endif
FUNCTION <SNR>180_WinFindBuf()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/list.vim:86
Called 3 times
Total time: 0.000014
Self time: 0.000014
count total (s) self (s)
3 0.000013 return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0]
FUNCTION ale#command#IsDeferred()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/command.vim:471
Called 16 times
Total time: 0.000040
Self time: 0.000040
count total (s) self (s)
16 0.000036 return type(a:value) is v:t_dict && has_key(a:value, '_deferred_job_id')
FUNCTION <lambda>343()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/ale_linters/go/gopls.vim:29
Called 1 time
Total time: 0.000007
Self time: 0.000002
count total (s) self (s)
return ale#Var(b, 'go_gopls_init_options')
FUNCTION ale#path#IsAbsolute()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/path.vim:117
Called 1 time
Total time: 0.000005
Self time: 0.000005
count total (s) self (s)
1 0.000002 if has('win32') && a:filename[:0] is# '\'
return 1
1 0.000000 endif
" Check for /foo and C:\foo, etc.
1 0.000001 return a:filename[:0] is# '/' || a:filename[1:2] is# ':\'
FUNCTION ale#linter#GetExecutable()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/linter.vim:424
Called 4 times
Total time: 0.000142
Self time: 0.000040
count total (s) self (s)
4 0.000012 let l:Executable = a:linter.executable
4 0.000123 0.000021 return type(l:Executable) is v:t_func ? l:Executable(a:buffer) : l:Executable
FUNCTION <SNR>181_matchaddpos()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/highlight.vim:89
Called 56 times
Total time: 0.003452
Self time: 0.002579
count total (s) self (s)
56 0.000042 if s:has_nvim_highlight
112 0.000124 for l:pos in a:pos_list
56 0.000137 let l:line = type(l:pos) == v:t_number ? l:pos - 1 : l:pos[0] - 1
56 0.000094 if type(l:pos) == v:t_number || len(l:pos) == 1
let l:col_start = 0
let l:col_end = s:MAX_COL_SIZE
56 0.000031 else
56 0.000090 let l:col_start = l:pos[1] - 1
56 0.000096 let l:col_end = l:col_start + get(l:pos, 2, 1)
56 0.000015 endif
56 0.001893 0.001020 call ale#highlight#nvim_buf_add_highlight( bufnr(''), s:ns_id, a:group, l:line, l:col_start, l:col_end,)
112 0.000062 endfor
else
call matchaddpos(a:group, a:pos_list)
56 0.000014 endif
FUNCTION ale#lsp_window#HandleShowMessage()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp_window.vim:26
Called 2 times
Total time: 0.000022
Self time: 0.000022
count total (s) self (s)
2 0.000003 let l:message = a:params.message
2 0.000002 let l:type = a:params.type
" Get the configured severity level threshold and check if the message
" should be displayed or not
2 0.000007 let l:configured_severity = tolower(get(g:, 'ale_lsp_show_message_severity', 'error'))
" If the user has configured with a value we can't find on the conversion
" dict, fall back to warning
2 0.000005 let l:cfg_severity_threshold = get(s:CFG_TO_LSP_SEVERITY, l:configured_severity, s:LSP_MESSAGE_TYPE_WARNING)
2 0.000002 if l:type > l:cfg_severity_threshold
2 0.000001 return
endif
" Severity will depend on the message type
if l:type is# s:LSP_MESSAGE_TYPE_ERROR
let l:severity = g:ale_echo_msg_error_str
elseif l:type is# s:LSP_MESSAGE_TYPE_INFORMATION
let l:severity = g:ale_echo_msg_info_str
elseif l:type is# s:LSP_MESSAGE_TYPE_LOG
let l:severity = g:ale_echo_msg_log_str
else
" Default to warning just in case
let l:severity = g:ale_echo_msg_warning_str
endif
let l:string = substitute(a:format, '\V%severity%', l:severity, 'g')
let l:string = substitute(l:string, '\V%linter%', a:linter_name, 'g')
let l:string = substitute(l:string, '\V%s\>', l:message, 'g')
call ale#util#ShowMessage(l:string)
FUNCTION <SNR>165_StopCurrentJobs()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:449
Called 1 time
Total time: 0.000035
Self time: 0.000018
count total (s) self (s)
1 0.000002 let l:info = get(g:ale_buffer_info, a:buffer, {})
1 0.000015 0.000005 call ale#command#StopJobs(a:buffer, 'linter')
" Update the active linter list, clearing out anything not running.
1 0.000001 if a:clear_lint_file_jobs
1 0.000010 0.000003 call ale#command#StopJobs(a:buffer, 'file_linter')
1 0.000001 let l:info.active_linter_list = []
else
let l:lint_file_map = {}
" Use a previously computed map of `lint_file` values to find
" linters that are used for linting files.
for [l:lint_file, l:linter] in a:linter_slots
if l:lint_file is 1
let l:lint_file_map[l:linter.name] = 1
endif
endfor
" Keep jobs for linting files when we're only linting buffers.
call filter(l:info.active_linter_list, 'get(l:lint_file_map, v:val.name)')
1 0.000000 endif
FUNCTION <SNR>146_workspaceFolder()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/lsp/message.vim:402
Called 2 times
Total time: 0.001138
Self time: 0.000010
count total (s) self (s)
2 0.001138 0.000009 return {'uri': go#path#ToURI(a:val), 'name': a:val}
FUNCTION <SNR>60_SynSet()
Defined: /opt/homebrew/Cellar/neovim/0.5.1_1/share/nvim/runtime/syntax/synload.vim:33
Called 1 time
Total time: 0.005070
Self time: 0.003307
count total (s) self (s)
" clear syntax for :set syntax=OFF and any syntax name that doesn't exist
1 0.000003 syn clear
1 0.000001 if exists("b:current_syntax")
unlet b:current_syntax
1 0.000000 endif
1 0.000001 let s = expand("<amatch>")
1 0.000001 if s == "ON"
" :set syntax=ON
if &filetype == ""
echohl ErrorMsg
echo "filetype unknown"
echohl None
endif
let s = &filetype
1 0.000001 elseif s == "OFF"
let s = ""
1 0.000000 endif
1 0.000000 if s != ""
" Load the syntax file(s). When there are several, separated by dots,
" load each in sequence. Skip empty entries.
2 0.000003 for name in split(s, '\.')
1 0.000001 if !empty(name)
1 0.003962 0.002199 exe "runtime! syntax/" . name . ".vim syntax/" . name . "/*.vim"
1 0.001086 exe "runtime! syntax/" . name . ".lua syntax/" . name . "/*.lua"
1 0.000001 endif
2 0.000001 endfor
1 0.000000 endif
FUNCTION ale#util#LocItemCompareWithText()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/util.vim:208
Called 252 times
Total time: 0.010661
Self time: 0.005394
count total (s) self (s)
252 0.010075 0.004808 let l:cmp_value = ale#util#LocItemCompare(a:left, a:right)
252 0.000140 if l:cmp_value
201 0.000086 return l:cmp_value
51 0.000011 endif
51 0.000060 if a:left.text < a:right.text
51 0.000021 return -1
endif
if a:left.text > a:right.text
return 1
endif
return 0
FUNCTION AutoPairsInit()
Defined: ~/.local/share/nvim/site/pack/packer/start/auto-pairs/plugin/auto-pairs.vim:471
Called 1 time
Total time: 0.000730
Self time: 0.000533
count total (s) self (s)
1 0.000005 let b:autopairs_loaded = 1
1 0.000001 if !exists('b:autopairs_enabled')
1 0.000001 let b:autopairs_enabled = 1
1 0.000000 end
1 0.000001 if !exists('b:AutoPairs')
1 0.000085 0.000034 let b:AutoPairs = AutoPairsDefaultPairs()
1 0.000000 end
1 0.000001 if !exists('b:AutoPairsMoveCharacter')
1 0.000001 let b:AutoPairsMoveCharacter = g:AutoPairsMoveCharacter
1 0.000000 end
1 0.000009 let b:autopairs_return_pos = 0
1 0.000001 let b:autopairs_saved_pair = [0, 0]
1 0.000001 let b:AutoPairsList = []
" buffer level map pairs keys
" n - do not map the first charactor of closed pair to close key
" m - close key jumps through multi line
" s - close key jumps only in the same line
10 0.000009 for [open, close] in items(b:AutoPairs)
9 0.000006 let o = open[-1:-1]
9 0.000005 let c = close[0]
9 0.000009 let opt = {'mapclose': 1, 'multiline':1}
9 0.000006 let opt['key'] = c
9 0.000004 if o == c
6 0.000004 let opt['multiline'] = 0
9 0.000002 end
9 0.000040 let m = matchlist(close, '\v(.*)//(.*)$')
9 0.000006 if len(m) > 0
if m[2] =~ 'n'
let opt['mapclose'] = 0
end
if m[2] =~ 'm'
let opt['multiline'] = 1
end
if m[2] =~ 's'
let opt['multiline'] = 0
end
let ks = matchlist(m[2], '\vk(.)')
if len(ks) > 0
let opt['key'] = ks[1]
let c = opt['key']
end
let close = m[1]
9 0.000002 end
9 0.000098 0.000020 call AutoPairsMap(o)
9 0.000008 if o != c && c != '' && opt['mapclose']
3 0.000026 0.000006 call AutoPairsMap(c)
9 0.000002 end
9 0.000011 let b:AutoPairsList += [[open, close, opt]]
10 0.000003 endfor
" sort pairs by length, longer pair should have higher priority
1 0.000177 0.000129 let b:AutoPairsList = sort(b:AutoPairsList, "s:sortByLength")
10 0.000004 for item in b:AutoPairsList
9 0.000006 let [open, close, opt] = item
9 0.000006 if open == "'" && open == close
1 0.000001 let item[0] = '\v(^|\W)\zs'''
9 0.000001 end
10 0.000002 endfor
9 0.000010 for key in split(b:AutoPairsMoveCharacter, '\s*')
8 0.000013 let escaped_key = substitute(key, "'", "''", 'g')
8 0.000035 execute 'inoremap <silent> <buffer> <M-'.key."> <C-R>=AutoPairsMoveCharacter('".escaped_key."')<CR>"
9 0.000002 endfor
" Still use <buffer> level mapping for <BS> <SPACE>
1 0.000001 if g:AutoPairsMapBS
" Use <C-R> instead of <expr> for issue #14 sometimes press BS output strange words
1 0.000005 execute 'inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>'
1 0.000000 end
1 0.000000 if g:AutoPairsMapCh
1 0.000003 execute 'inoremap <buffer> <silent> <C-h> <C-R>=AutoPairsDelete()<CR>'
1 0.000000 endif
1 0.000001 if g:AutoPairsMapSpace
" Try to respect abbreviations on a <SPACE>
1 0.000001 let do_abbrev = ""
1 0.000001 if v:version == 703 && has("patch489") || v:version > 703
1 0.000001 let do_abbrev = "<C-]>"
1 0.000000 endif
1 0.000004 execute 'inoremap <buffer> <silent> <SPACE> '.do_abbrev.'<C-R>=AutoPairsSpace()<CR>'
1 0.000000 end
1 0.000001 if g:AutoPairsShortcutFastWrap != ''
1 0.000004 execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutFastWrap.' <C-R>=AutoPairsFastWrap()<CR>'
1 0.000000 end
1 0.000001 if g:AutoPairsShortcutBackInsert != ''
1 0.000004 execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutBackInsert.' <C-R>=AutoPairsBackInsert()<CR>'
1 0.000000 end
1 0.000001 if g:AutoPairsShortcutToggle != ''
" use <expr> to ensure showing the status when toggle
1 0.000004 execute 'inoremap <buffer> <silent> <expr> '.g:AutoPairsShortcutToggle.' AutoPairsToggle()'
1 0.000005 execute 'noremap <buffer> <silent> '.g:AutoPairsShortcutToggle.' :call AutoPairsToggle()<CR>'
1 0.000000 end
1 0.000001 if g:AutoPairsShortcutJump != ''
1 0.000004 execute 'inoremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' <ESC>:call AutoPairsJump()<CR>a'
1 0.000004 execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
1 0.000000 end
1 0.000001 if &keymap != ''
let l:imsearch = &imsearch
let l:iminsert = &iminsert
let l:imdisable = &imdisable
execute 'setlocal keymap=' . &keymap
execute 'setlocal imsearch=' . l:imsearch
execute 'setlocal iminsert=' . l:iminsert
if l:imdisable
execute 'setlocal imdisable'
else
execute 'setlocal noimdisable'
end
1 0.000000 end
FUNCTION ale#sign#SetUpDefaultColumnWithoutErrorsHighlight()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:52
Called 1 time
Total time: 0.000135
Self time: 0.000120
count total (s) self (s)
1 0.000010 let l:verbose = &verbose
1 0.000027 0.000013 set verbose=0
1 0.000021 let l:output = execute('highlight SignColumn', 'silent')
1 0.000004 0.000002 let &verbose = l:verbose
1 0.000017 let l:highlight_syntax = join(split(l:output)[2:])
1 0.000004 let l:match = matchlist(l:highlight_syntax, '\vlinks to (.+)$')
1 0.000001 if !empty(l:match)
execute 'highlight link ALESignColumnWithoutErrors ' . l:match[1]
1 0.000002 elseif l:highlight_syntax isnot# 'cleared'
1 0.000021 execute 'highlight ALESignColumnWithoutErrors ' . l:highlight_syntax
1 0.000000 endif
FUNCTION <SNR>179_PriorityCmd()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/sign.vim:154
Called 22 times
Total time: 0.000037
Self time: 0.000037
count total (s) self (s)
22 0.000010 if s:supports_sign_groups
22 0.000021 return ' priority=' . g:ale_sign_priority . ' '
else
return ''
endif
FUNCTION <SNR>118_ResetConcealOption()
Defined: ~/.local/share/nvim/site/pack/packer/start/indentLine/after/plugin/indentLine.vim:110
Called 1 time
Total time: 0.000006
Self time: 0.000006
count total (s) self (s)
1 0.000001 if exists("b:indentLine_ConcealOptionSet") && b:indentLine_ConcealOptionSet
if exists("b:indentLine_original_concealcursor")
let &l:concealcursor = b:indentLine_original_concealcursor
endif
if exists("b:indentLine_original_conceallevel")
let &l:conceallevel = b:indentLine_original_conceallevel
endif
let b:indentLine_ConcealOptionSet = 0
1 0.000000 endif
FUNCTION <SNR>126_GetAliasedFiletype()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/linter.vim:294
Called 1 time
Total time: 0.000018
Self time: 0.000018
count total (s) self (s)
1 0.000002 let l:buffer_aliases = get(b:, 'ale_linter_aliases', {})
" b:ale_linter_aliases can be set to a List or String.
1 0.000002 if type(l:buffer_aliases) is v:t_list|| type(l:buffer_aliases) is v:t_string
return l:buffer_aliases
1 0.000000 endif
" Check for aliased filetypes first in a buffer variable,
" then the global variable,
" then in the default mapping,
" otherwise use the original filetype.
4 0.000003 for l:dict in [ l:buffer_aliases, g:ale_linter_aliases, s:default_ale_linter_aliases,]
3 0.000003 if has_key(l:dict, a:original_filetype)
return l:dict[a:original_filetype]
3 0.000001 endif
4 0.000001 endfor
1 0.000001 return a:original_filetype
FUNCTION ale#Queue()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale.vim:123
Called 1 time
Total time: 0.049362
Self time: 0.000042
count total (s) self (s)
1 0.000001 if a:0 > 2
throw 'too many arguments!'
1 0.000000 endif
1 0.000002 let l:buffer = get(a:000, 1, v:null)
1 0.000001 if l:buffer is v:null
let l:buffer = bufnr('')
1 0.000000 endif
1 0.000001 if type(l:buffer) isnot v:t_number
throw 'buffer_number must be a Number'
1 0.000000 endif
1 0.000055 0.000003 if ale#ShouldDoNothing(l:buffer)
return
1 0.000000 endif
" Default linting_flag to ''
1 0.000001 let l:should_lint_file = get(a:000, 0) is# 'lint_file'
1 0.000001 if s:lint_timer != -1
1 0.000001 call timer_stop(s:lint_timer)
1 0.000001 let s:lint_timer = -1
1 0.000000 endif
1 0.000000 if a:delay > 0
let s:lint_timer = timer_start( a:delay, function('s:Lint', [l:buffer, l:should_lint_file]))
1 0.000000 else
1 0.049287 0.000019 call s:Lint(l:buffer, l:should_lint_file, 0)
1 0.000000 endif
FUNCTION <SNR>148_clear()
Defined: ~/.local/share/nvim/site/pack/packer/start/vim-go/autoload/go/statusline.vim:100
Called 2 times
Total time: 0.000076
Self time: 0.000074
count total (s) self (s)
4 0.000006 for [status_dir, status] in items(s:statuses)
2 0.000008 let elapsed_time = reltimestr(reltime(status.created_at))
" strip whitespace
2 0.000018 let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
2 0.000003 if str2nr(elapsed_time) > 10
call remove(s:statuses, status_dir)
2 0.000001 endif
4 0.000002 endfor
2 0.000002 if len(s:statuses) == 0
let s:statuses = {}
2 0.000001 endif
" force to update the statusline, otherwise the user needs to move the
" cursor
2 0.000010 0.000008 exe 'let &ro = &ro'
FUNCTION <SNR>128_project_name()
Defined: ~/.local/share/nvim/site/pack/packer/start/dashboard-nvim/autoload/sessions/session.vim:48
Called 1 time
Total time: 0.001644
Self time: 0.001644
count total (s) self (s)
1 0.000907 let l:cwd = resolve(getcwd())
1 0.000046 let l:cwd = substitute(l:cwd, '^'.$HOME.'/', '', '')
1 0.000675 let l:cwd = fnamemodify(l:cwd, ':p:gs?/?_?')
1 0.000010 let l:cwd = substitute(l:cwd, '^\.', '', '')
1 0.000004 return l:cwd
FUNCTION ale#lsp#message#DidOpen()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/lsp/message.vim:54
Called 1 time
Total time: 0.000423
Self time: 0.000387
count total (s) self (s)
1 0.000039 let l:lines = getbufline(a:buffer, 1, '$')
1 0.000384 0.000348 return [1, 'textDocument/didOpen', { 'textDocument': { 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')), 'languageId': a:language_id, 'version': ale#lsp#message#GetNextVersionID(), 'text': join(l:lines, "\n") . "\n", },}]
FUNCTION <SNR>165_HandleExit()
Defined: ~/.local/share/nvim/site/pack/packer/start/ale/autoload/ale/engine.vim:151
Called 3 times
Total time: 0.041664
Self time: 0.003776
count total (s) self (s)
3 0.000009 let l:buffer_info = get(g:ale_buffer_info, a:buffer)
3 0.000004 if empty(l:buffer_info)
return
3 0.000001 e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment