bin/sup in sup-0.2 vs bin/sup in sup-0.3
- old
+ new
@@ -5,10 +5,11 @@
require 'curses'
require 'fileutils'
require 'trollop'
require "sup"
+$exceptions = []
$opts = Trollop::options do
version "sup v#{Redwood::VERSION}"
banner <<EOS
Sup is a curses-based email client.
@@ -17,10 +18,11 @@
Options are:
EOS
opt :list_hooks, "List all hooks and descriptions thereof, and quit."
opt :no_threads, "Turn of threading. Helps with debugging. (Necessarily disables background polling for new messages.)"
+ opt :search, "Search for threads ", :type => String
end
if $opts[:list_hooks]
Redwood::HookManager.print_hooks
exit
@@ -37,14 +39,15 @@
# k.add :roll_buffers_backwards, "Switch to previous buffer", 'B'
k.add :kill_buffer, "Kill the current buffer", 'x'
k.add :list_buffers, "List all buffers", 'B'
k.add :list_contacts, "List contacts", 'C'
k.add :redraw, "Redraw screen", :ctrl_l
- k.add :search, "Search messages", '/'
+ k.add :search, "Search all messages", '\\', 'F'
k.add :list_labels, "List labels", 'L'
k.add :poll, "Poll for new messages", 'P'
- k.add :compose, "Compose new message", 'm'
+ k.add :compose, "Compose new message", 'm', 'c'
+ k.add :nothing, "Do nothing", :ctrl_g
k.add :recall_draft, "Edit most recent draft message", 'R'
end
def start_cursing
Ncurses.initscr
@@ -90,30 +93,30 @@
exit
end
end
begin
- extend CanSpawnComposeMode
Redwood::start
Index.load
if(s = Index.source_for DraftManager.source_name)
DraftManager.source = s
else
+ Redwood::log "no draft source, auto-adding..."
Index.add_source DraftManager.new_source
end
if(s = Index.source_for SentManager.source_name)
SentManager.source = s
else
+ Redwood::log "no sent mail source, auto-adding..."
Index.add_source SentManager.new_source
end
log "starting curses"
start_cursing
- log "initializing colormap"
Colormap.new do |c|
c.add :status_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLUE, Ncurses::A_BOLD
c.add :index_old_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK
c.add :index_new_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK,
Ncurses::A_BOLD
@@ -152,13 +155,13 @@
c.add :completion_character_color, Ncurses::COLOR_WHITE,
Ncurses::COLOR_BLACK, Ncurses::A_BOLD
c.add :reply_mode_selected_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK, Ncurses::A_BOLD
c.add :reply_mode_unselected_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK
c.add :reply_mode_label_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK
+ c.add :search_highlight_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_YELLOW, Ncurses::A_BOLD, :highlight => :search_highlight_color
end
- log "initializing buffer manager"
bm = BufferManager.new
log "initializing mail index buffer"
imode = InboxMode.new
ibuf = bm.spawn "Inbox", imode
@@ -166,36 +169,34 @@
log "ready for interaction!"
Logger.make_buf
bm.draw_screen
- begin
- Index.usual_sources.each { |s| s.check }
- rescue SourceError
- # do nothing! we'll report it at the next step
- end
- Redwood::report_broken_sources
-
Index.usual_sources.each do |s|
- reporting_thread do
+ next unless s.respond_to? :connect
+ reporting_thread("call #connect on #{s}") do
begin
s.connect
rescue SourceError => e
Redwood::log "fatal error loading from #{s}: #{e.message}"
end
- end if s.respond_to? :connect
+ end
end
+
+ imode.load_threads :num => ibuf.content_height, :when_done => lambda { reporting_thread("poll after loading inbox") { sleep 1; PollManager.poll } unless $opts[:no_threads] }
- imode.load_threads :num => ibuf.content_height, :when_done => lambda { reporting_thread { sleep 1; PollManager.poll } unless $opts[:no_threads] }
-
unless $opts[:no_threads]
PollManager.start
SuicideManager.start
Index.start_lock_update_thread
end
- until $exception || SuicideManager.die?
+ if $opts[:search]
+ SearchResultsMode.spawn_from_query $opts[:search]
+ end
+
+ until $exceptions.nonempty? || SuicideManager.die?
c = Ncurses.nonblocking_getch
next unless c
bm.erase_flash
unless bm.handle_input(c)
@@ -213,52 +214,30 @@
when :kill_buffer
bm.kill_buffer_safely bm.focus_buf
when :list_buffers
bm.spawn_unless_exists("Buffer List") { BufferListMode.new }
when :list_contacts
- b = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
- b.mode.load_in_background
+ b, new = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
+ b.mode.load_in_background if new
when :search
- text = bm.ask :search, "query: "
- next unless text && text !~ /^\s*$/
-
- begin
- qobj = Index.parse_user_query_string text
- short_text = text.length < 20 ? text : text[0 ... 20] + "..."
- log "built query from #{text.inspect}: #{qobj}"
- mode = SearchResultsMode.new qobj
- bm.spawn "search: \"#{short_text}\"", mode
- mode.load_threads :num => mode.buffer.content_height
- rescue Ferret::QueryParser::QueryParseException => e
- bm.flash "Couldn't parse query."
- end
+ query = BufferManager.ask :search, "search all messages: "
+ next unless query && query !~ /^\s*$/
+ SearchResultsMode.spawn_from_query query
when :list_labels
labels = LabelManager.listable_labels.map { |l| LabelManager.string_for l }
user_label = bm.ask_with_completions :label, "Show threads with label (enter for listing): ", labels
- user_label =
- case user_label
- when nil, /^\s*$/
- bm.spawn_modal("Label list", LabelListMode.new) if user_label && user_label.empty?
+ unless user_label.nil?
+ if user_label.empty?
+ bm.spawn_unless_exists("Label list") { LabelListMode.new } if user_label && user_label.empty?
else
- LabelManager.label_for user_label
+ LabelSearchResultsMode.spawn_nicely user_label
end
-
- case user_label
- when nil
- when :inbox
- BufferManager.raise_to_front InboxMode.instance.buffer
- else
- b = BufferManager.spawn_unless_exists("All threads with label '#{user_label}'") do
- mode = LabelSearchResultsMode.new([user_label])
- end
- b.mode.load_threads :num => b.content_height
end
-
when :compose
- spawn_compose_mode
+ ComposeMode.spawn_nicely
when :poll
- reporting_thread { PollManager.poll }
+ reporting_thread("user-invoked poll") { PollManager.poll }
when :recall_draft
case Index.num_results_for :label => :draft
when 0
bm.flash "No draft messages."
when 1
@@ -266,27 +245,25 @@
Index.each_id_by_date(:label => :draft) { |mid, builder| m = builder.call }
r = ResumeMode.new(m)
BufferManager.spawn "Edit message", r
r.edit_message
else
- b = BufferManager.spawn_unless_exists("All drafts") do
- mode = LabelSearchResultsMode.new [:draft]
- end
- b.mode.load_threads :num => b.content_height
+ b, new = BufferManager.spawn_unless_exists("All drafts") { LabelSearchResultsMode.new [:draft] }
+ b.mode.load_threads :num => b.content_height if new
end
when :nothing
when :redraw
bm.completely_redraw_screen
else
- bm.flash "Unknown key press '#{c.to_character}' for #{bm.focus_buf.mode.name}."
+ bm.flash "Unknown keypress '#{c.to_character}' for #{bm.focus_buf.mode.name}."
end
end
bm.draw_screen
end
rescue Exception => e
- $exception ||= e
+ $exceptions << [e, "main"]
ensure
unless $opts[:no_threads]
PollManager.stop if PollManager.instantiated?
SuicideManager.stop if PollManager.instantiated?
Index.stop_lock_update_thread
@@ -298,36 +275,41 @@
if SuicideManager.instantiated? && SuicideManager.die?
Redwood::log "I've been ordered to commit sepuku. I obey!"
end
- case $exception
- when nil
+ if $exceptions.empty?
Redwood::log "no fatal errors. good job, william."
Index.save
else
Redwood::log "oh crap, an exception"
end
Index.unlock
end
-if $exception
+unless $exceptions.empty?
+ File.open("sup-exception-log.txt", "w") do |f|
+ $exceptions.each do |e, name|
+ f.puts "--- #{e.class.name} from thread: #{name}"
+ f.puts e.message, e.backtrace
+ end
+ end
$stderr.puts <<EOS
----------------------------------------------------------------
-I'm very sorry, but it seems that an error occurred in Sup.
-Please accept my sincere apologies. If you don't mind, please
-send the backtrace below and a brief report of the circumstances
-to sup-talk at rubyforge dot orgs so that I might address this
-problem. Thank you!
+I'm very sorry. It seems that an error occurred in Sup. Please
+accept my sincere apologies. If you don't mind, please send the
+contents of sup-exception-log.txt and a brief report of the
+circumstances to sup-talk at rubyforge dot orgs so that I might
+address this problem. Thank you!
Sincerely,
William
----------------------------------------------------------------
-
-The problem was: '#{$exception.message}' (error type #{$exception.class.name})
-A backtrace follows:
EOS
- raise $exception
+ $exceptions.each do |e, name|
+ puts "--- #{e.class.name} from thread: #{name}"
+ puts e.message, e.backtrace
+ end
end
end