Fix - don't switch windows/buffers to create a new hidden buffer

This commit is contained in:
Ben Jackson 2020-07-22 09:36:32 +01:00
commit 98bef3db03
5 changed files with 155 additions and 58 deletions

View file

@ -20,29 +20,47 @@ set cpoptions&vim
" }}} " }}}
call vimspector#internal#state#Reset() let s:enabled = vimspector#internal#state#Reset()
function! vimspector#Launch() abort function! vimspector#Launch() abort
if !s:enabled
return
endif
py3 _vimspector_session.Start() py3 _vimspector_session.Start()
endfunction endfunction
function! vimspector#LaunchWithSettings( settings ) abort function! vimspector#LaunchWithSettings( settings ) abort
if !s:enabled
return
endif
py3 _vimspector_session.Start( launch_variables = vim.eval( 'a:settings' ) ) py3 _vimspector_session.Start( launch_variables = vim.eval( 'a:settings' ) )
endfunction endfunction
function! vimspector#Reset() abort function! vimspector#Reset() abort
if !s:enabled
return
endif
py3 _vimspector_session.Reset() py3 _vimspector_session.Reset()
endfunction endfunction
function! vimspector#Restart() abort function! vimspector#Restart() abort
if !s:enabled
return
endif
py3 _vimspector_session.Restart() py3 _vimspector_session.Restart()
endfunction endfunction
function! vimspector#ClearBreakpoints() abort function! vimspector#ClearBreakpoints() abort
if !s:enabled
return
endif
py3 _vimspector_session.ClearBreakpoints() py3 _vimspector_session.ClearBreakpoints()
endfunction endfunction
function! vimspector#ToggleBreakpoint( ... ) abort function! vimspector#ToggleBreakpoint( ... ) abort
if !s:enabled
return
endif
if a:0 == 0 if a:0 == 0
let options = {} let options = {}
else else
@ -52,6 +70,9 @@ function! vimspector#ToggleBreakpoint( ... ) abort
endfunction endfunction
function! vimspector#AddFunctionBreakpoint( function, ... ) abort function! vimspector#AddFunctionBreakpoint( function, ... ) abort
if !s:enabled
return
endif
if a:0 == 0 if a:0 == 0
let options = {} let options = {}
else else
@ -62,42 +83,72 @@ function! vimspector#AddFunctionBreakpoint( function, ... ) abort
endfunction endfunction
function! vimspector#StepOver() abort function! vimspector#StepOver() abort
if !s:enabled
return
endif
py3 _vimspector_session.StepOver() py3 _vimspector_session.StepOver()
endfunction endfunction
function! vimspector#StepInto() abort function! vimspector#StepInto() abort
if !s:enabled
return
endif
py3 _vimspector_session.StepInto() py3 _vimspector_session.StepInto()
endfunction endfunction
function! vimspector#StepOut() abort function! vimspector#StepOut() abort
if !s:enabled
return
endif
py3 _vimspector_session.StepOut() py3 _vimspector_session.StepOut()
endfunction endfunction
function! vimspector#Continue() abort function! vimspector#Continue() abort
if !s:enabled
return
endif
py3 _vimspector_session.Continue() py3 _vimspector_session.Continue()
endfunction endfunction
function! vimspector#Pause() abort function! vimspector#Pause() abort
if !s:enabled
return
endif
py3 _vimspector_session.Pause() py3 _vimspector_session.Pause()
endfunction endfunction
function! vimspector#Stop() abort function! vimspector#Stop() abort
if !s:enabled
return
endif
py3 _vimspector_session.Stop() py3 _vimspector_session.Stop()
endfunction endfunction
function! vimspector#ExpandVariable() abort function! vimspector#ExpandVariable() abort
if !s:enabled
return
endif
py3 _vimspector_session.ExpandVariable() py3 _vimspector_session.ExpandVariable()
endfunction endfunction
function! vimspector#DeleteWatch() abort function! vimspector#DeleteWatch() abort
if !s:enabled
return
endif
py3 _vimspector_session.DeleteWatch() py3 _vimspector_session.DeleteWatch()
endfunction endfunction
function! vimspector#GoToFrame() abort function! vimspector#GoToFrame() abort
if !s:enabled
return
endif
py3 _vimspector_session.ExpandFrameOrThread() py3 _vimspector_session.ExpandFrameOrThread()
endfunction endfunction
function! vimspector#AddWatch( ... ) abort function! vimspector#AddWatch( ... ) abort
if !s:enabled
return
endif
if a:0 == 0 if a:0 == 0
let expr = input( 'Enter watch expression: ' ) let expr = input( 'Enter watch expression: ' )
else else
@ -112,27 +163,42 @@ function! vimspector#AddWatch( ... ) abort
endfunction endfunction
function! vimspector#AddWatchPrompt( expr ) abort function! vimspector#AddWatchPrompt( expr ) abort
if !s:enabled
return
endif
stopinsert stopinsert
setlocal nomodified setlocal nomodified
call vimspector#AddWatch( a:expr ) call vimspector#AddWatch( a:expr )
endfunction endfunction
function! vimspector#Evaluate( expr ) abort function! vimspector#Evaluate( expr ) abort
if !s:enabled
return
endif
py3 _vimspector_session.ShowOutput( 'Console' ) py3 _vimspector_session.ShowOutput( 'Console' )
py3 _vimspector_session.EvaluateConsole( vim.eval( 'a:expr' ) ) py3 _vimspector_session.EvaluateConsole( vim.eval( 'a:expr' ) )
endfunction endfunction
function! vimspector#EvaluateConsole( expr ) abort function! vimspector#EvaluateConsole( expr ) abort
if !s:enabled
return
endif
stopinsert stopinsert
setlocal nomodified setlocal nomodified
py3 _vimspector_session.EvaluateConsole( vim.eval( 'a:expr' ) ) py3 _vimspector_session.EvaluateConsole( vim.eval( 'a:expr' ) )
endfunction endfunction
function! vimspector#ShowOutput( category ) abort function! vimspector#ShowOutput( category ) abort
if !s:enabled
return
endif
py3 _vimspector_session.ShowOutput( vim.eval( 'a:category' ) ) py3 _vimspector_session.ShowOutput( vim.eval( 'a:category' ) )
endfunction endfunction
function! vimspector#ShowOutputInWindow( win_id, category ) abort function! vimspector#ShowOutputInWindow( win_id, category ) abort
if !s:enabled
return
endif
py3 __import__( 'vimspector', py3 __import__( 'vimspector',
\ fromlist = [ 'output' ] ).output.ShowOutputInWindow( \ fromlist = [ 'output' ] ).output.ShowOutputInWindow(
\ int( vim.eval( 'a:win_id' ) ), \ int( vim.eval( 'a:win_id' ) ),
@ -140,16 +206,25 @@ function! vimspector#ShowOutputInWindow( win_id, category ) abort
endfunction endfunction
function! vimspector#ListBreakpoints() abort function! vimspector#ListBreakpoints() abort
if !s:enabled
return
endif
py3 _vimspector_session.ListBreakpoints() py3 _vimspector_session.ListBreakpoints()
endfunction endfunction
function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort
if !s:enabled
return
endif
let buffers = py3eval( '_vimspector_session.GetOutputBuffers() ' let buffers = py3eval( '_vimspector_session.GetOutputBuffers() '
\ . ' if _vimspector_session else []' ) \ . ' if _vimspector_session else []' )
return join( buffers, "\n" ) return join( buffers, "\n" )
endfunction endfunction
function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
if !s:enabled
return
endif
return join( py3eval( '_vimspector_session.GetCompletionsSync( ' return join( py3eval( '_vimspector_session.GetCompletionsSync( '
\.' vim.eval( "a:CmdLine" ),' \.' vim.eval( "a:CmdLine" ),'
\.' int( vim.eval( "a:CursorPos" ) ) )' \.' int( vim.eval( "a:CursorPos" ) ) )'
@ -158,6 +233,9 @@ function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
endfunction endfunction
function! vimspector#Install( ... ) abort function! vimspector#Install( ... ) abort
if !s:enabled
return
endif
if a:0 < 1 if a:0 < 1
return return
endif endif
@ -169,6 +247,9 @@ function! vimspector#Install( ... ) abort
endfunction endfunction
function! vimspector#CompleteInstall( ArgLead, CmdLine, CursorPos ) abort function! vimspector#CompleteInstall( ArgLead, CmdLine, CursorPos ) abort
if !s:enabled
return
endif
return py3eval( '"\n".join(' return py3eval( '"\n".join('
\ . '__import__( "vimspector", fromlist = [ "gadgets" ] )' \ . '__import__( "vimspector", fromlist = [ "gadgets" ] )'
\ . '.gadgets.GADGETS.keys() ' \ . '.gadgets.GADGETS.keys() '

View file

@ -25,11 +25,21 @@ if has( 'nvim' )
endif endif
function! vimspector#internal#state#Reset() abort function! vimspector#internal#state#Reset() abort
py3 << EOF try
import vim py3 import vim
from vimspector import debug_session py3 _vimspector_session = __import__(
_vimspector_session = debug_session.DebugSession( vim.eval( 's:prefix' ) ) \ "vimspector",
EOF \ fromlist=[ "debug_session" ] ).debug_session.DebugSession(
\ vim.eval( 's:prefix' ) )
catch /.*/
echohl WarningMsg
echom 'Exception while loading vimspector:' v:exception
echom 'Vimspector unavailable: Requires Vim compiled with Python 3.6'
echohl None
return v:false
endtry
return v:true
endfunction endfunction
function! vimspector#internal#state#GetAPIPrefix() abort function! vimspector#internal#state#GetAPIPrefix() abort

View file

@ -90,7 +90,6 @@ def RunInstaller( api_prefix, *args, **kwargs ):
vimspector_home = utils.GetVimString( vim.vars, 'vimspector_home' ) vimspector_home = utils.GetVimString( vim.vars, 'vimspector_home' )
vimspector_base_dir = utils.GetVimspectorBase() vimspector_base_dir = utils.GetVimspectorBase()
# TODO: Translate the arguments to something more user-friendly than -- args
global OUTPUT_VIEW global OUTPUT_VIEW
if OUTPUT_VIEW: if OUTPUT_VIEW:
OUTPUT_VIEW.Reset() OUTPUT_VIEW.Reset()

View file

@ -52,6 +52,8 @@ def ShowOutputInWindow( win_id, category ):
class OutputView( object ): class OutputView( object ):
"""Container for a 'tabbed' window of buffers that can be used to display
files or the output of commands."""
def __init__( self, window, api_prefix ): def __init__( self, window, api_prefix ):
self._window = window self._window = window
self._buffers = {} self._buffers = {}
@ -144,75 +146,73 @@ class OutputView( object ):
file_name = None, file_name = None,
cmd = None, cmd = None,
completion_handler = None ): completion_handler = None ):
win = self._window if file_name is not None:
if not win.valid: assert cmd is None
# We need to borrow the current window if install.GetOS() == "windows":
win = vim.current.window # FIXME: Can't display fiels in windows (yet?)
return
with utils.LetCurrentWindow( win ): cmd = [ 'tail', '-F', '-n', '+1', '--', file_name ]
with utils.RestoreCurrentBuffer( win ):
if file_name is not None: if cmd is not None:
assert cmd is None out = utils.SetUpCommandBuffer(
if install.GetOS() == "windows": cmd,
# FIXME: Can't display fiels in windows (yet?) category,
return self._api_prefix,
completion_handler = completion_handler )
self._buffers[ category ] = TabBuffer( out, len( self._buffers ) )
self._buffers[ category ].is_job = True
self._RenderWinBar( category )
else:
if category == 'Console':
name = 'vimspector.Console'
else:
name = 'vimspector.Output:{0}'.format( category )
cmd = [ 'tail', '-F', '-n', '+1', '--', file_name ] tab_buffer = TabBuffer( utils.NewEmptyBuffer(), len( self._buffers ) )
self._buffers[ category ] = tab_buffer
if cmd is not None: if category == 'Console':
out = utils.SetUpCommandBuffer( utils.SetUpPromptBuffer( tab_buffer.buf,
cmd, name,
category, '> ',
self._api_prefix, 'vimspector#EvaluateConsole' )
completion_handler = completion_handler ) else:
self._buffers[ category ] = TabBuffer( out, len( self._buffers ) ) utils.SetUpHiddenBuffer( tab_buffer.buf, name )
self._buffers[ category ].is_job = True
self._RenderWinBar( category )
else:
vim.command( 'enew' )
tab_buffer = TabBuffer( vim.current.buffer, len( self._buffers ) )
self._buffers[ category ] = tab_buffer
if category == 'Console':
utils.SetUpPromptBuffer( tab_buffer.buf,
'vimspector.Console',
'> ',
'vimspector#EvaluateConsole' )
else:
utils.SetUpHiddenBuffer(
tab_buffer.buf,
'vimspector.Output:{0}'.format( category ) )
self._RenderWinBar( category ) self._RenderWinBar( category )
def _RenderWinBar( self, category ): def _RenderWinBar( self, category ):
if not self._window.valid: if not self._window.valid:
return return
tab_buffer = self._buffers[ category ] with utils.LetCurrentWindow( self._window ):
tab_buffer = self._buffers[ category ]
try: try:
if tab_buffer.flag: if tab_buffer.flag:
vim.command( 'nunmenu WinBar.{}'.format( utils.Escape( category ) ) ) vim.command( 'nunmenu WinBar.{}'.format( utils.Escape( category ) ) )
else: else:
vim.command( 'nunmenu WinBar.{}*'.format( utils.Escape( category ) ) ) vim.command( 'nunmenu WinBar.{}*'.format( utils.Escape( category ) ) )
except vim.error as e: except vim.error as e:
# E329 means the menu doesn't exist; ignore that. # E329 means the menu doesn't exist; ignore that.
if 'E329' not in str( e ): if 'E329' not in str( e ):
raise raise
vim.command( "nnoremenu 1.{0} WinBar.{1}{2} " vim.command(
":call vimspector#ShowOutputInWindow( {3}, '{1}' )<CR>".format( "nnoremenu 1.{0} WinBar.{1}{2} "
tab_buffer.index, ":call vimspector#ShowOutputInWindow( {3}, '{1}' )<CR>".format(
utils.Escape( category ), tab_buffer.index,
'*' if tab_buffer.flag else '', utils.Escape( category ),
utils.WindowID( self._window ) ) ) '*' if tab_buffer.flag else '',
utils.WindowID( self._window ) ) )
def GetCategories( self ): def GetCategories( self ):
return list( self._buffers.keys() ) return list( self._buffers.keys() )
class DAPOutputView( OutputView ): class DAPOutputView( OutputView ):
"""Specialised OutputView which adds the DAP Console (REPL)"""
def __init__( self, *args ): def __init__( self, *args ):
super().__init__( *args ) super().__init__( *args )

View file

@ -52,6 +52,12 @@ def BufferForFile( file_name ):
return vim.buffers[ BufferNumberForFile( file_name ) ] return vim.buffers[ BufferNumberForFile( file_name ) ]
def NewEmptyBuffer():
bufnr = int( vim.eval( 'bufadd("")' ) )
Call( 'bufload', bufnr )
return vim.buffers[ bufnr ]
def WindowForBuffer( buf ): def WindowForBuffer( buf ):
for w in vim.current.tabpage.windows: for w in vim.current.tabpage.windows:
if w.buffer == buf: if w.buffer == buf:
@ -353,6 +359,7 @@ def AskForInput( prompt, default_value = None ):
def AppendToBuffer( buf, line_or_lines, modified=False ): def AppendToBuffer( buf, line_or_lines, modified=False ):
line = 1
try: try:
# After clearing the buffer (using buf[:] = None) there is always a single # After clearing the buffer (using buf[:] = None) there is always a single
# empty line in the buffer object and no "is empty" method. # empty line in the buffer object and no "is empty" method.