1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
# Copyright (C) 2020, YouCompleteMe Contributors
#
# This file is part of YouCompleteMe.
#
# YouCompleteMe is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# YouCompleteMe is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
from ycm.client.semantic_tokens_request import SemanticTokensRequest
from ycm.client.base_request import BuildRequestData
from ycm import vimsupport
from ycm import text_properties as tp
HIGHLIGHT_GROUP = {
'namespace': 'Type',
'type': 'Type',
'class': 'Structure',
'enum': 'Structure',
'interface': 'Structure',
'struct': 'Structure',
'typeParameter': 'Identifier',
'parameter': 'Identifier',
'variable': 'Identifier',
'property': 'Identifier',
'enumMember': 'Identifier',
'enumConstant': 'Constant',
'event': 'Identifier',
'function': 'Function',
'member': 'Identifier',
'macro': 'Macro',
'method': 'Function',
'keyword': 'Keyword',
'modifier': 'Keyword',
'comment': 'Comment',
'string': 'String',
'number': 'Number',
'regexp': 'String',
'operator': 'Operator',
'unknown': 'Normal',
}
REPORTED_MISSING_TYPES = set()
def Initialise():
if vimsupport.VimIsNeovim():
return
props = tp.GetTextPropertyTypes()
if 'YCM_HL_UNKNOWN' not in props:
tp.AddTextPropertyType( 'YCM_HL_UNKNOWN',
highlight = 'WarningMsg',
priority = 0 )
for token_type, group in HIGHLIGHT_GROUP.items():
prop = f'YCM_HL_{ token_type }'
if prop not in props and vimsupport.GetIntValue(
f"hlexists( '{ vimsupport.EscapeForVim( group ) }' )" ):
tp.AddTextPropertyType( prop,
highlight = group,
priority = 0 )
# "arbitrary" base id
NEXT_TEXT_PROP_ID = 70784
def NextPropID():
global NEXT_TEXT_PROP_ID
try:
return NEXT_TEXT_PROP_ID
finally:
NEXT_TEXT_PROP_ID += 1
class SemanticHighlighting:
"""Stores the semantic highlighting state for a Vim buffer"""
def __init__( self, bufnr, user_options ):
self._request = None
self._bufnr = bufnr
self._prop_id = NextPropID()
self.tick = -1
def SendRequest( self ):
if self._request and not self.IsResponseReady():
return
self.tick = vimsupport.GetBufferChangedTick( self._bufnr )
request: dict = BuildRequestData( self._bufnr )
request.update( {
'range': vimsupport.RangeVisibleInBuffer( self._bufnr )
} )
self._request = SemanticTokensRequest( request )
self._request.Start()
def IsResponseReady( self ):
return self._request is not None and self._request.Done()
def Update( self ):
if not self._request:
# Nothing to update
return True
assert self.IsResponseReady()
# We're ready to use this response. Clear it (to avoid repeatedly
# re-polling).
response = self._request.Response()
self._request = None
if self.tick != vimsupport.GetBufferChangedTick( self._bufnr ):
# Buffer has changed, we should ignore the data and retry
self.SendRequest()
return False # poll again
# We requested a snapshot
tokens = response.get( 'tokens', [] )
prev_prop_id = self._prop_id
self._prop_id = NextPropID()
for token in tokens:
if token[ 'type' ] not in HIGHLIGHT_GROUP:
if token[ 'type' ] not in REPORTED_MISSING_TYPES:
REPORTED_MISSING_TYPES.add( token[ 'type' ] )
vimsupport.PostVimMessage(
f"Missing property type for { token[ 'type' ] }" )
continue
prop_type = f"YCM_HL_{ token[ 'type' ] }"
tp.AddTextProperty( self._bufnr,
self._prop_id,
prop_type,
token[ 'range' ] )
tp.ClearTextProperties( self._bufnr, prop_id = prev_prop_id )
# No need to re-poll
return True
|