From 7432be95329c0fe1ed531c75acb672be4646e835 Mon Sep 17 00:00:00 2001 From: dsych Date: Wed, 9 Dec 2020 23:19:32 -0500 Subject: [PATCH] implemented dynamic float windows for nvim --- autoload/vimspector/internal/state.vim | 27 ++++++---- python3/vimspector/variables.py | 74 +++++++++++++------------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/autoload/vimspector/internal/state.vim b/autoload/vimspector/internal/state.vim index 6d3aad4..b80a4b7 100644 --- a/autoload/vimspector/internal/state.vim +++ b/autoload/vimspector/internal/state.vim @@ -47,19 +47,24 @@ function! vimspector#internal#state#GetAPIPrefix() abort return s:prefix endfunction -" REMOVEME: this is just a temporary thing to get float window working -" Returns: py.ShowBalloon( winnr, expresssion ) -function! vimspector#internal#state#Tooltip() abort - " winnr + 1 because for *no good reason* winnr is 0 based here unlike - " everywhere else - " int() because for *no good reason* winnr is a string. - return py3eval('_vimspector_session.ShowTooltip(' - \ . 'int( vim.eval( "winnr()" ) ) ,' - \ . 'vim.eval( "expand(\"\")" ) )' ) -endfunction - function! vimspector#internal#state#CreateTooltip() abort + let buf = nvim_create_buf(v:false, v:true) + call nvim_buf_set_lines(buf, 0, -1, v:true, []) + " default the dimensions for now. they can be easily overwritten later + let opts = { 'relative': 'cursor', 'width': 50, 'height': 2, 'col': 0, 'row': 1, 'anchor': 'NW', 'style': 'minimal' } + let g:float_win = nvim_open_win(buf, 0, opts) + call setwinvar(g:float_win, '&wrap', 0) + + call win_gotoid(g:float_win) + + " make sure we clean up the float after it loses focus + augroup vimspector#internal#balloon#nvim_float + autocmd! + autocmd WinLeave * :call nvim_win_close(g:float_win, 1) | autocmd! vimspector#internal#balloon#nvim_float + augroup END + + return g:float_win endfunction function! vimspector#internal#state#ShowTooltip() abort diff --git a/python3/vimspector/variables.py b/python3/vimspector/variables.py index ec18a71..7019168 100644 --- a/python3/vimspector/variables.py +++ b/python3/vimspector/variables.py @@ -139,6 +139,8 @@ class VariablesView( object ): self._current_syntax = '' self._variable_eval = None + self._variable_eval_view = None + self._variable_eval_win = None def AddExpandMappings(): vim.command( 'nnoremap ' @@ -270,25 +272,12 @@ class VariablesView( object ): } ) def _DrawEval(self): - # TODO: create vim functin that creates a floating window and returns window id - # use that window id to retrieve the buffer - # use that buffer in order to populate the results of the query - indent = 0 - icon = '+' if self._variable_eval.IsExpandable() and not self._variable_eval.IsExpanded() else '-' + self._variable_eval_win.height = min(5, len(self._variable_eval.variables)) + with utils.RestoreCursorPosition(): + utils.ClearBuffer( self._variable_eval_view.buf ) + icon = '+' if self._variable_eval.IsExpandable() and not self._variable_eval.IsExpanded() else '-' - line = utils.AppendToBuffer( self._vars.buf, - '{0}{1} Scope: {2}'.format( - ' ' * indent, - icon, - self._variable_eval.scope[ 'name' ] ) ) - self._vars.lines[ line ] = self._variable_eval - - if self._variable_eval.ShouldDrawDrillDown(): - indent += 2 - # replace with a newly created view for the purposes of evaluation - self._DrawVariables( self._vars, self._variable_eval.variables, indent ) - - # vim.eval("vimspector#internal#state#TooltipExec({})".format([self._variable_eval])) + self._DrawVariables( self._variable_eval_view, self._variable_eval.variables, 2 ) def VariableEval(self, frame, expression): @@ -297,28 +286,38 @@ class VariablesView( object ): return '' def handler( message ): - # TODO: this result count be expandable, but we have no way to allow the - # user to interact with the balloon to expand it, unless we use a popup - # instead, but even then we don't really want to trap the cursor. body = message[ 'body' ] - result = body[ 'result' ] - if result is None: - result = 'null' - display = [ - 'Type: ' + body.get( 'type', '' ), - 'Value: ' + result - ] self._variable_eval = Scope(body) - self._connection.DoRequest( partial( self._ConsumeVariables, - self._DrawEval, - self._variable_eval ), { - 'command': 'variables', - 'arguments': { - 'variablesReference': self._variable_eval.VariablesReference(), - }, - } ) + float_win_id = vim.eval("vimspector#internal#state#CreateTooltip()") + self._variable_eval_win = vim.current.window + + with utils.LetCurrentWindow( self._variable_eval_win ): + vim.command( 'nnoremap ' + ':call vimspector#ExpandVariable()' ) + vim.command( 'nnoremap ' + ':quit' ) + vim.command( 'nnoremap <2-LeftMouse> ' + ':call vimspector#ExpandVariable()' ) + + + if(self._variable_eval.VariablesReference() > 0): + self._variable_eval_view = View(self._variable_eval_win, {}, self._DrawEval) + self._connection.DoRequest( partial( self._ConsumeVariables, + self._DrawEval, + self._variable_eval ), { + 'command': 'variables', + 'arguments': { + 'variablesReference': self._variable_eval.VariablesReference(), + }, + } ) + else: + # in case that there is nothing to expand, we need to simulate a response from 'variables' request + # it returns [Variable] + self._variable_eval_view = View(self._variable_eval_win, {}, self._DrawEval) + self._variable_eval.variables = [Variable({'name': expression, 'value': body['result']})] + self._DrawEval() def failure_handler( reason, message ): @@ -414,6 +413,8 @@ class VariablesView( object ): view = self._vars elif vim.current.buffer == self._watch.buf: view = self._watch + elif vim.current.buffer == self._variable_eval_view.buf: + view = self._variable_eval_view else: return @@ -542,7 +543,6 @@ class VariablesView( object ): variable = v found = True break - if not found: variable = Variable( variable_body ) else: