Browse Source

Reduce calls to prop_remove

When available use the "types" list in prop_remove
Ben Jackson 2 years ago
parent
commit
37b64d547b

+ 4 - 3
python/ycm/diagnostic_interface.py

@@ -125,9 +125,10 @@ class DiagnosticInterface:
          self._user_options[ 'echo_current_diagnostic' ] == 'virtual-text' ):
       if self._diag_message_needs_clearing:
         # Clear any previous diag echo
-        tp.ClearTextProperties( self._bufnr, type = 'YcmVirtDiagPadding' )
-        tp.ClearTextProperties( self._bufnr, type = 'YcmVirtDiagError' )
-        tp.ClearTextProperties( self._bufnr, type = 'YcmVirtDiagWarning' )
+        tp.ClearTextProperties( self._bufnr,
+                                prop_types = [ 'YcmVirtDiagPadding',
+                                               'YcmVirtDiagError',
+                                               'YcmVirtDiagWarning' ] )
         self._diag_message_needs_clearing = False
 
       if not text:

+ 10 - 17
python/ycm/inlay_hints.py

@@ -117,22 +117,15 @@ class InlayHints:
     except ( KeyError, IndexError ):
       last_line = None
 
-    for type in HIGHLIGHT_GROUP.keys():
-      if type == 0:
-        continue
-      tp.ClearTextProperties( self._bufnr,
-                              type=f'YCM_INLAY_{ type }',
-                              first_line = first_line,
-                              last_line = last_line )
-
-    tp.ClearTextProperties( self._bufnr,
-                            type='YCM_INLAY_UNKNOWN',
-                            first_line = first_line,
-                            last_line = last_line )
-    tp.ClearTextProperties( self._bufnr,
-                            type='YCM_INLAY_PADDING',
-                            first_line = first_line,
-                            last_line = last_line )
+    types = [ 'YCM_INLAY_UNKNOWN', 'YCM_INLAY_PADDING' ] + [
+      f'YCM_INLAY_{ prop_type }' for prop_type in HIGHLIGHT_GROUP.keys()
+    ]
+
+    tp.ClearTextProperties(
+      self._bufnr,
+      prop_types = types,
+      first_line = first_line,
+      last_line = last_line )
 
 
   def Update( self ):
@@ -179,7 +172,7 @@ class InlayHints:
       elif inlay_hint[ 'kind' ] not in HIGHLIGHT_GROUP:
         prop_type = 'YCM_INLAY_UNKNOWN'
       else:
-        prop_type = 'YCM_INLAY_' + str( inlay_hint[ 'kind' ] )
+        prop_type = 'YCM_INLAY_' + inlay_hint[ 'kind' ]
 
       if inlay_hint.get( 'paddingLeft', False ):
         tp.AddTextProperty( self._bufnr,

+ 1 - 1
python/ycm/semantic_highlighting.py

@@ -146,7 +146,7 @@ class SemanticHighlighting:
                           prop_type,
                           token[ 'range' ] )
 
-    tp.ClearTextProperties( self._bufnr, prev_prop_id )
+    tp.ClearTextProperties( self._bufnr, prop_id = prev_prop_id )
 
     # No need to re-poll
     return True

+ 38 - 15
python/ycm/text_properties.py

@@ -17,10 +17,12 @@
 
 
 from ycm import vimsupport
+from ycm.vimsupport import GetIntValue
 from ycmd import utils
 
 import vim
 import json
+import typing
 
 
 # FIXME/TODO: Merge this with vimsupport funcitons, added after these were
@@ -65,27 +67,48 @@ def AddTextProperty( bufnr,
                    f"          { json.dumps( props ) } )" )
 
 
-def ClearTextProperties( bufnr,
-                         prop_id=None,
-                         type=None,
-                         first_line = None,
-                         last_line = None ):
+def ClearTextProperties(
+  bufnr,
+  prop_id = None,
+  prop_types: typing.Union[ typing.List[ str ], str ] = None,
+  first_line = None,
+  last_line = None ):
+
   props = {
     'bufnr': bufnr,
     'all': 1,
   }
   if prop_id is not None:
     props[ 'id' ] = prop_id
-  if type is not None:
-    props[ 'type' ] = type
 
-  if prop_id is not None and type is not None:
+  if prop_id is not None and prop_types is not None:
     props[ 'both' ] = 1
 
-  if last_line is not None:
-    vim.eval(
-      f"prop_remove( { json.dumps( props ) }, { first_line }, { last_line } )" )
-  elif first_line is not None:
-    vim.eval( f"prop_remove( { json.dumps( props ) }, { first_line } )" )
-  else:
-    vim.eval( f"prop_remove( { json.dumps( props ) } )" )
+  def prop_remove():
+    if last_line is not None:
+      return GetIntValue( f"prop_remove( { json.dumps( props ) },"
+                                      f" { first_line },"
+                                      f" { last_line } )" )
+    elif first_line is not None:
+      return GetIntValue( f"prop_remove( { json.dumps( props ) },"
+                                      f" { first_line } )" )
+    else:
+      return GetIntValue( f"prop_remove( { json.dumps( props ) } )" )
+
+  if prop_types is None:
+    return prop_remove()
+
+  if not isinstance( prop_types, list ):
+    prop_types = [ prop_types ]
+
+  # 9.0.233 added types list to prop_remove, so use that
+  if vimsupport.VimVersionAtLeast( '9.0.233' ):
+    props[ 'types' ] = prop_types
+    return prop_remove()
+
+  # Older versions we have to run prop_remove for each type
+  removed = 0
+  for prop_type in prop_types:
+    props[ 'type' ] = prop_type
+    removed += prop_remove()
+  return removed