patch 9.1.0817: termdebug: cannot evaluate expr in a popup
Problem: termdebug: cannot evaluate expr in a popup
Solution: enhance termdebug plugin and allow to evaluate expressions in
a popup window, add a unit test (Peter Wolf).
fixes: #15877
closes: #15933
Signed-off-by: Peter Wolf <pwolf2310@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 0c1b31a..75359f2 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -10664,6 +10664,7 @@
termdebug-timeout terminal.txt /*termdebug-timeout*
termdebug-variables terminal.txt /*termdebug-variables*
termdebug_disasm_window terminal.txt /*termdebug_disasm_window*
+termdebug_evaluate_in_popup terminal.txt /*termdebug_evaluate_in_popup*
termdebug_map_K terminal.txt /*termdebug_map_K*
termdebug_map_minus terminal.txt /*termdebug_map_minus*
termdebug_map_plus terminal.txt /*termdebug_map_plus*
diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt
index 5020ed5..6b53e02 100644
--- a/runtime/doc/terminal.txt
+++ b/runtime/doc/terminal.txt
@@ -1,4 +1,4 @@
-*terminal.txt* For Vim version 9.1. Last change: 2024 Jul 28
+*terminal.txt* For Vim version 9.1. Last change: 2024 Oct 27
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1537,6 +1537,7 @@
<
However, the latter form will be deprecated in future releases.
+
Mappings ~
The termdebug plugin enables a few default mappings. All those mappings
are reset to their original values once the termdebug session concludes.
@@ -1591,6 +1592,7 @@
and the Var window will be shown side by side with the source code window (and
the height options won't be used).
+
Communication ~
*termdebug-communication*
There is another, hidden, buffer, which is used for Vim to communicate with
@@ -1675,10 +1677,11 @@
However, the latter form will be deprecated in future releases.
+
Change default signs ~
*termdebug_signs*
Termdebug uses the hex number of the breakpoint ID in the signcolumn to
-represent breakpoints. if it is greater than "0xFF", then it will be displayed
+represent breakpoints. If it is greater than "0xFF", then it will be displayed
as "F+", due to we really only have two screen cells for the sign.
If you want to customize the breakpoint signs: >
@@ -1716,4 +1719,18 @@
'columns'. This is useful when the terminal can't be resized by Vim.
+Evaluate in Popup Window at Cursor ~
+ *termdebug_evaluate_in_popup*
+By default |:Evaluate| will simply echo its output. For larger entities this
+might become difficult to read or even truncated.
+Alternatively, the evaluation result may be output into a popup window at the
+current cursor position: >
+ let g:termdebug_config['evaluate_in_popup'] = v:true
+This can also be used in a "one-shot" manner: >
+ func OnCursorHold()
+ let g:termdebug_config['evaluate_in_popup'] = v:true
+ :Evaluate
+ let g:termdebug_config['evaluate_in_popup'] = v:false
+ endfunc
+<
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index 377827e..e7c010d 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -121,7 +121,9 @@
var BreakpointSigns: list<string>
var evalFromBalloonExpr: bool
-var evalFromBalloonExprResult: string
+var evalInPopup: bool
+var evalPopupId: number
+var evalExprResult: string
var ignoreEvalError: bool
var evalexpr: string
# Remember the old value of 'signcolumn' for each buffer that it's set in, so
@@ -202,7 +204,9 @@
BreakpointSigns = []
evalFromBalloonExpr = false
- evalFromBalloonExprResult = ''
+ evalInPopup = false
+ evalPopupId = -1
+ evalExprResult = ''
ignoreEvalError = false
evalexpr = ''
# Remember the old value of 'signcolumn' for each buffer that it's set in, so
@@ -1478,10 +1482,23 @@
evalexpr = exprLHS
enddef
+# Returns whether to evaluate in a popup or not, defaults to false.
+def EvaluateInPopup(): bool
+ if exists('g:termdebug_config')
+ return get(g:termdebug_config, 'evaluate_in_popup', false)
+ endif
+ return false
+enddef
+
# :Evaluate - evaluate what is specified / under the cursor
def Evaluate(range: number, arg: string)
var expr = GetEvaluationExpression(range, arg)
- echom $"expr: {expr}"
+ if EvaluateInPopup()
+ evalInPopup = true
+ evalExprResult = ''
+ else
+ echomsg $'expr: {expr}'
+ endif
ignoreEvalError = false
SendEval(expr)
enddef
@@ -1541,6 +1558,37 @@
endif
enddef
+def Popup_format(expr: string): list<string>
+ var lines = expr
+ ->substitute('{', '{\n', 'g')
+ ->substitute('}', '\n}', 'g')
+ ->substitute(',', ',\n', 'g')
+ ->split('\n')
+ var indentation = 0
+ var formatted_lines = []
+ for line in lines
+ var stripped = line->substitute('^\s\+', '', '')
+ if stripped =~ '^}'
+ indentation -= 2
+ endif
+ formatted_lines->add(repeat(' ', indentation) .. stripped)
+ if stripped =~ '{$'
+ indentation += 2
+ endif
+ endfor
+ return formatted_lines
+enddef
+
+def Popup_show(expr: string)
+ var formatted = Popup_format(expr)
+ if evalPopupId != -1
+ popup_close(evalPopupId)
+ endif
+ # Specifying the line is necessary, as the winbar seems to cause issues
+ # otherwise. I.e., the popup would be shown one line too high.
+ evalPopupId = popup_atcursor(formatted, {'line': 'cursor-1'})
+enddef
+
def HandleEvaluate(msg: string)
var value = msg
->substitute('.*value="\(.*\)"', '\1', '')
@@ -1555,13 +1603,12 @@
#\ ->substitute('\\0x00', NullRep, 'g')
#\ ->substitute('\\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. '"')}, 'g')
->substitute(NullRepl, '\\000', 'g')
- if evalFromBalloonExpr
- if empty(evalFromBalloonExprResult)
- evalFromBalloonExprResult = $'{evalexpr}: {value}'
+ if evalFromBalloonExpr || evalInPopup
+ if empty(evalExprResult)
+ evalExprResult = $'{evalexpr}: {value}'
else
- evalFromBalloonExprResult ..= $' = {value}'
+ evalExprResult ..= $' = {value}'
endif
- Balloon_show(evalFromBalloonExprResult)
else
echomsg $'"{evalexpr}": {value}'
endif
@@ -1570,8 +1617,12 @@
# Looks like a pointer, also display what it points to.
ignoreEvalError = true
SendEval($'*{evalexpr}')
- else
+ elseif evalFromBalloonExpr
+ Balloon_show(evalExprResult)
evalFromBalloonExpr = false
+ elseif evalInPopup
+ Popup_show(evalExprResult)
+ evalInPopup = false
endif
enddef
@@ -1588,7 +1639,7 @@
return ''
endif
evalFromBalloonExpr = true
- evalFromBalloonExprResult = ''
+ evalExprResult = ''
ignoreEvalError = true
var expr = CleanupExpr(v:beval_text)
SendEval(expr)