Skip to content

Commit

Permalink
!breaking - simplify code, but remove ConvertToRegularString
Browse files Browse the repository at this point in the history
  • Loading branch information
predragnikolic committed Apr 12, 2023
1 parent 79b84ff commit bae810d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 84 deletions.
17 changes: 11 additions & 6 deletions Default.sublime-keymap
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
[
{ "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{$0}"}, "context":
[
{"keys": ["{"], "command": "chain",
"args": {
"commands": [
{"command": "insert_snippet", "args": {"contents": "{$0}"}},
{"command": "convert_to_template_string"},
]
},
"context": [
{ "key": "setting.auto_match_enabled" },
{ "key": "selector", "operand": "source.js | source.jsx | source.ts | source.tsx | text.html.ngx | text.html.svelte | text.html.vue" },
{ "key": "selection_empty", "match_all": true },
{ "key": "preceding_text", "operator": "not_regex_contains", "operand": "\\\\$", "match_all": true }
]
},
]
{ "key": "preceding_text", "operator": "not_regex_contains", "operand": "\\\\$", "match_all": true },
]}
]
85 changes: 7 additions & 78 deletions plugin.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
import re
from typing import List, Optional
import sublime
import sublime_plugin


class TextChangeListener(sublime_plugin.TextChangeListener):
def on_text_changed(self, changes: List[sublime.TextChange]):
if not self.buffer:
return
view = self.buffer.primary_view()
if not view:
return
for c in changes:
is_delete = not c.str
if c.str in ['$', '{', "{}"]:
sublime.set_timeout(lambda: view.run_command('convert_to_template_string'), 0)
if is_delete:
sublime.set_timeout(lambda: view.run_command('convert_to_regular_string'), 0)


class ConvertToTemplateString(sublime_plugin.TextCommand):
""" This command is guaranteed to executed when { is pressed """
def run(self, edit):
point = get_cursor_point(self.view)
if not point:
sel = self.view.sel()
if not sel:
return
point = sel[0].b
if not in_supported_file(self.view, point):
return None
regular_string_region = get_regular_string_region(self.view, point)
Expand All @@ -36,7 +20,7 @@ def run(self, edit):
return
first_quote = regular_string_region.begin()
last_quote = regular_string_region.end() - 1
are_quotes = is_regular_quote([self.view.substr(first_quote), self.view.substr(last_quote)])
are_quotes = is_regular_quote(self.view.substr(first_quote)) and is_regular_quote(self.view.substr(last_quote))
if not are_quotes:
return # sanity check, just to 100% make sure we are replacing quotes
if is_jsx_attribute(self.view, point) and not is_jsx_attribute_wrapped_with_curly_brackets(self.view, point):
Expand All @@ -52,40 +36,6 @@ def run(self, edit):
edit, sublime.Region(first_quote, first_quote + 1), '`')


class ConvertToRegularString(sublime_plugin.TextCommand):
def run(self, edit):
point = get_cursor_point(self.view)
if not point:
return
if not in_supported_file(self.view, point):
return None
backtick_string_region = get_backtick_string_region(self.view, point)
if not backtick_string_region:
return
backtick_text = self.view.substr(backtick_string_region)
# make sure that the string is surrounded with backticks
if not re.match(r"^`.+`$", backtick_text):
return
# if there are ${ that means it is still a template string
if '${' in backtick_text:
return
# else transform the template string to a regular string
first_quote = backtick_string_region.begin()
last_quote = backtick_string_region.end() - 1
# to transform to a regular string, the template string must be on the same line
first_row, _ = self.view.rowcol(first_quote)
last_row, _ = self.view.rowcol(last_quote)
if first_row != last_row:
return
are_backticks = is_backtick([self.view.substr(first_quote), self.view.substr(last_quote)])
if not are_backticks:
return # sanity check, just to 100% make sure we are replacing backticks
self.view.replace(
edit, sublime.Region(last_quote, last_quote + 1), "'")
self.view.replace(
edit, sublime.Region(first_quote, first_quote + 1), "'")


def is_jsx_attribute(view: sublime.View, point: int) -> bool:
return view.match_selector(point, "meta.jsx meta.tag.attributes")

Expand All @@ -94,34 +44,13 @@ def is_jsx_attribute_wrapped_with_curly_brackets(view: sublime.View, point: int)
return view.match_selector(point, "meta.jsx meta.tag.attributes meta.interpolation meta.string string.quoted")


def get_cursor_point(view: sublime.View) -> Optional[int]:
sel = view.sel()
if not sel:
return
return sel[0].b


def is_regular_quote(chars: List[str]) -> bool:
for c in chars:
if c not in ["'", '"']:
return False
return True


def is_backtick(chars: List[str]) -> bool:
for c in chars:
if c != "`":
return False
return True
def is_regular_quote(char: str) -> bool:
return char in ["'", '"']


def in_supported_file(view: sublime.View, point: int) -> bool:
return view.match_selector(point, "source.js | source.jsx | source.ts | source.tsx | text.html.ngx | text.html.svelte | text.html.vue")


def get_regular_string_region(view: sublime.View, point: int) -> Optional[sublime.Region]:
def get_regular_string_region(view: sublime.View, point: int):
return view.expand_to_scope(point, "string.quoted.single | string.quoted.double")


def get_backtick_string_region(view: sublime.View, point: int) -> Optional[sublime.Region]:
return view.expand_to_scope(point, "string.quoted.other")

0 comments on commit bae810d

Please sign in to comment.