eat-emacs/integration/bash

135 lines
4.1 KiB
Text
Raw Permalink Normal View History

# integration/bash --- Bash integration
# Copyright (C) 2022 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/>.
2022-12-03 21:30:11 +06:00
__eat_prompt_command () {
2022-12-05 23:50:10 +06:00
# 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.
2022-12-05 23:50:10 +06:00
printf '\e]51;e;A;%s;%s\e\\' "$(printf "%s" "$HOSTNAME" | 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" "$HOSTNAME" \
"${PWD/$HOME/'~'}" \
"$(test $UID -eq 0 && echo '#' || echo '$')"
}
__eat_preexec () {
2022-12-05 23:50:10 +06:00
# Get the real command typed by the user from the history.
__eat_current_command="$(history 1 | sed 's/ *[0-9]* *//')"
# 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" "$HOSTNAME" \
"${PWD/$HOME/'~'}" \
"$(test $UID -eq 0 && echo '#' || echo '$')" \
2022-12-05 23:50:10 +06:00
"$__eat_current_command"
}
__eat_before_prompt_command ()
{
2022-12-05 23:50:10 +06:00
__eat_exit_status="$?"
__eat_inhibit_preexec=yes
}
__eat_after_prompt_command ()
{
__eat_inhibit_preexec=no
}
__eat_before_exec () {
if test $__eat_inhibit_preexec = no \
&& test "$BASH_COMMAND" != __eat_before_prompt_command
then
__eat_inhibit_preexec=yes
__eat_preexec
fi
}
__eat_enable_integration ()
{
__eat_integration_enabled=yes
__eat_current_command=""
__eat_exit_status=0
__eat_inhibit_preexec=yes
local __eat_prompt_start='\e]51;e;B\e\\'
local __eat_prompt_end='\e]51;e;C\e\\'
local __eat_continuation_start='\e]51;e;D\e\\'
local __eat_continuation_end='\e]51;e;E\e\\'
2022-12-05 23:50:10 +06:00
PS1="\[$__eat_prompt_start\]$PS1\[$__eat_prompt_end\]"
PS2="\[$__eat_continuation_start\]$PS2\[$__eat_continuation_end\]"
2022-12-03 21:30:11 +06:00
PROMPT_COMMAND+=(__eat_prompt_command)
trap '__eat_before_exec' DEBUG
# Wrap 'PROMPT_COMMAND' to avoid it getting trapped in 'DEBUG' trap.
# Fun fact: Microsoft doesn't still about know this simple trick.
# They ended up using something as silly and pityful as
# 'VAR=$PROMPT_COMMAND' to copy a Bash array in VSCode Bash
# integration script, which simply won't work ever, and then
# complain about Bash in the comments! xD
PROMPT_COMMAND+=(__eat_after_prompt_command)
PROMPT_COMMAND=(__eat_before_prompt_command "${PROMPT_COMMAND[@]}")
Add prompt mode and process OSC 51 as UI Command * eat.el (eat-enable-native-shell-prompt-editing) (eat-prompt-input-ring-size) (eat-prompt-move-point-for-matching-input): New user option. * eat.el (eat--t-term): Remove slots 'cwd', 'prompt-start-fn', 'prompt-end-fn', 'cont-prompt-start-fn', 'cont-prompt-end-fn', 'cmd-start-fn' and 'cmd-finish-fn'. Add new slot 'ui-cmd-fn'. * eat.el (eat--t-set-cwd): Support only the format used by OSC 7. * eat.el (eat--t-prompt-start, eat--t-prompt-end) (eat--t-cont-prompt-start, eat--t-cont-prompt-end) (eat--t-set-cmd, eat--t-cmd-start, eat--t-cmd-finish): Remove function. * eat.el (eat--t-ui-cmd): New function. * eat.el (eat--t-handle-output): Remove all specialized OSC 51 handlers and call 'eat--t-ui-cmd' to handle any OSC 51 sequence. * eat.el (eat-term-set-parameter): Set 'ui-cmd-fn' slot of terminal when 'ui-command-function' is set. * eat.el (eat-term-cwd): Remove function. * eat.el (eat-term-prompt-start-function) (eat-term-prompt-end-function, eat-term-cmd-start-function) (eat-term-cont-prompt-start-function) (eat-term-cont-prompt-end-function, eat-term-set-cmd-function) (eat-term-cmd-finish-function): Remove generalized variables. * eat.el (eat-term-send-string): New function. * eat.el (eat-send-string-as-yank): Rename to 'eat-term-send-string-as-yank'. All callers changed. * eat.el (eat--set-cwd-uic, eat--post-cont-prompt): New function. * eat.el (eat--pre-prompt, eat--post-prompt, eat--set-cmd) (eat--pre-cmd, eat--set-cmd-status): Remove unused first argument. All callers changed. * eat.el (eat--get-shell-history, eat--handle-uic): New function. * eat.el (eat-prompt-mode-map): New variable. * eat.el (eat-emacs-mode, eat-semi-char-mode, eat-char-mode): Handle the case when prompt mode is active. * eat.el (eat--prompt-mode-previous-mode): New variable. * eat.el (eat--prompt-mode): New non-interactive minor mode. * eat.el (eat-prompt-send-default, eat-prompt-send) (eat-prompt-newline, eat-prompt-delchar-or-eof) (eat-prompt-send-interrupt): New command. * eat.el (eat--prompt-input-ring, eat--prompt-input-ring-index) (eat--prompt-stored-incomplete-input) (eat--prompt-matching-input-from-input-string): New variable. * eat.el (eat--prompt-populate-input-ring) (eat--prompt-reset-input-ring-vars, eat--prompt-ask-for-regexp-arg) (eat--prompt-search-arg, eat--prompt-search-start) (eat--prompt-prev-input-string, eat--prompt-prev-matching-input-str) (eat--prompt-delete-input, eat--prompt-prev-matching-input-str-pos): New function. * eat.el (eat-prompt-previous-input, eat-prompt-next-input) (eat-prompt-restore-input, eat-prompt-previous-matching-input) (eat-prompt-next-matching-input, eat-prompt-find-input) (eat-prompt-previous-matching-input-from-input) (eat-prompt-next-matching-input-from-input): New command. * eat.el (eat-mode): Make 'eat--prompt-mode-previous-mode', 'eat--prompt-input-ring', 'eat--prompt-input-ring-index', 'eat--prompt-stored-incomplete-input' and 'eat--prompt-matching-input-from-input-string' buffer-local. Record undo information if 'eat-enable-native-shell-prompt-editing' is enabled. Set 'mode-line-process' properly so that prompt mode is shown when enabled. * eat.el (eat--process-output-queue): Remove any narrowing temporarily when called. Don't * eat.el (eat--sentinel): Disable prompt mode. Also fix the bug where the point centers when the program exits, instead of going to the end of buffer. * eat.el (eat-exec): Don't set removed generalized variables 'eat-term-prompt-start-function', 'eat-term-set-cmd-function', 'eat-term-prompt-end-function', 'eat-term-cmd-start-function' and 'eat-term-cmd-finish-function'. Set terminal parameter 'ui-command-function' to 'eat--handle-uic'. * eat.el (eat--eshell-handle-uic): New function. * eat.el (eat--eshell-output-filter): Let-bind 'inhibit-read-only' only for required parts. * eat.el (eat--eshell-setup-proc-and-term): Set terminal parameter 'ui-command-function' to 'eat--eshell-handle-uic'. * eat.el (eat--eshell-sentinel): Fix the bug where the point centers when the program exits, instead of going to the end of buffer. * integration/bash (__eat_enable_integration): Send shell history.
2023-09-13 19:49:51 +06:00
# Send the history, for native shell prompt.
printf '\e]51;e;I;0;bash;%s;%s\e\\' \
Add prompt mode and process OSC 51 as UI Command * eat.el (eat-enable-native-shell-prompt-editing) (eat-prompt-input-ring-size) (eat-prompt-move-point-for-matching-input): New user option. * eat.el (eat--t-term): Remove slots 'cwd', 'prompt-start-fn', 'prompt-end-fn', 'cont-prompt-start-fn', 'cont-prompt-end-fn', 'cmd-start-fn' and 'cmd-finish-fn'. Add new slot 'ui-cmd-fn'. * eat.el (eat--t-set-cwd): Support only the format used by OSC 7. * eat.el (eat--t-prompt-start, eat--t-prompt-end) (eat--t-cont-prompt-start, eat--t-cont-prompt-end) (eat--t-set-cmd, eat--t-cmd-start, eat--t-cmd-finish): Remove function. * eat.el (eat--t-ui-cmd): New function. * eat.el (eat--t-handle-output): Remove all specialized OSC 51 handlers and call 'eat--t-ui-cmd' to handle any OSC 51 sequence. * eat.el (eat-term-set-parameter): Set 'ui-cmd-fn' slot of terminal when 'ui-command-function' is set. * eat.el (eat-term-cwd): Remove function. * eat.el (eat-term-prompt-start-function) (eat-term-prompt-end-function, eat-term-cmd-start-function) (eat-term-cont-prompt-start-function) (eat-term-cont-prompt-end-function, eat-term-set-cmd-function) (eat-term-cmd-finish-function): Remove generalized variables. * eat.el (eat-term-send-string): New function. * eat.el (eat-send-string-as-yank): Rename to 'eat-term-send-string-as-yank'. All callers changed. * eat.el (eat--set-cwd-uic, eat--post-cont-prompt): New function. * eat.el (eat--pre-prompt, eat--post-prompt, eat--set-cmd) (eat--pre-cmd, eat--set-cmd-status): Remove unused first argument. All callers changed. * eat.el (eat--get-shell-history, eat--handle-uic): New function. * eat.el (eat-prompt-mode-map): New variable. * eat.el (eat-emacs-mode, eat-semi-char-mode, eat-char-mode): Handle the case when prompt mode is active. * eat.el (eat--prompt-mode-previous-mode): New variable. * eat.el (eat--prompt-mode): New non-interactive minor mode. * eat.el (eat-prompt-send-default, eat-prompt-send) (eat-prompt-newline, eat-prompt-delchar-or-eof) (eat-prompt-send-interrupt): New command. * eat.el (eat--prompt-input-ring, eat--prompt-input-ring-index) (eat--prompt-stored-incomplete-input) (eat--prompt-matching-input-from-input-string): New variable. * eat.el (eat--prompt-populate-input-ring) (eat--prompt-reset-input-ring-vars, eat--prompt-ask-for-regexp-arg) (eat--prompt-search-arg, eat--prompt-search-start) (eat--prompt-prev-input-string, eat--prompt-prev-matching-input-str) (eat--prompt-delete-input, eat--prompt-prev-matching-input-str-pos): New function. * eat.el (eat-prompt-previous-input, eat-prompt-next-input) (eat-prompt-restore-input, eat-prompt-previous-matching-input) (eat-prompt-next-matching-input, eat-prompt-find-input) (eat-prompt-previous-matching-input-from-input) (eat-prompt-next-matching-input-from-input): New command. * eat.el (eat-mode): Make 'eat--prompt-mode-previous-mode', 'eat--prompt-input-ring', 'eat--prompt-input-ring-index', 'eat--prompt-stored-incomplete-input' and 'eat--prompt-matching-input-from-input-string' buffer-local. Record undo information if 'eat-enable-native-shell-prompt-editing' is enabled. Set 'mode-line-process' properly so that prompt mode is shown when enabled. * eat.el (eat--process-output-queue): Remove any narrowing temporarily when called. Don't * eat.el (eat--sentinel): Disable prompt mode. Also fix the bug where the point centers when the program exits, instead of going to the end of buffer. * eat.el (eat-exec): Don't set removed generalized variables 'eat-term-prompt-start-function', 'eat-term-set-cmd-function', 'eat-term-prompt-end-function', 'eat-term-cmd-start-function' and 'eat-term-cmd-finish-function'. Set terminal parameter 'ui-command-function' to 'eat--handle-uic'. * eat.el (eat--eshell-handle-uic): New function. * eat.el (eat--eshell-output-filter): Let-bind 'inhibit-read-only' only for required parts. * eat.el (eat--eshell-setup-proc-and-term): Set terminal parameter 'ui-command-function' to 'eat--eshell-handle-uic'. * eat.el (eat--eshell-sentinel): Fix the bug where the point centers when the program exits, instead of going to the end of buffer. * integration/bash (__eat_enable_integration): Send shell history.
2023-09-13 19:49:51 +06:00
"$(printf "%s" "$HOSTNAME" | base64)" \
"$(printf "%s" "$HISTFILE" | base64)"
local REPLY
IFS=$';\e' read -r -s -t 10 -d "\\" -a REPLY
if test "${REPLY[4]}" != 0
then
printf '\e]51;e;I;1;bash;%s\e\\' \
Add prompt mode and process OSC 51 as UI Command * eat.el (eat-enable-native-shell-prompt-editing) (eat-prompt-input-ring-size) (eat-prompt-move-point-for-matching-input): New user option. * eat.el (eat--t-term): Remove slots 'cwd', 'prompt-start-fn', 'prompt-end-fn', 'cont-prompt-start-fn', 'cont-prompt-end-fn', 'cmd-start-fn' and 'cmd-finish-fn'. Add new slot 'ui-cmd-fn'. * eat.el (eat--t-set-cwd): Support only the format used by OSC 7. * eat.el (eat--t-prompt-start, eat--t-prompt-end) (eat--t-cont-prompt-start, eat--t-cont-prompt-end) (eat--t-set-cmd, eat--t-cmd-start, eat--t-cmd-finish): Remove function. * eat.el (eat--t-ui-cmd): New function. * eat.el (eat--t-handle-output): Remove all specialized OSC 51 handlers and call 'eat--t-ui-cmd' to handle any OSC 51 sequence. * eat.el (eat-term-set-parameter): Set 'ui-cmd-fn' slot of terminal when 'ui-command-function' is set. * eat.el (eat-term-cwd): Remove function. * eat.el (eat-term-prompt-start-function) (eat-term-prompt-end-function, eat-term-cmd-start-function) (eat-term-cont-prompt-start-function) (eat-term-cont-prompt-end-function, eat-term-set-cmd-function) (eat-term-cmd-finish-function): Remove generalized variables. * eat.el (eat-term-send-string): New function. * eat.el (eat-send-string-as-yank): Rename to 'eat-term-send-string-as-yank'. All callers changed. * eat.el (eat--set-cwd-uic, eat--post-cont-prompt): New function. * eat.el (eat--pre-prompt, eat--post-prompt, eat--set-cmd) (eat--pre-cmd, eat--set-cmd-status): Remove unused first argument. All callers changed. * eat.el (eat--get-shell-history, eat--handle-uic): New function. * eat.el (eat-prompt-mode-map): New variable. * eat.el (eat-emacs-mode, eat-semi-char-mode, eat-char-mode): Handle the case when prompt mode is active. * eat.el (eat--prompt-mode-previous-mode): New variable. * eat.el (eat--prompt-mode): New non-interactive minor mode. * eat.el (eat-prompt-send-default, eat-prompt-send) (eat-prompt-newline, eat-prompt-delchar-or-eof) (eat-prompt-send-interrupt): New command. * eat.el (eat--prompt-input-ring, eat--prompt-input-ring-index) (eat--prompt-stored-incomplete-input) (eat--prompt-matching-input-from-input-string): New variable. * eat.el (eat--prompt-populate-input-ring) (eat--prompt-reset-input-ring-vars, eat--prompt-ask-for-regexp-arg) (eat--prompt-search-arg, eat--prompt-search-start) (eat--prompt-prev-input-string, eat--prompt-prev-matching-input-str) (eat--prompt-delete-input, eat--prompt-prev-matching-input-str-pos): New function. * eat.el (eat-prompt-previous-input, eat-prompt-next-input) (eat-prompt-restore-input, eat-prompt-previous-matching-input) (eat-prompt-next-matching-input, eat-prompt-find-input) (eat-prompt-previous-matching-input-from-input) (eat-prompt-next-matching-input-from-input): New command. * eat.el (eat-mode): Make 'eat--prompt-mode-previous-mode', 'eat--prompt-input-ring', 'eat--prompt-input-ring-index', 'eat--prompt-stored-incomplete-input' and 'eat--prompt-matching-input-from-input-string' buffer-local. Record undo information if 'eat-enable-native-shell-prompt-editing' is enabled. Set 'mode-line-process' properly so that prompt mode is shown when enabled. * eat.el (eat--process-output-queue): Remove any narrowing temporarily when called. Don't * eat.el (eat--sentinel): Disable prompt mode. Also fix the bug where the point centers when the program exits, instead of going to the end of buffer. * eat.el (eat-exec): Don't set removed generalized variables 'eat-term-prompt-start-function', 'eat-term-set-cmd-function', 'eat-term-prompt-end-function', 'eat-term-cmd-start-function' and 'eat-term-cmd-finish-function'. Set terminal parameter 'ui-command-function' to 'eat--handle-uic'. * eat.el (eat--eshell-handle-uic): New function. * eat.el (eat--eshell-output-filter): Let-bind 'inhibit-read-only' only for required parts. * eat.el (eat--eshell-setup-proc-and-term): Set terminal parameter 'ui-command-function' to 'eat--eshell-handle-uic'. * eat.el (eat--eshell-sentinel): Fix the bug where the point centers when the program exits, instead of going to the end of buffer. * integration/bash (__eat_enable_integration): Send shell history.
2023-09-13 19:49:51 +06:00
"$(tail -n "${REPLY[4]}" "$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: bash
# End: