[Lldb-commits] [lldb] Add the ability to define custom completers to the parsed_cmd template. (PR #109062)
Med Ismail Bennani via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 19 16:50:50 PDT 2024
================
@@ -587,8 +587,150 @@ say
SBCommandReturnObject and SBStream both support this file-like behavior by
providing write() and flush() calls at the Python layer.
+The commands that are added using this Class definition are what lldb calls
+"raw" commands. The command interpreter doesn't attempt to parse the command,
+doesn't handle option values, neither generating help for them, or their
+completion. Raw commands are useful when the arguments passed to the command
+are unstructured, and having to protect them against lldb command parsing would
+be onerous. For instance, "expr" is a raw command.
+
+You can also add scripted commands that implement the "parsed command", where
+the options and their types are specified, as well as the argument and argument
+types. These commands look and act like the majority of lldb commands, and you
+can also add custom completions for the options and/or the arguments if you have
+special needs.
+
+The easiest way to do this is to derive your new command from the lldb.ParsedCommand
+class. That responds in the same way to the help & repeat command interfaces, and
+provides some convenience methods, and most importantly an LLDBOptionValueParser,
+accessed throught lldb.ParsedCommand.get_parser(). The parser is used to set
+your command definitions, and to retrieve option values in the __call__ method.
+
+To set the command definition, implement the ParsedCommand abstract method:
+
+::
+
+ def setup_command_definition(self):
+
+This is called when your command is added to lldb. In this method you add the
+options and their types, the option help strings, etc. to the command using the API:
+
+::
+
+ def add_option(self, short_option, long_option, help, default,
+ dest = None, required=False, groups = None,
+ value_type=lldb.eArgTypeNone, completion_type=None,
+ enum_values=None):
+ """
+ short_option: one character, must be unique, not required
+ long_option: no spaces, must be unique, required
+ help: a usage string for this option, will print in the command help
+ default: the initial value for this option (if it has a value)
+ dest: the name of the property that gives you access to the value for
+ this value. Defaults to the long option if not provided.
+ required: if true, this option must be provided or the command will error out
+ groups: Which "option groups" does this option belong to. This can either be
+ a simple list (e.g. [1, 3, 4, 5]) or you can specify ranges by sublists:
+ so [1, [3,5]] is the same as [1, 3, 4, 5].
+ value_type: one of the lldb.eArgType enum values. Some of the common arg
+ types also have default completers, which will be applied automatically.
+ completion_type: currently these are values form the lldb.CompletionType enum. If
+ you need custom completions, implement handle_option_argument_completion.
+ enum_values: An array of duples: ["element_name", "element_help"]. If provided,
+ only one of the enum elements is allowed. The value will be the
+ element_name for the chosen enum element as a string.
+ """
+
+Similarly, you can add argument types to the command:
+
+::
+
+ def make_argument_element(self, arg_type, repeat = "optional", groups = None):
+ """
+ arg_type: The argument type, one of the lldb.eArgType enum values.
+ repeat: Choose from the following options:
+ "plain" - one value
+ "optional" - zero or more values
+ "plus" - one or more values
+ groups: As with add_option.
+ """
+
+Then implement the body of the command by defining:
+
+::
+
+ def __call__(self, debugger, args_array, exe_ctx, result):
+ """This is the command callback. The option values are
+ provided by the 'dest' properties on the parser.
+
+ args_array: This is the list of arguments provided.
+ exe_ctx: Gives the SBExecutionContext on which the
+ command should operate.
+ result: Any results of the command should be
+ written into this SBCommandReturnObject.
+ """
+
+This differs from the "raw" command's __call__ in that the arguments are already
+parsed into the args_array, and the option values are set in the parser, and
+can be accessed using their property name. The LLDBOptionValueParser class has
+a couple of other handy methods:
+
+::
+ def was_set(self, long_option_name):
+
+returns True if the option was specified on the command line.
+
+::
+ def dest_for_option(self, long_option_name):
+ """
+ This will return the value of the dest variable you defined for opt_name.
+ Mostly useful for handle_completion where you get passed the long option.
+ """
+
+lldb will handle completing your option names, and all your enum values
+automatically. If your option or argument types have associated built-in completers,
+then lldb will also handle that completion for you. But if you have a need for
+custom completions, either in your arguments or option values, you can handle
+completion by hand as well. To handle completion of option value arguments,
+your lldb.ParsedCommand subclass should implement:
+
+::
+ def handle_option_argument_completion(self, args, arg_pos, cursor_pos):
+ """
+ args: A list of the arguments to the command
+ arg_pos: An index into the args list of the argument with the cursor
+ cursor_pos: The cursor position in the arg specified by arg_pos
+ """
+
+When this command is called, the command line has been parsed up to the word
+containing the cursor, and any option values set in that part of the command
+string are available from the option value parser. That's useful for instance
+if you have a --shared-library option that would constrain the completions for,
+say, a symbol name option or argument.
+
+The return value specifies what the completion options are. You have four
+choices:
+
+True: the completion was handled with no completions.
+
+False: the completion was not handled, forward it to the regular
+completion machinery.
+
+A dictionary with the key: "completion": there is one candidate,
+whose value is the value of the "completion" key. Optionally you can pass a
+"mode" key whose value is either "partial" or "complete". Return partial if
+the "completion" string is a prefix for all the completed value, and "complete"
+if it is the full completion. The default is "complete".
----------------
medismailben wrote:
This paragraph is a bit confusing to me, an example would be useful or may be could be re-written.
https://github.com/llvm/llvm-project/pull/109062
More information about the lldb-commits
mailing list