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 autocomplete #289

Open
nikitavoloboev opened this issue Feb 6, 2020 · 22 comments · May be fixed by #488
Open

Add autocomplete #289

nikitavoloboev opened this issue Feb 6, 2020 · 22 comments · May be fixed by #488

Comments

@nikitavoloboev
Copy link

Would be great if you could type mage and press tab to autocomplete all the possible commands. Or start typing command mage st and on tab it would autocomplete to the nearest matching command.

Is it possible to add this to mage itself or it has to be added in some other way?

@natefinch
Copy link
Member

This has to be done by the terminal/os and is pretty fiddly, which is why I've hesitated to take on that maintenance burden.

@ghost
Copy link

ghost commented Mar 14, 2020

I'm currently using the zsh make plugin to provide autocomplete of build targets. The build targets for a particular project have become complicated though, and I'm thinking of moving to Mage to make development and maintenance easier. Not having autocomplete would be a huge burden, since the naming of the build targets are (by design) long, explicit, but organized such as:

kubernetes.render
kubernetes.apply
kubernetes.clean

docker.hadolint
docker.tag
docker.build

here's the script to do Makefile completion

https://github.com/zsh-users/zsh/blob/master/Completion/Unix/Command/_make

The only burden Mage has over Make is identifying mage files. But since that's already defined as:

A mage file is any regular go file marked with a build target of “mage” and in package main.

It only means that parsing many files in the repo root would be needed. I think parsing the first 10 lines of file would probably be enough to identify which files are mage files or not, for performance reasons.

@ghost
Copy link

ghost commented Mar 14, 2020

I also found this that might make it easier:
https://github.com/posener/complete/tree/master

@ghost
Copy link

ghost commented Mar 14, 2020

oh, target imports would also be another burden, though it's explained here:
https://magefile.org/importing/

@ghostsquad
Copy link

@natefinch could you point me at a method that would return a list of targets? I can see if I can submit a PR for this.

@ghostsquad
Copy link

ghostsquad commented Mar 16, 2020

It seems I could write something fairly simple, at least for oh-my-zsh by using mage -l, e.g. https://github.com/sawadashota/go-task-completions

The problems I see right now are that mage -l is fairly slow, so it would likely be pretty frustrating, especially when you compare it to autocomplete speed of the make script for zsh.

Additionally, it's not required that //+build mage files exist at the project root, or that you have a compiled binary.

Related situations to this I found:
#247
#283

In order to solve the performance problem, we could leverage the compiled binary if it exists, but since the name of that binary is unknown, and could likely change from project to project (even on the same developer machine), we'd need the global mage to pass thru to the compiled binary (if it exists). See #295 for that.

@ghostsquad
Copy link

for the time being though, the autocomplete script could do something like this:

if [ -x ./mage ]; then
  out=$(./mage -l)
else
  out=$(mage -l)
fi

echo "${out}" | tail -n +2 | awk '{ print $1 }'

This makes some assumptions though that cannot be easily controlled by the user.

@ghost
Copy link

ghost commented Mar 29, 2020

so looking at this more, completions, though folks have said is a "simple dsl" is hard to wrap my mind around. I'm wondering if instead, mage switched to using https://github.com/spf13/cobra which supports generating completions for zsh and bash natively.

@ghostsquad
Copy link

ghostsquad commented Mar 29, 2020

so, I figured out the script, naively assuming that the built binary is ./mg

#compdef _mg mg

function _mg {
    _complete_commands () {
        if [ -x ./mg ]; then
            compadd $(./mg -l | tail -n +2 | awk '{ print $1 }')
        fi
    }

    _arguments '1: :_complete_commands'
}

So, to make this work for both a binary and not, I think there needs to be some way of knowing what the binary name is, such as an environment variable. If that's not present, fallback to running mage -l.

@natefinch thoughts on this?

@ghostsquad
Copy link

haha, just found out that mg is a text editor.

man mg
...
mg -- emacs-like text editor

@johnboyes
Copy link

I haven't used it yet but https://github.com/iwittkau/mage-select offers bash completion, worth looking into I reckon

@jpopadak
Copy link

I haven't used it yet but https://github.com/iwittkau/mage-select offers bash completion, worth looking into I reckon

Downside is this also uses mage -l which can cause it to be slower.

But if its include in Mage and mage command is used (not compiled binary), maybe there is a way to short circuit the logic during reading of the magefiles? Or would that be too early?

@ghostsquad
Copy link

@jpopadak that's why I filed #295 such that mage can passthru to the compiled binary and not be required to read/parse in order to autocomplete.

@sluedecke
Copy link

#113 has some completion scripts which might solve this one

@sheldonhull
Copy link

I've asked a related question on #368

I was thinking of generating some vscode tasks, but also have thought about integration https://github.com/c-bata/go-prompt.

I'm thinking of:

  • a mage option that caches the target discovery to json or other format in a similar manner as the magefiles that could be read in by mage in an interactive prompt option when no arguments provided
  • Worse case, it could be done manually as a task that then calls other tasks, like mage p for prompt. I don't like this option as much other than how it might be a lot easier to do initially.

Some prompt action like the bit cli would be pretty awesome if we can figure it out.

@DavidGamba
Copy link

There is an alternative approach where you use the binary to generate completions directly. You can handle all your completions in Go and just detect if bash is calling the go binary in completion mode or in execution mode.

Once you do that you actually get built in completions that are never out of date. I have a Youtube video with my CLI parser which does just that, but the same approach can be adapted to leverage the existing CLI parser mage is using.
https://youtu.be/1ZGyIkC5shM

@josegonzalez
Copy link

Having mage generate completions directly would be great. This is how mitchellh/cli works (through an install command that can probably be genericized) which is used by all of the hashicorp tooling.

@Penthious
Copy link

Any traction on this?

@technicallyty
Copy link

technicallyty commented Mar 22, 2023

bumping, anyone ever get something going on their machine?

@mloskot
Copy link

mloskot commented Nov 22, 2023

Since I've started using Mage as an actual Bash replacement and I'm defining large number of targets-as-commands with variety of arguments, and aliases too, I'm thankful for the awesome mage -l and mage -h target commands.
However, shell completion would be awesome^2.

Would you indeed agree that the best approach seems to be that Mage could generates the completion itself?
And, that there are two options to achieve it

  1. https://github.com/posener/complete suggested by someone in Add autocomplete #289 (comment)
  2. https://github.com/DavidGamba/go-getoption suggested by @DavidGamba in Add autocomplete #289 (comment)

correct?

Any disadvantages of making the one or the other Mage's dependency?

@sheldonhull
Copy link

Mage development has stalled to my knowledge due to other priorities from the original creator. Still great to use as is but I doubt you'll see significant features until that changes.

Try Mage-select. It's a great alternative to invoking interactively.

@mloskot
Copy link

mloskot commented Nov 23, 2023

@sheldonhull

Mage development has stalled to my knowledge

I'm sad to say I have noticed. I still hope future of Mage is bright - I love it.

Try Mage-select.

Yeah, I am going to, definitely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.