Hotkey sequences

Propose new features and changes
Ytrairom
Posts: 2
Joined: 04 Oct 2019, 13:52

Hotkey sequences

04 Oct 2019, 16:18

Hi,
it would be great, if it was possible to define entire sequences of hotkeys, instead of just one.
Let say for example that I want to have automated launching of programs, such as Chrome, Firefox, Notepad, etc. Instead of making new shortcut for eachone, where I would run out of ideas soon, I would like to do just something like this:

^p,b,c::
run, chrome
return

^p,b,f::
run, firefox
return

^p,n::
run, notepad
return

Simple and elegant, all of this functionalities have in common that they launch a program, so when I want to launch something, I just press ctrl+p.
Then I can press b for example to enter browsers group and first letter of desired browser name, which won't collide with anything as it has its own group. Of course until ctrl+p is pressed, b and n would behave as usual.

VisualStudio users most likely know sequences like this very well, VS has tons of functionalities which can't have each its own shortcut, so sequences are used like ctrl+k, ctrl+d to format document, ctrl+k, ctrl+f to format selection etc.
it isn't that fast like pressing just one shortcut, but much faster than searching in a menu and it allows many kinds of functions to be handled without keyboard overloading.

Yes, I know this can be achieved in AHK using input command, however, it isn't very elegant even in the most basic form like:

^p::
input, command, l2

if (command="bc")
run, chrome
else if (command="bf")
run, firefox
;...
return

which has the limitation that for example notepad doesn't have a group, so its input would be just "n", where the keys limit would be problem.
It can be resolved using MatchList, however, for cost of even more writing, very inpractical for long list of possible inputs.

Thus having an option to write sequences just in the hotkey declaration seems very useful to me.
guest3456
Posts: 2651
Joined: 09 Oct 2013, 10:31

Re: Hotkey sequences

04 Oct 2019, 19:33

hostringskinda offer you sequences

Code: Select all

::pbc::Run, chrome
::pbf::Run, firefox
or if you want to require holding down ctrl you could use getkeystate. but actually not sure if this will fire if you are holding ctrl

Code: Select all

::pbc::
   if GetKeyState("CTRL")
      Run, chrome
return
BUT, for your specific example, its probably easier to remember to just press Windows key and start typing "chro" or "note", and the cognitive savings greatly outweigh the 2 extra keystrokes

lexikos
Posts: 6652
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Hotkey sequences

04 Oct 2019, 20:16

The existing feature set gives you the flexibility to implement almost whatever kind of system you would want. If repetition of code is the problem, you can wrap it into a reusable function, class, or set of functions or classes (and ideally share it around). One can utilize Input, InputHook(), Hotstring(), or even Hotkey or #If and normal hotkeys. A built-in solution has appeal mainly because 1) it integrates with the hotkey syntax, and 2) the work has already been done for you. But it is unclear how this should work, and if it doesn't work exactly how one wants, it is considerably less useful than any system implemented in script, which can be adapted to one's needs.

For instance, once you start a sequence with Visual Studio, all input is directed into recognition of the sequence, just like the Input command. Any out-of-sequence key is still blocked, but cancels the sequence. (I find it awkward when I've begun a sequence by accident.) The Input command does not have the flexibility to stop when you press any unrecognized key, but InputHook() does. (It can also allow the script to update visual cues on each key-press.)

Contrast this with hotkeys and hotstrings, which generally work independently; any subset of your input could be the beginning of any number of hotstrings. Hotstrings generally work like this because it's usually possible to undo the effects of pressing their individual keys (by backspacing). By contrast, the full range of keys and key combinations supported by hotkeys can have varied and dire consequences, and can't be simply undone, so would have to be blocked.

Example:

Code: Select all

^p::
Seq({
(Join,
    bc: "chrome"
    bf: "firefox"
    n: "notepad"
)})
return

Seq(def) {
    matchlist := ""
    maxlen := 1
    for key, value in def {
        matchlist .= "," key
        if (maxlen < StrLen(key))
            maxlen := StrLen(key)
    }
    Input command, % "L" maxlen,, % SubStr(matchlist, 2)
    if command := def[command]
        Run % command
}
You can also write the hotkey like this:

Code: Select all

^p::Seq({
(Join,
    bc: "chrome"
    bf: "firefox"
    n: "notepad"
)})
; No return needed because this is effectively a "one-line" hotkey.

Code: Select all

^p::Seq({bc: "chrome", bf: "firefox", n: "notepad"})
Or with AutoHotkey v2.0-a105:

Code: Select all

^p::Seq {
        bc: "chrome",
        bf: "firefox",
        n: "notepad",
    }

Seq(def) {
    matchlist := ""
    maxlen := 1
    for key, value in def.OwnProps() {
        matchlist .= "," key
        if (maxlen < StrLen(key))
            maxlen := StrLen(key)
    }
    command := Input("L" maxlen,, SubStr(matchlist, 2))
    if command := def.%command%
        Run command
}
Another simple idea for v1:

Code: Select all

^p::
InputBox command, Ctrl+P, Enter a command or abbreviation.
if !ErrorLevel
    Run % command
return

#if WinActive("Ctrl+P ahk_class #32770")
:*:bc::chrome`n
:*:bf::firefox`n
:*:n::notepad`n
#if
Now there's a basic visual cue, an obvious way to cancel, and you can enter any full command that doesn't start with "bc", "bf" or "n". Removing `n allows you to append parameters, but you must press Enter to confirm. Removing * and `n allows you to keep the abbreviations while still permitting other commands starting with these strings. The hotstrings can do things other than just typing commands, while still being limited to Ctrl+P (if placed between the #ifs):

Code: Select all

:*O:d::{Esc}#d  ; Show desktop.
:*O:m::
    WinClose Ctrl+P
    MsgBox Execute any other code as needed.
    return
These are just basic examples, since I'm not very invested in the idea. Others can do and probably have done more.
guest3456
Posts: 2651
Joined: 09 Oct 2013, 10:31

Re: Hotkey sequences

04 Oct 2019, 23:54

very thorough @lexikos really great

User avatar
jeeswg
Posts: 6821
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Hotkey sequences

05 Oct 2019, 01:53

I shared a little prototype here, for an any-key hotstring sequence:
Employ Useless Duplicate Set of Keys - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=60302&p=254709#p254709
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Ytrairom
Posts: 2
Joined: 04 Oct 2019, 13:52

Re: Hotkey sequences

05 Oct 2019, 18:08

Hi there,
well, problem of hotstrings is not just that ctrl or other modifier keys can't be used efficiently, but also that they pass to the environment before they get processed.
Yes, AHK erases written text automatically, but what about non-text environments like Mozilla Thunderbird? VLC? Audacity?
M for example in thunderbird automatically marks currently selected mail as unread, what can't be unset just by sending backspaces to the active window.

About cancelling sequences, in my opinion, VisualStudio's system is perfect in this. If you start one accidentally, well, that's the same as accidentally pressing any hotkey. Esc is a good way how to get out of it, although i don't remember any case I actually needed to do so.

Inputbox is not an ideal solution, as it not only requires to press enter, but also distracts focus, what can be umpleasant in some situations.

It's true that the functionality can be achieved by using AHk system features such as functions, lists, etc, I've said that already in post 1.
That's why I'm asking for language integration,.
Functions are okay for complex operations, like calculating factorials or square root of a number.
But not for such a basic feature.
Otherwise I wouldn't need AHK at all, because I can make all of its functionalities in C#, )C++ or Python.
However, AHK's power is exactly in way how it allows things to be done quickly, binding action to shortcuts just by s::, instead of messing with GetAsyncKeyState, tracking loops, keyboard hooks etc. in other languages.
And the same would be nice for sequences as well, doing just ^p,b,c, instead of constructing whole lists just to tell AHK how to recognize my sequences and only after this focusing on what to do.

Just for an imagination, I plan to have all of my scripts in some sort of sequence, not just playn hotkeys. I have a reason to do so, I use shortcuts of various programs quite intensively and it is thus much easier to sort everything nicely under one or two hotkeys which would start a sequence, instead of constantly monitoring, what will collide with what and balancing everything out, which may be even impossible to do plus when there are many functions to handle, even without using programs hotkeys, there simply wouldn't be enough place on the keyboard.

So lets say I had 100 actions to bind on sequences. Without language integration, I would need 100 entries long list for sequences evidence and 100 if statements to check if some concrete sequence was found, without any kind of possibility to break it to more scripts and 100 functions for each of the action i.e. 100 function declarations and 200 curly brackets. There we go, 500 totally wasted lines of code, just because of missing language integration.
And I'm not even talking about hard readability and mantainability plus modifier keys are still problem.
We could improve it slightly by using dictionaries and some sort of auto-searching algorithm, which would save the 100 if statements. That would be probably the best approach possible with current AHK version, although there are still 400 pointless lines, which could be saved if sequences were integrated. Even if we include the fact that with language integration there still need to be 200 lines to at least define and end each action, there are still 200 useless lines.

Now you might think, where on the earth do I get 100 actions? Well, answer is everywhere. Making shortcuts for various webpages control, programs automation etc. The programs launching example was just an example, I plan to do bit more complex things. :)
So okay, then why I don't use window or site specific shortcuts instead of sequences?
Simply because a. I would soon forget what I set where, b. because there wouldn't be an option to use letters only without modifier keys because of textboxes and c. it would be still much writing specifying windows and sites where those actions can be executed.
May be it's just me, but sequences are simply more practical for this, from whatever side I look on it.

Return to “Wish List”

Who is online

Users browsing this forum: No registered users and 15 guests