Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tab completion functionality #40

Open
robertfronzo opened this issue Dec 4, 2018 · 3 comments
Open

Add tab completion functionality #40

robertfronzo opened this issue Dec 4, 2018 · 3 comments
Labels
enhancement New feature or request 🤕 help wanted A headache for maintainer(s)

Comments

@robertfronzo
Copy link

Including the ability to tab complete would make this tool truly perfect.

Great job either way, love this idea!

@akavel
Copy link
Owner

akavel commented Dec 4, 2018

So. First of all, this is generally an awesome idea, and I'm totally for it, as a user of the tool myself.

Now, the big question is, how to do this in a reasonable way?

Notably:

  • in bash, completion is a horrid mess of actual bash scripts registering as callback hooks; supporting full bash completion would require actually running bash and calling appropriate hooks in some way, assuming it's possible at all;
  • per don't use hardcoded /bin/bash, allow other shells/engines #2, up now supports more "engines"/shells than just bash, so the completion feature would have to somehow be compatible with not only bash, but others too;
  • up is a small tool, and I would hope for any new feature to be small and simple too, so as to not dwarf the existing codebase; though external libraries are OK here as long as the footprint of the integration glue stays small.

With the above limitations, I just don't know how it could be done as of now. If you have some ideas, the issue is open to discussion and sharing. (Though I reserve right to hide comments if I don't see them as substantial contributions.) One vague thought that occurred to me now is that maybe some "language server protocol" integration could help here; though I'm not sure. Still, if yes, I would want this to be done via linking some external Go library, so as not to add langserver protocol implementation code into up codebase itself. With all this said, I'm not currently planning to explore this direction myself, so I'm going to mark it as "help-wanted". As per my usual stance in this situation:

If someone wants to jump in and help, I'm super happy to provide mentoring, design discussion and guidance! ❤️ The process will be easiest for us both if you start talking to me here even before you start working on this. Also it's ok to fail — I won't be regretful if you don't complete the task even after we've put a lot of our time into it. I am more than sure we both will learn a lot from this anyway!

@akavel akavel added enhancement New feature or request 🤕 help wanted A headache for maintainer(s) labels Dec 4, 2018
@akavel
Copy link
Owner

akavel commented Dec 6, 2018

See also a new WIP development in this area: Oil Dev Log #8: Shell Protocol Designs (via).

@nkh
Copy link

nkh commented Jun 16, 2023

Bash only answer.

Getting completion in bash is not a mess at all, it does have limitation but the complexity is very low.

here's a real life example using a function, I decorated it to output the current word and the completion. that function is used to complete a command called 'tmuxake'

_tmuxake_completion ()
{
    completion_list="toggle full attach detach break import push pop close position check kill status status2";
    local cur;
    COMPREPLY=();
    cur="${COMP_WORDS[COMP_CWORD]}";
    COMPREPLY=($(compgen -W "${completion_list}" -- ${cur}));
    declare -p COMPREPLY;
    return 0
}

To run the tab completion "manually", we need to find which function is registered for the 'tmuxake' command

run: complete | rg tmuxake
output:
complete -o nospace -F _tmuxake_completion tmuxake

We can then emulate bash's completion by running the completion function

run: COMP_WORDS=('s' 'p') ; COMP_CWORD=1 _tmuxake_completion
output:
declare -a COMPREPLY=([0]="push" [1]="pop" [2]="position")

Non Bash opinion:

It's more than understandable that one doesn't want Bash to creep (although I guess bash is used by 90%+ of all users) in up's code.

I wouldn't mind writing extra scripts for up to support completion for specific needs, that would eliminate the problem with different shells because that becomes the responsibility of the user not the up's developer.

It may sound like a lot of work for the user but it's a balance and sometimes using up and writing "completion" scripts is well worth it. And one doesn't have to support everything. Here's my use case:

I have integrated up in my file manager so I can filter a file list with normal shell commands, grep ... . I rarely need help with the core utilities and if I do then it's worth reading the manual.

screenshot_2023-06-16_11-17-19

Some of the features I'd like to add to my file manager are very simple to implement with a pipe, say only mp3s that have a specific singer. writing a filter that let's only specific singers through is in the Unix spirit.

The problem is remembering the name of the scripts, if I have ten scripts for filtering mp3s then it's ten commands to remember, in the shell: mp3_filter_[TAB] would help tremendously, when using 'up', I need to open another shell!

It's of course more complicate than just a single word completion, what about too many completions to list simply?, what about commands that do completion by starting another program (I have one that uses fzf), and many more problems still unforeseen.

I could add the functionality above in different ways but it's up's interactivity that's it's attractive and it's so easy to create new filters!

Here's an example of a filter that only lets files over or under a specified size to go through, I can reuse it everywhere (if I remember its name), in up, in the shell, in every program that runs other programs.

#!/bin/env perl
my ($less, $size) = $ARGV[0] =~ /(-?)([0-9]+)/ ;
do { chomp ; print $less ? (-s $_ <= $size && "$_\n") : (-s $_ > $size && "$_\n") } for <STDIN>

IMHO:

  • it all get standardized with a great API, I'll have re-incarnated twice before it's true, too many people involved
  • use more of the shell or be part of the shell, one is difficult and the other replaces "supporting shells" to "being supported by shells", we're back were we started.
  • offer yet another completion specific to 'up', probably the only realistic possibility

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request 🤕 help wanted A headache for maintainer(s)
Projects
None yet
Development

No branches or pull requests

3 participants