Basj
Basj

Reputation: 46401

Shortcut to move to a specific part of a text file

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:

but this requires too many actions.

How to do that in a single key shortcut?

Upvotes: 1

Views: 721

Answers (2)

Basj
Basj

Reputation: 46401

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!

Upvotes: 0

mattst
mattst

Reputation: 13950

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.]

Upvotes: 1

Related Questions