Skip to content

Commit 609fb65

Browse files
authored
fix(zsh): prevent terminal hang during sync and improve command execution (#2333)
1 parent 5859b29 commit 609fb65

4 files changed

Lines changed: 13 additions & 15 deletions

File tree

shell-plugin/lib/actions/config.zsh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ function _forge_action_model() {
9696
# Action handler: Sync workspace for codebase search
9797
function _forge_action_sync() {
9898
echo
99-
_forge_exec workspace sync
99+
# Execute sync with stdin redirected to prevent hanging
100+
# Sync doesn't need interactive input, so close stdin immediately
101+
_forge_exec workspace sync </dev/null
100102
}
101103

102104
# Helper function to select and set config values with fzf

shell-plugin/lib/actions/git.zsh

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ function _forge_action_commit() {
1919
else
2020
commit_message=$(FORCE_COLOR=true CLICOLOR_FORCE=1 $_FORGE_BIN commit --max-diff "$_FORGE_MAX_COMMIT_DIFF")
2121
fi
22-
23-
BUFFER=""
24-
CURSOR=0
2522
zle reset-prompt
2623
}
2724

@@ -49,10 +46,10 @@ function _forge_action_commit_preview() {
4946
# Check if there are staged changes to determine commit strategy
5047
if git diff --staged --quiet; then
5148
# No staged changes: commit all tracked changes with -a flag
52-
BUFFER="git commit -a -m '$commit_message'"
49+
BUFFER="git commit -am ${(qq)commit_message}"
5350
else
5451
# Staged changes exist: commit only what's staged
55-
BUFFER="git commit -m '$commit_message'"
52+
BUFFER="git commit -m ${(qq)commit_message}"
5653
fi
5754
# Move cursor to end of buffer for immediate execution
5855
CURSOR=${#BUFFER}

shell-plugin/lib/dispatcher.zsh

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,11 @@ function forge-accept-line() {
110110
# Add the original command to history before transformation
111111
print -s -- "$original_buffer"
112112

113-
# CRITICAL: For multiline buffers, move cursor to end so output doesn't overwrite
113+
# CRITICAL: Move cursor to end so output doesn't overwrite
114114
# Don't clear BUFFER yet - let _forge_reset do that after action completes
115115
# This keeps buffer state consistent if Ctrl+C is pressed
116-
if [[ "$BUFFER" == *$'\n'* ]]; then
117-
CURSOR=${#BUFFER}
118-
zle redisplay
119-
fi
116+
CURSOR=${#BUFFER}
117+
zle redisplay
120118

121119
# Handle aliases - convert to their actual agent names
122120
case "$user_action" in

shell-plugin/lib/helpers.zsh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ function _forge_fzf() {
1919
# Helper function to execute forge commands consistently
2020
# This ensures proper handling of special characters and consistent output
2121
function _forge_exec() {
22-
# Ensure FORGE_ACTIVE_AGENT always has a value, default to "forge"
2322
local agent_id="${_FORGE_ACTIVE_AGENT:-forge}"
24-
25-
eval "$_FORGE_BIN --agent $(printf '%q' "$agent_id") $(printf '%q ' "$@")"
23+
local -a cmd
24+
cmd=($_FORGE_BIN --agent "$agent_id" "$@")
25+
"${cmd[@]}"
2626
}
2727

2828
function _forge_reset() {
@@ -130,8 +130,9 @@ function _forge_start_background_sync() {
130130

131131
# Run sync once in background
132132
# Close all output streams immediately to prevent any flashing
133+
# Redirect stdin to /dev/null to prevent hanging if sync tries to read input
133134
{
134-
exec >/dev/null 2>&1
135+
exec >/dev/null 2>&1 </dev/null
135136
setopt NO_NOTIFY NO_MONITOR
136137
$_FORGE_BIN workspace sync "$workspace_path"
137138
} &!

0 commit comments

Comments
 (0)