Kakoune: Add a source-recursive command

Created on 17 Jan 2020  Â·  8Comments  Â·  Source: mawww/kakoune

It could be useful to extract that command from the [kakrc].

All 8 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Delapouite picture Delapouite  Â·  4Comments

lenormf picture lenormf  Â·  4Comments

dpc picture dpc  Â·  4Comments

vbauerster picture vbauerster  Â·  3Comments

alexherbo2 picture alexherbo2  Â·  4Comments