1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 06:40:05 +08:00
SpaceVim/bundle/deoplete-lsp/rplugin/python3/deoplete/source/lsp.py
2021-10-05 15:13:10 +08:00

185 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# =============================================================================
# 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']
params = self.vim.call(
'luaeval',
'vim.lsp.util.make_position_params()')
self.vim.call(
'luaeval', 'require("candidates").request_candidates('
'_A.arguments)',
{'arguments': params})
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