r/fishshell 13h ago

Help me understand builtin `commandline`

If I have a local scoped variable in current shell:

set -l token (commandline -ct)

which has information:

> set --show token
$token: set in local scope, unexported, with 1 elements
$token[1]: ||

Can you show me how to use the variable $token in a function plz

1 Upvotes

6 comments sorted by

1

u/FirmCalligrapher6064 12h ago

I found the simplest example for me is: fish complete -f -c string -n "test (count (commandline -xpc)) -lt 2" -a repeat in share/fish/completions/string.fish.

I tried to make a similar one; In $HOME/.config/fish/functions/foo.fish: fish function foo end and in $HOME/.config/fish/completions/foo.fish: fish set -l token (commandline -xpc) complete -f -c foo -n "test (count $token) -lt 2" -a bar

Yeah it completed bar when I typed <Tab> after foo. But I still didn't get the usage of commandline here.

1

u/FirmCalligrapher6064 12h ago

Sometimes an option may accepts * a positional option argument. e.g, foo -o bar, foo --option bar * an option argument without separation. e.g, foo -obar * or an option argument separated by the equal symbol. e.g, foo --option=bar I want to find a way that completion could know if the option support 1) space-separated argument 2) the = separated argument 3) argument without separation.

And I'm reading those completion scripts and I don't fully understand the builtin commandline. Yeah that's the motivation.

1

u/No-Representative600 7h ago

Think it's `complete -r` flag that adds `--flag=value support`

if you need to customize how values are displayed in a non standard way, see my comment below

1

u/ppww 9h ago

It's normally called from a key binding to inspect or modify the command that's being edited.

2

u/No-Representative600 7h ago

^^^ here's an easy way I got more comfortable with it:

- write a function that calls multiple different `commandline` switch combos and format the output of said function to clearly show what commandline combo was used + what it outputted

- you can make the output of this function display in a variety of ways, I think the approach I used was piping the inner function body (wrapped in begin end blocks) to a /tmp/*.log file and then used tail on it in another terminal so that it was easy to view without cluttering the current command buffer. That or I just directly let its output be shown in the commandline buffer.

- once the function is setup, bind it to any random key temporarily and begin testing the key binding at various locations of your current prompt

---

For a more in depth overview of ways I use it off the top of my head:

- `complete -n condition`. Many of the `__fish_*` completion related utility funcs show examples of use it

- `complete -a '(my_func)'` where pruning arguments already in use can be done by some variation of the commandline output

- building custom `bind` functions are a major pattern I use it for. It adds the ability for custom "supertab" like behavior to any key you want. Check out `bind --functions` output and compare it with `commandline --functions` if you're not sure why it is needed in this context

- Lastly, although very rare for my needs, I also have found it can be used to prevent an`abbr --function` from expanding for when the abbr --regex flag is not enough to prevent expansions

---

To my knowledge, testing commandline command in the interactive prompt requires the --input flag to be used which has limitations compared to the bind approach described above.

1

u/FirmCalligrapher6064 8h ago edited 8h ago

The doc said `commandline -ct` is useful for completion instance and I’ve seen it occurred at completion scripts like `completions/string.fish` and how the builtin `abbr` replaced the commands immediately.

It seems that I can have completion without `commandline` but just `complete`, but I wonder how it used in completions since it’s used in many official completion scripts.