Skip to content

Add regex fallback for prompt detection without shell integration#273

Merged
dakra merged 1 commit into
mainfrom
prompt-regex-fallback
May 13, 2026
Merged

Add regex fallback for prompt detection without shell integration#273
dakra merged 1 commit into
mainfrom
prompt-regex-fallback

Conversation

@dakra
Copy link
Copy Markdown
Owner

@dakra dakra commented May 13, 2026

Summary

  • Adds ghostel-prompt-regexp defcustom matched at BOL when the ghostel-prompt text property is absent.
  • Updates ghostel-input-start-point and ghostel-beginning-of-input-or-line to consult the regex before falling back to cursor / BOL.
  • New private helper ghostel--regex-prompt-end that returns nil for all-prompt lines (so empty prompts still fall through to BOL/cursor).

Motivation

Without OSC 133 integration — raw zsh, Python REPL, sqlite3, ssh into a box without the helper sourced — 0, $, word motions, and the bare ghostel keymap's C-a were useless on prompt rows because there was no way to detect where the prompt prefix ends.

Default regex

"^[^#$%>λ❯→➜\n]*[#$%>λ❯→➜]+ *"

Recognizes:

  • Standard shell prompts: $ , # , % , >
  • Python and similar REPLs: >>> (the + quantifier handles multi-char prompts)
  • Themed: λ (Lisp/Haskell), (Starship/Pure/Powerlevel10k), (oh-my-zsh robbyrussell),

The negated character class [^#$%>λ❯→➜\n]* forces the match to stop at the first prompt character on the line, so command lines echoed into scrollback (e.g. $ echo $foo) match by their leading prompt prefix rather than a later $ deeper in the line.

Trade-offs

Lines that start with one of the prompt characters in output — diff lines (> excluded), markdown headings (# H), math comparisons (5 > 3) — yield false positives for column-aware motions. OSC 133 integration remains the robust fix; the regex is a fallback for contexts where integration isn't available. Users can also set ghostel-prompt-regexp to nil to disable the fallback entirely, or customize it for prompts the default doesn't catch (, » , etc.).

Out of scope

evil-ghostel--input-start-from-prop (used by operator clamping) stays strict — prop-only — so its docstring guarantee about not mistaking the cursor for the input boundary holds. Extending it to consult the regex is a follow-up on the evil-ghostel branch.

Test plan

  • make -j4 all passes: 78/78 evil-ghostel, 180/180 native, 379/381 main (2 unrelated skipped).
  • 10 new tests cover regex fallback for Python REPL and λ, prop-wins-over-regex precedence, regex-disabled fallback to cursor/BOL, helper edge cases.
  • Live test in zsh without integration: 0, $ work on the prompt row.
  • Live test in python3: same.
  • Live test with λ prompt.

`ghostel-input-start-point' and `ghostel-beginning-of-input-or-line'
previously relied exclusively on the `ghostel-prompt' text property
set by OSC 133 shell integration.  Without integration — raw zsh,
Python REPL, sqlite3, ssh into a box without the helper sourced —
they fell back to either the cursor position (input-start) or
`beginning-of-line' (column 0), which left `0', `$', word motions,
and the bare ghostel keymap's `C-a' useless on prompt rows.

This adds `ghostel-prompt-regexp', a defcustom matched anchored at
BOL when the property isn't present:

    "^[^#$%>λ❯→➜\n]*[#$%>λ❯→➜]+ *"

The negated character class forces the match to stop at the first
prompt character on the line, so command lines echoed into
scrollback (e.g. `$ echo $foo') are detected by their leading
prompt prefix rather than a later `$' deeper in the line.

Default recognizes:
- Standard shell prompts: $ # % >
- Python and similar REPLs: >>> (the `+' quantifier handles the
  multi-char case correctly)
- Themed prompts: λ ❯ (Starship/Pure/Powerlevel10k) ➜ (oh-my-zsh) →

The new private helper `ghostel--regex-prompt-end' returns nil for
all-prompt lines (no input area past the prefix) so callers fall
through to BOL or the cursor as appropriate.

Trade-off: lines that *start* with one of these characters in
output — diff lines (`> excluded'), markdown headings (`# H'),
math comparisons (`5 > 3') — yield false positives for column-aware
motions.  OSC 133 integration remains the robust fix; the regex is
a fallback for contexts where integration isn't available.

The `evil-ghostel--input-start-from-prop' helper used by operator
clamping is intentionally unchanged — it stays strict (prop-only)
so the docstring's guarantee about not mistaking the cursor for
the input boundary holds.  Extending it to consult the regex is a
follow-up on the evil-ghostel branch.

Tests: 10 new tests covering regex fallback for Python REPL and
`λ', prop-wins-over-regex precedence, regex-disabled fallback to
cursor/BOL, and helper edge cases (empty all-prompt line, content
match, nil regex).
@dakra dakra force-pushed the prompt-regex-fallback branch 2 times, most recently from 873f5bd to fe4abec Compare May 13, 2026 21:21
@dakra dakra merged commit fe4abec into main May 13, 2026
22 checks passed
@dakra dakra deleted the prompt-regex-fallback branch May 13, 2026 21:24
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.

1 participant