From 5c8143a710a99a691ce4fc53900d37b68800b9df Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Mon, 8 Mar 2021 23:00:45 +0000 Subject: [PATCH] Add vertical (i.e. narrow) layout This puts the 3 utility windows at the top, horizontally split, with the code view below. The terminal window is drawn either vertically split (if there's room) or horizontally split otherwise. The output window remains at tht bottom. We add equivalent sizing options too, setting some defauts that roughly work on my macbook pro. By default we switch to the narrow layout if there are fewer than 160 columns, but this can be overridden by setting g:vimspector_ui_mode. --- python3/vimspector/debug_session.py | 72 +++++++++++++++++++++++++++++ python3/vimspector/settings.py | 19 ++++++-- python3/vimspector/terminal.py | 23 ++++++++- 3 files changed, 107 insertions(+), 7 deletions(-) diff --git a/python3/vimspector/debug_session.py b/python3/vimspector/debug_session.py index 03874f3..e3f5530 100644 --- a/python3/vimspector/debug_session.py +++ b/python3/vimspector/debug_session.py @@ -661,6 +661,18 @@ class DebugSession( object ): vim.command( 'tab split' ) self._uiTab = vim.current.tabpage + mode = settings.Get( 'ui_mode' ) + + if mode == 'auto': + mode = 'vertical' if vim.options[ 'columns' ] < 160 else 'horizontal' + + if mode == 'vertical': + self._SetUpUIVertical() + else: + self._SetUpUIHorizontal() + + + def _SetUpUIHorizontal( self ): # Code window code_window = vim.current.window self._codeView = code.CodeView( code_window, self._api_prefix ) @@ -701,6 +713,66 @@ class DebugSession( object ): # TODO: If/when we support multiple sessions, we'll need some way to # indicate which tab was created and store all the tabs vim.vars[ 'vimspector_session_windows' ] = { + 'mode': 'horizontal', + 'tabpage': self._uiTab.number, + 'code': utils.WindowID( code_window, self._uiTab ), + 'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ), + 'variables': utils.WindowID( vars_window, self._uiTab ), + 'watches': utils.WindowID( watch_window, self._uiTab ), + 'output': utils.WindowID( output_window, self._uiTab ), + 'eval': None # this is going to be updated every time eval popup is opened + } + with utils.RestoreCursorPosition(): + with utils.RestoreCurrentWindow(): + with utils.RestoreCurrentBuffer( vim.current.window ): + vim.command( 'doautocmd User VimspectorUICreated' ) + + + def _SetUpUIVertical( self ): + # Code window + code_window = vim.current.window + self._codeView = code.CodeView( code_window, self._api_prefix ) + + # Call stack + vim.command( + f'topleft { settings.Int( "topbar_height" ) }new' ) + stack_trace_window = vim.current.window + one_third = int( vim.eval( 'winwidth( 0 )' ) ) / 3 + self._stackTraceView = stack_trace.StackTraceView( self, + stack_trace_window ) + + + # Watches + vim.command( 'leftabove vertical new' ) + watch_window = vim.current.window + + # Variables + vim.command( 'leftabove vertical new' ) + vars_window = vim.current.window + + + with utils.LetCurrentWindow( vars_window ): + vim.command( f'{ one_third }wincmd |' ) + with utils.LetCurrentWindow( watch_window ): + vim.command( f'{ one_third }wincmd |' ) + with utils.LetCurrentWindow( stack_trace_window ): + vim.command( f'{ one_third }wincmd |' ) + + self._variablesView = variables.VariablesView( vars_window, + watch_window ) + + + # Output/logging + vim.current.window = code_window + vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' ) + output_window = vim.current.window + self._outputView = output.DAPOutputView( output_window, + self._api_prefix ) + + # TODO: If/when we support multiple sessions, we'll need some way to + # indicate which tab was created and store all the tabs + vim.vars[ 'vimspector_session_windows' ] = { + 'mode': 'vertical', 'tabpage': self._uiTab.number, 'code': utils.WindowID( code_window, self._uiTab ), 'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ), diff --git a/python3/vimspector/settings.py b/python3/vimspector/settings.py index 9ad9e41..e9e76ea 100644 --- a/python3/vimspector/settings.py +++ b/python3/vimspector/settings.py @@ -20,11 +20,20 @@ from vimspector import utils DEFAULTS = { # UI - 'bottombar_height': 10, - 'sidebar_width': 50, - 'code_minwidth': 82, - 'terminal_maxwidth': 80, - 'terminal_minwidth': 10, + 'ui_mode': 'auto', + 'bottombar_height': 10, + + # For ui_mode = 'horizontal': + 'sidebar_width': 50, + 'code_minwidth': 82, + 'terminal_maxwidth': 80, + 'terminal_minwidth': 10, + + # For ui_mode = 'vertical': + 'topbar_height': 15, + 'code_minheight': 20, + 'terminal_maxheight': 15, + 'terminal_minheight': 5, # Signs 'sign_priority': { diff --git a/python3/vimspector/terminal.py b/python3/vimspector/terminal.py index 6ffd56a..305c8ff 100644 --- a/python3/vimspector/terminal.py +++ b/python3/vimspector/terminal.py @@ -23,7 +23,16 @@ def LaunchTerminal( api_prefix, env = params.get( 'env' ) or {} term_options = { - 'vertical': 1, + # Use a vsplit in widw mode, and a horizontal split in narrow mode + 'vertical': ( + # Use a vsplit if we're in horizontal mode, or if we're in vertical mode, + # but there's enough space for the code and the terminal horizontally + # (this gives more vertical space, which becomes at at premium) + vim.vars[ 'vimspector_session_windows' ][ 'mode' ] == 'horizontal' or + vim.options[ 'columns' ] >= ( + settings.Int( 'terminal_maxwidth' ) + settings.Int( 'code_minwidth' ) + ) + ), 'norestore': 1, 'cwd': cwd, 'env': env, @@ -50,13 +59,23 @@ def LaunchTerminal( api_prefix, # If we're making a vertical split from the code window, make it no more # than 80 columns and no fewer than 10. Also try and keep the code window # at least 82 columns - if term_options[ 'vertical' ] and not term_options.get( 'curwin', 0 ): + if term_options.get( 'curwin', 0 ): + pass + elif term_options[ 'vertical' ]: term_options[ 'term_cols' ] = max( min ( int( vim.eval( 'winwidth( 0 )' ) ) - settings.Int( 'code_minwidth' ), settings.Int( 'terminal_maxwidth' ) ), settings.Int( 'terminal_minwidth' ) ) + else: + term_options[ 'term_rows' ] = max( + min ( int( vim.eval( 'winheight( 0 )' ) ) + - settings.Int( 'code_minheight' ), + settings.Int( 'terminal_maxheight' ) ), + settings.Int( 'terminal_minheight' ) + ) + buffer_number = int( utils.Call(