diff options
-rw-r--r-- | rekado-mode.el | 211 |
1 files changed, 118 insertions, 93 deletions
diff --git a/rekado-mode.el b/rekado-mode.el index 8a6283d..e050fab 100644 --- a/rekado-mode.el +++ b/rekado-mode.el @@ -1,106 +1,131 @@ +;;; -*- lexical-binding: t -*- + ;; ---------------- rekado minor mode -------------------- (defvar rekado-permanent-mode-q nil "indicates whether permanent keys are active") (defvar rekado-mode-map (make-sparse-keymap) "keymap for rekado-mode") (defun rekado-mode-define-keys (define-permanent-keys) "Defines key bindings for rekado-mode. If the argument is t, the edit mode keys will be bound as well." - (let* ((modal-keys - '( - ("a" . move-beginning-of-line) - ("e" . move-end-of-line) - - ;; define JKLI (HTNC in Dvorak) as arrow keys - ("c" . previous-line) - ("t" . next-line) - ("h" . backward-char) - ("n" . forward-char) - - ;; add meta key to move more quickly - ("M-c" . (lambda () (interactive) - (previous-line 5))) - ("M-t" . (lambda () (interactive) - (next-line 5))) - ("M-h" . backward-word) - ("M-n" . forward-word) - - ;; define U/O (G/R in Dvorak) to kill word in direction - ("G" . backward-kill-word) - ("R" . kill-word) - - ;; TODO: add advice for C, T, H and N (upper case arrows in Dvorak) to mark and start selection - ;; jump to character - ("f" . ace-jump-char-mode) - ("i" . rekado-permanent-mode-exit) - ("k" . (lambda () - (interactive) - (move-beginning-of-line nil) - (kill-whole-line))) - ;; undo as in vim - ("u" . undo) - ;; repeat as in vim - ("." . repeat) - ;; paste as in vim - ("p" . (lambda () - (interactive) - (next-line) - (beginning-of-line) - (yank))) - ("P" . (lambda () - (interactive) - (beginning-of-line) - (yank))) - ;; copy as in vim - ("y" . kill-ring-save) - ("s" . isearch-forward-regexp) - ;; open line below/above as in vim - ("o" . (lambda () - (interactive) - (open-line-below) - (rekado-permanent-mode-exit))) - ("O" . (lambda () - (interactive) - (open-line-above) - (rekado-permanent-mode-exit))) - ;; join lines (like J in vim) - ("j" . (lambda () - (interactive) - (join-line -1))) - ;; change till the end of the line - ("C" . (lambda () - (interactive) - (kill-line) - (rekado-permanent-mode-exit))) - ("<" . beginning-of-buffer) - (">" . end-of-buffer) - ))) - (progn - ;; toggle permanent mode - (define-key rekado-mode-map - (kbd "<C-return>") - 'rekado-permanent-mode-toggle) - - ;; toggle permanent mode - (define-key rekado-mode-map - (kbd "<M-SPC>") - 'rekado-permanent-mode-toggle) - - (if define-permanent-keys - ;; define permanent keys + + ;; return a command that will enable transient-mark-mode if it isn't + ;; yet active before running the command `cmd` + (cl-labels ((transient-wrap (cmd) + (lambda () + (interactive) + (unless (and transient-mark-mode mark-active) + (set-mark-command nil) + (setq transient-mark-mode '(only . ,transient-mark-mode))) + (funcall cmd)))) + (let* ((modal-keys + `(("a" . move-beginning-of-line) + ("e" . move-end-of-line) + + ;; define JKLI (HTNC in Dvorak) as arrow keys + ("c" . previous-line) + ("t" . next-line) + ("h" . backward-char) + ("n" . forward-char) + + ;; add meta key to move more quickly + ("M-c" . (lambda () (interactive) + (previous-line 5))) + ("M-t" . (lambda () (interactive) + (next-line 5))) + ("M-h" . backward-word) + ("M-n" . forward-word) + + ;; make shifted arrows work with transient-mark-mode + ("C" . ,(transient-wrap 'previous-line)) + ("T" . ,(transient-wrap 'next-line)) + ("H" . ,(transient-wrap 'backward-char)) + ("N" . ,(transient-wrap 'forward-char)) + + ("M-C" . ,(transient-wrap + '(lambda () (interactive) (previous-line 5)))) + ("M-T" . ,(transient-wrap + '(lambda () (interactive) (next-line 5)))) + ("M-H" . ,(transient-wrap 'backward-word)) + ("M-N" . ,(transient-wrap 'forward-word)) + + ;; define U/O (G/R in Dvorak) to kill word in direction + ("G" . backward-kill-word) + ("R" . kill-word) + + ;; jump to character + ("f" . ace-jump-char-mode) + ("i" . rekado-permanent-mode-exit) + ("k" . (lambda () + (interactive) + (move-beginning-of-line nil) + (kill-whole-line))) + ;; undo as in vim + ("u" . undo) + ;; repeat as in vim + ("." . repeat) + ;; paste as in vim + ("p" . (lambda () + (interactive) + (next-line) + (beginning-of-line) + (yank))) + ("P" . (lambda () + (interactive) + (beginning-of-line) + (yank))) + ;; TODO: replace single character as in vim + ;;("r" . forward-word) + ;; copy as in vim + ("y" . kill-ring-save) + ("s" . isearch-forward-regexp) + ;; open line below/above as in vim + ("o" . (lambda () + (interactive) + (open-line-below) + (rekado-permanent-mode-exit))) + ("O" . (lambda () + (interactive) + (open-line-above) + (rekado-permanent-mode-exit))) + ;; join lines (like J in vim) + ("j" . (lambda () + (interactive) + (join-line -1))) + ;; change till the end of the line + ("R" . (lambda () + (interactive) + (kill-line) + (rekado-permanent-mode-exit))) + ("<" . beginning-of-buffer) + (">" . end-of-buffer) + ))) + (progn + ;; toggle permanent mode + (define-key rekado-mode-map + (kbd "<C-return>") + 'rekado-permanent-mode-toggle) + + ;; toggle permanent mode + (define-key rekado-mode-map + (kbd "<M-SPC>") + 'rekado-permanent-mode-toggle) + + (if define-permanent-keys + ;; define permanent keys + (progn + (setq rekado-permanent-mode-q t) + (mapc (lambda (pair) + (define-key rekado-mode-map + (kbd (car pair)) + (cdr pair))) + modal-keys)) + ;; undefine permanent keys (progn - (setq rekado-permanent-mode-q t) + (setq rekado-permanent-mode-q nil) (mapc (lambda (pair) (define-key rekado-mode-map (kbd (car pair)) - (cdr pair))) - modal-keys)) - ;; undefine permanent keys - (progn - (setq rekado-permanent-mode-q nil) - (mapc (lambda (pair) - (define-key rekado-mode-map - (kbd (car pair)) - nil)) - modal-keys))))) + nil)) + modal-keys)))))) rekado-mode-map) (defun open-line-below () |