AutoHotKey v2.0.2: How to trigger HotKey on square bracket - autohotkey

I am trying to remap the opening square bracket ([) to a lower case u-umlaut (ü) and the opening curly bracket ({ / Shift+[) to the upper case U-umlaut (Ü) on a US keyboard layout using a AutoHotkey script.
The following works very well with ; to ö and : to Ö but the Variantes for ü and Ü don't. I suspect it's because a square bracket has a special meaning but there is no error about Syntax and AutoHotkey's escape Syntax with ` does not apply here.
I believe that the problem is the trigger $[:: because the first block with KeyWait alone without the second Up part does not prevent me typing [ while it does when I try that with ;.
Please explain what I am doing wrong.
#Requires AutoHotkey v2.0
#SingleInstance Force
LongPressDelay := 220
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; O-Umlaut | ; => ö und : => Ö
$;::
{
KeyWait ";"
return
}
$; Up::
{
If (A_PriorHotKey = "$;" AND A_TimeSincePriorHotkey < LongPressDelay)
Send ";"
else
Send "ö"
return
}
$+;::
{
KeyWait ";"
return
}
$+; Up::
{
If (A_PriorHotKey = "$+;" AND A_TimeSincePriorHotkey < LongPressDelay)
Send ":"
else
Send "Ö"
return
}
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; U-Umlaut| [ => ü und { => Ü
$[::
{
KeyWait "["
return
}
$[ Up::
{
If (A_PriorHotKey = "$[" AND A_TimeSincePriorHotkey < LongPressDelay)
Send "["
else
Send "ü"
return
}
$+[::
{
KeyWait "["
return
}
$+[ Up::
{
If (A_PriorHotKey = "$+[" AND A_TimeSincePriorHotkey < LongPressDelay)
Send "{"
else
Send "Ü"
return
}
; EDIT: My working solution per user3419297's answer
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; U-Umlaut| [ => ü und { => Ü
$SC01A::
{
KeyWait "SC01A"
return
}
$SC01A Up::
{
If (A_PriorHotKey = "$SC01A" AND A_TimeSincePriorHotkey < LongPressDelay)
Send "["
else
Send "ü"
return
}
$+SC01A::
{
KeyWait "SC01A"
return
}
$+SC01A Up::
{
If (A_PriorHotKey = "$+SC01A" AND A_TimeSincePriorHotkey < LongPressDelay)
SendText "{"
else
Send "Ü"
return
}
Script based on https://www.autohotkey.com/board/topic/80697-long-keypress-hotkeys-wo-modifiers/?p=689354
Context:
As a Developer it's super helpful to code using the US keyboard layout because all the special characters are within easy reach. As a native German speaker I'd like to access our beloved Umlauts at their traditional spots because I'm used to it.
On MacOS I solved this with Karabiner and Umlauts on long press. I want to replicate this on Windows.

In the rare case where a key has no name or the standard code doesn't work, Hotkeys can be triggered by using the 3-digit hexadecimal scan code (SC) of a key.
The scan code of a key can be determined by following the steps at Special Keys:
Run a script with keyboard hook
open the AutoHotkey window (context menu in systray, Open item)
go to View > Key History and script info
type the key
hit F5 to see the code

Trying the same right here, using a different code though.
https://www.autohotkey.com/boards/viewtopic.php?f=9&t=99809
I managed to migrate it to V2 and changed the keys to match the German Keyboard layout.
[ = ü
' = ä
; = ö
- = ß
Please feel free to try:
$[::
$+[::
$'::
$+'::
$;::
$+;::
$-::
{
umlaut_pairs := Map("$[" , "ü", "$'" , "ä", "$;" , "ö", "$-" , "ß", "$+[" , "Ü", "$+'" , "Ä", "$+;" , "Ö")
umlaut := umlaut_pairs[A_ThisHotkey]
Send SubStr(A_ThisHotkey,2) ; input the letter first, otherwise input order might be wrong
KeyWait Substr(A_ThisHotkey,-1), "T0.2" ; call only the specific character without "$" or "+" and show input of the pressed key
if(A_TimeSinceThisHotkey>200) ; if pressed more than 200ms
{
Send "{BackSpace}" ; backspace previous letter
Send umlaut_pairs[A_ThisHotkey] ; Replace acc. to the map
KeyWait Substr(A_ThisHotkey,-1), "T0.2"
; }
}
}

Related

How do you include a loop with modifiers?

I'm trying to get AHK to continue to press "2" until "2" is pressed a second time. If alt, ctrl, or shift is held it sends ^2, +2, !2 while held and then returns to spamming "2" once the modifier key is released.
This code works so far with modifiers I just need to figure out how to add the loop.
; Disable Alt+Tab
!Tab::Return
; Disable Windows Key + Tab
#Tab::Return
#ifWinActive World of Warcraft
{
$2::
$^2::
$+2::
$!2::
Loop
{
if not GetKeyState("2", "P")
break
if GetKeyState("LCtrl", "P")
Send ^2
else if GetKeyState("LShift", "P")
Send +2
else if GetKeyState("LAlt", "P")
Send !2
else
Send 2
sleep 135
}
return
}
I would recommend using SetTimer for your loop and to be able to toggle it on and off. Please see if the following works for you:
$2::
$<^2::
$<+2::
$<!2::
SetTimer , label_TwoLoop , % ( bT := !bT ) ? "135" : "Off"
Return
label_TwoLoop:
If GetKeyState( "LCtrl" , "P" )
Send , ^2
Else If GetKeyState( "LShift" , "P" )
Send , +2
Else If GetKeyState( "LAlt" , "P" )
Send , !2
Else
Send , 2
Return
https://autohotkey.com/docs/commands/SetTimer.htm
Note that I added the < to the hotkey definitions since the loop-portion is only looking for the left modifier keys. I figured this is the intended behavior.

How to achieve visual-studio-like chained hotkeys using AHK?

I'm trying to achieve a visual-studio-like chaining of hotkeys for something at work.
Basically, when I hit Ctrl+Alt+F, I want to enter a sort of "Format mode" The next key I press will determine what text is injected. I'd like "Format mode" to cease as soon as one of the inner hotkeys is pressed. However I'd also like the option to have to cancel it manually just in case.
I've tried searching for the chaining of hotkeys, as well as attempted the following, rather naive code:
;
;; Format Mode
;
^+f::
; Bold
b::
Send "<b></b>"
Send {Left 4}
return
; Italics
i::
Send "<i></i>"
Send {Left 4}
return
; Bulleted List
u::
Send "<u></u>"
Send {Left 4}
return
; Numbered List
o::
Send "<o></o>"
Send {Left 4}
return
; List Item
l::
Send "<li></li>"
Send {Left 4}
return
; Line Break
r::
Send "<br/>"
return
return
I was pretty sure this wasn't going to work, but I figured I'd give it a shot so as to not make y'all think I'm just asking to be spoon fed.
I haven't worked with AHK a whole lot, but I've used it enough to be able to accomplish some stuff both at home and at work, but it's suuuuper messy - just as some background as to my experience with AHK.
With the #if command you are able to Switch/Toggle between action1/Enable and action2/Disable with the same Hotkeys.
You can test it out in Notepad. if you then type the key t
type Ctrl+Shift+f keys to toggle between two the same hotkeys.
Note: For your Hotkeys You Can Change the Code a Little Bit! you can Place all your hotkeys into #if Mode1 and then use no hotkeys into #if Mode2
Example1.ahk
; [+ = Shift] [! = Alt] [^ = Ctrl] [# = Win]
#SingleInstance force
a := 1
#If mode1 ; All hotkeys below this line will only work if mode1 is TRUE or 1
t::
send 1
; Here you can put your first hotkey code
return
; Here you can Place All your Hotkeys
#If
#If mode2 ; All hotkeys below this line will only work if mode2 is TRUE or 1
t::
send 2
; And here you can put your second hotkey code
return
#If
; toggle between [t::1] and [t::2]
;a = 1 => t::1
;a = 2 => t::2
;type Ctrl+Shift+f keys to toggle between two the same hotkeys
;you can test it out in notepad - if you then type the key t
^+f::
if (a=1)
{
mode1 = 1
mode2 = 0
a := 2
}else{
mode1 = 0
mode2 = 1
a := 1
}
return
esc::exitapp
Using #If is a good choice, as stevecody showed. Below is another solution that may work for you. It uses your ^+f hotkey to activate the specialty hotkeys. The specialty hotkeys will also deactivate themselves upon use. f1 is your option to cancel it manually.
^+f::
Hotkey , b , l_Bold , On
Hotkey , i , l_Italics , On
Hotkey , l , l_ListItem , On
Return
f1::
Hotkey , b , l_Bold , Off
Hotkey , i , l_Italics , Off
Hotkey , l , l_ListItem , Off
Return
l_Bold:
Hotkey , b , l_Bold , Off
Send , <b></b>{left 4}
Return
l_Italics:
Hotkey , i , l_Italics , Off
Send , <i></i>{left 4}
Return
l_Italics:
Hotkey , l , l_ListItem , Off
Send , <li></li>{left 5}
Return
Something else I was looking at, but it doesn't quite work right, is below. The problem is that it will still send the specialty key and you end up with something like <i>i</i> instead of <i></i>.
f1::
KeyBdHook := DllCall( "SetWindowsHookEx" , "int" , 13 , "uint" , RegisterCallback( "KeyBdProc" ) , "uint" , 0 , "uint" , 0 )
input
Return
KeyBdProc( nCode , wParam , lParam )
{
global KeyBdHook
Critical
If ( wParam = 0x100 )
{
DllCall( "UnhookWindowsHookEx" , "ptr" , KeyBdHook )
sKey := GetKeyName( Format( "vk{:x}" , NumGet( lParam + 0 , 0 , "int" ) ) )
If ( sKey = "i" )
Send , <i></i>{left 4}
Else
MsgBox , You pressed %sKey%
}
}

Mapping Swedish character hotkeys in MacOS to Windows 10

I want to map the Swedish characters å,ä,ö,Å,Ä,Ö to the MacOS hotkeys, but I want it to work under Windows 10 since at work I use a Windows machine and I do not want to keep switching back and forth from a US to Swedish keyboard layout. I think Autohotkey will be appropriate for this.
The MacOS mappings are:
Option+a = å
Shift+Option+a = Å
Option + u, then a = ä
Option + u, then shift + A = Ä
Option + u, then o = ö
Option + u, then shift + O = Ö
Instead of using the option key in Windows (since it doesn't exist) I will use the Left Windows key.
So far I have the script:
#u::
Input Key, L1
if Key=a
{
Send, ä
}
if Key=o
{
Send, ö
}
return
#a::
Send, å
return
This works for the lowercase characters but I am not sure how to implement the upper case characters.
user3419297's answer didn't work for me but I was able to use parts of it to get the code to work properly. I have posted it below in case anyone is wondering how I was able to get it to work.
#u::
Input, Key, L1
if GetKeyState("LShift")
{
if Key=a
{
Send, Ä
}
if Key=o
{
Send, Ö
}
}
else
{
if Key=a
{
Send, ä
}
if Key=o
{
Send, ö
}
}
return
<#a:: Send, å
<#+a:: Send, Å

Autohotkey: Paste/write a simple line of text with a keyboard shortcut?

This is a super simple thing I am trying to get my head around
I want to use something like WINKEY + ALT + C to paste ** - words** so that I can sign-off my posts or whatever using the three-key combo
Not sure what exactly you want, maybe something like this?
Press WINKEY + ALT + C to paste the clipboard contents:
#!c::
SendInput, ^v
Return
Press WINKEY + ALT + C to paste "Some random text"
#!c::
SendInput, Some random text
Return
Instead of Sendinput which will type each characters you can use a clipboard paste approach. See for example https://github.com/tdalon/ahk/blob/59a8ab2a8fd497b4a5b5a85e73e32ff95d5d4425/Lib/Clip.ahk
Clip_Paste(sText,restore := True) {
; Syntax: Clip_Paste(sText,restore := True)
If (restore)
ClipBackup:= ClipboardAll
Clipboard := sText
WinClip.Paste()
If (restore)
Clip_Restore(ClipBackup)
} ; eofun
; ---------------------------------------------------------------------------
Clip_Restore(ClipBackup) {
Clip_Wait() ; in order not to overwrite running clipboard action like pasting
Clipboard:= ClipBackup
} ;eofun
; ---------------------------------------------------------------------------
Clip_Wait(){
Sleep, 150
while DllCall("user32\GetOpenClipboardWindow", "Ptr")
Sleep, -1
} ; eofun

AutoHotkey Script to send pound (£) on double press of Shift+3

I'm trying to make a script that sends a pound instead of a dollar when you hold down Shift and press 4 twice quickly.
Has anyone seen any code that does this sort of thing?
EDIT:
Okay I've seen some documentation and managed to get it detecting the double shift+3 press like this:
Shift & 4::
if (A_PriorHotkey <> "Shift & 4" or A_TimeSincePriorHotkey > 400)
{
KeyWait, 4
return
}
Send, £
return
But can't get it to send the $ for some reason. Any ideas?
I got the intended functionality working eventually:
Shift & 4::
if (A_PriorHotkey <> "Shift & 4" or A_TimeSincePriorHotkey > 800)
{
Send, {$}
return
}
Send, {BS}
Send, £
return
Basically, when you press Shift+4 the dollar is printed. If you're still holding shift and you press 4 again, the backspace key is pressed and the £ is printed.
As in http://www.autohotkey.com/docs/KeyList.htm#SpecialKeys, you should put key name into " ".
KeyWait, "3"
Does this work?
Shift & 4::
KeyWait, 4 ; waits for '4' to be released
KeyWait, 4, D T.4 ; waits 400ms for 4 to be pressed again
Send % ErrorLevel ? "{$}" : "{BS}{£}"
; if ErrorLevel=1 (4 not pressed) will send $ else will send {BS}£
return
I used to do this in a complicated way as well until I realized that the solution is very simple:
:*:$$::£
Just press $ sign twice to get a £ (or €)
B.t.w. I did the same for ", just press ' twice to get "
:?*:''::"{Space}
The {space} is required for me because " is only printed after I press space. (Dutch language setting).