# polyp **Repository Path**: mirrors_minad/polyp ## Basic Information - **Project Name**: polyp - **Description**: No description available - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-11-12 - **Last Updated**: 2025-10-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README * polyp.el - Nested modal keybindings #+html: GNU Emacs *Note:* This package is not yet published on melpa and it is unclear if I will ever put it there, since its functionality is too similar to hydra. This is an experimentation test ground for modal keybindings, together with my other package https://github.com/minad/tack. There are many alternatives to consider if you want modal keybindings. By just a quick search I came up with hydra, modalka, ryo-modal, xah, fingers, boon, multistate, meow and the obvious evil. Polyp is a small package which allows the creation of nested editing modes. This package is inspired by Hydra and takes ideas from modal keybinding packages like modalka/ryo-modal. ** Usage It is recommended to configure the package using =use-package=. #+begin_src emacs-lisp (use-package polyp :config ;; Enable the mode-line indicator, showing the currently active mode ;; This is optional. (polyp-mode)) #+end_src Basic example for text scaling. This functionality is already provided by the text-scale-adjust function built into Emacs. It can easily be replicated as follows. #+begin_src emacs-lisp (polyp-define ~scale "=Scale:= _+_:larger _-_:smaller _0_:default" (("-" "C--") text-scale-decrease "C-x C--") (("+" "C-+") text-scale-increase "C-x C-+" "C-x C-=") (("0" "C-0") (text-scale-increase 0) "C-x C-0")) #+end_src As a convention I am using names like =~nav= which begin with a tilde, like the arm of a polyp. The second argument of the =polyp= macro optionally specifies a description. The description is shown above the mode line, when the mode is active. The description string can contain highlighting using =_=, =*= and ===. Furthermore string interpolation using =%e(expr)= and toggles =%t(expr)= are supported. After the description keyword arguments can be specified. #+begin_src emacs-lisp :outer-map Keymap used for the outer bindings. :base-map Base keymap used for the transient bindings. :bind Bindings to which this Polyp is bound in the outer keymap. :enter Action to perform before entering the Polyp. :quit Action to perform after quitting the Polyp. :on Action to perform when Polyp is activated. :off Action to perform when Polyp is deactivated. :handler Specifies the Polyp handler, in particular the behavior if a foreign key is pressed. :status Specifies the status string shown in the mode-line. #+end_src The bindings have the following form, where the =key= is bound to =function= when the mode is active. Furthermore a binding ca be bound to a =outer-key= or can be marked as =:quit=. The =outer-key= enters the mode and if the key of a =:quit= binding is pressed, the mode is left again. #+begin_src emacs-lisp ("key" function :quit) ("key" function "outer-key") #+end_src It is also possible to specify multiple keys. #+begin_src emacs-lisp (("key1" "key2") function "outer-key1" "outer-key2"...) (("key1" "key2") function :quit) #+end_src Furthermore keys can be redirect to the underlying keymap, see the =~cmd= example. ** Examples #+begin_src emacs-lisp (polyp-define ~move-text "=Move Text:= _↕_" ("" move-text-up "M-") ("" move-text-down "M-")) (polyp-define ~expand-region "=Expand:= _#_:expand _'_:contract _0_:reset" ("#" er/expand-region) ("'" er/contract-region) ("0" (er/expand-region 0))) (polyp-define ~undo "=Undo:= _u_ndo _r_edo" ("u" undo-fu-only-undo "C-x u" "C-_" "C-/" "") ("r" undo-fu-only-redo)) (polyp-define ~bookmark "=Bookmark:= _s_et _j_ump _d_elete _r_ename _e_dit" ("s" bookmark-set-no-overwrite) ("j" bookmark-jump) ("r" bookmark-rename) ("d" bookmark-delete) ("e" edit-bookmarks :quit)) (polyp-define ~scale "=Scale:= _+_:larger _-_:smaller _0_:default" (("-" "C--") text-scale-decrease "C-x C--") (("+" "C-+") text-scale-increase "C-x C-+" "C-x C-=") (("0" "C-0") (text-scale-increase 0) "C-x C-0")) (polyp-define ~win "=Window:= _0123_ _↔↕_:move _C-↔↕_:resize _M-↔↕_:swap _u_ndo _r_edo" :bind "C-x w" ("0" delete-window) ("1" delete-other-windows) ("2" split-window-below) ("3" split-window-right) ("u" winner-undo) ("r" winner-redo) ("" windmove-left) ("" windmove-down) ("" windmove-up) ("" windmove-right) ("C-" shrink-window) ("C-" enlarge-window) ("C-" shrink-window-horizontally) ("C-" enlarge-window-horizontally) ("M-" (buffer-swap 'up)) ("M-" (buffer-swap 'down)) ("M-" (buffer-swap 'left)) ("M-" (buffer-swap 'right))) (polyp-define ~multiple-cursors "=Multiple Cursors (%(mc/num-cursors) active)= ↑^^ ↓^^ Mark^^ Other^^ ──^^─────────────^^────────────────^^───────────────────^^──────────── _p_ prev _n_ next *l* lines *c* inc chars _P_ skip _N_ skip *a* all like this *0* inc numbers _M-p_ unmark _M-n_ unmark *s* search _v_ vertical align" :bind "C-c m" ("n" mc/mark-next-like-this) ("N" mc/skip-to-next-like-this) ("M-n" mc/unmark-next-like-this) ("p" mc/mark-previous-like-this) ("P" mc/skip-to-previous-like-this) ("M-p" mc/unmark-previous-like-this) ("v" mc/vertical-align) ("" mc/add-cursor-on-click) (("" "") ignore) ("l" mc/edit-lines :quit) ("a" mc/mark-all-like-this :quit) ("s" mc/mark-all-in-region-regexp :quit) ("c" mc/insert-letters :quit) ("0" mc/insert-numbers :quit)) (polyp-define ~cmd :bind "C-z" :handler run :on (setq cursor-type 'hollow) :off (setq cursor-type 'box) (("z" "C-z") ignore :quit) ("SPC" "C-SPC") ("_" "C-_") ("?" "M-?") ("." "M-.") ("" "C-") ("" "M-") ("<" "M-<") (">" "M->") ("," "C-,") (";" "C-;") (":" "M-:") ("!" "M-!") ("#" "C-#") ("'" "C-'") ("A" "M-a") ("B" "M-b") ("C" "M-c") ("D" "M-d") ("E" "M-e") ("F" "M-f") ("G" "M-g") ("H" "M-h") ("I" "M-i") ("J" "M-j") ("K" "M-k") ("L" "M-l") ("M" "M-m") ("N" "M-n") ("O" "M-o") ("P" "M-p") ("Q" "M-q") ("R" "M-r") ("S" "M-s") ("T" "M-t") ("U" "M-u") ("V" "M-v") ("W" "M-w") ("X" "M-x") ("Y" "M-y") ("Z" "M-z") ("a" "C-a") ("b" "C-b") ("c" "C-c") ("d" "C-d") ("e" "C-e") ("f" "C-f") ("g" "C-g") ("h" "C-h") ("i" "C-i") ("j" "C-j") ("k" "C-k") ("l" "C-l") ("m" "C-m") ("n" "C-n") ("o" "C-o") ("p" "C-p") ("q" "C-q") ("r" "C-r") ("s" "C-s") ("t" "C-t") ("v" "C-v") ("w" "C-w") ("x" "C-x") ("y" "C-y")) (polyp-define ~toggles "=Toggles= ^^View ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^Highlight ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^Edit ^^^^^^^^^^^^^^^^^^^^^^ ^^Debug ─^^────────────────^^^^^^^^^^^^^^^^^^^^^^^^^^───^^─────────────────^^^^^^^^^^^^^^^^^^^^^^^^^───^^────────────────^^^^^^^^^^^^^^^^^^^^^^───^^─────────────^^^^^^^^^^^^^^^^─ _vl_ line-num %t(display-line-numbers-mode) _hd_ delim %t(rainbow-delimiters-mode ) _es_ subword %t(subword-mode ) _de_ error %t(debug-on-error ) _vr_ ruler %t(ruler-mode ) _hc_ color %t(rainbow-mode ) _ep_ elec-pair %t(electric-pair-mode ) _ds_ signal %t(debug-on-signal) _vm_ minions %t(minions-mode ) _hw_ whitespace %t(whitespace-mode ) _eo_ overwrite %t(overwrite-mode ) _vk_ which-key %t(which-key-mode ) _hl_ line %t(outer-hl-line-mode ) _ed_ delsel %t(delete-selection-mode) _vo_ outline %t(outline-minor-mode ) _ht_ todo %t(hl-todo-mode ) _ea_ auto-fill %t(auto-fill-function ) _vw_ winner %t(winner-mode ) _hp_ parens %t(show-paren-mode ) _vf_ which-fun %t(which-function-mode ) _hv_ volatile %t(volatile-highlights-mode) ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ _hh_ changes %t(highlight-changes-mode )" :bind "" :handler ignore ("ea" auto-fill-mode) ("ed" delete-selection-mode) ("eo" overwrite-mode) ("ep" electric-pair-mode) ("es" subword-mode) ("hc" rainbow-mode) ("hd" rainbow-delimiters-mode) ("hh" highlight-changes-mode) ("hl" outer-hl-line-mode) ("hp" show-paren-mode) ("ht" hl-todo-mode) ("hv" volatile-highlights-mode) ("hw" whitespace-mode) ("vf" which-function-mode) ("vk" which-key-mode) ("vl" display-line-numbers-mode) ("vr" ruler-mode) ("vo" outline-minor-mode) ("vw" winner-mode) ("vm" minions-mode) ("de" toggle-de) ("ds" toggle-ds) ("" ignore :quit)) #+end_src