-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
The Fanciest REPL History in the Land #59819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Anyone else getting "video playback aborted due to a network error"? |
If possible, it would be nice to cut this up into some orthogonal pieces. For example, the AnnotatedString perf improvements could be a separate PR that (with benchmarks) could be merged and would make the diff here smaller and easier to review. |
stdlib/REPL/src/History/search.jl
Outdated
filename = try | ||
readline(term.in_stream) | ||
catch err | ||
if err isa InterruptException | ||
"" | ||
else | ||
rethrow() | ||
end | ||
end | ||
isempty(filename) && (println(out, S"\e[F\e[2K{light,grey:{bold:history>} {red:×} History selection aborted}\n"); return) | ||
write(filename, "# Julia REPL history excerpt\n\n", content) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it should default write to a location? The prompt could default to ~/.julia/history.jl
(or a more appropriate location).
Ideally, the prompt for the filename would also allow scrolling up and down with the up arrow and down arrow, typing some characters of the file and hitting up arrow to narrow the search, have a ghost text of the last file name or the default file name so right arrow completes it etc. But I can imagine this being awkward the way things are set up in the REPL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, the prompt for the filename would also allow scrolling up and down with the up arrow and down arrow, typing some characters of the file and hitting up arrow to narrow the search, have a ghost text of the last file name or the default file name so right arrow completes it etc. But I can imagine this being awkward the way things are set up in the REPL?
I've had exactly the same thought. I just can't be bothered to make it happen 😅
I'm happy to split this up, but there are really just three parts to it:
I could split 1-2 off into a separate PR to review, if that sounds like a nice idea?
There's only suspicious performance here, not perf improvements, unfortunately 😞. I say "suspicious" because if I remove the keyword argument from For now, I've left these julia/base/strings/annotated_io.jl Lines 202 to 226 in cc7ed22
julia/base/strings/annotated_io.jl Lines 236 to 240 in cc7ed22
|
cc7ed22
to
75fd56d
Compare
I've just added back ~400 loc of the original code for using up/down arrow keys to go through recent history without If you start a new REPL and immediately press up arrow, it does nothing the first time. Not quite sure why... (any ideas?) I would like to add session-awareness. Maybe I'll try to drop that in this PR too? |
75fd56d
to
221b4e5
Compare
Rebased to the latest REPL Syntax Highlighting |
221b4e5
to
ee23322
Compare
Fixed some typos. |
The precompilation situation is looking pretty decent, this is all I'm seeing with
|
ee23322
to
3a6d8d7
Compare
Rebased now that #59778 has been merged. |
3a6d8d7
to
4bac24f
Compare
Fixed. |
4bac24f
to
c7a66cb
Compare
Thanks to Miguel, Camillo, and Sundar for taking this for a test-drive and providing feedback 🙂 Changes:
|
7126dd7
to
0da2a86
Compare
Rebase (get the REPL precompilation improvements) |
003fb6c
to
1faaa1b
Compare
|
Since almost* all tests were passing before, and all the new REPL History tests (~100) are passing locally, I expect that we'll see the same result after CI finishes. *there was one issue, a hang on FreeBSD, with the process terminated during |
The history display/interface is not currently covered by tests, not because I don't think it's worth testing, but because it's not clear how best to do so when the display is done asynchronously (two Furthermore, a lot of what we want to test is visual and behaviour varies by terminal emulator (e.g. see the sync / Terminal.app issue noted earlier). While not a substitute for unit tests, I am rather comforted by the fact that throughout the development of this feature, none of the testers have run into any major failures (the kind that would make someone want to reach for the current basic history finder: there's been no issing history, failure to parse, failure to filter, hang, etc.). The most substantial issues found by testers was (1) a precompilation issue on Mac, (2) Windows not supporting So, while I expect there to be a somewhat long tail of corner cases that come up, I am confident that in its current state this feature is a strict improvement over the current history experience, with no regressions in basic functionality. |
26d4e1b
to
f70652d
Compare
|
In my estimation, this PR should now be good to merge (not squashed, preferably, because the commits actually are meaningful). |
Tests are soley failing because of a Pkg/SHA issue:
I'll bump the |
f70652d
to
500feca
Compare
500feca
to
0ca1135
Compare
I accidentally pressed twice C-s and ended up in the history saving menu, then instinctively pressed C-g in the hope of aborting, but that didn't work (first issue), it only toggled the option, which is supposed to happen only with TAB. It looks like pressing any key toggles the options (second issue). Then I pressed C-c to try and exit from the history saving menu, that worked, but, also, I lost the cursor (third issue). |
ctrl + s seems to be launching the interactive history for me julia-ctrl-s.mov |
Similar issue when searching for |
So, currently, times are written as I've gone with (b) here, changing the format to
This does seem confusing. I've just adjusted the mode to be consistently stored/read in lowercase, and searched case-insensitive.
Curious, I have yet to see this behaviour. What's your platform/terminal?
That's what I get for an overly quick/casual refactor. Fixed.
Removed.
Urgh. I'm not sure how to address this well. I'd like to make it so that long prompts cause horizontal scrolling, but then I can't just reuse
Is there something extra you mean by "selecting"? Just going up arrow x3 down arrow x2 gets me back to
Initials, for instance,
Hmm, I thought I put C-g in the abort keymap. I missed it. Added now.
Currently, it happens with any non-abort non-select key.
🤔 That's a surprise. There's an initial I could make it so that aborting now takes you back to the history selection UI, that seems potentially more intuitive to me? |
500feca
to
d598c76
Compare
Another one I hit (enter
|
d598c76
to
dde05e5
Compare
Thanks, fixed in cb0894a. I've also had a chat with Mosè and figured out the disappearing cursor issue:
|
dde05e5
to
e396d06
Compare
|
Extract the replacement loop body into `_replace_once` to ease future annotation tracking during string replacement operations. The new function returns match information (pattern index, match range, bytes written) that will be needed to properly adjust annotation positions when replacements occur.
Implement `replace` function for `AnnotatedString` that properly handles annotation regions during pattern replacement operations. The function tracks which bytes are replaced versus preserved, maintaining annotations only on original content and adding new annotations from replacement text. - Supports AnnotatedChar, AnnotatedString, and SubString replacements - Drops, shifts, and splits existing annotations appropriately - Refactored `_insert_annotations!` to work with annotation vectors directly - Adjacent replacements with identical annotations are merged into single regions - Lots of tests (thanks Claude!) Performance is strangely poor. For the test case mentioned in the REVIEW comment within `_insert_annotations!` we should be able to perform the replacement in ~200ns (compared to ~70ns for the equivalent unannotated case). However, for two reasons that are beyond me instead it takes ~4400ns. See the REVIEW comments for more details, help would be much appreciated.
Discarding the annotations can come as a bit of a surprise best avoided.
Since the dawn of the Julia REPL, history completion has been limited to a readline-style interface. OhMyREPL improved the experience with fzf, but those who yearned for a delightful history completion experience (me) were left underwhelmed. With this overhaul, I now find myself spending more time looking through my history because it's just *so nice* to do so. The new history system is organised as a standalone module in stdlib/REPL/src/History with a clear separation of concerns: 1. History file management 2. Event-driven prompt/UI updating 3. Incremental filtering 4. UI display 5. Search coordination (prompt + display + filter) I've attempted to pull out all the (reasonable) stops to make history searching as fluid and snappy as possible. By memory mapping the history file in the initial read, and optimising the parser, we can read ~2 million history items per second. Result filtering is incremental and resumable, performed in dynamically sized batches to ensure responsiveness. Rapid user inputs are debouced. We store a log-structured record of previous search result, and compare search strictness to resume from prior partial results instead of filtering the history from scratch every time. Syncronisation between the interface and filtering is enabled via a Channel-based event loop. Enjoy! (I know I am)
Contains the following commits: 5bfd1161e * STDLIBS_BY_VERSION: Check sorted & require same minor (JuliaLang#4414) ce986129c * Fix completion on empty command (JuliaLang#4418) 8d74d35d1 * update SHA compat (JuliaLang#4436) 14c5ae327 * add a docstring to Registry module (JuliaLang#4432) bbb9e6d23 * allow `generate` into an empty directory (JuliaLang#4430) a1818b9a9 * Drop the REPL search keymap (JuliaLang#4425) baa7981c7 * do not try to update registries in an unwritable folder (JuliaLang#4429) 01690b54b * make `.path` field consistently be relative manifest and convert to project relative upon writing to a project file (JuliaLang#4427) 3306ed522 * Deduplicate suggestions in package completions (JuliaLang#4431)
e396d06
to
f604c7c
Compare
|
The Fanciest REPL History in the Land ✨
Do you dread typing out code for the second time? Are you a particular enjoyed of REPL history?
Well, I know I am, and for years I have yearned for something better than the current
readline
-style completion, better than OhMyREPL.jl's fzf-driven completion, better than any REPL history I've seen before!It's not quite finished baking, but we're onto the final stretch 😀
repl_history_demo.webm
Thanks to @kdheepak, @jakobnissen, and @digital-carver for helping me design the UI and UX over on Zulip (#repl > Revamped REPL history).
Features
TODO
replace
methodreplace
methodreplace
method (see: theREVIEW: ...
code comments inannotated_io.jl
)This PR is on top of #59778, because I think I can safely assume that will be merged first.