Skip to content

Commit

Permalink
Fix path completion when client doesn't support code snippets (#497)
Browse files Browse the repository at this point in the history
  • Loading branch information
i-aki-y committed Dec 12, 2023
1 parent 2a7d5b7 commit 14369f8
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
20 changes: 14 additions & 6 deletions pylsp/plugins/jedi_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def pylsp_completions(config, document, position):
include_params=include_params if c.type in ["class", "function"] else False,
resolve=resolve_eagerly,
resolve_label_or_snippet=(i < max_to_resolve),
snippet_support=snippet_support,
)
for i, c in enumerate(completions)
]
Expand All @@ -102,6 +103,7 @@ def pylsp_completions(config, document, position):
include_params=False,
resolve=resolve_eagerly,
resolve_label_or_snippet=(i < max_to_resolve),
snippet_support=snippet_support,
)
completion_dict["kind"] = lsp.CompletionItemKind.TypeParameter
completion_dict["label"] += " object"
Expand All @@ -116,6 +118,7 @@ def pylsp_completions(config, document, position):
include_params=False,
resolve=resolve_eagerly,
resolve_label_or_snippet=(i < max_to_resolve),
snippet_support=snippet_support,
)
completion_dict["kind"] = lsp.CompletionItemKind.TypeParameter
completion_dict["label"] += " object"
Expand Down Expand Up @@ -226,6 +229,7 @@ def _format_completion(
include_params=True,
resolve=False,
resolve_label_or_snippet=False,
snippet_support=False,
):
completion = {
"label": _label(d, resolve_label_or_snippet),
Expand All @@ -240,16 +244,20 @@ def _format_completion(
# Adjustments for file completions
if d.type == "path":
path = os.path.normpath(d.name)
path = path.replace("\\", "\\\\")
path = path.replace("/", "\\/")

# If the completion ends with os.sep, it means it's a directory. So we add an escaped os.sep
# at the end to ease additional file completions.
# If the completion ends with os.sep, it means it's a directory. So we add os.sep at the end
# to ease additional file completions.
if d.name.endswith(os.sep):
if os.name == "nt":
path = path + "\\\\"
path = path + "\\"
else:
path = path + "\\/"
path = path + "/"

# Escape to prevent conflicts with the code snippets grammer
# See also https://github.com/python-lsp/python-lsp-server/issues/373
if snippet_support:
path = path.replace("\\", "\\\\")
path = path.replace("/", "\\/")

completion["insertText"] = path

Expand Down
17 changes: 13 additions & 4 deletions test/plugins/test_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,18 @@ def test_file_completions(workspace, tmpdir):
# Check completions
assert len(completions) == 2
assert [c["kind"] == lsp.CompletionItemKind.File for c in completions]
assert (
completions[0]["insertText"] == ("bar" + "\\\\")
if os.name == "nt"
else ("bar" + "\\/")
assert completions[0]["insertText"] == (
("bar" + "\\") if os.name == "nt" else ("bar" + "/")
)
assert completions[1]["insertText"] == 'foo.txt"'

# When snippets are supported, ensure that path separators are escaped.
support_snippet = {
"textDocument": {"completion": {"completionItem": {"snippetSupport": True}}}
}
doc._config.capabilities.update(support_snippet)
completions = pylsp_jedi_completions(doc._config, doc, com_position)
assert completions[0]["insertText"] == (
("bar" + "\\\\") if os.name == "nt" else ("bar" + "\\/")
)
assert completions[1]["insertText"] == 'foo.txt"'

0 comments on commit 14369f8

Please sign in to comment.