[libvirt] virsh auto completion

Going over my local git branches, I found old patch set which I was trying to get in once. Along guest IP address patches I feel like this one is desired as well and keeps returning to us from time to time. What I think this feature should look like: virsh # sta<TAB> expands to: virsh # start Now, hitting <TAB> again (okay, several times actually) gives us a list of supported options: --autodestroy --bypass-cache --console --force-boot --paused virsh # start -- Up to here, it's just current implementation. What I'd like to see is list of (ideally shut off) domains: --autodestroy --bypass-cache --console --force-boot --paused f17 f18 <...> virsh # start -- The same applies to complete a single option as well. That is not (only) command based completer, but a option based one. IIRC, that was conclusion on my first approach as well. What I've come up with so far is: diff --git a/tools/virsh.h b/tools/virsh.h index ab7161f..c7cdb3a 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -146,6 +146,8 @@ typedef struct _vshCmdOptDef vshCmdOptDef; typedef struct _vshControl vshControl; typedef struct _vshCtrlData vshCtrlData; +typedef char ** (*vshCmdOptCompleter) + (const vshCmdDef *cmd, const char *optname, void *opaque); /* * vshCmdInfo -- name/value pair for information about command * @@ -162,11 +164,13 @@ struct _vshCmdInfo { * vshCmdOptDef - command option definition */ struct _vshCmdOptDef { - const char *name; /* the name of option, or NULL for list end */ - vshCmdOptType type; /* option type */ - unsigned int flags; /* flags */ - const char *help; /* non-NULL help string; or for VSH_OT_ALIAS - * the name of a later public option */ + const char *name; /* the name of option, or NULL for list end */ + vshCmdOptType type; /* option type */ + unsigned int flags; /* flags */ + vshCmdOptCompleter completer; /* option arguments completer */ + void *opaque; /* value to pass to @completer */ + const char *help; /* non-NULL help string; or for VSH_OT_ALIAS + * the name of a later public option */ }; One of the biggest problem with this is - I'd have to change all of option definitions (add 'NULL, NULL, ' to all of them). Apart from huge impact, we still want command based completer, otherwise we would only complete: f17 f18 <...> virsh # start --domain <TAB> Who's really typing '--domain'? The idea is to make users life easier, not harder. My aim to write this e-mail is: 1) let you know somebody is working on this 2) get your thoughts and opinions. Michal

On 01/08/2013 01:02 PM, Michal Privoznik wrote:
Going over my local git branches, I found old patch set which I was trying to get in once. Along guest IP address patches I feel like this one is desired as well and keeps returning to us from time to time.
What I think this feature should look like:
virsh # sta<TAB>
expands to:
virsh # start
Now, hitting <TAB> again (okay, several times actually) gives us a list of supported options:
--autodestroy --bypass-cache --console --force-boot --paused virsh # start --
Up to here, it's just current implementation. What I'd like to see is list of (ideally shut off) domains:
--autodestroy --bypass-cache --console --force-boot --paused f17 f18 <...> virsh # start --
The same applies to complete a single option as well. That is not (only) command based completer, but a option based one. IIRC, that was conclusion on my first approach as well. What I've come up with so far is:
diff --git a/tools/virsh.h b/tools/virsh.h index ab7161f..c7cdb3a 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -146,6 +146,8 @@ typedef struct _vshCmdOptDef vshCmdOptDef; typedef struct _vshControl vshControl; typedef struct _vshCtrlData vshCtrlData;
+typedef char ** (*vshCmdOptCompleter) + (const vshCmdDef *cmd, const char *optname, void *opaque); /* * vshCmdInfo -- name/value pair for information about command * @@ -162,11 +164,13 @@ struct _vshCmdInfo { * vshCmdOptDef - command option definition */ struct _vshCmdOptDef { - const char *name; /* the name of option, or NULL for list end */ - vshCmdOptType type; /* option type */ - unsigned int flags; /* flags */ - const char *help; /* non-NULL help string; or for VSH_OT_ALIAS - * the name of a later public option */ + const char *name; /* the name of option, or NULL for list end */ + vshCmdOptType type; /* option type */ + unsigned int flags; /* flags */ + vshCmdOptCompleter completer; /* option arguments completer */ + void *opaque; /* value to pass to @completer */ + const char *help; /* non-NULL help string; or for VSH_OT_ALIAS + * the name of a later public option */ };
One of the biggest problem with this is - I'd have to change all of option definitions (add 'NULL, NULL, ' to all of them). Apart from huge impact, we still want command based completer, otherwise we would only complete:
f17 f18 <...> virsh # start --domain <TAB>
Who's really typing '--domain'? The idea is to make users life easier, not harder.
Each command has several arguments whose meaning can be positionally determined, and the meaning of a non-"--" arg in any position can be derived from the information in that command's option list. I think that the autocomplete should only list possible alternatives for the current positionally-determined argument *unless* there is already a "-" just to the left of the cursor, and then it should provide a list of --options. I say this because most of the time it is the positional argument that people want, not one of the options. (Of course, once the commandline already has all arguments that could be identified positionally, then it would make sense to provide a list of options when someone typed <TAB> while sitting just past a space). This way, if you typed: virsh # start <TAB> you would be provided only with a list of domains (btw, the list in this case should only include inactive domains :-), but if you typed virsh # start -<TAB> you would get the list of options. Once the domain name is there: virsh # start f18 <TAB> would give you a list of --options, because there are no more possible positionally-determined args left. Similarly, if you entered: virsh # update-device <TAB> you would again get just a list of domains; Once you have a domain on the line, if you hit tab: virsh # update-device f18 <TAB> you would get a list of files in the current directory, etc.
My aim to write this e-mail is: 1) let you know somebody is working on this 2) get your thoughts and opinions.
I think about this/wish for it at least once a week :-)

On Tue, Jan 08, 2013 at 07:02:00PM +0100, Michal Privoznik wrote:
Going over my local git branches, I found old patch set which I was trying to get in once. Along guest IP address patches I feel like this one is desired as well and keeps returning to us from time to time.
What I think this feature should look like:
virsh # sta<TAB>
expands to:
virsh # start
Now, hitting <TAB> again (okay, several times actually) gives us a list of supported options:
--autodestroy --bypass-cache --console --force-boot --paused virsh # start --
Up to here, it's just current implementation. What I'd like to see is list of (ideally shut off) domains:
--autodestroy --bypass-cache --console --force-boot --paused f17 f18 <...> virsh # start --
The same applies to complete a single option as well. That is not (only) command based completer, but a option based one. IIRC, that was conclusion on my first approach as well. What I've come up with so far is:
If you search the mail archives there have been at least 4 postings of virsh autocompletion, but none ever got finished. IIRC the most recent was by Serge. Probably worth starting off from one of those patches rather than writing from scratch. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 01/08/2013 11:02 AM, Michal Privoznik wrote:
Going over my local git branches, I found old patch set which I was trying to get in once. Along guest IP address patches I feel like this one is desired as well and keeps returning to us from time to time.
Indeed. Furthermore, we'd want a 'virsh complete args...' command, which can be called from bash, and gives the same completion that would be provided from within interactive virsh when hitting TAB after 'args...'.
+++ b/tools/virsh.h @@ -146,6 +146,8 @@ typedef struct _vshCmdOptDef vshCmdOptDef; typedef struct _vshControl vshControl; typedef struct _vshCtrlData vshCtrlData;
+typedef char ** (*vshCmdOptCompleter) + (const vshCmdDef *cmd, const char *optname, void *opaque);
Yes, every option would need a callback function that says what completions that option would like to present (although the options of many commands can share the same function, such as a single completer for all domains, a completer for all online domains, a completer for all storage pool names, ...). Then it is a matter of wiring up the command line parser to recognize which option is next positionally, to determine which completion callback to use.
One of the biggest problem with this is - I'd have to change all of option definitions (add 'NULL, NULL, ' to all of them). Apart from huge impact, we still want command based completer, otherwise we would only complete:
Or even switch all option definitions to use C99 initializers, with { .name = "foo", .completer = fooComplete, } - but yes, we have to touch a lot of code to add it in, so we want to get the design right before starting this.
f17 f18 <...> virsh # start --domain <TAB>
Who's really typing '--domain'? The idea is to make users life easier, not harder.
If a user types --domain, then we know what to complete; but even if they don't, we often know which option is the next positional parameter (that is, our command line parser already knows that 'start foo' is shorthand for 'start --domain foo', and can thus use the --domain completer when the user types 'start TAB').
My aim to write this e-mail is: 1) let you know somebody is working on this 2) get your thoughts and opinions.
Go for it - but as others have said, also check the archives to reuse any useful starting points already out there. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (4)
-
Daniel P. Berrange
-
Eric Blake
-
Laine Stump
-
Michal Privoznik