aboutsummaryrefslogtreecommitdiff
hmm - Emacs Universal Handling System

hmm - Emacs Universal Handling System

Background

In Emacs, we do things in multiple ways:

  1. "Oh, I would like to invoke foo command, then choose the object of that command." Example: M-x eww (command), then put in the url (object) we want to visit
  2. "Oh, I have this thing (object) in the current context, and I would like to do something (command) about it. Example: click a link (object), which invokes eww (command) to visit open this url.

More often than not, we are faced with the second scenario, where we have a thing at point / in region / in the buffer-local environment, and we want to do something about it. Sometimes, we have multiple ways to handle the object, and we would like to choose the handler rather than the object. For example, say we want to clone the a git repo https://git.sr.ht/~bzg/org-mode at point. In this case, the default behaviour might be open the url with eww, which is not what we want. An adhoc way would be to implement a command that runs a git clone process to clone the url at point. The problem is how to invoke the command? We can do so by invoking it with M-x or binding it to a key. Maybe yet another thing we may want to do urls is to copy it, or run a command to fetch info and capture it into an org entry. It can soon be exhausting to remember these commands, and you might forget some useful commands you wrote a year ago!

hmm is designed to fix this problem. Depending on the context, hmm will guess the object, filter commands that handle the object, and prompt for you to choose which command to invoke. In the previous example, where the point is in at a url to a git repo, you invoke <C-M-return>, and a list of commands show up for you to choose from. In a sense it is like "open with".

Features:

  • Handling three types of objects: query, file (including directory) and url
  • Auto-creation of external handlers from xdg mimetype associations
  • Creation of handlers from cross prodcuct of search engines and web browsers.

Install and use

Clone the repo, add the path to load-path, require and update.

(add-to-list 'load-path "~/.emacs.d/hmm")
(require 'hmm)
;; set your own handlers, web browsers, search engines, external handlers,
;; matchers etc.
;; (add-to-list 'hmm-web-browser '(:name luwak :command luwak-open))
;; ...

;; Make the customisation come into effect.
(hmm-update)

This binds <C-M-<return>> to the hmm command.

TODOs

  • Include user-defined xdg mimetype associations from ~/.config/mimeapps.list etc.
  • Include an file of example configs, which may require optional deps like magit, osm etc.
  • Have a default handler for each scenario, to save effort in choosing handlers
  • A quick way to set default handler for a scenario
  • Allow user to choose which object type they want to handle
  • Maybe use file-directory-p instead of calling external command to check mime type agains "directory/inode" for directory recognition.

Prior art

  • Emacs browse-url.el has some functions and variables like browse-url-select-handler, browse-url-handlers and browse-url-default-handlers. It handles urls, and does not prompt selection of handlers.

Contact and license

hmm is maintained by Yuchen Pei (id@ypei.org). It is covered by GNU AGPLv3+. You may find the license text in a file named COPYING.agpl3 in the project tree.