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

Move args and run settings to lint.args and lint.run #255

Merged
merged 1 commit into from
Oct 2, 2023
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
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,17 @@ the LSP client's `settings.json`:
The exact mechanism by which settings will be passed to `ruff-lsp` will vary by editor. However,
the following settings are supported:

| Settings | Default | Description |
| ------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| args | `[]` | Additional command-line arguments to pass to `ruff`, e.g., `"args": ["--config=/path/to/pyproject.toml"]`. Supports a subset of Ruff's command-line arguments, ignoring those that are required to operate the LSP, like `--force-exclude` and `--verbose`. |
| logLevel | `error` | Sets the tracing level for the extension: `error`, `warn`, `info`, or `debug`. |
| path | `[]` | Path to a custom `ruff` executable, e.g., `["/path/to/ruff"]`. |
| interpreter | `[]` | Path to a Python interpreter to use to run the linter server. |
| run | `onType` | Run Ruff on every keystroke (`onType`) or on save (`onSave`). |
| organizeImports | `true` | Whether to register Ruff as capable of handling `source.organizeImports` actions. |
| fixAll | `true` | Whether to register Ruff as capable of handling `source.fixAll` actions. |
| codeAction.fixViolation.enable | `true` | Whether to display Quick Fix actions to autofix violations. |
| codeAction.disableRuleComment.enable | `true` | Whether to display Quick Fix actions to disable rules via `noqa` suppression comments. |
| Settings | Default | Description |
|--------------------------------------| -------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| lint.args | `[]` | Additional command-line arguments to pass to `ruff check`, e.g., `"args": ["--config=/path/to/pyproject.toml"]`. Supports a subset of Ruff's command-line arguments, ignoring those that are required to operate the LSP, like `--force-exclude` and `--verbose`. |
| lint.run | `onType` | Run Ruff on every keystroke (`onType`) or on save (`onSave`). |
| path | `[]` | Path to a custom `ruff` executable, e.g., `["/path/to/ruff"]`. |
| interpreter | `[]` | Path to a Python interpreter to use to run the linter server. |
| organizeImports | `true` | Whether to register Ruff as capable of handling `source.organizeImports` actions. |
| fixAll | `true` | Whether to register Ruff as capable of handling `source.fixAll` actions. |
| codeAction.fixViolation.enable | `true` | Whether to display Quick Fix actions to autofix violations. |
| logLevel | `error` | Sets the tracing level for the extension: `error`, `warn`, `info`, or `debug`. |
| codeAction.disableRuleComment.enable | `true` | Whether to display Quick Fix actions to disable rules via `noqa` suppression comments. |

## Development

Expand Down
32 changes: 21 additions & 11 deletions ruff_lsp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@
from typing_extensions import TypedDict

from ruff_lsp import __version__, utils
from ruff_lsp.settings import UserSettings, WorkspaceSettings
from ruff_lsp.settings import (
UserSettings,
WorkspaceSettings,
lint_args,
lint_run,
)
from ruff_lsp.utils import RunResult

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -179,7 +184,7 @@ def did_close(params: DidCloseTextDocumentParams) -> None:
async def did_save(params: DidSaveTextDocumentParams) -> None:
"""LSP handler for textDocument/didSave request."""
document = LSP_SERVER.workspace.get_document(params.text_document.uri)
if _get_settings_by_document(document).get("run", "onSave") == "onSave":
if lint_run(_get_settings_by_document(document), "onSave") == "onSave":
diagnostics: list[Diagnostic] = await _lint_document_impl(document)
LSP_SERVER.publish_diagnostics(document.uri, diagnostics)

Expand All @@ -188,7 +193,7 @@ async def did_save(params: DidSaveTextDocumentParams) -> None:
async def did_change(params: DidChangeTextDocumentParams) -> None:
"""LSP handler for textDocument/didChange request."""
document = LSP_SERVER.workspace.get_document(params.text_document.uri)
if _get_settings_by_document(document).get("run", "onType") == "onType":
if lint_run(_get_settings_by_document(document), "onType") == "onType":
diagnostics: list[Diagnostic] = await _lint_document_impl(document)
LSP_SERVER.publish_diagnostics(document.uri, diagnostics)

Expand Down Expand Up @@ -938,15 +943,18 @@ def _supports_code_action_resolve(capabilities: ClientCapabilities) -> bool:

def _get_global_defaults() -> UserSettings:
return {
"codeAction": GLOBAL_SETTINGS.get("codeAction", {}),
"fixAll": GLOBAL_SETTINGS.get("fixAll", True),
"importStrategy": GLOBAL_SETTINGS.get("importStrategy", "fromEnvironment"),
"interpreter": GLOBAL_SETTINGS.get("interpreter", [sys.executable]),
"lint": GLOBAL_SETTINGS.get("lint", {}),
"logLevel": GLOBAL_SETTINGS.get("logLevel", "error"),
"args": GLOBAL_SETTINGS.get("args", []),
"organizeImports": GLOBAL_SETTINGS.get("organizeImports", True),
"path": GLOBAL_SETTINGS.get("path", []),
"interpreter": GLOBAL_SETTINGS.get("interpreter", [sys.executable]),
"importStrategy": GLOBAL_SETTINGS.get("importStrategy", "fromEnvironment"),
# Deprecated: use `lint.args` instead.
"args": GLOBAL_SETTINGS.get("args", []),
# Deprecated: use `lint.run` instead.
"run": GLOBAL_SETTINGS.get("run", "onType"),
"codeAction": GLOBAL_SETTINGS.get("codeAction", {}),
"organizeImports": GLOBAL_SETTINGS.get("organizeImports", True),
"fixAll": GLOBAL_SETTINGS.get("fixAll", True),
}


Expand Down Expand Up @@ -993,7 +1001,9 @@ def _get_document_key(document: workspace.Document) -> str | None:
return None


def _get_settings_by_document(document: workspace.Document | None) -> WorkspaceSettings:
def _get_settings_by_document(
document: workspace.Document | None,
) -> WorkspaceSettings:
if document is None or document.path is None:
return list(WORKSPACE_SETTINGS.values())[0]

Expand Down Expand Up @@ -1133,7 +1143,7 @@ async def _run_check_on_document(
executable = _find_ruff_binary(settings, VERSION_REQUIREMENT_LINTER)
argv: list[str] = CHECK_ARGS + list(extra_args)

for arg in settings["args"]:
for arg in lint_args(settings):
if arg in UNSUPPORTED_ARGS:
log_to_output(f"Ignoring unsupported argument: {arg}")
else:
Expand Down
47 changes: 41 additions & 6 deletions ruff_lsp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@

from typing_extensions import Literal, TypedDict

Run = Literal["onSave", "onType"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe RunOn or RunTrigger or something else less generic



class UserSettings(TypedDict, total=False):
"""Settings for the Ruff Language Server."""

logLevel: Literal["error", "warning", "info", "debug"]
"""The log level for the Ruff server. Defaults to "error"."""

args: list[str]
"""Additional command-line arguments to pass to `ruff`."""

path: list[str]
"""Path to a custom `ruff` executable."""

Expand All @@ -21,9 +20,6 @@ class UserSettings(TypedDict, total=False):
importStrategy: Literal["fromEnvironment", "useBundled"]
"""Strategy for loading the `ruff` executable."""

run: Literal["onSave", "onType"]
"""Run Ruff on every keystroke (`onType`) or on save (`onSave`)."""

codeAction: CodeActions
"""Settings for the `source.codeAction` capability."""

Expand All @@ -33,6 +29,17 @@ class UserSettings(TypedDict, total=False):
fixAll: bool
"""Whether to register Ruff as capable of handling `source.fixAll`."""

lint: Lint
"""Settings specific to lint capabilities."""

# Deprecated: use `lint.args` instead.
args: list[str]
"""Additional command-line arguments to pass to `ruff check`."""

# Deprecated: use `lint.run` instead.
run: Run
"""Run Ruff on every keystroke (`onType`) or on save (`onSave`)."""


class WorkspaceSettings(TypedDict, UserSettings):
cwd: str | None
Expand All @@ -56,3 +63,31 @@ class CodeActions(TypedDict, total=False):
class CodeAction(TypedDict, total=False):
enable: bool
"""Whether to enable the code action."""


class Lint(TypedDict, total=False):
args: list[str]
"""Additional command-line arguments to pass to `ruff check`."""

run: Run
"""Run Ruff on every keystroke (`onType`) or on save (`onSave`)."""


def lint_args(settings: UserSettings) -> list[str]:
"""Get the `lint.args` setting from the user settings."""
if "lint" in settings and "args" in settings["lint"]:
return settings["lint"]["args"]
elif "args" in settings:
return settings["args"]
else:
return []


def lint_run(settings: UserSettings, default: Run) -> Run:
"""Get the `lint.run` setting from the user settings."""
if "lint" in settings and "run" in settings["lint"]:
return settings["lint"]["run"]
elif "run" in settings:
return settings["run"]
else:
return default