你需要的东西绝对可以用 AutoHotkey 来完成。
棘手的部分是:您需要动态分配热键和Hotstrings。前者可以通过Hotkey-command 实现,后者尚未实现,可能永远不会实现。
您可以将它们写入新的 .ahk 文件并单独执行该脚本,或者使用 polyethene's really awesome dynamical regEx hotstring creator。 autohotkey.net 的存储库已经关闭多年,但我找到了脚本here。
要运行以下示例脚本,您需要将该脚本下载到 Hotstrings.ahk 并将其放在主 .ahk 文件所在的同一目录中。
但是,我无法将布局更改器热键分配给
`
,所以我将它设置为ä。
我知道这个网站不是代码提供者网络,但我对这个问题也很感兴趣。
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#include Hotstrings.ahk
lastKey := ""
; KEYS OF THE NORMAL LAYOUT WHICH SHOULD BE NEGATABLE:
hotstrings("=", "_equals") ;
; CHOOSE LAYOUT OR NEGATE/EXPAND LAST CHARACTER:
:*?:ä::
; backSpacePressed: ; wtf is this? sorry just saw this now. Does not belong here, does not belong anywhere
sendRaw *
tooltip,
(
n normal layout
s set theory
r general math
x negate previous
w expand previous
{esc} cancel
), %A_CaretX%, %A_CaretY%
input, layout, L1, {Escape}, s,r,e,g,x,w
send {Backspace} ; remove the *
if layout in n,s,r,e,g,x,w
{
tooltip, %layout%, %A_CaretX%, %A_CaretY%
; RESET
if layout = n
{
reset_all_hotstrings()
; KEYS OF THE NORMAL LAYOUT WHICH SHOULD BE NEGATABLE:
hotstrings("=", "_equals")
}
; NEW LAYOUT
else if layout = s
{
reset_all_hotstrings()
; SET THEORY SHORTCUTS
hotstrings("o", "_emptySet")
hotstrings("\[", "_elementOf")
}
else if layout = r
{
reset_all_hotstrings()
; MATH SHORTCUTS
hotstrings("s", "_integral")
hotstrings("S", "_doubleIntegral")
hotstrings("=", "_identical")
}
; and so on
; ...
; EDIT PREVIOUS CHARACTER
else if layout = x
{
send {backSpace}
if lastKey = identical
sendUnicodeChar(0x2262)
else if lastKey = equals
sendUnicodeChar(0x2260)
}
; EXPAND PREVIOUS CHARACTER
else if layout = w
{
send {backSpace}
if lastKey = integral
sendUnicodeChar(0x222D)
else if lastKey = doubleIntegral
sendUnicodeChar(0x2A0C)
}
}
else
{
tooltip, cancelled, %A_CaretX%, %A_CaretY%
}
sleep, 500
tooltip
return
reset_all_hotstrings() {
hotstrings("=")
hotstrings("\[")
hotstrings("o")
hotstrings("s")
hotstrings("S")
; and so on
}
; NORMAL LAYOUT SHORTCUTS:
_equals:
sendUnicodeChar(0x003D)
lastKey = equals
return
; SPECIAL LAYOUT SHORTCUTS:
_emptySet:
;sendUnicodeChar(0x00D8)
altNumpad(0216)
; to find out numpad combination or unicode: press WIN+R, type in "charmap"
; or for unicode only, go to http://www.fileformat.info/info/unicode/category/index.htm
; (sendUnicodChar() needs 0x before the unicode string)
;altNumpad(0248)
;send Ø
;send ø
; choose whatever works best for you
lastKey = emptySet
return
_elementOf:
sendUnicodeChar(0x2208)
lastKey = elementOf
return
_integral:
sendUnicodeChar(0x222B)
lastKey = integral
return
_identical:
sendUnicodeChar(0x2261)
lastKey = identical
return
_doubleIntegral:
sendUnicodeChar(0x222C)
lastKey = doubleIntegral
return
; -------------------------------------------
altNumpad(numbers) {
stringSplit, n, numbers
setkeydelay, 100
send {alt down}
loop, %n0%
{
t := n%a_index%
send {numpad%t%}
}
send {alt up}
}
SendUnicodeChar(charCode)
{
VarSetCapacity(ki, 28 * 2, 0)
EncodeInteger(&ki + 0, 1)
EncodeInteger(&ki + 6, charCode)
EncodeInteger(&ki + 8, 4)
EncodeInteger(&ki +28, 1)
EncodeInteger(&ki +34, charCode)
EncodeInteger(&ki +36, 4|2)
DllCall("SendInput", "UInt", 2, "UInt", &ki, "Int", 28)
}
EncodeInteger(ref, val)
{
DllCall("ntdll\RtlFillMemoryUlong", "Uint", ref, "Uint", 4, "Uint", val)
}
^e::reload
显然还有很大的改进空间