sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit a2221d53d31241ca28cb27cfb6eff6807749f1c6
parent f7a497c1fb31214bdb24df2c42bb4c5a502019ba
Author: wmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Date:   Mon,  2 Apr 2007 00:59:17 +0000

better imap error checking, and now we can force error messages to stay at the top

git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@363 5c8cc53c-5e98-4d25-b20a-d8db53a31250

Diffstat:
M lib/sup.rb | 6 +++---
M lib/sup/buffer.rb | 27 ++++++++++++++++++++++-----
M lib/sup/imap.rb | 10 +++++++++-
M lib/sup/message.rb | 3 +++
4 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -97,12 +97,12 @@ module Redwood
   end
 
   ## not really a good place for this, so I'll just dump it here.
-  def report_broken_sources
+  def report_broken_sources opts={}
     return unless BufferManager.instantiated?
 
     broken_sources = Index.usual_sources.select { |s| s.error.is_a? FatalSourceError }
     unless broken_sources.empty?
-      BufferManager.spawn "Broken source notification", TextMode.new(<<EOM)
+      BufferManager.spawn "Broken source notification", TextMode.new(<<EOM), opts
 Source error notification
 -------------------------
 
@@ -117,7 +117,7 @@ EOM
 
     desynced_sources = Index.usual_sources.select { |s| s.error.is_a? OutOfSyncSourceError }
     unless desynced_sources.empty?
-      BufferManager.spawn("Out-of-sync source notification", TextMode.new(<<EOM))
+      BufferManager.spawn "Out-of-sync source notification", TextMode.new(<<EOM), opts
 Out-of-sync source notification
 -------------------------------
 
diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
@@ -50,6 +50,7 @@ module Redwood
 class Buffer
   attr_reader :mode, :x, :y, :width, :height, :title
   bool_reader :dirty
+  bool_accessor :force_to_top
 
   def initialize window, mode, width, height, opts={}
     @w = window
@@ -57,6 +58,7 @@ class Buffer
     @dirty = true
     @focus = false
     @title = opts[:title] || ""
+    @force_to_top = opts[:force_to_top] || false
     @x, @y, @width, @height = 0, 0, width, height
   end
 
@@ -156,18 +158,33 @@ class BufferManager
 
   def raise_to_front buf
     raise ArgumentError, "buffer not on stack: #{buf.inspect}" unless @buffers.member? buf
+
     @buffers.delete buf
-    @buffers.push buf
-    focus_on buf
+    if @buffers.length > 0 && @buffers.last.force_to_top?
+      @buffers.insert -2, buf
+    else
+      @buffers.push buf
+      focus_on buf
+    end
     @dirty = true
   end
 
+  ## we reset force_to_top when rolling buffers. this is so that the
+  ## human can actually still move buffers around, while still
+  ## programmatically being able to pop stuff up in the middle of
+  ## drawing a window without worrying about covering it up.
+  ##
+  ## if we ever start calling roll_buffers programmatically, we will
+  ## have to change this. but it's not clear that we will ever actually
+  ## do that.
   def roll_buffers
+    @buffers.last.force_to_top = false
     raise_to_front @buffers.first
   end
 
   def roll_buffers_backwards
     return unless @buffers.length > 1
+    @buffers.last.force_to_top = false
     raise_to_front @buffers[@buffers.length - 2]
   end
 
@@ -258,14 +275,14 @@ class BufferManager
     ## w = Ncurses::WINDOW.new(height, width, (opts[:top] || 0),
     ## (opts[:left] || 0))
     w = Ncurses.stdscr
-    b = Buffer.new w, mode, width, height, :title => realtitle
+    b = Buffer.new w, mode, width, height, :title => realtitle, :force_to_top => (opts[:force_to_top] || false)
     mode.buffer = b
     @name_map[realtitle] = b
+
+    @buffers.unshift b
     if opts[:hidden]
-      @buffers.unshift b
       focus_on b unless @focus_buf
     else
-      @buffers.push b
       raise_to_front b
     end
     b
diff --git a/lib/sup/imap.rb b/lib/sup/imap.rb
@@ -64,7 +64,15 @@ class IMAP < Source
   end
   def ssl?; @parsed_uri.scheme == 'imaps' end
 
-  def check; scan_mailbox; end
+  def check
+    ids = 
+      @mutex.synchronize do
+        unsynchronized_scan_mailbox
+        @ids
+      end
+
+    start = ids.index(cur_offset || start_offset) or raise OutOfSyncSourceError, "Unknown message id #{cur_offset || start_offset}."
+  end
 
   ## is this necessary? TODO: remove maybe
   def == o; o.is_a?(IMAP) && o.uri == self.uri && o.username == self.username; end
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
@@ -190,6 +190,9 @@ class Message
           read_header @source.load_header(@source_info)
           message_to_chunks @source.load_message(@source_info)
         rescue SourceError, SocketError, MessageFormatError => e
+          ## we need force_to_top here otherwise this window will cover
+          ## up the error message one
+          Redwood::report_broken_sources :force_to_top => true
           [Text.new(error_message(e.message))]
         end
       end