Skip to content

Instantly share code, notes, and snippets.

@zhenya1007
Created May 7, 2017 20:45
Show Gist options
  • Select an option

  • Save zhenya1007/b38582e7c73e2f0c52e77420b89fcf34 to your computer and use it in GitHub Desktop.

Select an option

Save zhenya1007/b38582e7c73e2f0c52e77420b89fcf34 to your computer and use it in GitHub Desktop.
A minimalist Hydra implementation for Emacs
;;; A simple/minimalist implementation of some of Hydra (github:abo-abo/hydra) functionality
;;; This code is in the public domain.
(defun my-make-universal-argument-map-insinuator (keymap)
(let ((name (symbol-name (cl-gensym "my-mini-hydra-universal-argument-insinuator-")))
(de-insinuator (cl-gensym)))
;; the code below relies on `lexical-binding' to capture the free variables in `lambda'
(fset de-insinuator (lambda ()
(let* ((vec (this-command-keys-vector))
(key (if (> (length vec) 0)
(vector (aref vec (1- (length vec))))
nil)))
(unless (or (null key) (lookup-key keymap key))
(advice-remove 'universal-argument--mode name)
(remove-hook 'post-command-hook de-insinuator)))))
(lambda ()
(advice-add 'universal-argument--mode :after
(lambda () (set-transient-map keymap))
`((name . ,name)))
(add-hook 'post-command-hook de-insinuator))))
(defvar my-kill-thing-map (make-sparse-keymap)
"A keymap that holds commands for killing \"things\"."
(set-keymap-parent my-kill-thing-map universal-argument-map)
;;; Order-matters here: I want all the relevant keys to be bound in `my-kill-thing-map'
;;; before the fset below binds `my-kill-thing-insinuator' to a closure which captures `my-kill-thing-map'
(define-key global-map [?\C-w]
(lambda ()
(interactive)
(if (use-region-p) ; this idea is from github:paldepind/composable.el
(call-interactively #'kill-region)
(funcall 'my-kill-thing-insinuator)
(universal-argument--mode))))
(defun my-defhead (map key cmd)
(define-key map key
(lambda () (interactive)
(call-interactively cmd)
(universal-argument--mode))))
;; now define some keys
;; a kludge to "bootstrap" the insinuator: the ?\C-w here matches the key used in in `(define-key global-map ...)' above
(my-defhead my-kill-thing-map [?\C-w] #'ignore)
;; and now for some actually useful key definitions
(my-defhead my-kill-thing-map [?w] #'kill-word)
;; ...
;; etc.
;; finally, pass the keymap to the insinuator
(fset 'my-kill-thing-insinuator (my-make-universal-argument-map-insinuator my-kill-thing-map))
;; that's it, folks!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment