1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 02:20:03 +08:00
SpaceVim/bundle/deoplete.nvim/rplugin/python3/deoplete/context.py

147 lines
5.4 KiB
Python
Raw Normal View History

2020-06-18 23:07:37 +08:00
# ============================================================================
# FILE: context.py
# AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
# License: MIT license
# ============================================================================
2022-04-23 12:09:55 +08:00
from pathlib import Path
from pynvim import Nvim
2020-06-18 23:07:37 +08:00
import re
import typing
2022-04-23 12:09:55 +08:00
from deoplete.util import exists_path
2020-06-18 23:07:37 +08:00
UserContext = typing.Dict[str, typing.Any]
class Context(object):
def __init__(self, vim: Nvim) -> None:
self._vim = vim
self._prev_filetype = ''
self._cached: typing.Optional[UserContext] = None
self._cached_filetype = self._init_cached_filetype(
self._prev_filetype)
self._init_cached()
self._context_filetype: UserContext = {}
def get(self, event: str) -> UserContext:
text = self._vim.call('deoplete#util#get_input', event)
[filetype, filetypes, same_filetypes] = self._get_context_filetype(
text, event, self._vim.call('getbufvar', '%', '&filetype'))
m = re.search(r'\w$', text)
word_len = len(m.group(0)) if m else 0
max_width = self._vim.call('winwidth', 0) - self._vim.call('col', '.')
max_width += word_len
context: UserContext = {
'changedtick': self._vim.call(
'getbufvar', '%', 'changedtick', 0),
'event': event,
'filetype': filetype,
'filetypes': filetypes,
'input': text,
'max_abbr_width': max_width,
'max_kind_width': max_width,
'max_menu_width': max_width,
'next_input': self._vim.call(
'deoplete#util#get_next_input', event),
'position': self._vim.call('getpos', '.'),
'same_filetypes': same_filetypes,
2022-04-23 12:09:55 +08:00
'time': self._vim.call('reltime'),
2020-06-18 23:07:37 +08:00
}
context.update(self._cached) # type: ignore
if filetype != self._prev_filetype:
self._prev_filetype = filetype
self._cached_filetype = self._init_cached_filetype(filetype)
context.update(self._cached_filetype)
return context
def _init_cached_filetype(self, filetype: str) -> UserContext:
return {
'keyword_pattern': self._vim.call(
'deoplete#util#get_keyword_pattern', filetype),
'sources': self._vim.call(
'deoplete#custom#_get_filetype_option',
'sources', filetype, []),
}
def _init_cached(self) -> None:
bufnr = self._vim.call('expand', '<abuf>')
if not bufnr:
bufnr = self._vim.call('bufnr', '%')
if not bufnr:
bufnr = -1
bufname = ''
else:
bufname = self._vim.call('bufname', bufnr)
cwd = self._vim.call('getcwd')
buftype = self._vim.call('getbufvar', '%', '&buftype')
2022-04-23 12:09:55 +08:00
bufpath = (bufname if Path(bufname).is_absolute()
else str(Path(cwd).joinpath(bufname)))
if not exists_path(bufpath) or 'nofile' in buftype:
2020-06-18 23:07:37 +08:00
bufpath = ''
self._cached = {
'bufnr': bufnr,
'bufname': bufname,
'bufpath': bufpath,
'complete_str': '',
'custom': self._vim.call('deoplete#custom#_get'),
'cwd': cwd,
'encoding': self._vim.options['encoding'],
'is_windows': self._vim.call('has', 'win32'),
}
def _get_context_filetype(self,
text: str, event: str, filetype: str
) -> typing.List[typing.Any]:
if not self._context_filetype and self._vim.call(
'exists', '*context_filetype#get_filetype'):
# Force context_filetype call
self._vim.call('context_filetype#get_filetype')
linenr = self._vim.call('line', '.')
bufnr = self._vim.call('bufnr', '%')
if (not self._context_filetype or
self._context_filetype['prev_filetype'] != filetype or
self._context_filetype['line'] != linenr or
self._context_filetype['bufnr'] != bufnr or
re.sub(r'\w+$', '', self._context_filetype['input']) !=
re.sub(r'\w+$', '', self._context_filetype['input']) or
event == 'InsertEnter'):
self._cache_context_filetype(text, filetype, linenr, bufnr)
return [
self._context_filetype['filetype'],
self._context_filetype['filetypes'],
self._context_filetype['same_filetypes']
]
def _cache_context_filetype(self, text: str, filetype: str,
linenr: int, bufnr: int) -> None:
exists_context_filetype = self._vim.call(
'exists', '*context_filetype#get_filetype')
self._context_filetype = {
'line': linenr,
'bufnr': bufnr,
'input': text,
'prev_filetype': filetype,
'filetype': (
self._vim.call('context_filetype#get_filetype')
if exists_context_filetype
else (filetype if filetype else 'nothing')),
'filetypes': (
self._vim.call('context_filetype#get_filetypes')
if exists_context_filetype
else filetype.split('.')),
'same_filetypes': (
self._vim.call('context_filetype#get_same_filetypes')
if exists_context_filetype else []),
}