Esempio n. 1
0
    def _update_result(self, result, context_input, next_input):
        source = result['source']

        # Gather async results
        if result['is_async']:
            self._gather_async_results(result, source)

        if not result['candidates']:
            return None

        # Source context
        ctx = copy.deepcopy(result['context'])

        ctx['input'] = context_input
        ctx['next_input'] = next_input
        ctx['complete_str'] = context_input[ctx['char_position']:]
        ctx['is_sorted'] = False

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

        # Filtering
        for f in [self._filters[x] for x
                  in source.matchers + source.sorters + source.converters
                  if x in self._filters]:
            self._process_filter(f, ctx, source.max_candidates)

        ctx['ignorecase'] = ignorecase

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

        mark = source.mark + ' '
        dup = bool(source.filetypes)
        for candidate in ctx['candidates']:
            # Set default menu and icase
            candidate['icase'] = 1
            if (mark != ' ' and
                    candidate.get('menu', '').find(mark) != 0):
                candidate['menu'] = mark + candidate.get('menu', '')
            if dup:
                candidate['dup'] = 1
        # Note: cannot use set() for dict
        if dup:
            # Remove duplicates
            ctx['candidates'] = uniq_list_dict(ctx['candidates'])

        result['candidates'] = ctx['candidates']
        return result if result['candidates'] else None
Esempio n. 2
0
    def _get_candidates(self, result, context_input, next_input):
        source = result['source']

        # Gather async results
        if result['is_async']:
            self._gather_async_results(result, source)

        if not result['candidates']:
            return None

        # Source context
        ctx = copy.deepcopy(result['context'])

        ctx['input'] = context_input
        ctx['next_input'] = next_input
        ctx['complete_str'] = context_input[ctx['char_position']:]
        ctx['is_sorted'] = False

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

        # Match
        matchers = [
            self._filters[x] for x in source.matchers if x in self._filters
        ]
        if source.matcher_key != '':
            # Convert word key to matcher_key
            for candidate in ctx['candidates']:
                candidate['__save_word'] = candidate['word']
                candidate['word'] = candidate[source.matcher_key]
        for f in matchers:
            self._process_filter(f, ctx, source.max_candidates)
        if source.matcher_key != '':
            # Restore word key
            for candidate in ctx['candidates']:
                candidate['word'] = candidate['__save_word']

        # Sort and Convert
        sorters = [
            self._filters[x] for x in source.sorters if x in self._filters
        ]
        converters = [
            self._filters[x] for x in source.converters if x in self._filters
        ]
        for f in sorters + converters:
            self._process_filter(f, ctx, source.max_candidates)

        if (isinstance(ctx['candidates'], dict)
                and 'sorted_candidates' in ctx['candidates']):
            sorted_candidates = ctx['candidates']['sorted_candidates']
            ctx['candidates'] = []
            for candidates in sorted_candidates:
                ctx['candidates'] += candidates

        ctx['ignorecase'] = ignorecase

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

        mark = source.mark + ' '
        for candidate in ctx['candidates']:
            # Set default menu and icase
            candidate['icase'] = 1
            if (mark != ' ' and candidate.get('menu', '').find(mark) != 0):
                candidate['menu'] = mark + candidate.get('menu', '')
            if source.dup:
                candidate['dup'] = 1
        # Note: cannot use set() for dict
        if source.dup:
            # Remove duplicates
            ctx['candidates'] = uniq_list_dict(ctx['candidates'])

        return ctx['candidates']
Esempio n. 3
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)
Esempio n. 4
0
class Child(logger.LoggingMixin):

    def __init__(self, vim):
        self.name = 'child'

        self._vim = vim
        self._filters = {}
        self._sources = {}
        self._custom = []
        self._profile_flag = None
        self._profile_start_time = 0
        self._loaded_sources = {}
        self._loaded_filters = {}
        self._source_errors = defaultdict(int)
        self._prev_results = {}
        self._unpacker = msgpack.Unpacker(
            encoding='utf-8',
            unicode_errors='surrogateescape')
        self._packer = msgpack.Packer(
            use_bin_type=True,
            encoding='utf-8',
            unicode_errors='surrogateescape')
        self._ignore_sources = []

    def main_loop(self, stdout):
        while True:
            feed = sys.stdin.buffer.raw.read(102400)
            if feed is None:
                continue
            if feed == b'':
                # EOF
                return

            self._unpacker.feed(feed)
            self.debug('_read: %d bytes', len(feed))

            for child_in in self._unpacker:
                name = child_in['name']
                args = child_in['args']
                queue_id = child_in['queue_id']
                self.debug('main_loop: %s begin', name)

                ret = self.main(name, args, queue_id)
                if ret:
                    self._write(stdout, ret)

                self.debug('main_loop: end')

    def main(self, name, args, queue_id):
        ret = None
        if name == 'enable_logging':
            self._enable_logging()
        elif name == 'add_source':
            self._add_source(args[0])
        elif name == 'add_filter':
            self._add_filter(args[0])
        elif name == 'set_source_attributes':
            self._set_source_attributes(args[0])
        elif name == 'set_custom':
            self._set_custom(args[0])
        elif name == 'on_event':
            self._on_event(args[0])
        elif name == 'merge_results':
            ret = self._merge_results(args[0], queue_id)
        return ret

    def _write(self, stdout, expr):
        stdout.buffer.write(self._packer.pack(expr))
        stdout.flush()

    def _enable_logging(self):
        logging = self._vim.vars['deoplete#_logging']
        logger.setup(self._vim, logging['level'], logging['logfile'])
        self.is_debug_enabled = True

    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)

    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)

    def _merge_results(self, context, queue_id):
        self.debug('merged_results: begin')
        results = self._gather_results(context)

        merged_results = []
        for result in [x for x in results
                       if not self._is_skip(x['context'], x['source'])]:
            source_result = self._source_result(result, context['input'])
            if source_result:
                rank = get_custom(self._custom,
                                  result['source'].name, 'rank',
                                  result['source'].rank)
                merged_results.append({
                    'complete_position': source_result['complete_position'],
                    'mark': result['source'].mark,
                    'dup': bool(result['source'].filetypes),
                    'candidates': result['candidates'],
                    'source_name': result['source'].name,
                    'rank': rank,
                })

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

        self.debug('merged_results: end')
        return {
            'queue_id': queue_id,
            'is_async': is_async,
            'merged_results': merged_results,
        }

    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)

                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 (source.name in self._prev_results and
                        self._use_previous_result(
                            context, self._prev_results[source.name],
                            source.is_volatile)):
                    results.append(self._prev_results[source.name])
                    continue

                ctx['is_async'] = False
                ctx['is_refresh'] = True
                ctx['max_abbr_width'] = min(source.max_abbr_width,
                                            ctx['max_abbr_width'])
                ctx['max_kind_width'] = min(source.max_kind_width,
                                            ctx['max_kind_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_kind_width'] > 0:
                    ctx['max_kind_width'] = max(10, ctx['max_kind_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'],
                    'input': ctx['input'],
                    'complete_position': ctx['complete_position'],
                    'candidates': ctx['candidates'],
                }
                self._prev_results[source.name] = result
                results.append(result)
            except Exception:
                self._source_errors[source.name] += 1
                if source.is_silent:
                    continue
                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)
                    continue
                error_tb(self._vim, 'Errors from: %s' % source.name)

        return results

    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)

    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)

    def _source_result(self, result, context_input):
        source = result['source']

        # Gather async results
        if result['is_async']:
            self._gather_async_results(result, source)

        if not result['candidates']:
            return None

        # Source context
        ctx = copy.deepcopy(result['context'])

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

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

        # Filtering
        for f in [self._filters[x] for x
                  in source.matchers + source.sorters + source.converters
                  if x in self._filters]:
            self._process_filter(f, ctx)

        ctx['ignorecase'] = ignorecase

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

        result['candidates'] = ctx['candidates']
        return result if result['candidates'] else None
Esempio n. 5
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)
Esempio n. 6
0
    def _get_candidates(self, result, context_input, next_input):
        source = result['source']

        # Gather async results
        if result['is_async']:
            self._gather_async_results(result, source)

        if not result['candidates']:
            return None

        # Source context
        ctx = copy.deepcopy(result['context'])

        ctx['input'] = context_input
        ctx['next_input'] = next_input
        ctx['complete_str'] = context_input[ctx['char_position']:]
        ctx['is_sorted'] = False

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

        # Match
        matchers = [self._filters[x] for x
                    in source.matchers if x in self._filters]
        if source.matcher_key != '':
            # Convert word key to matcher_key
            for candidate in ctx['candidates']:
                candidate['__save_word'] = candidate['word']
                candidate['word'] = candidate[source.matcher_key]
        for f in matchers:
            self._process_filter(f, ctx, source.max_candidates)
        if source.matcher_key != '':
            # Restore word key
            for candidate in ctx['candidates']:
                candidate['word'] = candidate['__save_word']

        # Sort and Convert
        sorters = [self._filters[x] for x
                   in source.sorters if x in self._filters]
        converters = [self._filters[x] for x
                      in source.converters if x in self._filters]
        for f in sorters + converters:
            self._process_filter(f, ctx, source.max_candidates)

        if (isinstance(ctx['candidates'], dict) and
                'sorted_candidates' in ctx['candidates']):
            sorted_candidates = ctx['candidates']['sorted_candidates']
            ctx['candidates'] = []
            for candidates in sorted_candidates:
                ctx['candidates'] += candidates

        ctx['ignorecase'] = ignorecase

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

        mark = source.mark + ' '
        for candidate in ctx['candidates']:
            # Set default menu and icase
            candidate['icase'] = 1
            if (mark != ' ' and
                    candidate.get('menu', '').find(mark) != 0):
                candidate['menu'] = mark + candidate.get('menu', '')
            if source.dup:
                candidate['dup'] = 1
        # Note: cannot use set() for dict
        if source.dup:
            # Remove duplicates
            ctx['candidates'] = uniq_list_dict(ctx['candidates'])

        return ctx['candidates']
Esempio n. 7
0
    def gather_results(self, context):
        results = []

        for source_name, source in list(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 Exception:
                        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.__ignored_filters.add(filter.path)
                            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 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
Esempio n. 8
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
Esempio n. 9
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        results = []
        for source_name, source in self.itersource(context):
            if source.disabled_syntaxes and 'syntax_name' not in context:
                context['syntax_name'] = get_syn_name(self.__vim)
            cont = copy.deepcopy(context)
            charpos = source.get_complete_position(cont)
            if charpos >= 0 and source.is_bytepos:
                charpos = bytepos2charpos(
                    self.__encoding, cont['input'], charpos)
            cont['complete_str'] = cont['input'][charpos:]
            cont['complete_position'] = charpos2bytepos(
                self.__encoding, cont['input'], charpos)
            cont['max_abbr_width'] = min(source.max_abbr_width,
                                         cont['max_abbr_width'])
            cont['max_menu_width'] = min(source.max_menu_width,
                                         cont['max_menu_width'])
            if cont['max_abbr_width'] > 0:
                cont['max_abbr_width'] = max(20, cont['max_abbr_width'])
            if cont['max_menu_width'] > 0:
                cont['max_menu_width'] = max(10, cont['max_menu_width'])
            # self.debug(source.rank)
            # self.debug(source_name)
            # self.debug(cont['input'])
            # self.debug(charpos)
            # self.debug(cont['complete_position'])
            # self.debug(cont['complete_str'])

            if charpos < 0 or self.is_skip(cont, source.disabled_syntaxes,
                                           source.min_pattern_length,
                                           source.max_pattern_length,
                                           source.input_pattern):
                # Skip
                continue
            results.append({
                'name': source_name,
                'source': source,
                'context': cont,
            })

        for result in results:
            context = result['context']
            source = result['source']

            # self.debug(source.name)
            self.profile_start(context, source.name)
            context['candidates'] = source.gather_candidates(context)
            self.profile_end(source.name)
            if context['candidates'] and isinstance(
                    context['candidates'][0], str):
                # Convert to dict
                context['candidates'] = [{'word': x}
                                         for x in context['candidates']]

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

                for filter in [self.__filters[x] for x
                               in source.matchers +
                               source.sorters +
                               source.converters
                               if x in self.__filters]:
                    self.profile_start(context, filter.name)
                    context['candidates'] = filter.filter(context)
                    self.profile_end(filter.name)
            finally:
                context['ignorecase'] = ignorecase
            # self.debug(context['candidates'])

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

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

            # self.debug(context['candidates'])
        return results