Skip to content

Commit 7859e32

Browse files
IanButterworthKristofferC
authored andcommitted
use more efficient _readdirx for tab completion (#53540)
Fixes #53153 (cherry picked from commit 188e386)
1 parent 6904351 commit 7859e32

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

stdlib/REPL/src/REPLCompletions.jl

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ using Core: CodeInfo, MethodInstance, CodeInstance, Const
88
const CC = Core.Compiler
99
using Base.Meta
1010
using Base: propertynames, something, IdSet
11+
using Base.Filesystem: _readdirx
1112

1213
abstract type Completion end
1314

@@ -317,8 +318,8 @@ function cache_PATH()
317318
continue
318319
end
319320

320-
filesinpath = try
321-
readdir(pathdir)
321+
path_entries = try
322+
_readdirx(pathdir)
322323
catch e
323324
# Bash allows dirs in PATH that can't be read, so we should as well.
324325
if isa(e, Base.IOError) || isa(e, Base.ArgumentError)
@@ -328,13 +329,13 @@ function cache_PATH()
328329
rethrow()
329330
end
330331
end
331-
for file in filesinpath
332+
for entry in path_entries
332333
# In a perfect world, we would filter on whether the file is executable
333334
# here, or even on whether the current user can execute the file in question.
334335
try
335-
if isfile(joinpath(pathdir, file))
336-
@lock PATH_cache_lock push!(PATH_cache, file)
337-
push!(this_PATH_cache, file)
336+
if isfile(entry)
337+
@lock PATH_cache_lock push!(PATH_cache, entry.name)
338+
push!(this_PATH_cache, entry.name)
338339
end
339340
catch e
340341
# `isfile()` can throw in rare cases such as when probing a
@@ -378,11 +379,11 @@ function complete_path(path::AbstractString;
378379
else
379380
dir, prefix = splitdir(path)
380381
end
381-
files = try
382+
entries = try
382383
if isempty(dir)
383-
readdir()
384+
_readdirx()
384385
elseif isdir(dir)
385-
readdir(dir)
386+
_readdirx(dir)
386387
else
387388
return Completion[], dir, false
388389
end
@@ -392,11 +393,10 @@ function complete_path(path::AbstractString;
392393
end
393394

394395
matches = Set{String}()
395-
for file in files
396-
if startswith(file, prefix)
397-
p = joinpath(dir, file)
398-
is_dir = try isdir(p) catch ex; ex isa Base.IOError ? false : rethrow() end
399-
push!(matches, is_dir ? file * "/" : file)
396+
for entry in entries
397+
if startswith(entry.name, prefix)
398+
is_dir = try isdir(entry) catch ex; ex isa Base.IOError ? false : rethrow() end
399+
push!(matches, is_dir ? entry.name * "/" : entry.name)
400400
end
401401
end
402402

@@ -1349,14 +1349,15 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
13491349
append!(suggestions, project_deps_get_completion_candidates(s, dir))
13501350
end
13511351
isdir(dir) || continue
1352-
for pname in readdir(dir)
1352+
for entry in _readdirx(dir)
1353+
pname = entry.name
13531354
if pname[1] != '.' && pname != "METADATA" &&
13541355
pname != "REQUIRE" && startswith(pname, s)
13551356
# Valid file paths are
13561357
# <Mod>.jl
13571358
# <Mod>/src/<Mod>.jl
13581359
# <Mod>.jl/src/<Mod>.jl
1359-
if isfile(joinpath(dir, pname))
1360+
if isfile(entry)
13601361
endswith(pname, ".jl") && push!(suggestions,
13611362
PackageCompletion(pname[1:prevind(pname, end-2)]))
13621363
else
@@ -1365,7 +1366,7 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
13651366
else
13661367
pname
13671368
end
1368-
if isfile(joinpath(dir, pname, "src",
1369+
if isfile(joinpath(entry, "src",
13691370
"$mod_name.jl"))
13701371
push!(suggestions, PackageCompletion(mod_name))
13711372
end

stdlib/REPL/src/docview.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import Base.Docs: doc, formatdoc, parsedoc, apropos
1111

1212
using Base: with_output_color, mapany, isdeprecated, isexported
1313

14+
using Base.Filesystem: _readdirx
15+
1416
import REPL
1517

1618
using InteractiveUtils: subtypes
@@ -379,9 +381,9 @@ function find_readme(m::Module)::Union{String, Nothing}
379381
path = dirname(mpath)
380382
top_path = pkgdir(m)
381383
while true
382-
for file in readdir(path; join=true, sort=true)
383-
isfile(file) && (basename(lowercase(file)) in ["readme.md", "readme"]) || continue
384-
return file
384+
for entry in _readdirx(path; sort=true)
385+
isfile(entry) && (lowercase(entry.name) in ["readme.md", "readme"]) || continue
386+
return entry.path
385387
end
386388
path == top_path && break # go no further than pkgdir
387389
path = dirname(path) # work up through nested modules

0 commit comments

Comments
 (0)