]> git.cworth.org Git - sup/blob - lib/sup/modes/label-list-mode.rb
add 'A' (archive and mark read) command to inbox-mode
[sup] / lib / sup / modes / label-list-mode.rb
1 module Redwood
2
3 class LabelListMode < LineCursorMode
4   register_keymap do |k|
5     k.add :select_label, "Search by label", :enter
6     k.add :reload, "Discard label list and reload", '@'
7     k.add :jump_to_next_new, "Jump to next new thread", :tab
8     k.add :toggle_show_unread_only, "Toggle between showing all labels and those with unread mail", 'u'
9   end
10
11   def initialize
12     @labels = []
13     @text = []
14     @unread_only = false
15     super
16     regen_text
17   end
18
19   def lines; @text.length end
20   def [] i; @text[i] end
21
22   def jump_to_next_new
23     n = ((curpos + 1) ... lines).find { |i| @labels[i][1] > 0 } || (0 ... curpos).find { |i| @labels[i][1] > 0 }
24     if n
25       ## jump there if necessary
26       jump_to_line n unless n >= topline && n < botline
27       set_cursor_pos n
28     else
29       BufferManager.flash "No labels messages with unread messages."
30     end
31   end
32 protected
33
34   def toggle_show_unread_only
35     @unread_only = !@unread_only
36     reload
37   end
38
39   def reload
40     regen_text
41     buffer.mark_dirty if buffer
42   end
43
44   def regen_text
45     @text = []
46     labels = LabelManager.listable_labels
47
48     counts = labels.map do |label|
49       string = LabelManager.string_for label
50       total = Index.num_results_for :label => label
51       unread = Index.num_results_for :labels => [label, :unread]
52       [label, string, total, unread]
53     end.sort_by { |l, s, t, u| s.downcase }
54
55     width = counts.max_of { |l, s, t, u| s.length }
56
57     if @unread_only
58       counts.delete_if { | l, s, t, u | u == 0 }
59     end
60
61     @labels = []
62     counts.map do |label, string, total, unread|
63       if total == 0 && !LabelManager::RESERVED_LABELS.include?(label)
64         Redwood::log "no hits for label #{label}, deleting"
65         LabelManager.delete label
66         next
67       end
68
69       @text << [[(unread == 0 ? :labellist_old_color : :labellist_new_color),
70           sprintf("%#{width + 1}s %5d %s, %5d unread", string, total, total == 1 ? " message" : "messages", unread)]]
71       @labels << [label, unread]
72       yield i if block_given?
73     end.compact
74
75     BufferManager.flash "No labels with unread messages!" if counts.empty? && @unread_only
76   end
77
78   def select_label
79     label, num_unread = @labels[curpos]
80     return unless label
81     LabelSearchResultsMode.spawn_nicely label
82   end
83 end
84
85 end