From e684fdffd951215dd80e16eb625f01d802548e64 Mon Sep 17 00:00:00 2001 From: Ingo Heimbach Date: Fri, 6 Jan 2017 23:01:30 +0100 Subject: [PATCH 1/2] Use vim 8 timers for continuous checking of debugger output --- autoload/vebugger.vim | 44 ++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/autoload/vebugger.vim b/autoload/vebugger.vim index bc863df..1c3871a 100644 --- a/autoload/vebugger.vim +++ b/autoload/vebugger.vim @@ -17,7 +17,9 @@ function! s:f_debugger.kill() dict if self.shell.is_valid call self.addLineToTerminal('','== DEBUGGER TERMINATED ==') endif - let &updatetime=self.prevUpdateTime + if !has('timers') + let &updatetime=self.prevUpdateTime + endif call self.shell.kill(15) if exists('s:debugger') for l:closeHandler in s:debugger.closeHandlers @@ -54,7 +56,9 @@ function! s:f_debugger.invokeReading() dict \|| 'error'==l:checkpid[0] call self.kill() endif - call feedkeys("f\e", '\n') " Make sure the CursorHold event is refired even if the user does nothing + if !has('timers') + call feedkeys("f\e", '\n') " Make sure the CursorHold event is refired even if the user does nothing + endif endfunction "Handle a single line from the debugger's interactive shell @@ -262,12 +266,19 @@ function! vebugger#createDebugger(command) let l:debugger.writeHandlers={} let l:debugger.closeHandlers=[] - let l:debugger.prevUpdateTime=&updatetime + if !has('timers') + let l:debugger.prevUpdateTime=&updatetime + set updatetime=500 + endif - set updatetime=500 return l:debugger endfunction +if has('timers') + function! s:readingTimerCallback(timerId) + call s:debugger.invokeReading() + endfunction +endif "Create a debugger and set it as the currently active debugger function! vebugger#startDebugger(command) @@ -275,19 +286,30 @@ function! vebugger#startDebugger(command) let s:debugger=vebugger#createDebugger(a:command) - augroup vebugger_shell - autocmd! - autocmd CursorHold * call s:debugger.invokeReading() - augroup END + if has('timers') + let s:timerId = timer_start(500, function('s:readingTimerCallback'), {'repeat': -1}) + else + augroup vebugger_shell + autocmd! + autocmd CursorHold * call s:debugger.invokeReading() + augroup END + endif return s:debugger endfunction "Terminate the currently active debugger function! vebugger#killDebugger() - augroup vebugger_shell - autocmd! - augroup END + if has('timers') + if exists('s:timerId') + call timer_stop(s:timerId) + unlet s:timerId + endif + else + augroup vebugger_shell + autocmd! + augroup END + endif if exists('s:debugger') call vebugger#std#closeShellBuffer(s:debugger) call s:debugger.closeTerminalBuffer() From a2e2dcd612621c3b35dc2f0fb6d4b9c8f60acd16 Mon Sep 17 00:00:00 2001 From: Ingo Heimbach Date: Sun, 22 Jan 2017 12:39:06 +0100 Subject: [PATCH 2/2] Use feedkeys for echoing evaluated expressions Echo commands in vim 8 timer handlers do not wait for the user to confirm. Echoing via feedkeys circumvents this problem. --- autoload/vebugger/std.vim | 42 ++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/autoload/vebugger/std.vim b/autoload/vebugger/std.vim index a3273ed..284bb7a 100644 --- a/autoload/vebugger/std.vim +++ b/autoload/vebugger/std.vim @@ -226,20 +226,52 @@ function! s:standardThinkHandlers.updateCallStack(readResult,debugger) dict endif endfunction +"Helper print function; when using vim timers feedkeys ensures that messages +"can be confirmend by the user. +function! s:printWithFeedKeys(evaluatedExpression) + if empty(get(a:evaluatedExpression,'expression')) + let l:echo = a:evaluatedExpression.value + else + let l:echo = a:evaluatedExpression.expression.': '.a:evaluatedExpression.value + endif + let l:echoLines = split(l:echo, '\r\n\|\n\|\r') + if len(l:echoLines) == 1 + call add(l:echoLines, '') + endif + + if has('timers') + " Convert to an expression we can use with feedkeys. + " string(l:echo) won't do because it uses single-quotes which + " do not escape newlines + let l:echoJoinExpr = 'join('.string(l:echoLines).', "\n")' + + let l:echoKeys = ':echo '.l:echoJoinExpr."\" + if mode() == 'n' + " Call echo normaly + call feedkeys(l:echoKeys) + elseif mode() == 'i' + " Execute command in insert mode + call feedkeys("\".l:echoKeys) + endif + " NOTE: Other modes are not supported + else + " Without timer support, feedkeys won't work and we have + " to echo directly + echo join(l:echoLines, "\n") + endif +endfunction + "Print an expression that it's evaluation was previously requested function! s:standardThinkHandlers.printEvaluatedExpression(readResult,debugger) dict let l:evaluatedExpression=a:readResult.std.evaluatedExpression if !empty(l:evaluatedExpression) - if empty(get(l:evaluatedExpression,'expression')) - echo l:evaluatedExpression.value."\n" - else + if !empty(get(l:evaluatedExpression,'expression')) let l:index=index(a:debugger.state.std.evaluateExpressions,l:evaluatedExpression.expression) if 0<=l:index call remove(a:debugger.state.std.evaluateExpressions,l:index) - echo l:evaluatedExpression.expression.': '.l:evaluatedExpression.value."\n" - let g:echo=l:evaluatedExpression.expression.': '.l:evaluatedExpression.value."\n" endif endif + call s:printWithFeedKeys(l:evaluatedExpression) call a:debugger.addWriteAction('std','removeAfterDisplayed',a:readResult) endif endfunction