Merge pull request #197 from puremourning/use-buffers-not-windows
Allow users to close UI windows
This commit is contained in:
commit
fe58b94bb0
16 changed files with 244 additions and 112 deletions
|
|
@ -20,12 +20,20 @@ set cpoptions&vim
|
|||
" }}}
|
||||
|
||||
function! s:_OnServerData( channel, data ) abort
|
||||
if !exists( 's:ch' ) || s:ch isnot a:channel
|
||||
return
|
||||
endif
|
||||
|
||||
py3 << EOF
|
||||
_vimspector_session.OnChannelData( vim.eval( 'a:data' ) )
|
||||
EOF
|
||||
endfunction
|
||||
|
||||
function! s:_OnClose( channel ) abort
|
||||
if !exists( 's:ch' ) || s:ch isnot a:channel
|
||||
return
|
||||
endif
|
||||
|
||||
echom 'Channel closed'
|
||||
redraw
|
||||
unlet s:ch
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ set cpoptions&vim
|
|||
" }}}
|
||||
|
||||
function! s:_OnServerData( channel, data ) abort
|
||||
if !exists( 's:job' )
|
||||
if !exists( 's:job' ) || ch_getjob( a:channel ) isnot s:job
|
||||
call ch_log( 'Get data after process exit' )
|
||||
return
|
||||
endif
|
||||
|
|
@ -29,7 +29,7 @@ function! s:_OnServerData( channel, data ) abort
|
|||
endfunction
|
||||
|
||||
function! s:_OnServerError( channel, data ) abort
|
||||
if !exists( 's:job' )
|
||||
if !exists( 's:job' ) || ch_getjob( a:channel ) isnot s:job
|
||||
call ch_log( 'Get data after process exit' )
|
||||
return
|
||||
endif
|
||||
|
|
@ -37,7 +37,16 @@ function! s:_OnServerError( channel, data ) abort
|
|||
py3 _vimspector_session.OnServerStderr( vim.eval( 'a:data' ) )
|
||||
endfunction
|
||||
|
||||
|
||||
" FIXME: We should wait until both the exit_cb _and_ the channel closed callback
|
||||
" have been received before OnServerExit?
|
||||
|
||||
function! s:_OnExit( channel, status ) abort
|
||||
if !exists( 's:job' ) || ch_getjob( a:channel ) isnot s:job
|
||||
call ch_log( 'Unexpected exit callback' )
|
||||
return
|
||||
endif
|
||||
|
||||
echom 'Channel exit with status ' . a:status
|
||||
redraw
|
||||
if exists( 's:job' )
|
||||
|
|
@ -47,6 +56,11 @@ function! s:_OnExit( channel, status ) abort
|
|||
endfunction
|
||||
|
||||
function! s:_OnClose( channel ) abort
|
||||
if !exists( 's:job' ) || job_getchannel( s:job ) != a:channel
|
||||
call ch_log( 'Channel closed after exit' )
|
||||
return
|
||||
endif
|
||||
|
||||
echom 'Channel closed'
|
||||
redraw
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -22,6 +22,14 @@ set cpoptions&vim
|
|||
|
||||
|
||||
function! s:_OnEvent( chan_id, data, event ) abort
|
||||
if v:exiting isnot# v:null
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists( 's:ch' ) || a:chan_id != s:ch
|
||||
return
|
||||
endif
|
||||
|
||||
if a:data == ['']
|
||||
echom 'Channel closed'
|
||||
redraw
|
||||
|
|
|
|||
|
|
@ -22,6 +22,14 @@ set cpoptions&vim
|
|||
|
||||
|
||||
function! s:_OnEvent( chan_id, data, event ) abort
|
||||
if v:exiting isnot# v:null
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists( 's:job' ) || a:chan_id != s:job
|
||||
return
|
||||
endif
|
||||
|
||||
" In neovim, the data argument is a list.
|
||||
if a:event ==# 'stdout'
|
||||
py3 _vimspector_session.OnChannelData( '\n'.join( vim.eval( 'a:data' ) ) )
|
||||
|
|
@ -30,11 +38,7 @@ function! s:_OnEvent( chan_id, data, event ) abort
|
|||
elseif a:event ==# 'exit'
|
||||
echom 'Channel exit with status ' . a:data
|
||||
redraw
|
||||
if exists( 's:job' )
|
||||
unlet s:job
|
||||
endif
|
||||
" This causes terminal spam in neovim due to
|
||||
" https://github.com/neovim/neovim/issues/11725
|
||||
unlet s:job
|
||||
py3 _vimspector_session.OnServerExit( vim.eval( 'a:data' ) )
|
||||
endif
|
||||
endfunction
|
||||
|
|
@ -108,10 +112,22 @@ function! vimspector#internal#neojob#Reset() abort
|
|||
endfunction
|
||||
|
||||
function! s:_OnCommandEvent( category, id, data, event ) abort
|
||||
if v:exiting isnot# v:null
|
||||
return
|
||||
endif
|
||||
|
||||
if a:data == ['']
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key( s:commands, a:category )
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key( s:commands[ a:category ], a:id )
|
||||
return
|
||||
endif
|
||||
|
||||
if a:event ==# 'stdout'
|
||||
let buffer = s:commands[ a:category ][ a:id ].stdout
|
||||
elseif a:event ==# 'stderr'
|
||||
|
|
@ -212,8 +228,8 @@ function! vimspector#internal#neojob#CleanUpCommand( category ) abort
|
|||
endif
|
||||
|
||||
for id in keys( s:commands[ a:category ] )
|
||||
call jobstop( id )
|
||||
call jobwait( id )
|
||||
call jobstop( str2nr( id ) )
|
||||
call jobwait( [ str2nr( id ) ] )
|
||||
endfor
|
||||
unlet! s:commands[ a:category ]
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -46,12 +46,17 @@ function! vimspector#internal#neoterm#ResetEnvironment( env, old_env ) abort
|
|||
endfunction
|
||||
|
||||
function! vimspector#internal#neoterm#Start( cmd, opts ) abort
|
||||
" Prepare current buffer to be turned into a term if curwin is not set
|
||||
if ! get( a:opts, 'curwin', 0 )
|
||||
let mods = ''
|
||||
if get( a:opts, 'vertical', 0 )
|
||||
vnew
|
||||
let mods .= 'vertical '
|
||||
let mods .= get( a:opts, 'term_cols', '' )
|
||||
else
|
||||
new
|
||||
let mods .= get( a:opts, 'term_rows', '' )
|
||||
endif
|
||||
|
||||
execute mods . 'new'
|
||||
endif
|
||||
|
||||
" HACK: Neovim's termopen doesn't support env
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ class CodeView( object ):
|
|||
'breakpoints': []
|
||||
}
|
||||
|
||||
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
vim.command( 'nnoremenu WinBar.Continue :call vimspector#Continue()<CR>' )
|
||||
vim.command( 'nnoremenu WinBar.Next :call vimspector#StepOver()<CR>' )
|
||||
|
|
@ -56,6 +55,10 @@ class CodeView( object ):
|
|||
|
||||
|
||||
def SetCurrentFrame( self, frame ):
|
||||
"""Returns True if the code window was updated with the frame, False
|
||||
otherwise. False means either the frame is junk, we couldn't find the file
|
||||
(or don't have the data) or the code window no longer exits."""
|
||||
|
||||
if self._signs[ 'vimspectorPC' ]:
|
||||
vim.command( 'sign unplace {} group=VimspectorCode'.format(
|
||||
self._signs[ 'vimspectorPC' ] ) )
|
||||
|
|
@ -67,8 +70,25 @@ class CodeView( object ):
|
|||
if 'path' not in frame[ 'source' ]:
|
||||
return False
|
||||
|
||||
utils.JumpToWindow( self._window )
|
||||
self._signs[ 'vimspectorPC' ] = self._next_sign_id
|
||||
self._next_sign_id += 1
|
||||
|
||||
try:
|
||||
vim.command( 'sign place {0} group=VimspectorCode priority=20 '
|
||||
'line={1} name=vimspectorPC '
|
||||
'file={2}'.format(
|
||||
self._signs[ 'vimspectorPC' ],
|
||||
frame[ 'line' ],
|
||||
frame[ 'source' ][ 'path' ] ) )
|
||||
except vim.error as e:
|
||||
# Ignore 'invalid buffer name'
|
||||
if 'E158' not in str( e ):
|
||||
raise
|
||||
|
||||
if not self._window.valid:
|
||||
return False
|
||||
|
||||
utils.JumpToWindow( self._window )
|
||||
try:
|
||||
utils.OpenFileInCurrentWindow( frame[ 'source' ][ 'path' ] )
|
||||
except vim.error:
|
||||
|
|
@ -89,16 +109,6 @@ class CodeView( object ):
|
|||
frame[ 'source' ][ 'path' ] )
|
||||
return False
|
||||
|
||||
self._signs[ 'vimspectorPC' ] = self._next_sign_id
|
||||
self._next_sign_id += 1
|
||||
|
||||
vim.command( 'sign place {0} group=VimspectorCode priority=20 '
|
||||
'line={1} name=vimspectorPC '
|
||||
'file={2}'.format(
|
||||
self._signs[ 'vimspectorPC' ],
|
||||
frame[ 'line' ],
|
||||
frame[ 'source' ][ 'path' ] ) )
|
||||
|
||||
self.current_syntax = utils.ToUnicode(
|
||||
vim.current.buffer.options[ 'syntax' ] )
|
||||
|
||||
|
|
@ -210,13 +220,19 @@ class CodeView( object ):
|
|||
|
||||
options = {
|
||||
'vertical': 1,
|
||||
'term_cols': 80,
|
||||
'norestore': 1,
|
||||
'cwd': cwd,
|
||||
'env': env,
|
||||
}
|
||||
|
||||
window_for_start = self._window
|
||||
if self._terminal_window is not None:
|
||||
if self._window.valid:
|
||||
window_for_start = self._window
|
||||
else:
|
||||
# TOOD: Where?
|
||||
window_for_start = vim.current.window
|
||||
|
||||
if self._terminal_window is not None and self._terminal_window.valid:
|
||||
assert self._terminal_buffer_number
|
||||
if ( self._terminal_window.buffer.number == self._terminal_buffer_number
|
||||
and int( utils.Call( 'vimspector#internal#{}term#IsFinished'.format(
|
||||
|
|
|
|||
|
|
@ -518,6 +518,10 @@ class DebugSession( object ):
|
|||
self.SetCurrentFrame( None )
|
||||
|
||||
def SetCurrentFrame( self, frame ):
|
||||
if not frame:
|
||||
self._stackTraceView.Clear()
|
||||
self._variablesView.Clear()
|
||||
|
||||
if not self._codeView.SetCurrentFrame( frame ):
|
||||
return False
|
||||
|
||||
|
|
@ -526,9 +530,6 @@ class DebugSession( object ):
|
|||
self._stackTraceView.SetSyntax( self._codeView.current_syntax )
|
||||
self._variablesView.LoadScopes( frame )
|
||||
self._variablesView.EvaluateWatches()
|
||||
else:
|
||||
self._stackTraceView.Clear()
|
||||
self._variablesView.Clear()
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -77,9 +77,10 @@ class OutputView( object ):
|
|||
self._ToggleFlag( category, True )
|
||||
|
||||
# Scroll the buffer
|
||||
with utils.RestoreCurrentWindow():
|
||||
with utils.RestoreCurrentBuffer( self._window ):
|
||||
self._ShowOutput( category )
|
||||
if self._window.valid:
|
||||
with utils.RestoreCurrentWindow():
|
||||
with utils.RestoreCurrentBuffer( self._window ):
|
||||
self._ShowOutput( category )
|
||||
|
||||
def ConnectionUp( self, connection ):
|
||||
self._connection = connection
|
||||
|
|
@ -96,18 +97,17 @@ class OutputView( object ):
|
|||
if tab_buffer.is_job:
|
||||
utils.CleanUpCommand( tab_buffer.job_category or category,
|
||||
self._api_prefix )
|
||||
try:
|
||||
vim.command( 'bdelete! {0}'.format( tab_buffer.buf.number ) )
|
||||
except vim.error as e:
|
||||
# FIXME: For now just ignore the "no buffers were deleted" error
|
||||
if 'E516' not in str( e ):
|
||||
raise
|
||||
utils.CleanUpHiddenBuffer( tab_buffer.buf )
|
||||
|
||||
# FIXME: nunmenu the WinBar ?
|
||||
self._buffers = {}
|
||||
|
||||
def _ShowOutput( self, category ):
|
||||
if not self._window.valid:
|
||||
return
|
||||
|
||||
utils.JumpToWindow( self._window )
|
||||
vim.command( 'bu {0}'.format( self._buffers[ category ].buf.name ) )
|
||||
vim.current.buffer = self._buffers[ category ].buf
|
||||
vim.command( 'normal G' )
|
||||
|
||||
def ShowOutput( self, category ):
|
||||
|
|
@ -146,8 +146,10 @@ class OutputView( object ):
|
|||
def _ToggleFlag( self, category, flag ):
|
||||
if self._buffers[ category ].flag != flag:
|
||||
self._buffers[ category ].flag = flag
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
self._RenderWinBar( category )
|
||||
|
||||
if self._window.valid:
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
self._RenderWinBar( category )
|
||||
|
||||
|
||||
def RunJobWithOutput( self, category, cmd ):
|
||||
|
|
@ -155,6 +157,9 @@ class OutputView( object ):
|
|||
|
||||
|
||||
def _CreateBuffer( self, category, file_name = None, cmd = None ):
|
||||
if not self._window.valid:
|
||||
return
|
||||
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
with utils.RestoreCurrentBuffer( self._window ):
|
||||
|
||||
|
|
@ -185,8 +190,7 @@ class OutputView( object ):
|
|||
utils.SetUpPromptBuffer( tab_buffer.buf,
|
||||
'vimspector.Console',
|
||||
'> ',
|
||||
'vimspector#EvaluateConsole',
|
||||
hidden=True )
|
||||
'vimspector#EvaluateConsole' )
|
||||
else:
|
||||
utils.SetUpHiddenBuffer(
|
||||
tab_buffer.buf,
|
||||
|
|
|
|||
|
|
@ -36,13 +36,10 @@ class StackTraceView( object ):
|
|||
self._threads = []
|
||||
self._sources = {}
|
||||
|
||||
utils.SetUpScratchBuffer( self._buf, 'vimspector.StackTrace' )
|
||||
utils.SetUpHiddenBuffer( self._buf, 'vimspector.StackTrace' )
|
||||
|
||||
vim.current.buffer = self._buf
|
||||
# FIXME: Remove all usage of "Windown" and just use buffers to prevent all
|
||||
# the bugs around the window being closed.
|
||||
self._win = vim.current.window
|
||||
utils.SetUpUIWindow( self._win )
|
||||
utils.SetUpUIWindow( vim.current.window )
|
||||
|
||||
vim.command( 'nnoremap <buffer> <CR> :call vimspector#GoToFrame()<CR>' )
|
||||
|
||||
|
|
@ -84,7 +81,7 @@ class StackTraceView( object ):
|
|||
|
||||
def Reset( self ):
|
||||
self.Clear()
|
||||
# TODO: delete the buffer ?
|
||||
utils.CleanUpHiddenBuffer( self._buf )
|
||||
|
||||
def LoadThreads( self, infer_current_frame ):
|
||||
pending_request = False
|
||||
|
|
@ -311,4 +308,4 @@ class StackTraceView( object ):
|
|||
def SetSyntax( self, syntax ):
|
||||
self._current_syntax = utils.SetSyntax( self._current_syntax,
|
||||
syntax,
|
||||
self._win )
|
||||
self._buf )
|
||||
|
|
|
|||
|
|
@ -86,15 +86,18 @@ def CleanUpCommand( name, api_prefix ):
|
|||
name ) )
|
||||
|
||||
|
||||
def CleanUpHiddenBuffer( buf ):
|
||||
try:
|
||||
vim.command( 'bdelete! {}'.format( buf.number ) )
|
||||
except vim.error as e:
|
||||
# FIXME: For now just ignore the "no buffers were deleted" error
|
||||
if 'E516' not in str( e ):
|
||||
raise
|
||||
|
||||
|
||||
def SetUpScratchBuffer( buf, name ):
|
||||
buf.options[ 'buftype' ] = 'nofile'
|
||||
buf.options[ 'swapfile' ] = False
|
||||
buf.options[ 'modifiable' ] = False
|
||||
buf.options[ 'modified' ] = False
|
||||
buf.options[ 'readonly' ] = True
|
||||
buf.options[ 'buflisted' ] = False
|
||||
SetUpHiddenBuffer( buf, name )
|
||||
buf.options[ 'bufhidden' ] = 'wipe'
|
||||
buf.name = name
|
||||
|
||||
|
||||
def SetUpHiddenBuffer( buf, name ):
|
||||
|
|
@ -108,7 +111,7 @@ def SetUpHiddenBuffer( buf, name ):
|
|||
buf.name = name
|
||||
|
||||
|
||||
def SetUpPromptBuffer( buf, name, prompt, callback, hidden=False ):
|
||||
def SetUpPromptBuffer( buf, name, prompt, callback ):
|
||||
# This feature is _super_ new, so only enable when available
|
||||
if not Exists( '*prompt_setprompt' ):
|
||||
return SetUpHiddenBuffer( buf, name )
|
||||
|
|
@ -119,7 +122,8 @@ def SetUpPromptBuffer( buf, name, prompt, callback, hidden=False ):
|
|||
buf.options[ 'modified' ] = False
|
||||
buf.options[ 'readonly' ] = False
|
||||
buf.options[ 'buflisted' ] = False
|
||||
buf.options[ 'bufhidden' ] = 'wipe' if not hidden else 'hide'
|
||||
buf.options[ 'bufhidden' ] = 'hide'
|
||||
buf.options[ 'textwidth' ] = 0
|
||||
buf.name = name
|
||||
|
||||
vim.eval( "prompt_setprompt( {0}, '{1}' )".format( buf.number,
|
||||
|
|
@ -177,7 +181,6 @@ def RestoreCurrentWindow():
|
|||
|
||||
@contextlib.contextmanager
|
||||
def RestoreCurrentBuffer( window ):
|
||||
# TODO: Don't trigger autoccommands when shifting buffers
|
||||
old_buffer = window.buffer
|
||||
try:
|
||||
yield
|
||||
|
|
@ -194,6 +197,14 @@ def LetCurrentWindow( window ):
|
|||
yield
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def LetCurrentBuffer( buf ):
|
||||
with RestoreCursorPosition():
|
||||
with RestoreCurrentBuffer( vim.current.window ):
|
||||
vim.current.buffer = buf
|
||||
yield
|
||||
|
||||
|
||||
def JumpToWindow( window ):
|
||||
vim.current.tabpage = window.tabpage
|
||||
vim.current.window = window
|
||||
|
|
@ -555,8 +566,11 @@ def SetSyntax( current_syntax, syntax, *args ):
|
|||
if current_syntax == syntax:
|
||||
return
|
||||
|
||||
for win in args:
|
||||
with LetCurrentWindow( win ):
|
||||
for buf in args:
|
||||
with LetCurrentBuffer( buf ):
|
||||
# We use set syn= because just setting vim.Buffer.options[ 'syntax' ]
|
||||
# doesn't actually trigger the Syntax autocommand, and i'm not sure that
|
||||
# 'doautocmd Syntax' is the right solution or not
|
||||
vim.command( 'set syntax={}'.format( Escape( syntax ) ) )
|
||||
|
||||
return syntax
|
||||
|
|
|
|||
|
|
@ -16,15 +16,11 @@
|
|||
import abc
|
||||
import vim
|
||||
import logging
|
||||
from collections import namedtuple
|
||||
from functools import partial
|
||||
import typing
|
||||
|
||||
from vimspector import utils
|
||||
|
||||
View = namedtuple( 'View', [ 'win', 'lines', 'draw' ] )
|
||||
|
||||
|
||||
|
||||
class Expandable:
|
||||
"""Base for anything which might contain a hierarchy of values represented by
|
||||
|
|
@ -104,7 +100,6 @@ class Variable( Expandable ):
|
|||
self.variable = variable
|
||||
|
||||
|
||||
|
||||
class Watch:
|
||||
"""Holds a user watch expression (DAP request) and the result (WatchResult)"""
|
||||
def __init__( self, expression: dict ):
|
||||
|
|
@ -114,29 +109,43 @@ class Watch:
|
|||
self.result = None
|
||||
|
||||
|
||||
class View:
|
||||
lines: typing.Dict[ int, Expandable ]
|
||||
draw: typing.Callable
|
||||
|
||||
def __init__( self, win, lines, draw ):
|
||||
self.lines = lines
|
||||
self.draw = draw
|
||||
self.buf = win.buffer
|
||||
|
||||
utils.SetUpUIWindow( win )
|
||||
|
||||
|
||||
class VariablesView( object ):
|
||||
def __init__( self, connection, variables_win, watches_win ):
|
||||
self._logger = logging.getLogger( __name__ )
|
||||
utils.SetUpLogging( self._logger )
|
||||
|
||||
self._vars = View( variables_win, {}, self._DrawScopes )
|
||||
self._watch = View( watches_win, {}, self._DrawWatches )
|
||||
self._connection = connection
|
||||
self._current_syntax = ''
|
||||
|
||||
# Allows us to hit <CR> to expand/collapse variables
|
||||
with utils.LetCurrentWindow( self._vars.win ):
|
||||
# Set up the "Variables" buffer in the variables_win
|
||||
self._scopes: typing.List[ Scope ] = []
|
||||
self._vars = View( variables_win, {}, self._DrawScopes )
|
||||
utils.SetUpHiddenBuffer( self._vars.buf, 'vimspector.Variables' )
|
||||
with utils.LetCurrentWindow( variables_win ):
|
||||
vim.command(
|
||||
'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>' )
|
||||
|
||||
# List of current scopes of type Scope
|
||||
self._scopes: typing.List[ 'Scope' ] = []
|
||||
|
||||
# List of current Watches of type Watch
|
||||
self._watches: typing.List[ 'Watch' ] = []
|
||||
|
||||
# Allows us to hit <CR> to expand/collapse variables
|
||||
with utils.LetCurrentWindow( self._watch.win ):
|
||||
# Set up the "Watches" buffer in the watches_win (and create a WinBar in
|
||||
# there)
|
||||
self._watches: typing.List[ Watch ] = []
|
||||
self._watch = View( watches_win, {}, self._DrawWatches )
|
||||
utils.SetUpPromptBuffer( self._watch.buf,
|
||||
'vimspector.Watches',
|
||||
'Expression: ',
|
||||
'vimspector#AddWatchPrompt' )
|
||||
with utils.LetCurrentWindow( watches_win ):
|
||||
vim.command(
|
||||
'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>' )
|
||||
vim.command(
|
||||
|
|
@ -149,15 +158,7 @@ class VariablesView( object ):
|
|||
vim.command( 'nnoremenu 1.3 WinBar.Delete '
|
||||
':call vimspector#DeleteWatch()<CR>' )
|
||||
|
||||
utils.SetUpScratchBuffer( self._vars.win.buffer, 'vimspector.Variables' )
|
||||
utils.SetUpPromptBuffer( self._watch.win.buffer,
|
||||
'vimspector.Watches',
|
||||
'Expression: ',
|
||||
'vimspector#AddWatchPrompt' )
|
||||
|
||||
utils.SetUpUIWindow( self._vars.win )
|
||||
utils.SetUpUIWindow( self._watch.win )
|
||||
|
||||
# Set the (global!) balloon expr if supported
|
||||
has_balloon = int( vim.eval( "has( 'balloon_eval' )" ) )
|
||||
has_balloon_term = int( vim.eval( "has( 'balloon_eval_term' )" ) )
|
||||
|
||||
|
|
@ -181,10 +182,10 @@ class VariablesView( object ):
|
|||
self._is_term = not bool( int( vim.eval( "has( 'gui_running' )" ) ) )
|
||||
|
||||
def Clear( self ):
|
||||
with utils.ModifiableScratchBuffer( self._vars.win.buffer ):
|
||||
utils.ClearBuffer( self._vars.win.buffer )
|
||||
with utils.ModifiableScratchBuffer( self._watch.win.buffer ):
|
||||
utils.ClearBuffer( self._watch.win.buffer )
|
||||
with utils.ModifiableScratchBuffer( self._vars.buf ):
|
||||
utils.ClearBuffer( self._vars.buf )
|
||||
with utils.ModifiableScratchBuffer( self._watch.buf ):
|
||||
utils.ClearBuffer( self._watch.buf )
|
||||
self._current_syntax = ''
|
||||
|
||||
def ConnectionUp( self, connection ):
|
||||
|
|
@ -198,8 +199,8 @@ class VariablesView( object ):
|
|||
for k, v in self._oldoptions.items():
|
||||
vim.options[ k ] = v
|
||||
|
||||
vim.command( 'bdelete! ' + str( self._watch.win.buffer.number ) )
|
||||
vim.command( 'bdelete! ' + str( self._vars.win.buffer.number ) )
|
||||
utils.CleanUpHiddenBuffer( self._vars.buf )
|
||||
utils.CleanUpHiddenBuffer( self._watch.buf )
|
||||
|
||||
def LoadScopes( self, frame ):
|
||||
def scopes_consumer( message ):
|
||||
|
|
@ -256,8 +257,8 @@ class VariablesView( object ):
|
|||
self.EvaluateWatches()
|
||||
|
||||
def DeleteWatch( self ):
|
||||
if vim.current.window != self._watch.win:
|
||||
utils.UserMessage( 'Not a watch window' )
|
||||
if vim.current.buffer != self._watch.buf:
|
||||
utils.UserMessage( 'Not a watch buffer' )
|
||||
return
|
||||
|
||||
current_line = vim.current.window.cursor[ 0 ]
|
||||
|
|
@ -305,9 +306,9 @@ class VariablesView( object ):
|
|||
self._DrawWatches()
|
||||
|
||||
def ExpandVariable( self ):
|
||||
if vim.current.window == self._vars.win:
|
||||
if vim.current.buffer == self._vars.buf:
|
||||
view = self._vars
|
||||
elif vim.current.window == self._watch.win:
|
||||
elif vim.current.buffer == self._watch.buf:
|
||||
view = self._watch
|
||||
else:
|
||||
return
|
||||
|
|
@ -341,7 +342,7 @@ class VariablesView( object ):
|
|||
assert indent > 0
|
||||
for variable in variables:
|
||||
line = utils.AppendToBuffer(
|
||||
view.win.buffer,
|
||||
view.buf,
|
||||
'{indent}{marker}{icon} {name} ({type_}): {value}'.format(
|
||||
# We borrow 1 space of indent to draw the change marker
|
||||
indent = ' ' * ( indent - 1 ),
|
||||
|
|
@ -363,8 +364,8 @@ class VariablesView( object ):
|
|||
# However it is pretty inefficient.
|
||||
self._vars.lines.clear()
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.ModifiableScratchBuffer( self._vars.win.buffer ):
|
||||
utils.ClearBuffer( self._vars.win.buffer )
|
||||
with utils.ModifiableScratchBuffer( self._vars.buf ):
|
||||
utils.ClearBuffer( self._vars.buf )
|
||||
for scope in self._scopes:
|
||||
self._DrawScope( 0, scope )
|
||||
|
||||
|
|
@ -374,11 +375,11 @@ class VariablesView( object ):
|
|||
# However it is pretty inefficient.
|
||||
self._watch.lines.clear()
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.ModifiableScratchBuffer( self._watch.win.buffer ):
|
||||
utils.ClearBuffer( self._watch.win.buffer )
|
||||
utils.AppendToBuffer( self._watch.win.buffer, 'Watches: ----' )
|
||||
with utils.ModifiableScratchBuffer( self._watch.buf ):
|
||||
utils.ClearBuffer( self._watch.buf )
|
||||
utils.AppendToBuffer( self._watch.buf, 'Watches: ----' )
|
||||
for watch in self._watches:
|
||||
line = utils.AppendToBuffer( self._watch.win.buffer,
|
||||
line = utils.AppendToBuffer( self._watch.buf,
|
||||
'Expression: '
|
||||
+ watch.expression[ 'expression' ] )
|
||||
watch.line = line
|
||||
|
|
@ -387,7 +388,7 @@ class VariablesView( object ):
|
|||
def _DrawScope( self, indent, scope ):
|
||||
icon = '+' if scope.IsExpandable() and not scope.IsExpandedByUser() else '-'
|
||||
|
||||
line = utils.AppendToBuffer( self._vars.win.buffer,
|
||||
line = utils.AppendToBuffer( self._vars.buf,
|
||||
'{0}{1} Scope: {2}'.format(
|
||||
' ' * indent,
|
||||
icon,
|
||||
|
|
@ -413,7 +414,7 @@ class VariablesView( object ):
|
|||
icon = icon,
|
||||
result = watch.result.result.get( 'result', '<unknown>' ) )
|
||||
|
||||
line = utils.AppendToBuffer( self._watch.win.buffer, line.split( '\n' ) )
|
||||
line = utils.AppendToBuffer( self._watch.buf, line.split( '\n' ) )
|
||||
self._watch.lines[ line ] = watch.result
|
||||
|
||||
if watch.result.ShouldDrawDrillDown():
|
||||
|
|
@ -495,7 +496,7 @@ class VariablesView( object ):
|
|||
def SetSyntax( self, syntax ):
|
||||
self._current_syntax = utils.SetSyntax( self._current_syntax,
|
||||
syntax,
|
||||
self._vars.win,
|
||||
self._watch.win )
|
||||
self._vars.buf,
|
||||
self._watch.buf )
|
||||
|
||||
# vim: sw=2
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@
|
|||
"classPaths": [ "${workspaceRoot}/target/classes" ],
|
||||
"args": "hello world!",
|
||||
"stopOnEntry": true,
|
||||
"console": "integratedTerminal"
|
||||
"console": "integratedTerminal",
|
||||
"stepFilters": {
|
||||
"skipClasses": [ "$$JDK" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Java Attach": {
|
||||
|
|
@ -19,7 +22,10 @@
|
|||
"sourcePaths": [ "${workspaceRoot}/src/main/java" ],
|
||||
"stopOnEntry": true,
|
||||
"hostName": "localhost",
|
||||
"port": "${JVMDebugPort}"
|
||||
"port": "${JVMDebugPort}",
|
||||
"stepFilters": {
|
||||
"skipClasses": [ "$$JDK" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Attach with vscode-javac": {
|
||||
|
|
|
|||
24
support/test/java/test_project/java.vim
Normal file
24
support/test/java/test_project/java.vim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
let g:ycm_java_jdtls_extension_path = [
|
||||
\ expand( '<sfile>:p:h:h:h:h:h' ) . '/gadgets/macos'
|
||||
\ ]
|
||||
|
||||
let s:jdt_ls_debugger_port = 0
|
||||
function! s:StartDebugging()
|
||||
if s:jdt_ls_debugger_port <= 0
|
||||
" Get the DAP port
|
||||
let s:jdt_ls_debugger_port = youcompleteme#GetCommandResponse(
|
||||
\ 'ExecuteCommand',
|
||||
\ 'vscode.java.startDebugSession' )
|
||||
|
||||
if s:jdt_ls_debugger_port == ''
|
||||
echom "Unable to get DAP port - is YCM initialized?"
|
||||
let s:jdt_ls_debugger_port = 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
" Start debugging with the DAP port
|
||||
call vimspector#LaunchWithSettings( { 'DAPPort': s:jdt_ls_debugger_port } )
|
||||
endfunction
|
||||
|
||||
nnoremap <silent> <buffer> <Leader><F5> :call <SID>StartDebugging()<CR>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<artifactId>TestApplication</artifactId>
|
||||
<version>1</version>
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.vimspector.test;
|
||||
|
||||
class Base {
|
||||
public String DoSomething()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,16 @@ public class TestApplication {
|
|||
}
|
||||
}
|
||||
|
||||
private static class TestGeneric<T extends Base > {
|
||||
T t;
|
||||
public TestGeneric( T t ) {
|
||||
this.t = t;
|
||||
}
|
||||
public void DoSomethingUseful() {
|
||||
System.out.println( t.DoSomething() );
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends Base> void DoGeneric( T b ) {
|
||||
TestGeneric<T> foo = new TestGeneric<>( b );
|
||||
foo.DoSomethingUseful();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue