mirror of
https://github.com/atuinsh/atuin.git
synced 2026-06-01 18:47:18 +02:00
fix: Atuin hangs when attempting to spawn daemon from Ctrl+R invocation (#3502)
Codespell / Check for spelling errors (push) Has been cancelled
Nix / check (push) Has been cancelled
Nix / build-test (push) Has been cancelled
Rust / unit-test (macos-14) (push) Has been cancelled
Install / install (macos-14) (push) Has been cancelled
Rust / build (depot-ubuntu-24.04) (push) Has been cancelled
Rust / build (macos-14) (push) Has been cancelled
Rust / build (windows-latest) (push) Has been cancelled
Rust / cross-compile (x86_64-unknown-illumos) (push) Has been cancelled
Rust / unit-test (depot-ubuntu-24.04) (push) Has been cancelled
Rust / unit-test (windows-latest) (push) Has been cancelled
Rust / clippy (push) Has been cancelled
Rust / format (push) Has been cancelled
Shellcheck / shellcheck (push) Has been cancelled
build-docker / publish (push) Has been cancelled
Install / install (depot-ubuntu-24.04) (push) Has been cancelled
Rust / check (depot-ubuntu-24.04) (push) Has been cancelled
Rust / check (macos-14) (push) Has been cancelled
Rust / check (windows-latest) (push) Has been cancelled
Rust / integration-test (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Nix / check (push) Has been cancelled
Nix / build-test (push) Has been cancelled
Rust / unit-test (macos-14) (push) Has been cancelled
Install / install (macos-14) (push) Has been cancelled
Rust / build (depot-ubuntu-24.04) (push) Has been cancelled
Rust / build (macos-14) (push) Has been cancelled
Rust / build (windows-latest) (push) Has been cancelled
Rust / cross-compile (x86_64-unknown-illumos) (push) Has been cancelled
Rust / unit-test (depot-ubuntu-24.04) (push) Has been cancelled
Rust / unit-test (windows-latest) (push) Has been cancelled
Rust / clippy (push) Has been cancelled
Rust / format (push) Has been cancelled
Shellcheck / shellcheck (push) Has been cancelled
build-docker / publish (push) Has been cancelled
Install / install (depot-ubuntu-24.04) (push) Has been cancelled
Rust / check (depot-ubuntu-24.04) (push) Has been cancelled
Rust / check (macos-14) (push) Has been cancelled
Rust / check (windows-latest) (push) Has been cancelled
Rust / integration-test (push) Has been cancelled
This PR fixes a shell hang when daemon autostart happens from the interactive search widget. The bash/zsh/fish integrations run `atuin search -i` under command substitution and swap stdout/stderr so the TUI can draw to the terminal while the selected command is captured: ```sh 3>&1 1>&2 2>&3 ``` This leaves fd 3 open in the atuin search process. If search autostarts the daemon, the spawned long-running `atuin daemon start --daemonize` inherits fd 3, the command-substitution pipe, so the shell keeps waiting for EOF until the daemon is killed. The fix: close fd 3 after the swap in the non-tmux bash/zsh/fish paths: ```sh 3>&1 1>&2 2>&3 3>&- ``` Tested on zsh; I still need to confirm for bash and fish. Near as I can tell, the other shell integrations don't need this change. Fixes #3499
This commit is contained in:
@@ -1532,17 +1532,29 @@ impl Stdout {
|
||||
impl Drop for Stdout {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
execute!(self.writer, PopKeyboardEnhancementFlags).unwrap();
|
||||
|
||||
if !self.inline_mode {
|
||||
execute!(self.writer, terminal::LeaveAlternateScreen).unwrap();
|
||||
if let Err(e) = execute!(self.writer, PopKeyboardEnhancementFlags) {
|
||||
tracing::error!(?e, "Failed to pop keyboard enhancement flags");
|
||||
}
|
||||
if !self.no_mouse {
|
||||
execute!(self.writer, event::DisableMouseCapture).unwrap();
|
||||
}
|
||||
execute!(self.writer, event::DisableBracketedPaste).unwrap();
|
||||
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
if !self.inline_mode
|
||||
&& let Err(e) = execute!(self.writer, terminal::LeaveAlternateScreen)
|
||||
{
|
||||
tracing::error!(?e, "Failed to leave alt screen mode");
|
||||
}
|
||||
|
||||
if !self.no_mouse
|
||||
&& let Err(e) = execute!(self.writer, event::DisableMouseCapture)
|
||||
{
|
||||
tracing::error!(?e, "Failed to disable mouse capture");
|
||||
}
|
||||
|
||||
if let Err(e) = execute!(self.writer, event::DisableBracketedPaste) {
|
||||
tracing::error!(?e, "Failed to disable bracketed paste");
|
||||
}
|
||||
|
||||
if let Err(e) = terminal::disable_raw_mode() {
|
||||
tracing::error!(?e, "Failed to disable raw mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ __atuin_search_cmd() {
|
||||
__atuin_tmux_popup_cleanup
|
||||
trap - EXIT HUP INT TERM
|
||||
else
|
||||
ATUIN_SHELL=bash ATUIN_LOG=error ATUIN_QUERY=$READLINE_LINE atuin search "${search_args[@]}" -i 3>&1 1>&2 2>&3
|
||||
ATUIN_SHELL=bash ATUIN_LOG=error ATUIN_QUERY=$READLINE_LINE atuin search "${search_args[@]}" -i 3>&1 1>&2 2>&3 3>&-
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -329,7 +329,10 @@ __atuin_history() {
|
||||
READLINE_LINE="" READLINE_POINT=0
|
||||
|
||||
local __atuin_output
|
||||
__atuin_output=$(__atuin_search_cmd "$@")
|
||||
if ! __atuin_output=$(__atuin_search_cmd "$@"); then
|
||||
[[ $__atuin_output ]] && printf '%s\n' "$__atuin_output" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# We do nothing when the search is canceled.
|
||||
[[ $__atuin_output ]] || return 0
|
||||
|
||||
@@ -81,11 +81,13 @@ function _atuin_search
|
||||
set -l use_tmux_popup (_atuin_tmux_popup_check)
|
||||
|
||||
set -l ATUIN_H
|
||||
set -l ATUIN_STATUS 0
|
||||
if test "$use_tmux_popup" -eq 1
|
||||
set -l tmpdir (mktemp -d)
|
||||
if not test -d "$tmpdir"
|
||||
# if mktemp got errors
|
||||
set ATUIN_H (ATUIN_SHELL=fish ATUIN_LOG=error ATUIN_QUERY=(commandline -b) atuin search --keymap-mode=$keymap_mode $argv -i 3>&1 1>&2 2>&3 | string collect)
|
||||
set ATUIN_H (ATUIN_SHELL=fish ATUIN_LOG=error ATUIN_QUERY=(commandline -b) atuin search --keymap-mode=$keymap_mode $argv -i 3>&1 1>&2 2>&3 3>&- | string collect)
|
||||
set ATUIN_STATUS $pipestatus[1]
|
||||
else
|
||||
set -l result_file "$tmpdir/result"
|
||||
|
||||
@@ -102,6 +104,7 @@ function _atuin_search
|
||||
set -l popup_height (test -n "$ATUIN_TMUX_POPUP_HEIGHT" && echo "$ATUIN_TMUX_POPUP_HEIGHT" || echo "60%")
|
||||
tmux display-popup -d "$cdir" -w "$popup_width" -h "$popup_height" -E -E -- \
|
||||
sh -c "PATH='$PATH' ATUIN_SESSION='$ATUIN_SESSION' ATUIN_SHELL=fish ATUIN_LOG=error ATUIN_QUERY='$query' atuin search --keymap-mode=$keymap_mode$escaped_args -i 2>'$result_file'"
|
||||
set ATUIN_STATUS $status
|
||||
|
||||
if test -f "$result_file"
|
||||
set ATUIN_H (cat "$result_file" | string collect)
|
||||
@@ -113,7 +116,14 @@ function _atuin_search
|
||||
# In fish 3.4 and above we can use `"$(some command)"` to keep multiple lines separate;
|
||||
# but to support fish 3.3 we need to use `(some command | string collect)`.
|
||||
# https://fishshell.com/docs/current/relnotes.html#id24 (fish 3.4 "Notable improvements and fixes")
|
||||
set ATUIN_H (ATUIN_SHELL=fish ATUIN_LOG=error ATUIN_QUERY=(commandline -b) atuin search --keymap-mode=$keymap_mode $argv -i 3>&1 1>&2 2>&3 | string collect)
|
||||
set ATUIN_H (ATUIN_SHELL=fish ATUIN_LOG=error ATUIN_QUERY=(commandline -b) atuin search --keymap-mode=$keymap_mode $argv -i 3>&1 1>&2 2>&3 3>&- | string collect)
|
||||
set ATUIN_STATUS $pipestatus[1]
|
||||
end
|
||||
|
||||
if test "$ATUIN_STATUS" -ne 0
|
||||
test -n "$ATUIN_H"; and printf '%s\n' "$ATUIN_H" >&2
|
||||
commandline -f repaint
|
||||
return "$ATUIN_STATUS"
|
||||
end
|
||||
|
||||
set ATUIN_H (string trim -- $ATUIN_H | string collect) # trim whitespace
|
||||
|
||||
@@ -109,7 +109,7 @@ __atuin_search_cmd() {
|
||||
__atuin_tmux_popup_cleanup
|
||||
trap - EXIT HUP INT TERM
|
||||
else
|
||||
ATUIN_SHELL=zsh ATUIN_LOG=error ATUIN_QUERY=$BUFFER atuin search "${search_args[@]}" -i 3>&1 1>&2 2>&3
|
||||
ATUIN_SHELL=zsh ATUIN_LOG=error ATUIN_QUERY=$BUFFER atuin search "${search_args[@]}" -i 3>&1 1>&2 2>&3 3>&-
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -119,15 +119,21 @@ _atuin_search() {
|
||||
|
||||
# swap stderr and stdout, so that the tui stuff works
|
||||
# TODO: not this
|
||||
local output
|
||||
local output __atuin_status
|
||||
# shellcheck disable=SC2048
|
||||
output=$(__atuin_search_cmd $*)
|
||||
__atuin_status=$?
|
||||
|
||||
zle reset-prompt
|
||||
# re-enable bracketed paste
|
||||
# shellcheck disable=SC2154
|
||||
echo -n ${zle_bracketed_paste[1]} >/dev/tty
|
||||
|
||||
if (( __atuin_status != 0 )); then
|
||||
[[ -n $output ]] && print -r -- "$output" >/dev/tty
|
||||
return $__atuin_status
|
||||
fi
|
||||
|
||||
if [[ -n $output ]]; then
|
||||
RBUFFER=""
|
||||
LBUFFER=$output
|
||||
|
||||
Reference in New Issue
Block a user