;; evil-tests.el --- unit tests for Evil -*- coding: utf-8 -*- ;; Author: Vegard Øye ;; Maintainer: Vegard Øye ;; Version: 1.15.0 ;; ;; 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 . ;;; Commentary: ;; This file is for developers. It runs some tests on Evil. ;; To load it, run the Makefile target "make test" or add ;; the following lines to .emacs: ;; ;; (setq evil-tests-run nil) ; set to t to run tests immediately ;; (global-set-key [f12] 'evil-tests-run) ; hotkey ;; (require 'evil-tests) ;; ;; Loading this file enables profiling on Evil. The current numbers ;; can be displayed with `elp-results'. The Makefile target ;; "make profiler" shows profiling results in the terminal on the ;; basis of running all tests. ;; ;; To write a test, use `ert-deftest' and specify a :tags value of at ;; least '(evil). The test may inspect the output of functions given ;; certain input, or it may execute a key sequence in a temporary ;; buffer and investigate the results. For the latter approach, the ;; macro `evil-test-buffer' creates a temporary buffer in Normal ;; state. String descriptors initialize and match the contents of ;; the buffer: ;; ;; (ert-deftest evil-test () ;; :tags '(evil) ;; (evil-test-buffer ;; "[T]his creates a test buffer." ; cursor on "T" ;; ("w") ; key sequence ;; "This [c]reates a test buffer."))) ; cursor moved to "c" ;; ;; The initial state, the cursor syntax, etc., can be changed ;; with keyword arguments. See the documentation string of ;; `evil-test-buffer' for more details. ;; ;; This file is NOT part of Evil itself. (require 'cl-lib) (require 'elp) (require 'ert) (require 'evil) (require 'evil-test-helpers) ;;; Code: (defvar evil-tests-run nil "*Run Evil tests.") (defvar evil-tests-profiler nil "*Profile Evil tests.") (defun evil-tests-initialize (&optional tests profiler interactive) (setq profiler (or profiler evil-tests-profiler)) (when (listp profiler) (setq profiler (car profiler))) (when profiler (setq evil-tests-profiler t) (setq profiler (or (cdr (assq profiler '((call . elp-sort-by-call-count) (average . elp-sort-by-average-time) (total . elp-sort-by-total-time)))))) (setq elp-sort-by-function (or profiler 'elp-sort-by-call-count)) (elp-instrument-package "evil")) (if interactive (if (y-or-n-p-with-timeout "Run tests? " 2 t) (evil-tests-run tests interactive) (message "You can run the tests at any time \ with `M-x evil-tests-run'")) (evil-tests-run tests))) (defun evil-tests-run (&optional tests interactive) "Run Evil tests." (interactive '(nil t)) (let ((elp-use-standard-output (not interactive))) (setq tests (or (null tests) `(or ,@(mapcar #'(lambda (test) (or (null test) (and (memq test '(evil t)) t) `(or (tag ,test) ,(format "^%s$" test)))) tests)))) (cond (interactive (ert-run-tests-interactively tests) (when evil-tests-profiler (elp-results))) (evil-tests-profiler (ert-run-tests-batch tests) (elp-results)) (t ;; We would like to use `ert-run-tests-batch-and-exit' ;; Unfortunately it doesn't work outside of batch mode, and we ;; can't use batch mode because we have tests that need windows. ;; Instead, run the tests interactively, copy the results to a ;; text file, and then exit with an appropriate code. (setq attempt-stack-overflow-recovery nil attempt-orderly-shutdown-on-fatal-signal nil) (unwind-protect (progn (ert-run-tests-interactively tests) (with-current-buffer "*ert*" (append-to-file (point-min) (point-max) "test-results.txt") (kill-emacs (if (zerop (ert-stats-completed-unexpected ert--results-stats)) 0 1)))) (unwind-protect (progn (append-to-file "Error running tests\n" nil "test-results.txt") (append-to-file (backtrace-to-string (backtrace-get-frames 'backtrace)) nil "test-results.txt")) (kill-emacs 2))))))) (defun evil-tests-profiler (&optional force) "Profile Evil tests." (when (or evil-tests-profiler force) (setq evil-tests-profiler t) (elp-instrument-package "evil"))) ;;; States (defun evil-test-local-mode-enabled () "Verify that `evil-local-mode' is enabled properly" (ert-info ("Set the mode variable to t") (should (eq evil-local-mode t))) (ert-info ("Refresh `emulation-mode-map-alist'") (should (memq 'evil-mode-map-alist emulation-mode-map-alists))) (ert-info ("Create a buffer-local value for `evil-mode-map-alist'") (should (assq 'evil-mode-map-alist (buffer-local-variables)))) (ert-info ("Initialize buffer-local keymaps") (should (assq 'evil-normal-state-local-map (buffer-local-variables))) (should (keymapp evil-normal-state-local-map)) (should (assq 'evil-emacs-state-local-map (buffer-local-variables))) (should (keymapp evil-emacs-state-local-map))) (ert-info ("Don't add buffer-local entries to the default value") (should-not (rassq evil-normal-state-local-map (default-value 'evil-mode-map-alist))) (should-not (rassq evil-emacs-state-local-map (default-value 'evil-mode-map-alist))))) (defun evil-test-local-mode-disabled () "Verify that `evil-local-mode' is disabled properly" (ert-info ("Set the mode variable to nil") (should-not evil-local-mode)) (ert-info ("Disable all states") (evil-test-no-states))) (defun evil-test-no-states () "Verify that all states are disabled" (ert-info ("Set `evil-state' to nil") (should-not evil-state)) (ert-info ("Disable all state keymaps") (dolist (state (mapcar #'car evil-state-properties) t) (should-not (evil-state-property state :mode t)) (should-not (memq (evil-state-property state :keymap t) (current-active-maps))) (should-not (evil-state-property state :local t)) (should-not (memq (evil-state-property state :local-keymap t) (current-active-maps))) (dolist (map (evil-state-auxiliary-keymaps state)) (should-not (memq map (current-active-maps))))))) (ert-deftest evil-test-toggle-local-mode () "Toggle `evil-local-mode'" :tags '(evil state) (with-temp-buffer (ert-info ("Enable `evil-local-mode'") (evil-local-mode 1) (evil-test-local-mode-enabled)) (ert-info ("Disable `evil-local-mode'") (evil-local-mode -1) (evil-test-local-mode-disabled)))) (defun evil-test-change-state (state) "Change state to STATE and check keymaps" (let (mode keymap local-mode local-keymap tag) (evil-change-state state) (setq mode (evil-state-property state :mode) keymap (evil-state-property state :keymap t) local-mode (evil-state-property state :local) local-keymap (evil-state-property state :local-keymap t) tag (evil-state-property state :tag t)) (when (functionp tag) (setq tag (funcall tag))) (ert-info ("Update `evil-state'") (should (eq evil-state state))) (ert-info ("Ensure `evil-local-mode' is enabled") (evil-test-local-mode-enabled)) (ert-info ("Enable state modes") (should (symbol-value mode)) (should (symbol-value local-mode))) (ert-info ("Push state keymaps to the top") (evil-test-state-keymaps state)) (ert-info ("Refresh mode line tag") (should (equal evil-mode-line-tag tag))))) (defun evil-test-state-keymaps (state) "Verify that STATE's keymaps are pushed to the top" (let ((actual (evil-state-keymaps state)) (expected `((,(evil-state-property state :local) . , (evil-state-property state :local-keymap t)) (,(evil-state-property state :mode) . ,(evil-state-property state :keymap t))))) ;; additional keymaps inherited with :enable (cond ((eq state 'operator) (setq expected `((evil-operator-shortcut-mode . ,evil-operator-shortcut-map) (evil-operator-state-local-minor-mode . ,evil-operator-state-local-map) (evil-operator-state-minor-mode . ,evil-operator-state-map) (evil-motion-state-local-minor-mode . ,evil-motion-state-local-map) (evil-motion-state-minor-mode . ,evil-motion-state-map) (evil-normal-state-local-minor-mode . ,evil-normal-state-local-map) (evil-normal-state-minor-mode . ,evil-normal-state-map))))) (let ((actual (butlast actual (- (length actual) (length expected))))) (should (equal actual expected)) (dolist (map actual) (setq map (cdr-safe map)) (should (keymapp map)))))) (ert-deftest evil-test-exit-normal-state () "Enter Normal state and then disable all states" :tags '(evil state) (with-temp-buffer (evil-test-change-state 'normal) (evil-normal-state -1) (evil-test-no-states))) (ert-deftest evil-test-change-states () "Change between Normal state, Emacs state and Operator-Pending state" :tags '(evil state) (with-temp-buffer (evil-test-change-state 'normal) (evil-test-change-state 'emacs) (evil-test-change-state 'normal) (evil-test-change-state 'operator) (evil-test-change-state 'normal) (evil-test-change-state 'emacs) (evil-test-change-state 'replace) (evil-test-change-state 'normal))) (ert-deftest evil-test-change-to-previous-state () "Change to some state and back." :tags '(evil state) (with-temp-buffer (evil-test-change-state 'normal) (evil-test-change-state 'visual) (evil-test-change-state 'emacs) (evil-change-to-previous-state) (should (eq evil-state 'visual)) (evil-change-to-previous-state) (should (eq evil-state 'normal)))) (ert-deftest evil-test-enter-normal-state-disabled () "Enter Normal state even if `evil-local-mode' is disabled" :tags '(evil state) (with-temp-buffer (evil-local-mode -1) (evil-test-local-mode-disabled) (evil-test-change-state 'normal))) (ert-deftest evil-test-execute-in-normal-state () "Test `evil-execute-in-normal-state'." :tags '(evil) (ert-info ("Execute normal state command in insert state") (evil-test-buffer "[a]bcdef\n" ("I") (should (evil-insert-state-p)) ("\C-ox") (ert-info ("Should return to insert state") (should (evil-insert-state-p))) "[b]cdef\n" ("\C-oA") (ert-info ("Should return to insert state after insert state command") (should (evil-insert-state-p))) ("bcdef[]\n")) (ert-info ("Cursor is placed correctly afterwards") (evil-test-buffer :state insert "abcdefg[]" ("\C-o~") "abcdefG[]") (evil-test-buffer :state insert "abcdefg[]" ("\C-ozz") "abcdefg[]") (evil-test-buffer :state insert "abc[]defg" ("\C-o$") "abcdefg[]") (evil-test-buffer :state insert "abcdefg[]" ("\C-o^") "[]abcdefg") (evil-test-buffer :state insert "abcdefg[]" ("\C-oi") "abcdef[]g") (evil-test-buffer "line1\nli[n]e2" ("ma" "kA" "\C-o`a") "line1\nli[]ne2")) (ert-info ("Can enter replace state and stay in it") (evil-test-buffer :state insert "abc[]defg" ("\C-oRfoo") "abcfoog")) (ert-info ("Insert count is ignored") (evil-test-buffer "[]" ("2i" "abcdef" "\C-o~" "g" [escape]) "abcdeF[g]")) (ert-info ("Can execute evil-repeat in normal state") (evil-test-buffer ;; Although this is the same in vim, text inserted after the temporary ;; normal command is not recorded for repetition, which is a subtle ;; (but arguably more useful) difference :state insert "ab[]cfg" ("\C-o~de\C-o.") "abCdeF[]g")))) (defun evil-test-suppress-keymap (state) "Verify that `self-insert-command' is suppressed in STATE" (evil-test-buffer ";; This buffer is for notes." (evil-test-change-state state) ;; TODO: this should be done better (ert-info ("Disable the state's own keymaps so that the suppression keymap comes first") (setq evil-operator-state-minor-mode nil evil-operator-state-local-minor-mode nil)) (should (eq (key-binding "Q") #'undefined)) (ert-info ("Don't insert text") ;; may or may not signal an error, depending on batch mode (condition-case nil (execute-kbd-macro "QQQ") (error nil)) (should (string= (buffer-substring 1 4) ";; "))))) (ert-deftest evil-test-emacs-state-suppress-keymap () "`self-insert-command' works in Emacs state" :tags '(evil state) (should-error (evil-test-suppress-keymap 'emacs))) (ert-deftest evil-test-normal-state-suppress-keymap () "No `self-insert-command' in Normal state" :tags '(evil state) (evil-test-suppress-keymap 'normal)) (ert-deftest evil-test-operator-state-suppress-keymap () "Operator-Pending state should inherit suppression of `self-insert-command' from Normal state" :tags '(evil state) (evil-test-suppress-keymap 'operator)) (ert-deftest evil-test-operator-state-shortcut-keymap () "Enable shortcut keymap in Operator-Pending state" :tags '(evil state) (evil-test-buffer (ert-info ("Activate `evil-operator-shortcut-map' in \ Operator-Pending state") (evil-test-change-state 'operator) (should (rassq evil-operator-shortcut-map (evil-state-keymaps 'operator))) (should (keymapp evil-operator-shortcut-map)) (should evil-operator-shortcut-mode) (should (memq evil-operator-shortcut-map (current-active-maps)))) (ert-info ("Deactivate `evil-operator-shortcut-map' \ outside Operator-Pending state") (evil-test-change-state 'emacs) (should-not evil-operator-shortcut-mode) (should-not (memq evil-operator-shortcut-map (current-active-maps)))) (ert-info ("Reset `evil-operator-shortcut-map' \ when entering Operator-Pending state") (define-key evil-operator-shortcut-map "f" 'foo) (should (eq (lookup-key evil-operator-shortcut-map "f") 'foo)) (evil-test-change-state 'operator) (should-not (eq (lookup-key evil-operator-shortcut-map "f") 'foo))) (ert-info ("Reset `evil-operator-shortcut-map' \ when exiting Operator-Pending state") (define-key evil-operator-shortcut-map "b" 'bar) (should (eq (lookup-key evil-operator-shortcut-map "b") 'bar)) (evil-test-change-state 'emacs) (should-not (eq (lookup-key evil-operator-shortcut-map "b") 'bar))))) (ert-deftest evil-test-auxiliary-maps () "Test auxiliary keymaps" :tags '(evil state) (let ((map (make-sparse-keymap)) aux) (ert-info ("Create a new auxiliary keymap") (evil-define-key 'normal map "f" 'foo) (setq aux (evil-get-auxiliary-keymap map 'normal)) (should (evil-auxiliary-keymap-p aux)) (should (eq (lookup-key aux "f") 'foo))) (ert-info ("Add to auxiliary keymap") (evil-define-key 'normal map "b" 'bar) (should (eq (lookup-key aux "f") 'foo)) (should (eq (lookup-key aux "b") 'bar))))) (ert-deftest evil-test-global-local-map-binding () "Test use of `evil-define-key' for binding in global maps." :tags '(evil state) (let ((evil-normal-state-map (copy-keymap evil-normal-state-map)) (evil-normal-state-local-map (when (keymapp evil-normal-state-local-map) (copy-keymap evil-normal-state-local-map))) (global-map (copy-keymap global-map)) (orig-local-map (when (keymapp (current-local-map)) (copy-keymap (current-local-map)))) (map (or (current-local-map) (make-sparse-keymap)))) (use-local-map map) (ert-info ("Bind in a global state map") (evil-define-key 'normal 'global "f" 'foo) (should (eq (lookup-key evil-normal-state-map "f") 'foo))) (ert-info ("Bind in a local state map") (evil-define-key 'normal 'local "f" 'foo) (should (eq (lookup-key evil-normal-state-local-map "f") 'foo))) (ert-info ("Bind in the global map") (evil-define-key nil 'global "b" 'bar) (should (eq (lookup-key global-map "b") 'bar))) (ert-info ("Bind in the local map") (evil-define-key nil 'local "b" 'bar) (should (eq (lookup-key (current-local-map) "b") 'bar))) (use-local-map orig-local-map))) ;;; Type system (ert-deftest evil-test-exclusive-type () "Expand and contract the `line' type" :tags '(evil type) (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (let* ((first-line 1) (second-line (progn (forward-line) (point))) (third-line (progn (forward-line) (point)))) (ert-info ("Return the beginning and end unchanged \ if they are the same") (should (equal (evil-normalize 1 1 'exclusive) (list 1 1 'exclusive)))) (ert-info ("expand to `inclusive' if the end position \ is at the beginning of a line") (should (equal (evil-normalize (1+ first-line) second-line 'exclusive) (list (1+ first-line) (1- second-line) 'inclusive :expanded t)))) (ert-info ("expand to `line' if both the beginning and end \ are at the beginning of a line") (should (equal (evil-normalize first-line second-line 'exclusive) (list first-line second-line 'line :expanded t)))) (ert-info ("Measure as the strict difference between the end \ and the beginning") (should (string= (evil-describe 1 1 'exclusive) "0 characters")) (should (string= (evil-describe 1 2 'exclusive) "1 character")) (should (string= (evil-describe 5 2 'exclusive) "3 characters")))))) (ert-deftest evil-test-inclusive-type () "Expand and contract the `inclusive' type" :tags '(evil type) (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (ert-info ("Include the ending character") (should (equal (evil-expand 1 1 'inclusive) '(1 2 inclusive :expanded t)))) (ert-info ("Don't mind if positions are in wrong order") (should (equal (evil-expand 5 2 'inclusive) '(2 6 inclusive :expanded t)))) (ert-info ("Exclude the ending character when contracting") (should (equal (evil-contract 1 2 'inclusive) '(1 1 inclusive :expanded nil)))) (ert-info ("Don't mind positions' order when contracting") (should (equal (evil-contract 6 2 'inclusive) '(2 5 inclusive :expanded nil)))) (ert-info ("Measure as one more than the difference") (should (string= (evil-describe 1 1 'inclusive) "1 character")) (should (string= (evil-describe 5 2 'inclusive) "4 characters"))))) (ert-deftest evil-test-line-type () "Expand the `line' type" :tags '(evil type) (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (let* ((first-line 1) (second-line (progn (forward-line) (point))) (third-line (progn (forward-line) (point)))) (ert-info ("Expand to the whole first line") (should (equal (evil-expand first-line first-line 'line) (list first-line second-line 'line :expanded t))) (should (string= (evil-describe first-line first-line 'line) "1 line"))) (ert-info ("Expand to the two first lines") (should (equal (evil-expand first-line second-line 'line) (list first-line third-line 'line :expanded t))) (should (string= (evil-describe first-line second-line 'line) "2 lines")))))) (ert-deftest evil-test-block-type () "Expand and contract the `block' type" :tags '(evil type) (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (let* ((first-line 1) (second-line (progn (forward-line) (point))) (third-line (progn (forward-line) (point)))) (ert-info ("Expand to a 1x1 block") (should (equal (evil-expand 1 1 'block) (list 1 2 'block :expanded t))) (should (string= (evil-describe 1 1 'block) "1 row and 1 column"))) (ert-info ("Expand to a 2x1 block") (should (equal (evil-expand first-line second-line 'block) (list first-line (1+ second-line) 'block :expanded t))) (should (string= (evil-describe first-line second-line 'block) "2 rows and 1 column"))) (ert-info ("Expand to a 3x2 block") (should (equal (evil-expand first-line (1+ third-line) 'block) (list first-line (1+ (1+ third-line)) 'block :expanded t))) (should (string= (evil-describe first-line (1+ third-line) 'block) "3 rows and 2 columns"))) (ert-info ("Contract to a 0x0 rectangle") (should (equal (evil-contract 1 2 'block) (list 1 1 'block :expanded nil)))) (ert-info ("Contract to a 2x0 rectangle") (should (equal (evil-contract first-line (1+ second-line) 'block) (list first-line second-line 'block :expanded nil)))) (ert-info ("Contract to a 3x1 rectangle") (should (equal (evil-contract first-line (1+ (1+ third-line)) 'block) (list first-line (1+ third-line) 'block :expanded nil))))))) (ert-deftest evil-test-type-transform () "Test `evil-transform'" :tags '(evil type) (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (ert-info ("Return positions unchanged when passed nil \ for TYPE or TRANSFORM") (should (equal (evil-transform nil 1 2 'block) '(1 2 block))) (should (equal (evil-transform :expand 1 2 nil) '(1 2))) (should (equal (evil-transform nil 1 2 nil) '(1 2)))) (ert-info ("Accept markers, but return positions") (should (equal (evil-transform :expand (move-marker (make-marker) 1) 1 'inclusive) '(1 2 inclusive :expanded t))) (should (equal (evil-transform nil (move-marker (make-marker) 1) 2 nil) '(1 2)))))) (ert-deftest evil-test-type-modifiers () "Test type modifiers like \"dv}\"" :tags '(evil type) (ert-info ("Change `inclusive' motions to `exclusive'") (evil-test-buffer "[A]bove some line" ("dve") "[e] some line")) (ert-info ("Change `exclusive' motions to `inclusive'") (evil-test-buffer "Above [s]ome line Below some empty line" ("dv}") "Above[ ] Below some empty line")) (ert-info ("Change type to `line'") (evil-test-buffer "Above [s]ome line Below some empty line" ("dV}") "Below [s]ome empty line"))) ;;; Insertion (ert-deftest evil-test-insert () "Test `evil-insert'" :tags '(evil insert) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save" ("ievil rulz " [escape]) ";; evil rulz[ ]This buffer is for notes you don't want to save")) (ert-deftest evil-test-append () "Test `evil-append'" :tags '(evil insert) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save" ("aevil rulz " [escape]) ";; Tevil rulz[ ]his buffer is for notes you don't want to save")) (ert-deftest evil-test-visual-append () "Test `evil-append' from visual state" :tags '(evil insert) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save" ("veA_evil rulz " [escape]) ";; This_evil rulz[ ] buffer is for notes you don't want to save")) (ert-deftest evil-test-open-above () "Test `evil-open-above'" :tags '(evil insert) (evil-test-buffer ";; This buffer is for notes you don't want to save, \[;]; and for Lisp evaluation." ("Oabc\ndef" [escape]) ";; This buffer is for notes you don't want to save, abc de[f] ;; and for Lisp evaluation.") (ert-info ("Open empty line") (evil-test-buffer "(let (var)\n [t]est)\n" (emacs-lisp-mode) ("O" [escape]) "(let (var)\n[\n] test)\n")) (ert-info ("Open non-empty line") (evil-test-buffer "(let (var)\n [t]est)\n" (emacs-lisp-mode) ("Odo-it" [escape]) "(let (var)\n do-i[t]\n test)\n"))) (ert-deftest evil-test-open-below () "Test `evil-open-below'" :tags '(evil insert) (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("oabc\ndef" [escape]) ";; This buffer is for notes you don't want to save, abc de[f] ;; and for Lisp evaluation.") (ert-info ("Open empty line") (evil-test-buffer "[(]let (var)\n test)\n" (emacs-lisp-mode) ("o" [escape]) "(let (var)\n[\n] test)\n")) (ert-info ("Open non-empty line") (evil-test-buffer "[(]let (var)\n test)\n" (emacs-lisp-mode) ("odo-it" [escape]) "(let (var)\n do-i[t]\n test)\n")) (let ((evil-auto-indent t)) (ert-info ("With count") (evil-test-buffer "[(]and a\n c)\n" (emacs-lisp-mode) ("3ob" [escape]) "(and a\n b\n b\n [b]\n c)\n")))) (ert-deftest evil-test-open-below-folded () "Test `evil-open-below' on folded lines" :tags '(evil insert) (evil-test-buffer "[l]ine1\n\n(let ()\n var)\n\nlast line\n" (emacs-lisp-mode) (hs-minor-mode 1) ("zm2joABC" [escape]) "line1\n\n(let ()\n var)\nAB[C]\n\nlast line\n")) (ert-deftest evil-test-insert-line () "Test `evil-insert-line'" :tags '(evil insert) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save" ("Ievil rulz " [escape]) "evil rulz[ ];; This buffer is for notes you don't want to save")) (ert-deftest evil-test-append-line () "Test `evil-append-line'" :tags '(evil insert) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save" ("Aevil rulz " [escape]) ";; This buffer is for notes you don't want to saveevil rulz[ ]")) (ert-deftest evil-test-insert-digraph () "Test `evil-insert-digraph'" :tags '(evil insert) (ert-info ("Predefined digraph") (evil-test-buffer ("i\C-kae") "æ[]")) (ert-info ("Custom digraph") (let ((evil-digraphs-table-user '(((?a ?o) . ?å)))) (evil-test-buffer ("i\C-kao") "å[]"))) (ert-info ("Digraph in replace state") (evil-test-buffer "ab[c]defgh" ("R\C-kc,") "abç[d]efgh") (ert-info ("with count") (evil-test-buffer "abc[d]efgh" ("R\C-u3\C-kd*") "abcδδδ[g]h")))) ;;; Repeat system (ert-deftest evil-test-normalize-repeat-info () "Test `evil-normalize-repeat-info'" :tags '(evil repeat) (ert-info ("Single array") (should (equal (evil-normalize-repeat-info '("abc")) '([?a ?b ?c]))) (should (equal (evil-normalize-repeat-info '("\M-f")) (list (kbd "M-f"))))) (ert-info ("Single symbol") (should (equal (evil-normalize-repeat-info '(SYM)) '(SYM)))) (ert-info ("Arrays only") (should (equal (evil-normalize-repeat-info '("abc" [XX YY] "def")) '([?a ?b ?c XX YY ?d ?e ?f])))) (ert-info ("Several symbols") (should (equal (evil-normalize-repeat-info '(BEG MID END)) '(BEG MID END)))) (ert-info ("Arrays with symbol at the beginning") (should (equal (evil-normalize-repeat-info '(BEG "abc" [XX YY] "def")) '(BEG [?a ?b ?c XX YY ?d ?e ?f])))) (ert-info ("Arrays with symbol at the end") (should (equal (evil-normalize-repeat-info '("abc" [XX YY] "def" END)) '([?a ?b ?c XX YY ?d ?e ?f] END)))) (ert-info ("Arrays with symbol in the middle") (should (equal (evil-normalize-repeat-info '("abc" [XX YY] MID "def" )) '([?a ?b ?c XX YY] MID [?d ?e ?f])))) (ert-info ("Concatenate arrays with several symbols") (should (equal (evil-normalize-repeat-info '(BEG "abc" [XX YY] MID "def" END)) '(BEG [?a ?b ?c XX YY] MID [?d ?e ?f] END))))) (defun evil-test-repeat-info (keys &optional recorded) "Execute a sequence of keys and verify that `evil-repeat-ring' records them correctly. KEYS is the sequence of keys to execute. RECORDED is the expected sequence of recorded events. If nil, KEYS is used." (execute-kbd-macro keys) (should (equal (evil-normalize-repeat-info (ring-ref evil-repeat-ring 0)) (list (vconcat (or recorded keys)))))) (ert-deftest evil-test-normal-repeat-info-simple-command () "Save key-sequence after simple editing command in Normal state" :tags '(evil repeat) (evil-test-buffer "[T]his is a test buffer" (ert-info ("Call simple command without count") (evil-test-repeat-info "x")) (ert-info ("Call simple command with count 3") (evil-test-repeat-info "3x")))) (ert-deftest evil-test-normal-repeat-info-char-command () "Save key-sequence after editing command with character in Normal state" :tags '(evil repeat) (evil-test-buffer "[T]his is a test buffer" (ert-info ("Call command with character argument without count") (evil-test-repeat-info "r5")) (ert-info ("Call command with character argument with count 12") (evil-test-repeat-info "12rX")))) (ert-deftest evil-test-insert-repeat-info () "Save key-sequence after Insert state" :tags '(evil repeat) (evil-test-buffer (ert-info ("Insert text without count") (evil-test-repeat-info (vconcat "iABC" [escape]))) (ert-info ("Insert text with count 42") (evil-test-repeat-info (vconcat "42iABC" [escape]))))) (ert-deftest evil-test-repeat () "Repeat several editing commands" :tags '(evil repeat) (ert-info ("Repeat replace") (evil-test-buffer "[;]; This buffer is for notes you don't want to save" ("rX") "[X]; This buffer is for notes you don't want to save" ([right right] ".") "X;[X]This buffer is for notes you don't want to save")) (ert-info ("Repeat replace with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save" ("2rX") "X[X] This buffer is for notes you don't want to save" ([right right] ".") "XX X[X]is buffer is for notes you don't want to save")) (ert-info ("Repeat replace without count with a new count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save" ("rX") "[X]; This buffer is for notes you don't want to save" ([right right] "13.") "X;XXXXXXXXXXXX[X]is for notes you don't want to save")) (ert-info ("Repeat replace with count replacing original count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save" ("10rX") "XXXXXXXXX[X]ffer is for notes you don't want to save" ([right right] "20.") "XXXXXXXXXXfXXXXXXXXXXXXXXXXXXX[X] don't want to save")) (ert-info ("Repeat movement in Insert state") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save" ("i(\M-f)" [escape]) ";; (This[)] buffer is for notes you don't want to save" ("w.") ";; (This) (buffer[)] is for notes you don't want to save"))) (ert-deftest evil-test-repeat-register () "Test repeating a register command." :tags '(evil repeat) (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4\n" ("\"addyy\"aP") "[l]ine 1\nline 2\nline 3\nline 4\n" (".") "[l]ine 1\nline 1\nline 2\nline 3\nline 4\n")) (ert-deftest evil-test-repeat-numeric-register () "Test repeating a command with a numeric register." :tags '(evil repeat) (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4\nline 5\n" ("dd...") "[l]ine 5\n" ("\"1P") "[l]ine 4\nline 5\n" (".") "[l]ine 3\nline 4\nline 5\n" (".") "[l]ine 2\nline 3\nline 4\nline 5\n" (".") "[l]ine 1\nline 2\nline 3\nline 4\nline 5\n")) (ert-deftest evil-test-cmd-replace-char () "Calling `evil-replace-char' should replace characters" :tags '(evil repeat) (evil-test-buffer "[;]; This buffer is for notes you don't want to save" ("r5") "[5]; This buffer is for notes you don't want to save" ("3rX") "XX[X]This buffer is for notes you don't want to save") (ert-info ("Replace digraph") (evil-test-buffer "[;]; This buffer is for notes you don't want to save" ("r e'") "[é]; This buffer is for notes you don't want to save" ("3r c*") "ξξ[ξ]This buffer is for notes you don't want to save")) (ert-info ("Replacing \\n should insert only one newline") (evil-test-buffer "(setq var xxx [y]yy zzz)\n" (emacs-lisp-mode) (setq indent-tabs-mode nil) ("2r\n") "(setq var xxx \n [y] zzz)\n"))) (ert-deftest evil-test-insert-with-count () "Test `evil-insert' with repeat count" :tags '(evil repeat) (evil-test-buffer ";; [T]his buffer is for notes" ("2ievil rulz " [escape]) ";; evil rulz evil rulz[ ]This buffer is for notes")) (ert-deftest evil-test-repeat-insert () "Test repeating of `evil-insert'" :tags '(evil repeat) (ert-info ("Repeat insert") (evil-test-buffer "[;]; This buffer is for notes" ("iABC" [escape]) "AB[C];; This buffer is for notes" ("..") "ABABAB[C]CC;; This buffer is for notes")) (ert-info ("Repeat insert with count") (evil-test-buffer "[;]; This buffer is for notes" ("2iABC" [escape]) "ABCAB[C];; This buffer is for notes" ("..") "ABCABABCABABCAB[C]CC;; This buffer is for notes")) (ert-info ("Repeat insert with repeat count") (evil-test-buffer "[;]; This buffer is for notes" ("iABC" [escape]) "AB[C];; This buffer is for notes" ("11.") "ABABCABCABCABCABCABCABCABCABCABCAB[C]C;; This buffer is for notes")) (ert-info ("Repeat insert with count with repeat with count") (evil-test-buffer "[;]; This buffer is for notes" ("10iABC" [escape]) "ABCABCABCABCABCABCABCABCABCAB[C];; This buffer is for notes" ("11.") "ABCABCABCABCABCABCABCABCABCABABCABCABCABCABCABCABCABCABCABCAB[C]C;; \ This buffer is for notes"))) (ert-deftest evil-test-repeat-error () "Test whether repeat returns to normal state in case of an error." (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" ("ixxx" [down] [down] [left] [left] [left] "yyy" [escape]) "xxxline 1\nline 2\nyy[y]line 3\nline 4" (should-error (execute-kbd-macro "j^.")) (should (evil-normal-state-p)) ("^") "xxxline 1\nline 2\nyyyline 3\n[x]xxline 4")) (ert-deftest evil-test-quoted-insert () "Test evil-quoted-insert in replace state." (ert-info ("Simple replace C-v") (evil-test-buffer "ab[c]defg" ("R\C-vx") "abx[d]efg")) (ert-info ("Control char replace C-v") (evil-test-buffer "ab[c]defg" ("R\C-v\C-g") "ab[d]efg")) (ert-info ("C-v with count") (evil-test-buffer "ab[c]defg" ("R\C-u3\C-vx") "abxxx[f]g")) (ert-info ("C-v with count near eol") (evil-test-buffer "abcde[f]g" ("R\C-u3\C-vx") "abcdexxx[]")) (ert-info ("C-v in replace can be backspaced") (evil-test-buffer "ab[c]defg" ("R\C-u3\C-vx" [backspace]) "abxx[e]fg"))) (ert-deftest evil-test-repeat-quoted-insert () "Test whether `quoted-insert' can be repeated." (ert-info ("Insert C-v") (evil-test-buffer "lin[e] 1\nline 2\nline 3\n" ("i\C-v\C-v" [escape]) "lin[]e 1\nline 2\nline 3\n")) (ert-info ("Insert ESC") (evil-test-buffer "lin[e] 1\nline 2\nline 3\n" ("i\C-v" [escape escape]) "lin[]e 1\nline 2\nline 3\n")) (ert-info ("Block insert C-v") (evil-test-buffer "lin[e] 1\nline 2\nline 3\n" ("gg\C-vGI\C-v\C-v" [escape]) "[]line 1\nline 2\nline 3\n"))) (ert-deftest evil-test-insert-vcount () "Test `evil-insert' with vertical repeating" :tags '(evil repeat) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. ;; Below the empty line." (define-key evil-normal-state-local-map "i" #'(lambda (count) (interactive "p") (evil-insert count 5))) ("2iABC" [escape]) "\ ;; ABCAB[C]This buffer is for notes you don't want to save. ;; ABCABCIf you want to create a file, visit that file with C-x C-f, ;; ABCABCthen enter the text in that file's own buffer. ABCABC ;; ABCABCBelow the empty line.")) (ert-deftest evil-test-append-with-count () "Test `evil-append' with repeat count" :tags '(evil repeat) (evil-test-buffer ";; [T]his buffer is for notes" ("2aevil rulz " [escape]) ";; Tevil rulz evil rulz[ ]his buffer is for notes")) (ert-deftest evil-test-repeat-append () "Test repeating of `evil-append'" :tags '(evil repeat) (ert-info ("Repeat insert") (evil-test-buffer "[;]; This buffer is for notes" ("aABC" [escape]) ";AB[C]; This buffer is for notes" ("..") ";ABCABCAB[C]; This buffer is for notes")) (ert-info ("Repeat insert with count") (evil-test-buffer "[;]; This buffer is for notes" ("2aABC" [escape]) ";ABCAB[C]; This buffer is for notes" ("..") ";ABCABCABCABCABCAB[C]; This buffer is for notes")) (ert-info ("Repeat insert with repeat count") (evil-test-buffer "[;]; This buffer is for notes" ("aABC" [escape]) ";AB[C]; This buffer is for notes" ("11.") ";ABCABCABCABCABCABCABCABCABCABCABCAB[C]; This buffer is for notes")) (ert-info ("Repeat insert with count with repeat with count") (evil-test-buffer "[;]; This buffer is for notes" ("10aABC" [escape]) ";ABCABCABCABCABCABCABCABCABCAB[C]; This buffer is for notes" ("11.") ";ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB[C]; \ This buffer is for notes"))) (ert-deftest evil-test-append-vcount () "Test `evil-append' with vertical repeating" :tags '(evil repeat) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. ;; Below the empty line." (define-key evil-normal-state-local-map "a" #'(lambda (count) (interactive "p") (evil-append count 5))) ("2aABC" [escape]) "\ ;; TABCAB[C]his buffer is for notes you don't want to save. ;; IABCABCf you want to create a file, visit that file with C-x C-f, ;; tABCABChen enter the text in that file's own buffer. ABCABC ;; BABCABCelow the empty line.")) (ert-deftest evil-test-open-above-with-count () "Test `evil-open-above' with repeat count" :tags '(evil repeat) (evil-test-buffer ";; This buffer is for notes you don't want to save, \[;]; and for Lisp evaluation." ("2Oevil\nrulz" [escape]) ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation.")) (ert-deftest evil-test-repeat-open-above () "Test repeating of `evil-open-above'" :tags '(evil repeat) (ert-info ("Repeat insert") (evil-test-buffer "[;]; This buffer is for notes you don't want to save." ("Oevil\nrulz" [escape]) "evil\nrul[z] ;; This buffer is for notes you don't want to save." ("..") "evil\nevil\nevil\nrul[z]\nrulz\nrulz ;; This buffer is for notes you don't want to save.")) (ert-info ("Repeat insert with count") (evil-test-buffer ";; This buffer is for notes you don't want to save." ("2Oevil\nrulz" [escape]) "evil\nrulz\nevil\nrul[z] ;; This buffer is for notes you don't want to save." ("..") "evil\nrulz\nevil\nevil\nrulz\nevil\nevil\nrulz\nevil\nrul[z]\nrulz\nrulz ;; This buffer is for notes you don't want to save.")) (ert-info ("Repeat insert with repeat count") (evil-test-buffer ";; This buffer is for notes you don't want to save." ("Oevil\nrulz" [escape]) "evil\nrul[z]\n;; This buffer is for notes you don't want to save." ("2.") "evil\nevil\nrulz\nevil\nrul[z]\nrulz ;; This buffer is for notes you don't want to save.")) (ert-info ("Repeat insert with count with repeat with count") (evil-test-buffer ";; This buffer is for notes you don't want to save." ("2Oevil\nrulz" [escape]) "evil\nrulz\nevil\nrul[z] ;; This buffer is for notes you don't want to save." ("3.") "evil\nrulz\nevil\nevil\nrulz\nevil\nrulz\nevil\nrul[z]\nrulz ;; This buffer is for notes you don't want to save."))) (ert-deftest evil-test-open-below-with-count () "Test insertion of `evil-open-below' with repeat count" :tags '(evil repeat) (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2oevil\nrulz" [escape]) ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation.")) (ert-deftest evil-test-repeat-open-below () "Test repeating `evil-open-below'" :tags '(evil repeat) (ert-info ("Repeat insert") (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("oevil\nrulz" [escape]) ";; This buffer is for notes you don't want to save, evil\nrul[z]\n;; and for Lisp evaluation." ("..") ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation.")) (ert-info ("Repeat insert with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2oevil\nrulz" [escape]) ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation." ("..") ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation.")) (ert-info ("Repeat insert with repeat count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("oevil\nrulz" [escape]) ";; This buffer is for notes you don't want to save, evil\nrul[z]\n;; and for Lisp evaluation." ("2.") ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation.")) (ert-info ("Repeat insert with count with repeat with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2oevil\nrulz" [escape]) ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation." ("3.") ";; This buffer is for notes you don't want to save, evil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrul[z] ;; and for Lisp evaluation."))) (ert-deftest evil-test-insert-line-with-count () "Test `evil-insert-line' with repeat count" :tags '(evil repeat) (evil-test-buffer ";; [T]his buffer is for notes" ("2Ievil rulz " [escape]) "evil rulz evil rulz[ ];; This buffer is for notes")) (ert-deftest evil-test-repeat-insert-line () "Test repeating of `evil-insert-line'" :tags '(evil repeat) (ert-info ("Repeat insert") (evil-test-buffer ";; This buffer is for note[s]" ("IABC" [escape]) "AB[C];; This buffer is for notes" ("..") "AB[C]ABCABC;; This buffer is for notes")) (ert-info ("Repeat insert with count") (evil-test-buffer ";; This buffer is for note[s]" ("2IABC" [escape]) "ABCAB[C];; This buffer is for notes" ("..") "ABCAB[C]ABCABCABCABC;; This buffer is for notes")) (ert-info ("Repeat insert with repeat count") (evil-test-buffer ";; This buffer is for note[s]" ("IABC" [escape]) "AB[C];; This buffer is for notes" ("11.") "ABCABCABCABCABCABCABCABCABCABCAB[C]ABC;; This buffer is for notes")) (ert-info ("Repeat insert with count with repeat with count") (evil-test-buffer ";; This buffer is for note[s]" ("10IABC" [escape]) "ABCABCABCABCABCABCABCABCABCAB[C];; This buffer is for notes" ("11.") "ABCABCABCABCABCABCABCABCABCABCAB[C]ABCABCABCABCABCABCABCABCABCABC;; This buffer is for notes"))) (ert-deftest evil-test-insert-line-vcount () "Test `evil-insert-line' with vertical repeating" :tags '(evil repeat) (evil-test-buffer "int[ ]main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" (define-key evil-normal-state-local-map "I" #'(lambda (count) (interactive "p") (evil-insert-line count 4))) ("2IABC" [escape]) "ABCABCint main(int argc, char** argv) ABCABC{ ABCABCprintf(\"Hello world\\n\"); ABCABCreturn EXIT_SUCCESS; }")) (ert-deftest evil-test-append-line-with-count () "Test `evil-append-line' with repeat count" :tags '(evil repeat) (evil-test-buffer ";; [T]his buffer is for notes." ("2Aevil rulz " [escape]) ";; This buffer is for notes.evil rulz evil rulz[ ]")) (ert-deftest evil-test-repeat-append-line () "Test repeating of `evil-append-line'" :tags '(evil repeat) (ert-info ("Repeat insert") (evil-test-buffer ";; [T]his buffer is for notes." ("AABC" [escape]) ";; This buffer is for notes.AB[C]" ("..") ";; This buffer is for notes.ABCABCAB[C]")) (ert-info ("Repeat insert with count") (evil-test-buffer ";; [T]his buffer is for notes." ("2AABC" [escape]) ";; This buffer is for notes.ABCAB[C]" ("..") ";; This buffer is for notes.ABCABCABCABCABCAB[C]")) (ert-info ("Repeat insert with repeat count") (evil-test-buffer ";; [T]his buffer is for notes." ("AABC" [escape]) ";; This buffer is for notes.ABC" ("11.") ";; This buffer is for notes.ABCABCABCABCABCABCABCABCABCABCABCAB[C]")) (ert-info ("Repeat insert with count with repeat with count") (evil-test-buffer ";; [T]his buffer is for notes." ("10AABC" [escape]) ";; This buffer is for notes.ABCABCABCABCABCABCABCABCABCAB[C]" ("11.") ";; This buffer is for notes.ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB[C]"))) (ert-deftest evil-test-append-line-vcount () "Test `evil-append-line' with vertical repeating" :tags '(evil repeat) (evil-test-buffer "int[ ]main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" (define-key evil-normal-state-local-map "A" #'(lambda (count) (interactive "p") (evil-append-line count 4))) ("2AABC" [escape]) "int main(int argc, char** argv)ABCAB[C] {ABCABC printf(\"Hello world\\n\");ABCABC return EXIT_SUCCESS;ABCABC }")) (ert-deftest evil-test-repeat-by-change () "Test repeating by tracking changes for completion commands" :tags '(evil repeat) (let ((line-move-visual nil) (change (evil-define-command nil () :repeat change (interactive) (delete-char 5) (insert "BEGIN\n") (save-excursion (insert "\nEND\n"))))) (evil-test-buffer ";; [T]his buffer is for notes." (define-key evil-insert-state-local-map (kbd "C-c C-p") change) ("iABC " (kbd "C-c C-p") "BODY" [escape]) ";; ABC BEGIN BOD[Y] END buffer is for notes." (".") ";; ABC BEGIN BODABC BEGIN BOD[Y] END buffer is for notes."))) (ert-deftest evil-test-repeat-kill-buffer () "Test safe-guard preventing buffers from being deleted when repeating a command" :tags '(evil repeat) (ert-info ("Test killing works for direct calls \ to `evil-execute-repeat-info'") (evil-test-buffer "[;]; This buffer is for notes." (setq evil-repeat-ring (make-ring 10)) (ring-insert evil-repeat-ring '((kill-buffer nil))) (evil-execute-repeat-info (ring-ref evil-repeat-ring 0)) (should-not (looking-at ";; This")))) (ert-info ("Verify an error is raised when using \ the `evil-repeat' command") (evil-test-buffer "[;]; This buffer is for notes." (setq evil-repeat-ring (make-ring 10)) (ring-insert evil-repeat-ring '((kill-buffer nil))) (evil-execute-repeat-info (ring-ref evil-repeat-ring 0)) (should-error (call-interactively #'evil-repeat))))) (ert-deftest evil-test-repeat-pop () "Test `repeat-pop'." :tags '(evil repeat) (ert-info ("Test repeat-pop") (evil-test-buffer ";; [T]his buffer is for notes." (setq evil-repeat-ring (make-ring 10)) ("iABC" [escape] "aXYZ" [escape]) ";; ABCXY[Z]This buffer is for notes." (".") ";; ABCXYZXY[Z]This buffer is for notes.")) (ert-info ("Test repeat-pop") (evil-test-buffer ";; [T]his buffer is for notes." (setq evil-repeat-ring (make-ring 10)) ("iABC" [escape] "aXYZ" [escape]) ";; ABCXY[Z]This buffer is for notes." ("." (kbd "C-.")) ";; ABCXYAB[C]ZThis buffer is for notes.")) (ert-info ("Test repeat-pop-next") (evil-test-buffer ";; [T]his buffer is for notes." (setq evil-repeat-ring (make-ring 10)) ("iABC" [escape] "aXYZ" [escape]) ";; ABCXY[Z]This buffer is for notes." ("." (kbd "C-.") (kbd "M-.")) ";; ABCXYZXY[Z]This buffer is for notes.")) (ert-info ("Test repeat-pop after non-change") (evil-test-buffer ";; [T]his buffer is for notes." (setq evil-repeat-ring (make-ring 10)) ("iABC" [escape] "a" [escape] "aXYZ" [escape]) ";; ABCXY[Z]This buffer is for notes." ("." (kbd "C-.") (kbd "C-.")) ";; ABCXYAB[C]ZThis buffer is for notes."))) (ert-deftest evil-test-ESC-repeat-normal-state () "Test if ESC is not been recorded in normal state." :tags '(evil repeat) (ert-info ("Test normal ESC") (evil-test-buffer ";;[ ]This buffer is for notes." (setq evil-repeat-ring (make-ring 10)) (should (= (ring-length evil-repeat-ring) 0)) ("aABC" [escape]) ";; AB[C]This buffer is for notes." (should (= (ring-length evil-repeat-ring) 1)) (".") ";; ABCAB[C]This buffer is for notes." ([escape]) (should (= (ring-length evil-repeat-ring) 1)) (".") ";; ABCABCAB[C]This buffer is for notes."))) (ert-deftest evil-test-abort-operator-repeat () "Test if ESC in operator-state cancels recording of repeation." :tags '(evil repeat) (let ((inhibit-quit t)) (ert-info ("Test ESC") (evil-test-buffer ";;[ ]This buffer is for notes." (setq evil-repeat-ring (make-ring 10)) (should (= (ring-length evil-repeat-ring) 0)) ("aABC" [escape]) ";; AB[C]This buffer is for notes." (should (= (ring-length evil-repeat-ring) 1)) (".") ";; ABCAB[C]This buffer is for notes." ("d" [escape]) (should (= (ring-length evil-repeat-ring) 1)) (".") ";; ABCABCAB[C]This buffer is for notes.")))) (ert-deftest evil-test-repeat-with-find-char () "Ensure that repeating find-char commands doesn't change `evil-last-find'" :tags '(evil repeat) (evil-test-buffer "[b]ar baz bat" ("dfa" "fb") "r [b]az bat" (".") "r [z] bat" (";") "r z [b]at")) (ert-deftest evil-test-repeat-visual-char () "Test repeat of character visual mode command." :tags '(evil repeat) (ert-info ("Test repeat on same line") (evil-test-buffer ";; [T]his buffer is for notes." ("v3lcABC" [escape]) ";; AB[C] buffer is for notes." ("ww.") ";; ABC buffer AB[C]or notes.")) (ert-info ("Test repeat on several lines") (evil-test-buffer ";; This [b]uffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. " ("vj^eerX") ";; This XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX[X] you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. " ("2gg^3w.") ";; This XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXX you want XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX[X]en enter the text in that file's own buffer. "))) (ert-deftest evil-test-repeat-visual-line () "Test repeat of linewise visual mode command." :tags '(evil repeat) (ert-info ("Test repeat on several lines") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter th[e] text in that file's own buffer. ;; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. " ("VkcNew Text" [escape]) ";; This buffer is for notes you don't want to save. New Tex[t] ;; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. " ("jj.") ";; This buffer is for notes you don't want to save. New Text New Tex[t] ;; then enter the text in that file's own buffer. "))) (ert-deftest evil-test-repeat-visual-block () "Test repeat of block visual mode command." :tags '(evil repeat) (ert-info ("Test repeat on several lines") (evil-test-buffer ";; This [b]uffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. ;; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. " ((kbd "C-v") "3j2lrQ") ";; This [Q]QQfer is for notes you don't want to save. ;; If yoQQQant to create a file, visit that file with C-x C-f, ;; then QQQer the text in that file's own buffer. ;; This QQQfer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. " ("2j3w.") ";; This QQQfer is for notes you don't want to save. ;; If yoQQQant to create a file, visit that file with C-x C-f, ;; then QQQer the text [Q]QQthat file's own buffer. ;; This QQQfer is for nQQQs you don't want to save. ;; If you want to creatQQQ file, visit that file with C-x C-f, ;; then enter the text QQQthat file's own buffer. "))) (ert-deftest evil-visual-block-append () "Test appending in visual block." :tags '(evil visual insert) (ert-info ("Simple append") (evil-test-buffer "l[i]ne 1\nline 2\nline 3\n" ((kbd "C-v") "jjllAXXX" [escape]) "lineXX[X] 1\nlineXXX 2\nlineXXX 3\n")) (ert-info ("Append after empty lines") (evil-test-buffer "line 1l[i]ne 1\nline 2\nline 3line 3\n" (setq indent-tabs-mode nil) ((kbd "C-v") "jjllAXXX" [escape]) "line 1lineXX[X] 1\nline 2 XXX\nline 3lineXXX 3\n")) (ert-info ("Append after empty first line") (evil-test-buffer "l[i]ne 1line 1\nline 2\nline 3line 3line 3\n" (setq indent-tabs-mode nil) ((kbd "C-v") "jj3feAXXX" [escape]) "line 1line 1 XX[X]\nline 2 XXX\nline 3line 3lineXXX 3\n")) (ert-info ("Append after end of lines") (evil-test-buffer "line 1l[i]ne 1line 1\nline 2\nline 3line 3\n" (setq indent-tabs-mode nil) ((kbd "C-v") "jj$AXXX" [escape]) "line 1line 1line 1XX[X]\nline 2XXX\nline 3line 3XXX\n"))) (ert-deftest evil-test-repeat-digraph () "Test repeat of insertion of a digraph." :tags '(evil digraph repeat) (evil-test-buffer "Line with ['] several apostrophes ', yeah." ("s" (kbd "C-k") "'9" [escape]) "Line with [’] several apostrophes ', yeah." ("f'.") "Line with ’ several apostrophes [’], yeah.")) ;;; Operators (ert-deftest evil-test-keypress-parser () "Test `evil-keypress-parser'" :tags '(evil operator) (evil-test-buffer :state operator (ert-info ("Read from the keyboard unless INPUT is given") (evil-test-buffer :state operator (let ((unread-command-events '(?d))) (should (equal (evil-keypress-parser) '(evil-delete nil))) (should (equal (evil-keypress-parser '(?d)) '(evil-delete nil)))))) (ert-info ("Read remainder from the keyboard if INPUT is incomplete") (let ((unread-command-events '(?d))) (should (equal (evil-keypress-parser '(?2)) '(evil-delete 2))))) (ert-info ("Handle counts not starting with zero") (should (equal (evil-keypress-parser '(?2 ?d)) '(evil-delete 2))) (should (equal (evil-keypress-parser '(?2 ?0 ?d)) '(evil-delete 20))) (should (equal (evil-keypress-parser '(?2 ?0 ?2 ?d)) '(evil-delete 202))) (should (equal (evil-keypress-parser '(?4 ?0 ?4 ?g ??)) '(evil-rot13 404)))) (ert-info ("Treat 0 as a motion") (should (equal (evil-keypress-parser '(?0)) '(evil-beginning-of-line nil)))) (ert-info ("Handle keyboard macros") (evil-test-buffer (define-key evil-motion-state-local-map (kbd "W") (kbd "w")) (should (equal (evil-keypress-parser '(?W)) '(evil-forward-word-begin nil))))))) (ert-deftest evil-test-invert-char () "Test `evil-invert-char'" :tags '(evil operator) (evil-test-buffer ";; [T]his buffer is for notes." ("~") ";; t[h]is buffer is for notes.") (evil-test-buffer ";; <[T]his> buffer is for notes." ("~") ";; [t]HIS buffer is for notes.") (evil-test-buffer :visual block ";; <[T]his buffer is for notes, ;; and >for Lisp evaluation." ("~") ";; [t]HIS buffer is for notes, ;; AND for Lisp evaluation.")) (ert-deftest evil-test-rot13 () "Test `evil-rot13'" :tags '(evil operator) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("g?" [M-right]) ";; [G]uvf buffer is for notes you don't want to save.")) (ert-deftest evil-test-rot13-with-count () "Test `evil-rot13' with count argument" :tags '(evil operator) (ert-info ("Count before operator") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("2g?" [M-right]) ";; [G]uvf ohssre is for notes you don't want to save.")) (ert-info ("Count before motion") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("g?2" [M-right]) ";; [G]uvf ohssre is for notes you don't want to save.")) (ert-info ("Count before operator and motion") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("3g?2" [M-right]) ";; [G]uvf ohssre vf sbe abgrf lbh don't want to save.")) (ert-info ("Count exceeding buffer boundaries") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("g?200" [right]) ";; [G]uvf ohssre vf sbe abgrf lbh qba'g jnag gb fnir."))) (ert-deftest evil-test-rot13-repeat () "Test repeating of `evil-rot13'" :tags '(evil operator) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("g?" [M-right] [M-right]) ";; Guvf[ ]buffer is for notes you don't want to save." (".") ";; Guvf[ ]ohssre is for notes you don't want to save.")) (ert-deftest evil-test-rot13-repeat-with-count () "Test repeating of `evil-rot13' with new count" :tags '(evil operator) (ert-info ("Count before operator") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("2g?" [M-right]) ";; [G]uvf ohssre is for notes you don't want to save." ("3.") ";; [T]his buffer vf for notes you don't want to save.")) (ert-info ("Count before motion") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("g?2" [M-right]) ";; [G]uvf ohssre is for notes you don't want to save." ("3.") ";; [T]his buffer vf for notes you don't want to save.")) (ert-info ("Count before operator and motion") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("3g?2" [M-right]) ";; [G]uvf ohssre vf sbe abgrf lbh don't want to save." ("4.") ";; [T]his buffer is for abgrf lbh don't want to save."))) (ert-deftest evil-test-operator-delete () "Test deleting text" :tags '(evil operator) (ert-info ("Delete characters") (evil-test-buffer ";; [T]his buffer is for notes." ("dl") ";; [h]is buffer is for notes." ("d1l") ";; [i]s buffer is for notes." ("1dl") ";; [s] buffer is for notes." ("1d1l") ";; [ ]buffer is for notes." ("d2l") ";; [u]ffer is for notes." ("2dl") ";; [f]er is for notes." ("d4l") ";; [i]s for notes." ("4dl") ";; [o]r notes." ("2d2l") ";; [o]tes.")) (ert-info ("Delete current line") (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("dd") ";; [a]nd for Lisp evaluation.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("d1d") ";; [a]nd for Lisp evaluation.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("1dd") ";; [a]nd for Lisp evaluation.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("1d1d") ";; [a]nd for Lisp evaluation.")) (ert-info ("With `evil-start-of-line' `t'") (let ((evil-start-of-line t)) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("dd") "[;]; and for Lisp evaluation.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("d1d") "[;]; and for Lisp evaluation.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("1dd") "[;]; and for Lisp evaluation.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("1d1d") "[;]; and for Lisp evaluation.")))) (ert-info ("Delete two lines") (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("d2d") ";; [t]hen enter the text in that file's own buffer.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2dd") ";; [t]hen enter the text in that file's own buffer.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("dj") ";; [t]hen enter the text in that file's own buffer.") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("dk") ";; [t]hen enter the text in that file's own buffer.")) (ert-info ("With `evil-start-of-line' `t'") (let ((evil-start-of-line t)) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("d2d") "[;]; then enter the text in that file's own buffer.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2dd") "[;]; then enter the text in that file's own buffer.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("dj") "[;]; then enter the text in that file's own buffer.") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("dk") "[;]; then enter the text in that file's own buffer."))))) (evil-define-motion evil-test-square-motion (count) "Test motion for selecting a square." :type block (let ((column (current-column))) (forward-line (1- count)) (move-to-column (+ column count -1)))) (ert-deftest evil-test-yank () "Test `evil-yank'" :tags '(evil operator yank) (ert-info ("Yank characters") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("y2e") (should (string= (current-kill 0) "This buffer")))) (ert-info ("Yank lines") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("yj") (should (string= (current-kill 0) (buffer-substring (point-min) (1+ (line-end-position 2))))) (should (eq (car-safe (get-text-property 0 'yank-handler (current-kill 0))) 'evil-yank-line-handler))) (evil-test-buffer ";; This buffer is for notes you don't want to save. \[;]; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("y5j") (should (string= (current-kill 0) (concat (buffer-substring (line-beginning-position 1) (point-max)) "\n"))) (should (eq (car-safe (get-text-property 0 'yank-handler (current-kill 0))) 'evil-yank-line-handler)))) (ert-info ("Yank rectangle") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y3s") (should (string= (current-kill 0) "Thi\nIf \nthe")) (should (eq (car-safe (get-text-property 0 'yank-handler (current-kill 0))) 'evil-yank-block-handler)))) (ert-info (":yank, then paste") (evil-test-buffer "a\n[b]\nc\nd\n" (":yank" [return] "p") "a\nb\nb\nc\nd\n")) (ert-info (":yank with COUNT") (evil-test-buffer "a\n[b]\nc\nd\n" (":yank 2" [return] "p") "a\nb\nb\nc\nc\nd\n")) (ert-info (":yank with COUNT in visual state") (evil-test-buffer "a\n\nd\ne\nf\n" (":yank 3" [return] "p") "a\nb\nc\nd\ne\nc\nd\ne\nf\n")) (ert-info (":yank with REGISTER") (evil-test-buffer "a\n[b]\nc\nd\n" (":yank r") ;; yank into the 'r' register "a\nb\nc\nd\n" ;; check the 'r' register contains the yanked text (should (string= (substring-no-properties (evil-get-register ?r)) "b\n")))) (ert-info (":yank with REGISTER and COUNT") (evil-test-buffer "a\n[b]\nc\nd\ne\nf\n" (":yank r 3") "a\nb\nc\nd\ne\nf\n" (should (string= (substring-no-properties (evil-get-register ?r)) "b\nc\nd\n")))) (ert-info (":yank with range yanks without moving point") (evil-test-buffer "[a]\nb\nc\nd\ne\n" (":4y" [return] "p") "a\n[d]\nb\nc\nd\ne\n") (evil-test-buffer "[a]\nb\nc\nd\ne\n" (":+4y" [return] "p") "a\n[e]\nb\nc\nd\ne\n"))) (ert-deftest evil-test-delete () "Test `evil-delete'" :tags '(evil operator delete) (ert-info ("Delete characters") (evil-test-buffer ";; This buffer is for notes you don't want to save[.]" ("x") ";; This buffer is for notes you don't want to sav[e]" (goto-char 4) ";; [T]his buffer is for notes you don't want to save" ("d2e") ";; [ ]is for notes you don't want to save" (should (string= (current-kill 0) "This buffer")) ("P") ";; This buffe[r] is for notes you don't want to save")) (ert-info ("Delete lines") (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2dd") ";; [t]hen enter the text in that file's own buffer." ("P") "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("With `evil-start-of-line' `t'") (let ((evil-start-of-line t)) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2dd") "[;]; then enter the text in that file's own buffer." ("P") "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")))) (ert-info ("Delete last line") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2dd") ";; [T]his buffer is for notes you don't want to save.")) (ert-info ("Delete last empty line") (evil-test-buffer "line 1\nline 2\n\n[]" ("dd") "line 1\nline 2\n[]")) (ert-info ("Delete rectangle") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("d3s") "[T]his buffer is for notes you don't want to save. If you want to create a file, visit that file with C-x C-f, then enter the text in that file's own buffer.")) (ert-info (":delete") (evil-test-buffer "a\n[b]\nc\nd\n" (":delete") "a\nc\nd\n")) (ert-info (":delete with COUNT") (evil-test-buffer "a\n[b]\nc\nd\n" (":delete 2") "a\nd\n")) (ert-info (":delete with COUNT in visual state") (evil-test-buffer "a\n\nd\ne\nf\n" (":delete 3") "a\nb\nf\n")) (ert-info (":delete with REGISTER") (evil-test-buffer "a\n[b]\nc\nd\n" (":delete r") ;; delete into the 'r' register "a\nc\nd\n" ;; check the 'r' register contains the deleted text (should (string= (substring-no-properties (evil-get-register ?r)) "b\n")))) (ert-info (":delete with REGISTER and COUNT") (evil-test-buffer "a\n[b]\nc\nd\ne\nf\n" (":delete r 3") "a\ne\nf\n" (should (string= (substring-no-properties (evil-get-register ?r)) "b\nc\nd\n")))) (ert-info ("Charwise multiple whole line delete becomes linewise") (evil-test-buffer "1\n[2]\n3\n4" ("d2w") "1\n[4]"))) (ert-deftest evil-test-delete-line () "Test `evil-delete-line'" :tags '(evil operator) (ert-info ("Delete to end of line") (evil-test-buffer ";; This buffer is for notes[ ]you don't want to save." ("D") ";; This buffer is for note[s]")) (ert-info ("Act linewise on character selection") (evil-test-buffer ";; This is for notes, and for Lisp evaluation." ("D") "[a]nd for Lisp evaluation.")) (ert-info ("Act on each line of block selection") (evil-test-buffer :visual block ";; This buffer is for ." ("D") ";; This buffer is for[ ] ;; and for Lisp evalua")) (ert-info ("Yank full block with block selection") (evil-test-buffer :visual block "line1 le3 line3\n" ("D") "line1 [l]\nline2 l\nline3 l\n" ("0P") "ine1 line1 line1line1 l ine2 line2 l ine3 line3 line3 l\n"))) (ert-deftest evil-test-delete-folded () "Test `evil-delete' on folded lines." :tags '(evil operator) (ert-info ("Delete folded lines") (evil-test-buffer "[l]ine1\n\n(let ()\n var)\n\n(let ()\n var2)\n" (emacs-lisp-mode) (hs-minor-mode 1) ("zm2jdd") "line1\n\n[\n](let ()\n var2)\n")) (ert-info ("Delete folded lines with count") (evil-test-buffer "[l]ine1\n\n(let ()\n var)\n\n(let ()\n var2)\n\nlast line\n" (emacs-lisp-mode) (hs-minor-mode 1) ("zm2j3dd") "line1\n\n[\n]last line\n"))) (ert-deftest evil-test-delete-backward-word () "Test `evil-delete-backward-word' in insert & replace states." :tags '(evil) (ert-info ("evil-delete-backward-word in insert state") (let ((evil-backspace-join-lines t)) (evil-test-buffer "abc def\n ghi j[k]l\n" ("i" (kbd "C-w")) "abc def\n ghi [k]l\n" ((kbd "C-w")) "abc def\n [k]l\n" ((kbd "C-w")) "abc def\n[k]l\n" ((kbd "C-w")) "abc def[k]l\n")) (let (evil-backspace-join-lines) (evil-test-buffer "abc def\n[k]l\n" (should-error (execute-kbd-macro (concat "i" (kbd "C-w")))) "abc def\n[k]l\n"))) (ert-info ("evil-delete-backward-word in replace state") (evil-test-buffer "alpha bravo [c]harlie delta" ("R" "one two") "alpha bravo one two[ ]delta" ("\C-w") "alpha bravo one [l]ie delta" ("\C-w") "alpha bravo [c]harlie delta" ("\C-w") "alpha [b]ravo charlie delta"))) (ert-deftest evil-test-delete-back-to-indentation () "Test `evil-delete-back-to-indentation' in insert & replace states." :tags '(evil) (let ((evil-backspace-join-lines t)) (evil-test-buffer "abc def\n ghi j[k]l\n" ("i" (call-interactively #'evil-delete-back-to-indentation)) "abc def\n [k]l\n" (left-char 2) "abc def\n [ ] kl\n" (call-interactively #'evil-delete-back-to-indentation) "abc def\n[ ] kl\n" (call-interactively #'evil-delete-back-to-indentation) "abc def[ ] kl\n")) (let (evil-backspace-join-lines) (evil-test-buffer "abc def\n[k]l\n" (should-error (progn (execute-kbd-macro "i") (call-interactively #'evil-delete-back-to-indentation))) "abc def\n[k]l\n")) (ert-info ("Delete back to indentation in replace state") (evil-test-buffer " alpha [b]ravo charlie" ("R" "delta") " alpha delta[ ]charlie" (evil-delete-back-to-indentation) " [a]lpha bravo charlie"))) (ert-deftest evil-test-change () "Test `evil-change'" :tags '(evil operator) (ert-info ("Change characters") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("c2eABC" [escape]) ";; AB[C] is for notes you don't want to save." (should (string= (current-kill 0) "This buffer")) ("p") ";; ABCThis buffe[r] is for notes you don't want to save.")) (ert-info ("Change lines") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2ccABCLINE\nDEFLINE" [escape]) "ABCLINE DEFLIN[E] ;; then enter the text in that file's own buffer." ("p") "ABCLINE DEFLINE \[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Change last line") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2ccABC" [escape]) ";; This buffer is for notes you don't want to save. AB[C]")) (ert-info ("C changes whole line in visual characterwise and linewise states") (evil-test-buffer "Two lines [s]hould suffice for this test." ("veC" "all gone!") "all gone![] for this test.") (evil-test-buffer "Two lines [w]ill be fine for this test too." ("VjC" "all gone!") "all gone![]")) (ert-info ("C clears the visual blockwise selection, and all text to the right") (evil-test-buffer "Two [l]ines will be fine for the tests here as well." ("\C-vjeC") "Two [] the ")) (ert-info ("S clears the whole line in normal mode, and all lines touched by visual selection") (evil-test-buffer "Two lines [s]hould suffice for this test." ("S" "all gone!") "all gone![] for this test.") (evil-test-buffer "Two lines [s]hould suffice for this test." ("vS" "all gone!") "all gone![] for this test.") (evil-test-buffer "Two lines [s]hould suffice for this test." ("VjS" "all gone!") "all gone![]") (evil-test-buffer "Two lines [s]hould suffice for this test." ("\C-VjS" "all gone!") "all gone![]")) (ert-info ("R behaves the same as S in visual modes") (evil-test-buffer "Two lines [s]hould suffice for this test." ("vR" "all gone!") "all gone![] for this test.")) (ert-info ("Change rectangle") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("c3sABC" [escape]) "AB[C]This buffer is for notes you don't want to save. ABCIf you want to create a file, visit that file with C-x C-f, ABCthen enter the text in that file's own buffer."))) (ert-deftest evil-maybe-remove-spaces-test () "Test maybe removing (indentation) spaces after some commands when making a clear line." :tags '(evil operator) (ert-info ("changing the line and returning to normal mode removes spaces") (evil-test-buffer (emacs-lisp-mode) ("i(one two" [return] "three" [return] "four" [return] "five" [escape] "?three" [return]) "(one two [t]hree four five" ("cc" "new line" [escape] "+") "(one two new line [f]our five" ("cc" [escape]) "(one two new line [] five"))) (ert-deftest evil-test-change-word () "Test changing words" :tags '(evil operator) (ert-info ("Non-word") (evil-test-buffer "[;]; This buffer is for notes." ("cwABC" [escape]) "AB[C] This buffer is for notes.")) (ert-info ("Word") (evil-test-buffer ";; [T]his buffer is for notes." ("cwABC" [escape]) ";; AB[C] buffer is for notes.")) (ert-info ("Single character") (evil-test-buffer "[;] This buffer is for notes." ("cwABC" [escape]) "AB[C] This buffer is for notes.")) (ert-info ("Whitespace") (evil-test-buffer "This[ ]is a test\n" ("cwABC" [escape]) "ThisAB[C]is a test\n"))) (ert-deftest evil-test-join () "Test `evil-join'" :tags '(evil join operator) (ert-info ("Simple") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f." ("J") ";; This buffer is for notes you don't want to save.[ ]\ ;; If you want to create a file, visit that file with C-x C-f.")) (ert-info ("Visual") (evil-test-buffer :visual line "<;; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f.>" ("J") ";; This buffer is for notes you don't want to save.[ ]\ ;; If you want to create a file, visit that file with C-x C-f.")) (ert-info ("Join with count") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":join 3") "line 1 line 2 line 3\nline 4")) (ert-info ("Join with bang and count") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":join! 3") "line 1line 2line 3\nline 4")) (ert-info ("Join with bang and count, exceeding end-of-buffer") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":join! 10") "line 1line 2line 3line 4")) (ert-info ("Join with count 1 should be the same as without count") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":join 1") "line 1 line 2\nline 3\nline 4")) (ert-info ("Join with count 2 should be the same as with count 1") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":join 2") "line 1 line 2\nline 3\nline 4")) (ert-info ("Join with count and single line range") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":2join 3") "line 1\nline 2 line 3 line 4")) (ert-info ("Join with count and range") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":1,2join 3") "line 1\nline 2 line 3 line 4")) (ert-info ("Join with count, range and bang") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":1,2join! 3") "line 1\nline 2line 3line 4")) (ert-info ("Join with range") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (":1,3join") "line 1 line 2 line 3\nline 4")) ) (ert-deftest evil-test-substitute () "Test `evil-substitute'" :tags '(evil operator) (ert-info ("Simple") (evil-test-buffer ";; [T]his buffer is for notes." ("5sABC" [escape]) ";; AB[C]buffer is for notes.")) (ert-info ("On empty line") (evil-test-buffer "Above some line \[] Below some empty line" ("5sABC" [escape]) "Above some line AB[C] Below some empty line"))) (ert-deftest evil-test-shift () "Test `evil-shift-right' and `evil-shift-left'." :tags '(evil operator) (let ((evil-shift-width 4) indent-tabs-mode) (ert-info ("Shift linewise") (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer "[l]ine 1\nline 2\nline 3\n" ("Vj>") "[ ] line 1\n line 2\nline 3\n")) (ert-info ("With `evil-start-of-line' `t'") (let ((evil-start-of-line t)) (evil-test-buffer "[l]ine 1\nline 2\nline 3\n" ("Vj>") " [l]ine 1\n line 2\nline 3\n")))) (ert-info ("Shift char selection on whole line") (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer "[l]ine 1\nline 2\nline 3\n" ("v$>") " line [1]\nline 2\nline 3\n")) (ert-info ("With `evil-start-of-line' `t'") (let ((evil-start-of-line t)) (evil-test-buffer "[l]ine 1\nline 2\nline 3\n" ("v$>") " [l]ine 1\nline 2\nline 3\n")))) (ert-info ("Shift visual with count") (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer "[l]ine 1\nline 2\nline 3\n" ("Vj3>") "[ ] line 1\n line 2\nline 3\n" ("Vj2<") "[ ] line 1\n line 2\nline 3\n")) (ert-info ("With `evil-start-of-line' `t'") (let ((evil-start-of-line t)) (evil-test-buffer "[l]ine 1\nline 2\nline 3\n" ("Vj3>") " [l]ine 1\n line 2\nline 3\n" ("Vj2<") " [l]ine 1\n line 2\nline 3\n")))) (ert-info ("Shift in insert state") (evil-test-buffer "line 1\nl[i]ne 2\nline 3\n" ("i\C-t\C-t") "line 1\n l[i]ne 2\nline 3\n" ("\C-d") "line 1\n l[i]ne 2\nline 3\n")) (ert-info ("Delete all indentation in insert state") (evil-test-buffer "line1\n sometext[ ]" ("a" "somemore" "0\C-d") "line1\nsometext somemore[]")))) ;;; Paste (ert-deftest evil-test-paste-before () "Test `evil-paste-before'" :tags '(evil paste) (ert-info ("Paste characters") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("y2ej0") ";; This buffer is for notes you don't want to save, \[;]; and for Lisp evaluation." ("P") ";; This buffer is for notes you don't want to save, This buffe[r];; and for Lisp evaluation.")) (ert-info ("Paste characters with count") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("y2ej0") ";; This buffer is for notes you don't want to save, \[;]; and for Lisp evaluation." ("3P") ";; This buffer is for notes you don't want to save, This bufferThis bufferThis buffe[r];; and for Lisp evaluation.")) (ert-info ("Paste characters at end-of-buffer") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("y2eG$") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation[.]" ("2P") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluationThis bufferThis buffe[r].")) (ert-info ("Paste lines") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2yyP") "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; This buffer is for notes you don't want to save, ;; and for Lisp evaluation.")) (ert-info ("Paste lines with count") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2yy2P") "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; This buffer is for notes you don't want to save, ;; and for Lisp evaluation.")) (ert-info ("Paste lines at end-of-buffer") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2yyG$") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation[.]" ("2P") ";; This buffer is for notes you don't want to save, \[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; and for Lisp evaluation.")) (ert-info ("Paste block") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ysP") "[;]; ;; This buffer is for notes you don't want to save. ;; ;; If you want to create a file, visit that file with C-x C-f, ;; ;; then enter the text in that file's own buffer.")) (ert-info ("Paste block with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ys2P") "[;]; ;; ;; This buffer is for notes you don't want to save. ;; ;; ;; If you want to create a file, visit that file with C-x C-f, ;; ;; ;; then enter the text in that file's own buffer.")) (ert-info ("Paste block with empty line") (evil-test-buffer "[;]; Above some line ;; Below some empty line" (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ys2P") "[;]; ;; ;; Above some line \n\ ;; ;; ;; Below some empty line")) (ert-info ("Paste block crossing end of buffer") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ysj") ";; This buffer is for notes you don't want to save. \[;]; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("P") ";; This buffer is for notes you don't want to save. \[;]; ;; If you want to create a file, visit that file with C-x C-f, ;; ;; then enter the text in that file's own buffer. ;;")) (ert-info ("Paste block at end-of-line") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ys$") ";; This buffer is for notes you don't want to save[.] ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("p") ";; This buffer is for notes you don't want to save.[;]; ;; If you want to create a file, visit that file wi;; th C-x C-f, ;; then enter the text in that file's own buffer. ;;"))) (ert-deftest evil-test-paste-after () "Test `evil-paste-after'" :tags '(evil paste) (ert-info ("Paste characters") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("y2ej0") ";; This buffer is for notes you don't want to save, \[;]; and for Lisp evaluation." ("p") ";; This buffer is for notes you don't want to save, ;This buffe[r]; and for Lisp evaluation.")) (ert-info ("Paste characters with count") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("y2ej0") ";; This buffer is for notes you don't want to save, \[;]; and for Lisp evaluation." ("3p") ";; This buffer is for notes you don't want to save, ;This bufferThis bufferThis buffe[r]; and for Lisp evaluation.")) (ert-info ("Paste characters at end-of-buffer") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("y2eG$") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation[.]" ("2p") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation.This bufferThis buffe[r]")) (ert-info ("Paste lines") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2yyp") ";; This buffer is for notes you don't want to save, \[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; and for Lisp evaluation.")) (ert-info ("Paste lines with count") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2yy2p") ";; This buffer is for notes you don't want to save, \[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; and for Lisp evaluation.")) (ert-info ("Paste lines at end-of-buffer") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("2yyG$") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation[.]" ("2p") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. \[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; This buffer is for notes you don't want to save, ;; and for Lisp evaluation.")) (ert-info ("Paste block") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ysp") ";[;]; ; This buffer is for notes you don't want to save. ;;; ; If you want to create a file, visit that file with C-x C-f, ;;; ; then enter the text in that file's own buffer.")) (ert-info ("Paste block with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ys2p") ";[;]; ;; ; This buffer is for notes you don't want to save. ;;; ;; ; If you want to create a file, visit that file with C-x C-f, ;;; ;; ; then enter the text in that file's own buffer.")) (ert-info ("Paste block with empty line") (evil-test-buffer "[;]; Above some line ;; Below some empty line" (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ys2p") ";;; ;; ; Above some line ;;; ;; ; Below some empty line")) (ert-info ("Paste block crossing end of buffer") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ysj") ";; This buffer is for notes you don't want to save. \[;]; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("p") ";; This buffer is for notes you don't want to save. ;;; ; If you want to create a file, visit that file with C-x C-f, ;;; ; then enter the text in that file's own buffer. ;;")) (ert-info ("Paste block at end-of-line") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("3ys$") ";; This buffer is for notes you don't want to save[.] ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("p") ";; This buffer is for notes you don't want to save.;; ;; If you want to create a file, visit that file wi;; th C-x C-f, ;; then enter the text in that file's own buffer. ;;")) (ert-info ("Paste preserves preceding text properties") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (put-text-property (point) (line-end-position) 'font-lock-face 'warning) ("yyp") ";; This buffer is for notes you don't want to save. [;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (should (equal (get-text-property (point-min) 'font-lock-face) 'warning))))) (ert-deftest evil-test-paste-pop-before () "Test `evil-paste-pop' after `evil-paste-before'" :tags '(evil paste) (ert-info ("Paste") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sj") ";; This buffer is for notes you don't want to save. \[;]; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("P") ";; This buffer is for notes you don't want to save. \[;]; ;; If you want to create a file, visit that file with C-x C-f, ;; ;; then enter the text in that file's own buffer. ;;")) (ert-info ("Single pop") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjP\C-p") ";; This buffer is for notes you don't want to save. \[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Two pops") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjP\C-p\C-p") ";; This buffer is for notes you don't want to save. ;; Thi[s];; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Pop with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjP2\C-p") ";; This buffer is for notes you don't want to save. ;; Thi[s];; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Single pop-next") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjP2\C-p\C-n") ";; This buffer is for notes you don't want to save. \[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Pop-next with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjP\C-p\C-p2\C-n") ";; This buffer is for notes you don't want to save. \[;]; ;; If you want to create a file, visit that file with C-x C-f, ;; ;; then enter the text in that file's own buffer. ;;"))) (ert-deftest evil-test-paste-pop-after () "Test `evil-paste-pop' after `evil-paste-after'" :tags '(evil paste) (ert-info ("Paste") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sj") ";; This buffer is for notes you don't want to save. \[;]; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("p") ";; This buffer is for notes you don't want to save. ;[;]; ; If you want to create a file, visit that file with C-x C-f, ;;; ; then enter the text in that file's own buffer. ;;")) (ert-info ("Single pop") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjp\C-p") ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, \[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Two pops") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjp\C-p\C-p") ";; This buffer is for notes you don't want to save. ;;; Thi[s]; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Pop with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjp2\C-p") ";; This buffer is for notes you don't want to save. ;;; Thi[s]; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Single pop-next") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjp2\C-p\C-n") ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, \[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Pop-next with count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjp\C-p\C-p2\C-n") ";; This buffer is for notes you don't want to save. ;[;]; ; If you want to create a file, visit that file with C-x C-f, ;;; ; then enter the text in that file's own buffer. ;;"))) (ert-deftest evil-test-paste-pop-without-undo () "Test `evil-paste-pop' with undo disabled" :tags '(evil paste) (ert-info ("Pop-next with count without undo") (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (setq buffer-undo-list t) (define-key evil-operator-state-local-map "s" 'evil-test-square-motion) ("y2e2yyy3sjP\C-p\C-p2\C-n") ";; This buffer is for notes you don't want to save. \[;]; ;; If you want to create a file, visit that file with C-x C-f, ;; ;; then enter the text in that file's own buffer. ;;"))) (ert-deftest evil-test-visual-paste () "Test `evil-paste-before' and `evil-paste-after' in Visual state" :tags '(evil paste) (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f." ("yyk") ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f." ("VP") "[;]; If you want to create a file, visit that file with C-x C-f. ;; If you want to create a file, visit that file with C-x C-f.") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f." ("yyj") ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f." ("Vp") ";; This buffer is for notes you don't want to save. \[;]; This buffer is for notes you don't want to save.") (ert-info ("Visual-paste from register 3") ;; This behaviour deviates from vim, which populates registers 1-9 with ;; deleted text only, not yanked text. This is an aspect of `evil-yank's ;; use of the emacs kill-ring, so is consistent with non-visual paste. (evil-test-buffer "[w]ord1a word1b word1c word1d word2a word2b word2c word2d" ("yiwwyiwwyiw") "word1a word1b [w]ord1c word1d word2a word2b word2c word2d" ("+viw\"3p") "word1a word1b word1c word1d word1[a] word2b word2c word2d")) (ert-info ("Visual-paste respects `evil-kill-on-visual-paste'") (evil-test-buffer "[w]ord1 word2 word3" (setq evil-kill-on-visual-paste nil) ("yewyew") "word1 word2 [w]ord3" ("ve\"2p") "word1 word2 word[1]" ("o\C-r\"") "word1 word2 word1 word2[]") (evil-test-buffer "[w]ord1 word2 word3" (setq evil-kill-on-visual-paste t) ("yewyew") "word1 word2 [w]ord3" ("ve\"2p") "word1 word2 word[1]" ("o\C-r\"") "word1 word2 word1 word3[]")) (ert-info ("Visual-paste from `=' register") (evil-test-buffer "foo" ("viw" "\"=p(* 6 7)" [return]) "4[2]")) (ert-info ("Blockwise visual paste (of charwise text) with count") (evil-test-buffer "[a]bc\n123\n123\n123" ("ye" "jl" "\C-vG" "2p") "abc\n1[a]bcabc3\n1abcabc3\n1abcabc3" ("gv") ;; Test point & mark are stored correctly "abc\n13")) (ert-info ("Blockwise visual paste of linewise text") (evil-test-buffer "[a]bc\n123\n123\n123" ("yy" "jl" "\C-vG" "p") "abc\n1\nabc\n3\n1\nabc\n3\n1\nabc\n3"))) (ert-deftest evil-test-visual-paste-pop () "Test `evil-paste-pop' after visual paste." :tags '(evil paste) (ert-info ("Visual-char paste, char paste") (evil-test-buffer "[w]ord1a word1b word1c\nword2a word2b\nword3a word3b word3c word3d\n" ("yiwyywyiw^jw") "word1a word1b word1c\nword2a [w]ord2b\nword3a word3b word3c word3d\n" ("viwp") "word1a word1b word1c\nword2a word1[b]\nword3a word3b word3c word3d\n")) (ert-info ("Visual-char paste, char paste, line pop") (evil-test-buffer "[w]ord1a word1b word1c\nword2a word2b\nword3a word3b word3c word3d\n" ("yiwyywyiw^jw") "word1a word1b word1c\nword2a [w]ord2b\nword3a word3b word3c word3d\n" ("viwp\C-p") "word1a word1b word1c\nword2a \n[w]ord1a word1b word1c\n\nword3a word3b word3c word3d\n")) (ert-info ("Visual-char paste, char paste, line pop, char pop") (evil-test-buffer "[w]ord1a word1b word1c\nword2a word2b\nword3a word3b word3c word3d\n" ("yiwyywyiw^jw") "word1a word1b word1c\nword2a [w]ord2b\nword3a word3b word3c word3d\n" ("viwp\C-p\C-p") "word1a word1b word1c\nword2a word1[a]\nword3a word3b word3c word3d\n")) (ert-info ("Visual-line paste, char paste") (evil-test-buffer "[w]ord1a word1b word1c\nword2a word2b\nword3a word3b word3c word3d\n" ("yiwyywyiw^j") "word1a word1b word1c\n[w]ord2a word2b\nword3a word3b word3c word3d\n" ("Vp") "word1a word1b word1c\nword1[b]word3a word3b word3c word3d\n")) (ert-info ("Visual-line paste, char paste, line pop") (evil-test-buffer "[w]ord1a word1b word1c\nword2a word2b\nword3a word3b word3c word3d\n" ("yiwyywyiw^j") "word1a word1b word1c\n[w]ord2a word2b\nword3a word3b word3c word3d\n" ("Vp\C-p") "word1a word1b word1c\n[w]ord1a word1b word1c\nword3a word3b word3c word3d\n")) (ert-info ("Visual-line paste, char paste, line pop, char pop") (evil-test-buffer "[w]ord1a word1b word1c\nword2a word2b\nword3a word3b word3c word3d\n" ("yiwyywyiw^j") "word1a word1b word1c\n[w]ord2a word2b\nword3a word3b word3c word3d\n" ("Vp\C-p\C-p") "word1a word1b word1c\nword1[a]word3a word3b word3c word3d\n"))) (ert-deftest evil-test-register () "Test yanking and pasting to and from register." :tags '(evil yank paste) (ert-info ("simple lower case register") (evil-test-buffer "[f]oo\n" ("\"ayw\"aP") "fo[o]foo\n" ("\"ayy\"aP") "[f]oofoo\nfoofoo\n")) (ert-info ("upper case register") (evil-test-buffer "[f]oo\n" ("\"ayw\"Ayw\"aP") "foofo[o]foo\n" ("\"ayy\"Ayy\"aP") "[f]oofoofoo\nfoofoofoo\nfoofoofoo\n")) (ert-info ("upper case register and lines") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4\n" ("\"a2Yjj\"A2Y\"aP") "line 1\nline 2\n[l]ine 1\nline 2\nline 3\nline 4\nline 3\nline 4\n" ("8G\"ap") "line 1\nline 2\nline 1\nline 2\nline 3\nline 4\nline 3\nline 4\n[l]ine 1\nline 2\nline 3\nline 4\n")) (ert-info ("yank with count") (evil-test-buffer "[l]ine 1\nline 2\nline 3\n" ("\"a2yw\"aP") "line [1]line 1\nline 2\nline 3\n" ("\"a2yy\"aP") "[l]ine 1line 1\nline 2\nline 1line 1\nline 2\nline 3\n")) (dolist (module '(evil-search isearch)) (evil-select-search-module 'evil-search-module module) (ert-info ((format "special register / (module: %s)" module)) (evil-test-buffer "[f]oo bar\n" ("/bar" [return] "0i\C-r/") "bar[f]oo bar\n"))) (ert-info ("special register :") (evil-test-buffer "[f]oo bar\n" (":noh\ni\C-r:"))) (ert-info ("Paste from register during change to register") (evil-test-buffer "[a]lpha beta" ("\"ayiw" "w" "\"bciw" "\C-ra") "alpha alpha[]")) (ert-info ("Paste from register in replace state") (evil-test-buffer "[a]lpha bravo charlie" ("yiw" "w" "R" "\C-r0") "alpha alpha[ ]charlie" ([backspace] [backspace] [backspace]) "alpha al[a]vo charlie"))) (ert-deftest evil-test-last-insert-register () "Test last insertion register." (evil-test-buffer "[l]ine 1\n" ("GiABC" [escape]) "line 1\nAB[C]" ("go\".P") "AB[C]line 1\nABC")) (ert-deftest evil-test-zero-register () "\"0 contains the last text that was yanked without specificying a register." (evil-test-buffer "[l]ine 1\nline 2\n" ("yy\"0p") "line 1\n[l]ine 1\nline 2\n" ("j\"ayy\"0p") "line 1\nline 1\nline 2\n[l]ine 1\n" ; yanked line 2 to "a, so "0 is still line 1 ("kdd\"0p") "line 1\nline 1\nline 1\n[l]ine 1\n")) (ert-deftest evil-test-=-register () "\"= is not really a register . It inserts the result of evaluating some elisp" (ert-info ("Can eval elisp, and can fetch default (last) result") (evil-test-buffer :state insert "8x8= []" ("\C-r=(* 8 8)" [return]) "8x8= 64" ([return] "16x4= \C-r=" [return]) "8x8= 64 16x4= 64")) (ert-info ("Can eval infix math, and can use register at prompt") (evil-test-buffer "[5]0/10 * 100 = " ("\"nyt=" "A\C-r=" "\C-rn" [return]) "50/10 * 100 = 500"))) (ert-deftest evil-test-ex-put () "evil-ex-put inserts text linewise, regardless of yank-handler" (ert-info ("Can put linewise text from default register, by line number") (evil-test-buffer "[L]orem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt" ("yy:2put" [return]) "Lorem ipsum dolor sit amet consectetur adipiscing elit [L]orem ipsum dolor sit amet sed do eiusmod tempor incididunt")) (ert-info ("Can put blockwise text from letter register, backwards") (evil-test-buffer "Lorem ipsum [d]olor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt" ("\C-vje\"xy" "bye" "Vj" ":put! x" [return]) "Lorem ipsum dolor sit amet dolor sit [a]dipiscing consectetur adipiscing elit sed do eiusmod tempor incididunt")) (ert-info ("Can supply args and put from = register") (evil-test-buffer "[L]ine one." (":put = (* 6 7)" [return]) "Line one. [4]2"))) (ert-deftest evil-test-align () "Test `evil-align-left', `evil-align-right' and `evil-align-center'." :tags '(evil operator) (evil-without-display (let ((fill-column 70) indent-tabs-mode) (evil-test-buffer "before\n[l]ine 1\nthis is line number 2\nline number 3\nafter\n" (":.,+2ri" [return] (kbd "M-x") "untabify" [return]) "before\n [l]ine 1\n this is line number 2\n line number 3\nafter\n" (":.,+2ri 60" [return] (kbd "M-x") "untabify" [return]) "before\n [l]ine 1\n this is line number 2\n line number 3\nafter\n" (":.,+2le" [return] (kbd "M-x") "untabify" [return]) "before\n[l]ine 1\nthis is line number 2\nline number 3\nafter\n" (":.,+2le 10" [return]) "before\n [l]ine 1\n this is line number 2\n line number 3\nafter\n" (":.,+2ce" [return] (kbd "M-x") "untabify" [return]) "before\n [l]ine 1\n this is line number 2\n line number 3\nafter\n" (":.,+2ce 40" [return] (kbd "M-x") "untabify" [return]) "before\n [l]ine 1\n this is line number 2\n line number 3\nafter\n")))) ;;; Motions (ert-deftest evil-test-forward-char () "Test `evil-forward-char' motion" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "[;]; This buffer is for notes." ("l") ";[;] This buffer is for notes.")) (ert-info ("End of line") (let ((evil-cross-lines t) (evil-move-beyond-eol nil)) (evil-test-buffer ";; This buffer is for notes[,] ;; and for Lisp evaluation." ("l") ";; This buffer is for notes, \[;]; and for Lisp evaluation."))) (ert-info ("With count") (evil-test-buffer "[;]; This buffer is for notes." ("12l") ";; This buff[e]r is for notes.")) (ert-info ("End of line") (evil-test-buffer ";; This buffer is for notes[.]" (should-error (execute-kbd-macro "l")) (should-error (execute-kbd-macro "10l")))) (ert-info ("Until end-of-line") (evil-test-buffer "[;]; This buffer is for notes." ("100l") ";; This buffer is for notes[.]")) (ert-info ("On empty line") (evil-test-buffer "Above some line \[] Below some empty line" (should-error (execute-kbd-macro "l")) (should-error (execute-kbd-macro "42l"))))) (ert-deftest evil-test-backward-char () "Test `evil-backward-char' motion" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; This[ ]buffer is for notes." ("h") ";; Thi[s] buffer is for notes.")) (ert-info ("With count") (evil-test-buffer ";; This[ ]buffer is for notes." ("3h") ";; T[h]is buffer is for notes.")) (ert-info ("Beginning of line") (evil-test-buffer "[;]; This buffer is for notes." (should-error (execute-kbd-macro "h")) (should-error (execute-kbd-macro "10h")))) (ert-info ("Until beginning-of-line") (evil-test-buffer ";; This[ ]buffer is for notes." ("100h") "[;]; This buffer is for notes.")) (ert-info ("On empty line") (evil-test-buffer "Above some line \[] Below some empty line" (should-error (execute-kbd-macro "h")) (should-error (execute-kbd-macro "42h"))))) (ert-deftest evil-test-previous-line () "Test `evil-previous-line' motion" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; This buffer is for notes you don't want to save, ;; [a]nd for Lisp evaluation." ("k") ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation.")) (ert-info ("With count") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; [t]hen enter the text in that file's own buffer." ("2k") ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("Until beginning of buffer") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; [t]hen enter the text in that file's own buffer." ("100k") ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) (ert-info ("At beginning of buffer") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." (should-error (execute-kbd-macro "k")) (should-error (execute-kbd-macro "42k"))))) (ert-deftest evil-test-next-line () "Test `evil-next-line' motion" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("j") ";; This buffer is for notes you don't want to save, ;; [a]nd for Lisp evaluation.")) (ert-info ("With count") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2j") ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; [t]hen enter the text in that file's own buffer.")) (ert-info ("Until end of buffer") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("100j") ";; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; [t]hen enter the text in that file's own buffer.")) (ert-info ("At end of buffer") (evil-test-buffer ";; This buffer is for notes you don't want to [s]ave." (should-error (execute-kbd-macro "j")) (should-error (execute-kbd-macro "42j"))))) (ert-deftest evil-test-next+previous-preserve-column () "Test `evil-previous-line' and `evil-next-line' preserve the column." :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "ab[c]\nabcdef\n\nabcd\n" ("j") "abc\nab[c]def\n\nabcd\n") (evil-test-buffer "ab[c]\nabcdef\n\nabcd\n" ("jj") "abc\nabcdef\n[\n]abcd\n") (evil-test-buffer "ab[c]\nabcdef\n\nabcd\n" ("jjj") "abc\nabcdef\n\nab[c]d\n") (evil-test-buffer "ab[c]\nabcdef\n\nabcd\n" ("jjjk") "abc\nabcdef\n[\n]abcd\n") (evil-test-buffer "ab[c]\nabcdef\n\nabcd\n" ("jjjkk") "abc\nab[c]def\n\nabcd\n"))) (ert-deftest evil-test-other-commands-preserve-column () "Test other comamnds preserve the column, when appropriate." :tags '(evil motion) (ert-info ("evil-goto-line can preserve column") (let ((evil-start-of-line nil)) (evil-test-buffer "Shor[t] line Average line The longest line" ("2G") "Short line Aver[a]ge line The longest line" ("$G") "Short line Average line The longest lin[e]" ("hgg") "Short lin[e] Average line The longest line"))) (ert-info ("evil-goto-line respects evil-start-of-line") (let ((evil-start-of-line t)) (evil-test-buffer "foo\n[b]ar" ("$ggj") "foo\n[b]ar"))) (ert-info ("N% (`evil-jump-item' with count) can preserve column") (let ((evil-start-of-line nil)) (evil-test-buffer "Short line Average line The lo[n]gest line" ("5%") "Short [l]ine Average line The longest line" ("$90%") "Short line Average line The longest lin[e]")))) (ert-deftest evil-test-beginning-of-line () "Test `evil-beginning-of-line' motion" :tags '(evil motion) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("0") "[;]; This buffer is for notes you don't want to save." ("0") "[;]; This buffer is for notes you don't want to save.")) (ert-deftest evil-test-end-of-line () "Test `evil-end-of-line' motion" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; [T]his buffer is for notes you don't want to save." ("$") ";; This buffer is for notes you don't want to save[.]" ("$") ";; This buffer is for notes you don't want to save[.]")) (ert-info ("Don't delete blank lines") (evil-test-buffer "Above some line \[] Below some empty line" ("d$") "Above some line \[] Below some empty line"))) (ert-deftest evil-test-percentage-of-line () "Test `evil-percentage-of-line' motion" :tags '(evil motion) (evil-test-buffer "[0]123456789" ("gM") "01234[5]6789" ("10gM") "0[1]23456789" ("85gM") "01234567[8]9")) (ert-deftest evil-test-first-non-blank () "Test `evil-first-non-blank' motion" :tags '(evil motion) (evil-test-buffer "\ printf(\"Hello world\\n\")[;] return EXIT_SUCCESS;" ("^") "\ [p]rintf(\"Hello world\\n\"); return EXIT_SUCCESS;" ("j^") "\ printf(\"Hello world\\n\"); [r]eturn EXIT_SUCCESS;")) (ert-deftest evil-test-last-non-blank () "Test `evil-last-non-blank' motion" :tags '(evil motion) (evil-test-buffer "[i]nt main(int argc, char** argv) \n\ { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("g_") "int main(int argc, char** argv[)] \n\ { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("jjg_") "int main(int argc, char** argv) \n\ { printf(\"Hello world\\n\")[;] return EXIT_SUCCESS; }")) (ert-deftest evil-test-goto-first-line () "Test `evil-goto-first-line' motion" :tags '(evil motion) (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("3gg") "int main(int argc, char** argv) { [ ] printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("gg") "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("100gg") "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]")) (ert-info ("With `evil-start-of-line' `nil'") (let ((evil-start-of-line t)) (evil-test-buffer "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("3gg") "int main(int argc, char** argv) { [p]rintf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("gg") "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("100gg") "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]")))) (ert-deftest evil-test-goto-line () "Test `evil-goto-line' motion" :tags '(evil motion) (ert-info ("With `evil-start-of-line' `t'") (let ((evil-start-of-line t)) (evil-test-buffer "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("G") "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]" ("3G") "int main(int argc, char** argv) { [p]rintf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("100G") "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]"))) (ert-info ("With `evil-start-of-line' `nil'") (evil-test-buffer "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("G") "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]" ("3G") "int main(int argc, char** argv) { [ ] printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("100G") "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]"))) (ert-deftest evil-test-goto-char () "Test `evil-goto-char' motion and ex command." :tags '(evil motion ex) (evil-test-buffer "[W]e only need a short buffer for this test" (":goto 9") "We only [n]eed a short buffer for this test" (":goto") "[W]e only need a short buffer for this test" ("16go") "We only need a [s]hort buffer for this test" ("go") "[W]e only need a short buffer for this test" (evil-goto-char 24) "We only need a short bu[f]fer for this test")) (ert-deftest evil-test-operator-0 () "Test motion \"0\" with an operator." :tags '(evil motion) (evil-test-buffer ";; [T]his buffer is for notes." ("d0") "[T]his buffer is for notes.")) (ert-deftest evil-test-forward-not-word () "Test `evil-forward-not-thing'" :tags '(evil motion) (evil-test-buffer "[ ] aa,," (evil-forward-not-thing 'evil-word) " [a]a,,")) ;; TODO: test Visual motions and window motions (ert-deftest evil-test-forward-word-begin () "Test `evil-forward-word-begin'" :tags '(evil motion) (ert-info ("Non-word") (evil-test-buffer "[;]; This buffer is for notes." ("w") ";; [T]his buffer is for notes.")) (ert-info ("Simple") (evil-test-buffer ";; [T]his buffer is for notes." ("w") ";; This [b]uffer is for notes.")) (ert-info ("With count") (evil-test-buffer ";; [T]his buffer is for notes." ("3w") ";; This buffer is [f]or notes.")) (ert-info ("With count on whitespace") (evil-test-buffer ";;[ ]This buffer is for notes." ("3w") ";; This buffer [i]s for notes.")) (ert-info ("Empty line") (evil-test-buffer "Above some line \[] Below some empty line" ("w") "Above some line \[B]elow some empty line") (evil-test-buffer "[A]bove Below some empty line" ("dw") "[] Below some empty line" ("dw") "[] Below some empty line" ("dw") "[B]elow some empty line") (evil-test-buffer "[A]bove Below some empty line with leading whitespace" ("dw") "[] Below some empty line with leading whitespace" ("dw") "[] Below some empty line with leading whitespace" ("dw") " [B]elow some empty line") (evil-test-buffer "Some line with trailing whitespace [ ] \n next line\n" ("dw") "Some line with trailing whitespace [ ]\n next line\n") (evil-test-buffer "[A]\n" ("dw") "[]\n")) (ert-info ("End of buffer") (evil-test-buffer ";; [T]his buffer is for notes." ("100w") ";; This buffer is for notes[.]" (should-error (execute-kbd-macro "w")) (should-error (execute-kbd-macro "10w")))) (ert-info ("Before last character in buffer") (evil-test-buffer "fo[o]." ("w") "foo[.]") (evil-test-buffer "fo[o] " ("w") "foo[ ]") (evil-test-buffer "[ ]e" ("w") " [e]"))) (ert-deftest evil-test-forward-word-end () "Test `evil-forward-word-end'" :tags '(evil motion) (ert-info ("Non-word") (evil-test-buffer "[;]; This buffer is for notes." ("e") ";[;] This buffer is for notes.")) (ert-info ("Simple") (evil-test-buffer ";; [T]his buffer is for notes." ("e") ";; Thi[s] buffer is for notes.")) (ert-info ("With count") (evil-test-buffer ";; [T]his buffer is for notes." ("3e") ";; This buffer i[s] for notes.")) (ert-info ("With count on whitespace") (evil-test-buffer ";;[ ]This buffer is for notes." ("3e") ";; This buffer i[s] for notes.")) (ert-info ("Delete") (evil-test-buffer ";; This[-]buffer-is-for-notes." ("de") ";; This[-]is-for-notes.")) (ert-info ("Empty line") (evil-test-buffer "Above some line \[] Below some empty line" ("e") "Above some line Belo[w] some empty line")) (ert-info ("End of buffer") (evil-test-buffer ";; [T]his buffer is for notes." ("100e") ";; This buffer is for notes[.]" (should-error (execute-kbd-macro "e")) (should-error (execute-kbd-macro "10e")))) ;; In Vim, "de" may delete two words rather than one ;; if the first word is only one letter. In Evil, ;; "de" always deletes one word. (ert-info ("Delete a single-letter word") (evil-test-buffer "a [b] c" ("de") "a [ ]c"))) (ert-deftest evil-test-backward-word-begin () "Test `evil-backward-word-begin'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; This buffer is for notes[.]" ("b") ";; This buffer is for [n]otes.")) (ert-info ("With count") (evil-test-buffer ";; This buffer is for notes[.]" ("2b") ";; This buffer is [f]or notes.")) (ert-info ("Empty line") (evil-test-buffer "Above some line \[] Below some empty line" ("b") "Above some [l]ine Below some empty line")) (ert-info ("With count on whitespace") (evil-test-buffer ";; This buffer is for[ ]notes." ("2b") ";; This buffer [i]s for notes.")) (ert-info ("Beginning of buffer") (evil-test-buffer ";; This buffer is for notes[.]" ("100b") "[;]; This buffer is for notes." (should-error (execute-kbd-macro "b")) (should-error (execute-kbd-macro "10b"))))) (ert-deftest evil-test-backward-word-end () "Test `evil-backward-word-end'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; This buffer is for notes[.]" ("ge") ";; This buffer is for note[s].")) (ert-info ("With count") (evil-test-buffer ";; This buffer is for notes[.]" ("2ge") ";; This buffer is fo[r] notes.")) (ert-info ("Empty line") (evil-test-buffer "Above some line \[] Below some empty line" ("ge") "Above some lin[e] Below some empty line")) (ert-info ("With count on whitespace") (evil-test-buffer ";; This buffer is for[ ]notes." ("2ge") ";; This buffer i[s] for notes.")) (ert-info ("Beginning of buffer") (evil-test-buffer ";; This buffer is for notes[.]" ("100ge") "[;]; This buffer is for notes." (should-error (execute-kbd-macro "ge")) (should-error (execute-kbd-macro "10ge"))))) (ert-deftest evil-test-forward-word-begin-cjk () "Test `evil-forward-word-begin' on CJK words" :tags '(evil motion cjk) (ert-info ("Latin / numeric") (evil-test-buffer "[a]bcd1234" ("w") "abcd123[4]")) (ert-info ("Latin / Kanji") (evil-test-buffer "[a]bcd漢字" ("w") "abcd[漢]字")) (ert-info ("Latin / Hiragana") (evil-test-buffer "[a]bcdひらがな" ("w") "abcd[ひ]らがな")) (ert-info ("Latin / Katakana") (evil-test-buffer "[a]bcdカタカナ" ("w") "abcd[カ]タカナ")) (ert-info ("Latin / half-width Katakana") (evil-test-buffer "[a]bcdカタカナ" ("w") "abcdカタカ[ナ]")) (ert-info ("Latin / full-width alphabet") (evil-test-buffer "[a]bcdABC" ("w") "abcdAB[C]")) (ert-info ("Latin / full-width numeric") (evil-test-buffer "[a]bcd123" ("w") "abcd12[3]")) (ert-info ("Latin / Hangul") (evil-test-buffer "[a]bcd한글" ("w") "abcd[한]글")) (ert-info ("numeric / Latin") (evil-test-buffer "[1]234abcd" ("w") "1234abc[d]")) (ert-info ("numeric / Kanji") (evil-test-buffer "[1]234漢字" ("w") "1234[漢]字")) (ert-info ("numeric / Hiragana") (evil-test-buffer "[1]234ひらがな" ("w") "1234[ひ]らがな")) (ert-info ("numeric / Katakana") (evil-test-buffer "[1]234カタカナ" ("w") "1234[カ]タカナ")) (ert-info ("numeric / half-width Katakana") (evil-test-buffer "[1]234カタカナ" ("w") "1234カタカ[ナ]")) (ert-info ("numeric / full-width alphabet") (evil-test-buffer "[1]234ABC" ("w") "1234AB[C]")) (ert-info ("numeric / full-width numeric") (evil-test-buffer "[1]234123" ("w") "123412[3]")) (ert-info ("numeric / Hangul") (evil-test-buffer "[1]234한글" ("w") "1234[한]글")) (ert-info ("Kanji / Latin") (evil-test-buffer "[漢]字abcd" ("w") "漢字[a]bcd")) (ert-info ("Kanji / numeric") (evil-test-buffer "[漢]字1234" ("w") "漢字[1]234")) (ert-info ("Kanji / Hiragana") (evil-test-buffer "[漢]字ひらがな" ("w") "漢字[ひ]らがな")) (ert-info ("Kanji / Katakana") (evil-test-buffer "[漢]字カタカナ" ("w") "漢字[カ]タカナ")) (ert-info ("Kanji / half-width Katakana") (evil-test-buffer "[漢]字カタカナ" ("w") "漢字[カ]タカナ")) (ert-info ("Kanji / full-width alphabet") (evil-test-buffer "[漢]字ABC" ("w") "漢字[A]BC")) (ert-info ("Kanji / full-width numeric") (evil-test-buffer "[漢]字123" ("w") "漢字[1]23")) (ert-info ("Kanji / Hangul") (evil-test-buffer "[漢]字한글" ("w") "漢字[한]글")) (ert-info ("Hiragana / Latin") (evil-test-buffer "[ひ]らがなabcd" ("w") "ひらがな[a]bcd")) (ert-info ("Hiragana / numeric") (evil-test-buffer "[ひ]らがな1234" ("w") "ひらがな[1]234")) (ert-info ("Hiragana / Kanji") (evil-test-buffer "[ひ]らがな漢字" ("w") "ひらがな[漢]字")) (ert-info ("Hiragana / Katakana") (evil-test-buffer "[ひ]らがなカタカナ" ("w") "ひらがな[カ]タカナ")) (ert-info ("Hiragana / half-width Katakana") (evil-test-buffer "[ひ]らがなカタカナ" ("w") "ひらがな[カ]タカナ")) (ert-info ("Hiragana / full-width alphabet") (evil-test-buffer "[ひ]らがなABC" ("w") "ひらがな[A]BC")) (ert-info ("Hiragana / full-width numeric") (evil-test-buffer "[ひ]らがな123" ("w") "ひらがな[1]23")) (ert-info ("Hiragana / Hangul") (evil-test-buffer "[ひ]らがな한글" ("w") "ひらがな[한]글")) (ert-info ("Katakana / Latin") (evil-test-buffer "[カ]タカナabcd" ("w") "カタカナ[a]bcd")) (ert-info ("Katakana / numeric") (evil-test-buffer "[カ]タカナ1234" ("w") "カタカナ[1]234")) (ert-info ("Katakana / Kanji") (evil-test-buffer "[カ]タカナ漢字" ("w") "カタカナ[漢]字")) (ert-info ("Katakana / Hiragana") (evil-test-buffer "[カ]タカナひらがな" ("w") "カタカナ[ひ]らがな")) (ert-info ("Katakana / half-width Katakana") (evil-test-buffer "[カ]タカナカタカナ" ("w") "カタカナ[カ]タカナ")) (ert-info ("Katakana / full-width alphabet") (evil-test-buffer "[カ]タカナABC" ("w") "カタカナ[A]BC")) (ert-info ("Katakana / full-width numeric") (evil-test-buffer "[カ]タカナ123" ("w") "カタカナ[1]23")) (ert-info ("Katakana / Hangul") (evil-test-buffer "[カ]タカナ한글" ("w") "カタカナ[한]글")) (ert-info ("half-width Katakana / Latin") (evil-test-buffer "[カ]タカナabcd" ("w") "カタカナabc[d]")) (ert-info ("half-width Katakana / numeric") (evil-test-buffer "[カ]タカナ1234" ("w") "カタカナ123[4]")) (ert-info ("half-width Katakana / Kanji") (evil-test-buffer "[カ]タカナ漢字" ("w") "カタカナ[漢]字")) (ert-info ("half-width Katakana / Hiragana") (evil-test-buffer "[カ]タカナひらがな" ("w") "カタカナ[ひ]らがな")) (ert-info ("half-width Katakana / Katakana") (evil-test-buffer "[カ]タカナカタカナ" ("w") "カタカナ[カ]タカナ")) (ert-info ("half-width Katakana / full-width alphabet") (evil-test-buffer "[カ]タカナABC" ("w") "カタカナAB[C]")) (ert-info ("half-width Katakana / full-width numeric") (evil-test-buffer "[カ]タカナ123" ("w") "カタカナ12[3]")) (ert-info ("half-width Katakana / Hangul") (evil-test-buffer "[カ]タカナ한글" ("w") "カタカナ[한]글")) (ert-info ("full-width alphabet / Latin") (evil-test-buffer "[A]BCabcd" ("w") "ABCabc[d]")) (ert-info ("full-width alphabet / numeric") (evil-test-buffer "[A]BC1234" ("w") "ABC123[4]")) (ert-info ("full-width alphabet / Kanji") (evil-test-buffer "[A]BC漢字" ("w") "ABC[漢]字")) (ert-info ("full-width alphabet / Hiragana") (evil-test-buffer "[A]BCひらがな" ("w") "ABC[ひ]らがな")) (ert-info ("full-width alphabet / Katakana") (evil-test-buffer "[A]BCカタカナ" ("w") "ABC[カ]タカナ")) (ert-info ("full-width alphabet / half-width Katakana") (evil-test-buffer "[A]BCカタカナ" ("w") "ABCカタカ[ナ]")) (ert-info ("full-width alphabet / full-width numeric") (evil-test-buffer "[A]BC123" ("w") "ABC12[3]")) (ert-info ("full-width alphabet / Hangul") (evil-test-buffer "[A]BC한글" ("w") "ABC[한]글")) (ert-info ("full-width numeric / Latin") (evil-test-buffer "[1]23abcd" ("w") "123abc[d]")) (ert-info ("full-width numeric / numeric") (evil-test-buffer "[1]231234" ("w") "123123[4]")) (ert-info ("full-width numeric / Kanji") (evil-test-buffer "[1]23漢字" ("w") "123[漢]字")) (ert-info ("full-width numeric / Hiragana") (evil-test-buffer "[1]23ひらがな" ("w") "123[ひ]らがな")) (ert-info ("full-width numeric / Katakana") (evil-test-buffer "[1]23カタカナ" ("w") "123[カ]タカナ")) (ert-info ("full-width numeric / half-width Katakana") (evil-test-buffer "[1]23カタカナ" ("w") "123カタカ[ナ]")) (ert-info ("full-width numeric / full-width alphabet") (evil-test-buffer "[1]23ABC" ("w") "123AB[C]")) (ert-info ("full-width numeric / Hangul") (evil-test-buffer "[1]23한글" ("w") "123[한]글")) (ert-info ("Hangul / Latin") (evil-test-buffer "[한]글abcd" ("w") "한글[a]bcd")) (ert-info ("Hangul / numeric") (evil-test-buffer "[한]글1234" ("w") "한글[1]234")) (ert-info ("Hangul / Kanji") (evil-test-buffer "[한]글漢字" ("w") "한글[漢]字")) (ert-info ("Hangul / Hiragana") (evil-test-buffer "[한]글ひらがな" ("w") "한글[ひ]らがな")) (ert-info ("Hangul / Katakana") (evil-test-buffer "[한]글カタカナ" ("w") "한글[カ]タカナ")) (ert-info ("Hangul / half-width Katakana") (evil-test-buffer "[한]글カタカナ" ("w") "한글[カ]タカナ")) (ert-info ("Hangul / full-width alphabet") (evil-test-buffer "[한]글ABC" ("w") "한글[A]BC")) (ert-info ("Hangul / full-width numeric") (evil-test-buffer "[한]글123" ("w") "한글[1]23"))) (ert-deftest evil-test-forward-word-end-cjk () "Test `evil-forward-word-end' on CJK words" :tags '(evil motion cjk) (ert-info ("Latin / numeric") (evil-test-buffer "[a]bcd1234" ("e") "abcd123[4]")) (ert-info ("Latin / Kanji") (evil-test-buffer "[a]bcd漢字" ("e") "abc[d]漢字")) (ert-info ("Latin / Hiragana") (evil-test-buffer "[a]bcdひらがな" ("e") "abc[d]ひらがな")) (ert-info ("Latin / Katakana") (evil-test-buffer "[a]bcdカタカナ" ("e") "abc[d]カタカナ")) (ert-info ("Latin / half-width Katakana") (evil-test-buffer "[a]bcdカタカナ" ("e") "abcdカタカ[ナ]")) (ert-info ("Latin / full-width alphabet") (evil-test-buffer "[a]bcdABC" ("e") "abcdAB[C]")) (ert-info ("Latin / full-width numeric") (evil-test-buffer "[a]bcd123" ("e") "abcd12[3]")) (ert-info ("Latin / Hangul") (evil-test-buffer "[a]bcd한글" ("e") "abc[d]한글")) (ert-info ("numeric / Latin") (evil-test-buffer "[1]234abcd" ("e") "1234abc[d]")) (ert-info ("numeric / Kanji") (evil-test-buffer "[1]234漢字" ("e") "123[4]漢字")) (ert-info ("numeric / Hiragana") (evil-test-buffer "[1]234ひらがな" ("e") "123[4]ひらがな")) (ert-info ("numeric / Katakana") (evil-test-buffer "[1]234カタカナ" ("e") "123[4]カタカナ")) (ert-info ("numeric / half-width Katakana") (evil-test-buffer "[1]234カタカナ" ("e") "1234カタカ[ナ]")) (ert-info ("numeric / full-width alphabet") (evil-test-buffer "[1]234ABC" ("e") "1234AB[C]")) (ert-info ("numeric / full-width numeric") (evil-test-buffer "[1]234123" ("e") "123412[3]")) (ert-info ("numeric / Hangul") (evil-test-buffer "[1]234한글" ("e") "123[4]한글")) (ert-info ("Kanji / Latin") (evil-test-buffer "[漢]字abcd" ("e") "漢[字]abcd")) (ert-info ("Kanji / numeric") (evil-test-buffer "[漢]字1234" ("e") "漢[字]1234")) (ert-info ("Kanji / Hiragana") (evil-test-buffer "[漢]字ひらがな" ("e") "漢[字]ひらがな")) (ert-info ("Kanji / Katakana") (evil-test-buffer "[漢]字カタカナ" ("e") "漢[字]カタカナ")) (ert-info ("Kanji / half-width Katakana") (evil-test-buffer "[漢]字カタカナ" ("e") "漢[字]カタカナ")) (ert-info ("Kanji / full-width alphabet") (evil-test-buffer "[漢]字ABC" ("e") "漢[字]ABC")) (ert-info ("Kanji / full-width numeric") (evil-test-buffer "[漢]字123" ("e") "漢[字]123")) (ert-info ("Kanji / Hangul") (evil-test-buffer "[漢]字한글" ("e") "漢[字]한글")) (ert-info ("Hiragana / Latin") (evil-test-buffer "[ひ]らがなabcd" ("e") "ひらが[な]abcd")) (ert-info ("Hiragana / numeric") (evil-test-buffer "[ひ]らがな1234" ("e") "ひらが[な]1234")) (ert-info ("Hiragana / Kanji") (evil-test-buffer "[ひ]らがな漢字" ("e") "ひらが[な]漢字")) (ert-info ("Hiragana / Katakana") (evil-test-buffer "[ひ]らがなカタカナ" ("e") "ひらが[な]カタカナ")) (ert-info ("Hiragana / half-width Katakana") (evil-test-buffer "[ひ]らがなカタカナ" ("e") "ひらが[な]カタカナ")) (ert-info ("Hiragana / full-width alphabet") (evil-test-buffer "[ひ]らがなABC" ("e") "ひらが[な]ABC")) (ert-info ("Hiragana / full-width numeric") (evil-test-buffer "[ひ]らがな123" ("e") "ひらが[な]123")) (ert-info ("Hiragana / Hangul") (evil-test-buffer "[ひ]らがな한글" ("e") "ひらが[な]한글")) (ert-info ("Katakana / Latin") (evil-test-buffer "[カ]タカナabcd" ("e") "カタカ[ナ]abcd")) (ert-info ("Katakana / numeric") (evil-test-buffer "[カ]タカナ1234" ("e") "カタカ[ナ]1234")) (ert-info ("Katakana / Kanji") (evil-test-buffer "[カ]タカナ漢字" ("e") "カタカ[ナ]漢字")) (ert-info ("Katakana / Hiragana") (evil-test-buffer "[カ]タカナひらがな" ("e") "カタカ[ナ]ひらがな")) (ert-info ("Katakana / half-width Katakana") (evil-test-buffer "[カ]タカナカタカナ" ("e") "カタカ[ナ]カタカナ")) (ert-info ("Katakana / full-width alphabet") (evil-test-buffer "[カ]タカナABC" ("e") "カタカ[ナ]ABC")) (ert-info ("Katakana / full-width numeric") (evil-test-buffer "[カ]タカナ123" ("e") "カタカ[ナ]123")) (ert-info ("Katakana / Hangul") (evil-test-buffer "[カ]タカナ한글" ("e") "カタカ[ナ]한글")) (ert-info ("half-width Katakana / Latin") (evil-test-buffer "[カ]タカナabcd" ("e") "カタカナabc[d]")) (ert-info ("half-width Katakana / numeric") (evil-test-buffer "[カ]タカナ1234" ("e") "カタカナ123[4]")) (ert-info ("half-width Katakana / Kanji") (evil-test-buffer "[カ]タカナ漢字" ("e") "カタカ[ナ]漢字")) (ert-info ("half-width Katakana / Hiragana") (evil-test-buffer "[カ]タカナひらがな" ("e") "カタカ[ナ]ひらがな")) (ert-info ("half-width Katakana / Katakana") (evil-test-buffer "[カ]タカナカタカナ" ("e") "カタカ[ナ]カタカナ")) (ert-info ("half-width Katakana / full-width alphabet") (evil-test-buffer "[カ]タカナABC" ("e") "カタカナAB[C]")) (ert-info ("half-width Katakana / full-width numeric") (evil-test-buffer "[カ]タカナ123" ("e") "カタカナ12[3]")) (ert-info ("half-width Katakana / Hangul") (evil-test-buffer "[カ]タカナ한글" ("e") "カタカ[ナ]한글")) (ert-info ("full-width alphabet / Latin") (evil-test-buffer "[A]BCabcd" ("e") "ABCabc[d]")) (ert-info ("full-width alphabet / numeric") (evil-test-buffer "[A]BC1234" ("e") "ABC123[4]")) (ert-info ("full-width alphabet / Kanji") (evil-test-buffer "[A]BC漢字" ("e") "AB[C]漢字")) (ert-info ("full-width alphabet / Hiragana") (evil-test-buffer "[A]BCひらがな" ("e") "AB[C]ひらがな")) (ert-info ("full-width alphabet / Katakana") (evil-test-buffer "[A]BCカタカナ" ("e") "AB[C]カタカナ")) (ert-info ("full-width alphabet / half-width Katakana") (evil-test-buffer "[A]BCカタカナ" ("e") "ABCカタカ[ナ]")) (ert-info ("full-width alphabet / full-width numeric") (evil-test-buffer "[A]BC123" ("e") "ABC12[3]")) (ert-info ("full-width alphabet / Hangul") (evil-test-buffer "[A]BC한글" ("e") "AB[C]한글")) (ert-info ("full-width numeric / Latin") (evil-test-buffer "[1]23abcd" ("e") "123abc[d]")) (ert-info ("full-width numeric / numeric") (evil-test-buffer "[1]231234" ("e") "123123[4]")) (ert-info ("full-width numeric / Kanji") (evil-test-buffer "[1]23漢字" ("e") "12[3]漢字")) (ert-info ("full-width numeric / Hiragana") (evil-test-buffer "[1]23ひらがな" ("e") "12[3]ひらがな")) (ert-info ("full-width numeric / Katakana") (evil-test-buffer "[1]23カタカナ" ("e") "12[3]カタカナ")) (ert-info ("full-width numeric / half-width Katakana") (evil-test-buffer "[1]23カタカナ" ("e") "123カタカ[ナ]")) (ert-info ("full-width numeric / full-width alphabet") (evil-test-buffer "[1]23ABC" ("e") "123AB[C]")) (ert-info ("full-width numeric / Hangul") (evil-test-buffer "[1]23한글" ("e") "12[3]한글")) (ert-info ("Hangul / Latin") (evil-test-buffer "[한]글abcd" ("e") "한[글]abcd")) (ert-info ("Hangul / numeric") (evil-test-buffer "[한]글1234" ("e") "한[글]1234")) (ert-info ("Hangul / Kanji") (evil-test-buffer "[한]글漢字" ("e") "한[글]漢字")) (ert-info ("Hangul / Hiragana") (evil-test-buffer "[한]글ひらがな" ("e") "한[글]ひらがな")) (ert-info ("Hangul / Katakana") (evil-test-buffer "[한]글カタカナ" ("e") "한[글]カタカナ")) (ert-info ("Hangul / half-width Katakana") (evil-test-buffer "[한]글カタカナ" ("e") "한[글]カタカナ")) (ert-info ("Hangul / full-width alphabet") (evil-test-buffer "[한]글ABC" ("e") "한[글]ABC")) (ert-info ("Hangul / full-width numeric") (evil-test-buffer "[한]글123" ("e") "한[글]123"))) (ert-deftest evil-test-backword-word-begin-cjk () "Test `evil-backward-word-begin' on CJK words" :tags '(evil motion cjk) (ert-info ("Latin / numeric") (evil-test-buffer "abcd123[4]" ("b") "[a]bcd1234")) (ert-info ("Latin / Kanji") (evil-test-buffer "abcd漢[字]" ("b") "abcd[漢]字")) (ert-info ("Latin / Hiragana") (evil-test-buffer "abcdひらが[な]" ("b") "abcd[ひ]らがな")) (ert-info ("Latin / Katakana") (evil-test-buffer "abcdカタカ[ナ]" ("b") "abcd[カ]タカナ")) (ert-info ("Latin / half-width Katakana") (evil-test-buffer "abcdカタカ[ナ]" ("b") "[a]bcdカタカナ")) (ert-info ("Latin / full-width alphabet") (evil-test-buffer "abcdAB[C]" ("b") "[a]bcdABC")) (ert-info ("Latin / full-width numeric") (evil-test-buffer "abcd12[3]" ("b") "[a]bcd123")) (ert-info ("Latin / Hangul") (evil-test-buffer "abcd한[글]" ("b") "abcd[한]글")) (ert-info ("numeric / Latin") (evil-test-buffer "1234abc[d]" ("b") "[1]234abcd")) (ert-info ("numeric / Kanji") (evil-test-buffer "1234漢[字]" ("b") "1234[漢]字")) (ert-info ("numeric / Hiragana") (evil-test-buffer "1234ひらが[な]" ("b") "1234[ひ]らがな")) (ert-info ("numeric / Katakana") (evil-test-buffer "1234カタカ[ナ]" ("b") "1234[カ]タカナ")) (ert-info ("numeric / half-width Katakana") (evil-test-buffer "1234カタカ[ナ]" ("b") "[1]234カタカナ")) (ert-info ("numeric / full-width alphabet") (evil-test-buffer "1234AB[C]" ("b") "[1]234ABC")) (ert-info ("numeric / full-width numeric") (evil-test-buffer "123412[3]" ("b") "[1]234123")) (ert-info ("numeric / Hangul") (evil-test-buffer "1234한[글]" ("b") "1234[한]글")) (ert-info ("Kanji / Latin") (evil-test-buffer "漢字abc[d]" ("b") "漢字[a]bcd")) (ert-info ("Kanji / numeric") (evil-test-buffer "漢字123[4]" ("b") "漢字[1]234")) (ert-info ("Kanji / Hiragana") (evil-test-buffer "漢字ひらが[な]" ("b") "漢字[ひ]らがな")) (ert-info ("Kanji / Katakana") (evil-test-buffer "漢字カタカ[ナ]" ("b") "漢字[カ]タカナ")) (ert-info ("Kanji / half-width Katakana") (evil-test-buffer "漢字カタカ[ナ]" ("b") "漢字[カ]タカナ")) (ert-info ("Kanji / full-width alphabet") (evil-test-buffer "漢字AB[C]" ("b") "漢字[A]BC")) (ert-info ("Kanji / full-width numeric") (evil-test-buffer "漢字12[3]" ("b") "漢字[1]23")) (ert-info ("Kanji / Hangul") (evil-test-buffer "漢字한[글]" ("b") "漢字[한]글")) (ert-info ("Hiragana / Latin") (evil-test-buffer "ひらがなabc[d]" ("b") "ひらがな[a]bcd")) (ert-info ("Hiragana / numeric") (evil-test-buffer "ひらがな123[4]" ("b") "ひらがな[1]234")) (ert-info ("Hiragana / Kanji") (evil-test-buffer "ひらがな漢[字]" ("b") "ひらがな[漢]字")) (ert-info ("Hiragana / Katakana") (evil-test-buffer "ひらがなカタカ[ナ]" ("b") "ひらがな[カ]タカナ")) (ert-info ("Hiragana / half-width Katakana") (evil-test-buffer "ひらがなカタカ[ナ]" ("b") "ひらがな[カ]タカナ")) (ert-info ("Hiragana / full-width alphabet") (evil-test-buffer "ひらがなAB[C]" ("b") "ひらがな[A]BC")) (ert-info ("Hiragana / full-width numeric") (evil-test-buffer "ひらがな12[3]" ("b") "ひらがな[1]23")) (ert-info ("Hiragana / Hangul") (evil-test-buffer "ひらがな한[글]" ("b") "ひらがな[한]글")) (ert-info ("Katakana / Latin") (evil-test-buffer "カタカナabc[d]" ("b") "カタカナ[a]bcd")) (ert-info ("Katakana / numeric") (evil-test-buffer "カタカナ123[4]" ("b") "カタカナ[1]234")) (ert-info ("Katakana / Kanji") (evil-test-buffer "カタカナ漢[字]" ("b") "カタカナ[漢]字")) (ert-info ("Katakana / Hiragana") (evil-test-buffer "カタカナひらが[な]" ("b") "カタカナ[ひ]らがな")) (ert-info ("Katakana / half-width Katakana") (evil-test-buffer "カタカナカタカ[ナ]" ("b") "カタカナ[カ]タカナ")) (ert-info ("Katakana / full-width alphabet") (evil-test-buffer "カタカナAB[C]" ("b") "カタカナ[A]BC")) (ert-info ("Katakana / full-width numeric") (evil-test-buffer "カタカナ12[3]" ("b") "カタカナ[1]23")) (ert-info ("Katakana / Hangul") (evil-test-buffer "カタカナ한[글]" ("b") "カタカナ[한]글")) (ert-info ("half-width Katakana / Latin") (evil-test-buffer "カタカナabc[d]" ("b") "[カ]タカナabcd")) (ert-info ("half-width Katakana / numeric") (evil-test-buffer "カタカナ123[4]" ("b") "[カ]タカナ1234")) (ert-info ("half-width Katakana / Kanji") (evil-test-buffer "カタカナ漢[字]" ("b") "カタカナ[漢]字")) (ert-info ("half-width Katakana / Hiragana") (evil-test-buffer "カタカナひらが[な]" ("b") "カタカナ[ひ]らがな")) (ert-info ("half-width Katakana / Katakana") (evil-test-buffer "カタカナカタカ[ナ]" ("b") "カタカナ[カ]タカナ")) (ert-info ("half-width Katakana / full-width alphabet") (evil-test-buffer "カタカナAB[C]" ("b") "[カ]タカナABC")) (ert-info ("half-width Katakana / full-width numeric") (evil-test-buffer "カタカナ12[3]" ("b") "[カ]タカナ123")) (ert-info ("half-width Katakana / Hangul") (evil-test-buffer "カタカナ한[글]" ("b") "カタカナ[한]글")) (ert-info ("full-width alphabet / Latin") (evil-test-buffer "ABCabc[d]" ("b") "[A]BCabcd")) (ert-info ("full-width alphabet / numeric") (evil-test-buffer "ABC123[4]" ("b") "[A]BC1234")) (ert-info ("full-width alphabet / Kanji") (evil-test-buffer "ABC漢[字]" ("b") "ABC[漢]字")) (ert-info ("full-width alphabet / Hiragana") (evil-test-buffer "ABCひらが[な]" ("b") "ABC[ひ]らがな")) (ert-info ("full-width alphabet / Katakana") (evil-test-buffer "ABCカタカ[ナ]" ("b") "ABC[カ]タカナ")) (ert-info ("full-width alphabet / half-width Katakana") (evil-test-buffer "ABCカタカ[ナ]" ("b") "[A]BCカタカナ")) (ert-info ("full-width alphabet / full-width numeric") (evil-test-buffer "ABC12[3]" ("b") "[A]BC123")) (ert-info ("full-width alphabet / Hangul") (evil-test-buffer "ABC한[글]" ("b") "ABC[한]글")) (ert-info ("full-width numeric / Latin") (evil-test-buffer "123abc[d]" ("b") "[1]23abcd")) (ert-info ("full-width numeric / numeric") (evil-test-buffer "123123[4]" ("b") "[1]231234")) (ert-info ("full-width numeric / Kanji") (evil-test-buffer "123漢[字]" ("b") "123[漢]字")) (ert-info ("full-width numeric / Hiragana") (evil-test-buffer "123ひらが[な]" ("b") "123[ひ]らがな")) (ert-info ("full-width numeric / Katakana") (evil-test-buffer "123カタカ[ナ]" ("b") "123[カ]タカナ")) (ert-info ("full-width numeric / half-width Katakana") (evil-test-buffer "123カタカ[ナ]" ("b") "[1]23カタカナ")) (ert-info ("full-width numeric / full-width alphabet") (evil-test-buffer "123AB[C]" ("b") "[1]23ABC")) (ert-info ("full-width numeric / Hangul") (evil-test-buffer "123한[글]" ("b") "123[한]글")) (ert-info ("Hangul / Latin") (evil-test-buffer "한글abc[d]" ("b") "한글[a]bcd")) (ert-info ("Hangul / numeric") (evil-test-buffer "한글123[4]" ("b") "한글[1]234")) (ert-info ("Hangul / Kanji") (evil-test-buffer "한글漢[字]" ("b") "한글[漢]字")) (ert-info ("Hangul / Hiragana") (evil-test-buffer "한글ひらが[な]" ("b") "한글[ひ]らがな")) (ert-info ("Hangul / Katakana") (evil-test-buffer "한글カタカ[ナ]" ("b") "한글[カ]タカナ")) (ert-info ("Hangul / half-width Katakana") (evil-test-buffer "한글カタカ[ナ]" ("b") "한글[カ]タカナ")) (ert-info ("Hangul / full-width alphabet") (evil-test-buffer "한글AB[C]" ("b") "한글[A]BC")) (ert-info ("Hangul / full-width numeric") (evil-test-buffer "한글12[3]" ("b") "한글[1]23"))) (ert-deftest evil-test-backword-word-end-cjk () "Test `evil-backward-word-end' on CJK words" :tags '(evil motion cjk) (ert-info ("Latin / numeric") (evil-test-buffer "abcd123[4]" ("ge") "[a]bcd1234")) (ert-info ("Latin / Kanji") (evil-test-buffer "abcd漢[字]" ("ge") "abc[d]漢字")) (ert-info ("Latin / Hiragana") (evil-test-buffer "abcdひらが[な]" ("ge") "abc[d]ひらがな")) (ert-info ("Latin / Katakana") (evil-test-buffer "abcdカタカ[ナ]" ("ge") "abc[d]カタカナ")) (ert-info ("Latin / half-width Katakana") (evil-test-buffer "abcdカタカ[ナ]" ("ge") "[a]bcdカタカナ")) (ert-info ("Latin / full-width alphabet") (evil-test-buffer "abcdAB[C]" ("ge") "[a]bcdABC")) (ert-info ("Latin / full-width numeric") (evil-test-buffer "abcd12[3]" ("ge") "[a]bcd123")) (ert-info ("Latin / Hangul") (evil-test-buffer "abcd한[글]" ("ge") "abc[d]한글")) (ert-info ("numeric / Latin") (evil-test-buffer "1234abc[d]" ("ge") "[1]234abcd")) (ert-info ("numeric / Kanji") (evil-test-buffer "1234漢[字]" ("ge") "123[4]漢字")) (ert-info ("numeric / Hiragana") (evil-test-buffer "1234ひらが[な]" ("ge") "123[4]ひらがな")) (ert-info ("numeric / Katakana") (evil-test-buffer "1234カタカ[ナ]" ("ge") "123[4]カタカナ")) (ert-info ("numeric / half-width Katakana") (evil-test-buffer "1234カタカ[ナ]" ("ge") "[1]234カタカナ")) (ert-info ("numeric / full-width alphabet") (evil-test-buffer "1234AB[C]" ("ge") "[1]234ABC")) (ert-info ("numeric / full-width numeric") (evil-test-buffer "123412[3]" ("ge") "[1]234123")) (ert-info ("numeric / Hangul") (evil-test-buffer "1234한[글]" ("ge") "123[4]한글")) (ert-info ("Kanji / Latin") (evil-test-buffer "漢字abc[d]" ("ge") "漢[字]abcd")) (ert-info ("Kanji / numeric") (evil-test-buffer "漢字123[4]" ("ge") "漢[字]1234")) (ert-info ("Kanji / Hiragana") (evil-test-buffer "漢字ひらが[な]" ("ge") "漢[字]ひらがな")) (ert-info ("Kanji / Katakana") (evil-test-buffer "漢字カタカ[ナ]" ("ge") "漢[字]カタカナ")) (ert-info ("Kanji / half-width Katakana") (evil-test-buffer "漢字カタカ[ナ]" ("ge") "漢[字]カタカナ")) (ert-info ("Kanji / full-width alphabet") (evil-test-buffer "漢字AB[C]" ("ge") "漢[字]ABC")) (ert-info ("Kanji / full-width numeric") (evil-test-buffer "漢字12[3]" ("ge") "漢[字]123")) (ert-info ("Kanji / Hangul") (evil-test-buffer "漢字한[글]" ("ge") "漢[字]한글")) (ert-info ("Hiragana / Latin") (evil-test-buffer "ひらがなabc[d]" ("ge") "ひらが[な]abcd")) (ert-info ("Hiragana / numeric") (evil-test-buffer "ひらがな123[4]" ("ge") "ひらが[な]1234")) (ert-info ("Hiragana / Kanji") (evil-test-buffer "ひらがな漢[字]" ("ge") "ひらが[な]漢字")) (ert-info ("Hiragana / Katakana") (evil-test-buffer "ひらがなカタカ[ナ]" ("ge") "ひらが[な]カタカナ")) (ert-info ("Hiragana / half-width Katakana") (evil-test-buffer "ひらがなカタカ[ナ]" ("ge") "ひらが[な]カタカナ")) (ert-info ("Hiragana / full-width alphabet") (evil-test-buffer "ひらがなAB[C]" ("ge") "ひらが[な]ABC")) (ert-info ("Hiragana / full-width numeric") (evil-test-buffer "ひらがな12[3]" ("ge") "ひらが[な]123")) (ert-info ("Hiragana / Hangul") (evil-test-buffer "ひらがな한[글]" ("ge") "ひらが[な]한글")) (ert-info ("Katakana / Latin") (evil-test-buffer "カタカナabc[d]" ("ge") "カタカ[ナ]abcd")) (ert-info ("Katakana / numeric") (evil-test-buffer "カタカナ123[4]" ("ge") "カタカ[ナ]1234")) (ert-info ("Katakana / Kanji") (evil-test-buffer "カタカナ漢[字]" ("ge") "カタカ[ナ]漢字")) (ert-info ("Katakana / Hiragana") (evil-test-buffer "カタカナひらが[な]" ("ge") "カタカ[ナ]ひらがな")) (ert-info ("Katakana / half-width Katakana") (evil-test-buffer "カタカナカタカ[ナ]" ("ge") "カタカ[ナ]カタカナ")) (ert-info ("Katakana / full-width alphabet") (evil-test-buffer "カタカナAB[C]" ("ge") "カタカ[ナ]ABC")) (ert-info ("Katakana / full-width numeric") (evil-test-buffer "カタカナ12[3]" ("ge") "カタカ[ナ]123")) (ert-info ("Katakana / Hangul") (evil-test-buffer "カタカナ한[글]" ("ge") "カタカ[ナ]한글")) (ert-info ("half-width Katakana / Latin") (evil-test-buffer "カタカナabc[d]" ("ge") "[カ]タカナabcd")) (ert-info ("half-width Katakana / numeric") (evil-test-buffer "カタカナ123[4]" ("ge") "[カ]タカナ1234")) (ert-info ("half-width Katakana / Kanji") (evil-test-buffer "カタカナ漢[字]" ("ge") "カタカ[ナ]漢字")) (ert-info ("half-width Katakana / Hiragana") (evil-test-buffer "カタカナひらが[な]" ("ge") "カタカ[ナ]ひらがな")) (ert-info ("half-width Katakana / Katakana") (evil-test-buffer "カタカナカタカ[ナ]" ("ge") "カタカ[ナ]カタカナ")) (ert-info ("half-width Katakana / full-width alphabet") (evil-test-buffer "カタカナAB[C]" ("ge") "[カ]タカナABC")) (ert-info ("half-width Katakana / full-width numeric") (evil-test-buffer "カタカナ12[3]" ("ge") "[カ]タカナ123")) (ert-info ("half-width Katakana / Hangul") (evil-test-buffer "カタカナ한[글]" ("ge") "カタカ[ナ]한글")) (ert-info ("full-width alphabet / Latin") (evil-test-buffer "ABCabc[d]" ("ge") "[A]BCabcd")) (ert-info ("full-width alphabet / numeric") (evil-test-buffer "ABC123[4]" ("ge") "[A]BC1234")) (ert-info ("full-width alphabet / Kanji") (evil-test-buffer "ABC漢[字]" ("ge") "AB[C]漢字")) (ert-info ("full-width alphabet / Hiragana") (evil-test-buffer "ABCひらが[な]" ("ge") "AB[C]ひらがな")) (ert-info ("full-width alphabet / Katakana") (evil-test-buffer "ABCカタカ[ナ]" ("ge") "AB[C]カタカナ")) (ert-info ("full-width alphabet / half-width Katakana") (evil-test-buffer "ABCカタカ[ナ]" ("ge") "[A]BCカタカナ")) (ert-info ("full-width alphabet / full-width numeric") (evil-test-buffer "ABC12[3]" ("ge") "[A]BC123")) (ert-info ("full-width alphabet / Hangul") (evil-test-buffer "ABC한[글]" ("ge") "AB[C]한글")) (ert-info ("full-width numeric / Latin") (evil-test-buffer "123abc[d]" ("ge") "[1]23abcd")) (ert-info ("full-width numeric / numeric") (evil-test-buffer "123123[4]" ("ge") "[1]231234")) (ert-info ("full-width numeric / Kanji") (evil-test-buffer "123漢[字]" ("ge") "12[3]漢字")) (ert-info ("full-width numeric / Hiragana") (evil-test-buffer "123ひらが[な]" ("ge") "12[3]ひらがな")) (ert-info ("full-width numeric / Katakana") (evil-test-buffer "123カタカ[ナ]" ("ge") "12[3]カタカナ")) (ert-info ("full-width numeric / half-width Katakana") (evil-test-buffer "123カタカ[ナ]" ("ge") "[1]23カタカナ")) (ert-info ("full-width numeric / full-width alphabet") (evil-test-buffer "123AB[C]" ("ge") "[1]23ABC")) (ert-info ("full-width numeric / Hangul") (evil-test-buffer "123한[글]" ("ge") "12[3]한글")) (ert-info ("Hangul / Latin") (evil-test-buffer "한글abc[d]" ("ge") "한[글]abcd")) (ert-info ("Hangul / numeric") (evil-test-buffer "한글123[4]" ("ge") "한[글]1234")) (ert-info ("Hangul / Kanji") (evil-test-buffer "한글漢[字]" ("ge") "한[글]漢字")) (ert-info ("Hangul / Hiragana") (evil-test-buffer "한글ひらが[な]" ("ge") "한[글]ひらがな")) (ert-info ("Hangul / Katakana") (evil-test-buffer "한글カタカ[ナ]" ("ge") "한[글]カタカナ")) (ert-info ("Hangul / half-width Katakana") (evil-test-buffer "한글カタカ[ナ]" ("ge") "한[글]カタカナ")) (ert-info ("Hangul / full-width alphabet") (evil-test-buffer "한글AB[C]" ("ge") "한[글]ABC")) (ert-info ("Hangul / full-width numeric") (evil-test-buffer "한글12[3]" ("ge") "한[글]123"))) (ert-deftest evil-test-forward-paragraph () "Test `evil-forward-paragraph'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "[A]bove some line Below some empty line" ("}") "Above some line \[] Below some empty line")) (ert-info ("With count") (evil-test-buffer "[A]bove some line Below some empty line" ("2}") "Above some line Below some empty lin[e]")) (ert-info ("End of buffer") (evil-test-buffer "[B]elow some empty line" ("100}") "Below some empty lin[e]" (should-error (execute-kbd-macro "}")) (should-error (execute-kbd-macro "42}")))) (ert-info ("End of buffer with newline") (evil-test-buffer "[B]elow some empty line\n\n" ("100}") "Below some empty line\n\n[]" (should-error (execute-kbd-macro "}")) (should-error (execute-kbd-macro "42}"))))) (ert-deftest evil-test-backward-paragraph () "Test `evil-backward-paragraph'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "Above some line Below some empty lin[e]" ("{") "Above some line \[] Below some empty line")) (ert-info ("With count") (evil-test-buffer "Above some line Below some empty lin[e]" ("2{") "[A]bove some line Below some empty line")) (ert-info ("Beginning of buffer") (evil-test-buffer "Above some line Below some empty lin[e]" ("100{") "[A]bove some line Below some empty line" (should-error (execute-kbd-macro "{")) (should-error (execute-kbd-macro "42{")))) (ert-info ("Beginning of buffer with newlines") (evil-test-buffer "\n\nAbove some line Below some empty lin[e]" ("100{") "[]\n\nAbove some line Below some empty line" (should-error (execute-kbd-macro "{")) (should-error (execute-kbd-macro "42{"))))) (ert-deftest evil-test-forward-sentence () "Test `evil-forward-sentence'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. Below some empty line." (")") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. [I]f you want to create a file, ;; visit that file with C-x C-f. Below some empty line." (")") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. \[] Below some empty line." (")") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. \[B]elow some empty line.")) (ert-info ("With count") (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. Below some empty line." ("2)") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. \[] Below some empty line." ("2)") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. Below some empty line[.]")) (ert-info ("End of buffer") (evil-test-buffer "[B]elow some empty line." ("100)") "Below some empty line[.]" (should-error (execute-kbd-macro ")")) (should-error (execute-kbd-macro "42)")))) (ert-info ("End of buffer with newline") (evil-test-buffer "[B]elow some empty line.\n\n" (")") "Below some empty line.\n[\n]" (")") "Below some empty line.\n\n[]" (should-error (execute-kbd-macro ")")) (should-error (execute-kbd-macro "42)"))))) (ert-deftest evil-test-backward-sentence () "Test `evil-backward-sentence'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. Below some empty line[.]" ("(") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. \[B]elow some empty line." ("(") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. \[] Below some empty line." ("(") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. [I]f you want to create a file, ;; visit that file with C-x C-f. Below some empty line." ("(") "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. Below some empty line.")) (ert-info ("With count") (evil-test-buffer ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. Below some empty line[.]" ("2(") ";; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. \[] Below some empty line." ("2(") "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. If you want to create a file, ;; visit that file with C-x C-f. Below some empty line.")) (ert-info ("Beginning of buffer") (evil-test-buffer ";; This buffer is for notes you don't want to save[.]" ("100(") "[;]; This buffer is for notes you don't want to save." (should-error (execute-kbd-macro "(")) (should-error (execute-kbd-macro "42(")))) (ert-info ("Beginning of buffer with newlines") (evil-test-buffer "\n\n;; This buffer is for notes you don't want to save[.]" ("100(") "[]\n\n;; This buffer is for notes you don't want to save." (should-error (execute-kbd-macro "(")) (should-error (execute-kbd-macro "42("))))) (ert-deftest evil-test-find-char () "Test `evil-find-char'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "[;]; This buffer is for notes." ("fT") ";; [T]his buffer is for notes.")) (ert-info ("With count") (evil-test-buffer "[;]; This buffer is for notes." ("2fe") ";; This buffer is for not[e]s.")) (ert-info ("Repeat") (evil-test-buffer "[;]; This buffer is for notes." ("fe;") ";; This buffer is for not[e]s.")) (ert-info ("Repeat backward") (evil-test-buffer "[;]; This buffer is for notes." ("2fe,") ";; This buff[e]r is for notes.")) (ert-info ("No match") (evil-test-buffer "[;]; This buffer is for notes." (should-error (execute-kbd-macro "fL")))) (ert-info ("End of line") (let ((evil-cross-lines t)) (evil-test-buffer "[;]; This buffer is for notes, ;; and for Lisp evaluation." ("fL") ";; This buffer is for notes, ;; and for [L]isp evaluation."))) (ert-info ("Empty line") (evil-test-buffer "[] This buffer is for notes." (should-error (execute-kbd-macro "fT"))))) (ert-deftest evil-test-find-char-backward () "Test `evil-find-char-backward'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; This buffer is for notes[.]" ("FT") ";; [T]his buffer is for notes.")) (ert-info ("With count") (evil-test-buffer ";; This buffer is for notes[.]" ("2Fe") ";; This buff[e]r is for notes.")) (ert-info ("Repeat") (evil-test-buffer ";; This buffer is for notes[.]" ("Fe;") ";; This buff[e]r is for notes.")) (ert-info ("Repeat backward") (evil-test-buffer ";; This buffer is for notes[.]" ("2Fe,") ";; This buffer is for not[e]s.")) (ert-info ("No match") (evil-test-buffer ";; This buffer is for notes[.]" (should-error (execute-kbd-macro "FL")))) (ert-info ("End of line") (let ((evil-cross-lines t)) (evil-test-buffer ";; This buffer is for notes, ;; and for Lisp evaluation[.]" ("FT") ";; [T]his buffer is for notes, ;; and for Lisp evaluation.")))) (ert-deftest evil-test-find-digraph-char () "Test evil-read-digraph-char while finding char." :tags '(evil motion) (ert-info ("Find digraph char") (evil-test-buffer "a[b]cde∀g" ("f\C-kFA") "abcde[∀]g"))) (ert-deftest evil-test-find-char-to () "Test `evil-find-char-to'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "[;]; This buffer is for notes." ("tT") ";;[ ]This buffer is for notes.")) (ert-info ("With count") (evil-test-buffer "[;]; This buffer is for notes." ("2te") ";; This buffer is for no[t]es.")) (ert-info ("Repeat") (evil-test-buffer "[;]; This buffer is for notes." ("tel;") ";; This buffer is for no[t]es.")) (ert-info ("Repeat backward") (evil-test-buffer "[;]; This buffer is for notes." ("2te,") ";; This buffe[r] is for notes.")) (ert-info ("Repeat should skip adjacent character") (let ((evil-repeat-find-to-skip-next t)) (evil-test-buffer "[a]aaxaaaxaaaxaaa" ("tx;") "aaaxaa[a]xaaaxaaa" (";") "aaaxaaaxaa[a]xaaa" (",") "aaaxaaax[a]aaxaaa" (",") "aaax[a]aaxaaaxaaa"))) (ert-info ("Repeat should NOT skip adjacent character") (let ((evil-repeat-find-to-skip-next nil)) (evil-test-buffer "[a]aaxaaaxaaaxaaa" ("tx;") "aa[a]xaaaxaaaxaaa"))) (ert-info ("No match") (evil-test-buffer "[;]; This buffer is for notes." (should-error (execute-kbd-macro "tL")))) (ert-info ("End of line") (let ((evil-cross-lines t)) (evil-test-buffer "[;]; This buffer is for notes, ;; and for Lisp evaluation." ("tL") ";; This buffer is for notes, ;; and for[ ]Lisp evaluation.")))) (ert-deftest evil-test-find-char-to-backward () "Test `evil-find-char-to-backward'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer ";; This buffer is for notes[.]" ("TT") ";; T[h]is buffer is for notes.")) (ert-info ("With count") (evil-test-buffer ";; This buffer is for notes[.]" ("2Te") ";; This buffe[r] is for notes.")) (ert-info ("Repeat") (evil-test-buffer ";; This buffer is for notes[.]" ("Teh;") ";; This buffe[r] is for notes.")) (ert-info ("Repeat backward") (evil-test-buffer ";; This buffer is for notes[.]" ("2Te,") ";; This buffer is for no[t]es.")) (ert-info ("Repeat should skip adjacent character") (let ((evil-repeat-find-to-skip-next t)) (evil-test-buffer "aaaxaaaxaaaxaa[a]" ("Tx;") "aaaxaaax[a]aaxaaa" (";") "aaax[a]aaxaaaxaaa" (",") "aaaxaa[a]xaaaxaaa" (",") "aaaxaaaxaa[a]xaaa"))) (ert-info ("Repeat should NOT skip adjacent character") (let ((evil-repeat-find-to-skip-next nil)) (evil-test-buffer "aaaxaaaxaaaxaa[a]" ("Tx;") "aaaxaaaxaaax[a]aa"))) (ert-info ("No match") (evil-test-buffer ";; This buffer is for notes[.]" (should-error (execute-kbd-macro "TL")))) (ert-info ("End of line") (let ((evil-cross-lines t)) (evil-test-buffer ";; This buffer is for notes, ;; and for Lisp evaluation[.]" ("TT") ";; T[h]is buffer is for notes, ;; and for Lisp evaluation.")))) (ert-deftest evil-test-jump-item () "Test `evil-jump-item'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "int main[(]int argc, char** argv)" ("%") "int main(int argc, char** argv[)]" ("%") "int main[(]int argc, char** argv)")) (ert-info ("Before parenthesis") (evil-test-buffer "[i]nt main(int argc, char** argv)" ("%") "int main(int argc, char** argv[)]" ("5h") "int main(int argc, char**[ ]argv)" ("%") "int main[(]int argc, char** argv)")) (ert-info ("Over several lines") (evil-test-buffer "int main(int argc, char** argv) \[{] printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" ("%") "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]")) (ert-info ("On line without parenthesis") (evil-test-buffer "[#]include " (should-error (execute-kbd-macro "%")))) (ert-info ("Before unmatched opening parenthesies") (evil-test-buffer "x[x]xx ( yyyyy () zzzz" (should-error (execute-kbd-macro "%")) "x[x]xx ( yyyyy () zzzz")) (ert-info ("Before unmatched closing parenthesies") (evil-test-buffer "x[x]xx ) yyyyy () zzzz" (should-error (execute-kbd-macro "%")) "x[x]xx ) yyyyy () zzzz")) (ert-info ("At the end of the line") (evil-test-buffer "[p]ublic void foo(String bar) {\n blabla;\n}\n" ("v$%") "public void foo(String bar) {\n blabla;\n[}]\n"))) (ert-deftest evil-test-unmatched-paren () "Test `evil-previous-open-paren' and `evil-next-close-paren'" :tags '(evil motion) (ert-info ("Simple") (evil-test-buffer "foo ( { ( [b]ar ) baz } )" ("[(") "foo ( { [(] bar ) baz } )" ("])") "foo ( { ( bar [)] baz } )" ("[(") "foo ( { [(] bar ) baz } )" ("[(") "foo [(] { ( bar ) baz } )" ("f)])") "foo ( { ( bar ) baz } [)]")) (ert-info ("With count") (evil-test-buffer "foo ( { ( [b]ar ) baz } )" ("2[(") "foo [(] { ( bar ) baz } )") (evil-test-buffer "foo ( { ( [b]ar ) baz } )" ("2])") "foo ( { ( bar ) baz } [)]"))) (ert-deftest evil-test-next-mark () "Test `evil-next-mark', `evil-previous-mark'" :tags '(evil motion) (ert-info ("Can move to next mark, next mark line, previous mark and previous mark line") (evil-test-buffer "[a]lpha bravo charlie delta echo foxtrot golf hotel india juliet" ("ma" "w" "mb" "w" "mc" "w" "md" "w" "me" "w" "mf" "w" "mg" "w" "mh" "w" "mi" "w" "mj") "alpha bravo charlie delta echo foxtrot golf hotel india [j]uliet" ("3]`") "alpha bravo [c]harlie delta echo foxtrot golf hotel india juliet" ("]'") "alpha bravo charlie delta echo [f]oxtrot golf hotel india juliet" ("[`") "alpha bravo charlie delta [e]cho foxtrot golf hotel india juliet" ("2['") "alpha bravo charlie delta echo foxtrot golf hotel [i]ndia juliet"))) (ert-deftest evil-set-col-0-mark-test () "Test `evil-set-col-0-mark' ex command" :tags '(evil ex) (evil-test-buffer "Lin[e] 1 Line 2" (":mark k" [return] "G" "`k") "[L]ine 1 Line 2")) (ert-deftest evil-delete-marks-test () "Test `evil-delete-marks' ex command" :tags '(evil ex) (ert-info ("Can delete marks") (evil-test-buffer "[O]ne line is enough if we use backtick to navigate" ("mO" "w" "ml" "w" "mi" "$b" "m4") "One line is enough if we use backtick to [n]avigate" ("`O") "[O]ne line is enough if we use backtick to navigate" (":delm O" [return] "`i") "One line [i]s enough if we use backtick to navigate" (error user-error "`O") "One line [i]s enough if we use backtick to navigate" ("`4") "One line is enough if we use backtick to [n]avigate" (":delm h-m" [return]) (error user-error "`i") "One line is enough if we use backtick to [n]avigate"))) (ert-deftest evil-test-flyspell-motions () "Test flyspell motions" :tags '(evil motion) (skip-unless (executable-find "aspell")) (ert-info ("Simple") (evil-test-buffer "[I] cannt tpye for lyfe" (flyspell-mode) (flyspell-buffer) ("]s") "I [c]annt tpye for lyfe" ("]s") "I cannt [t]pye for lyfe" ("]s") "I cannt tpye for [l]yfe" ("]s") "I [c]annt tpye for lyfe" ("[s") "I cannt tpye for [l]yfe" ("[s") "I cannt [t]pye for lyfe")) (ert-info ("With count") (evil-test-buffer "[I] cannt tpye for lyfe" (flyspell-mode) (flyspell-buffer) ("2]s") "I cannt [t]pye for lyfe" ("2]s") "I [c]annt tpye for lyfe" ("2[s") "I cannt [t]pye for lyfe" ("2[s") "I cannt tpye for [l]yfe")) (ert-info ("With evil-search-wrap disabled") (let (evil-search-wrap) (evil-test-buffer "[I] cannt tpye for lyfe" (flyspell-mode) (flyspell-buffer) ("]s") "I [c]annt tpye for lyfe" ("]s") "I cannt [t]pye for lyfe" ("]s") "I cannt tpye for [l]yfe" ("]s") "I cannt tpye for [l]yfe"))) (ert-info ("One mistake") (evil-test-buffer "[I]'m almst there..." (flyspell-mode) (flyspell-buffer) ("]s") "I'm [a]lmst there..." ("]s") "I'm [a]lmst there...")) (ert-info ("No mistakes") (evil-test-buffer "[I]'ve learned to type!" (flyspell-mode) (flyspell-buffer) ("]s") "[I]'ve learned to type!" ("[s") "[I]'ve learned to type!"))) ;;; Text objects (ert-deftest evil-test-text-object () "Test `evil-define-text-object'" :tags '(evil text-object) (let ((object (evil-define-text-object nil (count &optional beg end type) (let ((sel (and beg end (evil-range beg end)))) (when (and sel (> count 0)) (forward-char 1)) (let ((range (if (< count 0) (list (- (point) 3) (point)) (list (point) (+ (point) 3))))) (if sel (evil-range-union range sel) range)))))) (ert-info ("Select three characters after point") (evil-test-buffer :state operator ";; [T]his buffer is for notes." (should (equal (funcall object 1) '(4 7 inclusive))))) (ert-info ("Select three characters before point") (evil-test-buffer :state operator ";; [T]his buffer is for notes." (should (equal (funcall object -1) '(1 4 inclusive))))) (ert-info ("Select three characters after selection") (evil-test-buffer ";; buffer is for notes." (call-interactively object) ";; ffer is for notes.")) (ert-info ("Select three characters before selection") (evil-test-buffer ";; <[T]his> buffer is for notes." (call-interactively object) "<[;]; This> buffer is for notes.")) (ert-info ("Delete three characters after point") (evil-test-buffer "[;]; This buffer is for notes." (define-key evil-operator-state-local-map "io" object) ("dio") "[T]his buffer is for notes.")))) (ert-deftest evil-test-word-objects () "Test `evil-inner-word' and `evil-a-word'" :tags '(evil text-object) (ert-info ("Select a word") (evil-test-buffer ";; [T]his buffer is for notes." ("viw") ";; buffer is for notes.") (evil-test-buffer ";; [T]his buffer is for notes." ("vaw") ";; buffer is for notes.") (evil-test-buffer ";; Thi[s] buffer is for notes." ("viw") ";; buffer is for notes.") (evil-test-buffer ";; Thi[s] buffer is for notes." ("vaw") ";; buffer is for notes.")) (ert-info ("Select two words") (ert-info ("Include whitespace on this side") (evil-test-buffer ";;< Thi[s]> buffer is for notes." ("aw") ";;< This buffe[r]> is for notes.") (evil-test-buffer ";; This <[b]uffer >is for notes." ("aw") ";; <[T]his buffer >is for notes.")) (ert-info ("Include whitespace on the other side") (evil-test-buffer ";; buffer is for notes." ("aw") ";; is for notes.") (evil-test-buffer ";; This<[ ]buffer> is for notes." ("aw") ";;<[ ]This buffer> is for notes."))) (ert-info ("select first visual word") (evil-test-buffer "([a])" ("viw") "(<[a]>)")) (ert-info ("Deleting whitespace is confined to the line") (evil-test-buffer "foo\n [ ] bar" ("diw") "foo\n[b]ar") (evil-test-buffer "foo\n [ ] bar" ("diW") "foo\n[b]ar"))) (ert-deftest evil-test-word-objects-cjk () "Test `evil-inner-word' and `evil-a-word' on CJK words" :tags '(evil text-object cjk) (ert-info ("Select a word") (evil-test-buffer "[a]bcd1234" ("viw") "") (evil-test-buffer "[a]bcd1234" ("vaw") "") (evil-test-buffer "[a]bcd漢字" ("viw") "漢字") (evil-test-buffer "[a]bcd漢字" ("vaw") "漢字") (evil-test-buffer "[a]bcdひらがな" ("viw") "ひらがな") (evil-test-buffer "[a]bcdひらがな" ("vaw") "ひらがな") (evil-test-buffer "[a]bcdカタカナ" ("viw") "カタカナ") (evil-test-buffer "[a]bcdカタカナ" ("vaw") "カタカナ") (evil-test-buffer "[a]bcdカタカナ" ("viw") "") (evil-test-buffer "[a]bcdカタカナ" ("vaw") "") (evil-test-buffer "[a]bcdABC" ("viw") "") (evil-test-buffer "[a]bcdABC" ("vaw") "") (evil-test-buffer "[a]bcd123" ("viw") "") (evil-test-buffer "[a]bcd123" ("vaw") "") (evil-test-buffer "[a]bcd한글" ("viw") "한글") (evil-test-buffer "[a]bcd한글" ("vaw") "한글") (evil-test-buffer "[1]234abcd" ("viw") "<1234abc[d]>") (evil-test-buffer "[1]234abcd" ("vaw") "<1234abc[d]>") (evil-test-buffer "[1]234漢字" ("viw") "<123[4]>漢字") (evil-test-buffer "[1]234漢字" ("vaw") "<123[4]>漢字") (evil-test-buffer "[1]234ひらがな" ("viw") "<123[4]>ひらがな") (evil-test-buffer "[1]234ひらがな" ("vaw") "<123[4]>ひらがな") (evil-test-buffer "[1]234カタカナ" ("viw") "<123[4]>カタカナ") (evil-test-buffer "[1]234カタカナ" ("vaw") "<123[4]>カタカナ") (evil-test-buffer "[1]234カタカナ" ("viw") "<1234カタカ[ナ]>") (evil-test-buffer "[1]234カタカナ" ("vaw") "<1234カタカ[ナ]>") (evil-test-buffer "[1]234ABC" ("viw") "<1234AB[C]>") (evil-test-buffer "[1]234ABC" ("vaw") "<1234AB[C]>") (evil-test-buffer "[1]234123" ("viw") "<123412[3]>") (evil-test-buffer "[1]234123" ("vaw") "<123412[3]>") (evil-test-buffer "[1]234한글" ("viw") "<123[4]>한글") (evil-test-buffer "[1]234한글" ("vaw") "<123[4]>한글") (evil-test-buffer "[漢]字abcd" ("viw") "<漢[字]>abcd") (evil-test-buffer "[漢]字abcd" ("vaw") "<漢[字]>abcd") (evil-test-buffer "[漢]字1234" ("viw") "<漢[字]>1234") (evil-test-buffer "[漢]字1234" ("vaw") "<漢[字]>1234") (evil-test-buffer "[漢]字ひらがな" ("viw") "<漢[字]>ひらがな") (evil-test-buffer "[漢]字ひらがな" ("vaw") "<漢[字]>ひらがな") (evil-test-buffer "[漢]字カタカナ" ("viw") "<漢[字]>カタカナ") (evil-test-buffer "[漢]字カタカナ" ("vaw") "<漢[字]>カタカナ") (evil-test-buffer "[漢]字カタカナ" ("viw") "<漢[字]>カタカナ") (evil-test-buffer "[漢]字カタカナ" ("vaw") "<漢[字]>カタカナ") (evil-test-buffer "[漢]字ABC" ("viw") "<漢[字]>ABC") (evil-test-buffer "[漢]字ABC" ("vaw") "<漢[字]>ABC") (evil-test-buffer "[漢]字123" ("viw") "<漢[字]>123") (evil-test-buffer "[漢]字123" ("vaw") "<漢[字]>123") (evil-test-buffer "[漢]字한글" ("viw") "<漢[字]>한글") (evil-test-buffer "[漢]字한글" ("vaw") "<漢[字]>한글") (evil-test-buffer "[ひ]らがなabcd" ("viw") "<ひらが[な]>abcd") (evil-test-buffer "[ひ]らがなabcd" ("vaw") "<ひらが[な]>abcd") (evil-test-buffer "[ひ]らがな1234" ("viw") "<ひらが[な]>1234") (evil-test-buffer "[ひ]らがな1234" ("vaw") "<ひらが[な]>1234") (evil-test-buffer "[ひ]らがな漢字" ("viw") "<ひらが[な]>漢字") (evil-test-buffer "[ひ]らがな漢字" ("vaw") "<ひらが[な]>漢字") (evil-test-buffer "[ひ]らがなカタカナ" ("viw") "<ひらが[な]>カタカナ") (evil-test-buffer "[ひ]らがなカタカナ" ("vaw") "<ひらが[な]>カタカナ") (evil-test-buffer "[ひ]らがなカタカナ" ("viw") "<ひらが[な]>カタカナ") (evil-test-buffer "[ひ]らがなカタカナ" ("vaw") "<ひらが[な]>カタカナ") (evil-test-buffer "[ひ]らがなABC" ("viw") "<ひらが[な]>ABC") (evil-test-buffer "[ひ]らがなABC" ("vaw") "<ひらが[な]>ABC") (evil-test-buffer "[ひ]らがな123" ("viw") "<ひらが[な]>123") (evil-test-buffer "[ひ]らがな123" ("vaw") "<ひらが[な]>123") (evil-test-buffer "[ひ]らがな한글" ("viw") "<ひらが[な]>한글") (evil-test-buffer "[ひ]らがな한글" ("vaw") "<ひらが[な]>한글") (evil-test-buffer "[カ]タカナabcd" ("viw") "<カタカ[ナ]>abcd") (evil-test-buffer "[カ]タカナabcd" ("vaw") "<カタカ[ナ]>abcd") (evil-test-buffer "[カ]タカナ1234" ("viw") "<カタカ[ナ]>1234") (evil-test-buffer "[カ]タカナ1234" ("vaw") "<カタカ[ナ]>1234") (evil-test-buffer "[カ]タカナ漢字" ("viw") "<カタカ[ナ]>漢字") (evil-test-buffer "[カ]タカナ漢字" ("vaw") "<カタカ[ナ]>漢字") (evil-test-buffer "[カ]タカナひらがな" ("viw") "<カタカ[ナ]>ひらがな") (evil-test-buffer "[カ]タカナひらがな" ("vaw") "<カタカ[ナ]>ひらがな") (evil-test-buffer "[カ]タカナカタカナ" ("viw") "<カタカ[ナ]>カタカナ") (evil-test-buffer "[カ]タカナカタカナ" ("vaw") "<カタカ[ナ]>カタカナ") (evil-test-buffer "[カ]タカナABC" ("viw") "<カタカ[ナ]>ABC") (evil-test-buffer "[カ]タカナABC" ("vaw") "<カタカ[ナ]>ABC") (evil-test-buffer "[カ]タカナ123" ("viw") "<カタカ[ナ]>123") (evil-test-buffer "[カ]タカナ123" ("vaw") "<カタカ[ナ]>123") (evil-test-buffer "[カ]タカナ한글" ("viw") "<カタカ[ナ]>한글") (evil-test-buffer "[カ]タカナ한글" ("vaw") "<カタカ[ナ]>한글") (evil-test-buffer "[カ]タカナabcd" ("viw") "<カタカナabc[d]>") (evil-test-buffer "[カ]タカナabcd" ("vaw") "<カタカナabc[d]>") (evil-test-buffer "[カ]タカナ1234" ("viw") "<カタカナ123[4]>") (evil-test-buffer "[カ]タカナ1234" ("vaw") "<カタカナ123[4]>") (evil-test-buffer "[カ]タカナ漢字" ("viw") "<カタカ[ナ]>漢字") (evil-test-buffer "[カ]タカナ漢字" ("vaw") "<カタカ[ナ]>漢字") (evil-test-buffer "[カ]タカナひらがな" ("viw") "<カタカ[ナ]>ひらがな") (evil-test-buffer "[カ]タカナひらがな" ("vaw") "<カタカ[ナ]>ひらがな") (evil-test-buffer "[カ]タカナカタカナ" ("viw") "<カタカ[ナ]>カタカナ") (evil-test-buffer "[カ]タカナカタカナ" ("vaw") "<カタカ[ナ]>カタカナ") (evil-test-buffer "[カ]タカナABC" ("viw") "<カタカナAB[C]>") (evil-test-buffer "[カ]タカナABC" ("vaw") "<カタカナAB[C]>") (evil-test-buffer "[カ]タカナ123" ("viw") "<カタカナ12[3]>") (evil-test-buffer "[カ]タカナ123" ("vaw") "<カタカナ12[3]>") (evil-test-buffer "[カ]タカナ한글" ("viw") "<カタカ[ナ]>한글") (evil-test-buffer "[カ]タカナ한글" ("vaw") "<カタカ[ナ]>한글") (evil-test-buffer "[A]BCabcd" ("viw") "<ABCabc[d]>") (evil-test-buffer "[A]BCabcd" ("vaw") "<ABCabc[d]>") (evil-test-buffer "[A]BC1234" ("viw") "<ABC123[4]>") (evil-test-buffer "[A]BC1234" ("vaw") "<ABC123[4]>") (evil-test-buffer "[A]BC漢字" ("viw") "<AB[C]>漢字") (evil-test-buffer "[A]BC漢字" ("vaw") "<AB[C]>漢字") (evil-test-buffer "[A]BCひらがな" ("viw") "<AB[C]>ひらがな") (evil-test-buffer "[A]BCひらがな" ("vaw") "<AB[C]>ひらがな") (evil-test-buffer "[A]BCカタカナ" ("viw") "<AB[C]>カタカナ") (evil-test-buffer "[A]BCカタカナ" ("vaw") "<AB[C]>カタカナ") (evil-test-buffer "[A]BCカタカナ" ("viw") "<ABCカタカ[ナ]>") (evil-test-buffer "[A]BCカタカナ" ("vaw") "<ABCカタカ[ナ]>") (evil-test-buffer "[A]BC123" ("viw") "<ABC12[3]>") (evil-test-buffer "[A]BC123" ("vaw") "<ABC12[3]>") (evil-test-buffer "[A]BC한글" ("viw") "<AB[C]>한글") (evil-test-buffer "[A]BC한글" ("vaw") "<AB[C]>한글") (evil-test-buffer "[1]23abcd" ("viw") "<123abc[d]>") (evil-test-buffer "[1]23abcd" ("vaw") "<123abc[d]>") (evil-test-buffer "[1]231234" ("viw") "<123123[4]>") (evil-test-buffer "[1]231234" ("vaw") "<123123[4]>") (evil-test-buffer "[1]23漢字" ("viw") "<12[3]>漢字") (evil-test-buffer "[1]23漢字" ("vaw") "<12[3]>漢字") (evil-test-buffer "[1]23ひらがな" ("viw") "<12[3]>ひらがな") (evil-test-buffer "[1]23ひらがな" ("vaw") "<12[3]>ひらがな") (evil-test-buffer "[1]23カタカナ" ("viw") "<12[3]>カタカナ") (evil-test-buffer "[1]23カタカナ" ("vaw") "<12[3]>カタカナ") (evil-test-buffer "[1]23カタカナ" ("viw") "<123カタカ[ナ]>") (evil-test-buffer "[1]23カタカナ" ("vaw") "<123カタカ[ナ]>") (evil-test-buffer "[1]23ABC" ("viw") "<123AB[C]>") (evil-test-buffer "[1]23ABC" ("vaw") "<123AB[C]>") (evil-test-buffer "[1]23한글" ("viw") "<12[3]>한글") (evil-test-buffer "[1]23한글" ("vaw") "<12[3]>한글") (evil-test-buffer "[한]글abcd" ("viw") "<한[글]>abcd") (evil-test-buffer "[한]글abcd" ("vaw") "<한[글]>abcd") (evil-test-buffer "[한]글1234" ("viw") "<한[글]>1234") (evil-test-buffer "[한]글1234" ("vaw") "<한[글]>1234") (evil-test-buffer "[한]글漢字" ("viw") "<한[글]>漢字") (evil-test-buffer "[한]글漢字" ("vaw") "<한[글]>漢字") (evil-test-buffer "[한]글ひらがな" ("viw") "<한[글]>ひらがな") (evil-test-buffer "[한]글ひらがな" ("vaw") "<한[글]>ひらがな") (evil-test-buffer "[한]글カタカナ" ("viw") "<한[글]>カタカナ") (evil-test-buffer "[한]글カタカナ" ("vaw") "<한[글]>カタカナ") (evil-test-buffer "[한]글カタカナ" ("viw") "<한[글]>カタカナ") (evil-test-buffer "[한]글カタカナ" ("vaw") "<한[글]>カタカナ") (evil-test-buffer "[한]글ABC" ("viw") "<한[글]>ABC") (evil-test-buffer "[한]글ABC" ("vaw") "<한[글]>ABC") (evil-test-buffer "[한]글123" ("viw") "<한[글]>123") (evil-test-buffer "[한]글123" ("vaw") "<한[글]>123"))) (ert-deftest evil-test-paragraph-objects () "Test `evil-inner-paragraph' and `evil-a-paragraph'" :tags '(evil text-object) (ert-info ("Select a paragraph with point at beginning") (evil-test-buffer "[;]; This buffer is for notes, ;; and for Lisp evaluation. ;; This buffer is for notes, ;; and for Lisp evaluation." ("vap") "<;; This buffer is for notes, ;; and for Lisp evaluation. \[]\n>\ ;; This buffer is for notes, ;; and for Lisp evaluation.")) (ert-info ("Select a paragraph with point at last line") (evil-test-buffer ";; This buffer is for notes, \[;]; and for Lisp evaluation. ;; This buffer is for notes, ;; and for Lisp evaluation." ("vap") "<;; This buffer is for notes, ;; and for Lisp evaluation. \[]\n>\ ;; This buffer is for notes, ;; and for Lisp evaluation.")) (ert-info ("Select a paragraph with point after paragraph") (evil-test-buffer ";; This buffer is for notes, ;; and for Lisp evaluation. \[] ;; This buffer is for notes, ;; and for Lisp evaluation." ("vap") ";; This buffer is for notes, ;; and for Lisp evaluation. < ;; This buffer is for notes, ;; and for Lisp evaluation[.]>")) (ert-info ("Select inner paragraph") (evil-test-buffer "[;]; This buffer is for notes, ;; and for Lisp evaluation. ;; This buffer is for notes, ;; and for Lisp evaluation." ("vip") "<;; This buffer is for notes, ;; and for Lisp evaluation.[] > ;; This buffer is for notes, ;; and for Lisp evaluation.") (evil-test-buffer ";; This buffer is for notes, \[;]; and for Lisp evaluation. ;; This buffer is for notes, ;; and for Lisp evaluation." ("vip") "<;; This buffer is for notes, ;; and for Lisp evaluation.[] > ;; This buffer is for notes, ;; and for Lisp evaluation.") (evil-test-buffer ";; This buffer is for notes, ;; and for Lisp evaluation. \[] ;; This buffer is for notes, ;; and for Lisp evaluation." ("vip") ";; This buffer is for notes, ;; and for Lisp evaluation. < ;; This buffer is for notes, ;; and for Lisp evaluation[.]>"))) (ert-deftest evil-test-quote-objects () "Test `evil-inner-single-quote' and `evil-a-single-quote'" :tags '(evil text-object) (ert-info ("Select text inside of '...'") (evil-test-buffer "This is 'a [t]est' for quote objects." ("vi'") "This is '' for quote objects.") (evil-test-buffer "This is \"a '[t]est'\" for quote objects." ("vi'") "This is \"a ''\" for quote objects.")) (ert-info ("Select text including enclosing quotes") (evil-test-buffer "This is 'a [t]est' for quote objects." ("v2i'") "This is <'a test[']> for quote objects.")) (ert-info ("Select text including enclosing quotes and following space") (evil-test-buffer "This is 'a [t]est' for quote objects." ("va'") "This is <'a test'[ ]>for quote objects.")) (ert-info ("Select text including enclosing quotes and previous space") (evil-test-buffer "This is 'a [t]est'. For quote objects." ("va'") "This is< 'a test[']>. For quote objects.")) (ert-info ("Select text on opening quote") (evil-test-buffer "This is [\"]a test\". For \"quote\" objects." (emacs-lisp-mode) ("va\"") "This is< \"a test[\"]>. For \"quote\" objects.")) (ert-info ("Select text on closing quote") (evil-test-buffer "This is \"a test[\"]. For \"quote\" objects." (emacs-lisp-mode) ("va\"") "This is< \"a test[\"]>. For \"quote\" objects.")) (ert-info ("Delete text from outside") (evil-test-buffer "Th[i]s is \"a test\". For \"quote\" objects." (emacs-lisp-mode) ("da\"") "This is[.] For \"quote\" objects.")) (ert-info ("Operator on empty quotes") (evil-test-buffer "This is [a]n \"\" empty quote" (emacs-lisp-mode) ("ci\"XXX" [escape]) "This is an \"XX[X]\" empty quote"))) (ert-deftest evil-test-paren-objects () "Test `evil-inner-paren', etc." :tags '(evil text-object) (ert-info ("Select inner text") (evil-test-buffer "[(]aaa)" (emacs-lisp-mode) ; syntax ("vi(") "()") (evil-test-buffer "(aaa[)]" (emacs-lisp-mode) ("vi(") "()") (ert-info ("Next to outer delimiter") (evil-test-buffer "([(]aaa))" (emacs-lisp-mode) ("vi(") "(())") (evil-test-buffer "((aaa[)])" (emacs-lisp-mode) ("vi(") "(())"))) (ert-info ("Select double inner parentheses") (evil-test-buffer "([(]word))" ("dib") "(())") (evil-test-buffer "[(](word))" ("dib") "()") (evil-test-buffer "((word[)])" ("dib") "(())") (evil-test-buffer "((word)[)]" ("dib") "()")) (ert-info ("Select double outer parentheses") (evil-test-buffer "a([(]word))b" ("dab") "a()b") (evil-test-buffer "a[(](word))b" ("dab") "ab") (evil-test-buffer "a((word[)])b" ("dab") "a()b") (evil-test-buffer "a((word)[)]b" ("dab") "ab")) (ert-info ("Select parentheses inside strings") (evil-test-buffer "(aaa \"b(b[b]b)\" aa)" (emacs-lisp-mode) ("va(") "(aaa \"b<(bbb[)]>\" aa)")) (ert-info ("Break out of empty strings") (evil-test-buffer "(aaa \"bb[b]b\" aa)" (emacs-lisp-mode) ("va(") "<(aaa \"bbbb\" aa[)]>")) (ert-info ("Select inner parentheses around strings") (evil-test-buffer "((\"t[e]st\"))\n" (emacs-lisp-mode) ("vib") "((<\"test[\"]>))\n" ("ib") "(<(\"test\"[)]>)\n") (evil-test-buffer "( ( \"t[e]st\" ) )\n" (emacs-lisp-mode) ("vib") "( (< \"test\"[ ]>) )\n" ("ib") "(< ( \"test\" )[ ]>)\n") (evil-test-buffer "((\"t[e]st\"))\n" (emacs-lisp-mode) ("vhhib") "((<[\"]test\">))\n" ("ib") "(<[(]\"test\")>)\n") (evil-test-buffer "( ( \"t[e]st\" ) )\n" (emacs-lisp-mode) ("vhhib") "( (<[ ]\"test\" >) )\n" ("ib") "(<[ ]( \"test\" ) >)\n")) (ert-info ("Select outer parentheses around strings") (evil-test-buffer "((\"t[e]st\"))\n" (emacs-lisp-mode) ("vab") "(<(\"test\"[)]>)\n" ("ab") "<((\"test\")[)]>\n") (evil-test-buffer "( ( \"t[e]st\" ) )\n" (emacs-lisp-mode) ("vab") "( <( \"test\" [)]> )\n" ("ab") "<( ( \"test\" ) [)]>\n") (evil-test-buffer "((\"t[e]st\"))\n" (emacs-lisp-mode) ("vhhab") "(<[(]\"test\")>)\n" ("ab") "<[(](\"test\"))>\n") (evil-test-buffer "( ( \"t[e]st\" ) )\n" (emacs-lisp-mode) ("vhhab") "( <[(] \"test\" )> )\n" ("ab") "<[(] ( \"test\" ) )>\n") (evil-test-buffer "(([\"]\"))\n" ("dab") "([)]\n")) (ert-info ("Select inner paren on different lines") (evil-test-buffer "for (auto i : vector) { if (cond) { do_[s]omething(); } }" ("vi}") "for (auto i : vector) { if (cond) { < do_something();[\n]> }\n}" ("i}") "for (auto i : vector) { < if (cond) { do_something(); }[\n]>}")) (ert-info ("Enlarge to smallest complete surrounding") (evil-test-buffer "for (auto i : vector) { if (comething(); } }" ("i}") "for (auto i : vector) { < if (cond) { do_something(); }[\n]>}")) (ert-info ("yank on blocks is turned linewise") (evil-test-buffer "{\n [f]oo();\n}\n" ("yiBp") "{\n foo();\n [f]oo();\n}\n")) (ert-info ("exclusive like if ending at bol") (evil-test-buffer "(defun foo ()\n[ ] (insert \"bar\")\n )\n" ("cibx" [escape]) "([x]\n )\n")) (ert-info ("Operator on empty parentheses") (evil-test-buffer "a([(]))b" ("cibx" [escape]) "a(([x]))b") (evil-test-buffer "a(([)])b" ("cibx" [escape]) "a(([x]))b"))) (ert-deftest evil-test-forces-linewise-text-objects () "Test `evil-text-object-change-visual-type' option." :tags '(evil text-object) (let ((evil-text-object-change-visual-type t)) (ert-info ("Change visual type") (evil-test-buffer " function(opts) { this.var1 = something(); [t]his.var2 = something_else(); return something_nasty(); } " ("Vi}") " function(opts) { < this.var1 = something(); this.var2 = something_else(); return something_nasty();[ ]> } " (should (eq (evil-visual-type) 'inclusive))))) (let ((evil-text-object-change-visual-type nil)) (ert-info ("Change visual type keeping linewise") (evil-test-buffer " function(opts) { this.var1 = something(); [t]his.var2 = something_else(); return something_nasty(); } " ("Vi}") " function(opts) { < this.var1 = something(); this.var2 = something_else(); return something_nasty();\n> } " (should (eq (evil-visual-type) 'line))))) (let ((evil-text-object-change-visual-type nil)) (ert-info ("Linewise outer block") (evil-test-buffer " function(opts) { this.var1 = something(); [t]his.var2 = something_else(); return something_nasty(); } " ("Va}") "< function(opts) { this.var1 = something(); this.var2 = something_else(); return something_nasty(); } >" (should (eq (evil-visual-type) 'line))))) (ert-info ("Forced motion type should change text object type") (evil-test-buffer "for (int i=0; i<10; i++) { if ([c]ond) { do_something(); } }" ("dVi}") "for (int i=0; i<10; i++) { \[}]"))) (ert-deftest evil-test-tag-objects () "Test `evil-inner-tag', etc." :tags '(evil text-object) (ert-info ("Handle nested tags") (evil-test-buffer :visual-start "{" :visual-end "}" "

f[o]o bar

" ("vit") "

{fo[o]} bar

")) (ert-info ("Break out of tags") (evil-test-buffer :visual-start "{" :visual-end "}" "bbbb" ("vit") "{bbb[b]}") (evil-test-buffer :visual-start "{" :visual-end "}" "bbbb" ("vat") "{bbbb]}")) (ert-info ("Handle quoted strings tags") (evil-test-buffer :visual-start "{" :visual-end "}" "
\[ ]

UPDATE

test hello Creative Commons

" ("vit") "
{\n \n

UPDATE

test hello Creative Commons

[\n]}
")) (ert-info ("Handle js arrow fns") (evil-test-buffer :visual-start "«" :visual-end "»" "" ("vit") ""))) ;;; Visual state (defun evil-test-visual-select (selection &optional mark point) "Verify that TYPE is selected correctly" (let ((type (evil-visual-type selection))) (evil-visual-make-selection mark point type) (ert-info ("Activate region unless SELECTION is `block'") (cond ((eq selection 'block) (should (mark t)) (should-not (region-active-p)) (should-not transient-mark-mode)) (t (should (mark)) (should (region-active-p))))) (ert-info ("Refresh Visual markers") (should (= (evil-range-beginning (evil-expand (point) (mark) type)) evil-visual-beginning)) (should (= (evil-range-end (evil-expand (point) (mark) type)) evil-visual-end)) (should (eq (evil-visual-type) type)) (should (eq evil-visual-direction (if (< (point) (mark)) -1 1)))))) (ert-deftest evil-test-visual-refresh () "Test `evil-visual-refresh'" :tags '(evil visual) (evil-test-buffer ";; [T]his buffer is for notes." (evil-visual-refresh nil nil 'inclusive) (should (= evil-visual-beginning 4)) (should (= evil-visual-end 5))) (evil-test-buffer ";; [T]his buffer is for notes." (let ((evil-visual-region-expanded t)) (evil-visual-refresh nil nil 'inclusive) (should (= evil-visual-beginning 4)) (should (= evil-visual-end 4))))) (ert-deftest evil-test-visual-exchange () "Test `exchange-point-and-mark' in Visual character selection" :tags '(evil visual) (evil-test-buffer ";; <[T]his> buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("o") (should (region-active-p)) ";; buffer is for notes you don't want to save, ;; and for Lisp evaluation.")) (ert-deftest evil-test-visual-char () "Test Visual character selection" :tags '(evil visual) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." (evil-test-visual-select 'char) ";; <[T]>his buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("e") ";; buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("o") ";; <[T]his> buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("d") ";; [ ]buffer is for notes you don't want to save, ;; and for Lisp evaluation." ("vV") "<;; [ ]buffer is for notes you don't want to save,\n>\ ;; and for Lisp evaluation.") (ert-info ("Test `evil-want-visual-char-semi-exclusive") (let ((evil-want-visual-char-semi-exclusive t)) (evil-test-buffer "[;]; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; And a third line." ("v") "<[;]>; This buffer is for notes you don't want to save, ;; and for Lisp evaluation. ;; And a third line." ("$") "<;; This buffer is for notes you don't want to save,>[ ];; and for Lisp evaluation. ;; And a third line." ("^jj") "<;; This buffer is for notes you don't want to save, ;; and for Lisp evaluation.\n>[;]; And a third line.")))) (ert-deftest evil-test-visual-line () "Test Visual line selection" :tags '(evil visual) (evil-test-buffer ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." (evil-test-visual-select 'line) "<;; [T]his buffer is for notes you don't want to save,\n>\ ;; and for Lisp evaluation." ("e") "<;; Thi[s] buffer is for notes you don't want to save,\n>\ ;; and for Lisp evaluation." ("o") "<;; [T]his buffer is for notes you don't want to save,\n>\ ;; and for Lisp evaluation." ("d") ";; [a]nd for Lisp evaluation.")) (ert-deftest evil-test-visual-block () "Test Visual block selection" :tags '(evil visual) (evil-test-buffer "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." (evil-test-visual-select 'block) "<[;]>; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("jjll") "<;; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;;[ ]>then enter the text in that file's own buffer." ("O") ";; [;]; then enter the text in that file's own buffer." ("o") ";;[ ];; then enter the text in that file's own buffer." ("O") "<[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; >then enter the text in that file's own buffer." ("d") "This buffer is for notes you don't want to save. If you want to create a file, visit that file with C-x C-f, then enter the text in that file's own buffer.") (ert-info ("Visual block can select over lines of different length") (evil-test-buffer "Short [l]ine A much longer line A medium line Tiny ln" ("\C-v$jd") "Short[ ] A much A medium line Tiny ln" ("jj\C-v" [end] "jd") "Short A much A me[d] Tiny "))) (ert-deftest evil-test-visual-restore () "Test restoring a previous selection" :tags '(evil visual) (ert-info ("Start a characterwise selection \ if no previous selection") (evil-test-buffer ";; [T]his buffer is for notes." ("gv") ";; <[T]>his buffer is for notes.")) (ert-info ("Restore characterwise selection") (evil-test-buffer ";; <[T]his> buffer is for notes." ([escape] "gv") ";; <[T]his> buffer is for notes.")) (ert-info ("Restore linewise selection") (evil-test-buffer :visual line "<;; [T]his buffer is for notes.>" ([escape] "gv") "<;; [T]his buffer is for notes.>")) (ert-info ("Restore blockwise selection") (evil-test-buffer :visual block "<;; This buffer is for notes, ;;[ ]>and for Lisp evaluation." ([escape] "gv") "<;; This buffer is for notes, ;;[ ]>and for Lisp evaluation.") (ert-info ("After paste shifts initially selected text") (evil-test-buffer :visual block "<1\n2\n[3]>" ("yP") "[1]1\n22\n33" ("gvr*") "[*]1\n*2\n*3"))) (ert-info ("Restore linewise visually-pasted selection") (evil-test-buffer "[a]lpha bravo\ncharlie delta echo foxtrot\ngolf hotel" ("2yy" "++" "Vp" "gv") "alpha bravo\ncharlie delta golf hotel"))) ;;; Replace state (ert-deftest evil-test-replacement () "Test replacing consecutive characters" :tags '(evil replace) (ert-info ("Replace and restore consecutive characters") (evil-test-buffer ";; [T]his buffer is for notes" ("Rfoo") ";; foo[s] buffer is for notes" ([backspace backspace backspace]) ";; [T]his buffer is for notes")) (ert-info ("Replace and restore consecutive characters beyond eol") (evil-test-buffer ";; [T]his buffer is for notes" ("wwwwRxxxxxxx") ";; This buffer is for xxxxxxx[]" ([backspace backspace backspace backspace backspace backspace backspace]) ";; This buffer is for [n]otes")) (ert-info ("Replace from line below and restore") (define-key evil-replace-state-map (kbd "C-e") 'evil-copy-from-below) (evil-test-buffer ";; [f]oo bar\n;; qux quux" ("R\C-e\C-e\C-e") ";; qux[ ]bar\n;; qux quux" ([backspace backspace backspace]) ";; [f]oo bar\n;; qux quux") (define-key evil-replace-state-map (kbd "C-e") nil)) (ert-info ("Replace from line above and restore") (define-key evil-replace-state-map (kbd "C-y") 'evil-copy-from-above) (evil-test-buffer ";; foo bar\n;; [q]ux quux" ("R\C-y\C-y\C-y") ";; foo bar\n;; foo[ ]quux" ([backspace backspace backspace]) ";; foo bar\n;; [q]ux quux") (define-key evil-replace-state-map (kbd "C-y") nil))) ;;; Ex (ert-deftest evil-test-ex-parse () "Test `evil-ex-parse'" :tags '(evil ex) (should (equal (evil-ex-parse "5,2cmd arg") '(evil-ex-call-command (evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line (string-to-number "2") nil)) "cmd" "arg"))) (should (equal (evil-ex-parse "5,2cmd !arg") '(evil-ex-call-command (evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line (string-to-number "2") nil)) "cmd" "!arg"))) (should (equal (evil-ex-parse "5,2 arg") '(evil-ex-call-command (evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line (string-to-number "2") nil)) "arg" nil))) (should (equal (evil-ex-parse "+1,+2t-1") '(evil-ex-call-command (evil-ex-range (evil-ex-line nil (+ (evil-ex-signed-number (intern "+") (string-to-number "1")))) (evil-ex-line nil (+ (evil-ex-signed-number (intern "+") (string-to-number "2"))))) "t" "-1")))) (ert-deftest evil-test-ex-parse-ranges () "Test parsing of ranges" :tags '(evil ex) (should (equal (evil-ex-parse "%" nil 'range) '(evil-ex-full-range))) (should (equal (evil-ex-parse "*" nil 'range) '(evil-ex-last-visual-range))) (should (equal (evil-ex-parse "5,27" nil 'range) '(evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line (string-to-number "27") nil)))) (should (equal (evil-ex-parse "5,$" nil 'range) '(evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line (evil-ex-last-line) nil)))) (should (equal (evil-ex-parse "5,'x" nil 'range) '(evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line (evil-ex-marker "x") nil)))) (should (equal (evil-ex-parse "`x,`y" nil 'range) '(evil-ex-char-marker-range "x" "y"))) (should (equal (evil-ex-parse "`[,`]" nil 'range) '(evil-ex-char-marker-range "[" "]"))) (should (equal (evil-ex-parse "5,+" nil 'range) '(evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line nil (+ (evil-ex-signed-number (intern "+") nil)))))) (should (equal (evil-ex-parse "5,-" nil 'range) '(evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line nil (+ (evil-ex-signed-number (intern "-") nil)))))) (should (equal (evil-ex-parse "5,4+2-7-3+10-" nil 'range) '(evil-ex-range (evil-ex-line (string-to-number "5") nil) (evil-ex-line (string-to-number "4") (+ (evil-ex-signed-number (intern "+") (string-to-number "2")) (evil-ex-signed-number (intern "-") (string-to-number "7")) (evil-ex-signed-number (intern "-") (string-to-number "3")) (evil-ex-signed-number (intern "+") (string-to-number "10")) (evil-ex-signed-number (intern "-") nil)))))) (should (equal (evil-ex-parse ".-2,4+2-7-3+10-" nil 'range) '(evil-ex-range (evil-ex-line (evil-ex-current-line) (+ (evil-ex-signed-number (intern "-") (string-to-number "2")))) (evil-ex-line (string-to-number "4") (+ (evil-ex-signed-number (intern "+") (string-to-number "2")) (evil-ex-signed-number (intern "-") (string-to-number "7")) (evil-ex-signed-number (intern "-") (string-to-number "3")) (evil-ex-signed-number (intern "+") (string-to-number "10")) (evil-ex-signed-number (intern "-") nil)))))) (should (equal (evil-ex-parse "'a-2,$-10" nil 'range) '(evil-ex-range (evil-ex-line (evil-ex-marker "a") (+ (evil-ex-signed-number (intern "-") (string-to-number "2")))) (evil-ex-line (evil-ex-last-line) (+ (evil-ex-signed-number (intern "-") (string-to-number "10"))))))) (should (equal (evil-ex-parse "'[,']" nil 'range) '(evil-ex-range (evil-ex-line (evil-ex-marker "[") nil) (evil-ex-line (evil-ex-marker "]") nil)))) (should (equal (evil-ex-parse "'{,'}" nil 'range) '(evil-ex-range (evil-ex-line (evil-ex-marker "{") nil) (evil-ex-line (evil-ex-marker "}") nil)))) (should (equal (evil-ex-parse "'(,')" nil 'range) '(evil-ex-range (evil-ex-line (evil-ex-marker "(") nil) (evil-ex-line (evil-ex-marker ")") nil)))) (should (equal (evil-ex-parse ",']" nil 'range) '(evil-ex-range (evil-ex-current-line) (evil-ex-line (evil-ex-marker "]") nil)))) (should (equal (evil-ex-parse ";']" nil 'range) '(evil-ex-range (evil-ex-current-line) (evil-ex-line (evil-ex-marker "]") nil)))) (should (equal (evil-ex-parse ".+42" nil 'range) '(evil-ex-range (evil-ex-line (evil-ex-current-line) (+ (evil-ex-signed-number (intern "+") (string-to-number "42")))) nil)))) (ert-deftest evil-test-ex-parse-emacs-commands () "Test parsing of Emacs commands" :tags '(evil ex) (should (equal (evil-ex-parse "ido-mode") '(evil-ex-call-command nil "ido-mode" nil))) (should (equal (evil-ex-parse "yas/reload-all") '(evil-ex-call-command nil "yas/reload-all" nil))) (should (equal (evil-ex-parse "mu4e") '(evil-ex-call-command nil "mu4e" nil))) (should (equal (evil-ex-parse "make-frame") '(evil-ex-call-command nil "make-frame" nil)))) (ert-deftest evil-text-ex-search-offset () "Test for addresses like /base//pattern/" :tags '(evil ex) (ert-info ("without base") (evil-test-buffer "[l]ine 1\naaa\nbbb\naaa\nccc\nddd" (":/aaa/d") "line 1\nbbb\naaa\nccc\nddd")) (ert-info ("with base") (evil-test-buffer "[l]ine 1\naaa\nbbb\naaa\nccc\nddd" (":/bbb//aaa/d") "line 1\naaa\nbbb\nccc\nddd")) (ert-info ("range without base") (evil-test-buffer "[l]ine 1\naaa\nbbb\naaa\nccc\nddd\nccc\neee\n" (":/aaa/;/ccc/d") "line 1\nddd\nccc\neee\n")) (ert-info ("range with base") (evil-test-buffer "[l]ine 1\naaa\nbbb\naaa\nccc\nddd\nccc\neee\n" (":/bbb//aaa/;/ddd//ccc/d") "line 1\naaa\nbbb\neee\n"))) (ert-deftest evil-test-ex-goto-line () "Test if :number moves point to a certain line" :tags '(evil ex) (ert-info ("Move to line") (let ((evil-start-of-line t)) (evil-test-buffer :visual line "1\n 2\n [ ]3\n 4\n 5\n" (":4" [return]) "1\n 2\n 3\n [4]\n 5\n" (":2" [return]) "1\n [2]\n 3\n 4\n 5\n")))) (ert-deftest evil-test-ex-repeat () "Test :@: command." :tags '(evil ex) (evil-without-display (ert-info ("Repeat in current line") (evil-test-buffer "[a]bcdef\nabcdef\nabcdef" (":s/[be]/X/g" [return]) "[a]XcdXf\nabcdef\nabcdef" ("jj:@:" [return]) "aXcdXf\nabcdef\n[a]XcdXf")) (ert-info ("Repeat in specified line") (evil-test-buffer "[a]bcdef\nabcdef\nabcdef" (":s/[be]/X/g" [return]) "[a]XcdXf\nabcdef\nabcdef" (":3@:" [return]) "aXcdXf\nabcdef\n[a]XcdXf")) (ert-info ("Double repeat, first without then with specified line") (evil-test-buffer "[a]bcdef\nabcdef\nabcdef" (":s/[be]/X/" [return]) "[a]Xcdef\nabcdef\nabcdef" ("jj:@:" [return] ":1@:" [return]) "[a]XcdXf\nabcdef\naXcdef")))) (ert-deftest evil-test-ex-repeat2 () "Test @: command." :tags '(evil ex) (evil-without-display (ert-info ("Repeat in current line") (evil-test-buffer "[a]bcdef\nabcdef\nabcdef" (":s/[be]/X" [return]) "[a]Xcdef\nabcdef\nabcdef" ("jj@:") "aXcdef\nabcdef\n[a]Xcdef")) (ert-info ("Repeat with count in current line") (evil-test-buffer "[a]bcdef\nabcdef\nabcdef" (":s/[be]/X" [return]) "[a]Xcdef\nabcdef\nabcdef" ("jj2@:") "aXcdef\nabcdef\n[a]XcdXf")) (ert-info ("Do not record dot repeat") (evil-test-buffer "" ("OAAAAAA" [escape] "^") "[A]AAAAA\n" (":s/A/X" [return]) "[X]AAAAA\n" ("@:") "[X]XAAAA\n" (".") "AAAAAA\nXXAAAA\n")))) (ert-deftest evil-test-ex-visual-char-range () "Test visual character ranges in ex state." :tags '(evil ex visual) (evil-without-display (ert-info ("No character range, inclusive") (let ((evil-visual-char 'inclusive) evil-ex-visual-char-range) (evil-test-buffer "li[n]e 1\nline 2\nline 3\nline 4\n" ("vjll:d" [return]) "line 3\nline 4\n"))) (ert-info ("No character range, exclusive") (let ((evil-visual-char 'inclusive) evil-ex-visual-char-range) (evil-test-buffer "li[n]e 1\nline 2\nline 3\nline 4\n" ("vjll:d" [return]) "line 3\nline 4\n"))) (ert-info ("Character range, inclusive") (let ((evil-visual-char 'inclusive) (evil-ex-visual-char-range t)) (evil-test-buffer "li[n]e 1\nline 2\nline 3\nline 4\n" ("vjll:d" [return]) "li2\nline 3\nline 4\n"))) (ert-info ("Character range, exclusive") (let ((evil-visual-char 'exclusive) (evil-ex-visual-char-range t)) (evil-test-buffer "li[n]e 1\nline 2\nline 3\nline 4\n" ("vjll:d" [return]) "li 2\nline 3\nline 4\n"))))) (ert-deftest evil-test-ex-substitute-replacement () "Test `evil-ex-substitute' with special replacements." :tags '(evil ex search) (ert-info ("Substitute upper first on first match in line") (evil-test-buffer "[x]xx foo bar foo bar foo bar" (":s/\\(foo\\|bar\\)/\\u\\1" [return]) "[x]xx Foo bar foo bar foo bar")) (ert-info ("Substitute upper first on first match in line with confirm") (evil-test-buffer "[x]xx foo bar foo bar foo bar" (":s/\\(foo\\|bar\\)/\\u\\1/c" [return] "y") "[x]xx Foo bar foo bar foo bar")) (ert-info ("Substitute upper first on whole line") (evil-test-buffer "[x]xx foo bar foo bar foo bar" (":s/\\(foo\\|bar\\)/\\u\\1/g" [return]) "[x]xx Foo Bar Foo Bar Foo Bar")) (ert-info ("Substitute upper first on whole line") (evil-test-buffer "[x]xx foo bar foo bar foo bar" (":s/\\(foo\\|bar\\)/\\u\\1/gc" [return] "yynyyn") "[x]xx Foo Bar foo Bar Foo bar")) (ert-info ("Substitute upper/lower on first match in line") (evil-test-buffer "[x]xx foo BAR foo BAR foo BAR" (":s/\\(f[[:alpha:]]*\\>\\)\\s-*\\(b[[:alpha:]]*\\>\\)/\\L\\2_\\e\\U\\1" [return]) "[x]xx bar_FOO foo BAR foo BAR")) (ert-info ("Substitute upper/lower on first match in line with confirm") (evil-test-buffer "[x]xx foo BAR foo BAR foo BAR" (":s/\\(f[[:alpha:]]*\\>\\)\\s-*\\(b[[:alpha:]]*\\>\\)/\\L\\2_\\e\\U\\1/c" [return] "y") "[x]xx bar_FOO foo BAR foo BAR")) (ert-info ("Substitute upper/lower on whole line") (evil-test-buffer "[x]xx foo BAR foo BAR foo BAR" (":s/\\(f[[:alpha:]]*\\>\\)\\s-*\\(b[[:alpha:]]*\\>\\)/\\L\\2_\\e\\U\\1/g" [return]) "[x]xx bar_FOO bar_FOO bar_FOO")) (ert-info ("Substitute upper/lower on whole line") (evil-test-buffer "[x]xx foo BAR foo BAR foo BAR" (":s/\\(f[[:alpha:]]*\\>\\)\\s-*\\(b[[:alpha:]]*\\>\\)/\\L\\2_\\e\\U\\1/gc" [return] "yny") "[x]xx bar_FOO foo BAR bar_FOO")) (ert-info ("Substitute with escaped characters in replacement") (evil-test-buffer "[a]bcXdefXghiXjkl\n" (":s/X/\\|\\/\\|/g" [return]) "[a]bc|/|def|/|ghi|/|jkl\n")) (ert-info ("Substitute with register") (evil-test-buffer "[a]bc\niiiXiiiXiiiXiii\n" ("\"ayiwj:s/X/\\=@a/g" [return]) "abc\n[i]iiabciiiabciiiabciii\n")) (ert-info ("Substitute newlines") (evil-test-buffer "[a]bc\ndef\nghi\n" (":%s/\n/z/" [return]) "[a]bczdefzghiz")) (ert-info ("Substitute newlines with g flag") (evil-test-buffer "[a]bc\ndef\nghi\n" (":%s/\n/z/g" [return]) "[a]bczdefzghiz")) (ert-info ("Substitute newlines without newline in regexp") (evil-test-buffer "[A]BC\nDEF\nGHI\n" (":%s/[^]]*/z/" [return]) "Z")) (ert-info ("Substitute n flag does not replace") (evil-test-buffer "[a]bc\naef\nahi\n" (":%s/a//n" [return]) "[a]bc\naef\nahi\n")) (ert-info ("Substitute n flag does not replace with g flag") (evil-test-buffer "[a]bc\naef\nahi\n" (":%s/a//gn" [return]) "[a]bc\naef\nahi\n")) (ert-info ("Substitute $ does not loop infinitely") (evil-test-buffer "[a]bc\ndef\nghi" (":%s/$/ END/g" [return]) "abc END\ndef END\n[g]hi END")) (ert-info ("Substitute the zero-length beginning of line character") (evil-test-buffer "[a]bc\ndef\nghi" (":s/^/ #/" [return]) " [#]abc\ndef\nghi")) (ert-info ("Substitute the zero-length beginning of line character with g flag") (evil-test-buffer "[a]bc\ndef\nghi" (":s/^/ #/g" [return]) " [#]abc\ndef\nghi")) (ert-info ("Use Substitute to delete individual characters") (evil-test-buffer "[x]xyxxz" (":%s/x//g" [return]) "[y]z")) (ert-info ("Substitute doesn't match final empty line") (evil-test-buffer "abc\n[d]ef\n\nghi" (":s/$/4") "abc\n[d]ef4\n\nghi") (evil-test-buffer "abc\n[d]ef\n\nghi" (":s/f\\w*/4") "abc\n[d]e4\n\nghi"))) (ert-deftest evil-test-ex-repeat-substitute-replacement () "Test `evil-ex-substitute' with repeating of previous substitutions." :tags '(evil ex search) (ert-info ("Repeat previous pattern") (evil-select-search-module 'evil-search-module 'evil-search) (evil-test-buffer "[x]xx foo bar foo bar foo bar" (":s/foo/AAA" [return]) "[x]xx AAA bar foo bar foo bar" (":s//BBB" [return]) "[x]xx AAA bar BBB bar foo bar" ("/bar" [return] ":s//CCC" [return]) "[x]xx AAA CCC BBB bar foo bar" (":s/ar/XX" [return]) "[x]xx AAA CCC BBB bXX foo bar" (":s//YY" [return]) "[x]xx AAA CCC BBB bXX foo bYY")) (ert-info ("Repeat previous replacement") (evil-test-buffer "[x]xx foo bar foo bar foo bar" (":s/foo/AAA" [return]) "[x]xx AAA bar foo bar foo bar" (":s/bar/~" [return]) "[x]xx AAA AAA foo bar foo bar")) (ert-info ("Repeat with previous flags") (evil-test-buffer "[x]xx foo bar foo bar foo bar" (":s/foo/AAA/g" [return]) "[x]xx AAA bar AAA bar AAA bar" (":s/bar/BBB/&" [return]) "[x]xx AAA BBB AAA BBB AAA BBB")) (ert-info ("Repeat previous substitute without flags") (evil-select-search-module 'evil-search-module 'evil-search) (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA/g" [return]) "[x]xx AAA bar AAA bar AAA bar\nxxx foo bar foo bar foo bar" ("j:s" [return]) "xxx AAA bar AAA bar AAA bar\n[x]xx AAA bar foo bar foo bar" ("/bar" [return] ":s" [return]) "xxx AAA bar AAA bar AAA bar\n[x]xx AAA bar AAA bar foo bar") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA/g" [return]) "[x]xx AAA bar AAA bar AAA bar\nxxx foo bar foo bar foo bar" ("j&") "xxx AAA bar AAA bar AAA bar\n[x]xx AAA bar foo bar foo bar") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA/g" [return]) "[x]xx AAA bar AAA bar AAA bar\nxxx foo bar foo bar foo bar" ("j:&" [return]) "xxx AAA bar AAA bar AAA bar\n[x]xx AAA bar foo bar foo bar")) (ert-info ("Repeat previous substitute with the same flags") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA/g" [return]) "[x]xx AAA bar AAA bar AAA bar\nxxx foo bar foo bar foo bar" ("j:s//~/&" [return]) "xxx AAA bar AAA bar AAA bar\n[x]xx AAA bar AAA bar AAA bar") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA/g" [return]) "[x]xx AAA bar AAA bar AAA bar\nxxx foo bar foo bar foo bar" ("j:&&" [return]) "xxx AAA bar AAA bar AAA bar\n[x]xx AAA bar AAA bar AAA bar")) (ert-info ("Repeat previous substitute with new flags") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA" [return]) "[x]xx AAA bar foo bar foo bar\nxxx foo bar foo bar foo bar" ("j:s g" [return]) "xxx AAA bar foo bar foo bar\n[x]xx AAA bar AAA bar AAA bar") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA" [return]) "[x]xx AAA bar foo bar foo bar\nxxx foo bar foo bar foo bar" ("j:& g" [return]) "xxx AAA bar foo bar foo bar\n[x]xx AAA bar AAA bar AAA bar")) (ert-info ("Repeat with previous search pattern") (evil-select-search-module 'evil-search-module 'evil-search) (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA" [return]) "[x]xx AAA bar foo bar foo bar\nxxx foo bar foo bar foo bar" ("/bar" [return]) "xxx AAA [b]ar foo bar foo bar\nxxx foo bar foo bar foo bar" (":2s rg" [return]) "xxx AAA bar foo bar foo bar\n[x]xx foo AAA foo AAA foo AAA") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA" [return]) "[x]xx AAA bar foo bar foo bar\nxxx foo bar foo bar foo bar" ("/bar" [return]) "xxx AAA [b]ar foo bar foo bar\nxxx foo bar foo bar foo bar" (":2~ g" [return]) "xxx AAA bar foo bar foo bar\n[x]xx foo AAA foo AAA foo AAA")) (ert-info ("Repeat previous substitute globally") (evil-test-buffer "[x]xx foo bar foo bar foo bar\nxxx foo bar foo bar foo bar" (":s/foo/AAA/g" [return]) "[x]xx AAA bar AAA bar AAA bar\nxxx foo bar foo bar foo bar" ("g&") "xxx AAA bar AAA bar AAA bar\n[x]xx AAA bar AAA bar AAA bar"))) (ert-deftest evil-test-ex-regex-without-case () "Test `evil-ex-regex-without-case'" :tags '(evil ex search) (should (equal (evil-ex-regex-without-case "cdeCDE") "cdeCDE")) (should (equal (evil-ex-regex-without-case "\\ccde\\CCDE") "cdeCDE")) (should (equal (evil-ex-regex-without-case "\\\\ccde\\\\CCDE") "\\\\ccde\\\\CCDE")) (should (equal (evil-ex-regex-without-case "\\\\\\ccde\\\\\\CCDE") "\\\\cde\\\\CDE"))) (ert-deftest evil-test-ex-regex-case () "Test `evil-ex-regex-case'" :tags '(evil ex search) (should (equal (evil-ex-regex-case "cde" 'smart) 'insensitive)) (should (equal (evil-ex-regex-case "cDe" 'smart) 'sensitive)) (should (equal (evil-ex-regex-case "cde" 'sensitive) 'sensitive)) (should (equal (evil-ex-regex-case "cde" 'insensitive) 'insensitive)) (should (equal (evil-ex-regex-case "\\ccde" 'smart) 'insensitive)) (should (equal (evil-ex-regex-case "\\cCde" 'smart) 'insensitive)) (should (equal (evil-ex-regex-case "\\Ccde" 'smart) 'sensitive)) (should (equal (evil-ex-regex-case "\\CCde" 'smart) 'sensitive)) (should (equal (evil-ex-regex-case "\\ccd\\Ce" 'smart) 'insensitive)) (should (equal (evil-ex-regex-case "\\cCd\\Ce" 'smart) 'insensitive)) (should (equal (evil-ex-regex-case "\\Ccd\\ce" 'smart) 'sensitive)) (should (equal (evil-ex-regex-case "\\CCd\\ce" 'smart) 'sensitive))) (ert-deftest evil-test-ex-search () "Test evil internal search." :tags '(evil ex search) (evil-without-display (evil-select-search-module 'evil-search-module 'evil-search) (ert-info ("Test smart case insensitive") (evil-test-buffer "[s]tart you YOU You you YOU You" ("/you" [return]) "start [y]ou YOU You you YOU You" ("n") "start you [Y]OU You you YOU You" ("n") "start you YOU [Y]ou you YOU You" ("n") "start you YOU You [y]ou YOU You")) (ert-info ("Test smart case sensitive") (evil-test-buffer "[s]tart you YOU You you YOU You" ("/You" [return]) "start you YOU [Y]ou you YOU You" ("n") "start you YOU You you YOU [Y]ou")) (ert-info ("Test insensitive") (evil-test-buffer "[s]tart you YOU You you YOU You" ("/\\cyou" [return]) "start [y]ou YOU You you YOU You" ("n") "start you [Y]OU You you YOU You" ("n") "start you YOU [Y]ou you YOU You" ("n") "start you YOU You [y]ou YOU You")) (ert-info ("Test sensitive") (evil-test-buffer "[s]tart you YOU You you YOU You" ("/\\Cyou" [return]) "start [y]ou YOU You you YOU You" ("n") "start you YOU You [y]ou YOU You")) (ert-info ("Test failing search does not move point") (evil-test-buffer "foo [f]oo foo\nbar bar2 bar\nbaz baz baz\n" (error search-failed "/foofoo" [return]) "foo [f]oo foo\nbar bar2 bar\nbaz baz baz\n" ("/bar2" [return]) "foo foo foo\nbar [b]ar2 bar\nbaz baz baz\n" ("dw") "foo foo foo\nbar [b]ar\nbaz baz baz\n" (error search-failed "n") "foo foo foo\nbar [b]ar\nbaz baz baz\n" (error search-failed "N") "foo foo foo\nbar [b]ar\nbaz baz baz\n")) (ert-info ("Test search for newline") (evil-test-buffer "[s]tart\nline 2\nline 3\n\n" ("/\\n" [return]) "star[t]\nline 2\nline 3\n\n" ("n") "start\nline [2]\nline 3\n\n" ("n") "start\nline 2\nline [3]\n\n" ("n") "start\nline 2\nline 3\n[]\n")) (ert-info ("Can paste from register in ex-search") (evil-test-buffer "Alpha [b]ravo charlie alpha bravo delta bravo delta" ("\"bye" "w") "Alpha bravo [c]harlie alpha bravo delta bravo delta" ("/\C-rb" [return]) "Alpha bravo charlie alpha [b]ravo delta bravo delta" ("w/\C-r\C-o" [return]) "Alpha bravo charlie alpha bravo delta bravo [d]elta")))) (ert-deftest evil-test-ex-search-offset () "Test search offsets." :tags '(evil ex search) (evil-without-display (evil-select-search-module 'evil-search-module 'evil-search) (ert-info ("Test line offsets") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar/2") "foo foo\nbar bar\nbaz baz\n[A]nother line\nAnd yet another line" ("?bar?-") "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/r bar/") "foo foo\nba[r] bar\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Test end offsets") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar/e") "foo foo\nba[r] bar\nbaz baz\nAnother line\nAnd yet another line" ("/baz/e+2") "foo foo\nbar bar\nbaz [b]az\nAnother line\nAnd yet another line" ("/line/e-1") "foo foo\nbar bar\nbaz baz\nAnother li[n]e\nAnd yet another line")) (ert-info ("Test begin offsets") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar/b") "foo foo\n[b]ar bar\nbaz baz\nAnother line\nAnd yet another line" ("/baz/b+2") "foo foo\nbar bar\nba[z] baz\nAnother line\nAnd yet another line" ("/line/b-") "foo foo\nbar bar\nbaz baz\nAnother[ ]line\nAnd yet another line")) (ert-info ("Test search-next with offset") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/ ba/+1" [return]) "foo foo\nbar bar\n[b]az baz\nAnother line\nAnd yet another line" ("n") "foo foo\nbar bar\nbaz baz\n[A]nother line\nAnd yet another line")) (ert-info ("Test search next after /$") (evil-test-buffer "[l]ine 1\nline 2\n\n\line 4\n" ("/$" [return]) "line [1]\nline 2\n\n\line 4\n" ("n") "line 1\nline [2]\n\n\line 4\n" ("n") "line 1\nline 2\n[\n]\line 4\n" ("n") "line 1\nline 2\n\n\line [4]\n")))) (ert-deftest evil-test-ex-search-pattern-offset () "Test pattern offsets." :tags '(evil ex search) (evil-without-display (evil-select-search-module 'evil-search-module 'evil-search) (ert-info ("Test simple pattern offsets") (evil-test-buffer "[f]oo foo\nbar bar\nfoo foo\nbaz baz\nAnother line\nAnd yet another line" ("/bar/;/foo" [return]) "foo foo\nbar bar\n[f]oo foo\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Test simple pattern offsets in backward direction") (evil-test-buffer "[f]oo foo\nbar bar\nfoo foo\nbaz baz\nAnother line\nAnd yet another line" ("/bar/;?foo" [return]) "foo [f]oo\nbar bar\nfoo foo\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Ensure second pattern is used for search repeat") (evil-test-buffer "[f]oo foo\nbar bar\nfoo foo\nbaz baz\nAnother line\nAnd yet another line" ("/bar/;?foo" [return] "n") "foo foo\nbar bar\n[f]oo foo\nbaz baz\nAnother line\nAnd yet another line")))) (ert-deftest evil-test-ex-search-repeat () "Test repeat of search." :tags '(evil ex search) (evil-without-display (evil-select-search-module 'evil-search-module 'evil-search) (ert-info ("Test repeat of simple pattern") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar" [return] "/" [return]) "foo foo\nbar [b]ar\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Test repeat of simple pattern with new offset") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar" [return] "//e" [return]) "foo foo\nbar ba[r]\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Test repeat of pattern with offset") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar/e" [return] "/" [return]) "foo foo\nbar ba[r]\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Test repeat of pattern with offset without offset") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar/e" [return] "//" [return]) "foo foo\nbar [b]ar\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Test repeat of pattern with offset with new offset") (evil-test-buffer "[f]oo foo\nbar bar\nbaz baz\nAnother line\nAnd yet another line" ("/bar/e" [return] "//b+1" [return]) "foo foo\nbar b[a]r\nbaz baz\nAnother line\nAnd yet another line")) (ert-info ("Test repeat of pattern in the same search") (evil-test-buffer "[a]lpha bravo charlie delta charlie alpha bravo alpha" ("/charlie/;/") "alpha bravo charlie delta [c]harlie alpha bravo alpha" ("/alpha/;//") "alpha bravo charlie delta charlie alpha bravo [a]lpha" ("?charlie?;?") "alpha bravo [c]harlie delta charlie alpha bravo alpha") (ert-info ("including when switching direction") (evil-test-buffer "[a]lpha bravo charlie delta charlie alpha bravo alpha" ("/bravo/;?") "alpha bravo charlie delta charlie alpha [b]ravo alpha" ("?alpha?;//") "alpha bravo charlie delta charlie alpha bravo [a]lpha"))))) (ert-deftest evil-test-ex-search-word () "Test search for word under point." :tags '(evil ex search) (evil-without-display (evil-select-search-module 'evil-search-module 'evil-search) (setq evil-ex-search-history nil) (evil-test-buffer "so[m]e text with a strange word and here some other stuff maybe we need one line more with some text\n" (setq evil-symbol-word-search nil) ("*") "some text with a strange word and here [s]ome other stuff maybe we need one line more with some text\n" ("n") "some text with a strange word and here some other stuff maybe we need one line more with [s]ome text\n" (ert-info ("Search history") (should (equal evil-ex-search-history '("\\")))) ("*") "[s]ome text with a strange word and here some other stuff maybe we need one line more with some text\n" (ert-info ("Search history with double pattern") (should (equal evil-ex-search-history '("\\"))))) (ert-info ("Test unbounded search") (evil-select-search-module 'evil-search-module 'evil-search) (setq evil-ex-search-history nil) (evil-test-buffer "[s]ymbol\n(defun my-symbolfunc ())\n(defvar my-symbolvar)\nanother symbol\n" ("*") (setq evil-symbol-word-search nil) "symbol\n(defun my-symbolfunc ())\n(defvar my-symbolvar)\nanother [s]ymbol\n" ("ggg*") "symbol\n(defun my-[s]ymbolfunc ())\n(defvar my-symbolvar)\nanother symbol\n" (should (equal evil-ex-search-history '("symbol" "\\"))) ("n") "symbol\n(defun my-symbolfunc ())\n(defvar my-[s]ymbolvar)\nanother symbol\n")) (ert-info ("Test symbol search") (evil-select-search-module 'evil-search-module 'evil-search) (evil-test-buffer "(defun my-s[y]mbol-func ())\n(defvar my-symbol-var)\n(my-symbol-func)\n(setq my-symbol-func2 (my-symbol-func))\n" (setq evil-symbol-word-search t) ("*") "(defun my-symbol-func ())\n(defvar my-symbol-var)\n([m]y-symbol-func)\n(setq my-symbol-func2 (my-symbol-func))\n" ("n") "(defun my-symbol-func ())\n(defvar my-symbol-var)\n(my-symbol-func)\n(setq my-symbol-func2 ([m]y-symbol-func))\n")) (ert-info ("Test with non-nil `evil-ex-search-vim-style-regexp'") (evil-select-search-module 'evil-search-module 'evil-search) (let ((evil-ex-search-vim-style-regexp t) (evil-magic 'very-magic)) (evil-test-buffer "[a]lpha bravo alpha charlie alpha" ("*") "alpha bravo [a]lpha charlie alpha" ("/" [return]) "alpha bravo alpha charlie [a]lpha"))))) (ert-deftest evil-test-ex-search-motion () :tags '(evil ex search) (evil-without-display (evil-select-search-module 'evil-search-module 'evil-search) (ert-info ("Ex forward search, as a motion, can be repeated") (evil-test-buffer "alpha [b]ravo charlie delta golf hotel charlie india" ("c/charlie" [return] "replacement " [escape] "4w.") "alpha replacement charlie delta golf replacement[ ]charlie india")))) (ert-deftest evil-test-ex-search-next+previous-match () :tags '(evil ex search) (evil-without-display (evil-select-search-module 'evil-search-module 'evil-search) (ert-info ("evil-next-match in normal state") (evil-test-buffer "[b]ravo charlie delta charlie alpha charlie bravo" ("/charlie" [return] "e") "bravo charli[e] delta charlie alpha charlie bravo" ("gn") "bravo delta charlie alpha charlie bravo" ([escape] "b") "bravo [c]harlie delta charlie alpha charlie bravo" ("gn") "bravo delta charlie alpha charlie bravo" ([escape] "w") "bravo charlie [d]elta charlie alpha charlie bravo" ("gn") "bravo charlie delta alpha charlie bravo" ([escape] "^") "[b]ravo charlie delta charlie alpha charlie bravo" ("3gn") "bravo charlie delta charlie alpha bravo")) (ert-info ("evil-previous-match in normal state") (evil-test-buffer "[b]ravo charlie delta charlie alpha charlie bravo" ("/charlie" [return] "e") "bravo charli[e] delta charlie alpha charlie bravo" ("$gN") "bravo charlie delta charlie alpha <[c]harlie> bravo" ([escape] "gN") "bravo charlie delta charlie alpha <[c]harlie> bravo" ([escape] "e" "2gN") "bravo charlie delta <[c]harlie> alpha charlie bravo")) (ert-info ("evil-next-match in visual state") (evil-test-buffer "[b]ravo charlie delta charlie alpha charlie bravo" ("/charlie" [return] "e") "bravo charli[e] delta charlie alpha charlie bravo" ("gn") "bravo delta charlie alpha charlie bravo" ("gn") "bravo alpha charlie bravo" ("o") "bravo <[c]harlie delta charlie> alpha charlie bravo" ("gn") "bravo charli<[e] delta charlie> alpha charlie bravo" ([escape] "^v2gn") " alpha charlie bravo")) (ert-info ("evil-previous-match in visual state") (evil-test-buffer "bravo charlie delta charlie alpha charlie brav[o]" ("?charlie" [return]) "bravo charlie delta charlie alpha [c]harlie bravo" ("gN") "bravo charlie delta charlie alpha <[c]harlie> bravo" ("gN") "bravo charlie delta <[c]harlie alpha charlie> bravo" ("o") "bravo charlie delta bravo" ("gN") "bravo charlie delta harlie bravo" ([escape] "$v2gN") "bravo charlie delta <[c]harlie alpha charlie bravo>")) (ert-info ("evil-match in operator state") (evil-test-buffer "[b]ravo charlie delta charlie alpha charlie bravo" ("/charlie" [return]) "bravo [c]harlie delta charlie alpha charlie bravo" ("cgn" "foo" [escape]) "bravo fo[o] delta charlie alpha charlie bravo" (".") "bravo foo delta fo[o] alpha charlie bravo" ("$cgN" "bar" [escape]) "bravo foo delta foo alpha ba[r] bravo")) (ert-info ("Unfound evil ex next match doesn't move cursor") (evil-test-buffer "[a]lpha bravo" (should-error (execute-kbd-macro "/zulu")) "[a]lpha bravo" (should-error (execute-kbd-macro "gn")) "[a]lpha bravo")))) (ert-deftest evil-test-isearch-word () "Test isearch for word under point." :tags '(evil isearch) (evil-without-display (evil-select-search-module 'evil-search-module 'isearch) (evil-test-buffer "so[m]e text with a strange word and here some other stuff maybe we need one line more with some text\n" (setq evil-symbol-word-search nil) ("*") "some text with a strange word and here [s]ome other stuff maybe we need one line more with some text\n" ("n") "some text with a strange word and here some other stuff maybe we need one line more with [s]ome text\n" ("*") "[s]ome text with a strange word and here some other stuff maybe we need one line more with some text\n") (ert-info ("Test unbounded search") (evil-select-search-module 'evil-search-module 'isearch) (evil-test-buffer "[s]ymbol\n(defun my-symbolfunc ())\n(defvar my-symbolvar)\nanother symbol\n" (setq evil-symbol-word-search nil) ("*") "symbol\n(defun my-symbolfunc ())\n(defvar my-symbolvar)\nanother [s]ymbol\n" ("ggg*") "symbol\n(defun my-[s]ymbolfunc ())\n(defvar my-symbolvar)\nanother symbol\n" ("n") "symbol\n(defun my-symbolfunc ())\n(defvar my-[s]ymbolvar)\nanother symbol\n")) (ert-info ("Test symbol search") (evil-select-search-module 'evil-search-module 'isearch) (evil-test-buffer "(defun my-s[y]mbol-func ())\n(defvar my-symbol-var)\n(my-symbol-func)\n(setq my-symbol-func2 (my-symbol-func))\n" (setq evil-symbol-word-search t) ("*") "(defun my-symbol-func ())\n(defvar my-symbol-var)\n([m]y-symbol-func)\n(setq my-symbol-func2 (my-symbol-func))\n" ("n") "(defun my-symbol-func ())\n(defvar my-symbol-var)\n(my-symbol-func)\n(setq my-symbol-func2 ([m]y-symbol-func))\n")))) (ert-deftest evil-test-read () "Test of `evil-read'" :tags '(evil ex) (evil-without-display (ert-info ("Test insertion of file with trailing newline") (evil-with-temp-file name "temp file 1\ntemp file 2\n" (ert-info ("At first line") (evil-test-buffer "[l]ine 1\nline 2" ((vconcat ":read " name [return])) "line 1\n[t]emp file 1\ntemp file 2\nline 2")) (ert-info ("At last line") (evil-test-buffer "line 1\n[l]ine 2" ((vconcat ":read " name [return])) "line 1\nline 2\n[t]emp file 1\ntemp file 2\n")) (ert-info ("After specified line number") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4\line 5" ((vconcat ":3read " name [return])) "line 1\nline 2\nline 3\n[t]emp file 1\ntemp file 2\nline 4\line 5")) (ert-info ("After specified line 0") (evil-test-buffer "line 1\nline [2]\nline 3\nline 4\line 5" ((vconcat ":0read " name [return])) "[t]emp file 1\ntemp file 2\nline 1\nline 2\nline 3\nline 4\line 5")))) (ert-info ("Test insertion of file without trailing newline") (evil-with-temp-file name "temp file 1\ntemp file 2" (evil-test-buffer "[l]ine 1\nline 2" ((vconcat ":read " name [return])) "line 1\n[t]emp file 1\ntemp file 2\nline 2"))) (ert-info ("Test insertion of shell command") (ert-info ("with space") (evil-test-buffer "[l]line 1\nline 2" (":read !echo cmd line 1" [return]) "line 1\n[c]md line 1\nline 2")) (ert-info ("without space") (evil-test-buffer "[l]line 1\nline 2" (":read!echo cmd line 1" [return]) "line 1\n[c]md line 1\nline 2"))) (ert-info ("Test substitution of % in shell commands") (evil-with-temp-file name "3\n2\n1\n" (evil-test-buffer ((vconcat ":e " name [return])) "[3]\n2\n1\n" ((vconcat ":read !echo %" [return])) ((vconcat ":w " [return])) (file name (concat "3\n" (buffer-file-name) "\n" "2\n" "1\n"))))) (ert-info ("Ensure that point ends up at the last line of shell output, if any") (evil-with-temp-file name "3\n2\n1\n" (evil-test-buffer "[l]ine 1\nline 2" ((vconcat ":read !cat " name [return])) "line 1\n3\n2\n[1]\nline 2"))) (ert-info ("Test insertion of shell command without trailing newline") (ert-info ("with space") (evil-test-buffer "[l]line 1\nline 2" (":read !echo -n cmd line 1" [return]) "line 1\n[c]md line 1\nline 2")) (ert-info ("without space") (evil-test-buffer "[l]line 1\nline 2" (":read!echo -n cmd line 1" [return]) "line 1\n[c]md line 1\nline 2"))))) (ert-deftest evil-test-shell-command () "Test `evil-shell-command'." (ert-info ("ex shell command") (evil-test-buffer "[l]ine 5\nline 4\nline 3\nline 2\nline 1\n" (":2,3!sort" [return]) "line 5\n[l]ine 3\nline 4\nline 2\nline 1\n")) (ert-info ("shell command operator with count") (evil-test-buffer "line 5\n[l]ine 4\nline 3\nline 2\nline 1\n" ("2!!sort" [return]) "line 5\n[l]ine 3\nline 4\nline 2\nline 1\n")) (ert-info ("shell command operator with motion") (evil-test-buffer "line 5\n[l]ine 4\nline 3\nline 2\nline 1\n" ("!jsort" [return]) "line 5\n[l]ine 3\nline 4\nline 2\nline 1\n")) (ert-info ("shell command operator with backward motion") (evil-test-buffer "line 5\nline 4\n[l]ine 3\nline 2\nline 1\n" ("!ksort" [return]) "line 5\n[l]ine 3\nline 4\nline 2\nline 1\n")) (ert-info ("shell command operator with visual selection") (evil-test-buffer "line 5\n[l]ine 4\nline 3\nline 2\nline 1\n" ("vj!sort" [return]) "line 5\n[l]ine 3\nline 4\nline 2\nline 1\n"))) (ert-deftest evil-test-global () "Test `evil-ex-global'." :tags '(evil ex global) (ert-info ("global delete") (evil-test-buffer "[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n" (":g/yes/d" [return]) "no 1\nno 2\nno 3\n[n]o 5\nno 6\nno 7\n")) (ert-info ("global substitute") (evil-test-buffer "[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n" (":g/no/s/[3-6]/x" [return]) "no 1\nno 2\nno x\nyes 4\nno x\nno x\n[n]o 7\n" ("u") "no 1\nno 2\nno [3]\nyes 4\nno 5\nno 6\nno 7\n")) (ert-info ("global substitute with trailing slash") (evil-test-buffer "[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n" (":g/no/s/[3-6]/x/" [return]) "no 1\nno 2\nno x\nyes 4\nno x\nno x\n[n]o 7\n" ("u") "no 1\nno 2\nno [3]\nyes 4\nno 5\nno 6\nno 7\n")) (evil-select-search-module 'evil-search-module 'evil-search) (ert-info ("global use last match if none given, with evil-search") (evil-test-buffer "[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n" ("/yes" [return]) "no 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n" (":g//d" [return]) "no 1\nno 2\nno 3\n[n]o 5\nno 6\nno 7\n" (":v//d" [return]) "")) (evil-select-search-module 'evil-search-module 'isearch) (ert-info ("global use last match if none given, with isearch") (evil-test-buffer "[n]o 1\nno 2\nno 3\nisearch 4\nno 5\nno 6\nno 7\n" ("/isearch" [return]) "no 1\nno 2\nno 3\nisearch 4\nno 5\nno 6\nno 7\n" (":g//d" [return]) "no 1\nno 2\nno 3\n[n]o 5\nno 6\nno 7\n" (":v//d" [return]) "")) (ert-info (":global should take into account evil-ex-search-case") (evil-with-both-search-modules (let ((evil-ex-search-case 'sensitive)) (evil-test-buffer "this\nThis\n" (":g/this/d" [return]) "This\n")) (let ((evil-ex-search-case 'insensitive)) (evil-test-buffer "this\nThis\n" (":g/this/d" [return]) "")) (let ((evil-ex-search-case 'smart)) (evil-test-buffer "this\nThis\n" (":g/this/d" [return]) "") (evil-test-buffer "this\nThis\n" (":g/This/d" [return]) "this\n")))) (ert-info (":global should transform vim-style regexp when appropriate") (let ((evil-ex-search-vim-style-regexp t)) (evil-test-buffer "a\n1\nb\n2\nc\n3\n" (":g/\\d/>") "a\n 1\nb\n 2\nc\n 3\n")))) (ert-deftest evil-test-normal () "Test `evil-ex-normal'." :tags '(evil ex) (let (evil-want-fine-undo) (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4\nline 5\n" (":normal lxIABC" [escape] "AXYZ" [return]) "ABClne 1XY[Z]\nline 2\nline 3\nline 4\nline 5\n" (":3,4normal lxIABC" [escape] "AXYZ" [return]) "ABClne 1XYZ\nline 2\nABClne 3XYZ\nABClne 4XY[Z]\nline 5\n" ("u") "ABClne 1XYZ\nline 2\nl[i]ne 3\nline 4\nline 5\n"))) (ert-deftest evil-test-copy () :tags '(evil ex) "Test `evil-copy'." (ert-info ("Copy to last line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (":2,3copy$") "line1\nline2\nline3\nline4\nline5\nline2\n[l]ine3\n")) (ert-info ("Copy to last incomplete line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5" (":2,3copy$") "line1\nline2\nline3\nline4\nline5\nline2\n[l]ine3\n")) (ert-info ("Copy incomplete line to last incomplete line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5" (":4,5copy$") "line1\nline2\nline3\nline4\nline5\nline4\n[l]ine5\n")) (ert-info ("Copy to first line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (":2,3copy0") "line2\n[l]ine3\nline1\nline2\nline3\nline4\nline5\n")) (ert-info ("Copy to intermediate line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (":2,4copy2") "line1\nline2\nline2\nline3\n[l]ine4\nline3\nline4\nline5\n")) (ert-info ("Copy to current line") (evil-test-buffer "line1\nline2\nline3\nli[n]e4\nline5\n" (":2,4copy.") "line1\nline2\nline3\nline4\nline2\nline3\n[l]ine4\nline5\n"))) (ert-deftest evil-test-move () :tags '(evil ex) "Test `evil-move'." (ert-info ("Move to last line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (":2,3move$") "line1\nline4\nline5\nline2\n[l]ine3\n")) (ert-info ("Move to last incomplete line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5" (":2,3move$") "line1\nline4\nline5\nline2\n[l]ine3\n")) (ert-info ("Move incomplete line to last incomplete line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5" (":4,5move$") "line1\nline2\nline3\nline4\n[l]ine5\n")) (ert-info ("Move to first line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (":2,3move0") "line2\n[l]ine3\nline1\nline4\nline5\n")) (ert-info ("Move to intermediate line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (":2,4move2") "line1\nline2\nline3\n[l]ine4\nline5\n")) (ert-info ("Move to other line") (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (":2,3move4") "line1\nline4\nline2\n[l]ine3\nline5\n")) (ert-info ("Move to current line") (evil-test-buffer "line1\nline2\nline3\nli[n]e4\nline5\n" (":2,4move.") "line1\nline2\nline3\n[l]ine4\nline5\n")) (ert-info ("Move to backwards line, searching forwards (wrapping around)") (evil-test-buffer " Target Other line [S]ource " (":move/Target/") " Target [S]ource Other line ")) (ert-info ("Move to forwards line, searching backwards (wrapping around)") (evil-test-buffer " Target [O]ther line Source " (":move?Source?") " Target Source [O]ther line ")) (ert-info ("Move with global (classic line reversal)") (evil-test-buffer "5\n4\n3\n2\n1\n" (":g/^/m0") "1\n2\n3\n4\n5\n") (ert-info ("... and visual selection") (evil-test-buffer "<5\n4\n3\n2\n[1]>\n" (":g/^/m0") "1\n2\n3\n4\n5\n")) (ert-info ("... and no last blank line") (evil-test-buffer "5\n4\n3\n2\n1" (":g/^/m0") "1\n2\n3\n4\n5")))) (ert-deftest evil-test-write () :tags '(evil ex) "Test `evil-write'." (ert-info ("Write open file") (evil-with-temp-file filename "line1\nline2\nline3\n" (evil-test-buffer ((vconcat ":e " filename [return])) "[l]ine1\nline2\nline3\n" ("Galine4\nline5\n" [escape]) "line1\nline2\nline3\nline4\nline5\n" (":w") (file filename "line1\nline2\nline3\nline4\nline5\n")))) (ert-info ("Write current buffer to new file") (let ((filename (make-temp-file "evil-test-write"))) (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (delete-file filename) ((vconcat ":w " filename [return])) (file filename "line1\nline2\nline3\nline4\nline5\n") (delete-file filename)))) (ert-info ("Write part of a buffer") (let ((filename (make-temp-file "evil-test-write"))) (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (delete-file filename) ((vconcat ":2,3w " filename [return])) (file filename "line2\nline3\n") (delete-file filename)))) (ert-info ("Appending a file") (let ((filename (make-temp-file "evil-test-write"))) (evil-test-buffer "[l]ine1\nline2\nline3\nline4\nline5\n" (delete-file filename) ((vconcat ":4w " filename [return])) (file filename "line4\n") ((vconcat ":1,2w >>" filename [return])) (file filename "line4\nline1\nline2\n") ((vconcat ":w >> " filename [return])) (file filename "line4\nline1\nline2\nline1\nline2\nline3\nline4\nline5\n") (delete-file filename))))) (ert-deftest evil-test-ex-sort () :tags '(evil ex) "Text ex command :sort `evil-ex-sort`." (ert-info ("Plain sort") (evil-test-buffer "[z]zyy\ntest\ntEst\ntesT\nTEST\ntest\n" (":sort") "[T]EST\ntEst\ntesT\ntest\ntest\nzzyy\n")) (ert-info ("Reverse sort") (evil-test-buffer "[z]zyy\ntest\ntEst\ntesT\nTEST\ntest\n" (":sort!") "[z]zyy\ntest\ntest\ntesT\ntEst\nTEST\n")) (ert-info ("case insensitive") (evil-test-buffer "[z]zyy\ntest\ntEst\ntesT\nTEST\ntest\n" (":sort i") "[t]est\ntEst\ntesT\nTEST\ntest\nzzyy\n")) (ert-info ("unique") (evil-test-buffer "[z]zyy\ntest\ntEst\ntesT\nTEST\ntest\n" (":sort u") "[T]EST\ntEst\ntesT\ntest\nzzyy\n")) (ert-info ("case insensitive and unique") (evil-test-buffer "[z]zyy\ntest\ntEst\ntesT\nTEST\ntest\n" (":sort iu") "[t]est\nzzyy\n"))) ;;; Command line window (ert-deftest evil-test-command-window-ex () "Test command line window for ex commands" (skip-unless (not noninteractive)) (let (evil-ex-history) (evil-test-buffer "[f]oo foo foo" (":s/foo/bar" [return]) "[b]ar foo foo" (":s/foo/baz" [return]) "[b]ar baz foo" ("q:") "s/foo/bar\ns/foo/baz\n[]\n" ("kk:s/bar/quz" [return]) "[s]/foo/quz\ns/foo/baz\n" ("fzrx") "s/foo/qu[x]\ns/foo/baz\n" ([return]) "[b]ar baz qux" (should (equal (car evil-ex-history) "s/foo/qux"))))) (ert-deftest evil-test-command-window-recursive () "Test that recursive command windows shouldn't be allowed" (skip-unless (not noninteractive)) (let ((evil-command-window-height 0)) (evil-test-buffer "[f]oo foo foo" (":s/foo/bar" [return]) ("q:") (should-error (execute-kbd-macro "q:"))))) (ert-deftest evil-test-command-window-noop () "Test that executing a blank command does nothing" (skip-unless (not noninteractive)) (evil-test-buffer "[f]oo foo foo" ("q:") "[]\n" ([return]) "[f]oo foo foo")) (ert-deftest evil-test-command-window-multiple () "Test that multiple command line windows can't be visible at the same time" (skip-unless (not noninteractive)) (let ((evil-command-window-height 0)) (evil-test-buffer "[f]oo foo foo" ("q:") (let ((num-windows (length (window-list)))) (select-window (previous-window)) (execute-kbd-macro "q:") (should (= (length (window-list)) num-windows)))))) (defmacro evil-with-both-search-modules (&rest body) `(mapc (lambda (search-module) (setq evil-search-forward-history nil evil-search-backward-history nil evil-ex-search-history nil) (evil-select-search-module 'evil-search-module search-module) ,@body) '(isearch evil-search))) (ert-deftest evil-test-command-window-search-history () "Test command window with forward and backward search history" (skip-unless (not noninteractive)) (let ((evil-search-module 'isearch)) (evil-test-buffer "[f]oo bar baz qux one two three four" ("/qux" [return]) "foo bar baz [q]ux one two three four" ("/three" [return]) "foo bar baz qux one two [t]hree four" ("?bar" [return]) "foo [b]ar baz qux one two three four" ("/four" [return]) "foo bar baz qux one two three [f]our" ("?baz" [return]) "foo bar [b]az qux one two three four" ("q/") "qux\nthree\nfour\n[]\n" ("k" [return]) "foo bar baz qux one two three [f]our" ("0N") "foo bar baz qux one two three [f]our" ("q?") "bar\nbaz\n[]\n" ("k$rr" [return]) "foo [b]ar baz qux one two three four" (should-error (progn (execute-kbd-macro "q/iNOT THERE") (execute-kbd-macro [return]))) "foo [b]ar baz qux one two three four"))) (ert-deftest evil-test-command-window-search-word () "Test command window history when searching for word under cursor" (skip-unless (not noninteractive)) (let ((evil-search-module 'isearch)) (evil-test-buffer "[f]oo bar foo bar foo" ("**") "foo bar foo bar [f]oo" ("B#") "foo [b]ar foo bar foo" ("q/k" [return]) "foo bar [f]oo bar foo" ("q?k" [return]) "foo [b]ar foo bar foo"))) ;;; Utilities (ert-deftest evil-test-parser () "Test `evil-parser'" (let ((grammar '((number "[0-9]+" #'string-to-number) (plus "\\+" #'intern) (minus "-" #'intern) (operator plus minus) (sign ((\? operator) #'$1)) (signed-number (sign number)) (inc (number #'(lambda (n) (1+ n)))) (expr (number operator number) ("2" #'"1+1")) (epsilon nil)))) (ert-info ("Nothing") (should (equal (evil-parser "1+2" nil grammar t) nil)) (should (equal (evil-parser "1+2" nil grammar) '(nil . "1+2"))) (should (equal (evil-parser "1+2" 'epsilon grammar t) nil)) (should (equal (evil-parser "1+2" 'epsilon grammar) '(nil . "1+2")))) (ert-info ("Strings") (should (equal (evil-parser "1" 'number grammar t) '((string-to-number "1")))) (should (equal (evil-parser "11" 'number grammar) '((string-to-number "11") . "")))) (ert-info ("Sequences") (should (equal (evil-parser "1" '(number) grammar t) '((list (string-to-number "1"))))) (should (equal (evil-parser "1+2" '(number operator number) grammar t) '((list (string-to-number "1") (intern "+") (string-to-number "2")))))) (ert-info ("Symbols") (should (equal (evil-parser "+" 'plus grammar t) '((intern "+")))) (should (equal (evil-parser "+" 'operator grammar t) '((intern "+")))) (should (equal (evil-parser "1" 'number grammar t) '((string-to-number "1"))))) (ert-info ("Whitespace") (should (equal (evil-parser " 1" 'number grammar t) '((string-to-number "1"))))) (ert-info ("One or more") (should (equal (evil-parser "1 2 3" '(+ number) grammar t) '((list (string-to-number "1") (string-to-number "2") (string-to-number "3"))))) (should (equal (evil-parser "1 2 3" '(* number) grammar t) '((list (string-to-number "1") (string-to-number "2") (string-to-number "3"))))) (should (equal (evil-parser "1 2 3" '(\? number) grammar) '((string-to-number "1") . " 2 3"))) (should (equal (evil-parser "1 2 3" '(\? number number) grammar) '((list (string-to-number "1") (string-to-number "2")) . " 3"))) (should (equal (evil-parser "1 2 3" '(number (\? number)) grammar) '((list (string-to-number "1") (string-to-number "2")) . " 3"))) (should (equal (evil-parser "1 2 3" '(number (\? number number)) grammar) '((list (string-to-number "1") (list (string-to-number "2") (string-to-number "3"))) . ""))) (should (equal (evil-parser "1 a 3" '(number (\? number)) grammar) '((list (string-to-number "1") nil) . " a 3"))) (should (equal (evil-parser "1" 'signed-number grammar t t) '((signed-number (sign "") (number "1")) . "")))) (ert-info ("Lookahead") (should (equal (evil-parser "foobar" '("foo" (& "bar")) grammar) '((list "foo") . "bar"))) (should (equal (evil-parser "foobar" '("foo" (! "bar")) grammar) nil)) (should (equal (evil-parser "foobar" '("foo" (& "baz")) grammar) nil)) (should (equal (evil-parser "foobar" '("foo" (! "baz")) grammar) '((list "foo") . "bar")))) (ert-info ("Semantic actions") (should (equal (evil-parser "1" 'inc grammar t) '((funcall (lambda (n) (1+ n)) (string-to-number "1"))))) (should (equal (evil-parser "1+1" 'expr grammar t) '((list (string-to-number "1") (intern "+") (string-to-number "1"))))) (should (equal (evil-parser "2" 'expr grammar t) '((list (string-to-number "1") (intern "+") (string-to-number "1")))))))) (ert-deftest evil-test-delimited-arguments () "Test `evil-delimited-arguments'" :tags '(evil util) (ert-info ("Any number of arguments") (should (equal (evil-delimited-arguments "/a/b/c/") '("a" "b" "c"))) (should (equal (evil-delimited-arguments "/a/b/c") '("a" "b" "c"))) (should (equal (evil-delimited-arguments "/a/b//") '("a" "b" ""))) (should (equal (evil-delimited-arguments "/a///") '("a" "" ""))) (should (equal (evil-delimited-arguments "/a/ ") '("a" " "))) (should (equal (evil-delimited-arguments "/a/") '("a"))) (should (equal (evil-delimited-arguments "//b//") '("" "b" ""))) (should (equal (evil-delimited-arguments "/a//c") '("a" "" "c"))) (should (equal (evil-delimited-arguments "////") '("" "" ""))) (should (equal (evil-delimited-arguments "/") nil)) (should (equal (evil-delimited-arguments " ") nil)) (should (equal (evil-delimited-arguments "") nil))) (ert-info ("Two arguments") (should (equal (evil-delimited-arguments "/a/b/c" 2) '("a" "b/c"))) (should (equal (evil-delimited-arguments "/a/b/" 2) '("a" "b"))) (should (equal (evil-delimited-arguments "/a/b" 2) '("a" "b"))) (should (equal (evil-delimited-arguments "/a//" 2) '("a" ""))) (should (equal (evil-delimited-arguments "/a/ " 2) '("a" " "))) (should (equal (evil-delimited-arguments "/a/" 2) '("a" nil))) (should (equal (evil-delimited-arguments "/a" 2) '("a" nil))) (should (equal (evil-delimited-arguments " " 2) '(nil nil))) (should (equal (evil-delimited-arguments "" 2) '(nil nil)))) (ert-info ("One argument") (should (equal (evil-delimited-arguments "/a/b/c" 1) '("a/b/c"))) (should (equal (evil-delimited-arguments "/a/ " 1) '("a"))) (should (equal (evil-delimited-arguments "/a/" 1) '("a"))) (should (equal (evil-delimited-arguments "/a" 1) '("a"))) (should (equal (evil-delimited-arguments "/" 1) '(nil))) (should (equal (evil-delimited-arguments " " 1) '(nil))) (should (equal (evil-delimited-arguments "" 1) '(nil)))) (ert-info ("Zero arguments") (should (equal (evil-delimited-arguments "/a" 0) nil)) (should (equal (evil-delimited-arguments "/" 0) nil)) (should (equal (evil-delimited-arguments " " 0) nil)) (should (equal (evil-delimited-arguments "" 0) nil)))) (ert-deftest evil-test-concat-charsets () "Test `evil-concat-charsets'" :tags '(evil util) (ert-info ("Bracket") (should (equal (evil-concat-charsets "abc" "]def") "]abcdef"))) (ert-info ("Complement") (should (equal (evil-concat-charsets "^abc" "def") "^abcdef")) (should (equal (evil-concat-charsets "^abc" "^def") "^abcdef"))) (ert-info ("Hyphen") (should (equal (evil-concat-charsets "abc" "-def") "-abcdef")) (should (equal (evil-concat-charsets "^abc" "-def") "^-abcdef"))) (ert-info ("Newline") (should (equal (evil-concat-charsets "^ \t\r\n" "[:word:]_") "^ \t\r\n[:word:]_")))) (ert-deftest evil-test-properties () "Test `evil-get-property' and `evil-put-property'" :tags '(evil util) (let (alist) (ert-info ("Set properties") (evil-put-property 'alist 'wibble :foo t) (should (equal alist '((wibble . (:foo t))))) (evil-put-property 'alist 'wibble :bar nil) (should (equal alist '((wibble . (:foo t :bar nil))))) (evil-put-property 'alist 'wobble :foo nil :bar nil :baz t) (should (equal alist '((wobble . (:foo nil :bar nil :baz t)) (wibble . (:foo t :bar nil)))))) (ert-info ("Get properties") (should (evil-get-property alist 'wibble :foo)) (should-not (evil-get-property alist 'wibble :bar)) (should-not (evil-get-property alist 'wobble :foo)) (should-not (evil-get-property alist 'wibble :baz)) (should (equal (evil-get-property alist t :foo) '((wibble . t) (wobble . nil)))) (should (equal (evil-get-property alist t :bar) '((wibble . nil) (wobble . nil)))) (should (equal (evil-get-property alist t :baz) '((wobble . t))))))) (ert-deftest evil-test-filter-list () "Test `evil-filter-list'" :tags '(evil util) (ert-info ("Return filtered list") (should (equal (evil-filter-list #'null '(nil)) nil)) (should (equal (evil-filter-list #'null '(nil 1)) '(1))) (should (equal (evil-filter-list #'null '(nil 1 2 nil)) '(1 2))) (should (equal (evil-filter-list #'null '(nil nil 1)) '(1))) (should (equal (evil-filter-list #'null '(nil 1 nil 2 nil 3)) '(1 2 3)))) (ert-info ("Remove matches by side-effect when possible") (let (list) (setq list '(1 nil)) (evil-filter-list #'null list) (should (equal list '(1))) (setq list '(1 nil nil)) (evil-filter-list #'null list) (should (equal list '(1))) (setq list '(1 nil nil 2)) (evil-filter-list #'null list) (should (equal list '(1 2))) (setq list '(1 nil 2 nil 3)) (evil-filter-list #'null list) (should (equal list '(1 2 3)))))) (ert-deftest evil-test-concat-lists () "Test `evil-concat-lists' and `evil-concat-alists'" :tags '(evil util) (ert-info ("Remove duplicates across lists") (should (equal (evil-concat-lists nil '(a b) '(b c)) '(a b c)))) (ert-info ("Remove duplicates inside lists") (should (equal (evil-concat-lists '(a a b) nil '(b c) nil) '(a b c)))) (ert-info ("Remove duplicate associations") (should (equal (evil-concat-alists '((a . b)) '((a . c))) '((a . c)))) (should-not (equal (evil-concat-lists '((a . b)) '((a . c))) '((a . b)))))) (ert-deftest evil-test-sort () "Test `evil-sort' and `evil-swap'" :tags '(evil util) (let (a b c d) (ert-info ("Two elements") (setq a 2 b 1) (evil-sort a b) (should (= a 1)) (should (= b 2)) (evil-swap a b) (should (= a 2)) (should (= b 1))) (ert-info ("Three elements") (setq a 3 b 1 c 2) (evil-sort a b c) (should (= a 1)) (should (= b 2)) (should (= c 3))) (ert-info ("Four elements") (setq a 4 b 3 c 2 d 1) (evil-sort a b c d) (should (= a 1)) (should (= b 2)) (should (= c 3)) (should (= d 4))))) (ert-deftest evil-test-read-key () "Test `evil-read-key'" :tags '(evil util) (let ((unread-command-events '(?A))) (ert-info ("Prevent downcasing in `this-command-keys'") (should (eq (evil-read-key) ?A)) (should (equal (this-command-keys) "A"))))) (ert-deftest evil-test-extract-count () "Test `evil-extract-count'" :tags '(evil util) (evil-test-buffer (ert-info ("Exact without count") (should (equal (evil-extract-count "x") (list nil 'evil-delete-char "x" nil))) (should (equal (evil-extract-count "g0") (list nil 'evil-beginning-of-visual-line "g0" nil)))) (ert-info ("Exact with count") (should (equal (evil-extract-count "420x") (list 420 'evil-delete-char "x" nil))) (should (equal (evil-extract-count (vconcat "420" [M-right])) (list 420 (key-binding [M-right]) (vconcat [M-right]) nil))) (should (equal (evil-extract-count "2301g0") (list 2301 'evil-beginning-of-visual-line "g0" nil)))) (ert-info ("Extra elements without count") (should (equal (evil-extract-count "xAB") (list nil 'evil-delete-char "x" "AB"))) (should (equal (evil-extract-count "g0CD") (list nil 'evil-beginning-of-visual-line "g0" "CD")))) (ert-info ("Extra elements with count") (should (equal (evil-extract-count "420xAB") (list 420 'evil-delete-char "x" "AB"))) (should (equal (evil-extract-count "2301g0CD") (list 2301 'evil-beginning-of-visual-line "g0" "CD")))) (ert-info ("Exact \"0\" count") (should (equal (evil-extract-count "0") (list nil 'evil-beginning-of-line "0" nil)))) (ert-info ("Extra elements and \"0\"") (should (equal (evil-extract-count "0XY") (list nil 'evil-beginning-of-line "0" "XY")))) (ert-info ("Count only") (should-error (evil-extract-count "1230"))) (ert-info ("Unknown command") (should-error (evil-extract-count "°")) (should-error (evil-extract-count "12°"))))) (ert-deftest evil-transform-vim-style-regexp () "Test `evil-transform-vim-style-regexp'" (dolist (repl '((?s . "[[:space:]]") (?S . "[^[:space:]]") (?d . "[[:digit:]]") (?D . "[^[:digit:]]") (?x . "[[:xdigit:]]") (?X . "[^[:xdigit:]]") (?o . "[0-7]") (?O . "[^0-7]") (?a . "[[:alpha:]]") (?A . "[^[:alpha:]]") (?l . "[a-z]") (?L . "[^a-z]") (?u . "[A-Z]") (?U . "[^A-Z]") (?y . "\\s") (?Y . "\\S") (?w . "\\w") (?W . "\\W"))) (ert-info ((format "Test transform from '\\%c' to '%s'" (car repl) (cdr repl))) (should (equal (evil-transform-vim-style-regexp (concat "xxx\\" (char-to-string (car repl)) "\\" (char-to-string (car repl)) "\\\\" (char-to-string (car repl)) "\\\\\\" (char-to-string (car repl)) "yyy")) (concat "xxx" (cdr repl) (cdr repl) "\\\\" (char-to-string (car repl)) "\\\\" (cdr repl) "yyy")))))) ;;; Advice (ert-deftest evil-test-eval-last-sexp () "Test advised `evil-last-sexp'" :tags '(evil advice) (ert-info ("Normal state") (evil-test-buffer "(+ 1 (+ 2 3[)])" ("1" (kbd "C-x C-e")) "(+ 1 (+ 2 35[)])")) (ert-info ("Insert state") (evil-test-buffer "(+ 1 (+ 2 3[)])" ("i" (kbd "C-u") (kbd "C-x C-e") [escape]) "(+ 1 (+ 2 3[3]))")) (ert-info ("Emacs state") (evil-test-buffer "(+ 1 (+ 2 3[)])" ((kbd "C-z") (kbd "C-u") (kbd "C-x C-e")) "(+ 1 (+ 2 33[)])"))) ;;; ESC (ert-deftest evil-test-esc-count () "Test if prefix-argument is transfered for key sequences with meta-key" :tags '(evil esc) (unless noninteractive (ert-info ("Test M-") (evil-test-buffer "[A]BC DEF GHI JKL MNO" ("3" (kbd "ESC ")) "ABC DEF GHI[ ]JKL MNO")) (ert-info ("Test shell-command") (evil-test-buffer "[A]BC DEF GHI JKL MNO" ("1" (kbd "ESC !") "echo TEST" [return]) "[T]EST\nABC DEF GHI JKL MNO")))) (when (or evil-tests-profiler evil-tests-run) (evil-tests-initialize)) (ert-deftest evil-test-black-hole-register () :tags '(evil) (ert-info ("Test \"_ on delete word") (evil-test-buffer "[E]vil evil is awesome." ("dw\"_dwP") "Evil[ ]is awesome.")) (ert-info ("Test \"_ on delete line") (evil-test-buffer "[T]his line is a keeper!\nThis line is not." ("dd\"_ddP") "[T]his line is a keeper!")) (ert-info ("Test \"_ on delete region") (evil-test-buffer "!\nThis line is not." ("d\gg\"_dGP") "This region is a keepe[r]"))) (ert-deftest evil-test-pasteable-macros () "Test if we can yank and paste macros containing " :tags '(evil) (ert-info ("Execute yanked macro") (evil-test-buffer "[i]foo\e" ("\"qd$@q\"qp" "fooifoo\e"))) (ert-info ("Paste recorded marco") (evil-test-buffer "" (evil-set-register ?q (vconcat "ifoo" [escape])) ("@q\"qp") "fooifoo\e"))) (ert-deftest evil-test-forward-symbol () :tags '(evil) (ert-info ("Test symbol deletion") (evil-test-buffer "(test [t]his (hello there) with dao)" ("dao") "(test [(]hello there) with dao)")) (ert-info ("Test symbol motion") (evil-test-buffer "(test[ ](hello there) with dao)" (should (eq 0 (forward-evil-symbol 1))) "(test ([h]ello there) with dao)" (should (eq 0 (forward-evil-symbol 1))) "(test (hello[ ]there) with dao)")) (ert-info ("Test dio on whitespace") (evil-test-buffer "(test[ ]dio with whitespace)" ("dio") "(test[d]io with whitespace)")) (ert-info ("Test dao/dio with empty lines") (evil-test-buffer "there are two lines in this file\n[\n]and some whitespace between them" ("dao") "there are two lines in this file\n[a]nd some whitespace between them") (evil-test-buffer "here are another two lines\n[\n]with a blank line between them" ("dio") "here are another two lines\n[w]ith a blank line between them")) (ert-info ("Test dao/dio with empty lines and punctuation") (evil-test-buffer "These two lines \n[\n]!have punctuation on them" ("dao") "These two lines \n[!]have punctuation on them"))) (ert-deftest evil-test-jump () :tags '(evil jumps) (let ((evil--jumps-buffer-targets "\\*\\(new\\|scratch\\|test\\)\\*")) (ert-info ("Test jumping backward and forward in a single buffer") (evil-test-buffer "[z] z z z z z z z z z" ("/z" [return]) "z [z] z z z z z z z z" ("nnnn") "z z z z z [z] z z z z" ("\C-o") "z z z z [z] z z z z z" ("\C-o") "z z z [z] z z z z z z" ("\C-i\C-i") "z z z z z [z] z z z z")) (ert-info ("Test jumping backward and forward with counts") (evil-test-buffer "[z] z z z z z z z z z" ("/z" [return] "nnnn") "z z z z z [z] z z z z" ("3\C-o") "z z [z] z z z z z z z" ("2\C-i") "z z z z [z] z z z z z" )) (ert-info ("Jump list branches off when new jump is set") (evil-test-buffer "[z] z z z z z z z" ("/z" [return] "nnnn4\C-o") ;; adds a bunch of jumps after the 2nd z "z [z] z z z z z z" ("/z" [return]) ;; sets a new jump, list should be reset "z z [z] z z z z z" ("\C-o") "z [z] z z z z z z" ("3\C-i") ;; even after jumping forward 3 times it can't get past the 3rd z "z z [z] z z z z z")) (ert-info ("Jump across files") (let ((temp-file (make-temp-file "evil-test-"))) (unwind-protect (evil-test-buffer "[z] z z z z z z" ("\M-x" "find-file" [return] temp-file [return] "inew buffer" [escape]) "new buffe[r]" ("\C-o") "[z] z z z z z z" ("\C-i") "new buffe[r]") (delete-file temp-file) (with-current-buffer (get-file-buffer temp-file) (set-buffer-modified-p nil)) (kill-buffer (get-file-buffer temp-file))))))) (ert-deftest evil-test-find-file () :tags '(evil jumps) (ert-info ("Find file at point (normal state)") (evil-with-temp-file file-name "" (evil-test-buffer (vconcat "i" file-name [escape]) (should (not (equal file-name (buffer-file-name (current-buffer))))) ("gf") (should (equal file-name (buffer-file-name (current-buffer))))))) (ert-info ("Find file at point (visual state)") (evil-with-temp-file file-name "" (evil-test-buffer (vconcat "iuser@localhost:" file-name "$" [escape]) (should (not (equal file-name (buffer-file-name (current-buffer))))) ("0f:lvt$gf") (should (equal file-name (buffer-file-name (current-buffer))))))) (ert-info ("Find file at point with line number") (let* ((line-number 3) (file-content (make-string (* 2 line-number) ?\n))) (evil-with-temp-file file-name (insert file-content) (evil-test-buffer (vconcat "i" file-name (format ":%d" line-number) [escape]) (should (and (not (equal file-name (buffer-file-name (current-buffer)))) (not (equal line-number (line-number-at-pos))))) ("gF") (should (and (equal file-name (buffer-file-name (current-buffer))) (equal line-number (line-number-at-pos)))))))) (ert-info ("Find file at point with line and column numbers") (let* ((line-number 3) (column-number 5) (file-content (mapconcat 'identity (make-list (* 2 line-number) (make-string (* 2 column-number) ?\s)) "\n"))) (evil-with-temp-file file-name (insert file-content) (evil-test-buffer (vconcat "i" file-name (format ":%d:%d" line-number column-number) [escape]) (should (and (not (equal file-name (buffer-file-name (current-buffer)))) (not (equal line-number (line-number-at-pos))) (not (equal column-number (current-column))))) ("gF") (should (and (equal file-name (buffer-file-name (current-buffer))) (equal line-number (line-number-at-pos)) (equal column-number (1+ (current-column)))))))))) (ert-deftest evil-test-jump-buffers () :tags '(evil jumps) (skip-unless nil) (ert-info ("Test jumping backward and forward across buffers") (evil-test-buffer "[z] z z z z z z z z z" (":new" [return] "inew buffer" [escape]) "new buffe[r]" ("\C-o") "[z] z z z z z z z z z" ("\C-i") "new buffe[r]"))) (ert-deftest evil-test-abbrev-expand () :tags '(evil abbrev) (ert-info ("Test abbrev expansion on insert state exit") (define-abbrev-table 'global-abbrev-table '(("undef" "undefined"))) ; add global abbrev (evil-test-buffer "foo unde[f] bar" (abbrev-mode) ("a" [escape]) "foo undefine[d] bar") ; 'undef' should be expanded (evil-test-buffer "foo unde[f] bar" ("a" [escape]) "foo unde[f] bar") ; 'undef' shouldn't be expanded, ; abbrev-mode is not enabled (evil-test-buffer "fo[o] undef bar" (abbrev-mode) ("a" [escape]) "fo[o] undef bar") ; 'foo' shouldn't be expanded, ; it's not an abbrev (kill-all-abbrevs) ; remove all abbrevs (evil-test-buffer "foo unde[f] bar" (abbrev-mode) ("a" [escape]) "foo unde[f] bar") ; 'undef' shouldn't be expanded, ; it's not an abbrev (setq abbrevs-changed nil))) (ert-deftest evil-test-text-object-macro () :tags '(evil abbrev) (ert-info ("Test pipe character and other delimiters as object delimiters") ;; This is the macro that broke after pull #747. (defmacro evil-test-define-and-bind-text-object (name key start-regex end-regex) (let ((inner-name (make-symbol (concat "evil-inner-" name))) (outer-name (make-symbol (concat "evil-a-" name)))) `(progn (evil-define-text-object ,inner-name (count &optional beg end type) (evil-select-paren ,start-regex ,end-regex beg end type count nil)) (evil-define-text-object ,outer-name (count &optional beg end type) (evil-select-paren ,start-regex ,end-regex beg end type count t)) (define-key evil-inner-text-objects-map ,key #',inner-name) (define-key evil-outer-text-objects-map ,key #',outer-name)))) (evil-test-define-and-bind-text-object "pipe" "|" "|" "|") (evil-test-define-and-bind-text-object "rackety" "#" "#|" "|#") (evil-test-buffer "#|this i[s] a test #|with rackety|# multiline and nestable comments|#" ("vi#") "#||#") (evil-test-buffer "| foo | aoe[u] | bar |" ("vi|") "| foo |< aoeu >| bar |" ("a|") "| foo <| aoeu |> bar |" ("a|") "<| foo | aoeu | bar |>") (evil-test-buffer "| foo | aoe[u] | bar |" ("ci|testing" [escape]) "| foo |testing| bar |"))) (ert-deftest evil-test-undo-kbd-macro () "Test if evil can undo the changes made by a keyboard macro when an error stops the execution of the macro" :tags '(evil undo kbd-macro) (ert-info ("When kbd-macro goes to the end of buffer") (evil-test-buffer "[l]ine 1\nline 2\nline 3\nline 4" (evil-set-register ?q "jdd") ("jdd") (should-error (execute-kbd-macro "2@q")) ("uu") "line 1\n[l]ine 2\nline 3\nline 4")) (ert-info ("When kbd-macro goes to the end of line") (evil-test-buffer "[f]ofof" (evil-set-register ?q "lx") ("lx") (should-error (execute-kbd-macro "2@q")) ("uu") "f[o]fof")) (ert-info ("When kbd-macro goes to the beginning of buffer") (evil-test-buffer "line 1\nline 2\n[l]ine 3" (evil-set-register ?q "kx") ("kx") (should-error (execute-kbd-macro "2@q")) ("uu") "line 1\n[l]ine 2\nline 3"))) (ert-deftest evil-test-visual-update-x-selection () "Test `evil-visual-update-x-selection'." :tags '(evil) (ert-info ("Buffer argument isn't a live buffer") ;; create buffer in normal mode, so we don't try to actually copy anything to ;; the X selection. (let ((buf (evil-test-buffer-from-string "foobar"))) (kill-buffer buf) ;; should not raise an "Selecting deleted buffer" error (evil-visual-update-x-selection buf)))) ;;; Core (ert-deftest evil-test-initial-state () "Test `evil-initial-state'" :tags '(evil core) (define-derived-mode test-1-mode prog-mode "Test1") (define-derived-mode test-2-mode test-1-mode "Test2") (evil-set-initial-state 'test-1-mode 'insert) (ert-info ("Check default state") (should (eq (evil-initial-state 'prog-mode 'normal) 'normal))) (ert-info ("Basic functionality 1") (should (eq (evil-initial-state 'test-1-mode) 'insert))) (ert-info ("Basic functionality 2") (evil-test-buffer "abc\ndef\n" (test-1-mode) (should (eq evil-state 'insert)))) (ert-info ("Inherit initial state from a parent") (evil-test-buffer "abc\ndef\n" (test-2-mode) (should (eq evil-state 'insert)))) (evil-set-initial-state 'test-1-mode nil) (ert-info ("Check for inheritance loops") (evil-test-buffer "abc\ndef\n" (unwind-protect (let ((major-mode 'test-2-mode)) (put 'test-1-mode 'derived-mode-parent 'test-2-mode) ;; avoid triggering all of the hooks here, some of which might get ;; caught in loops depending on the environment. settings major-mode ;; is sufficient for `evil-initial-state-for-buffer' to work. (should-error (evil-initial-state-for-buffer))) (put 'test-1-mode 'derived-mode-parent 'prog-mode)))) (defalias 'test-1-alias-mode 'test-1-mode) (define-derived-mode test-3-mode test-1-alias-mode "Test3") (evil-set-initial-state 'test-1-mode 'insert) (ert-info ("Check inheritance from major mode aliases") "abc\ndef\n" (test-3-mode) (should (eq evil-state 'insert)))) (provide 'evil-tests) ;;; evil-tests.el ends here