sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 54d1a882de37495473c336ed286f6d3b8bd6ee1b
parent d5274cfcfc01382b00f5f86b26d9eab45b745deb
Author: Sascha Silbe <sascha-pgp@silbe.org>
Date:   Tue, 18 Jan 2011 18:58:00 +0100

fix EOL spaces

Trailing spaces can make dealing with patches a pain for some developers.

Signed-off-by: Sascha Silbe 

Diffstat:
M History.txt | 2 +-
M bin/sup-add | 4 ++--
M bin/sup-config | 4 ++--
M bin/sup-sync-back | 2 +-
M doc/Hooks.txt | 3 +--
M lib/sup.rb | 6 +++---
M lib/sup/colormap.rb | 4 ++--
M lib/sup/crypto.rb | 28 ++++++++++++++--------------
M lib/sup/draft.rb | 2 +-
M lib/sup/horizontal-selector.rb | 2 +-
M lib/sup/label.rb | 2 +-
M lib/sup/message-chunks.rb | 2 +-
M lib/sup/message.rb | 2 +-
M lib/sup/modes/compose-mode.rb | 2 +-
M lib/sup/modes/contact-list-mode.rb | 4 ++--
M lib/sup/modes/edit-message-mode.rb | 18 +++++++++---------
M lib/sup/modes/file-browser-mode.rb | 4 ++--
M lib/sup/modes/forward-mode.rb | 8 ++++----
M lib/sup/modes/line-cursor-mode.rb | 2 +-
M lib/sup/modes/reply-mode.rb | 2 +-
M lib/sup/modes/resume-mode.rb | 2 +-
M lib/sup/modes/scroll-mode.rb | 2 +-
M lib/sup/modes/text-mode.rb | 2 +-
M lib/sup/modes/thread-index-mode.rb | 26 +++++++++++++-------------
M lib/sup/modes/thread-view-mode.rb | 18 +++++++++---------
M lib/sup/person.rb | 2 +-
M lib/sup/poll.rb | 2 +-
M lib/sup/rfc2047.rb | 2 +-
M lib/sup/textfield.rb | 2 +-
M lib/sup/thread.rb | 2 +-
M lib/sup/util.rb | 8 ++++----
M test/dummy_source.rb | 8 ++++----
M test/test_header_parsing.rb | 2 +-
M test/test_message.rb | 50 +++++++++++++++++++++++++-------------------------
34 files changed, 115 insertions(+), 116 deletions(-)
diff --git a/History.txt b/History.txt
@@ -199,7 +199,7 @@
 * doc/UserGuide.txt
 
 == 0.0.4 / 2007-01-03
- 
+
 * Bugfixes, primarily for threaded networking.
 
 == 0.0.3 / 2007-01-02
diff --git a/bin/sup-add b/bin/sup-add
@@ -94,7 +94,7 @@ begin
 
     parsed_uri = URI(uri)
 
-    source = 
+    source =
       case parsed_uri.scheme
       when "maildir"
         Redwood::Maildir.new uri, !$opts[:unusual], $opts[:archive], nil, labels
@@ -103,7 +103,7 @@ begin
       when nil
         Trollop::die "Sources must be specified with an URI"
       else
-        Trollop::die "Unknown source type #{parsed_uri.scheme.inspect}"      
+        Trollop::die "Unknown source type #{parsed_uri.scheme.inspect}"
       end
     say "Adding #{source}..."
     Redwood::SourceManager.add_source source
diff --git a/bin/sup-config b/bin/sup-config
@@ -103,7 +103,7 @@ def add_source
     system cmd
     if $?.success?
       say "Great! Added!"
-      break 
+      break
     else
       say "Rats, that failed. You may have to do it manually."
       if axe_yes("Try again?") then next else return end
@@ -210,7 +210,7 @@ if axe_yes "Run sup-sync to import all messages now?"
     system cmd
     if $?.success?
       say "Great! It worked!"
-      break 
+      break
     else
       say "Rats, that failed. You may have to do it manually."
       if axe_yes("Try again?") then next else break end
diff --git a/bin/sup-sync-back b/bin/sup-sync-back
@@ -71,7 +71,7 @@ index.lock_interactively or exit
 
 deleted_fp, spam_fp = nil
 unless opts[:dry_run]
-  deleted_fp = File.open(opts[:move_deleted], "a") if opts[:move_deleted] 
+  deleted_fp = File.open(opts[:move_deleted], "a") if opts[:move_deleted]
   spam_fp = File.open(opts[:move_spam], "a") if opts[:move_spam]
 end
 
diff --git a/doc/Hooks.txt b/doc/Hooks.txt
@@ -71,4 +71,4 @@ after-poll:
   ## kills the background task after the first poll
   @bgtask_pid = get 'bgtask_pid'
   Process.kill("TERM", @bgtask_pid) unless @bgtask_pid == nil
-  set 'bgtask_pid' nil
-\ No newline at end of file
+  set 'bgtask_pid' nil
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -197,8 +197,8 @@ Until this is corrected, messages from these sources cannot be viewed,
 and new messages will not be detected. Luckily, this is easy to correct!
 
 #{desynced_sources.map do |s|
-  "Source: " + s.to_s + 
-   "\n Error: " + s.error.message.wrap(70).join("\n        ") + 
+  "Source: " + s.to_s +
+   "\n Error: " + s.error.message.wrap(70).join("\n        ") +
    "\n   Fix: sup-sync --changed #{s.to_s}"
   end}
 EOM
@@ -248,7 +248,7 @@ EOS
       require 'socket'
       name = Etc.getpwnam(ENV["USER"]).gecos.split(/,/).first rescue nil
       name ||= ENV["USER"]
-      email = ENV["USER"] + "@" + 
+      email = ENV["USER"] + "@" +
         begin
           Socket.gethostbyname(Socket.gethostname).first
         rescue SocketError
diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
@@ -65,7 +65,7 @@ class Colormap
     :modified_buffer => { :fg => "yellow", :bg => "default", :attrs => ["bold"] },
     :date => { :fg => "white", :bg => "default"},
   }
-  
+
   def initialize
     raise "only one instance can be created" if @@instance
     @@instance = self
@@ -115,7 +115,7 @@ class Colormap
         Curses::COLOR_BLACK
       end
 
-    hbg = 
+    hbg =
       case bg
       when Curses::COLOR_CYAN
         Curses::COLOR_YELLOW
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
@@ -31,7 +31,7 @@ EOS
   HookManager.register "sig-output", <<EOS
 Runs when the signature output is being generated, allowing you to
 add extra information to your signatures if you want.
-  
+
 Variables:
 signature: the signature object (class is GPGME::Signature)
 from_key: the key that generated the signature (class is GPGME::Key)
@@ -58,7 +58,7 @@ EOS
 
     gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
     gpg_opts.merge(gen_sign_user_opts(from))
-    gpg_opts = HookManager.run("gpg-options", 
+    gpg_opts = HookManager.run("gpg-options",
                                {:operation => "sign", :options => gpg_opts}) || gpg_opts
 
     begin
@@ -82,10 +82,10 @@ EOS
 
     gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
     if sign
-      gpg_opts.merge(gen_sign_user_opts(from)) 
+      gpg_opts.merge(gen_sign_user_opts(from))
       gpg_opts.merge({:sign => true})
     end
-    gpg_opts = HookManager.run("gpg-options", 
+    gpg_opts = HookManager.run("gpg-options",
                                {:operation => "encrypt", :options => gpg_opts}) || gpg_opts
     recipients = to + [from]
 
@@ -132,7 +132,7 @@ EOS
 
       err_code = GPGME::gpgme_err_code(signature.status)
       if err_code == GPGME::GPG_ERR_BAD_SIGNATURE
-        valid = false 
+        valid = false
       elsif err_code != GPGME::GPG_ERR_NO_ERROR
         valid = false
         unknown = true
@@ -158,9 +158,9 @@ EOS
     return unknown_status(cant_find_gpgme) unless @gpgme_present
 
     gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP}
-    gpg_opts = HookManager.run("gpg-options", 
+    gpg_opts = HookManager.run("gpg-options",
                                {:operation => "verify", :options => gpg_opts}) || gpg_opts
-    ctx = GPGME::Ctx.new(gpg_opts) 
+    ctx = GPGME::Ctx.new(gpg_opts)
     sig_data = GPGME::Data.from_str signature.decode
     if detached
       signed_text_data = GPGME::Data.from_str(format_payload(payload))
@@ -172,7 +172,7 @@ EOS
     begin
       ctx.verify(sig_data, signed_text_data, plain_data)
     rescue GPGME::Error => exc
-      return unknown_status exc.message 
+      return unknown_status exc.message
     end
     self.verified_ok? ctx.verify_result
   end
@@ -182,9 +182,9 @@ EOS
     return unknown_status(cant_find_gpgme) unless @gpgme_present
 
     gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP}
-    gpg_opts = HookManager.run("gpg-options", 
+    gpg_opts = HookManager.run("gpg-options",
                                {:operation => "decrypt", :options => gpg_opts}) || gpg_opts
-    ctx = GPGME::Ctx.new(gpg_opts) 
+    ctx = GPGME::Ctx.new(gpg_opts)
     cipher_data = GPGME::Data.from_str(format_payload(payload))
     plain_data = GPGME::Data.empty
     begin
@@ -216,7 +216,7 @@ EOS
       msg.body = output
     else
       # It appears that some clients use Windows new lines - CRLF - but RMail
-      # splits the body and header on "\n\n". So to allow the parse below to 
+      # splits the body and header on "\n\n". So to allow the parse below to
       # succeed, we will convert the newlines to what RMail expects
       output = output.gsub(/\r\n/, "\n")
       # This is gross. This decrypted payload could very well be a multipart
@@ -271,18 +271,18 @@ private
     begin
       from_key = ctx.get_key(signature.fingerprint)
       first_sig = signature.to_s.sub(/from [0-9A-F]{16} /, 'from "') + '"'
-    rescue EOFError 
+    rescue EOFError
       from_key = nil
       first_sig = "No public key available for #{signature.fingerprint}"
     end
 
     time_line = "Signature made " + signature.timestamp.strftime("%a %d %b %Y %H:%M:%S %Z") +
-                " using " + key_type(from_key, signature.fingerprint) + 
+                " using " + key_type(from_key, signature.fingerprint) +
                 "key ID " + signature.fingerprint[-8..-1]
     output_lines = [time_line, first_sig]
 
     trusted = false
-    if from_key 
+    if from_key
       # first list all the uids
       if from_key.uids.length > 1
         aka_list = from_key.uids[1..-1]
diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
@@ -70,7 +70,7 @@ class DraftLoader < Source
   def load_header offset
     File.open(fn_for_offset(offset)) { |f| parse_raw_email_header f }
   end
-  
+
   def load_message offset
     File.open fn_for_offset(offset) do |f|
       RMail::Mailbox::MBoxReader.new(f).each_message do |input|
diff --git a/lib/sup/horizontal-selector.rb b/lib/sup/horizontal-selector.rb
@@ -24,7 +24,7 @@ class HorizontalSelector
         "#{@label} "
       end
 
-    [[@base_color, label]] + 
+    [[@base_color, label]] +
       (0 ... @labels.length).inject([]) do |array, i|
         array + [
           if i == @selection
diff --git a/lib/sup/label.rb b/lib/sup/label.rb
@@ -12,7 +12,7 @@ class LabelManager
 
   def initialize fn
     @fn = fn
-    labels = 
+    labels =
       if File.exists? fn
         IO.readlines(fn).map { |x| x.chomp.intern }
       else
diff --git a/lib/sup/message-chunks.rb b/lib/sup/message-chunks.rb
@@ -198,7 +198,7 @@ EOS
     def initialize lines
       @lines = lines
     end
-    
+
     def inlineable?; @lines.length == 1 end
     def quotable?; true end
     def expandable?; !inlineable? end
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
@@ -503,7 +503,7 @@ private
         filename = Rfc2047.decode_to $encoding, filename
         # add this to the attachments list if its not a generated html
         # attachment (should we allow images with generated names?).
-        # Lowercase the filename because searches are easier that way 
+        # Lowercase the filename because searches are easier that way
         @attachments.push filename.downcase unless filename =~ /^sup-attachment-/
         add_label :attachment unless filename =~ /^sup-attachment-/
         content_type = (m.header.content_type || "application/unknown").downcase # sometimes RubyMail gives us nil
diff --git a/lib/sup/modes/compose-mode.rb b/lib/sup/modes/compose-mode.rb
@@ -26,7 +26,7 @@ class ComposeMode < EditMessageMode
     cc = opts[:cc] || (BufferManager.ask_for_contacts(:people, "Cc: ") or return if $config[:ask_for_cc])
     bcc = opts[:bcc] || (BufferManager.ask_for_contacts(:people, "Bcc: ") or return if $config[:ask_for_bcc])
     subj = opts[:subj] || (BufferManager.ask(:subject, "Subject: ") or return if $config[:ask_for_subject])
-    
+
     mode = ComposeMode.new :from => from, :to => to, :cc => cc, :bcc => bcc, :subj => subj
     BufferManager.spawn "New Message", mode
     mode.edit_message
diff --git a/lib/sup/modes/contact-list-mode.rb b/lib/sup/modes/contact-list-mode.rb
@@ -89,7 +89,7 @@ class ContactListMode < LineCursorMode
   def search
     p = @contacts[curpos] or return
     multi_search [p]
-  end    
+  end
 
   def reload
     @tags.drop_all_tags
@@ -114,7 +114,7 @@ class ContactListMode < LineCursorMode
       @contacts = (@user_contacts + recentc).sort_by { |p| p.sort_by_me }.uniq
     end
   end
-  
+
 protected
 
   def update
diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
@@ -88,7 +88,7 @@ EOS
   end
 
   def initialize opts={}
-    @header = opts.delete(:header) || {} 
+    @header = opts.delete(:header) || {}
     @header_lines = []
 
     @body = opts.delete(:body) || []
@@ -119,7 +119,7 @@ EOS
         HorizontalSelector.new "Crypto:", [:none] + CryptoManager::OUTGOING_MESSAGE_OPERATIONS.keys, ["None"] + CryptoManager::OUTGOING_MESSAGE_OPERATIONS.values
       end
     add_selector @crypto_selector if @crypto_selector
-    
+
     HookManager.run "before-edit", :header => @header, :body => @body
     if @crypto_selector
       HookManager.run "crypto-mode", :header => @header, :body => @body, :crypto_selector => @crypto_selector
@@ -130,7 +130,7 @@ EOS
   end
 
   def lines; @text.length + (@selectors.empty? ? 0 : (@selectors.length + DECORATION_LINES)) end
-  
+
   def [] i
     if @selectors.empty?
       @text[i]
@@ -270,7 +270,7 @@ protected
     header, @header_lines = format_headers(@header - NON_EDITABLE_HEADERS) + [""]
     @text = header + [""] + @body
     @text += sig_lines unless $config[:edit_signature]
-    
+
     @attachment_lines_offset = 0
 
     unless @attachments.empty?
@@ -339,7 +339,7 @@ protected
     return false if $config[:confirm_no_attachments] && mentions_attachments? && @attachments.size == 0 && !BufferManager.ask_yes_or_no("You haven't added any attachments. Really send?")#" stupid ruby-mode
     return false if $config[:confirm_top_posting] && top_posting? && !BufferManager.ask_yes_or_no("You're top-posting. That makes you a bad person. Really send?") #" stupid ruby-mode
 
-    from_email = 
+    from_email =
       if @header["From"] =~ /<?(\S+@(\S+?))>?$/
         $1
       else
@@ -393,7 +393,7 @@ protected
       body_m = m
       body_m.header["Content-Disposition"] = "inline"
       m = RMail::Message.new
-      
+
       m.add_part body_m
       @attachments.each { |a| m.add_part a }
     end
@@ -414,7 +414,7 @@ protected
     ## finally, set the top-level headers
     @header.each do |k, v|
       next if v.nil? || v.empty?
-      m.header[k] = 
+      m.header[k] =
         case v
         when String
           k.match(/subject/i) ? mime_encode_subject(v) : mime_encode_address(v)
@@ -454,7 +454,7 @@ EOS
     f.puts
     f.puts sanitize_body(@body.join("\n"))
     f.puts sig_lines if full unless $config[:edit_signature]
-  end  
+  end
 
 protected
 
@@ -514,7 +514,7 @@ private
 
     ## no hook, do default signature generation based on config.yaml
     return [] unless from_email
-    sigfn = (AccountManager.account_for(from_email) || 
+    sigfn = (AccountManager.account_for(from_email) ||
              AccountManager.default_account).signature
 
     if sigfn && File.exists?(sigfn)
diff --git a/lib/sup/modes/file-browser-mode.rb b/lib/sup/modes/file-browser-mode.rb
@@ -29,7 +29,7 @@ class FileBrowserMode < LineCursorMode
   def [] i; @text[i]; end
 
 protected
-  
+
   def back
     return if @dirs.size == 1
     @dirs.pop
@@ -75,7 +75,7 @@ protected
   end
 
   def regen_text
-    @files = 
+    @files =
       begin
         cwd.entries.sort_by do |f|
           [f.directory? ? 0 : 1, f.basename.to_s]
diff --git a/lib/sup/modes/forward-mode.rb b/lib/sup/modes/forward-mode.rb
@@ -7,7 +7,7 @@ class ForwardMode < EditMessageMode
       "From" => AccountManager.default_account.full_address,
     }
 
-    header["Subject"] = 
+    header["Subject"] =
       if opts[:message]
         "Fwd: " + opts[:message].subj
       elsif opts[:attachments]
@@ -20,7 +20,7 @@ class ForwardMode < EditMessageMode
 
     body =
       if opts[:message]
-        forward_body_lines(opts[:message]) 
+        forward_body_lines(opts[:message])
       elsif opts[:attachments]
         ["Note: #{opts[:attachments].size.pluralize 'attachment'}."]
       end
@@ -32,7 +32,7 @@ class ForwardMode < EditMessageMode
     to = opts[:to] || (BufferManager.ask_for_contacts(:people, "To: ") or return if ($config[:ask_for_to] != false))
     cc = opts[:cc] || (BufferManager.ask_for_contacts(:people, "Cc: ") or return if $config[:ask_for_cc])
     bcc = opts[:bcc] || (BufferManager.ask_for_contacts(:people, "Bcc: ") or return if $config[:ask_for_bcc])
-    
+
     attachment_hash = {}
     attachments = opts[:attachments] || []
 
@@ -64,7 +64,7 @@ class ForwardMode < EditMessageMode
 protected
 
   def forward_body_lines m
-    ["--- Begin forwarded message from #{m.from.mediumname} ---"] + 
+    ["--- Begin forwarded message from #{m.from.mediumname} ---"] +
       m.quotable_header_lines + [""] + m.quotable_body_lines +
       ["--- End forwarded message ---"]
   end
diff --git a/lib/sup/modes/line-cursor-mode.rb b/lib/sup/modes/line-cursor-mode.rb
@@ -78,7 +78,7 @@ protected
   end
 
   def search_start_line; @curpos end
- 
+
   def line_down # overwrite scrollmode
     super
     call_load_more_callbacks([topline + buffer.content_height - lines, 10].max) if topline + buffer.content_height > lines
diff --git a/lib/sup/modes/reply-mode.rb b/lib/sup/modes/reply-mode.rb
@@ -93,7 +93,7 @@ EOS
     ## to. if it's a list message, then the list address is. otherwise,
     ## the cc contains a recipient.
     useful_recipient = !(cc.empty? || @m.is_list_message?)
-    
+
     @headers = {}
     @headers[:recipient] = {
       "To" => cc.map { |p| p.full_address },
diff --git a/lib/sup/modes/resume-mode.rb b/lib/sup/modes/resume-mode.rb
@@ -35,7 +35,7 @@ class ResumeMode < EditMessageMode
 
   def send_message
     if super
-      DraftManager.discard @m 
+      DraftManager.discard @m
       @safe = true
     end
   end
diff --git a/lib/sup/modes/scroll-mode.rb b/lib/sup/modes/scroll-mode.rb
@@ -187,7 +187,7 @@ protected
       if in_search?
         ## seems like there ought to be a better way of doing this
         array = []
-        s.each do |color, text| 
+        s.each do |color, text|
           if text =~ regex
             array += matching_text_array text, regex, color
           else
diff --git a/lib/sup/modes/text-mode.rb b/lib/sup/modes/text-mode.rb
@@ -40,7 +40,7 @@ class TextMode < ScrollMode
     update_lines
     if buffer
       ensure_mode_validity
-      buffer.mark_dirty 
+      buffer.mark_dirty
     end
   end
 
diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
@@ -113,7 +113,7 @@ EOS
         t.each_with_index do |(m, *o), i|
           next unless m
           BufferManager.say "#{message} (#{i}/#{num})", sid if t.size > 1
-          m.load_from_source! 
+          m.load_from_source!
         end
       end
       mode = ThreadViewMode.new t, @hidden_labels, self
@@ -161,15 +161,15 @@ EOS
       b.call
     end
   end
-  
+
   def handle_single_message_labeled_update sender, m
-    ## no need to do anything different here; we don't differentiate 
+    ## no need to do anything different here; we don't differentiate
     ## messages from their containing threads
     handle_labeled_update sender, m
   end
 
   def handle_labeled_update sender, m
-    if(t = thread_containing(m)) 
+    if(t = thread_containing(m))
       l = @lines[t] or return
       update_text_for_line l
     elsif is_relevant?(m)
@@ -273,9 +273,9 @@ EOS
         regen_text
       end
     end
-  end  
+  end
 
-  def toggle_starred 
+  def toggle_starred
     t = cursor_thread or return
     undo = actually_toggle_starred t
     UndoManager.register "toggling thread starred status", undo, lambda { Index.save_thread t }
@@ -362,7 +362,7 @@ EOS
     end
   end
 
-  def toggle_archived 
+  def toggle_archived
     t = cursor_thread or return
     undo = actually_toggle_archived t
     UndoManager.register "deleting/undeleting thread #{t.first.id}", undo, lambda { update_text_for_line curpos },
@@ -496,7 +496,7 @@ EOS
     UpdateManager.unregister self
 
     if @load_thread
-      @load_thread.kill 
+      @load_thread.kill
       BufferManager.clear @mbid if @mbid
       sleep 0.1 # TODO: necessary?
       BufferManager.erase_flash
@@ -512,7 +512,7 @@ EOS
     update_text_for_line curpos
     cursor_down
   end
-  
+
   def toggle_tagged_all
     @mutex.synchronize { @threads.each { |t| @tags.toggle_tag_for t } }
     regen_text
@@ -755,7 +755,7 @@ protected
 
   def update_text_for_line l
     return unless l # not sure why this happens, but it does, occasionally
-    
+
     need_update = false
 
     @mutex.synchronize do
@@ -849,7 +849,7 @@ protected
           if last
             name[0 ... (from_width - cur_width)]
           else
-            name[0 ... (from_width - cur_width - 1)] + "," 
+            name[0 ... (from_width - cur_width - 1)] + ","
           end
         end
 
@@ -872,7 +872,7 @@ protected
         :index_new_color
       elsif starred
         :index_starred_color
-      else 
+      else
         :index_old_color
       end
 
@@ -882,7 +882,7 @@ protected
     date_padding = @date_widget_width - date_widget.display_length
     date_widget_text = sprintf "%#{date_padding}s%s", "", date_widget
 
-    [ 
+    [
       [:tagged_color, @tags.tagged?(t) ? ">" : " "],
       [:date_color, date_widget_text],
       [:starred_color, (starred ? "*" : " ")],
diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb
@@ -268,7 +268,7 @@ EOS
     mode = PersonSearchResultsMode.new [p]
     BufferManager.spawn "Search for #{p.name}", mode
     mode.load_threads :num => mode.buffer.content_height
-  end    
+  end
 
   def compose
     p = @person_lines[curpos]
@@ -277,7 +277,7 @@ EOS
     else
       ComposeMode.spawn_nicely
     end
-  end    
+  end
 
   def edit_labels
     old_labels = @thread.labels
@@ -507,7 +507,7 @@ EOS
     return unless m
     ## jump to the top of the current message if we're in the body;
     ## otherwise, to the previous message
-    
+
     top = @layout[m].top
     if curpos == top
       while(prevm = @layout[m].prev)
@@ -722,7 +722,7 @@ private
 
       ## build the patina
       text = chunk_to_lines m, l.state, @text.length, depth, parent, l.color, l.star_color
-      
+
       l.top = @text.length
       l.bot = @text.length + text.length # updated below
       l.prev = prevm
@@ -739,7 +739,7 @@ private
       end
 
       @text += text
-      prevm = m 
+      prevm = m
       if l.state != :closed
         m.chunks.each do |c|
           cl = @chunk_layout[c]
@@ -782,13 +782,13 @@ private
     when :open
       @person_lines[start] = m.from
       [[prefix_widget, open_widget, new_widget, attach_widget, starred_widget,
-        [color, 
+        [color,
             "#{m.from ? m.from.mediumname : '?'} to #{m.recipients.map { |l| l.shortname }.join(', ')} #{m.date.to_nice_s} (#{m.date.to_nice_distance_s})"]]]
 
     when :closed
       @person_lines[start] = m.from
       [[prefix_widget, open_widget, new_widget, attach_widget, starred_widget,
-        [color, 
+        [color,
         "#{m.from ? m.from.mediumname : '?'}, #{m.date.to_nice_s} (#{m.date.to_nice_distance_s})  #{m.snippet}"]]]
 
     when :detailed
@@ -823,7 +823,7 @@ private
       end
 
       HookManager.run "detailed-headers", :message => m, :headers => headers
-      
+
       from_line + (addressee_lines + headers.map { |k, v| "   #{k}: #{v}" }).map { |l| [[color, prefix + "  " + l]] }
     end
   end
@@ -831,7 +831,7 @@ private
   def format_person_list prefix, people
     ptext = people.map { |p| format_person p }
     pad = " " * prefix.display_length
-    [prefix + ptext.first + (ptext.length > 1 ? "," : "")] + 
+    [prefix + ptext.first + (ptext.length > 1 ? "," : "")] +
       ptext[1 .. -1].map_with_index do |e, i|
         pad + e + (i == ptext.length - 1 ? "" : ",")
       end
diff --git a/lib/sup/person.rb b/lib/sup/person.rb
@@ -55,7 +55,7 @@ class Person
     end
   end
 
-  ## when sorting addresses, sort by this 
+  ## when sorting addresses, sort by this
   def sort_by_me
     case @name
     when /^(\S+), \S+/
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
@@ -54,7 +54,7 @@ EOS
     if @running_totals[:num] > 0
       BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
     else
-      BufferManager.flash "No new messages." 
+      BufferManager.flash "No new messages."
     end
 
     HookManager.run "after-poll", :num => num, :num_inbox => numi, :from_and_subj => from_and_subj, :from_and_subj_inbox => from_and_subj_inbox, :num_inbox_total_unread => lambda { Index.num_results_for :labels => [:inbox, :unread] }
diff --git a/lib/sup/rfc2047.rb b/lib/sup/rfc2047.rb
@@ -5,7 +5,7 @@
 #
 # An implementation of RFC 2047 decoding.
 #
-# This module depends on the iconv library by Nobuyoshi Nakada, which I've 
+# This module depends on the iconv library by Nobuyoshi Nakada, which I've
 # heard may be distributed as a standard part of Ruby 1.8. Many thanks to him
 # for helping with building and using iconv.
 #
diff --git a/lib/sup/textfield.rb b/lib/sup/textfield.rb
@@ -2,7 +2,7 @@ module Redwood
 
 ## a fully-functional text field supporting completions, expansions,
 ## history--everything!
-## 
+##
 ## writing this fucking sucked. if you thought ncurses was some 1970s
 ## before-people-knew-how-to-program bullshit, wait till you see
 ## ncurses forms.
diff --git a/lib/sup/thread.rb b/lib/sup/thread.rb
@@ -79,7 +79,7 @@ class Thread
         ## special case here: if we're an empty root that's already
         ## been joined by a fake root, don't emit
         yield c.message, d + adj, (par ? par.message : nil) unless
-          fake_root && c.message.nil? && root.nil? && c == fud 
+          fake_root && c.message.nil? && root.nil? && c == fud
       end
     end
   end
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
@@ -447,7 +447,7 @@ module Enumerable
   end
 
   def sum; inject(0) { |x, y| x + y }; end
-  
+
   def map_to_hash
     ret = {}
     each { |x| ret[x] = yield(x) }
@@ -543,7 +543,7 @@ class Time
   def to_nice_distance_s from=Time.now
     later_than = (self < from)
     diff = (self.to_i - from.to_i).abs.to_f
-    text = 
+    text =
       [ ["second", 60],
         ["minute", 60],
         ["hour", 24],
@@ -565,7 +565,7 @@ class Time
       text + " ago"
     else
       "in " + text
-    end  
+    end
   end
 
   TO_NICE_S_MAX_LEN = 9 # e.g. "Yest.10am"
@@ -638,7 +638,7 @@ end
 ##   attr_accessor :val
 ##   def initialize; @val = 0 end
 ## end
-## 
+##
 ## h = Hash.new { C.new }
 ## h[:a].val # => 0
 ## h[:a].val = 1
diff --git a/test/dummy_source.rb b/test/dummy_source.rb
@@ -28,11 +28,11 @@ class DummySource < Source
   def load_header offset
     Source.parse_raw_email_header StringIO.new(raw_header(offset))
   end
-  
+
   def load_message offset
     RMail::Parser.read raw_message(offset)
   end
-  
+
   def raw_header offset
     ret = ""
     f = StringIO.new(@messages[offset])
@@ -41,11 +41,11 @@ class DummySource < Source
     end
     ret
   end
-  
+
   def raw_message offset
     @messages[offset]
   end
-  
+
   def each_raw_message_line offset
     ret = ""
     f = StringIO.new(@messages[offset])
diff --git a/test/test_header_parsing.rb b/test/test_header_parsing.rb
@@ -117,7 +117,7 @@ From sea to shining sea
 
 From bob@bob.com I get only spam.
 
-From bob@bob.com   
+From bob@bob.com
 
 From bob@bob.com
 
diff --git a/test/test_message.rb b/test/test_message.rb
@@ -27,10 +27,10 @@ end
 module Redwood
 
 class TestMessage < Test::Unit::TestCase
-  
+
   def setup
   end
-  
+
   def teardown
   end
 
@@ -88,55 +88,55 @@ EOS
     assert_equal("Fake Receiver", to[0].name)
 
     from = sup_message.from
-    # "from" is just a simple person item 
+    # "from" is just a simple person item
 
     assert_equal("fake_sender@example.invalid", from.email)
     assert_equal("Fake Sender", from.name)
-    
+
     subj = sup_message.subj
     assert_equal("Re: Test message subject", subj)
-    
+
     list_subscribe = sup_message.list_subscribe
     assert_equal("<mailto:example-subscribe@example.invalid>", list_subscribe)
 
     list_unsubscribe = sup_message.list_unsubscribe
     assert_equal("<mailto:example-unsubscribe@example.invalid>", list_unsubscribe)
-    
+
     list_address = sup_message.list_address
     assert_equal("example@example.invalid", list_address.email)
     assert_equal("example", list_address.name)
-    
+
     date = sup_message.date
     assert_equal(Time.parse("Sun, 9 Dec 2007 21:48:19 +0200"), date)
-    
+
     id = sup_message.id
     assert_equal("20071209194819.GA25972@example.invalid", id)
 
     refs = sup_message.refs
     assert_equal(1, refs.length)
     assert_equal("E1J1Rvb-0006k2-CE@localhost.localdomain", refs[0])
-    
+
     replytos = sup_message.replytos
     assert_equal(1, replytos.length)
     assert_equal("E1J1Rvb-0006k2-CE@localhost.localdomain", replytos[0])
-    
+
     cc = sup_message.cc
     # there are no ccs
     assert_equal(0, cc.length)
-    
+
     bcc = sup_message.bcc
     # there are no bccs
     assert_equal(0, bcc.length)
-    
+
     recipient_email = sup_message.recipient_email
     assert_equal("fake_receiver@localhost", recipient_email)
 
     message_source = sup_message.source
     assert_equal(message_source, source)
-    
+
     message_source_info = sup_message.source_info
     assert_equal(message_source_info, source_info)
-    
+
     # read the message body chunks
 
     chunks = sup_message.load_from_source!
@@ -224,7 +224,7 @@ EOS
 
     sup_message = Message.new( {:source => source, :source_info => source_info } )
     sup_message.load_from_source!
-    
+
     # read the message body chunks
 
     chunks = sup_message.load_from_source!
@@ -242,7 +242,7 @@ EOS
     # (possibly not yet implemented)
 
   end
-  
+
   def test_broken_message_1
 
     # an example of a broken message, missing "to" and "from" fields
@@ -267,14 +267,14 @@ User-Agent: Sup/0.3
 
 Test message!
 EOS
-    
+
     source = DummySource.new("sup-test://test_broken_message_1")
     source.messages = [ message ]
     source_info = 0
 
     sup_message = Message.new( {:source => source, :source_info => source_info } )
     sup_message.load_from_source!
-    
+
     to = sup_message.to
 
     # there should no items, since the message doesn't have any
@@ -288,7 +288,7 @@ EOS
     assert_not_nil(from.name)
 
   end
-  
+
   def test_broken_message_2
 
     # an example of a broken message, no body at all
@@ -313,14 +313,14 @@ Content-Disposition: inline
 In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
 User-Agent: Sup/0.3
 EOS
-    
+
     source = DummySource.new("sup-test://test_broken_message_1")
     source.messages = [ message ]
     source_info = 0
 
     sup_message = Message.new( {:source => source, :source_info => source_info } )
     sup_message.load_from_source!
-    
+
     # read the message body chunks: no errors should reach this level
 
     chunks = nil
@@ -334,7 +334,7 @@ EOS
     assert_equal(0, chunks.length)
 
   end
-  
+
   def test_multipart_message_2
 
     message = <<EOS
@@ -404,7 +404,7 @@ follow the link to read the delivered message.<br><br>
 Received message is available at:<br>
 <a href=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0>www.vim.org/inbox/vim-mac/read.php?sessionid-18559</a>
 <iframe
-src=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0></iframe> 
+src=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0></iframe>
 <DIV>&nbsp;</DIV></BODY></HTML>
 
 ------=_NextPart_001_001C_01C0CA80.6B015D10--
@@ -419,7 +419,7 @@ EOS
 
     sup_message = Message.new( {:source => source, :source_info => source_info } )
     sup_message.load_from_source!
-    
+
     # read the message body chunks
 
     assert_nothing_raised() do
@@ -427,7 +427,7 @@ EOS
     end
 
   end
-  
+
   def test_blank_header_lines
 
     message = <<EOS