-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathec
executable file
·350 lines (311 loc) · 12.6 KB
/
ec
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
#!/bin/sh
# SH FILE: ec
#
# Purpose : Launch an Emacs client to an Emacs Daemon - start the deamon if necessary.
# Created : Wednesday, May 22 2024.
# Author : Pierre Rouleau <[email protected]>
# Time-stamp: <2024-08-01 11:20:41 EDT, updated by Pierre Rouleau>
# ----------------------------------------------------------------------------
# Description
# -----------
#
# Launch an Emacs client, text by default, graphical if the --graphic or -g
# option is specified. Also starts the Emacs daemon if it is not already
# running. Can also be used to only start the daemon.
#
# ----------------------------------------------------------------------------
# Dependencies
# ------------
#
# On macOS: Emacs for mac OS/X must be installed : https://emacsformacosx.com/
# ----------------------------------------------------------------------------
# Code
# ----
#
os_name="$(uname)"
print_usage()
{
printf -- "\
ec : Open specified files in emacsclient. Start Emacs daemon if necessary.
Usage: ec [-h|--help]
ec [-g|--gui] [--name=DAEMON-NAME]
ec --check-daemon [--name=DAEMON-NAME]
ec --start-daemon [--name=DAEMON-NAME]
-h, --help: print this help.
-g, --gui: start a graphical emacsclient, otherwise
start a terminal-based emacsclient (the default).
If the Emacs daemon is not already running, start it.
If the --name option is specified, DAEMON-NAME identifies the
socket name the daemon and the client must use.
It's possible to create several daemons and client(s)
attaching to that daemon by using that option.
Use ec --start-daemon to only start the daemon without starting any client.
If the daemon is already running the command prints a message and exit with
an exit code of 1. It can be used to check if the daemon is running.
See emacsclient man page for more command line options.
"
case "${os_name}" in
Darwin)
printf -- "\
Note: under macOS, to be able to launch an Emacs client that is a GUI Emacs
the GUI supporting Emacs from https://emacsformacosx.com/
must be installed.
"
;;
Linux)
printf -- "\
Note: under Linux, emacs-lucid is used to start the daemon
if the --gui option is specified and the emacs-lucid
executable file is found on the current PATH.
Otherwise, ec defaults to emacs.
"
;;
esac
}
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
print_usage
exit 0
fi
# ----------------------------------------------------------------------------
# Identify which flavor (GUI or text) of Emacs Client to run
use_gui=false
if [ "$1" = "-g" ] || [ "$1" = "--gui" ]; then
use_gui=true
shift
fi
# ----------------------------------------------------------------------------
# Check if this is a request to only start the daemon
start_client=true
if [ "$1" = "--start-daemon" ] ; then
start_client=false
shift
fi
# Ensure that that --start-daemon option does not have extra text to it.
# ie: reject something like --start-daemon=NAME
case "$1" in
--start-daemon=*)
echo "*** ec: ERROR ***"
echo " Invalid option: $1"
echo "*****************"
print_usage
exit 1
esac
# ----------------------------------------------------------------------------
# Check if this a request to check if the daemon is running
start_daemon=true
if [ "$1" = "--check-daemon" ] ; then
start_daemon=false
start_client=false
shift
fi
# Ensure that that --check-daemon option does not have extra text to it.
# ie: reject something like --check-daemon=NAME
case "$1" in
--check-daemon=*)
echo "*** ec: ERROR ***"
echo " Invalid option: $1"
echo "*****************"
print_usage
exit 1
esac
# ----------------------------------------------------------------------------
# Check if the deamon/client use the default or specified socket filename
daemon_name=
daemon_opt="--daemon"
socket_opt=''
case "$1" in
--name=*)
daemon_name=$(echo "$1" | sed 's/--name=//g')
daemon_opt="--daemon=${daemon_name}"
socket_opt="--socket-name=${daemon_name}"
shift
;;
esac
# ----------------------------------------------------------------------------
# Start the daemon if necessary
case "${os_name}" in
Darwin)
# On macOS, check for the presence of required programs
if [ ! -d /Applications/Emacs.app/Contents ]; then
echo "*** ec: ERROR ***"
echo "The required /Applications/Emacs.app is missing."
echo "Please install Emacs from https://emacsformacosx.com/ "
echo "*****************"
exit 1
fi
# On macOS, start the graphics-capable Emacs daemon if it is not already running.
if [ -z "${daemon_name}" ]; then
# shellcheck disable=SC2009
if ps -ax | grep Emacs.app | grep -v grep | grep -- "--bg-daemon=\\\0123,4\\\012$" > /dev/null; then
if [ "${start_client}" = "false" ]; then
if [ "${start_daemon}" = "true" ]; then
echo "ec: Emacs daemon (for default socket name) is already running!"
exit 1
else
echo "ec: Emacs daemon (for default socket name) is running."
fi
fi
elif [ "${start_daemon}" = "true" ]; then
echo "ec: starting the Emacs daemon for default socket name..."
if ! /Applications/Emacs.app/Contents/MacOS/Emacs "${daemon_opt}"; then
echo "*** ec: ERROR: failed starting Emacs daemon"
exit 1
fi
else
echo "ec: the Emacs daemon for default socket is NOT running yet."
fi
else
# shellcheck disable=SC2009
if ps -ax | grep Emacs.app | grep -v grep | grep -- "--bg-daemon=" | grep "${daemon_name}" > /dev/null; then
if [ "${start_client}" = "false" ]; then
if [ "${start_daemon}" = "true" ]; then
echo "ec: Emacs daemon (for socket ${daemon_name}) is already running!"
exit 1
else
echo "ec: Emacs daemon (for socket ${daemon_name}) is running."
fi
fi
elif [ "${start_daemon}" = "true" ]; then
echo "ec : starting the Emacs daemon for socket=${daemon_name}..."
if ! /Applications/Emacs.app/Contents/MacOS/Emacs "${daemon_opt}"; then
echo "*** ec: ERROR: failed starting Emacs daemon ${daemon_name}"
exit 1
fi
else
echo "ec: the Emacs daemon for socket ${daemon_name} is NOT running yet."
fi
fi
;;
Linux)
# On Linux, use the standard Emacs program name, emacs, to start the
# Emacs daemon. However if emacs-lucid is present and the user
# requested using the graphics mode then use emacs-lucid to launch the
# Emacs daemon.
emacs_pgm=emacs
if [ "$use_gui" = "true" ]; then
if which emacs-lucid > /dev/null ; then
emacs_pgm=emacs-lucid
fi
fi
if [ -z "${daemon_name}" ]; then
# shellcheck disable=SC2009
if ps -ax | grep emacs | grep -- '--daemon' | grep -v grep > /dev/null; then
# emacs daemon is already running
if [ "${start_client}" = "false" ]; then
if [ "${start_daemon}" = "true" ]; then
echo "ec: Emacs daemon (for default socket name) is already running!"
exit 1
else
echo "ec: Emacs daemon (for default socket name) is running."
fi
fi
elif [ "${start_daemon}" = "true" ]; then
# Emacs daemon is not running
echo "ec: starting the Emacs daemon for default socket name..."
if ! ${emacs_pgm} "${daemon_opt}"; then
echo "*** ec: ERROR: failed starting Emacs daemon"
exit 1
fi
else
echo "ec: the Emacs daemon for default socket is NOT running yet."
fi
else
# shellcheck disable=SC2009
if ps -ax | grep emacs | grep -- '--daemon' | grep -v grep | grep "${daemon_name}" > /dev/null; then
if [ "${start_client}" = "false" ]; then
if [ "${start_daemon}" = "true" ]; then
echo "ec: Emacs daemon (for socket ${daemon_name}) is already running!"
exit 1
else
echo "ec: Emacs daemon (for socket ${daemon_name}) is running."
fi
fi
elif [ "${start_daemon}" = "true" ]; then
echo "ec : starting the Emacs daemon for socket=${daemon_name}..."
if ! ${emacs_pgm} "${daemon_opt}"; then
echo "*** ec: ERROR: failed starting Emacs daemon ${daemon_name}"
exit 1
fi
else
echo "ec: the Emacs daemon for socket ${daemon_name} is NOT running yet."
fi
fi
;;
*)
echo "Sorry, the $(uname) Operating System is not supported yet."
echo "Please create a bug report in the PEL project to request it."
exit 1
;;
esac
# ----------------------------------------------------------------------------
# Start the client if requested
if [ "${start_client}" = "true" ]; then
case "${os_name}" in
Darwin)
# on macOS use the GUI built Emacs as client.
# [:todo 2024-05-24, by Pierre Rouleau: should we depend on the internal symlink instead of checking the os version?]
case "$(arch)" in
arm64)
app=/Applications/Emacs.app/Contents/MacOS/bin-arm64-11/emacsclient
;;
i386)
case "$(sw_vers -productVersion)" in
10\.14\.*)
app=/Applications/Emacs.app/Contents/MacOS/bin-x86_64-10_14/emacsclient
;;
10\.13\.* | 10\.12\.* | 10\.11\.* | 10\.10\.*)
app=/Applications/Emacs.app/Contents/MacOS/bin-x86_64-10_14/emacsclient
;;
10\.9\.*)
app=/Applications/Emacs.app/Contents/MacOS/bin-x86_64-10_9/emacsclient
;;
*)
app=/Applications/Emacs.app/Contents/MacOS/bin/emacsclient
;;
esac
;;
*)
app=/Applications/Emacs.app/Contents/MacOS/bin/emacsclient
;;
esac
# Fail safety: use dispatcher if the selected executable does not exists
# in case older Emacs.app DMG is installed on the computer.
if [ ! -x "$app" ]; then
app=/Applications/Emacs.app/Contents/MacOS/bin/emacsclient
fi
if [ "${use_gui}" = "true" ]; then
# shellcheck disable=SC2086
"$app" -c -n ${socket_opt} "$@"
else
# shellcheck disable=SC2086
"$app" -nw ${socket_opt} "$@"
fi
;;
Linux)
# on Linux use emacsclient command in all cases.
# Also start the Emacs daemon if it is not already running.
# Use the '-a ""' for that.
# emacsclient options for reference
# -a "" starts emacs daemon and reattaches
# -c creates a new frame
# -n returns control back to the terminal
if [ "${use_gui}" = "true" ]; then
# echo "GUI emacsclient"
# exec /usr/bin/env emacsclient -c -n -a "" "$@"
# shellcheck disable=SC2086
emacsclient -c -n -a "" ${socket_opt} "$@"
else
# echo "text emacsclient"
# exec /usr/bin/env emacsclient -nw -a "" "$@"
# shellcheck disable=SC2086
emacsclient -nw -a "" ${socket_opt} "$@"
fi
;;
*)
echo "Sorry, the $(uname) Operating System is not supported yet."
echo "Please create a bug report in the PEL project to request it."
exit 1
;;
esac
fi
# ----------------------------------------------------------------------------