1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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"
|