_ split out threading & message chunk parsing to a separate library
_ decode RFC 2047 ("encoded word") headers
- see: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/101949, http://dev.rubyonrails.org/ticket/6807
+_ refactor all the *-search-results-mode classes into one.
+x autoload more threads when you go down
x add a sync-back tool that at least works for mboxes
x thread by subject configurable in config.yaml
x view as text command if the mime view command fails for an attachment
module Redwood
+## extends ScrollMode to have a line-based cursor.
class LineCursorMode < ScrollMode
register_keymap do |k|
## overwrite scrollmode binding on arrow keys for cursor movement
def initialize cursor_top=0, opts={}
@cursor_top = cursor_top
@curpos = cursor_top
+ @load_more_callbacks = []
+ @load_more_callbacks_m = Mutex.new
+ @load_more_callbacks_active = false
super opts
end
protected
+ ## callbacks when the cursor is asked to go beyond the bottom
+ def to_load_more &b
+ @load_more_callbacks << b
+ end
+
def draw_line ln, opts={}
if ln == @curpos
super ln, :highlight => true, :debug => opts[:debug]
def line_down # overwrite scrollmode
super
+ call_load_more_callbacks([topline + buffer.content_height - lines, 10].max) if topline + buffer.content_height > lines
set_cursor_pos topline if @curpos < topline
end
end
def cursor_down
+ call_load_more_callbacks buffer.content_height if @curpos == lines - 1
return false unless @curpos < lines - 1
+
if @curpos >= botline - 1
page_down
set_cursor_pos topline
end
end
+ ## more complicated than one might think. three behaviors.
def page_down
- if topline >= lines - buffer.content_height
+ ## if we're on the last page, and it's not a full page, just move
+ ## the cursor down to the bottom and assume we can't load anything
+ ## else via the callbacks.
+ if topline > lines - buffer.content_height
set_cursor_pos(lines - 1)
+
+ ## if we're on the last page, and it's a full page, try and load
+ ## more lines via the callbacks and then shift the page down
+ elsif topline == lines - buffer.content_height
+ call_load_more_callbacks buffer.content_height
+ super
+
+ ## otherwise, just move down
else
relpos = @curpos - topline
super
@status = l > 0 ? "line #{@curpos + 1} of #{l}" : ""
end
+ def call_load_more_callbacks size
+ go =
+ @load_more_callbacks_m.synchronize do
+ if @load_more_callbacks_active
+ false
+ else
+ @load_more_callbacks_active = true
+ end
+ end
+
+ return unless go
+
+ @load_more_callbacks.each { |c| c.call size }
+ @load_more_callbacks_active = false
+ end
+
end
end
module Redwood
## subclasses should implement load_threads
-
class ThreadIndexMode < LineCursorMode
DATE_WIDTH = Time::TO_NICE_S_MAX_LEN
FROM_WIDTH = 15
@date_width = DATE_WIDTH
@from_width = FROM_WIDTH
@size_width = nil
-
+ @last_load_more_size = nil
+
@tags = Tagger.new self
initialize_threads
update
UpdateManager.register self
+
+ to_load_more do |size|
+ next if @last_load_more_size == 0
+ load_threads :num => size,
+ :when_done => lambda { |num| @last_load_more_size = num }
+ sleep 1.0 # give 'em a chance to load
+ end
end
def lines; @text.length; end
def status
if (l = lines) == 0
- ""
+ "line 0 of 0"
else
"line #{curpos + 1} of #{l} #{dirty? ? '*modified*' : ''}"
end