Я получаю новую записную книжку Windows 10, в то время как я долго запускал MBP. В MacO я использую US Intl kezmap и мне очень нравятся ярлыки для написания умлаутов на немецком языке.

В MacOS я использую {RAlt} + {u}, а затем {a}, {o}, {u} или {s}, чтобы написать соответствующий немецкий Umlaut. Чтобы написать верхний регистр умлаут, я должен нажать {Shift} + {a}, {o} или {u}.

Я пытаюсь написать скрипт AHK, чтобы воспроизвести это поведение, но, к сожалению, у меня нет успеха.

В настоящее время я создал это.

;Umlaut
#Persistent

    RAlt & a::
        GetKeyState, state, Shift
        if state = U
        SendInput {ASC 0228}            ;RAlt+a = lower case a-umlaut
        else Send, {ASC 0196}           ;RAlt+Shift+a = UPPER CASE A-umlaut
    return

    RAlt & o:: 
        GetKeyState, state, Shift
        if state = U
        SendInput {ASC 0246}            ;RAlt+o = lower case o-umlaut
        else Send, {ASC 0214}           ;RAlt+Shift+o = UPPER CASE O-umlaut
    return

    RAlt & u:: 
        GetKeyState, state, Shift
        if state = U
        SendInput {ASC 0252}            ;RAlt+u = lower case u-umlaut
        else Send, {ASC 0220}           ;RAlt+Shift+u = UPPER CASE U-umlaut
    return

    RAlt & s:: Send, {ASC 0223}     ;RAlt+s = RAlt+s, Eszett
    return

Это работает, но я действительно хочу комбинации клавиш, описанные выше. Как я могу достичь этой цели?

1
Christian Meißner 18 Апр 2020 в 00:32

2 ответа

Лучший ответ

Во-первых, чтобы исправить код, увиденный в оригинальном посте, он довольно унаследован и использует много странных подходов. Чтобы перечислить и исправить все из них:

#Persistent для нас ничего не делает. Здесь бесполезно.

Ярлыки горячих клавиш типа RAlt & key:: должны использовать модификаторы и выглядеть следующим образом >!key::.
>! означает «прямо».

Использование устаревшей GetKeyState команды следует заменить на GetKeyState().
Хотя на самом деле это вообще не нужно. Модификатор горячей клавиши shift + должен использоваться просто так:

>!a::SendInput, ä
>!+a::SendInput, Ä
>!o::SendInput, ö
>!+o::SendInput, Ö
>!u::SendInput, ü
>!+u::SendInput, Ü
>!s::SendInput, ß

Я также отказался от использования кодов ASC, так как не вижу причин использовать их.
Я думаю, это сделало бы файл сценария более гибким для сохранения в более примитивной кодировке, но да.

Итак, этот код в вашем посте сделан правильно.


А теперь, чтобы реализовать то, что вы на самом деле хотели сделать:
Нажатие RAlt + u входит в режим ввода умляута .

Самый простой способ сделать это, о котором я могу подумать, - это просто создать контекстно-зависимые горячие клавиши с помощью #If.
Обычно я бы не рекомендовал использовать #If в AHK v1 из-за его недостатков (как задокументировано в документации), но для такого маленького сценария это более чем нормально. И это делает это намного проще и аккуратнее.

Итак, сначала давайте создадим горячую клавишу RAlt + u, которая устанавливает состояние некоторой переменной равным true:

>!u::UmlautTypingMode := true

Then we can create context sensitive hotkeys by always first checking the value of that variable:
>!u::UmlautTypingMode := true

#If, UmlautTypingMode ;start context sensitive hotkeys (if the variable value evaluates to true)
a::
    SendInput, ä
    UmlautTypingMode := false
return
+a::
    SendInput, Ä
    UmlautTypingMode := false
return
o::
    SendInput, ö
    UmlautTypingMode := false
return
+o::
    SendInput, Ö
    UmlautTypingMode := false
return
<!u::return
u::
    SendInput, ü
    UmlautTypingMode := false
return
+u::
    SendInput, Ü
    UmlautTypingMode := false
return
s::
    SendInput, ß
    UmlautTypingMode := false
return
#If ;end context sensitive hotkeys

Как видите, нам, к сожалению, пришлось избавиться от этих приятных, чистых однострочных горячих клавиш, начиная с false каждый раз, и завершать выполнение кода с return.
Конечно, это может быть сжато с некоторыми более продвинутыми AHK, но я буду держать это простым.
И маленькая маленькая <!u::return строка внутри, чтобы начальный пресс RAlt + u не создавал ü.


Так и должно быть. Хорошо работает с моей стороны, по крайней мере.
Тем не менее, я только сейчас понял, что с "{RAlt} + {u}, за которым следует {a}, {o}, {u} или {s}" , вы могли иметь в виду, что вы ' Продолжайте печатать умляуты до тех пор, пока удерживается RAlt. Если это так, код нуждается в некоторой корректировке.
Прямо сейчас вы нажимаете и отпускаете RAlt + u, чтобы войти в режим ввода умляута .


Наконец, в качестве бонуса приведен код, сжатый до одной строки.
Я знаю, это глупо, я просто не мог устоять, я люблю делать эти хаха.

>!u::UmlautTypingMode := true
#If, UmlautTypingMode
a::
+a::
o::
+o::
u::
+u::
s::SendInput, % ((A_ThisHotkey = "s"), UmlautTypingMode := false) ? "ß" : ("¨" ((A_ThisHotkey ~= "\+") ? Format("{:U}", SubStr(A_ThisHotkey, 0)) : SubStr(A_ThisHotkey, 0)))
>!u::return
#If

Кроме того, не знаю, будет ли это работать на разных раскладках клавиатуры.
У меня работает по крайней мере.


< Сильный > EDIT :
Запрошенный тайм-аут был комментариями. Их очень легко и удобно сделать с помощью таймера. Итак, мы изменили нашу горячую клавишу >!u::UmlautTypingMode := true на следующую:

>!u::
    UmlautTypingMode := true
    SetTimer, Timeout, -2000
return

Отрицательное число в периоде таймера означает, что он работает один раз после 2000 мс.

И теперь мы, конечно, должны также создать метку (или функцию, я буду использовать метку здесь, чтобы сделать ее более простой) с именем Timeout (это не встроенная вещь, мы могли бы использовать любое имя здесь ) .

Timeout:
    UmlautTypingMode := false
return

Эта метка может быть размещена, например, в нижней части скрипта.

1
0x464e 18 Апр 2020 в 12:27

Я бы предпочел немного другой подход к вводу: введите букву, а затем используйте скрипт, который заменяет последний символ слева от курсора.
Я сделал это, когда много работал с немецкими текстами и оказался более эффективным по сравнению с методом, который вы описали. Также можно заменить символы, которые уже есть в тексте, просто поместив курсор на них и нажав ту же горячую клавишу.

Вот

dict := ComObjCreate("Scripting.Dictionary")
dict.Add("a", "ä")
dict.Add("A", "Ä")
dict.Add("o", "ö")
dict.Add("O", "Ö")
dict.Add("u", "ü")
dict.Add("U", "Ü")

>!u::
    temp :=  clipboard  ; backup clipboard
    send +{left}
    send ^{insert}
    sleep 100
    c :=  clipboard
    found := false
    for key in dict {
        if (key==c) {
            v := dict.item[key]
            found := true
            send %v%
        }
    }
    if (found=false) {
        send {right}
        ; tooltip key not found
    }
    clipboard = %temp%
return
0
Mikhail V 19 Апр 2020 в 12:02