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