diff options
author | Shougo <Shougo.Matsu@gmail.com> | 2019-08-04 11:23:31 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-04 11:23:31 +0900 |
commit | d58f8f2686068080f123ad903b2113d6973250fb (patch) | |
tree | 865de73450cb8b2ad65bace856f7e9bdd7e89814 | |
parent | e8cab49ac99a5bb45e16a4bf24bb697163e7beaf (diff) | |
parent | 00d4d35f14fee6c23fa48017386760fc49a9ac4e (diff) | |
download | deoplete.nvim-d58f8f2686068080f123ad903b2113d6973250fb.zip |
Merge pull request #998 from Shougo/typing
Fix typing errors
27 files changed, 205 insertions, 147 deletions
@@ -3,4 +3,5 @@ doc/tags vim-themis .cache .mypy_cache +.pytest_cache tags diff --git a/rplugin/python3/deoplete/base/filter.py b/rplugin/python3/deoplete/base/filter.py index c6251ac..9927778 100644 --- a/rplugin/python3/deoplete/base/filter.py +++ b/rplugin/python3/deoplete/base/filter.py @@ -4,22 +4,25 @@ # License: MIT license # ============================================================================ +import typing + from abc import abstractmethod from deoplete.logger import LoggingMixin -from deoplete.util import error_vim +from deoplete.util import error_vim, Nvim, UserContext, Candidates class Base(LoggingMixin): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: self.vim = vim self.name = 'base' self.description = '' + self.vars: typing.Dict[str, typing.Any] = {} - def on_event(self, context): + def on_event(self, context: UserContext) -> None: pass - def get_var(self, var_name): + def get_var(self, var_name: str) -> typing.Optional[typing.Any]: custom_vars = self.vim.call( 'deoplete#custom#_get_filter', self.name) if var_name in custom_vars: @@ -29,8 +32,8 @@ class Base(LoggingMixin): return None @abstractmethod - def filter(self, context): - pass + def filter(self, context: UserContext) -> Candidates: + return [] - def print_error(self, expr): + def print_error(self, expr: typing.Any) -> None: error_vim(self.vim, expr) diff --git a/rplugin/python3/deoplete/base/source.py b/rplugin/python3/deoplete/base/source.py index ed4eb84..ce6a4ca 100644 --- a/rplugin/python3/deoplete/base/source.py +++ b/rplugin/python3/deoplete/base/source.py @@ -5,21 +5,24 @@ # ============================================================================ import re +import typing from abc import abstractmethod + from deoplete.logger import LoggingMixin -from deoplete.util import debug, error_vim +from deoplete.util import debug, error_vim, Nvim, UserContext, Candidates class Base(LoggingMixin): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: self.vim = vim self.description = '' self.mark = '' + self.name = '' self.max_pattern_length = 80 self.min_pattern_length = -1 self.input_pattern = '' - self.input_patterns = {} + self.input_patterns: typing.Dict[str, str] = {} self.matchers = ['matcher_fuzzy'] self.sorters = ['sorter_rank'] self.converters = [ @@ -28,17 +31,17 @@ class Base(LoggingMixin): 'converter_truncate_kind', 'converter_truncate_info', 'converter_truncate_menu'] - self.filetypes = [] - self.keyword_patterns = [] + self.filetypes: typing.List[str] = [] + self.keyword_patterns: typing.List[str] = [] self.is_debug_enabled = False self.is_bytepos = False self.is_initialized = False self.is_volatile = False self.is_silent = False self.rank = 100 - self.disabled_syntaxes = [] - self.events = None - self.vars = {} + self.disabled_syntaxes: typing.List[str] = [] + self.events: typing.List[str] = [] + self.vars: typing.Dict[str, typing.Any] = {} self.max_abbr_width = 80 self.max_kind_width = 40 self.max_info_width = 200 @@ -47,27 +50,27 @@ class Base(LoggingMixin): self.matcher_key = '' self.dup = False - def get_complete_position(self, context): + def get_complete_position(self, context: UserContext) -> int: m = re.search('(?:' + context['keyword_pattern'] + ')$|$', context['input']) return m.start() if m else -1 - def print(self, expr): + def print(self, expr: typing.Any) -> None: if not self.is_silent: debug(self.vim, expr) - def print_error(self, expr): + def print_error(self, expr: typing.Any) -> None: if not self.is_silent: error_vim(self.vim, expr) @abstractmethod - def gather_candidates(self, context): - pass + def gather_candidates(self, context: UserContext) -> Candidates: + return [] - def on_event(self, context): + def on_event(self, context: UserContext) -> None: pass - def get_var(self, var_name): + def get_var(self, var_name: str) -> typing.Optional[typing.Any]: custom_vars = self.vim.call( 'deoplete#custom#_get_source_vars', self.name) if var_name in custom_vars: @@ -76,19 +79,20 @@ class Base(LoggingMixin): return self.vars[var_name] return None - def get_filetype_var(self, filetype, var_name): + def get_filetype_var(self, filetype: str, + var_name: str) -> typing.Optional[typing.Any]: var = self.get_var(var_name) if var is None: return None ft = filetype if (filetype in var) else '_' return var.get(ft, '') - def get_input_pattern(self, filetype): + def get_input_pattern(self, filetype: str) -> str: if not self.input_patterns: return self.input_pattern ft = filetype if (filetype in self.input_patterns) else '_' return self.input_patterns.get(ft, self.input_pattern) - def get_buf_option(self, option): + def get_buf_option(self, option: str) -> typing.Any: return self.vim.call('getbufvar', '%', '&' + option) diff --git a/rplugin/python3/deoplete/filter/base.py b/rplugin/python3/deoplete/filter/base.py index 4612630..7b89960 100644 --- a/rplugin/python3/deoplete/filter/base.py +++ b/rplugin/python3/deoplete/filter/base.py @@ -6,8 +6,9 @@ # For backward compatibility from deoplete.base.filter import Base as _Base +from deoplete.util import Nvim class Base(_Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) diff --git a/rplugin/python3/deoplete/filter/converter_auto_delimiter.py b/rplugin/python3/deoplete/filter/converter_auto_delimiter.py index d37ceb7..5fdc3e3 100644 --- a/rplugin/python3/deoplete/filter/converter_auto_delimiter.py +++ b/rplugin/python3/deoplete/filter/converter_auto_delimiter.py @@ -4,11 +4,14 @@ # License: MIT license # ============================================================================ +import typing + from deoplete.base.filter import Base +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_auto_delimiter' @@ -17,8 +20,9 @@ class Filter(Base): 'delimiters': ['/'], } - def filter(self, context): - delimiters = self.get_var('delimiters') + def filter(self, context: UserContext) -> Candidates: + delimiters: typing.List[str] = self.get_var( # type: ignore + 'delimiters') for candidate, delimiter in [ [x, last_find(x['abbr'], delimiters)] for x in context['candidates'] @@ -26,10 +30,11 @@ class Filter(Base): not last_find(x['word'], delimiters) and last_find(x['abbr'], delimiters)]: candidate['word'] += delimiter - return context['candidates'] + return context['candidates'] # type: ignore -def last_find(s, needles): +def last_find(s: str, needles: typing.List[str]) -> typing.Optional[str]: for needle in needles: if len(s) >= len(needle) and s[-len(needle):] == needle: return needle + return None diff --git a/rplugin/python3/deoplete/filter/converter_auto_paren.py b/rplugin/python3/deoplete/filter/converter_auto_paren.py index 5596f62..047370f 100644 --- a/rplugin/python3/deoplete/filter/converter_auto_paren.py +++ b/rplugin/python3/deoplete/filter/converter_auto_paren.py @@ -5,17 +5,19 @@ # ============================================================================ import re + from deoplete.base.filter import Base +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_auto_paren' self.description = 'auto add parentheses converter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: p1 = re.compile(r'\(\)?$') p2 = re.compile(r'\(.*\)') for candidate in [ @@ -24,4 +26,4 @@ class Filter(Base): (('abbr' in x and p2.search(x['abbr'])) or ('info' in x and p2.search(x['info'])))]: candidate['word'] += '(' - return context['candidates'] + return context['candidates'] # type: ignore diff --git a/rplugin/python3/deoplete/filter/converter_remove_overlap.py b/rplugin/python3/deoplete/filter/converter_remove_overlap.py index 9c049a0..459607a 100644 --- a/rplugin/python3/deoplete/filter/converter_remove_overlap.py +++ b/rplugin/python3/deoplete/filter/converter_remove_overlap.py @@ -5,22 +5,24 @@ # ============================================================================ import re + from deoplete.base.filter import Base +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_remove_overlap' self.description = 'remove overlap converter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: if not context['next_input']: - return context['candidates'] + return context['candidates'] # type: ignore m = re.match(r'\S+', context['next_input']) if not m: - return context['candidates'] + return context['candidates'] # type: ignore next_input = m.group(0) for [overlap, candidate] in [ [x, y] for x, y @@ -29,10 +31,10 @@ class Filter(Base): if 'abbr' not in candidate: candidate['abbr'] = candidate['word'] candidate['word'] = candidate['word'][: -overlap] - return context['candidates'] + return context['candidates'] # type: ignore -def overlap_length(left, right): +def overlap_length(left: str, right: str) -> int: pos = len(right) while pos > 0 and not left.endswith(right[: pos]): pos -= 1 diff --git a/rplugin/python3/deoplete/filter/converter_remove_paren.py b/rplugin/python3/deoplete/filter/converter_remove_paren.py index a42900e..e62a7c2 100644 --- a/rplugin/python3/deoplete/filter/converter_remove_paren.py +++ b/rplugin/python3/deoplete/filter/converter_remove_paren.py @@ -5,19 +5,21 @@ # ============================================================================ import re + from deoplete.base.filter import Base +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_remove_paren' self.description = 'remove parentheses converter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: for candidate in [x for x in context['candidates'] if '(' in x['word']]: candidate['word'] = re.sub(r'\(.*\)(\$\d+)?', '', candidate['word']) - return context['candidates'] + return context['candidates'] # type: ignore diff --git a/rplugin/python3/deoplete/filter/converter_reorder_attr.py b/rplugin/python3/deoplete/filter/converter_reorder_attr.py index 1fa4ad7..308c754 100644 --- a/rplugin/python3/deoplete/filter/converter_reorder_attr.py +++ b/rplugin/python3/deoplete/filter/converter_reorder_attr.py @@ -4,12 +4,15 @@ # License: MIT license # ============================================================================ -from deoplete.base.filter import Base import re +import typing + +from deoplete.base.filter import Base +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_reorder_attr' @@ -19,7 +22,9 @@ class Filter(Base): } @staticmethod - def filter_attrs(candidates, preferred_order_attrs, max_list_size=500): + def filter_attrs(candidates: Candidates, + preferred_order_attrs: typing.Dict[str, typing.Any], + max_list_size: int = 500) -> Candidates: context_candidates = candidates[:] new_candidates = [] new_candidates_len = 0 @@ -57,11 +62,11 @@ class Filter(Base): return new_candidates - def filter(self, context): - preferred_order_attrs = self.get_var('attrs_order').get( - context['filetype'], []) + def filter(self, context: UserContext) -> Candidates: + preferred_order_attrs = self.get_var( # type: ignore + 'attrs_order').get(context['filetype'], []) if not context['candidates'] or not preferred_order_attrs: - return context['candidates'] + return context['candidates'] # type: ignore max_list_size = self.vim.call( 'deoplete#custom#_get_option', 'max_list' diff --git a/rplugin/python3/deoplete/filter/converter_truncate_abbr.py b/rplugin/python3/deoplete/filter/converter_truncate_abbr.py index 2331eed..b25a1ec 100644 --- a/rplugin/python3/deoplete/filter/converter_truncate_abbr.py +++ b/rplugin/python3/deoplete/filter/converter_truncate_abbr.py @@ -5,24 +5,24 @@ # ============================================================================ from deoplete.base.filter import Base -from deoplete.util import truncate_skipping +from deoplete.util import truncate_skipping, Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_truncate_abbr' self.description = 'truncate abbr converter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: max_width = context['max_abbr_width'] if max_width <= 0: - return context['candidates'] + return context['candidates'] # type: ignore footer_width = max_width / 3 for candidate in context['candidates']: candidate['abbr'] = truncate_skipping( candidate.get('abbr', candidate['word']), max_width, '..', footer_width) - return context['candidates'] + return context['candidates'] # type: ignore diff --git a/rplugin/python3/deoplete/filter/converter_truncate_info.py b/rplugin/python3/deoplete/filter/converter_truncate_info.py index aff7f46..fb85f5c 100644 --- a/rplugin/python3/deoplete/filter/converter_truncate_info.py +++ b/rplugin/python3/deoplete/filter/converter_truncate_info.py @@ -5,24 +5,24 @@ # ============================================================================ from deoplete.base.filter import Base -from deoplete.util import truncate_skipping +from deoplete.util import truncate_skipping, Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_truncate_info' self.description = 'truncate info converter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: max_width = context['max_info_width'] if not context['candidates'] or max_width <= 0: - return context['candidates'] + return context['candidates'] # type: ignore footer_width = 1 for candidate in context['candidates']: candidate['info'] = truncate_skipping( candidate.get('info', ''), max_width, '..', footer_width) - return context['candidates'] + return context['candidates'] # type: ignore diff --git a/rplugin/python3/deoplete/filter/converter_truncate_kind.py b/rplugin/python3/deoplete/filter/converter_truncate_kind.py index 57ed429..2c7c596 100644 --- a/rplugin/python3/deoplete/filter/converter_truncate_kind.py +++ b/rplugin/python3/deoplete/filter/converter_truncate_kind.py @@ -5,25 +5,25 @@ # ============================================================================ from deoplete.base.filter import Base -from deoplete.util import truncate_skipping +from deoplete.util import truncate_skipping, Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_truncate_kind' self.description = 'truncate kind converter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: max_width = context['max_kind_width'] if not context['candidates'] or 'kind' not in context[ 'candidates'][0] or max_width <= 0: - return context['candidates'] + return context['candidates'] # type: ignore footer_width = max_width / 3 for candidate in context['candidates']: candidate['kind'] = truncate_skipping( candidate.get('kind', ''), max_width, '..', footer_width) - return context['candidates'] + return context['candidates'] # type: ignore diff --git a/rplugin/python3/deoplete/filter/converter_truncate_menu.py b/rplugin/python3/deoplete/filter/converter_truncate_menu.py index 90a331d..164592a 100644 --- a/rplugin/python3/deoplete/filter/converter_truncate_menu.py +++ b/rplugin/python3/deoplete/filter/converter_truncate_menu.py @@ -5,25 +5,25 @@ # ============================================================================ from deoplete.base.filter import Base -from deoplete.util import truncate_skipping +from deoplete.util import truncate_skipping, Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'converter_truncate_menu' self.description = 'truncate menu converter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: max_width = context['max_menu_width'] if not context['candidates'] or 'menu' not in context[ 'candidates'][0] or max_width <= 0: - return context['candidates'] + return context['candidates'] # type: ignore footer_width = max_width / 3 for candidate in context['candidates']: candidate['menu'] = truncate_skipping( candidate.get('menu', ''), max_width, '..', footer_width) - return context['candidates'] + return context['candidates'] # type: ignore diff --git a/rplugin/python3/deoplete/filter/matcher_cpsm.py b/rplugin/python3/deoplete/filter/matcher_cpsm.py index e0b09cb..96e41ad 100644 --- a/rplugin/python3/deoplete/filter/matcher_cpsm.py +++ b/rplugin/python3/deoplete/filter/matcher_cpsm.py @@ -4,27 +4,29 @@ # License: MIT license # ============================================================================ -import sys import os +import sys +import typing from deoplete.base.filter import Base from deoplete.util import error, globruntime +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'matcher_cpsm' self.description = 'cpsm matcher' - self._cpsm = None + self._cpsm: typing.Optional[typing.Any] = None - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: if (not context['candidates'] or not context['input'] or self._cpsm is False): - return context['candidates'] + return context['candidates'] # type: ignore if self._cpsm is None: errmsg = self._init_cpsm(context) @@ -41,11 +43,11 @@ class Filter(Base): return [x for x in context['candidates'] if x['word'] in sorted(cpsm_result, key=cpsm_result.index)] - def _init_cpsm(self, context): + def _init_cpsm(self, context: UserContext) -> str: ext = '.pyd' if context['is_windows'] else '.so' fname = 'bin/cpsm_py' + ext found = globruntime(self.vim.options['runtimepath'], fname) - errmsg = None + errmsg = '' if found: sys.path.insert(0, os.path.dirname(found[0])) try: @@ -67,6 +69,8 @@ class Filter(Base): self._cpsm = False return errmsg - def _get_cpsm_result(self, candidates, pattern): - return self._cpsm.ctrlp_match((d['word'] for d in candidates), - pattern, limit=1000, ispath=False)[0] + def _get_cpsm_result(self, candidates: Candidates, + pattern: str) -> typing.List[str]: + return self._cpsm.ctrlp_match( # type: ignore + (d['word'] for d in candidates), + pattern, limit=1000, ispath=False)[0] diff --git a/rplugin/python3/deoplete/filter/matcher_full_fuzzy.py b/rplugin/python3/deoplete/filter/matcher_full_fuzzy.py index 6a58b9f..f7fec4c 100644 --- a/rplugin/python3/deoplete/filter/matcher_full_fuzzy.py +++ b/rplugin/python3/deoplete/filter/matcher_full_fuzzy.py @@ -6,18 +6,18 @@ import re from deoplete.base.filter import Base -from deoplete.util import fuzzy_escape +from deoplete.util import fuzzy_escape, Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'matcher_full_fuzzy' self.description = 'full fuzzy matcher' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: complete_str = context['complete_str'] if context['ignorecase']: complete_str = complete_str.lower() diff --git a/rplugin/python3/deoplete/filter/matcher_fuzzy.py b/rplugin/python3/deoplete/filter/matcher_fuzzy.py index ad9efa4..9f0092e 100644 --- a/rplugin/python3/deoplete/filter/matcher_fuzzy.py +++ b/rplugin/python3/deoplete/filter/matcher_fuzzy.py @@ -9,22 +9,23 @@ import re from deoplete.base.filter import Base from deoplete.util import ( fuzzy_escape, binary_search_begin, binary_search_end) +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'matcher_fuzzy' self.description = 'fuzzy matcher' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: complete_str = context['complete_str'] if context['ignorecase']: complete_str = complete_str.lower() if not complete_str: - return context['candidates'] + return context['candidates'] # type: ignore if context['is_sorted']: begin = binary_search_begin( diff --git a/rplugin/python3/deoplete/filter/matcher_head.py b/rplugin/python3/deoplete/filter/matcher_head.py index 5133169..de672de 100644 --- a/rplugin/python3/deoplete/filter/matcher_head.py +++ b/rplugin/python3/deoplete/filter/matcher_head.py @@ -6,17 +6,18 @@ from deoplete.base.filter import Base from deoplete.util import binary_search_begin, binary_search_end +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'matcher_head' self.description = 'head matcher' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: complete_str = context['complete_str'] if context['ignorecase']: complete_str = complete_str.lower() @@ -31,7 +32,7 @@ class Filter(Base): candidates = context['candidates'][begin:end+1] if context['ignorecase']: - return candidates + return candidates # type: ignore else: candidates = context['candidates'] diff --git a/rplugin/python3/deoplete/filter/matcher_length.py b/rplugin/python3/deoplete/filter/matcher_length.py index c9e6f6d..9804e67 100644 --- a/rplugin/python3/deoplete/filter/matcher_length.py +++ b/rplugin/python3/deoplete/filter/matcher_length.py @@ -5,17 +5,18 @@ # ============================================================================ from deoplete.base.filter import Base +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'matcher_length' self.description = 'length matcher' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: input_len = len(context['complete_str']) return [x for x in context['candidates'] if len(x['word']) > input_len] diff --git a/rplugin/python3/deoplete/filter/sorter_rank.py b/rplugin/python3/deoplete/filter/sorter_rank.py index 8e0199b..b64a20b 100644 --- a/rplugin/python3/deoplete/filter/sorter_rank.py +++ b/rplugin/python3/deoplete/filter/sorter_rank.py @@ -5,9 +5,11 @@ # ============================================================================ import re +import typing from deoplete.base.filter import Base from deoplete.util import getlines +from deoplete.util import Nvim, UserContext, Candidates, Candidate LINES_ABOVE = 100 @@ -16,14 +18,14 @@ LINES_BELOW = 100 class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'sorter_rank' self.description = 'rank sorter' - self._cache = {} + self._cache: typing.Dict[str, int] = {} - def on_event(self, context): + def on_event(self, context: UserContext) -> None: line = context['position'][1] lines = getlines(self.vim, max([1, line - LINES_ABOVE]), line + LINES_BELOW) @@ -36,10 +38,10 @@ class Filter(Base): else: self._cache[k] = 1 - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: complete_str = context['complete_str'].lower() - def compare(x): + def compare(x: Candidate) -> int: matched = int(complete_str in x['word'].lower()) mru = self._cache.get(x['word'], 0) return -(matched * 40 + mru * 20) diff --git a/rplugin/python3/deoplete/filter/sorter_word.py b/rplugin/python3/deoplete/filter/sorter_word.py index b09b9de..5558106 100644 --- a/rplugin/python3/deoplete/filter/sorter_word.py +++ b/rplugin/python3/deoplete/filter/sorter_word.py @@ -5,16 +5,17 @@ # ============================================================================ from deoplete.base.filter import Base +from deoplete.util import Nvim, UserContext, Candidates class Filter(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'sorter_word' self.description = 'word sorter' - def filter(self, context): + def filter(self, context: UserContext) -> Candidates: return sorted(context['candidates'], key=lambda x: x['word'].swapcase()) diff --git a/rplugin/python3/deoplete/source/around.py b/rplugin/python3/deoplete/source/around.py index 443144b..3a7a230 100644 --- a/rplugin/python3/deoplete/source/around.py +++ b/rplugin/python3/deoplete/source/around.py @@ -8,10 +8,11 @@ import re from deoplete.base.source import Base from deoplete.util import parse_buffer_pattern, getlines +from deoplete.util import Nvim, UserContext, Candidates class Source(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'around' self.rank = 300 @@ -28,9 +29,9 @@ class Source(Base): if custom_vars: self.vars.update(custom_vars) - def gather_candidates(self, context): + def gather_candidates(self, context: UserContext) -> Candidates: line = context['position'][1] - candidates = [] + candidates: Candidates = [] # lines above words = parse_buffer_pattern( @@ -49,7 +50,7 @@ class Source(Base): p = re.compile(r'[\s\d]+') lines = set() for change_line in [ - x[p.search(x).span()[1]:] + x[p.search(x).span()[1]:] # type: ignore for x in self.vim.call('execute', 'changes').split('\n')[2:] if p.search(x) ]: diff --git a/rplugin/python3/deoplete/source/base.py b/rplugin/python3/deoplete/source/base.py index cc061d4..0c59b5a 100644 --- a/rplugin/python3/deoplete/source/base.py +++ b/rplugin/python3/deoplete/source/base.py @@ -6,8 +6,9 @@ # For backward compatibility from deoplete.base.source import Base as _Base +from deoplete.util import Nvim class Base(_Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) diff --git a/rplugin/python3/deoplete/source/buffer.py b/rplugin/python3/deoplete/source/buffer.py index 2512e23..26108d1 100644 --- a/rplugin/python3/deoplete/source/buffer.py +++ b/rplugin/python3/deoplete/source/buffer.py @@ -4,13 +4,16 @@ # License: MIT license # ============================================================================ +import typing + from deoplete.base.source import Base from deoplete.util import parse_buffer_pattern, getlines +from deoplete.util import Nvim, UserContext, Candidates class Source(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'buffer' @@ -21,10 +24,10 @@ class Source(Base): } self._limit = 1000000 - self._buffers = {} + self._buffers: typing.Dict[int, typing.Any] = {} self._max_lines = 5000 - def on_event(self, context): + def on_event(self, context: UserContext) -> None: self._make_cache(context) tab_bufnrs = self.vim.call('tabpagebuflist') @@ -34,10 +37,10 @@ class Source(Base): self.vim.call('buflisted', x['bufnr']) } - def gather_candidates(self, context): + def gather_candidates(self, context: UserContext) -> Candidates: tab_bufnrs = self.vim.call('tabpagebuflist') same_filetype = self.get_var('require_same_filetype') - return {'sorted_candidates': [ + return {'sorted_candidates': [ # type: ignore x['candidates'] for x in self._buffers.values() if not same_filetype or x['filetype'] in context['filetypes'] or @@ -45,7 +48,7 @@ class Source(Base): x['bufnr'] in tab_bufnrs ]} - def _make_cache(self, context): + def _make_cache(self, context: UserContext) -> None: # Bufsize check size = self.vim.call('line2byte', self.vim.call('line', '$') + 1) - 1 @@ -64,4 +67,4 @@ class Source(Base): ] } except UnicodeDecodeError: - return [] + return diff --git a/rplugin/python3/deoplete/source/file.py b/rplugin/python3/deoplete/source/file.py index e83b599..58df975 100644 --- a/rplugin/python3/deoplete/source/file.py +++ b/rplugin/python3/deoplete/source/file.py @@ -7,22 +7,23 @@ import os import re +import typing from os.path import exists, dirname from deoplete.base.source import Base -from deoplete.util import expand +from deoplete.util import expand, Nvim, UserContext, Candidates class Source(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'file' self.mark = '[F]' self.min_pattern_length = 0 self.rank = 150 - self.events = ['InsertEnter'] + self.events: typing.List[str] = ['InsertEnter'] self.vars = { 'enable_buffer_path': True, 'force_completion_length': -1, @@ -30,22 +31,23 @@ class Source(Base): self._isfname = '' - def on_event(self, context): + def on_event(self, context: UserContext) -> None: self._isfname = self.vim.call( 'deoplete#util#vimoption2python_not', self.vim.options['isfname']) - def get_complete_position(self, context): - pos = context['input'].rfind('/') - if pos < 0 and self.get_var('force_completion_length') >= 0: - fmt = '[a-zA-Z0-9.-]{{{}}}$'.format( - self.get_var('force_completion_length')) + def get_complete_position(self, context: UserContext) -> int: + pos = int(context['input'].rfind('/')) + force_completion_length = int( # type: ignore + self.get_var('force_completion_length')) + if pos < 0 and force_completion_length >= 0: + fmt = '[a-zA-Z0-9.-]{{{}}}$'.format(force_completion_length) m = re.search(fmt, context['input']) if m: return m.start() return pos if pos < 0 else pos + 1 - def gather_candidates(self, context): + def gather_candidates(self, context: UserContext) -> Candidates: if not self._isfname: self.on_event(context) @@ -60,7 +62,7 @@ class Source(Base): if not os.path.isdir(complete_str): return [] hidden = context['complete_str'].find('.') == 0 - contents = [[], []] + contents: typing.List[typing.Any] = [[], []] try: for item in sorted(os.listdir(complete_str), key=str.lower): if not hidden and item[0] == '.': @@ -73,16 +75,17 @@ class Source(Base): return [{'word': x, 'abbr': x + '/'} for x in dirs ] + [{'word': x} for x in files] - def _longest_path_that_exists(self, context, input_str): + def _longest_path_that_exists(self, context: UserContext, + input_str: str) -> str: input_str = re.sub(r'[^/]*$', '', input_str) data = re.split(r'((?:%s+|(?:(?<![\w\s/\.])(?:~|\.{1,2})?/)+))' % self._isfname, input_str) data = [''.join(data[i:]) for i in range(len(data))] existing_paths = sorted(filter(lambda x: exists( dirname(self._substitute_path(context, x))), data)) - return existing_paths[-1] if existing_paths else None + return existing_paths[-1] if existing_paths else '' - def _substitute_path(self, context, path): + def _substitute_path(self, context: UserContext, path: str) -> str: m = re.match(r'(\.{1,2})/+', path) if m: if self.get_var('enable_buffer_path') and context['bufpath']: diff --git a/rplugin/python3/deoplete/source/member.py b/rplugin/python3/deoplete/source/member.py index b9e9083..6cca1fb 100644 --- a/rplugin/python3/deoplete/source/member.py +++ b/rplugin/python3/deoplete/source/member.py @@ -5,15 +5,17 @@ # ============================================================================ import re +import typing from deoplete.base.source import Base from deoplete.util import ( convert2list, parse_buffer_pattern, set_pattern, getlines) +from deoplete.util import Nvim, UserContext, Candidates class Source(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'member' @@ -23,7 +25,7 @@ class Source(Base): self._object_pattern = r'[a-zA-Z_]\w*(?:\(\)?)?' self._prefix = '' - prefix_patterns = {} + prefix_patterns: typing.Dict[str, str] = {} set_pattern(prefix_patterns, '_', r'\.') set_pattern(prefix_patterns, @@ -40,7 +42,7 @@ class Source(Base): 'prefix_patterns': prefix_patterns, } - def get_complete_position(self, context): + def get_complete_position(self, context: UserContext) -> int: # Check member prefix pattern. for prefix_pattern in convert2list( self.get_filetype_var( @@ -50,10 +52,12 @@ class Source(Base): if m is None or prefix_pattern == '': continue self._prefix = re.sub(r'\w*$', '', m.group(0)) - return re.search(r'\w*$', context['input']).start() + m = re.search(r'\w*$', context['input']) + if m: + return m.start() return -1 - def gather_candidates(self, context): + def gather_candidates(self, context: UserContext) -> Candidates: return [{'word': x} for x in parse_buffer_pattern( getlines(self.vim), diff --git a/rplugin/python3/deoplete/source/omni.py b/rplugin/python3/deoplete/source/omni.py index 6fe9d39..9590145 100644 --- a/rplugin/python3/deoplete/source/omni.py +++ b/rplugin/python3/deoplete/source/omni.py @@ -5,15 +5,17 @@ # ============================================================================ import re +import typing from deoplete.base.source import Base from deoplete.util import ( convert2list, set_pattern, convert2candidates) +from deoplete.util import Nvim, UserContext, Candidates class Source(Base): - def __init__(self, vim): + def __init__(self, vim: Nvim) -> None: super().__init__(vim) self.name = 'omni' @@ -22,7 +24,7 @@ class Source(Base): self.is_bytepos = True self.min_pattern_length = 0 - input_patterns = {} + input_patterns: typing.Dict[str, str] = {} set_pattern(input_patterns, 'css,less,scss,sass', [r'\w{2}', r'\w+:?\s*\w*', r'[@!]']) self.vars = { @@ -30,7 +32,7 @@ class Source(Base): 'functions': {}, } - def get_complete_position(self, context): + def get_complete_position(self, context: UserContext) -> int: current_ft = self.get_buf_option('filetype') for filetype in list(set([context['filetype']] + @@ -40,7 +42,8 @@ class Source(Base): return pos return -1 - def _get_complete_position(self, context, current_ft, filetype): + def _get_complete_position(self, context: UserContext, + current_ft: str, filetype: str) -> int: for omnifunc in convert2list( self.get_filetype_var(filetype, 'functions')): if omnifunc == '' and (filetype == current_ft or @@ -67,7 +70,7 @@ class Source(Base): # In the blacklist return -1 try: - complete_pos = self.vim.call(self._omnifunc, 1, '') + complete_pos = int(self.vim.call(self._omnifunc, 1, '')) except Exception: self.print_error('Error occurred calling omnifunction: ' + self._omnifunc) @@ -75,7 +78,7 @@ class Source(Base): return complete_pos return -1 - def gather_candidates(self, context): + def gather_candidates(self, context: UserContext) -> Candidates: try: candidates = self.vim.call(self._omnifunc, 0, '') if isinstance(candidates, dict): @@ -91,4 +94,4 @@ class Source(Base): candidate['dup'] = 1 candidate['equal'] = 1 - return candidates + return candidates # type: ignore diff --git a/rplugin/python3/deoplete/util.py b/rplugin/python3/deoplete/util.py index 97ce2cf..9803e92 100644 --- a/rplugin/python3/deoplete/util.py +++ b/rplugin/python3/deoplete/util.py @@ -20,11 +20,13 @@ else: from neovim import Nvim from neovim.api import Buffer -Candidates = typing.Dict[str, typing.Any] +UserContext = typing.Dict[str, typing.Any] +Candidate = typing.Dict[str, typing.Any] +Candidates = typing.List[Candidate] def set_pattern(variable: typing.Dict[str, str], - keys: str, pattern: str) -> None: + keys: str, pattern: typing.Any) -> None: for key in keys.split(','): variable[key] = pattern @@ -33,7 +35,7 @@ def convert2list(expr: typing.Any) -> typing.List[typing.Any]: return (expr if isinstance(expr, list) else [expr]) -def convert2candidates(l: typing.Any) -> typing.List[typing.Any]: +def convert2candidates(l: typing.Any) -> Candidates: ret = [] if l and isinstance(l, list): for x in l: @@ -239,17 +241,20 @@ def binary_search_begin(l: typing.List[Candidates], prefix: str) -> int: if not l: return -1 if len(l) == 1: - return 0 if l[0]['word'].lower().startswith(prefix) else -1 + word = l[0]['word'] # type: ignore + return 0 if word.lower().startswith(prefix) else -1 s = 0 e = len(l) prefix = prefix.lower() while s < e: index = int((s + e) / 2) - word = l[index]['word'].lower() + word = l[index]['word'].lower() # type: ignore if word.startswith(prefix): - if (index - 1 < 0 or not - l[index-1]['word'].lower().startswith(prefix)): + if (index - 1) < 0: + return index + prev_word = l[index-1]['word'] # type: ignore + if not prev_word.lower().startswith(prefix): return index e = index elif prefix < word: @@ -263,17 +268,20 @@ def binary_search_end(l: typing.List[Candidates], prefix: str) -> int: if not l: return -1 if len(l) == 1: - return 0 if l[0]['word'].lower().startswith(prefix) else -1 + word = l[0]['word'] # type: ignore + return 0 if word.lower().startswith(prefix) else -1 s = 0 e = len(l) prefix = prefix.lower() while s < e: index = int((s + e) / 2) - word = l[index]['word'].lower() + word = l[index]['word'].lower() # type: ignore if word.startswith(prefix): - if ((index + 1) >= len(l) or not - l[index+1]['word'].lower().startswith(prefix)): + if (index + 1) >= len(l): + return index + next_word = l[index+1]['word'] # type: ignore + if not next_word.lower().startswith(prefix): return index s = index + 1 elif prefix < word: |