Skip to content

Commit 8f01412

Browse files
committed
only show unique entries in history search
1 parent 1cc404e commit 8f01412

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

stdlib/REPL/src/History/resumablefiltering.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,16 +258,19 @@ end
258258
Incrementally filter `candidates[1:idx]` in reverse order.
259259
260260
Pushes matches onto `out` until either `maxtime` is exceeded or `maxresults`
261-
collected, then returns the new resume index.
261+
collected, then returns the new resume index. Only unique entries (by content)
262+
are added to avoid showing duplicate history items.
262263
"""
263264
function filterchunkrev!(out::Vector{HistEntry}, candidates::DenseVector{HistEntry},
264265
spec::FilterSpec, idx::Int = length(candidates);
265266
maxtime::Float64 = Inf, maxresults::Int = length(candidates))
267+
seen = Set(e.content for e in out)
266268
batchsize = clamp(length(candidates) ÷ 512, 10, 1000)
267269
for batch in Iterators.partition(idx:-1:1, batchsize)
268270
time() > maxtime && break
269271
for outer idx in batch
270272
entry = candidates[idx]
273+
entry.content seen && continue
271274
if !isempty(spec.modes)
272275
entry.mode spec.modes || continue
273276
end
@@ -293,6 +296,7 @@ function filterchunkrev!(out::Vector{HistEntry}, candidates::DenseVector{HistEnt
293296
end
294297
end
295298
matchfail && continue
299+
push!(seen, entry.content)
296300
pushfirst!(out, entry)
297301
length(out) == maxresults && break
298302
end

stdlib/REPL/test/history.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,29 @@ end
344344
@test filterchunkrev!(results, entries, spec) == 0
345345
@test results == entries[3:6]
346346
end
347+
@testset "Uniqueness" begin
348+
empty!(results)
349+
# Create entries with duplicate content
350+
dup_entries = [
351+
HistEntry(:julia, now(UTC), "println(\"hello\")", 1),
352+
HistEntry(:julia, now(UTC), "cos(2π)", 2),
353+
HistEntry(:julia, now(UTC), "println(\"hello\")", 3), # duplicate
354+
HistEntry(:julia, now(UTC), "sin(π)", 4),
355+
HistEntry(:julia, now(UTC), "cos(2π)", 5), # duplicate
356+
HistEntry(:julia, now(UTC), "println(\"hello\")", 6), # duplicate
357+
HistEntry(:julia, now(UTC), "tan(π/4)", 7),
358+
]
359+
cset = ConditionSet("") # Match all
360+
spec = FilterSpec(cset)
361+
@test filterchunkrev!(results, dup_entries, spec) == 0
362+
# Should only get unique entries
363+
# Since we iterate in reverse (7->1), we keep the most recent occurrence of each unique content
364+
@test length(results) == 4
365+
@test results[1] == dup_entries[4] # sin(π)
366+
@test results[2] == dup_entries[5] # cos(2π) - most recent
367+
@test results[3] == dup_entries[6] # println("hello") - most recent
368+
@test results[4] == dup_entries[7] # tan(π/4)
369+
end
347370
end
348371
@testset "Strictness comparison" begin
349372
c1 = ConditionSet("hello world")

0 commit comments

Comments
 (0)