feat: detect another command is running to stop iris

This commit is contained in:
verse91
2026-04-27 16:06:00 +07:00
parent b6e5096092
commit cea2a7bee7
2 changed files with 50 additions and 14 deletions
+43 -13
View File
@@ -20,6 +20,7 @@ import (
"github.com/versenilvis/iris/commands/core" "github.com/versenilvis/iris/commands/core"
"github.com/versenilvis/iris/integration" "github.com/versenilvis/iris/integration"
"github.com/versenilvis/iris/integration/shell" "github.com/versenilvis/iris/integration/shell"
"golang.org/x/sys/unix"
"golang.org/x/term" "golang.org/x/term"
) )
@@ -165,6 +166,15 @@ func runWrapper() {
var disableGhostText atomic.Bool var disableGhostText atomic.Bool
isExecuting := func() bool {
pgrp, err := unix.IoctlGetInt(int(ptmx.Fd()), unix.TIOCGPGRP)
if err != nil {
return false
}
// when another command starts, it puts it in a new process group and gives it the PTY
return pgrp != core.ShellPID
}
// listen for suggestion requests from shell scripts via the ipc pipe // listen for suggestion requests from shell scripts via the ipc pipe
go func() { go func() {
scanner := bufio.NewScanner(r) scanner := bufio.NewScanner(r)
@@ -183,6 +193,15 @@ func runWrapper() {
for scanner.Scan() { for scanner.Scan() {
query := scanner.Text() query := scanner.Text()
if query == "IRIS_CMD_STOP" {
continue
}
if isExecuting() {
continue
}
results := mergeResults(query, "spec") results := mergeResults(query, "spec")
if len(results) == 0 { if len(results) == 0 {
os.Stdout.Write([]byte(overlay.ClearAndDisable())) os.Stdout.Write([]byte(overlay.ClearAndDisable()))
@@ -215,7 +234,7 @@ func runWrapper() {
renderTimer.Stop() renderTimer.Stop()
} }
if !suggestionsEnabled { if !suggestionsEnabled || isExecuting() {
return return
} }
@@ -231,6 +250,10 @@ func runWrapper() {
// This completely prevents the asynchronous ghost text race condition where the PTY echo // This completely prevents the asynchronous ghost text race condition where the PTY echo
// overwrites the first letter of our ghost text! // overwrites the first letter of our ghost text!
renderTimer = time.AfterFunc(15*time.Millisecond, func() { renderTimer = time.AfterFunc(15*time.Millisecond, func() {
if isExecuting() {
return
}
debugLog("[Render] query: '%s', mode: %s", bufCopy, modeCopy) debugLog("[Render] query: '%s', mode: %s", bufCopy, modeCopy)
results := mergeResults(bufCopy, modeCopy) results := mergeResults(bufCopy, modeCopy)
debugLog("[Render] results found: %d", len(results)) debugLog("[Render] results found: %d", len(results))
@@ -266,6 +289,11 @@ func runWrapper() {
} }
if n > 0 { if n > 0 {
if isExecuting() {
ptmx.Write(inputSlice[:n])
continue
}
shouldOverlayDraw := false shouldOverlayDraw := false
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
b := inputSlice[i] b := inputSlice[i]
@@ -325,18 +353,20 @@ func runWrapper() {
} }
// forward escape sequence to pty if not intercepted // forward escape sequence to pty if not intercepted
os.Stdout.Write([]byte(overlay.ClearAndDisable())) if !intercepted {
disableGhostText.Store(true) os.Stdout.Write([]byte(overlay.ClearAndDisable()))
naiveBuffer = "" disableGhostText.Store(true)
naiveBuffer = ""
ptmx.Write([]byte{b}) ptmx.Write([]byte{b})
// skip remaining bytes of the escape sequence to avoid misinterpretation // skip remaining bytes of the escape sequence to avoid misinterpretation
for j := i + 1; j < n; j++ { for j := i + 1; j < n; j++ {
char := inputSlice[j] char := inputSlice[j]
ptmx.Write([]byte{char}) ptmx.Write([]byte{char})
i = j i = j
if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || char == '~' { if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || char == '~' {
break break
}
} }
} }
continue continue
@@ -408,7 +438,7 @@ func runWrapper() {
naiveBuffer = "" naiveBuffer = ""
} }
shouldOverlayDraw = true shouldOverlayDraw = true
case '\r', 0x03, 0x15, 0x0C: // enter, ctrl+c, ctrl+u, ctrl+l: clear buffer on line reset case '\r', '\n', 0x03, 0x15, 0x0C: // enter, ctrl+c, ctrl+u, ctrl+l: clear buffer on line reset
naiveBuffer = "" naiveBuffer = ""
disableGhostText.Store(false) disableGhostText.Store(false)
os.Stdout.Write([]byte(overlay.ClearAndDisable())) os.Stdout.Write([]byte(overlay.ClearAndDisable()))
+7 -1
View File
@@ -8,7 +8,13 @@ if [[ -n "$IRIS_FD" ]]; then
print -u $IRIS_FD -N -r -- "$LBUFFER" 2>/dev/null print -u $IRIS_FD -N -r -- "$LBUFFER" 2>/dev/null
} }
_iris_precmd() {
print -u $IRIS_FD -N -r -- "IRIS_CMD_STOP" 2>/dev/null
}
autoload -Uz add-zle-hook-widget autoload -Uz add-zle-hook-widget
# Hook into ZLE so this runs absolutely every time the line buffer changes autoload -Uz add-zsh-hook
add-zle-hook-widget line-pre-redraw _iris_send_lbuffer add-zle-hook-widget line-pre-redraw _iris_send_lbuffer
add-zsh-hook precmd _iris_precmd
fi fi