Custom deadkeys

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
berz
Posts: 18
Joined: 16 Apr 2021, 16:40

Custom deadkeys

20 Apr 2021, 11:19

Hi. I remade the deadkeys from the US international layout so that I can expand them and use them with a non-international US layout, however I'm having a couple issues.

Issue n°1: when you press hotkey + space, the symbol itself should appear (e.g. ` + {space} = `), instead, nothing shows.

Issue n°2: when you press hokey twice, the symbol should appear twice (e.g. ` + ` = ``). As above, nothing is printed instead.

Here's a snippet of the code (much of which is the result of you guys' help):

Code: Select all

#NoEnv
;#Warn
#KeyHistory 10
SendMode Input
SetWorkingDir %A_ScriptDir%
ListLines Off

DeadKey(sym)
{
    static TildeKeys := {a: "ã", Ax: "Ã", n: "ñ", Nx: "Ñ", o: "õ", Ox: "Õ", i: "ĩ", Ix: "Ĩ", u: "ũ", Ux: "Ũ", b: "ᵬ", d: "ᵭ", f: "ᵮ", m: "ᵯ", n: "ᵰ", p: "ᵱ", r: "ᵲ", s: "ᵴ", t: "ᵵ", z: "ᵶ", e: "ẽ", Ex: "Ẽ", v: "ṽ", Vx: "Ṽ", y: "ỹ", Yx: "Ỹ", Lx: "Ɫ"}
    static GraveKeys := {a: "à", Ax: "À", e: "è", Ex: "È", i: "ì", Ix: "Ì", o: "ò", Ox: "Ò", u: "ù", Ux: "Ù", n: "ǹ", Nx: "Ǹ", y: "ỳ", Yx: "Ỳ"}
    
    ; ... others ...

    static DeadKeys := {"~": TildeKeys, "`": GraveKeys}

    Input, Char, L1
    if (Char = " ") {
        Send, {Raw}%sym%
        return
    }

    ; Hack to detect uppercase variants
    Char .= (RegExMatch(Char, "[A-Z]") && DeadKeys[sym].HasKey(Char "x")) ? "x" : ""

    SendRaw, % (DeadKeys[sym].HasKey(Char)? DeadKeys[sym][Char] : sym Char)
}

; ...

`::
DeadKey("`")
return

+`::
DeadKey("~")
return
I also tried prepending $ to the hotkeys, with no result, and ~, which solves the issues but also always causes the symbol to be printed each time the key is pressed, even when not appropriate (~ + a = ~ã; ~ + ~ = ~~~~).

Am I missing something stupid?
User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Custom deadkeys

20 Apr 2021, 11:50

Which lines are supposed to address the two issues that you mentioned?
berz
Posts: 18
Joined: 16 Apr 2021, 16:40

Re: Custom deadkeys

20 Apr 2021, 14:01

mikeyww wrote:
20 Apr 2021, 11:50
Which lines are supposed to address the two issues that you mentioned?

Code: Select all

if (Char = " ") {
        Send, {Raw}%sym%
        return
    }
Should print the symbol of the deadkey itself when the input to it is just a space.

Code: Select all

SendRaw, % (DeadKeys[sym].HasKey(Char)? DeadKeys[sym][Char] : sym Char)
If the object matching with the deadkey (TildeKeys or GraveKeys here) has no key corresponding to the inputted character, it should print the symbol and then the inputted character. This should include when the symbol itself is inputted twice, since the objects don't have them as keys.
User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Custom deadkeys

20 Apr 2021, 16:18

Maybe:

Code: Select all

`::DeadKey("``")

Code: Select all

Send % "{Text}" (DeadKeys[sym].HasKey(Char) ? DeadKeys[sym][Char] : sym Char)
berz
Posts: 18
Joined: 16 Apr 2021, 16:40

Re: Custom deadkeys

21 Apr 2021, 05:11

Sorry, that doesn't work. It produces the same issues but prepending {Text} to the output.
User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Custom deadkeys

21 Apr 2021, 06:14

You'll need to fix the backtick to escape it, so change the following line, too.

Code: Select all

Static DeadKeys  := {"~": TildeKeys, "``": GraveKeys}
Explained: Escape sequences
berz
Posts: 18
Joined: 16 Apr 2021, 16:40

Re: Custom deadkeys

21 Apr 2021, 08:54

mikeyww wrote:
21 Apr 2021, 06:14
You'll need to fix the backtick to escape it, so change the following line, too.

Code: Select all

Static DeadKeys  := {"~": TildeKeys, "``": GraveKeys}
Explained: Escape sequences
Oh, sorry, I forgot to mention it but I did change that part too. An additional undesired side-effect of your suggestion is that if I press a character that isn't in the defined combination, it appears as normal, but spacebar is then "eaten" until I press a character that can be combined. In other words the hotkey seems to stay active until that happens.

Also note the issues I describe happen with every custom deadkey, not just `. For example, the same issues are there for ~ (which is shift + `) or ', which is not escapable as per the page you linked, so it must be something else.

There might be a need to tell AHK to treat a deadkey hotkey as a normal symbol while one is already active, but I'm still puzzled by the spacebar not being treated as expected, since it's specifically addressed by the DeadKey function.
User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Custom deadkeys

21 Apr 2021, 09:10

Please post your revised script.
berz
Posts: 18
Joined: 16 Apr 2021, 16:40

Re: Custom deadkeys

21 Apr 2021, 09:55

It's as in the original post.
User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Custom deadkeys

21 Apr 2021, 10:17

I'm not sure how you changed the script and also kept it the same. The revision below seemed to work.

Code: Select all

`::DeadKey("``")
+`::DeadKey("~")

DeadKey(sym) {
 Static TildeKeys := {a: "ã", Ax: "Ã", n: "ñ", Nx: "Ñ", o: "õ", Ox: "Õ",  i: "ĩ", Ix: "Ĩ", u: "ũ", Ux: "Ũ"
                    , b: "ᵬ",  d: "ᵭ", f: "ᵮ",  m: "ᵯ", n: "ᵰ",  p: "ᵱ",  r: "ᵲ",  s: "ᵴ", t: "ᵵ",  z: "ᵶ"
                    , e: "ẽ", Ex: "Ẽ", v: "ṽ", Vx: "Ṽ", y: "ỹ", Yx: "Ỹ", Lx: "Ɫ"}
 Static GraveKeys := {a: "à", Ax: "À", e: "è", Ex: "È", i: "ì", Ix: "Ì",  o: "ò", Ox: "Ò", u: "ù", Ux: "Ù"
                    , n: "ǹ", Nx: "Ǹ", y: "ỳ", Yx: "Ỳ"}
 Static DeadKeys  := {"~": TildeKeys, "``": GraveKeys}
 Input, Char, L1
 If (Char != " ") {
  Char .= (RegExMatch(Char, "[A-Z]") && DeadKeys[sym].HasKey(Char "x")) ? "x" : ""
  Send % "{Text}" (DeadKeys[sym].HasKey(Char) ? DeadKeys[sym][Char] : sym Char)
 } Else Send {Text}%sym%
}
berz
Posts: 18
Joined: 16 Apr 2021, 16:40

Re: Custom deadkeys

21 Apr 2021, 10:40

mikeyww wrote:
21 Apr 2021, 10:17
I'm not sure how you changed the script and also kept it the same. The revision below seemed to work.

Code: Select all

`::DeadKey("``")
+`::DeadKey("~")

DeadKey(sym) {
 Static TildeKeys := {a: "ã", Ax: "Ã", n: "ñ", Nx: "Ñ", o: "õ", Ox: "Õ",  i: "ĩ", Ix: "Ĩ", u: "ũ", Ux: "Ũ"
                    , b: "ᵬ",  d: "ᵭ", f: "ᵮ",  m: "ᵯ", n: "ᵰ",  p: "ᵱ",  r: "ᵲ",  s: "ᵴ", t: "ᵵ",  z: "ᵶ"
                    , e: "ẽ", Ex: "Ẽ", v: "ṽ", Vx: "Ṽ", y: "ỹ", Yx: "Ỹ", Lx: "Ɫ"}
 Static GraveKeys := {a: "à", Ax: "À", e: "è", Ex: "È", i: "ì", Ix: "Ì",  o: "ò", Ox: "Ò", u: "ù", Ux: "Ù"
                    , n: "ǹ", Nx: "Ǹ", y: "ỳ", Yx: "Ỳ"}
 Static DeadKeys  := {"~": TildeKeys, "``": GraveKeys}
 Input, Char, L1
 If (Char != " ") {
  Char .= (RegExMatch(Char, "[A-Z]") && DeadKeys[sym].HasKey(Char "x")) ? "x" : ""
  Send % "{Text}" (DeadKeys[sym].HasKey(Char) ? DeadKeys[sym][Char] : sym Char)
 } Else Send {Text}%sym%
}
I reverted all the changes I made when they didn't improve the script.

Anyway your version works, thank you! I think the key was the use of {Text}.

One more small thing: I noticed your code chops long lines. I tried doing the same with a different style I'm more used to (two examples:)

Code: Select all

static TildeKeys := {
        a: "ã",
        Ax: "Ã",
        n: "ñ",
        Nx: "Ñ",
        o: "õ",
        Ox: "Õ",
        i: "ĩ",
        Ix: "Ĩ",
        u: "ũ",
        Ux: "Ũ",
        b: "ᵬ",
        d: "ᵭ",
        f: "ᵮ",
        m: "ᵯ",
        n: "ᵰ",
        p: "ᵱ",
        r: "ᵲ",
        s: "ᵴ",
        t: "ᵵ",
        z: "ᵶ",
        e: "ẽ",
        Ex: "Ẽ",
        v: "ṽ",
        Vx: "Ṽ",
        y: "ỹ",
        Yx: "Ỹ",
        Lx: "Ɫ"
}
and

Code: Select all

static TildeKeys := {a: "ã", Ax: "Ã",
                         n: "ñ", Nx: "Ñ",
                         o: "õ", Ox: "Õ",
                         i: "ĩ", Ix: "Ĩ",
                         u: "ũ", Ux: "Ũ",
                         b: "ᵬ", d: "ᵭ",
                         f: "ᵮ", m: "ᵯ",
                         n: "ᵰ", p: "ᵱ",
                         r: "ᵲ", s: "ᵴ",
                         t: "ᵵ", z: "ᵶ",
                         e: "ẽ", Ex: "Ẽ",
                         v: "ṽ", Vx: "Ṽ",
                         y: "ỹ", Yx: "Ỹ",
                         Lx: "Ɫ"}
But I get the error "this line does not contain a recognized action". What is the trick here? Must the comma be brought to the next line or is there a way to avoid it?
berz
Posts: 18
Joined: 16 Apr 2021, 16:40

Re: Custom deadkeys

21 Apr 2021, 13:18

Brilliant, thank you.

I'd like to optimise the script as much as possible so I set #KeyHistory to 0. Is there anything else I could do to make the script as fast as possible?
User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Custom deadkeys

21 Apr 2021, 13:28

Some people use SetBatchLines or change the process priority. I do not necessarily recommend those approaches, but they are up to you. Enjoy!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Araphen, Descolada, Google [Bot], Oblomov228 and 175 guests