hmm - Emacs Universal Handling System
Table of Contents
Background
In Emacs, we do things in multiple ways:
- "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
- "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
andbrowse-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.