Ejemplo n.º 1
0
def pyls_completions(config, document, position):
    """Get formatted completions for current code position"""
    settings = config.plugin_settings('jedi_completion', document_path=document.path)
    code_position = _utils.position_to_jedi_linecolumn(document, position)

    code_position["fuzzy"] = settings.get("fuzzy", False)
    completions = document.jedi_script().complete(**code_position)

    if not completions:
        return None

    completion_capabilities = config.capabilities.get('textDocument', {}).get('completion', {})
    snippet_support = completion_capabilities.get('completionItem', {}).get('snippetSupport')

    should_include_params = settings.get('include_params')
    should_include_class_objects = settings.get('include_class_objects', True)

    include_params = snippet_support and should_include_params and use_snippets(document, position)
    include_class_objects = snippet_support and should_include_class_objects and use_snippets(document, position)

    ready_completions = [
        _format_completion(c, include_params)
        for c in completions
    ]

    if include_class_objects:
        for c in completions:
            if c.type == 'class':
                completion_dict = _format_completion(c, False)
                completion_dict['kind'] = lsp.CompletionItemKind.TypeParameter
                completion_dict['label'] += ' object'
                ready_completions.append(completion_dict)

    return ready_completions or None
Ejemplo n.º 2
0
def pyls_rename(config, workspace, document, position, new_name):  # pylint: disable=unused-argument
    log.debug('Executing rename of %s to %s', document.word_at_position(position), new_name)
    kwargs = _utils.position_to_jedi_linecolumn(document, position)
    kwargs['new_name'] = new_name
    try:
        refactoring = document.jedi_script().rename(**kwargs)
    except NotImplementedError:
        raise Exception('No support for renaming in Python 2/3.5 with Jedi. '
                        'Consider using the rope_rename plugin instead')
    log.debug('Finished rename: %s', refactoring.get_diff())

    return {
        'documentChanges': [
            {
                'textDocument': {
                    'uri': uris.uri_with(document.uri, path=file_path),
                    'version': workspace.get_document(document.uri).version,
                },
                'edits': [
                    {
                        'range': {
                            'start': {'line': 0, 'character': 0},
                            'end': {
                                'line': _num_lines(changed_file.get_new_code()),
                                'character': 0,
                            },
                        },
                        'newText': changed_file.get_new_code(),
                    }
                ],
            }
            for file_path, changed_file in refactoring.get_changed_files().items()
        ],
    }
Ejemplo n.º 3
0
def pyls_signature_help(document, position):
    code_position = _utils.position_to_jedi_linecolumn(document, position)
    signatures = document.jedi_script().get_signatures(**code_position)

    if not signatures:
        return {'signatures': []}

    s = signatures[0]

    # Docstring contains one or more lines of signature, followed by empty line, followed by docstring
    function_sig_lines = (s.docstring().split('\n\n') or [''])[0].splitlines()
    function_sig = ' '.join([line.strip() for line in function_sig_lines])
    sig = {
        'label': function_sig,
        'documentation': _utils.format_docstring(s.docstring(raw=True))
    }

    # If there are params, add those
    if s.params:
        sig['parameters'] = [{
            'label':
            p.name,
            'documentation':
            _param_docs(s.docstring(), p.name)
        } for p in s.params]

    # We only return a single signature because Python doesn't allow overloading
    sig_info = {'signatures': [sig], 'activeSignature': 0}

    if s.index is not None and s.params:
        # Then we know which parameter we're looking at
        sig_info['activeParameter'] = s.index

    return sig_info
Ejemplo n.º 4
0
def pyls_document_highlight(document, position):
    code_position = _utils.position_to_jedi_linecolumn(document, position)
    usages = document.jedi_script().get_references(**code_position)

    def is_valid(definition):
        return definition.line is not None and definition.column is not None

    def local_to_document(definition):
        return not definition.module_path or definition.module_path == document.path

    return [{
        'range': {
            'start': {
                'line': d.line - 1,
                'character': d.column
            },
            'end': {
                'line': d.line - 1,
                'character': d.column + len(d.name)
            }
        },
        'kind':
        lsp.DocumentHighlightKind.Write
        if d.is_definition() else lsp.DocumentHighlightKind.Read
    } for d in usages if is_valid(d) and local_to_document(d)]
Ejemplo n.º 5
0
def pyls_definitions(config, document, position):
    settings = config.plugin_settings('jedi_definition')
    code_position = _utils.position_to_jedi_linecolumn(document, position)
    definitions = document.jedi_script().goto(
        follow_imports=settings.get('follow_imports', True),
        follow_builtin_imports=settings.get('follow_builtin_imports', True),
        **code_position)

    return [{
        'uri': uris.uri_with(document.uri, path=d.module_path),
        'range': {
            'start': {
                'line': d.line - 1,
                'character': d.column
            },
            'end': {
                'line': d.line - 1,
                'character': d.column + len(d.name)
            },
        }
    } for d in definitions
            if d.is_definition() and _not_internal_definition(d)]
Ejemplo n.º 6
0
def pyls_hover(document, position):
    code_position = _utils.position_to_jedi_linecolumn(document, position)
    definitions = document.jedi_script().infer(**code_position)
    word = document.word_at_position(position)

    # Find first exact matching definition
    definition = next((x for x in definitions if x.name == word), None)

    # Ensure a definition is used if only one is available
    # even if the word doesn't match. An example of this case is 'np'
    # where 'numpy' doesn't match with 'np'. Same for NumPy ufuncs
    if len(definitions) == 1:
        definition = definitions[0]

    if not definition:
        return {'contents': ''}

    # raw docstring returns only doc, without signature
    doc = _utils.format_docstring(definition.docstring(raw=True))

    # Find first exact matching signature
    signature = next(
        (x.to_string() for x in definition.get_signatures() if x.name == word),
        '')

    contents = []
    if signature:
        contents.append({
            'language': 'python',
            'value': signature,
        })

    if doc:
        contents.append(doc)

    if not contents:
        return {'contents': ''}

    return {'contents': contents}
Ejemplo n.º 7
0
def pyls_references(document, position, exclude_declaration=False):
    code_position = _utils.position_to_jedi_linecolumn(document, position)
    usages = document.jedi_script().get_references(**code_position)

    if exclude_declaration:
        # Filter out if the usage is the actual declaration of the thing
        usages = [d for d in usages if not d.is_definition()]

    # Filter out builtin modules
    return [{
        'uri':
        uris.uri_with(document.uri, path=str(d.module_path))
        if d.module_path else document.uri,
        'range': {
            'start': {
                'line': d.line - 1,
                'character': d.column
            },
            'end': {
                'line': d.line - 1,
                'character': d.column + len(d.name)
            }
        }
    } for d in usages if not d.in_builtin_module()]