]> git.cworth.org Git - sup/blobdiff - lib/sup/buffer.rb
hook system
[sup] / lib / sup / buffer.rb
index dc3b44e6e385cfe1bf7709c347542d53a95c402e..467675a92de35f8cd278c5953901d6681dc945ee 100644 (file)
@@ -1,6 +1,8 @@
 require 'etc'
 require 'thread'
+require 'ncurses'
 
+if defined? Ncurses
 module Ncurses
   def rows
     lame, lamer = [], []
@@ -14,6 +16,12 @@ module Ncurses
     lamer.first
   end
 
+  def curx
+    lame, lamer = [], []
+    stdscr.getyx lame, lamer
+    lamer.first
+  end
+
   def mutex; @mutex ||= Mutex.new; end
   def sync &b; mutex.synchronize(&b); end
 
@@ -27,12 +35,16 @@ module Ncurses
     end
   end
 
-  module_function :rows, :cols, :nonblocking_getch, :mutex, :sync
+  module_function :rows, :cols, :curx, :nonblocking_getch, :mutex, :sync
+
+  remove_const :KEY_ENTER
+  remove_const :KEY_CANCEL
 
   KEY_ENTER = 10
-  KEY_CANCEL = ?\a # ctrl-g
+  KEY_CANCEL = 7 # ctrl-g
   KEY_TAB = 9
 end
+end
 
 module Redwood
 
@@ -332,6 +344,24 @@ class BufferManager
     end
   end
 
+  def ask_many_with_completions domain, question, completions, default=nil, sep=" "
+    ask domain, question, default do |partial|
+      prefix, target = 
+        case partial#.gsub(/#{sep}+/, sep)
+        when /^\s*$/
+          ["", ""]
+        when /^(.+#{sep})$/
+          [$1, ""]
+        when /^(.*#{sep})?(.+?)$/
+          [$1 || "", $2]
+        else
+          raise "william screwed up completion: #{partial.inspect}"
+        end
+
+      completions.select { |x| x =~ /^#{target}/i }.map { |x| [prefix + x, x] }
+    end
+  end
+
   ## returns an ARRAY of filenames!
   def ask_for_filenames domain, question, default=nil
     answer = ask domain, question, default do |s|
@@ -368,6 +398,42 @@ class BufferManager
     answer || []
   end
 
+  ## returns an array of labels
+  def ask_for_labels domain, question, default_labels, forbidden_labels=[]
+    default_labels = default_labels - forbidden_labels - LabelManager::RESERVED_LABELS
+    default = default_labels.join(" ")
+    default += " " unless default.empty?
+
+    applyable_labels = (LabelManager.applyable_labels - forbidden_labels).map { |l| LabelManager.string_for l }.sort_by { |s| s.downcase }
+
+    answer = ask_many_with_completions domain, question, applyable_labels, default
+
+    return unless answer
+
+    user_labels = answer.split(/\s+/).map { |l| l.intern }
+    user_labels.each do |l|
+      if forbidden_labels.include?(l) || LabelManager::RESERVED_LABELS.include?(l)
+        BufferManager.flash "'#{l}' is a reserved label!"
+        return
+      end
+    end
+    user_labels
+  end
+
+  def ask_for_contacts domain, question, default_contacts=[]
+    default = default_contacts.map { |s| s.to_s }.join(" ")
+    default += " " unless default.empty?
+
+    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*/
+
+    if answer
+      answer.split_on_commas.map { |x| ContactManager.contact_for(x.downcase) || PersonManager.person_for(x) }
+    end
+  end
+
+
   def ask domain, question, default=nil, &block
     raise "impossible!" if @asking
     @asking = true
@@ -409,7 +475,6 @@ class BufferManager
         tf.position_cursor
       elsif tf.roll_completions?
         completion_buf.mode.roll
-
         draw_screen :skip_minibuf => true
         tf.position_cursor
       end