From 6a1c9a6b52103e438dd228a2427fff92af55cee5 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Sun, 17 May 2020 19:15:39 +0100 Subject: [PATCH 1/4] Enable embedded vim python debugging This allows us to use vimspector to debug vimspector. The idea is that in Vim you call 'py3 from vimspector.developer import SetUpDebugpy; SetUpDebugpy()' and then just attach to localhost:5678 using the new multi-session mode support. Oof. --- .vimspector.json | 14 +++++++++++ python3/vimspector/developer.py | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 .vimspector.json create mode 100644 python3/vimspector/developer.py diff --git a/.vimspector.json b/.vimspector.json new file mode 100644 index 0000000..4a9889e --- /dev/null +++ b/.vimspector.json @@ -0,0 +1,14 @@ +{ + "configurations": { + "Python: Attach To Vim": { + "variables": { + "port": "5678", + "host": "localhost" + }, + "adapter": "multi-session", + "configuration": { + "request": "attach" + } + } + } +} diff --git a/python3/vimspector/developer.py b/python3/vimspector/developer.py new file mode 100644 index 0000000..4945e6a --- /dev/null +++ b/python3/vimspector/developer.py @@ -0,0 +1,42 @@ +# vimspector - A multi-language debugging system for Vim +# Copyright 2020 Ben Jackson +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import sys +import os + +from vimspector import install, utils + + +def SetUpDebugpy( wait=False, port=5678 ): + sys.path.insert( + 1, + os.path.join( install.GetGadgetDir( utils.GetVimspectorBase(), + install.GetOS() ), + 'debugpy', + 'build', + 'lib' ) ) + import debugpy + + exe = sys.executable + try: + # debugpy uses sys.executable (which is `vim`, so we hack it) + sys.executable = 'python3' + debugpy.listen( port ) + finally: + sys.executable = exe + + if wait: + debugpy.wait_for_client() From 8c4112cd1f4fbb310576efb14ba7eb82ee5da09e Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Tue, 12 May 2020 19:29:17 +0100 Subject: [PATCH 2/4] breakpoints list: fix listing while debugging Also, open the quickfix list when listing breakpoints, and add a test --- python3/vimspector/breakpoints.py | 5 +- python3/vimspector/debug_session.py | 8 +++- tests/breakpoints.test.vim | 74 +++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/python3/vimspector/breakpoints.py b/python3/vimspector/breakpoints.py index ea50fd6..b6a975d 100644 --- a/python3/vimspector/breakpoints.py +++ b/python3/vimspector/breakpoints.py @@ -82,7 +82,7 @@ class ProjectBreakpoints( object ): # FIXME: If the adapter type changes, we should probably forget this ? - def ListBreakpoints( self ): + def BreakpointsAsQuickFix( self ): # FIXME: Handling of breakpoints is a mess, split between _codeView and this # object. This makes no sense and should be centralised so that we don't # have this duplication and bug factory. @@ -115,7 +115,8 @@ class ProjectBreakpoints( object ): bp[ 'options' ] ), } ) - vim.eval( 'setqflist( {} )'.format( json.dumps( qf ) ) ) + return qf + def ClearBreakpoints( self ): # These are the user-entered breakpoints. diff --git a/python3/vimspector/debug_session.py b/python3/vimspector/debug_session.py index 5d07f46..c434c5a 100644 --- a/python3/vimspector/debug_session.py +++ b/python3/vimspector/debug_session.py @@ -979,7 +979,13 @@ class DebugSession( object ): self._stackTraceView.OnStopped( event ) def ListBreakpoints( self ): - return self._breakpoints.ListBreakpoints() + if self._connection: + qf = self._codeView.BreakpointsAsQuickFix() + else: + qf = self._breakpoints.BreakpointsAsQuickFix() + + vim.eval( 'setqflist( {} )'.format( json.dumps( qf ) ) ) + vim.command( 'copen' ) def ToggleBreakpoint( self, options ): return self._breakpoints.ToggleBreakpoint( options ) diff --git a/tests/breakpoints.test.vim b/tests/breakpoints.test.vim index fe3b303..0d2fa6c 100644 --- a/tests/breakpoints.test.vim +++ b/tests/breakpoints.test.vim @@ -452,3 +452,77 @@ endfunction " %bwipeout! " throw "xfail cpptools doesn't seem to honour conditions on function bps" " endfunction + +function! s:CheckQuickFixEntries( entries ) + let qf = getqflist() + let i = 0 + for entry in a:entries + if i >= len( qf ) + call assert_report( "Expected more quickfix entries" ) + endif + for key in keys( entry ) + call assert_equal( entry[ key ], + \ qf[ i ][ key ], + \ key . ' in ' . string( qf[ i ] ) + \ . ' expected ' . entry[ key ] ) + endfor + let i = i+1 + endfor +endfunction + +function! Test_ListBreakpoints() + lcd testdata/cpp/simple + edit simple.cpp + call setpos( '.', [ 0, 15, 1 ] ) + + call vimspector#ListBreakpoints() + wincmd p + cclose + call s:CheckQuickFixEntries( [] ) + + call vimspector#ToggleBreakpoint() + call assert_equal( [], getqflist() ) + + call vimspector#ListBreakpoints() + call s:CheckQuickFixEntries( [ + \ { 'lnum': 15, 'col': 1, 'bufnr': bufnr( 'simple.cpp', 0 ) } + \ ] ) + + " Cursor jumps to the quickfix window + call assert_equal( 'quickfix', &buftype ) + cclose + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 ) + + call vimspector#Launch() + " break on main + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 ) + + call vimspector#ListBreakpoints() + call s:CheckQuickFixEntries( [ + \ { 'lnum': 15, 'col': 1, 'bufnr': bufnr( 'simple.cpp', 0 ) } + \ ] ) + call assert_equal( 'quickfix', &buftype ) + wincmd p + cclose + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 ) + + " Add a breakpoint that moves (from line 5 to line 9) + call cursor( [ 5, 1 ] ) + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 5, 1 ) + call vimspector#ToggleBreakpoint() + + function! Check() + call vimspector#ListBreakpoints() + wincmd p + return assert_equal( 2, len( getqflist() ) ) + endfunction + call WaitForAssert( function( 'Check' ) ) + + call s:CheckQuickFixEntries( [ + \ { 'lnum': 15, 'col': 1, 'bufnr': bufnr( 'simple.cpp', 0 ) }, + \ { 'lnum': 9, 'col': 1, 'bufnr': bufnr( 'simple.cpp', 0 ) }, + \ ] ) + + call vimspector#test#setup#Reset() + %bwipe! +endfunction From 58a95402c4056ffdae2ae5d102dda60770b66aa0 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Sun, 17 May 2020 19:25:12 +0100 Subject: [PATCH 3/4] Use gloabl for test args as i always use a basedir now --- compiler/vimspector_test.vim | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/vimspector_test.vim b/compiler/vimspector_test.vim index a347f3b..18ef9ae 100644 --- a/compiler/vimspector_test.vim +++ b/compiler/vimspector_test.vim @@ -90,7 +90,9 @@ function! s:RunTestUnderCursor() let l:cwd = getcwd() execute 'lcd ' . s:root_dir try - execute s:make_cmd . ' ' . get( b:, 'test_args', '' ) . ' ' . l:test_arg + execute s:make_cmd . ' ' + \ . get( g:, 'vimspector_test_args', '' ) . ' ' + \ . l:test_arg finally execute 'lcd ' . l:cwd endtry @@ -101,7 +103,9 @@ function! s:RunTest() let l:cwd = getcwd() execute 'lcd ' . s:root_dir try - execute s:make_cmd . ' ' . get( b:, 'test_args', '' ) . ' %:p:t' + execute s:make_cmd . ' ' + \ . get( g:, 'vimspector_test_args', '' ) + \ . ' %:p:t' finally execute 'lcd ' . l:cwd endtry @@ -112,7 +116,8 @@ function! s:RunAllTests() let l:cwd = getcwd() execute 'lcd ' . s:root_dir try - execute s:make_cmd . ' ' . get( b:, 'test_args', '' ) + execute s:make_cmd . ' ' + \ . get( g:, 'vimspector_test_args', '' ) finally execute 'lcd ' . l:cwd endtry From 5f11fe4e6e1b75a490e074854b568ac6ae75974f Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Mon, 18 May 2020 19:24:34 +0100 Subject: [PATCH 4/4] Fix up vint errors --- azure-pipelines.yml | 2 +- compiler/vimspector_test.vim | 8 +++++--- tests/breakpoints.test.vim | 2 +- tests/lib/run_test.vim | 3 +++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f30e84d..5dc944a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -28,7 +28,7 @@ stages: - bash: pip3 install -r dev_requirements.txt displayName: "Install requirements" - - bash: $HOME/.local/bin/vint autoload/ plugin/ tests/ + - bash: $HOME/.local/bin/vint autoload/ compiler/ plugin/ tests/ displayName: "Run vint" - job: 'linux' diff --git a/compiler/vimspector_test.vim b/compiler/vimspector_test.vim index 18ef9ae..8ccd734 100644 --- a/compiler/vimspector_test.vim +++ b/compiler/vimspector_test.vim @@ -13,12 +13,14 @@ " See the License for the specific language governing permissions and " limitations under the License. +scriptencoding utf-8 + " Compiler plugin to help running vimspector tests -if exists("current_compiler") +if exists('current_compiler') finish endif -let current_compiler = "vimspector_test" +let current_compiler = 'vimspector_test' setlocal errorformat= \Found\ errors\ in\ %f:%.%#: @@ -80,7 +82,7 @@ function! s:RunTestUnderCursor() let l:test_func_name = s:GetCurrentFunction() if l:test_func_name ==# '' - echo "No test method found" + echo 'No test method found' return endif diff --git a/tests/breakpoints.test.vim b/tests/breakpoints.test.vim index 0d2fa6c..689ed4b 100644 --- a/tests/breakpoints.test.vim +++ b/tests/breakpoints.test.vim @@ -458,7 +458,7 @@ function! s:CheckQuickFixEntries( entries ) let i = 0 for entry in a:entries if i >= len( qf ) - call assert_report( "Expected more quickfix entries" ) + call assert_report( 'Expected more quickfix entries' ) endif for key in keys( entry ) call assert_equal( entry[ key ], diff --git a/tests/lib/run_test.vim b/tests/lib/run_test.vim index e03a1d4..fca26a6 100644 --- a/tests/lib/run_test.vim +++ b/tests/lib/run_test.vim @@ -46,13 +46,16 @@ call ch_logfile( 'debuglog', 'w' ) " For consistency run all tests with 'nocompatible' set. " This also enables use of line continuation. +" vint: Workaround for https://github.com/Vimjas/vint/issues/363 " vint: -ProhibitSetNoCompatible set nocompatible " vint: +ProhibitSetNoCompatible " Use utf-8 by default, instead of whatever the system default happens to be. " Individual tests can overrule this at the top of the file. +" vint: -ProhibitEncodingOptionAfterScriptEncoding set encoding=utf-8 +" vint: +ProhibitEncodingOptionAfterScriptEncoding " Avoid stopping at the "hit enter" prompt set nomore