]> git.cworth.org Git - sup/commitdiff
to, cc, bcc prompting and editing, with tab completion
authorwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Mon, 6 Aug 2007 00:05:54 +0000 (00:05 +0000)
committerwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Mon, 6 Aug 2007 00:05:54 +0000 (00:05 +0000)
git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@516 5c8cc53c-5e98-4d25-b20a-d8db53a31250

bin/sup
lib/sup.rb
lib/sup/buffer.rb
lib/sup/contact.rb
lib/sup/index.rb
lib/sup/modes/edit-message-mode.rb
lib/sup/textfield.rb

diff --git a/bin/sup b/bin/sup
index 59785c98d9192c9975807af9587a544826edbfef..cb4542ac340bb015fd3d519c40dc9a6dd808612a 100644 (file)
--- a/bin/sup
+++ b/bin/sup
@@ -233,9 +233,13 @@ begin
         end
 
       when :compose
-        mode = ComposeMode.new
+        to = BufferManager.ask_for_contacts(:people, "To: ") or next
+        cc = BufferManager.ask_for_contacts(:people, "Cc: ") or next if $config[:ask_for_cc]
+        bcc = BufferManager.ask_for_contacts(:people, "Bcc: ") or next if $config[:ask_for_bcc]
+
+        mode = ComposeMode.new :to => to, :cc => cc, :bcc => bcc
         bm.spawn "New Message", mode
-        mode.edit
+        mode.edit_message
       when :poll
         #          bm.raise_to_front PollManager.buffer
         reporting_thread { PollManager.poll }
index 2eb2998cb75d4ca121ca68de5f00a9b174beffa7..a6086bca4085b296c90d8f69701d1577d5603dc0 100644 (file)
@@ -193,6 +193,8 @@ else
     :editor => ENV["EDITOR"] || "/usr/bin/vim -f -c 'setlocal spell spelllang=en_us' -c 'set filetype=mail'",
     :thread_by_subject => false,
     :edit_signature => false,
+    :ask_for_cc => true,
+    :ask_for_bcc => false
   }
   begin
     FileUtils.mkdir_p Redwood::BASE_DIR
index 91c0869d0e63fe4bd1939c941ef47c7b802c2501..40bd6fcc9bd5b07de1496b48c9837e4aba0fcd6c 100644 (file)
@@ -39,7 +39,7 @@ module Ncurses
   remove_const :KEY_CANCEL
 
   KEY_ENTER = 10
-  KEY_CANCEL = ?\a # ctrl-g
+  KEY_CANCEL = 7 # ctrl-g
   KEY_TAB = 9
 end
 
@@ -344,7 +344,7 @@ class BufferManager
   def ask_many_with_completions domain, question, completions, default=nil, sep=" "
     ask domain, question, default do |partial|
       prefix, target = 
-        case partial.gsub(/#{sep}+/, sep)
+        case partial#.gsub(/#{sep}+/, sep)
         when /^\s*$/
           ["", ""]
         when /^(.+#{sep})$/
@@ -403,7 +403,7 @@ class BufferManager
 
     applyable_labels = (LabelManager.applyable_labels - forbidden_labels).map { |l| LabelManager.string_for l }.sort_by { |s| s.downcase }
 
-    answer = BufferManager.ask_many_with_completions domain, question, applyable_labels, default
+    answer = ask_many_with_completions domain, question, applyable_labels, default
 
     return unless answer
 
@@ -417,6 +417,19 @@ class BufferManager
     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
index 07067258a7e9cb92f274e944bb1b397c63c33fe2..94d076d0a8411a61273615bf24b107e740c8bb61 100644 (file)
@@ -35,7 +35,7 @@ class ContactManager
       @a2p.delete aalias
     end
   end    
-  def person_with aalias; @a2p[aalias]; end
+  def contact_for aalias; @a2p[aalias]; end
   def alias_for person; @p2a[person]; end
   def is_contact? person; @p2a.member? person; end
   def save
index 16528a4ba9348ed0e3bcf2b1f25727ed6ccc56be..694800d69a0e436886f706bc356701f20f86ebf7 100644 (file)
@@ -362,7 +362,7 @@ protected
   def parse_user_query_string str
     str2 = str.gsub(/(to|from):(\S+)/) do
       field, name = $1, $2
-      if(p = ContactManager.person_with(name))
+      if(p = ContactManager.contact_for(name))
         [field, p.email]
       else
         [field, name]
index 87fce0e23eed1924d54ddccd46e0c711127bc7a3..22fedc732835979de64550b8fb2c7d724594af46 100644 (file)
@@ -18,7 +18,8 @@ class EditMessageMode < LineCursorMode
 
   register_keymap do |k|
     k.add :send_message, "Send message", 'y'
-    k.add :edit, "Edit message", 'e', :enter
+    k.add :edit_field, "Edit field", 'e'
+    k.add :edit_message, "Edit message", :enter
     k.add :save_as_draft, "Save as draft", 'P'
     k.add :attach_file, "Attach a file", 'a'
     k.add :delete_attachment, "Delete an attachment", 'd'
@@ -26,10 +27,12 @@ class EditMessageMode < LineCursorMode
 
   def initialize opts={}
     @header = opts.delete(:header) || {} 
+    @header_lines = []
+
     @body = opts.delete(:body) || []
     @body += sig_lines if $config[:edit_signature]
+
     @attachments = []
-    @attachment_lines = {}
     @message_id = "<#{Time.now.to_i}-sup-#{rand 10000}@#{Socket.gethostname}>"
     @edited = false
 
@@ -43,9 +46,36 @@ class EditMessageMode < LineCursorMode
   ## a hook
   def handle_new_text header, body; end
 
-  def edit
+  def edit_field
+    if curpos >= @header_lines.length
+      edit_message
+    else
+      case(field = @header_lines[curpos])
+      when "Subject"
+        text = BufferManager.ask :subject, "Subject: ", @header[field]
+        @header[field] = parse_header field, text if text
+      else
+        default =
+          case field
+          when *MULTI_HEADERS
+            @header[field].join(", ")
+          else
+            @header[field]
+          end
+
+        contacts = BufferManager.ask_for_contacts :people, "#{field}: ", default
+        if contacts
+          text = contacts.map { |s| s.longname }.join(", ")
+          @header[field] = parse_header field, text
+        end
+      end
+      update
+    end
+  end
+
+  def edit_message
     @file = Tempfile.new "sup.#{self.class.name.gsub(/.*::/, '').camel_to_hyphy}"
-    @file.puts header_lines(@header - NON_EDITABLE_HEADERS)
+    @file.puts format_headers(@header - NON_EDITABLE_HEADERS).first
     @file.puts
     @file.puts @body
     @file.close
@@ -90,8 +120,8 @@ protected
   end
 
   def regen_text
-    top = header_lines(@header - NON_EDITABLE_HEADERS) + [""]
-    @text = top + @body
+    header, @header_lines = format_headers(@header - NON_EDITABLE_HEADERS) + [""]
+    @text = header + [""] + @body
     @text += sig_lines unless $config[:edit_signature]
 
     unless @attachments.empty?
@@ -107,24 +137,30 @@ protected
       body = f.readlines
 
       header.delete_if { |k, v| NON_EDITABLE_HEADERS.member? k }
-      header.each do |k, v|
-        next unless MULTI_HEADERS.include?(k) && !v.empty?
-        header[k] = v.split_on_commas.map do |name|
-          (p = ContactManager.person_with(name)) && p.full_address || name
-        end
-      end
+      header.each { |k, v| header[k] = parse_header k, v }
 
       [header, body]
     end
   end
 
-  def header_lines header
-    force_headers = FORCE_HEADERS.map { |h| make_lines "#{h}:", header[h] }
-    other_headers = (header.keys - FORCE_HEADERS).map do |h|
-      make_lines "#{h}:", header[h]
+  def parse_header k, v
+    if MULTI_HEADERS.include?(k)
+      v.split_on_commas.map do |name|
+        (p = ContactManager.contact_for(name)) && p.full_address || name
+      end
+    else
+      v
     end
+  end
 
-    (force_headers + other_headers).flatten.compact
+  def format_headers header
+    header_lines = []
+    headers = (FORCE_HEADERS + (header.keys - FORCE_HEADERS)).map do |h|
+      lines = make_lines "#{h}:", header[h]
+      lines.length.times { header_lines << h }
+      lines
+    end.flatten.compact
+    [headers, header_lines]
   end
 
   def make_lines header, things
index f147785915bc96ab169f476248f3b105a295255d..7fe020ccc355c888ce8bbf7d0354927a195175c5 100644 (file)
@@ -103,10 +103,12 @@ class TextField
         Ncurses::Form::REQ_NEXT_CHAR
       when Ncurses::KEY_BACKSPACE
         Ncurses::Form::REQ_DEL_PREV
-      when ?\001
+      when 1 #ctrl-a
         Ncurses::Form::REQ_BEG_FIELD
-      when ?\005
+      when 5 #ctrl-e
         Ncurses::Form::REQ_END_FIELD
+      when 11 # ctrl-k
+        Ncurses::Form::REQ_CLR_EOF
       when Ncurses::KEY_UP
         @i ||= @history.size
         @history[@i] = get_cursed_value