diff --git a/README.md b/README.md index e3a5ad5..bf84d2f 100644 --- a/README.md +++ b/README.md @@ -1007,6 +1007,8 @@ be changed manually to "switch to" that thread. to set the "focussed" thread to the currently selected one. If the selected line is a stack frame, set the focussed thread to the thread of that frame and jump to that frame in the code window. +* The current frame when a breakpoint is hit or if manuall jumping is also + highlighted. ![stack trace](https://puremourning.github.io/vimspector-web/img/vimspector-callstack-window.png) @@ -1700,22 +1702,26 @@ Vimsector uses them, they will not be replaced. So to customise the signs, define them in your `vimrc`. -| Sign | Description | Priority | -|------------------------|-------------------------------------|----------| -| `vimspectorBP` | Line breakpoint | 9 | -| `vimspectorBPCond` | Conditional line breakpoint | 9 | -| `vimspectorBPDisabled` | Disabled breakpoint | 9 | -| `vimspectorPC` | Program counter (i.e. current line) | 200 | -| `vimspectorPCBP` | Program counter and breakpoint | 200 | +| Sign | Description | Priority | +|---------------------------|-----------------------------------------|----------| +| `vimspectorBP` | Line breakpoint | 9 | +| `vimspectorBPCond` | Conditional line breakpoint | 9 | +| `vimspectorBPDisabled` | Disabled breakpoint | 9 | +| `vimspectorPC` | Program counter (i.e. current line) | 200 | +| `vimspectorPCBP` | Program counter and breakpoint | 200 | +| `vimspectorCurrentThread` | Focussed thread in stack trace view | 200 | +| `vimspectorCurrentFrame` | Current stack frame in stack trace view | 200 | The default symbols are the equivalent of something like the following: ```viml -sign define vimspectorBP text=\ ● texthl=WarningMsg -sign define vimspectorBPCond text=\ ◆ texthl=WarningMsg -sign define vimspectorBPDisabled text=\ ● texthl=LineNr -sign define vimspectorPC text=\ ▶ texthl=MatchParen linehl=CursorLine -sign define vimspectorPCBP text=●▶ texthl=MatchParen linehl=CursorLine +sign define vimspectorBP text=\ ● texthl=WarningMsg +sign define vimspectorBPCond text=\ ◆ texthl=WarningMsg +sign define vimspectorBPDisabled text=\ ● texthl=LineNr +sign define vimspectorPC text=\ ▶ texthl=MatchParen linehl=CursorLine +sign define vimspectorPCBP text=●▶ texthl=MatchParen linehl=CursorLine +sign define vimspectorCurrentThread text=▶ texthl=MatchParen linehl=CursorLine +sign define vimspectorCurrentFrame text=▶ texthl=Special linehl=CursorLine ``` If the signs don't display properly, your font probably doesn't contain these @@ -1723,11 +1729,13 @@ glyphs. You can easily change them by defining the sign in your vimrc. For example, you could put this in your `vimrc` to use some simple ASCII symbols: ```viml -sign define vimspectorBP text=o texthl=WarningMsg -sign define vimspectorBPCond text=o? texthl=WarningMsg -sign define vimspectorBPDisabled text=o! texthl=LineNr -sign define vimspectorPC text=\ > texthl=MatchParen -sign define vimspectorPCBP text=o> texthl=MatchParen +sign define vimspectorBP text=o texthl=WarningMsg +sign define vimspectorBPCond text=o? texthl=WarningMsg +sign define vimspectorBPDisabled text=o! texthl=LineNr +sign define vimspectorPC text=\ > texthl=MatchParen +sign define vimspectorPCBP text=o> texthl=MatchParen +sign define vimspectorCurrentThread text=> texthl=MatchParen +sign define vimspectorCurrentFrame text=> texthl=Special ``` ## Sign priority diff --git a/python3/vimspector/settings.py b/python3/vimspector/settings.py index a060543..89378af 100644 --- a/python3/vimspector/settings.py +++ b/python3/vimspector/settings.py @@ -42,7 +42,8 @@ DEFAULTS = { 'vimspectorBP': 9, 'vimspectorBPCond': 9, 'vimspectorBPDisabled': 9, - 'vimspectorCurrentThread': 200 + 'vimspectorCurrentThread': 200, + 'vimspectorCurrentFrame': 200, }, # Installer diff --git a/python3/vimspector/stack_trace.py b/python3/vimspector/stack_trace.py index ae14e68..f9540ba 100644 --- a/python3/vimspector/stack_trace.py +++ b/python3/vimspector/stack_trace.py @@ -102,7 +102,8 @@ class StackTraceView( object ): self._scratch_buffers = [] # FIXME: This ID is by group, so should be module scope - self._next_sign_id = 1 + self._current_thread_sign_id = 0 # 1 when used + self._current_frame_sign_id = 0 # 2 when used utils.SetUpHiddenBuffer( self._buf, 'vimspector.StackTrace' ) utils.SetUpUIWindow( win ) @@ -127,6 +128,7 @@ class StackTraceView( object ): ':call vimspector#SetCurrentThread()' ) win.options[ 'cursorline' ] = False + win.options[ 'signcolumn' ] = 'auto' if not signs.SignDefined( 'vimspectorCurrentThread' ): @@ -136,6 +138,13 @@ class StackTraceView( object ): texthl = 'MatchParen', linehl = 'CursorLine' ) + if not signs.SignDefined( 'vimspectorCurrentFrame' ): + signs.DefineSign( 'vimspectorCurrentFrame', + text = '▶ ', + double_text = '▶', + texthl = 'Special', + linehl = 'CursorLine' ) + self._line_to_frame = {} self._line_to_thread = {} @@ -157,9 +166,12 @@ class StackTraceView( object ): self._sources = {} self._requesting_threads = StackTraceView.ThreadRequestState.NO self._pending_thread_request = None - if self._next_sign_id: - signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' ) - self._next_sign_id = 0 + if self._current_thread_sign_id: + signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' ) + self._current_thread_sign_id = 0 + if self._current_frame_sign_id: + signs.UnplaceSign( self._current_frame_sign_id, 'VimspectorStackTrace' ) + self._current_frame_sign_id = 0 with utils.ModifiableScratchBuffer( self._buf ): utils.ClearBuffer( self._buf ) @@ -273,10 +285,10 @@ class StackTraceView( object ): self._line_to_frame.clear() self._line_to_thread.clear() - if self._next_sign_id: - signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' ) + if self._current_thread_sign_id: + signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' ) else: - self._next_sign_id = 1 + self._current_thread_sign_id = 1 with utils.ModifiableScratchBuffer( self._buf ): with utils.RestoreCursorPosition(): @@ -290,7 +302,7 @@ class StackTraceView( object ): f'({thread.State()})' ) if self._current_thread == thread.id: - signs.PlaceSign( self._next_sign_id, + signs.PlaceSign( self._current_thread_sign_id, 'VimspectorStackTrace', 'vimspectorCurrentThread', self._buf.name, @@ -421,6 +433,7 @@ class StackTraceView( object ): # Should this set the current _Thread_ too ? If i jump to a frame in # Thread 2, should that become the focussed thread ? self._current_frame = frame + self._DrawThreads() return self._session.SetCurrentFrame( self._current_frame, reason ) return False @@ -518,6 +531,11 @@ class StackTraceView( object ): if not thread.IsExpanded(): return + if self._current_frame_sign_id: + signs.UnplaceSign( self._current_frame_sign_id, 'VimspectorStackTrace' ) + else: + self._current_frame_sign_id = 2 + for frame in thread.stacktrace: if frame.get( 'source' ): source = frame[ 'source' ] @@ -542,6 +560,13 @@ class StackTraceView( object ): source[ 'name' ], frame[ 'line' ] ) ) + if self._current_frame[ 'id' ] == frame[ 'id' ]: + signs.PlaceSign( self._current_frame_sign_id, + 'VimspectorStackTrace', + 'vimspectorCurrentFrame', + self._buf.name, + line ) + self._line_to_frame[ line ] = ( thread, frame ) def _ResolveSource( self, source, and_then ): diff --git a/support/test/cpp/simple_c_program/.ycm_extra_conf.py b/support/test/cpp/simple_c_program/.ycm_extra_conf.py index 0d17586..4203b36 100644 --- a/support/test/cpp/simple_c_program/.ycm_extra_conf.py +++ b/support/test/cpp/simple_c_program/.ycm_extra_conf.py @@ -1,4 +1,4 @@ def Settings( **kwargs ): return { - 'flags': [ '-x', 'c++', '-Wall', '-Wextra' ] + 'flags': [ '-x', 'c++', '-Wall', '-Wextra', '-std=c++17' ] } diff --git a/tests/stack_trace.test.vim b/tests/stack_trace.test.vim index a65ea5e..f191201 100644 --- a/tests/stack_trace.test.vim +++ b/tests/stack_trace.test.vim @@ -379,6 +379,20 @@ function! Test_UpDownStack() \ '$' ) \ ) \ } ) + call win_gotoid( g:vimspector_session_windows.stack_trace ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 1, + \ 'vimspectorCurrentThread', + \ 200 ) } ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 2, + \ 'vimspectorCurrentFrame', + \ 200 ) } ) + wincmd w call vimspector#DownFrame() call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 ) @@ -396,6 +410,21 @@ function! Test_UpDownStack() \ '$' ) \ ) \ } ) + call win_gotoid( g:vimspector_session_windows.stack_trace ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 1, + \ 'vimspectorCurrentThread', + \ 200 ) } ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 2, + \ 'vimspectorCurrentFrame', + \ 200 ) } ) + wincmd w + call vimspector#UpFrame() call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 ) @@ -413,6 +442,21 @@ function! Test_UpDownStack() \ '$' ) \ ) \ } ) + call win_gotoid( g:vimspector_session_windows.stack_trace ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 1, + \ 'vimspectorCurrentThread', + \ 200 ) } ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 3, + \ 'vimspectorCurrentFrame', + \ 200 ) } ) + wincmd w + call feedkeys( "\VimspectorUpFrame", 'x' ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 23, 1 ) @@ -430,6 +474,21 @@ function! Test_UpDownStack() \ '$' ) \ ) \ } ) + call win_gotoid( g:vimspector_session_windows.stack_trace ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 1, + \ 'vimspectorCurrentThread', + \ 200 ) } ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 4, + \ 'vimspectorCurrentFrame', + \ 200 ) } ) + wincmd w + call feedkeys( "\VimspectorDownFrame", 'x' ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 ) @@ -447,6 +506,21 @@ function! Test_UpDownStack() \ '$' ) \ ) \ } ) + call win_gotoid( g:vimspector_session_windows.stack_trace ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 1, + \ 'vimspectorCurrentThread', + \ 200 ) } ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 3, + \ 'vimspectorCurrentFrame', + \ 200 ) } ) + wincmd w + call vimspector#DownFrame() call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 ) @@ -464,6 +538,21 @@ function! Test_UpDownStack() \ '$' ) \ ) \ } ) + call win_gotoid( g:vimspector_session_windows.stack_trace ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 1, + \ 'vimspectorCurrentThread', + \ 200 ) } ) + call WaitForAssert( { -> + \ vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorStackTrace', + \ 2, + \ 'vimspectorCurrentFrame', + \ 200 ) } ) + wincmd w + call vimspector#ClearBreakpoints()