From: Yegappan Lakshmanan Date: Wed, 12 Jan 2022 03:42:28 +0000 (-0800) Subject: Move the workspace-wide symbol search functions to symbolsearch.vim X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=1ed85cf4249af8ccb08b9c1980ac948a0b304770;p=vim-lsp.git Move the workspace-wide symbol search functions to symbolsearch.vim --- diff --git a/autoload/lsp.vim b/autoload/lsp.vim index 26793c9..2ff45a5 100644 --- a/autoload/lsp.vim +++ b/autoload/lsp.vim @@ -2,16 +2,23 @@ vim9script # Vim9 LSP client +# Needs Vim 8.2.2342 and higher +if v:version < 802 || !has('patch-8.2.2342') + finish +endif + var opt = {} var lserver = {} var util = {} var diag = {} +var symbol = {} if has('patch-8.2.4019') import './lspoptions.vim' as opt_import import './lspserver.vim' as server_import import './util.vim' as util_import import './diag.vim' as diag_import + import './symbolsearch.vim' as symbolsearch_import opt.LspOptionsSet = opt_import.LspOptionsSet opt.lspOptions = opt_import.lspOptions @@ -28,6 +35,7 @@ if has('patch-8.2.4019') diag.ShowCurrentDiag = diag_import.ShowCurrentDiag diag.LspDiagsJump = diag_import.LspDiagsJump diag.DiagRemoveFile = diag_import.DiagRemoveFile + symbol.ShowSymbolMenu = symbolsearch_import.ShowSymbolMenu else import {lspOptions, LspOptionsSet} from './lspoptions.vim' import NewLspServer from './lspserver.vim' @@ -43,6 +51,7 @@ else ShowAllDiags, ShowCurrentDiag, LspDiagsJump} from './diag.vim' + import {ShowSymbolMenu} from './symbolsearch.vim' opt.LspOptionsSet = LspOptionsSet opt.lspOptions = lspOptions @@ -59,11 +68,7 @@ else diag.ShowAllDiags = ShowAllDiags diag.ShowCurrentDiag = ShowCurrentDiag diag.LspDiagsJump = LspDiagsJump -endif - -# Needs Vim 8.2.2342 and higher -if v:version < 802 || !has('patch-8.2.2342') - finish + symbol.ShowSymbolMenu = ShowSymbolMenu endif # LSP server information @@ -1153,135 +1158,6 @@ def lsp#codeAction() lspserver.codeAction(fname) enddef -# Handle keys pressed when the workspace symbol popup menu is displayed -def s:filterSymbols(lspsrv: dict, popupID: number, key: string): bool - var key_handled: bool = false - var update_popup: bool = false - var query: string = lspsrv.workspaceSymbolQuery - - if key == "\" || key == "\" - # Erase one character from the filter text - if query->len() >= 1 - query = query[: -2] - update_popup = true - endif - key_handled = true - elseif key == "\" - # clear the filter text - query = '' - update_popup = true - key_handled = true - elseif key == "\" - || key == "\" - || key == "\" - || key == "\" - || key == "\" - || key == "\" - || key == "\" - || key == "\" - # scroll the popup window - var cmd: string = 'normal! ' .. (key == "\" ? 'j' : key == "\" ? 'k' : key) - win_execute(popupID, cmd) - key_handled = true - elseif key == "\" || key == "\" - # Use native Vim handling for these keys - key_handled = false - elseif key =~ '^\f$' || key == "\" - # Filter the names based on the typed key and keys typed before - query ..= key - update_popup = true - key_handled = true - endif - - if update_popup - # Update the popup with the new list of symbol names - popupID->popup_settext('') - if query != '' - lspsrv.workspaceQuery(query) - else - []->setwinvar(popupID, 'LspSymbolTable') - endif - echo 'Symbol: ' .. query - endif - - # Update the workspace symbol query string - lspsrv.workspaceSymbolQuery = query - - if key_handled - return true - endif - - return popupID->popup_filter_menu(key) -enddef - -# Jump to the location of a symbol selected in the popup menu -def s:jumpToWorkspaceSymbol(popupID: number, result: number): void - # clear the message displayed at the command-line - echo '' - - if result <= 0 - # popup is canceled - return - endif - - var symTbl: list> = popupID->getwinvar('LspSymbolTable', []) - if symTbl->empty() - return - endif - try - # Save the current location in the tag stack - util.PushCursorToTagStack() - - # if the selected file is already present in a window, then jump to it - var fname: string = symTbl[result - 1].file - var winList: list = fname->bufnr()->win_findbuf() - if winList->len() == 0 - # Not present in any window - if &modified || &buftype != '' - # the current buffer is modified or is not a normal buffer, then open - # the file in a new window - exe "split " .. symTbl[result - 1].file - else - exe "confirm edit " .. symTbl[result - 1].file - endif - else - winList[0]->win_gotoid() - endif - setcursorcharpos(symTbl[result - 1].pos.line + 1, - symTbl[result - 1].pos.character + 1) - catch - # ignore exceptions - endtry -enddef - -# display a list of symbols from the workspace -def s:showSymbolMenu(lspsrv: dict, query: string) - # Create the popup menu - var lnum = &lines - &cmdheight - 2 - 10 - var popupAttr = { - title: 'Workspace Symbol Search', - wrap: 0, - pos: 'topleft', - line: lnum, - col: 2, - minwidth: 60, - minheight: 10, - maxheight: 10, - maxwidth: 60, - mapping: false, - fixed: 1, - close: "button", - filter: function('s:filterSymbols', [lspsrv]), - callback: function('s:jumpToWorkspaceSymbol') - } - lspsrv.workspaceSymbolPopup = popup_menu([], popupAttr) - lspsrv.workspaceSymbolQuery = query - prop_type_add('lspworkspacesymbol', - {bufnr: lspsrv.workspaceSymbolPopup->winbufnr(), - highlight: 'Title'}) - echo 'Symbol: ' .. query -enddef - # Perform a workspace wide symbol lookup # Uses LSP "workspace/symbol" request def lsp#symbolSearch(queryArg: string) @@ -1314,7 +1190,7 @@ def lsp#symbolSearch(queryArg: string) endif redraw! - s:showSymbolMenu(lspserver, query) + symbol.ShowSymbolMenu(lspserver, query) if !lspserver.workspaceQuery(query) lspserver.workspaceSymbolPopup->popup_close() diff --git a/autoload/symbolsearch.vim b/autoload/symbolsearch.vim new file mode 100644 index 0000000..3d46354 --- /dev/null +++ b/autoload/symbolsearch.vim @@ -0,0 +1,144 @@ +vim9script + +# Functions for the LSP symbol menu and for searching symbols across the +# workspace. + +var util = {} + +if has('patch-8.2.4019') + import './util.vim' as util_import + util.PushCursorToTagStack = util_import.PushCursorToTagStack +else + import {PushCursorToTagStack} from './util.vim' + util.PushCursorToTagStack = PushCursorToTagStack +endif + +# Handle keys pressed when the workspace symbol popup menu is displayed +def s:filterSymbols(lspserver: dict, popupID: number, key: string): bool + var key_handled: bool = false + var update_popup: bool = false + var query: string = lspserver.workspaceSymbolQuery + + if key == "\" || key == "\" + # Erase one character from the filter text + if query->len() >= 1 + query = query[: -2] + update_popup = true + endif + key_handled = true + elseif key == "\" + # clear the filter text + query = '' + update_popup = true + key_handled = true + elseif key == "\" + || key == "\" + || key == "\" + || key == "\" + || key == "\" + || key == "\" + || key == "\" + || key == "\" + # scroll the popup window + var cmd: string = 'normal! ' .. (key == "\" ? 'j' : key == "\" ? 'k' : key) + win_execute(popupID, cmd) + key_handled = true + elseif key == "\" || key == "\" + # Use native Vim handling for these keys + key_handled = false + elseif key =~ '^\f$' || key == "\" + # Filter the names based on the typed key and keys typed before + query ..= key + update_popup = true + key_handled = true + endif + + if update_popup + # Update the popup with the new list of symbol names + popupID->popup_settext('') + if query != '' + lspserver.workspaceQuery(query) + else + []->setwinvar(popupID, 'LspSymbolTable') + endif + echo 'Symbol: ' .. query + endif + + # Update the workspace symbol query string + lspserver.workspaceSymbolQuery = query + + if key_handled + return true + endif + + return popupID->popup_filter_menu(key) +enddef + +# Jump to the location of a symbol selected in the popup menu +def s:jumpToWorkspaceSymbol(popupID: number, result: number): void + # clear the message displayed at the command-line + echo '' + + if result <= 0 + # popup is canceled + return + endif + + var symTbl: list> = popupID->getwinvar('LspSymbolTable', []) + if symTbl->empty() + return + endif + try + # Save the current location in the tag stack + util.PushCursorToTagStack() + + # if the selected file is already present in a window, then jump to it + var fname: string = symTbl[result - 1].file + var winList: list = fname->bufnr()->win_findbuf() + if winList->len() == 0 + # Not present in any window + if &modified || &buftype != '' + # the current buffer is modified or is not a normal buffer, then open + # the file in a new window + exe "split " .. symTbl[result - 1].file + else + exe "confirm edit " .. symTbl[result - 1].file + endif + else + winList[0]->win_gotoid() + endif + setcursorcharpos(symTbl[result - 1].pos.line + 1, + symTbl[result - 1].pos.character + 1) + catch + # ignore exceptions + endtry +enddef + +# display a list of symbols from the workspace +export def ShowSymbolMenu(lspserver: dict, query: string) + # Create the popup menu + var lnum = &lines - &cmdheight - 2 - 10 + var popupAttr = { + title: 'Workspace Symbol Search', + wrap: 0, + pos: 'topleft', + line: lnum, + col: 2, + minwidth: 60, + minheight: 10, + maxheight: 10, + maxwidth: 60, + mapping: false, + fixed: 1, + close: "button", + filter: function('s:filterSymbols', [lspserver]), + callback: function('s:jumpToWorkspaceSymbol') + } + lspserver.workspaceSymbolPopup = popup_menu([], popupAttr) + lspserver.workspaceSymbolQuery = query + prop_type_add('lspworkspacesymbol', + {bufnr: lspserver.workspaceSymbolPopup->winbufnr(), + highlight: 'Title'}) + echo 'Symbol: ' .. query +enddef +