xref: /llvm-project/lldb/test/API/terminal/TestEditline.py (revision 2841cdbfda92b3fb5fbec726f3376b198106d496)
1"""
2Test that the lldb editline handling is configured correctly.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9from lldbsuite.test.lldbpexpect import PExpectTest
10
11
12class EditlineTest(PExpectTest):
13    @skipIfAsan
14    @skipIfEditlineSupportMissing
15    @skipIf(oslist=["linux"], archs=["arm", "aarch64"])
16    def test_left_right_arrow(self):
17        """Test that ctrl+left/right arrow navigates words correctly.
18
19        Note: just sending escape characters to pexpect and checking the buffer
20        doesn't work well, so we run real commands. We want to type
21        "help command" while exercising word-navigation, so type it as below,
22        where [] indicates cursor position.
23
24        1. Send "el rint"  -> "el rint[]"
25        2. Ctrl+left once  -> "el []rint"
26        3. Send "p"        -> "el p[]rint"
27        4. Ctrl+left twice -> "[]el print"
28        5. Send "h"        -> "h[]el print"
29        6. Ctrl+right      -> "hel[] print"
30        7. Send "p"        -> "help print"
31        """
32        self.launch()
33
34        escape_pairs = [
35            ("\x1b[1;5D", "\x1b[1;5C"),
36            ("\x1b[5D", "\x1b[5C"),
37            ("\x1b\x1b[D", "\x1b\x1b[C"),
38        ]
39        for l_escape, r_escape in escape_pairs:
40            self.expect(
41                "el rint{L}p{L}{L}h{R}p".format(L=l_escape, R=r_escape),
42                substrs=["Syntax: print"],
43            )
44
45        self.quit()
46
47    @skipIfAsan
48    @skipIfEditlineSupportMissing
49    @skipIfEditlineWideCharSupportMissing
50    def test_prompt_unicode(self):
51        """Test that we can use Unicode in the LLDB prompt."""
52        self.launch(use_colors=True, encoding="utf-8")
53        self.child.send('settings set prompt "�� "\n')
54        # Check that the cursor is at position 4 ([4G)
55        # Prompt: �� _
56        # Column: 1..4
57        self.child.expect(re.escape("�� \x1b[0m\x1b[4G"))
58
59    @skipIfAsan
60    @skipIfEditlineSupportMissing
61    def test_prompt_color(self):
62        """Test that we can change the prompt color with prompt-ansi-prefix."""
63        self.launch(use_colors=True)
64        self.child.send('settings set prompt-ansi-prefix "${ansi.fg.red}"\n')
65        # Make sure this change is reflected immediately. Check that the color
66        # is set (31) and the cursor position (8) is correct.
67        # Prompt: (lldb) _
68        # Column: 1....6.8
69        self.child.expect(re.escape("\x1b[31m(lldb) \x1b[0m\x1b[8G"))
70
71    @skipIfAsan
72    @skipIfEditlineSupportMissing
73    def test_prompt_format_color(self):
74        """Test that we can change the prompt color with a format string."""
75        self.launch(use_colors=True)
76        # Clear the prefix and suffix setting to simplify the output.
77        self.expect('settings set prompt-ansi-prefix ""')
78        self.expect('settings set prompt-ansi-suffix ""')
79        self.expect('settings set prompt "${ansi.fg.red}(lldb) ${ansi.normal}"')
80        self.child.send("foo")
81        # Make sure this change is reflected immediately. Check that the color
82        # is set (31) and the cursor position (8) is correct.
83        # Prompt: (lldb) _
84        # Column: 1....6.8
85        self.child.expect(re.escape("\x1b[31m(lldb) \x1b[0m\x1b[8Gfoo"))
86
87    @skipIfAsan
88    @skipIfEditlineSupportMissing
89    def test_prompt_no_color(self):
90        """Test that prompt-ansi-prefix doesn't color the prompt when colors are off."""
91        self.launch(use_colors=False)
92        self.child.send('settings set prompt-ansi-prefix "${ansi.fg.red}"\n')
93        # Send foo so we can match the newline before the prompt and the foo
94        # after the prompt.
95        self.child.send("foo")
96        # Check that there are no escape codes.
97        self.child.expect(re.escape("\n(lldb) foo"))
98