fully implemented the hover function for vim
This commit is contained in:
parent
4e994968ff
commit
819d6366ac
5 changed files with 112 additions and 129 deletions
|
|
@ -523,6 +523,10 @@ function! vimspector#OnBufferCreated( file_name ) abort
|
||||||
py3 _vimspector_session.RefreshSigns( vim.eval( 'a:file_name' ) )
|
py3 _vimspector_session.RefreshSigns( vim.eval( 'a:file_name' ) )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! vimspector#ShowTooltip() abort
|
||||||
|
return py3eval('_vimspector_session.ShowTooltip(int( vim.eval( "winnr()" ) ) ,vim.eval( "expand(\"<cexpr>\")" ) )')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
" Boilerplate {{{
|
" Boilerplate {{{
|
||||||
let &cpoptions=s:save_cpo
|
let &cpoptions=s:save_cpo
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,99 @@ function! vimspector#internal#balloon#Tooltip() abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
let s:float_win = 0
|
||||||
|
|
||||||
|
function! vimspector#internal#balloon#closeCallback() abort
|
||||||
|
let s:float_win = 0
|
||||||
|
return py3eval('_vimspector_session._CleanUpTooltip()')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! vimspector#internal#balloon#CreateTooltip() abort
|
||||||
|
if has('nvim')
|
||||||
|
let buf = nvim_create_buf(v:false, v:true)
|
||||||
|
" call nvim_buf_set_option(buf, 'modifiable', v:false)
|
||||||
|
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: 5,
|
||||||
|
\ col: 0,
|
||||||
|
\ row: 1,
|
||||||
|
\ anchor: 'NW',
|
||||||
|
\ style: 'minimal'
|
||||||
|
\ }
|
||||||
|
let s:float_win = nvim_open_win(buf, 0, opts)
|
||||||
|
call nvim_win_set_option(s:float_win, 'wrap', v:true)
|
||||||
|
call nvim_win_set_option(s:float_win, 'cursorline', v:true)
|
||||||
|
call nvim_win_set_option(s:float_win, 'signcolumn', 'no')
|
||||||
|
call nvim_win_set_option(s:float_win, 'relativenumber', v:false)
|
||||||
|
call nvim_win_set_option(s:float_win, 'number', v:false)
|
||||||
|
|
||||||
|
noa call win_gotoid(s:float_win)
|
||||||
|
|
||||||
|
nnoremap <silent> <buffer> <CR> :<C-u>call vimspector#ExpandVariable()<CR>
|
||||||
|
nnoremap <silent> <buffer> <esc> :quit<CR>
|
||||||
|
nnoremap <silent> <buffer> <2-LeftMouse>:<C-u>call vimspector#ExpandVariable()<CR>
|
||||||
|
|
||||||
|
" make sure we clean up the float after it loses focus
|
||||||
|
augroup vimspector#internal#balloon#nvim_float
|
||||||
|
autocmd!
|
||||||
|
autocmd WinLeave * :call nvim_win_close(s:float_win, 1) | :call vimspector#internal#balloon#closeCallback() | autocmd! vimspector#internal#balloon#nvim_float
|
||||||
|
augroup END
|
||||||
|
|
||||||
|
else
|
||||||
|
" assume we are inside vim
|
||||||
|
func! MyFilter(winid, key)
|
||||||
|
if index(['j', 'k'], a:key) >= 0
|
||||||
|
call win_execute(a:winid, ':normal '.a:key)
|
||||||
|
" do something
|
||||||
|
return 1
|
||||||
|
elseif a:key == "\<leftmouse>"
|
||||||
|
let mouse_coords = getmousepos()
|
||||||
|
" close the popup if mouse is clicked outside the window
|
||||||
|
if mouse_coords['winid'] != a:winid
|
||||||
|
call popup_close(a:winid)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call win_execute(a:winid, ":call cursor(".mouse_coords['line'].", ".mouse_coords['column'].")")
|
||||||
|
return 1
|
||||||
|
elseif a:key == "\<cr>"
|
||||||
|
" forward line number to python, since vim does not allow us to focus
|
||||||
|
" the correct window
|
||||||
|
call py3eval("_vimspector_session.ExpandVariable(".line('.', a:winid).")")
|
||||||
|
|
||||||
|
return 1
|
||||||
|
elseif a:key == "\<esc>"
|
||||||
|
call popup_close(a:winid)
|
||||||
|
call vimspector#internal#balloon#closeCallback()
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
return 0
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
if s:float_win != 0
|
||||||
|
call popup_close(s:float_win)
|
||||||
|
call vimspector#internal#balloon#closeCallback()
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:float_win = popup_create([], #{
|
||||||
|
\ filter: "MyFilter",
|
||||||
|
\ cursorline: 1,
|
||||||
|
\ wrap: 1,
|
||||||
|
\ filtermode: "n",
|
||||||
|
\ maxwidth: 50,
|
||||||
|
\ maxheight: 5,
|
||||||
|
\ scrollbar: 1,
|
||||||
|
\ moved: "any",
|
||||||
|
\ })
|
||||||
|
" call setbufvar(winbufnr(s:float_win), '&buflisted', 1)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
return s:float_win
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Boilerplate {{{
|
" Boilerplate {{{
|
||||||
let &cpoptions=s:save_cpo
|
let &cpoptions=s:save_cpo
|
||||||
|
|
|
||||||
|
|
@ -47,122 +47,6 @@ function! vimspector#internal#state#GetAPIPrefix() abort
|
||||||
return s:prefix
|
return s:prefix
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:float_win = 0
|
|
||||||
|
|
||||||
function! vimspector#internal#state#CreateTooltip() abort
|
|
||||||
if has('nvim')
|
|
||||||
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 s:float_win = nvim_open_win(buf, 0, opts)
|
|
||||||
call setwinvar(s:float_win, '&wrap', 1)
|
|
||||||
call setwinvar(s:float_win, '&cursorline', 1)
|
|
||||||
|
|
||||||
call win_gotoid(s:float_win)
|
|
||||||
|
|
||||||
nnoremap <silent> <buffer> <CR> :<C-u>call vimspector#ExpandVariable()<CR>
|
|
||||||
nnoremap <silent> <buffer> <esc>:quit<CR>
|
|
||||||
nnoremap <silent> <buffer> <2-LeftMouse>:<C-u>call vimspector#ExpandVariable()<CR>
|
|
||||||
|
|
||||||
" make sure we clean up the float after it loses focus
|
|
||||||
augroup vimspector#internal#balloon#nvim_float
|
|
||||||
autocmd!
|
|
||||||
autocmd WinLeave * :call nvim_win_close(s:float_win, 1) | autocmd! vimspector#internal#balloon#nvim_float
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
else
|
|
||||||
" assume we are inside vim
|
|
||||||
func! MyFilter(winid, key)
|
|
||||||
if index(['j', 'k', 'h', 'l'], a:key) >= 0
|
|
||||||
call win_execute(a:winid, ':normal '.a:key)
|
|
||||||
" do something
|
|
||||||
return 1
|
|
||||||
elseif a:key == "\<leftmouse>"
|
|
||||||
echo 'pressed left mouse'
|
|
||||||
let mouse_coords = getmousepos()
|
|
||||||
" close the popup if mouse is clicked outside the window
|
|
||||||
if mouse_coords['winid'] != a:winid
|
|
||||||
call popup_close(a:winid)
|
|
||||||
endif
|
|
||||||
|
|
||||||
echo 'clicked line '.mouse_coords['line']
|
|
||||||
call win_execute(a:winid, ":call cursor(".mouse_coords['line'].", ".mouse_coords['column'].")")
|
|
||||||
return 1
|
|
||||||
elseif a:key == "\<cr>"
|
|
||||||
echo 'pressed enter at line '.line(".", a:winid)
|
|
||||||
echo 'here'
|
|
||||||
call vimspector#ExpandVariable()
|
|
||||||
|
|
||||||
return 1
|
|
||||||
elseif a:key == "\<esc>"
|
|
||||||
call popup_close(a:winid)
|
|
||||||
let s:float_win = 0
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
return 0
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
if s:float_win != 0
|
|
||||||
popup_close(s:float_win)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let s:float_win = popup_create([], #{
|
|
||||||
\ filter: "MyFilter",
|
|
||||||
\ cursorline: 1,
|
|
||||||
\ wrap: 1,
|
|
||||||
\ filtermode: "n",
|
|
||||||
\ maxwidth: 50,
|
|
||||||
\ maxheight: 5,
|
|
||||||
\ scrollbar: 1,
|
|
||||||
\ moved: "any",
|
|
||||||
\ })
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
return s:float_win
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! vimspector#internal#state#ShowTooltip() abort
|
|
||||||
return py3eval('_vimspector_session.ShowTooltip(int( vim.eval( "winnr()" ) ) ,vim.eval( "expand(\"<cexpr>\")" ) )')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! vimspector#internal#state#TooltipExec(body) abort
|
|
||||||
let buf = nvim_create_buf(v:false, v:true)
|
|
||||||
call nvim_buf_set_lines(buf, 0, -1, v:true, a:body)
|
|
||||||
|
|
||||||
" get the max width on a line
|
|
||||||
let width = 0
|
|
||||||
let maxWidth = winwidth(0)
|
|
||||||
|
|
||||||
for w in a:body
|
|
||||||
let width = max([len(w), width])
|
|
||||||
" reached the max size, no point in looping more
|
|
||||||
if width > maxWidth
|
|
||||||
let width = maxWidth
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
|
|
||||||
let opts = { 'relative': 'cursor', 'width': width, 'height': len(a:body), 'col': 0, 'row': 1, 'anchor': 'NW', 'style': 'minimal' }
|
|
||||||
let s:float_win = nvim_open_win(buf, 0, opts)
|
|
||||||
call setwinvar(s:float_win, '&wrap', 0)
|
|
||||||
|
|
||||||
augroup vimspector#internal#balloon#nvim_float
|
|
||||||
autocmd!
|
|
||||||
autocmd CursorMoved * :call nvim_win_close(s:float_win, 1) | autocmd! vimspector#internal#balloon#nvim_float
|
|
||||||
augroup END
|
|
||||||
endfunction
|
|
||||||
" Boilerplate {{{
|
" Boilerplate {{{
|
||||||
let &cpoptions=s:save_cpo
|
let &cpoptions=s:save_cpo
|
||||||
unlet s:save_cpo
|
unlet s:save_cpo
|
||||||
|
|
|
||||||
|
|
@ -520,8 +520,8 @@ class DebugSession( object ):
|
||||||
self._stackTraceView.SetCurrentThread()
|
self._stackTraceView.SetCurrentThread()
|
||||||
|
|
||||||
@IfConnected()
|
@IfConnected()
|
||||||
def ExpandVariable( self ):
|
def ExpandVariable( self, lineNum = -1 ):
|
||||||
self._variablesView.ExpandVariable()
|
self._variablesView.ExpandVariable(lineNum)
|
||||||
|
|
||||||
@IfConnected()
|
@IfConnected()
|
||||||
def AddWatch( self, expression ):
|
def AddWatch( self, expression ):
|
||||||
|
|
@ -558,6 +558,9 @@ class DebugSession( object ):
|
||||||
# Return variable aware function
|
# Return variable aware function
|
||||||
return self._variablesView.VariableEval(frame, expression)
|
return self._variablesView.VariableEval(frame, expression)
|
||||||
|
|
||||||
|
def _CleanUpTooltip(self):
|
||||||
|
return self._variablesView._CleanUpTooltip()
|
||||||
|
|
||||||
@IfConnected()
|
@IfConnected()
|
||||||
def ShowBalloon( self, winnr, expression ):
|
def ShowBalloon( self, winnr, expression ):
|
||||||
"""Proxy: ballonexpr -> variables.ShowBallon"""
|
"""Proxy: ballonexpr -> variables.ShowBallon"""
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,10 @@ class VariablesView( object ):
|
||||||
|
|
||||||
self._DrawVariables( self._variable_eval_view, self._variable_eval.variables, 2 )
|
self._DrawVariables( self._variable_eval_view, self._variable_eval.variables, 2 )
|
||||||
|
|
||||||
|
def _CleanUpTooltip(self):
|
||||||
|
# remove reference to old tooltip window
|
||||||
|
self._variable_eval_view = None
|
||||||
|
return ''
|
||||||
|
|
||||||
def VariableEval(self, frame, expression):
|
def VariableEval(self, frame, expression):
|
||||||
"""Callback to display variable under cursor `:h ballonexpr`"""
|
"""Callback to display variable under cursor `:h ballonexpr`"""
|
||||||
|
|
@ -288,12 +292,12 @@ class VariablesView( object ):
|
||||||
|
|
||||||
self._variable_eval = Scope(body)
|
self._variable_eval = Scope(body)
|
||||||
|
|
||||||
float_win_id = vim.eval("vimspector#internal#state#CreateTooltip()")
|
float_win_id = vim.eval("vimspector#internal#balloon#CreateTooltip()")
|
||||||
float_buf_nr = int(vim.eval("winbufnr({})".format(float_win_id)))
|
float_buf_nr = int(vim.eval("winbufnr({})".format(float_win_id)))
|
||||||
|
|
||||||
# since vim's popup cant be focused there is no way
|
# since vim's popup cant be focused there is no way
|
||||||
# to get a reference to its window
|
# to get a reference to its window
|
||||||
# we will emulate python's window object overselves
|
# we will emulate python's window object ourselves
|
||||||
self._variable_eval_view = View(type('__vim__window__', (object,), {'options': {}, 'buffer': vim.buffers[float_buf_nr]}), {}, self._DrawEval)
|
self._variable_eval_view = View(type('__vim__window__', (object,), {'options': {}, 'buffer': vim.buffers[float_buf_nr]}), {}, self._DrawEval)
|
||||||
|
|
||||||
if(self._variable_eval.VariablesReference() > 0):
|
if(self._variable_eval.VariablesReference() > 0):
|
||||||
|
|
@ -400,18 +404,17 @@ class VariablesView( object ):
|
||||||
watch.result = WatchFailure( reason )
|
watch.result = WatchFailure( reason )
|
||||||
self._DrawWatches()
|
self._DrawWatches()
|
||||||
|
|
||||||
def ExpandVariable( self ):
|
def ExpandVariable( self, lineNum = -1 ):
|
||||||
if vim.current.buffer == self._vars.buf:
|
if vim.current.buffer == self._vars.buf:
|
||||||
view = self._vars
|
view = self._vars
|
||||||
elif vim.current.buffer == self._watch.buf:
|
elif vim.current.buffer == self._watch.buf:
|
||||||
view = self._watch
|
view = self._watch
|
||||||
elif vim.current.buffer == self._variable_eval_view.buf:
|
elif self._variable_eval_view is not None:
|
||||||
view = self._variable_eval_view
|
view = self._variable_eval_view
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
current_line = int(vim.eval("getbufinfo({})['lnum']".format(view.buf.name)))
|
current_line = vim.current.window.cursor[0] if lineNum <= 0 else lineNum
|
||||||
print(current_line)
|
|
||||||
if current_line not in view.lines:
|
if current_line not in view.lines:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -436,10 +439,6 @@ class VariablesView( object ):
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _DrawVariables( self, view, variables, indent ):
|
def _DrawVariables( self, view, variables, indent ):
|
||||||
assert indent > 0
|
assert indent > 0
|
||||||
for variable in variables:
|
for variable in variables:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue