Add regex fallback for prompt detection without shell integration#273
Merged
Conversation
`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).
873f5bd to
fe4abec
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ghostel-prompt-regexpdefcustom matched at BOL when theghostel-prompttext property is absent.ghostel-input-start-pointandghostel-beginning-of-input-or-lineto consult the regex before falling back to cursor / BOL.ghostel--regex-prompt-endthat 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'sC-awere useless on prompt rows because there was no way to detect where the prompt prefix ends.Default regex
Recognizes:
$,#,%,>>>>(the+quantifier handles multi-char prompts)λ(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 setghostel-prompt-regexptonilto 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 allpasses: 78/78 evil-ghostel, 180/180 native, 379/381 main (2 unrelated skipped).λ, prop-wins-over-regex precedence, regex-disabled fallback to cursor/BOL, helper edge cases.0,$work on the prompt row.python3: same.λprompt.