attr_reader :focus_buf
+ ## we have to define the key used to continue in-buffer search here, because
+ ## it has special semantics that BufferManager deals with---current searches
+ ## are canceled by any keypress except this one.
+ CONTINUE_IN_BUFFER_SEARCH_KEY = "n"
+
def initialize
@name_map = {}
@buffers = []
def buffers; @name_map.to_a; end
def focus_on buf
- raise ArgumentError, "buffer not on stack: #{buf.inspect}" unless @buffers.member? buf
+ return unless @buffers.member? buf
+
return if buf == @focus_buf
@focus_buf.blur if @focus_buf
@focus_buf = buf
end
def raise_to_front buf
- raise ArgumentError, "buffer not on stack: #{buf.inspect}" unless @buffers.member? buf
+ return unless @buffers.member? buf
@buffers.delete buf
if @buffers.length > 0 && @buffers.last.force_to_top?
end
def handle_input c
- @focus_buf && @focus_buf.mode.handle_input(c)
+ if @focus_buf
+ if @focus_buf.mode.in_search? && c != CONTINUE_IN_BUFFER_SEARCH_KEY[0]
+ @focus_buf.mode.cancel_search!
+ @focus_buf.mark_dirty
+ end
+ @focus_buf.mode.handle_input c
+ end
end
def exists? n; @name_map.member? n; end
def spawn_unless_exists title, opts={}
if @name_map.member? title
raise_to_front @name_map[title] unless opts[:hidden]
+ nil
else
mode = yield
spawn title, mode, opts
+ @name_map[title]
end
- @name_map[title]
end
def spawn title, mode, opts={}
## TODO: something intelligent here
## for now I will simply prohibit killing the inbox buffer.
else
- raise_to_front @buffers.last
+ last = @buffers.last
+ @focus_buf ||= last
+ raise_to_front last
end
end
def ask_with_completions domain, question, completions, default=nil
ask domain, question, default do |s|
- completions.select { |x| x =~ /^#{s}/i }.map { |x| [x.downcase, x] }
+ completions.select { |x| x =~ /^#{s}/i }.map { |x| [x, x] }
end
end
- def ask_many_with_completions domain, question, completions, default=nil, sep=" "
+ def ask_many_with_completions domain, question, completions, default=nil
ask domain, question, default do |partial|
prefix, target =
- case partial#.gsub(/#{sep}+/, sep)
+ case partial
when /^\s*$/
["", ""]
- when /^(.+#{sep})$/
- [$1, ""]
- when /^(.*#{sep})?(.+?)$/
+ when /^(.*\s+)?(.*?)$/
[$1 || "", $2]
else
raise "william screwed up completion: #{partial.inspect}"
end
end
+ def ask_many_emails_with_completions domain, question, completions, default=nil
+ ask domain, question, default do |partial|
+ prefix, target = partial.split_on_commas_with_remainder
+ Redwood::log "before: prefix #{prefix.inspect}, target #{target.inspect}"
+ target ||= prefix.pop || ""
+ prefix = prefix.join(", ") + (prefix.empty? ? "" : ", ")
+ Redwood::log "after: prefix #{prefix.inspect}, target #{target.inspect}"
+ completions.select { |x| x =~ /^#{target}/i }.map { |x| [prefix + x, x] }
+ end
+ end
+
def ask_for_filename domain, question, default=nil
answer = ask domain, question, default do |s|
if s =~ /(~([^\s\/]*))/ # twiddle directory expansion
def ask_for_contacts domain, question, default_contacts=[]
default = default_contacts.map { |s| s.to_s }.join(" ")
default += " " unless default.empty?
+
+ recent = Index.load_contacts(AccountManager.user_emails, :num => 10).map { |c| [c.full_address, c.email] }
+ contacts = ContactManager.contacts.map { |c| [ContactManager.alias_for(c), c.full_address, c.email] }
- all_contacts = ContactManager.contacts.map { |c| [ContactManager.alias_for(c), c.longname, c.email] }.flatten.uniq.sort
-
- answer = BufferManager.ask_many_with_completions domain, question, all_contacts, default, /\s*,\s*/
+ completions = (recent + contacts).flatten.uniq.sort
+ answer = BufferManager.ask_many_emails_with_completions domain, question, completions, default
if answer
answer.split_on_commas.map { |x| ContactManager.contact_for(x.downcase) || PersonManager.person_for(x) }
Ncurses.sync do
tf.activate question, default, &block
@dirty = true
- draw_screen :skip_minibuf => true, :sync => false
+ #draw_screen :skip_minibuf => true, :sync => false
+ draw_screen :sync => false
end
ret = nil