Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hover filter #149

Merged
merged 7 commits into from
Jun 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,23 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.32.0

### Added

- Initialization options to granularly disable names and full names for hover operations based on their Jedi type. This is useful because some text editors will automatically send hover requests when a user pauses their cursor over text and the large amount of information can get annoying for some users. Resolves: <https://github.com/pappasam/jedi-language-server/issues/147>. Jedi types are currently: `module`, `class`, `instance`, `function`, `param`, `path`, `keyword`, `property`, and `statement`.
- Initialization option to disable hover entirely. If `enable` is set to false, the hover language feature will not be registered. May consider adding something similar to most language server features if this proves useful.

### Changed

- In Hover, `Path` has been renamed to `Full name`, which is more accurate and is directly tied to the hover disabling options.
- Restrict Python version support to >= 3.6.2. Upgraded development dependencies. Latest black doesn't support Python < 3.6.2, so to keep things simple here we're now not supporting Python versions below that version either.

## 0.31.2

### Fixed

- Docstring now presents same information as before, but organized more-tersely, (arguably) more clearly, and with much better markdown syntax support. For example, the name / signature has been pulled out from the main docstring and wrapped in python triple backticks while the docstring is conditionally replaced with the description where relevant.
- Docstring now presents same information as before, but organized more-tersely, (arguably) more clearly, and with much better markdown syntax support. For example, the name / signature has been pulled out from the main docstring and wrapped in python triple back ticks while the docstring is conditionally replaced with the description where relevant.

## 0.31.1

Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

[![image-version](https://img.shields.io/pypi/v/jedi-language-server.svg)](https://python.org/pypi/jedi-language-server)
[![image-license](https://img.shields.io/pypi/l/jedi-language-server.svg)](https://python.org/pypi/jedi-language-server)
[![image-python-versions](https://img.shields.io/badge/python->=3.6.1-blue)](https://python.org/pypi/jedi-language-server)
[![image-python-versions](https://img.shields.io/badge/python->=3.6.2-blue)](https://python.org/pypi/jedi-language-server)
[![image-pypi-downloads](https://pepy.tech/badge/jedi-language-server)](https://pepy.tech/project/jedi-language-server)
[![github-action-testing](https://github.com/pappasam/jedi-language-server/actions/workflows/testing.yaml/badge.svg)](https://github.com/pappasam/jedi-language-server/actions/workflows/testing.yaml)

A [Language Server](https://microsoft.github.io/language-server-protocol/) for the latest version(s) of [Jedi](https://jedi.readthedocs.io/en/latest/). If using Neovim/Vim, we recommend using with [coc-jedi](https://github.com/pappasam/coc-jedi). Supports Python versions 3.6.1 and newer.
A [Language Server](https://microsoft.github.io/language-server-protocol/) for the latest version(s) of [Jedi](https://jedi.readthedocs.io/en/latest/). If using Neovim/Vim, we recommend using with [coc-jedi](https://github.com/pappasam/coc-jedi). Supports Python versions 3.6.2 and newer.

**Note:** this tool is actively used by its primary author. He's happy to review pull requests / respond to issues you may discover.

Expand Down Expand Up @@ -125,6 +125,20 @@ If you are configuring manually, jedi-language-server supports the following [in
"didChange": true,
"didSave": true
},
"hover": {
"enable": true,
"disable": {
"class": { "all": false, "names": [], "full_names": [] },
"function": { "all": false, "names": [], "full_names": [] },
"instance": { "all": false, "names": [], "full_names": [] },
"keyword": { "all": false, "names": [], "full_names": [] },
"module": { "all": false, "names": [], "full_names": [] },
"param": { "all": false, "names": [], "full_names": [] },
"path": { "all": false, "names": [], "full_names": [] },
"property": { "all": false, "names": [], "full_names": [] },
"statement": { "all": false, "names": [], "full_names": [] }
}
},
"jediSettings": {
"autoImportModules": [],
"caseInsensitiveCompletion": true
Expand Down
53 changes: 51 additions & 2 deletions jedi_language_server/initialization_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
initialization options.
"""

from typing import List, Optional
from typing import List, Optional, Set

from pydantic import BaseModel
from pydantic import BaseModel, Field
from pygls.lsp.types import MarkupKind

# pylint: disable=missing-class-docstring
Expand Down Expand Up @@ -43,6 +43,54 @@ class Diagnostics(Model):
did_change: bool = True


class HoverDisableOptions(Model):
all: bool = False
names: Set[str] = set()
full_names: Set[str] = set()


class HoverDisable(Model):
"""All Attributes have _ appended to avoid syntax conflicts.

For example, the keyword class would have required a special case.
To get around this, I decided it's simpler to always assume an
underscore at the end.
"""

keyword_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="keyword"
)
module_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="module"
)
class_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="class"
)
instance_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="instance"
)
function_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="function"
)
param_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="param"
)
path_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="path"
)
property_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="property"
)
statement_: HoverDisableOptions = Field(
default=HoverDisableOptions(), alias="statement"
)


class Hover(Model):
enable: bool = True
disable: HoverDisable = HoverDisable()


class JediSettings(Model):
auto_import_modules: List[str] = []
case_insensitive_completion: bool = True
Expand All @@ -62,6 +110,7 @@ class InitializationOptions(Model):
code_action: CodeAction = CodeAction()
completion: Completion = Completion()
diagnostics: Diagnostics = Diagnostics()
hover: Hover = Hover()
jedi_settings: JediSettings = JediSettings()
markup_kind_preferred: Optional[MarkupKind]
workspace: Workspace = Workspace()
40 changes: 32 additions & 8 deletions jedi_language_server/jedi_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
)
from pygls.workspace import Document

from .initialization_options import InitializationOptions
from .initialization_options import HoverDisableOptions, InitializationOptions
from .type_map import get_lsp_completion_type, get_lsp_symbol_type


Expand Down Expand Up @@ -461,21 +461,47 @@ def convert_docstring(docstring: str, markup_kind: MarkupKind) -> str:
}


def hover_text(names: List[Name], markup_kind: MarkupKind) -> Optional[str]:
def _hover_ignore(name: Name, init: InitializationOptions) -> bool:
"""True if hover should be ignored, false otherwise.

Split into separate function for readability.

Note: appends underscore to lookup because pydantic model requires it.
"""
name_str = name.name
if not name_str:
return True
ignore_type: HoverDisableOptions = getattr(
init.hover.disable, name.type + "_"
)
return (
ignore_type.all is True
or name_str in ignore_type.names
or (name.full_name or name_str) in ignore_type.full_names
)


def hover_text(
names: List[Name],
markup_kind: MarkupKind,
initialization_options: InitializationOptions,
) -> Optional[str]:
"""Get a hover string from a list of names."""
# pylint: disable=too-many-branches
if not names:
return None
name = names[0]
if _hover_ignore(name, initialization_options):
return None
name_str = name.name
name_type = name.type
full_name = name.full_name
hover_type = _HOVER_TYPE_TRANSLATION[name_type]
signatures = (
[f"{hover_type} {s.to_string()}" for s in name.get_signatures()]
if name_type in _HOVER_SIGNATURE_TYPES
else []
)
name_str = name.name
full_name = name.full_name
description = name.description
docstring = name.docstring(raw=True)
if not signatures and name_type != "class":
Expand Down Expand Up @@ -504,7 +530,7 @@ def hover_text(names: List[Name], markup_kind: MarkupKind) -> Optional[str]:
if docstring:
result.append("---")
result.append(convert_docstring(docstring, markup_kind))
elif header_plain.strip().startswith(description.strip()):
elif header_plain.startswith(description):
pass
else:
result.append("---")
Expand All @@ -514,12 +540,10 @@ def hover_text(names: List[Name], markup_kind: MarkupKind) -> Optional[str]:
if len(result) == 1:
result.append("---")
result.append(
_md_bold("Path:", markup_kind)
_md_bold("Full name:", markup_kind)
+ " "
+ _md_text_sl(full_name, markup_kind)
)
if not result:
return None
return "\n".join(result).strip()


Expand Down
10 changes: 8 additions & 2 deletions jedi_language_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ def bf_initialize(self, params: InitializeParams) -> InitializeResult:
server.feature(TEXT_DOCUMENT_DID_OPEN)(did_open)
server.feature(TEXT_DOCUMENT_DID_CHANGE)(did_change)
server.feature(TEXT_DOCUMENT_DID_SAVE)(did_save)

if server.initialization_options.hover.enable:
server.feature(HOVER)(hover)

initialize_result: InitializeResult = super().bf_initialize(params)
server.project = (
Project(
Expand Down Expand Up @@ -301,7 +305,7 @@ def highlight(
return highlight_names if highlight_names else None


@SERVER.feature(HOVER)
# Registered with HOVER dynamically
def hover(
server: JediLanguageServer, params: TextDocumentPositionParams
) -> Optional[Hover]:
Expand All @@ -311,7 +315,9 @@ def hover(
jedi_lines = jedi_utils.line_column(jedi_script, params.position)
markup_kind = _choose_markup(server)
hover_text = jedi_utils.hover_text(
jedi_script.help(**jedi_lines), markup_kind
jedi_script.help(**jedi_lines),
markup_kind,
server.initialization_options,
)
if not hover_text:
return None
Expand Down
Loading