},
:editor => ENV["EDITOR"] || "/usr/bin/vim -f -c 'setlocal spell spelllang=en_us' -c 'set filetype=mail'",
:thread_by_subject => false,
+ :edit_signature => false,
}
begin
FileUtils.mkdir_p Redwood::BASE_DIR
module Redwood
class ComposeMode < EditMessageMode
- attr_reader :body, :header
-
def initialize opts={}
- super()
- @header = {
+ header = {
"From" => AccountManager.default_account.full_address,
- "Message-Id" => gen_message_id,
}
- @header["To"] = opts[:to].map { |p| p.full_address }.join(", ") if opts[:to]
- @header["Cc"] = opts[:cc].map { |p| p.full_address }.join(", ") if opts[:cc]
- @header["Bcc"] = opts[:bcc].map { |p| p.full_address }.join(", ") if opts[:bcc]
- @header["Subject"] = opts[:subj] if opts[:subj]
-
- @body = opts[:body] || []
- regen_text
- end
-
-protected
+ header["To"] = opts[:to].map { |p| p.full_address }.join(", ") if opts[:to]
+ header["Cc"] = opts[:cc].map { |p| p.full_address }.join(", ") if opts[:cc]
+ header["Bcc"] = opts[:bcc].map { |p| p.full_address }.join(", ") if opts[:bcc]
+ header["Subject"] = opts[:subj] if opts[:subj]
- def handle_new_text new_header, new_body
- @header = new_header
- @body = new_body
+ super :header => header, :body => (opts[:body] || [])
end
end
k.add :search, "Search for messages from particular people", 'S'
end
- def initialize mode = :regular
+ def initialize mode=:regular
@mode = mode
@tags = Tagger.new self
@num = nil
NON_EDITABLE_HEADERS = %w(Message-Id Date)
attr_reader :status
+ attr_accessor :body, :header
bool_reader :edited
register_keymap do |k|
k.add :save_as_draft, "Save as draft", 'P'
end
- def initialize *a
- super
+ def initialize opts={}
+ @header = opts.delete(:header) || {}
+ @body = opts.delete(:body) || []
+ @body += sig_lines if $config[:edit_signature]
@attachments = []
@edited = false
+ super opts
+ update
end
- def lines; @text.length; end
- def [] i; @text[i]; end
+ def lines; @text.length end
+ def [] i; @text[i] end
+
+ ## a hook
+ def handle_new_text header, body; end
def edit
@file = Tempfile.new "sup.#{self.class.name.gsub(/.*::/, '').camel_to_hyphy}"
- @file.puts header_lines(header - NON_EDITABLE_HEADERS)
+ @file.puts header_lines(@header - NON_EDITABLE_HEADERS)
@file.puts
- @file.puts body
+ @file.puts @body
@file.close
editor = $config[:editor] || ENV['EDITOR'] || "/usr/bin/vi"
BufferManager.shell_out "#{editor} #{@file.path}"
@edited = true if File.mtime(@file.path) > mtime
- new_header, new_body = parse_file(@file.path)
- NON_EDITABLE_HEADERS.each { |h| new_header[h] = header[h] if header[h] }
- handle_new_text new_header, new_body
+ header, @body = parse_file @file.path
+ @header = header - NON_EDITABLE_HEADERS
+ handle_new_text @header, @body
update
end
def update
regen_text
- buffer.mark_dirty
+ buffer.mark_dirty if buffer
end
def regen_text
- @text = header_lines(header - NON_EDITABLE_HEADERS) + [""] + body + sig_lines
+ @text = header_lines(@header - NON_EDITABLE_HEADERS) + [""] + @body
+ @text += sig_lines unless $config[:edit_signature]
end
def parse_file fn
def send_message
return unless edited? || BufferManager.ask_yes_or_no("Message unedited. Really send?")
- raise "no message id!" unless header["Message-Id"]
date = Time.now
from_email =
- if header["From"] =~ /<?(\S+@(\S+?))>?$/
+ if @header["From"] =~ /<?(\S+@(\S+?))>?$/
$1
else
AccountManager.default_account.email
BufferManager.flash "Saved for later editing."
end
+ ## this is going to change soon: draft messages (currently written
+ ## with full=false) will be output as yaml.
def write_message f, full=true, date=Time.now
- raise ArgumentError, "no pre-defined date: header allowed" if header["Date"]
- f.puts header_lines(header)
- f.puts "Date: #{date.rfc2822}"
+ raise ArgumentError, "no pre-defined date: header allowed" if @header["Date"]
+ f.puts header_lines(@header)
+ f.puts <<EOS
+Date: #{date.rfc2822}
+Message-Id: #{gen_message_id}
+EOS
if full
f.puts <<EOS
Mime-Version: 1.0
end
f.puts
- f.puts body.map { |l| l =~ /^From / ? ">#{l}" : l }
- f.puts sig_lines if full
+ f.puts @body.map { |l| l =~ /^From / ? ">#{l}" : l }
+ f.puts sig_lines if full unless $config[:edit_signature]
end
private
-
def sig_lines
- p = PersonManager.person_for header["From"]
+ p = PersonManager.person_for @header["From"]
sigfn = (AccountManager.account_for(p.email) ||
AccountManager.default_account).signature
module Redwood
class ForwardMode < EditMessageMode
- attr_reader :body, :header
-
def initialize m
- super()
- @header = {
+ super :header => {
"From" => AccountManager.default_account.full_address,
"Subject" => "Fwd: #{m.subj}",
- "Message-Id" => gen_message_id,
- }
- @body = forward_body_lines m
- regen_text
+ },
+ :body => forward_body_lines(m)
end
protected
m.basic_header_lines + [""] + m.basic_body_lines +
["--- End forwarded message ---"]
end
-
- def handle_new_text new_header, new_body
- @header = new_header
- @body = new_body
- end
end
end
attr_reader :curpos
- def initialize cursor_top=0, opts={}
- @cursor_top = cursor_top
- @curpos = cursor_top
+ def initialize opts={}
+ @cursor_top = @curpos = opts[:skip_top_rows] || 0
@load_more_callbacks = []
@load_more_callbacks_m = Mutex.new
@load_more_callbacks_active = false
end
def initialize message
- super 2, :twiddles => false
@m = message
## it's important to put this early because it forces a read of
## the full headers (most importantly the list-post header, if
## any)
- @body = reply_body_lines message
+ body = reply_body_lines message
from =
if @m.recipient_email
} if @m.is_list_message?
refs = gen_references
- mid = gen_message_id
@headers.each do |k, v|
@headers[k] = {
"To" => "",
"Bcc" => "",
"In-Reply-To" => "<#{@m.id}>",
"Subject" => Message.reify_subj(@m.subj),
- "Message-Id" => mid,
"References" => refs,
}.merge v
end
:recipient
end
- regen_text
+ super :header => @headers[@selected_type], :body => body,
+ :skip_top_rows => 2, :twiddles => false
end
- def lines; @text.length + 2; end
+ def lines; super + 2; end
def [] i
case i
when 0
- lame = []
- @type_labels.each do |t|
- lame << [(t == @selected_type ? :none_highlight : :none),
- "#{TYPE_DESCRIPTIONS[t]}"]
- lame << [:none, " "]
- end
- lame + [[:none, ""]]
+ @type_labels.inject([]) do |array, t|
+ array + [[(t == @selected_type ? :none_highlight : :none),
+ "#{TYPE_DESCRIPTIONS[t]}"], [:none, " "]]
+ end + [[:none, ""]]
when 1
""
else
- @text[i - 2]
+ super(i - 2)
end
end
protected
- def body; @body; end
- def header; @headers[@selected_type]; end
-
def reply_body_lines m
lines = ["Excerpts from #{@m.from.name}'s message of #{@m.date}:"] +
m.basic_body_lines.map { |l| "> #{l}" }
end
def handle_new_text new_header, new_body
- @body = new_body
-
- if new_header.size != header.size ||
- header.any? { |k, v| new_header[k] != v }
+ old_header = @headers[@selected_type]
+ if new_header.size != old_header.size || old_header.any? { |k, v| new_header[k] != v }
@selected_type = :user
- @headers[:user] = new_header
+ self.header = @headers[:user] = new_header
+ update
end
end
def move_cursor_left
i = @type_labels.index @selected_type
@selected_type = @type_labels[(i - 1) % @type_labels.length]
+ self.header = @headers[@selected_type]
update
end
def move_cursor_right
i = @type_labels.index @selected_type
@selected_type = @type_labels[(i + 1) % @type_labels.length]
+ self.header = @headers[@selected_type]
update
end
end