分享:让ahk的按键绑定在emacs中失效

经论坛用户推荐,我决定怎么也要把ahk用起来,第一步就是把日常使用的ctrl+c,ctrl+v给换掉,面临一个问题是会和emacs有冲突,比如说我绑定了alt+w作copy,然后emacs里我自定义的alt-w就没用了,c-h c查一下,在emacs里按alt+w显示我按的是’c-c’。

问chatGPT与各种搜索给出的代码发现都不能直接使用,经过各种试错,终于调试出一段有效代码,欢迎指正。

$!w::alt_w() ;;copy 这里前面必须有$号,否则会有未知问题
$!1::alt_1() ;;paste
alt_w(){
    if WinActive("ahk_class Emacs"){
        Send "!w"  ;;把按键发送给emacs
    }else{
        Send "^c"
    }
}
alt_1(){
    if WinActive("ahk_class Emacs"){
        Send "!1"
    }else{
        Send "^v"
    }
}

搭车说下,这个 winactive 如何能唯一地激活一个进程一直没搞懂

研究很久的结果是可以 winactive ahk.exe yourapp.exe 但有时也会失效,不明就里

我也不明白,于是写成了每个键绑定都先调用一次 winActive()

安装ahk的时候会附带一个WindowSpy.ahk,这个工具可以很方便的获取窗口的信息,比如当鼠标指向Emacs时,第一栏会显示:

*scratch* - GNU Emacs
ahk_class Emacs
ahk_exe emacs.exe
ahk_pid 12856

正好对应了 WinActive 的四种语法:标题、ahk_class、进程名、pid,一般用 ahk_classahk_exe 就可以唯一激活一个进程了。

至于标题里提到的排除某个程序,把绑定快捷键相关的代码写到 #IfNotWinActive 下就行了

我也贴一个。我是这种需要: 一个外接键盘,通过键盘自身的qmk设置了键映射,比如ctrl和CapsLock。。。 还有笔记本本身的键盘,也需要键映射。一会用外接键盘,一会儿用笔记本键盘。这样如果用ahk配置键盘的话,就会冲突混乱。

所以我把左边的windows键设置成了切换键。双击一下,它就切换到另一套配置。比如现在要用外接键盘了,就双击一下windows键。它就不用笔记本那套映射了。。。

很简单,但是感觉很有用。

~LWin::
    keyWait, LWin
	if IsDoubleClick() {
		RemapKeys := !RemapKeys
        MsgBox keyboard map toggled!
	}
return

#If RemapKeys
    CapsLock::LCtrl      ; 交换ctrl和大小写
    LCtrl::Shift         ; 左ctrl用作shift,来切换输入法中英文,频繁操作,和mac一致
    RCtrl::CapsLock      ; 右ctrl用作,大小写锁定,和mac一致

    ; LWin & Tab::AltTab    ; Win + tab 也和 alt + tab 一样切换应用,和mac一致
    ; RAlt::LAlt            ; 两边的alt 在emacs中都一致,这个无需设置,本来就一样
#If

IsDoubleClick() {
	static doubleClickTime := DllCall("GetDoubleClickTime")
	KeyWait, % LTrim(A_ThisHotkey, "~")
	return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey <= doubleClickTime)
}

精简一下,可以测试以下有没问题(适用ahk1版本):

#if !WinActive(“ahk_class Emacs”)

!w::send ^c

!1::send ^v

#if

winactive顾名思义,是指窗口,不是指进程

这段测试过不行,我用的是ahk2版本

搜索了一下V2的语法,你换下面试试

#HotIf WinActive(“ahk_class Emacs”)

!w::send “^c”

!1::send “^v”

#HotIf

你这个就是我前面提到的: emacs里我自定义的alt-w就没用了,c-h c 查一下,在emacs里按alt+w显示我按的是’c-c’ , 把这个!w::send “^c”写在#开头的指令的外面也是一样的结果,emacs里还是显示我alt+w是按的c-c

“emacs里我自定义的alt-w”

这个定义是在哪,emacs配置文件,还是ahk

我明白了,应该这样写

#HotIf WinActive("ahk_class Emacs")
$!w::Send "!w" ;;把按键原样发送给emacs

#HotIf

!w::send "^c"

image

这段指的就是我没有选中任何文字时按m-w就复制一整行,有选中就复制选中的

不好意思,刚才弄错了,第一行条件判断应该要加个!表示否

#HotIf !WinActive(“ahk_class Emacs”)

!w::send “^c”

!1::send “^v”

#HotIf

还真是…,感谢指正