]> git.cworth.org Git - sup/commitdiff
L now prompts for label rather than immediately spawning label-select-mode
authorwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Sun, 8 Jul 2007 23:08:50 +0000 (23:08 +0000)
committerwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Sun, 8 Jul 2007 23:08:50 +0000 (23:08 +0000)
git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@487 5c8cc53c-5e98-4d25-b20a-d8db53a31250

bin/sup
lib/sup/buffer.rb
lib/sup/keymap.rb
lib/sup/label.rb
lib/sup/modes/buffer-list-mode.rb
lib/sup/modes/completion-mode.rb
lib/sup/modes/file-browser-mode.rb
lib/sup/modes/label-list-mode.rb
lib/sup/modes/thread-index-mode.rb
lib/sup/textfield.rb
lib/sup/util.rb

diff --git a/bin/sup b/bin/sup
index 52de3fc7b2dd6435ea2c6d4dd1df6b48dfd5a522..bc3af0fc9799824618b1089a354e63e67c4112dd 100644 (file)
--- a/bin/sup
+++ b/bin/sup
@@ -216,8 +216,22 @@ begin
           bm.flash "Couldn't parse query."
         end
       when :list_labels
-        b = bm.spawn_unless_exists("Label list") { LabelListMode.new }
-        b.mode.load_in_background
+        labels = LabelManager.listable_label_strings
+        user_label = bm.ask_with_completions :label, "Show threads with label (enter for listing): ", labels
+        user_label = bm.spawn_modal("Label list", LabelListMode.new) if user_label && user_label.empty?
+        
+        label = LabelManager.label_for user_label if user_label
+        case label
+        when nil
+        when :inbox
+          BufferManager.raise_to_front InboxMode.instance.buffer
+        else
+          b = BufferManager.spawn_unless_exists("All threads with label '#{user_label}'") do
+            mode = LabelSearchResultsMode.new([label])
+          end
+          b.mode.load_threads :num => b.content_height
+        end
+
       when :compose
         mode = ComposeMode.new
         bm.spawn "New Message", mode
index 5aa97ca395df477377d52cb7974d9d0b3f5744b5..47a844a499947eea4b1c44013f395a44b3eb397e 100644 (file)
@@ -326,6 +326,12 @@ class BufferManager
     end
   end
 
+  def ask_with_completions domain, question, completions, default=nil
+    ask domain, question, default do |s|
+      completions.select { |x| x =~ /^#{s}/i }.map { |x| [x, x] }
+    end
+  end
+
   ## returns an ARRAY of filenames!
   def ask_for_filenames domain, question, default=nil
     answer = ask domain, question, default do |s|
index 64935d9702ed1611e0ec0a0727802c1effa80b96..ce261ba96ef05f8eaf17da7bfc7c836e468e381e 100644 (file)
@@ -81,7 +81,7 @@ class Keymap
       next if valid_keys.empty?
       [valid_keys.map { |k| keysym_to_string k }.join(", "), help]
     end.compact
-    llen = lines.map { |a, b| a.length }.max
+    llen = lines.max_of { |a, b| a.length }
     lines.map { |a, b| sprintf " %#{llen}s : %s", a, b }.join("\n")
   end
 end
index 770f21946ccb9d66c2dc9aad11744e05e917241e..5d3dc4a6403de0d3f116fa92e8b99516eab038f9 100644 (file)
@@ -8,10 +8,10 @@ class LabelManager
   RESERVED_LABELS = [ :starred, :spam, :draft, :unread, :killed, :sent, :deleted ]
 
   ## labels which it nonetheless makes sense to search for by
-  LISTABLE_LABELS = [ :starred, :spam, :draft, :sent, :killed, :deleted ]
+  LISTABLE_RESERVED_LABELS = [ :starred, :spam, :draft, :sent, :killed, :deleted ]
 
   ## labels that will never be displayed to the user
-  HIDDEN_LABELS = [ :starred, :unread ]
+  HIDDEN_RESERVED_LABELS = [ :starred, :unread ]
 
   def initialize fn
     @fn = fn
@@ -27,7 +27,19 @@ class LabelManager
     self.class.i_am_the_instance self
   end
 
-  def user_labels; @labels.keys; end
+  ## all listable (user-defined and system listable) labels, ordered
+  ## nicely and converted to pretty strings. use #label_for to recover
+  ## the original label.
+  def listable_label_strings
+    LISTABLE_RESERVED_LABELS.sort_by { |l| l.to_s }.map { |l| l.to_s.ucfirst } +
+      @labels.keys.map { |l| l.to_s }.sort
+  end
+
+  ## reverse the label->string mapping, for convenience!
+  def label_for string
+    string.downcase.intern
+  end
+  
   def << t; @labels[t] = true unless @labels.member?(t) || RESERVED_LABELS.member?(t); end
   def delete t; @labels.delete t; end
   def save
index a830b8ecdb0327a5548bb3c58409d9d5b0dbf57b..69d367f10829a127a428712cb8c691e7002c597b 100644 (file)
@@ -23,7 +23,7 @@ protected
 
   def regen_text
     @bufs = BufferManager.buffers.sort_by { |name, buf| name }
-    width = @bufs.map { |name, buf| buf.mode.name.length }.max
+    width = @bufs.max_of { |name, buf| buf.mode.name.length }
     @text = @bufs.map do |name, buf|
       sprintf "%#{width}s  %s", buf.mode.name, name
     end
index e96b93551e0e471aa73f8e1f3aaf926ba1e9d250..638c64e1e523625eda7495b14682ec157afcb385 100644 (file)
@@ -27,7 +27,7 @@ private
 
   def update_lines
     width = buffer.content_width
-    max_length = @list.map { |s| s.length }.max
+    max_length = @list.max_of { |s| s.length }
     num_per = buffer.content_width / (max_length + INTERSTITIAL.length)
     @lines = [@header].compact
     @list.each_with_index do |s, i|
index d9af9577c70501df80d1d3488eef086dd816190f..0105d73651de80a5674f82cecc5159d130eb6ef5 100644 (file)
@@ -96,8 +96,8 @@ protected
       [name, real_f]
     end
 
-    size_width = @files.map { |name, f| f.human_size.length }.max
-    time_width = @files.map { |name, f| f.human_time.length }.max
+    size_width = @files.max_of { |name, f| f.human_size.length }
+    time_width = @files.max_of { |name, f| f.human_time.length }
 
     @text = ["#{cwd}:"] + @files.map do |name, f|
       sprintf "%#{time_width}s %#{size_width}s %s", f.human_time, f.human_size, name
index 104bf86a3bec4fba231c2e083335b0a019427cd2..cd7f9f5b69e6542433735e8d01df7e51159bc57d 100644 (file)
@@ -2,79 +2,61 @@ module Redwood
 
 class LabelListMode < LineCursorMode
   register_keymap do |k|
-    k.add :view_results, "View messages with the selected label", :enter
-    k.add :reload, "Discard results and reload", 'D'
+    k.add :select_label, "Select label", :enter
+    k.add :reload, "Discard label list and reload", 'D'
   end
 
+  bool_reader :done
+  attr_reader :value
+
   def initialize
     @labels = []
     @text = []
-    super()
+    @done = false
+    @value = nil
+    super
+    regen_text
   end
 
-  def lines; @text.length; end
-  def [] i; @text[i]; end
-
-  def load_in_background
-    Redwood::reporting_thread do
-      BufferManager.say("Counting labels...") { regen_text }
-      BufferManager.draw_screen
-    end
-  end
+  def lines; @text.length end
+  def [] i; @text[i] end
 
 protected
 
   def reload
-    buffer.mark_dirty
-    BufferManager.draw_screen
-    load_in_background
+    regen_text
+    buffer.mark_dirty if buffer
   end
   
   def regen_text
     @text = []
-    @labels = (LabelManager::LISTABLE_LABELS + LabelManager.user_labels).sort_by { |t| t.to_s }
+    @labels = LabelManager.listable_label_strings
 
-    counts = @labels.map do |t|
-      total = Index.num_results_for :label => t
-      unread = Index.num_results_for :labels => [t, :unread]
-      [t, total, unread]
+    counts = @labels.map do |string|
+      label = LabelManager.label_for string
+      total = Index.num_results_for :label => label
+      unread = Index.num_results_for :labels => [label, :unread]
+      [label, string, total, unread]
     end      
 
-    width = @labels.map { |t| t.to_s.length }.max
+    width = @labels.max_of { |string| string.length }
 
-    counts.map_with_index do |(t, total, unread), i|
-      if total == 0 && !LabelManager::LISTABLE_LABELS.include?(t)
-        Redwood::log "no hits for label #{t}, deleting"
+    counts.map do |label, string, total, unread|
+      if total == 0 && !LabelManager::RESERVED_LABELS.include?(label)
+        Redwood::log "no hits for label #{label}, deleting"
         LabelManager.delete t
-        @labels.delete t
         next
       end
 
-      label =
-        case t
-        when *LabelManager::LISTABLE_LABELS
-          t.to_s.ucfirst
-        else
-          t.to_s
-        end
       @text << [[(unread == 0 ? :labellist_old_color : :labellist_new_color),
-          sprintf("%#{width + 1}s %5d %s, %5d unread", label, total, total == 1 ? " message" : "messages", unread)]]
+          sprintf("%#{width + 1}s %5d %s, %5d unread", string, total, total == 1 ? " message" : "messages", unread)]]
       yield i if block_given?
     end.compact
-
-    buffer.mark_dirty
   end
 
-  def view_results
-    label = @labels[curpos]
-    if label == :inbox
-      BufferManager.raise_to_front InboxMode.instance.buffer
-    else
-      b = BufferManager.spawn_unless_exists("All threads with label '#{label}'") do
-        mode = LabelSearchResultsMode.new [label]
-      end
-      b.mode.load_threads :num => b.content_height
-    end
+  def select_label
+    @value, string = @labels[curpos]
+    @done = true if @value
   end
 end
 
index 73c9ddaf0c59dc8fb4c79914aac53cd905005b66..11e463c5bbe7295e2b248ff3d38e6573eff170e3 100644 (file)
@@ -32,7 +32,7 @@ class ThreadIndexMode < LineCursorMode
     @mutex = Mutex.new
     @load_thread = nil
     @load_thread_opts = load_thread_opts
-    @hidden_labels = hidden_labels + LabelManager::HIDDEN_LABELS
+    @hidden_labels = hidden_labels + LabelManager::HIDDEN_RESERVED_LABELS
     @date_width = DATE_WIDTH
     @from_width = FROM_WIDTH
     @size_width = nil
@@ -127,7 +127,7 @@ class ThreadIndexMode < LineCursorMode
   def update
     ## let's see you do THIS in python
     @threads = @ts.threads.select { |t| !@hidden_threads[t] }.sort_by { |t| t.date }.reverse
-    @size_width = (@threads.map { |t| t.size }.max || 0).num_digits
+    @size_width = (@threads.max_of { |t| t.size } || 0).num_digits
     regen_text
   end
 
index bdd1228882e0bc552cd4b855961d1b6864516795..ba63638873dee463648394cfffca1df53adabec9 100644 (file)
@@ -74,7 +74,7 @@ class TextField
       @value = nil
       return false
     when Ncurses::KEY_TAB # completion
-      break unless @completion_block
+      return true unless @completion_block
       if @completions.empty?
         v = get_cur_value
         c = @completion_block.call v
index 2f89a40b218c52b3d9fa362641d1ab5915d1153c..bdb59e41d8d09954e81ef74453e50c4006836c91 100644 (file)
@@ -288,6 +288,10 @@ module Enumerable
     end
     prefix
   end
+
+  def max_of
+    map { |e| yield e }.max
+  end
 end
 
 class Array