autoload/handlers.vim | 2 +- autoload/symbol.vim | 15 +++++++++++++-- test/unit_tests.vim | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/autoload/handlers.vim b/autoload/handlers.vim index f6804165a830443aa607e743a86fd4990316b585..a83f9cdb3b38291731f6d1e330d87b7734e39f15 100644 --- a/autoload/handlers.vim +++ b/autoload/handlers.vim @@ -124,7 +124,7 @@ else location = reply.result endif - symbol.GotoSymbol(lspserver, location) + symbol.GotoSymbol(lspserver, location, req.method) enddef # process the 'textDocument/signatureHelp' reply from the LSP server diff --git a/autoload/symbol.vim b/autoload/symbol.vim index 4240f621098aaac3a8c126cf3a7f1163a6cfa465..812fe0284529a1ac8d4e2414dd1870db1d2fc6e3 100644 --- a/autoload/symbol.vim +++ b/autoload/symbol.vim @@ -211,9 +211,20 @@ # Jump to the definition, declaration or implementation of a symbol. # Also, used to peek at the definition, declaration or implementation of a # symbol. -export def GotoSymbol(lspserver: dict, location: dict) +export def GotoSymbol(lspserver: dict, location: dict, type: string) if location->empty() - util.WarnMsg("Error: definition is not found") + var msg: string + if type ==# 'textDocument/declaration' + msg = 'Error: declaration is not found' + elseif type ==# 'textDocument/typeDefinition' + msg = 'Error: type definition is not found' + elseif type ==# 'textDocument/implementation' + msg = 'Error: implementation is not found' + else + msg = 'Error: definition is not found' + endif + + util.WarnMsg(msg) if !lspserver.peekSymbol # pop the tag stack var tagstack: dict = gettagstack() diff --git a/test/unit_tests.vim b/test/unit_tests.vim index 5c9ececf6bffd12f72a104195bb14c98a2f7fb13..3e9590c5e812e78551941a94f72e979b00a521a4 100644 --- a/test/unit_tests.vim +++ b/test/unit_tests.vim @@ -389,6 +389,75 @@ assert_equal([4, 5, 6, 5], [line("'<"), col("'<"), line("'>"), col("'>")]) :%bw! enddef +# Test for LSP goto symobl definition, declaration and implementation +def Test_lsp_goto_definition() + silent! edit Xtest.cpp + var lines: list =<< trim END + #include + using namespace std; + + class base { + public: + virtual void print(); + }; + + void base::print() + { + } + + class derived : public base { + public: + void print() {} + }; + + void f1(void) + { + base *bp; + derived d; + bp = &d; + + bp->print(); + } + END + setline(1, lines) + :sleep 500m + cursor(24, 6) + :LspGotoDeclaration + :sleep 500m + assert_equal([6, 19], [line('.'), col('.')]) + exe "normal! \" + assert_equal([24, 6], [line('.'), col('.')]) + :LspGotoDefinition + :sleep 500m + assert_equal([9, 12], [line('.'), col('.')]) + exe "normal! \" + assert_equal([24, 6], [line('.'), col('.')]) + :LspGotoImpl + :sleep 500m + assert_equal([15, 11], [line('.'), col('.')]) + exe "normal! \" + assert_equal([24, 6], [line('.'), col('.')]) + + # Error cases + :messages clear + cursor(14, 5) + :LspGotoDeclaration + sleep 500m + var m = execute('messages')->split("\n") + assert_equal('Error: declaration is not found', m[1]) + :messages clear + :LspGotoDefinition + sleep 500m + m = execute('messages')->split("\n") + assert_equal('Error: definition is not found', m[1]) + :messages clear + :LspGotoImpl + sleep 500m + m = execute('messages')->split("\n") + assert_equal('Error: implementation is not found', m[1]) + :%bw! +enddef + def LspRunTests() :set nomore :set debug=beep