sup

A curses threads-with-tags style email client

sup-website.git

git clone https://supmua.dev/git/sup-website/

community/pipermail-archives/sup-devel/2010-01.txt (382885B) - raw

      1 From tero@tilus.net  Fri Jan  1 08:19:45 2010
      2 From: tero@tilus.net (Tero Tilus)
      3 Date: Fri, 01 Jan 2010 15:19:45 +0200
      4 Subject: [sup-devel] [PATCH] XapianIndex.each_message_in_thread_for
      5 	yields messages in cronological order
      6 In-Reply-To: <1262287125-sup-5933@masanjin.net>
      7 References: <1261485246-sup-4236@tilus.net> <1261938751-sup-9421@zyrg.net>
      8 	<1262136474-sup-312@tilus.net> <1262182085-sup-1405@masanjin.net>
      9 	<1262190807-sup-434@zyrg.net> <1262287125-sup-5933@masanjin.net>
     10 Message-ID: <1262345828-sup-6789@tilus.net>
     11 
     12 William Morgan, 2009-12-31 21:41:
     13 > Out of curiousity, Tero, could the problem also be solved by giving
     14 > the in-reply-to header precedence over the references header?
     15 
     16 Well, yes and no.  ;)
     17 
     18 I think what it needs is to do is 
     19 
     20  a) consider only the first message in In-reply-to: (like it already
     21     does),
     22  b) prioritize In-reply-to: ahead of References: (like it already
     23     does!) and
     24  c) if In-reply-to: would create a loop or diamond, resolve by
     25     dropping another link ("topmost" conflicting?) and keep the one
     26     from In-reply-to: (currently it drops the link suggested by
     27     In-reply-to: over another potentially coming from (messed up)
     28     References:).
     29 
     30 Lemme speculate on this a bit.
     31 
     32 Current threading implementation tries to give In-reply-to: precedence
     33 over References: but it still could leave the (in my previous mail
     34 described way) malformed References: affecting the real root of the
     35 thread.  By the time we encounter the In-reply-to: headers which would
     36 need to take precedence over the References:, there could already be
     37 bogus parent to the root.
     38 
     39 Say we have
     40 
     41 First (no In-reply-to: or References:)
     42  +- Second (In-reply-to: First; References: First)
     43      +- Third (In-reply-to: Second, First; no References:)
     44          +- Fourth (In-reply-to: Third; References: Second, First, Third)
     45 
     46 If Third is a reply to both Second and First (in that order). Then
     47 Fourth might have References: Second, First, Third.  If, when
     48 threading, Fourth is the first processed message then First is seen as
     49 a reply to Second.  Now when itself Second is processed, the
     50 In-reply-to: in it would create a loop and is discarded, (see
     51 ThreadSet#link).  Resulting in
     52 
     53 Second
     54  +- First
     55      +- Third
     56          +- Fourth
     57 
     58 which is exactly what the example headers I posted seem to produce
     59 (real root jumps in the middle of one of the branches).
     60 
     61 -- 
     62 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
     63 
     64 From wmorgan-sup@masanjin.net  Fri Jan  1 10:13:08 2010
     65 From: wmorgan-sup@masanjin.net (William Morgan)
     66 Date: Fri, 01 Jan 2010 07:13:08 -0800
     67 Subject: [sup-devel] [PATCH] fixed am/pm in thread-list-mode for ruby1.8
     68 In-Reply-To: <1262297415-sup-6997@changeling.local>
     69 References: <1262270484-sup-8396@changeling.local>
     70 	<1262289195-sup-4420@masanjin.net>
     71 	<1262289317-sup-7991@changeling.local>
     72 	<1262290432-sup-9868@masanjin.net>
     73 	<1262293338-sup-9364@changeling.local>
     74 	<1262294449-sup-8418@localdomain>
     75 	<1262297415-sup-6997@changeling.local>
     76 Message-ID: <1262358668-sup-7399@masanjin.net>
     77 
     78 Reformatted excerpts from Eric Sherman's message of 2009-12-31:
     79 > Hmm.  Maybe this issue only exists on OSX.
     80 
     81 I suspect so. Can you provide a patch that uses the downcase trick and
     82 doesn't check for the ruby version or the OS? (Maybe with a helpful
     83 comment.) That should work everywhere, lame as it may be.
     84 -- 
     85 William <wmorgan-sup at masanjin.net>
     86 
     87 From sup-bugs@masanjin.net  Fri Jan  1 14:05:26 2010
     88 From: sup-bugs@masanjin.net (William Morgan)
     89 Date: Fri, 01 Jan 2010 19:05:26 +0000
     90 Subject: [sup-devel] [issue40] ruby 1.9: lockfile gem failure
     91 In-Reply-To: <1262372726.5.0.155183041676.issue40@masanjin.net>
     92 Message-ID: <1262372726.5.0.155183041676.issue40@masanjin.net>
     93 
     94 
     95 New submission from William Morgan <wmorgan-sup at masanjin.net>:
     96 
     97 If the lock file is there, the lockfile gem dies with this error:
     98 
     99 $XXX/ruby/gems/1.9.1/gems/lockfile-1.4.3/lib/lockfile.rb:475:in `load_lock_id': 
    100 undefined method `each' for #<String:0x00000002afa860> (NoMethodError)
    101 
    102 It appears the gem is not 1.9-ready, so we'll need to work around it somehow.
    103 
    104 ----------
    105 messages: 102
    106 nosy: w
    107 priority: bug
    108 ruby_version: 1.9.1
    109 status: unread
    110 sup_version: git
    111 title: ruby 1.9: lockfile gem failure
    112 
    113 _________________________________________
    114 Sup issue tracker <sup-bugs at masanjin.net>
    115 <http://masanjin.net/sup-bugs/issue40>
    116 _________________________________________
    117 
    118 From wmorgan-sup@masanjin.net  Fri Jan  1 14:09:09 2010
    119 From: wmorgan-sup@masanjin.net (William Morgan)
    120 Date: Fri, 01 Jan 2010 11:09:09 -0800
    121 Subject: [sup-devel] Ruby 1.9 encoding fixes
    122 In-Reply-To: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    123 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    124 Message-ID: <1262372864-sup-22@masanjin.net>
    125 
    126 Branch ruby-1.9-encoding, merged into next. Thank you very much!
    127 
    128 Using the xapian-full and ncursesw gems, I can now run Sup under 1.9,
    129 though there are a few warts (for some reason the secondary questions
    130 like "are you sure you want to quit?" aren't getting keystrokes.)
    131 
    132 Anyways, getting close!
    133 -- 
    134 William <wmorgan-sup at masanjin.net>
    135 
    136 From rlane@club.cc.cmu.edu  Fri Jan  1 15:47:07 2010
    137 From: rlane@club.cc.cmu.edu (Rich Lane)
    138 Date: Fri,  1 Jan 2010 12:47:07 -0800
    139 Subject: [sup-devel] [PATCH] ruby 1.9: use String#ord in ask_getch and
    140 	ask_yes_or_no
    141 Message-ID: <1262378827-16722-1-git-send-email-rlane@club.cc.cmu.edu>
    142 
    143 In Ruby 1.9, character literals and the return value from string index
    144 accesses are now themselves strings and need to be converted to integers with
    145 String#ord. This was breaking ask_getch. Integer#ord is defined on Ruby 1.8 so
    146 this won't cause problems there.
    147 ---
    148  lib/sup/buffer.rb |    4 ++--
    149  1 files changed, 2 insertions(+), 2 deletions(-)
    150 
    151 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
    152 index 4498b08..c826ab9 100644
    153 --- a/lib/sup/buffer.rb
    154 +++ b/lib/sup/buffer.rb
    155 @@ -611,7 +611,7 @@ EOS
    156    def ask_getch question, accept=nil
    157      raise "impossible!" if @asking
    158  
    159 -    accept = accept.split(//).map { |x| x[0] } if accept
    160 +    accept = accept.split(//).map { |x| x.ord } if accept
    161  
    162      status, title = get_status_and_title @focus_buf
    163      Ncurses.sync do
    164 @@ -647,7 +647,7 @@ EOS
    165    ## returns true (y), false (n), or nil (ctrl-g / cancel)
    166    def ask_yes_or_no question
    167      case(r = ask_getch question, "ynYN")
    168 -    when ?y, ?Y
    169 +    when ?y.ord, ?Y.ord
    170        true
    171      when nil
    172        nil
    173 -- 
    174 1.6.3.3
    175 
    176 
    177 From pi+sup@pihost.us  Fri Jan  1 15:59:02 2010
    178 From: pi+sup@pihost.us (Anthony Martinez)
    179 Date: Fri, 01 Jan 2010 13:59:02 -0700
    180 Subject: [sup-devel] [PATCH 01/10] open mail source files as binary
    181 In-Reply-To: <1262302618-20503-2-git-send-email-rlane@club.cc.cmu.edu>
    182 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    183 	<1262302618-20503-2-git-send-email-rlane@club.cc.cmu.edu>
    184 Message-ID: <1262378704-sup-5011@home.mrtheplague.net>
    185 
    186 Excerpts from Rich Lane's message of Thu Dec 31 16:36:49 -0700 2009:
    187 > diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
    188 > index c2bd27a..0852576 100644
    189 > --- a/lib/sup/maildir.rb
    190 > +++ b/lib/sup/maildir.rb
    191 > @@ -59,7 +59,7 @@ class Maildir < Source
    192 >          File.stat(tmp_path)
    193 >        rescue Errno::ENOENT #this is what we want.
    194 >          begin
    195 > -          File.open(tmp_path, 'w') do |f|
    196 > +          File.open(tmp_path, 'wb:BINARY') do |f|
    197 >              yield f #provide a writable interface for the caller
    198 
    199 This patch causes the following warning on Ruby 1.8:
    200 warning: encoding options not supported in 1.8: wb:BINARY
    201 
    202 Especially if you use Maildir for a source, the resulting torrent of warnings
    203 makes Sup a bit difficult to use.
    204 
    205 I've gone and reverted this diff locally for now. I suppose I could also stop
    206 running sup with the -w flag...
    207 
    208 From sup-bugs@masanjin.net  Fri Jan  1 16:38:15 2010
    209 From: sup-bugs@masanjin.net (anonymous)
    210 Date: Fri, 01 Jan 2010 21:38:15 +0000
    211 Subject: [sup-devel] [issue41] killed threads don't show up in search
    212 In-Reply-To: <1262381895.96.0.844866246353.issue41@masanjin.net>
    213 Message-ID: <1262381895.96.0.844866246353.issue41@masanjin.net>
    214 
    215 
    216 New submission from anonymous:
    217 
    218 Killing threads works, but 'L' will only list the number of killed threads, when 
    219 I navigate to the search it won't show anything. Same goes for a search: 
    220 label:killed
    221 
    222 This is using Xapian
    223 
    224 ----------
    225 messages: 103
    226 nosy: anonymous
    227 priority: bug
    228 ruby_version: 1.8.7
    229 status: unread
    230 sup_version: sup 0.9.1
    231 title: killed threads don't show up in search
    232 
    233 _________________________________________
    234 Sup issue tracker <sup-bugs at masanjin.net>
    235 <http://masanjin.net/sup-bugs/issue41>
    236 _________________________________________
    237 
    238 From wmorgan-sup@masanjin.net  Fri Jan  1 16:43:13 2010
    239 From: wmorgan-sup@masanjin.net (William Morgan)
    240 Date: Fri, 01 Jan 2010 13:43:13 -0800
    241 Subject: [sup-devel] [PATCH 01/10] open mail source files as binary
    242 In-Reply-To: <1262378704-sup-5011@home.mrtheplague.net>
    243 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    244 	<1262302618-20503-2-git-send-email-rlane@club.cc.cmu.edu>
    245 	<1262378704-sup-5011@home.mrtheplague.net>
    246 Message-ID: <1262382164-sup-4751@masanjin.net>
    247 
    248 Reformatted excerpts from Anthony Martinez's message of 2010-01-01:
    249 > Especially if you use Maildir for a source, the resulting torrent of
    250 > warnings makes Sup a bit difficult to use.
    251 > 
    252 > I've gone and reverted this diff locally for now. I suppose I could
    253 > also stop running sup with the -w flag...
    254 
    255 I'm happy with either wrapping that whole thing in a RUBY_VERSION test,
    256 or mandating that thou shalt not run sup with -w. Votes?
    257 -- 
    258 William <wmorgan-sup at masanjin.net>
    259 
    260 From rlane@club.cc.cmu.edu  Fri Jan  1 16:44:34 2010
    261 From: rlane@club.cc.cmu.edu (Rich Lane)
    262 Date: Fri,  1 Jan 2010 13:44:34 -0800
    263 Subject: [sup-devel] [PATCH] xapian: respect :skip_killed in
    264 	each_message_in_thread_for
    265 Message-ID: <1262382274-24324-1-git-send-email-rlane@club.cc.cmu.edu>
    266 
    267 ---
    268  lib/sup/xapian_index.rb |    2 +-
    269  1 files changed, 1 insertions(+), 1 deletions(-)
    270 
    271 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
    272 index cebb148..955ec8f 100644
    273 --- a/lib/sup/xapian_index.rb
    274 +++ b/lib/sup/xapian_index.rb
    275 @@ -127,7 +127,7 @@ EOS
    276      while not queue.empty?
    277        thread_id = queue.pop
    278        next if seen_threads.member? thread_id
    279 -      return false if thread_killed? thread_id
    280 +      return false if opts[:skip_killed] && thread_killed?(thread_id)
    281        seen_threads << thread_id
    282        docs = term_docids(mkterm(:thread, thread_id)).map { |x| @xapian.document x }
    283        docs.each do |doc|
    284 -- 
    285 1.6.3.3
    286 
    287 
    288 From sup-bugs@masanjin.net  Fri Jan  1 16:46:33 2010
    289 From: sup-bugs@masanjin.net (anonymous)
    290 Date: Fri, 01 Jan 2010 21:46:33 +0000
    291 Subject: [sup-devel] [issue42] --all-sources needs specifying of at least
    292 	one source to	work
    293 In-Reply-To: <1262382393.53.0.979430173798.issue42@masanjin.net>
    294 Message-ID: <1262382393.53.0.979430173798.issue42@masanjin.net>
    295 
    296 
    297 New submission from anonymous:
    298 
    299 sup-tweak-labels -r killed --all-sources
    300 Error: no sources specified.
    301 Try --help for help.
    302 
    303 or
    304 
    305 sup-tweak-labels all-sources -r killed
    306 which: no gpg in 
    307 (/bin:/usr/bin:/sbin:/usr/sbin:/opt/kde/bin:/usr/bin/perlbin/site:/usr/bin/perlbi
    308 n/vendor:/usr/bin/perlbin/core:/opt/qt/bin)
    309 Error: Unknown source: all-sources. Did you add it with sup-add first?.
    310 Try --help for help.
    311 
    312 It's a bit annoying to have to specify an existing source to have --all-sources 
    313 work.
    314 
    315 ----------
    316 messages: 104
    317 nosy: anonymous
    318 priority: bug
    319 ruby_version: 1.8.7
    320 status: unread
    321 sup_version: 0.9.1
    322 title: --all-sources needs specifying of at least one source to work
    323 
    324 _________________________________________
    325 Sup issue tracker <sup-bugs at masanjin.net>
    326 <http://masanjin.net/sup-bugs/issue42>
    327 _________________________________________
    328 
    329 From rlane@club.cc.cmu.edu  Fri Jan  1 16:48:29 2010
    330 From: rlane@club.cc.cmu.edu (Rich Lane)
    331 Date: Fri, 01 Jan 2010 16:48:29 -0500
    332 Subject: [sup-devel] [PATCH 01/10] open mail source files as binary
    333 In-Reply-To: <1262382164-sup-4751@masanjin.net>
    334 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    335 	<1262302618-20503-2-git-send-email-rlane@club.cc.cmu.edu>
    336 	<1262378704-sup-5011@home.mrtheplague.net>
    337 	<1262382164-sup-4751@masanjin.net>
    338 Message-ID: <1262382312-sup-2326@zyrg.net>
    339 
    340 Excerpts from William Morgan's message of Fri Jan 01 16:43:13 -0500 2010:
    341 > Reformatted excerpts from Anthony Martinez's message of 2010-01-01:
    342 > > Especially if you use Maildir for a source, the resulting torrent of
    343 > > warnings makes Sup a bit difficult to use.
    344 > > 
    345 > > I've gone and reverted this diff locally for now. I suppose I could
    346 > > also stop running sup with the -w flag...
    347 > 
    348 > I'm happy with either wrapping that whole thing in a RUBY_VERSION test,
    349 > or mandating that thou shalt not run sup with -w. Votes?
    350 
    351 It doesn't sound very useful to have -w writing messages to the screen
    352 in an ncurses app. Could you redirect stderr to a file instead? Is it
    353 possible to do this from inside Sup?
    354 
    355 That warning's existence annoys me. I thought it was a feature that Ruby
    356 1.8 ignored the encoding in the mode string.
    357 
    358 From wmorgan-sup@masanjin.net  Fri Jan  1 16:57:33 2010
    359 From: wmorgan-sup@masanjin.net (William Morgan)
    360 Date: Fri, 01 Jan 2010 13:57:33 -0800
    361 Subject: [sup-devel] [PATCH 01/10] open mail source files as binary
    362 In-Reply-To: <1262382312-sup-2326@zyrg.net>
    363 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    364 	<1262302618-20503-2-git-send-email-rlane@club.cc.cmu.edu>
    365 	<1262378704-sup-5011@home.mrtheplague.net>
    366 	<1262382164-sup-4751@masanjin.net> <1262382312-sup-2326@zyrg.net>
    367 Message-ID: <1262382906-sup-5813@masanjin.net>
    368 
    369 Reformatted excerpts from Rich Lane's message of 2010-01-01:
    370 > It doesn't sound very useful to have -w writing messages to the screen
    371 > in an ncurses app. Could you redirect stderr to a file instead? Is it
    372 > possible to do this from inside Sup?
    373 
    374 Some experimentation suggests we can do
    375   $stderr = File.open(File.join(BASE_DIR, "warnings.txt"), "w")
    376 
    377 and subsequent warns go to that file. At least, it works in irb.
    378 
    379 > That warning's existence annoys me. I thought it was a feature that
    380 > Ruby 1.8 ignored the encoding in the mode string.
    381 
    382 Yeah, lame.
    383 -- 
    384 William <wmorgan-sup at masanjin.net>
    385 
    386 From rlane@club.cc.cmu.edu  Fri Jan  1 17:14:00 2010
    387 From: rlane@club.cc.cmu.edu (Rich Lane)
    388 Date: Fri,  1 Jan 2010 14:14:00 -0800
    389 Subject: [sup-devel] [PATCH] ruby 1.9: expect nil start_offset when an
    390 	MBox::Loader is first created
    391 Message-ID: <1262384040-27801-1-git-send-email-rlane@club.cc.cmu.edu>
    392 
    393 Various callers (including sup-add) passed a nil start_offset. Through a
    394 convoluted path probably involving the fact that nil.to_i == 0, this did the
    395 right thing on Ruby 1.8. It crashes on 1.9, so change initialize to expect a
    396 nil offset and replace it with 0.
    397 ---
    398  lib/sup/mbox/loader.rb |    3 ++-
    399  1 files changed, 2 insertions(+), 1 deletions(-)
    400 
    401 diff --git a/lib/sup/mbox/loader.rb b/lib/sup/mbox/loader.rb
    402 index 520e2ec..54d227d 100644
    403 --- a/lib/sup/mbox/loader.rb
    404 +++ b/lib/sup/mbox/loader.rb
    405 @@ -12,7 +12,7 @@ class Loader < Source
    406    attr_reader :labels
    407  
    408    ## uri_or_fp is horrific. need to refactor.
    409 -  def initialize uri_or_fp, start_offset=0, usual=true, archived=false, id=nil, labels=nil
    410 +  def initialize uri_or_fp, start_offset=nil, usual=true, archived=false, id=nil, labels=nil
    411      @mutex = Mutex.new
    412      @labels = Set.new((labels || []) - LabelManager::RESERVED_LABELS)
    413  
    414 @@ -29,6 +29,7 @@ class Loader < Source
    415        @path = uri_or_fp.path
    416      end
    417  
    418 +    start_offset ||= 0
    419      super uri_or_fp, start_offset, usual, archived, id
    420    end
    421  
    422 -- 
    423 1.6.3.3
    424 
    425 
    426 From pi+sup@pihost.us  Fri Jan  1 20:16:20 2010
    427 From: pi+sup@pihost.us (Anthony Martinez)
    428 Date: Fri, 01 Jan 2010 18:16:20 -0700
    429 Subject: [sup-devel] [PATCH 01/10] open mail source files as binary
    430 In-Reply-To: <1262382164-sup-4751@masanjin.net>
    431 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    432 	<1262302618-20503-2-git-send-email-rlane@club.cc.cmu.edu>
    433 	<1262378704-sup-5011@home.mrtheplague.net>
    434 	<1262382164-sup-4751@masanjin.net>
    435 Message-ID: <1262394142-sup-2602@home.mrtheplague.net>
    436 
    437 Excerpts from William Morgan's message of Fri Jan 01 14:43:13 -0700 2010:
    438 > Reformatted excerpts from Anthony Martinez's message of 2010-01-01:
    439 > > Especially if you use Maildir for a source, the resulting torrent of
    440 > > warnings makes Sup a bit difficult to use.
    441 > > 
    442 > > I've gone and reverted this diff locally for now. I suppose I could
    443 > > also stop running sup with the -w flag...
    444 > 
    445 > I'm happy with either wrapping that whole thing in a RUBY_VERSION test,
    446 > or mandating that thou shalt not run sup with -w. Votes?
    447 
    448 Well... the only reason I ran it with warnings enabled to begin with:
    449 
    450 $ ack -a --nogroup ' -w'
    451 HACKING:6:  ruby -I lib -w bin/sup
    452 
    453 I think redirecting stderr to .sup/warnings is the way to go.
    454 
    455 From rlane@club.cc.cmu.edu  Fri Jan  1 22:30:40 2010
    456 From: rlane@club.cc.cmu.edu (Rich Lane)
    457 Date: Fri,  1 Jan 2010 19:30:40 -0800
    458 Subject: [sup-devel] [PATCH] switch default index to Xapian
    459 Message-ID: <1262403040-24105-1-git-send-email-rlane@club.cc.cmu.edu>
    460 
    461 Previous versions didn't add an :index entry in config.yaml, so preserve
    462 compatibility by using Ferret if no index is specified and the ferret directory
    463 exists.
    464 ---
    465 This patch is meant for 0.10.
    466 
    467 AFAIK the xapian index has feature-parity with ferret. There are a couple of
    468 issues remaining with queries:
    469 
    470 Names are stemmed and otherwise munged for convenient searching by
    471 Xapian::TermGenerator, while email addresses are stored verbatim.
    472 Xapian::QueryParser needs to do the same alterations to search terms, so the
    473 parser uses separate from_{name,email} fields. This is not user-friendly but
    474 could be worked around by having parse_query insert an OR over both fields
    475 where it sees a from: prefix (same for to).
    476 
    477 A more pernicious issue is that QueryParser defaults to AND if there isn't an
    478 explicit operator (which is what we want), but if there are multiple boolean
    479 (label/email) terms over the same field it will OR them. So, "label:sup
    480 label:patch" will result in the union instead of the intersection. Assuming we
    481 don't want to write our own query parser, this needs to be made configurable in
    482 Xapian. I took a stab at it a few months ago but didn't get anywhere.
    483 
    484 There's also the issue of long delays when flushing the index to disk on exit.
    485 One option is to keep the delay and log an info message saying what's going on.
    486 A second option is to set the XAPIAN_FLUSH_THRESHOLD environment variable to
    487 something low in bin/sup, which will limit the final delay but potentially
    488 cause short delays during normal use. A third option is to detect when the user
    489 has been idle for a while and flush the index then.
    490 
    491 We can easily fix the first and third issues before 0.10. Are there any others
    492 I've forgotten?
    493 
    494  lib/sup.rb       |    5 +++--
    495  lib/sup/index.rb |    2 +-
    496  2 files changed, 4 insertions(+), 3 deletions(-)
    497 
    498 diff --git a/lib/sup.rb b/lib/sup.rb
    499 index 144f5e3..fa19de2 100644
    500 --- a/lib/sup.rb
    501 +++ b/lib/sup.rb
    502 @@ -54,7 +54,7 @@ module Redwood
    503    YAML_DOMAIN = "masanjin.net"
    504    YAML_DATE = "2006-10-01"
    505  
    506 -  DEFAULT_INDEX = 'ferret'
    507 +  DEFAULT_INDEX = 'xapian'
    508  
    509    ## record exceptions thrown in threads nicely
    510    @exceptions = []
    511 @@ -229,7 +229,8 @@ else
    512      :confirm_top_posting => true,
    513      :discard_snippets_from_encrypted_messages => false,
    514      :default_attachment_save_dir => "",
    515 -    :sent_source => "sup://sent"
    516 +    :sent_source => "sup://sent",
    517 +    :index => Redwood::DEFAULT_INDEX,
    518    }
    519    begin
    520      FileUtils.mkdir_p Redwood::BASE_DIR
    521 diff --git a/lib/sup/index.rb b/lib/sup/index.rb
    522 index 87d8d52..cc78292 100644
    523 --- a/lib/sup/index.rb
    524 +++ b/lib/sup/index.rb
    525 @@ -174,7 +174,7 @@ class BaseIndex
    526    end
    527  end
    528  
    529 -index_name = ENV['SUP_INDEX'] || $config[:index] || DEFAULT_INDEX
    530 +index_name = ENV['SUP_INDEX'] || $config[:index] || (File.exists?(File.join(BASE_DIR, 'ferret')) ? 'ferret' : DEFAULT_INDEX)
    531  case index_name
    532    when "xapian"; require "sup/xapian_index"
    533    when "ferret"; require "sup/ferret_index"
    534 -- 
    535 1.6.3.3
    536 
    537 
    538 From rlane@club.cc.cmu.edu  Fri Jan  1 23:37:26 2010
    539 From: rlane@club.cc.cmu.edu (Rich Lane)
    540 Date: Fri,  1 Jan 2010 20:37:26 -0800
    541 Subject: [sup-devel] [PATCH] xapian: translate from/to query term prefixes
    542 	to search over both name and email fields
    543 Message-ID: <1262407046-2029-1-git-send-email-rlane@club.cc.cmu.edu>
    544 
    545 ---
    546  lib/sup/xapian_index.rb |   19 ++++++++++++-------
    547  1 files changed, 12 insertions(+), 7 deletions(-)
    548 
    549 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
    550 index cebb148..c192b26 100644
    551 --- a/lib/sup/xapian_index.rb
    552 +++ b/lib/sup/xapian_index.rb
    553 @@ -159,14 +159,15 @@ EOS
    554  
    555      subs = HookManager.run("custom-search", :subs => s) || s
    556      subs = subs.gsub(/\b(to|from):(\S+)\b/) do
    557 -      field, name = $1, $2
    558 -      if(p = ContactManager.contact_for(name))
    559 -        [field, p.email]
    560 -      elsif name == "me"
    561 -        [field, "(" + AccountManager.user_emails.join("||") + ")"]
    562 +      field, value = $1, $2
    563 +      email_field, name_field = %w(email name).map { |x| "#{field}_#{x}" }
    564 +      if(p = ContactManager.contact_for(value))
    565 +        "#{email_field}:#{p.email}"
    566 +      elsif value == "me"
    567 +        '(' + AccountManager.user_emails.map { |e| "#{email_field}:#{e}" }.join(' OR ') + ')'
    568        else
    569 -        [field, name]
    570 -      end.join(":")
    571 +        "(#{email_field}:#{value} OR #{name_field}:#{value})"
    572 +      end
    573      end
    574  
    575      ## if we see a label:deleted or a label:spam term anywhere in the query
    576 @@ -250,6 +251,8 @@ EOS
    577        end
    578      end
    579  
    580 +    debug "translated query: #{subs.inspect}"
    581 +
    582      qp = Xapian::QueryParser.new
    583      qp.database = @xapian
    584      qp.stemmer = Xapian::Stem.new(STEM_LANGUAGE)
    585 @@ -260,6 +263,8 @@ EOS
    586      BOOLEAN_PREFIX.each { |k,v| qp.add_boolean_prefix k, v }
    587      xapian_query = qp.parse_query(subs, Xapian::QueryParser::FLAG_PHRASE|Xapian::QueryParser::FLAG_BOOLEAN|Xapian::QueryParser::FLAG_LOVEHATE|Xapian::QueryParser::FLAG_WILDCARD, PREFIX['body'])
    588  
    589 +    debug "parsed xapian query: #{xapian_query.description}"
    590 +
    591      raise ParseError if xapian_query.nil? or xapian_query.empty?
    592      query[:qobj] = xapian_query
    593      query[:text] = s
    594 -- 
    595 1.6.3.3
    596 
    597 
    598 From hyperbolist@gmail.com  Sat Jan  2 00:14:05 2010
    599 From: hyperbolist@gmail.com (Eric Sherman)
    600 Date: Sat, 02 Jan 2010 00:14:05 -0500
    601 Subject: [sup-devel] [PATCH] fixed am/pm display for ruby 1.8 darwin (v2)
    602 Message-ID: <1262409241-sup-3697@changeling.local>
    603 
    604 ---
    605  lib/sup/util.rb |    4 ++--
    606  1 files changed, 2 insertions(+), 2 deletions(-)
    607 
    608 diff --git a/lib/sup/util.rb b/lib/sup/util.rb
    609 index c27e527..206c18a 100644
    610 --- a/lib/sup/util.rb
    611 +++ b/lib/sup/util.rb
    612 @@ -513,9 +513,9 @@ class Time
    613        strftime "%b %e"
    614      else
    615        if is_the_same_day? from
    616 -        strftime("%l:%M%P")
    617 +        strftime("%l:%M%p").downcase # emulate %P (missing on ruby 1.8 darwin)
    618        elsif is_the_day_before? from
    619 -        "Yest."  + nearest_hour.strftime("%l%P")
    620 +        "Yest."  + nearest_hour.strftime("%l%p").downcase # emulate %P
    621        else
    622          strftime "%b %e"
    623        end
    624 -- 
    625 1.6.5.7
    626 
    627 From bburky@bburky.com  Sat Jan  2 00:59:08 2010
    628 From: bburky@bburky.com (Blake Burkhart)
    629 Date: Fri, 01 Jan 2010 23:59:08 -0600
    630 Subject: [sup-devel] [PATCH] fixed am/pm in thread-list-mode for ruby1.8
    631 In-Reply-To: <1262358668-sup-7399@masanjin.net>
    632 References: <1262270484-sup-8396@changeling.local>
    633 	<1262289195-sup-4420@masanjin.net>
    634 	<1262289317-sup-7991@changeling.local>
    635 	<1262290432-sup-9868@masanjin.net>
    636 	<1262293338-sup-9364@changeling.local>
    637 	<1262294449-sup-8418@localdomain>
    638 	<1262297415-sup-6997@changeling.local>
    639 	<1262358668-sup-7399@masanjin.net>
    640 Message-ID: <1262410432-sup-3347@Backspace.local>
    641 
    642 Excerpts from William Morgan's message of Fri Jan 01 09:13:08 -0600 2010:
    643 > Reformatted excerpts from Eric Sherman's message of 2009-12-31:
    644 > > Hmm.  Maybe this issue only exists on OSX.
    645 > 
    646 > I suspect so. Can you provide a patch that uses the downcase trick and
    647 > doesn't check for the ruby version or the OS? (Maybe with a helpful
    648 > comment.) That should work everywhere, lame as it may be.
    649 
    650 I don't know if you need any more examples of this, but I'm running Mac OS
    651 10.6, and can reproduce this with the three different versions of ruby I
    652 happen to have installed.
    653 
    654 Apple supplied ruby:
    655 $ /usr/bin/ruby --version
    656 ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]
    657 $ /usr/bin/ruby -e 'puts Time.now().strftime("%l:%M%P")'
    658 11:27P
    659 
    660 Ruby from the MacPorts package manager, patchlevel 174:
    661 $ ruby --version
    662 ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
    663 $ ruby -e 'puts Time.now().strftime("%l:%M%P")'
    664 11:25P
    665 
    666 And [MacRuby][1], which is completely beta everything, but is 1.9:
    667 $ macruby --version
    668 MacRuby version 0.5 (ruby 1.9.0) [universal-darwin10.0, x86_64]
    669 $ macruby -e 'puts Time.now().strftime("%l:%M%P")'
    670 11:25P
    671 
    672 I'm pretty sure that *should* work on MacRuby, but it's not. I think that's
    673 possibly their fault though. I guess I could report it as a bug to them then.
    674 I'm not really using that ruby version for anything, so I don't know how
    675 complete it is.
    676 
    677 [1]: http://www.macruby.org/
    678 
    679 -- 
    680 Blake Burkhart
    681 
    682 From hyperbolist@gmail.com  Sat Jan  2 01:13:50 2010
    683 From: hyperbolist@gmail.com (Eric Sherman)
    684 Date: Sat, 02 Jan 2010 01:13:50 -0500
    685 Subject: [sup-devel] [PATCH] fixed am/pm in thread-list-mode for ruby1.8
    686 In-Reply-To: <1262410432-sup-3347@Backspace.local>
    687 References: <1262270484-sup-8396@changeling.local>
    688 	<1262289195-sup-4420@masanjin.net>
    689 	<1262289317-sup-7991@changeling.local>
    690 	<1262290432-sup-9868@masanjin.net>
    691 	<1262293338-sup-9364@changeling.local>
    692 	<1262294449-sup-8418@localdomain>
    693 	<1262297415-sup-6997@changeling.local>
    694 	<1262358668-sup-7399@masanjin.net>
    695 	<1262410432-sup-3347@Backspace.local>
    696 Message-ID: <1262412365-sup-4135@changeling.local>
    697 
    698 Excerpts from Blake Burkhart's message of Sat Jan 02 00:59:08 -0500 2010:
    699 > Excerpts from William Morgan's message of Fri Jan 01 09:13:08 -0600 2010:
    700 > > I suspect so. Can you provide a patch that uses the downcase trick and
    701 > > doesn't check for the ruby version or the OS? (Maybe with a helpful
    702 > > comment.) That should work everywhere, lame as it may be.
    703 > 
    704 > And [MacRuby][1], which is completely beta everything, but is 1.9:
    705 > $ macruby --version
    706 > MacRuby version 0.5 (ruby 1.9.0) [universal-darwin10.0, x86_64]
    707 > $ macruby -e 'puts Time.now().strftime("%l:%M%P")'
    708 > 11:25P
    709 > 
    710 > I'm pretty sure that *should* work on MacRuby, but it's not. I think that's
    711 > possibly their fault though. I guess I could report it as a bug to them then.
    712 > I'm not really using that ruby version for anything, so I don't know how
    713 > complete it is.
    714 > 
    715 > [1]: http://www.macruby.org/
    716 
    717 I've resubmitted the patch in a new thread titled "[PATCH] fixed am/pm 
    718 display for ruby 1.8 darwin (v2)", but like William says it should work 
    719 everywhere including MacRuby because it just emulate's %P by downcase()ing 
    720 %p.
    721 
    722 From rlane@club.cc.cmu.edu  Sat Jan  2 11:42:15 2010
    723 From: rlane@club.cc.cmu.edu (Rich Lane)
    724 Date: Sat,  2 Jan 2010 08:42:15 -0800
    725 Subject: [sup-devel] [PATCH] force binary encoding before parsing decrypted
    726 	messages
    727 Message-ID: <1262450535-5439-1-git-send-email-rlane@club.cc.cmu.edu>
    728 
    729 ---
    730  lib/sup/crypto.rb |    2 ++
    731  1 files changed, 2 insertions(+), 0 deletions(-)
    732 
    733 diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
    734 index fb2661a..91652c7 100644
    735 --- a/lib/sup/crypto.rb
    736 +++ b/lib/sup/crypto.rb
    737 @@ -130,6 +130,7 @@ class CryptoManager
    738      end
    739  
    740      output = IO.read output_fn.path
    741 +    output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
    742  
    743      ## there's probably a better way to do this, but we're using the output to
    744      ## look for a valid signature being present.
    745 @@ -157,6 +158,7 @@ class CryptoManager
    746      msg = RMail::Parser.read output
    747      if msg.header.content_type =~ %r{^multipart/} && !msg.multipart?
    748        output = "MIME-Version: 1.0\n" + output
    749 +      output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
    750        msg = RMail::Parser.read output
    751      end
    752      notice = Chunk::CryptoNotice.new :valid, "This message has been decrypted for display"
    753 -- 
    754 1.6.3.3
    755 
    756 
    757 From rlane@club.cc.cmu.edu  Sat Jan  2 18:50:00 2010
    758 From: rlane@club.cc.cmu.edu (Rich Lane)
    759 Date: Sat,  2 Jan 2010 15:50:00 -0800
    760 Subject: [sup-devel] [PATCH] support high colors in colors.yaml
    761 Message-ID: <1262476200-25885-1-git-send-email-rlane@club.cc.cmu.edu>
    762 
    763 Add constants for colors >15 so that they can be used in the colors config
    764 file. You can use integers for all available colors. If you're running
    765 xterm-256color or compatible you can use "cXYZ" for the 6x6x6 color cube and
    766 "gXY" for grayscale.
    767 ---
    768 Using `tput` might be bad if we support any platforms that don't have it.
    769 Somebody with more artistic talent should submit a nice colorscheme for
    770 contrib/.
    771 
    772  lib/sup/colormap.rb |   34 +++++++++++++++++++++++-----------
    773  1 files changed, 23 insertions(+), 11 deletions(-)
    774 
    775 diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
    776 index c4a4024..dcae2d5 100644
    777 --- a/lib/sup/colormap.rb
    778 +++ b/lib/sup/colormap.rb
    779 @@ -1,5 +1,23 @@
    780  module Curses
    781    COLOR_DEFAULT = -1
    782 +
    783 +  NUM_COLORS = `tput colors`.to_i
    784 +  MAX_PAIRS = `tput pairs`.to_i
    785 +
    786 +  def self.color! name, value
    787 +    const_set "COLOR_#{name.to_s.upcase}", value
    788 +  end
    789 +
    790 +  ## numeric colors
    791 +  0.upto(Curses::NUM_COLORS) { |x| color! x, x }
    792 +
    793 +  if Curses::NUM_COLORS == 256
    794 +    ## xterm 6x6x6 color cube
    795 +    0.upto(5) { |x| 0.upto(5) { |y| 0.upto(5) { |z| color! "c#{x}#{y}#{z}", 16 + z + 6*y + 36*x } } }
    796 +
    797 +    ## xterm 6x6 grayscale
    798 +    0.upto(5) { |x| 0.upto(5) { |y| color! "g#{x}#{y}", (16+6*6*6) + y + 6*x } }
    799 +  end
    800  end
    801  
    802  module Redwood
    803 @@ -7,12 +25,6 @@ module Redwood
    804  class Colormap
    805    @@instance = nil
    806  
    807 -  CURSES_COLORS = [Curses::COLOR_BLACK, Curses::COLOR_RED, Curses::COLOR_GREEN,
    808 -                   Curses::COLOR_YELLOW, Curses::COLOR_BLUE,
    809 -                   Curses::COLOR_MAGENTA, Curses::COLOR_CYAN,
    810 -                   Curses::COLOR_WHITE, Curses::COLOR_DEFAULT]
    811 -  NUM_COLORS = (CURSES_COLORS.size - 1) * (CURSES_COLORS.size - 1)
    812 -
    813    DEFAULT_COLORS = {
    814      :status => { :fg => "white", :bg => "blue", :attrs => ["bold"] },
    815      :index_old => { :fg => "white", :bg => "default" },
    816 @@ -68,8 +80,8 @@ class Colormap
    817  
    818    def add sym, fg, bg, attr=nil, opts={}
    819      raise ArgumentError, "color for #{sym} already defined" if @entries.member? sym
    820 -    raise ArgumentError, "color '#{fg}' unknown" unless CURSES_COLORS.include? fg
    821 -    raise ArgumentError, "color '#{bg}' unknown" unless CURSES_COLORS.include? bg
    822 +    raise ArgumentError, "color '#{fg}' unknown" unless (-1...Curses::NUM_COLORS).include? fg
    823 +    raise ArgumentError, "color '#{bg}' unknown" unless (-1...Curses::NUM_COLORS).include? bg
    824      attrs = [attr].flatten.compact
    825  
    826      @entries[sym] = [fg, bg, attrs, nil]
    827 @@ -127,7 +139,7 @@ class Colormap
    828      if(cp = @color_pairs[[fg, bg]])
    829        ## nothing
    830      else ## need to get a new colorpair
    831 -      @next_id = (@next_id + 1) % NUM_COLORS
    832 +      @next_id = (@next_id + 1) % Curses::MAX_PAIRS
    833        @next_id += 1 if @next_id == 0 # 0 is always white on black
    834        id = @next_id
    835        debug "colormap: for color #{sym}, using id #{id} -> #{fg}, #{bg}"
    836 @@ -169,7 +181,7 @@ class Colormap
    837        if user_colors && (ucolor = user_colors[k])
    838          if(ufg = ucolor[:fg])
    839            begin
    840 -            fg = Curses.const_get "COLOR_#{ufg.upcase}"
    841 +            fg = Curses.const_get "COLOR_#{ufg.to_s.upcase}"
    842            rescue NameError
    843              error ||= "Warning: there is no color named \"#{ufg}\", using fallback."
    844              warn "there is no color named \"#{ufg}\""
    845 @@ -178,7 +190,7 @@ class Colormap
    846  
    847          if(ubg = ucolor[:bg])
    848            begin
    849 -            bg = Curses.const_get "COLOR_#{ubg.upcase}"
    850 +            bg = Curses.const_get "COLOR_#{ubg.to_s.upcase}"
    851            rescue NameError
    852              error ||= "Warning: there is no color named \"#{ubg}\", using fallback."
    853              warn "there is no color named \"#{ubg}\""
    854 -- 
    855 1.6.3.3
    856 
    857 
    858 From wmorgan-sup@masanjin.net  Sun Jan  3 09:48:22 2010
    859 From: wmorgan-sup@masanjin.net (William Morgan)
    860 Date: Sun, 03 Jan 2010 06:48:22 -0800
    861 Subject: [sup-devel] Ruby 1.9 encoding fixes
    862 In-Reply-To: <1262442839-sup-7738@peray>
    863 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
    864 	<1262372864-sup-22@masanjin.net> <1262442839-sup-7738@peray>
    865 Message-ID: <1262530083-sup-8232@masanjin.net>
    866 
    867 Reformatted excerpts from Nicolas Pouillard's message of 2010-01-02:
    868 > Gem files will remain installed in /home/ertai/.gem/ruby/1.8/gems/xapian-full-1.1.3 for inspection.
    869 > Results logged to /home/ertai/.gem/ruby/1.8/gems/xapian-full-1.1.3/gem_make.out
    870 
    871 Anything interested in that file?
    872 -- 
    873 William <wmorgan-sup at masanjin.net>
    874 
    875 From wmorgan-sup@masanjin.net  Sun Jan  3 09:59:09 2010
    876 From: wmorgan-sup@masanjin.net (William Morgan)
    877 Date: Sun, 03 Jan 2010 06:59:09 -0800
    878 Subject: [sup-devel] [PATCH] ruby 1.9: use String#ord in ask_getch and
    879 	ask_yes_or_no
    880 In-Reply-To: <1262378827-16722-1-git-send-email-rlane@club.cc.cmu.edu>
    881 References: <1262378827-16722-1-git-send-email-rlane@club.cc.cmu.edu>
    882 Message-ID: <1262530723-sup-1531@masanjin.net>
    883 
    884 Applied to ruby-1.9.encodings and remerged into next. Thanks!
    885 -- 
    886 William <wmorgan-sup at masanjin.net>
    887 
    888 From wmorgan-sup@masanjin.net  Sun Jan  3 10:00:03 2010
    889 From: wmorgan-sup@masanjin.net (William Morgan)
    890 Date: Sun, 03 Jan 2010 07:00:03 -0800
    891 Subject: [sup-devel] [PATCH] xapian: respect :skip_killed in
    892 	each_message_in_thread_for
    893 In-Reply-To: <1262382274-24324-1-git-send-email-rlane@club.cc.cmu.edu>
    894 References: <1262382274-24324-1-git-send-email-rlane@club.cc.cmu.edu>
    895 Message-ID: <1262530787-sup-4704@masanjin.net>
    896 
    897 Applied directly to master. Thanks!
    898 
    899 -- 
    900 William <wmorgan-sup at masanjin.net>
    901 
    902 From wmorgan-sup@masanjin.net  Sun Jan  3 10:00:21 2010
    903 From: wmorgan-sup@masanjin.net (William Morgan)
    904 Date: Sun, 03 Jan 2010 07:00:21 -0800
    905 Subject: [sup-devel] [PATCH] ruby 1.9: expect nil start_offset when an
    906 	MBox::Loader is first created
    907 In-Reply-To: <1262384040-27801-1-git-send-email-rlane@club.cc.cmu.edu>
    908 References: <1262384040-27801-1-git-send-email-rlane@club.cc.cmu.edu>
    909 Message-ID: <1262530809-sup-2404@masanjin.net>
    910 
    911 Applied directly to master. Thanks!
    912 -- 
    913 William <wmorgan-sup at masanjin.net>
    914 
    915 From rlane@club.cc.cmu.edu  Sun Jan  3 10:10:31 2010
    916 From: rlane@club.cc.cmu.edu (Rich Lane)
    917 Date: Sun, 03 Jan 2010 10:10:31 -0500
    918 Subject: [sup-devel] [PATCH] support high colors in colors.yaml
    919 In-Reply-To: <1262476200-25885-1-git-send-email-rlane@club.cc.cmu.edu>
    920 References: <1262476200-25885-1-git-send-email-rlane@club.cc.cmu.edu>
    921 Message-ID: <1262531429-sup-4730@zyrg.net>
    922 
    923 Excerpts from Rich Lane's message of 2010-01-02 18:50:00 -0500:
    924 > Add constants for colors >15 so that they can be used in the colors config
    925 > file. You can use integers for all available colors. If you're running
    926 > xterm-256color or compatible you can use "cXYZ" for the 6x6x6 color cube and
    927 > "gXY" for grayscale.
    928 
    929 Disregard this patch, grayscale should be one dimensional. I'll send out
    930 a fixed version.
    931 
    932 From wmorgan-sup@masanjin.net  Sun Jan  3 10:14:57 2010
    933 From: wmorgan-sup@masanjin.net (William Morgan)
    934 Date: Sun, 03 Jan 2010 07:14:57 -0800
    935 Subject: [sup-devel] [PATCH] switch default index to Xapian
    936 In-Reply-To: <1262403040-24105-1-git-send-email-rlane@club.cc.cmu.edu>
    937 References: <1262403040-24105-1-git-send-email-rlane@club.cc.cmu.edu>
    938 Message-ID: <1262530826-sup-7476@masanjin.net>
    939 
    940 Reformatted excerpts from Rich Lane's message of 2010-01-01:
    941 > Previous versions didn't add an :index entry in config.yaml, so
    942 > preserve compatibility by using Ferret if no index is specified and
    943 > the ferret directory exists.
    944 
    945 I have done something a little more extensive in the branch
    946 ferret-deprecation, merged into next, so I'm going to drop this patch,
    947 unless you think I missed something.
    948 
    949 The current behavior is:
    950 1. If a Xapian index exists, use Xapian
    951 2. Otherwise, if a Ferret index exists, use Ferret
    952 3. Otherwise (new index), use Xapian.
    953 
    954 The choice is overrideable by the environment variable (which I'd like
    955 to remove at some point), the config option, and a commandline flag
    956 --index added to most things in bin/.
    957 
    958 > Names are stemmed and otherwise munged for convenient searching by
    959 > Xapian::TermGenerator, while email addresses are stored verbatim.
    960 > Xapian::QueryParser needs to do the same alterations to search terms, so the
    961 > parser uses separate from_{name,email} fields. This is not user-friendly but
    962 > could be worked around by having parse_query insert an OR over both fields
    963 > where it sees a from: prefix (same for to).
    964 
    965 I'm fine with this solution. At some point (not necessarily for 0.10)
    966 I'd also like to add more email address munging so that the address
    967 bob at foo.com is matched by bob, foo, foo.com, and bob at foo.com, so maybe
    968 this is an analogous case.
    969 
    970 > A more pernicious issue is that QueryParser defaults to AND if there
    971 > isn't an explicit operator (which is what we want), but if there are
    972 > multiple boolean (label/email) terms over the same field it will OR
    973 > them. So, "label:sup label:patch" will result in the union instead of
    974 > the intersection. Assuming we don't want to write our own query
    975 > parser, this needs to be made configurable in Xapian. I took a stab at
    976 > it a few months ago but didn't get anywhere.
    977 
    978 Ok. Unfortunate, but not a dealbreaker by any means, especially if it's
    979 restricted to emails and labels.
    980 
    981 > There's also the issue of long delays when flushing the index to disk
    982 > on exit.  One option is to keep the delay and log an info message
    983 > saying what's going on.  A second option is to set the
    984 > XAPIAN_FLUSH_THRESHOLD environment variable to something low in
    985 > bin/sup, which will limit the final delay but potentially cause short
    986 > delays during normal use. A third option is to detect when the user
    987 > has been idle for a while and flush the index then.
    988 
    989 This is something I definitely would like to see fixed before 0.10, but
    990 I would be happy with the silly but trivial option #1. (I suspect #2/#3
    991 will require some back-and-forth to get just right.)
    992 
    993 > We can easily fix the first and third issues before 0.10. Are there
    994 > any others I've forgotten?
    995 
    996 There was something with the counts in label-list-mode at some point,
    997 but the whole issue has been swapped out of my head.
    998 
    999 Ultimately getting us out of the world of Ferret is worth almost any
   1000 amount of pain, so, who cares, and, as always, thank you.
   1001 -- 
   1002 William <wmorgan-sup at masanjin.net>
   1003 
   1004 From wmorgan-sup@masanjin.net  Sun Jan  3 10:15:17 2010
   1005 From: wmorgan-sup@masanjin.net (William Morgan)
   1006 Date: Sun, 03 Jan 2010 07:15:17 -0800
   1007 Subject: [sup-devel] [PATCH] fixed am/pm display for ruby 1.8 darwin (v2)
   1008 In-Reply-To: <1262409241-sup-3697@changeling.local>
   1009 References: <1262409241-sup-3697@changeling.local>
   1010 Message-ID: <1262531703-sup-3752@masanjin.net>
   1011 
   1012 Applied directly to master. Thanks!
   1013 -- 
   1014 William <wmorgan-sup at masanjin.net>
   1015 
   1016 From wmorgan-sup@masanjin.net  Sun Jan  3 10:16:03 2010
   1017 From: wmorgan-sup@masanjin.net (William Morgan)
   1018 Date: Sun, 03 Jan 2010 07:16:03 -0800
   1019 Subject: [sup-devel] [PATCH] force binary encoding before parsing
   1020 	decrypted messages
   1021 In-Reply-To: <1262450535-5439-1-git-send-email-rlane@club.cc.cmu.edu>
   1022 References: <1262450535-5439-1-git-send-email-rlane@club.cc.cmu.edu>
   1023 Message-ID: <1262531722-sup-1340@masanjin.net>
   1024 
   1025 Applied to the ruby-1.9-encoding branch, remerged into next. Thanks!
   1026 -- 
   1027 William <wmorgan-sup at masanjin.net>
   1028 
   1029 From rlane@club.cc.cmu.edu  Sun Jan  3 10:24:18 2010
   1030 From: rlane@club.cc.cmu.edu (Rich Lane)
   1031 Date: Sun,  3 Jan 2010 07:24:18 -0800
   1032 Subject: [sup-devel] [PATCHv2 1/3] support high colors in colors.yaml
   1033 Message-ID: <1262532260-18353-1-git-send-email-rlane@club.cc.cmu.edu>
   1034 
   1035 Add constants for colors >15 so that they can be used in the colors config
   1036 file. You can use integers for all available colors. If you're running
   1037 xterm-256color or compatible you can use "cXYZ" for the 6x6x6 color cube and
   1038 "gX" for 24 shades of gray.
   1039 ---
   1040  lib/sup/colormap.rb |   34 +++++++++++++++++++++++-----------
   1041  1 files changed, 23 insertions(+), 11 deletions(-)
   1042 
   1043 diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
   1044 index c4a4024..71c715f 100644
   1045 --- a/lib/sup/colormap.rb
   1046 +++ b/lib/sup/colormap.rb
   1047 @@ -1,5 +1,23 @@
   1048  module Curses
   1049    COLOR_DEFAULT = -1
   1050 +
   1051 +  NUM_COLORS = `tput colors`.to_i
   1052 +  MAX_PAIRS = `tput pairs`.to_i
   1053 +
   1054 +  def self.color! name, value
   1055 +    const_set "COLOR_#{name.to_s.upcase}", value
   1056 +  end
   1057 +
   1058 +  ## numeric colors
   1059 +  Curses::NUM_COLORS.times { |x| color! x, x }
   1060 +
   1061 +  if Curses::NUM_COLORS == 256
   1062 +    ## xterm 6x6x6 color cube
   1063 +    6.times { |x| 6.times { |y| 6.times { |z| color! "c#{x}#{y}#{z}", 16 + z + 6*y + 36*x } } }
   1064 +
   1065 +    ## xterm 24-shade grayscale
   1066 +    24.times { |x| color! "g#{x}", (16+6*6*6) + x }
   1067 +  end
   1068  end
   1069  
   1070  module Redwood
   1071 @@ -7,12 +25,6 @@ module Redwood
   1072  class Colormap
   1073    @@instance = nil
   1074  
   1075 -  CURSES_COLORS = [Curses::COLOR_BLACK, Curses::COLOR_RED, Curses::COLOR_GREEN,
   1076 -                   Curses::COLOR_YELLOW, Curses::COLOR_BLUE,
   1077 -                   Curses::COLOR_MAGENTA, Curses::COLOR_CYAN,
   1078 -                   Curses::COLOR_WHITE, Curses::COLOR_DEFAULT]
   1079 -  NUM_COLORS = (CURSES_COLORS.size - 1) * (CURSES_COLORS.size - 1)
   1080 -
   1081    DEFAULT_COLORS = {
   1082      :status => { :fg => "white", :bg => "blue", :attrs => ["bold"] },
   1083      :index_old => { :fg => "white", :bg => "default" },
   1084 @@ -68,8 +80,8 @@ class Colormap
   1085  
   1086    def add sym, fg, bg, attr=nil, opts={}
   1087      raise ArgumentError, "color for #{sym} already defined" if @entries.member? sym
   1088 -    raise ArgumentError, "color '#{fg}' unknown" unless CURSES_COLORS.include? fg
   1089 -    raise ArgumentError, "color '#{bg}' unknown" unless CURSES_COLORS.include? bg
   1090 +    raise ArgumentError, "color '#{fg}' unknown" unless (-1...Curses::NUM_COLORS).include? fg
   1091 +    raise ArgumentError, "color '#{bg}' unknown" unless (-1...Curses::NUM_COLORS).include? bg
   1092      attrs = [attr].flatten.compact
   1093  
   1094      @entries[sym] = [fg, bg, attrs, nil]
   1095 @@ -127,7 +139,7 @@ class Colormap
   1096      if(cp = @color_pairs[[fg, bg]])
   1097        ## nothing
   1098      else ## need to get a new colorpair
   1099 -      @next_id = (@next_id + 1) % NUM_COLORS
   1100 +      @next_id = (@next_id + 1) % Curses::MAX_PAIRS
   1101        @next_id += 1 if @next_id == 0 # 0 is always white on black
   1102        id = @next_id
   1103        debug "colormap: for color #{sym}, using id #{id} -> #{fg}, #{bg}"
   1104 @@ -169,7 +181,7 @@ class Colormap
   1105        if user_colors && (ucolor = user_colors[k])
   1106          if(ufg = ucolor[:fg])
   1107            begin
   1108 -            fg = Curses.const_get "COLOR_#{ufg.upcase}"
   1109 +            fg = Curses.const_get "COLOR_#{ufg.to_s.upcase}"
   1110            rescue NameError
   1111              error ||= "Warning: there is no color named \"#{ufg}\", using fallback."
   1112              warn "there is no color named \"#{ufg}\""
   1113 @@ -178,7 +190,7 @@ class Colormap
   1114  
   1115          if(ubg = ucolor[:bg])
   1116            begin
   1117 -            bg = Curses.const_get "COLOR_#{ubg.upcase}"
   1118 +            bg = Curses.const_get "COLOR_#{ubg.to_s.upcase}"
   1119            rescue NameError
   1120              error ||= "Warning: there is no color named \"#{ubg}\", using fallback."
   1121              warn "there is no color named \"#{ubg}\""
   1122 -- 
   1123 1.6.3.3
   1124 
   1125 
   1126 From rlane@club.cc.cmu.edu  Sun Jan  3 10:24:19 2010
   1127 From: rlane@club.cc.cmu.edu (Rich Lane)
   1128 Date: Sun,  3 Jan 2010 07:24:19 -0800
   1129 Subject: [sup-devel] [PATCH 2/3] send color errors to the log instead of
   1130 	flashing
   1131 In-Reply-To: <1262532260-18353-1-git-send-email-rlane@club.cc.cmu.edu>
   1132 References: <1262532260-18353-1-git-send-email-rlane@club.cc.cmu.edu>
   1133 Message-ID: <1262532260-18353-2-git-send-email-rlane@club.cc.cmu.edu>
   1134 
   1135 During startup, when these errors are most likely to occur, not enough buffer
   1136 initialization has been done for BufferManager.flash to work.
   1137 ---
   1138  lib/sup/colormap.rb |    2 +-
   1139  1 files changed, 1 insertions(+), 1 deletions(-)
   1140 
   1141 diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
   1142 index 71c715f..d28c550 100644
   1143 --- a/lib/sup/colormap.rb
   1144 +++ b/lib/sup/colormap.rb
   1145 @@ -213,7 +213,7 @@ class Colormap
   1146        add symbol, fg, bg, attrs
   1147      end
   1148  
   1149 -    BufferManager.flash error if error
   1150 +    warn error if error
   1151    end
   1152  
   1153    def self.instance; @@instance; end
   1154 -- 
   1155 1.6.3.3
   1156 
   1157 
   1158 From rlane@club.cc.cmu.edu  Sun Jan  3 10:24:20 2010
   1159 From: rlane@club.cc.cmu.edu (Rich Lane)
   1160 Date: Sun,  3 Jan 2010 07:24:20 -0800
   1161 Subject: [sup-devel] [PATCH 3/3] add keybinding 'Oc' to reload colors
   1162 In-Reply-To: <1262532260-18353-2-git-send-email-rlane@club.cc.cmu.edu>
   1163 References: <1262532260-18353-1-git-send-email-rlane@club.cc.cmu.edu>
   1164 	<1262532260-18353-2-git-send-email-rlane@club.cc.cmu.edu>
   1165 Message-ID: <1262532260-18353-3-git-send-email-rlane@club.cc.cmu.edu>
   1166 
   1167 ---
   1168  bin/sup             |   10 ++++++++++
   1169  lib/sup/colormap.rb |    6 +++++-
   1170  2 files changed, 15 insertions(+), 1 deletions(-)
   1171 
   1172 diff --git a/bin/sup b/bin/sup
   1173 index 5571598..0716e55 100755
   1174 --- a/bin/sup
   1175 +++ b/bin/sup
   1176 @@ -96,6 +96,11 @@ global_keymap = Keymap.new do |k|
   1177    k.add :recall_draft, "Edit most recent draft message", 'R'
   1178    k.add :show_inbox, "Show the Inbox buffer", 'I'
   1179    k.add :show_console, "Show the Console buffer", '~'
   1180 +
   1181 +  ## Submap for less often used keybindings
   1182 +  k.add_multi "reload (c)olors", 'O' do |kk|
   1183 +    kk.add :reload_colors, "Reload colors", 'c'
   1184 +  end
   1185  end
   1186  
   1187  ## the following magic enables wide characters when used with a ruby
   1188 @@ -326,6 +331,11 @@ begin
   1189      when :show_console
   1190        b, new = bm.spawn_unless_exists("Console", :system => true) { ConsoleMode.new }
   1191        b.mode.run
   1192 +    when :reload_colors
   1193 +      Colormap.reset
   1194 +      Colormap.populate_colormap
   1195 +      bm.completely_redraw_screen
   1196 +      bm.flash "reloaded colors"
   1197      when :nothing, InputSequenceAborted
   1198      when :redraw
   1199        bm.completely_redraw_screen
   1200 diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
   1201 index d28c550..6f21f9a 100644
   1202 --- a/lib/sup/colormap.rb
   1203 +++ b/lib/sup/colormap.rb
   1204 @@ -68,11 +68,15 @@ class Colormap
   1205    def initialize
   1206      raise "only one instance can be created" if @@instance
   1207      @@instance = self
   1208 -    @entries = {}
   1209      @color_pairs = {[Curses::COLOR_WHITE, Curses::COLOR_BLACK] => 0}
   1210      @users = []
   1211      @next_id = 0
   1212 +    reset
   1213      yield self if block_given?
   1214 +  end
   1215 +
   1216 +  def reset
   1217 +    @entries = {}
   1218      @entries[highlight_sym(:none)] = highlight_for(Curses::COLOR_WHITE,
   1219                                                     Curses::COLOR_BLACK,
   1220                                                     []) + [nil]
   1221 -- 
   1222 1.6.3.3
   1223 
   1224 
   1225 From wmorgan-sup@masanjin.net  Sun Jan  3 10:27:24 2010
   1226 From: wmorgan-sup@masanjin.net (William Morgan)
   1227 Date: Sun, 03 Jan 2010 07:27:24 -0800
   1228 Subject: [sup-devel] [PATCH] Move the mark-as-spam hook so it runs on
   1229 	all tagged threads.
   1230 In-Reply-To: <1262292330-28131-1-git-send-email-pi+sup@pihost.us>
   1231 References: <1262292330-28131-1-git-send-email-pi+sup@pihost.us>
   1232 Message-ID: <1262532435-sup-3410@masanjin.net>
   1233 
   1234 Applied directly to master. Thanks!
   1235 -- 
   1236 William <wmorgan-sup at masanjin.net>
   1237 
   1238 From rlane@club.cc.cmu.edu  Sun Jan  3 10:33:28 2010
   1239 From: rlane@club.cc.cmu.edu (Rich Lane)
   1240 Date: Sun,  3 Jan 2010 07:33:28 -0800
   1241 Subject: [sup-devel] [PATCH] add a mouse-enabled colorpicker to contrib
   1242 Message-ID: <1262532808-19401-1-git-send-email-rlane@club.cc.cmu.edu>
   1243 
   1244 Intended to make colorscheme creation easier.
   1245 ---
   1246  contrib/colorpicker.rb |  104 ++++++++++++++++++++++++++++++++++++++++++++++++
   1247  1 files changed, 104 insertions(+), 0 deletions(-)
   1248  create mode 100644 contrib/colorpicker.rb
   1249 
   1250 diff --git a/contrib/colorpicker.rb b/contrib/colorpicker.rb
   1251 new file mode 100644
   1252 index 0000000..c981a23
   1253 --- /dev/null
   1254 +++ b/contrib/colorpicker.rb
   1255 @@ -0,0 +1,104 @@
   1256 +require 'rubygems'
   1257 +
   1258 +begin
   1259 +  require 'ncursesw'
   1260 +rescue LoadError
   1261 +  require 'ncurses'
   1262 +end
   1263 +
   1264 +Ncurses.initscr
   1265 +Ncurses.noecho
   1266 +Ncurses.cbreak
   1267 +Ncurses.start_color
   1268 +
   1269 +Ncurses.curs_set 0
   1270 +Ncurses.move 0, 0
   1271 +Ncurses.clear
   1272 +Ncurses.refresh
   1273 +cc = Ncurses.COLORS
   1274 +
   1275 +Ncurses::keypad(Ncurses::stdscr, 1)
   1276 +Ncurses::mousemask(Ncurses::ALL_MOUSE_EVENTS | Ncurses::REPORT_MOUSE_POSITION, [])
   1277 +
   1278 +fail "color count is #{cc}, expected 256" unless cc == 256
   1279 +
   1280 +1.upto(255) do |c|
   1281 +  Ncurses.init_pair(c, 0, c)
   1282 +end
   1283 +
   1284 +def cell y, x, c
   1285 +  @map[[y,x]] = c
   1286 +  Ncurses.attron(Ncurses.COLOR_PAIR(c))
   1287 +  Ncurses.mvaddstr(y, x, " ")
   1288 +  Ncurses.attroff(Ncurses.COLOR_PAIR(c))
   1289 +end
   1290 +
   1291 +def handle_click y, x
   1292 +  c = @map[[y,x]] or return
   1293 +  name = case c
   1294 +  when 0...16
   1295 +    c.to_s
   1296 +  when 16...232
   1297 +    'c' + (c-16).to_s(6).rjust(3,'0')
   1298 +  when 232...256
   1299 +    'g' + (c-232).to_s
   1300 +  end
   1301 +
   1302 +  Ncurses.mvaddstr 11, 0, "#{name}            "
   1303 +
   1304 +  Ncurses.attron(Ncurses.COLOR_PAIR(c))
   1305 +  10.times do |i|
   1306 +    20.times do |j|
   1307 +      y = 13 + i
   1308 +      x = j
   1309 +      Ncurses.mvaddstr(y, x, " ")
   1310 +    end
   1311 +  end
   1312 +  Ncurses.attroff(Ncurses.COLOR_PAIR(c))
   1313 +end
   1314 +
   1315 + at map = {}
   1316 + at fg = @bg = 0
   1317 +
   1318 +begin
   1319 +  16.times do |i|
   1320 +    cell 0, i, i
   1321 +  end
   1322 +
   1323 +  6.times do |i|
   1324 +    6.times do |j|
   1325 +      6.times do |k|
   1326 +        c = 16 + 6*6*i + 6*j + k
   1327 +        y = 2 + j
   1328 +        x = 7*i + k
   1329 +        cell y, x, c
   1330 +      end
   1331 +    end
   1332 +  end
   1333 +
   1334 +  16.times do |i|
   1335 +    c = 16 + 6*6*6 + i
   1336 +    cell 9, i, c
   1337 +  end
   1338 +
   1339 +  handle_click 0, 0
   1340 +  Ncurses.refresh
   1341 +
   1342 +  while (c = Ncurses.getch)
   1343 +    case c
   1344 +    when 113 #q
   1345 +      break
   1346 +    when Ncurses::KEY_MOUSE
   1347 +      mev = Ncurses::MEVENT.new
   1348 +      Ncurses.getmouse(mev)
   1349 +      case(mev.bstate)
   1350 +      when Ncurses::BUTTON1_CLICKED
   1351 +        handle_click mev.y, mev.x
   1352 +      end
   1353 +    end
   1354 +    Ncurses.refresh
   1355 +  end
   1356 +
   1357 +ensure
   1358 +  Ncurses.endwin
   1359 +end
   1360 -- 
   1361 1.6.3.3
   1362 
   1363 
   1364 From nicolas.pouillard@gmail.com  Sun Jan  3 10:48:36 2010
   1365 From: nicolas.pouillard@gmail.com (Nicolas Pouillard)
   1366 Date: Sun, 03 Jan 2010 16:48:36 +0100
   1367 Subject: [sup-devel] Ruby 1.9 encoding fixes
   1368 In-Reply-To: <1262530083-sup-8232@masanjin.net>
   1369 References: <1262302618-20503-1-git-send-email-rlane@club.cc.cmu.edu>
   1370 	<1262372864-sup-22@masanjin.net> <1262442839-sup-7738@peray>
   1371 	<1262530083-sup-8232@masanjin.net>
   1372 Message-ID: <1262533689-sup-7301@peray>
   1373 
   1374 Excerpts from William Morgan's message of Sun Jan 03 15:48:22 +0100 2010:
   1375 > Reformatted excerpts from Nicolas Pouillard's message of 2010-01-02:
   1376 > > Gem files will remain installed in /home/ertai/.gem/ruby/1.8/gems/xapian-full-1.1.3 for inspection.
   1377 > > Results logged to /home/ertai/.gem/ruby/1.8/gems/xapian-full-1.1.3/gem_make.out
   1378 > 
   1379 > Anything interested in that file?
   1380 
   1381 No. But I attach it just in case.
   1382 
   1383 -- 
   1384 Nicolas Pouillard
   1385 http://nicolaspouillard.fr
   1386 -------------- next part --------------
   1387 A non-text attachment was scrubbed...
   1388 Name: gem_make.out.gz
   1389 Type: application/x-gzip
   1390 Size: 25765 bytes
   1391 Desc: not available
   1392 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100103/60c22ca8/attachment-0001.gz>
   1393 
   1394 From eg@gaute.vetsj.com  Sun Jan  3 10:51:55 2010
   1395 From: eg@gaute.vetsj.com (Gaute Hope)
   1396 Date: Sun, 03 Jan 2010 16:51:55 +0100
   1397 Subject: [sup-devel] [issue36] label tab completion with utf-8 chars fail
   1398 In-Reply-To: <1261749755.37.0.845609324711.issue36@masanjin.net>
   1399 References: <1261749755.37.0.845609324711.issue36@masanjin.net>
   1400 Message-ID: <1262533823-sup-5348@dolk>
   1401 
   1402 This goes for tab completion with contacts containing UTF-8 chars.
   1403 Possibly other places as well.
   1404 
   1405 Similar exception, see attached exception log.
   1406 
   1407 - gaute
   1408 
   1409 Excerpts from Gaute Hope's message of 2009-12-25 15:02:35 +0100:
   1410 > 
   1411 > New submission from Gaute Hope <eg at gaute.vetsj.com>:
   1412 > 
   1413 > When trying to label a thread with a label containing unicode chars and pressing 
   1414 > TAB I get this. When typing in the whole label manually it ads it with some 
   1415 > minor glitches in the rendering of the message-line. When restarting sup I get a 
   1416 > one space between the subject and the label that doesn't change background color 
   1417 > when selected.
   1418 > 
   1419 > [2009-12-25 14:51:11 +0100] ERROR: oh crap, an exception
   1420 > ----------------------------------------------------------------
   1421 > I'm very sorry. It seems that an error occurred in Sup. Please
   1422 > accept my sincere apologies. If you don't mind, please send the
   1423 > contents of /home/gaute/.sup/exception-log.txt and a brief report of the
   1424 > circumstances to sup-talk at rubyforge dot orgs so that I might
   1425 > address this problem. Thank you!
   1426 > 
   1427 > Sincerely,
   1428 > William
   1429 > ----------------------------------------------------------------
   1430 > --- Encoding::CompatibilityError from thread: main
   1431 > incompatible encoding regexp match (ASCII-8BIT regexp with UTF-8 string)
   1432 > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:461:in `block (2 levels) in 
   1433 > ask_many_with_completions'
   1434 > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:461:in `select'
   1435 > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:461:in `block in 
   1436 > ask_many_with_completions'
   1437 > /home/gaute/dev/ruby/sup.git/lib/sup/textfield.rb:75:in `call'
   1438 > /home/gaute/dev/ruby/sup.git/lib/sup/textfield.rb:75:in `handle_input'
   1439 > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:572:in `ask'
   1440 > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:450:in 
   1441 > `ask_many_with_completions'
   1442 > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:519:in `ask_for_labels'
   1443 > /home/gaute/dev/ruby/sup.git/lib/sup/util.rb:546:in `method_missing'
   1444 > /home/gaute/dev/ruby/sup.git/lib/sup/modes/thread-index-mode.rb:536:in 
   1445 > `edit_labels'
   1446 > /home/gaute/dev/ruby/sup.git/lib/sup/mode.rb:52:in `handle_input'
   1447 > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:266:in `handle_input'
   1448 > bin/sup:244:in `<module:Redwood>'
   1449 > bin/sup:67:in `<main>'
   1450 > 
   1451 > ----------
   1452 > messages: 97
   1453 > nosy: gauteh
   1454 > priority: bug
   1455 > ruby_version: 1.9.1
   1456 > status: unread
   1457 > sup_version: git
   1458 > title: label tab completion with utf-8 chars fail
   1459 > 
   1460 -------------- next part --------------
   1461 An embedded and charset-unspecified text was scrubbed...
   1462 Name: exception-log.txt
   1463 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100103/3b5c07ca/attachment.txt>
   1464 -------------- next part --------------
   1465 A non-text attachment was scrubbed...
   1466 Name: signature.asc
   1467 Type: application/pgp-signature
   1468 Size: 198 bytes
   1469 Desc: not available
   1470 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100103/3b5c07ca/attachment.bin>
   1471 
   1472 From eg@gaute.vetsj.com  Sun Jan  3 10:56:17 2010
   1473 From: eg@gaute.vetsj.com (Gaute Hope)
   1474 Date: Sun, 03 Jan 2010 16:56:17 +0100
   1475 Subject: [sup-devel] [issue36] label tab completion with utf-8 chars fail
   1476 In-Reply-To: <1262533823-sup-5348@dolk>
   1477 References: <1261749755.37.0.845609324711.issue36@masanjin.net>
   1478 	<1262533823-sup-5348@dolk>
   1479 Message-ID: <1262534029-sup-1213@dolk>
   1480 
   1481 Apparently I can't even send messages when I enter the UTF-8 email address
   1482 manually. sup fails after having edited message and returning to the
   1483 edit message view. Attached is the exception log.
   1484 
   1485 - gaute
   1486 
   1487 Excerpts from Gaute Hope's message of 2010-01-03 16:51:55 +0100:
   1488 > This goes for tab completion with contacts containing UTF-8 chars.
   1489 > Possibly other places as well.
   1490 > 
   1491 > Similar exception, see attached exception log.
   1492 > 
   1493 > - gaute
   1494 > 
   1495 > Excerpts from Gaute Hope's message of 2009-12-25 15:02:35 +0100:
   1496 > > 
   1497 > > New submission from Gaute Hope <eg at gaute.vetsj.com>:
   1498 > > 
   1499 > > When trying to label a thread with a label containing unicode chars and pressing 
   1500 > > TAB I get this. When typing in the whole label manually it ads it with some 
   1501 > > minor glitches in the rendering of the message-line. When restarting sup I get a 
   1502 > > one space between the subject and the label that doesn't change background color 
   1503 > > when selected.
   1504 > > 
   1505 > > [2009-12-25 14:51:11 +0100] ERROR: oh crap, an exception
   1506 > > ----------------------------------------------------------------
   1507 > > I'm very sorry. It seems that an error occurred in Sup. Please
   1508 > > accept my sincere apologies. If you don't mind, please send the
   1509 > > contents of /home/gaute/.sup/exception-log.txt and a brief report of the
   1510 > > circumstances to sup-talk at rubyforge dot orgs so that I might
   1511 > > address this problem. Thank you!
   1512 > > 
   1513 > > Sincerely,
   1514 > > William
   1515 > > ----------------------------------------------------------------
   1516 > > --- Encoding::CompatibilityError from thread: main
   1517 > > incompatible encoding regexp match (ASCII-8BIT regexp with UTF-8 string)
   1518 > > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:461:in `block (2 levels) in 
   1519 > > ask_many_with_completions'
   1520 > > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:461:in `select'
   1521 > > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:461:in `block in 
   1522 > > ask_many_with_completions'
   1523 > > /home/gaute/dev/ruby/sup.git/lib/sup/textfield.rb:75:in `call'
   1524 > > /home/gaute/dev/ruby/sup.git/lib/sup/textfield.rb:75:in `handle_input'
   1525 > > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:572:in `ask'
   1526 > > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:450:in 
   1527 > > `ask_many_with_completions'
   1528 > > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:519:in `ask_for_labels'
   1529 > > /home/gaute/dev/ruby/sup.git/lib/sup/util.rb:546:in `method_missing'
   1530 > > /home/gaute/dev/ruby/sup.git/lib/sup/modes/thread-index-mode.rb:536:in 
   1531 > > `edit_labels'
   1532 > > /home/gaute/dev/ruby/sup.git/lib/sup/mode.rb:52:in `handle_input'
   1533 > > /home/gaute/dev/ruby/sup.git/lib/sup/buffer.rb:266:in `handle_input'
   1534 > > bin/sup:244:in `<module:Redwood>'
   1535 > > bin/sup:67:in `<main>'
   1536 > > 
   1537 > > ----------
   1538 > > messages: 97
   1539 > > nosy: gauteh
   1540 > > priority: bug
   1541 > > ruby_version: 1.9.1
   1542 > > status: unread
   1543 > > sup_version: git
   1544 > > title: label tab completion with utf-8 chars fail
   1545 > > 
   1546 > --- Encoding::CompatibilityError from thread: main
   1547 > incompatible encoding regexp match (ASCII-8BIT regexp with UTF-8 string)
   1548 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/buffer.rb:476:in `block (2 levels) in ask_many_emails_with_completions'
   1549 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/buffer.rb:476:in `select'
   1550 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/buffer.rb:476:in `block in ask_many_emails_with_completions'
   1551 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/textfield.rb:74:in `call'
   1552 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/textfield.rb:74:in `handle_input'
   1553 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/buffer.rb:578:in `ask'
   1554 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/buffer.rb:472:in `ask_many_emails_with_completions'
   1555 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/util.rb:547:in `method_missing'
   1556 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/buffer.rb:548:in `ask_for_contacts'
   1557 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/util.rb:547:in `method_missing'
   1558 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/lib/sup/modes/compose-mode.rb:24:in `spawn_nicely'
   1559 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/bin/sup:331:in `<module:Redwood>'
   1560 > /home/gaute/.gem/ruby/1.9.1/gems/sup-999/bin/sup:78:in `<top (required)>'
   1561 > /home/gaute/.gem/ruby/1.9.1/bin/sup:19:in `load'
   1562 > /home/gaute/.gem/ruby/1.9.1/bin/sup:19:in `<main>'
   1563 -------------- next part --------------
   1564 An embedded and charset-unspecified text was scrubbed...
   1565 Name: exception-log.txt
   1566 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100103/2ad5ec58/attachment.txt>
   1567 -------------- next part --------------
   1568 A non-text attachment was scrubbed...
   1569 Name: signature.asc
   1570 Type: application/pgp-signature
   1571 Size: 198 bytes
   1572 Desc: not available
   1573 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100103/2ad5ec58/attachment.bin>
   1574 
   1575 From rlane@club.cc.cmu.edu  Sun Jan  3 11:07:16 2010
   1576 From: rlane@club.cc.cmu.edu (Rich Lane)
   1577 Date: Sun,  3 Jan 2010 08:07:16 -0800
   1578 Subject: [sup-devel] [PATCH] utf-8 script encoding
   1579 In-Reply-To: <1262533823-sup-5348@dolk>
   1580 References: <1262533823-sup-5348@dolk>
   1581 Message-ID: <1262534836-29113-1-git-send-email-rlane@club.cc.cmu.edu>
   1582 
   1583 ---
   1584 Does this patch help?
   1585 
   1586  bin/sup                                     |    1 +
   1587  bin/sup-add                                 |    1 +
   1588  bin/sup-config                              |    1 +
   1589  bin/sup-dump                                |    1 +
   1590  bin/sup-recover-sources                     |    1 +
   1591  bin/sup-sync                                |    1 +
   1592  bin/sup-sync-back                           |    1 +
   1593  bin/sup-tweak-labels                        |    1 +
   1594  lib/sup.rb                                  |    1 +
   1595  lib/sup/account.rb                          |    1 +
   1596  lib/sup/buffer.rb                           |    1 +
   1597  lib/sup/colormap.rb                         |    1 +
   1598  lib/sup/contact.rb                          |    1 +
   1599  lib/sup/crypto.rb                           |    1 +
   1600  lib/sup/draft.rb                            |    1 +
   1601  lib/sup/ferret_index.rb                     |    1 +
   1602  lib/sup/hook.rb                             |    1 +
   1603  lib/sup/horizontal-selector.rb              |    1 +
   1604  lib/sup/imap.rb                             |    1 +
   1605  lib/sup/index.rb                            |    1 +
   1606  lib/sup/interactive-lock.rb                 |    1 +
   1607  lib/sup/keymap.rb                           |    1 +
   1608  lib/sup/label.rb                            |    1 +
   1609  lib/sup/logger.rb                           |    1 +
   1610  lib/sup/maildir.rb                          |    1 +
   1611  lib/sup/mbox.rb                             |    1 +
   1612  lib/sup/mbox/loader.rb                      |    1 +
   1613  lib/sup/mbox/ssh-file.rb                    |    1 +
   1614  lib/sup/mbox/ssh-loader.rb                  |    1 +
   1615  lib/sup/message-chunks.rb                   |    1 +
   1616  lib/sup/message.rb                          |    1 +
   1617  lib/sup/mode.rb                             |    1 +
   1618  lib/sup/modes/buffer-list-mode.rb           |    1 +
   1619  lib/sup/modes/completion-mode.rb            |    1 +
   1620  lib/sup/modes/compose-mode.rb               |    1 +
   1621  lib/sup/modes/console-mode.rb               |    1 +
   1622  lib/sup/modes/contact-list-mode.rb          |    1 +
   1623  lib/sup/modes/edit-message-mode.rb          |    1 +
   1624  lib/sup/modes/file-browser-mode.rb          |    1 +
   1625  lib/sup/modes/forward-mode.rb               |    1 +
   1626  lib/sup/modes/help-mode.rb                  |    1 +
   1627  lib/sup/modes/inbox-mode.rb                 |    1 +
   1628  lib/sup/modes/label-list-mode.rb            |    1 +
   1629  lib/sup/modes/label-search-results-mode.rb  |    1 +
   1630  lib/sup/modes/line-cursor-mode.rb           |    1 +
   1631  lib/sup/modes/log-mode.rb                   |    1 +
   1632  lib/sup/modes/person-search-results-mode.rb |    1 +
   1633  lib/sup/modes/poll-mode.rb                  |    1 +
   1634  lib/sup/modes/reply-mode.rb                 |    1 +
   1635  lib/sup/modes/resume-mode.rb                |    1 +
   1636  lib/sup/modes/scroll-mode.rb                |    1 +
   1637  lib/sup/modes/search-results-mode.rb        |    1 +
   1638  lib/sup/modes/text-mode.rb                  |    1 +
   1639  lib/sup/modes/thread-index-mode.rb          |    1 +
   1640  lib/sup/modes/thread-view-mode.rb           |    1 +
   1641  lib/sup/person.rb                           |    1 +
   1642  lib/sup/poll.rb                             |    1 +
   1643  lib/sup/rfc2047.rb                          |    1 +
   1644  lib/sup/sent.rb                             |    1 +
   1645  lib/sup/source.rb                           |    1 +
   1646  lib/sup/tagger.rb                           |    1 +
   1647  lib/sup/textfield.rb                        |    1 +
   1648  lib/sup/thread.rb                           |    1 +
   1649  lib/sup/undo.rb                             |    1 +
   1650  lib/sup/update.rb                           |    1 +
   1651  lib/sup/util.rb                             |    1 +
   1652  lib/sup/xapian_index.rb                     |    1 +
   1653  67 files changed, 67 insertions(+), 0 deletions(-)
   1654 
   1655 diff --git a/bin/sup b/bin/sup
   1656 index 493f48f..f05acc3 100755
   1657 --- a/bin/sup
   1658 +++ b/bin/sup
   1659 @@ -1,4 +1,5 @@
   1660  #!/usr/bin/env ruby
   1661 +# encoding: utf-8
   1662  
   1663  require 'rubygems'
   1664  
   1665 diff --git a/bin/sup-add b/bin/sup-add
   1666 index c53378d..de4f65f 100755
   1667 --- a/bin/sup-add
   1668 +++ b/bin/sup-add
   1669 @@ -1,4 +1,5 @@
   1670  #!/usr/bin/env ruby
   1671 +# encoding: utf-8
   1672  
   1673  require 'uri'
   1674  require 'rubygems'
   1675 diff --git a/bin/sup-config b/bin/sup-config
   1676 index b37e0b2..da8777b 100755
   1677 --- a/bin/sup-config
   1678 +++ b/bin/sup-config
   1679 @@ -1,4 +1,5 @@
   1680  #!/usr/bin/env ruby
   1681 +# encoding: utf-8
   1682  
   1683  require 'rubygems'
   1684  require 'highline/import'
   1685 diff --git a/bin/sup-dump b/bin/sup-dump
   1686 index 7b33be5..78e388a 100755
   1687 --- a/bin/sup-dump
   1688 +++ b/bin/sup-dump
   1689 @@ -1,4 +1,5 @@
   1690  #!/usr/bin/env ruby
   1691 +# encoding: utf-8
   1692  
   1693  require 'rubygems'
   1694  require 'trollop'
   1695 diff --git a/bin/sup-recover-sources b/bin/sup-recover-sources
   1696 index 43fa5f6..d4a9170 100755
   1697 --- a/bin/sup-recover-sources
   1698 +++ b/bin/sup-recover-sources
   1699 @@ -1,4 +1,5 @@
   1700  #!/usr/bin/env ruby
   1701 +# encoding: utf-8
   1702  
   1703  require 'optparse'
   1704  
   1705 diff --git a/bin/sup-sync b/bin/sup-sync
   1706 index 5e89dac..184d740 100755
   1707 --- a/bin/sup-sync
   1708 +++ b/bin/sup-sync
   1709 @@ -1,4 +1,5 @@
   1710  #!/usr/bin/env ruby
   1711 +# encoding: utf-8
   1712  
   1713  require 'uri'
   1714  require 'rubygems'
   1715 diff --git a/bin/sup-sync-back b/bin/sup-sync-back
   1716 index 6298c97..ffc863f 100755
   1717 --- a/bin/sup-sync-back
   1718 +++ b/bin/sup-sync-back
   1719 @@ -1,4 +1,5 @@
   1720  #!/usr/bin/env ruby
   1721 +# encoding: utf-8
   1722  
   1723  require 'rubygems'
   1724  require 'uri'
   1725 diff --git a/bin/sup-tweak-labels b/bin/sup-tweak-labels
   1726 index 9bb97b2..3b7bcc4 100755
   1727 --- a/bin/sup-tweak-labels
   1728 +++ b/bin/sup-tweak-labels
   1729 @@ -1,4 +1,5 @@
   1730  #!/usr/bin/env ruby
   1731 +# encoding: utf-8
   1732  
   1733  require 'rubygems'
   1734  require 'trollop'
   1735 diff --git a/lib/sup.rb b/lib/sup.rb
   1736 index 144f5e3..e158249 100644
   1737 --- a/lib/sup.rb
   1738 +++ b/lib/sup.rb
   1739 @@ -1,3 +1,4 @@
   1740 +# encoding: utf-8
   1741  require 'rubygems'
   1742  require 'yaml'
   1743  require 'zlib'
   1744 diff --git a/lib/sup/account.rb b/lib/sup/account.rb
   1745 index bf8a8a0..fc655b9 100644
   1746 --- a/lib/sup/account.rb
   1747 +++ b/lib/sup/account.rb
   1748 @@ -1,3 +1,4 @@
   1749 +# encoding: utf-8
   1750  module Redwood
   1751  
   1752  class Account < Person
   1753 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
   1754 index 06923bd..cb045fc 100644
   1755 --- a/lib/sup/buffer.rb
   1756 +++ b/lib/sup/buffer.rb
   1757 @@ -1,3 +1,4 @@
   1758 +# encoding: utf-8
   1759  require 'etc'
   1760  require 'thread'
   1761  
   1762 diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
   1763 index c4a4024..acaf996 100644
   1764 --- a/lib/sup/colormap.rb
   1765 +++ b/lib/sup/colormap.rb
   1766 @@ -1,3 +1,4 @@
   1767 +# encoding: utf-8
   1768  module Curses
   1769    COLOR_DEFAULT = -1
   1770  end
   1771 diff --git a/lib/sup/contact.rb b/lib/sup/contact.rb
   1772 index c489aaf..25bf84a 100644
   1773 --- a/lib/sup/contact.rb
   1774 +++ b/lib/sup/contact.rb
   1775 @@ -1,3 +1,4 @@
   1776 +# encoding: utf-8
   1777  module Redwood
   1778  
   1779  class ContactManager
   1780 diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
   1781 index fb2661a..072a30c 100644
   1782 --- a/lib/sup/crypto.rb
   1783 +++ b/lib/sup/crypto.rb
   1784 @@ -1,3 +1,4 @@
   1785 +# encoding: utf-8
   1786  module Redwood
   1787  
   1788  class CryptoManager
   1789 diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
   1790 index 5ea2935..740ec6b 100644
   1791 --- a/lib/sup/draft.rb
   1792 +++ b/lib/sup/draft.rb
   1793 @@ -1,3 +1,4 @@
   1794 +# encoding: utf-8
   1795  module Redwood
   1796  
   1797  class DraftManager
   1798 diff --git a/lib/sup/ferret_index.rb b/lib/sup/ferret_index.rb
   1799 index 4a2cc76..05bc5b2 100644
   1800 --- a/lib/sup/ferret_index.rb
   1801 +++ b/lib/sup/ferret_index.rb
   1802 @@ -1,3 +1,4 @@
   1803 +# encoding: utf-8
   1804  require 'ferret'
   1805  
   1806  module Redwood
   1807 diff --git a/lib/sup/hook.rb b/lib/sup/hook.rb
   1808 index 3bf9823..b42b223 100644
   1809 --- a/lib/sup/hook.rb
   1810 +++ b/lib/sup/hook.rb
   1811 @@ -1,3 +1,4 @@
   1812 +# encoding: utf-8
   1813  module Redwood
   1814  
   1815  class HookManager
   1816 diff --git a/lib/sup/horizontal-selector.rb b/lib/sup/horizontal-selector.rb
   1817 index aef16d4..608703f 100644
   1818 --- a/lib/sup/horizontal-selector.rb
   1819 +++ b/lib/sup/horizontal-selector.rb
   1820 @@ -1,3 +1,4 @@
   1821 +# encoding: utf-8
   1822  module Redwood
   1823  
   1824  class HorizontalSelector
   1825 diff --git a/lib/sup/imap.rb b/lib/sup/imap.rb
   1826 index bdb9e15..5160e5c 100644
   1827 --- a/lib/sup/imap.rb
   1828 +++ b/lib/sup/imap.rb
   1829 @@ -1,3 +1,4 @@
   1830 +# encoding: utf-8
   1831  require 'uri'
   1832  require 'net/imap'
   1833  require 'stringio'
   1834 diff --git a/lib/sup/index.rb b/lib/sup/index.rb
   1835 index 87d8d52..829e6a5 100644
   1836 --- a/lib/sup/index.rb
   1837 +++ b/lib/sup/index.rb
   1838 @@ -1,3 +1,4 @@
   1839 +# encoding: utf-8
   1840  ## Index interface, subclassed by Ferret indexer.
   1841  
   1842  require 'fileutils'
   1843 diff --git a/lib/sup/interactive-lock.rb b/lib/sup/interactive-lock.rb
   1844 index 92a5ead..5150c89 100644
   1845 --- a/lib/sup/interactive-lock.rb
   1846 +++ b/lib/sup/interactive-lock.rb
   1847 @@ -1,3 +1,4 @@
   1848 +# encoding: utf-8
   1849  require 'fileutils'
   1850  
   1851  module Redwood
   1852 diff --git a/lib/sup/keymap.rb b/lib/sup/keymap.rb
   1853 index cb039e4..74e1599 100644
   1854 --- a/lib/sup/keymap.rb
   1855 +++ b/lib/sup/keymap.rb
   1856 @@ -1,3 +1,4 @@
   1857 +# encoding: utf-8
   1858  module Redwood
   1859  
   1860  class Keymap
   1861 diff --git a/lib/sup/label.rb b/lib/sup/label.rb
   1862 index 67474c2..f035dd8 100644
   1863 --- a/lib/sup/label.rb
   1864 +++ b/lib/sup/label.rb
   1865 @@ -1,3 +1,4 @@
   1866 +# encoding: utf-8
   1867  module Redwood
   1868  
   1869  class LabelManager
   1870 diff --git a/lib/sup/logger.rb b/lib/sup/logger.rb
   1871 index ccaeae0..7912ce2 100644
   1872 --- a/lib/sup/logger.rb
   1873 +++ b/lib/sup/logger.rb
   1874 @@ -1,3 +1,4 @@
   1875 +# encoding: utf-8
   1876  require "sup"
   1877  require 'stringio'
   1878  require 'thread'
   1879 diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
   1880 index c2bd27a..b3935d3 100644
   1881 --- a/lib/sup/maildir.rb
   1882 +++ b/lib/sup/maildir.rb
   1883 @@ -1,3 +1,4 @@
   1884 +# encoding: utf-8
   1885  require 'rmail'
   1886  require 'uri'
   1887  
   1888 diff --git a/lib/sup/mbox.rb b/lib/sup/mbox.rb
   1889 index 7af40dd..8973f06 100644
   1890 --- a/lib/sup/mbox.rb
   1891 +++ b/lib/sup/mbox.rb
   1892 @@ -1,3 +1,4 @@
   1893 +# encoding: utf-8
   1894  require "sup/mbox/loader"
   1895  require "sup/mbox/ssh-file"
   1896  require "sup/mbox/ssh-loader"
   1897 diff --git a/lib/sup/mbox/loader.rb b/lib/sup/mbox/loader.rb
   1898 index 54d227d..031a744 100644
   1899 --- a/lib/sup/mbox/loader.rb
   1900 +++ b/lib/sup/mbox/loader.rb
   1901 @@ -1,3 +1,4 @@
   1902 +# encoding: utf-8
   1903  require 'rmail'
   1904  require 'uri'
   1905  require 'set'
   1906 diff --git a/lib/sup/mbox/ssh-file.rb b/lib/sup/mbox/ssh-file.rb
   1907 index 4ae4bba..6f1c5ee 100644
   1908 --- a/lib/sup/mbox/ssh-file.rb
   1909 +++ b/lib/sup/mbox/ssh-file.rb
   1910 @@ -1,3 +1,4 @@
   1911 +# encoding: utf-8
   1912  require 'net/ssh'
   1913  
   1914  module Redwood
   1915 diff --git a/lib/sup/mbox/ssh-loader.rb b/lib/sup/mbox/ssh-loader.rb
   1916 index e422a48..75875d5 100644
   1917 --- a/lib/sup/mbox/ssh-loader.rb
   1918 +++ b/lib/sup/mbox/ssh-loader.rb
   1919 @@ -1,3 +1,4 @@
   1920 +# encoding: utf-8
   1921  require 'net/ssh'
   1922  
   1923  module Redwood
   1924 diff --git a/lib/sup/message-chunks.rb b/lib/sup/message-chunks.rb
   1925 index 581b707..8f0be32 100644
   1926 --- a/lib/sup/message-chunks.rb
   1927 +++ b/lib/sup/message-chunks.rb
   1928 @@ -1,3 +1,4 @@
   1929 +# encoding: utf-8
   1930  require 'tempfile'
   1931  
   1932  ## Here we define all the "chunks" that a message is parsed
   1933 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
   1934 index f3ac874..03fd831 100644
   1935 --- a/lib/sup/message.rb
   1936 +++ b/lib/sup/message.rb
   1937 @@ -1,3 +1,4 @@
   1938 +# encoding: utf-8
   1939  require 'time'
   1940  
   1941  module Redwood
   1942 diff --git a/lib/sup/mode.rb b/lib/sup/mode.rb
   1943 index c8ad0cc..899a9fb 100644
   1944 --- a/lib/sup/mode.rb
   1945 +++ b/lib/sup/mode.rb
   1946 @@ -1,3 +1,4 @@
   1947 +# encoding: utf-8
   1948  require 'open3'
   1949  module Redwood
   1950  
   1951 diff --git a/lib/sup/modes/buffer-list-mode.rb b/lib/sup/modes/buffer-list-mode.rb
   1952 index 1554cae..175b37a 100644
   1953 --- a/lib/sup/modes/buffer-list-mode.rb
   1954 +++ b/lib/sup/modes/buffer-list-mode.rb
   1955 @@ -1,3 +1,4 @@
   1956 +# encoding: utf-8
   1957  module Redwood
   1958  
   1959  class BufferListMode < LineCursorMode
   1960 diff --git a/lib/sup/modes/completion-mode.rb b/lib/sup/modes/completion-mode.rb
   1961 index 3cb2fad..62aeab0 100644
   1962 --- a/lib/sup/modes/completion-mode.rb
   1963 +++ b/lib/sup/modes/completion-mode.rb
   1964 @@ -1,3 +1,4 @@
   1965 +# encoding: utf-8
   1966  module Redwood
   1967  
   1968  class CompletionMode < ScrollMode
   1969 diff --git a/lib/sup/modes/compose-mode.rb b/lib/sup/modes/compose-mode.rb
   1970 index f0d1e23..90f6f18 100644
   1971 --- a/lib/sup/modes/compose-mode.rb
   1972 +++ b/lib/sup/modes/compose-mode.rb
   1973 @@ -1,3 +1,4 @@
   1974 +# encoding: utf-8
   1975  module Redwood
   1976  
   1977  class ComposeMode < EditMessageMode
   1978 diff --git a/lib/sup/modes/console-mode.rb b/lib/sup/modes/console-mode.rb
   1979 index f0c626e..c4e51fe 100644
   1980 --- a/lib/sup/modes/console-mode.rb
   1981 +++ b/lib/sup/modes/console-mode.rb
   1982 @@ -1,3 +1,4 @@
   1983 +# encoding: utf-8
   1984  require 'pp'
   1985  
   1986  module Redwood
   1987 diff --git a/lib/sup/modes/contact-list-mode.rb b/lib/sup/modes/contact-list-mode.rb
   1988 index 49804ad..63d1e2f 100644
   1989 --- a/lib/sup/modes/contact-list-mode.rb
   1990 +++ b/lib/sup/modes/contact-list-mode.rb
   1991 @@ -1,3 +1,4 @@
   1992 +# encoding: utf-8
   1993  module Redwood
   1994  
   1995  module CanAliasContacts
   1996 diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
   1997 index 8849271..618b3ef 100644
   1998 --- a/lib/sup/modes/edit-message-mode.rb
   1999 +++ b/lib/sup/modes/edit-message-mode.rb
   2000 @@ -1,3 +1,4 @@
   2001 +# encoding: utf-8
   2002  require 'tempfile'
   2003  require 'socket' # just for gethostname!
   2004  require 'pathname'
   2005 diff --git a/lib/sup/modes/file-browser-mode.rb b/lib/sup/modes/file-browser-mode.rb
   2006 index b92468d..976a8e8 100644
   2007 --- a/lib/sup/modes/file-browser-mode.rb
   2008 +++ b/lib/sup/modes/file-browser-mode.rb
   2009 @@ -1,3 +1,4 @@
   2010 +# encoding: utf-8
   2011  require 'pathname'
   2012  
   2013  module Redwood
   2014 diff --git a/lib/sup/modes/forward-mode.rb b/lib/sup/modes/forward-mode.rb
   2015 index 9428b4b..f5903f3 100644
   2016 --- a/lib/sup/modes/forward-mode.rb
   2017 +++ b/lib/sup/modes/forward-mode.rb
   2018 @@ -1,3 +1,4 @@
   2019 +# encoding: utf-8
   2020  module Redwood
   2021  
   2022  class ForwardMode < EditMessageMode
   2023 diff --git a/lib/sup/modes/help-mode.rb b/lib/sup/modes/help-mode.rb
   2024 index b98f131..6e3274e 100644
   2025 --- a/lib/sup/modes/help-mode.rb
   2026 +++ b/lib/sup/modes/help-mode.rb
   2027 @@ -1,3 +1,4 @@
   2028 +# encoding: utf-8
   2029  module Redwood
   2030  
   2031  class HelpMode < TextMode
   2032 diff --git a/lib/sup/modes/inbox-mode.rb b/lib/sup/modes/inbox-mode.rb
   2033 index 6c2244a..177c098 100644
   2034 --- a/lib/sup/modes/inbox-mode.rb
   2035 +++ b/lib/sup/modes/inbox-mode.rb
   2036 @@ -1,3 +1,4 @@
   2037 +# encoding: utf-8
   2038  require 'sup'
   2039  
   2040  module Redwood
   2041 diff --git a/lib/sup/modes/label-list-mode.rb b/lib/sup/modes/label-list-mode.rb
   2042 index f0084a9..50a4744 100644
   2043 --- a/lib/sup/modes/label-list-mode.rb
   2044 +++ b/lib/sup/modes/label-list-mode.rb
   2045 @@ -1,3 +1,4 @@
   2046 +# encoding: utf-8
   2047  module Redwood
   2048  
   2049  class LabelListMode < LineCursorMode
   2050 diff --git a/lib/sup/modes/label-search-results-mode.rb b/lib/sup/modes/label-search-results-mode.rb
   2051 index bca51d4..d45b764 100644
   2052 --- a/lib/sup/modes/label-search-results-mode.rb
   2053 +++ b/lib/sup/modes/label-search-results-mode.rb
   2054 @@ -1,3 +1,4 @@
   2055 +# encoding: utf-8
   2056  module Redwood
   2057  
   2058  class LabelSearchResultsMode < ThreadIndexMode
   2059 diff --git a/lib/sup/modes/line-cursor-mode.rb b/lib/sup/modes/line-cursor-mode.rb
   2060 index 1bd4ed1..0108592 100644
   2061 --- a/lib/sup/modes/line-cursor-mode.rb
   2062 +++ b/lib/sup/modes/line-cursor-mode.rb
   2063 @@ -1,3 +1,4 @@
   2064 +# encoding: utf-8
   2065  module Redwood
   2066  
   2067  ## extends ScrollMode to have a line-based cursor.
   2068 diff --git a/lib/sup/modes/log-mode.rb b/lib/sup/modes/log-mode.rb
   2069 index de320ce..0489a32 100644
   2070 --- a/lib/sup/modes/log-mode.rb
   2071 +++ b/lib/sup/modes/log-mode.rb
   2072 @@ -1,3 +1,4 @@
   2073 +# encoding: utf-8
   2074  require 'stringio'
   2075  module Redwood
   2076  
   2077 diff --git a/lib/sup/modes/person-search-results-mode.rb b/lib/sup/modes/person-search-results-mode.rb
   2078 index fc09126..656f394 100644
   2079 --- a/lib/sup/modes/person-search-results-mode.rb
   2080 +++ b/lib/sup/modes/person-search-results-mode.rb
   2081 @@ -1,3 +1,4 @@
   2082 +# encoding: utf-8
   2083  module Redwood
   2084  
   2085  class PersonSearchResultsMode < ThreadIndexMode
   2086 diff --git a/lib/sup/modes/poll-mode.rb b/lib/sup/modes/poll-mode.rb
   2087 index cf61343..2cb8d47 100644
   2088 --- a/lib/sup/modes/poll-mode.rb
   2089 +++ b/lib/sup/modes/poll-mode.rb
   2090 @@ -1,3 +1,4 @@
   2091 +# encoding: utf-8
   2092  module Redwood
   2093  
   2094  class PollMode < LogMode
   2095 diff --git a/lib/sup/modes/reply-mode.rb b/lib/sup/modes/reply-mode.rb
   2096 index 3d39a8a..b4f8bde 100644
   2097 --- a/lib/sup/modes/reply-mode.rb
   2098 +++ b/lib/sup/modes/reply-mode.rb
   2099 @@ -1,3 +1,4 @@
   2100 +# encoding: utf-8
   2101  module Redwood
   2102  
   2103  class ReplyMode < EditMessageMode
   2104 diff --git a/lib/sup/modes/resume-mode.rb b/lib/sup/modes/resume-mode.rb
   2105 index e527542..4e4346f 100644
   2106 --- a/lib/sup/modes/resume-mode.rb
   2107 +++ b/lib/sup/modes/resume-mode.rb
   2108 @@ -1,3 +1,4 @@
   2109 +# encoding: utf-8
   2110  module Redwood
   2111  
   2112  class ResumeMode < EditMessageMode
   2113 diff --git a/lib/sup/modes/scroll-mode.rb b/lib/sup/modes/scroll-mode.rb
   2114 index c131425..7b1aefd 100644
   2115 --- a/lib/sup/modes/scroll-mode.rb
   2116 +++ b/lib/sup/modes/scroll-mode.rb
   2117 @@ -1,3 +1,4 @@
   2118 +# encoding: utf-8
   2119  module Redwood
   2120  
   2121  class ScrollMode < Mode
   2122 diff --git a/lib/sup/modes/search-results-mode.rb b/lib/sup/modes/search-results-mode.rb
   2123 index 121e817..59e83af 100644
   2124 --- a/lib/sup/modes/search-results-mode.rb
   2125 +++ b/lib/sup/modes/search-results-mode.rb
   2126 @@ -1,3 +1,4 @@
   2127 +# encoding: utf-8
   2128  module Redwood
   2129  
   2130  class SearchResultsMode < ThreadIndexMode
   2131 diff --git a/lib/sup/modes/text-mode.rb b/lib/sup/modes/text-mode.rb
   2132 index 7c9e7d8..251b994 100644
   2133 --- a/lib/sup/modes/text-mode.rb
   2134 +++ b/lib/sup/modes/text-mode.rb
   2135 @@ -1,3 +1,4 @@
   2136 +# encoding: utf-8
   2137  module Redwood
   2138  
   2139  class TextMode < ScrollMode
   2140 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   2141 index ccda50b..617cf67 100644
   2142 --- a/lib/sup/modes/thread-index-mode.rb
   2143 +++ b/lib/sup/modes/thread-index-mode.rb
   2144 @@ -1,3 +1,4 @@
   2145 +# encoding: utf-8
   2146  require 'set'
   2147  
   2148  module Redwood
   2149 diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb
   2150 index 8b5642e..ca6108f 100644
   2151 --- a/lib/sup/modes/thread-view-mode.rb
   2152 +++ b/lib/sup/modes/thread-view-mode.rb
   2153 @@ -1,3 +1,4 @@
   2154 +# encoding: utf-8
   2155  module Redwood
   2156  
   2157  class ThreadViewMode < LineCursorMode
   2158 diff --git a/lib/sup/person.rb b/lib/sup/person.rb
   2159 index 4b1c80b..5256cc4 100644
   2160 --- a/lib/sup/person.rb
   2161 +++ b/lib/sup/person.rb
   2162 @@ -1,3 +1,4 @@
   2163 +# encoding: utf-8
   2164  module Redwood
   2165  
   2166  class Person
   2167 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   2168 index 4f30505..ac60373 100644
   2169 --- a/lib/sup/poll.rb
   2170 +++ b/lib/sup/poll.rb
   2171 @@ -1,3 +1,4 @@
   2172 +# encoding: utf-8
   2173  require 'thread'
   2174  
   2175  module Redwood
   2176 diff --git a/lib/sup/rfc2047.rb b/lib/sup/rfc2047.rb
   2177 index f31faa1..8fe645d 100644
   2178 --- a/lib/sup/rfc2047.rb
   2179 +++ b/lib/sup/rfc2047.rb
   2180 @@ -1,3 +1,4 @@
   2181 +# encoding: utf-8
   2182  ## from: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/101949
   2183  
   2184  # $Id: rfc2047.rb,v 1.4 2003/04/18 20:55:56 sam Exp $
   2185 diff --git a/lib/sup/sent.rb b/lib/sup/sent.rb
   2186 index 87ca6c6..8c48259 100644
   2187 --- a/lib/sup/sent.rb
   2188 +++ b/lib/sup/sent.rb
   2189 @@ -1,3 +1,4 @@
   2190 +# encoding: utf-8
   2191  module Redwood
   2192  
   2193  class SentManager
   2194 diff --git a/lib/sup/source.rb b/lib/sup/source.rb
   2195 index 6fe7bfb..134cda9 100644
   2196 --- a/lib/sup/source.rb
   2197 +++ b/lib/sup/source.rb
   2198 @@ -1,3 +1,4 @@
   2199 +# encoding: utf-8
   2200  require "sup/rfc2047"
   2201  
   2202  module Redwood
   2203 diff --git a/lib/sup/tagger.rb b/lib/sup/tagger.rb
   2204 index d62f340..0a04b0c 100644
   2205 --- a/lib/sup/tagger.rb
   2206 +++ b/lib/sup/tagger.rb
   2207 @@ -1,3 +1,4 @@
   2208 +# encoding: utf-8
   2209  module Redwood
   2210  
   2211  class Tagger
   2212 diff --git a/lib/sup/textfield.rb b/lib/sup/textfield.rb
   2213 index 9afeb34..8072f83 100644
   2214 --- a/lib/sup/textfield.rb
   2215 +++ b/lib/sup/textfield.rb
   2216 @@ -1,3 +1,4 @@
   2217 +# encoding: utf-8
   2218  module Redwood
   2219  
   2220  ## a fully-functional text field supporting completions, expansions,
   2221 diff --git a/lib/sup/thread.rb b/lib/sup/thread.rb
   2222 index 2300305..17d709d 100644
   2223 --- a/lib/sup/thread.rb
   2224 +++ b/lib/sup/thread.rb
   2225 @@ -1,3 +1,4 @@
   2226 +# encoding: utf-8
   2227  ## Herein lies all the code responsible for threading messages. It's
   2228  ## basically an online version of the JWZ threading algorithm:
   2229  ## http://www.jwz.org/doc/threading.html
   2230 diff --git a/lib/sup/undo.rb b/lib/sup/undo.rb
   2231 index 9ccf84a..2ca7d02 100644
   2232 --- a/lib/sup/undo.rb
   2233 +++ b/lib/sup/undo.rb
   2234 @@ -1,3 +1,4 @@
   2235 +# encoding: utf-8
   2236  module Redwood
   2237  
   2238  ## Implements a single undo list for the Sup instance
   2239 diff --git a/lib/sup/update.rb b/lib/sup/update.rb
   2240 index d386801..b689b51 100644
   2241 --- a/lib/sup/update.rb
   2242 +++ b/lib/sup/update.rb
   2243 @@ -1,3 +1,4 @@
   2244 +# encoding: utf-8
   2245  module Redwood
   2246  
   2247  ## Classic listener/broadcaster paradigm. Handles communication between various
   2248 diff --git a/lib/sup/util.rb b/lib/sup/util.rb
   2249 index 25af762..5bd93b3 100644
   2250 --- a/lib/sup/util.rb
   2251 +++ b/lib/sup/util.rb
   2252 @@ -1,3 +1,4 @@
   2253 +# encoding: utf-8
   2254  require 'thread'
   2255  require 'lockfile'
   2256  require 'mime/types'
   2257 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   2258 index 955ec8f..2919ce6 100644
   2259 --- a/lib/sup/xapian_index.rb
   2260 +++ b/lib/sup/xapian_index.rb
   2261 @@ -1,3 +1,4 @@
   2262 +# encoding: utf-8
   2263  require 'xapian'
   2264  require 'set'
   2265  
   2266 -- 
   2267 1.6.3.3
   2268 
   2269 
   2270 From eg@gaute.vetsj.com  Sun Jan  3 11:18:29 2010
   2271 From: eg@gaute.vetsj.com (Gaute Hope)
   2272 Date: Sun, 03 Jan 2010 17:18:29 +0100
   2273 Subject: [sup-devel] [PATCH] utf-8 script encoding
   2274 In-Reply-To: <1262534836-29113-1-git-send-email-rlane@club.cc.cmu.edu>
   2275 References: <1262533823-sup-5348@dolk>
   2276 	<1262534836-29113-1-git-send-email-rlane@club.cc.cmu.edu>
   2277 Message-ID: <1262535218-sup-9718@dolk>
   2278 
   2279 Excerpts from Rich Lane's message of 2010-01-03 17:07:16 +0100:
   2280 > --- Does this patch help?
   2281   
   2282 No. Tab completion fails, and sending fails, I can add names with UTF-8
   2283 chars to the recipient list, but it fails with the last attached
   2284 exception. This is the same behaviour as earlier.
   2285 
   2286 - gaute
   2287 -------------- next part --------------
   2288 A non-text attachment was scrubbed...
   2289 Name: signature.asc
   2290 Type: application/pgp-signature
   2291 Size: 198 bytes
   2292 Desc: not available
   2293 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100103/be6dac99/attachment.bin>
   2294 
   2295 From hyperbolist@gmail.com  Sun Jan  3 12:09:50 2010
   2296 From: hyperbolist@gmail.com (Eric Sherman)
   2297 Date: Sun, 03 Jan 2010 12:09:50 -0500
   2298 Subject: [sup-devel] [PATCH] [issue4] kill buffers in buffer-list-mode with
   2299 	"X"
   2300 Message-ID: <1262538511-sup-5390@changeling.local>
   2301 
   2302 ---
   2303  lib/sup/modes/buffer-list-mode.rb |    5 +++++
   2304  1 files changed, 5 insertions(+), 0 deletions(-)
   2305 
   2306 diff --git a/lib/sup/modes/buffer-list-mode.rb b/lib/sup/modes/buffer-list-mode.rb
   2307 index 1554cae..40f2e76 100644
   2308 --- a/lib/sup/modes/buffer-list-mode.rb
   2309 +++ b/lib/sup/modes/buffer-list-mode.rb
   2310 @@ -4,6 +4,7 @@ class BufferListMode < LineCursorMode
   2311    register_keymap do |k|
   2312      k.add :jump_to_buffer, "Jump to selected buffer", :enter
   2313      k.add :reload, "Reload buffer list", "@"
   2314 +    k.add :kill_selected_buffer, "Kill selected buffer", "X"
   2315    end
   2316  
   2317    def initialize
   2318 @@ -40,6 +41,10 @@ protected
   2319    def jump_to_buffer
   2320      BufferManager.raise_to_front @bufs[curpos][1]
   2321    end
   2322 +
   2323 +  def kill_selected_buffer
   2324 +    reload if BufferManager.kill_buffer_safely @bufs[curpos][1]
   2325 +  end
   2326  end
   2327  
   2328  end
   2329 -- 
   2330 1.6.5.7
   2331 
   2332 From pi+sup@pihost.us  Sun Jan  3 14:38:52 2010
   2333 From: pi+sup@pihost.us (Anthony Martinez)
   2334 Date: Sun, 03 Jan 2010 12:38:52 -0700
   2335 Subject: [sup-devel] [sup-talk] Ferret to Xapian conversion
   2336 In-Reply-To: <1262531773-sup-5192@masanjin.net>
   2337 References: <1262460996-sup-1383@home.mrtheplague.net>
   2338 	<1262467343-sup-9565@masanjin.net>
   2339 	<1262471675-sup-1708@masanjin.net>
   2340 	<1262531773-sup-5192@masanjin.net>
   2341 Message-ID: <1262546960-sup-6875@home.mrtheplague.net>
   2342 
   2343 Excerpts from William Morgan's message of Sun Jan 03 08:18:53 -0700 2010:
   2344 > If you run this script, please report your experience, since I'd like to
   2345 > include it in the 0.10 release coming soon.
   2346 
   2347 Here is a patch to make it complain about not having Xapian *before* starting
   2348 the state dump, so it doesn't get to step 3 and suddenly find out that it can't
   2349 load Xapian.
   2350 
   2351 Speaking of not having the Xapian gem, when I tried "gem install xapian-full",
   2352 it looked like it worked, but didn't actually install a gem on my system. Here's
   2353 the build log: http://pastebin.com/f2d25a13c
   2354 
   2355 I tried the regular 'xapian' gem, but the version available in Debian unstable
   2356 is newer than the gem bindings, so that one outright refuses to compile.
   2357 
   2358 Help!
   2359 
   2360 diff --git a/bin/sup-convert-ferret-index b/bin/sup-convert-ferret-index
   2361 index 96a97aa..e78ac4b 100755
   2362 --- a/bin/sup-convert-ferret-index
   2363 +++ b/bin/sup-convert-ferret-index
   2364 @@ -42,6 +42,12 @@ def run cmd
   2365    puts
   2366  end
   2367  
   2368 +begin
   2369 +    require 'xapian'
   2370 +rescue LoadError
   2371 +    Trollop::die "you don't have the xapian gem installed, so this script won't do much for you. `gem install xapian' first."
   2372 +end
   2373 +
   2374  Redwood::start
   2375  index = Redwood::Index.init
   2376  Trollop::die "you appear to already have a Xapian index--delete #{File.join(Redwood::BASE_DIR, "xapian")} if you really want to do this" unless Redwood::Index.is_a_deprecated_ferret_index?
   2377 
   2378 From rlane@club.cc.cmu.edu  Sun Jan  3 15:18:35 2010
   2379 From: rlane@club.cc.cmu.edu (Rich Lane)
   2380 Date: Sun, 03 Jan 2010 15:18:35 -0500
   2381 Subject: [sup-devel] [sup-talk] Ferret to Xapian conversion
   2382 In-Reply-To: <1262546960-sup-6875@home.mrtheplague.net>
   2383 References: <1262460996-sup-1383@home.mrtheplague.net>
   2384 	<1262467343-sup-9565@masanjin.net>
   2385 	<1262471675-sup-1708@masanjin.net>
   2386 	<1262531773-sup-5192@masanjin.net>
   2387 	<1262546960-sup-6875@home.mrtheplague.net>
   2388 Message-ID: <1262549410-sup-7918@zyrg.net>
   2389 
   2390 Excerpts from Anthony Martinez's message of 2010-01-03 14:38:52 -0500:
   2391 > Speaking of not having the Xapian gem, when I tried "gem install xapian-full",
   2392 > it looked like it worked, but didn't actually install a gem on my system. Here's
   2393 > the build log: http://pastebin.com/f2d25a13c
   2394 > 
   2395 > I tried the regular 'xapian' gem, but the version available in Debian unstable
   2396 > is newer than the gem bindings, so that one outright refuses to compile.
   2397 
   2398 I noticed that gem thinks the xapian compile failed, but it actually
   2399 succeeded and since it was in-place the installed gem worked fine. I've
   2400 pushed the ncursesw source to my github so please tinker and send me a
   2401 patch. I'm traveling for the next day so I won't be able to fix it soon
   2402 myself.
   2403 
   2404 From wmorgan-sup@masanjin.net  Sun Jan  3 17:00:28 2010
   2405 From: wmorgan-sup@masanjin.net (William Morgan)
   2406 Date: Sun, 03 Jan 2010 14:00:28 -0800
   2407 Subject: [sup-devel] [issue39] Exception running Sup while following the
   2408 	Instructions to fix UTF-8
   2409 In-Reply-To: <1262290995.91.0.416495320944.issue39@masanjin.net>
   2410 References: <1262290995.91.0.416495320944.issue39@masanjin.net>
   2411 	<1262290995.91.0.416495320944.issue39@masanjin.net>
   2412 Message-ID: <1262555973-sup-6555@masanjin.net>
   2413 
   2414 Reformatted excerpts from anonymous's message of 2009-12-31:
   2415 > --- RuntimeError from thread: main
   2416 > no Redwood::SentManager instance defined in method call to i_am_the_instance!
   2417 > ./lib/sup/util.rb:512:in `method_missing'
   2418 > /usr/lib/ruby/1.8/sup/sent.rb:10:in `initialize'
   2419 > ./lib/sup/util.rb:524:in `new'
   2420 > ./lib/sup/util.rb:524:in `init'
   2421 > ./lib/sup.rb:124:in `start'
   2422 > bin/sup:143
   2423 
   2424 Soemthing is screwey with your setup---you're loading most files from
   2425 ./lib, but sent.rb is being loaded from an old version of an installed
   2426 gem. Are you missing ./lib/sent.rb? If not, does this still happen if
   2427 you uninstall the Sup gem?
   2428 -- 
   2429 William <wmorgan-sup at masanjin.net>
   2430 
   2431 From wmorgan-sup@masanjin.net  Sun Jan  3 17:07:16 2010
   2432 From: wmorgan-sup@masanjin.net (William Morgan)
   2433 Date: Sun, 03 Jan 2010 14:07:16 -0800
   2434 Subject: [sup-devel] [sup-talk] Ferret to Xapian conversion
   2435 In-Reply-To: <1262546960-sup-6875@home.mrtheplague.net>
   2436 References: <1262460996-sup-1383@home.mrtheplague.net>
   2437 	<1262467343-sup-9565@masanjin.net>
   2438 	<1262471675-sup-1708@masanjin.net>
   2439 	<1262531773-sup-5192@masanjin.net>
   2440 	<1262546960-sup-6875@home.mrtheplague.net>
   2441 Message-ID: <1262556388-sup-4595@masanjin.net>
   2442 
   2443 Reformatted excerpts from Anthony Martinez's message of 2010-01-03:
   2444 > Here is a patch to make it complain about not having Xapian *before* starting
   2445 > the state dump, so it doesn't get to step 3 and suddenly find out that it can't
   2446 > load Xapian.
   2447 
   2448 Added to ferret-deprecation with minor editing, and remerged into next.
   2449 Thanks!
   2450 -- 
   2451 William <wmorgan-sup at masanjin.net>
   2452 
   2453 From wmorgan-sup@masanjin.net  Sun Jan  3 17:11:49 2010
   2454 From: wmorgan-sup@masanjin.net (William Morgan)
   2455 Date: Sun, 03 Jan 2010 14:11:49 -0800
   2456 Subject: [sup-devel] [PATCH] [issue4] kill buffers in buffer-list-mode
   2457 	with "X"
   2458 In-Reply-To: <1262538511-sup-5390@changeling.local>
   2459 References: <1262538511-sup-5390@changeling.local>
   2460 Message-ID: <1262556673-sup-781@masanjin.net>
   2461 
   2462 Applied directly to master. It's still Christmas! Thanks!
   2463 -- 
   2464 William <wmorgan-sup at masanjin.net>
   2465 
   2466 From pi+sup@pihost.us  Sun Jan  3 17:47:39 2010
   2467 From: pi+sup@pihost.us (Anthony Martinez)
   2468 Date: Sun, 03 Jan 2010 15:47:39 -0700
   2469 Subject: [sup-devel] [sup-talk] Ferret to Xapian conversion
   2470 In-Reply-To: <1262549410-sup-7918@zyrg.net>
   2471 References: <1262460996-sup-1383@home.mrtheplague.net>
   2472 	<1262467343-sup-9565@masanjin.net>
   2473 	<1262471675-sup-1708@masanjin.net>
   2474 	<1262531773-sup-5192@masanjin.net>
   2475 	<1262546960-sup-6875@home.mrtheplague.net>
   2476 	<1262549410-sup-7918@zyrg.net>
   2477 Message-ID: <1262558818-sup-5188@home.mrtheplague.net>
   2478 
   2479 Excerpts from Rich Lane's message of Sun Jan 03 13:18:35 -0700 2010:
   2480 > Excerpts from Anthony Martinez's message of 2010-01-03 14:38:52 -0500:
   2481 > > Speaking of not having the Xapian gem, when I tried "gem install xapian-full",
   2482 > > it looked like it worked, but didn't actually install a gem on my system. Here's
   2483 > > the build log: http://pastebin.com/f2d25a13c
   2484 > 
   2485 > I noticed that gem thinks the xapian compile failed, but it actually
   2486 > succeeded and since it was in-place the installed gem worked fine.
   2487 
   2488 I don't know enough about packaging Gems to help out, unfortunately. The way I'm
   2489 proceeding for now is to add "-I /var/lib/gems/1.8/gems/xapian-full-1.1.3/lib/"
   2490 to my Ruby command line (and in the case of the conversion script, to the
   2491 RUBY_INVOCATION environment). Life is ridiculous. :)
   2492 
   2493 It appears to have worked, though, as I'm now writing this from a
   2494 Xapian-indexed sup!
   2495 
   2496 From pi+sup@pihost.us  Mon Jan  4 01:06:36 2010
   2497 From: pi+sup@pihost.us (Anthony Martinez)
   2498 Date: Sun,  3 Jan 2010 23:06:36 -0700
   2499 Subject: [sup-devel] [PATCH 3/3] make the undo hooks also save the threads
   2500 In-Reply-To: <1262585196-25964-2-git-send-email-pi+sup@pihost.us>
   2501 References: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   2502 	<1262585196-25964-2-git-send-email-pi+sup@pihost.us>
   2503 Message-ID: <1262585196-25964-3-git-send-email-pi+sup@pihost.us>
   2504 
   2505 Since there is no explicit sync any longer, any action that has an
   2506 Index.save_thread must also repeat the save when the action is undone.
   2507 Failure to do this will result in an exception upon quit when the index
   2508 notices that there are still dirty messages.
   2509 ---
   2510  lib/sup/modes/inbox-mode.rb        |    4 ++++
   2511  lib/sup/modes/thread-index-mode.rb |   18 ++++++++++++------
   2512  lib/sup/modes/thread-view-mode.rb  |    4 ++++
   2513  3 files changed, 20 insertions(+), 6 deletions(-)
   2514 
   2515 diff --git a/lib/sup/modes/inbox-mode.rb b/lib/sup/modes/inbox-mode.rb
   2516 index 852ddb7..1b8eaed 100644
   2517 --- a/lib/sup/modes/inbox-mode.rb
   2518 +++ b/lib/sup/modes/inbox-mode.rb
   2519 @@ -37,6 +37,7 @@ class InboxMode < ThreadIndexMode
   2520      UndoManager.register "archiving thread" do
   2521        thread.apply_label :inbox
   2522        add_or_unhide thread.first
   2523 +      Index.save_thread thread
   2524      end
   2525  
   2526      cursor_thread.remove_label :inbox
   2527 @@ -50,6 +51,7 @@ class InboxMode < ThreadIndexMode
   2528        threads.map do |t|
   2529          t.apply_label :inbox
   2530          add_or_unhide t.first
   2531 +        Index.save_thread t
   2532        end
   2533        regen_text
   2534      end
   2535 @@ -71,6 +73,7 @@ class InboxMode < ThreadIndexMode
   2536        thread.apply_label :inbox
   2537        thread.apply_label :unread if was_unread
   2538        add_or_unhide thread.first
   2539 +      Index.save_thread thread
   2540      end
   2541  
   2542      cursor_thread.remove_label :unread
   2543 @@ -94,6 +97,7 @@ class InboxMode < ThreadIndexMode
   2544        threads.zip(old_labels).each do |t, l|
   2545          t.labels = l
   2546          add_or_unhide t.first
   2547 +        Index.save_thread t
   2548        end
   2549        regen_text
   2550      end
   2551 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   2552 index a5bd344..28cb858 100644
   2553 --- a/lib/sup/modes/thread-index-mode.rb
   2554 +++ b/lib/sup/modes/thread-index-mode.rb
   2555 @@ -265,7 +265,7 @@ EOS
   2556    def toggle_starred 
   2557      t = cursor_thread or return
   2558      undo = actually_toggle_starred t
   2559 -    UndoManager.register "toggling thread starred status", undo
   2560 +    UndoManager.register "toggling thread starred status", undo, lambda { Index.save_thread t }
   2561      update_text_for_line curpos
   2562      cursor_down
   2563      Index.save_thread t
   2564 @@ -273,7 +273,8 @@ EOS
   2565  
   2566    def multi_toggle_starred threads
   2567      UndoManager.register "toggling #{threads.size.pluralize 'thread'} starred status",
   2568 -      threads.map { |t| actually_toggle_starred t }
   2569 +      threads.map { |t| actually_toggle_starred t },
   2570 +      lambda { threads.each { |t| Index.save_thread t } }
   2571      regen_text
   2572      threads.each { |t| Index.save_thread t }
   2573    end
   2574 @@ -351,14 +352,16 @@ EOS
   2575    def toggle_archived 
   2576      t = cursor_thread or return
   2577      undo = actually_toggle_archived t
   2578 -    UndoManager.register "deleting/undeleting thread #{t.first.id}", undo, lambda { update_text_for_line curpos }
   2579 +    UndoManager.register "deleting/undeleting thread #{t.first.id}", undo, lambda { update_text_for_line curpos },
   2580 +                         lambda { Index.save_thread t }
   2581      update_text_for_line curpos
   2582      Index.save_thread t
   2583    end
   2584  
   2585    def multi_toggle_archived threads
   2586      undos = threads.map { |t| actually_toggle_archived t }
   2587 -    UndoManager.register "deleting/undeleting #{threads.size.pluralize 'thread'}", undos, lambda { regen_text }
   2588 +    UndoManager.register "deleting/undeleting #{threads.size.pluralize 'thread'}", undos, lambda { regen_text },
   2589 +                         lambda { threads.each { |t| Index.save_thread t } }
   2590      regen_text
   2591      threads.each { |t| Index.save_thread t }
   2592    end
   2593 @@ -425,7 +428,7 @@ EOS
   2594      undos = threads.map { |t| actually_toggle_spammed t }
   2595      threads.each { |t| HookManager.run("mark-as-spam", :thread => t) }
   2596      UndoManager.register "marking/unmarking  #{threads.size.pluralize 'thread'} as spam",
   2597 -                         undos, lambda { regen_text }
   2598 +                         undos, lambda { regen_text }, lambda { threads.each { |t| Index.save_thread t } }
   2599      regen_text
   2600      threads.each { |t| Index.save_thread t }
   2601    end
   2602 @@ -439,7 +442,7 @@ EOS
   2603    def multi_toggle_deleted threads
   2604      undos = threads.map { |t| actually_toggle_deleted t }
   2605      UndoManager.register "deleting/undeleting #{threads.size.pluralize 'thread'}",
   2606 -                         undos, lambda { regen_text }
   2607 +                         undos, lambda { regen_text }, lambda { threads.each { |t| Index.save_thread t } }
   2608      regen_text
   2609      threads.each { |t| Index.save_thread t }
   2610    end
   2611 @@ -455,6 +458,7 @@ EOS
   2612        threads.each do |t|
   2613          t.remove_label :killed
   2614          add_or_unhide t.first
   2615 +        Index.save_thread t
   2616        end
   2617        regen_text
   2618      end
   2619 @@ -530,6 +534,7 @@ EOS
   2620        thread.labels = old_labels
   2621        update_text_for_line pos
   2622        UpdateManager.relay self, :labeled, thread.first
   2623 +      Index.save_thread thread
   2624      end
   2625  
   2626      UpdateManager.relay self, :labeled, thread.first
   2627 @@ -567,6 +572,7 @@ EOS
   2628        threads.zip(old_labels).map do |t, old_labels|
   2629          t.labels = old_labels
   2630          UpdateManager.relay self, :labeled, t.first
   2631 +        Index.save_thread t
   2632        end
   2633        regen_text
   2634      end
   2635 diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb
   2636 index 7c0b869..b08c819 100644
   2637 --- a/lib/sup/modes/thread-view-mode.rb
   2638 +++ b/lib/sup/modes/thread-view-mode.rb
   2639 @@ -279,6 +279,7 @@ EOS
   2640      Index.save_thread @thread
   2641      UndoManager.register "labeling thread" do
   2642        @thread.labels = old_labels
   2643 +      Index.save_thread @thread
   2644        UpdateManager.relay self, :labeled, @thread.first
   2645      end
   2646    end
   2647 @@ -527,6 +528,7 @@ EOS
   2648        Index.save_thread @thread
   2649        UndoManager.register "archiving 1 thread" do
   2650          @thread.apply_label :inbox
   2651 +        Index.save_thread @thread
   2652          UpdateManager.relay self, :unarchived, @thread.first
   2653        end
   2654      end
   2655 @@ -539,6 +541,7 @@ EOS
   2656        Index.save_thread @thread
   2657        UndoManager.register "marking 1 thread as spam" do
   2658          @thread.remove_label :spam
   2659 +        Index.save_thread @thread
   2660          UpdateManager.relay self, :unspammed, @thread.first
   2661        end
   2662      end
   2663 @@ -551,6 +554,7 @@ EOS
   2664        Index.save_thread @thread
   2665        UndoManager.register "deleting 1 thread" do
   2666          @thread.remove_label :deleted
   2667 +        Index.save_thread @thread
   2668          UpdateManager.relay self, :undeleted, @thread.first
   2669        end
   2670      end
   2671 -- 
   2672 1.6.5
   2673 
   2674 
   2675 From pi+sup@pihost.us  Mon Jan  4 01:06:34 2010
   2676 From: pi+sup@pihost.us (Anthony Martinez)
   2677 Date: Sun,  3 Jan 2010 23:06:34 -0700
   2678 Subject: [sup-devel] [PATCH 1/3] punctuate "No new messages." consistently
   2679 	between poll, jump_to_next_new
   2680 Message-ID: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   2681 
   2682 ---
   2683  lib/sup/modes/thread-index-mode.rb |    2 +-
   2684  1 files changed, 1 insertions(+), 1 deletions(-)
   2685 
   2686 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   2687 index eaed0cb..a5bd344 100644
   2688 --- a/lib/sup/modes/thread-index-mode.rb
   2689 +++ b/lib/sup/modes/thread-index-mode.rb
   2690 @@ -405,7 +405,7 @@ EOS
   2691        jump_to_line n unless n >= topline && n < botline
   2692        set_cursor_pos n
   2693      else
   2694 -      BufferManager.flash "No new messages"
   2695 +      BufferManager.flash "No new messages."
   2696      end
   2697    end
   2698  
   2699 -- 
   2700 1.6.5
   2701 
   2702 
   2703 From pi+sup@pihost.us  Mon Jan  4 01:06:35 2010
   2704 From: pi+sup@pihost.us (Anthony Martinez)
   2705 Date: Sun,  3 Jan 2010 23:06:35 -0700
   2706 Subject: [sup-devel] [PATCH 2/3] undoing read_and_archive should preserve
   2707 	unread state
   2708 In-Reply-To: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   2709 References: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   2710 Message-ID: <1262585196-25964-2-git-send-email-pi+sup@pihost.us>
   2711 
   2712 ---
   2713  lib/sup/modes/inbox-mode.rb |    3 ++-
   2714  1 files changed, 2 insertions(+), 1 deletions(-)
   2715 
   2716 diff --git a/lib/sup/modes/inbox-mode.rb b/lib/sup/modes/inbox-mode.rb
   2717 index ad3a864..852ddb7 100644
   2718 --- a/lib/sup/modes/inbox-mode.rb
   2719 +++ b/lib/sup/modes/inbox-mode.rb
   2720 @@ -66,9 +66,10 @@ class InboxMode < ThreadIndexMode
   2721      return unless cursor_thread
   2722      thread = cursor_thread # to make sure lambda only knows about 'old' cursor_thread
   2723  
   2724 +    was_unread = thread.labels.member? :unread
   2725      UndoManager.register "reading and archiving thread" do
   2726        thread.apply_label :inbox
   2727 -      thread.apply_label :unread
   2728 +      thread.apply_label :unread if was_unread
   2729        add_or_unhide thread.first
   2730      end
   2731  
   2732 -- 
   2733 1.6.5
   2734 
   2735 
   2736 From hyperbolist@gmail.com  Mon Jan  4 01:20:34 2010
   2737 From: hyperbolist@gmail.com (Eric Sherman)
   2738 Date: Mon, 04 Jan 2010 01:20:34 -0500
   2739 Subject: [sup-devel] [PATCH] [issue14] poll updates accumulate while idle
   2740 Message-ID: <1262585888-sup-7490@changeling.local>
   2741 
   2742 If you were to leave sup running for a long time, this patch would
   2743 enable you to get a glance summary of new mail activity since sup was
   2744 last touched, by letting the poll update message accumulate its tally
   2745 while idle.
   2746 
   2747 On keystrokes, BufferManager sends an :unidle update if the last
   2748 keystroke occurred more than :idle_threshold seconds ago.  PollManager
   2749 listens for :unidle updates to clear PollTally, which will otherwise
   2750 accumulate.
   2751 
   2752 * :idle_threshold defaults to 60 seconds if not defined in config.yaml
   2753 * presently no :idle update is sent when becoming idle
   2754 * after-poll behavior is unaffected
   2755 ---
   2756  lib/sup.rb        |    3 ++-
   2757  lib/sup/buffer.rb |    5 +++++
   2758  lib/sup/poll.rb   |   23 +++++++++++++++++++++--
   2759  3 files changed, 28 insertions(+), 3 deletions(-)
   2760 
   2761 diff --git a/lib/sup.rb b/lib/sup.rb
   2762 index 840b3fc..a6de0ab 100644
   2763 --- a/lib/sup.rb
   2764 +++ b/lib/sup.rb
   2765 @@ -229,7 +229,8 @@ else
   2766      :confirm_top_posting => true,
   2767      :discard_snippets_from_encrypted_messages => false,
   2768      :default_attachment_save_dir => "",
   2769 -    :sent_source => "sup://sent"
   2770 +    :sent_source => "sup://sent",
   2771 +    :idle_threshold => 60
   2772    }
   2773    begin
   2774      FileUtils.mkdir_p Redwood::BASE_DIR
   2775 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
   2776 index c826ab9..c34917d 100644
   2777 --- a/lib/sup/buffer.rb
   2778 +++ b/lib/sup/buffer.rb
   2779 @@ -212,6 +212,7 @@ EOS
   2780      @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
   2781      @sigwinch_happened = false
   2782      @sigwinch_mutex = Mutex.new
   2783 +    @idle_since = Time.now
   2784    end
   2785  
   2786    def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
   2787 @@ -269,6 +270,8 @@ EOS
   2788          @focus_buf.mode.cancel_search!
   2789          @focus_buf.mark_dirty
   2790        end
   2791 +      UpdateManager.relay self, :unidle, Time.at(@idle_since) if idle?
   2792 +      @idle_since = Time.now
   2793        @focus_buf.mode.handle_input c
   2794      end
   2795    end
   2796 @@ -797,5 +800,7 @@ private
   2797      end
   2798      @users
   2799    end
   2800 +
   2801 +  def idle?; Time.now.to_i - @idle_since.to_i >= ($config[:idle_threshold] || 60); end
   2802  end
   2803  end
   2804 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   2805 index 4f30505..fb684df 100644
   2806 --- a/lib/sup/poll.rb
   2807 +++ b/lib/sup/poll.rb
   2808 @@ -37,6 +37,8 @@ EOS
   2809      @polling = false
   2810      @poll_sources = nil
   2811      @mode = nil
   2812 +    PollTally.init
   2813 +    UpdateManager.register self
   2814    end
   2815  
   2816    def poll_with_sources
   2817 @@ -45,8 +47,9 @@ EOS
   2818  
   2819      BufferManager.flash "Polling for new messages..."
   2820      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
   2821 -    if num > 0
   2822 -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
   2823 +    PollTally.add :num => num, :num_inbox => numi, :loaded_labels => loaded_labels
   2824 +    if PollTally.num > 0
   2825 +      BufferManager.flash "Loaded #{PollTally.num.pluralize 'new message'}, #{PollTally.num_inbox} to inbox. Labels: #{PollTally.loaded_labels.map{|l| l.to_s}.join(', ')}"
   2826      else
   2827        BufferManager.flash "No new messages." 
   2828      end
   2829 @@ -183,6 +186,22 @@ EOS
   2830      Index.add_message m
   2831      UpdateManager.relay self, :added, m
   2832    end
   2833 +
   2834 +  def handle_unidle_update sender, idle_since; PollTally.clear; end
   2835 +end
   2836 +
   2837 +class PollTally
   2838 +  include Singleton
   2839 +  attr_reader :num, :num_inbox, :loaded_labels
   2840 +
   2841 +  def initialize; @num = 0; @num_inbox = 0; @loaded_labels = Set.new; end
   2842 +  def clear; @num = 0; @num_inbox = 0; @loaded_labels.clear; end
   2843 +
   2844 +  def add opts={}
   2845 +    @num += opts[:num]||0
   2846 +    @num_inbox += opts[:num_inbox]||0
   2847 +    @loaded_labels = Set.new(opts[:loaded_labels] || []) + @loaded_labels
   2848 +  end
   2849  end
   2850  
   2851  end
   2852 -- 
   2853 1.6.5.7
   2854 
   2855 From hyperbolist@gmail.com  Mon Jan  4 06:47:46 2010
   2856 From: hyperbolist@gmail.com (Eric Sherman)
   2857 Date: Mon, 04 Jan 2010 06:47:46 -0500
   2858 Subject: [sup-devel] [PATCH] [issue14] poll updates accumulate while idle
   2859 In-Reply-To: <1262585888-sup-7490@changeling.local>
   2860 References: <1262585888-sup-7490@changeling.local>
   2861 Message-ID: <1262605439-sup-7146@changeling.local>
   2862 
   2863 Excerpts from Eric Sherman's message of Mon Jan 04 01:20:34 -0500 2010:
   2864 > If you were to leave sup running for a long time, this patch would
   2865 > enable you to get a glance summary of new mail activity since sup was
   2866 > last touched, by letting the poll update message accumulate its tally
   2867 > while idle.
   2868 > 
   2869 > On keystrokes, BufferManager sends an :unidle update if the last
   2870 > keystroke occurred more than :idle_threshold seconds ago.  PollManager
   2871 > listens for :unidle updates to clear PollTally, which will otherwise
   2872 > accumulate.
   2873 > 
   2874 > * :idle_threshold defaults to 60 seconds if not defined in config.yaml
   2875 > * presently no :idle update is sent when becoming idle
   2876 > * after-poll behavior is unaffected
   2877 > ---
   2878 >  lib/sup.rb        |    3 ++-
   2879 >  lib/sup/buffer.rb |    5 +++++
   2880 >  lib/sup/poll.rb   |   23 +++++++++++++++++++++--
   2881 >  3 files changed, 28 insertions(+), 3 deletions(-)
   2882 > 
   2883 > diff --git a/lib/sup.rb b/lib/sup.rb
   2884 > index 840b3fc..a6de0ab 100644
   2885 > --- a/lib/sup.rb
   2886 > +++ b/lib/sup.rb
   2887 > @@ -229,7 +229,8 @@ else
   2888 >      :confirm_top_posting => true,
   2889 >      :discard_snippets_from_encrypted_messages => false,
   2890 >      :default_attachment_save_dir => "",
   2891 > -    :sent_source => "sup://sent"
   2892 > +    :sent_source => "sup://sent",
   2893 > +    :idle_threshold => 60
   2894 >    }
   2895 >    begin
   2896 >      FileUtils.mkdir_p Redwood::BASE_DIR
   2897 > diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
   2898 > index c826ab9..c34917d 100644
   2899 > --- a/lib/sup/buffer.rb
   2900 > +++ b/lib/sup/buffer.rb
   2901 > @@ -212,6 +212,7 @@ EOS
   2902 >      @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
   2903 >      @sigwinch_happened = false
   2904 >      @sigwinch_mutex = Mutex.new
   2905 > +    @idle_since = Time.now
   2906 >    end
   2907 >  
   2908 >    def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
   2909 > @@ -269,6 +270,8 @@ EOS
   2910 >          @focus_buf.mode.cancel_search!
   2911 >          @focus_buf.mark_dirty
   2912 >        end
   2913 > +      UpdateManager.relay self, :unidle, Time.at(@idle_since) if idle?
   2914 > +      @idle_since = Time.now
   2915 >        @focus_buf.mode.handle_input c
   2916 >      end
   2917 >    end
   2918 > @@ -797,5 +800,7 @@ private
   2919 >      end
   2920 >      @users
   2921 >    end
   2922 > +
   2923 > +  def idle?; Time.now.to_i - @idle_since.to_i >= ($config[:idle_threshold] || 60); end
   2924 >  end
   2925 >  end
   2926 > diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   2927 > index 4f30505..fb684df 100644
   2928 > --- a/lib/sup/poll.rb
   2929 > +++ b/lib/sup/poll.rb
   2930 > @@ -37,6 +37,8 @@ EOS
   2931 >      @polling = false
   2932 >      @poll_sources = nil
   2933 >      @mode = nil
   2934 > +    PollTally.init
   2935 > +    UpdateManager.register self
   2936 >    end
   2937 >  
   2938 >    def poll_with_sources
   2939 > @@ -45,8 +47,9 @@ EOS
   2940 >  
   2941 >      BufferManager.flash "Polling for new messages..."
   2942 >      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
   2943 > -    if num > 0
   2944 > -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
   2945 > +    PollTally.add :num => num, :num_inbox => numi, :loaded_labels => loaded_labels
   2946 > +    if PollTally.num > 0
   2947 > +      BufferManager.flash "Loaded #{PollTally.num.pluralize 'new message'}, #{PollTally.num_inbox} to inbox. Labels: #{PollTally.loaded_labels.map{|l| l.to_s}.join(', ')}"
   2948 >      else
   2949 >        BufferManager.flash "No new messages." 
   2950 >      end
   2951 > @@ -183,6 +186,22 @@ EOS
   2952 >      Index.add_message m
   2953 >      UpdateManager.relay self, :added, m
   2954 >    end
   2955 > +
   2956 > +  def handle_unidle_update sender, idle_since; PollTally.clear; end
   2957 > +end
   2958 > +
   2959 > +class PollTally
   2960 > +  include Singleton
   2961 > +  attr_reader :num, :num_inbox, :loaded_labels
   2962 > +
   2963 > +  def initialize; @num = 0; @num_inbox = 0; @loaded_labels = Set.new; end
   2964 > +  def clear; @num = 0; @num_inbox = 0; @loaded_labels.clear; end
   2965 > +
   2966 > +  def add opts={}
   2967 > +    @num += opts[:num]||0
   2968 > +    @num_inbox += opts[:num_inbox]||0
   2969 > +    @loaded_labels = Set.new(opts[:loaded_labels] || []) + @loaded_labels
   2970 > +  end
   2971 >  end
   2972 >  
   2973 >  end
   2974 
   2975 Oops, please disregard this patch.  If one never goes idle, one can never 
   2976 go unidle, and so the PollTally will never clear.  I will resubmit a 
   2977 revised patch which clears the PollTally on polling unless idle.
   2978 
   2979 From hyperbolist@gmail.com  Mon Jan  4 07:14:33 2010
   2980 From: hyperbolist@gmail.com (Eric Sherman)
   2981 Date: Mon, 04 Jan 2010 07:14:33 -0500
   2982 Subject: [sup-devel] [PATCHv2] [issue14] poll updates accumulate while idle
   2983 Message-ID: <1262607214-sup-4535@changeling.local>
   2984 
   2985 If you were to leave sup running for a long time, this patch would
   2986 enable you to get a glance summary of new mail activity since sup was
   2987 last touched, by letting the poll update message accumulate its tally
   2988 while idle.
   2989 
   2990 On keystrokes, BufferManager sends an :unidle update if the last
   2991 keystroke occurred more than :idle_threshold seconds ago.  PollManager
   2992 listens for :unidle updates to clear PollTally.  It is also cleared on
   2993 each poll unless idle.
   2994 
   2995 * :idle_threshold defaults to 60 seconds if not defined in config.yaml
   2996 * presently no :idle update is sent when becoming idle
   2997 * but we can check for idleness with BufferManager.idle?
   2998 * after-poll behavior is unaffected
   2999 ---
   3000  lib/sup.rb        |    3 ++-
   3001  lib/sup/buffer.rb |    5 +++++
   3002  lib/sup/poll.rb   |   24 ++++++++++++++++++++++--
   3003  3 files changed, 29 insertions(+), 3 deletions(-)
   3004 
   3005 diff --git a/lib/sup.rb b/lib/sup.rb
   3006 index 840b3fc..a6de0ab 100644
   3007 --- a/lib/sup.rb
   3008 +++ b/lib/sup.rb
   3009 @@ -229,7 +229,8 @@ else
   3010      :confirm_top_posting => true,
   3011      :discard_snippets_from_encrypted_messages => false,
   3012      :default_attachment_save_dir => "",
   3013 -    :sent_source => "sup://sent"
   3014 +    :sent_source => "sup://sent",
   3015 +    :idle_threshold => 60
   3016    }
   3017    begin
   3018      FileUtils.mkdir_p Redwood::BASE_DIR
   3019 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
   3020 index c826ab9..8bf666b 100644
   3021 --- a/lib/sup/buffer.rb
   3022 +++ b/lib/sup/buffer.rb
   3023 @@ -212,6 +212,7 @@ EOS
   3024      @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
   3025      @sigwinch_happened = false
   3026      @sigwinch_mutex = Mutex.new
   3027 +    @idle_since = Time.now
   3028    end
   3029  
   3030    def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
   3031 @@ -269,6 +270,8 @@ EOS
   3032          @focus_buf.mode.cancel_search!
   3033          @focus_buf.mark_dirty
   3034        end
   3035 +      UpdateManager.relay self, :unidle, Time.at(@idle_since) if idle?
   3036 +      @idle_since = Time.now
   3037        @focus_buf.mode.handle_input c
   3038      end
   3039    end
   3040 @@ -761,6 +764,8 @@ EOS
   3041      @shelled = false
   3042    end
   3043  
   3044 +  def idle?; Time.now.to_i - @idle_since.to_i >= ($config[:idle_threshold] || 60); end
   3045 +
   3046  private
   3047  
   3048    def default_status_bar buf
   3049 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   3050 index 4f30505..48228ca 100644
   3051 --- a/lib/sup/poll.rb
   3052 +++ b/lib/sup/poll.rb
   3053 @@ -37,6 +37,8 @@ EOS
   3054      @polling = false
   3055      @poll_sources = nil
   3056      @mode = nil
   3057 +    PollTally.init
   3058 +    UpdateManager.register self
   3059    end
   3060  
   3061    def poll_with_sources
   3062 @@ -45,8 +47,10 @@ EOS
   3063  
   3064      BufferManager.flash "Polling for new messages..."
   3065      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
   3066 -    if num > 0
   3067 -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
   3068 +    PollTally.clear unless BufferManager.idle?
   3069 +    PollTally.add :num => num, :num_inbox => numi, :loaded_labels => loaded_labels
   3070 +    if PollTally.num > 0
   3071 +      BufferManager.flash "Loaded #{PollTally.num.pluralize 'new message'}, #{PollTally.num_inbox} to inbox. Labels: #{PollTally.loaded_labels.map{|l| l.to_s}.join(', ')}"
   3072      else
   3073        BufferManager.flash "No new messages." 
   3074      end
   3075 @@ -183,6 +187,22 @@ EOS
   3076      Index.add_message m
   3077      UpdateManager.relay self, :added, m
   3078    end
   3079 +
   3080 +  def handle_unidle_update sender, idle_since; PollTally.clear; end
   3081 +end
   3082 +
   3083 +class PollTally
   3084 +  include Singleton
   3085 +  attr_reader :num, :num_inbox, :loaded_labels
   3086 +
   3087 +  def initialize; @num = 0; @num_inbox = 0; @loaded_labels = Set.new; end
   3088 +  def clear; @num = 0; @num_inbox = 0; @loaded_labels.clear; end
   3089 +
   3090 +  def add opts={}
   3091 +    @num += opts[:num]||0
   3092 +    @num_inbox += opts[:num_inbox]||0
   3093 +    @loaded_labels = Set.new(opts[:loaded_labels] || []) + @loaded_labels
   3094 +  end
   3095  end
   3096  
   3097  end
   3098 -- 
   3099 1.6.5.7
   3100 
   3101 From hyperbolist@gmail.com  Mon Jan  4 10:23:55 2010
   3102 From: hyperbolist@gmail.com (Eric Sherman)
   3103 Date: Mon, 04 Jan 2010 10:23:55 -0500
   3104 Subject: [sup-devel] [PATCH] [issue7] configurable poll interval
   3105 Message-ID: <1262618580-sup-7433@changeling.local>
   3106 
   3107 This patch does not add configurable per-source poll intervals, but it
   3108 does add a single :poll_interval which still defaults to 300 seconds if
   3109 not defined in config.yaml.
   3110 ---
   3111  lib/sup.rb      |    3 ++-
   3112  lib/sup/poll.rb |    2 +-
   3113  2 files changed, 3 insertions(+), 2 deletions(-)
   3114 
   3115 diff --git a/lib/sup.rb b/lib/sup.rb
   3116 index 840b3fc..b83bbe7 100644
   3117 --- a/lib/sup.rb
   3118 +++ b/lib/sup.rb
   3119 @@ -229,7 +229,8 @@ else
   3120      :confirm_top_posting => true,
   3121      :discard_snippets_from_encrypted_messages => false,
   3122      :default_attachment_save_dir => "",
   3123 -    :sent_source => "sup://sent"
   3124 +    :sent_source => "sup://sent",
   3125 +    :poll_interval => 300
   3126    }
   3127    begin
   3128      FileUtils.mkdir_p Redwood::BASE_DIR
   3129 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   3130 index 4f30505..f3e1224 100644
   3131 --- a/lib/sup/poll.rb
   3132 +++ b/lib/sup/poll.rb
   3133 @@ -28,7 +28,7 @@ num_inbox_total_unread: the total number of unread messages in the inbox
   3134                          only those messages appearing in the inbox
   3135  EOS
   3136  
   3137 -  DELAY = 300
   3138 +  DELAY = $config[:poll_interval] || 300
   3139  
   3140    def initialize
   3141      @mutex = Mutex.new
   3142 -- 
   3143 1.6.5.7
   3144 
   3145 
   3146 From sup-bugs@masanjin.net  Mon Jan  4 13:11:23 2010
   3147 From: sup-bugs@masanjin.net (Ben Walton)
   3148 Date: Mon, 04 Jan 2010 18:11:23 +0000
   3149 Subject: [sup-devel] [issue43] fails to start after running current next
   3150 In-Reply-To: <1262628683.67.0.115853254107.issue43@masanjin.net>
   3151 Message-ID: <1262628683.67.0.115853254107.issue43@masanjin.net>
   3152 
   3153 
   3154 New submission from Ben Walton <bwalton at artsci.utoronto.ca>:
   3155 
   3156 Sup failed to start after updating to next (sha1: a1669), which is where the
   3157 ruby-1.9-encoding branch was merged.  It seems that my ruby doesn't like the
   3158 :BINARY suffix on the file open mode introduced by commit a6bb5.  Removing
   3159 :BINARY from the mode parameter works for me.  Eg: wr:BINARY -> wb, ab:BINARY ->
   3160 ab, etc.
   3161 
   3162 -Ben
   3163 
   3164 ----------
   3165 messages: 108
   3166 nosy: bwalton
   3167 priority: bug
   3168 ruby_version: 1.8.5
   3169 status: unread
   3170 sup_version: next/a1669
   3171 title: fails to start after running current next
   3172 
   3173 _________________________________________
   3174 Sup issue tracker <sup-bugs at masanjin.net>
   3175 <http://masanjin.net/sup-bugs/issue43>
   3176 _________________________________________
   3177 
   3178 From rlane@club.cc.cmu.edu  Mon Jan  4 14:19:40 2010
   3179 From: rlane@club.cc.cmu.edu (Rich Lane)
   3180 Date: Mon,  4 Jan 2010 11:19:40 -0800
   3181 Subject: [sup-devel] [PATCH] add console commands to get/set loglevel
   3182 Message-ID: <1262632780-3661-1-git-send-email-rlane@club.cc.cmu.edu>
   3183 
   3184 ---
   3185  lib/sup/logger.rb             |    3 ++-
   3186  lib/sup/modes/console-mode.rb |    4 ++++
   3187  2 files changed, 6 insertions(+), 1 deletions(-)
   3188 
   3189 diff --git a/lib/sup/logger.rb b/lib/sup/logger.rb
   3190 index ccaeae0..ab97e47 100644
   3191 --- a/lib/sup/logger.rb
   3192 +++ b/lib/sup/logger.rb
   3193 @@ -14,13 +14,14 @@ class Logger
   3194  
   3195    def initialize level=nil
   3196      level ||= ENV["SUP_LOG_LEVEL"] || "info"
   3197 -    @level = LEVELS.index(level) or raise ArgumentError, "invalid log level #{level.inspect}: should be one of #{LEVELS * ', '}"
   3198 +    self.level = level
   3199      @mutex = Mutex.new
   3200      @buf = StringIO.new
   3201      @sinks = []
   3202    end
   3203  
   3204    def level; LEVELS[@level] end
   3205 +  def level=(level); @level = LEVELS.index(level) || raise(ArgumentError, "invalid log level #{level.inspect}: should be one of #{LEVELS * ', '}"); end
   3206  
   3207    def add_sink s, copy_current=true
   3208      @mutex.synchronize do
   3209 diff --git a/lib/sup/modes/console-mode.rb b/lib/sup/modes/console-mode.rb
   3210 index e9bf47c..8ea8f38 100644
   3211 --- a/lib/sup/modes/console-mode.rb
   3212 +++ b/lib/sup/modes/console-mode.rb
   3213 @@ -21,6 +21,10 @@ class Console
   3214  
   3215    def xapian; Index.instance.instance_variable_get :@xapian; end
   3216    def ferret; Index.instance.instance_variable_get :@index; end
   3217 +
   3218 +  def loglevel; Redwood::Logger.level; end
   3219 +  def set_loglevel(level); Redwood::Logger.level = level; end
   3220 +
   3221    def special_methods; methods - Object.methods end
   3222  
   3223    ## files that won't cause problems when reloaded
   3224 -- 
   3225 1.6.3.3
   3226 
   3227 
   3228 From rlane@club.cc.cmu.edu  Mon Jan  4 14:34:31 2010
   3229 From: rlane@club.cc.cmu.edu (Rich Lane)
   3230 Date: Mon,  4 Jan 2010 11:34:31 -0800
   3231 Subject: [sup-devel] [PATCH] implement String#each on Ruby 1.9 for lockfile
   3232 Message-ID: <1262633671-5690-1-git-send-email-rlane@club.cc.cmu.edu>
   3233 
   3234 ---
   3235  lib/sup/util.rb |    6 ++++++
   3236  1 files changed, 6 insertions(+), 0 deletions(-)
   3237 
   3238 diff --git a/lib/sup/util.rb b/lib/sup/util.rb
   3239 index 206c18a..2d3a2ad 100644
   3240 --- a/lib/sup/util.rb
   3241 +++ b/lib/sup/util.rb
   3242 @@ -290,6 +290,12 @@ class String
   3243      end
   3244    end
   3245  
   3246 +  unless method_defined? :each
   3247 +    def each &b
   3248 +      each_line &b
   3249 +    end
   3250 +  end
   3251 +
   3252    ## takes a list of words, and returns an array of symbols.  typically used in
   3253    ## Sup for translating Ferret's representation of a list of labels (a string)
   3254    ## to an array of label symbols.
   3255 -- 
   3256 1.6.3.3
   3257 
   3258 
   3259 From rlane@club.cc.cmu.edu  Mon Jan  4 14:35:17 2010
   3260 From: rlane@club.cc.cmu.edu (Rich Lane)
   3261 Date: Mon,  4 Jan 2010 11:35:17 -0800
   3262 Subject: [sup-devel] [PATCH] implement const_missing for Index
   3263 Message-ID: <1262633717-5803-1-git-send-email-rlane@club.cc.cmu.edu>
   3264 
   3265 Otherwise, constant references to LockError and ParseError will fail.
   3266 ---
   3267 This should be added to the ruby-1.9-encoding branch.
   3268 
   3269  lib/sup/index.rb |    1 +
   3270  1 files changed, 1 insertions(+), 0 deletions(-)
   3271 
   3272 diff --git a/lib/sup/index.rb b/lib/sup/index.rb
   3273 index f02c96b..8a4b8f2 100644
   3274 --- a/lib/sup/index.rb
   3275 +++ b/lib/sup/index.rb
   3276 @@ -234,6 +234,7 @@ class Index
   3277  
   3278    def self.instance; @obj end
   3279    def self.method_missing m, *a, &b; @obj.send(m, *a, &b) end
   3280 +  def self.const_missing x; @obj.class.const_get(x) end
   3281  end
   3282  
   3283  end
   3284 -- 
   3285 1.6.3.3
   3286 
   3287 
   3288 From wmorgan-sup@masanjin.net  Mon Jan  4 14:43:58 2010
   3289 From: wmorgan-sup@masanjin.net (William Morgan)
   3290 Date: Mon, 04 Jan 2010 11:43:58 -0800
   3291 Subject: [sup-devel] [PATCH] implement const_missing for Index
   3292 In-Reply-To: <1262633717-5803-1-git-send-email-rlane@club.cc.cmu.edu>
   3293 References: <1262633717-5803-1-git-send-email-rlane@club.cc.cmu.edu>
   3294 Message-ID: <1262634229-sup-3258@masanjin.net>
   3295 
   3296 Reformatted excerpts from Rich Lane's message of 2010-01-04:
   3297 > This should be added to the ruby-1.9-encoding branch.
   3298 
   3299 Not to ferret-deprecation?
   3300 -- 
   3301 William <wmorgan-sup at masanjin.net>
   3302 
   3303 From rlane@club.cc.cmu.edu  Mon Jan  4 14:45:42 2010
   3304 From: rlane@club.cc.cmu.edu (Rich Lane)
   3305 Date: Mon,  4 Jan 2010 11:45:42 -0800
   3306 Subject: [sup-devel] [PATCH] only open mail files in binary mode on Ruby 1.9
   3307 Message-ID: <1262634342-7029-1-git-send-email-rlane@club.cc.cmu.edu>
   3308 
   3309 ---
   3310  lib/sup/maildir.rb     |    4 ++--
   3311  lib/sup/mbox/loader.rb |    4 ++--
   3312  lib/sup/util.rb        |    7 +++++++
   3313  3 files changed, 11 insertions(+), 4 deletions(-)
   3314 
   3315 diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
   3316 index 0852576..b2c5847 100644
   3317 --- a/lib/sup/maildir.rb
   3318 +++ b/lib/sup/maildir.rb
   3319 @@ -59,7 +59,7 @@ class Maildir < Source
   3320          File.stat(tmp_path)
   3321        rescue Errno::ENOENT #this is what we want.
   3322          begin
   3323 -          File.open(tmp_path, 'wb:BINARY') do |f|
   3324 +          File.open_binary(tmp_path, 'w') do |f|
   3325              yield f #provide a writable interface for the caller
   3326              f.fsync
   3327            end
   3328 @@ -207,7 +207,7 @@ private
   3329    def with_file_for id
   3330      fn = @ids_to_fns[id] or raise OutOfSyncSourceError, "No such id: #{id.inspect}."
   3331      begin
   3332 -      File.open(fn, 'rb:BINARY') { |f| yield f }
   3333 +      File.open_binary(fn, 'r') { |f| yield f }
   3334      rescue SystemCallError, IOError => e
   3335        raise FatalSourceError, "Problem reading file for id #{id.inspect}: #{fn.inspect}: #{e.message}."
   3336      end
   3337 diff --git a/lib/sup/mbox/loader.rb b/lib/sup/mbox/loader.rb
   3338 index ec28d3b..557c13b 100644
   3339 --- a/lib/sup/mbox/loader.rb
   3340 +++ b/lib/sup/mbox/loader.rb
   3341 @@ -22,7 +22,7 @@ class Loader < Source
   3342        raise ArgumentError, "not an mbox uri" unless uri.scheme == "mbox"
   3343        raise ArgumentError, "mbox URI ('#{uri}') cannot have a host: #{uri.host}" if uri.host
   3344        raise ArgumentError, "mbox URI must have a path component" unless uri.path
   3345 -      @f = File.open uri.path, 'rb:BINARY'
   3346 +      @f = File.open_binary uri.path, 'r'
   3347        @path = uri.path
   3348      else
   3349        @f = uri_or_fp
   3350 @@ -114,7 +114,7 @@ class Loader < Source
   3351  
   3352    def store_message date, from_email, &block
   3353      need_blank = File.exists?(@filename) && !File.zero?(@filename)
   3354 -    File.open(@filename, "ab:BINARY") do |f|
   3355 +    File.open_binary(@filename, "a") do |f|
   3356        f.puts if need_blank
   3357        f.puts "From #{from_email} #{date.rfc2822}"
   3358        yield f
   3359 diff --git a/lib/sup/util.rb b/lib/sup/util.rb
   3360 index c27e527..e8f3289 100644
   3361 --- a/lib/sup/util.rb
   3362 +++ b/lib/sup/util.rb
   3363 @@ -691,3 +691,10 @@ class Iconv
   3364      end
   3365    end
   3366  end
   3367 +
   3368 +class File
   3369 +  def self.open_binary filename, mode
   3370 +    mode += 'b:BINARY' if String.method_defined? :encoding
   3371 +    open filename, mode
   3372 +  end
   3373 +end
   3374 -- 
   3375 1.6.3.3
   3376 
   3377 
   3378 From rlane@club.cc.cmu.edu  Mon Jan  4 14:48:13 2010
   3379 From: rlane@club.cc.cmu.edu (Rich Lane)
   3380 Date: Mon, 04 Jan 2010 14:48:13 -0500
   3381 Subject: [sup-devel] [PATCH] implement const_missing for Index
   3382 In-Reply-To: <1262634229-sup-3258@masanjin.net>
   3383 References: <1262633717-5803-1-git-send-email-rlane@club.cc.cmu.edu>
   3384 	<1262634229-sup-3258@masanjin.net>
   3385 Message-ID: <1262634455-sup-4406@zyrg.net>
   3386 
   3387 Excerpts from William Morgan's message of 2010-01-04 14:43:58 -0500:
   3388 > Reformatted excerpts from Rich Lane's message of 2010-01-04:
   3389 > > This should be added to the ruby-1.9-encoding branch.
   3390 > 
   3391 > Not to ferret-deprecation?
   3392 
   3393 Oh, right, sorry. Airports are messing with my brain.
   3394 
   3395 From pi+sup@pihost.us  Tue Jan  5 12:20:24 2010
   3396 From: pi+sup@pihost.us (Anthony Martinez)
   3397 Date: Tue,  5 Jan 2010 10:20:24 -0700
   3398 Subject: [sup-devel] [PATCH] fix up options for sup-sync-back, tweak-labels
   3399 Message-ID: <1262712024-25264-1-git-send-email-pi+sup@pihost.us>
   3400 
   3401 These two violate the convention of the other scripts inside bin/ by
   3402 using a local variable for their Trollop results.
   3403 ---
   3404  bin/sup-sync-back    |    2 +-
   3405  bin/sup-tweak-labels |    2 +-
   3406  2 files changed, 2 insertions(+), 2 deletions(-)
   3407 
   3408 diff --git a/bin/sup-sync-back b/bin/sup-sync-back
   3409 index 19e6230..40c1e1c 100755
   3410 --- a/bin/sup-sync-back
   3411 +++ b/bin/sup-sync-back
   3412 @@ -66,7 +66,7 @@ EOS
   3413  end
   3414  
   3415  Redwood::start
   3416 -index = Redwood::Index.init $opts[:index]
   3417 +index = Redwood::Index.init opts[:index]
   3418  index.lock_interactively or exit
   3419  
   3420  deleted_fp, spam_fp = nil
   3421 diff --git a/bin/sup-tweak-labels b/bin/sup-tweak-labels
   3422 index f603502..bf36a32 100755
   3423 --- a/bin/sup-tweak-labels
   3424 +++ b/bin/sup-tweak-labels
   3425 @@ -61,7 +61,7 @@ remove_labels = opts[:remove].to_set_of_symbols ","
   3426  Trollop::die "nothing to do: no labels to add or remove" if add_labels.empty? && remove_labels.empty?
   3427  
   3428  Redwood::start
   3429 -index = Redwood::Index.init $opts[:index]
   3430 +index = Redwood::Index.init opts[:index]
   3431  index.lock_interactively or exit
   3432  begin
   3433    index.load
   3434 -- 
   3435 1.6.5
   3436 
   3437 
   3438 From wmorgan-sup@masanjin.net  Tue Jan  5 16:01:30 2010
   3439 From: wmorgan-sup@masanjin.net (William Morgan)
   3440 Date: Tue, 05 Jan 2010 13:01:30 -0800
   3441 Subject: [sup-devel] [PATCH] xapian: translate from/to query term
   3442 	prefixes to search over both name and email fields
   3443 In-Reply-To: <1262407046-2029-1-git-send-email-rlane@club.cc.cmu.edu>
   3444 References: <1262407046-2029-1-git-send-email-rlane@club.cc.cmu.edu>
   3445 Message-ID: <1262725281-sup-9273@masanjin.net>
   3446 
   3447 Branch xapain-name-email, merged into next. Thanks!
   3448 -- 
   3449 William <wmorgan-sup at masanjin.net>
   3450 
   3451 From wmorgan-sup@masanjin.net  Tue Jan  5 16:02:56 2010
   3452 From: wmorgan-sup@masanjin.net (William Morgan)
   3453 Date: Tue, 05 Jan 2010 13:02:56 -0800
   3454 Subject: [sup-devel] [PATCH 3/3] add keybinding 'Oc' to reload colors
   3455 In-Reply-To: <1262532260-18353-3-git-send-email-rlane@club.cc.cmu.edu>
   3456 References: <1262532260-18353-1-git-send-email-rlane@club.cc.cmu.edu>
   3457 	<1262532260-18353-2-git-send-email-rlane@club.cc.cmu.edu>
   3458 	<1262532260-18353-3-git-send-email-rlane@club.cc.cmu.edu>
   3459 Message-ID: <1262725368-sup-9219@masanjin.net>
   3460 
   3461 Branch colors, merged into next. Thanks!
   3462 -- 
   3463 William <wmorgan-sup at masanjin.net>
   3464 
   3465 From wmorgan-sup@masanjin.net  Tue Jan  5 16:04:24 2010
   3466 From: wmorgan-sup@masanjin.net (William Morgan)
   3467 Date: Tue, 05 Jan 2010 13:04:24 -0800
   3468 Subject: [sup-devel] [PATCH] add a mouse-enabled colorpicker to contrib
   3469 In-Reply-To: <1262532808-19401-1-git-send-email-rlane@club.cc.cmu.edu>
   3470 References: <1262532808-19401-1-git-send-email-rlane@club.cc.cmu.edu>
   3471 Message-ID: <1262725450-sup-277@masanjin.net>
   3472 
   3473 I've also thrown this on the colors branch. Looks fun!
   3474 -- 
   3475 William <wmorgan-sup at masanjin.net>
   3476 
   3477 From ezyang@MIT.EDU  Tue Jan  5 16:06:10 2010
   3478 From: ezyang@MIT.EDU (Edward Z. Yang)
   3479 Date: Tue, 05 Jan 2010 16:06:10 -0500
   3480 Subject: [sup-devel] [PATCH] xapian: translate from/to query term
   3481 	prefixes to search over both name and email fields
   3482 In-Reply-To: <1262407046-2029-1-git-send-email-rlane@club.cc.cmu.edu>
   3483 References: <1262407046-2029-1-git-send-email-rlane@club.cc.cmu.edu>
   3484 Message-ID: <1262725553-sup-8271@ezyang>
   3485 
   3486 At last! Good patch.
   3487 
   3488 Cheers,
   3489 Edward
   3490 
   3491 From wmorgan-sup@masanjin.net  Tue Jan  5 16:25:18 2010
   3492 From: wmorgan-sup@masanjin.net (William Morgan)
   3493 Date: Tue, 05 Jan 2010 13:25:18 -0800
   3494 Subject: [sup-devel] [PATCH 1/3] punctuate "No new messages."
   3495 	consistently between poll, jump_to_next_new
   3496 In-Reply-To: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   3497 References: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   3498 Message-ID: <1262726709-sup-1303@masanjin.net>
   3499 
   3500 Applied directly to master. Thanks!
   3501 -- 
   3502 William <wmorgan-sup at masanjin.net>
   3503 
   3504 From wmorgan-sup@masanjin.net  Tue Jan  5 16:25:29 2010
   3505 From: wmorgan-sup@masanjin.net (William Morgan)
   3506 Date: Tue, 05 Jan 2010 13:25:29 -0800
   3507 Subject: [sup-devel] [PATCH 2/3] undoing read_and_archive should
   3508 	preserve unread state
   3509 In-Reply-To: <1262585196-25964-2-git-send-email-pi+sup@pihost.us>
   3510 References: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   3511 	<1262585196-25964-2-git-send-email-pi+sup@pihost.us>
   3512 Message-ID: <1262726721-sup-9317@masanjin.net>
   3513 
   3514 Applied directly to master. Thanks!
   3515 -- 
   3516 William <wmorgan-sup at masanjin.net>
   3517 
   3518 From wmorgan-sup@masanjin.net  Tue Jan  5 16:26:42 2010
   3519 From: wmorgan-sup@masanjin.net (William Morgan)
   3520 Date: Tue, 05 Jan 2010 13:26:42 -0800
   3521 Subject: [sup-devel] [PATCH 3/3] make the undo hooks also save the
   3522 	threads
   3523 In-Reply-To: <1262585196-25964-3-git-send-email-pi+sup@pihost.us>
   3524 References: <1262585196-25964-1-git-send-email-pi+sup@pihost.us>
   3525 	<1262585196-25964-2-git-send-email-pi+sup@pihost.us>
   3526 	<1262585196-25964-3-git-send-email-pi+sup@pihost.us>
   3527 Message-ID: <1262726732-sup-3562@masanjin.net>
   3528 
   3529 Sorry to be a pain. Can you resend this patch against the insta-save
   3530 branch? (It looks like I don't have the necessary blobs for a 3-way
   3531 merge, so I suspect you generated this against an unpublished commit?)
   3532 -- 
   3533 William <wmorgan-sup at masanjin.net>
   3534 
   3535 From wmorgan-sup@masanjin.net  Tue Jan  5 16:30:58 2010
   3536 From: wmorgan-sup@masanjin.net (William Morgan)
   3537 Date: Tue, 05 Jan 2010 13:30:58 -0800
   3538 Subject: [sup-devel] [PATCH] [issue7] configurable poll interval
   3539 In-Reply-To: <1262618580-sup-7433@changeling.local>
   3540 References: <1262618580-sup-7433@changeling.local>
   3541 Message-ID: <1262727050-sup-1624@masanjin.net>
   3542 
   3543 Applied to master. Thanks!
   3544 -- 
   3545 William <wmorgan-sup at masanjin.net>
   3546 
   3547 From wmorgan-sup@masanjin.net  Tue Jan  5 16:33:44 2010
   3548 From: wmorgan-sup@masanjin.net (William Morgan)
   3549 Date: Tue, 05 Jan 2010 13:33:44 -0800
   3550 Subject: [sup-devel] [PATCH] add console commands to get/set loglevel
   3551 In-Reply-To: <1262632780-3661-1-git-send-email-rlane@club.cc.cmu.edu>
   3552 References: <1262632780-3661-1-git-send-email-rlane@club.cc.cmu.edu>
   3553 Message-ID: <1262727217-sup-9167@masanjin.net>
   3554 
   3555 Applied to master. Thanks!
   3556 -- 
   3557 William <wmorgan-sup at masanjin.net>
   3558 
   3559 From wmorgan-sup@masanjin.net  Tue Jan  5 16:34:10 2010
   3560 From: wmorgan-sup@masanjin.net (William Morgan)
   3561 Date: Tue, 05 Jan 2010 13:34:10 -0800
   3562 Subject: [sup-devel] [PATCH] implement String#each on Ruby 1.9 for
   3563 	lockfile
   3564 In-Reply-To: <1262633671-5690-1-git-send-email-rlane@club.cc.cmu.edu>
   3565 References: <1262633671-5690-1-git-send-email-rlane@club.cc.cmu.edu>
   3566 Message-ID: <1262727237-sup-9108@masanjin.net>
   3567 
   3568 So lame. Applied to master. Thanks!
   3569 -- 
   3570 William <wmorgan-sup at masanjin.net>
   3571 
   3572 From wmorgan-sup@masanjin.net  Tue Jan  5 16:50:18 2010
   3573 From: wmorgan-sup@masanjin.net (William Morgan)
   3574 Date: Tue, 05 Jan 2010 13:50:18 -0800
   3575 Subject: [sup-devel] [PATCH] implement const_missing for Index
   3576 In-Reply-To: <1262633717-5803-1-git-send-email-rlane@club.cc.cmu.edu>
   3577 References: <1262633717-5803-1-git-send-email-rlane@club.cc.cmu.edu>
   3578 Message-ID: <1262728206-sup-3668@masanjin.net>
   3579 
   3580 Reformatted excerpts from Rich Lane's message of 2010-01-04:
   3581 > Otherwise, constant references to LockError and ParseError will fail.
   3582 
   3583 Applied to ferret-deprecation and remerged into next. Thanks!
   3584 -- 
   3585 William <wmorgan-sup at masanjin.net>
   3586 
   3587 From wmorgan-sup@masanjin.net  Tue Jan  5 16:58:35 2010
   3588 From: wmorgan-sup@masanjin.net (William Morgan)
   3589 Date: Tue, 05 Jan 2010 13:58:35 -0800
   3590 Subject: [sup-devel] [PATCH] fix up options for sup-sync-back,
   3591 	tweak-labels
   3592 In-Reply-To: <1262712024-25264-1-git-send-email-pi+sup@pihost.us>
   3593 References: <1262712024-25264-1-git-send-email-pi+sup@pihost.us>
   3594 Message-ID: <1262728682-sup-9444@masanjin.net>
   3595 
   3596 Reformatted excerpts from Anthony Martinez's message of 2010-01-05:
   3597 > These two violate the convention of the other scripts inside bin/ by
   3598 > using a local variable for their Trollop results.
   3599 
   3600 I actually prefer the non-global-variable version, so maybe should say
   3601 the other scripts violate the convention. :)
   3602 
   3603 Branch ferret-deprecation, remerged into next. Thanks!
   3604 -- 
   3605 William <wmorgan-sup at masanjin.net>
   3606 
   3607 From wmorgan-sup@masanjin.net  Tue Jan  5 17:05:21 2010
   3608 From: wmorgan-sup@masanjin.net (William Morgan)
   3609 Date: Tue, 05 Jan 2010 14:05:21 -0800
   3610 Subject: [sup-devel] [PATCH] only open mail files in binary mode on Ruby
   3611 	1.9
   3612 In-Reply-To: <1262634342-7029-1-git-send-email-rlane@club.cc.cmu.edu>
   3613 References: <1262634342-7029-1-git-send-email-rlane@club.cc.cmu.edu>
   3614 Message-ID: <1262729069-sup-2235@masanjin.net>
   3615 
   3616 Applied to ruby-1.9-encodings. I added another commit to make it pass
   3617 through any block, otherwise it was silently failing on my 1.8.7 setup.
   3618 Hope it still works for 1.9. :) Thanks!
   3619 -- 
   3620 William <wmorgan-sup at masanjin.net>
   3621 
   3622 From pi+sup@pihost.us  Tue Jan  5 17:45:38 2010
   3623 From: pi+sup@pihost.us (Anthony Martinez)
   3624 Date: Tue,  5 Jan 2010 15:45:38 -0700
   3625 Subject: [sup-devel] [PATCH-insta-save] make the undo hooks also save the
   3626 	threads
   3627 In-Reply-To: <1262726732-sup-3562@masanjin.net>
   3628 References: <1262726732-sup-3562@masanjin.net>
   3629 Message-ID: <1262731539-29227-1-git-send-email-pi+sup@pihost.us>
   3630 
   3631 As requested, a patch against insta-save. Hopefully this works out better.
   3632 
   3633 I generated this by rebasing my local next onto origin/next, then checked out
   3634 a local insta-save and cherry-picked next. There shouldn't be any dependences
   3635 on unpublished commits, though, git says my next is only head by this one
   3636 patch.
   3637 
   3638 From pi+sup@pihost.us  Tue Jan  5 17:45:39 2010
   3639 From: pi+sup@pihost.us (Anthony Martinez)
   3640 Date: Tue,  5 Jan 2010 15:45:39 -0700
   3641 Subject: [sup-devel] [PATCH] make the undo hooks also save the threads
   3642 In-Reply-To: <1262731539-29227-1-git-send-email-pi+sup@pihost.us>
   3643 References: <1262726732-sup-3562@masanjin.net>
   3644 	<1262731539-29227-1-git-send-email-pi+sup@pihost.us>
   3645 Message-ID: <1262731539-29227-2-git-send-email-pi+sup@pihost.us>
   3646 
   3647 Since there is no explicit sync any longer, any action that has an
   3648 Index.save_thread must also repeat the save when the action is undone.
   3649 Failure to do this will result in an exception upon quit when the index
   3650 notices that there are still dirty messages.
   3651 ---
   3652  lib/sup/modes/inbox-mode.rb        |    4 ++++
   3653  lib/sup/modes/thread-index-mode.rb |   18 ++++++++++++------
   3654  lib/sup/modes/thread-view-mode.rb  |    4 ++++
   3655  3 files changed, 20 insertions(+), 6 deletions(-)
   3656 
   3657 diff --git a/lib/sup/modes/inbox-mode.rb b/lib/sup/modes/inbox-mode.rb
   3658 index 9220925..e2452e5 100644
   3659 --- a/lib/sup/modes/inbox-mode.rb
   3660 +++ b/lib/sup/modes/inbox-mode.rb
   3661 @@ -29,6 +29,7 @@ class InboxMode < ThreadIndexMode
   3662      UndoManager.register "archiving thread" do
   3663        thread.apply_label :inbox
   3664        add_or_unhide thread.first
   3665 +      Index.save_thread thread
   3666      end
   3667  
   3668      cursor_thread.remove_label :inbox
   3669 @@ -42,6 +43,7 @@ class InboxMode < ThreadIndexMode
   3670        threads.map do |t|
   3671          t.apply_label :inbox
   3672          add_or_unhide t.first
   3673 +        Index.save_thread t
   3674        end
   3675        regen_text
   3676      end
   3677 @@ -62,6 +64,7 @@ class InboxMode < ThreadIndexMode
   3678        thread.apply_label :inbox
   3679        thread.apply_label :unread
   3680        add_or_unhide thread.first
   3681 +      Index.save_thread thread
   3682      end
   3683  
   3684      cursor_thread.remove_label :unread
   3685 @@ -85,6 +88,7 @@ class InboxMode < ThreadIndexMode
   3686        threads.zip(old_labels).each do |t, l|
   3687          t.labels = l
   3688          add_or_unhide t.first
   3689 +        Index.save_thread t
   3690        end
   3691        regen_text
   3692      end
   3693 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   3694 index bbc9044..7808190 100644
   3695 --- a/lib/sup/modes/thread-index-mode.rb
   3696 +++ b/lib/sup/modes/thread-index-mode.rb
   3697 @@ -265,7 +265,7 @@ EOS
   3698    def toggle_starred 
   3699      t = cursor_thread or return
   3700      undo = actually_toggle_starred t
   3701 -    UndoManager.register "toggling thread starred status", undo
   3702 +    UndoManager.register "toggling thread starred status", undo, lambda { Index.save_thread t }
   3703      update_text_for_line curpos
   3704      cursor_down
   3705      Index.save_thread t
   3706 @@ -273,7 +273,8 @@ EOS
   3707  
   3708    def multi_toggle_starred threads
   3709      UndoManager.register "toggling #{threads.size.pluralize 'thread'} starred status",
   3710 -      threads.map { |t| actually_toggle_starred t }
   3711 +      threads.map { |t| actually_toggle_starred t },
   3712 +      lambda { threads.each { |t| Index.save_thread t } }
   3713      regen_text
   3714      threads.each { |t| Index.save_thread t }
   3715    end
   3716 @@ -351,14 +352,16 @@ EOS
   3717    def toggle_archived 
   3718      t = cursor_thread or return
   3719      undo = actually_toggle_archived t
   3720 -    UndoManager.register "deleting/undeleting thread #{t.first.id}", undo, lambda { update_text_for_line curpos }
   3721 +    UndoManager.register "deleting/undeleting thread #{t.first.id}", undo, lambda { update_text_for_line curpos },
   3722 +                         lambda { Index.save_thread t }
   3723      update_text_for_line curpos
   3724      Index.save_thread t
   3725    end
   3726  
   3727    def multi_toggle_archived threads
   3728      undos = threads.map { |t| actually_toggle_archived t }
   3729 -    UndoManager.register "deleting/undeleting #{threads.size.pluralize 'thread'}", undos, lambda { regen_text }
   3730 +    UndoManager.register "deleting/undeleting #{threads.size.pluralize 'thread'}", undos, lambda { regen_text },
   3731 +                         lambda { threads.each { |t| Index.save_thread t } }
   3732      regen_text
   3733      threads.each { |t| Index.save_thread t }
   3734    end
   3735 @@ -425,7 +428,7 @@ EOS
   3736    def multi_toggle_spam threads
   3737      undos = threads.map { |t| actually_toggle_spammed t }
   3738      UndoManager.register "marking/unmarking  #{threads.size.pluralize 'thread'} as spam",
   3739 -                         undos, lambda { regen_text }
   3740 +                         undos, lambda { regen_text }, lambda { threads.each { |t| Index.save_thread t } }
   3741      regen_text
   3742      threads.each { |t| Index.save_thread t }
   3743    end
   3744 @@ -439,7 +442,7 @@ EOS
   3745    def multi_toggle_deleted threads
   3746      undos = threads.map { |t| actually_toggle_deleted t }
   3747      UndoManager.register "deleting/undeleting #{threads.size.pluralize 'thread'}",
   3748 -                         undos, lambda { regen_text }
   3749 +                         undos, lambda { regen_text }, lambda { threads.each { |t| Index.save_thread t } }
   3750      regen_text
   3751      threads.each { |t| Index.save_thread t }
   3752    end
   3753 @@ -455,6 +458,7 @@ EOS
   3754        threads.each do |t|
   3755          t.remove_label :killed
   3756          add_or_unhide t.first
   3757 +        Index.save_thread t
   3758        end
   3759        regen_text
   3760      end
   3761 @@ -530,6 +534,7 @@ EOS
   3762        thread.labels = old_labels
   3763        update_text_for_line pos
   3764        UpdateManager.relay self, :labeled, thread.first
   3765 +      Index.save_thread thread
   3766      end
   3767  
   3768      UpdateManager.relay self, :labeled, thread.first
   3769 @@ -567,6 +572,7 @@ EOS
   3770        threads.zip(old_labels).map do |t, old_labels|
   3771          t.labels = old_labels
   3772          UpdateManager.relay self, :labeled, t.first
   3773 +        Index.save_thread t
   3774        end
   3775        regen_text
   3776      end
   3777 diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb
   3778 index 99abb04..ddac113 100644
   3779 --- a/lib/sup/modes/thread-view-mode.rb
   3780 +++ b/lib/sup/modes/thread-view-mode.rb
   3781 @@ -262,6 +262,7 @@ EOS
   3782      Index.save_thread @thread
   3783      UndoManager.register "labeling thread" do
   3784        @thread.labels = old_labels
   3785 +      Index.save_thread @thread
   3786        UpdateManager.relay self, :labeled, @thread.first
   3787      end
   3788    end
   3789 @@ -484,6 +485,7 @@ EOS
   3790        Index.save_thread @thread
   3791        UndoManager.register "archiving 1 thread" do
   3792          @thread.apply_label :inbox
   3793 +        Index.save_thread @thread
   3794          UpdateManager.relay self, :unarchived, @thread.first
   3795        end
   3796      end
   3797 @@ -496,6 +498,7 @@ EOS
   3798        Index.save_thread @thread
   3799        UndoManager.register "marking 1 thread as spam" do
   3800          @thread.remove_label :spam
   3801 +        Index.save_thread @thread
   3802          UpdateManager.relay self, :unspammed, @thread.first
   3803        end
   3804      end
   3805 @@ -508,6 +511,7 @@ EOS
   3806        Index.save_thread @thread
   3807        UndoManager.register "deleting 1 thread" do
   3808          @thread.remove_label :deleted
   3809 +        Index.save_thread @thread
   3810          UpdateManager.relay self, :undeleted, @thread.first
   3811        end
   3812      end
   3813 -- 
   3814 1.6.5
   3815 
   3816 
   3817 From wmorgan-sup@masanjin.net  Tue Jan  5 18:47:08 2010
   3818 From: wmorgan-sup@masanjin.net (William Morgan)
   3819 Date: Tue, 05 Jan 2010 15:47:08 -0800
   3820 Subject: [sup-devel] [PATCH-insta-save] make the undo hooks also save
   3821 	the threads
   3822 In-Reply-To: <1262731539-29227-1-git-send-email-pi+sup@pihost.us>
   3823 References: <1262726732-sup-3562@masanjin.net>
   3824 	<1262731539-29227-1-git-send-email-pi+sup@pihost.us>
   3825 Message-ID: <1262735108-sup-1634@masanjin.net>
   3826 
   3827 Reformatted excerpts from Anthony Martinez's message of 2010-01-05:
   3828 > As requested, a patch against insta-save. Hopefully this works out better.
   3829 
   3830 Applied to insta-save and remerged into next. Thanks!
   3831 
   3832 > I generated this by rebasing my local next onto origin/next, then
   3833 > checked out a local insta-save and cherry-picked next. There shouldn't
   3834 > be any dependences on unpublished commits, though, git says my next is
   3835 > only head by this one patch.
   3836 
   3837 Ah, the magic of git!
   3838 
   3839 Thanks for all your recent patches, btw. Top notch stuff.
   3840 -- 
   3841 William <wmorgan-sup at masanjin.net>
   3842 
   3843 From wmorgan-sup@masanjin.net  Wed Jan  6 11:35:55 2010
   3844 From: wmorgan-sup@masanjin.net (William Morgan)
   3845 Date: Wed, 06 Jan 2010 08:35:55 -0800
   3846 Subject: [sup-devel] [PATCH] only open mail files in binary mode on Ruby
   3847 	1.9
   3848 In-Reply-To: <1262729069-sup-2235@masanjin.net>
   3849 References: <1262634342-7029-1-git-send-email-rlane@club.cc.cmu.edu>
   3850 	<1262729069-sup-2235@masanjin.net>
   3851 Message-ID: <1262795751-sup-4525@masanjin.net>
   3852 
   3853 Reformatted excerpts from William Morgan's message of 2010-01-05:
   3854 > Applied to ruby-1.9-encodings. I added another commit to make it pass
   3855 > through any block, otherwise it was silently failing on my 1.8.7 setup.
   3856 > Hope it still works for 1.9. :) Thanks!
   3857 
   3858 The internet claims that using "rb" and "wb" works for both 1.8.5 and
   3859 1.9.1, but I haven't tried it.
   3860 -- 
   3861 William <wmorgan-sup at masanjin.net>
   3862 
   3863 From rlane@club.cc.cmu.edu  Wed Jan  6 22:34:18 2010
   3864 From: rlane@club.cc.cmu.edu (Rich Lane)
   3865 Date: Wed,  6 Jan 2010 19:34:18 -0800
   3866 Subject: [sup-devel] [PATCH] call index.load in sup-add
   3867 Message-ID: <1262835258-6130-1-git-send-email-rlane@club.cc.cmu.edu>
   3868 
   3869 If it's going to call index.save, it needs to load it first.
   3870 ---
   3871  bin/sup-add |    1 +
   3872  1 files changed, 1 insertions(+), 0 deletions(-)
   3873 
   3874 diff --git a/bin/sup-add b/bin/sup-add
   3875 index c53378d..a7a3752 100755
   3876 --- a/bin/sup-add
   3877 +++ b/bin/sup-add
   3878 @@ -86,6 +86,7 @@ end
   3879  $terminal.wrap_at = :auto
   3880  Redwood::start
   3881  index = Redwood::Index.init
   3882 +index.load
   3883  
   3884  index.lock_interactively or exit
   3885  
   3886 -- 
   3887 1.6.5.2
   3888 
   3889 
   3890 From sup-bugs@masanjin.net  Thu Jan  7 06:19:50 2010
   3891 From: sup-bugs@masanjin.net (Gregor Hoffleit)
   3892 Date: Thu, 07 Jan 2010 11:19:50 +0000
   3893 Subject: [sup-devel] [issue44] Inbox mode: Cursor should stick to current
   3894 	message when new	messages are polled in
   3895 In-Reply-To: <1262863190.45.0.140099138564.issue44@masanjin.net>
   3896 Message-ID: <1262863190.45.0.140099138564.issue44@masanjin.net>
   3897 
   3898 
   3899 New submission from Gregor Hoffleit <gregor at hoffleit.de>:
   3900 
   3901 When new messages are polled in during inbox mode, the cursor should move down 
   3902 along with the current message.
   3903 
   3904 Currently, when new messages are polled in while in inbox mode, the cursor stays 
   3905 at the same display line, while the old messages are pushed down. Consequently, 
   3906 the cursor ends up on another message.
   3907 
   3908 Every once in a while I end up tagging/archiving wrongs threads due to this 
   3909 misbehavior.
   3910 
   3911 ----------
   3912 messages: 109
   3913 nosy: flight
   3914 priority: bug
   3915 ruby_version: 1.8.7
   3916 status: unread
   3917 sup_version: next/dd641
   3918 title: Inbox mode: Cursor should stick to current message when new messages are polled in
   3919 
   3920 _________________________________________
   3921 Sup issue tracker <sup-bugs at masanjin.net>
   3922 <http://masanjin.net/sup-bugs/issue44>
   3923 _________________________________________
   3924 
   3925 From hyperbolist@gmail.com  Tue Jan 12 09:51:02 2010
   3926 From: hyperbolist@gmail.com (Eric Sherman)
   3927 Date: Tue, 12 Jan 2010 09:51:02 -0500
   3928 Subject: [sup-devel] [PATCHv2] [issue14] poll updates accumulate while
   3929 	idle
   3930 In-Reply-To: <1262607214-sup-4535@changeling.local>
   3931 References: <1262607214-sup-4535@changeling.local>
   3932 Message-ID: <1263307713-sup-7005@changeling.local>
   3933 
   3934 Excerpts from Eric Sherman's message of Mon Jan 04 07:14:33 -0500 2010:
   3935 > If you were to leave sup running for a long time, this patch would
   3936 > enable you to get a glance summary of new mail activity since sup was
   3937 > last touched, by letting the poll update message accumulate its tally
   3938 > while idle.
   3939 > 
   3940 > On keystrokes, BufferManager sends an :unidle update if the last
   3941 > keystroke occurred more than :idle_threshold seconds ago.  PollManager
   3942 > listens for :unidle updates to clear PollTally.  It is also cleared on
   3943 > each poll unless idle.
   3944 > 
   3945 > * :idle_threshold defaults to 60 seconds if not defined in config.yaml
   3946 > * presently no :idle update is sent when becoming idle
   3947 > * but we can check for idleness with BufferManager.idle?
   3948 > * after-poll behavior is unaffected
   3949 > ---
   3950 >  lib/sup.rb        |    3 ++-
   3951 >  lib/sup/buffer.rb |    5 +++++
   3952 >  lib/sup/poll.rb   |   24 ++++++++++++++++++++++--
   3953 >  3 files changed, 29 insertions(+), 3 deletions(-)
   3954 > 
   3955 > diff --git a/lib/sup.rb b/lib/sup.rb
   3956 > index 840b3fc..a6de0ab 100644
   3957 > --- a/lib/sup.rb
   3958 > +++ b/lib/sup.rb
   3959 > @@ -229,7 +229,8 @@ else
   3960 >      :confirm_top_posting => true,
   3961 >      :discard_snippets_from_encrypted_messages => false,
   3962 >      :default_attachment_save_dir => "",
   3963 > -    :sent_source => "sup://sent"
   3964 > +    :sent_source => "sup://sent",
   3965 > +    :idle_threshold => 60
   3966 >    }
   3967 >    begin
   3968 >      FileUtils.mkdir_p Redwood::BASE_DIR
   3969 > diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
   3970 > index c826ab9..8bf666b 100644
   3971 > --- a/lib/sup/buffer.rb
   3972 > +++ b/lib/sup/buffer.rb
   3973 > @@ -212,6 +212,7 @@ EOS
   3974 >      @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
   3975 >      @sigwinch_happened = false
   3976 >      @sigwinch_mutex = Mutex.new
   3977 > +    @idle_since = Time.now
   3978 >    end
   3979 >  
   3980 >    def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
   3981 > @@ -269,6 +270,8 @@ EOS
   3982 >          @focus_buf.mode.cancel_search!
   3983 >          @focus_buf.mark_dirty
   3984 >        end
   3985 > +      UpdateManager.relay self, :unidle, Time.at(@idle_since) if idle?
   3986 > +      @idle_since = Time.now
   3987 >        @focus_buf.mode.handle_input c
   3988 >      end
   3989 >    end
   3990 > @@ -761,6 +764,8 @@ EOS
   3991 >      @shelled = false
   3992 >    end
   3993 >  
   3994 > +  def idle?; Time.now.to_i - @idle_since.to_i >= ($config[:idle_threshold] || 60); end
   3995 > +
   3996 >  private
   3997 >  
   3998 >    def default_status_bar buf
   3999 > diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   4000 > index 4f30505..48228ca 100644
   4001 > --- a/lib/sup/poll.rb
   4002 > +++ b/lib/sup/poll.rb
   4003 > @@ -37,6 +37,8 @@ EOS
   4004 >      @polling = false
   4005 >      @poll_sources = nil
   4006 >      @mode = nil
   4007 > +    PollTally.init
   4008 > +    UpdateManager.register self
   4009 >    end
   4010 >  
   4011 >    def poll_with_sources
   4012 > @@ -45,8 +47,10 @@ EOS
   4013 >  
   4014 >      BufferManager.flash "Polling for new messages..."
   4015 >      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
   4016 > -    if num > 0
   4017 > -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
   4018 > +    PollTally.clear unless BufferManager.idle?
   4019 > +    PollTally.add :num => num, :num_inbox => numi, :loaded_labels => loaded_labels
   4020 > +    if PollTally.num > 0
   4021 > +      BufferManager.flash "Loaded #{PollTally.num.pluralize 'new message'}, #{PollTally.num_inbox} to inbox. Labels: #{PollTally.loaded_labels.map{|l| l.to_s}.join(', ')}"
   4022 >      else
   4023 >        BufferManager.flash "No new messages." 
   4024 >      end
   4025 > @@ -183,6 +187,22 @@ EOS
   4026 >      Index.add_message m
   4027 >      UpdateManager.relay self, :added, m
   4028 >    end
   4029 > +
   4030 > +  def handle_unidle_update sender, idle_since; PollTally.clear; end
   4031 > +end
   4032 > +
   4033 > +class PollTally
   4034 > +  include Singleton
   4035 > +  attr_reader :num, :num_inbox, :loaded_labels
   4036 > +
   4037 > +  def initialize; @num = 0; @num_inbox = 0; @loaded_labels = Set.new; end
   4038 > +  def clear; @num = 0; @num_inbox = 0; @loaded_labels.clear; end
   4039 > +
   4040 > +  def add opts={}
   4041 > +    @num += opts[:num]||0
   4042 > +    @num_inbox += opts[:num_inbox]||0
   4043 > +    @loaded_labels = Set.new(opts[:loaded_labels] || []) + @loaded_labels
   4044 > +  end
   4045 >  end
   4046 >  
   4047 >  end
   4048 
   4049 What manner of reimplementation would increase this patch's likelihood for 
   4050 inclusion?  Or is my whole approach JustWrong for sup?
   4051 
   4052 * @idle_since should probably be renamed to @no_keystrokes_since
   4053 * PollTally should probably be replaced by a hash
   4054 
   4055 Aside from its ugliness I'm happy with the result: running poll totals 
   4056 while idle.
   4057 
   4058 An alternative implementation with the above changes follows in reply, but 
   4059 it's probably still too ugly for inclusion.
   4060 
   4061 From hyperbolist@gmail.com  Tue Jan 12 09:56:21 2010
   4062 From: hyperbolist@gmail.com (Eric Sherman)
   4063 Date: Tue, 12 Jan 2010 09:56:21 -0500
   4064 Subject: [sup-devel] [PATCHv3] [issue14] poll updates accumulate while idle
   4065 In-Reply-To: <1263307713-sup-7005@changeling.local>
   4066 References: <1262607214-sup-4535@changeling.local>
   4067 	<1263307713-sup-7005@changeling.local>
   4068 Message-ID: <1263308149-sup-5426@changeling.local>
   4069 
   4070 If you were to leave sup running for a long time, this patch would
   4071 enable you to get a glance summary of new mail activity since sup was
   4072 last touched, by letting the poll update message accumulate its totals
   4073 while idle.
   4074 
   4075 On keystrokes, BufferManager sends an :unidle update if the last
   4076 keystroke occurred more than :idle_threshold seconds ago.  PollManager
   4077 listens for :unidle updates to clear @running_totals, which is also
   4078 cleared on each poll unless idle.
   4079 
   4080 * :idle_threshold defaults to 60 seconds if not defined in config.yaml
   4081 * presently no :idle update is sent when becoming idle
   4082 * but we can check for idleness with BufferManager.idle?
   4083 * after-poll behavior is unaffected
   4084 ---
   4085  lib/sup.rb        |    3 ++-
   4086  lib/sup/buffer.rb |    5 +++++
   4087  lib/sup/poll.rb   |   13 +++++++++++--
   4088  3 files changed, 18 insertions(+), 3 deletions(-)
   4089 
   4090 diff --git a/lib/sup.rb b/lib/sup.rb
   4091 index b83bbe7..e228772 100644
   4092 --- a/lib/sup.rb
   4093 +++ b/lib/sup.rb
   4094 @@ -230,7 +230,8 @@ else
   4095      :discard_snippets_from_encrypted_messages => false,
   4096      :default_attachment_save_dir => "",
   4097      :sent_source => "sup://sent",
   4098 -    :poll_interval => 300
   4099 +    :poll_interval => 300,
   4100 +    :idle_threshold => 60
   4101    }
   4102    begin
   4103      FileUtils.mkdir_p Redwood::BASE_DIR
   4104 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
   4105 index c826ab9..2f5eaa8 100644
   4106 --- a/lib/sup/buffer.rb
   4107 +++ b/lib/sup/buffer.rb
   4108 @@ -212,6 +212,7 @@ EOS
   4109      @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
   4110      @sigwinch_happened = false
   4111      @sigwinch_mutex = Mutex.new
   4112 +    @no_keystrokes_since = Time.now
   4113    end
   4114  
   4115    def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
   4116 @@ -269,6 +270,8 @@ EOS
   4117          @focus_buf.mode.cancel_search!
   4118          @focus_buf.mark_dirty
   4119        end
   4120 +      UpdateManager.relay self, :unidle, Time.at(@no_keystrokes_since) if idle?
   4121 +      @no_keystrokes_since = Time.now
   4122        @focus_buf.mode.handle_input c
   4123      end
   4124    end
   4125 @@ -761,6 +764,8 @@ EOS
   4126      @shelled = false
   4127    end
   4128  
   4129 +  def idle?; Time.now.to_i - @no_keystrokes_since.to_i >= ($config[:idle_threshold] || 60); end
   4130 +
   4131  private
   4132  
   4133    def default_status_bar buf
   4134 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   4135 index f3e1224..ad51647 100644
   4136 --- a/lib/sup/poll.rb
   4137 +++ b/lib/sup/poll.rb
   4138 @@ -37,6 +37,8 @@ EOS
   4139      @polling = false
   4140      @poll_sources = nil
   4141      @mode = nil
   4142 +    clear_running_totals
   4143 +    UpdateManager.register self
   4144    end
   4145  
   4146    def poll_with_sources
   4147 @@ -45,8 +47,12 @@ EOS
   4148  
   4149      BufferManager.flash "Polling for new messages..."
   4150      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
   4151 -    if num > 0
   4152 -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
   4153 +    clear_running_totals unless BufferManager.idle?
   4154 +    @running_totals[:num] += num
   4155 +    @running_totals[:numi] += numi
   4156 +    @running_totals[:loaded_labels] += loaded_labels || []
   4157 +    if @running_totals[:num] > 0
   4158 +      BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
   4159      else
   4160        BufferManager.flash "No new messages." 
   4161      end
   4162 @@ -183,6 +189,9 @@ EOS
   4163      Index.add_message m
   4164      UpdateManager.relay self, :added, m
   4165    end
   4166 +
   4167 +  def handle_unidle_update sender, idle_since; clear_running_totals; end
   4168 +  def clear_running_totals; @running_totals = {:num => 0, :numi => 0, :loaded_labels => Set.new}; end
   4169  end
   4170  
   4171  end
   4172 -- 
   4173 1.6.6
   4174 
   4175 From hyperbolist@gmail.com  Tue Jan 12 15:12:04 2010
   4176 From: hyperbolist@gmail.com (Eric Sherman)
   4177 Date: Tue, 12 Jan 2010 15:12:04 -0500
   4178 Subject: [sup-devel] [PATCH] [issue44] cursor sticks to thread
   4179 Message-ID: <1263327054-sup-3431@changeling.local>
   4180 
   4181 The cursor will track the thread it is on when that thread is moved up
   4182 or down on the screen as threads are added or removed from the view.
   4183 ---
   4184  lib/sup/modes/thread-index-mode.rb |    9 +++++++++
   4185  1 files changed, 9 insertions(+), 0 deletions(-)
   4186 
   4187 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   4188 index a5bd344..9e70ec8 100644
   4189 --- a/lib/sup/modes/thread-index-mode.rb
   4190 +++ b/lib/sup/modes/thread-index-mode.rb
   4191 @@ -219,6 +219,10 @@ EOS
   4192    end
   4193  
   4194    def update
   4195 +    ## remember the thread we are on and where the cursor is before we update
   4196 +    old_cursor_thread = cursor_thread
   4197 +    old_cursor_position = curpos
   4198 +
   4199      @mutex.synchronize do
   4200        ## let's see you do THIS in python
   4201        @threads = @ts.threads.select { |t| !@hidden_threads[t] }.sort_by { |t| [t.date, t.first.id] }.reverse
   4202 @@ -226,6 +230,11 @@ EOS
   4203        @size_widget_width = @size_widgets.max_of { |w| w.display_length }
   4204      end
   4205  
   4206 +    ## if the thread moved on screen, move the cursor to its new position
   4207 +    new_cursor_position = @threads.index(old_cursor_thread)||0
   4208 +    (old_cursor_position..(new_cursor_position-1)).each { |x| cursor_down }
   4209 +    (new_cursor_position..(old_cursor_position-1)).each { |x| cursor_up }
   4210 +
   4211      regen_text
   4212    end
   4213  
   4214 -- 
   4215 1.6.6
   4216 
   4217 
   4218 From hyperbolist@gmail.com  Tue Jan 12 15:36:13 2010
   4219 From: hyperbolist@gmail.com (Eric Sherman)
   4220 Date: Tue, 12 Jan 2010 15:36:13 -0500
   4221 Subject: [sup-devel] [PATCHv2] [issue44] cursor sticks to thread
   4222 Message-ID: <1263328554-sup-8440@changeling.local>
   4223 
   4224 This is much more concise version, using set_cursor_pos instead of 
   4225 cursor_up and cursor_down.
   4226 
   4227 The cursor will track the thread it is on when that thread is moved up
   4228 or down on the screen as threads are added or removed from the view.
   4229 ---
   4230  lib/sup/modes/thread-index-mode.rb |    2 ++
   4231  1 files changed, 2 insertions(+), 0 deletions(-)
   4232 
   4233 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   4234 index a5bd344..40f622b 100644
   4235 --- a/lib/sup/modes/thread-index-mode.rb
   4236 +++ b/lib/sup/modes/thread-index-mode.rb
   4237 @@ -219,12 +219,14 @@ EOS
   4238    end
   4239  
   4240    def update
   4241 +    old_cursor_thread = cursor_thread
   4242      @mutex.synchronize do
   4243        ## let's see you do THIS in python
   4244        @threads = @ts.threads.select { |t| !@hidden_threads[t] }.sort_by { |t| [t.date, t.first.id] }.reverse
   4245        @size_widgets = @threads.map { |t| size_widget_for_thread t }
   4246        @size_widget_width = @size_widgets.max_of { |w| w.display_length }
   4247      end
   4248 +    set_cursor_pos @threads.index(old_cursor_thread)||curpos
   4249  
   4250      regen_text
   4251    end
   4252 -- 
   4253 1.6.6
   4254 
   4255 From hyperbolist@gmail.com  Wed Jan 13 08:56:44 2010
   4256 From: hyperbolist@gmail.com (Eric Sherman)
   4257 Date: Wed, 13 Jan 2010 08:56:44 -0500
   4258 Subject: [sup-devel] [PATCH] idle and unidle updates
   4259 Message-ID: <1263390213-sup-2608@changeling.local>
   4260 
   4261 After talking it over with Rich Lane who suggested I check for idleness 
   4262 near the unblocking_getch loop, it made sense to separate it out into its 
   4263 own patch.
   4264 
   4265 The :idle and :unidle updates are relayed only once, when transitioning 
   4266 from one state to the other.
   4267 
   4268 * Is setting 'main' as the relay sender a problem?
   4269 * Is there anything more meaningful to send as the payload than the time of 
   4270 the last keystroke?
   4271 
   4272 ---
   4273  bin/sup    |   16 ++++++++++++++++
   4274  lib/sup.rb |    3 ++-
   4275  2 files changed, 18 insertions(+), 1 deletions(-)
   4276 
   4277 diff --git a/bin/sup b/bin/sup
   4278 index 19b2a87..f4261f4 100755
   4279 --- a/bin/sup
   4280 +++ b/bin/sup
   4281 @@ -260,6 +260,9 @@ begin
   4282      SearchResultsMode.spawn_from_query $opts[:search]
   4283    end
   4284  
   4285 +  no_keystrokes_since = Time.now
   4286 +  idle = false
   4287 +
   4288    until Redwood::exceptions.nonempty? || $die
   4289      c = begin
   4290        Ncurses.nonblocking_getch
   4291 @@ -274,9 +277,22 @@ begin
   4292          debug "redrawing screen on sigwinch"
   4293          BufferManager.completely_redraw_screen
   4294        end
   4295 +
   4296 +      if !idle and Time.now.to_i - no_keystrokes_since.to_i >= ($config[:idle_threshold] || 60)
   4297 +        UpdateManager.relay self, :idle, Time.at(no_keystrokes_since)
   4298 +        idle = true
   4299 +      end
   4300 +
   4301        next
   4302      end
   4303  
   4304 +    if idle
   4305 +      UpdateManager.relay self, :unidle, Time.at(no_keystrokes_since)
   4306 +      idle = false
   4307 +    end
   4308 +
   4309 +    no_keystrokes_since = Time.now
   4310 +
   4311      if c == 410
   4312        ## this is ncurses's way of telling us it's detected a refresh.
   4313        ## since we have our own sigwinch handler, we don't do anything.
   4314 diff --git a/lib/sup.rb b/lib/sup.rb
   4315 index b83bbe7..e228772 100644
   4316 --- a/lib/sup.rb
   4317 +++ b/lib/sup.rb
   4318 @@ -230,7 +230,8 @@ else
   4319      :discard_snippets_from_encrypted_messages => false,
   4320      :default_attachment_save_dir => "",
   4321      :sent_source => "sup://sent",
   4322 -    :poll_interval => 300
   4323 +    :poll_interval => 300,
   4324 +    :idle_threshold => 60
   4325    }
   4326    begin
   4327      FileUtils.mkdir_p Redwood::BASE_DIR
   4328 -- 
   4329 1.6.6
   4330 
   4331 From rlane@club.cc.cmu.edu  Wed Jan 13 13:13:40 2010
   4332 From: rlane@club.cc.cmu.edu (Rich Lane)
   4333 Date: Wed, 13 Jan 2010 10:13:40 -0800
   4334 Subject: [sup-devel] [PATCH] fix ask_for_contacts on Ruby 1.9
   4335 Message-ID: <1263406420-27036-1-git-send-email-rlane@club.cc.cmu.edu>
   4336 
   4337 From: Rich Lane <rlane at vmware.com>
   4338 
   4339 String doesn't respond to :map anymore. The previous code was also joining with
   4340 " " instead of ", ", which was broken.
   4341 ---
   4342  lib/sup/buffer.rb |    2 +-
   4343  1 files changed, 1 insertions(+), 1 deletions(-)
   4344 
   4345 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
   4346 index c826ab9..990dd4a 100644
   4347 --- a/lib/sup/buffer.rb
   4348 +++ b/lib/sup/buffer.rb
   4349 @@ -537,7 +537,7 @@ EOS
   4350    end
   4351  
   4352    def ask_for_contacts domain, question, default_contacts=[]
   4353 -    default = default_contacts.map { |s| s.to_s }.join(" ")
   4354 +    default = default_contacts.is_a?(String) ? default_contacts : default_contacts.map { |s| s.to_s }.join(", ")
   4355      default += " " unless default.empty?
   4356  
   4357      recent = Index.load_contacts(AccountManager.user_emails, :num => 10).map { |c| [c.full_address, c.email] }
   4358 -- 
   4359 1.6.3.3
   4360 
   4361 
   4362 From wmorgan-sup@masanjin.net  Thu Jan 14 08:55:00 2010
   4363 From: wmorgan-sup@masanjin.net (William Morgan)
   4364 Date: Thu, 14 Jan 2010 08:55:00 -0500
   4365 Subject: [sup-devel] [PATCH] call index.load in sup-add
   4366 In-Reply-To: <1262835258-6130-1-git-send-email-rlane@club.cc.cmu.edu>
   4367 References: <1262835258-6130-1-git-send-email-rlane@club.cc.cmu.edu>
   4368 Message-ID: <1263477241-sup-4943@masanjin.net>
   4369 
   4370 Reformatted excerpts from Rich Lane's message of 2010-01-06:
   4371 > If it's going to call index.save, it needs to load it first.
   4372 
   4373 Applied to master, thanks!
   4374 -- 
   4375 William <wmorgan-sup at masanjin.net>
   4376 
   4377 From wmorgan-sup@masanjin.net  Thu Jan 14 09:15:57 2010
   4378 From: wmorgan-sup@masanjin.net (William Morgan)
   4379 Date: Thu, 14 Jan 2010 09:15:57 -0500
   4380 Subject: [sup-devel] [PATCHv3] [issue14] poll updates accumulate while
   4381 	idle
   4382 In-Reply-To: <1263308149-sup-5426@changeling.local>
   4383 References: <1262607214-sup-4535@changeling.local>
   4384 	<1263307713-sup-7005@changeling.local>
   4385 	<1263308149-sup-5426@changeling.local>
   4386 Message-ID: <1263478428-sup-8860@masanjin.net>
   4387 
   4388 Reformatted excerpts from Eric Sherman's message of 2010-01-12:
   4389 > If you were to leave sup running for a long time, this patch would
   4390 > enable you to get a glance summary of new mail activity since sup was
   4391 > last touched, by letting the poll update message accumulate its totals
   4392 > while idle.
   4393 
   4394 I like this. My only request is that idle_threshold be a hard-coded
   4395 constant in buffer.rb, since I'm trying to avoid config-bloat.
   4396 -- 
   4397 William <wmorgan-sup at masanjin.net>
   4398 
   4399 From wmorgan-sup@masanjin.net  Thu Jan 14 09:22:45 2010
   4400 From: wmorgan-sup@masanjin.net (William Morgan)
   4401 Date: Thu, 14 Jan 2010 09:22:45 -0500
   4402 Subject: [sup-devel] [PATCH] idle and unidle updates
   4403 In-Reply-To: <1263390213-sup-2608@changeling.local>
   4404 References: <1263390213-sup-2608@changeling.local>
   4405 Message-ID: <1263478703-sup-3527@masanjin.net>
   4406 
   4407 Reformatted excerpts from Eric Sherman's message of 2010-01-13:
   4408 > After talking it over with Rich Lane who suggested I check for idleness 
   4409 > near the unblocking_getch loop, it made sense to separate it out into its 
   4410 > own patch.
   4411 
   4412 Yes, I like this even better, with the same caveat as before about the
   4413 config option.
   4414 
   4415 > * Is setting 'main' as the relay sender a problem?
   4416 
   4417 I don't think so.
   4418 
   4419 > * Is there anything more meaningful to send as the payload than the time of 
   4420 > the last keystroke?
   4421 
   4422 Probably not. Not a big deal either way.
   4423 
   4424 Are you going to send a second patch that makes use of these events to
   4425 do the accumulation?
   4426 -- 
   4427 William <wmorgan-sup at masanjin.net>
   4428 
   4429 From hyperbolist@gmail.com  Thu Jan 14 09:21:45 2010
   4430 From: hyperbolist@gmail.com (Eric Sherman)
   4431 Date: Thu, 14 Jan 2010 09:21:45 -0500
   4432 Subject: [sup-devel] [PATCHv3] [issue14] poll updates accumulate while
   4433 	idle
   4434 In-Reply-To: <1263478428-sup-8860@masanjin.net>
   4435 References: <1262607214-sup-4535@changeling.local>
   4436 	<1263307713-sup-7005@changeling.local>
   4437 	<1263308149-sup-5426@changeling.local>
   4438 	<1263478428-sup-8860@masanjin.net>
   4439 Message-ID: <1263478890-sup-9356@changeling.local>
   4440 
   4441 Excerpts from William Morgan's message of Thu Jan 14 09:15:57 -0500 2010:
   4442 > Reformatted excerpts from Eric Sherman's message of 2010-01-12:
   4443 > > If you were to leave sup running for a long time, this patch would
   4444 > > enable you to get a glance summary of new mail activity since sup was
   4445 > > last touched, by letting the poll update message accumulate its totals
   4446 > > while idle.
   4447 > 
   4448 > I like this. My only request is that idle_threshold be a hard-coded
   4449 > constant in buffer.rb, since I'm trying to avoid config-bloat.
   4450 
   4451 Ok.  I've since separated the idleness out into its own patch submitted 
   4452 yesterday.  Is 60 seconds a sensible threshold?
   4453 
   4454 From hyperbolist@gmail.com  Thu Jan 14 09:31:22 2010
   4455 From: hyperbolist@gmail.com (Eric Sherman)
   4456 Date: Thu, 14 Jan 2010 09:31:22 -0500
   4457 Subject: [sup-devel] [PATCH] idle and unidle updates
   4458 In-Reply-To: <1263478703-sup-3527@masanjin.net>
   4459 References: <1263390213-sup-2608@changeling.local>
   4460 	<1263478703-sup-3527@masanjin.net>
   4461 Message-ID: <1263479269-sup-3220@changeling.local>
   4462 
   4463 Excerpts from William Morgan's message of Thu Jan 14 09:22:45 -0500 2010:
   4464 > Are you going to send a second patch that makes use of these events to
   4465 > do the accumulation?
   4466 
   4467 Yes.  I wanted to wait till this was accepted though since I wasn't sure 
   4468 about submitting a patch that depends on another patch.
   4469 
   4470 From eg@gaute.vetsj.com  Thu Jan 14 09:39:34 2010
   4471 From: eg@gaute.vetsj.com (Gaute Hope)
   4472 Date: Thu, 14 Jan 2010 15:39:34 +0100
   4473 Subject: [sup-devel] feature request: mute thread
   4474 Message-ID: <1263479817-sup-6114@dolk>
   4475 
   4476 Greetings,
   4477 
   4478 Future feature request: ability to Mute threads - ala GMail's feature.
   4479 
   4480 I don't think this needs much elaboration, but I often end up archiving
   4481 the same thread 19 times - especially different mailing lists where I
   4482 would still like the threads to show up in the inbox in the first place.
   4483 
   4484 - Gaute
   4485 -------------- next part --------------
   4486 A non-text attachment was scrubbed...
   4487 Name: signature.asc
   4488 Type: application/pgp-signature
   4489 Size: 198 bytes
   4490 Desc: not available
   4491 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100114/6f26d04f/attachment.bin>
   4492 
   4493 From bwalton@artsci.utoronto.ca  Thu Jan 14 09:55:43 2010
   4494 From: bwalton@artsci.utoronto.ca (Ben Walton)
   4495 Date: Thu, 14 Jan 2010 09:55:43 -0500
   4496 Subject: [sup-devel] feature request: mute thread
   4497 In-Reply-To: <1263479817-sup-6114@dolk>
   4498 References: <1263479817-sup-6114@dolk>
   4499 Message-ID: <1263480927-sup-7353@ntdws12.chass.utoronto.ca>
   4500 
   4501 Excerpts from Gaute Hope's message of Thu Jan 14 09:39:34 -0500 2010:
   4502 
   4503 > Future feature request: ability to Mute threads - ala GMail's
   4504 > feature.
   4505 
   4506 Already there.  See the & key in index/inbox view.  It's called kill,
   4507 but the effect is what you're after.
   4508 
   4509 HTH.
   4510 -Ben
   4511 -- 
   4512 Ben Walton
   4513 Systems Programmer - CHASS
   4514 University of Toronto
   4515 C:416.407.5610 | W:416.978.4302
   4516 
   4517 GPG Key Id: 8E89F6D2; Key Server: pgp.mit.edu
   4518 Contact me to arrange for a CAcert assurance meeting.
   4519 -------------- next part --------------
   4520 A non-text attachment was scrubbed...
   4521 Name: signature.asc
   4522 Type: application/pgp-signature
   4523 Size: 189 bytes
   4524 Desc: not available
   4525 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100114/ef444262/attachment.bin>
   4526 
   4527 From hyperbolist@gmail.com  Thu Jan 14 10:45:54 2010
   4528 From: hyperbolist@gmail.com (Eric Sherman)
   4529 Date: Thu, 14 Jan 2010 10:45:54 -0500
   4530 Subject: [sup-devel] [PATCHv2] idle and unidle updates
   4531 Message-ID: <1263483819-sup-9886@changeling.local>
   4532 
   4533 ---
   4534  bin/sup |   17 +++++++++++++++++
   4535  1 files changed, 17 insertions(+), 0 deletions(-)
   4536 
   4537 diff --git a/bin/sup b/bin/sup
   4538 index 19b2a87..0d90d00 100755
   4539 --- a/bin/sup
   4540 +++ b/bin/sup
   4541 @@ -260,6 +260,10 @@ begin
   4542      SearchResultsMode.spawn_from_query $opts[:search]
   4543    end
   4544  
   4545 +  IDLE_THRESHOLD = 60
   4546 +  no_keystrokes_since = Time.now
   4547 +  idle = false
   4548 +
   4549    until Redwood::exceptions.nonempty? || $die
   4550      c = begin
   4551        Ncurses.nonblocking_getch
   4552 @@ -274,9 +278,22 @@ begin
   4553          debug "redrawing screen on sigwinch"
   4554          BufferManager.completely_redraw_screen
   4555        end
   4556 +
   4557 +      if !idle and Time.now.to_i - no_keystrokes_since.to_i >= IDLE_THRESHOLD
   4558 +        UpdateManager.relay self, :idle, Time.at(no_keystrokes_since)
   4559 +        idle = true
   4560 +      end
   4561 +
   4562        next
   4563      end
   4564  
   4565 +    if idle
   4566 +      UpdateManager.relay self, :unidle, Time.at(no_keystrokes_since)
   4567 +      idle = false
   4568 +    end
   4569 +
   4570 +    no_keystrokes_since = Time.now
   4571 +
   4572      if c == 410
   4573        ## this is ncurses's way of telling us it's detected a refresh.
   4574        ## since we have our own sigwinch handler, we don't do anything.
   4575 -- 
   4576 1.6.6
   4577 
   4578 
   4579 From hyperbolist@gmail.com  Thu Jan 14 10:51:48 2010
   4580 From: hyperbolist@gmail.com (Eric Sherman)
   4581 Date: Thu, 14 Jan 2010 10:51:48 -0500
   4582 Subject: [sup-devel] [PATCHv4] [issue14] poll updates accumulate while idle
   4583 Message-ID: <1263484192-sup-1782@changeling.local>
   4584 
   4585 If you were to leave sup running for a long time, this patch would
   4586 enable you to get a glance summary of new mail activity since sup was
   4587 last touched, by letting the poll update message accumulate its tally
   4588 while idle.
   4589 
   4590 This patch depends on [PATCHv2] idle and unidle updates.
   4591 ---
   4592  lib/sup/poll.rb |   15 +++++++++++++--
   4593  1 files changed, 13 insertions(+), 2 deletions(-)
   4594 
   4595 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   4596 index f3e1224..e9fba46 100644
   4597 --- a/lib/sup/poll.rb
   4598 +++ b/lib/sup/poll.rb
   4599 @@ -37,6 +37,9 @@ EOS
   4600      @polling = false
   4601      @poll_sources = nil
   4602      @mode = nil
   4603 +    @should_clear_running_totals = false
   4604 +    clear_running_totals # defines @running_totals
   4605 +    UpdateManager.register self
   4606    end
   4607  
   4608    def poll_with_sources
   4609 @@ -45,8 +48,12 @@ EOS
   4610  
   4611      BufferManager.flash "Polling for new messages..."
   4612      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
   4613 -    if num > 0
   4614 -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
   4615 +    clear_running_totals if @should_clear_running_totals
   4616 +    @running_totals[:num] += num
   4617 +    @running_totals[:numi] += numi
   4618 +    @running_totals[:loaded_labels] += loaded_labels || []
   4619 +    if @running_totals[:num] > 0
   4620 +      BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
   4621      else
   4622        BufferManager.flash "No new messages." 
   4623      end
   4624 @@ -183,6 +190,10 @@ EOS
   4625      Index.add_message m
   4626      UpdateManager.relay self, :added, m
   4627    end
   4628 +
   4629 +  def handle_idle_update sender, idle_since; @should_clear_running_totals = false; end
   4630 +  def handle_unidle_update sender, idle_since; @should_clear_running_totals = true; end
   4631 +  def clear_running_totals; @running_totals = {:num => 0, :numi => 0, :loaded_labels => Set.new}; end
   4632  end
   4633  
   4634  end
   4635 -- 
   4636 1.6.6
   4637 
   4638 From eg@gaute.vetsj.com  Thu Jan 14 12:40:49 2010
   4639 From: eg@gaute.vetsj.com (Gaute Hope)
   4640 Date: Thu, 14 Jan 2010 18:40:49 +0100
   4641 Subject: [sup-devel] feature request: mute thread
   4642 In-Reply-To: <1263480927-sup-7353@ntdws12.chass.utoronto.ca>
   4643 References: <1263479817-sup-6114@dolk>
   4644 	<1263480927-sup-7353@ntdws12.chass.utoronto.ca>
   4645 Message-ID: <1263490830-sup-8744@dolk>
   4646 
   4647 Excerpts from Ben Walton's message of 2010-01-14 15:55:43 +0100:
   4648 > Excerpts from Gaute Hope's message of Thu Jan 14 09:39:34 -0500 2010:
   4649 > 
   4650 > > Future feature request: ability to Mute threads - ala GMail's
   4651 > > feature.
   4652 > 
   4653 > Already there.  See the & key in index/inbox view.  It's called kill,
   4654 > but the effect is what you're after.
   4655  
   4656  ah great! didn't know that..
   4657 
   4658 From rlane@club.cc.cmu.edu  Fri Jan 15 00:14:29 2010
   4659 From: rlane@club.cc.cmu.edu (Rich Lane)
   4660 Date: Thu, 14 Jan 2010 21:14:29 -0800
   4661 Subject: [sup-devel] [PATCH] xapian: add boolean terms with zero wdf
   4662 Message-ID: <1263532469-30760-1-git-send-email-rlane@club.cc.cmu.edu>
   4663 
   4664 Xapian's Flint backend stores the document length in every posting, so if the
   4665 document length is changed (by adding a label, for example), every posting
   4666 entry needs to be rewritten. This basically nullifies the performance
   4667 improvement from the Xapian bug 250 fix. We can prevent this by adding these
   4668 terms with 0 within-document-frequency so that their addition or removal
   4669 doesn't change the document length.
   4670 
   4671 This is the analog to notmuch commit ccf2e0cc.
   4672 ---
   4673  lib/sup/xapian_index.rb |    2 +-
   4674  1 files changed, 1 insertions(+), 1 deletions(-)
   4675 
   4676 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   4677 index c81dca4..99d7c0e 100644
   4678 --- a/lib/sup/xapian_index.rb
   4679 +++ b/lib/sup/xapian_index.rb
   4680 @@ -590,7 +590,7 @@ class Xapian::Document
   4681    alias old_add_term add_term
   4682    def add_term term
   4683      if term.length <= Redwood::XapianIndex::MAX_TERM_LENGTH
   4684 -      old_add_term term
   4685 +      old_add_term term, 0
   4686      else
   4687        warn "dropping excessively long term #{term}"
   4688      end
   4689 -- 
   4690 1.6.3.3
   4691 
   4692 
   4693 From eg@gaute.vetsj.com  Fri Jan 15 05:23:03 2010
   4694 From: eg@gaute.vetsj.com (Gaute Hope)
   4695 Date: Fri, 15 Jan 2010 11:23:03 +0100
   4696 Subject: [sup-devel] [issue36] label tab completion with utf-8 chars fail
   4697 In-Reply-To: <1262534029-sup-1213@dolk>
   4698 References: <1261749755.37.0.845609324711.issue36@masanjin.net>
   4699 	<1262533823-sup-5348@dolk> <1262534029-sup-1213@dolk>
   4700 Message-ID: <1263550894-sup-165@dolk>
   4701 
   4702 Excerpts from Gaute Hope's message of 2010-01-03 16:56:17 +0100:
   4703 > Apparently I can't even send messages when I enter the UTF-8 email address
   4704 > manually. 
   4705 
   4706 This also goes for subjects containing UTF-8 chars, i can add them, or
   4707 reply to one containing it - but sup fails when trying to send.
   4708 
   4709 - gaute
   4710 
   4711 From hyperbolist@gmail.com  Fri Jan 15 07:59:41 2010
   4712 From: hyperbolist@gmail.com (Eric Sherman)
   4713 Date: Fri, 15 Jan 2010 07:59:41 -0500
   4714 Subject: [sup-devel] [PATCHv5] [issue14] poll updates accumulate while idle
   4715 Message-ID: <1263560293-sup-9529@changeling.local>
   4716 
   4717 If you were to leave sup running for a long time, this patch would
   4718 enable you to get a glance summary of new mail activity since sup was
   4719 last touched, by letting the poll update message accumulate its tally
   4720 while idle.
   4721 
   4722 Oops, forgot to clear_running_totals on :unidle.
   4723 
   4724 This patch depends on [PATCHv2] idle and unidle updates.
   4725 ---
   4726  lib/sup/poll.rb |   15 +++++++++++++--
   4727  1 files changed, 13 insertions(+), 2 deletions(-)
   4728 
   4729 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
   4730 index f3e1224..6b43b00 100644
   4731 --- a/lib/sup/poll.rb
   4732 +++ b/lib/sup/poll.rb
   4733 @@ -37,6 +37,9 @@ EOS
   4734      @polling = false
   4735      @poll_sources = nil
   4736      @mode = nil
   4737 +    @should_clear_running_totals = false
   4738 +    clear_running_totals # defines @running_totals
   4739 +    UpdateManager.register self
   4740    end
   4741  
   4742    def poll_with_sources
   4743 @@ -45,8 +48,12 @@ EOS
   4744  
   4745      BufferManager.flash "Polling for new messages..."
   4746      num, numi, from_and_subj, from_and_subj_inbox, loaded_labels = @mode.poll
   4747 -    if num > 0
   4748 -      BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox. Labels: #{loaded_labels.map{|l| l.to_s}.join(', ')}"
   4749 +    clear_running_totals if @should_clear_running_totals
   4750 +    @running_totals[:num] += num
   4751 +    @running_totals[:numi] += numi
   4752 +    @running_totals[:loaded_labels] += loaded_labels || []
   4753 +    if @running_totals[:num] > 0
   4754 +      BufferManager.flash "Loaded #{@running_totals[:num].pluralize 'new message'}, #{@running_totals[:numi]} to inbox. Labels: #{@running_totals[:loaded_labels].map{|l| l.to_s}.join(', ')}"
   4755      else
   4756        BufferManager.flash "No new messages." 
   4757      end
   4758 @@ -183,6 +190,10 @@ EOS
   4759      Index.add_message m
   4760      UpdateManager.relay self, :added, m
   4761    end
   4762 +
   4763 +  def handle_idle_update sender, idle_since; @should_clear_running_totals = false; end
   4764 +  def handle_unidle_update sender, idle_since; @should_clear_running_totals = true; clear_running_totals; end
   4765 +  def clear_running_totals; @running_totals = {:num => 0, :numi => 0, :loaded_labels => Set.new}; end
   4766  end
   4767  
   4768  end
   4769 -- 
   4770 1.6.6
   4771 
   4772 
   4773 From rlane@club.cc.cmu.edu  Sat Jan 16 15:03:04 2010
   4774 From: rlane@club.cc.cmu.edu (Rich Lane)
   4775 Date: Sat, 16 Jan 2010 12:03:04 -0800
   4776 Subject: [sup-devel] [PATCH 1/4] dont index redundant data
   4777 Message-ID: <1263672187-5174-1-git-send-email-rlane@club.cc.cmu.edu>
   4778 
   4779 Use the Xapian QueryParser ability to map a prefix in the query to multiple
   4780 prefixes in the index. This means we don't need to store duplicate names, email
   4781 addresses, and subjects. This also adds the stemmed attachment filenames to the
   4782 default (non-prefixed) search. We're storing a subset of the data previous
   4783 versions did, so we're able to read them but they can't read us.
   4784 ---
   4785  lib/sup/xapian_index.rb |   19 ++++++++-----------
   4786  1 files changed, 8 insertions(+), 11 deletions(-)
   4787 
   4788 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   4789 index c81dca4..c0b2f9f 100644
   4790 --- a/lib/sup/xapian_index.rb
   4791 +++ b/lib/sup/xapian_index.rb
   4792 @@ -258,9 +258,9 @@ EOS
   4793      qp.stemming_strategy = Xapian::QueryParser::STEM_SOME
   4794      qp.default_op = Xapian::Query::OP_AND
   4795      qp.add_valuerangeprocessor(Xapian::NumberValueRangeProcessor.new(DATE_VALUENO, 'date:', true))
   4796 -    NORMAL_PREFIX.each { |k,v| qp.add_prefix k, v }
   4797 -    BOOLEAN_PREFIX.each { |k,v| qp.add_boolean_prefix k, v }
   4798 -    xapian_query = qp.parse_query(subs, Xapian::QueryParser::FLAG_PHRASE|Xapian::QueryParser::FLAG_BOOLEAN|Xapian::QueryParser::FLAG_LOVEHATE|Xapian::QueryParser::FLAG_WILDCARD, PREFIX['body'])
   4799 +    NORMAL_PREFIX.each { |k,vs| vs.each { |v| qp.add_prefix k, v } }
   4800 +    BOOLEAN_PREFIX.each { |k,vs| vs.each { |v| qp.add_boolean_prefix k, v } }
   4801 +    xapian_query = qp.parse_query(subs, Xapian::QueryParser::FLAG_PHRASE|Xapian::QueryParser::FLAG_BOOLEAN|Xapian::QueryParser::FLAG_LOVEHATE|Xapian::QueryParser::FLAG_WILDCARD)
   4802  
   4803      raise ParseError if xapian_query.nil? or xapian_query.empty?
   4804      query[:qobj] = xapian_query
   4805 @@ -276,8 +276,9 @@ EOS
   4806      'body' => 'B',
   4807      'from_name' => 'FN',
   4808      'to_name' => 'TN',
   4809 -    'name' => 'N',
   4810 +    'name' => %w(FN TN),
   4811      'attachment' => 'A',
   4812 +    '' => %w(S B FN TN A),
   4813    }
   4814  
   4815    # Unstemmed
   4816 @@ -285,7 +286,7 @@ EOS
   4817      'type' => 'K',
   4818      'from_email' => 'FE',
   4819      'to_email' => 'TE',
   4820 -    'email' => 'E',
   4821 +    'email' => %w(FE TE),
   4822      'date' => 'D',
   4823      'label' => 'L',
   4824      'source_id' => 'I',
   4825 @@ -457,10 +458,8 @@ EOS
   4826      # Person names are indexed with several prefixes
   4827      person_termer = lambda do |d|
   4828        lambda do |p|
   4829 -        ["#{d}_name", "name", "body"].each do |x|
   4830 -          doc.index_text p.name, PREFIX[x]
   4831 -        end if p.name
   4832 -        [d, :any].each { |x| doc.add_term mkterm(:email, x, p.email) }
   4833 +        doc.index_text p.name, PREFIX["#{d}_name"] if p.name
   4834 +        doc.add_term mkterm(:email, d, p.email)
   4835        end
   4836      end
   4837  
   4838 @@ -471,7 +470,6 @@ EOS
   4839      subject_text = m.indexable_subject
   4840      body_text = m.indexable_body
   4841      doc.index_text subject_text, PREFIX['subject']
   4842 -    doc.index_text subject_text, PREFIX['body']
   4843      doc.index_text body_text, PREFIX['body']
   4844      m.attachments.each { |a| doc.index_text a, PREFIX['attachment'] }
   4845  
   4846 @@ -554,7 +552,6 @@ EOS
   4847        case args[0]
   4848        when :from then PREFIX['from_email']
   4849        when :to then PREFIX['to_email']
   4850 -      when :any then PREFIX['email']
   4851        else raise "Invalid email term type #{args[0]}"
   4852        end + args[1].to_s.downcase
   4853      when :source_id
   4854 -- 
   4855 1.6.5.2
   4856 
   4857 
   4858 From rlane@club.cc.cmu.edu  Sat Jan 16 15:03:05 2010
   4859 From: rlane@club.cc.cmu.edu (Rich Lane)
   4860 Date: Sat, 16 Jan 2010 12:03:05 -0800
   4861 Subject: [sup-devel] [PATCH 2/4] index email addresses as text
   4862 In-Reply-To: <1263672187-5174-1-git-send-email-rlane@club.cc.cmu.edu>
   4863 References: <1263672187-5174-1-git-send-email-rlane@club.cc.cmu.edu>
   4864 Message-ID: <1263672187-5174-2-git-send-email-rlane@club.cc.cmu.edu>
   4865 
   4866 This lets you search for an email address (or its component parts, since it's
   4867 indexed as a phrase) with no prefix.
   4868 ---
   4869  lib/sup/xapian_index.rb |    4 +++-
   4870  1 files changed, 3 insertions(+), 1 deletions(-)
   4871 
   4872 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   4873 index c0b2f9f..6fa6c55 100644
   4874 --- a/lib/sup/xapian_index.rb
   4875 +++ b/lib/sup/xapian_index.rb
   4876 @@ -278,7 +278,8 @@ EOS
   4877      'to_name' => 'TN',
   4878      'name' => %w(FN TN),
   4879      'attachment' => 'A',
   4880 -    '' => %w(S B FN TN A),
   4881 +    'email_text' => 'E',
   4882 +    '' => %w(S B FN TN A E),
   4883    }
   4884  
   4885    # Unstemmed
   4886 @@ -459,6 +460,7 @@ EOS
   4887      person_termer = lambda do |d|
   4888        lambda do |p|
   4889          doc.index_text p.name, PREFIX["#{d}_name"] if p.name
   4890 +        doc.index_text p.email, PREFIX['email_text']
   4891          doc.add_term mkterm(:email, d, p.email)
   4892        end
   4893      end
   4894 -- 
   4895 1.6.5.2
   4896 
   4897 
   4898 From rlane@club.cc.cmu.edu  Sat Jan 16 15:03:06 2010
   4899 From: rlane@club.cc.cmu.edu (Rich Lane)
   4900 Date: Sat, 16 Jan 2010 12:03:06 -0800
   4901 Subject: [sup-devel] [PATCH 3/4] id query prefix synonym for msgid
   4902 In-Reply-To: <1263672187-5174-2-git-send-email-rlane@club.cc.cmu.edu>
   4903 References: <1263672187-5174-1-git-send-email-rlane@club.cc.cmu.edu>
   4904 	<1263672187-5174-2-git-send-email-rlane@club.cc.cmu.edu>
   4905 Message-ID: <1263672187-5174-3-git-send-email-rlane@club.cc.cmu.edu>
   4906 
   4907 notmuch has created an "id:<msgid>" convention for referring to emails.
   4908 We already had "msgid:<msgid>", but support this syntax too.
   4909 ---
   4910  lib/sup/xapian_index.rb |    1 +
   4911  1 files changed, 1 insertions(+), 0 deletions(-)
   4912 
   4913 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   4914 index 6fa6c55..eefd492 100644
   4915 --- a/lib/sup/xapian_index.rb
   4916 +++ b/lib/sup/xapian_index.rb
   4917 @@ -293,6 +293,7 @@ EOS
   4918      'source_id' => 'I',
   4919      'attachment_extension' => 'O',
   4920      'msgid' => 'Q',
   4921 +    'id' => 'Q',
   4922      'thread' => 'H',
   4923      'ref' => 'R',
   4924    }
   4925 -- 
   4926 1.6.5.2
   4927 
   4928 
   4929 From rlane@club.cc.cmu.edu  Sat Jan 16 15:03:07 2010
   4930 From: rlane@club.cc.cmu.edu (Rich Lane)
   4931 Date: Sat, 16 Jan 2010 12:03:07 -0800
   4932 Subject: [sup-devel] [PATCH 4/4] trivial index format upgrade
   4933 In-Reply-To: <1263672187-5174-3-git-send-email-rlane@club.cc.cmu.edu>
   4934 References: <1263672187-5174-1-git-send-email-rlane@club.cc.cmu.edu>
   4935 	<1263672187-5174-2-git-send-email-rlane@club.cc.cmu.edu>
   4936 	<1263672187-5174-3-git-send-email-rlane@club.cc.cmu.edu>
   4937 Message-ID: <1263672187-5174-4-git-send-email-rlane@club.cc.cmu.edu>
   4938 
   4939 A v2 client can read a v1 index, but a v1 client cannot read a v2 index. Once
   4940 the v2 client modifies the index the v1 client will be unable to read it. So,
   4941 make the version check match that.
   4942 ---
   4943  lib/sup/xapian_index.rb |    7 +++++--
   4944  1 files changed, 5 insertions(+), 2 deletions(-)
   4945 
   4946 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   4947 index eefd492..464cee1 100644
   4948 --- a/lib/sup/xapian_index.rb
   4949 +++ b/lib/sup/xapian_index.rb
   4950 @@ -8,7 +8,7 @@ module Redwood
   4951  # for searching due to precomputing thread membership.
   4952  class XapianIndex < BaseIndex
   4953    STEM_LANGUAGE = "english"
   4954 -  INDEX_VERSION = '1'
   4955 +  INDEX_VERSION = '2'
   4956  
   4957    ## dates are converted to integers for xapian, and are used for document ids,
   4958    ## so we must ensure they're reasonably valid. this typically only affect
   4959 @@ -35,7 +35,10 @@ EOS
   4960        @xapian = Xapian::WritableDatabase.new(path, Xapian::DB_OPEN)
   4961        db_version = @xapian.get_metadata 'version'
   4962        db_version = '0' if db_version.empty?
   4963 -      if db_version != INDEX_VERSION
   4964 +      if db_version == '1'
   4965 +        info "Upgrading index format 1 to 2"
   4966 +        @xapian.set_metadata 'version', INDEX_VERSION
   4967 +      elsif db_version != INDEX_VERSION
   4968          fail "This Sup version expects a v#{INDEX_VERSION} index, but you have an existing v#{db_version} index. Please downgrade to your previous version and dump your labels before upgrading to this version (then run sup-sync --restore)."
   4969        end
   4970      else
   4971 -- 
   4972 1.6.5.2
   4973 
   4974 
   4975 From tero@tilus.net  Sat Jan 16 17:41:09 2010
   4976 From: tero@tilus.net (Tero Tilus)
   4977 Date: Sun, 17 Jan 2010 00:41:09 +0200
   4978 Subject: [sup-devel] [PATCH] Message#edit_labels [was: [sup-talk] Ruby
   4979 	question: before-add-message.rb and adding multiple labels at once]
   4980 In-Reply-To: <1263574849-sup-3477@sam.mediasupervision.de>
   4981 References: <1263574849-sup-3477@sam.mediasupervision.de>
   4982 Message-ID: <1263680819-sup-415@tilus.net>
   4983 
   4984 Gregor Hoffleit, 2010-01-15 19:01:
   4985 > Ok. I ended up with
   4986 > 
   4987 >     ([:list,:"sup-devel"].each {|l| message.add_label l}; message.remove_label :inbox) if message.subj =~ /\[sup-devel\]/
   4988 > 
   4989 > May I request a new function "message.edit_labels" that groks the syntax
   4990 > of the 'edit labels' command (cf. multi_edit_labels in thread-index-mode.rb):
   4991 > 
   4992 >     message.edit_labels "list sup-devel -inbox" if message.subj =~ /\[sup-devel\]/
   4993 > 
   4994 > Comments?
   4995 
   4996 I'll be using that one too.  Here's a patch.  Message#edit_labels
   4997 accepts array of strings.  I thought it'll be better that way.
   4998 Otherwise it gets really ugly with spaces in labels.
   4999 
   5000 So your usecase would be
   5001 
   5002   message.edit_labels %w{list sup-devel -inbox} if message.subj =~ /\[sup-devel\]/
   5003 
   5004 By the way, my pretty general list-labeling code looks like this
   5005 <http://pastie.org/781240>.
   5006 
   5007 And then the patch...
   5008 
   5009 >From 9eff953dbda404b149a77969305c5732fa1d694e Mon Sep 17 00:00:00 2001
   5010 From: Tero Tilus <tero at tilus.net>
   5011 Date: Sun, 17 Jan 2010 00:23:26 +0200
   5012 Subject: [PATCH] Message#edit_labels
   5013 
   5014 Signed-off-by: Tero Tilus <tero at tilus.net>
   5015 ---
   5016  lib/sup/message.rb |   12 ++++++++++++
   5017  1 files changed, 12 insertions(+), 0 deletions(-)
   5018 
   5019 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
   5020 index 3e55de5..e047927 100644
   5021 --- a/lib/sup/message.rb
   5022 +++ b/lib/sup/message.rb
   5023 @@ -206,6 +206,18 @@ class Message
   5024      @labels.delete l
   5025      @dirty = true
   5026    end
   5027 +  ## calling m.edit_labels ['foo', '-index', '+bar']
   5028 +  ## adds labels foo and bar and removes label index
   5029 +  def edit_labels l_arr
   5030 +    l_arr.each do |signedlabel|
   5031 +      signedlabel, sign, label = signedlabel.match(/^(-|\+)?(.*)$/).to_a
   5032 +      if sign == '-'
   5033 +        remove_label label
   5034 +      else
   5035 +        add_label label
   5036 +      end
   5037 +    end
   5038 +  end
   5039  
   5040    def recipients
   5041      @to + @cc + @bcc
   5042 -- 
   5043 1.5.6.5
   5044 
   5045 
   5046 -- 
   5047 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
   5048 
   5049 From wmorgan-sup@masanjin.net  Sun Jan 17 10:35:01 2010
   5050 From: wmorgan-sup@masanjin.net (William Morgan)
   5051 Date: Sun, 17 Jan 2010 10:35:01 -0500
   5052 Subject: [sup-devel] merged into master: ferret-deprecation
   5053 Message-ID: <1263742220-sup-2852@masanjin.net>
   5054 
   5055 I've merged this branch into master for the 0.10 release.
   5056 
   5057 I added:
   5058 
   5059   ENV["XAPIAN_FLUSH_THRESHOLD"] = "1000"
   5060 
   5061 to the top of xapian_index.rb (which seems to work), because that number
   5062 is an acceptable compromise to the two people who have had memory
   5063 issues.
   5064 
   5065 I'm thinking about also merging in insta-save before 0.10 goes out the
   5066 door, probably with the patch that makes '$' flush Xapian. Thoughts?
   5067 -- 
   5068 William <wmorgan-sup at masanjin.net>
   5069 
   5070 From bwalton@artsci.utoronto.ca  Sun Jan 17 11:11:36 2010
   5071 From: bwalton@artsci.utoronto.ca (Ben Walton)
   5072 Date: Sun, 17 Jan 2010 11:11:36 -0500
   5073 Subject: [sup-devel] merged into master: ferret-deprecation
   5074 In-Reply-To: <1263742220-sup-2852@masanjin.net>
   5075 References: <1263742220-sup-2852@masanjin.net>
   5076 Message-ID: <1263744321-sup-5501@ntdws12.chass.utoronto.ca>
   5077 
   5078 Excerpts from William Morgan's message of Sun Jan 17 10:35:01 -0500 2010:
   5079 
   5080 >   ENV["XAPIAN_FLUSH_THRESHOLD"] = "1000"
   5081 
   5082 A decent value, in my use too.
   5083 
   5084 > I'm thinking about also merging in insta-save before 0.10 goes out the
   5085 > door, probably with the patch that makes '$' flush Xapian. Thoughts?
   5086 
   5087 Yes please!
   5088 
   5089 Thanks
   5090 -Ben
   5091 -- 
   5092 Ben Walton
   5093 Systems Programmer - CHASS
   5094 University of Toronto
   5095 C:416.407.5610 | W:416.978.4302
   5096 
   5097 GPG Key Id: 8E89F6D2; Key Server: pgp.mit.edu
   5098 Contact me to arrange for a CAcert assurance meeting.
   5099 -------------- next part --------------
   5100 A non-text attachment was scrubbed...
   5101 Name: signature.asc
   5102 Type: application/pgp-signature
   5103 Size: 189 bytes
   5104 Desc: not available
   5105 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100117/a8cbc256/attachment.bin>
   5106 
   5107 From rlane@club.cc.cmu.edu  Sun Jan 17 13:50:44 2010
   5108 From: rlane@club.cc.cmu.edu (Rich Lane)
   5109 Date: Sun, 17 Jan 2010 10:50:44 -0800
   5110 Subject: [sup-devel] RFC: Nuke remote sources
   5111 Message-ID: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   5112 
   5113 Every few days someone joins the IRC channel complaining of poor
   5114 performance or bugs with IMAP sources, and we have to tell them to use
   5115 offlineimap or fetchmail instead. This is embarrassing. There are likely
   5116 many more users who don't bother to ask on IRC and either unhappily
   5117 tolerate IMAP or give up on Sup.
   5118 
   5119 Even with IMAP you still need to store a huge index on disk, so I can't
   5120 accept that you'd have enough space for that but not for the actual
   5121 messages. You still need to download every message to index it. Your
   5122 mails aren't any more secure from someone stealing your laptop. The same
   5123 arguments apply to mbox+ssh.
   5124 
   5125 The benefit for me is that I won't have to deal with slow, blocking
   5126 sources when converting the UI to EventMachine.
   5127 
   5128 If people agree that this change is a good idea, I assume William will
   5129 add a deprecation notice to master for 0.10 and merge this patchset to
   5130 next.
   5131 
   5132 From rlane@club.cc.cmu.edu  Sun Jan 17 13:50:45 2010
   5133 From: rlane@club.cc.cmu.edu (Rich Lane)
   5134 Date: Sun, 17 Jan 2010 10:50:45 -0800
   5135 Subject: [sup-devel] [PATCH 1/3] remove mbox+ssh source
   5136 In-Reply-To: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   5137 References: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   5138 Message-ID: <1263754247-20979-2-git-send-email-rlane@club.cc.cmu.edu>
   5139 
   5140 ---
   5141  README.txt                 |    1 -
   5142  Rakefile                   |    1 -
   5143  bin/sup-add                |    8 --
   5144  bin/sup-config             |   13 ---
   5145  doc/NewUserGuide.txt       |    1 -
   5146  lib/sup/mbox.rb            |    2 -
   5147  lib/sup/mbox/ssh-file.rb   |  254 --------------------------------------------
   5148  lib/sup/mbox/ssh-loader.rb |   74 -------------
   5149  8 files changed, 0 insertions(+), 354 deletions(-)
   5150  delete mode 100644 lib/sup/mbox/ssh-file.rb
   5151  delete mode 100644 lib/sup/mbox/ssh-loader.rb
   5152 
   5153 diff --git a/README.txt b/README.txt
   5154 index 4204270..7819f0b 100644
   5155 --- a/README.txt
   5156 +++ b/README.txt
   5157 @@ -100,7 +100,6 @@ Current limitations which will be fixed:
   5158   - ncurses >= 0.9.1
   5159   - rmail >= 0.17
   5160   - highline
   5161 - - net-ssh
   5162   - trollop >= 1.12
   5163   - lockfile
   5164   - mime-types
   5165 diff --git a/Rakefile b/Rakefile
   5166 index 67cd0d2..9cf911b 100644
   5167 --- a/Rakefile
   5168 +++ b/Rakefile
   5169 @@ -51,7 +51,6 @@ spec = Gem::Specification.new do |s|
   5170    s.add_dependency "ncurses", ">= 0.9.1"
   5171    s.add_dependency "rmail", ">= 0.17"
   5172    s.add_dependency "highline"
   5173 -  s.add_dependency "net-ssh"
   5174    s.add_dependency "trollop", ">= 1.12"
   5175    s.add_dependency "lockfile"
   5176    s.add_dependency "mime-types", "~> 1"
   5177 diff --git a/bin/sup-add b/bin/sup-add
   5178 index a7a3752..b92b5ad 100755
   5179 --- a/bin/sup-add
   5180 +++ b/bin/sup-add
   5181 @@ -20,9 +20,6 @@ For mbox files on local disk, use the form:
   5182      mbox:<path to mbox file>, or
   5183      mbox://<path to mbox file>
   5184  
   5185 -For mbox files on remote machines, use the form:
   5186 -    mbox+ssh://<machine name>/<path to mbox file>
   5187 -
   5188  For IMAP folders, use the form (note no username or password!):
   5189      imap://<machine name>/          # unsecure, "INBOX" folder  
   5190      imap://<machine name>/<folder>  # unsecure, arbitrary
   5191 @@ -105,11 +102,6 @@ begin
   5192  
   5193      source = 
   5194        case parsed_uri.scheme
   5195 -      when "mbox+ssh"
   5196 -        say "For SSH connections, if you will use public key authentication, you may leave the username and password blank."
   5197 -        say ""
   5198 -        username, password = get_login_info uri, Redwood::SourceManager.sources
   5199 -        Redwood::MBox::SSHLoader.new uri, username, password, nil, !$opts[:unusual], $opts[:archive], nil, labels
   5200        when "imap", "imaps"
   5201          username, password = get_login_info uri, Redwood::SourceManager.sources
   5202          Redwood::IMAP.new uri, username, password, nil, !$opts[:unusual], $opts[:archive], nil, labels
   5203 diff --git a/bin/sup-config b/bin/sup-config
   5204 index b37e0b2..5541965 100755
   5205 --- a/bin/sup-config
   5206 +++ b/bin/sup-config
   5207 @@ -44,7 +44,6 @@ def add_source
   5208      menu.prompt = "What type of mail source is it? "
   5209      menu.choice("mbox file") { type = :mbox }
   5210      menu.choice("maildir directory") { type = :maildir }
   5211 -    menu.choice("remote mbox file (accessible via ssh)") { type = :mboxssh }
   5212      menu.choice("IMAP server (secure)") { type = :imaps }
   5213      menu.choice("IMAP server (unsecure)") { type = :imap }
   5214      menu.choice("Get me out of here!") { return }
   5215 @@ -70,18 +69,6 @@ def add_source
   5216        $last_fn = fn
   5217        [Redwood::Maildir.suggest_labels_for(fn),
   5218         { :scheme => "maildir", :path => fn }]
   5219 -    when :mboxssh
   5220 -      $last_server ||= "localhost"
   5221 -      srv = axe "What machine is the mbox file located on?", $last_server
   5222 -      return if srv.nil? || srv.empty?
   5223 -      $last_server = srv
   5224 -
   5225 -      fn = axe "What's the path to the mbox file?", $last_fn
   5226 -      return if fn.nil? || fn.empty?
   5227 -      $last_fn = fn
   5228 -      fn = "/#{fn}" # lame
   5229 -      [Redwood::MBox::SSHLoader.suggest_labels_for(fn),
   5230 -       { :scheme => "mbox+ssh", :host => srv, :path => fn }]
   5231      when :imap, :imaps
   5232        $last_server ||= "localhost"
   5233        srv = axe "What is the IMAP server (host, or host:port notation)?", $last_server
   5234 diff --git a/doc/NewUserGuide.txt b/doc/NewUserGuide.txt
   5235 index f22d2f1..4b46ae2 100644
   5236 --- a/doc/NewUserGuide.txt
   5237 +++ b/doc/NewUserGuide.txt
   5238 @@ -208,7 +208,6 @@ Instead of using sup-config to add a new source, you can manually run
   5239  - maildir://path/to/a/filename, for a maildir directory on disk.
   5240  - imap://imap.server/folder for an unsecure IMAP folder.
   5241  - imaps://secure.imap.server/folder for a secure IMAP folder.
   5242 -- mbox+ssh://remote.machine/path/to/a/filename for a remote mbox file.
   5243  
   5244  Before you add the source, you need make three decisions. The first is
   5245  whether you want Sup to regularly poll this source for new messages.
   5246 diff --git a/lib/sup/mbox.rb b/lib/sup/mbox.rb
   5247 index 7af40dd..57c371c 100644
   5248 --- a/lib/sup/mbox.rb
   5249 +++ b/lib/sup/mbox.rb
   5250 @@ -1,6 +1,4 @@
   5251  require "sup/mbox/loader"
   5252 -require "sup/mbox/ssh-file"
   5253 -require "sup/mbox/ssh-loader"
   5254  
   5255  module Redwood
   5256  
   5257 diff --git a/lib/sup/mbox/ssh-file.rb b/lib/sup/mbox/ssh-file.rb
   5258 deleted file mode 100644
   5259 index 4ae4bba..0000000
   5260 --- a/lib/sup/mbox/ssh-file.rb
   5261 +++ /dev/null
   5262 @@ -1,254 +0,0 @@
   5263 -require 'net/ssh'
   5264 -
   5265 -module Redwood
   5266 -module MBox
   5267 -
   5268 -class SSHFileError < StandardError; end
   5269 -
   5270 -## this is a file-like interface to a file that actually lives on the
   5271 -## other end of an ssh connection. it works by using wc, head and tail
   5272 -## to simulate (buffered) random access. on a fast connection, this
   5273 -## can have a good bandwidth, but the latency is pretty terrible:
   5274 -## about 1 second (!) per request.  luckily, we're either just reading
   5275 -## straight through the mbox (an import) or we're reading a few
   5276 -## messages at a time (viewing messages) so the latency is not a problem.
   5277 -
   5278 -## all of the methods here can throw SSHFileErrors, SocketErrors,
   5279 -## Net::SSH::Exceptions and Errno::ENOENTs.
   5280 -
   5281 -## a simple buffer of contiguous data
   5282 -class Buffer
   5283 -  def initialize
   5284 -    clear!
   5285 -  end
   5286 -
   5287 -  def clear!
   5288 -    @start = nil
   5289 -    @buf = ""
   5290 -  end
   5291 -
   5292 -  def empty?; @start.nil?; end
   5293 -  def start; @start; end
   5294 -  def endd; @start + @buf.length; end
   5295 -
   5296 -  def add data, offset=endd
   5297 -    #MBox::debug "+ adding #{data.length} bytes; size will be #{size + data.length}; limit #{SSHFile::MAX_BUF_SIZE}"
   5298 -
   5299 -    if start.nil?
   5300 -      @buf = data
   5301 -      @start = offset
   5302 -      return
   5303 -    end
   5304 -
   5305 -    raise "non-continguous data added to buffer (data #{offset}:#{offset + data.length}, buf range #{start}:#{endd})" if offset + data.length < start || offset > endd
   5306 -
   5307 -    if offset < start
   5308 -      @buf = data[0 ... (start - offset)] + @buf
   5309 -      @start = offset
   5310 -    else
   5311 -      return if offset + data.length < endd
   5312 -      @buf += data[(endd - offset) .. -1]
   5313 -    end
   5314 -  end
   5315 -
   5316 -  def [](o)
   5317 -    raise "only ranges supported due to programmer's laziness" unless o.is_a? Range
   5318 -    @buf[Range.new(o.first - @start, o.last - @start, o.exclude_end?)]
   5319 -  end
   5320 -
   5321 -  def index what, start=0
   5322 -    x = @buf.index(what, start - @start)
   5323 -    x.nil? ? nil : x + @start
   5324 -  end
   5325 -
   5326 -  def rindex what, start=0
   5327 -    x = @buf.rindex(what, start - @start)
   5328 -    x.nil? ? nil : x + @start
   5329 -  end
   5330 -
   5331 -  def size; empty? ? 0 : @buf.size; end
   5332 -  def to_s; empty? ? "<empty>" : "[#{start}, #{endd})"; end # for debugging
   5333 -end
   5334 -
   5335 -## sharing a ssh connection to one machines between sources seems to
   5336 -## create lots of broken situations: commands returning bizarre (large
   5337 -## positive integer) return codes despite working; commands
   5338 -## occasionally not working, etc. i suspect this is because of the
   5339 -## fragile nature of the ssh syncshell. 
   5340 -##
   5341 -## at any rate, we now open up one ssh connection per file, which is
   5342 -## probably silly in the extreme case.
   5343 -
   5344 -## the file-like interface to a remote file
   5345 -class SSHFile
   5346 -  MAX_BUF_SIZE = 1024 * 1024 # bytes
   5347 -  MAX_TRANSFER_SIZE = 1024 * 128
   5348 -  REASONABLE_TRANSFER_SIZE = 1024 * 32
   5349 -  SIZE_CHECK_INTERVAL = 60 * 1 # seconds
   5350 -
   5351 -  ## upon these errors we'll try to rereconnect a few times
   5352 -  RECOVERABLE_ERRORS = [ Errno::EPIPE, Errno::ETIMEDOUT ]
   5353 -
   5354 -  @@shells = {}
   5355 -  @@shells_mutex = Mutex.new
   5356 -
   5357 -  def initialize host, fn, ssh_opts={}
   5358 -    @buf = Buffer.new
   5359 -    @host = host
   5360 -    @fn = fn
   5361 -    @ssh_opts = ssh_opts
   5362 -    @file_size = nil
   5363 -    @offset = 0
   5364 -    @say_id = nil
   5365 -    @shell = nil
   5366 -    @shell_mutex = nil
   5367 -    @buf_mutex = Mutex.new
   5368 -  end
   5369 -
   5370 -  def to_s; "mbox+ssh://#@host/#@fn"; end ## TODO: remove this EVILness
   5371 -
   5372 -  def connect
   5373 -    do_remote nil
   5374 -  end
   5375 -
   5376 -  def eof?; @offset >= size; end
   5377 -  def eof; eof?; end # lame but IO's method is named this and rmail calls that
   5378 -  def seek loc; @offset = loc; end
   5379 -  def tell; @offset; end
   5380 -  def total; size; end
   5381 -  def path; @fn end
   5382 -
   5383 -  def size
   5384 -    if @file_size.nil? || (Time.now - @last_size_check) > SIZE_CHECK_INTERVAL
   5385 -      @last_size_check = Time.now
   5386 -      @file_size = do_remote("wc -c #@fn").split.first.to_i
   5387 -    end
   5388 -    @file_size
   5389 -  end
   5390 -
   5391 -  def gets
   5392 -    return nil if eof?
   5393 -    @buf_mutex.synchronize do
   5394 -      make_buf_include @offset
   5395 -      expand_buf_forward while @buf.index("\n", @offset).nil? && @buf.endd < size
   5396 -      returning(@buf[@offset .. (@buf.index("\n", @offset) || -1)]) { |line| @offset += line.length }
   5397 -    end
   5398 -  end
   5399 -
   5400 -  def read n
   5401 -    return nil if eof?
   5402 -    @buf_mutex.synchronize do
   5403 -      make_buf_include @offset, n
   5404 -      @buf[@offset ... (@offset += n)]
   5405 -    end
   5406 -  end
   5407 -
   5408 -private
   5409 -
   5410 -  ## TODO: share this code with imap
   5411 -  def say s
   5412 -    @say_id = BufferManager.say s, @say_id if BufferManager.instantiated?
   5413 -    info s
   5414 -  end
   5415 -
   5416 -  def shutup
   5417 -    BufferManager.clear @say_id if BufferManager.instantiated? && @say_id
   5418 -    @say_id = nil
   5419 -  end
   5420 -
   5421 -  def unsafe_connect
   5422 -    return if @shell
   5423 -
   5424 -    @key = [@host, @ssh_opts[:username]]
   5425 -    begin
   5426 -      @shell, @shell_mutex = @@shells_mutex.synchronize do
   5427 -        unless @@shells.member? @key
   5428 -          say "Opening SSH connection to #{@host} for #@fn..."
   5429 -          session = Net::SSH.start @host, @ssh_opts
   5430 -          say "Starting SSH shell..."
   5431 -          @@shells[@key] = [session.shell.sync, Mutex.new]
   5432 -        end
   5433 -        @@shells[@key]
   5434 -      end
   5435 -      
   5436 -      say "Checking for #@fn..."
   5437 -      @shell_mutex.synchronize { raise Errno::ENOENT, @fn unless @shell.test("-e #@fn").status == 0 }
   5438 -    ensure
   5439 -      shutup
   5440 -    end
   5441 -  end
   5442 -
   5443 -  def do_remote cmd, expected_size=0
   5444 -    retries = 0
   5445 -    result = nil
   5446 -
   5447 -    begin
   5448 -      unsafe_connect
   5449 -      if cmd
   5450 -        # MBox::debug "sending command: #{cmd.inspect}"
   5451 -        result = @shell_mutex.synchronize { x = @shell.send_command cmd; sleep 0.25; x }
   5452 -        raise SSHFileError, "Failure during remote command #{cmd.inspect}: #{(result.stderr || result.stdout || "")[0 .. 100]}" unless result.status == 0
   5453 -      end
   5454 -      ## Net::SSH::Exceptions seem to happen every once in a while for
   5455 -      ## no good reason.
   5456 -    rescue Net::SSH::Exception, *RECOVERABLE_ERRORS
   5457 -      if (retries += 1) <= 3
   5458 -        @@shells_mutex.synchronize do
   5459 -          @shell = nil
   5460 -          @@shells[@key] = nil
   5461 -        end
   5462 -        retry
   5463 -      end
   5464 -      raise
   5465 -    end
   5466 -
   5467 -    result.stdout if cmd
   5468 -  end
   5469 -
   5470 -  def get_bytes offset, size
   5471 -    do_remote "tail -c +#{offset + 1} #@fn | head -c #{size}", size
   5472 -  end
   5473 -
   5474 -  def expand_buf_forward n=REASONABLE_TRANSFER_SIZE
   5475 -    @buf.add get_bytes(@buf.endd, n)
   5476 -  end
   5477 -
   5478 -  ## try our best to transfer somewhere between
   5479 -  ## REASONABLE_TRANSFER_SIZE and MAX_TRANSFER_SIZE bytes
   5480 -  def make_buf_include offset, size=0
   5481 -    good_size = [size, REASONABLE_TRANSFER_SIZE].max
   5482 -
   5483 -    trans_start, trans_size = 
   5484 -      if @buf.empty?
   5485 -        [offset, good_size]
   5486 -      elsif offset < @buf.start
   5487 -        if @buf.start - offset <= good_size
   5488 -          start = [@buf.start - good_size, 0].max
   5489 -          [start, @buf.start - start]
   5490 -        elsif @buf.start - offset < MAX_TRANSFER_SIZE
   5491 -          [offset, @buf.start - offset]
   5492 -        else
   5493 -          MBox::debug "clearing SSH buffer because buf.start #{@buf.start} - offset #{offset} >= #{MAX_TRANSFER_SIZE}"
   5494 -          @buf.clear!
   5495 -          [offset, good_size]
   5496 -        end
   5497 -      else
   5498 -        return if [offset + size, self.size].min <= @buf.endd # whoohoo!
   5499 -        if offset - @buf.endd <= good_size
   5500 -          [@buf.endd, good_size]
   5501 -        elsif offset - @buf.endd < MAX_TRANSFER_SIZE
   5502 -          [@buf.endd, offset - @buf.endd]
   5503 -        else
   5504 -          MBox::debug "clearing SSH buffer because offset #{offset} - buf.end #{@buf.endd} >= #{MAX_TRANSFER_SIZE}"
   5505 -          @buf.clear!
   5506 -          [offset, good_size]
   5507 -        end
   5508 -      end          
   5509 -
   5510 -    @buf.clear! if @buf.size > MAX_BUF_SIZE
   5511 -    @buf.add get_bytes(trans_start, trans_size), trans_start
   5512 -  end
   5513 -end
   5514 -
   5515 -end
   5516 -end
   5517 diff --git a/lib/sup/mbox/ssh-loader.rb b/lib/sup/mbox/ssh-loader.rb
   5518 deleted file mode 100644
   5519 index e422a48..0000000
   5520 --- a/lib/sup/mbox/ssh-loader.rb
   5521 +++ /dev/null
   5522 @@ -1,74 +0,0 @@
   5523 -require 'net/ssh'
   5524 -
   5525 -module Redwood
   5526 -module MBox
   5527 -
   5528 -class SSHLoader < Source
   5529 -  attr_accessor :username, :password
   5530 -
   5531 -  yaml_properties :uri, :username, :password, :cur_offset, :usual, 
   5532 -                  :archived, :id, :labels
   5533 -
   5534 -  def initialize uri, username=nil, password=nil, start_offset=nil, usual=true, archived=false, id=nil, labels=[]
   5535 -    raise ArgumentError, "not an mbox+ssh uri: #{uri.inspect}" unless uri =~ %r!^mbox\+ssh://!
   5536 -
   5537 -    super uri, start_offset, usual, archived, id
   5538 -
   5539 -    @parsed_uri = URI(uri)
   5540 -    @username = username
   5541 -    @password = password
   5542 -    @uri = uri
   5543 -    @cur_offset = start_offset
   5544 -    @labels = (labels || []).freeze
   5545 -
   5546 -    opts = {}
   5547 -    opts[:username] = @username if @username
   5548 -    opts[:password] = @password if @password
   5549 -    
   5550 -    @f = SSHFile.new host, filename, opts
   5551 -    @loader = Loader.new @f, start_offset, usual, archived, id
   5552 -    
   5553 -    ## heuristic: use the filename as a label, unless the file
   5554 -    ## has a path that probably represents an inbox.
   5555 -  end
   5556 -
   5557 -  def self.suggest_labels_for path; Loader.suggest_labels_for(path) end
   5558 -
   5559 -  def connect; safely { @f.connect }; end
   5560 -  def host; @parsed_uri.host; end
   5561 -  def filename; @parsed_uri.path[1..-1] end
   5562 -
   5563 -  def next
   5564 -    safely do
   5565 -      offset, labels = @loader.next
   5566 -      self.cur_offset = @loader.cur_offset # superclass keeps @cur_offset which is used by yaml
   5567 -      [offset, (labels + @labels).uniq] # add our labels
   5568 -    end
   5569 -  end
   5570 -
   5571 -  def end_offset
   5572 -    safely { @f.size }
   5573 -  end
   5574 -
   5575 -  def cur_offset= o; @cur_offset = @loader.cur_offset = o; @dirty = true; end
   5576 -  def id; @loader.id; end
   5577 -  def id= o; @id = @loader.id = o; end
   5578 -  # def cur_offset; @loader.cur_offset; end # think we'll be ok without this
   5579 -  def to_s; @parsed_uri.to_s; end
   5580 -
   5581 -  def safely
   5582 -    begin
   5583 -      yield
   5584 -    rescue Net::SSH::Exception, SocketError, SSHFileError, SystemCallError, IOError => e
   5585 -      m = "error communicating with SSH server #{host} (#{e.class.name}): #{e.message}"
   5586 -      raise FatalSourceError, m
   5587 -    end
   5588 -  end
   5589 -
   5590 -  [:start_offset, :load_header, :load_message, :raw_header, :raw_message].each do |meth|
   5591 -    define_method(meth) { |*a| safely { @loader.send meth, *a } }
   5592 -  end
   5593 -end
   5594 -
   5595 -end
   5596 -end
   5597 -- 
   5598 1.6.3.3
   5599 
   5600 
   5601 From rlane@club.cc.cmu.edu  Sun Jan 17 13:50:46 2010
   5602 From: rlane@club.cc.cmu.edu (Rich Lane)
   5603 Date: Sun, 17 Jan 2010 10:50:46 -0800
   5604 Subject: [sup-devel] [PATCH 2/3] remove imap source
   5605 In-Reply-To: <1263754247-20979-2-git-send-email-rlane@club.cc.cmu.edu>
   5606 References: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   5607 	<1263754247-20979-2-git-send-email-rlane@club.cc.cmu.edu>
   5608 Message-ID: <1263754247-20979-3-git-send-email-rlane@club.cc.cmu.edu>
   5609 
   5610 ---
   5611  README.txt              |   10 +--
   5612  bin/sup-add             |    9 --
   5613  bin/sup-config          |   21 ---
   5614  bin/sup-recover-sources |   13 +--
   5615  doc/FAQ.txt             |    8 +-
   5616  doc/NewUserGuide.txt    |   21 +--
   5617  lib/sup.rb              |    1 -
   5618  lib/sup/imap.rb         |  349 -----------------------------------------------
   5619  lib/sup/source.rb       |    8 +-
   5620  lib/sup/xapian_index.rb |    1 +
   5621  10 files changed, 16 insertions(+), 425 deletions(-)
   5622  delete mode 100644 lib/sup/imap.rb
   5623 
   5624 diff --git a/README.txt b/README.txt
   5625 index 7819f0b..dba7298 100644
   5626 --- a/README.txt
   5627 +++ b/README.txt
   5628 @@ -12,8 +12,7 @@ email as an extension of your long-term memory, Sup is for you.
   5629  Sup makes it easy to:
   5630  - Handle massive amounts of email.
   5631  
   5632 -- Mix email from different sources: mbox files (even across different
   5633 -  machines), Maildir directories, IMAP folders, and GMail accounts.
   5634 +- Mix email from different sources: mbox files and Maildir directories.
   5635  
   5636  - Instantaneously search over your entire email collection. Search over
   5637    body text, or use a query language to combine search predicates in any
   5638 @@ -73,13 +72,6 @@ Current limitations which will be fixed:
   5639    source (read, move, delete, etc) with another client Sup will punish
   5640    you with a lengthy reindexing process.
   5641  
   5642 -- Support for mbox, Maildir, and IMAP only at this point. No support for
   5643 -  POP or mh.
   5644 -
   5645 -- IMAP support is very slow due mostly to Ruby's IMAP library.  You may
   5646 -  consider something like offlineimap to mirror your IMAP folders with
   5647 -  local Maildir ones.
   5648 -
   5649  - Unix-centrism in MIME attachment handling and in sendmail invocation.
   5650  
   5651  == SYNOPSYS:
   5652 diff --git a/bin/sup-add b/bin/sup-add
   5653 index b92b5ad..059a4e2 100755
   5654 --- a/bin/sup-add
   5655 +++ b/bin/sup-add
   5656 @@ -20,12 +20,6 @@ For mbox files on local disk, use the form:
   5657      mbox:<path to mbox file>, or
   5658      mbox://<path to mbox file>
   5659  
   5660 -For IMAP folders, use the form (note no username or password!):
   5661 -    imap://<machine name>/          # unsecure, "INBOX" folder  
   5662 -    imap://<machine name>/<folder>  # unsecure, arbitrary
   5663 -    imaps://<machine name>/         # secure, "INBOX" folder
   5664 -    imaps://<machine name>/<folder> # secure, arbitrary folder 
   5665 -
   5666  For Maildir folders, use the form:
   5667      maildir:<path to Maildir directory>; or
   5668      maildir://<path to Maildir directory>
   5669 @@ -102,9 +96,6 @@ begin
   5670  
   5671      source = 
   5672        case parsed_uri.scheme
   5673 -      when "imap", "imaps"
   5674 -        username, password = get_login_info uri, Redwood::SourceManager.sources
   5675 -        Redwood::IMAP.new uri, username, password, nil, !$opts[:unusual], $opts[:archive], nil, labels
   5676        when "maildir"
   5677          Redwood::Maildir.new uri, nil, !$opts[:unusual], $opts[:archive], nil, labels
   5678        when "mbox"
   5679 diff --git a/bin/sup-config b/bin/sup-config
   5680 index 5541965..059af6d 100755
   5681 --- a/bin/sup-config
   5682 +++ b/bin/sup-config
   5683 @@ -44,8 +44,6 @@ def add_source
   5684      menu.prompt = "What type of mail source is it? "
   5685      menu.choice("mbox file") { type = :mbox }
   5686      menu.choice("maildir directory") { type = :maildir }
   5687 -    menu.choice("IMAP server (secure)") { type = :imaps }
   5688 -    menu.choice("IMAP server (unsecure)") { type = :imap }
   5689      menu.choice("Get me out of here!") { return }
   5690    end
   5691  
   5692 @@ -69,25 +67,6 @@ def add_source
   5693        $last_fn = fn
   5694        [Redwood::Maildir.suggest_labels_for(fn),
   5695         { :scheme => "maildir", :path => fn }]
   5696 -    when :imap, :imaps
   5697 -      $last_server ||= "localhost"
   5698 -      srv = axe "What is the IMAP server (host, or host:port notation)?", $last_server
   5699 -      return if srv.nil? || srv.empty?
   5700 -      $last_server = srv
   5701 -
   5702 -      $last_folder ||= "INBOX"
   5703 -      fn = axe "What's the folder path?", $last_folder
   5704 -      return if fn.nil? || fn.empty?
   5705 -      $last_folder = fn
   5706 -
   5707 -      fn = "/#{fn}"
   5708 -      if srv =~ /^(\S+):(\d+)$/
   5709 -        host, port = $1, $2.to_i
   5710 -      else
   5711 -        host, port = srv, nil
   5712 -      end
   5713 -      [Redwood::IMAP.suggest_labels_for(fn),
   5714 -       { :scheme => type.to_s, :host => host, :port => port, :path => fn }]
   5715      end
   5716  
   5717      uri = begin
   5718 diff --git a/bin/sup-recover-sources b/bin/sup-recover-sources
   5719 index 43fa5f6..03ac97d 100755
   5720 --- a/bin/sup-recover-sources
   5721 +++ b/bin/sup-recover-sources
   5722 @@ -58,17 +58,8 @@ ARGV.each do |fn|
   5723    next if Redwood::SourceManager.source_for fn
   5724  
   5725    ## TODO: merge this code with the same snippet in import
   5726 -  source = 
   5727 -    case fn
   5728 -    when %r!^imaps?://!
   5729 -      print "Username for #{fn}: "
   5730 -      username = $stdin.gets.chomp
   5731 -      print "Password for #{fn} (warning: cleartext): "
   5732 -      password = $stdin.gets.chomp
   5733 -      Redwood::IMAP.new(fn, username, password, nil, !$opts[:unusual], $opts[:archive])
   5734 -    else
   5735 -      Redwood::MBox::Loader.new(fn, nil, !$opts[:unusual], $opts[:archive])
   5736 -    end
   5737 +  ## XXX maildir?
   5738 +  source = Redwood::MBox::Loader.new(fn, nil, !$opts[:unusual], $opts[:archive])
   5739  
   5740    source_ids = Hash.new 0
   5741    count = 0
   5742 diff --git a/doc/FAQ.txt b/doc/FAQ.txt
   5743 index 997a357..1a86211 100644
   5744 --- a/doc/FAQ.txt
   5745 +++ b/doc/FAQ.txt
   5746 @@ -105,13 +105,7 @@ S: The current solution is to directly modify RubyMail. Change line 159 of
   5747  P: I see this error:
   5748       /usr/local/lib/ruby/1.8/yaml.rb:133:in `transfer': allocator undefined for Bignum (TypeError)
   5749  S: You need to upgrade to Ruby 1.8.5. YAML in earlier versions can't
   5750 -   parse BigNums, but Sup relies on that for Maildir and IMAP.
   5751 -
   5752 -P: I see this error:
   5753 -     /usr/lib/ruby/1.8/net/imap.rb:204: uninitialized constant Net::IMAP::SSL (NameError)
   5754 -S: You need to install a package called libssl-ruby or something similar.
   5755 -   Or, don't use imaps:// sources. Ruby's IMAP library otherwise fails in
   5756 -   this completely uninformative manner.
   5757 +   parse BigNums, but Sup relies on that for Maildir.
   5758  
   5759  P: When I run Sup remotely and view an HTML attachment, an existing
   5760     Firefox on the *local* machine is redirected to the attachment
   5761 diff --git a/doc/NewUserGuide.txt b/doc/NewUserGuide.txt
   5762 index 4b46ae2..af18aeb 100644
   5763 --- a/doc/NewUserGuide.txt
   5764 +++ b/doc/NewUserGuide.txt
   5765 @@ -19,14 +19,14 @@ index is where Sup stores all message state (e.g. read or unread, any
   5766  message labels), and all information necessary for searching and for
   5767  threading messages. Sup only knows about messages in its index.
   5768  
   5769 -We can add messages to the index by telling Sup about the "source"
   5770 -where the messages reside. Sources are things like IMAP folders, mbox
   5771 -folders, and maildir directories. Sup doesn't duplicate the actual
   5772 -message content in the index; it only stores whatever information is
   5773 -necessary for searching, threading and labelling. So when you search
   5774 -for messages or view your inbox, Sup talks only to the index (stored
   5775 -locally on disk). When you view a thread, Sup requests the full
   5776 -content of all the messages from the source.
   5777 +We can add messages to the index by telling Sup about the "source" where
   5778 +the messages reside. Sources are things like mbox folders and maildir
   5779 +directories. Sup doesn't duplicate the actual message content in the
   5780 +index; it only stores whatever information is necessary for searching,
   5781 +threading and labelling. So when you search for messages or view your
   5782 +inbox, Sup talks only to the index (stored locally on disk). When you
   5783 +view a thread, Sup requests the full content of all the messages from
   5784 +the source.
   5785  
   5786  The easiest way to set up all your sources is to run `sup-config`.
   5787  This will interactively walk you through some basic configuration,
   5788 @@ -206,8 +206,6 @@ Instead of using sup-config to add a new source, you can manually run
   5789  
   5790  - mbox://path/to/a/filename, for an mbox file on disk.
   5791  - maildir://path/to/a/filename, for a maildir directory on disk.
   5792 -- imap://imap.server/folder for an unsecure IMAP folder.
   5793 -- imaps://secure.imap.server/folder for a secure IMAP folder.
   5794  
   5795  Before you add the source, you need make three decisions. The first is
   5796  whether you want Sup to regularly poll this source for new messages.
   5797 @@ -226,9 +224,6 @@ lists that you don't want polluting your inbox.
   5798  The final decision is whether you want any labels automatically
   5799  applied to messages from this source. You can use `--labels` to do this.
   5800  
   5801 -If Sup requires account information, e.g. for IMAP servers and remote
   5802 -mbox files, `sup-add` will ask for it.
   5803 -
   5804  Now that you've added the source, let's import all the current
   5805  messages from it, by running sup-sync with the source URI. You can
   5806  specify `--archive` to automatically archive all messages in this
   5807 diff --git a/lib/sup.rb b/lib/sup.rb
   5808 index ddc602e..ef1b49a 100644
   5809 --- a/lib/sup.rb
   5810 +++ b/lib/sup.rb
   5811 @@ -274,7 +274,6 @@ require "sup/message"
   5812  require "sup/source"
   5813  require "sup/mbox"
   5814  require "sup/maildir"
   5815 -require "sup/imap"
   5816  require "sup/person"
   5817  require "sup/account"
   5818  require "sup/thread"
   5819 diff --git a/lib/sup/imap.rb b/lib/sup/imap.rb
   5820 deleted file mode 100644
   5821 index bdb9e15..0000000
   5822 --- a/lib/sup/imap.rb
   5823 +++ /dev/null
   5824 @@ -1,349 +0,0 @@
   5825 -require 'uri'
   5826 -require 'net/imap'
   5827 -require 'stringio'
   5828 -require 'time'
   5829 -require 'rmail'
   5830 -require 'cgi'
   5831 -require 'set'
   5832 -
   5833 -## TODO: remove synchronized method protector calls; use a Monitor instead
   5834 -## (ruby's reentrant mutex)
   5835 -
   5836 -## fucking imap fucking sucks. what the FUCK kind of committee of dunces
   5837 -## designed this shit.
   5838 -##
   5839 -## imap talks about 'unique ids' for messages, to be used for
   5840 -## cross-session identification. great---just what sup needs! except it
   5841 -## turns out the uids can be invalidated every time the 'uidvalidity'
   5842 -## value changes on the server, and 'uidvalidity' can change without
   5843 -## restriction. it can change any time you log in. it can change EVERY
   5844 -## time you log in. of course the imap spec "strongly recommends" that it
   5845 -## never change, but there's nothing to stop people from just setting it
   5846 -## to the current timestamp, and in fact that's EXACTLY what the one imap
   5847 -## server i have at my disposal does. thus the so-called uids are
   5848 -## absolutely useless and imap provides no cross-session way of uniquely
   5849 -## identifying a message. but thanks for the "strong recommendation",
   5850 -## guys!
   5851 -##
   5852 -## so right now i'm using the 'internal date' and the size of each
   5853 -## message to uniquely identify it, and i scan over the entire mailbox
   5854 -## each time i open it to map those things to message ids. that can be
   5855 -## slow for large mailboxes, and we'll just have to hope that there are
   5856 -## no collisions. ho ho! a perfectly reasonable solution!
   5857 -##
   5858 -## and here's another thing. check out RFC2060 2.2.2 paragraph 5:
   5859 -##
   5860 -##   A client MUST be prepared to accept any server response at all
   5861 -##   times.  This includes server data that was not requested.
   5862 -##
   5863 -## yeah. that totally makes a lot of sense. and once again, the idiocy of
   5864 -## the spec actually happens in practice. you'll request flags for one
   5865 -## message, and get it interspersed with a random bunch of flags for some
   5866 -## other messages, including a different set of flags for the same
   5867 -## message! totally ok by the imap spec. totally retarded by any other
   5868 -## metric.
   5869 -##
   5870 -## fuck you, imap committee. you managed to design something nearly as
   5871 -## shitty as mbox but goddamn THIRTY YEARS LATER.
   5872 -module Redwood
   5873 -
   5874 -class IMAP < Source
   5875 -  include SerializeLabelsNicely
   5876 -  SCAN_INTERVAL = 60 # seconds
   5877 -
   5878 -  ## upon these errors we'll try to rereconnect a few times
   5879 -  RECOVERABLE_ERRORS = [ Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError ]
   5880 -
   5881 -  attr_accessor :username, :password
   5882 -  yaml_properties :uri, :username, :password, :cur_offset, :usual,
   5883 -                  :archived, :id, :labels
   5884 -
   5885 -  def initialize uri, username, password, last_idate=nil, usual=true, archived=false, id=nil, labels=[]
   5886 -    raise ArgumentError, "username and password must be specified" unless username && password
   5887 -    raise ArgumentError, "not an imap uri" unless uri =~ %r!imaps?://!
   5888 -
   5889 -    super uri, last_idate, usual, archived, id
   5890 -
   5891 -    @parsed_uri = URI(uri)
   5892 -    @username = username
   5893 -    @password = password
   5894 -    @imap = nil
   5895 -    @imap_state = {}
   5896 -    @ids = []
   5897 -    @last_scan = nil
   5898 -    @labels = Set.new((labels || []) - LabelManager::RESERVED_LABELS)
   5899 -    @say_id = nil
   5900 -    @mutex = Mutex.new
   5901 -  end
   5902 -
   5903 -  def self.suggest_labels_for path
   5904 -    path =~ /([^\/]*inbox[^\/]*)/i ? [$1.downcase.intern] : []
   5905 -  end
   5906 -
   5907 -  def host; @parsed_uri.host; end
   5908 -  def port; @parsed_uri.port || (ssl? ? 993 : 143); end
   5909 -  def mailbox
   5910 -    x = @parsed_uri.path[1..-1]
   5911 -    (x.nil? || x.empty?) ? 'INBOX' : CGI.unescape(x)
   5912 -  end
   5913 -  def ssl?; @parsed_uri.scheme == 'imaps' end
   5914 -
   5915 -  def check; end # do nothing because anything we do will be too slow,
   5916 -                 # and we'll catch the errors later.
   5917 -
   5918 -  ## is this necessary? TODO: remove maybe
   5919 -  def == o; o.is_a?(IMAP) && o.uri == self.uri && o.username == self.username; end
   5920 -
   5921 -  def load_header id
   5922 -    parse_raw_email_header StringIO.new(raw_header(id))
   5923 -  end
   5924 -
   5925 -  def load_message id
   5926 -    RMail::Parser.read raw_message(id)
   5927 -  end
   5928 -  
   5929 -  def each_raw_message_line id
   5930 -    StringIO.new(raw_message(id)).each { |l| yield l }
   5931 -  end
   5932 -
   5933 -  def raw_header id
   5934 -    unsynchronized_scan_mailbox
   5935 -    header, flags = get_imap_fields id, 'RFC822.HEADER'
   5936 -    header.gsub(/\r\n/, "\n")
   5937 -  end
   5938 -  synchronized :raw_header
   5939 -
   5940 -  def store_message date, from_email, &block
   5941 -    message = StringIO.new
   5942 -    yield message
   5943 -    message.string.gsub! /\n/, "\r\n"
   5944 -
   5945 -    safely { @imap.append mailbox, message.string, [:Seen], Time.now }
   5946 -  end
   5947 -
   5948 -  def raw_message id
   5949 -    unsynchronized_scan_mailbox
   5950 -    get_imap_fields(id, 'RFC822').first.gsub(/\r\n/, "\n")
   5951 -  end
   5952 -  synchronized :raw_message
   5953 -
   5954 -  def mark_as_deleted ids
   5955 -    ids = [ids].flatten # accept single arguments
   5956 -    unsynchronized_scan_mailbox
   5957 -    imap_ids = ids.map { |i| @imap_state[i] && @imap_state[i][:id] }.compact
   5958 -    return if imap_ids.empty?
   5959 -    @imap.store imap_ids, "+FLAGS", [:Deleted]
   5960 -  end
   5961 -  synchronized :mark_as_deleted
   5962 -
   5963 -  def expunge
   5964 -    @imap.expunge
   5965 -    unsynchronized_scan_mailbox true
   5966 -    true
   5967 -  end
   5968 -  synchronized :expunge
   5969 -
   5970 -  def connect
   5971 -    return if @imap
   5972 -    safely { } # do nothing!
   5973 -  end
   5974 -  synchronized :connect
   5975 -
   5976 -  def scan_mailbox force=false
   5977 -    return if !force && @last_scan && (Time.now - @last_scan) < SCAN_INTERVAL
   5978 -    last_id = safely do
   5979 -      @imap.examine mailbox
   5980 -      @imap.responses["EXISTS"].last
   5981 -    end
   5982 -    @last_scan = Time.now
   5983 -
   5984 -    @ids = [] if force
   5985 -    return if last_id == @ids.length
   5986 -
   5987 -    range = (@ids.length + 1) .. last_id
   5988 -    debug "fetching IMAP headers #{range}"
   5989 -    fetch(range, ['RFC822.SIZE', 'INTERNALDATE', 'FLAGS']).each do |v|
   5990 -      id = make_id v
   5991 -      @ids << id
   5992 -      @imap_state[id] = { :id => v.seqno, :flags => v.attr["FLAGS"] }
   5993 -    end
   5994 -    debug "done fetching IMAP headers"
   5995 -  end
   5996 -  synchronized :scan_mailbox
   5997 -
   5998 -  def each
   5999 -    return unless start_offset
   6000 -
   6001 -    ids = 
   6002 -      @mutex.synchronize do
   6003 -        unsynchronized_scan_mailbox
   6004 -        @ids
   6005 -      end
   6006 -
   6007 -    start = ids.index(cur_offset || start_offset) or raise OutOfSyncSourceError, "Unknown message id #{cur_offset || start_offset}."
   6008 -
   6009 -    start.upto(ids.length - 1) do |i|
   6010 -      id = ids[i]
   6011 -      state = @mutex.synchronize { @imap_state[id] } or next
   6012 -      self.cur_offset = id 
   6013 -      labels = { :Flagged => :starred,
   6014 -                 :Deleted => :deleted
   6015 -               }.inject(@labels) do |cur, (imap, sup)|
   6016 -        cur + (state[:flags].include?(imap) ? [sup] : [])
   6017 -      end
   6018 -
   6019 -      labels += [:unread] unless state[:flags].include?(:Seen)
   6020 -
   6021 -      yield id, labels
   6022 -    end
   6023 -  end
   6024 -
   6025 -  def start_offset
   6026 -    unsynchronized_scan_mailbox
   6027 -    @ids.first
   6028 -  end
   6029 -  synchronized :start_offset
   6030 -
   6031 -  def end_offset
   6032 -    unsynchronized_scan_mailbox
   6033 -    @ids.last + 1
   6034 -  end
   6035 -  synchronized :end_offset
   6036 -
   6037 -  def pct_done; 100.0 * (@ids.index(cur_offset) || 0).to_f / (@ids.length - 1).to_f; end
   6038 -
   6039 -private
   6040 -
   6041 -  def fetch ids, fields
   6042 -    results = safely { @imap.fetch ids, fields }
   6043 -    good_results = 
   6044 -      if ids.respond_to? :member?
   6045 -        results.find_all { |r| ids.member?(r.seqno) && fields.all? { |f| r.attr.member?(f) } }
   6046 -      else
   6047 -        results.find_all { |r| ids == r.seqno && fields.all? { |f| r.attr.member?(f) } }
   6048 -      end
   6049 -
   6050 -    if good_results.empty?
   6051 -      raise FatalSourceError, "no IMAP response for #{ids} containing all fields #{fields.join(', ')} (got #{results.size} results)"
   6052 -    elsif good_results.size < results.size
   6053 -      warn "Your IMAP server sucks. It sent #{results.size} results for a request for #{good_results.size} messages. What are you using, Binc?"
   6054 -    end
   6055 -
   6056 -    good_results
   6057 -  end
   6058 -
   6059 -  def unsafe_connect
   6060 -    say "Connecting to IMAP server #{host}:#{port}..."
   6061 -
   6062 -    ## apparently imap.rb does a lot of threaded stuff internally and if
   6063 -    ## an exception occurs, it will catch it and re-raise it on the
   6064 -    ## calling thread. but i can't seem to catch that exception, so i've
   6065 -    ## resorted to initializing it in its own thread. surely there's a
   6066 -    ## better way.
   6067 -    exception = nil
   6068 -    ::Thread.new do
   6069 -      begin
   6070 -        #raise Net::IMAP::ByeResponseError, "simulated imap failure"
   6071 -        @imap = Net::IMAP.new host, port, ssl?
   6072 -        say "Logging in..."
   6073 -
   6074 -        ## although RFC1730 claims that "If an AUTHENTICATE command fails
   6075 -        ## with a NO response, the client may try another", in practice
   6076 -        ## it seems like they can also send a BAD response.
   6077 -        begin
   6078 -          raise Net::IMAP::NoResponseError unless @imap.capability().member? "AUTH=CRAM-MD5"
   6079 -          @imap.authenticate 'CRAM-MD5', @username, @password
   6080 -        rescue Net::IMAP::BadResponseError, Net::IMAP::NoResponseError => e
   6081 -          debug "CRAM-MD5 authentication failed: #{e.class}. Trying LOGIN auth..."
   6082 -          begin
   6083 -            raise Net::IMAP::NoResponseError unless @imap.capability().member? "AUTH=LOGIN"
   6084 -            @imap.authenticate 'LOGIN', @username, @password
   6085 -          rescue Net::IMAP::BadResponseError, Net::IMAP::NoResponseError => e
   6086 -            debug "LOGIN authentication failed: #{e.class}. Trying plain-text LOGIN..."
   6087 -            @imap.login @username, @password
   6088 -          end
   6089 -        end
   6090 -        say "Successfully connected to #{@parsed_uri}."
   6091 -      rescue Exception => e
   6092 -        exception = e
   6093 -      ensure
   6094 -        shutup
   6095 -      end
   6096 -    end.join
   6097 -
   6098 -    raise exception if exception
   6099 -  end
   6100 -
   6101 -  def say s
   6102 -    @say_id = BufferManager.say s, @say_id if BufferManager.instantiated?
   6103 -    info s
   6104 -  end
   6105 -
   6106 -  def shutup
   6107 -    BufferManager.clear @say_id if BufferManager.instantiated?
   6108 -    @say_id = nil
   6109 -  end
   6110 -
   6111 -  def make_id imap_stuff
   6112 -    # use 7 digits for the size. why 7? seems nice.
   6113 -    %w(RFC822.SIZE INTERNALDATE).each do |w|
   6114 -      raise FatalSourceError, "requested data not in IMAP response: #{w}" unless imap_stuff.attr[w]
   6115 -    end
   6116 -
   6117 -    msize, mdate = imap_stuff.attr['RFC822.SIZE'] % 10000000, Time.parse(imap_stuff.attr["INTERNALDATE"])
   6118 -    sprintf("%d%07d", mdate.to_i, msize).to_i
   6119 -  end
   6120 -
   6121 -  def get_imap_fields id, *fields
   6122 -    raise OutOfSyncSourceError, "Unknown message id #{id}" unless @imap_state[id]
   6123 -
   6124 -    imap_id = @imap_state[id][:id]
   6125 -    result = fetch(imap_id, (fields + ['RFC822.SIZE', 'INTERNALDATE']).uniq).first
   6126 -    got_id = make_id result
   6127 -
   6128 -    ## I've turned off the following sanity check because Microsoft
   6129 -    ## Exchange fails it.  Exchange actually reports two different
   6130 -    ## INTERNALDATEs for the exact same message when queried at different
   6131 -    ## points in time.
   6132 -    ##
   6133 -    ## RFC2060 defines the semantics of INTERNALDATE for messages that
   6134 -    ## arrive via SMTP for via various IMAP commands, but states that
   6135 -    ## "All other cases are implementation defined.". Great, thanks guys,
   6136 -    ## yet another useless field.
   6137 -    ## 
   6138 -    ## Of course no OTHER imap server I've encountered returns DIFFERENT
   6139 -    ## values for the SAME message. But it's Microsoft; what do you
   6140 -    ## expect? If their programmers were any good they'd be working at
   6141 -    ## Google.
   6142 -
   6143 -    # raise OutOfSyncSourceError, "IMAP message mismatch: requested #{id}, got #{got_id}." unless got_id == id
   6144 -
   6145 -    fields.map { |f| result.attr[f] or raise FatalSourceError, "empty response from IMAP server: #{f}" }
   6146 -  end
   6147 -
   6148 -  ## execute a block, connected if unconnected, re-connected up to 3
   6149 -  ## times if a recoverable error occurs, and properly dying if an
   6150 -  ## unrecoverable error occurs.
   6151 -  def safely
   6152 -    retries = 0
   6153 -    begin
   6154 -      begin
   6155 -        unsafe_connect unless @imap
   6156 -        yield
   6157 -      rescue *RECOVERABLE_ERRORS => e
   6158 -        if (retries += 1) <= 3
   6159 -          @imap = nil
   6160 -          warn "got #{e.class.name}: #{e.message.inspect}"
   6161 -          sleep 2
   6162 -          retry
   6163 -        end
   6164 -        raise
   6165 -      end
   6166 -    rescue SocketError, Net::IMAP::Error, SystemCallError, IOError, OpenSSL::SSL::SSLError => e
   6167 -      raise FatalSourceError, "While communicating with IMAP server (type #{e.class.name}): #{e.message.inspect}"
   6168 -    end
   6169 -  end
   6170 -
   6171 -end
   6172 -
   6173 -end
   6174 diff --git a/lib/sup/source.rb b/lib/sup/source.rb
   6175 index 6fe7bfb..02d99c7 100644
   6176 --- a/lib/sup/source.rb
   6177 +++ b/lib/sup/source.rb
   6178 @@ -28,8 +28,7 @@ class Source
   6179    ## (in the absence of some other client going in and fucking
   6180    ## everything up). For example, for mboxes I use the file offset of
   6181    ## the start of the message. If a source does NOT have that
   6182 -  ## capability, e.g. IMAP, then you have to do a little more work to
   6183 -  ## simulate it.
   6184 +  ## capability then you have to do a little more work to simulate it.
   6185    ##
   6186    ## To write a new source, subclass this class, and implement:
   6187    ##
   6188 @@ -51,13 +50,12 @@ class Source
   6189    ## OutOfSyncSourceErrors should be used for problems that a call to
   6190    ## sup-sync will fix (namely someone's been playing with the source
   6191    ## from another client); FatalSourceErrors can be used for anything
   6192 -  ## else (e.g. the imap server is down or the maildir is missing.)
   6193 +  ## else (e.g. the maildir is missing.)
   6194    ##
   6195    ## Finally, be sure the source is thread-safe, since it WILL be
   6196    ## pummelled from multiple threads at once.
   6197    ##
   6198 -  ## Examples for you to look at: mbox/loader.rb, imap.rb, and
   6199 -  ## maildir.rb.
   6200 +  ## Examples for you to look at: mbox/loader.rb and maildir.rb.
   6201  
   6202    ## let's begin!
   6203    ##
   6204 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   6205 index c81dca4..e0c6ecf 100644
   6206 --- a/lib/sup/xapian_index.rb
   6207 +++ b/lib/sup/xapian_index.rb
   6208 @@ -1,5 +1,6 @@
   6209  require 'xapian'
   6210  require 'set'
   6211 +require 'monitor'
   6212  
   6213  module Redwood
   6214  
   6215 -- 
   6216 1.6.3.3
   6217 
   6218 
   6219 From rlane@club.cc.cmu.edu  Sun Jan 17 13:50:47 2010
   6220 From: rlane@club.cc.cmu.edu (Rich Lane)
   6221 Date: Sun, 17 Jan 2010 10:50:47 -0800
   6222 Subject: [sup-devel] [PATCH 3/3] simplify sup-add
   6223 In-Reply-To: <1263754247-20979-3-git-send-email-rlane@club.cc.cmu.edu>
   6224 References: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   6225 	<1263754247-20979-2-git-send-email-rlane@club.cc.cmu.edu>
   6226 	<1263754247-20979-3-git-send-email-rlane@club.cc.cmu.edu>
   6227 Message-ID: <1263754247-20979-4-git-send-email-rlane@club.cc.cmu.edu>
   6228 
   6229 ---
   6230  bin/sup-add |   40 ----------------------------------------
   6231  1 files changed, 0 insertions(+), 40 deletions(-)
   6232 
   6233 diff --git a/bin/sup-add b/bin/sup-add
   6234 index 059a4e2..e354ea8 100755
   6235 --- a/bin/sup-add
   6236 +++ b/bin/sup-add
   6237 @@ -30,50 +30,10 @@ EOS
   6238    opt :unusual, "Do not automatically poll these sources for new messages."
   6239    opt :labels, "A comma-separated set of labels to apply to all messages from this source", :type => String
   6240    opt :force_new, "Create a new account for this source, even if one already exists."
   6241 -  opt :force_account, "Reuse previously defined account user at hostname.", :type => String
   6242  end
   6243  
   6244  Trollop::die "require one or more sources" if ARGV.empty?
   6245  
   6246 -## for sources that require login information, prompt the user for
   6247 -## that. also provide a list of previously-defined login info to
   6248 -## choose from, if any.
   6249 -def get_login_info uri, sources
   6250 -  uri = URI(uri)
   6251 -  accounts = sources.map do |s|
   6252 -    next unless s.respond_to?(:username)
   6253 -    suri = URI(s.uri)
   6254 -    [suri.host, s.username, s.password]
   6255 -  end.compact.uniq.sort_by { |h, u, p| h == uri.host ? 0 : 1 }
   6256 -
   6257 -  username, password = nil, nil
   6258 -  unless accounts.empty? || $opts[:force_new]
   6259 -    if $opts[:force_account]
   6260 -      host, username, password = accounts.find { |h, u, p| $opts[:force_account] == "#{u}@#{h}" }
   6261 -      unless username && password
   6262 -        say "No previous account #{$opts[:force_account].inspect} found."
   6263 -      end
   6264 -    else
   6265 -      say "Would you like to use the same account as for a previous source for #{uri}?"
   6266 -      choose do |menu|
   6267 -        accounts.each do |host, olduser, oldpw|
   6268 -          menu.choice("Use the account info for #{olduser}@#{host}") { username, password = olduser, oldpw }
   6269 -        end
   6270 -        menu.choice("Use a new account") { }
   6271 -        menu.prompt = "Account selection? "
   6272 -      end
   6273 -    end
   6274 -  end
   6275 -
   6276 -  unless username && password
   6277 -    username = ask("Username for #{uri.host}: ");
   6278 -    password = ask("Password for #{uri.host}: ") { |q| q.echo = false }
   6279 -    puts # why?
   6280 -  end
   6281 -
   6282 -  [username, password]
   6283 -end
   6284 -
   6285  $terminal.wrap_at = :auto
   6286  Redwood::start
   6287  index = Redwood::Index.init
   6288 -- 
   6289 1.6.3.3
   6290 
   6291 
   6292 From wmorgan-sup@masanjin.net  Sun Jan 17 15:39:58 2010
   6293 From: wmorgan-sup@masanjin.net (William Morgan)
   6294 Date: Sun, 17 Jan 2010 15:39:58 -0500
   6295 Subject: [sup-devel] RFC: Nuke remote sources
   6296 In-Reply-To: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   6297 References: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   6298 Message-ID: <1263760710-sup-5382@masanjin.net>
   6299 
   6300 Reformatted excerpts from Rich Lane's message of 2010-01-17:
   6301 > Every few days someone joins the IRC channel complaining of poor
   6302 > performance or bugs with IMAP sources, and we have to tell them to use
   6303 > offlineimap or fetchmail instead.
   6304 
   6305 I think this is a great idea. I'm sick of the same thing happening on
   6306 the mailing list. I actually currently use a plain IMAP source
   6307 successfully, but it's just a matter of time before it will start
   6308 bogging down.
   6309 
   6310 > If people agree that this change is a good idea, I assume William will
   6311 > add a deprecation notice to master for 0.10 and merge this patchset to
   6312 > next.
   6313 
   6314 Yeah, another thing to add to 0.10... sigh.
   6315 -- 
   6316 William <wmorgan-sup at masanjin.net>
   6317 
   6318 From sup-bugs@masanjin.net  Sun Jan 17 17:02:54 2010
   6319 From: sup-bugs@masanjin.net (Eric Sherman)
   6320 Date: Sun, 17 Jan 2010 22:02:54 +0000
   6321 Subject: [sup-devel] [issue45] BufferManager.ask truncates responses to
   6322 	(terminal width -	question length)
   6323 In-Reply-To: <1263765774.58.0.0728242048264.issue45@masanjin.net>
   6324 Message-ID: <1263765774.58.0.0728242048264.issue45@masanjin.net>
   6325 
   6326 
   6327 New submission from Eric Sherman <hyperbolist at gmail.com>:
   6328 
   6329 BufferManager.ask truncates responses to (terminal width - question length).
   6330 
   6331 The easiest way to test if this happens in your environment:
   6332 * open a search \ 
   6333 * hold down aaaaaaaaaabbbbbbbbbbbcccccccccccc and so on until you've wrapped
   6334 across the terminal width a few times
   6335 * refine search |
   6336 * (you may need to left-arrow a little to see anything)
   6337 * the string you are refining should be truncated where your cursor first went
   6338 beyond the terminal width in the original search
   6339 
   6340 This does not happen for everyone.
   6341 
   6342 git next
   6343 ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
   6344 ncursesw (1.2.4.1)
   6345 
   6346 ----------
   6347 messages: 110
   6348 nosy: hyperbolist
   6349 priority: bug
   6350 ruby_version: ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
   6351 status: unread
   6352 sup_version: git next
   6353 title: BufferManager.ask truncates responses to (terminal width - question length)
   6354 
   6355 _________________________________________
   6356 Sup issue tracker <sup-bugs at masanjin.net>
   6357 <http://masanjin.net/sup-bugs/issue45>
   6358 _________________________________________
   6359 
   6360 From wmorgan-sup@masanjin.net  Sun Jan 17 18:12:50 2010
   6361 From: wmorgan-sup@masanjin.net (William Morgan)
   6362 Date: Sun, 17 Jan 2010 18:12:50 -0500
   6363 Subject: [sup-devel] [PATCH] only open mail files in binary mode on Ruby
   6364 	1.9
   6365 In-Reply-To: <1262795751-sup-4525@masanjin.net>
   6366 References: <1262634342-7029-1-git-send-email-rlane@club.cc.cmu.edu>
   6367 	<1262729069-sup-2235@masanjin.net>
   6368 	<1262795751-sup-4525@masanjin.net>
   6369 Message-ID: <1263769911-sup-6744@masanjin.net>
   6370 
   6371 Reformatted excerpts from William Morgan's message of 2010-01-06:
   6372 > The internet claims that using "rb" and "wb" works for both 1.8.5 and
   6373 > 1.9.1, but I haven't tried it.
   6374 
   6375 I've done this in ruby-1.9-encodings and remerged into next.
   6376 
   6377 Those of you tracking next with 1.9, please let me know if you
   6378 experience any weird encoding errors.
   6379 
   6380 (And those with 1.8, as well, I suppose.)
   6381 -- 
   6382 William <wmorgan-sup at masanjin.net>
   6383 
   6384 From eg@gaute.vetsj.com  Mon Jan 18 03:38:03 2010
   6385 From: eg@gaute.vetsj.com (Gaute Hope)
   6386 Date: Mon, 18 Jan 2010 09:38:03 +0100
   6387 Subject: [sup-devel] [PATCH] only open mail files in binary mode on Ruby
   6388 	1.9
   6389 In-Reply-To: <1263769911-sup-6744@masanjin.net>
   6390 References: <1262634342-7029-1-git-send-email-rlane@club.cc.cmu.edu>
   6391 	<1262729069-sup-2235@masanjin.net>
   6392 	<1262795751-sup-4525@masanjin.net>
   6393 	<1263769911-sup-6744@masanjin.net>
   6394 Message-ID: <1263803813-sup-7395@dolk>
   6395 
   6396 Excerpts from William Morgan's message of 2010-01-18 00:12:50 +0100:
   6397 > Reformatted excerpts from William Morgan's message of 2010-01-06:
   6398 > > The internet claims that using "rb" and "wb" works for both 1.8.5 and
   6399 > > 1.9.1, but I haven't tried it.
   6400 > 
   6401 > I've done this in ruby-1.9-encodings and remerged into next.
   6402 > 
   6403 > Those of you tracking next with 1.9, please let me know if you
   6404 > experience any weird encoding errors.
   6405 > 
   6406 > (And those with 1.8, as well, I suppose.)
   6407 
   6408 See issue 36, its a bit big: problems with subjects, tab completion, and
   6409 recipients.
   6410 
   6411 - gaute
   6412 
   6413 From wmorgan-sup@masanjin.net  Mon Jan 18 08:05:45 2010
   6414 From: wmorgan-sup@masanjin.net (William Morgan)
   6415 Date: Mon, 18 Jan 2010 08:05:45 -0500
   6416 Subject: [sup-devel] [PATCH] only open mail files in binary mode on Ruby
   6417 	1.9
   6418 In-Reply-To: <1263803813-sup-7395@dolk>
   6419 References: <1262634342-7029-1-git-send-email-rlane@club.cc.cmu.edu>
   6420 	<1262729069-sup-2235@masanjin.net>
   6421 	<1262795751-sup-4525@masanjin.net>
   6422 	<1263769911-sup-6744@masanjin.net> <1263803813-sup-7395@dolk>
   6423 Message-ID: <1263819893-sup-815@masanjin.net>
   6424 
   6425 Reformatted excerpts from Gaute Hope's message of 2010-01-18:
   6426 > See issue 36, its a bit big: problems with subjects, tab completion,
   6427 > and recipients.
   6428 
   6429 This is an unrelated issue, though I agree it's important and should be
   6430 addressed.
   6431 
   6432 Rich sent out a patch a while ago that added the special encoding pragma
   6433 to a bunch of source files. That might fix this, as might putting a "u"
   6434 at the end of every Regexp in the source. :(
   6435 -- 
   6436 William <wmorgan-sup at masanjin.net>
   6437 
   6438 From wmorgan-sup@masanjin.net  Mon Jan 18 08:07:40 2010
   6439 From: wmorgan-sup@masanjin.net (William Morgan)
   6440 Date: Mon, 18 Jan 2010 08:07:40 -0500
   6441 Subject: [sup-devel] merged into master: ferret-deprecation
   6442 In-Reply-To: <1263744321-sup-5501@ntdws12.chass.utoronto.ca>
   6443 References: <1263742220-sup-2852@masanjin.net>
   6444 	<1263744321-sup-5501@ntdws12.chass.utoronto.ca>
   6445 Message-ID: <1263820045-sup-5119@masanjin.net>
   6446 
   6447 Reformatted excerpts from Ben Walton's message of 2010-01-17:
   6448 > Yes please!
   6449 
   6450 It's in.
   6451 -- 
   6452 William <wmorgan-sup at masanjin.net>
   6453 
   6454 From tero@tilus.net  Mon Jan 18 08:39:39 2010
   6455 From: tero@tilus.net (Tero Tilus)
   6456 Date: Mon, 18 Jan 2010 15:39:39 +0200
   6457 Subject: [sup-devel] merged into master: ferret-deprecation
   6458 In-Reply-To: <1263742220-sup-2852@masanjin.net>
   6459 References: <1263742220-sup-2852@masanjin.net>
   6460 Message-ID: <1263821943-sup-1630@tilus.net>
   6461 
   6462 William Morgan, 2010-01-17 17:35:
   6463 > I'm thinking about also merging in insta-save before 0.10 goes out
   6464 > the door, probably with the patch that makes '$' flush
   6465 > Xapian. Thoughts?
   6466 
   6467 If you do it, please include '$'-patch.
   6468 
   6469 -- 
   6470 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
   6471 
   6472 From wmorgan-sup@masanjin.net  Mon Jan 18 12:06:28 2010
   6473 From: wmorgan-sup@masanjin.net (William Morgan)
   6474 Date: Mon, 18 Jan 2010 12:06:28 -0500
   6475 Subject: [sup-devel] RFC: Nuke remote sources
   6476 In-Reply-To: <1263760710-sup-5382@masanjin.net>
   6477 References: <1263754247-20979-1-git-send-email-rlane@club.cc.cmu.edu>
   6478 	<1263760710-sup-5382@masanjin.net>
   6479 Message-ID: <1263834319-sup-3032@masanjin.net>
   6480 
   6481 Reformatted excerpts from William Morgan's message of 2010-01-17:
   6482 > Yeah, another thing to add to 0.10... sigh.
   6483 
   6484 On second thought, I'm going to wait to 0.12 to remove this, and add the
   6485 deprecation notice on 0.11. The poor guy with a ferret index and
   6486 multiple IMAP sources should have a fighting chance.
   6487 
   6488 I'm also going to try and spend less time between releases...
   6489 -- 
   6490 William <wmorgan-sup at masanjin.net>
   6491 
   6492 From hyperbolist@gmail.com  Mon Jan 18 18:44:37 2010
   6493 From: hyperbolist@gmail.com (Eric Sherman)
   6494 Date: Mon, 18 Jan 2010 18:44:37 -0500
   6495 Subject: [sup-devel] [PATCH] Saved Search Support
   6496 Message-ID: <1263858172-sup-547@changeling.local>
   6497 
   6498 Start an index search with a \ backslash and press enter to get a list
   6499 of searches that were previously saved from search-results-mode with %
   6500 percent or added from search-list-mode directly.  Saved searches may be
   6501 used in other searches by enclosing their names in {} curly braces.
   6502 Search names may contain letters, numbers, underscores and dashes.
   6503 
   6504 New Key Bindings
   6505 global
   6506   \<CR> open search-list-mode
   6507 search-list-mode
   6508   X     Delete selected search
   6509   r     Rename selected search
   6510   e     Edit selected search
   6511   a     Add new search
   6512 search-results-mode
   6513   %     Save search
   6514 
   6515 New Hooks
   6516 search-list-filter
   6517 search-list-format
   6518 
   6519 Search String Expansion
   6520 Include saved searches in other searches by enclosing their names in {}
   6521 curly braces.  The name and enclosing braces are replaced by the actual
   6522 search string.  When expanded, they are enclosed within parens to
   6523 preserve logic.
   6524 
   6525     low_traffic: has:foo OR has:bar
   6526     a_slow_week: {low_traffic} AND after:(7 days ago)
   6527 
   6528 {a_slow_week} expands to "(has:foo OR has:bar) AND after:(7 days ago)"
   6529 and may be used in a global search, a refinement or another saved
   6530 search.  If a string enclosed in {} curly braces does not match a saved
   6531 search name it is ignored.
   6532 
   6533 There is no nesting limit and searches are always expanded completely
   6534 before they are turned into proper queries for the index.
   6535 
   6536 Shrinking Search Strings
   6537 Search strings are kept as short as possible when displayed or saved.
   6538 So a search string of "has:foo OR has:bar OR has:baz" added with the
   6539 above searches would be saved as "{low_traffic} OR has:baz".  This may
   6540 or may not always be desirable, but it generally makes things easier.
   6541 
   6542 Editing, Renaming, Deleting
   6543 Editing a search string that has been included in other searches will
   6544 have no effect on those other searches' search strings, but they will
   6545 expand with its new contents.
   6546 
   6547 Renaming a search that has been included in other searches will cause
   6548 each occurrence in those other searches to be renamed as well.
   6549 
   6550 Deleting a search that has been included in other searches will cause it
   6551 to expand into those other searches to prevent breaking them.
   6552 
   6553 Save File Format
   6554 Searches are read from ~/.sup/searches.txt on startup and saved at exit.
   6555 The format is "name: search_string".  Here's a silly example:
   6556 
   6557     core: {me} AND NOT {crap} AND NOT {weak}
   6558     crap: is:leadlogger OR is:alert OR is:rzp
   6559     me: to:me OR from:me
   6560     recently: after:(14 days ago)
   6561     top: {core} AND {recently}
   6562     weak: is:feed OR is:list OR is:ham
   6563 
   6564 FLAG_PURE_NOT
   6565 I also added FLAG_PURE_NOT to the xapian parse_query requests to allow a
   6566 query in the form of "NOT <expression>", which is of questionable
   6567 usefulness but at least sup won't bomb when this happens.
   6568 ---
   6569  bin/sup                              |   11 ++-
   6570  lib/sup.rb                           |    5 +
   6571  lib/sup/modes/search-list-mode.rb    |  164 ++++++++++++++++++++++++++++++++++
   6572  lib/sup/modes/search-results-mode.rb |   14 +++-
   6573  lib/sup/search.rb                    |   87 ++++++++++++++++++
   6574  lib/sup/xapian_index.rb              |    2 +-
   6575  6 files changed, 276 insertions(+), 7 deletions(-)
   6576  create mode 100644 lib/sup/modes/search-list-mode.rb
   6577  create mode 100644 lib/sup/search.rb
   6578 
   6579 diff --git a/bin/sup b/bin/sup
   6580 index 19b2a87..b865b6d 100755
   6581 --- a/bin/sup
   6582 +++ b/bin/sup
   6583 @@ -317,9 +317,14 @@ begin
   6584        b, new = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
   6585        b.mode.load_in_background if new
   6586      when :search
   6587 -      query = BufferManager.ask :search, "search all messages: "
   6588 -      next unless query && query !~ /^\s*$/
   6589 -      SearchResultsMode.spawn_from_query query
   6590 +      query = BufferManager.ask :search, "Search all messages (enter for saved searches): "
   6591 +      unless query.nil?
   6592 +        if query.empty?
   6593 +          bm.spawn_unless_exists("Saved searches") { SearchListMode.new }
   6594 +        else
   6595 +          SearchResultsMode.spawn_from_query query
   6596 +        end
   6597 +      end
   6598      when :search_unread
   6599        SearchResultsMode.spawn_from_query "is:unread"
   6600      when :list_labels
   6601 diff --git a/lib/sup.rb b/lib/sup.rb
   6602 index b83bbe7..b8a0977 100644
   6603 --- a/lib/sup.rb
   6604 +++ b/lib/sup.rb
   6605 @@ -50,6 +50,7 @@ module Redwood
   6606    LOCK_FN    = File.join(BASE_DIR, "lock")
   6607    SUICIDE_FN = File.join(BASE_DIR, "please-kill-yourself")
   6608    HOOK_DIR   = File.join(BASE_DIR, "hooks")
   6609 +  SEARCH_FN  = File.join(BASE_DIR, "searches.txt")
   6610  
   6611    YAML_DOMAIN = "masanjin.net"
   6612    YAML_DATE = "2006-10-01"
   6613 @@ -131,12 +132,14 @@ module Redwood
   6614      Redwood::CryptoManager.init
   6615      Redwood::UndoManager.init
   6616      Redwood::SourceManager.init
   6617 +    Redwood::SearchManager.init Redwood::SEARCH_FN
   6618    end
   6619  
   6620    def finish
   6621      Redwood::LabelManager.save if Redwood::LabelManager.instantiated?
   6622      Redwood::ContactManager.save if Redwood::ContactManager.instantiated?
   6623      Redwood::BufferManager.deinstantiate! if Redwood::BufferManager.instantiated?
   6624 +    Redwood::SearchManager.save if Redwood::SearchManager.instantiated?
   6625    end
   6626  
   6627    ## not really a good place for this, so I'll just dump it here.
   6628 @@ -311,6 +314,8 @@ require "sup/modes/file-browser-mode"
   6629  require "sup/modes/completion-mode"
   6630  require "sup/modes/console-mode"
   6631  require "sup/sent"
   6632 +require "sup/search"
   6633 +require "sup/modes/search-list-mode"
   6634  
   6635  $:.each do |base|
   6636    d = File.join base, "sup/share/modes/"
   6637 diff --git a/lib/sup/modes/search-list-mode.rb b/lib/sup/modes/search-list-mode.rb
   6638 new file mode 100644
   6639 index 0000000..09d081c
   6640 --- /dev/null
   6641 +++ b/lib/sup/modes/search-list-mode.rb
   6642 @@ -0,0 +1,164 @@
   6643 +module Redwood
   6644 +
   6645 +class SearchListMode < LineCursorMode
   6646 +  register_keymap do |k|
   6647 +    k.add :select_search, "Open search results", :enter
   6648 +    k.add :reload, "Discard saved search list and reload", '@'
   6649 +    k.add :jump_to_next_new, "Jump to next new thread", :tab
   6650 +    k.add :toggle_show_unread_only, "Toggle between showing all saved searches and those with unread mail", 'u'
   6651 +    k.add :delete_selected_search, "Delete selected search", "X"
   6652 +    k.add :rename_selected_search, "Rename selected search", "r"
   6653 +    k.add :edit_selected_search, "Edit selected search", "e"
   6654 +    k.add :add_new_search, "Add new search", "a"
   6655 +  end
   6656 +
   6657 +  HookManager.register "search-list-filter", <<EOS
   6658 +Filter the search list, typically to sort.
   6659 +Variables:
   6660 +  counted: an array of counted searches.
   6661 +Return value:
   6662 +  An array of counted searches with sort_by output structure.
   6663 +EOS
   6664 +
   6665 +  HookManager.register "search-list-format", <<EOS
   6666 +Create the sprintf format string for search-list-mode.
   6667 +Variables:
   6668 +  n_width: the maximum search name width
   6669 +  tmax: the maximum total message count
   6670 +  umax: the maximum unread message count
   6671 +  s_width: the maximum search string width
   6672 +Return value:
   6673 +  A format string for sprintf
   6674 +EOS
   6675 +
   6676 +  def initialize
   6677 +    @searches = []
   6678 +    @text = []
   6679 +    @unread_only = false
   6680 +    super
   6681 +    UpdateManager.register self
   6682 +    regen_text
   6683 +  end
   6684 +
   6685 +  def cleanup
   6686 +    UpdateManager.unregister self
   6687 +    super
   6688 +  end
   6689 +
   6690 +  def lines; @text.length end
   6691 +  def [] i; @text[i] end
   6692 +
   6693 +  def jump_to_next_new
   6694 +    n = ((curpos + 1) ... lines).find { |i| @searches[i][1] > 0 } || (0 ... curpos).find { |i| @searches[i][1] > 0 }
   6695 +    if n
   6696 +      ## jump there if necessary
   6697 +      jump_to_line n unless n >= topline && n < botline
   6698 +      set_cursor_pos n
   6699 +    else
   6700 +      BufferManager.flash "No saved searches with unread messages."
   6701 +    end
   6702 +  end
   6703 +
   6704 +  def focus
   6705 +    reload # make sure unread message counts are up-to-date
   6706 +  end
   6707 +
   6708 +  def handle_added_update sender, m
   6709 +    reload
   6710 +  end
   6711 +
   6712 +protected
   6713 +
   6714 +  def toggle_show_unread_only
   6715 +    @unread_only = !@unread_only
   6716 +    reload
   6717 +  end
   6718 +
   6719 +  def reload
   6720 +    regen_text
   6721 +    buffer.mark_dirty if buffer
   6722 +  end
   6723 +
   6724 +  def regen_text
   6725 +    @text = []
   6726 +    searches = SearchManager.all_searches
   6727 +
   6728 +    counted = searches.map do |name|
   6729 +      search_string = SearchManager.search_string_for name
   6730 +      query = Index.parse_query(SearchManager.expand(search_string))
   6731 +      total = Index.num_results_for :qobj => query[:qobj]
   6732 +      unread = Index.num_results_for :qobj => query[:qobj], :label => :unread
   6733 +      [name, search_string, total, unread]
   6734 +    end
   6735 +
   6736 +    if HookManager.enabled? "search-list-filter"
   6737 +      counts = HookManager.run "search-list-filter", :counted => counted
   6738 +    else
   6739 +      counts = counted.sort_by { |n, s, t, u| n.downcase }
   6740 +    end
   6741 +
   6742 +    n_width = counts.max_of { |n, s, t, u| n.length }
   6743 +    tmax    = counts.max_of { |n, s, t, u| t }
   6744 +    umax    = counts.max_of { |n, s, t, u| u }
   6745 +    s_width = counts.max_of { |n, s, t, u| s.length }
   6746 +
   6747 +    if @unread_only
   6748 +      counts.delete_if { | n, s, t, u | u == 0 }
   6749 +    end
   6750 +
   6751 +    @searches = []
   6752 +    counts.map do |name, search_string, total, unread|
   6753 +      fmt = HookManager.run "search-list-format", :n_width => n_width, :tmax => tmax, :umax => umax, :s_width => s_width
   6754 +      if !fmt
   6755 +        fmt = "%#{n_width + 1}s %5d %s, %5d unread: %s"
   6756 +      end
   6757 +      @text << [[(unread == 0 ? :labellist_old_color : :labellist_new_color),
   6758 +          sprintf(fmt, name, total, total == 1 ? " message" : "messages", unread, search_string)]]
   6759 +      @searches << [name, unread]
   6760 +    end.compact
   6761 +
   6762 +    BufferManager.flash "No saved searches with unread messages!" if counts.empty? && @unread_only
   6763 +  end
   6764 +
   6765 +  def select_search
   6766 +    name, num_unread = @searches[curpos]
   6767 +    return unless name
   6768 +    SearchResultsMode.spawn_from_query SearchManager.search_string_for(name)
   6769 +  end
   6770 +
   6771 +  def delete_selected_search
   6772 +    name, num_unread = @searches[curpos]
   6773 +    return unless name
   6774 +    reload if SearchManager.delete name
   6775 +  end
   6776 +
   6777 +  def rename_selected_search
   6778 +    old_name, num_unread = @searches[curpos]
   6779 +    return unless old_name
   6780 +    new_name = BufferManager.ask :save_search, "Rename this saved search: ", old_name
   6781 +    return unless new_name && new_name !~ /^\s*$/ && new_name != old_name
   6782 +    reload if SearchManager.rename old_name, new_name
   6783 +    set_cursor_pos @searches.index([new_name, num_unread])||curpos
   6784 +  end
   6785 +
   6786 +  def edit_selected_search
   6787 +    name, num_unread = @searches[curpos]
   6788 +    return unless name
   6789 +    old_search_string = SearchManager.search_string_for name
   6790 +    new_search_string = BufferManager.ask :search, "Edit this saved search: ", (old_search_string + " ")
   6791 +    return unless new_search_string && new_search_string !~ /^\s*$/ && new_search_string != old_search_string
   6792 +    reload if SearchManager.edit name, new_search_string
   6793 +    set_cursor_pos @searches.index([name, num_unread])||curpos
   6794 +  end
   6795 +
   6796 +  def add_new_search
   6797 +    search_string = BufferManager.ask :search, "New search: "
   6798 +    return unless search_string && search_string !~ /^\s*$/
   6799 +    name = BufferManager.ask :save_search, "Name for new search: "
   6800 +    return unless name && name !~ /^\s*$/ && !(SearchManager.all_searches.include? name)
   6801 +    reload if SearchManager.add name, search_string
   6802 +    set_cursor_pos @searches.index(@searches.assoc(name))||curpos
   6803 +  end
   6804 +end
   6805 +
   6806 +end
   6807 diff --git a/lib/sup/modes/search-results-mode.rb b/lib/sup/modes/search-results-mode.rb
   6808 index 121e817..2237295 100644
   6809 --- a/lib/sup/modes/search-results-mode.rb
   6810 +++ b/lib/sup/modes/search-results-mode.rb
   6811 @@ -8,14 +8,21 @@ class SearchResultsMode < ThreadIndexMode
   6812  
   6813    register_keymap do |k|
   6814      k.add :refine_search, "Refine search", '|'
   6815 +    k.add :save_search, "Save search", '%'
   6816    end
   6817  
   6818    def refine_search
   6819 -    text = BufferManager.ask :search, "refine query: ", (@query[:text] + " ")
   6820 +    text = BufferManager.ask :search, "refine query: ", (SearchManager.shrink(@query[:text]) + " ")
   6821      return unless text && text !~ /^\s*$/
   6822      SearchResultsMode.spawn_from_query text
   6823    end
   6824  
   6825 +  def save_search
   6826 +    name = BufferManager.ask :save_search, "Name this search: "
   6827 +    return unless name && name !~ /^\s*$/
   6828 +    BufferManager.flash "Saved search." if SearchManager.add name, @query[:text]
   6829 +  end
   6830 +
   6831    ## a proper is_relevant? method requires some way of asking ferret
   6832    ## if an in-memory object satisfies a query. i'm not sure how to do
   6833    ## that yet. in the worst case i can make an in-memory index, add
   6834 @@ -24,9 +31,10 @@ class SearchResultsMode < ThreadIndexMode
   6835  
   6836    def self.spawn_from_query text
   6837      begin
   6838 -      query = Index.parse_query(text)
   6839 +      query = Index.parse_query(SearchManager.expand(text))
   6840        return unless query
   6841 -      short_text = text.length < 20 ? text : text[0 ... 20] + "..."
   6842 +      shrunk = SearchManager.shrink text
   6843 +      short_text = shrunk.length < 20 ? shrunk : shrunk[0 ... 20] + "..."
   6844        mode = SearchResultsMode.new query
   6845        BufferManager.spawn "search: \"#{short_text}\"", mode
   6846        mode.load_threads :num => mode.buffer.content_height
   6847 diff --git a/lib/sup/search.rb b/lib/sup/search.rb
   6848 new file mode 100644
   6849 index 0000000..e2a1a35
   6850 --- /dev/null
   6851 +++ b/lib/sup/search.rb
   6852 @@ -0,0 +1,87 @@
   6853 +module Redwood
   6854 +
   6855 +class SearchManager
   6856 +  include Singleton
   6857 +
   6858 +  def initialize fn
   6859 +    @fn = fn
   6860 +    @searches = {}
   6861 +    if File.exists? fn
   6862 +      IO.foreach(fn) do |l|
   6863 +        l =~ /^([^:]*): (.*)$/ or raise "can't parse #{fn} line #{l.inspect}"
   6864 +        @searches[$1] = $2
   6865 +      end
   6866 +    end
   6867 +    @modified = false
   6868 +    @expanded = {}
   6869 +    expand_all
   6870 +  end
   6871 +
   6872 +  def all_searches; return @searches.keys.sort; end
   6873 +  def search_string_for name; return @searches[name]; end
   6874 +
   6875 +  def add name, search_string
   6876 +    name.strip!
   6877 +    search_string.strip!
   6878 +    unless name !~ /^[\w-]+$/ or @searches[name] == search_string
   6879 +      @searches[name] = shrink search_string
   6880 +      expand_all
   6881 +      shrink_all
   6882 +      @modified = true
   6883 +    end
   6884 +  end
   6885 +
   6886 +  def rename old, new
   6887 +    new.strip!
   6888 +    return unless new =~ /^[\w-]+$/ and @searches.has_key? old
   6889 +    search_string = @searches[old]
   6890 +    delete old
   6891 +    add new, search_string
   6892 +  end
   6893 +
   6894 +  def edit name, search_string
   6895 +    return unless @searches.has_key? name
   6896 +    ## we want to delete the old one, but not expand it into searches when doing so
   6897 +    @expanded.delete name
   6898 +    @searches.delete name
   6899 +    add name, search_string
   6900 +  end
   6901 +
   6902 +  def delete name
   6903 +    return unless @searches.has_key? name
   6904 +    expand_into_searches name
   6905 +    @expanded.delete name
   6906 +    @searches.delete name
   6907 +    @modified = true
   6908 +  end
   6909 +
   6910 +  def expand search_string
   6911 +    s = search_string.dup
   6912 +    ## stop trying to expand if there are no expansion candidates left, if the none of the remaining candidates represent a search name, or if the string has grown abnormally large due to what would have been infinite recursion
   6913 +    until (m = /\{([\w-]+)\}/.match(s)).nil? or m.captures.collect { |n| @expanded.keys.index n }.compact.size == 0 or s.size >= 2048
   6914 +      m.captures.each { |n| s.gsub! "{#{n}}", "(#{@expanded[n]})" if @expanded.has_key? n }
   6915 +    end
   6916 +    return s
   6917 +  end
   6918 +
   6919 +  def shrink search_string
   6920 +    s = search_string.dup
   6921 +    @expanded.each { |k, v| s.gsub! /\(?#{Regexp.escape v}\)?/, "{#{k}}" unless k == @expanded.index(s) }
   6922 +    @searches.each { |k, v| s.gsub! /\(?#{Regexp.escape v}\)?/, "{#{k}}" unless k == @searches.index(s) }
   6923 +    return s
   6924 +  end
   6925 +
   6926 +  def save
   6927 +    return unless @modified
   6928 +    File.open(@fn, "w") { |f| @searches.sort.each { |(n, s)| f.puts "#{n}: #{s}" } }
   6929 +    @modified = false
   6930 +  end
   6931 +
   6932 +private
   6933 +
   6934 +  def expand_into_searches name; @searches.values.each { |v| v.gsub! "{#{name}}", "(#{@searches[name]})" }; end
   6935 +  def expand_all; @expanded.replace(@searches).each { |k, v| @expanded[k] = expand v }; end
   6936 +  def shrink_all; @searches.each { |k, v| @searches[k] = shrink v }; end
   6937 +end
   6938 +
   6939 +end
   6940 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   6941 index 0db5010..1bbde5d 100644
   6942 --- a/lib/sup/xapian_index.rb
   6943 +++ b/lib/sup/xapian_index.rb
   6944 @@ -263,7 +263,7 @@ EOS
   6945      qp.add_valuerangeprocessor(Xapian::NumberValueRangeProcessor.new(DATE_VALUENO, 'date:', true))
   6946      NORMAL_PREFIX.each { |k,v| qp.add_prefix k, v }
   6947      BOOLEAN_PREFIX.each { |k,v| qp.add_boolean_prefix k, v }
   6948 -    xapian_query = qp.parse_query(subs, Xapian::QueryParser::FLAG_PHRASE|Xapian::QueryParser::FLAG_BOOLEAN|Xapian::QueryParser::FLAG_LOVEHATE|Xapian::QueryParser::FLAG_WILDCARD, PREFIX['body'])
   6949 +    xapian_query = qp.parse_query(subs, Xapian::QueryParser::FLAG_PHRASE|Xapian::QueryParser::FLAG_BOOLEAN|Xapian::QueryParser::FLAG_LOVEHATE|Xapian::QueryParser::FLAG_WILDCARD|Xapian::QueryParser::FLAG_PURE_NOT, PREFIX['body'])
   6950  
   6951      debug "parsed xapian query: #{xapian_query.description}"
   6952  
   6953 -- 
   6954 1.6.6
   6955 
   6956 
   6957 From rlane@club.cc.cmu.edu  Tue Jan 19 13:00:32 2010
   6958 From: rlane@club.cc.cmu.edu (Rich Lane)
   6959 Date: Tue, 19 Jan 2010 13:00:32 -0500
   6960 Subject: [sup-devel] [PATCH] Saved Search Support
   6961 In-Reply-To: <1263858172-sup-547@changeling.local>
   6962 References: <1263858172-sup-547@changeling.local>
   6963 Message-ID: <1263920054-sup-9400@zyrg.net>
   6964 
   6965 Excerpts from Eric Sherman's message of 2010-01-18 18:44:37 -0500:
   6966 > Start an index search with a \ backslash and press enter to get a list
   6967 > of searches that were previously saved from search-results-mode with %
   6968 > percent or added from search-list-mode directly.  Saved searches may be
   6969 > used in other searches by enclosing their names in {} curly braces.
   6970 > Search names may contain letters, numbers, underscores and dashes.
   6971 
   6972 This is a nice feature. A few comments:
   6973 
   6974 I'd like it better if shrinking went away and the only time we expanded
   6975 was right before giving it to parse_query. I'd rather not have the
   6976 expand-on-delete or rename-tracking behaviors. These changes would
   6977 simplify the code quite a bit. I think attempting to expand a
   6978 nonexistent saved search should result in something false ("type:false",
   6979 maybe), send a warning to the log, and perhaps flash an error message.
   6980 
   6981 On Ruby 1.9.1 I get:
   6982 lib/sup/search.rb:69: warning: Hash#index is deprecated; use Hash#key
   6983 
   6984 SearchListMode#regen_text: looks like a mixup of each and map
   6985 
   6986 SearchListMode#add_new_search:
   6987 Should flash an error message on name collisions, or allow overwriting.
   6988 
   6989 SearchListMode#rename_selected_search, SearchListMode#save_search:
   6990 Name collision handling should be consistent with add_new_search.
   6991 
   6992 SearchManager:
   6993 I'd replace the duplicated name checking regexes with a method.
   6994 
   6995 SearchManager#rename:
   6996 I think the strip should be done by the caller.
   6997 
   6998 From sup-bugs@masanjin.net  Tue Jan 19 13:35:36 2010
   6999 From: sup-bugs@masanjin.net (anonymous)
   7000 Date: Tue, 19 Jan 2010 18:35:36 +0000
   7001 Subject: [sup-devel] [issue46] "stack level too deep" within xapian code
   7002 In-Reply-To: <1263926136.68.0.119961985085.issue46@masanjin.net>
   7003 Message-ID: <1263926136.68.0.119961985085.issue46@masanjin.net>
   7004 
   7005 
   7006 New submission from anonymous:
   7007 
   7008 In the most recent next, after writing a message:
   7009 
   7010 --- SystemStackError from thread: main
   7011 stack level too deep
   7012 ./lib/sup/xapian_index.rb:600:in `old_add_term'
   7013 ./lib/sup/xapian_index.rb:600:in `old_add_term'
   7014 ./lib/sup/xapian_index.rb:600:in `add_term'
   7015 ./lib/sup/xapian_index.rb:470:in `index_message_static'
   7016 ./lib/sup/xapian_index.rb:470:in `each'
   7017 ./lib/sup/xapian_index.rb:470:in `index_message_static'
   7018 ./lib/sup/xapian_index.rb:474:in `[]'
   7019 ./lib/sup/xapian_index.rb:474:in `index_message_static'
   7020 ./lib/sup/xapian_index.rb:442:in `sync_message'
   7021 ./lib/sup/xapian_index.rb:96:in `add_message'
   7022 ./lib/sup/index.rb:236:in `send'
   7023 ./lib/sup/index.rb:236:in `method_missing'
   7024 ./lib/sup/poll.rb:183:in `add_new_message'
   7025 ./lib/sup/util.rb:553:in `send'
   7026 ./lib/sup/util.rb:553:in `method_missing'
   7027 ./lib/sup/sent.rb:33:in `write_sent_message'
   7028 ./lib/sup/poll.rb:169:in `each_message_from'
   7029 ./lib/sup/imap.rb:197:in `each'
   7030 ./lib/sup/imap.rb:185:in `upto'
   7031 ./lib/sup/imap.rb:185:in `each'
   7032 ./lib/sup/util.rb:593:in `send'
   7033 ./lib/sup/util.rb:593:in `__pass'
   7034 ./lib/sup/util.rb:580:in `method_missing'
   7035 ./lib/sup/poll.rb:157:in `each_message_from'
   7036 ./lib/sup/util.rb:553:in `send'
   7037 ./lib/sup/util.rb:553:in `method_missing'
   7038 ./lib/sup/sent.rb:30:in `write_sent_message'
   7039 ./lib/sup/util.rb:553:in `send'
   7040 ./lib/sup/util.rb:553:in `method_missing'
   7041 ./lib/sup/modes/edit-message-mode.rb:325:in `send_message'
   7042 ./lib/sup/mode.rb:51:in `send'
   7043 ./lib/sup/mode.rb:51:in `handle_input'
   7044 ./lib/sup/buffer.rb:272:in `handle_input'
   7045 bin/sup:276
   7046 
   7047 ----------
   7048 messages: 111
   7049 nosy: anonymous
   7050 priority: bug
   7051 ruby_version: 1.8.7
   7052 status: unread
   7053 sup_version: git next
   7054 title: "stack level too deep" within xapian code
   7055 
   7056 _________________________________________
   7057 Sup issue tracker <sup-bugs at masanjin.net>
   7058 <http://masanjin.net/sup-bugs/issue46>
   7059 _________________________________________
   7060 
   7061 From rlane@club.cc.cmu.edu  Tue Jan 19 16:48:25 2010
   7062 From: rlane@club.cc.cmu.edu (Rich Lane)
   7063 Date: Tue, 19 Jan 2010 16:48:25 -0500
   7064 Subject: [sup-devel] [PATCH] asciify untrusted strings before displaying in
   7065 	TextMode
   7066 Message-ID: <1263937705-10875-1-git-send-email-rlane@club.cc.cmu.edu>
   7067 
   7068 ---
   7069  lib/sup/modes/file-browser-mode.rb |    2 +-
   7070  lib/sup/modes/text-mode.rb         |    2 +-
   7071  lib/sup/modes/thread-view-mode.rb  |    4 ++--
   7072  3 files changed, 4 insertions(+), 4 deletions(-)
   7073 
   7074 diff --git a/lib/sup/modes/file-browser-mode.rb b/lib/sup/modes/file-browser-mode.rb
   7075 index b92468d..72e12db 100644
   7076 --- a/lib/sup/modes/file-browser-mode.rb
   7077 +++ b/lib/sup/modes/file-browser-mode.rb
   7078 @@ -47,7 +47,7 @@ protected
   7079      return unless f && f.file?
   7080  
   7081      begin
   7082 -      BufferManager.spawn f.to_s, TextMode.new(f.read)
   7083 +      BufferManager.spawn f.to_s, TextMode.new(f.read.ascii)
   7084      rescue SystemCallError => e
   7085        BufferManager.flash e.message
   7086      end
   7087 diff --git a/lib/sup/modes/text-mode.rb b/lib/sup/modes/text-mode.rb
   7088 index 7c9e7d8..e772ff5 100644
   7089 --- a/lib/sup/modes/text-mode.rb
   7090 +++ b/lib/sup/modes/text-mode.rb
   7091 @@ -29,7 +29,7 @@ class TextMode < ScrollMode
   7092      end
   7093  
   7094      if output
   7095 -      BufferManager.spawn "Output of '#{command}'", TextMode.new(output)
   7096 +      BufferManager.spawn "Output of '#{command}'", TextMode.new(output.ascii)
   7097      else
   7098        BufferManager.flash "'#{command}' done!"
   7099      end
   7100 diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb
   7101 index b08c819..0e935a4 100644
   7102 --- a/lib/sup/modes/thread-view-mode.rb
   7103 +++ b/lib/sup/modes/thread-view-mode.rb
   7104 @@ -613,7 +613,7 @@ EOS
   7105      end
   7106  
   7107      if output
   7108 -      BufferManager.spawn "Output of '#{command}'", TextMode.new(output)
   7109 +      BufferManager.spawn "Output of '#{command}'", TextMode.new(output.ascii)
   7110      else
   7111        BufferManager.flash "'#{command}' done!"
   7112      end
   7113 @@ -815,7 +815,7 @@ private
   7114      BufferManager.erase_flash
   7115      BufferManager.completely_redraw_screen
   7116      unless success
   7117 -      BufferManager.spawn "Attachment: #{chunk.filename}", TextMode.new(chunk.to_s, chunk.filename)
   7118 +      BufferManager.spawn "Attachment: #{chunk.filename}", TextMode.new(chunk.to_s.ascii, chunk.filename)
   7119        BufferManager.flash "Couldn't execute view command, viewing as text."
   7120      end
   7121    end
   7122 -- 
   7123 1.5.6.5
   7124 
   7125 
   7126 From hyperbolist@gmail.com  Tue Jan 19 22:46:35 2010
   7127 From: hyperbolist@gmail.com (Eric Sherman)
   7128 Date: Tue, 19 Jan 2010 22:46:35 -0500
   7129 Subject: [sup-devel] [PATCH] Saved Search Support
   7130 In-Reply-To: <1263920054-sup-9400@zyrg.net>
   7131 References: <1263858172-sup-547@changeling.local>
   7132 	<1263920054-sup-9400@zyrg.net>
   7133 Message-ID: <1263959057-sup-3237@changeling.local>
   7134 
   7135 Excerpts from Rich Lane's message of Tue Jan 19 13:00:32 -0500 2010:
   7136 > I'd like it better if shrinking went away and the only time we expanded
   7137 > was right before giving it to parse_query. I'd rather not have the
   7138 > expand-on-delete or rename-tracking behaviors.
   7139 
   7140 I'm not sure why I thought any of that was such a great idea.
   7141 
   7142 > I think attempting to expand a nonexistent saved search should result in 
   7143 > something false ("type:false", maybe), send a warning to the log, and 
   7144 > perhaps flash an error message.
   7145 
   7146 SearchManager#expand now returns false, logs a warning and flashes an error 
   7147 message when expansion fails.
   7148 
   7149 > On Ruby 1.9.1 I get:
   7150 > lib/sup/search.rb:69: warning: Hash#index is deprecated; use Hash#key
   7151 
   7152 Removed.
   7153 
   7154 > SearchListMode#regen_text: looks like a mixup of each and map
   7155 
   7156 Fixed.
   7157 
   7158 > SearchListMode#add_new_search:
   7159 > Should flash an error message on name collisions, or allow overwriting.
   7160 >
   7161 > SearchListMode#rename_selected_search, SearchListMode#save_search:
   7162 > Name collision handling should be consistent with add_new_search.
   7163 
   7164 An error message is flashed.
   7165 
   7166 > SearchManager:
   7167 > I'd replace the duplicated name checking regexes with a method.
   7168 
   7169 Replaced.
   7170 
   7171 > SearchManager#rename:
   7172 > I think the strip should be done by the caller.
   7173 
   7174 Done.
   7175 
   7176 From hyperbolist@gmail.com  Tue Jan 19 22:48:50 2010
   7177 From: hyperbolist@gmail.com (Eric Sherman)
   7178 Date: Tue, 19 Jan 2010 22:48:50 -0500
   7179 Subject: [sup-devel] [PATCHv2] Saved Search Support
   7180 In-Reply-To: <1263920054-sup-9400@zyrg.net>
   7181 References: <1263858172-sup-547@changeling.local>
   7182 	<1263920054-sup-9400@zyrg.net>
   7183 Message-ID: <1263959248-sup-4163@changeling.local>
   7184 
   7185 Start an index search with a \ backslash and press enter to get a list
   7186 of searches that were previously saved from search-results-mode with %
   7187 percent or added from search-list-mode directly.  Saved searches may be
   7188 used in other searches by enclosing their names in {} curly braces.
   7189 Search names may contain letters, numbers, underscores and dashes.
   7190 
   7191 New Key Bindings
   7192 global
   7193   \<CR> open search-list-mode
   7194 search-list-mode
   7195   X     Delete selected search
   7196   r     Rename selected search
   7197   e     Edit selected search
   7198   a     Add new search
   7199 search-results-mode
   7200   %     Save search
   7201 
   7202 New Hooks
   7203 search-list-filter
   7204 search-list-format
   7205 
   7206 Search String Expansion
   7207 Include saved searches in other searches by enclosing their names in {}
   7208 curly braces.  The name and enclosing braces are replaced by the actual
   7209 search string and enclosing () parens.
   7210 
   7211     low_traffic: has:foo OR has:bar
   7212     a_slow_week: {low_traffic} AND after:(7 days ago)
   7213 
   7214 {a_slow_week} expands to "(has:foo OR has:bar) AND after:(7 days ago)"
   7215 and may be used in a global search, a refinement or another saved
   7216 search.  A search including the undefined {baz} will fail. To search for
   7217 a literal string enclosed in curly braces, escape the curly braces with
   7218 \ backslash: "\{baz\}".
   7219 
   7220 There is no nesting limit and searches are always expanded completely
   7221 before they are turned into proper queries for the index.
   7222 
   7223 Save File Format
   7224 Searches are read from ~/.sup/searches.txt on startup and saved at exit.
   7225 The format is "name: search_string".  Here's a silly example:
   7226 
   7227     core: {me} AND NOT {crap} AND NOT {weak}
   7228     crap: is:leadlogger OR is:alert OR is:rzp
   7229     me: to:me OR from:me
   7230     recent: after:(14 days ago)
   7231     top: {core} AND {recent}
   7232     weak: is:feed OR is:list OR is:ham
   7233 ---
   7234  bin/sup                              |   11 ++-
   7235  lib/sup.rb                           |    5 +
   7236  lib/sup/modes/search-list-mode.rb    |  188 ++++++++++++++++++++++++++++++++++
   7237  lib/sup/modes/search-results-mode.rb |   23 ++++-
   7238  lib/sup/search.rb                    |   72 +++++++++++++
   7239  5 files changed, 294 insertions(+), 5 deletions(-)
   7240  create mode 100644 lib/sup/modes/search-list-mode.rb
   7241  create mode 100644 lib/sup/search.rb
   7242 
   7243 diff --git a/bin/sup b/bin/sup
   7244 index 8bf640b..fb19795 100755
   7245 --- a/bin/sup
   7246 +++ b/bin/sup
   7247 @@ -303,9 +303,14 @@ begin
   7248        b, new = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
   7249        b.mode.load_in_background if new
   7250      when :search
   7251 -      query = BufferManager.ask :search, "search all messages: "
   7252 -      next unless query && query !~ /^\s*$/
   7253 -      SearchResultsMode.spawn_from_query query
   7254 +      query = BufferManager.ask :search, "Search all messages (enter for saved searches): "
   7255 +      unless query.nil?
   7256 +        if query.empty?
   7257 +          bm.spawn_unless_exists("Saved searches") { SearchListMode.new }
   7258 +        else
   7259 +          SearchResultsMode.spawn_from_query query
   7260 +        end
   7261 +      end
   7262      when :search_unread
   7263        SearchResultsMode.spawn_from_query "is:unread"
   7264      when :list_labels
   7265 diff --git a/lib/sup.rb b/lib/sup.rb
   7266 index e03a35d..b9dc749 100644
   7267 --- a/lib/sup.rb
   7268 +++ b/lib/sup.rb
   7269 @@ -50,6 +50,7 @@ module Redwood
   7270    LOCK_FN    = File.join(BASE_DIR, "lock")
   7271    SUICIDE_FN = File.join(BASE_DIR, "please-kill-yourself")
   7272    HOOK_DIR   = File.join(BASE_DIR, "hooks")
   7273 +  SEARCH_FN  = File.join(BASE_DIR, "searches.txt")
   7274  
   7275    YAML_DOMAIN = "masanjin.net"
   7276    YAML_DATE = "2006-10-01"
   7277 @@ -131,12 +132,14 @@ module Redwood
   7278      Redwood::CryptoManager.init
   7279      Redwood::UndoManager.init
   7280      Redwood::SourceManager.init
   7281 +    Redwood::SearchManager.init Redwood::SEARCH_FN
   7282    end
   7283  
   7284    def finish
   7285      Redwood::LabelManager.save if Redwood::LabelManager.instantiated?
   7286      Redwood::ContactManager.save if Redwood::ContactManager.instantiated?
   7287      Redwood::BufferManager.deinstantiate! if Redwood::BufferManager.instantiated?
   7288 +    Redwood::SearchManager.save if Redwood::SearchManager.instantiated?
   7289    end
   7290  
   7291    ## not really a good place for this, so I'll just dump it here.
   7292 @@ -341,6 +344,8 @@ require "sup/modes/file-browser-mode"
   7293  require "sup/modes/completion-mode"
   7294  require "sup/modes/console-mode"
   7295  require "sup/sent"
   7296 +require "sup/search"
   7297 +require "sup/modes/search-list-mode"
   7298  
   7299  $:.each do |base|
   7300    d = File.join base, "sup/share/modes/"
   7301 diff --git a/lib/sup/modes/search-list-mode.rb b/lib/sup/modes/search-list-mode.rb
   7302 new file mode 100644
   7303 index 0000000..076c3d9
   7304 --- /dev/null
   7305 +++ b/lib/sup/modes/search-list-mode.rb
   7306 @@ -0,0 +1,188 @@
   7307 +module Redwood
   7308 +
   7309 +class SearchListMode < LineCursorMode
   7310 +  register_keymap do |k|
   7311 +    k.add :select_search, "Open search results", :enter
   7312 +    k.add :reload, "Discard saved search list and reload", '@'
   7313 +    k.add :jump_to_next_new, "Jump to next new thread", :tab
   7314 +    k.add :toggle_show_unread_only, "Toggle between showing all saved searches and those with unread mail", 'u'
   7315 +    k.add :delete_selected_search, "Delete selected search", "X"
   7316 +    k.add :rename_selected_search, "Rename selected search", "r"
   7317 +    k.add :edit_selected_search, "Edit selected search", "e"
   7318 +    k.add :add_new_search, "Add new search", "a"
   7319 +  end
   7320 +
   7321 +  HookManager.register "search-list-filter", <<EOS
   7322 +Filter the search list, typically to sort.
   7323 +Variables:
   7324 +  counted: an array of counted searches.
   7325 +Return value:
   7326 +  An array of counted searches with sort_by output structure.
   7327 +EOS
   7328 +
   7329 +  HookManager.register "search-list-format", <<EOS
   7330 +Create the sprintf format string for search-list-mode.
   7331 +Variables:
   7332 +  n_width: the maximum search name width
   7333 +  tmax: the maximum total message count
   7334 +  umax: the maximum unread message count
   7335 +  s_width: the maximum search string width
   7336 +Return value:
   7337 +  A format string for sprintf
   7338 +EOS
   7339 +
   7340 +  def initialize
   7341 +    @searches = []
   7342 +    @text = []
   7343 +    @unread_only = false
   7344 +    super
   7345 +    UpdateManager.register self
   7346 +    regen_text
   7347 +  end
   7348 +
   7349 +  def cleanup
   7350 +    UpdateManager.unregister self
   7351 +    super
   7352 +  end
   7353 +
   7354 +  def lines; @text.length end
   7355 +  def [] i; @text[i] end
   7356 +
   7357 +  def jump_to_next_new
   7358 +    n = ((curpos + 1) ... lines).find { |i| @searches[i][1] > 0 } || (0 ... curpos).find { |i| @searches[i][1] > 0 }
   7359 +    if n
   7360 +      ## jump there if necessary
   7361 +      jump_to_line n unless n >= topline && n < botline
   7362 +      set_cursor_pos n
   7363 +    else
   7364 +      BufferManager.flash "No saved searches with unread messages."
   7365 +    end
   7366 +  end
   7367 +
   7368 +  def focus
   7369 +    reload # make sure unread message counts are up-to-date
   7370 +  end
   7371 +
   7372 +  def handle_added_update sender, m
   7373 +    reload
   7374 +  end
   7375 +
   7376 +protected
   7377 +
   7378 +  def toggle_show_unread_only
   7379 +    @unread_only = !@unread_only
   7380 +    reload
   7381 +  end
   7382 +
   7383 +  def reload
   7384 +    regen_text
   7385 +    buffer.mark_dirty if buffer
   7386 +  end
   7387 +
   7388 +  def regen_text
   7389 +    @text = []
   7390 +    searches = SearchManager.all_searches
   7391 +
   7392 +    counted = searches.map do |name|
   7393 +      search_string = SearchManager.search_string_for name
   7394 +      expanded_search_string= SearchManager.expand search_string
   7395 +      if expanded_search_string
   7396 +        query = Index.parse_query expanded_search_string
   7397 +        total = Index.num_results_for :qobj => query[:qobj]
   7398 +        unread = Index.num_results_for :qobj => query[:qobj], :label => :unread
   7399 +      else
   7400 +        total = 0
   7401 +        unread = 0
   7402 +      end
   7403 +      [name, search_string, total, unread]
   7404 +    end
   7405 +
   7406 +    if HookManager.enabled? "search-list-filter"
   7407 +      counts = HookManager.run "search-list-filter", :counted => counted
   7408 +    else
   7409 +      counts = counted.sort_by { |n, s, t, u| n.downcase }
   7410 +    end
   7411 +
   7412 +    n_width = counts.max_of { |n, s, t, u| n.length }
   7413 +    tmax    = counts.max_of { |n, s, t, u| t }
   7414 +    umax    = counts.max_of { |n, s, t, u| u }
   7415 +    s_width = counts.max_of { |n, s, t, u| s.length }
   7416 +
   7417 +    if @unread_only
   7418 +      counts.delete_if { | n, s, t, u | u == 0 }
   7419 +    end
   7420 +
   7421 +    @searches = []
   7422 +    counts.each do |name, search_string, total, unread|
   7423 +      fmt = HookManager.run "search-list-format", :n_width => n_width, :tmax => tmax, :umax => umax, :s_width => s_width
   7424 +      if !fmt
   7425 +        fmt = "%#{n_width + 1}s %5d %s, %5d unread: %s"
   7426 +      end
   7427 +      @text << [[(unread == 0 ? :labellist_old_color : :labellist_new_color),
   7428 +          sprintf(fmt, name, total, total == 1 ? " message" : "messages", unread, search_string)]]
   7429 +      @searches << [name, unread]
   7430 +    end
   7431 +
   7432 +    BufferManager.flash "No saved searches with unread messages!" if counts.empty? && @unread_only
   7433 +  end
   7434 +
   7435 +  def select_search
   7436 +    name, num_unread = @searches[curpos]
   7437 +    return unless name
   7438 +    SearchResultsMode.spawn_from_query SearchManager.search_string_for(name)
   7439 +  end
   7440 +
   7441 +  def delete_selected_search
   7442 +    name, num_unread = @searches[curpos]
   7443 +    return unless name
   7444 +    reload if SearchManager.delete name
   7445 +  end
   7446 +
   7447 +  def rename_selected_search
   7448 +    old_name, num_unread = @searches[curpos]
   7449 +    return unless old_name
   7450 +    new_name = BufferManager.ask :save_search, "Rename this saved search: ", old_name
   7451 +    return unless new_name && new_name !~ /^\s*$/ && new_name != old_name
   7452 +    new_name.strip!
   7453 +    unless SearchManager.valid_name? new_name
   7454 +      BufferManager.flash "Not renamed: " + SearchManager.name_format_hint
   7455 +      return
   7456 +    end
   7457 +    if SearchManager.all_searches.include? new_name
   7458 +      BufferManager.flash "Not renamed: \"#{new_name}\" already exists"
   7459 +      return
   7460 +    end
   7461 +    reload if SearchManager.rename old_name, new_name
   7462 +    set_cursor_pos @searches.index([new_name, num_unread])||curpos
   7463 +  end
   7464 +
   7465 +  def edit_selected_search
   7466 +    name, num_unread = @searches[curpos]
   7467 +    return unless name
   7468 +    old_search_string = SearchManager.search_string_for name
   7469 +    new_search_string = BufferManager.ask :search, "Edit this saved search: ", (old_search_string + " ")
   7470 +    return unless new_search_string && new_search_string !~ /^\s*$/ && new_search_string != old_search_string
   7471 +    reload if SearchManager.edit name, new_search_string.strip
   7472 +    set_cursor_pos @searches.index([name, num_unread])||curpos
   7473 +  end
   7474 +
   7475 +  def add_new_search
   7476 +    search_string = BufferManager.ask :search, "New search: "
   7477 +    return unless search_string && search_string !~ /^\s*$/
   7478 +    name = BufferManager.ask :save_search, "Name this search: "
   7479 +    return unless name && name !~ /^\s*$/
   7480 +    name.strip!
   7481 +    unless SearchManager.valid_name? name
   7482 +      BufferManager.flash "Not saved: " + SearchManager.name_format_hint
   7483 +      return
   7484 +    end
   7485 +    if SearchManager.all_searches.include? name
   7486 +      BufferManager.flash "Not saved: \"#{name}\" already exists"
   7487 +      return
   7488 +    end
   7489 +    reload if SearchManager.add name, search_string.strip
   7490 +    set_cursor_pos @searches.index(@searches.assoc(name))||curpos
   7491 +  end
   7492 +end
   7493 +
   7494 +end
   7495 diff --git a/lib/sup/modes/search-results-mode.rb b/lib/sup/modes/search-results-mode.rb
   7496 index 121e817..14d42b5 100644
   7497 --- a/lib/sup/modes/search-results-mode.rb
   7498 +++ b/lib/sup/modes/search-results-mode.rb
   7499 @@ -8,14 +8,30 @@ class SearchResultsMode < ThreadIndexMode
   7500  
   7501    register_keymap do |k|
   7502      k.add :refine_search, "Refine search", '|'
   7503 +    k.add :save_search, "Save search", '%'
   7504    end
   7505  
   7506    def refine_search
   7507 -    text = BufferManager.ask :search, "refine query: ", (@query[:text] + " ")
   7508 +    text = BufferManager.ask :search, "refine query: ", (@query[:unexpanded_text] + " ")
   7509      return unless text && text !~ /^\s*$/
   7510      SearchResultsMode.spawn_from_query text
   7511    end
   7512  
   7513 +  def save_search
   7514 +    name = BufferManager.ask :save_search, "Name this search: "
   7515 +    return unless name && name !~ /^\s*$/
   7516 +    name.strip!
   7517 +    unless SearchManager.valid_name? name
   7518 +      BufferManager.flash "Not saved: " + SearchManager.name_format_hint
   7519 +      return
   7520 +    end
   7521 +    if SearchManager.all_searches.include? name
   7522 +      BufferManager.flash "Not saved: \"#{name}\" already exists"
   7523 +      return
   7524 +    end
   7525 +    BufferManager.flash "Search saved as \"#{name}\"" if SearchManager.add name, @query[:unexpanded_text].strip
   7526 +  end
   7527 +
   7528    ## a proper is_relevant? method requires some way of asking ferret
   7529    ## if an in-memory object satisfies a query. i'm not sure how to do
   7530    ## that yet. in the worst case i can make an in-memory index, add
   7531 @@ -24,8 +40,11 @@ class SearchResultsMode < ThreadIndexMode
   7532  
   7533    def self.spawn_from_query text
   7534      begin
   7535 -      query = Index.parse_query(text)
   7536 +      expanded_text = SearchManager.expand text
   7537 +      return unless expanded_text
   7538 +      query = Index.parse_query expanded_text
   7539        return unless query
   7540 +      query[:unexpanded_text] = text
   7541        short_text = text.length < 20 ? text : text[0 ... 20] + "..."
   7542        mode = SearchResultsMode.new query
   7543        BufferManager.spawn "search: \"#{short_text}\"", mode
   7544 diff --git a/lib/sup/search.rb b/lib/sup/search.rb
   7545 new file mode 100644
   7546 index 0000000..799ca89
   7547 --- /dev/null
   7548 +++ b/lib/sup/search.rb
   7549 @@ -0,0 +1,72 @@
   7550 +module Redwood
   7551 +
   7552 +class SearchManager
   7553 +  include Singleton
   7554 +
   7555 +  def initialize fn
   7556 +    @fn = fn
   7557 +    @searches = {}
   7558 +    if File.exists? fn
   7559 +      IO.foreach(fn) do |l|
   7560 +        l =~ /^([^:]*): (.*)$/ or raise "can't parse #{fn} line #{l.inspect}"
   7561 +        @searches[$1] = $2
   7562 +      end
   7563 +    end
   7564 +    @modified = false
   7565 +  end
   7566 +
   7567 +  def all_searches; return @searches.keys.sort; end
   7568 +  def search_string_for name; return @searches[name]; end
   7569 +  def valid_name? name; name =~ /^[\w-]+$/; end
   7570 +  def name_format_hint; "letters, numbers, underscores and dashes only"; end
   7571 +
   7572 +  def add name, search_string
   7573 +    return unless valid_name? name
   7574 +    @searches[name] = search_string
   7575 +    @modified = true
   7576 +  end
   7577 +
   7578 +  def rename old, new
   7579 +    return unless @searches.has_key? old
   7580 +    search_string = @searches[old]
   7581 +    delete old if add new, search_string
   7582 +  end
   7583 +
   7584 +  def edit name, search_string
   7585 +    return unless @searches.has_key? name
   7586 +    @searches[name] = search_string
   7587 +    @modified = true
   7588 +  end
   7589 +
   7590 +  def delete name
   7591 +    return unless @searches.has_key? name
   7592 +    @searches.delete name
   7593 +    @modified = true
   7594 +  end
   7595 +
   7596 +  def expand search_string
   7597 +    expanded = search_string.dup
   7598 +    until (matches = expanded.scan(/\{([\w-]+)\}/).flatten).empty?
   7599 +      if !(unknown = matches - @searches.keys).empty?
   7600 +        error_message = "Unknown \"#{unknown.join('", "')}\" when expanding \"#{search_string}\""
   7601 +      elsif expanded.size >= 2048
   7602 +        error_message = "Check for infinite recursion in \"#{search_string}\""
   7603 +      end
   7604 +      if error_message
   7605 +        warn error_message
   7606 +        BufferManager.flash error_message
   7607 +        return false
   7608 +      end
   7609 +      matches.each { |n| expanded.gsub! "{#{n}}", "(#{@searches[n]})" if @searches.has_key? n }
   7610 +    end
   7611 +    return expanded
   7612 +  end
   7613 +
   7614 +  def save
   7615 +    return unless @modified
   7616 +    File.open(@fn, "w") { |f| @searches.sort.each { |(n, s)| f.puts "#{n}: #{s}" } }
   7617 +    @modified = false
   7618 +  end
   7619 +end
   7620 +
   7621 +end
   7622 -- 
   7623 1.6.6
   7624 
   7625 From rlane@club.cc.cmu.edu  Wed Jan 20 01:14:46 2010
   7626 From: rlane@club.cc.cmu.edu (Rich Lane)
   7627 Date: Wed, 20 Jan 2010 01:14:46 -0500
   7628 Subject: [sup-devel] [PATCHv2] Saved Search Support
   7629 In-Reply-To: <1263959248-sup-4163@changeling.local>
   7630 References: <1263858172-sup-547@changeling.local>
   7631 	<1263920054-sup-9400@zyrg.net>
   7632 	<1263959248-sup-4163@changeling.local>
   7633 Message-ID: <1263960767-sup-4706@zyrg.net>
   7634 
   7635 Excerpts from Eric Sherman's message of 2010-01-19 22:48:50 -0500:
   7636 > There is no nesting limit and searches are always expanded completely
   7637 > before they are turned into proper queries for the index.
   7638 
   7639 What do you think about doing the expansion in Index.parse_query, right
   7640 after the custom-search hook? That would save you from keeping track of
   7641 the unexpanded text. Otherwise this patch looks good to me.
   7642 
   7643 From aluink@gmail.com  Tue Jan 19 15:04:02 2010
   7644 From: aluink@gmail.com (Eric Polino)
   7645 Date: Tue, 19 Jan 2010 15:04:02 -0500
   7646 Subject: [sup-devel] Problems Syncing
   7647 Message-ID: <1263931111-sup-1739@europa>
   7648 
   7649 I'm trying to sync my local repository to my AllMail folder in GMail.  All works fine until it reaches a given point.  I'm guessing there's some message somewhere that's causing a problem, but I have no idea what to do about it, nor how to find this message.  Here's what happens when I run sup-sync.  I'm not sure what other information you'll need to help you find this problem, so let me know what you need and I'll do my best to get it to you.
   7650 
   7651 I did find a place that was saying that getting the lastest version of sup from the git repository could fix this problem...it didn't.
   7652 
   7653 TIA!
   7654 
   7655 
   7656 $ sup -v
   7657 sup v0.9.1
   7658 
   7659 $ cat ~/.sup/sources.yaml
   7660 ---
   7661 - !masanjin.net,2006-10-01/Redwood/IMAP
   7662   uri: imaps://imap.gmail.com/INBOX
   7663   username: me
   7664   password: secret
   7665   cur_offset: 12635776080006406
   7666   usual: true
   7667   archived: false
   7668   id: 1
   7669   labels:
   7670   - inbox
   7671 - !masanjin.net,2006-10-01/Redwood/IMAP
   7672   uri: imaps://imap.gmail.com/%5BGmail%5D%2FAll+Mail
   7673   username: me
   7674   password: secret
   7675   cur_offset: 11622394250003302
   7676   usual: true
   7677   archived: false
   7678   id: 2
   7679   labels: []
   7680 
   7681 - !masanjin.net,2006-10-01/Redwood/DraftLoader
   7682   cur_offset: 0
   7683 - !masanjin.net,2006-10-01/Redwood/SentLoader
   7684   cur_offset: 10325
   7685 
   7686 $ cat ~/.sup/config.yaml
   7687 ---
   7688 :thread_by_subject: false
   7689 :confirm_no_attachments: true
   7690 :edit_signature: false
   7691 :editor: /usr/bin/vim -f -c 'setlocal spell spelllang=en_us' -c 'set filetype=mail'
   7692 :confirm_top_posting: true
   7693 :accounts:
   7694   :default:
   7695     :signature: /home/aluink/.signature
   7696     :email: me at gmail.com
   7697     :name: Eric Polino
   7698     :alternates: []
   7699 
   7700     :sendmail: msmtp --account=gmail -t
   7701 :ask_for_to: true
   7702 :sent_source: sup://sent
   7703 :discard_snippets_from_encrypted_messages: false
   7704 :ask_for_cc: true
   7705 :default_attachment_save_dir: ""
   7706 :ask_for_bcc: false
   7707 :ask_for_subject: true
   7708 
   7709 
   7710 
   7711 ## read 6085m (about 28%) @ 2.3m/s. 0:43:49 elapsed, about 1:52:15 remaining
   7712 ## read 6112m (about 28%) @ 2.3m/s. 0:44:04 elapsed, about 1:52:32 remaining
   7713 ## read 6150m (about 28%) @ 2.3m/s. 0:44:20 elapsed, about 1:52:38 remaining
   7714 ## read 6188m (about 28%) @ 2.3m/s. 0:44:35 elapsed, about 1:52:45 remaining
   7715 ## read 6202m (about 28%) @ 2.3m/s. 0:44:53 elapsed, about 1:53:19 remaining
   7716 ## read 6244m (about 28%) @ 2.3m/s. 0:45:09 elapsed, about 1:53:23 remaining
   7717 ## read 6284m (about 29%) @ 2.3m/s. 0:45:24 elapsed, about 1:53:28 remaining
   7718 ## read 6323m (about 29%) @ 2.3m/s. 0:45:39 elapsed, about 1:53:33 remaining
   7719 ## read 6362m (about 29%) @ 2.3m/s. 0:45:54 elapsed, about 1:53:38 remaining
   7720 [Tue Jan 19 14:03:31 -0500 2010] WARNING: problem getting messages from imaps://imap.gmail.com/%5BGmail%5D%2FAll+Mail: While communicating with IMAP server (type Net::IMAP::NoResponseError): "Some messages could not be FETCHed (Failure)"
   7721 /home/aluink/.gem/ruby/1.8/gems/ferret-0.11.6/lib/ferret/index.rb:421:in `[]': :(null) isn't a valid argument for IndexReader.get_document(index) (ArgumentError)
   7722         from /home/aluink/.gem/ruby/1.8/gems/ferret-0.11.6/lib/ferret/index.rb:421:in `[]'
   7723         from /usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
   7724         from /home/aluink/.gem/ruby/1.8/gems/ferret-0.11.6/lib/ferret/index.rb:413:in `[]'
   7725         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/ferret_index.rb:257:in `build_message'
   7726         from /usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
   7727         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/ferret_index.rb:256:in `build_message'
   7728         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/bin/sup-sync:149
   7729         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/poll.rb:154:in `each_message_from'
   7730         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/imap.rb:197:in `each'
   7731         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/imap.rb:185:in `upto'
   7732         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/imap.rb:185:in `each'
   7733         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/util.rb:560:in `send'
   7734         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/util.rb:560:in `__pass'
   7735         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/util.rb:547:in `method_missing'
   7736         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/poll.rb:142:in `each_message_from'
   7737         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/util.rb:520:in `send'
   7738         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/lib/sup/util.rb:520:in `method_missing'
   7739         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/bin/sup-sync:146
   7740         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/bin/sup-sync:141:in `each'
   7741         from /home/aluink/.gem/ruby/1.8/gems/sup-0.9.1/bin/sup-sync:141
   7742         from /home/aluink/.gem/ruby/1.8/bin/sup-sync:19:in `load'
   7743         from /home/aluink/.gem/ruby/1.8/bin/sup-sync:19
   7744 
   7745 
   7746 
   7747 From hyperbolist@gmail.com  Wed Jan 20 09:25:57 2010
   7748 From: hyperbolist@gmail.com (Eric Sherman)
   7749 Date: Wed, 20 Jan 2010 09:25:57 -0500
   7750 Subject: [sup-devel] [PATCHv2] Saved Search Support
   7751 In-Reply-To: <1263960767-sup-4706@zyrg.net>
   7752 References: <1263858172-sup-547@changeling.local>
   7753 	<1263920054-sup-9400@zyrg.net>
   7754 	<1263959248-sup-4163@changeling.local>
   7755 	<1263960767-sup-4706@zyrg.net>
   7756 Message-ID: <1263997033-sup-7590@changeling.local>
   7757 
   7758 Excerpts from Rich Lane's message of Wed Jan 20 01:14:46 -0500 2010:
   7759 > What do you think about doing the expansion in Index.parse_query, right
   7760 > after the custom-search hook? That would save you from keeping track of
   7761 > the unexpanded text. Otherwise this patch looks good to me.
   7762 
   7763 Works for me.  I hadn't even considered it, thinking the index is sacred 
   7764 code.
   7765 
   7766 Another side-effect of making this change is ParseErrors are now gracefully 
   7767 handled in search-list-mode where before they would have crashed sup 
   7768 because I wasn't thinking.
   7769 
   7770 Instead of returning false and flashing like in the previous patch, 
   7771 SearchManager#expand raises an ExpansionError, which parse_query re-raises 
   7772 as a ParseError.
   7773 
   7774 From hyperbolist@gmail.com  Wed Jan 20 09:28:39 2010
   7775 From: hyperbolist@gmail.com (Eric Sherman)
   7776 Date: Wed, 20 Jan 2010 09:28:39 -0500
   7777 Subject: [sup-devel] [PATCHv3] Saved Search Support
   7778 In-Reply-To: <1263960767-sup-4706@zyrg.net>
   7779 References: <1263858172-sup-547@changeling.local>
   7780 	<1263920054-sup-9400@zyrg.net>
   7781 	<1263959248-sup-4163@changeling.local>
   7782 	<1263960767-sup-4706@zyrg.net>
   7783 Message-ID: <1263997604-sup-9969@changeling.local>
   7784 
   7785 Start an index search with a \ backslash and press enter to get a list
   7786 of searches that were previously saved from search-results-mode with %
   7787 percent or added from search-list-mode directly.  Saved searches may be
   7788 used in other searches by enclosing their names in {} curly braces.
   7789 Search names may contain letters, numbers, underscores and dashes.
   7790 
   7791 New Key Bindings
   7792 global
   7793   \<CR> open search-list-mode
   7794 search-list-mode
   7795   X     Delete selected search
   7796   r     Rename selected search
   7797   e     Edit selected search
   7798   a     Add new search
   7799 search-results-mode
   7800   %     Save search
   7801 
   7802 New Hooks
   7803 search-list-filter
   7804 search-list-format
   7805 
   7806 Search String Expansion
   7807 Include saved searches in other searches by enclosing their names in {}
   7808 curly braces.  The name and enclosing braces are replaced by the actual
   7809 search string and enclosing () parens.
   7810 
   7811     low_traffic: has:foo OR has:bar
   7812     a_slow_week: {low_traffic} AND after:(7 days ago)
   7813 
   7814 {a_slow_week} expands to "(has:foo OR has:bar) AND after:(7 days ago)"
   7815 and may be used in a global search, a refinement or another saved
   7816 search.  A search including the undefined {baz} will fail. To search for
   7817 a literal string enclosed in curly braces, escape the curly braces with
   7818 \ backslash: "\{baz\}".
   7819 
   7820 There is no nesting limit.
   7821 
   7822 Save File Format
   7823 Searches are read from ~/.sup/searches.txt on startup and saved at exit.
   7824 The format is "name: search_string".  Here's a silly example:
   7825 
   7826     core: {me} AND NOT {crap} AND NOT {weak}
   7827     crap: is:leadlogger OR is:alert OR is:rzp
   7828     me: to:me OR from:me
   7829     recent: after:(14 days ago)
   7830     top: {core} AND {recent}
   7831     weak: is:feed OR is:list OR is:ham
   7832 ---
   7833  bin/sup                              |   11 ++-
   7834  lib/sup.rb                           |    5 +
   7835  lib/sup/modes/search-list-mode.rb    |  188 ++++++++++++++++++++++++++++++++++
   7836  lib/sup/modes/search-results-mode.rb |   16 +++
   7837  lib/sup/search.rb                    |   73 +++++++++++++
   7838  lib/sup/xapian_index.rb              |    5 +
   7839  6 files changed, 295 insertions(+), 3 deletions(-)
   7840  create mode 100644 lib/sup/modes/search-list-mode.rb
   7841  create mode 100644 lib/sup/search.rb
   7842 
   7843 diff --git a/bin/sup b/bin/sup
   7844 index 8bf640b..fb19795 100755
   7845 --- a/bin/sup
   7846 +++ b/bin/sup
   7847 @@ -303,9 +303,14 @@ begin
   7848        b, new = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
   7849        b.mode.load_in_background if new
   7850      when :search
   7851 -      query = BufferManager.ask :search, "search all messages: "
   7852 -      next unless query && query !~ /^\s*$/
   7853 -      SearchResultsMode.spawn_from_query query
   7854 +      query = BufferManager.ask :search, "Search all messages (enter for saved searches): "
   7855 +      unless query.nil?
   7856 +        if query.empty?
   7857 +          bm.spawn_unless_exists("Saved searches") { SearchListMode.new }
   7858 +        else
   7859 +          SearchResultsMode.spawn_from_query query
   7860 +        end
   7861 +      end
   7862      when :search_unread
   7863        SearchResultsMode.spawn_from_query "is:unread"
   7864      when :list_labels
   7865 diff --git a/lib/sup.rb b/lib/sup.rb
   7866 index e03a35d..b9dc749 100644
   7867 --- a/lib/sup.rb
   7868 +++ b/lib/sup.rb
   7869 @@ -50,6 +50,7 @@ module Redwood
   7870    LOCK_FN    = File.join(BASE_DIR, "lock")
   7871    SUICIDE_FN = File.join(BASE_DIR, "please-kill-yourself")
   7872    HOOK_DIR   = File.join(BASE_DIR, "hooks")
   7873 +  SEARCH_FN  = File.join(BASE_DIR, "searches.txt")
   7874  
   7875    YAML_DOMAIN = "masanjin.net"
   7876    YAML_DATE = "2006-10-01"
   7877 @@ -131,12 +132,14 @@ module Redwood
   7878      Redwood::CryptoManager.init
   7879      Redwood::UndoManager.init
   7880      Redwood::SourceManager.init
   7881 +    Redwood::SearchManager.init Redwood::SEARCH_FN
   7882    end
   7883  
   7884    def finish
   7885      Redwood::LabelManager.save if Redwood::LabelManager.instantiated?
   7886      Redwood::ContactManager.save if Redwood::ContactManager.instantiated?
   7887      Redwood::BufferManager.deinstantiate! if Redwood::BufferManager.instantiated?
   7888 +    Redwood::SearchManager.save if Redwood::SearchManager.instantiated?
   7889    end
   7890  
   7891    ## not really a good place for this, so I'll just dump it here.
   7892 @@ -341,6 +344,8 @@ require "sup/modes/file-browser-mode"
   7893  require "sup/modes/completion-mode"
   7894  require "sup/modes/console-mode"
   7895  require "sup/sent"
   7896 +require "sup/search"
   7897 +require "sup/modes/search-list-mode"
   7898  
   7899  $:.each do |base|
   7900    d = File.join base, "sup/share/modes/"
   7901 diff --git a/lib/sup/modes/search-list-mode.rb b/lib/sup/modes/search-list-mode.rb
   7902 new file mode 100644
   7903 index 0000000..8f73659
   7904 --- /dev/null
   7905 +++ b/lib/sup/modes/search-list-mode.rb
   7906 @@ -0,0 +1,188 @@
   7907 +module Redwood
   7908 +
   7909 +class SearchListMode < LineCursorMode
   7910 +  register_keymap do |k|
   7911 +    k.add :select_search, "Open search results", :enter
   7912 +    k.add :reload, "Discard saved search list and reload", '@'
   7913 +    k.add :jump_to_next_new, "Jump to next new thread", :tab
   7914 +    k.add :toggle_show_unread_only, "Toggle between showing all saved searches and those with unread mail", 'u'
   7915 +    k.add :delete_selected_search, "Delete selected search", "X"
   7916 +    k.add :rename_selected_search, "Rename selected search", "r"
   7917 +    k.add :edit_selected_search, "Edit selected search", "e"
   7918 +    k.add :add_new_search, "Add new search", "a"
   7919 +  end
   7920 +
   7921 +  HookManager.register "search-list-filter", <<EOS
   7922 +Filter the search list, typically to sort.
   7923 +Variables:
   7924 +  counted: an array of counted searches.
   7925 +Return value:
   7926 +  An array of counted searches with sort_by output structure.
   7927 +EOS
   7928 +
   7929 +  HookManager.register "search-list-format", <<EOS
   7930 +Create the sprintf format string for search-list-mode.
   7931 +Variables:
   7932 +  n_width: the maximum search name width
   7933 +  tmax: the maximum total message count
   7934 +  umax: the maximum unread message count
   7935 +  s_width: the maximum search string width
   7936 +Return value:
   7937 +  A format string for sprintf
   7938 +EOS
   7939 +
   7940 +  def initialize
   7941 +    @searches = []
   7942 +    @text = []
   7943 +    @unread_only = false
   7944 +    super
   7945 +    UpdateManager.register self
   7946 +    regen_text
   7947 +  end
   7948 +
   7949 +  def cleanup
   7950 +    UpdateManager.unregister self
   7951 +    super
   7952 +  end
   7953 +
   7954 +  def lines; @text.length end
   7955 +  def [] i; @text[i] end
   7956 +
   7957 +  def jump_to_next_new
   7958 +    n = ((curpos + 1) ... lines).find { |i| @searches[i][1] > 0 } || (0 ... curpos).find { |i| @searches[i][1] > 0 }
   7959 +    if n
   7960 +      ## jump there if necessary
   7961 +      jump_to_line n unless n >= topline && n < botline
   7962 +      set_cursor_pos n
   7963 +    else
   7964 +      BufferManager.flash "No saved searches with unread messages."
   7965 +    end
   7966 +  end
   7967 +
   7968 +  def focus
   7969 +    reload # make sure unread message counts are up-to-date
   7970 +  end
   7971 +
   7972 +  def handle_added_update sender, m
   7973 +    reload
   7974 +  end
   7975 +
   7976 +protected
   7977 +
   7978 +  def toggle_show_unread_only
   7979 +    @unread_only = !@unread_only
   7980 +    reload
   7981 +  end
   7982 +
   7983 +  def reload
   7984 +    regen_text
   7985 +    buffer.mark_dirty if buffer
   7986 +  end
   7987 +
   7988 +  def regen_text
   7989 +    @text = []
   7990 +    searches = SearchManager.all_searches
   7991 +
   7992 +    counted = searches.map do |name|
   7993 +      search_string = SearchManager.search_string_for name
   7994 +      begin
   7995 +        query = Index.parse_query search_string
   7996 +        total = Index.num_results_for :qobj => query[:qobj]
   7997 +        unread = Index.num_results_for :qobj => query[:qobj], :label => :unread
   7998 +      rescue Index::ParseError => e
   7999 +        BufferManager.flash "Problem: #{e.message}!"
   8000 +        total = 0
   8001 +        unread = 0
   8002 +      end
   8003 +      [name, search_string, total, unread]
   8004 +    end
   8005 +
   8006 +    if HookManager.enabled? "search-list-filter"
   8007 +      counts = HookManager.run "search-list-filter", :counted => counted
   8008 +    else
   8009 +      counts = counted.sort_by { |n, s, t, u| n.downcase }
   8010 +    end
   8011 +
   8012 +    n_width = counts.max_of { |n, s, t, u| n.length }
   8013 +    tmax    = counts.max_of { |n, s, t, u| t }
   8014 +    umax    = counts.max_of { |n, s, t, u| u }
   8015 +    s_width = counts.max_of { |n, s, t, u| s.length }
   8016 +
   8017 +    if @unread_only
   8018 +      counts.delete_if { | n, s, t, u | u == 0 }
   8019 +    end
   8020 +
   8021 +    @searches = []
   8022 +    counts.each do |name, search_string, total, unread|
   8023 +      fmt = HookManager.run "search-list-format", :n_width => n_width, :tmax => tmax, :umax => umax, :s_width => s_width
   8024 +      if !fmt
   8025 +        fmt = "%#{n_width + 1}s %5d %s, %5d unread: %s"
   8026 +      end
   8027 +      @text << [[(unread == 0 ? :labellist_old_color : :labellist_new_color),
   8028 +          sprintf(fmt, name, total, total == 1 ? " message" : "messages", unread, search_string)]]
   8029 +      @searches << [name, unread]
   8030 +    end
   8031 +
   8032 +    BufferManager.flash "No saved searches with unread messages!" if counts.empty? && @unread_only
   8033 +  end
   8034 +
   8035 +  def select_search
   8036 +    name, num_unread = @searches[curpos]
   8037 +    return unless name
   8038 +    SearchResultsMode.spawn_from_query SearchManager.search_string_for(name)
   8039 +  end
   8040 +
   8041 +  def delete_selected_search
   8042 +    name, num_unread = @searches[curpos]
   8043 +    return unless name
   8044 +    reload if SearchManager.delete name
   8045 +  end
   8046 +
   8047 +  def rename_selected_search
   8048 +    old_name, num_unread = @searches[curpos]
   8049 +    return unless old_name
   8050 +    new_name = BufferManager.ask :save_search, "Rename this saved search: ", old_name
   8051 +    return unless new_name && new_name !~ /^\s*$/ && new_name != old_name
   8052 +    new_name.strip!
   8053 +    unless SearchManager.valid_name? new_name
   8054 +      BufferManager.flash "Not renamed: " + SearchManager.name_format_hint
   8055 +      return
   8056 +    end
   8057 +    if SearchManager.all_searches.include? new_name
   8058 +      BufferManager.flash "Not renamed: \"#{new_name}\" already exists"
   8059 +      return
   8060 +    end
   8061 +    reload if SearchManager.rename old_name, new_name
   8062 +    set_cursor_pos @searches.index([new_name, num_unread])||curpos
   8063 +  end
   8064 +
   8065 +  def edit_selected_search
   8066 +    name, num_unread = @searches[curpos]
   8067 +    return unless name
   8068 +    old_search_string = SearchManager.search_string_for name
   8069 +    new_search_string = BufferManager.ask :search, "Edit this saved search: ", (old_search_string + " ")
   8070 +    return unless new_search_string && new_search_string !~ /^\s*$/ && new_search_string != old_search_string
   8071 +    reload if SearchManager.edit name, new_search_string.strip
   8072 +    set_cursor_pos @searches.index([name, num_unread])||curpos
   8073 +  end
   8074 +
   8075 +  def add_new_search
   8076 +    search_string = BufferManager.ask :search, "New search: "
   8077 +    return unless search_string && search_string !~ /^\s*$/
   8078 +    name = BufferManager.ask :save_search, "Name this search: "
   8079 +    return unless name && name !~ /^\s*$/
   8080 +    name.strip!
   8081 +    unless SearchManager.valid_name? name
   8082 +      BufferManager.flash "Not saved: " + SearchManager.name_format_hint
   8083 +      return
   8084 +    end
   8085 +    if SearchManager.all_searches.include? name
   8086 +      BufferManager.flash "Not saved: \"#{name}\" already exists"
   8087 +      return
   8088 +    end
   8089 +    reload if SearchManager.add name, search_string.strip
   8090 +    set_cursor_pos @searches.index(@searches.assoc(name))||curpos
   8091 +  end
   8092 +end
   8093 +
   8094 +end
   8095 diff --git a/lib/sup/modes/search-results-mode.rb b/lib/sup/modes/search-results-mode.rb
   8096 index 121e817..5b529a8 100644
   8097 --- a/lib/sup/modes/search-results-mode.rb
   8098 +++ b/lib/sup/modes/search-results-mode.rb
   8099 @@ -8,6 +8,7 @@ class SearchResultsMode < ThreadIndexMode
   8100  
   8101    register_keymap do |k|
   8102      k.add :refine_search, "Refine search", '|'
   8103 +    k.add :save_search, "Save search", '%'
   8104    end
   8105  
   8106    def refine_search
   8107 @@ -16,6 +17,21 @@ class SearchResultsMode < ThreadIndexMode
   8108      SearchResultsMode.spawn_from_query text
   8109    end
   8110  
   8111 +  def save_search
   8112 +    name = BufferManager.ask :save_search, "Name this search: "
   8113 +    return unless name && name !~ /^\s*$/
   8114 +    name.strip!
   8115 +    unless SearchManager.valid_name? name
   8116 +      BufferManager.flash "Not saved: " + SearchManager.name_format_hint
   8117 +      return
   8118 +    end
   8119 +    if SearchManager.all_searches.include? name
   8120 +      BufferManager.flash "Not saved: \"#{name}\" already exists"
   8121 +      return
   8122 +    end
   8123 +    BufferManager.flash "Search saved as \"#{name}\"" if SearchManager.add name, @query[:text].strip
   8124 +  end
   8125 +
   8126    ## a proper is_relevant? method requires some way of asking ferret
   8127    ## if an in-memory object satisfies a query. i'm not sure how to do
   8128    ## that yet. in the worst case i can make an in-memory index, add
   8129 diff --git a/lib/sup/search.rb b/lib/sup/search.rb
   8130 new file mode 100644
   8131 index 0000000..0c63b06
   8132 --- /dev/null
   8133 +++ b/lib/sup/search.rb
   8134 @@ -0,0 +1,73 @@
   8135 +module Redwood
   8136 +
   8137 +class SearchManager
   8138 +  include Singleton
   8139 +
   8140 +  class ExpansionError < StandardError; end
   8141 +
   8142 +  def initialize fn
   8143 +    @fn = fn
   8144 +    @searches = {}
   8145 +    if File.exists? fn
   8146 +      IO.foreach(fn) do |l|
   8147 +        l =~ /^([^:]*): (.*)$/ or raise "can't parse #{fn} line #{l.inspect}"
   8148 +        @searches[$1] = $2
   8149 +      end
   8150 +    end
   8151 +    @modified = false
   8152 +  end
   8153 +
   8154 +  def all_searches; return @searches.keys.sort; end
   8155 +  def search_string_for name; return @searches[name]; end
   8156 +  def valid_name? name; name =~ /^[\w-]+$/; end
   8157 +  def name_format_hint; "letters, numbers, underscores and dashes only"; end
   8158 +
   8159 +  def add name, search_string
   8160 +    return unless valid_name? name
   8161 +    @searches[name] = search_string
   8162 +    @modified = true
   8163 +  end
   8164 +
   8165 +  def rename old, new
   8166 +    return unless @searches.has_key? old
   8167 +    search_string = @searches[old]
   8168 +    delete old if add new, search_string
   8169 +  end
   8170 +
   8171 +  def edit name, search_string
   8172 +    return unless @searches.has_key? name
   8173 +    @searches[name] = search_string
   8174 +    @modified = true
   8175 +  end
   8176 +
   8177 +  def delete name
   8178 +    return unless @searches.has_key? name
   8179 +    @searches.delete name
   8180 +    @modified = true
   8181 +  end
   8182 +
   8183 +  def expand search_string
   8184 +    expanded = search_string.dup
   8185 +    until (matches = expanded.scan(/\{([\w-]+)\}/).flatten).empty?
   8186 +      if !(unknown = matches - @searches.keys).empty?
   8187 +        error_message = "Unknown \"#{unknown.join('", "')}\" when expanding \"#{search_string}\""
   8188 +      elsif expanded.size >= 2048
   8189 +        error_message = "Check for infinite recursion in \"#{search_string}\""
   8190 +      end
   8191 +      if error_message
   8192 +        warn error_message
   8193 +        raise ExpansionError, error_message
   8194 +      end
   8195 +      matches.each { |n| expanded.gsub! "{#{n}}", "(#{@searches[n]})" if @searches.has_key? n }
   8196 +    end
   8197 +    return expanded
   8198 +  end
   8199 +
   8200 +  def save
   8201 +    return unless @modified
   8202 +    File.open(@fn, "w") { |f| @searches.sort.each { |(n, s)| f.puts "#{n}: #{s}" } }
   8203 +    @modified = false
   8204 +  end
   8205 +end
   8206 +
   8207 +end
   8208 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   8209 index 8f29faf..37f9b4a 100644
   8210 --- a/lib/sup/xapian_index.rb
   8211 +++ b/lib/sup/xapian_index.rb
   8212 @@ -162,6 +162,11 @@ EOS
   8213      query = {}
   8214  
   8215      subs = HookManager.run("custom-search", :subs => s) || s
   8216 +    begin
   8217 +      subs = SearchManager.expand subs
   8218 +    rescue SearchManager::ExpansionError => e
   8219 +      raise ParseError, e.message
   8220 +    end
   8221      subs = subs.gsub(/\b(to|from):(\S+)\b/) do
   8222        field, value = $1, $2
   8223        email_field, name_field = %w(email name).map { |x| "#{field}_#{x}" }
   8224 -- 
   8225 1.6.6
   8226 
   8227 From wmorgan-sup@masanjin.net  Wed Jan 20 11:28:23 2010
   8228 From: wmorgan-sup@masanjin.net (William Morgan)
   8229 Date: Wed, 20 Jan 2010 11:28:23 -0500
   8230 Subject: [sup-devel] [PATCHv2] [issue44] cursor sticks to thread
   8231 In-Reply-To: <1263328554-sup-8440@changeling.local>
   8232 References: <1263328554-sup-8440@changeling.local>
   8233 Message-ID: <1264004891-sup-9766@masanjin.net>
   8234 
   8235 Reformatted excerpts from Eric Sherman's message of 2010-01-12:
   8236 > This is much more concise version, using set_cursor_pos instead of 
   8237 > cursor_up and cursor_down.
   8238 
   8239 Applied directly to master. Thanks!
   8240 -- 
   8241 William <wmorgan-sup at masanjin.net>
   8242 
   8243 From wmorgan-sup@masanjin.net  Wed Jan 20 11:30:37 2010
   8244 From: wmorgan-sup@masanjin.net (William Morgan)
   8245 Date: Wed, 20 Jan 2010 11:30:37 -0500
   8246 Subject: [sup-devel] merged into master: ruby-1.9-encoding, insta-save,
   8247 	xapian-name-email
   8248 Message-ID: <1264005023-sup-9722@masanjin.net>
   8249 
   8250 All merged in, to go out in 0.10.
   8251 -- 
   8252 William <wmorgan-sup at masanjin.net>
   8253 
   8254 From michael+sup@stapelberg.de  Wed Jan 20 17:30:11 2010
   8255 From: michael+sup@stapelberg.de (Michael Stapelberg)
   8256 Date: Wed, 20 Jan 2010 23:30:11 +0100
   8257 Subject: [sup-devel] [PATCH] Use multiple body arrays when calling
   8258 	before-edit for each reply type
   8259 Message-ID: <1264026370-sup-8092@midna.zekjur.net>
   8260 
   8261 Hi,
   8262 
   8263 I created a hook which modified the body of each new message to look like my
   8264 usual skeleton for mails (greeting, content, signature). I did not use the
   8265 signature function for that because I wanted to put in the greeting with the
   8266 correct recipient.
   8267 
   8268 Now I wanted to make this even more comfortable for me by checking if the
   8269 recipient of my mail is speaking english and thus using the english signature
   8270 instead of the german one. This was possible to a certain degree, but failed
   8271 when I wanted to see if any of the CC'ed addresses matched a certain pattern.
   8272 
   8273 Attached to this mail you can find a patch which will copy the body object
   8274 for each type of headers (sender, recipient, all, list) and use the right
   8275 version of it in each case (like for the headers).
   8276 
   8277 I am not completely suure if the patch is 100% correct, so please review it
   8278 thoroughly. It works for me, though.
   8279 
   8280 Best regards,
   8281 Michael
   8282 -------------- next part --------------
   8283 A non-text attachment was scrubbed...
   8284 Name: 0001-Use-multiple-body-arrays-when-calling-before-edit-fo.patch
   8285 Type: application/octet-stream
   8286 Size: 1777 bytes
   8287 Desc: not available
   8288 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100120/27f07579/attachment.obj>
   8289 
   8290 From hyperbolist@gmail.com  Wed Jan 20 23:15:16 2010
   8291 From: hyperbolist@gmail.com (Eric Sherman)
   8292 Date: Wed, 20 Jan 2010 23:15:16 -0500
   8293 Subject: [sup-devel] [PATCH] flush index on idle
   8294 Message-ID: <1264047274-sup-6830@changeling.local>
   8295 
   8296 This patch depends on [PATCHv2] idle and unidle updates.
   8297 ---
   8298  lib/sup/modes/inbox-mode.rb |    4 ++++
   8299  1 files changed, 4 insertions(+), 0 deletions(-)
   8300 
   8301 diff --git a/lib/sup/modes/inbox-mode.rb b/lib/sup/modes/inbox-mode.rb
   8302 index 1b8eaed..9e37909 100644
   8303 --- a/lib/sup/modes/inbox-mode.rb
   8304 +++ b/lib/sup/modes/inbox-mode.rb
   8305 @@ -115,6 +115,10 @@ class InboxMode < ThreadIndexMode
   8306      regen_text
   8307    end
   8308  
   8309 +  def handle_idle_update sender, idle_since
   8310 +    flush_index
   8311 +  end
   8312 +
   8313    def status
   8314      super + "    #{Index.size} messages in index"
   8315    end
   8316 -- 
   8317 1.6.6
   8318 
   8319 
   8320 From hyperbolist@gmail.com  Thu Jan 21 10:36:28 2010
   8321 From: hyperbolist@gmail.com (Eric Sherman)
   8322 Date: Thu, 21 Jan 2010 10:36:28 -0500
   8323 Subject: [sup-devel] [PATCH] show (recipients) instead of lone "me"
   8324 Message-ID: <1264087996-sup-5125@changeling.local>
   8325 
   8326 I've changed thread-index-mode to show recipients in () parens instead
   8327 of "me" in the From field for threads from me with no replies.
   8328 
   8329 I've developed the habit of archiving a new thread as soon as I send it,
   8330 so until I receive a reply it's effectively non-existent.  When checking
   8331 on emails I may want to follow up on with a search like "is:sent AND
   8332 after:(14 days ago) AND before:(3 days ago)" I would get a pile of lone
   8333 "me"'s in the From field.  I would then open each of them to decide
   8334 whether or not to follow up based on who it was sent to.
   8335 
   8336 So this helps me cut down on the j<CR>x loops in that scenario.
   8337 
   8338 I'm not sure if this is something that is universally desirable, but
   8339 here's the patch anyway.
   8340 ---
   8341  lib/sup/modes/thread-index-mode.rb |   10 ++++++++++
   8342  1 files changed, 10 insertions(+), 0 deletions(-)
   8343 
   8344 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   8345 index a6bb2b9..0774aa8 100644
   8346 --- a/lib/sup/modes/thread-index-mode.rb
   8347 +++ b/lib/sup/modes/thread-index-mode.rb
   8348 @@ -793,6 +793,16 @@ protected
   8349        result << [name, new[a]]
   8350      end
   8351  
   8352 +    if result.size == 1 && (author_and_newness = result.assoc("me"))
   8353 +      unless (recipients = t.participants - t.authors).empty?
   8354 +        result = recipients.collect do |r|
   8355 +          break if limit && result.size >= limit
   8356 +          name = (recipients.size == 1) ? r.mediumname : r.shortname
   8357 +          ["(#{name})", author_and_newness[1]]
   8358 +        end
   8359 +      end
   8360 +    end
   8361 +
   8362      result
   8363    end
   8364  
   8365 -- 
   8366 1.6.6
   8367 
   8368 
   8369 From tero@tilus.net  Thu Jan 21 16:34:57 2010
   8370 From: tero@tilus.net (Tero Tilus)
   8371 Date: Thu, 21 Jan 2010 23:34:57 +0200
   8372 Subject: [sup-devel] [PATCH] show (recipients) instead of lone "me"
   8373 In-Reply-To: <1264087996-sup-5125@changeling.local>
   8374 References: <1264087996-sup-5125@changeling.local>
   8375 Message-ID: <1264109598-sup-3164@tilus.net>
   8376 
   8377 Eric Sherman, 2010-01-21 17:36:
   8378 > I've changed thread-index-mode to show recipients in () parens
   8379 > instead of "me" in the From field for threads from me with no
   8380 > replies.
   8381 
   8382 +1
   8383 
   8384 Patched my daily-sup right away.  I'd like to see this in mainline.
   8385 
   8386 -- 
   8387 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
   8388 
   8389 From tero@tilus.net  Thu Jan 21 18:51:05 2010
   8390 From: tero@tilus.net (Tero Tilus)
   8391 Date: Fri, 22 Jan 2010 01:51:05 +0200
   8392 Subject: [sup-devel] [PATCH] Message#edit_labels [was: Ruby question:
   8393 	before-add-message.rb and adding multiple labels at once]
   8394 In-Reply-To: <1263680819-sup-415@tilus.net>
   8395 References: <1263574849-sup-3477@sam.mediasupervision.de>
   8396 	<1263680819-sup-415@tilus.net>
   8397 Message-ID: <1264117436-sup-4429@tilus.net>
   8398 
   8399 Tero Tilus, 2010-01-17 00:41:
   8400 > Gregor Hoffleit, 2010-01-15 19:01:
   8401 >> May I request a new function "message.edit_labels"
   8402 > 
   8403 > I'll be using that one too.  Here's a patch.
   8404 
   8405 Did this get merged?  I got no feedback.
   8406 
   8407 -- 
   8408 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
   8409 
   8410 From bwalton@artsci.utoronto.ca  Thu Jan 21 18:56:18 2010
   8411 From: bwalton@artsci.utoronto.ca (Ben Walton)
   8412 Date: Thu, 21 Jan 2010 18:56:18 -0500
   8413 Subject: [sup-devel] [PATCH] show (recipients) instead of lone "me"
   8414 In-Reply-To: <1264109598-sup-3164@tilus.net>
   8415 References: <1264087996-sup-5125@changeling.local>
   8416 	<1264109598-sup-3164@tilus.net>
   8417 Message-ID: <1264118145-sup-5806@ntdws12.chass.utoronto.ca>
   8418 
   8419 Excerpts from Tero Tilus's message of Thu Jan 21 16:34:57 -0500 2010:
   8420 
   8421 > Patched my daily-sup right away.  I'd like to see this in mainline.
   8422 
   8423 I didn't get a chance today, but I'd also give this a +1.  It makes a
   8424 good deal of sense.
   8425 
   8426 -Ben
   8427 
   8428 -- 
   8429 Ben Walton
   8430 Systems Programmer - CHASS
   8431 University of Toronto
   8432 C:416.407.5610 | W:416.978.4302
   8433 
   8434 GPG Key Id: 8E89F6D2; Key Server: pgp.mit.edu
   8435 Contact me to arrange for a CAcert assurance meeting.
   8436 -------------- next part --------------
   8437 A non-text attachment was scrubbed...
   8438 Name: signature.asc
   8439 Type: application/pgp-signature
   8440 Size: 189 bytes
   8441 Desc: not available
   8442 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100121/6903f056/attachment.bin>
   8443 
   8444 From tero@tilus.net  Thu Jan 21 20:32:00 2010
   8445 From: tero@tilus.net (Tero Tilus)
   8446 Date: Fri, 22 Jan 2010 03:32:00 +0200
   8447 Subject: [sup-devel] [PATCH] I can haz moar hooks: attachment-mentioned,
   8448 	index-mode-date-widget
   8449 In-Reply-To: <1261402666-sup-8068@masanjin.net>
   8450 References: <1261167840-sup-592@orion> <1261179239-sup-9258@tilus.net>
   8451 	<1261246334-sup-1438@masanjin.net> <1261276156-sup-5510@tilus.net>
   8452 	<1261402666-sup-8068@masanjin.net>
   8453 Message-ID: <1264123657-sup-4929@tilus.net>
   8454 
   8455 William Morgan, 2009-12-21 15:38:
   8456 > Reformatted excerpts from Tero Tilus's message of 2009-12-19:
   8457 > > The detect-missing-attachment hook is pretty self evident but what you
   8458 > > had in mind for the dates?  Formatter for the thread-index-mode date
   8459 > > widget maybe?
   8460 > 
   8461 > Exactly. We already have index-mode-size-widget, so
   8462 > index-mode-date-widget would be analogous.
   8463 
   8464 Here they are, finally...
   8465 
   8466 -- 
   8467 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
   8468 -------------- next part --------------
   8469 A non-text attachment was scrubbed...
   8470 Name: 0001-index-mode-date-widget-hook-for-rendering-dates-in-t.patch
   8471 Type: application/octet-stream
   8472 Size: 4070 bytes
   8473 Desc: not available
   8474 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100122/92580ae4/attachment-0002.obj>
   8475 -------------- next part --------------
   8476 A non-text attachment was scrubbed...
   8477 Name: 0001-mentions-attachments-hook-to-detect-missing-attachme.patch
   8478 Type: application/octet-stream
   8479 Size: 1269 bytes
   8480 Desc: not available
   8481 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100122/92580ae4/attachment-0003.obj>
   8482 
   8483 From rlane@club.cc.cmu.edu  Thu Jan 21 23:25:16 2010
   8484 From: rlane@club.cc.cmu.edu (Rich Lane)
   8485 Date: Thu, 21 Jan 2010 20:25:16 -0800
   8486 Subject: [sup-devel] [PATCH] copy thread when spawning ThreadViewMode
   8487 Message-ID: <1264134316-17210-1-git-send-email-rlane@club.cc.cmu.edu>
   8488 
   8489 Currently ThreadIndexMode just passes a reference to the selected thread when
   8490 spawning a ThreadViewMode. This is a problem because as long as the original
   8491 ThreadIndexMode is alive that thread will be updated with new messages, but
   8492 ThreadViewMode will not display them. This can lead to the user unknowingly
   8493 archiving a thread containing unread messages.
   8494 ---
   8495  lib/sup/modes/thread-index-mode.rb |   16 +++++++++++++---
   8496  1 files changed, 13 insertions(+), 3 deletions(-)
   8497 
   8498 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   8499 index a6bb2b9..ca5e1f3 100644
   8500 --- a/lib/sup/modes/thread-index-mode.rb
   8501 +++ b/lib/sup/modes/thread-index-mode.rb
   8502 @@ -94,6 +94,18 @@ EOS
   8503      load_threads :num => buffer.content_height
   8504    end
   8505  
   8506 +  def copy_thread t
   8507 +    ts = ThreadSet.new nil
   8508 +    t.each_with_index do |(m, *o), i|
   8509 +      next unless m
   8510 +      yield i
   8511 +      m.load_from_source!
   8512 +      ts.add_message m
   8513 +    end
   8514 +    fail unless ts.threads.size == 1
   8515 +    ts.threads.first
   8516 +  end
   8517 +
   8518    ## open up a thread view window
   8519    def select t=nil, when_done=nil
   8520      t ||= cursor_thread or return
   8521 @@ -102,10 +114,8 @@ EOS
   8522        num = t.size
   8523        message = "Loading #{num.pluralize 'message body'}..."
   8524        BufferManager.say(message) do |sid|
   8525 -        t.each_with_index do |(m, *o), i|
   8526 -          next unless m
   8527 +        t = copy_thread t do |i|
   8528            BufferManager.say "#{message} (#{i}/#{num})", sid if t.size > 1
   8529 -          m.load_from_source! 
   8530          end
   8531        end
   8532        mode = ThreadViewMode.new t, @hidden_labels, self
   8533 -- 
   8534 1.6.3.3
   8535 
   8536 
   8537 From rlane@club.cc.cmu.edu  Fri Jan 22 02:46:40 2010
   8538 From: rlane@club.cc.cmu.edu (Rich Lane)
   8539 Date: Thu, 21 Jan 2010 23:46:40 -0800
   8540 Subject: [sup-devel] [PATCH] fix textfield truncation
   8541 Message-ID: <1264146400-2101-1-git-send-email-rlane@club.cc.cmu.edu>
   8542 
   8543 Long query strings (for example) are (for some people) silently truncated.
   8544 Other people have seen large amounts of whitespace inserted at word boundaries.
   8545 These issues are caused by using a multiline text field. This patch uses a
   8546 single-line dynamically growable textfield instead. It also disables the
   8547 field-blanking misfeature.
   8548 ---
   8549  lib/sup/textfield.rb |    4 +++-
   8550  1 files changed, 3 insertions(+), 1 deletions(-)
   8551 
   8552 diff --git a/lib/sup/textfield.rb b/lib/sup/textfield.rb
   8553 index 9afeb34..1c19751 100644
   8554 --- a/lib/sup/textfield.rb
   8555 +++ b/lib/sup/textfield.rb
   8556 @@ -33,7 +33,9 @@ class TextField
   8557      @w, @y, @x, @width = window, y, x, width
   8558      @question = question
   8559      @completion_block = block
   8560 -    @field = Ncurses::Form.new_field 1, @width - question.length, @y, @x + question.length, 256, 0
   8561 +    @field = Ncurses::Form.new_field 1, @width - question.length, @y, @x + question.length, 0, 0
   8562 +    @field.opts_off Ncurses::Form::O_STATIC
   8563 +    @field.opts_off Ncurses::Form::O_BLANK
   8564      @form = Ncurses::Form.new_form [@field]
   8565      @value = default || ''
   8566      Ncurses::Form.post_form @form
   8567 -- 
   8568 1.6.3.3
   8569 
   8570 
   8571 From hyperbolist@gmail.com  Fri Jan 22 07:02:55 2010
   8572 From: hyperbolist@gmail.com (Eric Sherman)
   8573 Date: Fri, 22 Jan 2010 07:02:55 -0500
   8574 Subject: [sup-devel] [PATCH] fix textfield truncation
   8575 In-Reply-To: <1264146400-2101-1-git-send-email-rlane@club.cc.cmu.edu>
   8576 References: <1264146400-2101-1-git-send-email-rlane@club.cc.cmu.edu>
   8577 Message-ID: <1264161767-sup-920@changeling.local>
   8578 
   8579 This is awesome, thank you!
   8580 
   8581 Excerpts from Rich Lane's message of Fri Jan 22 02:46:40 -0500 2010:
   8582 > Long query strings (for example) are (for some people) silently truncated.
   8583 > Other people have seen large amounts of whitespace inserted at word boundaries.
   8584 > These issues are caused by using a multiline text field. This patch uses a
   8585 > single-line dynamically growable textfield instead. It also disables the
   8586 > field-blanking misfeature.
   8587 > ---
   8588 >  lib/sup/textfield.rb |    4 +++-
   8589 >  1 files changed, 3 insertions(+), 1 deletions(-)
   8590 > 
   8591 > diff --git a/lib/sup/textfield.rb b/lib/sup/textfield.rb
   8592 > index 9afeb34..1c19751 100644
   8593 > --- a/lib/sup/textfield.rb
   8594 > +++ b/lib/sup/textfield.rb
   8595 > @@ -33,7 +33,9 @@ class TextField
   8596 >      @w, @y, @x, @width = window, y, x, width
   8597 >      @question = question
   8598 >      @completion_block = block
   8599 > -    @field = Ncurses::Form.new_field 1, @width - question.length, @y, @x + question.length, 256, 0
   8600 > +    @field = Ncurses::Form.new_field 1, @width - question.length, @y, @x + question.length, 0, 0
   8601 > +    @field.opts_off Ncurses::Form::O_STATIC
   8602 > +    @field.opts_off Ncurses::Form::O_BLANK
   8603 >      @form = Ncurses::Form.new_form [@field]
   8604 >      @value = default || ''
   8605 >      Ncurses::Form.post_form @form
   8606 
   8607 From hyperbolist@gmail.com  Fri Jan 22 15:13:01 2010
   8608 From: hyperbolist@gmail.com (Eric Sherman)
   8609 Date: Fri, 22 Jan 2010 15:13:01 -0500
   8610 Subject: [sup-devel] [PATCHv2] idle and unidle updates
   8611 In-Reply-To: <1263483819-sup-9886@changeling.local>
   8612 References: <1263483819-sup-9886@changeling.local>
   8613 Message-ID: <1264190784-sup-222@changeling.local>
   8614 
   8615 This is a problematic place for this logic to go, since it appears as if 
   8616 the idle update does not fire when shelled to the editor, and instead fires 
   8617 immediately upon returning.  Which ironically is exactly when you're 
   8618 becoming unidle.
   8619 
   8620 I'm thinking of an IdleManager with a single public method #ping that can 
   8621 be called here where no_keystrokes_since is being updated.  It has a thread 
   8622 that does the threshold checking and relays the updates.  This way it's not 
   8623 in the main thread and doesn't block when shelled.
   8624 
   8625 Thoughts?
   8626 
   8627 Excerpts from Eric Sherman's message of Thu Jan 14 10:45:54 -0500 2010:
   8628 > ---
   8629 >  bin/sup |   17 +++++++++++++++++
   8630 >  1 files changed, 17 insertions(+), 0 deletions(-)
   8631 > 
   8632 > diff --git a/bin/sup b/bin/sup
   8633 > index 19b2a87..0d90d00 100755
   8634 > --- a/bin/sup
   8635 > +++ b/bin/sup
   8636 > @@ -260,6 +260,10 @@ begin
   8637 >      SearchResultsMode.spawn_from_query $opts[:search]
   8638 >    end
   8639 >  
   8640 > +  IDLE_THRESHOLD = 60
   8641 > +  no_keystrokes_since = Time.now
   8642 > +  idle = false
   8643 > +
   8644 >    until Redwood::exceptions.nonempty? || $die
   8645 >      c = begin
   8646 >        Ncurses.nonblocking_getch
   8647 > @@ -274,9 +278,22 @@ begin
   8648 >          debug "redrawing screen on sigwinch"
   8649 >          BufferManager.completely_redraw_screen
   8650 >        end
   8651 > +
   8652 > +      if !idle and Time.now.to_i - no_keystrokes_since.to_i >= IDLE_THRESHOLD
   8653 > +        UpdateManager.relay self, :idle, Time.at(no_keystrokes_since)
   8654 > +        idle = true
   8655 > +      end
   8656 > +
   8657 >        next
   8658 >      end
   8659 >  
   8660 > +    if idle
   8661 > +      UpdateManager.relay self, :unidle, Time.at(no_keystrokes_since)
   8662 > +      idle = false
   8663 > +    end
   8664 > +
   8665 > +    no_keystrokes_since = Time.now
   8666 > +
   8667 >      if c == 410
   8668 >        ## this is ncurses's way of telling us it's detected a refresh.
   8669 >        ## since we have our own sigwinch handler, we don't do anything.
   8670 
   8671 From rlane@club.cc.cmu.edu  Fri Jan 22 18:47:14 2010
   8672 From: rlane@club.cc.cmu.edu (Rich Lane)
   8673 Date: Fri, 22 Jan 2010 18:47:14 -0500
   8674 Subject: [sup-devel] [PATCH] configurable color highlights
   8675 Message-ID: <1264204034-7088-1-git-send-email-rlane@club.cc.cmu.edu>
   8676 
   8677 Adds a :highlight key to the color entries in colors.yaml that names another
   8678 color to be used for highlighting.
   8679 ---
   8680  lib/sup/colormap.rb |   18 ++++++++++++++----
   8681  1 files changed, 14 insertions(+), 4 deletions(-)
   8682 
   8683 diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
   8684 index 6f21f9a..aeb3818 100644
   8685 --- a/lib/sup/colormap.rb
   8686 +++ b/lib/sup/colormap.rb
   8687 @@ -77,19 +77,26 @@ class Colormap
   8688  
   8689    def reset
   8690      @entries = {}
   8691 +    @highlights = { :none => highlight_sym(:none)}
   8692      @entries[highlight_sym(:none)] = highlight_for(Curses::COLOR_WHITE,
   8693                                                     Curses::COLOR_BLACK,
   8694                                                     []) + [nil]
   8695    end
   8696  
   8697 -  def add sym, fg, bg, attr=nil, opts={}
   8698 +  def add sym, fg, bg, attr=nil, highlight=nil
   8699      raise ArgumentError, "color for #{sym} already defined" if @entries.member? sym
   8700      raise ArgumentError, "color '#{fg}' unknown" unless (-1...Curses::NUM_COLORS).include? fg
   8701      raise ArgumentError, "color '#{bg}' unknown" unless (-1...Curses::NUM_COLORS).include? bg
   8702      attrs = [attr].flatten.compact
   8703  
   8704      @entries[sym] = [fg, bg, attrs, nil]
   8705 -    @entries[highlight_sym(sym)] = opts[:highlight] ? @entries[opts[:highlight]] : highlight_for(fg, bg, attrs) + [nil]
   8706 +
   8707 +    if not highlight
   8708 +      highlight = highlight_sym(sym)
   8709 +      @entries[highlight] = highlight_for(fg, bg, attrs) + [nil]
   8710 +    end
   8711 +
   8712 +    @highlights[sym] = highlight
   8713    end
   8714  
   8715    def highlight_sym sym
   8716 @@ -132,7 +139,7 @@ class Colormap
   8717    end
   8718  
   8719    def color_for sym, highlight=false
   8720 -    sym = highlight_sym(sym) if highlight
   8721 +    sym = @highlights[sym] if highlight
   8722      return Curses::COLOR_BLACK if sym == :none
   8723      raise ArgumentError, "undefined color #{sym}" unless @entries.member? sym
   8724  
   8725 @@ -213,8 +220,11 @@ class Colormap
   8726          end
   8727        end
   8728  
   8729 +      highlight = ucolor[:highlight] || v[:highlight]
   8730 +      highlight_symbol = highlight ? :"#{highlight}_color" : nil
   8731 +
   8732        symbol = (k.to_s + "_color").to_sym
   8733 -      add symbol, fg, bg, attrs
   8734 +      add symbol, fg, bg, attrs, highlight_symbol
   8735      end
   8736  
   8737      warn error if error
   8738 -- 
   8739 1.5.6.5
   8740 
   8741 
   8742 From hyperbolist@gmail.com  Sat Jan 23 00:42:56 2010
   8743 From: hyperbolist@gmail.com (Eric Sherman)
   8744 Date: Sat, 23 Jan 2010 00:42:56 -0500
   8745 Subject: [sup-devel] [PATCHv3] idle and unidle updates
   8746 Message-ID: <1264225074-sup-7366@changeling.local>
   8747 
   8748 Now handled outside of the main thread to accommodate shelling out to
   8749 the editor.
   8750 
   8751 [PATCH] flush index on idle
   8752 and
   8753 [PATCHv5] [issue14] poll updates accumulate while idle
   8754 will still work with this patch.
   8755 ---
   8756  bin/sup         |    4 ++++
   8757  lib/sup.rb      |    2 ++
   8758  lib/sup/idle.rb |   42 ++++++++++++++++++++++++++++++++++++++++++
   8759  3 files changed, 48 insertions(+), 0 deletions(-)
   8760  create mode 100644 lib/sup/idle.rb
   8761 
   8762 diff --git a/bin/sup b/bin/sup
   8763 index 8bf640b..a5d48f6 100755
   8764 --- a/bin/sup
   8765 +++ b/bin/sup
   8766 @@ -239,6 +239,7 @@ begin
   8767  
   8768    unless $opts[:no_threads]
   8769      PollManager.start
   8770 +    IdleManager.start
   8771      Index.start_lock_update_thread
   8772    end
   8773  
   8774 @@ -263,6 +264,8 @@ begin
   8775        next
   8776      end
   8777  
   8778 +    IdleManager.ping
   8779 +
   8780      if c == 410
   8781        ## this is ncurses's way of telling us it's detected a refresh.
   8782        ## since we have our own sigwinch handler, we don't do anything.
   8783 @@ -366,6 +369,7 @@ rescue Exception => e
   8784  ensure
   8785    unless $opts[:no_threads]
   8786      PollManager.stop if PollManager.instantiated?
   8787 +    IdleManager.stop if IdleManager.instantiated?
   8788      Index.stop_lock_update_thread
   8789    end
   8790  
   8791 diff --git a/lib/sup.rb b/lib/sup.rb
   8792 index e03a35d..2fbaa02 100644
   8793 --- a/lib/sup.rb
   8794 +++ b/lib/sup.rb
   8795 @@ -131,6 +131,7 @@ module Redwood
   8796      Redwood::CryptoManager.init
   8797      Redwood::UndoManager.init
   8798      Redwood::SourceManager.init
   8799 +    Redwood::IdleManager.init
   8800    end
   8801  
   8802    def finish
   8803 @@ -341,6 +342,7 @@ require "sup/modes/file-browser-mode"
   8804  require "sup/modes/completion-mode"
   8805  require "sup/modes/console-mode"
   8806  require "sup/sent"
   8807 +require "sup/idle"
   8808  
   8809  $:.each do |base|
   8810    d = File.join base, "sup/share/modes/"
   8811 diff --git a/lib/sup/idle.rb b/lib/sup/idle.rb
   8812 new file mode 100644
   8813 index 0000000..a3a272f
   8814 --- /dev/null
   8815 +++ b/lib/sup/idle.rb
   8816 @@ -0,0 +1,42 @@
   8817 +require 'thread'
   8818 +
   8819 +module Redwood
   8820 +
   8821 +class IdleManager
   8822 +  include Singleton
   8823 +
   8824 +  IDLE_THRESHOLD = 60
   8825 +
   8826 +  def initialize
   8827 +    @no_activity_since = Time.now
   8828 +    @idle = false
   8829 +    @thread = nil
   8830 +  end
   8831 +
   8832 +  def ping
   8833 +    if @idle
   8834 +      UpdateManager.relay self, :unidle, Time.at(@no_activity_since)
   8835 +      @idle = false
   8836 +    end
   8837 +    @no_activity_since = Time.now
   8838 +  end
   8839 +
   8840 +  def start
   8841 +    @thread = Redwood::reporting_thread("checking for idleness") do
   8842 +      while true
   8843 +        sleep 1
   8844 +        if !@idle and Time.now.to_i - @no_activity_since.to_i >= IDLE_THRESHOLD
   8845 +          UpdateManager.relay self, :idle, Time.at(@no_activity_since)
   8846 +          @idle = true
   8847 +        end
   8848 +      end
   8849 +    end
   8850 +  end
   8851 +
   8852 +  def stop
   8853 +    @thread.kill if @thread
   8854 +    @thread = nil
   8855 +  end
   8856 +end
   8857 +
   8858 +end
   8859 -- 
   8860 1.6.6
   8861 
   8862 From wmorgan-sup@masanjin.net  Sat Jan 23 07:41:53 2010
   8863 From: wmorgan-sup@masanjin.net (William Morgan)
   8864 Date: Sat, 23 Jan 2010 07:41:53 -0500
   8865 Subject: [sup-devel] [PATCH] fix ask_for_contacts on Ruby 1.9
   8866 In-Reply-To: <1263406420-27036-1-git-send-email-rlane@club.cc.cmu.edu>
   8867 References: <1263406420-27036-1-git-send-email-rlane@club.cc.cmu.edu>
   8868 Message-ID: <1264250463-sup-3881@masanjin.net>
   8869 
   8870 Applied to master and will go out in 0.10. Thanks!
   8871 -- 
   8872 William <wmorgan-sup at masanjin.net>
   8873 
   8874 From wmorgan-sup@masanjin.net  Sat Jan 23 07:43:18 2010
   8875 From: wmorgan-sup@masanjin.net (William Morgan)
   8876 Date: Sat, 23 Jan 2010 07:43:18 -0500
   8877 Subject: [sup-devel] [PATCH] xapian: add boolean terms with zero wdf
   8878 In-Reply-To: <1263532469-30760-1-git-send-email-rlane@club.cc.cmu.edu>
   8879 References: <1263532469-30760-1-git-send-email-rlane@club.cc.cmu.edu>
   8880 Message-ID: <1264250590-sup-8757@masanjin.net>
   8881 
   8882 Applied to master and will go out in 0.10. Thanks!
   8883 -- 
   8884 William <wmorgan-sup at masanjin.net>
   8885 
   8886 From wmorgan-sup@masanjin.net  Sat Jan 23 07:44:39 2010
   8887 From: wmorgan-sup@masanjin.net (William Morgan)
   8888 Date: Sat, 23 Jan 2010 07:44:39 -0500
   8889 Subject: [sup-devel] [PATCH] utf-8 script encoding
   8890 In-Reply-To: <1262535218-sup-9718@dolk>
   8891 References: <1262533823-sup-5348@dolk>
   8892 	<1262534836-29113-1-git-send-email-rlane@club.cc.cmu.edu>
   8893 	<1262535218-sup-9718@dolk>
   8894 Message-ID: <1264250655-sup-3062@masanjin.net>
   8895 
   8896 Reformatted excerpts from Gaute Hope's message of 2010-01-03:
   8897 > No. Tab completion fails, and sending fails, I can add names with
   8898 > UTF-8 chars to the recipient list, but it fails with the last attached
   8899 > exception. This is the same behaviour as earlier.
   8900 
   8901 That's weird, I would've expected this to help. What's the alternative,
   8902 adding "u" to the end of every regexp?
   8903 -- 
   8904 William <wmorgan-sup at masanjin.net>
   8905 
   8906 From wmorgan-sup@masanjin.net  Sat Jan 23 07:49:45 2010
   8907 From: wmorgan-sup@masanjin.net (William Morgan)
   8908 Date: Sat, 23 Jan 2010 07:49:45 -0500
   8909 Subject: [sup-devel] [PATCH 1/4] dont index redundant data
   8910 In-Reply-To: <1263672187-5174-1-git-send-email-rlane@club.cc.cmu.edu>
   8911 References: <1263672187-5174-1-git-send-email-rlane@club.cc.cmu.edu>
   8912 Message-ID: <1264250978-sup-9237@masanjin.net>
   8913 
   8914 Branch xapian-updates, merged into next.
   8915 
   8916 -- 
   8917 William <wmorgan-sup at masanjin.net>
   8918 
   8919 From wmorgan-sup@masanjin.net  Sat Jan 23 07:55:58 2010
   8920 From: wmorgan-sup@masanjin.net (William Morgan)
   8921 Date: Sat, 23 Jan 2010 07:55:58 -0500
   8922 Subject: [sup-devel] [PATCH] asciify untrusted strings before displaying
   8923 	in TextMode
   8924 In-Reply-To: <1263937705-10875-1-git-send-email-rlane@club.cc.cmu.edu>
   8925 References: <1263937705-10875-1-git-send-email-rlane@club.cc.cmu.edu>
   8926 Message-ID: <1264251348-sup-4751@masanjin.net>
   8927 
   8928 Applied to master and will go out in 0.10. Thanks!
   8929 -- 
   8930 William <wmorgan-sup at masanjin.net>
   8931 
   8932 From wmorgan-sup@masanjin.net  Sat Jan 23 08:01:33 2010
   8933 From: wmorgan-sup@masanjin.net (William Morgan)
   8934 Date: Sat, 23 Jan 2010 08:01:33 -0500
   8935 Subject: [sup-devel] [PATCHv3] Saved Search Support
   8936 In-Reply-To: <1263997604-sup-9969@changeling.local>
   8937 References: <1263858172-sup-547@changeling.local>
   8938 	<1263920054-sup-9400@zyrg.net>
   8939 	<1263959248-sup-4163@changeling.local>
   8940 	<1263960767-sup-4706@zyrg.net>
   8941 	<1263997604-sup-9969@changeling.local>
   8942 Message-ID: <1264251672-sup-7773@masanjin.net>
   8943 
   8944 Very nice. Was just longing for this functionality. Branch saved-search,
   8945 merged into next. Thanks!
   8946 -- 
   8947 William <wmorgan-sup at masanjin.net>
   8948 
   8949 From wmorgan-sup@masanjin.net  Sat Jan 23 08:11:33 2010
   8950 From: wmorgan-sup@masanjin.net (William Morgan)
   8951 Date: Sat, 23 Jan 2010 08:11:33 -0500
   8952 Subject: [sup-devel] [PATCH] Message#edit_labels [was: Ruby question:
   8953 	before-add-message.rb and adding multiple labels at once]
   8954 In-Reply-To: <1264117436-sup-4429@tilus.net>
   8955 References: <1263574849-sup-3477@sam.mediasupervision.de>
   8956 	<1263680819-sup-415@tilus.net> <1264117436-sup-4429@tilus.net>
   8957 Message-ID: <1264252198-sup-6507@masanjin.net>
   8958 
   8959 Reformatted excerpts from Tero Tilus's message of 2010-01-21:
   8960 > Did this get merged?  I got no feedback.
   8961 
   8962 Sorry about that. This is very similar to the code in
   8963 ThreadViewMode#multi_edit_labels, so I would prefer a solution that
   8964 shared a codepath. It's also important to call LabelManager.<< for each
   8965 label, to make sure they appear in label-list-mode.
   8966 -- 
   8967 William <wmorgan-sup at masanjin.net>
   8968 
   8969 From rlane@club.cc.cmu.edu  Sat Jan 23 22:16:00 2010
   8970 From: rlane@club.cc.cmu.edu (Rich Lane)
   8971 Date: Sat, 23 Jan 2010 19:16:00 -0800
   8972 Subject: [sup-devel] [PATCH] enable ruby-prof with SUP_PROFILE environment
   8973 	variable
   8974 Message-ID: <1264302960-17337-1-git-send-email-rlane@club.cc.cmu.edu>
   8975 
   8976 If SUP_PROFILE is set, it's used as the filename to dump profiling output
   8977 which you can use kcachegrind to inspect.
   8978 ---
   8979  bin/sup |   10 ++++++++++
   8980  1 files changed, 10 insertions(+), 0 deletions(-)
   8981 
   8982 diff --git a/bin/sup b/bin/sup
   8983 index 7824aca..f7c4af7 100755
   8984 --- a/bin/sup
   8985 +++ b/bin/sup
   8986 @@ -14,6 +14,11 @@ require 'fileutils'
   8987  require 'trollop'
   8988  require "sup"; Redwood::check_library_version_against "git"
   8989  
   8990 +if ENV['SUP_PROFILE']
   8991 +  require 'ruby-prof'
   8992 +  RubyProf.start
   8993 +end
   8994 +
   8995  if no_ncursesw
   8996    debug "No 'ncursesw' gem detected. Install it for wide character support."
   8997  end
   8998 @@ -379,6 +384,11 @@ ensure
   8999    end
   9000  
   9001    Index.unlock
   9002 +
   9003 +  if (fn = ENV['SUP_PROFILE'])
   9004 +    result = RubyProf.stop
   9005 +    File.open(fn, 'w') { |io| RubyProf::CallTreePrinter.new(result).print(io) }
   9006 +  end
   9007  end
   9008  
   9009  unless Redwood::exceptions.empty?
   9010 -- 
   9011 1.6.3.3
   9012 
   9013 
   9014 From rlane@club.cc.cmu.edu  Sat Jan 23 22:17:17 2010
   9015 From: rlane@club.cc.cmu.edu (Rich Lane)
   9016 Date: Sat, 23 Jan 2010 19:17:17 -0800
   9017 Subject: [sup-devel] [PATCH] dont check thread-index-mode dirtiness on every
   9018 	keypress
   9019 Message-ID: <1264303037-17440-1-git-send-email-rlane@club.cc.cmu.edu>
   9020 
   9021 Now that changes are instantly written to the index it's unnecessary to put the
   9022 "modified" message in the status line. Removing this cuts the time for a simple
   9023 action like moving the cursor by 75% or more, depending on the number of
   9024 messages loaded.
   9025 ---
   9026  lib/sup/modes/thread-index-mode.rb |    2 +-
   9027  1 files changed, 1 insertions(+), 1 deletions(-)
   9028 
   9029 diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb
   9030 index a6bb2b9..71c8f44 100644
   9031 --- a/lib/sup/modes/thread-index-mode.rb
   9032 +++ b/lib/sup/modes/thread-index-mode.rb
   9033 @@ -651,7 +651,7 @@ EOS
   9034      if (l = lines) == 0
   9035        "line 0 of 0"
   9036      else
   9037 -      "line #{curpos + 1} of #{l} #{dirty? ? '*modified*' : ''}"
   9038 +      "line #{curpos + 1} of #{l}"
   9039      end
   9040    end
   9041  
   9042 -- 
   9043 1.6.3.3
   9044 
   9045 
   9046 From pi+sup@pihost.us  Sat Jan 23 22:22:37 2010
   9047 From: pi+sup@pihost.us (Anthony Martinez)
   9048 Date: Sat, 23 Jan 2010 20:22:37 -0700
   9049 Subject: [sup-devel] [PATCH] enable ruby-prof with SUP_PROFILE
   9050 	environment variable
   9051 In-Reply-To: <1264302960-17337-1-git-send-email-rlane@club.cc.cmu.edu>
   9052 References: <1264302960-17337-1-git-send-email-rlane@club.cc.cmu.edu>
   9053 Message-ID: <1264303219-sup-9847@home.mrtheplague.net>
   9054 
   9055 Excerpts from Rich Lane's message of Sat Jan 23 20:16:00 -0700 2010:
   9056 > If SUP_PROFILE is set, it's used as the filename to dump profiling output
   9057 > which you can use kcachegrind to inspect.
   9058 
   9059 Excellent. I could use this to track down why it's taking forever to load a
   9060 20,000 line message :)
   9061 
   9062 -- 
   9063 If Java had true garbage collection, most programs would delete themselves upon execution.
   9064 -- Robert Sewell
   9065 
   9066 From wmorgan-sup@masanjin.net  Sun Jan 24 09:44:50 2010
   9067 From: wmorgan-sup@masanjin.net (William Morgan)
   9068 Date: Sun, 24 Jan 2010 09:44:50 -0500
   9069 Subject: [sup-devel] [ANN] Sup 0.10 released
   9070 Message-ID: <1264344055-sup-3295@masanjin.net>
   9071 
   9072 I'm pleased to announce the release of Sup 0.10. This version is
   9073 frickin' awesome because not only do we have Ruby 1.9 support, the
   9074 Xapian backend is now the default!  The next version will discard Ferret
   9075 like a used rag.
   9076 
   9077 Sup is a console-based email client for people with a lot of email.
   9078 It supports tagging, very fast full-text search, automatic contact-
   9079 list management, and more. If you're the type of person who treats
   9080 email as an extension of your long-term memory, Sup is for you.
   9081 
   9082 Get it: gem install sup
   9083 Learn it: http://sup.rubyforge.org
   9084 Love it: sup-talk at rubyforge.org
   9085 
   9086 Release notes:
   9087 
   9088 The Xapian backend is now the default. Convert your old, crash-prone
   9089 Ferret index to Xapian by running sup-convert-ferret-index.
   9090 
   9091 Using a Ferret backend will produce a deprecation notice, and will not be
   9092 supported in 0.11.
   9093 
   9094 Many thanks to Rich Lane for Xapian and Ruby 1.9 work.
   9095 
   9096 Excitement in 0.10:
   9097 
   9098 * Make Xapian backend the default, and add deprecation notice to Ferret indexes.
   9099 * Now Ruby 1.9 compatible (Xapian backend only).
   9100 * Changes are now saved automatically to the index. Pressing "$" now just
   9101   forces a flush of Xapian indexes, which can minimize quit time.
   9102 * Fix problem with replying to Google Groups messages.
   9103 * Allow toggling of line wrap. Useful for long URLs.
   9104 * Multiple attachments can be added at once by specifying a wildcard.
   9105 * New command to save all attachments at once.
   9106 * As always, many bugfixes and tweaks.
   9107 
   9108 -- 
   9109 William <wmorgan-sup at masanjin.net>
   9110 
   9111 From sup-bugs@masanjin.net  Sun Jan 24 12:07:08 2010
   9112 From: sup-bugs@masanjin.net (anonymous)
   9113 Date: Sun, 24 Jan 2010 17:07:08 +0000
   9114 Subject: [sup-devel] [issue47] utf-8 regression: search&inbox views has
   9115 	garbled utf-8
   9116 In-Reply-To: <1264352828.18.0.950975059303.issue47@masanjin.net>
   9117 Message-ID: <1264352828.18.0.950975059303.issue47@masanjin.net>
   9118 
   9119 
   9120 New submission from anonymous:
   9121 
   9122 Hi!
   9123 
   9124 I upgraded to 0.10 by doing git pull && git checkout origin/release-0.10.
   9125 
   9126 After a friendly nag about upgrading to Xapian, sup started nicely. But: In all
   9127 search-results and in the inbox, any non-ascii utf-8 characters are displayed in
   9128 a garbled format, for example: "Autos?k" becomes "Autos\xc3\xb8k".
   9129 
   9130 Searching for "autos?k" works as expected, and what's even stranger is that
   9131 after viewing one of these threads, and then going back to the search buffer, it
   9132 will show the utf-8 correctly for that single thread.
   9133 
   9134 Something is not quite right here...
   9135 
   9136 ----------
   9137 messages: 112
   9138 nosy: anonymous
   9139 priority: bug
   9140 ruby_version: 1.8.7
   9141 status: unread
   9142 sup_version: 0.10
   9143 title: utf-8 regression: search&inbox views has garbled utf-8
   9144 
   9145 _________________________________________
   9146 Sup issue tracker <sup-bugs at masanjin.net>
   9147 <http://masanjin.net/sup-bugs/issue47>
   9148 _________________________________________
   9149 
   9150 From rlane@club.cc.cmu.edu  Sun Jan 24 14:37:00 2010
   9151 From: rlane@club.cc.cmu.edu (Rich Lane)
   9152 Date: Sun, 24 Jan 2010 11:37:00 -0800
   9153 Subject: [sup-devel] [PATCH] dont restrict colors to those in
   9154 	Colormap::DEFAULT_COLORS
   9155 In-Reply-To: <1264204034-7088-1-git-send-email-rlane@club.cc.cmu.edu>
   9156 References: <1264204034-7088-1-git-send-email-rlane@club.cc.cmu.edu>
   9157 Message-ID: <1264361820-4176-1-git-send-email-rlane@club.cc.cmu.edu>
   9158 
   9159 This is necessary for user-created highlight colors. A side effect is that
   9160 invalid color names now default to ugly red/green instead of what was in
   9161 DEFAULT_COLORS, which seems more useful for debugging colormap problems. Also
   9162 remove the redundant warnings.
   9163 ---
   9164  lib/sup/colormap.rb |   58 ++++++++++++++++++--------------------------------
   9165  1 files changed, 21 insertions(+), 37 deletions(-)
   9166 
   9167 diff --git a/lib/sup/colormap.rb b/lib/sup/colormap.rb
   9168 index aeb3818..7de48db 100644
   9169 --- a/lib/sup/colormap.rb
   9170 +++ b/lib/sup/colormap.rb
   9171 @@ -183,51 +183,35 @@ class Colormap
   9172        Redwood::load_yaml_obj Redwood::COLOR_FN
   9173      end
   9174  
   9175 -    error = nil
   9176 -    Colormap::DEFAULT_COLORS.each_pair do |k, v|
   9177 -      fg = Curses.const_get "COLOR_#{v[:fg].upcase}"
   9178 -      bg = Curses.const_get "COLOR_#{v[:bg].upcase}"
   9179 -      attrs = v[:attrs] ? v[:attrs].map { |a| Curses.const_get "A_#{a.upcase}" } : []
   9180 -
   9181 -      if user_colors && (ucolor = user_colors[k])
   9182 -        if(ufg = ucolor[:fg])
   9183 -          begin
   9184 -            fg = Curses.const_get "COLOR_#{ufg.to_s.upcase}"
   9185 -          rescue NameError
   9186 -            error ||= "Warning: there is no color named \"#{ufg}\", using fallback."
   9187 -            warn "there is no color named \"#{ufg}\""
   9188 -          end
   9189 -        end
   9190 +    Colormap::DEFAULT_COLORS.merge(user_colors||{}).each_pair do |k, v|
   9191 +      fg = begin
   9192 +        Curses.const_get "COLOR_#{v[:fg].to_s.upcase}"
   9193 +      rescue NameError
   9194 +        warn "there is no color named \"#{v[:fg]}\""
   9195 +        Curses::COLOR_GREEN
   9196 +      end
   9197  
   9198 -        if(ubg = ucolor[:bg])
   9199 -          begin
   9200 -            bg = Curses.const_get "COLOR_#{ubg.to_s.upcase}"
   9201 -          rescue NameError
   9202 -            error ||= "Warning: there is no color named \"#{ubg}\", using fallback."
   9203 -            warn "there is no color named \"#{ubg}\""
   9204 -          end
   9205 -        end
   9206 +      bg = begin
   9207 +        Curses.const_get "COLOR_#{v[:bg].to_s.upcase}"
   9208 +      rescue NameError
   9209 +        warn "there is no color named \"#{v[:bg]}\""
   9210 +        Curses::COLOR_RED
   9211 +      end
   9212  
   9213 -        if(uattrs = ucolor[:attrs])
   9214 -          attrs = [*uattrs].flatten.map do |a|
   9215 -            begin
   9216 -              Curses.const_get "A_#{a.upcase}"
   9217 -            rescue NameError
   9218 -              error ||= "Warning: there is no attribute named \"#{a}\", using fallback."
   9219 -              warn "there is no attribute named \"#{a}\", using fallback."
   9220 -            end
   9221 -          end
   9222 +      attrs = (v[:attrs]||[]).map do |a|
   9223 +        begin
   9224 +          Curses.const_get "A_#{a.upcase}"
   9225 +        rescue NameError
   9226 +          warn "there is no attribute named \"#{a}\", using fallback."
   9227 +          nil
   9228          end
   9229 -      end
   9230 +      end.compact
   9231  
   9232 -      highlight = ucolor[:highlight] || v[:highlight]
   9233 -      highlight_symbol = highlight ? :"#{highlight}_color" : nil
   9234 +      highlight_symbol = v[:highlight] ? :"#{v[:highlight]}_color" : nil
   9235  
   9236        symbol = (k.to_s + "_color").to_sym
   9237        add symbol, fg, bg, attrs, highlight_symbol
   9238      end
   9239 -
   9240 -    warn error if error
   9241    end
   9242  
   9243    def self.instance; @@instance; end
   9244 -- 
   9245 1.6.3.3
   9246 
   9247 
   9248 From sup-bugs@masanjin.net  Sun Jan 24 17:30:40 2010
   9249 From: sup-bugs@masanjin.net (anonymous)
   9250 Date: Sun, 24 Jan 2010 22:30:40 +0000
   9251 Subject: [sup-devel] [issue48] Exception: calling id on nil during startup
   9252 In-Reply-To: <1264372240.82.0.635804068553.issue48@masanjin.net>
   9253 Message-ID: <1264372240.82.0.635804068553.issue48@masanjin.net>
   9254 
   9255 
   9256 New submission from anonymous:
   9257 
   9258 Appearently, t.first is nil in the given line in thread-index-mode.rb.
   9259 Interestingly, t.empty? is not true.
   9260 
   9261 --- RuntimeError from thread: load threads for thread-index-mode
   9262 wrong id called on nil
   9263 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup.rb:17:in `id'
   9264 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup/modes/thread-index-mode.rb:226:in
   9265 `block (2 levels) in update'
   9266 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup/modes/thread-index-mode.rb:226:in
   9267 `each'
   9268 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup/modes/thread-index-mode.rb:226:in
   9269 `sort_by'
   9270 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup/modes/thread-index-mode.rb:226:in
   9271 `block in update'
   9272 <internal:prelude>:8:in `synchronize'
   9273 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup/modes/thread-index-mode.rb:224:in
   9274 `update'
   9275 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup/modes/thread-index-mode.rb:642:in
   9276 `load_n_threads'
   9277 (eval):12:in `load_n_threads'
   9278 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup/modes/thread-index-mode.rb:614:in
   9279 `block in load_n_threads_background'
   9280 /usr/local/lib/ruby/gems/1.9.1/gems/sup-0.10.1/lib/sup.rb:77:in `block in
   9281 reporting_thread'
   9282 
   9283 ----------
   9284 messages: 114
   9285 nosy: anonymous
   9286 priority: bug
   9287 ruby_version: 1.9.1
   9288 status: unread
   9289 sup_version: 0.10.1
   9290 title: Exception: calling id on nil during startup
   9291 
   9292 _________________________________________
   9293 Sup issue tracker <sup-bugs at masanjin.net>
   9294 <http://masanjin.net/sup-bugs/issue48>
   9295 _________________________________________
   9296 
   9297 From tero@tilus.net  Sun Jan 24 21:05:30 2010
   9298 From: tero@tilus.net (Tero Tilus)
   9299 Date: Mon, 25 Jan 2010 04:05:30 +0200
   9300 Subject: [sup-devel] [PATCH] Message#edit_labels [was: Ruby question:
   9301 	before-add-message.rb and adding multiple labels at once]
   9302 In-Reply-To: <1264252198-sup-6507@masanjin.net>
   9303 References: <1263574849-sup-3477@sam.mediasupervision.de>
   9304 	<1263680819-sup-415@tilus.net> <1264117436-sup-4429@tilus.net>
   9305 	<1264252198-sup-6507@masanjin.net>
   9306 Message-ID: <1264384775-sup-925@tilus.net>
   9307 
   9308 William Morgan, 2010-01-23 15:11:
   9309 > This is very similar to ThreadViewMode#multi_edit_labels, so I would
   9310 > prefer a solution that shared a codepath.
   9311 
   9312 Similar indeed.  Factored out.
   9313 
   9314 > It's also important to call LabelManager.<< for each label, to make
   9315 > sure they appear in label-list-mode.
   9316 
   9317 I went a step further with this.  Counting on people not having
   9318 billion-mail threads and gazillions of tags (and thus this potentially
   9319 having performance implications) I dropped all the LabelManager.<<
   9320 calls to Message to ensure that every time labels change, LabelManager
   9321 is informed.
   9322 
   9323 Patch v2 attached.
   9324 
   9325 -- 
   9326 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
   9327 -------------- next part --------------
   9328 A non-text attachment was scrubbed...
   9329 Name: 0001-Message-edit_labels.patch
   9330 Type: application/octet-stream
   9331 Size: 7279 bytes
   9332 Desc: not available
   9333 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100125/b3a12b54/attachment-0001.obj>
   9334 
   9335 From rlane@club.cc.cmu.edu  Sun Jan 24 22:09:31 2010
   9336 From: rlane@club.cc.cmu.edu (Rich Lane)
   9337 Date: Sun, 24 Jan 2010 19:09:31 -0800
   9338 Subject: [sup-devel] [PATCH 1/3] make mode keymap easily accessible to hooks
   9339 Message-ID: <1264388973-5804-1-git-send-email-rlane@club.cc.cmu.edu>
   9340 
   9341 ---
   9342  lib/sup/mode.rb |    4 ++++
   9343  1 files changed, 4 insertions(+), 0 deletions(-)
   9344 
   9345 diff --git a/lib/sup/mode.rb b/lib/sup/mode.rb
   9346 index c8ad0cc..b9e0698 100644
   9347 --- a/lib/sup/mode.rb
   9348 +++ b/lib/sup/mode.rb
   9349 @@ -10,6 +10,10 @@ class Mode
   9350      @@keymaps[self] = keymap
   9351    end
   9352  
   9353 +  def self.keymap
   9354 +    @@keymaps[self] || register_keymap
   9355 +  end
   9356 +
   9357    def initialize
   9358      @buffer = nil
   9359    end
   9360 -- 
   9361 1.6.3.3
   9362 
   9363 
   9364 From rlane@club.cc.cmu.edu  Sun Jan 24 22:09:32 2010
   9365 From: rlane@club.cc.cmu.edu (Rich Lane)
   9366 Date: Sun, 24 Jan 2010 19:09:32 -0800
   9367 Subject: [sup-devel] [PATCH 2/3] add keymap rebinding support
   9368 In-Reply-To: <1264388973-5804-1-git-send-email-rlane@club.cc.cmu.edu>
   9369 References: <1264388973-5804-1-git-send-email-rlane@club.cc.cmu.edu>
   9370 Message-ID: <1264388973-5804-2-git-send-email-rlane@club.cc.cmu.edu>
   9371 
   9372 Keymap#delete removes an existing keybinding and Keymap#add! deletes existing
   9373 bindings to the given keys before adding new ones. Keymap#add_multi now allows
   9374 adding new bindings to an existing submap.
   9375 ---
   9376  lib/sup/keymap.rb |   27 ++++++++++++++++++++++++---
   9377  1 files changed, 24 insertions(+), 3 deletions(-)
   9378 
   9379 diff --git a/lib/sup/keymap.rb b/lib/sup/keymap.rb
   9380 index cb039e4..4cdeeed 100644
   9381 --- a/lib/sup/keymap.rb
   9382 +++ b/lib/sup/keymap.rb
   9383 @@ -60,10 +60,31 @@ class Keymap
   9384      end
   9385    end
   9386  
   9387 +  def delete k
   9388 +    kc = Keymap.keysym_to_keycode(k)
   9389 +    return unless @map.member? kc
   9390 +    entry = @map.delete kc
   9391 +    keys = entry[2]
   9392 +    keys.delete k
   9393 +    @order.delete entry if keys.empty?
   9394 +  end
   9395 +
   9396 +  def add! action, help, *keys
   9397 +    keys.each { |k| delete k }
   9398 +    add action, help, *keys
   9399 +  end
   9400 +
   9401    def add_multi prompt, key
   9402 -    submap = Keymap.new
   9403 -    add submap, prompt, key
   9404 -    yield submap
   9405 +    kc = Keymap.keysym_to_keycode(key)
   9406 +    if @map.member? kc
   9407 +      action = @map[kc].first
   9408 +      raise "existing action is not a keymap" unless action.is_a?(Keymap)
   9409 +      yield action
   9410 +    else
   9411 +      submap = Keymap.new
   9412 +      add submap, prompt, key
   9413 +      yield submap
   9414 +    end
   9415    end
   9416  
   9417    def action_for kc
   9418 -- 
   9419 1.6.3.3
   9420 
   9421 
   9422 From rlane@club.cc.cmu.edu  Sun Jan 24 22:09:33 2010
   9423 From: rlane@club.cc.cmu.edu (Rich Lane)
   9424 Date: Sun, 24 Jan 2010 19:09:33 -0800
   9425 Subject: [sup-devel] [PATCH 3/3] keybindings hook
   9426 In-Reply-To: <1264388973-5804-2-git-send-email-rlane@club.cc.cmu.edu>
   9427 References: <1264388973-5804-1-git-send-email-rlane@club.cc.cmu.edu>
   9428 	<1264388973-5804-2-git-send-email-rlane@club.cc.cmu.edu>
   9429 Message-ID: <1264388973-5804-3-git-send-email-rlane@club.cc.cmu.edu>
   9430 
   9431 Add a hook specifically for custom keybindings. The advantage of this over the
   9432 startup hook is that we can assume it's safe to reload this one while Sup is
   9433 running. The "modes" variable provides a debatably-useful mapping between
   9434 user-visible mode names and the actual classes, for use with class_eval.
   9435 ---
   9436  bin/sup           |    9 +++++++++
   9437  lib/sup/hook.rb   |    1 +
   9438  lib/sup/keymap.rb |   17 +++++++++++++++++
   9439  lib/sup/mode.rb   |    4 ++++
   9440  4 files changed, 31 insertions(+), 0 deletions(-)
   9441 
   9442 diff --git a/bin/sup b/bin/sup
   9443 index 7824aca..ad1271f 100755
   9444 --- a/bin/sup
   9445 +++ b/bin/sup
   9446 @@ -83,8 +83,13 @@ global_keymap = Keymap.new do |k|
   9447    k.add :recall_draft, "Edit most recent draft message", 'R'
   9448    k.add :show_inbox, "Show the Inbox buffer", 'I'
   9449    k.add :show_console, "Show the Console buffer", '~'
   9450 +  k.add_multi "Rerun (k)eybindings hook:", 'O' do |kk|
   9451 +    kk.add :run_keybindings_hook, "Rerun keybindings hook", 'k'
   9452 +  end
   9453  end
   9454  
   9455 +Redwood::Keymap.run_hook global_keymap
   9456 +
   9457  ## the following magic enables wide characters when used with a ruby
   9458  ## ncurses.so that's been compiled against libncursesw. (note the w.) why
   9459  ## this works, i have no idea. much like pretty much every aspect of
   9460 @@ -339,6 +344,10 @@ begin
   9461      when :show_console
   9462        b, new = bm.spawn_unless_exists("Console", :system => true) { ConsoleMode.new }
   9463        b.mode.run
   9464 +    when :run_keybindings_hook
   9465 +      HookManager.clear_one 'keybindings'
   9466 +      Keymap.run_hook global_keymap
   9467 +      bm.flash "keybindings hook run"
   9468      when :nothing, InputSequenceAborted
   9469      when :redraw
   9470        bm.completely_redraw_screen
   9471 diff --git a/lib/sup/hook.rb b/lib/sup/hook.rb
   9472 index 3bf9823..08738cd 100644
   9473 --- a/lib/sup/hook.rb
   9474 +++ b/lib/sup/hook.rb
   9475 @@ -113,6 +113,7 @@ EOS
   9476    def enabled? name; !hook_for(name).nil? end
   9477  
   9478    def clear; @hooks.clear; end
   9479 +  def clear_one k; @hooks.delete k; end
   9480  
   9481  private
   9482  
   9483 diff --git a/lib/sup/keymap.rb b/lib/sup/keymap.rb
   9484 index 4cdeeed..93060b8 100644
   9485 --- a/lib/sup/keymap.rb
   9486 +++ b/lib/sup/keymap.rb
   9487 @@ -1,6 +1,14 @@
   9488  module Redwood
   9489  
   9490  class Keymap
   9491 +
   9492 +  HookManager.register "keybindings", <<EOS
   9493 +Add custom keybindings.
   9494 +Methods:
   9495 +  modes: Hash from mode names to mode classes.
   9496 +  global_keymap: The top-level keymap.
   9497 +EOS
   9498 +
   9499    def initialize
   9500      @map = {}
   9501      @order = []
   9502 @@ -116,6 +124,15 @@ class Keymap
   9503      llen = lines.max_of { |a, b| a.length }
   9504      lines.map { |a, b| sprintf " %#{llen}s : %s", a, b }.join("\n")
   9505    end
   9506 +
   9507 +  def self.run_hook global_keymap
   9508 +    modes = Hash[Mode.keymaps.map { |klass,keymap| [Mode.make_name(klass.name),klass] }]
   9509 +    locals = {
   9510 +      :modes => modes,
   9511 +      :global_keymap => global_keymap,
   9512 +    }
   9513 +    HookManager.run 'keybindings', locals
   9514 +  end
   9515  end
   9516  
   9517  end
   9518 diff --git a/lib/sup/mode.rb b/lib/sup/mode.rb
   9519 index b9e0698..f5aee1c 100644
   9520 --- a/lib/sup/mode.rb
   9521 +++ b/lib/sup/mode.rb
   9522 @@ -14,6 +14,10 @@ class Mode
   9523      @@keymaps[self] || register_keymap
   9524    end
   9525  
   9526 +  def self.keymaps
   9527 +    @@keymaps
   9528 +  end
   9529 +
   9530    def initialize
   9531      @buffer = nil
   9532    end
   9533 -- 
   9534 1.6.3.3
   9535 
   9536 
   9537 From sup-bugs@masanjin.net  Mon Jan 25 08:41:29 2010
   9538 From: sup-bugs@masanjin.net (anonymous)
   9539 Date: Mon, 25 Jan 2010 13:41:29 +0000
   9540 Subject: [sup-devel] [issue49] crash when pressing 'c' to compose
   9541 In-Reply-To: <1264426888.82.0.129719799236.issue49@masanjin.net>
   9542 Message-ID: <1264426888.82.0.129719799236.issue49@masanjin.net>
   9543 
   9544 
   9545 New submission from anonymous:
   9546 
   9547 --- RuntimeError from thread: main
   9548 Invalid email term type any
   9549 ./sup/xapian_index.rb:573:in `mkterm'
   9550 ./sup/xapian_index.rb:410:in `build_xapian_query'
   9551 ./sup/xapian_index.rb:410:in `map'
   9552 ./sup/xapian_index.rb:410:in `build_xapian_query'
   9553 ./sup/xapian_index.rb:114:in `each_id'
   9554 ./sup/xapian_index.rb:124:in `each_id_by_date'
   9555 ./sup/xapian_index.rb:155:in `load_contacts'
   9556 ./sup/index.rb:236:in `send'
   9557 ./sup/index.rb:236:in `method_missing'
   9558 ./sup/buffer.rb:543:in `ask_for_contacts'
   9559 ./sup/util.rb:553:in `send'
   9560 ./sup/util.rb:553:in `method_missing'
   9561 ./sup/modes/compose-mode.rb:24:in `spawn_nicely'
   9562 ../bin/sup:327
   9563 
   9564 ----------
   9565 messages: 118
   9566 nosy: anonymous
   9567 priority: bug
   9568 ruby_version: 1.8.5
   9569 status: unread
   9570 sup_version: next/a3c2f5a0a
   9571 title: crash when pressing 'c' to compose
   9572 
   9573 _________________________________________
   9574 Sup issue tracker <sup-bugs at masanjin.net>
   9575 <http://masanjin.net/sup-bugs/issue49>
   9576 _________________________________________
   9577 
   9578 From isra@herraiz.org  Mon Jan 25 08:53:12 2010
   9579 From: isra@herraiz.org (Israel Herraiz)
   9580 Date: Mon, 25 Jan 2010 14:53:12 +0100
   9581 Subject: [sup-devel] Exception when composing messages
   9582 Message-ID: <1264427161-sup-6711@duck>
   9583 
   9584 Hi all,
   9585 
   9586 I am using the next branch of Sup, and since a couple of commits ago,
   9587 whenever I try to compose a message (new, forward, etc), I obtain this
   9588 exception:
   9589 
   9590 	--- RuntimeError from thread: main
   9591 	Invalid email term type any
   9592 	./lib/sup/xapian_index.rb:573:in `mkterm'
   9593 	./lib/sup/xapian_index.rb:410:in `build_xapian_query'
   9594 	./lib/sup/xapian_index.rb:410:in `map'
   9595 	./lib/sup/xapian_index.rb:410:in `build_xapian_query'
   9596 	./lib/sup/xapian_index.rb:114:in `each_id'
   9597 	./lib/sup/xapian_index.rb:124:in `each_id_by_date'
   9598 	./lib/sup/xapian_index.rb:155:in `load_contacts'
   9599 	./lib/sup/index.rb:236:in `send'
   9600 	./lib/sup/index.rb:236:in `method_missing'
   9601 	./lib/sup/buffer.rb:543:in `ask_for_contacts'
   9602 	./lib/sup/util.rb:553:in `send'
   9603 	./lib/sup/util.rb:553:in `method_missing'
   9604 	./lib/sup/modes/compose-mode.rb:24:in `spawn_nicely'
   9605 	bin/sup:327
   9606 
   9607 The problem seems to be between lines 410 and 573 of
   9608 lib/sup/xapian_index.rb
   9609 
   9610 Some time ago, around line 573, there was the following line in the
   9611 file:
   9612 
   9613 	when :any then PREFIX['email']
   9614 
   9615 Adding that to the current version of file does not solve the problem
   9616 though. I obtain another exception telling that it cannot convert from
   9617 String to Array. 
   9618 
   9619 If I change line 410 to the following (undoing my previous change), it
   9620 works again:
   9621 
   9622         participant_terms = opts[:participants].map { |p| mkterm(:email,:to, (Redwood::Person === p) ? p.email : p) }
   9623 
   9624 Notice that I have just substituted :any by :to.
   9625 
   9626 I have to admit that I am not really aware of what that change
   9627 implies. I have tried to find the commit that changed the behavior,
   9628 without success. But in any case I think this is a bug :-).
   9629 	
   9630 Cheers,
   9631 Israel
   9632 
   9633 From isra@herraiz.org  Mon Jan 25 08:57:07 2010
   9634 From: isra@herraiz.org (Israel Herraiz)
   9635 Date: Mon, 25 Jan 2010 14:57:07 +0100
   9636 Subject: [sup-devel] Exception when composing messages
   9637 In-Reply-To: <1264427161-sup-6711@duck>
   9638 References: <1264427161-sup-6711@duck>
   9639 Message-ID: <1264427765-sup-5441@duck>
   9640 
   9641 It seems that someone (not me :-) opened an issue about this some
   9642 minutes before my message:
   9643 
   9644  http://masanjin.net/sup-bugs/issue49
   9645 
   9646 Cheers,
   9647 Israel
   9648 
   9649 From bwalton@artsci.utoronto.ca  Mon Jan 25 09:22:49 2010
   9650 From: bwalton@artsci.utoronto.ca (Ben Walton)
   9651 Date: Mon, 25 Jan 2010 09:22:49 -0500
   9652 Subject: [sup-devel] [issue49] crash when pressing 'c' to compose
   9653 In-Reply-To: <1264426888.82.0.129719799236.issue49@masanjin.net>
   9654 References: <1264426888.82.0.129719799236.issue49@masanjin.net>
   9655 Message-ID: <1264429332-sup-9299@ntdws12.chass.utoronto.ca>
   9656 
   9657 Excerpts from anonymous's message of Mon Jan 25 08:41:29 -0500 2010:
   9658 
   9659 This was me...
   9660 
   9661 Patch attached.
   9662 
   9663 > --- RuntimeError from thread: main
   9664 > Invalid email term type any
   9665 > ./sup/xapian_index.rb:573:in `mkterm'
   9666 > ./sup/xapian_index.rb:410:in `build_xapian_query'
   9667 > ./sup/xapian_index.rb:410:in `map'
   9668 > ./sup/xapian_index.rb:410:in `build_xapian_query'
   9669 > ./sup/xapian_index.rb:114:in `each_id'
   9670 > ./sup/xapian_index.rb:124:in `each_id_by_date'
   9671 > ./sup/xapian_index.rb:155:in `load_contacts'
   9672 > ./sup/index.rb:236:in `send'
   9673 > ./sup/index.rb:236:in `method_missing'
   9674 > ./sup/buffer.rb:543:in `ask_for_contacts'
   9675 > ./sup/util.rb:553:in `send'
   9676 > ./sup/util.rb:553:in `method_missing'
   9677 > ./sup/modes/compose-mode.rb:24:in `spawn_nicely'
   9678 > ../bin/sup:327
   9679 
   9680 HTH.
   9681 -Ben
   9682 -- 
   9683 Ben Walton
   9684 Systems Programmer - CHASS
   9685 University of Toronto
   9686 C:416.407.5610 | W:416.978.4302
   9687 
   9688 GPG Key Id: 8E89F6D2; Key Server: pgp.mit.edu
   9689 Contact me to arrange for a CAcert assurance meeting.
   9690 -------------- next part --------------
   9691 A non-text attachment was scrubbed...
   9692 Name: 0001-Fix-crash-in-mkterm-when-parameter-any-is-used-with-.patch
   9693 Type: application/octet-stream
   9694 Size: 1083 bytes
   9695 Desc: not available
   9696 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100125/bfb63c96/attachment.obj>
   9697 -------------- next part --------------
   9698 A non-text attachment was scrubbed...
   9699 Name: signature.asc
   9700 Type: application/pgp-signature
   9701 Size: 189 bytes
   9702 Desc: not available
   9703 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100125/bfb63c96/attachment.bin>
   9704 
   9705 From bwalton@artsci.utoronto.ca  Mon Jan 25 09:29:05 2010
   9706 From: bwalton@artsci.utoronto.ca (Ben Walton)
   9707 Date: Mon, 25 Jan 2010 09:29:05 -0500
   9708 Subject: [sup-devel] [issue49] crash when pressing 'c' to compose
   9709 In-Reply-To: <1264429332-sup-9299@ntdws12.chass.utoronto.ca>
   9710 References: <1264426888.82.0.129719799236.issue49@masanjin.net>
   9711 	<1264429332-sup-9299@ntdws12.chass.utoronto.ca>
   9712 Message-ID: <1264429693-sup-5640@ntdws12.chass.utoronto.ca>
   9713 
   9714 Excerpts from Ben Walton's message of Mon Jan 25 09:22:49 -0500 2010:
   9715 
   9716 > Patch attached.
   9717 
   9718 BTW, the xapian index version bump (v1 -> v2) meant I couldn't
   9719 (easily) bisect this problem.  Luckily it wasn't too tough to track
   9720 down from the back trace.
   9721 
   9722 -Ben
   9723 -- 
   9724 Ben Walton
   9725 Systems Programmer - CHASS
   9726 University of Toronto
   9727 C:416.407.5610 | W:416.978.4302
   9728 
   9729 GPG Key Id: 8E89F6D2; Key Server: pgp.mit.edu
   9730 Contact me to arrange for a CAcert assurance meeting.
   9731 -------------- next part --------------
   9732 A non-text attachment was scrubbed...
   9733 Name: signature.asc
   9734 Type: application/pgp-signature
   9735 Size: 189 bytes
   9736 Desc: not available
   9737 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100125/18d2bd52/attachment.bin>
   9738 
   9739 From rlane@club.cc.cmu.edu  Mon Jan 25 11:03:35 2010
   9740 From: rlane@club.cc.cmu.edu (Rich Lane)
   9741 Date: Mon, 25 Jan 2010 08:03:35 -0800
   9742 Subject: [sup-devel] [PATCH] fix participants queries
   9743 In-Reply-To: <1264429332-sup-9299@ntdws12.chass.utoronto.ca>
   9744 References: <1264429332-sup-9299@ntdws12.chass.utoronto.ca>
   9745 Message-ID: <1264435415-11782-1-git-send-email-rlane@club.cc.cmu.edu>
   9746 
   9747 ---
   9748  lib/sup/xapian_index.rb |    2 +-
   9749  1 files changed, 1 insertions(+), 1 deletions(-)
   9750 
   9751 diff --git a/lib/sup/xapian_index.rb b/lib/sup/xapian_index.rb
   9752 index 5efd47b..443b88d 100644
   9753 --- a/lib/sup/xapian_index.rb
   9754 +++ b/lib/sup/xapian_index.rb
   9755 @@ -407,7 +407,7 @@ EOS
   9756      pos_terms << mkterm(:source_id, opts[:source_id]) if opts[:source_id]
   9757  
   9758      if opts[:participants]
   9759 -      participant_terms = opts[:participants].map { |p| mkterm(:email,:any, (Redwood::Person === p) ? p.email : p) }
   9760 +      participant_terms = opts[:participants].map { |p| [:from,:to].map { |d| mkterm(:email, d, (Redwood::Person === p) ? p.email : p) } }.flatten
   9761        pos_terms << Q.new(Q::OP_OR, participant_terms)
   9762      end
   9763  
   9764 -- 
   9765 1.6.3.3
   9766 
   9767 
   9768 From sup-bugs@masanjin.net  Mon Jan 25 11:18:41 2010
   9769 From: sup-bugs@masanjin.net (Scott Henson)
   9770 Date: Mon, 25 Jan 2010 16:18:41 +0000
   9771 Subject: [sup-devel] [issue50] 0.10 error in ask_yes_or_no
   9772 In-Reply-To: <1264436321.23.0.59454690461.issue50@masanjin.net>
   9773 Message-ID: <1264436321.23.0.59454690461.issue50@masanjin.net>
   9774 
   9775 
   9776 New submission from Scott Henson <scott at foolishpride.org>:
   9777 
   9778 [Mon Jan 25 11:06:26 -0500 2010] ERROR: oh crap, an exception
   9779 ----------------------------------------------------------------
   9780 I'm very sorry. It seems that an error occurred in Sup. Please
   9781 accept my sincere apologies. Please submit the contents of
   9782 /home/shenson/.sup/exception-log.txt and a brief report of the
   9783 circumstances to http://masanjin.net/sup-bugs/ so that I might
   9784 address this problem. Thank you!
   9785 
   9786 Sincerely,
   9787 William
   9788 ----------------------------------------------------------------
   9789 --- NoMethodError from thread: main
   9790 undefined method `ord' for 121:Fixnum
   9791 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/lib/sup/buffer.rb:648:in `ask_yes_or_no'
   9792 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/lib/sup/util.rb:553:in `send'
   9793 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/lib/sup/util.rb:553:in `method_missing'
   9794 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/lib/sup/modes/thread-view-mode.rb:232:in
   9795 `bounce'
   9796 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/lib/sup/mode.rb:51:in `send'
   9797 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/lib/sup/mode.rb:51:in `handle_input'
   9798 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/lib/sup/buffer.rb:270:in `handle_input'
   9799 /usr/lib/ruby/gems/1.8/gems/sup-0.10.1/bin/sup:270
   9800 /usr/bin/sup:19:in `load'
   9801 /usr/bin/sup:19
   9802 
   9803 shenson at junkyard ~$ cat /etc/redhat-release 
   9804 Fedora release 12 (Constantine)
   9805 shenson at junkyard ~$ ruby --version
   9806 ruby 1.8.6 (2009-08-04 patchlevel 383) [x86_64-linux]
   9807 
   9808 I was bouncing a message to another address and it caused the above error after
   9809 I hit 'y'.
   9810 
   9811 ----------
   9812 messages: 120
   9813 nosy: shenson
   9814 priority: bug
   9815 ruby_version: ruby 1.8.6 (2009-08-04 patchlevel 383) [x86_64-linux]
   9816 status: unread
   9817 sup_version: 0.10
   9818 title: 0.10 error in ask_yes_or_no
   9819 
   9820 _________________________________________
   9821 Sup issue tracker <sup-bugs at masanjin.net>
   9822 <http://masanjin.net/sup-bugs/issue50>
   9823 _________________________________________
   9824 
   9825 From rlane@club.cc.cmu.edu  Mon Jan 25 11:21:41 2010
   9826 From: rlane@club.cc.cmu.edu (Rich Lane)
   9827 Date: Mon, 25 Jan 2010 11:21:41 -0500
   9828 Subject: [sup-devel] [PATCH] copy thread when spawning ThreadViewMode
   9829 In-Reply-To: <1264134316-17210-1-git-send-email-rlane@club.cc.cmu.edu>
   9830 References: <1264134316-17210-1-git-send-email-rlane@club.cc.cmu.edu>
   9831 Message-ID: <1264436284-sup-7250@zyrg.net>
   9832 
   9833 This breaks ThreadIndexMode#launch_another_thread. I'll send a
   9834 new patch.
   9835 
   9836 From bwalton@artsci.utoronto.ca  Mon Jan 25 11:35:54 2010
   9837 From: bwalton@artsci.utoronto.ca (Ben Walton)
   9838 Date: Mon, 25 Jan 2010 11:35:54 -0500
   9839 Subject: [sup-devel] [PATCH] fix participants queries
   9840 In-Reply-To: <1264435415-11782-1-git-send-email-rlane@club.cc.cmu.edu>
   9841 References: <1264429332-sup-9299@ntdws12.chass.utoronto.ca>
   9842 	<1264435415-11782-1-git-send-email-rlane@club.cc.cmu.edu>
   9843 Message-ID: <1264437314-sup-4264@ntdws12.chass.utoronto.ca>
   9844 
   9845 Excerpts from Rich Lane's message of Mon Jan 25 11:03:35 -0500 2010:
   9846 
   9847 > -      participant_terms = opts[:participants].map { |p| mkterm(:email,:any, (Redwood::Person === p) ? p.email : p) }
   9848 > +      participant_terms = opts[:participants].map { |p| [:from,:to].map { |d| mkterm(:email, d, (Redwood::Person === p) ? p.email : p) } }.flatten
   9849 
   9850 Cleaner than mine.  +1 for prompt inclusion at gitorious. :)
   9851 
   9852 -Ben
   9853 
   9854 -- 
   9855 Ben Walton
   9856 Systems Programmer - CHASS
   9857 University of Toronto
   9858 C:416.407.5610 | W:416.978.4302
   9859 
   9860 GPG Key Id: 8E89F6D2; Key Server: pgp.mit.edu
   9861 Contact me to arrange for a CAcert assurance meeting.
   9862 -------------- next part --------------
   9863 A non-text attachment was scrubbed...
   9864 Name: signature.asc
   9865 Type: application/pgp-signature
   9866 Size: 189 bytes
   9867 Desc: not available
   9868 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100125/b0656f86/attachment.bin>
   9869 
   9870 From bwalton@artsci.utoronto.ca  Mon Jan 25 11:56:40 2010
   9871 From: bwalton@artsci.utoronto.ca (Ben Walton)
   9872 Date: Mon, 25 Jan 2010 11:56:40 -0500
   9873 Subject: [sup-devel] [PATCH] Conditionally define Fixnum#ord
   9874 In-Reply-To: <1264436321.23.0.59454690461.issue50@masanjin.net>
   9875 References: <1264436321.23.0.59454690461.issue50@masanjin.net>
   9876 Message-ID: <1264438600-30566-1-git-send-email-bwalton@artsci.utoronto.ca>
   9877 
   9878 Ruby 1.8.5 was throwing exceptions from lib/sup/util.rb line 650 due
   9879 to calling .ord on a Fixnum.  This patch defines Fixnum#ord if the
   9880 method doesn't exist already.  Helps on old ruby version (1.8.5 here).
   9881 
   9882 Signed-off-by: Ben Walton <bwalton at artsci.utoronto.ca>
   9883 ---
   9884  lib/sup/util.rb |    6 ++++++
   9885  1 files changed, 6 insertions(+), 0 deletions(-)
   9886 
   9887 diff --git a/lib/sup/util.rb b/lib/sup/util.rb
   9888 index 5dadba1..861db7f 100644
   9889 --- a/lib/sup/util.rb
   9890 +++ b/lib/sup/util.rb
   9891 @@ -366,6 +366,12 @@ class Fixnum
   9892      end
   9893    end
   9894  
   9895 +  unless method_defined?(:ord)
   9896 +    def ord
   9897 +      self
   9898 +    end
   9899 +  end
   9900 +
   9901    ## hacking the english language
   9902    def pluralize s
   9903      to_s + " " +
   9904 -- 
   9905 1.6.6
   9906 
   9907 
   9908 From wmorgan-sup@masanjin.net  Mon Jan 25 16:19:13 2010
   9909 From: wmorgan-sup@masanjin.net (William Morgan)
   9910 Date: Mon, 25 Jan 2010 16:19:13 -0500
   9911 Subject: [sup-devel] Fwd: Re: Sup 0.10 released
   9912 Message-ID: <1264454003-sup-9657@masanjin.net>
   9913 
   9914 I'm seeing a weird behavior with the xapian-full gem, and so is this
   9915 guy. The installation claims it fails, but it actually succeeds. The
   9916 spec file is not copied over after installation, so `gem list` doesn't
   9917 show it, but if you require 'xapian' it actually does pick up the code,
   9918 even after the failed installation.
   9919 
   9920 Ideas?
   9921 
   9922 --- Begin forwarded message from Andrea Fazzi ---
   9923 From: Andrea Fazzi <andrea.fazzi at alcacoop.it>
   9924 To: ruby-talk <ruby-talk at ruby-lang.org>
   9925 Date: Mon, 25 Jan 2010 05:32:10 -0500
   9926 Subject: Re: Sup 0.10 released
   9927 
   9928 William Morgan wrote:
   9929 > I'm pleased to announce the release of Sup 0.10. This version is
   9930 > frickin' awesome because not only do we have Ruby 1.9 support, the
   9931 > Xapian backend is now the default!  The next version will discard Ferret
   9932 > like a used rag.
   9933 
   9934 I had issues installing xapian-full gem on my ubuntu box running MRI
   9935 ruby1.8. The installation fails building native extension even if it 
   9936 seems that all the C stuff get compiled correctly. BTW, I solved the 
   9937 issue in this way:
   9938 
   9939 sudo gem install xapian-full
   9940 cd /usr/lib/ruby/gems/1.8/gems/xapian-full-1.1.3/
   9941 sudo rake build
   9942 sudo mv xapian-full.gemspec ../../specifications/
   9943 
   9944 andrea at ubuntu-desktop:~$ irb
   9945 irb(main):001:0> require 'rubygems'
   9946 => true
   9947 irb(main):002:0> require 'xapian'
   9948 => true
   9949 
   9950 Thanks for this great software!
   9951 
   9952 Cheers,
   9953 Andrea
   9954 --- End forwarded message ---
   9955 -- 
   9956 William <wmorgan-sup at masanjin.net>
   9957 
   9958 From wmorgan-sup@masanjin.net  Mon Jan 25 16:20:00 2010
   9959 From: wmorgan-sup@masanjin.net (William Morgan)
   9960 Date: Mon, 25 Jan 2010 16:20:00 -0500
   9961 Subject: [sup-devel] [PATCH] fix participants queries
   9962 In-Reply-To: <1264435415-11782-1-git-send-email-rlane@club.cc.cmu.edu>
   9963 References: <1264429332-sup-9299@ntdws12.chass.utoronto.ca>
   9964 	<1264435415-11782-1-git-send-email-rlane@club.cc.cmu.edu>
   9965 Message-ID: <1264454391-sup-6232@masanjin.net>
   9966 
   9967 Reformatted excerpts from Rich Lane's message of 2010-01-25:
   9968 >  lib/sup/xapian_index.rb |    2 +-
   9969 
   9970 Applied to branch xapian-updates and remerged into next. Thanks!
   9971 -- 
   9972 William <wmorgan-sup at masanjin.net>
   9973 
   9974 From wmorgan-sup@masanjin.net  Mon Jan 25 16:28:25 2010
   9975 From: wmorgan-sup@masanjin.net (William Morgan)
   9976 Date: Mon, 25 Jan 2010 16:28:25 -0500
   9977 Subject: [sup-devel] Exception when composing messages
   9978 In-Reply-To: <1264427161-sup-6711@duck>
   9979 References: <1264427161-sup-6711@duck>
   9980 Message-ID: <1264454887-sup-9882@masanjin.net>
   9981 
   9982 Reformatted excerpts from Israel Herraiz's message of 2010-01-25:
   9983 > I am using the next branch of Sup, and since a couple of commits ago,
   9984 > whenever I try to compose a message (new, forward, etc), I obtain this
   9985 > exception:
   9986 
   9987 This should be fixed!
   9988 -- 
   9989 William <wmorgan-sup at masanjin.net>
   9990 
   9991 From rlane@club.cc.cmu.edu  Mon Jan 25 16:52:23 2010
   9992 From: rlane@club.cc.cmu.edu (Rich Lane)
   9993 Date: Mon, 25 Jan 2010 16:52:23 -0500
   9994 Subject: [sup-devel] [PATCH] fix missing parentheses warning
   9995 In-Reply-To: <8b854d6b1001250307o42e85f44id88d3eea7f18beb4@mail.gmail.com>
   9996 References: <8b854d6b1001250307o42e85f44id88d3eea7f18beb4@mail.gmail.com>
   9997 Message-ID: <1264456343-32418-1-git-send-email-rlane@club.cc.cmu.edu>
   9998 
   9999 ---
  10000  lib/sup/message.rb |    6 +++---
  10001  1 files changed, 3 insertions(+), 3 deletions(-)
  10002 
  10003 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
  10004 index 3e55de5..a85cc0d 100644
  10005 --- a/lib/sup/message.rb
  10006 +++ b/lib/sup/message.rb
  10007 @@ -450,9 +450,9 @@ private
  10008          subj = decode_header_field(payload.header.subject) || DEFAULT_SUBJECT
  10009          subj = Message.normalize_subj(subj.gsub(/\s+/, " ").gsub(/\s+$/, ""))
  10010          msgdate = payload.header.date
  10011 -        from_person = from ? Person.from_address(decode_header_field from) : nil
  10012 -        to_people = to ? Person.from_address_list(decode_header_field to) : nil
  10013 -        cc_people = cc ? Person.from_address_list(decode_header_field cc) : nil
  10014 +        from_person = from ? Person.from_address(decode_header_field(from)) : nil
  10015 +        to_people = to ? Person.from_address_list(decode_header_field(to)) : nil
  10016 +        cc_people = cc ? Person.from_address_list(decode_header_field(cc)) : nil
  10017          [Chunk::EnclosedMessage.new(from_person, to_people, cc_people, msgdate, subj)] + message_to_chunks(payload, encrypted)
  10018        else
  10019          debug "no body for message/rfc822 enclosure; skipping"
  10020 -- 
  10021 1.5.6.5
  10022 
  10023 
  10024 From rlane@club.cc.cmu.edu  Mon Jan 25 17:05:49 2010
  10025 From: rlane@club.cc.cmu.edu (Rich Lane)
  10026 Date: Mon, 25 Jan 2010 17:05:49 -0500
  10027 Subject: [sup-devel] Fwd: Re: Sup 0.10 released
  10028 In-Reply-To: <1264454003-sup-9657@masanjin.net>
  10029 References: <1264454003-sup-9657@masanjin.net>
  10030 Message-ID: <1264456949-sup-3@zyrg.net>
  10031 
  10032 Excerpts from William Morgan's message of 2010-01-25 16:19:13 -0500:
  10033 > I'm seeing a weird behavior with the xapian-full gem, and so is this
  10034 > guy. The installation claims it fails, but it actually succeeds. The
  10035 > spec file is not copied over after installation, so `gem list` doesn't
  10036 > show it, but if you require 'xapian' it actually does pick up the code,
  10037 > even after the failed installation.
  10038 > 
  10039 > Ideas?
  10040 
  10041 This has been reported before but I haven't figured out what's going on.
  10042 I pushed the source of the xapian-full gem to git://github.com/rlane/xapian-full
  10043 in case anyone else wants to take a crack at this.
  10044 
  10045 From rlane@club.cc.cmu.edu  Mon Jan 25 18:37:24 2010
  10046 From: rlane@club.cc.cmu.edu (Rich Lane)
  10047 Date: Mon, 25 Jan 2010 18:37:24 -0500
  10048 Subject: [sup-devel] Fwd: Re: Sup 0.10 released
  10049 In-Reply-To: <1264456949-sup-3@zyrg.net>
  10050 References: <1264454003-sup-9657@masanjin.net> <1264456949-sup-3@zyrg.net>
  10051 Message-ID: <1264462577-sup-3137@zyrg.net>
  10052 
  10053 Excerpts from Rich Lane's message of 2010-01-25 17:05:49 -0500:
  10054 > Excerpts from William Morgan's message of 2010-01-25 16:19:13 -0500:
  10055 > > I'm seeing a weird behavior with the xapian-full gem, and so is this
  10056 > > guy. The installation claims it fails, but it actually succeeds. The
  10057 > > spec file is not copied over after installation, so `gem list` doesn't
  10058 > > show it, but if you require 'xapian' it actually does pick up the code,
  10059 > > even after the failed installation.
  10060 > > 
  10061 > > Ideas?
  10062 > 
  10063 > This has been reported before but I haven't figured out what's going on.
  10064 > I pushed the source of the xapian-full gem to git://github.com/rlane/xapian-full
  10065 > in case anyone else wants to take a crack at this.
  10066 
  10067 I think I fixed it. Please try xapian-full 1.1.3.1 from gemcutter.
  10068 
  10069 From marka@pobox.com  Mon Jan 25 19:21:14 2010
  10070 From: marka@pobox.com (Mark Alexander)
  10071 Date: Mon, 25 Jan 2010 19:21:14 -0500
  10072 Subject: [sup-devel] Fwd: Re: Sup 0.10 released
  10073 In-Reply-To: <1264462577-sup-3137@zyrg.net>
  10074 References: <1264454003-sup-9657@masanjin.net> <1264456949-sup-3@zyrg.net>
  10075 	<1264462577-sup-3137@zyrg.net>
  10076 Message-ID: <a412e2a71001251621o631cffb2gc4f65ef94c3290e8@mail.gmail.com>
  10077 
  10078 On Mon, Jan 25, 2010 at 6:37 PM, Rich Lane <rlane at club.cc.cmu.edu> wrote:
  10079 > I think I fixed it. Please try xapian-full 1.1.3.1 from gemcutter.
  10080 
  10081 Can you describe what you did to fix it?  I spent several hours
  10082 trying to fix this a while back and gave up.
  10083 
  10084 From rlane@club.cc.cmu.edu  Mon Jan 25 19:35:44 2010
  10085 From: rlane@club.cc.cmu.edu (Rich Lane)
  10086 Date: Mon, 25 Jan 2010 19:35:44 -0500
  10087 Subject: [sup-devel] Fwd: Re: Sup 0.10 released
  10088 In-Reply-To: <a412e2a71001251621o631cffb2gc4f65ef94c3290e8@mail.gmail.com>
  10089 References: <1264454003-sup-9657@masanjin.net> <1264456949-sup-3@zyrg.net>
  10090 	<1264462577-sup-3137@zyrg.net>
  10091 	<a412e2a71001251621o631cffb2gc4f65ef94c3290e8@mail.gmail.com>
  10092 Message-ID: <1264465797-sup-429@zyrg.net>
  10093 
  10094 Excerpts from Mark Alexander's message of 2010-01-25 19:21:14 -0500:
  10095 > On Mon, Jan 25, 2010 at 6:37 PM, Rich Lane <rlane at club.cc.cmu.edu> wrote:
  10096 > > I think I fixed it. Please try xapian-full 1.1.3.1 from gemcutter.
  10097 > 
  10098 > Can you describe what you did to fix it?  I spent several hours
  10099 > trying to fix this a while back and gave up.
  10100 
  10101 It turns out gem expects extconf.rb to create a Makefile, but mine was
  10102 just doing the compile itself. Gem also accepts Rakefiles for building
  10103 extensions, so I moved the code into a minimal Rakefile. I also added
  10104 the gemspec to the manifest.
  10105 
  10106 From wmorgan-sup@masanjin.net  Tue Jan 26 08:22:09 2010
  10107 From: wmorgan-sup@masanjin.net (William Morgan)
  10108 Date: Tue, 26 Jan 2010 08:22:09 -0500
  10109 Subject: [sup-devel] Fwd: Re: Sup 0.10 released
  10110 In-Reply-To: <1264462577-sup-3137@zyrg.net>
  10111 References: <1264454003-sup-9657@masanjin.net> <1264456949-sup-3@zyrg.net>
  10112 	<1264462577-sup-3137@zyrg.net>
  10113 Message-ID: <1264512093-sup-8869@masanjin.net>
  10114 
  10115 Reformatted excerpts from Rich Lane's message of 2010-01-25:
  10116 > I think I fixed it. Please try xapian-full 1.1.3.1 from gemcutter.
  10117 
  10118 Works great. Nice one.
  10119 
  10120 I'm going to release an 0.10.2 that has deps on that and ncursesw.
  10121 -- 
  10122 William <wmorgan-sup at masanjin.net>
  10123 
  10124 From wmorgan-sup@masanjin.net  Tue Jan 26 08:20:58 2010
  10125 From: wmorgan-sup@masanjin.net (William Morgan)
  10126 Date: Tue, 26 Jan 2010 08:20:58 -0500
  10127 Subject: [sup-devel] [PATCH] fix missing parentheses warning
  10128 In-Reply-To: <1264456343-32418-1-git-send-email-rlane@club.cc.cmu.edu>
  10129 References: <8b854d6b1001250307o42e85f44id88d3eea7f18beb4@mail.gmail.com>
  10130 	<1264456343-32418-1-git-send-email-rlane@club.cc.cmu.edu>
  10131 Message-ID: <1264511297-sup-1185@masanjin.net>
  10132 
  10133 Applied directly to master. Thanks!
  10134 
  10135 What do people think of turning warnings off entirely for bin/sup?
  10136 Should just be a matter of setting $VERBOSE = nil. It is a curses app,
  10137 after all.
  10138 -- 
  10139 William <wmorgan-sup at masanjin.net>
  10140 
  10141 From wmorgan-sup@masanjin.net  Tue Jan 26 09:05:40 2010
  10142 From: wmorgan-sup@masanjin.net (William Morgan)
  10143 Date: Tue, 26 Jan 2010 09:05:40 -0500
  10144 Subject: [sup-devel] [PATCH] Conditionally define Fixnum#ord
  10145 In-Reply-To: <1264438600-30566-1-git-send-email-bwalton@artsci.utoronto.ca>
  10146 References: <1264436321.23.0.59454690461.issue50@masanjin.net>
  10147 	<1264438600-30566-1-git-send-email-bwalton@artsci.utoronto.ca>
  10148 Message-ID: <1264514710-sup-1956@masanjin.net>
  10149 
  10150 Reformatted excerpts from Ben Walton's message of 2010-01-25:
  10151 > Ruby 1.8.5 was throwing exceptions from lib/sup/util.rb line 650 due
  10152 > to calling .ord on a Fixnum.  This patch defines Fixnum#ord if the
  10153 > method doesn't exist already.  Helps on old ruby version (1.8.5 here).
  10154 
  10155 Applied to master. Thanks!
  10156 -- 
  10157 William <wmorgan-sup at masanjin.net>
  10158 
  10159 From nicolas.pouillard@gmail.com  Tue Jan 26 10:50:30 2010
  10160 From: nicolas.pouillard@gmail.com (Nicolas Pouillard)
  10161 Date: Tue, 26 Jan 2010 07:50:30 -0800 (PST)
  10162 Subject: [sup-devel] Fwd: Re: Sup 0.10 released
  10163 In-Reply-To: <1264512093-sup-8869@masanjin.net>
  10164 References: <1264454003-sup-9657@masanjin.net> <1264456949-sup-3@zyrg.net>
  10165 	<1264462577-sup-3137@zyrg.net> <1264512093-sup-8869@masanjin.net>
  10166 Message-ID: <4b5f0f46.1067f10a.2eaa.ffffaccd@mx.google.com>
  10167 
  10168 On Tue, 26 Jan 2010 08:22:09 -0500, William Morgan <wmorgan-sup at masanjin.net> wrote:
  10169 > Reformatted excerpts from Rich Lane's message of 2010-01-25:
  10170 > > I think I fixed it. Please try xapian-full 1.1.3.1 from gemcutter.
  10171 > 
  10172 > Works great. Nice one.
  10173 > 
  10174 > I'm going to release an 0.10.2 that has deps on that and ncursesw.
  10175 
  10176 Yes worked great for me too.
  10177 
  10178 -- 
  10179 Nicolas Pouillard
  10180 http://nicolaspouillard.fr
  10181 
  10182 From sup-bugs@masanjin.net  Wed Jan 27 03:03:58 2010
  10183 From: sup-bugs@masanjin.net (anonymous)
  10184 Date: Wed, 27 Jan 2010 08:03:58 +0000
  10185 Subject: [sup-devel] [issue51] Crash on sup start
  10186 In-Reply-To: <1264579438.47.0.202537444992.issue51@masanjin.net>
  10187 Message-ID: <1264579438.47.0.202537444992.issue51@masanjin.net>
  10188 
  10189 
  10190 New submission from anonymous:
  10191 
  10192 sup crashes on startup.
  10193 
  10194 ----------
  10195 files: exception-log.txt
  10196 messages: 122
  10197 nosy: anonymous
  10198 priority: bug
  10199 ruby_version: ruby 1.8.6
  10200 status: unread
  10201 sup_version: sup vgit
  10202 title: Crash on sup start
  10203 
  10204 _________________________________________
  10205 Sup issue tracker <sup-bugs at masanjin.net>
  10206 <http://masanjin.net/sup-bugs/issue51>
  10207 _________________________________________
  10208 -------------- next part --------------
  10209 --- RuntimeError from thread: load threads for thread-index-mode
  10210 wrong id called on nil
  10211 ./lib/sup.rb:17:in `id'
  10212 ./lib/sup/modes/thread-index-mode.rb:226:in `update'
  10213 ./lib/sup/hook.rb:122:in `sort_by'
  10214 ./lib/sup/modes/thread-index-mode.rb:226:in `each'
  10215 ./lib/sup/modes/thread-index-mode.rb:226:in `sort_by'
  10216 ./lib/sup/modes/thread-index-mode.rb:226:in `update'
  10217 ./lib/sup/modes/thread-index-mode.rb:224:in `synchronize'
  10218 ./lib/sup/modes/thread-index-mode.rb:224:in `update'
  10219 ./lib/sup/modes/thread-index-mode.rb:642:in `__unprotected_load_n_threads'
  10220 (eval):12:in `load_n_threads'
  10221 ./lib/sup/modes/thread-index-mode.rb:614:in `load_n_threads_background'
  10222 ./lib/sup.rb:78:in `reporting_thread'
  10223 ./lib/sup.rb:76:in `initialize'
  10224 ./lib/sup.rb:76:in `new'
  10225 ./lib/sup.rb:76:in `reporting_thread'
  10226 ./lib/sup/modes/thread-index-mode.rb:613:in `load_n_threads_background'
  10227 ./lib/sup/modes/thread-index-mode.rb:684:in `__unprotected_load_threads'
  10228 (eval):12:in `load_threads'
  10229 bin/sup:231
  10230 
  10231 From sup-bugs@masanjin.net  Wed Jan 27 07:46:54 2010
  10232 From: sup-bugs@masanjin.net (Shreyank Gupta)
  10233 Date: Wed, 27 Jan 2010 12:46:54 +0000
  10234 Subject: [sup-devel] [issue52] Crash on sup start
  10235 In-Reply-To: <1264596414.87.0.250405531257.issue52@masanjin.net>
  10236 Message-ID: <1264596414.87.0.250405531257.issue52@masanjin.net>
  10237 
  10238 
  10239 New submission from Shreyank Gupta <shreyankg at gmail.com>:
  10240 
  10241 Crashes on start.
  10242 
  10243 ----------
  10244 files: exception-log.txt
  10245 messages: 123
  10246 nosy: shreyankg
  10247 priority: bug
  10248 ruby_version: ruby 1.8.6
  10249 status: unread
  10250 sup_version: sup v0.10.2
  10251 title: Crash on sup start
  10252 
  10253 _________________________________________
  10254 Sup issue tracker <sup-bugs at masanjin.net>
  10255 <http://masanjin.net/sup-bugs/issue52>
  10256 _________________________________________
  10257 -------------- next part --------------
  10258 --- RuntimeError from thread: main
  10259 This Sup version expects a v1 index, but you have an existing v2 index. Please downgrade to your previous version and dump your labels before upgrading to this version (then run sup-sync --restore).
  10260 /usr/lib/ruby/gems/1.8/gems/sup-0.10.2/lib/sup/xapian_index.rb:41:in `load_index'
  10261 /usr/lib/ruby/gems/1.8/gems/sup-0.10.2/lib/sup/index.rb:71:in `load'
  10262 /usr/lib/ruby/gems/1.8/gems/sup-0.10.2/lib/sup/index.rb:236:in `send'
  10263 /usr/lib/ruby/gems/1.8/gems/sup-0.10.2/lib/sup/index.rb:236:in `method_missing'
  10264 /usr/lib/ruby/gems/1.8/gems/sup-0.10.2/bin/sup:169
  10265 /usr/bin/sup:19:in `load'
  10266 /usr/bin/sup:19
  10267 
  10268 From sup-bugs@masanjin.net  Wed Jan 27 16:11:48 2010
  10269 From: sup-bugs@masanjin.net (Anirudh Sanjeev)
  10270 Date: Wed, 27 Jan 2010 21:11:48 +0000
  10271 Subject: [sup-devel] [issue53] Error if the composed text has tabs in the
  10272 	first character
  10273 In-Reply-To: <1264626708.47.0.495243760209.issue53@masanjin.net>
  10274 Message-ID: <1264626708.47.0.495243760209.issue53@masanjin.net>
  10275 
  10276 
  10277 New submission from Anirudh Sanjeev <anirudh at anirudhsanjeev.org>:
  10278 
  10279 Steps to reproduce:
  10280 1. Compose message with a tab as a first character
  10281 2. View composed message in the compose-mode
  10282 
  10283 It looks like this in my text editor:
  10284 http://imgur.com/NH2Rz.png
  10285 
  10286 Here's how it looks like in compose mode. Note how the last few characters of
  10287 the compose mode is truncated.
  10288 http://imgur.com/xdL0U.png
  10289 
  10290 ----------
  10291 messages: 124
  10292 nosy: anirudhs
  10293 priority: bug
  10294 ruby_version: 1.8
  10295 status: unread
  10296 sup_version: next
  10297 title: Error if the composed text has tabs in the first character
  10298 
  10299 _________________________________________
  10300 Sup issue tracker <sup-bugs at masanjin.net>
  10301 <http://masanjin.net/sup-bugs/issue53>
  10302 _________________________________________
  10303 
  10304 From marka@pobox.com  Wed Jan 27 16:57:33 2010
  10305 From: marka@pobox.com (Mark Alexander)
  10306 Date: Wed, 27 Jan 2010 16:57:33 -0500
  10307 Subject: [sup-devel] [issue53] Error if the composed text has tabs in
  10308 	the first character
  10309 In-Reply-To: <1264626708.47.0.495243760209.issue53@masanjin.net>
  10310 References: <1264626708.47.0.495243760209.issue53@masanjin.net>
  10311 	<1264626708.47.0.495243760209.issue53@masanjin.net>
  10312 Message-ID: <a412e2a71001271357p2885d513k838587576febecb1@mail.gmail.com>
  10313 
  10314 I've been noticing this problem for a long time now.
  10315 I think it happens with tabs anywhere in the
  10316 message, or perhaps at the beginning of lines,
  10317 but I haven't played with it enough to know for sure.
  10318 
  10319 From tero@tilus.net  Wed Jan 27 17:15:19 2010
  10320 From: tero@tilus.net (Tero Tilus)
  10321 Date: Thu, 28 Jan 2010 00:15:19 +0200
  10322 Subject: [sup-devel] [issue53] Error if the composed text has tabs in
  10323 	the first character
  10324 In-Reply-To: <1264626708.47.0.495243760209.issue53@masanjin.net>
  10325 References: <1264626708.47.0.495243760209.issue53@masanjin.net>
  10326 Message-ID: <1264630303-sup-9772@tilus.net>
  10327 
  10328 Anirudh Sanjeev, 2010-01-27 23:11:
  10329 > Steps to reproduce:
  10330 > 1. Compose message with a tab as a first character
  10331 > 2. View composed message in the compose-mode
  10332 
  10333 Looks like tabs are counted as 1 (instead of 8) when calculating
  10334 string display width.  Dunno why this did not affect thread-view-mode
  10335 thought.  Patch attached.
  10336 
  10337 -- 
  10338 Tero Tilus ## 050 3635 235 ## http://tero.tilus.net/
  10339 -------------- next part --------------
  10340 A non-text attachment was scrubbed...
  10341 Name: 0001-Count-tabs-as-8-chars-when-calculating-display-lengt.patch
  10342 Type: application/octet-stream
  10343 Size: 620 bytes
  10344 Desc: not available
  10345 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100128/9a82a235/attachment.obj>
  10346 
  10347 From rlane@club.cc.cmu.edu  Wed Jan 27 17:29:09 2010
  10348 From: rlane@club.cc.cmu.edu (Rich Lane)
  10349 Date: Wed, 27 Jan 2010 17:29:09 -0500
  10350 Subject: [sup-devel] [issue53] Error if the composed text has tabs in
  10351 	the first character
  10352 In-Reply-To: <a412e2a71001271357p2885d513k838587576febecb1@mail.gmail.com>
  10353 References: <1264626708.47.0.495243760209.issue53@masanjin.net>
  10354 	<a412e2a71001271357p2885d513k838587576febecb1@mail.gmail.com>
  10355 Message-ID: <1264629880-sup-9232@zyrg.net>
  10356 
  10357 Excerpts from Mark Alexander's message of 2010-01-27 16:57:33 -0500:
  10358 > I've been noticing this problem for a long time now.
  10359 > I think it happens with tabs anywhere in the
  10360 > message, or perhaps at the beginning of lines,
  10361 > but I haven't played with it enough to know for sure.
  10362 
  10363 Sup assumes that 1 codepoint == 1 screen cell. This also causes problems
  10364 with double-width Chinese(?) characters. William has suggested using
  10365 wc[s]width, and now that we've got our own fork of ncurses-ruby we might
  10366 as well stick it in there. I looked at it briefly and iirc the
  10367 troublesome part was getting a wchar_t from the bytes in a Ruby string.
  10368 
  10369 Tabs are funny because their width depends on their position. I say
  10370 replace all tabs with 2 spaces before calling ncurses.
  10371 
  10372 From sup-bugs@masanjin.net  Wed Jan 27 17:47:53 2010
  10373 From: sup-bugs@masanjin.net (Tero Tilus)
  10374 Date: Wed, 27 Jan 2010 22:47:53 +0000
  10375 Subject: [sup-devel] [issue54] Log-mode and poll-mode buffers should not be
  10376 	killable
  10377 In-Reply-To: <1264632472.97.0.545373102631.issue54@masanjin.net>
  10378 Message-ID: <1264632472.97.0.545373102631.issue54@masanjin.net>
  10379 
  10380 
  10381 New submission from Tero Tilus <tero at tilus.net>:
  10382 
  10383 [ this is a copy from <http://masanjin.net/sup-bugs/issue4> ]
  10384 
  10385 As a related point, can I make it so that the log-mode and poll-mode buffers
  10386 aren't killable with 'x'? I get in the habit of pressing 'x', and occasionally
  10387 forget that when I'm viewing one of those buffers, I need to press 'I' instead.
  10388 
  10389 ----------
  10390 messages: 129
  10391 nosy: terotil
  10392 priority: feature request
  10393 ruby_version: any
  10394 status: unread
  10395 sup_version: 0.10
  10396 title: Log-mode and poll-mode buffers should not be killable
  10397 
  10398 _________________________________________
  10399 Sup issue tracker <sup-bugs at masanjin.net>
  10400 <http://masanjin.net/sup-bugs/issue54>
  10401 _________________________________________
  10402 
  10403 From hyperbolist@gmail.com  Wed Jan 27 21:48:43 2010
  10404 From: hyperbolist@gmail.com (Eric Sherman)
  10405 Date: Wed, 27 Jan 2010 21:48:43 -0500
  10406 Subject: [sup-devel] [PATCH] [issue54] log-mode and poll-mode buffers are
  10407 	not killable
  10408 In-Reply-To: <1264632472.97.0.545373102631.issue54@masanjin.net>
  10409 References: <1264632472.97.0.545373102631.issue54@masanjin.net>
  10410 Message-ID: <1264646626-sup-7355@changeling.local>
  10411 
  10412 ---
  10413  lib/sup/modes/log-mode.rb  |    2 ++
  10414  lib/sup/modes/poll-mode.rb |    2 ++
  10415  2 files changed, 4 insertions(+), 0 deletions(-)
  10416 
  10417 diff --git a/lib/sup/modes/log-mode.rb b/lib/sup/modes/log-mode.rb
  10418 index de320ce..e583caf 100644
  10419 --- a/lib/sup/modes/log-mode.rb
  10420 +++ b/lib/sup/modes/log-mode.rb
  10421 @@ -52,6 +52,8 @@ class LogMode < TextMode
  10422      self.text = ""
  10423      super
  10424    end
  10425 +
  10426 +  def killable?; false; end
  10427  end
  10428  
  10429  end
  10430 diff --git a/lib/sup/modes/poll-mode.rb b/lib/sup/modes/poll-mode.rb
  10431 index cf61343..deb22d6 100644
  10432 --- a/lib/sup/modes/poll-mode.rb
  10433 +++ b/lib/sup/modes/poll-mode.rb
  10434 @@ -14,6 +14,8 @@ class PollMode < LogMode
  10435      self << "Poll started at #{Time.now}\n"
  10436      PollManager.do_poll { |s| self << (s + "\n") }
  10437    end
  10438 +
  10439 +  def killable?; false; end
  10440  end
  10441  
  10442  end
  10443 -- 
  10444 1.6.6
  10445 
  10446 From sup-bugs@masanjin.net  Thu Jan 28 03:02:43 2010
  10447 From: sup-bugs@masanjin.net (anonymous)
  10448 Date: Thu, 28 Jan 2010 08:02:43 +0000
  10449 Subject: [sup-devel] [issue55] undefined method `>=' for true:TrueClass
  10450 In-Reply-To: <1264665763.28.0.0069731812863.issue55@masanjin.net>
  10451 Message-ID: <1264665763.28.0.0069731812863.issue55@masanjin.net>
  10452 
  10453 
  10454 New submission from anonymous:
  10455 
  10456 Source#current_offset= returns true instead of the set value, causing
  10457 Source#done? to blow up on (self.cur_offset ||= start_offset) >= end_offset
  10458 
  10459 The fix is to swap the two lines in Source#current_offset= so that it returns
  10460 the value:
  10461 
  10462   def cur_offset= o
  10463     @dirty = true
  10464     @cur_offset = o
  10465   end
  10466 
  10467 As it is in 0.10.2 it returns the value for @dirty instead
  10468 
  10469 ----------
  10470 files: exception-log.txt
  10471 messages: 139
  10472 nosy: anonymous
  10473 priority: bug
  10474 ruby_version: 1.9.1
  10475 status: unread
  10476 sup_version: 0.10.2
  10477 title: undefined method `>=' for true:TrueClass
  10478 
  10479 _________________________________________
  10480 Sup issue tracker <sup-bugs at masanjin.net>
  10481 <http://masanjin.net/sup-bugs/issue55>
  10482 _________________________________________
  10483 -------------- next part --------------
  10484 --- NoMethodError from thread: poll after loading inbox
  10485 undefined method `>=' for true:TrueClass
  10486 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/source.rb:88:in `done?'
  10487 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/util.rb:599:in `__pass'
  10488 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/util.rb:586:in `method_missing'
  10489 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/poll.rb:100:in `block (2 levels) in do_poll'
  10490 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/poll.rb:97:in `each'
  10491 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/poll.rb:97:in `block in do_poll'
  10492 <internal:prelude>:8:in `synchronize'
  10493 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/poll.rb:96:in `do_poll'
  10494 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/util.rb:559:in `method_missing'
  10495 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/modes/poll-mode.rb:15:in `poll'
  10496 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/poll.rb:47:in `poll_with_sources'
  10497 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/poll.rb:62:in `poll'
  10498 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup/util.rb:559:in `method_missing'
  10499 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/bin/sup:226:in `block (2 levels) in <module:Redwood>'
  10500 /usr/local/lib/ruby-1.9/gems/1.9.1/gems/sup-0.10.2/lib/sup.rb:77:in `block in reporting_thread'
  10501 
  10502 From sup-bugs@masanjin.net  Thu Jan 28 07:21:48 2010
  10503 From: sup-bugs@masanjin.net (ideesnoires)
  10504 Date: Thu, 28 Jan 2010 12:21:48 +0000
  10505 Subject: [sup-devel] [issue56] Sup crashes while saving changes
  10506 In-Reply-To: <1264681308.87.0.11225407467.issue56@masanjin.net>
  10507 Message-ID: <1264681308.87.0.11225407467.issue56@masanjin.net>
  10508 
  10509 
  10510 New submission from ideesnoires <ideesnoires at gmail.com>:
  10511 
  10512 I'm running sup with the ncurses patch as specified in 
  10513 http://sup.rubyforge.org/wiki/wiki.pl?UTF8 
  10514 when i try to save the modified index with $ sup just crashes and leaves 
  10515 following exception behind: (also in exception log)
  10516 
  10517 
  10518 --- NoMethodError from thread: saving thread
  10519 undefined method `save_state' for #<Redwood::Thread:0x7f684ef5f998>
  10520 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:480:in `actually_save'
  10521 ./lib/sup/hook.rb:122:in `each_with_index'
  10522 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:478:in `each'
  10523 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:478:in `each_with_index'
  10524 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:478:in `actually_save'
  10525 ./lib/sup/buffer.rb:721:in `say'
  10526 ./lib/sup/util.rb:559:in `send'
  10527 ./lib/sup/util.rb:559:in `method_missing'
  10528 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:477:in `actually_save'
  10529 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:472:in `synchronize'
  10530 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:472:in `actually_save'
  10531 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:465:in `save'
  10532 ./lib/sup.rb:78:in `reporting_thread'
  10533 ./lib/sup.rb:76:in `initialize'
  10534 ./lib/sup.rb:76:in `new'
  10535 ./lib/sup.rb:76:in `reporting_thread'
  10536 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:465:in `save'
  10537 ./lib/sup/mode.rb:51:in `send'
  10538 ./lib/sup/mode.rb:51:in `handle_input'
  10539 ./lib/sup/buffer.rb:272:in `handle_input'
  10540 bin/sup:276
  10541 
  10542 ----------
  10543 files: exception-log.txt
  10544 messages: 140
  10545 nosy: ideesnoires
  10546 priority: bug
  10547 ruby_version: 1.8
  10548 status: unread
  10549 sup_version: next rev. 117b4f0
  10550 title: Sup crashes while saving changes
  10551 
  10552 _________________________________________
  10553 Sup issue tracker <sup-bugs at masanjin.net>
  10554 <http://masanjin.net/sup-bugs/issue56>
  10555 _________________________________________
  10556 -------------- next part --------------
  10557 --- NoMethodError from thread: saving thread
  10558 undefined method `save_state' for #<Redwood::Thread:0x7f684ef5f998>
  10559 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:480:in `actually_save'
  10560 ./lib/sup/hook.rb:122:in `each_with_index'
  10561 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:478:in `each'
  10562 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:478:in `each_with_index'
  10563 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:478:in `actually_save'
  10564 ./lib/sup/buffer.rb:721:in `say'
  10565 ./lib/sup/util.rb:559:in `send'
  10566 ./lib/sup/util.rb:559:in `method_missing'
  10567 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:477:in `actually_save'
  10568 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:472:in `synchronize'
  10569 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:472:in `actually_save'
  10570 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:465:in `save'
  10571 ./lib/sup.rb:78:in `reporting_thread'
  10572 ./lib/sup.rb:76:in `initialize'
  10573 ./lib/sup.rb:76:in `new'
  10574 ./lib/sup.rb:76:in `reporting_thread'
  10575 /usr/lib/ruby/1.8/sup/modes/thread-index-mode.rb:465:in `save'
  10576 ./lib/sup/mode.rb:51:in `send'
  10577 ./lib/sup/mode.rb:51:in `handle_input'
  10578 ./lib/sup/buffer.rb:272:in `handle_input'
  10579 bin/sup:276
  10580 
  10581 From hyperbolist@gmail.com  Thu Jan 28 08:46:25 2010
  10582 From: hyperbolist@gmail.com (Eric Sherman)
  10583 Date: Thu, 28 Jan 2010 08:46:25 -0500
  10584 Subject: [sup-devel] [PATCH] [issue54] log-mode and poll-mode buffers
  10585 	are not killable
  10586 In-Reply-To: <1264646626-sup-7355@changeling.local>
  10587 References: <1264632472.97.0.545373102631.issue54@masanjin.net>
  10588 	<1264646626-sup-7355@changeling.local>
  10589 Message-ID: <1264686346-sup-9488@changeling.local>
  10590 
  10591 That doesn't quite work, as sup won't quit.  Another patch on its way.
  10592 
  10593 From hyperbolist@gmail.com  Thu Jan 28 09:07:28 2010
  10594 From: hyperbolist@gmail.com (Eric Sherman)
  10595 Date: Thu, 28 Jan 2010 09:07:28 -0500
  10596 Subject: [sup-devel] [PATCHv2] [issue54] log-mode and poll-mode buffers are
  10597 	not killable
  10598 In-Reply-To: <1264632472.97.0.545373102631.issue54@masanjin.net>
  10599 References: <1264632472.97.0.545373102631.issue54@masanjin.net>
  10600 Message-ID: <1264687215-sup-8249@changeling.local>
  10601 
  10602 Oops.  Now, with the ability to quit sup.
  10603 
  10604 ---
  10605  lib/sup/buffer.rb          |    4 ++--
  10606  lib/sup/modes/log-mode.rb  |    2 ++
  10607  lib/sup/modes/poll-mode.rb |    2 ++
  10608  3 files changed, 6 insertions(+), 2 deletions(-)
  10609 
  10610 diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb
  10611 index 990dd4a..5fb1047 100644
  10612 --- a/lib/sup/buffer.rb
  10613 +++ b/lib/sup/buffer.rb
  10614 @@ -414,8 +414,8 @@ EOS
  10615  
  10616    def kill_all_buffers_safely
  10617      until @buffers.empty?
  10618 -      ## inbox mode always claims it's unkillable. we'll ignore it.
  10619 -      return false unless @buffers.last.mode.is_a?(InboxMode) || @buffers.last.mode.killable?
  10620 +      ## inbox, log and poll modes always claim they're unkillable. we'll ignore them.
  10621 +      return false unless @buffers.last.mode.is_a?(InboxMode) || @buffers.last.mode.is_a?(LogMode) ||  @buffers.last.mode.is_a?(PollMode) || @buffers.last.mode.killable?
  10622        kill_buffer @buffers.last
  10623      end
  10624      true
  10625 diff --git a/lib/sup/modes/log-mode.rb b/lib/sup/modes/log-mode.rb
  10626 index de320ce..e583caf 100644
  10627 --- a/lib/sup/modes/log-mode.rb
  10628 +++ b/lib/sup/modes/log-mode.rb
  10629 @@ -52,6 +52,8 @@ class LogMode < TextMode
  10630      self.text = ""
  10631      super
  10632    end
  10633 +
  10634 +  def killable?; false; end
  10635  end
  10636  
  10637  end
  10638 diff --git a/lib/sup/modes/poll-mode.rb b/lib/sup/modes/poll-mode.rb
  10639 index cf61343..deb22d6 100644
  10640 --- a/lib/sup/modes/poll-mode.rb
  10641 +++ b/lib/sup/modes/poll-mode.rb
  10642 @@ -14,6 +14,8 @@ class PollMode < LogMode
  10643      self << "Poll started at #{Time.now}\n"
  10644      PollManager.do_poll { |s| self << (s + "\n") }
  10645    end
  10646 +
  10647 +  def killable?; false; end
  10648  end
  10649  
  10650  end
  10651 -- 
  10652 1.6.6
  10653 
  10654 From sup-bugs@masanjin.net  Thu Jan 28 15:06:04 2010
  10655 From: sup-bugs@masanjin.net (Anirudh Sanjeev)
  10656 Date: Thu, 28 Jan 2010 20:06:04 +0000
  10657 Subject: [sup-devel] [issue57] Request: Flush changes periodically
  10658 In-Reply-To: <1264709164.82.0.12859120302.issue57@masanjin.net>
  10659 Message-ID: <1264709164.82.0.12859120302.issue57@masanjin.net>
  10660 
  10661 
  10662 New submission from Anirudh Sanjeev <anirudh at anirudhsanjeev.org>:
  10663 
  10664 Can there be an optional functionality to flush changes to disk every 10-15
  10665 minutes, instead of having to press $ every time
  10666 
  10667 Rationale: I'm in a place where power cuts are extremely frequent. I keep
  10668 forgetting to flush changes manually requiring me to re-delete and archive my
  10669 messages every time I reboot and restart sup.
  10670 
  10671 I run sup off of git 'next' head. A patch which will hard-code this
  10672 functionality would be fine as well. Alternatively, is there a command I can
  10673 call via a cron job to do this?
  10674 
  10675 Thanks!
  10676 
  10677 ----------
  10678 messages: 142
  10679 nosy: anirudhs
  10680 priority: feature request
  10681 ruby_version: 1.8
  10682 status: unread
  10683 sup_version: git/next
  10684 title: Request: Flush changes periodically
  10685 
  10686 _________________________________________
  10687 Sup issue tracker <sup-bugs at masanjin.net>
  10688 <http://masanjin.net/sup-bugs/issue57>
  10689 _________________________________________
  10690 
  10691 From hyperbolist@gmail.com  Thu Jan 28 15:21:54 2010
  10692 From: hyperbolist@gmail.com (Eric Sherman)
  10693 Date: Thu, 28 Jan 2010 15:21:54 -0500
  10694 Subject: [sup-devel] [issue57] Request: Flush changes periodically
  10695 In-Reply-To: <1264709164.82.0.12859120302.issue57@masanjin.net>
  10696 References: <1264709164.82.0.12859120302.issue57@masanjin.net>
  10697 Message-ID: <1264709474-sup-4387@changeling.local>
  10698 
  10699 Excerpts from Anirudh Sanjeev's message of Thu Jan 28 15:06:04 -0500 2010:
  10700 > 
  10701 > Can there be an optional functionality to flush changes to disk every 10-15
  10702 > minutes, instead of having to press $ every time
  10703 
  10704 You may want to try these patches:
  10705 [PATCHv3] idle and unidle updates [1]
  10706 [PATCH] flush index on idle [2]
  10707 
  10708 The first one relays the idle and unidle updates, and the second one will 
  10709 actually perform the flush when it gets an idle update.
  10710 
  10711 And you may be interested in this one too:
  10712 [PATCHv5] [issue14] poll updates accumulate while idle [3]
  10713 
  10714 I use these and they meet my needs.
  10715 
  10716 [1]: http://rubyforge.org/pipermail/sup-devel/2010-January/000285.html
  10717 [2]: http://rubyforge.org/pipermail/sup-devel/2010-January/000274.html
  10718 [3]: http://rubyforge.org/pipermail/sup-devel/2010-January/000241.html
  10719 
  10720 From sup-bugs@masanjin.net  Fri Jan 29 05:14:40 2010
  10721 From: sup-bugs@masanjin.net (Gregor Hoffleit)
  10722 Date: Fri, 29 Jan 2010 10:14:40 +0000
  10723 Subject: [sup-devel] [issue58] Set background for starred column
  10724 In-Reply-To: <1264760080.41.0.139357784083.issue58@masanjin.net>
  10725 Message-ID: <1264760080.41.0.139357784083.issue58@masanjin.net>
  10726 
  10727 
  10728 New submission from Gregor Hoffleit <gregor at hoffleit.de>:
  10729 
  10730 For the sake of consistency, Sup should always use the starred_color for the 
  10731 'starred' column in the thread-index-mode, whether there's a star or a blank.
  10732 
  10733 Rationale: With this patch, I'm able to set the background color of the thread-
  10734 index to bg:7 without having to change my term's background color. Without the 
  10735 patch, the background color shines through in the starred column.
  10736 
  10737 ----------
  10738 files: bg-starred.diff
  10739 messages: 143
  10740 nosy: flight
  10741 priority: bug
  10742 ruby_version: 1.8.5
  10743 status: unread
  10744 sup_version: 0.10.2
  10745 title: Set background for starred column
  10746 
  10747 _________________________________________
  10748 Sup issue tracker <sup-bugs at masanjin.net>
  10749 <http://masanjin.net/sup-bugs/issue58>
  10750 _________________________________________
  10751 -------------- next part --------------
  10752 A non-text attachment was scrubbed...
  10753 Name: bg-starred.diff
  10754 Type: application/octet-stream
  10755 Size: 483 bytes
  10756 Desc: not available
  10757 URL: <http://rubyforge.org/pipermail/sup-devel/attachments/20100129/8e697dac/attachment.obj>
  10758 
  10759 From sup-bugs@masanjin.net  Sun Jan 31 16:38:24 2010
  10760 From: sup-bugs@masanjin.net (anonymous)
  10761 Date: Sun, 31 Jan 2010 21:38:24 +0000
  10762 Subject: [sup-devel] [issue59] gem install sup on osx 10.6 fails due to
  10763 	.bundle instead of	.so being built in xapian-full
  10764 In-Reply-To: <1264973904.76.0.328276768293.issue59@masanjin.net>
  10765 Message-ID: <1264973904.76.0.328276768293.issue59@masanjin.net>
  10766 
  10767 
  10768 New submission from anonymous:
  10769 
  10770 on a default os X 10.6 machine (after updating rubygems) doing a 'gem sup
  10771 install' fails:
  10772 
  10773 The problem is xapian-full is making a .bundle instead of a .so. It's easy to
  10774 change to make a .so file (just remove the -bundle and chenge the output to .so,
  10775 but I know nothing of Ruby, or how to make ruby gems behave.  I can manually
  10776 build the .so file, but then doing another 'gem install sup' just replaces the
  10777 directory I just fixed.  So I don't even know of how to work-around this.
  10778 
  10779 Below is the evil details:
  10780 
  10781 p.cc
  10782 libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I..
  10783 -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0
  10784 -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0
  10785 -fno-strict-aliasing -Wall -Wno-unused -Wno-uninitialized -fvisibility=hidden
  10786 -I/Users/tara/.gem/ruby/1.8/gems/xapian-full-1.1.3.1/xapian-core-1.1.3/include
  10787 -g -O2 -MT xapian_wrap.lo -MD -MP -MF .deps/xapian_wrap.Tpo -c xapian_wrap.cc 
  10788 -fno-common -DPIC -o .libs/xapian_wrap.o
  10789 mv -f .deps/xapian_wrap.Tpo .deps/xapian_wrap.Plo
  10790 /bin/sh ../libtool  --tag=CXX   --mode=link g++ -fno-strict-aliasing -Wall
  10791 -Wno-unused -Wno-uninitialized -fvisibility=hidden
  10792 -I/Users/tara/.gem/ruby/1.8/gems/xapian-full-1.1.3.1/xapian-core-1.1.3/include
  10793 -g -O2 -avoid-version -module -shrext ".bundle"   -o _xapian.la -rpath
  10794 /Library/Ruby/Site/1.8/universal-darwin10.0 xapian_wrap.lo
  10795 /Users/tara/.gem/ruby/1.8/gems/xapian-full-1.1.3.1/xapian-core-1.1.3/libxapian-1.1.la
  10796 -lstdc++  
  10797 libtool: link: g++ -Wl,-undefined -Wl,dynamic_lookup -o .libs/_xapian.bundle
  10798 -bundle  .libs/xapian_wrap.o  
  10799 /Users/tara/.gem/ruby/1.8/gems/xapian-full-1.1.3.1/xapian-core-1.1.3/.libs/libxapian-1.1.dylib
  10800 -lz -lstdc++   
  10801 libtool: link: dsymutil .libs/_xapian.bundle || :
  10802 libtool: link: ( cd ".libs" && rm -f "_xapian.la" && ln -s "../_xapian.la"
  10803 "_xapian.la" )
  10804 mkdir -p lib
  10805 cp xapian-bindings-1.1.3/ruby/.libs/_xapian.so lib
  10806 cp: xapian-bindings-1.1.3/ruby/.libs/_xapian.so: No such file or directory
  10807 rake aborted!
  10808 
  10809 /Users/tara/.gem/ruby/1.8/gems/xapian-full-1.1.3.1/rakefile:6:in `system!'
  10810 (See full trace by running task with --trace)
  10811 
  10812 
  10813 Gem files will remain installed in
  10814 /Users/tara/.gem/ruby/1.8/gems/xapian-full-1.1.3.1 for inspection.
  10815 Results logged to /Users/tara/.gem/ruby/1.8/gems/xapian-full-1.1.3.1/gem_make.out
  10816 tara at mudita ~ % gem install ferret
  10817 
  10818 ----------
  10819 messages: 144
  10820 nosy: anonymous
  10821 priority: bug
  10822 ruby_version: 1.8.7
  10823 status: unread
  10824 sup_version: 0.10.2
  10825 title: gem install sup on osx 10.6 fails due to .bundle instead of .so being built in xapian-full
  10826 
  10827 _________________________________________
  10828 Sup issue tracker <sup-bugs at masanjin.net>
  10829 <http://masanjin.net/sup-bugs/issue59>
  10830 _________________________________________
  10831 
  10832 From rlane@club.cc.cmu.edu  Sun Jan 31 17:53:45 2010
  10833 From: rlane@club.cc.cmu.edu (Rich Lane)
  10834 Date: Sun, 31 Jan 2010 17:53:45 -0500
  10835 Subject: [sup-devel] [issue59] gem install sup on osx 10.6 fails due to
  10836 	.bundle instead of .so being built in xapian-full
  10837 In-Reply-To: <1264973904.76.0.328276768293.issue59@masanjin.net>
  10838 References: <1264973904.76.0.328276768293.issue59@masanjin.net>
  10839 Message-ID: <1264978339-sup-4555@zyrg.net>
  10840 
  10841 Excerpts from anonymous's message of 2010-01-31 16:38:24 -0500:
  10842 > 
  10843 > New submission from anonymous:
  10844 > 
  10845 > on a default os X 10.6 machine (after updating rubygems) doing a 'gem sup
  10846 > install' fails:
  10847 > 
  10848 > The problem is xapian-full is making a .bundle instead of a .so. It's easy to
  10849 > change to make a .so file (just remove the -bundle and chenge the output to .so,
  10850 > but I know nothing of Ruby, or how to make ruby gems behave.  I can manually
  10851 > build the .so file, but then doing another 'gem install sup' just replaces the
  10852 > directory I just fixed.  So I don't even know of how to work-around this.
  10853 
  10854 I just pushed xapian-full-1.1.3.2 which should fix this issue.
  10855