diff options
Diffstat (limited to 'emacsterm.sh.in')
-rw-r--r-- | emacsterm.sh.in | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/emacsterm.sh.in b/emacsterm.sh.in new file mode 100644 index 0000000..a8cef2a --- /dev/null +++ b/emacsterm.sh.in @@ -0,0 +1,160 @@ +#!@bash@ + +# Copyright (C) 2011, 2013-2014 Luke Shumaker <lukeshu@sbcglobal.net> +# +# This file is not considered part of GNU Emacs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +m4_include(common.sh) + +usage() { + print "Usage: %q [OPTIONS] [SHELL]" "$0" + echo + print 'This utility does NOT support option combining.' + echo + print 'The following OPTIONS are accepted:' + emacs_usage + flag '-r' 'Use rxvt-style parsing of CMD for -e (~execve)' + flag '-x' 'Use xterm-style parsing of CMD for -e (~system)' + flag "-e $(_ CMD)" 'Execute CMD instead of ${SHELL:-/bin/sh}' +} + + +main() { + declare mimic + declare cmd + declare -a flags + parse "$@" + + emacsclient "${flags[@]}" --eval \ + "(term $(emacs_quote "${cmd}"))" +} + +# Sets the 'global' variables: +# - mode +# - mimic +# - cmd +# - flags (array) +parse() { + mimic=rxvt + cmd= + flags=() + + local mode=normal + local error=false + emacs_getopt_init + + while [[ $# -gt 0 ]]; do + case "$1" in + -V|--version) shift; mode=version;; + -H|--help) shift; mode=usage;; + -r) shift; mimic=rxvt;; + -x) shift; mimic=xterm;; + -e) shift; parse_cmd "$@"; set --;; + --) shift; parse_shell "$@"; set --;; + -*) parse_emacs_getopt "$@"; shift $?;; + *) parse_shell "$@"; set --;; + esac + done + + if $error; then + usage >&2 + exit 1 + fi + case "$mode" in + usage) usage; exit 0;; + version) version; exit 0;; + esac + + if [[ -z "$cmd" ]]; then + # This matches rxvt's behavior. + # This is simpler than xterm's behavior. + cmd="${cmd:-${SHELL:-/bin/sh}}" + fi +} + +# Return status is the number of things to shift +parse_emacs_getopt() { + declare -a flag + if eval "flag=($(getopt -a \ + -n "$0" \ + -o "${emacs_getopt_o//:/}" \ + -l "${emacs_getopt_l//:/}" \ + -- "$1" 2>/dev/null))" && + [[ ${#flag[@]} == 2 ]] + then + # getopt worked + if [[ $flag =~ $emacs_getopt_2 ]]; then + # flag takes an argument + if [[ $# -gt 1 ]]; then + flags+=("$flag" "$2") + return 2 + else + # Missing the required 2nd part + getopt -a \ + -n "$0" \ + -o "$emacs_getopt_o" \ + -l "$emacs_getopt_l" \ + -- "$flag" >/dev/null + error=true + return 1 + fi + else + # pass the flag along to emacs + flags+=("$flag") + return 1 + fi + else + # getopt either didn't work, or did combined flags + # Have getopt display its own error message: + getopt -a -n "$0" -o '' -l '' -- "$1" >/dev/null + error=true + return 1 + fi +} + +parse_cmd() { + cmd="$(mktemp -t -- "${0##*/}.XXXXXXXXXX")" + trap "$(printf 'rm -f -- %q' "$cmd")" EXIT + { + echo '#!/bin/sh' + case "$mimic" in + xterm) + if [[ $# == 1 ]]; then + printf '%s' "$1" + else + printf -- '%q ' exec "$@" + fi + ;; + rxvt) + printf -- '%q ' exec "$@" + ;; + esac + echo + } > "$cmd" + chmod 755 "$cmd" +} + +parse_shell() { + if [[ $# == 1 ]]; then + cmd=$1 + else + shift + error "extra arguments: %s" "$*" + error=true + fi +} + +main "$@" |