Skip to content

Instantly share code, notes, and snippets.

@aeghn
Last active April 18, 2023 05:47
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aeghn/0b5db63c3d4290fa487aa48ab7f1264c to your computer and use it in GitHub Desktop.
Save aeghn/0b5db63c3d4290fa487aa48ab7f1264c to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Author: Aeghn
# A script for buffer switching between emacs buffers, firefox tabs and other windows.
# dependences: jq i3 qutebrowser emacs
# set -eo pipefail
# QUTEBROWSER_SESSION_FILE="/tmp/qutebrowser_buffers_zsbd"
# QUTEBROWSER_SOCKET_FILE="${XDG_RUNTIME_DIR}/qutebrowser/ipc-$(echo -n "$USER" | md5sum | cut -d' ' -f1)"
# BUFFERSWITCH_TEMP_FILE="/tmp/bufferswitch_temp_zsbd"
emacsclient="$HOME/.local/bin/emacsclient"
#emacsclient="emacsclient"
get_emacs_daemon_buffers() {
ls /run/user/1000/emacs -I chinbox | while read line; do
echo -e $($emacsclient --socket-name=$line -e '
(progn
(setq-default return-buffer "\n")
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(let* ((name (buffer-name)))
(when (not (string= (substring name 0 1) " "))
(setq return-buffer (concat return-buffer "ee | " name "\\0meta\\x1f" chin/emacs-load-mode " " default-directory "\\x1finfo\\x1fee " chin/emacs-load-mode " " name "\n"))))))
return-buffer)')
done
}
# get_qutebrowser_buffers() {
# echo '{"args":[":save-window-and-buffers"], "target_arg":"", "protocol_version":1}' |\
# socat - UNIX-CONNECT:"$QUTEBROWSER_SOCKET_FILE"
# for((i=0; i<5; i++)); do
# [ -f $QUTEBROWSER_SESSION_FILE ] && break || sleep 0.01
# done
# cat "$QUTEBROWSER_SESSION_FILE" | sed "s/^/ff /g"
# i3-msg "[title=\"CHin_bufferswitch\"] focus" &> /dev/null
# }
get_firefox_buffers() {
dbus-send --session --print-reply\
--dest=me.wangz.BrowserTabs\
/me/wangz/BrowserTabs me.wangz.BrowserTabs.tabs\
| sed -e '1d' -e 's/^[ ]*string "//g' -e 's/"$//g'\
| jq -r '.[] | "ff | \(.title)\\0meta\\x1f \(.url)\\x1finfo\\x1fff \(.id)\\n"'
}
get_windows() {
# wmctrl -l | awk "{\$1=\$3=\"\"; sub(/^ \-1/, \" d\"); sub(/^ /,\"d\"); print}"
i3-msg -t get_tree |\
jq -r '.nodes[].nodes[] | recurse(.nodes[], .floating_nodes[]) | select(.type == "workspace", .type == "con")|.num, .window_properties.class, .name, .window' |\
awk '{ line=NR%4;
if (line == "1") {skip=0; if ($1 == "-1") ws="ii"; else if ($1 != "null") ws="i"$1 }
else if (line == "2" && $1 ~ "null|i3bar|TelegramDesktop") { skip=1 }
else if (line == "2" && $1 != "null") { class=$0 }
else if (line == "3" && $1 ~ "Chin_.*") { skip=1 }
else if (line == "3" && skip != 1) { title=$0 }
else if (line == "0" && skip != 1) { printf("%s | %s\\0meta\\x1f%s\\x1finfo\\x1fii %s\\n\n", ws, title, class, $1) }
}'
}
get_all_objects() {
if [ -n "${ROFI_INFO}" ]; then
pkill rofi
exit
fi
get_windows
get_emacs_daemon_buffers
get_firefox_buffers
}
trim_list() {
sed -r '/^[ \t"]*$/d'
}
echo -en "$(get_all_objects | trim_list)"
try_to_switch() {
local type="${1%% *}"
local id="${1#* }"
case "$type" in
ff) firefox_switch_buffer "${id}";;
# ff) qutebrowser_switch_buffer "${_title%:*}" ;;
ee) emacs_switch_buffer "${id}" ;;
ii) i3_focus_id "${id}";;
*) : ;;
esac
}
# qutebrowser_switch_buffer() {
# local _id _title
# _id="${@%% *}"
# _title="${@#* }"
# echo "{\"args\":[\":buffer ${_id}\"], \"target_arg\":\"\", \"protocol_version\":1}" |\
# socat - UNIX-CONNECT:"${QUTEBROWSER_SOCKET_FILE}"
# i3_focus_class "qutebrowser"
# }
emacs_switch_buffer() {
local socket="${1%% *}"
local id="${1#* }"
$emacsclient --socket-name=$socket -e "(progn (switch-to-buffer \"$id\")(x-focus-frame (selected-frame)))"
i3_focus_class "Emacs"
}
firefox_switch_buffer() {
# Thanks to https://github.com/cubimon/dbus-tabs
local _id="$1"
dbus-send --session --print-reply --dest=me.wangz.BrowserTabs /me/wangz/BrowserTabs me.wangz.BrowserTabs.activate uint64:$_id
i3_focus_class "[Ff]irefox"
}
i3_focus_class() {
for((i=0; i<3; i++)); do
i3-msg "[class=\"$1\" urgent=latest] focus" && return || sleep 0.1
done
}
i3_focus_id() {
local id=$1
for((i=0; i<3; i++)); do
i3-msg "[id=\"${id}\"] focus" &> /dev/null && return || sleep 0.1
done
}
if [ -n "${ROFI_INFO}" ]; then
try_to_switch "${ROFI_INFO}"
fi
# Temporarily drop the qutebrowser part
from qutebrowser.utils import objreg
from qutebrowser.api import interceptor, cmdutils
@cmdutils.register()
def save_window_and_buffers():
"""
Save buffer list
like:
window_id/buffer_id buffer_title
"""
qbuffers = open('/tmp/qutebrowser_buffers_zsbd', "w")
print_buffers = ''
for windows_id in objreg.window_registry:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=windows_id)
for buffer_id in range(tabbed_browser.widget.count()):
print_buffers = print_buffers+str(windows_id)+'/'+str(buffer_id+1)+' '+str(tabbed_browser.widget.widget(buffer_id).title())+'\n'
qbuffers.write(str(print_buffers))
qbuffers.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment