From 2157ead39273691013c38529b14953ea839c2a58 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 21 Aug 2023 22:40:09 +1000 Subject: Adding transformers. Transformers convert from one type to another, thus generalises web search engines. Example: a function returning a url for a git commit hash is a query-to-url transformer --- hmm.el | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/hmm.el b/hmm.el index f3cd7e0..25ca4a0 100644 --- a/hmm.el +++ b/hmm.el @@ -52,6 +52,12 @@ (:command hmm-file-mime-type))) "hmm handlers.") +(defvar hmm-transformers + nil + "hmm transformers. + +Transforms from one type to another type.") + (defvar hmm-external-handlers '((:name mpv :external-command "mpv %U" @@ -90,18 +96,44 @@ ((expand-file-name default-directory) . hmm-file)) "Matchers for 'hmm-thing-at-point'.") -(defmacro hmm-define-web-search-engine (engine browser) +(defmacro hmm-define-web-search-engine (engine) + "Defines a simple transformer from a search engine. + +A search engine is basically a format string with one single %s +to be substitutes by the search query." (let* ((engine-name (plist-get engine :name)) - (browser-name (plist-get browser :name)) (function-name (intern - (format "hmm-search-%s-%s" engine-name browser-name)))) + (format "hmm-%s-format-url" engine-name)))) `(progn (defun ,function-name (query) - ,(format "Search %s in %s." engine-name browser-name) - (interactive ,(format "sSearch %s in %s for: " engine-name browser-name)) - (,(plist-get browser :command) - (format ,(plist-get engine :format) query))) - (hmm-add-handler '(:command ,function-name) :query)))) + ,(format "Format %s url from QUERY." engine-name) + (format ,(plist-get engine :format) query)) + (hmm-add-transformer + '( :function ,function-name :name ,engine-name + :from :query :to :url))))) + +;; TODO: Validate the output type of the transformer agrees with the +;; input type of the handler. +(defmacro hmm-define-compound-handler (transformer handler) + "Define a compound handler that feeds the output of TRANSFORMER into HANDLER. + +Say transformer is ddg (query->url) and handler is firefox (url), +then the resulting function is hmm-ddg-firefox, which takes a +input and open the ddg search url in firefox." + (when-let* ((trans-name (or (plist-get transformer :name) + (plist-get transformer :function))) + (handler-name (plist-get handler :name)) + (function-name (intern + (format "hmm-%s-%s" trans-name handler-name))) + (from (plist-get transformer :from))) + `(progn + (defun ,function-name (input) + ,(format "Handle the output of %s with %s." + trans-name handler-name) + (interactive ,(format "sHandle %s with %s for: " trans-name handler-name)) + (,(plist-get handler :command) + (,(plist-get transformer :function) input))) + (hmm-add-handler '(:command ,function-name) ,from)))) (defmacro hmm-define-external-handler (handler type) (let* ((name (plist-get handler :name)) @@ -142,7 +174,15 @@ (defun hmm-add-handler (handler handling) (let ((handlers (plist-get hmm-handlers handling))) (cl-pushnew handler handlers) - (plist-put hmm-handlers handling handlers))) + (setq hmm-handlers (plist-put hmm-handlers handling handlers)))) + +(defun hmm-add-transformer (transformer) + (let* ((sig (intern (format "%s->%s" + (plist-get transformer :from) + (plist-get transformer :to)))) + (transformers (plist-get hmm-transformers sig))) + (cl-pushnew transformer transformers) + (setq hmm-transformers (plist-put hmm-transformers sig transformers)))) (defun hmm-thing-in-region (from to) (interactive "r") @@ -211,7 +251,7 @@ (and (hmm-thing-match thing type handler) (or (null (plist-get handler :mimetypes)) - (member mimetype + (member mimetype (plist-get handler :mimetypes))))) (plist-get hmm-handlers type))))) @@ -240,8 +280,7 @@ (defun hmm-update-handlers () (interactive) (dolist (engine hmm-web-search-engines) - (dolist (browser hmm-web-browsers) - (eval `(hmm-define-web-search-engine ,engine ,browser)))) + (eval `(hmm-define-web-search-engine ,engine))) (dolist (xdg-handler (hmm-get-xdg-handlers)) (eval `(hmm-define-external-handler ,xdg-handler :file))) (dolist (handler hmm-external-handlers) @@ -249,14 +288,24 @@ (dolist (browser hmm-web-browsers) (hmm-add-handler (list :command (plist-get browser :command) + :name (plist-get browser :name) :schemes (list "http" "https")) - :url))) + :url)) + (print (length (plist-get hmm-transformers :query->:url))) + (print (length (plist-get hmm-handlers :url))) + (let ((pairs)) + (dolist (transformer (plist-get hmm-transformers :query->:url)) + (dolist (handler (plist-get hmm-handlers :url)) + (pushnew (cons transformer handler) pairs))) + (dolist (pair pairs) + (eval `(hmm-define-compound-handler ,(car pair) ,(cdr pair))))) + ) (defun hmm-update () (interactive) (hmm-update-handlers) (hmm-define-hmm-thing-at-point) - (message "Updated.")) + (message "hmm: updated.")) (defun hmm-get-xdg-handlers () (seq-filter -- cgit v1.2.3