]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
When applying text edits and restoring eol, ignore empty lines. Optimize use of range...
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 1 Jul 2023 04:37:26 +0000 (21:37 -0700)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 1 Jul 2023 04:37:26 +0000 (21:37 -0700)
autoload/lsp/diag.vim
autoload/lsp/inlayhints.vim
autoload/lsp/lsp.vim
autoload/lsp/lspserver.vim
autoload/lsp/outline.vim
autoload/lsp/selection.vim
autoload/lsp/symbol.vim
autoload/lsp/textedit.vim
autoload/lsp/util.vim

index 3238d74e284ffaca519e47dcab06add884887bd8..a892b74cce987b7e6387a51e3a79ec4a95a58b28 100644 (file)
@@ -108,9 +108,11 @@ enddef
 # Sort diagnostics ascending based on line and character offset
 def SortDiags(diags: list<dict<any>>): list<dict<any>>
   return diags->sort((a, b) => {
-    var linediff = a.range.start.line - b.range.start.line
+    var a_start = a.range.start
+    var b_start = b.range.start
+    var linediff = a_start.line - b_start.line
     if linediff == 0
-      return a.range.start.character - b.range.start.character
+      return a_start.character - b_start.character
     endif
     return linediff
   })
@@ -227,7 +229,9 @@ def DiagsRefresh(bnr: number)
   for diag in diags
     # TODO: prioritize most important severity if there are multiple diagnostics
     # from the same line
-    var lnum = diag.range.start.line + 1
+    var d_start = diag.range.start
+    var d_end = diag.range.end
+    var lnum = d_start.line + 1
     if opt.lspOptions.showDiagWithSign
       signs->add({id: 0, buffer: bnr, group: 'LSPDiag',
                  lnum: lnum, name: DiagSevToSignName(diag.severity),
@@ -236,12 +240,11 @@ def DiagsRefresh(bnr: number)
 
     try
       if opt.lspOptions.highlightDiagInline
-        prop_add(diag.range.start.line + 1,
-                  util.GetLineByteFromPos(bnr, diag.range.start) + 1,
-                  {end_lnum: diag.range.end.line + 1,
-                    end_col: util.GetLineByteFromPos(bnr, diag.range.end) + 1,
-                    bufnr: bnr,
-                    type: DiagSevToInlineHLName(diag.severity)})
+        prop_add(lnum, util.GetLineByteFromPos(bnr, d_start) + 1,
+                 {end_lnum: d_end.line + 1,
+                  end_col: util.GetLineByteFromPos(bnr, d_end) + 1,
+                  bufnr: bnr,
+                  type: DiagSevToInlineHLName(diag.severity)})
       endif
 
       if opt.lspOptions.showDiagWithVirtualText
@@ -253,10 +256,10 @@ def DiagsRefresh(bnr: number)
           padding = 3
           symbol = DiagSevToSymbolText(diag.severity)
         else
-         var charIdx = util.GetCharIdxWithoutCompChar(bnr, diag.range.start)
+         var charIdx = util.GetCharIdxWithoutCompChar(bnr, d_start)
           padding = charIdx
           if padding > 0
-            padding = strdisplaywidth(getline(diag.range.start.line + 1)[ : charIdx - 1])
+            padding = strdisplaywidth(getline(lnum)[ : charIdx - 1])
           endif
         endif
 
@@ -285,14 +288,16 @@ def SendAleDiags(bnr: number, timerid: number)
   endif
 
   # Convert to Ale's diagnostics format (:h ale-loclist-format)
-  ale#other_source#ShowResults(bnr, 'lsp', diagsMap[bnr].sortedDiagnostics->mapnew((_, v) => {
+  ale#other_source#ShowResults(bnr, 'lsp',
+    diagsMap[bnr].sortedDiagnostics->mapnew((_, v) => {
      return {text: v.message,
              lnum: v.range.start.line + 1,
              col: util.GetLineByteFromPos(bnr, v.range.start) + 1,
              end_lnum: v.range.end.line + 1,
              end_col: util.GetLineByteFromPos(bnr, v.range.end) + 1,
              type: "EWIH"[v.severity - 1]}
-  }))
+    })
+  )
 enddef
 
 # Hook called when Ale wants to retrieve new diagnostics
@@ -332,8 +337,9 @@ enddef
 # Notification: textDocument/publishDiagnostics
 # Param: PublishDiagnosticsParams
 export def DiagNotification(lspserver: dict<any>, uri: string, diags_arg: list<dict<any>>): void
-  # Diagnostics are disabled for this server
-  if lspserver.features->has_key('diagnostics') && !lspserver.features.diagnostics
+  # Diagnostics are disabled for this server?
+  var diagSupported = lspserver.features->get('diagnostics', true)
+  if !diagSupported
     return
   endif
 
@@ -366,12 +372,13 @@ export def DiagNotification(lspserver: dict<any>, uri: string, diags_arg: list<d
 
   var diagWithinRange: list<dict<any>> = []
   for diag in newDiags
-    if diag.range.start.line + 1 > lastlnum
+    var d_start = diag.range.start
+    if d_start.line + 1 > lastlnum
       # Make sure the line number is a valid buffer line number
-      diag.range.start.line = lastlnum - 1
+      d_start.line = lastlnum - 1
     endif
 
-    var lnum = diag.range.start.line + 1
+    var lnum = d_start.line + 1
     if !diagsByLnum->has_key(lnum)
       diagsByLnum[lnum] = []
     endif
@@ -485,12 +492,14 @@ def DiagsUpdateLocList(bnr: number, calledByCmd: bool = false): bool
 
   var diags = diagsMap[bnr].sortedDiagnostics
   for diag in diags
+    var d_start = diag.range.start
+    var d_end = diag.range.end
     text = diag.message->substitute("\n\\+", "\n", 'g')
     qflist->add({filename: fname,
-                   lnum: diag.range.start.line + 1,
-                   col: util.GetLineByteFromPos(bnr, diag.range.start) + 1,
-                   end_lnum: diag.range.end.line + 1,
-                    end_col: util.GetLineByteFromPos(bnr, diag.range.end) + 1,
+                   lnum: d_start.line + 1,
+                   col: util.GetLineByteFromPos(bnr, d_start) + 1,
+                   end_lnum: d_end.line + 1,
+                    end_col: util.GetLineByteFromPos(bnr, d_end) + 1,
                    text: text,
                    type: DiagSevToQfType(diag.severity)})
   endfor
@@ -531,9 +540,10 @@ enddef
 # Display the message of "diag" in a popup window right below the position in
 # the diagnostic message.
 def ShowDiagInPopup(diag: dict<any>)
-  var dlnum = diag.range.start.line + 1
+  var d_start = diag.range.start
+  var dlnum = d_start.line + 1
   var ltext = dlnum->getline()
-  var dlcol = ltext->byteidxcomp(diag.range.start.character) + 1
+  var dlcol = ltext->byteidxcomp(d_start.character) + 1
 
   var lastline = line('$')
   if dlnum > lastline
@@ -622,8 +632,9 @@ export def GetDiagByPos(bnr: number, lnum: number, col: number,
   var diags_in_line = GetDiagsByLine(bnr, lnum)
 
   for diag in diags_in_line
-    var startCharIdx = util.GetCharIdxWithoutCompChar(bnr, diag.range.start)
-    var endCharIdx = util.GetCharIdxWithoutCompChar(bnr, diag.range.end)
+    var r = diag.range
+    var startCharIdx = util.GetCharIdxWithoutCompChar(bnr, r.start)
+    var endCharIdx = util.GetCharIdxWithoutCompChar(bnr, r.end)
     if atPos
       if col >= startCharIdx + 1 && col < endCharIdx + 1
         return diag
@@ -715,8 +726,9 @@ export def LspDiagsJump(which: string, a_count: number = 0): void
   var curcol: number = charcol('.')
   for diag in (which == 'next' || which == 'here') ?
                                        diags : diags->copy()->reverse()
-    var lnum = diag.range.start.line + 1
-    var col = util.GetCharIdxWithoutCompChar(bnr, diag.range.start) + 1
+    var d_start = diag.range.start
+    var lnum = d_start.line + 1
+    var col = util.GetCharIdxWithoutCompChar(bnr, d_start) + 1
     if (which == 'next' && (lnum > curlnum || lnum == curlnum && col > curcol))
          || (which == 'prev' && (lnum < curlnum || lnum == curlnum
                                                        && col < curcol))
index a44e3fcf5f46be80376a1c04eec87c1210983549..37efdc4eef43ae0d83cb770e0e7f709eda8f0508 100644 (file)
@@ -9,8 +9,10 @@ import './options.vim' as opt
 # Initialize the highlight group and the text property type used for
 # inlay hints.
 export def InitOnce()
-  hlset([{name: 'LspInlayHintsType', default: true, linksto: 'Label'}])
-  hlset([{name: 'LspInlayHintsParam', default: true, linksto: 'Conceal'}])
+  hlset([
+    {name: 'LspInlayHintsType', default: true, linksto: 'Label'},
+    {name: 'LspInlayHintsParam', default: true, linksto: 'Conceal'}
+  ])
   prop_type_add('LspInlayHintsType', {highlight: 'LspInlayHintsType'})
   prop_type_add('LspInlayHintsParam', {highlight: 'LspInlayHintsParam'})
 enddef
index 43f96c564750a5cc5cb96f1dd77e49d9a412abce..a94940767f263aaefca096caad4b34f72000d589 100644 (file)
@@ -31,9 +31,11 @@ var ftypeServerMap: dict<list<dict<any>>> = {}
 var lspInitializedOnce = false
 
 def LspInitOnce()
-  hlset([{name: 'LspTextRef', default: true, linksto: 'Search'}])
-  hlset([{name: 'LspReadRef', default: true, linksto: 'DiffChange'}])
-  hlset([{name: 'LspWriteRef', default: true, linksto: 'DiffDelete'}])
+  hlset([
+    {name: 'LspTextRef', default: true, linksto: 'Search'},
+    {name: 'LspReadRef', default: true, linksto: 'DiffChange'},
+    {name: 'LspWriteRef', default: true, linksto: 'DiffDelete'}
+  ])
 
   var override = &cursorline
       && &cursorlineopt =~ '\<line\>\|\<screenline\>\|\<both\>'
index e5cb73155051d8e98a3ba886249d67b110b36754..9d888c8d627bf560bfab9bc9429c77824291e033 100644 (file)
@@ -964,10 +964,12 @@ def DocHighlightReply(lspserver: dict<any>, docHighlightReply: any,
       propName = 'LspTextRef'
     endif
     try
-      prop_add(docHL.range.start.line + 1,
-                  util.GetLineByteFromPos(bnr, docHL.range.start) + 1,
-                  {end_lnum: docHL.range.end.line + 1,
-                    end_col: util.GetLineByteFromPos(bnr, docHL.range.end) + 1,
+      var docHL_start = docHL.range.start
+      var docHL_end = docHL.range.end
+      prop_add(docHL_start.line + 1,
+                  util.GetLineByteFromPos(bnr, docHL_start) + 1,
+                  {end_lnum: docHL_end.line + 1,
+                    end_col: util.GetLineByteFromPos(bnr, docHL_end) + 1,
                     bufnr: bnr,
                     type: propName})
     catch /E966\|E964/ # Invalid lnum | Invalid col
index 2979d2096427114a882b0e2509223b76b9c60df2..dd7a049f3f9d578e6e11566b426edae7c3db0b9d 100644 (file)
@@ -82,8 +82,9 @@ def AddSymbolText(bnr: number,
     for s in symbols
       text->add(prefix .. s.name)
       # remember the line number for the symbol
-      var start_col: number = util.GetLineByteFromPos(bnr, s.range.start) + 1
-      lnumMap->add({name: s.name, lnum: s.range.start.line + 1,
+      var s_start = s.range.start
+      var start_col: number = util.GetLineByteFromPos(bnr, s_start) + 1
+      lnumMap->add({name: s.name, lnum: s_start.line + 1,
                        col: start_col})
       s.outlineLine = lnumMap->len()
       if s->has_key('children') && !s.children->empty()
@@ -172,11 +173,11 @@ def OutlineHighlightCurrentSymbol()
   var mid: number
   while left <= right
     mid = (left + right) / 2
-    if lnum >= (symbolTable[mid].range.start.line + 1) &&
-               lnum <= (symbolTable[mid].range.end.line + 1)
+    var r = symbolTable[mid].range
+    if lnum >= (r.start.line + 1) && lnum <= (r.end.line + 1)
       break
     endif
-    if lnum > (symbolTable[mid].range.start.line + 1)
+    if lnum > (r.start.line + 1)
       left = mid + 1
     else
       right = mid - 1
index 51467f18fb24ff0e52471d3889c64d9404150a57..1ef289ba9aaaffbee38b5c5bf11ac288bbd308d3 100644 (file)
@@ -6,12 +6,14 @@ import './util.vim'
 
 # Visually (character-wise) select the text in a range
 def SelectText(bnr: number, range: dict<dict<number>>)
-  var start_col: number = util.GetLineByteFromPos(bnr, range.start) + 1
-  var end_col: number = util.GetLineByteFromPos(bnr, range.end)
+  var rstart = range.start
+  var rend = range.end
+  var start_col: number = util.GetLineByteFromPos(bnr, rstart) + 1
+  var end_col: number = util.GetLineByteFromPos(bnr, rend)
 
   :normal! v"_y
-  setcharpos("'<", [0, range.start.line + 1, start_col, 0])
-  setcharpos("'>", [0, range.end.line + 1, end_col, 0])
+  setcharpos("'<", [0, rstart.line + 1, start_col, 0])
+  setcharpos("'>", [0, rend.line + 1, end_col, 0])
   :normal! gv
 enddef
 
@@ -48,10 +50,12 @@ enddef
 # Returns true if the current visual selection matches a range in the
 # selection reply from LSP.
 def SelectionFromLSP(range: dict<any>, startpos: list<number>, endpos: list<number>): bool
-  return startpos[1] == range.start.line + 1
-                       && endpos[1] == range.end.line + 1
-                       && startpos[2] == range.start.character + 1
-                       && endpos[2] == range.end.character
+  var rstart = range.start
+  var rend = range.end
+  return startpos[1] == rstart.line + 1
+                       && endpos[1] == rend.line + 1
+                       && startpos[2] == rstart.character + 1
+                       && endpos[2] == rend.character
 enddef
 
 # Expand or Shrink the current selection or start a new one.
index 0be5300e360916d7c72a02774b8c87fe7db119ae..6b9ac097f800a2ba5e5cbaa698ccb951f0bcb5ad 100644 (file)
@@ -14,12 +14,14 @@ import './outline.vim'
 # document symbol search
 export def InitOnce()
   # Use a high priority value to override other highlights in the line
-  hlset([{name: 'LspSymbolName', default: true, linksto: 'Search'}])
+  hlset([
+    {name: 'LspSymbolName', default: true, linksto: 'Search'},
+    {name: 'LspSymbolRange', default: true, linksto: 'Visual'}
+  ])
   prop_type_add('LspSymbolNameProp', {highlight: 'LspSymbolName',
                                       combine: false,
                                       override: true,
                                       priority: 201})
-  hlset([{name: 'LspSymbolRange', default: true, linksto: 'Visual'}])
   prop_type_add('LspSymbolRangeProp', {highlight: 'LspSymbolRange',
                                       combine: false,
                                       override: true,
@@ -307,17 +309,18 @@ def UpdatePeekFilePopup(lspserver: dict<any>, locations: list<dict<any>>)
   }
 
   lspserver.peekSymbolFilePopup = popup_create(bnr, popupAttrs)
+  var rstart = range.start
   var cmds =<< trim eval END
     :setlocal number
-    [{range.start.line + 1}, 1]->cursor()
+    [{rstart.line + 1}, 1]->cursor()
     :normal! z.
   END
   win_execute(lspserver.peekSymbolFilePopup, cmds)
 
   lspserver.peekSymbolFilePopup->clearmatches()
-  var start_col = util.GetLineByteFromPos(bnr, range.start) + 1
+  var start_col = util.GetLineByteFromPos(bnr, rstart) + 1
   var end_col = util.GetLineByteFromPos(bnr, range.end)
-  var pos = [[range.start.line + 1,
+  var pos = [[rstart.line + 1,
             start_col, end_col - start_col + 1]]
   matchaddpos('Search', pos, 10, -1, {window: lspserver.peekSymbolFilePopup})
 enddef
@@ -425,10 +428,11 @@ export def ShowLocations(lspserver: dict<any>, locations: list<dict<any>>,
       bnr = fname->bufadd()
     endif
     :silent! bnr->bufload()
-    var text: string = bnr->getbufline(range.start.line + 1)->get(0, '')->trim("\t ", 1)
+    var rstart = range.start
+    var text: string = bnr->getbufline(rstart.line + 1)->get(0, '')->trim("\t ", 1)
     qflist->add({filename: fname,
-                       lnum: range.start.line + 1,
-                       col: util.GetLineByteFromPos(bnr, range.start) + 1,
+                       lnum: rstart.line + 1,
+                       col: util.GetLineByteFromPos(bnr, rstart) + 1,
                        text: text})
   endfor
 
@@ -499,13 +503,14 @@ def PeekSymbolLocation(lspserver: dict<any>, location: dict<any>)
   var pos: list<number> = []
   var start_col: number
   var end_col: number
-  start_col = util.GetLineByteFromPos(pwbuf, range.start) + 1
+  var rstart = range.start
+  start_col = util.GetLineByteFromPos(pwbuf, rstart) + 1
   end_col = util.GetLineByteFromPos(pwbuf, range.end) + 1
-  pos->add(range.start.line + 1)
+  pos->add(rstart.line + 1)
   pos->extend([start_col, end_col - start_col])
   matchaddpos('Search', [pos], 10, 101, {window: pwid})
   var cmds =<< trim eval END
-    [{range.start.line + 1}, 1]->cursor()
+    [{rstart.line + 1}, 1]->cursor()
     :normal! z.
   END
   win_execute(pwid, cmds, 'silent!')
@@ -539,8 +544,9 @@ export def TagFunc(lspserver: dict<any>,
     var [uri, range] = util.LspLocationParse(tagloc)
     tagitem.filename = util.LspUriToFile(uri)
     var bnr = util.LspUriToBufnr(uri)
-    var startByteIdx = util.GetLineByteFromPos(bnr, range.start)
-    tagitem.cmd = $"/\\%{range.start.line + 1}l\\%{startByteIdx + 1}c"
+    var rstart = range.start
+    var startByteIdx = util.GetLineByteFromPos(bnr, rstart)
+    tagitem.cmd = $"/\\%{rstart.line + 1}l\\%{startByteIdx + 1}c"
 
     retval->add(tagitem)
   endfor
index 5c11408f1e604dfd659578228414a4ebba763413..0ea69fb911db8270ecefa21ec23b3310bd079b68 100644 (file)
@@ -119,12 +119,15 @@ export def ApplyTextEdits(bnr: number, text_edits: list<dict<any>>): void
   var idx = 0
   for e in text_edits
     # Adjust the start and end columns for multibyte characters
-    start_row = e.range.start.line
-    start_col = util.GetCharIdxWithoutCompChar(bnr, e.range.start)
-    end_row = e.range.end.line
-    end_col = util.GetCharIdxWithoutCompChar(bnr, e.range.end)
-    start_line = [e.range.start.line, start_line]->min()
-    finish_line = [e.range.end.line, finish_line]->max()
+    var r = e.range
+    var rstart: dict<any> = r.start
+    var rend: dict<any> = r.end
+    start_row = rstart.line
+    start_col = util.GetCharIdxWithoutCompChar(bnr, rstart)
+    end_row = rend.line
+    end_col = util.GetCharIdxWithoutCompChar(bnr, rend)
+    start_line = [rstart.line, start_line]->min()
+    finish_line = [rend.line, finish_line]->max()
 
     updated_edits->add({A: [start_row, start_col],
                        B: [end_row, end_col],
@@ -140,7 +143,7 @@ export def ApplyTextEdits(bnr: number, text_edits: list<dict<any>>): void
   var lines: list<string> = bnr->getbufline(start_line + 1, finish_line + 1)
   var fix_eol: bool = bnr->getbufvar('&fixeol')
   var set_eol = fix_eol && bnr->getbufinfo()[0].linecount <= finish_line + 1
-  if set_eol && lines[-1]->len() != 0
+  if !lines->empty() && set_eol && lines[-1]->len() != 0
     lines->add('')
   endif
 
@@ -156,7 +159,7 @@ export def ApplyTextEdits(bnr: number, text_edits: list<dict<any>>): void
   #echomsg $'lines(2) = {string(lines)}'
 
   # If the last line is empty and we need to set EOL, then remove it.
-  if set_eol && lines[-1]->len() == 0
+  if !lines->empty() && set_eol && lines[-1]->len() == 0
     lines->remove(-1)
   endif
 
index aefe7662ab58d0788e871c5cbd39ea69a261ef80..34fc5a67e9baaebbffe21386cc7785575d6a44ed 100644 (file)
@@ -301,8 +301,9 @@ export def JumpToLspLocation(location: dict<any>, cmdmods: string)
       exe $'{cmdmods} sbuffer {bnr}'
     endif
   endif
-  setcursorcharpos(range.start.line + 1,
-                  GetCharIdxWithoutCompChar(bufnr(), range.start) + 1)
+  var rstart = range.start
+  setcursorcharpos(rstart.line + 1,
+                  GetCharIdxWithoutCompChar(bufnr(), rstart) + 1)
   :normal! zv
 enddef