Sublime Forum

Keybinding to 'find' a particular set of characters

#1

Hi All.

Hope you’re all well.

The functionality I want is to be able to jump (the cursor) to comments in my code. eg ctrl+f, ctrl+c (find comment) and the cursor would move from the beginning of the line (or somewhere else) to the next comment…

{
let this = somecode + some_othercode(); // What a load of gibberish
}

so on pressing ctrl+f, ctrl+c the cursor would jump to ‘//W…’ or more accurately ‘/’

Am guessing the easiest way, would be to KeyBind the find function, but how do I specify arguments to the find function using a KB? And also what is the correct syntax for using the find command (in a keybinding)?
I’ve tried looking at the default keybindings and round the web, but no joy.

(Ideally I’d like to spend more time on my current project than tweaking Sublime, but there in lies a quandary, if something is really customisable (good) one ends up spending loads of time customising it (bad). Drat!)

If someone could give me something I can just copy and paste, that’d be amazing.

Hooragh fo the Sublime forum and all that sail this particular ship !

Lozminda

Ps Have tried this

{ “keys”: [“ctrl+f”,“ctrl+c”], “command”: “find”, “args”: {“characters”: “//”}},

it doesn’t work…cheers

0 Likes

Find for a Macro
#2

I don’t think there’s a way to bind a key to find directly and have it execute the search for you; if you started the search yourself manually you could use the default binding to find the next match on that search term though.

On the whole that might not be the best way to go regardless. Using the find command in that way would interrupt your ability to search for other things while you’re working if you still want to navigate comments. Also, a search like / (or based on language, even //) may end you up in places where you don’t want to be, like on a mathematical division or inside of a string, etc.

One way to pull this off is with something like the following plugin (see this video if you’re unsure of how to apply a plugin):

import sublime
import sublime_plugin


class ScopeNavigateCommand(sublime_plugin.TextCommand):
    """
    Jump the selection in the file to the next or previous location of the
    given scope based on the current cursor location. The search direction is
    controlled by the forward argument, and will wrap around the ends of the
    buffer.
    """
    def run(self, edit, scope, forward=True):
        # Find the locations where this scope occurs; leave if none
        regions = self.view.find_by_selector(scope)
        if not regions:
            return

        # Get a starting point for our search, and where we should jump to if
        # there are no matches in the specified direction.
        point = self.view.sel()[0].b
        fallback = regions[-1] if not forward else regions[0]

        # Remove all selections.
        self.view.sel().clear()

        # Look in the given direction for the first match from the current
        # position; if one is found jump there.
        pick = lambda p: (point < p.a) if forward else (point > p.a)
        for pos in regions if forward else reversed(regions):
            if pick(pos):
                return self.jump(pos.a)

        # No matches in the search direction, so wrap around.
        self.jump(fallback.a)

    def jump(self, point):
        # Add in the given position as a selection and ensure that it's
        # visible.
        self.view.sel().add(sublime.Region(point))
        self.view.show(point, True)

This implements a new scope_navigate command that you can provide a scope to, and the cursor will jump to the next or previous (based on the argument you provide) instance of that scope, wrapping around as needed.

With this command, your key binding from above would be:

    { "keys": ["ctrl+f","ctrl+c"], "command": "scope_navigate", "args": {
        "scope": "comment",
        "forward": true
    }},

You can swap the true for false if you want to go the other way. You can also replace the scope as needed. For example, a scope of "string.quoted" would let you skip between all of the strings in your file.

Using scopes is also not language specific, so the same binding will jump you between comments in JavaScript as well as HTML, Python, etc.

4 Likes

#3

in case anyone wants something similar but restricted to the current line, a plugin I wrote may be useful: https://packagecontrol.io/packages/GotoEndOfLineOrScope
by default, it binds on End to go to the start of a comment, or the end of the line if the caret is already inside a comment or there is no comment on the line

1 Like

#4

Could you give me an exmaple of how I’d use that in a key binding pls ?
eg

{ “keys”: [“ctrl+f”,“ctrl+c”], “command”: “ move_to_end_of_line_or_before_specified_scope”, and now i’m stuck},

To OdatNurd, thanks for your help, I appreciate your efforts no end, but your solution is gonna take me too much time (as a noob, my chances of everything running smoothly first time seem slim) to implement. This solution seems more possible…

Thank you to you both !

0 Likes

#5

Finally got round to installing your plugin. Works perfectly (so far) marvellous !!

Thanks

0 Likes