install.fairie/dotfiles/.vim/plugged/YouCompleteMe/python/ycm/inlay_hints.py
Git E2E Dev Test Username 1dcbe335e1 git subrepo clone (merge) https://github.com/ycm-core/YouCompleteMe.git ./dotfiles/.vim/plugged/YouCompleteMe
subrepo:
  subdir:   "dotfiles/.vim/plugged/YouCompleteMe"
  merged:   "99ccab251"
upstream:
  origin:   "https://github.com/ycm-core/YouCompleteMe.git"
  branch:   "master"
  commit:   "99ccab251"
git-subrepo:
  version:  "0.4.3"
  origin:   "???"
  commit:   "???"
2022-10-18 10:37:46 -04:00

195 lines
6.4 KiB
Python

# Copyright (C) 2022, 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.inlay_hints_request import InlayHintsRequest
from ycm.client.base_request import BuildRequestData
from ycm import vimsupport
from ycm import text_properties as tp
HIGHLIGHT_GROUP = {
'Type': 'YcmInlayHint',
'Parameter': 'YcmInlayHint',
'Enum': 'YcmInlayHint',
}
REPORTED_MISSING_TYPES = set()
def Initialise():
if not vimsupport.VimSupportsVirtualText():
return False
props = tp.GetTextPropertyTypes()
if 'YCM_INLAY_UNKNOWN' not in props:
tp.AddTextPropertyType( 'YCM_INLAY_UNKNOWN',
highlight = 'YcmInlayHint',
start_incl = 1 )
if 'YCM_INLAY_PADDING' not in props:
tp.AddTextPropertyType( 'YCM_INLAY_PADDING',
highlight = 'YcmInvisible',
start_incl = 1 )
for token_type, group in HIGHLIGHT_GROUP.items():
prop = f'YCM_INLAY_{ token_type }'
if prop not in props and vimsupport.GetIntValue(
f"hlexists( '{ vimsupport.EscapeForVim( group ) }' )" ):
tp.AddTextPropertyType( prop,
highlight = group,
start_incl = 1 )
return True
class InlayHints:
"""Stores the inlay hints state for a Vim buffer"""
# FIXME: Send a request per-disjoint range for this buffer rather than the
# maximal range. then collaate the results when all responses are returned
def __init__( self, bufnr, user_options ):
self._request = None
self._bufnr = bufnr
self.tick = -1
self._latest_inlay_hints = []
self._last_requested_range = None
def Request( self, force=False ):
if self._request and not self.Ready():
return True
# Check to see if the buffer ranges would actually change anything visible.
# This avoids a round-trip for every single line scroll event
if ( not force and
self.tick == vimsupport.GetBufferChangedTick( self._bufnr ) and
vimsupport.VisibleRangeOfBufferOverlaps(
self._bufnr,
self._last_requested_range ) ):
return False # don't poll
# We're requesting changes, so the existing results are now invalid
self._latest_inlay_hints = []
# FIXME: This call is duplicated in the call to VisibleRangeOfBufferOverlaps
# - remove the expansion param
# - look up the actual visible range, then call this function
# - if not overlapping, do the factor expansion and request
self._last_requested_range = vimsupport.RangeVisibleInBuffer( self._bufnr )
self.tick = vimsupport.GetBufferChangedTick( self._bufnr )
request_data = BuildRequestData( self._bufnr )
request_data.update( {
'range': self._last_requested_range
} )
self._request = InlayHintsRequest( request_data )
self._request.Start()
return True
def Ready( self ):
return self._request is not None and self._request.Done()
def Clear( self ):
# ClearTextProperties is slow as it must scan the whole buffer
# we shouldn't use _last_requested_range, because the server is free to
# return a larger range, so we pick the first/last from the latest results
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 )
def Update( self ):
if not self._request:
# Nothing to update
return True
assert self.Ready()
# We're ready to use this response. Clear it (to avoid repeatedly
# re-polling).
self._latest_inlay_hints = self._request.Response()
self._request = None
if self.tick != vimsupport.GetBufferChangedTick( self._bufnr ):
# Buffer has changed, we should ignore the data and retry
self.Request( force=True )
return False # poll again
self._Draw()
# No need to re-poll
return True
def Refresh( self ):
if self.tick != vimsupport.GetBufferChangedTick( self._bufnr ):
# stale data
return
if self._request is not None:
# request in progress; we''l handle refreshing when it's done.
return
self._Draw()
def _Draw( self ):
self.Clear()
for inlay_hint in self._latest_inlay_hints:
if 'kind' not in inlay_hint:
prop_type = 'YCM_INLAY_UNKNOWN'
elif inlay_hint[ 'kind' ] not in HIGHLIGHT_GROUP:
prop_type = 'YCM_INLAY_UNKNOWN'
else:
prop_type = 'YCM_INLAY_' + inlay_hint[ 'kind' ]
if inlay_hint.get( 'paddingLeft', False ):
tp.AddTextProperty( self._bufnr,
None,
'YCM_INLAY_PADDING',
{
'start': inlay_hint[ 'position' ],
'end': inlay_hint[ 'position' ],
},
{
'text': ' '
} )
tp.AddTextProperty( self._bufnr,
None,
prop_type,
{
'start': inlay_hint[ 'position' ],
'end': inlay_hint[ 'position' ],
},
{
'text': inlay_hint[ 'label' ]
} )
if inlay_hint.get( 'paddingRight', False ):
tp.AddTextProperty( self._bufnr,
None,
'YCM_INLAY_PADDING',
{
'start': inlay_hint[ 'position' ],
'end': inlay_hint[ 'position' ],
},
{
'text': ' '
} )