summaryrefslogtreecommitdiff
path: root/bin/emacsclient
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2023-01-14 11:14:23 -0700
committerSean Whitton <spwhitton@spwhitton.name>2023-01-14 11:14:26 -0700
commita7b8b3844b1b928664417240f366abd9c559b701 (patch)
treeb40feec61875d21f4cf5d29cfa145e84d592943e /bin/emacsclient
parentd20293daac22dbf9e421001bdc42d80fe2688b9c (diff)
downloaddotfiles-a7b8b3844b1b928664417240f366abd9c559b701.tar.gz
emacsclient wrapper: C-i E handles case where primary daemon wedged
Diffstat (limited to 'bin/emacsclient')
-rwxr-xr-xbin/emacsclient94
1 files changed, 52 insertions, 42 deletions
diff --git a/bin/emacsclient b/bin/emacsclient
index fe9335a5..a6c6cb14 100755
--- a/bin/emacsclient
+++ b/bin/emacsclient
@@ -81,8 +81,8 @@ eval set -- "$getopt"
get_listener () {
local socket="$1"
- local listener=$(ss -Hplx src "$socket" \
- | perl -wne'/pid=(\d+)/ and print $1')
+ local listener=$(ss -plx src "$socket" \
+ | perl -wne'$tmp = $_; END { $tmp =~ /pid=(\d+)/ and print $1 }')
if [ -z "$listener" -a -e "$socket" ]; then
# Nothing is listening: remove dangling socket.
rm "$socket"
@@ -91,6 +91,15 @@ get_listener () {
fi
}
+gud_status () {
+ gud_status="$(exec -a emacsclient "$installed_emacsclient" -sgdbmacs -w2 \
+ --eval '(and (boundp '"'"'gud-comint-buffer)
+ (get-buffer-process gud-comint-buffer)
+ (string= "signal-received"
+ gdb-inferior-status))')"
+ return $?
+}
+
maybe_notify () {
echo >&2 "$1"
$was_set && ! [ -t 2 ] \
@@ -189,25 +198,33 @@ fi
# Make it possible, with primary session, to quickly replace in-tree Emacs
# with installed Emacs. See 'C-i E' Sway/i3 binding.
if [ -z "$daemon_name" ] && $devel_running && $want_installed; then
- inotifywait -qq --timeout "${timeout:-15}" -e delete_self "$socket" &
- inotifywait=$!
- kill "$listener"
-
- # Detach gdb so that Emacs can handle the SIGTERM. We also have to quit
- # gdb so that `spw/gdbmacs-attach' doesn't look at `gdb-inferior-status'.
- if [ -n "${gdbmacs:=$(get_listener ${socket_dir}gdbmacs)}" ]; then \
- ( exec -a emacsclient "$installed_emacsclient" -sgdbmacs -w2 \
- --eval '(gdb-wait-for-pending
- (lambda ()
- (gud-basic-call "detach")
- (gdb-wait-for-pending
- (lambda ()
- (gud-basic-call "quit")))))' ) \
- || fail "gdbmacs detach request failed"
- fi
+ # If in-tree Emacs appears wedged, just delete the socket and start up an
+ # installed daemon. The idea is that I'll only type C-i E if I know
+ # that's not just wedged but crashed, and I want to keep that state in gdb
+ # but get another primary daemon up in the meantime.
+ if gud_status && [ "$gud_status" = t ]; then
+ rm "$socket"
+ else
+ inotifywait -qq --timeout "${timeout:-15}" -e delete_self "$socket" &
+ inotifywait=$!
+ kill "$listener"
+
+ # Detach gdb so that Emacs can handle the SIGTERM. We also have to
+ # quit gdb so that `spw/gdbmacs-attach' ignores `gdb-inferior-status'.
+ if [ -n "${gdbmacs:=$(get_listener ${socket_dir}gdbmacs)}" ]; then \
+ ( exec -a emacsclient "$installed_emacsclient" -sgdbmacs -w2 \
+ --eval '(gdb-wait-for-pending
+ (lambda ()
+ (gud-basic-call "detach")
+ (gdb-wait-for-pending
+ (lambda ()
+ (gud-basic-call "quit")))))' ) \
+ || fail "gdbmacs detach request failed"
+ fi
- wait_inotifywait \
- || fail "inotifywait(1) timed out waiting for socket deletion"
+ wait_inotifywait \
+ || fail "inotifywait(1) timed out waiting for socket deletion"
+ fi
listener=
devel_running=false
fi
@@ -230,28 +247,21 @@ if ! $want_installed && ! $installed_running && [ -x "$devel_emacsclient" ] \
emacsclient=("$devel_emacsclient")
if [ -z "$daemon_name" ] && ! $want_version; then
spw_flock 4 gdbmacs
- if [ -n "${gdbmacs:=$(get_listener ${socket_dir}gdbmacs)}" ]; then
- # If the primary session is known to be stopped, ask gdbmacs to
- # handle the request: it's probably C-i e or editing via EDITOR.
- #
- # Ignore a failure to obtain any information here, because one
- # likely cause is that the request times out because gdbmacs is
- # busy starting up Gnus. In that case we'd rather just try
- # sending the request to the primary session anyway.
- #
- # Ideally we could know that emacsclient exited non-zero only
- # because of a timeout, but currently that can be done only by
- # parsing emacsclient's output: see Emacs bug#60592.
- gud_status="$(exec -a emacsclient "$installed_emacsclient" \
- -sgdbmacs -w2 --eval \
- '(and (boundp '"'"'gud-comint-buffer)
- (get-buffer-process gud-comint-buffer)
- (string= "signal-received"
- gdb-inferior-status))')"
- if [ $? -eq 0 -a "$gud_status" = t ]; then
- maybe_notify "in-tree Emacs appears to be wedged"
- pass_to_gdbmacs "$@"
- fi
+ # If the primary session is known to be stopped, ask gdbmacs to
+ # handle the request: it's probably C-i e or editing via EDITOR.
+ #
+ # Ignore a failure to obtain any information here, because one
+ # likely cause is that the request times out because gdbmacs is
+ # busy starting up Gnus. In that case we'd rather just try
+ # sending the request to the primary session anyway.
+ #
+ # Ideally we could know that emacsclient exited non-zero only
+ # because of a timeout, but currently that can be done only by
+ # parsing emacsclient's output: see Emacs bug#60592.
+ if [ -n "${gdbmacs:=$(get_listener ${socket_dir}gdbmacs)}" ] \
+ && gud_status && [ "$gud_status" = t ]; then
+ maybe_notify "in-tree Emacs appears to be wedged"
+ pass_to_gdbmacs "$@"
fi
fi
else