check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
neogna2
Posts: 591
Joined: 15 Sep 2016, 15:44

check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Post by neogna2 » 04 Jun 2023, 09:29

In v1 IsLabel(LabelName) returns a non-zero number if the label exists, where label means the "name of a subroutine, hotkey, or hotstring". For example

Code: Select all

MsgBox % IsLabel("::a") ;1
::a::abc
(Note though that IsLabel() doesn't detect hotkeys or hotstrings created with the Hotkey() or Hotstring() functions.)

But in v2 IsLabel only returns 1 if "the specified label exists within the current scope", where label means only labels, *not* hotkeys or hotstrings.

Code: Select all

MsgBox IsLabel("::a") ;0
MsgBox IsLabel("b")   ;1
::a::abc
b:
return
Is there some other way in v2 to check if a hotstring or hotkey exists in the current script (in any context)?

edit:
I found the answer at Hotstring#Errors
A TargetError is thrown if Replacement is omitted and String is valid but does not match an existing hotstring. This can be utilized to test for the existence of a hotstring.
So we can use this (building on the doc's example)

Code: Select all

IsHotstring(Name) {
    Try Hotstring(Name)
    Catch TargetError
        Return 0
    Return 1
}
and similarly with Try Hotkey(Name)

However the above function only detects hotstrings that have no #HotIf context limitations.
To detect a hotstring in a context we can use

Code: Select all

IsHotstring(Name, Context := "") {
    Try HotIf Context ;defaults to turns of context-sensitivity from last call
    Try Hotstring(Name)
    Catch TargetError
        Return 0
    Return 1
}
but then must have a record of hotstring/hotkey contexts at hand where the function is called.

In contrast v1 IsLabel() returns 1 if the hotstring exists in any (at least one) context. Is there some v2 workaround to check if a hotstring exists across all contexts?

edit4:
- Changed from HotIfWinActive(Context) to Try HotIf Context to allow for more contexts and avoid error if parameter Context does not match an existing #HotIf context.
- Changed term 'Scope' to 'Context' because the HotIf documentation talks about context and scope is something else.
- Removed conditional so that Try HotIf Context always runs even if no Context parameter is supplied, in order to then clear the HotIf context set by previous function calls.
- Added note that v1 IsLabel() doesn't detect Hotstring() or Hotkey() created hotstrings/hotkeys.
Last edited by neogna2 on 05 Jun 2023, 06:57, edited 3 times in total.

User avatar
mikeyww
Posts: 26931
Joined: 09 Sep 2014, 18:38

Re: check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Post by mikeyww » 04 Jun 2023, 18:47

Code: Select all

; This script determines whether a hotkey exists in the script
#Requires AutoHotkey v2.0
Hotkey 'F4', go, 'On'
isHotkey

F2:: {
 For each, item in ['^F3', 'F4', 'F9', 'x', 'F2']
  MsgBox isHotkey(item), item
}

#HotIf WinActive('ahk_exe notepad.exe')
^F3::MsgBox 123
#HotIf

isHotkey(hk := '') {
 Static hkList := '`t'
 If hkList = '`t' {
  ListHotkeys
  WinWaitActive('ahk_class AutoHotkey'), txt := ControlGetText('Edit1'), Send('{Esc}')
  For n, line in StrSplit(txt, '`n')
   (n > 2 && RegExMatch(line, '\t{4}(.+)$', &m)) && hkList .= m[1] '`t'
 }
 Return InStr(hkList, '`t' hk '`t') > 0
}

go(ThisHotkey) {
 MsgBox 456
}

neogna2
Posts: 591
Joined: 15 Sep 2016, 15:44

Re: check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Post by neogna2 » 05 Jun 2023, 04:32

Thanks mikeyww, useful. Some drawbacks with the ListHotkeys approach: the main window briefly flickers visible, only hotkeys and not hotstrings are listed and here is no information about the hotkeys' context.

Another approach to getting the script's hotstrings and hotkeys is to parse the scripts source file.

But thinking on this topic makes me wish for built in functionality to get all existing hotkeys and hotstrings, including context, as a Map object or similar without having to interact with the script's main window. I'll make a feature request post for that later if this thread doesn't discover any more existing workarounds.

User avatar
mikeyww
Posts: 26931
Joined: 09 Sep 2014, 18:38

Re: check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Post by mikeyww » 05 Jun 2023, 05:10

You are correct on all points.

Parsing the source file could be easy or difficult, depending on the specific script. One can get to a point of writing a parser that might be similar to AHK itself!

Code: Select all

#Requires AutoHotkey v2.0
x := 'F'
j := 1
w := 'Q'
If w
 Loop 1
  Hotkey x 3 + j, go, 'On'

go(ThisHotkey) {
 MsgBox 123
}

User avatar
boiler
Posts: 16949
Joined: 21 Dec 2014, 02:44

Re: check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Post by boiler » 05 Jun 2023, 05:56

mikeyww wrote: Parsing the source file could be easy or difficult, depending on the specific script.
And the script itself may not contain the information at all if hotkeys are generated based on user selection and/or reading the selections from a file — assuming neogna2 is looking for a complete list no matter how they’re generated, which may not be the case since IsLabel() in v1 wouldn’t reveal such hotkeys either.

neogna2
Posts: 591
Joined: 15 Sep 2016, 15:44

Re: check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Post by neogna2 » 05 Jun 2023, 06:54

boiler wrote:
05 Jun 2023, 05:56
mikeyww wrote: Parsing the source file could be easy or difficult, depending on the specific script.
And the script itself may not contain the information at all if hotkeys are generated based on user selection and/or reading the selections from a file — assuming neogna2 is looking for a complete list no matter how they’re generated, which may not be the case since IsLabel() in v1 wouldn’t reveal such hotkeys either.
Yes that's relevant. I'm updating OP with the info that v1 IsLabel() doesn't detect hotkeys or hotstrings created with the Hotkey() or Hotstring() functions.

I have a use case where I'd like a list of all hotkeys/hotstrings regardless of how they're created, but in other cases I have use in v2 for what v1 IsLabel() offered and in some further cases a list of only hotkeys/hotstrings created with the direct syntax (for example "a::") would also be useful. So this thread can examine all such possibilities.

User avatar
mikeyww
Posts: 26931
Joined: 09 Sep 2014, 18:38

Re: check if hotstring or hotkey exists in v2 script, like IsLabel() in v1?

Post by mikeyww » 05 Jun 2023, 10:55

Good ideas, can still be a challenge with parsing.

Code: Select all

#Requires AutoHotkey v2.0
b:: Send '
(
a::
)'
Send 'c::d'

Post Reply

Return to “Ask for Help (v2)”