]> git.cworth.org Git - sup/blob - bin/sup
preparations for imap
[sup] / bin / sup
1 #!/usr/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   log "initializing mail index buffer"
103   imode = InboxMode.new
104   ibuf = bm.spawn "inbox", imode
105
106   log "ready for (inter)action!"
107   Logger.make_buf
108
109   bm.draw_screen
110   imode.load_more_threads ibuf.content_height
111
112   ::Thread.new { sleep 3; PollManager.poll }
113
114   until $exception
115     bm.draw_screen
116     c = Ncurses.nonblocking_getch
117     bm.erase_flash
118
119     if c == Ncurses::KEY_RESIZE
120       bm.handle_resize
121     elsif c
122       unless bm.handle_input(c)
123         x = global_keymap.action_for c
124         case x
125         when :quit
126           break
127         when :help
128           curmode = bm.focus_buf.mode
129           bm.spawn_unless_exists("<help for #{curmode.name}>") { HelpMode.new curmode, global_keymap }
130         when :roll_buffers
131           bm.roll_buffers
132         when :roll_buffers_backwards
133           bm.roll_buffers_backwards
134         when :kill_buffer
135           bm.kill_buffer bm.focus_buf unless bm.focus_buf.mode.is_a? InboxMode
136         when :list_buffers
137           bm.spawn_unless_exists("Buffer List") { BufferListMode.new }
138         when :list_contacts
139           mode = ContactListMode.new 
140           bm.spawn "compose to contacts", mode
141         when :search
142           text = bm.ask :search, "query: "
143           next unless text && text !~ /^\s*$/
144           mode = SearchResultsMode.new text
145           short_text = 
146             if text.length < 20
147               text
148             else
149               text[0 ... 20] + "..."
150             end
151           bm.spawn "search: \"#{short_text}\"", mode
152           bm.draw_screen
153           mode.load_more_threads mode.buffer.content_height
154         when :list_labels
155           b = BufferManager.spawn_unless_exists("all labels") do
156             LabelListMode.new
157           end
158           b.mode.load_in_background
159         when :compose
160           mode = ComposeMode.new
161           bm.spawn "new message", mode
162           mode.edit
163         when :poll
164           BufferManager.raise_to_front PollManager.buffer
165           PollManager.poll
166         when :nothing
167         when :redraw
168           bm.completely_redraw_screen
169         else
170           BufferManager.flash "Unknown key press '#{c.to_character}' for #{bm.focus_buf.mode.name}."
171         end
172       end
173     end
174   end
175   bm.kill_all_buffers
176   Redwood::LabelManager.save
177   Redwood::ContactManager.save
178 rescue Exception => e
179   $exception ||= e
180 ensure
181   stop_cursing
182 end
183
184 Index.save unless $exception # TODO: think about this
185
186 if $exception 
187   case $exception
188   when IndexError
189     $stderr.puts <<EOS
190 An error occurred while parsing a message from source "#{$exception.source}".
191 Typically, this means that the source has been modified in some
192 way which has rendered the messages invalid. For example, if it's an mbox
193 file, you may have read or deleted messages using another client.
194
195 You must rebuild the index for this source. Please run:
196   sup-import --rebuild #{$exception.source}
197 to correct this error.
198 EOS
199 #' stupid ruby-mode
200   else
201     $stderr.puts <<EOS
202 ----------------------------------------------------------------
203 I'm very sorry, but it seems that an error occurred in Sup. 
204 Please accept my sincere apologies. If you don't mind, please
205 send the backtrace below and a brief report of the circumstances
206 to user wmorgan-sup at site masanjin dot net so that I might
207 address this problem. Thank you!
208
209 Sincerely,
210 William
211 ----------------------------------------------------------------
212
213 The problem was: #{$exception.message} (error type #{$exception.class.name})
214 A backtrace follows:
215 EOS
216   end
217   raise $exception
218 end
219
220 end