diff options
| author | B. Watson <urchlay@slackware.uk> | 2026-09-09 19:16:34 -0400 |
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2026-09-09 19:16:34 -0400 |
| commit | 40e37237bd6d94869bec344a359fa0208cf60375 (patch) | |
| tree | 8add0f1c7592f14658556a9fced4651d203c03a3 /stealvim | |
| parent | c9b355ac004fb7913e4fabd02e274f3484b76ea8 (diff) | |
| download | misc-scripts-40e37237bd6d94869bec344a359fa0208cf60375.tar.gz | |
stealvim: added
Diffstat (limited to 'stealvim')
| -rwxr-xr-x | stealvim | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/stealvim b/stealvim new file mode 100755 index 0000000..754b02d --- /dev/null +++ b/stealvim @@ -0,0 +1,98 @@ +#!/bin/bash + +SELF="$( basename $0 )" + +warn() { + echo "$SELF: $*" 1>&2 +} + +die() { + echo "$SELF: fatal: $*" 1>&2 + exit 1 +} + +if [ "$1" = "-h" -o "$1" = "--help" -o "$2" != "" ]; then + cat <<EOF +$SELF - take over a running vim instance via reptyr + +Usage: $SELF [<file>} + +With no argument, $SELF searches for .*.swp files in the current +directory. If only one is found, the PID of the process that owns it +is redirected to the current TTY by running "reptyr <pid>". If there +are multiple .*.swp files, no process is redirected; instead the PIDs +that own the files are printed to stderr. + +With a <file> argument, the vim process editing that file (if any) +is passed to reptyr. The <file> can either be the actual file +being edited, or the .*.swp file. + +Typical use case: you were editing a file remotely (via ssh), left +yourself logged in and forgot to exit vim; now you're at the console +or logged in from a different host and want to continue editing the +same file. + +After "stealing" the vim process, it's best to write any changes +and then exit vim immediately. To continue editing, run vim again. +If you ignore this suggestion, things might or might not work OK +depending on the terminal emulators in use, and/or the TERM setting. +EOF +fi + +[ "$( type -p reptyr )" = "" ] && \ + die "reptyr not installed!" + +old="" + +for i in .*.swp; do + [ ! -e "$i" ] && die "no .*.swp files" + + swppid="$( file $i | sed 's/.*, pid \([^,]*\),.*/\1/' )" + + # If there's an argument and we found the matching .swp, use it. + if [ "$i" = "$1" -o "$i" = ".$1.swp" ]; then + pid=$swppid + break + fi + + # If there's an argument and the current .swp file doesn't + # match, ignore this .swp. + [ "$1" != "" ] && continue + + # If the .swp's PID is no longer running, ignore it. + if [ ! -d /proc/$swppid ]; then + warn "$i: PID $swppid no longer running" + continue + fi + + # If we can't read the exe, it likely means it belongs to root, + # or anyway not the current user. + if [ ! -r /proc/$swppid/exe ]; then + warn "$i: PID $swppid doesn't belong to user $( whoami )" + continue + fi + + # If the .swp's PID is running but it's not vim, the PID has been + # reused. ignore it. This works even if vim was called by a + # symlink (e.g. /usr/bin/vi => vim). + case "$( realpath /proc/$swppid/exe )" in + */vim) ;; + *) warn "$i: PID $swppid not a vim process"; continue ;; + esac + + pid=$swppid + if [ "$old" != "" ] && [ "$pid" != "$old" ]; then + die "multiple vim PIDs: $old $pid" + exit 1 + fi + + old=$pid +done + +if [ "$pid" = "" ]; then + msg="no vim PID found" + [ "$1" != "" ] && msg+=" for $1" + die $msg +fi + +reptyr "$pid" |
