]> git.cworth.org Git - sup/blob - lib/sup/modes/scroll-mode.rb
yet more fixes to imap, some buffer debugging, and more comment cleanups
[sup] / lib / sup / modes / scroll-mode.rb
1 module Redwood
2
3 class ScrollMode < Mode
4   attr_reader :status, :topline, :botline
5
6   COL_JUMP = 2
7
8   register_keymap do |k|
9     k.add :line_down, "Down one line", :down, 'j', 'J'
10     k.add :line_up, "Up one line", :up, 'k', 'K'
11     k.add :col_left, "Left one column", :left, 'h'
12     k.add :col_right, "Right one column", :right, 'l'
13     k.add :page_down, "Down one page", :page_down, 'n', ' '
14     k.add :page_up, "Up one page", :page_up, 'p', :backspace
15     k.add :jump_to_home, "Jump to top", :home, '^', '1'
16     k.add :jump_to_end, "Jump to bottom", :end, '$', '0'
17     k.add :jump_to_left, "Jump to the left", '['
18   end
19
20   def initialize opts={}
21     @topline, @botline, @leftcol = 0, 0, 0
22     @slip_rows = opts[:slip_rows] || 0 # when we pgup/pgdown,
23                                        # how many lines do we keep?
24     @twiddles = opts.member?(:twiddles) ? opts[:twiddles] : true
25     super()
26   end
27
28   def draw
29     ensure_mode_validity
30     (@topline ... @botline).each { |ln| draw_line ln }
31     ((@botline - @topline) ... buffer.content_height).each do |ln|
32       if @twiddles
33         buffer.write ln, 0, "~", :color => :twiddle_color
34       else
35         buffer.write ln, 0, ""
36       end
37     end
38     @status = "lines #{@topline + 1}:#{@botline}/#{lines}"
39   end
40
41   def col_left
42     return unless @leftcol > 0
43     @leftcol -= COL_JUMP
44     buffer.mark_dirty
45   end
46
47   def col_right
48     @leftcol += COL_JUMP
49     buffer.mark_dirty
50   end
51
52   def jump_to_left
53     buffer.mark_dirty unless @leftcol == 0
54     @leftcol = 0
55   end
56
57   ## set top line to l
58   def jump_to_line l
59     l = l.clamp 0, lines - 1
60     return if @topline == l
61     @topline = l
62     @botline = [l + buffer.content_height, lines].min
63     buffer.mark_dirty
64   end
65
66   def line_down; jump_to_line @topline + 1; end
67   def line_up;  jump_to_line @topline - 1; end
68   def page_down; jump_to_line @topline + buffer.content_height - @slip_rows; end
69   def page_up; jump_to_line @topline - buffer.content_height + @slip_rows; end
70   def jump_to_home; jump_to_line 0; end
71   def jump_to_end; jump_to_line lines - buffer.content_height; end
72
73
74   def ensure_mode_validity
75     @topline = @topline.clamp 0, lines - 1
76     @topline = 0 if @topline < 0 # empty 
77     @botline = [@topline + buffer.content_height, lines].min
78   end
79
80   def resize *a
81     super *a
82     ensure_mode_validity
83   end
84
85 protected
86
87   def draw_line ln, opts={}
88     case(s = self[ln])
89     when String
90       buffer.write ln - @topline, 0, s[@leftcol .. -1],
91                    :highlight => opts[:highlight]
92     when Array
93       xpos = 0
94
95       ## speed test
96       # str = s.map { |color, text| text }.join
97       # buffer.write ln - @topline, 0, str, :color => :none, :highlight => opts[:highlight]
98       # return
99
100       s.each do |color, text|
101         raise "nil text for color '#{color}'" if text.nil? # good for debugging
102         if xpos + text.length < @leftcol
103           buffer.write ln - @topline, 0, "", :color => color,
104                        :highlight => opts[:highlight]
105           xpos += text.length
106         elsif xpos < @leftcol
107           ## partial
108           buffer.write ln - @topline, 0, text[(@leftcol - xpos) .. -1],
109                        :color => color,
110                        :highlight => opts[:highlight]
111           xpos += text.length
112         else
113           buffer.write ln - @topline, xpos - @leftcol, text,
114                        :color => color, :highlight => opts[:highlight]
115           xpos += text.length
116         end
117
118       end
119     end
120   end
121 end
122
123 end