Home Download Buy Blog Forum Support

Bounded Quick Add Next

Bounded Quick Add Next

Postby Nilium on Wed Jan 30, 2013 1:18 am

This is a quick little plugin you can drop in your user package and use in addition to ⌘D and ⌘K⌘D (where skip_last is true in the command arguments). Basically, it searches for the current word, albeit bounded by \b in the regex (that is, word boundaries - so it won't work for everything [for example, searching for #/ using this plugin will not work since # and / are both word boundaries themselves, so consider using a different key instead of replacing ⌘D and such]).

It's handy if you're a terrible human being and use single-letter variable names other than [u-z] (because there's really no better way to refer to texture coordinates and vector components than with UVW and XYZ), which ⌘D will punish you for doing by finding every instance of that character. So, your best bet is to just not be an absolutely loathsome person who uses single letter variables (like all you horrible web developers do), but if you happen to be someone the entire world should despise because you absolutely cannot resist the allure of single letter variables like the absolutely awful depth-spawn that you might be, then this plugin is probably for you.

It's also handy if you have variable names that share words, like event and event_name and event_id, in which case ⌘D will unintentionally hate you and you're not an awful person, just unlucky. In those cases, it's probably fairly useful, though chances are you could ⌘K⌘D around the false positives without a lot of problems.

This came up on IRC (as usual) and it's something I'd experienced before, so I figured I might as well write a plugin for it. Did a cursory search and found nobody else had done it either, but I got lazy, so it wasn't thorough. Probably been solved before.

So, drop this in your user package if you think you might need it for something:
Code: Select all
# bounded_grab_next.py
import sublime, sublime_plugin, re

class BoundedGrabNextCommand(sublime_plugin.TextCommand):
  def __init__(self, p):
    super(BoundedGrabNextCommand, self).__init__(p)
    self._last_word = None
    self._last_regex = None
  #/__init__

  def run(self, edit, skip_last = False):
    last_selection = None
    view = self.view

    selections = view.sel()
    last_selection = selections[-1]

    # If the last selection is empty, expand to the current word. In other
    # words, just do the usual Cmd+D operation.
    if last_selection.a == last_selection.b:
      view.window().run_command('find_under_expand')
      return
    #/if

    regex = None
    word = view.substr(last_selection)
    if self._last_word == word:
      regex = self._last_regex
    else:
      regex = "\\b{0}\\b".format(re.escape(word))
    #/if

    if skip_last:
      selections.subtract(last_selection)
    #/if

    last_point = max(last_selection.a, last_selection.b)
    next_find = view.find(regex, last_point)
    if next_find is None:
      next_find = view.find(regex, 0)

      while next_find and selections.contains(next_find):
        next_find = view.find(regex, next_find.b)
      #/while
    #/if

    if next_find:
      selections.add(next_find)
    #/if

    self._last_word = word
    self._last_regex = regex
  #/run
#/BoundedGrabNextCommand


The command takes a single argument, skip_last, which behaves mostly the same as ⌘K⌘D. I rarely find this useful, and in this case the chance of a false positive is a bit lower than normal, so you may not need it.

You'll want to set up a keybinding for it as well. Here's an example that replaces the "Use Selection for Find" and "Use Selection for Replace" bindings because I never use those. Adjust as necessary, obviously.

Code: Select all
[
  { "command": "bounded_grab_next", "args": {"skip_last": false}, "keys": ["super+e"]},
  { "command": "bounded_grab_next", "args": {"skip_last": true}, "keys": ["super+shift+e"]}
]


So, have fun.
Nilium
 
Posts: 53
Joined: Fri May 25, 2012 11:22 pm

Re: Bounded Quick Add Next

Postby highend on Wed Jan 30, 2013 9:10 am

I tried it with ST 3 (Build 3007) and used ctrl+e and ctrl+shift+e as the shortcuts (Windows system).

I get this in the console when I use ctrl+e:
Code: Select all
Traceback (most recent call last):
  File "D:\Users\Highend\Downloads\Sublime Text 3\sublime_plugin.py", line 376, in run_
    return self.run(edit, **args)
  File "D:\Users\Highend\Downloads\Sublime Text 3\Data\Packages\User\BoundedQuickAddNext.py", line 16, in run
    last_selection = selections[-1]
  File "D:\Users\Highend\Downloads\Sublime Text 3\sublime.py", line 392, in __getitem__
    raise IndexError()
IndexError


Should it work with ST 3 or ST 2 only atm?
highend
 
Posts: 94
Joined: Fri Jan 20, 2012 2:47 pm

Re: Bounded Quick Add Next

Postby Nilium on Wed Jan 30, 2013 10:35 am

It's for Sublime Text 2. I don't plan to do anything for Sublime Text 3 until there's an official API reference.
Nilium
 
Posts: 53
Joined: Fri May 25, 2012 11:22 pm

Re: Bounded Quick Add Next

Postby urraka on Thu Jan 31, 2013 3:27 am

I added a small detail to the last part of the script:

Code: Select all
    if next_find:
      selections.add(next_find)
      view.show(next_find)
    #/if


This will scroll to the added selection when it's not visible.
urraka
 
Posts: 3
Joined: Thu Jan 31, 2013 3:20 am

Re: Bounded Quick Add Next

Postby Nilium on Thu Jan 31, 2013 4:02 am

That's a good idea.
Nilium
 
Posts: 53
Joined: Fri May 25, 2012 11:22 pm

Re: Bounded Quick Add Next

Postby adzenith on Tue Jul 30, 2013 4:02 pm

Note that if you start with an empty selection, then cmd+d (find_under_expand) will search by whole words automatically. If you start with a non-empty selection, then it will search for any instance of the text.
adzenith
 
Posts: 1215
Joined: Mon Oct 19, 2009 9:12 pm


Return to Plugin Announcements

Who is online

Users browsing this forum: No registered users and 6 guests