Skip link detection on the active prompt and prompt prefix (#199)#212
Merged
Conversation
91a9d97 to
31ee7fa
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #199 where, in tty Emacs, linkified text can steal the RET keybinding while the cursor is on the actively edited prompt line. It adds a semantic “user input” marker from the renderer and updates the Elisp URL/file detection to avoid linkifying the active input while keeping historical input linkified.
Changes:
- Add a
ghostel-inputtext property (set by the Zig renderer for OSC 133 B..C input cells). - Update
ghostel--detect-urlsto always skipghostel-promptand to skipghostel-inputonly on the active prompt line (with an O(1) per-match check). - Add Elisp + native-focused tests covering active-input skipping and wide-char input boundaries.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
lisp/ghostel.el |
Adds skip predicate and active-line bounds to avoid linkifying active prompt input. |
src/render.zig |
Tracks per-row input character range and applies ghostel-input property during insert/styling. |
src/emacs.zig |
Adds pre-interned symbol for ghostel-input so the native module can set the property. |
test/ghostel-test.el |
Adds regression tests for active-input URL detection skipping and OSC 133 input property behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
aff8f14 to
a53a7ba
Compare
Plain-text URL/file detection ran across the whole viewport including
the cell the user was typing into. In tty Emacs, RET on a linkified
cell resolves to `ghostel-open-link-at-point' (text-property keymap
overrides ghostel-mode-map), so pressing return at a path the shell
echoes — e.g. `cd src/main.rs' — opens the file instead of running
the command.
The renderer now marks OSC 133 B..C cells with a `ghostel-input' text
property alongside the existing `ghostel-prompt', and paints
`ghostel-prompt' only over the prompt prefix when an input range is
known (instead of the whole row). `ghostel--detect-urls' skips
`ghostel-prompt' regions unconditionally and skips `ghostel-input'
on the cursor's line only — historical typed commands keep their
links so the user can still follow a path inside an old `echo foo/bar'
or `cd ~/proj'.
The bundled bash/zsh/fish integrations are updated to emit 133;A and
133;B from PS1/PROMPT/fish_prompt itself rather than back-to-back from
PROMPT_COMMAND/precmd before the prompt expands. With both markers
fired pre-prompt, libghostty saw zero cells between A and B and tagged
the entire prompt row (prefix + input) as INPUT, defeating the prefix
protection.
For bash there are two extra wrinkles:
* bash 5.x readline redraws the prompt after bracketed-paste-mode
setup without re-firing PROMPT_COMMAND, and for multi-line prompts
redraws only the last visual line. We inject 133;A after every
newline in PS1 (literal newlines and the `\n' PS1 escape) so the
partial last-line redraw still has a 133;A to anchor PROMPT scope.
* The OSC terminator is BEL (`\a') rather than ST (`\e\\'): bash's
`${var//pat/repl}' substitution eats backslashes in the
replacement, mangling ST-terminated markers.
Closes #199
5301fee to
c145c5e
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
cd src/main.rs). The shell never sees RET — issue After adding a command on the shell, I need a trailing space before return executes the command #199.ghostel-inputtext property.ghostel--detect-urlsnow skipsghostel-promptalways (shell-generated decoration) and skipsghostel-inputonly on the cursor's line — historical typed commands stay clickable.(bol . eol)cons; the per-match skip check is O(1) instead ofline-number-at-pos(O(pos)).Test plan
make -j4 all: 39 zig + 103 native + 219 elisp, all green.mainfirst, passes after the fix:ghostel-test-detect-urls-skips-active-input(elisp): historical input/URL → linkified; active input/URL → skipped; intra-line partial skip; prompt prefix never linkified.ghostel-test-osc133-input-text-property(native): cells between OSC 133 B and C carryghostel-input; prompt prefix does not.ghostel-test-osc133-input-wide-char-boundary(native): wide CJK input takes 1 Emacs char ofghostel-input; the spacer-tail produces no Emacs char and doesn't extend the region.make bench-quick, 10 iters × 512KB URL/path-heavy data) — within run-to-run noise vsmain. The skip-check optimization protects against the worst case (large scrollback × many matches per redraw).*ghostel*(zsh shell integration): typingecho ghostel.elis not clickable while typing; after RET, outputghostel.elis clickable; scrolling back to the historical command line, the path insideecho ghostel.elis also clickable; the cwd shown by the prompt prefix is never clickable.Caveats
ghostel-promptand lose the historical-input-clickable benefit (the active prompt is still RET-safe).