This revision was automatically updated to reflect the committed changes.
Closed by commit rGdcd4589a0d68: [lldb][gui] use left/right in the source view 
to scroll (authored by llunak).
Herald added a project: LLDB.

Changed prior to commit:
  https://reviews.llvm.org/D85290?vs=283192&id=286246#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85290/new/

https://reviews.llvm.org/D85290

Files:
  lldb/source/Core/IOHandlerCursesGUI.cpp
  lldb/test/API/commands/gui/viewlarge/TestGuiViewLarge.py

Index: lldb/test/API/commands/gui/viewlarge/TestGuiViewLarge.py
===================================================================
--- lldb/test/API/commands/gui/viewlarge/TestGuiViewLarge.py
+++ lldb/test/API/commands/gui/viewlarge/TestGuiViewLarge.py
@@ -25,6 +25,9 @@
         self.expect("run", substrs=["stop reason ="])
 
         escape_key = chr(27).encode()
+        left_key = chr(27)+'OD' # for vt100 terminal (lldbexpect sets TERM=vt100)
+        right_key = chr(27)+'OC'
+        ctrl_l = chr(12)
 
         # Start the GUI and close the welcome window.
         self.child.sendline("gui")
@@ -45,6 +48,20 @@
         self.child.expect_exact("(int) a_variable_with_a_very_looooooooooooooooooooooooooooooo"+chr(27))
         self.child.expect_exact("(int) shortvar = 1"+chr(27))
 
+        # Scroll the sources view twice to the right.
+        self.child.send(right_key)
+        self.child.send(right_key)
+        # Force a redraw, otherwise curses will optimize the drawing to not draw all 'o'.
+        self.child.send(ctrl_l)
+        # The source code is indented by two spaces, so there'll be just two extra 'o' on the right.
+        self.child.expect_exact("int a_variable_with_a_very_looooooooooooooooooooooooooooo"+chr(27))
+
+        # And scroll back to the left.
+        self.child.send(left_key)
+        self.child.send(left_key)
+        self.child.send(ctrl_l)
+        self.child.expect_exact("int a_variable_with_a_very_looooooooooooooooooooooooooo"+chr(27))
+
         # Press escape to quit the gui
         self.child.send(escape_key)
 
Index: lldb/source/Core/IOHandlerCursesGUI.cpp
===================================================================
--- lldb/source/Core/IOHandlerCursesGUI.cpp
+++ lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -480,23 +480,40 @@
 
   // Curses doesn't allow direct output of color escape sequences, but that's
   // how we get source lines from the Highligher class. Read the line and
-  // convert color escape sequences to curses color attributes.
-  void OutputColoredStringTruncated(int right_pad, StringRef string,
+  // convert color escape sequences to curses color attributes. Use
+  // first_skip_count to skip leading visible characters. Returns false if all
+  // visible characters were skipped due to first_skip_count.
+  bool OutputColoredStringTruncated(int right_pad, StringRef string,
+                                    size_t skip_first_count,
                                     bool use_blue_background) {
     attr_t saved_attr;
     short saved_pair;
+    bool result = false;
     wattr_get(m_window, &saved_attr, &saved_pair, nullptr);
     if (use_blue_background)
       ::wattron(m_window, COLOR_PAIR(WhiteOnBlue));
     while (!string.empty()) {
       size_t esc_pos = string.find('\x1b');
       if (esc_pos == StringRef::npos) {
-        PutCStringTruncated(right_pad, string.data(), string.size());
+        string = string.substr(skip_first_count);
+        if (!string.empty()) {
+          PutCStringTruncated(right_pad, string.data(), string.size());
+          result = true;
+        }
         break;
       }
       if (esc_pos > 0) {
-        PutCStringTruncated(right_pad, string.data(), esc_pos);
-        string = string.drop_front(esc_pos);
+        if (skip_first_count > 0) {
+          int skip = std::min(esc_pos, skip_first_count);
+          string = string.substr(skip);
+          skip_first_count -= skip;
+          esc_pos -= skip;
+        }
+        if (esc_pos > 0) {
+          PutCStringTruncated(right_pad, string.data(), esc_pos);
+          result = true;
+          string = string.drop_front(esc_pos);
+        }
       }
       bool consumed = string.consume_front("\x1b");
       assert(consumed);
@@ -531,6 +548,7 @@
       }
     }
     wattr_set(m_window, saved_attr, saved_pair, nullptr);
+    return result;
   }
 
   void Touch() {
@@ -3379,7 +3397,8 @@
         m_disassembly_scope(nullptr), m_disassembly_sp(), m_disassembly_range(),
         m_title(), m_line_width(4), m_selected_line(0), m_pc_line(0),
         m_stop_id(0), m_frame_idx(UINT32_MAX), m_first_visible_line(0),
-        m_min_x(0), m_min_y(0), m_max_x(0), m_max_y(0) {}
+        m_first_visible_column(0), m_min_x(0), m_min_y(0), m_max_x(0),
+        m_max_y(0) {}
 
   ~SourceFileWindowDelegate() override = default;
 
@@ -3396,6 +3415,8 @@
         {KEY_RETURN, "Run to selected line with one shot breakpoint"},
         {KEY_UP, "Select previous source line"},
         {KEY_DOWN, "Select next source line"},
+        {KEY_LEFT, "Scroll to the left"},
+        {KEY_RIGHT, "Scroll to the right"},
         {KEY_PPAGE, "Page up"},
         {KEY_NPAGE, "Page down"},
         {'b', "Set breakpoint on selected source/disassembly line"},
@@ -3650,7 +3671,15 @@
           StringRef line = lineStream.GetString();
           if (line.endswith("\n"))
             line = line.drop_back();
-          window.OutputColoredStringTruncated(1, line, is_pc_line);
+          bool wasWritten = window.OutputColoredStringTruncated(
+              1, line, m_first_visible_column, line_is_selected);
+          if (line_is_selected && !wasWritten) {
+            // Draw an empty space to show the selected line if empty,
+            // or draw '<' if nothing is visible because of scrolling too much
+            // to the right.
+            window.PutCStringTruncated(
+                1, line.empty() && m_first_visible_column == 0 ? " " : "<");
+          }
 
           if (is_pc_line && frame_sp &&
               frame_sp->GetConcreteFrameIndex() == 0) {
@@ -3801,7 +3830,9 @@
             strm.Printf("%s", mnemonic);
 
           int right_pad = 1;
-          window.PutCStringTruncated(right_pad, strm.GetData());
+          window.PutCStringTruncated(
+              right_pad,
+              strm.GetString().substr(m_first_visible_column).data());
 
           if (is_pc_line && frame_sp &&
               frame_sp->GetConcreteFrameIndex() == 0) {
@@ -3896,6 +3927,15 @@
       }
       return eKeyHandled;
 
+    case KEY_LEFT:
+      if (m_first_visible_column > 0)
+        --m_first_visible_column;
+      return eKeyHandled;
+
+    case KEY_RIGHT:
+      ++m_first_visible_column;
+      return eKeyHandled;
+
     case '\r':
     case '\n':
     case KEY_ENTER:
@@ -4127,6 +4167,7 @@
   uint32_t m_stop_id;
   uint32_t m_frame_idx;
   int m_first_visible_line;
+  int m_first_visible_column;
   int m_min_x;
   int m_min_y;
   int m_max_x;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to