Sublime Forum

expandSelectionTo string

#1

Would it be possible to add string as an option for the feature parameter of expandSelectionTo? It would function similar to brackets, selecting the text between the quotes. This makes it easy to replace the content of string literals without having to manually select everything.

0 Likes

Whole variable content select
#2

You get a similar feature by pressing CTRL+SHIFT+SPACE BAR inside quoted strings. Does that help?

0 Likes

#3

Ah, I guess you mean “programmatically”.

0 Likes

#4

ctrl+shift+space class calls expandSelectionTo scope, which has two differences compared to the proposed addition:

  1. it selects the quotes as well, which means you can’t just start typing to replace the string
  2. if your cursor happens to be in a subscope inside the string, say a character literal, it will only select that as opposed to the entire string.
0 Likes

#5

+1

0 Likes

#6

Unfortunately, sublimator’s code isn’t entirely bugfree. For instance, in the test string “This doesn’t work”, selectString fails if the cursor is positioned anywhere after the single quote. This problem isn’t easy. Consider something like
foo("lorem ipsum ’ dolor ", sit, ‘amet’),
with the cursor positioned in dolor. We know the correct behaviour would be to select lorem…dolor, but to the algorithm dolor…sit is equally plausible since it has no awareness of scope. Perhaps this problem could be solved by also taking information from the syntax highlighter into account.

0 Likes

#7

Here’s a first stab at using syntax info for doing this. The obvious downside is that it doesn’t work in plain text files or syntax schemes that don’t adhere to the convention of naming strings string.quoted.double/single. Still, it should work for most languages (tried C, C++, C#, Java, Ruby, Python, Haskell and PHP).

import re
import sublime, sublimeplugin

class QuoteSelectCommand(sublimeplugin.TextCommand):
    def run(self, view, args):
        for region in view.sel():
            syntax = view.syntaxName(region.begin())
            if re.match(".*string.quoted.double", syntax): self.select(view, region, '"')
            if re.match(".*string.quoted.single", syntax): self.select(view, region, "'")
    
    def select(self, view, region, char):
        begin = region.begin() - 1
        end = region.begin()
        while view.substr(begin) != char or view.substr(begin - 1) == '\\': begin -= 1
        while view.substr(end) != char or view.substr(end - 1) == '\\': end += 1
        view.sel().subtract(region)
        view.sel().add(sublime.Region(begin + 1, end))

If anyone finds any cases where it doesn’t work, please let me know.

0 Likes