Как реализовать Macos-подобное (EN Intl) поведение немецкого умлаута? - PullRequest
0 голосов
/ 18 апреля 2020

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

В MacOS я использую {RAlt} + {u}, за которыми следуют {a}, {o}, {u} или {s} написать соответствующий немецкий умлаут. Для написания умляута в верхнем регистре я должен нажать {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

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

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

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

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

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

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

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

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

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


А теперь, чтобы реализовать то, что вы на самом деле хотели сделать:
Нажатие 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, чтобы войти в режим ввода umlaut .


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

>!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

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


РЕДАКТИРОВАТЬ:
A Запрошенный тайм-аут был комментариями. Их очень легко и удобно делать с таймером . Итак, мы изменили нашу горячую клавишу >!u::UmlautTypingMode := true на это:

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

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

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

Timeout:
    UmlautTypingMode := false
return

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

0 голосов
/ 19 апреля 2020

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

Вот оно

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
...