And just for the heck of it, if anyones interested - heres the hook code. (ns forex.util.emacs)) (defmacro is [val & message] `(let [result# ~val] (if (not result#) (throw (Exception. ~(or (and (first message) `(format ~@message)) (format "assert: %s" (str val))))) result#)))
(defn fn-meta [function meta] (let [ns-from *ns*] (proxy [clojure.lang.AFn clojure.lang.Fn clojure.lang.IMeta] [] (invoke [& args] (apply function args)) (meta [] (merge (meta function) (merge {:ns ns-from} meta)))))) (defn- val-of [a] (if (var? a) (var-get a) a)) ;;TODO: add log to this (defn- apply-fn [a args] (try (apply (val-of a) args) (catch Exception e (println (format "error in hook %s %s: %s" a (val-of a) e))))) (defmacro- run-fn [a & args] `(let [a# ~a] (try ((val-of a#) ~@args) (catch Exception e# (println (format "error in hook %s %s: %s" a# (val-of a#) e#)))))) (defn- as-ns [a] (condp = (class a) String (find-ns (symbol a)) clojure.lang.Symbol (find-ns a) a)) (defn ns-metas ([fn] (ns-metas *ns* fn)) ([ns fn] (is (as-ns ns) "%s is not a ns, or cant find it" ns) (let [vars (filter fn (vals (ns-interns (as-ns ns))))] (apply hash-map (interleave vars (map var-get vars)))))) (defn ns-vars ([] (ns-vars *ns*)) ([ns] (is (as-ns ns) "%s is not an ns, or cant find it" ns) (let [vars (filter #(:var (meta %)) (vals (ns-interns (as-ns ns))))] (apply hash-map (interleave vars (map var-get vars)))))) (defmacro defvar ([name] (let [new-name (with-meta name (assoc (meta name) :var true))] `(defonce ~new-name nil))) ([name init] (let [new-name (with-meta name (assoc (meta name) :var true))] `(defonce ~new-name ~init)))) (defmacro defhook [& args] `(defvar ~@args)) (defmacro setq [& args] `(do ~@(map (fn [[var val]] `(alter-var-root #'~var (fn [a#] ~val))) (group args)))) (defn- member ([value list] (member value list =)) ([value list test] (some #(test % value) list))) (defn- pushnew* [hook arg id replace] (if replace (alter-var-root hook (fn [old] (doall (concat (list arg) (filter #(and (if id (not (= (:id (meta %)) id)) true) (not (= % arg))) old))))) (alter-var-root hook (fn [old] (doall (if (empty? (take 1 (filter #(or (when id (= (:id (meta %)) id)) (= % arg)) old))) (concat (list arg) old) old)))))) (defmulti pushnew (fn [a b & args] [(if (fn? a) ::fn (type a)) (if (fn? b) ::fn (type b))])) (defmethod pushnew [clojure.lang.Var ::fn] ([hook function] (pushnew hook function *ns* true)) ([hook function id] (pushnew hook function id true)) ([hook function id replace] (let [new-function (if (:id (meta function)) function (if id (fn- meta function {:id id}) function))] (pushnew* hook new-function id replace)))) (defmethod pushnew [clojure.lang.Var clojure.lang.Var] ([hook var] (pushnew hook var nil false)) ([hook var id] (pushnew hook var id false)) ([hook var id replace] (pushnew* hook var id replace))) (defn- add-to-list* [hook arg id replace] (if replace (alter-var-root hook (fn [old] (doall (concat (filter #(and (if id (not (= (:id (meta %)) id)) true) (not (= % arg))) old) (list arg))))) (alter-var-root hook (fn [old] (doall (if (empty? (take 1 (filter #(or (when id (= (:id (meta %)) id)) (= % arg)) old))) (concat old (list arg)) old)))))) (defmulti add-to-list (fn [a b & args] [(if (fn? a) ::fn (type a)) (if (fn? b) ::fn (type b))])) (defmethod add-to-list [clojure.lang.Var ::fn] ([hook function] (add-to-list hook function *ns* true)) ([hook function id] (add-to-list hook function id true)) ([hook function id replace] (let [new-function (if (:id (meta function)) function (if id (fn- meta function {:id id}) function))] (add-to-list* hook new-function id replace)))) (defmethod add-to-list [clojure.lang.Var clojure.lang.Var] ([hook var] (add-to-list hook var nil false)) ([hook var id] (add-to-list hook var id false)) ([hook var id replace] (add-to-list* hook var id replace))) (comment (defn push [var val] (alter-var-root var (fn [it] (concat (list val) it))))) (defn add-hook [hook function] (pushnew hook function)) (defn add-hooks [hook functions] (doall (map #(pushnew hook %) functions))) ;;RUNNING hooks (defn run-hooks [& hooks] (mapc (fn [hook] (mapc #(run-fn %) hook)) hooks)) (defn run-hook-with-args [hook & args] (mapc #(apply-fn % args) hook)) (defn run-hook-with-args-until-success [hook & args] (is (sequence? hook) "hook %s isnt a list" hook) (loop [funcs hook] (cond (empty? funcs) nil true (if-let [it (apply-fn (first funcs) args)] it (recur (rest funcs)))))) (defn run-hook-with-args-until-failure [hook & args] (is (sequence? hook) "hook %s isnt a list" hook) (loop [funcs hook] (cond (empty? funcs) true true (when (apply-fn (first funcs) args) (recur (rest funcs)))))) ;; forex-util-emacs ends here -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en