Canop / broot

A new way to see and navigate directory trees : https://dystroy.org/broot
MIT License
10.35k stars 226 forks source link

Multiple arguments to custom verbs. #876

Closed CabalCrow closed 1 month ago

CabalCrow commented 2 months ago

Option to define a verb that could take a list arguments rather than a single argument. Use case would be something like this:

[search pattern] MakeMulipleDirs dir1 dir2 dir3

where the verb in this case wouldn't have only 1 argument "dir1 dir2 dir3", but rather 3 arguments allowing you to create multiple directories with a single verb as you would on the command line.

Canop commented 2 months ago

What would be MakeMulipleDirs in this case ? An internal (predefined operation in broot) or an external program ?

CabalCrow commented 2 months ago

MakeMultipleDirs would be a custom verb. Something like

{
        invocation: MakeMultipleDirs [dirs]
        shortcut: mmd
        execution: "mkmuldirs {directory} [dirs]"
        leave_broot: false
}

here I've used square brakets to indicate a list of arguments compared to 1 argument as an example. In this case mkmuldirs would be a simple script - something like:

#!/bin/bash

dir="$1"
shift

for var in "$@"
do
    mkdir -p "$dir/$var"
done
SamuelSwartzberg commented 1 month ago

I'm fairly sure that you don't need to change anything in broot for this. As you might be aware, shell doesn't have a strong distinction between one and multiple args. As far as I can see, broot just passes anything you specify as an arg to the function as a single, un-split string, but there is no rule saying that you can't just split the string yourself, either just using the shell's word-splitting, or by using your own splitting, e.g. by changing the IFS variable.

In your case, that would be

#!/bin/bash

dir="$1"
shift

for var in $*
do
    mkdir -p "$dir/$var"
done

Unless I missed or misunderstood something?

CabalCrow commented 1 month ago

@SamuelSwartzberg That is exactly what I wanted! Thanks a lot!

CabalCrow commented 1 month ago

This approach does still have 1 issue though - you are unable to use " for arguments in this case, since broot is automatically managing ".

I guess a better issue would be to ask for a way to toggle this behaviour depending on the verb. @Canop Should I open a new issue for that or can we reuse this one since it is related?

SamuelSwartzberg commented 1 month ago

What do you mean by 'use "'?

Given

[[verbs]]
invocation = "printargs {args}"
external = "echo {args}"

as a simple test verb:

:printargs foo "bar" baz
> foo "bar" baz

So they are preserved. If you mean 'prevent splitting on whitespace', that's true. I'm pretty sure there's a way around this, probably using eval, but once you're going down that road, you gotta wonder if you shouldn't be doing things differently. So it might be worth trying if you need the solution soon, but else, I also would kinda support an option for verbs that's something like no_quote_args, where all it does is pass the args down to the command raw, with no shell quoting and escaping. I do think that would be the cleaner solution, relying on shell resplitting is always non-ideal. Shellcheck warns you against it, for example.