]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Move the functions to display symbol references and jump to a symbol to a separate...
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sun, 16 Jan 2022 21:57:35 +0000 (13:57 -0800)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Sun, 16 Jan 2022 21:57:35 +0000 (13:57 -0800)
autoload/handlers.vim
autoload/lsp.vim
autoload/symbol.vim [new file with mode: 0644]
autoload/symbolsearch.vim [deleted file]

index 168743e0c4f8576813374b20735d2ef20e5e7e24..67b78651a1aca05680688f92640cb8d5a85fc8a9 100644 (file)
@@ -9,6 +9,7 @@ var util = {}
 var diag = {}
 var outline = {}
 var textedit = {}
+var symbol = {}
 var codeaction = {}
 
 if has('patch-8.2.4019')
@@ -17,6 +18,7 @@ if has('patch-8.2.4019')
   import './diag.vim' as diag_import
   import './outline.vim' as outline_import
   import './textedit.vim' as textedit_import
+  import './symbol.vim' as symbol_import
   import './codeaction.vim' as codeaction_import
 
   opt.lspOptions = opt_import.lspOptions
@@ -29,6 +31,8 @@ if has('patch-8.2.4019')
   outline.UpdateOutlineWindow = outline_import.UpdateOutlineWindow
   textedit.ApplyTextEdits = textedit_import.ApplyTextEdits
   textedit.ApplyWorkspaceEdit = textedit_import.ApplyWorkspaceEdit
+  symbol.ShowReferences = symbol_import.ShowReferences
+  symbol.GotoSymbol = symbol_import.GotoSymbol
   codeaction.ApplyCodeAction = codeaction_import.ApplyCodeAction
 else
   import lspOptions from './lspoptions.vim'
@@ -40,6 +44,7 @@ else
   import DiagNotification from './diag.vim'
   import UpdateOutlineWindow from './outline.vim'
   import {ApplyTextEdits, ApplyWorkspaceEdit} from './textedit.vim'
+  import {ShowReferences, GotoSymbol} from './symbol.vim'
   import ApplyCodeAction from './codeaction.vim'
 
   opt.lspOptions = lspOptions
@@ -52,6 +57,8 @@ else
   outline.UpdateOutlineWindow = UpdateOutlineWindow
   textedit.ApplyTextEdits = ApplyTextEdits
   textedit.ApplyWorkspaceEdit = ApplyWorkspaceEdit
+  symbol.ShowReferences = ShowReferences
+  symbol.GotoSymbol = GotoSymbol
   codeaction.ApplyCodeAction = ApplyCodeAction
 endif
 
@@ -103,75 +110,18 @@ enddef
 # the LSP server
 # Result: Location | Location[] | LocationLink[] | null
 def s:processDefDeclReply(lspserver: dict<any>, req: dict<any>, reply: dict<any>): void
-  if reply.result->empty()
-    util.WarnMsg("Error: definition is not found")
-    if !lspserver.peekSymbol
-      # pop the tag stack
-      var tagstack: dict<any> = gettagstack()
-      if tagstack.length > 0
-        settagstack(winnr(), {curidx: tagstack.length}, 't')
-      endif
-    endif
-    lspserver.peekSymbol = false
-    return
-  endif
-
   var location: dict<any>
   if reply.result->type() == v:t_list
-    location = reply.result[0]
-  else
-    location = reply.result
-  endif
-  var fname = util.LspUriToFile(location.uri)
-  if lspserver.peekSymbol
-    # open the definition/declaration in the preview window and highlight the
-    # matching symbol
-    exe 'pedit ' .. fname
-    var cur_wid = win_getid()
-    wincmd P
-    var pvwbuf = bufnr()
-    setcursorcharpos(location.range.start.line + 1,
-                       location.range.start.character + 1)
-    silent! matchdelete(101)
-    var pos: list<number> = []
-    var start_col: number
-    var end_col: number
-    start_col = util.GetLineByteFromPos(pvwbuf, location.range.start) + 1
-    end_col = util.GetLineByteFromPos(pvwbuf, location.range.end) + 1
-    pos->add(location.range.start.line + 1)
-    pos->extend([start_col, end_col - start_col])
-    matchaddpos('Search', [pos], 10, 101)
-    win_gotoid(cur_wid)
-  else
-    # jump to the file and line containing the symbol
-    var wid = fname->bufwinid()
-    if wid != -1
-      wid->win_gotoid()
+    if !reply.result->empty()
+      location = reply.result[0]
     else
-      var bnr: number = fname->bufnr()
-      if bnr != -1
-        if &modified || &buftype != ''
-          exe 'sbuffer ' .. bnr
-        else
-          exe 'buf ' .. bnr
-        endif
-      else
-        if &modified || &buftype != ''
-          # if the current buffer has unsaved changes, then open the file in a
-          # new window
-          exe 'split ' .. fname
-        else
-          exe 'edit  ' .. fname
-        endif
-      endif
+      location = {}
     endif
-    # Set the previous cursor location mark
-    setpos("'`", getcurpos())
-    setcursorcharpos(location.range.start.line + 1,
-                       location.range.start.character + 1)
+  else
+    location = reply.result
   endif
-  redraw!
-  lspserver.peekSymbol = false
+
+  symbol.GotoSymbol(lspserver, location)
 enddef
 
 # process the 'textDocument/signatureHelp' reply from the LSP server
@@ -420,50 +370,7 @@ enddef
 # process the 'textDocument/references' reply from the LSP server
 # Result: Location[] | null
 def s:processReferencesReply(lspserver: dict<any>, req: dict<any>, reply: dict<any>): void
-  if reply.result->empty()
-    util.WarnMsg('Error: No references found')
-    lspserver.peekSymbol = false
-    return
-  endif
-
-  # create a quickfix list with the location of the references
-  var locations: list<dict<any>> = reply.result
-  var qflist: list<dict<any>> = []
-  for loc in locations
-    var fname: string = util.LspUriToFile(loc.uri)
-    var bnr: number = fname->bufnr()
-    if bnr == -1
-      bnr = fname->bufadd()
-    endif
-    if !bnr->bufloaded()
-      bnr->bufload()
-    endif
-    var text: string = bnr->getbufline(loc.range.start.line + 1)[0]
-                                               ->trim("\t ", 1)
-    qflist->add({filename: fname,
-                       lnum: loc.range.start.line + 1,
-                       col: util.GetLineByteFromPos(bnr, loc.range.start) + 1,
-                       text: text})
-  endfor
-
-  var save_winid = win_getid()
-  if lspserver.peekSymbol
-    silent! pedit
-    wincmd P
-  endif
-  setloclist(0, [], ' ', {title: 'Symbol Reference', items: qflist})
-  var mods: string = ''
-  if lspserver.peekSymbol
-    # When peeking the references, open the location list in a vertically
-    # split window to the right and make the location list window 30% of the
-    # source window width
-    mods = 'belowright vert :' .. (winwidth(0) * 30) / 100
-  endif
-  exe mods .. 'lopen'
-  if !opt.lspOptions.keepFocusInReferences
-    save_winid->win_gotoid()
-  endif
-  lspserver.peekSymbol = false
+  symbol.ShowReferences(lspserver, reply.result)
 enddef
 
 # process the 'textDocument/documentHighlight' reply from the LSP server
index cdb65941e31687d50bd14d9736fa27da61ba5451..a30df2ab7c1b5c6643e6f59e3a5e55a1fc27e2f1 100644 (file)
@@ -19,7 +19,7 @@ if has('patch-8.2.4019')
   import './lspserver.vim' as server_import
   import './util.vim' as util_import
   import './diag.vim' as diag_import
-  import './symbolsearch.vim' as symbolsearch_import
+  import './symbol.vim' as symbol_import
   import './outline.vim' as outline_import
 
   opt.LspOptionsSet = opt_import.LspOptionsSet
@@ -37,7 +37,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
+  symbol.ShowSymbolMenu = symbol_import.ShowSymbolMenu
   outline.OpenOutlineWindow = outline_import.OpenOutlineWindow
   outline.SkipOutlineRefresh = outline_import.SkipOutlineRefresh
 else
@@ -55,7 +55,7 @@ else
        ShowAllDiags,
        ShowCurrentDiag,
        LspDiagsJump} from './diag.vim'
-  import ShowSymbolMenu from './symbolsearch.vim'
+  import ShowSymbolMenu from './symbol.vim'
   import {OpenOutlineWindow, SkipOutlineRefresh} from './outline.vim'
 
   opt.LspOptionsSet = LspOptionsSet
diff --git a/autoload/symbol.vim b/autoload/symbol.vim
new file mode 100644 (file)
index 0000000..4240f62
--- /dev/null
@@ -0,0 +1,280 @@
+vim9script
+
+# Functions for dealing with symbols.
+#   - LSP symbol menu and for searching symbols across the workspace.
+#   - show symbol references
+#   - jump to a symbol definition, declaration, type definition or
+#     implementation
+
+var opt = {}
+var util = {}
+
+if has('patch-8.2.4019')
+  import './lspoptions.vim' as opt_import
+  import './util.vim' as util_import
+
+  opt.lspOptions = opt_import.lspOptions
+  util.PushCursorToTagStack = util_import.PushCursorToTagStack
+  util.WarnMsg = util_import.WarnMsg
+  util.LspUriToFile = util_import.LspUriToFile
+  util.GetLineByteFromPos = util_import.GetLineByteFromPos
+else
+  import lspOptions from './lspoptions.vim'
+  import {WarnMsg,
+       LspUriToFile,
+       GetLineByteFromPos,
+       PushCursorToTagStack} from './util.vim'
+
+  opt.lspOptions = lspOptions
+  util.WarnMsg = WarnMsg
+  util.LspUriToFile = LspUriToFile
+  util.GetLineByteFromPos = GetLineByteFromPos
+  util.PushCursorToTagStack = PushCursorToTagStack
+endif
+
+# Handle keys pressed when the workspace symbol popup menu is displayed
+def s:filterSymbols(lspserver: dict<any>, popupID: number, key: string): bool
+  var key_handled: bool = false
+  var update_popup: bool = false
+  var query: string = lspserver.workspaceSymbolQuery
+
+  if key == "\<BS>" || key == "\<C-H>"
+    # Erase one character from the filter text
+    if query->len() >= 1
+      query = query[: -2]
+      update_popup = true
+    endif
+    key_handled = true
+  elseif key == "\<C-U>"
+    # clear the filter text
+    query = ''
+    update_popup = true
+    key_handled = true
+  elseif key == "\<C-F>"
+        || key == "\<C-B>"
+        || key == "\<PageUp>"
+        || key == "\<PageDown>"
+        || key == "\<C-Home>"
+        || key == "\<C-End>"
+        || key == "\<C-N>"
+        || key == "\<C-P>"
+    # scroll the popup window
+    var cmd: string = 'normal! ' .. (key == "\<C-N>" ? 'j' : key == "\<C-P>" ? 'k' : key)
+    win_execute(popupID, cmd)
+    key_handled = true
+  elseif key == "\<Up>" || key == "\<Down>"
+    # Use native Vim handling for these keys
+    key_handled = false
+  elseif key =~ '^\f$' || key == "\<Space>"
+    # 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<dict<any>> = 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<number> = 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<any>, 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
+
+# Display or peek symbol references in a location list
+export def ShowReferences(lspserver: dict<any>, refs: list<dict<any>>)
+  if refs->empty()
+    util.WarnMsg('Error: No references found')
+    lspserver.peekSymbol = false
+    return
+  endif
+
+  # create a location list with the location of the references
+  var qflist: list<dict<any>> = []
+  for loc in refs
+    var fname: string = util.LspUriToFile(loc.uri)
+    var bnr: number = fname->bufnr()
+    if bnr == -1
+      bnr = fname->bufadd()
+    endif
+    if !bnr->bufloaded()
+      bnr->bufload()
+    endif
+    var text: string = bnr->getbufline(loc.range.start.line + 1)[0]
+                                               ->trim("\t ", 1)
+    qflist->add({filename: fname,
+                       lnum: loc.range.start.line + 1,
+                       col: util.GetLineByteFromPos(bnr, loc.range.start) + 1,
+                       text: text})
+  endfor
+
+  var save_winid = win_getid()
+  if lspserver.peekSymbol
+    silent! pedit
+    wincmd P
+  endif
+  setloclist(0, [], ' ', {title: 'Symbol Reference', items: qflist})
+  var mods: string = ''
+  if lspserver.peekSymbol
+    # When peeking the references, open the location list in a vertically
+    # split window to the right and make the location list window 30% of the
+    # source window width
+    mods = 'belowright vert :' .. (winwidth(0) * 30) / 100
+  endif
+  exe mods .. 'lopen'
+  if !opt.lspOptions.keepFocusInReferences
+    save_winid->win_gotoid()
+  endif
+  lspserver.peekSymbol = false
+enddef
+
+# 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<any>, location: dict<any>)
+  if location->empty()
+    util.WarnMsg("Error: definition is not found")
+    if !lspserver.peekSymbol
+      # pop the tag stack
+      var tagstack: dict<any> = gettagstack()
+      if tagstack.length > 0
+        settagstack(winnr(), {curidx: tagstack.length}, 't')
+      endif
+    endif
+    lspserver.peekSymbol = false
+    return
+  endif
+
+  var fname = util.LspUriToFile(location.uri)
+  if lspserver.peekSymbol
+    # open the definition/declaration in the preview window and highlight the
+    # matching symbol
+    exe 'pedit ' .. fname
+    var cur_wid = win_getid()
+    wincmd P
+    var pvwbuf = bufnr()
+    setcursorcharpos(location.range.start.line + 1,
+                       location.range.start.character + 1)
+    silent! matchdelete(101)
+    var pos: list<number> = []
+    var start_col: number
+    var end_col: number
+    start_col = util.GetLineByteFromPos(pvwbuf, location.range.start) + 1
+    end_col = util.GetLineByteFromPos(pvwbuf, location.range.end) + 1
+    pos->add(location.range.start.line + 1)
+    pos->extend([start_col, end_col - start_col])
+    matchaddpos('Search', [pos], 10, 101)
+    win_gotoid(cur_wid)
+  else
+    # jump to the file and line containing the symbol
+    var wid = fname->bufwinid()
+    if wid != -1
+      wid->win_gotoid()
+    else
+      var bnr: number = fname->bufnr()
+      if bnr != -1
+        if &modified || &buftype != ''
+          exe 'sbuffer ' .. bnr
+        else
+          exe 'buf ' .. bnr
+        endif
+      else
+        if &modified || &buftype != ''
+          # if the current buffer has unsaved changes, then open the file in a
+          # new window
+          exe 'split ' .. fname
+        else
+          exe 'edit  ' .. fname
+        endif
+      endif
+    endif
+    # Set the previous cursor location mark
+    setpos("'`", getcurpos())
+    setcursorcharpos(location.range.start.line + 1,
+                       location.range.start.character + 1)
+  endif
+  redraw!
+  lspserver.peekSymbol = false
+enddef
+
+# vim: shiftwidth=2 softtabstop=2
diff --git a/autoload/symbolsearch.vim b/autoload/symbolsearch.vim
deleted file mode 100644 (file)
index cee7266..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-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<any>, popupID: number, key: string): bool
-  var key_handled: bool = false
-  var update_popup: bool = false
-  var query: string = lspserver.workspaceSymbolQuery
-
-  if key == "\<BS>" || key == "\<C-H>"
-    # Erase one character from the filter text
-    if query->len() >= 1
-      query = query[: -2]
-      update_popup = true
-    endif
-    key_handled = true
-  elseif key == "\<C-U>"
-    # clear the filter text
-    query = ''
-    update_popup = true
-    key_handled = true
-  elseif key == "\<C-F>"
-        || key == "\<C-B>"
-        || key == "\<PageUp>"
-        || key == "\<PageDown>"
-        || key == "\<C-Home>"
-        || key == "\<C-End>"
-        || key == "\<C-N>"
-        || key == "\<C-P>"
-    # scroll the popup window
-    var cmd: string = 'normal! ' .. (key == "\<C-N>" ? 'j' : key == "\<C-P>" ? 'k' : key)
-    win_execute(popupID, cmd)
-    key_handled = true
-  elseif key == "\<Up>" || key == "\<Down>"
-    # Use native Vim handling for these keys
-    key_handled = false
-  elseif key =~ '^\f$' || key == "\<Space>"
-    # 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<dict<any>> = 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<number> = 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<any>, 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
-
-# vim: shiftwidth=2 softtabstop=2