-
-
Notifications
You must be signed in to change notification settings - Fork 50
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
tools.python.CallFunction
macro
#2471
Comments
Yeah. the slow startup time of python is an issue. But it's also how click works. Not sure about the function call though. There's also In theory the application could be bridged at a given position with the full command line to let the click parser do it's job. |
For simple stuff this should work (just needs to get rid of positional args for flags with shift): # yaml-language-server: $schema=https://carapace.sh/schemas/command.json
name: example
commands:
- name: sub
flags:
-s, --string=: some string
completion:
flag:
string: ["$carapace.bridge.Click([example, sub, --string]) | shift(99)"]
positional:
- [one, two] |
Thanks, That's very helpful! I still wish we could have a macro of some kind to pass parsed args and opts into the called program. |
Those are avalable as environment variables and positional arguments ( # yaml-language-server: $schema=https://carapace.sh/schemas/command.json
name: context
persistentflags:
-p, --persistent: persistent flag
commands:
- name: sub
flags:
-s, --string=: string flag
-b, --bool: bool flag
--custom=: custom flag
completion:
flag:
custom: ["$(env)"] context --persistent sub --string one -b arg1 arg2 --custom C_[TAB]
# C_ARG0=arg1
# C_ARG1=arg2
# C_FLAG_BOOL=true
# C_FLAG_STRING=one
# C_VALUE=C_ |
Wow, that is incredibly useful undocumented behaviour! id be happy to close this issue and submit a PR to add this to the exec macro’s documentation, if you’d like |
Sure, you can also link this in the documentation. |
Excellent, will do! btw, one thing I’m not clear on in the variables document: “… during multipart completion“ What is multipart completion? |
https://carapace-sh.github.io/carapace/carapace/defaultActions/actionMultiParts.html There's still a lot to do on the specs, which is why the documentation is so lacking. |
see also the examples at https://carapace-sh.github.io/carapace/carapace/context.html#examples |
Fantastic! Thank you for the extra resources! As a non-golang-developer, I hadn’t thought to look at the carapace library docs for extra info. I’ll be sure to link to those pages as well where appropriate |
Also, for adding to exec documentation, I plan to add a more thorough “real-world” example for how to use the exec macro with parsed arg environment variables. Note to self since I’m on mobile and can’t test code right now: # yaml-language-server: $schema=https://carapace.sh/schemas/command.json
name: context
persistentflags:
-p, --persistent: persistent flag
commands:
- name: sub
flags:
-s, --string=: string flag
-b, --bool: bool flag
--custom=: custom flag
completion:
flag:
custom: ["$(python -c 'from my_package.my_module import completion_function; completion_function())"] # my_package/my_module.py
import os
def completion_function():
# all opts and args already parsed by carapace are provided as env vars
# if user typed `context --persistent sub --string one -b arg1 arg2 --custom unfinished-word-` and hit <TAB>, then os.environ would contain
# C_ARG0=arg1
# C_ARG1=arg2
# C_FLAG_BOOL=true
# C_FLAG_STRING=one
# C_VALUE=unfinished-word-
completion_candidates = … # completion logic goes here
for candidate in completion_candidates:
print(candidate)
# or if you’re feeling fancy
print(f”{candidate}\tcandidate description”) |
as per discussion in [carapace-bin#2471](carapace-sh/carapace-bin#2471), adding details about how carapace passes context variables into executed command as environmnet variables
btw, while testing the newly-documented behaviour discussed here, i noticed that caparace doesn't include any flags "outside the current scope" in the context that it passes into executed commands. ie: in your example above, context --persistent sub --string one -b arg1 arg2 --custom C_[TAB]
# C_ARG0=arg1
# C_ARG1=arg2
# C_FLAG_BOOL=true
# C_FLAG_STRING=one
# C_VALUE=C_ i would have expected Is this a bug, or intended behaviour? |
Sounds like bug 🐛 . Workaround is to just call |
Request
I'm very happy to see that carapace has bridges for some of the more popular python cli framework completion tools (
click
,argcomplete
)Every time one of these bridges is invoked, it executes the named python cli tool (ie
watson
in the example documentation) in a zsh completion context and lets the python cli framework's own cli completion logic produce completion candidates for carapace to useThe only problem i have with this approach is the heavy performance cost. every time completion is requested for one of these python tools, it executes the python cli app in a subprocess, which imports the whole tree of python modules depended on by that cli tool (most of which won't be needed), constructs the entire argument parser tree generated by the CLI framework (ie
click
orargparse/argcomplete
) and then executes completion code in python to generate completions.This is fine for small CLI apps, but quickly becomes VERY noticable to end users for larger CLI apps with nested trees of commands (sometimes >3 second delay between user hitting
<TAB>
and carapace returning values)My idea to solve this is to pre-generate carapace Specs for each of my python cli tools, to be installed as part of the cli tool installation process. I'm writing a tool at the moment which takes a
click.Group
object, introspects it, and generates a carapace Spec yaml fileSo far, this approach is proving very promising! every feature / capability expressible in a click CLI parser can be directly mapped to a carapace Spec option.
The only place where this falls short is in custom completion functions. Many python CLI frameworks allow you to specify python functions to execute during shell completions. These functions take in some object representing the current state of the parser (ie. which flags have been parsed so far, what positional arguments have been provided so far, their values, etc), as well as a string representing the current word being completed. These functions are expected to return a list of strings representing viable completion candidates.
here's a concrete example:
Proposed solution
I would love to see a custom macro that could be invoked something like this:
which, when invoked, would do the following:
python -c 'from python_package.python_module import completion_function; print(completion_function("<carapace variables json string>"))
["$(echo -e 'a\nb\nc')"]
)Anything else?
we can already very nearly get there with:
but:
Also, as a side note, i think this feature would be of value to anyone using carapace-bin, not just python CLI app authors.
With this feature, anyone writing custom carapace spec files could leverage this to write custom completion functions
Polar
The text was updated successfully, but these errors were encountered: