Sublime Forum

Non-wraparound version of `find_under`?

#1

Hi, I’d like to be able to run a find_under command without wrapping around past the bottom of the file, and starting at the top again.

Any ideas on how to do this?

Nb: I’m happy to rewrite my own version of find_under. So I guess one of my questions also is: where do I find the implementation of find_under, so that I can copy and tweak it?

PS: find_under_prev has the opposite behavior: it doesn’t wrap around the top of the file. So if the source code were located, it seems like it would be easy to modify find_under_prev (i.e., simply change the direction).

Thanks!

0 Likes

#2

I believe that find_under is implemented in the core, so it’s code is not readily available for tweaking. As such if you wanted to have a version that works different, you’d have to implement it from scratch.

With that said, find_under and find_under_prev both seem to respect the Wrap setting in the Find panel, so turning that off may solve the problem for you. Note however that for me both commands either wrap or don’t based on the setting, so if you’re seeing different behaviour between the two of them, there may be a package already in place that’s changing things a little bit.

0 Likes

#3

I’m sorry. I had confused find_under with find_under_expand. As you say, both find_under and find_under_prev obey the wrap mode set in the find panel. But find_under_expand does not, for some reason.

Using find_under and find_under_prev as primitives, I was able to write my own wrap-settings-respecting version of find_under_expand.

I copy-paste here in case anyone has the same issue.

def copy_regions(view):
    regions = view.sel()
    copy = []
    for r in regions:
        copy.append(sublime.Region(r.a, r.b))
    return copy, regions

class NoWrapFindUnderExpandCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        def has_proper_start(a, b):
            return min(a, b) == 0 or view.substr(min(a, b) - 1) not in alphanumeric

        def has_proper_end(a, b):
            return view.size() == max(a, b) or view.substr(max(a, b)) not in alphanumeric

        def is_standalone_word(a, b):
            if not has_proper_start(a, b):
                return False
            if not has_proper_end(a, b):
                return False
            return all(c in alphanumeric for c in view.substr(sublime.Region(a, b)))

        alphanumeric = string.ascii_letters + '_' + string.digits
        view = self.view
        copy, regions = copy_regions(view)
        if len(copy) > 0:
            a, b = copy[-1].a, copy[-1].b
        if len(copy) == 1 and a == b:
            if view.substr(a - 1) not in alphanumeric:
                copy[0].a = a + 1
                copy[0].b = b + 1
            regions.clear()
            regions.add_all(copy)
            view.window().run_command('find_under_prev')
            return
        if len(copy) > 0:
            regions.clear()
            regions.add(sublime.Region(a, b))
            seek_standalone_word = is_standalone_word(a, b)
            curx, cury = view.viewport_position()
            while True:
                old_a = view.sel()[-1].a
                view.window().run_command('find_under')
                if old_a == view.sel()[-1].a:
                    view.set_viewport_position((curx, cury))
                    drop_last_selection(view)
                    break
                last = view.sel()[-1]
                if not seek_standalone_word or is_standalone_word(last.a, last.b):
                    break
        view.sel().add_all(copy)

EDIT: Sorry, my initial code was totally buggy… the above should at least be moderately nearer to the mark.

0 Likes

#4

I am now wondering if this behavior could be modified by passing an option to find_under, find_under_prev. Something like

view.window().run_command('find_under', {'wrap': False})

to overwrite the setting that was last used in the find panel.

While we’re on the topic: Is there an official source of documentation for which options are available for a given command?

0 Likes

#5

Not at the moment; Will has mentioned that creating documentation for the internal commands is something that is on the radar so it is on the way (though we don’t know when it will arrive).

1 Like