From: wmorgan Date: Sun, 8 Jul 2007 23:08:50 +0000 (+0000) Subject: L now prompts for label rather than immediately spawning label-select-mode X-Git-Url: https://git.notmuchmail.org/git?a=commitdiff_plain;h=5b9e55388a0c261353073d0d88fcfb2ec1953a1b;p=sup L now prompts for label rather than immediately spawning label-select-mode git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@487 5c8cc53c-5e98-4d25-b20a-d8db53a31250 --- diff --git a/bin/sup b/bin/sup index 52de3fc..bc3af0f 100644 --- 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 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb index 5aa97ca..47a844a 100644 --- a/lib/sup/buffer.rb +++ b/lib/sup/buffer.rb @@ -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| diff --git a/lib/sup/keymap.rb b/lib/sup/keymap.rb index 64935d9..ce261ba 100644 --- a/lib/sup/keymap.rb +++ b/lib/sup/keymap.rb @@ -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 diff --git a/lib/sup/label.rb b/lib/sup/label.rb index 770f219..5d3dc4a 100644 --- a/lib/sup/label.rb +++ b/lib/sup/label.rb @@ -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 diff --git a/lib/sup/modes/buffer-list-mode.rb b/lib/sup/modes/buffer-list-mode.rb index a830b8e..69d367f 100644 --- a/lib/sup/modes/buffer-list-mode.rb +++ b/lib/sup/modes/buffer-list-mode.rb @@ -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 diff --git a/lib/sup/modes/completion-mode.rb b/lib/sup/modes/completion-mode.rb index e96b935..638c64e 100644 --- a/lib/sup/modes/completion-mode.rb +++ b/lib/sup/modes/completion-mode.rb @@ -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| diff --git a/lib/sup/modes/file-browser-mode.rb b/lib/sup/modes/file-browser-mode.rb index d9af957..0105d73 100644 --- a/lib/sup/modes/file-browser-mode.rb +++ b/lib/sup/modes/file-browser-mode.rb @@ -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 diff --git a/lib/sup/modes/label-list-mode.rb b/lib/sup/modes/label-list-mode.rb index 104bf86..cd7f9f5 100644 --- a/lib/sup/modes/label-list-mode.rb +++ b/lib/sup/modes/label-list-mode.rb @@ -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 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb index 73c9dda..11e463c 100644 --- a/lib/sup/modes/thread-index-mode.rb +++ b/lib/sup/modes/thread-index-mode.rb @@ -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 diff --git a/lib/sup/textfield.rb b/lib/sup/textfield.rb index bdd1228..ba63638 100644 --- a/lib/sup/textfield.rb +++ b/lib/sup/textfield.rb @@ -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 diff --git a/lib/sup/util.rb b/lib/sup/util.rb index 2f89a40..bdb59e4 100644 --- a/lib/sup/util.rb +++ b/lib/sup/util.rb @@ -288,6 +288,10 @@ module Enumerable end prefix end + + def max_of + map { |e| yield e }.max + end end class Array