Commit 228e159401d7

Vincent Demeester <vincent@sbr.pm>
2017-09-12 22:08:41
Add initial evil support (still lots of work to do)
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent f6311f9
.emacs.d/config/navigation-config.el
@@ -0,0 +1,36 @@
+
+(defun vde:config-evil ()
+  "Configure evil mode the way I want"
+  (vde:evil:configure-emacs-mode)
+  (vde:evil:configure-bepo))
+
+(defun vde:evil:configure-emacs-mode ()
+  "configure evil emacs mode"
+  (dolist (mode '(custom-mode
+                  dired-mode
+                  eshell-mode
+                  term-mode
+                  grep-mode))
+    (add-to-list 'evil-emacs-state-modes mode)))
+
+(defun vde:evil:configure-bepo ()
+  "Remap default bindings to bรฉpo one *if* the computer is
+  running on a bรฉpo keyboard layout.")
+
+(use-package evil
+  :ensure t
+  :config
+  (add-hook 'evil-mode-hook 'vde:config-evil)
+  (evil-mode 1)
+  (use-package evil-jumper
+    :ensure t
+    :config
+    (global-evil-jumper-mode))
+  (use-package evil-surround
+    :ensure t
+    :config
+    (global-evil-surround-mode))
+  (use-package evil-indent-textobject
+    :ensure t))
+
+(provide 'navigation-config)
.emacs.d/config/navigation-config.elc
Binary file
.emacs.d/config/navigation-config.org
@@ -0,0 +1,129 @@
+#+TITLE: Navigation configuration
+
+Let's configure general navigation elements of emacs here. By that I
+mean using modal edition (like =evil=) but also command and search
+like =ivy= and =counsel=.
+
+* Evil
+
+#+BEGIN_QUOTE
+Evil Mode, or, How I Learned to Stop Worrying and Love Emacs
+#+END_QUOTE
+
+As [[https://blog.aaronbieber.com/][Aaron Bieber]] says in one of his [[https://blog.aaronbieber.com/2015/06/03/evil-mode.html][talk]], let's stop worrying and use
+best of both worlds.
+
+First let's define the =vde:config-evil= function ๐Ÿ‘ผ.
+
+#+BEGIN_SRC emacs-lisp :tangle yes
+  (defun vde:config-evil ()
+    "Configure evil mode the way I want"
+    (vde:evil:configure-emacs-mode)
+    (vde:evil:configure-bepo))
+#+END_SRC
+
+Some modes will work better with =emacs= evil mode, i.e. not the
+default vim =normal= mode or =insert= mode. One example would be
+=grep-mode= which has already pretty useful one key bindings.
+
+#+BEGIN_SRC emacs-lisp :tangle yes
+  (defun vde:evil:configure-emacs-mode ()
+    "configure evil emacs mode"
+    (dolist (mode '(custom-mode
+                    dired-mode
+                    eshell-mode
+                    term-mode
+                    grep-mode))
+      (add-to-list 'evil-emacs-state-modes mode)))
+#+END_SRC
+
+I am a =bรฉpo= user in /most/ of my computer. This means the default
+vim bindings of evil are really not optimized for my keyboard
+layout. That said in a few (macbook at work/home and on tablets) I am
+using mainly qwerty or azerty. Soโ€ฆ
+
+I need to rebind those bindings to bรฉpo-optimized bindings,
+/conditionaly/. Any bindings I do for evil (and in general) should act
+the same with my bรฉpo keymap *and* a qwerty/azerty keymap. This means
+I need a way to rebind dynamically some stuff โ€” well not that
+dynamically but I need to have *one way* to bind things (the qwerty
+way) that should be translated to the =bรฉpo=-way if I'm on a bรฉpo
+computer. We'll detect they keyboard layout using a variable that
+needs to be set-up on bรฉpo machines.
+
+Let's first create a map that correspond one bรฉpo char to a qwerty
+char.
+
+#+BEGIN_SRC emacs-lisp :tangle no
+    (defvar vde:bepo-base-rebinding-map
+      (;;row0
+       ("=" . "-")
+       ;;row1
+       ("b" . "q")
+       ("รฉ" . "w")
+       ("p" . "e")
+       ("o" . "r")
+       ("รจ" . "t")
+       ("^" . "y")
+       ("v" . "u")
+       ("d" . "i")
+       ("l" . "o")
+       ("j" . "p")
+       ("z" . "[")
+       ;;row2
+       ("a" . "a")
+       ("u" . "s")
+       ("i" . "d")
+       ("e" . "f")
+       ("," . "g")
+       ("c" . "h")
+       ("t" . "j")
+       ("s" . "k")
+       ("r" . "l")
+       ("n" . ";")
+       ("m" . "'")
+       ;;row3
+       ("ร " . "z")
+       ("y" . "x")
+       ("x" . "c")
+       ("." . "v")
+       ("k" . "b")
+       ("'" . "n")
+       ("q" . "m")
+       ("g" . ",")
+       ("h" . ".")
+       ("f" . "/")
+       ("w" . "]")))
+#+END_SRC
+
+#+BEGIN_SRC emacs-lisp :tangle yes
+  (defun vde:evil:configure-bepo ()
+    "Remap default bindings to bรฉpo one *if* the computer is
+    running on a bรฉpo keyboard layout.")
+#+END_SRC
+
+Finally let's tie this altogether.
+
+#+BEGIN_SRC emacs-lisp :tangle yes
+  (use-package evil
+    :ensure t
+    :config
+    (add-hook 'evil-mode-hook 'vde:config-evil)
+    (evil-mode 1)
+    (use-package evil-jumper
+      :ensure t
+      :config
+      (global-evil-jumper-mode))
+    (use-package evil-surround
+      :ensure t
+      :config
+      (global-evil-surround-mode))
+    (use-package evil-indent-textobject
+      :ensure t))
+#+END_SRC
+
+* Provide configuration
+
+#+BEGIN_SRC emacs-lisp :tangle yes
+  (provide 'navigation-config)
+#+END_SRC
.emacs.d/elpa/evil-20170904.1346/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Evil: (evil).                 Extensible vi layer for Emacs.
.emacs.d/elpa/evil-20170904.1346/evil-autoloads.el
@@ -0,0 +1,26 @@
+;;; evil-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-core" "evil-core.el" (22968 12694 941943
+;;;;;;  544000))
+;;; Generated autoloads from evil-core.el
+ (autoload 'evil-mode "evil")
+
+;;;***
+
+;;;### (autoloads nil nil ("evil-command-window.el" "evil-commands.el"
+;;;;;;  "evil-common.el" "evil-digraphs.el" "evil-ex.el" "evil-integration.el"
+;;;;;;  "evil-jumps.el" "evil-macros.el" "evil-maps.el" "evil-pkg.el"
+;;;;;;  "evil-repeat.el" "evil-search.el" "evil-states.el" "evil-types.el"
+;;;;;;  "evil-vars.el" "evil.el") (22968 12694 944943 427000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-autoloads.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-command-window.el
@@ -0,0 +1,168 @@
+;;; evil-command-window.el --- Evil command line window implementation
+;; Author: Emanuel Evans <emanuel.evans at gmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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/>.
+
+;;; Commentary:
+
+;; This provides an implementation of the vim command line window for
+;; editing and repeating past ex commands and searches.
+
+;;; Code:
+
+(require 'evil-vars)
+(require 'evil-common)
+(require 'evil-search)
+(require 'evil-ex)
+
+(defvar evil-search-module)
+
+(define-derived-mode evil-command-window-mode fundamental-mode "Evil-cmd"
+  "Major mode for the Evil command line window."
+  (auto-fill-mode 0)
+  (setq-local after-change-functions (cons 'evil-command-window-draw-prefix
+                                           after-change-functions)))
+
+(defun evil-command-window (hist cmd-key execute-fn)
+  "Open a command line window for HIST with CMD-KEY and EXECUTE-FN.
+HIST should be a list of commands.  CMD-KEY should be the string of
+the key whose history is being shown (one of \":\", \"/\", or
+\"?\").  EXECUTE-FN should be a function of one argument to
+execute on the result that the user selects."
+  (when (eq major-mode 'evil-command-window-mode)
+    (user-error "Cannot recursively open command line window"))
+  (dolist (win (window-list))
+    (when (equal (buffer-name (window-buffer win))
+                 "*Command Line*")
+      (kill-buffer (window-buffer win))
+      (delete-window win)))
+  (split-window nil
+                (unless (zerop evil-command-window-height)
+                  evil-command-window-height)
+                'above)
+  (setq evil-command-window-current-buffer (current-buffer))
+  (ignore-errors (kill-buffer "*Command Line*"))
+  (switch-to-buffer "*Command Line*")
+  (setq-local evil-command-window-execute-fn execute-fn)
+  (setq-local evil-command-window-cmd-key cmd-key)
+  (evil-command-window-mode)
+  (evil-command-window-insert-commands hist))
+
+(defun evil-command-window-ex (&optional current-command)
+  "Open a command line window for editing and executing ex commands.
+If CURRENT-COMMAND is present, it will be inserted under the
+cursor as the current command to be edited."
+  (interactive)
+  (evil-command-window (cons (or current-command "") evil-ex-history)
+                       ":"
+                       'evil-command-window-ex-execute))
+
+(defun evil-command-window-execute ()
+  "Execute the command under the cursor in the appropriate buffer.
+The local var `evil-command-window-execute-fn' determines which
+function to execute."
+  (interactive)
+  (let ((result (buffer-substring (line-beginning-position)
+                                  (line-end-position)))
+        (execute-fn evil-command-window-execute-fn)
+        (command-window (get-buffer-window)))
+    (select-window (previous-window))
+    (unless (equal evil-command-window-current-buffer (current-buffer))
+      (user-error "Originating buffer is no longer active"))
+    (kill-buffer "*Command Line*")
+    (delete-window command-window)
+    (funcall execute-fn result)
+    (setq evil-command-window-current-buffer nil)))
+
+(defun evil-command-window-ex-execute (result)
+  "Execute RESULT as an ex command in the appropriate buffer."
+  (unless (string-match-p "^ *$" result)
+    (unless (equal result (car evil-ex-history))
+      (setq evil-ex-history (cons result evil-ex-history)))
+    (let ((evil-ex-current-buffer evil-command-window-current-buffer))
+      (evil-ex-execute result))))
+
+(defun evil-command-window-search-forward ()
+  "Open a command line window for forward searches."
+  (interactive)
+  (evil-command-window (cons ""
+                             (if (eq evil-search-module 'evil-search)
+                                 evil-ex-search-history
+                               evil-search-forward-history))
+                       "/"
+                       (lambda (result)
+                         (evil-command-window-search-execute result t))))
+
+(defun evil-command-window-search-backward ()
+  "Open a command line window for backward searches."
+  (interactive)
+  (evil-command-window (cons ""
+                             (if (eq evil-search-module 'evil-search)
+                                 evil-ex-search-history
+                               evil-search-backward-history))
+                       "?"
+                       (lambda (result)
+                         (evil-command-window-search-execute result nil))))
+
+(defun evil-command-window-search-execute (result forward)
+  "Search for RESULT using FORWARD to determine direction."
+  (unless (zerop (length result))
+
+    (if (eq evil-search-module 'evil-search)
+        (progn
+          (setq evil-ex-search-pattern (evil-ex-make-search-pattern result)
+                evil-ex-search-direction (if forward 'forward 'backward))
+          (unless (equal result (car-safe evil-ex-search-history))
+            (push result evil-ex-search-history))
+          (evil-ex-search))
+      (if forward
+          (unless (equal result (car-safe evil-search-forward-history))
+            (push result evil-search-forward-history))
+        (unless (equal result (car-safe evil-search-backward-history))
+          (push result evil-search-backward-history)))
+      (evil-search result forward evil-regexp-search))))
+
+(defun evil-command-window-draw-prefix (&rest ignored)
+  "Display `evil-command-window-cmd-key' as a prefix to the current line.
+Parameters passed in through IGNORED are ignored."
+  (let ((prefix (propertize evil-command-window-cmd-key
+                            'font-lock-face 'minibuffer-prompt)))
+    (set-text-properties (line-beginning-position) (line-beginning-position 2)
+                         (list 'line-prefix prefix))))
+
+(defun evil-command-window-insert-commands (hist)
+  "Insert the commands in HIST."
+  (let ((inhibit-modification-hooks t))
+    (mapc #'(lambda (cmd) (insert cmd) (newline)) hist)
+    (reverse-region (point-min) (point-max)))
+  (let ((prefix (propertize evil-command-window-cmd-key
+                            'font-lock-face 'minibuffer-prompt)))
+    (set-text-properties (point-min) (point-max) (list 'line-prefix prefix)))
+  (goto-char (point-max))
+  (when (and (bolp) (not (bobp))) (backward-char))
+  (evil-adjust-cursor))
+
+(provide 'evil-command-window)
+
+;;; evil-command-window.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-command-window.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-commands.el
@@ -0,0 +1,4453 @@
+;;; evil-commands.el --- Evil commands and operators
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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-common)
+(require 'evil-digraphs)
+(require 'evil-search)
+(require 'evil-ex)
+(require 'evil-types)
+(require 'evil-command-window)
+(require 'evil-jumps)
+(require 'flyspell)
+
+;;; Motions
+
+;; Movement commands, or motions, are defined with the macro
+;; `evil-define-motion'. A motion is a command with an optional
+;; argument COUNT (interactively accessed by the code "<c>").
+;; It may specify the :type command property (e.g., :type line),
+;; which determines how it is handled by an operator command.
+;; Furthermore, the command must have the command properties
+;; :keep-visual t and :repeat motion; these are automatically
+;; set by the `evil-define-motion' macro.
+
+;;; Code:
+
+(evil-define-motion evil-forward-char (count &optional crosslines noerror)
+  "Move cursor to the right by COUNT characters.
+Movement is restricted to the current line unless CROSSLINES is non-nil.
+If NOERROR is non-nil, don't signal an error upon reaching the end
+of the line or the buffer; just return nil."
+  :type exclusive
+  (interactive "<c>" (list evil-cross-lines
+                           (evil-kbd-macro-suppress-motion-error)))
+  (cond
+   (noerror
+    (condition-case nil
+        (evil-forward-char count crosslines nil)
+      (error nil)))
+   ((not crosslines)
+    ;; for efficiency, narrow the buffer to the projected
+    ;; movement before determining the current line
+    (evil-with-restriction
+        (point)
+        (save-excursion
+          (evil-forward-char (1+ (or count 1)) t t)
+          (point))
+      (condition-case err
+          (evil-narrow-to-line
+            (evil-forward-char count t noerror))
+        (error
+         ;; Restore the previous command (this one never happend).
+         ;; Actually, this preserves the current column if the
+         ;; previous command was `evil-next-line' or
+         ;; `evil-previous-line'.
+         (setq this-command last-command)
+         (signal (car err) (cdr err))))))
+   (t
+    (evil-motion-loop (nil (or count 1))
+      (forward-char)
+      ;; don't put the cursor on a newline
+      (when (and evil-move-cursor-back
+                 (not evil-move-beyond-eol)
+                 (not (evil-visual-state-p))
+                 (not (evil-operator-state-p))
+                 (eolp) (not (eobp)) (not (bolp)))
+        (forward-char))))))
+
+(evil-define-motion evil-backward-char (count &optional crosslines noerror)
+  "Move cursor to the left by COUNT characters.
+Movement is restricted to the current line unless CROSSLINES is non-nil.
+If NOERROR is non-nil, don't signal an error upon reaching the beginning
+of the line or the buffer; just return nil."
+  :type exclusive
+  (interactive "<c>" (list evil-cross-lines
+                           (evil-kbd-macro-suppress-motion-error)))
+  (cond
+   (noerror
+    (condition-case nil
+        (evil-backward-char count crosslines nil)
+      (error nil)))
+   ((not crosslines)
+    ;; restrict movement to the current line
+    (evil-with-restriction
+        (save-excursion
+          (evil-backward-char (1+ (or count 1)) t t)
+          (point))
+        (1+ (point))
+      (condition-case err
+          (evil-narrow-to-line
+            (evil-backward-char count t noerror))
+        (error
+         ;; Restore the previous command (this one never happened).
+         ;; Actually, this preserves the current column if the
+         ;; previous command was `evil-next-line' or
+         ;; `evil-previous-line'.
+         (setq this-command last-command)
+         (signal (car err) (cdr err))))))
+   (t
+    (evil-motion-loop (nil (or count 1))
+      (backward-char)
+      ;; don't put the cursor on a newline
+      (unless (or (evil-visual-state-p) (evil-operator-state-p))
+        (evil-adjust-cursor))))))
+
+(evil-define-motion evil-next-line (count)
+  "Move the cursor COUNT lines down."
+  :type line
+  (let (line-move-visual)
+    (evil-line-move (or count 1))))
+
+(evil-define-motion evil-previous-line (count)
+  "Move the cursor COUNT lines up."
+  :type line
+  (let (line-move-visual)
+    (evil-line-move (- (or count 1)))))
+
+(evil-define-motion evil-next-visual-line (count)
+  "Move the cursor COUNT screen lines down."
+  :type exclusive
+  (let ((line-move-visual t))
+    (evil-line-move (or count 1))))
+
+(evil-define-motion evil-previous-visual-line (count)
+  "Move the cursor COUNT screen lines up."
+  :type exclusive
+  (let ((line-move-visual t))
+    (evil-line-move (- (or count 1)))))
+
+;; used for repeated commands like "dd"
+(evil-define-motion evil-line (count)
+  "Move COUNT - 1 lines down."
+  :type line
+  (let (line-move-visual)
+    ;; Catch bob and eob errors. These are caused when not moving
+    ;; point starting in the first or last line, respectively. In this
+    ;; case the current line should be selected.
+    (condition-case err
+        (evil-line-move (1- (or count 1)))
+      ((beginning-of-buffer end-of-buffer)))))
+
+(evil-define-motion evil-beginning-of-line ()
+  "Move the cursor to the beginning of the current line."
+  :type exclusive
+  (move-beginning-of-line nil))
+
+(evil-define-motion evil-end-of-line (count)
+  "Move the cursor to the end of the current line.
+If COUNT is given, move COUNT - 1 lines downward first."
+  :type inclusive
+  (move-end-of-line count)
+  (when evil-track-eol
+    (setq temporary-goal-column most-positive-fixnum
+          this-command 'next-line))
+  (unless (evil-visual-state-p)
+    (evil-adjust-cursor)
+    (when (eolp)
+      ;; prevent "c$" and "d$" from deleting blank lines
+      (setq evil-this-type 'exclusive))))
+
+(evil-define-motion evil-beginning-of-visual-line ()
+  "Move the cursor to the first character of the current screen line."
+  :type exclusive
+  (if (fboundp 'beginning-of-visual-line)
+      (beginning-of-visual-line)
+    (beginning-of-line)))
+
+(evil-define-motion evil-end-of-visual-line (count)
+  "Move the cursor to the last character of the current screen line.
+If COUNT is given, move COUNT - 1 screen lines downward first."
+  :type inclusive
+  (if (fboundp 'end-of-visual-line)
+      (end-of-visual-line count)
+    (end-of-line count)))
+
+(evil-define-motion evil-middle-of-visual-line ()
+  "Move the cursor to the middle of the current visual line."
+  :type exclusive
+  (beginning-of-visual-line)
+  (evil-with-restriction
+      nil
+      (save-excursion (end-of-visual-line) (point))
+    (move-to-column (+ (current-column)
+                       -1
+                       (/ (with-no-warnings (window-body-width)) 2)))))
+
+(evil-define-motion evil-beginning-of-line-or-digit-argument ()
+  "Move the cursor to the beginning of the current line.
+This function passes its command to `digit-argument' (usually a 0)
+if it is not the first event."
+  :type exclusive
+  (cond
+   (current-prefix-arg
+    (setq this-command #'digit-argument)
+    (call-interactively #'digit-argument))
+   (t
+    (setq this-command #'evil-beginning-of-line)
+    (call-interactively #'evil-beginning-of-line))))
+
+(evil-define-motion evil-first-non-blank ()
+  "Move the cursor to the first non-blank character of the current line."
+  :type exclusive
+  (evil-narrow-to-line (back-to-indentation)))
+
+(evil-define-motion evil-last-non-blank (count)
+  "Move the cursor to the last non-blank character of the current line.
+If COUNT is given, move COUNT - 1 lines downward first."
+  :type inclusive
+  (goto-char
+   (save-excursion
+     (evil-move-beginning-of-line count)
+     (if (re-search-forward "[ \t]*$")
+         (max (line-beginning-position)
+              (1- (match-beginning 0)))
+       (line-beginning-position)))))
+
+(evil-define-motion evil-first-non-blank-of-visual-line ()
+  "Move the cursor to the first non blank character
+of the current screen line."
+  :type exclusive
+  (evil-beginning-of-visual-line)
+  (skip-chars-forward " \t\r"))
+
+(evil-define-motion evil-next-line-first-non-blank (count)
+  "Move the cursor COUNT lines down on the first non-blank character."
+  :type line
+  (let ((this-command this-command))
+    (evil-next-line (or count 1)))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-next-line-1-first-non-blank (count)
+  "Move the cursor COUNT-1 lines down on the first non-blank character."
+  :type line
+  (let ((this-command this-command))
+    (evil-next-line (1- (or count 1))))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-previous-line-first-non-blank (count)
+  "Move the cursor COUNT lines up on the first non-blank character."
+  :type line
+  (let ((this-command this-command))
+    (evil-previous-line (or count 1)))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-goto-line (count)
+  "Go to the first non-blank character of line COUNT.
+By default the last line."
+  :jump t
+  :type line
+  (if (null count)
+      (with-no-warnings (end-of-buffer))
+    (goto-char (point-min))
+    (forward-line (1- count)))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-goto-first-line (count)
+  "Go to the first non-blank character of line COUNT.
+By default the first line."
+  :jump t
+  :type line
+  (evil-goto-line (or count 1)))
+
+(evil-define-motion evil-forward-word-begin (count &optional bigword)
+  "Move the cursor to the beginning of the COUNT-th next word.
+If BIGWORD is non-nil, move by WORDS.
+
+If this command is called in operator-pending state it behaves
+differently. If point reaches the beginning of a word on a new
+line point is moved back to the end of the previous line.
+
+If called after a change operator, i.e. cw or cW,
+`evil-want-change-word-to-end' is non-nil and point is on a word,
+then both behave like ce or cE.
+
+If point is at the end of the buffer and cannot be moved signal
+'end-of-buffer is raised.
+"
+  :type exclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word))
+        (orig (point))
+        (count (or count 1)))
+    (evil-signal-at-bob-or-eob count)
+    (cond
+     ;; default motion, beginning of next word
+     ((not (evil-operator-state-p))
+      (evil-forward-beginning thing count))
+     ;; the evil-change operator, maybe behave like ce or cE
+     ((and evil-want-change-word-to-end
+           (memq evil-this-operator evil-change-commands)
+           (< orig (or (cdr-safe (bounds-of-thing-at-point thing)) orig)))
+      ;; forward-thing moves point to the correct position because
+      ;; this is an exclusive motion
+      (forward-thing thing count))
+     ;; operator state
+     (t
+      (prog1 (evil-forward-beginning thing count)
+        ;; if we reached the beginning of a word on a new line in
+        ;; Operator-Pending state, go back to the end of the previous
+        ;; line
+        (when (and (> (line-beginning-position) orig)
+                   (looking-back "^[[:space:]]*" (line-beginning-position)))
+          ;; move cursor back as long as the line contains only
+          ;; whitespaces and is non-empty
+          (evil-move-end-of-line 0)
+          ;; skip non-empty lines containing only spaces
+          (while (and (looking-back "^[[:space:]]+$" (line-beginning-position))
+                      (not (<= (line-beginning-position) orig)))
+            (evil-move-end-of-line 0))
+          ;; but if the previous line is empty, delete this line
+          (when (bolp) (forward-char))))))))
+
+(evil-define-motion evil-forward-word-end (count &optional bigword)
+  "Move the cursor to the end of the COUNT-th next word.
+If BIGWORD is non-nil, move by WORDS."
+  :type inclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word))
+        (count (or count 1)))
+    (evil-signal-at-bob-or-eob count)
+    ;; Evil special behaviour: e or E on a one-character word in
+    ;; operator state does not move point
+    (unless (and (evil-operator-state-p)
+                 (= 1 count)
+                 (let ((bnd (bounds-of-thing-at-point thing)))
+                   (and bnd
+                        (= (car bnd) (point))
+                        (= (cdr bnd) (1+ (point)))))
+                 (looking-at "[[:word:]]"))
+      (evil-forward-end thing count))))
+
+(evil-define-motion evil-backward-word-begin (count &optional bigword)
+  "Move the cursor to the beginning of the COUNT-th previous word.
+If BIGWORD is non-nil, move by WORDS."
+  :type exclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word)))
+    (evil-signal-at-bob-or-eob (- (or count 1)))
+    (evil-backward-beginning thing count)))
+
+(evil-define-motion evil-backward-word-end (count &optional bigword)
+  "Move the cursor to the end of the COUNT-th previous word.
+If BIGWORD is non-nil, move by WORDS."
+  :type inclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word)))
+    (evil-signal-at-bob-or-eob (- (or count 1)))
+    (evil-backward-end thing count)))
+
+(evil-define-motion evil-forward-WORD-begin (count)
+  "Move the cursor to the beginning of the COUNT-th next WORD."
+  :type exclusive
+  (evil-forward-word-begin count t))
+
+(evil-define-motion evil-forward-WORD-end (count)
+  "Move the cursor to the end of the COUNT-th next WORD."
+  :type inclusive
+  (evil-forward-word-end count t))
+
+(evil-define-motion evil-backward-WORD-begin (count)
+  "Move the cursor to the beginning of the COUNT-th previous WORD."
+  :type exclusive
+  (evil-backward-word-begin count t))
+
+(evil-define-motion evil-backward-WORD-end (count)
+  "Move the cursor to the end of the COUNT-th previous WORD."
+  :type inclusive
+  (evil-backward-word-end count t))
+
+;; section movement
+(evil-define-motion evil-forward-section-begin (count)
+  "Move the cursor to the beginning of the COUNT-th next section."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-beginning 'evil-defun count))
+
+(evil-define-motion evil-forward-section-end (count)
+  "Move the cursor to the end of the COUNT-th next section."
+  :jump t
+  :type inclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-end 'evil-defun count)
+  (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-backward-section-begin (count)
+  "Move the cursor to the beginning of the COUNT-th previous section."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (evil-backward-beginning 'evil-defun count))
+
+(evil-define-motion evil-backward-section-end (count)
+  "Move the cursor to the end of the COUNT-th previous section."
+  :jump t
+  :type inclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (end-of-line -1)
+  (evil-backward-end 'evil-defun count)
+  (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-forward-sentence-begin (count)
+  "Move to the next COUNT-th beginning of a sentence or end of a paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-nearest count
+                        #'(lambda (cnt)
+                            (evil-forward-beginning 'evil-sentence))
+                        #'evil-forward-paragraph))
+
+(evil-define-motion evil-backward-sentence-begin (count)
+  "Move to the previous COUNT-th beginning of a sentence or paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (evil-forward-nearest (- (or count 1))
+                        #'(lambda (cnt)
+                            (evil-backward-beginning 'evil-sentence))
+                        #'(lambda (cnt)
+                            (evil-backward-paragraph))))
+
+(evil-define-motion evil-forward-paragraph (count)
+  "Move to the end of the COUNT-th next paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-end 'evil-paragraph count)
+  (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-backward-paragraph (count)
+  "Move to the beginning of the COUNT-th previous paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (unless (eobp) (forward-line))
+  (evil-backward-beginning 'evil-paragraph count)
+  (unless (bobp) (forward-line -1)))
+
+(evil-define-motion evil-jump-item (count)
+  "Find the next item in this line after or under the cursor
+and jump to the corresponding one."
+  :jump t
+  :type inclusive
+  (cond
+   ;; COUNT% jumps to a line COUNT percentage down the file
+   (count
+    (goto-char
+     (evil-normalize-position
+      (let ((size (- (point-max) (point-min))))
+        (+ (point-min)
+           (if (> size 80000)
+               (* count (/ size 100))
+             (/ (* count size) 100))))))
+    (back-to-indentation)
+    (setq evil-this-type 'line))
+   ((and (evil-looking-at-start-comment t)
+         (let ((pnt (point)))
+           (forward-comment 1)
+           (or (not (bolp))
+               (prog1 nil (goto-char pnt)))))
+    (backward-char))
+   ((and (not (eolp)) (evil-looking-at-end-comment t))
+    (forward-comment -1))
+   ((and
+     (memq major-mode '(c-mode c++-mode))
+     (require 'hideif nil t)
+     (with-no-warnings
+       (let* ((hif-else-regexp (concat hif-cpp-prefix "\\(?:else\\|elif[ \t]+\\)"))
+              (hif-ifx-else-endif-regexp
+               (concat hif-ifx-regexp "\\|" hif-else-regexp "\\|" hif-endif-regexp)))
+         (cond
+          ((save-excursion (beginning-of-line) (or (hif-looking-at-ifX) (hif-looking-at-else)))
+           (hif-find-next-relevant)
+           (while (hif-looking-at-ifX)
+             (hif-ifdef-to-endif)
+             (hif-find-next-relevant))
+           t)
+          ((save-excursion (beginning-of-line) (hif-looking-at-endif))
+           (hif-endif-to-ifdef)
+           t))))))
+   (t
+    (let* ((open (point-max))
+           (close (point-max))
+           (open-pair (condition-case nil
+                          (save-excursion
+                            ;; consider the character right before eol given that
+                            ;; point may be placed there, e.g. in visual state
+                            (when (and (eolp) (not (bolp)))
+                              (backward-char))
+                            (setq open (1- (scan-lists (point) 1 -1)))
+                            (when (< open (line-end-position))
+                              (goto-char open)
+                              (forward-list)
+                              (1- (point))))
+                        (error nil)))
+           (close-pair (condition-case nil
+                           (save-excursion
+                             ;; consider the character right before eol given that
+                             ;; point may be placed there, e.g. in visual state
+                             (when (and (eolp) (not (bolp)))
+                               (backward-char))
+                             (setq close (1- (scan-lists (point) 1 1)))
+                             (when (< close (line-end-position))
+                               (goto-char (1+ close))
+                               (backward-list)
+                               (point)))
+                         (error nil))))
+      (cond
+       ((not (or open-pair close-pair))
+        ;; nothing found, check if we are inside a string
+        (let ((pnt (point))
+              (state (syntax-ppss (point)))
+              (bnd (bounds-of-thing-at-point 'evil-string)))
+          (if (not (and bnd (< (point) (cdr bnd))))
+              ;; no, then we really failed
+              (user-error "No matching item found on the current line")
+            ;; yes, go to the end of the string and try again
+            (let ((endstr (cdr bnd)))
+              (when (or (save-excursion
+                          (goto-char endstr)
+                          (let ((b (bounds-of-thing-at-point 'evil-string)))
+                            (and b (< (point) (cdr b))))) ; not at end of string
+                        (condition-case nil
+                            (progn
+                              (goto-char endstr)
+                              (evil-jump-item)
+                              nil)
+                          (error t)))
+                ;; failed again, go back to original point
+                (goto-char pnt)
+                (user-error "No matching item found on the current line"))))))
+       ((< open close) (goto-char open-pair))
+       (t (goto-char close-pair)))))))
+
+(defun evil--flyspell-overlays-in-p (beg end)
+  (let ((ovs (overlays-in beg end))
+        done)
+    (while (and ovs (not done))
+      (when (flyspell-overlay-p (car ovs))
+        (setq done t))
+      (setq ovs (cdr ovs)))
+    done))
+
+(defun evil--flyspell-overlay-at (pos forwardp)
+  (when (not forwardp)
+    (setq pos (max (1- pos) (point-min))))
+  (let ((ovs (overlays-at pos))
+        done)
+    (while (and ovs (not done))
+      (if (flyspell-overlay-p (car ovs))
+          (setq done t)
+        (setq ovs (cdr ovs))))
+    (when done
+      (car ovs))))
+
+(defun evil--flyspell-overlay-after (pos limit forwardp)
+  (let (done)
+    (while (and (if forwardp
+                    (< pos limit)
+                  (> pos limit))
+                (not done))
+      (let ((ov (evil--flyspell-overlay-at pos forwardp)))
+        (when ov
+          (setq done ov)))
+      (setq pos (if forwardp
+                    (next-overlay-change pos)
+                  (previous-overlay-change pos))))
+    done))
+
+(defun evil--next-flyspell-error (forwardp)
+  (when (evil--flyspell-overlays-in-p (point-min) (point-max))
+    (let ((pos (point))
+          limit
+          ov)
+      (when (evil--flyspell-overlay-at pos forwardp)
+        (if (/= pos (point-min))
+            (setq pos (save-excursion (goto-char pos)
+                                      (forward-word (if forwardp 1 -1))
+                                      (point)))
+          (setq pos (point-max))))
+      (setq limit (if forwardp (point-max) (point-min))
+            ov (evil--flyspell-overlay-after pos limit forwardp))
+      (if ov
+          (goto-char (overlay-start ov))
+        (when evil-search-wrap
+          (setq limit pos
+                pos (if forwardp (point-min) (point-max))
+                ov (evil--flyspell-overlay-after pos limit forwardp))
+          (when ov
+            (goto-char (overlay-start ov))))))))
+
+(evil-define-motion evil-next-flyspell-error (count)
+  "Go to the COUNT'th spelling mistake after point."
+  (interactive "p")
+  (dotimes (_ count)
+    (evil--next-flyspell-error t)))
+
+(evil-define-motion evil-prev-flyspell-error (count)
+  "Go to the COUNT'th spelling mistake preceding point."
+  (interactive "p")
+  (dotimes (_ count)
+    (evil--next-flyspell-error nil)))
+
+(evil-define-motion evil-previous-open-paren (count)
+  "Go to [count] previous unmatched '('."
+  :type exclusive
+  (evil-up-paren ?( ?) (- (or count 1))))
+
+(evil-define-motion evil-next-close-paren (count)
+  "Go to [count] next unmatched ')'."
+  :type exclusive
+  (forward-char)
+  (evil-up-paren ?( ?) (or count 1))
+  (backward-char))
+
+(evil-define-motion evil-previous-open-brace (count)
+  "Go to [count] previous unmatched '{'."
+  :type exclusive
+  (evil-up-paren ?{ ?} (- (or count 1))))
+
+(evil-define-motion evil-next-close-brace (count)
+  "Go to [count] next unmatched '}'."
+  :type exclusive
+  (forward-char)
+  (evil-up-paren ?{ ?} (or count 1))
+  (backward-char))
+
+(evil-define-motion evil-find-char (count char)
+  "Move to the next COUNT'th occurrence of CHAR."
+  :type inclusive
+  (interactive "<c><C>")
+  (setq count (or count 1))
+  (let ((fwd (> count 0)))
+    (setq evil-last-find (list #'evil-find-char char fwd))
+    (when fwd (forward-char))
+    (let ((case-fold-search nil))
+      (unless (prog1
+                  (search-forward (char-to-string char)
+                                  (unless evil-cross-lines
+                                    (if fwd
+                                        (line-end-position)
+                                      (line-beginning-position)))
+                                  t count)
+                (when fwd (backward-char)))
+        (user-error "Can't find %c" char)))))
+
+(evil-define-motion evil-find-char-backward (count char)
+  "Move to the previous COUNT'th occurrence of CHAR."
+  :type exclusive
+  (interactive "<c><C>")
+  (evil-find-char (- (or count 1)) char))
+
+(evil-define-motion evil-find-char-to (count char)
+  "Move before the next COUNT'th occurrence of CHAR."
+  :type inclusive
+  (interactive "<c><C>")
+  (unwind-protect
+      (progn
+        (evil-find-char count char)
+        (if (> (or count 1) 0)
+            (backward-char)
+          (forward-char)))
+    (setcar evil-last-find #'evil-find-char-to)))
+
+(evil-define-motion evil-find-char-to-backward (count char)
+  "Move before the previous COUNT'th occurrence of CHAR."
+  :type exclusive
+  (interactive "<c><C>")
+  (evil-find-char-to (- (or count 1)) char))
+
+(evil-define-motion evil-repeat-find-char (count)
+  "Repeat the last find COUNT times."
+  :type inclusive
+  (setq count (or count 1))
+  (if evil-last-find
+      (let ((cmd (car evil-last-find))
+            (char (nth 1 evil-last-find))
+            (fwd (nth 2 evil-last-find))
+            evil-last-find)
+        ;; ensure count is non-negative
+        (when (< count 0)
+          (setq count (- count)
+                fwd (not fwd)))
+        ;; skip next character when repeating t or T
+        (and (eq cmd #'evil-find-char-to)
+             evil-repeat-find-to-skip-next
+             (= count 1)
+             (or (and fwd (= (char-after (1+ (point))) char))
+                 (and (not fwd) (= (char-before) char)))
+             (setq count (1+ count)))
+        (funcall cmd (if fwd count (- count)) char)
+        (unless (nth 2 evil-last-find)
+          (setq evil-this-type 'exclusive)))
+    (user-error "No previous search")))
+
+(evil-define-motion evil-repeat-find-char-reverse (count)
+  "Repeat the last find COUNT times in the opposite direction."
+  :type inclusive
+  (evil-repeat-find-char (- (or count 1))))
+
+;; ceci n'est pas une pipe
+(evil-define-motion evil-goto-column (count)
+  "Go to column COUNT on the current line.
+Columns are counted from zero."
+  :type exclusive
+  (move-to-column (or count 0)))
+
+(evil-define-command evil-goto-mark (char &optional noerror)
+  "Go to the marker specified by CHAR."
+  :keep-visual t
+  :repeat nil
+  :type exclusive
+  (interactive (list (read-char)))
+  (let ((marker (evil-get-marker char)))
+    (cond
+     ((markerp marker)
+      (switch-to-buffer (marker-buffer marker))
+      (goto-char (marker-position marker)))
+     ((numberp marker)
+      (goto-char marker))
+     ((consp marker)
+      (when (or (find-buffer-visiting (car marker))
+                (and (y-or-n-p (format "Visit file %s again? "
+                                       (car marker)))
+                     (find-file (car marker))))
+        (goto-char (cdr marker))))
+     ((not noerror)
+      (user-error "Marker `%c' is not set%s" char
+                  (if (evil-global-marker-p char) ""
+                    " in this buffer"))))))
+
+(evil-define-command evil-goto-mark-line (char &optional noerror)
+  "Go to the line of the marker specified by CHAR."
+  :keep-visual t
+  :repeat nil
+  :type line
+  (interactive (list (read-char)))
+  (evil-goto-mark char noerror)
+  (evil-first-non-blank))
+
+(evil-define-motion evil-jump-backward (count)
+  "Go to older position in jump list.
+To go the other way, press \
+\\<evil-motion-state-map>\\[evil-jump-forward]."
+  (evil--jump-backward count))
+
+(evil-define-motion evil-jump-forward (count)
+  "Go to newer position in jump list.
+To go the other way, press \
+\\<evil-motion-state-map>\\[evil-jump-backward]."
+  (evil--jump-forward count))
+
+(evil-define-motion evil-jump-backward-swap (count)
+  "Go to the previous position in jump list.
+The current position is placed in the jump list."
+  (let ((pnt (point)))
+    (evil--jump-backward 1)
+    (evil-set-jump pnt)))
+
+(evil-define-motion evil-jump-to-tag (arg)
+  "Jump to tag under point.
+If called with a prefix argument, provide a prompt
+for specifying the tag."
+  :jump t
+  (interactive "P")
+  (if arg (call-interactively #'find-tag)
+    (let ((tag (funcall (or find-tag-default-function
+                            (get major-mode 'find-tag-default-function)
+                            #'find-tag-default))))
+      (unless tag (user-error "No tag candidate found around point"))
+      (find-tag tag))))
+
+(evil-define-motion evil-lookup ()
+  "Look up the keyword at point.
+Calls `evil-lookup-func'."
+  (funcall evil-lookup-func))
+
+(defun evil-ret-gen (count indent?)
+  (let* ((field  (get-char-property (point) 'field))
+         (button (get-char-property (point) 'button))
+         (doc    (get-char-property (point) 'widget-doc))
+         (widget (or field button doc)))
+    (cond
+     ((and widget
+           (fboundp 'widget-type)
+           (fboundp 'widget-button-press)
+           (or (and (symbolp widget)
+                    (get widget 'widget-type))
+               (and (consp widget)
+                    (get (widget-type widget) 'widget-type))))
+      (when (evil-operator-state-p)
+        (setq evil-inhibit-operator t))
+      (when (fboundp 'widget-button-press)
+        (widget-button-press (point))))
+     ((and (fboundp 'button-at)
+           (fboundp 'push-button)
+           (button-at (point)))
+      (when (evil-operator-state-p)
+        (setq evil-inhibit-operator t))
+      (push-button))
+     ((or (evil-emacs-state-p)
+          (and (evil-insert-state-p)
+               (not buffer-read-only)))
+      (if (not indent?)
+          (newline count)
+        (delete-horizontal-space t)
+        (newline count)
+        (indent-according-to-mode)))
+     (t
+      (evil-next-line-first-non-blank count)))))
+
+(evil-define-motion evil-ret (count)
+  "Move the cursor COUNT lines down.
+If point is on a widget or a button, click on it.
+In Insert state, insert a newline."
+  :type line
+  (evil-ret-gen count nil))
+
+(evil-define-motion evil-ret-and-indent (count)
+  "Move the cursor COUNT lines down.
+If point is on a widget or a button, click on it.
+In Insert state, insert a newline and indent."
+  :type line
+  (evil-ret-gen count t))
+
+(evil-define-motion evil-window-top (count)
+  "Move the cursor to line COUNT from the top of the window
+on the first non-blank character."
+  :jump t
+  :type line
+  (move-to-window-line (max (or count 0)
+                            (if (= (point-min) (window-start))
+                                0
+                              scroll-margin)))
+  (back-to-indentation))
+
+(evil-define-motion evil-window-middle ()
+  "Move the cursor to the middle line in the window
+on the first non-blank character."
+  :jump t
+  :type line
+  (move-to-window-line
+   (/ (1+ (save-excursion (move-to-window-line -1))) 2))
+  (back-to-indentation))
+
+(evil-define-motion evil-window-bottom (count)
+  "Move the cursor to line COUNT from the bottom of the window
+on the first non-blank character."
+  :jump t
+  :type line
+  (move-to-window-line (- (max (or count 1) (1+ scroll-margin))))
+  (back-to-indentation))
+
+;; scrolling
+(evil-define-command evil-scroll-line-up (count)
+  "Scrolls the window COUNT lines upwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (let ((scroll-preserve-screen-position nil))
+    (scroll-down count)))
+
+(evil-define-command evil-scroll-line-down (count)
+  "Scrolls the window COUNT lines downwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (let ((scroll-preserve-screen-position nil))
+    (scroll-up count)))
+
+(evil-define-command evil-scroll-count-reset ()
+  "Sets `evil-scroll-count' to 0.
+`evil-scroll-up' and `evil-scroll-down' will scroll
+for a half of the screen(default)."
+  :repeat nil
+  :keep-visual t
+  (interactive)
+  (setq evil-scroll-count 0))
+
+(evil-define-command evil-scroll-up (count)
+  "Scrolls the window and the cursor COUNT lines upwards.
+If COUNT is not specified the function scrolls down
+`evil-scroll-count', which is the last used count.
+If the scroll count is zero the command scrolls half the screen."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (setq count (or count (max 0 evil-scroll-count)))
+    (setq evil-scroll-count count)
+    (when (= (point-min) (line-beginning-position))
+      (signal 'beginning-of-buffer nil))
+    (when (zerop count)
+      (setq count (/ (1- (window-height)) 2)))
+    (let ((xy (posn-x-y (posn-at-point))))
+      (condition-case nil
+          (progn
+            (scroll-down count)
+            (goto-char (posn-point (posn-at-x-y (car xy) (cdr xy)))))
+        (beginning-of-buffer
+         (condition-case nil
+             (with-no-warnings (previous-line count))
+           (beginning-of-buffer)))))))
+
+(evil-define-command evil-scroll-down (count)
+  "Scrolls the window and the cursor COUNT lines downwards.
+If COUNT is not specified the function scrolls down
+`evil-scroll-count', which is the last used count.
+If the scroll count is zero the command scrolls half the screen."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (setq count (or count (max 0 evil-scroll-count)))
+    (setq evil-scroll-count count)
+    (when (eobp) (signal 'end-of-buffer nil))
+    (when (zerop count)
+      (setq count (/ (1- (window-height)) 2)))
+    ;; BUG #660: First check whether the eob is visible.
+    ;; In that case we do not scroll but merely move point.
+    (if (<= (point-max) (window-end))
+        (with-no-warnings (next-line count nil))
+      (let ((xy (posn-x-y (posn-at-point))))
+        (condition-case nil
+            (progn
+              (scroll-up count)
+              (let* ((wend (window-end nil t))
+                     (p (posn-at-x-y (car xy) (cdr xy)))
+                     (margin (max 0 (- scroll-margin
+                                       (cdr (posn-col-row p))))))
+                (goto-char (posn-point p))
+                ;; ensure point is not within the scroll-margin
+                (when (> margin 0)
+                  (with-no-warnings (next-line margin))
+                  (recenter scroll-margin))
+                (when (<= (point-max) wend)
+                  (save-excursion
+                    (goto-char (point-max))
+                    (recenter (- (max 1 scroll-margin)))))))
+          (end-of-buffer
+           (goto-char (point-max))
+           (recenter (- (max 1 scroll-margin)))))))))
+
+(evil-define-command evil-scroll-page-up (count)
+  "Scrolls the window COUNT pages upwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-save-column
+    (dotimes (i count)
+      (condition-case err
+          (scroll-down nil)
+        (beginning-of-buffer
+         (if (and (bobp) (zerop i))
+             (signal (car err) (cdr err))
+           (goto-char (point-min))))))))
+
+(evil-define-command evil-scroll-page-down (count)
+  "Scrolls the window COUNT pages downwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-save-column
+    (dotimes (i count)
+      (condition-case err
+          (scroll-up nil)
+        (end-of-buffer
+         (if (and (eobp) (zerop i))
+             (signal (car err) (cdr err))
+           (goto-char (point-max))))))))
+
+(evil-define-command evil-scroll-line-to-top (count)
+  "Scrolls line number COUNT (or the cursor line) to the top of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (let ((line (or count (line-number-at-pos (point)))))
+      (goto-char (point-min))
+      (forward-line (1- line)))
+    (recenter (1- (max 1 scroll-margin)))))
+
+(evil-define-command evil-scroll-line-to-center (count)
+  "Scrolls line number COUNT (or the cursor line) to the center of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (when count
+      (goto-char (point-min))
+      (forward-line (1- count)))
+    (recenter nil)))
+
+(evil-define-command evil-scroll-line-to-bottom (count)
+  "Scrolls line number COUNT (or the cursor line) to the bottom of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (let ((line (or count (line-number-at-pos (point)))))
+      (goto-char (point-min))
+      (forward-line (1- line)))
+    (recenter (- (max 1 scroll-margin)))))
+
+(evil-define-command evil-scroll-bottom-line-to-top (count)
+  "Scrolls the line right below the window,
+or line COUNT to the top of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (if count
+      (progn
+        (goto-char (point-min))
+        (forward-line (1- count)))
+    (goto-char (window-end))
+    (evil-move-cursor-back))
+  (recenter (1- (max 0 scroll-margin)))
+  (evil-first-non-blank))
+
+(evil-define-command evil-scroll-top-line-to-bottom (count)
+  "Scrolls the line right below the window,
+or line COUNT to the top of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (if count
+      (progn
+        (goto-char (point-min))
+        (forward-line (1- count)))
+    (goto-char (window-start)))
+  (recenter (- (max 1 scroll-margin)))
+  (evil-first-non-blank))
+
+(evil-define-command evil-scroll-left (count)
+  "Scrolls the window COUNT half-screenwidths to the left."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-right (* count (/ (window-width) 2)))))
+
+(evil-define-command evil-scroll-right (count)
+  "Scrolls the window COUNT half-screenwidths to the right."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-left (* count (/ (window-width) 2)))))
+
+(evil-define-command evil-scroll-column-left (count)
+  "Scrolls the window COUNT columns to the left."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-right count)))
+
+(evil-define-command evil-scroll-column-right (count)
+  "Scrolls the window COUNT columns to the right."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-left count)))
+
+;;; Text objects
+
+;; Text objects are defined with `evil-define-text-object'. In Visual
+;; state, they modify the current selection; in Operator-Pending
+;; state, they return a pair of buffer positions. Outer text objects
+;; are bound in the keymap `evil-outer-text-objects-map', and inner
+;; text objects are bound in `evil-inner-text-objects-map'.
+;;
+;; Common text objects like words, WORDS, paragraphs and sentences are
+;; defined via a corresponding move-function. This function must have
+;; the following properties:
+;;
+;;   1. Take exactly one argument, the count.
+;;   2. When the count is positive, move point forward to the first
+;;      character after the end of the next count-th object.
+;;   3. When the count is negative, move point backward to the first
+;;      character of the count-th previous object.
+;;   4. If point is placed on the first character of an object, the
+;;      backward motion does NOT count that object.
+;;   5. If point is placed on the last character of an object, the
+;;      forward motion DOES count that object.
+;;   6. The return value is "count left", i.e., in forward direction
+;;      count is decreased by one for each successful move and in
+;;      backward direction count is increased by one for each
+;;      successful move, returning the final value of count.
+;;      Therefore, if the complete move is successful, the return
+;;      value is 0.
+;;
+;; A useful macro in this regard is `evil-motion-loop', which quits
+;; when point does not move further and returns the count difference.
+;; It also provides a "unit value" of 1 or -1 for use in each
+;; iteration. For example, a hypothetical "foo-bar" move could be
+;; written as such:
+;;
+;;     (defun foo-bar (count)
+;;       (evil-motion-loop (var count)
+;;         (forward-foo var) ; `var' is 1 or -1 depending on COUNT
+;;         (forward-bar var)))
+;;
+;; If "forward-foo" and "-bar" didn't accept negative arguments,
+;; we could choose their backward equivalents by inspecting `var':
+;;
+;;     (defun foo-bar (count)
+;;       (evil-motion-loop (var count)
+;;         (cond
+;;          ((< var 0)
+;;           (backward-foo 1)
+;;           (backward-bar 1))
+;;          (t
+;;           (forward-foo 1)
+;;           (forward-bar 1)))))
+;;
+;; After a forward motion, point has to be placed on the first
+;; character after some object, unless no motion was possible at all.
+;; Similarly, after a backward motion, point has to be placed on the
+;; first character of some object. This implies that point should
+;; NEVER be moved to eob or bob, unless an object ends or begins at
+;; eob or bob. (Usually, Emacs motions always move as far as possible.
+;; But we want to use the motion-function to identify certain objects
+;; in the buffer, and thus exact movement to object boundaries is
+;; required.)
+
+(evil-define-text-object evil-a-word (count &optional beg end type)
+  "Select a word."
+  (evil-select-an-object 'evil-word beg end type count))
+
+(evil-define-text-object evil-inner-word (count &optional beg end type)
+  "Select inner word."
+  (evil-select-inner-object 'evil-word beg end type count))
+
+(evil-define-text-object evil-a-WORD (count &optional beg end type)
+  "Select a WORD."
+  (evil-select-an-object 'evil-WORD beg end type count))
+
+(evil-define-text-object evil-inner-WORD (count &optional beg end type)
+  "Select inner WORD."
+  (evil-select-inner-object 'evil-WORD beg end type count))
+
+(evil-define-text-object evil-a-symbol (count &optional beg end type)
+  "Select a symbol."
+  (evil-select-an-object 'evil-symbol beg end type count))
+
+(evil-define-text-object evil-inner-symbol (count &optional beg end type)
+  "Select inner symbol."
+  (evil-select-inner-object 'evil-symbol beg end type count))
+
+(evil-define-text-object evil-a-sentence (count &optional beg end type)
+  "Select a sentence."
+  (evil-select-an-object 'evil-sentence beg end type count))
+
+(evil-define-text-object evil-inner-sentence (count &optional beg end type)
+  "Select inner sentence."
+  (evil-select-inner-object 'evil-sentence beg end type count))
+
+(evil-define-text-object evil-a-paragraph (count &optional beg end type)
+  "Select a paragraph."
+  :type line
+  (evil-select-an-object 'evil-paragraph beg end type count t))
+
+(evil-define-text-object evil-inner-paragraph (count &optional beg end type)
+  "Select inner paragraph."
+  :type line
+  (evil-select-inner-object 'evil-paragraph beg end type count t))
+
+(evil-define-text-object evil-a-paren (count &optional beg end type)
+  "Select a parenthesis."
+  :extend-selection nil
+  (evil-select-paren ?( ?) beg end type count t))
+
+(evil-define-text-object evil-inner-paren (count &optional beg end type)
+  "Select inner parenthesis."
+  :extend-selection nil
+  (evil-select-paren ?( ?) beg end type count))
+
+(evil-define-text-object evil-a-bracket (count &optional beg end type)
+  "Select a square bracket."
+  :extend-selection nil
+  (evil-select-paren ?\[ ?\] beg end type count t))
+
+(evil-define-text-object evil-inner-bracket (count &optional beg end type)
+  "Select inner square bracket."
+  :extend-selection nil
+  (evil-select-paren ?\[ ?\] beg end type count))
+
+(evil-define-text-object evil-a-curly (count &optional beg end type)
+  "Select a curly bracket (\"brace\")."
+  :extend-selection nil
+  (evil-select-paren ?{ ?} beg end type count t))
+
+(evil-define-text-object evil-inner-curly (count &optional beg end type)
+  "Select inner curly bracket (\"brace\")."
+  :extend-selection nil
+  (evil-select-paren ?{ ?} beg end type count))
+
+(evil-define-text-object evil-an-angle (count &optional beg end type)
+  "Select an angle bracket."
+  :extend-selection nil
+  (evil-select-paren ?< ?> beg end type count t))
+
+(evil-define-text-object evil-inner-angle (count &optional beg end type)
+  "Select inner angle bracket."
+  :extend-selection nil
+  (evil-select-paren ?< ?> beg end type count))
+
+(evil-define-text-object evil-a-single-quote (count &optional beg end type)
+  "Select a single-quoted expression."
+  :extend-selection t
+  (evil-select-quote ?' beg end type count t))
+
+(evil-define-text-object evil-inner-single-quote (count &optional beg end type)
+  "Select inner single-quoted expression."
+  :extend-selection nil
+  (evil-select-quote ?' beg end type count))
+
+(evil-define-text-object evil-a-double-quote (count &optional beg end type)
+  "Select a double-quoted expression."
+  :extend-selection t
+  (evil-select-quote ?\" beg end type count t))
+
+(evil-define-text-object evil-inner-double-quote (count &optional beg end type)
+  "Select inner double-quoted expression."
+  :extend-selection nil
+  (evil-select-quote ?\" beg end type count))
+
+(evil-define-text-object evil-a-back-quote (count &optional beg end type)
+  "Select a back-quoted expression."
+  :extend-selection t
+  (evil-select-quote ?\` beg end type count t))
+
+(evil-define-text-object evil-inner-back-quote (count &optional beg end type)
+  "Select inner back-quoted expression."
+  :extend-selection nil
+  (evil-select-quote ?\` beg end type count))
+
+(evil-define-text-object evil-a-tag (count &optional beg end type)
+  "Select a tag block."
+  :extend-selection nil
+  (evil-select-xml-tag beg end type count t))
+
+(evil-define-text-object evil-inner-tag (count &optional beg end type)
+  "Select inner tag block."
+  :extend-selection nil
+  (evil-select-xml-tag beg end type count))
+
+(evil-define-text-object evil-next-match (count &optional beg end type)
+  "Select next match."
+  (unless (and (boundp 'evil-search-module)
+               (eq evil-search-module 'evil-search))
+    (user-error "next-match text objects only work with Evil search module."))
+  (let ((pnt (point)))
+    (cond
+     ((eq evil-ex-search-direction 'forward)
+      (unless (eobp) (forward-char))
+      (evil-ex-search-previous 1)
+      (when (and (<= evil-ex-search-match-beg pnt)
+                 (> evil-ex-search-match-end pnt)
+                 (not (evil-visual-state-p)))
+        (setq count (1- count)))
+      (if (> count 0) (evil-ex-search-next count)))
+     (t
+      (unless (eobp) (forward-char))
+      (evil-ex-search-next count))))
+  ;; active visual state if command is executed in normal state
+  (when (evil-normal-state-p)
+    (evil-visual-select evil-ex-search-match-beg evil-ex-search-match-end 'inclusive +1 t))
+  (list evil-ex-search-match-beg evil-ex-search-match-end))
+
+(evil-define-text-object evil-previous-match (count &optional beg end type)
+  "Select next match."
+  (unless (and (boundp 'evil-search-module)
+               (eq evil-search-module 'evil-search))
+    (user-error "previous-match text objects only work with Evil search module."))
+  (let ((evil-ex-search-direction
+         (if (eq evil-ex-search-direction 'backward)
+             'forward
+           'backward)))
+    (evil-next-match count beg end type)))
+
+;;; Operator commands
+
+(evil-define-operator evil-yank (beg end type register yank-handler)
+  "Saves the characters in motion into the kill-ring."
+  :move-point nil
+  :repeat nil
+  (interactive "<R><x><y>")
+  (let ((evil-was-yanked-without-register
+         (and evil-was-yanked-without-register (not register))))
+    (cond
+     ((and (fboundp 'cua--global-mark-active)
+           (fboundp 'cua-copy-region-to-global-mark)
+           (cua--global-mark-active))
+      (cua-copy-region-to-global-mark beg end))
+     ((eq type 'block)
+      (evil-yank-rectangle beg end register yank-handler))
+     ((eq type 'line)
+      (evil-yank-lines beg end register yank-handler))
+     (t
+      (evil-yank-characters beg end register yank-handler)))))
+
+(evil-define-operator evil-yank-line (beg end type register)
+  "Saves whole lines into the kill-ring."
+  :motion evil-line
+  :move-point nil
+  (interactive "<R><x>")
+  (when (evil-visual-state-p)
+    (unless (memq type '(line block))
+      (let ((range (evil-expand beg end 'line)))
+        (setq beg (evil-range-beginning range)
+              end (evil-range-end range)
+              type (evil-type range))))
+    (evil-exit-visual-state))
+  (evil-yank beg end type register))
+
+(evil-define-operator evil-delete (beg end type register yank-handler)
+  "Delete text from BEG to END with TYPE.
+Save in REGISTER or in the kill-ring with YANK-HANDLER."
+  (interactive "<R><x><y>")
+  (unless register
+    (let ((text (filter-buffer-substring beg end)))
+      (unless (string-match-p "\n" text)
+        ;; set the small delete register
+        (evil-set-register ?- text))))
+  (let ((evil-was-yanked-without-register nil))
+    (evil-yank beg end type register yank-handler))
+  (cond
+   ((eq type 'block)
+    (evil-apply-on-block #'delete-region beg end nil))
+   ((and (eq type 'line)
+         (= end (point-max))
+         (or (= beg end)
+             (/= (char-before end) ?\n))
+         (/= beg (point-min))
+         (=  (char-before beg) ?\n))
+    (delete-region (1- beg) end))
+   (t
+    (delete-region beg end)))
+  ;; place cursor on beginning of line
+  (when (and (called-interactively-p 'any)
+             (eq type 'line))
+    (evil-first-non-blank)))
+
+(evil-define-operator evil-delete-line (beg end type register yank-handler)
+  "Delete to end of line."
+  :motion nil
+  :keep-visual t
+  (interactive "<R><x>")
+  ;; act linewise in Visual state
+  (let* ((beg (or beg (point)))
+         (end (or end beg)))
+    (when (evil-visual-state-p)
+      (unless (memq type '(line block))
+        (let ((range (evil-expand beg end 'line)))
+          (setq beg (evil-range-beginning range)
+                end (evil-range-end range)
+                type (evil-type range))))
+      (evil-exit-visual-state))
+    (cond
+     ((eq type 'block)
+      ;; equivalent to $d, i.e., we use the block-to-eol selection and
+      ;; call `evil-delete'. In this case we fake the call to
+      ;; `evil-end-of-line' by setting `temporary-goal-column' and
+      ;; `last-command' appropriately as `evil-end-of-line' would do.
+      (let ((temporary-goal-column most-positive-fixnum)
+            (last-command 'next-line))
+        (evil-delete beg end 'block register yank-handler)))
+     ((eq type 'line)
+      (evil-delete beg end type register yank-handler))
+     (t
+      (evil-delete beg (line-end-position) type register yank-handler)))))
+
+(evil-define-operator evil-delete-whole-line
+  (beg end type register yank-handler)
+  "Delete whole line."
+  :motion evil-line
+  (interactive "<R><x>")
+  (evil-delete beg end type register yank-handler))
+
+(evil-define-operator evil-delete-char (beg end type register)
+  "Delete next character."
+  :motion evil-forward-char
+  (interactive "<R><x>")
+  (evil-delete beg end type register))
+
+(evil-define-operator evil-delete-backward-char (beg end type register)
+  "Delete previous character."
+  :motion evil-backward-char
+  (interactive "<R><x>")
+  (evil-delete beg end type register))
+
+(evil-define-command evil-delete-backward-char-and-join (count)
+  "Delete previous character and join lines.
+If point is at the beginning of a line then the current line will
+be joined with the previous line if and only if
+`evil-backspace-join-lines'."
+  (interactive "p")
+  (if (or evil-backspace-join-lines (not (bolp)))
+      (call-interactively 'delete-backward-char)
+    (user-error "Beginning of line")))
+
+(evil-define-command evil-delete-backward-word ()
+  "Delete previous word."
+  (if (and (bolp) (not (bobp)))
+      (progn
+        (unless evil-backspace-join-lines (user-error "Beginning of line"))
+        (delete-char -1))
+    (delete-region (max
+                    (save-excursion
+                      (evil-backward-word-begin)
+                      (point))
+                    (line-beginning-position))
+                   (point))))
+
+(defun evil-ex-delete-or-yank (should-delete beg end type register count yank-handler)
+  "Execute evil-delete or evil-yank on the given region.
+If SHOULD-DELETE is t, evil-delete will be executed, otherwise
+evil-yank.
+The region specified by BEG and END will be adjusted if COUNT is
+given."
+  (when count
+    ;; with COUNT, the command should go the end of the region and delete/yank
+    ;; COUNT lines from there
+    (setq beg (save-excursion
+                (goto-char end)
+                (forward-line -1)
+                (point))
+          end (save-excursion
+                (goto-char end)
+                (point-at-bol count))
+          type 'line))
+  (funcall (if should-delete 'evil-delete 'evil-yank) beg end type register yank-handler))
+
+(evil-define-operator evil-ex-delete (beg end type register count yank-handler)
+  "The Ex delete command.
+\[BEG,END]delete [REGISTER] [COUNT]"
+  (interactive "<R><xc/><y>")
+  (evil-ex-delete-or-yank t beg end type register count yank-handler))
+
+(evil-define-operator evil-ex-yank (beg end type register count yank-handler)
+  "The Ex yank command.
+\[BEG,END]yank [REGISTER] [COUNT]"
+  (interactive "<R><xc/><y>")
+  (evil-ex-delete-or-yank nil beg end type register count yank-handler))
+
+(evil-define-operator evil-change
+  (beg end type register yank-handler delete-func)
+  "Change text from BEG to END with TYPE.
+Save in REGISTER or the kill-ring with YANK-HANDLER.
+DELETE-FUNC is a function for deleting text, default `evil-delete'.
+If TYPE is `line', insertion starts on an empty line.
+If TYPE is `block', the inserted text in inserted at each line
+of the block."
+  (interactive "<R><x><y>")
+  (let ((delete-func (or delete-func #'evil-delete))
+        (nlines (1+ (evil-count-lines beg end)))
+        (opoint (save-excursion
+                  (goto-char beg)
+                  (line-beginning-position))))
+    (unless (eq evil-want-fine-undo t)
+      (evil-start-undo-step))
+    (funcall delete-func beg end type register yank-handler)
+    (cond
+     ((eq type 'line)
+      (if ( = opoint (point))
+          (evil-open-above 1)
+        (evil-open-below 1)))
+     ((eq type 'block)
+      (evil-insert 1 nlines))
+     (t
+      (evil-insert 1)))))
+
+(evil-define-operator evil-change-line (beg end type register yank-handler)
+  "Change to end of line."
+  :motion evil-end-of-line
+  (interactive "<R><x><y>")
+  (evil-change beg end type register yank-handler #'evil-delete-line))
+
+(evil-define-operator evil-change-whole-line
+  (beg end type register yank-handler)
+  "Change whole line."
+  :motion evil-line
+  (interactive "<R><x>")
+  (evil-change beg end type register yank-handler #'evil-delete-whole-line))
+
+(evil-define-command evil-copy (beg end address)
+  "Copy lines in BEG END below line given by ADDRESS."
+  :motion evil-line
+  (interactive "<r><addr>")
+  (goto-char (point-min))
+  (forward-line address)
+  (let* ((txt (buffer-substring-no-properties beg end))
+         (len (length txt)))
+    ;; ensure text consists of complete lines
+    (when (or (zerop len) (/= (aref txt (1- len)) ?\n))
+      (setq txt (concat txt "\n")))
+    (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line
+    (insert txt)
+    (forward-line -1)))
+
+(evil-define-command evil-move (beg end address)
+  "Move lines in BEG END below line given by ADDRESS."
+  :motion evil-line
+  (interactive "<r><addr>")
+  (goto-char (point-min))
+  (forward-line address)
+  (let* ((m (set-marker (make-marker) (point)))
+         (txt (buffer-substring-no-properties beg end))
+         (len (length txt)))
+    (delete-region beg end)
+    (goto-char m)
+    (set-marker m nil)
+    ;; ensure text consists of complete lines
+    (when (or (zerop len) (/= (aref txt (1- len)) ?\n))
+      (setq txt (concat txt "\n")))
+    (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line
+    (when (evil-visual-state-p)
+      (move-marker evil-visual-mark (point)))
+    (insert txt)
+    (forward-line -1)
+    (when (evil-visual-state-p)
+      (move-marker evil-visual-point (point)))))
+
+(evil-define-operator evil-substitute (beg end type register)
+  "Change a character."
+  :motion evil-forward-char
+  (interactive "<R><x>")
+  (evil-change beg end type register))
+
+(evil-define-operator evil-upcase (beg end type)
+  "Convert text to upper case."
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-upcase beg end nil)
+    (upcase-region beg end)))
+
+(evil-define-operator evil-downcase (beg end type)
+  "Convert text to lower case."
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-downcase beg end nil)
+    (downcase-region beg end)))
+
+(evil-define-operator evil-invert-case (beg end type)
+  "Invert case of text."
+  (let (char)
+    (if (eq type 'block)
+        (evil-apply-on-block #'evil-invert-case beg end nil)
+      (save-excursion
+        (goto-char beg)
+        (while (< beg end)
+          (setq char (following-char))
+          (delete-char 1 nil)
+          (if (eq (upcase char) char)
+              (insert-char (downcase char) 1)
+            (insert-char (upcase char) 1))
+          (setq beg (1+ beg)))))))
+
+(evil-define-operator evil-invert-char (beg end type)
+  "Invert case of character."
+  :motion evil-forward-char
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-invert-case beg end nil)
+    (evil-invert-case beg end)
+    (when evil-this-motion
+      (goto-char end)
+      (when (and evil-cross-lines
+                 evil-move-cursor-back
+                 (not evil-move-beyond-eol)
+                 (not (evil-visual-state-p))
+                 (not (evil-operator-state-p))
+                 (eolp) (not (eobp)) (not (bolp)))
+        (forward-char)))))
+
+(evil-define-operator evil-rot13 (beg end type)
+  "ROT13 encrypt text."
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-rot13 beg end nil)
+    (rot13-region beg end)))
+
+(evil-define-operator evil-join (beg end)
+  "Join the selected lines."
+  :motion evil-line
+  (let ((count (count-lines beg end)))
+    (when (> count 1)
+      (setq count (1- count)))
+    (goto-char beg)
+    (dotimes (var count)
+      (join-line 1))))
+
+(evil-define-operator evil-join-whitespace (beg end)
+  "Join the selected lines without changing whitespace.
+\\<evil-normal-state-map>Like \\[evil-join], \
+but doesn't insert or remove any spaces."
+  :motion evil-line
+  (let ((count (count-lines beg end)))
+    (when (> count 1)
+      (setq count (1- count)))
+    (goto-char beg)
+    (dotimes (var count)
+      (evil-move-end-of-line 1)
+      (unless (eobp)
+        (delete-char 1)))))
+
+(evil-define-operator evil-ex-join (beg end &optional count bang)
+  "Join the selected lines with optional COUNT and BANG."
+  (interactive "<r><a><!>")
+  (if (and count (not (string-match-p "^[1-9][0-9]*$" count)))
+      (user-error "Invalid count")
+    (let ((join-fn (if bang 'evil-join-whitespace 'evil-join)))
+      (cond
+       ((not count)
+        ;; without count - just join the given region
+        (funcall join-fn beg end))
+       (t
+        ;; emulate vim's :join when count is given - start from the
+        ;; end of the region and join COUNT lines from there
+        (let* ((count-num (string-to-number count))
+               (beg-adjusted (save-excursion
+                               (goto-char end)
+                               (forward-line -1)
+                               (point)))
+               (end-adjusted (save-excursion
+                               (goto-char end)
+                               (point-at-bol count-num))))
+          (funcall join-fn beg-adjusted end-adjusted)))))))
+
+(evil-define-operator evil-fill (beg end)
+  "Fill text."
+  :move-point nil
+  :type line
+  (save-excursion
+    (condition-case nil
+        (fill-region beg end)
+      (error nil))))
+
+(evil-define-operator evil-fill-and-move (beg end)
+  "Fill text and move point to the end of the filled region."
+  :move-point nil
+  :type line
+  (let ((marker (make-marker)))
+    (move-marker marker (1- end))
+    (condition-case nil
+        (progn
+          (fill-region beg end)
+          (goto-char marker)
+          (evil-first-non-blank))
+      (error nil))))
+
+(evil-define-operator evil-indent (beg end)
+  "Indent text."
+  :move-point nil
+  :type line
+  (if (and (= beg (line-beginning-position))
+           (= end (line-beginning-position 2)))
+      ;; since some Emacs modes can only indent one line at a time,
+      ;; implement "==" as a call to `indent-according-to-mode'
+      (indent-according-to-mode)
+    (goto-char beg)
+    (indent-region beg end))
+  ;; We also need to tabify or untabify the leading white characters
+  (when evil-indent-convert-tabs
+    (let* ((beg-line (line-number-at-pos beg))
+           (end-line (line-number-at-pos end))
+           (ln beg-line)
+           (convert-white (if indent-tabs-mode 'tabify 'untabify)))
+      (save-excursion
+        (while (<= ln end-line)
+          (goto-char (point-min))
+          (forward-line (- ln 1))
+          (back-to-indentation)
+          ;; Whether tab or space should be used is determined by indent-tabs-mode
+          (funcall convert-white (line-beginning-position) (point))
+          (setq ln (1+ ln)))))
+    (back-to-indentation)))
+
+(evil-define-operator evil-indent-line (beg end)
+  "Indent the line."
+  :motion evil-line
+  (evil-indent beg end))
+
+(evil-define-operator evil-shift-left (beg end &optional count preserve-empty)
+  "Shift text from BEG to END to the left.
+The text is shifted to the nearest multiple of `evil-shift-width'
+\(the rounding can be disabled by setting `evil-shift-round').
+If PRESERVE-EMPTY is non-nil, lines that contain only spaces are
+indented, too, otherwise they are ignored.  The relative column
+of point is preserved if this function is not called
+interactively. Otherwise, if the function is called as an
+operator, point is moved to the first non-blank character.
+See also `evil-shift-right'."
+  :type line
+  (interactive "<r><vc>")
+  (evil-shift-right beg end (- (or count 1)) preserve-empty))
+
+(evil-define-operator evil-shift-right (beg end &optional count preserve-empty)
+  "Shift text from BEG to END to the right.
+The text is shifted to the nearest multiple of `evil-shift-width'
+\(the rounding can be disabled by setting `evil-shift-round').
+If PRESERVE-EMPTY is non-nil, lines that contain only spaces are
+indented, too, otherwise they are ignored.  The relative column
+of point is preserved if this function is not called
+interactively. Otherwise, if the function is called as an
+operator, point is moved to the first non-blank character.
+See also `evil-shift-left'."
+  :type line
+  (interactive "<r><vc>")
+  (setq count (or count 1))
+  (let ((beg (set-marker (make-marker) beg))
+        (end (set-marker (make-marker) end))
+        (pnt-indent (current-column))
+        first-shift) ; shift of first line
+    (save-excursion
+      (goto-char beg)
+      (while (< (point) end)
+        (let* ((indent (current-indentation))
+               (new-indent
+                (max 0
+                     (if (not evil-shift-round)
+                         (+ indent (* count evil-shift-width))
+                       (* (+ (/ indent evil-shift-width)
+                             count
+                             (cond
+                              ((> count 0) 0)
+                              ((zerop (mod indent evil-shift-width)) 0)
+                              (t 1)))
+                          evil-shift-width)))))
+          (unless first-shift
+            (setq first-shift (- new-indent indent)))
+          (when (or preserve-empty
+                    (save-excursion
+                      (skip-chars-forward " \t")
+                      (not (eolp))))
+            (indent-to new-indent 0))
+          (delete-region (point) (progn (skip-chars-forward " \t") (point)))
+          (forward-line 1))))
+    ;; assuming that point is in the first line, adjust its position
+    (if (called-interactively-p 'any)
+        (evil-first-non-blank)
+      (move-to-column (max 0 (+ pnt-indent first-shift))))))
+
+(evil-define-command evil-shift-right-line (count)
+  "Shift the current line COUNT times to the right.
+The text is shifted to the nearest multiple of
+`evil-shift-width'. Like `evil-shift-right' but always works on
+the current line."
+  (interactive "<c>")
+  (evil-shift-right (line-beginning-position) (line-beginning-position 2) count t))
+
+(evil-define-command evil-shift-left-line (count)
+  "Shift the current line COUNT times to the left.
+The text is shifted to the nearest multiple of
+`evil-shift-width'. Like `evil-shift-left' but always works on
+the current line."
+  (interactive "<c>")
+  (evil-shift-left (line-beginning-position) (line-beginning-position 2) count t))
+
+(evil-define-operator evil-align-left (beg end type &optional width)
+  "Right-align lines in the region at WIDTH columns.
+The default for width is the value of `fill-column'."
+  :motion evil-line
+  :type line
+  (interactive "<R><a>")
+  (evil-justify-lines beg end 'left (if width
+                                        (string-to-number width)
+                                      0)))
+
+(evil-define-operator evil-align-right (beg end type &optional width)
+  "Right-align lines in the region at WIDTH columns.
+The default for width is the value of `fill-column'."
+  :motion evil-line
+  :type line
+  (interactive "<R><a>")
+  (evil-justify-lines beg end 'right (if width
+                                         (string-to-number width)
+                                       fill-column)))
+
+(evil-define-operator evil-align-center (beg end type &optional width)
+  "Centers lines in the region between WIDTH columns.
+The default for width is the value of `fill-column'."
+  :motion evil-line
+  :type line
+  (interactive "<R><a>")
+  (evil-justify-lines beg end 'center (if width
+                                          (string-to-number width)
+                                        fill-column)))
+
+(evil-define-operator evil-replace (beg end type char)
+  "Replace text from BEG to END with CHAR."
+  :motion evil-forward-char
+  (interactive "<R>"
+               (unwind-protect
+                   (let ((evil-force-cursor 'replace))
+                     (evil-refresh-cursor)
+                     (list (evil-read-key)))
+                 (evil-refresh-cursor)))
+  (when char
+    (if (eq type 'block)
+        (save-excursion
+          (evil-apply-on-rectangle
+           #'(lambda (begcol endcol char)
+               (let ((maxcol (evil-column (line-end-position))))
+                 (when (< begcol maxcol)
+                   (setq endcol (min endcol maxcol))
+                   (let ((beg (evil-move-to-column begcol nil t))
+                         (end (evil-move-to-column endcol nil t)))
+                     (delete-region beg end)
+                     (insert (make-string (- endcol begcol) char))))))
+           beg end char))
+      (goto-char beg)
+      (cond
+       ((eq char ?\n)
+        (delete-region beg end)
+        (newline)
+        (when evil-auto-indent
+          (indent-according-to-mode)))
+       (t
+        (while (< (point) end)
+          (if (eq (char-after) ?\n)
+              (forward-char)
+            (delete-char 1)
+            (insert-char char 1)))
+        (goto-char (max beg (1- end))))))))
+
+(evil-define-command evil-paste-before
+  (count &optional register yank-handler)
+  "Pastes the latest yanked text before the cursor position.
+The return value is the yanked text."
+  :suppress-operator t
+  (interactive "P<x>")
+  (if (evil-visual-state-p)
+      (evil-visual-paste count register)
+    (evil-with-undo
+      (let* ((text (if register
+                       (evil-get-register register)
+                     (current-kill 0)))
+             (yank-handler (or yank-handler
+                               (when (stringp text)
+                                 (car-safe (get-text-property
+                                            0 'yank-handler text)))))
+             (opoint (point)))
+        (when text
+          (if (functionp yank-handler)
+              (let ((evil-paste-count count)
+                    ;; for non-interactive use
+                    (this-command #'evil-paste-before))
+                (push-mark opoint t)
+                (insert-for-yank text))
+            ;; no yank-handler, default
+            (when (vectorp text)
+              (setq text (evil-vector-to-string text)))
+            (set-text-properties 0 (length text) nil text)
+            (push-mark opoint t)
+            (dotimes (i (or count 1))
+              (insert-for-yank text))
+            (setq evil-last-paste
+                  (list #'evil-paste-before
+                        count
+                        opoint
+                        opoint    ; beg
+                        (point))) ; end
+            (evil-set-marker ?\[ opoint)
+            (evil-set-marker ?\] (1- (point)))
+            (when (and evil-move-cursor-back
+                       (> (length text) 0))
+              (backward-char))))
+        ;; no paste-pop after pasting from a register
+        (when register
+          (setq evil-last-paste nil))
+        (and (> (length text) 0) text)))))
+
+(evil-define-command evil-paste-after
+  (count &optional register yank-handler)
+  "Pastes the latest yanked text behind point.
+The return value is the yanked text."
+  :suppress-operator t
+  (interactive "P<x>")
+  (if (evil-visual-state-p)
+      (evil-visual-paste count register)
+    (evil-with-undo
+      (let* ((text (if register
+                       (evil-get-register register)
+                     (current-kill 0)))
+             (yank-handler (or yank-handler
+                               (when (stringp text)
+                                 (car-safe (get-text-property
+                                            0 'yank-handler text)))))
+             (opoint (point)))
+        (when text
+          (if (functionp yank-handler)
+              (let ((evil-paste-count count)
+                    ;; for non-interactive use
+                    (this-command #'evil-paste-after))
+                (insert-for-yank text))
+            ;; no yank-handler, default
+            (when (vectorp text)
+              (setq text (evil-vector-to-string text)))
+            (set-text-properties 0 (length text) nil text)
+            (unless (eolp) (forward-char))
+            (push-mark (point) t)
+            ;; TODO: Perhaps it is better to collect a list of all
+            ;; (point . mark) pairs to undo the yanking for COUNT > 1.
+            ;; The reason is that this yanking could very well use
+            ;; `yank-handler'.
+            (let ((beg (point)))
+              (dotimes (i (or count 1))
+                (insert-for-yank text))
+              (setq evil-last-paste
+                    (list #'evil-paste-after
+                          count
+                          opoint
+                          beg       ; beg
+                          (point))) ; end
+              (evil-set-marker ?\[ beg)
+              (evil-set-marker ?\] (1- (point)))
+              (when (evil-normal-state-p)
+                (evil-move-cursor-back)))))
+        (when register
+          (setq evil-last-paste nil))
+        (and (> (length text) 0) text)))))
+
+(evil-define-command evil-visual-paste (count &optional register)
+  "Paste over Visual selection."
+  :suppress-operator t
+  (interactive "P<x>")
+  ;; evil-visual-paste is typically called from evil-paste-before or
+  ;; evil-paste-after, but we have to mark that the paste was from
+  ;; visual state
+  (setq this-command 'evil-visual-paste)
+  (let* ((text (if register
+                   (evil-get-register register)
+                 (current-kill 0)))
+         (yank-handler (car-safe (get-text-property
+                                  0 'yank-handler text)))
+         new-kill
+         paste-eob)
+    (evil-with-undo
+      (let* ((kill-ring (list (current-kill 0)))
+             (kill-ring-yank-pointer kill-ring))
+        (when (evil-visual-state-p)
+          (evil-visual-rotate 'upper-left)
+          ;; if we replace the last buffer line that does not end in a
+          ;; newline, we use `evil-paste-after' because `evil-delete'
+          ;; will move point to the line above
+          (when (and (= evil-visual-end (point-max))
+                     (/= (char-before (point-max)) ?\n))
+            (setq paste-eob t))
+          (evil-delete evil-visual-beginning evil-visual-end
+                       (evil-visual-type))
+          (when (and (eq yank-handler #'evil-yank-line-handler)
+                     (not (eq (evil-visual-type) 'line))
+                     (not (= evil-visual-end (point-max))))
+            (insert "\n"))
+          (evil-normal-state)
+          (setq new-kill (current-kill 0))
+          (current-kill 1))
+        (if paste-eob
+            (evil-paste-after count register)
+          (evil-paste-before count register)))
+      (when evil-kill-on-visual-paste
+        (kill-new new-kill))
+      ;; mark the last paste as visual-paste
+      (setq evil-last-paste
+            (list (nth 0 evil-last-paste)
+                  (nth 1 evil-last-paste)
+                  (nth 2 evil-last-paste)
+                  (nth 3 evil-last-paste)
+                  (nth 4 evil-last-paste)
+                  t)))))
+
+(defun evil-paste-from-register (register)
+  "Paste from REGISTER."
+  (interactive
+   (let ((overlay (make-overlay (point) (point)))
+         (string "\""))
+     (unwind-protect
+         (progn
+           ;; display " in the buffer while reading register
+           (put-text-property 0 1 'face 'minibuffer-prompt string)
+           (put-text-property 0 1 'cursor t string)
+           (overlay-put overlay 'after-string string)
+           (list (or evil-this-register (read-char))))
+       (delete-overlay overlay))))
+  (when (evil-paste-before nil register t)
+    ;; go to end of pasted text
+    (unless (eobp)
+      (forward-char))))
+
+(defun evil-paste-last-insertion ()
+  "Paste last insertion."
+  (interactive)
+  (evil-paste-from-register ?.))
+
+(evil-define-command evil-use-register (register)
+  "Use REGISTER for the next command."
+  :keep-visual t
+  :repeat ignore
+  (interactive "<C>")
+  (setq evil-this-register register))
+
+(defvar evil-macro-buffer nil
+  "The buffer that has been active on macro recording.")
+
+(defun evil-abort-macro ()
+  "Abort macro recording when the buffer is changed.
+Macros are aborted when the the current buffer
+is changed during macro recording."
+  (unless (or (minibufferp) (eq (current-buffer) evil-macro-buffer))
+    (remove-hook 'post-command-hook #'evil-abort-macro)
+    (end-kbd-macro)
+    (message "Abort macro recording (changed buffer)")))
+
+(evil-define-command evil-record-macro (register)
+  "Record a keyboard macro into REGISTER.
+If REGISTER is :, /, or ?, the corresponding command line window
+will be opened instead."
+  :keep-visual t
+  :suppress-operator t
+  (interactive
+   (list (unless (and evil-this-macro defining-kbd-macro)
+           (or evil-this-register (evil-read-key)))))
+  (cond
+   ((eq register ?\C-g)
+    (keyboard-quit))
+   ((and evil-this-macro defining-kbd-macro)
+    (remove-hook 'post-command-hook #'evil-abort-macro)
+    (setq evil-macro-buffer nil)
+    (condition-case nil
+        (end-kbd-macro)
+      (error nil))
+    (when last-kbd-macro
+      (when (member last-kbd-macro '("" []))
+        (setq last-kbd-macro nil))
+      (evil-set-register evil-this-macro last-kbd-macro))
+    (setq evil-this-macro nil))
+   ((eq register ?:)
+    (evil-command-window-ex))
+   ((eq register ?/)
+    (evil-command-window-search-forward))
+   ((eq register ??)
+    (evil-command-window-search-backward))
+   ((or (and (>= register ?0) (<= register ?9))
+        (and (>= register ?a) (<= register ?z))
+        (and (>= register ?A) (<= register ?Z)))
+    (when defining-kbd-macro (end-kbd-macro))
+    (setq evil-this-macro register)
+    (evil-set-register evil-this-macro nil)
+    (start-kbd-macro nil)
+    (setq evil-macro-buffer (current-buffer))
+    (add-hook 'post-command-hook #'evil-abort-macro))
+   (t (error "Invalid register"))))
+
+(evil-define-command evil-execute-macro (count macro)
+  "Execute keyboard macro MACRO, COUNT times.
+When called with a non-numerical prefix \
+\(such as \\[universal-argument]),
+COUNT is infinite. MACRO is read from a register
+when called interactively."
+  :keep-visual t
+  :suppress-operator t
+  (interactive
+   (let (count macro register)
+     (setq count (if current-prefix-arg
+                     (if (numberp current-prefix-arg)
+                         current-prefix-arg
+                       0) 1)
+           register (or evil-this-register (read-char)))
+     (cond
+      ((or (and (eq register ?@) (eq evil-last-register ?:))
+           (eq register ?:))
+       (setq macro (lambda () (evil-ex-repeat nil))
+             evil-last-register ?:))
+      ((eq register ?@)
+       (unless evil-last-register
+         (user-error "No previously executed keyboard macro."))
+       (setq macro (evil-get-register evil-last-register t)))
+      (t
+       (setq macro (evil-get-register register t)
+             evil-last-register register)))
+     (list count macro)))
+  (cond
+   ((functionp macro)
+    (evil-repeat-abort)
+    (dotimes (i (or count 1))
+      (funcall macro)))
+   ((or (and (not (stringp macro))
+             (not (vectorp macro)))
+        (member macro '("" [])))
+    ;; allow references to currently empty registers
+    ;; when defining macro
+    (unless evil-this-macro
+      (user-error "No previous macro")))
+   (t
+    (condition-case err
+        (evil-with-single-undo
+          (execute-kbd-macro macro count))
+      ;; enter Normal state if the macro fails
+      (error
+       (evil-normal-state)
+       (evil-normalize-keymaps)
+       (signal (car err) (cdr err)))))))
+
+;;; Visual commands
+
+(evil-define-motion evil-visual-restore ()
+  "Restore previous selection."
+  (let* ((point (point))
+         (mark (or (mark t) point))
+         (dir evil-visual-direction)
+         (type (evil-visual-type))
+         range)
+    (unless (evil-visual-state-p)
+      (cond
+       ;; No previous selection.
+       ((or (null evil-visual-selection)
+            (null evil-visual-mark)
+            (null evil-visual-point)))
+       ;; If the type was one-to-one, it is preferable to infer
+       ;; point and mark from the selection's boundaries. The reason
+       ;; is that a destructive operation may displace the markers
+       ;; inside the selection.
+       ((evil-type-property type :one-to-one)
+        (setq range (evil-contract-range (evil-visual-range))
+              mark (evil-range-beginning range)
+              point (evil-range-end range))
+        (when (< dir 0)
+          (evil-swap mark point)))
+       ;; If the type wasn't one-to-one, we have to restore the
+       ;; selection on the basis of the previous point and mark.
+       (t
+        (setq mark evil-visual-mark
+              point evil-visual-point)))
+      (evil-visual-make-selection mark point type t))))
+
+(evil-define-motion evil-visual-exchange-corners ()
+  "Rearrange corners in Visual Block mode.
+
+        M---+           +---M
+        |   |    <=>    |   |
+        +---P           P---+
+
+For example, if mark is in the upper left corner and point
+in the lower right, this function puts mark in the upper right
+corner and point in the lower left."
+  (cond
+   ((eq evil-visual-selection 'block)
+    (let* ((point (point))
+           (mark (or (mark t) point))
+           (point-col (evil-column point))
+           (mark-col (evil-column mark))
+           (mark (save-excursion
+                   (goto-char mark)
+                   (evil-move-to-column point-col)
+                   (point)))
+           (point (save-excursion
+                    (goto-char point)
+                    (evil-move-to-column mark-col)
+                    (point))))
+      (evil-visual-refresh mark point)))
+   (t
+    (evil-exchange-point-and-mark)
+    (evil-visual-refresh))))
+
+(evil-define-command evil-visual-rotate (corner &optional beg end type)
+  "In Visual Block selection, put point in CORNER.
+Corner may be one of `upper-left', `upper-right', `lower-left'
+and `lower-right':
+
+        upper-left +---+ upper-right
+                   |   |
+        lower-left +---+ lower-right
+
+When called interactively, the selection is rotated blockwise."
+  :keep-visual t
+  (interactive
+   (let ((corners '(upper-left upper-right lower-right lower-left)))
+     (list (or (cadr (memq (evil-visual-block-corner) corners))
+               'upper-left))))
+  (let* ((beg (or beg (point)))
+         (end (or end (mark t) beg))
+         (type (or type evil-this-type))
+         range)
+    (cond
+     ((memq type '(rectangle block))
+      (setq range (evil-block-rotate beg end :corner corner)
+            beg (pop range)
+            end (pop range))
+      (unless (eq corner (evil-visual-block-corner corner beg end))
+        (evil-swap beg end))
+      (goto-char beg)
+      (when (evil-visual-state-p)
+        (evil-move-mark end)
+        (evil-visual-refresh nil nil nil :corner corner)))
+     ((memq corner '(upper-right lower-right))
+      (goto-char (max beg end))
+      (when (evil-visual-state-p)
+        (evil-move-mark (min beg end))))
+     (t
+      (goto-char (min beg end))
+      (when (evil-visual-state-p)
+        (evil-move-mark (max beg end)))))))
+
+;;; Insertion commands
+
+(defun evil-insert (count &optional vcount skip-empty-lines)
+  "Switch to Insert state just before point.
+The insertion will be repeated COUNT times and repeated once for
+the next VCOUNT - 1 lines starting at the same column.
+If SKIP-EMPTY-LINES is non-nil, the insertion will not be performed
+on lines on which the insertion point would be after the end of the
+lines.  This is the default behaviour for Visual-state insertion."
+  (interactive
+   (list (prefix-numeric-value current-prefix-arg)
+         (and (evil-visual-state-p)
+              (memq (evil-visual-type) '(line block))
+              (save-excursion
+                (let ((m (mark)))
+                  ;; go to upper-left corner temporarily so
+                  ;; `count-lines' yields accurate results
+                  (evil-visual-rotate 'upper-left)
+                  (prog1 (count-lines evil-visual-beginning evil-visual-end)
+                    (set-mark m)))))
+         (evil-visual-state-p)))
+  (if (and (called-interactively-p 'any)
+           (evil-visual-state-p))
+      (cond
+       ((eq (evil-visual-type) 'line)
+        (evil-visual-rotate 'upper-left)
+        (evil-insert-line count vcount))
+       ((eq (evil-visual-type) 'block)
+        (let ((column (min (evil-column evil-visual-beginning)
+                           (evil-column evil-visual-end))))
+          (evil-visual-rotate 'upper-left)
+          (move-to-column column t)
+          (evil-insert count vcount skip-empty-lines)))
+       (t
+        (evil-visual-rotate 'upper-left)
+        (evil-insert count vcount skip-empty-lines)))
+    (setq evil-insert-count count
+          evil-insert-lines nil
+          evil-insert-vcount (and vcount
+                                  (> vcount 1)
+                                  (list (line-number-at-pos)
+                                        (current-column)
+                                        vcount))
+          evil-insert-skip-empty-lines skip-empty-lines)
+    (evil-insert-state 1)))
+
+(defun evil-append (count &optional vcount skip-empty-lines)
+  "Switch to Insert state just after point.
+The insertion will be repeated COUNT times and repeated once for
+the next VCOUNT - 1 lines starting at the same column.  If
+SKIP-EMPTY-LINES is non-nil, the insertion will not be performed
+on lines on which the insertion point would be after the end of
+the lines."
+  (interactive
+   (list (prefix-numeric-value current-prefix-arg)
+         (and (evil-visual-state-p)
+              (memq (evil-visual-type) '(line block))
+              (save-excursion
+                (let ((m (mark)))
+                  ;; go to upper-left corner temporarily so
+                  ;; `count-lines' yields accurate results
+                  (evil-visual-rotate 'upper-left)
+                  (prog1 (count-lines evil-visual-beginning evil-visual-end)
+                    (set-mark m)))))))
+  (if (and (called-interactively-p 'any)
+           (evil-visual-state-p))
+      (cond
+       ((or (eq (evil-visual-type) 'line)
+            (and (eq (evil-visual-type) 'block)
+                 (memq last-command '(next-line previous-line))
+                 (numberp temporary-goal-column)
+                 (= temporary-goal-column most-positive-fixnum)))
+        (evil-visual-rotate 'upper-left)
+        (evil-append-line count vcount))
+       ((eq (evil-visual-type) 'block)
+        (let ((column (max (evil-column evil-visual-beginning)
+                           (evil-column evil-visual-end))))
+          (evil-visual-rotate 'upper-left)
+          (move-to-column column t)
+          (evil-insert count vcount skip-empty-lines)))
+       (t
+        (evil-visual-rotate 'lower-right)
+        (evil-append count)))
+    (unless (eolp) (forward-char))
+    (evil-insert count vcount skip-empty-lines)
+    (add-hook 'post-command-hook #'evil-maybe-remove-spaces)))
+
+(defun evil-insert-resume (count)
+  "Switch to Insert state at previous insertion point.
+The insertion will be repeated COUNT times. If called from visual
+state, only place point at the previous insertion position but do not
+switch to insert state."
+  (interactive "p")
+  (evil-goto-mark ?^ t)
+  (unless (evil-visual-state-p)
+    (evil-insert count)))
+
+(defun evil-open-above (count)
+  "Insert a new line above point and switch to Insert state.
+The insertion will be repeated COUNT times."
+  (interactive "p")
+  (unless (eq evil-want-fine-undo t)
+    (evil-start-undo-step))
+  (evil-insert-newline-above)
+  (setq evil-insert-count count
+        evil-insert-lines t
+        evil-insert-vcount nil)
+  (evil-insert-state 1)
+  (when evil-auto-indent
+    (indent-according-to-mode)))
+
+(defun evil-open-below (count)
+  "Insert a new line below point and switch to Insert state.
+The insertion will be repeated COUNT times."
+  (interactive "p")
+  (unless (eq evil-want-fine-undo t)
+    (evil-start-undo-step))
+  (push (point) buffer-undo-list)
+  (evil-insert-newline-below)
+  (setq evil-insert-count count
+        evil-insert-lines t
+        evil-insert-vcount nil)
+  (evil-insert-state 1)
+  (when evil-auto-indent
+    (indent-according-to-mode)))
+
+(defun evil-insert-line (count &optional vcount)
+  "Switch to insert state at beginning of current line.
+Point is placed at the first non-blank character on the current
+line.  The insertion will be repeated COUNT times.  If VCOUNT is
+non nil it should be number > 0. The insertion will be repeated
+in the next VCOUNT - 1 lines below the current one."
+  (interactive "p")
+  (push (point) buffer-undo-list)
+  (back-to-indentation)
+  (setq evil-insert-count count
+        evil-insert-lines nil
+        evil-insert-vcount
+        (and vcount
+             (> vcount 1)
+             (list (line-number-at-pos)
+                   #'evil-first-non-blank
+                   vcount)))
+  (evil-insert-state 1))
+
+(defun evil-append-line (count &optional vcount)
+  "Switch to Insert state at the end of the current line.
+The insertion will be repeated COUNT times.  If VCOUNT is non nil
+it should be number > 0. The insertion will be repeated in the
+next VCOUNT - 1 lines below the current one."
+  (interactive "p")
+  (evil-move-end-of-line)
+  (setq evil-insert-count count
+        evil-insert-lines nil
+        evil-insert-vcount
+        (and vcount
+             (> vcount 1)
+             (list (line-number-at-pos)
+                   #'end-of-line
+                   vcount)))
+  (evil-insert-state 1))
+
+(evil-define-command evil-insert-digraph (count)
+  "Insert COUNT digraphs."
+  :repeat change
+  (interactive "p")
+  (let ((digraph (evil-read-digraph-char 0)))
+    (insert-char digraph count)))
+
+(evil-define-command evil-ex-show-digraphs ()
+  "Shows a list of all available digraphs."
+  :repeat nil
+  (let ((columns 3))
+    (evil-with-view-list
+      :name "evil-digraphs"
+      :mode-name "Evil Digraphs"
+      :format
+      (cl-loop repeat columns
+               vconcat [("Digraph" 8 nil)
+                        ("Sequence" 16 nil)])
+      :entries
+      (let* ((digraphs (mapcar #'(lambda (digraph)
+                                   (cons (cdr digraph)
+                                         (car digraph)))
+                               (append evil-digraphs-table
+                                       evil-digraphs-table-user)))
+             (entries (cl-loop for digraph in digraphs
+                               collect `(,(concat (char-to-string (nth 1 digraph))
+                                                  (char-to-string (nth 2 digraph)))
+                                         ,(char-to-string (nth 0 digraph)))))
+             (row)
+             (rows)
+             (clength (* columns 2)))
+        (cl-loop for e in entries
+                 do
+                 (push (nth 0 e) row)
+                 (push (nth 1 e) row)
+                 (when (eq (length row) clength)
+                   (push `(nil ,(apply #'vector row)) rows)
+                   (setq row nil)))
+        rows))))
+
+(defun evil--self-insert-string (string)
+  "Insert STRING as if typed interactively."
+  (let ((chars (append string nil)))
+    (dolist (char chars)
+      (let ((last-command-event char))
+        (self-insert-command 1)))))
+
+(defun evil-copy-from-above (arg)
+  "Copy characters from preceding non-blank line.
+The copied text is inserted before point.
+ARG is the number of lines to move backward.
+See also \\<evil-insert-state-map>\\[evil-copy-from-below]."
+  (interactive
+   (cond
+    ;; if a prefix argument was given, repeat it for subsequent calls
+    ((and (null current-prefix-arg)
+          (eq last-command #'evil-copy-from-above))
+     (setq current-prefix-arg last-prefix-arg)
+     (list (prefix-numeric-value current-prefix-arg)))
+    (t
+     (list (prefix-numeric-value current-prefix-arg)))))
+  (evil--self-insert-string (evil-copy-chars-from-line arg -1)))
+
+(defun evil-copy-from-below (arg)
+  "Copy characters from following non-blank line.
+The copied text is inserted before point.
+ARG is the number of lines to move forward.
+See also \\<evil-insert-state-map>\\[evil-copy-from-above]."
+  (interactive
+   (cond
+    ((and (null current-prefix-arg)
+          (eq last-command #'evil-copy-from-below))
+     (setq current-prefix-arg last-prefix-arg)
+     (list (prefix-numeric-value current-prefix-arg)))
+    (t
+     (list (prefix-numeric-value current-prefix-arg)))))
+  (evil--self-insert-string (evil-copy-chars-from-line arg 1)))
+
+;; adapted from `copy-from-above-command' in misc.el
+(defun evil-copy-chars-from-line (n num &optional col)
+  "Return N characters from line NUM, starting at column COL.
+NUM is relative to the current line and can be negative.
+COL defaults to the current column."
+  (interactive "p")
+  (let ((col (or col (current-column))) prefix)
+    (save-excursion
+      (forward-line num)
+      (when (looking-at "[[:space:]]*$")
+        (if (< num 0)
+            (skip-chars-backward " \t\n")
+          (skip-chars-forward " \t\n")))
+      (evil-move-beginning-of-line)
+      (move-to-column col)
+      ;; if the column winds up in middle of a tab,
+      ;; return the appropriate number of spaces
+      (when (< col (current-column))
+        (if (eq (preceding-char) ?\t)
+            (let ((len (min n (- (current-column) col))))
+              (setq prefix (make-string len ?\s)
+                    n (- n len)))
+          ;; if in middle of a control char, return the whole char
+          (backward-char 1)))
+      (concat prefix
+              (buffer-substring (point)
+                                (min (line-end-position)
+                                     (+ n (point))))))))
+
+;; completion
+(evil-define-command evil-complete-next (&optional arg)
+  "Complete to the nearest following word.
+Search backward if a match isn't found.
+Calls `evil-complete-next-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-next-minibuffer-func)
+    (funcall evil-complete-next-func arg)))
+
+(evil-define-command evil-complete-previous (&optional arg)
+  "Complete to the nearest preceding word.
+Search forward if a match isn't found.
+Calls `evil-complete-previous-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-previous-minibuffer-func)
+    (funcall evil-complete-previous-func arg)))
+
+(evil-define-command evil-complete-next-line (&optional arg)
+  "Complete a whole line.
+Calls `evil-complete-next-line-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-next-minibuffer-func)
+    (funcall evil-complete-next-line-func arg)))
+
+(evil-define-command evil-complete-previous-line (&optional arg)
+  "Complete a whole line.
+Calls `evil-complete-previous-line-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-previous-minibuffer-func)
+    (funcall evil-complete-previous-line-func arg)))
+
+;;; Search
+
+(defun evil-repeat-search (flag)
+  "Called to record a search command.
+FLAG is either 'pre or 'post if the function is called before resp.
+after executing the command."
+  (cond
+   ((and (evil-operator-state-p) (eq flag 'pre))
+    (evil-repeat-record (this-command-keys))
+    (evil-clear-command-keys))
+   ((and (evil-operator-state-p) (eq flag 'post))
+    ;; The value of (this-command-keys) at this point should be the
+    ;; key-sequence that called the last command that finished the
+    ;; search, usually RET. Therefore this key-sequence will be
+    ;; recorded in the post-command of the operator. Alternatively we
+    ;; could do it here.
+    (evil-repeat-record (if evil-regexp-search
+                            (car-safe regexp-search-ring)
+                          (car-safe search-ring))))
+   (t (evil-repeat-motion flag))))
+
+(evil-define-motion evil-search-forward ()
+  (format "Search forward for user-entered text.
+Searches for regular expression if `evil-regexp-search' is t.%s"
+          (if (and (fboundp 'isearch-forward)
+                   (documentation 'isearch-forward))
+              (format "\n\nBelow is the documentation string \
+for `isearch-forward',\nwhich lists available keys:\n\n%s"
+                      (documentation 'isearch-forward)) ""))
+  :jump t
+  :type exclusive
+  :repeat evil-repeat-search
+  (evil-search-incrementally t evil-regexp-search))
+
+(evil-define-motion evil-search-backward ()
+  (format "Search backward for user-entered text.
+Searches for regular expression if `evil-regexp-search' is t.%s"
+          (if (and (fboundp 'isearch-forward)
+                   (documentation 'isearch-forward))
+              (format "\n\nBelow is the documentation string \
+for `isearch-forward',\nwhich lists available keys:\n\n%s"
+                      (documentation 'isearch-forward)) ""))
+  :jump t
+  :type exclusive
+  :repeat evil-repeat-search
+  (evil-search-incrementally nil evil-regexp-search))
+
+(evil-define-motion evil-search-next (count)
+  "Repeat the last search."
+  :jump t
+  :type exclusive
+  (let ((orig (point))
+        (search-string (if evil-regexp-search
+                           (car-safe regexp-search-ring)
+                         (car-safe search-ring))))
+    (goto-char
+     ;; Wrap in `save-excursion' so that multiple searches have no visual effect.
+     (save-excursion
+       (evil-search search-string isearch-forward evil-regexp-search)
+       (when (and (> (point) orig)
+                  (save-excursion
+                    (evil-adjust-cursor)
+                    (= (point) orig)))
+         ;; Point won't move after first attempt and `evil-adjust-cursor' takes
+         ;; effect, so start again.
+         (evil-search search-string isearch-forward evil-regexp-search))
+       (point)))
+    (when (and count (> count 1))
+      (dotimes (var (1- count))
+        (evil-search search-string isearch-forward evil-regexp-search)))))
+
+(evil-define-motion evil-search-previous (count)
+  "Repeat the last search in the opposite direction."
+  :jump t
+  :type exclusive
+  (dotimes (var (or count 1))
+    (evil-search (if evil-regexp-search
+                     (car-safe regexp-search-ring)
+                   (car-safe search-ring))
+                 (not isearch-forward) evil-regexp-search)))
+
+(evil-define-motion evil-search-word-backward (count &optional symbol)
+  "Search backward for symbol under point."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word nil nil symbol)))
+
+(evil-define-motion evil-search-word-forward (count &optional symbol)
+  "Search forward for symbol under point."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word t nil symbol)))
+
+(evil-define-motion evil-search-unbounded-word-backward (count &optional symbol)
+  "Search backward for symbol under point.
+The search is unbounded, i.e., the pattern is not wrapped in
+\\<...\\>."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word nil t symbol)))
+
+(evil-define-motion evil-search-unbounded-word-forward (count &optional symbol)
+  "Search forward for symbol under point.
+The search is unbounded, i.e., the pattern is not wrapped in
+\\<...\\>."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word t t symbol)))
+
+(evil-define-motion evil-goto-definition ()
+  "Go to definition or first occurrence of symbol under point."
+  :jump t
+  :type exclusive
+  (let* ((string (evil-find-symbol t))
+         (search (format "\\_<%s\\_>" (regexp-quote string)))
+         ientry ipos)
+    ;; load imenu if available
+    (unless (featurep 'imenu)
+      (condition-case nil
+          (require 'imenu)
+        (error nil)))
+    (if (null string)
+        (user-error "No symbol under cursor")
+      (setq isearch-forward t)
+      ;; if imenu is available, try it
+      (cond
+       ((fboundp 'imenu--make-index-alist)
+        (condition-case nil
+            (setq ientry (imenu--make-index-alist))
+          (error nil))
+        (setq ientry (assoc string ientry))
+        (setq ipos (cdr ientry))
+        (when (and (markerp ipos)
+                   (eq (marker-buffer ipos) (current-buffer)))
+          (setq ipos (marker-position ipos)))
+        (cond
+         ;; imenu found a position, so go there and
+         ;; highlight the occurrence
+         ((numberp ipos)
+          (evil-search search t t ipos))
+         ;; imenu failed, try semantic
+         ((and (fboundp 'semantic-ia-fast-jump)
+               (ignore-errors (semantic-ia-fast-jump ipos)))
+          ()) ;; noop, already jumped
+         ((fboundp 'xref-find-definitions) ;; semantic failed, try the generic func
+          (xref-find-definitions string))))
+       ;; otherwise just go to first occurrence in buffer
+       (t
+        (evil-search search t t (point-min)))))))
+
+;;; Folding
+(defun evil-fold-action (list action)
+  "Perform fold ACTION for each matching major or minor mode in LIST.
+
+ACTION will be performed for the first matching handler in LIST.  For more
+information on its features and format, see the documentation for
+`evil-fold-list'.
+
+If no matching ACTION is found in LIST, an error will signaled.
+
+Handler errors will be demoted, so a problem in one handler will (hopefully)
+not interfere with another."
+  (if (null list)
+      (user-error
+       "Folding is not supported for any of these major/minor modes")
+    (let* ((modes (caar list)))
+      (if (evil--mode-p modes)
+          (let* ((actions (cdar list))
+                 (fn      (plist-get actions action)))
+            (when fn
+              (with-demoted-errors (funcall fn))))
+        (evil-fold-action (cdr list) action)))))
+
+(defun evil--mode-p (modes)
+  "Determines whether any symbol in MODES represents the current
+buffer's major mode or any of its minors."
+  (unless (eq modes '())
+    (let ((mode (car modes)))
+      (or (eq major-mode mode)
+          (and (boundp mode) (symbol-value mode))
+          (evil--mode-p (cdr modes))))))
+
+(evil-define-command evil-toggle-fold ()
+  "Open or close a fold under point.
+See also `evil-open-fold' and `evil-close-fold'."
+  (evil-fold-action evil-fold-list :toggle))
+
+(evil-define-command evil-open-folds ()
+  "Open all folds.
+See also `evil-close-folds'."
+  (evil-fold-action evil-fold-list :open-all))
+
+(evil-define-command evil-close-folds ()
+  "Close all folds.
+See also `evil-open-folds'."
+  (evil-fold-action evil-fold-list :close-all))
+
+(evil-define-command evil-open-fold ()
+  "Open fold at point.
+See also `evil-close-fold'."
+  (evil-fold-action evil-fold-list :open))
+
+(evil-define-command evil-open-fold-rec ()
+  "Open fold at point recursively.
+See also `evil-open-fold' and `evil-close-fold'."
+  (evil-fold-action evil-fold-list :open-rec))
+
+(evil-define-command evil-close-fold ()
+  "Close fold at point.
+See also `evil-open-fold'."
+  (evil-fold-action evil-fold-list :close))
+
+;;; Ex
+
+(evil-define-operator evil-write (beg end type file-or-append &optional bang)
+  "Save the current buffer, from BEG to END, to FILE-OR-APPEND.
+If FILE-OR-APPEND is of the form \">> FILE\", append to FILE
+instead of overwriting.  The current buffer's filename is not
+changed unless it has no associated file and no region is
+specified.  If the file already exists and the BANG argument is
+non-nil, it is overwritten without confirmation."
+  :motion nil
+  :move-point nil
+  :type line
+  :repeat nil
+  (interactive "<R><fsh><!>")
+  (let* ((append-and-filename (evil-extract-append file-or-append))
+         (append (car append-and-filename))
+         (filename (cdr append-and-filename))
+         (bufname (buffer-file-name (buffer-base-buffer))))
+    (when (zerop (length filename))
+      (setq filename bufname))
+    (cond
+     ((zerop (length filename))
+      (user-error "Please specify a file name for the buffer"))
+     ;; execute command on region
+     ((eq (aref filename 0) ?!)
+      (shell-command-on-region beg end (substring filename 1)))
+     ;; with region or append, always save to file without resetting
+     ;; modified flag
+     ((or append (and beg end))
+      (write-region beg end filename append nil nil (not (or append bang))))
+     ;; no current file
+     ((null bufname)
+      (write-file filename (not bang)))
+     ;; save current buffer to its file
+     ((string= filename bufname)
+      (if (not bang) (save-buffer) (write-file filename)))
+     ;; save to another file
+     (t
+      (write-region nil nil filename
+                    nil (not bufname) nil
+                    (not bang))))))
+
+(evil-define-command evil-write-all (bang)
+  "Saves all buffers visiting a file.
+If BANG is non nil then read-only buffers are saved, too,
+otherwise they are skipped. "
+  :repeat nil
+  :move-point nil
+  (interactive "<!>")
+  (if bang
+      (save-some-buffers t)
+    ;; save only buffer that are not read-only and
+    ;; that are visiting a file
+    (save-some-buffers t
+                       #'(lambda ()
+                           (and (not buffer-read-only)
+                                (buffer-file-name))))))
+
+(evil-define-command evil-save (filename &optional bang)
+  "Save the current buffer to FILENAME.
+Changes the file name of the current buffer to FILENAME.  If no
+FILENAME is given, the current file name is used."
+  :repeat nil
+  :move-point nil
+  (interactive "<f><!>")
+  (when (zerop (length filename))
+    (setq filename (buffer-file-name (buffer-base-buffer))))
+  (write-file filename (not bang)))
+
+(evil-define-command evil-edit (file &optional bang)
+  "Open FILE.
+If no FILE is specified, reload the current buffer from disk."
+  :repeat nil
+  (interactive "<f><!>")
+  (if file
+      (find-file file)
+    (revert-buffer bang (or bang (not (buffer-modified-p))) t)))
+
+(evil-define-command evil-read (count file)
+  "Inserts the contents of FILE below the current line or line COUNT."
+  :repeat nil
+  :move-point nil
+  (interactive "P<fsh>")
+  (when (and file (not (zerop (length file))))
+    (when count (goto-char (point-min)))
+    (when (or (not (zerop (forward-line (or count 1))))
+              (not (bolp)))
+      (insert "\n"))
+    (if (/= (aref file 0) ?!)
+        (let ((result (insert-file-contents file)))
+          (save-excursion
+            (forward-char (cadr result))
+            (unless (bolp) (insert "\n"))))
+      (shell-command (substring file 1) t)
+      (save-excursion
+        (goto-char (mark))
+        (unless (bolp) (insert "\n"))))))
+
+(evil-define-command evil-show-files ()
+  "Shows the file-list.
+The same as `buffer-menu', but shows only buffers visiting
+files."
+  :repeat nil
+  (buffer-menu 1))
+
+(evil-define-command evil-goto-error (count)
+  "Go to error number COUNT.
+
+If no COUNT supplied, move to the current error.
+
+Acts like `first-error' other than when given no counts, goes
+to the current error instead of the first, like in Vim's :cc
+command."
+  :repeat nil
+  (interactive "<c>")
+  (if count
+      (first-error (if (eql 0 count) 1 count))
+    (next-error 0)))
+
+(evil-define-command evil-buffer (buffer)
+  "Switches to another buffer."
+  :repeat nil
+  (interactive "<b>")
+  (cond
+   ;; no buffer given, switch to "other" buffer
+   ((null buffer) (switch-to-buffer (other-buffer)))
+   ;; we are given the name of an existing buffer
+   ((get-buffer buffer) (switch-to-buffer buffer))
+   ;; try to complete the buffer
+   ((let ((all-buffers (internal-complete-buffer buffer nil t)))
+      (when (= (length all-buffers) 1)
+        (switch-to-buffer (car all-buffers)))))
+   (t
+    (when (y-or-n-p
+           (format "No buffer with name \"%s\" exists. Create new buffer? "
+                   buffer))
+      (switch-to-buffer buffer)))))
+
+(evil-define-command evil-next-buffer (&optional count)
+  "Goes to the `count'-th next buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (next-buffer)))
+
+(evil-define-command evil-prev-buffer (&optional count)
+  "Goes to the `count'-th prev buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (previous-buffer)))
+
+(evil-define-command evil-delete-buffer (buffer &optional bang)
+  "Deletes a buffer.
+All windows currently showing this buffer will be closed except
+for the last window in each frame."
+  (interactive "<b><!>")
+  (with-current-buffer (or buffer (current-buffer))
+    (when bang
+      (set-buffer-modified-p nil)
+      (dolist (process (process-list))
+        (when (eq (process-buffer process) (current-buffer))
+          (set-process-query-on-exit-flag process nil))))
+    ;; get all windows that show this buffer
+    (let ((wins (get-buffer-window-list (current-buffer) nil t)))
+      ;; if the buffer which was initiated by emacsclient,
+      ;; call `server-edit' from server.el to avoid
+      ;; "Buffer still has clients" message
+      (if (and (fboundp 'server-edit)
+               (boundp 'server-buffer-clients)
+               server-buffer-clients)
+          (server-edit)
+        (kill-buffer nil))
+      ;; close all windows that showed this buffer
+      (mapc #'(lambda (w)
+                (condition-case nil
+                    (delete-window w)
+                  (error nil)))
+            wins))))
+
+(evil-define-command evil-quit (&optional force)
+  "Closes the current window, current frame, Emacs.
+If the current frame belongs to some client the client connection
+is closed."
+  :repeat nil
+  (interactive "<!>")
+  (condition-case nil
+      (delete-window)
+    (error
+     (if (and (boundp 'server-buffer-clients)
+              (fboundp 'server-edit)
+              (fboundp 'server-buffer-done)
+              server-buffer-clients)
+         (if force
+             (server-buffer-done (current-buffer))
+           (server-edit))
+       (condition-case nil
+           (delete-frame)
+         (error
+          (if force
+              (kill-emacs)
+            (save-buffers-kill-emacs))))))))
+
+(evil-define-command evil-quit-all (&optional bang)
+  "Exits Emacs, asking for saving."
+  :repeat nil
+  (interactive "<!>")
+  (if (null bang)
+      (save-buffers-kill-terminal)
+    (let ((proc (frame-parameter (selected-frame) 'client)))
+      (if proc
+          (with-no-warnings
+            (server-delete-client proc))
+        (dolist (process (process-list))
+          (set-process-query-on-exit-flag process nil))
+        (kill-emacs)))))
+
+(evil-define-command evil-quit-all-with-error-code (&optional force)
+  "Exits Emacs without saving, returning an non-zero error code.
+The FORCE argument is only there for compatibility and is ignored.
+This function fails with an error if Emacs is run in server mode."
+  :repeat nil
+  (interactive "<!>")
+  (if (and (boundp 'server-buffer-clients)
+           (fboundp 'server-edit)
+           (fboundp 'server-buffer-done)
+           server-buffer-clients)
+      (user-error "Cannot exit client process with error code.")
+    (kill-emacs 1)))
+
+(evil-define-command evil-save-and-quit ()
+  "Save all buffers and exit Emacs."
+  (save-buffers-kill-terminal t))
+
+(evil-define-command evil-save-and-close (file &optional bang)
+  "Saves the current buffer and closes the window."
+  :repeat nil
+  (interactive "<f><!>")
+  (evil-write nil nil nil file bang)
+  (evil-quit))
+
+(evil-define-command evil-save-modified-and-close (file &optional bang)
+  "Saves the current buffer and closes the window."
+  :repeat nil
+  (interactive "<f><!>")
+  (when (buffer-modified-p)
+    (evil-write nil nil nil file bang))
+  (evil-quit))
+
+(evil-define-operator evil-shell-command
+  (beg end type command &optional previous)
+  "Execute a shell command.
+If BEG, END and TYPE is specified, COMMAND is executed on the region,
+which is replaced with the command's output. Otherwise, the
+output is displayed in its own buffer. If PREVIOUS is non-nil,
+the previous shell command is executed instead."
+  (interactive "<R><sh><!>")
+  (if (not (evil-ex-p))
+      (let ((evil-ex-initial-input
+             (if (and beg
+                      (not (evil-visual-state-p))
+                      (not current-prefix-arg))
+                 (let ((range (evil-range beg end type)))
+                   (evil-contract-range range)
+                   ;; TODO: this is not exactly the same as Vim, which
+                   ;; uses .,+count as range. However, this is easier
+                   ;; to achieve with the current implementation and
+                   ;; the very inconvenient range interface.
+                   ;;
+                   ;; TODO: the range interface really needs some
+                   ;; rework!
+                   (format
+                    "%d,%d!"
+                    (line-number-at-pos (evil-range-beginning range))
+                    (line-number-at-pos (evil-range-end range))))
+               "!")))
+        (call-interactively 'evil-ex))
+    (when command
+      (setq command (evil-ex-replace-special-filenames command)))
+    (if (zerop (length command))
+        (when previous (setq command evil-previous-shell-command))
+      (setq evil-previous-shell-command command))
+    (cond
+     ((zerop (length command))
+      (if previous (user-error "No previous shell command")
+        (user-error "No shell command")))
+     (evil-ex-range
+      (if (not evil-display-shell-error-in-message)
+          (shell-command-on-region beg end command nil t)
+        (let ((output-buffer (generate-new-buffer " *temp*"))
+              (error-buffer (generate-new-buffer " *temp*")))
+          (unwind-protect
+              (if (zerop (shell-command-on-region beg end
+                                                  command
+                                                  output-buffer nil
+                                                  error-buffer))
+                  (progn
+                    (delete-region beg end)
+                    (insert-buffer-substring output-buffer)
+                    (goto-char beg)
+                    (evil-first-non-blank))
+                (display-message-or-buffer error-buffer))
+            (kill-buffer output-buffer)
+            (kill-buffer error-buffer)))))
+     (t
+      (shell-command command)))))
+
+(evil-define-command evil-make (arg)
+  "Call a build command in the current directory.
+If ARG is nil this function calls `recompile', otherwise it calls
+`compile' passing ARG as build command."
+  (interactive "<sh>")
+  (if (and (fboundp 'recompile)
+           (not arg))
+      (recompile)
+    (compile arg)))
+
+;; TODO: escape special characters (currently only \n) ... perhaps
+;; there is some Emacs function doing this?
+(evil-define-command evil-show-registers ()
+  "Shows the contents of all registers."
+  :repeat nil
+  (evil-with-view-list
+    :name "evil-registers"
+    :mode-name "Evil Registers"
+    :format
+    [("Register" 10 nil)
+     ("Value" 1000 nil)]
+    :entries
+    (cl-loop for (key . val) in (evil-register-list)
+             collect `(nil [,(char-to-string key)
+                            ,(or (and val
+                                      (stringp val)
+                                      (replace-regexp-in-string "\n" "^J" val))
+                                 "")]))))
+
+(evil-define-command evil-show-marks (mrks)
+  "Shows all marks.
+If MRKS is non-nil it should be a string and only registers
+corresponding to the characters of this string are shown."
+  :repeat nil
+  (interactive "<a>")
+  ;; To get markers and positions, we can't rely on 'global-mark-ring'
+  ;; provided by Emacs (although it will be much simpler and faster),
+  ;; because 'global-mark-ring' does not store mark characters, but
+  ;; only buffer name and position. Instead, 'evil-markers-alist' is
+  ;; used; this is list maintained by Evil for each buffer.
+  (let ((all-markers
+         ;; get global and local marks
+         (append (cl-remove-if (lambda (m)
+                                 (or (evil-global-marker-p (car m))
+                                     (not (markerp (cdr m)))))
+                               evil-markers-alist)
+                 (cl-remove-if (lambda (m)
+                                 (or (not (evil-global-marker-p (car m)))
+                                     (not (markerp (cdr m)))))
+                               (default-value 'evil-markers-alist)))))
+    (when mrks
+      (setq mrks (string-to-list mrks))
+      (setq all-markers (cl-delete-if (lambda (m)
+                                        (not (member (car m) mrks)))
+                                      all-markers)))
+    ;; map marks to list of 4-tuples (char row col file)
+    (setq all-markers
+          (mapcar (lambda (m)
+                    (with-current-buffer (marker-buffer (cdr m))
+                      (save-excursion
+                        (goto-char (cdr m))
+                        (list (car m)
+                              (line-number-at-pos (point))
+                              (current-column)
+                              (buffer-name)))))
+                  all-markers))
+    (evil-with-view-list
+      :name "evil-marks"
+      :mode-name "Evil Marks"
+      :format [("Mark" 8 nil)
+               ("Line" 8 nil)
+               ("Column" 8 nil)
+               ("Buffer" 1000 nil)]
+      :entries (cl-loop for m in (sort all-markers (lambda (a b) (< (car a) (car b))))
+                        collect `(nil [,(char-to-string (nth 0 m))
+                                       ,(number-to-string (nth 1 m))
+                                       ,(number-to-string (nth 2 m))
+                                       (,(nth 3 m))]))
+      :select-action #'evil--show-marks-select-action)))
+
+(defun evil--show-marks-select-action (entry)
+  (kill-buffer)
+  (switch-to-buffer (car (elt entry 3)))
+  (evil-goto-mark (string-to-char (elt entry 0))))
+
+(evil-define-command evil-delete-marks (marks &optional force)
+  "Delete all marks.
+MARKS is a string denoting all marks to be deleted. Mark names are
+either single characters or a range of characters in the form A-Z.
+
+If FORCE is non-nil all local marks except 0-9 are removed.
+"
+  (interactive "<a><!>")
+  (cond
+   ;; delete local marks except 0-9
+   (force
+    (setq evil-markers-alist
+          (cl-delete-if (lambda (m)
+                          (not (and (>= (car m) ?0) (<= (car m) ?9))))
+                        evil-markers-alist)))
+   (t
+    (let ((i 0)
+          (n (length marks))
+          delmarks)
+      (while (< i n)
+        (cond
+         ;; skip spaces
+         ((= (aref marks i) ?\ ) (cl-incf i))
+         ;; ranges of marks
+         ((and (< (+ i 2) n)
+               (= (aref marks (1+ i)) ?-)
+               (or (and (>= (aref marks i) ?a)
+                        (<= (aref marks i) ?z)
+                        (>= (aref marks (+ 2 i)) ?a)
+                        (<= (aref marks (+ 2 i)) ?z))
+                   (and (>= (aref marks i) ?A)
+                        (<= (aref marks i) ?Z)
+                        (>= (aref marks (+ 2 i)) ?A)
+                        (<= (aref marks (+ 2 i)) ?Z))))
+          (let ((m (aref marks i)))
+            (while (<= m (aref marks (+ 2 i)))
+              (push m delmarks)
+              (cl-incf m)))
+          (cl-incf i 2))
+         ;; single marks
+         (t
+          (push (aref marks i) delmarks)
+          (cl-incf i))))
+      ;; now remove all marks
+      (setq evil-markers-alist
+            (cl-delete-if (lambda (m) (member (car m) delmarks))
+                          evil-markers-alist))
+      (set-default 'evil-markers-alist
+                   (cl-delete-if (lambda (m) (member (car m) delmarks))
+                                 (default-value 'evil-markers-alist)))))))
+
+(eval-when-compile (require 'ffap))
+(evil-define-command evil-find-file-at-point-with-line ()
+  "Opens the file at point and goes to line-number."
+  (require 'ffap)
+  (let ((fname (with-no-warnings (ffap-file-at-point))))
+    (if fname
+        (let ((line
+               (save-excursion
+                 (goto-char (cadr ffap-string-at-point-region))
+                 (and (re-search-backward ":\\([0-9]+\\)\\="
+                                          (line-beginning-position) t)
+                      (string-to-number (match-string 1))))))
+          (with-no-warnings (ffap-other-window))
+          (when line
+            (goto-char (point-min))
+            (forward-line (1- line))))
+      (user-error "File does not exist."))))
+
+(evil-ex-define-argument-type state
+  "Defines an argument type which can take state names."
+  :collection
+  (lambda (arg predicate flag)
+    (let ((completions
+           (append '("nil")
+                   (mapcar #'(lambda (state)
+                               (format "%s" (car state)))
+                           evil-state-properties))))
+      (when arg
+        (cond
+         ((eq flag nil)
+          (try-completion arg completions predicate))
+         ((eq flag t)
+          (all-completions arg completions predicate))
+         ((eq flag 'lambda)
+          (test-completion arg completions predicate))
+         ((eq (car-safe flag) 'boundaries)
+          (cons 'boundaries
+                (completion-boundaries arg
+                                       completions
+                                       predicate
+                                       (cdr flag)))))))))
+
+(evil-define-interactive-code "<state>"
+  "A valid evil state."
+  :ex-arg state
+  (list (when (and (evil-ex-p) evil-ex-argument)
+          (intern evil-ex-argument))))
+
+;; TODO: should we merge this command with `evil-set-initial-state'?
+(evil-define-command evil-ex-set-initial-state (state)
+  "Set the initial state for the current major mode to STATE.
+This is the state the buffer comes up in. See `evil-set-initial-state'."
+  :repeat nil
+  (interactive "<state>")
+  (if (not (or (assq state evil-state-properties)
+               (null state)))
+      (user-error "State %s cannot be set as initial Evil state" state)
+    (let ((current-initial-state (evil-initial-state major-mode)))
+      (unless (eq current-initial-state state)
+        ;; only if we selected a new mode
+        (when (y-or-n-p (format "Major-mode `%s' has initial mode `%s'. \
+Change to `%s'? "
+                                major-mode
+                                (or current-initial-state "DEFAULT")
+                                (or state "DEFAULT")))
+          (evil-set-initial-state major-mode state)
+          (when (y-or-n-p "Save setting in customization file? ")
+            (dolist (s (list current-initial-state state))
+              (when s
+                (let ((var (intern (format "evil-%s-state-modes" s))))
+                  (customize-save-variable var (symbol-value var)))))))))))
+
+(evil-define-command evil-force-normal-state ()
+  "Switch to normal state without recording current command."
+  :repeat abort
+  :suppress-operator t
+  (evil-normal-state))
+
+(evil-define-motion evil-ex-search-next (count)
+  "Goes to the next occurrence."
+  :jump t
+  :type exclusive
+  (evil-ex-search count))
+
+(evil-define-motion evil-ex-search-previous (count)
+  "Goes the the previous occurrence."
+  :jump t
+  :type exclusive
+  (let ((evil-ex-search-direction
+         (if (eq evil-ex-search-direction 'backward) 'forward 'backward)))
+    (evil-ex-search count)))
+
+(defun evil-repeat-ex-search (flag)
+  "Called to record a search command.
+FLAG is either 'pre or 'post if the function is called before
+resp.  after executing the command."
+  (cond
+   ((and (evil-operator-state-p) (eq flag 'pre))
+    (evil-repeat-record (this-command-keys))
+    (evil-clear-command-keys))
+   ((and (evil-operator-state-p) (eq flag 'post))
+    ;; The value of (this-command-keys) at this point should be the
+    ;; key-sequence that called the last command that finished the
+    ;; search, usually RET. Therefore this key-sequence will be
+    ;; recorded in the post-command of the operator. Alternatively we
+    ;; could do it here.
+    (evil-repeat-record (evil-ex-pattern-regex evil-ex-search-pattern)))
+   (t (evil-repeat-motion flag))))
+
+(evil-define-motion evil-ex-search-forward (count)
+  "Starts a forward search."
+  :jump t
+  :type exclusive
+  :repeat evil-repeat-ex-search
+  (evil-ex-start-search 'forward count))
+
+(evil-define-motion evil-ex-search-backward (count)
+  "Starts a forward search."
+  :jump t
+  :repeat evil-repeat-ex-search
+  (evil-ex-start-search 'backward count))
+
+(evil-define-motion evil-ex-search-word-forward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search nil 'forward count symbol))
+
+(evil-define-motion evil-ex-search-word-backward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search nil 'backward count symbol))
+
+(evil-define-motion evil-ex-search-unbounded-word-forward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search t 'forward count symbol))
+
+(evil-define-motion evil-ex-search-unbounded-word-backward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search t 'backward count symbol))
+
+(evil-define-operator evil-ex-substitute
+  (beg end pattern replacement flags)
+  "The Ex substitute command.
+\[BEG,END]substitute/PATTERN/REPLACEMENT/FLAGS"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><s/>")
+  (evil-ex-nohighlight)
+  (unless pattern
+    (user-error "No pattern given"))
+  (setq replacement (or replacement ""))
+  (setq evil-ex-last-was-search nil)
+  (let* ((flags (append flags nil))
+         (count-only (memq ?n flags))
+         (confirm (and (memq ?c flags) (not count-only)))
+         (case-fold-search (evil-ex-pattern-ignore-case pattern))
+         (case-replace case-fold-search)
+         (evil-ex-substitute-regex (evil-ex-pattern-regex pattern))
+         (evil-ex-substitute-nreplaced 0)
+         (evil-ex-substitute-last-point (point))
+         (whole-line (evil-ex-pattern-whole-line pattern))
+         (evil-ex-substitute-overlay (make-overlay (point) (point)))
+         (evil-ex-substitute-hl (evil-ex-make-hl 'evil-ex-substitute))
+         (orig-point-marker (move-marker (make-marker) (point)))
+         (end-marker (move-marker (make-marker) end))
+         zero-length-match
+         match-contains-newline
+         transient-mark-mode)
+    (setq evil-ex-substitute-pattern pattern
+          evil-ex-substitute-replacement replacement
+          evil-ex-substitute-flags flags
+          isearch-string evil-ex-substitute-regex)
+    (isearch-update-ring evil-ex-substitute-regex t)
+    (unwind-protect
+        (progn
+          (evil-ex-hl-change 'evil-ex-substitute pattern)
+          (overlay-put evil-ex-substitute-overlay 'face 'isearch)
+          (overlay-put evil-ex-substitute-overlay 'priority 1001)
+          (goto-char beg)
+          (catch 'exit-search
+            (while (re-search-forward evil-ex-substitute-regex end-marker t)
+              (let ((match-str (match-string 0))
+                    (match-beg (move-marker (make-marker) (match-beginning 0)))
+                    (match-end (move-marker (make-marker) (match-end 0)))
+                    (match-data (match-data)))
+                (goto-char match-beg)
+                (setq match-contains-newline (string-match-p "\n" match-str))
+                (setq zero-length-match (= match-beg match-end))
+                (when (and (string= "^" evil-ex-substitute-regex)
+                           (= (point) end-marker))
+                  ;; The range (beg end) includes the final newline which means
+                  ;; end-marker is on one line down. With the regex "^" the
+                  ;; beginning of this last line will be matched which we don't
+                  ;; want, so we abort here.
+                  (throw 'exit-search t))
+                (if confirm
+                    (let ((prompt
+                           (format "Replace %s with %s (y/n/a/q/l/^E/^Y)? "
+                                   match-str
+                                   (evil-match-substitute-replacement
+                                    evil-ex-substitute-replacement
+                                    (not case-replace))))
+                          response)
+                      (move-overlay evil-ex-substitute-overlay match-beg match-end)
+                      (catch 'exit-read-char
+                        (while (setq response (read-char prompt))
+                          (when (member response '(?y ?a ?l))
+                            (unless count-only
+                              (set-match-data match-data)
+                              (evil-replace-match evil-ex-substitute-replacement
+                                                  (not case-replace)))
+                            (setq evil-ex-substitute-last-point (point))
+                            (setq evil-ex-substitute-nreplaced
+                                  (1+ evil-ex-substitute-nreplaced))
+                            (evil-ex-hl-set-region 'evil-ex-substitute
+                                                   (save-excursion
+                                                     (forward-line)
+                                                     (point))
+                                                   (evil-ex-hl-get-max
+                                                    'evil-ex-substitute)))
+                          (cl-case response
+                            ((?y ?n) (throw 'exit-read-char t))
+                            (?a (setq confirm nil)
+                                (throw 'exit-read-char t))
+                            ((?q ?l ?\C-\[) (throw 'exit-search t))
+                            (?\C-e (evil-scroll-line-down 1))
+                            (?\C-y (evil-scroll-line-up 1))))))
+                  (setq evil-ex-substitute-nreplaced
+                        (1+ evil-ex-substitute-nreplaced))
+                  (unless count-only
+                    (set-match-data match-data)
+                    (evil-replace-match evil-ex-substitute-replacement
+                                        (not case-replace)))
+                  (setq evil-ex-substitute-last-point (point)))
+                (goto-char match-end)
+                (cond ((and (not whole-line)
+                            (not match-contains-newline))
+                       (forward-line)
+                       ;; forward-line just moves to the end of the line on the
+                       ;; last line of the buffer.
+                       (when (or (eobp)
+                                 (> (point) end-marker))
+                         (throw 'exit-search t)))
+                      ;; For zero-length matches check to see if point won't
+                      ;; move next time. This is a problem when matching the
+                      ;; regexp "$" because we can enter an infinite loop,
+                      ;; repeatedly matching the same character
+                      ((and zero-length-match
+                            (let ((pnt (point)))
+                              (save-excursion
+                                (and
+                                 (re-search-forward
+                                  evil-ex-substitute-regex end-marker t)
+                                 (= pnt (point))))))
+                       (if (or (eobp)
+                               (= (point) end-marker))
+                           (throw 'exit-search t)
+                         (forward-char))))))))
+      (evil-ex-delete-hl 'evil-ex-substitute)
+      (delete-overlay evil-ex-substitute-overlay))
+
+    (if count-only
+        (goto-char orig-point-marker)
+      (goto-char evil-ex-substitute-last-point))
+
+    (move-marker orig-point-marker nil)
+    (move-marker end-marker nil)
+
+    (message "%s %d occurrence%s"
+             (if count-only "Found" "Replaced")
+             evil-ex-substitute-nreplaced
+             (if (/= evil-ex-substitute-nreplaced 1) "s" ""))
+    (evil-first-non-blank)))
+
+(evil-define-operator evil-ex-repeat-substitute
+  (beg end flags)
+  "Repeat last substitute command.
+This is the same as :s//~/"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-flags
+  (beg end flags)
+  "Repeat last substitute command with last flags.
+This is the same as :s//~/&"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/&" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-search
+  (beg end flags)
+  "Repeat last substitute command with last search pattern.
+This is the same as :s//~/r"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/r" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-search-and-flags
+  (beg end flags)
+  "Repeat last substitute command with last search pattern and last flags.
+This is the same as :s//~/&r"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/&r" flags))))
+
+(evil-define-operator evil-ex-repeat-global-substitute ()
+  "Repeat last substitute command on the whole buffer.
+This is the same as :%s//~/&"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive)
+  (apply #'evil-ex-substitute (point-min) (point-max)
+         (evil-ex-get-substitute-info (concat "//~/&"))))
+
+(evil-define-operator evil-ex-global
+  (beg end pattern command &optional invert)
+  "The Ex global command.
+\[BEG,END]global[!]/PATTERN/COMMAND"
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r><g/><!>")
+  (unless pattern
+    (user-error "No pattern given"))
+  (unless command
+    (user-error "No command given"))
+  ;; TODO: `evil-ex-make-substitute-pattern' should be executed so
+  ;; :substitute can re-use :global's pattern depending on its `r'
+  ;; flag. This isn't supported currently but should be simple to add
+  (evil-with-single-undo
+    (let ((case-fold-search
+           (eq (evil-ex-regex-case pattern 'smart) 'insensitive))
+          match markers)
+      (when (and pattern command)
+        (setq isearch-string pattern)
+        (isearch-update-ring pattern t)
+        (goto-char beg)
+        (evil-move-beginning-of-line)
+        (while (< (point) end)
+          (setq match (re-search-forward pattern (line-end-position) t))
+          (when (or (and match (not invert))
+                    (and invert (not match)))
+            (push (move-marker (make-marker)
+                               (or (and match (match-beginning 0))
+                                   (line-beginning-position)))
+                  markers))
+          (forward-line))
+        (setq markers (nreverse markers))
+        (unwind-protect
+            (dolist (marker markers)
+              (goto-char marker)
+              (evil-ex-eval command))
+          ;; ensure that all markers are deleted afterwards,
+          ;; even in the event of failure
+          (dolist (marker markers)
+            (set-marker marker nil)))))))
+
+(evil-define-operator evil-ex-global-inverted
+  (beg end pattern command &optional invert)
+  "The Ex vglobal command.
+\[BEG,END]vglobal/PATTERN/COMMAND"
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r><g/><!>")
+  (evil-ex-global beg end pattern command (not invert)))
+
+(evil-define-operator evil-ex-normal (beg end commands)
+  "The Ex normal command.
+Execute the argument as normal command on each line in the
+range. The given argument is passed straight to
+`execute-kbd-macro'.  The default is the current line."
+  :motion evil-line
+  (interactive "<r><a>")
+  (evil-with-single-undo
+    (let (markers evil-ex-current-buffer prefix-arg current-prefix-arg)
+      (goto-char beg)
+      (while
+          (and (< (point) end)
+               (progn
+                 (push (move-marker (make-marker) (line-beginning-position))
+                       markers)
+                 (and (= (forward-line) 0) (bolp)))))
+      (setq markers (nreverse markers))
+      (deactivate-mark)
+      (evil-force-normal-state)
+      ;; replace ^[ by escape
+      (setq commands
+            (vconcat
+             (mapcar #'(lambda (ch) (if (equal ch ?) 'escape ch))
+                     (append commands nil))))
+      (dolist (marker markers)
+        (goto-char marker)
+        (condition-case nil
+            (execute-kbd-macro commands)
+          (error nil))
+        (evil-force-normal-state)
+        (set-marker marker nil)))))
+
+(evil-define-command evil-goto-char (position)
+  "Go to POSITION in the buffer.
+Default position is the beginning of the buffer."
+  (interactive "p")
+  (let ((position (evil-normalize-position
+                   (or position (point-min)))))
+    (goto-char position)))
+
+(evil-define-operator evil-ex-line-number (beg end)
+  "Print the last line number."
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r>")
+  (message "%d" (count-lines (point-min) end)))
+
+(evil-define-command evil-show-file-info ()
+  "Shows basic file information."
+  (let* ((nlines   (count-lines (point-min) (point-max)))
+         (curr     (line-number-at-pos (point)))
+         (perc     (if (> nlines 0)
+                       (format "%d%%" (* (/ (float curr) (float nlines)) 100.0))
+                     "No lines in buffer"))
+         (file     (buffer-file-name (buffer-base-buffer)))
+         (writable (and file (file-writable-p file)))
+         (readonly (if (and file (not writable)) "[readonly] " "")))
+    (if file
+        (message "\"%s\" %d %slines --%s--" file nlines readonly perc)
+      (message "%d lines --%s--" nlines perc))))
+
+(evil-define-operator evil-ex-sort (beg end &optional options reverse)
+  "The Ex sort command.
+\[BEG,END]sort[!] [i][u]
+The following additional options are supported:
+
+  * i   ignore case
+  * u   remove duplicate lines
+
+The 'bang' argument means to sort in reverse order."
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r><a><!>")
+  (let ((beg (copy-marker beg))
+        (end (copy-marker end))
+        sort-fold-case uniq)
+    (dolist (opt (append options nil))
+      (cond
+       ((eq opt ?i) (setq sort-fold-case t))
+       ((eq opt ?u) (setq uniq t))
+       (t (user-error "Unsupported sort option: %c" opt))))
+    (sort-lines reverse beg end)
+    (when uniq
+      (let (line prev-line)
+        (goto-char beg)
+        (while (and (< (point) end) (not (eobp)))
+          (setq line (buffer-substring-no-properties
+                      (line-beginning-position)
+                      (line-end-position)))
+          (if (and (stringp prev-line)
+                   (eq t (compare-strings line nil nil
+                                          prev-line nil nil
+                                          sort-fold-case)))
+              (delete-region (progn (forward-line 0) (point))
+                             (progn (forward-line 1) (point)))
+            (setq prev-line line)
+            (forward-line 1)))))
+    (goto-char beg)
+    (set-marker beg nil)
+    (set-marker end nil)))
+
+;;; Window navigation
+
+(defun evil-resize-window (new-size &optional horizontal)
+  "Set the current window's width or height to NEW-SIZE.
+If HORIZONTAL is non-nil the width of the window is changed,
+otherwise its height is changed."
+  (let ((count (- new-size (if horizontal (window-width) (window-height)))))
+    (if (>= emacs-major-version 24)
+        (enlarge-window count horizontal)
+      (let ((wincfg (current-window-configuration))
+            (nwins (length (window-list)))
+            (inhibit-redisplay t))
+        (catch 'done
+          (save-window-excursion
+            (while (not (zerop count))
+              (if (> count 0)
+                  (progn
+                    (enlarge-window 1 horizontal)
+                    (setq count (1- count)))
+                (progn
+                  (shrink-window 1 horizontal)
+                  (setq count (1+ count))))
+              (if (= nwins (length (window-list)))
+                  (setq wincfg (current-window-configuration))
+                (throw 'done t)))))
+        (set-window-configuration wincfg)))))
+
+(defun evil-get-buffer-tree (wintree)
+  "Extracts the buffer tree from a given window tree WINTREE."
+  (if (consp wintree)
+      (cons (car wintree) (mapcar #'evil-get-buffer-tree (cddr wintree)))
+    (window-buffer wintree)))
+
+(defun evil-restore-window-tree (win tree)
+  "Restore the given buffer-tree layout as subwindows of WIN.
+TREE is the tree layout to be restored.
+A tree layout is either a buffer or a list of the form (DIR TREE ...),
+where DIR is t for horizontal split and nil otherwise. All other
+elements of the list are tree layouts itself."
+  (if (bufferp tree)
+      (set-window-buffer win tree)
+    ;; if tree is buffer list with one buffer only, do not split
+    ;; anymore
+    (if (not (cddr tree))
+        (evil-restore-window-tree win (cadr tree))
+      ;; tree is a regular list, split recursively
+      (let ((newwin (split-window win nil (not (car tree)))))
+        (evil-restore-window-tree win (cadr tree))
+        (evil-restore-window-tree newwin (cons (car tree) (cddr tree)))))))
+
+(defun evil-alternate-buffer (&optional window)
+  "Return the last buffer WINDOW has displayed other than the
+current one (equivalent to Vim's alternate buffer).
+
+Returns the first item in `window-prev-buffers' that isn't
+`window-buffer' of WINDOW."
+  ;; If the last buffer visited has been killed, then `window-prev-buffers'
+  ;; returns a list with `current-buffer' at the head, we account for this
+  ;; possibility.
+  (let* ((prev-buffers (window-prev-buffers))
+         (head (car prev-buffers)))
+    (if (eq (car head) (window-buffer window))
+        (cadr prev-buffers)
+      head)))
+
+(evil-define-command evil-switch-to-windows-last-buffer ()
+  "Switch to current windows last open buffer."
+  :repeat nil
+  (let ((previous-place (evil-alternate-buffer)))
+    (when previous-place
+      (switch-to-buffer (car previous-place))
+      (goto-char (car (last previous-place))))))
+
+(evil-define-command evil-window-delete ()
+  "Deletes the current window.
+If `evil-auto-balance-windows' is non-nil then all children of
+the deleted window's parent window are rebalanced."
+  (let ((p (window-parent)))
+    (delete-window)
+    (when evil-auto-balance-windows
+      ;; balance-windows raises an error if the parent does not have
+      ;; any further children (then rebalancing is not necessary anyway)
+      (condition-case nil
+          (balance-windows p)
+        (error)))))
+
+(evil-define-command evil-window-split (&optional count file)
+  "Splits the current window horizontally, COUNT lines height,
+editing a certain FILE. The new window will be created below
+when `evil-split-window-below' is non-nil. If COUNT and
+`evil-auto-balance-windows' are both non-nil then all children
+of the parent of the splitted window are rebalanced."
+  :repeat nil
+  (interactive "P<f>")
+  (split-window (selected-window) count
+                (if evil-split-window-below 'above 'below))
+  (when (and (not count) evil-auto-balance-windows)
+    (balance-windows (window-parent)))
+  (when file
+    (evil-edit file)))
+
+(evil-define-command evil-window-vsplit (&optional count file)
+  "Splits the current window vertically, COUNT columns width,
+editing a certain FILE. The new window will be created to the
+right when `evil-vsplit-window-right' is non-nil. If COUNT and
+`evil-auto-balance-windows'are both non-nil then all children
+of the parent of the splitted window are rebalanced."
+  :repeat nil
+  (interactive "P<f>")
+  (split-window (selected-window) count
+                (if evil-vsplit-window-right 'left 'right))
+  (when (and (not count) evil-auto-balance-windows)
+    (balance-windows (window-parent)))
+  (when file
+    (evil-edit file)))
+
+(evil-define-command evil-split-buffer (buffer)
+  "Splits window and switches to another buffer."
+  :repeat nil
+  (interactive "<b>")
+  (evil-window-split)
+  (evil-buffer buffer))
+
+(evil-define-command evil-split-next-buffer (&optional count)
+  "Splits the window and goes to the COUNT-th next buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (evil-window-split)
+  (evil-next-buffer count))
+
+(evil-define-command evil-split-prev-buffer (&optional count)
+  "Splits window and goes to the COUNT-th prev buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (evil-window-split)
+  (evil-prev-buffer count))
+
+(evil-define-command evil-window-left (count)
+  "Move the cursor to new COUNT-th window left of the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i count)
+    (windmove-left)))
+
+(evil-define-command evil-window-right (count)
+  "Move the cursor to new COUNT-th window right of the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i count)
+    (windmove-right)))
+
+(evil-define-command evil-window-up (count)
+  "Move the cursor to new COUNT-th window above the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (windmove-up)))
+
+(evil-define-command evil-window-down (count)
+  "Move the cursor to new COUNT-th window below the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (windmove-down)))
+
+(evil-define-command evil-window-bottom-right ()
+  "Move the cursor to bottom-right window."
+  :repeat nil
+  (let ((last-sibling (frame-root-window)))
+    (while (and last-sibling (not (window-live-p last-sibling)))
+      (setq last-sibling (window-last-child last-sibling)))
+    (when last-sibling
+      (select-window last-sibling))))
+
+(evil-define-command evil-window-top-left ()
+  "Move the cursor to top-left window."
+  :repeat nil
+  (let ((first-child (window-child (frame-root-window))))
+    (while (and first-child (not (window-live-p first-child)))
+      (setq first-child (window-child first-child)))
+    (when first-child
+      (select-window
+       first-child))))
+
+(evil-define-command evil-window-mru ()
+  "Move the cursor to the previous (last accessed) buffer in another window.
+More precisely, it selects the most recently used buffer that is
+shown in some other window, preferably of the current frame, and
+is different from the current one."
+  :repeat nil
+  (catch 'done
+    (dolist (buf (buffer-list (selected-frame)))
+      (let ((win (get-buffer-window buf)))
+        (when (and (not (eq buf (current-buffer)))
+                   win
+                   (not (eq win (selected-window))))
+          (select-window win)
+          (throw 'done nil))))))
+
+(evil-define-command evil-window-next (count)
+  "Move the cursor to the next window in the cyclic order.
+With COUNT go to the count-th window in the order starting from
+top-left."
+  :repeat nil
+  (interactive "<c>")
+  (if (not count)
+      (select-window (next-window))
+    (evil-window-top-left)
+    (other-window (1- count))))
+
+(evil-define-command evil-window-prev (count)
+  "Move the cursor to the previous window in the cyclic order.
+With COUNT go to the count-th window in the order starting from
+top-left."
+  :repeat nil
+  (interactive "<c>")
+  (if (not count)
+      (select-window (previous-window))
+    (evil-window-top-left)
+    (other-window (1- count))))
+
+(evil-define-command evil-window-new (count file)
+  "Splits the current window horizontally
+and opens a new buffer or edits a certain FILE."
+  :repeat nil
+  (interactive "P<f>")
+  (let ((new-window (split-window (selected-window) count
+                                  (if evil-split-window-below 'below 'above))))
+    (when (and (not count) evil-auto-balance-windows)
+      (balance-windows (window-parent)))
+    (if file
+        (evil-edit file)
+      (let ((buffer (generate-new-buffer "*new*")))
+        (set-window-buffer new-window buffer)
+        (select-window new-window)
+        (with-current-buffer buffer
+          (funcall (default-value 'major-mode)))))))
+
+(evil-define-command evil-window-vnew (count file)
+  "Splits the current window vertically
+and opens a new buffer name or edits a certain FILE."
+  :repeat nil
+  (interactive "P<f>")
+  (let ((new-window (split-window (selected-window) count
+                                  (if evil-vsplit-window-right 'right 'left))))
+    (when (and (not count) evil-auto-balance-windows)
+      (balance-windows (window-parent)))
+    (if file
+        (evil-edit file)
+      (let ((buffer (generate-new-buffer "*new*")))
+        (set-window-buffer new-window buffer)
+        (select-window new-window)
+        (with-current-buffer buffer
+          (funcall (default-value 'major-mode)))))))
+
+(evil-define-command evil-buffer-new (count file)
+  "Creates a new buffer replacing the current window, optionally
+   editing a certain FILE"
+  :repeat nil
+  (interactive "P<f>")
+  (if file
+      (evil-edit file)
+    (let ((buffer (generate-new-buffer "*new*")))
+      (set-window-buffer nil buffer)
+      (with-current-buffer buffer
+        (funcall (default-value 'major-mode))))))
+
+(evil-define-command evil-window-increase-height (count)
+  "Increase current window height by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (+ (window-height) count)))
+
+(evil-define-command evil-window-decrease-height (count)
+  "Decrease current window height by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (- (window-height) count)))
+
+(evil-define-command evil-window-increase-width (count)
+  "Increase current window width by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (+ (window-width) count) t))
+
+(evil-define-command evil-window-decrease-width (count)
+  "Decrease current window width by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (- (window-width) count) t))
+
+(evil-define-command evil-window-set-height (count)
+  "Sets the height of the current window to COUNT."
+  :repeat nil
+  (interactive "<c>")
+  (evil-resize-window (or count (frame-height)) nil))
+
+(evil-define-command evil-window-set-width (count)
+  "Sets the width of the current window to COUNT."
+  :repeat nil
+  (interactive "<c>")
+  (evil-resize-window (or count (frame-width)) t))
+
+(evil-define-command evil-ex-resize (arg)
+  "The ex :resize command.
+
+If ARG is a signed positive integer, increase the current window
+height by ARG.
+
+If ARG is a signed negative integer, decrease the current window
+height by ARG.
+
+If ARG is a positive integer without explicit sign, set the current
+window height to ARG.
+
+If ARG is empty, maximize the current window height."
+  (interactive "<a>")
+  (if (or (not arg) (= 0 (length arg)))
+      (evil-window-set-height nil)
+    (let ((n (string-to-number arg)))
+      (if (> n 0)
+          (if (= ?+ (aref arg 0))
+              (evil-window-increase-height n)
+            (evil-window-set-height n))
+        (evil-window-decrease-height (- n))))))
+
+(evil-define-command evil-window-rotate-upwards ()
+  "Rotates the windows according to the currenty cyclic ordering."
+  :repeat nil
+  (let ((wlist (window-list))
+        (blist (mapcar #'(lambda (w) (window-buffer w))
+                       (window-list))))
+    (setq blist (append (cdr blist) (list (car blist))))
+    (while (and wlist blist)
+      (set-window-buffer (car wlist) (car blist))
+      (setq wlist (cdr wlist)
+            blist (cdr blist)))
+    (select-window (car (last (window-list))))))
+
+(evil-define-command evil-window-rotate-downwards ()
+  "Rotates the windows according to the currenty cyclic ordering."
+  :repeat nil
+  (let ((wlist (window-list))
+        (blist (mapcar #'(lambda (w) (window-buffer w))
+                       (window-list))))
+    (setq blist (append (last blist) blist))
+    (while (and wlist blist)
+      (set-window-buffer (car wlist) (car blist))
+      (setq wlist (cdr wlist)
+            blist (cdr blist)))
+    (select-window (cadr (window-list)))))
+
+(evil-define-command evil-window-move-very-top ()
+  "Closes the current window, splits the upper-left one horizontally
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((newwin (selected-window))
+                (subwin (split-window)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+(evil-define-command evil-window-move-far-left ()
+  "Closes the current window, splits the upper-left one vertically
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((newwin (selected-window))
+                (subwin (split-window-horizontally)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+(evil-define-command evil-window-move-far-right ()
+  "Closes the current window, splits the lower-right one vertically
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((subwin (selected-window))
+                (newwin (split-window-horizontally)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+(evil-define-command evil-window-move-very-bottom ()
+  "Closes the current window, splits the lower-right one horizontally
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((subwin (selected-window))
+                (newwin (split-window)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+;;; Mouse handling
+
+;; Large parts of this code are taken from mouse.el which is
+;; distributed with GNU Emacs
+(defun evil-mouse-drag-region (start-event)
+  "Set the region to the text that the mouse is dragged over.
+Highlight the drag area as you move the mouse.
+This must be bound to a button-down mouse event.
+
+If the click is in the echo area, display the `*Messages*' buffer.
+
+START-EVENT should be the event that started the drag."
+  (interactive "e")
+  ;; Give temporary modes such as isearch a chance to turn off.
+  (run-hooks 'mouse-leave-buffer-hook)
+  (evil-mouse-drag-track start-event t))
+(evil-set-command-property 'evil-mouse-drag-region :keep-visual t)
+
+(defun evil-mouse-drag-track (start-event &optional
+                                          do-mouse-drag-region-post-process)
+  "Track mouse drags by highlighting area between point and cursor.
+The region will be defined with mark and point.
+DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
+`mouse-drag-region'."
+  (mouse-minibuffer-check start-event)
+  (setq mouse-selection-click-count-buffer (current-buffer))
+  (deactivate-mark)
+  (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541).
+         (original-window (selected-window))
+         ;; We've recorded what we needed from the current buffer and
+         ;; window, now let's jump to the place of the event, where things
+         ;; are happening.
+         (_ (mouse-set-point start-event))
+         (echo-keystrokes 0)
+         (start-posn (event-start start-event))
+         (start-point (posn-point start-posn))
+         (start-window (posn-window start-posn))
+         (start-window-start (window-start start-window))
+         (start-hscroll (window-hscroll start-window))
+         (bounds (window-edges start-window))
+         (make-cursor-line-fully-visible nil)
+         (top (nth 1 bounds))
+         (bottom (if (window-minibuffer-p start-window)
+                     (nth 3 bounds)
+                   ;; Don't count the mode line.
+                   (1- (nth 3 bounds))))
+         (on-link (and mouse-1-click-follows-link
+                       (or mouse-1-click-in-non-selected-windows
+                           (eq start-window original-window))
+                       ;; Use start-point before the intangibility
+                       ;; treatment, in case we click on a link inside an
+                       ;; intangible text.
+                       (mouse-on-link-p start-posn)))
+         (click-count (1- (event-click-count start-event)))
+         (remap-double-click (and on-link
+                                  (eq mouse-1-click-follows-link 'double)
+                                  (= click-count 1)))
+         ;; Suppress automatic hscrolling, because that is a nuisance
+         ;; when setting point near the right fringe (but see below).
+         (auto-hscroll-mode-saved auto-hscroll-mode)
+         (auto-hscroll-mode nil)
+         event end end-point)
+
+    (setq mouse-selection-click-count click-count)
+    ;; In case the down click is in the middle of some intangible text,
+    ;; use the end of that text, and put it in START-POINT.
+    (if (< (point) start-point)
+        (goto-char start-point))
+    (setq start-point (point))
+    (if remap-double-click
+        (setq click-count 0))
+
+    (setq click-count (mod click-count 4))
+
+    ;; activate correct visual state
+    (let ((range (evil-mouse-start-end start-point start-point click-count)))
+      (set-mark (nth 0 range))
+      (goto-char (nth 1 range)))
+
+    (cond
+     ((= click-count 0)
+      (when (evil-visual-state-p) (evil-exit-visual-state)))
+     ((= click-count 1)
+      (evil-visual-char)
+      (evil-visual-post-command))
+     ((= click-count 2)
+      (evil-visual-line)
+      (evil-visual-post-command))
+     ((= click-count 3)
+      (evil-visual-block)
+      (evil-visual-post-command)))
+
+    ;; Track the mouse until we get a non-movement event.
+    (track-mouse
+      (while (progn
+               (setq event (read-event))
+               (or (mouse-movement-p event)
+                   (memq (car-safe event) '(switch-frame select-window))))
+        (unless (evil-visual-state-p)
+          (cond
+           ((= click-count 0) (evil-visual-char))
+           ((= click-count 1) (evil-visual-char))
+           ((= click-count 2) (evil-visual-line))
+           ((= click-count 3) (evil-visual-block))))
+
+        (evil-visual-pre-command)
+        (unless (memq (car-safe event) '(switch-frame select-window))
+          ;; Automatic hscrolling did not occur during the call to
+          ;; `read-event'; but if the user subsequently drags the
+          ;; mouse, go ahead and hscroll.
+          (let ((auto-hscroll-mode auto-hscroll-mode-saved))
+            (redisplay))
+          (setq end (event-end event)
+                end-point (posn-point end))
+          (if (and (eq (posn-window end) start-window)
+                   (integer-or-marker-p end-point))
+              (evil-mouse--drag-set-mark-and-point start-point
+                                                   end-point click-count)
+            (let ((mouse-row (cdr (cdr (mouse-position)))))
+              (cond
+               ((null mouse-row))
+               ((< mouse-row top)
+                (mouse-scroll-subr start-window (- mouse-row top)
+                                   nil start-point))
+               ((>= mouse-row bottom)
+                (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
+                                   nil start-point))))))
+        (evil-visual-post-command)))
+
+    ;; Handle the terminating event if possible.
+    (when (consp event)
+      ;; Ensure that point is on the end of the last event.
+      (when (and (setq end-point (posn-point (event-end event)))
+                 (eq (posn-window end) start-window)
+                 (integer-or-marker-p end-point)
+                 (/= start-point end-point))
+        (evil-mouse--drag-set-mark-and-point start-point
+                                             end-point click-count))
+
+      ;; Find its binding.
+      (let* ((fun (key-binding (vector (car event))))
+             (do-multi-click (and (> (event-click-count event) 0)
+                                  (functionp fun)
+                                  (not (memq fun '(mouse-set-point
+                                                   mouse-set-region))))))
+        (if (and (or (/= (mark) (point))
+                     (= click-count 1) ; word selection
+                     (and (memq (evil-visual-type) '(line block))))
+                 (not do-multi-click))
+
+            ;; If point has moved, finish the drag.
+            (let (last-command this-command)
+              (and mouse-drag-copy-region
+                   do-mouse-drag-region-post-process
+                   (let (deactivate-mark)
+                     (evil-visual-expand-region)
+                     (copy-region-as-kill (mark) (point))
+                     (evil-visual-contract-region))))
+
+          ;; If point hasn't moved, run the binding of the
+          ;; terminating up-event.
+          (if do-multi-click
+              (goto-char start-point)
+            (deactivate-mark))
+          (when (and (functionp fun)
+                     (= start-hscroll (window-hscroll start-window))
+                     ;; Don't run the up-event handler if the window
+                     ;; start changed in a redisplay after the
+                     ;; mouse-set-point for the down-mouse event at
+                     ;; the beginning of this function.  When the
+                     ;; window start has changed, the up-mouse event
+                     ;; contains a different position due to the new
+                     ;; window contents, and point is set again.
+                     (or end-point
+                         (= (window-start start-window)
+                            start-window-start)))
+            (when (and on-link
+                       (= start-point (point))
+                       (evil-mouse--remap-link-click-p start-event event))
+              ;; If we rebind to mouse-2, reselect previous selected
+              ;; window, so that the mouse-2 event runs in the same
+              ;; situation as if user had clicked it directly.  Fixes
+              ;; the bug reported by juri@jurta.org on 2005-12-27.
+              (if (or (vectorp on-link) (stringp on-link))
+                  (setq event (aref on-link 0))
+                (select-window original-window)
+                (setcar event 'mouse-2)
+                ;; If this mouse click has never been done by the
+                ;; user, it doesn't have the necessary property to be
+                ;; interpreted correctly.
+                (put 'mouse-2 'event-kind 'mouse-click)))
+            (push event unread-command-events)))))))
+
+;; This function is a plain copy of `mouse--drag-set-mark-and-point',
+;; which is only available in Emacs 24
+(defun evil-mouse--drag-set-mark-and-point (start click click-count)
+  (let* ((range (evil-mouse-start-end start click click-count))
+         (beg (nth 0 range))
+         (end (nth 1 range)))
+    (cond ((eq (mark) beg)
+           (goto-char end))
+          ((eq (mark) end)
+           (goto-char beg))
+          ((< click (mark))
+           (set-mark end)
+           (goto-char beg))
+          (t
+           (set-mark beg)
+           (goto-char end)))))
+
+;; This function is a plain copy of `mouse--remap-link-click-p',
+;; which is only available in Emacs 23
+(defun evil-mouse--remap-link-click-p (start-event end-event)
+  (or (and (eq mouse-1-click-follows-link 'double)
+           (= (event-click-count start-event) 2))
+      (and
+       (not (eq mouse-1-click-follows-link 'double))
+       (= (event-click-count start-event) 1)
+       (= (event-click-count end-event) 1)
+       (or (not (integerp mouse-1-click-follows-link))
+           (let ((t0 (posn-timestamp (event-start start-event)))
+                 (t1 (posn-timestamp (event-end   end-event))))
+             (and (integerp t0) (integerp t1)
+                  (if (> mouse-1-click-follows-link 0)
+                      (<= (- t1 t0) mouse-1-click-follows-link)
+                    (< (- t0 t1) mouse-1-click-follows-link))))))))
+
+(defun evil-mouse-start-end (start end mode)
+  "Return a list of region bounds based on START and END according to MODE.
+If MODE is not 1 then set point to (min START END), mark to (max
+START END).  If MODE is 1 then set point to start of word at (min
+START END), mark to end of word at (max START END)."
+  (evil-sort start end)
+  (setq mode (mod mode 4))
+  (if (/= mode 1) (list start end)
+    (list
+     (save-excursion
+       (goto-char (min (point-max) (1+ start)))
+       (if (zerop (forward-thing evil-mouse-word -1))
+           (let ((bpnt (point)))
+             (forward-thing evil-mouse-word +1)
+             (if (> (point) start) bpnt (point)))
+         (point-min)))
+     (save-excursion
+       (goto-char end)
+       (1-
+        (if (zerop (forward-thing evil-mouse-word +1))
+            (let ((epnt (point)))
+              (forward-thing evil-mouse-word -1)
+              (if (<= (point) end) epnt (point)))
+          (point-max)))))))
+
+;;; State switching
+
+(evil-define-command evil-exit-emacs-state (&optional buffer message)
+  "Exit Emacs state.
+Changes the state to the previous state, or to Normal state
+if the previous state was Emacs state."
+  :keep-visual t
+  :suppress-operator t
+  (interactive '(nil t))
+  (with-current-buffer (or buffer (current-buffer))
+    (when (evil-emacs-state-p)
+      (evil-change-to-previous-state buffer message)
+      (when (evil-emacs-state-p)
+        (evil-normal-state (and message 1))))))
+
+(defun evil-execute-in-normal-state ()
+  "Execute the next command in Normal state."
+  (interactive)
+  (evil-delay '(not (memq this-command
+                          '(evil-execute-in-normal-state
+                            evil-use-register
+                            digit-argument
+                            negative-argument
+                            universal-argument
+                            universal-argument-minus
+                            universal-argument-more
+                            universal-argument-other-key)))
+      `(progn
+         (with-current-buffer ,(current-buffer)
+           (evil-change-state ',evil-state)
+           (setq evil-move-cursor-back ',evil-move-cursor-back)))
+    'post-command-hook)
+  (setq evil-move-cursor-back nil)
+  (evil-normal-state)
+  (evil-echo "Switched to Normal state for the next command ..."))
+
+(defun evil-stop-execute-in-emacs-state ()
+  (when (and (not (eq this-command #'evil-execute-in-emacs-state))
+             (not (minibufferp)))
+    (remove-hook 'post-command-hook 'evil-stop-execute-in-emacs-state)
+    (when (buffer-live-p evil-execute-in-emacs-state-buffer)
+      (with-current-buffer evil-execute-in-emacs-state-buffer
+        (if (and (eq evil-previous-state 'visual)
+                 (not (use-region-p)))
+            (progn
+              (evil-change-to-previous-state)
+              (evil-exit-visual-state))
+          (evil-change-to-previous-state))))
+    (setq evil-execute-in-emacs-state-buffer nil)))
+
+(evil-define-command evil-execute-in-emacs-state ()
+  "Execute the next command in Emacs state."
+  (add-hook 'post-command-hook #'evil-stop-execute-in-emacs-state t)
+  (setq evil-execute-in-emacs-state-buffer (current-buffer))
+  (cond
+   ((evil-visual-state-p)
+    (let ((mrk (mark))
+          (pnt (point)))
+      (evil-emacs-state)
+      (set-mark mrk)
+      (goto-char pnt)))
+   (t
+    (evil-emacs-state)))
+  (evil-echo "Switched to Emacs state for the next command ..."))
+
+(defun evil-exit-visual-and-repeat (event)
+  "Exit insert state and repeat event.
+This special command should be used if some command called from
+visual state should actually be called in normal-state.  The main
+reason for doing this is that the repeat system should *not*
+record the visual state information for some command.  This
+command should be bound to exactly the same event in visual state
+as the original command is bound in normal state.  EVENT is the
+event that triggered the execution of this command."
+  (interactive "e")
+  (when (evil-visual-state-p)
+    (evil-exit-visual-state)
+    (push event unread-command-events)))
+(evil-declare-ignore-repeat 'evil-exit-visual-and-repeat)
+
+(provide 'evil-commands)
+
+;;; evil-commands.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-commands.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-common.el
@@ -0,0 +1,3875 @@
+;;; evil-common.el --- Common functions and utilities
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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-vars)
+(require 'evil-digraphs)
+(require 'rect)
+(require 'thingatpt)
+(eval-when-compile (require 'cl))
+
+;;; Code:
+
+(declare-function evil-visual-state-p "evil-states")
+(declare-function evil-visual-restore "evil-states")
+(declare-function evil-motion-state "evil-states")
+(declare-function evil-ex-p "evil-ex")
+(declare-function evil-set-jump "evil-jumps")
+
+(condition-case nil
+    (require 'windmove)
+  (error
+   (message "evil: Could not load `windmove', \
+window commands not available.")
+   nil))
+
+;;; Compatibility with different Emacs versions
+
+(defmacro evil-called-interactively-p ()
+  "Wrapper for `called-interactively-p'.
+In older versions of Emacs, `called-interactively-p' takes
+no arguments.  In Emacs 23.2 and newer, it takes one argument."
+  (called-interactively-p 'any))
+(make-obsolete 'evil-called-interactively-p
+               "please use (called-interactively-p 'any) instead."
+               "Git commit 222b791")
+
+;; macro helper
+(eval-and-compile
+  (defun evil-unquote (exp)
+    "Return EXP unquoted."
+    (while (eq (car-safe exp) 'quote)
+      (setq exp (cadr exp)))
+    exp))
+
+(defun evil-delay (condition form hook &optional append local name)
+  "Execute FORM when CONDITION becomes true, checking with HOOK.
+NAME specifies the name of the entry added to HOOK. If APPEND is
+non-nil, the entry is appended to the hook. If LOCAL is non-nil,
+the buffer-local value of HOOK is modified."
+  (if (and (not (booleanp condition)) (eval condition))
+      (eval form)
+    (let* ((name (or name (format "evil-delay-form-in-%s" hook)))
+           (fun (make-symbol name))
+           (condition (or condition t)))
+      (fset fun `(lambda (&rest args)
+                   (when ,condition
+                     (remove-hook ',hook #',fun ',local)
+                     ,form)))
+      (put fun 'permanent-local-hook t)
+      (add-hook hook fun append local))))
+(put 'evil-delay 'lisp-indent-function 2)
+
+;;; List functions
+
+(defun evil-add-to-alist (list-var key val &rest elements)
+  "Add the assocation of KEY and VAL to the value of LIST-VAR.
+If the list already contains an entry for KEY, update that entry;
+otherwise add at the end of the list."
+  (let ((tail (symbol-value list-var)))
+    (while (and tail (not (equal (car-safe (car-safe tail)) key)))
+      (setq tail (cdr tail)))
+    (if tail
+        (setcar tail (cons key val))
+      (set list-var (append (symbol-value list-var)
+                            (list (cons key val)))))
+    (if elements
+        (apply #'evil-add-to-alist list-var elements)
+      (symbol-value list-var))))
+
+;; custom version of `delete-if'
+(defun evil-filter-list (predicate list &optional pointer)
+  "Delete by side-effect all items satisfying PREDICATE in LIST.
+Stop when reaching POINTER.  If the first item satisfies PREDICATE,
+there is no way to remove it by side-effect; therefore, write
+\(setq foo (evil-filter-list 'predicate foo)) to be sure of
+changing the value of `foo'."
+  (let ((tail list) elt head)
+    (while (and tail (not (eq tail pointer)))
+      (setq elt (car tail))
+      (cond
+       ((funcall predicate elt)
+        (setq tail (cdr tail))
+        (if head
+            (setcdr head tail)
+          (setq list tail)))
+       (t
+        (setq head tail
+              tail (cdr tail)))))
+    list))
+
+(defun evil-member-if (predicate list &optional pointer)
+  "Find the first item satisfying PREDICATE in LIST.
+Stop when reaching POINTER, which should point at a link
+in the list."
+  (let (elt)
+    (catch 'done
+      (while (and (consp list) (not (eq list pointer)))
+        (setq elt (car list))
+        (if (funcall predicate elt)
+            (throw 'done elt)
+          (setq list (cdr list)))))))
+
+(defun evil-member-recursive-if (predicate tree)
+  "Find the first item satisfying PREDICATE in TREE."
+  (cond
+   ((funcall predicate tree)
+    tree)
+   ((listp tree)
+    (catch 'done
+      (dolist (elt tree)
+        (when (setq elt (evil-member-recursive-if predicate elt))
+          (throw 'done elt)))))))
+
+(defun evil-concat-lists (&rest sequences)
+  "Concatenate lists, removing duplicates.
+Elements are compared with `eq'."
+  (let (result)
+    (dolist (sequence sequences)
+      (dolist (elt sequence)
+        (add-to-list 'result elt nil #'eq)))
+    (nreverse result)))
+
+(defun evil-concat-alists (&rest sequences)
+  "Concatenate association lists, removing duplicates.
+An alist is a list of cons cells (KEY . VALUE) where each key
+may occur only once. Later values overwrite earlier values."
+  (let (result)
+    (dolist (sequence sequences)
+      (dolist (elt sequence)
+        (setq result (assq-delete-all (car-safe elt) result))
+        (push elt result)))
+    (nreverse result)))
+
+(defun evil-concat-plists (&rest sequences)
+  "Concatenate property lists, removing duplicates.
+A property list is a list (:KEYWORD1 VALUE1 :KEYWORD2 VALUE2...)
+where each keyword may occur only once. Later values overwrite
+earlier values."
+  (let (result)
+    (dolist (sequence sequences result)
+      (while sequence
+        (setq result
+              (plist-put result (pop sequence) (pop sequence)))))))
+
+(defun evil-concat-keymap-alists (&rest sequences)
+  "Concatenate keymap association lists, removing duplicates.
+A keymap alist is a list of cons cells (VAR . MAP) where each keymap
+may occur only once, but where the variables may be repeated
+\(e.g., (VAR . MAP1) (VAR . MAP2) is allowed). The order matters,
+with the highest priority keymaps being listed first."
+  (let (result)
+    (dolist (sequence sequences)
+      (dolist (elt sequence)
+        (unless (rassq (cdr-safe elt) result)
+          (push elt result))))
+    (nreverse result)))
+
+(defun evil-plist-delete (prop plist)
+  "Delete by side effect the property PROP from PLIST.
+If PROP is the first property in PLIST, there is no way
+to remove it by side-effect; therefore, write
+\(setq foo (evil-plist-delete :prop foo)) to be sure of
+changing the value of `foo'."
+  (let ((tail plist) elt head)
+    (while tail
+      (setq elt (car tail))
+      (cond
+       ((eq elt prop)
+        (setq tail (cdr (cdr tail)))
+        (if head
+            (setcdr (cdr head) tail)
+          (setq plist tail)))
+       (t
+        (setq head tail
+              tail (cdr (cdr tail))))))
+    plist))
+
+(defun evil-get-property (alist key &optional prop)
+  "Return property PROP for KEY in ALIST.
+ALIST is an association list with entries of the form
+\(KEY . PLIST), where PLIST is a property list.
+If PROP is nil, return all properties for KEY.
+If KEY is t, return an association list of keys
+and their PROP values."
+  (cond
+   ((null prop)
+    (cdr (assq key alist)))
+   ((eq key t)
+    (let (result val)
+      (dolist (entry alist result)
+        (setq key (car entry)
+              val (cdr entry))
+        (when (plist-member val prop)
+          (setq val (plist-get val prop))
+          (push (cons key val) result)))))
+   (t
+    (plist-get (cdr (assq key alist)) prop))))
+
+(defun evil-put-property (alist-var key prop val &rest properties)
+  "Set PROP to VAL for KEY in ALIST-VAR.
+ALIST-VAR points to an association list with entries of the form
+\(KEY . PLIST), where PLIST is a property list storing PROP and VAL."
+  (set alist-var
+       (let* ((alist (symbol-value alist-var))
+              (plist (cdr (assq key alist))))
+         (setq plist (plist-put plist prop val))
+         (when properties
+           (setq plist (evil-concat-plists plist properties)
+                 val (car (last properties))))
+         (setq alist (assq-delete-all key alist))
+         (push (cons key plist) alist)))
+  val)
+
+(defun evil-state-property (state prop &optional value)
+  "Return the value of property PROP for STATE.
+PROP is a keyword as used by `evil-define-state'.
+STATE is the state's symbolic name.
+If VALUE is non-nil and the value is a variable,
+return the value of that variable."
+  (let ((val (evil-get-property evil-state-properties state prop)))
+    (if (and value (symbolp val) (boundp val))
+        (symbol-value val)
+      val)))
+
+(defmacro evil-swap (this that &rest vars)
+  "Swap the values of variables THIS and THAT.
+If three or more arguments are given, the values are rotated.
+E.g., (evil-swap A B C) sets A to B, B to C, and C to A."
+  `(progn
+     (setq ,this (prog1 ,that
+                   (setq ,that ,this)))
+     ,@(when vars
+         `((evil-swap ,that ,@vars)))))
+
+(defmacro evil-sort (min max &rest vars)
+  "Place the smallest value in MIN and the largest in MAX.
+If three or more arguments are given, place the smallest
+value in the first argument and the largest in the last,
+sorting in between."
+  (let ((sorted (make-symbol "sortvar")))
+    `(let ((,sorted (sort (list ,min ,max ,@vars) '<)))
+       (setq ,min (pop ,sorted)
+             ,max (pop ,sorted)
+             ,@(apply #'append
+                      (mapcar #'(lambda (var)
+                                  (list var `(pop ,sorted)))
+                              vars))))))
+
+(defun evil-vector-to-string (vector)
+  "Turns vector into a string, changing <escape> to '\\e'"
+  (mapconcat (lambda (c)
+               (if (equal c 'escape)
+                   "\e"
+                 (make-string 1 c)))
+             vector
+             ""))
+
+;;; Command properties
+
+(defmacro evil-define-command (command &rest body)
+  "Define a command COMMAND.
+
+\(fn COMMAND (ARGS...) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional lambda-list]
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           [&optional ("interactive" [&rest form])]
+                           def-body)))
+  (let ((interactive '(interactive))
+        arg args doc doc-form key keys)
+    ;; collect arguments
+    (when (listp (car-safe body))
+      (setq args (pop body)))
+    ;; collect docstring
+    (when (> (length body) 1)
+      (if (eq (car-safe (car-safe body)) 'format)
+          (setq doc-form (pop body))
+        (when (stringp (car-safe body))
+          (setq doc (pop body)))))
+    ;; collect keywords
+    (setq keys (plist-put keys :repeat t))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (unless nil ; TODO: add keyword check
+        (setq keys (plist-put keys key arg))))
+    ;; collect `interactive' form
+    (when (and body (consp (car body))
+               (eq (car (car body)) 'interactive))
+      (let* ((iform (pop body))
+             (result (apply #'evil-interactive-form (cdr iform)))
+             (form (car result))
+             (attrs (cdr result)))
+        (setq interactive `(interactive ,form)
+              keys (evil-concat-plists keys attrs))))
+    `(progn
+       ;; the compiler does not recognize `defun' inside `let'
+       ,(when (and command body)
+          `(defun ,command ,args
+             ,@(when doc `(,doc))
+             ,interactive
+             ,@body))
+       ,(when (and command doc-form)
+          `(put ',command 'function-documentation ,doc-form))
+       ;; set command properties for symbol or lambda function
+       (let ((func ',(if (and (null command) body)
+                         `(lambda ,args
+                            ,interactive
+                            ,@body)
+                       command)))
+         (apply #'evil-set-command-properties func ',keys)
+         func))))
+
+;; If no Evil properties are defined for the command, several parts of
+;; Evil apply certain default rules; e.g., the repeat system decides
+;; whether the command is repeatable by monitoring buffer changes.
+(defun evil-has-command-property-p (command property)
+  "Whether COMMAND has Evil PROPERTY.
+See also `evil-has-command-properties-p'."
+  (plist-member (evil-get-command-properties command) property))
+
+(defun evil-has-command-properties-p (command)
+  "Whether Evil properties are defined for COMMAND.
+See also `evil-has-command-property-p'."
+  (and (evil-get-command-properties command) t))
+
+(defun evil-get-command-property (command property &optional default)
+  "Return the value of Evil PROPERTY of COMMAND.
+If the command does not have the property, return DEFAULT.
+See also `evil-get-command-properties'."
+  (if (evil-has-command-property-p command property)
+      (evil-get-property evil-command-properties command property)
+    default))
+
+(defun evil-get-command-properties (command)
+  "Return all Evil properties of COMMAND.
+See also `evil-get-command-property'."
+  (evil-get-property evil-command-properties command))
+
+(defun evil-set-command-property (command property value)
+  "Set PROPERTY to VALUE for COMMAND.
+To set multiple properties at once, see
+`evil-set-command-properties' and `evil-add-command-properties'."
+  (evil-put-property 'evil-command-properties command property value))
+(defalias 'evil-put-command-property 'evil-set-command-property)
+
+(defun evil-add-command-properties (command &rest properties)
+  "Add PROPERTIES to COMMAND.
+PROPERTIES should be a property list.
+To replace all properties at once, use `evil-set-command-properties'."
+  (apply #'evil-put-property
+         'evil-command-properties command properties))
+
+(defun evil-set-command-properties (command &rest properties)
+  "Replace all of COMMAND's properties with PROPERTIES.
+PROPERTIES should be a property list.
+This erases all previous properties; to only add properties,
+use `evil-set-command-property'."
+  (setq evil-command-properties
+        (assq-delete-all command evil-command-properties))
+  (when properties
+    (apply #'evil-add-command-properties command properties)))
+
+(defun evil-remove-command-properties (command &rest properties)
+  "Remove PROPERTIES from COMMAND.
+PROPERTIES should be a list of properties (:PROP1 :PROP2 ...).
+If PROPERTIES is the empty list, all properties are removed."
+  (let (plist)
+    (when properties
+      (setq plist (evil-get-command-properties command))
+      (dolist (property properties)
+        (setq plist (evil-plist-delete property plist))))
+    (apply #'evil-set-command-properties command plist)))
+
+(defun evil-yank-handler (&optional motion)
+  "Return the yank handler for MOTION.
+MOTION defaults to the current motion."
+  (setq motion (or motion evil-this-motion))
+  (evil-get-command-property motion :yank-handler))
+
+(defun evil-declare-motion (command)
+  "Declare COMMAND to be a movement function.
+This ensures that it behaves correctly in Visual state."
+  (evil-add-command-properties command :keep-visual t :repeat 'motion))
+
+(defun evil-declare-repeat (command)
+  "Declare COMMAND to be repeatable."
+  (evil-add-command-properties command :repeat t))
+
+(defun evil-declare-not-repeat (command)
+  "Declare COMMAND to be nonrepeatable."
+  (evil-add-command-properties command :repeat nil))
+
+(defun evil-declare-ignore-repeat (command)
+  "Declare COMMAND to be nonrepeatable."
+  (evil-add-command-properties command :repeat 'ignore))
+
+(defun evil-declare-change-repeat (command)
+  "Declare COMMAND to be repeatable by buffer changes."
+  (evil-add-command-properties command :repeat 'change))
+
+(defun evil-declare-insert-at-point-repeat (command)
+  "Declare COMMAND to be repeatable by buffer changes."
+  (evil-add-command-properties command :repeat 'insert-at-point))
+
+(defun evil-declare-abort-repeat (command)
+  "Declare COMMAND to be nonrepeatable."
+  (evil-add-command-properties command :repeat 'abort))
+
+(defun evil-delimited-arguments (string &optional num)
+  "Parse STRING as a sequence of delimited arguments.
+Returns a list of NUM strings, or as many arguments as
+the string contains. The first non-blank character is
+taken to be the delimiter. If some arguments are missing
+from STRING, the resulting list is padded with nil values.
+Two delimiters following directly after each other gives
+an empty string."
+  (save-match-data
+    (let ((string (or string ""))
+          (count (or num -1)) (idx 0)
+          argument delim match result)
+      (when (string-match "^[[:space:]]*\\([^[:space:]]\\)" string)
+        (setq delim (match-string 1 string)
+              argument (format "%s\\(\\(?:[\\].\\|[^%s]\\)*\\)"
+                               (regexp-quote delim)
+                               delim))
+        (while (and (/= count 0) (string-match argument string idx))
+          (setq match (match-string 1 string)
+                idx (match-end 1)
+                count (1- count))
+          (when (= count 0)
+            (unless (save-match-data
+                      (string-match
+                       (format "%s[[:space:]]*$" delim) string idx))
+              (setq match (substring string (match-beginning 1)))))
+          (unless (and (zerop (length match))
+                       (zerop (length (substring string idx))))
+            (push match result))))
+      (when (and num (< (length result) num))
+        (dotimes (i (- num (length result)))
+          (push nil result)))
+      (nreverse result))))
+
+(defun evil-concat-charsets (&rest sets)
+  "Concatenate character sets.
+A character set is the part between [ and ] in a regular expression.
+If any character set is complemented, the result is also complemented."
+  (let ((bracket "") (complement "") (hyphen "") result)
+    (save-match-data
+      (dolist (set sets)
+        (when (string-match "^\\^" set)
+          (setq set (substring set 1)
+                complement "^"))
+        (when (string-match "^]" set)
+          (setq set (substring set 1)
+                bracket "]"))
+        (when (string-match "^-" set)
+          (setq set (substring set 1)
+                hyphen "-"))
+        (setq result (concat result set)))
+      (format "%s%s%s%s" complement bracket hyphen result))))
+
+;;; Key sequences
+
+(defun evil-keypress-parser (&optional input)
+  "Read from keyboard or INPUT and build a command description.
+Returns (CMD COUNT), where COUNT is the numeric prefix argument.
+Both COUNT and CMD may be nil."
+  (let (count negative)
+    (when input (setq unread-command-events (append input unread-command-events)))
+    (catch 'done
+      (while t
+        (let ((seq (read-key-sequence "")))
+          (when seq
+            (let ((cmd (key-binding seq)))
+              (cond
+               ((null cmd) (throw 'done (list nil nil)))
+               ((arrayp cmd) ; keyboard macro, recursive call
+                (let ((cmd (evil-keypress-parser cmd)))
+                  (throw 'done
+                         (list (car cmd)
+                               (if (or count (cadr cmd))
+                                   (list (car cmd) (* (or count 1)
+                                                      (or (cadr cmd) 1))))))))
+               ((or (eq cmd #'digit-argument)
+                    (and (eq cmd 'evil-digit-argument-or-evil-beginning-of-line)
+                         count))
+                (let* ((event (aref seq (- (length seq) 1)))
+                       (char (or (when (characterp event) event)
+                                 (when (symbolp event)
+                                   (get event 'ascii-character))))
+                       (digit (if (or (characterp char) (integerp char))
+                                  (- (logand char ?\177) ?0))))
+                  (setq count (+ (* 10 (or count 0)) digit))))
+               ((eq cmd #'negative-argument)
+                (setq negative (not negative)))
+               (t
+                (throw 'done (list cmd
+                                   (and count
+                                        (* count
+                                           (if negative -1 1))))))))))))))
+
+(defun evil-read-key (&optional prompt)
+  "Read a key from the keyboard.
+Translates it according to the input method."
+  (let ((old-global-map (current-global-map))
+        (new-global-map (make-sparse-keymap))
+        (overriding-terminal-local-map nil)
+        (overriding-local-map evil-read-key-map)
+        seq char cmd)
+    (unwind-protect
+        (condition-case nil
+            (progn
+              (define-key new-global-map [menu-bar]
+                (lookup-key global-map [menu-bar]))
+              (define-key new-global-map [tool-bar]
+                (lookup-key global-map [tool-bar]))
+              (add-to-list 'new-global-map
+                           (make-char-table 'display-table
+                                            'self-insert-command) t)
+              (use-global-map new-global-map)
+              (setq seq (read-key-sequence prompt nil t)
+                    char (aref seq 0)
+                    cmd (key-binding seq))
+              (while (arrayp cmd)
+                (setq char (aref cmd 0)
+                      cmd (key-binding cmd)))
+              (cond
+               ((eq cmd 'self-insert-command)
+                char)
+               (cmd
+                (call-interactively cmd))
+               (t
+                (user-error "No replacement character typed"))))
+          (quit
+           (when (fboundp 'evil-repeat-abort)
+             (evil-repeat-abort))
+           (signal 'quit nil)))
+      (use-global-map old-global-map))))
+
+(defun evil-read-quoted-char ()
+  "Command that calls `read-quoted-char'.
+This command can be used wherever `read-quoted-char' is required
+as a command. Its main use is in the `evil-read-key-map'."
+  (interactive)
+  (read-quoted-char))
+
+(defun evil-read-digraph-char (&optional hide-chars)
+  "Read two keys from keyboard forming a digraph.
+This function creates an overlay at (point), hiding the next
+HIDE-CHARS characters. HIDE-CHARS defaults to 1."
+  (interactive)
+  (let (char1 char2 string overlay)
+    (unwind-protect
+        (progn
+          (setq overlay (make-overlay (point)
+                                      (min (point-max)
+                                           (+ (or hide-chars 1)
+                                              (point)))))
+          (overlay-put overlay 'invisible t)
+          ;; create overlay prompt
+          (setq string "?")
+          (put-text-property 0 1 'face 'minibuffer-prompt string)
+          ;; put cursor at (i.e., right before) the prompt
+          (put-text-property 0 1 'cursor t string)
+          (overlay-put overlay 'after-string string)
+          (setq char1 (read-key))
+          (setq string (string char1))
+          (put-text-property 0 1 'face 'minibuffer-prompt string)
+          (put-text-property 0 1 'cursor t string)
+          (overlay-put overlay 'after-string string)
+          (setq char2 (read-key)))
+      (delete-overlay overlay))
+    (or (evil-digraph (list char1 char2))
+        ;; use the last character if undefined
+        char2)))
+
+(defun evil-read-motion (&optional motion count type modifier)
+  "Read a MOTION, motion COUNT and motion TYPE from the keyboard.
+The type may be overridden with MODIFIER, which may be a type
+or a Visual selection as defined by `evil-define-visual-selection'.
+Return a list (MOTION COUNT [TYPE])."
+  (let ((modifiers '((evil-visual-char . char)
+                     (evil-visual-line . line)
+                     (evil-visual-block . block)))
+        command prefix)
+    (setq evil-this-type-modified nil)
+    (unless motion
+      (while (progn
+               (setq command (evil-keypress-parser)
+                     motion (pop command)
+                     prefix (pop command))
+               (when prefix
+                 (if count
+                     (setq count (string-to-number
+                                  (concat (number-to-string count)
+                                          (number-to-string prefix))))
+                   (setq count prefix)))
+               ;; if the command is a type modifier, read more
+               (when (rassq motion evil-visual-alist)
+                 (setq modifier
+                       (or modifier
+                           (car (rassq motion evil-visual-alist))))))))
+    (when modifier
+      (setq type (or type (evil-type motion 'exclusive)))
+      (cond
+       ((eq modifier 'char)
+        ;; TODO: this behavior could be less hard-coded
+        (if (eq type 'exclusive)
+            (setq type 'inclusive)
+          (setq type 'exclusive)))
+       (t
+        (setq type modifier)))
+      (setq evil-this-type-modified type))
+    (list motion count type)))
+
+(defun evil-mouse-events-p (keys)
+  "Returns non-nil iff KEYS contains a mouse event."
+  (catch 'done
+    (dotimes (i (length keys))
+      (when (or (and (fboundp 'mouse-event-p)
+                     (mouse-event-p (aref keys i)))
+                (mouse-movement-p (aref keys i)))
+        (throw 'done t)))
+    nil))
+
+(defun evil-extract-count (keys)
+  "Splits the key-sequence KEYS into prefix-argument and the rest.
+Returns the list (PREFIX CMD SEQ REST), where PREFIX is the
+prefix count, CMD the command to be executed, SEQ the subsequence
+calling CMD, and REST is all remaining events in the
+key-sequence. PREFIX and REST may be nil if they do not exist.
+If a command is bound to some keyboard macro, it is expanded
+recursively."
+  (catch 'done
+    (let* ((len (length keys))
+           (beg 0)
+           (end 1)
+           (found-prefix nil))
+      (while (and (<= end len))
+        (let ((cmd (key-binding (substring keys beg end))))
+          (cond
+           ((memq cmd '(undefined nil))
+            (user-error "No command bound to %s" (substring keys beg end)))
+           ((arrayp cmd) ; keyboard macro, replace command with macro
+            (setq keys (vconcat (substring keys 0 beg)
+                                cmd
+                                (substring keys end))
+                  end (1+ beg)
+                  len (length keys)))
+           ((functionp cmd)
+            (if (or (memq cmd '(digit-argument negative-argument))
+                    (and found-prefix
+                         (evil-get-command-property
+                          cmd :digit-argument-redirection)))
+                ;; skip those commands
+                (setq found-prefix t ; found at least one prefix argument
+                      beg end
+                      end (1+ end))
+              ;; a real command, finish
+              (throw 'done
+                     (list (unless (zerop beg)
+                             (string-to-number
+                              (concat (substring keys 0 beg))))
+                           cmd
+                           (substring keys beg end)
+                           (when (< end len)
+                             (substring keys end))))))
+           (t ; append a further event
+            (setq end (1+ end))))))
+      (user-error "Key sequence contains no complete binding"))))
+
+(defmacro evil-redirect-digit-argument (map keys target)
+  "Bind a wrapper function calling TARGET or `digit-argument'.
+MAP is a keymap for binding KEYS to the wrapper for TARGET.
+The wrapper only calls `digit-argument' if a prefix-argument
+has already been started; otherwise TARGET is called."
+  (let* ((target (eval target))
+         (wrapper (intern (format "evil-digit-argument-or-%s"
+                                  target))))
+    `(progn
+       (define-key ,map ,keys ',wrapper)
+       (evil-define-command ,wrapper ()
+         :digit-argument-redirection ,target
+         :keep-visual t
+         :repeat nil
+         (interactive)
+         (cond
+          (current-prefix-arg
+           (setq this-command #'digit-argument)
+           (call-interactively #'digit-argument))
+          (t
+           (let ((target (or (command-remapping #',target)
+                             #',target)))
+             (setq this-command target)
+             (call-interactively target))))))))
+
+(defun evil-extract-append (file-or-append)
+  "Return an (APPEND . FILENAME) pair based on FILE-OR-APPEND.
+FILE-OR-APPEND should either be a filename or a \">> FILE\"
+directive.  APPEND will be t if FILE-OR-APPEND is an append
+directive and nil otherwise.  FILENAME will be the extracted
+filename."
+  (if (and (stringp file-or-append)
+           (string-match "\\(>> *\\)" file-or-append))
+      (cons t (substring file-or-append(match-end 1)))
+    (cons nil file-or-append)))
+
+(defun evil-set-keymap-prompt (map prompt)
+  "Set the prompt-string of MAP to PROMPT."
+  (delq (keymap-prompt map) map)
+  (when prompt
+    (setcdr map (cons prompt (cdr map)))))
+
+(defun evil-lookup-key (map key)
+  "Returns non-nil value if KEY is bound in MAP."
+  (let ((definition (lookup-key map key)))
+    (if (numberp definition) ; in-band error
+        nil
+      definition)))
+
+;;; Display
+
+(defun evil-set-cursor (specs)
+  "Change the cursor's apperance according to SPECS.
+SPECS may be a cursor type as per `cursor-type', a color
+string as passed to `set-cursor-color', a zero-argument
+function for changing the cursor, or a list of the above."
+  (unless (and (listp specs)
+               (null (cdr-safe (last specs))))
+    (setq specs (list specs)))
+  (dolist (spec specs)
+    (cond
+     ((functionp spec)
+      (condition-case nil
+          (funcall spec)
+        (error nil)))
+     ((stringp spec)
+      (evil-set-cursor-color spec))
+     (t
+      (setq cursor-type spec)))))
+
+(defun evil-set-cursor-color (color)
+  "Set the cursor color to COLOR."
+  (unless (equal (frame-parameter nil 'cursor-color) color)
+    ;; `set-cursor-color' forces a redisplay, so only
+    ;; call it when the color actually changes
+    (set-cursor-color color)))
+
+(defun evil-refresh-cursor (&optional state buffer)
+  "Refresh the cursor for STATE in BUFFER.
+BUFFER defaults to the current buffer.  If STATE is nil the
+cursor type is either `evil-force-cursor' or the current state."
+  (when (and (boundp 'evil-local-mode) evil-local-mode)
+    (let* ((state (or state evil-force-cursor evil-state 'normal))
+           (default (or evil-default-cursor t))
+           (cursor (evil-state-property state :cursor t))
+           (color (or (and (stringp cursor) cursor)
+                      (and (listp cursor)
+                           (evil-member-if #'stringp cursor))
+                      (frame-parameter nil 'cursor-color))))
+      (with-current-buffer (or buffer (current-buffer))
+        ;; if both STATE and `evil-default-cursor'
+        ;; specify a color, don't set it twice
+        (when (and color (listp default))
+          (setq default (evil-filter-list #'stringp default)))
+        (evil-set-cursor default)
+        (evil-set-cursor cursor)))))
+
+(defmacro evil-save-cursor (&rest body)
+  "Save the current cursor; execute BODY; restore the cursor."
+  (declare (indent defun)
+           (debug t))
+  `(let ((cursor cursor-type)
+         (color (frame-parameter (selected-frame) 'cursor-color))
+         (inhibit-quit t))
+     (unwind-protect
+         (progn ,@body)
+       (evil-set-cursor cursor)
+       (evil-set-cursor color))))
+
+(defun evil-echo (string &rest args)
+  "Display an unlogged message in the echo area.
+That is, the message is not logged in the *Messages* buffer.
+\(To log the message, just use `message'.)"
+  (unless evil-no-display
+    (let (message-log-max)
+      (apply #'message string args))))
+
+(defun evil-echo-area-save ()
+  "Save the current echo area in `evil-echo-area-message'."
+  (setq evil-echo-area-message (current-message)))
+
+(defun evil-echo-area-restore ()
+  "Restore the echo area from `evil-echo-area-message'.
+Does not restore if `evil-write-echo-area' is non-nil."
+  (unless evil-write-echo-area
+    (if evil-echo-area-message
+        (message "%s" evil-echo-area-message)
+      (message nil)))
+  (setq evil-echo-area-message nil
+        evil-write-echo-area nil))
+
+;; toggleable version of `with-temp-message'
+(defmacro evil-save-echo-area (&rest body)
+  "Save the echo area; execute BODY; restore the echo area.
+Intermittent messages are not logged in the *Messages* buffer."
+  (declare (indent defun)
+           (debug t))
+  `(let ((inhibit-quit t)
+         evil-echo-area-message
+         evil-write-echo-area)
+     (unwind-protect
+         (progn
+           (evil-echo-area-save)
+           ,@body)
+       (evil-echo-area-restore))))
+
+(defmacro evil-without-display (&rest body)
+  "Execute BODY without Evil displays.
+Inhibits echo area messages, mode line updates and cursor changes."
+  (declare (indent defun)
+           (debug t))
+  `(let ((evil-no-display t))
+     ,@body))
+
+(defun evil-num-visible-lines ()
+  "Returns the number of currently visible lines."
+  (- (window-height) 1))
+
+(defun evil-count-lines (beg end)
+  "Return absolute line-number-difference betweeen `beg` and `end`.
+This should give the same results no matter where on the line `beg`
+and `end` are."
+  (if (= beg end)
+      0
+    (let* ((last (max beg end))
+           (end-at-bol (save-excursion (goto-char last)
+                                       (bolp))))
+      (if end-at-bol
+          (count-lines beg end)
+        (1- (count-lines beg end))))))
+
+;;; Movement
+
+(defun evil-normalize-position (pos)
+  "Return POS if it does not exceed the buffer boundaries.
+If POS is less than `point-min', return `point-min'.
+Is POS is more than `point-max', return `point-max'.
+If POS is a marker, return its position."
+  (cond
+   ((not (number-or-marker-p pos))
+    pos)
+   ((< pos (point-min))
+    (point-min))
+   ((> pos (point-max))
+    (point-max))
+   ((markerp pos)
+    (marker-position pos))
+   (t
+    pos)))
+
+(defmacro evil-save-goal-column (&rest body)
+  "Restores the goal column after execution of BODY.
+See also `evil-save-column'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((goal-column goal-column)
+         (temporary-goal-column temporary-goal-column))
+     ,@body))
+
+(defmacro evil-save-column (&rest body)
+  "Restores the column after execution of BODY.
+See also `evil-save-goal-column'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((col (current-column)))
+     (evil-save-goal-column
+       ,@body
+       (move-to-column col))))
+
+(defun evil-narrow (beg end)
+  "Restrict the buffer to BEG and END.
+BEG or END may be nil, specifying a one-sided restriction including
+`point-min' or `point-max'. See also `evil-with-restriction.'"
+  (setq beg (or (evil-normalize-position beg) (point-min)))
+  (setq end (or (evil-normalize-position end) (point-max)))
+  (narrow-to-region beg end))
+
+(defmacro evil-with-restriction (beg end &rest body)
+  "Execute BODY with the buffer narrowed to BEG and END.
+BEG or END may be nil as passed to `evil-narrow'; this creates
+a one-sided restriction."
+  (declare (indent 2)
+           (debug t))
+  `(save-restriction
+     (let ((evil-restriction-stack
+            (cons (cons (point-min) (point-max)) evil-restriction-stack)))
+       (evil-narrow ,beg ,end)
+       ,@body)))
+
+(defmacro evil-without-restriction (&rest body)
+  "Execute BODY with the top-most narrowing removed.
+This works only if the previous narrowing has been generated by
+`evil-with-restriction'."
+  (declare (indent defun)
+           (debug t))
+  `(save-restriction
+     (widen)
+     (narrow-to-region (car (car evil-restriction-stack))
+                       (cdr (car evil-restriction-stack)))
+     (let ((evil-restriction-stack (cdr evil-restriction-stack)))
+       ,@body)))
+
+(defmacro evil-narrow-to-field (&rest body)
+  "Narrow to the current field."
+  (declare (indent defun)
+           (debug t))
+  `(evil-with-restriction (field-beginning) (field-end)
+     ,@body))
+
+(defun evil-move-beginning-of-line (&optional arg)
+  "Move to the beginning of the line as displayed.
+Like `move-beginning-of-line', but retains the goal column."
+  (evil-save-goal-column
+    (move-beginning-of-line arg)
+    (beginning-of-line)))
+
+(defun evil-move-end-of-line (&optional arg)
+  "Move to the end of the line as displayed.
+Like `move-end-of-line', but retains the goal column."
+  (evil-save-goal-column
+    (move-end-of-line arg)
+    (end-of-line)))
+
+(defun evil-adjust-cursor (&optional force)
+  "Move point one character back if at the end of a non-empty line.
+This behavior is contingent on the variable `evil-move-cursor-back';
+use the FORCE parameter to override it."
+  (when (and (eolp)
+             (not evil-move-beyond-eol)
+             (not (bolp))
+             (= (point)
+                (save-excursion
+                  (evil-move-end-of-line)
+                  (point))))
+    (evil-move-cursor-back force)))
+
+(defun evil-move-cursor-back (&optional force)
+  "Move point one character back within the current line.
+Contingent on the variable `evil-move-cursor-back' or the FORCE
+argument. Honors field boundaries, i.e., constrains the movement
+to the current field as recognized by `line-beginning-position'."
+  (when (or evil-move-cursor-back force)
+    (unless (or (= (point) (line-beginning-position))
+                (and (boundp 'visual-line-mode)
+                     visual-line-mode
+                     (= (point) (save-excursion
+                                  (beginning-of-visual-line)
+                                  (point)))))
+      (backward-char))))
+
+(defun evil-line-position (line &optional column)
+  "Return the position of LINE.
+If COLUMN is specified, return its position on the line.
+A negative number means the end of the line."
+  (save-excursion
+    (when (fboundp 'evil-goto-line)
+      (evil-goto-line line))
+    (if (numberp column)
+        (if (< column 0)
+            (beginning-of-line 2)
+          (move-to-column column))
+      (beginning-of-line))
+    (point)))
+
+(defun evil-column (&optional pos)
+  "Return the horizontal position of POS.
+POS defaults to point."
+  (save-excursion
+    (when pos
+      (goto-char pos))
+    (current-column)))
+
+(defun evil-move-to-column (column &optional dir force)
+  "Move point to column COLUMN in the current line.
+Places point at left of the tab character (at the right if DIR
+is non-nil) and returns point."
+  (interactive "p")
+  (move-to-column column force)
+  (unless force
+    (when (or (not dir) (and (numberp dir) (< dir 1)))
+      (when (> (current-column) column)
+        (evil-move-cursor-back))))
+  (point))
+
+(defmacro evil-loop (spec &rest body)
+  "Loop with countdown variable.
+Evaluate BODY with VAR counting down from COUNT to 0.
+COUNT can be negative, in which case VAR counts up instead.
+The return value is the value of VAR when the loop
+terminates, which is 0 if the loop completes successfully.
+RESULT specifies a variable for storing this value.
+
+\(fn (VAR COUNT [RESULT]) BODY...)"
+  (declare (indent defun)
+           (debug dolist))
+  (let* ((i (make-symbol "loopvar"))
+         (var (pop spec))
+         (count (pop spec))
+         (result (pop spec)))
+    (setq var (or (unless (eq var result) var) i)
+          result (or result var))
+    `(let ((,var ,count))
+       (setq ,result ,var)
+       (while (/= ,var 0)
+         ,@body
+         (if (> ,var 0)
+             (setq ,var (1- ,var))
+           (setq ,var (1+ ,var)))
+         (setq ,result ,var))
+       ,var)))
+
+;;; Motions
+
+(defmacro evil-motion-loop (spec &rest body)
+  "Loop a certain number of times.
+Evaluate BODY repeatedly COUNT times with VAR bound to 1 or -1,
+depending on the sign of COUNT. RESULT, if specified, holds
+the number of unsuccessful iterations, which is 0 if the loop
+completes successfully. This is also the return value.
+
+Each iteration must move point; if point does not change,
+the loop immediately quits. See also `evil-loop'.
+
+\(fn (VAR COUNT [RESULT]) BODY...)"
+  (declare (indent defun)
+           (debug ((symbolp form &optional symbolp) body)))
+  (let* ((var (or (pop spec) (make-symbol "unitvar")))
+         (countval (or (pop spec) 0))
+         (result (pop spec))
+         (i (make-symbol "loopvar"))
+         (count (make-symbol "countvar"))
+         (done (make-symbol "donevar"))
+         (orig (make-symbol "origvar")))
+    `(let* ((,count ,countval)
+            (,var (if (< ,count 0) -1 1)))
+       (catch ',done
+         (evil-loop (,i ,count ,result)
+           (let ((,orig (point)))
+             ,@body
+             (when (= (point) ,orig)
+               (throw ',done ,i))))))))
+
+(defmacro evil-signal-without-movement (&rest body)
+  "Catches errors provided point moves within this scope."
+  (declare (indent defun)
+           (debug t))
+  `(let ((p (point)))
+     (condition-case err
+         (progn ,@body)
+       (error
+        (when (= p (point))
+          (signal (car err) (cdr err)))))))
+
+(defun evil-signal-at-bob-or-eob (&optional count)
+  "Signals error if `point' is at boundaries.
+If `point' is at bob and COUNT is negative this function signal
+'beginning-of-buffer. If `point' is at eob and COUNT is positive
+this function singal 'end-of-buffer. This function should be used
+in motions. COUNT defaults to 1."
+  (setq count (or count 1))
+  (cond
+   ((< count 0) (evil-signal-at-bob))
+   ((> count 0) (evil-signal-at-eob))))
+
+(defun evil-signal-at-bob ()
+  "Signals 'beginning-of-buffer if `point' is at bob.
+This function should be used in backward motions. If `point' is at
+bob so that no further backward motion is possible the error
+'beginning-of-buffer is raised."
+  (when (bobp) (signal 'beginning-of-buffer nil)))
+
+(defun evil-signal-at-eob ()
+  "Signals 'end-of-buffer if `point' is at eob.
+This function should be used in forward motions. If `point' is close
+to eob so that no further forward motion is possible the error
+'end-of-buffer is raised. This is the case if `point' is at
+`point-max' or if is one position before `point-max',
+`evil-move-cursor-back' is non-nil and `point' is not at the end
+of a line. The latter is necessary because `point' cannot be
+moved to `point-max' if `evil-move-cursor-back' is non-nil and
+the last line in the buffer is not empty."
+  (when (or (eobp)
+            (and (not (eolp))
+                 evil-move-cursor-back
+                 (save-excursion (forward-char) (eobp))))
+    (signal 'end-of-buffer nil)))
+
+(defmacro evil-with-hproject-point-on-window (&rest body)
+  "Project point after BODY to current window.
+If point is on a position left or right of the current window
+then it is moved to the left and right boundary of the window,
+respectively. If `auto-hscroll-mode' is non-nil then the left and
+right positions are increased or decreased, respectively, by
+`horizontal-margin' so that no automatic scrolling occurs."
+  (declare (indent defun)
+           (debug t))
+  (let ((diff (make-symbol "diff"))
+        (left (make-symbol "left"))
+        (right (make-symbol "right")))
+    `(let ((,diff (if auto-hscroll-mode (1+ hscroll-margin) 0))
+           auto-hscroll-mode)
+       ,@body
+       (let* ((,left (+ (window-hscroll) ,diff))
+              (,right (+ (window-hscroll) (window-width) (- ,diff) -1)))
+         (move-to-column (min (max (current-column) ,left) ,right))))))
+
+(defun evil-goto-min (&rest positions)
+  "Go to the smallest position in POSITIONS.
+Non-numerical elements are ignored.
+See also `evil-goto-max'."
+  (when (setq positions (evil-filter-list
+                         #'(lambda (elt)
+                             (not (number-or-marker-p elt)))
+                         positions))
+    (goto-char (apply #'min positions))))
+
+(defun evil-goto-max (&rest positions)
+  "Go to the largest position in POSITIONS.
+Non-numerical elements are ignored.
+See also `evil-goto-min'."
+  (when (setq positions (evil-filter-list
+                         #'(lambda (elt)
+                             (not (number-or-marker-p elt)))
+                         positions))
+    (goto-char (apply #'max positions))))
+
+(defun evil-forward-not-thing (thing &optional count)
+  "Move point to the end or beginning of the complement of THING."
+  (evil-motion-loop (dir (or count 1))
+    (let (bnd)
+      (cond
+       ((> dir 0)
+        (while (and (setq bnd (bounds-of-thing-at-point thing))
+                    (< (point) (cdr bnd)))
+          (goto-char (cdr bnd)))
+        ;; no thing at (point)
+        (if (zerop (forward-thing thing))
+            ;; now at the end of the next thing
+            (let ((bnd (bounds-of-thing-at-point thing)))
+              (if (or (< (car bnd) (point))    ; end of a thing
+                      (= (car bnd) (cdr bnd))) ; zero width thing
+                  (goto-char (car bnd))
+                ;; beginning of yet another thing, go back
+                (forward-thing thing -1)))
+          (goto-char (point-max))))
+       (t
+        (while (and (not (bobp))
+                    (or (backward-char) t)
+                    (setq bnd (bounds-of-thing-at-point thing))
+                    (< (point) (cdr bnd)))
+          (goto-char (car bnd)))
+        ;; either bob or no thing at point
+        (goto-char
+         (if (and (not (bobp))
+                  (zerop (forward-thing thing -1))
+                  (setq bnd (bounds-of-thing-at-point thing)))
+             (cdr bnd)
+           (point-min))))))))
+
+(defun evil-bounds-of-not-thing-at-point (thing &optional which)
+  "Returns the bounds of a complement of THING at point.
+If there is a THING at point nil is returned.  Otherwise if WHICH
+is nil or 0 a cons cell (BEG . END) is returned. If WHICH is
+negative the beginning is returned. If WHICH is positive the END
+is returned."
+  (let ((pnt (point)))
+    (let ((beg (save-excursion
+                 (and (zerop (forward-thing thing -1))
+                      (forward-thing thing))
+                 (if (> (point) pnt) (point-min) (point))))
+          (end (save-excursion
+                 (and (zerop (forward-thing thing))
+                      (forward-thing thing -1))
+                 (if (< (point) pnt) (point-max) (point)))))
+      (when (and (<= beg (point)) (<= (point) end) (< beg end))
+        (cond
+         ((or (not which) (zerop which)) (cons beg end))
+         ((< which 0) beg)
+         ((> which 0) end))))))
+
+(defun evil-forward-nearest (count &rest forwards)
+  "Moves point forward to the first of several motions.
+FORWARDS is a list of forward motion functions (i.e. each moves
+point forward to the next end of a text object (if passed a +1)
+or backward to the preceeding beginning of a text object (if
+passed a -1)). This function calls each of these functions once
+and moves point to the nearest of the resulting positions. If
+COUNT is positive point is moved forward COUNT times, if negative
+point is moved backward -COUNT times."
+  (evil-motion-loop (dir (or count 1))
+    (let ((pnt (point))
+          (nxt (if (> dir 0) (point-max) (point-min))))
+      (dolist (fwd forwards)
+        (goto-char pnt)
+        (condition-case nil
+            (evil-with-restriction
+                (and (< dir 0)
+                     (save-excursion
+                       (goto-char nxt)
+                       (line-beginning-position 0)))
+                (and (> dir 0)
+                     (save-excursion
+                       (goto-char nxt)
+                       (line-end-position 2)))
+              (if (and (zerop (funcall fwd dir))
+                       (/= (point) pnt)
+                       (or (and (> dir 0) (< (point) nxt))
+                           (and (< dir 0) (> (point) nxt))))
+                  (setq nxt (point))))
+          (error)))
+      (goto-char nxt))))
+
+(defun bounds-of-evil-string-at-point (&optional state)
+  "Return the bounds of a string at point.
+If STATE is given it used a parsing state at point."
+  (save-excursion
+    (let ((state (or state (syntax-ppss))))
+      (and (nth 3 state)
+           (cons (nth 8 state)
+                 (and (parse-partial-sexp (point)
+                                          (point-max)
+                                          nil
+                                          nil
+                                          state
+                                          'syntax-table)
+                      (point)))))))
+(put 'evil-string 'bounds-of-thing-at-point #'bounds-of-evil-string-at-point)
+
+(defun bounds-of-evil-comment-at-point ()
+  "Return the bounds of a string at point."
+  (save-excursion
+    (let ((state (syntax-ppss)))
+      (and (nth 4 state)
+           (cons (nth 8 state)
+                 (and (parse-partial-sexp (point)
+                                          (point-max)
+                                          nil
+                                          nil
+                                          state
+                                          'syntax-table)
+                      (point)))))))
+(put 'evil-comment 'bounds-of-thing-at-point #'bounds-of-evil-comment-at-point)
+
+;; The purpose of this function is the provide line motions which
+;; preserve the column. This is how `previous-line' and `next-line'
+;; work, but unfortunately the behaviour is hard-coded: if and only if
+;; the last command was `previous-line' or `next-line', the column is
+;; preserved. Furthermore, in contrast to Vim, when we cannot go
+;; further, those motions move point to the beginning resp. the end of
+;; the line (we never want point to leave its column). The code here
+;; comes from simple.el, and I hope it will work in future.
+(defun evil-line-move (count &optional noerror)
+  "A wrapper for line motions which conserves the column.
+Signals an error at buffer boundaries unless NOERROR is non-nil."
+  (cond
+   (noerror
+    (condition-case nil
+        (evil-line-move count)
+      (error nil)))
+   (t
+    (evil-signal-without-movement
+      (setq this-command (if (>= count 0)
+                             #'next-line
+                           #'previous-line))
+      (let ((opoint (point)))
+        (condition-case err
+            (with-no-warnings
+              (funcall this-command (abs count)))
+          ((beginning-of-buffer end-of-buffer)
+           (let ((col (or goal-column
+                          (if (consp temporary-goal-column)
+                              (car temporary-goal-column)
+                            temporary-goal-column))))
+             (if line-move-visual
+                 (vertical-motion (cons col 0))
+               (line-move-finish col opoint (< count 0)))
+             ;; Maybe we should just `ding'?
+             (signal (car err) (cdr err))))))))))
+
+(defun evil-forward-syntax (syntax &optional count)
+  "Move point to the end or beginning of a sequence of characters in
+SYNTAX.
+Stop on reaching a character not in SYNTAX."
+  (let ((notsyntax (if (= (aref syntax 0) ?^)
+                       (substring syntax 1)
+                     (concat "^" syntax))))
+    (evil-motion-loop (dir (or count 1))
+      (cond
+       ((< dir 0)
+        (skip-syntax-backward notsyntax)
+        (skip-syntax-backward syntax))
+       (t
+        (skip-syntax-forward notsyntax)
+        (skip-syntax-forward syntax))))))
+
+(defun evil-forward-chars (chars &optional count)
+  "Move point to the end or beginning of a sequence of CHARS.
+CHARS is a character set as inside [...] in a regular expression."
+  (let ((notchars (if (= (aref chars 0) ?^)
+                      (substring chars 1)
+                    (concat "^" chars))))
+    (evil-motion-loop (dir (or count 1))
+      (cond
+       ((< dir 0)
+        (skip-chars-backward notchars)
+        (skip-chars-backward chars))
+       (t
+        (skip-chars-forward notchars)
+        (skip-chars-forward chars))))))
+
+(defun evil-up-block (beg end &optional count)
+  "Move point to the end or beginning of text enclosed by BEG and END.
+BEG and END should be regular expressions matching the opening
+and closing delimiters, respectively. If COUNT is greater than
+zero point is moved forward otherwise it is moved
+backwards. Whenever an opening delimiter is found the COUNT is
+increased by one, if a closing delimiter is found the COUNT is
+decreased by one. The motion stops when COUNT reaches zero. The
+match-data reflects the last successful match (that caused COUNT
+to reach zero). The behaviour of this functions is similar to
+`up-list'."
+  (let* ((count (or count 1))
+         (forwardp (> count 0))
+         (dir (if forwardp +1 -1)))
+    (catch 'done
+      (while (not (zerop count))
+        (let* ((pnt (point))
+               (cl (save-excursion
+                     (and (re-search-forward (if forwardp end beg) nil t dir)
+                          (or (/= pnt (point))
+                              (progn
+                                ;; zero size match, repeat search from
+                                ;; the next position
+                                (forward-char dir)
+                                (re-search-forward (if forwardp end beg) nil t dir)))
+                          (point))))
+               (match (match-data t))
+               (op (save-excursion
+                     (and (not (equal beg end))
+                          (re-search-forward (if forwardp beg end) cl t dir)
+                          (or (/= pnt (point))
+                              (progn
+                                ;; zero size match, repeat search from
+                                ;; the next position
+                                (forward-char dir)
+                                (re-search-forward (if forwardp beg end) cl t dir)))
+                          (point)))))
+          (cond
+           ((not cl)
+            (goto-char (if forwardp (point-max) (point-min)))
+            (set-match-data nil)
+            (throw 'done count))
+           (t
+            (if op
+                (progn
+                  (setq count (if forwardp (1+ count) (1- count)))
+                  (goto-char op))
+              (setq count (if forwardp (1- count) (1+ count)))
+              (if (zerop count) (set-match-data match))
+              (goto-char cl))))))
+      0)))
+
+(defun evil-up-paren (open close &optional count)
+  "Move point to the end or beginning of balanced parentheses.
+OPEN and CLOSE should be characters identifying the opening and
+closing parenthesis, respectively. If COUNT is greater than zero
+point is moved forward otherwise it is moved backwards. Whenever
+an opening delimiter is found the COUNT is increased by one, if a
+closing delimiter is found the COUNT is decreased by one. The
+motion stops when COUNT reaches zero. The match-data reflects the
+last successful match (that caused COUNT to reach zero)."
+  ;; Always use the default `forward-sexp-function'. This is important
+  ;; for modes that use a custom one like `python-mode'.
+  ;; (addresses #364)
+  (let (forward-sexp-function)
+    (with-syntax-table (copy-syntax-table (syntax-table))
+      (modify-syntax-entry open (format "(%c" close))
+      (modify-syntax-entry close (format ")%c" open))
+      (let ((rest (evil-motion-loop (dir count)
+                    (let ((pnt (point)))
+                      (condition-case nil
+                          (cond
+                           ((> dir 0)
+                            (while (progn
+                                     (up-list dir)
+                                     (/= (char-before) close))))
+                           (t
+                            (while (progn
+                                     (up-list dir)
+                                     (/= (char-after) open)))))
+                        (error (goto-char pnt)))))))
+        (cond
+         ((= rest count) (set-match-data nil))
+         ((> count 0) (set-match-data (list (1- (point)) (point))))
+         (t (set-match-data (list (point) (1+ (point))))))
+        rest))))
+
+(defun evil-up-xml-tag (&optional count)
+  "Move point to the end or beginning of balanced xml tags.
+OPEN and CLOSE should be characters identifying the opening and
+closing parenthesis, respectively. If COUNT is greater than zero
+point is moved forward otherwise it is moved backwards. Whenever
+an opening delimiter is found the COUNT is increased by one, if a
+closing delimiter is found the COUNT is decreased by one. The
+motion stops when COUNT reaches zero. The match-data reflects the
+last successful match (that caused COUNT to reach zero)."
+  (let* ((dir (if (> (or count 1) 0) +1 -1))
+         (count (abs (or count 1)))
+         (match (> count 0))
+         (op (if (> dir 0) 1 2))
+         (cl (if (> dir 0) 2 1))
+         (orig (point))
+         pnt tags match)
+    (catch 'done
+      (while (> count 0)
+        ;; find the previous opening tag
+        (while
+            (and (setq match
+                       (re-search-forward
+                        "<\\([^/ >]+\\)\\(?:[^\"/>]\\|\"[^\"]*\"\\)*?>\\|</\\([^>]+?\\)>"
+                        nil t dir))
+                 (cond
+                  ((match-beginning op)
+                   (push (match-string op) tags))
+                  ((null tags) nil) ; free closing tag
+                  ((and (< dir 0)
+                        (string= (car tags) (match-string cl)))
+                   ;; in backward direction we only accept matching
+                   ;; tags. If the current tag is a free opener
+                   ;; without matching closing tag, the subsequents
+                   ;; test will make us ignore this tag
+                   (pop tags))
+                  ((and (> dir 0))
+                   ;; non matching openers are considered free openers
+                   (while (and tags
+                               (not (string= (car tags)
+                                             (match-string cl))))
+                     (pop tags))
+                   (pop tags)))))
+        (unless (setq match (and match (match-data t)))
+          (setq match nil)
+          (throw 'done count))
+        ;; found closing tag, look for corresponding opening tag
+        (cond
+         ((> dir 0)
+          (setq pnt (match-end 0))
+          (goto-char (match-beginning 0)))
+         (t
+          (setq pnt (match-beginning 0))
+          (goto-char (match-end 0))))
+        (let* ((tag (match-string cl))
+               (refwd (concat "<\\(/\\)?"
+                              (regexp-quote tag)
+                              "\\(?:>\\| \\(?:[^\"/>]\\|\"[^\"]*\"\\)*?>\\)"))
+               (cnt 1))
+          (while (and (> cnt 0) (re-search-backward refwd nil t dir))
+            (setq cnt (+ cnt (if (match-beginning 1) dir (- dir)))))
+          (if (zerop cnt) (setq count (1- count) tags nil))
+          (goto-char pnt)))
+      (if (> count 0)
+          (set-match-data nil)
+        (set-match-data match)
+        (goto-char (if (> dir 0) (match-end 0) (match-beginning 0)))))
+    ;; if not found, set to point-max/point-min
+    (unless (zerop count)
+      (set-match-data nil)
+      (goto-char (if (> dir 0) (point-max) (point-min)))
+      (if (/= (point) orig) (setq count (1- count))))
+    (* dir count)))
+
+(defun evil-forward-quote (quote &optional count)
+  "Move point to the end or beginning of a string.
+QUOTE is the character delimiting the string. If COUNT is greater
+than zero point is moved forward otherwise it is moved
+backwards."
+  (let (reset-parser)
+    (with-syntax-table (copy-syntax-table (syntax-table))
+      (unless (= (char-syntax quote) ?\")
+        (modify-syntax-entry quote "\"")
+        (setq reset-parser t))
+      ;; global parser state is out of state, use local one
+      (let* ((pnt (point))
+             (state (save-excursion
+                      (beginning-of-defun)
+                      (parse-partial-sexp (point) pnt nil nil (syntax-ppss))))
+             (bnd (bounds-of-evil-string-at-point state)))
+        (when (and bnd (< (point) (cdr bnd)))
+          ;; currently within a string
+          (if (> count 0)
+              (progn
+                (goto-char (cdr bnd))
+                (setq count (1- count)))
+            (goto-char (car bnd))
+            (setq count (1+ count))))
+        ;; forward motions work with local parser state
+        (cond
+         ((> count 0)
+          ;; no need to reset global parser state because we only use
+          ;; the local one
+          (setq reset-parser nil)
+          (catch 'done
+            (while (and (> count 0) (not (eobp)))
+              (setq state (parse-partial-sexp (point) (point-max)
+                                              nil
+                                              nil
+                                              state
+                                              'syntax-table))
+              (cond
+               ((nth 3 state)
+                (setq bnd (bounds-of-thing-at-point 'evil-string))
+                (goto-char (cdr bnd))
+                (setq count (1- count)))
+               ((eobp) (goto-char pnt) (throw 'done nil))))))
+         ((< count 0)
+          ;; need to update global cache because of backward motion
+          (setq reset-parser (and reset-parser (point)))
+          (save-excursion
+            (beginning-of-defun)
+            (syntax-ppss-flush-cache (point)))
+          (catch 'done
+            (while (and (< count 0) (not (bobp)))
+              (setq pnt (point))
+              (while (and (not (bobp))
+                          (or (eobp) (/= (char-after) quote)))
+                (backward-char))
+              (cond
+               ((setq bnd (bounds-of-thing-at-point 'evil-string))
+                (goto-char (car bnd))
+                (setq count (1+ count)))
+               ((bobp) (goto-char pnt) (throw 'done nil))
+               (t (backward-char))))))
+         (t (setq reset-parser nil)))))
+    (when reset-parser
+      ;; reset global cache
+      (save-excursion
+        (goto-char reset-parser)
+        (beginning-of-defun)
+        (syntax-ppss-flush-cache (point))))
+    count))
+
+;;; Thing-at-point motion functions for Evil text objects and motions
+(defun forward-evil-empty-line (&optional count)
+  "Move forward COUNT empty lines."
+  (setq count (or count 1))
+  (cond
+   ((> count 0)
+    (while (and (> count 0) (not (eobp)))
+      (when (and (bolp) (eolp))
+        (setq count (1- count)))
+      (forward-line 1)))
+   (t
+    (while (and (< count 0) (not (bobp))
+                (zerop (forward-line -1)))
+      (when (and (bolp) (eolp))
+        (setq count (1+ count))))))
+  count)
+
+(defun forward-evil-space (&optional count)
+  "Move forward COUNT whitespace sequences [[:space:]]+."
+  (evil-forward-chars "[:space:]" count))
+
+(defun forward-evil-word (&optional count)
+  "Move forward COUNT words.
+Moves point COUNT words forward or (- COUNT) words backward if
+COUNT is negative. Point is placed after the end of the word (if
+forward) or at the first character of the word (if backward). A
+word is a sequence of word characters matching
+\[[:word:]] (recognized by `forward-word'), a sequence of
+non-whitespace non-word characters '[^[:word:]\\n\\r\\t\\f ]', or
+an empty line matching ^$."
+  (evil-forward-nearest
+   count
+   #'(lambda (&optional cnt)
+       (let ((word-separating-categories evil-cjk-word-separating-categories)
+             (word-combining-categories evil-cjk-word-combining-categories)
+             (pnt (point)))
+         (forward-word cnt)
+         (if (= pnt (point)) cnt 0)))
+   #'(lambda (&optional cnt)
+       (evil-forward-chars "^[:word:]\n\r\t\f " cnt))
+   #'forward-evil-empty-line))
+
+(defun forward-evil-WORD (&optional count)
+  "Move forward COUNT \"WORDS\".
+Moves point COUNT WORDS forward or (- COUNT) WORDS backward if
+COUNT is negative. Point is placed after the end of the WORD (if
+forward) or at the first character of the WORD (if backward). A
+WORD is a sequence of non-whitespace characters
+'[^\\n\\r\\t\\f ]', or an empty line matching ^$."
+  (evil-forward-nearest count
+                        #'(lambda (&optional cnt)
+                            (evil-forward-chars "^\n\r\t\f " cnt))
+                        #'forward-evil-empty-line))
+
+(defun forward-evil-symbol (&optional count)
+  "Move forward COUNT symbols.
+Moves point COUNT symbols forward or (- COUNT) symbols backward
+if COUNT is negative. Point is placed after the end of the
+symbol (if forward) or at the first character of the symbol (if
+backward). A symbol is either determined by `forward-symbol', or
+is a sequence of characters not in the word, symbol or whitespace
+syntax classes."
+  (evil-forward-nearest
+   count
+   #'(lambda (&optional cnt)
+       (evil-forward-syntax "^w_->" cnt))
+   #'(lambda (&optional cnt)
+       (let ((pnt (point)))
+         (forward-symbol cnt)
+         (if (= pnt (point)) cnt 0)))
+   #'forward-evil-empty-line))
+
+(defun forward-evil-defun (&optional count)
+  "Move forward COUNT defuns.
+Moves point COUNT defuns forward or (- COUNT) defuns backward
+if COUNT is negative.  A defun is defined by
+`beginning-of-defun' and `end-of-defun' functions."
+  (evil-motion-loop (dir (or count 1))
+    (if (> dir 0) (end-of-defun) (beginning-of-defun))))
+
+(defun forward-evil-sentence (&optional count)
+  "Move forward COUNT sentences.
+Moves point COUNT sentences forward or (- COUNT) sentences
+backward if COUNT is negative.  This function is the same as
+`forward-sentence' but returns the number of sentences that could
+NOT be moved over."
+  (evil-motion-loop (dir (or count 1))
+    (condition-case nil
+        (forward-sentence dir)
+      (error))))
+
+(defun forward-evil-paragraph (&optional count)
+  "Move forward COUNT paragraphs.
+Moves point COUNT paragraphs forward or (- COUNT) paragraphs backward
+if COUNT is negative.  A paragraph is defined by
+`start-of-paragraph-text' and `forward-paragraph' functions."
+  (evil-motion-loop (dir (or count 1))
+    (cond
+     ((> dir 0) (forward-paragraph))
+     ((not (bobp)) (start-of-paragraph-text) (beginning-of-line)))))
+
+(defvar evil-forward-quote-char ?\"
+  "The character to be used by `forward-evil-quote'.")
+
+(defun forward-evil-quote (&optional count)
+  "Move forward COUNT strings.
+The quotation character is specified by the global variable
+`evil-forward-quote-char'. This character is passed to
+`evil-forward-quote'."
+  (evil-forward-quote evil-forward-quote-char count))
+
+(defun forward-evil-quote-simple (&optional count)
+  "Move forward COUNT strings.
+The quotation character is specified by the global variable
+`evil-forward-quote-char'. This functions uses Vim's rules
+parsing from the beginning of the current line for quotation
+characters. It should only be used when looking for strings
+within comments and buffer *must* be narrowed to the comment."
+  (let ((dir (if (> (or count 1) 0) 1 -1))
+        (ch evil-forward-quote-char)
+        (pnt (point))
+        (cnt 0))
+    (beginning-of-line)
+    ;; count number of quotes before pnt
+    (while (< (point) pnt)
+      (when (= (char-after) ch)
+        (setq cnt (1+ cnt)))
+      (forward-char))
+    (setq cnt (- (* 2 (abs count)) (mod cnt 2)))
+    (cond
+     ((> dir 0)
+      (while (and (not (eolp)) (not (zerop cnt)))
+        (when (= (char-after) ch) (setq cnt (1- cnt)))
+        (forward-char))
+      (when (not (zerop cnt)) (goto-char (point-max))))
+     (t
+      (while (and (not (bolp)) (not (zerop cnt)))
+        (when (= (char-before) ch) (setq cnt (1- cnt)))
+        (forward-char -1))
+      (when (not (zerop cnt)) (goto-char (point-min)))))
+    (/ cnt 2)))
+
+;;; Motion functions
+(defun evil-forward-beginning (thing &optional count)
+  "Move forward to beginning of THING.
+The motion is repeated COUNT times."
+  (setq count (or count 1))
+  (if (< count 0)
+      (forward-thing thing count)
+    (let ((bnd (bounds-of-thing-at-point thing))
+          rest)
+      (when (and bnd (< (point) (cdr bnd)))
+        (goto-char (cdr bnd)))
+      (condition-case nil
+          (when (zerop (setq rest (forward-thing thing count)))
+            (when (and (bounds-of-thing-at-point thing)
+                       (not (bobp))
+                       ;; handle final empty line
+                       (not (and (bolp) (eobp))))
+              (forward-char -1))
+            (beginning-of-thing thing))
+        (error))
+      rest)))
+
+(defun evil-backward-beginning (thing &optional count)
+  "Move backward to beginning of THING.
+The motion is repeated COUNT times. This is the same as calling
+`evil-backward-beginning' with -COUNT."
+  (evil-forward-beginning thing (- (or count 1))))
+
+(defun evil-forward-end (thing &optional count)
+  "Move forward to end of THING.
+The motion is repeated COUNT times."
+  (setq count (or count 1))
+  (cond
+   ((> count 0)
+    (unless (eobp) (forward-char))
+    (prog1 (forward-thing thing count)
+      (unless (bobp) (forward-char -1))))
+   (t
+    (let ((bnd (bounds-of-thing-at-point thing))
+          rest)
+      (when (and bnd (< (point) (cdr bnd) ))
+        (goto-char (car bnd)))
+      (condition-case nil
+          (when (zerop (setq rest (forward-thing thing count)))
+            (end-of-thing thing)
+            (forward-char -1))
+        (error))
+      rest))))
+
+(defun evil-backward-end (thing &optional count)
+  "Move backward to end of THING.
+The motion is repeated COUNT times. This is the same as calling
+`evil-backward-end' with -COUNT."
+  (evil-forward-end thing (- (or count 1))))
+
+(defun evil-forward-word (&optional count)
+  "Move by words.
+Moves point COUNT words forward or (- COUNT) words backward if
+COUNT is negative. This function is the same as `forward-word'
+but returns the number of words by which point could *not* be
+moved."
+  (setq count (or count 1))
+  (let* ((dir (if (>= count 0) +1 -1))
+         (count (abs count)))
+    (while (and (> count 0)
+                (forward-word dir))
+      (setq count (1- count)))
+    count))
+
+(defun evil-in-comment-p (&optional pos)
+  "Checks if POS is within a comment according to current syntax.
+If POS is nil, (point) is used. The return value is the beginning
+position of the comment."
+  (setq pos (or pos (point)))
+  (let ((chkpos
+         (cond
+          ((eobp) pos)
+          ((= (char-syntax (char-after)) ?<) (1+ pos))
+          ((and (not (zerop (logand (car (syntax-after (point)))
+                                    (lsh 1 16))))
+                (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+                                    (lsh 1 17)))))
+           (+ pos 2))
+          ((and (not (zerop (logand (car (syntax-after (point)))
+                                    (lsh 1 17))))
+                (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+                                    (lsh 1 16)))))
+           (1+ pos))
+          (t pos))))
+    (let ((syn (save-excursion (syntax-ppss chkpos))))
+      (and (nth 4 syn) (nth 8 syn)))))
+
+(defun evil-looking-at-start-comment (&optional move)
+  "Returns t if point is at the start of a comment.
+point must be on one of the opening characters of a block comment
+according to the current syntax table. Futhermore these
+characters must been parsed as opening characters, i.e. they
+won't be considered as comment starters inside a string or
+possibly another comment. Point is moved to the first character
+of the comment opener if MOVE is non-nil."
+  (cond
+   ;; one character opener
+   ((= (char-syntax (char-after)) ?<)
+    (equal (point) (evil-in-comment-p (1+ (point)))))
+   ;; two character opener on first char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 16))))
+         (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+                             (lsh 1 17)))))
+    (equal (point) (evil-in-comment-p (+ 2 (point)))))
+   ;; two character opener on second char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 17))))
+         (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+                             (lsh 1 16)))))
+    (and (equal (1- (point)) (evil-in-comment-p (1+ (point))))
+         (prog1 t (when move (backward-char)))))))
+
+(defun evil-looking-at-end-comment (&optional move)
+  "Returns t if point is at the end of a comment.
+point must be on one of the opening characters of a block comment
+according to the current syntax table. Futhermore these
+characters must been parsed as opening characters, i.e. they
+won't be considered as comment starters inside a string or
+possibly another comment. Point is moved right after the comment
+closer if MOVE is non-nil."
+  (cond
+   ;; one char closer
+   ((= (char-syntax (char-after)) ?>)
+    (and (evil-in-comment-p) ; in comment
+         (not (evil-in-comment-p (1+ (point))))
+         (prog1 t (when move (forward-char)))))
+   ;; two char closer on first char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 18))))
+         (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+                             (lsh 1 19)))))
+    (and (evil-in-comment-p)
+         (not (evil-in-comment-p (+ (point) 2)))
+         (prog1 t (when move (forward-char 2)))))
+   ;; two char closer on second char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 19))))
+         (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+                             (lsh 1 18)))))
+    (and (evil-in-comment-p)
+         (not (evil-in-comment-p (1+ (point))))
+         (prog1 t (when move (forward-char)))))))
+
+(defun evil-insert-newline-above ()
+  "Inserts a new line above point and places point in that line
+with regard to indentation."
+  (evil-narrow-to-field
+    (evil-move-beginning-of-line)
+    (insert "\n")
+    (forward-line -1)
+    (back-to-indentation)))
+
+(defun evil-insert-newline-below ()
+  "Inserts a new line below point and places point in that line
+with regard to indentation."
+  (evil-narrow-to-field
+    (evil-move-end-of-line)
+    (insert "\n")
+    (back-to-indentation)))
+
+;;; Markers
+
+(defun evil-global-marker-p (char)
+  "Whether CHAR denotes a global marker."
+  (or (and (>= char ?A) (<= char ?Z))
+      (assq char (default-value 'evil-markers-alist))))
+
+(defun evil-set-marker (char &optional pos advance)
+  "Set the marker denoted by CHAR to position POS.
+POS defaults to the current position of point.
+If ADVANCE is t, the marker advances when inserting text at it;
+otherwise, it stays behind."
+  (interactive (list (read-char)))
+  (catch 'done
+    (let ((marker (evil-get-marker char t)) alist)
+      (unless (markerp marker)
+        (cond
+         ((and marker (symbolp marker) (boundp marker))
+          (set marker (or (symbol-value marker) (make-marker)))
+          (setq marker (symbol-value marker)))
+         ((eq marker 'evil-jump-backward-swap)
+          (evil-set-jump)
+          (throw 'done nil))
+         ((functionp marker)
+          (user-error "Cannot set special marker `%c'" char))
+         ((evil-global-marker-p char)
+          (setq alist (default-value 'evil-markers-alist)
+                marker (make-marker))
+          (evil-add-to-alist 'alist char marker)
+          (setq-default evil-markers-alist alist))
+         (t
+          (setq marker (make-marker))
+          (evil-add-to-alist 'evil-markers-alist char marker))))
+      (add-hook 'kill-buffer-hook #'evil-swap-out-markers nil t)
+      (set-marker-insertion-type marker advance)
+      (set-marker marker (or pos (point))))))
+
+(defun evil-get-marker (char &optional raw)
+  "Return the marker denoted by CHAR.
+This is either a marker object as returned by `make-marker',
+a number, a cons cell (FILE . POS) with FILE being a string
+and POS a number, or nil. If RAW is non-nil, then the
+return value may also be a variable, a movement function,
+or a marker object pointing nowhere."
+  (let ((marker (if (evil-global-marker-p char)
+                    (cdr-safe (assq char (default-value
+                                           'evil-markers-alist)))
+                  (cdr-safe (assq char evil-markers-alist)))))
+    (save-excursion
+      (if raw
+          marker
+        (when (and (symbolp marker) (boundp marker))
+          (setq marker (symbol-value marker)))
+        (when (functionp marker)
+          (funcall marker)
+          (setq marker (point)))
+        (when (markerp marker)
+          (if (eq (marker-buffer marker) (current-buffer))
+              (setq marker (marker-position marker))
+            (setq marker (and (marker-buffer marker) marker))))
+        (when (or (numberp marker)
+                  (markerp marker)
+                  (and (consp marker)
+                       (stringp (car marker))
+                       (numberp (cdr marker))))
+          marker)))))
+
+(defun evil-swap-out-markers ()
+  "Turn markers into file references when the buffer is killed."
+  (and buffer-file-name
+       (dolist (entry evil-markers-alist)
+         (and (markerp (cdr entry))
+              (eq (marker-buffer (cdr entry)) (current-buffer))
+              (setcdr entry (cons buffer-file-name
+                                  (marker-position (cdr entry))))))))
+(put 'evil-swap-out-markers 'permanent-local-hook t)
+
+(defun evil-get-register (register &optional noerror)
+  "Return contents of REGISTER.
+Signal an error if empty, unless NOERROR is non-nil.
+
+The following special registers are supported.
+  \"  the unnamed register
+  *  the clipboard contents
+  +  the clipboard contents
+  <C-w> the word at point (ex mode only)
+  <C-a> the WORD at point (ex mode only)
+  <C-o> the symbol at point (ex mode only)
+  <C-f> the current file at point (ex mode only)
+  %  the current file name (read only)
+  #  the alternate file name (read only)
+  /  the last search pattern (read only)
+  :  the last command line (read only)
+  .  the last inserted text (read only)
+  -  the last small (less than a line) delete
+  _  the black hole register
+  =  the expression register (read only)"
+  (condition-case err
+      (when (characterp register)
+        (or (cond
+             ((eq register ?\")
+              (current-kill 0))
+             ((and (<= ?1 register) (<= register ?9))
+              (let ((reg (- register ?1)))
+                (and (< reg (length kill-ring))
+                     (current-kill reg t))))
+             ((memq register '(?* ?+))
+              ;; the following code is modified from
+              ;; `x-selection-value-internal'
+              (let ((what (if (eq register ?*) 'PRIMARY 'CLIPBOARD))
+                    (request-type (or (and (boundp 'x-select-request-type)
+                                           x-select-request-type)
+                                      '(UTF8_STRING COMPOUNT_TEXT STRING)))
+                    text)
+                (unless (consp request-type)
+                  (setq request-type (list request-type)))
+                (while (and request-type (not text))
+                  (condition-case nil
+                      (setq text (x-get-selection what (pop request-type)))
+                    (error nil)))
+                (when text
+                  (remove-text-properties 0 (length text) '(foreign-selection nil) text))
+                text))
+             ((eq register ?\C-W)
+              (unless (evil-ex-p)
+                (user-error "Register <C-w> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'evil-word)))
+             ((eq register ?\C-A)
+              (unless (evil-ex-p)
+                (user-error "Register <C-a> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'evil-WORD)))
+             ((eq register ?\C-O)
+              (unless (evil-ex-p)
+                (user-error "Register <C-o> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'evil-symbol)))
+             ((eq register ?\C-F)
+              (unless (evil-ex-p)
+                (user-error "Register <C-f> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'filename)))
+             ((eq register ?%)
+              (or (buffer-file-name (and (evil-ex-p)
+                                         (minibufferp)
+                                         evil-ex-current-buffer))
+                  (user-error "No file name")))
+             ((= register ?#)
+              (or (with-current-buffer (other-buffer) (buffer-file-name))
+                  (user-error "No file name")))
+             ((eq register ?/)
+              (or (car-safe
+                   (or (and (boundp 'evil-search-module)
+                            (eq evil-search-module 'evil-search)
+                            evil-ex-search-history)
+                       (and isearch-regexp regexp-search-ring)
+                       search-ring))
+                  (user-error "No previous regular expression")))
+             ((eq register ?:)
+              (or (car-safe evil-ex-history)
+                  (user-error "No previous command line")))
+             ((eq register ?.)
+              evil-last-insertion)
+             ((eq register ?-)
+              evil-last-small-deletion)
+             ((eq register ?=)
+              (let* ((enable-recursive-minibuffers t)
+                     (result (eval (car (read-from-string (read-string "="))))))
+                (cond
+                 ((or (stringp result)
+                      (numberp result)
+                      (symbolp result))
+                  (prin1-to-string result))
+                 ((sequencep result)
+                  (mapconcat #'prin1-to-string result "\n"))
+                 (t (user-error "Using %s as a string" (type-of result))))))
+             ((eq register ?_) ; the black hole register
+              "")
+             (t
+              (setq register (downcase register))
+              (get-register register)))
+            (user-error "Register `%c' is empty" register)))
+    (error (unless err (signal (car err) (cdr err))))))
+
+(defun evil-set-register (register text)
+  "Set the contents of register REGISTER to TEXT.
+If REGISTER is an upcase character then text is appended to that
+register instead of replacing its content."
+  (cond
+   ((not (characterp register))
+    (user-error "Invalid register"))
+   ;; don't allow modification of read-only registers
+   ((member register '(?: ?. ?%))
+    (user-error "Can't modify read-only register"))
+   ((eq register ?\")
+    (kill-new text))
+   ((and (<= ?1 register) (<= register ?9))
+    (if (null kill-ring)
+        (kill-new text)
+      (let ((kill-ring-yank-pointer kill-ring-yank-pointer)
+            interprogram-paste-function
+            interprogram-cut-function)
+        (current-kill (- register ?1))
+        (setcar kill-ring-yank-pointer text))))
+   ((eq register ?*)
+    (x-set-selection 'PRIMARY text))
+   ((eq register ?+)
+    (x-set-selection 'CLIPBOARD text))
+   ((eq register ?-)
+    (setq evil-last-small-deletion text))
+   ((eq register ?_) ; the black hole register
+    nil)
+   ((and (<= ?A register) (<= register ?Z))
+    (setq register (downcase register))
+    (let ((content (get-register register)))
+      (cond
+       ((not content)
+        (set-register register text))
+       ((or (text-property-not-all 0 (length content)
+                                   'yank-handler nil
+                                   content)
+            (text-property-not-all 0 (length text)
+                                   'yank-handler nil
+                                   text))
+        ;; some non-trivial yank-handler -> always switch to line handler
+        ;; ensure complete lines
+        (when (and (> (length content) 0)
+                   (/= (aref content (1- (length content))) ?\n))
+          (setq content (concat content "\n")))
+        (when (and (> (length text) 0)
+                   (/= (aref text (1- (length text))) ?\n))
+          (setq text (concat text "\n")))
+        (setq text (concat content text))
+        (remove-list-of-text-properties 0 (length text) '(yank-handler) text)
+        (setq text (propertize text 'yank-handler '(evil-yank-line-handler)))
+        (set-register register text))
+       (t
+        (set-register register (concat content text))))))
+   (t
+    (set-register register text))))
+
+(defun evil-register-list ()
+  "Returns an alist of all registers"
+  (sort (append (mapcar #'(lambda (reg)
+                            (cons reg (evil-get-register reg t)))
+                        '(?\" ?* ?+ ?% ?# ?/ ?: ?. ?-
+                              ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
+                register-alist nil)
+        #'(lambda (reg1 reg2) (< (car reg1) (car reg2)))))
+
+(defsubst evil-kbd-macro-suppress-motion-error ()
+  "Returns non-nil if a motion error should be suppressed.
+Whether the motion error should be suppressed depends on the
+variable `evil-kbd-macro-suppress-motion-error'."
+  (or (and defining-kbd-macro
+           (memq evil-kbd-macro-suppress-motion-error '(t record)))
+      (and executing-kbd-macro
+           (memq evil-kbd-macro-suppress-motion-error '(t replay)))))
+
+;;; Region
+
+;; `set-mark' does too much at once
+(defun evil-move-mark (pos)
+  "Set buffer's mark to POS.
+If POS is nil, delete the mark."
+  (when pos
+    (setq pos (evil-normalize-position pos)))
+  (set-marker (mark-marker) pos))
+
+(defun evil-save-transient-mark-mode ()
+  "Save Transient Mark mode and make it buffer-local.
+Any changes to Transient Mark mode are now local to the current
+buffer, until `evil-restore-transient-mark-mode' is called.
+
+Variables pertaining to Transient Mark mode are listed in
+`evil-transient-vars', and their values are stored in
+`evil-transient-vals'."
+  (dolist (var evil-transient-vars)
+    (when (and (boundp var)
+               (not (assq var evil-transient-vals)))
+      (push (list var (symbol-value var)
+                  (and (assq var (buffer-local-variables)) t))
+            evil-transient-vals)
+      (make-variable-buffer-local var)
+      (put var 'permanent-local t))))
+
+(defun evil-restore-transient-mark-mode ()
+  "Restore Transient Mark mode.
+This presupposes that `evil-save-transient-mark-mode' has been
+called earlier. If Transient Mark mode was disabled before but
+enabled in the meantime, this function disables it; if it was
+enabled before but disabled in the meantime, this function
+enables it.
+
+The earlier settings of Transient Mark mode are stored in
+`evil-transient-vals'."
+  (let (entry local var val)
+    (while (setq entry (pop evil-transient-vals))
+      (setq var (pop entry)
+            val (pop entry)
+            local (pop entry))
+      (unless local
+        (kill-local-variable var))
+      (unless (equal (symbol-value var) val)
+        (if (fboundp var)
+            (funcall var (if val 1 -1))
+          (setq var val))))))
+
+(defun evil-save-mark ()
+  "Save the current mark, including whether it is transient.
+See also `evil-restore-mark'."
+  (unless evil-visual-previous-mark
+    (setq evil-visual-previous-mark (mark t))
+    (evil-save-transient-mark-mode)))
+
+(defun evil-restore-mark ()
+  "Restore the mark, including whether it was transient.
+See also `evil-save-mark'."
+  (when evil-visual-previous-mark
+    (evil-restore-transient-mark-mode)
+    (evil-move-mark evil-visual-previous-mark)
+    (setq evil-visual-previous-mark nil)))
+
+;; In theory, an active region implies Transient Mark mode, and
+;; disabling Transient Mark mode implies deactivating the region.
+;; In practice, Emacs never clears `mark-active' except in Transient
+;; Mark mode, so we define our own toggle functions to make things
+;; more predictable.
+(defun evil-transient-mark (&optional arg)
+  "Toggle Transient Mark mode.
+Ensure that the region is properly deactivated.
+Enable with positive ARG, disable with negative ARG."
+  (unless (numberp arg)
+    (setq arg (if transient-mark-mode -1 1)))
+  (cond
+   ((< arg 1)
+    (evil-active-region -1)
+    ;; Transient Mark mode cannot be disabled
+    ;; while CUA mode is enabled
+    (when (fboundp 'cua-mode)
+      (cua-mode -1))
+    (when transient-mark-mode
+      (transient-mark-mode -1)))
+   (t
+    (unless transient-mark-mode
+      (evil-active-region -1)
+      (transient-mark-mode 1)))))
+
+(defun evil-active-region (&optional arg)
+  "Toggle active region.
+Ensure that Transient Mark mode is properly enabled.
+Enable with positive ARG, disable with negative ARG."
+  (unless (numberp arg)
+    (setq arg (if (region-active-p) -1 1)))
+  (cond
+   ((and (< arg 1))
+    (when (or transient-mark-mode mark-active)
+      (setq mark-active nil
+            deactivate-mark nil)
+      (when (boundp 'cua--explicit-region-start)
+        (setq cua--explicit-region-start nil))
+      (run-hooks 'deactivate-mark-hook)))
+   (t
+    (evil-transient-mark 1)
+    (when deactivate-mark
+      (setq deactivate-mark nil))
+    (unless (mark t)
+      (evil-move-mark (point)))
+    (unless (region-active-p)
+      (set-mark (mark t)))
+    (when (boundp 'cua--explicit-region-start)
+      (setq cua--explicit-region-start t)))))
+
+(defmacro evil-with-transient-mark-mode (&rest body)
+  "Execute BODY with Transient Mark mode.
+Then restore Transient Mark mode to its previous setting."
+  (declare (indent defun)
+           (debug t))
+  `(let ((inhibit-quit t)
+         evil-transient-vals)
+     (unwind-protect
+         (progn
+           (evil-save-transient-mark-mode)
+           (evil-transient-mark 1)
+           ,@body)
+       (evil-restore-transient-mark-mode))))
+
+(defmacro evil-with-active-region (beg end &rest body)
+  "Execute BODY with an active region from BEG to END."
+  (declare (indent 2)
+           (debug t))
+  `(let ((beg ,beg) (end ,end)
+         evil-transient-vals)
+     (evil-with-transient-mark-mode
+       (save-excursion
+         (evil-active-region 1)
+         (evil-move-mark beg)
+         (goto-char end)
+         ,@body))))
+
+(defun evil-exchange-point-and-mark ()
+  "Exchange point and mark without activating the region."
+  (let* ((point (point))
+         (mark  (or (mark t) point)))
+    (set-marker (mark-marker) point)
+    (goto-char mark)))
+
+(defun evil-apply-on-block (func beg end pass-columns &rest args)
+  "Call FUNC for each line of a block selection.
+The selection is specified by the region BEG and END.  FUNC must
+take at least two arguments, the beginning and end of each
+line. If PASS-COLUMNS is non-nil, these values are the columns,
+otherwise tey are buffer positions. Extra arguments to FUNC may
+be passed via ARGS."
+  (let ((eol-col (and (memq last-command '(next-line previous-line))
+                      (numberp temporary-goal-column)
+                      temporary-goal-column))
+        startcol startpt endcol endpt)
+    (save-excursion
+      (goto-char beg)
+      (setq startcol (current-column))
+      (beginning-of-line)
+      (setq startpt (point))
+      (goto-char end)
+      (setq endcol (current-column))
+      (forward-line 1)
+      (setq endpt (point-marker))
+      ;; ensure the start column is the left one.
+      (evil-sort startcol endcol)
+      ;; maybe find maximal column
+      (when eol-col
+        (setq eol-col 0)
+        (goto-char startpt)
+        (while (< (point) endpt)
+          (setq eol-col (max eol-col
+                             (evil-column (line-end-position))))
+          (forward-line 1))
+        (setq endcol (max endcol
+                          (min eol-col
+                               (1+ (min (1- most-positive-fixnum)
+                                        (truncate temporary-goal-column)))))))
+      ;; start looping over lines
+      (goto-char startpt)
+      (while (< (point) endpt)
+        (if pass-columns
+            (apply func startcol endcol args)
+          (apply func
+                 (save-excursion (evil-move-to-column startcol))
+                 (save-excursion (evil-move-to-column endcol t))
+                 args))
+        (forward-line 1)))))
+
+(defun evil-apply-on-rectangle (function start end &rest args)
+  "Like `apply-on-rectangle' but maybe extends to eol.
+If `temporary-goal-column' is set to a big number, then the
+region of each line is extended to the end of each line. The end
+column is set to the maximal column in all covered lines."
+  (apply #'evil-apply-on-block function start end t args))
+
+;;; Insertion
+
+(defun evil-concat-ranges (ranges)
+  "Concatenate RANGES.
+RANGES must be a list of ranges.  They must be ordered so that
+successive ranges share their boundaries.  The return value is a
+single range of disjoint union of the ranges or nil if the
+disjoint union is not a single range."
+  (let ((range (car-safe ranges)) (ranges (cdr ranges)) r)
+    (while (and range (setq r (car-safe ranges)))
+      (setq range
+            (cond ((and (= (cdr r) (car range))) (cons (car r) (cdr range)))
+                  ((and (= (cdr range) (car r))) (cons (car range) (cdr r)))))
+      (setq ranges (cdr ranges)))
+    range))
+
+(defun evil-track-last-insertion (beg end len)
+  "Track the last insertion range and its text.
+The insertion range is stored as a pair of buffer positions in
+`evil-current-insertion'. If a subsequent change is compatible,
+then the current range is modified, otherwise it is replaced by a
+new range. Compatible changes are changes that do not create a
+disjoin range."
+  ;; deletion
+  (when (> len 0)
+    (if (and evil-current-insertion
+             (>= beg (car evil-current-insertion))
+             (<= (+ beg len) (cdr evil-current-insertion)))
+        (setcdr evil-current-insertion
+                (- (cdr evil-current-insertion) len))
+      (setq evil-current-insertion nil)))
+  ;; insertion
+  (if (and evil-current-insertion
+           (>= beg (car evil-current-insertion))
+           (<= beg (cdr evil-current-insertion)))
+      (setcdr evil-current-insertion
+              (+ (- end beg)
+                 (cdr evil-current-insertion)))
+    (setq evil-current-insertion (cons beg end))))
+(put 'evil-track-last-insertion 'permanent-local-hook t)
+
+(defun evil-start-track-last-insertion ()
+  "Start tracking the last insertion."
+  (setq evil-current-insertion nil)
+  (add-hook 'after-change-functions #'evil-track-last-insertion nil t))
+
+(defun evil-stop-track-last-insertion ()
+  "Stop tracking the last insertion.
+The tracked insertion is set to `evil-last-insertion'."
+  (setq evil-last-insertion
+        (and evil-current-insertion
+             ;; Check whether the insertion range is a valid buffer
+             ;; range.  If a buffer modification is done from within
+             ;; another change hook or modification-hook (yasnippet
+             ;; does this using overlay modification-hooks), then the
+             ;; insertion information may be invalid. There is no way
+             ;; to detect this situation, but at least we should
+             ;; ensure that no error occurs (see bug #272).
+             (>= (car evil-current-insertion) (point-min))
+             (<= (cdr evil-current-insertion) (point-max))
+             (buffer-substring-no-properties (car evil-current-insertion)
+                                             (cdr evil-current-insertion))))
+  (remove-hook 'after-change-functions #'evil-track-last-insertion t))
+
+;;; Paste
+
+(defun evil-yank-characters (beg end &optional register yank-handler)
+  "Saves the characters defined by the region BEG and END in the kill-ring."
+  (let ((text (filter-buffer-substring beg end)))
+    (when yank-handler
+      (setq text (propertize text 'yank-handler (list yank-handler))))
+    (when register
+      (evil-set-register register text))
+    (when evil-was-yanked-without-register
+      (evil-set-register ?0 text)) ; "0 register contains last yanked text
+    (unless (eq register ?_)
+      (kill-new text))))
+
+(defun evil-yank-lines (beg end &optional register yank-handler)
+  "Saves the lines in the region BEG and END into the kill-ring."
+  (let* ((text (filter-buffer-substring beg end))
+         (yank-handler (list (or yank-handler
+                                 #'evil-yank-line-handler)
+                             nil
+                             t)))
+    ;; Ensure the text ends with a newline. This is required
+    ;; if the deleted lines were the last lines in the buffer.
+    (when (or (zerop (length text))
+              (/= (aref text (1- (length text))) ?\n))
+      (setq text (concat text "\n")))
+    (setq text (propertize text 'yank-handler yank-handler))
+    (when register
+      (evil-set-register register text))
+    (when evil-was-yanked-without-register
+      (evil-set-register ?0 text)) ; "0 register contains last yanked text
+    (unless (eq register ?_)
+      (kill-new text))))
+
+(defun evil-yank-rectangle (beg end &optional register yank-handler)
+  "Saves the rectangle defined by region BEG and END into the kill-ring."
+  (let ((lines (list nil)))
+    (evil-apply-on-rectangle #'extract-rectangle-line beg end lines)
+    ;; We remove spaces from the beginning and the end of the next.
+    ;; Spaces are inserted explicitly in the yank-handler in order to
+    ;; NOT insert lines full of spaces.
+    (setq lines (nreverse (cdr lines)))
+    ;; `text' is used as default insert text when pasting this rectangle
+    ;; in another program, e.g., using the X clipboard.
+    (let* ((yank-handler (list (or yank-handler
+                                   #'evil-yank-block-handler)
+                               lines
+                               t
+                               'evil-delete-yanked-rectangle))
+           (text (propertize (mapconcat #'identity lines "\n")
+                             'yank-handler yank-handler)))
+      (when register
+        (evil-set-register register text))
+      (when evil-was-yanked-without-register
+        (evil-set-register ?0 text)) ; "0 register contains last yanked text
+      (unless (eq register ?_)
+        (kill-new text)))))
+
+(defun evil-yank-line-handler (text)
+  "Inserts the current text linewise."
+  (let ((text (apply #'concat (make-list (or evil-paste-count 1) text)))
+        (opoint (point)))
+    (remove-list-of-text-properties
+     0 (length text) yank-excluded-properties text)
+    (cond
+     ((eq this-command 'evil-paste-before)
+      (evil-move-beginning-of-line)
+      (evil-move-mark (point))
+      (insert text)
+      (setq evil-last-paste
+            (list 'evil-paste-before
+                  evil-paste-count
+                  opoint
+                  (mark t)
+                  (point)))
+      (evil-set-marker ?\[ (mark))
+      (evil-set-marker ?\] (1- (point)))
+      (evil-exchange-point-and-mark)
+      (back-to-indentation))
+     ((eq this-command 'evil-paste-after)
+      (evil-move-end-of-line)
+      (evil-move-mark (point))
+      (insert "\n")
+      (insert text)
+      (evil-set-marker ?\[ (1+ (mark)))
+      (evil-set-marker ?\] (1- (point)))
+      (delete-char -1) ; delete the last newline
+      (setq evil-last-paste
+            (list 'evil-paste-after
+                  evil-paste-count
+                  opoint
+                  (mark t)
+                  (point)))
+      (evil-move-mark (1+ (mark t)))
+      (evil-exchange-point-and-mark)
+      (back-to-indentation))
+     (t
+      (insert text)))))
+
+(defun evil-yank-block-handler (lines)
+  "Inserts the current text as block."
+  (let ((count (or evil-paste-count 1))
+        (col (if (eq this-command 'evil-paste-after)
+                 (1+ (current-column))
+               (current-column)))
+        (current-line (line-number-at-pos (point)))
+        (opoint (point))
+        epoint)
+    (dolist (line lines)
+      ;; concat multiple copies according to count
+      (setq line (apply #'concat (make-list count line)))
+      ;; strip whitespaces at beginning and end
+      (string-match "^ *\\(.*?\\) *$" line)
+      (let ((text (match-string 1 line))
+            (begextra (match-beginning 1))
+            (endextra (- (match-end 0) (match-end 1))))
+        ;; maybe we have to insert a new line at eob
+        (while (< (line-number-at-pos (point))
+                  current-line)
+          (goto-char (point-max))
+          (insert "\n"))
+        (setq current-line (1+ current-line))
+        ;; insert text unless we insert an empty line behind eol
+        (unless (and (< (evil-column (line-end-position)) col)
+                     (zerop (length text)))
+          ;; if we paste behind eol, it may be sufficient to insert tabs
+          (if (< (evil-column (line-end-position)) col)
+              (move-to-column (+ col begextra) t)
+            (move-to-column col t)
+            (insert (make-string begextra ? )))
+          (remove-list-of-text-properties 0 (length text)
+                                          yank-excluded-properties text)
+          (insert text)
+          (unless (eolp)
+            ;; text follows, so we have to insert spaces
+            (insert (make-string endextra ? )))
+          (setq epoint (point)))
+        (forward-line 1)))
+    (setq evil-last-paste
+          (list this-command
+                evil-paste-count
+                opoint
+                (length lines)                   ; number of rows
+                (* count (length (car lines))))) ; number of colums
+    (evil-set-marker ?\[ opoint)
+    (evil-set-marker ?\] (1- epoint))
+    (goto-char opoint)
+    (when (and (eq this-command 'evil-paste-after)
+               (not (eolp)))
+      (forward-char))))
+
+(defun evil-delete-yanked-rectangle (nrows ncols)
+  "Special function to delete the block yanked by a previous paste command."
+  (let ((opoint (point))
+        (col (if (eq last-command 'evil-paste-after)
+                 (1+ (current-column))
+               (current-column))))
+    (dotimes (i nrows)
+      (delete-region (save-excursion
+                       (move-to-column col)
+                       (point))
+                     (save-excursion
+                       (move-to-column (+ col ncols))
+                       (point)))
+      (unless (eobp) (forward-line)))
+    (goto-char opoint)))
+
+;; TODO: if undoing is disabled in the current buffer, paste-pop won't
+;; work. Although this is probably not a big problem, because usually
+;; buffers where `evil-paste-pop' may be useful have undoing enabled.
+;; A solution would be to temporarily enable undo when pasting and
+;; store the undo information in a special variable that does not
+;; interfere with `buffer-undo-list'.
+(defun evil-paste-pop (count)
+  "Replace the just-yanked stretch of killed text with a different stretch.
+This command is allowed only immediatly after a `yank',
+`evil-paste-before', `evil-paste-after' or `evil-paste-pop'.
+This command uses the same paste command as before, i.e., when
+used after `evil-paste-after' the new text is also yanked using
+`evil-paste-after', used with the same paste-count argument.
+
+The COUNT argument inserts the COUNTth previous kill.  If COUNT
+is negative this is a more recent kill."
+  (interactive "p")
+  (unless (memq last-command
+                '(evil-paste-after
+                  evil-paste-before
+                  evil-visual-paste))
+    (user-error "Previous command was not an evil-paste: %s" last-command))
+  (unless evil-last-paste
+    (user-error "Previous paste command used a register"))
+  (evil-undo-pop)
+  (goto-char (nth 2 evil-last-paste))
+  (setq this-command (nth 0 evil-last-paste))
+  ;; use temporary kill-ring, so the paste cannot modify it
+  (let ((kill-ring (list (current-kill
+                          (if (and (> count 0) (nth 5 evil-last-paste))
+                              ;; if was visual paste then skip the
+                              ;; text that has been replaced
+                              (1+ count)
+                            count))))
+        (kill-ring-yank-pointer kill-ring))
+    (when (eq last-command 'evil-visual-paste)
+      (let ((evil-no-display t))
+        (evil-visual-restore)))
+    (funcall (nth 0 evil-last-paste) (nth 1 evil-last-paste))
+    ;; if this was a visual paste, then mark the last paste as NOT
+    ;; being the first visual paste
+    (when (eq last-command 'evil-visual-paste)
+      (setcdr (nthcdr 4 evil-last-paste) nil))))
+
+(defun evil-paste-pop-next (count)
+  "Same as `evil-paste-pop' but with negative argument."
+  (interactive "p")
+  (evil-paste-pop (- count)))
+
+;;; Interactive forms
+
+(defun evil-match-interactive-code (interactive &optional pos)
+  "Match an interactive code at position POS in string INTERACTIVE.
+Returns the first matching entry in `evil-interactive-alist', or nil."
+  (let ((length (length interactive))
+        (pos (or pos 0)))
+    (catch 'done
+      (dolist (entry evil-interactive-alist)
+        (let* ((string (car entry))
+               (end (+ (length string) pos)))
+          (when (and (<= end length)
+                     (string= string
+                              (substring interactive pos end)))
+            (throw 'done entry)))))))
+
+(defun evil-concatenate-interactive-forms (&rest forms)
+  "Concatenate interactive list expressions FORMS.
+Returns a single expression where successive expressions
+are joined, if possible."
+  (let (result)
+    (when forms
+      (while (cdr forms)
+        (cond
+         ((null (car forms))
+          (pop forms))
+         ((and (eq (car (car forms)) 'list)
+               (eq (car (cadr forms)) 'list))
+          (setq forms (cons (append (car forms)
+                                    (cdr (cadr forms)))
+                            (cdr (cdr forms)))))
+         (t
+          (push (pop forms) result))))
+      (when (car forms)
+        (push (pop forms) result))
+      (setq result (nreverse result))
+      (cond
+       ((null result))
+       ((null (cdr result))
+        (car result))
+       (t
+        `(append ,@result))))))
+
+(defun evil-interactive-string (string)
+  "Evaluate the interactive string STRING.
+The string may contain extended interactive syntax.
+The return value is a cons cell (FORM . PROPERTIES),
+where FORM is a single list-expression to be passed to
+a standard `interactive' statement, and PROPERTIES is a
+list of command properties as passed to `evil-define-command'."
+  (let ((length (length string))
+        (pos 0)
+        code expr forms match plist prompt properties)
+    (while (< pos length)
+      (if (eq (aref string pos) ?\n)
+          (setq pos (1+ pos))
+        (setq match (evil-match-interactive-code string pos))
+        (if (null match)
+            (user-error "Unknown interactive code: `%s'"
+                        (substring string pos))
+          (setq code (car match)
+                expr (car (cdr match))
+                plist (cdr (cdr match))
+                pos (+ pos (length code)))
+          (when (functionp expr)
+            (setq prompt
+                  (substring string pos
+                             (or (string-match "\n" string pos)
+                                 length))
+                  pos (+ pos (length prompt))
+                  expr `(funcall ,expr ,prompt)))
+          (setq forms (append forms (list expr))
+                properties (append properties plist)))))
+    (cons `(append ,@forms) properties)))
+
+(defun evil-interactive-form (&rest args)
+  "Evaluate interactive forms ARGS.
+The return value is a cons cell (FORM . PROPERTIES),
+where FORM is a single list-expression to be passed to
+a standard `interactive' statement, and PROPERTIES is a
+list of command properties as passed to `evil-define-command'."
+  (let (forms properties)
+    (dolist (arg args)
+      (if (not (stringp arg))
+          (setq forms (append forms (list arg)))
+        (setq arg (evil-interactive-string arg)
+              forms (append forms (cdr (car arg)))
+              properties (append properties (cdr arg)))))
+    (cons (apply #'evil-concatenate-interactive-forms forms)
+          properties)))
+
+;;; Types
+
+(defun evil-type (object &optional default)
+  "Return the type of OBJECT, or DEFAULT if none."
+  (let (type)
+    (cond
+     ((overlayp object)
+      (setq type (overlay-get object :type)))
+     ((evil-range-p object)
+      (setq type (nth 2 object)))
+     ((listp object)
+      (setq type (plist-get object :type)))
+     ((commandp object)
+      (setq type (evil-get-command-property object :type)))
+     ((symbolp object)
+      (setq type (get object 'type))))
+    (setq type (or type default))
+    (and (evil-type-p type) type)))
+
+(defun evil-set-type (object type)
+  "Set the type of OBJECT to TYPE.
+For example, (evil-set-type 'next-line 'line)
+will make `line' the type of the `next-line' command."
+  (cond
+   ((overlayp object)
+    (overlay-put object :type type))
+   ((evil-range-p object)
+    (evil-set-range-type object type))
+   ((listp object)
+    (plist-put object :type type))
+   ((commandp object)
+    (evil-set-command-property object :type type))
+   ((symbolp object)
+    (put object 'type type)))
+  object)
+
+(defun evil-type-property (type prop)
+  "Return property PROP for TYPE."
+  (evil-get-property evil-type-properties type prop))
+
+(defun evil-type-p (sym)
+  "Whether SYM is the name of a type."
+  (assq sym evil-type-properties))
+
+(defun evil-expand (beg end type &rest properties)
+  "Expand BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+  (apply #'evil-transform
+         ;; don't expand if already expanded
+         (unless (plist-get properties :expanded) :expand)
+         beg end type properties))
+
+(defun evil-contract (beg end type &rest properties)
+  "Contract BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+  (apply #'evil-transform :contract beg end type properties))
+
+(defun evil-normalize (beg end type &rest properties)
+  "Normalize BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+  (apply #'evil-transform :normalize beg end type properties))
+
+(defun evil-transform (transform beg end type &rest properties)
+  "Apply TRANSFORM on BEG and END with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list. If TRANSFORM is undefined,
+return positions unchanged."
+  (let* ((type (or type (evil-type properties)))
+         (transform (when (and type transform)
+                      (evil-type-property type transform))))
+    (if transform
+        (apply transform beg end properties)
+      (apply #'evil-range beg end type properties))))
+
+(defun evil-describe (beg end type &rest properties)
+  "Return description of BEG and END with PROPERTIES.
+If no description is available, return the empty string."
+  (let* ((type (or type (evil-type properties)))
+         (properties (plist-put properties :type type))
+         (describe (evil-type-property type :string)))
+    (or (when describe
+          (apply describe beg end properties))
+        "")))
+
+;;; Ranges
+
+(defun evil-range (beg end &optional type &rest properties)
+  "Return a list (BEG END [TYPE] PROPERTIES...).
+BEG and END are buffer positions (numbers or markers),
+TYPE is a type as per `evil-type-p', and PROPERTIES is
+a property list."
+  (let ((beg (evil-normalize-position beg))
+        (end (evil-normalize-position end)))
+    (when (and (numberp beg) (numberp end))
+      (append (list (min beg end) (max beg end))
+              (when (evil-type-p type)
+                (list type))
+              properties))))
+
+(defun evil-range-p (object)
+  "Whether OBJECT is a range."
+  (and (listp object)
+       (>= (length object) 2)
+       (numberp (nth 0 object))
+       (numberp (nth 1 object))))
+
+(defun evil-range-beginning (range)
+  "Return beginning of RANGE."
+  (when (evil-range-p range)
+    (let ((beg (evil-normalize-position (nth 0 range)))
+          (end (evil-normalize-position (nth 1 range))))
+      (min beg end))))
+
+(defun evil-range-end (range)
+  "Return end of RANGE."
+  (when (evil-range-p range)
+    (let ((beg (evil-normalize-position (nth 0 range)))
+          (end (evil-normalize-position (nth 1 range))))
+      (max beg end))))
+
+(defun evil-range-properties (range)
+  "Return properties of RANGE."
+  (when (evil-range-p range)
+    (if (evil-type range)
+        (nthcdr 3 range)
+      (nthcdr 2 range))))
+
+(defun evil-copy-range (range)
+  "Return a copy of RANGE."
+  (copy-sequence range))
+
+(defun evil-set-range (range &optional beg end type &rest properties)
+  "Set RANGE to have beginning BEG and end END.
+The TYPE and additional PROPERTIES may also be specified.
+If an argument is nil, it's not used; the previous value is retained.
+See also `evil-set-range-beginning', `evil-set-range-end',
+`evil-set-range-type' and `evil-set-range-properties'."
+  (when (evil-range-p range)
+    (let ((beg (or (evil-normalize-position beg)
+                   (evil-range-beginning range)))
+          (end (or (evil-normalize-position end)
+                   (evil-range-end range)))
+          (type (or type (evil-type range)))
+          (plist (evil-range-properties range)))
+      (evil-sort beg end)
+      (setq plist (evil-concat-plists plist properties))
+      (evil-set-range-beginning range beg)
+      (evil-set-range-end range end)
+      (evil-set-range-type range type)
+      (evil-set-range-properties range plist)
+      range)))
+
+(defun evil-set-range-beginning (range beg &optional copy)
+  "Set RANGE's beginning to BEG.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (setcar range beg)
+  range)
+
+(defun evil-set-range-end (range end &optional copy)
+  "Set RANGE's end to END.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (setcar (cdr range) end)
+  range)
+
+(defun evil-set-range-type (range type &optional copy)
+  "Set RANGE's type to TYPE.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (if type
+      (setcdr (cdr range)
+              (cons type (evil-range-properties range)))
+    (setcdr (cdr range) (evil-range-properties range)))
+  range)
+
+(defun evil-set-range-properties (range properties &optional copy)
+  "Set RANGE's properties to PROPERTIES.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (if (evil-type range)
+      (setcdr (cdr (cdr range)) properties)
+    (setcdr (cdr range) properties))
+  range)
+
+(defun evil-range-union (range1 range2 &optional type)
+  "Return the union of the ranges RANGE1 and RANGE2.
+If the ranges have conflicting types, use RANGE1's type.
+This can be overridden with TYPE."
+  (when (and (evil-range-p range1)
+             (evil-range-p range2))
+    (evil-range (min (evil-range-beginning range1)
+                     (evil-range-beginning range2))
+                (max (evil-range-end range1)
+                     (evil-range-end range2))
+                (or type
+                    (evil-type range1)
+                    (evil-type range2)))))
+
+(defun evil-subrange-p (range1 range2)
+  "Whether RANGE1 is contained within RANGE2."
+  (and (evil-range-p range1)
+       (evil-range-p range2)
+       (<= (evil-range-beginning range2)
+           (evil-range-beginning range1))
+       (>= (evil-range-end range2)
+           (evil-range-end range1))))
+
+(defun evil-select-inner-object (thing beg end type &optional count line)
+  "Return an inner text object range of COUNT objects.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point.  FORWARD is a function
+which moves to the end of an object, and BACKWARD is a function
+which moves to the beginning.  If one is unspecified, the other
+is used with a negative argument.  THING is a symbol understood
+by thing-at-point. BEG, END and TYPE specify the current
+selection. If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+  (let* ((count (or count 1))
+         (bnd (or (let ((b (bounds-of-thing-at-point thing)))
+                    (and b (< (point) (cdr b)) b))
+                  (evil-bounds-of-not-thing-at-point thing))))
+    ;; check if current object is selected
+    (when (or (not beg) (not end)
+              (> beg (car bnd))
+              (< end (cdr bnd))
+              (and (eq type 'inclusive)
+                   (= (1+ beg) end))) ; empty region does not count
+      (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+      (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+      (setq count (if (> count 0) (1- count) (1+ count))))
+    (goto-char (if (< count 0) beg end))
+    (evil-forward-nearest count
+                          #'(lambda (cnt) (forward-thing thing cnt))
+                          #'(lambda (cnt) (evil-forward-not-thing thing cnt)))
+    (evil-range (if (>= count 0) beg (point))
+                (if (< count 0) end (point))
+                (if line 'line type)
+                :expanded t)))
+
+(defun evil-select-an-object (thing beg end type count &optional line)
+  "Return an outer text object range of COUNT objects.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point.  FORWARD is a function
+which moves to the end of an object, and BACKWARD is a function
+which moves to the beginning.  If one is unspecified, the other
+is used with a negative argument.  THING is a symbol understood
+by thing-at-point. BEG, END and TYPE specify the current
+selection. If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+  (let* ((dir (if (> (or count 1) 0) +1 -1))
+         (count (abs (or count 1)))
+         (objbnd (let ((b (bounds-of-thing-at-point thing)))
+                   (and b (< (point) (cdr b)) b)))
+         (bnd (or objbnd (evil-bounds-of-not-thing-at-point thing)))
+         addcurrent other)
+    ;; check if current object is not selected
+    (when (or (not beg) (not end)
+              (> beg (car bnd))
+              (< end (cdr bnd))
+              (and (eq type 'inclusive)
+                   (= (1+ beg) end))) ; empty region does not count
+      ;; if not, enlarge selection
+      (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+      (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+      (if objbnd (setq addcurrent t)))
+    ;; make other and (point) reflect the selection
+    (cond
+     ((> dir 0) (goto-char end) (setq other beg))
+     (t (goto-char beg) (setq other end)))
+    (cond
+     ;; do nothing more than only current is selected
+     ((not (and (= beg (car bnd)) (= end (cdr bnd)))))
+     ;; current match is thing, add whitespace
+     (objbnd
+      (let ((wsend (evil-with-restriction
+                       ;; restrict to current line if we do non-line selection
+                       (and (not line) (line-beginning-position))
+                       (and (not line) (line-end-position))
+                     (evil-bounds-of-not-thing-at-point thing dir))))
+        (cond
+         (wsend
+          ;; add whitespace at end
+          (goto-char wsend)
+          (setq addcurrent t))
+         (t
+          ;; no whitespace at end, try beginning
+          (save-excursion
+            (goto-char other)
+            (setq wsend
+                  (evil-with-restriction
+                      ;; restrict to current line if we do non-line selection
+                      (and (not line) (line-beginning-position))
+                      (and (not line) (line-end-position))
+                    (evil-bounds-of-not-thing-at-point thing (- dir))))
+            (when wsend (setq other wsend addcurrent t)))))))
+     ;; current match is whitespace, add thing
+     (t
+      (forward-thing thing dir)
+      (setq addcurrent t)))
+    ;; possibly count current object as selection
+    (if addcurrent (setq count (1- count)))
+    ;; move
+    (dotimes (var count)
+      (let ((wsend (evil-bounds-of-not-thing-at-point thing dir)))
+        (if (and wsend (/= wsend (point)))
+            ;; start with whitespace
+            (forward-thing thing dir)
+          ;; start with thing
+          (forward-thing thing dir)
+          (setq wsend (evil-bounds-of-not-thing-at-point thing dir))
+          (when wsend (goto-char wsend)))))
+    ;; return range
+    (evil-range (if (> dir 0) other (point))
+                (if (< dir 0) other (point))
+                (if line 'line type)
+                :expanded t)))
+
+(defun evil--get-block-range (op cl selection-type)
+  "Return the exclusive range of a visual selection.
+OP and CL are pairs of buffer positions for the opening and
+closing delimiter of a range. SELECTION-TYPE is the desired type
+of selection.  It is a symbol that determines which parts of the
+block are selected.  If it is 'inclusive or t the returned range
+is \(cons (car OP) (cdr CL)). If it is 'exclusive or nil the
+returned range is (cons (cdr OP) (car CL)).  If it is
+'exclusive-line the returned range will skip whitespace at the
+end of the line of OP and at the beginning of the line of CL."
+  (cond
+   ((memq selection-type '(inclusive t)) (cons (car op) (cdr cl)))
+   ((memq selection-type '(exclusive nil)) (cons (cdr op) (car cl)))
+   ((eq selection-type 'exclusive-line)
+    (let ((beg (cdr op))
+          (end (car cl)))
+      (save-excursion
+        (goto-char beg)
+        (when (and (eolp) (not (eobp)))
+          (setq beg (line-beginning-position 2)))
+        (goto-char end)
+        (skip-chars-backward " \t")
+        (when (bolp)
+          (setq end (point))
+          (goto-char beg)
+          (when (and (not (bolp)) (< beg end))
+            (setq end (1- end)))))
+      (cons beg end)))
+   (t
+    (user-error "Unknown selection-type %s" selection-type))))
+
+(defun evil-select-block (thing beg end type count
+                                &optional
+                                selection-type
+                                countcurrent
+                                fixedscan)
+  "Return a range (BEG END) of COUNT delimited text objects.
+BEG END TYPE are the currently selected (visual) range.  The
+delimited object must be given by THING-up function (see
+`evil-up-block').
+
+SELECTION-TYPE is symbol that determines which parts of the block
+are selected.  If it is 'inclusive or t OPEN and CLOSE are
+included in the range. If it is 'exclusive or nil the delimiters
+are not contained. If it is 'exclusive-line the delimiters are
+not included as well as adjacent whitespace until the beginning
+of the next line or the end of the previous line. If the
+resulting selection consists of complete lines only and visual
+state is not active, the returned selection is linewise.
+
+If COUNTCURRENT is non-nil an objected is counted if the current
+selection matches that object exactly.
+
+Usually scanning for the surrounding block starts at (1+ beg)
+and (1- end). If this might fail due to the behavior of THING
+then FIXEDSCAN can be set to t. In this case the scan starts at
+BEG and END. One example where this might fail is if BEG and END
+are the delimiters of a string or comment."
+  (save-excursion
+    (save-match-data
+      (let* ((orig-beg beg)
+             (orig-end end)
+             (beg (or beg (point)))
+             (end (or end (point)))
+             (count (abs (or count 1)))
+             op cl op-end cl-end)
+        ;; We always assume at least one selected character.
+        (if (= beg end) (setq end (1+ end)))
+        ;; We scan twice: starting at (1+ beg) forward and at (1- end)
+        ;; backward. The resulting selection is the smaller one.
+        (goto-char (if fixedscan beg (1+ beg)))
+        (when (and (zerop (funcall thing +1)) (match-beginning 0))
+          (setq cl (cons (match-beginning 0) (match-end 0)))
+          (goto-char (car cl))
+          (when (and (zerop (funcall thing -1)) (match-beginning 0))
+            (setq op (cons (match-beginning 0) (match-end 0)))))
+        ;; start scanning from end
+        (goto-char (if fixedscan end (1- end)))
+        (when (and (zerop (funcall thing -1)) (match-beginning 0))
+          (setq op-end (cons (match-beginning 0) (match-end 0)))
+          (goto-char (cdr op-end))
+          (when (and (zerop (funcall thing +1)) (match-beginning 0))
+            (setq cl-end (cons (match-beginning 0) (match-end 0)))))
+        ;; Bug #607: use the tightest selection that contains the
+        ;; original selection. If non selection contains the original,
+        ;; use the larger one.
+        (cond
+         ((and (not op) (not cl-end))
+          (error "No surrounding delimiters found"))
+         ((or (not op) ; first not found
+              (and cl-end ; second found
+                   (>= (car op-end) (car op)) ; second smaller
+                   (<= (cdr cl-end) (cdr cl))
+                   (<= (car op-end) beg)      ; second contains orig
+                   (>= (cdr cl-end) end)))
+          (setq op op-end cl cl-end)))
+        (setq op-end op cl-end cl) ; store copy
+        ;; if the current selection contains the surrounding
+        ;; delimiters, they do not count as new selection
+        (let ((cnt (if (and orig-beg orig-end (not countcurrent))
+                       (let ((sel (evil--get-block-range op cl selection-type)))
+                         (if (and (<= orig-beg (car sel))
+                                  (>= orig-end (cdr sel)))
+                             count
+                           (1- count)))
+                     (1- count))))
+          ;; starting from the innermost surrounding delimiters
+          ;; increase selection
+          (when (> cnt 0)
+            (setq op (progn
+                       (goto-char (car op-end))
+                       (funcall thing (- cnt))
+                       (if (match-beginning 0)
+                           (cons (match-beginning 0) (match-end 0))
+                         op))
+                  cl (progn
+                       (goto-char (cdr cl-end))
+                       (funcall thing cnt)
+                       (if (match-beginning 0)
+                           (cons (match-beginning 0) (match-end 0))
+                         cl)))))
+        (let ((sel (evil--get-block-range op cl selection-type)))
+          (setq op (car sel)
+                cl (cdr sel)))
+        (cond
+         ((and (equal op orig-beg) (equal cl orig-end)
+               (or (not countcurrent)
+                   (and countcurrent (/= count 1))))
+          (error "No surrounding delimiters found"))
+         ((save-excursion
+            (and (not (evil-visual-state-p))
+                 (eq type 'inclusive)
+                 (progn (goto-char op) (bolp))
+                 (progn (goto-char cl) (bolp))))
+          (evil-range op cl 'line :expanded t))
+         (t
+          (evil-range op cl type :expanded t)))))))
+
+(defun evil-select-paren (open close beg end type count &optional inclusive)
+  "Return a range (BEG END) of COUNT delimited text objects.
+OPEN and CLOSE specify the opening and closing delimiter,
+respectively. BEG END TYPE are the currently selected (visual)
+range.  If INCLUSIVE is non-nil, OPEN and CLOSE are included in
+the range; otherwise they are excluded.
+
+The types of OPEN and CLOSE specify which kind of THING is used
+for parsing with `evil-select-block'. If OPEN and CLOSE are
+characters `evil-up-paren' is used. Otherwise OPEN and CLOSE
+must be regular expressions and `evil-up-block' is used.
+
+If the selection is exclusive, whitespace at the end or at the
+beginning of the selection until the end-of-line or beginning-of-line
+is ignored."
+  ;; we need special linewise exclusive selection
+  (unless inclusive (setq inclusive 'exclusive-line))
+  (cond
+   ((and (characterp open) (characterp close))
+    (let ((thing #'(lambda (&optional cnt)
+                     (evil-up-paren open close cnt)))
+          (bnd (or (bounds-of-thing-at-point 'evil-string)
+                   (bounds-of-thing-at-point 'evil-comment)
+                   ;; If point is at the opening quote of a string,
+                   ;; this must be handled as if point is within the
+                   ;; string, i.e. the selection must be extended
+                   ;; around the string. Otherwise
+                   ;; `evil-select-block' might do the wrong thing
+                   ;; because it accidentally moves point inside the
+                   ;; string (for inclusive selection) when looking
+                   ;; for the current surrounding block. (re #364)
+                   (and (= (point) (or beg (point)))
+                        (save-excursion
+                          (goto-char (1+ (or beg (point))))
+                          (or (bounds-of-thing-at-point 'evil-string)
+                              (bounds-of-thing-at-point 'evil-comment)))))))
+      (if (not bnd)
+          (evil-select-block thing beg end type count inclusive)
+        (or (evil-with-restriction (car bnd) (cdr bnd)
+              (condition-case nil
+                  (evil-select-block thing beg end type count inclusive)
+                (error nil)))
+            (save-excursion
+              (setq beg (or beg (point))
+                    end (or end (point)))
+              (goto-char (car bnd))
+              (let ((extbeg (min beg (car bnd)))
+                    (extend (max end (cdr bnd))))
+                (evil-select-block thing
+                                   extbeg extend
+                                   type
+                                   count
+                                   inclusive
+                                   (or (< extbeg beg) (> extend end))
+                                   t)))))))
+   (t
+    (evil-select-block #'(lambda (&optional cnt)
+                           (evil-up-block open close cnt))
+                       beg end type count inclusive))))
+
+(defun evil-select-quote-thing (thing beg end type count &optional inclusive)
+  "Selection THING as if it described a quoted object.
+THING is typically either 'evil-quote or 'evil-chars. This
+function is called from `evil-select-quote'."
+  (save-excursion
+    (let* ((count (or count 1))
+           (dir (if (> count 0) 1 -1))
+           (bnd (let ((b (bounds-of-thing-at-point thing)))
+                  (and b (< (point) (cdr b)) b)))
+           contains-string
+           addcurrent
+           wsboth)
+      (if inclusive (setq inclusive t)
+        (when (= (abs count) 2)
+          (setq count dir)
+          (setq inclusive 'quote-only))
+        ;; never extend with exclusive selection
+        (setq beg nil end nil))
+      ;; check if the previously selected range does not contain a
+      ;; string
+      (unless (and beg end
+                   (save-excursion
+                     (goto-char (if (> dir 0) beg end))
+                     (forward-thing thing dir)
+                     (and (<= beg (point)) (< (point) end))))
+        ;; if so forget the range
+        (setq beg nil end nil))
+      ;; check if there is a current object, if not fetch one
+      (when (not bnd)
+        (unless (and (zerop (forward-thing thing dir))
+                     (setq bnd (bounds-of-thing-at-point thing)))
+          (error "No quoted string found"))
+        (if (> dir 0)
+            (setq end (point))
+          (setq beg (point)))
+        (setq addcurrent t))
+      ;; check if current object is not selected
+      (when (or (not beg) (not end) (> beg (car bnd)) (< end (cdr bnd)))
+        ;; if not, enlarge selection
+        (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+        (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+        (setq addcurrent t wsboth t))
+      ;; maybe count current element
+      (when addcurrent
+        (setq count (if (> dir 0) (1- count) (1+ count))))
+      ;; enlarge selection
+      (goto-char (if (> dir 0) end beg))
+      (when (and (not addcurrent)
+                 (= count (forward-thing thing count)))
+        (error "No quoted string found"))
+      (if (> dir 0) (setq end (point)) (setq beg (point)))
+      ;; add whitespace
+      (cond
+       ((not inclusive) (setq beg (1+ beg) end (1- end)))
+       ((not (eq inclusive 'quote-only))
+        ;; try to add whitespace in forward direction
+        (goto-char (if (> dir 0) end beg))
+        (if (setq bnd (bounds-of-thing-at-point 'evil-space))
+            (if (> dir 0) (setq end (cdr bnd)) (setq beg (car bnd)))
+          ;; if not found try backward direction
+          (goto-char (if (> dir 0) beg end))
+          (if (and wsboth (setq bnd (bounds-of-thing-at-point 'evil-space)))
+              (if (> dir 0) (setq beg (car bnd)) (setq end (cdr bnd)))))))
+      (evil-range beg end
+                  ;; HACK: fixes #583
+                  ;; When not in visual state, an empty range is
+                  ;; possible. However, this cannot be achieved with
+                  ;; inclusive ranges, hence we use exclusive ranges
+                  ;; in this case. In visual state the range must be
+                  ;; inclusive because otherwise the selection would
+                  ;; be wrong.
+                  (if (evil-visual-state-p) 'inclusive 'exclusive)
+                  :expanded t))))
+
+(defun evil-select-quote (quote beg end type count &optional inclusive)
+  "Return a range (BEG END) of COUNT quoted text objects.
+QUOTE specifies the quotation delimiter. BEG END TYPE are the
+currently selected (visual) range.
+
+If INCLUSIVE is nil the previous selection is ignore. If there is
+quoted string at point this object will be selected, otherwise
+the following (if (> COUNT 0)) or preceeding object (if (< COUNT
+0)) is selected. If (/= (abs COUNT) 2) the delimiting quotes are not
+contained in the range, otherwise they are contained in the range.
+
+If INCLUSIVE is non-nil the selection depends on the previous
+selection. If the currently selection contains at least one
+character that is contained in a quoted string then the selection
+is extended, otherwise it is thrown away. If there is a
+non-selected object at point then this object is added to the
+selection. Otherwise the selection is extended to the
+following (if (> COUNT 0)) or preceeding object (if (< COUNT
+0)). Any whitespace following (or preceeding if (< COUNT 0)) the
+new selection is added to the selection. If no such whitespace
+exists and the selection contains only one quoted string then the
+preceeding (or following) whitespace is added to the range. "
+  (let ((evil-forward-quote-char quote))
+    (or (let ((bnd (or (bounds-of-thing-at-point 'evil-comment)
+                       (bounds-of-thing-at-point 'evil-string))))
+          (when (and bnd (< (point) (cdr bnd))
+                     (/= (char-after (car bnd)) quote)
+                     (/= (char-before (cdr bnd)) quote))
+            (evil-with-restriction (car bnd) (cdr bnd)
+              (condition-case nil
+                  (evil-select-quote-thing 'evil-quote-simple
+                                           beg end type
+                                           count
+                                           inclusive)
+                (error nil)))))
+        (let ((evil-forward-quote-char quote))
+          (evil-select-quote-thing 'evil-quote
+                                   beg end type
+                                   count
+                                   inclusive)))))
+
+(defun evil-select-xml-tag (beg end type &optional count inclusive)
+  "Return a range (BEG END) of COUNT matching XML tags.
+If INCLUSIVE is non-nil, the tags themselves are included
+from the range."
+  (cond
+   ((and (not inclusive) (= (abs (or count 1)) 1))
+    (let ((rng (evil-select-block #'evil-up-xml-tag beg end type count nil t)))
+      (if (or (and beg (= beg (evil-range-beginning rng))
+                   end (= end (evil-range-end rng)))
+              (= (evil-range-beginning rng) (evil-range-end rng)))
+          (evil-select-block #'evil-up-xml-tag beg end type count t)
+        rng)))
+   (t
+    (evil-select-block #'evil-up-xml-tag beg end type count inclusive))))
+
+(defun evil-expand-range (range &optional copy)
+  "Expand RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (unless (plist-get (evil-range-properties range) :expanded)
+    (setq range (evil-transform-range :expand range)))
+  range)
+
+(defun evil-contract-range (range &optional copy)
+  "Contract RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (evil-transform-range :contract range copy))
+
+(defun evil-normalize-range (range &optional copy)
+  "Normalize RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (evil-transform-range :normalize range copy))
+
+(defun evil-transform-range (transform range &optional copy)
+  "Apply TRANSFORM to RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (when (evil-type range)
+    (apply #'evil-set-range range
+           (apply #'evil-transform transform range)))
+  range)
+
+(defun evil-describe-range (range)
+  "Return description of RANGE.
+If no description is available, return the empty string."
+  (apply #'evil-describe range))
+
+;;; Undo
+
+(defun evil-start-undo-step (&optional continue)
+  "Start a undo step.
+All following buffer modifications are grouped together as a
+single action. If CONTINUE is non-nil, preceding modifications
+are included. The step is terminated with `evil-end-undo-step'."
+  (when (and (listp buffer-undo-list)
+             (not evil-in-single-undo))
+    (if evil-undo-list-pointer
+        (evil-refresh-undo-step)
+      (unless (or continue (null (car-safe buffer-undo-list)))
+        (undo-boundary))
+      (setq evil-undo-list-pointer (or buffer-undo-list t)))))
+
+(defun evil-end-undo-step (&optional continue)
+  "End a undo step started with `evil-start-undo-step'.
+Adds an undo boundary unless CONTINUE is specified."
+  (when (and evil-undo-list-pointer
+             (not evil-in-single-undo))
+    (evil-refresh-undo-step)
+    (unless (or continue (null (car-safe buffer-undo-list)))
+      (undo-boundary))
+    (setq evil-undo-list-pointer nil)))
+
+(defun evil-refresh-undo-step ()
+  "Refresh `buffer-undo-list' entries for current undo step.
+Undo boundaries until `evil-undo-list-pointer' are removed to
+make the entries undoable as a single action. See
+`evil-start-undo-step'."
+  (when evil-undo-list-pointer
+    (setq buffer-undo-list
+          (evil-filter-list #'null buffer-undo-list evil-undo-list-pointer))
+    (setq evil-undo-list-pointer (or buffer-undo-list t))))
+
+(defmacro evil-with-undo (&rest body)
+  "Execute BODY with enabled undo.
+If undo is disabled in the current buffer, the undo information
+is stored in `evil-temporary-undo' instead of `buffer-undo-list'."
+  (declare (indent defun)
+           (debug t))
+  `(unwind-protect
+       (let (buffer-undo-list)
+         (prog1
+             (progn ,@body)
+           (setq evil-temporary-undo buffer-undo-list)
+           ;; ensure evil-temporary-undo starts with exactly one undo
+           ;; boundary marker, i.e. nil
+           (unless (null (car-safe evil-temporary-undo))
+             (push nil evil-temporary-undo))))
+     (unless (eq buffer-undo-list t)
+       ;; undo is enabled, so update the global buffer undo list
+       (setq buffer-undo-list
+             ;; prepend new undos (if there are any)
+             (if (cdr evil-temporary-undo)
+                 (nconc evil-temporary-undo buffer-undo-list)
+               buffer-undo-list)
+             evil-temporary-undo nil))))
+
+(defmacro evil-with-single-undo (&rest body)
+  "Execute BODY as a single undo step."
+  (declare (indent defun)
+           (debug t))
+  `(let (evil-undo-list-pointer)
+     (evil-with-undo
+       (unwind-protect
+           (progn
+             (evil-start-undo-step)
+             (let ((evil-in-single-undo t))
+               ,@body))
+         (evil-end-undo-step)))))
+
+(defun evil-undo-pop ()
+  "Undo the last buffer change.
+Removes the last undo information from `buffer-undo-list'.
+If undo is disabled in the current buffer, use the information
+in `evil-temporary-undo' instead."
+  (let ((paste-undo (list nil)))
+    (let ((undo-list (if (eq buffer-undo-list t)
+                         evil-temporary-undo
+                       buffer-undo-list)))
+      (when (or (not undo-list) (car undo-list))
+        (user-error "Can't undo previous change"))
+      (while (and undo-list (null (car undo-list)))
+        (pop undo-list)) ; remove nil
+      (while (and undo-list (car undo-list))
+        (push (pop undo-list) paste-undo))
+      (let ((buffer-undo-list (nreverse paste-undo)))
+        (evil-save-echo-area
+          (undo)))
+      (if (eq buffer-undo-list t)
+          (setq evil-temporary-undo nil)
+        (setq buffer-undo-list undo-list)))))
+
+;;; Search
+(defun evil-transform-regexp (regexp replacements-alist)
+  (let ((pos 0) result)
+    (replace-regexp-in-string
+     "\\\\+[^\\\\]"
+     #'(lambda (txt)
+         (let* ((b (match-beginning 0))
+                (e (match-end 0))
+                (ch (aref txt (1- e)))
+                (repl (assoc ch replacements-alist)))
+           (if (and repl (zerop (mod (length txt) 2)))
+               (concat (substring txt b (- e 2))
+                       (cdr repl))
+             txt)))
+     regexp nil t)))
+
+(defun evil-transform-magic (str magic quote transform &optional start)
+  "Transforms STR with magic characters.
+MAGIC is a regexp that matches all potential magic
+characters. Each occurence of CHAR as magic character within str
+is replaced by the result of calling the associated TRANSFORM
+function. TRANSFORM is a function taking two arguments, the
+character to be transformed and the rest of string after the
+character. The function should return a triple (REPLACEMENT REST
+. STOP) where REPLACEMENT is the replacement and REST is the rest
+of the string that has not been transformed. If STOP is non-nil
+then the substitution stops immediately.  The replacement starts
+at position START, everything before that position is returned
+literally.  The result is a pair (RESULT . REST). RESULT is a
+list containing the transformed parts in order. If two
+subsequents parts are both strings, they are concatenated. REST
+is the untransformed rest string (usually \"\" but may be more if
+TRANSFORM stopped the substitution). Which characters are
+considered as magic characters (i.e. the transformation happens
+if the character is NOT preceeded by a backslash) is determined
+by `evil-magic'. The special tokens \\v, \\V, \\m and \\M have
+always a special meaning (like in Vim) and should not be
+contained in TRANSFORMS, otherwise their meaning is overwritten.
+
+The parameter QUOTE is a quoting function applied to literal
+transformations, usually `regexp-quote' or `replace-quote'."
+  (save-match-data
+    (let ((regexp (concat "\\(?:\\`\\|[^\\]\\)\\(\\\\\\(?:\\(" magic "\\)\\|\\(.\\)\\)\\|\\(" magic "\\)\\)"))
+          (magic-chars (evil-get-magic evil-magic))
+          (evil-magic evil-magic)
+          (quote (or quote #'identity))
+          result stop)
+      (while (and (not stop) str (string-match regexp str))
+        (unless (zerop (match-beginning 1))
+          (push (substring str 0 (match-beginning 1)) result))
+        (let ((char (or (match-string 2 str)
+                        (match-string 3 str)
+                        (match-string 4 str)))
+              (rest (substring str (match-end 0))))
+          (cond
+           ((match-beginning 4)
+            ;; magic character without backslash
+            (if (string-match magic-chars char)
+                ;; magic, do transform
+                (let ((trans (funcall transform (aref char 0) rest)))
+                  (push (car trans) result)
+                  (setq str (cadr trans) stop (nthcdr 2 trans)))
+              ;; non-magic, literal transformation
+              (push (funcall quote char) result)
+              (setq str rest)))
+           ((match-beginning 2)
+            ;; magic character with backslash
+            (if (not (string-match magic-chars char))
+                ;; non-magic, do transform
+                (let ((trans (funcall transform (aref char 0) rest)))
+                  (push (car trans) result)
+                  (setq str (cadr trans) stop (nthcdr 2 trans)))
+              ;; magic, literal transformation
+              (push (funcall quote char) result)
+              (setq str rest)))
+           ((memq (aref char 0) '(?m ?M ?v ?V))
+            (setq evil-magic (cdr (assq (aref char 0)
+                                        '((?m . t)
+                                          (?M . nil)
+                                          (?v . very-magic)
+                                          (?V . very-nomagic)))))
+            (setq magic-chars (evil-get-magic evil-magic))
+            (setq str rest))
+           (t
+            ;; non-magic char with backslash, literal transformation
+            (push (funcall quote char) result)
+            (setq str rest)))))
+      (cond
+       ((and str (not stop))
+        (push str result)
+        (setq str ""))
+       ((not str)
+        (setq str "")))
+      ;; concatenate subsequent strings
+      ;; note that result is in reverse order
+      (let (repl)
+        (while result
+          (cond
+           ((and (stringp (car result))
+                 (zerop (length (car result))))
+            (pop result))
+           ((and (stringp (car result))
+                 (stringp (cadr result)))
+            (setq result (cons (concat (cadr result)
+                                       (car result))
+                               (nthcdr 2 result))))
+           (t
+            (push (pop result) repl))))
+        (cons repl str)))))
+
+(defconst evil-vim-regexp-replacements
+  '((?n . "\n")           (?r . "\r")
+    (?t . "\t")           (?b . "\b")
+    (?s . "[[:space:]]")  (?S . "[^[:space:]]")
+    (?d . "[[:digit:]]")  (?D . "[^[:digit:]]")
+    (?x . "[[:xdigit:]]") (?X . "[^[:xdigit:]]")
+    (?o . "[0-7]")        (?O . "[^0-7]")
+    (?a . "[[:alpha:]]")  (?A . "[^[:alpha:]]")
+    (?l . "[a-z]")        (?L . "[^a-z]")
+    (?u . "[A-Z]")        (?U . "[^A-Z]")
+    (?y . "\\s")          (?Y . "\\S")
+    (?( . "\\(")          (?) . "\\)")
+    (?{ . "\\{")          (?} . "\\}")
+    (?[ . "[")            (?] . "]")
+    (?< . "\\<")          (?> . "\\>")
+    (?_ . "\\_")
+    (?* . "*")            (?+ . "+")
+    (?? . "?")            (?= . "?")
+    (?. . ".")
+    (?` . "`")            (?^ . "^")
+    (?$ . "$")            (?| . "\\|")))
+
+(defconst evil-regexp-magic "[][(){}<>_dDsSxXoOaAlLuUwWyY.*+?=^$`|nrtb]")
+
+(defun evil-transform-vim-style-regexp (regexp)
+  "Transforms vim-style backslash codes to Emacs regexp.
+This includes the backslash codes \\d, \\D, \\s, \\S, \\x, \\X,
+\\o, \\O, \\a, \\A, \\l, \\L, \\u, \\U and \\w, \\W. The new
+codes \\y and \\Y can be used instead of the Emacs code \\s and
+\\S which have a different meaning in Vim-style."
+  (car
+   (car
+    (evil-transform-magic
+     regexp evil-regexp-magic #'regexp-quote
+     #'(lambda (char rest)
+         (let ((repl (assoc char evil-vim-regexp-replacements)))
+           (if repl
+               (list (cdr repl) rest)
+             (list (concat "\\" (char-to-string char)) rest))))))))
+
+;;; Substitute
+
+(defun evil-downcase-first (str)
+  "Return STR with the first letter downcased."
+  (if (zerop (length str))
+      str
+    (concat (downcase (substring str 0 1))
+            (substring str 1))))
+
+(defun evil-upcase-first (str)
+  "Return STR with the first letter upcased."
+  (if (zerop (length str))
+      str
+    (concat (upcase (substring str 0 1))
+            (substring str 1))))
+
+(defun evil-get-magic (magic)
+  "Returns a regexp matching the magic characters according to MAGIC.
+Depending on the value of MAGIC the following characters are
+considered magic.
+  t             [][{}*+?.&~$^
+  nil           [][{}*+?$^
+  'very-magic   not 0-9A-Za-z_
+  'very-nomagic empty."
+  (cond
+   ((eq magic t) "[][}{*+?.&~$^]")
+   ((eq magic 'very-magic) "[^0-9A-Za-z_]")
+   ((eq magic 'very-nomagic) "\\\\")
+   (t "[][}{*+?$^]")))
+
+;; TODO: support magic characters in patterns
+(defconst evil-replacement-magic "[eElLuU0-9&#,rnbt=]"
+  "All magic characters in a replacement string")
+
+(defun evil-compile-subreplacement (to &optional start)
+  "Convert a regexp replacement TO to Lisp from START until \\e or \\E.
+Returns a pair (RESULT . REST). RESULT is a list suitable for
+`perform-replace' if necessary, the original string if not.
+REST is the unparsed remainder of TO."
+  (let ((result
+         (evil-transform-magic
+          to evil-replacement-magic #'replace-quote
+          #'(lambda (char rest)
+              (cond
+               ((eq char ?#)
+                (list '(number-to-string replace-count) rest))
+               ((eq char ?r) (list "\r" rest))
+               ((eq char ?n) (list "\n" rest))
+               ((eq char ?b) (list "\b" rest))
+               ((eq char ?t) (list "\t" rest))
+               ((memq char '(?e ?E))
+                `("" ,rest . t))
+               ((memq char '(?l ?L ?u ?U))
+                (let ((result (evil-compile-subreplacement rest))
+                      (func (cdr (assoc char
+                                        '((?l . evil-downcase-first)
+                                          (?L . downcase)
+                                          (?u . evil-upcase-first)
+                                          (?U . upcase))))))
+                  (list `(,func
+                          (replace-quote
+                           (evil-match-substitute-replacement
+                            ,(car result)
+                            (not case-replace))))
+                        (cdr result))))
+               ((eq char ?=)
+                (when (or (zerop (length rest))
+                          (not (eq (aref rest 0) ?@)))
+                  (user-error "Expected @ after \\="))
+                (when (< (length rest) 2)
+                  (user-error "Expected register after \\=@"))
+                (list (evil-get-register (aref rest 1))
+                      (substring rest 2)))
+               ((eq char ?,)
+                (let* ((obj (read-from-string rest))
+                       (result `(replace-quote ,(car obj)))
+                       (end
+                        ;; swallow a space after a symbol
+                        (if (and (or (symbolp (car obj))
+                                     ;; swallow a space after 'foo,
+                                     ;; but not after (quote foo)
+                                     (and (eq (car-safe (car obj)) 'quote)
+                                          (not (= ?\( (aref rest 0)))))
+                                 (eq (string-match " " rest (cdr obj))
+                                     (cdr obj)))
+                            (1+ (cdr obj))
+                          (cdr obj))))
+                  (list result (substring rest end))))
+               ((eq char ?0)
+                (list "\\&" rest))
+               (t
+                (list (concat "\\" (char-to-string char)) rest))))
+          start)))
+    (let ((rest (cdr result))
+          (result (car result)))
+      (replace-match-string-symbols result)
+      (cons (if (cdr result)
+                (cons 'concat result)
+              (or (car result) ""))
+            rest))))
+
+(defun evil-compile-replacement (to)
+  "Maybe convert a regexp replacement TO to Lisp.
+Returns a list suitable for `perform-replace' if necessary, the
+original string if not. Currently the following magic characters
+in replacements are supported: 0-9&#lLuUrnbt,
+The magic character , (comma) start an Emacs-lisp expression."
+  (when (stringp to)
+    (save-match-data
+      (cons 'replace-eval-replacement
+            (car (evil-compile-subreplacement to))))))
+
+(defun evil-replace-match (replacement &optional fixedcase string)
+  "Replace text match by last search with REPLACEMENT.
+If REPLACEMENT is an expression it will be evaluated to compute
+the replacement text, otherwise the function behaves as
+`replace-match'."
+  (if (stringp replacement)
+      (replace-match replacement fixedcase nil string)
+    (replace-match (funcall (car replacement)
+                            (cdr replacement)
+                            0)
+                   fixedcase nil string)))
+
+(defun evil-match-substitute-replacement (replacement &optional fixedcase string)
+  "Return REPLACEMENT as it will be inserted by `evil-replace-match'."
+  (if (stringp replacement)
+      (match-substitute-replacement replacement fixedcase nil string)
+    (match-substitute-replacement (funcall (car replacement)
+                                           (cdr replacement)
+                                           0)
+                                  fixedcase nil string)))
+
+;;; Alignment
+
+(defun evil-justify-lines (beg end justify position)
+  "Justifes all lines in a range.
+BEG and END specify the range of those lines to be
+justified. JUSTIFY is either 'left, 'right or 'center according
+to the justification type. POSITION is the maximal text width for
+right and center justification or the column at which the lines
+should be left-aligned for left justification."
+  (let ((fill-column position)
+        adaptive-fill-mode fill-prefix)
+    (evil-with-restriction
+        (save-excursion
+          (goto-char beg)
+          (line-beginning-position))
+        (save-excursion
+          (goto-char end)
+          (if (bolp)
+              (line-end-position 0)
+            (line-end-position)))
+      (goto-char (point-min))
+      (while (progn
+               (if (eq justify 'left)
+                   (indent-line-to position)
+                 (when (re-search-forward "^[[:space:]]*" nil t)
+                   (delete-region (match-beginning 0)
+                                  (match-end 0)))
+                 (justify-current-line justify nil t))
+               (and (zerop (forward-line)) (bolp))))
+      (goto-char (point-min))
+      (back-to-indentation))))
+
+;;; View helper
+
+(defvar-local evil-list-view-select-action nil)
+(put 'evil-list-view-select-action 'permanent-local t)
+
+(define-derived-mode evil-list-view-mode tabulated-list-mode
+  "Evil List View"
+  (tabulated-list-init-header)
+  (tabulated-list-print))
+
+(defun evil-list-view-goto-entry ()
+  (interactive)
+  (when (and evil-list-view-select-action
+             (not (eobp)))
+    (let* ((line (line-number-at-pos (point)))
+           (entry (elt tabulated-list-entries (1- line))))
+      (funcall evil-list-view-select-action (nth 1 entry)))))
+
+(define-key evil-list-view-mode-map (kbd "q") #'kill-this-buffer)
+(define-key evil-list-view-mode-map [follow-link] nil) ;; allows mouse-1 to be activated
+(define-key evil-list-view-mode-map [mouse-1] #'evil-list-view-goto-entry)
+(define-key evil-list-view-mode-map [return] #'evil-list-view-goto-entry)
+
+(defmacro evil-with-view-list (&rest properties)
+  "Opens new list view buffer.
+
+PROPERTIES is a property-list which supports the following properties:
+
+:name           (required)   The name of the buffer.
+:mode-name      (required)   The name for the mode line.
+:format         (required)   The value for `tabulated-list-format'.
+:entries        (required)   The value for `tabulated-list-entries'.
+:select-action  (optional)   A function for row selection.
+                             It takes in a single parameter, which is the selected row's
+                             vector value that is passed into `:entries'.
+"
+  (declare (indent defun) (debug t))
+  `(let ((bufname (concat "*" ,(plist-get properties :name) "*"))
+         (inhibit-read-only t))
+     (and (get-buffer bufname)
+          (kill-buffer bufname))
+     (let ((buf (get-buffer-create bufname)))
+       (with-current-buffer buf
+         (setq tabulated-list-format ,(plist-get properties :format))
+         (setq tabulated-list-entries ,(plist-get properties :entries))
+         (setq evil-list-view-select-action ,(plist-get properties :select-action))
+         (evil-list-view-mode)
+         (setq mode-name ,(plist-get properties :mode-name))
+         (evil-motion-state))
+       (switch-to-buffer-other-window buf))))
+
+(provide 'evil-common)
+
+;;; evil-common.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-common.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-core.el
@@ -0,0 +1,1259 @@
+;;; evil-core.el --- Core functionality
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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/>.
+
+;;; Commentary:
+
+;; Evil is defined as a globalized minor mode, enabled with the toggle
+;; function `evil-mode'.  This in turn enables `evil-local-mode' in
+;; every buffer, which sets up the buffer's state.
+;;
+;; Each state has its own keymaps, and these keymaps have status as
+;; "emulation keymaps" with priority over regular keymaps.  Emacs
+;; maintains the following keymap hierarchy (highest priority first):
+;;
+;;     * Overriding keymaps/overlay keymaps...
+;;     * Emulation mode keymaps...
+;;       - Evil keymaps...
+;;     * Minor mode keymaps...
+;;     * Local keymap (`local-set-key')
+;;     * Global keymap (`global-set-key')
+;;
+;; Within this hierarchy, Evil arranges the keymaps for the current
+;; state as shown below:
+;;
+;;     * Intercept keymaps...
+;;     * Local state keymap
+;;     * Minor-mode keymaps...
+;;     * Auxiliary keymaps...
+;;     * Overriding keymaps...
+;;     * Global state keymap
+;;     * Keymaps for other states...
+;;
+;; These keymaps are listed in `evil-mode-map-alist', which is listed
+;; in `emulation-mode-map-alist'.
+;;
+;; Most of the key bindings for a state are stored in its global
+;; keymap, which has a name such as `evil-normal-state-map'. (See the
+;; file evil-maps.el, which contains all the default key bindings.) A
+;; state also has a local keymap (`evil-normal-state-local-map'),
+;; which may contain user customizations for the current buffer.
+;; Furthermore, any Emacs mode may be assigned state bindings of its
+;; own by passing the mode's keymap to the function `evil-define-key'
+;; or `evil-define-minor-mode-key'. The former uses a specific map to
+;; define the key in while the latter associates the key with a
+;; particular mode. These mode-specific bindings are ultimately stored
+;; in so-called auxiliary and minor-mode keymaps respectively, which
+;; are sandwiched between the local keymap and the global keymap.
+;; Finally, the state may also activate the keymaps of other states
+;; (e.g., Normal state inherits bindings from Motion state).
+;;
+;; For integration purposes, a regular Emacs keymap may be "elevated"
+;; to emulation status by passing it to `evil-make-intercept-map' or
+;; `evil-make-overriding-map'.  An "intercept" keymap has priority over
+;; all other Evil keymaps.  (Evil uses this facility when debugging and
+;; for handling the "ESC" key in the terminal.) More common is the
+;; "overriding" keymap, which only has priority over the global state
+;; keymap.  (This is useful for adapting key-heavy modes such as Dired,
+;; where all but a few keys should be left as-is and should not be
+;; shadowed by Evil's default bindings.)
+;;
+;; States are defined with the macro `evil-define-state', which
+;; creates a command for switching to the state.  This command,
+;; for example `evil-normal-state' for Normal state, performs
+;; the following tasks:
+;;
+;;     * Setting `evil-state' to the new state.
+;;     * Refreshing the keymaps in `evil-mode-map-alist'.
+;;     * Updating the mode line.
+;;       - Normal state depends on `evil-normal-state-tag'.
+;;     * Adjusting the cursor's appearance.
+;;       - Normal state depends on `evil-normal-state-cursor'.
+;;     * Displaying a message in the echo area.
+;;       - Normal state depends on `evil-normal-state-message'.
+;;     * Running hooks.
+;;       - Normal state runs `evil-normal-state-entry-hook' when
+;;         entering, and `evil-normal-state-exit-hook' when exiting.
+;;
+;; The various properties of a state can be accessed through their
+;; respective variables, or by passing a keyword and the state's name
+;; to the `evil-state-property' function.  Evil defines the states
+;; Normal state ("normal"), Insert state ("insert"), Visual state
+;; ("visual"), Replace state ("replace"), Operator-Pending state
+;; ("operator"), Motion state ("motion") and Emacs state ("emacs").
+
+(require 'evil-common)
+
+;;; Code:
+
+(declare-function evil-emacs-state-p "evil-states")
+(declare-function evil-ex-p "evil-ex")
+(defvar evil-mode-buffers)
+
+(define-minor-mode evil-local-mode
+  "Minor mode for setting up Evil in a single buffer."
+  :init-value nil
+  (cond
+   ((evil-disabled-buffer-p)
+    ;; Don't leave the mode variable on in buffers where evil disabled, because
+    ;; functions that check this variable will get an incorrect result (e.g.,
+    ;; evil-refresh-cursor).
+    (setq evil-local-mode nil))
+   (evil-local-mode
+    (setq emulation-mode-map-alists
+          (evil-concat-lists '(evil-mode-map-alist)
+                             emulation-mode-map-alists))
+    (evil-initialize-local-keymaps)
+    ;; restore the proper value of `major-mode' in Fundamental buffers
+    (when (eq major-mode 'turn-on-evil-mode)
+      (setq major-mode 'fundamental-mode))
+    ;; The initial state is usually setup by `evil-initialize' when
+    ;; the major-mode in a buffer changes. This preliminary
+    ;; initialization is only for the case when `evil-local-mode' is
+    ;; called directly for the first time in a buffer.
+    (unless evil-state (evil-initialize-state))
+    (add-hook 'input-method-activate-hook 'evil-activate-input-method t t)
+    (add-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t t)
+    (add-hook 'activate-mark-hook 'evil-visual-activate-hook nil t)
+    (add-hook 'pre-command-hook 'evil-repeat-pre-hook)
+    (add-hook 'post-command-hook 'evil-repeat-post-hook))
+   (t
+    (evil-refresh-mode-line)
+    (remove-hook 'activate-mark-hook 'evil-visual-activate-hook t)
+    (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
+    (remove-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t)
+    (evil-change-state nil))))
+
+;; Make the variable permanent local.  This is particular useful in
+;; conjunction with nXhtml/mumamo because mumamo does not touch these
+;; variables.
+(put 'evil-local-mode 'permanent-local t)
+
+(defun turn-on-evil-mode (&optional arg)
+  "Turn on Evil in the current buffer."
+  (interactive)
+  (evil-local-mode (or arg 1)))
+
+(defun turn-off-evil-mode (&optional arg)
+  "Turn off Evil in the current buffer."
+  (interactive)
+  (evil-local-mode (or arg -1)))
+
+;; The function `evil-initialize' should only be used to initialize
+;; `evil-local-mode' from the globalized minor-mode `evil-mode'. It is
+;; called whenever evil is enabled in a buffer for the first time or
+;; when evil is active and the major-mode of the buffer changes. In
+;; addition to enabling `evil-local-mode' it also sets the initial
+;; evil-state according to the major-mode.
+(defun evil-initialize ()
+  "Enable Evil in the current buffer, if appropriate.
+To enable Evil globally, do (evil-mode 1)."
+  ;; TODO: option for enabling vi keys in the minibuffer
+  (unless (minibufferp)
+    (evil-local-mode 1)
+    (evil-initialize-state)))
+
+;;;###autoload (autoload 'evil-mode "evil")
+(define-globalized-minor-mode evil-mode
+  evil-local-mode evil-initialize)
+
+;; No hooks are run in Fundamental buffers, so other measures are
+;; necessary to initialize Evil in these buffers. When Evil is
+;; enabled globally, the default value of `major-mode' is set to
+;; `turn-on-evil-mode', so that Evil is enabled in Fundamental
+;; buffers as well. Then, the buffer-local value of `major-mode' is
+;; changed back to `fundamental-mode'. (Since the `evil-mode' function
+;; is created by a macro, we use `defadvice' to augment it.)
+(defadvice evil-mode (after start-evil activate)
+  "Enable Evil in Fundamental mode."
+  (if evil-mode
+      (progn
+        (when (eq (default-value 'major-mode) 'fundamental-mode)
+          ;; changed back by `evil-local-mode'
+          (setq-default major-mode 'turn-on-evil-mode))
+        (ad-enable-regexp "^evil")
+        (ad-activate-regexp "^evil")
+        (with-no-warnings (evil-esc-mode 1)))
+    (when (eq (default-value 'major-mode) 'turn-on-evil-mode)
+      (setq-default major-mode 'fundamental-mode))
+    (ad-disable-regexp "^evil")
+    (ad-update-regexp "^evil")
+    (with-no-warnings (evil-esc-mode -1))))
+
+(defun evil-change-state (state &optional message)
+  "Change the state to STATE.
+If STATE is nil, disable all states."
+  (let ((func (evil-state-property (or state evil-state) :toggle)))
+    (when (and (functionp func)
+               (or message (not (eq state evil-state))))
+      (funcall func (if state (and message 1) -1)))))
+
+(defmacro evil-save-state (&rest body)
+  "Save the current state; execute BODY; restore the state."
+  (declare (indent defun)
+           (debug t))
+  `(let* ((evil-state evil-state)
+          (evil-previous-state evil-previous-state)
+          (evil-previous-state-alist (copy-tree evil-previous-state-alist))
+          (evil-next-state evil-next-state)
+          (old-state evil-state)
+          (inhibit-quit t)
+          (buf (current-buffer)))
+     (unwind-protect
+         (progn ,@body)
+       (when (buffer-live-p buf)
+         (with-current-buffer buf
+           (evil-change-state old-state))))))
+
+(defmacro evil-with-state (state &rest body)
+  "Change to STATE and execute BODY without refreshing the display.
+Restore the previous state afterwards."
+  (declare (indent defun)
+           (debug t))
+  `(evil-without-display
+     (evil-save-state
+       (evil-change-state ',state)
+       ,@body)))
+
+(defun evil-initializing-p (&optional buffer)
+  "Whether Evil is in the process of being initialized."
+  (memq (or buffer (current-buffer)) evil-mode-buffers))
+
+(defun evil-initialize-state (&optional state buffer)
+  "Set up the initial state for BUFFER.
+BUFFER defaults to the current buffer.
+Uses STATE if specified, or calls `evil-initial-state-for-buffer'.
+See also `evil-set-initial-state'."
+  (with-current-buffer (or buffer (current-buffer))
+    (if state (evil-change-state state)
+      (evil-change-to-initial-state buffer))))
+(put 'evil-initialize-state 'permanent-local-hook t)
+
+(defun evil-initial-state-for-buffer-name (&optional name default)
+  "Return the initial Evil state to use for a buffer with name NAME.
+Matches the name against the regular expressions in
+`evil-buffer-regexps'. If none matches, returns DEFAULT."
+  (let ((name (if (stringp name) name (buffer-name name)))
+        regexp state)
+    (when (stringp name)
+      (catch 'done
+        (dolist (entry evil-buffer-regexps default)
+          (setq regexp (car entry)
+                state (cdr entry))
+          (when (string-match regexp name)
+            (throw 'done state)))))))
+
+(defun evil-disabled-buffer-p (&optional buffer)
+  "Whether Evil should be disabled in BUFFER."
+  (null (evil-initial-state-for-buffer-name buffer 'undefined)))
+
+(defun evil-initial-state-for-buffer (&optional buffer default)
+  "Return the initial Evil state to use for BUFFER.
+BUFFER defaults to the current buffer. Returns DEFAULT
+if no initial state is associated with BUFFER.
+See also `evil-initial-state'."
+  (with-current-buffer (or buffer (current-buffer))
+    (or (evil-initial-state-for-buffer-name (buffer-name))
+        (catch 'done
+          (dolist (mode minor-mode-map-alist)
+            (setq mode (car-safe mode))
+            (when (and (boundp mode) (symbol-value mode))
+              (when (setq mode (evil-initial-state mode))
+                (throw 'done mode)))))
+        (evil-initial-state major-mode)
+        default)))
+
+(defun evil-initial-state (mode &optional default)
+  "Return the Evil state to use for MODE.
+Returns DEFAULT if no initial state is associated with MODE.
+The initial state for a mode can be set with
+`evil-set-initial-state'."
+  (let (state modes)
+    (catch 'done
+      (dolist (entry (evil-state-property t :modes) default)
+        (setq state (car entry)
+              modes (symbol-value (cdr entry)))
+        (when (memq mode modes)
+          (throw 'done state))))))
+
+(defun evil-set-initial-state (mode state)
+  "Set the initial state for MODE to STATE.
+This is the state the buffer comes up in."
+  (dolist (modes (evil-state-property t :modes))
+    (setq modes (cdr-safe modes))
+    (set modes (delq mode (symbol-value modes))))
+  (when state
+    (add-to-list (evil-state-property state :modes) mode)))
+
+(evil-define-command evil-change-to-initial-state
+  (&optional buffer message)
+  "Change the state of BUFFER to its initial state.
+This is the state the buffer came up in. If Evil is not activated
+then this function does nothing."
+  :keep-visual t
+  :suppress-operator t
+  (with-current-buffer (or buffer (current-buffer))
+    (when evil-local-mode
+      (evil-change-state (evil-initial-state-for-buffer
+                          buffer (or evil-default-state 'normal))
+                         message))))
+
+(evil-define-command evil-change-to-previous-state
+  (&optional buffer message)
+  "Change the state of BUFFER to its previous state."
+  :keep-visual t
+  :repeat abort
+  :suppress-operator t
+  (with-current-buffer (or buffer (current-buffer))
+    (let ((prev-state evil-previous-state)
+          (prev-prev-state (cdr-safe (assoc evil-previous-state
+                                            evil-previous-state-alist))))
+      (evil-change-state nil)
+      (when prev-prev-state
+        (setq evil-previous-state prev-prev-state))
+      (evil-change-state (or prev-state evil-default-state 'normal)
+                         message))))
+
+;; When a buffer is created in a low-level way, it is invisible to
+;; Evil (as well as other globalized minor modes) because no hooks are
+;; run. This is appropriate since many buffers are used for throwaway
+;; purposes. Passing the buffer to `set-window-buffer' indicates
+;; otherwise, though, so advise this function to initialize Evil.
+(defadvice set-window-buffer (before evil)
+  "Initialize Evil in the displayed buffer."
+  (when evil-mode
+    (when (get-buffer (ad-get-arg 1))
+      (with-current-buffer (ad-get-arg 1)
+        (unless evil-local-mode
+          (evil-local-mode 1))))))
+
+;; Refresh cursor color.
+;; Cursor color can only be set for each frame but not for each buffer.
+(add-hook 'window-configuration-change-hook 'evil-refresh-cursor)
+(defadvice select-window (after evil activate)
+  (evil-refresh-cursor))
+
+(defun evil-generate-mode-line-tag (&optional state)
+  "Generate the evil mode-line tag for STATE."
+  (let ((tag (evil-state-property state :tag t)))
+    ;; prepare mode-line: add tooltip
+    (if (stringp tag)
+        (propertize tag
+                    'help-echo (evil-state-property state :name)
+                    'mouse-face 'mode-line-highlight)
+      tag)))
+
+(defun evil-refresh-mode-line (&optional state)
+  "Refresh mode line tag."
+  (when (listp mode-line-format)
+    (setq evil-mode-line-tag (evil-generate-mode-line-tag state))
+    ;; refresh mode line data structure
+    ;; first remove evil from mode-line
+    (setq mode-line-format (delq 'evil-mode-line-tag mode-line-format))
+    (let ((mlpos mode-line-format)
+          pred which where)
+      ;; determine before/after which symbol the tag should be placed
+      (cond
+       ((eq evil-mode-line-format 'before)
+        (setq where 'after which 'mode-line-position))
+       ((eq evil-mode-line-format 'after)
+        (setq where 'after which 'mode-line-modes))
+       ((consp evil-mode-line-format)
+        (setq where (car evil-mode-line-format)
+              which (cdr evil-mode-line-format))))
+      ;; find the cons-cell of the symbol before/after which the tag
+      ;; should be placed
+      (while (and mlpos
+                  (let ((sym (or (car-safe (car mlpos)) (car mlpos))))
+                    (not (eq which sym))))
+        (setq pred mlpos
+              mlpos (cdr mlpos)))
+      ;; put evil tag at the right position in the mode line
+      (cond
+       ((not mlpos)) ;; position not found, so do not add the tag
+       ((eq where 'before)
+        (if pred
+            (setcdr pred (cons 'evil-mode-line-tag mlpos))
+          (setq mode-line-format
+                (cons 'evil-mode-line-tag mode-line-format))))
+       ((eq where 'after)
+        (setcdr mlpos (cons 'evil-mode-line-tag (cdr mlpos)))))
+      (force-mode-line-update))))
+
+;; input methods should be disabled in non-insertion states
+(defun evil-activate-input-method ()
+  "Enable input method in states with :input-method non-nil."
+  (let (input-method-activate-hook
+        input-method-deactivate-hook)
+    (when (and evil-local-mode evil-state)
+      (setq evil-input-method current-input-method)
+      (unless (evil-state-property evil-state :input-method)
+        (deactivate-input-method)))))
+(put 'evil-activate-input-method 'permanent-local-hook t)
+
+(defun evil-deactivate-input-method ()
+  "Disable input method in all states."
+  (let (input-method-activate-hook
+        input-method-deactivate-hook)
+    (when (and evil-local-mode evil-state)
+      (setq evil-input-method nil))))
+(put 'evil-deactivate-input-method 'permanent-local-hook t)
+
+(defmacro evil-without-input-method-hooks (&rest body)
+  "Execute body with evil's activate/deactivate-input-method hooks deactivated.
+
+This allows input methods to be used in normal-state."
+  `(unwind-protect
+       (progn
+         (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
+         (remove-hook 'input-method-deactivate-hook
+                      'evil-deactivate-input-method t)
+         ,@body)
+     (progn
+       (add-hook 'input-method-activate-hook 'evil-activate-input-method nil t)
+       (add-hook 'input-method-deactivate-hook
+                 'evil-deactivate-input-method nil t))))
+
+(defadvice toggle-input-method (around evil)
+  "Refresh `evil-input-method'."
+  (cond
+   ((not evil-local-mode)
+    ad-do-it)
+   ((evil-state-property evil-state :input-method)
+    ad-do-it)
+   (t
+    (let ((current-input-method evil-input-method))
+      ad-do-it))))
+
+;; Local keymaps are implemented using buffer-local variables.
+;; However, unless a buffer-local value already exists,
+;; `define-key' acts on the variable's default (global) value.
+;; So we need to initialize the variable whenever we enter a
+;; new buffer or when the buffer-local values are reset.
+(defun evil-initialize-local-keymaps ()
+  "Initialize a buffer-local value for local keymaps as necessary.
+The initial value is that of `make-sparse-keymap'."
+  (dolist (entry evil-local-keymaps-alist)
+    (let ((mode (car entry))
+          (map  (cdr entry)))
+      (unless (and (keymapp (symbol-value map))
+                   (assq map (buffer-local-variables)))
+        (set map (make-sparse-keymap))))))
+
+(defun evil-make-overriding-map (keymap &optional state copy)
+  "Give KEYMAP precedence over the global keymap of STATE.
+The keymap will have lower precedence than custom STATE bindings.
+If STATE is nil, give it precedence over all states.
+If COPY is t, create a copy of KEYMAP and give that
+higher precedence. See also `evil-make-intercept-map'."
+  (let ((key [override-state]))
+    (if (not copy)
+        (define-key keymap key (or state 'all))
+      (unless (keymapp copy)
+        (setq copy (assq-delete-all 'menu-bar (copy-keymap keymap))))
+      (define-key copy key (or state 'all))
+      (define-key keymap key copy))))
+
+(defun evil-make-intercept-map (keymap &optional state)
+  "Give KEYMAP precedence over all Evil keymaps in STATE.
+If STATE is nil, give it precedence over all states.
+See also `evil-make-overriding-map'."
+  (let ((key [intercept-state]))
+    (define-key keymap key (or state 'all))))
+
+(defmacro evil-define-keymap (keymap doc &rest body)
+  "Define a keymap KEYMAP listed in `evil-mode-map-alist'.
+That means it will have precedence over regular keymaps.
+
+DOC is the documentation for the variable. BODY, if specified,
+is executed after toggling the mode. Optional keyword arguments
+may be specified before the body code:
+
+:mode VAR       Mode variable. If unspecified, the variable
+                is based on the keymap name.
+:local BOOLEAN  Whether the keymap should be buffer-local, that is,
+                reinitialized for each buffer.
+:func BOOLEAN   Create a toggle function even if BODY is empty.
+
+\(fn KEYMAP DOC [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp sexp]]
+                           def-body)))
+  (let ((func t)
+        arg intercept key local mode overriding)
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :mode)
+        (setq mode arg))
+       ((eq key :local)
+        (setq local arg))
+       ((eq key :func)
+        (setq func arg))
+       ((eq key :intercept)
+        (setq intercept arg))
+       ((eq key :overriding)
+        (setq overriding arg))))
+    (setq mode (or mode
+                   (intern (replace-regexp-in-string
+                            "\\(?:-\\(?:mode-\\)?\\(?:key\\)?map\\)?$"
+                            "-mode"
+                            (symbol-name keymap)))))
+    `(progn
+       (defvar ,keymap ,(unless local '(make-sparse-keymap)))
+       (unless (get ',keymap 'variable-documentation)
+         (put ',keymap 'variable-documentation ,doc))
+       (defvar ,mode nil)
+       (unless (get ',mode 'variable-documentation)
+         (put ',mode 'variable-documentation ,doc))
+       (make-variable-buffer-local ',mode)
+       (put ',mode 'permanent-local t)
+       (when ,intercept
+         (evil-make-intercept-map ,keymap))
+       (when ,overriding
+         (evil-make-overriding-map ,keymap))
+       ,@(if local
+             `((make-variable-buffer-local ',keymap)
+               (put ',keymap 'permanent-local t)
+               (evil-add-to-alist 'evil-local-keymaps-alist
+                                  ',mode ',keymap))
+           `((evil-add-to-alist 'evil-global-keymaps-alist
+                                ',mode ',keymap)
+             (evil-add-to-alist 'evil-mode-map-alist
+                                ',mode ,keymap)))
+       ,(when (or body func)
+          `(defun ,mode (&optional arg)
+             ,@(when doc `(,doc))
+             (interactive)
+             (cond
+              ((numberp arg)
+               (setq ,mode (> arg 0)))
+              (t
+               (setq ,mode (not ,mode))))
+             ,@body))
+       ',keymap)))
+
+;; The ESC -> escape translation code has been provided by Stefan
+;; Monnier in the discussion of GNU Emacs bug #13793.
+(defun evil-esc-mode (&optional arg)
+  "Toggle interception of \\e (escape).
+Enable with positive ARG and disable with negative ARG.
+
+When enabled, `evil-esc-mode' modifies the entry of \\e in
+`input-decode-map'. If such an event arrives, it is translated to
+a plain 'escape event if no further event occurs within
+`evil-esc-delay' seconds. Otherwise no translation happens and
+the ESC prefix map (i.e. the map originally bound to \\e in
+`input-decode-map`) is returned."
+  (cond
+   ((or (null arg) (eq arg 0))
+    (evil-esc-mode (if evil-esc-mode -1 +1)))
+   ((> arg 0)
+    (unless evil-esc-mode
+      (setq evil-esc-mode t)
+      (add-hook 'after-make-frame-functions #'evil-init-esc)
+      (mapc #'evil-init-esc (frame-list))))
+   ((< arg 0)
+    (when evil-esc-mode
+      (remove-hook 'after-make-frame-functions #'evil-init-esc)
+      (mapc #'evil-deinit-esc (frame-list))
+      (setq evil-esc-mode nil)))))
+
+(defun evil-init-esc (frame)
+  "Update `input-decode-map' in terminal."
+  (with-selected-frame frame
+    (let ((term (frame-terminal frame)))
+      (when (and
+             (or (eq evil-intercept-esc 'always)
+                 (and evil-intercept-esc
+                      (eq (terminal-live-p term) t))) ; only patch tty
+             (not (terminal-parameter term 'evil-esc-map)))
+        (let ((evil-esc-map (lookup-key input-decode-map [?\e])))
+          (set-terminal-parameter term 'evil-esc-map evil-esc-map)
+          (define-key input-decode-map [?\e]
+            `(menu-item "" ,evil-esc-map :filter ,#'evil-esc)))))))
+
+(defun evil-deinit-esc (frame)
+  "Restore `input-decode-map' in terminal."
+  (with-selected-frame frame
+    (let ((term (frame-terminal frame)))
+      (when (terminal-live-p term)
+        (let ((evil-esc-map (terminal-parameter term 'evil-esc-map)))
+          (when evil-esc-map
+            (define-key input-decode-map [?\e] evil-esc-map)
+            (set-terminal-parameter term 'evil-esc-map nil)))))))
+
+(defun evil-esc (map)
+  "Translate \\e to 'escape if no further event arrives.
+This function is used to translate a \\e event either to 'escape
+or to the standard ESC prefix translation map. If \\e arrives,
+this function waits for `evil-esc-delay' seconds for another
+event. If no other event arrives, the event is translated to
+'escape, otherwise it is translated to the standard ESC prefix
+map stored in `input-decode-map'. If `evil-inhibit-esc' is
+non-nil or if evil is in emacs state, the event is always
+translated to the ESC prefix.
+
+The translation to 'escape happens only if the current command
+has indeed been triggered by \\e. In other words, this will only
+happen when the keymap is accessed from `read-key-sequence'. In
+particular, if it is access from `define-key' the returned
+mapping will always be the ESC prefix map."
+  (if (and (not evil-inhibit-esc)
+           (or evil-local-mode (evil-ex-p)
+               (active-minibuffer-window))
+           (not (evil-emacs-state-p))
+           (let ((keys (this-single-command-keys)))
+             (and (> (length keys) 0)
+                  (= (aref keys (1- (length keys))) ?\e)))
+           (sit-for evil-esc-delay))
+      (prog1 [escape]
+        (when defining-kbd-macro
+          (end-kbd-macro)
+          (setq last-kbd-macro (vconcat last-kbd-macro [escape]))
+          (start-kbd-macro t t)))
+    map))
+
+(defun evil-state-p (sym)
+  "Whether SYM is the name of a state."
+  (assq sym evil-state-properties))
+
+(defun evil-state-keymaps (state &rest excluded)
+  "Return a keymap alist of keymaps activated by STATE.
+If STATE references other states in its :enable property,
+these states are recursively processed and added to the list.
+\(The EXCLUDED argument is an internal safeguard against
+infinite recursion, keeping track of processed states.)"
+  (let* ((state (or state evil-state))
+         (enable (evil-state-property state :enable))
+         (map (cons
+               (evil-state-property state :mode)
+               (evil-state-property state :keymap t)))
+         (local-map (cons
+                     (evil-state-property state :local)
+                     (evil-state-property state :local-keymap t)))
+         (minor-mode-maps (evil-state-minor-mode-keymaps state))
+         (aux-maps (evil-state-auxiliary-keymaps state))
+         (overriding-maps
+          (evil-state-overriding-keymaps state))
+         (intercept-maps
+          (evil-state-intercept-keymaps state))
+         (result `(,intercept-maps))
+         (remove-duplicates (null excluded)))
+    (unless (memq state enable)
+      (setq enable (cons state enable)))
+    ;; process STATE's :enable property
+    (dolist (entry enable)
+      (cond
+       ((memq entry excluded))
+       ;; the keymaps for STATE
+       ((eq entry state)
+        (setq result `(,@result
+                       (,local-map)
+                       ,minor-mode-maps
+                       ,aux-maps
+                       ,overriding-maps
+                       (,map)))
+        (push state excluded))
+       ;; the keymaps for another state: call `evil-state-keymaps'
+       ;; recursively, but keep track of processed states
+       ((evil-state-p entry)
+        (setq result `(,@result
+                       ,(apply #'evil-state-keymaps entry excluded))))
+       ;; a single keymap
+       ((or (keymapp entry)
+            (and (keymapp (symbol-value entry))
+                 (setq entry (symbol-value entry)))
+            (setq entry (evil-keymap-for-mode entry)))
+        (setq result `(,@result
+                       ((,(evil-mode-for-keymap entry t) .
+                         ,entry)))))))
+    ;; postpone the expensive filtering of duplicates to the top level
+    (if remove-duplicates
+        (apply #'evil-concat-keymap-alists result)
+      (apply #'append result))))
+
+(defun evil-normalize-keymaps (&optional state)
+  "Create a buffer-local value for `evil-mode-map-alist'.
+This is a keymap alist, determined by the current state
+\(or by STATE if specified)."
+  (let ((state (or state evil-state))
+        (excluded '(nil t))
+        map mode temp)
+    ;; initialize buffer-local keymaps as necessary
+    (evil-initialize-local-keymaps)
+    ;; deactivate keymaps of previous state
+    (dolist (entry evil-mode-map-alist)
+      (setq mode (car-safe entry)
+            map (cdr-safe entry))
+      ;; don't deactivate overriding keymaps;
+      ;; they are toggled by their associated mode
+      (if (or (memq mode excluded)
+              (evil-intercept-keymap-p map)
+              (evil-overriding-keymap-p map)
+              (evil-auxiliary-keymap-p map)
+              (evil-minor-mode-keymap-p map))
+          (push mode excluded)
+        (when (and (fboundp mode) (symbol-value mode))
+          (funcall mode -1))
+        (set mode nil)))
+    (setq evil-mode-map-alist nil)
+    ;; activate keymaps of current state
+    (when state
+      (setq temp (evil-state-keymaps state))
+      (dolist (entry temp)
+        (setq mode (car entry)
+              map (cdr entry))
+        (unless (or (and (boundp mode) (symbol-value mode))
+                    ;; the minor-mode keymaps include modes that are not
+                    ;; necessarily active
+                    (evil-minor-mode-keymap-p map))
+          (when (fboundp mode)
+            (funcall mode 1))
+          (set mode t))
+        ;; refresh the keymap in case it has changed
+        ;; (e.g., `evil-operator-shortcut-map' is
+        ;; reset on toggling)
+        (if (or (memq mode excluded)
+                (evil-intercept-keymap-p map)
+                (evil-overriding-keymap-p map)
+                (evil-auxiliary-keymap-p map)
+                (evil-minor-mode-keymap-p map))
+            (push mode excluded)
+          (setcdr entry (or (evil-keymap-for-mode mode) map))))
+      ;; update `evil-mode-map-alist'
+      (setq evil-mode-map-alist temp))))
+
+(defun evil-mode-for-keymap (keymap &optional default)
+  "Return the minor mode associated with KEYMAP.
+Returns DEFAULT if no mode is found.
+See also `evil-keymap-for-mode'."
+  (let ((map (if (keymapp keymap) keymap (symbol-value keymap)))
+        (var (when (symbolp keymap) keymap)))
+    ;; Check Evil variables first for speed purposes.
+    ;; If all else fails, check `minor-mode-map-alist'.
+    (or (when var
+          (or (car (rassq var evil-global-keymaps-alist))
+              (car (rassq var evil-local-keymaps-alist))))
+        (car (rassq map (mapcar #'(lambda (e)
+                                    ;; from (MODE-VAR . MAP-VAR)
+                                    ;; to (MODE-VAR . MAP)
+                                    (cons (car-safe e)
+                                          (symbol-value (cdr-safe e))))
+                                (append evil-global-keymaps-alist
+                                        evil-local-keymaps-alist))))
+        (car (rassq map minor-mode-map-alist))
+        default)))
+
+(defun evil-keymap-for-mode (mode &optional variable)
+  "Return the keymap associated with MODE.
+Return the keymap variable if VARIABLE is non-nil.
+See also `evil-mode-for-keymap'."
+  (let* ((var (or (cdr (assq mode evil-global-keymaps-alist))
+                  (cdr (assq mode evil-local-keymaps-alist))))
+         (map (or (symbol-value var)
+                  (cdr (assq mode minor-mode-map-alist)))))
+    (if variable var map)))
+
+(defun evil-state-auxiliary-keymaps (state)
+  "Return a keymap alist of auxiliary keymaps for STATE."
+  (let ((state (or state evil-state))
+        aux result)
+    (dolist (map (current-active-maps) result)
+      (when (setq aux (evil-get-auxiliary-keymap map state))
+        (push (cons (evil-mode-for-keymap map t) aux) result)))
+    (nreverse result)))
+
+(defun evil-state-minor-mode-keymaps (state)
+  "Return a keymap alist of minor-mode keymaps for STATE."
+  (let* ((state (or state evil-state))
+         (state-entry (assq state evil-minor-mode-keymaps-alist)))
+    (when state-entry
+      (cdr state-entry))))
+
+(defun evil-state-overriding-keymaps (&optional state)
+  "Return a keymap alist of overriding keymaps for STATE."
+  (let* ((state (or state evil-state))
+         result)
+    (dolist (map (current-active-maps))
+      (when (setq map (evil-overriding-keymap-p map state))
+        (push (cons (evil-mode-for-keymap map t) map) result)))
+    (nreverse result)))
+
+(defun evil-state-intercept-keymaps (&optional state)
+  "Return a keymap alist of intercept keymaps for STATE."
+  (let* ((state (or state evil-state))
+         result)
+    (dolist (map (current-active-maps))
+      (when (setq map (evil-intercept-keymap-p map state))
+        (push (cons (evil-mode-for-keymap map t) map) result)))
+    (setq result (nreverse result))
+    result))
+
+(defun evil-set-auxiliary-keymap (map state &optional aux)
+  "Set the auxiliary keymap for MAP in STATE to AUX.
+If AUX is nil, create a new auxiliary keymap."
+  (unless (keymapp aux)
+    (setq aux (make-sparse-keymap)))
+  (unless (evil-auxiliary-keymap-p aux)
+    (evil-set-keymap-prompt
+     aux (format "Auxiliary keymap for %s"
+                 (or (evil-state-property state :name)
+                     (format "%s state" state)))))
+  (define-key map
+    (vconcat (list (intern (format "%s-state" state)))) aux)
+  aux)
+(put 'evil-set-auxiliary-keymap 'lisp-indent-function 'defun)
+
+(defun evil-get-auxiliary-keymap (map state &optional create ignore-parent)
+  "Get the auxiliary keymap for MAP in STATE.
+If CREATE is non-nil, create an auxiliary keymap
+if MAP does not have one. If CREATE and
+IGNORE-PARENT are non-nil then a new auxiliary
+keymap is created even if the parent of MAP has
+one already."
+  (when state
+    (let* ((key (vconcat (list (intern (format "%s-state" state)))))
+           (parent-aux (when (and ignore-parent
+                                  (keymap-parent map)
+                                  state)
+                         (lookup-key (keymap-parent map) key)))
+           (aux (if state (lookup-key map key) map)))
+      (cond
+       ((and ignore-parent
+             (equal parent-aux aux)
+             create)
+        (evil-set-auxiliary-keymap map state))
+       ((evil-auxiliary-keymap-p aux)
+        aux)
+       (create
+        (evil-set-auxiliary-keymap map state))))))
+
+(defun evil-get-minor-mode-keymap (state mode)
+  "Get the auxiliary keymap for MODE in STATE, creating one if it
+does not already exist."
+  (let ((state-entry (assq state evil-minor-mode-keymaps-alist)))
+    (if (and state-entry
+             (assq mode state-entry))
+        (cdr (assq mode state-entry))
+      (let ((map (make-sparse-keymap)))
+        (evil-set-keymap-prompt
+         map (format "Minor-mode keymap for %s in %s"
+                     (symbol-name mode)
+                     (or (evil-state-property state :name)
+                         (format "%s state" state))))
+        (if state-entry
+            (setcdr state-entry
+                    (append (list (cons mode map)) (cdr state-entry)))
+          (push (cons state (list (cons mode map)))
+                evil-minor-mode-keymaps-alist))
+        map))))
+
+(defun evil-auxiliary-keymap-p (map)
+  "Whether MAP is an auxiliary keymap."
+  (and (keymapp map)
+       (string-match "Auxiliary keymap"
+                     (or (keymap-prompt map) "")) t))
+
+(defun evil-minor-mode-keymap-p (map)
+  "Whether MAP is a minor-mode keymap."
+  (and (keymapp map)
+       (string-match "Minor-mode keymap"
+                     (or (keymap-prompt map) "")) t))
+
+(defun evil-intercept-keymap-p (map &optional state)
+  "Whether MAP is an intercept keymap for STATE.
+If STATE is nil, it means any state."
+  (let ((entry (and (keymapp map)
+                    (lookup-key map [intercept-state]))))
+    (cond
+     ((null entry)
+      nil)
+     ((null state)
+      map)
+     ((eq entry state)
+      map)
+     ((eq entry 'all)
+      map))))
+
+(defun evil-overriding-keymap-p (map &optional state)
+  "Whether MAP is an overriding keymap for STATE.
+If STATE is nil, it means any state."
+  (let ((entry (and (keymapp map)
+                    (lookup-key map [override-state]))))
+    (cond
+     ((null entry)
+      nil)
+     ((keymapp entry)
+      (evil-overriding-keymap-p entry state))
+     ((null state)
+      map)
+     ((eq entry state)
+      map)
+     ((eq entry 'all)
+      map))))
+
+(defun evil-intercept-keymap-state (map)
+  "Return the state for the intercept keymap MAP.
+A return value of t means all states."
+  (let ((state (lookup-key map [intercept-state] map)))
+    (cond
+     ((keymapp state)
+      (evil-intercept-keymap-state state))
+     ((eq state 'all)
+      t)
+     (t
+      state))))
+
+(defun evil-overriding-keymap-state (map)
+  "Return the state for the overriding keymap MAP.
+A return value of t means all states."
+  (let ((state (lookup-key map [override-state] map)))
+    (cond
+     ((keymapp state)
+      (evil-overriding-keymap-state state))
+     ((eq state 'all)
+      t)
+     (t
+      state))))
+
+(defmacro evil-define-key (state keymap key def &rest bindings)
+  "Create a STATE binding from KEY to DEF for KEYMAP.
+STATE is one of `normal', `insert', `visual', `replace',
+`operator', `motion', `emacs', or a list of one or more of
+these. The remaining arguments are like those of
+`define-key'. For example:
+
+    (evil-define-key 'normal foo-map \"a\" 'bar)
+
+This creates a binding from \"a\" to `bar' in Normal state,
+which is active whenever `foo-map' is active. It is possible
+to specify multiple bindings at once:
+
+    (evil-define-key 'normal foo-map
+      \"a\" 'bar
+      \"b\" 'foo)
+
+If foo-map has not been initialized yet, this macro adds an entry
+to `after-load-functions', delaying execution as necessary."
+  (declare (indent defun))
+  `(evil-delay ',(if (symbolp keymap)
+                     `(and (boundp ',keymap) (keymapp ,keymap))
+                   `(keymapp ,keymap))
+       '(evil-define-key* ,state ,keymap ,key ,def ,@bindings)
+     'after-load-functions t nil
+     (format "evil-define-key-in-%s"
+             ',(if (symbolp keymap) keymap 'keymap))))
+(defalias 'evil-declare-key 'evil-define-key)
+
+(defun evil-define-key* (state keymap key def &rest bindings)
+  "Create a STATE binding from KEY to DEF for KEYMAP.
+STATE is one of `normal', `insert', `visual', `replace',
+`operator', `motion', `emacs', or a list of one or more of these.
+
+The use is identical to `evil-define-key' with the exception that
+this is a function and not a macro (and so will not be expanded
+when compiled which can have unintended
+consequences). `evil-define-key*' also does not defer any
+bindings like `evil-define-key' does using `evil-delay'. This
+allows errors in the bindings to be caught immediately, and makes
+its behavior more predictable."
+  (let ((aux-maps
+         (cond ((listp state)
+                (mapcar
+                 (lambda (st)
+                   (evil-get-auxiliary-keymap keymap st t))
+                 state))
+               (state
+                (list (evil-get-auxiliary-keymap keymap state t)))
+               (t
+                (list keymap)))))
+    (while key
+      (dolist (map aux-maps)
+        (define-key map key def))
+      (setq key (pop bindings)
+            def (pop bindings)))
+    ;; ensure the prompt string comes first
+    (dolist (map aux-maps)
+      (evil-set-keymap-prompt map (keymap-prompt map)))))
+
+(defun evil-define-minor-mode-key (state mode key def &rest bindings)
+  "Similar to `evil-define-key' but the bindings are associated
+with the minor-mode symbol MODE instead of a particular map.
+Associating bindings with a mode symbol instead of a map allows
+evil to use Emacs' built-in mechanisms to enable the bindings
+automatically when MODE is active without relying on calling
+`evil-normalize-keymaps'. Another less significant difference is
+that the bindings can be created immediately, because this
+function only uses the symbol MODE and does not rely on its
+value.
+
+See `evil-define-key' for the usage of STATE, KEY, DEF and
+BINDINGS."
+  (declare (indent defun))
+  (let ((map (evil-get-minor-mode-keymap state mode)))
+    (while key
+      (define-key map key def)
+      (setq key (pop bindings)
+            def (pop bindings)))))
+
+(defmacro evil-add-hjkl-bindings (keymap &optional state &rest bindings)
+  "Add \"h\", \"j\", \"k\", \"l\" bindings to KEYMAP in STATE.
+Add additional BINDINGS if specified."
+  (declare (indent defun))
+  `(evil-define-key ,state ,keymap
+     "h" (lookup-key evil-motion-state-map "h")
+     "j" (lookup-key evil-motion-state-map "j")
+     "k" (lookup-key evil-motion-state-map "k")
+     "l" (lookup-key evil-motion-state-map "l")
+     ":" (lookup-key evil-motion-state-map ":")
+     ,@bindings))
+
+;; may be useful for programmatic purposes
+(defun evil-global-set-key (state key def)
+  "Bind KEY to DEF in STATE."
+  (define-key (evil-state-property state :keymap t) key def))
+
+(defun evil-local-set-key (state key def)
+  "Bind KEY to DEF in STATE in the current buffer."
+  (define-key (evil-state-property state :local-keymap t) key def))
+
+;; Advise these functions as they may activate an overriding keymap or
+;; a keymap with state bindings; if so, refresh `evil-mode-map-alist'.
+(defadvice use-global-map (after evil activate)
+  "Refresh Evil keymaps."
+  (evil-normalize-keymaps))
+
+(defadvice use-local-map (after evil activate)
+  "Refresh Evil keymaps."
+  (evil-normalize-keymaps))
+
+(defmacro evil-define-state (state doc &rest body)
+  "Define an Evil state STATE.
+DOC is a general description and shows up in all docstrings;
+the first line of the string should be the full name of the state.
+Then follows one or more optional keywords:
+
+:tag STRING             Mode line indicator.
+:message STRING         Echo area message when changing to STATE.
+:cursor SPEC            Cursor to use in STATE.
+:entry-hook LIST        Hooks run when changing to STATE.
+:exit-hook LIST         Hooks run when changing from STATE.
+:enable LIST            List of other states and modes enabled by STATE.
+:suppress-keymap FLAG   If FLAG is non-nil, makes `evil-suppress-map'
+                        the parent of the global map of STATE,
+                        effectively disabling bindings to
+                        `self-insert-command'.
+
+Following the keywords is optional code to be executed each time
+the state is enabled or disabled. For example:
+
+    (evil-define-state test
+      \"Test state.\"
+      :tag \"<T> \"
+      (setq test-var t))
+
+The global keymap of this state will be `evil-test-state-map',
+the local keymap will be `evil-test-state-local-map', and so on.
+
+\(fn STATE DOC [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp sexp]]
+                           def-body)))
+  (let* ((name (and (string-match "^\\(.+\\)\\(\\(?:.\\|\n\\)*\\)" doc)
+                    (match-string 1 doc)))
+         (doc (match-string 2 doc))
+         (name (and (string-match "^\\(.+?\\)\\.?$" name)
+                    (match-string 1 name)))
+         (doc (if (or (null doc) (string= doc "")) ""
+                (format "\n%s" doc)))
+         (toggle (intern (format "evil-%s-state" state)))
+         (mode (intern (format "%s-minor-mode" toggle)))
+         (keymap (intern (format "%s-map" toggle)))
+         (local (intern (format "%s-local-minor-mode" toggle)))
+         (local-keymap (intern (format "%s-local-map" toggle)))
+         (tag (intern (format "%s-tag" toggle)))
+         (message (intern (format "%s-message" toggle)))
+         (cursor (intern (format "%s-cursor" toggle)))
+         (entry-hook (intern (format "%s-entry-hook" toggle)))
+         (exit-hook (intern (format "%s-exit-hook" toggle)))
+         (modes (intern (format "%s-modes" toggle)))
+         (predicate (intern (format "%s-p" toggle)))
+         arg cursor-value enable entry-hook-value exit-hook-value
+         input-method key message-value suppress-keymap tag-value)
+    ;; collect keywords
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :tag)
+        (setq tag-value arg))
+       ((eq key :message)
+        (setq message-value arg))
+       ((eq key :cursor)
+        (setq cursor-value arg))
+       ((eq key :entry-hook)
+        (setq entry-hook-value arg)
+        (unless (listp entry-hook-value)
+          (setq entry-hook-value (list entry-hook-value))))
+       ((eq key :exit-hook)
+        (setq exit-hook-value arg)
+        (unless (listp exit-hook-value)
+          (setq exit-hook-value (list entry-hook-value))))
+       ((eq key :enable)
+        (setq enable arg))
+       ((eq key :input-method)
+        (setq input-method arg))
+       ((eq key :suppress-keymap)
+        (setq suppress-keymap arg))))
+
+    ;; macro expansion
+    `(progn
+       ;; Save the state's properties in `evil-state-properties' for
+       ;; runtime lookup. Among other things, this information is used
+       ;; to determine what keymaps should be activated by the state
+       ;; (and, when processing :enable, what keymaps are activated by
+       ;; other states). We cannot know this at compile time because
+       ;; it depends on the current buffer and its active keymaps
+       ;; (to which we may have assigned state bindings), as well as
+       ;; states whose definitions may not have been processed yet.
+       (evil-put-property
+        'evil-state-properties ',state
+        :name ',name
+        :toggle ',toggle
+        :mode (defvar ,mode nil
+                ,(format "Non-nil if %s is enabled.
+Use the command `%s' to change this variable." name toggle))
+        :keymap (defvar ,keymap (make-sparse-keymap)
+                  ,(format "Keymap for %s." name))
+        :local (defvar ,local nil
+                 ,(format "Non-nil if %s is enabled.
+Use the command `%s' to change this variable." name toggle))
+        :local-keymap (defvar ,local-keymap nil
+                        ,(format "Buffer-local keymap for %s." name))
+        :tag (defvar ,tag ,tag-value
+               ,(format "Mode line tag for %s." name))
+        :message (defvar ,message ,message-value
+                   ,(format "Echo area message for %s." name))
+        :cursor (defvar ,cursor ',cursor-value
+                  ,(format "Cursor for %s.
+May be a cursor type as per `cursor-type', a color string as passed
+to `set-cursor-color', a zero-argument function for changing the
+cursor, or a list of the above." name))
+        :entry-hook (defvar ,entry-hook nil
+                      ,(format "Hooks to run when entering %s." name))
+        :exit-hook (defvar ,exit-hook nil
+                     ,(format "Hooks to run when exiting %s." name))
+        :modes (defvar ,modes nil
+                 ,(format "Modes that should come up in %s." name))
+        :input-method ',input-method
+        :predicate ',predicate
+        :enable ',enable)
+
+       ,@(when suppress-keymap
+           `((set-keymap-parent ,keymap evil-suppress-map)))
+
+       (dolist (func ',entry-hook-value)
+         (add-hook ',entry-hook func))
+
+       (dolist (func ',exit-hook-value)
+         (add-hook ',exit-hook func))
+
+       (defun ,predicate (&optional state)
+         ,(format "Whether the current state is %s.
+\(That is, whether `evil-state' is `%s'.)" name state)
+         (and evil-local-mode
+              (eq (or state evil-state) ',state)))
+
+       ;; define state function
+       (defun ,toggle (&optional arg)
+         ,(format "Enable %s. Disable with negative ARG.
+If ARG is nil, don't display a message in the echo area.%s" name doc)
+         (interactive)
+         (cond
+          ((and (numberp arg) (< arg 1))
+           (setq evil-previous-state evil-state
+                 evil-state nil)
+           (let ((evil-state ',state))
+             (run-hooks ',exit-hook)
+             (setq evil-state nil)
+             (evil-normalize-keymaps)
+             ,@body))
+          (t
+           (unless evil-local-mode
+             (evil-local-mode 1))
+           (let ((evil-next-state ',state)
+                 input-method-activate-hook
+                 input-method-deactivate-hook)
+             (evil-change-state nil)
+             (setq evil-state ',state)
+             (evil-add-to-alist 'evil-previous-state-alist
+                                ',state evil-previous-state)
+             (let ((evil-state ',state))
+               (evil-normalize-keymaps)
+               (if ',input-method
+                   (activate-input-method evil-input-method)
+                 ;; BUG #475: Deactivate the current input method only
+                 ;; if there is a function to deactivate it, otherwise
+                 ;; an error would be raised. This strange situation
+                 ;; should not arise in general and there should
+                 ;; probably be a better way to handle this situation.
+                 (if deactivate-current-input-method-function
+                     (deactivate-input-method)))
+               (unless evil-no-display
+                 (evil-refresh-cursor ',state)
+                 (evil-refresh-mode-line ',state)
+                 (when (called-interactively-p 'any)
+                   (redisplay)))
+               ,@body
+               (run-hooks ',entry-hook)
+               (when (and evil-echo-state
+                          arg (not evil-no-display) ,message)
+                 (if (functionp ,message)
+                     (funcall ,message)
+                   (evil-echo "%s" ,message))))))))
+
+       (evil-set-command-property ',toggle :keep-visual t)
+       (evil-set-command-property ',toggle :suppress-operator t)
+
+       (evil-define-keymap ,keymap nil
+         :mode ,mode
+         :func nil)
+
+       (evil-define-keymap ,local-keymap nil
+         :mode ,local
+         :local t
+         :func nil)
+
+       ',state)))
+
+(provide 'evil-core)
+
+;;; evil-core.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-core.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-digraphs.el
@@ -0,0 +1,1729 @@
+;;; evil-digraphs.el --- Digraphs
+
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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-vars)
+
+;;; Code:
+
+(defgroup evil-digraphs nil
+  "Digraph support based on RFC 1345."
+  :group 'evil
+  :prefix "evil-digraph-")
+
+(defcustom evil-digraphs-table-user nil
+  "List of user-defined digraphs.
+Entries have the form ((?CHAR1 ?CHAR2) . ?DIGRAPH).  That is,
+a cons cell of the digraph and its character replacement,
+where the digraph is a list of two characters.
+See also `evil-digraphs-table'."
+  :type '(alist :key-type (list character character)
+                :value-type character)
+  :require 'evil-digraphs
+  :group 'evil-digraphs)
+
+(defconst evil-digraphs-table
+  '(((?N ?U) . ?\x00)
+    ((?S ?H) . ?\x01)
+    ((?S ?X) . ?\x02)
+    ((?E ?X) . ?\x03)
+    ((?E ?T) . ?\x04)
+    ((?E ?Q) . ?\x05)
+    ((?A ?K) . ?\x06)
+    ((?B ?L) . ?\x07)
+    ((?B ?S) . ?\x08)
+    ((?H ?T) . ?\x09)
+    ((?L ?F) . ?\x0a)
+    ((?V ?T) . ?\x0b)
+    ((?F ?F) . ?\x0c)
+    ((?C ?R) . ?\x0d)
+    ((?S ?O) . ?\x0e)
+    ((?S ?I) . ?\x0f)
+    ((?D ?L) . ?\x10)
+    ((?D ?1) . ?\x11)
+    ((?D ?2) . ?\x12)
+    ((?D ?3) . ?\x13)
+    ((?D ?4) . ?\x14)
+    ((?N ?K) . ?\x15)
+    ((?S ?Y) . ?\x16)
+    ((?E ?B) . ?\x17)
+    ((?C ?N) . ?\x18)
+    ((?E ?M) . ?\x19)
+    ((?S ?B) . ?\x1a)
+    ((?E ?C) . ?\x1b)
+    ((?F ?S) . ?\x1c)
+    ((?G ?S) . ?\x1d)
+    ((?R ?S) . ?\x1e)
+    ((?U ?S) . ?\x1f)
+    ((?S ?P) . ?\x20)
+    ((?N ?b) . ?\x23)
+    ((?D ?O) . ?\x24)
+    ((?A ?t) . ?\x40)
+    ((?< ?\() . ?\x5b)
+    ((?/ ?/) . ?\x5c)
+    ((?\) ?>) . ?\x5d)
+    ((?' ?>) . ?\x5e)
+    ((?' ?!) . ?\x60)
+    ((?\( ?!) . ?\x7b)
+    ((?! ?!) . ?\x7c)
+    ((?! ?\)) . ?\x7d)
+    ((?' ??) . ?\x7e)
+    ((?D ?T) . ?\x7f)
+    ((?P ?A) . ?\x80)
+    ((?H ?O) . ?\x81)
+    ((?B ?H) . ?\x82)
+    ((?N ?H) . ?\x83)
+    ((?I ?N) . ?\x84)
+    ((?N ?L) . ?\x85)
+    ((?S ?A) . ?\x86)
+    ((?E ?S) . ?\x87)
+    ((?H ?S) . ?\x88)
+    ((?H ?J) . ?\x89)
+    ((?V ?S) . ?\x8a)
+    ((?P ?D) . ?\x8b)
+    ((?P ?U) . ?\x8c)
+    ((?R ?I) . ?\x8d)
+    ((?S ?2) . ?\x8e)
+    ((?S ?3) . ?\x8f)
+    ((?D ?C) . ?\x90)
+    ((?P ?1) . ?\x91)
+    ((?P ?2) . ?\x92)
+    ((?T ?S) . ?\x93)
+    ((?C ?C) . ?\x94)
+    ((?M ?W) . ?\x95)
+    ((?S ?G) . ?\x96)
+    ((?E ?G) . ?\x97)
+    ((?S ?S) . ?\x98)
+    ((?G ?C) . ?\x99)
+    ((?S ?C) . ?\x9a)
+    ((?C ?I) . ?\x9b)
+    ((?S ?T) . ?\x9c)
+    ((?O ?C) . ?\x9d)
+    ((?P ?M) . ?\x9e)
+    ((?A ?C) . ?\x9f)
+    ((?N ?S) . ?\xa0)
+    ((?! ?I) . ?\xa1)
+    ((?C ?t) . ?\xa2)
+    ((?P ?d) . ?\xa3)
+    ((?C ?u) . ?\xa4)
+    ((?Y ?e) . ?\xa5)
+    ((?B ?B) . ?\xa6)
+    ((?S ?E) . ?\xa7)
+    ((?' ?:) . ?\xa8)
+    ((?C ?o) . ?\xa9)
+    ((?- ?a) . ?\xaa)
+    ((?< ?<) . ?\xab)
+    ((?N ?O) . ?\xac)
+    ((?- ?-) . ?\xad)
+    ((?R ?g) . ?\xae)
+    ((?' ?m) . ?\xaf)
+    ((?D ?G) . ?\xb0)
+    ((?+ ?-) . ?\xb1)
+    ((?2 ?S) . ?\xb2)
+    ((?3 ?S) . ?\xb3)
+    ((?' ?') . ?\xb4)
+    ((?M ?y) . ?\xb5)
+    ((?P ?I) . ?\xb6)
+    ((?. ?M) . ?\xb7)
+    ((?' ?,) . ?\xb8)
+    ((?1 ?S) . ?\xb9)
+    ((?- ?o) . ?\xba)
+    ((?> ?>) . ?\xbb)
+    ((?1 ?4) . ?\xbc)
+    ((?1 ?2) . ?\xbd)
+    ((?3 ?4) . ?\xbe)
+    ((?? ?I) . ?\xbf)
+    ((?A ?!) . ?\xc0)
+    ((?A ?') . ?\xc1)
+    ((?A ?>) . ?\xc2)
+    ((?A ??) . ?\xc3)
+    ((?A ?:) . ?\xc4)
+    ((?A ?A) . ?\xc5)
+    ((?A ?E) . ?\xc6)
+    ((?C ?,) . ?\xc7)
+    ((?E ?!) . ?\xc8)
+    ((?E ?') . ?\xc9)
+    ((?E ?>) . ?\xca)
+    ((?E ?:) . ?\xcb)
+    ((?I ?!) . ?\xcc)
+    ((?I ?') . ?\xcd)
+    ((?I ?>) . ?\xce)
+    ((?I ?:) . ?\xcf)
+    ((?D ?-) . ?\xd0)
+    ((?N ??) . ?\xd1)
+    ((?O ?!) . ?\xd2)
+    ((?O ?') . ?\xd3)
+    ((?O ?>) . ?\xd4)
+    ((?O ??) . ?\xd5)
+    ((?O ?:) . ?\xd6)
+    ((?* ?X) . ?\xd7)
+    ((?O ?/) . ?\xd8)
+    ((?U ?!) . ?\xd9)
+    ((?U ?') . ?\xda)
+    ((?U ?>) . ?\xdb)
+    ((?U ?:) . ?\xdc)
+    ((?Y ?') . ?\xdd)
+    ((?T ?H) . ?\xde)
+    ((?s ?s) . ?\xdf)
+    ((?a ?!) . ?\xe0)
+    ((?a ?') . ?\xe1)
+    ((?a ?>) . ?\xe2)
+    ((?a ??) . ?\xe3)
+    ((?a ?:) . ?\xe4)
+    ((?a ?a) . ?\xe5)
+    ((?a ?e) . ?\xe6)
+    ((?c ?,) . ?\xe7)
+    ((?e ?!) . ?\xe8)
+    ((?e ?') . ?\xe9)
+    ((?e ?>) . ?\xea)
+    ((?e ?:) . ?\xeb)
+    ((?i ?!) . ?\xec)
+    ((?i ?') . ?\xed)
+    ((?i ?>) . ?\xee)
+    ((?i ?:) . ?\xef)
+    ((?d ?-) . ?\xf0)
+    ((?n ??) . ?\xf1)
+    ((?o ?!) . ?\xf2)
+    ((?o ?') . ?\xf3)
+    ((?o ?>) . ?\xf4)
+    ((?o ??) . ?\xf5)
+    ((?o ?:) . ?\xf6)
+    ((?- ?:) . ?\xf7)
+    ((?o ?/) . ?\xf8)
+    ((?u ?!) . ?\xf9)
+    ((?u ?') . ?\xfa)
+    ((?u ?>) . ?\xfb)
+    ((?u ?:) . ?\xfc)
+    ((?y ?') . ?\xfd)
+    ((?t ?h) . ?\xfe)
+    ((?y ?:) . ?\xff)
+    ((?A ?-) . ?\x0100)
+    ((?a ?-) . ?\x0101)
+    ((?A ?\() . ?\x0102)
+    ((?a ?\() . ?\x0103)
+    ((?A ?\;) . ?\x0104)
+    ((?a ?\;) . ?\x0105)
+    ((?C ?') . ?\x0106)
+    ((?c ?') . ?\x0107)
+    ((?C ?>) . ?\x0108)
+    ((?c ?>) . ?\x0109)
+    ((?C ?.) . ?\x010a)
+    ((?c ?.) . ?\x010b)
+    ((?C ?<) . ?\x010c)
+    ((?c ?<) . ?\x010d)
+    ((?D ?<) . ?\x010e)
+    ((?d ?<) . ?\x010f)
+    ((?D ?/) . ?\x0110)
+    ((?d ?/) . ?\x0111)
+    ((?E ?-) . ?\x0112)
+    ((?e ?-) . ?\x0113)
+    ((?E ?\() . ?\x0114)
+    ((?e ?\() . ?\x0115)
+    ((?E ?.) . ?\x0116)
+    ((?e ?.) . ?\x0117)
+    ((?E ?\;) . ?\x0118)
+    ((?e ?\;) . ?\x0119)
+    ((?E ?<) . ?\x011a)
+    ((?e ?<) . ?\x011b)
+    ((?G ?>) . ?\x011c)
+    ((?g ?>) . ?\x011d)
+    ((?G ?\() . ?\x011e)
+    ((?g ?\() . ?\x011f)
+    ((?G ?.) . ?\x0120)
+    ((?g ?.) . ?\x0121)
+    ((?G ?,) . ?\x0122)
+    ((?g ?,) . ?\x0123)
+    ((?H ?>) . ?\x0124)
+    ((?h ?>) . ?\x0125)
+    ((?H ?/) . ?\x0126)
+    ((?h ?/) . ?\x0127)
+    ((?I ??) . ?\x0128)
+    ((?i ??) . ?\x0129)
+    ((?I ?-) . ?\x012a)
+    ((?i ?-) . ?\x012b)
+    ((?I ?\() . ?\x012c)
+    ((?i ?\() . ?\x012d)
+    ((?I ?\;) . ?\x012e)
+    ((?i ?\;) . ?\x012f)
+    ((?I ?.) . ?\x0130)
+    ((?i ?.) . ?\x0131)
+    ((?I ?J) . ?\x0132)
+    ((?i ?j) . ?\x0133)
+    ((?J ?>) . ?\x0134)
+    ((?j ?>) . ?\x0135)
+    ((?K ?,) . ?\x0136)
+    ((?k ?,) . ?\x0137)
+    ((?k ?k) . ?\x0138)
+    ((?L ?') . ?\x0139)
+    ((?l ?') . ?\x013a)
+    ((?L ?,) . ?\x013b)
+    ((?l ?,) . ?\x013c)
+    ((?L ?<) . ?\x013d)
+    ((?l ?<) . ?\x013e)
+    ((?L ?.) . ?\x013f)
+    ((?l ?.) . ?\x0140)
+    ((?L ?/) . ?\x0141)
+    ((?l ?/) . ?\x0142)
+    ((?N ?') . ?\x0143)
+    ((?n ?') . ?\x0144)
+    ((?N ?,) . ?\x0145)
+    ((?n ?,) . ?\x0146)
+    ((?N ?<) . ?\x0147)
+    ((?n ?<) . ?\x0148)
+    ((?' ?n) . ?\x0149)
+    ((?N ?G) . ?\x014a)
+    ((?n ?g) . ?\x014b)
+    ((?O ?-) . ?\x014c)
+    ((?o ?-) . ?\x014d)
+    ((?O ?\() . ?\x014e)
+    ((?o ?\() . ?\x014f)
+    ((?O ?\") . ?\x0150)
+    ((?o ?\") . ?\x0151)
+    ((?O ?E) . ?\x0152)
+    ((?o ?e) . ?\x0153)
+    ((?R ?') . ?\x0154)
+    ((?r ?') . ?\x0155)
+    ((?R ?,) . ?\x0156)
+    ((?r ?,) . ?\x0157)
+    ((?R ?<) . ?\x0158)
+    ((?r ?<) . ?\x0159)
+    ((?S ?') . ?\x015a)
+    ((?s ?') . ?\x015b)
+    ((?S ?>) . ?\x015c)
+    ((?s ?>) . ?\x015d)
+    ((?S ?,) . ?\x015e)
+    ((?s ?,) . ?\x015f)
+    ((?S ?<) . ?\x0160)
+    ((?s ?<) . ?\x0161)
+    ((?T ?,) . ?\x0162)
+    ((?t ?,) . ?\x0163)
+    ((?T ?<) . ?\x0164)
+    ((?t ?<) . ?\x0165)
+    ((?T ?/) . ?\x0166)
+    ((?t ?/) . ?\x0167)
+    ((?U ??) . ?\x0168)
+    ((?u ??) . ?\x0169)
+    ((?U ?-) . ?\x016a)
+    ((?u ?-) . ?\x016b)
+    ((?U ?\() . ?\x016c)
+    ((?u ?\() . ?\x016d)
+    ((?U ?0) . ?\x016e)
+    ((?u ?0) . ?\x016f)
+    ((?U ?\") . ?\x0170)
+    ((?u ?\") . ?\x0171)
+    ((?U ?\;) . ?\x0172)
+    ((?u ?\;) . ?\x0173)
+    ((?W ?>) . ?\x0174)
+    ((?w ?>) . ?\x0175)
+    ((?Y ?>) . ?\x0176)
+    ((?y ?>) . ?\x0177)
+    ((?Y ?:) . ?\x0178)
+    ((?Z ?') . ?\x0179)
+    ((?z ?') . ?\x017a)
+    ((?Z ?.) . ?\x017b)
+    ((?z ?.) . ?\x017c)
+    ((?Z ?<) . ?\x017d)
+    ((?z ?<) . ?\x017e)
+    ((?O ?9) . ?\x01a0)
+    ((?o ?9) . ?\x01a1)
+    ((?O ?I) . ?\x01a2)
+    ((?o ?i) . ?\x01a3)
+    ((?y ?r) . ?\x01a6)
+    ((?U ?9) . ?\x01af)
+    ((?u ?9) . ?\x01b0)
+    ((?Z ?/) . ?\x01b5)
+    ((?z ?/) . ?\x01b6)
+    ((?E ?D) . ?\x01b7)
+    ((?A ?<) . ?\x01cd)
+    ((?a ?<) . ?\x01ce)
+    ((?I ?<) . ?\x01cf)
+    ((?i ?<) . ?\x01d0)
+    ((?O ?<) . ?\x01d1)
+    ((?o ?<) . ?\x01d2)
+    ((?U ?<) . ?\x01d3)
+    ((?u ?<) . ?\x01d4)
+    ((?A ?1) . ?\x01de)
+    ((?a ?1) . ?\x01df)
+    ((?A ?7) . ?\x01e0)
+    ((?a ?7) . ?\x01e1)
+    ((?A ?3) . ?\x01e2)
+    ((?a ?3) . ?\x01e3)
+    ((?G ?/) . ?\x01e4)
+    ((?g ?/) . ?\x01e5)
+    ((?G ?<) . ?\x01e6)
+    ((?g ?<) . ?\x01e7)
+    ((?K ?<) . ?\x01e8)
+    ((?k ?<) . ?\x01e9)
+    ((?O ?\;) . ?\x01ea)
+    ((?o ?\;) . ?\x01eb)
+    ((?O ?1) . ?\x01ec)
+    ((?o ?1) . ?\x01ed)
+    ((?E ?Z) . ?\x01ee)
+    ((?e ?z) . ?\x01ef)
+    ((?j ?<) . ?\x01f0)
+    ((?G ?') . ?\x01f4)
+    ((?g ?') . ?\x01f5)
+    ((?\; ?S) . ?\x02bf)
+    ((?' ?<) . ?\x02c7)
+    ((?' ?\() . ?\x02d8)
+    ((?' ?.) . ?\x02d9)
+    ((?' ?0) . ?\x02da)
+    ((?' ?\;) . ?\x02db)
+    ((?' ?\") . ?\x02dd)
+    ((?A ?%) . ?\x0386)
+    ((?E ?%) . ?\x0388)
+    ((?Y ?%) . ?\x0389)
+    ((?I ?%) . ?\x038a)
+    ((?O ?%) . ?\x038c)
+    ((?U ?%) . ?\x038e)
+    ((?W ?%) . ?\x038f)
+    ((?i ?3) . ?\x0390)
+    ((?A ?*) . ?\x0391)
+    ((?B ?*) . ?\x0392)
+    ((?G ?*) . ?\x0393)
+    ((?D ?*) . ?\x0394)
+    ((?E ?*) . ?\x0395)
+    ((?Z ?*) . ?\x0396)
+    ((?Y ?*) . ?\x0397)
+    ((?H ?*) . ?\x0398)
+    ((?I ?*) . ?\x0399)
+    ((?K ?*) . ?\x039a)
+    ((?L ?*) . ?\x039b)
+    ((?M ?*) . ?\x039c)
+    ((?N ?*) . ?\x039d)
+    ((?C ?*) . ?\x039e)
+    ((?O ?*) . ?\x039f)
+    ((?P ?*) . ?\x03a0)
+    ((?R ?*) . ?\x03a1)
+    ((?S ?*) . ?\x03a3)
+    ((?T ?*) . ?\x03a4)
+    ((?U ?*) . ?\x03a5)
+    ((?F ?*) . ?\x03a6)
+    ((?X ?*) . ?\x03a7)
+    ((?Q ?*) . ?\x03a8)
+    ((?W ?*) . ?\x03a9)
+    ((?J ?*) . ?\x03aa)
+    ((?V ?*) . ?\x03ab)
+    ((?a ?%) . ?\x03ac)
+    ((?e ?%) . ?\x03ad)
+    ((?y ?%) . ?\x03ae)
+    ((?i ?%) . ?\x03af)
+    ((?u ?3) . ?\x03b0)
+    ((?a ?*) . ?\x03b1)
+    ((?b ?*) . ?\x03b2)
+    ((?g ?*) . ?\x03b3)
+    ((?d ?*) . ?\x03b4)
+    ((?e ?*) . ?\x03b5)
+    ((?z ?*) . ?\x03b6)
+    ((?y ?*) . ?\x03b7)
+    ((?h ?*) . ?\x03b8)
+    ((?i ?*) . ?\x03b9)
+    ((?k ?*) . ?\x03ba)
+    ((?l ?*) . ?\x03bb)
+    ((?m ?*) . ?\x03bc)
+    ((?n ?*) . ?\x03bd)
+    ((?c ?*) . ?\x03be)
+    ((?o ?*) . ?\x03bf)
+    ((?p ?*) . ?\x03c0)
+    ((?r ?*) . ?\x03c1)
+    ((?* ?s) . ?\x03c2)
+    ((?s ?*) . ?\x03c3)
+    ((?t ?*) . ?\x03c4)
+    ((?u ?*) . ?\x03c5)
+    ((?f ?*) . ?\x03c6)
+    ((?x ?*) . ?\x03c7)
+    ((?q ?*) . ?\x03c8)
+    ((?w ?*) . ?\x03c9)
+    ((?j ?*) . ?\x03ca)
+    ((?v ?*) . ?\x03cb)
+    ((?o ?%) . ?\x03cc)
+    ((?u ?%) . ?\x03cd)
+    ((?w ?%) . ?\x03ce)
+    ((?' ?G) . ?\x03d8)
+    ((?, ?G) . ?\x03d9)
+    ((?T ?3) . ?\x03da)
+    ((?t ?3) . ?\x03db)
+    ((?M ?3) . ?\x03dc)
+    ((?m ?3) . ?\x03dd)
+    ((?K ?3) . ?\x03de)
+    ((?k ?3) . ?\x03df)
+    ((?P ?3) . ?\x03e0)
+    ((?p ?3) . ?\x03e1)
+    ((?' ?%) . ?\x03f4)
+    ((?j ?3) . ?\x03f5)
+    ((?I ?O) . ?\x0401)
+    ((?D ?%) . ?\x0402)
+    ((?G ?%) . ?\x0403)
+    ((?I ?E) . ?\x0404)
+    ((?D ?S) . ?\x0405)
+    ((?I ?I) . ?\x0406)
+    ((?Y ?I) . ?\x0407)
+    ((?J ?%) . ?\x0408)
+    ((?L ?J) . ?\x0409)
+    ((?N ?J) . ?\x040a)
+    ((?T ?s) . ?\x040b)
+    ((?K ?J) . ?\x040c)
+    ((?V ?%) . ?\x040e)
+    ((?D ?Z) . ?\x040f)
+    ((?A ?=) . ?\x0410)
+    ((?B ?=) . ?\x0411)
+    ((?V ?=) . ?\x0412)
+    ((?G ?=) . ?\x0413)
+    ((?D ?=) . ?\x0414)
+    ((?E ?=) . ?\x0415)
+    ((?Z ?%) . ?\x0416)
+    ((?Z ?=) . ?\x0417)
+    ((?I ?=) . ?\x0418)
+    ((?J ?=) . ?\x0419)
+    ((?K ?=) . ?\x041a)
+    ((?L ?=) . ?\x041b)
+    ((?M ?=) . ?\x041c)
+    ((?N ?=) . ?\x041d)
+    ((?O ?=) . ?\x041e)
+    ((?P ?=) . ?\x041f)
+    ((?R ?=) . ?\x0420)
+    ((?S ?=) . ?\x0421)
+    ((?T ?=) . ?\x0422)
+    ((?U ?=) . ?\x0423)
+    ((?F ?=) . ?\x0424)
+    ((?H ?=) . ?\x0425)
+    ((?C ?=) . ?\x0426)
+    ((?C ?%) . ?\x0427)
+    ((?S ?%) . ?\x0428)
+    ((?S ?c) . ?\x0429)
+    ((?= ?\") . ?\x042a)
+    ((?Y ?=) . ?\x042b)
+    ((?% ?\") . ?\x042c)
+    ((?J ?E) . ?\x042d)
+    ((?J ?U) . ?\x042e)
+    ((?J ?A) . ?\x042f)
+    ((?a ?=) . ?\x0430)
+    ((?b ?=) . ?\x0431)
+    ((?v ?=) . ?\x0432)
+    ((?g ?=) . ?\x0433)
+    ((?d ?=) . ?\x0434)
+    ((?e ?=) . ?\x0435)
+    ((?z ?%) . ?\x0436)
+    ((?z ?=) . ?\x0437)
+    ((?i ?=) . ?\x0438)
+    ((?j ?=) . ?\x0439)
+    ((?k ?=) . ?\x043a)
+    ((?l ?=) . ?\x043b)
+    ((?m ?=) . ?\x043c)
+    ((?n ?=) . ?\x043d)
+    ((?o ?=) . ?\x043e)
+    ((?p ?=) . ?\x043f)
+    ((?r ?=) . ?\x0440)
+    ((?s ?=) . ?\x0441)
+    ((?t ?=) . ?\x0442)
+    ((?u ?=) . ?\x0443)
+    ((?f ?=) . ?\x0444)
+    ((?h ?=) . ?\x0445)
+    ((?c ?=) . ?\x0446)
+    ((?c ?%) . ?\x0447)
+    ((?s ?%) . ?\x0448)
+    ((?s ?c) . ?\x0449)
+    ((?= ?') . ?\x044a)
+    ((?y ?=) . ?\x044b)
+    ((?% ?') . ?\x044c)
+    ((?j ?e) . ?\x044d)
+    ((?j ?u) . ?\x044e)
+    ((?j ?a) . ?\x044f)
+    ((?i ?o) . ?\x0451)
+    ((?d ?%) . ?\x0452)
+    ((?g ?%) . ?\x0453)
+    ((?i ?e) . ?\x0454)
+    ((?d ?s) . ?\x0455)
+    ((?i ?i) . ?\x0456)
+    ((?y ?i) . ?\x0457)
+    ((?j ?%) . ?\x0458)
+    ((?l ?j) . ?\x0459)
+    ((?n ?j) . ?\x045a)
+    ((?t ?s) . ?\x045b)
+    ((?k ?j) . ?\x045c)
+    ((?v ?%) . ?\x045e)
+    ((?d ?z) . ?\x045f)
+    ((?Y ?3) . ?\x0462)
+    ((?y ?3) . ?\x0463)
+    ((?O ?3) . ?\x046a)
+    ((?o ?3) . ?\x046b)
+    ((?F ?3) . ?\x0472)
+    ((?f ?3) . ?\x0473)
+    ((?V ?3) . ?\x0474)
+    ((?v ?3) . ?\x0475)
+    ((?C ?3) . ?\x0480)
+    ((?c ?3) . ?\x0481)
+    ((?G ?3) . ?\x0490)
+    ((?g ?3) . ?\x0491)
+    ((?A ?+) . ?\x05d0)
+    ((?B ?+) . ?\x05d1)
+    ((?G ?+) . ?\x05d2)
+    ((?D ?+) . ?\x05d3)
+    ((?H ?+) . ?\x05d4)
+    ((?W ?+) . ?\x05d5)
+    ((?Z ?+) . ?\x05d6)
+    ((?X ?+) . ?\x05d7)
+    ((?T ?j) . ?\x05d8)
+    ((?J ?+) . ?\x05d9)
+    ((?K ?%) . ?\x05da)
+    ((?K ?+) . ?\x05db)
+    ((?L ?+) . ?\x05dc)
+    ((?M ?%) . ?\x05dd)
+    ((?M ?+) . ?\x05de)
+    ((?N ?%) . ?\x05df)
+    ((?N ?+) . ?\x05e0)
+    ((?S ?+) . ?\x05e1)
+    ((?E ?+) . ?\x05e2)
+    ((?P ?%) . ?\x05e3)
+    ((?P ?+) . ?\x05e4)
+    ((?Z ?j) . ?\x05e5)
+    ((?Z ?J) . ?\x05e6)
+    ((?Q ?+) . ?\x05e7)
+    ((?R ?+) . ?\x05e8)
+    ((?S ?h) . ?\x05e9)
+    ((?T ?+) . ?\x05ea)
+    ((?, ?+) . ?\x060c)
+    ((?\; ?+) . ?\x061b)
+    ((?? ?+) . ?\x061f)
+    ((?H ?') . ?\x0621)
+    ((?a ?M) . ?\x0622)
+    ((?a ?H) . ?\x0623)
+    ((?w ?H) . ?\x0624)
+    ((?a ?h) . ?\x0625)
+    ((?y ?H) . ?\x0626)
+    ((?a ?+) . ?\x0627)
+    ((?b ?+) . ?\x0628)
+    ((?t ?m) . ?\x0629)
+    ((?t ?+) . ?\x062a)
+    ((?t ?k) . ?\x062b)
+    ((?g ?+) . ?\x062c)
+    ((?h ?k) . ?\x062d)
+    ((?x ?+) . ?\x062e)
+    ((?d ?+) . ?\x062f)
+    ((?d ?k) . ?\x0630)
+    ((?r ?+) . ?\x0631)
+    ((?z ?+) . ?\x0632)
+    ((?s ?+) . ?\x0633)
+    ((?s ?n) . ?\x0634)
+    ((?c ?+) . ?\x0635)
+    ((?d ?d) . ?\x0636)
+    ((?t ?j) . ?\x0637)
+    ((?z ?H) . ?\x0638)
+    ((?e ?+) . ?\x0639)
+    ((?i ?+) . ?\x063a)
+    ((?+ ?+) . ?\x0640)
+    ((?f ?+) . ?\x0641)
+    ((?q ?+) . ?\x0642)
+    ((?k ?+) . ?\x0643)
+    ((?l ?+) . ?\x0644)
+    ((?m ?+) . ?\x0645)
+    ((?n ?+) . ?\x0646)
+    ((?h ?+) . ?\x0647)
+    ((?w ?+) . ?\x0648)
+    ((?j ?+) . ?\x0649)
+    ((?y ?+) . ?\x064a)
+    ((?: ?+) . ?\x064b)
+    ((?\" ?+) . ?\x064c)
+    ((?= ?+) . ?\x064d)
+    ((?/ ?+) . ?\x064e)
+    ((?' ?+) . ?\x064f)
+    ((?1 ?+) . ?\x0650)
+    ((?3 ?+) . ?\x0651)
+    ((?0 ?+) . ?\x0652)
+    ((?a ?S) . ?\x0670)
+    ((?p ?+) . ?\x067e)
+    ((?v ?+) . ?\x06a4)
+    ((?g ?f) . ?\x06af)
+    ((?0 ?a) . ?\x06f0)
+    ((?1 ?a) . ?\x06f1)
+    ((?2 ?a) . ?\x06f2)
+    ((?3 ?a) . ?\x06f3)
+    ((?4 ?a) . ?\x06f4)
+    ((?5 ?a) . ?\x06f5)
+    ((?6 ?a) . ?\x06f6)
+    ((?7 ?a) . ?\x06f7)
+    ((?8 ?a) . ?\x06f8)
+    ((?9 ?a) . ?\x06f9)
+    ((?B ?.) . ?\x1e02)
+    ((?b ?.) . ?\x1e03)
+    ((?B ?_) . ?\x1e06)
+    ((?b ?_) . ?\x1e07)
+    ((?D ?.) . ?\x1e0a)
+    ((?d ?.) . ?\x1e0b)
+    ((?D ?_) . ?\x1e0e)
+    ((?d ?_) . ?\x1e0f)
+    ((?D ?,) . ?\x1e10)
+    ((?d ?,) . ?\x1e11)
+    ((?F ?.) . ?\x1e1e)
+    ((?f ?.) . ?\x1e1f)
+    ((?G ?-) . ?\x1e20)
+    ((?g ?-) . ?\x1e21)
+    ((?H ?.) . ?\x1e22)
+    ((?h ?.) . ?\x1e23)
+    ((?H ?:) . ?\x1e26)
+    ((?h ?:) . ?\x1e27)
+    ((?H ?,) . ?\x1e28)
+    ((?h ?,) . ?\x1e29)
+    ((?K ?') . ?\x1e30)
+    ((?k ?') . ?\x1e31)
+    ((?K ?_) . ?\x1e34)
+    ((?k ?_) . ?\x1e35)
+    ((?L ?_) . ?\x1e3a)
+    ((?l ?_) . ?\x1e3b)
+    ((?M ?') . ?\x1e3e)
+    ((?m ?') . ?\x1e3f)
+    ((?M ?.) . ?\x1e40)
+    ((?m ?.) . ?\x1e41)
+    ((?N ?.) . ?\x1e44)
+    ((?n ?.) . ?\x1e45)
+    ((?N ?_) . ?\x1e48)
+    ((?n ?_) . ?\x1e49)
+    ((?P ?') . ?\x1e54)
+    ((?p ?') . ?\x1e55)
+    ((?P ?.) . ?\x1e56)
+    ((?p ?.) . ?\x1e57)
+    ((?R ?.) . ?\x1e58)
+    ((?r ?.) . ?\x1e59)
+    ((?R ?_) . ?\x1e5e)
+    ((?r ?_) . ?\x1e5f)
+    ((?S ?.) . ?\x1e60)
+    ((?s ?.) . ?\x1e61)
+    ((?T ?.) . ?\x1e6a)
+    ((?t ?.) . ?\x1e6b)
+    ((?T ?_) . ?\x1e6e)
+    ((?t ?_) . ?\x1e6f)
+    ((?V ??) . ?\x1e7c)
+    ((?v ??) . ?\x1e7d)
+    ((?W ?!) . ?\x1e80)
+    ((?w ?!) . ?\x1e81)
+    ((?W ?') . ?\x1e82)
+    ((?w ?') . ?\x1e83)
+    ((?W ?:) . ?\x1e84)
+    ((?w ?:) . ?\x1e85)
+    ((?W ?.) . ?\x1e86)
+    ((?w ?.) . ?\x1e87)
+    ((?X ?.) . ?\x1e8a)
+    ((?x ?.) . ?\x1e8b)
+    ((?X ?:) . ?\x1e8c)
+    ((?x ?:) . ?\x1e8d)
+    ((?Y ?.) . ?\x1e8e)
+    ((?y ?.) . ?\x1e8f)
+    ((?Z ?>) . ?\x1e90)
+    ((?z ?>) . ?\x1e91)
+    ((?Z ?_) . ?\x1e94)
+    ((?z ?_) . ?\x1e95)
+    ((?h ?_) . ?\x1e96)
+    ((?t ?:) . ?\x1e97)
+    ((?w ?0) . ?\x1e98)
+    ((?y ?0) . ?\x1e99)
+    ((?A ?2) . ?\x1ea2)
+    ((?a ?2) . ?\x1ea3)
+    ((?E ?2) . ?\x1eba)
+    ((?e ?2) . ?\x1ebb)
+    ((?E ??) . ?\x1ebc)
+    ((?e ??) . ?\x1ebd)
+    ((?I ?2) . ?\x1ec8)
+    ((?i ?2) . ?\x1ec9)
+    ((?O ?2) . ?\x1ece)
+    ((?o ?2) . ?\x1ecf)
+    ((?U ?2) . ?\x1ee6)
+    ((?u ?2) . ?\x1ee7)
+    ((?Y ?!) . ?\x1ef2)
+    ((?y ?!) . ?\x1ef3)
+    ((?Y ?2) . ?\x1ef6)
+    ((?y ?2) . ?\x1ef7)
+    ((?Y ??) . ?\x1ef8)
+    ((?y ??) . ?\x1ef9)
+    ((?\; ?') . ?\x1f00)
+    ((?, ?') . ?\x1f01)
+    ((?\; ?!) . ?\x1f02)
+    ((?, ?!) . ?\x1f03)
+    ((?? ?\;) . ?\x1f04)
+    ((?? ?,) . ?\x1f05)
+    ((?! ?:) . ?\x1f06)
+    ((?? ?:) . ?\x1f07)
+    ((?1 ?N) . ?\x2002)
+    ((?1 ?M) . ?\x2003)
+    ((?3 ?M) . ?\x2004)
+    ((?4 ?M) . ?\x2005)
+    ((?6 ?M) . ?\x2006)
+    ((?1 ?T) . ?\x2009)
+    ((?1 ?H) . ?\x200a)
+    ((?- ?1) . ?\x2010)
+    ((?- ?N) . ?\x2013)
+    ((?- ?M) . ?\x2014)
+    ((?- ?3) . ?\x2015)
+    ((?! ?2) . ?\x2016)
+    ((?= ?2) . ?\x2017)
+    ((?' ?6) . ?\x2018)
+    ((?' ?9) . ?\x2019)
+    ((?. ?9) . ?\x201a)
+    ((?9 ?') . ?\x201b)
+    ((?\" ?6) . ?\x201c)
+    ((?\" ?9) . ?\x201d)
+    ((?: ?9) . ?\x201e)
+    ((?9 ?\") . ?\x201f)
+    ((?/ ?-) . ?\x2020)
+    ((?/ ?=) . ?\x2021)
+    ((?. ?.) . ?\x2025)
+    ((?% ?0) . ?\x2030)
+    ((?1 ?') . ?\x2032)
+    ((?2 ?') . ?\x2033)
+    ((?3 ?') . ?\x2034)
+    ((?1 ?\") . ?\x2035)
+    ((?2 ?\") . ?\x2036)
+    ((?3 ?\") . ?\x2037)
+    ((?C ?a) . ?\x2038)
+    ((?< ?1) . ?\x2039)
+    ((?> ?1) . ?\x203a)
+    ((?: ?X) . ?\x203b)
+    ((?' ?-) . ?\x203e)
+    ((?/ ?f) . ?\x2044)
+    ((?0 ?S) . ?\x2070)
+    ((?4 ?S) . ?\x2074)
+    ((?5 ?S) . ?\x2075)
+    ((?6 ?S) . ?\x2076)
+    ((?7 ?S) . ?\x2077)
+    ((?8 ?S) . ?\x2078)
+    ((?9 ?S) . ?\x2079)
+    ((?+ ?S) . ?\x207a)
+    ((?- ?S) . ?\x207b)
+    ((?= ?S) . ?\x207c)
+    ((?\( ?S) . ?\x207d)
+    ((?\) ?S) . ?\x207e)
+    ((?n ?S) . ?\x207f)
+    ((?0 ?s) . ?\x2080)
+    ((?1 ?s) . ?\x2081)
+    ((?2 ?s) . ?\x2082)
+    ((?3 ?s) . ?\x2083)
+    ((?4 ?s) . ?\x2084)
+    ((?5 ?s) . ?\x2085)
+    ((?6 ?s) . ?\x2086)
+    ((?7 ?s) . ?\x2087)
+    ((?8 ?s) . ?\x2088)
+    ((?9 ?s) . ?\x2089)
+    ((?+ ?s) . ?\x208a)
+    ((?- ?s) . ?\x208b)
+    ((?= ?s) . ?\x208c)
+    ((?\( ?s) . ?\x208d)
+    ((?\) ?s) . ?\x208e)
+    ((?L ?i) . ?\x20a4)
+    ((?P ?t) . ?\x20a7)
+    ((?W ?=) . ?\x20a9)
+    ((?= ?e) . ?\x20ac)
+    ((?E ?u) . ?\x20ac)
+    ((?o ?C) . ?\x2103)
+    ((?c ?o) . ?\x2105)
+    ((?o ?F) . ?\x2109)
+    ((?N ?0) . ?\x2116)
+    ((?P ?O) . ?\x2117)
+    ((?R ?x) . ?\x211e)
+    ((?S ?M) . ?\x2120)
+    ((?T ?M) . ?\x2122)
+    ((?O ?m) . ?\x2126)
+    ((?A ?O) . ?\x212b)
+    ((?1 ?3) . ?\x2153)
+    ((?2 ?3) . ?\x2154)
+    ((?1 ?5) . ?\x2155)
+    ((?2 ?5) . ?\x2156)
+    ((?3 ?5) . ?\x2157)
+    ((?4 ?5) . ?\x2158)
+    ((?1 ?6) . ?\x2159)
+    ((?5 ?6) . ?\x215a)
+    ((?1 ?8) . ?\x215b)
+    ((?3 ?8) . ?\x215c)
+    ((?5 ?8) . ?\x215d)
+    ((?7 ?8) . ?\x215e)
+    ((?1 ?R) . ?\x2160)
+    ((?2 ?R) . ?\x2161)
+    ((?3 ?R) . ?\x2162)
+    ((?4 ?R) . ?\x2163)
+    ((?5 ?R) . ?\x2164)
+    ((?6 ?R) . ?\x2165)
+    ((?7 ?R) . ?\x2166)
+    ((?8 ?R) . ?\x2167)
+    ((?9 ?R) . ?\x2168)
+    ((?a ?R) . ?\x2169)
+    ((?b ?R) . ?\x216a)
+    ((?c ?R) . ?\x216b)
+    ((?1 ?r) . ?\x2170)
+    ((?2 ?r) . ?\x2171)
+    ((?3 ?r) . ?\x2172)
+    ((?4 ?r) . ?\x2173)
+    ((?5 ?r) . ?\x2174)
+    ((?6 ?r) . ?\x2175)
+    ((?7 ?r) . ?\x2176)
+    ((?8 ?r) . ?\x2177)
+    ((?9 ?r) . ?\x2178)
+    ((?a ?r) . ?\x2179)
+    ((?b ?r) . ?\x217a)
+    ((?c ?r) . ?\x217b)
+    ((?< ?-) . ?\x2190)
+    ((?- ?!) . ?\x2191)
+    ((?- ?>) . ?\x2192)
+    ((?- ?v) . ?\x2193)
+    ((?< ?>) . ?\x2194)
+    ((?U ?D) . ?\x2195)
+    ((?< ?=) . ?\x21d0)
+    ((?= ?>) . ?\x21d2)
+    ((?= ?=) . ?\x21d4)
+    ((?F ?A) . ?\x2200)
+    ((?d ?P) . ?\x2202)
+    ((?T ?E) . ?\x2203)
+    ((?/ ?0) . ?\x2205)
+    ((?D ?E) . ?\x2206)
+    ((?N ?B) . ?\x2207)
+    ((?\( ?-) . ?\x2208)
+    ((?- ?\)) . ?\x220b)
+    ((?* ?P) . ?\x220f)
+    ((?+ ?Z) . ?\x2211)
+    ((?- ?2) . ?\x2212)
+    ((?- ?+) . ?\x2213)
+    ((?* ?-) . ?\x2217)
+    ((?O ?b) . ?\x2218)
+    ((?S ?b) . ?\x2219)
+    ((?R ?T) . ?\x221a)
+    ((?0 ?\() . ?\x221d)
+    ((?0 ?0) . ?\x221e)
+    ((?- ?L) . ?\x221f)
+    ((?- ?V) . ?\x2220)
+    ((?P ?P) . ?\x2225)
+    ((?A ?N) . ?\x2227)
+    ((?O ?R) . ?\x2228)
+    ((?\( ?U) . ?\x2229)
+    ((?\) ?U) . ?\x222a)
+    ((?I ?n) . ?\x222b)
+    ((?D ?I) . ?\x222c)
+    ((?I ?o) . ?\x222e)
+    ((?. ?:) . ?\x2234)
+    ((?: ?.) . ?\x2235)
+    ((?: ?R) . ?\x2236)
+    ((?: ?:) . ?\x2237)
+    ((?? ?1) . ?\x223c)
+    ((?C ?G) . ?\x223e)
+    ((?? ?-) . ?\x2243)
+    ((?? ?=) . ?\x2245)
+    ((?? ?2) . ?\x2248)
+    ((?= ??) . ?\x224c)
+    ((?H ?I) . ?\x2253)
+    ((?! ?=) . ?\x2260)
+    ((?= ?3) . ?\x2261)
+    ((?= ?<) . ?\x2264)
+    ((?> ?=) . ?\x2265)
+    ((?< ?*) . ?\x226a)
+    ((?* ?>) . ?\x226b)
+    ((?! ?<) . ?\x226e)
+    ((?! ?>) . ?\x226f)
+    ((?\( ?C) . ?\x2282)
+    ((?\) ?C) . ?\x2283)
+    ((?\( ?_) . ?\x2286)
+    ((?\) ?_) . ?\x2287)
+    ((?0 ?.) . ?\x2299)
+    ((?0 ?2) . ?\x229a)
+    ((?- ?T) . ?\x22a5)
+    ((?. ?P) . ?\x22c5)
+    ((?: ?3) . ?\x22ee)
+    ((?. ?3) . ?\x22ef)
+    ((?E ?h) . ?\x2302)
+    ((?< ?7) . ?\x2308)
+    ((?> ?7) . ?\x2309)
+    ((?7 ?<) . ?\x230a)
+    ((?7 ?>) . ?\x230b)
+    ((?N ?I) . ?\x2310)
+    ((?\( ?A) . ?\x2312)
+    ((?T ?R) . ?\x2315)
+    ((?I ?u) . ?\x2320)
+    ((?I ?l) . ?\x2321)
+    ((?< ?/) . ?\x2329)
+    ((?/ ?>) . ?\x232a)
+    ((?V ?s) . ?\x2423)
+    ((?1 ?h) . ?\x2440)
+    ((?3 ?h) . ?\x2441)
+    ((?2 ?h) . ?\x2442)
+    ((?4 ?h) . ?\x2443)
+    ((?1 ?j) . ?\x2446)
+    ((?2 ?j) . ?\x2447)
+    ((?3 ?j) . ?\x2448)
+    ((?4 ?j) . ?\x2449)
+    ((?1 ?.) . ?\x2488)
+    ((?2 ?.) . ?\x2489)
+    ((?3 ?.) . ?\x248a)
+    ((?4 ?.) . ?\x248b)
+    ((?5 ?.) . ?\x248c)
+    ((?6 ?.) . ?\x248d)
+    ((?7 ?.) . ?\x248e)
+    ((?8 ?.) . ?\x248f)
+    ((?9 ?.) . ?\x2490)
+    ((?h ?h) . ?\x2500)
+    ((?H ?H) . ?\x2501)
+    ((?v ?v) . ?\x2502)
+    ((?V ?V) . ?\x2503)
+    ((?3 ?-) . ?\x2504)
+    ((?3 ?_) . ?\x2505)
+    ((?3 ?!) . ?\x2506)
+    ((?3 ?/) . ?\x2507)
+    ((?4 ?-) . ?\x2508)
+    ((?4 ?_) . ?\x2509)
+    ((?4 ?!) . ?\x250a)
+    ((?4 ?/) . ?\x250b)
+    ((?d ?r) . ?\x250c)
+    ((?d ?R) . ?\x250d)
+    ((?D ?r) . ?\x250e)
+    ((?D ?R) . ?\x250f)
+    ((?d ?l) . ?\x2510)
+    ((?d ?L) . ?\x2511)
+    ((?D ?l) . ?\x2512)
+    ((?L ?D) . ?\x2513)
+    ((?u ?r) . ?\x2514)
+    ((?u ?R) . ?\x2515)
+    ((?U ?r) . ?\x2516)
+    ((?U ?R) . ?\x2517)
+    ((?u ?l) . ?\x2518)
+    ((?u ?L) . ?\x2519)
+    ((?U ?l) . ?\x251a)
+    ((?U ?L) . ?\x251b)
+    ((?v ?r) . ?\x251c)
+    ((?v ?R) . ?\x251d)
+    ((?V ?r) . ?\x2520)
+    ((?V ?R) . ?\x2523)
+    ((?v ?l) . ?\x2524)
+    ((?v ?L) . ?\x2525)
+    ((?V ?l) . ?\x2528)
+    ((?V ?L) . ?\x252b)
+    ((?d ?h) . ?\x252c)
+    ((?d ?H) . ?\x252f)
+    ((?D ?h) . ?\x2530)
+    ((?D ?H) . ?\x2533)
+    ((?u ?h) . ?\x2534)
+    ((?u ?H) . ?\x2537)
+    ((?U ?h) . ?\x2538)
+    ((?U ?H) . ?\x253b)
+    ((?v ?h) . ?\x253c)
+    ((?v ?H) . ?\x253f)
+    ((?V ?h) . ?\x2542)
+    ((?V ?H) . ?\x254b)
+    ((?F ?D) . ?\x2571)
+    ((?B ?D) . ?\x2572)
+    ((?T ?B) . ?\x2580)
+    ((?L ?B) . ?\x2584)
+    ((?F ?B) . ?\x2588)
+    ((?l ?B) . ?\x258c)
+    ((?R ?B) . ?\x2590)
+    ((?. ?S) . ?\x2591)
+    ((?: ?S) . ?\x2592)
+    ((?? ?S) . ?\x2593)
+    ((?f ?S) . ?\x25a0)
+    ((?O ?S) . ?\x25a1)
+    ((?R ?O) . ?\x25a2)
+    ((?R ?r) . ?\x25a3)
+    ((?R ?F) . ?\x25a4)
+    ((?R ?Y) . ?\x25a5)
+    ((?R ?H) . ?\x25a6)
+    ((?R ?Z) . ?\x25a7)
+    ((?R ?K) . ?\x25a8)
+    ((?R ?X) . ?\x25a9)
+    ((?s ?B) . ?\x25aa)
+    ((?S ?R) . ?\x25ac)
+    ((?O ?r) . ?\x25ad)
+    ((?U ?T) . ?\x25b2)
+    ((?u ?T) . ?\x25b3)
+    ((?P ?R) . ?\x25b6)
+    ((?T ?r) . ?\x25b7)
+    ((?D ?t) . ?\x25bc)
+    ((?d ?T) . ?\x25bd)
+    ((?P ?L) . ?\x25c0)
+    ((?T ?l) . ?\x25c1)
+    ((?D ?b) . ?\x25c6)
+    ((?D ?w) . ?\x25c7)
+    ((?L ?Z) . ?\x25ca)
+    ((?0 ?m) . ?\x25cb)
+    ((?0 ?o) . ?\x25ce)
+    ((?0 ?M) . ?\x25cf)
+    ((?0 ?L) . ?\x25d0)
+    ((?0 ?R) . ?\x25d1)
+    ((?S ?n) . ?\x25d8)
+    ((?I ?c) . ?\x25d9)
+    ((?F ?d) . ?\x25e2)
+    ((?B ?d) . ?\x25e3)
+    ((?* ?2) . ?\x2605)
+    ((?* ?1) . ?\x2606)
+    ((?< ?H) . ?\x261c)
+    ((?> ?H) . ?\x261e)
+    ((?0 ?u) . ?\x263a)
+    ((?0 ?U) . ?\x263b)
+    ((?S ?U) . ?\x263c)
+    ((?F ?m) . ?\x2640)
+    ((?M ?l) . ?\x2642)
+    ((?c ?S) . ?\x2660)
+    ((?c ?H) . ?\x2661)
+    ((?c ?D) . ?\x2662)
+    ((?c ?C) . ?\x2663)
+    ((?M ?d) . ?\x2669)
+    ((?M ?8) . ?\x266a)
+    ((?M ?2) . ?\x266b)
+    ((?M ?b) . ?\x266d)
+    ((?M ?x) . ?\x266e)
+    ((?M ?X) . ?\x266f)
+    ((?O ?K) . ?\x2713)
+    ((?X ?X) . ?\x2717)
+    ((?- ?X) . ?\x2720)
+    ((?I ?S) . ?\x3000)
+    ((?, ?_) . ?\x3001)
+    ((?. ?_) . ?\x3002)
+    ((?+ ?\") . ?\x3003)
+    ((?+ ?_) . ?\x3004)
+    ((?* ?_) . ?\x3005)
+    ((?\; ?_) . ?\x3006)
+    ((?0 ?_) . ?\x3007)
+    ((?< ?+) . ?\x300a)
+    ((?> ?+) . ?\x300b)
+    ((?< ?') . ?\x300c)
+    ((?> ?') . ?\x300d)
+    ((?< ?\") . ?\x300e)
+    ((?> ?\") . ?\x300f)
+    ((?\( ?\") . ?\x3010)
+    ((?\) ?\") . ?\x3011)
+    ((?= ?T) . ?\x3012)
+    ((?= ?_) . ?\x3013)
+    ((?\( ?') . ?\x3014)
+    ((?\) ?') . ?\x3015)
+    ((?\( ?I) . ?\x3016)
+    ((?\) ?I) . ?\x3017)
+    ((?- ??) . ?\x301c)
+    ((?A ?5) . ?\x3041)
+    ((?a ?5) . ?\x3042)
+    ((?I ?5) . ?\x3043)
+    ((?i ?5) . ?\x3044)
+    ((?U ?5) . ?\x3045)
+    ((?u ?5) . ?\x3046)
+    ((?E ?5) . ?\x3047)
+    ((?e ?5) . ?\x3048)
+    ((?O ?5) . ?\x3049)
+    ((?o ?5) . ?\x304a)
+    ((?k ?a) . ?\x304b)
+    ((?g ?a) . ?\x304c)
+    ((?k ?i) . ?\x304d)
+    ((?g ?i) . ?\x304e)
+    ((?k ?u) . ?\x304f)
+    ((?g ?u) . ?\x3050)
+    ((?k ?e) . ?\x3051)
+    ((?g ?e) . ?\x3052)
+    ((?k ?o) . ?\x3053)
+    ((?g ?o) . ?\x3054)
+    ((?s ?a) . ?\x3055)
+    ((?z ?a) . ?\x3056)
+    ((?s ?i) . ?\x3057)
+    ((?z ?i) . ?\x3058)
+    ((?s ?u) . ?\x3059)
+    ((?z ?u) . ?\x305a)
+    ((?s ?e) . ?\x305b)
+    ((?z ?e) . ?\x305c)
+    ((?s ?o) . ?\x305d)
+    ((?z ?o) . ?\x305e)
+    ((?t ?a) . ?\x305f)
+    ((?d ?a) . ?\x3060)
+    ((?t ?i) . ?\x3061)
+    ((?d ?i) . ?\x3062)
+    ((?t ?U) . ?\x3063)
+    ((?t ?u) . ?\x3064)
+    ((?d ?u) . ?\x3065)
+    ((?t ?e) . ?\x3066)
+    ((?d ?e) . ?\x3067)
+    ((?t ?o) . ?\x3068)
+    ((?d ?o) . ?\x3069)
+    ((?n ?a) . ?\x306a)
+    ((?n ?i) . ?\x306b)
+    ((?n ?u) . ?\x306c)
+    ((?n ?e) . ?\x306d)
+    ((?n ?o) . ?\x306e)
+    ((?h ?a) . ?\x306f)
+    ((?b ?a) . ?\x3070)
+    ((?p ?a) . ?\x3071)
+    ((?h ?i) . ?\x3072)
+    ((?b ?i) . ?\x3073)
+    ((?p ?i) . ?\x3074)
+    ((?h ?u) . ?\x3075)
+    ((?b ?u) . ?\x3076)
+    ((?p ?u) . ?\x3077)
+    ((?h ?e) . ?\x3078)
+    ((?b ?e) . ?\x3079)
+    ((?p ?e) . ?\x307a)
+    ((?h ?o) . ?\x307b)
+    ((?b ?o) . ?\x307c)
+    ((?p ?o) . ?\x307d)
+    ((?m ?a) . ?\x307e)
+    ((?m ?i) . ?\x307f)
+    ((?m ?u) . ?\x3080)
+    ((?m ?e) . ?\x3081)
+    ((?m ?o) . ?\x3082)
+    ((?y ?A) . ?\x3083)
+    ((?y ?a) . ?\x3084)
+    ((?y ?U) . ?\x3085)
+    ((?y ?u) . ?\x3086)
+    ((?y ?O) . ?\x3087)
+    ((?y ?o) . ?\x3088)
+    ((?r ?a) . ?\x3089)
+    ((?r ?i) . ?\x308a)
+    ((?r ?u) . ?\x308b)
+    ((?r ?e) . ?\x308c)
+    ((?r ?o) . ?\x308d)
+    ((?w ?A) . ?\x308e)
+    ((?w ?a) . ?\x308f)
+    ((?w ?i) . ?\x3090)
+    ((?w ?e) . ?\x3091)
+    ((?w ?o) . ?\x3092)
+    ((?n ?5) . ?\x3093)
+    ((?v ?u) . ?\x3094)
+    ((?\" ?5) . ?\x309b)
+    ((?0 ?5) . ?\x309c)
+    ((?* ?5) . ?\x309d)
+    ((?+ ?5) . ?\x309e)
+    ((?a ?6) . ?\x30a1)
+    ((?A ?6) . ?\x30a2)
+    ((?i ?6) . ?\x30a3)
+    ((?I ?6) . ?\x30a4)
+    ((?u ?6) . ?\x30a5)
+    ((?U ?6) . ?\x30a6)
+    ((?e ?6) . ?\x30a7)
+    ((?E ?6) . ?\x30a8)
+    ((?o ?6) . ?\x30a9)
+    ((?O ?6) . ?\x30aa)
+    ((?K ?a) . ?\x30ab)
+    ((?G ?a) . ?\x30ac)
+    ((?K ?i) . ?\x30ad)
+    ((?G ?i) . ?\x30ae)
+    ((?K ?u) . ?\x30af)
+    ((?G ?u) . ?\x30b0)
+    ((?K ?e) . ?\x30b1)
+    ((?G ?e) . ?\x30b2)
+    ((?K ?o) . ?\x30b3)
+    ((?G ?o) . ?\x30b4)
+    ((?S ?a) . ?\x30b5)
+    ((?Z ?a) . ?\x30b6)
+    ((?S ?i) . ?\x30b7)
+    ((?Z ?i) . ?\x30b8)
+    ((?S ?u) . ?\x30b9)
+    ((?Z ?u) . ?\x30ba)
+    ((?S ?e) . ?\x30bb)
+    ((?Z ?e) . ?\x30bc)
+    ((?S ?o) . ?\x30bd)
+    ((?Z ?o) . ?\x30be)
+    ((?T ?a) . ?\x30bf)
+    ((?D ?a) . ?\x30c0)
+    ((?T ?i) . ?\x30c1)
+    ((?D ?i) . ?\x30c2)
+    ((?T ?U) . ?\x30c3)
+    ((?T ?u) . ?\x30c4)
+    ((?D ?u) . ?\x30c5)
+    ((?T ?e) . ?\x30c6)
+    ((?D ?e) . ?\x30c7)
+    ((?T ?o) . ?\x30c8)
+    ((?D ?o) . ?\x30c9)
+    ((?N ?a) . ?\x30ca)
+    ((?N ?i) . ?\x30cb)
+    ((?N ?u) . ?\x30cc)
+    ((?N ?e) . ?\x30cd)
+    ((?N ?o) . ?\x30ce)
+    ((?H ?a) . ?\x30cf)
+    ((?B ?a) . ?\x30d0)
+    ((?P ?a) . ?\x30d1)
+    ((?H ?i) . ?\x30d2)
+    ((?B ?i) . ?\x30d3)
+    ((?P ?i) . ?\x30d4)
+    ((?H ?u) . ?\x30d5)
+    ((?B ?u) . ?\x30d6)
+    ((?P ?u) . ?\x30d7)
+    ((?H ?e) . ?\x30d8)
+    ((?B ?e) . ?\x30d9)
+    ((?P ?e) . ?\x30da)
+    ((?H ?o) . ?\x30db)
+    ((?B ?o) . ?\x30dc)
+    ((?P ?o) . ?\x30dd)
+    ((?u ?R) . ?\x2515)
+    ((?U ?r) . ?\x2516)
+    ((?U ?R) . ?\x2517)
+    ((?u ?l) . ?\x2518)
+    ((?u ?L) . ?\x2519)
+    ((?U ?l) . ?\x251a)
+    ((?U ?L) . ?\x251b)
+    ((?v ?r) . ?\x251c)
+    ((?v ?R) . ?\x251d)
+    ((?V ?r) . ?\x2520)
+    ((?V ?R) . ?\x2523)
+    ((?v ?l) . ?\x2524)
+    ((?v ?L) . ?\x2525)
+    ((?V ?l) . ?\x2528)
+    ((?V ?L) . ?\x252b)
+    ((?d ?h) . ?\x252c)
+    ((?d ?H) . ?\x252f)
+    ((?D ?h) . ?\x2530)
+    ((?D ?H) . ?\x2533)
+    ((?u ?h) . ?\x2534)
+    ((?u ?H) . ?\x2537)
+    ((?U ?h) . ?\x2538)
+    ((?U ?H) . ?\x253b)
+    ((?v ?h) . ?\x253c)
+    ((?v ?H) . ?\x253f)
+    ((?V ?h) . ?\x2542)
+    ((?V ?H) . ?\x254b)
+    ((?F ?D) . ?\x2571)
+    ((?B ?D) . ?\x2572)
+    ((?T ?B) . ?\x2580)
+    ((?L ?B) . ?\x2584)
+    ((?F ?B) . ?\x2588)
+    ((?l ?B) . ?\x258c)
+    ((?R ?B) . ?\x2590)
+    ((?. ?S) . ?\x2591)
+    ((?: ?S) . ?\x2592)
+    ((?? ?S) . ?\x2593)
+    ((?f ?S) . ?\x25a0)
+    ((?O ?S) . ?\x25a1)
+    ((?R ?O) . ?\x25a2)
+    ((?R ?r) . ?\x25a3)
+    ((?R ?F) . ?\x25a4)
+    ((?R ?Y) . ?\x25a5)
+    ((?R ?H) . ?\x25a6)
+    ((?R ?Z) . ?\x25a7)
+    ((?R ?K) . ?\x25a8)
+    ((?R ?X) . ?\x25a9)
+    ((?s ?B) . ?\x25aa)
+    ((?S ?R) . ?\x25ac)
+    ((?O ?r) . ?\x25ad)
+    ((?U ?T) . ?\x25b2)
+    ((?u ?T) . ?\x25b3)
+    ((?P ?R) . ?\x25b6)
+    ((?T ?r) . ?\x25b7)
+    ((?D ?t) . ?\x25bc)
+    ((?d ?T) . ?\x25bd)
+    ((?P ?L) . ?\x25c0)
+    ((?T ?l) . ?\x25c1)
+    ((?D ?b) . ?\x25c6)
+    ((?D ?w) . ?\x25c7)
+    ((?L ?Z) . ?\x25ca)
+    ((?0 ?m) . ?\x25cb)
+    ((?0 ?o) . ?\x25ce)
+    ((?0 ?M) . ?\x25cf)
+    ((?0 ?L) . ?\x25d0)
+    ((?0 ?R) . ?\x25d1)
+    ((?S ?n) . ?\x25d8)
+    ((?I ?c) . ?\x25d9)
+    ((?F ?d) . ?\x25e2)
+    ((?B ?d) . ?\x25e3)
+    ((?* ?2) . ?\x2605)
+    ((?* ?1) . ?\x2606)
+    ((?< ?H) . ?\x261c)
+    ((?> ?H) . ?\x261e)
+    ((?0 ?u) . ?\x263a)
+    ((?0 ?U) . ?\x263b)
+    ((?S ?U) . ?\x263c)
+    ((?F ?m) . ?\x2640)
+    ((?M ?l) . ?\x2642)
+    ((?c ?S) . ?\x2660)
+    ((?c ?H) . ?\x2661)
+    ((?c ?D) . ?\x2662)
+    ((?c ?C) . ?\x2663)
+    ((?M ?d) . ?\x2669)
+    ((?M ?8) . ?\x266a)
+    ((?M ?2) . ?\x266b)
+    ((?M ?b) . ?\x266d)
+    ((?M ?x) . ?\x266e)
+    ((?M ?X) . ?\x266f)
+    ((?O ?K) . ?\x2713)
+    ((?X ?X) . ?\x2717)
+    ((?- ?X) . ?\x2720)
+    ((?I ?S) . ?\x3000)
+    ((?, ?_) . ?\x3001)
+    ((?. ?_) . ?\x3002)
+    ((?+ ?\") . ?\x3003)
+    ((?+ ?_) . ?\x3004)
+    ((?* ?_) . ?\x3005)
+    ((?\; ?_) . ?\x3006)
+    ((?0 ?_) . ?\x3007)
+    ((?< ?+) . ?\x300a)
+    ((?> ?+) . ?\x300b)
+    ((?< ?') . ?\x300c)
+    ((?> ?') . ?\x300d)
+    ((?< ?\") . ?\x300e)
+    ((?> ?\") . ?\x300f)
+    ((?\( ?\") . ?\x3010)
+    ((?\) ?\") . ?\x3011)
+    ((?= ?T) . ?\x3012)
+    ((?= ?_) . ?\x3013)
+    ((?\( ?') . ?\x3014)
+    ((?\) ?') . ?\x3015)
+    ((?\( ?I) . ?\x3016)
+    ((?\) ?I) . ?\x3017)
+    ((?- ??) . ?\x301c)
+    ((?A ?5) . ?\x3041)
+    ((?a ?5) . ?\x3042)
+    ((?I ?5) . ?\x3043)
+    ((?i ?5) . ?\x3044)
+    ((?U ?5) . ?\x3045)
+    ((?u ?5) . ?\x3046)
+    ((?E ?5) . ?\x3047)
+    ((?e ?5) . ?\x3048)
+    ((?O ?5) . ?\x3049)
+    ((?o ?5) . ?\x304a)
+    ((?k ?a) . ?\x304b)
+    ((?g ?a) . ?\x304c)
+    ((?k ?i) . ?\x304d)
+    ((?g ?i) . ?\x304e)
+    ((?k ?u) . ?\x304f)
+    ((?g ?u) . ?\x3050)
+    ((?k ?e) . ?\x3051)
+    ((?g ?e) . ?\x3052)
+    ((?k ?o) . ?\x3053)
+    ((?g ?o) . ?\x3054)
+    ((?s ?a) . ?\x3055)
+    ((?z ?a) . ?\x3056)
+    ((?s ?i) . ?\x3057)
+    ((?z ?i) . ?\x3058)
+    ((?s ?u) . ?\x3059)
+    ((?z ?u) . ?\x305a)
+    ((?s ?e) . ?\x305b)
+    ((?z ?e) . ?\x305c)
+    ((?s ?o) . ?\x305d)
+    ((?z ?o) . ?\x305e)
+    ((?t ?a) . ?\x305f)
+    ((?d ?a) . ?\x3060)
+    ((?t ?i) . ?\x3061)
+    ((?d ?i) . ?\x3062)
+    ((?t ?U) . ?\x3063)
+    ((?t ?u) . ?\x3064)
+    ((?d ?u) . ?\x3065)
+    ((?t ?e) . ?\x3066)
+    ((?d ?e) . ?\x3067)
+    ((?t ?o) . ?\x3068)
+    ((?d ?o) . ?\x3069)
+    ((?n ?a) . ?\x306a)
+    ((?n ?i) . ?\x306b)
+    ((?n ?u) . ?\x306c)
+    ((?n ?e) . ?\x306d)
+    ((?n ?o) . ?\x306e)
+    ((?h ?a) . ?\x306f)
+    ((?b ?a) . ?\x3070)
+    ((?p ?a) . ?\x3071)
+    ((?h ?i) . ?\x3072)
+    ((?b ?i) . ?\x3073)
+    ((?p ?i) . ?\x3074)
+    ((?h ?u) . ?\x3075)
+    ((?b ?u) . ?\x3076)
+    ((?p ?u) . ?\x3077)
+    ((?h ?e) . ?\x3078)
+    ((?b ?e) . ?\x3079)
+    ((?p ?e) . ?\x307a)
+    ((?h ?o) . ?\x307b)
+    ((?b ?o) . ?\x307c)
+    ((?p ?o) . ?\x307d)
+    ((?m ?a) . ?\x307e)
+    ((?m ?i) . ?\x307f)
+    ((?m ?u) . ?\x3080)
+    ((?m ?e) . ?\x3081)
+    ((?m ?o) . ?\x3082)
+    ((?y ?A) . ?\x3083)
+    ((?y ?a) . ?\x3084)
+    ((?y ?U) . ?\x3085)
+    ((?y ?u) . ?\x3086)
+    ((?y ?O) . ?\x3087)
+    ((?y ?o) . ?\x3088)
+    ((?r ?a) . ?\x3089)
+    ((?r ?i) . ?\x308a)
+    ((?r ?u) . ?\x308b)
+    ((?r ?e) . ?\x308c)
+    ((?r ?o) . ?\x308d)
+    ((?w ?A) . ?\x308e)
+    ((?w ?a) . ?\x308f)
+    ((?w ?i) . ?\x3090)
+    ((?w ?e) . ?\x3091)
+    ((?w ?o) . ?\x3092)
+    ((?n ?5) . ?\x3093)
+    ((?v ?u) . ?\x3094)
+    ((?\" ?5) . ?\x309b)
+    ((?0 ?5) . ?\x309c)
+    ((?* ?5) . ?\x309d)
+    ((?+ ?5) . ?\x309e)
+    ((?a ?6) . ?\x30a1)
+    ((?A ?6) . ?\x30a2)
+    ((?i ?6) . ?\x30a3)
+    ((?I ?6) . ?\x30a4)
+    ((?u ?6) . ?\x30a5)
+    ((?U ?6) . ?\x30a6)
+    ((?e ?6) . ?\x30a7)
+    ((?E ?6) . ?\x30a8)
+    ((?o ?6) . ?\x30a9)
+    ((?O ?6) . ?\x30aa)
+    ((?K ?a) . ?\x30ab)
+    ((?G ?a) . ?\x30ac)
+    ((?K ?i) . ?\x30ad)
+    ((?G ?i) . ?\x30ae)
+    ((?K ?u) . ?\x30af)
+    ((?G ?u) . ?\x30b0)
+    ((?K ?e) . ?\x30b1)
+    ((?G ?e) . ?\x30b2)
+    ((?K ?o) . ?\x30b3)
+    ((?G ?o) . ?\x30b4)
+    ((?S ?a) . ?\x30b5)
+    ((?Z ?a) . ?\x30b6)
+    ((?S ?i) . ?\x30b7)
+    ((?Z ?i) . ?\x30b8)
+    ((?S ?u) . ?\x30b9)
+    ((?Z ?u) . ?\x30ba)
+    ((?S ?e) . ?\x30bb)
+    ((?Z ?e) . ?\x30bc)
+    ((?S ?o) . ?\x30bd)
+    ((?Z ?o) . ?\x30be)
+    ((?T ?a) . ?\x30bf)
+    ((?D ?a) . ?\x30c0)
+    ((?T ?i) . ?\x30c1)
+    ((?D ?i) . ?\x30c2)
+    ((?T ?U) . ?\x30c3)
+    ((?T ?u) . ?\x30c4)
+    ((?D ?u) . ?\x30c5)
+    ((?T ?e) . ?\x30c6)
+    ((?D ?e) . ?\x30c7)
+    ((?T ?o) . ?\x30c8)
+    ((?D ?o) . ?\x30c9)
+    ((?N ?a) . ?\x30ca)
+    ((?N ?i) . ?\x30cb)
+    ((?N ?u) . ?\x30cc)
+    ((?N ?e) . ?\x30cd)
+    ((?N ?o) . ?\x30ce)
+    ((?H ?a) . ?\x30cf)
+    ((?B ?a) . ?\x30d0)
+    ((?P ?a) . ?\x30d1)
+    ((?H ?i) . ?\x30d2)
+    ((?B ?i) . ?\x30d3)
+    ((?P ?i) . ?\x30d4)
+    ((?H ?u) . ?\x30d5)
+    ((?B ?u) . ?\x30d6)
+    ((?P ?u) . ?\x30d7)
+    ((?H ?e) . ?\x30d8)
+    ((?B ?e) . ?\x30d9)
+    ((?P ?e) . ?\x30da)
+    ((?H ?o) . ?\x30db)
+    ((?B ?o) . ?\x30dc)
+    ((?P ?o) . ?\x30dd)
+    ((?M ?a) . ?\x30de)
+    ((?M ?i) . ?\x30df)
+    ((?M ?u) . ?\x30e0)
+    ((?M ?e) . ?\x30e1)
+    ((?M ?o) . ?\x30e2)
+    ((?Y ?A) . ?\x30e3)
+    ((?Y ?a) . ?\x30e4)
+    ((?Y ?U) . ?\x30e5)
+    ((?Y ?u) . ?\x30e6)
+    ((?Y ?O) . ?\x30e7)
+    ((?Y ?o) . ?\x30e8)
+    ((?R ?a) . ?\x30e9)
+    ((?R ?i) . ?\x30ea)
+    ((?R ?u) . ?\x30eb)
+    ((?R ?e) . ?\x30ec)
+    ((?R ?o) . ?\x30ed)
+    ((?W ?A) . ?\x30ee)
+    ((?W ?a) . ?\x30ef)
+    ((?W ?i) . ?\x30f0)
+    ((?W ?e) . ?\x30f1)
+    ((?W ?o) . ?\x30f2)
+    ((?N ?6) . ?\x30f3)
+    ((?V ?u) . ?\x30f4)
+    ((?K ?A) . ?\x30f5)
+    ((?K ?E) . ?\x30f6)
+    ((?V ?a) . ?\x30f7)
+    ((?V ?i) . ?\x30f8)
+    ((?V ?e) . ?\x30f9)
+    ((?V ?o) . ?\x30fa)
+    ((?. ?6) . ?\x30fb)
+    ((?- ?6) . ?\x30fc)
+    ((?* ?6) . ?\x30fd)
+    ((?+ ?6) . ?\x30fe)
+    ((?b ?4) . ?\x3105)
+    ((?p ?4) . ?\x3106)
+    ((?m ?4) . ?\x3107)
+    ((?f ?4) . ?\x3108)
+    ((?d ?4) . ?\x3109)
+    ((?t ?4) . ?\x310a)
+    ((?n ?4) . ?\x310b)
+    ((?l ?4) . ?\x310c)
+    ((?g ?4) . ?\x310d)
+    ((?k ?4) . ?\x310e)
+    ((?h ?4) . ?\x310f)
+    ((?j ?4) . ?\x3110)
+    ((?q ?4) . ?\x3111)
+    ((?x ?4) . ?\x3112)
+    ((?z ?h) . ?\x3113)
+    ((?c ?h) . ?\x3114)
+    ((?s ?h) . ?\x3115)
+    ((?r ?4) . ?\x3116)
+    ((?z ?4) . ?\x3117)
+    ((?c ?4) . ?\x3118)
+    ((?s ?4) . ?\x3119)
+    ((?a ?4) . ?\x311a)
+    ((?o ?4) . ?\x311b)
+    ((?e ?4) . ?\x311c)
+    ((?a ?i) . ?\x311e)
+    ((?e ?i) . ?\x311f)
+    ((?a ?u) . ?\x3120)
+    ((?o ?u) . ?\x3121)
+    ((?a ?n) . ?\x3122)
+    ((?e ?n) . ?\x3123)
+    ((?a ?N) . ?\x3124)
+    ((?e ?N) . ?\x3125)
+    ((?e ?r) . ?\x3126)
+    ((?i ?4) . ?\x3127)
+    ((?u ?4) . ?\x3128)
+    ((?i ?u) . ?\x3129)
+    ((?v ?4) . ?\x312a)
+    ((?n ?G) . ?\x312b)
+    ((?g ?n) . ?\x312c)
+    ((?1 ?c) . ?\x3220)
+    ((?2 ?c) . ?\x3221)
+    ((?3 ?c) . ?\x3222)
+    ((?4 ?c) . ?\x3223)
+    ((?5 ?c) . ?\x3224)
+    ((?6 ?c) . ?\x3225)
+    ((?7 ?c) . ?\x3226)
+    ((?8 ?c) . ?\x3227)
+    ((?9 ?c) . ?\x3228)
+    ((?\s ?\s) . ?\xe000)
+    ((?/ ?c) . ?\xe001)
+    ((?U ?A) . ?\xe002)
+    ((?U ?B) . ?\xe003)
+    ((?\" ?3) . ?\xe004)
+    ((?\" ?1) . ?\xe005)
+    ((?\" ?!) . ?\xe006)
+    ((?\" ?') . ?\xe007)
+    ((?\" ?>) . ?\xe008)
+    ((?\" ??) . ?\xe009)
+    ((?\" ?-) . ?\xe00a)
+    ((?\" ?\() . ?\xe00b)
+    ((?\" ?.) . ?\xe00c)
+    ((?\" ?:) . ?\xe00d)
+    ((?\" ?0) . ?\xe00e)
+    ((?\" ?\") . ?\xe00f)
+    ((?\" ?<) . ?\xe010)
+    ((?\" ?,) . ?\xe011)
+    ((?\" ?\;) . ?\xe012)
+    ((?\" ?_) . ?\xe013)
+    ((?\" ?=) . ?\xe014)
+    ((?\" ?/) . ?\xe015)
+    ((?\" ?i) . ?\xe016)
+    ((?\" ?d) . ?\xe017)
+    ((?\" ?p) . ?\xe018)
+    ((?\; ?\;) . ?\xe019)
+    ((?, ?,) . ?\xe01a)
+    ((?b ?3) . ?\xe01b)
+    ((?C ?i) . ?\xe01c)
+    ((?f ?\() . ?\xe01d)
+    ((?e ?d) . ?\xe01e)
+    ((?a ?m) . ?\xe01f)
+    ((?p ?m) . ?\xe020)
+    ((?F ?l) . ?\xe023)
+    ((?G ?F) . ?\xe024)
+    ((?> ?V) . ?\xe025)
+    ((?! ?*) . ?\xe026)
+    ((?? ?*) . ?\xe027)
+    ((?J ?<) . ?\xe028)
+    ((?f ?f) . ?\xfb00)
+    ((?f ?i) . ?\xfb01)
+    ((?f ?l) . ?\xfb02)
+    ((?f ?t) . ?\xfb05)
+    ((?s ?t) . ?\xfb06)
+    ((?~ ?!) . ?\x00a1)
+    ((?c ?|) . ?\x00a2)
+    ((?$ ?$) . ?\x00a3)
+    ((?o ?x) . ?\x00a4)
+    ((?Y ?-) . ?\x00a5)
+    ((?| ?|) . ?\x00a6)
+    ((?c ?O) . ?\x00a9)
+    ((?- ?,) . ?\x00ac)
+    ((?- ?=) . ?\x00af)
+    ((?~ ?o) . ?\x00b0)
+    ((?2 ?2) . ?\x00b2)
+    ((?3 ?3) . ?\x00b3)
+    ((?p ?p) . ?\x00b6)
+    ((?~ ?.) . ?\x00b7)
+    ((?1 ?1) . ?\x00b9)
+    ((?~ ??) . ?\x00bf)
+    ((?A ?`) . ?\x00c0)
+    ((?A ?^) . ?\x00c2)
+    ((?A ?~) . ?\x00c3)
+    ((?A ?\") . ?\x00c4)
+    ((?A ?@) . ?\x00c5)
+    ((?E ?`) . ?\x00c8)
+    ((?E ?^) . ?\x00ca)
+    ((?E ?\") . ?\x00cb)
+    ((?I ?`) . ?\x00cc)
+    ((?I ?^) . ?\x00ce)
+    ((?I ?\") . ?\x00cf)
+    ((?N ?~) . ?\x00d1)
+    ((?O ?`) . ?\x00d2)
+    ((?O ?^) . ?\x00d4)
+    ((?O ?~) . ?\x00d5)
+    ((?/ ?\\) . ?\x00d7)
+    ((?U ?`) . ?\x00d9)
+    ((?U ?^) . ?\x00db)
+    ((?I ?p) . ?\x00de)
+    ((?a ?`) . ?\x00e0)
+    ((?a ?^) . ?\x00e2)
+    ((?a ?~) . ?\x00e3)
+    ((?a ?\") . ?\x00e4)
+    ((?a ?@) . ?\x00e5)
+    ((?e ?`) . ?\x00e8)
+    ((?e ?^) . ?\x00ea)
+    ((?e ?\") . ?\x00eb)
+    ((?i ?`) . ?\x00ec)
+    ((?i ?^) . ?\x00ee)
+    ((?n ?~) . ?\x00f1)
+    ((?o ?`) . ?\x00f2)
+    ((?o ?^) . ?\x00f4)
+    ((?o ?~) . ?\x00f5)
+    ((?u ?`) . ?\x00f9)
+    ((?u ?^) . ?\x00fb)
+    ((?y ?\") . ?\x00ff))
+  "Table of default digraphs.
+This includes all digraphs defined in RFC 1345,
+as well as miscellaneous digraphs for multi-byte characters.
+See also `evil-digraphs-table-user'.")
+
+(defun evil-digraph (digraph)
+  "Convert DIGRAPH to character or list representation.
+If DIGRAPH is a list (CHAR1 CHAR2), return the corresponding character;
+if DIGRAPH is a character, return the corresponding list.
+Searches in `evil-digraphs-table-user' and `evil-digraphs-table'."
+  (if (listp digraph)
+      (let* ((char1 (car digraph))
+             (char2 (cadr digraph)))
+        (or (cdr (assoc (list char1 char2) evil-digraphs-table-user))
+            (cdr (assoc (list char1 char2) evil-digraphs-table))
+            (unless (eq char1 char2)
+              (or (cdr (assoc (list char2 char1) evil-digraphs-table-user))
+                  (cdr (assoc (list char2 char1) evil-digraphs-table))))))
+    (or (car (rassoc digraph evil-digraphs-table-user))
+        (car (rassoc digraph evil-digraphs-table)))))
+
+(provide 'evil-digraphs)
+
+;;; evil-digraphs.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-digraphs.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-ex.el
@@ -0,0 +1,1157 @@
+;;; evil-ex.el --- Ex-mode
+
+;; Author: Frank Fischer <frank fischer at mathematik.tu-chemnitz.de>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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/>.
+
+;;; Commentary:
+
+;; Ex is implemented as an extensible minilanguage, whose grammar
+;; is stored in `evil-ex-grammar'.  Ex commands are defined with
+;; `evil-ex-define-cmd', which creates a binding from a string
+;; to an interactive function.  It is also possible to define key
+;; sequences which execute a command immediately when entered:
+;; such shortcuts go in `evil-ex-map'.
+;;
+;; To provide buffer and filename completion, as well as interactive
+;; feedback, Ex defines the concept of an argument handler, specified
+;; with `evil-ex-define-argument-type'.  In the case of the
+;; substitution command (":s/foo/bar"), the handler incrementally
+;; highlights matches in the buffer as the substitution is typed.
+
+(require 'evil-common)
+(require 'evil-states)
+(require 'shell)
+
+;;; Code:
+
+(defconst evil-ex-grammar
+  '((expression
+     (count command argument #'evil-ex-call-command)
+     ((\? range) command argument #'evil-ex-call-command)
+     (line #'evil-goto-line)
+     (sexp #'eval-expression))
+    (count
+     number)
+    (command #'evil-ex-parse-command)
+    (binding
+     "[~&*@<>=:]+\\|[[:alpha:]-]+\\|!")
+    (emacs-binding
+     "[[:alpha:]-][[:alnum:][:punct:]-]+")
+    (bang
+     (\? (! space) "!" #'$1))
+    (argument
+     ((\? space) (\? "\\(?:.\\|\n\\)+") #'$2))
+    (range
+     ("%" #'(evil-ex-full-range))
+     (line ";" line #'(let ((tmp1 $1))
+                        (save-excursion
+                          (goto-line tmp1)
+                          (evil-ex-range tmp1 $3))))
+     (line "," line #'(evil-ex-range $1 $3))
+     (line #'(evil-ex-range $1 nil))
+     ("`" "[-a-zA-Z_<>']" ",`" "[-a-zA-Z_<>']"
+      #'(evil-ex-char-marker-range $2 $4)))
+    (line
+     (base (\? offset) search (\? offset)
+           #'(let ((tmp (evil-ex-line $1 $2)))
+               (save-excursion
+                 (goto-line tmp)
+                 (evil-ex-line $3 $4))))
+     ((\? base) offset search (\? offset)
+      #'(let ((tmp (evil-ex-line $1 $2)))
+          (save-excursion
+            (goto-line tmp)
+            (evil-ex-line $3 $4))))
+     (base (\? offset) #'evil-ex-line)
+     ((\? base) offset #'evil-ex-line))
+    (base
+     number
+     marker
+     search
+     ("\\^" #'(evil-ex-first-line))
+     ("\\$" #'(evil-ex-last-line))
+     ("\\." #'(evil-ex-current-line)))
+    (offset
+     (+ signed-number #'+))
+    (marker
+     ("'" "[-a-zA-Z_<>']" #'(evil-ex-marker $2)))
+    (search
+     forward
+     backward
+     next
+     prev
+     subst)
+    (forward
+     ("/" "\\(?:[\\].\\|[^/,; ]\\)+" (! "/")
+      #'(evil-ex-re-fwd $2))
+     ("/" "\\(?:[\\].\\|[^/]\\)+" "/"
+      #'(evil-ex-re-fwd $2)))
+    (backward
+     ("\\?" "\\(?:[\\].\\|[^?,; ]\\)+" (! "\\?")
+      #'(evil-ex-re-bwd $2))
+     ("\\?" "\\(?:[\\].\\|[^?]\\)+" "\\?"
+      #'(evil-ex-re-bwd $2)))
+    (next
+     "\\\\/" #'(evil-ex-prev-search))
+    (prev
+     "\\\\\\?" #'(evil-ex-prev-search))
+    (subst
+     "\\\\&" #'(evil-ex-prev-search))
+    (signed-number
+     (sign (\? number) #'evil-ex-signed-number))
+    (sign
+     "\\+\\|-" #'intern)
+    (number
+     "[0-9]+" #'string-to-number)
+    (space
+     "[ ]+")
+    (sexp
+     "(.*)" #'(car-safe (read-from-string $1))))
+  "Grammar for Ex.
+An association list of syntactic symbols and their definitions.
+The first entry is the start symbol.  A symbol's definition may
+reference other symbols, but the grammar cannot contain
+left recursion.  See `evil-parser' for a detailed explanation
+of the syntax.")
+
+(defvar evil-ex-echo-overlay nil
+  "Overlay used for displaying info messages during ex.")
+
+(defun evil-ex-p ()
+  "Whether Ex is currently active."
+  (and evil-ex-current-buffer t))
+
+(evil-define-command evil-ex (&optional initial-input)
+  "Enter an Ex command.
+The ex command line is initialized with the value of
+INITIAL-INPUT. If the command is called interactively the initial
+input depends on the current state. If the current state is
+normal state and no count argument is given then the initial
+input is empty. If a prefix count is given the initial input is
+.,.+count. If the current state is visual state then the initial
+input is the visual region '<,'> or `<,`>. If the value of the
+global variable `evil-ex-initial-input' is non-nil, its content
+is appended to the line."
+  :keep-visual t
+  :repeat abort
+  (interactive
+   (list
+    (let ((s (concat
+              (cond
+               ((and (evil-visual-state-p)
+                     evil-ex-visual-char-range
+                     (memq (evil-visual-type) '(inclusive exclusive)))
+                "`<,`>")
+               ((evil-visual-state-p)
+                "'<,'>")
+               (current-prefix-arg
+                (let ((arg (prefix-numeric-value current-prefix-arg)))
+                  (cond ((< arg 0) (setq arg (1+ arg)))
+                        ((> arg 0) (setq arg (1- arg))))
+                  (if (= arg 0) '(".")
+                    (format ".,.%+d" arg)))))
+              evil-ex-initial-input)))
+      (and (> (length s) 0) s))))
+  (let ((evil-ex-current-buffer (current-buffer))
+        (evil-ex-previous-command (unless initial-input
+                                    (car-safe evil-ex-history)))
+        evil-ex-argument-handler
+        evil-ex-info-string
+        result)
+    (minibuffer-with-setup-hook
+        #'evil-ex-setup
+      (setq result
+            (read-from-minibuffer
+             ":"
+             (or initial-input
+                 (and evil-ex-previous-command
+                      (propertize evil-ex-previous-command 'face 'shadow)))
+             evil-ex-completion-map
+             nil
+             'evil-ex-history
+             evil-ex-previous-command
+             t)))
+    (evil-ex-execute result)))
+
+(defun evil-ex-execute (result)
+  "Execute RESULT as an ex command on `evil-ex-current-buffer'."
+  ;; empty input means repeating the previous command
+  (when (zerop (length result))
+    (setq result evil-ex-previous-command))
+  ;; parse data
+  (evil-ex-update nil nil nil result)
+  ;; execute command
+  (unless (zerop (length result))
+    (if evil-ex-expression
+        (eval evil-ex-expression)
+      (user-error "Ex: syntax error"))))
+
+(defun evil-ex-delete-backward-char ()
+  "Close the minibuffer if it is empty.
+Otherwise behaves like `delete-backward-char'."
+  (interactive)
+  (call-interactively
+   (if (zerop (length (minibuffer-contents)))
+       #'abort-recursive-edit
+     #'delete-backward-char)))
+
+(defun evil-ex-abort ()
+  "Cancel ex state when another buffer is selected."
+  (unless (minibufferp)
+    (abort-recursive-edit)))
+
+(defun evil-ex-setup ()
+  "Initialize Ex minibuffer.
+This function registers several hooks that are used for the
+interactive actions during ex state."
+  (add-hook 'post-command-hook #'evil-ex-abort)
+  (add-hook 'after-change-functions #'evil-ex-update nil t)
+  (add-hook 'minibuffer-exit-hook #'evil-ex-teardown)
+  (when evil-ex-previous-command
+    (add-hook 'pre-command-hook #'evil-ex-remove-default))
+  (remove-hook 'minibuffer-setup-hook #'evil-ex-setup)
+  (with-no-warnings
+    (make-variable-buffer-local 'completion-at-point-functions))
+  (setq completion-at-point-functions
+        '(evil-ex-command-completion-at-point
+          evil-ex-argument-completion-at-point)))
+(put 'evil-ex-setup 'permanent-local-hook t)
+
+(defun evil-ex-teardown ()
+  "Deinitialize Ex minibuffer.
+Clean up everything set up by `evil-ex-setup'."
+  (remove-hook 'post-command-hook #'evil-ex-abort)
+  (remove-hook 'minibuffer-exit-hook #'evil-ex-teardown)
+  (remove-hook 'after-change-functions #'evil-ex-update t)
+  (when evil-ex-argument-handler
+    (let ((runner (evil-ex-argument-handler-runner
+                   evil-ex-argument-handler)))
+      (when runner
+        (funcall runner 'stop)))))
+(put 'evil-ex-teardown 'permanent-local-hook t)
+
+(defun evil-ex-remove-default ()
+  "Remove the default text shown in the ex minibuffer.
+When ex starts, the previous command is shown enclosed in
+parenthesis. This function removes this text when the first key
+is pressed."
+  (when (and (not (eq this-command 'exit-minibuffer))
+             (/= (minibuffer-prompt-end) (point-max)))
+    (if (eq this-command 'evil-ex-delete-backward-char)
+        (setq this-command 'ignore))
+    (delete-minibuffer-contents))
+  (remove-hook 'pre-command-hook #'evil-ex-remove-default))
+(put 'evil-ex-remove-default 'permanent-local-hook t)
+
+(defun evil-ex-update (&optional beg end len string)
+  "Update Ex variables when the minibuffer changes.
+This function is usually called from `after-change-functions'
+hook. If BEG is non-nil (which is the case when called from
+`after-change-functions'), then an error description is shown
+in case of incomplete or unknown commands."
+  (let* ((prompt (minibuffer-prompt-end))
+         (string (or string (buffer-substring prompt (point-max))))
+         arg bang cmd count expr func handler range tree type)
+    (cond
+     ((and (eq this-command #'self-insert-command)
+           (commandp (setq cmd (lookup-key evil-ex-map string))))
+      (setq evil-ex-expression `(call-interactively #',cmd))
+      (when (minibufferp)
+        (exit-minibuffer)))
+     (t
+      (setq cmd nil)
+      ;; store the buffer position of each character
+      ;; as the `ex-index' text property
+      (dotimes (i (length string))
+        (add-text-properties
+         i (1+ i) (list 'ex-index (+ i prompt)) string))
+      (with-current-buffer evil-ex-current-buffer
+        (setq tree (evil-ex-parse string t)
+              expr (evil-ex-parse string))
+        (when (eq (car-safe expr) 'evil-ex-call-command)
+          (setq count (eval (nth 1 expr))
+                cmd (eval (nth 2 expr))
+                arg (eval (nth 3 expr))
+                range (cond
+                       ((evil-range-p count)
+                        count)
+                       ((numberp count)
+                        (evil-ex-range count count)))
+                bang (and (save-match-data (string-match ".!$" cmd)) t))))
+      (setq evil-ex-tree tree
+            evil-ex-expression expr
+            evil-ex-range range
+            evil-ex-cmd cmd
+            evil-ex-bang bang
+            evil-ex-argument arg)
+      ;; test the current command
+      (when (and cmd (minibufferp))
+        (setq func (evil-ex-completed-binding cmd t))
+        (cond
+         ;; update argument-handler
+         (func
+          (when (setq type (evil-get-command-property
+                            func :ex-arg))
+            (setq handler (cdr-safe
+                           (assoc type
+                                  evil-ex-argument-types))))
+          (unless (eq handler evil-ex-argument-handler)
+            (let ((runner (and evil-ex-argument-handler
+                               (evil-ex-argument-handler-runner
+                                evil-ex-argument-handler))))
+              (when runner (funcall runner 'stop)))
+            (setq evil-ex-argument-handler handler)
+            (let ((runner (and evil-ex-argument-handler
+                               (evil-ex-argument-handler-runner
+                                evil-ex-argument-handler))))
+              (when runner (funcall runner 'start evil-ex-argument))))
+          (let ((runner (and evil-ex-argument-handler
+                             (evil-ex-argument-handler-runner
+                              evil-ex-argument-handler))))
+            (when runner (funcall runner 'update evil-ex-argument))))
+         (beg
+          ;; show error message only when called from `after-change-functions'
+          (let ((n (length (all-completions cmd (evil-ex-completion-table)))))
+            (cond
+             ((> n 1) (evil-ex-echo "Incomplete command"))
+             ((= n 0) (evil-ex-echo "Unknown command")))))))))))
+(put 'evil-ex-update 'permanent-local-hook t)
+
+(defun evil-ex-echo (string &rest args)
+  "Display a message after the current Ex command."
+  (with-selected-window (minibuffer-window)
+    (with-current-buffer (window-buffer (minibuffer-window))
+      (unless (or evil-no-display
+                  (zerop (length string)))
+        (let ((string (format " [%s]" (apply #'format string args)))
+              (ov (or evil-ex-echo-overlay
+                      (setq evil-ex-echo-overlay (make-overlay (point-min) (point-max) nil t t))))
+              after-change-functions before-change-functions)
+          (put-text-property 0 (length string) 'face 'evil-ex-info string)
+          ;; The following 'trick' causes point to be shown before the
+          ;; message instead behind. It is shamelessly stolen from the
+          ;; implementation of `minibuffer-message`.
+          (put-text-property 0 1 'cursor t string)
+          (move-overlay ov (point-max) (point-max))
+          (overlay-put ov 'after-string string)
+          (add-hook 'pre-command-hook #'evil--ex-remove-echo-overlay nil t))))))
+
+(defun evil--ex-remove-echo-overlay ()
+  "Remove echo overlay from ex minibuffer."
+  (when evil-ex-echo-overlay
+    (delete-overlay evil-ex-echo-overlay)
+    (setq evil-ex-echo-overlay nil))
+  (remove-hook 'pre-command-hook 'evil--ex-remove-echo-overlay t))
+
+(defun evil-ex-completion ()
+  "Completes the current ex command or argument."
+  (interactive)
+  (let (after-change-functions)
+    (evil-ex-update)
+    (completion-at-point)
+    (remove-text-properties (minibuffer-prompt-end) (point-max) '(face nil evil))))
+
+(defun evil-ex-command-completion-at-point ()
+  (let ((context (evil-ex-syntactic-context (1- (point)))))
+    (when (memq 'command context)
+      (let ((beg (or (get-text-property 0 'ex-index evil-ex-cmd)
+                     (point)))
+            (end (1+ (or (get-text-property (1- (length evil-ex-cmd))
+                                            'ex-index
+                                            evil-ex-cmd)
+                         (1- (point))))))
+        (list beg end (evil-ex-completion-table))))))
+
+(defun evil-ex-completion-table ()
+  (cond
+   ((eq evil-ex-complete-emacs-commands nil)
+    #'evil-ex-command-collection)
+   ((eq evil-ex-complete-emacs-commands 'in-turn)
+    (completion-table-in-turn
+     #'evil-ex-command-collection
+     #'(lambda (str pred flag)
+         (completion-table-with-predicate
+          obarray #'commandp t str pred flag))))
+   (t
+    #'(lambda (str pred flag)
+        (evil-completion-table-concat
+         #'evil-ex-command-collection
+         #'(lambda (str pred flag)
+             (completion-table-with-predicate
+              obarray #'commandp t str pred flag))
+         str pred flag)))))
+
+(defun evil-completion-table-concat (table1 table2 string pred flag)
+  (cond
+   ((eq flag nil)
+    (let ((result1 (try-completion string table1 pred))
+          (result2 (try-completion string table2 pred)))
+      (cond
+       ((null result1) result2)
+       ((null result2) result1)
+       ((and (eq result1 t) (eq result2 t)) t)
+       (t result1))))
+   ((eq flag t)
+    (delete-dups
+     (append (all-completions string table1 pred)
+             (all-completions string table2 pred))))
+   ((eq flag 'lambda)
+    (and (or (eq t (test-completion string table1 pred))
+             (eq t (test-completion string table2 pred)))
+         t))
+   ((eq (car-safe flag) 'boundaries)
+    (or (completion-boundaries string table1 pred (cdr flag))
+        (completion-boundaries string table2 pred (cdr flag))))
+   ((eq flag 'metadata)
+    '(metadata (display-sort-function . evil-ex-sort-completions)))))
+
+(defun evil-ex-sort-completions (completions)
+  (sort completions
+        #'(lambda (str1 str2)
+            (let ((p1 (eq 'evil-ex-commands (get-text-property 0 'face str1)))
+                  (p2 (eq 'evil-ex-commands (get-text-property 0 'face str2))))
+              (if (equal p1 p2)
+                  (string< str1 str2)
+                p1)))))
+
+(defun evil-ex-command-collection (cmd predicate flag)
+  "Called to complete a command."
+  (let (commands)
+    ;; append ! to all commands that may take a bang argument
+    (dolist (cmd (mapcar #'car evil-ex-commands))
+      (push cmd commands)
+      (if (evil-ex-command-force-p cmd)
+          (push (concat cmd "!") commands)))
+    (when (eq evil-ex-complete-emacs-commands t)
+      (setq commands
+            (mapcar #'(lambda (str) (propertize str 'face 'evil-ex-commands))
+                    commands)))
+    (cond
+     ((eq flag nil) (try-completion cmd commands predicate))
+     ((eq flag t) (all-completions cmd commands predicate))
+     ((eq flag 'lambda) (test-completion cmd commands))
+     ((eq (car-safe flag) 'boundaries)
+      `(boundaries 0 . ,(length (cdr flag)))))))
+
+(defun evil-ex-argument-completion-at-point ()
+  (let ((context (evil-ex-syntactic-context (1- (point)))))
+    (when (memq 'argument context)
+      (let* ((beg (or (and evil-ex-argument
+                           (get-text-property 0 'ex-index evil-ex-argument))
+                      (point)))
+             (end (1+ (or (and evil-ex-argument
+                               (get-text-property (1- (length evil-ex-argument))
+                                                  'ex-index
+                                                  evil-ex-argument))
+                          (1- (point)))))
+             (binding (evil-ex-completed-binding evil-ex-cmd))
+             (arg-type (evil-get-command-property binding :ex-arg))
+             (arg-handler (assoc arg-type evil-ex-argument-types))
+             (completer (and arg-handler
+                             (evil-ex-argument-handler-completer
+                              (cdr arg-handler)))))
+        (when completer
+          (if (eq (car completer) 'collection)
+              (list beg end (cdr completer))
+            (save-restriction
+              (narrow-to-region beg (point-max))
+              (funcall (cdr completer)))))))))
+
+(defun evil-ex-define-cmd (cmd function)
+  "Binds the function FUNCTION to the command CMD."
+  (save-match-data
+    (if (string-match "^[^][]*\\(\\[\\(.*\\)\\]\\)[^][]*$" cmd)
+        (let ((abbrev (replace-match "" nil t cmd 1))
+              (full (replace-match "\\2" nil nil cmd 1)))
+          (evil-add-to-alist 'evil-ex-commands full function)
+          (evil-add-to-alist 'evil-ex-commands abbrev full))
+      (evil-add-to-alist 'evil-ex-commands cmd function))))
+
+(defun evil-ex-make-argument-handler (runner completer)
+  (list runner completer))
+
+(defun evil-ex-argument-handler-runner (arg-handler)
+  (car arg-handler))
+
+(defun evil-ex-argument-handler-completer (arg-handler)
+  (cadr arg-handler))
+
+(defmacro evil-ex-define-argument-type (arg-type doc &rest body)
+  "Defines a new handler for argument-type ARG-TYPE.
+DOC is the documentation string. It is followed by a list of
+keywords and function:
+
+:collection COLLECTION
+
+  A collection for completion as required by `all-completions'.
+
+:completion-at-point FUNC
+
+  Function to be called to initialize a potential
+  completion. FUNC must match the requirements as described for
+  the variable `completion-at-point-functions'. When FUNC is
+  called the minibuffer content is narrowed to exactly match the
+  argument.
+
+:runner FUNC
+
+  Function to be called when the type of the current argument
+  changes or when the content of this argument changes. This
+  function should take one obligatory argument FLAG followed by
+  an optional argument ARG. FLAG is one of three symbol 'start,
+  'stop or 'update. When the argument type is recognized for the
+  first time and this handler is started the FLAG is 'start. If
+  the argument type changes to something else or ex state
+  finished the handler FLAG is 'stop. If the content of the
+  argument has changed FLAG is 'update. If FLAG is either 'start
+  or 'update then ARG is the current value of this argument. If
+  FLAG is 'stop then arg is nil."
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp function-form]])))
+  (unless (stringp doc) (push doc body))
+  (let (runner completer)
+    (while (keywordp (car-safe body))
+      (let ((key (pop body))
+            (func (pop body)))
+        (cond
+         ((eq key :runner)
+          (setq runner func))
+         ((eq key :collection)
+          (setq completer (cons 'collection func)))
+         ((eq key :completion-at-point)
+          (setq completer (cons 'completion-at-point func))))))
+    `(eval-and-compile
+       (evil-add-to-alist
+        'evil-ex-argument-types
+        ',arg-type
+        '(,runner ,completer)))))
+
+(evil-ex-define-argument-type file
+  "Handles a file argument."
+  :collection read-file-name-internal)
+
+(evil-ex-define-argument-type buffer
+  "Called to complete a buffer name argument."
+  :collection internal-complete-buffer)
+
+(declare-function shell-completion-vars "shell" ())
+
+(defun evil-ex-init-shell-argument-completion (flag &optional arg)
+  "Prepares the current minibuffer for completion of shell commands.
+This function must be called from the :runner function of some
+argument handler that requires shell completion."
+  (when (and (eq flag 'start)
+             (not evil-ex-shell-argument-initialized))
+    (set (make-local-variable 'evil-ex-shell-argument-initialized) t)
+    (cond
+     ;; Emacs 24
+     ((fboundp 'comint-completion-at-point)
+      (shell-completion-vars))
+     (t
+      (set (make-local-variable 'minibuffer-default-add-function)
+           'minibuffer-default-add-shell-commands)))
+    (setq completion-at-point-functions
+          '(evil-ex-command-completion-at-point
+            evil-ex-argument-completion-at-point))))
+
+(define-obsolete-function-alias
+  'evil-ex-shell-command-completion-at-point
+  'comint-completion-at-point)
+
+(evil-ex-define-argument-type shell
+  "Shell argument type, supports completion."
+  :completion-at-point comint-completion-at-point
+  :runner evil-ex-init-shell-argument-completion)
+
+(defun evil-ex-file-or-shell-command-completion-at-point ()
+  (if (and (< (point-min) (point-max))
+           (= (char-after (point-min)) ?!))
+      (save-restriction
+        (narrow-to-region (1+ (point-min)) (point-max))
+        (comint-completion-at-point))
+    (list (point-min) (point-max) #'read-file-name-internal)))
+
+(evil-ex-define-argument-type file-or-shell
+  "File or shell argument type.
+If the current argument starts with a ! the rest of the argument
+is considered a shell command, otherwise a file-name. Completion
+works accordingly."
+  :completion-at-point evil-ex-file-or-shell-command-completion-at-point
+  :runner evil-ex-init-shell-argument-completion)
+
+(defun evil-ex-binding (command &optional noerror)
+  "Returns the final binding of COMMAND."
+  (save-match-data
+    (let ((binding command))
+      (when binding
+        (string-match "^\\(.+?\\)\\!?$" binding)
+        (setq binding (match-string 1 binding))
+        (while (progn
+                 (setq binding (cdr (assoc binding evil-ex-commands)))
+                 (stringp binding)))
+        (unless binding
+          (setq binding (intern command)))
+        (if (commandp binding)
+            ;; check for remaps
+            (or (command-remapping binding) binding)
+          (unless noerror
+            (user-error "Unknown command: `%s'" command)))))))
+
+(defun evil-ex-completed-binding (command &optional noerror)
+  "Returns the final binding of the completion of COMMAND."
+  (let ((completion (try-completion command evil-ex-commands)))
+    (evil-ex-binding (if (eq completion t) command
+                       (or completion command))
+                     noerror)))
+
+;;; TODO: extensions likes :p :~ <cfile> ...
+(defun evil-ex-replace-special-filenames (file-name)
+  "Replace special symbols in FILE-NAME.
+Replaces % by the current file-name,
+Replaces # by the alternate file-name in FILE-NAME."
+  (let ((current-fname (buffer-file-name))
+        (alternate-fname (and (other-buffer)
+                              (buffer-file-name (other-buffer)))))
+    (when current-fname
+      (setq file-name
+            (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)"
+                                      current-fname file-name
+                                      t t 2)))
+    (when alternate-fname
+      (setq file-name
+            (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)"
+                                      alternate-fname file-name
+                                      t t 2)))
+    (setq file-name
+          (replace-regexp-in-string "\\\\\\([#%]\\)"
+                                    "\\1" file-name t)))
+  file-name)
+
+(defun evil-ex-file-arg ()
+  "Returns the current Ex argument as a file name.
+This function interprets special file names like # and %."
+  (unless (or (null evil-ex-argument)
+              (zerop (length evil-ex-argument)))
+    (evil-ex-replace-special-filenames evil-ex-argument)))
+
+(defun evil-ex-repeat (count)
+  "Repeats the last ex command."
+  (interactive "P")
+  (when count
+    (goto-char (point-min))
+    (forward-line (1- count)))
+  (let ((evil-ex-current-buffer (current-buffer))
+        (hist evil-ex-history))
+    (while hist
+      (let ((evil-ex-last-cmd (pop hist)))
+        (when evil-ex-last-cmd
+          (evil-ex-update nil nil nil evil-ex-last-cmd)
+          (let ((binding (evil-ex-binding evil-ex-cmd)))
+            (unless (eq binding #'evil-ex-repeat)
+              (setq hist nil)
+              (if evil-ex-expression
+                  (eval evil-ex-expression)
+                (user-error "Ex: syntax error")))))))))
+
+(defun evil-ex-call-command (range command argument)
+  "Execute the given command COMMAND."
+  (let* ((count (when (numberp range) range))
+         (range (when (evil-range-p range) range))
+         (bang (and (save-match-data (string-match ".!$" command)) t))
+         (evil-ex-point (point))
+         (evil-ex-range
+          (or range (and count (evil-ex-range count count))))
+         (evil-ex-command (evil-ex-completed-binding command))
+         (evil-ex-bang (and bang t))
+         (evil-ex-argument (copy-sequence argument))
+         (evil-this-type (evil-type evil-ex-range))
+         (current-prefix-arg count)
+         (prefix-arg current-prefix-arg))
+    (when (stringp evil-ex-argument)
+      (set-text-properties
+       0 (length evil-ex-argument) nil evil-ex-argument))
+    (let ((buf (current-buffer)))
+      (unwind-protect
+          (cond
+           ((not evil-ex-range)
+            (setq this-command evil-ex-command)
+            (run-hooks 'pre-command-hook)
+            (call-interactively evil-ex-command)
+            (run-hooks 'post-command-hook))
+           (t
+            ;; set visual selection to match the region if an explicit
+            ;; range has been specified
+            (let ((ex-range (evil-copy-range evil-ex-range))
+                  beg end)
+              (evil-expand-range ex-range)
+              (setq beg (evil-range-beginning ex-range)
+                    end (evil-range-end ex-range))
+              (evil-sort beg end)
+              (setq this-command evil-ex-command)
+              (run-hooks 'pre-command-hook)
+              (set-mark end)
+              (goto-char beg)
+              (activate-mark)
+              (call-interactively evil-ex-command)
+              (run-hooks 'post-command-hook))))
+        (when (buffer-live-p buf)
+          (with-current-buffer buf
+            (deactivate-mark)))))))
+
+(defun evil-ex-line (base &optional offset)
+  "Return the line number of BASE plus OFFSET."
+  (+ (or base (line-number-at-pos))
+     (or offset 0)))
+
+(defun evil-ex-first-line ()
+  "Return the line number of the first line."
+  (line-number-at-pos (point-min)))
+
+(defun evil-ex-current-line ()
+  "Return the line number of the current line."
+  (line-number-at-pos (point)))
+
+(defun evil-ex-last-line ()
+  "Return the line number of the last line."
+  (save-excursion
+    (goto-char (point-max))
+    (when (bolp)
+      (forward-line -1))
+    (line-number-at-pos)))
+
+(defun evil-ex-range (beg-line &optional end-line)
+  "Returns the first and last position of the current range."
+  (evil-range
+   (evil-line-position beg-line)
+   (evil-line-position (or end-line beg-line) -1)
+   'line
+   :expanded t))
+
+(defun evil-ex-full-range ()
+  "Return a range encompassing the whole buffer."
+  (evil-range (point-min) (point-max) 'line))
+
+(defun evil-ex-marker (marker)
+  "Return MARKER's line number in the current buffer.
+Signal an error if MARKER is in a different buffer."
+  (when (stringp marker)
+    (setq marker (aref marker 0)))
+  (setq marker (evil-get-marker marker))
+  (if (numberp marker)
+      (line-number-at-pos marker)
+    (user-error "Ex does not support markers in other files")))
+
+(defun evil-ex-char-marker-range (beg end)
+  (when (stringp beg) (setq beg (aref beg 0)))
+  (when (stringp end) (setq end (aref end 0)))
+  (setq beg (evil-get-marker beg)
+        end (evil-get-marker end))
+  (if (and (numberp beg) (numberp end))
+      (evil-expand-range
+       (evil-range beg end
+                   (if (evil-visual-state-p)
+                       (evil-visual-type)
+                     'inclusive)))
+    (user-error "Ex does not support markers in other files")))
+
+(defun evil-ex-re-fwd (pattern)
+  "Search forward for PATTERN.
+Returns the line number of the match."
+  (condition-case err
+      (save-match-data
+        (save-excursion
+          (set-text-properties 0 (length pattern) nil pattern)
+          (evil-move-end-of-line)
+          (and (re-search-forward pattern nil t)
+               (line-number-at-pos (1- (match-end 0))))))
+    (invalid-regexp
+     (evil-ex-echo (cadr err))
+     nil)))
+
+(defun evil-ex-re-bwd (pattern)
+  "Search backward for PATTERN.
+Returns the line number of the match."
+  (condition-case err
+      (save-match-data
+        (save-excursion
+          (set-text-properties 0 (length pattern) nil pattern)
+          (evil-move-beginning-of-line)
+          (and (re-search-backward pattern nil t)
+               (line-number-at-pos (match-beginning 0)))))
+    (invalid-regexp
+     (evil-ex-echo (cadr err))
+     nil)))
+
+(defun evil-ex-prev-search ()
+  (error "Previous search not yet implemented"))
+
+(defun evil-ex-signed-number (sign &optional number)
+  "Return a signed number like -3 and +1.
+NUMBER defaults to 1."
+  (funcall sign (or number 1)))
+
+(defun evil-ex-eval (string &optional start)
+  "Evaluate STRING as an Ex command.
+START is the start symbol, which defaults to `expression'."
+  ;; disable the mark before executing, otherwise the visual region
+  ;; may be used as operator range instead of the ex-range
+  (let ((form (evil-ex-parse string nil start))
+        transient-mark-mode deactivate-mark)
+    (eval form)))
+
+(defun evil-ex-parse (string &optional syntax start)
+  "Parse STRING as an Ex expression and return an evaluation tree.
+If SYNTAX is non-nil, return a syntax tree instead.
+START is the start symbol, which defaults to `expression'."
+  (let* ((start (or start (car-safe (car-safe evil-ex-grammar))))
+         (match (evil-parser
+                 string start evil-ex-grammar t syntax)))
+    (car-safe match)))
+
+(defun evil-ex-parse-command (string)
+  "Parse STRING as an Ex binding."
+  (let ((result (evil-parser string 'binding evil-ex-grammar))
+        bang command)
+    (when result
+      (setq command (car-safe result)
+            string (cdr-safe result))
+      ;; check whether the parsed command is followed by a slash or
+      ;; number and the part before it is not a known ex binding
+      (when (and (> (length string) 0)
+                 (string-match-p "^[/[:digit:]]" string)
+                 (not (evil-ex-binding command t)))
+        ;; if this is the case, assume the slash or number and all
+        ;; following symbol characters form an (Emacs-)command
+        (setq result (evil-parser (concat command string)
+                                  'emacs-binding
+                                  evil-ex-grammar)
+              command (car-safe result)
+              string (cdr-safe result)))
+      ;; parse a following "!" as bang only if
+      ;; the command has the property :ex-bang t
+      (when (evil-ex-command-force-p command)
+        (setq result (evil-parser string 'bang evil-ex-grammar)
+              bang (or (car-safe result) "")
+              string (cdr-safe result)
+              command (concat command bang)))
+      (cons command string))))
+
+(defun evil-ex-command-force-p (command)
+  "Whether COMMAND accepts the bang argument."
+  (let ((binding (evil-ex-completed-binding command t)))
+    (when binding
+      (evil-get-command-property binding :ex-bang))))
+
+(defun evil-flatten-syntax-tree (tree)
+  "Find all paths from the root of TREE to its leaves.
+TREE is a syntax tree, i.e., all its leave nodes are strings.
+The `nth' element in the result is the syntactic context
+for the corresponding string index (counted from zero)."
+  (let* ((result nil)
+         (traverse nil)
+         (traverse
+          #'(lambda (tree path)
+              (if (stringp tree)
+                  (dotimes (char (length tree))
+                    (push path result))
+                (let ((path (cons (car tree) path)))
+                  (dolist (subtree (cdr tree))
+                    (funcall traverse subtree path)))))))
+    (funcall traverse tree nil)
+    (nreverse result)))
+
+(defun evil-ex-syntactic-context (&optional pos)
+  "Return the syntactical context of the character at POS.
+POS defaults to the current position of point."
+  (let* ((contexts (evil-flatten-syntax-tree evil-ex-tree))
+         (length (length contexts))
+         (pos (- (or pos (point)) (minibuffer-prompt-end))))
+    (when (>= pos length)
+      (setq pos (1- length)))
+    (when (< pos 0)
+      (setq pos 0))
+    (when contexts
+      (nth pos contexts))))
+
+(defun evil-parser (string symbol grammar &optional greedy syntax)
+  "Parse STRING as a SYMBOL in GRAMMAR.
+If GREEDY is non-nil, the whole of STRING must match.
+If the parse succeeds, the return value is a cons cell
+\(RESULT . TAIL), where RESULT is a parse tree and TAIL is
+the remainder of STRING. Otherwise, the return value is nil.
+
+GRAMMAR is an association list of symbols and their definitions.
+A definition is either a list of production rules, which are
+tried in succession, or a #'-quoted function, which is called
+to parse the input.
+
+A production rule can be one of the following:
+
+    nil matches the empty string.
+    A regular expression matches a substring.
+    A symbol matches a production for that symbol.
+    (X Y) matches X followed by Y.
+    (\\? X) matches zero or one of X.
+    (* X) matches zero or more of X.
+    (+ X) matches one or more of X.
+    (& X) matches X, but does not consume.
+    (! X) matches anything but X, but does not consume.
+
+Thus, a simple grammar may look like:
+
+    ((plus \"\\\\+\")           ; plus <- \"+\"
+     (minus \"-\")            ; minus <- \"-\"
+     (operator plus minus)) ; operator <- plus / minus
+
+All input-consuming rules have a value. A regular expression evaluates
+to the text matched, while a list evaluates to a list of values.
+The value of a list may be overridden with a semantic action, which is
+specified with a #'-quoted expression at the end:
+
+    (X Y #'foo)
+
+The value of this rule is the result of calling foo with the values
+of X and Y as arguments. Alternatively, the function call may be
+specified explicitly:
+
+    (X Y #'(foo $1 $2))
+
+Here, $1 refers to X and $2 refers to Y. $0 refers to the whole list.
+Dollar expressions can also be used directly:
+
+    (X Y #'$1)
+
+This matches X followed by Y, but ignores the value of Y;
+the value of the list is the same as the value of X.
+
+If the SYNTAX argument is non-nil, then all semantic actions
+are ignored, and a syntax tree is constructed instead. The
+syntax tree obeys the property that all the leave nodes are
+parts of the input string. Thus, by traversing the syntax tree,
+one can determine how each character was parsed.
+
+The following symbols have reserved meanings within a grammar:
+`\\?', `*', `+', `&', `!', `function', `alt', `seq' and nil."
+  (let ((string (or string ""))
+        func pair result rules tail)
+    (cond
+     ;; epsilon
+     ((member symbol '("" nil))
+      (setq pair (cons (if syntax "" nil) string)))
+     ;; token
+     ((stringp symbol)
+      (save-match-data
+        (when (or (eq (string-match symbol string) 0)
+                  ;; ignore leading whitespace
+                  (and (eq (string-match "^[ \f\t\n\r\v]+" string) 0)
+                       (eq (match-end 0)
+                           (string-match
+                            symbol string (match-end 0)))))
+          (setq result (match-string 0 string)
+                tail (substring string (match-end 0))
+                pair (cons result tail))
+          (when (and syntax pair)
+            (setq result (substring string 0
+                                    (- (length string)
+                                       (length tail))))
+            (setcar pair result)))))
+     ;; symbol
+     ((symbolp symbol)
+      (let ((context symbol))
+        (setq rules (cdr-safe (assq symbol grammar)))
+        (setq pair (evil-parser string `(alt ,@rules)
+                                grammar greedy syntax))
+        (when (and syntax pair)
+          (setq result (car pair))
+          (if (and (listp result) (sequencep (car result)))
+              (setq result `(,symbol ,@result))
+            (setq result `(,symbol ,result)))
+          (setcar pair result))))
+     ;; function
+     ((eq (car-safe symbol) 'function)
+      (setq symbol (cadr symbol)
+            pair (funcall symbol string))
+      (when (and syntax pair)
+        (setq tail (or (cdr pair) "")
+              result (substring string 0
+                                (- (length string)
+                                   (length tail))))
+        (setcar pair result)))
+     ;; list
+     ((listp symbol)
+      (setq rules symbol
+            symbol (car-safe rules))
+      (if (memq symbol '(& ! \? * + alt seq))
+          (setq rules (cdr rules))
+        (setq symbol 'seq))
+      (when (and (memq symbol '(+ alt seq))
+                 (> (length rules) 1))
+        (setq func (car (last rules)))
+        (if (eq (car-safe func) 'function)
+            (setq rules (delq func (copy-sequence rules))
+                  func (cadr func))
+          (setq func nil)))
+      (cond
+       ;; positive lookahead
+       ((eq symbol '&)
+        (when (evil-parser string rules grammar greedy syntax)
+          (setq pair (evil-parser string nil grammar nil syntax))))
+       ;; negative lookahead
+       ((eq symbol '!)
+        (unless (evil-parser string rules grammar greedy syntax)
+          (setq pair (evil-parser string nil grammar nil syntax))))
+       ;; zero or one
+       ((eq symbol '\?)
+        (setq rules (if (> (length rules) 1)
+                        `(alt ,rules nil)
+                      `(alt ,@rules nil))
+              pair (evil-parser string rules grammar greedy syntax)))
+       ;; zero or more
+       ((eq symbol '*)
+        (setq rules `(alt (+ ,@rules) nil)
+              pair (evil-parser string rules grammar greedy syntax)))
+       ;; one or more
+       ((eq symbol '+)
+        (let (current results)
+          (catch 'done
+            (while (setq current (evil-parser
+                                  string rules grammar nil syntax))
+              (setq result (car-safe current)
+                    tail (or (cdr-safe current) "")
+                    results (append results (if syntax result
+                                              (cdr-safe result))))
+              ;; stop if stuck
+              (if (equal string tail)
+                  (throw 'done nil)
+                (setq string tail))))
+          (when results
+            (setq func (or func 'list)
+                  pair (cons results tail)))))
+       ;; alternatives
+       ((eq symbol 'alt)
+        (catch 'done
+          (dolist (rule rules)
+            (when (setq pair (evil-parser
+                              string rule grammar greedy syntax))
+              (throw 'done pair)))))
+       ;; sequence
+       (t
+        (setq func (or func 'list))
+        (let ((last (car-safe (last rules)))
+              current results rule)
+          (catch 'done
+            (while rules
+              (setq rule (pop rules)
+                    current (evil-parser string rule grammar
+                                         (when greedy
+                                           (null rules))
+                                         syntax))
+              (cond
+               ((null current)
+                (setq results nil)
+                (throw 'done nil))
+               (t
+                (setq result (car-safe current)
+                      tail (cdr-safe current))
+                (unless (memq (car-safe rule) '(& !))
+                  (if (and syntax
+                           (or (null result)
+                               (and (listp result)
+                                    (listp rule)
+                                    ;; splice in single-element
+                                    ;; (\? ...) expressions
+                                    (not (and (eq (car-safe rule) '\?)
+                                              (eq (length rule) 2))))))
+                      (setq results (append results result))
+                    (setq results (append results (list result)))))
+                (setq string (or tail ""))))))
+          (when results
+            (setq pair (cons results tail))))))
+      ;; semantic action
+      (when (and pair func (not syntax))
+        (setq result (car pair))
+        (let* ((dexp
+                #'(lambda (obj)
+                    (when (symbolp obj)
+                      (let ((str (symbol-name obj)))
+                        (save-match-data
+                          (when (string-match "\\$\\([0-9]+\\)" str)
+                            (string-to-number (match-string 1 str))))))))
+               ;; traverse a tree for dollar expressions
+               (dval nil)
+               (dval
+                #'(lambda (obj)
+                    (if (listp obj)
+                        (mapcar dval obj)
+                      (let ((num (funcall dexp obj)))
+                        (if num
+                            (if (not (listp result))
+                                result
+                              (if (eq num 0)
+                                  `(list ,@result)
+                                (nth (1- num) result)))
+                          obj))))))
+          (cond
+           ((null func)
+            (setq result nil))
+           ;; lambda function
+           ((eq (car-safe func) 'lambda)
+            (if (memq symbol '(+ seq))
+                (setq result `(funcall ,func ,@result))
+              (setq result `(funcall ,func ,result))))
+           ;; string replacement
+           ((or (stringp func) (stringp (car-safe func)))
+            (let* ((symbol (or (car-safe (cdr-safe func))
+                               (and (boundp 'context) context)
+                               (car-safe (car-safe grammar))))
+                   (string (if (stringp func) func (car-safe func))))
+              (setq result (car-safe (evil-parser string symbol grammar
+                                                  greedy syntax)))))
+           ;; dollar expression
+           ((funcall dexp func)
+            (setq result (funcall dval func)))
+           ;; function call
+           ((listp func)
+            (setq result (funcall dval func)))
+           ;; symbol
+           (t
+            (if (memq symbol '(+ seq))
+                (setq result `(,func ,@result))
+              (setq result `(,func ,result))))))
+        (setcar pair result))))
+    ;; weed out incomplete matches
+    (when pair
+      (if (not greedy) pair
+        (if (null (cdr pair)) pair
+          ;; ignore trailing whitespace
+          (when (save-match-data (string-match "^[ \f\t\n\r\v]*$" (cdr pair)))
+            (unless syntax (setcdr pair nil))
+            pair))))))
+
+(provide 'evil-ex)
+
+;;; evil-ex.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-ex.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-integration.el
@@ -0,0 +1,573 @@
+;;; 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.12
+
+;;
+;; 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:
+
+;;; Evilize some commands
+
+;; unbound keys should be ignored
+(evil-declare-ignore-repeat 'undefined)
+
+(mapc #'(lambda (cmd)
+          (evil-set-command-property cmd :keep-visual t)
+          (evil-declare-not-repeat cmd))
+      '(digit-argument
+        negative-argument
+        universal-argument
+        universal-argument-minus
+        universal-argument-more
+        universal-argument-other-key))
+(mapc #'evil-declare-not-repeat
+      '(what-cursor-position))
+(mapc #'evil-declare-change-repeat
+      '(dabbrev-expand
+        hippie-expand
+        quoted-insert))
+(mapc #'evil-declare-abort-repeat
+      '(balance-windows
+        eval-expression
+        execute-extended-command
+        exit-minibuffer
+        compile
+        delete-window
+        delete-other-windows
+        find-file-at-point
+        ffap-other-window
+        recompile
+        redo
+        save-buffer
+        split-window
+        split-window-horizontally
+        split-window-vertically
+        undo
+        undo-tree-redo
+        undo-tree-undo))
+
+(evil-set-type #'previous-line 'line)
+(evil-set-type #'next-line 'line)
+
+(dolist (cmd '(keyboard-quit keyboard-escape-quit))
+  (evil-set-command-property cmd :suppress-operator t))
+
+;;; Mouse
+(evil-declare-insert-at-point-repeat 'mouse-yank-primary)
+(evil-declare-insert-at-point-repeat 'mouse-yank-secondary)
+
+;;; key-binding
+
+;; Calling `keyboard-quit' should cancel repeat
+(defadvice keyboard-quit (before evil activate)
+  (when (fboundp 'evil-repeat-abort)
+    (evil-repeat-abort)))
+
+;; etags-select
+;; FIXME: probably etags-select should be recomended in docs
+(eval-after-load 'etags-select
+  '(progn
+     (define-key evil-motion-state-map "g]" 'etags-select-find-tag-at-point)))
+
+;;; Buffer-menu
+
+(evil-add-hjkl-bindings Buffer-menu-mode-map 'motion)
+
+;; dictionary.el
+
+(evil-add-hjkl-bindings dictionary-mode-map 'motion
+  "?" 'dictionary-help        ; "h"
+  "C-o" 'dictionary-previous) ; "l"
+
+;;; Dired
+
+(eval-after-load 'dired
+  '(progn
+     ;; use the standard Dired bindings as a base
+     (defvar dired-mode-map)
+     (evil-make-overriding-map dired-mode-map 'normal)
+     (evil-add-hjkl-bindings dired-mode-map 'normal
+       "J" 'dired-goto-file                   ; "j"
+       "K" 'dired-do-kill-lines               ; "k"
+       "r" 'dired-do-redisplay                ; "l"
+       ;; ":d", ":v", ":s", ":e"
+       ";" (lookup-key dired-mode-map ":"))))
+
+(eval-after-load 'wdired
+  '(progn
+     (add-hook 'wdired-mode-hook #'evil-change-to-initial-state)
+     (defadvice wdired-change-to-dired-mode (after evil activate)
+       (evil-change-to-initial-state nil t))))
+
+;;; ELP
+
+(eval-after-load 'elp
+  '(defadvice elp-results (after evil activate)
+     (evil-motion-state)))
+
+;;; ERT
+
+(evil-add-hjkl-bindings ert-results-mode-map 'motion)
+
+;;; Info
+
+(evil-add-hjkl-bindings Info-mode-map 'motion
+  "0" 'evil-digit-argument-or-evil-beginning-of-line
+  (kbd "\M-h") 'Info-help   ; "h"
+  "\C-t" 'Info-history-back ; "l"
+  "\C-o" 'Info-history-back
+  " " 'Info-scroll-up
+  "\C-]" 'Info-follow-nearest-node
+  (kbd "DEL") 'Info-scroll-down)
+
+;;; Parentheses
+
+(defadvice show-paren-function (around evil disable)
+  "Match parentheses in Normal state."
+  (if (if (memq 'not evil-highlight-closing-paren-at-point-states)
+          (memq evil-state evil-highlight-closing-paren-at-point-states)
+        (not (memq evil-state evil-highlight-closing-paren-at-point-states)))
+      ad-do-it
+    (let ((pos (point)) syntax narrow)
+      (setq pos
+            (catch 'end
+              (dotimes (var (1+ (* 2 evil-show-paren-range)))
+                (if (zerop (mod var 2))
+                    (setq pos (+ pos var))
+                  (setq pos (- pos var)))
+                (setq syntax (syntax-class (syntax-after pos)))
+                (cond
+                 ((eq syntax 4)
+                  (setq narrow pos)
+                  (throw 'end pos))
+                 ((eq syntax 5)
+                  (throw 'end (1+ pos)))))))
+      (if pos
+          (save-excursion
+            (goto-char pos)
+            (save-restriction
+              (when narrow
+                (narrow-to-region narrow (point-max)))
+              ad-do-it))
+        ;; prevent the preceding pair from being highlighted
+        (dolist (ov '(show-paren--overlay
+                      show-paren--overlay-1
+                      show-paren-overlay
+                      show-paren-overlay-1))
+          (let ((ov (and (boundp ov) (symbol-value ov))))
+            (when (overlayp ov) (delete-overlay ov))))))))
+
+;;; Speedbar
+
+(evil-add-hjkl-bindings speedbar-key-map 'motion
+  "h" 'backward-char
+  "j" 'speedbar-next
+  "k" 'speedbar-prev
+  "l" 'forward-char
+  "i" 'speedbar-item-info
+  "r" 'speedbar-refresh
+  "u" 'speedbar-up-directory
+  "o" 'speedbar-toggle-line-expansion
+  (kbd "RET") 'speedbar-edit-line)
+
+;; Ibuffer
+(eval-after-load 'ibuffer
+  '(progn
+     (defvar ibuffer-mode-map)
+     (evil-make-overriding-map ibuffer-mode-map 'normal)
+     (evil-define-key 'normal ibuffer-mode-map
+       "j" 'evil-next-line
+       "k" 'evil-previous-line
+       "RET" 'ibuffer-visit-buffer)))
+
+;;; 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))))
+
+;;; Auto-complete
+(eval-after-load 'auto-complete
+  '(progn
+     (evil-add-command-properties 'auto-complete :repeat 'evil-ac-repeat)
+     (evil-add-command-properties 'ac-complete :repeat 'evil-ac-repeat)
+     (evil-add-command-properties 'ac-expand :repeat 'evil-ac-repeat)
+     (evil-add-command-properties 'ac-next :repeat 'ignore)
+     (evil-add-command-properties 'ac-previous :repeat 'ignore)
+
+     (defvar evil-ac-prefix-len nil
+       "The length of the prefix of the current item to be completed.")
+
+     (defvar ac-prefix)
+     (defun evil-ac-repeat (flag)
+       "Record the changes for auto-completion."
+       (cond
+        ((eq flag 'pre)
+         (setq evil-ac-prefix-len (length ac-prefix))
+         (evil-repeat-start-record-changes))
+        ((eq flag 'post)
+         ;; Add change to remove the prefix
+         (evil-repeat-record-change (- evil-ac-prefix-len)
+                                    ""
+                                    evil-ac-prefix-len)
+         ;; Add change to insert the full completed text
+         (evil-repeat-record-change
+          (- evil-ac-prefix-len)
+          (buffer-substring-no-properties (- evil-repeat-pos
+                                             evil-ac-prefix-len)
+                                          (point))
+          0)
+         ;; Finish repeation
+         (evil-repeat-finish-record-changes))))))
+
+;;; Company
+(eval-after-load 'company
+  '(progn
+     (mapc #'evil-declare-change-repeat
+           '(company-complete-mouse
+             company-complete-number
+             company-complete-selection
+             company-complete-common))
+
+     (mapc #'evil-declare-ignore-repeat
+           '(company-abort
+             company-select-next
+             company-select-previous
+             company-select-next-or-abort
+             company-select-previous-or-abort
+             company-select-mouse
+             company-show-doc-buffer
+             company-show-location
+             company-search-candidates
+             company-filter-candidates))))
+
+;; 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)))))
+
+;; Show key
+(defadvice quail-show-key (around evil activate)
+  "Temporarily go to Emacs state"
+  (evil-with-state emacs ad-do-it))
+
+(defadvice describe-char (around evil activate)
+  "Temporarily go to Emacs state"
+  (evil-with-state emacs ad-do-it))
+
+;; 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))))
+
+;;; nXhtml/mumamo
+;; ensure that mumamo does not toggle evil through its globalized mode
+(eval-after-load 'mumamo
+  '(with-no-warnings
+     (push 'evil-mode-cmhh mumamo-change-major-mode-no-nos)))
+
+;;; ag.el
+(eval-after-load 'ag
+  '(progn
+     (defvar ag-mode-map)
+     (add-to-list 'evil-motion-state-modes 'ag-mode)
+     (evil-add-hjkl-bindings ag-mode-map 'motion)))
+
+;; 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)))))
+
+(provide 'evil-integration)
+
+;;; abbrev.el
+(when evil-want-abbrev-expand-on-insert-exit
+  (eval-after-load 'abbrev
+    '(add-hook 'evil-insert-state-exit-hook 'expand-abbrev)))
+
+;;; evil-integration.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-integration.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-jumps.el
@@ -0,0 +1,314 @@
+;;; evil-jumps.el --- Jump list implementation
+
+;; Author: Bailey Ling <bling at live.ca>
+
+;; Version: 1.2.10
+
+;;
+;; 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 'cl-lib)
+(require 'evil-core)
+(require 'evil-states)
+
+;;; Code:
+
+(defgroup evil-jumps nil
+  "Evil jump list configuration options."
+  :prefix "evil-jumps"
+  :group 'evil)
+
+(defcustom evil-jumps-cross-buffers t
+  "When non-nil, the jump commands can cross borders between buffers, otherwise the jump commands act only within the current buffer."
+  :type 'boolean
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-max-length 100
+  "The maximum number of jumps to keep track of."
+  :type 'integer
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-pre-jump-hook nil
+  "Hooks to run just before jumping to a location in the jump list."
+  :type 'hook
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-post-jump-hook nil
+  "Hooks to run just after jumping to a location in the jump list."
+  :type 'hook
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-ignored-file-patterns '("COMMIT_EDITMSG$" "TAGS$")
+  "A list of pattern regexps to match on the file path to exclude from being included in the jump list."
+  :type '(repeat string)
+  :group 'evil-jumps)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar savehist-additional-variables)
+
+(defvar evil--jumps-jumping nil)
+
+(eval-when-compile (defvar evil--jumps-debug nil))
+
+(defvar evil--jumps-buffer-targets "\\*\\(new\\|scratch\\)\\*"
+  "Regexp to match against `buffer-name' to determine whether it's a valid jump target.")
+
+(defvar evil--jumps-window-jumps (make-hash-table)
+  "Hashtable which stores all jumps on a per window basis.")
+
+(defvar evil-jumps-history nil
+  "History of `evil-mode' jumps that are persisted with `savehist'.")
+
+(cl-defstruct evil-jumps-struct
+  ring
+  (idx -1))
+
+(defmacro evil--jumps-message (format &rest args)
+  (when evil--jumps-debug
+    `(with-current-buffer (get-buffer-create "*evil-jumps*")
+       (goto-char (point-max))
+       (insert (apply #'format ,format ',args) "\n"))))
+
+(defun evil--jumps-get-current (&optional window)
+  (unless window
+    (setq window (frame-selected-window)))
+  (let* ((jump-struct (gethash window evil--jumps-window-jumps)))
+    (unless jump-struct
+      (setq jump-struct (make-evil-jumps-struct))
+      (puthash window jump-struct evil--jumps-window-jumps))
+    jump-struct))
+
+(defun evil--jumps-get-jumps (struct)
+  (let ((ring (evil-jumps-struct-ring struct)))
+    (unless ring
+      (setq ring (make-ring evil-jumps-max-length))
+      (setf (evil-jumps-struct-ring struct) ring))
+    ring))
+
+(defun evil--jumps-get-window-jump-list ()
+  (let ((struct (evil--jumps-get-current)))
+    (evil--jumps-get-jumps struct)))
+
+(defun evil--jumps-savehist-load ()
+  (add-to-list 'savehist-additional-variables 'evil-jumps-history)
+  (let ((ring (make-ring evil-jumps-max-length)))
+    (cl-loop for jump in (reverse evil-jumps-history)
+             do (ring-insert ring jump))
+    (setf (evil-jumps-struct-ring (evil--jumps-get-current)) ring))
+  (add-hook 'savehist-save-hook #'evil--jumps-savehist-sync)
+  (remove-hook 'savehist-mode-hook #'evil--jumps-savehist-load))
+
+(defun evil--jumps-savehist-sync ()
+  "Updates the printable value of window jumps for `savehist'."
+  (setq evil-jumps-history
+        (cl-remove-if-not #'identity
+                          (mapcar #'(lambda (jump)
+                                      (let* ((mark (car jump))
+                                             (pos (if (markerp mark)
+                                                      (marker-position mark)
+                                                    mark))
+                                             (file-name (cadr jump)))
+                                        (if (and (not (file-remote-p file-name))
+                                                 (file-exists-p file-name)
+                                                 pos)
+                                            (list pos file-name)
+                                          nil)))
+                                  (ring-elements (evil--jumps-get-window-jump-list))))))
+
+(defun evil--jumps-jump (idx shift)
+  (let ((target-list (evil--jumps-get-window-jump-list)))
+    (evil--jumps-message "jumping from %s by %s" idx shift)
+    (evil--jumps-message "target list = %s" target-list)
+    (setq idx (+ idx shift))
+    (let* ((current-file-name (or (buffer-file-name) (buffer-name)))
+           (size (ring-length target-list)))
+      (unless evil-jumps-cross-buffers
+        ;; skip jump marks pointing to other buffers
+        (while (and (< idx size) (>= idx 0)
+                    (not (string= current-file-name
+                                  (let* ((place (ring-ref target-list idx))
+                                         (pos (car place)))
+                                    (cadr place)))))
+          (setq idx (+ idx shift))))
+      (when (and (< idx size) (>= idx 0))
+        ;; actual jump
+        (run-hooks 'evil-jumps-pre-jump-hook)
+        (let* ((place (ring-ref target-list idx))
+               (pos (car place))
+               (file-name (cadr place)))
+          (setq evil--jumps-jumping t)
+          (if (string-match-p evil--jumps-buffer-targets file-name)
+              (switch-to-buffer file-name)
+            (find-file file-name))
+          (setq evil--jumps-jumping nil)
+          (goto-char pos)
+          (setf (evil-jumps-struct-idx (evil--jumps-get-current)) idx)
+          (run-hooks 'evil-jumps-post-jump-hook))))))
+
+(defun evil--jumps-push ()
+  "Pushes the current cursor/file position to the jump list."
+  (let ((target-list (evil--jumps-get-window-jump-list)))
+    (let ((file-name (buffer-file-name))
+          (buffer-name (buffer-name))
+          (current-pos (point-marker))
+          (first-pos nil)
+          (first-file-name nil)
+          (excluded nil))
+      (when (and (not file-name)
+                 (string-match-p evil--jumps-buffer-targets buffer-name))
+        (setq file-name buffer-name))
+      (when file-name
+        (dolist (pattern evil-jumps-ignored-file-patterns)
+          (when (string-match-p pattern file-name)
+            (setq excluded t)))
+        (unless excluded
+          (unless (ring-empty-p target-list)
+            (setq first-pos (car (ring-ref target-list 0)))
+            (setq first-file-name (car (cdr (ring-ref target-list 0)))))
+          (unless (and (equal first-pos current-pos)
+                       (equal first-file-name file-name))
+            (evil--jumps-message "pushing %s on %s" current-pos file-name)
+            (ring-insert target-list `(,current-pos ,file-name))))))
+    (evil--jumps-message "%s %s"
+                         (selected-window)
+                         (and (not (ring-empty-p target-list))
+                              (ring-ref target-list 0)))))
+
+(evil-define-command evil-show-jumps ()
+  "Display the contents of the jump list."
+  :repeat nil
+  (evil-with-view-list
+    :name "evil-jumps"
+    :mode "Evil Jump List"
+    :format [("Jump" 5 nil)
+             ("Marker" 8 nil)
+             ("File/text" 1000 t)]
+    :entries (let* ((jumps (evil--jumps-savehist-sync))
+                    (count 0))
+               (cl-loop for jump in jumps
+                        collect `(nil [,(number-to-string (cl-incf count))
+                                       ,(number-to-string (car jump))
+                                       (,(cadr jump))])))
+    :select-action #'evil--show-jumps-select-action))
+
+(defun evil--show-jumps-select-action (jump)
+  (let ((position (string-to-number (elt jump 1)))
+        (file (car (elt jump 2))))
+    (kill-buffer)
+    (switch-to-buffer (find-file file))
+    (goto-char position)))
+
+(defun evil-set-jump (&optional pos)
+  "Set jump point at POS.
+POS defaults to point."
+  (unless (or (region-active-p) (evil-visual-state-p))
+    (push-mark pos t))
+
+  (unless evil--jumps-jumping
+    ;; clear out intermediary jumps when a new one is set
+    (let* ((struct (evil--jumps-get-current))
+           (target-list (evil--jumps-get-jumps struct))
+           (idx (evil-jumps-struct-idx struct)))
+      (cl-loop repeat idx
+               do (ring-remove target-list))
+      (setf (evil-jumps-struct-idx struct) -1))
+    (evil--jumps-push)))
+
+(defun evil--jump-backward (count)
+  (let ((count (or count 1)))
+    (evil-motion-loop (nil count)
+      (let* ((struct (evil--jumps-get-current))
+             (idx (evil-jumps-struct-idx struct)))
+        (evil--jumps-message "jumping back %s" idx)
+        (when (= idx -1)
+          (setq idx 0)
+          (setf (evil-jumps-struct-idx struct) 0)
+          (evil--jumps-push))
+        (evil--jumps-jump idx 1)))))
+
+(defun evil--jump-forward (count)
+  (let ((count (or count 1)))
+    (evil-motion-loop (nil count)
+      (let* ((struct (evil--jumps-get-current))
+             (idx (evil-jumps-struct-idx struct)))
+        (when (= idx -1)
+          (setq idx 0)
+          (setf (evil-jumps-struct-idx struct) 0)
+          (evil--jumps-push))
+          (evil--jumps-jump idx -1)))))
+
+(defun evil--jumps-window-configuration-hook (&rest args)
+  (let* ((window-list (window-list-1 nil nil t))
+         (existing-window (selected-window))
+         (new-window (previous-window)))
+    (when (and (not (eq existing-window new-window))
+               (> (length window-list) 1))
+      (let* ((target-jump-struct (evil--jumps-get-current new-window))
+             (target-jump-count (ring-length (evil--jumps-get-jumps target-jump-struct))))
+        (if (not (ring-empty-p (evil--jumps-get-jumps target-jump-struct)))
+            (evil--jumps-message "target window %s already has %s jumps" new-window target-jump-count)
+          (evil--jumps-message "new target window detected; copying %s to %s" existing-window new-window)
+          (let* ((source-jump-struct (evil--jumps-get-current existing-window))
+                 (source-list (evil--jumps-get-jumps source-jump-struct)))
+            (when (= (ring-length (evil--jumps-get-jumps target-jump-struct)) 0)
+              (setf (evil-jumps-struct-idx target-jump-struct) (evil-jumps-struct-idx source-jump-struct))
+              (setf (evil-jumps-struct-ring target-jump-struct) (ring-copy source-list)))))))
+    ;; delete obsolete windows
+    (maphash (lambda (key val)
+               (unless (member key window-list)
+                 (evil--jumps-message "removing %s" key)
+                 (remhash key evil--jumps-window-jumps)))
+             evil--jumps-window-jumps)))
+
+(defun evil--jump-hook (&optional command)
+  "Set jump point if COMMAND has a non-nil :jump property."
+  (setq command (or command this-command))
+  (when (evil-get-command-property command :jump)
+    (evil-set-jump)))
+
+(defadvice switch-to-buffer (before evil-jumps activate)
+  (evil-set-jump))
+
+(defadvice split-window-internal (before evil-jumps activate)
+  (evil-set-jump))
+
+(defadvice find-tag-noselect (before evil-jumps activate)
+  (evil-set-jump))
+
+(if (bound-and-true-p savehist-loaded)
+    (evil--jumps-savehist-load)
+  (add-hook 'savehist-mode-hook #'evil--jumps-savehist-load))
+
+(add-hook 'evil-local-mode-hook
+          (lambda ()
+            (if evil-local-mode
+                (progn
+                  (add-hook 'pre-command-hook #'evil--jump-hook nil t)
+                  (add-hook 'next-error-hook #'evil-set-jump nil t)
+                  (add-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook nil t))
+              (progn
+                (remove-hook 'pre-command-hook #'evil--jump-hook t)
+                (remove-hook 'next-error-hook #'evil-set-jump t)
+                (remove-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook t)))))
+
+(provide 'evil-jumps)
+
+;;; evil-jumps.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-jumps.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-macros.el
@@ -0,0 +1,777 @@
+;;; evil-macros.el --- Macros
+
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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-common)
+(require 'evil-states)
+(require 'evil-repeat)
+
+;;; Code:
+
+(declare-function evil-ex-p "evil-ex")
+
+;; set some error codes
+(put 'beginning-of-line 'error-conditions '(beginning-of-line error))
+(put 'beginning-of-line 'error-message "Beginning of line")
+(put 'end-of-line 'error-conditions '(end-of-line error))
+(put 'end-of-line 'error-message "End of line")
+
+(defun evil-motion-range (motion &optional count type)
+  "Execute a motion and return the buffer positions.
+The return value is a list (BEG END TYPE)."
+  (let ((opoint   (point))
+        (omark    (mark t))
+        (omactive (and (boundp 'mark-active) mark-active))
+        (obuffer  (current-buffer))
+        (evil-motion-marker (move-marker (make-marker) (point)))
+        range)
+    (evil-with-transient-mark-mode
+      (evil-narrow-to-field
+        (unwind-protect
+            (let ((current-prefix-arg count)
+                  ;; Store type in global variable `evil-this-type'.
+                  ;; If necessary, motions can change their type
+                  ;; during execution by setting this variable.
+                  (evil-this-type
+                   (or type (evil-type motion 'exclusive))))
+              (condition-case err
+                  (let ((repeat-type (evil-repeat-type motion t)))
+                    (if (functionp repeat-type)
+                        (funcall repeat-type 'pre))
+                    (unless (with-local-quit
+                              (setq range (call-interactively motion))
+                              t)
+                      (evil-repeat-abort)
+                      (setq quit-flag t))
+                    (if (functionp repeat-type)
+                        (funcall repeat-type 'post)))
+                (error (prog1 nil
+                         (evil-repeat-abort)
+                         ;; some operators depend on succeeding
+                         ;; motions, in particular for
+                         ;; `evil-forward-char' (e.g., used by
+                         ;; `evil-substitute'), therefore we let
+                         ;; end-of-line and end-of-buffer pass
+                         (if (not (memq (car err) '(end-of-line end-of-buffer)))
+                             (signal (car err) (cdr err))
+                           (message (error-message-string err))))))
+              (cond
+               ;; the motion returned a range
+               ((evil-range-p range))
+               ;; the motion made a Visual selection
+               ((evil-visual-state-p)
+                (setq range (evil-visual-range)))
+               ;; the motion made an active region
+               ((region-active-p)
+                (setq range (evil-range (region-beginning)
+                                        (region-end)
+                                        evil-this-type)))
+               ;; default: range from previous position to current
+               (t
+                (setq range (evil-expand-range
+                             (evil-normalize evil-motion-marker
+                                             (point)
+                                             evil-this-type)))))
+              (unless (or (null type) (eq (evil-type range) type))
+                (evil-set-type range type)
+                (evil-expand-range range))
+              (evil-set-range-properties range nil)
+              range)
+          ;; restore point and mark like `save-excursion',
+          ;; but only if the motion hasn't disabled the operator
+          (unless evil-inhibit-operator
+            (set-buffer obuffer)
+            (evil-move-mark omark)
+            (goto-char opoint))
+          ;; delete marker so it doesn't slow down editing
+          (move-marker evil-motion-marker nil))))))
+
+(defmacro evil-define-motion (motion args &rest body)
+  "Define an motion command MOTION.
+
+\(fn MOTION (COUNT ARGS...) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           [&optional ("interactive" [&rest form])]
+                           def-body)))
+  (let (arg doc interactive key keys type)
+    (when args
+      (setq args `(&optional ,@(delq '&optional args))
+            ;; the count is either numerical or nil
+            interactive '("<c>")))
+    ;; collect docstring
+    (when (and (> (length body) 1)
+               (or (eq (car-safe (car-safe body)) 'format)
+                   (stringp (car-safe body))))
+      (setq doc (pop body)))
+    ;; collect keywords
+    (setq keys (plist-put keys :repeat 'motion))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body)
+            keys (plist-put keys key arg)))
+    ;; collect `interactive' specification
+    (when (eq (car-safe (car-safe body)) 'interactive)
+      (setq interactive (cdr (pop body))))
+    ;; macro expansion
+    `(progn
+       ;; refresh echo area in Eldoc mode
+       (when ',motion
+         (eval-after-load 'eldoc
+           '(and (fboundp 'eldoc-add-command)
+                 (eldoc-add-command ',motion))))
+       (evil-define-command ,motion (,@args)
+         ,@(when doc `(,doc))          ; avoid nil before `interactive'
+         ,@keys
+         :keep-visual t
+         (interactive ,@interactive)
+         ,@body))))
+
+(defmacro evil-narrow-to-line (&rest body)
+  "Narrow BODY to the current line.
+BODY will signal the errors 'beginning-of-line or 'end-of-line
+upon reaching the beginning or end of the current line.
+
+\(fn [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug t))
+  `(let* ((range (evil-expand (point) (point) 'line))
+          (beg (evil-range-beginning range))
+          (end (evil-range-end range))
+          (min (point-min))
+          (max (point-max)))
+     (when (save-excursion (goto-char end) (bolp))
+       (setq end (max beg (1- end))))
+     ;; don't include the newline in Normal state
+     (when (and evil-move-cursor-back
+                (not evil-move-beyond-eol)
+                (not (evil-visual-state-p))
+                (not (evil-operator-state-p)))
+       (setq end (max beg (1- end))))
+     (evil-with-restriction beg end
+       (evil-signal-without-movement
+         (condition-case err
+             (progn ,@body)
+           (beginning-of-buffer
+            (if (= beg min)
+                (signal (car err) (cdr err))
+              (signal 'beginning-of-line nil)))
+           (end-of-buffer
+            (if (= end max)
+                (signal (car err) (cdr err))
+              (signal 'end-of-line nil))))))))
+
+;; we don't want line boundaries to trigger the debugger
+;; when `debug-on-error' is t
+(add-to-list 'debug-ignored-errors "^Beginning of line$")
+(add-to-list 'debug-ignored-errors "^End of line$")
+
+(defun evil-eobp (&optional pos)
+  "Whether point is at end-of-buffer with regard to end-of-line."
+  (save-excursion
+    (when pos (goto-char pos))
+    (cond
+     ((eobp))
+     ;; the rest only pertains to Normal state
+     ((not (evil-normal-state-p))
+      nil)
+     ;; at the end of the last line
+     ((eolp)
+      (forward-char)
+      (eobp))
+     ;; at the last character of the last line
+     (t
+      (forward-char)
+      (cond
+       ((eobp))
+       ((eolp)
+        (forward-char)
+        (eobp)))))))
+
+(defun evil-move-beginning (count forward &optional backward)
+  "Move to the beginning of the COUNT next object.
+If COUNT is negative, move to the COUNT previous object.
+FORWARD is a function which moves to the end of the object, and
+BACKWARD is a function which moves to the beginning.
+If one is unspecified, the other is used with a negative argument."
+  (let* ((count (or count 1))
+         (backward (or backward
+                       #'(lambda (count)
+                           (funcall forward (- count)))))
+         (forward (or forward
+                      #'(lambda (count)
+                          (funcall backward (- count)))))
+         (opoint (point)))
+    (cond
+     ((< count 0)
+      (when (bobp)
+        (signal 'beginning-of-buffer nil))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall backward 1))
+        (unless (zerop count)
+          (goto-char (point-min)))))
+     ((> count 0)
+      (when (evil-eobp)
+        (signal 'end-of-buffer nil))
+      ;; Do we need to move past the current object?
+      (when (<= (save-excursion
+                  (funcall forward 1)
+                  (funcall backward 1)
+                  (point))
+                opoint)
+        (setq count (1+ count)))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall forward 1))
+        (if (zerop count)
+            ;; go back to beginning of object
+            (funcall backward 1)
+          (goto-char (point-max)))))
+     (t
+      count))))
+
+(defun evil-move-end (count forward &optional backward inclusive)
+  "Move to the end of the COUNT next object.
+If COUNT is negative, move to the COUNT previous object.
+FORWARD is a function which moves to the end of the object, and
+BACKWARD is a function which moves to the beginning.
+If one is unspecified, the other is used with a negative argument.
+If INCLUSIVE is non-nil, then point is placed at the last character
+of the object; otherwise it is placed at the end of the object."
+  (let* ((count (or count 1))
+         (backward (or backward
+                       #'(lambda (count)
+                           (funcall forward (- count)))))
+         (forward (or forward
+                      #'(lambda (count)
+                          (funcall backward (- count)))))
+         (opoint (point)))
+    (cond
+     ((< count 0)
+      (when (bobp)
+        (signal 'beginning-of-buffer nil))
+      ;; Do we need to move past the current object?
+      (when (>= (save-excursion
+                  (funcall backward 1)
+                  (funcall forward 1)
+                  (point))
+                (if inclusive
+                    (1+ opoint)
+                  opoint))
+        (setq count (1- count)))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall backward 1))
+        (if (not (zerop count))
+            (goto-char (point-min))
+          ;; go to end of object
+          (funcall forward 1)
+          (when inclusive
+            (unless (bobp) (backward-char)))
+          (when (or (evil-normal-state-p)
+                    (evil-motion-state-p))
+            (evil-adjust-cursor t)))))
+     ((> count 0)
+      (when (evil-eobp)
+        (signal 'end-of-buffer nil))
+      (when inclusive
+        (forward-char))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall forward 1))
+        (if (not (zerop count))
+            (goto-char (point-max))
+          (when inclusive
+            (unless (bobp) (backward-char)))
+          (when (or (evil-normal-state-p)
+                    (evil-motion-state-p))
+            (evil-adjust-cursor t)))))
+     (t
+      count))))
+
+(defun evil-text-object-make-linewise (range)
+  "Turn the text object selection RANGE to linewise.
+The selection is adjusted in a sensible way so that the selected
+lines match the user intent. In particular, whitespace-only parts
+at the first and last lines are omitted. This function returns
+the new range."
+  ;; Bug #607
+  ;; If new type is linewise and the selection of the
+  ;; first line consists of whitespace only, the
+  ;; beginning is moved to the start of the next line. If
+  ;; the selections of the last line consists of
+  ;; whitespace only, the end is moved to the end of the
+  ;; previous line.
+  (if (eq (evil-type range) 'line)
+      range
+    (let ((expanded (plist-get (evil-range-properties range) :expanded))
+          (newrange (evil-expand-range range t)))
+      (save-excursion
+        ;; skip whitespace at the beginning
+        (goto-char (evil-range-beginning newrange))
+        (skip-chars-forward " \t")
+        (when (and (not (bolp)) (eolp))
+          (evil-set-range-beginning newrange (1+ (point))))
+        ;; skip whitepsace at the end
+        (goto-char (evil-range-end newrange))
+        (skip-chars-backward " \t")
+        (when (and (not (eolp)) (bolp))
+          (evil-set-range-end newrange (1- (point))))
+        ;; only modify range if result is not empty
+        (if (> (evil-range-beginning newrange)
+               (evil-range-end newrange))
+            range
+          (unless expanded
+            (evil-contract-range newrange))
+          newrange)))))
+
+(defmacro evil-define-text-object (object args &rest body)
+  "Define a text object command OBJECT.
+BODY should return a range (BEG END) to the right of point
+if COUNT is positive, and to the left of it if negative.
+
+\(fn OBJECT (COUNT) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           def-body)))
+  (let* ((args (delq '&optional args))
+         (count (or (pop args) 'count))
+         (args (when args `(&optional ,@args)))
+         (interactive '((interactive "<c><v>")))
+         arg doc key keys)
+    ;; collect docstring
+    (when (stringp (car-safe body))
+      (setq doc (pop body)))
+    ;; collect keywords
+    (setq keys (plist-put keys :extend-selection t))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body)
+            keys (plist-put keys key arg)))
+    ;; interactive
+    (when (eq (car-safe (car-safe body)) 'interactive)
+      (setq interactive (list (pop body))))
+    ;; macro expansion
+    `(evil-define-motion ,object (,count ,@args)
+       ,@(when doc `(,doc))
+       ,@keys
+       ,@interactive
+       (setq ,count (or ,count 1))
+       (when (/= ,count 0)
+         (let ((type (evil-type ',object evil-visual-char))
+               (extend (and (evil-visual-state-p)
+                            (evil-get-command-property
+                             ',object :extend-selection
+                             ',(plist-get keys :extend-selection))))
+               (dir evil-visual-direction)
+               mark point range selection)
+           (cond
+            ;; Visual state: extend the current selection
+            ((and (evil-visual-state-p)
+                  (called-interactively-p 'any))
+             ;; if we are at the beginning of the Visual selection,
+             ;; go to the left (negative COUNT); if at the end,
+             ;; go to the right (positive COUNT)
+             (setq dir evil-visual-direction
+                   ,count (* ,count dir))
+             (setq range (progn ,@body))
+             (when (evil-range-p range)
+               (setq range (evil-expand-range range))
+               (evil-set-type range (evil-type range type))
+               (setq range (evil-contract-range range))
+               ;; the beginning is mark and the end is point
+               ;; unless the selection goes the other way
+               (setq mark  (evil-range-beginning range)
+                     point (evil-range-end range)
+                     type  (evil-type
+                            (if evil-text-object-change-visual-type
+                                range
+                              (evil-visual-range))))
+               (when (and (eq type 'line)
+                          (not (eq type (evil-type range))))
+                 (let ((newrange (evil-text-object-make-linewise range)))
+                   (setq mark (evil-range-beginning newrange)
+                         point (evil-range-end newrange))))
+               (when (< dir 0)
+                 (evil-swap mark point))
+               ;; select the union
+               (evil-visual-make-selection mark point type)))
+            ;; not Visual state: return a pair of buffer positions
+            (t
+             (setq range (progn ,@body))
+             (unless (evil-range-p range)
+               (setq ,count (- ,count)
+                     range (progn ,@body)))
+             (when (evil-range-p range)
+               (setq selection (evil-range (point) (point) type))
+               (if extend
+                   (setq range (evil-range-union range selection))
+                 (evil-set-type range (evil-type range type)))
+               ;; possibly convert to linewise
+               (when (eq evil-this-type-modified 'line)
+                 (setq range (evil-text-object-make-linewise range)))
+               (evil-set-range-properties range nil)
+               range))))))))
+
+(defmacro evil-define-operator (operator args &rest body)
+  "Define an operator command OPERATOR.
+
+\(fn OPERATOR (BEG END ARGS...) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           [&optional ("interactive" [&rest form])]
+                           def-body)))
+  (let* ((args (delq '&optional args))
+         (interactive (if (> (length args) 2) '("<R>") '("<r>")))
+         (args (if (> (length args) 2)
+                   `(,(nth 0 args) ,(nth 1 args)
+                     &optional ,@(nthcdr 2 args))
+                 args))
+         arg doc key keys visual)
+    ;; collect docstring
+    (when (and (> (length body) 1)
+               (or (eq (car-safe (car-safe body)) 'format)
+                   (stringp (car-safe body))))
+      (setq doc (pop body)))
+    ;; collect keywords
+    (setq keys (plist-put keys :move-point t))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :keep-visual)
+        (setq visual arg))
+       (t
+        (setq keys (plist-put keys key arg)))))
+    ;; collect `interactive' specification
+    (when (eq (car-safe (car-safe body)) 'interactive)
+      (setq interactive (cdr-safe (pop body))))
+    ;; transform extended interactive specs
+    (setq interactive (apply #'evil-interactive-form interactive))
+    (setq keys (evil-concat-plists keys (cdr-safe interactive))
+          interactive (car-safe interactive))
+    ;; macro expansion
+    `(evil-define-command ,operator ,args
+       ,@(when doc `(,doc))
+       ,@keys
+       :keep-visual t
+       :suppress-operator t
+       (interactive
+        (let* ((evil-operator-range-motion
+                (when (evil-has-command-property-p ',operator :motion)
+                  ;; :motion nil is equivalent to :motion undefined
+                  (or (evil-get-command-property ',operator :motion)
+                      #'undefined)))
+               (evil-operator-range-type
+                (evil-get-command-property ',operator :type))
+               (orig (point))
+               evil-operator-range-beginning
+               evil-operator-range-end
+               evil-inhibit-operator)
+          (setq evil-inhibit-operator-value nil
+                evil-this-operator this-command)
+          (prog1 ,interactive
+            (setq orig (point)
+                  evil-inhibit-operator-value evil-inhibit-operator)
+            (if ,visual
+                (when (evil-visual-state-p)
+                  (evil-visual-expand-region))
+              (when (or (evil-visual-state-p) (region-active-p))
+                (setq deactivate-mark t)))
+            (cond
+             ((evil-visual-state-p)
+              (evil-visual-rotate 'upper-left))
+             ((evil-get-command-property ',operator :move-point)
+              (goto-char (or evil-operator-range-beginning orig)))
+             (t
+              (goto-char orig))))))
+       (unwind-protect
+           (let ((evil-inhibit-operator evil-inhibit-operator-value))
+             (unless (and evil-inhibit-operator
+                          (called-interactively-p 'any))
+               ,@body))
+         (setq evil-inhibit-operator-value nil)))))
+
+;; this is used in the `interactive' specification of an operator command
+(defun evil-operator-range (&optional return-type)
+  "Read a motion from the keyboard and return its buffer positions.
+The return value is a list (BEG END), or (BEG END TYPE) if
+RETURN-TYPE is non-nil."
+  (let ((motion (or evil-operator-range-motion
+                    (when (evil-ex-p) 'evil-line)))
+        (type evil-operator-range-type)
+        (range (evil-range (point) (point)))
+        command count modifier)
+    (setq evil-this-type-modified nil)
+    (evil-save-echo-area
+      (cond
+       ;; Ex mode
+       ((and (evil-ex-p) evil-ex-range)
+        (setq range evil-ex-range))
+       ;; Visual selection
+       ((and (not (evil-ex-p)) (evil-visual-state-p))
+        (setq range (evil-visual-range)))
+       ;; active region
+       ((and (not (evil-ex-p)) (region-active-p))
+        (setq range (evil-range (region-beginning)
+                                (region-end)
+                                (or evil-this-type 'exclusive))))
+       (t
+        ;; motion
+        (evil-save-state
+          (unless motion
+            (evil-change-state 'operator)
+            ;; Make linewise operator shortcuts. E.g., "d" yields the
+            ;; shortcut "dd", and "g?" yields shortcuts "g??" and "g?g?".
+            (let ((keys (nth 2 (evil-extract-count (this-command-keys)))))
+              (setq keys (listify-key-sequence keys))
+              (dotimes (var (length keys))
+                (define-key evil-operator-shortcut-map
+                  (vconcat (nthcdr var keys)) 'evil-line)))
+            ;; read motion from keyboard
+            (setq command (evil-read-motion motion)
+                  motion (nth 0 command)
+                  count (nth 1 command)
+                  type (or type (nth 2 command))))
+          (cond
+           ((eq motion #'undefined)
+            (setq range (if return-type '(nil nil nil) '(nil nil))
+                  motion nil))
+           ((or (null motion) ; keyboard-quit
+                (evil-get-command-property motion :suppress-operator))
+            (when (fboundp 'evil-repeat-abort)
+              (evil-repeat-abort))
+            (setq quit-flag t
+                  motion nil))
+           (evil-repeat-count
+            (setq count evil-repeat-count
+                  ;; only the first operator's count is overwritten
+                  evil-repeat-count nil))
+           ((or count current-prefix-arg)
+            ;; multiply operator count and motion count together
+            (setq count
+                  (* (prefix-numeric-value count)
+                     (prefix-numeric-value current-prefix-arg)))))
+          (when motion
+            (let ((evil-state 'operator)
+                  mark-active)
+              ;; calculate motion range
+              (setq range (evil-motion-range
+                           motion
+                           count
+                           type))))
+          ;; update global variables
+          (setq evil-this-motion motion
+                evil-this-motion-count count
+                type (evil-type range type)
+                evil-this-type type))))
+      (when (evil-range-p range)
+        (unless (or (null type) (eq (evil-type range) type))
+          (evil-contract-range range)
+          (evil-set-type range type)
+          (evil-expand-range range))
+        (evil-set-range-properties range nil)
+        (unless return-type
+          (evil-set-type range nil))
+        (setq evil-operator-range-beginning (evil-range-beginning range)
+              evil-operator-range-end (evil-range-end range)
+              evil-operator-range-type (evil-type range)))
+      range)))
+
+(defmacro evil-define-type (type doc &rest body)
+  "Define type TYPE.
+DOC is a general description and shows up in all docstrings.
+It is followed by a list of keywords and functions:
+
+:expand FUNC     Expansion function. This function should accept
+                 two positions in the current buffer, BEG and END,
+                 and return a pair of expanded buffer positions.
+:contract FUNC   The opposite of :expand, optional.
+:one-to-one BOOL Whether expansion is one-to-one. This means that
+                 :expand followed by :contract always returns the
+                 original range.
+:normalize FUNC  Normalization function, optional. This function should
+                 accept two unexpanded positions and adjust them before
+                 expansion. May be used to deal with buffer boundaries.
+:string FUNC     Description function. This takes two buffer positions
+                 and returns a human-readable string, for example,
+                 \"2 lines\".
+
+If further keywords and functions are specified, they are assumed to
+be transformations on buffer positions, like :expand and :contract.
+
+\(fn TYPE DOC [[KEY FUNC]...])"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp function-form]])))
+  (let (args defun-forms func key name plist string sym val)
+    ;; standard values
+    (setq plist (plist-put plist :one-to-one t))
+    ;; keywords
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            val (pop body))
+      (if (plist-member plist key) ; not a function
+          (setq plist (plist-put plist key val))
+        (setq func val
+              sym (intern (replace-regexp-in-string
+                           "^:" "" (symbol-name key)))
+              name (intern (format "evil-%s-%s" type sym))
+              args (car (cdr-safe func))
+              string (car (cdr (cdr-safe func)))
+              string (if (stringp string)
+                         (format "%s\n\n" string) "")
+              plist (plist-put plist key `',name))
+        (add-to-list
+         'defun-forms
+         (cond
+          ((eq key :string)
+           `(defun ,name (beg end &rest properties)
+              ,(format "Return size of %s from BEG to END \
+with PROPERTIES.\n\n%s%s" type string doc)
+              (let ((beg (evil-normalize-position beg))
+                    (end (evil-normalize-position end))
+                    (type ',type)
+                    plist range)
+                (when (and beg end)
+                  (save-excursion
+                    (evil-sort beg end)
+                    (unless (plist-get properties :expanded)
+                      (setq range (apply #'evil-expand
+                                         beg end type properties)
+                            beg (evil-range-beginning range)
+                            end (evil-range-end range)
+                            type (evil-type range type)
+                            plist (evil-range-properties range))
+                      (setq properties
+                            (evil-concat-plists properties plist)))
+                    (or (apply #',func beg end
+                               (when ,(> (length args) 2)
+                                 properties))
+                        ""))))))
+          (t
+           `(defun ,name (beg end &rest properties)
+              ,(format "Perform %s transformation on %s from BEG to END \
+with PROPERTIES.\n\n%s%s" sym type string doc)
+              (let ((beg (evil-normalize-position beg))
+                    (end (evil-normalize-position end))
+                    (type ',type)
+                    plist range)
+                (when (and beg end)
+                  (save-excursion
+                    (evil-sort beg end)
+                    (when (memq ,key '(:expand :contract))
+                      (setq properties
+                            (plist-put properties
+                                       :expanded
+                                       ,(eq key :expand))))
+                    (setq range (or (apply #',func beg end
+                                           (when ,(> (length args) 2)
+                                             properties))
+                                    (apply #'evil-range
+                                           beg end type properties))
+                          beg (evil-range-beginning range)
+                          end (evil-range-end range)
+                          type (evil-type range type)
+                          plist (evil-range-properties range))
+                    (setq properties
+                          (evil-concat-plists properties plist))
+                    (apply #'evil-range beg end type properties)))))))
+         t)))
+    ;; :one-to-one requires both or neither of :expand and :contract
+    (when (plist-get plist :expand)
+      (setq plist (plist-put plist :one-to-one
+                             (and (plist-get plist :contract)
+                                  (plist-get plist :one-to-one)))))
+    `(progn
+       (evil-put-property 'evil-type-properties ',type ,@plist)
+       ,@defun-forms
+       ',type)))
+
+(defmacro evil-define-interactive-code (code &rest body)
+  "Define an interactive code.
+PROMPT, if given, is the remainder of the interactive string
+up to the next newline. Command properties may be specified
+via KEY-VALUE pairs. BODY should evaluate to a list of values.
+
+\(fn CODE (PROMPT) [[KEY VALUE]...] BODY...)"
+  (declare (indent defun))
+  (let* ((args (when (and (> (length body) 1)
+                          (listp (car-safe body)))
+                 (pop body)))
+         (doc (when (stringp (car-safe body)) (pop body)))
+         func properties)
+    (while (keywordp (car-safe body))
+      (setq properties
+            (append properties (list (pop body) (pop body)))))
+    (cond
+     (args
+      (setq func `(lambda ,args
+                    ,@(when doc `(,doc))
+                    ,@body)))
+     ((> (length body) 1)
+      (setq func `(progn ,@body)))
+     (t
+      (setq func (car body))))
+    `(eval-and-compile
+       (let* ((code ,code)
+              (entry (assoc code evil-interactive-alist))
+              (value (cons ',func ',properties)))
+         (if entry
+             (setcdr entry value)
+           (push (cons code value) evil-interactive-alist))
+         code))))
+
+;;; Highlighting
+
+(when (fboundp 'font-lock-add-keywords)
+  (font-lock-add-keywords
+   'emacs-lisp-mode
+   ;; Match all `evil-define-' forms except `evil-define-key'.
+   ;; (In the interests of speed, this expression is incomplete
+   ;; and does not match all three-letter words.)
+   '(("(\\(evil-\\(?:ex-\\)?define-\
+\\(?:[^ k][^ e][^ y]\\|[-[:word:]]\\{4,\\}\\)\\)\
+\\>[ \f\t\n\r\v]*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
+      (1 font-lock-keyword-face)
+      (2 font-lock-function-name-face nil t))
+     ("(\\(evil-\\(?:delay\\|narrow\\|signal\\|save\\|with\\(?:out\\)?\\)\
+\\(?:-[-[:word:]]+\\)?\\)\\>\[ \f\t\n\r\v]+"
+      1 font-lock-keyword-face)
+     ("(\\(evil-\\(?:[-[:word:]]\\)*loop\\)\\>[ \f\t\n\r\v]+"
+      1 font-lock-keyword-face))))
+
+(provide 'evil-macros)
+
+;;; evil-macros.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-macros.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-maps.el
@@ -0,0 +1,559 @@
+;;; evil-maps.el --- Default keymaps
+
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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-states)
+(require 'evil-ex)
+(require 'evil-commands)
+(require 'evil-command-window)
+(require 'evil-common)
+
+;;; Code:
+
+;;; Normal state
+
+(define-key evil-normal-state-map "a" 'evil-append)
+(define-key evil-normal-state-map "A" 'evil-append-line)
+(define-key evil-normal-state-map "c" 'evil-change)
+(define-key evil-normal-state-map "C" 'evil-change-line)
+(define-key evil-normal-state-map "d" 'evil-delete)
+(define-key evil-normal-state-map "D" 'evil-delete-line)
+(define-key evil-normal-state-map "i" 'evil-insert)
+(define-key evil-normal-state-map (kbd "<insert>") 'evil-insert)
+(define-key evil-normal-state-map (kbd "<insertchar>") 'evil-insert)
+(define-key evil-normal-state-map "I" 'evil-insert-line)
+(define-key evil-normal-state-map "J" 'evil-join)
+(define-key evil-normal-state-map "m" 'evil-set-marker)
+(define-key evil-normal-state-map "o" 'evil-open-below)
+(define-key evil-normal-state-map "O" 'evil-open-above)
+(define-key evil-normal-state-map "p" 'evil-paste-after)
+(define-key evil-normal-state-map "P" 'evil-paste-before)
+(define-key evil-normal-state-map "q" 'evil-record-macro)
+(define-key evil-normal-state-map "r" 'evil-replace)
+(define-key evil-normal-state-map "R" 'evil-replace-state)
+(define-key evil-normal-state-map "s" 'evil-substitute)
+(define-key evil-normal-state-map "S" 'evil-change-whole-line)
+(define-key evil-normal-state-map "x" 'evil-delete-char)
+(define-key evil-normal-state-map "X" 'evil-delete-backward-char)
+(define-key evil-normal-state-map [deletechar] 'evil-delete-char)
+(define-key evil-normal-state-map "y" 'evil-yank)
+(define-key evil-normal-state-map "Y" 'evil-yank-line)
+(define-key evil-normal-state-map "&" 'evil-ex-repeat-substitute)
+(define-key evil-normal-state-map "g&" 'evil-ex-repeat-global-substitute)
+(define-key evil-normal-state-map "g8" 'what-cursor-position)
+(define-key evil-normal-state-map "ga" 'what-cursor-position)
+(define-key evil-normal-state-map "gi" 'evil-insert-resume)
+(define-key evil-normal-state-map "gJ" 'evil-join-whitespace)
+(define-key evil-normal-state-map "gq" 'evil-fill-and-move)
+(define-key evil-normal-state-map "gw" 'evil-fill)
+(define-key evil-normal-state-map "gu" 'evil-downcase)
+(define-key evil-normal-state-map "gU" 'evil-upcase)
+(define-key evil-normal-state-map "gf" 'find-file-at-point)
+(define-key evil-normal-state-map "gF" 'evil-find-file-at-point-with-line)
+(define-key evil-normal-state-map "g?" 'evil-rot13)
+(define-key evil-normal-state-map "g~" 'evil-invert-case)
+(define-key evil-normal-state-map "zo" 'evil-open-fold)
+(define-key evil-normal-state-map "zO" 'evil-open-fold-rec)
+(define-key evil-normal-state-map "zc" 'evil-close-fold)
+(define-key evil-normal-state-map "za" 'evil-toggle-fold)
+(define-key evil-normal-state-map "zr" 'evil-open-folds)
+(define-key evil-normal-state-map "zm" 'evil-close-folds)
+(define-key evil-normal-state-map "z=" 'ispell-word)
+(define-key evil-normal-state-map "\C-n" 'evil-paste-pop-next)
+(define-key evil-normal-state-map "\C-p" 'evil-paste-pop)
+(define-key evil-normal-state-map "\C-t" 'pop-tag-mark)
+(define-key evil-normal-state-map (kbd "C-.") 'evil-repeat-pop)
+(define-key evil-normal-state-map (kbd "M-.") 'evil-repeat-pop-next)
+(define-key evil-normal-state-map "." 'evil-repeat)
+(define-key evil-normal-state-map "@" 'evil-execute-macro)
+(define-key evil-normal-state-map "\"" 'evil-use-register)
+(define-key evil-normal-state-map "~" 'evil-invert-char)
+(define-key evil-normal-state-map "=" 'evil-indent)
+(define-key evil-normal-state-map "<" 'evil-shift-left)
+(define-key evil-normal-state-map ">" 'evil-shift-right)
+(define-key evil-normal-state-map "ZZ" 'evil-save-modified-and-close)
+(define-key evil-normal-state-map "ZQ" 'evil-quit)
+(define-key evil-normal-state-map (kbd "DEL") 'evil-backward-char)
+(define-key evil-normal-state-map [escape] 'evil-force-normal-state)
+(define-key evil-normal-state-map [remap cua-paste-pop] 'evil-paste-pop)
+(define-key evil-normal-state-map [remap yank-pop] 'evil-paste-pop)
+
+;; go to last change
+(define-key evil-normal-state-map "g;" 'goto-last-change)
+(define-key evil-normal-state-map "g," 'goto-last-change-reverse)
+
+;; undo
+(define-key evil-normal-state-map "u" 'undo)
+(define-key evil-normal-state-map "\C-r" 'redo)
+
+;; window commands
+(define-prefix-command 'evil-window-map)
+(define-key evil-window-map "b" 'evil-window-bottom-right)
+(define-key evil-window-map "c" 'evil-window-delete)
+(define-key evil-window-map "h" 'evil-window-left)
+(define-key evil-window-map "H" 'evil-window-move-far-left)
+(define-key evil-window-map "j" 'evil-window-down)
+(define-key evil-window-map "J" 'evil-window-move-very-bottom)
+(define-key evil-window-map "k" 'evil-window-up)
+(define-key evil-window-map "K" 'evil-window-move-very-top)
+(define-key evil-window-map "l" 'evil-window-right)
+(define-key evil-window-map "L" 'evil-window-move-far-right)
+(define-key evil-window-map "n" 'evil-window-new)
+(define-key evil-window-map "o" 'delete-other-windows)
+(define-key evil-window-map "p" 'evil-window-mru)
+(define-key evil-window-map "q" 'evil-quit)
+(define-key evil-window-map "r" 'evil-window-rotate-downwards)
+(define-key evil-window-map "R" 'evil-window-rotate-upwards)
+(define-key evil-window-map "s" 'evil-window-split)
+(define-key evil-window-map "S" 'evil-window-split)
+(define-key evil-window-map "t" 'evil-window-top-left)
+(define-key evil-window-map "v" 'evil-window-vsplit)
+(define-key evil-window-map "w" 'evil-window-next)
+(define-key evil-window-map "W" 'evil-window-prev)
+(define-key evil-window-map "+" 'evil-window-increase-height)
+(define-key evil-window-map "-" 'evil-window-decrease-height)
+(define-key evil-window-map "_" 'evil-window-set-height)
+(define-key evil-window-map "<" 'evil-window-decrease-width)
+(define-key evil-window-map ">" 'evil-window-increase-width)
+(define-key evil-window-map "=" 'balance-windows)
+(define-key evil-window-map "|" 'evil-window-set-width)
+(define-key evil-window-map "\C-b" 'evil-window-bottom-right)
+(define-key evil-window-map "\C-c" 'evil-window-delete)
+(define-key evil-window-map (kbd "C-S-h") 'evil-window-move-far-left)
+(define-key evil-window-map (kbd "C-S-j") 'evil-window-move-very-bottom)
+(define-key evil-window-map (kbd "C-S-k") 'evil-window-move-very-top)
+(define-key evil-window-map (kbd "C-S-l") 'evil-window-move-far-right)
+(define-key evil-window-map "\C-n" 'evil-window-new)
+(define-key evil-window-map "\C-o" 'delete-other-windows)
+(define-key evil-window-map "\C-p" 'evil-window-mru)
+(define-key evil-window-map "\C-r" 'evil-window-rotate-downwards)
+(define-key evil-window-map (kbd "C-S-r") 'evil-window-rotate-upwards)
+(define-key evil-window-map "\C-s" 'evil-window-split)
+(define-key evil-window-map (kbd "C-S-s") 'evil-window-split)
+(define-key evil-window-map "\C-t" 'evil-window-top-left)
+(define-key evil-window-map "\C-v" 'evil-window-vsplit)
+(define-key evil-window-map "\C-w" 'evil-window-next)
+(define-key evil-window-map (kbd "C-S-W") 'evil-window-prev)
+(define-key evil-window-map "\C-_" 'evil-window-set-height)
+(define-key evil-window-map "\C-f" 'ffap-other-window)
+
+;;; Motion state
+
+;; "0" is a special command when called first
+(evil-redirect-digit-argument evil-motion-state-map "0" 'evil-beginning-of-line)
+(define-key evil-motion-state-map "1" 'digit-argument)
+(define-key evil-motion-state-map "2" 'digit-argument)
+(define-key evil-motion-state-map "3" 'digit-argument)
+(define-key evil-motion-state-map "4" 'digit-argument)
+(define-key evil-motion-state-map "5" 'digit-argument)
+(define-key evil-motion-state-map "6" 'digit-argument)
+(define-key evil-motion-state-map "7" 'digit-argument)
+(define-key evil-motion-state-map "8" 'digit-argument)
+(define-key evil-motion-state-map "9" 'digit-argument)
+(define-key evil-motion-state-map "b" 'evil-backward-word-begin)
+(define-key evil-motion-state-map "B" 'evil-backward-WORD-begin)
+(define-key evil-motion-state-map "e" 'evil-forward-word-end)
+(define-key evil-motion-state-map "E" 'evil-forward-WORD-end)
+(define-key evil-motion-state-map "f" 'evil-find-char)
+(define-key evil-motion-state-map "F" 'evil-find-char-backward)
+(define-key evil-motion-state-map "G" 'evil-goto-line)
+(define-key evil-motion-state-map "h" 'evil-backward-char)
+(define-key evil-motion-state-map "H" 'evil-window-top)
+(define-key evil-motion-state-map "j" 'evil-next-line)
+(define-key evil-motion-state-map "k" 'evil-previous-line)
+(define-key evil-motion-state-map "l" 'evil-forward-char)
+(define-key evil-motion-state-map " " 'evil-forward-char)
+(define-key evil-motion-state-map "K" 'evil-lookup)
+(define-key evil-motion-state-map "L" 'evil-window-bottom)
+(define-key evil-motion-state-map "M" 'evil-window-middle)
+(define-key evil-motion-state-map "n" 'evil-search-next)
+(define-key evil-motion-state-map "N" 'evil-search-previous)
+(define-key evil-motion-state-map "t" 'evil-find-char-to)
+(define-key evil-motion-state-map "T" 'evil-find-char-to-backward)
+(define-key evil-motion-state-map "w" 'evil-forward-word-begin)
+(define-key evil-motion-state-map "W" 'evil-forward-WORD-begin)
+(define-key evil-motion-state-map "y" 'evil-yank)
+(define-key evil-motion-state-map "Y" 'evil-yank-line)
+(define-key evil-motion-state-map "gd" 'evil-goto-definition)
+(define-key evil-motion-state-map "ge" 'evil-backward-word-end)
+(define-key evil-motion-state-map "gE" 'evil-backward-WORD-end)
+(define-key evil-motion-state-map "gg" 'evil-goto-first-line)
+(define-key evil-motion-state-map "gj" 'evil-next-visual-line)
+(define-key evil-motion-state-map "gk" 'evil-previous-visual-line)
+(define-key evil-motion-state-map "g0" 'evil-beginning-of-visual-line)
+(define-key evil-motion-state-map "g_" 'evil-last-non-blank)
+(define-key evil-motion-state-map "g^" 'evil-first-non-blank-of-visual-line)
+(define-key evil-motion-state-map "gm" 'evil-middle-of-visual-line)
+(define-key evil-motion-state-map "g$" 'evil-end-of-visual-line)
+(define-key evil-motion-state-map "g\C-]" 'find-tag)
+(define-key evil-motion-state-map "{" 'evil-backward-paragraph)
+(define-key evil-motion-state-map "}" 'evil-forward-paragraph)
+(define-key evil-motion-state-map "#" 'evil-search-word-backward)
+(define-key evil-motion-state-map "g#" 'evil-search-unbounded-word-backward)
+(define-key evil-motion-state-map "$" 'evil-end-of-line)
+(define-key evil-motion-state-map "%" 'evil-jump-item)
+(define-key evil-motion-state-map "`" 'evil-goto-mark)
+(define-key evil-motion-state-map "'" 'evil-goto-mark-line)
+(define-key evil-motion-state-map "(" 'evil-backward-sentence-begin)
+(define-key evil-motion-state-map ")" 'evil-forward-sentence-begin)
+(define-key evil-motion-state-map "]]" 'evil-forward-section-begin)
+(define-key evil-motion-state-map "][" 'evil-forward-section-end)
+(define-key evil-motion-state-map "[[" 'evil-backward-section-begin)
+(define-key evil-motion-state-map "[]" 'evil-backward-section-end)
+(define-key evil-motion-state-map "[(" 'evil-previous-open-paren)
+(define-key evil-motion-state-map "])" 'evil-next-close-paren)
+(define-key evil-motion-state-map "[{" 'evil-previous-open-brace)
+(define-key evil-motion-state-map "]}" 'evil-next-close-brace)
+(define-key evil-motion-state-map "]s" 'evil-next-flyspell-error)
+(define-key evil-motion-state-map "[s" 'evil-prev-flyspell-error)
+(define-key evil-motion-state-map "*" 'evil-search-word-forward)
+(define-key evil-motion-state-map "g*" 'evil-search-unbounded-word-forward)
+(define-key evil-motion-state-map "," 'evil-repeat-find-char-reverse)
+(define-key evil-motion-state-map "/" 'evil-search-forward)
+(define-key evil-motion-state-map ";" 'evil-repeat-find-char)
+(define-key evil-motion-state-map "?" 'evil-search-backward)
+(define-key evil-motion-state-map "|" 'evil-goto-column)
+(define-key evil-motion-state-map "^" 'evil-first-non-blank)
+(define-key evil-motion-state-map "+" 'evil-next-line-first-non-blank)
+(define-key evil-motion-state-map "_" 'evil-next-line-1-first-non-blank)
+(define-key evil-motion-state-map "-" 'evil-previous-line-first-non-blank)
+(define-key evil-motion-state-map "\C-w" 'evil-window-map)
+(define-key evil-motion-state-map (kbd "C-6") 'evil-switch-to-windows-last-buffer)
+(define-key evil-motion-state-map "\C-]" 'evil-jump-to-tag)
+(define-key evil-motion-state-map (kbd "C-b") 'evil-scroll-page-up)
+(define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down)
+(define-key evil-motion-state-map (kbd "C-e") 'evil-scroll-line-down)
+(define-key evil-motion-state-map (kbd "C-f") 'evil-scroll-page-down)
+(define-key evil-motion-state-map (kbd "C-o") 'evil-jump-backward)
+(define-key evil-motion-state-map (kbd "C-y") 'evil-scroll-line-up)
+(define-key evil-motion-state-map (kbd "RET") 'evil-ret)
+(define-key evil-motion-state-map "\\" 'evil-execute-in-emacs-state)
+(define-key evil-motion-state-map "z^" 'evil-scroll-top-line-to-bottom)
+(define-key evil-motion-state-map "z+" 'evil-scroll-bottom-line-to-top)
+(define-key evil-motion-state-map "zt" 'evil-scroll-line-to-top)
+;; TODO: z RET has an advanced form taking an count before the RET
+;; but this requires again a special state with a single command
+;; bound to RET
+(define-key evil-motion-state-map (vconcat "z" [return]) "zt^")
+(define-key evil-motion-state-map (kbd "z RET") (vconcat "z" [return]))
+(define-key evil-motion-state-map "zz" 'evil-scroll-line-to-center)
+(define-key evil-motion-state-map "z." "zz^")
+(define-key evil-motion-state-map "zb" 'evil-scroll-line-to-bottom)
+(define-key evil-motion-state-map "z-" "zb^")
+(define-key evil-motion-state-map "v" 'evil-visual-char)
+(define-key evil-motion-state-map "V" 'evil-visual-line)
+(define-key evil-motion-state-map "\C-v" 'evil-visual-block)
+(define-key evil-motion-state-map "gv" 'evil-visual-restore)
+(define-key evil-motion-state-map (kbd "C-^") 'evil-buffer)
+(define-key evil-motion-state-map [left] 'evil-backward-char)
+(define-key evil-motion-state-map [right] 'evil-forward-char)
+(define-key evil-motion-state-map [up] 'evil-previous-line)
+(define-key evil-motion-state-map [down] 'evil-next-line)
+(define-key evil-motion-state-map "zl" 'evil-scroll-column-right)
+(define-key evil-motion-state-map [?z right] "zl")
+(define-key evil-motion-state-map "zh" 'evil-scroll-column-left)
+(define-key evil-motion-state-map [?z left] "zh")
+(define-key evil-motion-state-map "zL" 'evil-scroll-right)
+(define-key evil-motion-state-map "zH" 'evil-scroll-left)
+(define-key evil-motion-state-map
+  (read-kbd-macro evil-toggle-key) 'evil-emacs-state)
+
+;; text objects
+(define-key evil-outer-text-objects-map "w" 'evil-a-word)
+(define-key evil-outer-text-objects-map "W" 'evil-a-WORD)
+(define-key evil-outer-text-objects-map "s" 'evil-a-sentence)
+(define-key evil-outer-text-objects-map "p" 'evil-a-paragraph)
+(define-key evil-outer-text-objects-map "b" 'evil-a-paren)
+(define-key evil-outer-text-objects-map "(" 'evil-a-paren)
+(define-key evil-outer-text-objects-map ")" 'evil-a-paren)
+(define-key evil-outer-text-objects-map "[" 'evil-a-bracket)
+(define-key evil-outer-text-objects-map "]" 'evil-a-bracket)
+(define-key evil-outer-text-objects-map "B" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "{" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "}" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "<" 'evil-an-angle)
+(define-key evil-outer-text-objects-map ">" 'evil-an-angle)
+(define-key evil-outer-text-objects-map "'" 'evil-a-single-quote)
+(define-key evil-outer-text-objects-map "\"" 'evil-a-double-quote)
+(define-key evil-outer-text-objects-map "`" 'evil-a-back-quote)
+(define-key evil-outer-text-objects-map "t" 'evil-a-tag)
+(define-key evil-outer-text-objects-map "o" 'evil-a-symbol)
+(define-key evil-inner-text-objects-map "w" 'evil-inner-word)
+(define-key evil-inner-text-objects-map "W" 'evil-inner-WORD)
+(define-key evil-inner-text-objects-map "s" 'evil-inner-sentence)
+(define-key evil-inner-text-objects-map "p" 'evil-inner-paragraph)
+(define-key evil-inner-text-objects-map "b" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map "(" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map ")" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map "[" 'evil-inner-bracket)
+(define-key evil-inner-text-objects-map "]" 'evil-inner-bracket)
+(define-key evil-inner-text-objects-map "B" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "{" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "}" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "<" 'evil-inner-angle)
+(define-key evil-inner-text-objects-map ">" 'evil-inner-angle)
+(define-key evil-inner-text-objects-map "'" 'evil-inner-single-quote)
+(define-key evil-inner-text-objects-map "\"" 'evil-inner-double-quote)
+(define-key evil-inner-text-objects-map "`" 'evil-inner-back-quote)
+(define-key evil-inner-text-objects-map "t" 'evil-inner-tag)
+(define-key evil-inner-text-objects-map "o" 'evil-inner-symbol)
+(define-key evil-motion-state-map "gn" 'evil-next-match)
+(define-key evil-motion-state-map "gN" 'evil-previous-match)
+
+(when evil-want-C-i-jump
+  (define-key evil-motion-state-map (kbd "C-i") 'evil-jump-forward))
+
+(when evil-want-C-u-scroll
+  (define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up))
+
+;;; Visual state
+
+(define-key evil-visual-state-map "A" 'evil-append)
+(define-key evil-visual-state-map "I" 'evil-insert)
+(define-key evil-visual-state-map "o" 'exchange-point-and-mark)
+(define-key evil-visual-state-map "O" 'evil-visual-exchange-corners)
+(define-key evil-visual-state-map "R" 'evil-change)
+(define-key evil-visual-state-map "u" 'evil-downcase)
+(define-key evil-visual-state-map "U" 'evil-upcase)
+(define-key evil-visual-state-map "z=" 'ispell-word)
+(define-key evil-visual-state-map "a" evil-outer-text-objects-map)
+(define-key evil-visual-state-map "i" evil-inner-text-objects-map)
+(define-key evil-visual-state-map (kbd "<insert>") 'undefined)
+(define-key evil-visual-state-map (kbd "<insertchar>") 'undefined)
+(define-key evil-visual-state-map [remap evil-repeat] 'undefined)
+(define-key evil-visual-state-map [escape] 'evil-exit-visual-state)
+
+;;; Operator-Pending state
+
+(define-key evil-operator-state-map "a" evil-outer-text-objects-map)
+(define-key evil-operator-state-map "i" evil-inner-text-objects-map)
+;; (define-key evil-operator-state-map [escape] 'keyboard-quit)
+
+;;; Insert state
+
+(defvar evil-insert-state-bindings
+  `(("\C-v" . quoted-insert)
+    ("\C-k" . evil-insert-digraph)
+    ("\C-o" . evil-execute-in-normal-state)
+    ("\C-r" . evil-paste-from-register)
+    ("\C-y" . evil-copy-from-above)
+    ("\C-e" . evil-copy-from-below)
+    ("\C-n" . evil-complete-next)
+    ("\C-p" . evil-complete-previous)
+    ("\C-x\C-n" . evil-complete-next-line)
+    ("\C-x\C-p" . evil-complete-previous-line)
+    ("\C-t" . evil-shift-right-line)
+    ("\C-d" . evil-shift-left-line)
+    ("\C-a" . evil-paste-last-insertion)
+    ([remap delete-backward-char] . evil-delete-backward-char-and-join)
+    ,(if evil-want-C-w-delete
+         '("\C-w" . evil-delete-backward-word)
+       '("\C-w" . evil-window-map))
+    ([mouse-2] . mouse-yank-primary))
+  "Evil's bindings for insert state (for
+`evil-insert-state-map'), excluding <delete>, <escape>, and
+`evil-toggle-key'.")
+
+(defun evil-update-insert-state-bindings (&optional _option-name remove force)
+  "Update bindings in `evil-insert-state-map'.
+If no arguments are given add the bindings specified in
+`evil-insert-state-bindings'. If REMOVE is non nil, remove only
+these bindings. Unless FORCE is non nil, this will not
+overwriting existing bindings, which means bindings will not be
+added if one already exists for a key and only default bindings
+are removed.
+
+Note that <delete>, <escape> and `evil-toggle-key' are not
+included in `evil-insert-state-bindings' by default."
+  (interactive)
+  (dolist (binding evil-insert-state-bindings)
+    (cond
+     ((and remove
+           (or force
+               ;; Only remove if the default binding has not changed
+               (eq (evil-lookup-key evil-insert-state-map (car binding))
+                   (cdr binding))))
+      (define-key evil-insert-state-map (car binding) nil))
+     ((and (null remove)
+           (or force
+               ;; Check to see that nothing is bound here before adding
+               (not (evil-lookup-key evil-insert-state-map (car binding)))))
+      (define-key evil-insert-state-map (car binding) (cdr binding))))))
+
+(define-key evil-insert-state-map [delete] 'delete-char)
+(define-key evil-insert-state-map [escape] 'evil-normal-state)
+(define-key evil-insert-state-map
+  (read-kbd-macro evil-toggle-key) 'evil-emacs-state)
+
+;;; Replace state
+
+(define-key evil-replace-state-map (kbd "DEL") 'evil-replace-backspace)
+(define-key evil-replace-state-map [escape] 'evil-normal-state)
+
+;;; Emacs state
+
+(define-key evil-emacs-state-map
+  (read-kbd-macro evil-toggle-key) 'evil-exit-emacs-state)
+
+(when evil-want-C-w-in-emacs-state
+  (define-key evil-emacs-state-map "\C-w" 'evil-window-map))
+
+;;; Mouse
+(define-key evil-motion-state-map [down-mouse-1] 'evil-mouse-drag-region)
+(define-key evil-visual-state-map [mouse-2] 'evil-exit-visual-and-repeat)
+(define-key evil-normal-state-map [mouse-2] 'mouse-yank-primary)
+
+;; Ex
+(define-key evil-motion-state-map ":" 'evil-ex)
+(define-key evil-motion-state-map "!" 'evil-shell-command)
+
+(evil-ex-define-cmd "e[dit]" 'evil-edit)
+(evil-ex-define-cmd "w[rite]" 'evil-write)
+(evil-ex-define-cmd "wa[ll]" 'evil-write-all)
+(evil-ex-define-cmd "sav[eas]" 'evil-save)
+(evil-ex-define-cmd "r[ead]" 'evil-read)
+(evil-ex-define-cmd "b[uffer]" 'evil-buffer)
+(evil-ex-define-cmd "bn[ext]" 'evil-next-buffer)
+(evil-ex-define-cmd "bp[revious]" 'evil-prev-buffer)
+(evil-ex-define-cmd "bN[ext]" "bprevious")
+(evil-ex-define-cmd "sb[uffer]" 'evil-split-buffer)
+(evil-ex-define-cmd "sbn[ext]" 'evil-split-next-buffer)
+(evil-ex-define-cmd "sbp[revious]" 'evil-split-prev-buffer)
+(evil-ex-define-cmd "sbN[ext]" "sbprevious")
+(evil-ex-define-cmd "buffers" 'buffer-menu)
+(evil-ex-define-cmd "files" 'evil-show-files)
+(evil-ex-define-cmd "ls" "buffers")
+
+(evil-ex-define-cmd "c[hange]" 'evil-change)
+(evil-ex-define-cmd "co[py]" 'evil-copy)
+(evil-ex-define-cmd "t" "copy")
+(evil-ex-define-cmd "m[ove]" 'evil-move)
+(evil-ex-define-cmd "d[elete]" 'evil-ex-delete)
+(evil-ex-define-cmd "y[ank]" 'evil-ex-yank)
+(evil-ex-define-cmd "go[to]" 'evil-goto-char)
+(evil-ex-define-cmd "j[oin]" 'evil-ex-join)
+(evil-ex-define-cmd "le[ft]" 'evil-align-left)
+(evil-ex-define-cmd "ri[ght]" 'evil-align-right)
+(evil-ex-define-cmd "ce[nter]" 'evil-align-center)
+(evil-ex-define-cmd "sp[lit]" 'evil-window-split)
+(evil-ex-define-cmd "vs[plit]" 'evil-window-vsplit)
+(evil-ex-define-cmd "new" 'evil-window-new)
+(evil-ex-define-cmd "ene[w]" 'evil-buffer-new)
+(evil-ex-define-cmd "vne[w]" 'evil-window-vnew)
+(evil-ex-define-cmd "clo[se]" 'evil-window-delete)
+(evil-ex-define-cmd "on[ly]" 'delete-other-windows)
+(evil-ex-define-cmd "q[uit]" 'evil-quit)
+(evil-ex-define-cmd "wq" 'evil-save-and-close)
+(evil-ex-define-cmd "quita[ll]" 'evil-quit-all)
+(evil-ex-define-cmd "qa[ll]" "quitall")
+(evil-ex-define-cmd "cq[uit]" 'evil-quit-all-with-error-code)
+(evil-ex-define-cmd "wqa[ll]" 'evil-save-and-quit)
+(evil-ex-define-cmd "xa[ll]" "wqall")
+(evil-ex-define-cmd "x[it]" 'evil-save-modified-and-close)
+(evil-ex-define-cmd "exi[t]" 'evil-save-modified-and-close)
+(evil-ex-define-cmd "bd[elete]" 'evil-delete-buffer)
+(evil-ex-define-cmd "bw[ipeout]" 'evil-delete-buffer)
+(evil-ex-define-cmd "g[lobal]" 'evil-ex-global)
+(evil-ex-define-cmd "v[global]" 'evil-ex-global-inverted)
+(evil-ex-define-cmd "norm[al]" 'evil-ex-normal)
+(evil-ex-define-cmd "s[ubstitute]" 'evil-ex-substitute)
+(evil-ex-define-cmd "&" 'evil-ex-repeat-substitute)
+(evil-ex-define-cmd "&&" 'evil-ex-repeat-substitute-with-flags)
+(evil-ex-define-cmd "~" 'evil-ex-repeat-substitute-with-search)
+(evil-ex-define-cmd "~&" 'evil-ex-repeat-substitute-with-search-and-flags)
+(evil-ex-define-cmd "registers" 'evil-show-registers)
+(evil-ex-define-cmd "marks" 'evil-show-marks)
+(evil-ex-define-cmd "delm[arks]" 'evil-delete-marks)
+(evil-ex-define-cmd "ju[mps]" 'evil-show-jumps)
+(evil-ex-define-cmd "noh[lsearch]" 'evil-ex-nohighlight)
+(evil-ex-define-cmd "f[ile]" 'evil-show-file-info)
+(evil-ex-define-cmd "<" 'evil-shift-left)
+(evil-ex-define-cmd ">" 'evil-shift-right)
+(evil-ex-define-cmd "=" 'evil-ex-line-number)
+(evil-ex-define-cmd "!" 'evil-shell-command)
+(evil-ex-define-cmd "@:" 'evil-ex-repeat)
+(evil-ex-define-cmd "mak[e]" 'evil-make)
+(evil-ex-define-cmd "cc" 'evil-goto-error)
+(evil-ex-define-cmd "cfir[st]" 'first-error)
+(evil-ex-define-cmd "cr[ewind]" 'first-error)
+(evil-ex-define-cmd "cn[ext]" 'next-error)
+(evil-ex-define-cmd "cp[revious]" 'previous-error)
+(evil-ex-define-cmd "set-initial-state" 'evil-ex-set-initial-state)
+(evil-ex-define-cmd "show-digraphs" 'evil-ex-show-digraphs)
+(evil-ex-define-cmd "sor[t]" 'evil-ex-sort)
+(evil-ex-define-cmd "res[ize]" 'evil-ex-resize)
+
+;; search command line
+(define-key evil-ex-search-keymap "\d" #'evil-ex-delete-backward-char)
+(define-key evil-ex-search-keymap "\C-r" 'evil-paste-from-register)
+(define-key evil-ex-search-keymap "\C-n" 'next-history-element)
+(define-key evil-ex-search-keymap "\C-p" 'previous-history-element)
+
+;; ex command line
+(define-key evil-ex-completion-map "\d" #'evil-ex-delete-backward-char)
+(define-key evil-ex-completion-map "\t" #'evil-ex-completion)
+(define-key evil-ex-completion-map [tab] #'evil-ex-completion)
+(define-key evil-ex-completion-map [remap completion-at-point] #'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-a" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-b" 'move-beginning-of-line)
+(define-key evil-ex-completion-map "\C-c" 'abort-recursive-edit)
+(define-key evil-ex-completion-map "\C-d" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-g" 'abort-recursive-edit)
+(define-key evil-ex-completion-map "\C-k" 'evil-insert-digraph)
+(define-key evil-ex-completion-map "\C-l" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-p" #'previous-complete-history-element)
+(define-key evil-ex-completion-map "\C-r" 'evil-paste-from-register)
+(define-key evil-ex-completion-map "\C-n" #'next-complete-history-element)
+(define-key evil-ex-completion-map "\C-u" 'evil-delete-whole-line)
+(define-key evil-ex-completion-map "\C-v" #'quoted-insert)
+(define-key evil-ex-completion-map "\C-w" 'backward-kill-word)
+(define-key evil-ex-completion-map [escape] 'abort-recursive-edit)
+(define-key evil-ex-completion-map [S-left] 'backward-word)
+(define-key evil-ex-completion-map [S-right] 'forward-word)
+(define-key evil-ex-completion-map [up] 'previous-complete-history-element)
+(define-key evil-ex-completion-map [down] 'next-complete-history-element)
+(define-key evil-ex-completion-map [prior] 'previous-history-element)
+(define-key evil-ex-completion-map [next] 'next-history-element)
+(define-key evil-ex-completion-map [return] 'exit-minibuffer)
+(define-key evil-ex-completion-map (kbd "RET") 'exit-minibuffer)
+
+;; evil-read-key
+(define-key evil-read-key-map (kbd "ESC") #'keyboard-quit)
+(define-key evil-read-key-map (kbd "C-]") #'keyboard-quit)
+(define-key evil-read-key-map (kbd "C-q") #'evil-read-quoted-char)
+(define-key evil-read-key-map (kbd "C-v") #'evil-read-quoted-char)
+(define-key evil-read-key-map (kbd "C-k") #'evil-read-digraph-char)
+(define-key evil-read-key-map "\r" "\n")
+
+;; command line window
+(evil-define-key 'normal
+  evil-command-window-mode-map (kbd "RET") 'evil-command-window-execute)
+(evil-define-key 'insert
+  evil-command-window-mode-map (kbd "RET") 'evil-command-window-execute)
+
+(provide 'evil-maps)
+
+;;; evil-maps.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-maps.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-pkg.el
@@ -0,0 +1,8 @@
+(define-package "evil" "20170904.1346" "Extensible Vi layer for Emacs."
+  '((emacs "24.1")
+    (undo-tree "0.6.3")
+    (goto-chg "1.6")
+    (cl-lib "0.5")))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
.emacs.d/elpa/evil-20170904.1346/evil-repeat.el
@@ -0,0 +1,638 @@
+;;; evil-repeat.el --- Repeat system
+
+;; Author: Frank Fischer <frank.fischer at mathematik.tu-chemnitz.de>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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/>.
+
+;;; Commentary:
+
+;; A repeat begins when leaving Normal state; it ends when re-entering
+;; Normal state. The diagram below shows possible routes between
+;; Normal state (N), Insert state (I), Visual state (V),
+;; Operator-Pending state (O) and Replace state (R). (Emacs state
+;; is an exception: nothing is repeated in that state.)
+;;                              ___
+;;                             /   \
+;;                             | R |
+;;                             \___/
+;;                             ^   |
+;;                             |   |
+;;               ___           |___V           ___
+;;              /   \ <------- /   \ -------> /   \
+;;              | V |          | N |          | O |
+;;              \___/ -------> \___/ <------- \___/
+;;                  |          |   ^          |
+;;                  |          |   |          |
+;;                  |          V___|          |
+;;                  |          /   \          |
+;;                  +--------> | I | <--------+
+;;                             \___/
+;;
+;; The recording of a repeat is started in one of two cases: Either a
+;; command is about being executed (in pre-command-hook) or normal
+;; state is exited. The recording is stopped whenever a command has
+;; being completed and evil is in normal state afterwards. Therefore,
+;; a non-inserting command in normal-state is recorded as a single
+;; repeat unit. In contrast, if the command leaves normal state and
+;; starts insert-state, all commands that are executed until
+;; insert-state is left and normal state is reactivated are recorded
+;; together in one repeat unit. In other words, a repeat unit consists
+;; of all commands that are executed starting and ending in normal
+;; state.
+;;
+;; Not all commands are recorded. There are several commands that are
+;; completely ignored and other commands that even abort the currently
+;; active recording, e.g., commands that change the current buffer.
+;;
+;; During recording the repeat information is appended to the variable
+;; `evil-repeat-info', which is cleared when the recording
+;; starts. This accumulated repeat information is put into the
+;; `evil-repeat-ring' when the recording is finished. The dot command,
+;; `\[evil-repeat]' (`evil-repeat') replays the most recent entry in
+;; the ring, preceeding repeats can be replayed using
+;; `\[evil-repeat-pop]' (`evil-repeat-pop').
+;;
+;; Repeat information can be stored in almost arbitrary form. How the
+;; repeat information for each single command is recored is determined
+;; by the :repeat property of the command. This property has the
+;; following interpretation:
+;;
+;; t         record commands by storing the key-sequence that invoked it
+;; nil       ignore this command completely
+;; ignore    synonym to nil
+;; motion    command is recorded by storing the key-sequence but only in
+;;           insert state, otherwise it is ignored.
+;; abort     stop recording of repeat information immediately
+;; change    record commands by storing buffer changes
+;; SYMBOL    if SYMBOL is contained as key in `evil-repeat-types'
+;;           call the corresponding (function-)value, otherwise
+;;           call the function associated with SYMBOL. In both
+;;           cases the function should take exactly one argument
+;;           which is either 'pre or 'post depending on whether
+;;           the function is called before or after the execution
+;;           of the command.
+;;
+;; Therefore, using a certain SYMBOL one can write specific repeation
+;; functions for each command.
+;;
+;; Each value of ring `evil-repeat-info', i.e., each single repeat
+;; information must be one of the following two possibilities:
+;; If element is a sequence, it is regarded as a key-sequence to
+;; be repeated. Otherwise the element must be a list
+;; (FUNCTION PARAMS ...) which will be called using
+;; (apply FUNCTION PARAMS) whenever this repeat is being executed.
+;;
+;; A user supplied repeat function can use the functions
+;; `evil-record-repeat' to append further repeat-information of the
+;; form described above to `evil-repeat-info'. See the implementation
+;; of `evil-repeat-keystrokes' and `evil-repeat-changes' for examples.
+;; Those functions are called in different situations before and after
+;; the execution of a command. Each function should take one argument
+;; which can be either 'pre, 'post, 'pre-operator or 'post-operator
+;; specifying when the repeat function has been called. If the command
+;; is a usual command the function is called with 'pre before the
+;; command is executed and with 'post after the command has been
+;; executed.
+;;
+;; The repeat information is executed with `evil-execute-repeat-info',
+;; which passes key-sequence elements to `execute-kbd-macro' and
+;; executes other elements as defined above.  A special version is
+;; `evil-execute-repeat-info-with-count'.  This function works as
+;; `evil-execute-repeat-info', but replaces the count of the first
+;; command. This is done by parsing the key-sequence, ignoring all
+;; calls to `digit-prefix-argument' and `negative-argument', and
+;; prepending the count as a string to the vector of the remaining
+;; key-sequence.
+
+(require 'evil-states)
+
+;;; Code:
+
+(declare-function evil-visual-state-p "evil-visual")
+(declare-function evil-visual-range "evil-visual")
+(declare-function evil-visual-char "evil-visual")
+(declare-function evil-visual-line "evil-visual")
+(declare-function evil-visual-block "evil-visual")
+
+(defmacro evil-without-repeat (&rest body)
+  (declare (indent defun)
+           (debug t))
+  `(let ((pre-command-hook (remq 'evil-repeat-pre-hook pre-command-hook))
+         (post-command-hook (remq 'evil-repeat-post-hook post-command-hook)))
+     ,@body
+     (evil-repeat-abort)))
+
+(defsubst evil-repeat-recording-p ()
+  "Returns non-nil iff a recording is in progress."
+  (eq evil-recording-repeat t))
+
+(defun evil-repeat-start ()
+  "Start recording a new repeat into `evil-repeat-info'."
+  (evil-repeat-reset t)
+  (evil-repeat-record-buffer)
+  (when (evil-visual-state-p)
+    (let* ((range (evil-visual-range))
+           (beg (evil-range-beginning range))
+           (end (1- (evil-range-end range)))
+           (nfwdlines (evil-count-lines beg end)))
+      (evil-repeat-record
+       (cond
+        ((eq evil-visual-selection 'char)
+         (list #'evil-repeat-visual-char
+               nfwdlines
+               (- end
+                  (if (zerop nfwdlines)
+                      beg
+                    (save-excursion
+                      (goto-char end)
+                      (line-beginning-position))))))
+        ((eq evil-visual-selection 'line)
+         (list #'evil-repeat-visual-line nfwdlines))
+        ((eq evil-visual-selection 'block)
+         (list #'evil-repeat-visual-block
+               nfwdlines
+               (abs (- (evil-column beg) (evil-column end))))))))))
+
+(defun evil-repeat-stop ()
+  "Stop recording a repeat.
+Update `evil-repeat-ring' with the accumulated changes
+in `evil-repeat-info' and clear variables."
+  (unwind-protect
+      (when (evil-repeat-recording-p)
+        (setq evil-repeat-info
+              (evil-normalize-repeat-info evil-repeat-info))
+        (when (and evil-repeat-info evil-repeat-ring)
+          (ring-insert evil-repeat-ring evil-repeat-info)))
+    (evil-repeat-reset nil)))
+
+(defun evil-repeat-abort ()
+  "Abort current repeation."
+  (evil-repeat-reset 'abort))
+
+(defun evil-repeat-reset (flag)
+  "Clear all repeat recording variables.
+Set `evil-recording-repeat' to FLAG."
+  (setq evil-recording-repeat flag
+        evil-repeat-info nil
+        evil-repeat-buffer nil))
+
+(defsubst evil-repeat-record-position (&optional pos)
+  "Set `evil-repeat-pos' to POS or point."
+  (setq evil-repeat-pos (or pos (point))))
+
+(defun evil-repeat-record-buffer ()
+  "Set `evil-repeat-buffer' to the current buffer."
+  (unless (minibufferp)
+    (setq evil-repeat-buffer (current-buffer))))
+
+(defmacro evil-save-repeat-info (&rest body)
+  "Execute BODY, protecting the values of repeat variables."
+  (declare (indent defun)
+           (debug t))
+  `(let (evil-repeat-ring
+         evil-recording-repeat
+         evil-recording-current-command
+         evil-repeat-info
+         evil-repeat-changes
+         evil-repeat-pos
+         evil-repeat-keys
+         evil-repeat-buffer
+         this-command
+         last-command)
+     ,@body))
+
+(defun evil-repeat-different-buffer-p (&optional strict)
+  "Whether the buffer has changed in a repeat.
+If STRICT is non-nil, returns t if the previous buffer
+is unknown; otherwise returns t only if the previous
+buffer is known and different from the current buffer."
+  (and (or (buffer-live-p evil-repeat-buffer) strict)
+       (not (minibufferp))
+       (not (eq (current-buffer) evil-repeat-buffer))))
+
+(defun evil-repeat-type (command &optional default)
+  "Return the :repeat property of COMMAND.
+If COMMAND doesn't have this property, return DEFAULT."
+  (when (functionp command) ; ignore keyboard macros
+    (let* ((type (evil-get-command-property command :repeat default))
+           (repeat-type (assq type evil-repeat-types)))
+      (if repeat-type (cdr repeat-type) type))))
+
+(defun evil-repeat-force-abort-p (repeat-type)
+  "Returns non-nil iff the current command should abort the recording of repeat information."
+  (or (evil-repeat-different-buffer-p)           ; ... buffer changed
+      (eq repeat-type 'abort)                    ; ... explicitely forced
+      (eq evil-recording-repeat 'abort)          ; ... already aborted
+      (evil-emacs-state-p)                       ; ... in Emacs state
+      (and (evil-mouse-events-p (this-command-keys))  ; ... mouse events
+           (eq repeat-type nil))
+      (minibufferp)))                            ; ... minibuffer activated
+
+(defun evil-repeat-record (info)
+  "Add INFO to the end of `evil-repeat-info'."
+  (when (evil-repeat-recording-p)
+    (setq evil-repeat-info (nconc evil-repeat-info (list info)))))
+
+;; called from `evil-normal-state-exit-hook'
+(defun evil-repeat-start-hook ()
+  "Record a new repeat when exiting Normal state.
+Does not record in Emacs state or if the current command
+has :repeat nil."
+  (when (and (eq (evil-repeat-type this-command t) t)
+             (not (evil-emacs-state-p)))
+    (evil-repeat-start)))
+
+;; called from `pre-command-hook'
+(defun evil-repeat-pre-hook ()
+  "Prepare the current command for recording the repeation."
+  (when evil-local-mode
+    (let ((repeat-type (evil-repeat-type this-command t)))
+      (cond
+       ;; abort the repeat
+       ((evil-repeat-force-abort-p repeat-type)
+        ;; We mark the current record as being aborted, because there
+        ;; may be further pre-hooks following before the post-hook is
+        ;; called.
+        (evil-repeat-abort))
+       ;; ignore those commands completely
+       ((null repeat-type))
+       ;; record command
+       (t
+        ;; In normal-state or visual state, each command is a single
+        ;; repeation, therefore start a new repeation.
+        (when (or (evil-normal-state-p)
+                  (evil-visual-state-p))
+          (evil-repeat-start))
+        (setq evil-recording-current-command t)
+        (funcall repeat-type 'pre))))))
+(put 'evil-repeat-pre-hook 'permanent-local-hook t)
+
+;; called from `post-command-hook'
+(defun evil-repeat-post-hook ()
+  "Finish recording of repeat-information for the current-command."
+  (when (and evil-local-mode evil-recording-repeat)
+    (let ((repeat-type (evil-repeat-type this-command t)))
+      (cond
+       ;; abort the repeat
+       ((evil-repeat-force-abort-p repeat-type)
+        ;; The command has been aborted but is complete, so just reset
+        ;; the recording state.
+        (evil-repeat-reset nil))
+       ;; ignore if command should not be recorded or the current
+       ;; command is not being recorded
+       ((or (null repeat-type)
+            (not evil-recording-current-command)))
+       ;; record command
+       (t
+        (funcall repeat-type 'post)
+        ;; In normal state, the repeat sequence is complete, so record it.
+        (when (evil-normal-state-p)
+          (evil-repeat-stop)))))
+    ;; done with recording the current command
+    (setq evil-recording-current-command nil)))
+(put 'evil-repeat-post-hook 'permanent-local-hook t)
+
+(defun evil-clear-command-keys ()
+  "Clear `this-command-keys' and all information about the current command keys.
+Calling this function prevents further recording of the keys that
+invoked the current command"
+  (clear-this-command-keys t)
+  (setq evil-repeat-keys ""))
+
+(defun evil-this-command-keys (&optional post-cmd)
+  "Version of `this-command-keys' with finer control over prefix args."
+  (let ((arg (if post-cmd current-prefix-arg prefix-arg)))
+    (vconcat
+     (when (and (numberp arg)
+                ;; Only add prefix if no repeat info recorded yet
+                (null evil-repeat-info))
+       (string-to-vector (number-to-string arg)))
+     (this-single-command-keys))))
+
+(defun evil-repeat-keystrokes (flag)
+  "Repeation recording function for commands that are repeated by keystrokes."
+  (cond
+   ((eq flag 'pre)
+    (when evil-this-register
+      (evil-repeat-record
+       `(set evil-this-register ,evil-this-register)))
+    (setq evil-repeat-keys (evil-this-command-keys)))
+   ((eq flag 'post)
+    (evil-repeat-record (if (zerop (length (evil-this-command-keys t)))
+                            evil-repeat-keys
+                          (evil-this-command-keys t)))
+    ;; erase commands keys to prevent double recording
+    (evil-clear-command-keys))))
+
+(defun evil-repeat-motion (flag)
+  "Repeation for motions. Motions are recorded by keystroke but only in insert state."
+  (when (memq evil-state '(insert replace))
+    (evil-repeat-keystrokes flag)))
+
+(defun evil-repeat-changes (flag)
+  "Repeation recording function for commands that are repeated by buffer changes."
+  (cond
+   ((eq flag 'pre)
+    (add-hook 'after-change-functions #'evil-repeat-change-hook nil t)
+    (evil-repeat-start-record-changes))
+   ((eq flag 'post)
+    (remove-hook 'after-change-functions #'evil-repeat-change-hook t)
+    (evil-repeat-finish-record-changes))))
+
+;; called from the `after-change-functions' hook
+(defun evil-repeat-change-hook (beg end length)
+  "Record change information for current command."
+  (let ((repeat-type (evil-repeat-type this-command t)))
+    (when (and (evil-repeat-recording-p)
+               (eq repeat-type 'evil-repeat-changes)
+               (not (evil-emacs-state-p))
+               (not (evil-repeat-different-buffer-p t))
+               evil-state)
+      (unless (evil-repeat-recording-p)
+        (evil-repeat-start))
+      (evil-repeat-record-change (- beg evil-repeat-pos)
+                                 (buffer-substring beg end)
+                                 length))))
+(put 'evil-repeat-change-hook 'permanent-local-hook t)
+
+(defun evil-repeat-record-change (relpos ins ndel)
+  "Record the current buffer changes during a repeat.
+If CHANGE is specified, it is added to `evil-repeat-changes'."
+  (when (evil-repeat-recording-p)
+    (setq evil-repeat-changes
+          (nconc evil-repeat-changes (list (list relpos ins ndel))))))
+
+(defun evil-repeat-start-record-changes ()
+  "Starts the recording of a new set of buffer changes."
+  (setq evil-repeat-changes nil)
+  (evil-repeat-record-position))
+
+(defun evil-repeat-finish-record-changes ()
+  "Finishes the recording of buffer changes and records them as repeat."
+  (when (evil-repeat-recording-p)
+    (evil-repeat-record `(evil-execute-change
+                          ,evil-repeat-changes
+                          ,(- (point) evil-repeat-pos)))
+    (setq evil-repeat-changes nil)))
+
+(defun evil-repeat-insert-at-point (flag)
+  "Repeation recording function for commands that insert text in region.
+This records text insertion when a command inserts some text in a
+buffer between (point) and (mark)."
+  (cond
+   ((eq flag 'pre)
+    (add-hook 'after-change-functions #'evil-repeat-insert-at-point-hook nil t))
+   ((eq flag 'post)
+    (remove-hook 'after-change-functions #'evil-repeat-insert-at-point-hook t))))
+
+(defun evil-repeat-insert-at-point-hook (beg end length)
+  (let ((repeat-type (evil-repeat-type this-command t)))
+    (when (and (evil-repeat-recording-p)
+               (eq repeat-type 'evil-repeat-insert-at-point)
+               (not (evil-emacs-state-p))
+               (not (evil-repeat-different-buffer-p t))
+               evil-state)
+      (setq evil-repeat-pos beg)
+      (evil-repeat-record (list 'insert (buffer-substring beg end))))))
+(put 'evil-repeat-insert-at-point-hook 'permanent-local-hook t)
+
+(defun evil-normalize-repeat-info (repeat-info)
+  "Concatenate consecutive arrays in REPEAT-INFO.
+Returns a single array."
+  (let* ((result (cons nil nil))
+         (result-last result)
+         cur cur-last)
+    (dolist (rep repeat-info)
+      (cond
+       ((null rep))
+       ((arrayp rep)
+        (setq rep (listify-key-sequence rep))
+        (cond
+         (cur
+          (setcdr cur-last (cons rep nil))
+          (setq cur-last (cdr cur-last)))
+         (t
+          (setq cur (cons rep nil))
+          (setq cur-last cur))))
+       (t
+        (when cur
+          (setcdr result-last (cons (apply #'vconcat cur) nil))
+          (setq result-last (cdr result-last))
+          (setq cur nil))
+        (setcdr result-last (cons rep nil))
+        (setq result-last (cdr result-last)))))
+    (when cur
+      (setcdr result-last (cons (apply #'vconcat cur) nil)))
+    (cdr result)))
+
+(defun evil-repeat-visual-char (nfwdlines nfwdchars)
+  "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+  (evil-visual-char)
+  (when (> nfwdlines 0)
+    (forward-line nfwdlines))
+  (forward-char nfwdchars))
+
+(defun evil-repeat-visual-line (nfwdlines)
+  "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+  (evil-visual-line)
+  (forward-line nfwdlines))
+
+(defun evil-repeat-visual-block (nfwdlines nfwdchars)
+  "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+  (evil-visual-block)
+  (let ((col (current-column)))
+    (forward-line nfwdlines)
+    (move-to-column (+ col nfwdchars) t)))
+
+(defun evil-execute-change (changes rel-point)
+  "Executes as list of changes.
+
+CHANGES is a list of triples (REL-BEG INSERT-TEXT NDEL).
+REL-BEG is the relative position (to point) where the change
+takes place. INSERT-TEXT is the text to be inserted at that
+position and NDEL the number of characters to be deleted at that
+position before insertion.
+
+REL-POINT is the relative position to point before the changed
+where point should be placed after all changes."
+  (evil-save-repeat-info
+    (let ((point (point)))
+      (dolist (change changes)
+        (goto-char (+ point (nth 0 change)))
+        (delete-char (nth 2 change))
+        (insert (nth 1 change)))
+      (goto-char (+ point rel-point)))))
+
+(defun evil-execute-repeat-info (repeat-info)
+  "Executes a repeat-information REPEAT-INFO."
+  (evil-save-repeat-info
+    (dolist (rep repeat-info)
+      (cond
+       ((or (arrayp rep) (stringp rep))
+        (let ((input-method current-input-method)
+              (evil-input-method nil))
+          (deactivate-input-method)
+          (unwind-protect
+              (execute-kbd-macro rep)
+            (activate-input-method input-method))))
+       ((consp rep)
+        (when (and (= 3 (length rep))
+                   (eq (nth 0 rep) 'set)
+                   (eq (nth 1 rep) 'evil-this-register)
+                   (>= (nth 2 rep) ?0)
+                   (< (nth 2 rep) ?9))
+          (setcar (nthcdr 2 rep) (1+ (nth 2 rep))))
+        (apply (car rep) (cdr rep)))
+       (t
+        (error "Unexpected repeat-info: %S" rep))))))
+
+;; TODO: currently we prepend the replacing count before the
+;; key-sequence that calls the command. Can we use direct
+;; modification of prefix-arg instead? Does it work in
+;; conjunction with `execute-kbd-macro'?
+(defun evil-execute-repeat-info-with-count (count repeat-info)
+  "Repeat the repeat-information REPEAT-INFO with the count of
+the first command replaced by COUNT. The count is replaced if
+and only if COUNT is non-nil."
+  (evil-save-repeat-info
+    (cond
+     ;; do nothing (zero repeating)
+     ((and count (zerop count)))
+     ;; replace count
+     (count
+      (let ((evil-repeat-count count)
+            done)
+        (while (and repeat-info
+                    (arrayp (car repeat-info))
+                    (not done))
+          (let* ((count-and-cmd (evil-extract-count (pop repeat-info))))
+            (push (vconcat (number-to-string count)
+                           (nth 2 count-and-cmd)
+                           (nth 3 count-and-cmd))
+                  repeat-info)
+            (setq done t)))
+        (evil-execute-repeat-info repeat-info)))
+     ;; repeat with original count
+     (t
+      (evil-execute-repeat-info repeat-info)))))
+
+(evil-define-command evil-repeat (count &optional save-point)
+  "Repeat the last editing command with count replaced by COUNT.
+If SAVE-POINT is non-nil, do not move point."
+  :repeat ignore
+  :suppress-operator t
+  (interactive (list current-prefix-arg
+                     (not evil-repeat-move-cursor)))
+  (cond
+   ((null evil-repeat-ring)
+    (error "Already executing repeat"))
+   (save-point
+    (save-excursion
+      (evil-repeat count)))
+   (t
+    (unwind-protect
+        (let ((confirm-kill-emacs t)
+              (kill-buffer-hook
+               (cons #'(lambda ()
+                         (user-error "Cannot delete buffer in repeat command"))
+                     kill-buffer-hook))
+              (undo-pointer buffer-undo-list))
+          (evil-with-single-undo
+            (setq evil-last-repeat (list (point) count undo-pointer))
+            (evil-execute-repeat-info-with-count
+             count (ring-ref evil-repeat-ring 0))))
+      (evil-normal-state)))))
+
+;; TODO: the same issue concering disabled undos as for `evil-paste-pop'
+(evil-define-command evil-repeat-pop (count &optional save-point)
+  "Replace the just repeated command with a previously executed command.
+Only allowed after `evil-repeat', `evil-repeat-pop' or
+`evil-repeat-pop-next'. Uses the same repeat count that
+was used for the first repeat.
+
+The COUNT argument inserts the COUNT-th previous kill.
+If COUNT is negative, this is a more recent kill."
+  :repeat nil
+  :suppress-operator t
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     (not evil-repeat-move-cursor)))
+  (cond
+   ((not (and (eq last-command #'evil-repeat)
+              evil-last-repeat))
+    (user-error "Previous command was not evil-repeat: %s" last-command))
+   (save-point
+    (save-excursion
+      (evil-repeat-pop count)))
+   (t
+    (unless (eq buffer-undo-list (nth 2 evil-last-repeat))
+      (evil-undo-pop))
+    (goto-char (car evil-last-repeat))
+    ;; rotate the repeat-ring
+    (while (> count 0)
+      (when evil-repeat-ring
+        (ring-insert-at-beginning evil-repeat-ring
+                                  (ring-remove evil-repeat-ring 0)))
+      (setq count (1- count)))
+    (while (< count 0)
+      (when evil-repeat-ring
+        (ring-insert evil-repeat-ring
+                     (ring-remove evil-repeat-ring)))
+      (setq count (1+ count)))
+    (setq this-command #'evil-repeat)
+    (evil-repeat (cadr evil-last-repeat)))))
+
+(evil-define-command evil-repeat-pop-next (count &optional save-point)
+  "Same as `evil-repeat-pop', but with negative COUNT."
+  :repeat nil
+  :suppress-operator t
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     (not evil-repeat-move-cursor)))
+  (evil-repeat-pop (- count) save-point))
+
+(defadvice read-key-sequence (before evil activate)
+  "Record `this-command-keys' before it is reset."
+  (when (and (evil-repeat-recording-p)
+             evil-recording-current-command)
+    (let ((repeat-type (evil-repeat-type this-command t)))
+      (if (functionp repeat-type)
+          (funcall repeat-type 'post)))))
+
+(provide 'evil-repeat)
+
+;;; evil-repeat.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-repeat.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-search.el
@@ -0,0 +1,1294 @@
+;;; evil-search.el --- Search and substitute
+
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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-core)
+(require 'evil-common)
+(require 'evil-ex)
+
+;;; Code:
+
+(defun evil-select-search-module (option module)
+  "Change the search module according to MODULE.
+If MODULE is `isearch', then Emacs' isearch module is used.
+If MODULE is `evil-search', then Evil's own interactive
+search module is used."
+  (let ((search-functions
+         '(forward
+           backward
+           word-forward
+           word-backward
+           unbounded-word-forward
+           unbounded-word-backward
+           next
+           previous)))
+    (dolist (fun search-functions)
+      (let ((isearch (intern (format "evil-search-%s" fun)))
+            (evil-search (intern (format "evil-ex-search-%s" fun))))
+        (if (eq module 'isearch)
+            (substitute-key-definition
+             evil-search isearch evil-motion-state-map)
+          (substitute-key-definition
+           isearch evil-search evil-motion-state-map)))))
+  (set-default option module))
+
+;; this customization is here because it requires
+;; the knowledge of `evil-select-search-mode'
+(defcustom evil-search-module 'isearch
+  "The search module to be used."
+  :type '(radio (const :tag "Emacs built-in isearch." :value isearch)
+                (const :tag "Evil interactive search." :value evil-search))
+  :group 'evil
+  :set 'evil-select-search-module
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defun evil-push-search-history (string forward)
+  "Push STRING into the appropriate search history (determined by FORWARD)."
+  (let* ((history-var (if forward
+                          'evil-search-forward-history
+                        'evil-search-backward-history))
+         (history (symbol-value history-var)))
+    (unless (equal (car-safe history) string)
+      (set history-var (cons string history)))))
+
+(defun evil-search-incrementally (forward regexp-p)
+  "Search incrementally for user-entered text."
+  (let ((evil-search-prompt (evil-search-prompt forward))
+        (isearch-search-fun-function 'evil-isearch-function)
+        (point (point))
+        search-nonincremental-instead)
+    (setq isearch-forward forward)
+    (evil-save-echo-area
+      (evil-without-input-method-hooks
+       ;; set the input method locally rather than globally to ensure that
+       ;; isearch clears the input method when it's finished
+       (setq current-input-method evil-input-method)
+       (if forward
+           (isearch-forward regexp-p)
+         (isearch-backward regexp-p))
+       (evil-push-search-history isearch-string forward)
+       (setq current-input-method nil))
+      (when (/= (point) point)
+        ;; position the point at beginning of the match only if the call to
+        ;; `isearch' has really moved the point. `isearch' doesn't move the
+        ;; point only if "C-g" is hit twice to exit the search, in which case we
+        ;; shouldn't move the point either.
+        (when (and forward isearch-other-end)
+          (goto-char isearch-other-end))
+        (when (and (eq point (point))
+                   (not (string= isearch-string "")))
+          (if forward
+              (isearch-repeat-forward)
+            (isearch-repeat-backward))
+          (isearch-exit)
+          (when (and forward isearch-other-end)
+            (goto-char isearch-other-end)))
+        (evil-flash-search-pattern
+         (evil-search-message isearch-string forward))))))
+
+(defun evil-flash-search-pattern (string &optional all)
+  "Flash last search matches for duration of `evil-flash-delay'.
+If ALL is non-nil, flash all matches. STRING is a message
+to display in the echo area."
+  (let ((lazy-highlight-initial-delay 0)
+        (isearch-search-fun-function 'evil-isearch-function)
+        (isearch-case-fold-search case-fold-search)
+        (disable #'(lambda (&optional arg) (evil-flash-hook t))))
+    (when evil-flash-timer
+      (cancel-timer evil-flash-timer))
+    (unless (or (null string)
+                (string= string ""))
+      (evil-echo-area-save)
+      (evil-echo "%s" string)
+      (isearch-highlight (match-beginning 0) (match-end 0))
+      (when all
+        (setq isearch-lazy-highlight-wrapped nil
+              isearch-lazy-highlight-start (point)
+              isearch-lazy-highlight-end (point))
+        (isearch-lazy-highlight-new-loop)
+        (unless isearch-lazy-highlight-overlays
+          (isearch-lazy-highlight-update)))
+      (add-hook 'pre-command-hook #'evil-flash-hook nil t)
+      (add-hook 'evil-operator-state-exit-hook #'evil-flash-hook nil t)
+      (add-hook 'pre-command-hook #'evil-clean-isearch-overlays nil t)
+      (setq evil-flash-timer
+            (run-at-time evil-flash-delay nil disable)))))
+
+(defun evil-clean-isearch-overlays ()
+  "Clean isearch overlays unless `this-command' is search."
+  (remove-hook 'pre-command-hook #'evil-clean-isearch-overlays t)
+  (unless (memq this-command
+                '(evil-search-backward
+                  evil-search-forward
+                  evil-search-next
+                  evil-search-previous
+                  evil-search-word-backward
+                  evil-search-word-forward))
+    (isearch-clean-overlays)))
+(put 'evil-clean-isearch-overlays 'permanent-local-hook t)
+
+(defun evil-flash-hook (&optional force)
+  "Disable hightlighting if `this-command' is not search.
+Disable anyway if FORCE is t."
+  (when (or force
+            ;; to avoid flicker, don't disable highlighting
+            ;; if the next command is also a search command
+            (not (memq this-command
+                       '(evil-search-backward
+                         evil-search-forward
+                         evil-search-next
+                         evil-search-previous
+                         evil-search-word-backward
+                         evil-search-word-forward))))
+    (evil-echo-area-restore)
+    (isearch-dehighlight)
+    (setq isearch-lazy-highlight-last-string nil)
+    (lazy-highlight-cleanup t)
+    (when evil-flash-timer
+      (cancel-timer evil-flash-timer)))
+  (remove-hook 'pre-command-hook #'evil-flash-hook t)
+  (remove-hook 'evil-operator-state-exit-hook #'evil-flash-hook t))
+(put 'evil-flash-hook 'permanent-local-hook t)
+
+(defun evil-search-function (&optional forward regexp-p wrap)
+  "Return a search function.
+If FORWARD is nil, search backward, otherwise forward.
+If REGEXP-P is non-nil, the input is a regular expression.
+If WRAP is non-nil, the search wraps around the top or bottom
+of the buffer."
+  `(lambda (string &optional bound noerror count)
+     (let ((start (point))
+           (search-fun ',(if regexp-p
+                             (if forward
+                                 're-search-forward
+                               're-search-backward)
+                           (if forward
+                               'search-forward
+                             'search-backward)))
+           result)
+       (setq result (funcall search-fun string bound
+                             ,(if wrap t 'noerror) count))
+       (when (and ,wrap (null result))
+         (goto-char ,(if forward '(point-min) '(point-max)))
+         (unwind-protect
+             (setq result (funcall search-fun string bound noerror count))
+           (unless result
+             (goto-char start))))
+       result)))
+
+(defun evil-isearch-function ()
+  "Return a search function for use with isearch.
+Based on `isearch-regexp' and `isearch-forward'."
+  (evil-search-function isearch-forward evil-regexp-search evil-search-wrap))
+
+(defun evil-search (string forward &optional regexp-p start)
+  "Search for STRING and highlight matches.
+If FORWARD is nil, search backward, otherwise forward.
+If REGEXP-P is non-nil, STRING is taken to be a regular expression.
+START is the position to search from; if unspecified, it is
+one more than the current position."
+  (when (and (stringp string)
+             (not (string= string "")))
+    (let* ((orig (point))
+           (start (or start
+                      (if forward
+                          (min (point-max) (1+ orig))
+                        orig)))
+           (isearch-regexp regexp-p)
+           (isearch-forward forward)
+           (case-fold-search
+            (unless (and search-upper-case
+                         (not (isearch-no-upper-case-p string nil)))
+              case-fold-search))
+           (search-func (evil-search-function
+                         forward regexp-p evil-search-wrap)))
+      ;; no text properties, thank you very much
+      (set-text-properties 0 (length string) nil string)
+      ;; position to search from
+      (goto-char start)
+      (setq isearch-string string)
+      (isearch-update-ring string regexp-p)
+      (condition-case nil
+          (funcall search-func string)
+        (search-failed
+         (goto-char orig)
+         (user-error "\"%s\": %s not found"
+                     string (if regexp-p "pattern" "string"))))
+      ;; handle opening and closing of invisible area
+      (cond
+       ((boundp 'isearch-filter-predicates)
+        (dolist (pred isearch-filter-predicates)
+          (funcall pred (match-beginning 0) (match-end 0))))
+       ((boundp 'isearch-filter-predicate)
+        (funcall isearch-filter-predicate (match-beginning 0) (match-end 0))))
+      ;; always position point at the beginning of the match
+      (goto-char (match-beginning 0))
+      ;; determine message for echo area
+      (cond
+       ((and forward (< (point) start))
+        (setq string "Search wrapped around BOTTOM of buffer"))
+       ((and (not forward) (> (point) start))
+        (setq string "Search wrapped around TOP of buffer"))
+       (t
+        (setq string (evil-search-message string forward))))
+      (evil-flash-search-pattern string t))))
+
+(defun evil-search-word (forward unbounded symbol)
+  "Search for word near point.
+If FORWARD is nil, search backward, otherwise forward. If SYMBOL
+is non-nil then the functions searches for the symbol at point,
+otherwise for the word at point."
+  (let ((string (car-safe regexp-search-ring))
+        (move (if forward #'forward-char #'backward-char))
+        (end (if forward #'eobp #'bobp)))
+    (setq isearch-forward forward)
+    (cond
+     ((and (memq last-command
+                 '(evil-search-word-forward
+                   evil-search-word-backward))
+           (stringp string)
+           (not (string= string "")))
+      (evil-search string forward t))
+     (t
+      (setq string (evil-find-thing forward (if symbol 'symbol 'evil-word)))
+      (cond
+       ((null string)
+        (user-error "No word under point"))
+       (unbounded
+        (setq string (regexp-quote string)))
+       (t
+        (setq string
+              (format (if symbol "\\_<%s\\_>" "\\<%s\\>")
+                      (regexp-quote string)))))
+      (evil-push-search-history string forward)
+      (evil-search string forward t)))))
+
+(defun evil-find-thing (forward thing)
+  "Return THING near point as a string.
+THING should be a symbol understood by `thing-at-point',
+e.g. 'symbol or 'word.  If FORWARD is nil, search backward,
+otherwise forward.  Returns nil if nothing is found."
+  (let ((move (if forward #'forward-char #'backward-char))
+        (end (if forward #'eobp #'bobp))
+        string)
+    (save-excursion
+      (setq string (thing-at-point thing))
+      ;; if there's nothing under point, go forwards
+      ;; (or backwards) to find it
+      (while (and (null string) (not (funcall end)))
+        (funcall move)
+        (setq string (thing-at-point thing)))
+      (when (stringp string)
+        (set-text-properties 0 (length string) nil string))
+      (when (> (length string) 0)
+        string))))
+
+(defun evil-find-word (forward)
+  "Return word near point as a string.
+If FORWARD is nil, search backward, otherwise forward.  Returns
+nil if nothing is found."
+  (evil-find-thing forward 'word))
+
+(defun evil-find-symbol (forward)
+  "Return word near point as a string.
+If FORWARD is nil, search backward, otherwise forward.  Returns
+nil if nothing is found."
+  (evil-find-thing forward 'symbol))
+
+(defun evil-search-prompt (forward)
+  "Return the search prompt for the given direction."
+  (if forward "/" "?"))
+
+(defun evil-search-message (string forward)
+  "Prefix STRING with the search prompt."
+  (format "%s%s" (evil-search-prompt forward) string))
+
+(defadvice isearch-message-prefix (around evil activate)
+  "Use `evil-search-prompt'."
+  (if evil-search-prompt
+      (setq ad-return-value evil-search-prompt)
+    ad-do-it))
+
+(defadvice isearch-delete-char (around evil activate)
+  "Exit search if no search string."
+  (cond
+   ((and evil-search-prompt (string= isearch-string ""))
+    (let (search-nonincremental-instead)
+      (setq isearch-success nil)
+      (isearch-exit)))
+   (t
+    ad-do-it)))
+
+(defadvice isearch-lazy-highlight-search (around evil activate)
+  "Never wrap the search in this context."
+  (let (evil-search-wrap)
+    ad-do-it))
+
+;;; Ex search
+
+(defun evil-ex-regex-without-case (re)
+  "Return the regular expression without all occurrences of \\c and \\C."
+  (evil-transform-regexp re '((?c . "") (?C . ""))))
+
+(defun evil-ex-regex-case (re default-case)
+  "Return the case as implied by \\c or \\C in regular expression RE.
+If \\c appears anywhere in the pattern, the pattern is case
+insensitive. If \\C appears, the pattern is case sensitive.
+Only the first occurrence of \\c or \\C is used, all others are
+ignored. If neither \\c nor \\C appears in the pattern, the case
+specified by DEFAULT-CASE is used. DEFAULT-CASE should be either
+`sensitive', `insensitive' or `smart'. In the latter case, the pattern
+will be case-sensitive if and only if it contains an upper-case
+letter, otherwise it will be case-insensitive."
+  (cond
+   ((string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\\\\\([cC]\\)" re)
+    (if (eq (aref (match-string 1 re) 0) ?c) 'insensitive 'sensitive))
+   ((eq default-case 'smart)
+    (if (isearch-no-upper-case-p re t)
+        'insensitive
+      'sensitive))
+   (t default-case)))
+
+;; a pattern
+(defun evil-ex-make-substitute-pattern (regexp flags)
+  "Creates a PATTERN for substitution with FLAGS.
+This function respects the values of `evil-ex-substitute-case'
+and `evil-ex-substitute-global'."
+  (evil-ex-make-pattern regexp
+                        (cond
+                         ((memq ?i flags) 'insensitive)
+                         ((memq ?I flags) 'sensitive)
+                         ((not evil-ex-substitute-case)
+                          evil-ex-search-case)
+                         (t evil-ex-substitute-case))
+                        (or (and evil-ex-substitute-global
+                                 (not (memq ?g flags)))
+                            (and (not evil-ex-substitute-global)
+                                 (memq ?g flags)))))
+
+(defun evil-ex-make-search-pattern (regexp)
+  "Creates a PATTERN for search.
+This function respects the values of `evil-ex-search-case'."
+  (evil-ex-make-pattern regexp evil-ex-search-case t))
+
+(defun evil-ex-make-pattern (regexp case whole-line)
+  "Create a new search pattern.
+REGEXP is the regular expression to be searched for. CASE should
+be either 'sensitive, 'insensitive for case-sensitive and
+case-insensitive search, respectively, or anything else.  In the
+latter case the pattern is smart-case, i.e. it is automatically
+sensitive of the pattern contains one upper case letter,
+otherwise it is insensitive.  The input REGEXP is considered a
+Vim-style regular expression if `evil-ex-search-vim-style-regexp'
+is non-nil, in which case it is transformed to an Emacs style
+regular expression (i.e. certain backslash-codes are
+transformed. Otherwise REGEXP must be an Emacs style regular
+expression and is not transformed."
+  (let ((re (evil-ex-regex-without-case regexp))
+        (ignore-case (eq (evil-ex-regex-case regexp case) 'insensitive)))
+    ;; possibly transform regular expression from vim-style to
+    ;; Emacs-style.
+    (if evil-ex-search-vim-style-regexp
+        (setq re (evil-transform-vim-style-regexp re))
+      ;; Even for Emacs regular expressions we translate certain
+      ;; whitespace sequences
+      (setq re (evil-transform-regexp re
+                                      '((?t . "\t")
+                                        (?n . "\n")
+                                        (?r . "\r")))))
+    (list re ignore-case whole-line)))
+
+(defun evil-ex-pattern-regex (pattern)
+  "Return the regular expression of a search PATTERN."
+  (nth 0 pattern))
+
+(defun evil-ex-pattern-ignore-case (pattern)
+  "Return t if and only if PATTERN should ignore case."
+  (nth 1 pattern))
+
+(defun evil-ex-pattern-whole-line (pattern)
+  "Return t if and only if PATTERN should match all occurences of a line.
+Otherwise PATTERN matches only the first occurence."
+  (nth 2 pattern))
+
+;; Highlight
+(defun evil-ex-make-hl (name &rest args)
+  "Create a new highlight object with name NAME and properties ARGS.
+The following properties are supported:
+:face The face to be used for the highlighting overlays.
+:win The window in which the highlighting should be shown.
+     Note that the highlight will be visible in all windows showing
+     the corresponding buffer, but only the matches visible in the
+     specified window will actually be highlighted. If :win is nil,
+     the matches in all windows will be highlighted.
+:min The minimal buffer position for highlighted matches.
+:max The maximal buffer position for highlighted matches.
+:match-hook A hook to be called once for each highlight.
+            The hook must take two arguments, the highlight and
+            the overlay for that highlight.
+:update-hook A hook called once after updating the highlighting
+             with two arguments, the highlight and a message string
+             describing the current match status."
+  (unless (symbolp name)
+    (user-error "Expected symbol as name of highlight"))
+  (let ((face 'evil-ex-lazy-highlight)
+        (win (selected-window))
+        min max match-hook update-hook)
+    (while args
+      (let ((key (pop args))
+            (val (pop args)))
+        (cond
+         ((eq key :face) (setq face val))
+         ((eq key :win)  (setq win val))
+         ((eq key :min)  (setq min val))
+         ((eq key :max)  (setq max val))
+         ((eq key :match-hook) (setq match-hook val))
+         ((eq key :update-hook) (setq update-hook val))
+         (t (user-error "Unexpected keyword: %s" key)))))
+    (when (assoc name evil-ex-active-highlights-alist)
+      (evil-ex-delete-hl name))
+    (when (null evil-ex-active-highlights-alist)
+      (add-hook 'window-scroll-functions
+                #'evil-ex-hl-update-highlights-scroll nil t)
+      (add-hook 'window-size-change-functions
+                #'evil-ex-hl-update-highlights-resize nil))
+    (push (cons name (vector name
+                             nil
+                             face
+                             win
+                             min
+                             max
+                             match-hook
+                             update-hook
+                             nil))
+          evil-ex-active-highlights-alist)))
+
+(defun evil-ex-hl-name (hl)
+  "Return the name of the highlight HL."
+  (aref hl 0))
+
+(defun evil-ex-hl-pattern (hl)
+  "Return the pattern of the highlight HL."
+  (aref hl 1))
+
+(defun evil-ex-hl-set-pattern (hl pattern)
+  "Set the pattern of the highlight HL to PATTERN."
+  (aset hl 1 pattern))
+
+(defun evil-ex-hl-face (hl)
+  "Return the face of the highlight HL."
+  (aref hl 2))
+
+(defun evil-ex-hl-window (hl)
+  "Return the window of the highlight HL."
+  (aref hl 3))
+
+(defun evil-ex-hl-min (hl)
+  "Return the minimal buffer position of the highlight HL."
+  (aref hl 4))
+
+(defun evil-ex-hl-set-min (hl min)
+  "Set the minimal buffer position of the highlight HL to MIN."
+  (aset hl 4 min))
+
+(defun evil-ex-hl-max (hl)
+  "Return the maximal buffer position of the highlight HL."
+  (aref hl 5))
+
+(defun evil-ex-hl-set-max (hl max)
+  "Set the minimal buffer position of the highlight HL to MAX."
+  (aset hl 5 max))
+
+(defun evil-ex-hl-match-hook (hl)
+  "Return the match-hook of the highlight HL."
+  (aref hl 6))
+
+(defun evil-ex-hl-update-hook (hl)
+  "Return the update-hook of the highlight HL."
+  (aref hl 7))
+
+(defun evil-ex-hl-overlays (hl)
+  "Return the list of active overlays of the highlight HL."
+  (aref hl 8))
+
+(defun evil-ex-hl-set-overlays (hl overlays)
+  "Set the list of active overlays of the highlight HL to OVERLAYS."
+  (aset hl 8 overlays))
+
+(defun evil-ex-delete-hl (name)
+  "Remove the highlighting object with a certain NAME."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (when hl
+      (mapc #'delete-overlay (evil-ex-hl-overlays hl))
+      (setq evil-ex-active-highlights-alist
+            (assq-delete-all name evil-ex-active-highlights-alist))
+      (evil-ex-hl-update-highlights))
+    (when (null evil-ex-active-highlights-alist)
+      (remove-hook 'window-scroll-functions
+                   #'evil-ex-hl-update-highlights-scroll t)
+      (remove-hook 'window-size-change-functions
+                   #'evil-ex-hl-update-highlights-resize))))
+
+(defun evil-ex-hl-active-p (name)
+  "Whether the highlight with a certain NAME is active."
+  (and (assoc name evil-ex-active-highlights-alist) t))
+
+(defun evil-ex-hl-change (name pattern)
+  "Set the regular expression of highlight NAME to PATTERN."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (when hl
+      (evil-ex-hl-set-pattern hl
+                              (if (zerop (length pattern))
+                                  nil
+                                pattern))
+      (evil-ex-hl-idle-update))))
+
+(defun evil-ex-hl-set-region (name beg end &optional type)
+  "Set minimal and maximal position of highlight NAME to BEG and END."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (when hl
+      (evil-ex-hl-set-min hl beg)
+      (evil-ex-hl-set-max hl end)
+      (evil-ex-hl-idle-update))))
+
+(defun evil-ex-hl-get-max (name)
+  "Return the maximal position of the highlight with name NAME."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (and hl (evil-ex-hl-max hl))))
+
+(defun evil-ex-hl-update-highlights ()
+  "Update the overlays of all active highlights."
+  (dolist (hl (mapcar #'cdr evil-ex-active-highlights-alist))
+    (let* ((old-ovs (evil-ex-hl-overlays hl))
+           new-ovs
+           (pattern (evil-ex-hl-pattern hl))
+           (case-fold-search (evil-ex-pattern-ignore-case pattern))
+           (case-replace case-fold-search)
+           (face (evil-ex-hl-face hl))
+           (match-hook (evil-ex-hl-match-hook hl))
+           result)
+      (if pattern
+          ;; collect all visible ranges
+          (let (ranges sranges)
+            (dolist (win (if (eq evil-ex-interactive-search-highlight
+                                 'all-windows)
+                             (get-buffer-window-list (current-buffer) nil t)
+                           (list (evil-ex-hl-window hl))))
+              (let ((beg (max (window-start win)
+                              (or (evil-ex-hl-min hl) (point-min))))
+                    (end (min (window-end win)
+                              (or (evil-ex-hl-max hl) (point-max)))))
+                (when (< beg end)
+                  (push (cons beg end) ranges))))
+            (setq ranges
+                  (sort ranges #'(lambda (r1 r2) (< (car r1) (car r2)))))
+            (while ranges
+              (let ((r1 (pop ranges))
+                    (r2 (pop ranges)))
+                (cond
+                 ;; last range
+                 ((null r2)
+                  (push r1 sranges))
+                 ;; ranges overlap, union
+                 ((>= (cdr r1) (car r2))
+                  (push (cons (car r1)
+                              (max (cdr r1) (cdr r2)))
+                        ranges))
+                 ;; ranges distinct
+                 (t
+                  (push r1 sranges)
+                  (push r2 ranges)))))
+
+            ;; run through all ranges
+            (condition-case lossage
+                (save-match-data
+                  (dolist (r sranges)
+                    (let ((beg (car r))
+                          (end (cdr r)))
+                      (save-excursion
+                        (goto-char beg)
+                        ;; set the overlays for the current highlight,
+                        ;; reusing old overlays (if possible)
+                        (while (and (not (eobp))
+                                    (evil-ex-search-find-next-pattern pattern)
+                                    (<= (match-end 0) end)
+                                    (not (and (= (match-end 0) end)
+                                              (string= (evil-ex-pattern-regex pattern)
+                                                       "^"))))
+                          (let ((ov (or (pop old-ovs) (make-overlay 0 0))))
+                            (move-overlay ov (match-beginning 0) (match-end 0))
+                            (overlay-put ov 'face face)
+                            (overlay-put ov 'evil-ex-hl (evil-ex-hl-name hl))
+                            (overlay-put ov 'priority 1000)
+                            (push ov new-ovs)
+                            (when match-hook (funcall match-hook hl ov)))
+                          (cond
+                           ((and (not (evil-ex-pattern-whole-line pattern))
+                                 (not (string-match-p "\n" (buffer-substring-no-properties
+                                                            (match-beginning 0)
+                                                            (match-end 0)))))
+                            (forward-line))
+                           ((= (match-beginning 0) (match-end 0))
+                            (forward-char))
+                           (t (goto-char (match-end 0))))))))
+                  (mapc #'delete-overlay old-ovs)
+                  (evil-ex-hl-set-overlays hl new-ovs)
+                  (if (or (null pattern) new-ovs)
+                      (setq result t)
+                    ;; Maybe the match could just not be found somewhere else?
+                    (save-excursion
+                      (goto-char (or (evil-ex-hl-min hl) (point-min)))
+                      (if (and (evil-ex-search-find-next-pattern pattern)
+                               (< (match-end 0) (or (evil-ex-hl-max hl)
+                                                    (point-max))))
+                          (setq result (format "Match in line %d"
+                                               (line-number-at-pos
+                                                (match-beginning 0))))
+                        (setq result "No match")))))
+
+              (invalid-regexp
+               (setq result (cadr lossage)))
+
+              (search-failed
+               (setq result (nth 2 lossage)))
+
+              (error
+               (setq result (format "%s" (cadr lossage))))
+
+              (user-error
+               (setq result (format "%s" (cadr lossage))))))
+        ;; no pattern, remove all highlights
+        (mapc #'delete-overlay old-ovs)
+        (evil-ex-hl-set-overlays hl new-ovs))
+      (when (evil-ex-hl-update-hook hl)
+        (funcall (evil-ex-hl-update-hook hl) hl result)))))
+
+(defun evil-ex-search-find-next-pattern (pattern &optional direction)
+  "Look for the next occurrence of PATTERN in a certain DIRECTION.
+Note that this function ignores the whole-line property of PATTERN."
+  (setq direction (or direction 'forward))
+  (let ((case-fold-search (evil-ex-pattern-ignore-case pattern)))
+    (cond
+     ((eq direction 'forward)
+      (re-search-forward (evil-ex-pattern-regex pattern) nil t))
+     ((eq direction 'backward)
+      (let* ((pnt (point))
+             (ret (re-search-backward (evil-ex-pattern-regex pattern) nil t))
+             (m (and ret (match-data))))
+        (if ret
+            (forward-char)
+          (goto-char (point-min)))
+        (let ((fwdret
+               (re-search-forward (evil-ex-pattern-regex pattern) nil t)))
+          (cond
+           ((and fwdret (< (match-beginning 0) pnt))
+            (setq ret fwdret)
+            (goto-char (match-beginning 0)))
+           (ret
+            (set-match-data m)
+            (goto-char (match-beginning 0)))
+           (t
+            (goto-char pnt)
+            ret)))))
+     (t
+      (user-error "Unknown search direction: %s" direction)))))
+
+(defun evil-ex-hl-idle-update ()
+  "Triggers the timer to update the highlights in the current buffer."
+  (when (and evil-ex-interactive-search-highlight
+             evil-ex-active-highlights-alist)
+    (when evil-ex-hl-update-timer
+      (cancel-timer evil-ex-hl-update-timer))
+    (setq evil-ex-hl-update-timer
+          (run-at-time evil-ex-hl-update-delay nil
+                       #'evil-ex-hl-do-update-highlight
+                       (current-buffer)))))
+
+(defun evil-ex-hl-do-update-highlight (&optional buffer)
+  "Timer function for updating the highlights."
+  (when (buffer-live-p buffer)
+    (with-current-buffer buffer
+      (evil-ex-hl-update-highlights)))
+  (setq evil-ex-hl-update-timer nil))
+
+(defun evil-ex-hl-update-highlights-scroll (win beg)
+  "Update highlights after scrolling in some window."
+  (with-current-buffer (window-buffer win)
+    (evil-ex-hl-idle-update)))
+(put 'evil-ex-hl-update-highlights-scroll 'permanent-local-hook t)
+
+(defun evil-ex-hl-update-highlights-resize (frame)
+  "Update highlights after resizing a window."
+  (let ((buffers (delete-dups (mapcar #'window-buffer (window-list frame)))))
+    (dolist (buf buffers)
+      (with-current-buffer buf
+        (evil-ex-hl-idle-update)))))
+(put 'evil-ex-hl-update-highlights-resize 'permanent-local-hook t)
+
+;; interactive search
+(defun evil-ex-search-activate-highlight (pattern)
+  "Activate highlighting of the search pattern set to PATTERN.
+This function does nothing if `evil-ex-search-interactive' or
+`evil-ex-search-highlight-all' is nil. "
+  (when (and evil-ex-search-interactive evil-ex-search-highlight-all)
+    (with-current-buffer (or evil-ex-current-buffer (current-buffer))
+      (unless (evil-ex-hl-active-p 'evil-ex-search)
+        (evil-ex-make-hl 'evil-ex-search
+                         :win (minibuffer-selected-window)))
+      (if pattern
+          (evil-ex-hl-change 'evil-ex-search pattern)))))
+
+(defun evil-ex-search (&optional count)
+  "Search forward or backward COUNT times for the current ex search pattern.
+The search pattern is determined by `evil-ex-search-pattern' and
+the direcion is determined by `evil-ex-search-direction'."
+  (setq evil-ex-search-start-point (point)
+        evil-ex-last-was-search t
+        count (or count 1))
+  (let ((orig (point))
+        wrapped)
+    (dotimes (i (or count 1))
+      (when (eq evil-ex-search-direction 'forward)
+        (unless (eobp) (forward-char))
+        ;; maybe skip end-of-line
+        (when (and evil-move-cursor-back (eolp) (not (eobp)))
+          (forward-char)))
+      (let ((res (evil-ex-find-next nil nil (not evil-search-wrap))))
+        (cond
+         ((not res)
+          (goto-char orig)
+          (signal 'search-failed
+                  (list (evil-ex-pattern-regex evil-ex-search-pattern))))
+         ((eq res 'wrapped) (setq wrapped t)))))
+    (if wrapped
+        (let (message-log-max)
+          (message "Search wrapped")))
+    (goto-char (match-beginning 0))
+    (setq evil-ex-search-match-beg (match-beginning 0)
+          evil-ex-search-match-end (match-end 0))
+    (evil-ex-search-goto-offset evil-ex-search-offset)
+    (evil-ex-search-activate-highlight evil-ex-search-pattern)))
+
+(defun evil-ex-find-next (&optional pattern direction nowrap)
+  "Search for the next occurrence of the PATTERN in DIRECTION.
+PATTERN must be created using `evil-ex-make-pattern', DIRECTION
+is either 'forward or 'backward. If NOWRAP is non nil, the search
+does not wrap at buffer boundaries. Furthermore this function
+only searches invisible text if `search-invisible' is t. If
+PATTERN is not specified the current global pattern
+`evil-ex-search-pattern' and if DIRECTION is not specified the
+current global direction `evil-ex-search-direction' is used.
+This function returns t if the search was successful, nil if it
+was unsuccessful and 'wrapped if the search was successful but
+has been wrapped at the buffer boundaries."
+  (setq pattern (or pattern evil-ex-search-pattern)
+        direction (or direction evil-ex-search-direction))
+  (unless (and pattern (evil-ex-pattern-regex pattern))
+    (signal 'search-failed (list "No search pattern")))
+  (catch 'done
+    (let (wrapped)
+      (while t
+        (let ((search-result (evil-ex-search-find-next-pattern pattern
+                                                               direction)))
+          (cond
+           ((and search-result
+                 (or (eq search-invisible t)
+                     (not (isearch-range-invisible
+                           (match-beginning 0) (match-end 0)))))
+            ;; successful search and not invisible
+            (throw 'done (if wrapped 'wrapped t)))
+           ((not search-result)
+            ;; unsuccessful search
+            (if nowrap
+                (throw 'done nil)
+              (setq nowrap t
+                    wrapped t)
+              (goto-char (if (eq direction 'forward)
+                             (point-min)
+                           (point-max)))))))))))
+
+(defun evil-ex-search-update (pattern offset beg end message)
+  "Update the highlighting and info-message for the search pattern.
+PATTERN is the search pattern and OFFSET the associated offset.
+BEG and END specifiy the current match, MESSAGE is the info
+message to be shown. This function does nothing if
+`evil-ex-search-interactive' is nil."
+  (when evil-ex-search-interactive
+    (cond
+     ((and beg end)
+      ;; update overlay
+      (if evil-ex-search-overlay
+          (move-overlay evil-ex-search-overlay beg end)
+        (setq evil-ex-search-overlay
+              (make-overlay beg end))
+        (overlay-put evil-ex-search-overlay 'priority 1001)
+        (overlay-put evil-ex-search-overlay 'face 'evil-ex-search))
+      ;; move point
+      (goto-char beg)
+      (evil-ex-search-goto-offset offset)
+      ;; update highlights
+      (when evil-ex-search-highlight-all
+        (evil-ex-hl-change 'evil-ex-search pattern)))
+     (t
+      ;; no match
+      (when evil-ex-search-overlay
+        ;; remove overlay
+        (delete-overlay evil-ex-search-overlay)
+        (setq evil-ex-search-overlay nil))
+      ;; no highlights
+      (when evil-ex-search-highlight-all
+        (evil-ex-hl-change 'evil-ex-search nil))
+      ;; and go to initial position
+      (goto-char evil-ex-search-start-point)))
+    (when (stringp message)
+      (evil-ex-echo "%s" message))))
+
+(defun evil-ex-search-start-session ()
+  "Initialize Ex for interactive search."
+  (remove-hook 'minibuffer-setup-hook #'evil-ex-search-start-session)
+  (add-hook 'after-change-functions #'evil-ex-search-update-pattern nil t)
+  (add-hook 'minibuffer-exit-hook #'evil-ex-search-stop-session)
+  (evil-ex-search-activate-highlight nil))
+(put 'evil-ex-search-start-session 'permanent-local-hook t)
+
+(defun evil-ex-search-stop-session ()
+  "Stop interactive search."
+  (with-current-buffer evil-ex-current-buffer
+    ;; TODO: This is a bad fix to remove duplicates. The duplicates
+    ;;       exist because `isearch-range-invisible' may add a single
+    ;;       overlay multiple times if we are in an unlucky situation
+    ;;       of overlapping overlays. This happens in our case because
+    ;;       of the overlays that are used for (lazy) highlighting.
+    ;;       Perhaps it would be better to disable those overlays
+    ;;       temporarily before calling `isearch-range-invisible'.
+    (setq isearch-opened-overlays (delete-dups isearch-opened-overlays))
+    (isearch-clean-overlays))
+  (remove-hook 'minibuffer-exit-hook #'evil-ex-search-stop-session)
+  (remove-hook 'after-change-functions #'evil-ex-search-update-pattern t)
+  (when evil-ex-search-overlay
+    (delete-overlay evil-ex-search-overlay)
+    (setq evil-ex-search-overlay nil)))
+(put 'evil-ex-search-stop-session 'permanent-local-hook t)
+
+(defun evil-ex-split-search-pattern (pattern direction)
+  "Split PATTERN in regexp, offset and next-pattern parts.
+Returns a triple (regexp  offset next-search)."
+  (save-match-data
+    (if (or (and (eq direction 'forward)
+                 (string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(/\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$"
+                               pattern))
+            (and (eq direction 'backward)
+                 (string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(\\?\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$"
+                               pattern)))
+        (list (substring pattern 0 (match-beginning 1))
+              (match-string 2 pattern)
+              (match-string 3 pattern))
+      (list pattern nil nil))))
+
+(defun evil-ex-search-full-pattern (pattern-string count direction)
+  "Search for a full search pattern PATTERN-STRING in DIRECTION.
+This function split PATTERN-STRING in
+pattern/offset/;next-pattern parts and performs the search in
+DIRECTION which must be either 'forward or 'backward. The first
+search is repeated COUNT times. If the pattern part of
+PATTERN-STRING is empty, the last global pattern stored in
+`evil-ex-search-pattern' is used instead if in addition the
+offset part is nil (i.e. no pattern/offset separator), the last
+global offset stored in `evil-ex-search-offset' is used as
+offset. The current match data will correspond to the last
+successful match.  This function returns a triple (RESULT PATTERN
+OFFSET) where RESULT is
+
+  t              the search has been successful without wrap
+  'wrap          the search has been successful with wrap
+  'empty-pattern the last pattern has been empty
+  nil            the search has not been successful
+
+and PATTERN and OFFSET are the last pattern and offset this
+function searched for. Note that this function does not handle
+any error conditions."
+  (setq count (or count 1))
+  (catch 'done
+    (while t
+      (let* ((res (evil-ex-split-search-pattern pattern-string direction))
+             (pat (pop res))
+             (offset (pop res))
+             (next-pat (pop res)))
+        ;; use last pattern of no new pattern has been specified
+        (if (not (zerop (length pat)))
+            (setq pat (evil-ex-make-search-pattern pat))
+          (setq pat evil-ex-search-pattern
+                offset (or offset evil-ex-search-offset)))
+        (when (zerop (length pat))
+          (throw 'done (list 'empty-pattern pat offset)))
+        (let (search-result)
+          (while (> count 0)
+            (let ((result (evil-ex-find-next pat direction
+                                             (not evil-search-wrap))))
+              (if (not result) (setq search-result nil count 0)
+                (setq search-result
+                      (if (or (eq result 'wrap)
+                              (eq search-result 'wrap))
+                          'wrap t)
+                      count (1- count)))))
+          (cond
+           ;; search failed
+           ((not search-result) (throw 'done (list nil pat offset)))
+           ;; no next pattern, search complete
+           ((zerop (length next-pat))
+            (evil-ex-search-goto-offset offset)
+            (throw 'done (list search-result pat offset)))
+           ;; next pattern but empty
+           ((= 1 (length next-pat))
+            (evil-ex-search-goto-offset offset)
+            (throw 'done (list 'empty-pattern pat offset)))
+           ;; next non-empty pattern, next search iteration
+           (t
+            (evil-ex-search-goto-offset offset)
+            (setq count 1
+                  pattern-string (substring next-pat 1)
+                  direction (if (= (aref next-pat 0) ?/)
+                                'forward
+                              'backward)))))))))
+
+(defun evil-ex-search-update-pattern (beg end range)
+  "Update the current search pattern."
+  (save-match-data
+    (let ((pattern-string (minibuffer-contents)))
+      (with-current-buffer evil-ex-current-buffer
+        (with-selected-window (minibuffer-selected-window)
+          (goto-char (1+ evil-ex-search-start-point))
+          (condition-case err
+              (let* ((result (evil-ex-search-full-pattern pattern-string
+                                                          (or evil-ex-search-count 1)
+                                                          evil-ex-search-direction))
+                     (success (pop result))
+                     (pattern (pop result))
+                     (offset (pop result)))
+                (cond
+                 ((eq success 'wrap)
+                  (evil-ex-search-update pattern offset
+                                         (match-beginning 0) (match-end 0)
+                                         "Wrapped"))
+                 ((eq success 'empty-pattern)
+                  (evil-ex-search-update nil nil nil nil nil))
+                 (success
+                  (evil-ex-search-update pattern offset
+                                         (match-beginning 0) (match-end 0)
+                                         nil))
+                 (t
+                  (evil-ex-search-update nil nil
+                                         nil nil
+                                         "search failed"))))
+            (invalid-regexp
+             (evil-ex-search-update nil nil nil nil (cadr err)))
+            (error
+             (evil-ex-search-update nil nil nil nil (format "%s" err)))))))))
+(put 'evil-ex-search-update-pattern 'permanent-local-hook t)
+
+(defun evil-ex-search-exit ()
+  "Exit interactive search, keeping lazy highlighting active."
+  (interactive)
+  (evil-ex-search-stop-session)
+  (exit-minibuffer))
+
+(defun evil-ex-search-abort ()
+  "Abort interactive search, disabling lazy highlighting."
+  (interactive)
+  (evil-ex-search-stop-session)
+  (evil-ex-delete-hl 'evil-ex-search)
+  (abort-recursive-edit))
+
+(defun evil-ex-search-goto-offset (offset)
+  "Move point according to search OFFSET and set `evil-this-type' accordingly.
+This function assumes that the current match data represents the
+current search result."
+  (unless (zerop (length offset))
+    (let ((beg (match-beginning 0))
+          (end (match-end 0)))
+      (save-match-data
+        (unless
+            (string-match
+             "^\\([esb]\\)?\\(\\([-+]\\)?\\([0-9]*\\)\\)$"
+             offset)
+          (user-error "Invalid search offset: %s" offset))
+        (let ((count (if (= (match-beginning 4) (match-end 4))
+                         (cond
+                          ((not (match-beginning 3)) 0)
+                          ((= (aref offset (match-beginning 3)) ?+) +1)
+                          (t -1))
+                       (string-to-number (match-string 2 offset)))))
+          (cond
+           ((not (match-beginning 1))
+            (setq evil-this-type 'line)
+            (forward-line count))
+           ((= (aref offset (match-beginning 1)) ?e)
+            (goto-char (+ end count -1))
+            (setq evil-this-type 'inclusive))
+           ((memq (aref offset (match-beginning 1)) '(?s ?b))
+            (goto-char (+ beg count))
+            (setq evil-this-type 'inclusive))))))))
+
+(defun evil-ex-search-setup ()
+  "Hook to initialize the minibuffer for ex search."
+  (add-hook 'pre-command-hook #'evil-ex-remove-default))
+
+(defun evil-ex-start-search (direction count)
+  "Start a new search in a certain DIRECTION."
+  ;; store buffer and window where the search started
+  (let ((evil-ex-current-buffer (current-buffer)))
+    (setq evil-ex-search-count count
+          evil-ex-search-direction direction
+          evil-ex-search-start-point (point)
+          evil-ex-last-was-search t)
+    (progn
+      ;; ensure minibuffer is initialized accordingly
+      (add-hook 'minibuffer-setup-hook #'evil-ex-search-start-session)
+      ;; read the search string
+      (let* ((minibuffer-local-map evil-ex-search-keymap)
+             (search-string
+              (condition-case err
+                  (minibuffer-with-setup-hook
+                      #'evil-ex-search-setup
+                    (read-string (if (eq evil-ex-search-direction 'forward)
+                                     "/" "?")
+                                 (and evil-ex-search-history
+                                      (propertize
+                                       (car evil-ex-search-history)
+                                       'face 'shadow))
+                                 'evil-ex-search-history))
+                (quit
+                 (evil-ex-search-stop-session)
+                 (evil-ex-delete-hl 'evil-ex-search)
+                 (goto-char evil-ex-search-start-point)
+                 (signal (car err) (cdr err))))))
+        ;; pattern entered successful
+        (goto-char (1+ evil-ex-search-start-point))
+        (let* ((result
+                (evil-ex-search-full-pattern search-string
+                                             evil-ex-search-count
+                                             evil-ex-search-direction))
+               (success (pop result))
+               (pattern (pop result))
+               (offset (pop result)))
+          (setq evil-ex-search-pattern pattern
+                evil-ex-search-offset offset)
+          (cond
+           ((memq success '(t wrap))
+            (goto-char (match-beginning 0))
+            (setq evil-ex-search-match-beg (match-beginning 0)
+                  evil-ex-search-match-end (match-end 0))
+            (evil-ex-search-goto-offset offset)
+            (evil-push-search-history search-string (eq direction 'forward))
+            (unless evil-ex-search-persistent-highlight
+              (evil-ex-delete-hl 'evil-ex-search)))
+           (t
+            (goto-char evil-ex-search-start-point)
+            (evil-ex-delete-hl 'evil-ex-search)
+            (signal 'search-failed (list search-string)))))))))
+
+(defun evil-ex-start-word-search (unbounded direction count &optional symbol)
+  "Search for the symbol under point.
+The search matches the COUNT-th occurrence of the word.  If the
+UNBOUNDED argument is nil, the search matches only at symbol
+boundaries, otherwise it matches anywhere.  The DIRECTION
+argument should be either `forward' or `backward', determining
+the search direction. If SYMBOL is non-nil then the functions
+searches for the symbol at point, otherwise for the word at
+point."
+  (let ((string (evil-find-thing (eq direction 'forward)
+                                 (if symbol 'symbol 'word))))
+    (if (null string)
+        (user-error "No word under point")
+      (let ((regex (if unbounded
+                       (regexp-quote string)
+                     (format (if symbol "\\_<%s\\_>" "\\<%s\\>")
+                             (regexp-quote string)))))
+        (setq evil-ex-search-count count
+              evil-ex-search-direction direction
+              evil-ex-search-pattern
+              (evil-ex-make-search-pattern regex)
+              evil-ex-search-offset nil
+              evil-ex-last-was-search t)
+        ;; update search history unless this pattern equals the
+        ;; previous pattern
+        (unless (equal (car-safe evil-ex-search-history) regex)
+          (push regex evil-ex-search-history))
+        (evil-push-search-history regex (eq direction 'forward)))
+      (evil-ex-delete-hl 'evil-ex-search)
+      (when (fboundp 'evil-ex-search-next)
+        (evil-ex-search-next count)))))
+
+;; substitute
+(evil-ex-define-argument-type substitution
+  "A substitution pattern argument /pattern/replacement/flags.
+This handler highlights the pattern of the current substitution."
+  :runner
+  (lambda (flag &optional arg)
+    (with-selected-window (minibuffer-selected-window)
+      (with-current-buffer evil-ex-current-buffer
+        (cond
+         ((eq flag 'start)
+          (evil-ex-make-hl
+           'evil-ex-substitute
+           :face 'evil-ex-substitute-matches
+           :update-hook #'evil-ex-pattern-update-ex-info
+           :match-hook (and evil-ex-substitute-interactive-replace
+                            #'evil-ex-pattern-update-replacement))
+          (setq flag 'update))
+
+         ((eq flag 'stop)
+          (evil-ex-delete-hl 'evil-ex-substitute))))
+
+      (when (and (eq flag 'update)
+                 evil-ex-substitute-highlight-all
+                 (not (zerop (length arg))))
+        (condition-case lossage
+            (let* ((result (evil-ex-get-substitute-info arg t))
+                   (pattern (pop result))
+                   (replacement (pop result))
+                   (range (or (evil-copy-range evil-ex-range)
+                              (evil-range (line-beginning-position)
+                                          (line-end-position)
+                                          'line
+                                          :expanded t))))
+              (setq evil-ex-substitute-current-replacement replacement)
+              (evil-expand-range range)
+              (evil-ex-hl-set-region 'evil-ex-substitute
+                                     (evil-range-beginning range)
+                                     (evil-range-end range))
+              (evil-ex-hl-change 'evil-ex-substitute pattern))
+          (end-of-file
+           (evil-ex-pattern-update-ex-info nil
+                                           "incomplete replacement"))
+          (user-error
+           (evil-ex-pattern-update-ex-info nil
+                                           (format "%s" lossage))))))))
+
+(defun evil-ex-pattern-update-ex-info (hl result)
+  "Update the Ex info string."
+  (when (stringp result)
+    (evil-ex-echo "%s" result)))
+
+(defun evil-ex-pattern-update-replacement (hl overlay)
+  "Update the replacement display."
+  (when (fboundp 'match-substitute-replacement)
+    (let ((fixedcase (not case-replace))
+          repl)
+      (setq repl (if evil-ex-substitute-current-replacement
+                     (evil-match-substitute-replacement
+                      evil-ex-substitute-current-replacement
+                      fixedcase)
+                   ""))
+      (put-text-property 0 (length repl)
+                         'face 'evil-ex-substitute-replacement
+                         repl)
+      (overlay-put overlay 'after-string repl))))
+
+(defun evil-ex-parse-global (string)
+  "Parse STRING as a global argument."
+  (let* ((args (evil-delimited-arguments string 2))
+         (pattern (nth 0 args))
+         (command (nth 1 args)))
+    ;; use last pattern if none given
+    (when (zerop (length pattern))
+      (setq pattern
+            (cond
+             ((and (eq evil-search-module 'evil-search) evil-ex-search-pattern)
+              (evil-ex-pattern-regex evil-ex-search-pattern))
+             ((and (eq evil-search-module 'isearch) (not (zerop (length isearch-string))))
+              isearch-string)
+             (t (user-error "No previous pattern")))))
+    (list pattern command)))
+
+(defun evil-ex-get-substitute-info (string &optional implicit-r)
+  "Returns the substitution info of command line STRING.
+This function returns a three-element list \(PATTERN REPLACEMENT
+FLAGS) consisting of the substitution parts of STRING. PATTERN is
+a ex-pattern (see `evil-ex-make-pattern') and REPLACEMENT in a
+compiled replacement expression (see `evil-compile-replacement').
+The information returned is the actual substitution information
+w.r.t. to special situations like empty patterns or repetition of
+previous substitution commands. If IMPLICIT-R is non-nil, then
+the flag 'r' is assumed, i.e. in the case of an empty pattern the
+last search pattern is used. This will be used when called from
+a :substitute command with arguments."
+  (let (pattern replacement flags)
+    (cond
+     ((or (null string) (string-match "^[a-zA-Z]" string))
+      ;; starts with letter so there is no pattern because the
+      ;; separator must not be a letter repeat last substitute
+      (setq replacement evil-ex-substitute-replacement)
+      ;; flags are everything that is not a white space
+      (when (and string (string-match "[^[:space:]]+" string))
+        (setq flags (match-string 0 string))))
+     (t
+      (let ((args (evil-delimited-arguments string 3)))
+        (setq pattern (pop args)
+              replacement (pop args)
+              flags (pop args))
+        ;; if replacment equals "~" use previous replacement
+        (if (equal replacement "~")
+            (setq replacement evil-ex-substitute-replacement)
+          (setq replacement (evil-compile-replacement replacement)))
+        ;; append implicit "r" flag if required
+        (when (and implicit-r (not (memq ?r (append flags nil))))
+          (setq flags (concat flags "r"))))))
+    ;; if flags equals "&" add previous flags
+    (if (and (not (zerop (length flags)))
+             (= (aref flags 0) ?&))
+        (setq flags (append (substring flags 1)
+                            evil-ex-substitute-flags))
+      (setq flags (append flags nil)))
+    ;; if no pattern, use previous pattern, either search or
+    ;; substitute pattern depending on `evil-ex-last-was-search' and
+    ;; the r flag
+    (when (zerop (length pattern))
+      (setq pattern
+            (if (eq evil-search-module 'evil-search)
+                (if (and evil-ex-last-was-search (memq ?r flags))
+                    (and evil-ex-search-pattern
+                         (evil-ex-pattern-regex evil-ex-search-pattern))
+                  (and evil-ex-substitute-pattern
+                       (evil-ex-pattern-regex evil-ex-substitute-pattern)))
+              (if (eq case-fold-search t)
+                  isearch-string
+                (concat isearch-string "\\C")))
+            flags (remq ?r flags)))
+    ;; generate pattern
+    (when pattern
+      (setq pattern (evil-ex-make-substitute-pattern pattern flags)))
+    (list pattern replacement flags)))
+
+(defun evil-ex-nohighlight ()
+  "Disable the active search highlightings."
+  (interactive)
+  (evil-ex-delete-hl 'evil-ex-substitute)
+  (evil-ex-delete-hl 'evil-ex-search))
+
+(provide 'evil-search)
+
+;;; evil-search.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-search.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-states.el
@@ -0,0 +1,905 @@
+;;; evil-states.el --- States
+
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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-core)
+
+;;; Code:
+
+;;; Normal state
+
+(evil-define-state normal
+  "Normal state.
+AKA \"Command\" state."
+  :tag " <N> "
+  :enable (motion)
+  :exit-hook (evil-repeat-start-hook)
+  (cond
+   ((evil-normal-state-p)
+    (overwrite-mode -1)
+    (add-hook 'post-command-hook #'evil-normal-post-command nil t))
+   (t
+    (remove-hook 'post-command-hook #'evil-normal-post-command t))))
+
+(defun evil-normal-post-command (&optional command)
+  "Reset command loop variables in Normal state.
+Also prevent point from reaching the end of the line.
+If the region is activated, enter Visual state."
+  (unless (or (evil-initializing-p)
+              (null this-command))
+    (setq command (or command this-command))
+    (when (evil-normal-state-p)
+      (setq evil-this-type nil
+            evil-this-operator nil
+            evil-this-motion nil
+            evil-this-motion-count nil
+            evil-inhibit-operator nil
+            evil-inhibit-operator-value nil)
+      (unless (memq command '(evil-use-register
+                              digit-argument
+                              negative-argument
+                              universal-argument
+                              universal-argument-minus
+                              universal-argument-more
+                              universal-argument-other-key))
+        (setq evil-this-register nil))
+      (evil-adjust-cursor))))
+(put 'evil-normal-post-command 'permanent-local-hook t)
+
+;;; Insert state
+
+(defun evil-maybe-remove-spaces (&optional do-remove)
+  "Remove space from newly opened empty line.
+This function removes (indentation) spaces that have been
+inserted by opening a new empty line. The behavior depends on the
+variable `evil-maybe-remove-spaces'. If this variable is nil the
+function does nothing. Otherwise the behavior depends on
+DO-REMOVE.  If DO-REMOVE is non-nil the spaces are
+removed. Otherwise `evil-maybe-remove-spaces' is set to nil
+unless the last command opened yet another new line.
+
+This function should be added as a post-command-hook to track
+commands opening a new line."
+  (cond
+   ((not evil-maybe-remove-spaces)
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))
+   (do-remove
+    (when (save-excursion
+            (beginning-of-line)
+            (looking-at "^\\s-*$"))
+      (delete-region (line-beginning-position)
+                     (line-end-position)))
+    (setq evil-maybe-remove-spaces nil)
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))
+   ((not (memq this-command
+               '(evil-open-above
+                 evil-open-below
+                 evil-append
+                 evil-append-line
+                 newline
+                 newline-and-indent
+                 indent-and-newline)))
+    (setq evil-maybe-remove-spaces nil)
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))))
+
+(evil-define-state insert
+  "Insert state."
+  :tag " <I> "
+  :cursor (bar . 2)
+  :message "-- INSERT --"
+  :entry-hook (evil-start-track-last-insertion)
+  :exit-hook (evil-cleanup-insert-state evil-stop-track-last-insertion)
+  :input-method t
+  (cond
+   ((evil-insert-state-p)
+    (add-hook 'post-command-hook #'evil-maybe-remove-spaces)
+    (add-hook 'pre-command-hook #'evil-insert-repeat-hook)
+    (setq evil-maybe-remove-spaces t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-start-undo-step)))
+   (t
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces)
+    (remove-hook 'pre-command-hook #'evil-insert-repeat-hook)
+    (evil-maybe-remove-spaces t)
+    (setq evil-insert-repeat-info evil-repeat-info)
+    (evil-set-marker ?^ nil t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-end-undo-step))
+    (when evil-move-cursor-back
+      (when (or (evil-normal-state-p evil-next-state)
+                (evil-motion-state-p evil-next-state))
+        (evil-move-cursor-back))))))
+
+(defun evil-insert-repeat-hook ()
+  "Record insertion keys in `evil-insert-repeat-info'."
+  (setq evil-insert-repeat-info (last evil-repeat-info))
+  (remove-hook 'pre-command-hook #'evil-insert-repeat-hook))
+(put 'evil-insert-repeat-hook 'permanent-local-hook t)
+
+(defun evil-cleanup-insert-state ()
+  "Called when Insert state is about to be exited.
+Handles the repeat-count of the insertion command."
+  (when evil-insert-count
+    (dotimes (i (1- evil-insert-count))
+      (when evil-insert-lines
+        (evil-insert-newline-below)
+        (when evil-auto-indent
+          (indent-according-to-mode)))
+      (when (fboundp 'evil-execute-repeat-info)
+        (evil-execute-repeat-info
+         (cdr evil-insert-repeat-info)))))
+  (when evil-insert-vcount
+    (let ((buffer-invisibility-spec buffer-invisibility-spec))
+      ;; make all lines hidden by hideshow temporarily visible
+      (when (listp buffer-invisibility-spec)
+        (setq buffer-invisibility-spec
+              (evil-filter-list
+               #'(lambda (x)
+                   (or (eq x 'hs)
+                       (eq (car-safe x) 'hs)))
+               buffer-invisibility-spec)))
+      (let ((line (nth 0 evil-insert-vcount))
+            (col (nth 1 evil-insert-vcount))
+            (vcount (nth 2 evil-insert-vcount)))
+        (save-excursion
+          (dotimes (v (1- vcount))
+            (goto-char (point-min))
+            (forward-line (+ line v))
+            (when (or (not evil-insert-skip-empty-lines)
+                      (not (integerp col))
+                      (save-excursion
+                        (evil-move-end-of-line)
+                        (>= (current-column) col)))
+              (if (integerp col)
+                  (move-to-column col t)
+                (funcall col))
+              (dotimes (i (or evil-insert-count 1))
+                (when (fboundp 'evil-execute-repeat-info)
+                  (evil-execute-repeat-info
+                   (cdr evil-insert-repeat-info)))))))))))
+
+;;; Visual state
+
+;; Visual selections are implemented in terms of types, and are
+;; compatible with the Emacs region. This is achieved by "translating"
+;; the region to the selected text right before a command is executed.
+;; If the command is a motion, the translation is postponed until a
+;; non-motion command is invoked (distinguished by the :keep-visual
+;; command property).
+;;
+;; Visual state activates the region, enabling Transient Mark mode if
+;; not already enabled. This is only temporay: if Transient Mark mode
+;; was disabled before entering Visual state, it is disabled when
+;; exiting Visual state. This allows Visual state to harness the
+;; "transient" behavior of many commands without overriding the user's
+;; preferences in other states.
+
+(defmacro evil-define-visual-selection (selection doc &rest body)
+  "Define a Visual selection SELECTION.
+Creates a command evil-visual-SELECTION for enabling the selection.
+DOC is the function's documentation string. The following keywords
+may be specified in BODY:
+
+:message STRING         Status message when enabling the selection.
+:type TYPE              Type to use (defaults to SELECTION).
+
+Following the keywords is optional code which is executed each time
+the selection is enabled.
+
+\(fn SELECTION DOC [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name stringp
+                           [&rest keywordp sexp]
+                           def-body)))
+  (let* ((name (intern (format "evil-visual-%s" selection)))
+         (message (intern (format "%s-message" name)))
+         (type selection)
+         arg key string)
+    ;; collect keywords
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :message)
+        (setq string arg))
+       ((eq key :type)
+        (setq type arg))))
+    ;; macro expansion
+    `(progn
+       (add-to-list 'evil-visual-alist (cons ',selection ',name))
+       (defvar ,name ',type ,(format "*%s" doc))
+       (defvar ,message ,string ,doc)
+       (evil-define-command ,name (&optional mark point type message)
+         ,@(when doc `(,doc))
+         :keep-visual t
+         :repeat nil
+         (interactive
+          (list nil nil
+                (if (and (evil-visual-state-p)
+                         (eq evil-visual-selection ',selection))
+                    'exit ,name) t))
+         (if (eq type 'exit)
+             (evil-exit-visual-state)
+           (setq type (or type ,name)
+                 evil-visual-selection ',selection)
+           (evil-visual-make-region mark point type message)
+           ,@body))
+       ',selection)))
+
+(evil-define-visual-selection char
+  "Characterwise selection."
+  :type inclusive
+  :message "-- VISUAL --")
+
+(evil-define-visual-selection line
+  "Linewise selection."
+  :message "-- VISUAL LINE --")
+
+(evil-define-visual-selection block
+  "Blockwise selection."
+  :message "-- VISUAL BLOCK --"
+  (evil-transient-mark -1)
+  ;; refresh the :corner property
+  (setq evil-visual-properties
+        (plist-put evil-visual-properties :corner
+                   (evil-visual-block-corner 'upper-left))))
+
+(evil-define-state visual
+  "Visual state."
+  :tag " <V> "
+  :enable (motion normal)
+  :message 'evil-visual-message
+  (cond
+   ((evil-visual-state-p)
+    (evil-save-transient-mark-mode)
+    (setq select-active-regions nil)
+    (cond
+     ((region-active-p)
+      (if (< (evil-visual-direction) 0)
+          (evil-visual-select (region-beginning) (region-end)
+                              evil-visual-char
+                              (evil-visual-direction))
+        (evil-visual-make-selection (mark t) (point)
+                                    evil-visual-char))
+      (evil-visual-highlight))
+     (t
+      (evil-visual-make-region (point) (point) evil-visual-char)))
+    (add-hook 'pre-command-hook #'evil-visual-pre-command nil t)
+    (add-hook 'post-command-hook #'evil-visual-post-command nil t)
+    (add-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook nil t))
+   (t
+    ;; Postpone deactivation of region if next state is Insert.
+    ;; This gives certain insertion commands (auto-pairing characters,
+    ;; for example) an opportunity to access the region.
+    (if (and (eq evil-next-state 'insert)
+             (eq evil-visual-selection 'char))
+        (add-hook 'evil-normal-state-entry-hook
+                  #'evil-visual-deactivate-hook nil t)
+      (evil-visual-deactivate-hook))
+    (setq evil-visual-region-expanded nil)
+    (remove-hook 'pre-command-hook #'evil-visual-pre-command t)
+    (remove-hook 'post-command-hook #'evil-visual-post-command t)
+    (remove-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook t)
+    (evil-visual-highlight -1))))
+
+(defun evil-visual-pre-command (&optional command)
+  "Run before each COMMAND in Visual state.
+Expand the region to the selection unless COMMAND is a motion."
+  (when (evil-visual-state-p)
+    (setq command (or command this-command))
+    (when evil-visual-x-select-timer
+      (cancel-timer evil-visual-x-select-timer))
+    (unless (evil-get-command-property command :keep-visual)
+      (evil-visual-update-x-selection)
+      (evil-visual-expand-region
+       ;; exclude final newline from linewise selection
+       ;; unless the command has real need of it
+       (and (eq (evil-visual-type) 'line)
+            (evil-get-command-property command :exclude-newline))))))
+
+(put 'evil-visual-pre-command 'permanent-local-hook t)
+
+(defun evil-visual-post-command (&optional command)
+  "Run after each COMMAND in Visual state.
+If COMMAND is a motion, refresh the selection;
+otherwise exit Visual state."
+  (when (evil-visual-state-p)
+    (setq command (or command this-command))
+    (if (or quit-flag
+            (eq command #'keyboard-quit)
+            ;; Is `mark-active' nil for an unexpanded region?
+            deactivate-mark
+            (and (not evil-visual-region-expanded)
+                 (not (region-active-p))
+                 (not (eq evil-visual-selection 'block))))
+        (progn
+          (evil-exit-visual-state)
+          (evil-adjust-cursor))
+      (if evil-visual-region-expanded
+          (evil-visual-contract-region)
+        (evil-visual-refresh))
+      (setq evil-visual-x-select-timer
+            (run-with-idle-timer evil-visual-x-select-timeout nil
+                                 #'evil-visual-update-x-selection
+                                 (current-buffer)))
+      (evil-visual-highlight))))
+(put 'evil-visual-post-command 'permanent-local-hook t)
+
+(defun evil-visual-update-x-selection (&optional buffer)
+  "Update the X selection with the current visual region."
+  (let ((buf (or buffer (current-buffer))))
+    (when (buffer-live-p buf)
+      (with-current-buffer buf
+        (when (and (evil-visual-state-p)
+                   (fboundp 'x-select-text)
+                   (or (not (boundp 'ns-initialized))
+                       (with-no-warnings ns-initialized))
+                   (not (eq evil-visual-selection 'block)))
+          (x-select-text (buffer-substring-no-properties
+                          evil-visual-beginning
+                          evil-visual-end)))))))
+
+(defun evil-visual-activate-hook (&optional command)
+  "Enable Visual state if the region is activated."
+  (unless (evil-visual-state-p)
+    (evil-delay nil
+        ;; the activation may only be momentary, so re-check
+        ;; in `post-command-hook' before entering Visual state
+        '(unless (or (evil-visual-state-p)
+                     (evil-insert-state-p)
+                     (evil-emacs-state-p))
+           (when (and (region-active-p)
+                      (not deactivate-mark))
+             (evil-visual-state)))
+      'post-command-hook nil t
+      "evil-activate-visual-state")))
+(put 'evil-visual-activate-hook 'permanent-local-hook t)
+
+(defun evil-visual-deactivate-hook (&optional command)
+  "Deactivate the region and restore Transient Mark mode."
+  (setq command (or command this-command))
+  (remove-hook 'deactivate-mark-hook
+               #'evil-visual-deactivate-hook t)
+  (remove-hook 'evil-normal-state-entry-hook
+               #'evil-visual-deactivate-hook t)
+  (cond
+   ((and (evil-visual-state-p) command
+         (not (evil-get-command-property command :keep-visual)))
+    (setq evil-visual-region-expanded nil)
+    (evil-exit-visual-state))
+   ((not (evil-visual-state-p))
+    (evil-active-region -1)
+    (evil-restore-transient-mark-mode))))
+(put 'evil-visual-deactivate-hook 'permanent-local-hook t)
+
+(evil-define-command evil-exit-visual-state (&optional later buffer)
+  "Exit from Visual state to the previous state.
+If LATER is non-nil, exit after the current command."
+  :keep-visual t
+  :repeat abort
+  (with-current-buffer (or buffer (current-buffer))
+    (when (evil-visual-state-p)
+      (if later
+          (setq deactivate-mark t)
+        (when evil-visual-region-expanded
+          (evil-visual-contract-region))
+        (evil-change-to-previous-state)))))
+
+(defun evil-visual-message (&optional selection)
+  "Create an echo area message for SELECTION.
+SELECTION is a kind of selection as defined by
+`evil-define-visual-selection', such as `char', `line'
+or `block'."
+  (let (message)
+    (setq selection (or selection evil-visual-selection))
+    (when selection
+      (setq message
+            (symbol-value (intern (format "evil-visual-%s-message"
+                                          selection))))
+      (cond
+       ((functionp message)
+        (funcall message))
+       ((stringp message)
+        (evil-echo "%s" message))))))
+
+(defun evil-visual-select (beg end &optional type dir message)
+  "Create a Visual selection of type TYPE from BEG to END.
+Point and mark are positioned so that the resulting selection
+has the specified boundaries. If DIR is negative, point precedes mark,
+otherwise it succedes it. To specify point and mark directly,
+use `evil-visual-make-selection'."
+  (let* ((range (evil-contract beg end type))
+         (mark (evil-range-beginning range))
+         (point (evil-range-end range))
+         (dir (or dir 1)))
+    (when (< dir 0)
+      (evil-swap mark point))
+    (evil-visual-make-selection mark point type message)))
+
+(defun evil-visual-make-selection (mark point &optional type message)
+  "Create a Visual selection with point at POINT and mark at MARK.
+The boundaries of the selection are inferred from these
+and the current TYPE. To specify the boundaries and infer
+mark and point, use `evil-visual-select' instead."
+  (let* ((selection (evil-visual-selection-for-type type))
+         (func (evil-visual-selection-function selection))
+         (prev (and (evil-visual-state-p) evil-visual-selection))
+         (mark (evil-normalize-position mark))
+         (point (evil-normalize-position point))
+         (state evil-state))
+    (unless (evil-visual-state-p)
+      (evil-visual-state))
+    (setq evil-visual-selection selection)
+    (funcall func mark point type
+             ;; signal a message when changing the selection
+             (when (or (not (evil-visual-state-p state))
+                       (not (eq selection prev)))
+               message))))
+
+(defun evil-visual-make-region (mark point &optional type message)
+  "Create an active region from MARK to POINT.
+If TYPE is given, also set the Visual type.
+If MESSAGE is given, display it in the echo area."
+  (interactive)
+  (let* ((point (evil-normalize-position
+                 (or point (point))))
+         (mark (evil-normalize-position
+                (or mark
+                    (when (or (evil-visual-state-p)
+                              (region-active-p))
+                      (mark t))
+                    point))))
+    (unless (evil-visual-state-p)
+      (evil-visual-state))
+    (evil-active-region 1)
+    (setq evil-visual-region-expanded nil)
+    (evil-visual-refresh mark point type)
+    (cond
+     ((null evil-echo-state))
+     ((stringp message)
+      (evil-echo "%s" message))
+     (message
+      (cond
+       ((stringp evil-visual-state-message)
+        (evil-echo "%s" evil-visual-state-message))
+       ((functionp evil-visual-state-message)
+        (funcall evil-visual-state-message)))))))
+
+(defun evil-visual-expand-region (&optional exclude-newline)
+  "Expand the region to the Visual selection.
+If EXCLUDE-NEWLINE is non-nil and the selection ends with a newline,
+exclude that newline from the region."
+  (when (and (evil-visual-state-p)
+             (not evil-visual-region-expanded))
+    (let ((mark evil-visual-beginning)
+          (point evil-visual-end))
+      (when (< evil-visual-direction 0)
+        (evil-swap mark point))
+      (setq evil-visual-region-expanded t)
+      (evil-visual-refresh mark point)
+      (when (and exclude-newline
+                 (save-excursion
+                   (goto-char evil-visual-end)
+                   (and (bolp) (not (bobp)))))
+        (if (< evil-visual-direction 0)
+            (evil-move-mark (max point (1- (mark))))
+          (goto-char (max mark (1- (point)))))))))
+
+(defun evil-visual-contract-region ()
+  "The inverse of `evil-visual-expand-region'.
+Create a Visual selection that expands to the current region."
+  (evil-visual-refresh)
+  (setq evil-visual-region-expanded nil)
+  (evil-visual-refresh evil-visual-mark evil-visual-point))
+
+(defun evil-visual-refresh (&optional mark point type &rest properties)
+  "Refresh point, mark and Visual variables.
+Refreshes `evil-visual-beginning', `evil-visual-end',
+`evil-visual-mark', `evil-visual-point', `evil-visual-selection',
+`evil-visual-direction', `evil-visual-properties' and `evil-this-type'."
+  (let* ((point (or point (point)))
+         (mark (or mark (mark t) point))
+         (dir (evil-visual-direction))
+         (type (or type (evil-visual-type evil-visual-selection)
+                   (evil-visual-type)))
+         range)
+    (evil-move-mark mark)
+    (goto-char point)
+    (setq evil-visual-beginning
+          (or evil-visual-beginning
+              (let ((marker (make-marker)))
+                (move-marker marker (min point mark))))
+          evil-visual-end
+          (or evil-visual-end
+              (let ((marker (make-marker)))
+                (set-marker-insertion-type marker t)
+                (move-marker marker (max point mark))))
+          evil-visual-mark
+          (or evil-visual-mark
+              (let ((marker (make-marker)))
+                (move-marker marker mark)))
+          evil-visual-point
+          (or evil-visual-point
+              (let ((marker (make-marker)))
+                (move-marker marker point))))
+    (setq evil-visual-properties
+          (evil-concat-plists evil-visual-properties properties))
+    (cond
+     (evil-visual-region-expanded
+      (setq type (or (evil-visual-type) type))
+      (move-marker evil-visual-beginning (min point mark))
+      (move-marker evil-visual-end (max point mark))
+      ;; if the type is one-to-one, we can safely refresh
+      ;; the unexpanded positions as well
+      (when (evil-type-property type :one-to-one)
+        (setq range (apply #'evil-contract point mark type
+                           evil-visual-properties)
+              mark (evil-range-beginning range)
+              point (evil-range-end range))
+        (when (< dir 0)
+          (evil-swap mark point))
+        (move-marker evil-visual-mark mark)
+        (move-marker evil-visual-point point)))
+     (t
+      (setq range (apply #'evil-expand point mark type
+                         evil-visual-properties)
+            type (evil-type range type))
+      (move-marker evil-visual-beginning (evil-range-beginning range))
+      (move-marker evil-visual-end (evil-range-end range))
+      (move-marker evil-visual-mark mark)
+      (move-marker evil-visual-point point)))
+    (setq evil-visual-direction dir
+          evil-this-type type)))
+
+(defun evil-visual-highlight (&optional arg)
+  "Highlight Visual selection, depending on the Visual type.
+With negative ARG, disable highlighting."
+  (cond
+   ((and (numberp arg) (< arg 1))
+    (when evil-visual-overlay
+      (delete-overlay evil-visual-overlay)
+      (setq evil-visual-overlay nil))
+    (when evil-visual-block-overlays
+      (mapc #'delete-overlay evil-visual-block-overlays)
+      (setq evil-visual-block-overlays nil)))
+   ((eq evil-visual-selection 'block)
+    (when evil-visual-overlay
+      (evil-visual-highlight -1))
+    (evil-visual-highlight-block
+     evil-visual-beginning
+     evil-visual-end))
+   (t
+    (when evil-visual-block-overlays
+      (evil-visual-highlight -1))
+    (if evil-visual-overlay
+        (move-overlay evil-visual-overlay
+                      evil-visual-beginning evil-visual-end)
+      (setq evil-visual-overlay
+            (make-overlay evil-visual-beginning evil-visual-end)))
+    (overlay-put evil-visual-overlay 'face 'region)
+    (overlay-put evil-visual-overlay 'priority 99))))
+
+(defun evil-visual-highlight-block (beg end &optional overlays)
+  "Highlight rectangular region from BEG to END.
+Do this by putting an overlay on each line within the rectangle.
+Each overlay extends across all the columns of the rectangle.
+Reuse overlays where possible to prevent flicker."
+  (let* ((point (point))
+         (mark (or (mark t) point))
+         (overlays (or overlays 'evil-visual-block-overlays))
+         (old (symbol-value overlays))
+         (eol-col (and (memq this-command '(next-line previous-line))
+                       (numberp temporary-goal-column)
+                       (1+ (min (round temporary-goal-column)
+                                (1- most-positive-fixnum)))))
+         beg-col end-col new nlines overlay window-beg window-end)
+    (save-excursion
+      ;; calculate the rectangular region represented by BEG and END,
+      ;; but put BEG in the upper-left corner and END in the
+      ;; lower-right if not already there
+      (setq beg-col (evil-column beg)
+            end-col (evil-column end))
+      (when (>= beg-col end-col)
+        (if (= beg-col end-col)
+            (setq end-col (1+ end-col))
+          (evil-sort beg-col end-col))
+        (setq beg (save-excursion
+                    (goto-char beg)
+                    (evil-move-to-column beg-col))
+              end (save-excursion
+                    (goto-char end)
+                    (evil-move-to-column end-col 1))))
+      ;; update end column with eol-col (extension to eol).
+      (when (and eol-col (> eol-col end-col))
+        (setq end-col eol-col))
+      ;; force a redisplay so we can do reliable window
+      ;; BEG/END calculations
+      (sit-for 0)
+      (setq window-beg (max (window-start) beg)
+            window-end (min (window-end) (1+ end))
+            nlines (count-lines window-beg
+                                (min window-end (point-max))))
+      ;; iterate over those lines of the rectangle which are
+      ;; visible in the currently selected window
+      (goto-char window-beg)
+      (dotimes (i nlines)
+        (let (before after row-beg row-end)
+          ;; beginning of row
+          (evil-move-to-column beg-col)
+          (when (< (current-column) beg-col)
+            ;; prepend overlay with virtual spaces if unable to
+            ;; move directly to the first column
+            (setq before
+                  (propertize
+                   (make-string
+                    (- beg-col (current-column)) ?\ )
+                   'face
+                   (or (get-text-property (1- (point)) 'face)
+                       'default))))
+          (setq row-beg (point))
+          ;; end of row
+          (evil-move-to-column end-col)
+          (when (and (not (eolp))
+                     (< (current-column) end-col))
+            ;; append overlay with virtual spaces if unable to
+            ;; move directly to the last column
+            (setq after
+                  (propertize
+                   (make-string
+                    (if (= (point) row-beg)
+                        (- end-col beg-col)
+                      (- end-col (current-column)))
+                    ?\ ) 'face 'region))
+            ;; place cursor on one of the virtual spaces
+            (if (= point row-beg)
+                (put-text-property
+                 0 (min (length after) 1)
+                 'cursor t after)
+              (put-text-property
+               (max 0 (1- (length after))) (length after)
+               'cursor t after)))
+          (setq row-end (min (point) (line-end-position)))
+          ;; trim old leading overlays
+          (while (and old
+                      (setq overlay (car old))
+                      (< (overlay-start overlay) row-beg)
+                      (/= (overlay-end overlay) row-end))
+            (delete-overlay overlay)
+            (setq old (cdr old)))
+          ;; reuse an overlay if possible, otherwise create one
+          (cond
+           ((and old (setq overlay (car old))
+                 (or (= (overlay-start overlay) row-beg)
+                     (= (overlay-end overlay) row-end)))
+            (move-overlay overlay row-beg row-end)
+            (overlay-put overlay 'before-string before)
+            (overlay-put overlay 'after-string after)
+            (setq new (cons overlay new)
+                  old (cdr old)))
+           (t
+            (setq overlay (make-overlay row-beg row-end))
+            (overlay-put overlay 'before-string before)
+            (overlay-put overlay 'after-string after)
+            (setq new (cons overlay new)))))
+        (forward-line 1))
+      ;; display overlays
+      (dolist (overlay new)
+        (overlay-put overlay 'face 'region)
+        (overlay-put overlay 'priority 99))
+      ;; trim old overlays
+      (dolist (overlay old)
+        (delete-overlay overlay))
+      (set overlays (nreverse new)))))
+
+(defun evil-visual-range ()
+  "Return the Visual selection as a range.
+This is a list (BEG END TYPE PROPERTIES...), where BEG is the
+beginning of the selection, END is the end of the selection,
+TYPE is the selection's type, and PROPERTIES is a property list
+of miscellaneous selection attributes."
+  (apply #'evil-range
+         evil-visual-beginning evil-visual-end
+         (evil-visual-type)
+         :expanded t
+         evil-visual-properties))
+
+(defun evil-visual-direction ()
+  "Return direction of Visual selection.
+The direction is -1 if point precedes mark and 1 otherwise.
+See also the variable `evil-visual-direction', which holds
+the direction of the last selection."
+  (let* ((point (point))
+         (mark (or (mark t) point)))
+    (if (< point mark) -1 1)))
+
+(defun evil-visual-type (&optional selection)
+  "Return the type of the Visual selection.
+If SELECTION is specified, return the type of that instead."
+  (if (and (null selection) (evil-visual-state-p))
+      (or evil-this-type (evil-visual-type evil-visual-selection))
+    (setq selection (or selection evil-visual-selection))
+    (symbol-value (cdr-safe (assq selection evil-visual-alist)))))
+
+(defun evil-visual-goto-end ()
+  "Go to the last line of the Visual selection.
+This position may differ from `evil-visual-end' depending on
+the selection type, and is contained in the selection."
+  (let ((range (evil-contract-range (evil-visual-range))))
+    (goto-char (evil-range-end range))))
+
+(defun evil-visual-alist ()
+  "Return an association list from types to selection symbols."
+  (mapcar #'(lambda (e)
+              (cons (symbol-value (cdr-safe e)) (cdr-safe e)))
+          evil-visual-alist))
+
+(defun evil-visual-selection-function (selection)
+  "Return a selection function for TYPE.
+Default to `evil-visual-make-region'."
+  (or (cdr-safe (assq selection evil-visual-alist))
+      ;; generic selection function
+      'evil-visual-make-region))
+
+(defun evil-visual-selection-for-type (type)
+  "Return a Visual selection for TYPE."
+  (catch 'done
+    (dolist (selection evil-visual-alist)
+      (when (eq (symbol-value (cdr selection)) type)
+        (throw 'done (car selection))))))
+
+(defun evil-visual-block-corner (&optional corner point mark)
+  "Block corner corresponding to POINT, with MARK in opposite corner.
+Depending on POINT and MARK, the return value is `upper-left',
+`upper-right', `lower-left' or `lower-right':
+
+        upper-left +---+ upper-right
+                   |   |
+        lower-left +---+ lower-right
+
+One-column or one-row blocks are ambiguous. In such cases,
+the horizontal or vertical component of CORNER is used.
+CORNER defaults to `upper-left'."
+  (let* ((point (or point (point)))
+         (mark (or mark (mark t)))
+         (corner (symbol-name
+                  (or corner
+                      (and (overlayp evil-visual-overlay)
+                           (overlay-get evil-visual-overlay
+                                        :corner))
+                      'upper-left)))
+         (point-col (evil-column point))
+         (mark-col (evil-column mark))
+         horizontal vertical)
+    (cond
+     ((= point-col mark-col)
+      (setq horizontal
+            (or (and (string-match "left\\|right" corner)
+                     (match-string 0 corner))
+                "left")))
+     ((< point-col mark-col)
+      (setq horizontal "left"))
+     ((> point-col mark-col)
+      (setq horizontal "right")))
+    (cond
+     ((= (line-number-at-pos point)
+         (line-number-at-pos mark))
+      (setq vertical
+            (or (and (string-match "upper\\|lower" corner)
+                     (match-string 0 corner))
+                "upper")))
+     ((< point mark)
+      (setq vertical "upper"))
+     ((> point mark)
+      (setq vertical "lower")))
+    (intern (format "%s-%s" vertical horizontal))))
+
+;;; Operator-Pending state
+
+(evil-define-state operator
+  "Operator-Pending state."
+  :tag " <O> "
+  :cursor evil-half-cursor
+  :enable (evil-operator-shortcut-map operator motion normal))
+
+(evil-define-keymap evil-operator-shortcut-map
+  "Keymap for Operator-Pending shortcuts like \"dd\" and \"gqq\"."
+  :local t
+  (setq evil-operator-shortcut-map (make-sparse-keymap))
+  (evil-initialize-local-keymaps))
+
+;; the half-height "Operator-Pending cursor" cannot be specified
+;; as a static `cursor-type' value, since its height depends on
+;; the current font size
+(defun evil-half-cursor ()
+  "Change cursor to a half-height box.
+\(This is really just a thick horizontal bar.)"
+  (let ((height (/ (window-pixel-height) (* (window-height) 2))))
+    (setq cursor-type (cons 'hbar height))))
+
+;;; Replace state
+
+(evil-define-state replace
+  "Replace state."
+  :tag " <R> "
+  :cursor hbar
+  :message "-- REPLACE --"
+  :input-method t
+  (cond
+   ((evil-replace-state-p)
+    (overwrite-mode 1)
+    (add-hook 'pre-command-hook #'evil-replace-pre-command nil t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-start-undo-step)))
+   (t
+    (overwrite-mode -1)
+    (remove-hook 'pre-command-hook #'evil-replace-pre-command t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-end-undo-step))
+    (when evil-move-cursor-back
+      (evil-move-cursor-back))))
+  (setq evil-replace-alist nil))
+
+(defun evil-replace-pre-command ()
+  "Remember the character under point."
+  (when (evil-replace-state-p)
+    (unless (assq (point) evil-replace-alist)
+      (add-to-list 'evil-replace-alist
+                   (cons (point)
+                         (unless (eolp)
+                           (char-after)))))))
+(put 'evil-replace-pre-command 'permanent-local-hook t)
+
+(defun evil-replace-backspace ()
+  "Restore character under cursor."
+  (interactive)
+  (let (char)
+    (backward-char)
+    (when (assq (point) evil-replace-alist)
+      (setq char (cdr (assq (point) evil-replace-alist)))
+      (save-excursion
+        (delete-char 1)
+        (when char
+          (insert char))))))
+
+;;; Motion state
+
+(evil-define-state motion
+  "Motion state."
+  :tag " <M> "
+  :suppress-keymap t)
+
+;;; Emacs state
+
+(evil-define-state emacs
+  "Emacs state."
+  :tag " <E> "
+  :message "-- EMACS --"
+  :input-method t
+  :intercept-esc nil)
+
+(provide 'evil-states)
+
+;;; evil-states.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-states.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-types.el
@@ -0,0 +1,424 @@
+;;; evil-types.el --- Type system
+
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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/>.
+
+;;; Commentary:
+
+;; A type defines a transformation on a pair of buffer positions.
+;; Types are used by Visual state (character/line/block selection)
+;; and Operator-Pending state (character/line/block motions).
+;;
+;; The basic transformation is "expansion". For example, the `line'
+;; type "expands" a pair of positions to whole lines by moving the
+;; first position to the beginning of the line and the last position
+;; to the end of the line. That expanded selection is what the rest
+;; of Emacs sees and acts on.
+;;
+;; An optional transformation is "contraction", which is the opposite
+;; of expansion. If the transformation is one-to-one, expansion
+;; followed by contraction always returns the original range.
+;; (The `line' type is not one-to-one, as it may expand multiple
+;; positions to the same lines.)
+;;
+;; Another optional transformation is "normalization", which takes
+;; two unexpanded positions and adjusts them before expansion.
+;; This is useful for cleaning up "invalid" positions.
+;;
+;; Types are defined at the end of this file using the macro
+;; `evil-define-type'.
+
+(require 'evil-common)
+(require 'evil-macros)
+
+;;; Code:
+
+;;; Type definitions
+
+(evil-define-type exclusive
+  "Return the positions unchanged, with some exceptions.
+If the end position is at the beginning of a line, then:
+
+* If the beginning position is at or before the first non-blank
+  character on the line, return `line' (expanded).
+
+* Otherwise, move the end position to the end of the previous
+  line and return `inclusive' (expanded)."
+  :normalize (lambda (beg end)
+               (cond
+                ((progn
+                   (goto-char end)
+                   (and (/= beg end) (bolp)))
+                 (setq end (max beg (1- end)))
+                 (cond
+                  ((progn
+                     (goto-char beg)
+                     (looking-back "^[ \f\t\v]*" (line-beginning-position)))
+                   (evil-expand beg end 'line))
+                  (t
+                   (unless evil-cross-lines
+                     (setq end (max beg (1- end))))
+                   (evil-expand beg end 'inclusive))))
+                (t
+                 (evil-range beg end))))
+  :string (lambda (beg end)
+            (let ((width (- end beg)))
+              (format "%s character%s" width
+                      (if (= width 1) "" "s")))))
+
+(evil-define-type inclusive
+  "Include the character under point.
+If the end position is at the beginning of a line or the end of a
+line and `evil-want-visual-char-semi-exclusive', then:
+
+* If in visual state return `exclusive' (expanded)."
+  :expand (lambda (beg end)
+            (if (and evil-want-visual-char-semi-exclusive
+                     (evil-visual-state-p)
+                     (< beg end)
+                     (save-excursion
+                       (goto-char end)
+                       (or (bolp) (eolp))))
+                (evil-range beg end 'exclusive)
+              (evil-range beg (1+ end))))
+  :contract (lambda (beg end)
+              (evil-range beg (max beg (1- end))))
+  :normalize (lambda (beg end)
+               (goto-char end)
+               (when (eq (char-after) ?\n)
+                 (setq end (max beg (1- end))))
+               (evil-range beg end))
+  :string (lambda (beg end)
+            (let ((width (- end beg)))
+              (format "%s character%s" width
+                      (if (= width 1) "" "s")))))
+
+(evil-define-type line
+  "Include whole lines."
+  :one-to-one nil
+  :expand (lambda (beg end)
+            (evil-range
+             (progn
+               (goto-char beg)
+               (min (line-beginning-position)
+                    (progn
+                      ;; move to beginning of line as displayed
+                      (evil-move-beginning-of-line)
+                      (line-beginning-position))))
+             (progn
+               (goto-char end)
+               (max (line-beginning-position 2)
+                    (progn
+                      ;; move to end of line as displayed
+                      (evil-move-end-of-line)
+                      (line-beginning-position 2))))))
+  :contract (lambda (beg end)
+              (evil-range beg (max beg (1- end))))
+  :string (lambda (beg end)
+            (let ((height (count-lines beg end)))
+              (format "%s line%s" height
+                      (if (= height 1) "" "s")))))
+
+(evil-define-type block
+  "Like `inclusive', but for rectangles:
+the last column is included."
+  :expand (lambda (beg end &rest properties)
+            (let ((beg-col (evil-column beg))
+                  (end-col (evil-column end))
+                  (corner (plist-get properties :corner)))
+              ;; Since blocks are implemented as a pair of buffer
+              ;; positions, expansion is restricted to what the buffer
+              ;; allows. In the case of a one-column block, there are
+              ;; two ways to expand it (either move the upper corner
+              ;; beyond the lower corner, or the lower beyond the
+              ;; upper), so try out both possibilities when
+              ;; encountering the end of the line.
+              (cond
+               ((= beg-col end-col)
+                (goto-char end)
+                (cond
+                 ((eolp)
+                  (goto-char beg)
+                  (if (eolp)
+                      (evil-range beg end)
+                    (evil-range (1+ beg) end)))
+                 ((memq corner '(lower-right upper-right right))
+                  (evil-range (1+ beg) end))
+                 (t
+                  (evil-range beg (1+ end)))))
+               ((< beg-col end-col)
+                (goto-char end)
+                (if (eolp)
+                    (evil-range beg end)
+                  (evil-range beg (1+ end))))
+               (t
+                (goto-char beg)
+                (if (eolp)
+                    (evil-range beg end)
+                  (evil-range (1+ beg) end))))))
+  :contract (lambda (beg end)
+              (let ((beg-col (evil-column beg))
+                    (end-col (evil-column end)))
+                (if (> beg-col end-col)
+                    (evil-range (1- beg) end)
+                  (evil-range beg (max beg (1- end))))))
+  :string (lambda (beg end)
+            (let ((height (count-lines
+                           beg
+                           (progn
+                             (goto-char end)
+                             (if (and (bolp) (not (eobp)))
+                                 (1+ end)
+                               end))))
+                  (width (abs (- (evil-column beg)
+                                 (evil-column end)))))
+              (format "%s row%s and %s column%s"
+                      height
+                      (if (= height 1) "" "s")
+                      width
+                      (if (= width 1) "" "s"))))
+  :rotate (lambda (beg end &rest properties)
+            "Rotate block according to :corner property.
+:corner can be one of `upper-left',``upper-right', `lower-left'
+and `lower-right'."
+            (let ((left  (evil-column beg))
+                  (right (evil-column end))
+                  (corner (or (plist-get properties :corner)
+                              'upper-left)))
+              (evil-sort left right)
+              (goto-char beg)
+              (if (memq corner '(upper-right lower-left))
+                  (move-to-column right)
+                (move-to-column left))
+              (setq beg (point))
+              (goto-char end)
+              (if (memq corner '(upper-right lower-left))
+                  (move-to-column left)
+                (move-to-column right))
+              (setq end (point))
+              (setq properties (plist-put properties
+                                          :corner corner))
+              (apply #'evil-range beg end properties))))
+
+(evil-define-type rectangle
+  "Like `exclusive', but for rectangles:
+the last column is excluded."
+  :expand (lambda (beg end)
+            ;; select at least one column
+            (if (= (evil-column beg) (evil-column end))
+                (evil-expand beg end 'block)
+              (evil-range beg end 'block))))
+
+;;; Standard interactive codes
+
+(evil-define-interactive-code "*"
+  "Signal error if the buffer is read-only."
+  (when buffer-read-only
+    (signal 'buffer-read-only nil)))
+
+(evil-define-interactive-code "b" (prompt)
+  "Name of existing buffer."
+  (list (read-buffer prompt (current-buffer) t)))
+
+(evil-define-interactive-code "c"
+  "Read character."
+  (list (read-char)))
+
+(evil-define-interactive-code "p"
+  "Prefix argument converted to number."
+  (list (prefix-numeric-value current-prefix-arg)))
+
+(evil-define-interactive-code "P"
+  "Prefix argument in raw form."
+  (list current-prefix-arg))
+
+;;; Custom interactive codes
+
+(evil-define-interactive-code "<c>"
+  "Count."
+  (list (when current-prefix-arg
+          (prefix-numeric-value
+           current-prefix-arg))))
+
+(evil-define-interactive-code "<vc>"
+  "Count, but only in visual state.
+This should be used by an operator taking a count. In normal
+state the count should not be handled by the operator but by the
+motion that defines the operator's range. In visual state the
+range is specified by the visual region and the count is not used
+at all. Thus in the case the operator may use the count
+directly."
+  (list (when (and (evil-visual-state-p) current-prefix-arg)
+          (prefix-numeric-value
+           current-prefix-arg))))
+
+(evil-define-interactive-code "<C>"
+  "Character read through `evil-read-key'."
+  (list
+   (if (evil-operator-state-p)
+       (evil-without-restriction (evil-read-key))
+     (evil-read-key))))
+
+(evil-define-interactive-code "<r>"
+  "Untyped motion range (BEG END)."
+  (evil-operator-range))
+
+(evil-define-interactive-code "<R>"
+  "Typed motion range (BEG END TYPE)."
+  (evil-operator-range t))
+
+(evil-define-interactive-code "<v>"
+  "Typed motion range of visual range(BEG END TYPE).
+If visual state is inactive then those values are nil."
+  (if (evil-visual-state-p)
+      (let ((range (evil-visual-range)))
+        (list (car range)
+              (cadr range)
+              (evil-type range)))
+    (list nil nil nil)))
+
+(evil-define-interactive-code "<x>"
+  "Current register."
+  (list evil-this-register))
+
+(evil-define-interactive-code "<y>"
+  "Current yank-handler."
+  (list (evil-yank-handler)))
+
+(evil-define-interactive-code "<a>"
+  "Ex argument."
+  :ex-arg t
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<f>"
+  "Ex file argument."
+  :ex-arg file
+  (list (when (evil-ex-p) (evil-ex-file-arg))))
+
+(evil-define-interactive-code "<b>"
+  "Ex buffer argument."
+  :ex-arg buffer
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<sh>"
+  "Ex shell command argument."
+  :ex-arg shell
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<fsh>"
+  "Ex file or shell command argument."
+  :ex-arg file-or-shell
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<sym>"
+  "Ex symbolic argument."
+  :ex-arg sym
+  (list (when (and (evil-ex-p) evil-ex-argument)
+          (intern evil-ex-argument))))
+
+(evil-define-interactive-code "<addr>"
+  "Ex line number."
+  (list
+   (and (evil-ex-p)
+        (let ((expr (evil-ex-parse  evil-ex-argument)))
+          (if (eq (car expr) 'evil-goto-line)
+              (save-excursion
+                (goto-char evil-ex-point)
+                (eval (cadr expr)))
+            (user-error "Invalid address"))))))
+
+(evil-define-interactive-code "<!>"
+  "Ex bang argument."
+  :ex-bang t
+  (list (when (evil-ex-p) evil-ex-bang)))
+
+(evil-define-interactive-code "</>"
+  "Ex delimited argument."
+  (when (evil-ex-p)
+    (evil-delimited-arguments evil-ex-argument)))
+
+(evil-define-interactive-code "<g/>"
+  "Ex global argument."
+  (when (evil-ex-p)
+    (evil-ex-parse-global evil-ex-argument)))
+
+(evil-define-interactive-code "<s/>"
+  "Ex substitution argument."
+  :ex-arg substitution
+  (when (evil-ex-p)
+    (evil-ex-get-substitute-info evil-ex-argument t)))
+
+(evil-define-interactive-code "<xc/>"
+  "Ex register and count argument, both optional.
+Can be used for commands such as :delete [REGISTER] [COUNT] where the
+command can be called with either zero, one or two arguments. When the
+argument is one, if it's numeric it's treated as a COUNT, otherwise -
+REGISTER"
+  (when (evil-ex-p)
+    (evil-ex-get-optional-register-and-count evil-ex-argument)))
+
+(defun evil-ex-get-optional-register-and-count (string)
+  "Parse STRING as an ex arg with both optional REGISTER and COUNT.
+Returns a list (REGISTER COUNT)."
+  (let* ((split-args (split-string (or string "")))
+         (arg-count (length split-args))
+         (arg0 (car split-args))
+         (arg1 (cadr split-args))
+         (number-regex "^-?[1-9][0-9]*$")
+         (register nil)
+         (count nil))
+    (cond
+     ;; :command REGISTER or :command COUNT
+     ((= arg-count 1)
+      (if (string-match-p number-regex arg0)
+          (setq count arg0)
+        (setq register arg0)))
+     ;; :command REGISTER COUNT
+     ((eq arg-count 2)
+      (setq register arg0
+            count arg1))
+     ;; more than 2 args aren't allowed
+     ((> arg-count 2)
+      (user-error "Invalid use")))
+
+    ;; if register is given, check it's valid
+    (when register
+      (unless (= (length register) 1)
+        (user-error "Invalid register"))
+      (setq register (string-to-char register)))
+
+    ;; if count is given, check it's valid
+    (when count
+      (unless (string-match-p number-regex count)
+        (user-error "Invalid count"))
+      (setq count (string-to-number count))
+      (unless (> count 0)
+        (user-error "Invalid count")))
+
+    (list register count)))
+
+(provide 'evil-types)
+
+;;; evil-types.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-types.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil-vars.el
@@ -0,0 +1,1854 @@
+;;; evil-vars.el --- Settings and variables
+
+;; Author: Vegard ร˜ye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard ร˜ye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.12
+
+;;
+;; 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/>.
+
+;;; Code:
+
+(declare-function evil-add-command-properties "evil-common"
+                  (command &rest properties))
+(declare-function evil-update-insert-state-bindings "evil-maps"
+                  (&optional _option-name remove force))
+
+;;; Hooks
+
+(defvar evil-after-load-hook nil
+  "Functions to be run when loading of evil is finished.
+This hook can be used the execute some initialization routines
+when evil is completely loaded.")
+
+;;; Initialization
+
+(defvar evil-pending-custom-initialize nil
+  "A list of pending initializations for custom variables.
+Each element is a triple (FUNC VAR VALUE). When evil is
+completely loaded then the functions (funcall FUNC VAR VALUE) is
+called for each element. FUNC should be a function suitable for
+the :initialize property of `defcustom'.")
+
+(defun evil-custom-initialize-pending-reset (var value)
+  "Add a pending customization with `custom-initialize-reset'."
+  (push (list 'custom-initialize-reset var value)
+        evil-pending-custom-initialize))
+
+(defun evil-run-pending-custom-initialize ()
+  "Executes the pending initializations.
+See `evil-pending-custom-initialize'."
+  (dolist (init evil-pending-custom-initialize)
+    (apply (car init) (cdr init)))
+  (remove-hook 'evil-after-load-hook 'evil-run-pending-custom-initialize))
+(add-hook 'evil-after-load-hook 'evil-run-pending-custom-initialize)
+
+;;; Setters
+
+(defun evil-set-toggle-key (key)
+  "Set `evil-toggle-key' to KEY.
+KEY must be readable by `read-kbd-macro'."
+  (let ((old-key (read-kbd-macro
+                  (if (boundp 'evil-toggle-key)
+                      evil-toggle-key
+                    "C-z")))
+        (key (read-kbd-macro key)))
+    (with-no-warnings
+      (dolist (pair '((evil-motion-state-map evil-emacs-state)
+                      (evil-insert-state-map evil-emacs-state)
+                      (evil-emacs-state-map evil-exit-emacs-state)))
+        (when (boundp (car pair))
+          (let ((map (symbol-value (car pair)))
+                (fun (cadr pair)))
+            (when (keymapp map)
+              (define-key map key fun)
+              (define-key map old-key nil))))))))
+
+(defun evil-set-custom-state-maps (var pending-var key make newlist)
+  "Changes the list of special keymaps.
+VAR         is the variable containing the list of keymaps.
+PENDING-VAR is the variable containing the list of the currently pending
+            keymaps.
+KEY         the special symbol to be stored in the keymaps.
+MAKE        the creation function of the special keymaps.
+NEWLIST     the list of new special keymaps."
+  (set-default pending-var newlist)
+  (when (default-boundp var)
+    (dolist (map (default-value var))
+      (when (and (boundp (car map))
+                 (keymapp (default-value (car map))))
+        (define-key (default-value (car map)) (vector key) nil))))
+  (set-default var newlist)
+  (evil-update-pending-maps))
+
+(defun evil-update-pending-maps (&optional file)
+  "Tries to set pending special keymaps.
+This function should be called from an `after-load-functions'
+hook."
+  (let ((maps '((evil-make-overriding-map . evil-pending-overriding-maps)
+                (evil-make-intercept-map . evil-pending-intercept-maps))))
+    (while maps
+      (let* ((map (pop maps))
+             (make (car map))
+             (pending-var (cdr map))
+             (pending (symbol-value pending-var))
+             newlist)
+        (while pending
+          (let* ((map (pop pending))
+                 (kmap (and (boundp (car map))
+                            (keymapp (symbol-value (car map)))
+                            (symbol-value (car map))))
+                 (state (cdr map)))
+            (if kmap
+                (funcall make kmap state)
+              (push map newlist))))
+        (set-default pending-var newlist)))))
+
+(defun evil-set-visual-newline-commands (var value)
+  "Set the value of `evil-visual-newline-commands'.
+Setting this variable changes the properties of the appropriate
+commands."
+  (with-no-warnings
+    (when (default-boundp var)
+      (dolist (cmd (default-value var))
+        (evil-set-command-property cmd :exclude-newline nil)))
+    (set-default var value)
+    (dolist (cmd (default-value var))
+      (evil-set-command-property cmd :exclude-newline t))))
+
+(defun evil-set-custom-motions (var values)
+  "Sets the list of motion commands."
+  (with-no-warnings
+    (when (default-boundp var)
+      (dolist (motion (default-value var))
+        (evil-add-command-properties motion :keep-visual nil :repeat nil)))
+    (set-default var values)
+    (mapc #'evil-declare-motion (default-value var))))
+
+;;; Customization group
+
+(defgroup evil nil
+  "Extensible vi layer."
+  :group 'emulations
+  :prefix 'evil-)
+
+(defcustom evil-auto-indent t
+  "Whether to auto-indent when entering Insert state."
+  :type  'boolean
+  :group 'evil)
+(make-variable-buffer-local 'evil-auto-indent)
+
+(defcustom evil-shift-width 4
+  "The offset used by \\<evil-normal-state-map>\\[evil-shift-right] \
+and \\[evil-shift-left]."
+  :type 'integer
+  :group 'evil)
+(make-variable-buffer-local 'evil-shift-width)
+
+(defcustom evil-shift-round t
+  "Whether \\<evil-normal-state-map>\\[evil-shift-right] \
+and \\[evil-shift-left] round to the nearest multiple \
+of `evil-shift-width'."
+  :type 'boolean
+  :group 'evil)
+(make-variable-buffer-local 'evil-shift-round)
+
+(defcustom evil-indent-convert-tabs t
+  "If non-nil `evil-indent' converts between leading tabs and spaces.
+  Whether tabs are converted to spaces or vice versa depends on the
+  value of `indent-tabs-mode'."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-default-cursor t
+  "The default cursor.
+May be a cursor type as per `cursor-type', a color string as passed
+to `set-cursor-color', a zero-argument function for changing the
+cursor, or a list of the above."
+  :type '(set symbol (cons symbol symbol) string function)
+  :group 'evil)
+
+(defvar evil-force-cursor nil
+  "Overwrite the current states default cursor.")
+
+(defcustom evil-repeat-move-cursor t
+  "Whether \"\\<evil-normal-state-map>\\[evil-repeat]\" \
+moves the cursor."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-cross-lines nil
+  "Whether motions may cross newlines."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-backspace-join-lines t
+  "Whether backward delete in insert state may join lines."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-move-cursor-back t
+  "Whether the cursor is moved backwards when exiting Insert state."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-move-beyond-eol nil
+  "Whether the cursor is allowed to move past the last character of \
+a line."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-respect-visual-line-mode nil
+  "Whether to remap movement commands when `visual-line-mode' is active.
+This variable must be set before evil is loaded. The commands
+swapped are
+
+`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'"
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-repeat-find-to-skip-next t
+  "Whether a repeat of t or T should skip an adjacent character."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-kbd-macro-suppress-motion-error nil
+  "Whether left/right motions signal errors during keyboard-macro definition.
+If this variable is set to non-nil, then the function
+`evil-forward-char' and `evil-backward-char' do not signal
+`end-of-line' or `beginning-of-line' errors when a keyboard macro
+is being defined and/or it is being executed. This may be desired
+because such an error would cause the macro definition/execution
+being terminated."
+  :type '(radio (const :tag "No" :value nil)
+                (const :tag "Record" :value record)
+                (const :tag "Replay" :value replay)
+                (const :tag "Both" :value t))
+  :group 'evil)
+
+(defcustom evil-track-eol t
+  "If non-nil line moves after a call to `evil-end-of-line' stay at eol.
+This is analogous to `track-eol' but deals with the end-of-line
+interpretation of evil."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-mode-line-format 'before
+  "The position of the mode line tag.
+Either a symbol or a cons-cell. If it is a symbol it should be
+one of 'before, 'after or 'nil. 'before means the tag is
+placed before the mode-list, 'after means it is placed after the
+mode-list, and 'nil means no mode line tag. If it is a cons cell
+it should have the form (WHERE . WHICH) where WHERE is either
+'before or 'after and WHICH is a symbol in
+`mode-line-format'. The tag is then placed right before or after
+that symbol."
+  :type '(radio :value 'before
+                (const before)
+                (const after)
+                (cons :tag "Next to symbol"
+                      (choice :value after
+                              (const before)
+                              (const after))
+                      symbol))
+  :group 'evil)
+
+(defcustom evil-mouse-word 'evil-word
+  "The thing-at-point symbol for double click selection.
+The double-click starts visual state in a special word selection
+mode. This symbol is used to determine the words to be
+selected. Possible values are 'evil-word or
+'evil-WORD."
+  :type 'symbol
+  :group 'evil)
+
+(defcustom evil-bigword "^ \t\r\n"
+  "The characters to be considered as a big word.
+This should be a regexp set without the enclosing []."
+  :type 'string
+  :group 'evil)
+(make-variable-buffer-local 'evil-bigword)
+
+(defcustom evil-want-fine-undo nil
+  "Whether actions like \"cw\" are undone in several steps.
+There are three possible choices. \"No\" means all changes made
+during insert state including a possible delete after a change
+operation are collected in a single undo step. If \"Yes\" is
+selected, undo steps are determined according to Emacs heuristics
+and no attempt is made to further aggregate changes.
+
+As of 1.2.13, the option \"fine\" is ignored and means the same
+thing as \"No\". It used to be the case that fine would only try
+to merge the first two changes in an insert operation. For
+example, merging the delete and first insert operation after
+\"cw\", but this option was removed because it did not work
+consistently."
+  :type '(radio (const :tag "No" :value nil)
+                (const :tag "Fine (obsolete)" :value fine)
+                (const :tag "Yes" :value t))
+  :group 'evil)
+
+(defcustom evil-regexp-search t
+  "Whether to use regular expressions for searching."
+  :type  'boolean
+  :group 'evil)
+
+(defcustom evil-search-wrap t
+  "Whether search wraps around."
+  :type  'boolean
+  :group 'evil)
+
+(defcustom evil-flash-delay 2
+  "Time in seconds to flash search matches."
+  :type  'number
+  :group 'evil)
+
+(defcustom evil-fold-level 0
+  "Default fold level."
+  :type  'integer
+  :group 'evil)
+
+(defcustom evil-auto-balance-windows t
+  "If non-nil creating/deleting a window causes a rebalance."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-split-window-below nil
+  "If non-nil split windows are created below."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-vsplit-window-right nil
+  "If non-nil vsplit windows are created to the right."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-esc-delay 0.01
+  "Time in seconds to wait for another key after ESC."
+  :type 'number
+  :group 'evil)
+
+(defvar evil-esc-mode nil
+  "Non-nil if `evil-esc-mode' is enabled.")
+
+(defvar evil-esc-map nil
+  "Original ESC prefix map in `input-decode-map'.
+Used by `evil-esc-mode'.")
+
+(defvar evil-inhibit-esc nil
+  "If non-nil, the \\e event will never be translated to 'escape.")
+
+(defcustom evil-intercept-esc 'always
+  "Whether evil should intercept the ESC key.
+In terminal, a plain ESC key and a meta-key-sequence both
+generate the same event. In order to distinguish both evil
+modifies `input-decode-map'. This is necessary in terminal but
+not in X mode. However, the terminal ESC is equivalent to C-[, so
+if you want to use C-[ instead of ESC in X, then Evil must
+intercept the ESC event in X, too. This variable determines when
+Evil should intercept the event."
+  :type '(radio (const :tag "Never" :value nil)
+                (const :tag "In terminal only" :value t)
+                (const :tag "Always" :value always))
+  :group 'evil)
+
+(defcustom evil-show-paren-range 0
+  "The minimal distance between point and a parenthesis
+which causes the parenthesis to be highlighted."
+  :type 'integer
+  :group 'evil)
+
+(defcustom evil-ex-hl-update-delay 0.02
+  "Time in seconds of idle before updating search highlighting.
+Setting this to a period shorter than that of keyboard's repeat
+rate allows highlights to update while scrolling."
+  :type 'number
+  :group 'evil)
+
+(defcustom evil-highlight-closing-paren-at-point-states
+  '(not emacs insert replace)
+  "The states in which the closing parenthesis at point should be highlighted.
+All states listed here highlight the closing parenthesis at
+point (which is Vim default behavior), all others highlight the
+parenthesis before point (which is Emacs default behavior). If
+this list contains the symbol 'not then its meaning is inverted,
+i.e., all states listed here highlight the closing parenthesis
+before point."
+  :type '(repeat symbol)
+  :group 'evil)
+
+(defcustom evil-kill-on-visual-paste t
+  "Whether `evil-visual-paste' adds the replaced text to the kill
+ring, making it the default for the next paste. The default, t,
+replicates the default vim behavior."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-want-C-i-jump t
+  "Whether \"C-i\" jumps forward like in Vim."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-motion-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-motion-state-map (kbd "C-i"))
+                        'evil-jump-forward))
+               (define-key evil-motion-state-map (kbd "C-i") nil))
+              ((and value
+                    (not (lookup-key evil-motion-state-map (kbd "C-i"))))
+               (define-key evil-motion-state-map (kbd "C-i") 'evil-jump-forward))))))
+
+(defcustom evil-want-C-u-scroll nil
+  "Whether \"C-u\" scrolls like in Vim."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-motion-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-motion-state-map (kbd "C-u"))
+                        'evil-scroll-up))
+               (define-key evil-motion-state-map (kbd "C-u") nil))
+              ((and value
+                    (not (lookup-key evil-motion-state-map (kbd "C-u"))))
+               (define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up))))))
+
+(defcustom evil-want-C-d-scroll t
+  "Whether \"C-d\" scrolls like in Vim."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-motion-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-motion-state-map (kbd "C-d"))
+                        'evil-scroll-down))
+               (define-key evil-motion-state-map (kbd "C-d") nil))
+              ((and value
+                    (not (lookup-key evil-motion-state-map (kbd "C-d"))))
+               (define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down))))))
+
+(defcustom evil-want-C-w-delete t
+  "Whether \"C-w\" deletes a word in Insert state."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-insert-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-insert-state-map (kbd "C-w"))
+                        'evil-delete-backward-word))
+               (define-key evil-insert-state-map (kbd "C-w") 'evil-window-map))
+              ((and value
+                    (eq (lookup-key evil-insert-state-map (kbd "C-w"))
+                        'evil-window-map))
+               (define-key evil-insert-state-map (kbd "C-w") 'evil-delete-backward-word))))))
+
+(defcustom evil-want-C-w-in-emacs-state nil
+  "Whether \"C-w\" prefixes windows commands in Emacs state."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-emacs-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-emacs-state-map (kbd "C-w"))
+                        'evil-window-map))
+               (define-key evil-emacs-state-map (kbd "C-w") nil))
+              ((and value
+                    (not (lookup-key evil-emacs-state-map (kbd "C-w"))))
+               (define-key evil-emacs-state-map (kbd "C-w") 'evil-window-map))))))
+
+(defcustom evil-want-change-word-to-end t
+  "Whether \"cw\" behaves like \"ce\"."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-want-Y-yank-to-eol nil
+  "Whether \"Y\" yanks to the end of the line.
+The default behavior is to yank the whole line."
+  :group 'evil
+  :type 'boolean
+  :initialize #'evil-custom-initialize-pending-reset
+  :set #'(lambda (sym value)
+           (evil-add-command-properties
+            'evil-yank-line
+            :motion (if value 'evil-end-of-line 'evil-line))))
+
+(defcustom evil-disable-insert-state-bindings nil
+  "Whether insert state bindings should be used. Excludes
+bindings for escape, delete and `evil-toggle-key'."
+  :group 'evil
+  :type 'boolean
+  :initialize #'evil-custom-initialize-pending-reset
+  :set #'evil-update-insert-state-bindings)
+
+(defcustom evil-echo-state t
+  "Whether to signal the current state in the echo area."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-complete-all-buffers t
+  "Whether completion looks for matches in all buffers."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-complete-next-func
+  #'(lambda (arg)
+      (require 'dabbrev)
+      (let ((dabbrev-search-these-buffers-only
+             (unless evil-complete-all-buffers
+               (list (current-buffer))))
+            dabbrev-case-distinction)
+        (condition-case nil
+            (if (eq last-command this-command)
+                (dabbrev-expand nil)
+              (dabbrev-expand (- (abs (or arg 1)))))
+          (error (dabbrev-expand nil)))))
+  "Completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-previous-func
+  #'(lambda (arg)
+      (require 'dabbrev)
+      (let ((dabbrev-search-these-buffers-only
+             (unless evil-complete-all-buffers
+               (list (current-buffer))))
+            dabbrev-case-distinction)
+        (dabbrev-expand arg)))
+  "Completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-next-minibuffer-func 'minibuffer-complete
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-previous-minibuffer-func 'minibuffer-complete
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-next-line-func
+  #'(lambda (arg)
+      (let ((hippie-expand-try-functions-list
+             '(try-expand-line
+               try-expand-line-all-buffers)))
+        (hippie-expand arg)))
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next-line]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-previous-line-func
+  evil-complete-next-line-func
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous-line]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-lookup-func #'woman
+  "Lookup function used by \
+\"\\<evil-motion-state-map>\\[evil-lookup]\"."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-toggle-key "C-z"
+  "The key used to change to and from Emacs state.
+Must be readable by `read-kbd-macro'. For example: \"C-z\"."
+  :type 'string
+  :group 'evil
+  :set #'(lambda (sym value)
+           (evil-set-toggle-key value)
+           (set-default sym value)))
+
+(defcustom evil-default-state 'normal
+  "The default state.
+This is the state a mode comes up in when it is not listed
+in `evil-emacs-state-modes', `evil-insert-state-modes' or
+`evil-motion-state-modes'. The value may be one of `normal',
+`insert', `visual', `replace', `operator', `motion' and
+`emacs'."
+  :type  'symbol
+  :group 'evil)
+
+(defcustom evil-buffer-regexps
+  '(("^ \\*load\\*" . nil))
+  "Regular expression determining the initial state for a buffer.
+Entries have the form (REGEXP . STATE), where REGEXP is a regular
+expression matching the buffer's name and STATE is one of `normal',
+`insert', `visual', `replace', `operator', `motion', `emacs' and nil.
+If STATE is nil, Evil is disabled in the buffer."
+  :type '(alist :key-type string :value-type symbol)
+  :group 'evil)
+
+(defcustom evil-emacs-state-modes
+  '(archive-mode
+    bbdb-mode
+    biblio-selection-mode
+    bookmark-bmenu-mode
+    bookmark-edit-annotation-mode
+    browse-kill-ring-mode
+    bzr-annotate-mode
+    calc-mode
+    cfw:calendar-mode
+    completion-list-mode
+    Custom-mode
+    custom-theme-choose-mode
+    debugger-mode
+    delicious-search-mode
+    desktop-menu-blist-mode
+    desktop-menu-mode
+    doc-view-mode
+    dvc-bookmarks-mode
+    dvc-diff-mode
+    dvc-info-buffer-mode
+    dvc-log-buffer-mode
+    dvc-revlist-mode
+    dvc-revlog-mode
+    dvc-status-mode
+    dvc-tips-mode
+    ediff-mode
+    ediff-meta-mode
+    efs-mode
+    Electric-buffer-menu-mode
+    emms-browser-mode
+    emms-mark-mode
+    emms-metaplaylist-mode
+    emms-playlist-mode
+    ess-help-mode
+    etags-select-mode
+    fj-mode
+    gc-issues-mode
+    gdb-breakpoints-mode
+    gdb-disassembly-mode
+    gdb-frames-mode
+    gdb-locals-mode
+    gdb-memory-mode
+    gdb-registers-mode
+    gdb-threads-mode
+    gist-list-mode
+    git-commit-mode
+    git-rebase-mode
+    gnus-article-mode
+    gnus-browse-mode
+    gnus-group-mode
+    gnus-server-mode
+    gnus-summary-mode
+    google-maps-static-mode
+    ibuffer-mode
+    jde-javadoc-checker-report-mode
+    magit-cherry-mode
+    magit-diff-mode
+    magit-log-mode
+    magit-log-select-mode
+    magit-popup-mode
+    magit-popup-sequence-mode
+    magit-process-mode
+    magit-reflog-mode
+    magit-refs-mode
+    magit-revision-mode
+    magit-stash-mode
+    magit-stashes-mode
+    magit-status-mode
+    ;; Obsolete as of Magit v2.1.0
+    magit-mode
+    magit-branch-manager-mode
+    magit-commit-mode
+    magit-key-mode
+    magit-rebase-mode
+    magit-wazzup-mode
+    ;; end obsolete
+    mh-folder-mode
+    monky-mode
+    mu4e-main-mode
+    mu4e-headers-mode
+    mu4e-view-mode
+    notmuch-hello-mode
+    notmuch-search-mode
+    notmuch-show-mode
+    occur-mode
+    org-agenda-mode
+    package-menu-mode
+    pdf-outline-buffer-mode
+    pdf-view-mode
+    proced-mode
+    rcirc-mode
+    rebase-mode
+    recentf-dialog-mode
+    reftex-select-bib-mode
+    reftex-select-label-mode
+    reftex-toc-mode
+    sldb-mode
+    slime-inspector-mode
+    slime-thread-control-mode
+    slime-xref-mode
+    sr-buttons-mode
+    sr-mode
+    sr-tree-mode
+    sr-virtual-mode
+    tar-mode
+    tetris-mode
+    tla-annotate-mode
+    tla-archive-list-mode
+    tla-bconfig-mode
+    tla-bookmarks-mode
+    tla-branch-list-mode
+    tla-browse-mode
+    tla-category-list-mode
+    tla-changelog-mode
+    tla-follow-symlinks-mode
+    tla-inventory-file-mode
+    tla-inventory-mode
+    tla-lint-mode
+    tla-logs-mode
+    tla-revision-list-mode
+    tla-revlog-mode
+    tla-tree-lint-mode
+    tla-version-list-mode
+    twittering-mode
+    urlview-mode
+    vc-annotate-mode
+    vc-dir-mode
+    vc-git-log-view-mode
+    vc-hg-log-view-mode
+    vc-svn-log-view-mode
+    vm-mode
+    vm-summary-mode
+    w3m-mode
+    wab-compilation-mode
+    xgit-annotate-mode
+    xgit-changelog-mode
+    xgit-diff-mode
+    xgit-revlog-mode
+    xhg-annotate-mode
+    xhg-log-mode
+    xhg-mode
+    xhg-mq-mode
+    xhg-mq-sub-mode
+    xhg-status-extra-mode)
+  "Modes that should come up in Emacs state."
+  :type  '(repeat symbol)
+  :group 'evil)
+
+(defcustom evil-insert-state-modes
+  '(comint-mode
+    erc-mode
+    eshell-mode
+    geiser-repl-mode
+    gud-mode
+    inferior-apl-mode
+    inferior-caml-mode
+    inferior-emacs-lisp-mode
+    inferior-j-mode
+    inferior-python-mode
+    inferior-scheme-mode
+    inferior-sml-mode
+    internal-ange-ftp-mode
+    prolog-inferior-mode
+    reb-mode
+    shell-mode
+    slime-repl-mode
+    term-mode
+    wdired-mode)
+  "Modes that should come up in Insert state."
+  :type  '(repeat symbol)
+  :group 'evil)
+
+(defcustom evil-motion-state-modes
+  '(apropos-mode
+    Buffer-menu-mode
+    calendar-mode
+    color-theme-mode
+    command-history-mode
+    compilation-mode
+    dictionary-mode
+    ert-results-mode
+    help-mode
+    Info-mode
+    Man-mode
+    speedbar-mode
+    undo-tree-visualizer-mode
+    woman-mode)
+  "Modes that should come up in Motion state."
+  :type  '(repeat symbol)
+  :group 'evil)
+
+(defvar evil-pending-overriding-maps nil
+  "An alist of pending overriding maps.")
+
+(defvar evil-pending-intercept-maps nil
+  "An alist of pending intercept maps.")
+
+(defcustom evil-overriding-maps
+  '((Buffer-menu-mode-map . nil)
+    (color-theme-mode-map . nil)
+    (comint-mode-map . nil)
+    (compilation-mode-map . nil)
+    (grep-mode-map . nil)
+    (dictionary-mode-map . nil)
+    (ert-results-mode-map . motion)
+    (Info-mode-map . motion)
+    (speedbar-key-map . nil)
+    (speedbar-file-key-map . nil)
+    (speedbar-buffers-key-map . nil))
+  "Keymaps that should override Evil maps.
+Entries have the form (MAP-VAR . STATE), where MAP-VAR is
+a keymap variable and STATE is the state whose bindings
+should be overridden. If STATE is nil, all states are
+overridden."
+  :type '(alist :key-type symbol :value-type symbol)
+  :group 'evil
+  :set #'(lambda (var values)
+           (evil-set-custom-state-maps 'evil-overriding-maps
+                                       'evil-pending-overriding-maps
+                                       'override-state
+                                       'evil-make-overriding-map
+                                       values))
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(add-hook 'after-load-functions #'evil-update-pending-maps)
+
+(defcustom evil-intercept-maps
+  '((edebug-mode-map . nil))
+  "Keymaps that should intercept Evil maps.
+Entries have the form (MAP-VAR . STATE), where MAP-VAR is
+a keymap variable and STATE is the state whose bindings
+should be intercepted. If STATE is nil, all states are
+intercepted."
+  :type '(alist :key-type symbol :value-type symbol)
+  :group 'evil
+  :set #'(lambda (var values)
+           (evil-set-custom-state-maps 'evil-intercept-maps
+                                       'evil-pending-intercept-maps
+                                       'intercept-state
+                                       'evil-make-intercept-map
+                                       values))
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-motions
+  '(back-to-indentation
+    backward-char
+    backward-list
+    backward-paragraph
+    backward-sentence
+    backward-sexp
+    backward-up-list
+    backward-word
+    beginning-of-buffer
+    beginning-of-defun
+    beginning-of-line
+    beginning-of-visual-line
+    c-beginning-of-defun
+    c-end-of-defun
+    diff-file-next
+    diff-file-prev
+    diff-hunk-next
+    diff-hunk-prev
+    down-list
+    end-of-buffer
+    end-of-defun
+    end-of-line
+    end-of-visual-line
+    exchange-point-and-mark
+    forward-char
+    forward-list
+    forward-paragraph
+    forward-sentence
+    forward-sexp
+    forward-word
+    goto-last-change
+    ibuffer-backward-line
+    ibuffer-forward-line
+    isearch-abort
+    isearch-cancel
+    isearch-complete
+    isearch-del-char
+    isearch-delete-char
+    isearch-edit-string
+    isearch-exit
+    isearch-highlight-regexp
+    isearch-occur
+    isearch-other-control-char
+    isearch-other-meta-char
+    isearch-printing-char
+    isearch-query-replace
+    isearch-query-replace-regexp
+    isearch-quote-char
+    isearch-repeat-backward
+    isearch-repeat-forward
+    isearch-ring-advance
+    isearch-ring-retreat
+    isearch-toggle-case-fold
+    isearch-toggle-input-method
+    isearch-toggle-regexp
+    isearch-toggle-specified-input-method
+    isearch-toggle-word
+    isearch-yank-char
+    isearch-yank-kill
+    isearch-yank-line
+    isearch-yank-word-or-char
+    keyboard-quit
+    left-char
+    left-word
+    mouse-drag-region
+    mouse-save-then-kill
+    mouse-set-point
+    mouse-set-region
+    mwheel-scroll
+    move-beginning-of-line
+    move-end-of-line
+    next-error
+    next-line
+    paredit-backward
+    paredit-backward-down
+    paredit-backward-up
+    paredit-forward
+    paredit-forward-down
+    paredit-forward-up
+    pop-global-mark
+    pop-tag-mark
+    pop-to-mark-command
+    previous-error
+    previous-line
+    right-char
+    right-word
+    scroll-down
+    scroll-down-command
+    scroll-up
+    scroll-up-command
+    sgml-skip-tag-backward
+    sgml-skip-tag-forward
+    up-list)
+  "Non-Evil commands to initialize to motions."
+  :type  '(repeat symbol)
+  :group 'evil
+  :set 'evil-set-custom-motions
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-visual-newline-commands
+  '(LaTeX-section
+    TeX-font)
+  "Commands excluding the trailing newline of a Visual Line selection.
+These commands work better without this newline."
+  :type  '(repeat symbol)
+  :group 'evil
+  :set 'evil-set-visual-newline-commands
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-want-visual-char-semi-exclusive nil
+  "Visual character selection to beginning/end of line is exclusive.
+If non nil then an inclusive visual character selection which
+ends at the beginning or end of a line is turned into an
+exclusive selection. Thus if the selected (inclusive) range ends
+at the beginning of a line it is changed to not include the first
+character of that line, and if the selected range ends at the end
+of a line it is changed to not include the newline character of
+that line."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-text-object-change-visual-type t
+  "Text objects change the current visual state type.
+If non-nil then a text-object changes the type of the visual state to
+its default selection type (e.g. a word object always changes to
+charwise visual state). Otherwise the current visual state type is
+preserved."
+  :type 'boolean
+  :group 'evil)
+
+(defgroup evil-cjk nil
+  "CJK support"
+  :prefix "evil-cjk-"
+  :group 'evil)
+
+(defcustom evil-cjk-emacs-word-boundary nil
+  "Determine word boundary exactly the same way as Emacs does."
+  :type 'boolean
+  :group 'evil-cjk)
+
+(defcustom evil-cjk-word-separating-categories
+  '(;; Kanji
+    (?C . ?H) (?C . ?K) (?C . ?k) (?C . ?A) (?C . ?G)
+    ;; Hiragana
+    (?H . ?C) (?H . ?K) (?H . ?k) (?H . ?A) (?H . ?G)
+    ;; Katakana
+    (?K . ?C) (?K . ?H) (?K . ?k) (?K . ?A) (?K . ?G)
+    ;; half-width Katakana
+    (?k . ?C) (?k . ?H) (?k . ?K) ; (?k . ?A) (?k . ?G)
+    ;; full-width alphanumeric
+    (?A . ?C) (?A . ?H) (?A . ?K) ; (?A . ?k) (?A . ?G)
+    ;; full-width Greek
+    (?G . ?C) (?G . ?H) (?G . ?K) ; (?G . ?k) (?G . ?A)
+    )
+  "List of pair (cons) of categories to determine word boundary
+used in `evil-cjk-word-boundary-p'. See the documentation of
+`word-separating-categories'. Use `describe-categories' to see
+the list of categories."
+  :type '((character . character))
+  :group 'evil-cjk)
+
+(defcustom evil-cjk-word-combining-categories
+  '(;; default value in word-combining-categories
+    (nil . ?^) (?^ . nil)
+    ;; Roman
+    (?r . ?k) (?r . ?A) (?r . ?G)
+    ;; half-width Katakana
+    (?k . ?r) (?k . ?A) (?k . ?G)
+    ;; full-width alphanumeric
+    (?A . ?r) (?A . ?k) (?A . ?G)
+    ;; full-width Greek
+    (?G . ?r) (?G . ?k) (?G . ?A)
+    )
+  "List of pair (cons) of categories to determine word boundary
+used in `evil-cjk-word-boundary-p'. See the documentation of
+`word-combining-categories'. Use `describe-categories' to see the
+list of categories."
+  :type '((character . character))
+  :group 'evil-cjk)
+
+(defcustom evil-ex-complete-emacs-commands 'in-turn
+  "TAB-completion for Emacs commands in ex command line.
+This variable determines when Emacs commands are considered for
+completion, always, never, or only if no Evil ex command is
+available for completion."
+  :group 'evil
+  :type '(radio (const :tag "Only if no ex-command." :value in-turn)
+                (const :tag "Never" :value nil)
+                (const :tag "Always" :value t)))
+
+(defface evil-ex-commands '(( nil
+                              :underline t
+                              :slant italic))
+  "Face for the evil command in completion in ex mode."
+  :group 'evil)
+
+(defface evil-ex-info '(( ((supports :slant))
+                          :slant italic
+                          :foreground "red"))
+  "Face for the info message in ex mode."
+  :group 'evil)
+
+(defcustom evil-ex-visual-char-range nil
+  "Type of default ex range in visual char state.
+If non-nil the default range when starting an ex command from
+character visual state is `<,`> otherwise it is '<,'>. In the
+first case the ex command will be passed a region covering only
+the visual selection. In the second case the passed region will
+be extended to contain full lines."
+  :group 'evil
+  :type 'boolean)
+
+;; Searching
+(defcustom evil-symbol-word-search nil
+  "If nil then * and # search for words otherwise for symbols."
+  :group 'evil
+  :type 'boolean)
+(make-variable-buffer-local 'evil-symbol-word-search)
+
+(defcustom evil-magic t
+  "Meaning which characters in a pattern are magic.
+The meaning of those values is the same as in Vim. Note that it
+only has influence if the evil search module is chosen in
+`evil-search-module'."
+  :group 'evil
+  :type '(radio (const :tag "Very magic." :value very-magic)
+                (const :tag "Magic" :value t)
+                (const :tag "Nomagic" :value nil)
+                (const :tag "Very nomagic" :value very-nomagic)))
+
+(defcustom evil-ex-search-vim-style-regexp nil
+  "If non-nil Vim-style backslash codes are supported in search patterns.
+See `evil-transform-vim-style-regexp' for the supported backslash
+codes.  Note that this only affects the search command if
+`evil-search-module' is set to 'evil-search. The isearch module
+always uses plain Emacs regular expressions."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-interactive-search-highlight 'all-windows
+  "Determine in which windows the interactive highlighting should be shown."
+  :type '(radio (const :tag "All windows." all-windows)
+                (const :tag "Selected window." selected-window)
+                (const :tag "Disable highlighting." nil))
+  :group 'evil)
+
+(defcustom evil-ex-search-persistent-highlight t
+  "If non-nil matches remain highlighted when the search ends."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-search-case 'smart
+  "The case behaviour of the search command.
+Smart case means that the pattern is case sensitive if and only
+if it contains an upper case letter, otherwise it is case
+insensitive."
+  :type '(radio (const :tag "Case sensitive." sensitive)
+                (const :tag "Case insensitive." insensitive)
+                (const :tag "Smart case." smart))
+  :group 'evil)
+
+(defcustom evil-ex-substitute-case nil
+  "The case behaviour of the search command.
+Smart case means that the pattern is case sensitive if and only
+if it contains an upper case letter, otherwise it is case
+insensitive. If nil then the setting of `evil-ex-search-case' is
+used."
+  :type '(radio (const :tag "Same as interactive search." nil)
+                (const :tag "Case sensitive." sensitive)
+                (const :tag "Case insensitive." insensitive)
+                (const :tag "Smart case." smart))
+  :group 'evil)
+
+(defcustom evil-ex-search-interactive t
+  "If t search is interactive."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-search-highlight-all t
+  "If t and interactive search is enabled, all matches are
+highlighted."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-substitute-highlight-all t
+  "If t all matches for the substitute pattern are highlighted."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-substitute-interactive-replace t
+  "If t and substitute patterns are highlighted,
+the replacement is shown interactively."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-substitute-global nil
+  "If non-nil substitute patterns are global by default.
+Usually (if this variable is nil) a substitution works only on
+the first match of a pattern in a line unless the 'g' flag is
+given, in which case the substitution happens on all matches in a
+line. If this option is non-nil, this behaviour is reversed: the
+substitution works on all matches unless the 'g' pattern is
+specified, then is works only on the first match."
+  :type  'boolean
+  :group 'evil)
+
+(defface evil-ex-search '((t :inherit isearch))
+  "Face for interactive search."
+  :group 'evil)
+
+(defface evil-ex-lazy-highlight '((t :inherit lazy-highlight))
+  "Face for highlighting all matches in interactive search."
+  :group 'evil)
+
+(defface evil-ex-substitute-matches '((t :inherit lazy-highlight))
+  "Face for interactive substitute matches."
+  :group 'evil)
+
+(defface evil-ex-substitute-replacement '((((supports :underline))
+                                           :underline t
+                                           :foreground "red"))
+  "Face for interactive replacement text."
+  :group 'evil)
+
+(defcustom evil-command-window-height 8
+  "Height (in lines) of the command line window.
+Set to 0 to use the default height for `split-window'."
+  :type 'integer
+  :group 'evil)
+
+(defcustom evil-display-shell-error-in-message nil
+  "Show error output of a shell command in the error buffer.
+If this variable is non-nil the error output of a shell command
+goes to the messages buffer instead of being mixed with the
+regular output. This happens only if the exit status of the
+command is non-zero."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-want-abbrev-expand-on-insert-exit t
+  "If non-nil abbrevs will be expanded when leaving Insert state
+like in Vim. This variable is read only on load."
+  :type 'boolean
+  :group 'evil)
+
+;;; Variables
+
+(defmacro evil-define-local-var (symbol &optional initvalue docstring)
+  "Define SYMBOL as permanent buffer local variable, and return SYMBOL.
+The parameters are the same as for `defvar', but the variable
+SYMBOL is made permanent buffer local."
+  (declare (indent defun)
+           (debug (symbolp &optional form stringp)))
+  `(progn
+     (defvar ,symbol ,initvalue ,docstring)
+     (make-variable-buffer-local ',symbol)
+     (put ',symbol 'permanent-local t)))
+
+(evil-define-local-var evil-scroll-count 0
+  "Holds last used prefix for `evil-scroll-up'
+and `evil-scroll-down'.
+Determines how many lines should be scrolled.
+Default value is 0 - scroll half the screen.")
+
+(evil-define-local-var evil-state nil
+  "The current Evil state.
+To change the state, use `evil-change-state'
+or call the state function (e.g., `evil-normal-state').")
+
+;; these may be used inside `evil-define-state'
+(evil-define-local-var evil-next-state nil
+  "The Evil state being switched to.")
+
+(evil-define-local-var evil-previous-state-alist nil
+  "For Each evil state the Evil state being switched from.")
+
+(evil-define-local-var evil-previous-state nil
+  "The Evil state being switched from.")
+
+(defvar evil-execute-in-emacs-state-buffer nil
+  "The buffer of the latest `evil-execute-in-emacs-state'.
+When this command is being executed the current buffer is stored
+in this variable. This is necessary in case the Emacs-command to
+be called changes the current buffer.")
+
+(evil-define-local-var evil-mode-line-tag nil
+  "Mode-Line indicator for the current state.")
+(put 'evil-mode-line-tag 'risky-local-variable t)
+
+(defvar evil-global-keymaps-alist nil
+  "Association list of keymap variables.
+Entries have the form (MODE . KEYMAP), where KEYMAP
+is the variable containing the keymap for MODE.")
+
+(defvar evil-local-keymaps-alist nil
+  "Association list of keymap variables that must be
+reinitialized in each buffer. Entries have the form
+\(MODE . KEYMAP), where KEYMAP is the variable containing
+the keymap for MODE.")
+
+(defvar evil-minor-mode-keymaps-alist nil
+  "Association list of evil states to minor-mode keymap alists.
+Entries have the form (STATE . MODE-MAP-ALIST), where
+MODE-MAP-ALIST is an alist taking the form of
+`minor-mode-map-alist'.")
+
+(defvar evil-state-properties nil
+  "Specifications made by `evil-define-state'.
+Entries have the form (STATE . PLIST), where PLIST is a property
+list specifying various aspects of the state. To access a property,
+use `evil-state-property'.")
+
+(evil-define-local-var evil-mode-map-alist nil
+  "Association list of keymaps to use for Evil modes.
+Elements have the form (MODE . KEYMAP), with the first keymaps
+having higher priority.")
+
+(defvar evil-command-properties nil
+  "Specifications made by `evil-define-command'.")
+
+(defvar evil-change-commands '(evil-change)
+  "Commands that wrap or replace `evil-change'.
+This list exists to apply an inconsistency with vim's change command
+to commands that wrap or redefine it. See emacs-evil/evil#916.")
+
+(defvar evil-transient-vars '(cua-mode transient-mark-mode select-active-regions)
+  "List of variables pertaining to Transient Mark mode.")
+
+(defvar evil-transient-vals nil
+  "Association list of old values for Transient Mark mode variables.
+Entries have the form (VARIABLE VALUE LOCAL), where LOCAL is
+whether the variable was previously buffer-local.")
+
+(evil-define-local-var evil-no-display nil
+  "If non-nil, various Evil displays are inhibited.
+Use the macro `evil-without-display' to set this variable.")
+
+(defvar evil-type-properties nil
+  "Specifications made by `evil-define-type'.
+Entries have the form (TYPE . PLIST), where PLIST is a property
+list specifying functions for handling the type: expanding it,
+describing it, etc.")
+
+(defvar evil-interactive-alist nil
+  "Association list of Evil-specific interactive codes.")
+
+(evil-define-local-var evil-motion-marker nil
+  "Marker for storing the starting position of a motion.")
+
+(evil-define-local-var evil-this-type nil
+  "Current motion type.")
+
+(evil-define-local-var evil-this-type-modified nil
+  "Non-nil iff current motion type has been modified by the user.
+If the type has been modified, this variable contains the new
+type.")
+
+(evil-define-local-var evil-this-register nil
+  "Current register.")
+
+(evil-define-local-var evil-this-macro nil
+  "Current macro register.")
+
+(evil-define-local-var evil-this-operator nil
+  "Current operator.")
+
+(evil-define-local-var evil-this-motion nil
+  "Current motion.")
+
+(evil-define-local-var evil-this-motion-count nil
+  "Current motion count.")
+
+(defvar evil-last-register nil
+  "The last executed register.")
+
+(defvar evil-inhibit-operator nil
+  "Inhibit current operator.
+If an operator calls a motion and the motion sets this variable
+to t, the operator code is not executed.")
+
+(defvar evil-inhibit-operator-value nil
+  "This variable is used to transfer the value
+of `evil-inhibit-operator' from one local scope to another.")
+
+;; used by `evil-define-operator'
+(defvar evil-operator-range-beginning nil
+  "Beginning of `evil-operator-range'.")
+
+(defvar evil-operator-range-end nil
+  "End of `evil-operator-range'.")
+
+(defvar evil-operator-range-type nil
+  "Type of `evil-operator-range'.")
+
+(defvar evil-operator-range-motion nil
+  "Motion of `evil-operator-range'.")
+
+(defvar evil-restriction-stack nil
+  "List of previous restrictions.
+Using `evil-with-restriction' stores the previous values of
+`point-min' and `point-max' as a pair in this list.")
+
+(evil-define-local-var evil-markers-alist
+  '((?\( . evil-backward-sentence)
+    (?\) . evil-forward-sentence)
+    (?{ . evil-backward-paragraph)
+    (?} . evil-forward-paragraph)
+    (?' . evil-jump-backward-swap)
+    (?` . evil-jump-backward-swap)
+    (?< . evil-visual-beginning)
+    (?> . evil-visual-goto-end)
+    (?. . (lambda ()
+            (let (last-command)
+              (goto-last-change nil)))))
+  "Association list for markers.
+Entries have the form (CHAR . DATA), where CHAR is the marker's
+name and DATA is either a marker object as returned by `make-marker',
+a variable, a movement function, or a cons cell (STRING NUMBER),
+where STRING is a file path and NUMBER is a buffer position.
+The global value of this variable holds markers available from
+every buffer, while the buffer-local value holds markers available
+only in the current buffer.")
+
+(defconst evil-suppress-map (make-keymap)
+  "Full keymap disabling default bindings to `self-insert-command'.")
+(suppress-keymap evil-suppress-map t)
+
+(defvar evil-read-key-map (make-sparse-keymap)
+  "Keymap active during `evil-read-key'.
+This keymap can be used to bind some commands during the
+execution of `evil-read-key' which is usually used to read a
+character argument for some commands, e.g. `evil-replace'.")
+
+;; TODO: customize size of ring
+(defvar evil-repeat-ring (make-ring 10)
+  "A ring of repeat-informations to repeat the last command.")
+
+(defvar evil-repeat-types
+  '((t . evil-repeat-keystrokes)
+    (change . evil-repeat-changes)
+    (motion . evil-repeat-motion)
+    (insert-at-point . evil-repeat-insert-at-point)
+    (ignore . nil))
+  "An alist of defined repeat-types.")
+
+(defvar evil-recording-repeat nil
+  "Whether we are recording a repeat.")
+
+(defvar evil-recording-current-command nil
+  "Whether we are recording the current command for repeat.")
+
+(defvar evil-repeat-changes nil
+  "Accumulated buffer changes for changed-based commands.")
+
+(defvar evil-repeat-info nil
+  "Information accumulated during current repeat.")
+
+(defvar evil-repeat-buffer nil
+  "The buffer in which the repeat started.
+If the buffer is changed, the repeat is cancelled.")
+
+(defvar evil-repeat-pos nil
+  "The position of point at the beginning of an change-tracking
+  editing command.")
+
+(defvar evil-repeat-keys nil
+  "The keys that invoked the current command.")
+
+(defvar evil-last-repeat nil
+  "Information about the latest repeat command.
+This is a list of three elements (POINT COUNT UNDO-POINTER),
+where POINT is the position of point before the latest repeat,
+COUNT the count-argument of the latest repeat command and
+UNDO-POINTER the head of the undo-list before the last command
+has been repeated.")
+
+(defvar evil-repeat-count nil
+  "The explicit count when repeating a command.")
+
+(defvar evil-maybe-remove-spaces nil
+  "Flag to determine if newly inserted spaces should be removed.
+See the function `evil-maybe-remove-spaces'.")
+
+(evil-define-local-var evil-insert-count nil
+  "The explicit count passed to an command starting Insert state.")
+
+(evil-define-local-var evil-insert-vcount nil
+  "The information about the number of following lines the
+insertion should be repeated. This is list (LINE COLUMN COUNT)
+where LINE is the line-number where the original insertion
+started and COLUMN is either a number or function determining the
+column where the repeated insertions should take place. COUNT is
+number of repeats (including the original insertion).")
+
+(defvar evil-insert-skip-empty-lines nil
+  "Non-nil of the current insertion should not take place on
+  lines at which the insertion point is behind the end of the
+  line.")
+
+(evil-define-local-var evil-insert-lines nil
+  "Non-nil if the current insertion command is a line-insertion
+command o or O.")
+
+(evil-define-local-var evil-insert-repeat-info nil
+  "Repeat information accumulated during an insertion.")
+
+(evil-define-local-var evil-replace-alist nil
+  "Association list of characters overwritten in Replace state.
+The format is (POS . CHAR).")
+
+(evil-define-local-var evil-echo-area-message nil
+  "Previous value of `current-message'.")
+
+(defvar evil-write-echo-area nil
+  "If set to t inside `evil-save-echo-area', then the echo area
+is not restored.")
+
+(defvar evil-last-find nil
+  "A pair (FUNCTION . CHAR) describing the lastest character
+  search command.")
+
+(defvar evil-last-paste nil
+  "Information about the latest paste.
+This should be a list (CMD COUNT POINT BEG END FIRSTVISUAL) where
+CMD is the last paste-command (`evil-paste-before',
+`evil-paste-after' or `evil-visual-paste'), COUNT is the repeat
+count of the paste, POINT is the position of point before the
+paste, BEG end END are the region of the inserted
+text. FIRSTVISUAL is t if and only if the previous command was
+the first visual paste (i.e. before any paste-pop).")
+
+(evil-define-local-var evil-last-undo-entry nil
+  "Information about the latest undo entry in the buffer.
+This should be a pair (OBJ . CONS) where OBJ is the entry as an
+object, and CONS is a copy of the entry.")
+
+(evil-define-local-var evil-current-insertion nil
+  "Information about the latest insertion in insert state.
+This should be a pair (BEG . END) that describes the
+buffer-region of the newly inserted text.")
+
+(defvar evil-last-insertion nil
+  "The last piece of inserted text.")
+
+(defvar evil-last-small-deletion nil
+  "The last piece of deleted text.
+The text should be less than a line.")
+
+(defvar evil-was-yanked-without-register t
+  "Whether text being saved to the numbered-register ring was
+not deleted and not yanked to a specific register.")
+
+(defvar evil-paste-count nil
+  "The count argument of the current paste command.")
+
+(defvar evil-temporary-undo nil
+  "When undo is disabled in current buffer.
+Certain commands depending on undo use this variable
+instead of `buffer-undo-list'.")
+
+(evil-define-local-var evil-undo-list-pointer nil
+  "Everything up to this mark is united in the undo-list.")
+
+(defvar evil-in-single-undo nil
+  "Set to non-nil if the current undo steps are connected.")
+
+(defvar evil-flash-timer nil
+  "Timer for flashing search results.")
+
+(defvar evil-search-prompt nil
+  "String to use for search prompt.")
+
+(defvar evil-search-forward-history nil
+  "History of forward searches.")
+
+(defvar evil-search-backward-history nil
+  "History of backward searches.")
+
+(defvar evil-inner-text-objects-map (make-sparse-keymap)
+  "Keymap for inner text objects.")
+
+(defvar evil-outer-text-objects-map (make-sparse-keymap)
+  "Keymap for outer text objects.")
+
+(defvar evil-window-map (make-sparse-keymap)
+  "Keymap for window-related commands.")
+
+(evil-define-local-var evil-input-method nil
+  "Input method used in Insert state and Emacs state.")
+
+;;; Visual state
+
+(evil-define-local-var evil-visual-beginning nil
+  "The beginning of the Visual selection, a marker.")
+
+(evil-define-local-var evil-visual-end nil
+  "The end of the Visual selection, a marker.")
+
+(evil-define-local-var evil-visual-point nil
+  "The position of point in Visual state, a marker.")
+
+(evil-define-local-var evil-visual-mark nil
+  "The position of mark in Visual state, a marker.")
+
+(evil-define-local-var evil-visual-previous-mark nil
+  "The position of mark before Visual state, a marker.")
+
+(evil-define-local-var evil-visual-selection nil
+  "The kind of Visual selection.
+This is a selection as defined by `evil-define-visual-selection'.")
+
+;; we could infer the direction by comparing `evil-visual-mark'
+;; and `evil-visual-point', but destructive operations may
+;; displace the markers
+(evil-define-local-var evil-visual-direction 0
+  "Whether point follows mark in Visual state.
+Negative if point precedes mark, otherwise positive.
+See also the function `evil-visual-direction'.")
+
+(evil-define-local-var evil-visual-properties nil
+  "Property list of miscellaneous Visual properties.")
+
+(evil-define-local-var evil-visual-region-expanded nil
+  "Whether the region matches the Visual selection.
+That is, whether the positions of point and mark have been
+expanded to coincide with the selection's boundaries.
+This makes the selection available to functions acting
+on Emacs' region.")
+
+(evil-define-local-var evil-visual-overlay nil
+  "Overlay for highlighting the Visual selection.
+Not used for blockwise selections, in which case
+see `evil-visual-block-overlays'.")
+
+(evil-define-local-var evil-visual-block-overlays nil
+  "Overlays for Visual Block selection, one for each line.
+They are reused to minimize flicker.")
+
+(defvar evil-visual-alist nil
+  "Association list of Visual selection functions.
+Elements have the form (NAME . FUNCTION).")
+
+(evil-define-local-var evil-visual-x-select-timer nil
+  "Timer for updating the X selection in visual state.")
+
+(defvar evil-visual-x-select-timeout 0.1
+  "Time in seconds for the update of the X selection.")
+
+(declare-function origami-open-all-nodes "origami.el")
+(declare-function origami-close-all-nodes "origami.el")
+(declare-function origami-toggle-node "origami.el")
+(declare-function origami-open-node "origami.el")
+(declare-function origami-open-node-recursively "origami.el")
+(declare-function origami-close-node "origami.el")
+
+(defvar evil-fold-list
+  `(((hs-minor-mode)
+     :open-all   hs-show-all
+     :close-all  hs-hide-all
+     :toggle     hs-toggle-hiding
+     :open       hs-show-block
+     :open-rec   nil
+     :close      hs-hide-block)
+    ((hide-ifdef-mode)
+     :open-all   show-ifdefs
+     :close-all  hide-ifdefs
+     :toggle     nil
+     :open       show-ifdef-block
+     :open-rec   nil
+     :close      hide-ifdef-block)
+    ((outline-mode
+      outline-minor-mode
+      org-mode
+      markdown-mode)
+     :open-all   show-all
+     :close-all  ,(lambda ()
+                    (with-no-warnings (hide-sublevels 1)))
+     :toggle     outline-toggle-children
+     :open       ,(lambda ()
+                    (with-no-warnings
+                      (show-entry)
+                      (show-children)))
+     :open-rec   show-subtree
+     :close      hide-subtree)
+    ((origami-mode)
+     :open-all   ,(lambda () (origami-open-all-nodes (current-buffer)))
+     :close-all  ,(lambda () (origami-close-all-nodes (current-buffer)))
+     :toggle     ,(lambda () (origami-toggle-node (current-buffer) (point)))
+     :open       ,(lambda () (origami-open-node (current-buffer) (point)))
+     :open-rec   ,(lambda () (origami-open-node-recursively (current-buffer) (point)))
+     :close      ,(lambda () (origami-close-node (current-buffer) (point)))))
+  "Actions to be performed for various folding operations.
+
+The value should be a list of fold handlers, were a fold handler has
+the format:
+
+  ((MODES) PROPERTIES)
+
+MODES acts as a predicate, containing the symbols of all major or
+minor modes for which the handler should match.  For example:
+
+  '((outline-minor-mode org-mode) ...)
+
+would match for either outline-minor-mode or org-mode, even though the
+former is a minor mode and the latter is a major.
+
+PROPERTIES specifies possible folding actions and the functions to be
+applied in the event of a match on one (or more) of the MODES; the
+supported properties are:
+
+  - `:open-all'
+    Open all folds.
+  - `:close-all'
+    Close all folds.
+  - `:toggle'
+    Toggle the display of the fold at point.
+  - `:open'
+    Open the fold at point.
+  - `:open-rec'
+    Open the fold at point recursively.
+  - `:close'
+    Close the fold at point.
+
+Each value must be a function.  A value of `nil' will cause the action
+to be ignored for that respective handler.  For example:
+
+  `((org-mode)
+     :close-all  nil
+     :open       ,(lambda ()
+                    (show-entry)
+                    (show-children))
+     :close      hide-subtree)
+
+would ignore `:close-all' actions and invoke the provided functions on
+`:open' or `:close'.")
+
+;;; Ex
+
+(defvar evil-ex-map (make-sparse-keymap)
+  "Keymap for Ex.
+Key sequences bound in this map are immediately executed.")
+
+(defvar evil-ex-completion-map (make-sparse-keymap)
+  "Completion keymap for Ex.")
+
+(defvar evil-ex-initial-input nil
+  "Additional initial content of the ex command line.
+This content of this variable is appended to the ex command line
+if ex is started interactively.")
+
+(defvar evil-ex-shell-argument-initialized nil
+  "This variable is set to t if shell command completion has been initialized.
+See `evil-ex-init-shell-argument-completion'.")
+
+(defvar evil-ex-commands nil
+  "Association list of command bindings and functions.")
+
+(defvar evil-ex-history nil
+  "History of Ex commands.")
+
+(defvar evil-ex-current-buffer nil
+  "The buffer from which Ex was started.")
+
+(defvar evil-ex-expression nil
+  "The evaluation tree.")
+
+(defvar evil-ex-tree nil
+  "The syntax tree.")
+
+(defvar evil-ex-command nil
+  "The current Ex command.")
+
+(defvar evil-ex-previous-command nil
+  "The previously executed Ex command.")
+
+(defvar evil-ex-cmd nil
+  "The current Ex command string.")
+
+(defvar evil-ex-point nil
+  "The position of `point' when the ex command has been called.")
+
+(defvar evil-ex-range nil
+  "The current range of the Ex command.")
+
+(defvar evil-ex-bang nil
+  "The \"!\" argument of the current Ex command.")
+
+(defvar evil-ex-argument nil
+  "The current argument of the Ex command.")
+
+(defvar evil-ex-argument-handler nil
+  "The argument handler for the current Ex command.")
+
+(defvar evil-ex-argument-types nil
+  "Association list of argument handlers.")
+
+(defvar evil-previous-shell-command nil
+  "The last shell command.")
+
+;; Searching
+(defvar evil-ex-search-history nil
+  "The history for the search command.")
+
+(defvar evil-ex-search-direction nil
+  "The direction of the current search, either 'forward or 'backward.")
+
+(defvar evil-ex-search-count nil
+  "The count if the current search.")
+
+(defvar evil-ex-search-start-point nil
+  "The point where the search started.")
+
+(defvar evil-ex-search-overlay nil
+  "The overlay for the current search result.")
+
+(defvar evil-ex-search-pattern nil
+  "The last search pattern.")
+
+(defvar evil-ex-search-offset nil
+  "The last search offset.")
+
+(defvar evil-ex-search-match-beg nil
+  "The beginning position of the last match.")
+
+(defvar evil-ex-search-match-end nil
+  "The end position of the last match.")
+
+(defvar evil-ex-substitute-pattern nil
+  "The last substitute pattern.")
+
+(defvar evil-ex-substitute-replacement nil
+  "The last substitute replacement.")
+
+(defvar evil-ex-substitute-flags nil
+  "The last substitute flags.")
+
+(defvar evil-ex-substitute-current-replacement nil
+  "The actual replacement.")
+
+(defvar evil-ex-last-was-search nil
+  "Non-nil if the previous was a search.
+Otherwise the previous command is assumed as substitute.")
+
+;;; Command line window
+
+(defvar evil-command-window-current-buffer nil
+  "The buffer from which the command line window was called.")
+
+(evil-define-local-var evil-command-window-execute-fn nil
+  "The command to execute when exiting the command line window.")
+
+(evil-define-local-var evil-command-window-cmd-key nil
+  "The key for the command that opened the command line window (:, /, or ?).")
+
+;; The lazy-highlighting framework.
+(evil-define-local-var evil-ex-active-highlights-alist nil
+  "An alist of currently active highlights.")
+
+(evil-define-local-var evil-ex-hl-update-timer nil
+  "Time used for updating highlights.")
+
+(defvar evil-ex-search-keymap (make-sparse-keymap)
+  "Keymap used in ex-search-mode.")
+(set-keymap-parent evil-ex-search-keymap minibuffer-local-map)
+
+(defconst evil-version
+  (eval-when-compile
+    (with-temp-buffer
+      (let ((dir (file-name-directory (or load-file-name
+                                          byte-compile-current-file))))
+        ;; git repository
+        (if (and (file-exists-p (concat dir "/.git"))
+                 (ignore-errors
+                   (zerop (call-process "git" nil '(t nil) nil
+                                        "rev-parse"
+                                        "--short" "HEAD"))))
+            (progn
+              (goto-char (point-min))
+              (concat "evil-git-"
+                      (buffer-substring (point-min)
+                                        (line-end-position))))
+          ;; no repo, use plain version
+          "1.2.12"))))
+  "The current version of Evil")
+
+(defun evil-version ()
+  (interactive)
+  (message "Evil version %s" evil-version))
+
+(provide 'evil-vars)
+
+;;; evil-vars.el ends here
.emacs.d/elpa/evil-20170904.1346/evil-vars.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil.el
@@ -0,0 +1,146 @@
+;;; evil.el --- extensible vi layer
+
+;; The following list of authors was kept up to date until the beginning of
+;; 2017, when evil moved under new maintainers. For authors since then, please
+;; consult the git logs.
+
+;;      Alessandro Piras <laynor at gmail.com>
+;;      Alexander Baier <alexander.baier at mailbox.org>
+;;      Antono Vasiljev <antono.vasiljev at gmail.com>
+;;      Bailey Ling <bling at live.ca>
+;;      Barry O'Reilly <gundaetiapo at gmail.com>
+;;      Christoph Lange <langec at web.de>
+;;      Daniel Reiter <danieltreiter at gmail.com>
+;;      Eivind Fonn <evfonn at gmail.com>
+;;      Emanuel Evans <emanuel.evans at gmail.com>
+;;      Eric Siegel <siegel.eric at gmail.com>
+;;      Eugene Yaremenko <w3techplayground at gmail.com>
+;;      Frank Fischer <frank-fischer at shadow-soft.de>
+;;      Frank Terbeck <ft at bewatermyfriend.org>
+;;      Gordon Gustafson <gordon3.14 at gmail.com>
+;;      Herbert Jones <jones.herbert at gmail.com>
+;;      Jonas Bernoulli <jonas at bernoul.li>
+;;      Jonathan Claggett <jclaggett at lonocloud.com>
+;;      Josรฉ A. Romero L. <escherdragon at gmail.com>
+;;      Justin Burkett <justin at burkett.cc>
+;;      Lars Andersen <expez at expez.com>
+;;      Lintaro Ina <tarao.gnn at gmail.com>
+;;      Lukasz Wrzosek <wrzoski at mail.com>
+;;      Marian Schubert <maio at netsafe.cz>
+;;      Matthew Malcomson <>
+;;      Michael Markert <markert.michael at googlemail.com>
+;;      Mike Gerwitz <mikegerwitz at gnu.org>
+;;      Nikolai Weibull <now at bitwi.se>
+;;      phaebz <phaebz at gmail.com>
+;;      ralesi <scio62 at gmail.com>
+;;      Rodrigo Setti <rodrigosetti at gmail.com>
+;;      Sanel Zukan <sanelz at gmail.com>
+;;      Sarah Brofeldt <sarah at thinkmonster.(none)>
+;;      Simon Hafner <hafnersimon at gmail.com>
+;;      Stefan Wehr <mail at stefanwehr.de>
+;;      Sune Simonsen <sune.simonsen at jayway.com>
+;;      Thomas Hisch <thomas at opentech.at>
+;;      Tim Harper <timcharper at gmail.com>
+;;      Tom Willemse <tom at ryuslash.org>
+;;      Trevor Murphy <trevor.m.murphy at gmail.com>
+;;      Ulrich Mรผller <ulm at gentoo.org>
+;;      Vasilij Schneidermann <v.schneidermann at gmail.com>
+;;      Vegard ร˜ye <vegard_oye at hotmail.com>
+;;      Winfred Lu <winfred.lu at gmail.com>
+;;      Wolfgang Jenkner <wjenkner at inode.at>
+;;      Xiao Hanyu <xiaohanyu1988 at gmail.com>
+;;      York Zhao <yzhao at telecor.com>
+
+;; Maintainers: The emacs-evil team. <https://github.com/orgs/emacs-evil/people>
+;;      To get in touch, please use the bug tracker or the
+;;      mailing list (see below).
+;; Created: 2011-03-01
+;; Version: 1.2.12
+;; Keywords: emulation, vim
+;; URL: https://github.com/emacs-evil/evil
+;;      Repository: https://github.com/emacs-evil/evil.git
+;;      EmacsWiki: http://www.emacswiki.org/emacs/Evil
+;; Bug tracker: https://github.com/emacs-evil/evil/issues
+;;      If you have bug reports, suggestions or patches, please
+;;      create an issue at the bug tracker (open for everyone).
+;;      Other discussions (tips, extensions) go to the mailing list.
+;; Mailing list: <implementations-list at lists.ourproject.org>
+;;      Subscribe: http://tinyurl.com/implementations-list
+;;      Newsgroup: nntp://news.gmane.org/gmane.emacs.vim-emulation
+;;      Archives: http://dir.gmane.org/gmane.emacs.vim-emulation
+;;      You don't have to subscribe to post; we usually reply
+;;      within a few days and CC our replies back to you.
+;;
+;; 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/>.
+
+;;; Commentary:
+
+;; Evil is an extensible vi layer for Emacs. It emulates the main
+;; features of Vim, and provides facilities for writing custom
+;; extensions.
+;;
+;; Evil lives in a Git repository. To obtain Evil, do
+;;
+;;      git clone git://github.com/emacs-evil/evil.git
+;;
+;; Move Evil to ~/.emacs.d/evil (or somewhere else in the `load-path').
+;; Then add the following lines to ~/.emacs:
+;;
+;;      (add-to-list 'load-path "~/.emacs.d/evil")
+;;      (require 'evil)
+;;      (evil-mode 1)
+;;
+;; Evil requires undo-tree.el for linear undo and undo branches:
+;;
+;;      http://www.emacswiki.org/emacs/UndoTree
+;;
+;; Otherwise, Evil uses regular Emacs undo.
+;;
+;; Evil requires `goto-last-change' and `goto-last-change-reverse'
+;; function for the corresponding motions g; g, as well as the
+;; last-change-register `.'. One package providing these functions is
+;; goto-chg.el:
+;;
+;;     http://www.emacswiki.org/emacs/GotoChg
+;;
+;; Without this package the corresponding motions will raise an error.
+
+;;; Code:
+
+(require 'evil-vars)
+(require 'evil-common)
+(require 'evil-core)
+(require 'evil-states)
+(require 'evil-repeat)
+(require 'evil-macros)
+(require 'evil-search)
+(require 'evil-ex)
+(require 'evil-digraphs)
+(require 'evil-types)
+(require 'evil-commands)
+(require 'evil-jumps)
+(require 'evil-maps)
+(require 'evil-integration)
+
+(run-hooks 'evil-after-load-hook)
+
+(provide 'evil)
+
+;;; evil.el ends here
.emacs.d/elpa/evil-20170904.1346/evil.elc
Binary file
.emacs.d/elpa/evil-20170904.1346/evil.info
@@ -0,0 +1,1215 @@
+This is evil.info, produced by makeinfo version 5.2 from evil.texi.
+
+This manual is for Evil (version 0.1 of 2011-07-30), an extensible vi
+layer for Emacs.
+
+   Copyright ๏ฟฝ 2011 Frank Fischer and Vegard ๏ฟฝye.
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU Free Documentation License,
+     Version 1.3 or any later version published by the Free Software
+     Foundation; with no Invariant Sections, no Front-Cover Texts, and
+     no Back-Cover Texts.  A copy of the license is included in the
+     section entitled "GNU Free Documentation License".
+
+   The Evil team thanks everyone at gmane.emacs.vim-emulation for their
+feedback and contributions.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Evil: (evil). Extensible vi layer for Emacs.
+END-INFO-DIR-ENTRY
+
+
+File: evil.info,  Node: Top,  Next: Overview,  Prev: (dir),  Up: (dir)
+
+Evil
+****
+
+This is the manual for Evil, an extensible vi layer for Emacs.
+
+* Menu:
+
+* Overview::
+* Settings::
+* Keymaps::
+* Hooks::
+* Macros::
+* Other internals::
+* GNU Free Documentation License::
+
+
+File: evil.info,  Node: Overview,  Next: Settings,  Up: Top
+
+1 Overview
+**********
+
+Evil is an extensible vi layer for Emacs.  It emulates the main features
+of Vim,(1) turning Emacs into a modal editor.  Like Emacs in general,
+Evil is extensible in Emacs Lisp.
+
+* Menu:
+
+* Installation::
+* Modes and states::
+
+   ---------- Footnotes ----------
+
+   (1) Vim is the most popular version of "vi", a modal text editor with
+many implementations.  Vim also adds some functions of its own, like
+Visual selection and text objects.  For more information, see:
+<http://www.vim.org/>
+
+
+File: evil.info,  Node: Installation,  Next: Modes and states,  Up: Overview
+
+1.1 Installation
+================
+
+Evil lives in a Git repository.  To download Evil, do:
+
+     git clone https://github.com/emacs-evil/evil.git
+
+Move Evil to '~/.emacs.d/evil'.  Then add the following lines to
+'~/.emacs':
+
+     (add-to-list 'load-path "~/.emacs.d/evil")
+     (require 'evil)
+     (evil-mode 1)
+
+Evil requires 'undo-tree.el' to provide linear undo and undo branches.
+It is available from EmacsWiki.(1)  (A copy of 'undo-tree.el' is also
+included in the Git repository.)
+
+   ---------- Footnotes ----------
+
+   (1) <http://www.emacswiki.org/emacs/UndoTree>
+
+
+File: evil.info,  Node: Modes and states,  Prev: Installation,  Up: Overview
+
+1.2 Modes and states
+====================
+
+The next time Emacs is started, it will come up in "Normal state",
+denoted by '<N>' on the mode line.  This is where the main vi bindings
+are defined.  Note that you can always disable Normal state with 'C-z',
+which switches to an "Emacs state" (denoted by '<E>') in which vi keys
+are completely disabled.  Press 'C-z' again to switch back to Normal
+state.
+
+   Evil uses the term "state" for what is called a "mode" in vi, since
+"mode" already has its own meaning in Emacs.  Evil defines a number of
+states, such as Normal state ('<N>'), Insert state ('<I>'), Visual state
+('<V>'), Replace state ('<R>'), Operator-Pending state ('<O>'), Motion
+state ('<M>') and Emacs state ('<E>').  Each state has its own keymaps
+and customization variables.
+
+   Meanwhile, a "mode" in Emacs is a set of key bindings for editing a
+certain sort of text, like 'emacs-lisp-mode' for Emacs Lisp.  Modes may
+include custom bindings for Evil states.
+
+
+File: evil.info,  Node: Settings,  Next: Keymaps,  Prev: Overview,  Up: Top
+
+2 Settings
+**********
+
+Evil's behavior can be adjusted by setting various variables.  The
+current values may be inspected by doing 'M-x customize-group RET evil
+RET'.
+
+   To change the value of a variable, add a 'setq' form to '~/.emacs',
+preferably before Evil is loaded:(1)
+
+     (setq evil-shift-width 8)
+     ;; Load Evil
+     (require 'evil) ...
+
+Note that if a variable is buffer-local, you must use 'setq-default'
+instead of 'setq' to change its global value.
+
+ -- Variable: evil-auto-indent
+     Whether the current line is indented when entering Insert state.
+     If 't' (the default), then the line is indented.  If 'nil', then
+     the line is not indented.  Buffer-local.
+
+ -- Variable: evil-shift-width
+     The number of columns a line is shifted by the commands '>' and
+     '<'.
+
+ -- Variable: evil-repeat-move-cursor
+     If 't' (the default), then repeating a command with '.' may change
+     the position of the cursor.  If 'nil', then the original position
+     is preserved.
+
+ -- Variable: evil-find-skip-newlines
+     If 't', then 'f', 'F', 't' and 'T' may skip over newlines to find a
+     character.  If 'nil' (the default), then they are restricted to the
+     current line.
+
+ -- Variable: evil-move-cursor-back
+     If 't' (the default), then the cursor moves backwards when exiting
+     Insert state.  If 'nil', then the cursor does not move.
+
+ -- Variable: evil-want-fine-undo
+     If 't', then a change-based action like 'cw' may be undone in
+     several steps.  If 'nil' (the default), then it is undone in one
+     step.
+
+ -- Variable: evil-regexp-search
+     If 't' (the default), then '/' and '?' use regular expressions for
+     searching.  If 'nil', they use plain text.
+
+ -- Variable: evil-search-wrap
+     If 't' (the default), then '/' and '?' wrap the search around the
+     buffer.  If 'nil', then they stop at buffer boundaries.
+
+ -- Variable: evil-flash-delay
+     The number of seconds to flash search matches when pressing 'n' and
+     'N'.
+
+ -- Variable: evil-want-C-i-jump
+     If 't' (the default), then 'C-i' jumps forwards in the jump list.
+     If 'nil', then 'C-i' inserts a tab.
+
+ -- Variable: evil-want-C-u-scroll
+     If 't', then 'C-u' scrolls the buffer.  If 'nil' (the default),
+     then 'C-u' begins a numeric prefix argument.
+
+* Menu:
+
+* The cursor::
+* The initial state::
+
+   ---------- Footnotes ----------
+
+   (1) Strictly speaking, the order only matters if the variable affects
+the way Evil is loaded.  This is the case with some of the 'evil-want-'
+variables.
+
+
+File: evil.info,  Node: The cursor,  Next: The initial state,  Up: Settings
+
+2.1 The cursor
+==============
+
+A state may change the cursor's appearance.  The cursor settings are
+stored in the variables below, which may contain a cursor type as per
+the 'cursor-type' variable, a color string as passed to the
+'set-cursor-color' function, a zero-argument function for changing the
+cursor, or a list of the above.  For example, the following changes the
+cursor in Replace state to a red box:
+
+     (setq evil-replace-state-cursor '("red" box))
+
+If the state does not specify a cursor, 'evil-default-cursor' is used.
+
+ -- Variable: evil-default-cursor
+     The default cursor.
+
+ -- Variable: evil-normal-state-cursor
+     The cursor for Normal state.
+
+ -- Variable: evil-insert-state-cursor
+     The cursor for Insert state.
+
+ -- Variable: evil-visual-state-cursor
+     The cursor for Visual state.
+
+ -- Variable: evil-replace-state-cursor
+     The cursor for Replace state.
+
+ -- Variable: evil-operator-state-cursor
+     The cursor for Operator-Pending state.
+
+ -- Variable: evil-motion-state-cursor
+     The cursor for Motion state.
+
+ -- Variable: evil-emacs-state-cursor
+     The cursor for Emacs state.
+
+
+File: evil.info,  Node: The initial state,  Prev: The cursor,  Up: Settings
+
+2.2 The initial state
+=====================
+
+By default, a new buffer comes up in Normal state.  This can be changed
+with the function 'evil-set-initial-state'.
+
+ -- Function: evil-set-initial-state mode state
+     Set the initial state for a buffer in which MODE is active to
+     STATE.  MODE should be a major mode such as 'text-mode', although
+     minor modes work as well.
+
+
+File: evil.info,  Node: Keymaps,  Next: Hooks,  Prev: Settings,  Up: Top
+
+3 Keymaps
+*********
+
+Evil's key bindings are stored in a number of keymaps.  Each state has a
+"global keymap", where the default key bindings for the state are
+stored.  For example, the global keymap for Normal state is
+'evil-normal-state-map', and the key bindings in this map are seen in
+all buffers that are currently in Normal state.
+
+   Keymaps are modified with the Emacs function 'define-key':
+
+     (define-key evil-normal-state-map "w" 'foo)
+
+This binds the key 'w' to the command 'foo' in Normal state.  The file
+'evil-maps.el' contains all the key bindings.
+
+ -- Variable: evil-normal-state-map
+     The global keymap for Normal state.
+
+ -- Variable: evil-insert-state-map
+     The global keymap for Insert state.
+
+ -- Variable: evil-visual-state-map
+     The global keymap for Visual state.
+
+ -- Variable: evil-replace-state-map
+     The global keymap for Replace state.
+
+ -- Variable: evil-operator-state-map
+     The global keymap for Operator-Pending state.
+
+ -- Variable: evil-motion-state-map
+     The global keymap for Motion state.
+
+Each state also has a "buffer-local keymap", which is specific to the
+current buffer and has precedence over the global keymap.  These maps
+may be changed from a mode hook.
+
+ -- Variable: evil-normal-state-local-map
+     Buffer-local keymap for Normal state.
+
+ -- Variable: evil-insert-state-local-map
+     Buffer-local keymap for Insert state.
+
+ -- Variable: evil-visual-state-local-map
+     Buffer-local keymap for Visual state.
+
+ -- Variable: evil-replace-state-local-map
+     Buffer-local keymap for Replace state.
+
+ -- Variable: evil-operator-state-local-map
+     Buffer-local keymap for Operator-Pending state.
+
+ -- Variable: evil-motion-state-local-map
+     Buffer-local keymap for Motion state.
+
+* Menu:
+
+* 'evil-define-key'::
+
+
+File: evil.info,  Node: 'evil-define-key',  Up: Keymaps
+
+3.1 'evil-define-key'
+=====================
+
+Finally, Evil provides the function 'evil-define-key' for adding state
+bindings to a regular keymap.
+
+ -- Function: evil-define-key state keymap key def
+     In KEYMAP, create a binding from KEY to DEF in STATE.  STATE is one
+     of 'normal', 'insert', 'visual', 'replace', 'operator' and
+     'motion'.  The other parameters are like those of 'define-key'.
+
+'evil-define-key' can be used to augment existing modes with state
+bindings, as well as create packages for custom bindings.  For example,
+the following will create a minor mode 'foo-mode' with Normal state
+bindings for the keys 'w' and 'e':
+
+     (define-minor-mode foo-mode
+       "Foo mode."
+       :keymap (make-sparse-keymap))
+
+     (evil-define-key 'normal foo-mode-map "w" 'bar)
+     (evil-define-key 'normal foo-mode-map "e" 'baz)
+
+This minor mode can then be enabled in any buffers where the custom
+bindings are desired:
+
+     (add-hook 'text-mode-hook 'foo-mode) ; enable alongside 'text-mode'
+
+If the minor mode is put into its own file 'foo.el' with a '(provide
+'foo)' statement, it becomes an Emacs package.
+
+
+File: evil.info,  Node: Hooks,  Next: Macros,  Prev: Keymaps,  Up: Top
+
+4 Hooks
+*******
+
+A "hook" is a list of functions to execute.  Hooks are modified with the
+Emacs function 'add-hook'.  Evil provides entry and exit hooks for all
+of its states.
+
+ -- Variable: evil-normal-state-entry-hook
+     Run when entering Normal state.
+
+ -- Variable: evil-normal-state-exit-hook
+     Run when exiting Normal state.
+
+ -- Variable: evil-insert-state-entry-hook
+     Run when entering Insert state.
+
+ -- Variable: evil-insert-state-exit-hook
+     Run when exiting Insert state.
+
+ -- Variable: evil-visual-state-entry-hook
+     Run when entering Visual state.
+
+ -- Variable: evil-visual-state-exit-hook
+     Run when exiting Visual state.
+
+ -- Variable: evil-replace-state-entry-hook
+     Run when entering Replace state.
+
+ -- Variable: evil-replace-state-exit-hook
+     Run when exiting Replace state.
+
+ -- Variable: evil-operator-state-entry-hook
+     Run when entering Operator-Pending state.
+
+ -- Variable: evil-operator-state-exit-hook
+     Run when exiting Operator-Pending state.
+
+ -- Variable: evil-motion-state-entry-hook
+     Run when entering Motion state.
+
+ -- Variable: evil-motion-state-exit-hook
+     Run when exiting Motion state.
+
+When these hooks are run, the variables 'evil-next-state' and
+'evil-previous-state' hold information about the states being switched
+to and from.
+
+ -- Variable: evil-next-state
+     The state being switched to.
+
+ -- Variable: evil-previous-state
+     The state being switched from.
+
+
+File: evil.info,  Node: Macros,  Next: Other internals,  Prev: Hooks,  Up: Top
+
+5 Macros
+********
+
+Evil is implemented in terms of reusable macros.  Package writers can
+use these to define new commands.
+
+* Menu:
+
+* Motions::
+* Operators::
+* Text objects::
+* Types::
+* States::
+
+
+File: evil.info,  Node: Motions,  Next: Operators,  Up: Macros
+
+5.1 Motions
+===========
+
+A "motion" is a command which moves the cursor, such as 'w' and 'e'.
+Motions are defined with the macro 'evil-define-motion'.  Motions not
+defined in this way should be declared with 'evil-declare-motion'.
+
+ -- Function: evil-declare-motion command
+     Declare COMMAND to be a motion.  This ensures that it works
+     properly in Visual state.
+
+ -- Macro: evil-define-motion motion (count args...) doc keyword-args...
+          body...
+     Define a movement command MOTION.  A motion can have any number of
+     arguments, but the first argument, if any, has a predefined meaning
+     as the COUNT.  It is a positive or negative number, or 'nil'.  The
+     argument list is followed by the documentation string DOC, which is
+     followed by optional keyword arguments:
+
+     ':type TYPE'
+          The TYPE determines how the motion works after an operator.
+          If TYPE is 'inclusive', then the ending position is included
+          in the motion range.  If TYPE is 'line', then the range is
+          expanded to linewise positions.  If TYPE is 'block', then the
+          range is blockwise.  The default is 'exclusive', which means
+          that the range is used as-is.
+
+     ':jump JUMP'
+          If JUMP is 't', then the previous position is stored in the
+          jump list so it can be restored with 'C-o'.  The default is
+          'nil'.
+
+     The keyword arguments are followed by the BODY, which is where the
+     motion's behavior is defined.  For instance:
+
+          (evil-define-motion foo-forward (count)
+            "Move to the right by COUNT characters."
+            :type inclusive
+            (forward-char (or count 1)))
+
+     For more examples, you can view the source code for any command
+     with 'C-h k'.  For instance, 'evil-goto-line' may be viewed by
+     typing 'C-h k G' and following the file link.
+
+
+File: evil.info,  Node: Operators,  Next: Text objects,  Prev: Motions,  Up: Macros
+
+5.2 Operators
+=============
+
+An "operator" is a command which acts on the text moved over by a
+motion, such as 'c', 'd' and 'y'.  Operators are defined with the macro
+'evil-define-operator'.
+
+ -- Macro: evil-define-operator operator (beg end type args...) doc
+          keyword-args... body...
+     Define an operator command OPERATOR.  An operator must have at
+     least two or three arguments, which have predefined meanings.  BEG
+     is the beginning position, END is the ending position, and TYPE, if
+     given, is the type of the motion range.  The argument list is
+     followed by the documentation string DOC, which is followed by
+     optional keyword arguments:
+
+     ':type TYPE'
+          Make the input range be a certain TYPE.  For example, an
+          operator which only works with whole lines may set TYPE to
+          'line'.
+
+     ':motion MOTION'
+          Use the motion MOTION instead of reading one from the
+          keyboard.  This does not affect the behavior in Visual state,
+          where the selection boundaries are used instead.
+
+     ':repeat REPEAT'
+          If REPEAT is 't' (the default), then '.' will repeat the
+          operator.  If REPEAT is 'nil', then the operator will not be
+          repeated.
+
+     ':move-point MOVE-POINT'
+          If MOVE-POINT is 't' (the default), then the cursor is
+          positioned at the beginning of the range.  If MOVE-POINT is
+          'nil', then the original position is preserved.
+
+     ':keep-visual KEEP-VISUAL'
+          If KEEP-VISUAL is 't', then the selection is not disabled when
+          the operator is run in Visual state; it is up to the operator
+          to do this.  The default is 'nil', which means that Visual
+          state is exited automatically.
+
+     The keyword arguments are followed by the BODY, which is where the
+     operator's actions on BEG and END are defined.  For example,
+     'evil-rot13', which is bound to 'g?' and performs ROT13 encryption
+     on the text, may be defined as:
+
+          (evil-define-operator evil-rot13 (beg end)
+            "ROT13 encrypt text."
+            (rot13-region beg end))
+
+     Pressing 'g?w' will encrypt a word by calling 'rot13-region' on the
+     text moved over by the 'w' motion.
+
+
+File: evil.info,  Node: Text objects,  Next: Types,  Prev: Operators,  Up: Macros
+
+5.3 Text objects
+================
+
+A "text object" is a special kind of motion which sets a beginning
+position as well as an ending position, such as 'iw' and 'a('.  In
+Visual state, text objects alter both ends of the selection.  Text
+objects are defined with the macro 'evil-define-text-object'.
+
+ -- Macro: evil-define-text-object object (count args...) doc
+          keyword-args... body...
+     Define a text object OBJECT.  The first argument has a predefined
+     meaning as the COUNT: it is a positive or negative number.  The
+     argument list is followed by the documentation string DOC, which is
+     followed by optional keyword arguments:
+
+     ':type TYPE'
+          Use the type TYPE after an operator.  In Visual state, this is
+          the type of the selection.
+
+     ':extend-selection EXTEND-SELECTION'
+          If EXTEND-SELECTION is 't' (the default), then the text object
+          always enlarges the current selection.  If 'nil', then the
+          object replaces the selection.
+
+     The keyword arguments are followed by the BODY, which should
+     evaluate to a list '(BEG END)' of two positions in the buffer.  For
+     example, a text object which selects three characters following the
+     current position could be defined as:
+
+          (evil-define-text-object foo (count)
+            "Select three characters."
+            (list (point) (+ (point) 3)))
+
+Evil provides several functions which return a list of positions, for
+use in the definition of a text object.  These functions follow the rule
+that a positive COUNT selects text after the current position, while a
+negative COUNT selects text before it.
+
+ -- Function: evil-inner-object-range count forward backward
+     Return a text range '(BEG END)' of COUNT "inner" text objects
+     (e.g., 'iw', 'is').  FORWARD is a function which moves to the end
+     of an object, and BACKWARD is a function which moves to the
+     beginning.
+
+ -- Function: evil-an-object-range count forward backward
+     Return a text range '(BEG END)' of COUNT text objects with
+     whitespace (e.g., 'aw', 'as').  FORWARD is a function which moves
+     to the end of an object, and BACKWARD is a function which moves to
+     the beginning.
+
+ -- Function: evil-paren-range count open close &optional exclusive
+     Return a text range '(BEG END)' of COUNT delimited blocks (e.g.,
+     'i(', 'a(').  OPEN and CLOSE are characters.  If EXCLUSIVE is
+     non-nil, then the delimiters are excluded from the range.  This
+     function uses Emacs' syntax table and is only applicable for
+     single-character delimiters; use 'evil-regexp-range' to match
+     multiple characters.
+
+ -- Function: evil-regexp-range count open close &optional exclusive
+     Return a text range '(BEG END)' of COUNT delimited blocks (e.g.,
+     'it', 'at').  OPEN and CLOSE are regular expressions.  If EXCLUSIVE
+     is non-nil, then the delimiters are excluded from the range.
+
+
+File: evil.info,  Node: Types,  Next: States,  Prev: Text objects,  Up: Macros
+
+5.4 Types
+=========
+
+A "type" is a transformation on a pair of buffer positions.  Evil
+defines the types 'exclusive', 'inclusive', 'line' and 'block', which
+are used for motion ranges and Visual selection.  Types are defined with
+the macro 'evil-define-type'.
+
+ -- Macro: evil-define-type type doc keyword-args...
+     Define a type TYPE, described by the documentation string DOC.
+     Then follows keyword arguments:
+
+     ':expand EXPAND'
+          A function which takes two buffer positions and returns a list
+          '(BEG END)' of expanded positions.
+
+     ':contract CONTRACT'
+          A function which takes two expanded buffer positions and
+          returns a list '(BEG END)' of unexpanded positions.  Optional.
+
+     ':normalize NORMALIZE'
+          A function which takes two unexpanded buffer positions and
+          returns a list '(BEG END)' of adjusted positions.  Optional.
+
+     ':injective INJECTIVE'
+          If 't' (the default), then expansion is one-to-one - i.e.,
+          EXPAND followed by CONTRACT always returns the original
+          positions.  If 'nil', then several positions may expand to the
+          same (for example, the 'line' type is one-to-many as it
+          expands to the containing lines).
+
+     Further keywords and functions may be specified.  These are
+     understood to be transformations on buffer positions, like EXPAND
+     and CONTRACT.
+
+
+File: evil.info,  Node: States,  Prev: Types,  Up: Macros
+
+5.5 States
+==========
+
+States are defined with the macro 'evil-define-state'.  The macro
+defines the necessary hooks, keymaps and variables for a state, as well
+as a toggle function 'evil-STATE-state' for entering the state, and a
+predicate function 'evil-STATE-state-p' which returns 't' when the state
+is active, and 'nil' otherwise.
+
+ -- Macro: evil-define-state state doc keyword-args... body...
+     Define an Evil state STATE, described by the documentation string
+     DOC.  Then follows optional keyword arguments:
+
+     ':tag TAG'
+          Mode line indicitor, e.g., '"<T>"'.
+     ':message MESSAGE'
+          String shown in the echo area.
+     ':cursor CURSOR'
+          Cursor specification.
+     ':enable ENABLE'
+          List of other modes and states to enable.  A state may enable
+          another state's keymaps in addition to its own.
+
+     This is followed the BODY, which is executed whenever the state is
+     enabled or disabled.  The state's predicate function may be used to
+     distinguish between the two.
+
+
+File: evil.info,  Node: Other internals,  Next: GNU Free Documentation License,  Prev: Macros,  Up: Top
+
+6 Other internals
+*****************
+
+* Menu:
+
+* Command properties::
+
+
+File: evil.info,  Node: Command properties,  Up: Other internals
+
+6.1 Command properties
+======================
+
+Evil defines "command properties" to store information about commands,
+such as whether they should be repeated.  A command property is a
+':KEYWORD' with an associated value, e.g., ':repeat nil'.
+
+ -- Function: evil-add-command-properties command &rest properties
+     Add PROPERTIES to COMMAND.  The properties should be specified as a
+     list of keywords and values:
+
+          (evil-add-command-properties 'my-command :repeat t)
+
+ -- Function: evil-set-command-properties command &rest properties
+     Like 'evil-add-command-properties', but resets all previous
+     properties.
+
+ -- Function: evil-get-command-property command property
+     Return the value of a command property.
+
+ -- Macro: evil-define-command command (args...) doc keyword-args...
+          body...
+     Define a command with command properties KEYWORD-ARGS.
+
+For setting repeat properties, Evil provides the following functions:
+
+ -- Function: evil-declare-repeat command
+     Declare COMMAND to be repeatable.
+
+ -- Function: evil-declare-not-repeat command
+     Declare COMMAND to be nonrepeatable.
+
+ -- Function: evil-declare-change-repeat command
+     Declare COMMAND to be repeatable by buffer changes rather than
+     keystrokes.
+
+
+File: evil.info,  Node: GNU Free Documentation License,  Prev: Other internals,  Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+                     Version 1.3, 3 November 2008
+
+     Copyright ๏ฟฝ 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+     <http://fsf.org/>
+
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+
+  0. PREAMBLE
+
+     The purpose of this License is to make a manual, textbook, or other
+     functional and useful document "free" in the sense of freedom: to
+     assure everyone the effective freedom to copy and redistribute it,
+     with or without modifying it, either commercially or
+     noncommercially.  Secondarily, this License preserves for the
+     author and publisher a way to get credit for their work, while not
+     being considered responsible for modifications made by others.
+
+     This License is a kind of "copyleft", which means that derivative
+     works of the document must themselves be free in the same sense.
+     It complements the GNU General Public License, which is a copyleft
+     license designed for free software.
+
+     We have designed this License in order to use it for manuals for
+     free software, because free software needs free documentation: a
+     free program should come with manuals providing the same freedoms
+     that the software does.  But this License is not limited to
+     software manuals; it can be used for any textual work, regardless
+     of subject matter or whether it is published as a printed book.  We
+     recommend this License principally for works whose purpose is
+     instruction or reference.
+
+  1. APPLICABILITY AND DEFINITIONS
+
+     This License applies to any manual or other work, in any medium,
+     that contains a notice placed by the copyright holder saying it can
+     be distributed under the terms of this License.  Such a notice
+     grants a world-wide, royalty-free license, unlimited in duration,
+     to use that work under the conditions stated herein.  The
+     "Document", below, refers to any such manual or work.  Any member
+     of the public is a licensee, and is addressed as "you".  You accept
+     the license if you copy, modify or distribute the work in a way
+     requiring permission under copyright law.
+
+     A "Modified Version" of the Document means any work containing the
+     Document or a portion of it, either copied verbatim, or with
+     modifications and/or translated into another language.
+
+     A "Secondary Section" is a named appendix or a front-matter section
+     of the Document that deals exclusively with the relationship of the
+     publishers or authors of the Document to the Document's overall
+     subject (or to related matters) and contains nothing that could
+     fall directly within that overall subject.  (Thus, if the Document
+     is in part a textbook of mathematics, a Secondary Section may not
+     explain any mathematics.)  The relationship could be a matter of
+     historical connection with the subject or with related matters, or
+     of legal, commercial, philosophical, ethical or political position
+     regarding them.
+
+     The "Invariant Sections" are certain Secondary Sections whose
+     titles are designated, as being those of Invariant Sections, in the
+     notice that says that the Document is released under this License.
+     If a section does not fit the above definition of Secondary then it
+     is not allowed to be designated as Invariant.  The Document may
+     contain zero Invariant Sections.  If the Document does not identify
+     any Invariant Sections then there are none.
+
+     The "Cover Texts" are certain short passages of text that are
+     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+     that says that the Document is released under this License.  A
+     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+     be at most 25 words.
+
+     A "Transparent" copy of the Document means a machine-readable copy,
+     represented in a format whose specification is available to the
+     general public, that is suitable for revising the document
+     straightforwardly with generic text editors or (for images composed
+     of pixels) generic paint programs or (for drawings) some widely
+     available drawing editor, and that is suitable for input to text
+     formatters or for automatic translation to a variety of formats
+     suitable for input to text formatters.  A copy made in an otherwise
+     Transparent file format whose markup, or absence of markup, has
+     been arranged to thwart or discourage subsequent modification by
+     readers is not Transparent.  An image format is not Transparent if
+     used for any substantial amount of text.  A copy that is not
+     "Transparent" is called "Opaque".
+
+     Examples of suitable formats for Transparent copies include plain
+     ASCII without markup, Texinfo input format, LaTeX input format,
+     SGML or XML using a publicly available DTD, and standard-conforming
+     simple HTML, PostScript or PDF designed for human modification.
+     Examples of transparent image formats include PNG, XCF and JPG.
+     Opaque formats include proprietary formats that can be read and
+     edited only by proprietary word processors, SGML or XML for which
+     the DTD and/or processing tools are not generally available, and
+     the machine-generated HTML, PostScript or PDF produced by some word
+     processors for output purposes only.
+
+     The "Title Page" means, for a printed book, the title page itself,
+     plus such following pages as are needed to hold, legibly, the
+     material this License requires to appear in the title page.  For
+     works in formats which do not have any title page as such, "Title
+     Page" means the text near the most prominent appearance of the
+     work's title, preceding the beginning of the body of the text.
+
+     The "publisher" means any person or entity that distributes copies
+     of the Document to the public.
+
+     A section "Entitled XYZ" means a named subunit of the Document
+     whose title either is precisely XYZ or contains XYZ in parentheses
+     following text that translates XYZ in another language.  (Here XYZ
+     stands for a specific section name mentioned below, such as
+     "Acknowledgements", "Dedications", "Endorsements", or "History".)
+     To "Preserve the Title" of such a section when you modify the
+     Document means that it remains a section "Entitled XYZ" according
+     to this definition.
+
+     The Document may include Warranty Disclaimers next to the notice
+     which states that this License applies to the Document.  These
+     Warranty Disclaimers are considered to be included by reference in
+     this License, but only as regards disclaiming warranties: any other
+     implication that these Warranty Disclaimers may have is void and
+     has no effect on the meaning of this License.
+
+  2. VERBATIM COPYING
+
+     You may copy and distribute the Document in any medium, either
+     commercially or noncommercially, provided that this License, the
+     copyright notices, and the license notice saying this License
+     applies to the Document are reproduced in all copies, and that you
+     add no other conditions whatsoever to those of this License.  You
+     may not use technical measures to obstruct or control the reading
+     or further copying of the copies you make or distribute.  However,
+     you may accept compensation in exchange for copies.  If you
+     distribute a large enough number of copies you must also follow the
+     conditions in section 3.
+
+     You may also lend copies, under the same conditions stated above,
+     and you may publicly display copies.
+
+  3. COPYING IN QUANTITY
+
+     If you publish printed copies (or copies in media that commonly
+     have printed covers) of the Document, numbering more than 100, and
+     the Document's license notice requires Cover Texts, you must
+     enclose the copies in covers that carry, clearly and legibly, all
+     these Cover Texts: Front-Cover Texts on the front cover, and
+     Back-Cover Texts on the back cover.  Both covers must also clearly
+     and legibly identify you as the publisher of these copies.  The
+     front cover must present the full title with all words of the title
+     equally prominent and visible.  You may add other material on the
+     covers in addition.  Copying with changes limited to the covers, as
+     long as they preserve the title of the Document and satisfy these
+     conditions, can be treated as verbatim copying in other respects.
+
+     If the required texts for either cover are too voluminous to fit
+     legibly, you should put the first ones listed (as many as fit
+     reasonably) on the actual cover, and continue the rest onto
+     adjacent pages.
+
+     If you publish or distribute Opaque copies of the Document
+     numbering more than 100, you must either include a machine-readable
+     Transparent copy along with each Opaque copy, or state in or with
+     each Opaque copy a computer-network location from which the general
+     network-using public has access to download using public-standard
+     network protocols a complete Transparent copy of the Document, free
+     of added material.  If you use the latter option, you must take
+     reasonably prudent steps, when you begin distribution of Opaque
+     copies in quantity, to ensure that this Transparent copy will
+     remain thus accessible at the stated location until at least one
+     year after the last time you distribute an Opaque copy (directly or
+     through your agents or retailers) of that edition to the public.
+
+     It is requested, but not required, that you contact the authors of
+     the Document well before redistributing any large number of copies,
+     to give them a chance to provide you with an updated version of the
+     Document.
+
+  4. MODIFICATIONS
+
+     You may copy and distribute a Modified Version of the Document
+     under the conditions of sections 2 and 3 above, provided that you
+     release the Modified Version under precisely this License, with the
+     Modified Version filling the role of the Document, thus licensing
+     distribution and modification of the Modified Version to whoever
+     possesses a copy of it.  In addition, you must do these things in
+     the Modified Version:
+
+       A. Use in the Title Page (and on the covers, if any) a title
+          distinct from that of the Document, and from those of previous
+          versions (which should, if there were any, be listed in the
+          History section of the Document).  You may use the same title
+          as a previous version if the original publisher of that
+          version gives permission.
+
+       B. List on the Title Page, as authors, one or more persons or
+          entities responsible for authorship of the modifications in
+          the Modified Version, together with at least five of the
+          principal authors of the Document (all of its principal
+          authors, if it has fewer than five), unless they release you
+          from this requirement.
+
+       C. State on the Title page the name of the publisher of the
+          Modified Version, as the publisher.
+
+       D. Preserve all the copyright notices of the Document.
+
+       E. Add an appropriate copyright notice for your modifications
+          adjacent to the other copyright notices.
+
+       F. Include, immediately after the copyright notices, a license
+          notice giving the public permission to use the Modified
+          Version under the terms of this License, in the form shown in
+          the Addendum below.
+
+       G. Preserve in that license notice the full lists of Invariant
+          Sections and required Cover Texts given in the Document's
+          license notice.
+
+       H. Include an unaltered copy of this License.
+
+       I. Preserve the section Entitled "History", Preserve its Title,
+          and add to it an item stating at least the title, year, new
+          authors, and publisher of the Modified Version as given on the
+          Title Page.  If there is no section Entitled "History" in the
+          Document, create one stating the title, year, authors, and
+          publisher of the Document as given on its Title Page, then add
+          an item describing the Modified Version as stated in the
+          previous sentence.
+
+       J. Preserve the network location, if any, given in the Document
+          for public access to a Transparent copy of the Document, and
+          likewise the network locations given in the Document for
+          previous versions it was based on.  These may be placed in the
+          "History" section.  You may omit a network location for a work
+          that was published at least four years before the Document
+          itself, or if the original publisher of the version it refers
+          to gives permission.
+
+       K. For any section Entitled "Acknowledgements" or "Dedications",
+          Preserve the Title of the section, and preserve in the section
+          all the substance and tone of each of the contributor
+          acknowledgements and/or dedications given therein.
+
+       L. Preserve all the Invariant Sections of the Document, unaltered
+          in their text and in their titles.  Section numbers or the
+          equivalent are not considered part of the section titles.
+
+       M. Delete any section Entitled "Endorsements".  Such a section
+          may not be included in the Modified Version.
+
+       N. Do not retitle any existing section to be Entitled
+          "Endorsements" or to conflict in title with any Invariant
+          Section.
+
+       O. Preserve any Warranty Disclaimers.
+
+     If the Modified Version includes new front-matter sections or
+     appendices that qualify as Secondary Sections and contain no
+     material copied from the Document, you may at your option designate
+     some or all of these sections as invariant.  To do this, add their
+     titles to the list of Invariant Sections in the Modified Version's
+     license notice.  These titles must be distinct from any other
+     section titles.
+
+     You may add a section Entitled "Endorsements", provided it contains
+     nothing but endorsements of your Modified Version by various
+     parties--for example, statements of peer review or that the text
+     has been approved by an organization as the authoritative
+     definition of a standard.
+
+     You may add a passage of up to five words as a Front-Cover Text,
+     and a passage of up to 25 words as a Back-Cover Text, to the end of
+     the list of Cover Texts in the Modified Version.  Only one passage
+     of Front-Cover Text and one of Back-Cover Text may be added by (or
+     through arrangements made by) any one entity.  If the Document
+     already includes a cover text for the same cover, previously added
+     by you or by arrangement made by the same entity you are acting on
+     behalf of, you may not add another; but you may replace the old
+     one, on explicit permission from the previous publisher that added
+     the old one.
+
+     The author(s) and publisher(s) of the Document do not by this
+     License give permission to use their names for publicity for or to
+     assert or imply endorsement of any Modified Version.
+
+  5. COMBINING DOCUMENTS
+
+     You may combine the Document with other documents released under
+     this License, under the terms defined in section 4 above for
+     modified versions, provided that you include in the combination all
+     of the Invariant Sections of all of the original documents,
+     unmodified, and list them all as Invariant Sections of your
+     combined work in its license notice, and that you preserve all
+     their Warranty Disclaimers.
+
+     The combined work need only contain one copy of this License, and
+     multiple identical Invariant Sections may be replaced with a single
+     copy.  If there are multiple Invariant Sections with the same name
+     but different contents, make the title of each such section unique
+     by adding at the end of it, in parentheses, the name of the
+     original author or publisher of that section if known, or else a
+     unique number.  Make the same adjustment to the section titles in
+     the list of Invariant Sections in the license notice of the
+     combined work.
+
+     In the combination, you must combine any sections Entitled
+     "History" in the various original documents, forming one section
+     Entitled "History"; likewise combine any sections Entitled
+     "Acknowledgements", and any sections Entitled "Dedications".  You
+     must delete all sections Entitled "Endorsements."
+
+  6. COLLECTIONS OF DOCUMENTS
+
+     You may make a collection consisting of the Document and other
+     documents released under this License, and replace the individual
+     copies of this License in the various documents with a single copy
+     that is included in the collection, provided that you follow the
+     rules of this License for verbatim copying of each of the documents
+     in all other respects.
+
+     You may extract a single document from such a collection, and
+     distribute it individually under this License, provided you insert
+     a copy of this License into the extracted document, and follow this
+     License in all other respects regarding verbatim copying of that
+     document.
+
+  7. AGGREGATION WITH INDEPENDENT WORKS
+
+     A compilation of the Document or its derivatives with other
+     separate and independent documents or works, in or on a volume of a
+     storage or distribution medium, is called an "aggregate" if the
+     copyright resulting from the compilation is not used to limit the
+     legal rights of the compilation's users beyond what the individual
+     works permit.  When the Document is included in an aggregate, this
+     License does not apply to the other works in the aggregate which
+     are not themselves derivative works of the Document.
+
+     If the Cover Text requirement of section 3 is applicable to these
+     copies of the Document, then if the Document is less than one half
+     of the entire aggregate, the Document's Cover Texts may be placed
+     on covers that bracket the Document within the aggregate, or the
+     electronic equivalent of covers if the Document is in electronic
+     form.  Otherwise they must appear on printed covers that bracket
+     the whole aggregate.
+
+  8. TRANSLATION
+
+     Translation is considered a kind of modification, so you may
+     distribute translations of the Document under the terms of section
+     4.  Replacing Invariant Sections with translations requires special
+     permission from their copyright holders, but you may include
+     translations of some or all Invariant Sections in addition to the
+     original versions of these Invariant Sections.  You may include a
+     translation of this License, and all the license notices in the
+     Document, and any Warranty Disclaimers, provided that you also
+     include the original English version of this License and the
+     original versions of those notices and disclaimers.  In case of a
+     disagreement between the translation and the original version of
+     this License or a notice or disclaimer, the original version will
+     prevail.
+
+     If a section in the Document is Entitled "Acknowledgements",
+     "Dedications", or "History", the requirement (section 4) to
+     Preserve its Title (section 1) will typically require changing the
+     actual title.
+
+  9. TERMINATION
+
+     You may not copy, modify, sublicense, or distribute the Document
+     except as expressly provided under this License.  Any attempt
+     otherwise to copy, modify, sublicense, or distribute it is void,
+     and will automatically terminate your rights under this License.
+
+     However, if you cease all violation of this License, then your
+     license from a particular copyright holder is reinstated (a)
+     provisionally, unless and until the copyright holder explicitly and
+     finally terminates your license, and (b) permanently, if the
+     copyright holder fails to notify you of the violation by some
+     reasonable means prior to 60 days after the cessation.
+
+     Moreover, your license from a particular copyright holder is
+     reinstated permanently if the copyright holder notifies you of the
+     violation by some reasonable means, this is the first time you have
+     received notice of violation of this License (for any work) from
+     that copyright holder, and you cure the violation prior to 30 days
+     after your receipt of the notice.
+
+     Termination of your rights under this section does not terminate
+     the licenses of parties who have received copies or rights from you
+     under this License.  If your rights have been terminated and not
+     permanently reinstated, receipt of a copy of some or all of the
+     same material does not give you any rights to use it.
+
+  10. FUTURE REVISIONS OF THIS LICENSE
+
+     The Free Software Foundation may publish new, revised versions of
+     the GNU Free Documentation License from time to time.  Such new
+     versions will be similar in spirit to the present version, but may
+     differ in detail to address new problems or concerns.  See
+     <http://www.gnu.org/copyleft/>.
+
+     Each version of the License is given a distinguishing version
+     number.  If the Document specifies that a particular numbered
+     version of this License "or any later version" applies to it, you
+     have the option of following the terms and conditions either of
+     that specified version or of any later version that has been
+     published (not as a draft) by the Free Software Foundation.  If the
+     Document does not specify a version number of this License, you may
+     choose any version ever published (not as a draft) by the Free
+     Software Foundation.  If the Document specifies that a proxy can
+     decide which future versions of this License can be used, that
+     proxy's public statement of acceptance of a version permanently
+     authorizes you to choose that version for the Document.
+
+  11. RELICENSING
+
+     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+     World Wide Web server that publishes copyrightable works and also
+     provides prominent facilities for anybody to edit those works.  A
+     public wiki that anybody can edit is an example of such a server.
+     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+     site means any set of copyrightable works thus published on the MMC
+     site.
+
+     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+     license published by Creative Commons Corporation, a not-for-profit
+     corporation with a principal place of business in San Francisco,
+     California, as well as future copyleft versions of that license
+     published by that same organization.
+
+     "Incorporate" means to publish or republish a Document, in whole or
+     in part, as part of another Document.
+
+     An MMC is "eligible for relicensing" if it is licensed under this
+     License, and if all works that were first published under this
+     License somewhere other than this MMC, and subsequently
+     incorporated in whole or in part into the MMC, (1) had no cover
+     texts or invariant sections, and (2) were thus incorporated prior
+     to November 1, 2008.
+
+     The operator of an MMC Site may republish an MMC contained in the
+     site under CC-BY-SA on the same site at any time before August 1,
+     2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+       Copyright (C)  YEAR  YOUR NAME.
+       Permission is granted to copy, distribute and/or modify this document
+       under the terms of the GNU Free Documentation License, Version 1.3
+       or any later version published by the Free Software Foundation;
+       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+       Texts.  A copy of the license is included in the section entitled ``GNU
+       Free Documentation License''.
+
+   If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts."  line with this:
+
+         with the Invariant Sections being LIST THEIR TITLES, with
+         the Front-Cover Texts being LIST, and with the Back-Cover Texts
+         being LIST.
+
+   If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+   If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+
+Tag Table:
+Node: Top819
+Node: Overview1092
+Ref: Overview-Footnote-11440
+Node: Installation1668
+Ref: Installation-Footnote-12272
+Node: Modes and states2322
+Node: Settings3375
+Ref: Settings-Footnote-15826
+Node: The cursor5983
+Node: The initial state7188
+Node: Keymaps7647
+Node: 'evil-define-key'9511
+Node: Hooks10697
+Node: Macros12219
+Node: Motions12499
+Node: Operators14436
+Node: Text objects16769
+Node: Types19782
+Node: States21264
+Node: Other internals22363
+Node: Command properties22540
+Node: GNU Free Documentation License23867
+
+End Tag Table
+
+
+Local Variables:
+coding: iso-8859-1
+End:
.emacs.d/elpa/evil-20170904.1346/fdl-1.3.info
@@ -0,0 +1,484 @@
+This is fdl-1.3.info, produced by makeinfo version 5.2 from
+fdl-1.3.texi.
+
+                     Version 1.3, 3 November 2008
+
+     Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+     <http://fsf.org/>
+
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+
+  0. PREAMBLE
+
+     The purpose of this License is to make a manual, textbook, or other
+     functional and useful document "free" in the sense of freedom: to
+     assure everyone the effective freedom to copy and redistribute it,
+     with or without modifying it, either commercially or
+     noncommercially.  Secondarily, this License preserves for the
+     author and publisher a way to get credit for their work, while not
+     being considered responsible for modifications made by others.
+
+     This License is a kind of "copyleft", which means that derivative
+     works of the document must themselves be free in the same sense.
+     It complements the GNU General Public License, which is a copyleft
+     license designed for free software.
+
+     We have designed this License in order to use it for manuals for
+     free software, because free software needs free documentation: a
+     free program should come with manuals providing the same freedoms
+     that the software does.  But this License is not limited to
+     software manuals; it can be used for any textual work, regardless
+     of subject matter or whether it is published as a printed book.  We
+     recommend this License principally for works whose purpose is
+     instruction or reference.
+
+  1. APPLICABILITY AND DEFINITIONS
+
+     This License applies to any manual or other work, in any medium,
+     that contains a notice placed by the copyright holder saying it can
+     be distributed under the terms of this License.  Such a notice
+     grants a world-wide, royalty-free license, unlimited in duration,
+     to use that work under the conditions stated herein.  The
+     "Document", below, refers to any such manual or work.  Any member
+     of the public is a licensee, and is addressed as "you".  You accept
+     the license if you copy, modify or distribute the work in a way
+     requiring permission under copyright law.
+
+     A "Modified Version" of the Document means any work containing the
+     Document or a portion of it, either copied verbatim, or with
+     modifications and/or translated into another language.
+
+     A "Secondary Section" is a named appendix or a front-matter section
+     of the Document that deals exclusively with the relationship of the
+     publishers or authors of the Document to the Document's overall
+     subject (or to related matters) and contains nothing that could
+     fall directly within that overall subject.  (Thus, if the Document
+     is in part a textbook of mathematics, a Secondary Section may not
+     explain any mathematics.)  The relationship could be a matter of
+     historical connection with the subject or with related matters, or
+     of legal, commercial, philosophical, ethical or political position
+     regarding them.
+
+     The "Invariant Sections" are certain Secondary Sections whose
+     titles are designated, as being those of Invariant Sections, in the
+     notice that says that the Document is released under this License.
+     If a section does not fit the above definition of Secondary then it
+     is not allowed to be designated as Invariant.  The Document may
+     contain zero Invariant Sections.  If the Document does not identify
+     any Invariant Sections then there are none.
+
+     The "Cover Texts" are certain short passages of text that are
+     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+     that says that the Document is released under this License.  A
+     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+     be at most 25 words.
+
+     A "Transparent" copy of the Document means a machine-readable copy,
+     represented in a format whose specification is available to the
+     general public, that is suitable for revising the document
+     straightforwardly with generic text editors or (for images composed
+     of pixels) generic paint programs or (for drawings) some widely
+     available drawing editor, and that is suitable for input to text
+     formatters or for automatic translation to a variety of formats
+     suitable for input to text formatters.  A copy made in an otherwise
+     Transparent file format whose markup, or absence of markup, has
+     been arranged to thwart or discourage subsequent modification by
+     readers is not Transparent.  An image format is not Transparent if
+     used for any substantial amount of text.  A copy that is not
+     "Transparent" is called "Opaque".
+
+     Examples of suitable formats for Transparent copies include plain
+     ASCII without markup, Texinfo input format, LaTeX input format,
+     SGML or XML using a publicly available DTD, and standard-conforming
+     simple HTML, PostScript or PDF designed for human modification.
+     Examples of transparent image formats include PNG, XCF and JPG.
+     Opaque formats include proprietary formats that can be read and
+     edited only by proprietary word processors, SGML or XML for which
+     the DTD and/or processing tools are not generally available, and
+     the machine-generated HTML, PostScript or PDF produced by some word
+     processors for output purposes only.
+
+     The "Title Page" means, for a printed book, the title page itself,
+     plus such following pages as are needed to hold, legibly, the
+     material this License requires to appear in the title page.  For
+     works in formats which do not have any title page as such, "Title
+     Page" means the text near the most prominent appearance of the
+     work's title, preceding the beginning of the body of the text.
+
+     The "publisher" means any person or entity that distributes copies
+     of the Document to the public.
+
+     A section "Entitled XYZ" means a named subunit of the Document
+     whose title either is precisely XYZ or contains XYZ in parentheses
+     following text that translates XYZ in another language.  (Here XYZ
+     stands for a specific section name mentioned below, such as
+     "Acknowledgements", "Dedications", "Endorsements", or "History".)
+     To "Preserve the Title" of such a section when you modify the
+     Document means that it remains a section "Entitled XYZ" according
+     to this definition.
+
+     The Document may include Warranty Disclaimers next to the notice
+     which states that this License applies to the Document.  These
+     Warranty Disclaimers are considered to be included by reference in
+     this License, but only as regards disclaiming warranties: any other
+     implication that these Warranty Disclaimers may have is void and
+     has no effect on the meaning of this License.
+
+  2. VERBATIM COPYING
+
+     You may copy and distribute the Document in any medium, either
+     commercially or noncommercially, provided that this License, the
+     copyright notices, and the license notice saying this License
+     applies to the Document are reproduced in all copies, and that you
+     add no other conditions whatsoever to those of this License.  You
+     may not use technical measures to obstruct or control the reading
+     or further copying of the copies you make or distribute.  However,
+     you may accept compensation in exchange for copies.  If you
+     distribute a large enough number of copies you must also follow the
+     conditions in section 3.
+
+     You may also lend copies, under the same conditions stated above,
+     and you may publicly display copies.
+
+  3. COPYING IN QUANTITY
+
+     If you publish printed copies (or copies in media that commonly
+     have printed covers) of the Document, numbering more than 100, and
+     the Document's license notice requires Cover Texts, you must
+     enclose the copies in covers that carry, clearly and legibly, all
+     these Cover Texts: Front-Cover Texts on the front cover, and
+     Back-Cover Texts on the back cover.  Both covers must also clearly
+     and legibly identify you as the publisher of these copies.  The
+     front cover must present the full title with all words of the title
+     equally prominent and visible.  You may add other material on the
+     covers in addition.  Copying with changes limited to the covers, as
+     long as they preserve the title of the Document and satisfy these
+     conditions, can be treated as verbatim copying in other respects.
+
+     If the required texts for either cover are too voluminous to fit
+     legibly, you should put the first ones listed (as many as fit
+     reasonably) on the actual cover, and continue the rest onto
+     adjacent pages.
+
+     If you publish or distribute Opaque copies of the Document
+     numbering more than 100, you must either include a machine-readable
+     Transparent copy along with each Opaque copy, or state in or with
+     each Opaque copy a computer-network location from which the general
+     network-using public has access to download using public-standard
+     network protocols a complete Transparent copy of the Document, free
+     of added material.  If you use the latter option, you must take
+     reasonably prudent steps, when you begin distribution of Opaque
+     copies in quantity, to ensure that this Transparent copy will
+     remain thus accessible at the stated location until at least one
+     year after the last time you distribute an Opaque copy (directly or
+     through your agents or retailers) of that edition to the public.
+
+     It is requested, but not required, that you contact the authors of
+     the Document well before redistributing any large number of copies,
+     to give them a chance to provide you with an updated version of the
+     Document.
+
+  4. MODIFICATIONS
+
+     You may copy and distribute a Modified Version of the Document
+     under the conditions of sections 2 and 3 above, provided that you
+     release the Modified Version under precisely this License, with the
+     Modified Version filling the role of the Document, thus licensing
+     distribution and modification of the Modified Version to whoever
+     possesses a copy of it.  In addition, you must do these things in
+     the Modified Version:
+
+       A. Use in the Title Page (and on the covers, if any) a title
+          distinct from that of the Document, and from those of previous
+          versions (which should, if there were any, be listed in the
+          History section of the Document).  You may use the same title
+          as a previous version if the original publisher of that
+          version gives permission.
+
+       B. List on the Title Page, as authors, one or more persons or
+          entities responsible for authorship of the modifications in
+          the Modified Version, together with at least five of the
+          principal authors of the Document (all of its principal
+          authors, if it has fewer than five), unless they release you
+          from this requirement.
+
+       C. State on the Title page the name of the publisher of the
+          Modified Version, as the publisher.
+
+       D. Preserve all the copyright notices of the Document.
+
+       E. Add an appropriate copyright notice for your modifications
+          adjacent to the other copyright notices.
+
+       F. Include, immediately after the copyright notices, a license
+          notice giving the public permission to use the Modified
+          Version under the terms of this License, in the form shown in
+          the Addendum below.
+
+       G. Preserve in that license notice the full lists of Invariant
+          Sections and required Cover Texts given in the Document's
+          license notice.
+
+       H. Include an unaltered copy of this License.
+
+       I. Preserve the section Entitled "History", Preserve its Title,
+          and add to it an item stating at least the title, year, new
+          authors, and publisher of the Modified Version as given on the
+          Title Page.  If there is no section Entitled "History" in the
+          Document, create one stating the title, year, authors, and
+          publisher of the Document as given on its Title Page, then add
+          an item describing the Modified Version as stated in the
+          previous sentence.
+
+       J. Preserve the network location, if any, given in the Document
+          for public access to a Transparent copy of the Document, and
+          likewise the network locations given in the Document for
+          previous versions it was based on.  These may be placed in the
+          "History" section.  You may omit a network location for a work
+          that was published at least four years before the Document
+          itself, or if the original publisher of the version it refers
+          to gives permission.
+
+       K. For any section Entitled "Acknowledgements" or "Dedications",
+          Preserve the Title of the section, and preserve in the section
+          all the substance and tone of each of the contributor
+          acknowledgements and/or dedications given therein.
+
+       L. Preserve all the Invariant Sections of the Document, unaltered
+          in their text and in their titles.  Section numbers or the
+          equivalent are not considered part of the section titles.
+
+       M. Delete any section Entitled "Endorsements".  Such a section
+          may not be included in the Modified Version.
+
+       N. Do not retitle any existing section to be Entitled
+          "Endorsements" or to conflict in title with any Invariant
+          Section.
+
+       O. Preserve any Warranty Disclaimers.
+
+     If the Modified Version includes new front-matter sections or
+     appendices that qualify as Secondary Sections and contain no
+     material copied from the Document, you may at your option designate
+     some or all of these sections as invariant.  To do this, add their
+     titles to the list of Invariant Sections in the Modified Version's
+     license notice.  These titles must be distinct from any other
+     section titles.
+
+     You may add a section Entitled "Endorsements", provided it contains
+     nothing but endorsements of your Modified Version by various
+     parties--for example, statements of peer review or that the text
+     has been approved by an organization as the authoritative
+     definition of a standard.
+
+     You may add a passage of up to five words as a Front-Cover Text,
+     and a passage of up to 25 words as a Back-Cover Text, to the end of
+     the list of Cover Texts in the Modified Version.  Only one passage
+     of Front-Cover Text and one of Back-Cover Text may be added by (or
+     through arrangements made by) any one entity.  If the Document
+     already includes a cover text for the same cover, previously added
+     by you or by arrangement made by the same entity you are acting on
+     behalf of, you may not add another; but you may replace the old
+     one, on explicit permission from the previous publisher that added
+     the old one.
+
+     The author(s) and publisher(s) of the Document do not by this
+     License give permission to use their names for publicity for or to
+     assert or imply endorsement of any Modified Version.
+
+  5. COMBINING DOCUMENTS
+
+     You may combine the Document with other documents released under
+     this License, under the terms defined in section 4 above for
+     modified versions, provided that you include in the combination all
+     of the Invariant Sections of all of the original documents,
+     unmodified, and list them all as Invariant Sections of your
+     combined work in its license notice, and that you preserve all
+     their Warranty Disclaimers.
+
+     The combined work need only contain one copy of this License, and
+     multiple identical Invariant Sections may be replaced with a single
+     copy.  If there are multiple Invariant Sections with the same name
+     but different contents, make the title of each such section unique
+     by adding at the end of it, in parentheses, the name of the
+     original author or publisher of that section if known, or else a
+     unique number.  Make the same adjustment to the section titles in
+     the list of Invariant Sections in the license notice of the
+     combined work.
+
+     In the combination, you must combine any sections Entitled
+     "History" in the various original documents, forming one section
+     Entitled "History"; likewise combine any sections Entitled
+     "Acknowledgements", and any sections Entitled "Dedications".  You
+     must delete all sections Entitled "Endorsements."
+
+  6. COLLECTIONS OF DOCUMENTS
+
+     You may make a collection consisting of the Document and other
+     documents released under this License, and replace the individual
+     copies of this License in the various documents with a single copy
+     that is included in the collection, provided that you follow the
+     rules of this License for verbatim copying of each of the documents
+     in all other respects.
+
+     You may extract a single document from such a collection, and
+     distribute it individually under this License, provided you insert
+     a copy of this License into the extracted document, and follow this
+     License in all other respects regarding verbatim copying of that
+     document.
+
+  7. AGGREGATION WITH INDEPENDENT WORKS
+
+     A compilation of the Document or its derivatives with other
+     separate and independent documents or works, in or on a volume of a
+     storage or distribution medium, is called an "aggregate" if the
+     copyright resulting from the compilation is not used to limit the
+     legal rights of the compilation's users beyond what the individual
+     works permit.  When the Document is included in an aggregate, this
+     License does not apply to the other works in the aggregate which
+     are not themselves derivative works of the Document.
+
+     If the Cover Text requirement of section 3 is applicable to these
+     copies of the Document, then if the Document is less than one half
+     of the entire aggregate, the Document's Cover Texts may be placed
+     on covers that bracket the Document within the aggregate, or the
+     electronic equivalent of covers if the Document is in electronic
+     form.  Otherwise they must appear on printed covers that bracket
+     the whole aggregate.
+
+  8. TRANSLATION
+
+     Translation is considered a kind of modification, so you may
+     distribute translations of the Document under the terms of section
+     4.  Replacing Invariant Sections with translations requires special
+     permission from their copyright holders, but you may include
+     translations of some or all Invariant Sections in addition to the
+     original versions of these Invariant Sections.  You may include a
+     translation of this License, and all the license notices in the
+     Document, and any Warranty Disclaimers, provided that you also
+     include the original English version of this License and the
+     original versions of those notices and disclaimers.  In case of a
+     disagreement between the translation and the original version of
+     this License or a notice or disclaimer, the original version will
+     prevail.
+
+     If a section in the Document is Entitled "Acknowledgements",
+     "Dedications", or "History", the requirement (section 4) to
+     Preserve its Title (section 1) will typically require changing the
+     actual title.
+
+  9. TERMINATION
+
+     You may not copy, modify, sublicense, or distribute the Document
+     except as expressly provided under this License.  Any attempt
+     otherwise to copy, modify, sublicense, or distribute it is void,
+     and will automatically terminate your rights under this License.
+
+     However, if you cease all violation of this License, then your
+     license from a particular copyright holder is reinstated (a)
+     provisionally, unless and until the copyright holder explicitly and
+     finally terminates your license, and (b) permanently, if the
+     copyright holder fails to notify you of the violation by some
+     reasonable means prior to 60 days after the cessation.
+
+     Moreover, your license from a particular copyright holder is
+     reinstated permanently if the copyright holder notifies you of the
+     violation by some reasonable means, this is the first time you have
+     received notice of violation of this License (for any work) from
+     that copyright holder, and you cure the violation prior to 30 days
+     after your receipt of the notice.
+
+     Termination of your rights under this section does not terminate
+     the licenses of parties who have received copies or rights from you
+     under this License.  If your rights have been terminated and not
+     permanently reinstated, receipt of a copy of some or all of the
+     same material does not give you any rights to use it.
+
+  10. FUTURE REVISIONS OF THIS LICENSE
+
+     The Free Software Foundation may publish new, revised versions of
+     the GNU Free Documentation License from time to time.  Such new
+     versions will be similar in spirit to the present version, but may
+     differ in detail to address new problems or concerns.  See
+     <http://www.gnu.org/copyleft/>.
+
+     Each version of the License is given a distinguishing version
+     number.  If the Document specifies that a particular numbered
+     version of this License "or any later version" applies to it, you
+     have the option of following the terms and conditions either of
+     that specified version or of any later version that has been
+     published (not as a draft) by the Free Software Foundation.  If the
+     Document does not specify a version number of this License, you may
+     choose any version ever published (not as a draft) by the Free
+     Software Foundation.  If the Document specifies that a proxy can
+     decide which future versions of this License can be used, that
+     proxy's public statement of acceptance of a version permanently
+     authorizes you to choose that version for the Document.
+
+  11. RELICENSING
+
+     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+     World Wide Web server that publishes copyrightable works and also
+     provides prominent facilities for anybody to edit those works.  A
+     public wiki that anybody can edit is an example of such a server.
+     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+     site means any set of copyrightable works thus published on the MMC
+     site.
+
+     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+     license published by Creative Commons Corporation, a not-for-profit
+     corporation with a principal place of business in San Francisco,
+     California, as well as future copyleft versions of that license
+     published by that same organization.
+
+     "Incorporate" means to publish or republish a Document, in whole or
+     in part, as part of another Document.
+
+     An MMC is "eligible for relicensing" if it is licensed under this
+     License, and if all works that were first published under this
+     License somewhere other than this MMC, and subsequently
+     incorporated in whole or in part into the MMC, (1) had no cover
+     texts or invariant sections, and (2) were thus incorporated prior
+     to November 1, 2008.
+
+     The operator of an MMC Site may republish an MMC contained in the
+     site under CC-BY-SA on the same site at any time before August 1,
+     2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+       Copyright (C)  YEAR  YOUR NAME.
+       Permission is granted to copy, distribute and/or modify this document
+       under the terms of the GNU Free Documentation License, Version 1.3
+       or any later version published by the Free Software Foundation;
+       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+       Texts.  A copy of the license is included in the section entitled ``GNU
+       Free Documentation License''.
+
+   If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts."  line with this:
+
+         with the Invariant Sections being LIST THEIR TITLES, with
+         the Front-Cover Texts being LIST, and with the Back-Cover Texts
+         being LIST.
+
+   If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+   If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+
+Tag Table:
+
+End Tag Table
.emacs.d/elpa/evil-20170904.1346/macros.info
@@ -0,0 +1,7 @@
+This is macros.info, produced by makeinfo version 5.2 from macros.texi.
+
+
+
+Tag Table:
+
+End Tag Table
.emacs.d/elpa/evil-20170904.1346/version.info
@@ -0,0 +1,8 @@
+This is version.info, produced by makeinfo version 5.2 from
+version.texi.
+
+
+
+Tag Table:
+
+End Tag Table
.emacs.d/elpa/evil-indent-textobject-20130831.1519/evil-indent-textobject-autoloads.el
@@ -0,0 +1,19 @@
+;;; evil-indent-textobject-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-indent-textobject" "evil-indent-textobject.el"
+;;;;;;  (22968 13521 188620 887000))
+;;; Generated autoloads from evil-indent-textobject.el
+
+(eval-after-load 'evil '(progn (autoload 'evil-indent-i-indent "evil-indent-textobject" nil t) (autoload 'evil-indent-a-indent "evil-indent-textobject" nil t) (autoload 'evil-indent-a-indent-lines "evil-indent-textobject" nil t) (define-key evil-inner-text-objects-map "i" 'evil-indent-i-indent) (define-key evil-outer-text-objects-map "i" 'evil-indent-a-indent) (define-key evil-outer-text-objects-map "I" 'evil-indent-a-indent-lines)))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-indent-textobject-autoloads.el ends here
.emacs.d/elpa/evil-indent-textobject-20130831.1519/evil-indent-textobject-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "evil-indent-textobject" "20130831.1519" "evil textobjects based on indentation" '((evil "0")) :commit "70a1154a531b7cfdbb9a31d6922482791e20a3a7" :url "http://github.com/cofi/evil-indent-textobject" :keywords '("convenience" "evil"))
.emacs.d/elpa/evil-indent-textobject-20130831.1519/evil-indent-textobject.el
@@ -0,0 +1,125 @@
+;;; evil-indent-textobject.el --- evil textobjects based on indentation
+
+;; Copyright (C) 2013 Michael Markert
+;; Author: Michael Markert <markert.michael@gmail.com>
+;; Created: 2013-08-31
+;; Version: 0.2
+;; Package-Version: 20130831.1519
+;; Keywords: convenience evil
+;; URL: http://github.com/cofi/evil-indent-textobject
+;; Package-Requires: ((evil "0"))
+;;
+;; This file is not part of GNU Emacs.
+
+;; This program 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 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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 GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;;; Adds new textobjects:
+;;;
+;;; ii - Inner Indentation: the surrounding textblock with the same indentation
+;;; ai - Above and Indentation: ii + the line above with a different indentation
+;;; aI - Above and Indentation+: ai + the line below with a different indentation
+;;;
+;;; With | representing the cursor:
+;;;
+;;; (while (not done)
+;;;   (messa|ge "All work and no play makes Jack a dull boy."))
+;;; (1+ 41)
+;;;
+;;; - vii will select the line with message
+;;; - vai will select the whole while loop
+;;; - vaI will select the whole fragment
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'evil)
+
+(defun evil-indent--current-indentation ()
+  "Return the indentation of the current line.
+Moves point."
+  (buffer-substring-no-properties (point-at-bol)
+                                  (progn (back-to-indentation)
+                                         (point))))
+
+(defun evil-indent--same-indent-range (&optional point)
+  "Return the point at the begin and end of the text block with the same indentation.
+If `point' is supplied and non-nil it will return the begin and
+end of the block surrounding point."
+  (save-excursion
+    (when point
+      (goto-char point))
+    (let ((start (point))
+          (indent (evil-indent--current-indentation))
+          begin end)
+      (loop while (and (/= (point) (point-min))
+                       (string= (evil-indent--current-indentation) indent))
+            do (progn
+                 (setq begin (point-at-bol))
+                 (forward-line -1)))
+      (goto-char start)
+      (loop while (and (/= (point) (point-max))
+                       (string= (evil-indent--current-indentation) indent))
+            do (progn
+                 (setq end (point-at-eol))
+                 (forward-line 1)))
+      (list begin end))))
+
+(evil-define-text-object evil-indent-a-indent (&optional count beg end type)
+  "Text object describing the block with the same indentation as
+the current line and the line above."
+  :type line
+  (let ((range (evil-indent--same-indent-range)))
+    (evil-range (save-excursion
+                  (goto-char (first (evil-indent--same-indent-range)))
+                  (forward-line -1)
+                  (point-at-bol))
+                (second range) 'line)))
+
+(evil-define-text-object evil-indent-a-indent-lines (&optional count beg end type)
+  "Text object describing the block with the same indentation as
+the current line and the lines above and below."
+  :type line
+  (let ((range (evil-indent--same-indent-range)))
+    (evil-range (save-excursion
+                  (goto-char (first range))
+                  (forward-line -1)
+                  (point-at-bol))
+                (save-excursion
+                  (goto-char (second range))
+                  (forward-line 1)
+                  (point-at-eol)) 'line)))
+
+(evil-define-text-object evil-indent-i-indent (&optional count beg end type)
+  "Text object describing the block with the same indentation as
+the current line."
+  :type line
+  (let ((range (evil-indent--same-indent-range)))
+    (evil-range (first range) (second range) 'line)))
+
+;;;###autoload
+(eval-after-load 'evil
+  '(progn
+     (autoload 'evil-indent-i-indent "evil-indent-textobject" nil t)
+     (autoload 'evil-indent-a-indent "evil-indent-textobject" nil t)
+     (autoload 'evil-indent-a-indent-lines "evil-indent-textobject" nil t)
+     (define-key evil-inner-text-objects-map "i" 'evil-indent-i-indent)
+     (define-key evil-outer-text-objects-map "i" 'evil-indent-a-indent)
+     (define-key evil-outer-text-objects-map "I" 'evil-indent-a-indent-lines)))
+
+(provide 'evil-indent-textobject)
+;;; evil-indent-textobject.el ends here
.emacs.d/elpa/evil-indent-textobject-20130831.1519/evil-indent-textobject.elc
Binary file
.emacs.d/elpa/evil-surround-20170910.1952/evil-surround-autoloads.el
@@ -0,0 +1,70 @@
+;;; evil-surround-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-surround" "evil-surround.el" (22968 13502
+;;;;;;  622816 101000))
+;;; Generated autoloads from evil-surround.el
+
+(autoload 'evil-surround-delete "evil-surround" "\
+Delete the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with
+the overlays OUTER and INNER, where OUTER includes the delimiters
+and INNER excludes them. The intersection (i.e., difference)
+between these overlays is what is deleted.
+
+\(fn CHAR &optional OUTER INNER)" t nil)
+
+(autoload 'evil-surround-change "evil-surround" "\
+Change the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with the
+overlays OUTER and INNER, which are passed to `evil-surround-delete'.
+
+\(fn CHAR &optional OUTER INNER)" t nil)
+
+(autoload 'evil-surround-mode "evil-surround" "\
+Buffer-local minor mode to emulate surround.vim.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-evil-surround-mode "evil-surround" "\
+Enable evil-surround-mode in the current buffer.
+
+\(fn)" nil nil)
+
+(autoload 'turn-off-evil-surround-mode "evil-surround" "\
+Disable evil-surround-mode in the current buffer.
+
+\(fn)" nil nil)
+
+(defvar global-evil-surround-mode nil "\
+Non-nil if Global Evil-Surround mode is enabled.
+See the `global-evil-surround-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-evil-surround-mode'.")
+
+(custom-autoload 'global-evil-surround-mode "evil-surround" nil)
+
+(autoload 'global-evil-surround-mode "evil-surround" "\
+Toggle Evil-Surround mode in all buffers.
+With prefix ARG, enable Global Evil-Surround mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Evil-Surround mode is enabled in all buffers where
+`turn-on-evil-surround-mode' would do it.
+See `evil-surround-mode' for more information on Evil-Surround mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-surround-autoloads.el ends here
.emacs.d/elpa/evil-surround-20170910.1952/evil-surround-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "evil-surround" "20170910.1952" "emulate surround.vim from Vim" '((evil "1.2.12")) :commit "7839abe0e04740e2928a6b799557d1b16460fa5f" :keywords '("emulation" "vi" "evil"))
.emacs.d/elpa/evil-surround-20170910.1952/evil-surround.el
@@ -0,0 +1,385 @@
+;;; evil-surround.el --- emulate surround.vim from Vim
+
+;; Copyright (C) 2010 - 2017 Tim Harper
+
+;; Licensed under the same terms as Emacs (GPLv3)
+
+;;
+;; Author: Tim Harper <timcharper at gmail dot com>
+;;      Vegard ร˜ye <vegard_oye at hotmail dot com>
+;; Current Maintainer: ninrod (github.com/ninrod)
+;; Created: July 23 2011
+;; Version: 0.1
+;; Package-Version: 20170910.1952
+;; Package-Requires: ((evil "1.2.12"))
+;; Mailing list: <implementations-list at lists.ourproject.org>
+;;      Subscribe: http://tinyurl.com/implementations-list
+;;      Newsgroup: nntp://news.gmane.org/gmane.emacs.vim-emulation
+;;      Archives: http://dir.gmane.org/gmane.emacs.vim-emulation
+;; Keywords: emulation, vi, evil
+;;
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; This package emulates surround.vim by Tim Pope.
+;; The functionality is wrapped into a minor mode. To enable
+;; it globally, add the following lines to ~/.emacs:
+;;
+;;     (require 'evil-surround)
+;;     (global-evil-surround-mode 1)
+;;
+;; Alternatively, you can enable evil-surround-mode along a major mode
+;; by adding `turn-on-evil-surround-mode' to the mode hook.
+;;
+;; This package uses Evil as its vi layer. It is available from:
+;;
+;;     https://github.com/emacs-evil/evil
+
+;;; Code:
+
+(require 'evil)
+
+(defgroup surround nil
+  "surround.vim for Emacs"
+  :prefix "surround-"
+  :group 'evil)
+
+(defcustom evil-surround-pairs-alist
+  '((?\( . ("( " . " )"))
+    (?\[ . ("[ " . " ]"))
+    (?\{ . ("{ " . " }"))
+
+    (?\) . ("(" . ")"))
+    (?\] . ("[" . "]"))
+    (?\} . ("{" . "}"))
+
+    (?# . ("#{" . "}"))
+    (?b . ("(" . ")"))
+    (?B . ("{" . "}"))
+    (?> . ("<" . ">"))
+    (?t . evil-surround-read-tag)
+    (?< . evil-surround-read-tag)
+    (?f . evil-surround-function))
+  "Association list of surround items.
+Each item is of the form (TRIGGER . (LEFT . RIGHT)), all strings.
+Alternatively, a function can be put in place of (LEFT . RIGHT).
+This only affects inserting pairs, not deleting or changing them."
+  :group 'surround
+  :type '(alist
+          :key-type (character :tag "Key")
+          :value-type (choice
+                       (cons (string :tag "Opening") (string :tag "Closing"))
+                       (function :tag "Function"))))
+(make-variable-buffer-local 'evil-surround-pairs-alist)
+
+(defcustom evil-surround-operator-alist
+  '((evil-change . change)
+    (evil-delete . delete))
+  "Association list of operators to their fundamental operation.
+Each item is of the form (OPERATOR . OPERATION)."
+  :group 'surround
+  :type '(repeat (cons (symbol :tag "Operator")
+                       (symbol :tag "Operation"))))
+
+(defvar evil-surround-read-tag-map
+  (let ((map (copy-keymap minibuffer-local-map)))
+    (define-key map ">" 'exit-minibuffer)
+    map)
+  "Keymap used by `evil-surround-read-tag'.")
+
+(defun evil-surround-function ()
+  "Read a functionname from the minibuffer and wrap selection in function call"
+  (let ((fname (read-from-minibuffer "" "" )))
+    (cons (format "%s(" (or fname ""))
+          ")")))
+
+(defun evil-surround-read-tag ()
+  "Read a XML tag from the minibuffer."
+  (let* ((input (read-from-minibuffer "<" "" evil-surround-read-tag-map))
+         (match (string-match "\\([0-9a-z-]+\\)\\(.*?\\)[>]*$" input))
+         (tag  (match-string 1 input))
+         (rest (match-string 2 input)))
+    (cons (format "<%s%s>" (or tag "") (or rest ""))
+          (format "</%s>" (or tag "")))))
+
+(defun evil-surround-valid-char-p (char)
+  "Returns whether CHAR is a valid surround char or not."
+  (not (memq char '(?\C-\[ ?\C-?))))
+
+(defun evil-surround-pair (char)
+  "Return the evil-surround pair of char.
+This is a cons cell (LEFT . RIGHT), both strings."
+  (let ((pair (assoc-default char evil-surround-pairs-alist)))
+    (cond
+     ((functionp pair)
+      (funcall pair))
+
+     ((consp pair)
+      pair)
+
+     (t
+      (cons (format "%c" char) (format "%c" char))))))
+
+(defun evil-surround-outer-overlay (char)
+  "Return outer overlay for the delimited range represented by CHAR.
+This overlay includes the delimiters.
+See also `evil-surround-inner-overlay'."
+  (let ((outer (lookup-key evil-outer-text-objects-map (string char))))
+    (when (functionp outer)
+      (setq outer (funcall outer))
+      (when (evil-range-p outer)
+        (evil-surround-trim-whitespace-from-range outer "[[:space:]]")
+        (setq outer (make-overlay (evil-range-beginning outer)
+                                  (evil-range-end outer)
+                                  nil nil t))))))
+
+(defun evil-surround-trim-whitespace-from-range (range &optional regexp)
+  "Given an evil-range, trim whitespace around range by shrinking the range such that it neither begins nor ends with whitespace. Does not modify the buffer."
+  (let ((regexp (or regexp "[ \f\t\n\r\v]")))
+    (save-excursion
+      (save-match-data
+        (goto-char (evil-range-beginning range))
+        (while (looking-at regexp) (forward-char))
+        (evil-set-range-beginning range (point))
+        (goto-char (evil-range-end range))
+        (while (looking-back regexp) (backward-char))
+        (evil-set-range-end range (point))))))
+
+(defun evil-surround-inner-overlay (char)
+  "Return inner overlay for the delimited range represented by CHAR.
+This overlay excludes the delimiters.
+See also `evil-surround-outer-overlay'."
+  (let ((inner (lookup-key evil-inner-text-objects-map (string char))))
+    (when (functionp inner)
+      (setq inner (funcall inner))
+      (when (evil-range-p inner)
+        (when (eq (char-syntax char) ?\()
+          (evil-surround-trim-whitespace-from-range inner "[[:space:]]"))
+        (setq inner (make-overlay (evil-range-beginning inner)
+                                  (evil-range-end inner)
+                                  nil nil t))))))
+
+(evil-define-motion evil-surround-line (count)
+  "Move COUNT - 1 lines down but return exclusive character motion."
+  :type exclusive
+  (let ((beg (line-beginning-position)))
+    (evil-line count)
+    (end-of-line)
+    (let ((range (evil-range beg (point) 'exclusive)))
+      (evil-expand-range range)
+      range)))
+
+;;;###autoload
+(defun evil-surround-delete (char &optional outer inner)
+  "Delete the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with
+the overlays OUTER and INNER, where OUTER includes the delimiters
+and INNER excludes them. The intersection (i.e., difference)
+between these overlays is what is deleted."
+  (interactive "c")
+  (cond
+   ((and outer inner)
+    (delete-region (overlay-start outer) (overlay-start inner))
+    (delete-region (overlay-end inner) (overlay-end outer))
+    (goto-char (overlay-start outer)))
+   (t
+    ;; no overlays specified: create them on the basis of CHAR
+    ;; and delete after use
+    (let* ((outer (evil-surround-outer-overlay char))
+           (inner (evil-surround-inner-overlay char)))
+      (unwind-protect
+          (when (and outer inner)
+            (evil-surround-delete char outer inner))
+        (when outer (delete-overlay outer))
+        (when inner (delete-overlay inner)))))))
+
+;;;###autoload
+(defun evil-surround-change (char &optional outer inner)
+  "Change the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with the
+overlays OUTER and INNER, which are passed to `evil-surround-delete'."
+  (interactive "c")
+  (cond
+   ((and outer inner)
+    (evil-surround-delete char outer inner)
+    (let ((key (read-char)))
+      (evil-surround-region (overlay-start outer)
+                            (overlay-end outer)
+                            nil (if (evil-surround-valid-char-p key) key char))))
+   (t
+    (let* ((outer (evil-surround-outer-overlay char))
+           (inner (evil-surround-inner-overlay char)))
+      (unwind-protect
+          (when (and outer inner)
+            (evil-surround-change char outer inner))
+        (when outer (delete-overlay outer))
+        (when inner (delete-overlay inner)))))))
+
+(defun evil-surround-interactive-setup ()
+  (setq evil-inhibit-operator t)
+     (list (assoc-default evil-this-operator
+                          evil-surround-operator-alist)))
+
+(defun evil-surround-setup-surround-line-operators ()
+  (define-key evil-operator-shortcut-map "s" 'evil-surround-line)
+  (define-key evil-operator-shortcut-map "S" 'evil-surround-line))
+
+(defun evil-surround-column-at (pos)
+  (save-excursion (goto-char pos) (current-column)))
+
+(defun evil-surround-block (beg end char)
+  "Surrounds a block selection with a character, as if `evil-surround-region'
+were called on each segment in each line. This skips lines where EOL < BEG's
+column."
+  (let ((beg-col (evil-surround-column-at beg))
+        (end-col (evil-surround-column-at end)))
+    (evil-apply-on-block
+     (lambda (ibeg iend)
+       (unless (< (evil-surround-column-at ibeg) (min beg-col end-col))
+         (evil-surround-region ibeg iend t char)))
+     beg end nil)))
+
+(defun evil-surround-call-with-repeat (callback)
+  "Record keystrokes to repeat surround-region operator and it's motion.
+This is necessary because `evil-yank' operator is not repeatable (:repeat nil)"
+  (evil-repeat-start)
+  (evil-repeat-record "y")
+  (evil-repeat-record (this-command-keys))
+  (call-interactively callback)
+  (evil-repeat-keystrokes 'post)
+  (evil-repeat-stop))
+
+;; Dispatcher function in Operator-Pending state.
+;; "cs" calls `evil-surround-change', "ds" calls `evil-surround-delete',
+;; and "ys" calls `evil-surround-region'.
+(evil-define-command evil-surround-edit (operation)
+  "Edit the surrounding delimiters represented by CHAR.
+If OPERATION is `change', call `evil-surround-change'.
+if OPERATION is `delete', call `evil-surround-delete'.
+Otherwise call `evil-surround-region'."
+  (interactive (evil-surround-interactive-setup))
+  (cond
+   ((eq operation 'change)
+    (call-interactively 'evil-surround-change))
+   ((eq operation 'delete)
+    (call-interactively 'evil-surround-delete))
+   (t
+    (evil-surround-setup-surround-line-operators)
+    (evil-surround-call-with-repeat 'evil-surround-region))))
+
+(evil-define-command evil-Surround-edit (operation)
+  "Like evil-surround-edit, but for surrounding with additional new-lines.
+
+It does nothing for change / delete."
+  (interactive (evil-surround-interactive-setup))
+  (cond
+   ((eq operation 'change) nil)
+   ((eq operation 'delete) nil)
+   (t
+    (evil-surround-setup-surround-line-operators)
+    (evil-surround-call-with-repeat 'evil-Surround-region))))
+
+(evil-define-operator evil-surround-region (beg end type char &optional force-new-line)
+  "Surround BEG and END with CHAR.
+
+When force-new-line is true, and region type is not line, the
+following: (vertical bars indicate region start/end points)
+
+   do |:thing|
+
+Becomes this:
+
+   do {
+     :thing
+   }"
+
+  (interactive "<R>c")
+  (when (evil-surround-valid-char-p char)
+    (let* ((overlay (make-overlay beg end nil nil t))
+           (pair (or (and (boundp 'pair) pair) (evil-surround-pair char)))
+           (open (car pair))
+           (close (cdr pair))
+           (beg-pos (overlay-start overlay)))
+      (unwind-protect
+          (progn
+            (goto-char beg-pos)
+            (cond ((eq type 'block)
+                   (evil-surround-block beg end char))
+
+                  ((eq type 'line)
+                   (setq force-new-line
+                         (or force-new-line
+                             ;; Force newline if not invoked from an operator, e.g. VS)
+                             (eq evil-this-operator 'evil-surround-region)
+                             ;; Or on multi-line operator surrounds (like 'ysj]')
+                             (/= (line-number-at-pos) (line-number-at-pos (1- end)))))
+
+                   (back-to-indentation)
+                   (setq beg-pos (point))
+                   (insert open)
+                   (when force-new-line (newline-and-indent))
+                   (goto-char (overlay-end overlay))
+                   (if force-new-line
+                       (when (eobp)
+                         (newline-and-indent))
+                     (backward-char)
+                     (evil-last-non-blank)
+                     (forward-char))
+                   (insert close)
+                   (when (or force-new-line
+                             (/= (line-number-at-pos) (line-number-at-pos beg-pos)))
+                     (indent-region beg-pos (point))
+                     (newline-and-indent)))
+
+                  (force-new-line
+                   (insert open)
+                   (newline-and-indent)
+                   (let ((pt (point)))
+                     (goto-char (overlay-end overlay))
+                     (newline-and-indent)
+                     (insert close)
+                     (indent-region pt (point))))
+
+                  (t
+                   (insert open)
+                   (goto-char (overlay-end overlay))
+                   (insert close)))
+            (goto-char beg-pos))
+        (delete-overlay overlay)))))
+
+(evil-define-operator evil-Surround-region (beg end type char)
+  "Call surround-region, toggling force-new-line"
+  (interactive "<R>c")
+  (evil-surround-region beg end type char t))
+
+;;;###autoload
+(define-minor-mode evil-surround-mode
+  "Buffer-local minor mode to emulate surround.vim."
+  :keymap (make-sparse-keymap)
+  (evil-normalize-keymaps))
+
+;;;###autoload
+(defun turn-on-evil-surround-mode ()
+  "Enable evil-surround-mode in the current buffer."
+  (evil-surround-mode 1))
+
+;;;###autoload
+(defun turn-off-evil-surround-mode ()
+  "Disable evil-surround-mode in the current buffer."
+  (evil-surround-mode -1))
+
+;;;###autoload
+(define-globalized-minor-mode global-evil-surround-mode
+  evil-surround-mode turn-on-evil-surround-mode
+  "Global minor mode to emulate surround.vim.")
+
+(evil-define-key 'operator evil-surround-mode-map "s" 'evil-surround-edit)
+(evil-define-key 'operator evil-surround-mode-map "S" 'evil-Surround-edit)
+
+(evil-define-key 'visual evil-surround-mode-map "S" 'evil-surround-region)
+(evil-define-key 'visual evil-surround-mode-map "gS" 'evil-Surround-region)
+
+(provide 'evil-surround)
+
+;;; evil-surround.el ends here
.emacs.d/elpa/evil-surround-20170910.1952/evil-surround.elc
Binary file
.emacs.d/elpa/goto-chg-20131228.659/goto-chg-autoloads.el
@@ -0,0 +1,50 @@
+;;; goto-chg-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "goto-chg" "goto-chg.el" (22968 12680 41528
+;;;;;;  650000))
+;;; Generated autoloads from goto-chg.el
+
+(autoload 'goto-last-change "goto-chg" "\
+Go to the point where the last edit was made in the current buffer.
+Repeat the command to go to the second last edit, etc.
+
+To go back to more recent edit, the reverse of this command, use \\[goto-last-change-reverse]
+or precede this command with \\[universal-argument] - (minus).
+
+It does not go to the same point twice even if there has been many edits
+there. I call the minimal distance between distinguishable edits \"span\".
+Set variable `glc-default-span' to control how close is \"the same point\".
+Default span is 8.
+The span can be changed temporarily with \\[universal-argument] right before \\[goto-last-change]:
+\\[universal-argument] <NUMBER> set current span to that number,
+\\[universal-argument] (no number) multiplies span by 4, starting with default.
+The so set span remains until it is changed again with \\[universal-argument], or the consecutive
+repetition of this command is ended by any other command.
+
+When span is zero (i.e. \\[universal-argument] 0) subsequent \\[goto-last-change] visits each and
+every point of edit and a message shows what change was made there.
+In this case it may go to the same point twice.
+
+This command uses undo information. If undo is disabled, so is this command.
+At times, when undo information becomes too large, the oldest information is
+discarded. See variable `undo-limit'.
+
+\(fn ARG)" t nil)
+
+(autoload 'goto-last-change-reverse "goto-chg" "\
+Go back to more recent changes after \\[goto-last-change] have been used.
+See `goto-last-change' for use of prefix argument.
+
+\(fn ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; goto-chg-autoloads.el ends here
.emacs.d/elpa/goto-chg-20131228.659/goto-chg-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "goto-chg" "20131228.659" "goto last change" 'nil :keywords '("convenience" "matching"))
.emacs.d/elpa/goto-chg-20131228.659/goto-chg.el
@@ -0,0 +1,316 @@
+;;; goto-chg.el --- goto last change
+;;--------------------------------------------------------------------
+;;
+;; Copyright (C) 2002-2008,2013 David Andersson
+;;
+;; This program 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 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+;;
+;;-------------------------------------------------------------------
+;;
+;; Author: David Andersson <l.david.andersson(at)sverige.nu>
+;; Created: 16 May 2002
+;; Version: 1.6
+;; Package-Version: 20131228.659
+;; Keywords: convenience, matching
+;;
+;;; Commentary:
+;;
+;; Goto Last Change
+;;
+;; Goto the point of the most recent edit in the buffer.
+;; When repeated, goto the second most recent edit, etc.
+;; Negative argument, C-u -, for reverse direction.
+;; Works by looking into buffer-undo-list to find points of edit.
+;;
+;; You would probably like to bind this command to a key.
+;; For example in your ~/.emacs:
+;;
+;;   (require 'goto-chg)
+;;
+;;   (global-set-key [(control ?.)] 'goto-last-change)
+;;   (global-set-key [(control ?,)] 'goto-last-change-reverse)
+;;
+;; Works with emacs-19.29, 19.31, 20.3, 20.7, 21.1, 21.4, 22.1 and 23.1
+;; Works with XEmacs-20.4 and 21.4 (but see todo about `last-command' below)
+;;
+;;--------------------------------------------------------------------
+;; History
+;;
+;; Ver 1.6 2013-12-12 David Andersson
+;;    Add keywords; Cleanup comments
+;; Ver 1.5 2013-12-11 David Andersson
+;;    Autoload and document `goto-last-change-reverse'
+;; Ver 1.4 2008-09-20 David Andersson
+;;    Improved property change description; Update comments.
+;; Ver 1.3 2007-03-14 David Andersson
+;;    Added `goto-last-change-reverse'
+;; Ver 1.2 2003-04-06 David Andersson
+;;    Don't let repeating error depthen glc-probe-depth.
+;; Ver 1.1 2003-04-06 David Andersson
+;;    Zero arg describe changes. Negative arg go back.
+;;    Autoload. Remove message using nil in stead of an empty string.
+;; Ver 1.0 2002-05-18 David Andersson
+;;    Initial version
+;;
+;;--------------------------------------------------------------------
+;;
+;;todo: Rename "goto-chg.el" -> "gotochange.el" or "goto-chgs" ?
+;;todo: Rename function goto-last-change -> goto-last-edit ?
+;;todo: Rename adjective "-last-" -> "-latest-" or "-most-recent-" ?
+;;todo: There are some, maybe useful, funcs  for region undo 
+;;       in simple.el in emacs 20. Take a look.
+;;todo: Add functionality to visit changed point in text order, not only in
+;;        chronological order. (Naa, highlight-changes-mode does that).
+;;todo: Inverse indication that a change has been saved or not
+;;todo: Highlight the range of text involved in the last change?
+;;todo: See session-jump-to-last-change in session.el?
+;;todo: Unhide invisible text (e.g. outline mode) like isearch do.
+;;todo: XEmacs sets last-command to `t' after an error, so you cannot reverse
+;;        after "No furter change info". Should we bother?
+;;todo: Try distinguish "No further change info" (end of truncated undo list)
+;;        and "No further changes" (end of a complete undo list).
+;;
+;;--------------------------------------------------------------------
+
+;;; Code:
+
+(defvar glc-default-span 8 "*goto-last-change don't visit the same point twice. glc-default-span tells how far around a visited point not to visit again.")
+(defvar glc-current-span 8 "Internal for goto-last-change.\nA copy of glc-default-span or the ARG passed to goto-last-change.")
+(defvar glc-probe-depth 0 "Internal for goto-last-change.\nIt is non-zero between successive goto-last-change.")
+
+;;todo: Find begin and end of line, then use it somewhere
+
+(defun glc-center-ellipsis (str maxlen &optional ellipsis)
+  "Truncate STRING in the middle to length MAXLEN.
+If STRING is max MAXLEN just return the string.
+Optional third argument is the replacement, which defaults to \"...\"."
+  (if (<= (length str) maxlen)
+      str
+    ;; else
+    (let* ((lipsis (or ellipsis "..."))
+	   (i (/ (- maxlen (length lipsis)) 2)))
+      (concat (substring str 0 i)
+	      lipsis 
+	      (substring str (- i))))))
+
+(defun glc-adjust-pos2 (pos p1 p2 adj)
+  ;; Helper function to glc-adjust-pos
+  ;; p1, p2: interval where an edit occured
+  ;; adj: amount of text added (positive) or removed (negativ) by the edit
+  ;; Return pos if well before p1, or pos+adj if well after p2, or nil if too close
+  (cond ((<= pos (- p1 glc-current-span))
+	 pos)
+	((> pos (+ p2 glc-current-span))
+	 (+ pos adj))
+	((zerop glc-current-span)
+	 p1)
+	(t
+	 nil)))
+
+(defun glc-adjust-pos (pos e)
+  "Given POS, a buffer position before the edit E, compute and return
+the \"same\" buffer position after E happened.
+Exception: return nil if POS is closer than `glc-current-span' to the edit E.
+\nInsertion edits before POS returns a larger value.
+Deletion edits before POS returns a smaller value.
+\nThe edit E is an entry from the `buffer-undo-list'. See for details."
+  (cond ((atom e)			; nil==cmd boundary, or, num==changed pos
+	 pos)
+	((numberp (car e))		; (beg . end)==insertion
+	 (glc-adjust-pos2 pos (car e) (car e) (- (cdr e) (car e))))
+	((stringp (car e))		; (string . pos)==deletion
+	 (glc-adjust-pos2 pos (abs (cdr e)) (+ (abs (cdr e)) (length (car e))) (- (length (car e)))))
+	((null (car e))			; (nil prop val beg . end)==prop change
+	 (glc-adjust-pos2 pos (nth 3 e) (nthcdr 4 e) 0))
+	(t				; (marker . dist)==marker moved
+	 pos)))
+
+;; If recursive in stead of iterative (while), it tends to fill the call stack.
+;; (Isn't it tail optimized?)
+(defun glc-adjust-list (r)
+  "R is list of edit entries in chronological order.
+Pick the point of the first edit entry and update that point with
+the second, third, etc, edit entries. Return the final updated point,
+or nil if the point was closer than `glc-current-span' to some edit in R.
+\nR is basically a reversed slice from the buffer-undo-list."
+  (if r
+      ;; Get pos
+      (let ((pos (glc-get-pos (car r))))
+	(setq r (cdr r))
+	;; Walk back in reverse list
+	(while (and r pos)
+	  (setq pos (glc-adjust-pos pos (car r))
+		r (cdr r)))
+	pos)
+    ;; else
+    nil))
+
+(defun glc-get-pos (e)
+  "If E represents an edit, return a position value in E, the position
+where the edit took place. Return nil if E represents no real change.
+\nE is an entry in the buffer-undo-list."
+  (cond ((numberp e) e)			; num==changed position
+	((atom e) nil)			; nil==command boundary
+	((numberp (car e)) (cdr e))	; (beg . end)==insertion
+	((stringp (car e)) (abs (cdr e))) ; (string . pos)==deletion
+	((null (car e)) (nthcdr 4 e))	; (nil ...)==text property change
+	((atom (car e)) nil)		; (t ...)==file modification time
+	(t nil)))			; (marker ...)==marker moved
+
+(defun glc-get-descript (e &optional n)
+  "If E represents an edit, return a short string describing E.
+Return nil if E represents no real change.
+\nE is an entry in the buffer-undo-list."
+  (let ((nn (or (format "T-%d: " n) "")))
+    (cond ((numberp e) "New position")	; num==changed position
+	  ((atom e) nil)		; nil==command boundary
+	  ((numberp (car e))		; (beg . end)==insertion
+	   (if (and n (< n 2))
+	       (format "%sInserted %d chars \"%s\"" nn (- (cdr e) (car e)) 
+		       (glc-center-ellipsis (buffer-substring (car e) (cdr e)) 60))
+	     ;; else
+	     ;; An older insert. The inserted text cannot easily be computed.
+	     ;; Just show the char count.
+	     (format "%sInserted %d chars" nn (- (cdr e) (car e)))))
+	  ((stringp (car e))		; (string . pos)==deletion
+	   (format "%sDeleted \"%s\"" nn (glc-center-ellipsis (car e) 60)))
+	  ((null (car e))		; (nil ...)==text property change
+	   (format "%sProperty change" nn))
+	  ((atom (car e)) nil)		; (t ...)==file modification time
+	  (t nil))))			; (marker ...)==marker moved
+
+(defun glc-is-positionable (e)
+  "Return non-nil if E is an insertion, deletion or text property change.
+\nE is an entry in the buffer-undo-list."
+  (and (not (numberp e)) (glc-get-pos e)))
+
+(defun glc-is-filetime (e)
+  "Return t if E indicates a buffer became \"modified\",
+that is, it was previously saved or unchanged. Nil otherwise."
+  (and (listp e) (eq (car e) t)))
+
+;;;###autoload
+(defun goto-last-change (arg)
+"Go to the point where the last edit was made in the current buffer.
+Repeat the command to go to the second last edit, etc.
+\nTo go back to more recent edit, the reverse of this command, use \\[goto-last-change-reverse]
+or precede this command with \\[universal-argument] - (minus).
+\nIt does not go to the same point twice even if there has been many edits
+there. I call the minimal distance between distinguishable edits \"span\".
+Set variable `glc-default-span' to control how close is \"the same point\".
+Default span is 8.
+The span can be changed temporarily with \\[universal-argument] right before \\[goto-last-change]:
+\\[universal-argument] <NUMBER> set current span to that number,
+\\[universal-argument] (no number) multiplies span by 4, starting with default.
+The so set span remains until it is changed again with \\[universal-argument], or the consecutive
+repetition of this command is ended by any other command.
+\nWhen span is zero (i.e. \\[universal-argument] 0) subsequent \\[goto-last-change] visits each and
+every point of edit and a message shows what change was made there.
+In this case it may go to the same point twice.
+\nThis command uses undo information. If undo is disabled, so is this command.
+At times, when undo information becomes too large, the oldest information is
+discarded. See variable `undo-limit'."
+  (interactive "P")
+  (cond ((not (eq this-command last-command))
+	 ;; Start a glc sequence
+	 ;; Don't go to current point if last command was an obvious edit
+	 ;; (yank or self-insert, but not kill-region). Makes it easier to
+	 ;; jump back and forth when copying seleced lines.
+	 (setq glc-probe-depth (if (memq last-command '(yank self-insert-command)) 1 0)
+	       glc-direction 1
+	       glc-current-span glc-default-span)
+	 (if (< (prefix-numeric-value arg) 0)
+	     (error "Negative arg: Cannot reverse as the first operation"))))
+  (cond ((null buffer-undo-list)
+	 (error "Buffer has not been changed"))
+	((eq buffer-undo-list t)
+	 (error "No change info (undo is disabled)")))
+  (cond ((numberp arg)			; Numeric arg sets span
+	 (setq glc-current-span (abs arg)))
+	((consp arg)			; C-u's multiply previous span by 4
+	 (setq glc-current-span (* (abs (car arg)) glc-default-span))
+	 (message "Current span is %d chars" glc-current-span))) ;todo: keep message with "waiting" and "is saved"
+  (cond ((< (prefix-numeric-value arg) 0)
+	 (setq glc-direction -1))
+	(t
+	 (setq glc-direction 1)))
+  (let (rev				; Reversed (and filtered) undo list
+	pos				; The pos we look for, nil until found
+	(n 0)				; Steps in undo list (length of 'rev')
+	(l buffer-undo-list) 
+	(passed-save-entry (not (buffer-modified-p)))
+	(new-probe-depth glc-probe-depth))
+    ;; Walk back and forth in the buffer-undo-list, each time one step deeper,
+    ;; until we can walk back the whole list with a 'pos' that is not coming
+    ;; too close to another edit.
+    (while (null pos)
+      (setq new-probe-depth (+ new-probe-depth glc-direction))
+      (if (< glc-direction 0)
+	  (setq rev ()
+		n 0
+		l buffer-undo-list
+		passed-save-entry (not (buffer-modified-p))))
+      (if (< new-probe-depth 1)
+	  (error "No later change info"))
+      (if (> n 150)
+	  (message "working..."))
+      ;; Walk forward in buffer-undo-list, glc-probe-depth steps.
+      ;; Build reverse list along the way
+      (while (< n new-probe-depth)
+	(cond ((null l)
+	       ;(setq this-command t)	; Disrupt repeat sequence
+	       (error "No further change info"))
+	      ((glc-is-positionable (car l))
+	       (setq n (1+ n)
+		     rev (cons (car l) rev)))
+	      ((or passed-save-entry (glc-is-filetime (car l)))
+	       (setq passed-save-entry t)))
+	(setq l (cdr l)))
+      ;; Walk back in reverse list, from older to newer edits.
+      ;; Adjusting pos along the way.
+      (setq pos (glc-adjust-list rev)))
+    ;; Found a place not previously visited, in 'pos'.
+    ;; (An error have been issued if nothing (more) found.)
+    (if (> n 150)
+	(message nil))			; remove message "working..."
+    (if (and (= glc-current-span 0) (glc-get-descript (car rev) n))
+	(message "%s" (glc-get-descript (car rev) n))
+      ;; else
+      (if passed-save-entry
+	  (message "(This change is saved)")))
+    (setq glc-probe-depth new-probe-depth)
+    (goto-char pos)))
+
+;;;###autoload
+(defun goto-last-change-reverse (arg)
+  "Go back to more recent changes after \\[goto-last-change] have been used.
+See `goto-last-change' for use of prefix argument."
+  (interactive "P")
+  ;; Negate arg, all kinds
+  (cond ((eq arg nil)  (setq arg '-))
+	((eq arg '-)   (setq arg nil))
+	((listp arg)   (setq arg (list (- (car arg)))))
+	(t (setq arg   (- arg))))
+  ;; Make 'goto-last-change-reverse' look like 'goto-last-change'
+  (cond ((eq last-command this-command)
+	 (setq last-command 'goto-last-change)))
+  (setq this-command 'goto-last-change)
+  ;; Call 'goto-last-change' to do the job
+  (goto-last-change arg))
+
+(provide 'goto-chg)
+
+;;; goto-chg.el ends here
.emacs.d/elpa/goto-chg-20131228.659/goto-chg.elc
Binary file
.emacs.d/elpa/undo-tree-20170706.246/undo-tree-autoloads.el
@@ -0,0 +1,59 @@
+;;; undo-tree-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "undo-tree" "undo-tree.el" (22968 12682 18450
+;;;;;;  681000))
+;;; Generated autoloads from undo-tree.el
+
+(autoload 'undo-tree-mode "undo-tree" "\
+Toggle undo-tree mode.
+With no argument, this command toggles the mode.
+A positive prefix argument turns the mode on.
+A negative prefix argument turns it off.
+
+Undo-tree-mode replaces Emacs' standard undo feature with a more
+powerful yet easier to use version, that treats the undo history
+as what it is: a tree.
+
+The following keys are available in `undo-tree-mode':
+
+  \\{undo-tree-map}
+
+Within the undo-tree visualizer, the following keys are available:
+
+  \\{undo-tree-visualizer-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-undo-tree-mode nil "\
+Non-nil if Global Undo-Tree mode is enabled.
+See the `global-undo-tree-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-undo-tree-mode'.")
+
+(custom-autoload 'global-undo-tree-mode "undo-tree" nil)
+
+(autoload 'global-undo-tree-mode "undo-tree" "\
+Toggle Undo-Tree mode in all buffers.
+With prefix ARG, enable Global Undo-Tree mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Undo-Tree mode is enabled in all buffers where
+`turn-on-undo-tree-mode' would do it.
+See `undo-tree-mode' for more information on Undo-Tree mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; undo-tree-autoloads.el ends here
.emacs.d/elpa/undo-tree-20170706.246/undo-tree-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "undo-tree" "20170706.246" "Treat undo history as a tree" 'nil :commit "e9a9102f515acd7523158f20e83f300600374989" :url "http://www.dr-qubit.org/emacs.php" :keywords '("convenience" "files" "undo" "redo" "history" "tree"))
.emacs.d/elpa/undo-tree-20170706.246/undo-tree.el
@@ -0,0 +1,4433 @@
+;;; undo-tree.el --- Treat undo history as a tree  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2009-2014  Free Software Foundation, Inc
+
+;; Author: Toby Cubitt <toby-undo-tree@dr-qubit.org>
+;; Maintainer: Toby Cubitt <toby-undo-tree@dr-qubit.org>
+;; Version: 0.6.6
+;; Package-Version: 20170706.246
+;; Keywords: convenience, files, undo, redo, history, tree
+;; URL: http://www.dr-qubit.org/emacs.php
+;; Repository: http://www.dr-qubit.org/git/undo-tree.git
+
+;; This file is part of Emacs.
+;;
+;; This file 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.
+;;
+;; This program 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;;
+;; Emacs has a powerful undo system. Unlike the standard undo/redo system in
+;; most software, it allows you to recover *any* past state of a buffer
+;; (whereas the standard undo/redo system can lose past states as soon as you
+;; redo). However, this power comes at a price: many people find Emacs' undo
+;; system confusing and difficult to use, spawning a number of packages that
+;; replace it with the less powerful but more intuitive undo/redo system.
+;;
+;; Both the loss of data with standard undo/redo, and the confusion of Emacs'
+;; undo, stem from trying to treat undo history as a linear sequence of
+;; changes. It's not. The `undo-tree-mode' provided by this package replaces
+;; Emacs' undo system with a system that treats undo history as what it is: a
+;; branching tree of changes. This simple idea allows the more intuitive
+;; behaviour of the standard undo/redo system to be combined with the power of
+;; never losing any history. An added side bonus is that undo history can in
+;; some cases be stored more efficiently, allowing more changes to accumulate
+;; before Emacs starts discarding history.
+;;
+;; The only downside to this more advanced yet simpler undo system is that it
+;; was inspired by Vim. But, after all, most successful religions steal the
+;; best ideas from their competitors!
+;;
+;;
+;; Installation
+;; ============
+;;
+;; This package has only been tested with Emacs versions 24 and CVS. It should
+;; work in Emacs versions 22 and 23 too, but will not work without
+;; modifications in earlier versions of Emacs.
+;;
+;; To install `undo-tree-mode', make sure this file is saved in a directory in
+;; your `load-path', and add the line:
+;;
+;;   (require 'undo-tree)
+;;
+;; to your .emacs file. Byte-compiling undo-tree.el is recommended (e.g. using
+;; "M-x byte-compile-file" from within emacs).
+;;
+;; If you want to replace the standard Emacs' undo system with the
+;; `undo-tree-mode' system in all buffers, you can enable it globally by
+;; adding:
+;;
+;;   (global-undo-tree-mode)
+;;
+;; to your .emacs file.
+;;
+;;
+;; Quick-Start
+;; ===========
+;;
+;; If you're the kind of person who likes to jump in the car and drive,
+;; without bothering to first figure out whether the button on the left dips
+;; the headlights or operates the ejector seat (after all, you'll soon figure
+;; it out when you push it), then here's the minimum you need to know:
+;;
+;; `undo-tree-mode' and `global-undo-tree-mode'
+;;   Enable undo-tree mode (either in the current buffer or globally).
+;;
+;; C-_  C-/  (`undo-tree-undo')
+;;   Undo changes.
+;;
+;; M-_  C-?  (`undo-tree-redo')
+;;   Redo changes.
+;;
+;; `undo-tree-switch-branch'
+;;   Switch undo-tree branch.
+;;   (What does this mean? Better press the button and see!)
+;;
+;; C-x u  (`undo-tree-visualize')
+;;   Visualize the undo tree.
+;;   (Better try pressing this button too!)
+;;
+;; C-x r u  (`undo-tree-save-state-to-register')
+;;   Save current buffer state to register.
+;;
+;; C-x r U  (`undo-tree-restore-state-from-register')
+;;   Restore buffer state from register.
+;;
+;;
+;;
+;; In the undo-tree visualizer:
+;;
+;; <up>  p  C-p  (`undo-tree-visualize-undo')
+;;   Undo changes.
+;;
+;; <down>  n  C-n  (`undo-tree-visualize-redo')
+;;   Redo changes.
+;;
+;; <left>  b  C-b  (`undo-tree-visualize-switch-branch-left')
+;;   Switch to previous undo-tree branch.
+;;
+;; <right>  f  C-f  (`undo-tree-visualize-switch-branch-right')
+;;   Switch to next undo-tree branch.
+;;
+;; C-<up>  M-{  (`undo-tree-visualize-undo-to-x')
+;;   Undo changes up to last branch point.
+;;
+;; C-<down>  M-}  (`undo-tree-visualize-redo-to-x')
+;;   Redo changes down to next branch point.
+;;
+;; <down>  n  C-n  (`undo-tree-visualize-redo')
+;;   Redo changes.
+;;
+;; <mouse-1>  (`undo-tree-visualizer-mouse-set')
+;;   Set state to node at mouse click.
+;;
+;; t  (`undo-tree-visualizer-toggle-timestamps')
+;;   Toggle display of time-stamps.
+;;
+;; d  (`undo-tree-visualizer-toggle-diff')
+;;   Toggle diff display.
+;;
+;; s  (`undo-tree-visualizer-selection-mode')
+;;   Toggle keyboard selection mode.
+;;
+;; q  (`undo-tree-visualizer-quit')
+;;   Quit undo-tree-visualizer.
+;;
+;; C-q  (`undo-tree-visualizer-abort')
+;;   Abort undo-tree-visualizer.
+;;
+;; ,  <
+;;   Scroll left.
+;;
+;; .  >
+;;   Scroll right.
+;;
+;; <pgup>  M-v
+;;   Scroll up.
+;;
+;; <pgdown>  C-v
+;;   Scroll down.
+;;
+;;
+;;
+;; In visualizer selection mode:
+;;
+;; <up>  p  C-p  (`undo-tree-visualizer-select-previous')
+;;   Select previous node.
+;;
+;; <down>  n  C-n  (`undo-tree-visualizer-select-next')
+;;   Select next node.
+;;
+;; <left>  b  C-b  (`undo-tree-visualizer-select-left')
+;;   Select left sibling node.
+;;
+;; <right>  f  C-f  (`undo-tree-visualizer-select-right')
+;;   Select right sibling node.
+;;
+;; <pgup>  M-v
+;;   Select node 10 above.
+;;
+;; <pgdown>  C-v
+;;   Select node 10 below.
+;;
+;; <enter>  (`undo-tree-visualizer-set')
+;;   Set state to selected node and exit selection mode.
+;;
+;; s  (`undo-tree-visualizer-mode')
+;;   Exit selection mode.
+;;
+;; t  (`undo-tree-visualizer-toggle-timestamps')
+;;   Toggle display of time-stamps.
+;;
+;; d  (`undo-tree-visualizer-toggle-diff')
+;;   Toggle diff display.
+;;
+;; q  (`undo-tree-visualizer-quit')
+;;   Quit undo-tree-visualizer.
+;;
+;; C-q  (`undo-tree-visualizer-abort')
+;;   Abort undo-tree-visualizer.
+;;
+;; ,  <
+;;   Scroll left.
+;;
+;; .  >
+;;   Scroll right.
+;;
+;;
+;;
+;; Persistent undo history:
+;;
+;; Note: Requires Emacs version 24.3 or higher.
+;;
+;; `undo-tree-auto-save-history' (variable)
+;;    automatically save and restore undo-tree history along with buffer
+;;    (disabled by default)
+;;
+;; `undo-tree-save-history' (command)
+;;    manually save undo history to file
+;;
+;; `undo-tree-load-history' (command)
+;;    manually load undo history from file
+;;
+;;
+;;
+;; Compressing undo history:
+;;
+;;   Undo history files cannot grow beyond the maximum undo tree size, which
+;;   is limited by `undo-limit', `undo-strong-limit' and
+;;   `undo-outer-limit'. Nevertheless, undo history files can grow quite
+;;   large. If you want to automatically compress undo history, add the
+;;   following advice to your .emacs file (replacing ".gz" with the filename
+;;   extension of your favourite compression algorithm):
+;;
+;;   (defadvice undo-tree-make-history-save-file-name
+;;     (after undo-tree activate)
+;;     (setq ad-return-value (concat ad-return-value ".gz")))
+;;
+;;
+;;
+;;
+;; Undo Systems
+;; ============
+;;
+;; To understand the different undo systems, it's easiest to consider an
+;; example. Imagine you make a few edits in a buffer. As you edit, you
+;; accumulate a history of changes, which we might visualize as a string of
+;; past buffer states, growing downwards:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o  (first edit)
+;;                                |
+;;                                |
+;;                                o  (second edit)
+;;                                |
+;;                                |
+;;                                x  (current buffer state)
+;;
+;;
+;; Now imagine that you undo the last two changes. We can visualize this as
+;; rewinding the current state back two steps:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                x  (current buffer state)
+;;                                |
+;;                                |
+;;                                o
+;;                                |
+;;                                |
+;;                                o
+;;
+;;
+;; However, this isn't a good representation of what Emacs' undo system
+;; does. Instead, it treats the undos as *new* changes to the buffer, and adds
+;; them to the history:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o  (first edit)
+;;                                |
+;;                                |
+;;                                o  (second edit)
+;;                                |
+;;                                |
+;;                                x  (buffer state before undo)
+;;                                |
+;;                                |
+;;                                o  (first undo)
+;;                                |
+;;                                |
+;;                                x  (second undo)
+;;
+;;
+;; Actually, since the buffer returns to a previous state after an undo,
+;; perhaps a better way to visualize it is to imagine the string of changes
+;; turning back on itself:
+;;
+;;        (initial buffer state)  o
+;;                                |
+;;                                |
+;;                  (first edit)  o  x  (second undo)
+;;                                |  |
+;;                                |  |
+;;                 (second edit)  o  o  (first undo)
+;;                                | /
+;;                                |/
+;;                                o  (buffer state before undo)
+;;
+;; Treating undos as new changes might seem a strange thing to do. But the
+;; advantage becomes clear as soon as we imagine what happens when you edit
+;; the buffer again. Since you've undone a couple of changes, new edits will
+;; branch off from the buffer state that you've rewound to. Conceptually, it
+;; looks like this:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o
+;;                                |\
+;;                                | \
+;;                                o  x  (new edit)
+;;                                |
+;;                                |
+;;                                o
+;;
+;; The standard undo/redo system only lets you go backwards and forwards
+;; linearly. So as soon as you make that new edit, it discards the old
+;; branch. Emacs' undo just keeps adding changes to the end of the string. So
+;; the undo history in the two systems now looks like this:
+;;
+;;            Undo/Redo:                      Emacs' undo
+;;
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               o                                o  o
+;;               .\                               |  |\
+;;               . \                              |  | \
+;;               .  x  (new edit)                 o  o  |
+;;   (discarded  .                                | /   |
+;;     branch)   .                                |/    |
+;;               .                                o     |
+;;                                                      |
+;;                                                      |
+;;                                                      x  (new edit)
+;;
+;; Now, what if you change your mind about those undos, and decide you did
+;; like those other changes you'd made after all? With the standard undo/redo
+;; system, you're lost. There's no way to recover them, because that branch
+;; was discarded when you made the new edit.
+;;
+;; However, in Emacs' undo system, those old buffer states are still there in
+;; the undo history. You just have to rewind back through the new edit, and
+;; back through the changes made by the undos, until you reach them. Of
+;; course, since Emacs treats undos (even undos of undos!) as new changes,
+;; you're really weaving backwards and forwards through the history, all the
+;; time adding new changes to the end of the string as you go:
+;;
+;;                       o
+;;                       |
+;;                       |
+;;                       o  o     o  (undo new edit)
+;;                       |  |\    |\
+;;                       |  | \   | \
+;;                       o  o  |  |  o  (undo the undo)
+;;                       | /   |  |  |
+;;                       |/    |  |  |
+;;      (trying to get   o     |  |  x  (undo the undo)
+;;       to this state)        | /
+;;                             |/
+;;                             o
+;;
+;; So far, this is still reasonably intuitive to use. It doesn't behave so
+;; differently to standard undo/redo, except that by going back far enough you
+;; can access changes that would be lost in standard undo/redo.
+;;
+;; However, imagine that after undoing as just described, you decide you
+;; actually want to rewind right back to the initial state. If you're lucky,
+;; and haven't invoked any command since the last undo, you can just keep on
+;; undoing until you get back to the start:
+;;
+;;      (trying to get   o              x  (got there!)
+;;       to this state)  |              |
+;;                       |              |
+;;                       o  o     o     o  (keep undoing)
+;;                       |  |\    |\    |
+;;                       |  | \   | \   |
+;;                       o  o  |  |  o  o  (keep undoing)
+;;                       | /   |  |  | /
+;;                       |/    |  |  |/
+;;      (already undid   o     |  |  o  (got this far)
+;;       to this state)        | /
+;;                             |/
+;;                             o
+;;
+;; But if you're unlucky, and you happen to have moved the point (say) after
+;; getting to the state labelled "got this far", then you've "broken the undo
+;; chain". Hold on to something solid, because things are about to get
+;; hairy. If you try to undo now, Emacs thinks you're trying to undo the
+;; undos! So to get back to the initial state you now have to rewind through
+;; *all* the changes, including the undos you just did:
+;;
+;;      (trying to get   o                          x  (finally got there!)
+;;       to this state)  |                          |
+;;                       |                          |
+;;                       o  o     o     o     o     o
+;;                       |  |\    |\    |\    |\    |
+;;                       |  | \   | \   | \   | \   |
+;;                       o  o  |  |  o  o  |  |  o  o
+;;                       | /   |  |  | /   |  |  | /
+;;                       |/    |  |  |/    |  |  |/
+;;      (already undid   o     |  |  o<.   |  |  o
+;;       to this state)        | /     :   | /
+;;                             |/      :   |/
+;;                             o       :   o
+;;                                     :
+;;                             (got this far, but
+;;                              broke the undo chain)
+;;
+;; Confused?
+;;
+;; In practice you can just hold down the undo key until you reach the buffer
+;; state that you want. But whatever you do, don't move around in the buffer
+;; to *check* that you've got back to where you want! Because you'll break the
+;; undo chain, and then you'll have to traverse the entire string of undos
+;; again, just to get back to the point at which you broke the
+;; chain. Undo-in-region and commands such as `undo-only' help to make using
+;; Emacs' undo a little easier, but nonetheless it remains confusing for many
+;; people.
+;;
+;;
+;; So what does `undo-tree-mode' do? Remember the diagram we drew to represent
+;; the history we've been discussing (make a few edits, undo a couple of them,
+;; and edit again)? The diagram that conceptually represented our undo
+;; history, before we started discussing specific undo systems? It looked like
+;; this:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o
+;;                                |\
+;;                                | \
+;;                                o  x  (current state)
+;;                                |
+;;                                |
+;;                                o
+;;
+;; Well, that's *exactly* what the undo history looks like to
+;; `undo-tree-mode'.  It doesn't discard the old branch (as standard undo/redo
+;; does), nor does it treat undos as new changes to be added to the end of a
+;; linear string of buffer states (as Emacs' undo does). It just keeps track
+;; of the tree of branching changes that make up the entire undo history.
+;;
+;; If you undo from this point, you'll rewind back up the tree to the previous
+;; state:
+;;
+;;                                o
+;;                                |
+;;                                |
+;;                                x  (undo)
+;;                                |\
+;;                                | \
+;;                                o  o
+;;                                |
+;;                                |
+;;                                o
+;;
+;; If you were to undo again, you'd rewind back to the initial state. If on
+;; the other hand you redo the change, you'll end up back at the bottom of the
+;; most recent branch:
+;;
+;;                                o  (undo takes you here)
+;;                                |
+;;                                |
+;;                                o  (start here)
+;;                                |\
+;;                                | \
+;;                                o  x  (redo takes you here)
+;;                                |
+;;                                |
+;;                                o
+;;
+;; So far, this is just like the standard undo/redo system. But what if you
+;; want to return to a buffer state located on a previous branch of the
+;; history? Since `undo-tree-mode' keeps the entire history, you simply need
+;; to tell it to switch to a different branch, and then redo the changes you
+;; want:
+;;
+;;                                o
+;;                                |
+;;                                |
+;;                                o  (start here, but switch
+;;                                |\  to the other branch)
+;;                                | \
+;;                        (redo)  o  o
+;;                                |
+;;                                |
+;;                        (redo)  x
+;;
+;; Now you're on the other branch, if you undo and redo changes you'll stay on
+;; that branch, moving up and down through the buffer states located on that
+;; branch. Until you decide to switch branches again, of course.
+;;
+;; Real undo trees might have multiple branches and sub-branches:
+;;
+;;                                o
+;;                            ____|______
+;;                           /           \
+;;                          o             o
+;;                      ____|__         __|
+;;                     /    |  \       /   \
+;;                    o     o   o     o     x
+;;                    |               |
+;;                   / \             / \
+;;                  o   o           o   o
+;;
+;; Trying to imagine what Emacs' undo would do as you move about such a tree
+;; will likely frazzle your brain circuits! But in `undo-tree-mode', you're
+;; just moving around this undo history tree. Most of the time, you'll
+;; probably only need to stay on the most recent branch, in which case it
+;; behaves like standard undo/redo, and is just as simple to understand. But
+;; if you ever need to recover a buffer state on a different branch, the
+;; possibility of switching between branches and accessing the full undo
+;; history is still there.
+;;
+;;
+;;
+;; The Undo-Tree Visualizer
+;; ========================
+;;
+;; Actually, it gets better. You don't have to imagine all these tree
+;; diagrams, because `undo-tree-mode' includes an undo-tree visualizer which
+;; draws them for you! In fact, it draws even better diagrams: it highlights
+;; the node representing the current buffer state, it highlights the current
+;; branch, and you can toggle the display of time-stamps (by hitting "t") and
+;; a diff of the undo changes (by hitting "d"). (There's one other tiny
+;; difference: the visualizer puts the most recent branch on the left rather
+;; than the right.)
+;;
+;; Bring up the undo tree visualizer whenever you want by hitting "C-x u".
+;;
+;; In the visualizer, the usual keys for moving up and down a buffer instead
+;; move up and down the undo history tree (e.g. the up and down arrow keys, or
+;; "C-n" and "C-p"). The state of the "parent" buffer (the buffer whose undo
+;; history you are visualizing) is updated as you move around the undo tree in
+;; the visualizer. If you reach a branch point in the visualizer, the usual
+;; keys for moving forward and backward in a buffer instead switch branch
+;; (e.g. the left and right arrow keys, or "C-f" and "C-b").
+;;
+;; Clicking with the mouse on any node in the visualizer will take you
+;; directly to that node, resetting the state of the parent buffer to the
+;; state represented by that node.
+;;
+;; You can also select nodes directly using the keyboard, by hitting "s" to
+;; toggle selection mode. The usual motion keys now allow you to move around
+;; the tree without changing the parent buffer. Hitting <enter> will reset the
+;; state of the parent buffer to the state represented by the currently
+;; selected node.
+;;
+;; It can be useful to see how long ago the parent buffer was in the state
+;; represented by a particular node in the visualizer. Hitting "t" in the
+;; visualizer toggles the display of time-stamps for all the nodes. (Note
+;; that, because of the way `undo-tree-mode' works, these time-stamps may be
+;; somewhat later than the true times, especially if it's been a long time
+;; since you last undid any changes.)
+;;
+;; To get some idea of what changes are represented by a given node in the
+;; tree, it can be useful to see a diff of the changes. Hit "d" in the
+;; visualizer to toggle a diff display. This normally displays a diff between
+;; the current state and the previous one, i.e. it shows you the changes that
+;; will be applied if you undo (move up the tree). However, the diff display
+;; really comes into its own in the visualizer's selection mode (see above),
+;; where it instead shows a diff between the current state and the currently
+;; selected state, i.e. it shows you the changes that will be applied if you
+;; reset to the selected state.
+;;
+;; (Note that the diff is generated by the Emacs `diff' command, and is
+;; displayed using `diff-mode'. See the corresponding customization groups if
+;; you want to customize the diff display.)
+;;
+;; Finally, hitting "q" will quit the visualizer, leaving the parent buffer in
+;; whatever state you ended at. Hitting "C-q" will abort the visualizer,
+;; returning the parent buffer to whatever state it was originally in when the
+;; visualizer was invoked.
+;;
+;;
+;;
+;; Undo-in-Region
+;; ==============
+;;
+;; Emacs allows a very useful and powerful method of undoing only selected
+;; changes: when a region is active, only changes that affect the text within
+;; that region will be undone. With the standard Emacs undo system, changes
+;; produced by undoing-in-region naturally get added onto the end of the
+;; linear undo history:
+;;
+;;                       o
+;;                       |
+;;                       |  x  (second undo-in-region)
+;;                       o  |
+;;                       |  |
+;;                       |  o  (first undo-in-region)
+;;                       o  |
+;;                       | /
+;;                       |/
+;;                       o
+;;
+;; You can of course redo these undos-in-region as usual, by undoing the
+;; undos:
+;;
+;;                       o
+;;                       |
+;;                       |  o_
+;;                       o  | \
+;;                       |  |  |
+;;                       |  o  o  (undo the undo-in-region)
+;;                       o  |  |
+;;                       | /   |
+;;                       |/    |
+;;                       o     x  (undo the undo-in-region)
+;;
+;;
+;; In `undo-tree-mode', undo-in-region works much the same way: when there's
+;; an active region, undoing only undoes changes that affect that region. In
+;; `undo-tree-mode', redoing when there's an active region similarly only
+;; redoes changes that affect that region.
+;;
+;; However, the way these undo- and redo-in-region changes are recorded in the
+;; undo history is quite different. The good news is, you don't need to
+;; understand this to use undo- and redo-in-region in `undo-tree-mode' - just
+;; go ahead and use them! They'll probably work as you expect. But if you're
+;; masochistic enough to want to understand conceptually what's happening to
+;; the undo tree as you undo- and redo-in-region, then read on...
+;;
+;;
+;; Undo-in-region creates a new branch in the undo history. The new branch
+;; consists of an undo step that undoes some of the changes that affect the
+;; current region, and another step that undoes the remaining changes needed
+;; to rejoin the previous undo history.
+;;
+;;      Previous undo history                Undo-in-region
+;;
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               |                                |
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               |                                |
+;;               o                                o_
+;;               |                                | \
+;;               |                                |  x  (undo-in-region)
+;;               |                                |  |
+;;               x                                o  o
+;;
+;; As long as you don't change the active region after undoing-in-region,
+;; continuing to undo-in-region extends the new branch, pulling more changes
+;; that affect the current region into an undo step immediately above your
+;; current location in the undo tree, and pushing the point at which the new
+;; branch is attached further up the tree:
+;;
+;;      First undo-in-region                 Second undo-in-region
+;;
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               |                                |
+;;               o                                o_
+;;               |                                | \
+;;               |                                |  x  (undo-in-region)
+;;               |                                |  |
+;;               o_                               o  |
+;;               | \                              |  |
+;;		 |  x                             |  o
+;;		 |  |                             |  |
+;;		 o  o     			  o  o
+;;
+;; Redoing takes you back down the undo tree, as usual (as long as you haven't
+;; changed the active region after undoing-in-region, it doesn't matter if it
+;; is still active):
+;;
+;;                       o
+;;			 |
+;;			 |
+;;			 |
+;;			 o_
+;;			 | \
+;;			 |  o
+;;			 |  |
+;;			 o  |
+;;			 |  |
+;;			 |  o  (redo)
+;;			 |  |
+;;			 o  x  (redo)
+;;
+;;
+;; What about redo-in-region? Obviously, redo-in-region only makes sense if
+;; you have already undone some changes, so that there are some changes to
+;; redo! Redoing-in-region splits off a new branch of the undo history below
+;; your current location in the undo tree. This time, the new branch consists
+;; of a first redo step that redoes some of the redo changes that affect the
+;; current region, followed by *all* the remaining redo changes.
+;;
+;;      Previous undo history                Redo-in-region
+;;
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               |                                |
+;;               x                                o_
+;;               |                                | \
+;;               |                                |  x  (redo-in-region)
+;;               |                                |  |
+;;               o                                o  |
+;;               |                                |  |
+;;               |                                |  |
+;;               |                                |  |
+;;               o                                o  o
+;;
+;; As long as you don't change the active region after redoing-in-region,
+;; continuing to redo-in-region extends the new branch, pulling more redo
+;; changes into a redo step immediately below your current location in the
+;; undo tree.
+;;
+;;      First redo-in-region                 Second redo-in-region
+;;
+;;               o                                 o
+;;               |                                 |
+;;               |                                 |
+;;               |                                 |
+;;               o_                                o_
+;;               | \                               | \
+;;               |  x                              |  o
+;;               |  |                              |  |
+;;               o  |                              o  |
+;;               |  |                              |  |
+;;               |  |                              |  x  (redo-in-region)
+;;               |  |                              |  |
+;;               o  o                              o  o
+;;
+;; Note that undo-in-region and redo-in-region only ever add new changes to
+;; the undo tree, they *never* modify existing undo history. So you can always
+;; return to previous buffer states by switching to a previous branch of the
+;; tree.
+
+
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'diff)
+
+
+
+;;; =====================================================================
+;;;              Compatibility hacks for older Emacsen
+
+;; `characterp' isn't defined in Emacs versions < 23
+(unless (fboundp 'characterp)
+  (defalias 'characterp 'char-valid-p))
+
+;; `region-active-p' isn't defined in Emacs versions < 23
+(unless (fboundp 'region-active-p)
+  (defun region-active-p () (and transient-mark-mode mark-active)))
+
+
+;; `registerv' defstruct isn't defined in Emacs versions < 24
+(unless (fboundp 'registerv-make)
+  (defmacro registerv-make (data &rest _dummy) data))
+
+(unless (fboundp 'registerv-data)
+  (defmacro registerv-data (data) data))
+
+
+;; `diff-no-select' and `diff-file-local-copy' aren't defined in Emacs
+;; versions < 24 (copied and adapted from Emacs 24)
+(unless (fboundp 'diff-no-select)
+  (defun diff-no-select (old new &optional switches no-async buf)
+    ;; Noninteractive helper for creating and reverting diff buffers
+    (unless (bufferp new) (setq new (expand-file-name new)))
+    (unless (bufferp old) (setq old (expand-file-name old)))
+    (or switches (setq switches diff-switches)) ; If not specified, use default.
+    (unless (listp switches) (setq switches (list switches)))
+    (or buf (setq buf (get-buffer-create "*Diff*")))
+    (let* ((old-alt (diff-file-local-copy old))
+	   (new-alt (diff-file-local-copy new))
+	   (command
+	    (mapconcat 'identity
+		       `(,diff-command
+			 ;; Use explicitly specified switches
+			 ,@switches
+			 ,@(mapcar #'shell-quote-argument
+				   (nconc
+				    (when (or old-alt new-alt)
+				      (list "-L" (if (stringp old)
+						     old (prin1-to-string old))
+					    "-L" (if (stringp new)
+						     new (prin1-to-string new))))
+				    (list (or old-alt old)
+					  (or new-alt new)))))
+		       " "))
+	   (thisdir default-directory))
+      (with-current-buffer buf
+	(setq buffer-read-only t)
+	(buffer-disable-undo (current-buffer))
+	(let ((inhibit-read-only t))
+	  (erase-buffer))
+	(buffer-enable-undo (current-buffer))
+	(diff-mode)
+	(set (make-local-variable 'revert-buffer-function)
+	     (lambda (_ignore-auto _noconfirm)
+	       (diff-no-select old new switches no-async (current-buffer))))
+	(setq default-directory thisdir)
+	(let ((inhibit-read-only t))
+	  (insert command "\n"))
+	(if (and (not no-async) (fboundp 'start-process))
+	    (let ((proc (start-process "Diff" buf shell-file-name
+				       shell-command-switch command)))
+	      (set-process-filter proc 'diff-process-filter)
+	      (set-process-sentinel
+	       proc (lambda (proc _msg)
+		      (with-current-buffer (process-buffer proc)
+			(diff-sentinel (process-exit-status proc))
+			(if old-alt (delete-file old-alt))
+			(if new-alt (delete-file new-alt))))))
+	  ;; Async processes aren't available.
+	  (let ((inhibit-read-only t))
+	    (diff-sentinel
+	     (call-process shell-file-name nil buf nil
+			   shell-command-switch command))
+	    (if old-alt (delete-file old-alt))
+	    (if new-alt (delete-file new-alt)))))
+      buf)))
+
+(unless (fboundp 'diff-file-local-copy)
+  (defun diff-file-local-copy (file-or-buf)
+    (if (bufferp file-or-buf)
+	(with-current-buffer file-or-buf
+	  (let ((tempfile (make-temp-file "buffer-content-")))
+	    (write-region nil nil tempfile nil 'nomessage)
+	    tempfile))
+      (file-local-copy file-or-buf))))
+
+
+;; `user-error' isn't defined in Emacs < 24.3
+(unless (fboundp 'user-error)
+  (defalias 'user-error 'error)
+  ;; prevent debugger being called on user errors
+  (add-to-list 'debug-ignored-errors "^No further undo information")
+  (add-to-list 'debug-ignored-errors "^No further redo information")
+  (add-to-list 'debug-ignored-errors "^No further redo information for region"))
+
+
+
+
+
+;;; =====================================================================
+;;;              Global variables and customization options
+
+(defvar buffer-undo-tree nil
+  "Tree of undo entries in current buffer.")
+(put 'buffer-undo-tree 'permanent-local t)
+(make-variable-buffer-local 'buffer-undo-tree)
+
+
+(defgroup undo-tree nil
+  "Tree undo/redo."
+  :group 'undo)
+
+(defcustom undo-tree-mode-lighter " Undo-Tree"
+  "Lighter displayed in mode line
+when `undo-tree-mode' is enabled."
+  :group 'undo-tree
+  :type 'string)
+
+
+(defcustom undo-tree-incompatible-major-modes '(term-mode)
+  "List of major-modes in which `undo-tree-mode' should not be enabled.
+\(See `turn-on-undo-tree-mode'.\)"
+  :group 'undo-tree
+  :type '(repeat symbol))
+
+
+(defcustom undo-tree-enable-undo-in-region t
+  "When non-nil, enable undo-in-region.
+
+When undo-in-region is enabled, undoing or redoing when the
+region is active (in `transient-mark-mode') or with a prefix
+argument (not in `transient-mark-mode') only undoes changes
+within the current region."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-auto-save-history nil
+  "When non-nil, `undo-tree-mode' will save undo history to file
+when a buffer is saved to file.
+
+It will automatically load undo history when a buffer is loaded
+from file, if an undo save file exists.
+
+By default, undo-tree history is saved to a file called
+\".<buffer-file-name>.~undo-tree~\" in the same directory as the
+file itself. To save under a different directory, customize
+`undo-tree-history-directory-alist' (see the documentation for
+that variable for details).
+
+WARNING! `undo-tree-auto-save-history' will not work properly in
+Emacs versions prior to 24.3, so it cannot be enabled via
+the customization interface in versions earlier than that one. To
+ignore this warning and enable it regardless, set
+`undo-tree-auto-save-history' to a non-nil value outside of
+customize."
+  :group 'undo-tree
+  :type (if (version-list-< (version-to-list emacs-version) '(24 3))
+	    '(choice (const :tag "<disabled>" nil))
+	  'boolean))
+
+
+(defcustom undo-tree-history-directory-alist nil
+  "Alist of filename patterns and undo history directory names.
+Each element looks like (REGEXP . DIRECTORY).  Undo history for
+files with names matching REGEXP will be saved in DIRECTORY.
+DIRECTORY may be relative or absolute.  If it is absolute, so
+that all matching files are backed up into the same directory,
+the file names in this directory will be the full name of the
+file backed up with all directory separators changed to `!' to
+prevent clashes.  This will not work correctly if your filesystem
+truncates the resulting name.
+
+For the common case of all backups going into one directory, the
+alist should contain a single element pairing \".\" with the
+appropriate directory name.
+
+If this variable is nil, or it fails to match a filename, the
+backup is made in the original file's directory.
+
+On MS-DOS filesystems without long names this variable is always
+ignored."
+  :group 'undo-tree
+  :type '(repeat (cons (regexp :tag "Regexp matching filename")
+		       (directory :tag "Undo history directory name"))))
+
+
+
+(defcustom undo-tree-visualizer-relative-timestamps t
+  "When non-nil, display times relative to current time
+when displaying time stamps in visualizer.
+
+Otherwise, display absolute times."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-visualizer-timestamps nil
+  "When non-nil, display time-stamps by default
+in undo-tree visualizer.
+
+\\<undo-tree-visualizer-mode-map>You can always toggle time-stamps on and off \
+using \\[undo-tree-visualizer-toggle-timestamps], regardless of the
+setting of this variable."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-visualizer-diff nil
+  "When non-nil, display diff by default in undo-tree visualizer.
+
+\\<undo-tree-visualizer-mode-map>You can always toggle the diff display \
+using \\[undo-tree-visualizer-toggle-diff], regardless of the
+setting of this variable."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-visualizer-lazy-drawing 100
+  "When non-nil, use lazy undo-tree drawing in visualizer.
+
+Setting this to a number causes the visualizer to switch to lazy
+drawing when the number of nodes in the tree is larger than this
+value.
+
+Lazy drawing means that only the visible portion of the tree will
+be drawn initially, and the tree will be extended later as
+needed. For the most part, the only visible effect of this is to
+significantly speed up displaying the visualizer for very large
+trees.
+
+There is one potential negative effect of lazy drawing. Other
+branches of the tree will only be drawn once the node from which
+they branch off becomes visible. So it can happen that certain
+portions of the tree that would be shown with lazy drawing
+disabled, will not be drawn immediately when it is
+enabled. However, this effect is quite rare in practice."
+  :group 'undo-tree
+  :type '(choice (const :tag "never" nil)
+		 (const :tag "always" t)
+		 (integer :tag "> size")))
+
+
+(defface undo-tree-visualizer-default-face
+  '((((class color)) :foreground "gray"))
+  "Face used to draw undo-tree in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-current-face
+  '((((class color)) :foreground "red"))
+  "Face used to highlight current undo-tree node in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-active-branch-face
+  '((((class color) (background dark))
+     (:foreground "white" :weight bold))
+    (((class color) (background light))
+     (:foreground "black" :weight bold)))
+  "Face used to highlight active undo-tree branch in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-register-face
+  '((((class color)) :foreground "yellow"))
+  "Face used to highlight undo-tree nodes saved to a register
+in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-unmodified-face
+  '((((class color)) :foreground "cyan"))
+  "Face used to highlight nodes corresponding to unmodified buffers
+in visualizer."
+  :group 'undo-tree)
+
+
+(defvar undo-tree-visualizer-parent-buffer nil
+  "Parent buffer in visualizer.")
+(put 'undo-tree-visualizer-parent-buffer 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-parent-buffer)
+
+;; stores modification time of parent buffer's file, if any
+(defvar undo-tree-visualizer-parent-mtime nil)
+(put 'undo-tree-visualizer-parent-mtime 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-parent-mtime)
+
+;; stores current horizontal spacing needed for drawing undo-tree
+(defvar undo-tree-visualizer-spacing nil)
+(put 'undo-tree-visualizer-spacing 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-spacing)
+
+;; calculate horizontal spacing required for drawing tree with current
+;; settings
+(defsubst undo-tree-visualizer-calculate-spacing ()
+  (if undo-tree-visualizer-timestamps
+      (if undo-tree-visualizer-relative-timestamps 9 13)
+    3))
+
+;; holds node that was current when visualizer was invoked
+(defvar undo-tree-visualizer-initial-node nil)
+(put 'undo-tree-visualizer-initial-node 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-initial-node)
+
+;; holds currently selected node in visualizer selection mode
+(defvar undo-tree-visualizer-selected-node nil)
+(put 'undo-tree-visualizer-selected-node 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-selected)
+
+;; used to store nodes at edge of currently drawn portion of tree
+(defvar undo-tree-visualizer-needs-extending-down nil)
+(put 'undo-tree-visualizer-needs-extending-down 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-needs-extending-down)
+(defvar undo-tree-visualizer-needs-extending-up nil)
+(put 'undo-tree-visualizer-needs-extending-up 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-needs-extending-up)
+
+;; dynamically bound to t when undoing from visualizer, to inhibit
+;; `undo-tree-kill-visualizer' hook function in parent buffer
+(defvar undo-tree-inhibit-kill-visualizer nil)
+
+;; can be let-bound to a face name, used in drawing functions
+(defvar undo-tree-insert-face nil)
+
+;; visualizer buffer names
+(defconst undo-tree-visualizer-buffer-name " *undo-tree*")
+(defconst undo-tree-diff-buffer-name "*undo-tree Diff*")
+
+;; install history-auto-save hooks
+(add-hook 'write-file-functions 'undo-tree-save-history-hook)
+(add-hook 'find-file-hook 'undo-tree-load-history-hook)
+
+
+
+
+;;; =================================================================
+;;;                          Default keymaps
+
+(defvar undo-tree-map nil
+  "Keymap used in undo-tree-mode.")
+
+(unless undo-tree-map
+  (let ((map (make-sparse-keymap)))
+    ;; remap `undo' and `undo-only' to `undo-tree-undo'
+    (define-key map [remap undo] 'undo-tree-undo)
+    (define-key map [remap undo-only] 'undo-tree-undo)
+    ;; bind standard undo bindings (since these match redo counterparts)
+    (define-key map (kbd "C-/") 'undo-tree-undo)
+    (define-key map "\C-_" 'undo-tree-undo)
+    ;; redo doesn't exist normally, so define our own keybindings
+    (define-key map (kbd "C-?") 'undo-tree-redo)
+    (define-key map (kbd "M-_") 'undo-tree-redo)
+    ;; just in case something has defined `redo'...
+    (define-key map [remap redo] 'undo-tree-redo)
+    ;; we use "C-x u" for the undo-tree visualizer
+    (define-key map (kbd "\C-x u") 'undo-tree-visualize)
+    ;; bind register commands
+    (define-key map (kbd "C-x r u") 'undo-tree-save-state-to-register)
+    (define-key map (kbd "C-x r U") 'undo-tree-restore-state-from-register)
+    ;; set keymap
+    (setq undo-tree-map map)))
+
+
+(defvar undo-tree-visualizer-mode-map nil
+  "Keymap used in undo-tree visualizer.")
+
+(unless undo-tree-visualizer-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; vertical motion keys undo/redo
+    (define-key map [remap previous-line] 'undo-tree-visualize-undo)
+    (define-key map [remap next-line] 'undo-tree-visualize-redo)
+    (define-key map [up] 'undo-tree-visualize-undo)
+    (define-key map "p" 'undo-tree-visualize-undo)
+    (define-key map "\C-p" 'undo-tree-visualize-undo)
+    (define-key map [down] 'undo-tree-visualize-redo)
+    (define-key map "n" 'undo-tree-visualize-redo)
+    (define-key map "\C-n" 'undo-tree-visualize-redo)
+    ;; horizontal motion keys switch branch
+    (define-key map [remap forward-char]
+      'undo-tree-visualize-switch-branch-right)
+    (define-key map [remap backward-char]
+      'undo-tree-visualize-switch-branch-left)
+    (define-key map [right] 'undo-tree-visualize-switch-branch-right)
+    (define-key map "f" 'undo-tree-visualize-switch-branch-right)
+    (define-key map "\C-f" 'undo-tree-visualize-switch-branch-right)
+    (define-key map [left] 'undo-tree-visualize-switch-branch-left)
+    (define-key map "b" 'undo-tree-visualize-switch-branch-left)
+    (define-key map "\C-b" 'undo-tree-visualize-switch-branch-left)
+    ;; paragraph motion keys undo/redo to significant points in tree
+    (define-key map [remap backward-paragraph] 'undo-tree-visualize-undo-to-x)
+    (define-key map [remap forward-paragraph] 'undo-tree-visualize-redo-to-x)
+    (define-key map "\M-{" 'undo-tree-visualize-undo-to-x)
+    (define-key map "\M-}" 'undo-tree-visualize-redo-to-x)
+    (define-key map [C-up] 'undo-tree-visualize-undo-to-x)
+    (define-key map [C-down] 'undo-tree-visualize-redo-to-x)
+    ;; mouse sets buffer state to node at click
+    (define-key map [mouse-1] 'undo-tree-visualizer-mouse-set)
+    ;; toggle timestamps
+    (define-key map "t" 'undo-tree-visualizer-toggle-timestamps)
+    ;; toggle diff
+    (define-key map "d" 'undo-tree-visualizer-toggle-diff)
+    ;; toggle selection mode
+    (define-key map "s" 'undo-tree-visualizer-selection-mode)
+    ;; horizontal scrolling may be needed if the tree is very wide
+    (define-key map "," 'undo-tree-visualizer-scroll-left)
+    (define-key map "." 'undo-tree-visualizer-scroll-right)
+    (define-key map "<" 'undo-tree-visualizer-scroll-left)
+    (define-key map ">" 'undo-tree-visualizer-scroll-right)
+    ;; vertical scrolling may be needed if the tree is very tall
+    (define-key map [next] 'undo-tree-visualizer-scroll-up)
+    (define-key map [prior] 'undo-tree-visualizer-scroll-down)
+    ;; quit/abort visualizer
+    (define-key map "q" 'undo-tree-visualizer-quit)
+    (define-key map "\C-q" 'undo-tree-visualizer-abort)
+    ;; set keymap
+    (setq undo-tree-visualizer-mode-map map)))
+
+
+(defvar undo-tree-visualizer-selection-mode-map nil
+  "Keymap used in undo-tree visualizer selection mode.")
+
+(unless undo-tree-visualizer-selection-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; vertical motion keys move up and down tree
+    (define-key map [remap previous-line]
+      'undo-tree-visualizer-select-previous)
+    (define-key map [remap next-line]
+      'undo-tree-visualizer-select-next)
+    (define-key map [up] 'undo-tree-visualizer-select-previous)
+    (define-key map "p" 'undo-tree-visualizer-select-previous)
+    (define-key map "\C-p" 'undo-tree-visualizer-select-previous)
+    (define-key map [down] 'undo-tree-visualizer-select-next)
+    (define-key map "n" 'undo-tree-visualizer-select-next)
+    (define-key map "\C-n" 'undo-tree-visualizer-select-next)
+    ;; vertical scroll keys move up and down quickly
+    (define-key map [next]
+      (lambda () (interactive) (undo-tree-visualizer-select-next 10)))
+    (define-key map [prior]
+      (lambda () (interactive) (undo-tree-visualizer-select-previous 10)))
+    ;; horizontal motion keys move to left and right siblings
+    (define-key map [remap forward-char] 'undo-tree-visualizer-select-right)
+    (define-key map [remap backward-char] 'undo-tree-visualizer-select-left)
+    (define-key map [right] 'undo-tree-visualizer-select-right)
+    (define-key map "f" 'undo-tree-visualizer-select-right)
+    (define-key map "\C-f" 'undo-tree-visualizer-select-right)
+    (define-key map [left] 'undo-tree-visualizer-select-left)
+    (define-key map "b" 'undo-tree-visualizer-select-left)
+    (define-key map "\C-b" 'undo-tree-visualizer-select-left)
+    ;; horizontal scroll keys move left or right quickly
+    (define-key map ","
+      (lambda () (interactive) (undo-tree-visualizer-select-left 10)))
+    (define-key map "."
+      (lambda () (interactive) (undo-tree-visualizer-select-right 10)))
+    (define-key map "<"
+      (lambda () (interactive) (undo-tree-visualizer-select-left 10)))
+    (define-key map ">"
+      (lambda () (interactive) (undo-tree-visualizer-select-right 10)))
+    ;; <enter> sets buffer state to node at point
+    (define-key map "\r" 'undo-tree-visualizer-set)
+    ;; mouse selects node at click
+    (define-key map [mouse-1] 'undo-tree-visualizer-mouse-select)
+    ;; toggle diff
+    (define-key map "d" 'undo-tree-visualizer-selection-toggle-diff)
+    ;; set keymap
+    (setq undo-tree-visualizer-selection-mode-map map)))
+
+
+(defvar undo-tree-old-undo-menu-item nil)
+
+(defun undo-tree-update-menu-bar ()
+  "Update `undo-tree-mode' Edit menu items."
+  (if undo-tree-mode
+      (progn
+	;; save old undo menu item, and install undo/redo menu items
+	(setq undo-tree-old-undo-menu-item
+	      (cdr (assq 'undo (lookup-key global-map [menu-bar edit]))))
+	(define-key (lookup-key global-map [menu-bar edit])
+	  [undo] '(menu-item "Undo" undo-tree-undo
+			     :enable (and undo-tree-mode
+					  (not buffer-read-only)
+					  (not (eq t buffer-undo-list))
+					  (not (eq nil buffer-undo-tree))
+					  (undo-tree-node-previous
+					   (undo-tree-current buffer-undo-tree)))
+			     :help "Undo last operation"))
+	(define-key-after (lookup-key global-map [menu-bar edit])
+	  [redo] '(menu-item "Redo" undo-tree-redo
+			     :enable (and undo-tree-mode
+					  (not buffer-read-only)
+					  (not (eq t buffer-undo-list))
+					  (not (eq nil buffer-undo-tree))
+					  (undo-tree-node-next
+					   (undo-tree-current buffer-undo-tree)))
+			     :help "Redo last operation")
+	  'undo))
+    ;; uninstall undo/redo menu items
+    (define-key (lookup-key global-map [menu-bar edit])
+      [undo] undo-tree-old-undo-menu-item)
+    (define-key (lookup-key global-map [menu-bar edit])
+      [redo] nil)))
+
+(add-hook 'menu-bar-update-hook 'undo-tree-update-menu-bar)
+
+
+
+
+
+;;; =====================================================================
+;;;                     Undo-tree data structure
+
+(defstruct
+  (undo-tree
+   :named
+   (:constructor nil)
+   (:constructor make-undo-tree
+                 (&aux
+                  (root (undo-tree-make-node nil nil))
+                  (current root)
+                  (size 0)
+		  (count 0)
+		  (object-pool (make-hash-table :test 'eq :weakness 'value))))
+   ;;(:copier nil)
+   )
+  root current size count object-pool)
+
+
+
+(defstruct
+  (undo-tree-node
+   (:type vector)   ; create unnamed struct
+   (:constructor nil)
+   (:constructor undo-tree-make-node
+                 (previous undo
+		  &optional redo
+                  &aux
+                  (timestamp (current-time))
+                  (branch 0)))
+   (:constructor undo-tree-make-node-backwards
+                 (next-node undo
+		  &optional redo
+                  &aux
+                  (next (list next-node))
+                  (timestamp (current-time))
+                  (branch 0)))
+   (:copier nil))
+  previous next undo redo timestamp branch meta-data)
+
+
+(defmacro undo-tree-node-p (n)
+  (let ((len (length (undo-tree-make-node nil nil))))
+    `(and (vectorp ,n) (= (length ,n) ,len))))
+
+
+
+(defstruct
+  (undo-tree-region-data
+   (:type vector)   ; create unnamed struct
+   (:constructor nil)
+   (:constructor undo-tree-make-region-data
+		 (&optional undo-beginning undo-end
+			     redo-beginning redo-end))
+   (:constructor undo-tree-make-undo-region-data
+		 (undo-beginning undo-end))
+   (:constructor undo-tree-make-redo-region-data
+		 (redo-beginning redo-end))
+   (:copier nil))
+  undo-beginning undo-end redo-beginning redo-end)
+
+
+(defmacro undo-tree-region-data-p (r)
+  (let ((len (length (undo-tree-make-region-data))))
+    `(and (vectorp ,r) (= (length ,r) ,len))))
+
+(defmacro undo-tree-node-clear-region-data (node)
+  `(setf (undo-tree-node-meta-data ,node)
+	 (delq nil
+	       (delq :region
+		     (plist-put (undo-tree-node-meta-data ,node)
+				:region nil)))))
+
+
+(defmacro undo-tree-node-undo-beginning (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-undo-beginning r))))
+
+(defmacro undo-tree-node-undo-end (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-undo-end r))))
+
+(defmacro undo-tree-node-redo-beginning (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-redo-beginning r))))
+
+(defmacro undo-tree-node-redo-end (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-redo-end r))))
+
+
+(defsetf undo-tree-node-undo-beginning (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-undo-beginning r) ,val)))
+
+(defsetf undo-tree-node-undo-end (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-undo-end r) ,val)))
+
+(defsetf undo-tree-node-redo-beginning (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-redo-beginning r) ,val)))
+
+(defsetf undo-tree-node-redo-end (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-redo-end r) ,val)))
+
+
+
+(defstruct
+  (undo-tree-visualizer-data
+   (:type vector)   ; create unnamed struct
+   (:constructor nil)
+   (:constructor undo-tree-make-visualizer-data
+		 (&optional lwidth cwidth rwidth marker))
+   (:copier nil))
+  lwidth cwidth rwidth marker)
+
+
+(defmacro undo-tree-visualizer-data-p (v)
+  (let ((len (length (undo-tree-make-visualizer-data))))
+    `(and (vectorp ,v) (= (length ,v) ,len))))
+
+(defun undo-tree-node-clear-visualizer-data (node)
+  (let ((plist (undo-tree-node-meta-data node)))
+    (if (eq (car plist) :visualizer)
+	(setf (undo-tree-node-meta-data node) (nthcdr 2 plist))
+      (while (and plist (not (eq (cadr plist) :visualizer)))
+	(setq plist (cdr plist)))
+      (if plist (setcdr plist (nthcdr 3 plist))))))
+
+(defmacro undo-tree-node-lwidth (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-lwidth v))))
+
+(defmacro undo-tree-node-cwidth (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-cwidth v))))
+
+(defmacro undo-tree-node-rwidth (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-rwidth v))))
+
+(defmacro undo-tree-node-marker (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-marker v))))
+
+
+(defsetf undo-tree-node-lwidth (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-lwidth v) ,val)))
+
+(defsetf undo-tree-node-cwidth (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-cwidth v) ,val)))
+
+(defsetf undo-tree-node-rwidth (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-rwidth v) ,val)))
+
+(defsetf undo-tree-node-marker (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-marker v) ,val)))
+
+
+
+(defstruct
+  (undo-tree-register-data
+   (:type vector)
+   (:constructor nil)
+   (:constructor undo-tree-make-register-data (buffer node)))
+  buffer node)
+
+(defun undo-tree-register-data-p (data)
+  (and (vectorp data)
+       (= (length data) 2)
+       (undo-tree-node-p (undo-tree-register-data-node data))))
+
+(defun undo-tree-register-data-print-func (data)
+  (princ (format "an undo-tree state for buffer %s"
+		 (undo-tree-register-data-buffer data))))
+
+(defmacro undo-tree-node-register (node)
+  `(plist-get (undo-tree-node-meta-data ,node) :register))
+
+(defsetf undo-tree-node-register (node) (val)
+  `(setf (undo-tree-node-meta-data ,node)
+	 (plist-put (undo-tree-node-meta-data ,node) :register ,val)))
+
+
+
+
+;;; =====================================================================
+;;;              Basic undo-tree data structure functions
+
+(defun undo-tree-grow (undo)
+  "Add an UNDO node to current branch of `buffer-undo-tree'."
+  (let* ((current (undo-tree-current buffer-undo-tree))
+         (new (undo-tree-make-node current undo)))
+    (push new (undo-tree-node-next current))
+    (setf (undo-tree-current buffer-undo-tree) new)))
+
+
+(defun undo-tree-grow-backwards (node undo &optional redo)
+  "Add new node *above* undo-tree NODE, and return new node.
+Note that this will overwrite NODE's \"previous\" link, so should
+only be used on a detached NODE, never on nodes that are already
+part of `buffer-undo-tree'."
+  (let ((new (undo-tree-make-node-backwards node undo redo)))
+    (setf (undo-tree-node-previous node) new)
+    new))
+
+
+(defun undo-tree-splice-node (node splice)
+  "Splice NODE into undo tree, below node SPLICE.
+Note that this will overwrite NODE's \"next\" and \"previous\"
+links, so should only be used on a detached NODE, never on nodes
+that are already part of `buffer-undo-tree'."
+  (setf (undo-tree-node-next node) (undo-tree-node-next splice)
+	(undo-tree-node-branch node) (undo-tree-node-branch splice)
+	(undo-tree-node-previous node) splice
+	(undo-tree-node-next splice) (list node)
+	(undo-tree-node-branch splice) 0)
+  (dolist (n (undo-tree-node-next node))
+    (setf (undo-tree-node-previous n) node)))
+
+
+(defun undo-tree-snip-node (node)
+  "Snip NODE out of undo tree."
+  (let* ((parent (undo-tree-node-previous node))
+	 position p)
+    ;; if NODE is only child, replace parent's next links with NODE's
+    (if (= (length (undo-tree-node-next parent)) 0)
+	(setf (undo-tree-node-next parent) (undo-tree-node-next node)
+	      (undo-tree-node-branch parent) (undo-tree-node-branch node))
+      ;; otherwise...
+      (setq position (undo-tree-position node (undo-tree-node-next parent)))
+      (cond
+       ;; if active branch used do go via NODE, set parent's branch to active
+       ;; branch of NODE
+       ((= (undo-tree-node-branch parent) position)
+	(setf (undo-tree-node-branch parent)
+	      (+ position (undo-tree-node-branch node))))
+       ;; if active branch didn't go via NODE, update parent's branch to point
+       ;; to same node as before
+       ((> (undo-tree-node-branch parent) position)
+	(incf (undo-tree-node-branch parent)
+	      (1- (length (undo-tree-node-next node))))))
+      ;; replace NODE in parent's next list with NODE's entire next list
+      (if (= position 0)
+	  (setf (undo-tree-node-next parent)
+		(nconc (undo-tree-node-next node)
+		       (cdr (undo-tree-node-next parent))))
+	(setq p (nthcdr (1- position) (undo-tree-node-next parent)))
+	(setcdr p (nconc (undo-tree-node-next node) (cddr p)))))
+    ;; update previous links of NODE's children
+    (dolist (n (undo-tree-node-next node))
+      (setf (undo-tree-node-previous n) parent))))
+
+
+(defun undo-tree-mapc (--undo-tree-mapc-function-- node)
+  ;; Apply FUNCTION to NODE and to each node below it.
+  (let ((stack (list node))
+	n)
+    (while stack
+      (setq n (pop stack))
+      (funcall --undo-tree-mapc-function-- n)
+      (setq stack (append (undo-tree-node-next n) stack)))))
+
+
+(defmacro undo-tree-num-branches ()
+  "Return number of branches at current undo tree node."
+  '(length (undo-tree-node-next (undo-tree-current buffer-undo-tree))))
+
+
+(defun undo-tree-position (node list)
+  "Find the first occurrence of NODE in LIST.
+Return the index of the matching item, or nil of not found.
+Comparison is done with `eq'."
+  (let ((i 0))
+    (catch 'found
+      (while (progn
+               (when (eq node (car list)) (throw 'found i))
+               (incf i)
+               (setq list (cdr list))))
+      nil)))
+
+
+(defvar *undo-tree-id-counter* 0)
+(make-variable-buffer-local '*undo-tree-id-counter*)
+
+(defmacro undo-tree-generate-id ()
+  ;; Generate a new, unique id (uninterned symbol).
+  ;; The name is made by appending a number to "undo-tree-id".
+  ;; (Copied from CL package `gensym'.)
+  `(let ((num (prog1 *undo-tree-id-counter* (incf *undo-tree-id-counter*))))
+     (make-symbol (format "undo-tree-id%d" num))))
+
+
+(defun undo-tree-decircle (undo-tree)
+  ;; Nullify PREVIOUS links of UNDO-TREE nodes, to make UNDO-TREE data
+  ;; structure non-circular.
+  (undo-tree-mapc
+   (lambda (node)
+     (dolist (n (undo-tree-node-next node))
+       (setf (undo-tree-node-previous n) nil)))
+   (undo-tree-root undo-tree)))
+
+
+(defun undo-tree-recircle (undo-tree)
+  ;; Recreate PREVIOUS links of UNDO-TREE nodes, to restore circular UNDO-TREE
+  ;; data structure.
+  (undo-tree-mapc
+   (lambda (node)
+     (dolist (n (undo-tree-node-next node))
+       (setf (undo-tree-node-previous n) node)))
+   (undo-tree-root undo-tree)))
+
+
+
+
+;;; =====================================================================
+;;;             Undo list and undo changeset utility functions
+
+(defmacro undo-list-marker-elt-p (elt)
+  `(markerp (car-safe ,elt)))
+
+(defmacro undo-list-GCd-marker-elt-p (elt)
+  ;; Return t if ELT is a marker element whose marker has been moved to the
+  ;; object-pool, so may potentially have been garbage-collected.
+  ;; Note: Valid marker undo elements should be uniquely identified as cons
+  ;; cells with a symbol in the car (replacing the marker), and a number in
+  ;; the cdr. However, to guard against future changes to undo element
+  ;; formats, we perform an additional redundant check on the symbol name.
+  `(and (car-safe ,elt)
+	(symbolp (car ,elt))
+	(let ((str (symbol-name (car ,elt))))
+	  (and (> (length str) 12)
+	       (string= (substring str 0 12) "undo-tree-id")))
+	(numberp (cdr-safe ,elt))))
+
+
+(defun undo-tree-move-GC-elts-to-pool (elt)
+  ;; Move elements that can be garbage-collected into `buffer-undo-tree'
+  ;; object pool, substituting a unique id that can be used to retrieve them
+  ;; later. (Only markers require this treatment currently.)
+  (when (undo-list-marker-elt-p elt)
+    (let ((id (undo-tree-generate-id)))
+      (puthash id (car elt) (undo-tree-object-pool buffer-undo-tree))
+      (setcar elt id))))
+
+
+(defun undo-tree-restore-GC-elts-from-pool (elt)
+  ;; Replace object id's in ELT with corresponding objects from
+  ;; `buffer-undo-tree' object pool and return modified ELT, or return nil if
+  ;; any object in ELT has been garbage-collected.
+  (if (undo-list-GCd-marker-elt-p elt)
+      (when (setcar elt (gethash (car elt)
+				 (undo-tree-object-pool buffer-undo-tree)))
+	elt)
+    elt))
+
+
+(defun undo-list-clean-GCd-elts (undo-list)
+  ;; Remove object id's from UNDO-LIST that refer to elements that have been
+  ;; garbage-collected. UNDO-LIST is modified by side-effect.
+  (while (undo-list-GCd-marker-elt-p (car undo-list))
+    (unless (gethash (caar undo-list)
+		     (undo-tree-object-pool buffer-undo-tree))
+      (setq undo-list (cdr undo-list))))
+  (let ((p undo-list))
+    (while (cdr p)
+      (when (and (undo-list-GCd-marker-elt-p (cadr p))
+		 (null (gethash (car (cadr p))
+				(undo-tree-object-pool buffer-undo-tree))))
+	(setcdr p (cddr p)))
+      (setq p (cdr p))))
+  undo-list)
+
+
+(defun undo-list-pop-changeset (&optional discard-pos)
+  ;; Pop changeset from `buffer-undo-list'. If DISCARD-POS is non-nil, discard
+  ;; any position entries from changeset.
+
+  ;; discard undo boundaries and (if DISCARD-POS is non-nil) position entries
+  ;; at head of undo list
+  (while (or (null (car buffer-undo-list))
+	     (and discard-pos (integerp (car buffer-undo-list))))
+    (setq buffer-undo-list (cdr buffer-undo-list)))
+  ;; pop elements up to next undo boundary, discarding position entries if
+  ;; DISCARD-POS is non-nil
+  (if (eq (car buffer-undo-list) 'undo-tree-canary)
+      (push nil buffer-undo-list)
+    (let* ((changeset (list (pop buffer-undo-list)))
+           (p changeset))
+      (while (progn
+	       (undo-tree-move-GC-elts-to-pool (car p))
+	       (while (and discard-pos (integerp (car buffer-undo-list)))
+		 (setq buffer-undo-list (cdr buffer-undo-list)))
+	       (and (car buffer-undo-list)
+		    (not (eq (car buffer-undo-list) 'undo-tree-canary))))
+        (setcdr p (list (pop buffer-undo-list)))
+	(setq p (cdr p)))
+      changeset)))
+
+
+(defun undo-tree-copy-list (undo-list)
+  ;; Return a deep copy of first changeset in `undo-list'. Object id's are
+  ;; replaced by corresponding objects from `buffer-undo-tree' object-pool.
+    (let (copy p)
+      ;; if first element contains an object id, replace it with object from
+      ;; pool, discarding element entirely if it's been GC'd
+    (while (and undo-list (null copy))
+	(setq copy
+	      (undo-tree-restore-GC-elts-from-pool (pop undo-list))))
+    (when copy
+      (setq copy (list copy)
+	    p copy)
+      ;; copy remaining elements, replacing object id's with objects from
+      ;; pool, or discarding them entirely if they've been GC'd
+      (while undo-list
+	(when (setcdr p (undo-tree-restore-GC-elts-from-pool
+			 (undo-copy-list-1 (pop undo-list))))
+	  (setcdr p (list (cdr p)))
+	  (setq p (cdr p))))
+      copy)))
+
+
+
+(defun undo-list-transfer-to-tree ()
+  ;; Transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'.
+
+  ;; `undo-list-transfer-to-tree' should never be called when undo is disabled
+  ;; (i.e. `buffer-undo-tree' is t)
+  (assert (not (eq buffer-undo-tree t)))
+
+  ;; if `buffer-undo-tree' is empty, create initial undo-tree
+  (when (null buffer-undo-tree) (setq buffer-undo-tree (make-undo-tree)))
+  ;; make sure there's a canary at end of `buffer-undo-list'
+  (when (null buffer-undo-list)
+    (setq buffer-undo-list '(nil undo-tree-canary)))
+
+  (unless (or (eq (cadr buffer-undo-list) 'undo-tree-canary)
+	      (eq (car buffer-undo-list) 'undo-tree-canary))
+    ;; create new node from first changeset in `buffer-undo-list', save old
+    ;; `buffer-undo-tree' current node, and make new node the current node
+    (let* ((node (undo-tree-make-node nil (undo-list-pop-changeset)))
+	   (splice (undo-tree-current buffer-undo-tree))
+	   (size (undo-list-byte-size (undo-tree-node-undo node)))
+	   (count 1))
+      (setf (undo-tree-current buffer-undo-tree) node)
+      ;; grow tree fragment backwards using `buffer-undo-list' changesets
+      (while (and buffer-undo-list
+		  (not (eq (cadr buffer-undo-list) 'undo-tree-canary)))
+	(setq node
+	      (undo-tree-grow-backwards node (undo-list-pop-changeset)))
+	(incf size (undo-list-byte-size (undo-tree-node-undo node)))
+	(incf count))
+      ;; if no undo history has been discarded from `buffer-undo-list' since
+      ;; last transfer, splice new tree fragment onto end of old
+      ;; `buffer-undo-tree' current node
+      (if (or (eq (cadr buffer-undo-list) 'undo-tree-canary)
+	      (eq (car buffer-undo-list) 'undo-tree-canary))
+	  (progn
+	    (setf (undo-tree-node-previous node) splice)
+	    (push node (undo-tree-node-next splice))
+	    (setf (undo-tree-node-branch splice) 0)
+	    (incf (undo-tree-size buffer-undo-tree) size)
+	    (incf (undo-tree-count buffer-undo-tree) count))
+	;; if undo history has been discarded, replace entire
+	;; `buffer-undo-tree' with new tree fragment
+	(setq node (undo-tree-grow-backwards node nil))
+	(setf (undo-tree-root buffer-undo-tree) node)
+	(setq buffer-undo-list '(nil undo-tree-canary))
+	(setf (undo-tree-size buffer-undo-tree) size)
+	(setf (undo-tree-count buffer-undo-tree) count)
+	(setq buffer-undo-list '(nil undo-tree-canary))))
+    ;; discard undo history if necessary
+    (undo-tree-discard-history)))
+
+
+(defun undo-list-byte-size (undo-list)
+  ;; Return size (in bytes) of UNDO-LIST
+  (let ((size 0) (p undo-list))
+    (while p
+      (incf size 8)  ; cons cells use up 8 bytes
+      (when (and (consp (car p)) (stringp (caar p)))
+        (incf size (string-bytes (caar p))))
+      (setq p (cdr p)))
+    size))
+
+
+
+(defun undo-list-rebuild-from-tree ()
+  "Rebuild `buffer-undo-list' from information in `buffer-undo-tree'."
+  (unless (eq buffer-undo-list t)
+    (undo-list-transfer-to-tree)
+    (setq buffer-undo-list nil)
+    (when buffer-undo-tree
+      (let ((stack (list (list (undo-tree-root buffer-undo-tree)))))
+	(push (sort (mapcar 'identity (undo-tree-node-next (caar stack)))
+		    (lambda (a b)
+		      (time-less-p (undo-tree-node-timestamp a)
+				   (undo-tree-node-timestamp b))))
+	      stack)
+	;; Traverse tree in depth-and-oldest-first order, but add undo records
+	;; on the way down, and redo records on the way up.
+	(while (or (car stack)
+		   (not (eq (car (nth 1 stack))
+			    (undo-tree-current buffer-undo-tree))))
+	  (if (car stack)
+	      (progn
+		(setq buffer-undo-list
+		      (append (undo-tree-node-undo (caar stack))
+			      buffer-undo-list))
+		(undo-boundary)
+		(push (sort (mapcar 'identity
+				    (undo-tree-node-next (caar stack)))
+			    (lambda (a b)
+			      (time-less-p (undo-tree-node-timestamp a)
+					   (undo-tree-node-timestamp b))))
+		      stack))
+	    (pop stack)
+	    (setq buffer-undo-list
+		  (append (undo-tree-node-redo (caar stack))
+			  buffer-undo-list))
+	    (undo-boundary)
+	    (pop (car stack))))))))
+
+
+
+
+;;; =====================================================================
+;;;                History discarding utility functions
+
+(defun undo-tree-oldest-leaf (node)
+  ;; Return oldest leaf node below NODE.
+  (while (undo-tree-node-next node)
+    (setq node
+          (car (sort (mapcar 'identity (undo-tree-node-next node))
+                     (lambda (a b)
+                       (time-less-p (undo-tree-node-timestamp a)
+                                    (undo-tree-node-timestamp b)))))))
+  node)
+
+
+(defun undo-tree-discard-node (node)
+  ;; Discard NODE from `buffer-undo-tree', and return next in line for
+  ;; discarding.
+
+  ;; don't discard current node
+  (unless (eq node (undo-tree-current buffer-undo-tree))
+
+    ;; discarding root node...
+    (if (eq node (undo-tree-root buffer-undo-tree))
+        (cond
+         ;; should always discard branches before root
+         ((> (length (undo-tree-node-next node)) 1)
+          (error "Trying to discard undo-tree root which still\
+ has multiple branches"))
+         ;; don't discard root if current node is only child
+         ((eq (car (undo-tree-node-next node))
+              (undo-tree-current buffer-undo-tree))
+	  nil)
+	 ;; discard root
+         (t
+	  ;; clear any register referring to root
+	  (let ((r (undo-tree-node-register node)))
+	    (when (and r (eq (get-register r) node))
+	      (set-register r nil)))
+          ;; make child of root into new root
+          (setq node (setf (undo-tree-root buffer-undo-tree)
+                           (car (undo-tree-node-next node))))
+	  ;; update undo-tree size
+	  (decf (undo-tree-size buffer-undo-tree)
+		(+ (undo-list-byte-size (undo-tree-node-undo node))
+		   (undo-list-byte-size (undo-tree-node-redo node))))
+	  (decf (undo-tree-count buffer-undo-tree))
+	  ;; discard new root's undo data and PREVIOUS link
+	  (setf (undo-tree-node-undo node) nil
+		(undo-tree-node-redo node) nil
+		(undo-tree-node-previous node) nil)
+          ;; if new root has branches, or new root is current node, next node
+          ;; to discard is oldest leaf, otherwise it's new root
+          (if (or (> (length (undo-tree-node-next node)) 1)
+                  (eq (car (undo-tree-node-next node))
+                      (undo-tree-current buffer-undo-tree)))
+              (undo-tree-oldest-leaf node)
+            node)))
+
+      ;; discarding leaf node...
+      (let* ((parent (undo-tree-node-previous node))
+             (current (nth (undo-tree-node-branch parent)
+                           (undo-tree-node-next parent))))
+	;; clear any register referring to the discarded node
+	(let ((r (undo-tree-node-register node)))
+	  (when (and r (eq (get-register r) node))
+	    (set-register r nil)))
+	;; update undo-tree size
+	(decf (undo-tree-size buffer-undo-tree)
+	      (+ (undo-list-byte-size (undo-tree-node-undo node))
+		 (undo-list-byte-size (undo-tree-node-redo node))))
+	(decf (undo-tree-count buffer-undo-tree))
+	;; discard leaf
+        (setf (undo-tree-node-next parent)
+                (delq node (undo-tree-node-next parent))
+              (undo-tree-node-branch parent)
+                (undo-tree-position current (undo-tree-node-next parent)))
+        ;; if parent has branches, or parent is current node, next node to
+        ;; discard is oldest leaf, otherwise it's the parent itself
+        (if (or (eq parent (undo-tree-current buffer-undo-tree))
+                (and (undo-tree-node-next parent)
+                     (or (not (eq parent (undo-tree-root buffer-undo-tree)))
+                         (> (length (undo-tree-node-next parent)) 1))))
+            (undo-tree-oldest-leaf parent)
+          parent)))))
+
+
+
+(defun undo-tree-discard-history ()
+  "Discard undo history until we're within memory usage limits
+set by `undo-limit', `undo-strong-limit' and `undo-outer-limit'."
+
+  (when (> (undo-tree-size buffer-undo-tree) undo-limit)
+    ;; if there are no branches off root, first node to discard is root;
+    ;; otherwise it's leaf node at botom of oldest branch
+    (let ((node (if (> (length (undo-tree-node-next
+                                (undo-tree-root buffer-undo-tree))) 1)
+                    (undo-tree-oldest-leaf (undo-tree-root buffer-undo-tree))
+                  (undo-tree-root buffer-undo-tree))))
+
+      ;; discard nodes until memory use is within `undo-strong-limit'
+      (while (and node
+                  (> (undo-tree-size buffer-undo-tree) undo-strong-limit))
+        (setq node (undo-tree-discard-node node)))
+
+      ;; discard nodes until next node to discard would bring memory use
+      ;; within `undo-limit'
+      (while (and node
+		  ;; check first if last discard has brought us within
+		  ;; `undo-limit', in case we can avoid more expensive
+		  ;; `undo-strong-limit' calculation
+		  ;; Note: this assumes undo-strong-limit > undo-limit;
+		  ;;       if not, effectively undo-strong-limit = undo-limit
+		  (> (undo-tree-size buffer-undo-tree) undo-limit)
+                  (> (- (undo-tree-size buffer-undo-tree)
+			;; if next node to discard is root, the memory we
+			;; free-up comes from discarding changesets from its
+			;; only child...
+			(if (eq node (undo-tree-root buffer-undo-tree))
+			    (+ (undo-list-byte-size
+				(undo-tree-node-undo
+				 (car (undo-tree-node-next node))))
+			       (undo-list-byte-size
+				(undo-tree-node-redo
+				 (car (undo-tree-node-next node)))))
+			  ;; ...otherwise, it comes from discarding changesets
+			  ;; from along with the node itself
+			  (+ (undo-list-byte-size (undo-tree-node-undo node))
+			     (undo-list-byte-size (undo-tree-node-redo node)))
+			  ))
+                     undo-limit))
+        (setq node (undo-tree-discard-node node)))
+
+      ;; if we're still over the `undo-outer-limit', discard entire history
+      (when (> (undo-tree-size buffer-undo-tree) undo-outer-limit)
+        ;; query first if `undo-ask-before-discard' is set
+        (if undo-ask-before-discard
+            (when (yes-or-no-p
+                   (format
+                    "Buffer `%s' undo info is %d bytes long;  discard it? "
+                    (buffer-name) (undo-tree-size buffer-undo-tree)))
+              (setq buffer-undo-tree nil))
+          ;; otherwise, discard and display warning
+          (display-warning
+           '(undo discard-info)
+           (concat
+            (format "Buffer `%s' undo info was %d bytes long.\n"
+                    (buffer-name) (undo-tree-size buffer-undo-tree))
+            "The undo info was discarded because it exceeded\
+ `undo-outer-limit'.
+
+This is normal if you executed a command that made a huge change
+to the buffer. In that case, to prevent similar problems in the
+future, set `undo-outer-limit' to a value that is large enough to
+cover the maximum size of normal changes you expect a single
+command to make, but not so large that it might exceed the
+maximum memory allotted to Emacs.
+
+If you did not execute any such command, the situation is
+probably due to a bug and you should report it.
+
+You can disable the popping up of this buffer by adding the entry
+\(undo discard-info) to the user option `warning-suppress-types',
+which is defined in the `warnings' library.\n")
+           :warning)
+          (setq buffer-undo-tree nil)))
+      )))
+
+
+
+
+;;; =====================================================================
+;;;                   Visualizer utility functions
+
+(defun undo-tree-compute-widths (node)
+  "Recursively compute widths for nodes below NODE."
+  (let ((stack (list node))
+        res)
+    (while stack
+      ;; try to compute widths for node at top of stack
+      (if (undo-tree-node-p
+           (setq res (undo-tree-node-compute-widths (car stack))))
+          ;; if computation fails, it returns a node whose widths still need
+          ;; computing, which we push onto the stack
+          (push res stack)
+        ;; otherwise, store widths and remove it from stack
+        (setf (undo-tree-node-lwidth (car stack)) (aref res 0)
+              (undo-tree-node-cwidth (car stack)) (aref res 1)
+              (undo-tree-node-rwidth (car stack)) (aref res 2))
+        (pop stack)))))
+
+
+(defun undo-tree-node-compute-widths (node)
+  ;; Compute NODE's left-, centre-, and right-subtree widths. Returns widths
+  ;; (in a vector) if successful. Otherwise, returns a node whose widths need
+  ;; calculating before NODE's can be calculated.
+  (let ((num-children (length (undo-tree-node-next node)))
+        (lwidth 0) (cwidth 0) (rwidth 0) p)
+    (catch 'need-widths
+      (cond
+       ;; leaf nodes have 0 width
+       ((= 0 num-children)
+        (setf cwidth 1
+              (undo-tree-node-lwidth node) 0
+              (undo-tree-node-cwidth node) 1
+              (undo-tree-node-rwidth node) 0))
+
+       ;; odd number of children
+       ((= (mod num-children 2) 1)
+        (setq p (undo-tree-node-next node))
+        ;; compute left-width
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf lwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            ;; if child's widths haven't been computed, return that child
+            (throw 'need-widths (car p)))
+          (setq p (cdr p)))
+        (if (undo-tree-node-lwidth (car p))
+            (incf lwidth (undo-tree-node-lwidth (car p)))
+          (throw 'need-widths (car p)))
+        ;; centre-width is inherited from middle child
+        (setf cwidth (undo-tree-node-cwidth (car p)))
+        ;; compute right-width
+        (incf rwidth (undo-tree-node-rwidth (car p)))
+        (setq p (cdr p))
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf rwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            (throw 'need-widths (car p)))
+          (setq p (cdr p))))
+
+       ;; even number of children
+       (t
+        (setq p (undo-tree-node-next node))
+        ;; compute left-width
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf lwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            (throw 'need-widths (car p)))
+          (setq p (cdr p)))
+        ;; centre-width is 0 when number of children is even
+        (setq cwidth 0)
+        ;; compute right-width
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf rwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            (throw 'need-widths (car p)))
+          (setq p (cdr p)))))
+
+      ;; return left-, centre- and right-widths
+      (vector lwidth cwidth rwidth))))
+
+
+(defun undo-tree-clear-visualizer-data (tree)
+  ;; Clear visualizer data below NODE.
+  (undo-tree-mapc
+   (lambda (n) (undo-tree-node-clear-visualizer-data n))
+   (undo-tree-root tree)))
+
+
+(defun undo-tree-node-unmodified-p (node &optional mtime)
+  ;; Return non-nil if NODE corresponds to a buffer state that once upon a
+  ;; time was unmodified. If a file modification time MTIME is specified,
+  ;; return non-nil if the corresponding buffer state really is unmodified.
+  (let (changeset ntime)
+    (setq changeset
+	  (or (undo-tree-node-redo node)
+	      (and (setq changeset (car (undo-tree-node-next node)))
+		   (undo-tree-node-undo changeset)))
+	  ntime
+	  (catch 'found
+	    (dolist (elt changeset)
+	      (when (and (consp elt) (eq (car elt) t) (consp (cdr elt))
+			 (throw 'found (cdr elt)))))))
+    (and ntime
+	 (or (null mtime)
+	     ;; high-precision timestamps
+	     (if (listp (cdr ntime))
+		 (equal ntime mtime)
+	       ;; old-style timestamps
+	       (and (= (car ntime) (car mtime))
+		    (= (cdr ntime) (cadr mtime))))))))
+
+
+
+
+;;; =====================================================================
+;;;                  Undo-in-region utility functions
+
+;; `undo-elt-in-region' uses this as a dynamically-scoped variable
+(defvar undo-adjusted-markers nil)
+
+
+(defun undo-tree-pull-undo-in-region-branch (start end)
+  ;; Pull out entries from undo changesets to create a new undo-in-region
+  ;; branch, which undoes changeset entries lying between START and END first,
+  ;; followed by remaining entries from the changesets, before rejoining the
+  ;; existing undo tree history. Repeated calls will, if appropriate, extend
+  ;; the current undo-in-region branch rather than creating a new one.
+
+  ;; if we're just reverting the last redo-in-region, we don't need to
+  ;; manipulate the undo tree at all
+  (if (undo-tree-reverting-redo-in-region-p start end)
+      t  ; return t to indicate success
+
+    ;; We build the `region-changeset' and `delta-list' lists forwards, using
+    ;; pointers `r' and `d' to the penultimate element of the list. So that we
+    ;; don't have to treat the first element differently, we prepend a dummy
+    ;; leading nil to the lists, and have the pointers point to that
+    ;; initially.
+    ;; Note: using '(nil) instead of (list nil) in the `let*' results in
+    ;;       bizarre errors when the code is byte-compiled, where parts of the
+    ;;       lists appear to survive across different calls to this function.
+    ;;       An obscure byte-compiler bug, perhaps?
+    (let* ((region-changeset (list nil))
+	   (r region-changeset)
+	   (delta-list (list nil))
+	   (d delta-list)
+	   (node (undo-tree-current buffer-undo-tree))
+	   (repeated-undo-in-region
+	    (undo-tree-repeated-undo-in-region-p start end))
+	   undo-adjusted-markers  ; `undo-elt-in-region' expects this
+	   fragment splice original-fragment original-splice original-current
+	   got-visible-elt undo-list elt)
+
+      ;; --- initialisation ---
+      (cond
+       ;; if this is a repeated undo in the same region, start pulling changes
+       ;; from NODE at which undo-in-region branch iss attached, and detatch
+       ;; the branch, using it as initial FRAGMENT of branch being constructed
+       (repeated-undo-in-region
+	(setq original-current node
+	      fragment (car (undo-tree-node-next node))
+	      splice node)
+	;; undo up to node at which undo-in-region branch is attached
+	;; (recognizable as first node with more than one branch)
+	(let ((mark-active nil))
+	  (while (= (length (undo-tree-node-next node)) 1)
+	    (undo-tree-undo-1)
+	    (setq fragment node
+		  node (undo-tree-current buffer-undo-tree))))
+	(when (eq splice node) (setq splice nil))
+	;; detatch undo-in-region branch
+	(setf (undo-tree-node-next node)
+	      (delq fragment (undo-tree-node-next node))
+	      (undo-tree-node-previous fragment) nil
+	      original-fragment fragment
+	      original-splice node))
+
+       ;; if this is a new undo-in-region, initial FRAGMENT is a copy of all
+       ;; nodes below the current one in the active branch
+       ((undo-tree-node-next node)
+	(setq fragment (undo-tree-make-node nil nil)
+	      splice fragment)
+	(while (setq node (nth (undo-tree-node-branch node)
+			       (undo-tree-node-next node)))
+	  (push (undo-tree-make-node
+		 splice
+		 (undo-copy-list (undo-tree-node-undo node))
+		 (undo-copy-list (undo-tree-node-redo node)))
+		(undo-tree-node-next splice))
+	  (setq splice (car (undo-tree-node-next splice))))
+	(setq fragment (car (undo-tree-node-next fragment))
+	      splice nil
+	      node (undo-tree-current buffer-undo-tree))))
+
+
+      ;; --- pull undo-in-region elements into branch ---
+      ;; work backwards up tree, pulling out undo elements within region until
+      ;; we've got one that undoes a visible change (insertion or deletion)
+      (catch 'abort
+	(while (and (not got-visible-elt) node (undo-tree-node-undo node))
+	  ;; we cons a dummy nil element on the front of the changeset so that
+	  ;; we can conveniently remove the first (real) element from the
+	  ;; changeset if we need to; the leading nil is removed once we're
+	  ;; done with this changeset
+	  (setq undo-list (cons nil (undo-copy-list (undo-tree-node-undo node)))
+		elt (cadr undo-list))
+	  (if fragment
+	      (progn
+		(setq fragment (undo-tree-grow-backwards fragment undo-list))
+		(unless splice (setq splice fragment)))
+	    (setq fragment (undo-tree-make-node nil undo-list))
+	    (setq splice fragment))
+
+	  (while elt
+	    (cond
+	     ;; keep elements within region
+	     ((undo-elt-in-region elt start end)
+	      ;; set flag if kept element is visible (insertion or deletion)
+	      (when (and (consp elt)
+			 (or (stringp (car elt)) (integerp (car elt))))
+		(setq got-visible-elt t))
+	      ;; adjust buffer positions in elements previously undone before
+	      ;; kept element, as kept element will now be undone first
+	      (undo-tree-adjust-elements-to-elt splice elt)
+	      ;; move kept element to undo-in-region changeset, adjusting its
+	      ;; buffer position as it will now be undone first
+	      (setcdr r (list (undo-tree-apply-deltas elt (cdr delta-list))))
+	      (setq r (cdr r))
+	      (setcdr undo-list (cddr undo-list)))
+
+	     ;; discard "was unmodified" elements
+	     ;; FIXME: deal properly with these
+	     ((and (consp elt) (eq (car elt) t))
+	      (setcdr undo-list (cddr undo-list)))
+
+	     ;; if element crosses region, we can't pull any more elements
+	     ((undo-elt-crosses-region elt start end)
+	      ;; if we've found a visible element, it must be earlier in
+	      ;; current node's changeset; stop pulling elements (null
+	      ;; `undo-list' and non-nil `got-visible-elt' cause loop to exit)
+	      (if got-visible-elt
+		  (setq undo-list nil)
+		;; if we haven't found a visible element yet, pulling
+		;; undo-in-region branch has failed
+		(setq region-changeset nil)
+		(throw 'abort t)))
+
+	     ;; if rejecting element, add its delta (if any) to the list
+	     (t
+	      (let ((delta (undo-delta elt)))
+		(when (/= 0 (cdr delta))
+		  (setcdr d (list delta))
+		  (setq d (cdr d))))
+	      (setq undo-list (cdr undo-list))))
+
+	    ;; process next element of current changeset
+	    (setq elt (cadr undo-list)))
+
+	  ;; if there are remaining elements in changeset, remove dummy nil
+	  ;; from front
+	  (if (cadr (undo-tree-node-undo fragment))
+	      (pop (undo-tree-node-undo fragment))
+	    ;; otherwise, if we've kept all elements in changeset, discard
+	    ;; empty changeset
+	    (when (eq splice fragment) (setq splice nil))
+	    (setq fragment (car (undo-tree-node-next fragment))))
+	  ;; process changeset from next node up the tree
+	  (setq node (undo-tree-node-previous node))))
+
+      ;; pop dummy nil from front of `region-changeset'
+      (setq region-changeset (cdr region-changeset))
+
+
+      ;; --- integrate branch into tree ---
+      ;; if no undo-in-region elements were found, restore undo tree
+      (if (null region-changeset)
+	  (when original-current
+	    (push original-fragment (undo-tree-node-next original-splice))
+	    (setf (undo-tree-node-branch original-splice) 0
+		  (undo-tree-node-previous original-fragment) original-splice)
+	    (let ((mark-active nil))
+	      (while (not (eq (undo-tree-current buffer-undo-tree)
+			      original-current))
+		(undo-tree-redo-1)))
+	    nil)  ; return nil to indicate failure
+
+	;; otherwise...
+	;; need to undo up to node where new branch will be attached, to
+	;; ensure redo entries are populated, and then redo back to where we
+	;; started
+	(let ((mark-active nil)
+	      (current (undo-tree-current buffer-undo-tree)))
+	  (while (not (eq (undo-tree-current buffer-undo-tree) node))
+	    (undo-tree-undo-1))
+	  (while (not (eq (undo-tree-current buffer-undo-tree) current))
+	    (undo-tree-redo-1)))
+
+	(cond
+	 ;; if there's no remaining fragment, just create undo-in-region node
+	 ;; and attach it to parent of last node from which elements were
+	 ;; pulled
+	 ((null fragment)
+	  (setq fragment (undo-tree-make-node node region-changeset))
+	  (push fragment (undo-tree-node-next node))
+	  (setf (undo-tree-node-branch node) 0)
+	  ;; set current node to undo-in-region node
+	  (setf (undo-tree-current buffer-undo-tree) fragment))
+
+	 ;; if no splice point has been set, add undo-in-region node to top of
+	 ;; fragment and attach it to parent of last node from which elements
+	 ;; were pulled
+	 ((null splice)
+	  (setq fragment (undo-tree-grow-backwards fragment region-changeset))
+	  (push fragment (undo-tree-node-next node))
+	  (setf (undo-tree-node-branch node) 0
+		(undo-tree-node-previous fragment) node)
+	  ;; set current node to undo-in-region node
+	  (setf (undo-tree-current buffer-undo-tree) fragment))
+
+	 ;; if fragment contains nodes, attach fragment to parent of last node
+	 ;; from which elements were pulled, and splice in undo-in-region node
+	 (t
+	  (setf (undo-tree-node-previous fragment) node)
+	  (push fragment (undo-tree-node-next node))
+	  (setf (undo-tree-node-branch node) 0)
+	  ;; if this is a repeated undo-in-region, then we've left the current
+	  ;; node at the original splice-point; we need to set the current
+	  ;; node to the equivalent node on the undo-in-region branch and redo
+	  ;; back to where we started
+	  (when repeated-undo-in-region
+	    (setf (undo-tree-current buffer-undo-tree)
+		  (undo-tree-node-previous original-fragment))
+	    (let ((mark-active nil))
+	      (while (not (eq (undo-tree-current buffer-undo-tree) splice))
+		(undo-tree-redo-1 nil 'preserve-undo))))
+	  ;; splice new undo-in-region node into fragment
+	  (setq node (undo-tree-make-node nil region-changeset))
+	  (undo-tree-splice-node node splice)
+	  ;; set current node to undo-in-region node
+	  (setf (undo-tree-current buffer-undo-tree) node)))
+
+	;; update undo-tree size
+	(setq node (undo-tree-node-previous fragment))
+	(while (progn
+		 (and (setq node (car (undo-tree-node-next node)))
+		      (not (eq node original-fragment))
+		      (incf (undo-tree-count buffer-undo-tree))
+		      (incf (undo-tree-size buffer-undo-tree)
+			    (+ (undo-list-byte-size (undo-tree-node-undo node))
+			       (undo-list-byte-size (undo-tree-node-redo node)))))))
+	t)  ; indicate undo-in-region branch was successfully pulled
+      )))
+
+
+
+(defun undo-tree-pull-redo-in-region-branch (start end)
+  ;; Pull out entries from redo changesets to create a new redo-in-region
+  ;; branch, which redoes changeset entries lying between START and END first,
+  ;; followed by remaining entries from the changesets. Repeated calls will,
+  ;; if appropriate, extend the current redo-in-region branch rather than
+  ;; creating a new one.
+
+  ;; if we're just reverting the last undo-in-region, we don't need to
+  ;; manipulate the undo tree at all
+  (if (undo-tree-reverting-undo-in-region-p start end)
+      t  ; return t to indicate success
+
+    ;; We build the `region-changeset' and `delta-list' lists forwards, using
+    ;; pointers `r' and `d' to the penultimate element of the list. So that we
+    ;; don't have to treat the first element differently, we prepend a dummy
+    ;; leading nil to the lists, and have the pointers point to that
+    ;; initially.
+    ;; Note: using '(nil) instead of (list nil) in the `let*' causes bizarre
+    ;;       errors when the code is byte-compiled, where parts of the lists
+    ;;       appear to survive across different calls to this function.  An
+    ;;       obscure byte-compiler bug, perhaps?
+    (let* ((region-changeset (list nil))
+	   (r region-changeset)
+	   (delta-list (list nil))
+	   (d delta-list)
+	   (node (undo-tree-current buffer-undo-tree))
+	   (repeated-redo-in-region
+	    (undo-tree-repeated-redo-in-region-p start end))
+	   undo-adjusted-markers  ; `undo-elt-in-region' expects this
+	   fragment splice got-visible-elt redo-list elt)
+
+      ;; --- inisitalisation ---
+      (cond
+       ;; if this is a repeated redo-in-region, detach fragment below current
+       ;; node
+       (repeated-redo-in-region
+	(when (setq fragment (car (undo-tree-node-next node)))
+	  (setf (undo-tree-node-previous fragment) nil
+		(undo-tree-node-next node)
+		(delq fragment (undo-tree-node-next node)))))
+       ;; if this is a new redo-in-region, initial fragment is a copy of all
+       ;; nodes below the current one in the active branch
+       ((undo-tree-node-next node)
+	(setq fragment (undo-tree-make-node nil nil)
+	      splice fragment)
+	(while (setq node (nth (undo-tree-node-branch node)
+			       (undo-tree-node-next node)))
+	  (push (undo-tree-make-node
+		 splice nil
+		 (undo-copy-list (undo-tree-node-redo node)))
+		(undo-tree-node-next splice))
+	  (setq splice (car (undo-tree-node-next splice))))
+	(setq fragment (car (undo-tree-node-next fragment)))))
+
+
+      ;; --- pull redo-in-region elements into branch ---
+      ;; work down fragment, pulling out redo elements within region until
+      ;; we've got one that redoes a visible change (insertion or deletion)
+      (setq node fragment)
+      (catch 'abort
+	(while (and (not got-visible-elt) node (undo-tree-node-redo node))
+	  ;; we cons a dummy nil element on the front of the changeset so that
+	  ;; we can conveniently remove the first (real) element from the
+	  ;; changeset if we need to; the leading nil is removed once we're
+	  ;; done with this changeset
+	  (setq redo-list (push nil (undo-tree-node-redo node))
+		elt (cadr redo-list))
+	  (while elt
+	    (cond
+	     ;; keep elements within region
+	     ((undo-elt-in-region elt start end)
+	      ;; set flag if kept element is visible (insertion or deletion)
+	      (when (and (consp elt)
+			 (or (stringp (car elt)) (integerp (car elt))))
+		(setq got-visible-elt t))
+	      ;; adjust buffer positions in elements previously redone before
+	      ;; kept element, as kept element will now be redone first
+	      (undo-tree-adjust-elements-to-elt fragment elt t)
+	      ;; move kept element to redo-in-region changeset, adjusting its
+	      ;; buffer position as it will now be redone first
+	      (setcdr r (list (undo-tree-apply-deltas elt (cdr delta-list) -1)))
+	      (setq r (cdr r))
+	      (setcdr redo-list (cddr redo-list)))
+
+	     ;; discard "was unmodified" elements
+	     ;; FIXME: deal properly with these
+	     ((and (consp elt) (eq (car elt) t))
+	      (setcdr redo-list (cddr redo-list)))
+
+	     ;; if element crosses region, we can't pull any more elements
+	     ((undo-elt-crosses-region elt start end)
+	      ;; if we've found a visible element, it must be earlier in
+	      ;; current node's changeset; stop pulling elements (null
+	      ;; `redo-list' and non-nil `got-visible-elt' cause loop to exit)
+	      (if got-visible-elt
+		  (setq redo-list nil)
+		;; if we haven't found a visible element yet, pulling
+		;; redo-in-region branch has failed
+		(setq region-changeset nil)
+		(throw 'abort t)))
+
+	     ;; if rejecting element, add its delta (if any) to the list
+	     (t
+	      (let ((delta (undo-delta elt)))
+		(when (/= 0 (cdr delta))
+		  (setcdr d (list delta))
+		  (setq d (cdr d))))
+	      (setq redo-list (cdr redo-list))))
+
+	    ;; process next element of current changeset
+	    (setq elt (cadr redo-list)))
+
+	  ;; if there are remaining elements in changeset, remove dummy nil
+	  ;; from front
+	  (if (cadr (undo-tree-node-redo node))
+	      (pop (undo-tree-node-undo node))
+	    ;; otherwise, if we've kept all elements in changeset, discard
+	    ;; empty changeset
+	    (if (eq fragment node)
+		(setq fragment (car (undo-tree-node-next fragment)))
+	      (undo-tree-snip-node node)))
+	  ;; process changeset from next node in fragment
+	  (setq node (car (undo-tree-node-next node)))))
+
+      ;; pop dummy nil from front of `region-changeset'
+      (setq region-changeset (cdr region-changeset))
+
+
+      ;; --- integrate branch into tree ---
+      (setq node (undo-tree-current buffer-undo-tree))
+      ;; if no redo-in-region elements were found, restore undo tree
+      (if (null (car region-changeset))
+	  (when (and repeated-redo-in-region fragment)
+	    (push fragment (undo-tree-node-next node))
+	    (setf (undo-tree-node-branch node) 0
+		  (undo-tree-node-previous fragment) node)
+	    nil)  ; return nil to indicate failure
+
+	;; otherwise, add redo-in-region node to top of fragment, and attach
+	;; it below current node
+	(setq fragment
+	      (if fragment
+		  (undo-tree-grow-backwards fragment nil region-changeset)
+		(undo-tree-make-node nil nil region-changeset)))
+	(push fragment (undo-tree-node-next node))
+	(setf (undo-tree-node-branch node) 0
+	      (undo-tree-node-previous fragment) node)
+	;; update undo-tree size
+	(unless repeated-redo-in-region
+	  (setq node fragment)
+	  (while (and (setq node (car (undo-tree-node-next node)))
+		      (incf (undo-tree-count buffer-undo-tree))
+		      (incf (undo-tree-size buffer-undo-tree)
+			    (undo-list-byte-size
+			     (undo-tree-node-redo node))))))
+	(incf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-redo fragment)))
+	t)  ; indicate redo-in-region branch was successfully pulled
+      )))
+
+
+
+(defun undo-tree-adjust-elements-to-elt (node undo-elt &optional below)
+  "Adjust buffer positions of undo elements, starting at NODE's
+and going up the tree (or down the active branch if BELOW is
+non-nil) and through the nodes' undo elements until we reach
+UNDO-ELT.  UNDO-ELT must appear somewhere in the undo changeset
+of either NODE itself or some node above it in the tree."
+  (let ((delta (list (undo-delta undo-elt)))
+	(undo-list (undo-tree-node-undo node)))
+    ;; adjust elements until we reach UNDO-ELT
+    (while (and (car undo-list)
+		(not (eq (car undo-list) undo-elt)))
+      (setcar undo-list
+	      (undo-tree-apply-deltas (car undo-list) delta -1))
+      ;; move to next undo element in list, or to next node if we've run out
+      ;; of elements
+      (unless (car (setq undo-list (cdr undo-list)))
+	(if below
+	    (setq node (nth (undo-tree-node-branch node)
+			    (undo-tree-node-next node)))
+	  (setq node (undo-tree-node-previous node)))
+	(setq undo-list (undo-tree-node-undo node))))))
+
+
+
+(defun undo-tree-apply-deltas (undo-elt deltas &optional sgn)
+  ;; Apply DELTAS in order to UNDO-ELT, multiplying deltas by SGN
+  ;; (only useful value for SGN is -1).
+  (let (position offset)
+    (dolist (delta deltas)
+      (setq position (car delta)
+	    offset (* (cdr delta) (or sgn 1)))
+      (cond
+       ;; POSITION
+       ((integerp undo-elt)
+	(when (>= undo-elt position)
+	  (setq undo-elt (- undo-elt offset))))
+       ;; nil (or any other atom)
+       ((atom undo-elt))
+       ;; (TEXT . POSITION)
+       ((stringp (car undo-elt))
+	(let ((text-pos (abs (cdr undo-elt)))
+	      (point-at-end (< (cdr undo-elt) 0)))
+	  (if (>= text-pos position)
+	      (setcdr undo-elt (* (if point-at-end -1 1)
+				  (- text-pos offset))))))
+       ;; (BEGIN . END)
+       ((integerp (car undo-elt))
+	(when (>= (car undo-elt) position)
+	  (setcar undo-elt (- (car undo-elt) offset))
+	  (setcdr undo-elt (- (cdr undo-elt) offset))))
+       ;; (nil PROPERTY VALUE BEG . END)
+       ((null (car undo-elt))
+	(let ((tail (nthcdr 3 undo-elt)))
+	  (when (>= (car tail) position)
+	    (setcar tail (- (car tail) offset))
+	    (setcdr tail (- (cdr tail) offset)))))
+       ))
+    undo-elt))
+
+
+
+(defun undo-tree-repeated-undo-in-region-p (start end)
+  ;; Return non-nil if undo-in-region between START and END is a repeated
+  ;; undo-in-region
+  (let ((node (undo-tree-current buffer-undo-tree)))
+    (and (setq node
+	       (nth (undo-tree-node-branch node) (undo-tree-node-next node)))
+	 (eq (undo-tree-node-undo-beginning node) start)
+	 (eq (undo-tree-node-undo-end node) end))))
+
+
+(defun undo-tree-repeated-redo-in-region-p (start end)
+  ;; Return non-nil if undo-in-region between START and END is a repeated
+  ;; undo-in-region
+  (let ((node (undo-tree-current buffer-undo-tree)))
+    (and (eq (undo-tree-node-redo-beginning node) start)
+	 (eq (undo-tree-node-redo-end node) end))))
+
+
+;; Return non-nil if undo-in-region between START and END is simply
+;; reverting the last redo-in-region
+(defalias 'undo-tree-reverting-undo-in-region-p
+  'undo-tree-repeated-undo-in-region-p)
+
+
+;; Return non-nil if redo-in-region between START and END is simply
+;; reverting the last undo-in-region
+(defalias 'undo-tree-reverting-redo-in-region-p
+  'undo-tree-repeated-redo-in-region-p)
+
+
+
+
+;;; =====================================================================
+;;;                        Undo-tree commands
+
+;;;###autoload
+(define-minor-mode undo-tree-mode
+  "Toggle undo-tree mode.
+With no argument, this command toggles the mode.
+A positive prefix argument turns the mode on.
+A negative prefix argument turns it off.
+
+Undo-tree-mode replaces Emacs' standard undo feature with a more
+powerful yet easier to use version, that treats the undo history
+as what it is: a tree.
+
+The following keys are available in `undo-tree-mode':
+
+  \\{undo-tree-map}
+
+Within the undo-tree visualizer, the following keys are available:
+
+  \\{undo-tree-visualizer-mode-map}"
+
+  nil                       ; init value
+  undo-tree-mode-lighter    ; lighter
+  undo-tree-map             ; keymap
+
+  ;; if disabling `undo-tree-mode', rebuild `buffer-undo-list' from tree so
+  ;; Emacs undo can work
+  (when (not undo-tree-mode)
+    (undo-list-rebuild-from-tree)
+    (setq buffer-undo-tree nil)))
+
+
+(defun turn-on-undo-tree-mode (&optional print-message)
+  "Enable `undo-tree-mode' in the current buffer, when appropriate.
+Some major modes implement their own undo system, which should
+not normally be overridden by `undo-tree-mode'. This command does
+not enable `undo-tree-mode' in such buffers. If you want to force
+`undo-tree-mode' to be enabled regardless, use (undo-tree-mode 1)
+instead.
+
+The heuristic used to detect major modes in which
+`undo-tree-mode' should not be used is to check whether either
+the `undo' command has been remapped, or the default undo
+keybindings (C-/ and C-_) have been overridden somewhere other
+than in the global map. In addition, `undo-tree-mode' will not be
+enabled if the buffer's `major-mode' appears in
+`undo-tree-incompatible-major-modes'."
+  (interactive "p")
+  (if (or (key-binding [remap undo])
+	  (undo-tree-overridden-undo-bindings-p)
+	  (memq major-mode undo-tree-incompatible-major-modes))
+      (when print-message
+	(message "Buffer does not support undo-tree-mode;\
+ undo-tree-mode NOT enabled"))
+    (undo-tree-mode 1)))
+
+
+(defun undo-tree-overridden-undo-bindings-p ()
+  "Returns t if default undo bindings are overridden, nil otherwise.
+Checks if either of the default undo key bindings (\"C-/\" or
+\"C-_\") are overridden in the current buffer by any keymap other
+than the global one. (So global redefinitions of the default undo
+key bindings do not count.)"
+  (let ((binding1 (lookup-key (current-global-map) [?\C-/]))
+	(binding2 (lookup-key (current-global-map) [?\C-_])))
+    (global-set-key [?\C-/] 'undo)
+    (global-set-key [?\C-_] 'undo)
+    (unwind-protect
+	(or (and (key-binding [?\C-/])
+		 (not (eq (key-binding [?\C-/]) 'undo)))
+	    (and (key-binding [?\C-_])
+		 (not (eq (key-binding [?\C-_]) 'undo))))
+      (global-set-key [?\C-/] binding1)
+      (global-set-key [?\C-_] binding2))))
+
+
+;;;###autoload
+(define-globalized-minor-mode global-undo-tree-mode
+  undo-tree-mode turn-on-undo-tree-mode)
+
+
+
+(defun undo-tree-undo (&optional arg)
+  "Undo changes.
+Repeat this command to undo more changes.
+A numeric ARG serves as a repeat count.
+
+In Transient Mark mode when the mark is active, only undo changes
+within the current region. Similarly, when not in Transient Mark
+mode, just \\[universal-argument] as an argument limits undo to
+changes within the current region."
+  (interactive "*P")
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  (undo-tree-undo-1 arg)
+  ;; inform user if at branch point
+  (when (> (undo-tree-num-branches) 1) (message "Undo branch point!")))
+
+
+(defun undo-tree-undo-1 (&optional arg preserve-redo preserve-timestamps)
+  ;; Internal undo function. An active mark in `transient-mark-mode', or
+  ;; non-nil ARG otherwise, enables undo-in-region. Non-nil PRESERVE-REDO
+  ;; causes the existing redo record to be preserved, rather than replacing it
+  ;; with the new one generated by undoing. Non-nil PRESERVE-TIMESTAMPS
+  ;; disables updating of timestamps in visited undo-tree nodes. (This latter
+  ;; should *only* be used when temporarily visiting another undo state and
+  ;; immediately returning to the original state afterwards. Otherwise, it
+  ;; could cause history-discarding errors.)
+  (let ((undo-in-progress t)
+	(undo-in-region (and undo-tree-enable-undo-in-region
+			     (or (region-active-p)
+				 (and arg (not (numberp arg))))))
+	pos current)
+    ;; transfer entries accumulated in `buffer-undo-list' to
+    ;; `buffer-undo-tree'
+    (undo-list-transfer-to-tree)
+
+    (dotimes (i (or (and (numberp arg) (prefix-numeric-value arg)) 1))
+      ;; check if at top of undo tree
+      (unless (undo-tree-node-previous (undo-tree-current buffer-undo-tree))
+	(user-error "No further undo information"))
+
+      ;; if region is active, or a non-numeric prefix argument was supplied,
+      ;; try to pull out a new branch of changes affecting the region
+      (when (and undo-in-region
+		 (not (undo-tree-pull-undo-in-region-branch
+		       (region-beginning) (region-end))))
+	(user-error "No further undo information for region"))
+
+      ;; remove any GC'd elements from node's undo list
+      (setq current (undo-tree-current buffer-undo-tree))
+      (decf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-undo current)))
+      (setf (undo-tree-node-undo current)
+	    (undo-list-clean-GCd-elts (undo-tree-node-undo current)))
+      (incf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-undo current)))
+      ;; undo one record from undo tree
+      (when undo-in-region
+	(setq pos (set-marker (make-marker) (point)))
+	(set-marker-insertion-type pos t))
+      (primitive-undo 1 (undo-tree-copy-list (undo-tree-node-undo current)))
+      (undo-boundary)
+
+      ;; if preserving old redo record, discard new redo entries that
+      ;; `primitive-undo' has added to `buffer-undo-list', and remove any GC'd
+      ;; elements from node's redo list
+      (if preserve-redo
+	  (progn
+	    (undo-list-pop-changeset)
+	    (decf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-redo current)))
+	    (setf (undo-tree-node-redo current)
+		  (undo-list-clean-GCd-elts (undo-tree-node-redo current)))
+	    (incf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-redo current))))
+	;; otherwise, record redo entries that `primitive-undo' has added to
+	;; `buffer-undo-list' in current node's redo record, replacing
+	;; existing entry if one already exists
+	(decf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-redo current)))
+	(setf (undo-tree-node-redo current)
+	      (undo-list-pop-changeset 'discard-pos))
+	(incf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-redo current))))
+
+      ;; rewind current node and update timestamp
+      (setf (undo-tree-current buffer-undo-tree)
+	    (undo-tree-node-previous (undo-tree-current buffer-undo-tree)))
+      (unless preserve-timestamps
+	(setf (undo-tree-node-timestamp (undo-tree-current buffer-undo-tree))
+	      (current-time)))
+
+      ;; if undoing-in-region, record current node, region and direction so we
+      ;; can tell if undo-in-region is repeated, and re-activate mark if in
+      ;; `transient-mark-mode'; if not, erase any leftover data
+      (if (not undo-in-region)
+	  (undo-tree-node-clear-region-data current)
+	(goto-char pos)
+	;; note: we deliberately want to store the region information in the
+	;; node *below* the now current one
+	(setf (undo-tree-node-undo-beginning current) (region-beginning)
+	      (undo-tree-node-undo-end current) (region-end))
+	(set-marker pos nil)))
+
+    ;; undo deactivates mark unless undoing-in-region
+    (setq deactivate-mark (not undo-in-region))))
+
+
+
+(defun undo-tree-redo (&optional arg)
+  "Redo changes. A numeric ARG serves as a repeat count.
+
+In Transient Mark mode when the mark is active, only redo changes
+within the current region. Similarly, when not in Transient Mark
+mode, just \\[universal-argument] as an argument limits redo to
+changes within the current region."
+  (interactive "*P")
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  (undo-tree-redo-1 arg)
+  ;; inform user if at branch point
+  (when (> (undo-tree-num-branches) 1) (message "Undo branch point!")))
+
+
+(defun undo-tree-redo-1 (&optional arg preserve-undo preserve-timestamps)
+  ;; Internal redo function. An active mark in `transient-mark-mode', or
+  ;; non-nil ARG otherwise, enables undo-in-region. Non-nil PRESERVE-UNDO
+  ;; causes the existing redo record to be preserved, rather than replacing it
+  ;; with the new one generated by undoing. Non-nil PRESERVE-TIMESTAMPS
+  ;; disables updating of timestamps in visited undo-tree nodes. (This latter
+  ;; should *only* be used when temporarily visiting another undo state and
+  ;; immediately returning to the original state afterwards. Otherwise, it
+  ;; could cause history-discarding errors.)
+  (let ((undo-in-progress t)
+	(redo-in-region (and undo-tree-enable-undo-in-region
+			     (or (region-active-p)
+				 (and arg (not (numberp arg))))))
+	pos current)
+    ;; transfer entries accumulated in `buffer-undo-list' to
+    ;; `buffer-undo-tree'
+    (undo-list-transfer-to-tree)
+
+    (dotimes (i (or (and (numberp arg) (prefix-numeric-value arg)) 1))
+      ;; check if at bottom of undo tree
+      (when (null (undo-tree-node-next (undo-tree-current buffer-undo-tree)))
+	(user-error "No further redo information"))
+
+      ;; if region is active, or a non-numeric prefix argument was supplied,
+      ;; try to pull out a new branch of changes affecting the region
+      (when (and redo-in-region
+		 (not (undo-tree-pull-redo-in-region-branch
+		       (region-beginning) (region-end))))
+	(user-error "No further redo information for region"))
+
+      ;; get next node (but DON'T advance current node in tree yet, in case
+      ;; redoing fails)
+      (setq current (undo-tree-current buffer-undo-tree)
+	    current (nth (undo-tree-node-branch current)
+			 (undo-tree-node-next current)))
+      ;; remove any GC'd elements from node's redo list
+      (decf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-redo current)))
+      (setf (undo-tree-node-redo current)
+	    (undo-list-clean-GCd-elts (undo-tree-node-redo current)))
+      (incf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-redo current)))
+      ;; redo one record from undo tree
+      (when redo-in-region
+	(setq pos (set-marker (make-marker) (point)))
+	(set-marker-insertion-type pos t))
+      (primitive-undo 1 (undo-tree-copy-list (undo-tree-node-redo current)))
+      (undo-boundary)
+      ;; advance current node in tree
+      (setf (undo-tree-current buffer-undo-tree) current)
+
+      ;; if preserving old undo record, discard new undo entries that
+      ;; `primitive-undo' has added to `buffer-undo-list', and remove any GC'd
+      ;; elements from node's redo list
+      (if preserve-undo
+	  (progn
+	    (undo-list-pop-changeset)
+	    (decf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-undo current)))
+	    (setf (undo-tree-node-undo current)
+		  (undo-list-clean-GCd-elts (undo-tree-node-undo current)))
+	    (incf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-undo current))))
+	;; otherwise, record undo entries that `primitive-undo' has added to
+	;; `buffer-undo-list' in current node's undo record, replacing
+	;; existing entry if one already exists
+	(decf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-undo current)))
+	(setf (undo-tree-node-undo current)
+	      (undo-list-pop-changeset 'discard-pos))
+	(incf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-undo current))))
+
+      ;; update timestamp
+      (unless preserve-timestamps
+	(setf (undo-tree-node-timestamp current) (current-time)))
+
+      ;; if redoing-in-region, record current node, region and direction so we
+      ;; can tell if redo-in-region is repeated, and re-activate mark if in
+      ;; `transient-mark-mode'
+      (if (not redo-in-region)
+	  (undo-tree-node-clear-region-data current)
+	(goto-char pos)
+	(setf (undo-tree-node-redo-beginning current) (region-beginning)
+	      (undo-tree-node-redo-end current) (region-end))
+	(set-marker pos nil)))
+
+    ;; redo deactivates the mark unless redoing-in-region
+    (setq deactivate-mark (not redo-in-region))))
+
+
+
+(defun undo-tree-switch-branch (branch)
+  "Switch to a different BRANCH of the undo tree.
+This will affect which branch to descend when *redoing* changes
+using `undo-tree-redo'."
+  (interactive (list (or (and prefix-arg (prefix-numeric-value prefix-arg))
+                         (and (not (eq buffer-undo-list t))
+			      (or (undo-list-transfer-to-tree) t)
+			      (let ((b (undo-tree-node-branch
+					(undo-tree-current
+					 buffer-undo-tree))))
+				(cond
+				 ;; switch to other branch if only 2
+				 ((= (undo-tree-num-branches) 2) (- 1 b))
+				 ;; prompt if more than 2
+				 ((> (undo-tree-num-branches) 2)
+				  (read-number
+				   (format "Branch (0-%d, on %d): "
+					   (1- (undo-tree-num-branches)) b)))
+				 ))))))
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  ;; sanity check branch number
+  (when (<= (undo-tree-num-branches) 1)
+    (user-error "Not at undo branch point"))
+  (when (or (< branch 0) (> branch (1- (undo-tree-num-branches))))
+    (user-error "Invalid branch number"))
+  ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+  (undo-list-transfer-to-tree)
+  ;; switch branch
+  (setf (undo-tree-node-branch (undo-tree-current buffer-undo-tree))
+	branch)
+  (message "Switched to branch %d" branch))
+
+
+(defun undo-tree-set (node &optional preserve-timestamps)
+  ;; Set buffer to state corresponding to NODE. Returns intersection point
+  ;; between path back from current node and path back from selected NODE.
+  ;; Non-nil PRESERVE-TIMESTAMPS disables updating of timestamps in visited
+  ;; undo-tree nodes. (This should *only* be used when temporarily visiting
+  ;; another undo state and immediately returning to the original state
+  ;; afterwards. Otherwise, it could cause history-discarding errors.)
+  (let ((path (make-hash-table :test 'eq))
+        (n node))
+    (puthash (undo-tree-root buffer-undo-tree) t path)
+    ;; build list of nodes leading back from selected node to root, updating
+    ;; branches as we go to point down to selected node
+    (while (progn
+             (puthash n t path)
+             (when (undo-tree-node-previous n)
+               (setf (undo-tree-node-branch (undo-tree-node-previous n))
+                     (undo-tree-position
+                      n (undo-tree-node-next (undo-tree-node-previous n))))
+               (setq n (undo-tree-node-previous n)))))
+    ;; work backwards from current node until we intersect path back from
+    ;; selected node
+    (setq n (undo-tree-current buffer-undo-tree))
+    (while (not (gethash n path))
+      (setq n (undo-tree-node-previous n)))
+    ;; ascend tree until intersection node
+    (while (not (eq (undo-tree-current buffer-undo-tree) n))
+      (undo-tree-undo-1 nil nil preserve-timestamps))
+    ;; descend tree until selected node
+    (while (not (eq (undo-tree-current buffer-undo-tree) node))
+      (undo-tree-redo-1 nil nil preserve-timestamps))
+    n))  ; return intersection node
+
+
+
+(defun undo-tree-save-state-to-register (register)
+  "Store current undo-tree state to REGISTER.
+The saved state can be restored using
+`undo-tree-restore-state-from-register'.
+Argument is a character, naming the register."
+  (interactive "cUndo-tree state to register: ")
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+  (undo-list-transfer-to-tree)
+  ;; save current node to REGISTER
+  (set-register
+   register (registerv-make
+	     (undo-tree-make-register-data
+	      (current-buffer) (undo-tree-current buffer-undo-tree))
+	     :print-func 'undo-tree-register-data-print-func))
+  ;; record REGISTER in current node, for visualizer
+  (setf (undo-tree-node-register (undo-tree-current buffer-undo-tree))
+	register))
+
+
+
+(defun undo-tree-restore-state-from-register (register)
+  "Restore undo-tree state from REGISTER.
+The state must be saved using `undo-tree-save-state-to-register'.
+Argument is a character, naming the register."
+  (interactive "*cRestore undo-tree state from register: ")
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  ;; throw error if undo is disabled in buffer, or if register doesn't contain
+  ;; an undo-tree node
+  (let ((data (registerv-data (get-register register))))
+    (cond
+     ((eq buffer-undo-list t)
+      (user-error "No undo information in this buffer"))
+     ((not (undo-tree-register-data-p data))
+      (user-error "Register doesn't contain undo-tree state"))
+     ((not (eq (current-buffer) (undo-tree-register-data-buffer data)))
+      (user-error "Register contains undo-tree state for a different buffer")))
+    ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+    (undo-list-transfer-to-tree)
+    ;; restore buffer state corresponding to saved node
+    (undo-tree-set (undo-tree-register-data-node data))))
+
+
+
+
+;;; =====================================================================
+;;;                    Persistent storage commands
+
+(defun undo-tree-make-history-save-file-name (file)
+  "Create the undo history file name for FILE.
+Normally this is the file's name with \".\" prepended and
+\".~undo-tree~\" appended.
+
+A match for FILE is sought in `undo-tree-history-directory-alist'
+\(see the documentation of that variable for details\). If the
+directory for the backup doesn't exist, it is created."
+  (let* ((backup-directory-alist undo-tree-history-directory-alist)
+	 (name (make-backup-file-name-1 file)))
+    (concat (file-name-directory name) "." (file-name-nondirectory name)
+	    ".~undo-tree~")))
+
+
+(defun undo-tree-save-history (&optional filename overwrite)
+  "Store undo-tree history to file.
+
+If optional argument FILENAME is omitted, default save file is
+\".<buffer-file-name>.~undo-tree\" if buffer is visiting a file.
+Otherwise, prompt for one.
+
+If OVERWRITE is non-nil, any existing file will be overwritten
+without asking for confirmation."
+  (interactive)
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  (undo-list-transfer-to-tree)
+  (when (and buffer-undo-tree (not (eq buffer-undo-tree t)))
+    (condition-case nil
+	(undo-tree-kill-visualizer)
+      (error (undo-tree-clear-visualizer-data buffer-undo-tree)))
+    (let ((buff (current-buffer))
+	  tree)
+      ;; get filename
+      (unless filename
+	(setq filename
+	      (if buffer-file-name
+		  (undo-tree-make-history-save-file-name buffer-file-name)
+		(expand-file-name (read-file-name "File to save in: ") nil))))
+      (when (or (not (file-exists-p filename))
+		overwrite
+		(yes-or-no-p (format "Overwrite \"%s\"? " filename)))
+	(unwind-protect
+	    (progn
+	      ;; transform undo-tree into non-circular structure, and make
+	      ;; temporary copy
+	      (undo-tree-decircle buffer-undo-tree)
+	      (setq tree (copy-undo-tree buffer-undo-tree))
+	      ;; discard undo-tree object pool before saving
+	      (setf (undo-tree-object-pool tree) nil)
+	      ;; print undo-tree to file
+	      ;; NOTE: We use `with-temp-buffer' instead of `with-temp-file'
+	      ;;       to allow `auto-compression-mode' to take effect, in
+	      ;;       case user has overridden or advised the default
+	      ;;       `undo-tree-make-history-save-file-name' to add a
+	      ;;       compressed file extension.
+	      (with-auto-compression-mode
+		(with-temp-buffer
+		  (prin1 (sha1 buff) (current-buffer))
+		  (terpri (current-buffer))
+		  (let ((print-circle t)) (prin1 tree (current-buffer)))
+		  (write-region nil nil filename))))
+	  ;; restore circular undo-tree data structure
+	  (undo-tree-recircle buffer-undo-tree))
+	))))
+
+
+
+(defun undo-tree-load-history (&optional filename noerror)
+  "Load undo-tree history from file.
+
+If optional argument FILENAME is null, default load file is
+\".<buffer-file-name>.~undo-tree\" if buffer is visiting a file.
+Otherwise, prompt for one.
+
+If optional argument NOERROR is non-nil, return nil instead of
+signaling an error if file is not found."
+  (interactive)
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  ;; get filename
+  (unless filename
+    (setq filename
+	  (if buffer-file-name
+	      (undo-tree-make-history-save-file-name buffer-file-name)
+	    (expand-file-name (read-file-name "File to load from: ") nil))))
+
+  ;; attempt to read undo-tree from FILENAME
+  (catch 'load-error
+    (unless (file-exists-p filename)
+      (if noerror
+	  (throw 'load-error nil)
+	(error "File \"%s\" does not exist; could not load undo-tree history"
+	       filename)))
+    (let (buff hash tree)
+      (setq buff (current-buffer))
+      (with-auto-compression-mode
+	(with-temp-buffer
+	  (insert-file-contents filename)
+	  (goto-char (point-min))
+	  (condition-case nil
+	      (setq hash (read (current-buffer)))
+	    (error
+	     (kill-buffer nil)
+	     (funcall (if noerror 'message 'user-error)
+		      "Error reading undo-tree history from \"%s\"" filename)
+	     (throw 'load-error nil)))
+	  (unless (string= (sha1 buff) hash)
+	    (kill-buffer nil)
+	    (funcall (if noerror 'message 'user-error)
+		     "Buffer has been modified; could not load undo-tree history")
+	    (throw 'load-error nil))
+	  (condition-case nil
+	      (setq tree (read (current-buffer)))
+	    (error
+	     (kill-buffer nil)
+	     (funcall (if noerror 'message 'error)
+		      "Error reading undo-tree history from \"%s\"" filename)
+	     (throw 'load-error nil)))
+	  (kill-buffer nil)))
+      ;; initialise empty undo-tree object pool
+      (setf (undo-tree-object-pool tree)
+	    (make-hash-table :test 'eq :weakness 'value))
+      ;; restore circular undo-tree data structure
+      (undo-tree-recircle tree)
+      (setq buffer-undo-tree tree))))
+
+
+
+;; Versions of save/load functions for use in hooks
+(defun undo-tree-save-history-hook ()
+  (when (and undo-tree-mode undo-tree-auto-save-history
+	     (not (eq buffer-undo-list t)))
+    (undo-tree-save-history nil t) nil))
+
+(defun undo-tree-load-history-hook ()
+  (when (and undo-tree-mode undo-tree-auto-save-history
+	     (not (eq buffer-undo-list t))
+	     (not revert-buffer-in-progress-p))
+    (undo-tree-load-history nil t)))
+
+
+
+
+;;; =====================================================================
+;;;                    Visualizer drawing functions
+
+(defun undo-tree-visualize ()
+  "Visualize the current buffer's undo tree."
+  (interactive "*")
+  (unless undo-tree-mode
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (deactivate-mark)
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+  (undo-list-transfer-to-tree)
+  ;; add hook to kill visualizer buffer if original buffer is changed
+  (add-hook 'before-change-functions 'undo-tree-kill-visualizer nil t)
+  ;; prepare *undo-tree* buffer, then draw tree in it
+  (let ((undo-tree buffer-undo-tree)
+        (buff (current-buffer))
+	(display-buffer-mark-dedicated 'soft))
+    (switch-to-buffer-other-window
+     (get-buffer-create undo-tree-visualizer-buffer-name))
+    (setq undo-tree-visualizer-parent-buffer buff)
+    (setq undo-tree-visualizer-parent-mtime
+	  (and (buffer-file-name buff)
+	       (nth 5 (file-attributes (buffer-file-name buff)))))
+    (setq undo-tree-visualizer-initial-node (undo-tree-current undo-tree))
+    (setq undo-tree-visualizer-spacing
+	  (undo-tree-visualizer-calculate-spacing))
+    (make-local-variable 'undo-tree-visualizer-timestamps)
+    (make-local-variable 'undo-tree-visualizer-diff)
+    (setq buffer-undo-tree undo-tree)
+    (undo-tree-visualizer-mode)
+    ;; FIXME; don't know why `undo-tree-visualizer-mode' clears this
+    (setq buffer-undo-tree undo-tree)
+    (set (make-local-variable 'undo-tree-visualizer-lazy-drawing)
+	 (or (eq undo-tree-visualizer-lazy-drawing t)
+	     (and (numberp undo-tree-visualizer-lazy-drawing)
+		  (>= (undo-tree-count undo-tree)
+		      undo-tree-visualizer-lazy-drawing))))
+    (when undo-tree-visualizer-diff (undo-tree-visualizer-show-diff))
+    (let ((inhibit-read-only t)) (undo-tree-draw-tree undo-tree))))
+
+
+(defun undo-tree-kill-visualizer (&rest _dummy)
+  ;; Kill visualizer. Added to `before-change-functions' hook of original
+  ;; buffer when visualizer is invoked.
+  (unless (or undo-tree-inhibit-kill-visualizer
+	      (null (get-buffer undo-tree-visualizer-buffer-name)))
+    (with-current-buffer undo-tree-visualizer-buffer-name
+      (undo-tree-visualizer-quit))))
+
+
+
+(defun undo-tree-draw-tree (undo-tree)
+  ;; Draw undo-tree in current buffer starting from NODE (or root if nil).
+  (let ((node (if undo-tree-visualizer-lazy-drawing
+		  (undo-tree-current undo-tree)
+		(undo-tree-root undo-tree))))
+    (erase-buffer)
+    (setq undo-tree-visualizer-needs-extending-down nil
+	  undo-tree-visualizer-needs-extending-up nil)
+    (undo-tree-clear-visualizer-data undo-tree)
+    (undo-tree-compute-widths node)
+    ;; lazy drawing starts vertically centred and displaced horizontally to
+    ;; the left (window-width/4), since trees will typically grow right
+    (if undo-tree-visualizer-lazy-drawing
+	(progn
+	  (undo-tree-move-down (/ (window-height) 2))
+	  (undo-tree-move-forward (max 2 (/ (window-width) 4)))) ; left margin
+      ;; non-lazy drawing starts in centre at top of buffer
+      (undo-tree-move-down 1)  ; top margin
+      (undo-tree-move-forward
+       (max (/ (window-width) 2)
+	    (+ (undo-tree-node-char-lwidth node)
+	       ;; add space for left part of left-most time-stamp
+	       (if undo-tree-visualizer-timestamps
+		   (/ (- undo-tree-visualizer-spacing 4) 2)
+		 0)
+	       2))))  ; left margin
+    ;; link starting node to its representation in visualizer
+    (setf (undo-tree-node-marker node) (make-marker))
+    (set-marker-insertion-type (undo-tree-node-marker node) nil)
+    (move-marker (undo-tree-node-marker node) (point))
+    ;; draw undo-tree
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-default-face)
+	  node-list)
+      (if (not undo-tree-visualizer-lazy-drawing)
+	  (undo-tree-extend-down node t)
+	(undo-tree-extend-down node)
+	(undo-tree-extend-up node)
+	(setq node-list undo-tree-visualizer-needs-extending-down
+	      undo-tree-visualizer-needs-extending-down nil)
+	(while node-list (undo-tree-extend-down (pop node-list)))))
+    ;; highlight active branch
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face))
+      (undo-tree-highlight-active-branch
+       (or undo-tree-visualizer-needs-extending-up
+	   (undo-tree-root undo-tree))))
+    ;; highlight current node
+    (undo-tree-draw-node (undo-tree-current undo-tree) 'current)))
+
+
+(defun undo-tree-extend-down (node &optional bottom)
+  ;; Extend tree downwards starting from NODE and point. If BOTTOM is t,
+  ;; extend all the way down to the leaves. If BOTTOM is a node, extend down
+  ;; as far as that node. If BOTTOM is an integer, extend down as far as that
+  ;; line. Otherwise, only extend visible portion of tree. NODE is assumed to
+  ;; already have a node marker. Returns non-nil if anything was actually
+  ;; extended.
+  (let ((extended nil)
+	(cur-stack (list node))
+	next-stack)
+    ;; don't bother extending if BOTTOM specifies an already-drawn node
+    (unless (and (undo-tree-node-p bottom) (undo-tree-node-marker bottom))
+      ;; draw nodes layer by layer
+      (while (or cur-stack
+		 (prog1 (setq cur-stack next-stack)
+		   (setq next-stack nil)))
+	(setq node (pop cur-stack))
+	;; if node is within range being drawn...
+	(if (or (eq bottom t)
+		(and (undo-tree-node-p bottom)
+		     (not (eq (undo-tree-node-previous node) bottom)))
+		(and (integerp bottom)
+		     (>= bottom (line-number-at-pos
+				 (undo-tree-node-marker node))))
+		(and (null bottom)
+		     (pos-visible-in-window-p (undo-tree-node-marker node)
+					      nil t)))
+	    ;; ...draw one layer of node's subtree (if not already drawn)
+	    (progn
+	      (unless (and (undo-tree-node-next node)
+			   (undo-tree-node-marker
+			    (nth (undo-tree-node-branch node)
+				 (undo-tree-node-next node))))
+		(goto-char (undo-tree-node-marker node))
+		(undo-tree-draw-subtree node)
+		(setq extended t))
+	      (setq next-stack
+		    (append (undo-tree-node-next node) next-stack)))
+	  ;; ...otherwise, postpone drawing until later
+	  (push node undo-tree-visualizer-needs-extending-down))))
+    extended))
+
+
+(defun undo-tree-extend-up (node &optional top)
+  ;; Extend tree upwards starting from NODE. If TOP is t, extend all the way
+  ;; to root. If TOP is a node, extend up as far as that node. If TOP is an
+  ;; integer, extend up as far as that line. Otherwise, only extend visible
+  ;; portion of tree. NODE is assumed to already have a node marker. Returns
+  ;; non-nil if anything was actually extended.
+  (let ((extended nil) parent)
+    ;; don't bother extending if TOP specifies an already-drawn node
+    (unless (and (undo-tree-node-p top) (undo-tree-node-marker top))
+      (while node
+	(setq parent (undo-tree-node-previous node))
+	;; if we haven't reached root...
+	(if parent
+	    ;; ...and node is within range being drawn...
+	    (if (or (eq top t)
+		    (and (undo-tree-node-p top) (not (eq node top)))
+		    (and (integerp top)
+			 (< top (line-number-at-pos
+				 (undo-tree-node-marker node))))
+		    (and (null top)
+			 ;; NOTE: we check point in case window-start is outdated
+			 (< (min (line-number-at-pos (point))
+				 (line-number-at-pos (window-start)))
+			    (line-number-at-pos
+			     (undo-tree-node-marker node)))))
+		;; ...and it hasn't already been drawn
+		(when (not (undo-tree-node-marker parent))
+		  ;; link parent node to its representation in visualizer
+		  (undo-tree-compute-widths parent)
+		  (undo-tree-move-to-parent node)
+		  (setf (undo-tree-node-marker parent) (make-marker))
+		  (set-marker-insertion-type
+		   (undo-tree-node-marker parent) nil)
+		  (move-marker (undo-tree-node-marker parent) (point))
+		  ;; draw subtree beneath parent
+		  (setq undo-tree-visualizer-needs-extending-down
+			(nconc (delq node (undo-tree-draw-subtree parent))
+			       undo-tree-visualizer-needs-extending-down))
+		  (setq extended t))
+	      ;; ...otherwise, postpone drawing for later and exit
+	      (setq undo-tree-visualizer-needs-extending-up (when parent node)
+		    parent nil))
+
+	  ;; if we've reached root, stop extending and add top margin
+	  (setq undo-tree-visualizer-needs-extending-up nil)
+	  (goto-char (undo-tree-node-marker node))
+	  (undo-tree-move-up 1)  ; top margin
+	  (delete-region (point-min) (line-beginning-position)))
+	;; next iteration
+	(setq node parent)))
+    extended))
+
+
+(defun undo-tree-expand-down (from &optional to)
+  ;; Expand tree downwards. FROM is the node to start expanding from. Stop
+  ;; expanding at TO if specified. Otherwise, just expand visible portion of
+  ;; tree and highlight active branch from FROM.
+  (when undo-tree-visualizer-needs-extending-down
+    (let ((inhibit-read-only t)
+	  node-list extended)
+      ;; extend down as far as TO node
+      (when to
+	(setq extended (undo-tree-extend-down from to))
+	(goto-char (undo-tree-node-marker to))
+	(redisplay t))  ; force redisplay to scroll buffer if necessary
+      ;; extend visible portion of tree downwards
+      (setq node-list undo-tree-visualizer-needs-extending-down
+	    undo-tree-visualizer-needs-extending-down nil)
+      (when node-list
+	(dolist (n node-list)
+	  (when (undo-tree-extend-down n) (setq extended t)))
+	;; highlight active branch in newly-extended-down portion, if any
+	(when extended
+	  (let ((undo-tree-insert-face
+		 'undo-tree-visualizer-active-branch-face))
+	    (undo-tree-highlight-active-branch from)))))))
+
+
+(defun undo-tree-expand-up (from &optional to)
+  ;; Expand tree upwards. FROM is the node to start expanding from, TO is the
+  ;; node to stop expanding at. If TO node isn't specified, just expand visible
+  ;; portion of tree and highlight active branch down to FROM.
+  (when undo-tree-visualizer-needs-extending-up
+    (let ((inhibit-read-only t)
+	  extended node-list)
+      ;; extend up as far as TO node
+      (when to
+	(setq extended (undo-tree-extend-up from to))
+	(goto-char (undo-tree-node-marker to))
+	;; simulate auto-scrolling if close to top of buffer
+	(when (<= (line-number-at-pos (point)) scroll-margin)
+	  (undo-tree-move-up (if (= scroll-conservatively 0)
+				 (/ (window-height) 2) 3))
+	  (when (undo-tree-extend-up to) (setq extended t))
+	  (goto-char (undo-tree-node-marker to))
+	  (unless (= scroll-conservatively 0) (recenter scroll-margin))))
+      ;; extend visible portion of tree upwards
+      (and undo-tree-visualizer-needs-extending-up
+	   (undo-tree-extend-up undo-tree-visualizer-needs-extending-up)
+	   (setq extended t))
+      ;; extend visible portion of tree downwards
+      (setq node-list undo-tree-visualizer-needs-extending-down
+	    undo-tree-visualizer-needs-extending-down nil)
+      (dolist (n node-list) (undo-tree-extend-down n))
+      ;; highlight active branch in newly-extended-up portion, if any
+      (when extended
+	(let ((undo-tree-insert-face
+	       'undo-tree-visualizer-active-branch-face))
+	  (undo-tree-highlight-active-branch
+	   (or undo-tree-visualizer-needs-extending-up
+	       (undo-tree-root buffer-undo-tree))
+	   from))))))
+
+
+
+(defun undo-tree-highlight-active-branch (node &optional end)
+  ;; Draw highlighted active branch below NODE in current buffer. Stop
+  ;; highlighting at END node if specified.
+  (let ((stack (list node)))
+    ;; draw active branch
+    (while stack
+      (setq node (pop stack))
+      (unless (or (eq node end)
+		  (memq node undo-tree-visualizer-needs-extending-down))
+	(goto-char (undo-tree-node-marker node))
+	(setq node (undo-tree-draw-subtree node 'active)
+	      stack (nconc stack node))))))
+
+
+(defun undo-tree-draw-node (node &optional current)
+  ;; Draw symbol representing NODE in visualizer. If CURRENT is non-nil, node
+  ;; is current node.
+  (goto-char (undo-tree-node-marker node))
+  (when undo-tree-visualizer-timestamps
+    (undo-tree-move-backward (/ undo-tree-visualizer-spacing 2)))
+
+  (let* ((undo-tree-insert-face (and undo-tree-insert-face
+				     (or (and (consp undo-tree-insert-face)
+					      undo-tree-insert-face)
+					 (list undo-tree-insert-face))))
+	 (register (undo-tree-node-register node))
+	 (unmodified (if undo-tree-visualizer-parent-mtime
+			 (undo-tree-node-unmodified-p
+			  node undo-tree-visualizer-parent-mtime)
+		       (undo-tree-node-unmodified-p node)))
+	node-string)
+    ;; check node's register (if any) still stores appropriate undo-tree state
+    (unless (and register
+		 (undo-tree-register-data-p
+		  (registerv-data (get-register register)))
+		 (eq node (undo-tree-register-data-node
+			   (registerv-data (get-register register)))))
+      (setq register nil))
+    ;; represent node by different symbols, depending on whether it's the
+    ;; current node, is saved in a register, or corresponds to an unmodified
+    ;; buffer
+    (setq node-string
+	    (cond
+	     (undo-tree-visualizer-timestamps
+	        (undo-tree-timestamp-to-string
+	         (undo-tree-node-timestamp node)
+		 undo-tree-visualizer-relative-timestamps
+		 current register))
+	     (register (char-to-string register))
+	     (unmodified "s")
+	     (current "x")
+	     (t "o"))
+	  undo-tree-insert-face
+	    (nconc
+	     (cond
+	      (current    '(undo-tree-visualizer-current-face))
+	      (unmodified '(undo-tree-visualizer-unmodified-face))
+	      (register   '(undo-tree-visualizer-register-face)))
+	     undo-tree-insert-face))
+    ;; draw node and link it to its representation in visualizer
+    (undo-tree-insert node-string)
+    (undo-tree-move-backward (if undo-tree-visualizer-timestamps
+				 (1+ (/ undo-tree-visualizer-spacing 2))
+			       1))
+    (move-marker (undo-tree-node-marker node) (point))
+    (put-text-property (point) (1+ (point)) 'undo-tree-node node)))
+
+
+(defun undo-tree-draw-subtree (node &optional active-branch)
+  ;; Draw subtree rooted at NODE. The subtree will start from point.
+  ;; If ACTIVE-BRANCH is non-nil, just draw active branch below NODE. Returns
+  ;; list of nodes below NODE.
+  (let ((num-children (length (undo-tree-node-next node)))
+        node-list pos trunk-pos n)
+    ;; draw node itself
+    (undo-tree-draw-node node)
+
+    (cond
+     ;; if we're at a leaf node, we're done
+     ((= num-children 0))
+
+     ;; if node has only one child, draw it (not strictly necessary to deal
+     ;; with this case separately, but as it's by far the most common case
+     ;; this makes the code clearer and more efficient)
+     ((= num-children 1)
+      (undo-tree-move-down 1)
+      (undo-tree-insert ?|)
+      (undo-tree-move-backward 1)
+      (undo-tree-move-down 1)
+      (undo-tree-insert ?|)
+      (undo-tree-move-backward 1)
+      (undo-tree-move-down 1)
+      (setq n (car (undo-tree-node-next node)))
+      ;; link next node to its representation in visualizer
+      (unless (markerp (undo-tree-node-marker n))
+        (setf (undo-tree-node-marker n) (make-marker))
+        (set-marker-insertion-type (undo-tree-node-marker n) nil))
+      (move-marker (undo-tree-node-marker n) (point))
+      ;; add next node to list of nodes to draw next
+      (push n node-list))
+
+     ;; if node has multiple children, draw branches
+     (t
+      (undo-tree-move-down 1)
+      (undo-tree-insert ?|)
+      (undo-tree-move-backward 1)
+      (move-marker (setq trunk-pos (make-marker)) (point))
+      ;; left subtrees
+      (undo-tree-move-backward
+       (- (undo-tree-node-char-lwidth node)
+          (undo-tree-node-char-lwidth
+           (car (undo-tree-node-next node)))))
+      (move-marker (setq pos (make-marker)) (point))
+      (setq n (cons nil (undo-tree-node-next node)))
+      (dotimes (i (/ num-children 2))
+        (setq n (cdr n))
+        (when (or (null active-branch)
+                  (eq (car n)
+                      (nth (undo-tree-node-branch node)
+                           (undo-tree-node-next node))))
+          (undo-tree-move-forward 2)
+          (undo-tree-insert ?_ (- trunk-pos pos 2))
+          (goto-char pos)
+          (undo-tree-move-forward 1)
+          (undo-tree-move-down 1)
+          (undo-tree-insert ?/)
+          (undo-tree-move-backward 2)
+          (undo-tree-move-down 1)
+          ;; link node to its representation in visualizer
+          (unless (markerp (undo-tree-node-marker (car n)))
+            (setf (undo-tree-node-marker (car n)) (make-marker))
+            (set-marker-insertion-type (undo-tree-node-marker (car n)) nil))
+          (move-marker (undo-tree-node-marker (car n)) (point))
+          ;; add node to list of nodes to draw next
+          (push (car n) node-list))
+        (goto-char pos)
+        (undo-tree-move-forward
+         (+ (undo-tree-node-char-rwidth (car n))
+            (undo-tree-node-char-lwidth (cadr n))
+            undo-tree-visualizer-spacing 1))
+        (move-marker pos (point)))
+      ;; middle subtree (only when number of children is odd)
+      (when (= (mod num-children 2) 1)
+        (setq n (cdr n))
+        (when (or (null active-branch)
+                  (eq (car n)
+                      (nth (undo-tree-node-branch node)
+                           (undo-tree-node-next node))))
+          (undo-tree-move-down 1)
+          (undo-tree-insert ?|)
+          (undo-tree-move-backward 1)
+          (undo-tree-move-down 1)
+          ;; link node to its representation in visualizer
+          (unless (markerp (undo-tree-node-marker (car n)))
+            (setf (undo-tree-node-marker (car n)) (make-marker))
+            (set-marker-insertion-type (undo-tree-node-marker (car n)) nil))
+          (move-marker (undo-tree-node-marker (car n)) (point))
+          ;; add node to list of nodes to draw next
+          (push (car n) node-list))
+        (goto-char pos)
+        (undo-tree-move-forward
+         (+ (undo-tree-node-char-rwidth (car n))
+            (if (cadr n) (undo-tree-node-char-lwidth (cadr n)) 0)
+            undo-tree-visualizer-spacing 1))
+        (move-marker pos (point)))
+      ;; right subtrees
+      (move-marker trunk-pos (1+ trunk-pos))
+      (dotimes (i (/ num-children 2))
+        (setq n (cdr n))
+        (when (or (null active-branch)
+                  (eq (car n)
+                      (nth (undo-tree-node-branch node)
+                           (undo-tree-node-next node))))
+          (goto-char trunk-pos)
+          (undo-tree-insert ?_ (- pos trunk-pos 1))
+          (goto-char pos)
+          (undo-tree-move-backward 1)
+          (undo-tree-move-down 1)
+          (undo-tree-insert ?\\)
+          (undo-tree-move-down 1)
+          ;; link node to its representation in visualizer
+          (unless (markerp (undo-tree-node-marker (car n)))
+            (setf (undo-tree-node-marker (car n)) (make-marker))
+            (set-marker-insertion-type (undo-tree-node-marker (car n)) nil))
+          (move-marker (undo-tree-node-marker (car n)) (point))
+          ;; add node to list of nodes to draw next
+          (push (car n) node-list))
+        (when (cdr n)
+          (goto-char pos)
+          (undo-tree-move-forward
+           (+ (undo-tree-node-char-rwidth (car n))
+              (if (cadr n) (undo-tree-node-char-lwidth (cadr n)) 0)
+              undo-tree-visualizer-spacing 1))
+          (move-marker pos (point))))
+      ))
+    ;; return list of nodes to draw next
+    (nreverse node-list)))
+
+
+(defun undo-tree-node-char-lwidth (node)
+  ;; Return left-width of NODE measured in characters.
+  (if (= (length (undo-tree-node-next node)) 0) 0
+    (- (* (+ undo-tree-visualizer-spacing 1) (undo-tree-node-lwidth node))
+       (if (= (undo-tree-node-cwidth node) 0)
+           (1+ (/ undo-tree-visualizer-spacing 2)) 0))))
+
+
+(defun undo-tree-node-char-rwidth (node)
+  ;; Return right-width of NODE measured in characters.
+  (if (= (length (undo-tree-node-next node)) 0) 0
+    (- (* (+ undo-tree-visualizer-spacing 1) (undo-tree-node-rwidth node))
+       (if (= (undo-tree-node-cwidth node) 0)
+           (1+ (/ undo-tree-visualizer-spacing 2)) 0))))
+
+
+(defun undo-tree-insert (str &optional arg)
+  ;; Insert character or string STR ARG times, overwriting, and using
+  ;; `undo-tree-insert-face'.
+  (unless arg (setq arg 1))
+  (when (characterp str)
+    (setq str (make-string arg str))
+    (setq arg 1))
+  (dotimes (i arg) (insert str))
+  (setq arg (* arg (length str)))
+  (undo-tree-move-forward arg)
+  ;; make sure mark isn't active, otherwise `backward-delete-char' might
+  ;; delete region instead of single char if transient-mark-mode is enabled
+  (setq mark-active nil)
+  (backward-delete-char arg)
+  (when undo-tree-insert-face
+    (put-text-property (- (point) arg) (point) 'face undo-tree-insert-face)))
+
+
+(defun undo-tree-move-down (&optional arg)
+  ;; Move down, extending buffer if necessary.
+  (let ((row (line-number-at-pos))
+        (col (current-column))
+        line)
+    (unless arg (setq arg 1))
+    (forward-line arg)
+    (setq line (line-number-at-pos))
+    ;; if buffer doesn't have enough lines, add some
+    (when (/= line (+ row arg))
+      (cond
+       ((< arg 0)
+	(insert (make-string (- line row arg) ?\n))
+	(forward-line (+ arg (- row line))))
+       (t (insert (make-string (- arg (- line row)) ?\n)))))
+    (undo-tree-move-forward col)))
+
+
+(defun undo-tree-move-up (&optional arg)
+  ;; Move up, extending buffer if necessary.
+  (unless arg (setq arg 1))
+  (undo-tree-move-down (- arg)))
+
+
+(defun undo-tree-move-forward (&optional arg)
+  ;; Move forward, extending buffer if necessary.
+  (unless arg (setq arg 1))
+  (let (n)
+    (cond
+     ((>= arg 0)
+      (setq n (- (line-end-position) (point)))
+      (if (> n arg)
+	  (forward-char arg)
+	(end-of-line)
+	(insert (make-string (- arg n) ? ))))
+     ((< arg 0)
+      (setq arg (- arg))
+      (setq n (- (point) (line-beginning-position)))
+      (when (< (- n 2) arg)  ; -2 to create left-margin
+	;; no space left - shift entire buffer contents right!
+	(let ((pos (move-marker (make-marker) (point))))
+	  (set-marker-insertion-type pos t)
+	  (goto-char (point-min))
+	  (while (not (eobp))
+	    (insert-before-markers (make-string (- arg -2 n) ? ))
+	    (forward-line 1))
+	  (goto-char pos)))
+      (backward-char arg)))))
+
+
+(defun undo-tree-move-backward (&optional arg)
+  ;; Move backward, extending buffer if necessary.
+  (unless arg (setq arg 1))
+  (undo-tree-move-forward (- arg)))
+
+
+(defun undo-tree-move-to-parent (node)
+  ;; Move to position of parent of NODE, extending buffer if necessary.
+  (let* ((parent (undo-tree-node-previous node))
+	 (n (undo-tree-node-next parent))
+	 (l (length n)) p)
+    (goto-char (undo-tree-node-marker node))
+    (unless (= l 1)
+      ;; move horizontally
+      (setq p (undo-tree-position node n))
+      (cond
+       ;; node in centre subtree: no horizontal movement
+       ((and (= (mod l 2) 1) (= p (/ l 2))))
+       ;; node in left subtree: move right
+       ((< p (/ l 2))
+	(setq n (nthcdr p n))
+	(undo-tree-move-forward
+	 (+ (undo-tree-node-char-rwidth (car n))
+	    (/ undo-tree-visualizer-spacing 2) 1))
+	(dotimes (i (- (/ l 2) p 1))
+	  (setq n (cdr n))
+	  (undo-tree-move-forward
+	   (+ (undo-tree-node-char-lwidth (car n))
+	      (undo-tree-node-char-rwidth (car n))
+	      undo-tree-visualizer-spacing 1)))
+	(when (= (mod l 2) 1)
+	  (setq n (cdr n))
+	  (undo-tree-move-forward
+	   (+ (undo-tree-node-char-lwidth (car n))
+	      (/ undo-tree-visualizer-spacing 2) 1))))
+       (t ;; node in right subtree: move left
+	(setq n (nthcdr (/ l 2) n))
+	(when (= (mod l 2) 1)
+	  (undo-tree-move-backward
+	   (+ (undo-tree-node-char-rwidth (car n))
+	      (/ undo-tree-visualizer-spacing 2) 1))
+	  (setq n (cdr n)))
+	(dotimes (i (- p (/ l 2) (mod l 2)))
+	  (undo-tree-move-backward
+	   (+ (undo-tree-node-char-lwidth (car n))
+	      (undo-tree-node-char-rwidth (car n))
+	      undo-tree-visualizer-spacing 1))
+	  (setq n (cdr n)))
+	(undo-tree-move-backward
+	 (+ (undo-tree-node-char-lwidth (car n))
+	    (/ undo-tree-visualizer-spacing 2) 1)))))
+    ;; move vertically
+    (undo-tree-move-up 3)))
+
+
+(defun undo-tree-timestamp-to-string
+  (timestamp &optional relative current register)
+  ;; Convert TIMESTAMP to string (either absolute or RELATVE time), indicating
+  ;; if it's the CURRENT node and/or has an associated REGISTER.
+  (if relative
+      ;; relative time
+      (let ((time (floor (float-time
+			  (subtract-time (current-time) timestamp))))
+	    n)
+	(setq time
+	      ;; years
+	      (if (> (setq n (/ time 315360000)) 0)
+		  (if (> n 999) "-ages" (format "-%dy" n))
+		(setq time (% time 315360000))
+		;; days
+		(if (> (setq n (/ time 86400)) 0)
+		    (format "-%dd" n)
+		  (setq time (% time 86400))
+		  ;; hours
+		  (if (> (setq n (/ time 3600)) 0)
+		      (format "-%dh" n)
+		    (setq time (% time 3600))
+		    ;; mins
+		    (if (> (setq n (/ time 60)) 0)
+			(format "-%dm" n)
+		      ;; secs
+		      (format "-%ds" (% time 60)))))))
+	(setq time (concat
+		    (if current "*" " ")
+		    time
+		    (if register (concat "[" (char-to-string register) "]")
+		      "   ")))
+	(setq n (length time))
+	(if (< n 9)
+	    (concat (make-string (- 9 n) ? ) time)
+	  time))
+    ;; absolute time
+    (concat (if current " *" "  ")
+	    (format-time-string "%H:%M:%S" timestamp)
+	    (if register
+		(concat "[" (char-to-string register) "]")
+	      "   "))))
+
+
+
+
+;;; =====================================================================
+;;;                        Visualizer commands
+
+(define-derived-mode
+  undo-tree-visualizer-mode special-mode "undo-tree-visualizer"
+  "Major mode used in undo-tree visualizer.
+
+The undo-tree visualizer can only be invoked from a buffer in
+which `undo-tree-mode' is enabled. The visualizer displays the
+undo history tree graphically, and allows you to browse around
+the undo history, undoing or redoing the corresponding changes in
+the parent buffer.
+
+Within the undo-tree visualizer, the following keys are available:
+
+  \\{undo-tree-visualizer-mode-map}"
+  :syntax-table nil
+  :abbrev-table nil
+  (setq truncate-lines t)
+  (setq cursor-type nil)
+  (setq undo-tree-visualizer-selected-node nil))
+
+
+
+(defun undo-tree-visualize-undo (&optional arg)
+  "Undo changes. A numeric ARG serves as a repeat count."
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (let ((old (undo-tree-current buffer-undo-tree))
+	current)
+    ;; unhighlight old current node
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face)
+	  (inhibit-read-only t))
+      (undo-tree-draw-node old))
+    ;; undo in parent buffer
+    (switch-to-buffer-other-window undo-tree-visualizer-parent-buffer)
+    (deactivate-mark)
+    (unwind-protect
+	(let ((undo-tree-inhibit-kill-visualizer t)) (undo-tree-undo-1 arg))
+      (setq current (undo-tree-current buffer-undo-tree))
+      (switch-to-buffer-other-window undo-tree-visualizer-buffer-name)
+      ;; when using lazy drawing, extend tree upwards as required
+      (when undo-tree-visualizer-lazy-drawing
+	(undo-tree-expand-up old current))
+      ;; highlight new current node
+      (let ((inhibit-read-only t)) (undo-tree-draw-node current 'current))
+      ;; update diff display, if any
+      (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))))
+
+
+(defun undo-tree-visualize-redo (&optional arg)
+  "Redo changes. A numeric ARG serves as a repeat count."
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (let ((old (undo-tree-current buffer-undo-tree))
+	current)
+    ;; unhighlight old current node
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face)
+	  (inhibit-read-only t))
+      (undo-tree-draw-node (undo-tree-current buffer-undo-tree)))
+    ;; redo in parent buffer
+    (switch-to-buffer-other-window undo-tree-visualizer-parent-buffer)
+    (deactivate-mark)
+    (unwind-protect
+	(let ((undo-tree-inhibit-kill-visualizer t)) (undo-tree-redo-1 arg))
+      (setq current (undo-tree-current buffer-undo-tree))
+      (switch-to-buffer-other-window undo-tree-visualizer-buffer-name)
+      ;; when using lazy drawing, extend tree downwards as required
+      (when undo-tree-visualizer-lazy-drawing
+	(undo-tree-expand-down old current))
+      ;; highlight new current node
+      (let ((inhibit-read-only t)) (undo-tree-draw-node current 'current))
+      ;; update diff display, if any
+      (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))))
+
+
+(defun undo-tree-visualize-switch-branch-right (arg)
+  "Switch to next branch of the undo tree.
+This will affect which branch to descend when *redoing* changes
+using `undo-tree-redo' or `undo-tree-visualizer-redo'."
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  ;; un-highlight old active branch below current node
+  (goto-char (undo-tree-node-marker (undo-tree-current buffer-undo-tree)))
+  (let ((undo-tree-insert-face 'undo-tree-visualizer-default-face)
+	(inhibit-read-only t))
+    (undo-tree-highlight-active-branch (undo-tree-current buffer-undo-tree)))
+  ;; increment branch
+  (let ((branch (undo-tree-node-branch (undo-tree-current buffer-undo-tree))))
+  (setf (undo-tree-node-branch (undo-tree-current buffer-undo-tree))
+        (cond
+         ((>= (+ branch arg) (undo-tree-num-branches))
+          (1- (undo-tree-num-branches)))
+         ((<= (+ branch arg) 0) 0)
+         (t (+ branch arg))))
+  (let ((inhibit-read-only t))
+    ;; highlight new active branch below current node
+    (goto-char (undo-tree-node-marker (undo-tree-current buffer-undo-tree)))
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face))
+      (undo-tree-highlight-active-branch (undo-tree-current buffer-undo-tree)))
+    ;; re-highlight current node
+    (undo-tree-draw-node (undo-tree-current buffer-undo-tree) 'current))))
+
+
+(defun undo-tree-visualize-switch-branch-left (arg)
+  "Switch to previous branch of the undo tree.
+This will affect which branch to descend when *redoing* changes
+using `undo-tree-redo' or `undo-tree-visualizer-redo'."
+  (interactive "p")
+  (undo-tree-visualize-switch-branch-right (- arg)))
+
+
+(defun undo-tree-visualizer-quit ()
+  "Quit the undo-tree visualizer."
+  (interactive)
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (undo-tree-clear-visualizer-data buffer-undo-tree)
+  ;; remove kill visualizer hook from parent buffer
+  (unwind-protect
+      (with-current-buffer undo-tree-visualizer-parent-buffer
+	(remove-hook 'before-change-functions 'undo-tree-kill-visualizer t))
+    ;; kill diff buffer, if any
+    (when undo-tree-visualizer-diff (undo-tree-visualizer-hide-diff))
+    (let ((parent undo-tree-visualizer-parent-buffer)
+	  window)
+      ;; kill visualizer buffer
+      (kill-buffer nil)
+      ;; switch back to parent buffer
+      (unwind-protect
+	  (if (setq window (get-buffer-window parent))
+	      (select-window window)
+	    (switch-to-buffer parent))))))
+
+
+(defun undo-tree-visualizer-abort ()
+  "Quit the undo-tree visualizer and return buffer to original state."
+  (interactive)
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (let ((node undo-tree-visualizer-initial-node))
+    (undo-tree-visualizer-quit)
+    (undo-tree-set node)))
+
+
+(defun undo-tree-visualizer-set (&optional pos)
+  "Set buffer to state corresponding to undo tree node
+at POS, or point if POS is nil."
+  (interactive)
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (unless pos (setq pos (point)))
+  (let ((node (get-text-property pos 'undo-tree-node)))
+    (when node
+      ;; set parent buffer to state corresponding to node at POS
+      (switch-to-buffer-other-window undo-tree-visualizer-parent-buffer)
+      (let ((undo-tree-inhibit-kill-visualizer t)) (undo-tree-set node))
+      (switch-to-buffer-other-window undo-tree-visualizer-buffer-name)
+      ;; re-draw undo tree
+      (let ((inhibit-read-only t)) (undo-tree-draw-tree buffer-undo-tree))
+      (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))))
+
+
+(defun undo-tree-visualizer-mouse-set (pos)
+  "Set buffer to state corresponding to undo tree node
+at mouse event POS."
+  (interactive "@e")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (undo-tree-visualizer-set (event-start (nth 1 pos))))
+
+
+(defun undo-tree-visualize-undo-to-x (&optional x)
+  "Undo to last branch point, register, or saved state.
+If X is the symbol `branch', undo to last branch point. If X is
+the symbol `register', undo to last register. If X is the sumbol
+`saved', undo to last saved state. If X is null, undo to first of
+these that's encountered.
+
+Interactively, a single \\[universal-argument] specifies
+`branch', a double \\[universal-argument] \\[universal-argument]
+specifies `saved', and a negative prefix argument specifies
+`register'."
+  (interactive "P")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (when (and (called-interactively-p 'any) x)
+    (setq x (prefix-numeric-value x)
+	  x (cond
+	     ((< x 0)  'register)
+	     ((<= x 4) 'branch)
+	     (t        'saved))))
+  (let ((current (if undo-tree-visualizer-selection-mode
+		     undo-tree-visualizer-selected-node
+		   (undo-tree-current buffer-undo-tree)))
+	(diff undo-tree-visualizer-diff)
+	r)
+    (undo-tree-visualizer-hide-diff)
+    (while (and (undo-tree-node-previous current)
+		(or (if undo-tree-visualizer-selection-mode
+			(progn
+			  (undo-tree-visualizer-select-previous)
+			  (setq current undo-tree-visualizer-selected-node))
+		      (undo-tree-visualize-undo)
+		      (setq current (undo-tree-current buffer-undo-tree)))
+		    t)
+		         ;; branch point
+		(not (or (and (or (null x) (eq x 'branch))
+			      (> (undo-tree-num-branches) 1))
+			 ;; register
+			 (and (or (null x) (eq x 'register))
+			      (setq r (undo-tree-node-register current))
+			      (undo-tree-register-data-p
+			       (setq r (registerv-data (get-register r))))
+			      (eq current (undo-tree-register-data-node r)))
+			 ;; saved state
+			 (and (or (null x) (eq x 'saved))
+			      (undo-tree-node-unmodified-p current))
+			 ))))
+    ;; update diff display, if any
+    (when diff
+      (undo-tree-visualizer-show-diff
+       (when undo-tree-visualizer-selection-mode
+	 undo-tree-visualizer-selected-node)))))
+
+
+(defun undo-tree-visualize-redo-to-x (&optional x)
+  "Redo to last branch point, register, or saved state.
+If X is the symbol `branch', redo to last branch point. If X is
+the symbol `register', redo to last register. If X is the sumbol
+`saved', redo to last saved state. If X is null, redo to first of
+these that's encountered.
+
+Interactively, a single \\[universal-argument] specifies
+`branch', a double \\[universal-argument] \\[universal-argument]
+specifies `saved', and a negative prefix argument specifies
+`register'."
+  (interactive "P")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (when (and (called-interactively-p 'any) x)
+    (setq x (prefix-numeric-value x)
+	  x (cond
+	     ((< x 0)  'register)
+	     ((<= x 4) 'branch)
+	     (t        'saved))))
+  (let ((current (if undo-tree-visualizer-selection-mode
+		     undo-tree-visualizer-selected-node
+		   (undo-tree-current buffer-undo-tree)))
+	(diff undo-tree-visualizer-diff)
+	r)
+    (undo-tree-visualizer-hide-diff)
+    (while (and (undo-tree-node-next current)
+		(or (if undo-tree-visualizer-selection-mode
+			(progn
+			  (undo-tree-visualizer-select-next)
+			  (setq current undo-tree-visualizer-selected-node))
+		      (undo-tree-visualize-redo)
+		      (setq current (undo-tree-current buffer-undo-tree)))
+		    t)
+		         ;; branch point
+		(not (or (and (or (null x) (eq x 'branch))
+			      (> (undo-tree-num-branches) 1))
+			 ;; register
+			 (and (or (null x) (eq x 'register))
+			      (setq r (undo-tree-node-register current))
+			      (undo-tree-register-data-p
+			       (setq r (registerv-data (get-register r))))
+			      (eq current (undo-tree-register-data-node r)))
+			 ;; saved state
+			 (and (or (null x) (eq x 'saved))
+			      (undo-tree-node-unmodified-p current))
+			 ))))
+    ;; update diff display, if any
+    (when diff
+      (undo-tree-visualizer-show-diff
+       (when undo-tree-visualizer-selection-mode
+	 undo-tree-visualizer-selected-node)))))
+
+
+(defun undo-tree-visualizer-toggle-timestamps ()
+  "Toggle display of time-stamps."
+  (interactive)
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (setq undo-tree-visualizer-timestamps (not undo-tree-visualizer-timestamps))
+  (setq undo-tree-visualizer-spacing (undo-tree-visualizer-calculate-spacing))
+  ;; redraw tree
+  (let ((inhibit-read-only t)) (undo-tree-draw-tree buffer-undo-tree)))
+
+
+(defun undo-tree-visualizer-scroll-left (&optional arg)
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (scroll-left (or arg 1) t))
+
+
+(defun undo-tree-visualizer-scroll-right (&optional arg)
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (scroll-right (or arg 1) t))
+
+
+(defun undo-tree-visualizer-scroll-up (&optional arg)
+  (interactive "P")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (if (or (and (numberp arg) (< arg 0)) (eq arg '-))
+      (undo-tree-visualizer-scroll-down arg)
+    ;; scroll up and expand newly-visible portion of tree
+    (unwind-protect
+	(scroll-up-command arg)
+      (undo-tree-expand-down
+       (nth (undo-tree-node-branch (undo-tree-current buffer-undo-tree))
+	    (undo-tree-node-next (undo-tree-current buffer-undo-tree)))))
+    ;; signal error if at eob
+    (when (and (not undo-tree-visualizer-needs-extending-down) (eobp))
+      (scroll-up))))
+
+
+(defun undo-tree-visualizer-scroll-down (&optional arg)
+  (interactive "P")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (if (or (and (numberp arg) (< arg 0)) (eq arg '-))
+      (undo-tree-visualizer-scroll-up arg)
+    ;; ensure there's enough room at top of buffer to scroll
+    (let ((scroll-lines
+	   (or arg (- (window-height) next-screen-context-lines)))
+	  (window-line (1- (line-number-at-pos (window-start)))))
+      (when (and undo-tree-visualizer-needs-extending-up
+		 (< window-line scroll-lines))
+	(let ((inhibit-read-only t))
+	  (goto-char (point-min))
+	  (undo-tree-move-up (- scroll-lines window-line)))))
+    ;; scroll down and expand newly-visible portion of tree
+    (unwind-protect
+	(scroll-down-command arg)
+      (undo-tree-expand-up
+       (undo-tree-node-previous (undo-tree-current buffer-undo-tree))))
+    ;; signal error if at bob
+    (when (and (not undo-tree-visualizer-needs-extending-down) (bobp))
+      (scroll-down))))
+
+
+
+
+;;; =====================================================================
+;;;                    Visualizer selection mode
+
+(define-minor-mode undo-tree-visualizer-selection-mode
+  "Toggle mode to select nodes in undo-tree visualizer."
+  :lighter "Select"
+  :keymap undo-tree-visualizer-selection-mode-map
+  :group undo-tree
+  (cond
+   ;; enable selection mode
+   (undo-tree-visualizer-selection-mode
+    (setq cursor-type 'box)
+    (setq undo-tree-visualizer-selected-node
+	  (undo-tree-current buffer-undo-tree))
+    ;; erase diff (if any), as initially selected node is identical to current
+    (when undo-tree-visualizer-diff
+      (let ((buff (get-buffer undo-tree-diff-buffer-name))
+	    (inhibit-read-only t))
+	(when buff (with-current-buffer buff (erase-buffer))))))
+   (t ;; disable selection mode
+    (setq cursor-type nil)
+    (setq undo-tree-visualizer-selected-node nil)
+    (goto-char (undo-tree-node-marker (undo-tree-current buffer-undo-tree)))
+    (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))
+   ))
+
+
+(defun undo-tree-visualizer-select-previous (&optional arg)
+  "Move to previous node."
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (let ((node undo-tree-visualizer-selected-node))
+    (catch 'top
+      (dotimes (i (or arg 1))
+	(unless (undo-tree-node-previous node) (throw 'top t))
+	(setq node (undo-tree-node-previous node))))
+    ;; when using lazy drawing, extend tree upwards as required
+    (when undo-tree-visualizer-lazy-drawing
+      (undo-tree-expand-up undo-tree-visualizer-selected-node node))
+    ;; update diff display, if any
+    (when (and undo-tree-visualizer-diff
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    ;; move to selected node
+    (goto-char (undo-tree-node-marker node))
+    (setq undo-tree-visualizer-selected-node node)))
+
+
+(defun undo-tree-visualizer-select-next (&optional arg)
+  "Move to next node."
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (let ((node undo-tree-visualizer-selected-node))
+    (catch 'bottom
+      (dotimes (i (or arg 1))
+	(unless (nth (undo-tree-node-branch node) (undo-tree-node-next node))
+	  (throw 'bottom t))
+	(setq node
+	      (nth (undo-tree-node-branch node) (undo-tree-node-next node)))))
+    ;; when using lazy drawing, extend tree downwards as required
+    (when undo-tree-visualizer-lazy-drawing
+      (undo-tree-expand-down undo-tree-visualizer-selected-node node))
+    ;; update diff display, if any
+    (when (and undo-tree-visualizer-diff
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    ;; move to selected node
+    (goto-char (undo-tree-node-marker node))
+    (setq undo-tree-visualizer-selected-node node)))
+
+
+(defun undo-tree-visualizer-select-right (&optional arg)
+  "Move right to a sibling node."
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (let ((node undo-tree-visualizer-selected-node)
+	end)
+    (goto-char (undo-tree-node-marker undo-tree-visualizer-selected-node))
+    (setq end (line-end-position))
+    (catch 'end
+      (dotimes (i arg)
+	(while (or (null node) (eq node undo-tree-visualizer-selected-node))
+	  (forward-char)
+	  (setq node (get-text-property (point) 'undo-tree-node))
+	  (when (= (point) end) (throw 'end t)))))
+    (goto-char (undo-tree-node-marker
+		(or node undo-tree-visualizer-selected-node)))
+    (when (and undo-tree-visualizer-diff node
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    (when node (setq undo-tree-visualizer-selected-node node))))
+
+
+(defun undo-tree-visualizer-select-left (&optional arg)
+  "Move left to a sibling node."
+  (interactive "p")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (let ((node (get-text-property (point) 'undo-tree-node))
+	beg)
+    (goto-char (undo-tree-node-marker undo-tree-visualizer-selected-node))
+    (setq beg (line-beginning-position))
+    (catch 'beg
+      (dotimes (i arg)
+	(while (or (null node) (eq node undo-tree-visualizer-selected-node))
+	  (backward-char)
+	  (setq node (get-text-property (point) 'undo-tree-node))
+	  (when (= (point) beg) (throw 'beg t)))))
+    (goto-char (undo-tree-node-marker
+		(or node undo-tree-visualizer-selected-node)))
+    (when (and undo-tree-visualizer-diff node
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    (when node (setq undo-tree-visualizer-selected-node node))))
+
+
+(defun undo-tree-visualizer-select (pos)
+  (let ((node (get-text-property pos 'undo-tree-node)))
+    (when node
+      ;; select node at POS
+      (goto-char (undo-tree-node-marker node))
+      ;; when using lazy drawing, extend tree up and down as required
+      (when undo-tree-visualizer-lazy-drawing
+	(undo-tree-expand-up undo-tree-visualizer-selected-node node)
+	(undo-tree-expand-down undo-tree-visualizer-selected-node node))
+      ;; update diff display, if any
+      (when (and undo-tree-visualizer-diff
+		 (not (eq node undo-tree-visualizer-selected-node)))
+	(undo-tree-visualizer-update-diff node))
+      ;; update selected node
+      (setq undo-tree-visualizer-selected-node node)
+      )))
+
+
+(defun undo-tree-visualizer-mouse-select (pos)
+  "Select undo tree node at mouse event POS."
+  (interactive "@e")
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (undo-tree-visualizer-select (event-start (nth 1 pos))))
+
+
+
+
+;;; =====================================================================
+;;;                      Visualizer diff display
+
+(defun undo-tree-visualizer-toggle-diff ()
+  "Toggle diff display in undo-tree visualizer."
+  (interactive)
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (if undo-tree-visualizer-diff
+      (undo-tree-visualizer-hide-diff)
+    (undo-tree-visualizer-show-diff)))
+
+
+(defun undo-tree-visualizer-selection-toggle-diff ()
+  "Toggle diff display in undo-tree visualizer selection mode."
+  (interactive)
+  (unless (eq major-mode 'undo-tree-visualizer-mode)
+    (user-error "Undo-tree mode not enabled in buffer"))
+  (if undo-tree-visualizer-diff
+      (undo-tree-visualizer-hide-diff)
+    (let ((node (get-text-property (point) 'undo-tree-node)))
+      (when node (undo-tree-visualizer-show-diff node)))))
+
+
+(defun undo-tree-visualizer-show-diff (&optional node)
+  ;; show visualizer diff display
+  (setq undo-tree-visualizer-diff t)
+  (let ((buff (with-current-buffer undo-tree-visualizer-parent-buffer
+		(undo-tree-diff node)))
+	(display-buffer-mark-dedicated 'soft)
+	win)
+    (setq win (split-window))
+    (set-window-buffer win buff)
+    (shrink-window-if-larger-than-buffer win)))
+
+
+(defun undo-tree-visualizer-hide-diff ()
+  ;; hide visualizer diff display
+  (setq undo-tree-visualizer-diff nil)
+  (let ((win (get-buffer-window undo-tree-diff-buffer-name)))
+    (when win (with-selected-window win (kill-buffer-and-window)))))
+
+
+(defun undo-tree-diff (&optional node)
+  ;; Create diff between NODE and current state (or previous state and current
+  ;; state, if NODE is null). Returns buffer containing diff.
+  (let (tmpfile buff)
+    ;; generate diff
+    (let ((undo-tree-inhibit-kill-visualizer t)
+	  (current (undo-tree-current buffer-undo-tree)))
+      (undo-tree-set (or node (undo-tree-node-previous current) current)
+		     'preserve-timestamps)
+      (setq tmpfile (diff-file-local-copy (current-buffer)))
+      (undo-tree-set current 'preserve-timestamps))
+    (setq buff (diff-no-select
+		tmpfile (current-buffer) nil 'noasync
+		(get-buffer-create undo-tree-diff-buffer-name)))
+    ;; delete process messages and useless headers from diff buffer
+    (let ((inhibit-read-only t))
+      (with-current-buffer buff
+	(goto-char (point-min))
+	(delete-region (point) (1+ (line-end-position 3)))
+	(goto-char (point-max))
+	(forward-line -2)
+	(delete-region (point) (point-max))
+	(setq cursor-type nil)
+	(setq buffer-read-only t)))
+    buff))
+
+
+(defun undo-tree-visualizer-update-diff (&optional node)
+  ;; update visualizer diff display to show diff between current state and
+  ;; NODE (or previous state, if NODE is null)
+  (with-current-buffer undo-tree-visualizer-parent-buffer
+    (undo-tree-diff node))
+  (let ((win (get-buffer-window undo-tree-diff-buffer-name)))
+    (when win
+      (balance-windows)
+      (shrink-window-if-larger-than-buffer win))))
+
+
+
+(provide 'undo-tree)
+
+;;; undo-tree.el ends here
.emacs.d/elpa/undo-tree-20170706.246/undo-tree.elc
Binary file
.emacs.d/elpa/which-key-20170817.1107/which-key-autoloads.el
@@ -0,0 +1,141 @@
+;;; which-key-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "which-key" "which-key.el" (22968 11435 249641
+;;;;;;  77000))
+;;; Generated autoloads from which-key.el
+
+(defvar which-key-mode nil "\
+Non-nil if Which-Key mode is enabled.
+See the `which-key-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `which-key-mode'.")
+
+(custom-autoload 'which-key-mode "which-key" nil)
+
+(autoload 'which-key-mode "which-key" "\
+Toggle which-key-mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'which-key-setup-side-window-right "which-key" "\
+Apply suggested settings for side-window that opens on right.
+
+\(fn)" t nil)
+
+(autoload 'which-key-setup-side-window-right-bottom "which-key" "\
+Apply suggested settings for side-window that opens on right
+if there is space and the bottom otherwise.
+
+\(fn)" t nil)
+
+(autoload 'which-key-setup-side-window-bottom "which-key" "\
+Apply suggested settings for side-window that opens on
+bottom.
+
+\(fn)" t nil)
+
+(autoload 'which-key-setup-minibuffer "which-key" "\
+Apply suggested settings for minibuffer.
+
+\(fn)" t nil)
+
+(autoload 'which-key-add-key-based-replacements "which-key" "\
+Replace the description of KEY-SEQUENCE with REPLACEMENT.
+KEY-SEQUENCE is a string suitable for use in `kbd'. REPLACEMENT
+may either be a string, as in
+
+\(which-key-add-key-based-replacements \"C-x 1\" \"maximize\")
+
+a cons of two strings as in
+
+\(which-key-add-key-based-replacements \"C-x 8\"
+                                        '(\"unicode\" . \"Unicode keys\"))
+
+or a function that takes a (KEY . BINDING) cons and returns a
+replacement.
+
+In the second case, the second string is used to provide a longer
+name for the keys under a prefix.
+
+MORE allows you to specifcy additional KEY REPLACEMENT pairs.  All
+replacements are added to
+`which-key-key-based-description-replacement-alist'.
+
+\(fn KEY-SEQUENCE REPLACEMENT &rest MORE)" nil nil)
+
+(autoload 'which-key-add-major-mode-key-based-replacements "which-key" "\
+Functions like `which-key-add-key-based-replacements'.
+The difference is that MODE specifies the `major-mode' that must
+be active for KEY-SEQUENCE and REPLACEMENT (MORE contains
+addition KEY-SEQUENCE REPLACEMENT pairs) to apply.
+
+\(fn MODE KEY-SEQUENCE REPLACEMENT &rest MORE)" nil nil)
+
+(autoload 'which-key-reload-key-sequence "which-key" "\
+Simulate entering the key sequence KEY-SEQ.
+KEY-SEQ should be a list of events as produced by
+`listify-key-sequence'. Any prefix arguments that were used are
+reapplied to the new key sequence.
+
+\(fn KEY-SEQ)" nil nil)
+
+(autoload 'which-key-show-standard-help "which-key" "\
+Call the command in `which-key--prefix-help-cmd-backup'.
+Usually this is `describe-prefix-bindings'.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-next-page-no-cycle "which-key" "\
+Show next page of keys unless on the last page, in which case
+call `which-key-show-standard-help'.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-previous-page-no-cycle "which-key" "\
+Show previous page of keys unless on the first page, in which
+case do nothing.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-next-page-cycle "which-key" "\
+Show the next page of keys, cycling from end to beginning
+after last page.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-previous-page-cycle "which-key" "\
+Show the previous page of keys, cycling from beginning to end
+after first page.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-top-level "which-key" "\
+Show top-level bindings.
+
+\(fn)" t nil)
+
+(autoload 'which-key-undo-key "which-key" "\
+Undo last keypress and force which-key update.
+
+\(fn)" t nil)
+
+(autoload 'which-key-C-h-dispatch "which-key" "\
+Dispatch C-h commands by looking up key in
+`which-key-C-h-map'. This command is always accessible (from any
+prefix) if `which-key-use-C-h-commands' is non nil.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; which-key-autoloads.el ends here
.emacs.d/elpa/which-key-20170817.1107/which-key-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "which-key" "20170817.1107" "Display available keybindings in popup" '((emacs "24.4")) :commit "6d2e17c949ff7bfebfe0b0878a93d94b31585031" :url "https://github.com/justbur/emacs-which-key")
.emacs.d/elpa/which-key-20170817.1107/which-key.el
@@ -0,0 +1,2356 @@
+;;; which-key.el --- Display available keybindings in popup  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  Free Software Foundation, Inc.
+
+;; Author: Justin Burkett <justin@burkett.cc>
+;; Maintainer: Justin Burkett <justin@burkett.cc>
+;; URL: https://github.com/justbur/emacs-which-key
+;; Package-Version: 20170817.1107
+;; Version: 3.0.2
+;; Keywords:
+;; Package-Requires: ((emacs "24.4"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; which-key provides the minor mode which-key-mode for Emacs. The mode displays
+;; the key bindings following your currently entered incomplete command (a
+;; prefix) in a popup. For example, after enabling the minor mode if you enter
+;; C-x and wait for the default of 1 second the minibuffer will expand with all
+;; of the available key bindings that follow C-x (or as many as space allows
+;; given your settings). This includes prefixes like C-x 8 which are shown in a
+;; different face. Screenshots of what the popup will look like along with
+;; information about additional features can be found at
+;; https://github.com/justbur/emacs-which-key.
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'button)
+(require 'regexp-opt)
+
+;; For compiler
+(defvar evil-operator-shortcut-map)
+(defvar evil-operator-state-map)
+(defvar evil-motion-state-map)
+(defvar golden-ratio-mode)
+(declare-function evil-get-command-property "ext:evil-common.el")
+
+;;; Options
+
+(defgroup which-key nil
+  "Customization options for which-key-mode"
+  :group 'help
+  :prefix "which-key-")
+
+(defcustom which-key-idle-delay 1.0
+  "Delay (in seconds) for which-key buffer to popup. A value of zero
+might lead to issues, so a non-zero value is recommended
+(see https://github.com/justbur/emacs-which-key/issues/134)."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-idle-secondary-delay nil
+  "Once the which-key buffer shows once for a key sequence reduce
+the idle time to this amount (in seconds). This makes it possible
+to shorten the delay for subsequent popups in the same key
+sequence. The default is for this value to be nil, which disables
+this behavior."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-echo-keystrokes (if (and echo-keystrokes
+                                              (> (+ echo-keystrokes 0.01)
+                                                 which-key-idle-delay))
+                                         (/ (float which-key-idle-delay) 4)
+                                       echo-keystrokes)
+  "Value to use for `echo-keystrokes'.
+This only applies if `which-key-popup-type' is minibuffer or
+`which-key-show-prefix' is echo. It needs to be less than
+`which-key-idle-delay' or else the keystroke echo will erase the
+which-key popup."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-max-description-length 27
+  "Truncate the description of keys to this length.
+Also adds \"..\". If nil, disable any truncation."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-add-column-padding 0
+  "Additional padding (number of spaces) to add to the left of
+each key column."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-unicode-correction 3
+  "Correction for wide unicode characters.
+Since we measure width in terms of the number of characters,
+Unicode characters that are wider than ASCII characters throw off
+the calculation for available width in the which-key buffer.  This
+variable allows you to adjust for the wide unicode characters by
+artificially reducing the available width in the buffer.
+
+The default of 3 means allow for the total extra width
+contributed by any wide unicode characters to be up to one
+additional ASCII character in the which-key buffer.  Increase this
+number if you are seeing charaters get cutoff on the right side
+of the which-key popup."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-dont-use-unicode nil
+  "If non-nil, don't use any unicode characters in default setup."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-separator
+  (if which-key-dont-use-unicode " : " " โ†’ ")
+  "Separator to use between key and description. Default is \" โ†’
+\", unless `which-key-dont-use-unicode' is non nil, in which case
+the default is \" : \"."
+  :group 'which-key
+  :type 'string)
+
+(defcustom which-key-prefix-prefix "+"
+  "String to insert in front of prefix commands (i.e., commands
+that represent a sub-map). Default is \"+\"."
+  :group 'which-key
+  :type 'string)
+
+(defcustom which-key-compute-remaps nil
+  "If non-nil, show remapped command if a command has been
+remapped given the currently active keymaps."
+  :group 'which-key
+  :type 'boolean)
+
+(defvar which-key-key-replacement-alist nil)
+(make-obsolete-variable 'which-key-key-replacement-alist
+                        'which-key-replacement-alist "2016-11-21")
+(defvar which-key-description-replacement-alist nil)
+(make-obsolete-variable 'which-key-description-replacement-alist
+                        'which-key-replacement-alist "2016-11-21")
+(defvar which-key-key-based-description-replacement-alist nil)
+(make-obsolete-variable 'which-key-key-based-description-replacement-alist
+                        'which-key-replacement-alist "2016-11-21")
+
+(defcustom which-key-replacement-alist
+  (delq nil
+        `(((nil . "Prefix Command") . (nil . "prefix"))
+          ((nil . "\\`\\?\\?\\'") . (nil . "lambda"))
+          ((nil . "which-key-show-next-page-no-cycle") . (nil . "wk next pg"))
+          (("<\\([[:alnum:]-]+\\)>") . ("\\1"))
+          ,@(unless which-key-dont-use-unicode
+              '((("left") . ("โ†"))
+                (("right") . ("โ†’"))))))
+  "Association list to determine how to manipulate descriptions
+of key bindings in the which-key popup. Each element of the list
+is a nested cons cell with the format
+
+\(MATCH CONS . REPLACEMENT\).
+
+The MATCH CONS determines when a replacement should occur and
+REPLACEMENT determines how the replacement should occur. Each may
+have the format \(KEY REGEXP . BINDING REGEXP\). For the
+replacement to apply the key binding must match both the KEY
+REGEXP and the BINDING REGEXP. A value of nil in either position
+can be used to match every possibility. The replacement is
+performed by using `replace-regexp-in-string' on the KEY REGEXP
+from the MATCH CONS and REPLACEMENT when it is a cons cell, and
+then similarly for the BINDING REGEXP. A nil value in the BINDING
+REGEXP position cancels the replacement. For example, the entry
+
+\(\(nil . \"Prefix Command\"\) . \(nil . \"prefix\"\)\)
+
+matches any binding with the descriptions \"Prefix Command\" and
+replaces the description with \"prefix\", ignoring the
+corresponding key.
+
+REPLACEMENT may also be a function taking a cons cell
+\(KEY . BINDING\) and producing a new corresponding cons cell.
+
+If REPLACEMENT is anything other than a cons cell \(and non nil\)
+the key binding is ignored by which-key.
+
+Finally, you can multiple replacements to occur for a given key
+binding by setting `which-key-allow-multiple-replacements' to a
+non-nil value."
+  :group 'which-key
+  :type '(alist :key-type (cons (choice regexp nil)
+                                (choice regexp nil))
+                :value-type (cons (choice string nil)
+                                  (choice string nil))))
+
+(when (bound-and-true-p which-key-key-replacement-alist)
+  (mapc
+   (lambda (repl)
+     (push (cons (cons (car repl) nil) (cons (cdr repl) nil))
+           which-key-replacement-alist))
+   which-key-key-replacement-alist))
+(when (bound-and-true-p which-key-description-replacement-alist)
+  (mapc
+   (lambda (repl)
+     (push (cons (cons nil (car repl)) (cons nil (cdr repl)))
+           which-key-replacement-alist))
+   which-key-description-replacement-alist))
+
+(defcustom which-key-allow-multiple-replacements nil
+  "Allow a key binding to match and be modified by multiple
+elements in `which-key-replacement-alist' if non-nil. When nil,
+only the first match is used to perform replacements from
+`which-key-replacement-alist'."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-highlighted-command-list '()
+  "A list of strings and/or cons cells used to highlight certain
+commands. If the element is a string, assume it is a regexp
+pattern for matching command names and use
+`which-key-highlighted-command-face' for any matching names. If
+the element is a cons cell, it should take the form (regexp .
+face to apply)."
+  :group 'which-key
+  :type  '(repeat (choice string (cons regexp face))))
+
+(defcustom which-key-special-keys '()
+  "These keys will automatically be truncated to one character
+and have `which-key-special-key-face' applied to them. This is
+disabled by default. Try this to see the effect.
+
+\(setq which-key-special-keys '(\"SPC\" \"TAB\" \"RET\" \"ESC\" \"DEL\")\)"
+  :group 'which-key
+  :type '(repeat string))
+
+(defcustom which-key-buffer-name " *which-key*"
+  "Name of which-key buffer."
+  :group 'which-key
+  :type 'string)
+
+(defcustom which-key-show-prefix 'echo
+  "Whether to and where to display the current prefix sequence.
+Possible choices are echo for echo area (the default), left, top
+and nil. Nil turns the feature off."
+  :group 'which-key
+  :type '(radio (const :tag "Left of the keys" left)
+                (const :tag "In the first line" top)
+                (const :tag "In the last line" bottom)
+                (const :tag "In the echo area" echo)
+                (const :tag "In the mode-line" mode-line)
+                (const :tag "Hide" nil)))
+
+(defcustom which-key-popup-type 'side-window
+  "Supported types are minibuffer, side-window, frame, and custom."
+  :group 'which-key
+  :type '(radio (const :tag "Show in minibuffer" minibuffer)
+                (const :tag "Show in side window" side-window)
+                (const :tag "Show in popup frame" frame)
+                (const :tag "Use your custom display functions" custom)))
+
+(defcustom which-key-min-display-lines 1
+  "The minimum number of horizontal lines to display in the
+  which-key buffer."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-max-display-columns nil
+  "The maximum number of columns to display in the which-key
+buffer. nil means don't impose a maximum."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-side-window-location 'bottom
+  "Location of which-key popup when `which-key-popup-type' is side-window.
+Should be one of top, bottom, left or right. You can also specify
+a list of two locations, like (right bottom). In this case, the
+first location is tried. If there is not enough room, the second
+location is tried."
+  :group 'which-key
+  :type '(radio (const right)
+                (const bottom)
+                (const left)
+                (const top)
+                (const (right bottom))
+                (const (bottom right))))
+
+(defcustom which-key-side-window-slot 0
+  "The `slot' to use for `display-buffer-in-side-window' when
+`which-key-popup-type' is 'side-window. Quoting from the
+docstring of `display-buffer-in-side-window',
+
+โ€˜slotโ€™ if non-nil, specifies the window slot where to display
+  BUFFER.  A value of zero or nil means use the middle slot on
+  the specified side.  A negative value means use a slot
+  preceding (that is, above or on the left of) the middle slot.
+  A positive value means use a slot following (that is, below or
+  on the right of) the middle slot.  The default is zero."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-side-window-max-width 0.333
+  "Maximum width of which-key popup when type is side-window and
+location is left or right.
+This variable can also be a number between 0 and 1. In that case, it denotes
+a percentage out of the frame's width."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-side-window-max-height 0.25
+  "Maximum height of which-key popup when type is side-window and
+location is top or bottom.
+This variable can also be a number between 0 and 1. In that case, it denotes
+a percentage out of the frame's height."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-frame-max-width 60
+  "Maximum width of which-key popup when type is frame."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-frame-max-height 20
+  "Maximum height of which-key popup when type is frame."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-allow-imprecise-window-fit nil
+  "If non-nil allow which-key to use a less intensive method of
+fitting the popup window to the buffer. If you are noticing lag
+when the which-key popup displays turning this on may help.
+
+See https://github.com/justbur/emacs-which-key/issues/130"
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-show-remaining-keys nil
+  "Show remaining keys in last slot, when keys are hidden."
+  :group 'which-key
+  :type '(radio (const :tag "Yes" t)
+                (const :tag "No" nil)))
+
+(defcustom which-key-sort-order 'which-key-key-order
+  "If nil, do not resort the output from
+`describe-buffer-bindings' which groups by mode. Ordering options
+are
+
+1. `which-key-key-order': by key (default)
+2. `which-key-key-order-alpha': by key using alphabetical order
+3. `which-key-description-order': by description
+4. `which-key-prefix-then-key-order': prefix (no prefix first) then key
+5. `which-key-local-then-key-order': local binding then key
+
+See the README and the docstrings for those functions for more
+information."
+  :group 'which-key
+  :type '(choice (function-item which-key-key-order)
+                 (function-item which-key-key-order-alpha)
+                 (function-item which-key-description-order)
+                 (function-item which-key-prefix-then-key-order)
+                 (function-item which-key-local-then-key-order)))
+
+(defcustom which-key-sort-uppercase-first t
+  "If non-nil, uppercase comes before lowercase in sorting
+function chosen in `which-key-sort-order'. Otherwise, the order
+is reversed."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-paging-prefixes '()
+  "Enable paging for these prefixes."
+  :group 'which-key
+  :type '(repeat string))
+
+(defcustom which-key-paging-key "<f5>"
+  "Key to use for changing pages. Bound after each of the
+prefixes in `which-key-paging-prefixes'"
+  :group 'which-key
+  :type 'string)
+
+;; (defcustom which-key-undo-key nil
+;;   "Key (string) to use for undoing keypresses. Bound recursively
+;; in each of the maps in `which-key-undo-keymaps'."
+;;   :group 'which-key
+;;   :type 'string)
+
+;; (defcustom which-key-undo-keymaps '()
+;;   "Keymaps in which to bind `which-key-undo-key'"
+;;   :group 'which-key
+;;   :type '(repeat symbol))
+
+(defcustom which-key-use-C-h-commands t
+  "Use C-h for paging if non-nil. Normally C-h after a prefix
+  calls `describe-prefix-bindings'. This changes that command to
+  a which-key paging command when which-key-mode is active."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-is-verbose nil
+  "Whether to warn about potential mistakes in configuration."
+  :group 'which-key
+  :type 'boolean)
+
+(defvar which-key-C-h-map
+  (let ((map (make-sparse-keymap)))
+    (dolist (bind '(("\C-a" . which-key-abort)
+                    ("a" . which-key-abort)
+                    ("\C-h" . which-key-show-standard-help)
+                    ("h" . which-key-show-standard-help)
+                    ("\C-n" . which-key-show-next-page-cycle)
+                    ("n" . which-key-show-next-page-cycle)
+                    ("\C-p" . which-key-show-previous-page-cycle)
+                    ("p" . which-key-show-previous-page-cycle)
+                    ("\C-u" . which-key-undo-key)
+                    ("u" . which-key-undo-key)))
+      (define-key map (car bind) (cdr bind)))
+    map)
+  "Keymap for C-h commands.")
+
+(defvar which-key--paging-functions '(which-key-C-h-dispatch
+                                      which-key-turn-page
+                                      which-key-show-next-page-cycle
+                                      which-key-show-next-page-no-cycle
+                                      which-key-show-previous-page-cycle
+                                      which-key-show-previous-page-no-cycle
+                                      which-key-undo-key
+                                      which-key-undo))
+
+(defcustom which-key-hide-alt-key-translations t
+  "Hide key translations using Alt key if non nil.
+These translations are not relevant most of the times since a lot
+of terminals issue META modifier for the Alt key.
+
+See http://www.gnu.org/software/emacs/manual/html_node/emacs/Modifier-Keys.html"
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-delay-functions nil
+  "A list of functions that may decide whether to delay the
+which-key popup based on the current incomplete key
+sequence. Each function in the list is run with two arguments,
+the current key sequence as produced by `key-description' and the
+length of the key sequence. If the popup should be delayed based
+on that key sequence, the function should return the delay time
+in seconds. Returning nil means no delay. The first function in
+this list to return a value is the value that is used.
+
+The delay time is effectively added to the normal
+`which-key-idle-delay'."
+  :group 'which-key
+  :type '(repeat function))
+
+(defcustom which-key-allow-regexps nil
+  "A list of regexp strings to use to filter key sequences. When
+non-nil, for a key sequence to trigger the which-key popup it
+must match one of the regexps in this list. The format of the key
+sequences is what is produced by `key-description'."
+  :group 'which-key
+  :type '(repeat regexp))
+
+(defcustom which-key-inhibit-regexps nil
+  "Similar to `which-key-allow-regexps', a list of regexp strings
+to use to filter key sequences. When non-nil, for a key sequence
+to trigger the which-key popup it cannot match one of the regexps
+in this list. The format of the key sequences is what is produced
+by `key-description'."
+  :group 'which-key
+  :type '(repeat regexp))
+
+(defcustom which-key-show-transient-maps nil
+  "Show keymaps created by `set-transient-map' when applicable.
+
+More specifically, detect when `overriding-terminal-local-map' is
+set (this is the keymap used by `set-transient-map') and display
+it."
+  :group 'which-key
+  :type 'boolean)
+
+;; Hooks
+(defcustom which-key-init-buffer-hook '()
+  "Hook run when which-key buffer is initialized."
+  :group 'which-key
+  :type 'hook)
+
+;;;; Faces
+
+(defgroup which-key-faces nil
+  "Faces for which-key-mode"
+  :group 'which-key
+  :prefix "which-key-")
+
+(defface which-key-key-face
+  '((t . (:inherit font-lock-constant-face)))
+  "Face for which-key keys"
+  :group 'which-key-faces)
+
+(defface which-key-separator-face
+  '((t . (:inherit font-lock-comment-face)))
+  "Face for the separator (default separator is an arrow)"
+  :group 'which-key-faces)
+
+(defface which-key-note-face
+  '((t . (:inherit which-key-separator-face)))
+  "Face for notes or hints occasionally provided"
+  :group 'which-key-faces)
+
+(defface which-key-command-description-face
+  '((t . (:inherit font-lock-function-name-face)))
+  "Face for the key description when it is a command"
+  :group 'which-key-faces)
+
+(defface which-key-local-map-description-face
+  '((t . (:inherit which-key-command-description-face)))
+  "Face for the key description when it is found in `current-local-map'"
+  :group 'which-key-faces)
+
+(defface which-key-highlighted-command-face
+  '((t . (:inherit which-key-command-description-face :underline t)))
+  "Default face for the command description when it is a command
+and it matches a string in `which-key-highlighted-command-list'."
+  :group 'which-key-faces)
+
+(defface which-key-group-description-face
+  '((t . (:inherit font-lock-keyword-face)))
+  "Face for the key description when it is a group or prefix"
+  :group 'which-key-faces)
+
+(defface which-key-special-key-face
+  '((t . (:inherit which-key-key-face :inverse-video t :weight bold)))
+  "Face for special keys (SPC, TAB, RET)"
+  :group 'which-key-faces)
+
+;;;; Custom popup
+
+(defcustom which-key-custom-popup-max-dimensions-function nil
+  "Variable to hold a custom max-dimensions function.
+Will be passed the width of the active window and is expected to
+return the maximum height in lines and width in characters of the
+which-key popup in the form a cons cell (height . width)."
+  :group 'which-key
+  :type 'function)
+
+(defcustom which-key-custom-hide-popup-function nil
+  "Variable to hold a custom hide-popup function.
+It takes no arguments and the return value is ignored."
+  :group 'which-key
+  :type 'function)
+
+(defcustom which-key-custom-show-popup-function nil
+  "Variable to hold a custom show-popup function.
+Will be passed the required dimensions in the form (height .
+width) in lines and characters respectively.  The return value is
+ignored."
+  :group 'which-key
+  :type 'function)
+
+(defcustom which-key-lighter " WK"
+  "Minor mode lighter to use in the mode-line."
+  :group 'which-key
+  :type 'string)
+
+(defvar which-key-inhibit nil
+  "Prevent which-key from popping up momentarily by setting this
+to a non-nil value for the execution of a command. Like this
+
+\(let \(\(which-key-inhibit t\)\)
+...\)")
+
+(defvar which-key-keymap-history nil
+  "History of keymap selections in functions like
+`which-key-show-keymap'.")
+
+;;; Internal Vars
+
+(defvar which-key--buffer nil
+  "Internal: Holds reference to which-key buffer.")
+(defvar which-key--timer nil
+  "Internal: Holds reference to open window timer.")
+(defvar which-key--secondary-timer-active nil
+  "Internal: Non-nil if the secondary timer is active.")
+(defvar which-key--paging-timer nil
+  "Internal: Holds reference to timer for paging.")
+(defvar which-key--frame nil
+  "Internal: Holds reference to which-key frame.
+Used when `which-key-popup-type' is frame.")
+(defvar which-key--echo-keystrokes-backup nil
+  "Internal: Backup the initial value of `echo-keystrokes'.")
+(defvar which-key--prefix-help-cmd-backup nil
+  "Internal: Backup the value of `prefix-help-command'.")
+(defvar which-key--pages-plist nil
+  "Internal: Holds page objects")
+(defvar which-key--current-prefix nil
+  "Internal: Holds current prefix")
+(defvar which-key--current-page-n nil
+  "Internal: Current pages of showing buffer. Nil means no buffer
+showing.")
+(defvar which-key--on-last-page nil
+  "Internal: Non-nil if showing last page.")
+(defvar which-key--last-try-2-loc nil
+  "Internal: Last location of side-window when two locations
+used.")
+(defvar which-key--multiple-locations nil)
+(defvar which-key--using-top-level nil)
+(defvar which-key--using-show-keymap nil)
+(defvar which-key--using-show-operator-keymap nil)
+(defvar which-key--inhibit-next-operator-popup nil)
+(defvar which-key--current-show-keymap-name nil)
+(defvar which-key--prior-show-keymap-args nil)
+(defvar which-key--previous-frame-size nil)
+(defvar which-key--prefix-title-alist nil)
+(defvar which-key--debug nil)
+
+(make-obsolete-variable 'which-key-prefix-name-alist nil "2016-10-05")
+(make-obsolete-variable 'which-key-prefix-title-alist nil "2016-10-05")
+
+;;; Third-party library support
+;;;; Evil
+
+(defcustom which-key-allow-evil-operators (boundp 'evil-this-operator)
+  "Allow popup to show for evil operators. The popup is normally
+  inhibited in the middle of commands, but setting this to
+  non-nil will override this behavior for evil operators."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-show-operator-state-maps nil
+  "Experimental: Try to show the right keys following an evil
+command that reads a motion, such as \"y\", \"d\" and \"c\" from
+normal state. This is experimental, because there might be some
+valid keys missing and it might be showing some invalid keys."
+  :group 'which-key
+  :type 'boolean)
+
+;;;;; God-mode
+
+(defvar which-key--god-mode-support-enabled nil
+  "Support god-mode if non-nil. This is experimental,
+so you need to explicitly opt-in for now. Please report any
+problems at github.")
+
+(defvar which-key--god-mode-key-string nil
+  "Holds key string to use for god-mode support.")
+
+(defadvice god-mode-lookup-command
+    (around which-key--god-mode-lookup-command-advice disable)
+  (setq which-key--god-mode-key-string (ad-get-arg 0))
+  (unwind-protect
+      ad-do-it
+    (when (bound-and-true-p which-key-mode)
+      (which-key--hide-popup))))
+
+(defun which-key-enable-god-mode-support (&optional disable)
+  "Enable support for god-mode if non-nil. This is experimental,
+so you need to explicitly opt-in for now. Please report any
+problems at github. If DISABLE is non-nil disable support."
+  (interactive "P")
+  (setq which-key--god-mode-support-enabled (null disable))
+  (if disable
+      (ad-disable-advice
+       'god-mode-lookup-command
+       'around 'which-key--god-mode-lookup-command-advice)
+    (ad-enable-advice
+     'god-mode-lookup-command
+     'around 'which-key--god-mode-lookup-command-advice))
+  (ad-activate 'god-mode-lookup-command))
+
+;;; Mode
+
+;;;###autoload
+(define-minor-mode which-key-mode
+  "Toggle which-key-mode."
+  :global t
+  :lighter which-key-lighter
+  :keymap (let ((map (make-sparse-keymap)))
+            (mapc
+             (lambda (prefix)
+               (define-key map
+                 (kbd (concat prefix " " which-key-paging-key))
+                 #'which-key-C-h-dispatch))
+             which-key-paging-prefixes)
+            map)
+  (if which-key-mode
+      (progn
+        (setq which-key--echo-keystrokes-backup echo-keystrokes)
+        (when (or (eq which-key-show-prefix 'echo)
+                  (eq which-key-popup-type 'minibuffer))
+          (which-key--setup-echo-keystrokes))
+        (unless (member prefix-help-command which-key--paging-functions)
+          (setq which-key--prefix-help-cmd-backup prefix-help-command))
+        (when which-key-use-C-h-commands
+          (setq prefix-help-command #'which-key-C-h-dispatch))
+        (when which-key-show-remaining-keys
+          (add-hook 'pre-command-hook #'which-key--lighter-restore))
+        (add-hook 'pre-command-hook #'which-key--hide-popup)
+        (add-hook 'focus-out-hook #'which-key--stop-timer)
+        (add-hook 'focus-in-hook #'which-key--start-timer)
+        (add-hook 'window-configuration-change-hook
+                  'which-key--hide-popup-on-frame-size-change)
+        (which-key--start-timer))
+    (setq echo-keystrokes which-key--echo-keystrokes-backup)
+    (when which-key--prefix-help-cmd-backup
+      (setq prefix-help-command which-key--prefix-help-cmd-backup))
+    (when which-key-show-remaining-keys
+      (remove-hook 'pre-command-hook #'which-key--lighter-restore))
+    (remove-hook 'pre-command-hook #'which-key--hide-popup)
+    (remove-hook 'focus-out-hook #'which-key--stop-timer)
+    (remove-hook 'focus-in-hook #'which-key--start-timer)
+    (remove-hook 'window-configuration-change-hook
+                 'which-key--hide-popup-on-frame-size-change)
+    (which-key--stop-timer)))
+
+(defun which-key--init-buffer ()
+  "Initialize which-key buffer"
+  (unless (buffer-live-p which-key--buffer)
+    (setq which-key--buffer (get-buffer-create which-key-buffer-name))
+    (with-current-buffer which-key--buffer
+      ;; suppress confusing minibuffer message
+      (let (message-log-max)
+        (toggle-truncate-lines 1)
+        (message ""))
+      (setq-local cursor-type nil)
+      (setq-local cursor-in-non-selected-windows nil)
+      (setq-local mode-line-format nil)
+      (setq-local word-wrap nil)
+      (setq-local show-trailing-whitespace nil)
+      (run-hooks 'which-key-init-buffer-hook))))
+
+(defun which-key--setup-echo-keystrokes ()
+  "Reduce `echo-keystrokes' if necessary (it will interfere if
+it's set too high)."
+  (when (and echo-keystrokes
+             (> (abs (- echo-keystrokes which-key-echo-keystrokes)) 0.000001))
+    (if (> which-key-idle-delay which-key-echo-keystrokes)
+        (setq echo-keystrokes which-key-echo-keystrokes)
+      (setq which-key-echo-keystrokes (/ (float which-key-idle-delay) 4)
+            echo-keystrokes which-key-echo-keystrokes))))
+
+(defun which-key-remove-default-unicode-chars ()
+  "Use of `which-key-dont-use-unicode' is preferred to this
+function, but it's included here in case someone cannot set that
+variable early enough in their configuration, if they are using a
+starter kit for example."
+  (when (string-equal which-key-separator " โ†’ ")
+    (setq which-key-separator " : "))
+  (setq which-key-key-replacement-alist
+        (delete '("left" . "โ†") which-key-key-replacement-alist))
+  (setq which-key-key-replacement-alist
+        (delete '("right" . "โ†’") which-key-key-replacement-alist)))
+
+;;; Default configuration functions for use by users.
+
+;;;###autoload
+(defun which-key-setup-side-window-right ()
+  "Apply suggested settings for side-window that opens on right."
+  (interactive)
+  (setq which-key-popup-type 'side-window
+        which-key-side-window-location 'right
+        which-key-show-prefix 'top))
+
+;;;###autoload
+(defun which-key-setup-side-window-right-bottom ()
+  "Apply suggested settings for side-window that opens on right
+if there is space and the bottom otherwise."
+  (interactive)
+  (setq which-key-popup-type 'side-window
+        which-key-side-window-location '(right bottom)
+        which-key-show-prefix 'top))
+
+;;;###autoload
+(defun which-key-setup-side-window-bottom ()
+  "Apply suggested settings for side-window that opens on
+bottom."
+  (interactive)
+  (which-key--setup-echo-keystrokes)
+  (setq which-key-popup-type 'side-window
+        which-key-side-window-location 'bottom
+        which-key-show-prefix 'echo))
+
+;;;###autoload
+(defun which-key-setup-minibuffer ()
+  "Apply suggested settings for minibuffer."
+  (interactive)
+  (which-key--setup-echo-keystrokes)
+  (setq which-key-popup-type 'minibuffer
+        which-key-show-prefix 'left))
+
+;;; Helper functions to modify replacement lists.
+
+;;;###autoload
+(defun which-key-add-key-based-replacements
+    (key-sequence replacement &rest more)
+  "Replace the description of KEY-SEQUENCE with REPLACEMENT.
+KEY-SEQUENCE is a string suitable for use in `kbd'. REPLACEMENT
+may either be a string, as in
+
+\(which-key-add-key-based-replacements \"C-x 1\" \"maximize\"\)
+
+a cons of two strings as in
+
+\(which-key-add-key-based-replacements \"C-x 8\"
+                                        '(\"unicode\" . \"Unicode keys\")\)
+
+or a function that takes a \(KEY . BINDING\) cons and returns a
+replacement.
+
+In the second case, the second string is used to provide a longer
+name for the keys under a prefix.
+
+MORE allows you to specifcy additional KEY REPLACEMENT pairs.  All
+replacements are added to
+`which-key-key-based-description-replacement-alist'."
+  ;; TODO: Make interactive
+  (while key-sequence
+    ;; normalize key sequences before adding
+    (let ((key-seq (key-description (kbd key-sequence)))
+          (replace (or (and (functionp replacement) replacement)
+                       (car-safe replacement)
+                       replacement)))
+      (push (cons (cons (concat "\\`" (regexp-quote key-seq) "\\'") nil)
+                  (if (functionp replace) replace (cons nil replace)))
+            which-key-replacement-alist)
+      (when (and (not (functionp replacement)) (consp replacement))
+        (push (cons key-seq (cdr-safe replacement))
+              which-key--prefix-title-alist)))
+    (setq key-sequence (pop more) replacement (pop more))))
+(put 'which-key-add-key-based-replacements 'lisp-indent-function 'defun)
+
+;;;###autoload
+(defun which-key-add-major-mode-key-based-replacements
+    (mode key-sequence replacement &rest more)
+  "Functions like `which-key-add-key-based-replacements'.
+The difference is that MODE specifies the `major-mode' that must
+be active for KEY-SEQUENCE and REPLACEMENT (MORE contains
+addition KEY-SEQUENCE REPLACEMENT pairs) to apply."
+  ;; TODO: Make interactive
+  (when (not (symbolp mode))
+    (error "MODE should be a symbol corresponding to a value of major-mode"))
+  (let ((mode-alist
+         (or (cdr-safe (assq mode which-key-replacement-alist)) (list)))
+        (title-mode-alist
+         (or (cdr-safe (assq mode which-key--prefix-title-alist)) (list))))
+    (while key-sequence
+    ;; normalize key sequences before adding
+      (let ((key-seq (key-description (kbd key-sequence)))
+            (replace (or (and (functionp replacement) replacement)
+                         (car-safe replacement)
+                         replacement)))
+        (push (cons (cons (concat "\\`" (regexp-quote key-seq) "\\'") nil)
+                    (if (functionp replace) replace (cons nil replace)))
+              mode-alist)
+        (when (and (not (functionp replacement)) (consp replacement))
+          (push (cons key-seq (cdr-safe replacement))
+                title-mode-alist)))
+      (setq key-sequence (pop more) replacement (pop more)))
+    (if (assq mode which-key-replacement-alist)
+        (setcdr (assq mode which-key-replacement-alist) mode-alist)
+      (push (cons mode mode-alist) which-key-replacement-alist))
+    (if (assq mode which-key--prefix-title-alist)
+        (setcdr (assq mode which-key--prefix-title-alist) title-mode-alist)
+      (push (cons mode title-mode-alist) which-key--prefix-title-alist))))
+(put 'which-key-add-major-mode-key-based-replacements
+     'lisp-indent-function 'defun)
+
+(defalias 'which-key-add-prefix-title 'which-key-add-key-based-replacements)
+(make-obsolete 'which-key-add-prefix-title
+               'which-key-add-key-based-replacements
+               "2016-10-05")
+
+(defalias 'which-key-declare-prefixes 'which-key-add-key-based-replacements)
+(make-obsolete 'which-key-declare-prefixes
+               'which-key-add-key-based-replacements
+               "2016-10-05")
+
+(defalias 'which-key-declare-prefixes-for-mode
+  'which-key-add-major-mode-key-based-replacements)
+(make-obsolete 'which-key-declare-prefixes-for-mode
+               'which-key-add-major-mode-key-based-replacements
+               "2016-10-05")
+
+(defun which-key-define-key-recursively (map key def &optional at-root)
+  "Recursively bind KEY in MAP to DEF on every level of MAP except the first.
+If AT-ROOT is non-nil the binding is also placed at the root of MAP."
+  (when at-root (define-key map key def))
+  (map-keymap
+   (lambda (_ev df)
+     (when (keymapp df)
+       (which-key-define-key-recursively df key def t)))
+   map))
+
+;;; Functions for computing window sizes
+
+(defun which-key--text-width-to-total (text-width)
+  "Convert window text-width to window total-width.
+TEXT-WIDTH is the desired text width of the window.  The function
+calculates what total width is required for a window in the
+selected to have a text-width of TEXT-WIDTH columns.  The
+calculation considers possible fringes and scroll bars.  This
+function assumes that the desired window has the same character
+width as the frame."
+  (let ((char-width (frame-char-width)))
+    (+ text-width
+       (/ (frame-fringe-width) char-width)
+       (/ (frame-scroll-bar-width) char-width)
+       (if (which-key--char-enlarged-p) 1 0)
+       ;; add padding to account for possible wide (unicode) characters
+       3)))
+
+(defun which-key--total-width-to-text (total-width)
+  "Convert window total-width to window text-width.
+TOTAL-WIDTH is the desired total width of the window.  The function calculates
+what text width fits such a window.  The calculation considers possible fringes
+and scroll bars.  This function assumes that the desired window has the same
+character width as the frame."
+  (let ((char-width (frame-char-width)))
+    (- total-width
+       (/ (frame-fringe-width) char-width)
+       (/ (frame-scroll-bar-width) char-width)
+       (if (which-key--char-enlarged-p) 1 0)
+       ;; add padding to account for possible wide (unicode) characters
+       3)))
+
+(defun which-key--char-enlarged-p (&optional _frame)
+  (> (frame-char-width)
+     (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--char-reduced-p (&optional _frame)
+  (< (frame-char-width)
+     (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--char-exact-p (&optional _frame)
+  (= (frame-char-width)
+     (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--width-or-percentage-to-width (width-or-percentage)
+  "Return window total width.
+If WIDTH-OR-PERCENTAGE is a whole number, return it unchanged.  Otherwise, it
+should be a percentage (a number between 0 and 1) out of the frame's width.
+More precisely, it should be a percentage out of the frame's root window's
+total width."
+  (if (wholenump width-or-percentage)
+      width-or-percentage
+    (round (* width-or-percentage (window-total-width (frame-root-window))))))
+
+(defun which-key--height-or-percentage-to-height (height-or-percentage)
+  "Return window total height.
+If HEIGHT-OR-PERCENTAGE is a whole number, return it unchanged.  Otherwise, it
+should be a percentage (a number between 0 and 1) out of the frame's height.
+More precisely, it should be a percentage out of the frame's root window's
+total height."
+  (if (wholenump height-or-percentage)
+      height-or-percentage
+    (round (* height-or-percentage (window-total-height (frame-root-window))))))
+
+(defun which-key--frame-size-changed-p ()
+  "Non-nil if a change in frame size is detected."
+  (let ((new-size (cons (frame-width) (frame-height))))
+    (cond ((null which-key--previous-frame-size)
+           (setq which-key--previous-frame-size new-size)
+           nil)
+          ((not (equal which-key--previous-frame-size new-size))
+           (setq which-key--previous-frame-size new-size)))))
+
+;;; Show/hide which-key buffer
+
+(defun which-key--hide-popup ()
+  "This function is called to hide the which-key buffer."
+  (unless (member real-this-command which-key--paging-functions)
+    (setq which-key--current-page-n nil
+          which-key--current-prefix nil
+          which-key--using-top-level nil
+          which-key--using-show-keymap nil
+          which-key--using-show-operator-keymap nil
+          which-key--current-show-keymap-name nil
+          which-key--prior-show-keymap-args nil
+          which-key--on-last-page nil)
+    (when (and which-key-idle-secondary-delay
+               which-key--secondary-timer-active)
+      (which-key--start-timer))
+    (which-key--lighter-restore)
+    (cl-case which-key-popup-type
+      ;; Not necessary to hide minibuffer
+      ;; (minibuffer (which-key--hide-buffer-minibuffer))
+      (side-window (which-key--hide-buffer-side-window))
+      (frame (which-key--hide-buffer-frame))
+      (custom (funcall which-key-custom-hide-popup-function)))))
+
+(defun which-key--hide-popup-ignore-command ()
+  "Version of `which-key--hide-popup' without the check of
+`real-this-command'."
+  (cl-case which-key-popup-type
+    (side-window (which-key--hide-buffer-side-window))
+    (frame (which-key--hide-buffer-frame))
+    (custom (funcall which-key-custom-hide-popup-function))))
+
+(defun which-key--hide-popup-on-frame-size-change ()
+  "Hide which-key popup if the frame is resized (to trigger a new
+popup)."
+  (when (which-key--frame-size-changed-p)
+    (which-key--hide-popup)))
+
+(defun which-key--hide-buffer-side-window ()
+  "Hide which-key buffer when side-window popup is used."
+  (when (buffer-live-p which-key--buffer)
+    ;; in case which-key buffer was shown in an existing window, `quit-window'
+    ;; will re-show the previous buffer, instead of closing the window
+    (quit-windows-on which-key--buffer)))
+
+(defun which-key--hide-buffer-frame ()
+  "Hide which-key buffer when frame popup is used."
+  (when (frame-live-p which-key--frame)
+    (delete-frame which-key--frame)))
+
+(defun which-key--popup-showing-p ()
+  (window-live-p (get-buffer-window which-key--buffer)))
+
+(defun which-key--show-popup (act-popup-dim)
+  "Show the which-key buffer.
+ACT-POPUP-DIM includes the dimensions, (height . width) of the
+buffer text to be displayed in the popup.  Return nil if no window
+is shown, or if there is no need to start the closing timer."
+  (when (and (> (car act-popup-dim) 0) (> (cdr act-popup-dim) 0))
+    (cl-case which-key-popup-type
+      ;; Not called for minibuffer
+      ;; (minibuffer (which-key--show-buffer-minibuffer act-popup-dim))
+      (side-window (which-key--show-buffer-side-window act-popup-dim))
+      (frame (which-key--show-buffer-frame act-popup-dim))
+      (custom (funcall which-key-custom-show-popup-function act-popup-dim)))))
+
+(defun which-key--fit-buffer-to-window-horizontally
+    (&optional window &rest params)
+  "Slightly modified version of `fit-buffer-to-window'.
+Use &rest params because `fit-buffer-to-window' has a different
+call signature in different emacs versions"
+  (let ((fit-window-to-buffer-horizontally t))
+    (apply #'fit-window-to-buffer window params)))
+
+(defun which-key--show-buffer-side-window (act-popup-dim)
+  "Show which-key buffer when popup type is side-window."
+  (let* ((height (car act-popup-dim))
+         (width (cdr act-popup-dim))
+         (alist
+          (if which-key-allow-imprecise-window-fit
+              `((window-width .  ,(which-key--text-width-to-total width))
+                (window-height . ,height)
+                (side . ,which-key-side-window-location)
+                (slot . ,which-key-side-window-slot))
+            `((window-width . which-key--fit-buffer-to-window-horizontally)
+              (window-height . (lambda (w) (fit-window-to-buffer w nil 1)))
+              (side . ,which-key-side-window-location)
+              (slot . ,which-key-side-window-slot)))))
+    ;; Previously used `display-buffer-in-major-side-window' here, but
+    ;; apparently that is meant to be an internal function. See emacs bug #24828
+    ;; and advice given there.
+    (cond
+     ((eq which-key--multiple-locations t)
+      ;; possibly want to switch sides in this case so we can't reuse the window
+      (delete-windows-on which-key--buffer)
+      (display-buffer-in-side-window which-key--buffer alist))
+     ((get-buffer-window which-key--buffer)
+      (display-buffer-reuse-window which-key--buffer alist))
+     (t
+      (display-buffer-in-side-window which-key--buffer alist)))))
+
+(defun which-key--show-buffer-frame (act-popup-dim)
+  "Show which-key buffer when popup type is frame."
+  (let* (;(orig-window (selected-window))
+         (frame-height (+ (car act-popup-dim)
+                          (if (with-current-buffer which-key--buffer
+                                mode-line-format)
+                              1
+                            0)))
+         ;; without adding 2, frame sometimes isn't wide enough for the buffer.
+         ;; this is probably because of the fringes. however, setting fringes
+         ;; sizes to 0 (instead of adding 2) didn't always make the frame wide
+         ;; enough. don't know why it is so.
+         (frame-width (+ (cdr act-popup-dim) 2))
+         (new-window (if (and (frame-live-p which-key--frame)
+                              (eq which-key--buffer
+                                  (window-buffer
+                                   (frame-root-window which-key--frame))))
+                         (which-key--show-buffer-reuse-frame
+                          frame-height frame-width)
+                       (which-key--show-buffer-new-frame
+                        frame-height frame-width))))
+    (when new-window
+      ;; display successful
+      (setq which-key--frame (window-frame new-window))
+      new-window)))
+
+(defun which-key--show-buffer-new-frame (frame-height frame-width)
+  "Helper for `which-key--show-buffer-frame'."
+  (let* ((frame-params `((height . ,frame-height)
+                         (width . ,frame-width)
+                         ;; tell the window manager to respect the given sizes
+                         (user-size . t)
+                         ;; which-key frame doesn't need a minibuffer
+                         (minibuffer . nil)
+                         (name . "which-key")
+                         ;; no need for scroll bars in which-key frame
+                         (vertical-scroll-bars . nil)
+                         ;; (left-fringe . 0)
+                         ;; (right-fringe . 0)
+                         ;; (right-divider-width . 0)
+                         ;; make sure frame is visible
+                         (visibility . t)))
+         (alist `((pop-up-frame-parameters . ,frame-params)))
+         (orig-frame (selected-frame))
+         (new-window (display-buffer-pop-up-frame which-key--buffer alist)))
+    (when new-window
+      ;; display successful
+      (redirect-frame-focus (window-frame new-window) orig-frame)
+      new-window)))
+
+(defun which-key--show-buffer-reuse-frame (frame-height frame-width)
+  "Helper for `which-key--show-buffer-frame'."
+  (let ((window
+         (display-buffer-reuse-window
+          which-key--buffer `((reusable-frames . ,which-key--frame)))))
+    (when window
+      ;; display successful
+      (set-frame-size (window-frame window) frame-width frame-height)
+      window)))
+
+;;; Max dimension of available window functions
+
+(defun which-key--popup-max-dimensions ()
+  "Dimesion functions should return the maximum possible (height
+. width) of the intended popup. SELECTED-WINDOW-WIDTH is the
+width of currently active window, not the which-key buffer
+window."
+  (cl-case which-key-popup-type
+    (minibuffer (which-key--minibuffer-max-dimensions))
+    (side-window (which-key--side-window-max-dimensions))
+    (frame (which-key--frame-max-dimensions))
+    (custom (funcall which-key-custom-popup-max-dimensions-function
+                     (window-width)))))
+
+(defun which-key--minibuffer-max-dimensions ()
+  "Return max-dimensions of minibuffer (height . width).
+Measured in lines and characters respectively."
+  (cons
+   ;; height
+   (if (floatp max-mini-window-height)
+       (floor (* (frame-text-lines)
+                 max-mini-window-height))
+     max-mini-window-height)
+   ;; width
+   (max 0 (- (frame-text-cols) which-key-unicode-correction))))
+
+(defun which-key--side-window-max-dimensions ()
+  "Return max-dimensions of the side-window popup (height .
+width) in lines and characters respectively."
+  (cons
+   ;; height
+   (if (member which-key-side-window-location '(left right))
+       ;; 1 is a kludge to make sure there is no overlap
+       (- (frame-height) (window-text-height (minibuffer-window)) 1)
+     ;; (window-mode-line-height which-key--window))
+     ;; FIXME: change to something like
+     ;; (min which-*-height (calculate-max-height))
+     (which-key--height-or-percentage-to-height
+      which-key-side-window-max-height))
+   ;; width
+   (max 0
+        (- (if (member which-key-side-window-location '(left right))
+               (which-key--total-width-to-text
+                (which-key--width-or-percentage-to-width
+                 which-key-side-window-max-width))
+             (which-key--total-width-to-text
+              (which-key--width-or-percentage-to-width
+               1.0)))
+           which-key-unicode-correction))))
+
+(defun which-key--frame-max-dimensions ()
+  "Return max-dimensions of the frame popup (height .
+width) in lines and characters respectively."
+  (cons which-key-frame-max-height which-key-frame-max-width))
+
+;;; Sorting functions
+
+(defun which-key--string< (a b &optional alpha)
+  (let* ((da (downcase a))
+         (db (downcase b)))
+    (cond ((string-equal da db)
+           (if which-key-sort-uppercase-first
+               (string-lessp a b)
+             (not (string-lessp a b))))
+          (alpha (string-lessp da db))
+          (t (string-lessp a b)))))
+
+(defun which-key--key-description< (a b &optional alpha)
+  "Sorting function used for `which-key-key-order' and
+`which-key-key-order-alpha'."
+  (save-match-data
+    (let* ((rngrgxp "^\\([^ ]+\\) \\.\\. [^ ]+")
+           (a (if (string-match rngrgxp a) (match-string 1 a) a))
+           (b (if (string-match rngrgxp b) (match-string 1 b) b))
+           (aem? (string-equal a ""))
+           (bem? (string-equal b ""))
+           (a1? (= 1 (length a)))
+           (b1? (= 1 (length b)))
+           (srgxp "^\\(RET\\|SPC\\|TAB\\|DEL\\|LFD\\|ESC\\|NUL\\)")
+           (asp? (string-match-p srgxp a))
+           (bsp? (string-match-p srgxp b))
+           (prrgxp "^\\(M\\|C\\|S\\|A\\|H\\|s\\)-")
+           (apr? (string-match-p prrgxp a))
+           (bpr? (string-match-p prrgxp b))
+           (afn? (string-match-p "<f[0-9]+>" a))
+           (bfn? (string-match-p "<f[0-9]+>" b)))
+      (cond ((or aem? bem?) (and aem? (not bem?)))
+            ((and asp? bsp?)
+             (if (string-equal (substring a 0 3) (substring b 0 3))
+                 (which-key--key-description<
+                  (substring a 3) (substring b 3) alpha)
+               (which-key--string< a b alpha)))
+            ((or asp? bsp?) asp?)
+            ((and a1? b1?) (which-key--string< a b alpha))
+            ((or a1? b1?) a1?)
+            ((and afn? bfn?)
+             (< (string-to-number
+                 (replace-regexp-in-string "<f\\([0-9]+\\)>" "\\1" a))
+                (string-to-number
+                 (replace-regexp-in-string "<f\\([0-9]+\\)>" "\\1" b))))
+            ((or afn? bfn?) afn?)
+            ((and apr? bpr?)
+             (if (string-equal (substring a 0 2) (substring b 0 2))
+                 (which-key--key-description<
+                  (substring a 2) (substring b 2) alpha)
+               (which-key--string< a b alpha)))
+            ((or apr? bpr?) apr?)
+            (t (which-key--string< a b alpha))))))
+
+(defsubst which-key-key-order-alpha (acons bcons)
+  "Order key descriptions A and B.
+Order is lexicographic within a \"class\", where the classes and
+the ordering of classes are listed below.
+
+special (SPC,TAB,...) < single char < mod (C-,M-,...) < other.
+Sorts single characters alphabetically with lowercase coming
+before upper."
+  (which-key--key-description< (car acons) (car bcons) t))
+
+(defsubst which-key-key-order (acons bcons)
+  "Order key descriptions A and B.
+Order is lexicographic within a \"class\", where the classes and
+the ordering of classes are listed below.
+
+special (SPC,TAB,...) < single char < mod (C-,M-,...) < other."
+  (which-key--key-description< (car acons) (car bcons)))
+
+(defsubst which-key-description-order (acons bcons)
+  "Order descriptions of A and B.
+Uses `string-lessp' after applying lowercase."
+  (string-lessp (downcase (cdr acons)) (downcase (cdr bcons))))
+
+(defsubst which-key--group-p (description)
+  (or (string-match-p "^\\(group:\\|Prefix\\)" description)
+      (keymapp (intern description))))
+
+(defun which-key-prefix-then-key-order (acons bcons)
+  "Order first by whether A and/or B is a prefix with no prefix
+coming before a prefix. Within these categories order using
+`which-key-key-order'."
+  (let ((apref? (which-key--group-p (cdr acons)))
+        (bpref? (which-key--group-p (cdr bcons))))
+    (if (not (eq apref? bpref?))
+        (and (not apref?) bpref?)
+      (which-key-key-order acons bcons))))
+
+(defun which-key-prefix-then-key-order-reverse (acons bcons)
+  "Order first by whether A and/or B is a prefix with prefix
+coming before a prefix. Within these categories order using
+`which-key-key-order'."
+  (let ((apref? (which-key--group-p (cdr acons)))
+        (bpref? (which-key--group-p (cdr bcons))))
+    (if (not (eq apref? bpref?))
+        (and apref? (not bpref?))
+      (which-key-key-order acons bcons))))
+
+(defun which-key-local-then-key-order (acons bcons)
+  "Order first by whether A and/or B is a local binding with
+local bindings coming first. Within these categories order using
+`which-key-key-order'."
+  (let ((aloc? (which-key--local-binding-p acons))
+        (bloc? (which-key--local-binding-p bcons)))
+    (if (not (eq aloc? bloc?))
+        (and aloc? (not bloc?))
+      (which-key-key-order acons bcons))))
+
+;;; Functions for retrieving and formatting keys
+
+(defsubst which-key--string-width (maybe-string)
+  "If MAYBE-STRING is a string use `which-key--string-width' o/w return 0."
+  (if (stringp maybe-string) (string-width maybe-string) 0))
+
+(defsubst which-key--safe-lookup-key (keymap key)
+  "Version of `lookup-key' that allows KEYMAP to be nil. KEY is not checked."
+  (when (keymapp keymap) (lookup-key keymap key)))
+
+(defsubst which-key--butlast-string (str)
+  (mapconcat #'identity (butlast (split-string str)) " "))
+
+(defun which-key--get-replacements (key-binding &optional use-major-mode)
+  (let ((alist (or (and use-major-mode
+                        (cdr-safe
+                         (assq major-mode which-key-replacement-alist)))
+                   which-key-replacement-alist))
+        res case-fold-search)
+    (catch 'res
+      (dolist (replacement alist)
+        ;; these are mode specific ones to ignore. The mode specific case is
+        ;; handled in the selection of alist
+        (unless (symbolp (car replacement))
+          (let ((key-regexp (caar replacement))
+                (binding-regexp (cdar replacement)))
+            (when (and (or (null key-regexp)
+                           (string-match-p key-regexp
+                                           (car key-binding)))
+                       (or (null binding-regexp)
+                           (string-match-p binding-regexp
+                                           (cdr key-binding))))
+              (push replacement res)
+              (when (not which-key-allow-multiple-replacements)
+                (throw 'res res)))))))
+    (nreverse res)))
+
+(defun which-key--maybe-replace (key-binding)
+  "Use `which-key--replacement-alist' to maybe replace KEY-BINDING.
+KEY-BINDING is a cons cell of the form \(KEY . BINDING\) each of
+which are strings. KEY is of the form produced by `key-binding'."
+  (let* ((mode-res (which-key--get-replacements key-binding t))
+         (all-repls (or mode-res
+                      (which-key--get-replacements key-binding))))
+    (dolist (repl all-repls key-binding)
+      (setq key-binding
+            (cond ((or (not (consp repl)) (null (cdr repl)))
+                   key-binding)
+                  ((functionp (cdr repl))
+                   (funcall (cdr repl) key-binding))
+                  ((consp (cdr repl))
+                   (cons
+                    (cond ((and (caar repl) (cadr repl))
+                           (replace-regexp-in-string
+                            (caar repl) (cadr repl) (car key-binding) t))
+                          ((cadr repl) (cadr repl))
+                          (t (car key-binding)))
+                    (cond ((and (cdar repl) (cddr repl))
+                           (replace-regexp-in-string
+                            (cdar repl) (cddr repl) (cdr key-binding) t))
+                          ((cddr repl) (cddr repl))
+                          (t (cdr key-binding))))))))))
+
+(defsubst which-key--current-key-list (&optional key-str)
+  (append (listify-key-sequence which-key--current-prefix)
+          (when key-str
+            (listify-key-sequence (kbd key-str)))))
+
+(defsubst which-key--current-key-string (&optional key-str)
+  (key-description (which-key--current-key-list key-str)))
+
+(defun which-key--local-binding-p (keydesc)
+  (eq (which-key--safe-lookup-key
+       (current-local-map) (kbd (which-key--current-key-string (car keydesc))))
+      (intern (cdr keydesc))))
+
+(defun which-key--maybe-get-prefix-title (keys)
+  "KEYS is a string produced by `key-description'.
+A title is possibly returned using
+`which-key--prefix-title-alist'.  An empty stiring is returned if
+no title exists."
+  (cond
+   ((not (string-equal keys ""))
+    (let* ((title-res
+            (cdr-safe (assoc-string keys which-key--prefix-title-alist)))
+           (repl-res
+            (cdr-safe (which-key--maybe-replace (cons keys ""))))
+           (binding (key-binding (kbd keys)))
+           (alternate (when (and binding (symbolp binding))
+                        (symbol-name binding))))
+      (cond (title-res title-res)
+            ((not (string-equal repl-res "")) repl-res)
+            ((and (eq which-key-show-prefix 'echo) alternate)
+             alternate)
+            ((and (member which-key-show-prefix '(bottom top))
+                  (eq which-key-side-window-location 'bottom)
+                  echo-keystrokes)
+             (if alternate alternate
+               (concat "Following " keys)))
+            (t ""))))
+    (which-key--using-top-level "Top-level bindings")
+    (which-key--current-show-keymap-name
+     which-key--current-show-keymap-name)
+    (t "")))
+
+(defun which-key--propertize-key (key)
+  "Add a face to KEY.
+If KEY contains any \"special keys\" defined in
+`which-key-special-keys' then truncate and add the corresponding
+`which-key-special-key-face'."
+  (let ((key-w-face (propertize key 'face 'which-key-key-face))
+        (regexp (concat "\\("
+                        (mapconcat 'identity which-key-special-keys
+                                   "\\|") "\\)"))
+        case-fold-search)
+    (save-match-data
+      (if (and which-key-special-keys
+               (string-match regexp key))
+          (let ((beg (match-beginning 0)) (end (match-end 0)))
+            (concat (substring key-w-face 0 beg)
+                    (propertize (substring key-w-face beg (1+ beg))
+                                'face 'which-key-special-key-face)
+                    (substring key-w-face end
+                               (which-key--string-width key-w-face))))
+        key-w-face))))
+
+(defsubst which-key--truncate-description (desc)
+  "Truncate DESC description to `which-key-max-description-length'."
+  (if (and which-key-max-description-length
+           (> (length desc) which-key-max-description-length))
+      (concat (substring desc 0 which-key-max-description-length) "..")
+    desc))
+
+(defun which-key--highlight-face (description)
+  "Return the highlight face for DESCRIPTION if it has one."
+  (let (face)
+    (dolist (el which-key-highlighted-command-list)
+      (unless face
+        (cond ((consp el)
+               (when (string-match-p (car el) description)
+                 (setq face (cdr el))))
+              ((stringp el)
+               (when (string-match-p el description)
+                 (setq face 'which-key-highlighted-command-face)))
+              (t
+               (message "which-key: warning: element %s of \
+which-key-highlighted-command-list is not a string or a cons
+cell" el)))))
+    face))
+
+(defun which-key--propertize-description
+    (description group local hl-face &optional original-description)
+  "Add face to DESCRIPTION where the face chosen depends on
+whether the description represents a group or a command. Also
+make some minor adjustments to the description string, like
+removing a \"group:\" prefix.
+
+ORIGINAL-DESCRIPTION is the description given by
+`describe-buffer-bindings'."
+  (let* ((desc description)
+         (desc (if (string-match-p "^group:" desc)
+                   (substring desc 6) desc))
+         (desc (if group (concat which-key-prefix-prefix desc) desc))
+         (desc (which-key--truncate-description desc)))
+    (make-text-button desc nil
+      'face (cond (hl-face hl-face)
+                  (group 'which-key-group-description-face)
+                  (local 'which-key-local-map-description-face)
+                  (t 'which-key-command-description-face))
+      'help-echo (cond
+                  ((and original-description
+                        (fboundp (intern original-description))
+                        (documentation (intern original-description))
+                        ;; tooltip-mode doesn't exist in emacs-nox
+                        (boundp 'tooltip-mode) tooltip-mode)
+                   (documentation (intern original-description)))
+                  ((and original-description
+                        (fboundp (intern original-description))
+                        (documentation (intern original-description))
+                        (let* ((doc (documentation
+                                     (intern original-description)))
+                               (str (replace-regexp-in-string "\n" " " doc))
+                               (max (floor (* (frame-width) 0.8))))
+                          (if (> (length str) max)
+                              (concat (substring str 0 max) "...")
+                            str))))))
+    desc))
+
+(defun which-key--extract-key (key-str)
+  "Pull the last key (or key range) out of KEY-STR."
+  (save-match-data
+    (let ((key-range-regexp "\\`.*\\([^ \t]+ \\.\\. [^ \t]+\\)\\'"))
+      (if (string-match key-range-regexp key-str)
+          (match-string 1 key-str)
+        (car (last (split-string key-str " ")))))))
+
+(defun which-key--format-and-replace (unformatted)
+  "Take a list of (key . desc) cons cells in UNFORMATTED, add
+faces and perform replacements according to the three replacement
+alists. Returns a list (key separator description)."
+  (let ((sep-w-face
+         (propertize which-key-separator 'face 'which-key-separator-face))
+        (local-map (current-local-map))
+        new-list)
+    (dolist (key-binding unformatted)
+      (let* ((key (car key-binding))
+             (orig-desc (cdr key-binding))
+             (group (which-key--group-p orig-desc))
+             ;; At top-level prefix is nil
+             (keys (if which-key--current-prefix
+                       (concat (which-key--current-key-string) " " key)
+                     key))
+             (local (eq (which-key--safe-lookup-key local-map (kbd keys))
+                        (intern orig-desc)))
+             (hl-face (which-key--highlight-face orig-desc))
+             (key-binding (which-key--maybe-replace (cons keys orig-desc))))
+        (when (consp key-binding)
+          (push
+           (list (which-key--propertize-key
+                  (which-key--extract-key (car key-binding)))
+                 sep-w-face
+                 (which-key--propertize-description
+                  (cdr key-binding) group local hl-face orig-desc))
+           new-list))))
+    (nreverse new-list)))
+
+(defun which-key--get-keymap-bindings (keymap &optional filter)
+  "Retrieve top-level bindings from KEYMAP."
+  (let (bindings)
+    (map-keymap
+     (lambda (ev def)
+       (unless (and (functionp filter) (funcall filter ev def))
+         (cl-pushnew
+          (cons (key-description (list ev))
+                (cond ((keymapp def) "Prefix Command")
+                      ((symbolp def) (copy-sequence (symbol-name def)))
+                      ((eq 'lambda (car-safe def)) "lambda")
+                      (t (format "%s" def))))
+          bindings :test (lambda (a b) (string= (car a) (car b))))))
+     keymap)
+    bindings))
+
+(defun which-key--compute-binding (binding)
+  "Replace BINDING with remapped binding if it exists.
+
+Requires `which-key-compute-remaps' to be non-nil"
+  (let (remap)
+    (if (and which-key-compute-remaps
+             (setq remap (command-remapping (intern binding))))
+        (copy-sequence (symbol-name remap))
+      binding)))
+
+(defun which-key--get-current-bindings ()
+  "Generate a list of current active bindings."
+  (let ((key-str-qt (regexp-quote (key-description which-key--current-prefix)))
+        (buffer (current-buffer))
+        (ignore-bindings '("self-insert-command" "ignore"
+                           "ignore-event" "company-ignore"))
+        (ignore-keys-regexp
+         (eval-when-compile
+           (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
+                         "select-window" "switch-frame" "-state"))))
+        (ignore-sections-regexp
+         (eval-when-compile
+           (regexp-opt '("Key translations" "Function key map translations"
+                         "Input decoding map translations")))))
+    (with-temp-buffer
+      (setq-local indent-tabs-mode t)
+      (setq-local tab-width 8)
+      (describe-buffer-bindings buffer which-key--current-prefix)
+      (goto-char (point-min))
+      (let ((header-p (not (= (char-after) ?\f)))
+            bindings header)
+        (while (not (eobp))
+          (cond
+           (header-p
+            (setq header (buffer-substring-no-properties
+                          (point)
+                          (line-end-position)))
+            (setq header-p nil)
+            (forward-line 3))
+           ((= (char-after) ?\f)
+            (setq header-p t))
+           ((looking-at "^[ \t]*$"))
+           ((or (not (string-match-p ignore-sections-regexp header))
+                which-key--current-prefix)
+            (let ((binding-start (save-excursion
+                                   (and (re-search-forward "\t+" nil t)
+                                        (match-end 0))))
+                  key binding)
+              (when binding-start
+                (setq key (buffer-substring-no-properties
+                           (point) binding-start))
+                (setq binding (buffer-substring-no-properties
+                               binding-start
+                               (line-end-position)))
+                (save-match-data
+                  (cond
+                   ((member binding ignore-bindings))
+                   ((string-match-p ignore-keys-regexp key))
+                   ((and which-key--current-prefix
+                         (string-match (format "^%s[ \t]\\([^ \t]+\\)[ \t]+$"
+                                               key-str-qt) key))
+                    (unless (assoc-string (match-string 1 key) bindings)
+                      (push (cons (match-string 1 key)
+                                  (which-key--compute-binding binding))
+                            bindings)))
+                   ((and which-key--current-prefix
+                         (string-match
+                          (format
+                           "^%s[ \t]\\([^ \t]+\\) \\.\\. %s[ \t]\\([^ \t]+\\)[ \t]+$"
+                           key-str-qt key-str-qt) key))
+                    (let ((stripped-key (concat (match-string 1 key)
+                                                " \.\. "
+                                                (match-string 2 key))))
+                      (unless (assoc-string stripped-key bindings)
+                        (push (cons stripped-key
+                                    (which-key--compute-binding binding))
+                              bindings))))
+                   ((string-match
+                     "^\\([^ \t]+\\|[^ \t]+ \\.\\. [^ \t]+\\)[ \t]+$" key)
+                    (unless (assoc-string (match-string 1 key) bindings)
+                      (push (cons (match-string 1 key)
+                                  (which-key--compute-binding binding))
+                            bindings)))))))))
+          (forward-line))
+        (nreverse bindings)))))
+
+(defun which-key--get-formatted-key-bindings (&optional bindings)
+  "Uses `describe-buffer-bindings' to collect the key bindings in
+BUFFER that follow the key sequence KEY-SEQ."
+  (let* ((unformatted (if bindings bindings (which-key--get-current-bindings))))
+    (when which-key-sort-order
+      (setq unformatted
+            (sort unformatted which-key-sort-order)))
+    (which-key--format-and-replace unformatted)))
+
+;;; Functions for laying out which-key buffer pages
+
+(defun which-key--normalize-columns (columns)
+  "Pad COLUMNS to the same length using empty strings."
+  (let ((max-len (cl-reduce (lambda (a x) (max a (length x))) columns
+                            :initial-value 0)))
+    (mapcar
+     (lambda (c)
+       (if (< (length c) max-len)
+           (append c (make-list (- max-len (length c)) ""))
+         c))
+     columns)))
+
+(defsubst which-key--join-columns (columns)
+  "Transpose columns into rows, concat rows into lines and rows into page."
+  (let* ((padded (which-key--normalize-columns (nreverse columns)))
+         (rows (apply #'cl-mapcar #'list padded)))
+    (mapconcat (lambda (row) (mapconcat #'identity row " ")) rows "\n")))
+
+(defsubst which-key--max-len (keys index)
+  "Internal function for finding the max length of the INDEX
+element in each list element of KEYS."
+  (cl-reduce
+   (lambda (x y) (max x (which-key--string-width (nth index y))))
+   keys :initial-value 0))
+
+(defun which-key--pad-column (col-keys)
+  "Take a column of (key separator description) COL-KEYS,
+calculate the max width in the column and pad all cells out to
+that width."
+  (let* ((col-key-width  (+ which-key-add-column-padding
+                            (which-key--max-len col-keys 0)))
+         (col-sep-width  (which-key--max-len col-keys 1))
+         (col-desc-width (which-key--max-len col-keys 2))
+         (col-width      (+ 1 col-key-width col-sep-width col-desc-width)))
+    (cons col-width
+          (mapcar (lambda (k)
+                    (format (concat "%" (int-to-string col-key-width)
+                                    "s%s%-" (int-to-string col-desc-width) "s")
+                            (nth 0 k) (nth 1 k) (nth 2 k)))
+                  col-keys))))
+
+(defun which-key--partition-list (n list)
+  "Partition LIST into N-sized sublists."
+  (let (res)
+    (while list
+      (setq res (cons (cl-subseq list 0 (min n (length list))) res)
+            list (nthcdr n list)))
+    (nreverse res)))
+
+(defun which-key--list-to-pages (keys avl-lines avl-width)
+  "Convert list of KEYS to columns based on dimensions AVL-LINES and AVL-WIDTH.
+Returns a plist that holds the page strings, as well as
+metadata."
+  (let ((cols-w-widths (mapcar #'which-key--pad-column
+                               (which-key--partition-list avl-lines keys)))
+        (page-width 0) (n-pages 0) (n-keys 0) (n-columns 0)
+        page-cols pages page-widths keys/page col)
+    (if (> (apply #'max (mapcar #'car cols-w-widths)) avl-width)
+        ;; give up if no columns fit
+        (list :pages nil :page-height 0 :page-widths '(0)
+              :keys/page '(0) :n-pages 0 :tot-keys 0)
+      (while cols-w-widths
+        ;; start new page
+        (cl-incf n-pages)
+        (setq col (pop cols-w-widths))
+        (setq page-cols (list (cdr col)))
+        (setq page-width (car col))
+        (setq n-keys (length (cdr col)))
+        (setq n-columns 1)
+        ;; add additional columns as long as they fit
+        (while (and cols-w-widths
+                    (or (null which-key-max-display-columns)
+                        (< n-columns which-key-max-display-columns))
+                    (<= (+ (caar cols-w-widths) page-width) avl-width))
+          (setq col (pop cols-w-widths))
+          (push (cdr col) page-cols)
+          (cl-incf page-width (car col))
+          (cl-incf n-keys (length (cdr col)))
+          (cl-incf n-columns))
+        (push (which-key--join-columns page-cols) pages)
+        (push n-keys keys/page)
+        (push page-width page-widths))
+      (list :pages (nreverse pages) :page-height avl-lines
+            :page-widths (nreverse page-widths)
+            :keys/page (reverse keys/page) :n-pages n-pages
+            :tot-keys (apply #'+ keys/page)))))
+
+(defun which-key--create-pages-1
+    (keys available-lines available-width &optional min-lines vertical)
+  "Create page strings using `which-key--list-to-pages'.
+Will try to find the best number of rows and columns using the
+given dimensions and the length and widths of ITEMS. Use VERTICAL
+if the ITEMS are laid out vertically and the number of columns
+should be minimized."
+  (let ((result (which-key--list-to-pages
+                 keys available-lines available-width))
+        (min-lines (or min-lines 0))
+        found prev-result)
+    (if (or vertical
+            (> (plist-get result :n-pages) 1)
+            (= 1 available-lines))
+        result
+      ;; simple search for a fitting page
+      (while (and (> available-lines min-lines)
+                  (not found))
+        (setq available-lines (- available-lines 1)
+              prev-result result
+              result (which-key--list-to-pages
+                      keys available-lines available-width)
+              found (> (plist-get result :n-pages) 1)))
+      (if found prev-result result))))
+
+(defun which-key--create-pages (keys)
+  "Create page strings using `which-key--list-to-pages'.
+Will try to find the best number of rows and columns using the
+given dimensions and the length and wdiths of KEYS. SEL-WIN-WIDTH
+is the width of the live window."
+  (let* ((max-dims (which-key--popup-max-dimensions))
+         (max-lines (car max-dims))
+         (max-width (cdr max-dims))
+         (prefix-keys-desc (key-description which-key--current-prefix))
+         (full-prefix (which-key--full-prefix prefix-keys-desc))
+         (prefix (when (eq which-key-show-prefix 'left)
+                   (+ 2 (which-key--string-width full-prefix))))
+         (prefix-top-bottom (member which-key-show-prefix '(bottom top)))
+         (avl-lines (if prefix-top-bottom (- max-lines 1) max-lines))
+         (min-lines (min avl-lines which-key-min-display-lines))
+         (avl-width (if prefix (- max-width prefix) max-width))
+         (vertical (and (eq which-key-popup-type 'side-window)
+                        (member which-key-side-window-location '(left right)))))
+    (which-key--create-pages-1 keys avl-lines avl-width min-lines vertical)))
+
+(defun which-key--lighter-status (page-n)
+  "Possibly show number of keys and total in the mode line."
+  (when which-key-show-remaining-keys
+    (let ((n-shown (nth page-n (plist-get which-key--pages-plist :keys/page)))
+          (n-tot (plist-get which-key--pages-plist :tot-keys)))
+      (setcar (cdr (assq 'which-key-mode minor-mode-alist))
+              (format " WK: %s/%s keys" n-shown n-tot)))))
+
+(defun which-key--lighter-restore ()
+  "Restore the lighter for which-key."
+  (when which-key-show-remaining-keys
+    (setcar (cdr (assq 'which-key-mode minor-mode-alist))
+            which-key-lighter)))
+
+(defun which-key--echo (text)
+  "Echo TEXT to minibuffer without logging."
+  (let (message-log-max)
+    (message "%s" text)))
+
+(defun which-key--next-page-hint (prefix-keys)
+  "Return string for next page hint."
+  (let* ((paging-key (concat prefix-keys " " which-key-paging-key))
+         (paging-key-bound (eq 'which-key-C-h-dispatch
+                               (key-binding (kbd paging-key))))
+         (key (if paging-key-bound which-key-paging-key "C-h")))
+    (when (and which-key-use-C-h-commands
+               (or which-key--using-show-operator-keymap
+                   (not (and which-key-allow-evil-operators
+                             (bound-and-true-p evil-this-operator)))))
+      (propertize (format "[%s paging/help]" key)
+                  'face 'which-key-note-face))))
+
+(eval-and-compile
+  (if (fboundp 'universal-argument--description)
+      (defalias 'which-key--universal-argument--description
+        'universal-argument--description)
+    (defun which-key--universal-argument--description ()
+      ;; Backport of the definition of universal-argument--description in
+      ;; emacs25 on 2015-12-04
+      (when prefix-arg
+        (concat "C-u"
+                (pcase prefix-arg
+                  (`(-) " -")
+                  (`(,(and (pred integerp) n))
+                   (let ((str ""))
+                     (while (and (> n 4) (= (mod n 4) 0))
+                       (setq str (concat str " C-u"))
+                       (setq n (/ n 4)))
+                     (if (= n 4) str (format " %s" prefix-arg))))
+                  (_ (format " %s" prefix-arg))))))))
+
+(defun which-key--full-prefix (prefix-keys &optional -prefix-arg dont-prop-keys)
+  "Return a description of the full key sequence up to now,
+including prefix arguments."
+  (let* ((left (eq which-key-show-prefix 'left))
+         (prefix-arg (if -prefix-arg -prefix-arg prefix-arg))
+         (str (concat
+               (which-key--universal-argument--description)
+               (when prefix-arg " ")
+               prefix-keys))
+         (dash (if (and which-key--current-prefix
+                        (null left)) "-" "")))
+    (if (or (eq which-key-show-prefix 'echo) dont-prop-keys)
+        (concat str dash)
+      (concat (which-key--propertize-key str)
+              (propertize dash 'face 'which-key-key-face)))))
+
+(defun which-key--get-popup-map ()
+  "Generate transient-map for use in the top level binding display."
+  (unless which-key--current-prefix
+    (let ((map (make-sparse-keymap)))
+      (define-key map (kbd which-key-paging-key) #'which-key-C-h-dispatch)
+      (when which-key-use-C-h-commands
+        ;; Show next page even when C-h is pressed
+        (define-key map (kbd "C-h") #'which-key-C-h-dispatch))
+      map)))
+
+(defun which-key--process-page (page-n pages-plist)
+  "Add information to the basic list of key bindings, including
+if applicable the current prefix, the name of the current prefix,
+and a page count."
+  (let* ((page (nth page-n (plist-get pages-plist :pages)))
+         (height (plist-get pages-plist :page-height))
+         (n-pages (plist-get pages-plist :n-pages))
+         (prefix-keys (key-description which-key--current-prefix))
+         (full-prefix (which-key--full-prefix prefix-keys))
+         (nxt-pg-hint (which-key--next-page-hint prefix-keys))
+         ;; not used in left case
+         (status-line
+          (concat (propertize (which-key--maybe-get-prefix-title
+                               (which-key--current-key-string))
+                              'face 'which-key-note-face)
+                  (when (< 1 n-pages)
+                    (propertize (format " (%s of %s)"
+                                        (1+ page-n) n-pages)
+                                'face 'which-key-note-face)))))
+    (pcase which-key-show-prefix
+      (`left
+       (let* ((page-cnt (propertize (format "%s/%s" (1+ page-n) n-pages)
+                                    'face 'which-key-separator-face))
+              (first-col-width (+ 2 (max (which-key--string-width full-prefix)
+                                         (which-key--string-width page-cnt))))
+              (prefix (format (concat "%-" (int-to-string first-col-width) "s")
+                              full-prefix))
+              (page-cnt (if (> n-pages 1)
+                            (format
+                             (concat "%-" (int-to-string first-col-width) "s")
+                             page-cnt)
+                          (make-string first-col-width 32)))
+              lines first-line new-end)
+         (if (= 1 height)
+             (cons (concat prefix page) nil)
+           (setq lines (split-string page "\n")
+                 first-line (concat prefix (car lines) "\n" page-cnt)
+                 new-end (concat "\n" (make-string first-col-width 32)))
+           (cons
+            (concat first-line (mapconcat #'identity (cdr lines) new-end))
+            nil))))
+      (`top
+       (cons
+        (concat (when (or (= 0 echo-keystrokes)
+                          (not (eq which-key-side-window-location 'bottom)))
+                  (concat full-prefix " "))
+                status-line " " nxt-pg-hint "\n" page)
+        nil))
+      (`bottom
+       (cons
+        (concat page "\n"
+                (when (or (= 0 echo-keystrokes)
+                          (not (eq which-key-side-window-location 'bottom)))
+                  (concat full-prefix " "))
+                status-line " " nxt-pg-hint)
+        nil))
+      (`echo
+       (cons page
+             (lambda ()
+               (which-key--echo
+                (concat full-prefix (when prefix-keys " ")
+                        status-line (when status-line " ")
+                        nxt-pg-hint)))))
+      (`mode-line
+       (cons page
+             (lambda ()
+               (with-current-buffer which-key--buffer
+                 (setq-local mode-line-format
+                             (concat " " full-prefix
+                                     " " status-line
+                                     " " nxt-pg-hint))))))
+      (_ (cons page nil)))))
+
+(defun which-key--show-page (n)
+  "Show page N, starting from 0."
+  (which-key--init-buffer) ;; in case it was killed
+  (let ((n-pages (plist-get which-key--pages-plist :n-pages))
+        (prefix-keys (key-description which-key--current-prefix))
+        page-n golden-ratio-mode)
+    (if (= 0 n-pages)
+        (message "%s- which-key can't show keys: There is not \
+enough space based on your settings and frame size." prefix-keys)
+      (setq page-n (mod n n-pages))
+      (setq which-key--current-page-n page-n)
+      (when (= n-pages (1+ n)) (setq which-key--on-last-page t))
+      (let ((page-echo (which-key--process-page page-n which-key--pages-plist))
+            (height (plist-get which-key--pages-plist :page-height))
+            (width
+             (nth page-n (plist-get which-key--pages-plist :page-widths))))
+        (which-key--lighter-status page-n)
+        (if (eq which-key-popup-type 'minibuffer)
+            (which-key--echo (car page-echo))
+          (with-current-buffer which-key--buffer
+            (erase-buffer)
+            (insert (car page-echo))
+            (goto-char (point-min)))
+          (when (cdr page-echo) (funcall (cdr page-echo)))
+          (which-key--show-popup (cons height width)))))
+    ;; used for paging at top-level
+    (if (fboundp 'set-transient-map)
+        (set-transient-map (which-key--get-popup-map))
+      (with-no-warnings
+        (set-temporary-overlay-map (which-key--get-popup-map))))))
+
+;;; Paging functions
+
+;;;###autoload
+(defun which-key-reload-key-sequence (key-seq)
+  "Simulate entering the key sequence KEY-SEQ.
+KEY-SEQ should be a list of events as produced by
+`listify-key-sequence'. Any prefix arguments that were used are
+reapplied to the new key sequence."
+  (let ((next-event (mapcar (lambda (ev) (cons t ev)) key-seq)))
+    (setq prefix-arg current-prefix-arg
+          unread-command-events next-event)))
+
+(defun which-key-turn-page (delta)
+  "Show the next page of keys."
+  (let ((next-page (if which-key--current-page-n
+                       (+ which-key--current-page-n delta) 0)))
+    (which-key-reload-key-sequence (which-key--current-key-list))
+    (if which-key--last-try-2-loc
+        (let ((which-key-side-window-location which-key--last-try-2-loc)
+              (which-key--multiple-locations t))
+          (which-key--show-page next-page))
+      (which-key--show-page next-page))
+    (which-key--start-paging-timer)))
+
+;;;###autoload
+(defun which-key-show-standard-help ()
+  "Call the command in `which-key--prefix-help-cmd-backup'.
+Usually this is `describe-prefix-bindings'."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key--hide-popup-ignore-command)
+    (cond ((eq which-key--prefix-help-cmd-backup
+               'describe-prefix-bindings)
+           ;; This is essentially what `describe-prefix-bindings' does
+           (describe-bindings
+            (kbd (which-key--current-key-string))))
+          ((functionp which-key--prefix-help-cmd-backup)
+           (funcall which-key--prefix-help-cmd-backup)))))
+
+;;;###autoload
+(defun which-key-show-next-page-no-cycle ()
+  "Show next page of keys unless on the last page, in which case
+call `which-key-show-standard-help'."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (if (and which-key--current-page-n
+             which-key--on-last-page)
+        (which-key-show-standard-help)
+      (which-key-turn-page 1))))
+
+;;;###autoload
+(defun which-key-show-previous-page-no-cycle ()
+  "Show previous page of keys unless on the first page, in which
+case do nothing."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (if (and which-key--current-page-n
+             (eq which-key--current-page-n 0))
+        (which-key-turn-page 0)
+      (which-key-turn-page -1))))
+
+;;;###autoload
+(defun which-key-show-next-page-cycle ()
+  "Show the next page of keys, cycling from end to beginning
+after last page."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key-turn-page 1)))
+
+;;;###autoload
+(defun which-key-show-previous-page-cycle ()
+  "Show the previous page of keys, cycling from beginning to end
+after first page."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key-turn-page -1)))
+
+;;;###autoload
+(defun which-key-show-top-level ()
+  "Show top-level bindings."
+  (interactive)
+  (setq which-key--using-top-level t)
+  (which-key--create-buffer-and-show nil))
+
+;;;###autoload
+(defun which-key-undo-key ()
+  "Undo last keypress and force which-key update."
+  (interactive)
+  (let* ((key-lst (butlast (which-key--current-key-list)))
+         (which-key-inhibit t))
+    (cond ((stringp which-key--current-show-keymap-name)
+           (if (keymapp (cdr (car-safe which-key--prior-show-keymap-args)))
+               (let ((args (pop which-key--prior-show-keymap-args)))
+                 (which-key--show-keymap (car args) (cdr args)))
+             (which-key--hide-popup)))
+          (key-lst
+           (which-key-reload-key-sequence key-lst)
+           (which-key--create-buffer-and-show (apply #'vector key-lst)))
+          (t (which-key-show-top-level)))))
+(defalias 'which-key-undo 'which-key-undo-key)
+
+(defun which-key-abort ()
+  "Abort key sequence."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key--hide-popup-ignore-command)
+    (keyboard-quit)))
+
+;;;###autoload
+(defun which-key-C-h-dispatch ()
+  "Dispatch C-h commands by looking up key in
+`which-key-C-h-map'. This command is always accessible (from any
+prefix) if `which-key-use-C-h-commands' is non nil."
+  (interactive)
+  (if (not (which-key--popup-showing-p))
+      (which-key-show-standard-help)
+    (let* ((prefix-keys (key-description which-key--current-prefix))
+           (full-prefix (which-key--full-prefix prefix-keys current-prefix-arg t))
+           (prompt (concat (when (string-equal prefix-keys "")
+                             (propertize
+                              (concat " "
+                                      (or which-key--current-show-keymap-name
+                                          "Top-level bindings"))
+                              'face 'which-key-note-face))
+                           full-prefix
+                           (propertize
+                            (substitute-command-keys
+                             (concat
+                              " \\<which-key-C-h-map>"
+                              " \\[which-key-show-next-page-cycle]"
+                              which-key-separator "next-page,"
+                              " \\[which-key-show-previous-page-cycle]"
+                              which-key-separator "previous-page,"
+                              " \\[which-key-undo-key]"
+                              which-key-separator "undo-key,"
+                              " \\[which-key-show-standard-help]"
+                              which-key-separator "help,"
+                              " \\[which-key-abort]"
+                              which-key-separator "abort"))
+                            'face 'which-key-note-face)))
+           (key (string (read-key prompt)))
+           (cmd (lookup-key which-key-C-h-map key))
+           (which-key-inhibit t))
+      (if cmd (funcall cmd) (which-key-turn-page 0)))))
+
+;;; Update
+
+(defun which-key--any-match-p (regexps string)
+  "Non-nil if any of REGEXPS match STRING."
+  (catch 'match
+    (dolist (regexp regexps)
+      (when (string-match-p regexp string)
+        (throw 'match t)))))
+
+(defun which-key--try-2-side-windows (keys page-n loc1 loc2 &rest _ignore)
+  "Try to show KEYS (PAGE-N) in LOC1 first.
+
+Only if no keys fit fallback to LOC2."
+  (let (pages1)
+    (let ((which-key-side-window-location loc1)
+          (which-key--multiple-locations t))
+      (setq pages1 (which-key--create-pages keys)))
+    (if (< 0 (plist-get pages1 :n-pages))
+        (progn
+          (setq which-key--pages-plist pages1)
+          (let ((which-key-side-window-location loc1)
+                (which-key--multiple-locations t))
+            (which-key--show-page page-n))
+          loc1)
+      (let ((which-key-side-window-location loc2)
+            (which-key--multiple-locations t))
+        (setq which-key--pages-plist
+              (which-key--create-pages keys))
+        (which-key--show-page page-n)
+        loc2))))
+
+(defun which-key-show-keymap ()
+  "Show the top-level bindings in KEYMAP using which-key. KEYMAP
+is selected interactively from all available keymaps."
+  (interactive)
+  (let ((keymap-sym (intern
+                     (completing-read
+                      "Keymap: " obarray
+                      (lambda (m)
+                        (and (boundp m)
+                             (keymapp (symbol-value m))
+                             (not (equal (symbol-value m)
+                                         (make-sparse-keymap)))))
+                      t nil 'which-key-keymap-history))))
+    (which-key--show-keymap (symbol-name keymap-sym)
+                            (symbol-value keymap-sym))))
+
+(defun which-key-show-minor-mode-keymap ()
+  "Show the top-level bindings in KEYMAP using which-key. KEYMAP
+is selected interactively by mode in `minor-mode-map-alist'."
+  (interactive)
+  (let ((mode-sym
+         (intern
+          (completing-read
+           "Minor Mode: "
+           (mapcar 'car
+                   (cl-remove-if-not
+                    (lambda (entry)
+                      (and (symbol-value (car entry))
+                           (not (equal (cdr entry) (make-sparse-keymap)))))
+                    minor-mode-map-alist))
+           nil t nil 'which-key-keymap-history))))
+    (which-key--show-keymap (symbol-name mode-sym)
+                            (cdr (assq mode-sym minor-mode-map-alist)))))
+
+(defun which-key--show-keymap (keymap-name keymap &optional prior-args)
+  (setq which-key--current-prefix nil
+        which-key--current-show-keymap-name keymap-name
+        which-key--using-show-keymap t)
+  (when prior-args (push prior-args which-key--prior-show-keymap-args))
+  (when (keymapp keymap)
+    (let ((formatted-keys (which-key--get-formatted-key-bindings
+                           (which-key--get-keymap-bindings keymap))))
+      (cond ((= (length formatted-keys) 0)
+             (message "which-key: Keymap empty"))
+            ((listp which-key-side-window-location)
+             (setq which-key--last-try-2-loc
+                   (apply #'which-key--try-2-side-windows
+                          formatted-keys 0 which-key-side-window-location)))
+            (t (setq which-key--pages-plist
+                     (which-key--create-pages formatted-keys))
+               (which-key--show-page 0)))))
+  (let* ((key (key-description (list (read-key))))
+         (next-def (lookup-key keymap (kbd key))))
+    (cond ((and which-key-use-C-h-commands (string= "C-h" key))
+           (which-key-C-h-dispatch))
+          ((keymapp next-def)
+           (which-key--hide-popup-ignore-command)
+           (which-key--show-keymap (concat keymap-name " " key) next-def
+                                   (cons keymap-name keymap)))
+          (t (which-key--hide-popup)))))
+
+(defun which-key--evil-operator-filter (_ev def)
+  (and (functionp def)
+       (evil-get-command-property def :suppress-operator)))
+
+(defun which-key--show-evil-operator-keymap ()
+  (if which-key--inhibit-next-operator-popup
+      (setq which-key--inhibit-next-operator-popup nil)
+    (let ((keymap
+           (make-composed-keymap (list evil-operator-shortcut-map
+                                       evil-operator-state-map
+                                       evil-motion-state-map))))
+      (setq which-key--current-prefix nil
+            which-key--current-show-keymap-name "evil operator/motion keys"
+            which-key--using-show-operator-keymap t)
+      (when (keymapp keymap)
+        (let ((formatted-keys (which-key--get-formatted-key-bindings
+                               (which-key--get-keymap-bindings
+                                keymap 'which-key--evil-operator-filter))))
+          (cond ((= (length formatted-keys) 0)
+                 (message "which-key: Keymap empty"))
+                ((listp which-key-side-window-location)
+                 (setq which-key--last-try-2-loc
+                       (apply #'which-key--try-2-side-windows
+                              formatted-keys 0 which-key-side-window-location)))
+                (t (setq which-key--pages-plist
+                         (which-key--create-pages formatted-keys))
+                   (which-key--show-page 0)))))
+      (let* ((key (key-description (list (read-key)))))
+        (when (string= key "`")
+          ;; evil-goto-mark reads the next char manually
+          (setq which-key--inhibit-next-operator-popup t))
+        (cond ((and which-key-use-C-h-commands (string= "C-h" key))
+               (which-key-C-h-dispatch))
+              ((string= key "ESC")
+               (which-key--hide-popup)
+               (keyboard-quit))
+              (t
+               (which-key--hide-popup)
+               (setq unread-command-events (listify-key-sequence key))))))))
+
+(defun which-key--create-buffer-and-show (&optional prefix-keys from-keymap)
+  "Fill `which-key--buffer' with key descriptions and reformat.
+Finally, show the buffer."
+  (setq which-key--current-prefix prefix-keys
+        which-key--last-try-2-loc nil)
+  (let ((start-time (when which-key--debug (current-time)))
+        (formatted-keys (which-key--get-formatted-key-bindings
+                         (when from-keymap
+                           (which-key--get-keymap-bindings from-keymap))))
+        (prefix-keys (key-description which-key--current-prefix)))
+    (cond ((= (length formatted-keys) 0)
+           (message "%s-  which-key: There are no keys to show" prefix-keys))
+          ((listp which-key-side-window-location)
+           (setq which-key--last-try-2-loc
+                 (apply #'which-key--try-2-side-windows
+                        formatted-keys 0 which-key-side-window-location)))
+          (t (setq which-key--pages-plist
+                   (which-key--create-pages formatted-keys))
+             (which-key--show-page 0)))
+    (when which-key--debug
+      (message "On prefix \"%s\" which-key took %.0f ms." prefix-keys
+               (* 1000 (float-time (time-since start-time)))))))
+
+(defun which-key--update ()
+  "Function run by timer to possibly trigger
+`which-key--create-buffer-and-show'."
+  (let ((prefix-keys (this-single-command-keys))
+        delay-time)
+    (when (and (equal prefix-keys [key-chord])
+               (bound-and-true-p key-chord-mode))
+      (setq prefix-keys
+            (condition-case nil
+                (let ((rkeys (recent-keys)))
+                  (vector 'key-chord
+                          ;; Take the two preceding the last one, because the
+                          ;; read-event call in key-chord seems to add a
+                          ;; spurious key press to this list. Note this is
+                          ;; different from guide-key's method which didn't work
+                          ;; for me.
+                          (aref rkeys (- (length rkeys) 3))
+                          (aref rkeys (- (length rkeys) 2))))
+              (error (progn
+                       (message "which-key error in key-chord handling")
+                       [key-chord])))))
+    (when (and which-key--god-mode-support-enabled
+               (bound-and-true-p god-local-mode)
+               (eq this-command 'god-mode-self-insert))
+      (setq prefix-keys (when which-key--god-mode-key-string
+                          (kbd which-key--god-mode-key-string))))
+    (cond ((and (> (length prefix-keys) 0)
+                (or (keymapp (key-binding prefix-keys))
+                    ;; Some keymaps are stored here like iso-transl-ctl-x-8-map
+                    (keymapp (which-key--safe-lookup-key
+                              key-translation-map prefix-keys))
+                    ;; just in case someone uses one of these
+                    (keymapp (which-key--safe-lookup-key
+                              function-key-map prefix-keys)))
+                (not which-key-inhibit)
+                (or (null which-key-allow-regexps)
+                    (which-key--any-match-p
+                     which-key-allow-regexps (key-description prefix-keys)))
+                (or (null which-key-inhibit-regexps)
+                    (not
+                     (which-key--any-match-p
+                      which-key-inhibit-regexps (key-description prefix-keys))))
+                ;; Do not display the popup if a command is currently being
+                ;; executed
+                (or (and which-key-allow-evil-operators
+                         (bound-and-true-p evil-this-operator))
+                    (and which-key--god-mode-support-enabled
+                         (bound-and-true-p god-local-mode)
+                         (eq this-command 'god-mode-self-insert))
+                    (null this-command)))
+           (when (and (not (equal prefix-keys which-key--current-prefix))
+                      (or (null which-key-delay-functions)
+                          (null (setq delay-time
+                                      (run-hook-with-args-until-success
+                                       'which-key-delay-functions
+                                       (key-description prefix-keys)
+                                       (length prefix-keys))))
+                          (sit-for delay-time)))
+             (which-key--create-buffer-and-show prefix-keys)
+             (when (and which-key-idle-secondary-delay
+                        (not which-key--secondary-timer-active))
+               (which-key--start-timer which-key-idle-secondary-delay t))))
+          ((and which-key-show-transient-maps
+                (keymapp overriding-terminal-local-map)
+                ;; basic test for it being a hydra
+                (not (eq (lookup-key overriding-terminal-local-map "\C-u")
+                         'hydra--universal-argument)))
+           (which-key--create-buffer-and-show
+            nil overriding-terminal-local-map))
+          ((and which-key-show-operator-state-maps
+                (bound-and-true-p evil-state)
+                (eq evil-state 'operator)
+                (not which-key--using-show-operator-keymap))
+           (which-key--show-evil-operator-keymap))
+          ((and which-key--current-page-n
+                (not which-key--using-top-level)
+                (not which-key--using-show-operator-keymap)
+                (not which-key--using-show-keymap))
+           (which-key--hide-popup)))))
+
+;;; Timers
+
+(defun which-key--start-timer (&optional delay secondary)
+  "Activate idle timer to trigger `which-key--update'."
+  (which-key--stop-timer)
+  (setq which-key--secondary-timer-active secondary)
+  (setq which-key--timer
+        (run-with-idle-timer
+         (if delay
+             delay
+           which-key-idle-delay) t #'which-key--update)))
+
+(defun which-key--stop-timer ()
+  "Deactivate idle timer for `which-key--update'."
+  (when which-key--timer (cancel-timer which-key--timer)))
+
+(defun which-key--start-paging-timer ()
+  "Activate timer to restart which-key after paging."
+  (when which-key--paging-timer (cancel-timer which-key--paging-timer))
+  (which-key--stop-timer)
+  (setq which-key--paging-timer
+        (run-with-idle-timer
+         0.2 t (lambda ()
+                 (when (or (not (member real-last-command
+                                        which-key--paging-functions))
+                           (and (< 0 (length (this-single-command-keys)))
+                                (not (equal which-key--current-prefix
+                                            (this-single-command-keys)))))
+                   (setq which-key--current-page-n nil
+                         which-key--on-last-page nil)
+                   (cancel-timer which-key--paging-timer)
+                   (which-key--start-timer))))))
+
+(provide 'which-key)
+;;; which-key.el ends here
.emacs.d/elpa/which-key-20170817.1107/which-key.elc
Binary file
.emacs.d/emacs.org
@@ -267,13 +267,35 @@
      (server-start))))
 #+END_SRC
 
+** Which-key
+
+Emacs has 100s of bindings and it is impossible to remember them
+all. Sometimes I can remember the start of a key chord but not the
+entire one. [[https://github.com/justbur/emacs-which-key][Which-key]] is a package that gives you key hints on delay
+or if prompted. I really like it and use it extensively to setup the
+modal state.
+
+#+BEGIN_SRC emacs-lisp :tangle init.el
+  (use-package which-key
+    :ensure t
+    :defer t
+    :diminish which-key-mode
+    :init
+    (setq which-key-sort-order 'which-key-key-order-alpha)
+    :bind* (("M-m ?" . which-key-show-top-level))
+    :config
+    (which-key-mode)
+    (which-key-add-key-based-replacements
+      "M-m ?" "top level bindings"))
+#+END_SRC
+
 * Load configurations
 
 It is now time to load other configuration.
 
 #+BEGIN_SRC emacs-lisp :tangle init.el
-  ;; (require 'evil-config)
   (use-package visual-config)
   (use-package org-config)
+  (use-package navigation-config)
 #+END_SRC
 
.emacs.d/init.el
@@ -103,6 +103,32 @@
     (unless (server-running-p server-name)
    (server-start))))
 
-;; (require 'evil-config)
+(use-package which-key
+  :ensure t
+  :defer t
+  :diminish which-key-mode
+  :init
+  (setq which-key-sort-order 'which-key-key-order-alpha)
+  :bind* (("M-m ?" . which-key-show-top-level))
+  :config
+  (which-key-mode)
+  (which-key-add-key-based-replacements
+    "M-m ?" "top level bindings"))
+
 (use-package visual-config)
 (use-package org-config)
+(use-package navigation-config)
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(package-selected-packages
+   (quote
+    (evil-indent-textobject evil-surround evil-jumper evil which-key delight diminish solaire-mode htmlize exec-path-from-shell doom-themes dashboard auto-compile))))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ )
.emacs.d/init.elc
Binary file