HotKey multiple characters - autohotkey

Is it possible to define an AutoHotKey HotKey which require multiple characters to fire ?
Example: if I write the AHK script
^j::
Send, my test
return
The Hotkey Control j fires off the string "my test"
What if I wanted to require Control jBAS to fire off the script ...in this case the letters BAS following the Control j ? From the examples I have seen, HotKey does not seem to allow this ...I can accomplish this with a HotString ...problem with HotString is that you must hit Enter and then the original String is replaced with the new HotString definition.

Heres an option:
^j::
Input, matchVal, C L3,, BAS
if (matchVal=="BAS") {
Send, mytest
}
Return
Check out https://www.autohotkey.com/docs/commands/Input.htm for further data and options.

Related

Toggle keys in autohotkey

My goal is mapping WASD to the 4 arrow buttons on the keyboard and make 1 'Suspend' the script while z exits it. That was easy enough. Now I'd like a and d only apply conditionally. I look at the docs and I have no idea what's wrong here. I think I'm either using the if statement wrong or Left/Right doesn't work in if statements in which case I have no idea what to do.
#SingleInstance
a::if(UseAD) Left
d::if(UseAD) Right
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp
Try this:
#SingleInstance
$a::Send % UseAD ? "{Left}" : "a"
$d::Send % UseAD ? "{Right}" : "d"
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp
Okay now a break down.
Your If statement wasn't being evaluated correctly. The following line of code after the condition is met is what is run. Like so:
If (true)
do this
Your Hotkey is also wrong for a Multi lined statement. Essentially a single lined Hotkey is a basically a Send command for whatever key or keys specified on that line (unless you specify an assignment/function/command etc...) it will act as a Send Command does. To have an If evaluation requires multiple lines. When you specify a hotkey and you want an evaluation that will require multiple lines you, and must return from a Multi-Lined Hotkey same a Sub Routine:
a::
Code goes here
more code
etc..
Return
b::AnotherHotkey
etc..
Okay so lets plug this Logic in with your code:
#SingleInstance
a::
if(UseAD)
Left
return
d::
if(UseAD)
Right
return
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp
If you run this you'll get an Error about the Text Left... that is because instead of our Hotkey acting as Send command it's acting as a Sub Routine so we have to specify Send command with Left:
a::
if(UseAD)
Send, Left
return
But this isn't correct either, now it's sending the word Left instead of the Key left.. so again we have add Brackets around our named key like so:
a::
if(UseAD)
Send, {Left}
return
Okay, now a and b are not being sent when UseAD is False, so we must Send them by specifying with Else like so:
a::
if(UseAD)
Send, {Left}
else
Send, a
return
Now we run this code and press a or b get an Max Hotkeys reached message because our code is triggering the Hotkey in an Infinate loop. We need to specify our code in such a way that it will not trigger itself, like so:
$a::
if(UseAD)
Send, {Left}
else
Send, a
return
If you notice we have added a $ symbol in front of our hotkey, this adds a keyboard Hook to that Hotkey and will prevent the the script from triggering that hotkey itself. This is now a complete working script but looks entirely different from the first code I posted. That is because I like typing less lines, if I can.
In the first code sample I'm using a Forced Expression % on the Send command and Ternary ? : to evaluate UseAD and if true send Left key if false send the letter, exactly the same as above code, just more concise.

Autohotkey, putting "D89dl" at the end of a sentence doesn't work as intended

I have a Autohotkey script that puts "D89dl" at the end of a sentence everytime I press Enter, but using it with a AutoCorrect script it doesn't work as it should. Let's say you type "dont", it then would look like this "don't" instead of "don't.". Something is blocking it but I'm not sure what it is, I've been trying for months now.
Here are the scripts:
enter::
send,D89dl{Enter}
Return
#Hotstring EndChars -()[]{}:;'"/\,.?!`n `t
::dont::don't
I would be VERY thankful if anyone of you helps me with this.
Overall, do you know any other way instead of Autohotkey that puts "D89dl" at the end of a sentence?
The easiest solution seems to be to use the :*: mode, which will trigger everytime the misspelled word is typed, without the need for Hotstring EndChars:
:*:dont::don't
Instead of using Enter, I suggest you use a special combination of keys that enter the string D89dl and then press Enter. Use a modifier like ctrl or alt and another key. The reasoning is that the key Enter has very important functionality and should not be changed. Pressing that special combination is appropriate, given the very special function it does.
It's a bit hacky, but it should do the job (given that by "end of sentence" you actually meant pressing "Enter"):
~enter::
Sleep, 100
SendInput, {BS}D89dl{Enter}
Return
#Hotstring EndChars -()[]{}:;'"/\,.?!`n `t
::dont::don't

advance hotstrings in autohotkey

I found this working autohotkey (ahk) code from the website https://jacksautohotkeyblog.wordpress.com/2015/10/22/how-to-turn-autohotkey-hotstring-autocorrect-pop-up-menus-into-a-function-part-5-beginning-hotstrings/ .
::agin::
TextMenu("again,a gin,aging")
Return
::duh::
TextMenu("what,huh,you're joking")
Return
TextMenu(TextOptions)
{
StringSplit, MenuItems, TextOptions , `,
Loop %MenuItems0%
{
Item := MenuItems%A_Index%
Menu, MyMenu, add, %Item%, MenuAction
}
Menu, MyMenu, Show
Menu, MyMenu, DeleteAll ;Moved from MenuAction:
}
MenuAction:
SendInput %A_ThisMenuItem%{Raw}%A_EndChar%
Return
This is a hotstring script with menu. For example when I type agin I get a many with three options (again,a gin,aging) to choose. Now I want to write it something like this:
agin=again,a gin,aging
duh=what,huh,you're joking
qwe=qwe,qww,ere
Because I have a lot of hotstrings.
As time has passed, in the most recent version of AHK it became possible to do!
Use option x to allow expressions in the oneliner.
Either as :x:...:: OR as a group option above all lines: #Hotstring x
:x:agin::TextMenu("again,a gin,aging")
As nice as it would be, unlike AutoHotkey Hotkeys, I don't believe you can put anything other than replacement text on the same line of an AutoHotkey Hotstring. In other words,
::agin::TextMenu("again,a gin,aging")
would not work while,
::agin::
TextMenu("again,a gin,aging")
Return
does. It is a few more characters long, but not overwhelming.

(AHK) Creating variable hotkeys that gets the key names from a 2 char file name of a script

I'm trying to make something for our employees to use so that they dont have to alter the script itself to define hotkeys. This may only work for hotkeys which can be defined by a single character, but that's fine, as there are so many combinations that can be made with them, and they can be very easy to remember. The script would look only at 2 character AHK files (or 6 if you must include the extension) in the working directory. And the variables it would search for could be defined with RegEx so for the first hotkey, it would look like ^. and then second would look like .(?=.) Once a match is found, it would simply launch that matched file. Has something like this been done before? It seems so simple but I can't seem to find anything on it.
Edit: Elliot brought this to my attention: http://autohotkey.com/board/topic/60630-easy-editmanage-hotkeyshotstrings-plugin-ahk-l/
It's a neat script manager, and very useful, but it's not what I'm looking for.
I dont not want an additional interface. I want to be able to change the hotkeys by using the filename.
Based on the answer of Forvin. Added the execution of the corresponding ahk script.
#Persistent
SetTimer, FindNewHotkeys, 2000
FindNewHotkeys:
Loop, %A_ScriptDir%\*
{
RegExMatch(A_LoopFileName, "^(.)(.).ahk$", hk)
If (hk)
{
Hotkey, ~%hk1% & ~%hk2%, HotkeyLabel
}
}
Return
HotkeyLabel:
RegExMatch(A_ThisHotkey, "~(.) & ~(.)", hk)
run, %hk1%%hk2%.ahk
Return
#Persistent
SetTimer, FindNewHotkeys, 2000
FindNewHotkeys:
Loop, %A_ScriptDir%\*
{
RegExMatch(A_LoopFileName, "^(.)(.).ahk$", hk)
If (hk)
Hotkey, ~%hk1% & ~%hk2%, HotkeyLabel
}
Return
HotkeyLabel:
MsgBox, A hotkey has been pressed!
Return

How to remap key in certain case and not remap in other case with autohotkey?

I want to remap alt+e when caps is on in autocad.
And when capslock is not on, alt+e should open menu edit.
I use script like this
<!e::
if(GetKeyState( "CAPSLOCK", "T" ))
{
SendInput erase{space}wp{space}
}
else
{
Send !e
}
When I turn on capslock, remap key is OK.
When I turn off capslockand alt+e, menu edit opened, but closed immediately.
Thanks.
You will want a $ at the beginning of your hotkey to prevent the endless loop that the !e in your else block will trigger. You will also want to add a Return at the end of the hotkey to prevent the script from continuing into what is below this hotkey.
$!e::
if GetKeyState( "CapsLock", "T" )
Sendinput, erase{space}wp{space}
else
Sendinput, !e
Return
(Brackets are only required when if/else blocks are more than one line.)
Beyond that, the likely issue is that it's an alt hotkey that is also set to send alt.
I say this is an issue because if you press and hold alt, it activates menus,
and then the script sends alt, which will be in conflict with that.
As Ricardo said, the ideal way to script this is with the #IF command (only included with AHK_L).
#If GetKeyState("CapsLock", "T") and WinActive("AutoCAD")
!e:: SendInput, erase{space}wp{space}
#If
Notice that you can add the WinActive() function to the #If command's expression.
Try it without that first, and also realize that the application's title needs to be exactly "AutoCAD" at all times for that to work. I would recommend finding AutoCad's ahk_class,
with AHK's window spy, instead of using the title.
If it still does not work, it is likely that AHK is sending faster than AutoCAD would like to receive.
Info on how to deal with that can be found here.
Try to change your else block to this:
Send, {ALTDOWN}e{ALTUP}
I do not rely on these symbols to send keystrokes in AutoHotKey.