Skip to content

Commit

Permalink
Settings: Fix completion values (#348)
Browse files Browse the repository at this point in the history
The root cause was that text manipulation was reordered in a wrong way:
JSON-encoded string was converted to snippet-field-content-encoded
string first, but then it was treated as a simply JSON-encoded string
again. Namely, stripping curly brackets away _after_ encoding them
as \\} broke cursor things in a weird ways.

Used pretty printing just because it looks better. But it required extra
whitespace stripping: both outside and inside stripped
brackets/braces.

Also changed variable name from `encoded` to `content` in fmt, so they
can never be accidentally reordered again.

Fixes #347
  • Loading branch information
ratijas authored and FichteFoll committed Feb 26, 2022
1 parent ae1fb8a commit bfa509b
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions plugins/settings/known_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,14 @@ def key_completions(self, view, prefix, point):

return completions

@staticmethod
def _encode_snippet_field_default_content(content: str) -> str:
"""Escape string for snippet's default content context."""
return content \
.replace("\\", "\\\\") \
.replace("$", "\\$") \
.replace("}", "\\}")

@staticmethod
def _key_snippet(key, value, bol="", eol=",\n"):
"""Create snippet with default value depending on type.
Expand All @@ -450,19 +458,16 @@ def _key_snippet(key, value, bol="", eol=",\n"):
Returns:
string: the contents field to insert into completions entry
"""
encoded = sublime.encode_value(value)
encoded = encoded.replace("\\", "\\\\") # escape snippet markers
encoded = encoded.replace("$", "\\$")
encoded = encoded.replace("}", "\\}")
encoded = sublime.encode_value(value, pretty=True).strip()

if isinstance(value, str):
# create the snippet for json strings and exclude quotation marks
# from the input field {1:}
#
# "key": "value"
#
fmt = '{bol}"{key}": "${{1:{encoded}}}"{eol}'
encoded = encoded[1:-1] # strip quotation
fmt = '{bol}"{key}": "${{1:{content}}}"{eol}'
encoded = encoded[1:-1]
elif isinstance(value, list):
# create the snippet for json lists and exclude brackets
# from the input field {1:}
Expand All @@ -472,8 +477,8 @@ def _key_snippet(key, value, bol="", eol=",\n"):
# value
# ]
#
fmt = '{bol}"{key}":\n[\n\t${{1:{encoded}}}\n]{eol}'
encoded = encoded[1:-1] # strip brackets
fmt = '{bol}"{key}":\n[\n\t${{1:{content}}}\n]{eol}'
encoded = encoded[1:-1].strip()
elif isinstance(value, dict):
# create the snippet for json dictionaries braces
# from the input field {1:}
Expand All @@ -483,11 +488,13 @@ def _key_snippet(key, value, bol="", eol=",\n"):
# value
# }
#
fmt = '{bol}"{key}":\n{{\n\t${{1:{encoded}}}\n}}{eol}'
encoded = encoded[1:-1] # strip braces
fmt = '{bol}"{key}":\n{{\n\t${{1:{content}}}\n}}{eol}'
encoded = encoded[1:-1].strip()
else:
fmt = '{bol}"{key}": ${{1:{encoded}}}{eol}'
return fmt.format(**locals())
fmt = '{bol}"{key}": ${{1:{content}}}{eol}'
# `encoded` is like a JSON string, but with quotes/braces/brackets stripped.
content = KnownSettings._encode_snippet_field_default_content(encoded)
return fmt.format(key=key, content=content, bol=bol, eol=eol)

def value_completions(self, view, prefix, point):
"""Create a list with completions for all known settings values.
Expand Down

0 comments on commit bfa509b

Please sign in to comment.