Skip to content

Commit cc7ed22

Browse files
committed
Overhaul REPL history, introduce a flashy searcher
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)
1 parent a83369a commit cc7ed22

File tree

12 files changed

+1869
-740
lines changed

12 files changed

+1869
-740
lines changed

stdlib/Manifest.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
195195
version = "1.11.0"
196196

197197
[[deps.REPL]]
198-
deps = ["FileWatching", "InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"]
198+
deps = ["Dates", "FileWatching", "InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Mmap", "Sockets", "StyledStrings", "Unicode"]
199199
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
200200
version = "1.11.0"
201201

stdlib/REPL/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
33
version = "1.11.0"
44

55
[deps]
6+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
67
FileWatching = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
78
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
89
JuliaSyntaxHighlighting = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011"
910
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
11+
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
1012
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
1113
StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b"
1214
Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

stdlib/REPL/src/History/History.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
module History
4+
5+
using ..REPL: REPL
6+
7+
using StyledStrings: @styled_str as @S_str, Face, addface!, face!, annotations, AnnotatedIOBuffer, AnnotatedString, AnnotatedChar
8+
using JuliaSyntaxHighlighting: highlight
9+
using Base.Threads
10+
using Mmap
11+
using Dates
12+
using InteractiveUtils: clipboard
13+
14+
export HistoryFile, HistEntry, runsearch
15+
16+
const FACES = (
17+
# :REPL_history_search_prompt => Face(foreground=:blue, inherit=:julia_prompt),
18+
:REPL_history_search_seperator => Face(foreground=:blue),
19+
:REPL_history_search_prefix => Face(foreground=:magenta),
20+
:REPL_history_search_selected => Face(foreground=:blue),
21+
:REPL_history_search_unselected => Face(foreground=:grey),
22+
# :REPL_history_search_preview_box => Face(foreground=:grey),
23+
:REPL_history_search_hint => Face(foreground=:magenta, slant=:italic, weight=:light),
24+
:REPL_history_search_results => Face(inherit=:shadow),
25+
:REPL_history_search_match => Face(weight = :bold, underline = true),
26+
)
27+
28+
include("histfile.jl")
29+
include("resumablefiltering.jl")
30+
include("prompt.jl")
31+
include("display.jl")
32+
include("search.jl")
33+
34+
__init__() = foreach(addface!, FACES)
35+
36+
end

0 commit comments

Comments
 (0)