sup 0.4 → 0.5

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

Potentially problematic release.


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

@@ -49,20 +49,28 @@ EOS
49
49
  k.add :unsubscribe_from_list, "Subscribe to/unsubscribe from mailing list", ")"
50
50
  k.add :pipe_message, "Pipe message or attachment to a shell command", '|'
51
51
 
52
- k.add_multi "(A)rchive/(d)elete/mark as (s)pam/mark as u(N)read:", '.' do |kk|
52
+ k.add_multi "(a)rchive/(d)elete/mark as (s)pam/mark as u(N)read:", '.' do |kk|
53
53
  kk.add :archive_and_kill, "Archive this thread and kill buffer", 'a'
54
54
  kk.add :delete_and_kill, "Delete this thread and kill buffer", 'd'
55
55
  kk.add :spam_and_kill, "Mark this thread as spam and kill buffer", 's'
56
56
  kk.add :unread_and_kill, "Mark this thread as unread and kill buffer", 'N'
57
57
  end
58
58
 
59
- k.add_multi "(A)rchive/(d)elete/mark as (s)pam/mark as u(N)read/do (n)othing:", ',' do |kk|
59
+ k.add_multi "(a)rchive/(d)elete/mark as (s)pam/mark as u(N)read/do (n)othing:", ',' do |kk|
60
60
  kk.add :archive_and_next, "Archive this thread, kill buffer, and view next", 'a'
61
61
  kk.add :delete_and_next, "Delete this thread, kill buffer, and view next", 'd'
62
62
  kk.add :spam_and_next, "Mark this thread as spam, kill buffer, and view next", 's'
63
63
  kk.add :unread_and_next, "Mark this thread as unread, kill buffer, and view next", 'N'
64
64
  kk.add :do_nothing_and_next, "Kill buffer, and view next", 'n'
65
65
  end
66
+
67
+ k.add_multi "(a)rchive/(d)elete/mark as (s)pam/mark as u(N)read/do (n)othing:", ']' do |kk|
68
+ kk.add :archive_and_prev, "Archive this thread, kill buffer, and view previous", 'a'
69
+ kk.add :delete_and_prev, "Delete this thread, kill buffer, and view previous", 'd'
70
+ kk.add :spam_and_prev, "Mark this thread as spam, kill buffer, and view previous", 's'
71
+ kk.add :unread_and_prev, "Mark this thread as unread, kill buffer, and view previous", 'N'
72
+ kk.add :do_nothing_and_prev, "Kill buffer, and view previous", 'n'
73
+ end
66
74
  end
67
75
 
68
76
  ## there are a couple important instance variables we hold to format
@@ -318,6 +326,8 @@ EOS
318
326
  end
319
327
  end
320
328
 
329
+ IDEAL_TOP_CONTEXT = 3 # try and give 3 rows of top context
330
+ IDEAL_LEFT_CONTEXT = 4 # try and give 4 columns of left context
321
331
  def jump_to_message m, loose_alignment=false
322
332
  l = @layout[m]
323
333
  left = l.depth * INDENT_SPACES
@@ -325,19 +335,20 @@ EOS
325
335
 
326
336
  ## jump to the top line
327
337
  if loose_alignment
328
- jump_to_line [l.top - 3, 0].max # give 3 lines of top context
338
+ jump_to_line [l.top - IDEAL_TOP_CONTEXT, 0].max # give 3 lines of top context
329
339
  else
330
340
  jump_to_line l.top
331
341
  end
332
342
 
333
343
  ## jump to the left column
334
- if loose_alignment
335
- ## try and give 4 columns of left context, but not if it means that
336
- ## the right of the message is truncated.
337
- jump_to_col [[left - 4, rightcol - l.width - 1].min, 0].max
338
- else
339
- jump_to_col left
340
- end
344
+ ideal_left = left +
345
+ if loose_alignment
346
+ -IDEAL_LEFT_CONTEXT + (l.width - buffer.content_width + IDEAL_LEFT_CONTEXT + 1).clamp(0, IDEAL_LEFT_CONTEXT)
347
+ else
348
+ 0
349
+ end
350
+
351
+ jump_to_col [ideal_left, 0].max
341
352
 
342
353
  ## either way, move the cursor to the first line
343
354
  set_cursor_pos l.top
@@ -380,6 +391,12 @@ EOS
380
391
  def unread_and_next; unread_and_then :next end
381
392
  def do_nothing_and_next; do_nothing_and_then :next end
382
393
 
394
+ def archive_and_prev; archive_and_then :prev end
395
+ def spam_and_prev; spam_and_then :prev end
396
+ def delete_and_prev; delete_and_then :prev end
397
+ def unread_and_prev; unread_and_then :prev end
398
+ def do_nothing_and_prev; do_nothing_and_then :prev end
399
+
383
400
  def archive_and_then op
384
401
  dispatch op do
385
402
  @thread.remove_label :inbox
@@ -416,15 +433,18 @@ EOS
416
433
  return if @dying
417
434
  @dying = true
418
435
 
436
+ l = lambda do
437
+ yield if block_given?
438
+ BufferManager.kill_buffer_safely buffer
439
+ end
440
+
419
441
  case op
420
442
  when :next
421
- @index_mode.launch_next_thread_after(@thread) do
422
- @thread.save Index if block_given? && yield
423
- BufferManager.kill_buffer_safely buffer
424
- end
443
+ @index_mode.launch_next_thread_after @thread, &l
444
+ when :prev
445
+ @index_mode.launch_prev_thread_before @thread, &l
425
446
  when :kill
426
- @thread.save Index if yield
427
- BufferManager.kill_buffer_safely buffer
447
+ l.call
428
448
  else
429
449
  raise ArgumentError, "unknown thread dispatch operation #{op.inspect}"
430
450
  end
@@ -9,7 +9,7 @@ class PersonManager
9
9
 
10
10
  ## read in stored people
11
11
  IO.readlines(fn).map do |l|
12
- l =~ /^(.*)?:\s+(\d+)\s+(.*)$/ or raise "can't parse: #{l}"
12
+ l =~ /^(.*)?:\s+(\d+)\s+(.*)$/ or next
13
13
  email, time, name = $1, $2, $3
14
14
  @@people[email] = Person.new name, email, time, false
15
15
  end if File.exists? fn
@@ -21,7 +21,7 @@ class PersonManager
21
21
  File.open(@fn, "w") do |f|
22
22
  @@people.each do |email, p|
23
23
  next if p.email == p.name
24
- next if p.email =~ /=/ # drop rfc2047-encoded, and lots of other useless emails. definitely a heuristic.
24
+ next if p.name =~ /=/ # drop rfc2047-encoded, and lots of other useless emails. definitely a heuristic.
25
25
  f.puts "#{p.email}: #{p.timestamp} #{p.name}"
26
26
  end
27
27
  end
@@ -162,6 +162,10 @@ class Person
162
162
  Person.new name, email
163
163
  end
164
164
 
165
+ def indexable_content
166
+ [name, email, email.split(/@/).first].join(" ")
167
+ end
168
+
165
169
  def eql? o; email.eql? o.email end
166
170
  def hash; email.hash end
167
171
  end
@@ -134,7 +134,7 @@ EOS
134
134
  ## labels. it is likely that callers will want to replace these with
135
135
  ## the index labels, if they exist, so that state is not lost when
136
136
  ## e.g. a new version of a message from a mailing list comes in.
137
- def add_messages_from source
137
+ def add_messages_from source, opts={}
138
138
  begin
139
139
  return if source.done? || source.has_errors?
140
140
 
@@ -156,8 +156,8 @@ EOS
156
156
 
157
157
  docid, entry = Index.load_entry_for_id m.id
158
158
  HookManager.run "before-add-message", :message => m
159
- m = yield(m, offset, entry) or next
160
- Index.sync_message m, docid, entry
159
+ m = yield(m, offset, entry) or next if block_given?
160
+ Index.sync_message m, docid, entry, opts
161
161
  UpdateManager.relay self, :added, m unless entry
162
162
  rescue MessageFormatError => e
163
163
  Redwood::log "ignoring erroneous message at #{source}##{offset}: #{e.message}"
@@ -22,10 +22,9 @@ class SentManager
22
22
  yield f
23
23
  end
24
24
 
25
- @source.each do |offset, labels|
26
- m = Message.new :source => @source, :source_info => offset, :labels => @source.labels
27
- Index.sync_message m
28
- UpdateManager.relay self, :added, m
25
+ PollManager.add_messages_from(@source) do |m, o, e|
26
+ m.remove_label :unread
27
+ m
29
28
  end
30
29
  end
31
30
  end
@@ -1,9 +1,11 @@
1
1
  module Redwood
2
2
 
3
3
  class Tagger
4
- def initialize mode
4
+ def initialize mode, noun="thread", plural_noun=nil
5
5
  @mode = mode
6
6
  @tagged = {}
7
+ @noun = noun
8
+ @plural_noun = plural_noun || (@noun + "s")
7
9
  end
8
10
 
9
11
  def tagged? o; @tagged[o]; end
@@ -21,7 +23,7 @@ class Tagger
21
23
  return
22
24
  end
23
25
 
24
- noun = num_tagged == 1 ? "thread" : "threads"
26
+ noun = num_tagged == 1 ? @noun : @plural_noun
25
27
 
26
28
  unless action
27
29
  c = BufferManager.ask_getch "apply to #{num_tagged} tagged #{noun}:"
@@ -100,7 +100,7 @@ class TextField
100
100
  Ncurses::Form::REQ_NEXT_CHAR
101
101
  when Ncurses::KEY_DC
102
102
  Ncurses::Form::REQ_DEL_CHAR
103
- when Ncurses::KEY_BACKSPACE
103
+ when Ncurses::KEY_BACKSPACE, 127 # 127 is also a backspace keysym
104
104
  Ncurses::Form::REQ_DEL_PREV
105
105
  when 1 #ctrl-a
106
106
  Ncurses::Form::REQ_BEG_FIELD
@@ -259,7 +259,7 @@ class ThreadSet
259
259
  @thread_by_subj = thread_by_subj
260
260
  end
261
261
 
262
- def thread_for_id mid; (c = @messages[mid]) && c.root.thread end
262
+ def thread_for_id mid; @messages.member?(mid) && @messages[mid].root.thread end
263
263
  def contains_id? id; @messages.member?(id) && !@messages[id].empty? end
264
264
  def thread_for m; thread_for_id m.id end
265
265
  def contains? m; contains_id? m.id end
@@ -324,7 +324,7 @@ class ThreadSet
324
324
  ## load in (at most) num number of threads from the index
325
325
  def load_n_threads num, opts={}
326
326
  @index.each_id_by_date opts do |mid, builder|
327
- break if size >= num
327
+ break if size >= num unless num == -1
328
328
  next if contains_id? mid
329
329
 
330
330
  m = builder.call
@@ -415,14 +415,8 @@ class ThreadSet
415
415
  ## that we first added a child message with a different
416
416
  ## subject)
417
417
  if root.thread
418
- unless @threads[key] == root.thread
419
- if @threads[key]
420
- root.thread.empty!
421
- @threads[key] << root
422
- root.thread = @threads[key]
423
- else
424
- @threads[key] = root.thread
425
- end
418
+ if @threads.member?(key) && @threads[key] != root.thread
419
+ @threads.delete key
426
420
  end
427
421
  else
428
422
  thread = @threads[key]
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'sup'
5
+ require 'mockfs/override.rb'
6
+
7
+ module Redwood
8
+ class TestMaildir < Test::Unit::TestCase
9
+
10
+ def setup
11
+ MockFS.mock = true
12
+ MockFS.dir.mkdir "maildir-test"
13
+ MockFS.dir.mkdir "maildir-test/cur"
14
+ MockFS.dir.mkdir "maildir-test/tmp"
15
+ MockFS.dir.mkdir "maildir-test/new"
16
+ end
17
+
18
+ def teardown
19
+ end
20
+
21
+ def test_empty_maildir
22
+ end
23
+ end
24
+
25
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sup
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.4"
4
+ version: "0.5"
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Morgan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-01-23 00:00:00 -08:00
12
+ date: 2008-04-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -121,6 +121,7 @@ files:
121
121
  - Manifest.txt
122
122
  - README.txt
123
123
  - Rakefile
124
+ - ReleaseNotes
124
125
  - bin/sup
125
126
  - bin/sup-add
126
127
  - bin/sup-config
@@ -218,3 +219,4 @@ specification_version: 2
218
219
  summary: A console-based email client with the best features of GMail, mutt, and emacs. Features full text search, labels, tagged operations, multiple buffers, recent contacts, and more.
219
220
  test_files:
220
221
  - test/test_message.rb
222
+ - test/test_maildir.rb