给萌新解释下,哈! 在 Emacs 里面,一个新的窗口叫做 Frame, 打开一个窗口,里面的面板叫做 Window,别搞错。如果你像我一样,在使用 Wayland + GNOME 4.5, 而且,Emacs 在 GUI 模式下使用(典型的,首先启动一个 daemon, 然后使用 emacsclient 连接到它),那么这篇文章的的技巧适合你。
这个脚本基于下面这个 GNOME extension, 以及命令行工具 jq 必须是可用的。
脚本1, wayland_activate_window, 用来激活指定 id 的 window,这里的 id 是 wayland 下的 windows id.
id=$1
gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell/Extensions/Windows --method org.gnome.Shell.Extensions.Windows.Activate $id
脚本2, switch_to_wayland
class_type=$1
initalize_command=${2}
command=${3-true}
ids_and_classes_in_current_workspace=$(gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell/Extensions/Windows --method org.gnome.Shell.Extensions.Windows.List |gdbus_json | jq -e -c '[.[] | select (.in_current_workspace == true and .frame_type == 0 and .window_type == 0) | {id: .id,wm_class: .wm_class,focus: .focus,pid: .pid}]')
read -r CURRENT_WND_ID CURRENT_WND_PID CURRENT_WND_CLASS <<< "$(echo "$ids_and_classes_in_current_workspace" |jq -j '.[] |select (.focus == true) |.id," ",.pid," ",.wm_class')"
if [[ $CURRENT_WND_CLASS != $class_type ]]; then
id=$(echo "$ids_and_classes_in_current_workspace" |jq -e -c ".[] |select (.wm_class == \"$class_type\") |.id" |head -n1)
if [ "$id" ]; then
wayland_activate_window $id && $command
else
exec $initalize_command
fi
fi
扔上面两个脚本到 $PATH 里,并改为可执行,用法如下:
switch_to_wayland “窗口类名称” “第一次运行执行的命令” “随后运行执行的命令(可选的)”
例如:
$: switch_to_wayland "emacs" "emacsclient -nc $@" "emacsclient -n $@"
第一次使用,会使用 emacsclient -nc 1.txt 打开一个新的 frame, 随后的使用,就会复用存在的 frame.