AHK 和 US-INT 键盘:为什么不再吞下 "dead" 键?
AHK and US-INT keyboard: Why are "dead" keys no longer swallowed?
我通常使用美国-国际键盘布局。此布局有几个键设置为变音符号的“死”键 - 例如,按 ^ 是死键;在按下下一个键之前它似乎什么都不做;如果该键是一个音调符号是允许的变音符号,它将用标记的键替换它 - 也就是说,如果我按 ^ 然后 a ,我会得到 â - 但是如果我按下一个不允许使用变音符号的键,我会得到抑扬符后跟字母,例如 ^ 后面跟着 h 给我 ^h.
我写了一个 AHK 脚本,它添加了世界语的变音字符(见下文)。它曾经“透明地”工作并符合上述行为。但是,最近,行为似乎发生了变化:它不再“吞下”变音符号,而是在插入所需字符之前插入一个后退space。
换句话说,如果我输入“The Esperanto character that sounds like English 'ch' is” 然后输入 ^ 然后 c,它 将 后面的 space 替换为 ĉ,并且在下一次击键时,无论它是什么,就像我按下 ^ 然后那个键一样。
为什么?以及如何解决这个问题?
#Hotstring ? C *
; Esperanto diacriticalized characters
::^c::ĉ
::^C::Ĉ
::^g::ĝ
::^G::Ĝ
::^h::ĥ
::^H::Ĥ
::^j::ĵ
::^J::Ĵ
::^s::ŝ
::^S::Ŝ
::~u::ŭ
::~U::Ŭ
不知道我是否可能错过了一些简单的热字串,但如果不尝试做一些更进一步的诡计,我无法真正让它工作。
我认为 InputHook
(docs) 实现可以很好地工作。
不过它可能是 overkill/stupid,因为它基本上只是为热字串创建自定义实现。但是好吧,至少它有效。
key_map := { "c": "ĉ"
, "g": "ĝ"
, "h": "ĥ"
, "j": "ĵ"
, "s": "ŝ"
, "u": "ŭ" }
ih := InputHook("V")
ih.OnChar := Func("OnChar")
ih.Start()
OnChar(_, char)
{
if (StrLen(char) != 2 || SubStr(char, 1, 1) != "^" || !(key := diacriticalize(SubStr(char, 2))))
return
fObj := Func("SendReplacement").Bind(key)
SetTimer, % fObj, -0
}
diacriticalize(key)
{
global key_map
if key is upper
return Format("{:U}", key_map[key])
else
return key_map[key]
}
SendReplacement(key)
{
SendInput, % "{BS 2}" key
}
发生了什么事?
首先定义密钥替换映射。
为 ^
添加任何额外的死键组合都可以正常工作。
输入挂钩仅使用 V
(docs) 选项创建。
这使得它在处理输入时不会消耗输入。
然后,使用 .OnChar
(docs) 我们定义一个函数,每次输入接收到一个新字符时 运行s。
这些函数总是只接收一个字符,除非使用死键时它会接收例如 ^c
.
这就是为什么我们检查输入长度是否为二以及为什么我们使用 SubStr()
(docs) 将 ^c
转换为 c
的原因。
SubStr(char, 1, 1) != "^"
还确保按下的死键是 ^
,而不是 ¨
。否则 ¨c
会产生 ĉ
.
然后在用户定义的函数 diacriticalize()
中,我们 return 来自 key_map
的相应变音键(如果可能)。如果输入键是大写的,return 变音键也是大写的。
如果 key_map
中没有匹配的键,则不会 returned。如果输入键无效,这使得 || !(key := ...)
部分也会 return 发挥作用。
然后计时器(docs) 欺骗只是为了在另一个线程中执行 OnChar()
函数之外的替换以避免发送命令出现问题 运行太早了。
基本上句号 -0
只是意味着立即 运行 一次。
定时器将被定义为一个函数对象,它有一个参数(键)绑定到它 .Bind()
(docs).
好的,我不确定为什么它以这种方式工作,但我可以通过关闭自动退格并手动添加我自己的来让它工作。修改后的AHK脚本如下:
#Hotstring ? C * B0
; Acts only as a supplement to a keyboard that (a) does not
; have these characters defined _and_ uses ^ and ~ as "dead"
; keys to apply accents.
::^c::{bs 2}ĉ
::^C::{bs 2}Ĉ
::^g::{bs 2}ĝ
::^G::{bs 2}Ĝ
::^h::{bs 2}ĥ
::^H::{bs 2}Ĥ
::^j::{bs 2}ĵ
::^J::{bs 2}Ĵ
::^s::{bs 2}ŝ
::^S::{bs 2}Ŝ
::~u::{bs 2}ŭ
::~U::{bs 2}Ŭ
::^::^
::~::~
#Hotstring
指令中的 B0
关闭自动退格。如果该选项在原始脚本中生效,键入 ^c 将导致 ^cĉ
,因此通过向后插入两个 spaces 在它之前 ({bs 2}
),我在插入 ĉ
.
之前去掉了多余的 ^c
最后两行,将插入符和代字号替换为它们自己,对于需要它们的原因没有明显的解释,但它们确保行为与标准死键用法一致,因此如果我输入 ^spacec 我得到预期的 ^c
意想不到的 ĉ
.
我通常使用美国-国际键盘布局。此布局有几个键设置为变音符号的“死”键 - 例如,按 ^ 是死键;在按下下一个键之前它似乎什么都不做;如果该键是一个音调符号是允许的变音符号,它将用标记的键替换它 - 也就是说,如果我按 ^ 然后 a ,我会得到 â - 但是如果我按下一个不允许使用变音符号的键,我会得到抑扬符后跟字母,例如 ^ 后面跟着 h 给我 ^h.
我写了一个 AHK 脚本,它添加了世界语的变音字符(见下文)。它曾经“透明地”工作并符合上述行为。但是,最近,行为似乎发生了变化:它不再“吞下”变音符号,而是在插入所需字符之前插入一个后退space。
换句话说,如果我输入“The Esperanto character that sounds like English 'ch' is” 然后输入 ^ 然后 c,它 将 后面的 space 替换为 ĉ,并且在下一次击键时,无论它是什么,就像我按下 ^ 然后那个键一样。
为什么?以及如何解决这个问题?
#Hotstring ? C *
; Esperanto diacriticalized characters
::^c::ĉ
::^C::Ĉ
::^g::ĝ
::^G::Ĝ
::^h::ĥ
::^H::Ĥ
::^j::ĵ
::^J::Ĵ
::^s::ŝ
::^S::Ŝ
::~u::ŭ
::~U::Ŭ
不知道我是否可能错过了一些简单的热字串,但如果不尝试做一些更进一步的诡计,我无法真正让它工作。
我认为 InputHook
(docs) 实现可以很好地工作。
不过它可能是 overkill/stupid,因为它基本上只是为热字串创建自定义实现。但是好吧,至少它有效。
key_map := { "c": "ĉ"
, "g": "ĝ"
, "h": "ĥ"
, "j": "ĵ"
, "s": "ŝ"
, "u": "ŭ" }
ih := InputHook("V")
ih.OnChar := Func("OnChar")
ih.Start()
OnChar(_, char)
{
if (StrLen(char) != 2 || SubStr(char, 1, 1) != "^" || !(key := diacriticalize(SubStr(char, 2))))
return
fObj := Func("SendReplacement").Bind(key)
SetTimer, % fObj, -0
}
diacriticalize(key)
{
global key_map
if key is upper
return Format("{:U}", key_map[key])
else
return key_map[key]
}
SendReplacement(key)
{
SendInput, % "{BS 2}" key
}
发生了什么事?
首先定义密钥替换映射。
为 ^
添加任何额外的死键组合都可以正常工作。
输入挂钩仅使用 V
(docs) 选项创建。
这使得它在处理输入时不会消耗输入。
然后,使用 .OnChar
(docs) 我们定义一个函数,每次输入接收到一个新字符时 运行s。
这些函数总是只接收一个字符,除非使用死键时它会接收例如 ^c
.
这就是为什么我们检查输入长度是否为二以及为什么我们使用 SubStr()
(docs) 将 ^c
转换为 c
的原因。
SubStr(char, 1, 1) != "^"
还确保按下的死键是 ^
,而不是 ¨
。否则 ¨c
会产生 ĉ
.
然后在用户定义的函数 diacriticalize()
中,我们 return 来自 key_map
的相应变音键(如果可能)。如果输入键是大写的,return 变音键也是大写的。
如果 key_map
中没有匹配的键,则不会 returned。如果输入键无效,这使得 || !(key := ...)
部分也会 return 发挥作用。
然后计时器(docs) 欺骗只是为了在另一个线程中执行 OnChar()
函数之外的替换以避免发送命令出现问题 运行太早了。
基本上句号 -0
只是意味着立即 运行 一次。
定时器将被定义为一个函数对象,它有一个参数(键)绑定到它 .Bind()
(docs).
好的,我不确定为什么它以这种方式工作,但我可以通过关闭自动退格并手动添加我自己的来让它工作。修改后的AHK脚本如下:
#Hotstring ? C * B0
; Acts only as a supplement to a keyboard that (a) does not
; have these characters defined _and_ uses ^ and ~ as "dead"
; keys to apply accents.
::^c::{bs 2}ĉ
::^C::{bs 2}Ĉ
::^g::{bs 2}ĝ
::^G::{bs 2}Ĝ
::^h::{bs 2}ĥ
::^H::{bs 2}Ĥ
::^j::{bs 2}ĵ
::^J::{bs 2}Ĵ
::^s::{bs 2}ŝ
::^S::{bs 2}Ŝ
::~u::{bs 2}ŭ
::~U::{bs 2}Ŭ
::^::^
::~::~
#Hotstring
指令中的 B0
关闭自动退格。如果该选项在原始脚本中生效,键入 ^c 将导致 ^cĉ
,因此通过向后插入两个 spaces 在它之前 ({bs 2}
),我在插入 ĉ
.
^c
最后两行,将插入符和代字号替换为它们自己,对于需要它们的原因没有明显的解释,但它们确保行为与标准死键用法一致,因此如果我输入 ^spacec 我得到预期的 ^c
意想不到的 ĉ
.