Skip to content

Commit

Permalink
Support notebook-scoped VS Code actions
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jan 5, 2024
1 parent 9d7db27 commit 1c7c119
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 56 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ urls = { repository = "https://github.com/astral-sh/ruff-lsp" }
dependencies = [
"packaging>=23.1",
"pygls>=1.1.0",
"lsprotocol>=2023.0.0a1",
"lsprotocol>=2023.0.0",
"ruff>=0.0.274",
"typing_extensions",
]
Expand Down
48 changes: 24 additions & 24 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#
# pip-compile --extra=dev --generate-hashes --output-file=requirements-dev.txt --resolver=backtracking pyproject.toml
#
attrs==23.1.0 \
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
attrs==23.2.0 \
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
# via
# cattrs
# lsprotocol
Expand Down Expand Up @@ -102,9 +102,9 @@ pyproject-hooks==1.0.0 \
--hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 \
--hash=sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5
# via build
pytest==7.4.3 \
--hash=sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac \
--hash=sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5
pytest==7.4.4 \
--hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \
--hash=sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8
# via
# pytest-asyncio
# ruff-lsp (pyproject.toml)
Expand All @@ -116,24 +116,24 @@ python-lsp-jsonrpc==1.0.0 \
--hash=sha256:079b143be64b0a378bdb21dff5e28a8c1393fe7e8a654ef068322d754e545fc7 \
--hash=sha256:7bec170733db628d3506ea3a5288ff76aa33c70215ed223abdb0d95e957660bd
# via ruff-lsp (pyproject.toml)
ruff==0.1.8 \
--hash=sha256:05ffe9dbd278965271252704eddb97b4384bf58b971054d517decfbf8c523f05 \
--hash=sha256:5daaeaf00ae3c1efec9742ff294b06c3a2a9db8d3db51ee4851c12ad385cda30 \
--hash=sha256:7d076717c67b34c162da7c1a5bda16ffc205e0e0072c03745275e7eab888719f \
--hash=sha256:7de792582f6e490ae6aef36a58d85df9f7a0cfd1b0d4fe6b4fb51803a3ac96fa \
--hash=sha256:a05b0ddd7ea25495e4115a43125e8a7ebed0aa043c3d432de7e7d6e8e8cd6448 \
--hash=sha256:aa8ee4f8440023b0a6c3707f76cadce8657553655dcbb5fc9b2f9bb9bee389f6 \
--hash=sha256:b6a21ab023124eafb7cef6d038f835cb1155cd5ea798edd8d9eb2f8b84be07d9 \
--hash=sha256:bd8ee69b02e7bdefe1e5da2d5b6eaaddcf4f90859f00281b2333c0e3a0cc9cd6 \
--hash=sha256:c8e3255afd186c142eef4ec400d7826134f028a85da2146102a1172ecc7c3696 \
--hash=sha256:ce697c463458555027dfb194cb96d26608abab920fa85213deb5edf26e026664 \
--hash=sha256:db6cedd9ffed55548ab313ad718bc34582d394e27a7875b4b952c2d29c001b26 \
--hash=sha256:e49fbdfe257fa41e5c9e13c79b9e79a23a79bd0e40b9314bc53840f520c2c0b3 \
--hash=sha256:e6f08ca730f4dc1b76b473bdf30b1b37d42da379202a059eae54ec7fc1fbcfed \
--hash=sha256:f35960b02df6b827c1b903091bb14f4b003f6cf102705efc4ce78132a0aa5af3 \
--hash=sha256:f41f692f1691ad87f51708b823af4bb2c5c87c9248ddd3191c8f088e66ce590a \
--hash=sha256:f7ee467677467526cfe135eab86a40a0e8db43117936ac4f9b469ce9cdb3fb62 \
--hash=sha256:ff78a7583020da124dd0deb835ece1d87bb91762d40c514ee9b67a087940528b
ruff==0.1.11 \
--hash=sha256:09c415716884950080921dd6237767e52e227e397e2008e2bed410117679975b \
--hash=sha256:0f58948c6d212a6b8d41cd59e349751018797ce1727f961c2fa755ad6208ba45 \
--hash=sha256:190a566c8f766c37074d99640cd9ca3da11d8deae2deae7c9505e68a4a30f740 \
--hash=sha256:231d8fb11b2cc7c0366a326a66dafc6ad449d7fcdbc268497ee47e1334f66f77 \
--hash=sha256:4b077ce83f47dd6bea1991af08b140e8b8339f0ba8cb9b7a484c30ebab18a23f \
--hash=sha256:5b25093dad3b055667730a9b491129c42d45e11cdb7043b702e97125bcec48a1 \
--hash=sha256:6464289bd67b2344d2a5d9158d5eb81025258f169e69a46b741b396ffb0cda95 \
--hash=sha256:934832f6ed9b34a7d5feea58972635c2039c7a3b434fe5ba2ce015064cb6e955 \
--hash=sha256:97ce4d752f964ba559c7023a86e5f8e97f026d511e48013987623915431c7ea9 \
--hash=sha256:9b8f397902f92bc2e70fb6bebfa2139008dc72ae5177e66c383fa5426cb0bf2c \
--hash=sha256:9bd4025b9c5b429a48280785a2b71d479798a69f5c2919e7d274c5f4b32c3607 \
--hash=sha256:a7f772696b4cdc0a3b2e527fc3c7ccc41cdcb98f5c80fdd4f2b8c50eb1458196 \
--hash=sha256:c4a88efecec23c37b11076fe676e15c6cdb1271a38f2b415e381e87fe4517f18 \
--hash=sha256:e1ad00662305dcb1e987f5ec214d31f7d6a062cae3e74c1cbccef15afd96611d \
--hash=sha256:ea0d3e950e394c4b332bcdd112aa566010a9f9c95814844a7468325290aabfd9 \
--hash=sha256:eb85ee287b11f901037a6683b2374bb0ec82928c5cbc984f575d0437979c521a \
--hash=sha256:f9d4d88cb6eeb4dfe20f9f0519bd2eaba8119bde87c3d5065c541dbae2b5a2cb
# via ruff-lsp (pyproject.toml)
tomli==2.0.1 \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
Expand Down
42 changes: 21 additions & 21 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#
# pip-compile --generate-hashes --output-file=requirements.txt --resolver=backtracking pyproject.toml
#
attrs==23.1.0 \
--hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
--hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
attrs==23.2.0 \
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
--hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
# via
# cattrs
# lsprotocol
Expand Down Expand Up @@ -36,24 +36,24 @@ pygls==1.2.1 \
--hash=sha256:04f9b9c115b622dcc346fb390289066565343d60245a424eca77cb429b911ed8 \
--hash=sha256:7dcfcf12b6f15beb606afa46de2ed348b65a279c340ef2242a9a35c22eeafe94
# via ruff-lsp (pyproject.toml)
ruff==0.1.8 \
--hash=sha256:05ffe9dbd278965271252704eddb97b4384bf58b971054d517decfbf8c523f05 \
--hash=sha256:5daaeaf00ae3c1efec9742ff294b06c3a2a9db8d3db51ee4851c12ad385cda30 \
--hash=sha256:7d076717c67b34c162da7c1a5bda16ffc205e0e0072c03745275e7eab888719f \
--hash=sha256:7de792582f6e490ae6aef36a58d85df9f7a0cfd1b0d4fe6b4fb51803a3ac96fa \
--hash=sha256:a05b0ddd7ea25495e4115a43125e8a7ebed0aa043c3d432de7e7d6e8e8cd6448 \
--hash=sha256:aa8ee4f8440023b0a6c3707f76cadce8657553655dcbb5fc9b2f9bb9bee389f6 \
--hash=sha256:b6a21ab023124eafb7cef6d038f835cb1155cd5ea798edd8d9eb2f8b84be07d9 \
--hash=sha256:bd8ee69b02e7bdefe1e5da2d5b6eaaddcf4f90859f00281b2333c0e3a0cc9cd6 \
--hash=sha256:c8e3255afd186c142eef4ec400d7826134f028a85da2146102a1172ecc7c3696 \
--hash=sha256:ce697c463458555027dfb194cb96d26608abab920fa85213deb5edf26e026664 \
--hash=sha256:db6cedd9ffed55548ab313ad718bc34582d394e27a7875b4b952c2d29c001b26 \
--hash=sha256:e49fbdfe257fa41e5c9e13c79b9e79a23a79bd0e40b9314bc53840f520c2c0b3 \
--hash=sha256:e6f08ca730f4dc1b76b473bdf30b1b37d42da379202a059eae54ec7fc1fbcfed \
--hash=sha256:f35960b02df6b827c1b903091bb14f4b003f6cf102705efc4ce78132a0aa5af3 \
--hash=sha256:f41f692f1691ad87f51708b823af4bb2c5c87c9248ddd3191c8f088e66ce590a \
--hash=sha256:f7ee467677467526cfe135eab86a40a0e8db43117936ac4f9b469ce9cdb3fb62 \
--hash=sha256:ff78a7583020da124dd0deb835ece1d87bb91762d40c514ee9b67a087940528b
ruff==0.1.11 \
--hash=sha256:09c415716884950080921dd6237767e52e227e397e2008e2bed410117679975b \
--hash=sha256:0f58948c6d212a6b8d41cd59e349751018797ce1727f961c2fa755ad6208ba45 \
--hash=sha256:190a566c8f766c37074d99640cd9ca3da11d8deae2deae7c9505e68a4a30f740 \
--hash=sha256:231d8fb11b2cc7c0366a326a66dafc6ad449d7fcdbc268497ee47e1334f66f77 \
--hash=sha256:4b077ce83f47dd6bea1991af08b140e8b8339f0ba8cb9b7a484c30ebab18a23f \
--hash=sha256:5b25093dad3b055667730a9b491129c42d45e11cdb7043b702e97125bcec48a1 \
--hash=sha256:6464289bd67b2344d2a5d9158d5eb81025258f169e69a46b741b396ffb0cda95 \
--hash=sha256:934832f6ed9b34a7d5feea58972635c2039c7a3b434fe5ba2ce015064cb6e955 \
--hash=sha256:97ce4d752f964ba559c7023a86e5f8e97f026d511e48013987623915431c7ea9 \
--hash=sha256:9b8f397902f92bc2e70fb6bebfa2139008dc72ae5177e66c383fa5426cb0bf2c \
--hash=sha256:9bd4025b9c5b429a48280785a2b71d479798a69f5c2919e7d274c5f4b32c3607 \
--hash=sha256:a7f772696b4cdc0a3b2e527fc3c7ccc41cdcb98f5c80fdd4f2b8c50eb1458196 \
--hash=sha256:c4a88efecec23c37b11076fe676e15c6cdb1271a38f2b415e381e87fe4517f18 \
--hash=sha256:e1ad00662305dcb1e987f5ec214d31f7d6a062cae3e74c1cbccef15afd96611d \
--hash=sha256:ea0d3e950e394c4b332bcdd112aa566010a9f9c95814844a7468325290aabfd9 \
--hash=sha256:eb85ee287b11f901037a6683b2374bb0ec82928c5cbc984f575d0437979c521a \
--hash=sha256:f9d4d88cb6eeb4dfe20f9f0519bd2eaba8119bde87c3d5065c541dbae2b5a2cb
# via ruff-lsp (pyproject.toml)
typing-extensions==4.7.1 \
--hash=sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36 \
Expand Down
46 changes: 36 additions & 10 deletions ruff_lsp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,19 @@ class LegacyFix(TypedDict):
TEXT_DOCUMENT_CODE_ACTION,
CodeActionOptions(
code_action_kinds=[
# Standard code action kinds.
CodeActionKind.QuickFix,
CodeActionKind.SourceFixAll,
CodeActionKind.SourceOrganizeImports,
# Standard code action kinds, scoped to Ruff.
f"{CodeActionKind.SourceFixAll.value}.ruff",
f"{CodeActionKind.SourceOrganizeImports.value}.ruff",
# Notebook code action kinds.
f"notebook.{CodeActionKind.SourceFixAll.value}",
f"notebook.{CodeActionKind.SourceOrganizeImports.value}",
# Notebook code action kinds, scoped to Ruff.
f"notebook.{CodeActionKind.SourceFixAll.value}.ruff",
f"notebook.{CodeActionKind.SourceOrganizeImports.value}.ruff",
],
resolve_provider=True,
),
Expand All @@ -821,26 +829,44 @@ async def code_action(params: CodeActionParams) -> list[CodeAction] | None:
first, and if there's no cell with the given URI, it will fallback to the text
document.
"""

def document(uri: str, kind: str) -> Document:
if kind in (
# For `notebook`-scoped actions, use the Notebook Document instead of
# the cell, despite being passed the URI of the first cell.
# See: https://github.com/microsoft/vscode/issues/193120
f"notebook.{CodeActionKind.SourceFixAll.value}",
f"notebook.{CodeActionKind.SourceOrganizeImports.value}",
f"notebook.{CodeActionKind.SourceFixAll.value}.ruff",
f"notebook.{CodeActionKind.SourceOrganizeImports.value}.ruff",
):
return Document.from_uri(uri)
else:
return Document.from_cell_or_text_uri(uri)

document_path = _uri_to_fs_path(params.text_document.uri)
if utils.is_stdlib_file(document_path):
# Don't format standard library files.
# Publishing empty list clears the entry.
return None

settings = _get_settings_by_document(document_path)

if settings["organizeImports"]:
# Generate the "Ruff: Organize Imports" edit
for kind in (
CodeActionKind.SourceOrganizeImports,
f"{CodeActionKind.SourceOrganizeImports.value}.ruff",
f"notebook.{CodeActionKind.SourceOrganizeImports.value}",
f"notebook.{CodeActionKind.SourceOrganizeImports.value}.ruff",
):
if (
params.context.only
and len(params.context.only) == 1
and kind in params.context.only
):
workspace_edit = await _fix_document_impl(
Document.from_cell_or_text_uri(params.text_document.uri),
document(params.text_document.uri, kind),
only=["I001", "I002"],
)
if workspace_edit:
Expand All @@ -861,14 +887,16 @@ async def code_action(params: CodeActionParams) -> list[CodeAction] | None:
for kind in (
CodeActionKind.SourceFixAll,
f"{CodeActionKind.SourceFixAll.value}.ruff",
f"notebook.{CodeActionKind.SourceFixAll.value}",
f"notebook.{CodeActionKind.SourceFixAll.value}.ruff",
):
if (
params.context.only
and len(params.context.only) == 1
and kind in params.context.only
):
workspace_edit = await _fix_document_impl(
Document.from_cell_or_text_uri(params.text_document.uri)
document(params.text_document.uri, kind)
)
if workspace_edit:
return [
Expand Down Expand Up @@ -1063,17 +1091,14 @@ async def resolve_code_action(params: CodeAction) -> CodeAction:

settings = _get_settings_by_document(document.path)

if settings["organizeImports"] and params.kind in (
CodeActionKind.SourceOrganizeImports,
f"{CodeActionKind.SourceOrganizeImports.value}.ruff",
if (
settings["organizeImports"]
and params.kind == CodeActionKind.SourceOrganizeImports
):
# Generate the "Ruff: Organize Imports" edit
params.edit = await _fix_document_impl(document, only=["I001", "I002"])

elif settings["fixAll"] and params.kind in (
CodeActionKind.SourceFixAll,
f"{CodeActionKind.SourceFixAll.value}.ruff",
):
elif settings["fixAll"] and params.kind == CodeActionKind.SourceFixAll:
# Generate the "Ruff: Fix All" edit.
params.edit = await _fix_document_impl(document)

Expand Down Expand Up @@ -1125,7 +1150,8 @@ async def apply_format(arguments: tuple[TextDocument]):
async def format_document(params: DocumentFormattingParams) -> list[TextEdit] | None:
# For a Jupyter Notebook, this request can only format a single cell as the
# request itself can only act on a text document. A cell in a Notebook is
# represented as a text document.
# represented as a text document. The "Notebook: Format notebook" action calls
# this request for every cell.
document = Document.from_cell_or_text_uri(params.text_document.uri)

result = await _run_format_on_document(document)
Expand Down

0 comments on commit 1c7c119

Please sign in to comment.