Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/zcaudate/eta

multi dispatch key bindings for emacs
https://github.com/zcaudate/eta

Last synced: 25 days ago
JSON representation

multi dispatch key bindings for emacs

Awesome Lists containing this project

README

        

#+AUTHOR: Chris Zheng
#+EMAIL: [email protected]
#+OPTIONS: toc:nil
#+STARTUP: showall

** Introduction

[[https://github.com/zcaudate/eta][eta]] a *micro-framework* for customising key-bindings built on top of
[[https://github.com/jwiegley/use-package/blob/master/bind-key.el][bind-key]]. It provides two macros for standardising and associating
intent with key-bindings: a standard version ~eta-bind~ and
multi-dispatch version for standardisation of functionality across
major modes: ~eta-modal-init~ and ~eta-modal~.

** Installation

Install from Melpa:

~quepa~
#+BEGIN_SRC emacs-lisp
(use-package eta :ensure t)
#+END_SRC

** Usage

Let's see these macros in action:

*** ~eta-bind~

#+BEGIN_SRC emacs-lisp
;; First argument is a [vector]
;; [*] means cannot be overriden
;; [] means global but can be overriden by other modes
;; [] means bind for given mode only

;; Subsequent arguments are tabular of the form
;; - ACTION (a tag that states what the action is)
;; - BINDINGS (a set of key bindings bound to the intent)
;; - IMPLEMENTATION (the actual command that performs the action)

;; ACTION BINDINGS IMPLEMENTATION
(eta-bind [*]
::no-action () 'e/no-action ;; can be nothing
::which-key ("C-x C-h" "C-x h") 'which-key-show-major-mode ;; allow multi
::main-menu ("C-p" "M-p" "M-x" "ESC p" "ESC x") 'counsel-M-x
::quit ("ESC q" "M-q") 'save-buffers-kill-terminal
::help-key ("ESC ") 'helpful-key
::eval-elisp ("ESC l") 'eval-last-sexp)
#+END_SRC

*** ~eta-modal~

It's easier to think of this as using multimethods for major
modes. ~eta-modal-init~ is akin to ~defmulti~ while ~eta-modal~ is akin
to ~defmethod~. This allows actiovs that will be consistent across
major modes.

For example the default bindings in Eclipse are ~~ for build and
~~ for debug. ~Build~ and ~Debug~ are actions that can be reassigned
key-bindings. Whether one is writing ~java~, ~c++~ or any other
language, these actions are the same although the underlying
implementation might be very different.

This type of standardisation can now be applied to one's Emacs setup.

#+BEGIN_SRC emacs-lisp
;; ACTION BINDINGS INTERACTIVE PARAMS
(eta-modal-init []
::mode-menu ("") ()
::eval-cursor ("C-e") ("P")
::eval-cursor-alt ("C-x p" "C-x C-p") ("P")
::eval-file ("C-x x" "C-x C-x") ())

;;... then later on ...

;; elisp mode
(eta-modal [::lisp lisp-interaction-mode]
::eval-cursor 'eval-last-sexp
::eval-file 'e/eval-buffer
::eval-cursor-alt 'pp-macroexpand-last-sexp)

;; org mode
(eta-modal [::org org-mode]
::eval-cursor 'org-ctrl-c-ctrl-c
::eval-cursor-alt 'e/org-babel-tangle-block
::mode-connect 'org-babel-tangle
::eval-file nil)

;; elisp mode
(eta-modal [::clojure cider-mode]
::eval-cursor 'cider-eval-last-sexp
::eval-file 'cider-eval-buffer
::eval-cursor-alt 'cider-macroexpand-last-sexp)

;; ... and so on ...
#+END_SRC

* Concept

~eta~ provides a indirection layer between the bindings and the
implementation so that the intent of the user can be stated.

#+BEGIN_SRC md.graph
BINDINGS -> [ACTION or INTENT] -> IMPLEMENTATION
#+END_SRC

This leads to better organisation a cleaner binding definition and
gives the user a bit more control over where the bindings are
placed. It makes migrating away from older libraries much less
painful.

Another features is the ability to have multiple keybindings for a
given action. This is extremely useful in a lot of situations:

- allow access to a commonly used feature at various hand positions
- when minor modes override one binding, the feature is still
available via another set of shortcuts.

* Similar Libraries

These are current libraries that attempt to solve the same problem:

- [[https://github.com/jwiegley/use-package/blob/master/bind-key.el][Bind Key]] is the go to binding library shipped as part of
~use-package~. ~eta~ is essentially offerring a more conventient
interface for ~bind-key~).
- [[https://github.com/jerrypnz/major-mode-hydra.el][Major Mode Hydra]] is a multimethod for only the one action. In this
case, a user can define a ~major-mode-hydra~ key that brings up the
hydra menu for the mode.
- This library is backed by ~pretty-hydra~. ~pretty-hydra~ and ~eta~
are used extensively in [[https://github.com/zcaudate/etude/blob/master/etude/core/etude-core-lisp.el#L37-L72][etude]] for modal menus (effectively
emulatinig what Major Mode Hydra provides).

- [[https://github.com/noctuid/general.el][General]] does something similar.
- [[https://github.com/countvajhula/rigpa][Rigpa]] This project is quite recent, very interesting and offers a framework for the user to build around as opposed to eta's whatever goes approach.