]> git.cworth.org Git - sup/blobdiff - lib/sup/modes/scroll-mode.rb
abort message composition if the file is unedited
[sup] / lib / sup / modes / scroll-mode.rb
index 3477575998413249ff94c007fd18dbebc1c123f1..513ecc90a030dc16f8a1dffb9633270f7a0e548d 100644 (file)
@@ -1,7 +1,16 @@
 module Redwood
 
 class ScrollMode < Mode
-  attr_reader :status, :topline, :botline
+  ## 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
+  ## width. (whereas botline is topline + at most the buffer height,
+  ## and can be == to topline in the case that there's no content.)
+
+  attr_reader :status, :topline, :botline, :leftcol
 
   COL_JUMP = 2
 
@@ -12,7 +21,7 @@ class ScrollMode < Mode
     k.add :col_right, "Right one column", :right, 'l'
     k.add :page_down, "Down one page", :page_down, 'n', ' '
     k.add :page_up, "Up one page", :page_up, 'p', :backspace
-    k.add :jump_to_home, "Jump to top", :home, '^', '1'
+    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", '['
   end
@@ -25,6 +34,8 @@ class ScrollMode < Mode
     super()
   end
 
+  def rightcol; @leftcol + buffer.content_width; end
+
   def draw
     ensure_mode_validity
     (@topline ... @botline).each { |ln| draw_line ln }
@@ -49,11 +60,13 @@ class ScrollMode < Mode
     buffer.mark_dirty
   end
 
-  def jump_to_left
-    buffer.mark_dirty unless @leftcol == 0
-    @leftcol = 0
+  def jump_to_col col
+    buffer.mark_dirty unless @leftcol == col
+    @leftcol = col
   end
 
+  def jump_to_left; jump_to_col 0; end
+
   ## set top line to l
   def jump_to_line l
     l = l.clamp 0, lines - 1
@@ -63,20 +76,26 @@ class ScrollMode < Mode
     buffer.mark_dirty
   end
 
+  def at_top?; @topline == 0 end
+  def at_bottom?; @botline == lines end
+
   def line_down; jump_to_line @topline + 1; end
   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 jump_to_home; jump_to_line 0; end
+  def jump_to_start; jump_to_line 0; end
   def jump_to_end; jump_to_line lines - buffer.content_height; end
 
-
   def ensure_mode_validity
-    @topline = @topline.clamp 0, lines - 1
-    @topline = 0 if @topline < 0 # empty 
+    @topline = @topline.clamp 0, [lines - 1, 0].max
     @botline = [@topline + buffer.content_height, lines].min
   end
 
+  def resize *a
+    super(*a)
+    ensure_mode_validity
+  end
+
 protected
 
   def draw_line ln, opts={}
@@ -86,6 +105,12 @@ protected
                    :highlight => opts[:highlight]
     when Array
       xpos = 0
+
+      ## speed test
+      # str = s.map { |color, text| text }.join
+      # buffer.write ln - @topline, 0, str, :color => :none, :highlight => opts[:highlight]
+      # return
+
       s.each do |color, text|
         raise "nil text for color '#{color}'" if text.nil? # good for debugging
         if xpos + text.length < @leftcol