https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/155705
>From e5a8bb8a2cf2154c805ef60c0a9e34973f0a27ea Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Wed, 27 Aug 2025 14:25:29 -0700 Subject: [PATCH] [lldb] Add more command option mnemonics Add a bunch of mnemonics to the command options now that they're highlighted in the help output. This uncovered two issues: - We had an instance where we weren't applying the ANSI formatting. - We had a place where we were now incorrectly computing the column width. Both are fixed by this PR. --- lldb/include/lldb/Utility/AnsiTerminal.h | 5 + lldb/source/Commands/Options.td | 680 +++++++++++------- lldb/source/Host/common/Editline.cpp | 15 +- lldb/source/Interpreter/Options.cpp | 23 +- .../completion/TestCompletion.py | 12 +- 5 files changed, 472 insertions(+), 263 deletions(-) diff --git a/lldb/include/lldb/Utility/AnsiTerminal.h b/lldb/include/lldb/Utility/AnsiTerminal.h index 5c99341ad888a..7db184ad67225 100644 --- a/lldb/include/lldb/Utility/AnsiTerminal.h +++ b/lldb/include/lldb/Utility/AnsiTerminal.h @@ -260,6 +260,11 @@ inline std::string TrimAndPad(llvm::StringRef str, size_t visible_length, return result; } +inline size_t ColumnWidth(llvm::StringRef str) { + std::string stripped = ansi::StripAnsiTerminalCodes(str); + return llvm::sys::locale::columnWidth(stripped); +} + } // namespace ansi } // namespace lldb_private diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index bb4769c78b491..0a29c096e7308 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1,96 +1,122 @@ include "OptionsBase.td" let Command = "target modules dump symtab" in { - def tm_sort : Option<"sort", "s">, Group<1>, - Desc<"Supply a sort order when dumping the symbol table.">, - EnumArg<"SortOrder">; - def tm_smn : Option<"show-mangled-names", "m">, Group<1>, - Desc<"Do not demangle symbol names before showing them.">; + def tm_sort : Option<"sort", "s">, + Group<1>, + Desc<"${S}upply a sort order when dumping the symbol table.">, + EnumArg<"SortOrder">; + def tm_smn : Option<"show-mangled-names", "m">, + Group<1>, + Desc<"Do not de${m}angle symbol names before showing them.">; } let Command = "target modules dump separate debug info" in { - def tm_json : Option<"json", "j">, Group<1>, - Desc<"Output the details in JSON format.">; - def tm_errors_only : Option<"errors-only", "e">, Group<1>, - Desc<"Filter to show only debug info files with errors.">; + def tm_json : Option<"json", "j">, + Group<1>, + Desc<"Output the details in ${J}SON format.">; + def tm_errors_only + : Option<"errors-only", "e">, + Group<1>, + Desc<"Filter to show only debug info files with ${e}rrors.">; def tm_force_load_all_debug_info : Option<"force-load-all-debug-info", "f">, Group<1>, - Desc<"Load all debug info files.">; + Desc<"Load all debug in${f}o files.">; } let Command = "help" in { def help_hide_aliases : Option<"hide-aliases", "a">, - Desc<"Hide aliases in the command list.">; + Desc<"Hide ${a}liases in the command list.">; def help_hide_user : Option<"hide-user-commands", "u">, - Desc<"Hide user-defined commands from the list.">; + Desc<"Hide ${u}ser-defined commands from the list.">; def help_show_hidden : Option<"show-hidden-commands", "h">, Desc<"Include commands prefixed with an underscore.">; } let Command = "settings set" in { - def setset_global : Option<"global", "g">, - Desc<"Apply the new value to the global default value.">; - def setset_force : Option<"force", "f">, - Desc<"Force an empty value to be accepted as the default.">; + def setset_global + : Option<"global", "g">, + Desc<"Apply the new value to the ${g}lobal default value.">; + def setset_force + : Option<"force", "f">, + Desc<"${F}orce an empty value to be accepted as the default.">; def setset_exists : Option<"exists", "e">, - Desc<"Set the setting if it exists, but do not cause the command to raise " - "an error if it does not exist.">; + Desc<"Set the setting if it ${e}xists, but do not cause " + "the command to raise " + "an error if it does not exist.">; } let Command = "settings write" in { - def setwrite_file : Option<"file", "f">, Required, Arg<"Filename">, - Completion<"DiskFile">, - Desc<"The file into which to write the settings.">; + def setwrite_file : Option<"file", "f">, + Required, + Arg<"Filename">, + Completion<"DiskFile">, + Desc<"The ${f}ile into which to write the settings.">; def setwrite_append : Option<"append", "a">, - Desc<"Append to saved settings file if it exists.">; + Desc<"${A}ppend to saved settings file if it exists.">; } let Command = "settings read" in { - def setread_file : Option<"file", "f">, Required, Arg<"Filename">, - Completion<"DiskFile">, - Desc<"The file from which to read the settings.">; + def setread_file : Option<"file", "f">, + Required, + Arg<"Filename">, + Completion<"DiskFile">, + Desc<"The ${f}ile from which to read the settings.">; } let Command = "settings clear" in { - def setclear_all : Option<"all", "a">, - Desc<"Clear all settings.">; + def setclear_all : Option<"all", "a">, Desc<"Clear ${a}ll settings.">; } let Command = "settings show" in { def setshow_defaults : Option<"defaults", "d">, - Desc<"Include default values if defined.">; + Desc<"Include ${d}efault values if defined.">; } let Command = "breakpoint list" in { // FIXME: We need to add an "internal" command, and then add this sort of // thing to it. But I need to see it for now, and don't want to wait. def blist_internal : Option<"internal", "i">, - Desc<"Show debugger internal breakpoints">; - def blist_brief : Option<"brief", "b">, Group<1>, - Desc<"Give a brief description of the breakpoint (no location info).">; - def blist_full : Option<"full", "f">, Group<2>, - Desc<"Give a full description of the breakpoint and its locations.">; + Desc<"Show debugger ${i}nternal breakpoints">; + def blist_brief : Option<"brief", "b">, + Group<1>, + Desc<"Give a ${b}rief description of the breakpoint (no " + "location info).">; + def blist_full + : Option<"full", "f">, + Group<2>, + Desc<"Give a ${f}ull description of the breakpoint and its locations.">; def blist_verbose : Option<"verbose", "v">, Group<3>, Desc<"Explain everything we know about the breakpoint (for debugging " "debugger bugs).">; - def blist_dummy_bp : Option<"dummy-breakpoints", "D">, - Desc<"List Dummy breakpoints - i.e. breakpoints set before a file is " - "provided, which prime new targets.">; + def blist_dummy_bp + : Option<"dummy-breakpoints", "D">, + Desc< + "List ${D}ummy breakpoints - i.e. breakpoints set before a file is " + "provided, which prime new targets.">; } let Command = "breakpoint modify" in { def breakpoint_modify_ignore_count : Option<"ignore-count", "i">, Group<1>, Arg<"Count">, Desc<"Set the number of times this breakpoint is skipped before stopping.">; - def breakpoint_modify_one_shot : Option<"one-shot", "o">, Group<1>, - Arg<"Boolean">, - Desc<"The breakpoint is deleted the first time it causes a stop.">; - def breakpoint_modify_thread_index : Option<"thread-index", "x">, Group<1>, - Arg<"ThreadIndex">, Desc<"The breakpoint stops only for the thread whose " - "index matches this argument.">; - def breakpoint_modify_thread_id : Option<"thread-id", "t">, Group<1>, - Arg<"ThreadID">, Desc<"The breakpoint stops only for the thread whose TID " - "matches this argument. The token 'current' resolves to the current thread's ID.">; + def breakpoint_modify_one_shot + : Option<"one-shot", "o">, + Group<1>, + Arg<"Boolean">, + Desc<"The breakpoint is deleted the first time it causes a stop.">; + def breakpoint_modify_thread_index + : Option<"thread-index", "x">, + Group<1>, + Arg<"ThreadIndex">, + Desc<"The breakpoint stops only for the thread whose " + "inde${x} matches this argument.">; + def breakpoint_modify_thread_id + : Option<"thread-id", "t">, + Group<1>, + Arg<"ThreadID">, + Desc<"The breakpoint stops only for the ${t}hread whose TID " + "matches this argument. The token 'current' resolves to the " + "current thread's ID.">; def breakpoint_modify_thread_name : Option<"thread-name", "T">, Group<1>, Arg<"ThreadName">, Desc<"The breakpoint stops only for the thread whose " "thread name matches this argument.">; @@ -109,121 +135,215 @@ let Command = "breakpoint modify" in { def breakpoint_modify_auto_continue : Option<"auto-continue", "G">, Group<1>, Arg<"Boolean">, Desc<"The breakpoint will auto-continue after running its commands.">; - def breakpoint_modify_enable : Option<"enable", "e">, Group<2>, - Desc<"Enable the breakpoint.">; - def breakpoint_modify_disable : Option<"disable", "d">, Group<3>, - Desc<"Disable the breakpoint.">; - def breakpoint_modify_command : Option<"command", "C">, Group<4>, - Arg<"Command">, - Desc<"A command to run when the breakpoint is hit, can be provided more " - "than once, the commands will be run in left-to-right order.">; + def breakpoint_modify_enable : Option<"enable", "e">, + Group<2>, + Desc<"${E}nable the breakpoint.">; + def breakpoint_modify_disable : Option<"disable", "d">, + Group<3>, + Desc<"${D}isable the breakpoint.">; + def breakpoint_modify_command + : Option<"command", "C">, + Group<4>, + Arg<"Command">, + Desc<"A ${c}ommand to run when the breakpoint is hit, can be provided " + "more " + "than once, the commands will be run in left-to-right order.">; } let Command = "breakpoint dummy" in { - def breakpoint_dummy_options_dummy_breakpoints : - Option<"dummy-breakpoints", "D">, Group<1>, - Desc<"Act on Dummy breakpoints - i.e. breakpoints set before a file is " - "provided, which prime new targets.">; + def breakpoint_dummy_options_dummy_breakpoints + : Option<"dummy-breakpoints", "D">, + Group<1>, + Desc<"Act on ${D}ummy breakpoints - i.e. breakpoints set before a file " + "is " + "provided, which prime new targets.">; } let Command = "breakpoint set" in { - def breakpoint_set_shlib : Option<"shlib", "s">, Arg<"ShlibName">, - Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11,12]>, // *not* in group 10 - Desc<"Set the breakpoint only in this shared library. Can repeat this " - "option multiple times to specify multiple shared libraries.">; - def breakpoint_set_hardware : Option<"hardware", "H">, - Desc<"Require the breakpoint to use hardware breakpoints.">; - def breakpoint_set_file : Option<"file", "f">, Arg<"Filename">, - Completion<"SourceFile">, Groups<[1,3,4,5,6,7,8,9,11]>, - Desc<"Specifies the source file in which to set this breakpoint. Note, by " - "default lldb only looks for files that are #included if they use the " - "standard include file extensions. To set breakpoints on .c/.cpp/.m/.mm " - "files that are #included, set target.inline-breakpoint-strategy to " - "\"always\".">; - def breakpoint_set_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, - Required, - Desc<"Specifies the line number on which to set this breakpoint.">; - def breakpoint_set_column : Option<"column", "u">, Group<1>, Arg<"ColumnNum">, - Desc<"Specifies the column number on which to set this breakpoint.">; - def breakpoint_set_address : Option<"address", "a">, Group<2>, - Arg<"AddressOrExpression">, Required, - Desc<"Set the breakpoint at the specified address. If the address maps " - "uniquely to a particular binary, then the address will be converted to " - "a \"file\"address, so that the breakpoint will track that binary+offset " - "no matter where the binary eventually loads. Alternately, if you also " - "specify the module - with the -s option - then the address will be " - "treated as a file address in that module, and resolved accordingly. " - "Again, this will allow lldb to track that offset on subsequent reloads. " - "The module need not have been loaded at the time you specify this " - "breakpoint, and will get resolved when the module is loaded.">; - def breakpoint_set_name : Option<"name", "n">, Group<3>, Arg<"FunctionName">, - Completion<"Symbol">, Required, - Desc<"Set the breakpoint by function name. Can be repeated multiple times " - "to make one breakpoint for multiple names.">; + def breakpoint_set_shlib + : Option<"shlib", "s">, + Arg<"ShlibName">, + Completion<"Module">, + Groups<[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12]>, // *not* in group 10 + Desc<"${S}et the breakpoint only in this shared library. Can repeat " + "this " + "option multiple times to specify multiple shared libraries.">; + def breakpoint_set_hardware + : Option<"hardware", "H">, + Desc<"Require the breakpoint to use ${h}ardware breakpoints.">; + def breakpoint_set_file : Option<"file", "f">, + Arg<"Filename">, + Completion<"SourceFile">, + Groups<[1, 3, 4, 5, 6, 7, 8, 9, 11]>, + Desc<"Specifies the source ${f}ile in which to set " + "this breakpoint. Note, by " + "default lldb only looks for files that are " + "#included if they use the " + "standard include file extensions. To set " + "breakpoints on .c/.cpp/.m/.mm " + "files that are #included, set " + "target.inline-breakpoint-strategy to " + "\"always\".">; + def breakpoint_set_line + : Option<"line", "l">, + Group<1>, + Arg<"LineNum">, + Required, + Desc<"Specifies the ${l}ine number on which to set this breakpoint.">; + def breakpoint_set_column + : Option<"column", "u">, + Group<1>, + Arg<"ColumnNum">, + Desc<"Specifies the col${u}mn number on which to set this breakpoint.">; + def breakpoint_set_address + : Option<"address", "a">, + Group<2>, + Arg<"AddressOrExpression">, + Required, + Desc< + "Set the breakpoint at the specified ${a}ddress. If the address " + "maps " + "uniquely to a particular binary, then the address will be " + "converted to " + "a \"file\"address, so that the breakpoint will track that " + "binary+offset " + "no matter where the binary eventually loads. Alternately, if you " + "also " + "specify the module - with the -s option - then the address will " + "be " + "treated as a file address in that module, and resolved " + "accordingly. " + "Again, this will allow lldb to track that offset on subsequent " + "reloads. " + "The module need not have been loaded at the time you specify this " + "breakpoint, and will get resolved when the module is loaded.">; + def breakpoint_set_name : Option<"name", "n">, + Group<3>, + Arg<"FunctionName">, + Completion<"Symbol">, + Required, + Desc<"Set the breakpoint by function ${n}ame. Can " + "be repeated multiple times " + "to make one breakpoint for multiple names.">; def breakpoint_set_source_regexp_function : Option<"source-regexp-function", "X">, Group<9>, Arg<"FunctionName">, Completion<"Symbol">, Desc<"When used with '-p' limits the source regex to source contained in " "the named functions. Can be repeated multiple times.">; - def breakpoint_set_fullname : Option<"fullname", "F">, Group<4>, - Arg<"FullName">, Required, Completion<"Symbol">, - Desc<"Set the breakpoint by fully qualified function names. For C++ this " - "means namespaces and all arguments, and for Objective-C this means a full " - "function prototype with class and selector. Can be repeated multiple times" - " to make one breakpoint for multiple names.">; - def breakpoint_set_selector : Option<"selector", "S">, Group<5>, - Arg<"Selector">, Required, - Desc<"Set the breakpoint by Objective-C selector name. Can be repeated " - "multiple times to make one breakpoint for multiple Selectors.">; - def breakpoint_set_method : Option<"method", "M">, Group<6>, Arg<"Method">, - Required, Desc<"Set the breakpoint by C++ method names. Can be repeated " - "multiple times to make one breakpoint for multiple methods.">; - def breakpoint_set_func_regex : Option<"func-regex", "r">, Group<7>, - Arg<"RegularExpression">, Required, Desc<"Set the breakpoint by function " - "name, evaluating a regular-expression to find the function name(s).">; - def breakpoint_set_basename : Option<"basename", "b">, Group<8>, - Arg<"FunctionName">, Required, Completion<"Symbol">, - Desc<"Set the breakpoint by function basename (C++ namespaces and arguments" - " will be ignored). Can be repeated multiple times to make one breakpoint " - "for multiple symbols.">; - def breakpoint_set_source_pattern_regexp : - Option<"source-pattern-regexp", "p">, Group<9>, Arg<"RegularExpression">, - Required, Desc<"Set the breakpoint by specifying a regular expression which" - " is matched against the source text in a source file or files specified " - "with the -f can be specified more than once. If no source files " - "are specified, uses the current \"default source file\". If you want to " - "match against all source files, pass the \"--all-files\" option.">; - def breakpoint_set_all_files : Option<"all-files", "A">, Group<9>, - Desc<"All files are searched for source pattern matches.">; - def breakpoint_set_language_exception : Option<"language-exception", "E">, - Group<10>, Arg<"Language">, Required, - Desc<"Set the breakpoint on exceptions thrown by the specified language " - "(without options, on throw but not catch.)">; - def breakpoint_set_on_throw : Option<"on-throw", "w">, Group<10>, - Arg<"Boolean">, Desc<"Set the breakpoint on exception throW.">; - def breakpoint_set_on_catch : Option<"on-catch", "h">, Group<10>, - Arg<"Boolean">, Desc<"Set the breakpoint on exception catcH.">; - def breakpoint_set_language : Option<"language", "L">, GroupRange<3, 8>, - Arg<"Language">, - Desc<"Specifies the Language to use when interpreting the breakpoint's " - "expression (note: currently only implemented for setting breakpoints on " - "identifiers). If not set the target.language setting is used.">; - def breakpoint_set_skip_prologue : Option<"skip-prologue", "K">, - Arg<"Boolean">, Groups<[1,3,4,5,6,7,8,12]>, - Desc<"Skip the prologue if the breakpoint is at the beginning of a " - "function. If not set the target.skip-prologue setting is used.">; - def breakpoint_set_breakpoint_name : Option<"breakpoint-name", "N">, - Arg<"BreakpointName">, - Desc<"Adds this to the list of names for this breakpoint.">; - def breakpoint_set_address_slide : Option<"address-slide", "R">, - Arg<"Address">, Groups<[1,3,4,5,6,7,8,12]>, - Desc<"Add the specified offset to whatever address(es) the breakpoint " - "resolves to. At present this applies the offset directly as given, and " - "doesn't try to align it to instruction boundaries.">; - def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">, - Groups<[1,9,12]>, Arg<"Boolean">, - Desc<"Move breakpoints to nearest code. If not set the " - "target.move-to-nearest-code setting is used.">; + def breakpoint_set_fullname + : Option<"fullname", "F">, + Group<4>, + Arg<"FullName">, + Required, + Completion<"Symbol">, + Desc<"Set the breakpoint by ${F}ully qualified function names. For C++ " + "this " + "means namespaces and all arguments, and for Objective-C this " + "means a full " + "function prototype with class and selector. Can be repeated " + "multiple times" + " to make one breakpoint for multiple names.">; + def breakpoint_set_selector + : Option<"selector", "S">, + Group<5>, + Arg<"Selector">, + Required, + Desc<"Set the breakpoint by Objective-C ${s}elector name. Can be " + "repeated " + "multiple times to make one breakpoint for multiple Selectors.">; + def breakpoint_set_method + : Option<"method", "M">, + Group<6>, + Arg<"Method">, + Required, + Desc<"Set the breakpoint by C++ ${m}ethod names. Can be repeated " + "multiple times to make one breakpoint for multiple methods.">; + def breakpoint_set_func_regex + : Option<"func-regex", "r">, + Group<7>, + Arg<"RegularExpression">, + Required, + Desc<"Set the breakpoint by function " + "name, evaluating a ${r}egular-expression to find the function " + "name(s).">; + def breakpoint_set_basename : Option<"basename", "b">, + Group<8>, + Arg<"FunctionName">, + Required, + Completion<"Symbol">, + Desc<"Set the breakpoint by function " + "${b}asename (C++ namespaces and arguments" + " will be ignored). Can be repeated " + "multiple times to make one breakpoint " + "for multiple symbols.">; + def breakpoint_set_source_pattern_regexp + : Option<"source-pattern-regexp", "p">, + Group<9>, + Arg<"RegularExpression">, + Required, + Desc<"Set the breakpoint by specifying a regular expression which" + " is matched against the source text in a source file or files " + "specified " + "with the -f can be specified more than once. If no source files " + "are specified, uses the current \"default source file\". If you " + "want to " + "match against all source files, ${p}ass the \"--all-files\" " + "option.">; + def breakpoint_set_all_files + : Option<"all-files", "A">, + Group<9>, + Desc<"${A}ll files are searched for source pattern matches.">; + def breakpoint_set_language_exception + : Option<"language-exception", "E">, + Group<10>, + Arg<"Language">, + Required, + Desc<"Set the breakpoint on ${e}xceptions thrown by the specified " + "language " + "(without options, on throw but not catch.)">; + def breakpoint_set_on_throw + : Option<"on-throw", "w">, + Group<10>, + Arg<"Boolean">, + Desc<"Set the breakpoint on exception thro${w}.">; + def breakpoint_set_on_catch + : Option<"on-catch", "h">, + Group<10>, + Arg<"Boolean">, + Desc<"Set the breakpoint on exception catc${h}.">; + def breakpoint_set_language + : Option<"language", "L">, + GroupRange<3, 8>, + Arg<"Language">, + Desc<"Specifies the ${L}anguage to use when interpreting the " + "breakpoint's " + "expression (note: currently only implemented for setting " + "breakpoints on " + "identifiers). If not set the target.language setting is used.">; + def breakpoint_set_skip_prologue + : Option<"skip-prologue", "K">, + Arg<"Boolean">, + Groups<[1, 3, 4, 5, 6, 7, 8, 12]>, + Desc<"S${k}ip the prologue if the breakpoint is at the beginning of a " + "function. If not set the target.skip-prologue setting is used.">; + def breakpoint_set_breakpoint_name + : Option<"breakpoint-name", "N">, + Arg<"BreakpointName">, + Desc<"Adds this to the list of ${n}ames for this breakpoint.">; + def breakpoint_set_address_slide + : Option<"address-slide", "R">, + Arg<"Address">, + Groups<[1, 3, 4, 5, 6, 7, 8, 12]>, + Desc<"Add the specified offset to whatever address(es) the breakpoint " + "${r}esolves to. At present this applies the offset directly as " + "given, and " + "doesn't try to align it to instruction boundaries.">; + def breakpoint_set_move_to_nearest_code + : Option<"move-to-nearest-code", "m">, + Groups<[1, 9, 12]>, + Arg<"Boolean">, + Desc<"${M}ove breakpoints to nearest code. If not set the " + "target.move-to-nearest-code setting is used.">; def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">, Required, Completion<"SourceFile">, Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">; @@ -236,128 +356,206 @@ let Command = "breakpoint set" in { } let Command = "breakpoint clear" in { - def breakpoint_clear_file : Option<"file", "f">, Group<1>, Arg<"Filename">, - Completion<"SourceFile">, - Desc<"Specify the breakpoint by source location in this particular file.">; - def breakpoint_clear_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, - Required, - Desc<"Specify the breakpoint by source location at this particular line.">; + def breakpoint_clear_file : Option<"file", "f">, + Group<1>, + Arg<"Filename">, + Completion<"SourceFile">, + Desc<"Specify the breakpoint by source location " + "in this particular ${f}ile.">; + def breakpoint_clear_line : Option<"line", "l">, + Group<1>, + Arg<"LineNum">, + Required, + Desc<"Specify the breakpoint by source " + "${l}ocation at this particular line.">; } let Command = "breakpoint delete" in { - def breakpoint_delete_force : Option<"force", "f">, Group<1>, - Desc<"Delete all breakpoints without querying for confirmation.">; - def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">, - Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a " - "file is provided, which prime new targets.">; - def breakpoint_delete_disabled : Option<"disabled", "d">, Group<1>, - Desc<"Delete all breakpoints which are currently disabled. When using the disabled option " - "any breakpoints listed on the command line are EXCLUDED from deletion.">; + def breakpoint_delete_force + : Option<"force", "f">, + Group<1>, + Desc<"Delete all breakpoints without querying ${f}or confirmation.">; + def breakpoint_delete_dummy_breakpoints + : Option<"dummy-breakpoints", "D">, + Group<1>, + Desc<"${D}elete Dummy breakpoints - i.e. breakpoints set before a " + "file is provided, which prime new targets.">; + def breakpoint_delete_disabled + : Option<"disabled", "d">, + Group<1>, + Desc<"${D}elete all breakpoints which are currently disabled. When " + "using the disabled option " + "any breakpoints listed on the command line are EXCLUDED from " + "deletion.">; } let Command = "breakpoint name" in { - def breakpoint_name_name : Option<"name", "N">, Group<1>, - Arg<"BreakpointName">, Desc<"Specifies a breakpoint name to use.">; - def breakpoint_name_breakpoint_id : Option<"breakpoint-id", "B">, Group<2>, - Arg<"BreakpointID">, Desc<"Specify a breakpoint ID to use.">; - def breakpoint_name_dummy_breakpoints : Option<"dummy-breakpoints", "D">, - Group<3>, Desc<"Operate on Dummy breakpoints - i.e. breakpoints set before " - "a file is provided, which prime new targets.">; - def breakpoint_name_help_string : Option<"help-string", "H">, Group<4>, - Arg<"None">, Desc<"A help string describing the purpose of this name.">; + def breakpoint_name_name : Option<"name", "N">, + Group<1>, + Arg<"BreakpointName">, + Desc<"Specifies a breakpoint ${n}ame to use.">; + def breakpoint_name_breakpoint_id + : Option<"breakpoint-id", "B">, + Group<2>, + Arg<"BreakpointID">, + Desc<"Specify a ${b}reakpoint ID to use.">; + def breakpoint_name_dummy_breakpoints + : Option<"dummy-breakpoints", "D">, + Group<3>, + Desc<"Operate on ${D}ummy breakpoints - i.e. breakpoints set before " + "a file is provided, which prime new targets.">; + def breakpoint_name_help_string + : Option<"help-string", "H">, + Group<4>, + Arg<"None">, + Desc<"A ${h}elp string describing the purpose of this name.">; } let Command = "breakpoint access" in { - def breakpoint_access_allow_list : Option<"allow-list", "L">, Group<1>, - Arg<"Boolean">, Desc<"Determines whether the breakpoint will show up in " - "break list if not referred to explicitly.">; - def breakpoint_access_allow_disable : Option<"allow-disable", "A">, Group<2>, - Arg<"Boolean">, Desc<"Determines whether the breakpoint can be disabled by " - "name or when all breakpoints are disabled.">; - def breakpoint_access_allow_delete : Option<"allow-delete", "D">, Group<3>, - Arg<"Boolean">, Desc<"Determines whether the breakpoint can be deleted by " - "name or when all breakpoints are deleted.">; + def breakpoint_access_allow_list + : Option<"allow-list", "L">, + Group<1>, + Arg<"Boolean">, + Desc<"Determines whether the breakpoint will show up in " + "break ${l}ist if not referred to explicitly.">; + def breakpoint_access_allow_disable + : Option<"allow-disable", "A">, + Group<2>, + Arg<"Boolean">, + Desc<"Determines whether the breakpoint can be disabled by " + "name or when ${a}ll breakpoints are disabled.">; + def breakpoint_access_allow_delete + : Option<"allow-delete", "D">, + Group<3>, + Arg<"Boolean">, + Desc<"${D}etermines whether the breakpoint can be deleted by " + "name or when all breakpoints are deleted.">; } let Command = "breakpoint read" in { - def breakpoint_read_file : Option<"file", "f">, Arg<"Filename">, Required, - Completion<"DiskFile">, - Desc<"The file from which to read the breakpoints.">; - def breakpoint_read_breakpoint_name : Option<"breakpoint-name", "N">, - Arg<"BreakpointName">, Desc<"Only read in breakpoints with this name.">; + def breakpoint_read_file + : Option<"file", "f">, + Arg<"Filename">, + Required, + Completion<"DiskFile">, + Desc<"The ${f}ile from which to read the breakpoints.">; + def breakpoint_read_breakpoint_name + : Option<"breakpoint-name", "N">, + Arg<"BreakpointName">, + Desc<"Only read in breakpoints with this ${n}ame.">; } let Command = "breakpoint write" in { - def breakpoint_write_file : Option<"file", "f">, Arg<"Filename">, Required, - Completion<"DiskFile">, - Desc<"The file into which to write the breakpoints.">; - def breakpoint_write_append : Option<"append", "a">, - Desc<"Append to saved breakpoints file if it exists.">; + def breakpoint_write_file + : Option<"file", "f">, + Arg<"Filename">, + Required, + Completion<"DiskFile">, + Desc<"The ${f}ile into which to write the breakpoints.">; + def breakpoint_write_append + : Option<"append", "a">, + Desc<"${A}ppend to saved breakpoints file if it exists.">; } let Command = "breakpoint command add" in { - def breakpoint_add_one_liner : Option<"one-liner", "o">, Group<1>, - Arg<"OneLiner">, Desc<"Specify a one-line breakpoint command inline. Be " - "sure to surround it with quotes.">; - def breakpoint_add_stop_on_error : Option<"stop-on-error", "e">, - Arg<"Boolean">, Desc<"Specify whether breakpoint command execution should " - "terminate on error.">; - def breakpoint_add_script_type : Option<"script-type", "s">, - EnumArg<"ScriptLang">, - Desc<"Specify the language for the commands - if none is specified, the " - "lldb command interpreter will be used.">; - def breakpoint_add_dummy_breakpoints : Option<"dummy-breakpoints", "D">, - Desc<"Sets Dummy breakpoints - i.e. breakpoints set before a file is " - "provided, which prime new targets.">; + def breakpoint_add_one_liner + : Option<"one-liner", "o">, + Group<1>, + Arg<"OneLiner">, + Desc<"Specify a ${o}ne-line breakpoint command inline. Be " + "sure to surround it with quotes.">; + def breakpoint_add_stop_on_error + : Option<"stop-on-error", "e">, + Arg<"Boolean">, + Desc<"Specify whether breakpoint command ${e}xecution should " + "terminate on error.">; + def breakpoint_add_script_type + : Option<"script-type", "s">, + EnumArg<"ScriptLang">, + Desc<"${S}pecify the language for the commands - if none is specified, " + "the " + "lldb command interpreter will be used.">; + def breakpoint_add_dummy_breakpoints + : Option<"dummy-breakpoints", "D">, + Desc< + "Sets ${D}ummy breakpoints - i.e. breakpoints set before a file is " + "provided, which prime new targets.">; } let Command = "breakpoint command delete" in { - def breakpoint_command_delete_dummy_breakpoints : - Option<"dummy-breakpoints", "D">, Group<1>, - Desc<"Delete commands from Dummy breakpoints - i.e. breakpoints set before " - "a file is provided, which prime new targets.">; + def breakpoint_command_delete_dummy_breakpoints + : Option<"dummy-breakpoints", "D">, + Group<1>, + Desc<"${D}elete commands from Dummy breakpoints - i.e. breakpoints set " + "before " + "a file is provided, which prime new targets.">; } let Command = "disassemble" in { - def disassemble_options_bytes : Option<"bytes", "b">, - Desc<"Show opcode bytes when disassembling.">; - def disassemble_options_kind : Option<"kind", "k">, - Desc<"Show instruction control flow kind. Refer to the enum " - "`InstructionControlFlowKind` for a list of control flow kind. " - "As an important note, far jumps, far calls and far returns often indicate " - "calls to and from kernel.">; - def disassemble_options_context : Option<"context", "C">, Arg<"NumLines">, - Desc<"Number of context lines of source to show.">; - def disassemble_options_mixed : Option<"mixed", "m">, - Desc<"Enable mixed source and assembly display.">; - def disassemble_options_raw : Option<"raw", "r">, - Desc<"Print raw disassembly with no symbol information.">; - def disassemble_options_plugin : Option<"plugin", "P">, Arg<"Plugin">, - Desc<"Name of the disassembler plugin you want to use.">; - def disassemble_options_flavor : Option<"flavor", "F">, - Arg<"DisassemblyFlavor">, Desc<"Name of the disassembly flavor you want to " - "use. Currently the only valid options are default, and for Intel " - "architectures, att and intel.">; + def disassemble_options_bytes + : Option<"bytes", "b">, + Desc<"Show opcode ${b}ytes when disassembling.">; + def disassemble_options_kind + : Option<"kind", "k">, + Desc<"Show instruction control flow ${k}ind. Refer to the enum " + "`InstructionControlFlowKind` for a list of control flow kind. " + "As an important note, far jumps, far calls and far returns often " + "indicate " + "calls to and from kernel.">; + def disassemble_options_context + : Option<"context", "C">, + Arg<"NumLines">, + Desc<"Number of ${c}ontext lines of source to show.">; + def disassemble_options_mixed + : Option<"mixed", "m">, + Desc<"Enable ${m}ixed source and assembly display.">; + def disassemble_options_raw + : Option<"raw", "r">, + Desc<"Print ${r}aw disassembly with no symbol information.">; + def disassemble_options_plugin + : Option<"plugin", "P">, + Arg<"Plugin">, + Desc<"Name of the disassembler ${p}lugin you want to use.">; + def disassemble_options_flavor + : Option<"flavor", "F">, + Arg<"DisassemblyFlavor">, + Desc<"Name of the disassembly ${f}lavor you want to " + "use. Currently the only valid options are default, and for Intel " + "architectures, att and intel.">; def disassemble_options_cpu : Option<"cpu", "X">, Arg<"CPUName">, Desc<"Override the CPU for disassembling.">; def disassemble_options_features : Option<"features", "Y">, Arg<"CPUFeatures">, Desc<"Specify additional CPU features for disassembling.">; - def disassemble_options_arch : Option<"arch", "A">, Arg<"Architecture">, - Desc<"Specify the architecture to use from cross disassembly.">; - def disassemble_options_start_address : Option<"start-address", "s">, - Groups<[1,2]>, Arg<"AddressOrExpression">, Required, - Desc<"Address at which to start disassembling.">; - def disassemble_options_end_address : Option<"end-address", "e">, Group<1>, - Arg<"AddressOrExpression">, Desc<"Address at which to end disassembling.">; + def disassemble_options_arch + : Option<"arch", "A">, + Arg<"Architecture">, + Desc<"Specify the ${a}rchitecture to use from cross disassembly.">; + def disassemble_options_start_address + : Option<"start-address", "s">, + Groups<[1, 2]>, + Arg<"AddressOrExpression">, + Required, + Desc<"Address at which to ${s}tart disassembling.">; + def disassemble_options_end_address + : Option<"end-address", "e">, + Group<1>, + Arg<"AddressOrExpression">, + Desc<"Address at which to ${e}nd disassembling.">; def disassemble_options_count : Option<"count", "c">, Groups<[2,3,4,5,7]>, Arg<"NumLines">, Desc<"Number of instructions to display.">; - def disassemble_options_name : Option<"name", "n">, Group<3>, - Arg<"FunctionName">, Completion<"Symbol">, - Desc<"Disassemble entire contents of the given function name.">; - def disassemble_options_frame : Option<"frame", "f">, Group<4>, - Desc<"Disassemble from the start of the current frame's function.">; - def disassemble_options_pc : Option<"pc", "p">, Group<5>, - Desc<"Disassemble around the current pc.">; + def disassemble_options_name + : Option<"name", "n">, + Group<3>, + Arg<"FunctionName">, + Completion<"Symbol">, + Desc<"Disassemble entire contents of the given function ${n}ame.">; + def disassemble_options_frame + : Option<"frame", "f">, + Group<4>, + Desc<"Disassemble ${f}rom the start of the current frame's function.">; + def disassemble_options_pc : Option<"pc", "p">, + Group<5>, + Desc<"Disassemble around the current ${p}c.">; def disassemble_options_line : Option<"line", "l">, Group<6>, Desc<"Disassemble the current frame's current source line instructions if " "there is debug line table information, else disassemble around the pc.">; diff --git a/lldb/source/Host/common/Editline.cpp b/lldb/source/Host/common/Editline.cpp index 5ed30fbb231d8..5b0997a2eb490 100644 --- a/lldb/source/Host/common/Editline.cpp +++ b/lldb/source/Host/common/Editline.cpp @@ -100,11 +100,6 @@ bool IsOnlySpaces(const EditLineStringType &content) { return true; } -static size_t ColumnWidth(llvm::StringRef str) { - std::string stripped = ansi::StripAnsiTerminalCodes(str); - return llvm::sys::locale::columnWidth(stripped); -} - static int GetOperation(HistoryOperation op) { // The naming used by editline for the history operations is counter // intuitive to how it's used in LLDB's editline implementation. @@ -332,8 +327,8 @@ std::string Editline::PromptForIndex(int line_index) { if (m_set_continuation_prompt.length() > 0) { continuation_prompt = m_set_continuation_prompt; // Ensure that both prompts are the same length through space padding - const size_t prompt_width = ColumnWidth(prompt); - const size_t cont_prompt_width = ColumnWidth(continuation_prompt); + const size_t prompt_width = ansi::ColumnWidth(prompt); + const size_t cont_prompt_width = ansi::ColumnWidth(continuation_prompt); const size_t padded_prompt_width = std::max(prompt_width, cont_prompt_width); if (prompt_width < padded_prompt_width) @@ -358,7 +353,9 @@ void Editline::SetCurrentLine(int line_index) { m_current_prompt = PromptForIndex(line_index); } -size_t Editline::GetPromptWidth() { return ColumnWidth(PromptForIndex(0)); } +size_t Editline::GetPromptWidth() { + return ansi::ColumnWidth(PromptForIndex(0)); +} bool Editline::IsEmacs() { const char *editor; @@ -448,7 +445,7 @@ void Editline::DisplayInput(int firstIndex) { int Editline::CountRowsForLine(const EditLineStringType &content) { std::string prompt = PromptForIndex(0); // Prompt width is constant during an edit session - int line_length = (int)(content.length() + ColumnWidth(prompt)); + int line_length = (int)(content.length() + ansi::ColumnWidth(prompt)); return (line_length / m_terminal_width) + 1; } diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp index ec725428483ff..a51fa2ee20bc7 100644 --- a/lldb/source/Interpreter/Options.cpp +++ b/lldb/source/Interpreter/Options.cpp @@ -273,11 +273,13 @@ void Options::OutputFormattedUsageText(Stream &strm, actual_text.append("] "); } } - actual_text.append(option_def.usage_text); + actual_text.append( + ansi::FormatAnsiTerminalCodes(option_def.usage_text, use_color)); + const size_t visible_length = ansi::ColumnWidth(actual_text); // Will it all fit on one line? - if (static_cast<uint32_t>(actual_text.length() + strm.GetIndentLevel()) < + if (static_cast<uint32_t>(visible_length + strm.GetIndentLevel()) < output_max_columns) { // Output it as a single line. strm.Indent(ansi::FormatAnsiTerminalCodes(actual_text, use_color)); @@ -288,7 +290,7 @@ void Options::OutputFormattedUsageText(Stream &strm, int text_width = output_max_columns - strm.GetIndentLevel() - 1; int start = 0; int end = start; - int final_end = actual_text.length(); + int final_end = visible_length; int sub_len; while (end < final_end) { @@ -631,6 +633,7 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, auto opt_defs = GetDefinitions(); llvm::StringRef cur_opt_str = request.GetCursorArgumentPrefix(); + const bool use_color = interpreter.GetDebugger().GetUseColor(); for (size_t i = 0; i < opt_element_vector.size(); i++) { size_t opt_pos = static_cast<size_t>(opt_element_vector[i].opt_pos); @@ -650,7 +653,8 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, if (!def.short_option) continue; opt_str[1] = def.short_option; - request.AddCompletion(opt_str, def.usage_text); + request.AddCompletion(opt_str, ansi::FormatAnsiTerminalCodes( + def.usage_text, use_color)); } return true; @@ -662,7 +666,8 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, full_name.erase(full_name.begin() + 2, full_name.end()); full_name.append(def.long_option); - request.AddCompletion(full_name, def.usage_text); + request.AddCompletion(full_name, ansi::FormatAnsiTerminalCodes( + def.usage_text, use_color)); } return true; } else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) { @@ -673,7 +678,9 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, const OptionDefinition &opt = opt_defs[opt_defs_index]; llvm::StringRef long_option = opt.long_option; if (cur_opt_str.starts_with("--") && cur_opt_str != long_option) { - request.AddCompletion("--" + long_option.str(), opt.usage_text); + request.AddCompletion( + "--" + long_option.str(), + ansi::FormatAnsiTerminalCodes(opt.usage_text, use_color)); return true; } else request.AddCompletion(request.GetCursorArgumentPrefix()); @@ -689,7 +696,9 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, for (auto &def : opt_defs) { llvm::StringRef long_option(def.long_option); if (long_option.starts_with(cur_opt_str)) - request.AddCompletion("--" + long_option.str(), def.usage_text); + request.AddCompletion( + "--" + long_option.str(), + ansi::FormatAnsiTerminalCodes(def.usage_text, use_color)); } } return true; diff --git a/lldb/test/API/functionalities/completion/TestCompletion.py b/lldb/test/API/functionalities/completion/TestCompletion.py index e7c53729f2090..45750c7ac0817 100644 --- a/lldb/test/API/functionalities/completion/TestCompletion.py +++ b/lldb/test/API/functionalities/completion/TestCompletion.py @@ -676,8 +676,8 @@ def test_completion_description_command_options(self): self.check_completion_with_desc( "breakpoint set -", [ - ["-h", "Set the breakpoint on exception catcH."], - ["-w", "Set the breakpoint on exception throW."], + ["-h", "Set the breakpoint on exception catch."], + ["-w", "Set the breakpoint on exception throw."], ], ) @@ -685,8 +685,8 @@ def test_completion_description_command_options(self): self.check_completion_with_desc( "breakpoint set --", [ - ["--on-catch", "Set the breakpoint on exception catcH."], - ["--on-throw", "Set the breakpoint on exception throW."], + ["--on-catch", "Set the breakpoint on exception catch."], + ["--on-throw", "Set the breakpoint on exception throw."], ], ) @@ -694,8 +694,8 @@ def test_completion_description_command_options(self): self.check_completion_with_desc( "breakpoint set --on-", [ - ["--on-catch", "Set the breakpoint on exception catcH."], - ["--on-throw", "Set the breakpoint on exception throW."], + ["--on-catch", "Set the breakpoint on exception catch."], + ["--on-throw", "Set the breakpoint on exception throw."], ], ) _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits