0

Is there a way to use AHK to bind ' to be Control, but only used in conjunction with other keys besides shift (so that when ' or Shift + ' is pressed on its own, it still sends ' and ", respectively)? I tried the following, but it didn't work:

'::Control
' Up::'

My goal is to basically make ' a control key, while retaining its functionality when pressed alone.

2
  • Shift+' is not pressed alone. Please define better your needs. – harrymc Apr 5 '20 at 18:27
  • @harrymc I edited my question to make it clearer. – user1770201 Apr 5 '20 at 22:57
2
'::Control                      ; bind ' to be Control

' Up::
    Send, {Ctrl up}             ; release the Control key
    If GetKeyState("Shift","P") ; Shift + '
        Send, "
    else
    If (A_PriorKey = "'")       ; quote was pressed alone
        Send, '
return
1

This script is a bit tricky, so here is what it does. It assumes that Shift is always pressed before quote.

  • The variable waskey marks that an alphabetic key was pressed, starting as 0 (false).

  • The Loop command sets all alphabetic keys as hotkeys that cause execution of label keypress, which marks the fact that they were pressed.

  • The first rule is for ' down. If Shift is not pressed it sets Ctrl to down.

  • The second rule is for ' up. It sets Ctrl to up, and if no other key was entered in the meantime it issues the ' key.

global waskey = 0
global ctrldown = 0

keys = "a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"
; '|' is used as a delimiter
Loop Parse, keys
   HotKey ~*%A_LoopField%, keypress

keypress:
   waskey = 1
Return

'::        ; quote down
    if !GetKeyState("Shift") {
        waskey = 0
        ctrldown = 1
        Send, {Ctrl down}
        SetTimer, checkPressed, 3
    }
return

' up::     ; quote up
    SetTimer, checkPressed, Off
    unPressCtrl()
return

checkPressed:
    if !GetKeyState("'", "P") {
        SetTimer, checkPressed, Off
        unPressCtrl()
    }
Return

unPressCtrl() {
    if (ctrldown = 1) {
        ctrldown = 0
        Send, {Ctrl up}
        if (waskey = 0)
            Send,'
    }
}
2
  • This is so close! The problem is, for example, if I press ' + a (to get the effect of Control + a to i.e. select all text in a text field), then when I release the keys I still get a ' sent to my text field. Is there to fix this? – user1770201 Apr 6 '20 at 21:31
  • 1
    The script was working fine yesterday, but today I'm getting the same results as you. So I made it more deterministic by adding a timer that checks for quote key up. Apparently sometimes the up event is not sent. Funny that AHK is not deterministic. – harrymc Apr 7 '20 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.