From cec9c74b79740f5e88300c02bf43a350d233eb8c Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Sun, 19 Nov 2023 10:58:03 -0800 Subject: [PATCH 1/2] config: add g:go_debug_log_delay Add an option to configure the timer delay when logging LSP messages. This is mostly useful when needing to get logs for an LSP operation when the behavior of the operation being debugged is sensitive to a window losing focus. --- autoload/go/config.vim | 4 ++++ autoload/go/lsp.vim | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/autoload/go/config.vim b/autoload/go/config.vim index ea51f0d78a..f0f13d56bb 100644 --- a/autoload/go/config.vim +++ b/autoload/go/config.vim @@ -200,6 +200,10 @@ function! go#config#Debug() abort return get(g:, 'go_debug', []) endfunction +function! go#config#DebugLogDelay() abort + return get(g:, 'go_debug_log_delay', 10) +endfunction + function! go#config#DebugWindows() abort return get(g:, 'go_debug_windows', { \ 'vars': 'leftabove 30vnew', diff --git a/autoload/go/lsp.vim b/autoload/go/lsp.vim index d747af38ae..294dced26a 100644 --- a/autoload/go/lsp.vim +++ b/autoload/go/lsp.vim @@ -1374,7 +1374,7 @@ function! s:debugasync(timer) abort " completion, because the window can not be changed while completion is in " progress. if len(s:log) != 0 - let s:logtimer = timer_start(10, function('s:debugasync', [])) + let s:logtimer = timer_start(go#config#DebugLogDelay(), function('s:debugasync', [])) endif endtry endfunction @@ -1384,7 +1384,7 @@ function! s:debug(event, data) abort let s:log = add(s:log, [a:event, a:data]) if l:shouldStart - let s:logtimer = timer_start(10, function('s:debugasync', [])) + let s:logtimer = timer_start(go#config#DebugLogDelay(), function('s:debugasync', [])) endif endfunction From b4560d406acb31682d4d033d01ff25e26f3ae092 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Sat, 23 Dec 2023 15:52:52 -0800 Subject: [PATCH 2/2] lsp: log more efficiently * Do not log when in visual mode, select mode, or while waiting on completion. This keeps the screen from being cleared or from generating an exception when logging would otherwise change to the log window to scroll. * Do not change to the log window merely to write to it. The only operation that is now required to change to the log window is to scroll it, so limit the time that it's the active window to that single operation. --- autoload/go/lsp.vim | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/autoload/go/lsp.vim b/autoload/go/lsp.vim index 294dced26a..e7a29f5554 100644 --- a/autoload/go/lsp.vim +++ b/autoload/go/lsp.vim @@ -1332,6 +1332,15 @@ let s:logtimer = 0 function! s:debugasync(timer) abort let s:logtimer = 0 + " set the timer to try again if Vim is in a state where we don't want to + " change the window. + let l:state = state('a') + let l:mode = mode(1) + if len(l:state) > 0 || l:mode[0] == 'v' || l:mode[0] == 'V' || l:mode[0] == 's' || l:mode =~ 'CTRL-V' + let s:logtimer = timer_start(go#config#DebugLogDelay(), function('s:debugasync', [])) + return + endif + if !go#util#HasDebug('lsp') let s:log = [] return @@ -1347,30 +1356,35 @@ function! s:debugasync(timer) abort 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) + call win_gotoid(l:winid) endif + let l:logwinid = bufwinid(l:name) + try - setlocal modifiable + call setbufvar(l:name, '&modifiable', 1) for [l:event, l:data] in s:log call remove(s:log, 0) - if getline(1) == '' - call setline('$', printf('===== %s =====', l:event)) + if getbufline(l:name, 1)[0] == '' + call setbufline(l:name, '$', printf('===== %s =====', l:event)) else - call append('$', printf('===== %s =====', l:event)) + call appendbufline(l:name, '$', printf('===== %s =====', l:event)) endif - call append('$', split(l:data, "\r\n")) + call appendbufline(l:name, '$', split(l:data, "\r\n")) endfor + + " TODO(bc): how to move the window's cursor position without switching + " to the window? + call win_gotoid(l:logwinid) normal! G - setlocal nomodifiable - finally call win_gotoid(l:winid) + call setbufvar(l:name, '&modifiable', 0) + finally endtry catch - call go#util#EchoError(v:exception) + call go#util#EchoError(printf('at %s: %s', v:throwpoint, v:exception)) finally - " retry in when there's an exception. This can happen when trying to do + " retry when there's an exception. This can happen when trying to do " completion, because the window can not be changed while completion is in " progress. if len(s:log) != 0