Skip to content

Commit 2f3ceab

Browse files
author
adrianbartyczak
committed
Rename all scripts in subsection "Terminal" of section "Application management"
1 parent c1932be commit 2f3ceab

File tree

5 files changed

+244
-7
lines changed

5 files changed

+244
-7
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
# Application management - modules
3+
4+
## Terminal
5+
6+
* [execcmdinnewterm](terminal/execcmdinnewterm): Execute a command in a new terminal emulator.
7+
* [execcmdinterm](terminal/execcmdinterm): Execute a command in a terminal emulator.
8+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env bash
2+
#
3+
# File:
4+
# execcmdinnewterm
5+
#
6+
# Description:
7+
# Execute a command in a new terminal emulator.
8+
#
9+
# Supplemental feature:
10+
# This script returns the window ID of the new terminal emulator window.
11+
#
12+
# Usage:
13+
# execcmdinnewterm [command]
14+
#
15+
# Dependencies:
16+
# xterm (the terminal emulator program used)
17+
# wmctrl (used to get the window ID of the new terminal emulator window)
18+
#
19+
# Notes:
20+
# The terminal emulator will load the Bash shell after the command is
21+
# finished.
22+
#
23+
# This solution accepts a Bash Here document as a command.
24+
#
25+
26+
# ============================================
27+
# Utilitiy functions
28+
# ============================================
29+
30+
getWindIdByPid() {
31+
while IFS= read line; do
32+
if [[ "${line}" =~ (0x)([0-9a-z]+)([ ][- ][0-9]+[ ])([0-9]*) ]]; then
33+
local winId="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
34+
local pid="${BASH_REMATCH[4]}"
35+
if [ "${pid}" -eq "${1}" ]; then
36+
echo "${winId}"
37+
break
38+
fi
39+
fi
40+
done < <(wmctrl -lp)
41+
}
42+
43+
# ============================================
44+
# Launch terminal emulator
45+
# ============================================
46+
47+
nohup xterm -e bash -c "$(printf '%s\nexec bash' "${*}")" &>/dev/null &
48+
# "$(printf '%s\nexec bash' "${*}")" allows a bash Here document to be passed
49+
# as a command.
50+
51+
PID="$!"
52+
53+
sleep .08
54+
WIND_ID="$(getWindIdByPid "${PID}")"
55+
56+
# Check if stdout and stderr point to a terminal. If so, redirect them to
57+
# /dev/null to prevent unnecessary output to the spawning terminal. Note: The
58+
# window ID will still be obtainable in a subprocess.
59+
if test -t 1; then
60+
exec 1>/dev/null
61+
fi
62+
if test -t 2; then
63+
exec 2>/dev/null
64+
fi
65+
66+
# echo the window ID so the caller can obtain it
67+
echo "${WIND_ID}"
68+
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#!/usr/bin/env bash
2+
#
3+
# File:
4+
# execcmdinterm
5+
#
6+
# Description:
7+
# Execute a command in a terminal emulator.
8+
#
9+
# Usage:
10+
# execcmdinterm (--class <TERM_CLASS> | --title <TERM_TITLE>) [options] --
11+
# <command>
12+
#
13+
# Options:
14+
# -c --class <TERM_CLASS> class of the terminal emulator (required if
15+
# --title is not used)
16+
# -t --title <TERM_TITLE> partial or full window title of the terminal
17+
# emulator (required if --class is not used; will
18+
# override --class if both are used)
19+
#
20+
# -r --refocus refocus previous window after running command
21+
#
22+
# Exit codes:
23+
# 0: command executed
24+
# 1: command not executed
25+
#
26+
# Dependencies:
27+
# xautomation (if xdotool is preferred, follow the instructions at the bottom
28+
# where xte is used. [Note: Running the command with xdotool is
29+
# significantly slower as it sends each character individually]).
30+
#
31+
# Notes:
32+
# This utility should be used with a keybinding or in a script.
33+
#
34+
35+
# ======= CONFIGURATIONS ==============
36+
37+
# This is the delay time for running the xautomation events in the terminal
38+
# emulator after it has been focused. With no delay time, the terminal emulator
39+
# may focused too quickly, causing none or only a part of the events to succeed.
40+
# (Note: This delay time is also applied before refocusing the previously
41+
# focused window).
42+
readonly XEVENTS_DELAY_TIME='.15'
43+
44+
# ======= ! CONFIGURATIONS ==============
45+
46+
OPTS="$(getopt -q -o c:,t:,r --long class:,title:,refocus -n 'execcmdinterm' \
47+
-- "${@}")"
48+
if [ "$?" -ne 0 ]; then
49+
# output errors as a desktop notification since this script is meant to be
50+
# used with a keybinding and errors printed to stderr will not be seen.
51+
notify-send 'execcmdinterm (err): unrecognized option'
52+
exit 1
53+
fi
54+
eval set -- "${OPTS}"
55+
56+
while true; do
57+
case "${1}" in
58+
--class|-c) TERM_CLASS="${2}"; shift;;
59+
--title|-t) TERM_TITLE="${2}"; shift;;
60+
--refocus|-r) OPT_REFOCUS=true;;
61+
--) shift; break;;
62+
*) break;;
63+
esac
64+
shift
65+
done
66+
67+
if [ -z "${TERM_CLASS}" ] && [ -z "${TERM_TITLE}" ]; then
68+
notify-send 'execcmdinterm (err): must use option --class or --title'
69+
exit 1
70+
fi
71+
72+
if [ "$#" -eq 0 ]; then
73+
# print to the terminal for testing purposes
74+
echo 'execcmdinterm: no execute command provided' 1>&2
75+
exit 1
76+
fi
77+
78+
# ============================================
79+
# Utilitiy functions
80+
# ============================================
81+
82+
getWindIdByName() {
83+
local windIds=("$(wmctrl -l | awk -v srch="${1}" '{$2=$3=""; windName = \
84+
gensub(/([^ ]*)(.*)/, "\\2", "g", $0)} windName ~ srch {print $1}')")
85+
[ $((${#windIds[@]})) -ge 1 ] && echo "${windIds[0]}"
86+
}
87+
88+
getFirstWindIdInClass() {
89+
local classWindIds=($(wmctrl -lx | awk -v class="${1}" '$3 ~ class \
90+
{print $1}'))
91+
[ $((${#classWindIds[@]})) -ge 1 ] && echo "${classWindIds[0]}"
92+
}
93+
94+
getActvWindId() {
95+
echo "$(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5 | rev | cut -c \
96+
2- | rev | sed 's/^0x/0x0/')"
97+
}
98+
99+
# ============================================
100+
# Get the window ID of the terminal
101+
# ============================================
102+
103+
if [ -n "${TERM_TITLE}" ]; then
104+
termWindId="$(getWindIdByName ${TERM_TITLE})"
105+
else
106+
termWindId="$(getFirstWindIdInClass "${TERM_CLASS}")"
107+
fi
108+
109+
# ============================================
110+
# Execute the X events
111+
# ============================================
112+
113+
if [ -n "${termWindId}" ]; then
114+
[ "${OPT_REFOCUS}" = 'true' ] && currWindId="$(getActvWindId)"
115+
116+
wmctrl -i -a "${termWindId}"
117+
[ -n "${XEVENTS_DELAY_TIME}" ] && sleep "${XEVENTS_DELAY_TIME}"
118+
119+
# To use xdotool, comment the xte code sections and uncomment the xdotool code
120+
# sections.
121+
122+
# --------- xte ---------
123+
124+
# Note: Xte sometimes fails to completely paste a string with more than 249
125+
# characters. As a result, a string with more than 249 characters is pasted
126+
# by every 249 character part.
127+
argStr="${@}"
128+
if [ "${#argStr}" -gt 249 ]; then
129+
for ((i=0; i<=${#argStr}; i+=249)); do
130+
xte "str ${argStr:${i}:249}"
131+
done
132+
xte 'key Return'
133+
else
134+
xte <<-EOF
135+
str ${@}
136+
usleep 14000
137+
key Return
138+
EOF
139+
fi
140+
141+
# --------- xdotool ---------
142+
143+
# xdotool type "${@}"
144+
# # must run a separate xdotool command as "type" will type everything after
145+
# # it; also a much higher sleep time is needed as xdotool types each
146+
# # character (instead of pasting the string).
147+
# xdotool sleep .5 key Return
148+
149+
if [ "${OPT_REFOCUS}" = 'true' ]; then
150+
[ -n "${XEVENTS_DELAY_TIME}" ] && sleep "${XEVENTS_DELAY_TIME}"
151+
wmctrl -i -a "${currWindId}"
152+
fi
153+
fi
154+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
# Application management
3+
4+
## Terminal
5+
6+
* [execlasttermcmd](terminal/execlasttermcmd): Execute the last command of a terminal emulator.
7+

scripts/application_management/terminal/execlasttermcommand renamed to scripts/application_management/terminal/execlasttermcmd

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/usr/bin/env bash
22
#
33
# File:
4-
# execlasttermcommand
4+
# execlasttermcmd
55
#
66
# Description:
77
# Execute the last command of a terminal emulator.
88
#
99
# Usage:
10-
# execlasttermcommand (--class <TERM_CLASS> | --title <TERM_TITLE>) [options]
11-
# -- <command>
10+
# execlasttermcmd (--class <TERM_CLASS> | --title <TERM_TITLE>) [options] --
11+
# <command>
1212
#
1313
# Options:
1414
# -c --class <TERM_CLASS> class of the terminal emulator (required if
@@ -46,12 +46,12 @@ readonly XEVENTS_DELAY_TIME='.18'
4646

4747
# ======= ! CONFIGURATIONS ==============
4848

49-
OPTS="$(getopt -q -o c:,t:,r --long class:,title:,refocus -n \
50-
'execlasttermcommand' -- "${@}")"
49+
OPTS="$(getopt -q -o c:,t:,r --long class:,title:,refocus -n 'execlasttermcmd' \
50+
-- "${@}")"
5151
if [ "$?" -ne 0 ]; then
5252
# output errors as a desktop notification since this script is meant to be
5353
# used with a keybinding and errors printed to stderr will not be seen.
54-
notify-send 'execlasttermcommand (err): unrecognized option'
54+
notify-send 'execlasttermcmd (err): unrecognized option'
5555
exit 1
5656
fi
5757
eval set -- "${OPTS}"
@@ -68,7 +68,7 @@ while true; do
6868
done
6969

7070
if [ -z "${TERM_CLASS}" ] && [ -z "${TERM_TITLE}" ]; then
71-
notify-send 'execlasttermcommand (err): must use option --class or --title'
71+
notify-send 'execlasttermcmd (err): must use option --class or --title'
7272
exit 1
7373
fi
7474

0 commit comments

Comments
 (0)