#!/bin/bash
# ---------------------
# DWIM - do what i mean
# ---------------------
# if supplied -q then kill otherwise DWIM
# original script by Ian Yang.
# updated by Tim O'Callagan
# - added colourisation, path checking, +comments
# default TMPDIR to /tmp
if [ -z "${TMPDIR}" ] ; then
TMPDIR=/tmp
fi
# change this if you have modified server-socket-dir,
# server-socket-diret-dir or similar in your .emacs
_EMACS_SERVER_DIR="${TMPDIR}/emacs${UID}"
# define some ansi terminal colours
_C_RED_="\e[0;31m"
_C_GRN_="\e[0;32m"
_C_OFF_="\e[m\017"
_log_success () { echo -e "${_C_GRN_}[SUCCESS]${_C_OFF_} -> $1" ; }
_log_failure () { echo -e "${_C_RED_}[FAILURE]${_C_OFF_} -> $1" ; }
_is_emacs_daemon_started () {
${_DWIM_NETSTAT} -nlpx 2> /dev/null | awk '{print $NF}' | grep -qF "${_EMACS_SERVER_DIR}/server"
}
_is_emacs_window_exist () {
${_DWIM_WMCTRL} -lx 2> /dev/null | awk '{print $3}' | grep -qF 'emacs.Emacs'
}
_active_window_id () {
${_DWIM_XPROP} -root 2> /dev/null |\
sed -n 's/^_NET_ACTIVE_WINDOW(WINDOW): window id # //p;T;q'
}
_kill_emacs () {
if _is_emacs_window_exist ; then
# store existing window id
local cur=$(_active_window_id)
# bring forward and focus emacs window
${_DWIM_WMCTRL} -x -a emacs.Emacs &> /dev/null
# send kill signal
${_DWIM_EMACSCLIENT} -n -e '(progn (dolist (f (cdr-safe (reverse (frame-list)))) (delete-frame f t)) (kill-emacs))'
# switch back to calling window when done
[ -n "$cur" ] && ${_DWIM_WMCTRL} -i -a "$cur"
_log_success "killed all running emacs instances"
else
_log_failure "emacs not running"
fi
}
_dwim_main () {
# if called without an emacs deamon running, if not then exit
if ! _is_emacs_daemon_started ; then
_EMACS_LOGFILE="${_EMACS_SERVER_DIR}/emacs-${UID}.log"
_EMACS_LOGMESG="starting emacs daemon with ${_EMACS_LOGFILE} file"
if ${_DWIM_EMACS} --daemon &> ${_EMACS_LOGFILE} ; then
_log_success "${_EMACS_LOGMESG}"
else
_log_failure "${_EMACS_LOGMESG}"
return 1
fi
fi
# if DISPLAY ise set then an Xserver exists
if [ -n "$DISPLAY" ]; then
# store active window id for shell window
local cur=$(_active_window_id)
# if an emacs window exists then
if _is_emacs_window_exist ; then
# bring forward and focus emacs window
${_DWIM_WMCTRL} -x -a emacs.Emacs &> /dev/null
# if filename supplied then open with filename
if [ -n "$1" ]; then
${_DWIM_EMACSCLIENT} "$@"
# switch back to calling window when done
[ -n "$cur" ] && ${_DWIM_WMCTRL} -i -a "$cur"
fi
else
# no emacs window exits, so if filename supplied
if [ -n "$1" ]; then
# open file in new frame and send tty into background
${_DWIM_EMACSCLIENT} -c "$@" &
else
# open file in new frame with no wait and send tty into background
${_DWIM_EMACSCLIENT} -n -c &
fi
# create an integer variable i, and set it to 3
local -i tries=3
# try 3 times (once per second) to switch focus to the opened emacs frame
while ! ${_DWIM_WMCTRL} -x -a emacs.Emacs &> /dev/null && [ $tries -gt 0 ]; do
sleep 1
tries=tries-1
done
# ${!} Expands to the process ID of the most recently
# executed background (asynchronous) command.
# so wait until the emacs instance returns
wait ${!}
# switch back to calling window when done if there is one and a filename was used
[ -n "$1" -a -n "$cur" ] && ${_DWIM_WMCTRL} -i -a "$cur"
fi
else
# otherwise run emacs in text mode
${_DWIM_EMACSCLIENT} -t "$@"
fi
}
# going to assume awk and grep exists, testing for other binaries
# check required dwim binaries are here
for i in emacs emacsclient netstat wmctrl xprop ; do
_WHCIH=$(which $i)
if [[ -z "${_WHCIH}" ]] ; then
echo "$i is not found in path!"
exit 1
else
eval "_DWIM_${i^^}=${_WHCIH}"
# echo $(eval "echo _DWIM_${i^^}=\$_DWIM_${i^^}")
fi
done
# if $1 (filename) is not empty and is -q then kill emacs, otherwise do what i mean
[ -n "$1" -a "$1" = "-q" ] && _kill_emacs || _dwim_main "$@"