Example #1
0
    def _put(self, name, args):
        queue_id = str(time.time())

        if self._child:
            return self._child.main(name, args, queue_id)

        if not self._hnd:
            return None

        msg = self._packer.pack({
            'name': name,
            'args': args,
            'queue_id': queue_id
        })
        self._queue_in.put(msg)

        if self._stdin:
            try:
                while not self._queue_in.empty():
                    self._stdin.write(self._queue_in.get_nowait())
            except BrokenPipeError as e:
                error_tb(self._vim, 'Crash in child process')
                error(self._vim, 'stderr=' + str(self._proc.read_error()))
                self._hnd = None
        return queue_id
Example #2
0
    def load_filters(self, context):
        # Load filters from runtimepath
        for path in find_rplugins(context, 'filter'):
            name = os.path.splitext(os.path.basename(path))[0]
            if name in self.__filters:
                continue

            filter = None

            try:
                Filter = import_plugin(path, 'filter', 'Filter')
                if Filter is None:
                    continue

                filter = Filter(self.__vim)

                filter.name = getattr(filter, 'name', name)
                self.__filters[filter.name] = filter
            except Exception:
                # Exception occurred when loading a filter.  Log stack trace.
                error_tb(self.__vim, 'Could not load filter: %s' % name)
            finally:
                if filter is not None:
                    self.__filters[filter.name] = filter
                    self.debug('Loaded Filter: %s (%s)', filter.name, path)
Example #3
0
    def load_filters(self, context):
        # Load filters from runtimepath
        loaded_paths = [filter.path for filter in self.__filters.values()]
        for path in find_rplugins(context, 'filter'):
            if path in self.__ignored_filters:
                continue
            if path in loaded_paths:
                continue
            name = os.path.splitext(os.path.basename(path))[0]

            filter = None
            try:
                Filter = import_plugin(path, 'filter', 'Filter')
                if Filter is None:
                    continue

                filter = Filter(self.__vim)
                filter.name = getattr(filter, 'name', name)
                filter.path = path
                self.__filters[filter.name] = filter
            except Exception:
                # Exception occurred when loading a filter.  Log stack trace.
                error_tb(self.__vim, 'Could not load filter: %s' % name)
            finally:
                if filter is not None:
                    self.__filters[filter.name] = filter
                    self.debug('Loaded Filter: %s (%s)', filter.name, path)
Example #4
0
    def _itersource(self, context):
        filetypes = context['filetypes']
        ignore_sources = set(self._ignore_sources)
        for ft in filetypes:
            ignore_sources.update(
                self._vim.call('deoplete#custom#_get_filetype_option',
                               'ignore_sources', ft, []))

        for source_name, source in self._get_sources().items():
            if source.filetypes is None or source_name in ignore_sources:
                continue
            if context['sources'] and source_name not in context['sources']:
                continue
            if source.filetypes and not any(x in filetypes
                                            for x in source.filetypes):
                continue
            if not source.is_initialized and hasattr(source, 'on_init'):
                self.debug('on_init Source: %s', source.name)
                try:
                    source.on_init(context)
                except Exception as exc:
                    if isinstance(exc, SourceInitError):
                        error(self._vim, 'Error when loading source '
                              f'{source_name}: {exc}. Ignoring.')
                    else:
                        error_tb(self._vim, 'Error when loading source '
                                 f'{source_name}: {exc}. Ignoring.')
                    self._ignore_sources.append(source_name)
                    continue
                else:
                    source.is_initialized = True
            yield source_name, source
Example #5
0
    def load_sources(self, context):
        # Load sources from runtimepath
        for path in find_rplugins(context, 'source'):
            name = os.path.splitext(os.path.basename(path))[0]
            if name in self.__sources:
                continue

            source = None

            try:
                Source = import_plugin(path, 'source', 'Source')
                if Source is None:
                    continue
                source = Source(self.__vim)
                source.name = getattr(source, 'name', name)

                source.min_pattern_length = getattr(
                    source, 'min_pattern_length',
                    context['vars']['deoplete#auto_complete_start_length'])
                source.max_abbr_width = getattr(
                    source, 'max_abbr_width',
                    context['vars']['deoplete#max_abbr_width'])
                source.max_menu_width = getattr(
                    source, 'max_menu_width',
                    context['vars']['deoplete#max_menu_width'])

            except Exception:
                error_tb(self.__vim, 'Could not load source: %s' % name)
            finally:
                if source is not None:
                    self.__sources[source.name] = source
                    self.debug('Loaded Source: %s (%s)', source.name, path)

        self.set_source_attributes(context)
        self.__custom = context['custom']
Example #6
0
    def load_filters(self, context):
        # Load filters from runtimepath
        for path in find_rplugins(context, 'filter'):
            if path in self._ignored_filters or path in self._loaded_paths:
                continue
            self._loaded_paths.add(path)

            name = os.path.splitext(os.path.basename(path))[0]

            f = None
            try:
                Filter = import_plugin(path, 'filter', 'Filter')
                if not Filter:
                    continue

                f = Filter(self._vim)
                f.name = getattr(f, 'name', name)
                f.path = path
                self._filters[f.name] = f
            except Exception:
                # Exception occurred when loading a filter.  Log stack trace.
                error_tb(self._vim, 'Could not load filter: %s' % name)
            finally:
                if f:
                    self._filters[f.name] = f
                    self.debug('Loaded Filter: %s (%s)', f.name, path)
Example #7
0
    def completion_begin(self, context):
        self.check_recache(context)

        try:
            is_async, complete_position, candidates = self.merge_results(
                self.gather_results(context), context['input'])

        except Exception:
            error_tb(self._vim, 'Error while gathering completions')

            is_async = False
            complete_position = -1
            candidates = []

        if is_async:
            self._vim.call('deoplete#handler#_async_timer_start')
        else:
            self._vim.call('deoplete#handler#_async_timer_stop')

        if not candidates and ('deoplete#_saved_completeopt'
                               in context['vars']):
            self._vim.call('deoplete#mapping#_restore_completeopt')

        # error(self._vim, context['input'])
        # error(self._vim, candidates)
        self._vim.vars['deoplete#_context'] = {
            'complete_position': complete_position,
            'candidates': candidates,
            'event': context['event'],
            'input': context['input'],
        }
Example #8
0
    def completion_begin(self, context):
        self.check_recache(context)

        try:
            is_async, complete_position, candidates = self.merge_results(
                self.gather_results(context), context['input'])

        except Exception:
            error_tb(self._vim, 'Error while gathering completions')

            is_async = False
            complete_position = -1
            candidates = []

        if is_async:
            self._vim.call('deoplete#handler#_async_timer_start')
        else:
            self._vim.call('deoplete#handler#_async_timer_stop')

        if not candidates and ('deoplete#_saved_completeopt'
                               in context['vars']):
            self._vim.call('deoplete#mapping#_restore_completeopt')

        # error(self._vim, context['input'])
        # error(self._vim, candidates)
        self._vim.vars['deoplete#_context'] = {
            'complete_position': complete_position,
            'candidates': candidates,
            'event': context['event'],
            'input': context['input'],
        }
Example #9
0
    def load_filters(self, context):
        # Load filters from runtimepath
        for path in find_rplugins(context, 'filter'):
            if path in self._ignored_filters or path in self._loaded_paths:
                continue
            self._loaded_paths.add(path)

            name = os.path.splitext(os.path.basename(path))[0]

            f = None
            try:
                Filter = import_plugin(path, 'filter', 'Filter')
                if not Filter:
                    continue

                f = Filter(self._vim)
                f.name = getattr(f, 'name', name)
                f.path = path
                self._filters[f.name] = f
            except Exception:
                # Exception occurred when loading a filter.  Log stack trace.
                error_tb(self._vim, 'Could not load filter: %s' % name)
            finally:
                if f:
                    self._filters[f.name] = f
                    self.debug('Loaded Filter: %s (%s)', f.name, path)
Example #10
0
    def load_sources(self, context):
        # Load sources from runtimepath
        for path in find_rplugins(context, 'source'):
            if path in self._loaded_paths:
                continue
            self._loaded_paths.add(path)

            name = os.path.splitext(os.path.basename(path))[0]

            source = None
            try:
                Source = import_plugin(path, 'source', 'Source')
                if not Source:
                    continue

                source = Source(self._vim)
                source.name = getattr(source, 'name', name)
                source.path = path
            except Exception:
                error_tb(self._vim, 'Could not load source: %s' % name)
            finally:
                if source:
                    self._sources[source.name] = source
                    self.debug('Loaded Source: %s (%s)', source.name, path)

        self.set_source_attributes(context)
        self._custom = context['custom']
Example #11
0
    def completion_begin(self, context):
        try:
            complete_position, candidates = self.gather_candidates(context)
        except Exception:
            error_tb(self._vim, 'Error while gathering completions')
            candidates = []

        if not candidates or self.position_has_changed(
                context['changedtick']) or self._vim.funcs.mode() != 'i':
            if 'deoplete#_saved_completeopt' in context['vars']:
                self._vim.call('deoplete#mapping#_restore_completeopt')
            return

        self._vim.vars['deoplete#_context'] = {
            'complete_position': complete_position,
            'changedtick': context['changedtick'],
            'candidates': candidates,
            'event': context['event'],
        }

        if context['event'] != 'Manual' and (
                'deoplete#_saved_completeopt' not in context['vars']):
            self._vim.call('deoplete#mapping#_set_completeopt')

        self._vim.feedkeys(context['start_complete'])
        if self._vim.call(
                'has', 'patch-7.4.1758') and context['event'] != 'Manual':
            self._vim.feedkeys('', 'x!')
Example #12
0
    def _itersource(self, context):
        filetypes = context['filetypes']
        ignore_sources = set(self._ignore_sources)
        for ft in filetypes:
            ignore_sources.update(
                self._vim.call('deoplete#custom#_get_filetype_option',
                               'ignore_sources', ft, []))

        for source_name, source in self._get_sources().items():
            if source.filetypes is None or source_name in ignore_sources:
                continue
            if context['sources'] and source_name not in context['sources']:
                continue
            if source.filetypes and not any(x in filetypes
                                            for x in source.filetypes):
                continue
            if not source.is_initialized and hasattr(source, 'on_init'):
                self.debug('on_init Source: %s', source.name)
                try:
                    source.on_init(context)
                except Exception as exc:
                    if isinstance(exc, SourceInitError):
                        error(
                            self._vim, 'Error when loading source {}: {}. '
                            'Ignoring.'.format(source_name, exc))
                    else:
                        error_tb(
                            self._vim, 'Error when loading source {}: {}. '
                            'Ignoring.'.format(source_name, exc))
                    self._ignore_sources.append(source_name)
                    continue
                else:
                    source.is_initialized = True
            yield source_name, source
Example #13
0
    def completion_begin(self, context):
        try:
            complete_position, candidates = self.gather_candidates(context)
        except Exception:
            error_tb(self._vim, 'Error while gathering completions')
            candidates = []

        if not candidates or self.position_has_changed(
                context['changedtick']) or self._vim.funcs.mode() != 'i':
            if 'deoplete#_saved_completeopt' in context['vars']:
                self._vim.call('deoplete#mapping#_restore_completeopt')
            return

        self._vim.vars['deoplete#_context'] = {
            'complete_position': complete_position,
            'changedtick': context['changedtick'],
            'candidates': candidates,
            'event': context['event'],
        }

        if context['event'] != 'Manual' and ('deoplete#_saved_completeopt'
                                             not in context['vars']):
            self._vim.call('deoplete#mapping#_set_completeopt')

        self._vim.feedkeys(context['start_complete'])
Example #14
0
    def itersource(self, context):
        sources = sorted(self.__sources.items(),
                         key=lambda x: get_custom(context['custom'], x[1].name,
                                                  'rank', x[1].rank),
                         reverse=True)
        filetypes = context['filetypes']
        ignore_sources = set()
        for ft in filetypes:
            ignore_sources.update(
                get_buffer_config(context, ft, 'deoplete_ignore_sources',
                                  'deoplete#ignore_sources', {}))

        for source_name, source in sources:
            if (source_name in ignore_sources):
                continue
            if context['sources'] and source_name not in context['sources']:
                continue
            if source.filetypes and not any(x in filetypes
                                            for x in source.filetypes):
                continue
            if not source.is_initialized and hasattr(source, 'on_init'):
                self.debug('on_init Source: %s', source.name)
                try:
                    source.on_init(context)
                except Exception as exc:
                    error_tb(
                        self.__vim, 'Error when loading source {}. '
                        'Ignoring.'.format(source_name, exc))
                    self.__ignored_sources.add(source.path)
                    self.__sources.pop(source_name)
                    continue
                else:
                    source.is_initialized = True

            yield source_name, source
Example #15
0
    def _itersource(self, context: UserContext
                    ) -> typing.Generator[typing.Any, None, None]:
        filetypes = context['filetypes']
        ignore_sources = set(self._ignore_sources)
        for ft in filetypes:
            ignore_sources.update(
                self._vim.call('deoplete#custom#_get_filetype_option',
                               'ignore_sources', ft, []))

        for source_name, source in self._get_sources().items():
            if source.filetypes is None or source_name in ignore_sources:
                continue
            if context['sources'] and source_name not in context['sources']:
                continue
            if source.filetypes and not any(x in filetypes
                                            for x in source.filetypes):
                continue
            if not source.is_initialized and hasattr(source, 'on_init'):
                self.debug('on_init Source: ' + source.name)  # type: ignore
                try:
                    context['vars'] = self._vim.vars
                    source.on_init(context)
                    context['vars'] = None
                except Exception as exc:
                    if isinstance(exc, SourceInitError):
                        error(self._vim, 'Error when loading source '
                              f'{source_name}: {exc}. Ignoring.')
                    else:
                        error_tb(self._vim, 'Error when loading source '
                                 f'{source_name}: {exc}. Ignoring.')
                    self._ignore_sources.append(source_name)
                    continue
                else:
                    source.is_initialized = True
            yield source_name, source
Example #16
0
    def completion_begin(self, user_context: UserContext) -> None:
        if not self._context:
            self.init_context()

        context = self._context.get(user_context['event'])  # type: ignore
        context.update(user_context)

        self.debug(
            'completion_begin (%s): %r',  # type: ignore
            context['event'],
            context['input'])

        if self._vim.call('deoplete#handler#_check_omnifunc', context):
            return

        self._check_recache(context)

        try:
            (is_async, needs_poll, position,
             candidates) = self._merge_results(context)
        except Exception:
            error_tb(self._vim, 'Error while gathering completions')

            is_async = False
            needs_poll = False
            position = -1
            candidates = []

        if needs_poll:
            self._vim.call('deoplete#handler#_async_timer_start')

        # Async update is skipped if same.
        prev_completion = self._vim.vars['deoplete#_prev_completion']
        prev_candidates = prev_completion['candidates']
        event = context['event']
        if (event == 'Async' or event == 'Update' and prev_candidates
                and candidates == prev_candidates):
            return

        # error(self._vim, candidates)
        self._vim.vars['deoplete#_context'] = {
            'complete_position': position,
            'candidates': candidates,
            'event': context['event'],
            'input': context['input'],
            'is_async': needs_poll,
        }

        if candidates or self._vim.call('deoplete#util#check_popup'):
            self.debug(
                'do_complete (%s): '  # type: ignore
                + '%d candidates, input=%s, complete_position=%d, ' +
                'is_async=%d',
                context['event'],
                len(candidates),
                context['input'],
                position,
                is_async)
            self._vim.call('deoplete#handler#_do_complete')
Example #17
0
    def completion_begin(self, user_context):
        if not self._context:
            self.init_context()

        context = self._context.get(user_context['event'])
        context.update(user_context)

        self.debug('completion_begin (%s): %r',
                   context['event'], context['input'])

        if self._vim.call('deoplete#handler#_check_omnifunc', context):
            return

        self._check_recache(context)

        try:
            is_async, position, candidates = self._merge_results(context)
        except Exception:
            error_tb(self._vim, 'Error while gathering completions')

            is_async = False
            position = -1
            candidates = []

        # is_async = True
        if is_async:
            self._vim.call('deoplete#handler#_async_timer_start')
        else:
            self._vim.call('deoplete#handler#_async_timer_stop')

        if not candidates and ('deoplete#_saved_completeopt'
                               in self._vim.vars):
            self._vim.call('deoplete#mapping#_restore_completeopt')

        # Async update is skipped if same.
        prev_completion = self._vim.vars['deoplete#_prev_completion']
        prev_candidates = prev_completion['candidates']
        if (context['event'] == 'Async' and
                prev_candidates and len(candidates) <= len(prev_candidates)):
            return

        # error(self._vim, candidates)
        self._vim.vars['deoplete#_context'] = {
            'complete_position': position,
            'candidates': candidates,
            'event': context['event'],
            'input': context['input'],
            'is_async': is_async,
        }
        self.debug('do_complete (%s): '
                   + '%d candidates, input=%s, complete_position=%d, '
                   + 'is_async=%d',
                   context['event'],
                   len(candidates), context['input'], position,
                   is_async)
        self._vim.call('deoplete#handler#_do_complete')
Example #18
0
    def completion_begin(self, user_context):
        if not self._context:
            self.init_context()

        context = self._context.get(user_context['event'])
        context.update(user_context)

        self.debug('completion_begin (%s): %r', context['event'],
                   context['input'])

        if self._vim.call('deoplete#handler#_check_omnifunc', context):
            return

        self._check_recache(context)

        try:
            (is_async, needs_poll, position,
             candidates) = self._merge_results(context)
        except Exception:
            error_tb(self._vim, 'Error while gathering completions')

            is_async = False
            needs_poll = False
            position = -1
            candidates = []

        if needs_poll:
            self._vim.call('deoplete#handler#_async_timer_start')

        if not candidates and ('deoplete#_saved_completeopt'
                               in self._vim.vars):
            self._vim.call('deoplete#mapping#_restore_completeopt')

        # Async update is skipped if same.
        prev_completion = self._vim.vars['deoplete#_prev_completion']
        prev_candidates = prev_completion['candidates']
        if (context['event'] == 'Async'
                and context['event'] == prev_completion['event']
                and prev_candidates
                and len(candidates) <= len(prev_candidates)):
            return

        # error(self._vim, candidates)
        self._vim.vars['deoplete#_context'] = {
            'complete_position': position,
            'candidates': candidates,
            'event': context['event'],
            'input': context['input'],
            'is_async': is_async,
        }
        self.debug(
            'do_complete (%s): ' +
            '%d candidates, input=%s, complete_position=%d, ' + 'is_async=%d',
            context['event'], len(candidates), context['input'], position,
            is_async)
        self._vim.call('deoplete#handler#_do_complete')
Example #19
0
 def _on_event(self, context):
     event = context['event']
     for source_name, source in self._itersource(context):
         if source.events is None or event in source.events:
             try:
                 source.on_event(context)
             except Exception as exc:
                 error_tb(
                     self._vim, 'Exception during {}.on_event '
                     'for event {!r}: {}'.format(source_name, event, exc))
Example #20
0
 def _on_event(self, context):
     for source_name, source in self._itersource(context):
         if source.events is None or context['event'] in source.events:
             self.debug('on_event: Source: %s', source_name)
             try:
                 source.on_event(context)
             except Exception as exc:
                 error_tb(self._vim, 'Exception during {}.on_event '
                          'for event {!r}: {}'.format(
                              source_name, context['event'], exc))
Example #21
0
 def _on_event(self, context):
     event = context['event']
     for source_name, source in self._itersource(context):
         if source.events is None or event in source.events:
             try:
                 source.on_event(context)
             except Exception as exc:
                 error_tb(self._vim, 'Exception during {}.on_event '
                          'for event {!r}: {}'.format(
                              source_name, event, exc))
Example #22
0
 def _on_event(self, context):
     for source_name, source in self._itersource(context):
         if hasattr(source, 'on_event'):
             self.debug('on_event: Source: %s', source_name)
             try:
                 source.on_event(context)
             except Exception as exc:
                 error_tb(self._vim, 'Exception during {}.on_event '
                          'for event {!r}: {}'.format(
                              source_name, context['event'], exc))
Example #23
0
def main(serveraddr):
    vim = attach_vim(serveraddr)
    from deoplete.child import Child
    from deoplete.util import error_tb
    stdout = sys.stdout
    sys.stdout = RedirectStream(lambda data: vim.out_write(data))
    sys.stderr = RedirectStream(lambda data: vim.err_write(data))
    try:
        child = Child(vim)
        child.main_loop(stdout)
    except Exception as exc:
        error_tb(vim, 'Error in child: %r' % exc)
Example #24
0
def main(serveraddr):
    vim = attach_vim(serveraddr)
    from deoplete.util import error_tb
    child = None
    try:
        from deoplete.child import Child
        child = Child(vim)
        while 1:
            child.main()
    except Exception:
        error_tb(vim, 'Error in child')
    return
Example #25
0
def main(serveraddr):
    vim = attach_vim(serveraddr)
    from deoplete.child import Child
    from deoplete.util import error_tb
    stdout = sys.stdout
    sys.stdout = RedirectStream(lambda data: vim.out_write(data))
    sys.stderr = RedirectStream(lambda data: vim.err_write(data))
    try:
        child = Child(vim)
        child.main_loop(stdout)
    except Exception as exc:
        error_tb(vim, 'Error in child: %r' % exc)
Example #26
0
    def _on_event(self, context):
        event = context['event']
        for source_name, source in self._itersource(context):
            if source.events is None or event in source.events:
                try:
                    source.on_event(context)
                except Exception as exc:
                    error_tb(self._vim,
                             f'Exception during {source.name}.on_event '
                             'for event {!r}: {}'.format(event, exc))

        for f in self._filters.values():
            f.on_event(context)
Example #27
0
    def on_event(self, context):
        self.debug('on_event: %s', context['event'])
        self.check_recache(context)

        for source_name, source in self.itersource(context):
            if hasattr(source, 'on_event'):
                self.debug('on_event: Source: %s', source_name)
                try:
                    source.on_event(context)
                except Exception as exc:
                    error_tb(self._vim, 'Exception during {}.on_event '
                             'for event {!r}: {}'.format(
                                 source_name, context['event'], exc))
Example #28
0
    def _on_event(self, context):
        event = context['event']
        for source_name, source in self._itersource(context):
            if source.events is None or event in source.events:
                try:
                    source.on_event(context)
                except Exception as exc:
                    error_tb(self._vim,
                             f'Exception during {source.name}.on_event '
                             'for event {!r}: {}'.format(event, exc))

        for f in self._filters.values():
            f.on_event(context)
Example #29
0
    def _get(self, queue_id):
        if not self._hnd:
            return []

        outs = []
        while not self._queue_out.empty():
            outs.append(self._queue_out.get_nowait())
        try:
            return [x for x in outs if x['queue_id'] == queue_id]
        except TypeError:
            error_tb(
                self._vim, '"stdout" seems contaminated by sources. '
                '"stdout" is used for RPC; Please pipe or discard')
            return []
Example #30
0
    def _get(self, queue_id):
        if not self._hnd:
            return []

        outs = []
        while not self._queue_out.empty():
            outs.append(self._queue_out.get_nowait())
        try:
            return [x for x in outs if x['queue_id'] == queue_id]
        except TypeError:
            error_tb(self._vim,
                     '"stdout" seems contaminated by sources. '
                     '"stdout" is used for RPC; Please pipe or discard')
            return []
Example #31
0
    def _on_event(self, context: UserContext) -> None:
        event = context['event']
        context['vars'] = self._vim.vars
        for source_name, source in self._itersource(context):
            if not source.events or event in source.events:
                try:
                    source.on_event(context)
                except Exception as exc:
                    error_tb(self._vim,
                             f'Exception during {source.name}.on_event '
                             'for event {!r}: {}'.format(event, exc))

        for f in self._filters.values():
            f.on_event(context)
        context['vars'] = None
Example #32
0
 def _process_filter(self, f, context):
     try:
         self._profile_start(context, f.name)
         if (isinstance(context['candidates'], dict) and
                 'sorted_candidates' in context['candidates']):
             context_candidates = []
             context['is_sorted'] = True
             for candidates in context['candidates']['sorted_candidates']:
                 context['candidates'] = candidates
                 context_candidates += f.filter(context)
             context['candidates'] = context_candidates
         else:
             context['candidates'] = f.filter(context)
         self._profile_end(f.name)
     except Exception:
         error_tb(self._vim, 'Errors from: %s' % f)
Example #33
0
 def _process_filter(self, f, context, max_candidates):
     try:
         self._profile_start(context, f.name)
         if (isinstance(context['candidates'], dict) and
                 'sorted_candidates' in context['candidates']):
             filtered = []
             context['is_sorted'] = True
             for candidates in context['candidates']['sorted_candidates']:
                 context['candidates'] = candidates
                 filtered += f.filter(context)
         else:
             filtered = f.filter(context)
         if max_candidates > 0:
             filtered = filtered[: max_candidates]
         context['candidates'] = filtered
         self._profile_end(f.name)
     except Exception:
         error_tb(self._vim, 'Errors from: %s' % f)
Example #34
0
    def _handle_source_exception(self, source, exc):
        if isinstance(exc, SourceInitError):
            error(self._vim,
                  f'Error when loading source {source.name}: {exc}. '
                  'Ignoring.')
            self._ignore_sources.append(source.name)
            return

        self._source_errors[source.name] += 1
        if source.is_silent:
            return
        if self._source_errors[source.name] > 2:
            error(self._vim,
                  f'Too many errors from "{source.name}". '
                  'This source is disabled until Neovim is restarted.')
            self._ignore_sources.append(source.name)
        else:
            error_tb(self._vim, f'Error from {source.name}: {exc}')
Example #35
0
    def _handle_source_exception(self, source, exc):
        if isinstance(exc, SourceInitError):
            error(self._vim,
                  f'Error when loading source {source.name}: {exc}. '
                  'Ignoring.')
            self._ignore_sources.append(source.name)
            return

        self._source_errors[source.name] += 1
        if source.is_silent:
            return
        if self._source_errors[source.name] > 2:
            error(self._vim,
                  f'Too many errors from "{source.name}". '
                  'This source is disabled until Neovim is restarted.')
            self._ignore_sources.append(source.name)
        else:
            error_tb(self._vim, f'Error from {source.name}: {exc}')
Example #36
0
    def _handle_source_exception(self, source, exc):
        if isinstance(exc, SourceInitError):
            error(self._vim,
                  'Error when loading source {}: {}. '
                  'Ignoring.'.format(source.name, exc))
            self._ignore_sources.append(source.name)
            return

        self._source_errors[source.name] += 1
        if source.is_silent:
            return
        if self._source_errors[source.name] > 2:
            error(self._vim, 'Too many errors from "%s". '
                  'This source is disabled until Neovim '
                  'is restarted.' % source.name)
            self._ignore_sources.append(source.name)
        else:
            error_tb(self._vim, 'Error from %s: %r' % (source.name, exc))
Example #37
0
 def _process_filter(self, f, context, max_candidates):
     try:
         self._profile_start(context, f.name)
         if (isinstance(context['candidates'], dict)
                 and 'sorted_candidates' in context['candidates']):
             filtered = []
             context['is_sorted'] = True
             for candidates in context['candidates']['sorted_candidates']:
                 context['candidates'] = candidates
                 filtered += f.filter(context)
         else:
             filtered = f.filter(context)
         if max_candidates > 0:
             filtered = filtered[:max_candidates]
         context['candidates'] = filtered
         self._profile_end(f.name)
     except Exception:
         error_tb(self._vim, 'Errors from: %s' % f)
Example #38
0
    def completion_begin(self, context):
        self.debug('completion_begin: %s', context['input'])

        self._check_recache(context)

        try:
            is_async, position, candidates = self._merge_results(context)
        except Exception:
            error_tb(self._vim, 'Error while gathering completions')

            is_async = False
            position = -1
            candidates = []

        if is_async:
            self._vim.call('deoplete#handler#_async_timer_start')
        else:
            self._vim.call('deoplete#handler#_async_timer_stop')

        if not candidates and ('deoplete#_saved_completeopt'
                               in context['vars']):
            self._vim.call('deoplete#mapping#_restore_completeopt')

        # Async update is skipped if same.
        prev_completion = context['vars']['deoplete#_prev_completion']
        prev_candidates = prev_completion['candidates']
        prev_pos = prev_completion['complete_position']
        if (context['event'] == 'Async'
                and prev_pos == self._vim.call('getpos', '.')
                and prev_candidates
                and len(candidates) <= len(prev_candidates)):
            return

        # error(self._vim, candidates)
        self._vim.vars['deoplete#_context'] = {
            'complete_position': position,
            'candidates': candidates,
            'event': context['event'],
            'input': context['input'],
            'is_async': is_async,
        }
        self._vim.call('deoplete#handler#_do_complete')

        self.debug('completion_end: %s', context['input'])
Example #39
0
    def itersource(self, context):
        sources = sorted(self._sources.items(),
                         key=lambda x: get_custom(
                             context['custom'],
                             x[1].name, 'rank', x[1].rank),
                         reverse=True)
        filetypes = context['filetypes']
        ignore_sources = set()
        for ft in filetypes:
            ignore_sources.update(
                get_buffer_config(context, ft,
                                  'deoplete_ignore_sources',
                                  'deoplete#ignore_sources',
                                  {}))

        for source_name, source in sources:
            if source.limit > 0 and context['bufsize'] > source.limit:
                continue
            if source.filetypes is None or source_name in ignore_sources:
                continue
            if context['sources'] and source_name not in context['sources']:
                continue
            if source.filetypes and not any(x in filetypes
                                            for x in source.filetypes):
                continue
            if not source.is_initialized and hasattr(source, 'on_init'):
                self.debug('on_init Source: %s', source.name)
                try:
                    source.on_init(context)
                except Exception as exc:
                    if isinstance(exc, SourceInitError):
                        error(self._vim,
                              'Error when loading source {}: {}. '
                              'Ignoring.'.format(source_name, exc))
                    else:
                        error_tb(self._vim,
                                 'Error when loading source {}: {}. '
                                 'Ignoring.'.format(source_name, exc))
                    self._ignored_sources.add(source.path)
                    self._sources.pop(source_name)
                    continue
                else:
                    source.is_initialized = True
            yield source_name, source
Example #40
0
    def completion_begin(self, context):
        try:
            complete_position, candidates = self.gather_candidates(context)
        except Exception:
            error_tb(self.__vim, 'Error while gathering completions')
            candidates = []

        if not candidates or self.position_has_changed(
                context['changedtick']) or self.__vim.funcs.mode() != 'i':
            return

        self.__vim.vars['deoplete#_context'] = {
            'complete_position': complete_position,
            'changedtick': context['changedtick'],
            'candidates': candidates,
            'event': context['event'],
        }

        self.__vim.feedkeys(context['start_complete'])
Example #41
0
    def _put(self, name, args):
        if not self._hnd:
            return None

        queue_id = str(time.time())
        msg = self._packer.pack({
            'name': name, 'args': args, 'queue_id': queue_id
        })
        self._queue_in.put(msg)

        if self._stdin:
            try:
                while not self._queue_in.empty():
                    self._stdin.write(self._queue_in.get_nowait())
            except BrokenPipeError:
                error_tb(self._vim, 'Crash in child process')
                error(self._vim, 'stderr=' + str(self._proc.read_error()))
                self._hnd = None
        return queue_id
Example #42
0
    def completion_begin(self, context):
        self.debug('completion_begin: %s', context['input'])

        self._check_recache(context)

        try:
            is_async, position, candidates = self._merge_results(context)
        except Exception:
            error_tb(self._vim, 'Error while gathering completions')

            is_async = False
            position = -1
            candidates = []

        if is_async:
            self._vim.call('deoplete#handler#_async_timer_start')
        else:
            self._vim.call('deoplete#handler#_async_timer_stop')

        if not candidates and ('deoplete#_saved_completeopt'
                               in context['vars']):
            self._vim.call('deoplete#mapping#_restore_completeopt')

        # Async update is skipped if same.
        prev_completion = context['vars']['deoplete#_prev_completion']
        prev_candidates = prev_completion['candidates']
        prev_pos = prev_completion['complete_position']
        if (context['event'] == 'Async' and
                prev_pos == self._vim.call('getpos', '.') and
                prev_candidates and len(candidates) <= len(prev_candidates)):
            return

        # error(self._vim, candidates)
        self._vim.vars['deoplete#_context'] = {
            'complete_position': position,
            'candidates': candidates,
            'event': context['event'],
            'input': context['input'],
            'is_async': is_async,
        }
        self._vim.call('deoplete#handler#_do_complete')

        self.debug('completion_end: %s', context['input'])
Example #43
0
    def _put(self, name, args):
        queue_id = str(time.time())

        if self._proc:
            try:
                self._proc.write({
                    'name': name,
                    'args': args,
                    'queue_id': queue_id
                })
            except BrokenPipeError as e:
                error_tb(self._vim, 'Crash in child process')
                error(self._vim, 'stderr=' + str(self._proc.read_error()))
                self._proc.kill()
            return queue_id
        elif self._child:
            return self._child.main(name, args, queue_id)
        else:
            return None
Example #44
0
    def _handle_source_exception(self, source, exc):
        if isinstance(exc, SourceInitError):
            error(
                self._vim, 'Error when loading source {}: {}. '
                'Ignoring.'.format(source.name, exc))
            self._ignore_sources.append(source.name)
            return

        self._source_errors[source.name] += 1
        if source.is_silent:
            return
        if self._source_errors[source.name] > 2:
            error(
                self._vim, 'Too many errors from "%s". '
                'This source is disabled until Neovim '
                'is restarted.' % source.name)
            self._ignore_sources.append(source.name)
        else:
            error_tb(self._vim, 'Error from %s: %r' % (source.name, exc))
Example #45
0
    def completion_begin(self, context):
        try:
            complete_position, candidates = self.gather_candidates(context)
        except Exception:
            error_tb(self.__vim, 'Error while gathering completions')
            candidates = []

        if not candidates or self.position_has_changed(
                context['changedtick']) or self.__vim.funcs.mode() != 'i':
            return

        self.__vim.vars['deoplete#_context'] = {
            'complete_position': complete_position,
            'changedtick': context['changedtick'],
            'candidates': candidates,
            'event': context['event'],
        }

        self.__vim.feedkeys(context['start_complete'])
Example #46
0
    def _get(self, queue_id: str) -> typing.List[typing.Any]:
        if not self._hnd:
            return []

        check_stderr = self._vim.call(
            'deoplete#custom#_get_option', 'check_stderr')
        while check_stderr and not self._queue_err.empty():
            self._print_error(self._queue_err.get_nowait())

        outs = []
        while not self._queue_out.empty():
            outs.append(self._queue_out.get_nowait())
        try:
            return [x for x in outs if x['queue_id'] == queue_id]
        except TypeError:
            error_tb(self._vim,
                     '"stdout" seems contaminated by sources. '
                     '"stdout" is used for RPC; Please pipe or discard')
            return []
Example #47
0
 def _gather_async_results(self, result, source):
     try:
         context = result['context']
         context['is_refresh'] = False
         async_candidates = source.gather_candidates(context)
         result['is_async'] = context['is_async']
         if async_candidates is None:
             return
         context['candidates'] += convert2candidates(async_candidates)
     except Exception:
         self._source_errors[source.name] += 1
         if source.is_silent:
             return
         if self._source_errors[source.name] > 2:
             error(self._vim, 'Too many errors from "%s". '
                   'This source is disabled until Neovim '
                   'is restarted.' % source.name)
             self._ignore_sources.append(source.name)
         else:
             error_tb(self._vim, 'Errors from: %s' % source.name)
Example #48
0
 def _gather_async_results(self, result, source):
     try:
         context = result['context']
         context['is_refresh'] = False
         async_candidates = source.gather_candidates(context)
         result['is_async'] = context['is_async']
         if async_candidates is None:
             return
         context['candidates'] += convert2candidates(async_candidates)
     except Exception as exc:
         self._source_errors[source.name] += 1
         if source.is_silent:
             return
         if self._source_errors[source.name] > 2:
             error(self._vim, 'Too many errors from "%s". '
                   'This source is disabled until Neovim '
                   'is restarted.' % source.name)
             self._ignore_sources.append(source.name)
         else:
             error_tb(self._vim, 'Error from %s: %r' % (source.name, exc))
Example #49
0
    def _put(self, name: str,
             args: typing.List[typing.Any]) -> typing.Optional[str]:
        if not self._hnd:
            return None

        queue_id = str(time.time())
        msg = self._packer.pack({
            'name': name, 'args': args, 'queue_id': queue_id
        })
        self._queue_in.put(msg)

        if self._stdin:
            try:
                while not self._queue_in.empty():
                    self._stdin.write(self._queue_in.get_nowait())
            except BrokenPipeError:
                error_tb(self._vim, 'Crash in child process')
                error(self._vim, 'stderr=' +
                      str(self._proc.read_error()))  # type: ignore
                self._hnd = None
        return queue_id
Example #50
0
    def _add_source(self, path):
        source = None
        try:
            Source = import_plugin(path, 'source', 'Source')
            if not Source:
                return

            source = Source(self._vim)
            name = os.path.splitext(os.path.basename(path))[0]
            source.name = getattr(source, 'name', name)
            source.path = path
            if source.name in self._loaded_sources:
                # Duplicated name
                error_tb(self._vim, 'Duplicated source: %s' % source.name)
                error_tb(
                    self._vim, 'path: "%s" "%s"' %
                    (path, self._loaded_sources[source.name]))
                source = None
        except Exception:
            error_tb(self._vim, 'Could not load source: %s' % path)
        finally:
            if source:
                self._loaded_sources[source.name] = path
                self._sources[source.name] = source
                self.debug('Loaded Source: %s (%s)', source.name, path)
Example #51
0
    def _add_filter(self, path):
        f = None
        try:
            Filter = import_plugin(path, 'filter', 'Filter')
            if not Filter:
                return

            f = Filter(self._vim)
            name = os.path.splitext(os.path.basename(path))[0]
            f.name = getattr(f, 'name', name)
            f.path = path
            if f.name in self._loaded_filters:
                # Duplicated name
                error_tb(self._vim, 'Duplicated filter: %s' % f.name)
                error_tb(self._vim, 'path: "%s" "%s"' %
                         (path, self._loaded_filters[f.name]))
                f = None
        except Exception:
            # Exception occurred when loading a filter.  Log stack trace.
            error_tb(self._vim, 'Could not load filter: %s' % path)
        finally:
            if f:
                self._loaded_filters[f.name] = path
                self._filters[f.name] = f
                self.debug('Loaded Filter: %s (%s)', f.name, path)
Example #52
0
    def _add_source(self, path):
        source = None
        try:
            Source = import_plugin(path, 'source', 'Source')
            if not Source:
                return

            source = Source(self._vim)
            name = os.path.splitext(os.path.basename(path))[0]
            source.name = getattr(source, 'name', name)
            source.path = path
            if source.name in self._loaded_sources:
                # Duplicated name
                error_tb(self._vim, 'Duplicated source: %s' % source.name)
                error_tb(self._vim, 'path: "%s" "%s"' %
                         (path, self._loaded_sources[source.name]))
                source = None
        except Exception:
            error_tb(self._vim, 'Could not load source: %s' % path)
        finally:
            if source:
                self._loaded_sources[source.name] = path
                self._sources[source.name] = source
                self.debug('Loaded Source: %s (%s)', source.name, path)
Example #53
0
    def merge_results(self, results, context_input):
        merged_results = []
        all_candidates = []
        for result in [x for x in results
                       if not self.is_skip(x['context'], x['source'])]:
            source = result['source']

            # Gather async results
            if result['is_async']:
                async_candidates = source.gather_candidates(
                    result['context'])
                result['is_async'] = result['context']['is_async']
                if async_candidates is None:
                    continue
                result['context']['candidates'] += convert2candidates(
                    async_candidates)

            if not result['context']['candidates']:
                continue

            context = copy.deepcopy(result['context'])

            context['input'] = context_input
            context['complete_str'] = context['input'][
                context['char_position']:]
            context['is_sorted'] = False

            # Filtering
            ignorecase = context['ignorecase']
            smartcase = context['smartcase']
            camelcase = context['camelcase']

            # Set ignorecase
            if (smartcase or camelcase) and re.search(
                    r'[A-Z]', context['complete_str']):
                context['ignorecase'] = 0

            for f in [self._filters[x] for x
                      in source.matchers + source.sorters + source.converters
                      if x in self._filters]:
                try:
                    self.profile_start(context, f.name)
                    if (isinstance(context['candidates'], dict) and
                            'sorted_candidates' in context['candidates']):
                        context_candidates = []
                        sorted_candidates = context['candidates'][
                            'sorted_candidates']
                        context['is_sorted'] = True
                        for candidates in sorted_candidates:
                            context['candidates'] = candidates
                            context_candidates += f.filter(context)
                        context['candidates'] = context_candidates
                    else:
                        context['candidates'] = f.filter(context)
                    self.profile_end(f.name)
                except Exception:
                    self._filter_errors[f.name] += 1
                    if self._source_errors[f.name] > 2:
                        error(self._vim, 'Too many errors from "%s". '
                              'This filter is disabled until Neovim '
                              'is restarted.' % f.name)
                        self._ignored_filters.add(f.path)
                        self._filters.pop(f.name)
                        continue
                    error_tb(self._vim, 'Could not filter using: %s' % f)

            context['ignorecase'] = ignorecase

            # On post filter
            if hasattr(source, 'on_post_filter'):
                context['candidates'] = source.on_post_filter(context)

            if context['candidates']:
                merged_results.append([context['candidates'], result])

        is_async = len([x for x in results if x['context']['is_async']]) > 0

        if not merged_results:
            return (is_async, -1, [])

        complete_position = min([x[1]['context']['complete_position']
                                 for x in merged_results])

        for [candidates, result] in merged_results:
            context = result['context']
            source = result['source']
            prefix = context['input'][
                complete_position:context['complete_position']]

            mark = source.mark + ' '
            for candidate in candidates:
                # Add prefix
                candidate['word'] = prefix + candidate['word']

                # Set default menu and icase
                candidate['icase'] = 1
                if (source.mark != '' and
                        candidate.get('menu', '').find(mark) != 0):
                    candidate['menu'] = mark + candidate.get('menu', '')
                if source.filetypes:
                    candidate['dup'] = 1

            all_candidates += candidates

        # self.debug(candidates)
        if context['vars']['deoplete#max_list'] > 0:
            all_candidates = all_candidates[
                : context['vars']['deoplete#max_list']]

        return (is_async, complete_position, all_candidates)
Example #54
0
    def gather_results(self, context):
        results = []

        for source_name, source in self.itersource(context):
            try:
                if source.disabled_syntaxes and 'syntax_names' not in context:
                    context['syntax_names'] = get_syn_names(self.__vim)
                ctx = copy.deepcopy(context)
                charpos = source.get_complete_position(ctx)
                if charpos >= 0 and source.is_bytepos:
                    charpos = bytepos2charpos(
                        ctx['encoding'], ctx['input'], charpos)
                ctx['complete_str'] = ctx['input'][charpos:]
                ctx['complete_position'] = charpos2bytepos(
                    ctx['encoding'], ctx['input'], charpos)
                ctx['max_abbr_width'] = min(source.max_abbr_width,
                                            ctx['max_abbr_width'])
                ctx['max_menu_width'] = min(source.max_menu_width,
                                            ctx['max_menu_width'])
                if ctx['max_abbr_width'] > 0:
                    ctx['max_abbr_width'] = max(20, ctx['max_abbr_width'])
                if ctx['max_menu_width'] > 0:
                    ctx['max_menu_width'] = max(10, ctx['max_menu_width'])

                if charpos < 0 or self.is_skip(ctx, source.disabled_syntaxes,
                                               source.min_pattern_length,
                                               source.max_pattern_length,
                                               source.input_pattern):
                    # Skip
                    continue

                # Gathering
                self.profile_start(ctx, source.name)
                ctx['candidates'] = source.gather_candidates(ctx)
                self.profile_end(source.name)

                if 'candidates' not in ctx or not ctx['candidates']:
                    continue

                if ctx['candidates'] and isinstance(ctx['candidates'][0], str):
                    # Convert to dict
                    ctx['candidates'] = [{'word': x}
                                         for x in ctx['candidates']]

                # Filtering
                ignorecase = ctx['ignorecase']
                smartcase = ctx['smartcase']
                camelcase = ctx['camelcase']

                # Set ignorecase
                if (smartcase or camelcase) and re.search(r'[A-Z]',
                                                          ctx['complete_str']):
                    ctx['ignorecase'] = 0

                for filter in [self.__filters[x] for x
                               in source.matchers +
                               source.sorters +
                               source.converters
                               if x in self.__filters]:
                    try:
                        self.profile_start(ctx, filter.name)
                        ctx['candidates'] = filter.filter(ctx)
                        self.profile_end(filter.name)
                    except:
                        self.__filter_errors[filter.name] += 1
                        if self.__source_errors[filter.name] > 2:
                            error(self.__vim, 'Too many errors from "%s". '
                                  'This filter is disabled until Neovim '
                                  'is restarted.' % filter.name)
                            self.__filters.pop(filter.name)
                            continue
                        error_tb(self.__vim,
                                 'Could not filter using: %s' % filter)

                ctx['ignorecase'] = ignorecase

                # On post filter
                if hasattr(source, 'on_post_filter'):
                    ctx['candidates'] = source.on_post_filter(ctx)

                # Set default menu and icase
                mark = source.mark + ' '
                for candidate in ctx['candidates']:
                    candidate['icase'] = 1
                    if source.mark != '' \
                            and candidate.get('menu', '').find(mark) != 0:
                        candidate['menu'] = mark + candidate.get('menu', '')

                results.append({
                    'name': source_name,
                    'source': source,
                    'context': ctx,
                })
            except:
                self.__source_errors[source_name] += 1
                if self.__source_errors[source_name] > 2:
                    error(self.__vim, 'Too many errors from "%s". '
                          'This source is disabled until Neovim '
                          'is restarted.' % source_name)
                    self.__sources.pop(source_name)
                    continue
                error_tb(self.__vim,
                         'Could not get completions from: %s' % source_name)

        return results
Example #55
0
    def gather_results(self, context):
        results = []

        for source in [x[1] for x in self.itersource(context)]:
            try:
                if source.disabled_syntaxes and 'syntax_names' not in context:
                    context['syntax_names'] = get_syn_names(self._vim)
                ctx = copy.deepcopy(context)
                ctx['is_async'] = False

                charpos = source.get_complete_position(ctx)
                if charpos >= 0 and source.is_bytepos:
                    charpos = bytepos2charpos(
                        ctx['encoding'], ctx['input'], charpos)

                ctx['char_position'] = charpos
                ctx['complete_position'] = charpos2bytepos(
                    ctx['encoding'], ctx['input'], charpos)
                ctx['complete_str'] = ctx['input'][ctx['char_position']:]

                if charpos < 0 or self.is_skip(ctx, source):
                    if source.name in self._prev_results:
                        self._prev_results.pop(source.name)
                    # Skip
                    continue

                if (not source.is_volatile and
                        source.name in self._prev_results and
                        self.use_previous_result(
                            context, self._prev_results[source.name])):
                    results.append(self._prev_results[source.name])
                    continue

                ctx['max_abbr_width'] = min(source.max_abbr_width,
                                            ctx['max_abbr_width'])
                ctx['max_menu_width'] = min(source.max_menu_width,
                                            ctx['max_menu_width'])
                if ctx['max_abbr_width'] > 0:
                    ctx['max_abbr_width'] = max(20, ctx['max_abbr_width'])
                if ctx['max_menu_width'] > 0:
                    ctx['max_menu_width'] = max(10, ctx['max_menu_width'])

                # Gathering
                self.profile_start(ctx, source.name)
                ctx['candidates'] = source.gather_candidates(ctx)
                self.profile_end(source.name)

                if ctx['candidates'] is None:
                    continue

                ctx['candidates'] = convert2candidates(ctx['candidates'])

                result = {
                    'name': source.name,
                    'source': source,
                    'context': ctx,
                    'is_async': ctx['is_async'],
                    'prev_linenr': ctx['position'][1],
                    'prev_input': ctx['input'],
                }
                self._prev_results[source.name] = result
                results.append(result)
            except Exception:
                self._source_errors[source.name] += 1
                if self._source_errors[source.name] > 2:
                    error(self._vim, 'Too many errors from "%s". '
                          'This source is disabled until Neovim '
                          'is restarted.' % source.name)
                    self._ignored_sources.add(source.path)
                    self._sources.pop(source.name)
                    continue
                error_tb(self._vim,
                         'Could not get completions from: %s' % source.name)

        return results