1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 04:50:04 +08:00
SpaceVim/bundle/deoplete-lsp/rplugin/python3/deoplete/source/lsp.py

188 lines
5.5 KiB
Python
Raw Normal View History

2021-10-05 15:13:10 +08:00
# =============================================================================
# FILE: lsp.py
# AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
# =============================================================================
import json
import re
from deoplete.source.base import Base
LSP_KINDS = [
'Text',
'Method',
'Function',
'Constructor',
'Field',
'Variable',
'Class',
'Interface',
'Module',
'Property',
'Unit',
'Value',
'Enum',
'Keyword',
'Snippet',
'Color',
'File',
'Reference',
'Folder',
'EnumMember',
'Constant',
'Struct',
'Event',
'Operator',
'TypeParameter',
]
LSP_KINDS_WITH_ICONS = [
' [text] ',
' [method] ',
' [function] ',
' [constructor]',
'ﰠ [field] ',
'𝒙 [variable] ',
' [class] ',
' [interface]',
' [module] ',
' [property] ',
' [unit] ',
' [value] ',
' [enum] ',
' [key] ',
'﬌ [snippet] ',
' [color] ',
' [file] ',
' [refrence] ',
' [folder] ',
' [enumMember]',
' [constant] ',
' [struct] ',
' [event] ',
' [operator] ',
' [typeParameter]',
]
class Source(Base):
def __init__(self, vim):
Base.__init__(self, vim)
self.name = 'lsp'
self.mark = '[lsp]'
self.rank = 500
self.input_pattern = r'(\.|:|->)$'
self.is_volatile = True
self.vars = {}
self.vim.vars['deoplete#source#lsp#_results'] = []
self.vim.vars['deoplete#source#lsp#_success'] = False
self.vim.vars['deoplete#source#lsp#_requested'] = False
self.vim.vars['deoplete#source#lsp#_prev_input'] = ''
if 'deoplete#lsp#use_icons_for_candidates' not in self.vim.vars:
self.vim.vars['deoplete#lsp#use_icons_for_candidates'] = False
self.lsp_kinds = LSP_KINDS
def gather_candidates(self, context):
if not self.vim.call('has', 'nvim-0.5.0'):
return []
prev_input = self.vim.vars['deoplete#source#lsp#_prev_input']
if context['input'] == prev_input and self.vim.vars[
'deoplete#source#lsp#_requested']:
return self.process_candidates()
vars = self.vim.vars
vars['deoplete#source#lsp#_requested'] = False
vars['deoplete#source#lsp#_prev_input'] = context['input']
vars['deoplete#source#lsp#_complete_position'] = context[
'complete_position']
# Note: request_candidates() may be failed
try:
params = self.vim.call(
'luaeval',
'vim.lsp.util.make_position_params()')
self.vim.call(
'luaeval', 'require("candidates").request_candidates('
'_A.arguments)',
{'arguments': params})
except Exception:
pass
2021-10-05 15:13:10 +08:00
return []
def process_candidates(self):
candidates = []
vars = self.vim.vars
results = vars['deoplete#source#lsp#_results']
if not results:
return
elif isinstance(results, dict):
if 'items' not in results:
self.print_error(
'LSP results does not have "items" key:{}'.format(
str(results)))
return
items = results['items']
else:
items = results
use_icons = vars['deoplete#lsp#use_icons_for_candidates']
if use_icons:
self.lsp_kinds = LSP_KINDS_WITH_ICONS
for rec in items:
if 'textEdit' in rec and rec['textEdit'] is not None:
textEdit = rec['textEdit']
if ('range' in textEdit and textEdit['range']['start'] ==
textEdit['range']['end']):
previous_input = vars['deoplete#source#lsp#_prev_input']
complete_position = vars[
'deoplete#source#lsp#_complete_position']
new_text = textEdit['newText']
word = f'{previous_input[complete_position:]}{new_text}'
else:
word = textEdit['newText']
elif rec.get('insertText', ''):
if rec.get('insertTextFormat', 1) != 1:
word = rec.get('entryName', rec.get('label'))
else:
word = rec['insertText']
else:
word = rec.get('entryName', rec.get('label'))
# Remove parentheses from word.
# Note: some LSP includes snippet parentheses in word(newText)
word = re.sub(r'[\(|<].*[\)|>](\$\d+)?', '', word)
item = {
'word': word,
'abbr': rec['label'],
'dup': 0,
'user_data': json.dumps({
'lspitem': rec
})
}
if isinstance(rec.get('kind'), int):
item['kind'] = self.lsp_kinds[rec['kind'] - 1]
elif rec.get('insertTextFormat') == 2:
item['kind'] = 'Snippet'
if rec.get('detail'):
item['menu'] = rec['detail']
if isinstance(rec.get('documentation'), str):
item['info'] = rec['documentation']
elif (isinstance(rec.get('documentation'), dict) and
'value' in rec['documentation']):
item['info'] = rec['documentation']['value']
candidates.append(item)
return candidates