Skip to content

Handle bash-5.1+ PROMPT_COMMAND arrays in the bash integration#542

Merged
dakra merged 1 commit into
mainfrom
fix/540-prompt-command-array
Jul 14, 2026
Merged

Handle bash-5.1+ PROMPT_COMMAND arrays in the bash integration#542
dakra merged 1 commit into
mainfrom
fix/540-prompt-command-array

Conversation

@dakra

@dakra dakra commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Fixes #540.

systemd >= 258 installs /etc/profile.d/80-systemd-osc-context.sh (enabled on Fedora 44), which converts PROMPT_COMMAND into a bash-5.1+ array by appending __systemd_osc_context_precmdline, and emits OSC 3008 context sequences. The OSC 3008 sequences themselves are harmless (libghostty parses them as a no-op) — the breakage was in ghostel.bash:

  • The scalar capture "${PROMPT_COMMAND:+$PROMPT_COMMAND}" only sees element [0] of an array, and the scalar overwrite only replaces element [0], so systemd's hook survived as a sibling array element.
  • That sibling ran at top level after the wrapper each prompt cycle, firing the DEBUG trap as if a user command had started: it restored the unmarked PS1/PS2 and emitted a stray 133;C after 133;A. The prompt was then displayed with no semantic marks, so no row ever got the ghostel-prompt property and C-c M-p / C-c M-n found nothing.

Changes

  • Capture every PROMPT_COMMAND element (scalar or array) and collapse the variable to the wrapper alone, keeping correct $? for 133;D and OSC 7 firing last (the tramp getting triggered inside local fedora-toolbox container #276 vte race).
  • Run the captured hooks inside the wrapper with the user command's $? restored before each, so status-reporting hooks (systemd, vte) stay accurate.
  • Guard the DEBUG trap against PROMPT_COMMAND content by matching BASH_COMMAND against ;/newline-split fragments (bash-preexec's technique), covering compound hooks appended after load. Nounset-safe and bash 3.2 compatible.

Verification

  • Two new regression tests (array capture incl. exit-status fidelity, compound sibling-hook guard); both fail against the old script.
  • Live-verified with a replica of systemd's script: the old integration reproduces Prompt tracking breaks in bash when systemd OSC context is enabled #540 exactly; with the fix, prompt navigation works and systemd's hook keeps running with correct exit statuses.
  • Regression-swept common setups live (bash 5.3 empty rc / classic scalar PROMPT_COMMAND / multiline PS1, bash 3.2): no behavior changes.

systemd >= 258 ships a profile.d script that converts PROMPT_COMMAND
into an array before ghostel.bash loads. The scalar capture saw only
element 0 and the scalar overwrite left the other elements running at
top level, where each prompt cycle they fired the DEBUG trap after the
wrapper finished - unwrapping PS1 and emitting a stray 133;C after
133;A, so no row was ever marked as a prompt and prompt navigation
found nothing.

Capture every PROMPT_COMMAND element and collapse the variable to the
wrapper alone, run the captured hooks inside the wrapper with the user
command's $? restored, and guard the DEBUG trap against PROMPT_COMMAND
content by matching BASH_COMMAND against ';'/newline-split fragments
(nounset-safe, bash 3.2 compatible).

Fixes #540
@dakra dakra merged commit 4edd130 into main Jul 14, 2026
28 checks passed
@dakra dakra deleted the fix/540-prompt-command-array branch July 14, 2026 10:22
@dakra dakra temporarily deployed to github-pages July 14, 2026 10:22 — with GitHub Actions Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prompt tracking breaks in bash when systemd OSC context is enabled

1 participant