It could be useful to extract that command from the [kakrc].
define-command \
-params .. \
-file-completion \
-docstring "
source-recursive [<path>]..: execute commands contained in any *.kak
files under <path>, or the working directory" \
source-recursive %{
evaluate-commands %sh{
find -L "${@:-.}" -type f -name '*\.kak' |
while read file; do
printf '
try %%{
source "%s"
} catch %%{
echo -debug Autoload: coult not load "%s"
}
' "$file" "$file"
done
}
}
source-recursive command kindly posted by @chambln can be optimized like:
evaluate-commands %sh{
find -L "${@:-.}" -type f -name '*.kak' -exec printf 'source "%s"\n' {} \;
}
try/catch is skipped for the sake of optimization.
Can be optimized even more by using sed:
find -L "${@:-.}" -type f -name '*.kak' | sed 's/.*/source "&"/'
Benchmark with my installed plugins:
$ hyperfine ./find.sh ./find-sed.sh
Benchmark #1: ./find.sh
Time (mean ± σ): 67.0 ms ± 17.9 ms [User: 12.9 ms, System: 51.3 ms]
Range (min … max): 33.9 ms … 109.1 ms 44 runs
Benchmark #2: ./find-sed.sh
Time (mean ± σ): 19.3 ms ± 5.8 ms [User: 11.2 ms, System: 13.3 ms]
Range (min … max): 6.7 ms … 29.6 ms 180 runs
Summary
'./find-sed.sh' ran
3.47 ± 1.39 times faster than './find.sh'
I'd still like to have this as a built-in command though.
It'd be even faster than this (I think) and a lot more flexible than the currently hardcoded autoload path.
Edit: Wait the runtime kakrc uses find/sed for this too, it wouldn't be faster. I thought it was built in to the code.
Edit: Updated the sed code to be the same as the kakrc.
I've switched to fd command:
fd -L --type f --glob '*.kak' -X printf 'source "%s"\n' {} \; "${@:-.}"
@SeerLite Can you please include it in your benchmark?
Woah I had no idea printf accepted multiple arguments like that!
FWIW find can also do what fd -X does:
# find-printf+.sh
find -L "${@:-.}" -type f -name '*.kak' -exec printf 'source "%s"\n' {} +
I ran benchmarks with most combinations. There isn't a significant performance difference with a normal amount of plugins (25 .kak files), except from the original find/printf combo but that one isn't used anymore:
hyperfine ./fd-printf.sh ./fd-sed.sh ./find-sed.sh ./find-printf+.sh ./find-printf.sh
Benchmark #1: ./fd-printf.sh
Time (mean ± σ): 19.1 ms ± 3.5 ms [User: 4.4 ms, System: 21.1 ms]
Range (min … max): 12.2 ms … 28.1 ms 115 runs
Benchmark #2: ./fd-sed.sh
Time (mean ± σ): 18.6 ms ± 3.2 ms [User: 9.3 ms, System: 25.7 ms]
Range (min … max): 12.5 ms … 26.1 ms 100 runs
Benchmark #3: ./find-sed.sh
Time (mean ± σ): 19.4 ms ± 5.4 ms [User: 12.3 ms, System: 12.9 ms]
Range (min … max): 6.8 ms … 29.3 ms 184 runs
Benchmark #4: ./find-printf+.sh
Time (mean ± σ): 20.5 ms ± 5.7 ms [User: 7.5 ms, System: 12.6 ms]
Range (min … max): 8.1 ms … 31.3 ms 92 runs
Benchmark #5: ./find-printf.sh
Time (mean ± σ): 65.0 ms ± 10.7 ms [User: 13.7 ms, System: 49.9 ms]
Range (min … max): 41.8 ms … 83.3 ms 51 runs
Summary
'./fd-sed.sh' ran
1.03 ± 0.26 times faster than './fd-printf.sh'
1.04 ± 0.34 times faster than './find-sed.sh'
1.10 ± 0.36 times faster than './find-printf+.sh'
3.50 ± 0.83 times faster than './find-printf.sh'
So I ran a benchmark with a larger amount (250 .kak files):
$ for i in {2..10}; do cp -r plugins plugins${i}; done
hyperfine ./fd-printf.sh ./fd-sed.sh ./find-sed.sh ./find-printf+.sh ./find-printf.sh
Benchmark #1: ./fd-printf.sh
Time (mean ± σ): 25.4 ms ± 3.3 ms [User: 13.9 ms, System: 32.0 ms]
Range (min … max): 17.7 ms … 31.4 ms 81 runs
Benchmark #2: ./fd-sed.sh
Time (mean ± σ): 45.9 ms ± 4.6 ms [User: 45.9 ms, System: 81.8 ms]
Range (min … max): 37.9 ms … 56.3 ms 50 runs
Benchmark #3: ./find-sed.sh
Time (mean ± σ): 89.2 ms ± 8.9 ms [User: 29.9 ms, System: 64.9 ms]
Range (min … max): 74.1 ms … 113.9 ms 30 runs
Benchmark #4: ./find-printf+.sh
Time (mean ± σ): 93.7 ms ± 10.8 ms [User: 24.8 ms, System: 67.2 ms]
Range (min … max): 71.1 ms … 120.3 ms 30 runs
Benchmark #5: ./find-printf.sh
Time (mean ± σ): 691.5 ms ± 30.2 ms [User: 110.5 ms, System: 563.2 ms]
Range (min … max): 626.5 ms … 729.2 ms 10 runs
Summary
'./fd-printf.sh' ran
1.81 ± 0.30 times faster than './fd-sed.sh'
3.52 ± 0.58 times faster than './find-sed.sh'
3.70 ± 0.64 times faster than './find-printf+.sh'
27.26 ± 3.74 times faster than './find-printf.sh'
The version you posted is a clear winner ;)
Also I find it weird (no pun intended) that fd runs faster with a single printf than sed, but find runs faster with sed than with printf.
PS: Run fd with the -uu flag to avoid surprises
That is a fun discussion and benchmarks, however regarding the feature request itself I dont quite see why we would need to provide that command in the first place.
We source recursively only one at startup, and I cant see a lot of use for that command in user scripts. plugin managers maybe, but they will likely want to control that logic themselves (arbitrary order ? depth first ? alphabetical ?).
Whats the use case ?
Yeah it's just that at first I didn't realize the sourcing was done with the shell and thought Kakoune had some super fast way of sourcing, that could be exposed through a command. Now I know it's just find/sed.
The benchmarks were a bit off topic but I think they could have led to a faster way for how Kakoune sources autoload. It seems it already does it the fastest way possible though (while being POSIX compliant)
Edit: Personally I have no usecase for having it as a command. Maybe there's people who'd appreciate being able to source directories from their kakrc though
Whats the use case ?
Old thread but the use case was something like sourcing an entire
plugin repository on the fly -- i.e. without having to put it in your
autoload. I think.