-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathexeccmdinterm
executable file
·154 lines (131 loc) · 4.5 KB
/
execcmdinterm
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env bash
#
# File:
# execcmdinterm
#
# Description:
# Execute a command in a terminal emulator.
#
# Usage:
# execcmdinterm (--class <TERM_CLASS> | --title <TERM_TITLE>) [options] --
# <command>
#
# Options:
# -c --class <TERM_CLASS> class of the terminal emulator (required if
# --title is not used)
# -t --title <TERM_TITLE> partial or full window title of the terminal
# emulator (required if --class is not used; will
# override --class if both are used)
#
# -r --refocus refocus previous window after running command
#
# Exit codes:
# 0: command executed
# 1: command not executed
#
# Dependencies:
# xautomation (if xdotool is preferred, follow the instructions at the bottom
# where xte is used. [Note: Running the command with xdotool is
# significantly slower as it sends each character individually]).
#
# Notes:
# This utility should be used with a keybinding or in a script.
#
# ======= CONFIGURATIONS ==============
# This is the delay time for running the xautomation events in the terminal
# emulator after it has been focused. With no delay time, the terminal emulator
# may focused too quickly, causing none or only a part of the events to succeed.
# (Note: This delay time is also applied before refocusing the previously
# focused window).
readonly XEVENTS_DELAY_TIME='.15'
# ======= ! CONFIGURATIONS ==============
OPTS="$(getopt -q -o c:,t:,r --long class:,title:,refocus -n 'execcmdinterm' \
-- "${@}")"
if [ "$?" -ne 0 ]; then
# output errors as a desktop notification since this script is meant to be
# used with a keybinding and errors printed to stderr will not be seen.
notify-send 'execcmdinterm (err): unrecognized option'
exit 1
fi
eval set -- "${OPTS}"
while true; do
case "${1}" in
--class|-c) TERM_CLASS="${2}"; shift;;
--title|-t) TERM_TITLE="${2}"; shift;;
--refocus|-r) OPT_REFOCUS=true;;
--) shift; break;;
*) break;;
esac
shift
done
if [ -z "${TERM_CLASS}" ] && [ -z "${TERM_TITLE}" ]; then
notify-send 'execcmdinterm (err): must use option --class or --title'
exit 1
fi
if [ "$#" -eq 0 ]; then
# print to the terminal for testing purposes
echo 'execcmdinterm: no execute command provided' 1>&2
exit 1
fi
# ============================================
# Utilitiy functions
# ============================================
getWindIdByName() {
local windIds=("$(wmctrl -l | awk -v srch="${1}" '{$2=$3=""; windName = \
gensub(/([^ ]*)(.*)/, "\\2", "g", $0)} windName ~ srch {print $1}')")
[ $((${#windIds[@]})) -ge 1 ] && echo "${windIds[0]}"
}
getFirstWindIdInClass() {
local classWindIds=($(wmctrl -lx | awk -v class="${1}" '$3 ~ class \
{print $1}'))
[ $((${#classWindIds[@]})) -ge 1 ] && echo "${classWindIds[0]}"
}
getActvWindId() {
echo "$(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5 | rev | cut -c \
2- | rev | sed 's/^0x/0x0/')"
}
# ============================================
# Get the window ID of the terminal
# ============================================
if [ -n "${TERM_TITLE}" ]; then
termWindId="$(getWindIdByName ${TERM_TITLE})"
else
termWindId="$(getFirstWindIdInClass "${TERM_CLASS}")"
fi
# ============================================
# Execute the X events
# ============================================
if [ -n "${termWindId}" ]; then
[ "${OPT_REFOCUS}" = 'true' ] && currWindId="$(getActvWindId)"
wmctrl -i -a "${termWindId}"
[ -n "${XEVENTS_DELAY_TIME}" ] && sleep "${XEVENTS_DELAY_TIME}"
# To use xdotool, comment the xte code sections and uncomment the xdotool code
# sections.
# --------- xte ---------
# Note: Xte sometimes fails to completely paste a string with more than 249
# characters. As a result, a string with more than 249 characters is pasted
# by every 249 character part.
argStr="${@}"
if [ "${#argStr}" -gt 249 ]; then
for ((i=0; i<=${#argStr}; i+=249)); do
xte "str ${argStr:${i}:249}"
done
xte 'key Return'
else
xte <<-EOF
str ${@}
usleep 14000
key Return
EOF
fi
# --------- xdotool ---------
# xdotool type "${@}"
# # must run a separate xdotool command as "type" will type everything after
# # it; also a much higher sleep time is needed as xdotool types each
# # character (instead of pasting the string).
# xdotool sleep .5 key Return
if [ "${OPT_REFOCUS}" = 'true' ]; then
[ -n "${XEVENTS_DELAY_TIME}" ] && sleep "${XEVENTS_DELAY_TIME}"
wmctrl -i -a "${currWindId}"
fi
fi