1

I'd like to create a keyboard shortcut (such as CTRL+T) that automatically moves the cursor to the line after the occurence of a fixed text, such as &todo.

Example:

foo 
bar
&todo
fix bug #783
blah
blah2

Pressing CTRL+T would automatically move the cursor to the line beginning with fix ....

Currently I'm doing it like this:

  • CTRL F
  • enter &todo, ENTER
  • ESCAPE (closes the Search bottom panel)
  • HOME
  • DOWN ARROW (moves to next line)

but this requires too many actions.

How to do that in a single key shortcut?

mattst
  • 13,340
  • 4
  • 31
  • 43
Basj
  • 41,386
  • 99
  • 383
  • 673

2 Answers2

1

The best solution is it use a plugin to do that.

The plugin below does what you require. It will find the next occurrence of pattern (i.e. the &todo marker) below the current cursor position, move the cursor to the line below it, and centre that position in the window. If the pattern is not found below the current cursor position it will search again from the top of the buffer providing a wrap around feature.

Copy and paste the following Python code into a buffer and save it in your Sublime Text config User folder as GoToPattern.py.

import sublime
import sublime_plugin

class GotoPatternCommand(sublime_plugin.TextCommand):

    def run(self, edit, pattern):

        sels = self.view.sel()
        # Optional flags; see API.
        flags = sublime.LITERAL | sublime.IGNORECASE
        start_pos = sels[0].end() if len(sels) > 0 else 0
        find_pos = self.view.find(pattern, start_pos, flags)

        if not find_pos and start_pos > 0:
            # Begin search again at the top of the buffer; wrap around
            # feature, i.e. do not stop the search at the buffer's end.
            find_pos = self.view.find(pattern, 0, flags)

        if not find_pos:
            sublime.status_message("'{}' not found".format(pattern))
            return

        sels.clear()
        sels.add(find_pos.begin())
        self.view.show_at_center(find_pos.begin())
        row, col = self.view.rowcol(find_pos.begin())
        self.view.run_command("goto_line", {"line": row + 2})
        # Uncomment for: cursor to the end of the line.
        # self.view.run_command("move_to", {"to": "eol"})

Add key bindings:

// The pattern arg, i.e. "&todo", can be changed to anything you want
// and other key bindings can also be added to use different patterns.
{"keys": ["???"], "command": "goto_pattern", "args": {"pattern": "&todo"}}

Add a Command Palette entry to Default.sublime-commands if you want:

{"caption": "GoToPattern: &todo", "command": "goto_pattern", "args": {"pattern": "&todo"}},

These links may be useful to you ST v. 2 API and ST v. 3 API.

P.S. Did you know that Sublime Text has bookmarks? [Just in case you didn't.]

mattst
  • 13,340
  • 4
  • 31
  • 43
0

The accepted answer is really better and I'm finally using it.

For reference, here an old solution I used: first create a gototodo.py file in "C:\Users\User\AppData\Roaming\Sublime Text 2\Packages\User\" containing:

import sublime, sublime_plugin

class GototodoCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        contents = self.view.substr(sublime.Region(0, self.view.size()))  # https://stackoverflow.com/questions/20182008/sublime-text-3-api-get-all-text-from-a-file
        a = contents.find('&todo')
        cursors = self.view.sel()
        cursors.clear()
        location = sublime.Region(a, a)
        cursors.add(location)
        self.view.show_at_center(location)

        (row, col) = self.view.rowcol(self.view.sel()[0].begin())  # go to the next line
        self.view.run_command("goto_line", {"line": row+2})

Then add this in "C:\Users\User\AppData\Roaming\Sublime Text 2\Packages\User\Default (Windows).sublime-keymap":

{ "keys": ["ctrl+t"], "command": "gototodo" }

Done!

Basj
  • 41,386
  • 99
  • 383
  • 673
  • No need for `import subprocess`. Your plugin will only ever move the cursor to the first occurrence of "&todo". – mattst Mar 27 '19 at 17:07
  • Sublime Text version 3 has been stable for 5+ years and is almost certainly a much better choice than the very old version 2 which was last updated in 2013. Version 3 has been out of beta for several years and it is the default download on [SublimeText.com](https://www.sublimetext.com/3). – mattst Mar 27 '19 at 17:09
  • @mattst You're right about `subprocess`, I first included it because of something totally different (nearly another plugin), but you're right, it should be removed. I'll edit now. – Basj Mar 27 '19 at 22:48
  • @mattst About ST version: would this code here run perfectly on ST3 or would a few modifications be required here? – Basj Mar 27 '19 at 22:49
  • 1
    No modifications needed, it works fine, I tested it to make sure. Note that ST2 and ST3 can both be installed on the same computer while you make the transition from version 2 to 3. – mattst Mar 28 '19 at 12:28