xref: /llvm-project/lldb/test/API/iohandler/autosuggestion/TestAutosuggestion.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""
2Tests autosuggestion using pexpect.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test.lldbpexpect import PExpectTest
9
10
11def cursor_horizontal_abs(s):
12    return "\x1b[" + str(len(s) + 1) + "G"
13
14
15class TestCase(PExpectTest):
16    ANSI_FAINT = "\x1b[2m"
17    ANSI_RESET = "\x1b[0m"
18    ANSI_RED = "\x1b[31m"
19    ANSI_CYAN = "\x1b[36m"
20
21    # PExpect uses many timeouts internally and doesn't play well
22    # under ASAN on a loaded machine..
23    @skipIfAsan
24    @skipIfEditlineSupportMissing
25    def test_autosuggestion_add_spaces(self):
26        self.launch(
27            use_colors=True,
28            extra_args=[
29                "-o",
30                "settings set show-autosuggestion true",
31                "-o",
32                "settings set use-color true",
33            ],
34        )
35
36        # Check if spaces are added to hide the previous gray characters.
37        self.expect("help frame var")
38        self.expect("help frame info")
39        self.child.send("help frame v")
40        self.child.expect_exact(
41            cursor_horizontal_abs("(lldb) help frame ")
42            + "v"
43            + self.ANSI_FAINT
44            + "ar"
45            + self.ANSI_RESET
46            + " "
47        )
48
49        self.quit()
50
51    @skipIfAsan
52    @skipIfEditlineSupportMissing
53    def test_autosuggestion(self):
54        self.launch(
55            use_colors=True,
56            extra_args=[
57                "-o",
58                "settings set show-autosuggestion true",
59                "-o",
60                "settings set use-color true",
61            ],
62        )
63
64        # Common input codes.
65        ctrl_f = "\x06"
66        delete = chr(127)
67
68        frame_output_needle = "Syntax: frame <subcommand>"
69        # Run 'help frame' once to put it into the command history.
70        self.expect("help frame", substrs=[frame_output_needle])
71
72        # Check that LLDB shows the autosuggestion in gray behind the text.
73        self.child.send("hel")
74        self.child.expect_exact(
75            cursor_horizontal_abs("(lldb) he")
76            + "l"
77            + self.ANSI_FAINT
78            + "p frame"
79            + self.ANSI_RESET
80        )
81
82        # Apply the autosuggestion and press enter. This should print the
83        # 'help frame' output if everything went correctly.
84        self.child.send(ctrl_f + "\n")
85        self.child.expect_exact(frame_output_needle)
86
87        # Check that pressing Ctrl+F directly after Ctrl+F again does nothing.
88        self.child.send("hel" + ctrl_f + ctrl_f + "\n")
89        self.child.expect_exact(frame_output_needle)
90
91        # Try autosuggestion using tab and ^f.
92        # \t makes "help" and ^f makes "help frame". If everything went
93        # correct we should see the 'help frame' output again.
94        self.child.send("hel\t" + ctrl_f + "\n")
95        self.child.expect_exact(frame_output_needle)
96
97        # Check that autosuggestion works after delete.
98        self.child.send("a1234" + 5 * delete + "hel" + ctrl_f + "\n")
99        self.child.expect_exact(frame_output_needle)
100
101        # Check that autosuggestion works after delete.
102        self.child.send("help x" + delete + ctrl_f + "\n")
103        self.child.expect_exact(frame_output_needle)
104
105        # Check that autosuggestion complete to the most recent one.
106        self.child.send("help frame variable\n")
107        self.child.send("help fr")
108        self.child.expect_exact(self.ANSI_FAINT + "ame variable" + self.ANSI_RESET)
109        self.child.send("\n")
110
111        # Try another command.
112        apropos_output_needle = "Syntax: apropos <search-word>"
113        # Run 'help frame' once to put it into the command history.
114        self.expect("help apropos", substrs=[apropos_output_needle])
115
116        # Check that 'hel' should have an autosuggestion for 'help apropos' now.
117        self.child.send("hel")
118        self.child.expect_exact(
119            cursor_horizontal_abs("(lldb) he")
120            + "l"
121            + self.ANSI_FAINT
122            + "p apropos"
123            + self.ANSI_RESET
124        )
125
126        # Run the command and expect the 'help apropos' output.
127        self.child.send(ctrl_f + "\n")
128        self.child.expect_exact(apropos_output_needle)
129
130        # Check that pressing Ctrl+F in an empty prompt does nothing.
131        breakpoint_output_needle = "Syntax: breakpoint <subcommand>"
132        self.child.send(ctrl_f + "help breakpoint" + "\n")
133        self.child.expect_exact(breakpoint_output_needle)
134
135        self.quit()
136
137    @skipIfAsan
138    @skipIfEditlineSupportMissing
139    def test_autosuggestion_custom_ansi_prefix_suffix(self):
140        self.launch(
141            use_colors=True,
142            extra_args=[
143                "-o",
144                "settings set show-autosuggestion true",
145                "-o",
146                "settings set use-color true",
147                "-o",
148                "settings set show-autosuggestion-ansi-prefix ${ansi.fg.red}",
149                "-o",
150                "setting set show-autosuggestion-ansi-suffix ${ansi.fg.cyan}",
151            ],
152        )
153
154        self.child.send("help frame variable\n")
155        self.child.send("help fr")
156        self.child.expect_exact(self.ANSI_RED + "ame variable" + self.ANSI_CYAN)
157        self.child.send("\n")
158
159        self.quit()
160