Esempio n. 1
0
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim, context['input'][: column], column) - 1
        offset += len(context['complete_str'])
        source = '\n'.join(buf).encode()

        args = [self.source_kitten_binary(), "complete", "--offset", str(offset)]

        process = subprocess.Popen(args,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        result = stdout_data.decode()

        if stderr_data != b'':
            raise Exception((args, stderr_data.decode()))

        results = json.loads(result)

        return self.identifiers_from_result(results)
Esempio n. 2
0
    def get_complete_result(self, context, buffer, bufname):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'][: column],
                            column) - 1

        env = os.environ.copy()
        if self.auto_goos:
            name = os.path.basename(os.path.splitext(bufname)[0])
            if '_' in name:
                for part in name.rsplit('_', 2):
                    if part in known_goos:
                        env['GOOS'] = part
                        break
            if 'GOOS' not in env:
                for line in buffer:
                    if line.startswith('package '):
                        break
                    elif not line.startswith('// +build'):
                        continue
                    directives = [
                        x.split(',', 1)[0] for x in line[9:].strip().split()
                    ]
                    if platform.system().lower() not in directives:
                        for plat in directives:
                            if plat in known_goos:
                                env['GOOS'] = plat
                                break
        elif self.goos != '':
            env['GOOS'] = self.goos

        if 'GOOS' in env and env['GOOS'] != platform.system().lower():
            env['CGO_ENABLED'] = '0'

        if self.goarch != '':
            env['GOARCH'] = self.goarch

        args = [self.find_gocode_binary(), '-f=json']
        # basically, '-sock' option for mdempsky/gocode.
        # probably meaningless in nsf/gocode that already run the rpc server
        if self.sock != '' and self.sock in ['unix', 'tcp', 'none']:
            args.append('-sock={}'.format(self.sock))

        args += ['autocomplete', bufname, str(offset)]

        process = subprocess.Popen(
            args,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            start_new_session=True,
            env=env
        )
        stdout_data, stderr_data = process.communicate(
            '\n'.join(buffer).encode()
        )

        return loads(stdout_data.decode())
Esempio n. 3
0
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim, context['input'][: column], column) - 1
        offset += len(context['complete_str'])
        source = '\n'.join(buf).encode()

        args = [
            self.source_kitten_binary(), "complete", "--offset",
            str(offset)
        ]

        process = subprocess.Popen(args,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        result = stdout_data.decode()

        if stderr_data != b'':
            raise Exception((args, stderr_data.decode()))

        results = json.loads(result)

        return self.identifiers_from_result(results)
Esempio n. 4
0
    def get_complete_result(self, context, buffer, bufname):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']
        cwd = context['cwd']

        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'][: column],
                            column) - 1

        env = os.environ.copy()
        if self.auto_goos:
            name = os.path.basename(os.path.splitext(bufname)[0])
            if '_' in name:
                for part in name.rsplit('_', 2):
                    if part in known_goos:
                        env['GOOS'] = part
                        break
            if 'GOOS' not in env:
                for line in buffer:
                    if line.startswith('package '):
                        break
                    elif not line.startswith('// +build'):
                        continue
                    directives = [
                        x.split(',', 1)[0] for x in line[9:].strip().split()
                    ]
                    if platform.system().lower() not in directives:
                        for plat in directives:
                            if plat in known_goos:
                                env['GOOS'] = plat
                                break
        elif self.goos != '':
            env['GOOS'] = self.goos

        if 'GOOS' in env and env['GOOS'] != platform.system().lower():
            env['CGO_ENABLED'] = '0'

        if self.goarch != '':
            env['GOARCH'] = self.goarch

        args = [self.find_gocode_binary(), '-f=json']
        # basically, '-sock' option for mdempsky/gocode.
        # probably meaningless in nsf/gocode that already run the rpc server
        if self.sock != '' and self.sock in ['unix', 'tcp', 'none']:
            args.append('-sock={}'.format(self.sock))

        args += ['autocomplete', os.path.join(cwd, bufname), str(offset)]

        process = subprocess.Popen(args,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True,
                                   env=env)
        stdout_data, stderr_data = process.communicate(
            '\n'.join(buffer).encode())

        return loads(stdout_data.decode())
Esempio n. 5
0
 def get_cursor_offset(self, context):
     line = self.vim.current.window.cursor[0]
     column = context["complete_position"]
     count = self.vim.call("line2byte", line)
     if self.vim.current.buffer.options["fileformat"] == "dos":
         # Note: line2byte() counts "\r\n" in DOS format.  It must be "\n"
         # in gocode.
         count -= line - 1
     return count + charpos2bytepos("utf-8", context["input"][:column], column) - 1
Esempio n. 6
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = context["sources"]
        results = []
        start_length = self.vim.eval("g:deoplete#auto_completion_start_length")
        for source_name, source in sorted(self.sources.items(), key=lambda x: x[1].rank, reverse=True):
            if (sources and not source_name in sources) or (
                source.filetypes and not context["filetype"] in source.filetypes
            ):
                continue
            cont = copy.deepcopy(context)
            charpos = source.get_complete_position(cont)
            if source.is_bytepos:
                charpos = bytepos2charpos(self.vim, cont["input"], charpos)
            cont["complete_str"] = cont["input"][charpos:]
            cont["complete_position"] = charpos2bytepos(self.vim, cont["input"], charpos)
            # 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'])

            min_pattern_length = source.min_pattern_length
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length

            if charpos < 0 or (cont["event"] != "Manual" and len(cont["complete_str"]) < min_pattern_length):
                # Skip
                continue
            results.append({"name": source_name, "source": source, "context": cont})

        for result in results:
            context = result["context"]
            source = result["source"]
            context["candidates"] = source.gather_candidates(context)
            # self.debug(context['candidates'])

            # self.debug(context['complete_str'])
            # self.debug(context['candidates'])
            for filter_name in source.matchers + source.sorters + source.converters:
                if filter_name in self.filters:
                    context["candidates"] = self.filters[filter_name].filter(context)
            # self.debug(context['candidates'])

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

            # Set default menu
            for candidate in context["candidates"]:
                if not "menu" in candidate:
                    candidate["menu"] = source.mark
            # self.debug(context['candidates'])
        return results
Esempio n. 7
0
 def get_cursor_offset(self, context):
     line = self.vim.current.window.cursor[0]
     column = context['complete_position']
     count = self.vim.call('line2byte', line)
     if self.vim.current.buffer.options['fileformat'] == 'dos':
         # Note: line2byte() counts "\r\n" in DOS format.  It must be "\n"
         # in gocode.
         count -= line - 1
     return count + charpos2bytepos(
         'utf-8', context['input'][: column], column) - 1
Esempio n. 8
0
 def get_cursor_offset(self, context):
     line = self.vim.current.window.cursor[0]
     column = context['complete_position']
     count = self.vim.call('line2byte', line)
     if self.vim.current.buffer.options['fileformat'] == 'dos':
         # Note: line2byte() counts "\r\n" in DOS format.  It must be "\n"
         # in gocode.
         count -= line - 1
     return count + charpos2bytepos('utf-8', context['input'][:column],
                                    column) - 1
Esempio n. 9
0
    def gather_candidates(self, context):
        """
        Request completions from analysis_server backend
        """
        current_file = os.path.join(context['cwd'], context['bufname'])

        # Check if we're analyzed yet. If yes then update buffer in analysis
        # server, otherwise add for analysis
        if self._server.is_analyzed(current_file):
            self._server.update_file_content(
                current_file, '\n'.join(self.vim.current.buffer[:]))
        else:
            self._server.add_analysis_roots([current_file])

        # Need a better way to get the offset
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'][: column],
                            column) - 1
        suggestions = self._server.get_suggestions(current_file, offset)

        candidates = []
        for suggest in suggestions:
            candidate = dict(word=suggest['completion'], dup=1)

            candidate['info'] = suggest['completion']

            if 'element' in suggest:
                element = suggest['element']

                if 'returnType' in element:
                    candidate['info'] = element[
                        'returnType'] + ' ' + candidate['info']
                if 'parameters' in element:
                    candidate['info'] += element['parameters']

                if 'kind' in element:
                    candidate['kind'] = element['kind']

            if 'docSummary' in suggest:
                candidate['info'] += '\n' + suggest['docSummary']

            candidates.append(candidate)

        return candidates
Esempio n. 10
0
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim.options['encoding'], context['input'][: column], column) - 1
        offset += len(context['complete_str'])
        source = '\n'.join(buf).encode()

        args = [self.dcd_client_binary(), "-c" + str(offset), "--extended"]

        if buf.name != "":
            buf_path = os.path.dirname(buf.name)
            for dir in [self.SRC_DIR, self.SOURCE_DIR]:
                if dir in buf_path:
                    buf_path = buf_path[:buf_path.find(dir) + len(dir)]
                    break
            if not buf_path in self.import_dirs:
                args.append("-I{}".format(buf_path))
                self.import_dirs.append(buf_path)

        for import_path in self.import_dirs:
            args.append("-I{}".format(import_path))

        process = subprocess.Popen(args,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        result = stdout_data.decode().split('\n')

        if stderr_data != b'':
            return []
            #raise Exception((args, stderr_data.decode()))

        if result[0] == "identifiers":
            return self.identifiers_from_result(result)
        elif result[0] == "calltips":
            return self.calltips_from_result(result)

        return []
Esempio n. 11
0
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim, context['input'][: column], column) - 1
        source = '\n'.join(buf).encode()

        with tempfile.NamedTemporaryFile(delete=False, suffix=".swift") as fp:
            fp.write(source)
            path = fp.name

        completer = self.__choose_completer(path)
        try:
            results = completer.complete(path, offset)
        finally:
            os.remove(path)

        return self.identifiers_from_result(results)
Esempio n. 12
0
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim, context['input'][: column], column) - 1
        source = '\n'.join(buf).encode()

        with tempfile.NamedTemporaryFile(delete=False, suffix=".swift") as fp:
            fp.write(source)
            path = fp.name

        completer = self.__choose_completer(path)
        try:
            results = completer.complete(path, offset)
        finally:
            os.remove(path)

        return self.identifiers_from_result(results)
Esempio n. 13
0
    def get_complete_result(self, buffer, context, **kwargs):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'][: column],
                            column) - 1
        source = '\n'.join(buffer).encode()

        process = subprocess.Popen(
            [self.find_gocode_binary(), '-f=json', 'autocomplete', buffer.name,
             str(offset)],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        if kwargs and kwargs['kill'] is True:
            process.kill
        return loads(stdout_data.decode())
Esempio n. 14
0
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim, context['input'][: column], column) - 1
        offset += len(context['complete_str'])
        source = '\n'.join(buf).encode()

        buf_path = os.path.dirname(buf.name);

        for dir in [self.SRC_DIR, self.SOURCE_DIR]:
            if dir in buf_path:
                buf_path = buf_path[:buf_path.find(dir) + len(dir)]
                break

        args = [self.dcd_client_binary(), "-c" + str(offset)]
        if not buf_path in self.import_dirs:
            args.append("-I{}".format(buf_path))
            self.import_dirs.append(buf_path)

        process = subprocess.Popen(args,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        result = stdout_data.decode().split('\n')

        if stderr_data != b'':
            raise Exception((args, stderr_data.decode()))

        if result[0] == "identifiers":
            return self.identifiers_from_result(result)
        elif result[0] ==  "calltips":
            return self.calltips_from_result(result)

        return []
Esempio n. 15
0
    def get_complete_result(self, buffer, context, **kwargs):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'][: column],
                            column) - 1
        source = '\n'.join(buffer).encode()

        process = subprocess.Popen([
            self.find_gocode_binary(), '-f=json', 'autocomplete', buffer.name,
            str(offset)
        ],
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        if kwargs and kwargs['kill'] is True:
            process.kill
        return loads(stdout_data.decode())
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = self.vim.current.window.cursor[1]

        filename = self.vim.call('expand', '%:p').split('/')[-1]
        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'], column) - 1

        source = '\n'.join(buf)
        tmp_path = self.temp_file_directory + filename
        tmp_file = open(tmp_path, 'w+')
        tmp_file.write(source)
        tmp_file.close()

        request = urllib2.Request("http://localhost:8081/complete")
        request.add_header("X-Path", tmp_path)
        request.add_header("X-Offset", offset - 1)
        request.add_header("X-File", filename)
        try:
            response = urllib2.urlopen(request).read().decode('utf-8')
            return self.identifiers_from_result(json.loads(response))
        except:
            return []
Esempio n. 17
0
    def gather_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim, context['input'][: column], column) - 1
        source = '\n'.join(buf).encode()

        process = subprocess.Popen([self.GoCodeBinary(),
                                    '-f=json',
                                    'autocomplete',
                                    buf.name,
                                    str(offset)],
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        result = loads(stdout_data.decode())

        if not self.sort_class == []:
            # TODO(zchee): Why not work with this?
            #              class_dict = {}.fromkeys(self.sort_class, [])
            class_dict = {
                'package': [],
                'func': [],
                'type': [],
                'var': [],
                'const': [],
            }
        try:
            out = []
            sep = ' '
            for complete in result[1]:
                _class = complete['class']
                word = complete['name']
                info = complete['type']

                if not _class == 'package' and self.align_class:
                    abbr = '{:<6}'.format(_class) + word
                else:
                    abbr = _class + sep + word

                if _class == 'package' and self.package_dot:
                    word += '.'
                if _class == 'func':
                    word = word + '('
                    abbr += str(info).strip('func')
                elif _class in ('type', 'var'):
                    abbr += sep + info

                candidates = dict(word=word,
                                  abbr=abbr,
                                  info=info,
                                  dup=1
                                  )
                if self.sort_class == []:
                    out.append(candidates)
                else:
                    class_dict[_class].append(candidates)

            # append with sort by complete['class']
            if not self.sort_class == []:
                for c in self.sort_class:
                    for x in class_dict[c]:
                        out.append(x)

            return out
        except Exception:
            return []
Esempio n. 18
0
    def gather_results(self, context):
        if not self.use_previous_result(context):
            self._prev_linenr = context['position'][1]
            self._prev_input = context['input']
            self._results = {}

        results = self._results

        for source in [
                x[1] for x in self.itersource(context)
                if x[1].name not in results
        ]:
            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.disabled_syntaxes,
                                               source.min_pattern_length,
                                               source.max_pattern_length,
                                               source.input_pattern):
                    # Skip
                    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 not ctx['is_async'] and ('candidates' not in ctx
                                            or not ctx['candidates']):
                    continue

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

                results[source.name] = {
                    'name': source.name,
                    'source': source,
                    'context': ctx,
                    'is_async': ctx['is_async'],
                }
            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.values()
Esempio n. 19
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
Esempio n. 20
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
Esempio n. 21
0
def test_pos():
    assert util.bytepos2charpos('utf-8', 'foo bar', 3) == 3
    assert util.bytepos2charpos('utf-8', 'あああ', 3) == 1
    assert util.charpos2bytepos('utf-8', 'foo bar', 3) == 3
    assert util.charpos2bytepos('utf-8', 'あああ', 3) == 9
Esempio n. 22
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
Esempio n. 23
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = sorted(self.sources.items(),
                         key=lambda x: get_custom(self.vim, x[1].name).get(
                             'rank', x[1].rank),
                         reverse=True)
        results = []
        start_length = self.vim.eval(
            'g:deoplete#auto_completion_start_length')
        ignore_sources = get_buffer_config(
            self.vim, context['filetype'],
            'b:deoplete_ignore_sources',
            'g:deoplete#ignore_sources',
            '{}')
        for source_name, source in sources:
            filetypes = get_custom(self.vim, source.name).get(
                'filetypes', source.filetypes)

            in_sources = not context['sources'] or (
                source_name in context['sources'])
            in_fts = not filetypes or (
                context['filetype'] in filetypes)
            in_ignore = source_name in ignore_sources
            if not in_sources or not in_fts or in_ignore:
                continue
            cont = copy.deepcopy(context)
            charpos = source.get_complete_position(cont)
            if charpos >= 0 and source.is_bytepos:
                charpos = bytepos2charpos(
                    self.vim, cont['input'], charpos)
            cont['complete_str'] = cont['input'][charpos:]
            cont['complete_position'] = charpos2bytepos(
                self.vim, cont['input'], charpos)
            # 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'])

            min_pattern_length = get_custom(self.vim, source.name).get(
                'min_pattern_length', source.min_pattern_length)
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length
            input_pattern = get_custom(self.vim, source.name).get(
                'input_pattern', source.input_pattern)

            if charpos < 0 or self.is_skip(cont,
                                           min_pattern_length,
                                           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)
            context['candidates'] = source.gather_candidates(context)
            if context['candidates'] and isinstance(
                    context['candidates'][0], str):
                # Convert to dict
                context['candidates'] = [{'word': x}
                                         for x in context['candidates']]

            matchers = get_custom(self.vim, source.name).get(
                'matchers', source.matchers)
            sorters = get_custom(self.vim, source.name).get(
                'sorters', source.sorters)
            converters = get_custom(self.vim, source.name).get(
                'converters', source.converters)

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

                for filter_name in matchers + sorters + converters:
                    if filter_name in self.filters:
                        context['candidates'] = self.filters[
                            filter_name].filter(context)
            finally:
                context['ignorecase'] = ignorecase
            # self.debug(context['candidates'])

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

            if context['candidates'] and (
                    not re.match(r'\[.*\]',
                                 context['candidates'][0].get('menu', ''))):
                # Set default menu
                for candidate in context['candidates']:
                    candidate['menu'] = source.mark + ' ' + candidate.get(
                        'menu', '')

            # Set icase
            for candidate in context['candidates']:
                candidate['icase'] = 1
            # self.debug(context['candidates'])
        return results
Esempio n. 24
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. 25
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = context['sources']
        results = []
        start_length = self.vim.eval(
            'g:deoplete#auto_completion_start_length')
        for source_name, source in sorted(self.sources.items(),
                key=lambda x: x[1].rank, reverse=True):
            if (sources and not source_name in sources) \
                    or (source.filetypes and
                        not context['filetype'] in source.filetypes):
                continue
            cont = copy.deepcopy(context)
            charpos = source.get_complete_position(cont)
            if charpos >= 0 and source.is_bytepos:
                charpos = bytepos2charpos(
                    self.vim, cont['input'], charpos)
            cont['complete_str'] = cont['input'][charpos :]
            cont['complete_position'] = charpos2bytepos(
                self.vim, cont['input'], charpos)
            # 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'])

            min_pattern_length = source.min_pattern_length
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length

            if charpos < 0 \
                    or (cont['event'] != 'Manual' \
                        and len(cont['complete_str']) < min_pattern_length):
                # Skip
                continue
            results.append({
                'name': source_name,
                'source': source,
                'context': cont,
            })

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

            context['candidates'] = source.gather_candidates(context)
            if context['candidates'] \
                    and type(context['candidates'][0]) == type(''):
                # Convert to dict
                context['candidates'] = \
                    [{ 'word': x } for x in context['candidates'] ]

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

            # self.debug(context['complete_str'])
            # self.debug(context['candidates'])
            for filter_name in \
                    source.matchers + source.sorters + source.converters:
                if filter_name in self.filters:
                    context['candidates'] = \
                        self.filters[filter_name].filter(context)
            # self.debug(context['candidates'])

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

            # Set default menu
            for candidate in context['candidates']:
                candidate['menu'] = \
                    source.mark + ' ' + candidate.get('menu', '')
            # self.debug(context['candidates'])
        return results
Esempio n. 26
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = context['sources']
        results = []
        start_length = self.vim.eval('g:deoplete#auto_completion_start_length')
        for source_name, source in sorted(self.sources.items(),
                                          key=lambda x: x[1].rank,
                                          reverse=True):
            if (sources and source_name not in sources) or (
                    source.filetypes
                    and not context['filetype'] in source.filetypes):
                continue
            cont = copy.deepcopy(context)
            charpos = source.get_complete_position(cont)
            if charpos >= 0 and source.is_bytepos:
                charpos = bytepos2charpos(self.vim, cont['input'], charpos)
            cont['complete_str'] = cont['input'][charpos:]
            cont['complete_position'] = charpos2bytepos(
                self.vim, cont['input'], charpos)
            # debug(self.vim, source.rank)
            # debug(self.vim, source_name)
            # debug(self.vim, cont['input'])
            # debug(self.vim, charpos)
            # debug(self.vim, cont['complete_position'])
            # debug(self.vim, cont['complete_str'])

            min_pattern_length = get_custom(self.vim, source.name).get(
                'min_pattern_length', source.min_pattern_length)
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length

            if charpos < 0 or (cont['event'] != 'Manual' and
                               len(cont['complete_str']) < min_pattern_length):
                # Skip
                continue
            results.append({
                'name': source_name,
                'source': source,
                'context': cont,
            })

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

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

            matchers = get_custom(self.vim,
                                  source.name).get('matchers', source.matchers)
            sorters = get_custom(self.vim,
                                 source.name).get('sorters', source.sorters)
            converters = get_custom(self.vim,
                                    source.name).get('converters',
                                                     source.converters)

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

                for filter_name in matchers + sorters + converters:
                    if filter_name in self.filters:
                        context['candidates'] = self.filters[
                            filter_name].filter(context)
            finally:
                context['ignorecase'] = ignorecase
            # debug(self.vim, context['candidates'])

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

            if context['candidates'] and (not re.match(
                    r'\[.*\]', context['candidates'][0].get('menu', ''))):
                # Set default menu
                for candidate in context['candidates']:
                    candidate['menu'] = source.mark + ' ' + candidate.get(
                        'menu', '')
            # debug(self.vim, context['candidates'])
        return results
Esempio n. 27
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = context['sources']
        results = []
        start_length = self.vim.eval('g:deoplete#auto_completion_start_length')
        for source_name, source in sorted(self.sources.items(),
                                          key=lambda x: x[1].rank,
                                          reverse=True):
            if (sources and not source_name in sources) \
                    or (source.filetypes and
                        not context['filetype'] in source.filetypes):
                continue
            cont = copy.deepcopy(context)
            charpos = source.get_complete_position(cont)
            if source.is_bytepos:
                charpos = bytepos2charpos(self.vim, cont['input'], charpos)
            cont['complete_str'] = cont['input'][charpos:]
            cont['complete_position'] = charpos2bytepos(
                self.vim, cont['input'], charpos)
            # 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'])

            min_pattern_length = source.min_pattern_length
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length

            if charpos < 0 \
                    or (cont['event'] != 'Manual' \
                        and len(cont['complete_str']) < min_pattern_length):
                # Skip
                continue
            results.append({
                'name': source_name,
                'source': source,
                'context': cont,
            })

        for result in results:
            context = result['context']
            source = result['source']
            context['candidates'] = source.gather_candidates(context)
            # self.debug(context['candidates'])

            # self.debug(context['complete_str'])
            # self.debug(context['candidates'])
            for filter_name in \
                    source.matchers + source.sorters + source.converters:
                if filter_name in self.filters:
                    context['candidates'] = \
                        self.filters[filter_name].filter(context)
            # self.debug(context['candidates'])

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

            # Set default menu
            for candidate in context['candidates']:
                if not 'menu' in candidate:
                    candidate['menu'] = source.mark
            # self.debug(context['candidates'])
        return results
Esempio n. 28
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. 29
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)

                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_candidates(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        buf = self.vim.current.buffer
        offset = self.vim.call('line2byte', line) + \
            charpos2bytepos(self.vim, context['input'][: column], column) - 1
        source = '\n'.join(buf).encode()

        process = subprocess.Popen([
            self.GoCodeBinary(), '-f=json', 'autocomplete', buf.name,
            str(offset)
        ],
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   start_new_session=True)
        process.stdin.write(source)
        stdout_data, stderr_data = process.communicate()
        result = loads(stdout_data.decode())

        try:
            if result[1][0]['class'] == 'PANIC':
                error(self.vim, 'gocode panicked')
                return []

            if self.sort_class:
                # TODO(zchee): Why not work with this?
                #              class_dict = {}.fromkeys(self.sort_class, [])
                class_dict = {
                    'package': [],
                    'func': [],
                    'type': [],
                    'var': [],
                    'const': [],
                }

            out = []
            sep = ' '

            for complete in result[1]:
                word = complete['name']
                info = complete['type']
                _class = complete['class']
                abbr = str(word + sep + info).replace(' func', '', 1)
                kind = _class

                if _class == 'package' and self.package_dot:
                    word += '.'

                candidates = dict(word=word,
                                  abbr=abbr,
                                  kind=kind,
                                  info=info,
                                  menu=self.mark,
                                  dup=1)

                if not self.sort_class or _class == 'import':
                    out.append(candidates)
                else:
                    class_dict[_class].append(candidates)

            # append with sort by complete['class']
            if self.sort_class:
                for c in self.sort_class:
                    for x in class_dict[c]:
                        out.append(x)

            return out
        except Exception:
            return []
Esempio n. 31
0
def test_pos():
    assert util.bytepos2charpos('utf-8', 'foo bar', 3) == 3
    assert util.bytepos2charpos('utf-8', 'あああ', 3) == 1
    assert util.charpos2bytepos('utf-8', 'foo bar', 3) == 3
    assert util.charpos2bytepos('utf-8', 'あああ', 3) == 9
Esempio n. 32
0
    def _get_result(self, context, source):
        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
            return {}

        if (source.name in self._prev_results and
                self._use_previous_result(
                    context, self._prev_results[source.name],
                    source.is_volatile)):
            return self._prev_results[source.name]

        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_info_width'] = min(source.max_info_width,
                                    ctx['max_info_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_info_width'] > 0:
            ctx['max_info_width'] = max(10, ctx['max_info_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:
            return {}

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

        return {
            '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'],
        }
Esempio n. 33
0
    def get_cursor_offset(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        return self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'][: column], column) - 1
Esempio n. 34
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = context["sources"]
        results = []
        start_length = self.vim.eval("g:deoplete#auto_completion_start_length")
        for source_name, source in sorted(self.sources.items(), key=lambda x: x[1].rank, reverse=True):
            if (sources and not source_name in sources) or (
                source.filetypes and not context["filetype"] in source.filetypes
            ):
                continue
            cont = copy.deepcopy(context)
            charpos = source.get_complete_position(cont)
            if charpos >= 0 and source.is_bytepos:
                charpos = bytepos2charpos(self.vim, cont["input"], charpos)
            cont["complete_str"] = cont["input"][charpos:]
            cont["complete_position"] = charpos2bytepos(self.vim, cont["input"], charpos)
            # debug(self.vim, source.rank)
            # debug(self.vim, source_name)
            # debug(self.vim, cont['input'])
            # debug(self.vim, charpos)
            # debug(self.vim, cont['complete_position'])
            # debug(self.vim, cont['complete_str'])

            min_pattern_length = source.min_pattern_length
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length

            if charpos < 0 or (cont["event"] != "Manual" and len(cont["complete_str"]) < min_pattern_length):
                # Skip
                continue
            results.append({"name": source_name, "source": source, "context": cont})

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

            # debug(self.vim, source.name)
            context["candidates"] = source.gather_candidates(context)
            if context["candidates"] and type(context["candidates"][0]) == type(""):
                # Convert to dict
                context["candidates"] = [{"word": x} for x in context["candidates"]]

            matchers = get_custom(self.vim, source.name).get("matchers", source.matchers)
            sorters = get_custom(self.vim, source.name).get("sorters", source.sorters)
            converters = get_custom(self.vim, source.name).get("converters", source.converters)

            ignorecase = context["ignorecase"]
            try:
                # Set ignorecase
                if context["smartcase"] and re.match(r"[A-Z]", context["complete_str"]):
                    context["ignorecase"] = 0

                for filter_name in matchers + sorters + converters:
                    if filter_name in self.filters:
                        context["candidates"] = self.filters[filter_name].filter(context)
            finally:
                context["ignorecase"] = ignorecase
            # debug(self.vim, context['candidates'])

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

            if context["candidates"] and (not re.match(r"\[.*\]", context["candidates"][0].get("menu", ""))):
                # Set default menu
                for candidate in context["candidates"]:
                    candidate["menu"] = source.mark + " " + candidate.get("menu", "")
            # debug(self.vim, context['candidates'])
        return results
Esempio n. 35
0
 def test_pos(self):
     eq_(bytepos2charpos('utf-8', 'foo bar', 3), 3)
     eq_(bytepos2charpos('utf-8', 'あああ', 3), 1)
     eq_(charpos2bytepos('utf-8', 'foo bar', 3), 3)
     eq_(charpos2bytepos('utf-8', 'あああ', 3), 9)
Esempio n. 36
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = sorted(
            self.__sources.items(), key=lambda x: get_custom(self.__vim, x[1].name).get("rank", x[1].rank), reverse=True
        )
        results = []
        start_length = self.__vim.vars["deoplete#auto_complete_start_length"]
        ignore_sources = get_buffer_config(
            self.__vim, context["filetype"], "b:deoplete_ignore_sources", "g:deoplete#ignore_sources", "{}"
        )
        for source_name, source in sources:
            in_sources = not context["sources"] or (source_name in context["sources"])
            in_fts = not source.filetypes or (context["filetype"] in source.filetypes)
            in_ignore = source_name in ignore_sources
            if not in_sources or not in_fts or in_ignore:
                continue
            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.__vim, cont["input"], charpos)
            cont["complete_str"] = cont["input"][charpos:]
            cont["complete_position"] = charpos2bytepos(self.__vim, cont["input"], charpos)
            # 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'])

            min_pattern_length = source.min_pattern_length
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length

            if charpos < 0 or self.is_skip(
                cont, source.disabled_syntaxes, 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(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(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)

            if context["candidates"] and not (re.match(r"\[.*\]", context["candidates"][0].get("menu", ""))):
                # Set default menu
                for candidate in context["candidates"]:
                    candidate["menu"] = source.mark + " " + candidate.get("menu", "")

            # self.debug(context['candidates'])
        return results
Esempio n. 37
0
    def _get_result(self, context, source):
        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
            return {}

        if (source.name in self._prev_results and self._use_previous_result(
                context, self._prev_results[source.name], source.is_volatile)):
            return self._prev_results[source.name]

        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:
            return {}

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

        return {
            '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'],
        }
Esempio n. 38
0
    def get_cursor_offset(self, context):
        line = self.vim.current.window.cursor[0]
        column = context['complete_position']

        return self.vim.call('line2byte', line) + \
            charpos2bytepos('utf-8', context['input'][: column], column) - 1
Esempio n. 39
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = sorted(self.__sources.items(),
                         key=lambda x: get_custom(self.__vim, x[1].name).get(
                             'rank', x[1].rank),
                         reverse=True)
        results = []
        start_length = self.__vim.vars['deoplete#auto_complete_start_length']
        ignore_sources = get_buffer_config(self.__vim, context['filetype'],
                                           'b:deoplete_ignore_sources',
                                           'g:deoplete#ignore_sources', '{}')
        for source_name, source in sources:
            filetypes = get_custom(self.__vim,
                                   source.name).get('filetypes',
                                                    source.filetypes)

            in_sources = not context['sources'] or (source_name
                                                    in context['sources'])
            in_fts = not filetypes or (context['filetype'] in filetypes)
            in_ignore = source_name in ignore_sources
            if not in_sources or not in_fts or in_ignore:
                continue
            disabled_syntaxes = get_custom(self.__vim, source.name).get(
                'disabled_syntaxes', source.disabled_syntaxes)
            if 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.__vim, cont['input'], charpos)
            cont['complete_str'] = cont['input'][charpos:]
            cont['complete_position'] = charpos2bytepos(
                self.__vim, cont['input'], charpos)
            # 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'])

            min_pattern_length = get_custom(self.__vim, source.name).get(
                'min_pattern_length', source.min_pattern_length)
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length
            max_pattern_length = get_custom(self.__vim, source.name).get(
                'max_pattern_length', source.max_pattern_length)
            input_pattern = get_custom(self.__vim, source.name).get(
                'input_pattern', source.input_pattern)

            if charpos < 0 or self.is_skip(cont, disabled_syntaxes,
                                           min_pattern_length,
                                           max_pattern_length, 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(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']]

            matchers = get_custom(self.__vim,
                                  source.name).get('matchers', source.matchers)
            sorters = get_custom(self.__vim,
                                 source.name).get('sorters', source.sorters)
            converters = get_custom(self.__vim,
                                    source.name).get('converters',
                                                     source.converters)

            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 matchers + sorters + converters
                        if x in self.__filters
                ]:
                    self.profile_start(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)

            if context['candidates'] and not (re.match(
                    r'\[.*\]', context['candidates'][0].get('menu', ''))):
                # Set default menu
                for candidate in context['candidates']:
                    candidate['menu'] = source.mark + ' ' + candidate.get(
                        'menu', '')

            # self.debug(context['candidates'])
        return results
Esempio n. 40
0
    def gather_results(self, context):
        # sources = ['buffer', 'neosnippet']
        # sources = ['buffer']
        sources = sorted(self.__sources.items(),
                         key=lambda x: get_custom(self.__vim, x[1].name).get(
                             'rank', x[1].rank),
                         reverse=True)
        results = []
        start_length = self.__vim.vars['deoplete#auto_complete_start_length']
        for source_name, source in self.itersource(context, sources):
            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.__vim, cont['input'], charpos)
            cont['complete_str'] = cont['input'][charpos:]
            cont['complete_position'] = charpos2bytepos(
                self.__vim, 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'])

            min_pattern_length = source.min_pattern_length
            if min_pattern_length < 0:
                # Use default value
                min_pattern_length = start_length

            if charpos < 0 or self.is_skip(cont, source.disabled_syntaxes,
                                           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(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(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)

            if context['candidates'] and not (
                    re.match(r'\[.*\]',
                             context['candidates'][0].get('menu', ''))):
                # Set default menu
                for candidate in context['candidates']:
                    candidate['menu'] = source.mark + ' ' + candidate.get(
                        'menu', '')

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