#!@bash@ # Copyright (C) 2011, 2013-2014 Luke Shumaker # # 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 . 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 \ '(select-frame (make-frame))' \ "(term $(emacs_quote "${cmd}"))" \ '(set-window-dedicated-p (selected-window) t)' } # 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 "$@"