Skip to content

Commit

Permalink
Use --range, extract _format_document_impl
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Feb 2, 2024
1 parent b1044ed commit 49b9db7
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 46 deletions.
77 changes: 38 additions & 39 deletions ruff_lsp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1215,14 +1215,41 @@ async def apply_format(arguments: tuple[TextDocument]):


@LSP_SERVER.feature(TEXT_DOCUMENT_FORMATTING)
async def format_document(
params: DocumentFormattingParams, range: Range | None = None
async def format_document(params: DocumentFormattingParams) -> list[TextEdit] | None:
return await _format_document_impl(params, None)


@LSP_SERVER.feature(
TEXT_DOCUMENT_RANGE_FORMATTING,
DocumentRangeFormattingRegistrationOptions(
document_selector=[
TextDocumentFilter_Type1(language="python", scheme="file"),
TextDocumentFilter_Type1(language="python", scheme="untitled"),
],
ranges_support=False,
work_done_progress=False,
),
)
async def format_document_range(
params: DocumentRangeFormattingParams,
) -> list[TextEdit] | None:
return await _format_document_impl(
DocumentFormattingParams(
params.text_document, params.options, params.work_done_token
),
params.range,
)


async def _format_document_impl(
params: DocumentFormattingParams, range: Range | None
) -> 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. The "Notebook: Format notebook" action calls
# this request for every cell.
document = Document.from_cell_or_text_uri(params.text_document.uri)

settings = _get_settings_by_document(document.path)

# We don't support range formatting of notebooks yet but VS Code
Expand Down Expand Up @@ -1253,28 +1280,6 @@ async def format_document(
)


@LSP_SERVER.feature(
TEXT_DOCUMENT_RANGE_FORMATTING,
DocumentRangeFormattingRegistrationOptions(
document_selector=[
TextDocumentFilter_Type1(language="python", scheme="file"),
TextDocumentFilter_Type1(language="python", scheme="untitled"),
],
ranges_support=False,
work_done_progress=False,
),
)
async def format_document_range(
params: DocumentRangeFormattingParams,
) -> list[TextEdit] | None:
return await format_document(
DocumentFormattingParams(
params.text_document, params.options, params.work_done_token
),
params.range,
)


async def _fix_document_impl(
document: Document,
settings: WorkspaceSettings,
Expand Down Expand Up @@ -1913,23 +1918,17 @@ async def _run_format_on_document(
]

if format_range:
# Convert the start and end to character offsets instead of line:column
lines = document.source.splitlines(True)
codec = PositionCodec(PositionEncodingKind.Utf16)
range = codec.range_from_client_units(lines, format_range)
start = format_range.start.character
end = format_range.end.character

for index, line in enumerate(lines):
if index < range.start.line:
start += len(line)

if index < range.end.line:
end += len(line)
else:
break
format_range = codec.range_from_client_units(
document.source.splitlines(True), format_range
)

argv.extend(["--range-start", str(start), "--range-end", str(end)])
argv.extend(
[
"--range",
f"{format_range.start.line + 1}:{format_range.start.character + 1}-{format_range.end.line + 1}:{format_range.end.character + 1}", # noqa: E501
]
)

for arg in settings.get("format", {}).get("args", []):
if arg in UNSUPPORTED_FORMAT_ARGS:
Expand Down
11 changes: 4 additions & 7 deletions tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,7 @@ async def test_format_range(tmp_path, ruff_version: Version):
print ("Not formatted")
"""

expected = """x = 1
print("Formatted")
print ("Not formatted")
"""
expected = """print("Formatted")\n"""

test_file = tmp_path.joinpath("main.py")
test_file.write_text(original)
Expand Down Expand Up @@ -128,3 +122,6 @@ async def test_format_range(tmp_path, ruff_version: Version):
original_source=document.source, fixed_source=result.stdout.decode("utf-8")
)
assert edit.new_text == expected
assert edit.range == Range(
start=Position(line=3, character=0), end=Position(line=5, character=0)
)

0 comments on commit 49b9db7

Please sign in to comment.