Sublime Forum

Key shortcut based on time between keys

#1

is it possible to detect and act on a chain of key presses that are sensitive to the time between keystrokes?

Something analogous to the double-click event for a mouse where the threshold time between clicks changes behaviour?

I’d like to emulate the behaviour of Brief, where the “Home” key moves to the start of the line on a single tap, to the first line on the page in response to a double tap, and to the first line in the file in response to a triple tap, as long as you tap quickly enough. “End” had similar behaviour.

I think you could make “Home” and “End” context sensitive in that:

  • “Home” in the middle of a line goes to the start of the line
  • “Home” pressed at the start of the line goes to the start of the first line on the page
  • “Home” pressed at the start of the first line on the page goes to the start of the first line in the file

but I’d prefer to be able to tap in a way that was consistent irrespective of the context.

0 Likes

#2

Someone can correct me on this one, but as of today, I don’t think this is possible. Taking Build 4116 (current dev), the single/double/triple clicks only apply to mouse button clicks (through which you can configure different commands to run in mouse map files). Sublime Text 4 also adds the ability to chain modifier keys i.e. different commands can be run when you single/double/triple press ctrl/shift/alt etc. But that’s about it honestly

0 Likes

#3

I almost forgot

I think you could make “Home” and “End” context sensitive in that:

  • “Home” in the middle of a line goes to the start of the line
  • “Home” pressed at the start of the line goes to the start of the first line on the page
  • “Home” pressed at the start of the first line on the page goes to the start of the first line in the file

I am pretty sure this at least is doable via a custom plugin. It will just take someone who is willing to put a bit of effort to write it.

0 Likes

#4

Here is a proof of concept plugin that implements your second part.

import sublime
import sublime_plugin

class HomeTravelCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        cur_pos = self.view.sel()[0].begin()
        cur_line_region = self.view.line(cur_pos)
        cur_line_begin = cur_line_region.begin()
        visible_region_begin = self.view.visible_region().begin()

        # If the cursor is somewhere between a line, travel to the start.
        if (cur_pos != cur_line_begin):
            self.view.sel().clear()
            self.view.sel().add(sublime.Region(cur_line_begin, cur_line_begin))

        # If the cursor is already at the start, then just go to the start of the
        # visible region. If the file is small such that the visible region takes
        # up the entire file content region, then it will just travel to the start 
        # of the file.
        if (cur_pos != cur_line_begin) and (cur_line_begin != 0):
            self.view.sel().clear()
            self.view.sel().add(sublime.Region(visible_region_begin, visible_region_begin))

        # If the cursor is at the start of the line and visible region, go to
        # the start of the file.
        if (cur_pos == cur_line_begin == visible_region_begin):
            self.view.sel().clear()
            self.view.sel().add(sublime.Region(0, 0))
            self.view.show(0)

And a sample binding

{
    "keys": ["home"],
    "command": "home_travel",
},

An EndTravel command can be made similarly thus. I’ll leave that upto to the interested readers as an exercise.

0 Likes

#5

This is extremely kind - I’ll fire this up when I’m back at my desk.

0 Likes

#6

With a few tweaks for my particular use, this works a treat, thanks.

As a clue to the functions I’m after, I’ve been recording macros and looking at the source as a pointer to the function I’m after; is there a naming rule I can apply to the function name the macro attempts to apply - “my_test_command” -and the function name I should refer to in the plug-in.

It seems to be PascalCase so “MyTest” in that example?

0 Likes

#7

The rule is that SomeCamelCaseName becomes some_camel_case_name when it’s converted from a class name to a command name. Also, the _command suffix (if there would be one) is dropped.

So HomeTravel and HomeTravelCommand both turn into home_travel ; the addition of the Command on the class name is optional and there to make it easier to navigate plugin code.

0 Likes

#8

Ta! Here are more characters to satisfy posting rules.

0 Likes