Evil: Move bindings of Emacs special modes to dedicated package

master
Pierre Neidhardt 2017-10-16 18:21:24 +01:00
parent c4b0699ba7
commit f8b5ca82b4
15 changed files with 60 additions and 352 deletions

View File

@ -45,6 +45,8 @@ lnn "$SOURCEDIR/bookmarks/quickmarks" "$XDG_CONFIG_HOME/qutebrowser/"
if command -v emacs >/dev/null 2>&1; then
echo "==> Emacs extra packages"
yes | emacs --batch -l ~/.emacs.d/init.el --eval '(progn (package-refresh-contents) (package-install-selected-packages))'
mkdir -pv ~/.emacs.d/site-lisp
git clone https://github.com/Ambrevar/evil-special-modes ~/.emacs.d/site-lisp/evil-special-modes
fi
echo "==> Go path"

View File

@ -31,12 +31,18 @@
;;; Store additional config in a 'lisp' subfolder and add it to the load path so
;;; that `require' can find the files.
(add-to-list 'load-path "~/.emacs.d/lisp")
(add-to-list 'load-path (expand-file-name "lisp/" user-emacs-directory))
;;; Local plugin folder for quick install. All files in this folder will be
;;; accessible to Emacs config. This is done to separate the versioned config
;;; files from the external packages.
(add-to-list 'load-path "~/.emacs.d/local")
;;; Site Lisp folder for local packages and development.
(defun package-refresh-load-path (path)
"Add every non-hidden sub-folder of PATH to `load-path'."
(when (file-directory-p path)
(dolist (dir (directory-files path t "^[^\\.]"))
(when (file-directory-p dir)
(setq load-path (add-to-list 'load-path dir))))))
(let ((site-lisp (expand-file-name "site-lisp/" user-emacs-directory)))
(add-to-list 'load-path site-lisp)
(package-refresh-load-path site-lisp))
(when (require 'package nil t)
;; (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
@ -314,6 +320,7 @@
;;; Terminal
(with-eval-after-load 'term
(require 'init-term)
(setq term-buffer-maximum-size 0))
;;; TeX / LaTeX / Texinfo

View File

@ -1,42 +0,0 @@
;;; Evil+Calendar
(evil-define-key 'motion calendar-mode-map
"v" 'calendar-set-mark
"h" 'calendar-backward-day
"0" 'calendar-beginning-of-week
"$" 'calendar-end-of-week
"l" 'calendar-forward-day
"j" 'calendar-forward-week
"k" 'calendar-backward-week
"\C-f" 'calendar-scroll-left-three-months
;; (kbd "<space>") 'scroll-other-window
"." 'calendar-goto-today
"<" 'calendar-scroll-right
">" 'calendar-scroll-left
"?" 'calendar-goto-info-node
"D" 'diary-view-other-diary-entries
"M" 'calendar-lunar-phases
"S" 'calendar-sunrise-sunset
"a" 'calendar-list-holidays
"c" 'org-calendar-goto-agenda
"d" 'diary-view-entries
"\M-h" 'calendar-cursor-holidays
"m" 'diary-mark-entries
"o" 'calendar-other-month
"q" 'calendar-exit
"s" 'diary-show-all-entries
"u" 'calendar-unmark
"x" 'calendar-mark-holidays
"\C-c\C-l" 'calendar-redraw
"[" 'calendar-backward-year
"]" 'calendar-forward-year
"\M-<" 'calendar-beginning-of-year
"\M-=" 'calendar-count-days-region
"\M->" 'calendar-end-of-year
"(" 'calendar-beginning-of-month
")" 'calendar-end-of-month
"\C-b" 'calendar-scroll-right-three-months
"{" 'calendar-backward-month
"}" 'calendar-forward-month)
(provide 'init-evil-calendar)

View File

@ -1,21 +0,0 @@
;;; Evil+custom-mode
(evil-set-initial-state 'Custom-mode 'motion)
(evil-define-key 'motion custom-mode-map
(kbd "SPC") 'scroll-up-command
(kbd "S-SPC") 'scroll-down-command
(kbd "DEL") 'scroll-down-command
(kbd "RET") 'Custom-newline
(kbd "TAB") 'widget-forward
(kbd "S-TAB") 'widget-backward
(kbd "<backtab>") 'widget-backward
"\M-sf" 'Man-goto-section
"<" 'Custom-goto-parent
"\C-j" 'widget-forward
"\C-k" 'widget-backward
"\M-j" 'widget-forward ; custom
"\M-k" 'widget-backward ; custom
"q" 'Custom-buffer-done)
(provide 'init-evil-custom)

View File

@ -1,21 +0,0 @@
;;; Evil+Debugger
(evil-set-initial-state 'debugger-mode 'motion)
(evil-define-key 'motion debugger-mode-map
(kbd "TAB") 'forward-button
(kbd "RET") 'debug-help-follow
(kbd "SPC") 'next-line
"R" 'debugger-record-expression
"gb" 'debugger-frame
"c" 'debugger-continue
"d" 'debugger-step-through
"x" 'debugger-eval-expression
"J" 'debugger-jump
"zl" 'debugger-list-functions
"q" 'top-level
"r" 'debugger-return-value
"u" 'debugger-frame-clear
"p" 'debugger-toggle-locals)
(provide 'init-evil-debugger)

View File

@ -1,43 +0,0 @@
;;; Evil+Eshell
(defun evil/eshell-next-prompt ()
(when (get-text-property (point) 'read-only)
;; If at end of prompt, `eshell-next-prompt' will not move, so go backward.
(beginning-of-line)
(eshell-next-prompt 1)))
(defun evil/eshell-setup ()
(dolist (hook '(evil-replace-state-entry-hook evil-insert-state-entry-hook))
(add-hook hook 'evil/eshell-next-prompt nil t)))
(add-hook 'eshell-mode-hook 'evil/eshell-setup)
(defun evil/eshell-interrupt-process ()
(interactive)
(eshell-interrupt-process)
(evil-insert 1))
;;; `eshell-mode-map' is reset when Eshell is initialized in `eshell-mode'. We
;;; need to add bindings to `eshell-first-time-mode-hook'.
(defun evil/eshell-set-keys ()
(with-eval-after-load 'init-helm
(evil-define-key 'insert eshell-mode-map "\C-e" 'helm-find-files))
(evil-define-key 'normal eshell-mode-map
"[" 'eshell-previous-prompt
"]" 'eshell-next-prompt
"\C-k" 'eshell-previous-prompt
"\C-j" 'eshell-next-prompt
"\M-k" 'eshell-previous-prompt ; Custom
"\M-j" 'eshell-next-prompt ; Custom
"0" 'eshell-bol
(kbd "RET") 'eshell-send-input
(kbd "C-c C-c") 'evil/eshell-interrupt-process
"\M-h" 'eshell-backward-argument
"\M-l" 'eshell-forward-argument)
(evil-define-key 'insert
eshell-mode-map "\M-h" 'eshell-backward-argument
"\M-l" 'eshell-forward-argument))
(add-hook 'eshell-first-time-mode-hook 'evil/eshell-set-keys)
(provide 'init-evil-eshell)

View File

@ -1,11 +0,0 @@
;;; Evil+help-mode
(evil-define-key 'motion help-mode-map
(kbd "SPC") 'scroll-up-command
"\C-f" 'scroll-up-command
"\C-b" 'scroll-down-command
(kbd "TAB") 'forward-button
(kbd "<backtab>") 'backward-button
"\C-o" 'help-go-back)
(provide 'init-evil-help)

View File

@ -0,0 +1,14 @@
;;; Evil+Image+
(when (require 'image+ nil t)
(evil-define-key 'motion image-mode-map
"+" 'imagex-sticky-zoom-in
"-" 'imagex-sticky-zoom-out
"M" 'imagex-sticky-maximize
"m" 'imagex-auto-adjust-mode
"O" 'imagex-sticky-restore-original
"S" 'imagex-sticky-save-image
"r" 'imagex-sticky-rotate-right
"l" 'imagex-sticky-rotate-left))
(provide 'init-evil-image+)

View File

@ -1,51 +0,0 @@
;;; Evil+Image
(evil-set-initial-state 'image-mode 'motion)
(evil-define-key 'motion image-mode-map
(kbd "<return>") 'image-toggle-animation
(kbd "<space>") 'image-scroll-up
(kbd "S-<space>") 'image-scroll-down
"F" 'image-goto-frame
"," 'image-previous-frame ; mpv-style
"." 'image-next-frame ; mpv-style
"H" 'image-transform-fit-to-height
"W" 'image-transform-fit-to-width
"K" 'image-previous-file
"J" 'image-next-file
"q" 'quit-window
"gg" 'image-bob
"G" 'image-eob
"h" 'image-backward-hscroll
"l" 'image-forward-hscroll
"0" 'image-bol
"^" 'image-bol
"$" 'image-eol
"j" 'image-next-line
"k" 'image-previous-line
"\C-d" 'image-scroll-down
"a+" 'image-increase-speed
"a-" 'image-decrease-speed
"}" 'image-increase-speed ; mpv-style
"{" 'image-decrease-speed ; mpv-style
"a0" 'image-reset-speed
"ar" 'image-reverse-speed
"\C-c\C-c" 'image-toggle-display
(kbd "<delete>") 'image-scroll-down)
(when (require 'image+ nil t)
(evil-define-key 'motion image-mode-map
"+" 'imagex-sticky-zoom-in
"-" 'imagex-sticky-zoom-out
"M" 'imagex-sticky-maximize
"m" 'imagex-auto-adjust-mode
"O" 'imagex-sticky-restore-original
"S" 'imagex-sticky-save-image
"r" 'imagex-sticky-rotate-right
"l" 'imagex-sticky-rotate-left))
(when evil-want-C-u-scroll
(evil-define-key 'motion image-mode-map
(kbd "C-u") 'image-scroll-up))
(provide 'init-evil-image)

View File

@ -1,26 +0,0 @@
;;; Evil+Info
(evil-define-key 'motion Info-mode-map
"\C-j" 'Info-next
"\C-k" 'Info-prev
"\M-j" 'Info-next ; Custom
"\M-k" 'Info-prev ; Custom
"\M-sf" 'Info-goto-node
"w" 'evil-forward-word-begin
"e" 'evil-forward-word-end
"ge" 'evil-backward-word-end
"gE" 'evil-backward-WORD-end
"b" 'evil-backward-word-begin
"\M-w" 'Info-copy-current-node-name
"gg" 'evil-goto-first-line
"gt" 'Info-top-node
"gT" 'Info-toc
"gf" 'Info-follow-reference
"t" 'evil-find-char-to
"T" 'evil-find-char-to-backward
"f" 'evil-find-char
"n" 'evil-search-next
"?" 'evil-search-backward
"p" nil)
(provide 'init-evil-info)

View File

@ -1,18 +0,0 @@
;;; Evil+man-mode
(evil-define-key 'motion Man-mode-map
(kbd "SPC") 'scroll-up-command
(kbd "TAB") 'forward-button
(kbd "<backtab>") 'backward-button
"\M-sf" 'Man-goto-section
"q" 'Man-quit
"gm" 'man
"\C-j" 'Man-next-section
"\C-k" 'Man-previous-section
"gr" 'Man-follow-manual-reference
"gs" 'Man-goto-see-also-section
"u" 'Man-update-manpage
"J" 'Man-next-manpage
"K" 'Man-previous-manpage)
(provide 'init-evil-man)

View File

@ -1,6 +0,0 @@
;;; Evil+outline
(evil-define-key 'motion outline-mode-map
(kbd "TAB") 'outline-toggle-children)
(provide 'init-evil-outline)

View File

@ -1,11 +0,0 @@
;;; Evil+Package-menu-mode
(evil-set-initial-state 'package-menu-mode 'motion)
(evil-define-key 'motion package-menu-mode-map "q" 'quit-window)
(evil-define-key 'motion package-menu-mode-map "i" 'package-menu-mark-install)
(evil-define-key 'motion package-menu-mode-map "U" 'package-menu-mark-upgrades)
(evil-define-key 'motion package-menu-mode-map "u" 'package-menu-mark-unmark)
(evil-define-key 'motion package-menu-mode-map "d" 'package-menu-mark-delete)
(evil-define-key 'motion package-menu-mode-map "x" 'package-menu-execute)
(provide 'init-evil-package)

View File

@ -141,9 +141,27 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Mode specific bindings.
(require 'init-evil-info)
(require 'init-evil-help)
(require 'init-evil-man)
;;; Emacs special modes
(when (require 'evil-special-modes nil t)
(evil-special-modes-init))
;; TODO: Copy extra term code.
;;; nXML
;;; TODO: Add to Emacs special modes
(evil-define-key 'normal nxml-mode-map
"\C-j" 'nxml-forward-element
"\C-k" 'nxml-backward-element
"\M-j" 'nxml-forward-element ; Custom
"\M-k" 'nxml-backward-element ; Custom
">" 'nxml-down-element
"<" 'nxml-backward-up-element)
(evil-define-key 'visual nxml-mode-map
"\C-j" 'nxml-forward-element
"\C-k" 'nxml-backward-element
"\M-j" 'nxml-forward-element ; Custom
"\M-k" 'nxml-backward-element ; Custom
">" 'nxml-down-element
"<" 'nxml-backward-up-element)
(with-eval-after-load 'transmission (require 'init-evil-transmission))
@ -151,6 +169,8 @@
(with-eval-after-load 'emms (require 'init-evil-emms))
(with-eval-after-load 'image+ (require 'init-evil-image+))
(with-eval-after-load 'mu4e
(when (require 'evil-mu4e nil t)
;; TODO: evil-mu4e needs a big overhaul, e.g. 'visual commands are not supported. Report upstream.
@ -181,24 +201,6 @@
(with-eval-after-load 'init-helm (require 'init-evil-helm))
(with-eval-after-load 'calendar (require 'init-evil-calendar))
;;; nXML
(evil-define-key 'normal nxml-mode-map
"\C-j" 'nxml-forward-element
"\C-k" 'nxml-backward-element
"\M-j" 'nxml-forward-element ; Custom
"\M-k" 'nxml-backward-element ; Custom
">" 'nxml-down-element
"<" 'nxml-backward-up-element)
(evil-define-key 'visual nxml-mode-map
"\C-j" 'nxml-forward-element
"\C-k" 'nxml-backward-element
"\M-j" 'nxml-forward-element ; Custom
"\M-k" 'nxml-backward-element ; Custom
">" 'nxml-down-element
"<" 'nxml-backward-up-element)
(with-eval-after-load 'magit
(when (require 'evil-magit nil t)
(evil-magit-define-key evil-magit-state 'magit-mode-map "<" 'magit-section-up)
@ -213,33 +215,15 @@
;; (add-hook 'org-mode-hook 'evil-org-mode)
;; (evil-org-set-key-theme '(textobjects insert navigation additional shift todo heading)))
(with-eval-after-load 'package (require 'init-evil-package))
(with-eval-after-load 'eshell (require 'init-evil-eshell))
(with-eval-after-load 'outline (require 'init-evil-outline))
(with-eval-after-load 'image-mode (require 'init-evil-image))
(with-eval-after-load 'pdf-view
(require 'init-evil-pdf)
;; TODO: `image-mode-map' is the parent of `pdf-view-mode-map'. A bug(?) in
;; Evil overrides all image-mode-map bindings.
;; See https://github.com/emacs-evil/evil/issues/938
;; and https://github.com/politza/pdf-tools/issues/324.
;; A workaround is to re-load the image bindings after PDF bindings are set.
(load-library "init-evil-image"))
(with-eval-after-load 'term (require 'init-evil-term))
;; TODO: `image-mode-map' is the parent of `pdf-view-mode-map'. A bug(?) in
;; image-mode-map and pdf-mode-map seem to conflict with Evil.
;; See https://github.com/emacs-evil/evil/issues/938
;; and https://github.com/politza/pdf-tools/issues/324.
;; Changing load order only changes which mode overrides the other.
(with-eval-after-load 'pdf-view (require 'init-evil-pdf))
(with-eval-after-load 'ztree-diff (require 'init-evil-ztree))
(with-eval-after-load 'debug (require 'init-evil-debugger))
(with-eval-after-load 'debbugs (require 'init-evil-debbugs))
(with-eval-after-load 'gnus (require 'init-evil-gnus))
(with-eval-after-load 'cus-edit (require 'init-evil-custom))
(with-eval-after-load 'debbugs (require 'init-evil-debbugs nil t))
(provide 'init-evil)

View File

@ -1,53 +1,4 @@
;;; Evil+term
(evil-set-initial-state 'term-mode 'insert)
;;; TODO: Set prompt regexp. Test next/previous prompt functions, term-bol, etc.
;;; Probably needs the same fix as Eshell.
;;; TODO: Can the prompt be read-only?
;;; TODO: Rebinding ESC has the drawback that programs like vi cannot use it anymore.
;;; Workaround: switch to Emacs mode and double-press ESC.
;;; Otherwise leave ESC to C-cC-j.
;;; Or bind char-mode ESC to C-cC-x?
(defun evil-term-char-mode-insert ()
(interactive)
(term-char-mode)
(evil-insert-state))
(evil-define-key 'normal term-mode-map
"\C-c\C-k" 'evil-term-char-mode-insert
(kbd "RET") 'term-send-input)
(evil-define-key 'insert term-mode-map "\C-c\C-k" 'term-char-mode)
(evil-define-key 'normal term-mode-map
"[" 'term-previous-prompt
"]" 'term-next-prompt
"\C-k" 'eshell-previous-prompt
"\C-j" 'eshell-next-prompt
"\M-k" 'eshell-previous-prompt ; Custom
"\M-j" 'eshell-next-prompt ; Custom
;; TODO: Why not J/K? Already bound to join/look-up. Does it matter?
"0" 'term-bol
"$" 'term-show-maximum-output)
(defun evil-term-char-mode-entry-function ()
(when (get-buffer-process (current-buffer))
(let (last-prompt)
(save-excursion
(goto-char (point-max))
(when (= (line-beginning-position) (line-end-position))
(ignore-errors (backward-char)))
(setq last-prompt (max (term-bol nil) (line-beginning-position))))
(when (>= (point) last-prompt)
(term-char-mode)))))
(defun evil-term-setup ()
(add-hook 'evil-insert-state-entry-hook 'evil-term-char-mode-entry-function)
(add-hook 'evil-insert-state-exit-hook 'term-line-mode))
(add-hook 'term-mode-hook 'evil-term-setup)
;;; Term
;;; TODO: Report `term-char-mode' fix upstream.
;;;
@ -128,4 +79,4 @@ intervention from Emacs, except for the escape character (usually C-c)."
;; Finish up.
(term-update-mode-line))))
(provide 'init-evil-term)
(provide 'init-term)