]> git.cworth.org Git - sup/blob - lib/sup/modes/line-cursor-mode.rb
no status line with 0 lines
[sup] / lib / sup / modes / line-cursor-mode.rb
1 module Redwood
2
3 class LineCursorMode < ScrollMode
4   register_keymap do |k|
5     ## overwrite scrollmode binding on arrow keys for cursor movement
6     ## but j and k still scroll!
7     k.add :cursor_down, "Move cursor down one line", :down, 'j'
8     k.add :cursor_up, "Move cursor up one line", :up, 'k'
9     k.add :select, "Select this item", :enter
10   end
11
12   attr_reader :curpos
13
14   def initialize cursor_top=0, opts={}
15     @cursor_top = cursor_top
16     @curpos = cursor_top
17     super opts
18   end
19
20   def draw
21     super
22     set_status
23   end
24
25 protected
26
27   def draw_line ln, opts={}
28     if ln == @curpos
29       super ln, :highlight => true, :debug => opts[:debug]
30     else
31       super
32     end
33   end
34
35   def ensure_mode_validity
36     super
37     raise @curpos.inspect unless @curpos.is_a?(Integer)
38     c = @curpos.clamp topline, botline - 1
39     c = @cursor_top if c < @cursor_top
40     buffer.mark_dirty unless c == @curpos
41     @curpos = c
42   end
43
44   def set_cursor_pos p
45     return if @curpos == p
46     @curpos = p.clamp @cursor_top, lines
47     buffer.mark_dirty
48   end
49
50   def line_down # overwrite scrollmode
51     super
52     set_cursor_pos topline if @curpos < topline
53   end
54
55   def line_up # overwrite scrollmode
56     super
57     set_cursor_pos botline - 1 if @curpos > botline - 1
58   end
59
60   def cursor_down
61     return false unless @curpos < lines - 1
62     if @curpos >= botline - 1
63       page_down
64       set_cursor_pos [topline + 1, botline].min
65     else
66       @curpos += 1
67       unless buffer.dirty?
68         draw_line @curpos - 1
69         draw_line @curpos
70         set_status
71         buffer.commit
72       end
73     end
74     true
75   end
76
77   def cursor_up
78     return false unless @curpos > @cursor_top
79     if @curpos == topline
80       page_up
81       set_cursor_pos [botline - 2, topline].max
82     else
83       @curpos -= 1
84       unless buffer.dirty?
85         draw_line @curpos + 1
86         draw_line @curpos
87         set_status
88         buffer.commit
89       end
90     end
91     true
92   end
93
94   def page_up # overwrite
95     if topline <= @cursor_top
96       set_cursor_pos @cursor_top
97     else
98       relpos = @curpos - topline
99       super
100       set_cursor_pos topline + relpos
101     end
102   end
103
104   def page_down
105     if topline >= lines - buffer.content_height
106       set_cursor_pos(lines - 1)
107     else
108       relpos = @curpos - topline
109       super
110       set_cursor_pos [topline + relpos, lines - 1].min
111     end
112   end
113
114   def jump_to_home
115     super
116     set_cursor_pos @cursor_top
117   end
118
119   def jump_to_end
120     super if topline < (lines - buffer.content_height)
121     set_cursor_pos(lines - 1)
122   end
123
124 private
125
126   def set_status
127     l = lines
128     @status = l > 0 ? "line #{@curpos + 1} of #{l}" : ""
129   end
130
131 end
132
133 end