]> git.cworth.org Git - sup/blob - bin/sup
moved evertying to devel
[sup] / bin / sup
1 #!/bin/env ruby
2
3 require 'rubygems'
4 require 'ncurses'
5 require "sup"
6
7 module Redwood
8
9 $exception = nil
10
11 global_keymap = Keymap.new do |k|
12   k.add :quit, "Quit Redwood", 'q'
13   k.add :help, "Show help", 'H', '?'
14   k.add :roll_buffers, "Switch to next buffer", 'b'
15   k.add :roll_buffers_backwards, "Switch to previous buffer", 'B'
16   k.add :kill_buffer, "Kill the current buffer", 'x'
17   k.add :list_buffers, "List all buffers", 'A'
18   k.add :list_contacts, "List contacts", 'C'
19   k.add :redraw, "Redraw screen", :ctrl_l
20   k.add :search, "Search messages", '/'
21   k.add :list_labels, "List labels", 'L'
22   k.add :poll, "Poll for new messages", 'P'
23   k.add :compose, "Compose new message", 'm'
24 end
25
26 def start_cursing
27   Ncurses.initscr
28   Ncurses.noecho
29   Ncurses.cbreak
30   Ncurses.stdscr.keypad 1
31   Ncurses.curs_set 0
32   Ncurses.start_color
33 end
34
35 def stop_cursing
36   Ncurses.curs_set 1
37   Ncurses.echo
38   Ncurses.endwin
39 end
40 module_function :start_cursing, :stop_cursing
41
42 Redwood::SentManager.new Redwood::SENT_FN
43 Redwood::ContactManager.new Redwood::CONTACT_FN
44 Redwood::LabelManager.new Redwood::LABEL_FN
45 Redwood::AccountManager.new $config[:accounts]
46 Redwood::DraftManager.new Redwood::DRAFT_DIR
47 Redwood::UpdateManager.new
48 Redwood::PollManager.new
49
50 Index.new.load
51 log "loaded #{Index.size} messages from index"
52
53 if(s = Index.source_for DraftManager.source_name)
54   DraftManager.source = s
55 else
56   Index.add_source DraftManager.new_source
57 end
58
59 if(s = Index.source_for SentManager.source_name)
60   SentManager.source = s
61 else
62   Index.add_source SentManager.new_source
63 end
64   
65 begin
66   log "starting curses"
67   start_cursing
68
69   log "initializing colormap"
70   Colormap.new do |c|
71     c.add :status_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLUE, Ncurses::A_BOLD
72     c.add :index_old_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK
73     c.add :index_new_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK, 
74            Ncurses::A_BOLD
75     c.add :labellist_old_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK
76     c.add :labellist_new_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK, 
77            Ncurses::A_BOLD
78     c.add :twiddle_color, Ncurses::COLOR_BLUE, Ncurses::COLOR_BLACK
79     c.add :label_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
80     c.add :message_patina_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_GREEN
81     c.add :mime_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK
82     c.add :quote_patina_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
83     c.add :sig_patina_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
84     c.add :quote_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
85     c.add :sig_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
86     c.add :to_me_color, Ncurses::COLOR_GREEN, Ncurses::COLOR_BLACK
87     c.add :starred_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK,
88           Ncurses::A_BOLD
89     c.add :starred_patina_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_GREEN,
90           Ncurses::A_BOLD
91     c.add :snippet_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK
92     c.add :option_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK
93     c.add :tagged_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK,
94           Ncurses::A_BOLD
95     c.add :draft_notification_color, Ncurses::COLOR_RED, Ncurses::COLOR_BLACK,
96           Ncurses::A_BOLD
97   end
98
99   log "initializing buffer manager"
100   bm = BufferManager.new
101
102   if Index.usual_sources.any? { |s| !s.done? }
103     log "polling for new mail"
104     pmode = PollMode.new
105     pbuf = bm.spawn "load new messages", pmode
106     pmode.poll
107 #    sleep 1
108 #    bm.kill_buffer pbuf
109   end
110
111   log "initializing mail index buffer"
112   imode = InboxMode.new
113   ibuf = bm.spawn "inbox", imode
114
115   log "ready for (inter)action!"
116   Logger.make_buf
117
118   bm.draw_screen
119   imode.load_more_threads ibuf.content_height
120
121   until $exception
122     bm.draw_screen
123     c = Ncurses.nonblocking_getch
124     bm.erase_flash
125
126     if c == Ncurses::KEY_RESIZE
127       bm.handle_resize
128     elsif c
129       unless bm.handle_input(c)
130         x = global_keymap.action_for c
131         case x
132         when :quit
133           break
134         when :help
135           curmode = bm.focus_buf.mode
136           bm.spawn_unless_exists("<help for #{curmode.name}>") { HelpMode.new curmode, global_keymap }
137         when :roll_buffers
138           bm.roll_buffers
139         when :roll_buffers_backwards
140           bm.roll_buffers_backwards
141         when :kill_buffer
142           bm.kill_buffer bm.focus_buf unless bm.focus_buf.mode.is_a? InboxMode
143         when :list_buffers
144           bm.spawn_unless_exists("Buffer List") { BufferListMode.new }
145         when :list_contacts
146           mode = ContactListMode.new 
147           bm.spawn "compose to contacts", mode
148         when :search
149           text = bm.ask :search, "query: "
150           next unless text && text !~ /^\s*$/
151           mode = SearchResultsMode.new text
152           short_text = 
153             if text.length < 20
154               text
155             else
156               text[0 ... 20] + "..."
157             end
158           bm.spawn "search: \"#{short_text}\"", mode
159           bm.draw_screen
160           mode.load_more_threads mode.buffer.content_height
161         when :list_labels
162           b = BufferManager.spawn_unless_exists("all labels") do
163             LabelListMode.new
164           end
165           b.mode.load_in_background
166         when :compose
167           mode = ComposeMode.new
168           bm.spawn "new message", mode
169           mode.edit
170         when :poll
171           b = BufferManager.spawn_unless_exists("load new messages") do
172             PollMode.new
173           end
174           b.mode.poll
175         when :nothing
176         when :redraw
177           bm.completely_redraw_screen
178         else
179           BufferManager.flash "Unknown key press '#{c.to_character}' for #{bm.focus_buf.mode.name}."
180         end
181       end
182     end
183   end
184   bm.kill_all_buffers
185   Redwood::LabelManager.save
186   Redwood::ContactManager.save
187 rescue Exception => e
188   $exception ||= e
189 ensure
190   stop_cursing
191 end
192
193 Index.save unless $exception # TODO: think about this
194
195 if $exception 
196   if $exception.is_a? IndexError
197     $stderr.puts <<EOS
198 An error occurred while loading a message from source "#{$exception.source}".
199 Typically, this means that the source has been modified in some
200 way which has rendered the messages invalid.
201
202 You must rebuild the index for this source. Please run:
203   sup-import --rebuild #{$exception.source}
204 to correct this error.
205 EOS
206   raise $exception                             
207   else
208     $stderr.puts <<EOS
209 -----------------------------------------------------------------
210 I'm very sorry, but it seems that an error occurred in Redwood. 
211 Please accept my sincere apologies. If you don't mind, please
212 send the backtrace below and a brief report of the circumstances
213 to user wmorgan-sup at site masanjin dot net so that I might
214 address this problem. Thank you!
215
216 Sincerely,
217 William
218 -----------------------------------------------------------------
219
220 The problem was: #{$exception.message} (error type #{$exception.class.name})
221 A backtrace follows:
222 EOS
223     raise $exception
224   end
225 end
226
227
228 end
229