fix: iris stops working after exec a command in bash (#66)
Fix #65 when the user presses Enter to run a command, Iris sets `isCommandActive = true` so it knows a command is running and skips rendering the overlay. After the command finishes, `isCommandActive` needs to reset to `false` for Iris to work again. In zsh/fish, preexec/precmd hooks send an `IRIS_CMD_STOP` signal over the IPC pipe, which Iris receives to reset `isCommandActive = false`. Bash has no equivalent hook, so `IRIS_CMD_STOP` is never sent and `isCommandActive` stays stuck at true forever so I added a bash-only fallback inside `isExecuting()`: if `isCommandActive` is true but `TIOCGPGRP` (a kernel API) confirms the shell's process group is back in the foreground (meaning the command finished), automatically reset `isCommandActive` to false. zsh/fish still rely on IPC signals as before also added a `PROMPT_COMMAND` hook to iris init bash to `send IRIS_CMD_STOP` after every command (belt-and-suspenders), though that's not the main fix
This commit is contained in:
@@ -71,6 +71,18 @@ if [ -z "$IRIS_PID" ] && [ -z "$IRIS_RESCUE" ]; then
|
|||||||
export IRIS_ACTIVE_SHELL="bash"
|
export IRIS_ACTIVE_SHELL="bash"
|
||||||
exec iris
|
exec iris
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Iris Autocomplete Hook
|
||||||
|
if [ -n "$IRIS_PID" ] && [ -n "$IRIS_FD" ]; then
|
||||||
|
_iris_bash_precmd() {
|
||||||
|
printf "IRIS_CMD_STOP\x00" >&$IRIS_FD 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ";$PROMPT_COMMAND;" != *";_iris_bash_precmd;"* ]]; then
|
||||||
|
PROMPT_COMMAND="_iris_bash_precmd${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
`)
|
`)
|
||||||
case "fish":
|
case "fish":
|
||||||
fmt.Printf(`
|
fmt.Printf(`
|
||||||
|
|||||||
@@ -287,6 +287,14 @@ func runWrapper() {
|
|||||||
renderOverlay := func() {}
|
renderOverlay := func() {}
|
||||||
isExecuting := func() bool {
|
isExecuting := func() bool {
|
||||||
if isCommandActive.Load() {
|
if isCommandActive.Load() {
|
||||||
|
// for bash: no preexec/precmd hooks, so fall back to TIOCGPGRP to detect when shell returns
|
||||||
|
if shellName == "bash" {
|
||||||
|
pgrp, pgrpErr := unix.IoctlGetInt(int(ptmx.Fd()), unix.TIOCGPGRP)
|
||||||
|
if pgrpErr == nil && pgrp == shellPGID {
|
||||||
|
isCommandActive.Store(false)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
pgrp, err := unix.IoctlGetInt(int(ptmx.Fd()), unix.TIOCGPGRP)
|
pgrp, err := unix.IoctlGetInt(int(ptmx.Fd()), unix.TIOCGPGRP)
|
||||||
|
|||||||
Reference in New Issue
Block a user