-
Notifications
You must be signed in to change notification settings - Fork 284
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Spin off evil-basic-integration.el from evil-integration.el #992
- Loading branch information
Showing
3 changed files
with
328 additions
and
280 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,323 @@ | ||
;;; evil-integration.el --- Integrate Evil with other modules | ||
|
||
;; Author: Vegard Øye <vegard_oye at hotmail.com> | ||
;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> | ||
|
||
;; Version: 1.2.13 | ||
|
||
;; | ||
;; This file is NOT part of GNU Emacs. | ||
|
||
;;; License: | ||
|
||
;; This file is part of Evil. | ||
;; | ||
;; Evil is free software: you can redistribute it and/or modify | ||
;; it under the terms of the GNU General Public License as published by | ||
;; the Free Software Foundation, either version 3 of the License, or | ||
;; (at your option) any later version. | ||
;; | ||
;; Evil is distributed in the hope that it will be useful, | ||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
;; GNU General Public License for more details. | ||
;; | ||
;; You should have received a copy of the GNU General Public License | ||
;; along with Evil. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
(require 'evil-maps) | ||
(require 'evil-core) | ||
(require 'evil-macros) | ||
(require 'evil-types) | ||
(require 'evil-repeat) | ||
|
||
;;; Code: | ||
|
||
;;; Undo tree | ||
|
||
(when (and (require 'undo-tree nil t) | ||
(fboundp 'global-undo-tree-mode)) | ||
(global-undo-tree-mode 1)) | ||
|
||
(eval-after-load 'undo-tree | ||
'(with-no-warnings | ||
(defun evil-turn-on-undo-tree-mode () | ||
"Enable `undo-tree-mode' if evil is enabled. | ||
This function enables `undo-tree-mode' when Evil is activated in | ||
some buffer, but only if `global-undo-tree-mode' is also | ||
activated." | ||
(when (and (boundp 'global-undo-tree-mode) | ||
global-undo-tree-mode) | ||
(turn-on-undo-tree-mode))) | ||
|
||
(add-hook 'evil-local-mode-hook #'evil-turn-on-undo-tree-mode) | ||
|
||
(defadvice undo-tree-visualize (after evil activate) | ||
"Initialize Evil in the visualization buffer." | ||
(when evil-local-mode | ||
(evil-initialize-state))) | ||
|
||
(when (fboundp 'undo-tree-visualize) | ||
(evil-ex-define-cmd "undol[ist]" 'undo-tree-visualize) | ||
(evil-ex-define-cmd "ul" 'undo-tree-visualize)) | ||
|
||
(when (boundp 'undo-tree-visualizer-mode-map) | ||
(define-key undo-tree-visualizer-mode-map | ||
[remap evil-backward-char] 'undo-tree-visualize-switch-branch-left) | ||
(define-key undo-tree-visualizer-mode-map | ||
[remap evil-forward-char] 'undo-tree-visualize-switch-branch-right) | ||
(define-key undo-tree-visualizer-mode-map | ||
[remap evil-next-line] 'undo-tree-visualize-redo) | ||
(define-key undo-tree-visualizer-mode-map | ||
[remap evil-previous-line] 'undo-tree-visualize-undo) | ||
(define-key undo-tree-visualizer-mode-map | ||
[remap evil-ret] 'undo-tree-visualizer-set)) | ||
|
||
(when (boundp 'undo-tree-visualizer-selection-mode-map) | ||
(define-key undo-tree-visualizer-selection-mode-map | ||
[remap evil-backward-char] 'undo-tree-visualizer-select-left) | ||
(define-key undo-tree-visualizer-selection-mode-map | ||
[remap evil-forward-char] 'undo-tree-visualizer-select-right) | ||
(define-key undo-tree-visualizer-selection-mode-map | ||
[remap evil-next-line] 'undo-tree-visualizer-select-next) | ||
(define-key undo-tree-visualizer-selection-mode-map | ||
[remap evil-previous-line] 'undo-tree-visualizer-select-previous) | ||
(define-key undo-tree-visualizer-selection-mode-map | ||
[remap evil-ret] 'undo-tree-visualizer-set)))) | ||
|
||
;;; Eval last sexp | ||
|
||
(cond | ||
((version< emacs-version "25") | ||
(defadvice preceding-sexp (around evil activate) | ||
"In normal-state or motion-state, last sexp ends at point." | ||
(if (and (not evil-move-beyond-eol) | ||
(or (evil-normal-state-p) (evil-motion-state-p))) | ||
(save-excursion | ||
(unless (or (eobp) (eolp)) (forward-char)) | ||
ad-do-it) | ||
ad-do-it)) | ||
|
||
(defadvice pp-last-sexp (around evil activate) | ||
"In normal-state or motion-state, last sexp ends at point." | ||
(if (and (not evil-move-beyond-eol) | ||
(or (evil-normal-state-p) (evil-motion-state-p))) | ||
(save-excursion | ||
(unless (or (eobp) (eolp)) (forward-char)) | ||
ad-do-it) | ||
ad-do-it))) | ||
(t | ||
(defun evil--preceding-sexp (command &rest args) | ||
"In normal-state or motion-state, last sexp ends at point." | ||
(if (and (not evil-move-beyond-eol) | ||
(or (evil-normal-state-p) (evil-motion-state-p))) | ||
(save-excursion | ||
(unless (or (eobp) (eolp)) (forward-char)) | ||
(apply command args)) | ||
(apply command args))) | ||
|
||
(advice-add 'elisp--preceding-sexp :around 'evil--preceding-sexp '((name . evil))) | ||
(advice-add 'pp-last-sexp :around 'evil--preceding-sexp '((name . evil))))) | ||
|
||
;;; ace-jump-mode | ||
|
||
(declare-function 'ace-jump-char-mode "ace-jump-mode") | ||
(declare-function 'ace-jump-word-mode "ace-jump-mode") | ||
(declare-function 'ace-jump-line-mode "ace-jump-mode") | ||
|
||
(defvar evil-ace-jump-active nil) | ||
|
||
(defmacro evil-enclose-ace-jump-for-motion (&rest body) | ||
"Enclose ace-jump to make it suitable for motions. | ||
This includes restricting `ace-jump-mode' to the current window | ||
in visual and operator state, deactivating visual updates, saving | ||
the mark and entering `recursive-edit'." | ||
(declare (indent defun) | ||
(debug t)) | ||
`(let ((old-mark (mark)) | ||
(ace-jump-mode-scope | ||
(if (and (not (memq evil-state '(visual operator))) | ||
(boundp 'ace-jump-mode-scope)) | ||
ace-jump-mode-scope | ||
'window))) | ||
(remove-hook 'pre-command-hook #'evil-visual-pre-command t) | ||
(remove-hook 'post-command-hook #'evil-visual-post-command t) | ||
(unwind-protect | ||
(let ((evil-ace-jump-active 'prepare)) | ||
(add-hook 'ace-jump-mode-end-hook | ||
#'evil-ace-jump-exit-recursive-edit) | ||
,@body | ||
(when evil-ace-jump-active | ||
(setq evil-ace-jump-active t) | ||
(recursive-edit))) | ||
(remove-hook 'post-command-hook | ||
#'evil-ace-jump-exit-recursive-edit) | ||
(remove-hook 'ace-jump-mode-end-hook | ||
#'evil-ace-jump-exit-recursive-edit) | ||
(if (evil-visual-state-p) | ||
(progn | ||
(add-hook 'pre-command-hook #'evil-visual-pre-command nil t) | ||
(add-hook 'post-command-hook #'evil-visual-post-command nil t) | ||
(set-mark old-mark)) | ||
(push-mark old-mark))))) | ||
|
||
(eval-after-load 'ace-jump-mode | ||
`(defadvice ace-jump-done (after evil activate) | ||
(when evil-ace-jump-active | ||
(add-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit)))) | ||
|
||
(defun evil-ace-jump-exit-recursive-edit () | ||
"Exit a recursive edit caused by an evil jump." | ||
(cond | ||
((eq evil-ace-jump-active 'prepare) | ||
(setq evil-ace-jump-active nil)) | ||
(evil-ace-jump-active | ||
(remove-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit) | ||
(exit-recursive-edit)))) | ||
|
||
(evil-define-motion evil-ace-jump-char-mode (count) | ||
"Jump visually directly to a char using ace-jump." | ||
:type inclusive | ||
(evil-without-repeat | ||
(let ((pnt (point)) | ||
(buf (current-buffer))) | ||
(evil-enclose-ace-jump-for-motion | ||
(call-interactively 'ace-jump-char-mode)) | ||
;; if we jump backwards, motion type is exclusive, analogously | ||
;; to `evil-find-char-backward' | ||
(when (and (equal buf (current-buffer)) | ||
(< (point) pnt)) | ||
(setq evil-this-type | ||
(cond | ||
((eq evil-this-type 'exclusive) 'inclusive) | ||
((eq evil-this-type 'inclusive) 'exclusive))))))) | ||
|
||
(evil-define-motion evil-ace-jump-char-to-mode (count) | ||
"Jump visually to the char in front of a char using ace-jump." | ||
:type inclusive | ||
(evil-without-repeat | ||
(let ((pnt (point)) | ||
(buf (current-buffer))) | ||
(evil-enclose-ace-jump-for-motion | ||
(call-interactively 'ace-jump-char-mode)) | ||
(if (and (equal buf (current-buffer)) | ||
(< (point) pnt)) | ||
(progn | ||
(or (eobp) (forward-char)) | ||
(setq evil-this-type | ||
(cond | ||
((eq evil-this-type 'exclusive) 'inclusive) | ||
((eq evil-this-type 'inclusive) 'exclusive)))) | ||
(backward-char))))) | ||
|
||
(evil-define-motion evil-ace-jump-line-mode (count) | ||
"Jump visually to the beginning of a line using ace-jump." | ||
:type line | ||
:repeat abort | ||
(evil-without-repeat | ||
(evil-enclose-ace-jump-for-motion | ||
(call-interactively 'ace-jump-line-mode)))) | ||
|
||
(evil-define-motion evil-ace-jump-word-mode (count) | ||
"Jump visually to the beginning of a word using ace-jump." | ||
:type exclusive | ||
:repeat abort | ||
(evil-without-repeat | ||
(evil-enclose-ace-jump-for-motion | ||
(call-interactively 'ace-jump-word-mode)))) | ||
|
||
(define-key evil-motion-state-map [remap ace-jump-char-mode] #'evil-ace-jump-char-mode) | ||
(define-key evil-motion-state-map [remap ace-jump-line-mode] #'evil-ace-jump-line-mode) | ||
(define-key evil-motion-state-map [remap ace-jump-word-mode] #'evil-ace-jump-word-mode) | ||
|
||
;;; avy | ||
|
||
(declare-function 'avy-goto-word-or-subword-1 "avy") | ||
(declare-function 'avy-goto-line "avy") | ||
(declare-function 'avy-goto-char "avy") | ||
(declare-function 'avy-goto-char-2 "avy") | ||
(declare-function 'avy-goto-char-2-above "avy") | ||
(declare-function 'avy-goto-char-2-below "avy") | ||
(declare-function 'avy-goto-char-in-line "avy") | ||
(declare-function 'avy-goto-word-0 "avy") | ||
(declare-function 'avy-goto-word-1 "avy") | ||
(declare-function 'avy-goto-word-1-above "avy") | ||
(declare-function 'avy-goto-word-1-below "avy") | ||
(declare-function 'avy-goto-subword-0 "avy") | ||
(declare-function 'avy-goto-subword-1 "avy") | ||
(declare-function 'avy-goto-char-timer "avy") | ||
|
||
(defmacro evil-enclose-avy-for-motion (&rest body) | ||
"Enclose avy to make it suitable for motions. | ||
Based on `evil-enclose-ace-jump-for-motion'." | ||
(declare (indent defun) | ||
(debug t)) | ||
`(let ((avy-all-windows | ||
(if (and (not (memq evil-state '(visual operator))) | ||
(boundp 'avy-all-windows)) | ||
avy-all-windows | ||
nil))) | ||
,@body)) | ||
|
||
(defmacro evil-define-avy-motion (command type) | ||
(declare (indent defun) | ||
(debug t)) | ||
(let ((name (intern (format "evil-%s" command)))) | ||
`(evil-define-motion ,name (_count) | ||
,(format "Evil motion for `%s'." command) | ||
:type ,type | ||
:jump t | ||
:repeat abort | ||
(evil-without-repeat | ||
(evil-enclose-avy-for-motion | ||
(call-interactively ',command)))))) | ||
|
||
;; define evil-avy-* motion commands for avy-* commands | ||
(evil-define-avy-motion avy-goto-word-or-subword-1 exclusive) | ||
(evil-define-avy-motion avy-goto-line line) | ||
(evil-define-avy-motion avy-goto-char inclusive) | ||
(evil-define-avy-motion avy-goto-char-2 inclusive) | ||
(evil-define-avy-motion avy-goto-char-2-above inclusive) | ||
(evil-define-avy-motion avy-goto-char-2-below inclusive) | ||
(evil-define-avy-motion avy-goto-char-in-line inclusive) | ||
(evil-define-avy-motion avy-goto-char-timer inclusive) | ||
(evil-define-avy-motion avy-goto-word-0 exclusive) | ||
(evil-define-avy-motion avy-goto-word-1 exclusive) | ||
(evil-define-avy-motion avy-goto-word-1-above exclusive) | ||
(evil-define-avy-motion avy-goto-word-1-below exclusive) | ||
(evil-define-avy-motion avy-goto-subword-0 exclusive) | ||
(evil-define-avy-motion avy-goto-subword-1 exclusive) | ||
|
||
;; remap avy-* commands to evil-avy-* commands | ||
(dolist (command '(avy-goto-word-or-subword-1 | ||
avy-goto-line | ||
avy-goto-char | ||
avy-goto-char-2 | ||
avy-goto-char-2-above | ||
avy-goto-char-2-below | ||
avy-goto-char-in-line | ||
avy-goto-char-timer | ||
avy-goto-word-0 | ||
avy-goto-word-1 | ||
avy-goto-word-1-above | ||
avy-goto-word-1-below | ||
avy-goto-subword-0 | ||
avy-goto-subword-1)) | ||
(define-key evil-motion-state-map | ||
(vector 'remap command) (intern-soft (format "evil-%s" command)))) | ||
|
||
;;; visual-line-mode integration | ||
|
||
(when evil-respect-visual-line-mode | ||
(let ((swaps '((evil-next-line . evil-next-visual-line) | ||
(evil-previous-line . evil-previous-visual-line) | ||
(evil-beginning-of-line . evil-beginning-of-visual-line) | ||
(evil-end-of-line . evil-end-of-visual-line)))) | ||
(dolist (swap swaps) | ||
(define-key visual-line-mode-map (vector 'remap (car swap)) (cdr swap)) | ||
(define-key visual-line-mode-map (vector 'remap (cdr swap)) (car swap))))) | ||
|
||
|
||
;;; evil-basic-integration.el ends here | ||
|
||
(provide 'evil-basic-integration) |
Oops, something went wrong.