;; -*- lexical-binding: t; -*- (defvar hmm-search-engines nil "hmm web search engines.") (defvar hmm-web-browsers nil "hmm web browers.") (defvar hmm-query-handlers nil "hmm query handlers.") (defvar hmm-favourite-commands nil) (defmacro hmm-define-web-search-engine (engine browser) (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)))) `(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-to-favourite-commands ',function-name)))) (defun hmm-add-to-favourite-commands (command) (add-to-list 'hmm-favourite-commands command)) (defun hmm-search-region (from to) (interactive "r") (unless (region-active-p) (error "Region not active.")) (let* ((query (buffer-substring from to))) (hmm-search-internal query))) (defun hmm-search (query) (interactive "sQuery: ") (hmm-search-internal query)) (defun hmm-search-internal (query) (let ((selected (completing-read (format "Search %s using: " query) (mapcar (lambda (command) (format "%s (%s)" command (if (documentation command) (car (split-string (documentation command) "\n")) "Undocumented"))) hmm-favourite-commands)))) (funcall (intern (car (split-string selected " ("))) query))) (dolist (engine hmm-web-search-engines) (dolist (browser hmm-web-browsers) (eval `(hmm-define-web-search-engine ,engine ,browser)))) (mapc 'hmm-add-to-favourite-commands hmm-query-handlers)