Skip to content

Allow certain comments to be case-insensitive for toggling #6001

Closed
@mataha

Description

Problem description

In some programming languages, the keywords responsible for commenting out the code are case-insensitive, which conflicts with comment specification in Comments.tmPreferences and, consequently, produces unexpected results when executing toggle_comment.

Take, for instance, the following Batch code:

REM call :define_assertion_macro assert_eq equ
REM %$assert_eq% 1 1
REM echo Exit code: %ERRORLEVEL%

Expected:

call :define_assertion_macro assert equ
%$assert_eq% 1 1
echo Exit code: %ERRORLEVEL%

Actual:

rem REM call :define_assertion_macro assert equ
rem REM %$assert_eq% 1 1
rem REM echo Exit code: %ERRORLEVEL%

Preferred solution

Allow specifying certain comments as case-insensitive by introducing the following property in Comments.tmPreferences:

<dict>
  <key>name</key>
  <string>TM_COMMENT_CASE_INSENSITIVE</string>
  <key>value</key>
  <string>yes</string>
</dict>

As already is with TM_COMMENT_DISABLE_INDENT, that would only take effect with value set to yes - the default behavior would not change.

Alternatives

I can't see any long-term alternatives.

Additional Information

Feel free to use the following patch as you deem fit:

diff --git a/Default/comment.py b/Default/comment.py
index de85ee0d2c3b..b29b373edd38 100644
--- a/Default/comment.py
+++ b/Default/comment.py
@@ -3,6 +3,13 @@ import sublime
 import sublime_plugin
 
 
+def compare(a: str, b: str, case_insensitive: bool = False) -> bool:
+    if case_insensitive:
+        return a.casefold() == b.casefold()
+
+    return a == b
+
+
 def advance_to_first_non_white_space_on_line(view, pt):
     while True:
         c = view.substr(pt)
@@ -42,14 +49,33 @@ def build_comment_data(view, pt):
     for suffix in suffixes:
         start = all_vars.get("TM_COMMENT_START" + suffix)
         end = all_vars.get("TM_COMMENT_END" + suffix)
+        case_insensitive = all_vars.get("TM_COMMENT_CASE_INSENSITIVE" + suffix)
         disable_indent = all_vars.get("TM_COMMENT_DISABLE_INDENT" + suffix)
 
         if start and end:
-            block_comments.append((start, end, disable_indent == 'yes'))
-            block_comments.append((start.strip(), end.strip(), disable_indent == 'yes'))
+            block_comments.append((
+                start,
+                end,
+                case_insensitive == 'yes',
+                disable_indent == 'yes'
+            ))
+            block_comments.append((
+                start.strip(),
+                end.strip(),
+                case_insensitive == 'yes',
+                disable_indent == 'yes'
+            ))
         elif start:
-            line_comments.append((start, disable_indent == 'yes'))
-            line_comments.append((start.strip(), disable_indent == 'yes'))
+            line_comments.append((
+                start,
+                case_insensitive == 'yes',
+                disable_indent == 'yes'
+            ))
+            line_comments.append((
+                start.strip(),
+                case_insensitive == 'yes',
+                disable_indent == 'yes'
+            ))
 
     return (line_comments, block_comments)
 
@@ -122,11 +148,19 @@ class ToggleCommentCommand(sublime_plugin.TextCommand):
         block_comments = build_comment_data(view, whole_region.begin())[1]
 
         for c in block_comments:
-            (start, end, disable_indent) = c
-            start_region = sublime.Region(whole_region.begin(), whole_region.begin() + len(start))
-            end_region = sublime.Region(whole_region.end() - len(end), whole_region.end())
-
-            if view.substr(start_region) == start and view.substr(end_region) == end:
+            (start, end, case_insensitive, _) = c
+
+            start_region = sublime.Region(
+                whole_region.begin(),
+                whole_region.begin() + len(start)
+            )
+            end_region = sublime.Region(
+                whole_region.end() - len(end),
+                whole_region.end()
+            )
+
+            if (compare(view.substr(start_region), start, case_insensitive)
+                and compare(view.substr(end_region), end, case_insensitive)):
                 # It's faster to erase the start region first
                 view.erase(edit, start_region)
 
@@ -152,9 +186,9 @@ class ToggleCommentCommand(sublime_plugin.TextCommand):
         regions = []
         for pos in start_positions:
             found = False
-            for (start, _) in line_comments:
+            for (start, case_insensitive, _) in line_comments:
                 comment_region = sublime.Region(pos, pos + len(start))
-                if view.substr(comment_region) == start:
+                if compare(view.substr(comment_region), start, case_insensitive):
                     found = True
                     regions.append(comment_region)
                     break
@@ -176,7 +210,7 @@ class ToggleCommentCommand(sublime_plugin.TextCommand):
         if len(comment_data[1]) <= variant:
             return False
 
-        (start, end, disable_indent) = comment_data[1][variant]
+        (start, end, _, disable_indent) = comment_data[1][variant]
 
         if enable_indent and not disable_indent:
             min_indent_lines(view, [region])
@@ -223,7 +257,7 @@ class ToggleCommentCommand(sublime_plugin.TextCommand):
 
             return False
 
-        (start, disable_indent) = comment_data[0][variant]
+        (start, _, disable_indent) = comment_data[0][variant]
 
         if not disable_indent:
             min_indent_lines(view, lines)

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions