Tidy up, refactor and fix some bugs
This commit is contained in:
parent
7dcb15f11c
commit
cc84e15932
6 changed files with 307 additions and 210 deletions
|
|
@ -525,13 +525,18 @@ endfunction
|
||||||
|
|
||||||
function! vimspector#ShowEvalBalloon( is_visual ) abort
|
function! vimspector#ShowEvalBalloon( is_visual ) abort
|
||||||
if a:is_visual
|
if a:is_visual
|
||||||
let expr = py3eval( '__import__( "vimspector", fromlist = [ "utils" ] ).utils.GetVisualSelection( int( vim.eval( "winbufnr( winnr() )" ) ) )' )
|
let expr = py3eval( '__import__( "vimspector", fromlist = [ "utils" ] )'
|
||||||
let expr = join(expr)
|
\ . '.utils.GetVisualSelection('
|
||||||
|
\ . ' int( vim.eval( "winbufnr( winnr() )" ) ) )' )
|
||||||
|
let expr = join( expr, '\n' )
|
||||||
else
|
else
|
||||||
let expr = expand( '<cexpr>' )
|
let expr = expand( '<cexpr>' )
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return py3eval( '_vimspector_session.ShowEvalBalloon( int( vim.eval( "winnr()" ) ), "'.expr.'", 0 )' )
|
return py3eval( '_vimspector_session.ShowEvalBalloon('
|
||||||
|
\ . ' int( vim.eval( "winnr()" ) ), "'
|
||||||
|
\ . expr
|
||||||
|
\ . '", 0 )' )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,8 @@ set cpoptions&vim
|
||||||
|
|
||||||
scriptencoding utf-8
|
scriptencoding utf-8
|
||||||
|
|
||||||
function! vimspector#internal#balloon#HoverTooltip() abort
|
let s:popup_win_id = 0
|
||||||
return py3eval('_vimspector_session.ShowEvalBalloon(int( vim.eval( "v:beval_winnr" ) ) + 1 ,vim.eval( "v:beval_text"), 1)')
|
let s:nvim_border_win_id = 0
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:float_win = 0
|
|
||||||
let s:nvim_related_win = 0
|
|
||||||
"
|
"
|
||||||
" tooltip dimensions
|
" tooltip dimensions
|
||||||
let s:min_width = 1
|
let s:min_width = 1
|
||||||
|
|
@ -34,105 +30,16 @@ let s:min_height = 1
|
||||||
let s:max_width = 80
|
let s:max_width = 80
|
||||||
let s:max_height = 20
|
let s:max_height = 20
|
||||||
|
|
||||||
function! vimspector#internal#balloon#MouseFilter(winid, key) abort
|
let s:is_neovim = has( 'nvim' )
|
||||||
if index(["\<leftmouse>", "\<2-leftmouse>"], a:key) < 0
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
let handled = 0
|
|
||||||
let mouse_coords = getmousepos()
|
|
||||||
|
|
||||||
" close the popup if mouse is clicked outside the window
|
|
||||||
if mouse_coords['winid'] != a:winid
|
|
||||||
call vimspector#internal#balloon#Close()
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
" place the cursor according to the click
|
|
||||||
call win_execute(a:winid, ':call cursor('.mouse_coords['line'].', '.mouse_coords['column'].')')
|
|
||||||
|
|
||||||
" expand the variable if we got double click
|
|
||||||
if a:key ==? "\<2-leftmouse>"
|
|
||||||
" forward line number to python, since vim does not allow us to focus
|
|
||||||
" the correct window
|
|
||||||
call py3eval('_vimspector_session.ExpandVariable('.line('.', a:winid).')')
|
|
||||||
let handled = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
return handled
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! vimspector#internal#balloon#CursorFilter(winid, key) abort
|
|
||||||
if 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 index( [ "\<LeftMouse>", "\<2-LeftMouse>" ], a:key ) >= 0
|
|
||||||
return vimspector#internal#balloon#MouseFilter( a:winid, a:key )
|
|
||||||
endif
|
|
||||||
|
|
||||||
return popup_filter_menu( a:winid, a:key )
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! vimspector#internal#balloon#Close() abort
|
|
||||||
if has('nvim')
|
|
||||||
call nvim_win_close(s:float_win, v:true)
|
|
||||||
call nvim_win_close(s:nvim_related_win, v:true)
|
|
||||||
|
|
||||||
call vimspector#internal#balloon#CloseCallback()
|
|
||||||
else
|
|
||||||
call popup_close(s:float_win)
|
|
||||||
endif
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! vimspector#internal#balloon#CloseCallback( ... ) abort
|
|
||||||
let s:float_win = 0
|
|
||||||
let s:nvim_related_win = 0
|
|
||||||
return py3eval('_vimspector_session._CleanUpTooltip()')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! vimspector#internal#balloon#nvim_generate_border(width, height) abort
|
|
||||||
let top = '╭' . repeat('─',a:width + 2) . '╮'
|
|
||||||
let mid = '│' . repeat(' ',a:width + 2) . '│'
|
|
||||||
let bot = '╰' . repeat('─',a:width + 2) . '╯'
|
|
||||||
let lines = [top] + repeat([mid], a:height) + [bot]
|
|
||||||
|
|
||||||
return lines
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! vimspector#internal#balloon#nvim_resize_tooltip() abort
|
|
||||||
if !has('nvim') || s:float_win <= 0 || s:nvim_related_win <= 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
noa call win_gotoid(s:float_win)
|
|
||||||
let buf_lines = getline(1, '$')
|
|
||||||
|
|
||||||
let width = s:min_width
|
|
||||||
let height = min([max([s:min_height, len(buf_lines)]), s:max_height])
|
|
||||||
|
|
||||||
" calculate the longest line
|
|
||||||
for l in buf_lines
|
|
||||||
let width = max([width, len(l)])
|
|
||||||
endfor
|
|
||||||
|
|
||||||
let width = min([width, s:max_width])
|
|
||||||
|
|
||||||
let opts = {
|
|
||||||
\ 'width': width,
|
|
||||||
\ 'height': height,
|
|
||||||
\ }
|
|
||||||
" resize the content window
|
|
||||||
call nvim_win_set_config(s:float_win, opts)
|
|
||||||
|
|
||||||
" resize the border window
|
|
||||||
let opts['width'] = width + 4
|
|
||||||
let opts['height'] = height + 2
|
|
||||||
call nvim_win_set_config(s:nvim_related_win, opts)
|
|
||||||
call nvim_buf_set_lines(nvim_win_get_buf(s:nvim_related_win), 0, -1, v:true, vimspector#internal#balloon#nvim_generate_border(width, height))
|
|
||||||
|
|
||||||
|
" This is used as the balloonexpr in vim to show the Tooltip at the hover
|
||||||
|
" position
|
||||||
|
function! vimspector#internal#balloon#HoverTooltip() abort
|
||||||
|
return py3eval( '_vimspector_session.ShowEvalBalloon('
|
||||||
|
\ . ' int( vim.eval( "v:beval_winnr" ) ) + 1,'
|
||||||
|
\ . ' vim.eval( "v:beval_text"),'
|
||||||
|
\ . ' 1 )' )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
|
function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
|
||||||
|
|
@ -141,66 +48,13 @@ function! vimspector#internal#balloon#CreateTooltip(is_hover, ...) abort
|
||||||
let body = a:1
|
let body = a:1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if has('nvim')
|
if s:popup_win_id != 0
|
||||||
" generate border for the float window by creating a background buffer and
|
|
||||||
" overlaying the content buffer
|
|
||||||
" see https://github.com/neovim/neovim/issues/9718#issuecomment-546603628
|
|
||||||
let buf_id = nvim_create_buf(v:false, v:true)
|
|
||||||
call nvim_buf_set_lines(buf_id, 0, -1, v:true, vimspector#internal#balloon#nvim_generate_border(s:max_width, s:max_height))
|
|
||||||
|
|
||||||
" default the dimensions for now. they can be easily overwritten later
|
|
||||||
let opts = {
|
|
||||||
\ 'relative': 'cursor',
|
|
||||||
\ 'width': s:max_width + 2,
|
|
||||||
\ 'height': s:max_height + 2,
|
|
||||||
\ 'col': 0,
|
|
||||||
\ 'row': 1,
|
|
||||||
\ 'anchor': 'NW',
|
|
||||||
\ 'style': 'minimal'
|
|
||||||
\ }
|
|
||||||
" this is the border window
|
|
||||||
let s:nvim_related_win = nvim_open_win(buf_id, 0, opts)
|
|
||||||
call nvim_win_set_option(s:nvim_related_win, 'signcolumn', 'no')
|
|
||||||
call nvim_win_set_option(s:nvim_related_win, 'relativenumber', v:false)
|
|
||||||
call nvim_win_set_option(s:nvim_related_win, 'number', v:false)
|
|
||||||
|
|
||||||
" when calculating where to display the content window, we need to account
|
|
||||||
" for the border
|
|
||||||
let opts.row += 1
|
|
||||||
let opts.height -= 2
|
|
||||||
let opts.col += 2
|
|
||||||
let opts.width -= 4
|
|
||||||
|
|
||||||
" create the content window
|
|
||||||
let buf_id = nvim_create_buf(v:false, v:true)
|
|
||||||
call nvim_buf_set_lines(buf_id, 0, -1, v:true, body)
|
|
||||||
call nvim_buf_set_option(buf_id, 'modifiable', v:false)
|
|
||||||
let s:float_win = nvim_open_win(buf_id, v:false, opts)
|
|
||||||
|
|
||||||
call nvim_win_set_option(s:float_win, 'wrap', v:false)
|
|
||||||
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)
|
|
||||||
|
|
||||||
noautocmd 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 BufLeave * :call vimspector#internal#balloon#Close() | autocmd! vimspector#internal#balloon#nvim_float
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
if s:float_win != 0
|
|
||||||
call vimspector#internal#balloon#Close()
|
call vimspector#internal#balloon#Close()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if s:is_neovim
|
||||||
|
call s:CreateNeovimTooltip( body )
|
||||||
|
else
|
||||||
let config = {
|
let config = {
|
||||||
\ 'wrap': 0,
|
\ 'wrap': 0,
|
||||||
\ 'filtermode': 'n',
|
\ 'filtermode': 'n',
|
||||||
|
|
@ -217,6 +71,8 @@ function! vimspector#internal#balloon#CreateTooltip(is_hover, ...) abort
|
||||||
\ 'callback': 'vimspector#internal#balloon#CloseCallback'
|
\ 'callback': 'vimspector#internal#balloon#CloseCallback'
|
||||||
\ }
|
\ }
|
||||||
|
|
||||||
|
" When ambiwidth is single, use prettier characters for the border. This
|
||||||
|
" would look silly when ambiwidth is double.
|
||||||
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
|
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
|
||||||
let config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
|
let config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
|
||||||
endif
|
endif
|
||||||
|
|
@ -224,19 +80,232 @@ function! vimspector#internal#balloon#CreateTooltip(is_hover, ...) abort
|
||||||
if a:is_hover
|
if a:is_hover
|
||||||
let config[ 'filter' ] = 'vimspector#internal#balloon#MouseFilter'
|
let config[ 'filter' ] = 'vimspector#internal#balloon#MouseFilter'
|
||||||
let config[ 'mousemoved' ] = [ 0, 0, 0 ]
|
let config[ 'mousemoved' ] = [ 0, 0, 0 ]
|
||||||
let s:float_win = popup_beval(body, config)
|
let s:popup_win_id = popup_beval( body, config )
|
||||||
else
|
else
|
||||||
let config[ 'filter' ] = 'vimspector#internal#balloon#CursorFilter'
|
let config[ 'filter' ] = 'vimspector#internal#balloon#CursorFilter'
|
||||||
let config[ 'moved' ] = 'any'
|
let config[ 'moved' ] = 'any'
|
||||||
let config[ 'cursorline' ] = 1
|
let config[ 'cursorline' ] = 1
|
||||||
let s:float_win = popup_atcursor(body, config)
|
let s:popup_win_id = popup_atcursor( body, config )
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return s:float_win
|
return s:popup_win_id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Filters for vim {{{
|
||||||
|
function! vimspector#internal#balloon#MouseFilter( winid, key ) abort
|
||||||
|
if a:key ==# "\<Esc>"
|
||||||
|
call vimspector#internal#balloon#Close()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if index( [ "\<leftmouse>", "\<2-leftmouse>" ], a:key ) < 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let handled = 0
|
||||||
|
let mouse_coords = getmousepos()
|
||||||
|
|
||||||
|
" close the popup if mouse is clicked outside the window
|
||||||
|
if mouse_coords[ 'winid' ] != a:winid
|
||||||
|
call vimspector#internal#balloon#Close()
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" place the cursor according to the click
|
||||||
|
call win_execute( a:winid,
|
||||||
|
\ ':call cursor( '
|
||||||
|
\ . mouse_coords[ 'line' ]
|
||||||
|
\ . ', '
|
||||||
|
\ . mouse_coords[ 'column' ]
|
||||||
|
\ . ' )' )
|
||||||
|
|
||||||
|
" expand the variable if we got double click
|
||||||
|
if a:key ==? "\<2-leftmouse>"
|
||||||
|
" forward line number to python, since vim does not allow us to focus
|
||||||
|
" the correct window
|
||||||
|
call py3eval( '_vimspector_session.ExpandVariable('
|
||||||
|
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
|
||||||
|
\ . 'line_num = ' . line( '.', a:winid )
|
||||||
|
\ . ')' )
|
||||||
|
let handled = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return handled
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! vimspector#internal#balloon#CursorFilter( winid, key ) abort
|
||||||
|
if a:key ==? "\<CR>"
|
||||||
|
" forward line number to python, since vim does not allow us to focus
|
||||||
|
" the correct window
|
||||||
|
call py3eval( '_vimspector_session.ExpandVariable('
|
||||||
|
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
|
||||||
|
\ . 'line_num = ' . line( '.', a:winid )
|
||||||
|
\ . ')' )
|
||||||
|
return 1
|
||||||
|
elseif index( [ "\<LeftMouse>", "\<2-LeftMouse>" ], a:key ) >= 0
|
||||||
|
return vimspector#internal#balloon#MouseFilter( a:winid, a:key )
|
||||||
|
endif
|
||||||
|
|
||||||
|
return popup_filter_menu( a:winid, a:key )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" }}}
|
||||||
|
|
||||||
|
" Closing {{{
|
||||||
|
|
||||||
|
function! vimspector#internal#balloon#CloseCallback( ... ) abort
|
||||||
|
let s:popup_win_id = 0
|
||||||
|
let s:nvim_border_win_id = 0
|
||||||
|
return py3eval( '_vimspector_session.CleanUpTooltip()' )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! vimspector#internal#balloon#Close() abort
|
||||||
|
if s:is_neovim
|
||||||
|
call nvim_win_close( s:popup_win_id, v:true )
|
||||||
|
call nvim_win_close( s:nvim_border_win_id, v:true )
|
||||||
|
|
||||||
|
call vimspector#internal#balloon#CloseCallback()
|
||||||
|
else
|
||||||
|
call popup_close(s:popup_win_id)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" }}}
|
||||||
|
|
||||||
|
" Neovim pollyfill {{{
|
||||||
|
|
||||||
|
function! vimspector#internal#balloon#ResizeTooltip() abort
|
||||||
|
if !s:is_neovim
|
||||||
|
" Vim does this for us
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:popup_win_id <= 0 || s:nvim_border_win_id <= 0
|
||||||
|
" nothing to resize
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
noautocmd call win_gotoid( s:popup_win_id )
|
||||||
|
let buf_lines = getline( 1, '$' )
|
||||||
|
|
||||||
|
let width = s:min_width
|
||||||
|
let height = min( [ max( [ s:min_height, len( buf_lines ) ] ),
|
||||||
|
\ s:max_height ] )
|
||||||
|
|
||||||
|
" calculate the longest line
|
||||||
|
for l in buf_lines
|
||||||
|
let width = max( [ width, len( l ) ] )
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let width = min( [ width, s:max_width ] )
|
||||||
|
|
||||||
|
let opts = {
|
||||||
|
\ 'width': width,
|
||||||
|
\ 'height': height,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
" resize the content window
|
||||||
|
call nvim_win_set_config( s:popup_win_id, opts )
|
||||||
|
|
||||||
|
" resize the border window
|
||||||
|
let opts[ 'width' ] = width + 4
|
||||||
|
let opts[ 'height' ] = height + 2
|
||||||
|
|
||||||
|
call nvim_win_set_config( s:nvim_border_win_id, opts )
|
||||||
|
call nvim_buf_set_lines( nvim_win_get_buf( s:nvim_border_win_id ),
|
||||||
|
\ 0,
|
||||||
|
\ -1,
|
||||||
|
\ v:true,
|
||||||
|
\ s:GenerateBorder( width, height ) )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" neovim doesn't have the border support, so we have to make our own.
|
||||||
|
" FIXME: This will likely break if the user has `ambiwidth=2`
|
||||||
|
function! s:GenerateBorder( width, height ) abort
|
||||||
|
|
||||||
|
let top = '╭' . repeat('─',a:width + 2) . '╮'
|
||||||
|
let mid = '│' . repeat(' ',a:width + 2) . '│'
|
||||||
|
let bot = '╰' . repeat('─',a:width + 2) . '╯'
|
||||||
|
let lines = [ top ] + repeat( [ mid ], a:height ) + [ bot ]
|
||||||
|
|
||||||
|
return lines
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:CreateNeovimTooltip( body ) abort
|
||||||
|
" generate border for the float window by creating a background buffer and
|
||||||
|
" overlaying the content buffer
|
||||||
|
" see https://github.com/neovim/neovim/issues/9718#issuecomment-546603628
|
||||||
|
let buf_id = nvim_create_buf( v:false, v:true )
|
||||||
|
call nvim_buf_set_lines( buf_id,
|
||||||
|
\ 0,
|
||||||
|
\ -1,
|
||||||
|
\ v:true,
|
||||||
|
\ s:GenerateBorder( s:max_width, s:max_height ) )
|
||||||
|
|
||||||
|
" default the dimensions initially, then we'll calculate the real size and
|
||||||
|
" resize it.
|
||||||
|
let opts = {
|
||||||
|
\ 'relative': 'cursor',
|
||||||
|
\ 'width': s:max_width + 2,
|
||||||
|
\ 'height': s:max_height + 2,
|
||||||
|
\ 'col': 0,
|
||||||
|
\ 'row': 1,
|
||||||
|
\ 'anchor': 'NW',
|
||||||
|
\ 'style': 'minimal'
|
||||||
|
\ }
|
||||||
|
|
||||||
|
" this is the border window
|
||||||
|
let s:nvim_border_win_id = nvim_open_win( buf_id, 0, opts )
|
||||||
|
call nvim_win_set_option( s:nvim_border_win_id, 'signcolumn', 'no' )
|
||||||
|
call nvim_win_set_option( s:nvim_border_win_id, 'relativenumber', v:false )
|
||||||
|
call nvim_win_set_option( s:nvim_border_win_id, 'number', v:false )
|
||||||
|
|
||||||
|
" when calculating where to display the content window, we need to account
|
||||||
|
" for the border
|
||||||
|
let opts.row += 1
|
||||||
|
let opts.height -= 2
|
||||||
|
let opts.col += 2
|
||||||
|
let opts.width -= 4
|
||||||
|
|
||||||
|
" create the content window
|
||||||
|
let buf_id = nvim_create_buf( v:false, v:true )
|
||||||
|
call nvim_buf_set_lines( buf_id, 0, -1, v:true, a:body )
|
||||||
|
call nvim_buf_set_option( buf_id, 'modifiable', v:false )
|
||||||
|
let s:popup_win_id = nvim_open_win( buf_id, v:false, opts )
|
||||||
|
|
||||||
|
call nvim_win_set_option( s:popup_win_id, 'wrap', v:false )
|
||||||
|
call nvim_win_set_option( s:popup_win_id, 'cursorline', v:true )
|
||||||
|
call nvim_win_set_option( s:popup_win_id, 'signcolumn', 'no' )
|
||||||
|
call nvim_win_set_option( s:popup_win_id, 'relativenumber', v:false )
|
||||||
|
call nvim_win_set_option( s:popup_win_id, 'number', v:false )
|
||||||
|
|
||||||
|
" Move the cursor into the popup window, as this is the only way we can
|
||||||
|
" interract with the popup in neovim
|
||||||
|
noautocmd call win_gotoid( s:popup_win_id )
|
||||||
|
|
||||||
|
nnoremap <silent> <buffer> <CR>
|
||||||
|
\ <cmd>call vimspector#ExpandVariable()<CR>
|
||||||
|
nnoremap <silent> <buffer> <Esc>
|
||||||
|
\ <cmd>quit<CR>
|
||||||
|
nnoremap <silent> <buffer> <2-LeftMouse>
|
||||||
|
\ <cmd>call vimspector#ExpandVariable()<CR>
|
||||||
|
|
||||||
|
" Close the popup whenever we leave this window
|
||||||
|
augroup vimspector#internal#balloon#nvim_float
|
||||||
|
autocmd!
|
||||||
|
autocmd WinLeave <buffer>
|
||||||
|
\ :call vimspector#internal#balloon#Close()
|
||||||
|
\ | autocmd! vimspector#internal#balloon#nvim_float
|
||||||
|
augroup END
|
||||||
|
|
||||||
|
call vimspector#internal#balloon#ResizeTooltip()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" }}}
|
||||||
|
|
||||||
|
|
||||||
" Boilerplate {{{
|
" Boilerplate {{{
|
||||||
let &cpoptions=s:save_cpo
|
let &cpoptions=s:save_cpo
|
||||||
unlet s:save_cpo
|
unlet s:save_cpo
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,10 @@ nnoremap <silent> <Plug>VimspectorStepOut
|
||||||
nnoremap <silent> <Plug>VimspectorRunToCursor
|
nnoremap <silent> <Plug>VimspectorRunToCursor
|
||||||
\ :<c-u>call vimspector#RunToCursor()<CR>
|
\ :<c-u>call vimspector#RunToCursor()<CR>
|
||||||
|
|
||||||
|
" Eval for normal mode
|
||||||
nnoremap <silent> <Plug>VimspectorBalloonEval
|
nnoremap <silent> <Plug>VimspectorBalloonEval
|
||||||
\ :<c-u>call vimspector#ShowEvalBalloon( 0 )<CR>
|
\ :<c-u>call vimspector#ShowEvalBalloon( 0 )<CR>
|
||||||
|
" And for visual modes
|
||||||
xnoremap <silent> <Plug>VimspectorBalloonEval
|
xnoremap <silent> <Plug>VimspectorBalloonEval
|
||||||
\ :<c-u>call vimspector#ShowEvalBalloon( 1 )<CR>
|
\ :<c-u>call vimspector#ShowEvalBalloon( 1 )<CR>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -520,8 +520,8 @@ class DebugSession( object ):
|
||||||
self._stackTraceView.SetCurrentThread()
|
self._stackTraceView.SetCurrentThread()
|
||||||
|
|
||||||
@IfConnected()
|
@IfConnected()
|
||||||
def ExpandVariable( self, lineNum = -1 ):
|
def ExpandVariable( self, buf = None, line_num = None ):
|
||||||
self._variablesView.ExpandVariable( lineNum )
|
self._variablesView.ExpandVariable( buf, line_num )
|
||||||
|
|
||||||
@IfConnected()
|
@IfConnected()
|
||||||
def AddWatch( self, expression ):
|
def AddWatch( self, expression ):
|
||||||
|
|
@ -558,8 +558,8 @@ class DebugSession( object ):
|
||||||
return self._variablesView.VariableEval( frame, expression, is_hover )
|
return self._variablesView.VariableEval( frame, expression, is_hover )
|
||||||
|
|
||||||
|
|
||||||
def _CleanUpTooltip( self ):
|
def CleanUpTooltip( self ):
|
||||||
return self._variablesView._CleanUpTooltip()
|
return self._variablesView.CleanUpTooltip()
|
||||||
|
|
||||||
@IfConnected()
|
@IfConnected()
|
||||||
def ExpandFrameOrThread( self ):
|
def ExpandFrameOrThread( self ):
|
||||||
|
|
|
||||||
|
|
@ -645,8 +645,6 @@ def DisplayBalloon( is_term, display, is_hover = False ):
|
||||||
)
|
)
|
||||||
) )
|
) )
|
||||||
|
|
||||||
vim.eval( "vimspector#internal#balloon#nvim_resize_tooltip()" )
|
|
||||||
|
|
||||||
return created_win_id
|
return created_win_id
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -728,11 +726,20 @@ def GetVisualSelection( bufnr ):
|
||||||
start_line, start_col = vim.current.buffer.mark( "<" )
|
start_line, start_col = vim.current.buffer.mark( "<" )
|
||||||
end_line, end_col = vim.current.buffer.mark( ">" )
|
end_line, end_col = vim.current.buffer.mark( ">" )
|
||||||
|
|
||||||
|
|
||||||
# lines are 1 based, but columns are 0 based
|
# lines are 1 based, but columns are 0 based
|
||||||
# don't as me why...
|
# don't ask me why...
|
||||||
lines = vim.buffers[ bufnr ][ start_line - 1 : end_line ]
|
start_line -= 1
|
||||||
lines[ 0 ] = lines[ 0 ][ start_col : ]
|
end_line -= 1
|
||||||
|
|
||||||
|
lines = vim.buffers[ bufnr ][ start_line : end_line + 1 ]
|
||||||
|
# Do end first, in case it's on the same line as start (as doing start first
|
||||||
|
# would change the offset)
|
||||||
lines[ -1 ] = lines[ -1 ][ : end_col + 1 ]
|
lines[ -1 ] = lines[ -1 ][ : end_col + 1 ]
|
||||||
|
lines[ 0 ] = lines[ 0 ][ start_col : ]
|
||||||
|
|
||||||
|
_logger.debug( f'Visual selection: { lines } from '
|
||||||
|
f'{ start_line }/{ start_col } -> { end_line }/{ end_col }' )
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,12 @@ class View:
|
||||||
utils.SetUpUIWindow( win )
|
utils.SetUpUIWindow( win )
|
||||||
|
|
||||||
|
|
||||||
|
class BufView( View ):
|
||||||
|
def __init__( self, buf, lines, draw ):
|
||||||
|
super().__init__( None, lines, draw )
|
||||||
|
self.buf = buf
|
||||||
|
|
||||||
|
|
||||||
class VariablesView( object ):
|
class VariablesView( object ):
|
||||||
def __init__( self, variables_win, watches_win ):
|
def __init__( self, variables_win, watches_win ):
|
||||||
self._logger = logging.getLogger( __name__ )
|
self._logger = logging.getLogger( __name__ )
|
||||||
|
|
@ -219,6 +225,7 @@ class VariablesView( object ):
|
||||||
utils.ClearBuffer( self._vars.buf )
|
utils.ClearBuffer( self._vars.buf )
|
||||||
with utils.ModifiableScratchBuffer( self._watch.buf ):
|
with utils.ModifiableScratchBuffer( self._watch.buf ):
|
||||||
utils.ClearBuffer( self._watch.buf )
|
utils.ClearBuffer( self._watch.buf )
|
||||||
|
self.ClearTooltip()
|
||||||
self._current_syntax = ''
|
self._current_syntax = ''
|
||||||
|
|
||||||
def ConnectionUp( self, connection ):
|
def ConnectionUp( self, connection ):
|
||||||
|
|
@ -234,6 +241,8 @@ class VariablesView( object ):
|
||||||
|
|
||||||
utils.CleanUpHiddenBuffer( self._vars.buf )
|
utils.CleanUpHiddenBuffer( self._vars.buf )
|
||||||
utils.CleanUpHiddenBuffer( self._watch.buf )
|
utils.CleanUpHiddenBuffer( self._watch.buf )
|
||||||
|
self.ClearTooltip()
|
||||||
|
|
||||||
|
|
||||||
def LoadScopes( self, frame ):
|
def LoadScopes( self, frame ):
|
||||||
def scopes_consumer( message ):
|
def scopes_consumer( message ):
|
||||||
|
|
@ -302,9 +311,14 @@ class VariablesView( object ):
|
||||||
watch,
|
watch,
|
||||||
is_short = True )
|
is_short = True )
|
||||||
|
|
||||||
vim.eval( "vimspector#internal#balloon#nvim_resize_tooltip()" )
|
vim.eval( "vimspector#internal#balloon#ResizeTooltip()" )
|
||||||
|
|
||||||
def _CleanUpTooltip( self ) :
|
def ClearTooltip( self ):
|
||||||
|
# This will actually end up calling CleanUpTooltip via the popup close
|
||||||
|
# callback
|
||||||
|
vim.eval( 'vimspector#internal#balloon#Close()' )
|
||||||
|
|
||||||
|
def CleanUpTooltip( self ) :
|
||||||
# remove reference to old tooltip window
|
# remove reference to old tooltip window
|
||||||
self._variable_eval_view = None
|
self._variable_eval_view = None
|
||||||
vim.vars[ 'vimspector_session_windows' ][ 'eval' ] = None
|
vim.vars[ 'vimspector_session_windows' ][ 'eval' ] = None
|
||||||
|
|
@ -322,20 +336,15 @@ class VariablesView( object ):
|
||||||
else:
|
else:
|
||||||
watch.result.Update( message[ 'body' ] )
|
watch.result.Update( message[ 'body' ] )
|
||||||
|
|
||||||
float_win_id = utils.DisplayBalloon( self._is_term, [], is_hover )
|
popup_win_id = utils.DisplayBalloon( self._is_term, [], is_hover )
|
||||||
# record the global eval window id
|
# record the global eval window id
|
||||||
vim.vars[ 'vimspector_session_windows' ][ 'eval' ] = int( float_win_id )
|
vim.vars[ 'vimspector_session_windows' ][ 'eval' ] = int( popup_win_id )
|
||||||
float_buf_nr = int( vim.eval( "winbufnr({})".format( float_win_id ) ) )
|
popup_bufnr = int( vim.eval( "winbufnr({})".format( popup_win_id ) ) )
|
||||||
|
|
||||||
# since vim's popup cant be focused there is no way
|
# We don't need to do any UI window setup here, as it's already done as
|
||||||
# to get a reference to its window
|
# part of the popup creation, so just pass the buffer to the View instance
|
||||||
# we will emulate python's window object ourselves
|
self._variable_eval_view = BufView(
|
||||||
self._variable_eval_view = View(
|
vim.buffers[ popup_bufnr ],
|
||||||
type(
|
|
||||||
'__vim__window__',
|
|
||||||
( object, ),
|
|
||||||
{ 'options': {}, 'buffer': vim.buffers[ float_buf_nr ] }
|
|
||||||
),
|
|
||||||
{},
|
{},
|
||||||
self._DrawBalloonEval
|
self._DrawBalloonEval
|
||||||
)
|
)
|
||||||
|
|
@ -439,21 +448,27 @@ class VariablesView( object ):
|
||||||
watch.result = WatchFailure( reason )
|
watch.result = WatchFailure( reason )
|
||||||
self._DrawWatches()
|
self._DrawWatches()
|
||||||
|
|
||||||
def ExpandVariable( self, lineNum = -1 ):
|
def ExpandVariable( self, buf = None, line_num = None ):
|
||||||
if vim.current.buffer == self._vars.buf:
|
if buf is None:
|
||||||
|
buf = vim.current.buffer
|
||||||
|
|
||||||
|
if line_num is None:
|
||||||
|
line_num = vim.current.window.cursor[ 0 ]
|
||||||
|
|
||||||
|
if buf == self._vars.buf:
|
||||||
view = self._vars
|
view = self._vars
|
||||||
elif vim.current.buffer == self._watch.buf:
|
elif buf == self._watch.buf:
|
||||||
view = self._watch
|
view = self._watch
|
||||||
elif self._variable_eval_view is not None:
|
elif ( self._variable_eval_view is not None
|
||||||
|
and buf == self._variable_eval_view.buf ):
|
||||||
view = self._variable_eval_view
|
view = self._variable_eval_view
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
current_line = vim.current.window.cursor[ 0 ] if lineNum <= 0 else lineNum
|
if line_num not in view.lines:
|
||||||
if current_line not in view.lines:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
variable = view.lines[ current_line ]
|
variable = view.lines[ line_num ]
|
||||||
|
|
||||||
if variable.IsExpanded():
|
if variable.IsExpanded():
|
||||||
# Collapse
|
# Collapse
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue