summaryrefslogtreecommitdiff
path: root/emacs/site-lisp
diff options
context:
space:
mode:
Diffstat (limited to 'emacs/site-lisp')
-rw-r--r--emacs/site-lisp/my-modal.el211
1 files changed, 211 insertions, 0 deletions
diff --git a/emacs/site-lisp/my-modal.el b/emacs/site-lisp/my-modal.el
new file mode 100644
index 0000000..52cf8d3
--- /dev/null
+++ b/emacs/site-lisp/my-modal.el
@@ -0,0 +1,211 @@
+;;; bespoke vish modal -*- lexical-binding: t; -*-
+
+(require 's)
+
+
+(defun do-nothing () (interactive))
+
+(defun yank-looks-like-lines ()
+ (s-contains? "
+" (current-kill 0 t)))
+
+(defun paste-after-maybe-lines ()
+ (interactive)
+ (if (yank-looks-like-lines)
+ (progn
+ (move-end-of-line nil)
+ (newline)
+ (yank))
+ (forward-char-unless-eol)
+ (yank)))
+
+(defun paste-before-maybe-lines ()
+ (interactive)
+ (if (yank-looks-like-lines)
+ (progn
+ (move-beginning-of-line nil)
+ (yank))
+ (yank)))
+
+(defun forward-char-unless-eol (&optional arg)
+ (interactive "P")
+ (when (< (point) (point-at-eol)) (forward-char arg)))
+
+(defun mark-end-of-line (&optional arg)
+ (interactive "P")
+ (push-mark)
+ (move-end-of-line arg)
+ (exchange-point-and-mark))
+
+(defun mark-beginning-of-line (&optional arg)
+ (interactive "P")
+ (push-mark)
+ (move-beginning-of-line arg)
+ (exchange-point-and-mark))
+
+;; what I really want is a meta operator to invert the arg count,
+;; but between how ryo calls functions and expects symbols in binds,
+;; this is the best I can do.
+(defun mark-word-backward (&optional arg allow-extend)
+ (interactive "P\np")
+ (cond
+ ((null arg)
+ (setq arg -1))
+ ((numberp arg)
+ (setq arg (* -1 arg))))
+ (mark-word arg allow-extend))
+
+(defun mark-sexp-backward (&optional arg allow-extend)
+ (interactive "P\np")
+ (cond
+ ((null arg)
+ (setq arg -1))
+ ((numberp arg)
+ (setq arg (* -1 arg))))
+ (mark-sexp arg allow-extend))
+
+(defun mark-defun-backward (&optional arg interactive)
+ (interactive "p\nd")
+ (cond
+ ((null arg)
+ (setq arg -1))
+ ((numberp arg)
+ (setq arg (* -1 arg))))
+ (mark-defun arg interactive))
+
+(defun mark-paragraph-backward (&optional arg allow-extend)
+ (interactive "P\np")
+ (cond
+ ((null arg)
+ (setq arg -1))
+ ((numberp arg)
+ (setq arg (* -1 arg))))
+ (mark-paragraph arg allow-extend))
+
+(defconst my/ryo-digits '(("1" "C-1" :norepeat t)
+ ("2" "C-2" :norepeat t)
+ ("3" "C-3" :norepeat t)
+ ("4" "C-4" :norepeat t)
+ ("5" "C-5" :norepeat t)
+ ("6" "C-6" :norepeat t)
+ ("7" "C-7" :norepeat t)
+ ("8" "C-8" :norepeat t)
+ ("9" "C-9" :norepeat t)))
+
+(defconst my/ryo-moves '(("h" backward-char)
+ ("j" next-line)
+ ("k" previous-line)
+ ("l" forward-char)
+
+ ("e" forward-word)
+ ("b" backward-word)
+ ("E" forward-sexp)
+ ("B" backward-sexp)
+
+ ("0" "C-a")
+ ("$" "C-e")
+
+ ("[" beginning-of-defun)
+ ("]" end-of-defun)
+ ("{" backward-paragraph)
+ ("}" forward-paragraph)
+ ))
+
+(defconst my/ryo-marking-moves '(("h" backward-char :first (push-mark-command))
+ ("j" next-line :first (push-mark-command))
+ ("k" previous-line :first (push-mark-command))
+ ("l" forward-char :first (push-mark-command))
+
+ ("b" mark-word-backward)
+ ("e" mark-word)
+ ("B" mark-sexp-backward)
+ ("E" mark-sexp)
+
+ ("[" mark-defun-backward)
+ ("]" mark-defun)
+
+ ("0" mark-beginning-of-line)
+ ("$" mark-end-of-line)
+
+ ("{" mark-paragraph-backward)
+ ("}" mark-paragraph)
+ ))
+
+(defconst my/ryo-no-ops '(
+ "<escape>"
+ "`" "-" "+"
+ "q" "w" "r" "t" "\\"
+ "s" "f" ";" "'"
+ "z" "n" "m" "," "."
+
+ "~" "!" "@" "#" "%" "^" "&" "*" "(" ")" "_" "+"
+ "Q" "W" "R" "T" "Y" "U" "|"
+ "S" "D" "F" "H" "J" "K" "L" ":" "\""
+ "Z" "X" "C" "V" "N" "M" "<" ">"
+ ))
+
+
+
+(use-package ryo-modal
+ :demand t
+ :bind (:map my/keys-mode-map
+ ("C-c C-<space>" . ryo-modal-mode))
+ :config
+ (define-minor-mode my/temp-nonmodal-mode
+ "Minor mode for a temporary exit that should return to ryo-modal-mode."
+ :keymap (define-keymap
+ "<escape>"
+ 'my/temp-nonmodal-mode)
+ :lighter " <NM>"
+ (ryo-modal-mode (if my/temp-nonmodal-mode -1 1)))
+
+ (let* ()
+ (eval
+ `(ryo-modal-keys
+ ,@my/ryo-moves
+ ,@my/ryo-digits
+ ,@(mapcar (lambda (key) (list key 'do-nothing)) my/ryo-no-ops)
+ ("g" (("g" beginning-of-buffer)))
+ ("G" end-of-buffer)
+
+ ("i" my/temp-nonmodal-mode)
+ ("I" back-to-indentation :then '(my/temp-nonmodal-mode))
+ ("a" forward-char-unless-eol :then '(my/temp-nonmodal-mode))
+ ("A" move-end-of-line :then '(my/temp-nonmodal-mode))
+ ("o" move-end-of-line :then '(newline-and-indent my/temp-nonmodal-mode))
+ ("O" move-beginning-of-line
+ :then '(open-line indent-according-to-mode my/temp-nonmodal-mode))
+
+ ("x" delete-char)
+ ("d" (("d" kill-whole-line)
+ ("m" kill-region)))
+ ("d" ,my/ryo-marking-moves :then '(kill-region))
+
+ ("c" (("c" kill-whole-line))
+ :then '(open-line my/temp-nonmodal-mode))
+ ("c" (("m" kill-region))
+ :then '(my/temp-nonmodal-mode))
+ ("C" kill-line :then '(my/temp-nonmodal-mode))
+ ("c" ,my/ryo-marking-moves :then '(kill-region my/temp-nonmodal-mode))
+
+ ("y" (("m" copy-region-as-kill)))
+ ("y" (("y" copy-region-as-kill))
+ :first '(push-mark move-beginning-of-line push-mark move-end-of-line forward-char)
+ :then '(pop-mark pop-to-mark-command))
+
+ ("P" paste-before-maybe-lines)
+ ("p" paste-after-maybe-lines)
+
+ ("/" isearch-forward-regexp)
+ ("?" isearch-backward-regexp)
+
+ ("u" undo)
+
+ ("SPC" set-mark-command)
+ ("v" set-mark-command)
+ )))
+ (setq ryo-modal-cursor-color "aquamarine")
+ (defun ryo-modal-unless-minibuffer ()
+ (unless (minibufferp)
+ (ryo-modal-mode 1)))
+ (add-hook 'after-change-major-mode-hook 'ryo-modal-unless-minibuffer))