eat-emacs/integration/zsh
Akib Azmain Turja b2ad1be411
Add message passing support
* eat.el (eat-message-handler-alist): New user option.
* eat.el (eat--handle-message): New function.
* eat.el (eat--handle-uic, eat--eshell-handle-uic): Handle
message passing sequence.
* eat.texi (Message Passing): New section in chapter "Shell
Integration".
* integration/bash (__eat_enable_integration): Remove the
unnecessary complex code to update PROMPT_COMMAND.
* integration/bash (_eat_msg):
* integration/zsh (_eat_msg):
New function.
2023-09-17 21:58:40 +06:00

105 lines
3.2 KiB
Text

# integration/zsh --- Zsh integration
# Copyright (C) 2022, 2023 Akib Azmain Turja.
# This file is not part of GNU Emacs.
# This file 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, 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.
# For a full copy of the GNU General Public License
# see <https://www.gnu.org/licenses/>.
__eat_precmd () {
__eat_exit_status="$?"
# Send exit status.
if test -n "$__eat_current_command"
then
printf '\e]51;e;H;%i\e\\' "$__eat_exit_status"
fi
__eat_current_command=""
# Inform that a new prompt is going to be printed.
printf '\e]51;e;J\e\\'
# Send the current working directory, for directory tracking.
printf '\e]51;e;A;%s;%s\e\\' "$(printf "%s" "$HOST" | base64)" \
"$(printf "%s" "$PWD" | base64)"
# Update title.
# "${PWD/$HOME/'~'}" converts "/home/akib/org/" to "~/org/".
# The next one is substituted with '%', or '#' if we're "root".
printf '\e]2;%s@%s:%s%s\e\\' "$USER" "$HOST" "${PWD/$HOME/~}" \
"$(test $UID -eq 0 && echo '#' || echo '%')"
}
__eat_preexec () {
__eat_current_command="$1"
# Send current command.
printf '\e]51;e;F;%s\e\\' \
"$(printf "%s" "$__eat_current_command" | base64)"
# Send pre-exec sequence.
printf '\e]51;e;G\e\\'
# Update title to include the command running.
# "${PWD/$HOME/~}" converts "/home/akib/foo/" to "~/foo/".
# The next one is substituted with '%', or '#' if we're "root".
printf '\e]2;%s@%s:%s%s %s\e\\' "$USER" "$HOST" "${PWD/$HOME/~}" \
"$(test $UID -eq 0 && echo '#' || echo '%')" \
"$__eat_current_command"
}
__eat_enable_integration ()
{
__eat_integration_enabled=yes
__eat_current_command=""
__eat_exit_status=0
local __eat_prompt_start="$(printf '\e]51;e;B\e\\')"
local __eat_prompt_end="$(printf '\e]51;e;C\e\\')"
local __eat_continuation_start="$(printf '\e]51;e;D\e\\')"
local __eat_continuation_end="$(printf '\e]51;e;E\e\\')"
PS1="%{$__eat_prompt_start%}$PS1%{$__eat_prompt_end%}"
PS2="%{$__eat_continuation_start%}$PS2%{$__eat_continuation_end%}"
# TODO: What to do about RPS1 and friends?
autoload -Uz add-zsh-hook
add-zsh-hook precmd __eat_precmd
add-zsh-hook preexec __eat_preexec
# Send the history, for native shell prompt.
printf '\e]51;e;I;0;bash;%s;%s\e\\' \
"$(printf "%s" "$HOSTNAME" | base64)" \
"$(printf "%s" "$HISTFILE" | base64)"
local REPLY
IFS=$';\e' read -r -s -t 10 -d "\\" -A REPLY
if test "${REPLY[5]}" != 0
then
printf '\e]51;e;I;1;zsh;%s\e\\' \
"$(tail -n "${REPLY[5]}" "$HISTFILE" | base64)"
fi
}
_eat_msg () {
local msg=$'\e]51;e;M'
for _ in $(eval "echo {1..$#}")
do
msg="$msg;$(printf "%s" "$1" | base64)"
shift
done
printf "%s\e\\" "$msg"
}
# Enable.
if test -z "$__eat_integration_enabled" && \
test "${TERM:0:4}" = "eat-"
then
__eat_enable_integration
else
true
fi
# Local Variables:
# mode: sh
# sh-shell: zsh
# End: