Skip to content

Commit b542228

Browse files
authored
Merge pull request #4030 from apple/🍒/austria/080635ef2791+0acc9e4b5edd+4b093cdc2886
🍒/austria/080635ef2791+0acc9e4b5edd+4b093cdc2886
2 parents 3c2f185 + 86ef7f8 commit b542228

File tree

8 files changed

+135
-47
lines changed

8 files changed

+135
-47
lines changed

lldb/include/lldb/Core/Debugger.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
335335

336336
bool GetUseAutosuggestion() const;
337337

338+
llvm::StringRef GetAutosuggestionAnsiPrefix() const;
339+
340+
llvm::StringRef GetAutosuggestionAnsiSuffix() const;
341+
338342
bool GetUseSourceCache() const;
339343

340344
bool SetUseSourceCache(bool use_source_cache);

lldb/include/lldb/Host/Editline.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,14 @@ class Editline {
210210
m_fix_indentation_callback_chars = indent_chars;
211211
}
212212

213+
void SetSuggestionAnsiPrefix(std::string prefix) {
214+
m_suggestion_ansi_prefix = std::move(prefix);
215+
}
216+
217+
void SetSuggestionAnsiSuffix(std::string suffix) {
218+
m_suggestion_ansi_suffix = std::move(suffix);
219+
}
220+
213221
/// Prompts for and reads a single line of user input.
214222
bool GetLine(std::string &line, bool &interrupted);
215223

@@ -388,9 +396,11 @@ class Editline {
388396
const char *m_fix_indentation_callback_chars = nullptr;
389397

390398
CompleteCallbackType m_completion_callback;
391-
392399
SuggestionCallbackType m_suggestion_callback;
393400

401+
std::string m_suggestion_ansi_prefix;
402+
std::string m_suggestion_ansi_suffix;
403+
394404
std::size_t m_previous_autosuggestion_size = 0;
395405
std::mutex m_output_mutex;
396406
};

lldb/include/lldb/Utility/AnsiTerminal.h

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
#ifndef LLDB_UTILITY_ANSITERMINAL_H
2-
3-
#define LLDB_UTILITY_ANSITERMINAL_H
4-
51
//===---------------------AnsiTerminal.h ------------------------*- C++ -*-===//
62
//
73
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -10,6 +6,9 @@
106
//
117
//===----------------------------------------------------------------------===//
128

9+
#ifndef LLDB_UTILITY_ANSITERMINAL_H
10+
#define LLDB_UTILITY_ANSITERMINAL_H
11+
1312
#define ANSI_FG_COLOR_BLACK 30
1413
#define ANSI_FG_COLOR_RED 31
1514
#define ANSI_FG_COLOR_GREEN 32
@@ -19,6 +18,15 @@
1918
#define ANSI_FG_COLOR_CYAN 36
2019
#define ANSI_FG_COLOR_WHITE 37
2120

21+
#define ANSI_FG_COLOR_BRIGHT_BLACK 90
22+
#define ANSI_FG_COLOR_BRIGHT_RED 91
23+
#define ANSI_FG_COLOR_BRIGHT_GREEN 92
24+
#define ANSI_FG_COLOR_BRIGHT_YELLOW 93
25+
#define ANSI_FG_COLOR_BRIGHT_BLUE 94
26+
#define ANSI_FG_COLOR_BRIGHT_PURPLE 95
27+
#define ANSI_FG_COLOR_BRIGHT_CYAN 96
28+
#define ANSI_FG_COLOR_BRIGHT_WHITE 97
29+
2230
#define ANSI_BG_COLOR_BLACK 40
2331
#define ANSI_BG_COLOR_RED 41
2432
#define ANSI_BG_COLOR_GREEN 42
@@ -28,6 +36,15 @@
2836
#define ANSI_BG_COLOR_CYAN 46
2937
#define ANSI_BG_COLOR_WHITE 47
3038

39+
#define ANSI_BG_COLOR_BRIGHT_BLACK 100
40+
#define ANSI_BG_COLOR_BRIGHT_RED 101
41+
#define ANSI_BG_COLOR_BRIGHT_GREEN 102
42+
#define ANSI_BG_COLOR_BRIGHT_YELLOW 103
43+
#define ANSI_BG_COLOR_BRIGHT_BLUE 104
44+
#define ANSI_BG_COLOR_BRIGHT_PURPLE 105
45+
#define ANSI_BG_COLOR_BRIGHT_CYAN 106
46+
#define ANSI_BG_COLOR_BRIGHT_WHITE 107
47+
3148
#define ANSI_SPECIAL_FRAMED 51
3249
#define ANSI_SPECIAL_ENCIRCLED 52
3350

@@ -67,45 +84,59 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
6784
bool do_color = true) {
6885
// Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is
6986
// false.
87+
// clang-format off
7088
static const struct {
7189
const char *name;
7290
const char *value;
7391
} g_color_tokens[] = {
7492
#define _TO_STR2(_val) #_val
7593
#define _TO_STR(_val) _TO_STR2(_val)
76-
{"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END},
77-
{"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END},
78-
{"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END},
79-
{"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END},
80-
{"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END},
81-
{"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END},
82-
{"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END},
83-
{"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END},
84-
{"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END},
85-
{"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END},
86-
{"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END},
87-
{"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END},
88-
{"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END},
89-
{"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END},
90-
{"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END},
91-
{"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END},
92-
{"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END},
93-
{"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END},
94-
{"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END},
95-
{"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END},
96-
{"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END},
97-
{"slow-blink}",
98-
ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END},
99-
{"fast-blink}",
100-
ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END},
101-
{"negative}",
102-
ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END},
103-
{"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END},
104-
{"crossed-out}",
105-
ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END},
94+
{"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END},
95+
{"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END},
96+
{"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END},
97+
{"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END},
98+
{"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END},
99+
{"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END},
100+
{"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END},
101+
{"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END},
102+
{"fg.bright.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_BLACK) ANSI_ESC_END},
103+
{"fg.bright.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_RED) ANSI_ESC_END},
104+
{"fg.bright.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_GREEN) ANSI_ESC_END},
105+
{"fg.bright.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_YELLOW) ANSI_ESC_END},
106+
{"fg.bright.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_BLUE) ANSI_ESC_END},
107+
{"fg.bright.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_PURPLE) ANSI_ESC_END},
108+
{"fg.bright.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_CYAN) ANSI_ESC_END},
109+
{"fg.bright.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_WHITE) ANSI_ESC_END},
110+
{"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END},
111+
{"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END},
112+
{"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END},
113+
{"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END},
114+
{"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END},
115+
{"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END},
116+
{"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END},
117+
{"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END},
118+
{"bg.bright.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_BLACK) ANSI_ESC_END},
119+
{"bg.bright.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_RED) ANSI_ESC_END},
120+
{"bg.bright.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_GREEN) ANSI_ESC_END},
121+
{"bg.bright.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_YELLOW) ANSI_ESC_END},
122+
{"bg.bright.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_BLUE) ANSI_ESC_END},
123+
{"bg.bright.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_PURPLE) ANSI_ESC_END},
124+
{"bg.bright.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_CYAN) ANSI_ESC_END},
125+
{"bg.bright.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_WHITE) ANSI_ESC_END},
126+
{"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END},
127+
{"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END},
128+
{"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END},
129+
{"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END},
130+
{"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END},
131+
{"slow-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END},
132+
{"fast-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END},
133+
{"negative}", ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END},
134+
{"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END},
135+
{"crossed-out}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END},
106136
#undef _TO_STR
107137
#undef _TO_STR2
108138
};
139+
// clang-format on
109140
auto codes = llvm::makeArrayRef(g_color_tokens);
110141

111142
static const char tok_hdr[] = "${ansi.";

lldb/source/Core/CoreProperties.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,12 @@ let Definition = "debugger" in {
161161
Global,
162162
DefaultFalse,
163163
Desc<"If true, LLDB will show suggestions to complete the command the user typed. Suggestions may be accepted using Ctrl-F.">;
164+
def ShowAutosuggestionAnsiPrefix: Property<"show-autosuggestion-ansi-prefix", "String">,
165+
Global,
166+
DefaultStringValue<"${ansi.faint}">,
167+
Desc<"When displaying suggestion in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately before the suggestion.">;
168+
def ShowAutosuggestionAnsiSuffix: Property<"show-autosuggestion-ansi-suffix", "String">,
169+
Global,
170+
DefaultStringValue<"${ansi.normal}">,
171+
Desc<"When displaying suggestion in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the suggestion.">;
164172
}

lldb/source/Core/Debugger.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,16 @@ bool Debugger::GetUseAutosuggestion() const {
384384
nullptr, idx, g_debugger_properties[idx].default_uint_value != 0);
385385
}
386386

387+
llvm::StringRef Debugger::GetAutosuggestionAnsiPrefix() const {
388+
const uint32_t idx = ePropertyShowAutosuggestionAnsiPrefix;
389+
return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, "");
390+
}
391+
392+
llvm::StringRef Debugger::GetAutosuggestionAnsiSuffix() const {
393+
const uint32_t idx = ePropertyShowAutosuggestionAnsiSuffix;
394+
return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, "");
395+
}
396+
387397
bool Debugger::GetUseSourceCache() const {
388398
const uint32_t idx = ePropertyUseSourceCache;
389399
return m_collection_sp->GetPropertyAtIndexAsBoolean(

lldb/source/Core/IOHandler.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "lldb/Core/StreamFile.h"
1818
#include "lldb/Host/Config.h"
1919
#include "lldb/Host/File.h"
20+
#include "lldb/Utility/AnsiTerminal.h"
2021
#include "lldb/Utility/Predicate.h"
2122
#include "lldb/Utility/ReproducerProvider.h"
2223
#include "lldb/Utility/Status.h"
@@ -273,10 +274,14 @@ IOHandlerEditline::IOHandlerEditline(
273274
this->AutoCompleteCallback(request);
274275
});
275276

276-
if (debugger.GetUseAutosuggestion() && debugger.GetUseColor()) {
277+
if (debugger.GetUseAutosuggestion()) {
277278
m_editline_up->SetSuggestionCallback([this](llvm::StringRef line) {
278279
return this->SuggestionCallback(line);
279280
});
281+
m_editline_up->SetSuggestionAnsiPrefix(ansi::FormatAnsiTerminalCodes(
282+
debugger.GetAutosuggestionAnsiPrefix()));
283+
m_editline_up->SetSuggestionAnsiSuffix(ansi::FormatAnsiTerminalCodes(
284+
debugger.GetAutosuggestionAnsiSuffix()));
280285
}
281286
// See if the delegate supports fixing indentation
282287
const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();

lldb/source/Host/common/Editline.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,8 +1080,13 @@ unsigned char Editline::TypedCharacter(int ch) {
10801080
llvm::StringRef line(line_info->buffer,
10811081
line_info->lastchar - line_info->buffer);
10821082

1083+
const char *ansi_prefix =
1084+
m_color_prompts ? m_suggestion_ansi_prefix.c_str() : "";
1085+
const char *ansi_suffix =
1086+
m_color_prompts ? m_suggestion_ansi_suffix.c_str() : "";
1087+
10831088
if (llvm::Optional<std::string> to_add = m_suggestion_callback(line)) {
1084-
std::string to_add_color = ANSI_FAINT + to_add.getValue() + ANSI_UNFAINT;
1089+
std::string to_add_color = ansi_prefix + to_add.getValue() + ansi_suffix;
10851090
fputs(typed.c_str(), m_output_file);
10861091
fputs(to_add_color.c_str(), m_output_file);
10871092
size_t new_autosuggestion_size = line.size() + to_add->length();

lldb/test/API/iohandler/autosuggestion/TestAutosuggestion.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,24 @@ class TestCase(PExpectTest):
1616

1717
mydir = TestBase.compute_mydir(__file__)
1818

19+
ANSI_FAINT = "\x1b[2m"
20+
ANSI_RESET = "\x1b[0m"
21+
ANSI_RED = "\x1b[31m"
22+
ANSI_CYAN = "\x1b[36m"
23+
1924
# PExpect uses many timeouts internally and doesn't play well
2025
# under ASAN on a loaded machine..
2126
@skipIfAsan
2227
@skipIfEditlineSupportMissing
2328
def test_autosuggestion_add_spaces(self):
2429
self.launch(extra_args=["-o", "settings set show-autosuggestion true", "-o", "settings set use-color true"])
2530

26-
# Common input codes and escape sequences.
27-
faint_color = "\x1b[2m"
28-
reset = "\x1b[0m"
2931

3032
# Check if spaces are added to hide the previous gray characters.
3133
self.expect("help frame var")
3234
self.expect("help frame info")
3335
self.child.send("help frame v")
34-
self.child.expect_exact(cursor_horizontal_abs("(lldb) help frame ") + "v" + faint_color + "ar" + reset + " ")
36+
self.child.expect_exact(cursor_horizontal_abs("(lldb) help frame ") + "v" + self.ANSI_FAINT + "ar" + self.ANSI_RESET + " ")
3537

3638
self.quit()
3739

@@ -40,10 +42,8 @@ def test_autosuggestion_add_spaces(self):
4042
def test_autosuggestion(self):
4143
self.launch(extra_args=["-o", "settings set show-autosuggestion true", "-o", "settings set use-color true"])
4244

43-
# Common input codes and escape sequences.
45+
# Common input codes.
4446
ctrl_f = "\x06"
45-
faint_color = "\x1b[2m"
46-
reset = "\x1b[0m"
4747
delete = chr(127)
4848

4949
frame_output_needle = "Syntax: frame <subcommand>"
@@ -52,7 +52,7 @@ def test_autosuggestion(self):
5252

5353
# Check that LLDB shows the autosuggestion in gray behind the text.
5454
self.child.send("hel")
55-
self.child.expect_exact(cursor_horizontal_abs("(lldb) he") + "l" + faint_color + "p frame" + reset)
55+
self.child.expect_exact(cursor_horizontal_abs("(lldb) he") + "l" + self.ANSI_FAINT + "p frame" + self.ANSI_RESET)
5656

5757
# Apply the autosuggestion and press enter. This should print the
5858
# 'help frame' output if everything went correctly.
@@ -80,7 +80,7 @@ def test_autosuggestion(self):
8080
# Check that autosuggestion complete to the most recent one.
8181
self.child.send("help frame variable\n")
8282
self.child.send("help fr")
83-
self.child.expect_exact(faint_color + "ame variable" + reset)
83+
self.child.expect_exact(self.ANSI_FAINT + "ame variable" + self.ANSI_RESET)
8484
self.child.send("\n")
8585

8686
# Try another command.
@@ -90,7 +90,7 @@ def test_autosuggestion(self):
9090

9191
# Check that 'hel' should have an autosuggestion for 'help apropos' now.
9292
self.child.send("hel")
93-
self.child.expect_exact(cursor_horizontal_abs("(lldb) he") + "l" + faint_color + "p apropos" + reset)
93+
self.child.expect_exact(cursor_horizontal_abs("(lldb) he") + "l" + self.ANSI_FAINT + "p apropos" + self.ANSI_RESET)
9494

9595
# Run the command and expect the 'help apropos' output.
9696
self.child.send(ctrl_f + "\n")
@@ -102,4 +102,19 @@ def test_autosuggestion(self):
102102
self.child.expect_exact(breakpoint_output_needle)
103103

104104

105+
self.quit()
106+
107+
@skipIfAsan
108+
@skipIfEditlineSupportMissing
109+
def test_autosuggestion_custom_ansi_prefix_suffix(self):
110+
self.launch(extra_args=["-o", "settings set show-autosuggestion true",
111+
"-o", "settings set use-color true",
112+
"-o", "settings set show-autosuggestion-ansi-prefix ${ansi.fg.red}",
113+
"-o", "setting set show-autosuggestion-ansi-suffix ${ansi.fg.cyan}"])
114+
115+
self.child.send("help frame variable\n")
116+
self.child.send("help fr")
117+
self.child.expect_exact(self.ANSI_RED + "ame variable" + self.ANSI_CYAN)
118+
self.child.send("\n")
119+
105120
self.quit()

0 commit comments

Comments
 (0)