summaryrefslogtreecommitdiff
path: root/emacsterm.sh.in
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2016-06-08 23:20:23 -0400
committerLuke Shumaker <lukeshu@sbcglobal.net>2016-06-08 23:20:23 -0400
commit5f29a477f190b9f4c0d3835574dfbcbad19d827c (patch)
treea2eef90f0afd351c65edb7aae5c9dc45699dedd9 /emacsterm.sh.in
parent8c67cad1f2bbcaabe23586643d670ba08f3d2a05 (diff)
emacsterm: sane option parsing; create emacsterm-{xterm,rxvt} for insanity
Diffstat (limited to 'emacsterm.sh.in')
-rw-r--r--emacsterm.sh.in163
1 files changed, 51 insertions, 112 deletions
diff --git a/emacsterm.sh.in b/emacsterm.sh.in
index 6ecbed3..e850aad 100644
--- a/emacsterm.sh.in
+++ b/emacsterm.sh.in
@@ -20,135 +20,74 @@
m4_include(common.sh.in)
usage() {
- print "Usage: %q [OPTIONS] [SHELL]" "$0"
+ print "Usage: %q [OPTIONS] [--] [PROGRAM [ARGS...]]" "$0"
+ print 'Use Emacs as a terminal emulator'
echo
- print 'This utility does NOT support option combining.'
+ print \
+'If ARGS contains anything beginning with "-", then you will need to put
+"--" before PROGRAM so that it does not get treated as part of OPTIONS.'
+ echo
+ print 'If PROGRAM is not given, the default is "${SHELL:-/bin/sh}".'
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}'
+ flag "-T $(_ FUNCTION)" 'Use Emacs Lisp FUNCTION instead of "term"'
}
main() {
- declare mode
- declare mimic
- declare cmd
- declare -a flags
- parse "$@"
-
- next \
- emacsclient "${flags[@]}" --eval \
- "(term $(emacs_quote "${cmd}"))"
-}
-
-# Sets the 'global' variables:
-# - mode
-# - mimic
-# - cmd
-# - flags (array)
-parse() {
- mode=normal
- mimic=rxvt
- cmd=
- flags=()
+ declare -a flags=()
+ declare fn=term
+ declare -a prog=("${SHELL:-/bin/sh}")
+ declare mode=normal
emacs_getopt_init
-
- while [[ $# -gt 0 ]] && [ "$mode" != error ]; 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
-
- # This matches rxvt's behavior.
- # This is simpler than xterm's behavior.
- cmd="${cmd:-${SHELL:-/bin/sh}}"
-}
-
-# Return status is the number of things to shift
-parse_emacs_getopt() {
- declare -a flag
- # Because we don't want options to get combined, we run getopt
- # with : stripped, so that we can check that it returned 2
- # arguments: the flag itself, and '--'. If there were
- # combined flags, then it will return more than 2 arguments.
- 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 -Q -a \
- -n "$0" \
- -o "$emacs_getopt_o" \
- -l "$emacs_getopt_l" \
- -- "$flag"
- mode=error
- 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 -Q -a -n "$0" -o '' -l '' -- "$1"
+ declare args
+ if ! args="$(emacs_getopt T: '' "$@")"; then
mode=error
- return 1
+ else
+ eval set -- "$args"
+ while true; do
+ case "$1" in
+ -V|--version) shift; mode=version;;
+ -H|--help) shift; mode=usage;;
+ -T) fn="$2"; shift 2;;
+ --) shift; break;;
+ *)
+ if [[ $1 =~ $emacs_getopt_2 ]]; then
+ flags+=("$1" "$2"); shift 2
+ else
+ flags+=("$1"); shift 1
+ fi
+ ;;
+ esac
+ done
+ if [[ $# -gt 0 ]]; then
+ prog=("$@")
+ fi
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"
+ next "$mode" \
+ emacsclient "${flags[@]}" --eval \
+ "($fn $(emacs_quote "$(args2program "${prog[@]}")"))"
}
-parse_shell() {
- if [[ $# == 1 ]]; then
- cmd=$1
+args2program() {
+ local program
+ if [ $# = 1 ]; then
+ program="$1"
else
- shift
- error "extra arguments: %s" "$*"
- mode=error
+ program="$(mktemp -t -- "${0##*/}.XXXXXXXXXX")"
+ {
+ echo '#!@bash@'
+ echo '{'
+ echo 'rm -f -- "$0"'
+ printf '%q ' exec -- "$@"
+ echo '}'
+ } > "$program"
+ chmod 755 "$program"
fi
+ printf '%s\n' "$program"
}
main "$@"