]> git.cworth.org Git - sup/blobdiff - lib/sup/modes/scroll-mode.rb
Merge branch 'hook-local-vars'
[sup] / lib / sup / modes / scroll-mode.rb
index 219a4ce33bb0271653775276b38ef1d88f6f9c6b..c13142599e9aed1aaad9bde0c1a029b2331fa72e 100644 (file)
@@ -3,7 +3,7 @@ module Redwood
 class ScrollMode < Mode
   ## we define topline and botline as the top and bottom lines of any
   ## content in the currentview.
-  
+
   ## we left leftcol and rightcol as the left and right columns of any
   ## content in the current view. but since we're operating in a
   ## line-centric fashion, rightcol is always leftcol + the buffer
@@ -12,15 +12,17 @@ class ScrollMode < Mode
 
   attr_reader :status, :topline, :botline, :leftcol
 
-  COL_JUMP = 4
+  COL_JUMP = 2
 
   register_keymap do |k|
-    k.add :line_down, "Down one line", :down, 'j', 'J'
-    k.add :line_up, "Up one line", :up, 'k', 'K'
+    k.add :line_down, "Down one line", :down, 'j', 'J', "\C-e"
+    k.add :line_up, "Up one line", :up, 'k', 'K', "\C-y"
     k.add :col_left, "Left one column", :left, 'h'
     k.add :col_right, "Right one column", :right, 'l'
-    k.add :page_down, "Down one page", :page_down, ' '
-    k.add :page_up, "Up one page", :page_up, 'p', :backspace
+    k.add :page_down, "Down one page", :page_down, ' ', "\C-f"
+    k.add :page_up, "Up one page", :page_up, 'p', :backspace, "\C-b"
+    k.add :half_page_down, "Down one half page", "\C-d"
+    k.add :half_page_up, "Up one half page", "\C-u"
     k.add :jump_to_start, "Jump to top", :home, '^', '1'
     k.add :jump_to_end, "Jump to bottom", :end, '$', '0'
     k.add :jump_to_left, "Jump to the left", '['
@@ -64,14 +66,14 @@ class ScrollMode < Mode
     end
 
     start = @search_line || search_start_line
-    line = find_text @search_query, start
+    line, col = find_text @search_query, start
     if line.nil? && (start > 0)
-      line = find_text @search_query, 0
+      line, col = find_text @search_query, 0
       BufferManager.flash "Search wrapped to top!" if line
     end
     if line
       @search_line = line + 1
-      search_goto_line line
+      search_goto_pos line, col, col + @search_query.display_length
       buffer.mark_dirty
     else
       BufferManager.flash "Not found!"
@@ -85,9 +87,16 @@ class ScrollMode < Mode
     continue_search_in_buffer
   end
 
-  ## subclasses can override these two!
-  def search_goto_line line; jump_to_line line end
+  ## subclasses can override these three!
+  def search_goto_pos line, leftcol, rightcol
+    search_goto_line line
+
+    if rightcol > self.rightcol # if it's occluded...
+      jump_to_col [rightcol - buffer.content_width + 1, 0].max # move right
+    end
+  end
   def search_start_line; @topline end
+  def search_goto_line line; jump_to_line line end
 
   def col_left
     return unless @leftcol > 0
@@ -124,6 +133,8 @@ class ScrollMode < Mode
   def line_up;  jump_to_line @topline - 1; end
   def page_down; jump_to_line @topline + buffer.content_height - @slip_rows; end
   def page_up; jump_to_line @topline - buffer.content_height + @slip_rows; end
+  def half_page_down; jump_to_line @topline + buffer.content_height / 2; end
+  def half_page_up; jump_to_line @topline - buffer.content_height / 2; end
   def jump_to_start; jump_to_line 0; end
   def jump_to_end; jump_to_line lines - buffer.content_height; end
 
@@ -144,9 +155,18 @@ protected
     (start_line ... lines).each do |i|
       case(s = self[i])
       when String
-        return i if s =~ regex
+        match = s =~ regex
+        return [i, match] if match
       when Array
-        return i if s.any? { |color, string| string =~ regex }
+        offset = 0
+        s.each do |color, string|
+          match = string =~ regex
+          if match
+            return [i, offset + match]
+          else
+            offset += string.display_length
+          end
+        end
       end
     end
     nil
@@ -199,24 +219,25 @@ protected
 
   def draw_line_from_array ln, a, opts
     xpos = 0
-    a.each do |color, text|
+    a.each_with_index do |(color, text), i|
       raise "nil text for color '#{color}'" if text.nil? # good for debugging
-      
-      if xpos + text.length < @leftcol
+      l = text.display_length
+      no_fill = i != a.size - 1
+
+      if xpos + l < @leftcol
         buffer.write ln - @topline, 0, "", :color => color,
                      :highlight => opts[:highlight]
-        xpos += text.length
       elsif xpos < @leftcol
         ## partial
         buffer.write ln - @topline, 0, text[(@leftcol - xpos) .. -1],
                      :color => color,
-                     :highlight => opts[:highlight]
-        xpos += text.length
+                     :highlight => opts[:highlight], :no_fill => no_fill
       else
         buffer.write ln - @topline, xpos - @leftcol, text,
-                     :color => color, :highlight => opts[:highlight]
-        xpos += text.length
+                     :color => color, :highlight => opts[:highlight],
+                     :no_fill => no_fill
       end
+      xpos += l
     end
   end