sup 0.8 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sup might be problematic. Click here for more details.

data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.8.1 / 2009-06-15
2
+ * make multibyte display "work" for non-utf8 locales
3
+ * fix reply-mode always selecting "Customized"
4
+ * reduce email quote parsing worst-case behavior
5
+
1
6
  == 0.8 / 2009-06-05
2
7
  * Undo support on many operations. Yay!
3
8
  * Mbox splitting fixes. No more "From "-line problems.
data/ReleaseNotes CHANGED
@@ -1,3 +1,8 @@
1
+ Release 0.8.1:
2
+
3
+ A bugfix release with fixes for quote parsing (bad behavior in certain long
4
+ emails), multibyte display for non-utf8 locales, and reply-mode mode selection.
5
+
1
6
  Release 0.8:
2
7
 
3
8
  The big wins are undo support, mbox splitting fixes, and the various UI
data/bin/sup CHANGED
@@ -8,7 +8,7 @@ require 'trollop'
8
8
  require 'fastthread'
9
9
  require "sup"
10
10
 
11
- BIN_VERSION = "0.8"
11
+ BIN_VERSION = "0.8.1"
12
12
 
13
13
  unless Redwood::VERSION == BIN_VERSION
14
14
  $stderr.puts <<EOS
data/lib/ncurses.rb ADDED
@@ -0,0 +1,289 @@
1
+ # ncurses-ruby is a ruby module for accessing the FSF's ncurses library
2
+ # (C) 2002, 2003 Tobias Peters <t-peters@users.berlios.de>
3
+ # (C) 2004 Simon Kaczor <skaczor@cox.net>
4
+ #
5
+ # This module is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2 of the License, or (at your option) any later version.
9
+ #
10
+ # This module is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this module; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+
19
+ # $Id: ncurses.rb,v 1.5 2004/07/31 08:34:09 t-peters Exp $
20
+
21
+ require "ncurses.so"
22
+
23
+
24
+ # Ncurses constants with leading underscore
25
+ def Ncurses._XOPEN_CURSES
26
+ Ncurses::XOPEN_CURSES
27
+ end
28
+ def Ncurses._SUBWIN
29
+ Ncurses::SUBWIN
30
+ end
31
+ def Ncurses._ENDLINE
32
+ Ncurses::ENDLINE
33
+ end
34
+ def Ncurses._FULLWIN
35
+ Ncurses::FULLWIN
36
+ end
37
+ def Ncurses._SCROLLWIN
38
+ Ncurses::SCROLLWIN
39
+ end
40
+ def Ncurses._ISPAD
41
+ Ncurses::ISPAD
42
+ end
43
+ def Ncurses._HASMOVED
44
+ Ncurses::HASMOVED
45
+ end
46
+ def Ncurses._WRAPPED
47
+ Ncurses::WRAPPED
48
+ end
49
+ def Ncurses._NOCHANGE
50
+ Ncurses::NOCHANGE
51
+ end
52
+ def Ncurses._NEWINDEX
53
+ Ncurses::NEWINDEX
54
+ end
55
+
56
+
57
+ module Ncurses
58
+ module Destroy_checker; def destroyed?; @destroyed; end; end
59
+ class WINDOW
60
+ include Destroy_checker
61
+ def method_missing(name, *args)
62
+ name = name.to_s
63
+ if (name[0,2] == "mv")
64
+ test_name = name.dup
65
+ test_name[2,0] = "w" # insert "w" after"mv"
66
+ if (Ncurses.respond_to?(test_name))
67
+ return Ncurses.send(test_name, self, *args)
68
+ end
69
+ end
70
+ test_name = "w" + name
71
+ if (Ncurses.respond_to?(test_name))
72
+ return Ncurses.send(test_name, self, *args)
73
+ end
74
+ Ncurses.send(name, self, *args)
75
+ end
76
+ def respond_to?(name)
77
+ name = name.to_s
78
+ if (name[0,2] == "mv" && Ncurses.respond_to?("mvw" + name[2..-1]))
79
+ return true
80
+ end
81
+ Ncurses.respond_to?("w" + name) || Ncurses.respond_to?(name)
82
+ end
83
+ def del
84
+ Ncurses.delwin(self)
85
+ end
86
+ alias delete del
87
+ def WINDOW.new(*args)
88
+ Ncurses.newwin(*args)
89
+ end
90
+ end
91
+ class SCREEN
92
+ include Destroy_checker
93
+ def del
94
+ Ncurses.delscreen(self)
95
+ end
96
+ alias delete del
97
+ end
98
+ class MEVENT
99
+ attr_accessor :id, :x,:y,:z, :bstate
100
+ end
101
+ GETSTR_LIMIT = 1024
102
+
103
+ module Panel
104
+ class PANEL; end
105
+ end
106
+
107
+ module Form
108
+ class FORM
109
+ attr_reader :user_object
110
+
111
+ # This placeholder replaces the field_userptr function in curses
112
+ def user_object=(obj)
113
+ @user_object = obj
114
+ end
115
+ end
116
+
117
+ class FIELD
118
+ attr_reader :user_object
119
+
120
+ # This placeholder replaces the field_userptr function in curses
121
+ def user_object=(obj)
122
+ @user_object = obj
123
+ end
124
+ end
125
+
126
+ class FIELDTYPE
127
+ end
128
+ end
129
+ end
130
+ def Ncurses.inchnstr(str,n)
131
+ Ncurses.winchnstr(Ncurses.stdscr, str, n)
132
+ end
133
+ def Ncurses.inchstr(str)
134
+ Ncurses.winchstr(Ncurses.stdscr, str)
135
+ end
136
+ def Ncurses.mvinchnstr(y,x, str, n)
137
+ Ncurses.mvwinchnstr(Ncurses.stdscr, y,x, str, n)
138
+ end
139
+ def Ncurses.mvinchstr(y,x, str)
140
+ Ncurses.mvwinchstr(Ncurses.stdscr, y,x, str)
141
+ end
142
+ def Ncurses.mvwinchnstr(win, y,x, str, n)
143
+ if (Ncurses.wmove(win,y,x) == Ncurses::ERR)
144
+ Ncurses::ERR
145
+ else
146
+ Ncurses.winchnstr(win,str,n)
147
+ end
148
+ end
149
+ def Ncurses.mvwinchstr(win, y,x, str)
150
+ maxy = []; maxx = []; getmaxyx(win, maxy,maxx)
151
+ return Ncurses::ERR if (maxx[0] == Ncurses::ERR)
152
+ Ncurses.mvwinchnstr(win, y,x, str, maxx[0]+1)
153
+ end
154
+ def Ncurses.winchstr(win, str)
155
+ maxy = []; maxx = []; getmaxyx(win, maxy,maxx)
156
+ return Ncurses::ERR if (maxx[0] == Ncurses::ERR)
157
+ Ncurses.winchnstr(win, str, maxx[0]+1)
158
+ end
159
+
160
+ def Ncurses.getnstr(str,n)
161
+ Ncurses.wgetnstr(Ncurses.stdscr, str, n)
162
+ end
163
+ def Ncurses.mvgetnstr(y,x, str, n)
164
+ Ncurses.mvwgetnstr(Ncurses.stdscr, y,x, str, n)
165
+ end
166
+ def Ncurses.mvwgetnstr(win, y,x, str, n)
167
+ if (Ncurses.wmove(win,y,x) == Ncurses::ERR)
168
+ Ncurses::ERR
169
+ else
170
+ Ncurses.wgetnstr(win,str,n)
171
+ end
172
+ end
173
+
174
+ def Ncurses.innstr(str,n)
175
+ Ncurses.winnstr(Ncurses.stdscr, str, n)
176
+ end
177
+ def Ncurses.instr(str)
178
+ Ncurses.winstr(Ncurses.stdscr, str)
179
+ end
180
+ def Ncurses.mvinnstr(y,x, str, n)
181
+ Ncurses.mvwinnstr(Ncurses.stdscr, y,x, str, n)
182
+ end
183
+ def Ncurses.mvinstr(y,x, str)
184
+ Ncurses.mvwinstr(Ncurses.stdscr, y,x, str)
185
+ end
186
+ def Ncurses.mvwinnstr(win, y,x, str, n)
187
+ if (Ncurses.wmove(win,y,x) == Ncurses::ERR)
188
+ Ncurses::ERR
189
+ else
190
+ Ncurses.winnstr(win,str,n)
191
+ end
192
+ end
193
+ def Ncurses.mvwinstr(win, y,x, str)
194
+ maxy = []; maxx = []; getmaxyx(win, maxy,maxx)
195
+ return Ncurses::ERR if (maxx[0] == Ncurses::ERR)
196
+ Ncurses.mvwinnstr(win, y,x, str, maxx[0]+1)
197
+ end
198
+ def Ncurses.winstr(win, str)
199
+ maxy = []; maxx = []; getmaxyx(win, maxy,maxx)
200
+ return Ncurses::ERR if (maxx[0] == Ncurses::ERR)
201
+ Ncurses.winnstr(win, str, maxx[0]+1)
202
+ end
203
+
204
+ def Ncurses.mouse_trafo(pY, pX, to_screen)
205
+ Ncurses.wmouse_trafo(Ncurses.stdscr, pY, pX, to_screen)
206
+ end
207
+
208
+ def Ncurses.getcurx(win)
209
+ x = []; y = []; Ncurses.getyx(win, y,x); x[0]
210
+ end
211
+ def Ncurses.getcury(win)
212
+ x = []; y = []; Ncurses.getyx(win, y,x); y[0]
213
+ end
214
+ def Ncurses.getbegx(win)
215
+ x = []; y = []; Ncurses.getbegyx(win, y,x); x[0]
216
+ end
217
+ def Ncurses.getbegy(win)
218
+ x = []; y = []; Ncurses.getbegyx(win, y,x); y[0]
219
+ end
220
+ def Ncurses.getmaxx(win)
221
+ x = []; y = []; Ncurses.getmaxyx(win, y,x); x[0]
222
+ end
223
+ def Ncurses.getmaxy(win)
224
+ x = []; y = []; Ncurses.getmaxyx(win, y,x); y[0]
225
+ end
226
+ def Ncurses.getparx(win)
227
+ x = []; y = []; Ncurses.getparyx(win, y,x); x[0]
228
+ end
229
+ def Ncurses.getpary(win)
230
+ x = []; y = []; Ncurses.getparyx(win, y,x); y[0]
231
+ end
232
+ def Ncurses.erase
233
+ Ncurses.werase(Ncurses.stdscr)
234
+ end
235
+ def Ncurses.getstr(str)
236
+ Ncurses.getnstr(str, Ncurses::GETSTR_LIMIT)
237
+ end
238
+ def Ncurses.mvgetstr(y,x, str)
239
+ Ncurses.mvgetnstr(y,x, str, Ncurses::GETSTR_LIMIT)
240
+ end
241
+ def Ncurses.mvwgetstr(win, y,x, str)
242
+ Ncurses.mvwgetnstr(win, y,x, str, Ncurses::GETSTR_LIMIT)
243
+ end
244
+ def Ncurses.wgetstr(win, str)
245
+ Ncurses.wgetnstr(win, str, Ncurses::GETSTR_LIMIT)
246
+ end
247
+
248
+ def Ncurses.scanw(format, result)
249
+ Ncurses.wscanw(Ncurses.stdscr, format, result)
250
+ end
251
+ def Ncurses.mvscanw(y,x, format, result)
252
+ Ncurses.mvwscanw(Ncurses.stdscr, y,x, format, result)
253
+ end
254
+ def Ncurses.mvwscanw(win, y,x, format, result)
255
+ if (Ncurses.wmove(win, y,x) == Ncurses::ERR)
256
+ Ncurses::ERR
257
+ else
258
+ Ncurses.wscanw(win, format, result)
259
+ end
260
+ end
261
+ def Ncurses.wscanw(win, format, result)
262
+ str = ""
263
+ if (Ncurses.wgetstr(win, str) == Ncurses::ERR)
264
+ Ncurses::ERR
265
+ else
266
+ require "scanf.rb" # Use ruby's implementation of scanf
267
+ result.replace(str.scanf(format))
268
+ end
269
+ end
270
+
271
+ def Ncurses.mvprintw(*args)
272
+ Ncurses.mvwprintw(Ncurses.stdscr, *args)
273
+ end
274
+ def Ncurses.mvwprintw(win, y,x, *args)
275
+ if (Ncurses.wmove(win,y,x) == Ncurses::ERR)
276
+ Ncurses::ERR
277
+ else
278
+ wprintw(win, *args)
279
+ end
280
+ end
281
+ def Ncurses.printw(*args)
282
+ Ncurses.wprintw(Ncurses.stdscr, *args)
283
+ end
284
+ def Ncurses.touchline(win, start, count)
285
+ Ncurses.wtouchln(win, start, count, 1)
286
+ end
287
+ def Ncurses.touchwin(win)
288
+ wtouchln(win, 0, getmaxy(win), 1)
289
+ end
data/lib/sup.rb CHANGED
@@ -33,7 +33,7 @@ class Module
33
33
  end
34
34
 
35
35
  module Redwood
36
- VERSION = "0.8"
36
+ VERSION = "0.8.1"
37
37
 
38
38
  BASE_DIR = ENV["SUP_BASE"] || File.join(ENV["HOME"], ".sup")
39
39
  CONFIG_FN = File.join(BASE_DIR, "config.yaml")
@@ -243,7 +243,7 @@ end
243
243
  Redwood::log "using character set encoding #{$encoding.inspect}"
244
244
  else
245
245
  Redwood::log "warning: can't find character set by using locale, defaulting to utf-8"
246
- $encoding = "utf-8"
246
+ $encoding = "UTF-8"
247
247
  end
248
248
 
249
249
  ## now everything else (which can feel free to call Redwood::log at load time)
data/lib/sup/message.rb CHANGED
@@ -26,7 +26,6 @@ class Message
26
26
 
27
27
  QUOTE_PATTERN = /^\s{0,4}[>|\}]/
28
28
  BLOCK_QUOTE_PATTERN = /^-----\s*Original Message\s*----+$/
29
- QUOTE_START_PATTERN = /\w.*:$/
30
29
  SIG_PATTERN = /(^-- ?$)|(^\s*----------+\s*$)|(^\s*_________+\s*$)|(^\s*--~--~-)|(^\s*--\+\+\*\*==)/
31
30
 
32
31
  MAX_SIG_DISTANCE = 15 # lines from the end
@@ -449,7 +448,11 @@ private
449
448
  when :text
450
449
  newstate = nil
451
450
 
452
- if line =~ QUOTE_PATTERN || (line =~ QUOTE_START_PATTERN && nextline =~ QUOTE_PATTERN)
451
+ ## the following /:$/ followed by /\w/ is an attempt to detect the
452
+ ## start of a quote. this is split into two regexen because the
453
+ ## original regex /\w.*:$/ had very poor behavior on long lines
454
+ ## like ":a:a:a:a:a" that occurred in certain emails.
455
+ if line =~ QUOTE_PATTERN || (line =~ /:$/ && line =~ /\w/ && nextline =~ QUOTE_PATTERN)
453
456
  newstate = :quote
454
457
  elsif line =~ SIG_PATTERN && (lines.length - i) < MAX_SIG_DISTANCE
455
458
  newstate = :sig
@@ -126,7 +126,7 @@ EOS
126
126
  "To" => [],
127
127
  "Cc" => [],
128
128
  "Bcc" => [],
129
- "In-Reply-To" => "<#{@m.id}>",
129
+ "In-reply-to" => "<#{@m.id}>",
130
130
  "Subject" => Message.reify_subj(@m.subj),
131
131
  "References" => refs,
132
132
  }.merge v
data/lib/sup/util.rb CHANGED
@@ -172,7 +172,15 @@ class Object
172
172
  end
173
173
 
174
174
  class String
175
- def display_length; scan(/./u).size end
175
+ ## nasty multibyte hack for ruby 1.8. if it's utf-8, split into chars using
176
+ ## the utf8 regex and count those. otherwise, use the byte length.
177
+ def display_length
178
+ if $encoding == "UTF-8"
179
+ scan(/./u).size
180
+ else
181
+ size
182
+ end
183
+ end
176
184
 
177
185
  def camel_to_hyphy
178
186
  self.gsub(/([a-z])([A-Z0-9])/, '\1-\2').downcase
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sup
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.8"
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Morgan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-05 12:45:26 -04:00
12
+ date: 2009-06-15 08:11:54 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -141,62 +141,63 @@ files:
141
141
  - bin/sup-sync
142
142
  - bin/sup-sync-back
143
143
  - bin/sup-tweak-labels
144
+ - lib/ncurses.rb
144
145
  - lib/sup.rb
145
- - lib/sup/poll.rb
146
- - lib/sup/source.rb
147
- - lib/sup/crypto.rb
148
- - lib/sup/horizontal-selector.rb
149
- - lib/sup/mode.rb
150
- - lib/sup/account.rb
146
+ - lib/sup/draft.rb
151
147
  - lib/sup/imap.rb
152
- - lib/sup/maildir.rb
153
- - lib/sup/contact.rb
154
- - lib/sup/message.rb
155
- - lib/sup/label.rb
156
- - lib/sup/index.rb
157
- - lib/sup/keymap.rb
148
+ - lib/sup/thread.rb
149
+ - lib/sup/logger.rb
150
+ - lib/sup/person.rb
158
151
  - lib/sup/rfc2047.rb
159
- - lib/sup/tagger.rb
160
- - lib/sup/suicide.rb
161
- - lib/sup/util.rb
152
+ - lib/sup/account.rb
153
+ - lib/sup/buffer.rb
154
+ - lib/sup/horizontal-selector.rb
162
155
  - lib/sup/textfield.rb
163
- - lib/sup/sent.rb
156
+ - lib/sup/source.rb
157
+ - lib/sup/suicide.rb
158
+ - lib/sup/maildir.rb
159
+ - lib/sup/tagger.rb
164
160
  - lib/sup/undo.rb
165
- - lib/sup/mbox.rb
166
- - lib/sup/person.rb
167
- - lib/sup/thread.rb
168
- - lib/sup/update.rb
161
+ - lib/sup/colormap.rb
169
162
  - lib/sup/hook.rb
163
+ - lib/sup/index.rb
164
+ - lib/sup/update.rb
165
+ - lib/sup/util.rb
170
166
  - lib/sup/message-chunks.rb
171
- - lib/sup/colormap.rb
172
- - lib/sup/buffer.rb
173
- - lib/sup/logger.rb
174
- - lib/sup/draft.rb
175
- - lib/sup/modes/label-search-results-mode.rb
176
- - lib/sup/modes/completion-mode.rb
177
- - lib/sup/modes/thread-index-mode.rb
178
- - lib/sup/modes/reply-mode.rb
179
- - lib/sup/modes/forward-mode.rb
180
- - lib/sup/modes/compose-mode.rb
167
+ - lib/sup/label.rb
168
+ - lib/sup/mbox.rb
169
+ - lib/sup/poll.rb
170
+ - lib/sup/message.rb
171
+ - lib/sup/crypto.rb
172
+ - lib/sup/sent.rb
173
+ - lib/sup/mode.rb
174
+ - lib/sup/contact.rb
175
+ - lib/sup/keymap.rb
176
+ - lib/sup/modes/resume-mode.rb
177
+ - lib/sup/modes/poll-mode.rb
181
178
  - lib/sup/modes/thread-view-mode.rb
182
- - lib/sup/modes/person-search-results-mode.rb
179
+ - lib/sup/modes/label-search-results-mode.rb
180
+ - lib/sup/modes/label-list-mode.rb
183
181
  - lib/sup/modes/help-mode.rb
184
- - lib/sup/modes/file-browser-mode.rb
182
+ - lib/sup/modes/log-mode.rb
185
183
  - lib/sup/modes/edit-message-mode.rb
186
- - lib/sup/modes/contact-list-mode.rb
187
- - lib/sup/modes/poll-mode.rb
184
+ - lib/sup/modes/forward-mode.rb
185
+ - lib/sup/modes/person-search-results-mode.rb
188
186
  - lib/sup/modes/inbox-mode.rb
189
- - lib/sup/modes/log-mode.rb
187
+ - lib/sup/modes/buffer-list-mode.rb
190
188
  - lib/sup/modes/scroll-mode.rb
191
- - lib/sup/modes/text-mode.rb
192
- - lib/sup/modes/label-list-mode.rb
193
- - lib/sup/modes/resume-mode.rb
194
- - lib/sup/modes/line-cursor-mode.rb
195
189
  - lib/sup/modes/search-results-mode.rb
196
- - lib/sup/modes/buffer-list-mode.rb
197
- - lib/sup/mbox/ssh-file.rb
198
- - lib/sup/mbox/loader.rb
190
+ - lib/sup/modes/compose-mode.rb
191
+ - lib/sup/modes/line-cursor-mode.rb
192
+ - lib/sup/modes/thread-index-mode.rb
193
+ - lib/sup/modes/contact-list-mode.rb
194
+ - lib/sup/modes/completion-mode.rb
195
+ - lib/sup/modes/file-browser-mode.rb
196
+ - lib/sup/modes/reply-mode.rb
197
+ - lib/sup/modes/text-mode.rb
199
198
  - lib/sup/mbox/ssh-loader.rb
199
+ - lib/sup/mbox/loader.rb
200
+ - lib/sup/mbox/ssh-file.rb
200
201
  has_rdoc: false
201
202
  homepage: http://sup.rubyforge.org/
202
203
  post_install_message:
@@ -219,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
220
  requirements: []
220
221
 
221
222
  rubyforge_project:
222
- rubygems_version: 1.3.1
223
+ rubygems_version: 1.2.0
223
224
  signing_key:
224
225
  specification_version: 2
225
226
  summary: A console-based email client with the best features of GMail, mutt, and emacs. Features full text search, labels, tagged operations, multiple buffers, recent contacts, and more.