]> git.cworth.org Git - sup/blobdiff - lib/sup/buffer.rb
maybe fix disappearign status lines when a #say and an #ask are both active
[sup] / lib / sup / buffer.rb
index 467675a92de35f8cd278c5953901d6681dc945ee..b2106718f21a57ec3ad0b27d39c716dedf90e2d7 100644 (file)
@@ -133,6 +133,11 @@ class BufferManager
 
   attr_reader :focus_buf
 
+  ## we have to define the key used to continue in-buffer search here, because
+  ## it has special semantics that BufferManager deals with---current searches
+  ## are canceled by any keypress except this one.
+  CONTINUE_IN_BUFFER_SEARCH_KEY = "n"
+
   def initialize
     @name_map = {}
     @buffers = []
@@ -150,7 +155,8 @@ class BufferManager
   def buffers; @name_map.to_a; end
 
   def focus_on buf
-    raise ArgumentError, "buffer not on stack: #{buf.inspect}" unless @buffers.member? buf
+    return unless @buffers.member? buf
+
     return if buf == @focus_buf 
     @focus_buf.blur if @focus_buf
     @focus_buf = buf
@@ -158,7 +164,7 @@ class BufferManager
   end
 
   def raise_to_front buf
-    raise ArgumentError, "buffer not on stack: #{buf.inspect}" unless @buffers.member? buf
+    return unless @buffers.member? buf
 
     @buffers.delete buf
     if @buffers.length > 0 && @buffers.last.force_to_top?
@@ -190,7 +196,13 @@ class BufferManager
   end
 
   def handle_input c
-    @focus_buf && @focus_buf.mode.handle_input(c)
+    if @focus_buf
+      if @focus_buf.mode.in_search? && c != CONTINUE_IN_BUFFER_SEARCH_KEY[0]
+        @focus_buf.mode.cancel_search!
+        @focus_buf.mark_dirty
+      end
+      @focus_buf.mode.handle_input c
+    end
   end
 
   def exists? n; @name_map.member? n; end
@@ -247,11 +259,12 @@ class BufferManager
   def spawn_unless_exists title, opts={}
     if @name_map.member? title
       raise_to_front @name_map[title] unless opts[:hidden]
+      nil
     else
       mode = yield
       spawn title, mode, opts
+      @name_map[title]
     end
-    @name_map[title]
   end
 
   def spawn title, mode, opts={}
@@ -334,25 +347,25 @@ class BufferManager
       ## TODO: something intelligent here
       ## for now I will simply prohibit killing the inbox buffer.
     else
-      raise_to_front @buffers.last
+      last = @buffers.last
+      @focus_buf ||= last
+      raise_to_front last
     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.downcase, x] }
+      completions.select { |x| x =~ /^#{s}/i }.map { |x| [x, x] }
     end
   end
 
-  def ask_many_with_completions domain, question, completions, default=nil, sep=" "
+  def ask_many_with_completions domain, question, completions, default=nil
     ask domain, question, default do |partial|
       prefix, target = 
-        case partial#.gsub(/#{sep}+/, sep)
+        case partial
         when /^\s*$/
           ["", ""]
-        when /^(.+#{sep})$/
-          [$1, ""]
-        when /^(.*#{sep})?(.+?)$/
+        when /^(.*\s+)?(.*?)$/
           [$1 || "", $2]
         else
           raise "william screwed up completion: #{partial.inspect}"
@@ -362,8 +375,18 @@ class BufferManager
     end
   end
 
-  ## returns an ARRAY of filenames!
-  def ask_for_filenames domain, question, default=nil
+  def ask_many_emails_with_completions domain, question, completions, default=nil
+    ask domain, question, default do |partial|
+      prefix, target = partial.split_on_commas_with_remainder
+      Redwood::log "before: prefix #{prefix.inspect}, target #{target.inspect}"
+      target ||= prefix.pop || ""
+      prefix = prefix.join(", ") + (prefix.empty? ? "" : ", ")
+      Redwood::log "after: prefix #{prefix.inspect}, target #{target.inspect}"
+      completions.select { |x| x =~ /^#{target}/i }.map { |x| [prefix + x, x] }
+    end
+  end
+
+  def ask_for_filename domain, question, default=nil
     answer = ask domain, question, default do |s|
       if s =~ /(~([^\s\/]*))/ # twiddle directory expansion
         full = $1
@@ -391,11 +414,11 @@ class BufferManager
         elsif File.directory?(answer)
           spawn_modal "file browser", FileBrowserMode.new(answer)
         else
-          [answer]
+          answer
         end
     end
 
-    answer || []
+    answer
   end
 
   ## returns an array of labels
@@ -423,10 +446,12 @@ class BufferManager
   def ask_for_contacts domain, question, default_contacts=[]
     default = default_contacts.map { |s| s.to_s }.join(" ")
     default += " " unless default.empty?
+    
+    recent = Index.load_contacts(AccountManager.user_emails, :num => 10).map { |c| [c.full_address, c.email] }
+    contacts = ContactManager.contacts.map { |c| [ContactManager.alias_for(c), c.full_address, c.email] }
 
-    all_contacts = ContactManager.contacts.map { |c| [ContactManager.alias_for(c), c.longname, c.email] }.flatten.uniq.sort
-
-    answer = BufferManager.ask_many_with_completions domain, question, all_contacts, default, /\s*,\s*/
+    completions = (recent + contacts).flatten.uniq.sort
+    answer = BufferManager.ask_many_emails_with_completions domain, question, completions, default
 
     if answer
       answer.split_on_commas.map { |x| ContactManager.contact_for(x.downcase) || PersonManager.person_for(x) }
@@ -450,7 +475,8 @@ class BufferManager
     Ncurses.sync do
       tf.activate question, default, &block
       @dirty = true
-      draw_screen :skip_minibuf => true, :sync => false
+      #draw_screen :skip_minibuf => true, :sync => false
+      draw_screen :sync => false
     end
 
     ret = nil