From: wmorgan Date: Sun, 19 Aug 2007 00:45:50 +0000 (+0000) Subject: hook system X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=af218d4236c162f69fd5d816204aba4aaeae2ab2;p=sup hook system git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@528 5c8cc53c-5e98-4d25-b20a-d8db53a31250 --- diff --git a/Manifest.txt b/Manifest.txt index c499da0..02628fc 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -21,6 +21,7 @@ lib/sup/buffer.rb lib/sup/colormap.rb lib/sup/contact.rb lib/sup/draft.rb +lib/sup/hook.rb lib/sup/imap.rb lib/sup/index.rb lib/sup/keymap.rb diff --git a/bin/sup b/bin/sup index 2b412aa..918ec47 100644 --- a/bin/sup +++ b/bin/sup @@ -16,9 +16,15 @@ Usage: Options are: EOS + opt :list_hooks, "List all hooks and descriptions thereof, and quit." opt :no_threads, "Turn of threading. Helps with debugging. (Necessarily disables background polling for new messages.)" end +if $opts[:list_hooks] + Redwood::HookManager.print_hooks + exit +end + Thread.abort_on_exception = true # make debugging possible module Redwood @@ -241,7 +247,6 @@ begin bm.spawn "New Message", mode mode.edit_message when :poll - # bm.raise_to_front PollManager.buffer reporting_thread { PollManager.poll } when :recall_draft case Index.num_results_for :label => :draft diff --git a/doc/TODO b/doc/TODO index 7522377..bf4be63 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,15 +1,14 @@ for next release ---------------- +_ imap "add all folders on this server" option in sup-add _ mailing list subscribe/unsubscribe _ BufferManager#ask_for_labels opens up label-list-mode if empty _ tab completion for mid-text cursors +_ ncurses text entry horizontal scrolling _ forward attachments _ messages as attachments -_ individual labeling in thread-view-mode -_ tab completion for to: and cc: in compose-mode _ use trac or something. this file is getting a little silly. _ gpg integration -_ user-defined hooks _ saved searches _ bugfix: missing sources should be handled better _ bugfix: screwing with the headers when editing causes a crash @@ -20,10 +19,10 @@ _ bugfix: need a better way to force an address to a particular name, for things like evite addresses _ bugfix: ferret flakiness: just added message but can't find it (? still relevant ?) _ for new message flashes, add new message counts until keypress -_ bugfix: deadlock (on rubyforge) +_ bugfix: deadlock (on rubyforge) (? still valid ?) _ bugfix: ferret corrupt index problem at index.c:901. see http://ferret.davebalmain.com/trac/ticket/279 _ bugfix: read before thread-index has finished loading then hides the - thread?!? wtf. (on jamie) + thread?!? wtf. (on jamie) (? still valid ?) _ bugfix: width in index-mode needs to be determined per-character rather than per-byte _ search results: highlight relevant snippets and open to relevant @@ -33,6 +32,9 @@ _ undo _ gmail support _ warnings: top-posting, missing attachment, ruby-talk:XXXX detection _ Net::SMTP support +x user-defined hooks +x tab completion for to: and cc: in compose-mode +x individual labeling in thread-view-mode x translate aliases in queries on to: and from: fields x tab completion on labeling diff --git a/lib/sup.rb b/lib/sup.rb index 311b401..7de719a 100644 --- a/lib/sup.rb +++ b/lib/sup.rb @@ -43,6 +43,7 @@ module Redwood SENT_FN = File.join(BASE_DIR, "sent.mbox") LOCK_FN = File.join(BASE_DIR, "lock") SUICIDE_FN = File.join(BASE_DIR, "please-kill-yourself") + HOOK_DIR = File.join(BASE_DIR, "hooks") YAML_DOMAIN = "masanjin.net" YAML_DATE = "2006-10-01" @@ -205,6 +206,13 @@ else end require "sup/util" +require "sup/hook" + +## we have to initialize this guy first, because other classes must +## reference it in order to register hooks, and they do that at parse +## time. +Redwood::HookManager.new Redwood::HOOK_DIR + require "sup/update" require "sup/suicide" require "sup/message" diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb index 55a53ff..467675a 100644 --- a/lib/sup/buffer.rb +++ b/lib/sup/buffer.rb @@ -2,6 +2,7 @@ require 'etc' require 'thread' require 'ncurses' +if defined? Ncurses module Ncurses def rows lame, lamer = [], [] @@ -43,6 +44,7 @@ module Ncurses KEY_CANCEL = 7 # ctrl-g KEY_TAB = 9 end +end module Redwood diff --git a/lib/sup/hook.rb b/lib/sup/hook.rb new file mode 100644 index 0000000..11c6323 --- /dev/null +++ b/lib/sup/hook.rb @@ -0,0 +1,111 @@ +module Redwood + +class HookManager + + ## there's probably a better way to do this, but to evaluate a hook + ## with a bunch of pre-set "local variables" i define a function + ## per variable and then instance_evaluate the code. + ## + ## i don't bother providing setters, since i'm pretty sure the + ## charade will fall apart pretty quickly with respect to scoping. + ## this is basically fail-fast. + class HookContext + def initialize name, hash + @__name = name + hash.each do |k, v| + self.class.instance_eval { define_method(k) { v } } + end + end + + def say s + @__say_id = BufferManager.say s, @__say_id + end + + def log s + Redwood::log "hook[#@__name]: #{s}" + end + + def __binding + binding + end + + def __cleanup + BufferManager.clear @__say_id if @__say_id + end + end + + include Singleton + + def initialize dir + @dir = dir + @hooks = {} + @descs = {} + Dir.mkdir dir unless File.exists? dir + + self.class.i_am_the_instance self + end + + def run name, locals={} + hook = hook_for(name) or return + context = HookContext.new name, locals + + begin + result = eval @hooks[name], context.__binding, fn_for(name) + if result.is_a? String + log "got return value: #{result.inspect}" + BufferManager.flash result + end + rescue Exception => e + log "error running hook: #{e.message}" + BufferManager.flash "Error running hook: #{e.message}" + end + context.__cleanup + end + + def register name, desc + @descs[name] = desc + end + + def print_hooks f=$stdout +puts < e + nil + end + end + + @hooks[name] + end + + def fn_for name + File.join @dir, "#{name}.rb" + end + + def log m + Redwood::log("hook: " + m) + end +end + +end diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb index fc86be7..952dd22 100644 --- a/lib/sup/modes/thread-index-mode.rb +++ b/lib/sup/modes/thread-index-mode.rb @@ -382,9 +382,9 @@ class ThreadIndexMode < LineCursorMode myopts = @load_thread_opts.merge({ :when_done => (lambda do |num| opts[:when_done].call(num) if opts[:when_done] if num > 0 - BufferManager.flash "Found #{num} threads" + BufferManager.flash "Found #{num} threads." else - BufferManager.flash "No matches" + BufferManager.flash "No matches." end end)}) diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb index 822521d..4d6c5c0 100644 --- a/lib/sup/poll.rb +++ b/lib/sup/poll.rb @@ -5,6 +5,20 @@ module Redwood class PollManager include Singleton + HookManager.register "before-poll", < 0 BufferManager.flash "Loaded #{num} new messages, #{numi} to inbox." else BufferManager.flash "No new messages." end + + HookManager.run "after-poll", :num => num, :num_inbox => numi, :from_and_subj => from_and_subj + [num, numi] end @@ -46,6 +65,8 @@ class PollManager def do_poll total_num = total_numi = 0 + from_and_subj = [] + @mutex.synchronize do Index.usual_sources.each do |source| # yield "source #{source} is done? #{source.done?} (cur_offset #{source.cur_offset} >= #{source.end_offset})" @@ -66,6 +87,7 @@ class PollManager unless entry num += 1 numi += 1 if m.labels.include? :inbox + from_and_subj << [m.from.longname, m.subj] end m end @@ -78,7 +100,7 @@ class PollManager @last_poll = Time.now @polling = false end - [total_num, total_numi] + [total_num, total_numi, from_and_subj] end ## this is the main mechanism for adding new messages to the diff --git a/lib/sup/util.rb b/lib/sup/util.rb index b9563e1..520a648 100644 --- a/lib/sup/util.rb +++ b/lib/sup/util.rb @@ -123,21 +123,7 @@ class Object ret end - ## takes a value which it yields and then returns, so that code - ## like: - ## - ## x = expensive_operation - ## log "got #{x}" - ## x - ## - ## now becomes: - ## - ## with(expensive_operation) { |x| log "got #{x}" } - ## - ## i'm sure there's pithy comment i could make here about the - ## superiority of lisp, but fuck lisp. - ## - ## addendum: apparently this is a "k combinator". whoda thunk it? + ## "k combinator" def returning x; yield x; x; end ## clone of java-style whole-method synchronization diff --git a/www/index.html b/www/index.html index 697e137..95a2054 100644 --- a/www/index.html +++ b/www/index.html @@ -24,6 +24,10 @@ “Every other client we've tried is intolerable.” +
+ “Sup is almost to the point where I could jump ship from mutt.” +
+

Sup is a console-based email client for people with a lot of email. It supports tagging, very fast full-text search, automatic