#!/hint/bash if [[ $TERM == eterm* ]]; then SELECTED_EDITOR='emacsclient' EDITOR=$SELECTED_EDITOR VISUAL=$SELECTED_EDITOR export SELECTED_EDITOR EDITOR VISUAL export PAGER=cat ## Primatives for interacting with Emacs ############################### # _emacs_run LISP _emacs_run() { emacsclient -a false -e "$*" 2>/dev/null } # _emacs_quote UNQUOTED_STRING _emacs_quote() { local str="$*" str="${str//\\/\\\\}" # \ -> \\ str="${str//\"/\\\"}" # " -> \" str="\"${str}\"" # wrap it in quotes printf '%s' "$str" } # _emacs_unquote QUOTED_STRING _emacs_unquote() { local str="$*" if [[ $str =~ ^\"(.*)\"$ ]]; then str=${BASH_REMATCH[1]} # un-quote it str="${str//\\\\/\\}" # \\ -> \ str="${str//\\\"/\"}" # \" -> " fi printf '%s' "$str" } ## Deal with renaming the terminal ##################################### # _emacs_rename_terminal NEW_BUFFER_NAME # This function uses the variable _EMACS_BUFFER to store some state _emacs_rename_terminal() { local name=$(_emacs_quote "$*") if [[ -n $_EMACS_BUFFER ]]; then local buffer="(get-buffer $_EMACS_BUFFER)" else local buffer='(window-buffer (selected-window))' fi _EMACS_BUFFER=$(_emacs_run "(with-current-buffer ${buffer} (rename-buffer ${name} t))") } # _emacs_get_short_cwd _emacs_get_short_cwd() { local base=$PWD local suffix='' # The regex here is a list of directory names # that aren't really helpful, and that the # parent directory should be included also. if [[ $base =~ (/(src|pkg|doc|pkg-libre|src-libre|trunk|tags|branches))*$ ]]; then suffix=$BASH_REMATCH base=${base%$suffix} fi base=${base##*/} echo ${base}${suffix} } # _emacs_get_desired_buffer_name _emacs_get_desired_buffer_name() { echo "*ansi-term*<$(_emacs_get_short_cwd)>" } ## High-level tasks #################################################### # Like uniquify on the buffer name (shell -> emacs) _emacs_set_buffer_name() { # This doesn't work correctly on remote hosts. # The "correct" solution is probably to hook into # default-directory being set in term.el _emacs_rename_terminal "$(_emacs_get_desired_buffer_name)" } # Set the TRAMP directory for remote hosts (shell -> emacs) _emacs_set_remote_dir() { if [[ -n $SSH_CONNECTION ]]; then printf '\eAnSiT%s %s\n' \ u "$USER" \ c "$PWD" \ h "$HOSTNAME" fi } # Set the shell's X11 display (emacs -> shell) _emacs_set_shell_DISPLAY() { export DISPLAY=$(_emacs_unquote "$(_emacs_run "(cdr (assoc 'display (frame-parameters)))")") [[ $DISPLAY != nil ]] || unset DISPLAY } ## Do those things ##################################################### _emacs_PROMPT_COMMAND() { _emacs_set_buffer_name _emacs_set_remote_dir _emacs_set_shell_DISPLAY } if _emacs_run '()' >/dev/null; then PROMPT_COMMAND=_emacs_PROMPT_COMMAND fi fi