about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el4496
1 files changed, 4496 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el
new file mode 100644
index 0000000000..6ae1a45b79
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el
@@ -0,0 +1,4496 @@
+;;; 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.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; Evil is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-common)
+(require 'evil-digraphs)
+(require 'evil-search)
+(require 'evil-ex)
+(require 'evil-types)
+(require 'evil-command-window)
+(require 'evil-jumps)
+(require 'flyspell)
+(require 'cl-lib)
+(require 'reveal)
+
+;;; 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.
+Movement is restricted to the current line unless `evil-cross-lines' is non-nil."
+  :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
+  :jump t
+  (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
+  :jump t
+  (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")
+  (cond
+   ((fboundp 'xref-find-definitions)
+    (let ((xref-prompt-for-identifier arg))
+      (call-interactively #'xref-find-definitions)))
+   ((fboundp 'find-tag)
+    (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.")
+
+(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)
+    (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)))
+   (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
+       "Enable one of the following modes for folding to work: %s"
+       (mapconcat 'symbol-name (mapcar 'caar evil-fold-list) ", "))
+    (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) ?\s) (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))
+
+(defun evil-revert-reveal (open-spots)
+  "Unconditionally close overlays in OPEN-SPOTS in current window.
+Modified version of `reveal-close-old-overlays' from
+reveal.el. OPEN-SPOTS is a local version of `reveal-open-spots'."
+  (dolist (spot open-spots)
+    (let ((window (car spot))
+          (ol (cdr spot)))
+      (unless (eq window (selected-window))
+        (error "evil-revert-reveal: slot with wrong window"))
+      (let* ((inv (overlay-get ol 'reveal-invisible))
+             (open (or (overlay-get ol 'reveal-toggle-invisible)
+                       (get inv 'reveal-toggle-invisible)
+                       (overlay-get ol 'isearch-open-invisible-temporary))))
+        (if (and (overlay-start ol) ;Check it's still live.
+                 open)
+            (condition-case err
+                (funcall open ol t)
+              (error (message "!!Reveal-hide (funcall %s %s t): %s !!"
+                              open ol err)))
+          (overlay-put ol 'invisible inv))
+        ;; Remove the overlay from the list of open spots.
+        (overlay-put ol 'reveal-invisible nil)))))
+
+(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))
+         (use-reveal confirm)
+         reveal-open-spots
+         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)
+              (when (not (and query-replace-skip-read-only
+                              (text-property-any (match-beginning 0) (match-end 0) 'read-only 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" (buffer-substring-no-properties
+                                              match-beg match-end)))
+                  (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))
+                  (setq evil-ex-substitute-last-point match-beg)
+                  (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))))
+                            (search-invisible t)
+                            response)
+                        (move-overlay evil-ex-substitute-overlay match-beg match-end)
+                        ;; Simulate `reveal-mode'. `reveal-mode' uses
+                        ;; `post-command-hook' but that won't work here.
+                        (when use-reveal
+                          (reveal-post-command))
+                        (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-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))))
+                  (goto-char match-end)
+                  (cond ((>= (point) end-marker)
+                         ;; Don't want to perform multiple replacements at the end
+                         ;; of the search region.
+                         (throw 'exit-search t))
+                        ((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)
+
+      (when use-reveal
+        (evil-revert-reveal reveal-open-spots)))
+
+    (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 evil-ex-search-case) 'insensitive))
+          (command-form (evil-ex-parse command))
+          (transient-mark-mode transient-mark-mode)
+          (deactivate-mark deactivate-mark)
+          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)
+              (eval command-form))
+          ;; 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-key))
+               (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