diff options
Diffstat (limited to '.config/emacs/lisp/evil')
53 files changed, 0 insertions, 35090 deletions
diff --git a/.config/emacs/lisp/evil/.dir-locals.el b/.config/emacs/lisp/evil/.dir-locals.el deleted file mode 100644 index d79ba71..0000000 --- a/.config/emacs/lisp/evil/.dir-locals.el +++ /dev/null @@ -1,3 +0,0 @@ -;; Don't use tabs for el files -((emacs-lisp-mode . - ((indent-tabs-mode . nil)))) diff --git a/.config/emacs/lisp/evil/.gitattributes b/.config/emacs/lisp/evil/.gitattributes deleted file mode 100644 index b362cfa..0000000 --- a/.config/emacs/lisp/evil/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.el diff=lisp diff --git a/.config/emacs/lisp/evil/.github/ISSUE_TEMPLATE.md b/.config/emacs/lisp/evil/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 53cbe14..0000000 --- a/.config/emacs/lisp/evil/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,29 +0,0 @@ -<!-- Replace every comment and delete this line --> -# Issue type - -<!-- Pick one of the following, delete the rest --> -- Bug report -- Enhancement request -- Question -- Other - -# Environment - -Emacs version: <!-- M-x emacs-version --> -Operating System: <!-- Name and version, e.g. Windows 10, macOS Sierra, Debian Jessie --> -Evil version: <!-- M-x evil-version --> -Evil installation type: <!-- MELPA, MELPA stable, NonGNU ELPA, Quelpa, El-Get, manual --> -Graphical/Terminal: <!-- Whether you're running Emacs in a terminal emulator or under X --> -Tested in a `make emacs` session (see [CONTRIBUTING.md](https://github.com/emacs-evil/evil/blob/master/CONTRIBUTING.md#bug-reports)): <!-- Yes / No --> - -# Reproduction steps -- Start Emacs -<!-- Minimal list of steps to reproduce the bug, preferably using `make emacs`: https://github.com/emacs-evil/evil/blob/master/CONTRIBUTING.md#bug-reports --> - -# Expected behavior -<!-- Describe how it should behave --> - -# Actual behavior -<!-- Describe how it does behave --> - -# Further notes diff --git a/.config/emacs/lisp/evil/.github/workflows/test.yml b/.config/emacs/lisp/evil/.github/workflows/test.yml deleted file mode 100644 index d73cf73..0000000 --- a/.config/emacs/lisp/evil/.github/workflows/test.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: CI - -on: [push, pull_request] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.experimental }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - emacs-version: - - 26.3 - - 27.2 - - 28.2 - - 29.4 - experimental: [false] - include: - - os: ubuntu-latest - emacs-version: snapshot - experimental: true - - os: macos-latest - emacs-version: snapshot - experimental: true - exclude: - - os: macos-latest - emacs-version: 26.3 - - os: macos-latest - emacs-version: 27.2 - - steps: - - uses: jcs090218/setup-emacs@master - with: - version: ${{ matrix.emacs-version }} - - - uses: actions/checkout@v4 - - - name: Print emacs version - run: | - emacs --version - - - uses: emacs-eask/setup-eask@master - with: - version: 'snapshot' - - - name: Run tests - run: | - make test - - - name: Print results - if: ${{ always() }} - run: | - cat test-results.txt diff --git a/.config/emacs/lisp/evil/.gitignore b/.config/emacs/lisp/evil/.gitignore deleted file mode 100644 index c5b19d7..0000000 --- a/.config/emacs/lisp/evil/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -*.elc -*.cp -*.ky -*.pg -*.tp -.depend -/evil-autoloads.el -/evil-pkg.el -test-results.txt -typescript - -/doc/dir -/doc/*.aux -/doc/*.fn -/doc/*.fns -/doc/*.info -/doc/*.log -/doc/*.toc -/doc/*.vr -/doc/*.vrs -/doc/docstringdb.json -/doc/build/*/ -!/doc/build/texinfo/evil.texi -*.pyc - -/.eask -/dist diff --git a/.config/emacs/lisp/evil/.readthedocs.yaml b/.config/emacs/lisp/evil/.readthedocs.yaml deleted file mode 100644 index f4b346b..0000000 --- a/.config/emacs/lisp/evil/.readthedocs.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: 2 - -build: - os: ubuntu-22.04 - tools: - python: "3.12" - apt_packages: [emacs-nox] - jobs: - pre_build: - - scripts/evil-extract-docstrings - -sphinx: - configuration: doc/source/conf.py - -python: - install: - - requirements: doc/requirements.txt diff --git a/.config/emacs/lisp/evil/CHANGES.org b/.config/emacs/lisp/evil/CHANGES.org deleted file mode 100644 index 102c6ab..0000000 --- a/.config/emacs/lisp/evil/CHANGES.org +++ /dev/null @@ -1,56 +0,0 @@ -* Changes and New Features in Evil - -** News in 1.0.7 - - * Fix #319. - -** News in 1.0.6 - - * Fix bug induced in emacs trunk due to changed behaviour of - `overriding-terminal-local-map` (fixes #309). - -** News in 1.0.5 - - * Fix bug in `show-paren-mode` due to variable renaming in latest - emacs. - - * Fix bug in isearch module due to variable renaming in latest - emacs. - -** News in 1.0.4 - - * Undo one restriction when <c> argument is read in operator state. - -** News in 1.0.3 - - * Fix `evil-delete-backward-word` at first non-blank in a line. - -** News in 1.0.2 - - * Fix #290. - -** News in 1.0.1 - -*** Improvements - - * An ELPA package built by =make elpa= contains COPYING file. - - * Bind =[tab]= like =\t= in =evil-ex-completion-map=, so that it - cannot be overwritten by a =[tab]= binding in the parent keymap - =minibuffer-local-completion-map=. - - * Improve worst case performance of internal functions - =evil-in-string-p=, =evil-string-beginning= and - =evil-string-end=. This functions are used, e.g., in certain text - objects to detect whether point is within a string. - - * Update authors list. - -*** Fixes - - * The interactive code =<state>= is fixed and used correctly in - =evil-ex-set-initial-state=. - - * =evil-ex-global= always generates a single undo-step. - - * Resolved issues: #249, #250, #253 and #257. diff --git a/.config/emacs/lisp/evil/CONTRIBUTING.md b/.config/emacs/lisp/evil/CONTRIBUTING.md deleted file mode 100644 index 913a5e2..0000000 --- a/.config/emacs/lisp/evil/CONTRIBUTING.md +++ /dev/null @@ -1,56 +0,0 @@ -# Bug reports - -Bug reports and feature requests should be made on the -[issue tracker](https://github.com/emacs-evil/evil/issues) here on github. - -**Before** sending a bug report, please take note of the following comments. - -1. Please provide a full description of the configuration of your - system. This includes - - - Emacs version, - - Evil version (e.g., the hash in the git repository), - - Whether you use Emacs/Evil in X mode or in terminal mode, - - Whether you use Emacs/Evil in terminal mode with some terminal multiplexer - like **tmux** or **screen** (and see below). - -2. Test the bug in a clean Emacs environment without any additional - packages loaded (besides Evil itself). You can easily get such an - environment by executing either `make emacs` (for X) or `make - terminal` (for terminal mode) in Evil's source directory. If your - bug is related to some other package, try to load only this package - from the clean environment after using `M-x package-initialize` - first. - -3. If you've just updated your Evil from the repository, **do not forget to - recompile** Evil by executing `make` in Evil's source directory. - -4. If possible, try to give a minimal example how to reproduce the error - starting from a fresh Emacs. The minimal example could be some buffer content - and a sequence of key-strokes that show up the error. - -5. If the bug you want to report is related to the behavior of some commands or - motions, please note the following. One goal of Evil is to get a behavior as - close to **Vim** as possible unless there is a good reason not to do so. The - reason is that many users come from Vim or use both, Vim and Evil, and we - want to keep the number of annoying differences between both as small as - possible, especially in common commands. In case you get an unexpected - behavior, please compare the behavior with plain Vim (i.e., without any - customization), if there's a difference please file the bug with a - description of this difference (and possibly a reference to Vim's - documentation). If you realize that both, Vim and Evil, behave the same but - you want a different behavior, you may make a **feature request** for some - customization option (but the default behavior will probably not be changed - in favor for Vim compatibility). Evil already contains several customization - options and sometimes the desired changes can be achieved as easily as - redefining some key-bindings. - -# Pull Requests - -1. Please follow the - [Emacs Lisp Style Guide](https://github.com/bbatsov/emacs-lisp-style-guide/) -2. When in doubt, adhere to the style conventions in the source code, - but don't be afraid of suggesting code enhancements in case you - encounter suboptimal code. -3. If your pull requests adds a feature or fixes a regression, add - tests covering it to `evil-tests.el`. diff --git a/.config/emacs/lisp/evil/COPYING b/.config/emacs/lisp/evil/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/.config/emacs/lisp/evil/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<http://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/.config/emacs/lisp/evil/Eask b/.config/emacs/lisp/evil/Eask deleted file mode 100644 index 77bf0c7..0000000 --- a/.config/emacs/lisp/evil/Eask +++ /dev/null @@ -1,57 +0,0 @@ -;; -*- mode: eask; lexical-binding: t -*- - -(package "evil" - "1.15.0" - "Extensible vi layer") - -(website-url "https://github.com/emacs-evil/evil") -(keywords "emulations") - -(package-file "evil.el") -(files "evil-*.el" '(:exclude "*-tests.el" "*-pkg.el")) - -(script "test" "echo \"Error: no test specified\" && exit 1") - -(source 'gnu) -(source 'melpa) - -(depends-on "emacs" "24.1") -(depends-on "cl-lib") -(depends-on "goto-chg") -(depends-on "nadvice") - -(setq network-security-level 'low) ; see https://github.com/jcs090218/setup-emacs-windows/issues/156#issuecomment-932956432 - -(eask-defcommand test - "Basic tests." - (require 'evil-tests) - (evil-tests-initialize nil nil)) - -(eask-defcommand terminal - "Load Evil in a terminal Emacs and run all tests." - (require 'evil-tests) - (evil-tests-initialize nil nil t)) - -(eask-defcommand profiler - "Run all tests with profiler." - (require 'evil-tests) - (evil-mode 1) - (evil-tests-initialize nil t)) - -(eask-defcommand indent - "Re-indent all Evil code." - (setq vc-handled-backends nil) - (dolist (file (eask-package-el-files)) (load file)) - (dolist (buffer (reverse (buffer-list))) - (when (buffer-file-name buffer) - (set-buffer buffer) - (message "Indenting %s" (current-buffer)) - (setq-default indent-tabs-mode nil) - (untabify (point-min) (point-max)) - (indent-region (point-min) (point-max)) - (delete-trailing-whitespace) - (untabify (point-min) (point-max)) - (goto-char (point-min)) - (while (re-search-forward "\\n\\\\{3,\\\\}" nil t) - (replace-match "\\n\\n")) - (when (buffer-modified-p) (save-buffer 0))))) diff --git a/.config/emacs/lisp/evil/Makefile b/.config/emacs/lisp/evil/Makefile deleted file mode 100644 index 6dd8f25..0000000 --- a/.config/emacs/lisp/evil/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -EMACS ?= emacs -SED ?= sed -FILES = $(filter-out evil-test-helpers.el evil-tests.el evil-pkg.el,$(wildcard evil*.el)) -VERSION := $(shell $(SED) -n '/^;\+ \+Version: *\(.*\)/{s//\1/p;q}' evil.el) -PROFILER = -TAG = -EASK ?= eask - -ELCFILES = $(FILES:.el=.elc) - -.PHONY: all compile docstrings doc clean tests test emacs term terminal profiler indent elpa version - -# Byte-compile Evil. -all: compile - -compile: - $(EASK) compile - -# Documentation. -docstrings: - @$(EMACS) --script scripts/evil-extract-docstrings - -doc: docstrings - @$(MAKE) -C doc texinfo - -info: doc - @$(MAKE) -C doc info - -# Delete byte-compiled files etc. -clean: - $(EASK) clean all - -# Run tests. -# The TAG variable may specify a test tag or a test name: -# make test TAG=repeat -# This will only run tests pertaining to the repeat system. -test: - $(EASK) run command test - -# Byte-compile Evil and run all tests. -tests: compile - $(EASK) run command test - $(EASK) clean elc - rm -f .depend - -# Load Evil in a fresh instance of Emacs and run all tests. -emacs: - $(EMACS) -Q -L . -l evil-tests.el \ - --eval "(evil-mode 1)" \ - --eval "(evil-tests-initialize '(${TAG}) '(${PROFILER}) t)" - -# Load Evil in a terminal Emacs and run all tests. -term terminal: - $(EASK) run command terminal - -# Run all tests with profiler. -profiler: - $(EASK) run command profiler - -# Re-indent all Evil code. -# Loads Evil into memory in order to indent macros properly. -# Also removes trailing whitespace, tabs and extraneous blank lines. -indent: clean - $(EASK) run command indent - -evil-pkg.el: evil.el - $(EMACS) --batch -l package $^ \ - --eval "(package-generate-description-file (package-buffer-info) \"$@\")" - -# Create an ELPA package. -elpa: evil-pkg.el - $(EASK) package - -# Change the version using make VERSION=x.y.z -version: - @$(EMACS) --script scripts/evilupdate "${VERSION}" - -# Change the version using make VERSION=x.y.z, but do not post to the newsgroup -nversion: - @$(EMACS) --script scripts/evilupdate nonews "${VERSION}" diff --git a/.config/emacs/lisp/evil/README.md b/.config/emacs/lisp/evil/README.md deleted file mode 100644 index b753ef5..0000000 --- a/.config/emacs/lisp/evil/README.md +++ /dev/null @@ -1,83 +0,0 @@ - - -[](https://github.com/emacs-evil/evil/actions/workflows/test.yml) -[](https://melpa.org/#/evil) -[](https://stable.melpa.org/#/evil) -[](http://elpa.nongnu.org/nongnu/evil.html) -[](https://evil.readthedocs.io/en/latest/?badge=latest) -[](https://www.gnu.org/licenses/gpl-3.0) - -Evil is an **e**xtensible **vi** **l**ayer -for [Emacs](http://www.gnu.org/software/emacs/). It emulates the main features -of [Vim](http://www.vim.org/), and provides facilities for writing custom -extensions. Also see our page on [EmacsWiki](http://emacswiki.org/emacs/Evil). - -# Installation - -See the -[official documentation](https://evil.readthedocs.io/en/latest/overview.html#installation-via-package-el) -for installation instructions. We recommend using *package.el*. - -As a quickstart, you can add the following code to your Emacs init -file. - -```elisp -;; Set up package.el to work with MELPA -(require 'package) -(add-to-list 'package-archives - '("melpa" . "https://melpa.org/packages/")) -(package-initialize) -(package-refresh-contents) - -;; Download Evil -(unless (package-installed-p 'evil) - (package-install 'evil)) - -;; Enable Evil -(require 'evil) -(evil-mode 1) -``` - -## Dependencies - -* Evil requires Emacs 24.1 or later. - -* Evil requires any of the following for `C-r`: - * `undo-redo` from Emacs 28 - * The [undo-tree] package (available via GNU ELPA) - * The [undo-fu] package (available via MELPA and NonGNU ELPA) - -* For the motions `g;` `g,` and for the last-change-register `.`, Evil - requires the [goto-chg.el](https://github.com/emacs-evil/goto-chg) - package (available via MELPA and NonGNU ELPA), which provides the - functions `goto-last-change` and `goto-last-change-reverse`. - -* For Emacs 24.1 and 24.2 Evil also requires - [cl-lib](https://elpa.gnu.org/packages/cl-lib.html). - -# Documentation - -The latest version of the documentation is readable online -[here](https://evil.readthedocs.io/en/latest/index.html). It is also -available as -[PDF](https://evil.readthedocs.io/_/downloads/en/stable/pdf/) and -as [EPUB](https://evil.readthedocs.io/_/downloads/en/stable/epub/). - -# Mailing list - -Evil is discussed at the -[gmane.emacs.vim-emulation](http://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list) -mailing list. - -# IRC - -Visit us on `irc.libera.chat #evil-mode`. - -# Contribution - -See -[CONTRIBUTING.md](https://github.com/emacs-evil/evil/blob/master/CONTRIBUTING.md) -for guidelines for issues and pull requests. - -[undo-tree]: https://gitlab.com/tsc25/undo-tree -[undo-fu]: https://codeberg.org/ideasman42/emacs-undo-fu diff --git a/.config/emacs/lisp/evil/doc/Makefile b/.config/emacs/lisp/evil/doc/Makefile deleted file mode 100644 index d0c3cbf..0000000 --- a/.config/emacs/lisp/evil/doc/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/.config/emacs/lisp/evil/doc/front.png b/.config/emacs/lisp/evil/doc/front.png Binary files differdeleted file mode 100644 index f79a67e..0000000 --- a/.config/emacs/lisp/evil/doc/front.png +++ /dev/null diff --git a/.config/emacs/lisp/evil/doc/logo.png b/.config/emacs/lisp/evil/doc/logo.png Binary files differdeleted file mode 100644 index 842a49d..0000000 --- a/.config/emacs/lisp/evil/doc/logo.png +++ /dev/null diff --git a/.config/emacs/lisp/evil/doc/logo.svg b/.config/emacs/lisp/evil/doc/logo.svg deleted file mode 100644 index ff833c2..0000000 --- a/.config/emacs/lisp/evil/doc/logo.svg +++ /dev/null @@ -1,110 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="127.82534" - height="62.426407" - id="svg2" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="evil.svg" - inkscape:export-filename="/home/vegard/evil.png" - inkscape:export-xdpi="150" - inkscape:export-ydpi="150"> - <defs - id="defs4" /> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="2.2069466" - inkscape:cx="173.13654" - inkscape:cy="12.652914" - inkscape:document-units="px" - inkscape:current-layer="layer1" - showgrid="false" - inkscape:window-width="1680" - inkscape:window-height="998" - inkscape:window-x="0" - inkscape:window-y="24" - inkscape:window-maximized="1" - fit-margin-left="10" - fit-margin-top="10" - fit-margin-right="10" - fit-margin-bottom="10" - showguides="true" - inkscape:guide-bbox="true" /> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-165.00893,-164.53963)"> - <rect - style="fill:#000000" - id="rect2991" - width="30.809652" - height="42.426407" - x="175.00893" - y="174.53963" /> - <text - xml:space="preserve" - style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" - x="178.15302" - y="209.50504" - id="text2985" - sodipodi:linespacing="125%"><tspan - sodipodi:role="line" - id="tspan2987" - x="178.15302" - y="209.50504" - style="font-weight:bold;letter-spacing:5.28999996px;-inkscape-font-specification:Ubuntu Bold"><tspan - style="letter-spacing:6.60000228999999994px;fill:#ffffff" - id="tspan2989">E</tspan><tspan - style="fill:#333333" - id="tspan2995">VIL</tspan></tspan></text> - <g - style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" - id="text2997" - transform="matrix(0.89694705,0.44213798,-0.44213798,0.89694705,260.2961,-122.4502)"> - <path - d="m 144.8919,272.13985 c 0.57684,-0.24621 1.4908,-0.78829 1.94103,-1.23149 0.46429,-0.46428 0.81251,-0.98134 1.04466,-1.55116 0.23214,-0.5698 0.33721,-0.99165 0.33722,-1.62479 0.0155,-0.43449 -0.28674,-1.22826 -0.57298,-1.8313 -0.26496,-0.55821 -0.52007,-1.02571 -0.52007,-1.02571 l -1.99277,2.29588 0.22983,-5.91917 5.5976,0.45081 -2.34283,1.96492 c 0,0 0.49752,1.04212 0.73633,1.68916 0.23881,0.64704 0.58739,1.34614 0.66973,2.19566 0.0366,0.62546 -0.16181,1.70241 -0.4854,2.4903 -0.33767,0.79493 -0.81956,1.50544 -1.44564,2.13152 -0.59093,0.58389 -1.53465,1.17717 -2.35067,1.54297" - style="fill:#333333" - id="path3002" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccscsccccczcccc" /> - </g> - <text - xml:space="preserve" - style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" - x="309.28571" - y="111.6479" - id="text3011" - sodipodi:linespacing="125%"><tspan - sodipodi:role="line" - id="tspan3013" - x="309.28571" - y="111.6479" /></text> - </g> -</svg> diff --git a/.config/emacs/lisp/evil/doc/make.bat b/.config/emacs/lisp/evil/doc/make.bat deleted file mode 100644 index 6247f7e..0000000 --- a/.config/emacs/lisp/evil/doc/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF
-
-pushd %~dp0
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set SOURCEDIR=source
-set BUILDDIR=build
-
-if "%1" == "" goto help
-
-%SPHINXBUILD% >NUL 2>NUL
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.http://sphinx-doc.org/
- exit /b 1
-)
-
-%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-goto end
-
-:help
-%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-
-:end
-popd
diff --git a/.config/emacs/lisp/evil/doc/requirements.txt b/.config/emacs/lisp/evil/doc/requirements.txt deleted file mode 100644 index 4e09d9c..0000000 --- a/.config/emacs/lisp/evil/doc/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Sphinx==7.3.7 -sphinx-rtd-theme==2.0.0 diff --git a/.config/emacs/lisp/evil/doc/source/_ext/elisp.py b/.config/emacs/lisp/evil/doc/source/_ext/elisp.py deleted file mode 100644 index ab82105..0000000 --- a/.config/emacs/lisp/evil/doc/source/_ext/elisp.py +++ /dev/null @@ -1,289 +0,0 @@ -import re -from os import path -import json - -from sphinx import addnodes -from sphinx.domains import Domain, ObjType, Index -from sphinx.domains.std import StandardDomain -from sphinx.directives import ObjectDescription -from sphinx.roles import XRefRole -from sphinx.util.nodes import make_refnode - - -with open(path.join(path.dirname(__file__), '..', '..', 'docstringdb.json')) as f: - DATA = json.load(f) - - -re_evilcode = re.compile(r"‘(evil-[^’]*)’") -re_code = re.compile(r"‘([^:][^ ’]*)’") -re_kwd = re.compile(r"‘(:[^’]*)’") -re_item = re.compile(r"([^\n])\n- ") -re_sexp = re.compile(r"\([A-Z \-\.‘’\[\]]+\)|[A-Z\-]+") -re_capitals = re.compile(r"[A-Z\-]+") -re_nonspace = re.compile(r"[^ ]") -re_signature = re.compile(r'\(fn (.*)\)') - -emphasis = [ - 'thing-at-point', -] - -def emacs_is_local(var): - return DATA[var]['local'] - -def emacs_default_value(var): - default = DATA[var]['default'] - tp = DATA[var]['default-type'] - if tp == 'string': - rep = repr(default)[1:-1] - return f'"{rep}"' - return str(default) - -def process_docstring(docstring, capitals=None): - # Remove explicit signature - docstring = re_signature.sub('', docstring) - - # Add code blocks to indented sections - def blockified_lines(lines): - in_block = False - for line in lines: - try: - indented = next(re_nonspace.finditer(line)).start(0) >= 4 - except StopIteration: - indented = None - if indented is True and not in_block: - yield '.. code-block:: elisp' - yield '' - in_block = True - elif indented is False: - in_block = False - yield line - docstring = '\n'.join(blockified_lines(docstring.split('\n'))) - - # Substitute `evil-alpha' with :elisp:ref:`evil-alpha` - docstring = re_evilcode.sub(r':elisp:ref:`\1`', docstring) - - # Substitute `alpha' with ``alpha`` - docstring = re_code.sub(r'``\1``', docstring) - - # Substitute `:alpha' with ``alpha`` - docstring = re_kwd.sub(r'``\1``', docstring) - - # Add empty line between list items - docstring = re_item.sub(r'\1\n\n- ', docstring) - - if capitals is None: - capitals = [] - else: - capitals = list(capitals) - - # Find things that look like sexps - def substitute_sexp(match): - s = match.group(0) - if re_capitals.match(s): - if s in capitals: - return f'*{s}*' - return s - else: - capitals.extend(re_capitals.findall(s)) - return f'``{s}``' - docstring = re_sexp.sub(substitute_sexp, docstring) - - # Italicize some words - for s in emphasis: - docstring = docstring.replace(s, f'*{s}*') - - return docstring - -def emacs_variable_docstring(var): - docstring = DATA[var]['var-docstring'] - return process_docstring(docstring) - -def emacs_function_docstring(var): - docstring = DATA[var]['fn-docstring'] - return process_docstring(docstring, capitals=emacs_argnames(var)) - -def emacs_argnames(var): - arglist = emacs_arglist(var) - return re_capitals.findall(arglist) - -def emacs_arglist(var): - docstring = DATA[var]['fn-docstring'] - match = re_signature.search(docstring) - if match: - return match.group(1) - - arglist = [arg.upper() for arg in DATA[var]['arglist']] - state = None - ret = '' - for arg in arglist: - if arg in ('&REST', '&OPTIONAL'): - if state == '&OPTIONAL': - ret += ']' - state = arg - ret += ' [' - continue - ret += ('' if state in ('&REST', '&OPTIONAL') else ' ') + arg - if state == '&OPTIONAL': - state += '-CONT' - if state is not None and state.startswith('&OPTIONAL'): - ret += ']' - if state == '&REST': - ret += '...]' - return ret - - -class AbstractElisp(ObjectDescription): - - def add_target_and_index(self, name, sig, signode): - anchor = f'elispobj-{sig}' - signode['ids'].append(anchor) - - objs = self.env.domaindata['elisp']['objects'] - objs[sig] = { - 'docname': self.env.docname, - 'anchor': f'elispobj-{sig}', - 'type': self.object_type, - } - - -class AbstractVariable(AbstractElisp): - object_type = 'variable' - - def handle_signature(self, sig, signode): - signode += addnodes.desc_annotation(sig, sig) - return sig - - def run(self): - extra = [] - - default = self.default_value() - if default: - extra.append(f'Default: ``{default}``') - if self.is_buffer_local(): - extra.append('buffer-local') - - self.content.data.extend(['', ', '.join(extra)]) - retval = super().run() - return retval - - -class Variable(AbstractVariable): - required_arguments = 1 - optional_arguments = 2 - - def default_value(self): - try: - return self.arguments[1] - except IndexError: - return None - - def is_buffer_local(self): - return 'bufloc' in self.arguments[1:] - - -class AutoVariable(AbstractVariable): - required_arguments = 1 - - def is_buffer_local(self): - return emacs_is_local(self.arguments[0]) - - def default_value(self): - return emacs_default_value(self.arguments[0]) - - def run(self): - docstring = emacs_variable_docstring(self.arguments[0]) - self.content.data.extend(docstring.split('\n')) - return super().run() - - -class AutoFunction(AbstractElisp): - required_arguments = 1 - - @property - def object_type(self): - return 'macro' if DATA[self.arguments[0]]['macrop'] else 'function' - - def handle_signature(self, sig, signode): - args = emacs_arglist(sig) - signode += addnodes.desc_annotation(sig, f'({sig} {args})') - return sig - - def run(self): - docstring = emacs_function_docstring(self.arguments[0]) - self.content.data.extend(docstring.split('\n')) - return super().run() - - -class ElispIndex(Index): - name = 'index' - localname = 'Emacs lisp functions and variables' - shortname = 'Elisp' - - def generate(self, docnames=None): - index = {} - for name, item in self.domain.data['objects'].items(): - if name.startswith('evil-'): - letter = name[5].upper() - else: - letter = name[0].upper() - index.setdefault(letter, []).append(( - name, - 0, - item['docname'], - item['anchor'], - item['type'], - '', - '', - )) - - index = {k: sorted(v, key=lambda k: k[0].lower()) for k, v in index.items()} - index = list(index.items()) - index = sorted(index, key=lambda k: k[0]) - return index, True - - -class Elisp(Domain): - name = 'elisp' - label = 'Emacs lisp' - - object_types = { - 'variable': ObjType('variable', 'variable', 'obj'), - 'autovariable': ObjType('autovariable', 'autovariable', 'obj'), - 'autofunction': ObjType('autofunction', 'autofunction', 'obj'), - } - - directives = { - 'variable': Variable, - 'autovariable': AutoVariable, - 'autofunction': AutoFunction, - } - - roles = { - 'ref': XRefRole(), - } - - initial_data = { - 'objects': {}, - } - - indices = { - ElispIndex, - } - - def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): - obj = self.data['objects'].get(target, None) - if obj is None: - return None - return make_refnode(builder, fromdocname, obj['docname'], obj['anchor'], contnode, obj['anchor']) - - -def setup(app): - app.add_domain(Elisp) - StandardDomain.initial_data['labels']['elispindex'] = ('elisp-index', '', 'Emacs lisp functions and variables') - StandardDomain.initial_data['anonlabels']['elispindex'] = ('elisp-index', '') - - return { - 'version': '0.1', - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/.config/emacs/lisp/evil/doc/source/conf.py b/.config/emacs/lisp/evil/doc/source/conf.py deleted file mode 100644 index 5b1b6f5..0000000 --- a/.config/emacs/lisp/evil/doc/source/conf.py +++ /dev/null @@ -1,85 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# - -import os, sys -sys.path.append(os.path.abspath("./_ext")) - - -# -- Project information ----------------------------------------------------- - -project = 'Evil' -copyright = '2011-2019, Eivind Fonn, Frank Fischer, Vegard Øye' -author = 'Eivind Fonn, Frank Fischer, Vegard Øye' - -# The full version, including alpha/beta/rc tags -release = '1.15.0' - -master_doc = 'index' - - -latex_elements = { - 'fontpkg': r'\usepackage{palatino} \usepackage{inconsolata}', - 'maketitle': r""" - \newcommand\sphinxbackoftitlepage{{ - Copyright {copyright}. - - \begin{{quote}} - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free Documentation License, - Version 1.3 or any later version published by the Free Software - Foundation; with no Invariant Sections, no Front-Cover Texts, - and no Back-Cover Texts. A copy of the license is included in - the section entitled ``GNU Free Documentation License''. - \end{{quote}} - - The Evil team thanks everyone at gmane.emacs.vim-emulation for - their feedback and contributions. - }} - \sphinxmaketitle - """.format(copyright=copyright), -} - - -texinfo_documents = [ - (master_doc, 'evil', 'Evil documentation', author, 'evil', - 'Extensible vi layer for Emacs', 'Emacs'), -] - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'elisp', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' diff --git a/.config/emacs/lisp/evil/doc/source/extension.rst b/.config/emacs/lisp/evil/doc/source/extension.rst deleted file mode 100644 index 444502f..0000000 --- a/.config/emacs/lisp/evil/doc/source/extension.rst +++ /dev/null @@ -1,146 +0,0 @@ -Extension -========= - -The main functionality of Evil is implemented in terms of reusable -macros. Package writers can use these to define new commands. - - -Motions -------- - -A *motion* is a command which moves the cursor, such as :kbd:`w` or -:kbd:`e`. Motions are defined with the macro -:elisp:ref:`evil-define-motion`. Motions not defined in this way -should be declared with :elisp:ref:`evil-declare-motion`. - -.. elisp:autofunction:: evil-declare-motion - -.. elisp:autofunction:: evil-define-motion - -For example, this is a motion that moves the cursor forward by a -number of characters: - -.. code-block:: elisp - - (evil-define-motion foo-forward (count) - "Move to the right by COUNT characters." - :type inclusive - (forward-char (or count 1))) - -The *type* of a motion determines how it works when used together with -an operator. Inclusive motions include the endpoint in the range -being operated on, while exclusive motions do not. Line motions -extend the whole range to linewise positions, effectively behaving as -if the endpoint were really at the end of the line. Blockwise ranges -behave as a "rectangle" on screen rather than a contiguous range of -characters. - - -Operators ---------- - -An operator is a command that acts on the text moved over by a motion, -such as :kbd:`c` (change), :kbd:`d` (delete) or :kbd:`y` (yank or -copy, not to be confused with "yank" in Emacs terminology which means -*paste*). - -.. elisp:autofunction:: evil-define-operator - -For example, this is an operator that performs ROT13 encryption on the -text under consideration: - -.. code-block:: elisp - - (evil-define-operator evil-rot13 (beg end) - "ROT13 encrypt text." - (rot13-region beg end)) - -Binding this to :kbd:`g?` (where it is by default) will cause a key -sequence such as :kbd:`g?w` to encrypt from the current cursor to the -end of the word. - - -Text objects ------------- - -Text objects are like motions in that they define a range over which -an operator may act. Unlike motions, text objects can set both a -beginning and an endpoint. In visual state, text objects alter both -ends of the selection. - -Text objects are not directly usable in normal state. Instead, they -are bound in the two keymaps ``evil-inner-text-ojects-map`` and -``evil-outer-text-objects-map``, which are available in visual and -operator-pending state under the keys :kbd:`i` and :kbd:`a` -respectively. - -.. elisp:autofunction:: evil-define-text-object - -For example, this is a text object which selects the next three -characters after the current location: - -.. code-block:: elisp - - (evil-define-text-object foo (count) - "Select three characters." - (list (point) (+ 3 (point)))) - -For convenience, Evil provides several functions returning a list of -positions which can be used for defining text objects. All of them -follow the convention that a positive *count* selects text after the -current location, while negative *count* selects text before it. - -.. note:: - - The *thingatpt* library is used quite extensively in Evil to define - text objects, and this dependency leaks through in the following - functions. A *thing* in this context is any symbol for which there - is a function called ``forward-THING`` [#thing]_ which moves past a - number of *things*. - -.. elisp:autofunction:: evil-select-inner-object - -.. elisp:autofunction:: evil-select-an-object - -.. elisp:autofunction:: evil-select-paren - - -Range types ------------ - -A *type* is a transformation acting on a pair of buffer positions. -Evil defines the types ``inclusive``, ``line``, ``block`` and -``exclusive``, which are used for motion ranges and visual selection. -New types may be defined with the macro *evil-define-type*. - -.. elisp:autofunction:: evil-define-type - - -States ------- - -States are defined with the macro :elisp:ref:`evil-define-state`, -which takes care to define the necessary hooks, keymaps and variables, -as well as a toggle function ``evil-NAME-state`` and a predicate -function ``evil-NAME-state-p`` for checking whether the state is -active. - -.. elisp:autofunction:: evil-define-state - -For example: - -.. code-block:: elisp - - (evil-define-state test - "Test state." - :tag " <T> " - (message (if (evil-test-state-p) - "Enabling test state." - "Disabling test state."))) - - -.. rubric:: Footnotes - -.. [#thing] There are many more ways that a *thing* can be defined, - but the definition of ``forward-THING`` is perhaps the most - straightforward way to go about it. diff --git a/.config/emacs/lisp/evil/doc/source/faq.rst b/.config/emacs/lisp/evil/doc/source/faq.rst deleted file mode 100644 index d389df0..0000000 --- a/.config/emacs/lisp/evil/doc/source/faq.rst +++ /dev/null @@ -1,118 +0,0 @@ -Frequently Asked Questions -========================== - -Problems with the escape key in the terminal --------------------------------------------- - -A common problem when using Evil in terminal mode is a certain delay -after pressing the escape key. Even more, when pressing the escape key -followed quickly by another key the command is recognized as -:kbd:`M-<key>` instead of two separate keys: :kbd:`ESC` followed by -:kbd:`<key>`. In fact, it is perfectly valid to simulate -:kbd:`M-<key>` by pressing :kbd:`ESC <key>` quickly (but see below). - -The reason for this is that in terminal mode a key sequence involving -the meta key (or alt key) always generates a so called "escape -sequence", i.e. a sequence of two events sent to Emacs, the first -being :kbd:`ESC` and the second the key pressed simultaneously. The -problem is that pressing the escape key itself also generates the -:kbd:`ESC` event. Thus, if Emacs (and therefore Evil) receives an -:kbd:`ESC` event there is no way to tell whether the escape key has -been pressed (and no further event will arrive) or a :kbd:`M-<key>` -combination has been pressed (and the :kbd:`<key>` event will arrive -soon). In order to distinguish both situations Evil does the -following. After receiving an :kbd:`ESC` event Evil waits for a short -time period (specified by the variable :elisp:ref:`evil-esc-delay` -which defaults to 0.01 seconds) for another event. If no other event -arrives Evil assumes that the plain escape key has been pressed, -otherwise it assumes a :kbd:`M-<key>` combination has been pressed and -combines the :kbd:`ESC` event with the second one. Because a -:kbd:`M-<key>` sequence usually generates both events in very quick -succession, 0.01 seconds are usually enough and the delay is hardly -noticeable by the user. - -If you use a terminal multiplexer like *tmux* or *screen* the -situation may be worse. These multiplexers have exactly the same -problem recognizing :kbd:`M-<key>` sequences and often introduce their -own delay for the :kbd:`ESC` key. There is no way for Evil to -influence this delay. In order to reduce it you must reconfigure your -terminal multiplexer. - -Note that this problem should not arise when using Evil in graphical -mode. The reason is that in this case the escape key itself generates -a different command, namely ``escape`` (a symbol) and hence Evil can -distinguish whether the escape key or a :kbd:`M-<key>` combination has -been pressed. But this also implies that pressing :kbd:`ESC` followed -by <key> cannot be used to simulate :kbd:`M-<key>` in graphical mode! - - -Underscore is not a word character ----------------------------------- - -An underscore ``_`` is a word character in Vim. This means that word -motions like :kbd:`w` skip over underlines in a sequence of letters as -if it was a letter itself. In contrast, in Evil the underscore is -often a non-word character like operators, e.g. ``+``. - -The reason is that Evil uses Emacs' definition of a word and this -definition does often not include the underscore. In Emacs word -characters are determined by the syntax-class of the buffer. The -syntax-class usually depends on the major-mode of this buffer. This -has the advantage that the definition of a "word" may be adapted to -the particular type of document being edited. Evil uses Emacs' -definition and does not simply use Vim's definition in order to be -consistent with other Emacs functions. For example, word characters -are exactly those characters that are matched by the regular -expression character class ``[:word:]``. - -If you would be satisfied by having the :kbd:`*` and :kbd:`#` searches -use symbols instead of words, this can be achieved by setting the -:elisp:ref:`evil-symbol-word-search` variable to ``t``. - -If you want the underscore to be recognised as word character for other -motions, you can modify its entry in the syntax-table: - -.. code-block:: elisp - - (modify-syntax-entry ?_ "w") - -This gives the underscore the 'word' syntax class. You can use a -mode-hook to modify the syntax-table in all buffers of some mode, -e.g.: - -.. code-block:: elisp - - (add-hook 'c-mode-common-hook - (lambda () (modify-syntax-entry ?_ "w"))) - -This gives the underscore the word syntax-class in all C-like buffers. - -Similarly to Emacs' definition of a word, the definition of a "symbol" is also -dependent on the syntax-class of the buffer, which often includes the -underscore. The default text objects keymap associates kbd::`o` with the symbol -object, making kbd::`cio` a good alternative to Vim's kbd::`ciw`, for example. -The following will swap between the word and symbol objects in the keymap: - -.. code-block:: elisp - - (define-key evil-outer-text-objects-map "w" 'evil-a-symbol) - (define-key evil-inner-text-objects-map "w" 'evil-inner-symbol) - (define-key evil-outer-text-objects-map "o" 'evil-a-word) - (define-key evil-inner-text-objects-map "o" 'evil-inner-word) - -This will not change the motion keys, however. One way to make word motions -operate as symbol motions is to alias the ``evil-word`` *thing* [#thingatpt]_ to -the ``evil-symbol`` thing: - -.. code-block:: elisp - - (defalias 'forward-evil-word 'forward-evil-symbol) - - -.. rubric:: Footnotes - -.. [#thingatpt] Many of Evil's text objects and motions are defined in - terms of the *thingatpt* library, which in this case are defined - entirely in terms of ``forward-THING`` functions. Thus aliasing - one to another should make all motions and text objects implemented - in terms of that *thing* behave the same. diff --git a/.config/emacs/lisp/evil/doc/source/hooks.rst b/.config/emacs/lisp/evil/doc/source/hooks.rst deleted file mode 100644 index 28ade72..0000000 --- a/.config/emacs/lisp/evil/doc/source/hooks.rst +++ /dev/null @@ -1,16 +0,0 @@ -Hooks -===== - -A *hook* is a list of functions that are executed when certain events -happen. Hooks are modified with the Emacs function ``add-hook``. -Evil provides entry and exit hooks for all its states. For example, -when switching from normal state to insert state, all functions in -``evil-normal-state-exit-hook`` and ``evil-insert-state-entry-hook`` -are executed. - -It is guaranteed that the exit hook will be executed before the entry -hook on all state switches. - -During the hook execution, the variables ``evil-next-state`` and -``evil-previous-state`` contain information about the states being -switched to and from, respectively. diff --git a/.config/emacs/lisp/evil/doc/source/index.rst b/.config/emacs/lisp/evil/doc/source/index.rst deleted file mode 100644 index 95da7b7..0000000 --- a/.config/emacs/lisp/evil/doc/source/index.rst +++ /dev/null @@ -1,21 +0,0 @@ -.. Evil documentation master file, created by - sphinx-quickstart on Thu Dec 12 10:34:49 2019. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Evil -==== - -.. toctree:: - :maxdepth: 2 - :caption: Contents - - overview - settings - keymaps - hooks - extension - faq - internals - license - indices diff --git a/.config/emacs/lisp/evil/doc/source/indices.rst b/.config/emacs/lisp/evil/doc/source/indices.rst deleted file mode 100644 index 46f687e..0000000 --- a/.config/emacs/lisp/evil/doc/source/indices.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. only:: html - - Index - ===== - - - :ref:`elispindex` diff --git a/.config/emacs/lisp/evil/doc/source/internals.rst b/.config/emacs/lisp/evil/doc/source/internals.rst deleted file mode 100644 index 9984f7c..0000000 --- a/.config/emacs/lisp/evil/doc/source/internals.rst +++ /dev/null @@ -1,36 +0,0 @@ -Internals -========= - -Command properties ------------------- - -Evil defines *command properties* to store information about commands -[#command]_, such as whether they should be repeated. A command -property is a ``:keyword`` with an associated value, e.g. -``:repeat nil``. - -.. elisp:autofunction:: evil-add-command-properties - -.. elisp:autofunction:: evil-set-command-properties - -.. elisp:autofunction:: evil-get-command-properties - -.. elisp:autofunction:: evil-get-command-property - -.. elisp:autofunction:: evil-define-command - - -For setting repeat properties, use the following functions: - -.. elisp:autofunction:: evil-declare-repeat - -.. elisp:autofunction:: evil-declare-not-repeat - -.. elisp:autofunction:: evil-declare-change-repeat - - -.. rubric:: Footnotes - -.. [#command] In this context, a *command* may mean any Evil motion, - text object, operator or indeed other Emacs commands, which have - not been defined through the Evil machinery. diff --git a/.config/emacs/lisp/evil/doc/source/keymaps.rst b/.config/emacs/lisp/evil/doc/source/keymaps.rst deleted file mode 100644 index 36f8141..0000000 --- a/.config/emacs/lisp/evil/doc/source/keymaps.rst +++ /dev/null @@ -1,145 +0,0 @@ -.. _chapter-keymaps: - -Keymaps -======= - -Evil's key bindings are stored in a number of different keymaps. Each -state has a *global keymap*, where the default bindings for that state -are stored. They are named ``evil-normal-state-map``, -``evil-insert-state-map``, and so on. The bindings in these maps are -visible in all buffers currently in the corresponding state. - -These keymaps function like ordinary Emacs keymaps and may be modified -using the Emacs function ``define-key``: - -.. code-block:: elisp - - (define-key evil-normal-state-map (kbd "w") 'some-function) - -This binds the key :kbd:`w` to the command ``some-function`` in normal -state. The use of ``kbd`` is optional for simple key sequences, like -this one, but recommended in general. - -Most of Evil's bindings are defined in the file ``evil-maps.el``. - -To facilitate shared keybindings between states, some states may -activate keybindings from other states as well. For example, motion -state bindings are visible in normal and visual state, and normal -state bindings are also visible in visual state. - -Each state also has a *buffer-local keymap* which is specific to the -current buffer, and which takes precedence over the global keymap. -These maps are most suitably modified by a mode hook. They are named -``evil-normal-state-local-map``, ``evil-insert-state-local-map``, and -so on. - -.. code-block:: elisp - - (add-hook 'some-mode-hook - (lambda () - (define-key evil-normal-state-local-map - (kbd "w") 'some-function))) - -For convenience, the functions :elisp:ref:`evil-global-set-key` and -:elisp:ref:`evil-local-set-key` are available for setting global and -local state keys. - -.. elisp:autofunction:: evil-global-set-key - -.. elisp:autofunction:: evil-local-set-key - -The above examples could therefore have been written as follows: - -.. code-block:: elisp - - (evil-global-set-key 'normal (kbd "w") 'some-function) - - (add-hook 'some-mode-hook - (lambda () - (evil-local-set-key 'normal (kbd "w") 'some-function))) - - -evil-define-key ---------------- - -Evil provides the macro :elisp:ref:`evil-define-key` for adding state -bindings to ordinary keymaps. It is quite powerful, and is the -preferred method for fine-tuning bindings to activate in specific -circumstances. - -.. elisp:autofunction:: evil-define-key - -There follows a brief overview of the main functions of this macro. - -- Define a binding in a given state - - .. code-block:: elisp - - (evil-define-key 'state 'global (kbd "key") 'target) - -- Define a binding in a given state in the current buffer - - .. code-block:: elisp - - (evil-define-key 'state 'local (kbd "key") 'target) - -- Define a binding in a given state under the *foo-mode* major mode. - - .. code-block:: elisp - - (evil-define-key 'state foo-mode-map (kbd "key") 'target) - - Note that ``foo-mode-map`` is unquoted, and that this form is safe - before ``foo-mode-map`` is loaded. - -- Define a binding in a given state under the *bar-mode* minor mode. - - .. code-block:: elisp - - (evil-define-key 'state 'bar-mode (kbd "key") 'target) - - Note that ``bar-mode`` is quoted, and that this form is safe before - ``bar-mode`` is loaded. - - -The macro :elisp:ref:`evil-define-key` can be used to augment existing -modes with state bindings, as well as creating packages with custom -bindings. For example, the following will create a minor mode -``foo-mode`` with normal state bindings for the keys :kbd:`w` and -:kbd:`e`: - -.. code-block:: elisp - - (define-minor-mode foo-mode - "Foo mode." - :keymap (make-sparse-keymap)) - - (evil-define-key 'normal 'foo-mode "w" 'bar) - (evil-define-key 'normal 'foo-mode "e" 'baz) - -This minor mode can then be enabled in any buffers where the custom -bindings are desired: - -.. code-block:: elisp - - (add-hook 'text-mode-hook 'foo-mode) ; enable alongside text-mode - - -Leader keys ------------ - -Evil supports a simple implementation of Vim's *leader* keys. To bind -a function to a leader key you can use the expression ``<leader>`` in -a key mapping, e.g. - -.. code-block:: elisp - - (evil-define-key 'normal 'global (kbd "<leader>fs") 'save-buffer) - -Likewise, you can use the expression ``<localleader>`` to mimic Vim's -local leader, which is designed for mode-specific key bindings. - -You can use the function :elisp:ref:`evil-set-leader` to designate -which key acts as the leader and the local leader. - -.. elisp:autofunction:: evil-set-leader diff --git a/.config/emacs/lisp/evil/doc/source/license.rst b/.config/emacs/lisp/evil/doc/source/license.rst deleted file mode 100644 index 39d6701..0000000 --- a/.config/emacs/lisp/evil/doc/source/license.rst +++ /dev/null @@ -1,447 +0,0 @@ -The GNU Free Documentation License -================================== - -Version 1.3, 3 November 2008 - - Copyright (c) 2000, 2001, 2002, 2007, 2008 Free Software - Foundation, Inc. http://fsf.org/ - - Everyone is permitted to copy and distribute verbatim copies of - this license document, but changing it is not allowed. - - -0. PREAMBLE - - The purpose of this License is to make a manual, textbook, or other - functional and useful document *free* in the sense of freedom: to - assure everyone the effective freedom to copy and redistribute it, - with or without modifying it, either commercially or - noncommercially. Secondarily, this License preserves for the - author and publisher a way to get credit for their work, while not - being considered responsible for modifications made by others. - - This License is a kind of "copyleft", which means that derivative - works of the document must themselves be free in the same sense. - It complements the GNU General Public License, which is a copyleft - license designed for free software. - - We have designed this License in order to use it for manuals for - free software, because free software needs free documentation: a - free program should come with manuals providing the same freedoms - that the software does. But this License is not limited to - software manuals; it can be used for any textual work, regardless - of subject matter or whether it is published as a printed book. We - recommend this License principally for works whose purpose is - instruction or reference. - -1. APPLICABILITY AND DEFINITIONS - - This License applies to any manual or other work, in any medium, - that contains a notice placed by the copyright holder saying it can - be distributed under the terms of this License. Such a notice - grants a world-wide, royalty-free license, unlimited in duration, - to use that work under the conditions stated herein. The - "Document", below, refers to any such manual or work. Any member - of the public is a licensee, and is addressed as "you". You accept - the license if you copy, modify or distribute the work in a way - requiring permission under copyright law. - - A "Modified Version" of the Document means any work containing the - Document or a portion of it, either copied verbatim, or with - modifications and/or translated into another language. - - A "Secondary Section" is a named appendix or a front-matter section - of the Document that deals exclusively with the relationship of the - publishers or authors of the Document to the Document's overall - subject (or to related matters) and contains nothing that could - fall directly within that overall subject. (Thus, if the Document - is in part a textbook of mathematics, a Secondary Section may not - explain any mathematics.) The relationship could be a matter of - historical connection with the subject or with related matters, or - of legal, commercial, philosophical, ethical or political position - regarding them. - - The "Invariant Sections" are certain Secondary Sections whose - titles are designated, as being those of Invariant Sections, in the - notice that says that the Document is released under this License. - If a section does not fit the above definition of Secondary then it - is not allowed to be designated as Invariant. The Document may - contain zero Invariant Sections. If the Document does not identify - any Invariant Sections then there are none. - - The "Cover Texts" are certain short passages of text that are - listed, as Front-Cover Texts or Back-Cover Texts, in the notice - that says that the Document is released under this License. A - Front-Cover Text may be at most 5 words, and a Back-Cover Text may - be at most 25 words. - - A "Transparent" copy of the Document means a machine-readable copy, - represented in a format whose specification is available to the - general public, that is suitable for revising the document - straightforwardly with generic text editors or (for images composed - of pixels) generic paint programs or (for drawings) some widely - available drawing editor, and that is suitable for input to text - formatters or for automatic translation to a variety of formats - suitable for input to text formatters. A copy made in an otherwise - Transparent file format whose markup, or absence of markup, has - been arranged to thwart or discourage subsequent modification by - readers is not Transparent. An image format is not Transparent if - used for any substantial amount of text. A copy that is not - "Transparent" is called "Opaque". - - Examples of suitable formats for Transparent copies include plain - ASCII without markup, Texinfo input format, LaTeX input format, - SGML or XML using a publicly available DTD, and standard-conforming - simple HTML, PostScript or PDF designed for human modification. - Examples of transparent image formats include PNG, XCF and JPG. - Opaque formats include proprietary formats that can be read and - edited only by proprietary word processors, SGML or XML for which - the DTD and/or processing tools are not generally available, and - the machine-generated HTML, PostScript or PDF produced by some word - processors for output purposes only. - - The "Title Page" means, for a printed book, the title page itself, - plus such following pages as are needed to hold, legibly, the - material this License requires to appear in the title page. For - works in formats which do not have any title page as such, "Title - Page" means the text near the most prominent appearance of the - work's title, preceding the beginning of the body of the text. - - The "publisher" means any person or entity that distributes copies - of the Document to the public. - - A section "Entitled XYZ" means a named subunit of the Document - whose title either is precisely XYZ or contains XYZ in parentheses - following text that translates XYZ in another language. (Here XYZ - stands for a specific section name mentioned below, such as - "Acknowledgements", "Dedications", "Endorsements", or "History".) - To "Preserve the Title" of such a section when you modify the - Document means that it remains a section "Entitled XYZ" according - to this definition. - - The Document may include Warranty Disclaimers next to the notice - which states that this License applies to the Document. These - Warranty Disclaimers are considered to be included by reference in - this License, but only as regards disclaiming warranties: any other - implication that these Warranty Disclaimers may have is void and - has no effect on the meaning of this License. - -2. VERBATIM COPYING - - You may copy and distribute the Document in any medium, either - commercially or noncommercially, provided that this License, the - copyright notices, and the license notice saying this License - applies to the Document are reproduced in all copies, and that you - add no other conditions whatsoever to those of this License. You - may not use technical measures to obstruct or control the reading - or further copying of the copies you make or distribute. However, - you may accept compensation in exchange for copies. If you - distribute a large enough number of copies you must also follow the - conditions in section 3. - - You may also lend copies, under the same conditions stated above, - and you may publicly display copies. - -3. COPYING IN QUANTITY - - If you publish printed copies (or copies in media that commonly - have printed covers) of the Document, numbering more than 100, and - the Document's license notice requires Cover Texts, you must - enclose the copies in covers that carry, clearly and legibly, all - these Cover Texts: Front-Cover Texts on the front cover, and - Back-Cover Texts on the back cover. Both covers must also clearly - and legibly identify you as the publisher of these copies. The - front cover must present the full title with all words of the title - equally prominent and visible. You may add other material on the - covers in addition. Copying with changes limited to the covers, as - long as they preserve the title of the Document and satisfy these - conditions, can be treated as verbatim copying in other respects. - - If the required texts for either cover are too voluminous to fit - legibly, you should put the first ones listed (as many as fit - reasonably) on the actual cover, and continue the rest onto - adjacent pages. - - If you publish or distribute Opaque copies of the Document - numbering more than 100, you must either include a machine-readable - Transparent copy along with each Opaque copy, or state in or with - each Opaque copy a computer-network location from which the general - network-using public has access to download using public-standard - network protocols a complete Transparent copy of the Document, free - of added material. If you use the latter option, you must take - reasonably prudent steps, when you begin distribution of Opaque - copies in quantity, to ensure that this Transparent copy will - remain thus accessible at the stated location until at least one - year after the last time you distribute an Opaque copy (directly or - through your agents or retailers) of that edition to the public. - - It is requested, but not required, that you contact the authors of - the Document well before redistributing any large number of copies, - to give them a chance to provide you with an updated version of the - Document. - -4. MODIFICATIONS - - You may copy and distribute a Modified Version of the Document - under the conditions of sections 2 and 3 above, provided that you - release the Modified Version under precisely this License, with the - Modified Version filling the role of the Document, thus licensing - distribution and modification of the Modified Version to whoever - possesses a copy of it. In addition, you must do these things in - the Modified Version: - - A. Use in the Title Page (and on the covers, if any) a title - distinct from that of the Document, and from those of previous - versions (which should, if there were any, be listed in the - History section of the Document). You may use the same title as - a previous version if the original publisher of that version - gives permission. - - B. List on the Title Page, as authors, one or more persons or - entities responsible for authorship of the modifications in the - Modified Version, together with at least five of the principal - authors of the Document (all of its principal authors, if it has - fewer than five), unless they release you from this requirement. - - C. State on the Title page the name of the publisher of the - Modified Version, as the publisher. - - D. Preserve all the copyright notices of the Document. - - E. Add an appropriate copyright notice for your modifications - adjacent to the other copyright notices. - - F. Include, immediately after the copyright notices, a license - notice giving the public permission to use the Modified Version - under the terms of this License, in the form shown in the - Addendum below. - - G. Preserve in that license notice the full lists of Invariant - Sections and required Cover Texts given in the Document's - license notice. - - H. Include an unaltered copy of this License. - - I. Preserve the section Entitled "History", Preserve its Title, and - add to it an item stating at least the title, year, new authors, - and publisher of the Modified Version as given on the Title - Page. If there is no section Entitled "History" in the - Document, create one stating the title, year, authors, and - publisher of the Document as given on its Title Page, then add - an item describing the Modified Version as stated in the - previous sentence. - - J. Preserve the network location, if any, given in the Document for - public access to a Transparent copy of the Document, and - likewise the network locations given in the Document for - previous versions it was based on. These may be placed in the - "History" section. You may omit a network location for a work - that was published at least four years before the Document - itself, or if the original publisher of the version it refers to - gives permission. - - K. For any section Entitled "Acknowledgements" or "Dedications", - Preserve the Title of the section, and preserve in the section - all the substance and tone of each of the contributor - acknowledgements and/or dedications given therein. - - L. Preserve all the Invariant Sections of the Document, unaltered - in their text and in their titles. Section numbers or the - equivalent are not considered part of the section titles. - - M. Delete any section Entitled "Endorsements". Such a section may - not be included in the Modified Version. - - N. Do not retitle any existing section to be Entitled - "Endorsements" or to conflict in title with any Invariant - Section. - - O. Preserve any Warranty Disclaimers. - - If the Modified Version includes new front-matter sections or - appendices that qualify as Secondary Sections and contain no - material copied from the Document, you may at your option designate - some or all of these sections as invariant. To do this, add their - titles to the list of Invariant Sections in the Modified Version's - license notice. These titles must be distinct from any other - section titles. - - You may add a section Entitled "Endorsements", provided it contains - nothing but endorsements of your Modified Version by various - parties---for example, statements of peer review or that the text - has been approved by an organization as the authoritative - definition of a standard. - - You may add a passage of up to five words as a Front-Cover Text, - and a passage of up to 25 words as a Back-Cover Text, to the end of - the list of Cover Texts in the Modified Version. Only one passage - of Front-Cover Text and one of Back-Cover Text may be added by (or - through arrangements made by) any one entity. If the Document - already includes a cover text for the same cover, previously added - by you or by arrangement made by the same entity you are acting on - behalf of, you may not add another; but you may replace the old - one, on explicit permission from the previous publisher that added - the old one. - - The author(s) and publisher(s) of the Document do not by this - License give permission to use their names for publicity for or to - assert or imply endorsement of any Modified Version. - -5. COMBINING DOCUMENTS - - You may combine the Document with other documents released under - this License, under the terms defined in section 4 above for - modified versions, provided that you include in the combination all - of the Invariant Sections of all of the original documents, - unmodified, and list them all as Invariant Sections of your - combined work in its license notice, and that you preserve all - their Warranty Disclaimers. - - The combined work need only contain one copy of this License, and - multiple identical Invariant Sections may be replaced with a single - copy. If there are multiple Invariant Sections with the same name - but different contents, make the title of each such section unique - by adding at the end of it, in parentheses, the name of the - original author or publisher of that section if known, or else a - unique number. Make the same adjustment to the section titles in - the list of Invariant Sections in the license notice of the - combined work. - - In the combination, you must combine any sections Entitled - "History" in the various original documents, forming one section - Entitled "History"; likewise combine any sections Entitled - "Acknowledgements", and any sections Entitled "Dedications". You - must delete all sections Entitled "Endorsements." - -6. COLLECTIONS OF DOCUMENTS - - You may make a collection consisting of the Document and other - documents released under this License, and replace the individual - copies of this License in the various documents with a single copy - that is included in the collection, provided that you follow the - rules of this License for verbatim copying of each of the documents - in all other respects. - - You may extract a single document from such a collection, and - distribute it individually under this License, provided you insert - a copy of this License into the extracted document, and follow this - License in all other respects regarding verbatim copying of that - document. - -7. AGGREGATION WITH INDEPENDENT WORKS - - A compilation of the Document or its derivatives with other - separate and independent documents or works, in or on a volume of a - storage or distribution medium, is called an "aggregate" if the - copyright resulting from the compilation is not used to limit the - legal rights of the compilation's users beyond what the individual - works permit. When the Document is included in an aggregate, this - License does not apply to the other works in the aggregate which - are not themselves derivative works of the Document. - - If the Cover Text requirement of section 3 is applicable to these - copies of the Document, then if the Document is less than one half - of the entire aggregate, the Document's Cover Texts may be placed - on covers that bracket the Document within the aggregate, or the - electronic equivalent of covers if the Document is in electronic - form. Otherwise they must appear on printed covers that bracket - the whole aggregate. - -8. TRANSLATION - - Translation is considered a kind of modification, so you may - distribute translations of the Document under the terms of - section 4. Replacing Invariant Sections with translations requires - special permission from their copyright holders, but you may - include translations of some or all Invariant Sections in addition - to the original versions of these Invariant Sections. You may - include a translation of this License, and all the license notices - in the Document, and any Warranty Disclaimers, provided that you - also include the original English version of this License and the - original versions of those notices and disclaimers. In case of a - disagreement between the translation and the original version of - this License or a notice or disclaimer, the original version will - prevail. - - If a section in the Document is Entitled "Acknowledgements", - "Dedications", or "History", the requirement (section 4) to - Preserve its Title (section 1) will typically require changing the - actual title. - -9. TERMINATION - - You may not copy, modify, sublicense, or distribute the Document - except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense, or distribute it is void, - and will automatically terminate your rights under this License. - - However, if you cease all violation of this License, then your - license from a particular copyright holder is reinstated (a) - provisionally, unless and until the copyright holder explicitly and - finally terminates your license, and (b) permanently, if the - copyright holder fails to notify you of the violation by some - reasonable means prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is - reinstated permanently if the copyright holder notifies you of the - violation by some reasonable means, this is the first time you have - received notice of violation of this License (for any work) from - that copyright holder, and you cure the violation prior to 30 days - after your receipt of the notice. - - Termination of your rights under this section does not terminate - the licenses of parties who have received copies or rights from you - under this License. If your rights have been terminated and not - permanently reinstated, receipt of a copy of some or all of the - same material does not give you any rights to use it. - -10. FUTURE REVISIONS OF THIS LICENSE - - The Free Software Foundation may publish new, revised versions of - the GNU Free Documentation License from time to time. Such new - versions will be similar in spirit to the present version, but may - differ in detail to address new problems or concerns. See - http://www.gnu.org/copyleft. - - Each version of the License is given a distinguishing version - number. If the Document specifies that a particular numbered - version of this License "or any later version" applies to it, you - have the option of following the terms and conditions either of - that specified version or of any later version that has been - published (not as a draft) by the Free Software Foundation. If the - Document does not specify a version number of this License, you may - choose any version ever published (not as a draft) by the Free - Software Foundation. If the Document specifies that a proxy can - decide which future versions of this License can be used, that - proxy's public statement of acceptance of a version permanently - authorizes you to choose that version for the Document. - -11. RELICENSING - - "Massive Multiauthor Collaboration Site" (or "MMC Site") means any - World Wide Web server that publishes copyrightable works and also - provides prominent facilities for anybody to edit those works. A - public wiki that anybody can edit is an example of such a server. - A "Massive Multiauthor Collaboration" (or "MMC") contained in the - site means any set of copyrightable works thus published on the MMC - site. - - "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 - license published by Creative Commons Corporation, a not-for-profit - corporation with a principal place of business in San Francisco, - California, as well as future copyleft versions of that license - published by that same organization. - - "Incorporate" means to publish or republish a Document, in whole or - in part, as part of another Document. - - An MMC is "eligible for relicensing" if it is licensed under this - License, and if all works that were first published under this - License somewhere other than this MMC, and subsequently - incorporated in whole or in part into the MMC, (1) had no cover - texts or invariant sections, and (2) were thus incorporated prior - to November 1, 2008. - - The operator of an MMC Site may republish an MMC contained in the - site under CC-BY-SA on the same site at any time before August 1, - 2009, provided the MMC is eligible for relicensing. diff --git a/.config/emacs/lisp/evil/doc/source/overview.rst b/.config/emacs/lisp/evil/doc/source/overview.rst deleted file mode 100644 index 96af183..0000000 --- a/.config/emacs/lisp/evil/doc/source/overview.rst +++ /dev/null @@ -1,117 +0,0 @@ -Overview -======== - -Evil is an extensible vi layer for Emacs. It emulates the main -features of Vim, [#vim]_ turning Emacs into a modal editor. Like Emacs in -general, Evil is extensible in Emacs Lisp. - - -Installation via package.el ---------------------------- - -Evil is available as a package from MELPA stable, MELPA unstable and -NonGNU ELPA. This is the recommended way of installing Evil. - -To set up `package.el` to work with one of the MELPA repositories, you -can follow the instructions on `melpa.org -<https://melpa.org/#/getting-started>`_. - -Alternatively you can use NonGNU ELPA. It is part of the default -package archives as of Emacs 28. For older Emacs versions you'll need -to add it yourself: - -.. code-block:: elisp - - (add-to-list 'package-archives - (cons "nongnu" (format "http%s://elpa.nongnu.org/nongnu/" - (if (gnutls-available-p) "s" "")))) - -Once that is done, you can execute the following commands:: - - M-x package-refresh-contents - M-x package-install RET evil RET - -Finally, add the following lines to your Emacs init file: - -.. code-block:: elisp - - (require 'evil) - (evil-mode 1) - - -Manual installation -------------------- - -First, install `goto-chg` and `cl-lib`. If you have an Emacs version -of 24.3 or newer, you should already have `cl-lib`. - -Evil lives in a git repository. To download Evil, do:: - - git clone --depth 1 https://github.com/emacs-evil/evil.git - -Then add the following lines to your Emacs init file: - -.. code-block:: elisp - - (add-to-list 'load-path "path/to/evil") - (require 'evil) - (evil-mode 1) - -Ensure that your replace ``path/to/evil`` with the actual path to -where you cloned Evil. - - -Modes and states ----------------- - -The next time Emacs is started, it will come up in *normal state*, -denoted by ``<N>`` in the mode line. This is where the main vi -bindings are defined. Note that you can always disable normal state -with :kbd:`C-z`, which switches to an "Emacs state" (denoted by -``<E>``) in which vi keys are completely disabled. Press :kbd:`C-z` -again to switch back to normal state. - -state - Evil uses the term *state* for what is called a "mode" in regular vi - usage, because *modes* are understood in Emacs terms to mean - something else. - -Evil defines a number of states by default: - -normal state (``<N>``) - This is the default "resting state" of Evil, in which the main body - of vi bindings are defined. - -insert state (``<I>``) - This is the state for insertion of text, where non-modified keys - will insert the corresponding character in the buffer. - -visual state (``<V>``) - A state for selecting text regions. Motions are available for - modifying the selected region, and operators are available for - acting on it. - -replace state (``<R>``) - A special state mostly similar to insert state, except it replaces - text instead of inserting. - -operator-pending state (``<O>``) - A special state entered after launching an operator, but before - specifying the corresponding motion or text object. - -motion state (``<M>``) - A special state useful for buffers that are read-only, where motions - are available but editing operations are not. - -Emacs state (``<E>``) - A state that as closely as possible mimics default Emacs behaviour, - by eliminating all vi bindings, except for :kbd:`C-z`, to re-enter - normal state. - - -.. rubric:: Footnotes - -.. [#vim] Vim is the most popular version of *vi*, a modal text editor - with many implementations. Vim also adds some functions of its - own, like visual selection and text objects. For more information - see `the official Vim website <https://www.vim.org>`_. diff --git a/.config/emacs/lisp/evil/doc/source/settings.rst b/.config/emacs/lisp/evil/doc/source/settings.rst deleted file mode 100644 index 8ca78e6..0000000 --- a/.config/emacs/lisp/evil/doc/source/settings.rst +++ /dev/null @@ -1,199 +0,0 @@ -Settings -======== - -Evil's behaviour can be adjusted by setting some variables. The list -of all available variables and their current values can be inspected -by doing:: - - M-x customize-group RET evil RET - -To change the value of a variable, you can use this interface, or add -a ``setq`` form to your Emacs init file, preferably before Evil is -loaded. [#order]_ - -.. code-block:: elisp - - (setq evil-shift-width 0) - ;; Load Evil - (require 'evil) - -What follows is a non-exhaustive list of the most relevant -customization options. - - -The initial state ------------------ - -The initial state of a buffer is determined by its major mode. Evil -maintains an association between major modes and their corresponding -states, which is most easily modified using the function -:elisp:ref:`evil-set-initial-state`. - -.. elisp:autofunction:: evil-set-initial-state - -If no state can be found, Evil uses the default initial state. - -.. elisp:autovariable:: evil-default-state - -Alternatively, it is possible to select the initial state based on the -buffer *name* rather than its major mode. This is checked first, so -it takes precedence over the other methods for setting the state. - -.. elisp:autovariable:: evil-buffer-regexps - - -Keybindings and other behaviour -------------------------------- - -Evil comes with a rich system for modifying its key bindings -:ref:`chapter-keymaps`. For the most common tweaks, the following -variables are available. - -.. elisp:autovariable:: evil-toggle-key - -.. elisp:autovariable:: evil-want-C-i-jump - -.. elisp:autovariable:: evil-want-C-u-delete - -.. elisp:autovariable:: evil-want-C-u-scroll - -.. elisp:autovariable:: evil-want-C-d-scroll - -.. elisp:autovariable:: evil-want-C-w-delete - -.. elisp:autovariable:: evil-want-C-w-in-emacs-state - -.. elisp:autovariable:: evil-want-Y-yank-to-eol - -.. elisp:autovariable:: evil-disable-insert-state-bindings - - -Search ------- - -.. elisp:autovariable:: evil-search-module - -.. elisp:autovariable:: evil-regexp-search - -.. elisp:autovariable:: evil-search-wrap - -.. elisp:autovariable:: evil-flash-delay - -.. elisp:autovariable:: evil-ex-hl-update-delay - -.. elisp:autovariable:: evil-ex-search-incremental - - -Indentation ------------ - -.. elisp:autovariable:: evil-auto-indent - -.. elisp:autovariable:: evil-shift-width - -.. elisp:autovariable:: evil-shift-round - -.. elisp:autovariable:: evil-indent-convert-tabs - - -Cursor movement ---------------- - -In standard Emacs terms, the cursor is generally understood to be -located between two characters. In Vim, and therefore also Evil, this -is the case in insert state, but in other states the cursor is -understood to be *on* a character, and that this character is not a -newline. - -Forcing this behaviour in Emacs is the source of some potentially -surprising results (especially for traditional Emacs users---users -used to Vim may find the default behavior to their satisfaction). Many -of them can be tweaked using the following variables. - -.. elisp:autovariable:: evil-repeat-move-cursor - -.. elisp:autovariable:: evil-move-cursor-back - -.. elisp:autovariable:: evil-move-beyond-eol - -.. elisp:autovariable:: evil-v$-excludes-newline - -.. elisp:autovariable:: evil-cross-lines - -.. elisp:autovariable:: evil-respect-visual-line-mode - -.. elisp:autovariable:: evil-track-eol - -.. elisp:autovariable:: evil-start-of-line - - -Cursor display --------------- - -A state may change the appearance of the cursor. Use the variable -:elisp:ref:`evil-default-cursor` to set the default cursor, and the -variables ``evil-normal-state-cursor``, ``evil-insert-state-cursor`` -etc. to set the cursors for specific states. The acceptable values -for all of them are the same. - -.. elisp:autovariable:: evil-default-cursor - - -Window management ------------------ - -.. elisp:autovariable:: evil-auto-balance-windows - -.. elisp:autovariable:: evil-split-window-below - -.. elisp:autovariable:: evil-vsplit-window-right - - -Parenthesis highlighting ------------------------- - -These settings concern the integration between Evil and -``show-paren-mode``. They take no effect if this mode is not enabled. - -.. elisp:autovariable:: evil-show-paren-range - -.. elisp:autovariable:: evil-highlight-closing-paren-at-point-states - - -Miscellaneous -------------- - -.. elisp:autovariable:: evil-want-fine-undo - -.. elisp:autovariable:: evil-undo-system - -.. elisp:autovariable:: evil-backspace-join-lines - -.. elisp:autovariable:: evil-kbd-macro-suppress-motion-error - -.. elisp:autovariable:: evil-mode-line-format - -.. elisp:autovariable:: evil-mouse-word - -.. elisp:autovariable:: evil-transient-mouse-selection - -.. elisp:autovariable:: evil-bigword - -.. elisp:autovariable:: evil-esc-delay - -.. elisp:autovariable:: evil-intercept-esc - -.. elisp:autovariable:: evil-kill-on-visual-paste - -.. elisp:autovariable:: evil-echo-state - -.. elisp:autovariable:: evil-complete-all-buffers - -.. elisp:autovariable:: evil-want-empty-ex-last-command - - -.. rubric:: Footnotes - -.. [#order] Strictly speaking, the order only matters if the variable - affects the way Evil is loaded. This is the case with some - variables. diff --git a/.config/emacs/lisp/evil/evil-command-window.el b/.config/emacs/lisp/evil/evil-command-window.el deleted file mode 100644 index ef22be0..0000000 --- a/.config/emacs/lisp/evil/evil-command-window.el +++ /dev/null @@ -1,191 +0,0 @@ -;;; evil-command-window.el --- Evil command-line window -*- lexical-binding: t -*- -;; Author: Emanuel Evans <emanuel.evans at gmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; This provides an implementation of the Vim command-line window for -;; editing and repeating past Ex commands and searches. - -;;; Code: - -(require 'evil-vars) -(require 'evil-common) -(require 'evil-ex) -(require 'evil-search) - -(defvar evil-search-module) - -(defvar evil-command-window-current-buffer nil - "The buffer from which the command-line window was called.") - -(defvar evil-command-window-execute-fn nil - "The command to execute when exiting the command-line window.") - -(defvar evil--command-window-prompt nil - "The key for the command that opened the command-line window (:, /, or ?).") - -(define-derived-mode evil-command-window-mode fundamental-mode "Evil-cmd" - "Major mode for the Evil command-line window." - (add-hook 'after-change-functions #'evil--command-window-draw-prefix nil t) - (auto-fill-mode 0)) - -(defun evil-command-window (history prompt execute-fn) - "Open a command-line window for HISTORY with PROMPT and EXECUTE-FN. -HISTORY should be a list of commands. PROMPT should be the -command-line prompt (one of \":\", \"/\" or \"?\"). EXECUTE-FN should -be a unary function to execute on the result that the user selects. - -If called interactively, edit this minibuffer argument." - (interactive - (list (cons (minibuffer-contents) (minibuffer-history-value)) - (or (minibuffer-prompt) (user-error "Minibuffer is inactive")) - #'evil--command-window-minibuffer-execute)) - (when (derived-mode-p 'evil-command-window-mode) - (user-error "Command-line window is already open")) - (when (evil-ex-p) (evil-ex-teardown)) - (let ((previous-buffer (current-buffer)) - (buffer (get-buffer-create "*Command Line*"))) - (with-current-buffer buffer - (erase-buffer) - (evil-command-window-mode) - (setq-local evil-command-window-current-buffer previous-buffer) - (setq-local evil-command-window-execute-fn execute-fn) - (setq-local evil--command-window-prompt prompt) - (evil--command-window-insert-commands history)) - - (let* ((action - `((display-buffer-reuse-window display-buffer-at-bottom) - ,@(unless (zerop evil-command-window-height) - `((window-height body-lines . ,evil-command-window-height) - (preserve-size nil . t))) - (dedicated . t))) - (window (display-buffer buffer action)) - (delete-window-fun - (lambda (window) - (set-window-parameter window 'delete-window nil) - (delete-window window) - (switch-to-minibuffer)))) - (when (minibufferp) - (set-window-parameter window 'delete-window delete-window-fun)) - (select-window window))) - (goto-char (point-max)) - (unless (bobp) (backward-char) (evil-adjust-cursor))) - -(defun evil--command-window-draw-prefix (beg end _old-len) - "Display `evil--command-window-prompt' as a prefix of the changed lines." - (let ((prefix (propertize evil--command-window-prompt - 'font-lock-face 'minibuffer-prompt))) - (put-text-property beg end 'line-prefix prefix))) - -(defun evil--command-window-insert-commands (history) - "Insert the commands in HISTORY." - (let ((inhibit-modification-hooks t)) - (dolist (cmd (reverse history)) (insert cmd "\n")) - (evil--command-window-draw-prefix (point-min) (point-max) nil))) - -(defun evil-command-window-execute () - "Execute the command on the current line in the appropriate buffer. -The local variable `evil-command-window-execute-fn' determines which -function to execute." - (interactive) - (let ((result (buffer-substring-no-properties - (line-beginning-position) (line-end-position))) - (original-buffer evil-command-window-current-buffer) - (execute-fn evil-command-window-execute-fn)) - (let ((ignore-window-parameters t)) - (ignore-errors (kill-buffer-and-window))) - (unless (buffer-live-p original-buffer) - (user-error "Originating buffer is no longer active")) - (let ((window (get-buffer-window original-buffer))) - (when window (select-window window))) - (with-current-buffer original-buffer (funcall execute-fn result)))) - -(defun evil--command-window-minibuffer-execute (result) - "Terminate this minibuffer argument with RESULT." - (delete-minibuffer-contents) - (insert result) - (exit-minibuffer)) - -(defun evil-command-window-ex (&optional current-command) - "Open a command-line window for editing and executing Ex commands. -If CURRENT-COMMAND is present, it will be inserted under the cursor as -the current command to be edited." - (interactive) - (evil-command-window (cons (or current-command "") evil-ex-history) - ":" - #'evil-command-window-ex-execute)) - -(define-obsolete-function-alias - 'evil-ex-command-window #'evil-command-window "1.15.0" - "Start command window with Ex history and current minibuffer content.") - -(define-obsolete-function-alias - 'evil-ex-search-command-window #'evil-command-window "1.15.0" - "Start command window with search history and current minibuffer content.") - -(defun evil-command-window-ex-execute (result) - "Execute RESULT as an Ex command." - (unless (string-match-p "\\`[ \t\n\r]*\\'" result) - (unless (equal result (car evil-ex-history)) - (push result evil-ex-history)) - (evil-ex-execute result))) - -(defun evil--command-window-search (forward) - "Open a command-line window for searches." - (evil-command-window - (cons "" (cond ((eq evil-search-module 'evil-search) - evil-ex-search-history) - (forward evil-search-forward-history) - (t evil-search-backward-history))) - (evil-search-prompt forward) - (lambda (result) (evil-command-window-search-execute result forward)))) - -(defun evil-command-window-search-forward () - "Open a command-line window for forward searches." - (interactive) - (evil--command-window-search t)) - -(defun evil-command-window-search-backward () - "Open a command-line window for backward searches." - (interactive) - (evil--command-window-search nil)) - -(defun evil-command-window-search-execute (result forward) - "Search for RESULT using FORWARD to determine direction." - (unless (string= result "") - (if (eq evil-search-module 'evil-search) - (progn - (setq evil-ex-search-pattern (evil-ex-make-search-pattern result) - evil-ex-search-direction (if forward 'forward 'backward)) - (unless (equal result (car evil-ex-search-history)) - (push result evil-ex-search-history)) - (evil-ex-search)) - (evil-push-search-history result forward) - (evil-search result forward evil-regexp-search)))) - -(provide 'evil-command-window) - -;;; evil-command-window.el ends here diff --git a/.config/emacs/lisp/evil/evil-commands.el b/.config/emacs/lisp/evil/evil-commands.el deleted file mode 100644 index 5dbda83..0000000 --- a/.config/emacs/lisp/evil/evil-commands.el +++ /dev/null @@ -1,5288 +0,0 @@ -;;; evil-commands.el --- Evil commands and operators -*- lexical-binding: t -*- -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(require 'evil-common) -(require 'evil-search) -(require 'evil-states) -(require 'evil-ex) -(require 'evil-types) -(require 'evil-command-window) -(require 'evil-jumps) -(require 'evil-vars) -(require 'cl-lib) -(require 'reveal) - -(declare-function imenu--in-alist "imenu") - -;;; Motions - -;; Movement commands, or motions, are defined with the macro -;; `evil-define-motion'. A motion is a command with an optional -;; argument COUNT (interactively accessed by the code "<c>"). -;; It may specify the :type command property (e.g., :type line), -;; which determines how it is handled by an operator command. -;; Furthermore, the command must have the command properties -;; :keep-visual t and :repeat motion; these are automatically -;; set by the `evil-define-motion' macro. - -(evil-define-motion evil-forward-char (count &optional crosslines noerror) - "Move cursor to the right by COUNT characters. -Movement is restricted to the current line unless CROSSLINES is non-nil. -If NOERROR is non-nil, don't signal an error upon reaching the end -of the line or the buffer; just return nil." - :type exclusive - (interactive "<c>" (list evil-cross-lines - (evil-kbd-macro-suppress-motion-error))) - (cond - ((not crosslines) - ;; For efficiency, narrow the buffer to the projected - ;; movement before determining the current line - (evil-with-restriction nil (min (+ (point) (or count 1) 1) (point-max)) - (condition-case err - (evil-narrow-to-line (forward-char count)) - (error - ;; Restore the previous command (this one never happened). - ;; This preserves the current column if the previous command - ;; was `evil-next-line' or `evil-previous-line'. - (setq this-command last-command) - (unless noerror (signal (car err) (cdr err))))))) - (noerror (ignore-errors (evil-forward-char count crosslines))) - (t (evil-motion-loop (nil (or count 1)) - (forward-char) - ;; don't put the cursor on a newline - (or evil-move-beyond-eol - (evil-visual-state-p) (evil-operator-state-p) - (not (eolp)) (bolp) - (forward-char)))))) - -(evil-define-motion evil-backward-char (count &optional crosslines noerror) - "Move cursor to the left by COUNT characters. -Movement is restricted to the current line unless CROSSLINES is non-nil. -If NOERROR is non-nil, don't signal an error upon reaching the beginning -of the line or the buffer; just return nil." - :type exclusive - (interactive "<c>" (list evil-cross-lines - (evil-kbd-macro-suppress-motion-error))) - (cond - ((not crosslines) - ;; Restrict movement to the current line - (evil-with-restriction - (max (- (point) (or count 1)) (point-min)) - (min (1+ (point)) (point-max)) - (condition-case err - (evil-narrow-to-line (backward-char count)) - (error - ;; Restore the previous command (this one never happened). - ;; This preserves the current column if the previous command - ;; was `evil-next-line' or `evil-previous-line'. - (setq this-command last-command) - (unless noerror (signal (car err) (cdr err))))))) - (noerror (ignore-errors (evil-backward-char count crosslines))) - (t (evil-motion-loop (nil (or count 1)) - (backward-char) - ;; don't put the cursor on a newline - (unless (or (evil-visual-state-p) (evil-operator-state-p)) - (evil-adjust-cursor)))))) - -(evil-define-motion evil-next-line (count) - "Move the cursor COUNT lines down." - :type line - (let (line-move-visual) - (evil-line-move (or count 1)))) - -(evil-define-motion evil-previous-line (count) - "Move the cursor COUNT lines up." - :type line - (let (line-move-visual) - (evil-line-move (- (or count 1))))) - -(evil-define-motion evil-next-visual-line (count) - "Move the cursor COUNT screen lines down." - :type exclusive - (let ((line-move-visual t)) - (evil-line-move (or count 1)))) - -(evil-define-motion evil-previous-visual-line (count) - "Move the cursor COUNT screen lines up." - :type exclusive - (let ((line-move-visual t)) - (evil-line-move (- (or count 1))))) - -;; Used for repeated commands like "dd" -(evil-define-motion evil-line (count) - "Move COUNT - 1 lines down." - :type line - (let (line-move-visual) - (evil-line-move (1- (or count 1)) t))) - -(evil-define-motion evil-line-or-visual-line (count) - "Move COUNT - 1 lines down." - :type screen-line - (let ((line-move-visual (and evil-respect-visual-line-mode - visual-line-mode))) - (evil-line-move (1- (or count 1)) t))) - -(evil-define-motion evil-beginning-of-line () - "Move the cursor to the beginning of the current line." - :type exclusive - (move-beginning-of-line nil)) - -(evil-define-motion evil-end-of-line (count) - "Move the cursor to the end of the current line. -If COUNT is given, move COUNT - 1 lines downward first." - :type inclusive - (move-end-of-line count) - (when evil-track-eol - (setq temporary-goal-column most-positive-fixnum - this-command 'next-line)) - (let ((evil-move-beyond-eol - (if (evil-visual-state-p) (not evil-v$-excludes-newline) - evil-move-beyond-eol))) - (evil-adjust-cursor)) - ;; Prevent "c$" and "d$" from deleting blank lines - (when (eolp) (setq evil-this-type 'exclusive))) - -(evil-define-motion evil-beginning-of-visual-line () - "Move the cursor to the first character of the current screen line." - :type exclusive - (beginning-of-visual-line)) - -(evil-define-motion evil-end-of-visual-line (count) - "Move the cursor to the last character of the current screen line. -If COUNT is given, move COUNT - 1 screen lines downward first." - :type inclusive - (end-of-visual-line count) - (evil-move-cursor-back t)) - -(evil-define-motion evil-end-of-line-or-visual-line (count) - "Move the cursor to the last character of the current screen -line if `visual-line-mode' is active and -`evil-respect-visual-line-mode' is non-nil. If COUNT is given, -move COUNT - 1 screen lines downward first." - :type inclusive - (if (and evil-respect-visual-line-mode - visual-line-mode) - (evil-end-of-visual-line count) - (evil-end-of-line count))) - -(evil-define-motion evil-middle-of-visual-line () - "Move the cursor to the middle of the current visual line." - :type exclusive - (beginning-of-visual-line) - (evil-with-restriction - nil - (save-excursion (end-of-visual-line) (point)) - (move-to-column - (+ (current-column) -1 (/ (window-body-width) 2))))) - -(evil-define-motion evil-percentage-of-line (count) - "Move the cursor to COUNT % of the width of the current line. -If no COUNT is given, default to 50%." - :type exclusive - (let ((line-length (- (line-end-position) (line-beginning-position) - (if evil-move-beyond-eol -1 0)))) - (move-to-column (truncate (* line-length (or count 50)) 100)))) - -(evil-define-motion evil-first-non-blank () - "Move the cursor to the first non-blank character of the current line." - :type exclusive - (evil-narrow-to-line (back-to-indentation))) - -(evil-define-motion evil-last-non-blank (count) - "Move the cursor to the last non-blank character of the current line. -If COUNT is given, move COUNT - 1 lines downward first." - :type inclusive - (evil-move-end-of-line count) - (skip-chars-backward " \t") - (unless (bolp) (backward-char))) - -(evil-define-motion evil-first-non-blank-of-visual-line () - "Move the cursor to the first non blank character -of the current screen line." - :type exclusive - (evil-beginning-of-visual-line) - (skip-chars-forward " \t\r")) - -(evil-define-motion evil-next-line-first-non-blank (count) - "Move the cursor COUNT lines down on the first non-blank character." - :type line - (let ((this-command this-command)) - (evil-next-line (or count 1))) - (evil-first-non-blank)) - -(evil-define-motion evil-next-line-1-first-non-blank (count) - "Move the cursor COUNT-1 lines down on the first non-blank character." - :type line - (let ((this-command this-command)) - (evil-next-line (1- (or count 1)))) - (evil-first-non-blank)) - -(evil-define-motion evil-previous-line-first-non-blank (count) - "Move the cursor COUNT lines up on the first non-blank character." - :type line - (let ((this-command this-command)) - (evil-previous-line (or count 1))) - (evil-first-non-blank)) - -(evil-define-motion evil-goto-line (count) - "Go to line COUNT. By default the last line." - :jump t - :type line - (evil-ensure-column - (if (null count) - (progn - (goto-char (point-max)) - (when (and (eq (current-buffer) (window-buffer)) - (> (point) (window-end nil t))) - ;; If the end of the buffer is not already on the screen, scroll to - ;; position it near the bottom. - (overlay-recenter (point)) - (recenter (and (< 100 scroll-conservatively) -1)))) - (goto-char (point-min)) - (forward-line (1- count))))) - -(evil-define-motion evil-goto-first-line (count) - "Go to line COUNT. By default the first line." - :jump t - :type line - (evil-goto-line (or count 1))) - -(evil-define-motion evil-forward-word-begin (count &optional bigword) - "Move the cursor to the beginning of the COUNT-th next word. -If BIGWORD is non-nil, move by WORDS. - -If this command is called in operator-pending state it behaves -differently. If point reaches the beginning of a word on a new -line point is moved back to the end of the previous line. - -If called after a change operator, i.e. cw or cW, -`evil-want-change-word-to-end' is non-nil and point is on a word, -then both behave like ce or cE. - -If point is at the end of the buffer and cannot be moved then -`end-of-buffer' is signaled." - :type exclusive - (let ((thing (if bigword 'evil-WORD 'evil-word)) - (orig (point)) - (count (or count 1))) - (evil-signal-at-bob-or-eob count) - (cond - ;; default motion, beginning of next word - ((not (evil-operator-state-p)) - (evil-forward-beginning thing count)) - ;; the evil-change operator, maybe behave like ce or cE - ((and evil-want-change-word-to-end - (memq evil-this-operator evil-change-commands) - (< orig (or (cdr-safe (bounds-of-thing-at-point thing)) orig))) - ;; forward-thing moves point to the correct position because - ;; this is an exclusive motion - (forward-thing thing count)) - ;; operator state - (t - (prog1 (evil-forward-beginning thing count) - ;; if we reached the beginning of a word on a new line in - ;; Operator-Pending state, go back to the end of the previous - ;; line - (when (and (> (line-beginning-position) orig) - (looking-back "^[[:space:]]*" (line-beginning-position))) - ;; move cursor back as long as the line contains only - ;; whitespaces and is non-empty - (evil-move-end-of-line 0) - ;; skip non-empty lines containing only spaces - (while (and (looking-back "^[[:space:]]+$" (line-beginning-position)) - (not (<= (line-beginning-position) orig))) - (evil-move-end-of-line 0)) - ;; but if the previous line is empty, delete this line - (when (bolp) (forward-char)))))))) - -(evil-define-motion evil-forward-word-end (count &optional bigword) - "Move the cursor to the end of the COUNT-th next word. -If BIGWORD is non-nil, move by WORDS." - :type inclusive - (let ((thing (if bigword 'evil-WORD 'evil-word)) - (count (or count 1))) - (evil-signal-at-bob-or-eob count) - ;; Evil special behaviour: e or E on a one-character word in - ;; operator state does not move point - (unless (and (evil-operator-state-p) - (= 1 count) - (let ((bnd (bounds-of-thing-at-point thing))) - (and bnd - (= (car bnd) (point)) - (= (cdr bnd) (1+ (point))))) - (looking-at "[[:word:]]")) - (evil-forward-end thing count)))) - -(evil-define-motion evil-backward-word-begin (count &optional bigword) - "Move the cursor to the beginning of the COUNT-th previous word. -If BIGWORD is non-nil, move by WORDS." - :type exclusive - (let ((thing (if bigword 'evil-WORD 'evil-word))) - (evil-signal-at-bob-or-eob (- (or count 1))) - (evil-backward-beginning thing count))) - -(evil-define-motion evil-backward-word-end (count &optional bigword) - "Move the cursor to the end of the COUNT-th previous word. -If BIGWORD is non-nil, move by WORDS." - :type inclusive - (let ((thing (if bigword 'evil-WORD 'evil-word))) - (evil-signal-at-bob-or-eob (- (or count 1))) - (evil-backward-end thing count))) - -(evil-define-motion evil-forward-WORD-begin (count) - "Move the cursor to the beginning of the COUNT-th next WORD." - :type exclusive - (evil-forward-word-begin count t)) - -(evil-define-motion evil-forward-WORD-end (count) - "Move the cursor to the end of the COUNT-th next WORD." - :type inclusive - (evil-forward-word-end count t)) - -(evil-define-motion evil-backward-WORD-begin (count) - "Move the cursor to the beginning of the COUNT-th previous WORD." - :type exclusive - (evil-backward-word-begin count t)) - -(evil-define-motion evil-backward-WORD-end (count) - "Move the cursor to the end of the COUNT-th previous WORD." - :type inclusive - (evil-backward-word-end count t)) - -;; section movement -(evil-define-motion evil-forward-section-begin (count) - "Move the cursor to the beginning of the COUNT-th next section." - :jump t - :type exclusive - (evil-signal-at-bob-or-eob count) - (evil-forward-beginning 'evil-defun count)) - -(evil-define-motion evil-forward-section-end (count) - "Move the cursor to the end of the COUNT-th next section." - :jump t - :type inclusive - (evil-signal-at-bob-or-eob count) - (evil-forward-end 'evil-defun count) - (unless (eobp) (forward-line))) - -(evil-define-motion evil-backward-section-begin (count) - "Move the cursor to the beginning of the COUNT-th previous section." - :jump t - :type exclusive - (evil-signal-at-bob-or-eob (- (or count 1))) - (evil-backward-beginning 'evil-defun count)) - -(evil-define-motion evil-backward-section-end (count) - "Move the cursor to the end of the COUNT-th previous section." - :jump t - :type inclusive - (evil-signal-at-bob-or-eob (- (or count 1))) - (end-of-line -1) - (evil-backward-end 'evil-defun count) - (unless (eobp) (forward-line))) - -(evil-define-motion evil-forward-sentence-begin (count) - "Move to the next COUNT-th beginning of a sentence or end of a paragraph." - :jump t - :type exclusive - (evil-signal-at-bob-or-eob count) - (evil-forward-nearest count - #'(lambda (_cnt) - (evil-forward-beginning 'evil-sentence)) - #'evil-forward-paragraph)) - -(evil-define-motion evil-backward-sentence-begin (count) - "Move to the previous COUNT-th beginning of a sentence or paragraph." - :jump t - :type exclusive - (evil-signal-at-bob-or-eob (- (or count 1))) - (evil-forward-nearest (- (or count 1)) - #'(lambda (_cnt) - (evil-backward-beginning 'evil-sentence)) - #'(lambda (_cnt) - (evil-backward-paragraph)))) - -(evil-define-motion evil-forward-paragraph (count) - "Move to the end of the COUNT-th next paragraph." - :jump t - :type exclusive - (evil-signal-at-bob-or-eob count) - (evil-forward-end 'evil-paragraph count) - (unless (eobp) (forward-line))) - -(evil-define-motion evil-backward-paragraph (count) - "Move to the beginning of the COUNT-th previous paragraph." - :jump t - :type exclusive - (evil-signal-at-bob-or-eob (- (or count 1))) - (unless (eobp) (forward-line)) - (evil-backward-beginning 'evil-paragraph count) - (unless (bobp) (forward-line -1))) - -(defvar hif-ifx-else-endif-regexp) -(evil-define-motion evil-jump-item (count) - "Find the next item in this line after or under the cursor -and jump to the corresponding one." - :jump t - :type inclusive - (cond - ;; COUNT% jumps to a line COUNT percentage down the file - (count - (evil-ensure-column - (goto-char - (let ((size (- (point-max) (point-min)))) - (+ (point-min) - (if (> size 80000) - (* count (/ size 100)) - (/ (* count size) 100)))))) - (setq evil-this-type 'line)) - ((and (evil-looking-at-start-comment t) - (let ((pnt (point))) - (forward-comment 1) - (or (not (bolp)) - (prog1 nil (goto-char pnt))))) - (backward-char)) - ((and (not (eolp)) (evil-looking-at-end-comment t)) - (forward-comment -1)) - ((and - (memq major-mode '(c-mode c++-mode c-ts-mode c++-ts-mode)) - (require 'hideif nil t) - (with-no-warnings - (let* ((hif-else-regexp (concat hif-cpp-prefix "\\(?:else\\|elif[ \t]+\\)")) - (hif-ifx-else-endif-regexp - (concat hif-ifx-regexp "\\|" hif-else-regexp "\\|" hif-endif-regexp))) - (cond - ((save-excursion (beginning-of-line) (or (hif-looking-at-ifX) (hif-looking-at-else))) - (hif-find-next-relevant) - (while (hif-looking-at-ifX) - (hif-ifdef-to-endif) - (hif-find-next-relevant)) - t) - ((save-excursion (beginning-of-line) (hif-looking-at-endif)) - (hif-endif-to-ifdef) - t)))))) - (t - (let* ((open (point-max)) - (close (point-max)) - (open-pair (ignore-errors - (save-excursion - ;; consider the character right before eol given that - ;; point may be placed there, e.g. in visual state - (when (and (eolp) (not (bolp))) - (backward-char)) - (setq open (1- (scan-lists (point) 1 -1))) - (when (< open (line-end-position)) - (goto-char open) - (forward-list) - (1- (point)))))) - (close-pair (ignore-errors - (save-excursion - ;; consider the character right before eol given that - ;; point may be placed there, e.g. in visual state - (when (and (eolp) (not (bolp))) - (backward-char)) - (setq close (1- (scan-lists (point) 1 1))) - (when (< close (line-end-position)) - (goto-char (1+ close)) - (backward-list) - (point)))))) - (cond - ((not (or open-pair close-pair)) - ;; nothing found, check if we are inside a string - (let ((pnt (point)) - (bnd (bounds-of-thing-at-point 'evil-string))) - (if (not (and bnd (< (point) (cdr bnd)))) - ;; no, then we really failed - (user-error "No matching item found on the current line") - ;; yes, go to the end of the string and try again - (let ((endstr (cdr bnd))) - (when (or (save-excursion - (goto-char endstr) - (let ((b (bounds-of-thing-at-point 'evil-string))) - (and b (< (point) (cdr b))))) ; not at end of string - (condition-case nil - (progn - (goto-char endstr) - (evil-jump-item) - nil) - (error t))) - ;; failed again, go back to original point - (goto-char pnt) - (user-error "No matching item found on the current line")))))) - ((< open close) (goto-char open-pair)) - (t (goto-char close-pair))))))) - -(declare-function flyspell-overlay-p "flyspell") -(evil-define-motion evil-next-flyspell-error (count) - "Go to the COUNT'th spelling mistake after point." - :jump t - (unless (bound-and-true-p flyspell-mode) (signal 'search-failed nil)) - (let ((fwd (> (or count 1) 0)) (start (point)) (pos (point)) ov) - (dotimes (_ (abs (or count 1))) - (let ((limit (if fwd (point-max) (point-min))) wrappedp) - (when fwd (setq pos (save-excursion (goto-char pos) - (skip-syntax-forward "w") (point)))) - (while (progn (if (if fwd (>= pos limit) (<= pos limit)) - (if (or wrappedp (not evil-search-wrap)) - (signal 'search-failed nil) - (setq wrappedp t - limit start - pos (if fwd (point-min) - (previous-overlay-change (point-max))))) - (setq pos (if fwd (next-overlay-change pos) - (previous-overlay-change pos)))) - (not (setq ov (seq-find #'flyspell-overlay-p - (overlays-at pos)))))) - (when wrappedp (let (message-log-max) (message "Search wrapped"))))) - (goto-char (overlay-start ov)))) - -(evil-define-motion evil-prev-flyspell-error (count) - "Go to the COUNT'th spelling mistake preceding point." - :jump t - (evil-next-flyspell-error (- (or count 1)))) - -(evil-define-motion evil-previous-open-paren (count) - "Go to COUNT previous unmatched \"(\"." - :jump t - :type exclusive - (evil-up-paren ?\( ?\) (- (or count 1)))) - -(evil-define-motion evil-next-close-paren (count) - "Go to COUNT next unmatched \")\"." - :jump t - :type exclusive - (forward-char) - (evil-up-paren ?\( ?\) (or count 1)) - (backward-char)) - -(evil-define-motion evil-previous-open-brace (count) - "Go to COUNT previous unmatched \"{\"." - :jump t - :type exclusive - (evil-up-paren ?{ ?} (- (or count 1)))) - -(evil-define-motion evil-next-close-brace (count) - "Go to COUNT next unmatched \"}\"." - :jump t - :type exclusive - (forward-char) - (evil-up-paren ?{ ?} (or count 1)) - (backward-char)) - -(defun evil--lowercase-markers () - "Get all lowercase markers." - (cl-remove-if-not (lambda (x) (and (markerp (cdr x)) - (<= ?a (car x) ?z))) - evil-markers-alist)) - -(defun evil--next-mark (forwardp) - "Move to next lowercase mark. -Move forward if FORWARDP is non-nil, and backward otherwise. Loop back -to the beginning of buffer if the end is reached." - (let* ((pos (if forwardp (1+ (point)) (point))) - (centered-markers - (cl-sort - (or (evil--lowercase-markers) (user-error "No marks in this buffer")) - (if forwardp #'< #'>) - :key (lambda (x) (+ (if (< (cdr x) pos) 0 most-negative-fixnum) - (cdr x)))))) - (goto-char (cdar centered-markers)))) - -(evil-define-motion evil-next-mark (count) - "Go to COUNT next lowercase mark." - :keep-visual t - :repeat nil - :type exclusive - :jump t - (dotimes (_ (or count 1)) - (evil--next-mark t))) - -(evil-define-motion evil-next-mark-line (count) - "Go to COUNT line of next lowercase mark after current line." - :keep-visual t - :repeat nil - :type exclusive - :jump t - (unless (evil--lowercase-markers) (user-error "No marks in this buffer")) - (dotimes (_ (or count 1)) - (move-end-of-line nil) - (evil--next-mark t)) - (evil-first-non-blank)) - -(evil-define-motion evil-previous-mark (count) - "Go to COUNT previous lowercase mark." - :keep-visual t - :repeat nil - :type exclusive - :jump t - (dotimes (_ (or count 1)) - (evil--next-mark nil))) - -(evil-define-motion evil-previous-mark-line (count) - "Go to COUNT line of previous lowercase mark before current line." - :keep-visual t - :repeat nil - :type exclusive - :jump t - (unless (evil--lowercase-markers) (user-error "No marks in this buffer")) - (dotimes (_ (or count 1)) - (move-beginning-of-line nil) - (evil--next-mark nil)) - (evil-first-non-blank)) - -(evil-define-command evil-set-col-0-mark (_beg end mark) - "Set MARK at column 0 of line of END. -Default is cursor line." - (interactive "<r><a>") - (if (< 1 (length mark)) - (user-error "Trailing characters") - (save-excursion - (goto-char (if (eobp) end (1- end))) - (evil-beginning-of-line) - (evil-set-marker (string-to-char mark))))) - -(evil-define-motion evil-find-char (count char) - "Move to the next COUNT'th occurrence of CHAR. -Movement is restricted to the current line unless `evil-cross-lines' -is non-nil." - :type inclusive - (interactive "<c><C>") - (setq count (or count 1)) - (let ((fwd (> count 0)) - (visual (and evil-respect-visual-line-mode - visual-line-mode)) - case-fold-search) - (setq evil-last-find (list #'evil-find-char char fwd)) - (when fwd (evil-forward-char 1 evil-cross-lines)) - (unless (prog1 - (search-forward - (char-to-string char) - (cond (evil-cross-lines nil) - ((and fwd visual) - (save-excursion - (end-of-visual-line) - (point))) - (fwd (line-end-position)) - (visual - (save-excursion - (beginning-of-visual-line) - (point))) - (t (line-beginning-position))) - t count) - (when fwd (backward-char))) - (user-error "Can't find `%c'" char)))) - -(evil-define-motion evil-find-char-backward (count char) - "Move to the previous COUNT'th occurrence of CHAR." - :type exclusive - (interactive "<c><C>") - (evil-find-char (- (or count 1)) char)) - -(evil-define-motion evil-find-char-to (count char) - "Move before the next COUNT'th occurrence of CHAR." - :type inclusive - (interactive "<c><C>") - (unwind-protect - (evil-find-char count char) - (setcar evil-last-find #'evil-find-char-to)) - (if (> (or count 1) 0) - (backward-char) - (forward-char))) - -(evil-define-motion evil-find-char-to-backward (count char) - "Move before the previous COUNT'th occurrence of CHAR." - :type exclusive - (interactive "<c><C>") - (evil-find-char-to (- (or count 1)) char)) - -(evil-define-motion evil-repeat-find-char (count) - "Repeat the last find COUNT times." - :type inclusive - (setq count (or count 1)) - (cl-destructuring-bind (cmd char fwd) - (or evil-last-find (user-error "No previous search")) - ;; ensure count is non-negative - (when (< count 0) - (setq count (- count) - fwd (not fwd))) - ;; skip next character when repeating t or T - (and (eq cmd #'evil-find-char-to) - evil-repeat-find-to-skip-next - (= count 1) - (eql (if fwd (char-after (1+ (point))) (char-before)) char) - (setq count (1+ count))) - (let (evil-last-find) - (funcall cmd (if fwd count (- count)) char) - (unless (nth 2 evil-last-find) - (setq evil-this-type 'exclusive))))) - -(evil-define-motion evil-repeat-find-char-reverse (count) - "Repeat the last find COUNT times in the opposite direction." - :type inclusive - (evil-repeat-find-char (- (or count 1)))) - -;; ceci n'est pas une pipe -(evil-define-motion evil-goto-column (count) - "Go to column COUNT on the current line. -Columns are counted from zero." - :type exclusive - (move-to-column (or count 0))) - -(evil-define-command evil-goto-mark (char &optional noerror) - "Go to the marker specified by CHAR." - :keep-visual t - :repeat nil - :type exclusive - :jump t - (interactive (list (read-char))) - (let ((marker (evil-get-marker char))) - (cond - ((markerp marker) - (switch-to-buffer (marker-buffer marker)) - (goto-char marker)) - ((numberp marker) (goto-char marker)) - ((consp marker) - (when (or (find-buffer-visiting (car marker)) - (and (y-or-n-p (format "Visit file %s again? " - (car marker))) - (find-file (car marker)))) - (goto-char (cdr marker)))) - ((not noerror) - (user-error "Marker `%c' is not set%s" char - (if (evil-global-marker-p char) "" - " in this buffer")))))) - -(evil-define-command evil-goto-mark-line (char &optional noerror) - "Go to the line of the marker specified by CHAR." - :keep-visual t - :repeat nil - :type line - :jump t - (interactive (list (read-char))) - (evil-goto-mark char noerror) - (evil-first-non-blank)) - -(declare-function goto-last-change "ext:goto-chg") -(declare-function goto-last-change-reverse "ext:goto-chg") - -(evil-define-motion evil-goto-last-change (count) - "Like `goto-last-change' but takes a COUNT rather than a span." - (setq this-command 'goto-last-change) - (dotimes (_ (or count 1)) - (goto-last-change nil))) - -(evil-define-motion evil-goto-last-change-reverse (count) - "Like `goto-last-change-reverse' but takes a COUNT rather than a span." - (setq this-command 'goto-last-change-reverse) - (dotimes (_ (or count 1)) - (goto-last-change-reverse nil))) - -(evil-define-motion evil-jump-backward (count) - "Go to older position in jump list. -To go the other way, press \ -\\<evil-motion-state-map>\\[evil-jump-forward]." - (evil--jump-backward count)) - -(evil-define-motion evil-jump-forward (count) - "Go to newer position in jump list. -To go the other way, press \ -\\<evil-motion-state-map>\\[evil-jump-backward]." - (evil--jump-forward count)) - -(evil-define-motion evil-jump-backward-swap (_count) - "Go to the previous position in jump list. -The current position is placed in the jump list." - (let ((pnt (point))) - (evil--jump-backward 1) - (evil-set-jump pnt))) - -(defvar xref-prompt-for-identifier) -(evil-define-motion evil-jump-to-tag (arg) - "Jump to tag under point. -If called with a prefix argument, provide a prompt -for specifying the tag." - :jump t - (interactive "P") - (cond - ((fboundp 'xref-find-definitions) - (let ((xref-prompt-for-identifier arg)) - (call-interactively #'xref-find-definitions))) - ((fboundp 'find-tag) - (if arg (call-interactively #'find-tag) - (let ((tag (funcall (or find-tag-default-function - (get major-mode 'find-tag-default-function) - #'find-tag-default)))) - (find-tag (or tag (user-error "No tag found around point")))))))) - -(evil-define-motion evil-lookup () - "Look up the keyword at point. -Calls `evil-lookup-func'." - (funcall evil-lookup-func)) - -(defun evil-ret-gen (count indent?) - (let ((widget (or (get-char-property (point) 'field) - (get-char-property (point) 'button) - (get-char-property (point) 'widget-doc)))) - (cond - ((and widget - (fboundp 'widget-type) - (fboundp 'widget-button-press) - (or (and (symbolp widget) - (get widget 'widget-type)) - (and (consp widget) - (get (widget-type widget) 'widget-type)))) - (when (evil-operator-state-p) - (setq evil-inhibit-operator t)) - (when (fboundp 'widget-button-press) - (widget-button-press (point)))) - ((and (fboundp 'button-at) - (fboundp 'push-button) - (button-at (point))) - (when (evil-operator-state-p) - (setq evil-inhibit-operator t)) - (push-button)) - ((or (evil-emacs-state-p) - (and (evil-insert-state-p) - (not buffer-read-only))) - (if (not indent?) - (newline count) - (delete-horizontal-space t) - (newline count) - (indent-according-to-mode))) - (t (evil-next-line-first-non-blank count))))) - -(evil-define-motion evil-ret (count) - "Move the cursor COUNT lines down. -If point is on a widget or a button, click on it. -In Insert state, insert a newline." - :type line - (evil-ret-gen count nil)) - -(evil-define-motion evil-ret-and-indent (count) - "Move the cursor COUNT lines down. -If point is on a widget or a button, click on it. -In Insert state, insert a newline and indent." - :type line - (evil-ret-gen count t)) - -(evil-define-motion evil-window-top (count) - "Move the cursor to line COUNT from the top of the window." - :jump t - :type line - (evil-ensure-column - (move-to-window-line - (max (or count 0) - (if (or (zerop scroll-margin) - (= (point-min) (window-start)) - (< (count-screen-lines (window-start) (point)) - scroll-margin)) - 0 - scroll-margin))))) - -(evil-define-motion evil-window-middle () - "Move the cursor to the middle line in the window." - :jump t - :type line - (evil-ensure-column (move-to-window-line nil))) - -(evil-define-motion evil-window-bottom (count) - "Move the cursor to line COUNT from the bottom of the window." - :jump t - :type line - (evil-ensure-column - (move-to-window-line - (- (max (or count 1) - (if (or (zerop scroll-margin) - (< (count-screen-lines (point) (window-end)) - scroll-margin)) - 1 - (1+ scroll-margin))))))) - -;; scrolling -(evil-define-command evil-scroll-line-up (count) - "Scroll the window COUNT lines upwards." - :repeat nil - :keep-visual t - (interactive "p") - (let (scroll-preserve-screen-position) (scroll-down count))) - -(evil-define-command evil-scroll-line-down (count) - "Scroll the window COUNT lines downwards." - :repeat nil - :keep-visual t - (interactive "p") - (let (scroll-preserve-screen-position) (scroll-up count))) - -(evil-define-command evil-scroll-count-reset () - "Set `evil-scroll-count' to 0. -`evil-scroll-up' and `evil-scroll-down' will then scroll by half of -the screen (the default)." - :repeat nil - :keep-visual t - (interactive) - (setq evil-scroll-count 0)) - -(defun evil--get-scroll-count (count) - "Given a user-supplied COUNT, return scroll count." - (cl-flet ((posint (x) (and (natnump x) (< 0 x) x))) - (or (posint count) - (posint evil-scroll-count) - (/ (window-body-height) 2)))) - -;; With `scroll-preserve-screen-position' `scroll-up'/`scroll-down' -;; target the same cursor pixel Y-coordinate while `last-command' has -;; the `scroll-command' property. However the target needs updating -;; when e.g. scrolling maximally to the first or last line and then -;; switching scroll direction. Do this by resetting `last-command' -;; when `real-this-command' (`evil-ensure-column' modifies -;; `this-command') changed from last value: - -(evil-define-command evil-scroll-up (count) - "Scroll the window and the cursor COUNT lines upwards. -If COUNT is not specified the function scrolls up `evil-scroll-count' -lines, which is the last used count. -If the scroll count is zero the command scrolls half the screen." - :repeat nil - :keep-visual t - (interactive "<c>") - (when (= (line-beginning-position) (point-min)) - (signal 'beginning-of-buffer nil)) - (setq count (evil--get-scroll-count count)) - (evil-ensure-column - (let ((opoint (point))) - (condition-case nil - (let ((scroll-preserve-screen-position 'always) - (last-command (when (eq real-last-command real-this-command) - real-last-command))) - (scroll-down count)) - (:success - ;; Redo if `scroll-down' only did partial scroll up to BOB - (when (<= (window-start) (point-min)) - (goto-char opoint) - (vertical-motion (- count)))) - (beginning-of-buffer (vertical-motion (- count))))))) -(put 'evil-scroll-up 'scroll-command t) - -(evil-define-command evil-scroll-down (count) - "Scroll the window and the cursor COUNT lines downwards. -If COUNT is not specified the function scrolls down -`evil-scroll-count' lines, which is the last used count. -If the scroll count is zero the command scrolls half the screen." - :repeat nil - :keep-visual t - (interactive "<c>") - (when (= (line-end-position) (point-max)) - (signal 'end-of-buffer nil)) - (setq count (evil--get-scroll-count count)) - (evil-ensure-column - ;; BUG #660: First check whether the eob is visible. - ;; In that case we do not scroll but merely move point. - (if (<= (point-max) (window-end)) - (vertical-motion count) - (condition-case nil - (let ((scroll-preserve-screen-position 'always) - (last-command (when (eq real-last-command real-this-command) - real-last-command))) - (scroll-up count)) - (:success - ;; If EOB became visible: Scroll it to the bottom - (save-excursion - (goto-char (window-start)) - (vertical-motion (max 0 (- (window-height) 1 scroll-margin))) - (when (<= (point-max) (point)) (recenter -1)))) - (end-of-buffer (goto-char (point-max)) (recenter -1)))))) -(put 'evil-scroll-down 'scroll-command t) - -(evil-define-command evil-scroll-page-up (count) - "Scroll the window COUNT pages upwards." - :repeat nil - :keep-visual t - (interactive "p") - (evil-ensure-column - (dotimes (i count) - (condition-case err - (scroll-down nil) - (beginning-of-buffer - (if (and (bobp) (zerop i)) - (signal (car err) (cdr err)) - (goto-char (point-min)))))))) - -(evil-define-command evil-scroll-page-down (count) - "Scroll the window COUNT pages downwards." - :repeat nil - :keep-visual t - (interactive "p") - (evil-ensure-column - (dotimes (i count) - (condition-case err - (scroll-up nil) - (end-of-buffer - (if (and (eobp) (zerop i)) - (signal (car err) (cdr err)) - (goto-char (point-max)))))))) - -(evil-define-command evil-scroll-line-to-top (count) - "Scroll line number COUNT (or the cursor line) to the top of the window." - :repeat nil - :keep-visual t - (interactive "<c>") - (when count - (evil-save-column - (goto-char (point-min)) - (forward-line (1- count)))) - (recenter 0)) - -(evil-define-command evil-scroll-line-to-top-first-non-blank (count) - "Scroll line number COUNT (or the cursor line) to the top of the window. -Then move the cursor to the first non-blank character of that line." - :repeat nil - :keep-visual t - (interactive "<c>") - (evil-scroll-line-to-top count) - (evil-first-non-blank)) - -(evil-define-command evil-scroll-line-to-center (count) - "Scroll line number COUNT (or the cursor line) to the center of the window." - :repeat nil - :keep-visual t - (interactive "<c>") - (when count - (evil-save-column - (goto-char (point-min)) - (forward-line (1- count)))) - (recenter)) - -(evil-define-command evil-scroll-line-to-center-first-non-blank (count) - "Scroll line number COUNT (or the cursor line) to the center of the window. -Then move the cursor to the first non-blank character of that line." - :repeat nil - :keep-visual t - (interactive "<c>") - (evil-scroll-line-to-center count) - (evil-first-non-blank)) - -(evil-define-command evil-scroll-line-to-bottom (count) - "Scroll line number COUNT (or the cursor line) to the bottom of the window." - :repeat nil - :keep-visual t - (interactive "<c>") - (when count - (evil-save-column - (goto-char (point-min)) - (forward-line (1- count)))) - (recenter -1)) - -(evil-define-command evil-scroll-line-to-bottom-first-non-blank (count) - "Scroll line number COUNT (or the cursor line) to the bottom of the window. -Then move the cursor to the first non-blank character of that line." - :repeat nil - :keep-visual t - (interactive "<c>") - (evil-scroll-line-to-bottom count) - (evil-first-non-blank)) - -(evil-define-command evil-scroll-bottom-line-to-top (count) - "Scroll the line right below the window, -or line COUNT to the top of the window." - :repeat nil - :keep-visual t - (interactive "<c>") - (unless count - (goto-char (window-end)) - (evil-first-non-blank)) - (evil-scroll-line-to-top count)) - -(evil-define-command evil-scroll-top-line-to-bottom (count) - "Scroll the line right above the window, -or line COUNT to the bottom of the window." - :repeat nil - :keep-visual t - (interactive "<c>") - (unless count - (goto-char (window-start)) - (evil-first-non-blank)) - (evil-scroll-line-to-bottom count)) - -(evil-define-command evil-scroll-left (count) - "Scroll the window COUNT half-screenwidths to the left." - :repeat nil - :keep-visual t - (interactive "p") - (evil-with-hproject-point-on-window - (scroll-right (* count (/ (window-width) 2))))) - -(evil-define-command evil-scroll-right (count) - "Scroll the window COUNT half-screenwidths to the right." - :repeat nil - :keep-visual t - (interactive "p") - (evil-with-hproject-point-on-window - (scroll-left (* count (/ (window-width) 2))))) - -(evil-define-command evil-scroll-column-left (count) - "Scroll the window COUNT columns to the left." - :repeat nil - :keep-visual t - (interactive "p") - (evil-with-hproject-point-on-window - (scroll-right count))) - -(evil-define-command evil-scroll-column-right (count) - "Scroll the window COUNT columns to the right." - :repeat nil - :keep-visual t - (interactive "p") - (evil-with-hproject-point-on-window - (scroll-left count))) - -(evil-define-command evil-scroll-end-column () - "Scroll the window to position the cursor at the end (right side) of the screen. -Warn if `hscroll-margin' > 0, as cursor will be `hscroll-margin' chars from -the right edge." - :repeat nil - :keep-visual t - (interactive) - (let* ((window-hpos (- (current-column) (window-hscroll))) - (dist-from-right-edge (- (window-width) window-hpos))) - (when (< 0 hscroll-margin) - (evil-echo "%s: hscroll-margin = %d" this-command hscroll-margin)) - (evil-scroll-column-left (- dist-from-right-edge (abs (* 2 hscroll-margin)))))) - -(evil-define-command evil-scroll-start-column () - "Scroll the window to position the cursor at the start (left side) of the screen. -Warn if `hscroll-margin' > 0, as cursor will be `hscroll-margin' chars from -the left edge." - :repeat nil - :keep-visual t - (interactive) - (let ((initial-column (current-column)) - (initial-hscroll (window-hscroll))) - (when (< 0 hscroll-margin) - (evil-echo "%s: hscroll-margin = %d" this-command hscroll-margin)) - (evil-scroll-column-right (- initial-column initial-hscroll hscroll-margin 1)))) - -;;; Text objects - -;; Text objects are defined with `evil-define-text-object'. In Visual -;; state, they modify the current selection; in Operator-Pending -;; state, they return a pair of buffer positions. Outer text objects -;; are bound in the keymap `evil-outer-text-objects-map', and inner -;; text objects are bound in `evil-inner-text-objects-map'. -;; -;; Common text objects like words, WORDS, paragraphs and sentences are -;; defined via a corresponding move-function. This function must have -;; the following properties: -;; -;; 1. Take exactly one argument, the count. -;; 2. When the count is positive, move point forward to the first -;; character after the end of the next count-th object. -;; 3. When the count is negative, move point backward to the first -;; character of the count-th previous object. -;; 4. If point is placed on the first character of an object, the -;; backward motion does NOT count that object. -;; 5. If point is placed on the last character of an object, the -;; forward motion DOES count that object. -;; 6. The return value is "count left", i.e., in forward direction -;; count is decreased by one for each successful move and in -;; backward direction count is increased by one for each -;; successful move, returning the final value of count. -;; Therefore, if the complete move is successful, the return -;; value is 0. -;; -;; A useful macro in this regard is `evil-motion-loop', which quits -;; when point does not move further and returns the count difference. -;; It also provides a "unit value" of 1 or -1 for use in each -;; iteration. For example, a hypothetical "foo-bar" move could be -;; written as such: -;; -;; (defun foo-bar (count) -;; (evil-motion-loop (var count) -;; (forward-foo var) ; `var' is 1 or -1 depending on COUNT -;; (forward-bar var))) -;; -;; If "forward-foo" and "-bar" didn't accept negative arguments, -;; we could choose their backward equivalents by inspecting `var': -;; -;; (defun foo-bar (count) -;; (evil-motion-loop (var count) -;; (cond -;; ((< var 0) -;; (backward-foo 1) -;; (backward-bar 1)) -;; (t -;; (forward-foo 1) -;; (forward-bar 1))))) -;; -;; After a forward motion, point has to be placed on the first -;; character after some object, unless no motion was possible at all. -;; Similarly, after a backward motion, point has to be placed on the -;; first character of some object. This implies that point should -;; NEVER be moved to eob or bob, unless an object ends or begins at -;; eob or bob. (Usually, Emacs motions always move as far as possible. -;; But we want to use the motion-function to identify certain objects -;; in the buffer, and thus exact movement to object boundaries is -;; required.) - -(evil-define-text-object evil-a-word (count &optional beg end _type) - "Select a word." - (evil-select-a-restricted-object 'evil-word beg end type count)) - -(evil-define-text-object evil-inner-word (count &optional beg end _type) - "Select inner word." - (evil-select-inner-restricted-object 'evil-word beg end type count)) - -(evil-define-text-object evil-a-WORD (count &optional beg end _type) - "Select a WORD." - (evil-select-a-restricted-object 'evil-WORD beg end type count)) - -(evil-define-text-object evil-inner-WORD (count &optional beg end _type) - "Select inner WORD." - (evil-select-inner-restricted-object 'evil-WORD beg end type count)) - -(evil-define-text-object evil-a-symbol (count &optional beg end _type) - "Select a symbol." - (evil-select-an-object 'evil-symbol beg end type count)) - -(evil-define-text-object evil-inner-symbol (count &optional beg end _type) - "Select inner symbol." - (evil-select-inner-object 'evil-symbol beg end type count)) - -(evil-define-text-object evil-a-sentence (count &optional beg end _type) - "Select a sentence." - (evil-select-an-object 'evil-sentence beg end type count)) - -(evil-define-text-object evil-inner-sentence (count &optional beg end _type) - "Select inner sentence." - (evil-select-inner-object 'evil-sentence beg end type count)) - -(evil-define-text-object evil-a-paragraph (count &optional beg end _type) - "Select a paragraph." - :type line - (evil-select-an-object 'evil-paragraph beg end type count t)) - -(evil-define-text-object evil-inner-paragraph (count &optional beg end _type) - "Select inner paragraph." - :type line - (evil-select-inner-object 'evil-paragraph beg end type count t)) - -(evil-define-text-object evil-a-paren (count &optional beg end _type) - "Select a parenthesis." - :extend-selection nil - (evil-select-paren ?\( ?\) beg end type count t)) - -(evil-define-text-object evil-inner-paren (count &optional beg end _type) - "Select inner parenthesis." - :extend-selection nil - (evil-select-paren ?\( ?\) beg end type count)) - -(evil-define-text-object evil-a-bracket (count &optional beg end _type) - "Select a square bracket." - :extend-selection nil - (evil-select-paren ?\[ ?\] beg end type count t)) - -(evil-define-text-object evil-inner-bracket (count &optional beg end _type) - "Select inner square bracket." - :extend-selection nil - (evil-select-paren ?\[ ?\] beg end type count)) - -(evil-define-text-object evil-a-curly (count &optional beg end _type) - "Select a curly bracket (\"brace\")." - :extend-selection nil - (evil-select-paren ?{ ?} beg end type count t)) - -(evil-define-text-object evil-inner-curly (count &optional beg end _type) - "Select inner curly bracket (\"brace\")." - :extend-selection nil - (evil-select-paren ?{ ?} beg end type count)) - -(evil-define-text-object evil-an-angle (count &optional beg end _type) - "Select an angle bracket." - :extend-selection nil - (evil-select-paren ?< ?> beg end type count t)) - -(evil-define-text-object evil-inner-angle (count &optional beg end _type) - "Select inner angle bracket." - :extend-selection nil - (evil-select-paren ?< ?> beg end type count)) - -(evil-define-text-object evil-a-single-quote (count &optional beg end _type) - "Select a single-quoted expression." - :extend-selection t - (evil-select-quote ?' beg end type count t)) - -(evil-define-text-object evil-inner-single-quote (count &optional beg end _type) - "Select inner single-quoted expression." - :extend-selection nil - (evil-select-quote ?' beg end type count)) - -(evil-define-text-object evil-a-double-quote (count &optional beg end _type) - "Select a double-quoted expression." - :extend-selection t - (evil-select-quote ?\" beg end type count t)) - -(evil-define-text-object evil-inner-double-quote (count &optional beg end _type) - "Select inner double-quoted expression." - :extend-selection nil - (evil-select-quote ?\" beg end type count)) - -(evil-define-text-object evil-a-back-quote (count &optional beg end _type) - "Select a back-quoted expression." - :extend-selection t - (evil-select-quote ?\` beg end type count t)) - -(evil-define-text-object evil-inner-back-quote (count &optional beg end _type) - "Select inner back-quoted expression." - :extend-selection nil - (evil-select-quote ?\` beg end type count)) - -(evil-define-text-object evil-a-tag (count &optional beg end _type) - "Select a tag block." - :extend-selection nil - (evil-select-xml-tag beg end type count t)) - -(evil-define-text-object evil-inner-tag (count &optional beg end _type) - "Select inner tag block." - :extend-selection nil - (evil-select-xml-tag beg end type count)) - -(defun evil-match (direction count) - "Find COUNTth next match in DIRECTION." - (defvar evil-search-module) - (unless (eq evil-search-module 'evil-search) - (user-error "Match text objects only work with Evil search module")) - (let ((pnt (point)) - (count (abs count)) ; Undo effect of evil-visual-direction - (evil-ex-search-direction 'backward) - (visual-state (evil-visual-state-p)) - on-start-match in-match on-end-match) - (save-excursion - (unless (eobp) (forward-char)) ; If on start of a match, stay there - (evil-ex-search 1) - (setq on-start-match (= evil-ex-search-match-beg pnt) - in-match (<= evil-ex-search-match-beg pnt (1- evil-ex-search-match-end)) - on-end-match (= (1- evil-ex-search-match-end) pnt) - evil-ex-search-direction direction) - (cond - ((and visual-state on-start-match (eq 'backward direction)) - (evil-ex-search count)) - ((and visual-state on-end-match (eq 'forward direction)) - (evil-ex-search count)) - ((or in-match (eq 'backward direction)) - (evil-ex-search (1- count))) - (t (evil-ex-search count))) - (setq pnt (point))) - (goto-char pnt) - (cond - ((evil-normal-state-p) - (evil-visual-select evil-ex-search-match-beg - evil-ex-search-match-end - 'inclusive - (pcase direction ('forward +1) ('backward -1)) - t) - (list evil-ex-search-match-beg evil-ex-search-match-end)) - ((and visual-state (eq 'forward direction)) - (goto-char (1- evil-ex-search-match-end))) - ((and visual-state (eq 'backward direction)) - (goto-char evil-ex-search-match-beg)) - ;; e.g. operator pending... - (t (list evil-ex-search-match-beg evil-ex-search-match-end))))) - -(evil-define-text-object evil-next-match (count &optional _beg _end _type) - "Select next match." - :extend-selection t - (evil-match 'forward count)) - -(evil-define-text-object evil-previous-match (count &optional _beg _end _type) - "Select previous match." - :extend-selection t - (evil-match 'backward count)) - -;;; Operator commands - -(evil-define-operator evil-yank (beg end type register yank-handler) - "Save the characters in motion into the kill-ring." - :move-point nil - :repeat nil - (interactive "<R><x><y>") - (let ((evil-was-yanked-without-register - (and evil-was-yanked-without-register (not register)))) - (cond - ((and (fboundp 'cua--global-mark-active) - (fboundp 'cua-copy-region-to-global-mark) - (cua--global-mark-active)) - (cua-copy-region-to-global-mark beg end)) - ((eq type 'block) - (evil-yank-rectangle beg end register yank-handler)) - ((memq type '(line screen-line)) - (evil-yank-lines beg end register yank-handler)) - (t - (evil-yank-characters beg end register yank-handler) - (goto-char beg))))) - -(defun evil-expand-line-for-line-based-operators (beg end type) - "Expand to line when in visual mode possibly changing BEG, END and TYPE. -Avoids double expansion for line-based commands like \"V\" or \"D\"." - (when (evil-visual-state-p) - (unless (memq type '(line block screen-line)) - ;; Subtract 1 from end to avoid expanding to the next line - ;; when \n is part of the visually selected region. - ;; If removed (evil-expand beg end 'line) - ;; will expand to the end of the next line instead of the current - ;; line which will cause line expanding commands like 'Y' to - ;; misbehave when used in visual state. - (when (eq ?\n (char-before end)) - (cl-decf end)) - (let ((range (evil-expand beg end (if (and evil-respect-visual-line-mode - visual-line-mode) - 'screen-line - 'line)))) - (setq beg (evil-range-beginning range) - end (evil-range-end range) - type (evil-type range)))) - (evil-exit-visual-state)) - (list beg end type)) - -(evil-define-operator evil-yank-line (beg end type register) - "Save whole lines into the kill-ring." - :motion evil-line-or-visual-line - :move-point nil - (interactive "<R><x>") - (cl-destructuring-bind - (beg end type) (evil-expand-line-for-line-based-operators beg end type) - (evil-yank beg end type register))) - -(evil-define-operator evil-delete (beg end type register yank-handler) - "Delete text from BEG to END with TYPE. -Save in REGISTER or in the kill-ring with YANK-HANDLER." - (interactive "<R><x><y>") - (when (and (memq type '(inclusive exclusive)) - (not (evil-visual-state-p)) - (eq 'evil-delete evil-this-operator) - (save-excursion (goto-char beg) (bolp)) - (save-excursion (goto-char end) (eolp)) - (<= 1 (evil-count-lines beg end))) - ;; Imitate Vi strangeness: if motion meets above criteria, - ;; delete linewise. Not for change operator or visual state. - (let ((new-range (evil-line-expand beg end))) - (setq beg (car new-range) - end (cadr new-range) - type 'line))) - (unless register - (let ((text (filter-buffer-substring beg end))) - (unless (string-match-p "\n" text) - ;; set the small delete register - (evil-set-register ?- text)))) - (let ((evil-was-yanked-without-register nil)) - (evil-yank beg end type register yank-handler)) - (cond - ((eq type 'block) - (evil-apply-on-block #'delete-region beg end nil)) - ((and (eq type 'line) - (= end (point-max)) - (or (= beg end) - (/= (char-before end) ?\n)) - (/= beg (point-min)) - (= (char-before beg) ?\n)) - (delete-region (1- beg) end)) - (t (delete-region beg end))) - (when (and (eq type 'line) - (called-interactively-p 'any)) - (evil-first-non-blank) - (when (and (not evil-start-of-line) - evil-operator-start-col - ;; Special exceptions to ever saving column: - (not (memq evil-this-motion '(evil-forward-word-begin - evil-forward-WORD-begin)))) - (move-to-column (if (and (eq most-positive-fixnum temporary-goal-column) - (memq last-command '(next-line previous-line))) - temporary-goal-column - evil-operator-start-col))))) - -(evil-define-operator evil-delete-line (beg end type register yank-handler) - "Delete to end of line." - :motion evil-end-of-line-or-visual-line - (interactive "<R><x>") - (cl-destructuring-bind - (beg end type) (evil-expand-line-for-line-based-operators beg end type) - (if (eq type 'block) - ;; Equivalent to $d, i.e., we use the block-to-eol selection and - ;; call `evil-delete'. In this case we fake the call to - ;; `evil-end-of-line' by setting `temporary-goal-column' and - ;; `last-command' appropriately as `evil-end-of-line' would do. - (let ((temporary-goal-column most-positive-fixnum) - (last-command 'next-line)) - (evil-delete beg end 'block register yank-handler)) - (evil-delete beg end type register yank-handler) - (when (eq 'line type) - (evil-first-non-blank) - (when (and (not evil-start-of-line) evil-operator-start-col) - (move-to-column (if (and (eq most-positive-fixnum temporary-goal-column) - (memq last-command '(next-line previous-line))) - temporary-goal-column - evil-operator-start-col))))))) - -(evil-define-operator evil-delete-whole-line - (beg end type register yank-handler) - "Delete whole line." - :motion evil-line-or-visual-line - (interactive "<R><x>") - (evil-delete beg end type register yank-handler)) - -(evil-define-operator evil-delete-char (beg end type register) - "Delete next character." - :motion evil-forward-char - (interactive "<R><x>") - (evil-delete beg end type register)) - -(evil-define-operator evil-delete-backward-char (beg end type register) - "Delete previous character." - :motion evil-backward-char - (interactive "<R><x>") - (evil-delete beg end type register)) - -(evil-define-command evil-delete-backward-char-and-join (_count) - "Delete previous character and join lines. -If point is at the beginning of a line then the current line will -be joined with the previous line if and only if -`evil-backspace-join-lines'." - (interactive "p") - (if (or evil-backspace-join-lines (not (bolp))) - (call-interactively #'delete-backward-char) - (signal 'beginning-of-line nil))) - -(evil-define-command evil-delete-backward-word () - "Delete previous word." - (let ((beg (save-excursion (evil-backward-word-begin) (point))) - (end (point))) - (cond - ((evil-replace-state-p) (while (< beg (point)) - (evil-replace-backspace))) - ((or (not (bolp)) (bobp)) (delete-region (max beg (line-beginning-position)) - end)) - (evil-backspace-join-lines (delete-char -1)) - (t (signal 'beginning-of-line nil))))) - -(evil-define-command evil-delete-back-to-indentation () - "Delete back to the first non-whitespace character. -If point is before the first non-whitespace character of a -current line then delete from the point to the beginning of the -current line. If point is on the beginning of the line, behave -according to `evil-backspace-join-lines'." - (let ((beg (if (<= (current-column) (current-indentation)) - (line-beginning-position) - (save-excursion (evil-first-non-blank) (point))))) - (cond - ((and (bolp) (evil-replace-state-p)) (evil-replace-backspace)) - ((bolp) (evil-delete-backward-char-and-join 1)) - ((evil-replace-state-p) - (while (< beg (point)) (evil-replace-backspace))) - (t (delete-region beg (point)))))) - -(defun evil-ex-delete-or-yank (should-delete beg end type register count yank-handler) - "Execute evil-delete or evil-yank on the given region. -If SHOULD-DELETE is t, evil-delete will be executed, otherwise -evil-yank. -The region specified by BEG and END will be adjusted if COUNT is -given." - (when count - ;; with COUNT, the command should go the end of the region and delete/yank - ;; COUNT lines from there - (setq beg (save-excursion (goto-char end) - (line-beginning-position 0)) - end (save-excursion (goto-char end) - (line-beginning-position count)) - type 'line)) - (funcall (if should-delete #'evil-delete #'evil-yank) - beg end type register yank-handler)) - -(evil-define-operator evil-ex-delete (beg end type register count yank-handler) - "The Ex delete command. -\[BEG,END]delete [REGISTER] [COUNT]" - (interactive "<R><xc/><y>") - (evil-ex-delete-or-yank t beg end type register count yank-handler)) - -(evil-define-operator evil-ex-yank (beg end type register count yank-handler) - "The Ex yank command. -\[BEG,END]yank [REGISTER] [COUNT]" - :restore-point t - (interactive "<R><xc/><y>") - (evil-ex-delete-or-yank nil beg end type register count yank-handler)) - -(evil-define-command evil-ex-put (_beg end ex-arg &optional force) - (interactive "<r><a><!>") - (let* ((arg-chars (remove ?\s (string-to-list ex-arg))) - (reg (or (car arg-chars) ?\")) - (text (cond - ((and (< 1 (length arg-chars)) - (/= ?= reg)) - (user-error "Trailing characters")) - ((eq ?= reg) - (evil--eval-expr (if (= 1 (length arg-chars)) - evil-last-=-register-input - (setq evil-last-=-register-input (substring ex-arg 1))))) - (t (evil-get-register reg))))) - (unless text (user-error "Nothing in register %c" reg)) - (evil-remove-yank-excluded-properties text) - (goto-char (if (= (point-max) end) end (1- end))) - (if force (evil-insert-newline-above) (evil-insert-newline-below)) - (evil-set-marker ?\[ (point)) - ;; `insert' rather than `insert-for-yank' as we want to ignore yank-handlers... - (insert (if (and (< 0 (length text)) - (eq ?\n (aref text (1- (length text))))) - (substring text 0 (1- (length text))) - text)) - (evil-set-marker ?\] (1- (point))) - (back-to-indentation) - (evil-normal-state))) - -(evil-define-operator evil-change - (beg end type register yank-handler delete-func) - "Change text from BEG to END with TYPE. -Save in REGISTER or the kill-ring with YANK-HANDLER. -DELETE-FUNC is a function for deleting text, default `evil-delete'. -If TYPE is `line', insertion starts on an empty line. -If TYPE is `block', the inserted text in inserted at each line -of the block." - (interactive "<R><x><y>") - (let ((delete-func (or delete-func #'evil-delete)) - (nlines (1+ (evil-count-lines beg end))) - opoint leftmost-point) - (save-excursion - (goto-char beg) - (setq opoint (line-beginning-position)) - (setq leftmost-point - (let ((inhibit-field-text-motion t)) (line-beginning-position)))) - (unless (eq evil-want-fine-undo t) - (evil-start-undo-step)) - (funcall delete-func beg end type register yank-handler) - (cond - ((eq type 'line) - (setq this-command 'evil-change-whole-line) ; for evil-maybe-remove-spaces - (cond - ((/= opoint leftmost-point) (evil-insert 1)) ; deletion didn't delete line - ((= opoint (point)) (evil-open-above 1)) - (t (evil-open-below 1)))) - ((eq type 'block) - (evil-insert 1 nlines)) - (t (evil-insert 1))) - (setq evil-this-register nil))) - -(evil-define-operator evil-change-line (beg end type register yank-handler) - "Change to end of line, or change whole line if characterwise visual mode." - :motion evil-end-of-line-or-visual-line - (interactive "<R><x><y>") - (if (and (evil-visual-state-p) (eq type 'inclusive)) - (cl-destructuring-bind - (beg end _type) (evil-expand-line-for-line-based-operators beg end type) - (evil-change-whole-line beg end register yank-handler)) - (evil-change beg end type register yank-handler #'evil-delete-line))) - -(evil-define-operator evil-change-whole-line - (beg end register yank-handler) - "Change whole line." - :motion evil-line-or-visual-line - :type line - (interactive "<r><x>") - (evil-change beg end 'line register yank-handler)) - -(evil-define-command evil-copy (beg end address) - "Copy lines in BEG END below line given by ADDRESS." - :motion evil-line-or-visual-line - (interactive "<r><addr>") - (goto-char (point-min)) - (forward-line address) - (let* ((txt (buffer-substring-no-properties beg end)) - (len (length txt))) - ;; ensure text consists of complete lines - (when (or (zerop len) (/= (aref txt (1- len)) ?\n)) - (setq txt (concat txt "\n"))) - (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line - (insert txt) - (forward-line -1))) - -(evil-define-command evil-move (beg end address) - "Move lines in BEG .. END below the line given by ADDRESS." - :motion evil-line-or-visual-line - (interactive "<r><addr>") - (unless (= (1+ address) (line-number-at-pos beg)) - (goto-char (point-min)) - (forward-line address) - (let* ((m (set-marker (make-marker) (point))) - (txt (buffer-substring-no-properties beg end)) - (len (length txt)) - (last-line-blank (progn (goto-char (point-max)) (bolp)))) - (delete-region beg end) - (unless last-line-blank ; as vim, preserve lack of blank last line - (progn (goto-char (point-max)) (when (bolp) (delete-char -1)))) - (goto-char m) - (set-marker m nil) - ;; ensure text consists of complete lines - (when (or (zerop len) (/= (aref txt (1- len)) ?\n)) - (setq txt (concat txt "\n"))) - (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line - (when (evil-visual-state-p) - (move-marker evil-visual-mark (point))) - (insert txt) - (forward-line -1) - (when (evil-visual-state-p) - (move-marker evil-visual-point (point)))))) - -(defun evil--check-undo-system () - (when (and (eq evil-undo-system 'undo-tree) - (not (bound-and-true-p undo-tree-mode))) - (user-error "Enable `global-undo-tree-mode' to use undo-tree commands. -Add (add-hook 'evil-local-mode-hook 'turn-on-undo-tree-mode) to your init file for undo in non-file buffers."))) - -(evil-define-command evil-undo (count) - "Undo COUNT changes in buffer using `evil-undo-function'." - :repeat abort - :jump t - (interactive "*p") - (evil--check-undo-system) - (let ((state-before evil-state)) - (unless (memq state-before '(normal visual)) (evil-normal-state)) - (funcall evil-undo-function count) - (unless (memq state-before '(normal visual)) (evil-change-state state-before)))) - -(evil-define-command evil-redo (count) - "Undo COUNT changes in buffer using `evil-redo-function'." - :repeat abort - (interactive "*p") - (evil--check-undo-system) - (funcall evil-redo-function count)) - -(evil-define-operator evil-substitute (beg end type register) - "Change a character." - :motion evil-forward-char - (interactive "<R><x>") - (evil-change beg end type register)) - -(evil-define-operator evil-upcase (beg end type) - "Convert text to upper case." - (if (eq type 'block) - (evil-apply-on-block #'evil-upcase beg end nil) - (upcase-region beg end))) - -(evil-define-operator evil-downcase (beg end type) - "Convert text to lower case." - (if (eq type 'block) - (evil-apply-on-block #'evil-downcase beg end nil) - (downcase-region beg end))) - -(evil-define-operator evil-invert-case (beg end type) - "Invert case of text." - (if (eq type 'block) - (evil-apply-on-block #'evil-invert-case beg end nil) - (save-excursion - (goto-char beg) - (while (< beg end) - (let ((char (following-char))) - (delete-char 1) - (insert-char - (if (eq (upcase char) char) (downcase char) (upcase char)))) - (setq beg (1+ beg)))))) - -(evil-define-operator evil-invert-char (beg end type) - "Invert case of character." - :motion evil-forward-char - (if (eq type 'block) - (evil-apply-on-block #'evil-invert-case beg end nil) - (evil-invert-case beg end) - (when evil-this-motion - (goto-char end) - (when (and evil-cross-lines - (not evil-move-beyond-eol) - (not (evil-visual-state-p)) - (not (evil-operator-state-p)) - (eolp) (not (eobp)) (not (bolp))) - (forward-char))))) - -(evil-define-operator evil-rot13 (beg end type) - "ROT13 encrypt text." - (if (eq type 'block) - (evil-apply-on-block #'rot13-region beg end nil) - (rot13-region beg end))) - -(evil-define-operator evil-join (beg end) - "Join the selected lines." - :motion evil-line - (let ((count (count-lines beg end)) - last-line-blank) - (when (> count 1) - (setq count (1- count))) - (goto-char beg) - (dotimes (i count) - (when (= (1+ i) count) ; i.e. we're just before the last join - (evil-move-beginning-of-line) - (setq last-line-blank (looking-at "[ \t]*$"))) - (join-line 1)) - (and last-line-blank (indent-according-to-mode)))) - -(evil-define-operator evil-join-whitespace (beg end) - "Join the selected lines without changing whitespace. -\\<evil-normal-state-map>Like \\[evil-join], \ -but doesn't insert or remove any spaces." - :motion evil-line - (let ((count (count-lines beg end))) - (when (> count 1) - (setq count (1- count))) - (goto-char beg) - (dotimes (_ count) - (evil-move-end-of-line 1) - (unless (eobp) - (delete-char 1))))) - -(evil-define-operator evil-ex-join (beg end &optional count bang) - "Join the selected lines with optional COUNT and BANG." - (interactive "<r><a><!>") - (let ((join-fn (if bang 'evil-join-whitespace 'evil-join))) - (if (not count) - ;; without count - just join the given region - (funcall join-fn beg end) - (unless (string-match-p "^[1-9][0-9]*$" count) - (user-error "Invalid count")) - ;; emulate Vim's :join when count is given - start from the - ;; end of the region and join COUNT lines from there - (save-excursion - (goto-char end) - (let ((beg-adjusted (line-beginning-position 0)) - (end-adjusted (line-beginning-position (string-to-number count)))) - (funcall join-fn beg-adjusted end-adjusted)))))) - -(defun evil--ex-string-for-print (beg end linump borderline) - "Return a string to be printed by :print etc. -Starts at line of BEG and end at line of END. -Include line number at the start of each line if LINUMP is non-nil. -Surround line denoted by BORDERLINE with dashes if non-nil." - (let ((result-string "") - (continue t) - (line-move-visual nil)) - (save-excursion - (goto-char beg) - (while continue - (let* ((line-num (line-number-at-pos)) - (border (and (natnump borderline) (= borderline line-num))) - (raw-line (thing-at-point 'line)) - (line (if (string= "\n" (substring raw-line -1)) - raw-line (concat raw-line "\n"))) - (border-length (1- (min (length line) (frame-width))))) - (when border - (setq result-string - (concat result-string (make-string border-length ?-) "\n"))) - (when linump - (setq result-string - (concat result-string - (propertize (number-to-string (line-number-at-pos)) - 'face 'line-number-current-line) - " "))) - (unless (eobp) - (setq result-string (concat result-string line))) - (when border - (setq result-string - (concat result-string (make-string border-length ?-) "\n"))) - (when (or (= (point) (progn (evil-line-move 1 t) (point))) - (> (line-end-position) end)) - (setq continue nil))))) - (string-trim-right result-string "\n"))) - -(defun evil--ex-print-to-minibuffer (string) - "Print STRING to the minibuffer for better persistence." - (let ((keymap (make-keymap)) - minibuffer-local-map) - (set-char-table-range (nth 1 keymap) t 'abort-recursive-edit) - (setq minibuffer-local-map keymap) - (read-from-minibuffer "" (propertize string 'read-only t)))) - -(defun evil--ex-print (beg end count &optional linump borderline) - "Print lines in range to the minibuffer. -Starting at BEG and ending at END + COUNT lines. -Include line number at the start of each line if LINUMP is non-nil. -Surround line denoted by BORDERLINE with dashes if non-nil." - (let* ((count (cond ((stringp count) (string-to-number count)) - ((natnump count) count) - (t 1))) - (end (save-excursion (goto-char (if (= (point-max) end) end (1- end))) - (line-end-position count))) - (substring (evil--ex-string-for-print beg end linump borderline))) - (cond ((> 1 count) (user-error "Positive count required")) - (evil--ex-global-active-p - (setq evil--ex-print-accumulator - (if (string= "" evil--ex-print-accumulator) - (concat evil--ex-print-accumulator substring) - (concat evil--ex-print-accumulator "\n" substring)))) - (t (evil--ex-print-to-minibuffer substring) - (when (string-match-p "\n" substring) - (goto-char end) - (evil-beginning-of-line)))))) - -(defun evil--global-print+clear () - "Print accumulated print output from :global print, and clear." - (let ((s evil--ex-print-accumulator)) - (unless (string= s "") - (setq evil--ex-print-accumulator "") - (evil--ex-print-to-minibuffer s)))) -(add-hook 'evil-after-global-hook #'evil--global-print+clear) - -(evil-define-command evil-ex-print (beg end &optional count) - (interactive "<r><a>") - (evil--ex-print beg end count)) - -(evil-define-command evil-ex-numbered-print (beg end &optional count) - (interactive "<r><a>") - (evil--ex-print beg end count t)) - -(evil-define-command evil-ex-z (_beg end &optional zmarks _bang) - "Display several lines of text surrounding the line specified by range. -BEG and END represent the range, ZMARKS represents the args in string form. -With a count supplied in the args, display that number of lines. Without a -count, display `evil-scroll-count' number of lines, or half the window height. -This table explains what each mark argument does. - -mark | first line | last line | new cursor line ------+-------------------------+----------------------------+---------------- -+ | current line | 1 scr (or 1 count) forward | last line -- | 1 scr (or 1 count) back | current line | last line -^ | 2 scr (or 2 count) back | 1 scr (or 1 count) back | last line -. | ½ scr (or ½ count) back | ½ scr (or ½ count) forward | last line -= | ½ scr (or ½ count) back | ½ scr (or ½ count) forward | current line - -Specifying no mark at all is the same as `+'. -If the mark is `=' a line of dashes is printed around the current line. -If a `#' is included before the mark args, the lines are numbered." - ;; TODO implement bang argument. - (interactive "<r><a><!>") - (goto-char (setq end (1- end))) - (save-match-data - (string-match "\\(#?\\)\\([^0-9]*\\)\\([0-9]*\\)" (or zmarks "")) - (cl-destructuring-bind (_ _ hs he ms me cs ce) (match-data) - (let* ((linump (/= hs he)) - (mark-string (if (= ms me) "+" (substring zmarks ms me))) - (count-string (if (= cs ce) "" (substring zmarks cs ce))) - (count (evil--get-scroll-count (string-to-number count-string))) - (max-mini-window-height 0.5)) - (cond - ((< 1 (- me ms)) - (evil-beginning-of-line) - (user-error "Too many mark args (got %d, expected 1)" (- me ms))) - ((string= "+" mark-string) - (ignore-errors (beginning-of-line count)) - (evil--ex-print end end count linump)) - ((string= "-" mark-string) - (evil-beginning-of-line) - (evil--ex-print (line-beginning-position (- 2 count)) end 1 linump)) - ((string= "^" mark-string) - (let ((end* (progn (move-end-of-line (- 1 count)) (point))) - (beg* (line-beginning-position (- 2 count)))) - (evil-beginning-of-line) - (evil--ex-print beg* end* 1 linump))) - ((string= "." mark-string) - (let ((beg* (line-beginning-position (- 1 (floor count 2)))) - (end* (progn (move-end-of-line (ceiling count 2)) (point)))) - (evil-beginning-of-line) - (evil--ex-print beg* end* 1 linump))) - ((string= "=" mark-string) - (let ((beg* (line-beginning-position (- 1 (floor count 2)))) - (end* (line-end-position (ceiling count 2)))) - (evil-beginning-of-line) - (evil--ex-print beg* end* 1 linump (line-number-at-pos end)))) - (t (evil-beginning-of-line) - (user-error "Invalid mark arg: %s" mark-string))))))) - -(evil-define-operator evil-fill (beg end) - "Fill text." - :move-point nil - :type line - (save-excursion - (ignore-errors (fill-region beg end)))) - -(evil-define-operator evil-fill-and-move (beg end) - "Fill text and move point to the end of the filled region." - :move-point nil - :type line - (let ((marker (make-marker))) - (move-marker marker (1- end)) - (ignore-errors - (fill-region beg end) - (goto-char marker) - (evil-first-non-blank)))) - -(evil-define-operator evil-indent (beg end) - "Indent text." - :move-point nil - :type line - (evil-ensure-column - (setq this-command real-this-command) ; Reset change made by evil-ensure-column - (save-restriction - (narrow-to-region beg end) - (if (save-excursion (goto-char beg) (= end (line-beginning-position 2))) - ;; since some Emacs modes can only indent one line at a time, - ;; implement "==" as a call to `indent-according-to-mode' - (indent-according-to-mode) - (goto-char beg) - (indent-region beg end)) - ;; Tabify or untabify leading whitespace characters - (when evil-indent-convert-tabs - ;; Whether tab or space should be used is determined by indent-tabs-mode - (let ((convert-fun (if indent-tabs-mode #'tabify #'untabify))) - (save-excursion - (goto-char (point-min)) - (while (not (eolp)) - (funcall convert-fun (point) (progn (skip-chars-forward " \t") (point))) - (forward-line)))))))) - -(evil-define-operator evil-indent-line (beg end) - "Indent the line." - :motion evil-line - (evil-indent beg end)) - -(evil-define-operator evil-shift-left (beg end &optional count preserve-empty) - "Shift text from BEG to END to the left. -The text is shifted to the nearest multiple of `evil-shift-width' -\(the rounding can be disabled by setting `evil-shift-round'). -If PRESERVE-EMPTY is non-nil, lines that contain only spaces are -indented, too, otherwise they are ignored. Location of point -is preserved relative to text when called from insert state. -Otherwise, it is determined by `evil-start-of-line' and/or `evil-track-eol'. -See also `evil-shift-right'." - :type line - (interactive "<r><vc>") - (evil-shift-right beg end (- (or count 1)) preserve-empty)) - -(evil-define-operator evil-shift-right (beg end &optional count preserve-empty) - "Shift text from BEG to END to the right. -The text is shifted to the nearest multiple of `evil-shift-width' -\(the rounding can be disabled by setting `evil-shift-round'). -If PRESERVE-EMPTY is non-nil, lines that contain only spaces are -indented, too, otherwise they are ignored. Location of point -is preserved relative to text when called from insert or replace states. -Otherwise, it is determined by `evil-start-of-line' and/or `evil-track-eol'. -See also `evil-shift-left'." - :type line - :move-point nil ; point is moved according to `evil-start-of-line' and state - (interactive "<r><vc>") - (setq count (or count 1)) - (let ((beg (set-marker (make-marker) beg)) - (end (set-marker (make-marker) end)) - (col-for-insert (current-column)) - first-shift) ; shift of first line - (save-excursion - (goto-char beg) - (while (< (point) end) - (let* ((indent (current-indentation)) - (new-indent - (max 0 - (if (not evil-shift-round) - (+ indent (* count evil-shift-width)) - (* (+ (/ indent evil-shift-width) - count - (cond - ((> count 0) 0) - ((zerop (mod indent evil-shift-width)) 0) - (t 1))) - evil-shift-width))))) - (unless first-shift - (setq first-shift (- new-indent indent))) - (when (or preserve-empty - (save-excursion - (skip-chars-forward " \t") - (not (eolp)))) - (indent-to new-indent 0)) - (delete-region (point) (progn (skip-chars-forward " \t") (point))) - (forward-line 1)))) - ;; in case we're in an empty buffer first-shift is still unchanged - (unless first-shift - (if (< count 0) - (setq first-shift 0) - (setq first-shift (* count evil-shift-width)) - (indent-to first-shift))) - ;; When called from insert state (C-t or C-d) the cursor should shift with the line, - ;; otherwise (normal state) its position is determined by `evil-start-of-line'. - (cond - ((or (evil-insert-state-p) (evil-replace-state-p)) - (move-to-column (max 0 (+ col-for-insert first-shift)))) - (evil-start-of-line (evil-first-non-blank)) - ((evil--stick-to-eol-p) (move-end-of-line 1)) - (t (move-to-column (or goal-column evil-operator-start-col col-for-insert)))))) - -(defun evil-delete-indentation () - "Delete all indentation on current line." - (interactive) - (save-excursion - (move-beginning-of-line nil) - (delete-region (point) (progn (skip-chars-forward " \t") (point))))) - -(evil-define-command evil-shift-right-line (count) - "Shift the current line COUNT times to the right. -The text is shifted to the nearest multiple of -`evil-shift-width'. Like `evil-shift-right' but always works on -the current line." - (interactive "<c>") - (evil-shift-right (line-beginning-position) (line-beginning-position 2) count t)) - -(evil-define-command evil-shift-left-line (count) - "Shift the current line COUNT times to the left. -The text is shifted to the nearest multiple of -`evil-shift-width'. Like `evil-shift-left' but always works on -the current line." - (interactive "<c>") - (if (and (eq 'self-insert-command last-command) - (eq ?0 (char-before))) - (progn (delete-char -1) - (evil-delete-indentation)) - (evil-shift-left (line-beginning-position) (line-beginning-position 2) count t))) - -(evil-define-operator evil-align-left (beg end _type &optional width) - "Left-align lines in the region at WIDTH columns. -The default for width is the value of `fill-column'." - :motion evil-line - :type line - (interactive "<R><a>") - (evil-justify-lines beg end 'left (if width - (string-to-number width) - 0))) - -(evil-define-operator evil-align-right (beg end _type &optional width) - "Right-align lines in the region at WIDTH columns. -The default for width is the value of `fill-column'." - :motion evil-line - :type line - (interactive "<R><a>") - (evil-justify-lines beg end 'right (if width - (string-to-number width) - fill-column))) - -(evil-define-operator evil-align-center (beg end _type &optional width) - "Center lines in the region between WIDTH columns. -The default for width is the value of `fill-column'." - :motion evil-line - :type line - (interactive "<R><a>") - (evil-justify-lines beg end 'center (if width - (string-to-number width) - fill-column))) - -(evil-define-operator evil-replace (beg end type char) - "Replace text from BEG to END with CHAR." - :motion evil-forward-char - (interactive "<R>" - (unwind-protect - (let ((evil-force-cursor 'replace)) - (evil-refresh-cursor) - (list (evil-read-key))) - (evil-refresh-cursor))) - (when char - (if (eq type 'block) - (save-excursion - (evil-apply-on-rectangle - #'(lambda (begcol endcol char) - (let ((maxcol (evil-column (line-end-position)))) - (when (< begcol maxcol) - (setq endcol (min endcol maxcol)) - (let ((beg (evil-move-to-column begcol nil t)) - (end (evil-move-to-column endcol nil t))) - (delete-region beg end) - (insert (make-string (- endcol begcol) char)))))) - beg end char)) - (goto-char beg) - (cond - ((eq char ?\n) - (delete-region beg end) - (newline) - (when evil-auto-indent - (indent-according-to-mode))) - (t - (while (< (point) end) - (if (eq (char-after) ?\n) - (forward-char) - (delete-char 1) - (insert-char char 1))) - (goto-char (max beg (1- end)))))))) - -(evil-define-command evil-paste-before - (count &optional register yank-handler) - "Paste the latest yanked text before the cursor position. -The return value is the yanked text." - :suppress-operator t - (interactive "*P<x>") - (setq count (prefix-numeric-value count)) - (if (evil-visual-state-p) - ;; This is the only difference with evil-paste-after in visual-state - (let ((evil-kill-on-visual-paste (not evil-kill-on-visual-paste))) - (evil-visual-paste count register)) - (evil-with-undo - (let* ((text (copy-sequence - (if register - (evil-get-register register) - (current-kill 0)))) - (yank-handler (or yank-handler - (when (stringp text) - (car-safe (get-text-property - 0 'yank-handler text))))) - (opoint (point))) - (when evil-paste-clear-minibuffer-first - (delete-minibuffer-contents) - (setq evil-paste-clear-minibuffer-first nil)) - (when text - (if (functionp yank-handler) - (let ((evil-paste-count count) - ;; for non-interactive use - (this-command #'evil-paste-before)) - (push-mark opoint t) - (insert-for-yank text)) - ;; no yank-handler, default - (when (vectorp text) - (setq text (evil-vector-to-string text))) - (set-text-properties 0 (length text) nil text) - (push-mark opoint t) - (dotimes (_ (or count 1)) - (insert-for-yank text)) - (setq evil-last-paste - (list #'evil-paste-before - count - opoint - opoint ; beg - (point))) ; end - (evil-set-marker ?\[ opoint) - (evil-set-marker ?\] (1- (point))) - (when (and evil-move-cursor-back - (> (length text) 0)) - (backward-char)))) - (when evil--cursor-after - (if (eq 'evil-yank-line-handler yank-handler) - (ignore-errors (evil-next-line-first-non-blank)) - (evil-forward-char 1 nil t)) - (setq evil--cursor-after nil)) - ;; no paste-pop after pasting from a register - (when register - (setq evil-last-paste nil)) - (and (> (length text) 0) text))))) - -(evil-define-command evil-paste-after - (count &optional register yank-handler) - "Paste the latest yanked text behind point. -The return value is the yanked text." - :suppress-operator t - (interactive "*P<x>") - (setq count (prefix-numeric-value count)) - (if (evil-visual-state-p) - (evil-visual-paste count register) - (evil-with-undo - (let* ((text (copy-sequence - (if register - (evil-get-register register) - (current-kill 0)))) - (yank-handler (or yank-handler - (when (stringp text) - (car-safe (get-text-property - 0 'yank-handler text))))) - (opoint (point))) - (when text - (if (functionp yank-handler) - (let ((evil-paste-count count) - ;; for non-interactive use - (this-command #'evil-paste-after)) - (insert-for-yank text)) - ;; no yank-handler, default - (when (vectorp text) - (setq text (evil-vector-to-string text))) - (set-text-properties 0 (length text) nil text) - (unless (eolp) (forward-char)) - (push-mark (point) t) - ;; TODO: Perhaps it is better to collect a list of all - ;; (point . mark) pairs to undo the yanking for COUNT > 1. - ;; The reason is that this yanking could very well use - ;; `yank-handler'. - (let ((beg (point))) - (dotimes (_ (or count 1)) - (insert-for-yank text)) - (setq evil-last-paste - (list #'evil-paste-after - count - opoint - beg ; beg - (point))) ; end - (evil-set-marker ?\[ beg) - (evil-set-marker ?\] (1- (point))) - (when (evil-normal-state-p) - (evil-move-cursor-back))))) - (when evil--cursor-after - (if (eq 'evil-yank-line-handler yank-handler) - (ignore-errors (evil-next-line-first-non-blank 1)) - (evil-forward-char 1 nil t)) - (setq evil--cursor-after nil)) - (when register - (setq evil-last-paste nil)) - (and (> (length text) 0) text))))) - -(evil-define-command evil-paste-before-cursor-after - (count &optional register yank-handler) - "The same as `evil-paste-before' but -leave the cursor just after the new text." - :suppress-operator t - (interactive "*P<x>") - (setq count (prefix-numeric-value count) - evil--cursor-after t) - (evil-paste-before count register yank-handler)) - -(evil-define-command evil-paste-after-cursor-after - (count &optional register yank-handler) - "The same as `evil-paste-after' but -leave the cursor just after the new text." - :suppress-operator t - (interactive "*P<x>") - (setq count (prefix-numeric-value count) - evil--cursor-after t) - (evil-paste-after count register yank-handler)) - -(defun evil-insert-for-yank-at-col (startcol _endcol string count) - "Insert STRING at STARTCOL." - (move-to-column startcol) - (dotimes (_ (or count 1)) - (insert-for-yank string)) - (evil-set-marker ?\] (1- (point)))) - -(evil-define-command evil-visual-paste (count &optional register) - "Paste over Visual selection." - :suppress-operator t - (interactive "*P<x>") - (setq count (prefix-numeric-value count)) - ;; evil-visual-paste is typically called from evil-paste-before or - ;; evil-paste-after, but we have to mark that the paste was from - ;; visual state - (setq this-command 'evil-visual-paste) - (let* ((text (if register - (evil-get-register register) - (current-kill 0))) - (yank-handler (car-safe (get-text-property - 0 'yank-handler text))) - (dir (evil-visual-direction)) - beg end type) - (evil-with-undo - (let ((kill-ring-yank-pointer (when kill-ring (list (current-kill 0))))) - (when (evil-visual-state-p) - (setq beg evil-visual-beginning - end evil-visual-end - type (evil-visual-type)) - ;; When pasting charwise text into linewise selection, keep trailing NL - (when (and text end - (eq 'line type) - (not (eq ?\n (aref text (1- (length text)))))) - (cl-decf end)) - (evil-visual-rotate 'upper-left) - (evil-delete beg end type (unless evil-kill-on-visual-paste ?_)) - (when (and (eq yank-handler #'evil-yank-line-handler) - (not (memq type '(line block))) - (/= end (point-max))) - (insert "\n")) - (evil-normal-state) - (when kill-ring (current-kill 1))) - ;; Effectively memoize `evil-get-register' because it can be - ;; side-effecting (e.g. for the "=" register)... - (cl-letf (((symbol-function #'evil-get-register) - (lambda (&rest _) text))) - (cond - ;; When replacing the last buffer line and it does not end - ;; in a newline, use `evil-paste-after' because - ;; `evil-delete' will have moved point to the line above. - ((cond ((eq type 'line) (= end (point-max))) - ((eq type 'block) (eq yank-handler #'evil-yank-line-handler))) - (goto-char end) - (evil-paste-after count register)) - ((and (eq type 'block) - (not (eq yank-handler #'evil-yank-block-handler)) - (not (string-match-p "\n" text))) - (evil-apply-on-block #'evil-insert-for-yank-at-col beg end t text count)) - (t (evil-paste-before count register))))) - (when evil-kill-on-visual-paste - (current-kill -1)) - ;; Ensure that gv can restore visually pasted area... - (set-marker evil-visual-point (evil-get-marker (if (< dir 0) ?\[ ?\]) t)) - (set-marker evil-visual-mark (evil-get-marker (if (< dir 0) ?\] ?\[) t)) - ;; mark the last paste as visual-paste - (setq evil-last-paste - (list (nth 0 evil-last-paste) - (nth 1 evil-last-paste) - (nth 2 evil-last-paste) - (nth 3 evil-last-paste) - (nth 4 evil-last-paste) - t))))) - -(defun evil-paste-from-register (register) - "Paste from REGISTER." - (interactive - (let ((ov (make-overlay (point) (+ (point) (if (evil-replace-state-p) 1 0))))) - (unwind-protect - (progn - (overlay-put ov 'invisible t) - (overlay-put ov 'after-string - #("\"" 0 1 (face minibuffer-prompt cursor 1))) - (list (or evil-this-register (read-char)))) - (delete-overlay ov)))) - (let ((opoint (point)) - evil-move-cursor-back) - (evil-paste-before nil register t) - (when (evil-replace-state-p) - (let* ((reg-length (- (point) opoint)) - (chars-to-delete (min (- (line-end-position) (point)) reg-length))) - ;; TODO: handle multi-line paste backspacing - (evil-update-replace-alist (point) reg-length chars-to-delete chars-to-delete) - (delete-char chars-to-delete))))) - -(defun evil-paste-last-insertion () - "Paste last insertion." - (interactive) - (evil-paste-from-register ?.)) - -(defun evil-paste-last-insertion-and-stop-insert () - "Paste last insertion and change to normal state." - (interactive) - (evil-paste-last-insertion) - (evil-normal-state)) - -(evil-define-command evil-use-register (register) - "Use REGISTER for the next command." - :keep-visual t - :repeat ignore - :suppress-operator t - (interactive "<C>") - (setq evil-this-register register)) - -(defvar evil-macro-buffer nil - "The buffer that has been active on macro recording.") - -(defvar evil-execute-normal-keys nil - "The keys used to invoke the current `evil-execute-in-normal-state'. -Can be used to detect if we are currently in that quasi-state. -With current bindings, it will be \\<evil-insert-state-map>\\[evil-execute-in-normal-state]") - -(defun evil-end-and-return-macro () - "Like `kmacro-end-macro' but also return the macro. -Remove \\<evil-insert-state-map>\\[evil-execute-in-normal-state] from the end." - ;; `end-kbd-macro' rather than `kmacro-end-macro' to allow clearing registers - (end-kbd-macro nil #'kmacro-loop-setup-function) - (let ((end-keys-seq (append evil-execute-normal-keys nil)) - (last-kbd-macro-seq (append last-kbd-macro nil))) - (unless last-kbd-macro-seq - (setq last-kbd-macro nil)) - (if (and end-keys-seq last-kbd-macro-seq) - (apply #'vector (butlast last-kbd-macro-seq (length end-keys-seq))) - last-kbd-macro))) - -(evil-define-command evil-record-macro (register) - "Record a keyboard macro into REGISTER. -If REGISTER is :, /, or ?, the corresponding command line window -will be opened instead." - :keep-visual t - :suppress-operator t - (interactive - (list (unless (and evil-this-macro defining-kbd-macro) - (or evil-this-register (evil-read-key))))) - (let (last-macro) - (cond - ((eq register ?\C-g) - (keyboard-quit)) - ((and evil-this-macro defining-kbd-macro) - (setq evil-macro-buffer nil - last-macro (ignore-errors (evil-end-and-return-macro))) - (when last-macro - (evil-set-register evil-this-macro last-macro)) - (setq evil-this-macro nil)) - ((eq register ?:) - (evil-command-window-ex)) - ((eq register ?/) - (evil-command-window-search-forward)) - ((eq register ??) - (evil-command-window-search-backward)) - ((or (<= ?0 register ?9) - (<= ?a register ?z) - (<= ?A register ?Z)) - (when defining-kbd-macro (end-kbd-macro)) - (setq evil-this-macro register - evil-last-recorded-register register) - (evil-set-register evil-this-macro nil) - (kmacro-start-macro nil) - (setq evil-macro-buffer (current-buffer))) - (t (error "Invalid register `%s'" register))))) - -(defun evil-repeat-execute-macro (flag) - "Called to record a macro execution. -FLAG is either `pre' or `post' if the function is called before resp. -after executing the command." - (pcase flag - ('pre (evil-repeat-record (this-command-keys))) - ('post (evil-repeat-record (string evil-last-register))))) - -(evil-define-command evil-execute-macro (count macro) - "Execute keyboard macro MACRO, COUNT times. -When called with a non-numerical prefix \ -\(such as \\[universal-argument]), -COUNT is infinite. MACRO is read from a register -when called interactively." - :keep-visual t - :suppress-operator t - :repeat evil-repeat-execute-macro - (interactive - (let (count macro register) - (setq count (cond ((null current-prefix-arg) 1) - ((numberp current-prefix-arg) current-prefix-arg) - (t 0)) - register (or evil-this-register (read-char))) - (cond - ((or (eq register ?:) - (and (eq register ?@) (eq evil-last-register ?:))) - (setq macro #'evil-ex-repeat - evil-last-register ?:)) - ((eq register ?@) - (unless evil-last-register - (user-error "No previously executed keyboard macro.")) - (setq macro (evil-get-register evil-last-register t))) - (t - (setq macro (evil-get-register register t) - evil-last-register register))) - (list count macro))) - (cond - ((functionp macro) - (evil-repeat-abort) - (if (zerop count) - (while t (funcall macro)) - (dotimes (_ (or count 1)) (funcall macro)))) - ((or (and (not (stringp macro)) - (not (vectorp macro))) - (member macro '("" []))) - ;; allow references to currently empty registers - ;; when defining macro - (unless evil-this-macro (user-error "No previous macro"))) - (t - (condition-case err - (evil-with-single-undo - (let (pre-command-hook post-command-hook) ; For performance - (combine-after-change-calls - (execute-kbd-macro macro count) - (setq this-command 'evil-execute-macro)))) ; For repeatability - ;; enter Normal state if the macro fails - (error - (evil-normal-state) - (signal (car err) (cdr err))))))) - -(evil-define-command evil-execute-last-recorded-macro (count) - "Execute last recorded keyboard macro COUNT times. -When called with a non-numerical prefix \ -\(such as \\[universal-argument]), -COUNT is infinite." - :keep-visual t - :suppress-operator t - (interactive - (list (cond - ((and current-prefix-arg (numberp current-prefix-arg)) current-prefix-arg) - (current-prefix-arg 0) - (t 1)))) - (if evil-last-recorded-register - (evil-execute-macro count (evil-get-register evil-last-recorded-register t)) - (user-error "No previous macro")) - (setq evil-last-register evil-last-recorded-register)) - -;;; Visual commands - -(evil-define-motion evil-visual-restore () - "Restore previous selection." - (cond - ;; Called from visual state - ((and (evil-visual-state-p) - evil-prev-visual-mark evil-prev-visual-point evil-prev-visual-selection) - (let ((tmp-visual-mark (marker-position evil-visual-mark)) - (tmp-visual-point (marker-position evil-visual-point)) - (tmp-visual-selection evil-visual-selection)) - (evil-visual-make-selection evil-prev-visual-mark - evil-prev-visual-point - evil-prev-visual-selection - t) - (move-marker evil-prev-visual-mark tmp-visual-mark) - (move-marker evil-prev-visual-point tmp-visual-point) - (setq evil-prev-visual-selection tmp-visual-selection))) - ;; Called from other state - ((and evil-visual-selection evil-visual-mark evil-visual-point) - (evil-visual-make-selection evil-visual-mark - evil-visual-point - (evil-visual-type) - t)))) - -(evil-define-motion evil-visual-exchange-corners () - "Rearrange corners in Visual Block mode. - - M---+ +---M - | | <=> | | - +---P P---+ - -For example, if mark is in the upper left corner and point -in the lower right, this function puts mark in the upper right -corner and point in the lower left." - (cond - ((eq evil-visual-selection 'block) - (let* ((point (point)) - (mark (or (mark t) point)) - (point-col (evil-column point)) - (mark-col (evil-column mark)) - (mark (save-excursion - (goto-char mark) - (evil-move-to-column point-col) - (point))) - (point (save-excursion - (goto-char point) - (evil-move-to-column mark-col) - (point)))) - (evil-visual-refresh mark point))) - (t - (evil-exchange-point-and-mark) - (evil-visual-refresh)))) - -(evil-define-command evil-visual-rotate (corner &optional beg end type) - "Move point to CORNER of the Visual selection. -Corner may be one of `upper-left', `upper-right', `lower-left' and -`lower-right': - - upper-left +---+ upper-right - | | - lower-left +---+ lower-right - -When called interactively, the selection is rotated clockwise." - :keep-visual t - (interactive - (let ((corners '(#1=upper-left upper-right lower-right lower-left #1#))) - (list (cadr (memq (evil-visual-block-corner) corners))))) - (let* ((beg (or beg (point))) - (end (or end (mark t) beg)) - (type (or type evil-this-type)) - range) - (cond - ((memq type '(rectangle block)) - (setq range (evil-block-rotate beg end :corner corner) - beg (pop range) - end (pop range)) - (unless (eq corner (evil-visual-block-corner corner beg end)) - (evil-swap beg end)) - (goto-char beg) - (when (evil-visual-state-p) - (evil-move-mark end) - (evil-visual-refresh nil nil nil :corner corner))) - ((memq corner '(upper-right lower-right)) - (goto-char (max beg end)) - (when (evil-visual-state-p) - (evil-move-mark (min beg end)))) - (t - (goto-char (min beg end)) - (when (evil-visual-state-p) - (evil-move-mark (max beg end))))))) - -;;; Insertion commands - -(defun evil-insert (count &optional vcount skip-empty-lines) - "Switch to Insert state just before point. -The insertion will be repeated COUNT times on the next VCOUNT lines, -starting at the same column. -If SKIP-EMPTY-LINES is non-nil, the insertion will not be performed -on lines on which the insertion point would be after the end of the -lines. This is the default behaviour for Visual-state insertion." - (interactive - (if (not (evil-visual-state-p)) - (list (prefix-numeric-value current-prefix-arg)) - (evil-visual-rotate 'upper-left) - (list (prefix-numeric-value current-prefix-arg) - (when (memq (evil-visual-type) '(line block)) - (1+ (evil-count-lines evil-visual-point evil-visual-mark))) - t))) - (and evil-want-fine-undo vcount (evil-start-undo-step)) - (if (and (evil-visual-state-p) (eq (evil-visual-type) 'line)) - (evil-insert-line count vcount) - (setq evil-insert-count count - evil-insert-lines nil - evil-insert-vcount (and vcount - (> vcount 1) - (list (line-number-at-pos) - (current-column) - vcount)) - evil-insert-skip-empty-lines skip-empty-lines) - (evil-insert-state 1))) - -(defun evil-append (count &optional vcount skip-empty-lines) - "Switch to Insert state just after point. -The insertion will be repeated COUNT times and repeated once for -the next VCOUNT - 1 lines starting at the same column. If -SKIP-EMPTY-LINES is non-nil, the insertion will not be performed -on lines on which the insertion point would be after the end of -the lines." - (interactive - (list (prefix-numeric-value current-prefix-arg) - (and (evil-visual-state-p) - (memq (evil-visual-type) '(line block)) - (1+ (evil-count-lines evil-visual-point evil-visual-mark))))) - (if (and (called-interactively-p 'any) - (evil-visual-state-p)) - (cond - ((or (eq (evil-visual-type) 'line) - (and (eq (evil-visual-type) 'block) - (memq last-command '(next-line previous-line)) - (eq temporary-goal-column most-positive-fixnum))) - (evil-visual-rotate 'upper-left) - (evil-append-line count vcount)) - ((eq (evil-visual-type) 'block) - (let ((column (max (evil-column evil-visual-beginning) - (evil-column evil-visual-end)))) - (evil-visual-rotate 'upper-left) - (move-to-column column t) - (evil-insert count vcount skip-empty-lines))) - (t - (evil-visual-rotate 'lower-right) - (backward-char) - (evil-append count))) - (unless (eolp) (forward-char)) - (evil-insert count vcount skip-empty-lines) - (add-hook 'post-command-hook #'evil-maybe-remove-spaces))) - -(evil-define-command evil-insert-resume (count) - "Switch to Insert state at previous insertion point. -The insertion will be repeated COUNT times. If called from visual -state, only place point at the previous insertion position but do not -switch to insert state." - :keep-visual t - :type exclusive - :jump t - (interactive "p") - (evil-goto-mark ?^ t) - (unless (evil-visual-state-p) - (evil-insert count))) - -(defun evil-quoted-insert (count) - "Like `quoted-insert' but delete COUNT chars forward in replace state. -Adds a \"^\" overlay as an input prompt." - (interactive "p") - (let* ((opoint (point)) - chars-to-delete - (ov (if (not (evil-replace-state-p)) - (make-overlay opoint opoint) - (setq chars-to-delete (min (- (line-end-position) opoint) count)) - (evil-update-replace-alist opoint count chars-to-delete) - (make-overlay opoint (+ chars-to-delete opoint))))) - (unwind-protect - (progn - (overlay-put ov 'invisible t) - (overlay-put ov 'after-string #("^" 0 1 (face escape-glyph cursor 1))) - (let (overwrite-mode) ; Force `read-quoted-char' - (quoted-insert count)) - (when chars-to-delete (delete-char chars-to-delete))) - (delete-overlay ov)))) - -(evil-define-command evil-open-above (count) - "Insert a new line above point and switch to Insert state. -The insertion will be repeated COUNT times." - :suppress-operator t - (interactive "p") - (unless (eq evil-want-fine-undo t) - (evil-start-undo-step)) - (evil-insert-newline-above) - (setq evil-insert-count count - evil-insert-lines t - evil-insert-vcount nil) - (unwind-protect - (when evil-auto-indent - (indent-according-to-mode)) - (evil-insert-state 1))) - -(evil-define-command evil-open-below (count) - "Insert a new line below point and switch to Insert state. -The insertion will be repeated COUNT times." - :suppress-operator t - (interactive "p") - (unless (eq evil-want-fine-undo t) - (evil-start-undo-step)) - (push (point) buffer-undo-list) - (evil-insert-newline-below) - (setq evil-insert-count count - evil-insert-lines t - evil-insert-vcount nil) - (unwind-protect - (when evil-auto-indent - (indent-according-to-mode)) - (evil-insert-state 1))) - -(defun evil--insert-line (count vcount non-blank-p) - "Switch to insert state at the beginning of the current line. -If NON-BLANK-P is non-nil, point is placed at the first non-blank character -on the current line. If NON-BLANK-P is nil, point is placed at column 0, -or the beginning of visual line. The insertion will be repeated COUNT times. -If VCOUNT is non nil it should be number > 0. The insertion will be repeated -in the next VCOUNT - 1 lines below the current one." - (push (point) buffer-undo-list) - (let ((move-fn (if non-blank-p #'evil-first-non-blank #'evil-beginning-of-line))) - (if (and visual-line-mode - evil-respect-visual-line-mode) - (goto-char - (max (save-excursion - (funcall move-fn) - (point)) - (save-excursion - (beginning-of-visual-line) - (point)))) - (funcall move-fn)) - (setq evil-insert-count count - evil-insert-lines nil - evil-insert-vcount - (and vcount - (> vcount 1) - (list (line-number-at-pos) - move-fn - vcount)))) - (evil-insert-state 1)) - -(defun evil-insert-line (count &optional vcount) - "Switch to insert state at beginning of current line. -Point is placed at the first non-blank character on the current -line. The insertion will be repeated COUNT times. If VCOUNT is -non nil it should be number > 0. The insertion will be repeated -in the next VCOUNT - 1 lines below the current one." - (interactive "p") - (evil--insert-line count vcount t)) - -(evil-define-command evil-insert-0-line (count &optional vcount) - "Switch to insert state at beginning of current line. -Point is placed at column 0, or the beginning of the visual line. -The insertion will be repeated COUNT times. If VCOUNT is -non nil it should be number > 0. The insertion will be repeated -in the next VCOUNT - 1 lines below the current one." - :keep-visual t - :type exclusive - (interactive "p") - (if (evil-visual-state-p) - (evil-beginning-of-line) - (evil--insert-line count vcount nil))) - -(defun evil-append-line (count &optional vcount) - "Switch to Insert state at the end of the current line. -The insertion will be repeated COUNT times. If VCOUNT is non nil -it should be number > 0. The insertion will be repeated in the -next VCOUNT - 1 lines below the current one." - (interactive "p") - (if (and visual-line-mode - evil-respect-visual-line-mode) - (end-of-visual-line) - (evil-move-end-of-line)) - (setq evil-insert-count count - evil-insert-lines nil - evil-insert-vcount - (and vcount - (> vcount 1) - (list (line-number-at-pos) - #'end-of-line - vcount))) - (evil-insert-state 1)) - -(evil-define-command evil-insert-digraph (count) - "Insert COUNT digraphs." - :repeat change - (interactive "p") - (let ((opoint (point)) - chars-to-delete insert-prompt) - (if (evil-replace-state-p) - (progn - (setq chars-to-delete (min (- (line-end-position) opoint) count) - insert-prompt (make-overlay opoint (+ chars-to-delete opoint))) - (evil-update-replace-alist opoint count chars-to-delete)) - (setq insert-prompt (make-overlay opoint opoint))) - (insert-char (evil-read-digraph-char-with-overlay insert-prompt) count) - (when chars-to-delete (delete-char chars-to-delete)))) - -(evil-define-command evil-ex-show-digraphs () - "Show a list of all available digraphs." - :repeat nil - (eval-and-compile (require 'evil-digraphs)) - (let ((columns 3)) - (evil-with-view-list - :name "evil-digraphs" - :mode-name "Evil Digraphs" - :format - (cl-loop repeat columns vconcat [("Digraph" 8 nil) ("Sequence" 16 nil)]) - :entries - (cl-loop - with xs = (append evil-digraphs-table-user evil-digraphs-table) - while xs collect - (cl-loop - repeat columns vconcat - (cl-destructuring-bind (chars . digraph) (or (pop xs) '(() . ?\ )) - (list (char-to-string digraph) (concat chars))) - into row finally return (list nil row)))))) - -(defun evil--self-insert-string (string) - "Insert STRING as if typed interactively." - (let ((chars (append string nil))) - (dolist (char chars) - (let ((last-command-event char)) - (self-insert-command 1))))) - -(defun evil-copy-from-above (arg) - "Copy characters from preceding non-blank line. -The copied text is inserted before point. -ARG is the number of lines to move backward. -See also \\<evil-insert-state-map>\\[evil-copy-from-below]." - (interactive - (cond - ;; if a prefix argument was given, repeat it for subsequent calls - ((and (null current-prefix-arg) - (eq last-command #'evil-copy-from-above)) - (setq current-prefix-arg last-prefix-arg) - (list (prefix-numeric-value current-prefix-arg))) - (t - (list (prefix-numeric-value current-prefix-arg))))) - (evil--self-insert-string (evil-copy-chars-from-line arg -1))) - -(defun evil-copy-from-below (arg) - "Copy characters from following non-blank line. -The copied text is inserted before point. -ARG is the number of lines to move forward. -See also \\<evil-insert-state-map>\\[evil-copy-from-above]." - (interactive - (cond - ((and (null current-prefix-arg) - (eq last-command #'evil-copy-from-below)) - (setq current-prefix-arg last-prefix-arg) - (list (prefix-numeric-value current-prefix-arg))) - (t - (list (prefix-numeric-value current-prefix-arg))))) - (evil--self-insert-string (evil-copy-chars-from-line arg 1))) - -;; adapted from `copy-from-above-command' in misc.el -(defun evil-copy-chars-from-line (n num &optional col) - "Return N characters from line NUM, starting at column COL. -NUM is relative to the current line and can be negative. -COL defaults to the current column." - (interactive "p") - (let ((col (or col (current-column))) prefix) - (save-excursion - (forward-line num) - (when (looking-at "[[:space:]]*$") - (if (< num 0) - (skip-chars-backward " \t\n") - (skip-chars-forward " \t\n"))) - (evil-move-beginning-of-line) - (move-to-column col) - ;; if the column winds up in middle of a tab, - ;; return the appropriate number of spaces - (when (< col (current-column)) - (if (eq (preceding-char) ?\t) - (let ((len (min n (- (current-column) col)))) - (setq prefix (make-string len ?\s) - n (- n len))) - ;; if in middle of a control char, return the whole char - (backward-char 1))) - (concat prefix - (buffer-substring (point) - (min (line-end-position) - (+ n (point)))))))) - -(defun evil-enter-replace-state (count) - "Switch to Replace state at point. -The insertion will be repeated COUNT times." - (interactive "p") - (setq evil-insert-count count) - (setq evil-insert-count count - evil-insert-lines nil - evil-insert-vcount nil) - (evil-replace-state 1)) - -;; completion -(evil-define-command evil-complete-next (&optional arg) - "Complete to the nearest following word. -Search backward if a match isn't found. -Calls `evil-complete-next-func'." - :repeat change - (interactive "P") - (if (minibufferp) - (funcall evil-complete-next-minibuffer-func) - (funcall evil-complete-next-func arg))) - -(evil-define-command evil-complete-previous (&optional arg) - "Complete to the nearest preceding word. -Search forward if a match isn't found. -Calls `evil-complete-previous-func'." - :repeat change - (interactive "P") - (if (minibufferp) - (funcall evil-complete-previous-minibuffer-func) - (funcall evil-complete-previous-func arg))) - -(evil-define-command evil-complete-next-line (&optional arg) - "Complete a whole line. -Calls `evil-complete-next-line-func'." - :repeat change - (interactive "P") - (if (minibufferp) - (funcall evil-complete-next-minibuffer-func) - (funcall evil-complete-next-line-func arg))) - -(evil-define-command evil-complete-previous-line (&optional arg) - "Complete a whole line. -Calls `evil-complete-previous-line-func'." - :repeat change - (interactive "P") - (if (minibufferp) - (funcall evil-complete-previous-minibuffer-func) - (funcall evil-complete-previous-line-func arg))) - -;;; Search - -(defun evil-repeat-search (flag) - "Called to record a search command. -FLAG is either `pre' or `post' if the function is called before resp. -after executing the command." - (cond - ((and (evil-operator-state-p) (eq flag 'pre)) - (evil-repeat-record (this-command-keys)) - (evil-clear-command-keys)) - ((and (evil-operator-state-p) (eq flag 'post)) - ;; The value of (this-command-keys) at this point should be the - ;; key-sequence that called the last command that finished the - ;; search, usually RET. Therefore this key-sequence will be - ;; recorded in the post-command of the operator. Alternatively we - ;; could do it here. - (evil-repeat-record (if evil-regexp-search - (car-safe regexp-search-ring) - (car-safe search-ring)))) - (t (evil-repeat-motion flag)))) - -(evil-define-motion evil-search-forward () - (format "Search forward for user-entered text. -Searches for regular expression if `evil-regexp-search' is t.%s" - (if (and (fboundp 'isearch-forward) - (documentation 'isearch-forward)) - (format "\n\nBelow is the documentation string \ -for `isearch-forward',\nwhich lists available keys:\n\n%s" - (documentation 'isearch-forward)) "")) - :jump t - :type exclusive - :repeat evil-repeat-search - (evil-search-incrementally t evil-regexp-search)) - -(evil-define-motion evil-search-backward () - (format "Search backward for user-entered text. -Searches for regular expression if `evil-regexp-search' is t.%s" - (if (and (fboundp 'isearch-forward) - (documentation 'isearch-forward)) - (format "\n\nBelow is the documentation string \ -for `isearch-forward',\nwhich lists available keys:\n\n%s" - (documentation 'isearch-forward)) "")) - :jump t - :type exclusive - :repeat evil-repeat-search - (evil-search-incrementally nil evil-regexp-search)) - -(evil-define-motion evil-search-next (count) - "Repeat the last search." - :jump t - :type exclusive - (let ((orig (point)) - (search-string (if evil-regexp-search - (car-safe regexp-search-ring) - (car-safe search-ring)))) - (goto-char - ;; Wrap in `save-excursion' so that multiple searches have no visual effect. - (save-excursion - (evil-search search-string isearch-forward evil-regexp-search) - (when (and (> (point) orig) - (save-excursion - (evil-adjust-cursor) - (= (point) orig))) - ;; Point won't move after first attempt and `evil-adjust-cursor' takes - ;; effect, so start again. - (evil-search search-string isearch-forward evil-regexp-search)) - (point))) - (when (and count (> count 1)) - (dotimes (_ (1- count)) - (evil-search search-string isearch-forward evil-regexp-search))))) - -(evil-define-motion evil-search-previous (count) - "Repeat the last search in the opposite direction." - :jump t - :type exclusive - (dotimes (_ (or count 1)) - (evil-search (if evil-regexp-search - (car-safe regexp-search-ring) - (car-safe search-ring)) - (not isearch-forward) evil-regexp-search))) - -(evil-define-motion evil-search-word-backward (count &optional symbol) - "Search backward for symbol under point." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (dotimes (_ (or count 1)) - (evil-search-word nil nil symbol))) - -(evil-define-motion evil-search-word-forward (count &optional symbol) - "Search forward for symbol under point." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (dotimes (_ (or count 1)) - (evil-search-word t nil symbol))) - -(evil-define-motion evil-search-unbounded-word-backward (count &optional symbol) - "Search backward for symbol under point. -The search is unbounded, i.e., the pattern is not wrapped in -\\<...\\>." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (dotimes (_ (or count 1)) - (evil-search-word nil t symbol))) - -(evil-define-motion evil-search-unbounded-word-forward (count &optional symbol) - "Search forward for symbol under point. -The search is unbounded, i.e., the pattern is not wrapped in -\\<...\\>." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (dotimes (_ (or count 1)) - (evil-search-word t t symbol))) - -(defun evil-goto-definition-imenu (string _position) - "Find definition for STRING with imenu." - (require 'imenu nil t) - (let (ientry ipos) - (when (fboundp 'imenu--make-index-alist) - (ignore-errors (setq ientry (imenu--make-index-alist))) - (setq ientry (imenu--in-alist string ientry)) - (setq ipos (cdr ientry)) - (when (and (markerp ipos) - (eq (marker-buffer ipos) (current-buffer))) - (setq ipos (marker-position ipos)) - (when (numberp ipos) - (evil-search (format "\\_<%s\\_>" (regexp-quote string)) t t ipos) - t))))) - -(defun evil-goto-definition-semantic (_string position) - "Find definition for POSITION with semantic." - (and (fboundp 'semantic-ia-fast-jump) - (ignore-errors (semantic-ia-fast-jump position)))) - -(declare-function xref-backend-identifier-at-point "xref") - -(defun evil-goto-definition-xref (_string position) - "Find definition at POSITION with xref." - (when (fboundp 'xref-find-definitions) - (let ((identifier (save-excursion - (goto-char position) - (xref-backend-identifier-at-point (xref-find-backend))))) - (condition-case nil - (progn (xref-find-definitions identifier) - t) - (user-error nil))))) - -(defun evil-goto-definition-search (string _position) - "Find definition for STRING with evil-search." - (evil-search (format "\\_<%s\\_>" (regexp-quote string)) t t (point-min)) - t) - -(evil-define-motion evil-goto-definition () - "Go to definition or first occurrence of symbol under point. -See also `evil-goto-definition-functions'." - :jump t - :type exclusive - (let* ((match (evil--find-thing t 'symbol)) - (string (car match)) - (position (cdr match))) - (if (null string) - (user-error "No symbol under cursor") - (setq isearch-forward t) - (run-hook-with-args-until-success 'evil-goto-definition-functions - string position)))) - -;;; Folding -(defun evil-fold-action (list action) - "Perform fold ACTION for each matching major or minor mode in LIST. - -ACTION will be performed for the first matching handler in LIST. For more -information on its features and format, see the documentation for -`evil-fold-list'. - -If no matching ACTION is found in LIST, an error will signaled. - -Handler errors will be demoted, so a problem in one handler will (hopefully) -not interfere with another." - (if (null list) - (user-error - "Enable one of the following modes for folding to work: %s" - (mapconcat #'symbol-name (mapcar #'caar evil-fold-list) ", ")) - (let* ((modes (caar list))) - (if (evil--mode-p modes) - (let* ((actions (cdar list)) - (fn (plist-get actions action))) - (when fn - (with-demoted-errors "Error: %S" (funcall fn)))) - (evil-fold-action (cdr list) action))))) - -(defun evil--mode-p (modes) - "Determine whether any symbol in MODES represents the current -buffer's major mode or any of its minors." - (unless (eq modes '()) - (let ((mode (car modes))) - (or (eq major-mode mode) - (and (boundp mode) (symbol-value mode)) - (evil--mode-p (cdr modes)))))) - -(evil-define-command evil-toggle-fold () - "Open or close a fold under point. -See also `evil-open-fold' and `evil-close-fold'." - (evil-fold-action evil-fold-list :toggle)) - -(evil-define-command evil-open-folds () - "Open all folds. -See also `evil-close-folds'." - (evil-fold-action evil-fold-list :open-all)) - -(evil-define-command evil-close-folds () - "Close all folds. -See also `evil-open-folds'." - (evil-fold-action evil-fold-list :close-all)) - -(evil-define-command evil-open-fold () - "Open fold at point. -See also `evil-close-fold'." - (evil-fold-action evil-fold-list :open)) - -(evil-define-command evil-open-fold-rec () - "Open fold at point recursively. -See also `evil-open-fold' and `evil-close-fold'." - (evil-fold-action evil-fold-list :open-rec)) - -(evil-define-command evil-close-fold () - "Close fold at point. -See also `evil-open-fold'." - (evil-fold-action evil-fold-list :close)) - -;;; Ex - -(evil-define-operator evil-write (beg end _type file-or-append &optional bang) - "Save the current buffer, from BEG to END, to FILE-OR-APPEND. -If FILE-OR-APPEND is of the form \">> FILE\", append to FILE -instead of overwriting. The current buffer's filename is not -changed unless it has no associated file and no region is -specified. If the file already exists and the BANG argument is -non-nil, it is overwritten without confirmation." - :motion nil - :move-point nil - :type line - :repeat nil - (interactive "<R><fsh><!>") - (let* ((append-and-filename (evil-extract-append file-or-append)) - (append (car append-and-filename)) - (filename (cdr append-and-filename)) - (bufname (buffer-file-name (buffer-base-buffer)))) - (when (zerop (length filename)) - (setq filename bufname)) - (cond - ((zerop (length filename)) - (user-error "Please specify a file name for the buffer")) - ;; execute command on region - ((eq (aref filename 0) ?!) - (shell-command-on-region beg end (substring filename 1))) - ;; with region or append, always save to file without resetting - ;; modified flag - ((or append (and beg end)) - (write-region beg end filename append nil nil (not (or append bang)))) - ;; no current file - ((null bufname) - (write-file filename (not bang))) - ;; save current buffer to its file - ((string= filename bufname) - (if (not bang) (save-buffer) (write-file filename))) - ;; save to another file - (t - (write-region nil nil filename - nil (not bufname) nil - (not bang)))))) - -(evil-define-command evil-write-all (bang) - "Save all buffers visiting a file. -If BANG is non nil then read-only buffers are saved, too, -otherwise they are skipped. " - :repeat nil - :move-point nil - (interactive "<!>") - (if bang - (save-some-buffers t) - ;; save only buffer that are not read-only and - ;; that are visiting a file - (save-some-buffers t - #'(lambda () - (and (not buffer-read-only) - (buffer-file-name)))))) - -(evil-define-command evil-update () - "Same as `evil-write', but only write when the buffer has been modified." - :motion nil - :move-point nil - :type line - :repeat nil - (when (buffer-modified-p) - (call-interactively #'evil-write))) - -(evil-define-command evil-save (filename &optional bang) - "Save the current buffer to FILENAME. -Changes the file name of the current buffer to FILENAME. If no -FILENAME is given, the current file name is used." - :repeat nil - :move-point nil - (interactive "<f><!>") - (when (zerop (length filename)) - (setq filename (buffer-file-name (buffer-base-buffer)))) - (write-file filename (not bang))) - -(evil-define-command evil-edit (file &optional bang) - "Open FILE. -If no FILE is specified, reload the current buffer from disk." - :repeat nil - (interactive "<f><!>") - (if file - (find-file file) - (revert-buffer bang (or bang (not (buffer-modified-p))) t) - (read-only-mode -1))) - -(evil-define-command evil-view (file &optional bang) - "Open FILE but don't allow changes. -If no FILE is specified, reload the current buffer from disk as read-only." - :repeat nil - (interactive "<f><!>") - (if file - (find-file-read-only file) - (revert-buffer bang (or bang (not (buffer-modified-p))) t) - (read-only-mode +1))) - -(evil-define-command evil-buffer-add (file) - "Add FILE to the buffer list, but don't visit it. " - :repeat nil - (interactive "<f>") - (if (or (not file) (string= "" file)) - (user-error "No file specified") - (find-file-noselect file))) - -(evil-define-command evil-read (count file) - "Insert the contents of FILE below the current line or line COUNT." - :repeat nil - :move-point nil - (interactive "P<fsh>") - (when (and file (not (zerop (length file)))) - (when count (goto-char (point-min))) - (when (or (not (zerop (forward-line (or count 1)))) - (not (bolp))) - (insert "\n")) - (cond - ((/= (aref file 0) ?!) - (when (member file '("#" "%")) - (setq file (evil-ex-replace-special-filenames file))) - (let ((result (insert-file-contents file))) - (save-excursion - (forward-char (cadr result)) - (unless (bolp) (insert "\n"))))) - (t - (shell-command (evil-ex-replace-special-filenames (substring file 1)) t) - (goto-char (mark)) - (unless (bolp) (insert "\n")) - (forward-line -1))))) - -(evil-define-command evil-show-files () - "Show the file-list. -The same as `buffer-menu', but shows only buffers visiting -files." - :repeat nil - (buffer-menu 1)) - -(evil-define-command evil-goto-error (count) - "Go to error number COUNT. -If no COUNT is supplied, move to the current error. - -Acts like `first-error' other than when given no counts, goes -to the current error instead of the first, like in Vim's :cc -command." - :repeat nil - (interactive "<c>") - (if count - (first-error (if (eql 0 count) 1 count)) - (next-error 0))) - -(evil-define-command evil-buffer (buffer) - "Switch to another buffer." - :repeat nil - (interactive "<b>") - (cond - ;; no buffer given, switch to "other" buffer - ((null buffer) (switch-to-buffer (other-buffer))) - ;; we are given the name of an existing buffer - ((get-buffer buffer) (switch-to-buffer buffer)) - ;; try to complete the buffer - ((let ((all-buffers (internal-complete-buffer buffer nil t))) - (when (= (length all-buffers) 1) - (switch-to-buffer (car all-buffers))))) - (t - (when (y-or-n-p - (format "No buffer with name \"%s\" exists. Create new buffer? " - buffer)) - (switch-to-buffer buffer))))) - -(evil-define-command evil-next-buffer (&optional count) - "Go to the COUNTth next buffer in the buffer list." - :repeat nil - (interactive "p") - (next-buffer count)) - -(evil-define-command evil-prev-buffer (&optional count) - "Go to the COUNTth prev buffer in the buffer list." - :repeat nil - (interactive "p") - (previous-buffer count)) - -(evil-define-command evil-delete-buffer (buffer &optional bang) - "Delete a buffer. -All windows currently showing this buffer will be closed except -for the last window in each frame." - (interactive "<b><!>") - (with-current-buffer (or buffer (current-buffer)) - (when bang - (set-buffer-modified-p nil) - (dolist (process (process-list)) - (when (eq (process-buffer process) (current-buffer)) - (set-process-query-on-exit-flag process nil)))) - ;; get all windows that show this buffer - (let ((wins (get-buffer-window-list (current-buffer) nil t))) - ;; if the buffer which was initiated by emacsclient, - ;; call `server-edit' from server.el to avoid - ;; "Buffer still has clients" message - (if (and (bound-and-true-p server-buffer-clients) - (fboundp 'server-edit)) - (server-edit) - (kill-buffer nil)) - ;; close all windows that showed this buffer - (dolist (w wins) (ignore-errors (delete-window w)))))) - -(evil-define-command evil-quit (&optional force) - "Close the current window, current frame, current tab, Emacs. -If the current frame belongs to some client the client connection -is closed." - :repeat nil - (interactive "<!>") - (condition-case nil - (evil-window-delete) - (error - (if (and (bound-and-true-p server-buffer-clients) - (fboundp 'server-edit) - (fboundp 'server-buffer-done)) - (if force - (server-buffer-done (current-buffer)) - (server-edit)) - (condition-case nil - (delete-frame) - (error - (condition-case nil - (tab-bar-close-tab) - (error - (if force - (kill-emacs) - (save-buffers-kill-emacs)))))))))) - -(evil-define-command evil-quit-all (&optional bang) - "Exit Emacs, asking for saving." - :repeat nil - (interactive "<!>") - (if (null bang) - (save-buffers-kill-terminal) - (let ((proc (frame-parameter (selected-frame) 'client))) - (if proc - (with-no-warnings - (server-delete-client proc)) - (dolist (process (process-list)) - (set-process-query-on-exit-flag process nil)) - (kill-emacs))))) - -(evil-define-command evil-quit-all-with-error-code (&optional err-code _force) - "Exit Emacs without saving, returning an non-zero error code. -The FORCE argument is only there for compatibility and is ignored. -This function fails with an error if Emacs is run in server mode." - :repeat nil - (interactive "<N><!>") - (if (bound-and-true-p server-buffer-clients) - (user-error "Cannot exit client process with error code") - (kill-emacs (or err-code 1)))) - -(evil-define-command evil-save-and-quit () - "Save all buffers and exit Emacs." - (save-buffers-kill-terminal t)) - -(evil-define-command evil-save-and-close (file &optional bang) - "Save the current buffer and close the window." - :repeat nil - (interactive "<f><!>") - (evil-write nil nil nil file bang) - (evil-quit)) - -(evil-define-command evil-save-modified-and-close (file &optional bang) - "Save the current buffer and close the window." - :repeat nil - (interactive "<f><!>") - (when (buffer-modified-p) - (evil-write nil nil nil file bang)) - (evil-quit)) - -(evil-define-operator evil-shell-command - (beg end _type command &optional previous) - "Execute a shell command. -If BEG, END and TYPE is specified, COMMAND is executed on the region, -which is replaced with the command's output. Otherwise, the -output is displayed in its own buffer. If PREVIOUS is non-nil, -the previous shell command is executed instead." - (interactive "<R><sh><!>") - (if (not evil-called-from-ex-p) - (let ((current-prefix-arg - (if (or current-prefix-arg (evil-visual-state-p)) - current-prefix-arg - (goto-char (min beg end)) - (count-lines beg end))) - (evil-ex-initial-input "!")) - (call-interactively #'evil-ex)) - (if (zerop (length command)) - (when previous (setq command evil-previous-shell-command)) - (setq command (evil-ex-replace-special-filenames command) - evil-previous-shell-command command)) - (cond - ((zerop (length command)) - (user-error "No%s shell command" (if previous " previous" ""))) - (evil-ex-range - (if (not evil-display-shell-error-in-message) - (shell-command-on-region beg end command nil t) - (let ((output-buffer (generate-new-buffer " *temp*")) - (error-buffer (generate-new-buffer " *temp*"))) - (unwind-protect - (if (zerop (shell-command-on-region - beg end command - output-buffer nil error-buffer)) - (progn - (delete-region beg end) - (insert-buffer-substring output-buffer) - (goto-char beg) - (evil-first-non-blank)) - (display-message-or-buffer error-buffer)) - (kill-buffer output-buffer) - (kill-buffer error-buffer))))) - (t (shell-command command))))) - -(evil-define-command evil-make (arg) - "Call a build command in the current directory. -If ARG is nil this function calls `recompile', otherwise it calls -`compile' passing ARG as build command." - (interactive "<sh>") - (if (and (fboundp 'recompile) - (not arg)) - (recompile) - (compile arg))) - -;; TODO: escape special characters (currently only \n) ... perhaps -;; there is some Emacs function doing this? -(evil-define-command evil-show-registers (registers) - "Show the contents of REGISTERS, or all registers, if none supplied." - :repeat nil - (interactive "<a>") - (let* ((all-registers (evil-register-list)) - (reg-chars (string-to-list registers)) - (display-regs (if reg-chars - (cl-remove-if-not (lambda (r) (memq (car r) reg-chars)) - all-registers) - all-registers))) - (evil-with-view-list - :name "evil-registers" - :mode-name "Evil Registers" - :format - [("Register" 10 nil) - ("Value" 1000 nil)] - :entries - (cl-loop for (key . val) in display-regs - collect `(nil [,(char-to-string key) - ,(cond ((stringp val) - (replace-regexp-in-string "\n" "^J" val)) - ((vectorp val) - (key-description val)) - (t ""))]))))) - -(evil-define-command evil-show-marks (mrks) - "Show all marks. -If MRKS is non-nil it should be a string and only registers -corresponding to the characters of this string are shown." - :repeat nil - (interactive "<a>") - ;; To get markers and positions, we can't rely on 'global-mark-ring' - ;; provided by Emacs (although it will be much simpler and faster), - ;; because 'global-mark-ring' does not store mark characters, but - ;; only buffer name and position. Instead, 'evil-markers-alist' is - ;; used; this is list maintained by Evil for each buffer. - (let ((all-markers - ;; get global and local marks - (append (cl-remove-if (lambda (m) - (or (evil-global-marker-p (car m)) - (not (markerp (cdr m))))) - evil-markers-alist) - (cl-remove-if (lambda (m) - (or (not (evil-global-marker-p (car m))) - (not (markerp (cdr m))))) - (default-value 'evil-markers-alist))))) - (when mrks - (setq mrks (string-to-list mrks)) - (setq all-markers (cl-delete-if (lambda (m) - (not (member (car m) mrks))) - all-markers))) - ;; map marks to list of 4-tuples (char row col file) - (setq all-markers - (mapcar (lambda (m) - (with-current-buffer (marker-buffer (cdr m)) - (save-excursion - (goto-char (cdr m)) - (list (car m) - (line-number-at-pos (point)) - (current-column) - (buffer-name))))) - all-markers)) - (evil-with-view-list - :name "evil-marks" - :mode-name "Evil Marks" - :format [("Mark" 8 nil) - ("Line" 8 nil) - ("Column" 8 nil) - ("Buffer" 1000 nil)] - :entries (cl-loop for m in (sort all-markers (lambda (a b) (< (car a) (car b)))) - collect `(nil [,(char-to-string (nth 0 m)) - ,(number-to-string (nth 1 m)) - ,(number-to-string (nth 2 m)) - (,(nth 3 m))])) - :select-action #'evil--show-marks-select-action))) - -(defun evil--show-marks-select-action (entry) - (kill-buffer) - (switch-to-buffer (car (elt entry 3))) - (evil-goto-mark (string-to-char (elt entry 0)))) - -(defun evil--parse-delmarks (to-be-parsed &optional parsed) - "Where TO-BE-PARSED can contain ranges in the form `x-y'. -PARSED is a list of characters whose marks should be deleted. -Like vim, on invalid input, preceeding valid input is still parsed." - (cl-destructuring-bind (&optional a b c &rest) to-be-parsed - (cond - ((null to-be-parsed) parsed) - ;; single mark... - ((and (not (eq ?- b)) (or (<= ?a a ?z) (<= ?A a ?Z) (<= ?0 a ?9) - (memq a '(?\" ?^ ?. ?\[ ?\] ?< ?>)))) - (evil--parse-delmarks (cdr to-be-parsed) (cons a parsed))) - ;; range of marks... - ((and (eq ?- b) c (or (<= ?a a c ?z) (<= ?A a c ?Z) (<= ?0 a c ?9))) - (evil--parse-delmarks (nthcdr 3 to-be-parsed) - (append parsed (number-sequence a c)))) - (t (progn (evil-echo "Invalid input: %s" (apply #'string (remove nil to-be-parsed))) - parsed))))) - -(evil-define-command evil-delete-marks (marks &optional force) - "MARKS is a string denoting all marks to be deleted. Mark names are -either single characters or a range of characters in the form `x-y'. -If FORCE is non-nil and MARKS is blank, all local marks except 0-9 are removed." - (interactive "<a><!>") - (let ((mark-chars (remove ?\s (append marks nil)))) - (cond - ((and force mark-chars) (evil-echo "Invalid input")) - (mark-chars - (let* ((delmarks (evil--parse-delmarks mark-chars)) - (delmarkp (lambda (m) (member (car m) delmarks)))) - ;; delete all parsed marks... - (setq evil-markers-alist - (cl-remove-if delmarkp evil-markers-alist)) - ;; ensure all parsed marks are deleted globally... - (set-default 'evil-markers-alist - (cl-remove-if delmarkp (default-value 'evil-markers-alist))))) - ;; delete local marks except 0-9... - (force (setq evil-markers-alist - (cl-remove-if-not (lambda (m) (<= ?0 (car m) ?9)) - evil-markers-alist)))))) - -(declare-function ffap-file-at-point "ffap") -(defvar ffap-string-at-point-region) -(evil-define-command evil-find-file-at-point-with-line () - "Open the file at point and go to position if present. -Supports positions in the following formats: \"path:line path(line)\", -\"path:line:col\" and \"path(line,col)\"." - (require 'ffap) - (let ((fname (ffap-file-at-point))) - (unless fname - (user-error "File does not exist.")) - (let* ((line-number-pattern ":\\([0-9]+\\)\\=" ) ; path:line format - (line-number-pattern-alt "\\=(\\([0-9]+\\))") ; path(line) format - (line-and-column-numbers-pattern ":\\([0-9]+\\):\\([0-9]+\\)\\=") ; path:line:col format - (line-and-column-numbers-pattern-alt "\\=(\\([0-9]+\\),\\([0-9]+\\))") ; file(line,col) format - (get-number (lambda (pattern match-number backward) - (save-excursion - (goto-char (cadr ffap-string-at-point-region)) - (and (if backward - (re-search-backward pattern (line-beginning-position) t) - (re-search-forward pattern (line-end-position) t)) - (string-to-number (match-string match-number)))))) - (line-number (or (funcall get-number line-and-column-numbers-pattern 1 t) - (funcall get-number line-and-column-numbers-pattern-alt 1 nil) - (funcall get-number line-number-pattern 1 t) - (funcall get-number line-number-pattern-alt 1 nil))) - (column-number (or (funcall get-number line-and-column-numbers-pattern 2 t) - (funcall get-number line-and-column-numbers-pattern-alt 2 nil)))) - (evil-echo "%s, %s" - (if line-number (format "line: %s" line-number) "no line") - (if column-number (format "column: %s" column-number) "no column")) - (find-file-at-point fname) - (when line-number - (goto-char (point-min)) - (forward-line (1- line-number)) - (when column-number - (move-to-column (1- column-number))))))) - -(evil-define-command evil-find-file-at-point-visual () - "Find the filename selected by the visual region. -Signal an error if the file does not exist." - (let ((region (buffer-substring (region-beginning) (region-end)))) - (if (file-exists-p region) - (find-file-at-point region) - (user-error "Can't find file \"%s\" in path" region)))) - -(evil-ex-define-argument-type state - "Define an argument type which can take state names." - :collection - (lambda (arg predicate flag) - (let ((completions (cons '(nil) evil-state-properties))) - (when arg - (cond - ((null flag) - (try-completion arg completions predicate)) - ((eq flag t) - (all-completions arg completions predicate)) - ((eq flag 'lambda) - (test-completion arg completions predicate)) - ((eq (car-safe flag) 'boundaries) - (cons 'boundaries - (completion-boundaries arg - completions - predicate - (cdr flag))))))))) - -(evil-define-interactive-code "<state>" - "A valid evil state." - :ex-arg state - (list (and evil-called-from-ex-p evil-ex-argument - (intern-soft evil-ex-argument)))) - -;; TODO: should we merge this command with `evil-set-initial-state'? -(evil-define-command evil-ex-set-initial-state (state) - "Set the initial state for the current major mode to STATE. -This is the state the buffer comes up in. See `evil-set-initial-state'." - :repeat nil - (interactive "<state>") - (if (not (or (assq state evil-state-properties) - (null state))) - (user-error "State %s cannot be set as initial Evil state" state) - (let ((current-initial-state (evil-initial-state major-mode))) - (unless (eq current-initial-state state) - ;; only if we selected a new mode - (when (y-or-n-p (format "Major-mode `%s' has initial mode `%s'. \ -Change to `%s'? " - major-mode - (or current-initial-state "DEFAULT") - (or state "DEFAULT"))) - (evil-set-initial-state major-mode state) - (when (y-or-n-p "Save setting in customization file? ") - (dolist (s (list current-initial-state state)) - (when s - (let ((var (intern (format "evil-%s-state-modes" s)))) - (customize-save-variable var (symbol-value var))))))))))) - -(evil-define-command evil-force-normal-state () - "Switch to normal state without recording current command." - :repeat abort - :suppress-operator t - (evil-normal-state)) - -(evil-define-motion evil-ex-search-next (count) - "Go to the next occurrence." - :jump t - :type exclusive - (evil-ex-search count)) - -(evil-define-motion evil-ex-search-previous (count) - "Go the the previous occurrence." - :jump t - :type exclusive - (let ((evil-ex-search-direction - (if (eq evil-ex-search-direction 'backward) 'forward 'backward))) - (evil-ex-search count))) - -(defun evil-repeat-ex-search (flag) - "Called to record a search command. -FLAG is either `pre' or `post' if the function is called before resp. -after executing the command." - (cond - ((and (evil-operator-state-p) (eq flag 'pre)) - (evil-repeat-record (this-command-keys)) - (evil-clear-command-keys)) - ((and (evil-operator-state-p) (eq flag 'post)) - (let ((search-separator (car (last evil-repeat-info)))) - (evil-repeat-record (evil-ex-pattern-regex evil-ex-search-pattern)) - (when evil-ex-search-offset - (evil-repeat-record (concat search-separator evil-ex-search-offset)))) - ;; If it weren't for the fact that `exit-minibuffer' throws an `exit' - ;; tag, which bypasses the source of `this-command-keys', we'd be able - ;; to capture the key(s) in the post-command of the operator as usual. - ;; Fortunately however, `last-input-event' can see the key (by default, `return') - (when (zerop (length (this-command-keys))) - (evil-repeat-record (vector last-input-event)))) - (t (evil-repeat-motion flag)))) - -(evil-define-motion evil-ex-search-forward (count) - "Start a forward search." - :jump t - :type exclusive - :repeat evil-repeat-ex-search - (evil-ex-start-search 'forward count)) - -(evil-define-motion evil-ex-search-backward (count) - "Start a backward search." - :jump t - :repeat evil-repeat-ex-search - (evil-ex-start-search 'backward count)) - -(evil-define-motion evil-ex-search-word-forward (count &optional symbol) - "Search for the next occurrence of word under the cursor." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (evil-ex-start-word-search nil 'forward count symbol)) - -(evil-define-motion evil-ex-search-word-backward (count &optional symbol) - "Search for the next occurrence of word under the cursor." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (evil-ex-start-word-search nil 'backward count symbol)) - -(evil-define-motion evil-ex-search-unbounded-word-forward (count &optional symbol) - "Search for the next occurrence of word under the cursor." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (evil-ex-start-word-search t 'forward count symbol)) - -(evil-define-motion evil-ex-search-unbounded-word-backward (count &optional symbol) - "Search for the next occurrence of word under the cursor." - :jump t - :type exclusive - (interactive (list (prefix-numeric-value current-prefix-arg) - evil-symbol-word-search)) - (evil-ex-start-word-search t 'backward count symbol)) - -(defun evil-revert-reveal (open-spots) - "Unconditionally close overlays in OPEN-SPOTS in current window. -Modified version of `reveal-close-old-overlays' from -reveal.el. OPEN-SPOTS is a local version of `reveal-open-spots'." - (dolist (spot open-spots) - (let ((window (car spot)) - (ol (cdr spot))) - (unless (eq window (selected-window)) - (error "evil-revert-reveal: slot with wrong window")) - (let* ((inv (overlay-get ol 'reveal-invisible)) - (open (or (overlay-get ol 'reveal-toggle-invisible) - (get inv 'reveal-toggle-invisible) - (overlay-get ol 'isearch-open-invisible-temporary)))) - (if (and (overlay-start ol) ; Check if still live - open) - (condition-case err - (funcall open ol t) - (error (message "!!Reveal-hide (funcall %s %s t): %s !!" - open ol err))) - (overlay-put ol 'invisible inv)) - ;; Remove the overlay from the list of open spots. - (overlay-put ol 'reveal-invisible nil))))) - -(defun evil--ex-substitute-final-message (nreplaced flags) - "Display message according to replacements and flags. -If FLAGS contains \"p\" or \"#\" and NREPLACED is more than 0, print -the last line to the echo area. Otherwise, print the number of -replacements made or found." - (let ((replaced-any (< 0 nreplaced))) - (cond - ((and replaced-any (memq ?p flags)) - (evil-echo "%s" (buffer-substring (line-beginning-position) - (line-end-position)))) - ((and replaced-any (memq ?# flags)) - (evil-echo "%s %s" (propertize (number-to-string (line-number-at-pos)) - 'face 'line-number-current-line) - (buffer-substring (line-beginning-position) - (line-end-position)))) - (t (evil-echo "%s %d occurrence%s" - (if (memq ?n flags) "Found" "Replaced") - nreplaced - (if (/= nreplaced 1) "s" "")))))) - -(evil-define-operator evil-ex-substitute - (beg end pattern replacement flags) - "The Ex substitute command. -\[BEG,END]substitute/PATTERN/REPLACEMENT/FLAGS" - :repeat nil - :jump t - :move-point nil - :motion evil-line - (interactive "<r><s/>") - (evil-ex-nohighlight) - (unless pattern (user-error "No pattern given")) - (setq replacement (or replacement "") - flags (append flags) - evil-ex-last-was-search nil - evil-ex-substitute-pattern pattern - evil-ex-substitute-replacement replacement - evil-ex-substitute-flags flags) - (let* ((inhibit-field-text-motion t) - (count-only (memq ?n flags)) - (confirm (and (memq ?c flags) (not count-only))) - (case-fold-search (evil-ex-pattern-ignore-case pattern)) - (case-replace case-fold-search) - (regex (evil-ex-pattern-regex pattern)) - (nreplaced 0) - (orig-point (point-marker)) - (last-point (point)) - (whole-line (evil-ex-pattern-whole-line pattern)) - (evil-ex-substitute-overlay (make-overlay (point) (point))) - (end-marker (move-marker (make-marker) end)) - (use-reveal confirm) - match-data - reveal-open-spots - transient-mark-mode) - (unwind-protect - (catch 'exit-search - (isearch-update-ring (setq isearch-string regex) t) - (evil-ex-hl-change 'evil-ex-substitute pattern) - (overlay-put evil-ex-substitute-overlay 'face 'isearch) - (overlay-put evil-ex-substitute-overlay 'priority 1001) - (goto-char beg) - (while (re-search-forward regex end-marker t) - (unless (and query-replace-skip-read-only - (text-property-any (match-beginning 0) (match-end 0) 'read-only t)) - (let* ((match-beg (match-beginning 0)) - (match-end (match-end 0)) - (zero-length-match (= match-beg match-end)) - match-contains-newline) - (goto-char match-beg) - (when (and (= match-beg end-marker) (> end-marker beg) (bolp)) - ;; This line is not included due to range being exclusive - (throw 'exit-search nil)) - (setq match-data (match-data t match-data) - match-contains-newline (search-forward "\n" match-end t)) - (goto-char match-end) - (if confirm - (let* ((next-replacement - (if (stringp replacement) replacement - (funcall (car replacement) (cdr replacement) nreplaced))) - (prompt - (format "Replace %s with %s (y/n/a/q/l/^E/^Y)? " - (match-string 0) - (match-substitute-replacement - next-replacement (not case-replace)))) - (search-invisible t) - response) - (move-overlay evil-ex-substitute-overlay match-beg match-end) - ;; Simulate `reveal-mode'. `reveal-mode' uses - ;; `post-command-hook' but that won't work here. - (when use-reveal - (reveal-post-command)) - (catch 'exit-read-char - (while (setq response (read-char prompt)) - (when (member response '(?y ?a ?l)) - (unless count-only - (set-match-data match-data) - (replace-match next-replacement (not case-replace))) - (cl-incf nreplaced) - (evil-ex-hl-set-region - 'evil-ex-substitute - (line-beginning-position 2) - (evil-ex-hl-get-max 'evil-ex-substitute))) - (cl-case response - ((?y ?n) (throw 'exit-read-char nil)) - (?a (setq confirm nil) - (throw 'exit-read-char nil)) - ((?q ?l ?\C-\[) (throw 'exit-search nil)) - (?\C-e (evil-scroll-line-down 1)) - (?\C-y (evil-scroll-line-up 1)))))) - (unless count-only - (let ((next-replacement - (if (stringp replacement) replacement - (funcall (car replacement) (cdr replacement) nreplaced)))) - (set-match-data match-data) - (replace-match next-replacement (not case-replace)))) - (cl-incf nreplaced)) - (setq last-point (point)) - (cond ((>= (point) end-marker) - ;; Don't want to perform multiple replacements at the end - ;; of the search region. - (throw 'exit-search nil)) - ((and (not whole-line) - (not match-contains-newline)) - (forward-line) - ;; forward-line just moves to the end of the line on the - ;; last line of the buffer. - (when (>= (point) end-marker) (throw 'exit-search nil))) - ;; For zero-length matches check to see if point won't - ;; move next time. This is a problem when matching the - ;; regexp "$" because we can enter an infinite loop, - ;; repeatedly matching the same character - ((and zero-length-match - (let ((pnt (point))) - (save-excursion - (and (re-search-forward regex end-marker t) - (= pnt (point)))))) - (when (eobp) (throw 'exit-search nil)) - (forward-char))))))) - (evil-ex-delete-hl 'evil-ex-substitute) - (delete-overlay evil-ex-substitute-overlay) - (goto-char (if count-only orig-point last-point)) - (move-marker orig-point nil) - (move-marker end-marker nil) - - (when use-reveal - (evil-revert-reveal reveal-open-spots))) - - (evil--ex-substitute-final-message nreplaced flags) - - (if (and (= nreplaced 0) evil-ex-point) - (goto-char evil-ex-point) - (evil-first-non-blank)))) - -(evil-define-operator evil-ex-repeat-substitute (beg end flags) - "Repeat last substitute command. -This is the same as \":s//~/\"." - :repeat nil - :jump t - :move-point nil - :motion evil-line - (interactive "<r><a>") - (apply #'evil-ex-substitute beg end - (evil-ex-get-substitute-info (concat "//~/" flags)))) - -(evil-define-operator evil-ex-repeat-substitute-with-flags (beg end flags) - "Repeat last substitute command with last flags. -This is the same as \":s//~/&\"." - :repeat nil - :jump t - :move-point nil - :motion evil-line - (interactive "<r><a>") - (apply #'evil-ex-substitute beg end - (evil-ex-get-substitute-info (concat "//~/&" flags)))) - -(evil-define-operator evil-ex-repeat-substitute-with-search (beg end flags) - "Repeat last substitute command with last search pattern. -This is the same as \":s//~/r\"." - :repeat nil - :jump t - :move-point nil - :motion evil-line - (interactive "<r><a>") - (apply #'evil-ex-substitute beg end - (evil-ex-get-substitute-info (concat "//~/r" flags)))) - -(evil-define-operator evil-ex-repeat-substitute-with-search-and-flags - (beg end flags) - "Repeat last substitute command with last search pattern and last flags. -This is the same as \":s//~/&r\"." - :repeat nil - :jump t - :move-point nil - :motion evil-line - (interactive "<r><a>") - (apply #'evil-ex-substitute beg end - (evil-ex-get-substitute-info (concat "//~/&r" flags)))) - -(evil-define-operator evil-ex-repeat-global-substitute () - "Repeat last substitute command on the whole buffer. -This is the same as \":%s//~/&\"." - :repeat nil - :jump t - :move-point nil - :motion evil-line - (interactive) - (apply #'evil-ex-substitute (point-min) (point-max) - (evil-ex-get-substitute-info (concat "//~/&")))) - -(declare-function hi-lock-read-face-name "hi-lock") -(evil-define-command evil-ex-match (args &optional bang) - "Define a pattern to highlight in the current buffer. -With no args, clear a highlight from the buffer -With only an ! argument, clear all highlights from the buffer. -With one arg, interpret as the pattern, and prompt for a face. -With two args, interpret as :match {face} /{pattern}/. -Unlike Vim, multiple highlights can be set at once, so there is no need for -\":2match\" and \":3match\" Ex commands." - (interactive "<a><!>") - (unless args (setq args "")) - (string-match "\\` *\\([^ ]+\\)? *\\(.+\\)?\\'" args) - (let* ((face (match-string 1 args)) - (search-string (match-string 2 args)) - (raw-patterns (evil-delimited-arguments (or search-string face ""))) - (raw-pattern (or (car raw-patterns) "")) - (case-fold-search ; ignore case if non-nil - (eq (evil-ex-regex-case raw-pattern evil-ex-search-case) 'insensitive)) - search-upper-case ; bypass isearch-no-upper-case-p - (pattern-no-case (evil-ex-regex-without-case raw-pattern)) - (pattern (if evil-ex-search-vim-style-regexp - (evil-transform-vim-style-regexp pattern-no-case) - pattern-no-case))) - (cond - ((or (not face) (string= "none" face)) - (if bang - (hi-lock-unface-buffer t) - (call-interactively #'hi-lock-unface-buffer))) - ((/= 1 (length raw-patterns)) - (user-error "Invalid pattern argument")) - ((not search-string) - (require 'hi-lock) - (hi-lock-face-buffer pattern (hi-lock-read-face-name))) - (t (hi-lock-face-buffer pattern face))))) - -(defun evil-keep-lines (pattern beg end) - "Stripped down version of `keep-lines'. -Delete lines between BEG & END which don't match PATTERN." - (goto-char (min beg end)) - (setq end - (progn - (save-excursion - (goto-char (max beg end)) - (unless (or (bolp) (eobp)) - (forward-line 0)) - (point-marker)))) - (save-excursion - (or (bolp) (forward-line 1)) - (let ((start (point))) - (while (< (point) end) - ;; Start is first char not preserved by previous match. - (if (not (re-search-forward pattern end 'move)) - (delete-region start end) - (let ((end (save-excursion (goto-char (match-beginning 0)) - (forward-line 0) - (point)))) - ;; Now end is first char preserved by the new match. - (if (< start end) - (delete-region start end)))) - - (setq start (save-excursion (forward-line 1) (point))) - ;; If the match was empty, avoid matching again at same place. - (and (< (point) end) - (= (match-beginning 0) (match-end 0)) - (forward-char 1))))) - (set-marker end nil) - nil) - -(defun evil-flush-lines (pattern beg end) - "Stripped down version of `flush-lines'. -Delete lines between BEG & END which match PATTERN." - (goto-char (min beg end)) - (setq end (copy-marker (max beg end))) - (save-excursion - (while (and (< (point) end) - (re-search-forward pattern end t)) - (delete-region (save-excursion (goto-char (match-beginning 0)) - (forward-line 0) - (point)) - (progn (forward-line 1) (point))))) - (set-marker end nil)) - -(defun evil--ex-performant-global-delete (beg end pattern invert) - "Use fast functions for fast line deletion. -Delete lines between BEG & END which match PATTERN. -Use `evil-flush-lines' if INVERT is nil, or `evil-keep-lines' if not." - (goto-char end) - (re-search-backward pattern beg t) - (let ((end-marker (point-marker))) - (if invert - (evil-keep-lines pattern beg end) - (evil-flush-lines pattern beg end)) - (goto-char end-marker) - (set-marker end-marker nil))) - -(evil-define-operator evil-ex-global - (beg end pattern command &optional invert) - "The Ex global command. -\[BEG,END]global[!]/PATTERN/COMMAND" - :motion mark-whole-buffer - :move-point nil - (interactive "<r><g/><!>") - (unless pattern - (user-error "No pattern given")) - (unless command - (user-error "No command given")) - ;; TODO: `evil-ex-make-substitute-pattern' should be executed so - ;; :substitute can re-use :global's pattern depending on its `r' - ;; flag. This isn't supported currently but should be simple to add - (let* ((case-fold-search - (eq (evil-ex-regex-case pattern evil-ex-search-case) 'insensitive)) - (pattern (evil-ex-regex-without-case pattern)) - (command-form (evil-ex-parse command)) - (ex-delete (eq 'evil-ex-delete (evil-ex-completed-binding (nth 2 command-form)))) - (transient-mark-mode transient-mark-mode) - (deactivate-mark deactivate-mark) - markers) - (when (and pattern command) - (when evil-ex-search-vim-style-regexp - (setq pattern (evil-transform-vim-style-regexp pattern))) - (if (and ex-delete (not (nth 3 command-form)) (not (nth 1 command-form))) - (evil--ex-performant-global-delete beg end pattern invert) - (setq isearch-string pattern) - (isearch-update-ring pattern t) - (goto-char beg) - (evil-move-beginning-of-line) - (while (< (point) end) - (let ((match (re-search-forward pattern (line-end-position) t))) - (when (if invert (not match) match) - (push (move-marker (make-marker) - (or (and match (match-beginning 0)) - (line-beginning-position))) - markers))) - (forward-line)) - (setq markers (nreverse markers)) - (unwind-protect - (evil-with-single-undo - (let ((evil--ex-global-active-p t)) - (dolist (marker markers) - (goto-char marker) - (eval command-form t)))) - ;; ensure that all markers are deleted afterwards, - ;; even in the event of failure - (dolist (marker markers) - (set-marker marker nil)) - (run-hooks 'evil-after-global-hook)))))) - -(evil-define-operator evil-ex-global-inverted - (beg end pattern command &optional invert) - "The Ex vglobal command. -\[BEG,END]vglobal/PATTERN/COMMAND" - :motion mark-whole-buffer - :move-point nil - (interactive "<r><g/><!>") - (evil-ex-global beg end pattern command (not invert))) - -(evil-define-operator evil-ex-normal (beg end commands) - "The Ex normal command. -Execute the argument as normal command on each line in the -range. The given argument is passed straight to -`execute-kbd-macro'. The default is the current line." - :motion evil-line - (interactive "<r><a>") - ;; replace ^[ by escape - (setq commands - (vconcat (mapcar (lambda (ch) (if (eq ch ?) 'escape ch)) - commands))) - (let (markers evil-called-from-ex-p prefix-arg current-prefix-arg) - (goto-char beg) - (beginning-of-line) - (while (when (< (point) end) - (push (point-marker) markers) - (and (= (forward-line) 0) (bolp)))) - (setq markers (nreverse markers)) - (deactivate-mark) - (evil-force-normal-state) - (evil-with-single-undo - (dolist (marker markers) - (goto-char marker) - (ignore-errors (execute-kbd-macro commands)) - (evil-force-normal-state) - (set-marker marker nil))))) - -(evil-define-motion evil-goto-char (position) - "Go to POSITION in the buffer. -Default position is the beginning of the buffer." - :jump t - (interactive "<N>") - (goto-char (or position (point-min)))) - -(evil-define-operator evil-ex-line-number (beg end) - "Print the last line number." - :motion mark-whole-buffer - :move-point nil - (interactive "<r>") - (evil-echo "%d" (count-lines (point-min) end))) - -(evil-define-command evil-show-file-info () - "Show basic file information." - (let* ((nlines (count-lines (point-min) (point-max))) - (curr (line-number-at-pos (point))) - (perc (if (> nlines 0) - (format "%d%%" (* (/ (float curr) (float nlines)) 100.0)) - "No lines in buffer")) - (file (buffer-file-name (buffer-base-buffer))) - (writable (and file (file-writable-p file))) - (readonly (if (and file (not writable)) "[readonly] " ""))) - (if file - (evil-echo "\"%s\" %d %slines --%s--" file nlines readonly perc) - (evil-echo "%d lines --%s--" nlines perc)))) - -(defvar sort-fold-case) -(evil-define-operator evil-ex-sort (beg end &optional args reverse) - "The Ex sort command. -\[BEG,END]sort[!] [/PATTERN/] [b][i][u][r][n][x][o] -The following additional options are supported: - - * i ignore case - * u remove duplicate lines - * r sort the contents of pattern - * n sort by the first decimal number - * x sort by the first hexadecimal number (with optional \"0x\" prefix) - * o sort by the first octal number - * b sort by the first binary number - -If a pattern is supplied without supplying the \"r\" option, sort -the contents of the lines after skipping the pattern. -If the pattern is empty, the last search pattern is used instead. - -The \"!\" argument means to sort in reverse order." - :motion mark-whole-buffer - :move-point nil - (interactive "<r><a><!>") - (unless args (setq args "")) - (let ((inhibit-field-text-motion t) - options sort-fold-case unique base sort-pat pat) - ;; Handle arguments like - ;; /[^,]*,/ n - ;; and - ;; nu - (if (or (zerop (length args)) (memq (aref args 0) '(?i ?n ?x ?o ?b ?u ?r))) - (setq options args) - (setq args (evil-delimited-arguments args 2) - ;; Use last search pattern when an empty pattern is provided - pat (if (string= (car args) "") - (evil-ex-pattern-regex evil-ex-search-pattern) - (car args)) - options (cadr args))) - (cl-loop - for opt across options do - (cond - ((eq opt ?i) (setq sort-fold-case t)) - ((eq opt ?b) (setq base 2)) - ((eq opt ?o) (setq base 8)) - ((eq opt ?n) (setq base 10)) - ((eq opt ?x) (setq base 16)) - ((eq opt ?r) (setq sort-pat t)) - ((eq opt ?u) (setq unique t)) - ((eq opt ? )) - (t (user-error "Invalid sort option `%c'" opt)))) - (evil-with-restriction beg end - (goto-char beg) - (let ((num-re - (cond - ((null base) nil) - ((= base 2) "[01]+") - ((= base 8) "[0-7]+") - ((= base 10) "-?[0-9]+") - ((= base 16) "\\(-\\)?\\(?:0x\\)?\\([0-9a-f]+\\)"))) - key-end) - (sort-subr - reverse - #'forward-line - #'end-of-line - (lambda () - ;; Find the boundary of the key to match on the line - (setq key-end (line-end-position)) - (and (> (length pat) 0) - ;; When matching a pattern and one doesn't exist on the line, - ;; skip the line - (re-search-forward pat key-end 'move) - sort-pat ; Otherwise go to the start of the key - (progn (setq key-end (point)) - (goto-char (match-beginning 0)))) - ;; Return the key for the line when sorting numbers, otherwise let - ;; `sort-subr' extract the key - (when base - (let ((case-fold-search t)) - (if (not (re-search-forward num-re key-end t)) - ;; When sorting numbers and a number doesn't exist on the - ;; line, place it above all the numeric lines - most-negative-fixnum - (let ((num (string-to-number - (buffer-substring - (match-beginning (if (= base 16) 2 0)) - (match-end 0)) - base))) - (if (and (= base 16) (match-beginning 1)) - (- num) - num)))))) - ;; Only called when sorting lexicographically - (lambda () (goto-char key-end)))) - (when unique - (goto-char (point-min)) - (let ((case-fold-search sort-fold-case) - prev-line-beg) - (while (not (eobp)) - (if (and prev-line-beg - (eq 0 (compare-buffer-substrings - nil prev-line-beg (1- (point)) - nil (point) (line-end-position)))) - (delete-region (point) (line-beginning-position 2)) - (setq prev-line-beg (point)) - (forward-line))))))) - (goto-char beg)) - -;;; Window navigation - -(defvar evil--window-digit nil) - -(defun evil--window-keep-pred () - (eq 'evil-window-digit-argument this-command)) - -(defun evil--window-reset-digit () - (setq evil--window-digit nil) - (remove-hook 'post-command-hook #'evil--window-reset-digit)) - -(defun evil--window-on-exit () - (add-hook 'post-command-hook #'evil--window-reset-digit)) - -(defun evil-window-digit-argument () - "Like `digit-argument' but maintains the window map." - (interactive) - (unless (eq 'evil-window-digit-argument last-command) - (set-transient-map evil-window-map #'evil--window-keep-pred #'evil--window-on-exit)) - (let* ((char (if (integerp last-command-event) - last-command-event - (get last-command-event 'ascii-character))) - (digit (- (logand char ?\177) ?0))) - (setq evil--window-digit (+ (* 10 (or evil--window-digit 0)) digit)))) - -(defmacro evil-save-side-windows (&rest body) - "Toggle side windows, evaluate BODY, restore side windows." - (declare (indent defun) (debug (&rest form))) - (let ((sides (make-symbol "sidesvar"))) - `(let ((,sides (and (fboundp 'window-toggle-side-windows) - (window-with-parameter 'window-side)))) - ;; The compiler doesn't understand that all uses are protected - ;; by `fboundp' :-( - (declare-function window-toggle-side-windows "window") - (when ,sides - (window-toggle-side-windows)) - (unwind-protect - (progn ,@body) - (when ,sides - (window-toggle-side-windows)))))) - -(defun evil-resize-window (new-size &optional horizontal) - "Set the current window's width or height to NEW-SIZE. -If HORIZONTAL is non-nil the width of the window is changed, -otherwise its height is changed." - (let ((count (- new-size (if horizontal (window-width) (window-height))))) - (enlarge-window count horizontal))) - -(defun evil-move-window (side) - "Move the `selected-window' to SIDE. -The state of the `selected-window' is saved along with the state -of the window tree consisting of all the other windows. Then, all -windows are deleted, the remaining window is split according to -SIDE, the state of the window at SIDE is replaced with the saved -state of the `selected-window', and, finally, the state of the -saved window tree is reconstructed on the opposite side. - -SIDE has the same meaning as in `split-window'. - -Note, this function only operates on the window tree rooted in -the frame's main window and effectively preserves any side -windows (i.e. windows with a valid window-side window -parameter)." - (evil-save-side-windows - (unless (one-window-p) - (save-excursion - (let ((w (window-state-get (selected-window)))) - (delete-window) - (let ((wtree (window-state-get))) - (delete-other-windows) - (let ((subwin (selected-window)) - ;; NOTE: SIDE is new in Emacs 24 - (newwin (split-window nil nil side))) - (window-state-put wtree subwin) - (window-state-put w newwin) - (select-window newwin))))) - (balance-windows)))) - -(defun evil-alternate-buffer (&optional window) - "Return the last buffer WINDOW has displayed other than the current one. -This is equivalent to Vim's alternate buffer." - ;; If the last buffer visited has been killed, then `window-prev-buffers' - ;; returns a list with `window-buffer' at the head. - (let* ((prev-buffers (window-prev-buffers)) - (head (car prev-buffers))) - (if (eq (car head) (window-buffer window)) - (cadr prev-buffers) - head))) - -(evil-define-command evil-switch-to-windows-last-buffer () - "Switch to the last open buffer of the current window." - :repeat nil - (let ((previous-place (evil-alternate-buffer))) - (when previous-place - (switch-to-buffer (car previous-place))))) - -(evil-define-command evil-window-delete () - "Delete the current window or tab. -If `evil-auto-balance-windows' is non-nil then all children of -the deleted window's parent window are rebalanced." - (let ((p (window-parent))) - ;; If tabs are enabled and this is the only visible window, then attempt to - ;; close this tab. - (if (and (bound-and-true-p tab-bar-mode) - (null p)) - (tab-close) - (delete-window) - (when evil-auto-balance-windows - ;; balance-windows raises an error if the parent does not have - ;; any further children (then rebalancing is not necessary anyway) - (ignore-errors (balance-windows p)))))) - -(evil-define-command evil-window-split (&optional count file read-only) - "Split the current window horizontally, COUNT lines height, -editing a certain FILE. The new window will be created below -when `evil-split-window-below' is non-nil. If COUNT and -`evil-auto-balance-windows' are both non-nil then all children -of the parent of the splitted window are rebalanced." - :repeat nil - (interactive "<wc><f>") - (select-window - (split-window (selected-window) (when count (- count)) - (if evil-split-window-below 'below 'above))) - (when (and (not count) evil-auto-balance-windows) - (balance-windows (window-parent))) - (when file - (funcall (if read-only #'evil-view #'evil-edit) file))) - -(evil-define-command evil-window-split-view (&optional count file) - "As with `evil-window-split' but the file is opened read-only." - :repeat nil - (interactive "<c><f>") - (evil-window-split count file t)) - -(evil-define-command evil-window-vsplit (&optional count file) - "Split the current window vertically, COUNT columns width, -editing a certain FILE. The new window will be created to the -right when `evil-vsplit-window-right' is non-nil. If COUNT and -`evil-auto-balance-windows'are both non-nil then all children -of the parent of the splitted window are rebalanced." - :repeat nil - (interactive "<wc><f>") - (select-window - (split-window (selected-window) (when count (- count)) - (if evil-vsplit-window-right 'right 'left))) - (when (and (not count) evil-auto-balance-windows) - (balance-windows (window-parent))) - (when file - (evil-edit file))) - -(evil-define-command evil-split-buffer (buffer) - "Split window and switch to another buffer." - :repeat nil - (interactive "<b>") - (evil-window-split) - (evil-buffer buffer)) - -(evil-define-command evil-split-next-buffer (&optional count) - "Split the window and go to the COUNT-th next buffer in the buffer list." - :repeat nil - (interactive "p") - (evil-window-split) - (next-buffer count)) - -(evil-define-command evil-split-prev-buffer (&optional count) - "Split window and go to the COUNT-th prev buffer in the buffer list." - :repeat nil - (interactive "p") - (evil-window-split) - (previous-buffer count)) - -(evil-define-command evil-window-left (count) - "Move the cursor to new COUNT-th window left of the current one." - :repeat nil - (interactive "<w>") - (dotimes (_ count) - (windmove-left))) - -(evil-define-command evil-window-right (count) - "Move the cursor to new COUNT-th window right of the current one." - :repeat nil - (interactive "<w>") - (dotimes (_ count) - (windmove-right))) - -(evil-define-command evil-window-up (count) - "Move the cursor to new COUNT-th window above the current one." - :repeat nil - (interactive "<w>") - (dotimes (_ (or count 1)) - (windmove-up))) - -(evil-define-command evil-window-down (count) - "Move the cursor to new COUNT-th window below the current one." - :repeat nil - (interactive "<w>") - (dotimes (_ (or count 1)) - (windmove-down))) - -(evil-define-command evil-window-bottom-right () - "Move the cursor to bottom-right window." - :repeat nil - (let ((last-sibling (frame-root-window))) - (while (and last-sibling (not (window-live-p last-sibling))) - (setq last-sibling (window-last-child last-sibling))) - (when last-sibling - (select-window last-sibling)))) - -(evil-define-command evil-window-top-left () - "Move the cursor to top-left window." - :repeat nil - (let ((first-child (window-child (frame-root-window)))) - (while (and first-child (not (window-live-p first-child))) - (setq first-child (window-child first-child))) - (when first-child - (select-window - first-child)))) - -(evil-define-command evil-window-mru () - "Move the cursor to the previous (last accessed) buffer in another window. -More precisely, it selects the most recently used buffer that is -shown in some other window, preferably of the current frame, and -is different from the current one." - :repeat nil - (catch 'done - (dolist (buf (buffer-list (selected-frame))) - (let ((win (get-buffer-window buf))) - (when (and (not (eq buf (current-buffer))) - win - (not (eq win (selected-window)))) - (select-window win) - (throw 'done nil)))))) - -(evil-define-command evil-window-next (count) - "Move the cursor to the next window in the cyclic order. -With COUNT go to the count-th window in the order starting from -top-left." - :repeat nil - (interactive "<wc>") - (if (not count) - (other-window +1) - (evil-window-top-left) - (other-window (1- (min count (length (window-list))))))) - -(evil-define-command evil-window-prev (count) - "Move the cursor to the previous window in the cyclic order. -With COUNT go to the count-th window in the order starting from -top-left." - :repeat nil - (interactive "<wc>") - (if (not count) - (other-window -1) - (evil-window-top-left) - (other-window (1- (min count (length (window-list))))))) - -(evil-define-command evil-window-new (count file) - "Split the current window horizontally -and open a new buffer or edit a certain FILE." - :repeat nil - (interactive "<wc><f>") - (let ((new-window (split-window (selected-window) (when count (- count)) - (if evil-split-window-below 'below 'above)))) - (when (and (not count) evil-auto-balance-windows) - (balance-windows (window-parent))) - (select-window new-window) - (evil-buffer-new file))) - -(evil-define-command evil-window-vnew (count file) - "Split the current window vertically -and open a new buffer name or edit a certain FILE." - :repeat nil - (interactive "<wc><f>") - (let ((new-window (split-window (selected-window) (when count (- count)) - (if evil-vsplit-window-right 'right 'left)))) - (when (and (not count) evil-auto-balance-windows) - (balance-windows (window-parent))) - (select-window new-window) - (evil-buffer-new file))) - -(evil-define-command evil-buffer-new (&optional file) - "Edit a new unnamed buffer or FILE." - :repeat nil - (interactive "<f>") - (if file - (evil-edit file) - (let ((buffer (generate-new-buffer "*new*"))) - (set-buffer-major-mode buffer) - (set-window-buffer nil buffer)))) - -(evil-define-command evil-window-increase-height (count) - "Increase current window height by COUNT." - :repeat nil - (interactive "<w>") - (enlarge-window count)) - -(evil-define-command evil-window-decrease-height (count) - "Decrease current window height by COUNT." - :repeat nil - (interactive "<w>") - (enlarge-window (- count))) - -(evil-define-command evil-window-increase-width (count) - "Increase current window width by COUNT." - :repeat nil - (interactive "<w>") - (enlarge-window count t)) - -(evil-define-command evil-window-decrease-width (count) - "Decrease current window width by COUNT." - :repeat nil - (interactive "<w>") - (enlarge-window (- count) t)) - -(evil-define-command evil-window-set-height (count) - "Set the height of the current window to COUNT." - :repeat nil - (interactive "<wc>") - (evil-resize-window (or count (frame-height)) nil)) - -(evil-define-command evil-window-set-width (count) - "Set the width of the current window to COUNT." - :repeat nil - (interactive "<wc>") - (evil-resize-window (or count (frame-width)) t)) - -(evil-define-command evil-ex-resize (arg) - "The ex :resize command. - -If ARG is a signed positive integer, increase the current window -height by ARG. - -If ARG is a signed negative integer, decrease the current window -height by ARG. - -If ARG is a positive integer without explicit sign, set the current -window height to ARG. - -If ARG is empty, maximize the current window height." - (interactive "<a>") - (if (or (not arg) (= 0 (length arg))) - (evil-window-set-height nil) - (let ((n (string-to-number arg))) - (if (> n 0) - (if (= ?+ (aref arg 0)) - (evil-window-increase-height n) - (evil-window-set-height n)) - (evil-window-decrease-height (- n)))))) - -(evil-define-command evil-window-rotate-upwards () - "Rotate the windows according to the current cyclic ordering." - :repeat nil - (evil-save-side-windows - (let ((wlist (window-list)) - (slist (mapcar #'window-state-get (window-list)))) - (setq slist (append (cdr slist) (list (car slist)))) - (while (and wlist slist) - (window-state-put (car slist) (car wlist)) - (setq wlist (cdr wlist) - slist (cdr slist))) - (select-window (car (window-list)))))) - -(evil-define-command evil-window-rotate-downwards () - "Rotate the windows according to the current cyclic ordering." - :repeat nil - (evil-save-side-windows - (let ((wlist (window-list)) - (slist (mapcar #'window-state-get (window-list)))) - (setq slist (append (last slist) slist)) - (while (and wlist slist) - (window-state-put (car slist) (car wlist)) - (setq wlist (cdr wlist) - slist (cdr slist))) - (select-window (car (window-list)))))) - -(evil-define-command evil-window-exchange (&optional count) - "Exchange the current window with the next, or the COUNT-th, one." - :repeat nil - (interactive "<wc>") - (let ((original-window (selected-window))) - (evil-window-next count) - (if (fboundp 'window-swap-states) - (window-swap-states nil original-window t) - (let* ((other-window (selected-window)) - (original-state (window-state-get original-window)) - (other-state (window-state-get other-window))) - (window-state-put other-state original-window t) - (window-state-put original-state other-window t))))) - -(evil-define-command evil-window-move-very-top () - "Close the current window, split the upper-left one horizontally -and redisplay the current buffer there." - :repeat nil - (evil-move-window 'above)) - -(evil-define-command evil-window-move-far-left () - "Close the current window, split the upper-left one vertically -and redisplay the current buffer there." - :repeat nil - (evil-move-window 'left)) - -(evil-define-command evil-window-move-far-right () - "Close the current window, split the lower-right one vertically -and redisplay the current buffer there." - :repeat nil - (evil-move-window 'right)) - -(evil-define-command evil-window-move-very-bottom () - "Close the current window, split the lower-right one horizontally -and redisplay the current buffer there." - :repeat nil - (evil-move-window 'below)) - -;;; Tab commands - -(evil-define-command evil-tab-next (arg) - "Switch to the next tab. -If ARG is non-nil, parse ARG as an index and go to the tab at that -index." - :repeat nil - (interactive "<c>") - (if arg - (tab-bar-select-tab arg) - (tab-bar-switch-to-next-tab))) - -;;; Mouse handling - -;; Large parts of this code are taken from mouse.el which is -;; distributed with GNU Emacs -(defun evil-mouse-drag-region (start-event) - "Set the region to the text that the mouse is dragged over. -Highlight the drag area as you move the mouse. -This must be bound to a button-down mouse event. - -If the click is in the echo area, display the `*Messages*' buffer. - -START-EVENT should be the event that started the drag." - (interactive "e") - ;; Give temporary modes such as isearch a chance to turn off. - (run-hooks 'mouse-leave-buffer-hook) - (evil-mouse-drag-track start-event t)) -(evil-set-command-property 'evil-mouse-drag-region :keep-visual t) - -;; Make sure `touch-screen-handle-touch' processes touch screen gestures by -;; ignoring `evil-mouse-drag-region' (bound to `down-mouse-1') during mouse -;; click emulation. -(put 'evil-mouse-drag-region 'ignored-mouse-command t) - -(defun evil-mouse-drag-track (start-event &optional - do-mouse-drag-region-post-process) - "Track mouse drags by highlighting area between point and cursor. -The region will be defined with mark and point. -DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by -`mouse-drag-region'." - (mouse-minibuffer-check start-event) - (setq mouse-selection-click-count-buffer (current-buffer)) - (deactivate-mark) - (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541). - (original-window (selected-window)) - ;; We've recorded what we needed from the current buffer and - ;; window, now let's jump to the place of the event, where things - ;; are happening. - (_ (mouse-set-point start-event)) - (echo-keystrokes 0) - (start-posn (event-start start-event)) - (start-point (posn-point start-posn)) - (start-window (posn-window start-posn)) - (start-window-start (window-start start-window)) - (start-hscroll (window-hscroll start-window)) - (bounds (window-edges start-window)) - (make-cursor-line-fully-visible nil) - (top (nth 1 bounds)) - (bottom (if (or (window-minibuffer-p start-window) - (not mode-line-format)) - (nth 3 bounds) - ;; Don't count the mode line. - (1- (nth 3 bounds)))) - (on-link (and mouse-1-click-follows-link - (or mouse-1-click-in-non-selected-windows - (eq start-window original-window)) - ;; Use start-point before the intangibility - ;; treatment, in case we click on a link inside an - ;; intangible text. - (mouse-on-link-p start-posn))) - (click-count (1- (event-click-count start-event))) - (remap-double-click (and on-link - (eq mouse-1-click-follows-link 'double) - (= click-count 1))) - ;; Suppress automatic hscrolling, because that is a nuisance - ;; when setting point near the right fringe (but see below). - (auto-hscroll-mode-saved auto-hscroll-mode) - (auto-hscroll-mode nil) - event end end-point) - - (setq mouse-selection-click-count click-count) - ;; In case the down click is in the middle of some intangible text, - ;; use the end of that text, and put it in START-POINT. - (if (< (point) start-point) - (goto-char start-point)) - (setq start-point (point)) - (if remap-double-click - (setq click-count 0)) - - (setq click-count (mod click-count 4)) - - ;; activate correct visual state - (let ((range (evil-mouse-start-end start-point start-point click-count))) - (set-mark (nth 0 range)) - (goto-char (nth 1 range))) - - (cond - ((= click-count 0) - (when (evil-visual-state-p) (evil-exit-visual-state))) - ((= click-count 1) - (evil-visual-char) - (evil-visual-post-command)) - ((= click-count 2) - (evil-visual-line) - (evil-visual-post-command)) - ((= click-count 3) - (evil-visual-block) - (evil-visual-post-command))) - - ;; Track the mouse until we get a non-movement event. - (track-mouse - (while (progn - (setq event (read-key)) - (or (mouse-movement-p event) - (memq (car-safe event) '(switch-frame select-window)))) - (unless (evil-visual-state-p) - (cond - ((= click-count 0) (evil-visual-char)) - ((= click-count 1) (evil-visual-char)) - ((= click-count 2) (evil-visual-line)) - ((= click-count 3) (evil-visual-block)))) - - (evil-visual-pre-command) - (unless (memq (car-safe event) '(switch-frame select-window)) - ;; Automatic hscrolling did not occur during the call to - ;; `read-event'; but if the user subsequently drags the - ;; mouse, go ahead and hscroll. - (let ((auto-hscroll-mode auto-hscroll-mode-saved)) - (redisplay)) - (setq end (event-end event) - end-point (posn-point end)) - (if (and (eq (posn-window end) start-window) - (integer-or-marker-p end-point)) - (evil-mouse--drag-set-mark-and-point start-point - end-point click-count) - (let ((mouse-row (cdr (cdr (mouse-position))))) - (cond - ((null mouse-row)) - ((< mouse-row top) - (mouse-scroll-subr start-window (- mouse-row top) - nil start-point)) - ((>= mouse-row bottom) - (mouse-scroll-subr start-window (1+ (- mouse-row bottom)) - nil start-point)))))) - (evil-visual-post-command))) - - ;; Store the fact that the current region was set by the mouse - (setq evil--region-from-mouse t) - - ;; Handle the terminating event if possible. - (when (consp event) - ;; Ensure that point is on the end of the last event. - (when (and (setq end-point (posn-point (event-end event))) - (eq (posn-window end) start-window) - (integer-or-marker-p end-point) - (/= start-point end-point)) - (evil-mouse--drag-set-mark-and-point start-point - end-point click-count)) - - ;; Find its binding. - (let* ((fun (key-binding (vector (car event)))) - (do-multi-click (and (> (event-click-count event) 0) - (functionp fun) - (not (memq fun '(mouse-set-point - mouse-set-region)))))) - (if (and (or (/= (mark) (point)) - (= click-count 1) ; word selection - (and (memq (evil-visual-type) '(line block)))) - (not do-multi-click)) - - ;; If point has moved, finish the drag. - (let (last-command this-command) - (and mouse-drag-copy-region - do-mouse-drag-region-post-process - (let (deactivate-mark) - (evil-visual-expand-region) - (copy-region-as-kill (mark) (point)) - (evil-visual-contract-region)))) - - ;; If point hasn't moved, run the binding of the - ;; terminating up-event. - (if do-multi-click - (goto-char start-point) - (deactivate-mark)) - (when (and (functionp fun) - (= start-hscroll (window-hscroll start-window)) - ;; Don't run the up-event handler if the window - ;; start changed in a redisplay after the - ;; mouse-set-point for the down-mouse event at - ;; the beginning of this function. When the - ;; window start has changed, the up-mouse event - ;; contains a different position due to the new - ;; window contents, and point is set again. - (or end-point - (= (window-start start-window) - start-window-start))) - (when (and on-link - (= start-point (point)) - (evil-mouse--remap-link-click-p start-event event)) - ;; If we rebind to mouse-2, reselect previous selected - ;; window, so that the mouse-2 event runs in the same - ;; situation as if user had clicked it directly. Fixes - ;; the bug reported by juri@jurta.org on 2005-12-27. - (if (or (vectorp on-link) (stringp on-link)) - (setq event (aref on-link 0)) - (select-window original-window) - (setcar event 'mouse-2) - ;; If this mouse click has never been done by the - ;; user, it doesn't have the necessary property to be - ;; interpreted correctly. - (put 'mouse-2 'event-kind 'mouse-click))) - (push event unread-command-events))))))) - -;; This function is a plain copy of `mouse--drag-set-mark-and-point', -;; which is only available in Emacs 24 -(defun evil-mouse--drag-set-mark-and-point (start click click-count) - (let* ((range (evil-mouse-start-end start click click-count)) - (beg (nth 0 range)) - (end (nth 1 range))) - (cond ((eq (mark) beg) - (goto-char end)) - ((eq (mark) end) - (goto-char beg)) - ((< click (mark)) - (set-mark end) - (goto-char beg)) - (t - (set-mark beg) - (goto-char end))))) - -;; This function is a plain copy of `mouse--remap-link-click-p', -;; which is only available in Emacs 23 -(defun evil-mouse--remap-link-click-p (start-event end-event) - (or (and (eq mouse-1-click-follows-link 'double) - (= (event-click-count start-event) 2)) - (and - (not (eq mouse-1-click-follows-link 'double)) - (= (event-click-count start-event) 1) - (= (event-click-count end-event) 1) - (or (not (integerp mouse-1-click-follows-link)) - (let ((t0 (posn-timestamp (event-start start-event))) - (t1 (posn-timestamp (event-end end-event)))) - (and (integerp t0) (integerp t1) - (if (> mouse-1-click-follows-link 0) - (<= (- t1 t0) mouse-1-click-follows-link) - (< (- t0 t1) mouse-1-click-follows-link)))))))) - -(defun evil-mouse-start-end (start end mode) - "Return a list of region bounds based on START and END according to MODE. -If MODE is not 1 then set point to (min START END), mark to (max -START END). If MODE is 1 then set point to start of word at (min -START END), mark to end of word at (max START END)." - (evil-sort start end) - (setq mode (mod mode 4)) - (if (/= mode 1) (list start end) - (list - (save-excursion - (goto-char (min (point-max) (1+ start))) - (if (zerop (forward-thing evil-mouse-word -1)) - (let ((bpnt (point))) - (forward-thing evil-mouse-word +1) - (if (> (point) start) bpnt (point))) - (point-min))) - (save-excursion - (goto-char end) - (1- - (if (zerop (forward-thing evil-mouse-word +1)) - (let ((epnt (point))) - (forward-thing evil-mouse-word -1) - (if (<= (point) end) epnt (point))) - (point-max))))))) - -;;; State switching - -(evil-define-command evil-exit-emacs-state (&optional buffer message) - "Exit Emacs state. -Changes the state to the previous state, or to Normal state -if the previous state was Emacs state." - :keep-visual t - :suppress-operator t - (interactive '(nil t)) - (with-current-buffer (or buffer (current-buffer)) - (when (evil-emacs-state-p) - (evil-change-to-previous-state buffer message) - (when (evil-emacs-state-p) - (evil-normal-state (and message 1)))))) - -(defun evil--restore-repeat-hooks () - "No insert-state repeat info is recorded after executing in normal state. -Restore the disabled repeat hooks on insert-state exit." - (evil-repeat-stop) - (add-hook 'pre-command-hook #'evil-repeat-pre-hook) - (add-hook 'post-command-hook #'evil-repeat-post-hook) - (remove-hook 'evil-insert-state-exit-hook #'evil--restore-repeat-hooks)) - -(defvar evil--execute-normal-return-state nil - "The state to return to after executing in normal state.") - -(evil-define-local-var evil--execute-normal-eol-pos nil - "Point position if it was at EOL before `evil-execute-in-normal-state'.") - -(defun evil-execute-in-normal-state () - "Execute the next command in Normal state." - (interactive) - (let ((buf (current-buffer)) - (state evil-state)) - (evil-with-delay (not (memq this-command - '(nil - evil-execute-in-normal-state - evil-replace-state - evil-use-register - evil-window-digit-argument - digit-argument - negative-argument - universal-argument - universal-argument-minus - universal-argument-more - universal-argument-other-key))) - post-command-hook - (with-current-buffer buf - ;; If cursor was after EOL before CTRL-O and is now at EOL, - ;; put it after EOL. - (and (or (when evil--execute-normal-eol-pos - (= (1+ (point)) (save-excursion - (goto-char evil--execute-normal-eol-pos) - (set-marker evil--execute-normal-eol-pos nil) - (line-end-position)))) - (and (eq (or goal-column temporary-goal-column) most-positive-fixnum) - (memq this-command '(next-line previous-line)))) - (not (eolp)) - (not (memq this-command - '(evil-insert evil-beginning-of-line evil-first-non-blank))) - (forward-char)) - (unless (memq evil-state '(replace insert)) - (evil-change-state state)) - (when (eq 'insert evil-state) - (remove-hook 'pre-command-hook #'evil-repeat-pre-hook) - (remove-hook 'post-command-hook #'evil-repeat-post-hook) - (add-hook 'evil-insert-state-exit-hook #'evil--restore-repeat-hooks)) - (setq evil-execute-normal-keys nil)))) - (setq evil-insert-count nil - evil--execute-normal-return-state evil-state - evil--execute-normal-eol-pos (when (eolp) (point-marker)) - evil-execute-normal-keys (this-command-keys)) - (let (evil-move-cursor-back) (evil-normal-state)) - (evil-echo "Switched to Normal state for the next command...")) - -(defun evil-stop-execute-in-emacs-state () - (when (and (not (eq this-command #'evil-execute-in-emacs-state)) - (not (minibufferp))) - (remove-hook 'post-command-hook #'evil-stop-execute-in-emacs-state) - (when (buffer-live-p evil-execute-in-emacs-state-buffer) - (with-current-buffer evil-execute-in-emacs-state-buffer - (if (and (eq evil-previous-state 'visual) - (not (use-region-p))) - (progn - (evil-change-to-previous-state) - (evil-exit-visual-state)) - (evil-change-to-previous-state)))) - (setq evil-execute-in-emacs-state-buffer nil))) - -(evil-define-command evil-execute-in-emacs-state () - "Execute the next command in Emacs state." - (add-hook 'post-command-hook #'evil-stop-execute-in-emacs-state t) - (setq evil-execute-in-emacs-state-buffer (current-buffer)) - (cond - ((evil-visual-state-p) - (let ((mrk (mark)) - (pnt (point))) - (evil-emacs-state) - (set-mark mrk) - (goto-char pnt))) - (t - (evil-emacs-state))) - (evil-echo "Switched to Emacs state for the next command ...")) - -(defun evil-exit-visual-and-repeat (event) - "Exit insert state and repeat event. -This special command should be used if some command called from -visual state should actually be called in normal-state. The main -reason for doing this is that the repeat system should *not* -record the visual state information for some command. This -command should be bound to exactly the same event in visual state -as the original command is bound in normal state. EVENT is the -event that triggered the execution of this command." - (interactive "e") - (when (evil-visual-state-p) - (evil-exit-visual-state) - (push event unread-command-events))) -(evil-declare-ignore-repeat 'evil-exit-visual-and-repeat) - -(evil-define-command evil-retab (tabstop) - "Convert all tabs to spaces or the other way around. -Replace all sequences of white-space containing a <Tab> with new -strings of white-space using the new TABSTOP value given. -If you do not specify a new TABSTOP size or it is zero, Evil uses the -current value of `tab-width'." - (interactive "<a>") - (unless (or (not tabstop) (string-match-p "^[0-9]*$" tabstop)) - (user-error "Invalid argument: %s" tabstop)) - (let ((beg (if (use-region-p) (region-beginning) (point-min))) - (end (if (use-region-p) (region-end) (point-max))) - (retab (if indent-tabs-mode #'tabify #'untabify)) - (tab-width (cond ((not tabstop) tab-width) - ((equal tabstop "0") tab-width) - (t (string-to-number tabstop))))) - (funcall retab beg end))) - -(provide 'evil-commands) - -;;; evil-commands.el ends here diff --git a/.config/emacs/lisp/evil/evil-common.el b/.config/emacs/lisp/evil/evil-common.el deleted file mode 100644 index 4aa1416..0000000 --- a/.config/emacs/lisp/evil/evil-common.el +++ /dev/null @@ -1,3843 +0,0 @@ -;;; evil-common.el --- Common functions and utilities -*- lexical-binding: t -*- -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(require 'evil-vars) -(require 'rect) -(require 'thingatpt) -(require 'cl-lib) - -(declare-function evil-visual-state-p "evil-states") -(declare-function evil-visual-restore "evil-states") -(declare-function evil-motion-state "evil-states") -(declare-function evil-replace-state-p "evil-states") -(declare-function evil-set-jump "evil-jumps") - -;;; Compatibility with different Emacs versions - -;; x-set-selection and x-get-selection have been deprecated since 25.1 -;; by gui-set-selection and gui-get-selection -(defalias 'evil-get-selection - (if (fboundp 'gui-get-selection) 'gui-get-selection 'x-get-selection)) -(defalias 'evil-set-selection - (if (fboundp 'gui-set-selection) 'gui-set-selection 'x-set-selection)) - -(defmacro evil-with-delay (condition hook &rest body) - "Execute BODY when CONDITION becomes true, checking with HOOK. -HOOK can be a simple symbol or of the form (HOOK APPEND LOCAL NAME) -where: -NAME specifies the name of the entry added to HOOK. -If APPEND is non-nil, the entry is appended to the hook. -If LOCAL is non-nil, the buffer-local value of HOOK is modified." - (declare (debug (form sexp body)) (indent 2)) - (cl-destructuring-bind (hook-sym &optional append local name) - (mapcar #'macroexp-quote (if (consp hook) hook (list hook))) - (macroexp-let2* nil - ((fun-name `(make-symbol - ,(or name (format "evil-delay-in-%s" hook-sym)))) - ;; `apply-partially' is used in case this macro is expanded - ;; (via `evil-define-key') in a file which still does not - ;; activate `lexical-binding'. - (fun `(apply-partially - (lambda (name &rest _) - (when ,(or condition t) - (remove-hook ,hook-sym name ,local) - ,@body - t)) - ,fun-name))) - `(unless ,(and condition `(funcall ,fun)) - (progn (fset ,fun-name ,fun) - ,@(when local `((put ,fun-name 'permanent-local-hook t))) - (add-hook ,hook-sym ,fun-name ,append ,local)))))) - -(defun evil-delay (condition form hook &optional append local name) - "Execute FORM when CONDITION becomes true, checking with HOOK. -NAME specifies the name of the entry added to HOOK. If APPEND is -non-nil, the entry is appended to the hook. If LOCAL is non-nil, -the buffer-local value of HOOK is modified." - (declare (obsolete evil-with-delay "1.15.0") (indent 2)) - (eval `(evil-with-delay ,condition (,hook ,append ,local ,name) ,form) t)) - -;;; List functions - -(defmacro evil--add-to-alist (alist &rest elements) - "Add the association of KEY and VAL to the value of ALIST. -If the list already contains an entry for KEY, update that entry; -otherwise prepend it to the list. - -\(fn ALIST [KEY VAL]...)" - `(progn - ,@(cl-loop - for (key val) on elements by #'cddr collect - (if (< emacs-major-version 26) - (macroexp-let2* nil ((k key) (p `(assoc ,k ,alist))) - `(if ,p (setcdr ,p ,val) - (push (cons ,k ,val) ,alist))) - `(setf (alist-get ,key ,alist nil nil #'equal) ,val))) - ,alist)) - -;; custom version of `delete-if' -(defun evil-filter-list (predicate list &optional pointer) - "Delete by side-effect all items satisfying PREDICATE in LIST. -Stop when reaching POINTER. If the first item satisfies PREDICATE, -there is no way to remove it by side-effect; therefore, write -\(setq foo (evil-filter-list #\\='predicate foo)) to be sure of -changing the value of `foo'." - (let ((tail list) elt head) - (while (and tail (not (eq tail pointer))) - (setq elt (car tail)) - (cond - ((funcall predicate elt) - (setq tail (cdr tail)) - (if head - (setcdr head tail) - (setq list tail))) - (t - (setq head tail - tail (cdr tail))))) - list)) - -(defun evil-member-if (predicate list &optional pointer) - "Find the first item satisfying PREDICATE in LIST. -Stop when reaching POINTER, which should point at a link -in the list." - (let (elt) - (catch 'done - (while (and (consp list) (not (eq list pointer))) - (setq elt (car list)) - (if (funcall predicate elt) - (throw 'done elt) - (setq list (cdr list))))))) - -(defun evil-member-recursive-if (predicate tree) - "Find the first item satisfying PREDICATE in TREE." - (declare (obsolete nil "1.15.0")) - (cond - ((funcall predicate tree) - tree) - ((listp tree) - (catch 'done - (dolist (elt tree) - (when (setq elt (evil-member-recursive-if predicate elt)) - (throw 'done elt))))))) - -(defun evil-concat-lists (&rest sequences) - "Concatenate lists, removing duplicates. -Elements are compared with `eq'." - (let (result) - (dolist (sequence sequences) - (dolist (elt sequence) - (push elt result))) - (nreverse (cl-remove-duplicates result :test #'eq)))) - -(defun evil-concat-alists (&rest sequences) - "Concatenate association lists, removing duplicates. -An alist is a list of cons cells (KEY . VALUE) where each key -may occur only once. Later values overwrite earlier values." - (let (result) - (dolist (sequence sequences) - (dolist (elt sequence) - (setq result (assq-delete-all (car-safe elt) result)) - (push elt result))) - (nreverse result))) - -(defun evil-concat-plists (&rest sequences) - "Concatenate property lists, removing duplicates. -A property list is a list (:KEYWORD1 VALUE1 :KEYWORD2 VALUE2...) -where each keyword may occur only once. Later values overwrite -earlier values." - (let (result) - (dolist (sequence sequences result) - (while sequence - (setq result - (plist-put result (pop sequence) (pop sequence))))))) - -(defun evil-concat-keymap-alists (&rest sequences) - "Concatenate keymap association lists, removing duplicates. -A keymap alist is a list of cons cells (VAR . MAP) where each keymap -may occur only once, but where the variables may be repeated -\(e.g., (VAR . MAP1) (VAR . MAP2) is allowed). The order matters, -with the highest priority keymaps being listed first." - (let (result) - (dolist (sequence sequences) - (dolist (elt sequence) - (unless (rassq (cdr-safe elt) result) - (push elt result)))) - (nreverse result))) - -(defun evil-plist-delete (prop plist) - "Delete by side effect the property PROP from PLIST. -If PROP is the first property in PLIST, there is no way -to remove it by side-effect; therefore, write -\(setq foo (evil-plist-delete :prop foo)) to be sure of -changing the value of `foo'." - (let ((tail plist) elt head) - (while tail - (setq elt (car tail)) - (cond - ((eq elt prop) - (setq tail (cdr (cdr tail))) - (if head - (setcdr (cdr head) tail) - (setq plist tail))) - (t - (setq head tail - tail (cdr (cdr tail)))))) - plist)) - -(defun evil-get-property (alist key &optional prop) - "Return property PROP for KEY in ALIST. -ALIST is an association list with entries of the form -\(KEY . PLIST), where PLIST is a property list. -If PROP is nil, return all properties for KEY. -If KEY is t, return an association list of keys -and their PROP values." - (declare (obsolete nil "1.15.0")) - (cond - ((null prop) - (cdr (assq key alist))) - ((eq key t) - (let (result val) - (dolist (entry alist result) - (setq key (car entry) - val (cdr entry)) - (when (plist-member val prop) - (setq val (plist-get val prop)) - (push (cons key val) result))))) - (t - (plist-get (cdr (assq key alist)) prop)))) - -(defun evil-put-property (alist-var key prop val &rest properties) - "Set PROP to VAL for KEY in ALIST-VAR. -ALIST-VAR points to an association list with entries of the form -\(KEY . PLIST), where PLIST is a property list storing PROP and VAL." - (declare (obsolete nil "1.15.0")) - (set alist-var - (let* ((alist (symbol-value alist-var)) - (plist (cdr (assq key alist)))) - (setq plist (plist-put plist prop val)) - (when properties - (setq plist (evil-concat-plists plist properties) - val (car (last properties)))) - (setq alist (assq-delete-all key alist)) - (push (cons key plist) alist))) - val) - -(defun evil-state-property (state prop &optional value) - "Return the value of property PROP for STATE. -PROP is a keyword as used by `evil-define-state'. STATE is the state's -symbolic name. If VALUE is non-nil and the value is a variable, return -the value of that variable. - -If STATE is t, return an association list of states and their PROP -values instead." - (if (eq state t) - (cl-loop for (key . plist) in evil-state-properties with result do - (let ((p (plist-member plist prop))) - (when p (push (cons key (cadr p)) result))) - finally return result) - (let ((val (plist-get (cdr (assq state evil-state-properties)) prop))) - (if (and value (symbolp val) (boundp val)) - (symbol-value val) - val)))) - -(eval-and-compile (defalias 'evil-swap #'cl-rotatef)) - -(defmacro evil-sort (&rest vars) - "Sort the symbol values of VARS. -Place the smallest value in the first argument and the largest in the -last, sorting in between." - (if (= (length vars) 2) - `(when (> ,@vars) (evil-swap ,@vars)) - (let ((sorted (make-symbol "sortvar"))) - `(let ((,sorted (sort (list ,@vars) #'<))) - (setq ,@(apply #'nconc - (mapcar (lambda (var) (list var `(pop ,sorted))) - vars))))))) - -(defun evil-vector-to-string (vector) - "Turn VECTOR into a string, changing <escape> to \"\\e\"." - (mapconcat (lambda (c) (if (eq c 'escape) "\e" (list c))) - vector - "")) - -;;; Command properties - -(defmacro evil-define-command (command &rest body) - "Define a command COMMAND. - -\(fn COMMAND (ARGS...) DOC [[KEY VALUE]...] BODY...)" - (declare (indent defun) - (doc-string 3) - (debug (&define name - [&optional lambda-list] - [&optional stringp] - [&rest keywordp sexp] - [&optional ("interactive" [&rest form])] - def-body))) - (let ((interactive '(interactive)) - args doc doc-form keys) - ;; collect arguments - (when (listp (car body)) - (setq args (pop body))) - ;; collect docstring - (cond ((stringp (car body)) (setq doc (pop body))) - ((eq (car-safe (car body)) #'format) (setq doc-form (pop body)))) - ;; collect keywords - (while (keywordp (car body)) - (let* ((key (pop body)) - (arg (pop body))) - (setq keys (plist-put keys key arg)))) ; TODO: add keyword check - ;; collect `interactive' form - (when (eq (caar body) 'interactive) - (cl-destructuring-bind (form . attrs) - (apply #'evil-interactive-form (cdr (pop body))) - (setq interactive `(interactive ,form) - keys (evil-concat-plists keys attrs)))) - `(progn - ;; the compiler does not recognize `defun' inside `let' - ,(when (and command body) - `(defun ,command ,args - ,@(when doc `(,doc)) - ,interactive - ,@body)) - ,(when (and command doc-form) - `(put ',command 'function-documentation ,doc-form)) - ;; set command properties for symbol or lambda function - (let ((func ,(if (and (null command) body) - `(lambda ,args - ,interactive - ,@body) - `#',command))) - (apply #'evil-set-command-properties func ',keys) - func)))) - -(define-obsolete-variable-alias - 'evil-command-properties 'evil--command-properties "1.15.0") -(defvar evil--command-properties nil - "Specifications made by `evil-define-command'.") - -(defun evil-command-properties (command) - "Return the Evil command property list for COMMAND. -See also `evil-get-command-property'." - (if (symbolp command) (get command 'evil--command-plist) - (cdr (assq command evil--command-properties)))) -(define-obsolete-function-alias - 'evil-get-command-properties #'evil-command-properties "1.15.0") - -(gv-define-setter evil-command-properties (val command) - `(if (symbolp ,command) (put ,command 'evil--command-plist ,val) - ,(macroexp-let2 nil p `(assq ,command evil--command-properties) - `(if ,p (setcdr ,p ,val) - (push (cons ,command ,val) evil--command-properties))))) - -(defalias 'evil-has-command-properties-p #'evil-command-properties - "Whether Evil properties are defined for COMMAND. -See also `evil-has-command-property-p'.") - -(defun evil-has-command-property-p (command property) - "Whether COMMAND has Evil PROPERTY. -See also `evil-has-command-properties-p'." - (plist-member (evil-command-properties command) property)) - -(defun evil-get-command-property (command property &optional default) - "Return the value of Evil PROPERTY of COMMAND. -If the command does not have the property, return DEFAULT. -See also `evil-get-command-properties'." - (let ((p (plist-member (evil-command-properties command) property))) - (if p (cadr p) default))) - -(defun evil-add-command-properties (command &rest properties) - "Set each Evil command property KEY to its VAL for COMMAND. -To replace existing properties, use `evil-set-command-properties'. - -\(fn COMMAND [KEY VAL]...)" - (let ((props (evil-command-properties command))) - (while properties - (setq props (plist-put props (pop properties) (pop properties)))) - (setf (evil-command-properties command) props))) - -(defalias 'evil-set-command-property #'evil-add-command-properties - "Set PROPERTY to VALUE for COMMAND. -To set multiple properties at once, see -`evil-set-command-properties' and `evil-add-command-properties'. - -\(fn COMMAND PROPERTY VALUE)") -(defalias 'evil-put-command-property #'evil-set-command-property) - -(defun evil-set-command-properties (command &rest properties) - "Replace all of COMMAND's properties with PROPERTIES. -PROPERTIES should be a property list. -This erases all previous properties; to only add properties, -use `evil-set-command-property'." - (setf (evil-command-properties command) properties)) - -(defun evil-remove-command-properties (command &rest properties) - "Remove PROPERTIES from COMMAND. -PROPERTIES should be a list of properties (:PROP1 :PROP2 ...). -If PROPERTIES is the empty list, all properties are removed." - (let (plist) - (when properties - (setq plist (evil-command-properties command)) - (dolist (property properties) - (setq plist (evil-plist-delete property plist)))) - (apply #'evil-set-command-properties command plist))) - -(defun evil-yank-handler (&optional motion) - "Return the yank handler for MOTION. -MOTION defaults to the current motion." - (evil-get-command-property (or motion evil-this-motion) :yank-handler)) - -(defun evil-declare-motion (command) - "Declare COMMAND to be a movement function. -This ensures that it behaves correctly in visual state." - (evil-add-command-properties command :keep-visual t :repeat 'motion)) - -(defun evil-declare-repeat (command) - "Declare COMMAND to be repeatable." - (evil-add-command-properties command :repeat t)) - -(defun evil-declare-not-repeat (command) - "Declare COMMAND to be nonrepeatable." - (evil-add-command-properties command :repeat nil)) -(defalias 'evil-declare-ignore-repeat #'evil-declare-not-repeat) - -(defun evil-declare-change-repeat (command) - "Declare COMMAND to be repeatable by buffer changes rather than -keystrokes." - (evil-add-command-properties command :repeat 'change)) - -(defun evil-declare-insert-at-point-repeat (command) - "Declare COMMAND to be repeatable by buffer changes." - (evil-add-command-properties command :repeat 'insert-at-point)) - -(defun evil-declare-abort-repeat (command) - "Declare COMMAND to be nonrepeatable." - (evil-add-command-properties command :repeat 'abort)) - -(defun evil-delimited-arguments (string &optional count) - "Parse STRING as a sequence of delimited arguments. -Return a list of COUNT strings, or as many arguments as the string -contains. The first non-blank character is taken to be the delimiter. -If some arguments are missing from STRING, the resulting list is -padded with nil values. Two delimiters following directly after each -other gives an empty string." - (unless count (setq count -1)) - (let ((idx 0) delim regexp result) - (when (string-match "^[[:space:]]*\\([^[:space:]]\\)" string) - (setq delim (match-string 1 string) - regexp (format "%s\\(\\(?:\\\\.\\|[^%s]\\)*\\)" - (regexp-quote delim) delim)) - (while (and (/= count 0) (string-match regexp string idx) - (/= (match-beginning 1) (length string))) - (setq idx (match-end 0) - count (1- count)) - (push - (if (when (= count 0) - (not (string-match-p - (concat (regexp-quote delim) "[[:space:]]*$") - string idx))) - (substring string (match-beginning 1)) - (match-string 1 string)) - result))) - (dotimes (_ count) (push nil result)) - (nreverse result))) - -(defun evil-concat-charsets (&rest sets) - "Concatenate character sets. -A character set is the part between [ and ] in a regular expression. -If any character set is complemented, the result is also complemented." - (let ((bracket "") (complement "") (hyphen "") result) - (dolist (set sets) - (when (string-match-p "^\\^" set) - (setq set (substring set 1) - complement "^")) - (when (string-match-p "^]" set) - (setq set (substring set 1) - bracket "]")) - (when (string-match-p "^-" set) - (setq set (substring set 1) - hyphen "-")) - (setq result (concat result set))) - (format "%s%s%s%s" complement bracket hyphen result))) - -;;; Key sequences - -(defun evil-keypress-parser (&optional input) - "Read from keyboard or INPUT and build a command description. -Return (CMD COUNT), where COUNT is the numeric prefix argument. -Both COUNT and CMD may be nil." - (when input (setq unread-command-events (append input unread-command-events))) - (let (count negative) - (catch 'done - (while t - (let ((seq (read-key-sequence ""))) - (when seq - (let ((cmd (key-binding seq))) - (cond - ((null cmd) (throw 'done (list nil nil))) - ((arrayp cmd) ; keyboard macro, recursive call - (let ((cmd (evil-keypress-parser cmd))) - (throw 'done - (list (car cmd) - (if (or count (cadr cmd)) - (list (car cmd) (* (or count 1) - (or (cadr cmd) 1)))))))) - ((or (eq cmd #'digit-argument) - (and (equal seq "0") count)) - (let* ((event (aref seq (1- (length seq)))) - (char (or (when (characterp event) event) - (when (symbolp event) - (get event 'ascii-character)))) - (digit (when (integerp char) (- (logand char ?\177) ?0)))) - (setq count (+ (* 10 (or count 0)) digit)))) - ((eq cmd #'negative-argument) - (setq negative (not negative))) - (t - (throw 'done (list cmd - (and count - (* count - (if negative -1 1)))))))))))))) - -(defun evil-read-key (&optional prompt) - "Read a key from the keyboard. -Translates it according to the input method." - (let ((old-global-map (current-global-map)) - (new-global-map (make-sparse-keymap)) - (overriding-terminal-local-map nil) - (overriding-local-map evil-read-key-map) - seq char cmd) - (unwind-protect - (condition-case nil - (progn - (define-key new-global-map [menu-bar] - (lookup-key global-map [menu-bar])) - (define-key new-global-map [tab-bar] - (lookup-key global-map [tab-bar])) - (define-key new-global-map [tool-bar] - (lookup-key global-map [tool-bar])) - (setq new-global-map - (append new-global-map - (list (make-char-table 'display-table - 'self-insert-command)))) - (use-global-map new-global-map) - (setq seq (read-key-sequence prompt nil t) - char (aref seq 0) - cmd (key-binding seq)) - (while (arrayp cmd) - (setq char (aref cmd 0) - cmd (key-binding cmd))) - (cond - ((eq cmd 'self-insert-command) char) - (cmd (call-interactively cmd)) - (t (user-error "No replacement character typed")))) - (quit - (when (fboundp 'evil-repeat-abort) - (evil-repeat-abort)) - (signal 'quit nil))) - (use-global-map old-global-map)))) - -(defun evil-read-quoted-char () - "Command that calls `read-quoted-char'. -This command can be used wherever `read-quoted-char' is required -as a command. Its main use is in the `evil-read-key-map'." - (interactive) - (read-quoted-char)) - -(defvar evil-digraph-read-key-keymap - (let ((map (make-sparse-keymap)) - (n ?0)) - (while (<= n ?9) - (define-key map (vector (intern (concat "kp-" (string n)))) nil) - (cl-incf n)) - map) - "By default, used to exclude otherwise disabled fallbacks.") - -(declare-function evil-digraph "evil-digraphs") -(defun evil-read-digraph-char-with-overlay (overlay) - "Read two chars, displaying the first in OVERLAY, replacing \"?\". -Return the digraph from `evil-digraph', else return second char." - (interactive) - (unwind-protect - (let ((read-key-empty-map - (let ((map (copy-keymap evil-digraph-read-key-keymap))) - (set-keymap-parent map read-key-empty-map) - ;; Disable read-key-sequence unbound fallbacks, e.g. downcasing - (define-key map [t] 'dummy) - map)) - char1 char2) - ;; create overlay prompt - (overlay-put overlay 'invisible t) - (overlay-put overlay 'after-string - #("?" 0 1 (face minibuffer-prompt cursor 1))) - (setq char1 (read-key)) - (overlay-put overlay 'after-string - (propertize (char-to-string char1) - 'face 'minibuffer-prompt - 'cursor 1)) - (setq char2 (read-key)) - - (or (evil-digraph (list char1 char2)) - ;; use the last character if undefined - char2)) - (delete-overlay overlay))) - -(defun evil-read-digraph-char (&optional hide-chars) - "Read two keys from keyboard forming a digraph. -This function creates an overlay at (point), hiding the next -HIDE-CHARS characters. HIDE-CHARS defaults to 1." - (interactive) - (let ((overlay (make-overlay - (point) (min (+ (point) (or hide-chars 1)) - (point-max))))) - (evil-read-digraph-char-with-overlay overlay))) - -(defun evil-read-motion (&optional motion count type modifier) - "Read a MOTION, motion COUNT and motion TYPE from the keyboard. -The type may be overridden with MODIFIER, which may be a type -or a Visual selection as defined by `evil-define-visual-selection'. -Return a list (MOTION COUNT [TYPE])." - (let (command prefix) - (setq evil-this-type-modified nil) - (unless motion - (while (progn - (setq command (evil-keypress-parser) - motion (pop command) - prefix (pop command)) - (when prefix - (setq count - (if count - (string-to-number - (concat (number-to-string count) - (number-to-string prefix))) - prefix))) - ;; if the command is a type modifier, read more - (when (rassq motion evil-visual-alist) - (setq modifier - (or modifier - (car (rassq motion evil-visual-alist)))))))) - (when modifier - (setq type (or type (evil-type motion 'exclusive))) - (cond - ((eq modifier 'char) - ;; TODO: this behavior could be less hard-coded - (setq type (if (eq type 'exclusive) 'inclusive 'exclusive))) - (t (setq type modifier))) - (setq evil-this-type-modified type)) - (list motion count type))) - -(defun evil-mouse-events-p (keys) - "Return non-nil iff KEYS contains a mouse event." - (cl-loop for key across keys thereis - (or (mouse-event-p key) - (mouse-movement-p key)))) - -(defun evil-extract-count (keys) - "Split the key-sequence KEYS into prefix-argument and the rest. -Return the list (PREFIX CMD SEQ REST), where PREFIX is the -prefix count, CMD the command to be executed, SEQ the subsequence -calling CMD, and REST is all remaining events in the -key-sequence. PREFIX and REST may be nil if they do not exist. -If a command is bound to some keyboard macro, it is expanded -recursively." - (catch 'done - (let ((len (length keys)) - (beg 0) - (end 1) - found-prefix) - (while (<= end len) - (let* ((seq (substring keys beg end)) - (cmd (key-binding seq))) - (cond - ((memq cmd '(undefined nil)) - (user-error "No command bound to `%s'" seq)) - ((arrayp cmd) ; keyboard macro, replace command with macro - (setq keys (vconcat (substring keys 0 beg) - cmd - (substring keys end)) - end (1+ beg) - len (length keys))) - ((functionp cmd) - (if (or (memq cmd '(digit-argument negative-argument)) - (and found-prefix - (equal (vconcat seq) (vector ?0)))) - ;; skip those commands - (setq found-prefix t ; found at least one prefix argument - beg end - end (1+ end)) - ;; a real command, finish - (throw 'done - (list (unless (zerop beg) - (string-to-number - (concat (substring keys 0 beg)))) - cmd - seq - (when (< end len) - (substring keys end)))))) - (t ; append a further event - (setq end (1+ end)))))) - (user-error "Key sequence contains no complete binding")))) - -(defun evil-extract-append (file-or-append) - "Return an (APPEND . FILENAME) pair based on FILE-OR-APPEND. -FILE-OR-APPEND should either be a filename or a \">> FILE\" -directive. APPEND will be t if FILE-OR-APPEND is an append -directive and nil otherwise. FILENAME will be the extracted -filename." - (if (and (stringp file-or-append) - (string-match "\\(>> *\\)" file-or-append)) - (cons t (substring file-or-append (match-end 1))) - (cons nil file-or-append))) - -(defun evil-set-keymap-prompt (map prompt) - "Set the prompt-string of MAP to PROMPT." - (delq (keymap-prompt map) map) - (when prompt - (setcdr map (cons prompt (cdr map))))) - -(defun evil-lookup-key (map key) - "Return non-nil value if KEY is bound in MAP." - (let ((definition (lookup-key map key))) - (unless (numberp definition) ; in-band error - definition))) - -;;; Display - -(defun evil-set-cursor (specs) - "Change the cursor's apperance according to SPECS. -SPECS may be a cursor type as per `cursor-type', a color -string as passed to `set-cursor-color', a zero-argument -function for changing the cursor, or a list of the above. - -If SPECS is nil, this function does not have an effect; -pass (list nil) instead to indicate a nil `cursor-type' -\(i.e., to disable the cursor)." - (unless (and (not (functionp specs)) - (listp specs) - (null (cdr-safe (last specs)))) - (setq specs (list specs))) - (dolist (spec specs) - (cond - ((functionp spec) - (ignore-errors (funcall spec))) - ((stringp spec) - (evil-set-cursor-color spec)) - (t - (setq cursor-type spec))))) - -(defun evil-set-cursor-color (color) - "Set the cursor color to COLOR." - (unless (equal (frame-parameter nil 'cursor-color) color) - ;; `set-cursor-color' forces a redisplay, so only - ;; call it when the color actually changes - (set-cursor-color color))) - -(defun evil-refresh-cursor (&optional state buffer) - "Refresh the cursor for STATE in BUFFER. -BUFFER defaults to the current buffer. If STATE is nil the -cursor type is either `evil-force-cursor' or the current state." - (defvar evil-local-mode) - (when evil-local-mode - (let* ((state (or state evil-force-cursor evil-state 'normal)) - (default (or evil-default-cursor t)) - (cursor (evil-state-property state :cursor t)) - (color (or (and (stringp cursor) cursor) - (and (listp cursor) (evil-member-if #'stringp cursor)) - (frame-parameter nil 'cursor-color)))) - (with-current-buffer (or buffer (current-buffer)) - ;; if both STATE and `evil-default-cursor' - ;; specify a color, don't set it twice - (evil-set-cursor (if (and color (listp default)) - (cl-remove-if #'stringp default) - default)) - (evil-set-cursor cursor))))) - -(defmacro evil-save-cursor (&rest body) - "Save the current cursor; execute BODY; restore the cursor." - (declare (indent defun) (debug t) (obsolete nil "1.15.0")) - `(let ((cursor cursor-type) - (color (frame-parameter (selected-frame) 'cursor-color)) - (inhibit-quit t)) - (unwind-protect - (progn ,@body) - (setq cursor-type cursor) - (evil-set-cursor-color color)))) - -(defun evil-echo (string &rest args) - "Display an unlogged message in the echo area. -That is, the message is not logged in the *Messages* buffer. -\(To log the message, just use `message'.)" - (unless evil-no-display - (let (message-log-max) - (apply #'message string args)))) - -(defun evil-echo-area-save () - "Save the current echo area in `evil-echo-area-message'." - (setq evil-echo-area-message (current-message))) - -(defun evil-echo-area-restore () - "Restore the echo area from `evil-echo-area-message'. -Does not restore if `evil-write-echo-area' is non-nil." - (unless evil-write-echo-area - (if evil-echo-area-message - (message "%s" evil-echo-area-message) - (message nil))) - (setq evil-echo-area-message nil - evil-write-echo-area nil)) - -;; toggleable version of `with-temp-message' -(defmacro evil-save-echo-area (&rest body) - "Save the echo area; execute BODY; restore the echo area. -Intermittent messages are not logged in the *Messages* buffer." - (declare (indent defun) (debug t)) - `(let ((inhibit-quit t) - evil-echo-area-message evil-write-echo-area) - (evil-echo-area-save) - (unwind-protect - (progn ,@body) - (evil-echo-area-restore)))) - -(defmacro evil-without-display (&rest body) - "Execute BODY without Evil displays. -Inhibits echo area messages, mode line updates and cursor changes." - (declare (indent defun) - (debug t)) - `(let ((evil-no-display t)) - ,@body)) - -(defun evil-count-lines (beg end) - "Return absolute line-number-difference betweeen BEG and END. -This should give the same results no matter where on the line BEG -and END are." - (if (= beg end) - 0 - (let ((end-at-bol (save-excursion (goto-char (max beg end)) - (bolp)))) - (if end-at-bol - (count-lines beg end) - (1- (count-lines beg end)))))) - -;;; Movement - -(defun evil-normalize-position (pos) - "Return POS if it does not exceed the buffer boundaries. -If POS is less than `point-min', return `point-min'. -Is POS is more than `point-max', return `point-max'. -If POS is a marker, return its position." - (cond - ((not (number-or-marker-p pos)) - pos) - ((< pos (point-min)) - (point-min)) - ((> pos (point-max)) - (point-max)) - ((markerp pos) - (marker-position pos)) - (t - pos))) - -(defmacro evil-save-goal-column (&rest body) - "Restore the goal column after execution of BODY. -See also `evil-save-column'." - (declare (indent defun) - (debug t)) - `(let ((goal-column goal-column) - (temporary-goal-column temporary-goal-column)) - ,@body)) - -(defmacro evil-save-column (&rest body) - "Restore the column after execution of BODY. -See also `evil-save-goal-column'." - (declare (indent defun) - (debug t)) - `(let ((col (current-column))) - (evil-save-goal-column - ,@body - (move-to-column col)))) - -(defun evil--stick-to-eol-p () - "Called by vertical movement commands to help determine cursor position." - (and evil-track-eol - (eq (or goal-column temporary-goal-column) most-positive-fixnum) - (memq last-command '(next-line previous-line)))) - -(defun evil-eolp () - "Like `eolp' but accounts for `evil-move-beyond-eol' being nil." - (ignore-errors - (save-excursion - (unless (or evil-move-beyond-eol (memq evil-state '(insert replace))) - (forward-char)) - (eolp)))) - -(defmacro evil-ensure-column (&rest body) - "Execute BODY so that column after execution is correct. -If `evil-start-of-line' is nil, treat BODY as if it were a `next-line' command. -This mostly copies the approach of Emacs' `line-move-1', but is modified -so it is more compatible with Evil's notion of EOL tracking." - (declare (indent defun) (debug t)) - `(progn - (unless evil-start-of-line - (setq this-command 'next-line - temporary-goal-column - (cond ((memq last-command '(next-line previous-line)) - temporary-goal-column) - ((and track-eol (eolp) (not (bolp))) most-positive-fixnum) - (t (current-column))))) - ,@body - (if evil-start-of-line - (evil-first-non-blank) - (line-move-to-column - (or goal-column - (if (consp temporary-goal-column) - ;; Guard against a negative value as `temporary-goal-column' - ;; may have a negative component when both `whitespace-mode' - ;; and `display-line-numbers-mode' are enabled (#1297). - (max 0 (+ (truncate (car temporary-goal-column)) - (cdr temporary-goal-column))) - temporary-goal-column)))))) - -(defun evil-narrow (beg end) - "Restrict the buffer to BEG and END. -BEG or END may be nil, specifying a one-sided restriction including -`point-min' or `point-max'. See also `evil-with-restriction.'" - (declare (obsolete nil "1.15.0")) - (narrow-to-region - (if beg (max beg (point-min)) (point-min)) - (if end (min end (point-max)) (point-max)))) - -(defmacro evil-with-restriction (beg end &rest body) - "Execute BODY with the buffer narrowed to BEG and END. -BEG or END may be nil to specify a one-sided restriction." - (declare (indent 2) (debug t)) - `(save-restriction - (let ((evil-restriction-stack - (cons (cons (point-min) (point-max)) evil-restriction-stack))) - (narrow-to-region (or ,beg (point-min)) (or ,end (point-max))) - ,@body))) - -(defmacro evil-without-restriction (&rest body) - "Execute BODY with the top-most narrowing removed. -This works only if the previous narrowing has been generated by -`evil-with-restriction'." - (declare (indent defun) (debug t)) - `(save-restriction - (widen) - (narrow-to-region (car (car evil-restriction-stack)) - (cdr (car evil-restriction-stack))) - (let ((evil-restriction-stack (cdr evil-restriction-stack))) - ,@body))) - -(defmacro evil-narrow-to-field (&rest body) - "Narrow to the current field." - (declare (indent defun) - (debug t)) - `(evil-with-restriction (field-beginning) (field-end) - ,@body)) - -(defun evil-move-beginning-of-line (&optional arg) - "Move to the beginning of the line as displayed. -Like `move-beginning-of-line', but retains the goal column." - (evil-save-goal-column - (move-beginning-of-line arg) - (beginning-of-line))) - -(defun evil-move-end-of-line (&optional arg) - "Move to the end of the line as displayed. -Like `move-end-of-line', but retains the goal column." - (evil-save-goal-column - (move-end-of-line arg) - (end-of-line))) - -(defun evil-adjust-cursor (&optional _) - "Move point one character back if at the end of a non-empty line. -This behavior is controlled by `evil-move-beyond-eol'." - (and (not evil-move-beyond-eol) - (eolp) - (evil-move-cursor-back t))) - -(defun evil-move-cursor-back (&optional force) - "Move point one character back within the current line. -Contingent on the variable `evil-move-cursor-back' or the FORCE -argument. Movement is constrained to the current field." - (or (not (or evil-move-cursor-back force)) - (bolp) - (when (bound-and-true-p visual-line-mode) - (= (point) (save-excursion (vertical-motion 0) (point)))) - (goto-char (constrain-to-field (1- (point)) (point))))) - -(defun evil-line-position (line &optional column) - "Return the position of LINE. -If COLUMN is specified, return its position on the line. -A negative number means the end of the line." - (save-excursion - (goto-char (point-min)) - (forward-line (1- line)) - (when (numberp column) - (if (< column 0) - (forward-line) - (move-to-column column))) - (point))) - -(defun evil-column (&optional pos) - "Return the horizontal position of POS. -POS defaults to point." - (save-excursion - (when pos - (goto-char pos)) - (current-column))) - -(defun evil-move-to-column (column &optional dir force) - "Move point to column COLUMN in the current line. -Places point at left of the tab character (at the right if DIR -is non-nil) and returns point." - (interactive "p") - (move-to-column column force) - (unless force - (when (or (not dir) (and (numberp dir) (< dir 1))) - (when (> (current-column) column) - (evil-move-cursor-back)))) - (point)) - -(defmacro evil-loop (spec &rest body) - "Loop with countdown variable. -Evaluate BODY with VAR counting down from COUNT to 0. -COUNT can be negative, in which case VAR counts up instead. -The return value is the value of VAR when the loop -terminates, which is 0 if the loop completes successfully. -RESULT specifies a variable for storing this value. - -\(fn (VAR COUNT [RESULT]) BODY...)" - (declare (indent defun) (debug dolist) (obsolete nil "1.15.0")) - (let* ((i (make-symbol "loopvar")) - (var (pop spec)) - (count (pop spec)) - (result (pop spec))) - (setq var (or (unless (eq var result) var) i) - result (or result var)) - `(let ((,var ,count)) - (setq ,result ,var) - (while (/= ,var 0) - ,@body - (if (> ,var 0) - (setq ,var (1- ,var)) - (setq ,var (1+ ,var))) - (setq ,result ,var)) - ,var))) - -;;; Motions - -(defmacro evil-motion-loop (spec &rest body) - "Loop a certain number of times. -Evaluate BODY repeatedly COUNT times with VAR bound to 1 or -1, -depending on the sign of COUNT. Set RESULT, if specified, to the -number of unsuccessful iterations, which is 0 if the loop completes -successfully. This is also the return value. - -Each iteration must move point; if point does not change, the loop -immediately quits. - -\(fn (VAR COUNT [RESULT]) BODY...)" - (declare (indent defun) - (debug ((symbolp form &optional symbolp) body))) - (let* ((var (or (pop spec) (make-symbol "unitvar"))) - (count (or (pop spec) 0)) - (result (or (pop spec) var)) - (i (make-symbol "loopvar"))) - `(let* ((,i ,count) - (,var (if (< ,i 0) -1 1))) - (while (and (/= ,i 0) - (/= (point) (progn ,@body (point)))) - (setq ,i (if (< ,i 0) (1+ ,i) (1- ,i)))) - (setq ,result ,i)))) - -(defun evil-signal-at-bob-or-eob (&optional count) - "Signal error if `point' is at boundaries. -If `point' is at bob and COUNT is negative this function signals -`beginning-of-buffer'. If `point' is at eob and COUNT is positive -this function signals `end-of-buffer'. This function should be used -in motions. COUNT defaults to 1." - (setq count (or count 1)) - (cond - ((< count 0) (evil-signal-at-bob)) - ((> count 0) (evil-signal-at-eob)))) - -(defun evil-signal-at-bob () - "Signal `beginning-of-buffer' if `point' is at bob. -This function should be used in backward motions. If `point' is at -bob so that no further backward motion is possible the error -`beginning-of-buffer' is raised." - (when (bobp) (signal 'beginning-of-buffer nil))) - -(defun evil-signal-at-eob () - "Signal `end-of-buffer' if `point' is at eob. -This function should be used in forward motions. If `point' is close -to eob so that no further forward motion is possible the error -`end-of-buffer' is raised. This is the case if `point' is at -`point-max' or if is one position before `point-max', -`evil-move-beyond-eol' is nil and `point' is not at the end -of a line. The latter is necessary because `point' cannot be -moved to `point-max' if `evil-move-beyond-eol' is nil and -the last line in the buffer is not empty." - (when (or (eobp) - (and (not (eolp)) - (not evil-move-beyond-eol) - (save-excursion (forward-char) (eobp)))) - (signal 'end-of-buffer nil))) - -(defmacro evil-with-hproject-point-on-window (&rest body) - "Project point after BODY to current window. -If point is on a position left or right of the current window -then it is moved to the left and right boundary of the window, -respectively. If `auto-hscroll-mode' is non-nil then the left and -right positions are increased or decreased, respectively, by -`horizontal-margin' so that no automatic scrolling occurs." - (declare (indent defun) - (debug t)) - (let ((diff (make-symbol "diff")) - (left (make-symbol "left")) - (right (make-symbol "right"))) - `(let ((,diff (if auto-hscroll-mode (1+ hscroll-margin) 0)) - auto-hscroll-mode) - ,@body - (let* ((,left (+ (window-hscroll) ,diff)) - (,right (+ (window-hscroll) (window-width) (- ,diff) -1))) - (move-to-column (min (max (current-column) ,left) ,right)))))) - -(defun evil-forward-not-thing (thing &optional count) - "Move point to the end or beginning of the complement of THING." - (evil-motion-loop (dir (or count 1)) - (let (bnd) - (cond - ((> dir 0) - (while (and (setq bnd (bounds-of-thing-at-point thing)) - (< (point) (cdr bnd))) - (goto-char (cdr bnd))) - ;; no thing at (point) - (if (zerop (forward-thing thing)) - ;; now at the end of the next thing - (let ((bnd (bounds-of-thing-at-point thing))) - (if (or (< (car bnd) (point)) ; end of a thing - (= (car bnd) (cdr bnd))) ; zero width thing - (goto-char (car bnd)) - ;; beginning of yet another thing, go back - (forward-thing thing -1))) - (goto-char (point-max)))) - (t - (while (and (not (bobp)) - (setq bnd (progn (backward-char) (bounds-of-thing-at-point thing))) - (< (point) (cdr bnd))) - (goto-char (car bnd))) - ;; either bob or no thing at point - (goto-char - (if (and (not (bobp)) - (zerop (forward-thing thing -1)) - (setq bnd (bounds-of-thing-at-point thing))) - (cdr bnd) - (point-min)))))))) - -(defun evil-bounds-of-not-thing-at-point (thing &optional which) - "Return the bounds of a complement of THING at point. -If there is a THING at point nil is returned. Otherwise if WHICH -is nil or 0 a cons cell (BEG . END) is returned. If WHICH is -negative the beginning is returned. If WHICH is positive the END -is returned." - (let ((pnt (point))) - (let ((beg (save-excursion - (and (zerop (forward-thing thing -1)) - (forward-thing thing)) - (if (> (point) pnt) (point-min) (point)))) - (end (save-excursion - (and (zerop (forward-thing thing)) - (forward-thing thing -1)) - (if (< (point) pnt) (point-max) (point))))) - (when (and (<= beg (point) end) (< beg end)) - (cond - ((or (not which) (zerop which)) (cons beg end)) - ((< which 0) beg) - ((> which 0) end)))))) - -(defun evil-forward-nearest (count &rest forwards) - "Move point forward to the first of several motions. -FORWARDS is a list of forward motion functions (i.e. each moves -point forward to the next end of a text object (if passed a +1) -or backward to the preceeding beginning of a text object (if -passed a -1)). This function calls each of these functions once -and moves point to the nearest of the resulting positions. If -COUNT is positive point is moved forward COUNT times, if negative -point is moved backward -COUNT times." - (evil-motion-loop (dir (or count 1)) - (let ((pnt (point)) - (nxt (if (< dir 0) (point-min) (point-max)))) - (dolist (fwd forwards) - (goto-char pnt) - (ignore-errors - (evil-with-restriction - (when (< dir 0) - (save-excursion - (goto-char nxt) - (line-beginning-position 0))) - (when (> dir 0) - (save-excursion - (goto-char nxt) - (line-end-position 2))) - (and (zerop (funcall fwd dir)) - (/= (point) pnt) - (if (< dir 0) (> (point) nxt) (< (point) nxt)) - (setq nxt (point)))))) - (goto-char nxt)))) - -(defun bounds-of-evil-string-at-point (&optional state) - "Return the bounds of a string at point. -If STATE is given it used a parsing state at point." - (save-excursion - (let ((state (or state (syntax-ppss)))) - (when (nth 3 state) - (cons (nth 8 state) - (when (parse-partial-sexp - (point) (point-max) nil nil state 'syntax-table) - (point))))))) -(put 'evil-string 'bounds-of-thing-at-point #'bounds-of-evil-string-at-point) - -(defun bounds-of-evil-comment-at-point () - "Return the bounds of a string at point." - (save-excursion - (let ((state (syntax-ppss))) - (when (nth 4 state) - (cons (nth 8 state) - (when (parse-partial-sexp - (point) (point-max) nil nil state 'syntax-table) - (point))))))) -(put 'evil-comment 'bounds-of-thing-at-point #'bounds-of-evil-comment-at-point) - -;; The purpose of this function is to provide line motions which -;; preserve the column. This is how `previous-line' and `next-line' -;; work, but unfortunately the behaviour is hard-coded: if and only if -;; the last command was `previous-line' or `next-line', the column is -;; preserved. Furthermore, in contrast to Vim, when we cannot go -;; further, those motions move point to the beginning resp. the end of -;; the line (we never want point to leave its column). The code here -;; comes from simple.el, and I hope it will work in future. -(declare-function evil-end-of-visual-line "evil-commands") -(defun evil-line-move (count &optional noerror) - "Like `line-move' but conserves the column. -Signal an error at buffer boundaries unless NOERROR is non-nil." - (setq this-command (if (< count 0) 'previous-line 'next-line)) - (let ((last-command - ;; Reset tmp goal column between visual/logical movement - (when (or (eq line-move-visual (consp temporary-goal-column)) - (eq temporary-goal-column most-positive-fixnum)) - last-command)) - (opoint (point))) - (if (and line-move-visual - (eq temporary-goal-column most-positive-fixnum) - (memq last-command '(next-line previous-line))) - (let (temporary-goal-column) (evil-end-of-visual-line (1+ count))) - (condition-case err - (line-move count) - ((beginning-of-buffer end-of-buffer) - (let* ((raw-col (or goal-column - (car-safe temporary-goal-column) - temporary-goal-column)) - (col (if (numberp raw-col) (max 0 raw-col) 0))) - (line-move-finish col opoint (< count 0))) - (or noerror (/= (point) opoint) (signal (car err) (cdr err)))))))) - -(defun evil-forward-syntax (syntax &optional count) - "Move point to the end or beginning of a sequence of characters in SYNTAX. -Stop on reaching a character not in SYNTAX." - (let ((notsyntax (if (= (aref syntax 0) ?^) - (substring syntax 1) - (concat "^" syntax)))) - (evil-motion-loop (dir (or count 1)) - (cond - ((< dir 0) - (skip-syntax-backward notsyntax) - (skip-syntax-backward syntax)) - (t - (skip-syntax-forward notsyntax) - (skip-syntax-forward syntax)))))) - -(defun evil-forward-chars (chars &optional count) - "Move point to the end or beginning of a sequence of CHARS. -CHARS is a character set as inside [...] in a regular expression." - (let ((notchars (if (= (aref chars 0) ?^) - (substring chars 1) - (concat "^" chars)))) - (evil-motion-loop (dir (or count 1)) - (cond - ((< dir 0) - (skip-chars-backward notchars) - (skip-chars-backward chars)) - (t - (skip-chars-forward notchars) - (skip-chars-forward chars)))))) - -(defun evil-up-block (beg end &optional count) - "Move point to the end or beginning of text enclosed by BEG and END. -BEG and END should be regular expressions matching the opening -and closing delimiters, respectively. If COUNT is greater than -zero point is moved forward otherwise it is moved -backwards. Whenever an opening delimiter is found the COUNT is -increased by one, if a closing delimiter is found the COUNT is -decreased by one. The motion stops when COUNT reaches zero. The -match-data reflects the last successful match (that caused COUNT -to reach zero). The behaviour of this functions is similar to -`up-list'." - (let* ((count (or count 1)) - (forwardp (> count 0)) - (dir (if forwardp +1 -1))) - (catch 'done - (while (not (zerop count)) - (let* ((pnt (point)) - (cl (save-excursion - (and (re-search-forward (if forwardp end beg) nil t dir) - (or (/= pnt (point)) - (progn - ;; zero size match, repeat search from - ;; the next position - (forward-char dir) - (re-search-forward (if forwardp end beg) nil t dir))) - (point)))) - (match (match-data t)) - (op (save-excursion - (and (not (equal beg end)) - (re-search-forward (if forwardp beg end) cl t dir) - (or (/= pnt (point)) - (progn - ;; zero size match, repeat search from - ;; the next position - (forward-char dir) - (re-search-forward (if forwardp beg end) cl t dir))) - (point))))) - (cond - ((not cl) - (goto-char (if forwardp (point-max) (point-min))) - (set-match-data nil) - (throw 'done count)) - (t - (if op - (progn - (setq count (if forwardp (1+ count) (1- count))) - (goto-char op)) - (setq count (if forwardp (1- count) (1+ count))) - (if (zerop count) (set-match-data match)) - (goto-char cl)))))) - 0))) - -(defun evil-up-paren (open close &optional count) - "Move point to the end or beginning of balanced parentheses. -OPEN and CLOSE should be characters identifying the opening and -closing parenthesis, respectively. If COUNT is greater than zero -point is moved forward otherwise it is moved backwards. Whenever -an opening delimiter is found the COUNT is increased by one, if a -closing delimiter is found the COUNT is decreased by one. The -motion stops when COUNT reaches zero. The match-data reflects the -last successful match (that caused COUNT to reach zero)." - ;; Always use the default `forward-sexp-function'. This is important - ;; for modes that use a custom one like `python-mode'. - ;; (addresses #364) - (let (forward-sexp-function up-list-function) - (with-syntax-table (copy-syntax-table (syntax-table)) - (modify-syntax-entry open (format "(%c" close)) - (modify-syntax-entry close (format ")%c" open)) - (let ((rest (evil-motion-loop (dir count) - (let ((pnt (point))) - (condition-case nil - (cond - ((> dir 0) - (while (progn - (up-list dir t) - (/= (char-before) close)))) - (t - (while (progn - (up-list dir t) - (/= (char-after) open))))) - (error (goto-char pnt))))))) - (cond - ((= rest count) (set-match-data nil)) - ((> count 0) (set-match-data (list (1- (point)) (point)))) - (t (set-match-data (list (point) (1+ (point)))))) - rest)))) - -(defun evil-up-xml-tag (&optional count) - "Move point to the end or beginning of balanced xml tags. -If COUNT is greater than zero point is moved forward otherwise it is moved -backwards. Whenever an opening delimiter is found the COUNT is increased by -one, if a closing delimiter is found the COUNT is decreased by one. The motion -stops when COUNT reaches zero. The match data reflects the last successful -match (that caused COUNT to reach zero)." - (let* ((dir (if (> (or count 1) 0) +1 -1)) - (count (abs (or count 1))) - (op (if (> dir 0) 1 2)) - (cl (if (> dir 0) 2 1)) - (orig (point)) - pnt tags match) - (catch 'done - (while (> count 0) - ;; find the previous opening tag - (while - (and (setq match - (re-search-forward - "<\\([^/ >\n]+\\)\\(?:=>?\\|[^\"/>]\\|\"[^\"]*\"\\)*?>\\|</\\([^>]+?\\)>" - nil t dir)) - (cond - ((match-beginning op) - (push (match-string op) tags)) - ((null tags) nil) ; free closing tag - ((and (< dir 0) - (string= (car tags) (match-string cl))) - ;; in backward direction we only accept matching - ;; tags. If the current tag is a free opener - ;; without matching closing tag, the subsequent - ;; test will make us ignore this tag - (pop tags)) - ((and (> dir 0)) - ;; non matching openers are considered free openers - (while (and tags - (not (string= (car tags) - (match-string cl)))) - (pop tags)) - (pop tags))))) - (unless (setq match (and match (match-data t))) - (setq match nil) - (throw 'done count)) - ;; found closing tag, look for corresponding opening tag - (cond - ((> dir 0) - (setq pnt (match-end 0)) - (goto-char (match-beginning 0))) - (t - (setq pnt (match-beginning 0)) - (goto-char (match-end 0)))) - (let* ((tag (match-string cl)) - (refwd (concat "<\\(/\\)?" - (regexp-quote tag) - "\\(?:>\\|[ \n]\\(?:[^\"/>]\\|\"[^\"]*\"\\)*?>\\)")) - (cnt 1)) - (while (and (> cnt 0) (re-search-backward refwd nil t dir)) - (setq cnt (+ cnt (if (match-beginning 1) dir (- dir))))) - (if (zerop cnt) (setq count (1- count) tags nil)) - (goto-char pnt))) - (if (> count 0) - (set-match-data nil) - (set-match-data match) - (goto-char (if (> dir 0) (match-end 0) (match-beginning 0))))) - ;; if not found, set to point-max/point-min - (unless (zerop count) - (set-match-data nil) - (goto-char (if (> dir 0) (point-max) (point-min))) - (if (/= (point) orig) (setq count (1- count)))) - (* dir count))) - -(defun evil-forward-quote (quote &optional count) - "Move point to the end or beginning of a string. -QUOTE is the character delimiting the string. If COUNT is greater -than zero point is moved forward otherwise it is moved -backwards." - (let (reset-parser) - (with-syntax-table (copy-syntax-table (syntax-table)) - (unless (= (char-syntax quote) ?\") - (modify-syntax-entry quote "\"") - (setq reset-parser t)) - ;; global parser state is out of state, use local one - (let* ((pnt (point)) - (state (save-excursion - (beginning-of-defun) - (parse-partial-sexp (point) pnt nil nil (syntax-ppss)))) - (bnd (bounds-of-evil-string-at-point state))) - (when (and bnd (< (point) (cdr bnd))) - ;; currently within a string - (if (> count 0) - (progn - (goto-char (cdr bnd)) - (setq count (1- count))) - (goto-char (car bnd)) - (setq count (1+ count)))) - ;; forward motions work with local parser state - (cond - ((> count 0) - ;; no need to reset global parser state because we only use - ;; the local one - (setq reset-parser nil) - (catch 'done - (while (and (> count 0) (not (eobp))) - (setq state (parse-partial-sexp - (point) (point-max) nil nil state 'syntax-table)) - (cond - ((nth 3 state) - (setq bnd (bounds-of-thing-at-point 'evil-string)) - (goto-char (cdr bnd)) - (setq count (1- count))) - ((eobp) (goto-char pnt) (throw 'done nil)))))) - ((< count 0) - ;; need to update global cache because of backward motion - (setq reset-parser (and reset-parser (point))) - (save-excursion - (beginning-of-defun) - (syntax-ppss-flush-cache (point))) - (catch 'done - (while (and (< count 0) (not (bobp))) - (setq pnt (point)) - (while (and (not (bobp)) - (or (eobp) (/= (char-after) quote))) - (backward-char)) - (cond - ((setq bnd (bounds-of-thing-at-point 'evil-string)) - (goto-char (car bnd)) - (setq count (1+ count))) - ((bobp) (goto-char pnt) (throw 'done nil)) - (t (backward-char)))))) - (t (setq reset-parser nil))))) - (when reset-parser - ;; reset global cache - (save-excursion - (goto-char reset-parser) - (beginning-of-defun) - (syntax-ppss-flush-cache (point)))) - count)) - -;;; Thing-at-point motion functions for Evil text objects and motions -(defun forward-evil-empty-line (&optional count) - "Move forward COUNT empty lines." - (setq count (or count 1)) - (cond - ((> count 0) - (while (and (> count 0) (not (eobp))) - (when (and (bolp) (eolp)) - (setq count (1- count))) - (forward-line 1))) - (t - (while (and (< count 0) (not (bobp)) - (zerop (forward-line -1))) - (when (and (bolp) (eolp)) - (setq count (1+ count)))))) - count) - -(defun forward-evil-space (&optional count) - "Move forward COUNT whitespace sequences [[:space:]]+." - (evil-forward-chars "[:space:]" count)) - -(defun forward-evil-word (&optional count) - "Move forward COUNT words. -Moves point COUNT words forward or (- COUNT) words backward if -COUNT is negative. Point is placed after the end of the word (if -forward) or at the first character of the word (if backward). A -word is a sequence of word characters matching -\[[:word:]] (recognized by `forward-word'), a sequence of -non-whitespace non-word characters '[^[:word:]\\n\\r\\t\\f ]', or -an empty line matching ^$." - (evil-forward-nearest - count - #'(lambda (&optional cnt) - (let ((word-separating-categories evil-cjk-word-separating-categories) - (word-combining-categories evil-cjk-word-combining-categories) - (pnt (point))) - (forward-word cnt) - (if (= pnt (point)) cnt 0))) - #'(lambda (&optional cnt) - (evil-forward-chars "^[:word:]\n\r\t\f " cnt)) - #'forward-evil-empty-line)) - -(defun forward-evil-WORD (&optional count) - "Move forward COUNT \"WORDS\". -Moves point COUNT WORDS forward or (- COUNT) WORDS backward if -COUNT is negative. Point is placed after the end of the WORD (if -forward) or at the first character of the WORD (if backward). A -WORD is a sequence of non-whitespace characters -'[^\\n\\r\\t\\f ]', or an empty line matching ^$." - (evil-forward-nearest count - #'(lambda (&optional cnt) - (evil-forward-chars "^\n\r\t\f " cnt)) - #'forward-evil-empty-line)) - -(defun forward-evil-symbol (&optional count) - "Move forward COUNT symbols. -Moves point COUNT symbols forward or (- COUNT) symbols backward -if COUNT is negative. Point is placed after the end of the -symbol (if forward) or at the first character of the symbol (if -backward). A symbol is either determined by `forward-symbol', or -is a sequence of characters not in the word, symbol or whitespace -syntax classes." - (evil-forward-nearest - count - #'(lambda (&optional cnt) - (evil-forward-syntax "^w_->" cnt)) - #'(lambda (&optional cnt) - (let ((pnt (point))) - (forward-symbol cnt) - (if (= pnt (point)) cnt 0))) - #'forward-evil-empty-line)) - -(defun forward-evil-defun (&optional count) - "Move forward COUNT defuns. -Moves point COUNT defuns forward or (- COUNT) defuns backward -if COUNT is negative. A defun is defined by -`beginning-of-defun' and `end-of-defun' functions." - (evil-motion-loop (dir (or count 1)) - (if (> dir 0) (end-of-defun) (beginning-of-defun)))) - -(defun forward-evil-sentence (&optional count) - "Move forward COUNT sentences. -Moves point COUNT sentences forward or (- COUNT) sentences -backward if COUNT is negative. This function is the same as -`forward-sentence' but returns the number of sentences that could -NOT be moved over." - (evil-motion-loop (dir (or count 1)) - (ignore-errors (forward-sentence dir)))) - -(defun forward-evil-paragraph (&optional count) - "Move forward COUNT paragraphs. -Moves point COUNT paragraphs forward or (- COUNT) paragraphs backward -if COUNT is negative. A paragraph is defined by -`start-of-paragraph-text' and `forward-paragraph' functions." - (evil-motion-loop (dir (or count 1)) - (cond - ((> dir 0) (forward-paragraph)) - ((not (bobp)) (start-of-paragraph-text) (beginning-of-line))))) - -(defvar evil-forward-quote-char ?\" - "The character to be used by `forward-evil-quote'.") - -(defun forward-evil-quote (&optional count) - "Move forward COUNT strings. -The quotation character is specified by the global variable -`evil-forward-quote-char'. This character is passed to -`evil-forward-quote'." - (evil-forward-quote evil-forward-quote-char count)) - -(defun forward-evil-quote-simple (&optional count) - "Move forward COUNT strings. -The quotation character is specified by the global variable -`evil-forward-quote-char'. This functions uses Vim's rules -parsing from the beginning of the current line for quotation -characters. It should only be used when looking for strings -within comments and buffer *must* be narrowed to the comment." - (let ((dir (if (> (or count 1) 0) 1 -1)) - (ch evil-forward-quote-char) - (pnt (point)) - (cnt 0)) - (beginning-of-line) - ;; count number of quotes before pnt - (while (< (point) pnt) - (when (= (char-after) ch) - (setq cnt (1+ cnt))) - (forward-char)) - (setq cnt (- (* 2 (abs count)) (mod cnt 2))) - (cond - ((> dir 0) - (while (and (not (eolp)) (not (zerop cnt))) - (when (= (char-after) ch) (setq cnt (1- cnt))) - (forward-char)) - (when (not (zerop cnt)) (goto-char (point-max)))) - (t - (while (and (not (bolp)) (not (zerop cnt))) - (when (= (char-before) ch) (setq cnt (1- cnt))) - (forward-char -1)) - (when (not (zerop cnt)) (goto-char (point-min))))) - (/ cnt 2))) - -;;; Motion functions -(defun evil-forward-beginning (thing &optional count) - "Move forward to beginning of THING. -The motion is repeated COUNT times." - (setq count (or count 1)) - (if (< count 0) - (forward-thing thing count) - (let ((bnd (bounds-of-thing-at-point thing)) - rest) - (when (and bnd (< (point) (cdr bnd))) - (goto-char (cdr bnd))) - (ignore-errors - (when (zerop (setq rest (forward-thing thing count))) - (when (and (bounds-of-thing-at-point thing) - (not (bobp)) - ;; handle final empty line - (not (and (bolp) (eobp)))) - (backward-char)) - (beginning-of-thing thing))) - rest))) - -(defun evil-backward-beginning (thing &optional count) - "Move backward to beginning of THING. -The motion is repeated COUNT times. This is the same as calling -`evil-backward-beginning' with -COUNT." - (evil-forward-beginning thing (- (or count 1)))) - -(defun evil-forward-end (thing &optional count) - "Move forward to end of THING. -The motion is repeated COUNT times." - (setq count (or count 1)) - (if (> count 0) - (progn (unless (eobp) (forward-char)) - (prog1 (forward-thing thing count) - (unless (bobp) (backward-char)))) - (let ((bnd (bounds-of-thing-at-point thing)) - rest) - (when (and bnd (< (point) (cdr bnd) )) - (goto-char (car bnd))) - (ignore-errors - (when (zerop (setq rest (forward-thing thing count))) - (end-of-thing thing) - (backward-char))) - rest))) - -(defun evil-backward-end (thing &optional count) - "Move backward to end of THING. -The motion is repeated COUNT times. This is the same as calling -`evil-backward-end' with -COUNT." - (evil-forward-end thing (- (or count 1)))) - -(defun evil-forward-word (&optional count) - "Move by words. -Moves point COUNT words forward or (- COUNT) words backward if -COUNT is negative. This function is the same as `forward-word' -but returns the number of words by which point could *not* be -moved." - (setq count (or count 1)) - (let* ((dir (if (>= count 0) +1 -1)) - (count (abs count))) - (while (and (> count 0) - (forward-word dir)) - (setq count (1- count))) - count)) - -(defun evil-in-comment-p (&optional pos) - "Check if POS is within a comment according to current syntax. -If POS is nil, (point) is used. The return value is the beginning -position of the comment." - (setq pos (or pos (point))) - (let ((chkpos - (cond - ((eobp) pos) - ((= (char-syntax (char-after)) ?<) (1+ pos)) - ((and (not (zerop (logand (car (syntax-after (point))) - (ash 1 16)))) - (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0) - (ash 1 17))))) - (+ pos 2)) - ((and (not (zerop (logand (car (syntax-after (point))) - (ash 1 17)))) - (not (zerop (logand (or (car (syntax-after (1- (point)))) 0) - (ash 1 16))))) - (1+ pos)) - (t pos)))) - (let ((syn (save-excursion (syntax-ppss chkpos)))) - (and (nth 4 syn) (nth 8 syn))))) - -(defun evil-looking-at-start-comment (&optional move) - "Return t if point is at the start of a comment. -Point must be on one of the opening characters of a block comment -according to the current syntax table. Futhermore, these -characters must been parsed as opening characters, i.e. they -won't be considered as comment starters inside a string or -possibly another comment. Point is moved to the first character -of the comment opener if MOVE is non-nil." - (cond - ((= (point) (point-max)) nil) - ;; one character opener - ((= (char-syntax (char-after)) ?<) - (equal (point) (evil-in-comment-p (1+ (point))))) - ;; two character opener on first char - ((and (not (zerop (logand (car (syntax-after (point))) - (ash 1 16)))) - (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0) - (ash 1 17))))) - (equal (point) (evil-in-comment-p (+ 2 (point))))) - ;; two character opener on second char - ((and (not (zerop (logand (car (syntax-after (point))) - (ash 1 17)))) - (not (zerop (logand (or (car (syntax-after (1- (point)))) 0) - (ash 1 16))))) - (and (equal (1- (point)) (evil-in-comment-p (1+ (point)))) - (prog1 t (when move (backward-char))))))) - -(defun evil-looking-at-end-comment (&optional move) - "Return t if point is at the end of a comment. -Point must be on one of the opening characters of a block comment -according to the current syntax table. Futhermore, these -characters must been parsed as opening characters, i.e. they -won't be considered as comment starters inside a string or -possibly another comment. Point is moved right after the comment -closer if MOVE is non-nil." - (cond - ;; one char closer - ((= (char-syntax (char-after)) ?>) - (and (evil-in-comment-p) ; in comment - (not (evil-in-comment-p (1+ (point)))) - (prog1 t (when move (forward-char))))) - ;; two char closer on first char - ((and (not (zerop (logand (car (syntax-after (point))) - (ash 1 18)))) - (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0) - (ash 1 19))))) - (and (evil-in-comment-p) - (not (evil-in-comment-p (+ (point) 2))) - (prog1 t (when move (forward-char 2))))) - ;; two char closer on second char - ((and (not (zerop (logand (car (syntax-after (point))) - (ash 1 19)))) - (not (zerop (logand (or (car (syntax-after (1- (point)))) 0) - (ash 1 18))))) - (and (evil-in-comment-p) - (not (evil-in-comment-p (1+ (point)))) - (prog1 t (when move (forward-char))))))) - -(defun evil-insert-newline-above () - "Insert a new line above point and place point in that line -with regard to indentation." - (evil-narrow-to-field - (evil-move-beginning-of-line) - (insert (if use-hard-newlines hard-newline "\n")) - (forward-line -1) - (back-to-indentation))) - -(defun evil-insert-newline-below () - "Insert a new line below point and place point in that line -with regard to indentation." - (evil-narrow-to-field - (evil-move-end-of-line) - (insert (if use-hard-newlines hard-newline "\n")) - (back-to-indentation))) - -;;; Markers - -(defun evil-global-marker-p (char) - "Whether CHAR denotes a global marker." - (or (and (>= char ?A) (<= char ?Z)) - (assq char (default-value 'evil-markers-alist)))) - -(defun evil-set-marker (char &optional pos advance) - "Set the marker denoted by CHAR to position POS. -POS defaults to the current position of point. -If ADVANCE is t, the marker advances when inserting text at it; -otherwise, it stays behind." - (interactive (list (read-char))) - (catch 'done - (let ((marker (evil-get-marker char t)) alist) - (unless (markerp marker) - (cond - ((eq marker 'evil-visual-beginning) - (setq marker evil-visual-mark)) - ((eq marker 'evil-visual-goto-end) - (setq marker evil-visual-point)) - ((and marker (symbolp marker) (boundp marker)) - (set marker (or (symbol-value marker) (make-marker))) - (setq marker (symbol-value marker))) - ((eq marker 'evil-jump-backward-swap) - (evil-set-jump) - (throw 'done nil)) - ((functionp marker) - (user-error "Cannot set special marker `%c'" char)) - ((evil-global-marker-p char) - (setq alist (default-value 'evil-markers-alist) - marker (make-marker)) - (evil--add-to-alist alist char marker) - (setq-default evil-markers-alist alist)) - (t - (setq marker (make-marker)) - (evil--add-to-alist evil-markers-alist char marker)))) - (add-hook 'kill-buffer-hook #'evil-swap-out-markers nil t) - (set-marker-insertion-type marker advance) - (set-marker marker (or pos (point)))))) -(evil-set-command-properties #'evil-set-marker :suppress-operator t) - -(defun evil-get-marker (char &optional raw) - "Return the marker denoted by CHAR. -This is either a marker object as returned by `make-marker', -a number, a cons cell (FILE . POS) with FILE being a string -and POS a number, or nil. If RAW is non-nil, then the -return value may also be a variable, a movement function, -or a marker object pointing nowhere." - (let ((marker (cdr (assq char (if (evil-global-marker-p char) - (default-value 'evil-markers-alist) - evil-markers-alist))))) - (if raw - marker - (when (and (symbolp marker) (boundp marker)) - (setq marker (symbol-value marker))) - (when (functionp marker) - (save-excursion - (save-window-excursion - (funcall marker) - (setq marker (move-marker (make-marker) (point)))))) - (if (markerp marker) - (if (eq (marker-buffer marker) (current-buffer)) - (marker-position marker) - (when (marker-buffer marker) marker)) - marker)))) - -(defun evil-swap-out-markers () - "Turn markers into file references when the buffer is killed." - (when buffer-file-name - (dolist (entry evil-markers-alist) - (and (markerp (cdr entry)) - (eq (marker-buffer (cdr entry)) (current-buffer)) - (setcdr entry (cons buffer-file-name - (marker-position (cdr entry)))))))) -(put 'evil-swap-out-markers 'permanent-local-hook t) - -(defvar calc-multiplication-has-precedence) -(defun evil--eval-expr (input) - "Eval INPUT and return stringified result, if of a suitable type. -If INPUT starts with a number, +, -, or . use `calc-eval' instead." - (let* ((calcable-p (string-match-p "\\`[[:space:]]*[0-9+.-]" input)) - (result (if calcable-p - (let ((calc-multiplication-has-precedence nil)) - (calc-eval input)) - (eval (car (read-from-string input)) t)))) - (cond - ((stringp result) result) - ((or (numberp result) (symbolp result)) - (format "%s" result)) - ((sequencep result) - (mapconcat (lambda (x) (format "%s" x)) result "\n")) - (t (user-error "Using `%s' as a string" (type-of result)))))) - -(defvar evil-paste-clear-minibuffer-first nil - "`evil-paste-before' cannot have `delete-minibuffer-contents' called before -it fetches certain registers becuase this would trigger various ex-updates, -sometimes moving point, so `C-a' `C-w' etc. would miss their intended target.") - -(defun evil-ex-remove-default () - "Remove the default text shown in the ex minibuffer. -When Ex starts, the previous command is shown enclosed in -parenthesis. This function removes this text when the first key -is pressed." - (when (and (not (eq this-command 'exit-minibuffer)) - (/= (minibuffer-prompt-end) (point-max))) - (when (eq this-command 'evil-ex-delete-backward-char) - (setq this-command 'ignore)) - (if (eq this-original-command 'evil-paste-from-register) - (setq evil-paste-clear-minibuffer-first t) - (delete-minibuffer-contents))) - (remove-hook 'pre-command-hook #'evil-ex-remove-default t)) - -(defun evil-get-register (register &optional noerror) - "Return contents of REGISTER. -Signal an error if empty, unless NOERROR is non-nil. - -The following special registers are supported. - \" the unnamed register - * the clipboard contents - + the clipboard contents - <C-w> the word at point (ex mode only) - <C-a> the WORD at point (ex mode only) - <C-o> the symbol at point (ex mode only) - <C-f> the current file at point (ex mode only) - % the current file name (read only) - # the alternate file name (read only) - / the last search pattern (read only) - : the last command line (read only) - . the last inserted text (read only) - - the last small (less than a line) delete - _ the black hole register - = the expression register (read only)" - (unless (characterp register) (error "Invalid register `%S'" register)) - (condition-case err - (or (cond - ((eq register ?\") - (current-kill 0)) - ((<= ?1 register ?9) - (let ((reg (- register ?1))) - (and (< reg (length kill-ring)) - (current-kill reg t)))) - ((memq register '(?* ?+)) - (let ((what (if (eq register ?*) 'PRIMARY 'CLIPBOARD))) - (if (eval-when-compile (>= emacs-major-version 29)) - (gui--selection-value-internal what) - ;; The following code is based on `x-selection-value-internal' - ;; (now `gui--selection-value-internal') circa Emacs 24. We're - ;; unsure why exactly it's duplicated here, and it's possible - ;; it needn't be for newer versions of Emacs. - (let ((request-type (or (bound-and-true-p x-select-request-type) - '(UTF8_STRING COMPOUND_TEXT STRING))) - text) - (unless (consp request-type) - (setq request-type (list request-type))) - (while (and request-type (not text)) - (setq text (ignore-errors - (evil-get-selection what (pop request-type))))) - (when text - (remove-text-properties 0 (length text) '(foreign-selection nil) text)) - text)))) - ((eq register ?\C-W) - (with-current-buffer - (or evil-ex-original-buffer - (let ((w (minibuffer-selected-window))) (and w (window-buffer w))) - (user-error "Register <C-w> is only available in Ex state")) - (thing-at-point 'evil-word))) - ((eq register ?\C-A) - (with-current-buffer - (or evil-ex-original-buffer - (let ((w (minibuffer-selected-window))) (and w (window-buffer w))) - (user-error "Register <C-a> is only available in Ex state")) - (thing-at-point 'evil-WORD))) - ((eq register ?\C-O) - (with-current-buffer - (or evil-ex-original-buffer - (let ((w (minibuffer-selected-window))) (and w (window-buffer w))) - (user-error "Register <C-o> is only available in Ex state")) - (thing-at-point 'evil-symbol))) - ((eq register ?\C-F) - (with-current-buffer - (or evil-ex-original-buffer - (let ((w (minibuffer-selected-window))) (and w (window-buffer w))) - (user-error "Register <C-f> is only available in Ex state")) - (thing-at-point 'filename))) - ((eq register ?\C-L) - (with-current-buffer - (or evil-ex-original-buffer - (let ((w (minibuffer-selected-window))) (and w (window-buffer w))) - (user-error "Register <C-l> is only available in Ex state")) - (replace-regexp-in-string "\n\\'" "" (thing-at-point 'line)))) - ((eq register ?%) - (or (buffer-file-name - (or evil-ex-original-buffer - (let ((w (minibuffer-selected-window))) (and w (window-buffer w))))) - (user-error "No file name"))) - ((= register ?#) - (or (with-current-buffer (other-buffer) (buffer-file-name)) - (user-error "No file name"))) - ((eq register ?/) - (defvar evil-search-module) - (or (car (cond - ((eq evil-search-module 'evil-search) evil-ex-search-history) - (isearch-regexp regexp-search-ring) - (t search-ring))) - (user-error "No previous regular expression"))) - ((eq register ?:) - (or (car evil-ex-history) (user-error "No previous command line"))) - ((eq register ?.) evil-last-insertion) - ((eq register ?-) evil-last-small-deletion) - ((eq register ?=) - (let ((enable-recursive-minibuffers t)) - (setq evil-last-=-register-input - (minibuffer-with-setup-hook - (lambda () - (when evil-last-=-register-input - (add-hook 'pre-command-hook #'evil-ex-remove-default nil t))) - (read-from-minibuffer - "=" - (and evil-last-=-register-input - (propertize evil-last-=-register-input 'face 'shadow)) - evil-eval-map - nil - 'evil-eval-history - evil-last-=-register-input - t))) - (evil--eval-expr evil-last-=-register-input))) - ((eq register ?_) "") ; the black hole register - (t (setq register (downcase register)) - (get-register register))) - (user-error "Register `%c' is empty" register)) - (error (unless noerror (signal (car err) (cdr err)))))) - -(defun evil-append-register (register text) - "Append TEXT to the contents of REGISTER." - (let ((content (get-register register))) - (set-register - register - (cond - ((not content) text) - ;; if the register does not contain a string treat it as a vector - ((not (stringp content)) (vconcat content text)) - ;; some non-trivial yank-handler -> always switch to line handler - ((or (text-property-not-all - 0 (length content) 'yank-handler nil content) - (text-property-not-all - 0 (length text) 'yank-handler nil text)) - ;; ensure complete lines - (setq text - (concat - content - (and (> (length content) 0) - (/= (aref content (1- (length content))) ?\n) - "\n") - text - (and (> (length text) 0) - (/= (aref text (1- (length text))) ?\n) - "\n"))) - (put-text-property 0 (length text) 'yank-handler '(evil-yank-line-handler) - text) - text) - (t (concat content text)))))) - -(defun evil-set-register (register text) - "Set the contents of REGISTER to TEXT. -If REGISTER is an upper case character then TEXT is appended to that -register instead of replacing its content." - (cond - ((not (characterp register)) (user-error "Invalid register")) - ;; don't allow modification of read-only registers - ((member register '(?: ?. ?%)) - (user-error "Can't modify read-only register")) - ((eq register ?\") (kill-new text)) - ((<= ?1 register ?9) - (if (null kill-ring) - (kill-new text) - (let ((kill-ring-yank-pointer kill-ring-yank-pointer) - interprogram-paste-function - interprogram-cut-function) - (current-kill (- register ?1)) - (setcar kill-ring-yank-pointer text)))) - ((eq register ?*) (evil-set-selection 'PRIMARY text)) - ((eq register ?+) (evil-set-selection 'CLIPBOARD text)) - ((eq register ?-) (setq evil-last-small-deletion text)) - ((eq register ?_) nil) ; the black hole register - ((and (<= ?A register) (<= register ?Z)) - (evil-append-register (downcase register) text)) - (t (set-register register text)))) - -(defun evil-register-list () - "Return an alist of all registers, but only those named -with number or character. Registers with symbol or string in names are ignored -to keep Vim compatibility with register jumps." - (sort (append (mapcar (lambda (reg) (cons reg (evil-get-register reg t))) - '(?\" ?* ?+ ?% ?# ?/ ?: ?. ?- - ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) - (list (cons ?= evil-last-=-register-input)) - (cl-remove-if-not (lambda (reg) (number-or-marker-p (car reg))) register-alist) - nil) - #'car-less-than-car)) - -(defsubst evil-kbd-macro-suppress-motion-error () - "Return non-nil if a motion error should be suppressed. -Whether the motion error should be suppressed depends on the -variable `evil-kbd-macro-suppress-motion-error'." - (or (and defining-kbd-macro - (memq evil-kbd-macro-suppress-motion-error '(t record))) - (and executing-kbd-macro - (memq evil-kbd-macro-suppress-motion-error '(t replay))))) - -;;; Region - -;; `set-mark' does too much at once -(defun evil-move-mark (pos) - "Set buffer's mark to POS. -If POS is nil, delete the mark." - (set-marker (mark-marker) pos)) - -(defun evil-save-transient-mark-mode () - "Save Transient Mark mode and make it buffer-local. -Any changes to Transient Mark mode are now local to the current -buffer, until `evil-restore-transient-mark-mode' is called. - -Variables pertaining to Transient Mark mode are listed in -`evil-transient-vars', and their values are stored in -`evil-transient-vals'." - (dolist (var evil-transient-vars) - (when (and (boundp var) - (not (assq var evil-transient-vals))) - (push (list var (symbol-value var) - (local-variable-p var)) - evil-transient-vals) - (make-variable-buffer-local var) - (put var 'permanent-local t)))) - -(defun evil-restore-transient-mark-mode () - "Restore Transient Mark mode. -This presupposes that `evil-save-transient-mark-mode' has been -called earlier. If Transient Mark mode was disabled before but -enabled in the meantime, this function disables it; if it was -enabled before but disabled in the meantime, this function -enables it. - -The earlier settings of Transient Mark mode are stored in -`evil-transient-vals'." - (let (entry local var val) - (while (setq entry (pop evil-transient-vals)) - (setq var (pop entry) - val (pop entry) - local (pop entry)) - (unless local - (kill-local-variable var)) - (unless (equal (symbol-value var) val) - (if (fboundp var) - (funcall var (if val 1 -1)) - (setq var val)))))) - -;; In theory, an active region implies Transient Mark mode, and -;; disabling Transient Mark mode implies deactivating the region. -;; In practice, Emacs never clears `mark-active' except in Transient -;; Mark mode, so we define our own toggle functions to make things -;; more predictable. -(defun evil-transient-mark (&optional arg) - "Toggle Transient Mark mode. -Ensure that the region is properly deactivated. -Enable with positive ARG, disable with negative ARG." - (unless (numberp arg) - (setq arg (if transient-mark-mode -1 1))) - (cond - ((< arg 1) - (evil-active-region -1) - ;; Transient Mark mode cannot be disabled - ;; while CUA mode is enabled - (when (fboundp 'cua-mode) - (cua-mode -1)) - (when transient-mark-mode - (transient-mark-mode -1))) - (t - (unless transient-mark-mode - (evil-active-region -1) - (transient-mark-mode 1))))) - -(defun evil-active-region (&optional arg) - "Toggle active region. -Ensure that Transient Mark mode is properly enabled. -Enable with positive ARG, disable with negative ARG." - (unless (numberp arg) - (setq arg (if (region-active-p) -1 1))) - (cond - ((and (< arg 1)) - (when (or transient-mark-mode mark-active) - (setq mark-active nil - deactivate-mark nil) - (when (boundp 'cua--explicit-region-start) - (setq cua--explicit-region-start nil)) - (run-hooks 'deactivate-mark-hook))) - (t - (evil-transient-mark 1) - (when deactivate-mark - (setq deactivate-mark nil)) - (unless (mark t) - (evil-move-mark (point))) - (unless (region-active-p) - (set-mark (mark t))) - (when (boundp 'cua--explicit-region-start) - (setq cua--explicit-region-start t))))) - -(defmacro evil-with-transient-mark-mode (&rest body) - "Execute BODY with Transient Mark mode. -Then restore Transient Mark mode to its previous setting." - (declare (indent defun) - (debug t)) - `(let ((inhibit-quit t) - evil-transient-vals) - (unwind-protect - (progn - (evil-save-transient-mark-mode) - (evil-transient-mark 1) - ,@body) - (evil-restore-transient-mark-mode)))) - -(defmacro evil-with-active-region (beg end &rest body) - "Execute BODY with an active region from BEG to END." - (declare (indent 2) - (debug t)) - `(let ((beg ,beg) (end ,end) - evil-transient-vals) - (evil-with-transient-mark-mode - (save-excursion - (evil-active-region 1) - (evil-move-mark beg) - (goto-char end) - ,@body)))) - -(defun evil-exchange-point-and-mark () - "Exchange point and mark without activating the region." - (let* ((point (point)) - (mark (or (mark t) point))) - (set-marker (mark-marker) point) - (goto-char mark))) - -(defun evil-apply-on-block (func beg end pass-columns &rest args) - "Call FUNC for each line of a block selection. -The selection is specified by the region BEG and END. FUNC must -take at least two arguments, the beginning and end of each -line. If PASS-COLUMNS is non-nil, these values are the columns, -otherwise they are buffer positions. Extra arguments to FUNC may -be passed via ARGS." - (let (startcol startpt endcol endpt) - (save-excursion - (goto-char beg) - (setq startcol (current-column) - startpt (line-beginning-position)) - (goto-char end) - (setq endcol (current-column)) - (forward-line 1) - (setq endpt (point-marker)) - ;; ensure the start column is the left one. - (evil-sort startcol endcol) - ;; maybe extend up to EOL - (when (and (memq last-command '(next-line previous-line evil-use-register)) - (eq temporary-goal-column most-positive-fixnum)) - (goto-char startpt) - (while (< (point) endpt) - (setq endcol (max endcol (evil-column (line-end-position)))) - (forward-line 1))) - ;; start looping over lines - (goto-char startpt) - (while (< (point) endpt) - (if pass-columns - (apply func startcol endcol args) - (apply func - (save-excursion (evil-move-to-column startcol)) - (save-excursion (evil-move-to-column endcol t)) - args)) - (forward-line 1))))) - -(defun evil-apply-on-rectangle (function start end &rest args) - "Like `apply-on-rectangle' but maybe extends to eol. -If `temporary-goal-column' is set to a big number, then the -region of each line is extended to the end of each line. The end -column is set to the maximal column in all covered lines." - (apply #'evil-apply-on-block function start end t args)) - -;;; Insertion - -(defun evil-track-last-insertion (beg end old-len) - "Track the last insertion range and its text. -BEG, END and OLD-LEN are as for `after-change-functions'. -The insertion range is stored as a pair of buffer positions in -`evil-current-insertion'." - ;; For deletions left of, or insertions right of the end of the last - ;; insertion (with any changes in between), extend or contract the - ;; insertion range as appropriate. Otherwise, start a new range. - (if (when evil-current-insertion - (let ((ins-beg (car evil-current-insertion)) - (ins-end (cdr evil-current-insertion))) - (and (<= ins-beg beg) - (or (= (+ beg old-len) ins-end) - (when (evil-replace-state-p) (= beg ins-end)))))) - ;; Ignore insertion of previous char from Backspace in Replace state - (unless (and (eq this-command 'evil-replace-backspace) (= old-len 0)) - (setcdr evil-current-insertion end)) - (setq evil-current-insertion (cons beg end)))) -(put 'evil-track-last-insertion 'permanent-local-hook t) - -(defun evil-start-track-last-insertion () - "Start tracking the last insertion." - (setq evil-current-insertion nil) - (add-hook 'after-change-functions #'evil-track-last-insertion nil t)) - -(defun evil-stop-track-last-insertion () - "Stop tracking the last insertion. -The tracked insertion is set to `evil-last-insertion'." - (setq evil-last-insertion - (and evil-current-insertion - ;; Check whether the insertion range is a valid buffer - ;; range. If a buffer modification is done from within - ;; another change hook or modification-hook (yasnippet - ;; does this using overlay modification-hooks), then the - ;; insertion information may be invalid. There is no way - ;; to detect this situation, but at least we should - ;; ensure that no error occurs (see bug #272). - (>= (car evil-current-insertion) (point-min)) - (<= (cdr evil-current-insertion) (point-max)) - (buffer-substring-no-properties (car evil-current-insertion) - (cdr evil-current-insertion)))) - (remove-hook 'after-change-functions #'evil-track-last-insertion t)) - -;;; Paste - -(defun evil-yank-characters (beg end &optional register yank-handler) - "Save the characters defined by the region BEG and END in the kill-ring." - (let ((text (filter-buffer-substring beg end))) - (when yank-handler - (put-text-property 0 (length text) 'yank-handler (list yank-handler) text)) - (when register - (evil-set-register register text)) - (when evil-was-yanked-without-register - (evil-set-register ?0 text)) ; "0 register contains last yanked text - (unless (eq register ?_) - (kill-new text)))) - -(defun evil-yank-lines (beg end &optional register yank-handler) - "Save the lines in the region BEG and END into the kill-ring." - (let ((text (filter-buffer-substring beg end)) - (yank-handler (list (or yank-handler #'evil-yank-line-handler) - nil - t))) - ;; Ensure the text ends with a newline. This is required - ;; if the deleted lines were the last lines in the buffer. - (when (or (zerop (length text)) - (/= (aref text (1- (length text))) ?\n)) - (setq text (concat text "\n"))) - (put-text-property 0 (length text) 'yank-handler yank-handler text) - (when register - (evil-set-register register text)) - (when evil-was-yanked-without-register - (evil-set-register ?0 text)) ; "0 register contains last yanked text - (unless (eq register ?_) - (kill-new text)))) - -(defun evil-yank-rectangle (beg end &optional register yank-handler) - "Save the rectangle defined by region BEG and END into the kill-ring." - (let ((lines (list nil))) - (evil-apply-on-rectangle #'extract-rectangle-line beg end lines) - ;; We remove spaces from the beginning and the end of the next. - ;; Spaces are inserted explicitly in the yank-handler in order to - ;; NOT insert lines full of spaces. - (setq lines (nreverse (cdr lines))) - ;; `text' is used as default insert text when pasting this rectangle - ;; in another program, e.g., using the X clipboard. - (let ((yank-handler (list (or yank-handler #'evil-yank-block-handler) - lines - t - #'evil-delete-yanked-rectangle)) - (text (mapconcat #'identity lines "\n"))) - (put-text-property 0 (length text) 'yank-handler yank-handler text) - (when register - (evil-set-register register text)) - (when evil-was-yanked-without-register - (evil-set-register ?0 text)) ; "0 register contains last yanked text - (unless (eq register ?_) - (kill-new text)) - text))) - -(defun evil-remove-yank-excluded-properties (text) - "Remove `yank-excluded-properties' from TEXT." - (if (eq yank-excluded-properties t) - (set-text-properties 0 (length text) nil text) - (remove-list-of-text-properties 0 (length text) - yank-excluded-properties text))) - -(defun evil-yank-line-handler (text) - "Insert the current text linewise." - (let ((text (apply #'concat (make-list (or evil-paste-count 1) text))) - (opoint (point))) - (evil-remove-yank-excluded-properties text) - (cond - ((eq this-command 'evil-paste-before) - (evil-move-beginning-of-line) - (let ((beg (point))) - (insert text) - (setq evil-last-paste - (list 'evil-paste-before evil-paste-count opoint beg (point))) - (evil-set-marker ?\[ beg) - (evil-set-marker ?\] (1- (point))) - (goto-char beg)) - (back-to-indentation)) - ((eq this-command 'evil-paste-after) - (evil-move-end-of-line) - (let ((beg (point))) - (insert "\n") - (insert text) - (delete-char -1) ; delete the last newline - (setq evil-last-paste - (list 'evil-paste-after evil-paste-count opoint beg (point))) - (evil-set-marker ?\[ (1+ beg)) - (evil-set-marker ?\] (point)) - (unless evil--cursor-after - (goto-char (1+ beg)))) - (back-to-indentation)) - (t (insert text))))) - -(defun evil-yank-block-handler (lines) - "Insert the current text as block." - (let* ((count (or evil-paste-count 1)) - shifted-forward - (col (if (and (eq this-command 'evil-paste-after) - (not (and (bolp) (eolp))) - (setq shifted-forward t)) - (1+ (current-column)) - (current-column))) - (opoint (point)) - (first t)) - (dolist (line lines) - ;; maybe we have to insert a new line at eob - (if first - (setq first nil) - (when (or (> (forward-line 1) 0) - (and (eobp) (not (bolp)))) - (insert "\n"))) - ;; concat multiple copies according to count - (setq line (apply #'concat (make-list count line))) - ;; trim whitespace at beginning and end - (string-match "\\` *\\(.*?\\) *\\'" line) - (let ((text (match-string 1 line)) - (begextra (match-beginning 1)) - (endextra (- (match-end 0) (match-end 1)))) - ;; insert text unless we insert an empty line behind eol - (unless (and (< (evil-column (line-end-position)) col) - (string= text "")) - ;; if we paste behind eol, it may be sufficient to insert tabs - (if (< (evil-column (line-end-position)) col) - (move-to-column (+ col begextra) t) - (move-to-column col t) - (insert (make-string begextra ?\s))) - (evil-remove-yank-excluded-properties text) - (insert text) - (unless (eolp) - ;; text follows, so we have to insert spaces - (insert (make-string endextra ?\s)))))) - (setq evil-last-paste - (list this-command - evil-paste-count - opoint - (length lines) ; number of rows - (* count (length (car lines))))) ; number of columns - (evil-set-marker ?\[ opoint) - (evil-set-marker ?\] (1- (point))) - (if evil--cursor-after - (backward-char) - (goto-char opoint) - (when shifted-forward (forward-char))))) - -(defun evil-delete-yanked-rectangle (nrows ncols) - "Special function to delete the block yanked by a previous paste command. -Supplied as the `undo' element of a yank handler." - (let ((opoint (point)) - (col (if (eq last-command 'evil-paste-after) - (1+ (current-column)) - (current-column)))) - (dotimes (_ nrows) - (delete-region (save-excursion - (move-to-column col) - (point)) - (save-excursion - (move-to-column (+ col ncols)) - (point))) - (unless (eobp) (forward-line))) - (goto-char opoint))) - -;; TODO: if undoing is disabled in the current buffer, paste-pop won't -;; work. Although this is probably not a big problem, because usually -;; buffers where `evil-paste-pop' may be useful have undoing enabled. -;; A solution would be to temporarily enable undo when pasting and -;; store the undo information in a special variable that does not -;; interfere with `buffer-undo-list'. -(defun evil-paste-pop (count) - "Replace the just-yanked stretch of killed text with a different stretch. -This command is allowed only immediatly after a `yank', -`evil-paste-before', `evil-paste-after' or `evil-paste-pop'. -This command uses the same paste command as before, i.e., when -used after `evil-paste-after' the new text is also yanked using -`evil-paste-after', used with the same paste-count argument. - -The COUNT argument inserts the COUNTth previous kill. If COUNT -is negative this is a more recent kill." - (interactive "p") - (unless (memq last-command - '(evil-paste-after - evil-paste-before - evil-visual-paste)) - (user-error "Previous command was not an evil-paste: %s" last-command)) - (unless evil-last-paste - (user-error "Previous paste command used a register")) - (evil-undo-pop) - (goto-char (nth 2 evil-last-paste)) - (setq this-command (nth 0 evil-last-paste)) - ;; use temporary kill-ring, so the paste cannot modify it - (let ((kill-ring (list (current-kill - (if (and (> count 0) (nth 5 evil-last-paste)) - ;; if was visual paste then skip the - ;; text that has been replaced - (1+ count) - count)))) - (kill-ring-yank-pointer kill-ring)) - (when (eq last-command 'evil-visual-paste) - (let ((evil-no-display t)) - (evil-visual-restore))) - (funcall (nth 0 evil-last-paste) (nth 1 evil-last-paste)) - ;; if this was a visual paste, then mark the last paste as NOT - ;; being the first visual paste - (when (eq last-command 'evil-visual-paste) - (setcdr (nthcdr 4 evil-last-paste) nil)))) - -(defun evil-paste-pop-next (count) - "Same as `evil-paste-pop' but with negative argument." - (interactive "p") - (evil-paste-pop (- count))) - -;;; Interactive forms - -(defun evil-match-interactive-code (interactive &optional pos) - "Match an interactive code at position POS in string INTERACTIVE. -Return the first matching entry in `evil-interactive-alist', or nil." - (unless pos (setq pos 0)) - (cl-loop - with len = (length interactive) for entry in evil-interactive-alist thereis - (let* ((string (car entry)) - (end (+ pos (length string)))) - (and (<= end len) - (eq (compare-strings string nil nil interactive pos end) t) - entry)))) - -(defun evil-concatenate-interactive-forms (&rest forms) - "Concatenate interactive list expressions FORMS. -Return a single expression where successive expressions -are joined, if possible." - (let (result) - (when forms - (while (cdr forms) - (cond - ((null (car forms)) - (pop forms)) - ((and (eq (car (car forms)) 'list) - (eq (car (cadr forms)) 'list)) - (setq forms (cons (append (car forms) - (cdr (cadr forms))) - (cdr (cdr forms))))) - (t (push (pop forms) result)))) - (when (car forms) - (push (pop forms) result)) - (setq result (nreverse result)) - (cond - ((null result)) - ((null (cdr result)) (car result)) - (t `(append ,@result)))))) - -(defun evil-interactive-string (string) - "Evaluate the interactive string STRING. -The string may contain extended interactive syntax. -The return value is a cons cell (FORM . PROPERTIES), -where FORM is a single list-expression to be passed to -a standard `interactive' statement, and PROPERTIES is a -list of command properties as passed to `evil-define-command'." - (let ((len (length string)) - (pos 0) - forms properties) - (while (< pos len) - (if (eq (aref string pos) ?\n) - (setq pos (1+ pos)) - (cl-destructuring-bind (code expr . plist) - (or (evil-match-interactive-code string pos) - (user-error "Unknown interactive code: `%s'" - (substring string pos))) - (setq pos (+ pos (length code))) - (when (functionp expr) - (let ((prompt (substring - string pos - (or (string-match-p "\n" string pos) len)))) - (setq pos (+ pos (length prompt)) - expr `(funcall ,expr ,prompt)))) - (setq forms (append forms (list expr)) - properties (append properties plist))))) - (cons `(append ,@forms) properties))) - -(defun evil-interactive-form (&rest args) - "Evaluate interactive forms ARGS. -The return value is a cons cell (FORM . PROPERTIES), -where FORM is a single list-expression to be passed to -a standard `interactive' statement, and PROPERTIES is a -list of command properties as passed to `evil-define-command'." - (let (forms properties) - (dolist (arg args) - (if (not (stringp arg)) - (setq forms (append forms (list arg))) - (setq arg (evil-interactive-string arg) - forms (append forms (cdr (car arg))) - properties (append properties (cdr arg))))) - (cons (apply #'evil-concatenate-interactive-forms forms) - properties))) - -;;; Types - -(defun evil-type (object &optional default) - "Return the type of OBJECT, or DEFAULT if none." - (let (type) - (cond - ((overlayp object) - (setq type (overlay-get object :type))) - ((evil-range-p object) - (setq type (nth 2 object))) - ((listp object) - (setq type (plist-get object :type))) - ((commandp object) - (setq type (evil-get-command-property object :type))) - ((symbolp object) - (setq type (get object 'type)))) - (setq type (or type default)) - (and (evil-type-p type) type))) - -(defun evil-set-type (object type) - "Set the type of OBJECT to TYPE. -For example, (evil-set-type \\='next-line \\='line) -will make `line' the type of the `next-line' command." - (cond - ((overlayp object) - (overlay-put object :type type)) - ((evil-range-p object) - (evil-set-range-type object type)) - ((listp object) - (plist-put object :type type)) - ((commandp object) - (evil-set-command-property object :type type)) - ((symbolp object) - (put object 'type type))) - object) - -(defun evil-type-property (type prop) - "Return property PROP for TYPE." - (plist-get (cdr (assq type evil-type-properties)) prop)) - -(defun evil-type-p (sym) - "Whether SYM is the name of a type." - (assq sym evil-type-properties)) - -(defun evil-expand (beg end type &rest properties) - "Expand BEG and END as TYPE with PROPERTIES. -Return a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list." - (apply #'evil-transform - ;; don't expand if already expanded - (unless (plist-get properties :expanded) :expand) - beg end type properties)) - -(defun evil-contract (beg end type &rest properties) - "Contract BEG and END as TYPE with PROPERTIES. -Return a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list." - (apply #'evil-transform :contract beg end type properties)) - -(defun evil-normalize (beg end type &rest properties) - "Normalize BEG and END as TYPE with PROPERTIES. -Return a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list." - (apply #'evil-transform :normalize beg end type properties)) - -(defun evil-transform (transform beg end type &rest properties) - "Apply TRANSFORM on BEG and END with PROPERTIES. -Return a list (BEG END TYPE PROPERTIES ...), where the tail -may contain a property list. If TRANSFORM is undefined, -return positions unchanged." - (let* ((type (or type (evil-type properties))) - (transform (when (and type transform) - (evil-type-property type transform)))) - (if transform - (apply transform beg end properties) - (apply #'evil-range beg end type properties)))) - -(defun evil-describe (beg end type &rest properties) - "Return description of BEG and END with PROPERTIES. -If no description is available, return the empty string." - (let* ((type (or type (evil-type properties))) - (properties (plist-put properties :type type)) - (describe (evil-type-property type :string))) - (or (when describe - (apply describe beg end properties)) - ""))) - -;;; Ranges - -(defun evil-range (beg end &optional type &rest properties) - "Return a list (BEG END [TYPE] PROPERTIES...). -BEG and END are buffer positions (numbers or markers), -TYPE is a type as per `evil-type-p', and PROPERTIES is -a property list." - (let ((beg (evil-normalize-position beg)) - (end (evil-normalize-position end))) - (when (and (numberp beg) (numberp end)) - (evil-sort beg end) - (nconc (list beg end) - (when (evil-type-p type) (list type)) - properties)))) - -(defun evil-range-p (object) - "Whether OBJECT is a range." - (and (listp object) - (numberp (nth 0 object)) - (numberp (nth 1 object)))) - -(defun evil-range-beginning (range) - "Return beginning of RANGE." - (when (evil-range-p range) - (let ((beg (evil-normalize-position (nth 0 range))) - (end (evil-normalize-position (nth 1 range)))) - (min beg end)))) - -(defun evil-range-end (range) - "Return end of RANGE." - (when (evil-range-p range) - (let ((beg (evil-normalize-position (nth 0 range))) - (end (evil-normalize-position (nth 1 range)))) - (max beg end)))) - -(defun evil-range-properties (range) - "Return properties of RANGE." - (when (evil-range-p range) - (nthcdr (if (evil-type range) 3 2) range))) - -(defalias 'evil-copy-range #'copy-sequence - "Return a copy of RANGE.") - -(defun evil-set-range (range &optional beg end type &rest properties) - "Set RANGE to have beginning BEG and end END. -The TYPE and additional PROPERTIES may also be specified. -If an argument is nil, it's not used; the previous value is retained. -See also `evil-set-range-beginning', `evil-set-range-end', -`evil-set-range-type' and `evil-set-range-properties'." - (when (evil-range-p range) - (let ((beg (or (evil-normalize-position beg) - (evil-range-beginning range))) - (end (or (evil-normalize-position end) - (evil-range-end range))) - (type (or type (evil-type range))) - (plist (evil-range-properties range))) - (evil-sort beg end) - (setq plist (evil-concat-plists plist properties)) - (evil-set-range-beginning range beg) - (evil-set-range-end range end) - (evil-set-range-type range type) - (evil-set-range-properties range plist) - range))) - -(defun evil-set-range-beginning (range beg &optional copy) - "Set RANGE's beginning to BEG. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (setcar range beg) - range) - -(defun evil-set-range-end (range end &optional copy) - "Set RANGE's end to END. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (setcar (cdr range) end) - range) - -(defun evil-set-range-type (range type &optional copy) - "Set RANGE's type to TYPE. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (if type - (setcdr (cdr range) - (cons type (evil-range-properties range))) - (setcdr (cdr range) (evil-range-properties range))) - range) - -(defun evil-set-range-properties (range properties &optional copy) - "Set RANGE's properties to PROPERTIES. -If COPY is non-nil, return a copy of RANGE." - (when copy - (setq range (evil-copy-range range))) - (setcdr (if (evil-type range) (cddr range) (cdr range)) properties) - range) - -(defun evil-range-union (range1 range2 &optional type) - "Return the union of the ranges RANGE1 and RANGE2. -If the ranges have conflicting types, use RANGE1's type. -This can be overridden with TYPE." - (when (and (evil-range-p range1) - (evil-range-p range2)) - (evil-range (min (evil-range-beginning range1) - (evil-range-beginning range2)) - (max (evil-range-end range1) - (evil-range-end range2)) - (or type - (evil-type range1) - (evil-type range2))))) - -(defun evil-subrange-p (range1 range2) - "Whether RANGE1 is contained within RANGE2." - (and (evil-range-p range1) - (evil-range-p range2) - (<= (evil-range-beginning range2) - (evil-range-beginning range1)) - (>= (evil-range-end range2) - (evil-range-end range1)))) - -(defun evil-select-inner-object (thing beg end type &optional count line) - "Return an inner text object range of COUNT objects. -If COUNT is positive, return objects following point; if COUNT is -negative, return objects preceding point. If one is unspecified, -the other is used with a negative argument. THING is a symbol -understood by `thing-at-point'. BEG, END and TYPE specify the -current selection. If LINE is non-nil, the text object should be -linewise, otherwise it is character wise." - (let* ((count (or count 1)) - (bnd (or (let ((b (bounds-of-thing-at-point thing))) - (and b (< (point) (cdr b)) b)) - (evil-bounds-of-not-thing-at-point thing) - (cons (point-min) (point-max))))) - ;; check if current object is selected - (when (or (not beg) (not end) - (> beg (car bnd)) - (< end (cdr bnd)) - (and (eq type 'inclusive) - (= (1+ beg) end))) ; empty region does not count - (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd))) - (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd))) - (setq count (if (> count 0) (1- count) (1+ count)))) - (goto-char (if (< count 0) beg end)) - (evil-forward-nearest count - #'(lambda (cnt) (forward-thing thing cnt)) - #'(lambda (cnt) (evil-forward-not-thing thing cnt))) - (evil-range (if (>= count 0) beg (point)) - (if (< count 0) end (point)) - (if line 'line type) - :expanded t))) - -(defun evil-select-inner-restricted-object (thing beg end type &optional count line) - "Return an inner text object range of COUNT objects. -Selection is restricted to the current line, unless it is empty. -If COUNT is positive, return objects following point; if COUNT is -negative, return objects preceding point. If one is unspecified, -the other is used with a negative argument. THING is a symbol -understood by `thing-at-point'. BEG, END and TYPE specify the -current selection. If LINE is non-nil, the text object should be -linewise, otherwise it is character wise." - (save-restriction - (let ((start (line-beginning-position)) - (end (line-end-position))) - (unless (= start end) - (narrow-to-region start end))) - (evil-select-inner-object thing beg end type count line))) - -(defun evil-select-an-object (thing beg end type count &optional line) - "Return an outer text object range of COUNT objects. -If COUNT is positive, return objects following point; if COUNT is -negative, return objects preceding point. If one is unspecified, -the other is used with a negative argument. THING is a symbol -understood by thing-at-point. BEG, END and TYPE specify the -current selection. If LINE is non-nil, the text object should be -linewise, otherwise it is character wise." - (let* ((dir (if (> (or count 1) 0) +1 -1)) - (count (abs (or count 1))) - (objbnd (let ((b (bounds-of-thing-at-point thing))) - (and b (< (point) (cdr b)) b))) - (bnd (or objbnd - (evil-bounds-of-not-thing-at-point thing) - (cons (point-min) (point-max)))) - addcurrent other) - ;; check if current object is not selected - (when (or (not beg) (not end) - (> beg (car bnd)) - (< end (cdr bnd)) - (and (eq type 'inclusive) - (= (1+ beg) end))) ; empty region does not count - ;; if not, enlarge selection - (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd))) - (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd))) - (if objbnd (setq addcurrent t))) - ;; make other and (point) reflect the selection - (cond - ((> dir 0) (goto-char end) (setq other beg)) - (t (goto-char beg) (setq other end))) - (cond - ;; do nothing more than only current is selected - ((not (and (= beg (car bnd)) (= end (cdr bnd))))) - ;; current match is thing, add whitespace - (objbnd - (let ((wsend (evil-with-restriction - ;; restrict to current line if we do non-line selection - (unless line (line-beginning-position)) - (unless line (line-end-position)) - (evil-bounds-of-not-thing-at-point thing dir)))) - (cond - (wsend - ;; add whitespace at end - (goto-char wsend) - (setq addcurrent t)) - (t - ;; no whitespace at end, try beginning - (save-excursion - (goto-char other) - (setq wsend - (evil-with-restriction - ;; restrict to current line if we do non-line selection - (unless line - (if (member thing '(evil-word evil-WORD)) - (save-excursion (back-to-indentation) (point)) - (line-beginning-position))) - (unless line (line-end-position)) - (evil-bounds-of-not-thing-at-point thing (- dir)))) - (when wsend (setq other wsend addcurrent t))))))) - ;; current match is whitespace, add thing - (t - (forward-thing thing dir) - (setq addcurrent t))) - ;; possibly count current object as selection - (if addcurrent (setq count (1- count))) - ;; move - (dotimes (_ count) - (let ((wsend (evil-bounds-of-not-thing-at-point thing dir))) - (if (and wsend (/= wsend (point))) - ;; start with whitespace - (forward-thing thing dir) - ;; start with thing - (forward-thing thing dir) - (setq wsend (evil-bounds-of-not-thing-at-point thing dir)) - (when wsend (goto-char wsend))))) - ;; return range - (evil-range (if (> dir 0) other (point)) - (if (< dir 0) other (point)) - (if line 'line type) - :expanded t))) - -(defun evil-select-a-restricted-object (thing beg end type &optional count line) - "Return an outer text object range of COUNT objects. -Selection is restricted to the current line, unless it is empty. -If COUNT is positive, return objects following point; if COUNT is -negative, return objects preceding point. If one is unspecified, -the other is used with a negative argument. THING is a symbol -understood by thing-at-point. BEG, END and TYPE specify the -current selection. If LINE is non-nil, the text object should be -linewise, otherwise it is character wise." - (save-restriction - (let ((start (line-beginning-position)) - (end (line-end-position))) - (when (/= start end) - (narrow-to-region start end))) - (evil-select-an-object thing beg end type count line))) - -(defun evil--get-block-range (op cl selection-type) - "Return the exclusive range of a visual selection. -OP and CL are pairs of buffer positions for the opening and -closing delimiter of a range. SELECTION-TYPE is the desired type -of selection. It is a symbol that determines which parts of the -block are selected. If it is `inclusive' or t the returned range -is \(cons (car OP) (cdr CL)). If it is `exclusive' or nil the -returned range is (cons (cdr OP) (car CL)). If it is -`exclusive-line' the returned range will skip whitespace at the -end of the line of OP and at the beginning of the line of CL." - (cond - ((memq selection-type '(inclusive t)) (cons (car op) (cdr cl))) - ((memq selection-type '(exclusive nil)) (cons (cdr op) (car cl))) - ((eq selection-type 'exclusive-line) - (let ((beg (cdr op)) - (end (car cl))) - (save-excursion - (goto-char beg) - (when (and (eolp) (not (eobp))) - (setq beg (line-beginning-position 2))) - (goto-char end) - (skip-chars-backward " \t") - (when (bolp) - (setq end (point)) - (goto-char beg) - (when (and (not (bolp)) (< beg end)) - (setq end (1- end))))) - (cons beg end))) - (t (user-error "Unknown selection-type `%s'" selection-type)))) - -(defun evil-select-block (thing beg end type count - &optional - selection-type - countcurrent - fixedscan) - "Return a range (BEG END) of COUNT delimited text objects. -BEG END TYPE are the currently selected (visual) range. The -delimited object must be given by THING-up function (see -`evil-up-block'). - -SELECTION-TYPE is symbol that determines which parts of the block -are selected. If it is `inclusive' or t OPEN and CLOSE are -included in the range. If it is `exclusive' or nil the delimiters -are not contained. If it is `exclusive-line' the delimiters are -not included as well as adjacent whitespace until the beginning -of the next line or the end of the previous line. If the -resulting selection consists of complete lines only and visual -state is not active, the returned selection is linewise. - -If COUNTCURRENT is non-nil an objected is counted if the current -selection matches that object exactly. - -Usually scanning for the surrounding block starts at (1+ beg) -and (1- end). If this might fail due to the behavior of THING -then FIXEDSCAN can be set to t. In this case the scan starts at -BEG and END. One example where this might fail is if BEG and END -are the delimiters of a string or comment." - (save-excursion - (save-match-data - (let* ((orig-beg beg) - (orig-end end) - (beg (or beg (point))) - (end (or end (point))) - (count (abs (or count 1))) - op cl op-end cl-end) - ;; We always assume at least one selected character. - (if (= beg end) (setq end (1+ end))) - ;; We scan twice: starting at (1+ beg) forward and at (1- end) - ;; backward. The resulting selection is the smaller one. - (goto-char (if fixedscan beg (1+ beg))) - (when (and (zerop (funcall thing +1)) (match-beginning 0)) - (setq cl (cons (match-beginning 0) (match-end 0))) - (goto-char (car cl)) - (when (and (zerop (funcall thing -1)) (match-beginning 0)) - (setq op (cons (match-beginning 0) (match-end 0))))) - ;; start scanning from end - (goto-char (if fixedscan end (1- end))) - (when (and (zerop (funcall thing -1)) (match-beginning 0)) - (setq op-end (cons (match-beginning 0) (match-end 0))) - (goto-char (cdr op-end)) - (when (and (zerop (funcall thing +1)) (match-beginning 0)) - (setq cl-end (cons (match-beginning 0) (match-end 0))))) - ;; Bug #607: use the tightest selection that contains the - ;; original selection. If non selection contains the original, - ;; use the larger one. - (cond - ((and (not op) (not cl-end)) - (error "No surrounding delimiters found")) - ((or (not op) ; first not found - (and cl-end ; second found - (>= (car op-end) (car op)) ; second smaller - (<= (cdr cl-end) (cdr cl)) - (<= (car op-end) beg) ; second contains orig - (>= (cdr cl-end) end))) - (setq op op-end cl cl-end))) - (setq op-end op cl-end cl) ; store copy - ;; if the current selection contains the surrounding - ;; delimiters, they do not count as new selection - (let ((cnt (if (and orig-beg orig-end (not countcurrent)) - (let ((sel (evil--get-block-range op cl selection-type))) - (if (and (<= orig-beg (car sel)) - (>= orig-end (cdr sel))) - count - (1- count))) - (1- count)))) - ;; starting from the innermost surrounding delimiters - ;; increase selection - (when (> cnt 0) - (setq op (progn - (goto-char (car op-end)) - (funcall thing (- cnt)) - (if (match-beginning 0) - (cons (match-beginning 0) (match-end 0)) - op)) - cl (progn - (goto-char (cdr cl-end)) - (funcall thing cnt) - (if (match-beginning 0) - (cons (match-beginning 0) (match-end 0)) - cl))))) - (let ((sel (evil--get-block-range op cl selection-type))) - (setq op (car sel) - cl (cdr sel))) - (cond - ((and (equal op orig-beg) (equal cl orig-end) - (or (not countcurrent) (/= count 1))) - (error "No surrounding delimiters found")) - ((save-excursion - (and (not (evil-visual-state-p)) - (eq type 'inclusive) - (progn (goto-char op) (bolp)) - (progn (goto-char cl) (bolp)))) - (evil-range op cl 'line :expanded t)) - (t (evil-range op cl type :expanded t))))))) - -(defun evil-select-paren (open close beg end type count &optional inclusive) - "Return a range (BEG END) of COUNT delimited text objects. -OPEN and CLOSE specify the opening and closing delimiter, -respectively. BEG END TYPE are the currently selected (visual) -range. If INCLUSIVE is non-nil, OPEN and CLOSE are included in -the range; otherwise they are excluded. - -If you aren't inside a pair of the opening and closing delimiters, -it jumps you inside the next one. If there isn't one, it errors. - -The types of OPEN and CLOSE specify which kind of THING is used -for parsing with `evil-select-block'. If OPEN and CLOSE are -characters `evil-up-paren' is used. Otherwise OPEN and CLOSE -must be regular expressions and `evil-up-block' is used. - -If the selection is exclusive, whitespace at the end or at the -beginning of the selection until the end-of-line or beginning-of-line -is ignored." - (condition-case nil - (progn - ;; we need special linewise exclusive selection - (unless inclusive (setq inclusive 'exclusive-line)) - (cond - ((and (characterp open) (characterp close)) - (let ((thing #'(lambda (&optional cnt) - (evil-up-paren open close cnt))) - (bnd (or (bounds-of-thing-at-point 'evil-string) - (bounds-of-thing-at-point 'evil-comment) - ;; If point is at the opening quote of a string, - ;; this must be handled as if point is within the - ;; string, i.e. the selection must be extended - ;; around the string. Otherwise - ;; `evil-select-block' might do the wrong thing - ;; because it accidentally moves point inside the - ;; string (for inclusive selection) when looking - ;; for the current surrounding block. (re #364) - (and (= (point) (or beg (point))) - (save-excursion - (goto-char (1+ (or beg (point)))) - (or (bounds-of-thing-at-point 'evil-string) - (bounds-of-thing-at-point 'evil-comment))))))) - (if (not bnd) - (evil-select-block thing beg end type count inclusive) - (or (evil-with-restriction (car bnd) (cdr bnd) - (ignore-errors - (evil-select-block thing beg end type count inclusive))) - (save-excursion - (setq beg (or beg (point)) - end (or end (point))) - (goto-char (car bnd)) - (let ((extbeg (min beg (car bnd))) - (extend (max end (cdr bnd)))) - (evil-select-block thing - extbeg extend - type - count - inclusive - (or (< extbeg beg) (> extend end)) - t))))))) - (t - (evil-select-block #'(lambda (&optional cnt) - (evil-up-block open close cnt)) - beg end type count inclusive)))) - (error ; we aren't in the parens, so find next instance - (save-match-data - (goto-char (or (if (and count (> 0 count)) end beg) - (point))) - (let ((re (if (characterp open) (regexp-quote (string open)) open))) - (if (and (not (looking-at-p re)) - (re-search-forward re nil t count)) - (progn - (goto-char (match-beginning 0)) - (let* ((mbeg (match-beginning 0)) - (res (evil-select-paren open close mbeg mbeg - type nil inclusive))) - (if (< (car res) mbeg) - ;; this will error if the beginning of the found parens is before the target paren - ;; this prevents things such as on the line `prova ( verder "((testo)")`, - ;; the inputs `g2ci(` from putting your cursor inside the deleted `()` after `prova` - ;; without this, it would go to the second paren (the unbalanced first paren inside the quotes) - ;; and then do a change there, changing inside the whole paren after `prova` - (error "No surrounding delimiters found") - res))) - (error "No surrounding delimiters found"))))))) - -(defun evil-select-quote-thing (thing beg end _type count &optional inclusive) - "Selection THING as if it described a quoted object. -THING is typically either `evil-quote' or `evil-chars'. This -function is called from `evil-select-quote'." - (save-excursion - (let* ((count (or count 1)) - (dir (if (> count 0) 1 -1)) - (bnd (let ((b (bounds-of-thing-at-point thing))) - (and b (< (point) (cdr b)) b))) - addcurrent - wsboth) - (if inclusive (setq inclusive t) - (when (= (abs count) 2) - (setq count dir) - (setq inclusive 'quote-only)) - ;; never extend with exclusive selection - (setq beg nil end nil)) - ;; check if the previously selected range does not contain a - ;; string - (unless (and beg end - (save-excursion - (goto-char (if (> dir 0) beg end)) - (forward-thing thing dir) - (and (<= beg (point)) (< (point) end)))) - ;; if so forget the range - (setq beg nil end nil)) - ;; check if there is a current object, if not fetch one - (when (not bnd) - (unless (and (zerop (forward-thing thing dir)) - (setq bnd (bounds-of-thing-at-point thing))) - (error "No quoted string found")) - (if (> dir 0) - (setq end (point)) - (setq beg (point))) - (setq addcurrent t)) - ;; check if current object is not selected - (when (or (not beg) (not end) (> beg (car bnd)) (< end (cdr bnd))) - ;; if not, enlarge selection - (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd))) - (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd))) - (setq addcurrent t wsboth t)) - ;; maybe count current element - (when addcurrent - (setq count (if (> dir 0) (1- count) (1+ count)))) - ;; enlarge selection - (goto-char (if (> dir 0) end beg)) - (when (and (not addcurrent) - (= count (forward-thing thing count))) - (error "No quoted string found")) - (if (> dir 0) (setq end (point)) (setq beg (point))) - ;; add whitespace - (cond - ((not inclusive) (setq beg (1+ beg) end (1- end))) - ((not (eq inclusive 'quote-only)) - ;; try to add whitespace in forward direction - (goto-char (if (> dir 0) end beg)) - (if (setq bnd (bounds-of-thing-at-point 'evil-space)) - (if (> dir 0) (setq end (cdr bnd)) (setq beg (car bnd))) - ;; if not found try backward direction - (goto-char (if (> dir 0) beg end)) - (if (and wsboth (setq bnd (bounds-of-thing-at-point 'evil-space))) - (if (> dir 0) (setq beg (car bnd)) (setq end (cdr bnd))))))) - (evil-range beg end - ;; HACK: fixes #583 - ;; When not in visual state, an empty range is - ;; possible. However, this cannot be achieved with - ;; inclusive ranges, hence we use exclusive ranges - ;; in this case. In visual state the range must be - ;; inclusive because otherwise the selection would - ;; be wrong. - (if (evil-visual-state-p) 'inclusive 'exclusive) - :expanded t)))) - -(defun evil-select-quote (quote beg end type count &optional inclusive) - "Return a range (BEG END) of COUNT quoted text objects. -QUOTE specifies the quotation delimiter. BEG END TYPE are the -currently selected (visual) range. - -If INCLUSIVE is nil the previous selection is ignore. If there is -quoted string at point this object will be selected, otherwise -the following (if (> COUNT 0)) or preceeding object (if (< COUNT -0)) is selected. If (/= (abs COUNT) 2) the delimiting quotes are not -contained in the range, otherwise they are contained in the range. - -If INCLUSIVE is non-nil the selection depends on the previous -selection. If the currently selection contains at least one -character that is contained in a quoted string then the selection -is extended, otherwise it is thrown away. If there is a -non-selected object at point then this object is added to the -selection. Otherwise the selection is extended to the -following (if (> COUNT 0)) or preceeding object (if (< COUNT -0)). Any whitespace following (or preceeding if (< COUNT 0)) the -new selection is added to the selection. If no such whitespace -exists and the selection contains only one quoted string then the -preceeding (or following) whitespace is added to the range. " - (let ((evil-forward-quote-char quote)) - (or (let ((bnd (or (bounds-of-thing-at-point 'evil-comment) - (bounds-of-thing-at-point 'evil-string)))) - (when (and bnd (< (point) (cdr bnd)) - (/= (char-after (car bnd)) quote) - (/= (char-before (cdr bnd)) quote)) - (evil-with-restriction (car bnd) (cdr bnd) - (ignore-errors (evil-select-quote-thing - 'evil-quote-simple - beg end type - count - inclusive))))) - (let ((evil-forward-quote-char quote)) - (evil-select-quote-thing 'evil-quote - beg end type - count - inclusive))))) - -(defun evil-select-xml-tag (beg end type &optional count inclusive) - "Return a range (BEG END) of COUNT matching XML tags. -If INCLUSIVE is non-nil, the tags themselves are included -from the range." - (cond - ((and (not inclusive) (= (abs (or count 1)) 1)) - (let ((rng (evil-select-block #'evil-up-xml-tag beg end type count nil t))) - (if (or (and beg (= beg (evil-range-beginning rng)) - end (= end (evil-range-end rng)))) - (evil-select-block #'evil-up-xml-tag beg end type count t) - rng))) - (t - (evil-select-block #'evil-up-xml-tag beg end type count inclusive)))) - -(defun evil-expand-range (range &optional copy) - "Expand RANGE according to its type. -Return a new range if COPY is non-nil." - (when copy - (setq range (evil-copy-range range))) - (unless (plist-get (evil-range-properties range) :expanded) - (setq range (evil-transform-range :expand range))) - range) - -(defun evil-contract-range (range &optional copy) - "Contract RANGE according to its type. -Return a new range if COPY is non-nil." - (evil-transform-range :contract range copy)) - -(defun evil-normalize-range (range &optional copy) - "Normalize RANGE according to its type. -Return a new range if COPY is non-nil." - (evil-transform-range :normalize range copy)) - -(defun evil-transform-range (transform range &optional copy) - "Apply TRANSFORM to RANGE according to its type. -Return a new range if COPY is non-nil." - (when copy - (setq range (evil-copy-range range))) - (when (evil-type range) - (apply #'evil-set-range range - (apply #'evil-transform transform range))) - range) - -(defun evil-describe-range (range) - "Return description of RANGE. -If no description is available, return the empty string." - (apply #'evil-describe range)) - -;;; Undo - -(defvar buffer-undo-tree) -(declare-function undo-tree-current "ext:undo-tree") -(declare-function undo-tree-node-next "ext:undo-tree") -(declare-function undo-tree-node-branch "ext:undo-tree") -(declare-function undo-tree-node-branch "ext:undo-tree") -(declare-function undo-tree-undo "ext:undo-tree") -(declare-function undo-tree-snip-node "ext:undo-tree") - -(defun evil-start-undo-step (&optional continue) - "Start a undo step. -All following buffer modifications are grouped together as a -single action. If CONTINUE is non-nil, preceding modifications -are included. The step is terminated with `evil-end-undo-step'." - (when (and (listp buffer-undo-list) - (not evil-in-single-undo)) - (if evil-undo-list-pointer - (evil-refresh-undo-step) - (unless (or continue (null (car-safe buffer-undo-list))) - (undo-boundary)) - (setq evil-undo-list-pointer (or buffer-undo-list t))))) - -(defun evil-end-undo-step (&optional continue) - "End a undo step started with `evil-start-undo-step'. -Adds an undo boundary unless CONTINUE is specified." - (when (and (listp buffer-undo-list) - evil-undo-list-pointer - (not evil-in-single-undo)) - (evil-refresh-undo-step) - (unless (or continue (null (car-safe buffer-undo-list))) - (undo-boundary)) - (setq evil-undo-list-pointer nil))) - -(defun evil-refresh-undo-step () - "Refresh `buffer-undo-list' entries for current undo step. -Undo boundaries until `evil-undo-list-pointer' are removed to -make the entries undoable as a single action. See -`evil-start-undo-step'." - (when evil-undo-list-pointer - (setq buffer-undo-list - (evil-filter-list #'null buffer-undo-list evil-undo-list-pointer)) - (setq evil-undo-list-pointer (or buffer-undo-list t)))) - -(defmacro evil-with-undo (&rest body) - "Execute BODY with enabled undo. -If undo is disabled in the current buffer, the undo information -is stored in `evil-temporary-undo' instead of `buffer-undo-list'." - (declare (indent defun) (debug t)) - (let ((undo-list (make-symbol "undo-list"))) - `(let ((,undo-list buffer-undo-list) - (evil-undo-system evil-undo-system)) - (when (eq ,undo-list t) (setq buffer-undo-list nil - evil-undo-system nil)) - (unwind-protect - (progn ,@body) - ;; ensure any new undo changes we've accumulated start with - ;; exactly one undo boundary marker, i.e. nil - (when (car-safe buffer-undo-list) (push nil buffer-undo-list)) - (if (eq ,undo-list t) - ;; undo is disabled, so store undo information in - ;; evil-temporary-undo - (setq evil-temporary-undo buffer-undo-list - buffer-undo-list t) - (setq evil-temporary-undo nil)))))) - -(defmacro evil-with-single-undo (&rest body) - "Execute BODY as a single undo step." - (declare (indent defun) (debug t)) - `(let (evil-undo-list-pointer) - (evil-with-undo - (evil-start-undo-step) - (unwind-protect - (let ((evil-in-single-undo t)) ,@body) - (evil-end-undo-step))))) - -(defun evil-undo-pop () - "Undo and forget the last buffer change. -If undo is disabled in the current buffer, use the information -in `evil-temporary-undo' instead." - (if (and (eq evil-undo-system 'undo-tree) - (not (eq buffer-undo-list t))) - (let (current) - (undo-tree-undo) - (setq current (undo-tree-current buffer-undo-tree) - current (nth (undo-tree-node-branch current) - (undo-tree-node-next current))) - ;; Remove only if leaf to not have to adjust child buffer positions - (unless (undo-tree-node-next current) (undo-tree-snip-node current))) - (let ((paste-undo (list nil)) - (undo-list (if (eq buffer-undo-list t) - evil-temporary-undo - buffer-undo-list))) - (when (or (not undo-list) (car undo-list)) - (user-error "Can't undo previous change")) - (while (and undo-list (null (car undo-list))) - (pop undo-list)) ; remove nil - (while (and undo-list (car undo-list)) - (push (pop undo-list) paste-undo)) - (let ((buffer-undo-list (nreverse paste-undo))) - (evil-save-echo-area - (undo))) - (if (eq buffer-undo-list t) - (setq evil-temporary-undo nil) - (setq buffer-undo-list undo-list))))) - -;;; Search -(defun evil-transform-regexp (regexp replacements-alist) - (replace-regexp-in-string - "\\\\+[^\\\\]" - #'(lambda (txt) - (let* ((b (match-beginning 0)) - (e (match-end 0)) - (ch (aref txt (1- e))) - (repl (assoc ch replacements-alist))) - (if (and repl (zerop (mod (length txt) 2))) - (concat (substring txt b (- e 2)) - (cdr repl)) - txt))) - regexp nil t)) - -(defun evil-transform-magic (str magic quote transform &optional _start) - "Transform STR with magic characters. -MAGIC is a regexp that matches all potential magic -characters. Each occurence of CHAR as magic character within str -is replaced by the result of calling the associated TRANSFORM -function. TRANSFORM is a function taking two arguments, the -character to be transformed and the rest of string after the -character. The function should return a triple (REPLACEMENT REST -. STOP) where REPLACEMENT is the replacement and REST is the rest -of the string that has not been transformed. If STOP is non-nil -then the substitution stops immediately. The replacement starts -at position START, everything before that position is returned -literally. The result is a pair (RESULT . REST). RESULT is a -list containing the transformed parts in order. If two -subsequents parts are both strings, they are concatenated. REST -is the untransformed rest string (usually \"\" but may be more if -TRANSFORM stopped the substitution). Which characters are -considered as magic characters (i.e. the transformation happens -if the character is NOT preceeded by a backslash) is determined -by `evil-magic'. The special tokens \\v, \\V, \\m and \\M have -always a special meaning (like in Vim) and should not be -contained in TRANSFORMS, otherwise their meaning is overwritten. - -The parameter QUOTE is a quoting function applied to literal -transformations, usually `regexp-quote' or `replace-quote'." - (save-match-data - (let ((regexp (concat "\\(?:\\`\\|[^\\]\\)\\(\\\\\\(?:\\(" magic "\\)\\|\\(.\\)\\)\\|\\(" magic "\\)\\)")) - (magic-chars (evil-get-magic evil-magic)) - (evil-magic evil-magic) - (quote (or quote #'identity)) - result stop) - (while (and (not stop) str (string-match regexp str)) - (unless (zerop (match-beginning 1)) - (push (substring str 0 (match-beginning 1)) result)) - (let ((char (or (match-string 2 str) - (match-string 3 str) - (match-string 4 str))) - (rest (substring str (match-end 0)))) - (cond - ((match-beginning 4) - ;; magic character without backslash - (if (string-match magic-chars char) - ;; magic, do transform - (let ((trans (funcall transform (aref char 0) rest))) - (push (car trans) result) - (setq str (cadr trans) stop (nthcdr 2 trans))) - ;; non-magic, literal transformation - (push (funcall quote char) result) - (setq str rest))) - ((match-beginning 2) - ;; magic character with backslash - (if (not (string-match magic-chars char)) - ;; non-magic, do transform - (let ((trans (funcall transform (aref char 0) rest))) - (push (car trans) result) - (setq str (cadr trans) stop (nthcdr 2 trans))) - ;; magic, literal transformation - (push (funcall quote char) result) - (setq str rest))) - ((memq (aref char 0) '(?m ?M ?v ?V)) - (setq evil-magic (cdr (assq (aref char 0) - '((?m . t) - (?M . nil) - (?v . very-magic) - (?V . very-nomagic))))) - (setq magic-chars (evil-get-magic evil-magic)) - (setq str rest)) - (t - ;; non-magic char with backslash, literal transformation - (push (funcall quote char) result) - (setq str rest))))) - (cond - ((and str (not stop)) - (push str result) - (setq str "")) - ((not str) - (setq str ""))) - ;; concatenate subsequent strings - ;; note that result is in reverse order - (let (repl) - (while result - (cond - ((and (stringp (car result)) - (zerop (length (car result)))) - (pop result)) - ((and (stringp (car result)) - (stringp (cadr result))) - (setq result (cons (concat (cadr result) - (car result)) - (nthcdr 2 result)))) - (t - (push (pop result) repl)))) - (cons repl str))))) - -(defconst evil-vim-regexp-replacements - '((?n . "\n") (?r . "\r") - (?t . "\t") (?b . "\b") - (?s . "[[:space:]]") (?S . "[^[:space:]]") - (?d . "[[:digit:]]") (?D . "[^[:digit:]]") - (?x . "[[:xdigit:]]") (?X . "[^[:xdigit:]]") - (?o . "[0-7]") (?O . "[^0-7]") - (?a . "[[:alpha:]]") (?A . "[^[:alpha:]]") - (?l . "[a-z]") (?L . "[^a-z]") - (?u . "[A-Z]") (?U . "[^A-Z]") - (?y . "\\s") (?Y . "\\S") - (?\( . "\\(") (?\) . "\\)") - (?{ . "\\{") (?} . "\\}") - (?\[ . "[") (?\] . "]") - (?< . "\\<") (?> . "\\>") - (?_ . "\\_") - (?* . "*") (?+ . "+") - (?? . "?") (?= . "?") - (?. . ".") - (?` . "`") (?^ . "^") - (?$ . "$") (?| . "\\|"))) - -(defconst evil-regexp-magic "[][(){}<>_dDsSxXoOaAlLuUwWyY.*+?=^$`|nrtb0-9]") - -(defun evil-transform-vim-style-regexp (regexp) - "Transform vim-style backslash codes to Emacs regexp. -This includes the backslash codes \\d, \\D, \\s, \\S, \\x, \\X, -\\o, \\O, \\a, \\A, \\l, \\L, \\u, \\U and \\w, \\W. The new -codes \\y and \\Y can be used instead of the Emacs code \\s and -\\S which have a different meaning in Vim-style." - (car - (car - (evil-transform-magic - regexp evil-regexp-magic #'regexp-quote - #'(lambda (char rest) - (let ((repl (assoc char evil-vim-regexp-replacements))) - (if repl - (list (cdr repl) rest) - (list (concat "\\" (char-to-string char)) rest)))))))) - -;;; Substitute - -(defun evil-downcase-first (str) - "Return STR with the first letter downcased." - (if (zerop (length str)) - str - (concat (downcase (substring str 0 1)) - (substring str 1)))) - -(defun evil-upcase-first (str) - "Return STR with the first letter upcased." - (if (zerop (length str)) - str - (concat (upcase (substring str 0 1)) - (substring str 1)))) - -(defun evil-get-magic (magic) - "Return a regexp matching the magic characters according to MAGIC. -Depending on the value of MAGIC the following characters are -considered magic. - t [][{}*+?.&~$^ - nil [][{}*+?$^ - `very-magic' not 0-9A-Za-z_ - `very-nomagic' empty." - (cond - ((eq magic t) "[][}{*+?.&~$^]") - ((eq magic 'very-magic) "[^0-9A-Za-z_]") - ((eq magic 'very-nomagic) "\\\\") - (t "[][}{*+?$^]"))) - -;; TODO: support magic characters in patterns -(defconst evil-replacement-magic "[eElLuU0-9&#,rnbt=]" - "All magic characters in a replacement string") - -(defun evil-compile-subreplacement (to &optional start) - "Convert a regexp replacement TO to Lisp from START until \\e or \\E. -Return a pair (RESULT . REST). RESULT is a list suitable for -`perform-replace' if necessary, the original string if not. -REST is the unparsed remainder of TO." - (let ((result - (evil-transform-magic - to evil-replacement-magic #'replace-quote - #'(lambda (char rest) - (cond - ((eq char ?#) - (list '(number-to-string replace-count) rest)) - ((eq char ?r) (list "\r" rest)) - ((eq char ?n) (list "\n" rest)) - ((eq char ?b) (list "\b" rest)) - ((eq char ?t) (list "\t" rest)) - ((memq char '(?e ?E)) - `("" ,rest . t)) - ((memq char '(?l ?L ?u ?U)) - (let ((result (evil-compile-subreplacement rest)) - (func (cdr (assoc char - '((?l . evil-downcase-first) - (?L . downcase) - (?u . evil-upcase-first) - (?U . upcase)))))) - (list `(,func - (replace-quote - (evil-match-substitute-replacement - ,(car result) - (not case-replace)))) - (cdr result)))) - ((eq char ?=) - (when (or (zerop (length rest)) - (not (eq (aref rest 0) ?@))) - (user-error "Expected @ after \\=")) - (when (< (length rest) 2) - (user-error "Expected register after \\=@")) - (list (evil-get-register (aref rest 1)) - (substring rest 2))) - ((eq char ?,) - (let* ((obj (read-from-string rest)) - (result `(replace-quote ,(car obj))) - (end - ;; swallow a space after a symbol - (if (and (or (symbolp (car obj)) - ;; swallow a space after 'foo, - ;; but not after (quote foo) - (and (eq (car-safe (car obj)) 'quote) - (not (= ?\( (aref rest 0))))) - (eq (string-match " " rest (cdr obj)) - (cdr obj))) - (1+ (cdr obj)) - (cdr obj)))) - (list result (substring rest end)))) - ((eq char ?0) - (list "\\&" rest)) - (t - (list (concat "\\" (char-to-string char)) rest)))) - start))) - (let ((rest (cdr result)) - (result (car result))) - (replace-match-string-symbols result) - (cons (if (cdr result) - (cons 'concat result) - (or (car result) "")) - rest)))) - -(defun evil-compile-replacement (to) - "Maybe convert a regexp replacement TO to Lisp. -Return a list suitable for `perform-replace' if necessary, the -original string if not. Currently the following magic characters -in replacements are supported: 0-9&#lLuUrnbt, -The magic character , (comma) start an Emacs-lisp expression." - (when (stringp to) - (save-match-data - (cons 'replace-eval-replacement - (car (evil-compile-subreplacement to)))))) - -(defun evil-match-substitute-replacement (replacement &optional fixedcase string) - "Return REPLACEMENT as it will be inserted by `evil-replace-match'. -If REPLACEMENT is an expression it will be evaluated to compute the -replacement text first." - (match-substitute-replacement - (if (stringp replacement) - replacement - (funcall (car replacement) - (cdr replacement) - 0)) - fixedcase nil string)) - -;;; Alignment - -(defun evil-justify-lines (beg end justify position) - "Justify all lines in a range. -BEG and END specify the range of those lines to be -justified. JUSTIFY is either `left', `right' or `center' according -to the justification type. POSITION is the maximal text width for -right and center justification or the column at which the lines -should be left-aligned for left justification." - (let ((fill-column position) - adaptive-fill-mode fill-prefix) - (evil-with-restriction - (save-excursion (goto-char beg) (line-beginning-position)) - (save-excursion (goto-char end) (line-end-position (if (bolp) 0 1))) - (goto-char (point-min)) - (while (progn - (if (eq justify 'left) - (indent-line-to position) - (when (re-search-forward "^[[:space:]]*" nil t) - (delete-region (match-beginning 0) - (match-end 0))) - (justify-current-line justify nil t)) - (and (zerop (forward-line)) (bolp)))) - (goto-char (point-min)) - (back-to-indentation)))) - -;;; View helper - -(defvar-local evil-list-view-select-action nil) - -(define-derived-mode evil-list-view-mode tabulated-list-mode - "Evil List View" - (tabulated-list-init-header) - (tabulated-list-print)) - -(defun evil-list-view-goto-entry () - (interactive) - (when (and evil-list-view-select-action - (not (eobp))) - (let* ((line (line-number-at-pos (point))) - (entry (elt tabulated-list-entries (1- line)))) - (funcall evil-list-view-select-action (nth 1 entry))))) - -(defun evil-list-view-quit () - (interactive) - (quit-window 'kill)) - -(define-key evil-list-view-mode-map (kbd "q") #'evil-list-view-quit) -(define-key evil-list-view-mode-map [follow-link] nil) ;; allows mouse-1 to be activated -(define-key evil-list-view-mode-map [mouse-1] #'evil-list-view-goto-entry) -(define-key evil-list-view-mode-map [return] #'evil-list-view-goto-entry) - -(defmacro evil-with-view-list (&rest properties) - "Open a new list view buffer. -PROPERTIES is a property-list which supports the following properties: - -:name (required) The name of the buffer. -:mode-name (required) The name for the mode line. -:format (required) The value for `tabulated-list-format'. -:entries (required) The value for `tabulated-list-entries'. -:select-action (optional) A function for row selection. - It takes a single parameter, which is the - selected row's vector value that is - passed into `:entries'." - (declare (indent defun) (debug t)) - `(let ((bufname (concat "*" ,(plist-get properties :name) "*")) - (inhibit-read-only t)) - (and (get-buffer bufname) - (kill-buffer bufname)) - (let ((buf (get-buffer-create bufname))) - (with-current-buffer buf - (setq tabulated-list-format ,(plist-get properties :format)) - (setq tabulated-list-entries ,(plist-get properties :entries)) - (setq evil-list-view-select-action ,(plist-get properties :select-action)) - (evil-list-view-mode) - (setq mode-name ,(plist-get properties :mode-name)) - (evil-motion-state)) - (switch-to-buffer-other-window buf)))) - -(provide 'evil-common) - -;;; evil-common.el ends here diff --git a/.config/emacs/lisp/evil/evil-core.el b/.config/emacs/lisp/evil/evil-core.el deleted file mode 100644 index ae3f949..0000000 --- a/.config/emacs/lisp/evil/evil-core.el +++ /dev/null @@ -1,1322 +0,0 @@ -;;; evil-core.el --- Core functionality -*- lexical-binding: t -*- -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; Evil is defined as a globalized minor mode, enabled with the toggle -;; function `evil-mode'. This in turn enables `evil-local-mode' in -;; every buffer, which sets up the buffer's state. -;; -;; Each state has its own keymaps, and these keymaps have status as -;; "emulation keymaps" with priority over regular keymaps. Emacs -;; maintains the following keymap hierarchy (highest priority first): -;; -;; * Overriding keymaps/overlay keymaps... -;; * Emulation mode keymaps... -;; - Evil keymaps... -;; * Minor mode keymaps... -;; * Local keymap (`local-set-key') -;; * Global keymap (`global-set-key') -;; -;; Within this hierarchy, Evil arranges the keymaps for the current -;; state as shown below: -;; -;; * Intercept keymaps... -;; * Local state keymap -;; * Minor-mode keymaps... -;; * Auxiliary keymaps... -;; * Overriding keymaps... -;; * Global state keymap -;; * Keymaps for other states... -;; -;; These keymaps are listed in `evil-mode-map-alist', which is listed -;; in `emulation-mode-map-alist'. -;; -;; Most of the key bindings for a state are stored in its global -;; keymap, which has a name such as `evil-normal-state-map'. (See the -;; file evil-maps.el, which contains all the default key bindings.) A -;; state also has a local keymap (`evil-normal-state-local-map'), -;; which may contain user customizations for the current buffer. -;; Furthermore, any Emacs mode may be assigned state bindings of its -;; own by passing the mode's keymap to the function `evil-define-key' -;; or `evil-define-minor-mode-key'. The former uses a specific map to -;; define the key in while the latter associates the key with a -;; particular mode. These mode-specific bindings are ultimately stored -;; in so-called auxiliary and minor-mode keymaps respectively, which -;; are sandwiched between the local keymap and the global keymap. -;; Finally, the state may also activate the keymaps of other states -;; (e.g., Normal state inherits bindings from Motion state). -;; -;; For integration purposes, a regular Emacs keymap may be "elevated" -;; to emulation status by passing it to `evil-make-intercept-map' or -;; `evil-make-overriding-map'. An "intercept" keymap has priority over -;; all other Evil keymaps. (Evil uses this facility when debugging and -;; for handling the "ESC" key in the terminal.) More common is the -;; "overriding" keymap, which only has priority over the global state -;; keymap. (This is useful for adapting key-heavy modes such as Dired, -;; where all but a few keys should be left as-is and should not be -;; shadowed by Evil's default bindings.) -;; -;; States are defined with the macro `evil-define-state', which -;; creates a command for switching to the state. This command, -;; for example `evil-normal-state' for Normal state, performs -;; the following tasks: -;; -;; * Setting `evil-state' to the new state. -;; * Refreshing the keymaps in `evil-mode-map-alist'. -;; * Updating the mode line. -;; - Normal state depends on `evil-normal-state-tag'. -;; * Adjusting the cursor's appearance. -;; - Normal state depends on `evil-normal-state-cursor'. -;; * Displaying a message in the echo area. -;; - Normal state depends on `evil-normal-state-message'. -;; * Running hooks. -;; - Normal state runs `evil-normal-state-entry-hook' when -;; entering, and `evil-normal-state-exit-hook' when exiting. -;; -;; The various properties of a state can be accessed through their -;; respective variables, or by passing a keyword and the state's name -;; to the `evil-state-property' function. Evil defines the states -;; Normal state ("normal"), Insert state ("insert"), Visual state -;; ("visual"), Replace state ("replace"), Operator-Pending state -;; ("operator"), Motion state ("motion") and Emacs state ("emacs"). - -;;; Code: - -(require 'evil-common) - -(declare-function evil-emacs-state-p "evil-states") -(declare-function evil-ex-p "evil-ex") - -(define-minor-mode evil-local-mode - "Minor mode for setting up Evil in a single buffer." - :init-value nil - (if evil-local-mode - (progn - (cl-pushnew 'evil-mode-map-alist emulation-mode-map-alists) - (evil-initialize-local-keymaps) - (when (minibufferp) - (setq-local evil-default-state 'insert) - (setq-local evil-echo-state nil)) - (setq evil-input-method current-input-method) - (evil-initialize-state) - (add-hook 'input-method-activate-hook #'evil-activate-input-method t t) - (add-hook 'input-method-deactivate-hook #'evil-deactivate-input-method t t) - (add-hook 'activate-mark-hook 'evil-visual-activate-hook nil t) - ;; FIXME: Add these hooks buffer-locally and remove when disabling - (add-hook 'pre-command-hook 'evil-repeat-pre-hook) - (add-hook 'post-command-hook 'evil-repeat-post-hook)) - (evil-refresh-mode-line) - (remove-hook 'activate-mark-hook 'evil-visual-activate-hook t) - (remove-hook 'input-method-activate-hook #'evil-activate-input-method t) - (remove-hook 'input-method-deactivate-hook #'evil-deactivate-input-method t) - (activate-input-method evil-input-method) - (evil-change-state nil))) - -;; Make the variable permanent local. This is particular useful in -;; conjunction with nXhtml/mumamo because mumamo does not touch these -;; variables. -(put 'evil-local-mode 'permanent-local t) - -(defun turn-on-evil-mode () - "Turn on Evil in the current buffer." - (interactive) - (evil-local-mode)) - -(defun turn-off-evil-mode () - "Turn off Evil in the current buffer." - (interactive) - (evil-local-mode -1)) - -;; The function `evil-initialize' should only be used to initialize -;; `evil-local-mode' from the globalized minor-mode `evil-mode'. It is -;; called whenever evil is enabled in a buffer for the first time or -;; when evil is active and the major-mode of the buffer changes. -(defun evil-initialize () - "Enable Evil in the current buffer, if appropriate. -To enable Evil globally, do (evil-mode)." - (if evil-local-mode - ;; Set Evil state according to new major-mode - (evil-initialize-state) - (or (and (minibufferp) (not evil-want-minibuffer)) - (evil-disabled-buffer-p) - (evil-local-mode)))) - -(defalias 'evil--fundamental-mode #'fundamental-mode) - -(defvar evil--advices ()) - -;;;###autoload (autoload 'evil-mode "evil" nil t) -(define-globalized-minor-mode evil-mode evil-local-mode evil-initialize - :group 'evil) - -;; `define-globalized-minor-mode' supports a BODY argument but only since -;; GNU Emacs 27.1, so resort to this ugly advice in the mean time. -(define-advice evil-mode (:after (&optional _arg) body) - ;; Hooks used to not run in Fundamental buffers (bug#23827), so - ;; other measures are necessary to initialize Evil there. When Evil - ;; is enabled globally, the default value of `major-mode' is set to - ;; the `evil--fundamental-mode' alias, sidestepping the restriction. - (if evil-mode - (progn - (and (eval-when-compile (version< emacs-version "26.1")) - (eq (default-value 'major-mode) 'fundamental-mode) - (setq-default major-mode #'evil--fundamental-mode)) - (dolist (advice evil--advices) (apply #'advice-add advice)) - (with-no-warnings (evil-esc-mode 1))) - (when (eq (default-value 'major-mode) #'evil--fundamental-mode) - (setq-default major-mode 'fundamental-mode)) - (pcase-dolist (`(,funname ,_where ,adfun) evil--advices) - (advice-remove funname adfun)) - (with-no-warnings (evil-esc-mode -1)))) - -(defun evil--advice-add (&rest args) - "Like `advice-add' for advices active only in `evil-mode'." - (when evil-mode (apply #'advice-add args)) - (cl-pushnew args evil--advices :test #'equal)) - -(defun evil-change-state (state &optional message) - "Change the state to STATE. -If STATE is nil, disable all states." - (let ((func (evil-state-property (or state evil-state) :toggle))) - (when (and (functionp func) - (or message (not (eq state evil-state)))) - (funcall func (if state (and message 1) -1))))) - -(defmacro evil-save-state (&rest body) - "Save the current state; execute BODY; restore the state." - (declare (indent defun) - (debug t)) - `(let ((evil-state evil-state) - (evil-previous-state evil-previous-state) - (evil-previous-state-alist (copy-tree evil-previous-state-alist)) - (evil-next-state evil-next-state) - (old-state evil-state) - (inhibit-quit t) - (buf (current-buffer))) - (unwind-protect - (progn ,@body) - (when (buffer-live-p buf) - (with-current-buffer buf - (evil-change-state old-state)))))) - -(defmacro evil-with-state (state &rest body) - "Change to STATE and execute BODY without refreshing the display. -Restore the previous state afterwards." - (declare (indent defun) - (debug t)) - `(evil-without-display - (evil-save-state - (evil-change-state ',state) - ,@body))) - -(defun evil-initialize-state () - "Set up the initial state for the current buffer. -See also `evil-set-initial-state'." - (evil-change-state (evil-initial-state-for-buffer))) - -(defun evil-initial-state-for-buffer-name (&optional name default) - "Return the initial Evil state to use for a buffer with name NAME. -Matches the name against the regular expressions in -`evil-buffer-regexps'. If none matches, returns DEFAULT." - (let ((name (if (stringp name) name (buffer-name name)))) - (when name - (catch 'done - (dolist (entry evil-buffer-regexps default) - (let ((regexp (car entry)) - (state (cdr entry))) - (when (string-match-p regexp name) - (throw 'done state)))))))) - -(defun evil-disabled-buffer-p (&optional buffer) - "Whether Evil should be disabled in BUFFER." - (null (evil-initial-state-for-buffer-name buffer 'undefined))) - -(defun evil-initial-state-for-buffer (&optional buffer) - "Return the initial Evil state to use for BUFFER. -BUFFER defaults to the current buffer. See also `evil-initial-state'." - (with-current-buffer (or buffer (current-buffer)) - (or (evil-initial-state-for-buffer-name) - (cl-loop for (mode) in minor-mode-map-alist - when (and (boundp mode) (symbol-value mode)) - thereis (evil-initial-state mode)) - (evil-initial-state major-mode nil t) - evil-default-state))) - -(defun evil-initial-state (mode &optional default follow-parent checked-modes) - "Return the Evil state to use for MODE or its alias. -Return DEFAULT if no initial state is associated with MODE. -The initial state for a mode can be set with -`evil-set-initial-state'. - -If FOLLOW-PARENT is non-nil, also check parent modes of MODE and -its alias. CHECKED-MODES is used internally and should not be set -initially." - (when (memq mode checked-modes) - (error "Circular reference detected in ancestors of `%s'\n%s" - major-mode checked-modes)) - (let ((mode-alias (let ((func (symbol-function mode))) - (when (symbolp func) func)))) - (or (cl-dolist (entry (evil-state-property t :modes) default) - (let ((state (car entry)) - (modes (symbol-value (cdr entry)))) - (when (or (memq mode modes) - (and mode-alias (memq mode-alias modes))) - (cl-return state)))) - (and follow-parent (get mode 'derived-mode-parent) - (evil-initial-state (get mode 'derived-mode-parent) - nil t (cons mode checked-modes))) - (and follow-parent mode-alias - (get mode-alias 'derived-mode-parent) - (evil-initial-state (get mode-alias 'derived-mode-parent) - nil t (cons mode-alias checked-modes)))))) - -(defun evil-set-initial-state (mode state) - "Set the initial state for major mode MODE to STATE. -This is the state the buffer comes up in." - (dolist (modes (evil-state-property t :modes)) - (setq modes (cdr-safe modes)) - (set modes (delq mode (symbol-value modes)))) - (when state - (add-to-list (evil-state-property state :modes) mode))) - -(evil-define-command evil-change-to-initial-state - (&optional buffer message) - "Change the state of BUFFER to its initial state. -This is the state the buffer came up in. If Evil is not activated -then this function does nothing." - :keep-visual t - :suppress-operator t - (when evil-local-mode - (with-current-buffer (or buffer (current-buffer)) - (evil-change-state (evil-initial-state-for-buffer buffer) - message)))) - -(evil-define-command evil-change-to-previous-state - (&optional buffer message) - "Change the state of BUFFER to its previous state." - :keep-visual t - :repeat abort - :suppress-operator t - (with-current-buffer (or buffer (current-buffer)) - (let ((prev-state evil-previous-state) - (prev-prev-state (cdr-safe (assoc evil-previous-state - evil-previous-state-alist)))) - (evil-change-state nil) - (when prev-prev-state - (setq evil-previous-state prev-prev-state)) - (evil-change-state (or prev-state evil-default-state 'normal) - message)))) - -;; When a buffer is created in a low-level way, it is invisible to -;; Evil (as well as other globalized minor modes) because no hooks are -;; run. This is appropriate since many buffers are used for throwaway -;; purposes. Passing the buffer to `set-window-buffer' indicates -;; otherwise, though, so advise this function to initialize Evil. -(evil--advice-add 'set-window-buffer :before #'evil--swb-initialize) -(defun evil--swb-initialize (_window buffer &rest _) - "Initialize Evil in the displayed buffer." - (when (and evil-mode (get-buffer buffer)) - (with-current-buffer buffer - (unless evil-local-mode - (save-match-data (evil-initialize)))))) - -;; Refresh cursor color. -;; Cursor color can only be set for each frame but not for each buffer. -;; FIXME: Shouldn't this belong in `evil-(local-)mode'? -(add-hook 'window-configuration-change-hook #'evil-refresh-cursor) -(advice-add 'select-window :after #'evil--sw-refresh-cursor) -(defun evil--sw-refresh-cursor (&rest _) - (evil-refresh-cursor)) - -(defun evil-generate-mode-line-tag (&optional state) - "Generate the evil mode-line tag for STATE." - (let ((tag (evil-state-property state :tag t))) - (when (functionp tag) - (setq tag (funcall tag))) - ;; prepare mode-line: add tooltip - (if (stringp tag) - (propertize tag - 'help-echo (evil-state-property state :name) - 'mouse-face 'mode-line-highlight) - tag))) - -(defun evil-refresh-mode-line (&optional state) - "Refresh mode line tag." - (when (listp mode-line-format) - (setq evil-mode-line-tag (evil-generate-mode-line-tag state)) - ;; refresh mode line data structure - ;; first remove evil from mode-line - (setq mode-line-format (delq 'evil-mode-line-tag mode-line-format)) - (let ((mlpos mode-line-format) - pred which where) - ;; determine before/after which symbol the tag should be placed - (cond - ((eq evil-mode-line-format 'before) - (setq where 'after which 'mode-line-position)) - ((eq evil-mode-line-format 'after) - (setq where 'after which 'mode-line-modes)) - ((consp evil-mode-line-format) - (setq where (car evil-mode-line-format) - which (cdr evil-mode-line-format)))) - ;; find the cons-cell of the symbol before/after which the tag - ;; should be placed - (while (and mlpos - (let ((sym (or (car-safe (car mlpos)) (car mlpos)))) - (not (eq which sym)))) - (setq pred mlpos - mlpos (cdr mlpos))) - ;; put evil tag at the right position in the mode line - (cond - ((not mlpos)) ;; position not found, so do not add the tag - ((eq where 'before) - (if pred - (setcdr pred (cons 'evil-mode-line-tag mlpos)) - (setq mode-line-format - (cons 'evil-mode-line-tag mode-line-format)))) - ((eq where 'after) - (setcdr mlpos (cons 'evil-mode-line-tag (cdr mlpos))))) - (force-mode-line-update)))) - -;; input methods should be disabled in non-insertion states -(defun evil-activate-input-method () - "Enable input method in states with :input-method non-nil." - (let (input-method-activate-hook - input-method-deactivate-hook) - (when (and evil-local-mode evil-state) - (setq evil-input-method current-input-method) - (unless (evil-state-property evil-state :input-method) - (deactivate-input-method))))) -(put 'evil-activate-input-method 'permanent-local-hook t) - -(defun evil-deactivate-input-method () - "Disable input method in all states." - (let (input-method-activate-hook - input-method-deactivate-hook) - (when (and evil-local-mode evil-state) - (setq evil-input-method nil)))) -(put 'evil-deactivate-input-method 'permanent-local-hook t) - -(defmacro evil-without-input-method-hooks (&rest body) - "Execute body with evil's activate/deactivate-input-method hooks deactivated. -This allows input methods to be used in normal-state." - (declare (indent defun)) - `(unwind-protect - (progn - (remove-hook 'input-method-activate-hook #'evil-activate-input-method t) - (remove-hook 'input-method-deactivate-hook #'evil-deactivate-input-method t) - ,@body) - (add-hook 'input-method-activate-hook #'evil-activate-input-method nil t) - (add-hook 'input-method-deactivate-hook #'evil-deactivate-input-method nil t))) - -(evil--advice-add 'toggle-input-method :around #'evil--refresh-input-method) -(defun evil--refresh-input-method (orig-fun &rest args) - "Refresh `evil-input-method'." - (cond - ((not evil-local-mode) - (apply orig-fun args)) - ((evil-state-property evil-state :input-method) - (apply orig-fun args)) - (t - (let ((current-input-method evil-input-method)) - (apply orig-fun args))))) - -;; Local keymaps are implemented using buffer-local variables. -;; However, unless a buffer-local value already exists, -;; `define-key' acts on the variable's default (global) value. -;; So we need to initialize the variable whenever we enter a -;; new buffer or when the buffer-local values are reset. -(defun evil-initialize-local-keymaps () - "Initialize a buffer-local value for local keymaps as necessary. -The initial value is that of `make-sparse-keymap'." - (dolist (entry evil-local-keymaps-alist) - (let ((map (cdr entry))) - (unless (and (keymapp (symbol-value map)) - (local-variable-p map)) - (set map (make-sparse-keymap)))))) - -(defun evil-make-overriding-map (keymap &optional state copy) - "Give KEYMAP precedence over the global keymap of STATE. -The keymap will have lower precedence than custom STATE bindings. -If STATE is nil, give it precedence over all states. -If COPY is t, create a copy of KEYMAP and give that -higher precedence. See also `evil-make-intercept-map'." - (let ((key [override-state])) - (if (not copy) - (define-key keymap key (or state 'all)) - (unless (keymapp copy) - (setq copy (assq-delete-all 'menu-bar (copy-keymap keymap)))) - (define-key copy key (or state 'all)) - (define-key keymap key copy)))) - -(defun evil-make-intercept-map (keymap &optional state aux) - "Give KEYMAP precedence over all Evil keymaps in STATE. -If STATE is nil, give it precedence over all states. If AUX is non-nil, make the -auxiliary keymap corresponding to KEYMAP in STATE an intercept keymap instead of -KEYMAP itself. See also `evil-make-overriding-map'." - (let ((key [intercept-state]) - (keymap (if aux - (evil-get-auxiliary-keymap keymap state t t) - keymap))) - (define-key keymap key (or state 'all)))) - -(defmacro evil-define-keymap (keymap doc &rest body) - "Define a keymap KEYMAP listed in `evil-mode-map-alist'. -That means it will have precedence over regular keymaps. - -DOC is the documentation for the variable. BODY, if specified, -is executed after toggling the mode. Optional keyword arguments -may be specified before the body code: - -:mode VAR Mode variable. If unspecified, the variable - is based on the keymap name. -:local BOOLEAN Whether the keymap should be buffer-local, that is, - reinitialized for each buffer. -:func BOOLEAN Create a toggle function even if BODY is empty. - -\(fn KEYMAP DOC [[KEY VAL]...] BODY...)" - (declare (indent defun) - (doc-string 2) - (debug (&define name - [&optional stringp] - [&rest [keywordp sexp]] - def-body))) - (let ((func t) - arg intercept key local mode overriding) - (while (keywordp (car-safe body)) - (setq key (pop body) - arg (pop body)) - (cond - ((eq key :mode) (setq mode arg)) - ((eq key :local) (setq local arg)) - ((eq key :func) (setq func arg)) - ((eq key :intercept) (setq intercept arg)) - ((eq key :overriding) (setq overriding arg)))) - (setq mode (or mode - (intern (replace-regexp-in-string - "\\(?:-\\(?:mode-\\)?\\(?:key\\)?map\\)?$" - "-mode" - (symbol-name keymap))))) - `(progn - (defvar ,keymap ,(unless local '(make-sparse-keymap))) - (unless (get ',keymap 'variable-documentation) - (put ',keymap 'variable-documentation ,doc)) - (defvar ,mode nil) - (unless (get ',mode 'variable-documentation) - (put ',mode 'variable-documentation ,doc)) - (make-variable-buffer-local ',mode) - (put ',mode 'permanent-local t) - (when ,intercept - (evil-make-intercept-map ,keymap)) - (when ,overriding - (evil-make-overriding-map ,keymap)) - ,@(if local - `((make-variable-buffer-local ',keymap) - (put ',keymap 'permanent-local t) - (evil--add-to-alist evil-local-keymaps-alist ',mode ',keymap)) - `((evil--add-to-alist evil-global-keymaps-alist ',mode ',keymap) - (evil--add-to-alist evil-mode-map-alist ',mode ,keymap))) - ,(when (or body func) - `(defun ,mode (&optional arg) - ,@(when doc `(,doc)) - (interactive) - (cond - ((numberp arg) (setq ,mode (> arg 0))) - (t (setq ,mode (not ,mode)))) - ,@body)) - ',keymap))) - -;; The ESC -> escape translation code has been provided by Stefan -;; Monnier in the discussion of GNU Emacs bug #13793. -(defun evil-esc-mode (&optional arg) - "Toggle interception of \\e (escape). -Enable with positive ARG and disable with negative ARG. - -When enabled, `evil-esc-mode' modifies the entry of \\e in -`input-decode-map'. If such an event arrives, it is translated to -a plain `escape' event if no further event occurs within -`evil-esc-delay' seconds. Otherwise no translation happens and -the ESC prefix map (i.e. the map originally bound to \\e in -`input-decode-map`) is returned." - (cond - ((or (null arg) (eq arg 0)) - (evil-esc-mode (if evil-esc-mode -1 +1))) - ((> arg 0) - (unless evil-esc-mode - (setq evil-esc-mode t) - (add-hook 'after-make-frame-functions #'evil-init-esc) - (mapc #'evil-init-esc (frame-list)))) - ((< arg 0) - (when evil-esc-mode - (remove-hook 'after-make-frame-functions #'evil-init-esc) - (mapc #'evil-deinit-esc (frame-list)) - (setq evil-esc-mode nil))))) - -(defun evil-init-esc (frame) - "Update `input-decode-map' in terminal." - (with-selected-frame frame - (let ((term (frame-terminal frame))) - (when (and - (or (eq evil-intercept-esc 'always) - (and evil-intercept-esc - (eq (terminal-live-p term) t))) ; only patch tty - (not (terminal-parameter term 'evil-esc-map))) - (let ((evil-esc-map (lookup-key input-decode-map [?\e]))) - (set-terminal-parameter term 'evil-esc-map evil-esc-map) - (define-key input-decode-map [?\e] - `(menu-item "" ,evil-esc-map :filter ,#'evil-esc))))))) - -(defun evil-deinit-esc (frame) - "Restore `input-decode-map' in terminal." - (with-selected-frame frame - (let ((term (frame-terminal frame))) - (when (terminal-live-p term) - (let ((evil-esc-map (terminal-parameter term 'evil-esc-map))) - (when evil-esc-map - (define-key input-decode-map [?\e] evil-esc-map) - (set-terminal-parameter term 'evil-esc-map nil))))))) - -(defun evil-esc (map) - "Translate \\e to `escape' if no further event arrives. -This function is used to translate a \\e event either to `escape' -or to the standard ESC prefix translation map. If \\e arrives, -this function waits for `evil-esc-delay' seconds for another -event. If no other event arrives, the event is translated to -`escape', otherwise it is translated to the standard ESC prefix -map stored in `input-decode-map'. If `evil-inhibit-esc' is -non-nil or if evil is in emacs state, the event is always -translated to the ESC prefix. - -The translation to `escape' happens only if the current command -has indeed been triggered by \\e. In other words, this will only -happen when the keymap is accessed from `read-key-sequence'. In -particular, if it is access from `define-key' the returned -mapping will always be the ESC prefix map." - (if (and (not evil-inhibit-esc) - (or evil-local-mode (evil-ex-p) - (active-minibuffer-window)) - (not (evil-emacs-state-p)) - (let ((keys (this-single-command-keys))) - (and (> (length keys) 0) - (= (aref keys (1- (length keys))) ?\e))) - (sit-for evil-esc-delay)) - (prog1 [escape] - (when defining-kbd-macro - (end-kbd-macro) - (setq last-kbd-macro (vconcat last-kbd-macro [escape])) - (start-kbd-macro t t))) - map)) - -(defun evil-state-p (sym) - "Whether SYM is the name of a state." - (assq sym evil-state-properties)) - -(defun evil-state-keymaps (state &rest excluded) - "Return a keymap alist of keymaps activated by STATE. -If STATE references other states in its :enable property, -these states are recursively processed and added to the list. -\(The EXCLUDED argument is an internal safeguard against -infinite recursion, keeping track of processed states.)" - (let* ((state (or state evil-state)) - (enable (evil-state-property state :enable)) - (map (cons - (evil-state-property state :mode) - (evil-state-property state :keymap t))) - (local-map (cons - (evil-state-property state :local) - (evil-state-property state :local-keymap t))) - (minor-mode-maps (evil-state-minor-mode-keymaps state)) - (aux-maps (evil-state-auxiliary-keymaps state)) - (overriding-maps - (evil-state-overriding-keymaps state)) - (intercept-maps - (evil-state-intercept-keymaps state)) - (result `(,intercept-maps)) - (remove-duplicates (null excluded))) - (unless (memq state enable) - (setq enable (cons state enable))) - ;; process STATE's :enable property - (dolist (entry enable) - (cond - ((memq entry excluded)) - ;; the keymaps for STATE - ((eq entry state) - (setq result `(,@result - (,local-map) - ,minor-mode-maps - ,aux-maps - ,overriding-maps - (,map))) - (push state excluded)) - ;; the keymaps for another state: call `evil-state-keymaps' - ;; recursively, but keep track of processed states - ((evil-state-p entry) - (setq result `(,@result - ,(apply #'evil-state-keymaps entry excluded)))) - ;; a single keymap - ((or (keymapp entry) - (and (keymapp (symbol-value entry)) - (setq entry (symbol-value entry))) - (setq entry (evil-keymap-for-mode entry))) - (setq result `(,@result - ((,(evil-mode-for-keymap entry t) . - ,entry))))))) - ;; postpone the expensive filtering of duplicates to the top level - (if remove-duplicates - (apply #'evil-concat-keymap-alists result) - (apply #'append result)))) - -(defun evil-normalize-keymaps (&optional state) - "Create a buffer-local value for `evil-mode-map-alist'. -This is a keymap alist, determined by the current state -\(or by STATE if specified)." - (let ((state (or state evil-state)) - (excluded '(nil t)) - map mode temp) - ;; initialize buffer-local keymaps as necessary - (evil-initialize-local-keymaps) - ;; deactivate keymaps of previous state - (dolist (entry evil-mode-map-alist) - (setq mode (car entry) - map (cdr entry)) - ;; don't deactivate overriding keymaps; - ;; they are toggled by their associated mode - (if (or (memq mode excluded) - (evil-intercept-keymap-p map) - (evil-overriding-keymap-p map) - (evil-auxiliary-keymap-p map) - (evil-minor-mode-keymap-p map)) - (push mode excluded) - (and (fboundp mode) (symbol-value mode) (funcall mode -1)) - (set mode nil))) - (setq evil-mode-map-alist nil) - ;; activate keymaps of current state - (when state - (setq temp (evil-state-keymaps state)) - (dolist (entry temp) - (setq mode (car entry) - map (cdr entry)) - (unless (or (and (boundp mode) (symbol-value mode)) - ;; the minor-mode keymaps include modes that are not - ;; necessarily active - (evil-minor-mode-keymap-p map)) - (when (fboundp mode) - (funcall mode 1)) - (set mode t)) - ;; refresh the keymap in case it has changed - ;; (e.g., `evil-operator-shortcut-map' is - ;; reset on toggling) - (if (or (memq mode excluded) - (evil-intercept-keymap-p map) - (evil-overriding-keymap-p map) - (evil-auxiliary-keymap-p map) - (evil-minor-mode-keymap-p map)) - (push mode excluded) - (setcdr entry (or (evil-keymap-for-mode mode) map)))) - ;; update `evil-mode-map-alist' - (setq evil-mode-map-alist temp)))) - -(defun evil-mode-for-keymap (keymap &optional default) - "Return the minor mode associated with KEYMAP. -Return DEFAULT if no mode is found. -See also `evil-keymap-for-mode'." - (let ((map (if (keymapp keymap) keymap (symbol-value keymap))) - (var (when (symbolp keymap) keymap))) - ;; Check Evil variables first for speed purposes. - ;; If all else fails, check `minor-mode-map-alist'. - (or (when var - (or (car (rassq var evil-global-keymaps-alist)) - (car (rassq var evil-local-keymaps-alist)))) - (car (rassq map (mapcar #'(lambda (e) - ;; from (MODE-VAR . MAP-VAR) - ;; to (MODE-VAR . MAP) - (cons (car-safe e) - (symbol-value (cdr-safe e)))) - (append evil-global-keymaps-alist - evil-local-keymaps-alist)))) - (car (rassq map minor-mode-map-alist)) - default))) - -(defun evil-keymap-for-mode (mode &optional variable) - "Return the keymap associated with MODE. -Return the keymap variable if VARIABLE is non-nil. -See also `evil-mode-for-keymap'." - (let* ((var (or (cdr (assq mode evil-global-keymaps-alist)) - (cdr (assq mode evil-local-keymaps-alist)))) - (map (or (symbol-value var) - (cdr (assq mode minor-mode-map-alist))))) - (if variable var map))) - -(defun evil-state-auxiliary-keymaps (state) - "Return a keymap alist of auxiliary keymaps for STATE." - (let ((state (or state evil-state)) - aux result) - (dolist (map (current-active-maps) (nreverse result)) - (when (setq aux (evil-get-auxiliary-keymap map state)) - (push (cons (evil-mode-for-keymap map t) aux) result))))) - -(defun evil-state-minor-mode-keymaps (state) - "Return a keymap alist of minor-mode keymaps for STATE." - (cdr (assq (or state evil-state) evil-minor-mode-keymaps-alist))) - -(defun evil-state-overriding-keymaps (&optional state) - "Return a keymap alist of overriding keymaps for STATE." - (let* ((state (or state evil-state)) - result) - (dolist (map (current-active-maps)) - (when (setq map (evil-overriding-keymap-p map state)) - (push (cons (evil-mode-for-keymap map t) map) result))) - (nreverse result))) - -(defun evil-state-intercept-keymaps (&optional state) - "Return a keymap alist of intercept keymaps for STATE." - (let* ((state (or state evil-state)) - result) - (dolist (map (current-active-maps)) - (when (setq map (or (evil-intercept-keymap-p map state) - (evil-intercept-keymap-p - (evil-get-auxiliary-keymap map state) state))) - (push (cons (evil-mode-for-keymap map t) map) result))) - (setq result (nreverse result)) - result)) - -(defun evil-set-auxiliary-keymap (map state &optional aux) - "Set the auxiliary keymap for MAP in STATE to AUX. -If AUX is nil, create a new auxiliary keymap." - (unless aux (setq aux (make-sparse-keymap))) - (unless (evil-auxiliary-keymap-p aux) - (evil-set-keymap-prompt - aux (format "Auxiliary keymap for %s" - (or (evil-state-property state :name) - (format "%s state" state))))) - (define-key map (vector (intern (format "%s-state" state))) aux) - aux) - -(defun evil-get-auxiliary-keymap (map state &optional create ignore-parent) - "Get the auxiliary keymap for MAP in STATE. -If CREATE is non-nil, create an auxiliary keymap -if MAP does not have one. If CREATE and -IGNORE-PARENT are non-nil then a new auxiliary -keymap is created even if the parent of MAP has -one already." - (when state - (let* ((key (vector (intern (format "%s-state" state)))) - (parent-aux (when (and ignore-parent - (keymap-parent map)) - (lookup-key (keymap-parent map) key))) - (aux (lookup-key map key))) - (cond - ((and ignore-parent - (equal parent-aux aux) - create) - (evil-set-auxiliary-keymap map state)) - ((evil-auxiliary-keymap-p aux) - aux) - (create - (evil-set-auxiliary-keymap map state)))))) - -(defun evil-get-minor-mode-keymap (state mode) - "Get the auxiliary keymap for MODE in STATE, creating one if it -does not already exist." - (let ((state-entry (assq state evil-minor-mode-keymaps-alist))) - (if (and state-entry - (assq mode state-entry)) - (cdr (assq mode state-entry)) - (let ((map (make-sparse-keymap))) - (evil-set-keymap-prompt - map (format "Minor-mode keymap for %s in %s" - mode - (or (evil-state-property state :name) - (format "%s state" state)))) - (if state-entry - (setcdr state-entry - (append (list (cons mode map)) (cdr state-entry))) - (push (cons state (list (cons mode map))) - evil-minor-mode-keymaps-alist)) - map)))) - -(defun evil-auxiliary-keymap-p (map) - "Whether MAP is an auxiliary keymap." - (let ((prompt (keymap-prompt map))) - (when prompt (string-prefix-p "Auxiliary keymap" prompt)))) - -(defun evil-minor-mode-keymap-p (map) - "Whether MAP is a minor-mode keymap." - (let ((prompt (keymap-prompt map))) - (when prompt (string-prefix-p "Minor-mode keymap" prompt)))) - -(defun evil-intercept-keymap-p (map &optional state) - "Whether MAP is an intercept keymap for STATE. -If STATE is nil, it means any state." - (let ((entry (and (keymapp map) - (lookup-key map [intercept-state])))) - (cond - ((null entry) nil) - ((null state) map) - ((eq entry state) map) - ((eq entry 'all) map)))) - -(defun evil-overriding-keymap-p (map &optional state) - "Whether MAP is an overriding keymap for STATE. -If STATE is nil, it means any state." - (let ((entry (and (keymapp map) - (lookup-key map [override-state])))) - (cond - ((null entry) nil) - ((keymapp entry) (evil-overriding-keymap-p entry state)) - ((null state) map) - ((eq entry state) map) - ((eq entry 'all) map)))) - -(defun evil-intercept-keymap-state (map) - "Return the state for the intercept keymap MAP. -A return value of t means all states." - (let ((state (lookup-key map [intercept-state] map))) - (cond - ((keymapp state) - (evil-intercept-keymap-state state)) - ((eq state 'all) - t) - (t - state)))) - -(defun evil-overriding-keymap-state (map) - "Return the state for the overriding keymap MAP. -A return value of t means all states." - (let ((state (lookup-key map [override-state] map))) - (cond - ((keymapp state) - (evil-overriding-keymap-state state)) - ((eq state 'all) - t) - (t - state)))) - -(defun evil-set-leader (state key &optional localleader) - "Set KEY to trigger leader bindings in STATE. -KEY should be in the form produced by `kbd'. STATE is one of -`normal', `insert', `visual', `replace', `operator', `motion', -`emacs', a list of one or more of these, or `nil', which means -all of the above. If LOCALLEADER is non-nil, set the local leader -instead." - (let* ((all-states '(normal insert visual replace operator motion emacs)) - (states (cond ((null state) all-states) - ((consp state) state) - (t (list state)))) - (leaderkey (if localleader [localleader] [leader])) - (binding - `(menu-item "" nil :filter ,(lambda (_cmd) (key-binding leaderkey))))) - (dolist (state states) - (evil-global-set-key state key binding)))) - -(defmacro evil-define-key (state keymap key def &rest bindings) - "Create a STATE binding from KEY to DEF for KEYMAP. -STATE is one of `normal', `insert', `visual', `replace', -`operator', `motion', `emacs', or a list of one or more of -these. Omitting a state by using `nil' corresponds to a standard -Emacs binding using `define-key'. The remaining arguments are -like those of `define-key'. For example: - - (evil-define-key \\='normal foo-map \"a\" \\='bar) - -This creates a binding from `a' to `bar' in normal state, which -is active whenever `foo-map' is active. Using nil for the state, -the following lead to identical bindings: - - (evil-define-key nil foo-map \"a\" \\='bar) - (define-key foo-map \"a\" \\='bar) - -It is possible to specify multiple states and/or bindings at -once: - - (evil-define-key \\='(normal visual) foo-map - \"a\" \\='bar - \"b\" \\='foo) - -If `foo-map' has not been initialized yet, this macro adds an -entry to `after-load-functions', delaying execution as necessary. - -KEYMAP may also be a quoted symbol. If the symbol is `global', the -global evil keymap corresponding to the state(s) is used, meaning -the following lead to identical bindings: - - (evil-define-key \\='normal \\='global \"a\" \\='bar) - (evil-global-set-key \\='normal \"a\" \\='bar) - -The symbol `local' may also be used, which corresponds to using -`evil-local-set-key'. If a quoted symbol is used that is not -`global' or `local', it is assumed to be the name of a minor -mode, in which case `evil-define-minor-mode-key' is used. - -KEY is an internal Emacs representation of a key, as for -`define-key'. To bind key sequences that use modifier keys such -as \"C-a\" or \"M-a\", convert the key sequences using `kbd'. -For example: - - (evil-define-key \\='normal foo-map (kbd \"C-a\") \\='bar)" - (declare (indent defun)) - (cond - ((member keymap '('global 'local)) - `(evil-define-key* ,state ,keymap ,key ,def ,@bindings)) - ((eq (car-safe keymap) 'quote) - `(evil-define-minor-mode-key ,state ,keymap ,key ,def ,@bindings)) - (t `(evil-with-delay ,(if (symbolp keymap) - ;; BEWARE: Can't work for lexically scoped vars - `(and (boundp ',keymap) (keymapp ,keymap)) - `(keymapp ,keymap)) - (after-load-functions - t nil ,(format "evil-define-key-in-%s" - (if (symbolp keymap) keymap 'keymap))) - (with-demoted-errors "Error in evil-define-key: %S" - (evil-define-key* ,state ,keymap ,key ,def ,@bindings)))))) -(defalias 'evil-declare-key #'evil-define-key) - -(defun evil-define-key* (state keymap key def &rest bindings) - "Create a STATE binding from KEY to DEF for KEYMAP. -STATE is one of normal, insert, visual, replace, operator, -motion, emacs, or a list of one or more of these. Omitting a -state by using nil corresponds to a standard Emacs binding using -`define-key' The remaining arguments are like those of -`define-key'. For example: - - (evil-define-key* \\='normal foo-map \"a\" \\='bar) - -This creates a binding from \"a\" to bar in Normal state, which -is active whenever foo-map is active. Using nil for the state, -the following are equivalent: - - (evil-define-key* nil foo-map \"a\" \\='bar) - - (define-key foo-map \"a\" \\='bar) - - It is possible to specify multiple states and/or bindings at - once: - - (evil-define-key* \\='(normal visual) foo-map - \"a\" \\='bar - \"b\" \\='foo) - -KEYMAP may also be a quoted symbol. If the symbol is global, the -global evil keymap corresponding to the state(s) is used, meaning -the following are equivalent: - - (evil-define-key* \\='normal \\='global \"a\" \\='bar) - - (evil-global-set-key \\='normal \"a\" \\='bar) - -The symbol local may also be used, which corresponds to using -`evil-local-set-key'. - -The use is nearly identical to `evil-define-key' with the -exception that this is a function and not a macro (and so will -not be expanded when compiled which can have unintended -consequences). `evil-define-key*' also does not defer any -bindings like `evil-define-key' does using `evil-with-delay'. This -allows errors in the bindings to be caught immediately, and makes -its behavior more predictable." - (declare (indent defun)) - (let ((maps - (if state - (mapcar - (lambda (st) - (cond ((eq keymap 'global) - (evil-state-property st :keymap t)) - ((eq keymap 'local) - (evil-state-property st :local-keymap t)) - (t - (evil-get-auxiliary-keymap keymap st t t)))) - (if (listp state) state (list state))) - (list - (cond ((eq keymap 'global) - global-map) - ((eq keymap 'local) - ;; see `local-set-key' - (or (current-local-map) - (let ((map (make-sparse-keymap))) - (use-local-map map) - map))) - (t - keymap)))))) - (while key - (dolist (map maps) - (define-key map key def)) - (setq key (pop bindings) - def (pop bindings))) - ;; ensure the prompt string comes first - (dolist (map maps) - (evil-set-keymap-prompt map (keymap-prompt map))))) - -(defun evil-define-minor-mode-key (state mode key def &rest bindings) - "Similar to `evil-define-key' but the bindings are associated -with the minor-mode symbol MODE instead of a particular map. -Associating bindings with a mode symbol instead of a map allows -evil to use Emacs' built-in mechanisms to enable the bindings -automatically when MODE is active without relying on calling -`evil-normalize-keymaps'. Another less significant difference is -that the bindings can be created immediately, because this -function only uses the symbol MODE and does not rely on its -value. - -See `evil-define-key' for the usage of STATE, KEY, DEF and -BINDINGS." - (declare (indent defun)) - (let ((maps (mapcar - (lambda (st) - (evil-get-minor-mode-keymap st mode)) - (if (listp state) state (list state))))) - (while key - (dolist (map maps) - (define-key map key def)) - (setq key (pop bindings) - def (pop bindings))))) - -(defmacro evil-add-hjkl-bindings (keymap &optional state &rest bindings) - "Add \"h\", \"j\", \"k\", \"l\" bindings to KEYMAP in STATE. -Add additional BINDINGS if specified." - (declare (indent defun)) - `(evil-define-key ,state ,keymap - "h" (lookup-key evil-motion-state-map "h") - "j" (lookup-key evil-motion-state-map "j") - "k" (lookup-key evil-motion-state-map "k") - "l" (lookup-key evil-motion-state-map "l") - ":" (lookup-key evil-motion-state-map ":") - ,@bindings)) - -;; may be useful for programmatic purposes -(defun evil-global-set-key (state key def) - "Bind KEY to DEF in STATE." - (define-key (evil-state-property state :keymap t) key def)) - -(defun evil-local-set-key (state key def) - "Bind KEY to DEF in STATE in the current buffer." - (define-key (evil-state-property state :local-keymap t) key def)) - -;; Advise these functions as they may activate an overriding keymap or -;; a keymap with state bindings; if so, refresh `evil-mode-map-alist'. -(advice-add 'use-global-map :after #'evil--do-normalize-keymaps) -(advice-add 'use-local-map :after #'evil--do-normalize-keymaps) -(defun evil--do-normalize-keymaps (&rest _) - "Refresh Evil keymaps." - (evil-normalize-keymaps)) - - -(defmacro evil-define-state (state doc &rest body) - "Define an Evil state STATE. -DOC is a general description and shows up in all docstrings; -the first line of the string should be the full name of the state. - -BODY is executed each time the state is enabled or disabled. - -Optional keyword arguments: -- `:tag' - the mode line indicator, e.g. \"<T>\". -- `:message' - string shown in the echo area when the state is - activated. -- `:cursor' - default cursor specification. -- `:enable' - list of other state keymaps to enable when in this - state. -- `:entry-hook' - list of functions to run when entering this state. -- `:exit-hook' - list of functions to run when exiting this state. -- `:suppress-keymap' - if non-nil, effectively disables bindings to - `self-insert-command' by making `evil-suppress-map' the parent of - the global state keymap. - -The global keymap of this state will be `evil-test-state-map', -the local keymap will be `evil-test-state-local-map', and so on. - -\(fn STATE DOC [[KEY VAL]...] BODY...)" - (declare (indent defun) - (doc-string 2) - (debug (&define name - [&optional stringp] - [&rest [keywordp sexp]] - def-body))) - (let* ((name (and (string-match "^\\(.+\\)\\(\\(?:.\\|\n\\)*\\)" doc) - (match-string 1 doc))) - (doc (match-string 2 doc)) - (name (and (string-match "^\\(.+?\\)\\.?$" name) - (match-string 1 name))) - (doc (if (or (null doc) (string= doc "")) "" - (format "\n%s" doc))) - (toggle (intern (format "evil-%s-state" state))) - (mode (intern (format "%s-minor-mode" toggle))) - (keymap (intern (format "%s-map" toggle))) - (local (intern (format "%s-local-minor-mode" toggle))) - (local-keymap (intern (format "%s-local-map" toggle))) - (tag (intern (format "%s-tag" toggle))) - (message (intern (format "%s-message" toggle))) - (cursor (intern (format "%s-cursor" toggle))) - (entry-hook (intern (format "%s-entry-hook" toggle))) - (exit-hook (intern (format "%s-exit-hook" toggle))) - (modes (intern (format "%s-modes" toggle))) - (predicate (intern (format "%s-p" toggle))) - arg cursor-value enable entry-hook-value exit-hook-value - input-method key message-value suppress-keymap tag-value) - ;; collect keywords - (while (keywordp (car-safe body)) - (setq key (pop body) - arg (pop body)) - (cond - ((eq key :tag) - (setq tag-value arg)) - ((eq key :message) - (setq message-value arg)) - ((eq key :cursor) - (setq cursor-value arg)) - ((eq key :entry-hook) - (setq entry-hook-value arg) - (unless (listp entry-hook-value) - (setq entry-hook-value (list entry-hook-value)))) - ((eq key :exit-hook) - (setq exit-hook-value arg) - (unless (listp exit-hook-value) - (setq exit-hook-value (list exit-hook-value)))) - ((eq key :enable) - (setq enable arg)) - ((eq key :input-method) - (setq input-method arg)) - ((eq key :suppress-keymap) - (setq suppress-keymap arg)))) - - ;; macro expansion - `(progn - ;; Save the state's properties in `evil-state-properties' for - ;; runtime lookup. Among other things, this information is used - ;; to determine what keymaps should be activated by the state - ;; (and, when processing :enable, what keymaps are activated by - ;; other states). We cannot know this at compile time because - ;; it depends on the current buffer and its active keymaps - ;; (to which we may have assigned state bindings), as well as - ;; states whose definitions may not have been processed yet. - (let ((plist (list - :name ',name - :toggle ',toggle - :mode (defvar ,mode nil - ,(format "Non-nil if %s is enabled. -Use the command `%s' to change this variable." name toggle)) - :keymap (defvar ,keymap (make-sparse-keymap) - ,(format "Keymap for %s." name)) - :local (defvar ,local nil - ,(format "Non-nil if %s is enabled. -Use the command `%s' to change this variable." name toggle)) - :local-keymap (defvar ,local-keymap nil - ,(format "Buffer-local keymap for %s." name)) - :tag (defvar ,tag ,tag-value - ,(format "Mode line tag for %s." name)) - :message (defvar ,message ,message-value - ,(format "Echo area message for %s." name)) - :cursor (defvar ,cursor ',cursor-value - ,(format "Cursor for %s. -May be a cursor type as per `cursor-type', a color string as passed -to `set-cursor-color', a zero-argument function for changing the -cursor, or a list of the above. - -If set to nil, the value of `evil-default-cursor' is used; if you -want the nil `cursor-type' (i.e., you want to disable the cursor), -set this variable to (list nil)." name)) - :entry-hook (defvar ,entry-hook nil - ,(format "Hooks to run when entering %s." name)) - :exit-hook (defvar ,exit-hook nil - ,(format "Hooks to run when exiting %s." name)) - :modes (defvar ,modes nil - ,(format "Modes that should come up in %s." name)) - :input-method ',input-method - :predicate ',predicate - :enable ',enable))) - (evil--add-to-alist evil-state-properties ',state plist)) - - ,@(when suppress-keymap - `((set-keymap-parent ,keymap evil-suppress-map))) - - (dolist (func ',entry-hook-value) (add-hook ',entry-hook func)) - (dolist (func ',exit-hook-value) (add-hook ',exit-hook func)) - - (defun ,predicate (&optional state) - ,(format "Whether the current state is %s. -\(That is, whether `evil-state' is `%s'.)" name state) - (and evil-local-mode - (eq (or state evil-state) ',state))) - - ;; define state function - (defun ,toggle (&optional arg) - ,(format "Enable %s. Disable with negative ARG. -If ARG is nil, don't display a message in the echo area.%s" name doc) - (interactive) - (cond - ((and (numberp arg) (< arg 1)) - (setq evil-previous-state evil-state - evil-state nil) - (let ((evil-state ',state)) - (run-hooks ',exit-hook) - (setq evil-state nil) - (evil-normalize-keymaps) - ,@body)) - (t - (unless evil-local-mode (evil-local-mode)) - (let ((evil-next-state ',state) - input-method-activate-hook input-method-deactivate-hook) - (evil-change-state nil) - (setq evil-state ',state) - (evil--add-to-alist evil-previous-state-alist - ',state evil-previous-state) - (let ((evil-state ',state)) - (evil-normalize-keymaps) - (if ',input-method - (activate-input-method evil-input-method) - ;; BUG #475: Deactivate the current input method only - ;; if there is a function to deactivate it, otherwise - ;; an error would be raised. This strange situation - ;; should not arise in general and there should - ;; probably be a better way to handle this situation. - (when deactivate-current-input-method-function - (deactivate-input-method))) - (unless evil-no-display - (when (eq (window-buffer) (current-buffer)) - (evil-refresh-cursor ',state)) - (evil-refresh-mode-line ',state)) - ,@body - (run-hooks ',entry-hook) - (when (and evil-echo-state - arg (not evil-no-display) ,message) - (if (functionp ,message) - (funcall ,message) - (evil-echo "%s" ,message)))))))) - - (evil-add-command-properties ',toggle :keep-visual t :suppress-operator t) - - (evil-define-keymap ,keymap nil - :mode ,mode - :func nil) - - (evil-define-keymap ,local-keymap nil - :mode ,local - :local t - :func nil) - - ',state))) - -(provide 'evil-core) - -;;; evil-core.el ends here diff --git a/.config/emacs/lisp/evil/evil-development.el b/.config/emacs/lisp/evil/evil-development.el deleted file mode 100644 index 60da92d..0000000 --- a/.config/emacs/lisp/evil/evil-development.el +++ /dev/null @@ -1,50 +0,0 @@ -;;; evil-development.el --- Useful features for Evil developers -*- lexical-binding: t -*- - -;; Author: Justin Burkett <justin at burkett dot cc> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -;;; Teach imenu about evil macros - -(with-eval-after-load 'lisp-mode - (when (boundp 'lisp-imenu-generic-expression) - (dolist (macro '("interactive-code" - "type" - "text-object" - "motion" - "command" - "operator")) - (let ((macro-name (format "evil-%s" macro))) - (unless (assoc macro-name lisp-imenu-generic-expression) - (push (list - macro-name - (format "^\\s-*(evil-define-%s\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" - macro) - 1) - lisp-imenu-generic-expression)))))) - -(provide 'evil-development) - -;;; evil-development.el ends here diff --git a/.config/emacs/lisp/evil/evil-digraphs.el b/.config/emacs/lisp/evil/evil-digraphs.el deleted file mode 100644 index 2bd3687..0000000 --- a/.config/emacs/lisp/evil/evil-digraphs.el +++ /dev/null @@ -1,1735 +0,0 @@ -;;; evil-digraphs.el --- Digraphs -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(require 'evil-vars) - -(defgroup evil-digraphs nil - "Digraph support based on RFC 1345." - :group 'evil - :prefix "evil-digraph-") - -(defcustom evil-digraphs-table-user nil - "List of user-defined digraphs. -Entries have the form ((?CHAR1 ?CHAR2) . ?DIGRAPH). That is, -a cons cell of the digraph and its character replacement, -where the digraph is a list of two characters. -See also `evil-digraphs-table'." - :type '(alist :key-type (list character character) - :value-type character)) - -(defconst evil-digraphs-table - '(((?N ?U) . ?\x00) - ((?S ?H) . ?\x01) - ((?S ?X) . ?\x02) - ((?E ?X) . ?\x03) - ((?E ?T) . ?\x04) - ((?E ?Q) . ?\x05) - ((?A ?K) . ?\x06) - ((?B ?L) . ?\x07) - ((?B ?S) . ?\x08) - ((?H ?T) . ?\x09) - ((?L ?F) . ?\x0a) - ((?V ?T) . ?\x0b) - ((?F ?F) . ?\x0c) - ((?C ?R) . ?\x0d) - ((?S ?O) . ?\x0e) - ((?S ?I) . ?\x0f) - ((?D ?L) . ?\x10) - ((?D ?1) . ?\x11) - ((?D ?2) . ?\x12) - ((?D ?3) . ?\x13) - ((?D ?4) . ?\x14) - ((?N ?K) . ?\x15) - ((?S ?Y) . ?\x16) - ((?E ?B) . ?\x17) - ((?C ?N) . ?\x18) - ((?E ?M) . ?\x19) - ((?S ?B) . ?\x1a) - ((?E ?C) . ?\x1b) - ((?F ?S) . ?\x1c) - ((?G ?S) . ?\x1d) - ((?R ?S) . ?\x1e) - ((?U ?S) . ?\x1f) - ((?S ?P) . ?\x20) - ((?N ?b) . ?\x23) - ((?D ?O) . ?\x24) - ((?A ?t) . ?\x40) - ((?< ?\() . ?\x5b) - ((?/ ?/) . ?\x5c) - ((?\) ?>) . ?\x5d) - ((?' ?>) . ?\x5e) - ((?' ?!) . ?\x60) - ((?\( ?!) . ?\x7b) - ((?! ?!) . ?\x7c) - ((?! ?\)) . ?\x7d) - ((?' ??) . ?\x7e) - ((?D ?T) . ?\x7f) - ((?P ?A) . ?\x80) - ((?H ?O) . ?\x81) - ((?B ?H) . ?\x82) - ((?N ?H) . ?\x83) - ((?I ?N) . ?\x84) - ((?N ?L) . ?\x85) - ((?S ?A) . ?\x86) - ((?E ?S) . ?\x87) - ((?H ?S) . ?\x88) - ((?H ?J) . ?\x89) - ((?V ?S) . ?\x8a) - ((?P ?D) . ?\x8b) - ((?P ?U) . ?\x8c) - ((?R ?I) . ?\x8d) - ((?S ?2) . ?\x8e) - ((?S ?3) . ?\x8f) - ((?D ?C) . ?\x90) - ((?P ?1) . ?\x91) - ((?P ?2) . ?\x92) - ((?T ?S) . ?\x93) - ((?C ?C) . ?\x94) - ((?M ?W) . ?\x95) - ((?S ?G) . ?\x96) - ((?E ?G) . ?\x97) - ((?S ?S) . ?\x98) - ((?G ?C) . ?\x99) - ((?S ?C) . ?\x9a) - ((?C ?I) . ?\x9b) - ((?S ?T) . ?\x9c) - ((?O ?C) . ?\x9d) - ((?P ?M) . ?\x9e) - ((?A ?C) . ?\x9f) - ((?N ?S) . ?\xa0) - ((?! ?I) . ?\xa1) - ((?C ?t) . ?\xa2) - ((?P ?d) . ?\xa3) - ((?C ?u) . ?\xa4) - ((?Y ?e) . ?\xa5) - ((?B ?B) . ?\xa6) - ((?S ?E) . ?\xa7) - ((?' ?:) . ?\xa8) - ((?C ?o) . ?\xa9) - ((?- ?a) . ?\xaa) - ((?< ?<) . ?\xab) - ((?N ?O) . ?\xac) - ((?- ?-) . ?\xad) - ((?R ?g) . ?\xae) - ((?' ?m) . ?\xaf) - ((?D ?G) . ?\xb0) - ((?+ ?-) . ?\xb1) - ((?2 ?S) . ?\xb2) - ((?3 ?S) . ?\xb3) - ((?' ?') . ?\xb4) - ((?M ?y) . ?\xb5) - ((?P ?I) . ?\xb6) - ((?. ?M) . ?\xb7) - ((?' ?,) . ?\xb8) - ((?1 ?S) . ?\xb9) - ((?- ?o) . ?\xba) - ((?> ?>) . ?\xbb) - ((?1 ?4) . ?\xbc) - ((?1 ?2) . ?\xbd) - ((?3 ?4) . ?\xbe) - ((?? ?I) . ?\xbf) - ((?A ?!) . ?\xc0) - ((?A ?') . ?\xc1) - ((?A ?>) . ?\xc2) - ((?A ??) . ?\xc3) - ((?A ?:) . ?\xc4) - ((?A ?A) . ?\xc5) - ((?A ?E) . ?\xc6) - ((?C ?,) . ?\xc7) - ((?E ?!) . ?\xc8) - ((?E ?') . ?\xc9) - ((?E ?>) . ?\xca) - ((?E ?:) . ?\xcb) - ((?I ?!) . ?\xcc) - ((?I ?') . ?\xcd) - ((?I ?>) . ?\xce) - ((?I ?:) . ?\xcf) - ((?D ?-) . ?\xd0) - ((?N ??) . ?\xd1) - ((?O ?!) . ?\xd2) - ((?O ?') . ?\xd3) - ((?O ?>) . ?\xd4) - ((?O ??) . ?\xd5) - ((?O ?:) . ?\xd6) - ((?* ?X) . ?\xd7) - ((?O ?/) . ?\xd8) - ((?U ?!) . ?\xd9) - ((?U ?') . ?\xda) - ((?U ?>) . ?\xdb) - ((?U ?:) . ?\xdc) - ((?Y ?') . ?\xdd) - ((?T ?H) . ?\xde) - ((?s ?s) . ?\xdf) - ((?a ?!) . ?\xe0) - ((?a ?') . ?\xe1) - ((?a ?>) . ?\xe2) - ((?a ??) . ?\xe3) - ((?a ?:) . ?\xe4) - ((?a ?a) . ?\xe5) - ((?a ?e) . ?\xe6) - ((?c ?,) . ?\xe7) - ((?e ?!) . ?\xe8) - ((?e ?') . ?\xe9) - ((?e ?>) . ?\xea) - ((?e ?:) . ?\xeb) - ((?i ?!) . ?\xec) - ((?i ?') . ?\xed) - ((?i ?>) . ?\xee) - ((?i ?:) . ?\xef) - ((?d ?-) . ?\xf0) - ((?n ??) . ?\xf1) - ((?o ?!) . ?\xf2) - ((?o ?') . ?\xf3) - ((?o ?>) . ?\xf4) - ((?o ??) . ?\xf5) - ((?o ?:) . ?\xf6) - ((?- ?:) . ?\xf7) - ((?o ?/) . ?\xf8) - ((?u ?!) . ?\xf9) - ((?u ?') . ?\xfa) - ((?u ?>) . ?\xfb) - ((?u ?:) . ?\xfc) - ((?y ?') . ?\xfd) - ((?t ?h) . ?\xfe) - ((?y ?:) . ?\xff) - ((?A ?-) . ?\x0100) - ((?a ?-) . ?\x0101) - ((?A ?\() . ?\x0102) - ((?a ?\() . ?\x0103) - ((?A ?\;) . ?\x0104) - ((?a ?\;) . ?\x0105) - ((?C ?') . ?\x0106) - ((?c ?') . ?\x0107) - ((?C ?>) . ?\x0108) - ((?c ?>) . ?\x0109) - ((?C ?.) . ?\x010a) - ((?c ?.) . ?\x010b) - ((?C ?<) . ?\x010c) - ((?c ?<) . ?\x010d) - ((?D ?<) . ?\x010e) - ((?d ?<) . ?\x010f) - ((?D ?/) . ?\x0110) - ((?d ?/) . ?\x0111) - ((?E ?-) . ?\x0112) - ((?e ?-) . ?\x0113) - ((?E ?\() . ?\x0114) - ((?e ?\() . ?\x0115) - ((?E ?.) . ?\x0116) - ((?e ?.) . ?\x0117) - ((?E ?\;) . ?\x0118) - ((?e ?\;) . ?\x0119) - ((?E ?<) . ?\x011a) - ((?e ?<) . ?\x011b) - ((?G ?>) . ?\x011c) - ((?g ?>) . ?\x011d) - ((?G ?\() . ?\x011e) - ((?g ?\() . ?\x011f) - ((?G ?.) . ?\x0120) - ((?g ?.) . ?\x0121) - ((?G ?,) . ?\x0122) - ((?g ?,) . ?\x0123) - ((?H ?>) . ?\x0124) - ((?h ?>) . ?\x0125) - ((?H ?/) . ?\x0126) - ((?h ?/) . ?\x0127) - ((?I ??) . ?\x0128) - ((?i ??) . ?\x0129) - ((?I ?-) . ?\x012a) - ((?i ?-) . ?\x012b) - ((?I ?\() . ?\x012c) - ((?i ?\() . ?\x012d) - ((?I ?\;) . ?\x012e) - ((?i ?\;) . ?\x012f) - ((?I ?.) . ?\x0130) - ((?i ?.) . ?\x0131) - ((?I ?J) . ?\x0132) - ((?i ?j) . ?\x0133) - ((?J ?>) . ?\x0134) - ((?j ?>) . ?\x0135) - ((?K ?,) . ?\x0136) - ((?k ?,) . ?\x0137) - ((?k ?k) . ?\x0138) - ((?L ?') . ?\x0139) - ((?l ?') . ?\x013a) - ((?L ?,) . ?\x013b) - ((?l ?,) . ?\x013c) - ((?L ?<) . ?\x013d) - ((?l ?<) . ?\x013e) - ((?L ?.) . ?\x013f) - ((?l ?.) . ?\x0140) - ((?L ?/) . ?\x0141) - ((?l ?/) . ?\x0142) - ((?N ?') . ?\x0143) - ((?n ?') . ?\x0144) - ((?N ?,) . ?\x0145) - ((?n ?,) . ?\x0146) - ((?N ?<) . ?\x0147) - ((?n ?<) . ?\x0148) - ((?' ?n) . ?\x0149) - ((?N ?G) . ?\x014a) - ((?n ?g) . ?\x014b) - ((?O ?-) . ?\x014c) - ((?o ?-) . ?\x014d) - ((?O ?\() . ?\x014e) - ((?o ?\() . ?\x014f) - ((?O ?\") . ?\x0150) - ((?o ?\") . ?\x0151) - ((?O ?E) . ?\x0152) - ((?o ?e) . ?\x0153) - ((?R ?') . ?\x0154) - ((?r ?') . ?\x0155) - ((?R ?,) . ?\x0156) - ((?r ?,) . ?\x0157) - ((?R ?<) . ?\x0158) - ((?r ?<) . ?\x0159) - ((?S ?') . ?\x015a) - ((?s ?') . ?\x015b) - ((?S ?>) . ?\x015c) - ((?s ?>) . ?\x015d) - ((?S ?,) . ?\x015e) - ((?s ?,) . ?\x015f) - ((?S ?<) . ?\x0160) - ((?s ?<) . ?\x0161) - ((?T ?,) . ?\x0162) - ((?t ?,) . ?\x0163) - ((?T ?<) . ?\x0164) - ((?t ?<) . ?\x0165) - ((?T ?/) . ?\x0166) - ((?t ?/) . ?\x0167) - ((?U ??) . ?\x0168) - ((?u ??) . ?\x0169) - ((?U ?-) . ?\x016a) - ((?u ?-) . ?\x016b) - ((?U ?\() . ?\x016c) - ((?u ?\() . ?\x016d) - ((?U ?0) . ?\x016e) - ((?u ?0) . ?\x016f) - ((?U ?\") . ?\x0170) - ((?u ?\") . ?\x0171) - ((?U ?\;) . ?\x0172) - ((?u ?\;) . ?\x0173) - ((?W ?>) . ?\x0174) - ((?w ?>) . ?\x0175) - ((?Y ?>) . ?\x0176) - ((?y ?>) . ?\x0177) - ((?Y ?:) . ?\x0178) - ((?Z ?') . ?\x0179) - ((?z ?') . ?\x017a) - ((?Z ?.) . ?\x017b) - ((?z ?.) . ?\x017c) - ((?Z ?<) . ?\x017d) - ((?z ?<) . ?\x017e) - ((?O ?9) . ?\x01a0) - ((?o ?9) . ?\x01a1) - ((?O ?I) . ?\x01a2) - ((?o ?i) . ?\x01a3) - ((?y ?r) . ?\x01a6) - ((?U ?9) . ?\x01af) - ((?u ?9) . ?\x01b0) - ((?Z ?/) . ?\x01b5) - ((?z ?/) . ?\x01b6) - ((?E ?D) . ?\x01b7) - ((?A ?<) . ?\x01cd) - ((?a ?<) . ?\x01ce) - ((?I ?<) . ?\x01cf) - ((?i ?<) . ?\x01d0) - ((?O ?<) . ?\x01d1) - ((?o ?<) . ?\x01d2) - ((?U ?<) . ?\x01d3) - ((?u ?<) . ?\x01d4) - ((?A ?1) . ?\x01de) - ((?a ?1) . ?\x01df) - ((?A ?7) . ?\x01e0) - ((?a ?7) . ?\x01e1) - ((?A ?3) . ?\x01e2) - ((?a ?3) . ?\x01e3) - ((?G ?/) . ?\x01e4) - ((?g ?/) . ?\x01e5) - ((?G ?<) . ?\x01e6) - ((?g ?<) . ?\x01e7) - ((?K ?<) . ?\x01e8) - ((?k ?<) . ?\x01e9) - ((?O ?\;) . ?\x01ea) - ((?o ?\;) . ?\x01eb) - ((?O ?1) . ?\x01ec) - ((?o ?1) . ?\x01ed) - ((?E ?Z) . ?\x01ee) - ((?e ?z) . ?\x01ef) - ((?j ?<) . ?\x01f0) - ((?G ?') . ?\x01f4) - ((?g ?') . ?\x01f5) - ((?\; ?S) . ?\x02bf) - ((?' ?<) . ?\x02c7) - ((?' ?\() . ?\x02d8) - ((?' ?.) . ?\x02d9) - ((?' ?0) . ?\x02da) - ((?' ?\;) . ?\x02db) - ((?' ?\") . ?\x02dd) - ((?A ?%) . ?\x0386) - ((?E ?%) . ?\x0388) - ((?Y ?%) . ?\x0389) - ((?I ?%) . ?\x038a) - ((?O ?%) . ?\x038c) - ((?U ?%) . ?\x038e) - ((?W ?%) . ?\x038f) - ((?i ?3) . ?\x0390) - ((?A ?*) . ?\x0391) - ((?B ?*) . ?\x0392) - ((?G ?*) . ?\x0393) - ((?D ?*) . ?\x0394) - ((?E ?*) . ?\x0395) - ((?Z ?*) . ?\x0396) - ((?Y ?*) . ?\x0397) - ((?H ?*) . ?\x0398) - ((?I ?*) . ?\x0399) - ((?K ?*) . ?\x039a) - ((?L ?*) . ?\x039b) - ((?M ?*) . ?\x039c) - ((?N ?*) . ?\x039d) - ((?C ?*) . ?\x039e) - ((?O ?*) . ?\x039f) - ((?P ?*) . ?\x03a0) - ((?R ?*) . ?\x03a1) - ((?S ?*) . ?\x03a3) - ((?T ?*) . ?\x03a4) - ((?U ?*) . ?\x03a5) - ((?F ?*) . ?\x03a6) - ((?X ?*) . ?\x03a7) - ((?Q ?*) . ?\x03a8) - ((?W ?*) . ?\x03a9) - ((?J ?*) . ?\x03aa) - ((?V ?*) . ?\x03ab) - ((?a ?%) . ?\x03ac) - ((?e ?%) . ?\x03ad) - ((?y ?%) . ?\x03ae) - ((?i ?%) . ?\x03af) - ((?u ?3) . ?\x03b0) - ((?a ?*) . ?\x03b1) - ((?b ?*) . ?\x03b2) - ((?g ?*) . ?\x03b3) - ((?d ?*) . ?\x03b4) - ((?e ?*) . ?\x03b5) - ((?z ?*) . ?\x03b6) - ((?y ?*) . ?\x03b7) - ((?h ?*) . ?\x03b8) - ((?i ?*) . ?\x03b9) - ((?k ?*) . ?\x03ba) - ((?l ?*) . ?\x03bb) - ((?m ?*) . ?\x03bc) - ((?n ?*) . ?\x03bd) - ((?c ?*) . ?\x03be) - ((?o ?*) . ?\x03bf) - ((?p ?*) . ?\x03c0) - ((?r ?*) . ?\x03c1) - ((?* ?s) . ?\x03c2) - ((?s ?*) . ?\x03c3) - ((?t ?*) . ?\x03c4) - ((?u ?*) . ?\x03c5) - ((?f ?*) . ?\x03c6) - ((?x ?*) . ?\x03c7) - ((?q ?*) . ?\x03c8) - ((?w ?*) . ?\x03c9) - ((?j ?*) . ?\x03ca) - ((?v ?*) . ?\x03cb) - ((?o ?%) . ?\x03cc) - ((?u ?%) . ?\x03cd) - ((?w ?%) . ?\x03ce) - ((?' ?G) . ?\x03d8) - ((?, ?G) . ?\x03d9) - ((?T ?3) . ?\x03da) - ((?t ?3) . ?\x03db) - ((?M ?3) . ?\x03dc) - ((?m ?3) . ?\x03dd) - ((?K ?3) . ?\x03de) - ((?k ?3) . ?\x03df) - ((?P ?3) . ?\x03e0) - ((?p ?3) . ?\x03e1) - ((?' ?%) . ?\x03f4) - ((?j ?3) . ?\x03f5) - ((?I ?O) . ?\x0401) - ((?D ?%) . ?\x0402) - ((?G ?%) . ?\x0403) - ((?I ?E) . ?\x0404) - ((?D ?S) . ?\x0405) - ((?I ?I) . ?\x0406) - ((?Y ?I) . ?\x0407) - ((?J ?%) . ?\x0408) - ((?L ?J) . ?\x0409) - ((?N ?J) . ?\x040a) - ((?T ?s) . ?\x040b) - ((?K ?J) . ?\x040c) - ((?V ?%) . ?\x040e) - ((?D ?Z) . ?\x040f) - ((?A ?=) . ?\x0410) - ((?B ?=) . ?\x0411) - ((?V ?=) . ?\x0412) - ((?G ?=) . ?\x0413) - ((?D ?=) . ?\x0414) - ((?E ?=) . ?\x0415) - ((?Z ?%) . ?\x0416) - ((?Z ?=) . ?\x0417) - ((?I ?=) . ?\x0418) - ((?J ?=) . ?\x0419) - ((?K ?=) . ?\x041a) - ((?L ?=) . ?\x041b) - ((?M ?=) . ?\x041c) - ((?N ?=) . ?\x041d) - ((?O ?=) . ?\x041e) - ((?P ?=) . ?\x041f) - ((?R ?=) . ?\x0420) - ((?S ?=) . ?\x0421) - ((?T ?=) . ?\x0422) - ((?U ?=) . ?\x0423) - ((?F ?=) . ?\x0424) - ((?H ?=) . ?\x0425) - ((?C ?=) . ?\x0426) - ((?C ?%) . ?\x0427) - ((?S ?%) . ?\x0428) - ((?S ?c) . ?\x0429) - ((?= ?\") . ?\x042a) - ((?Y ?=) . ?\x042b) - ((?% ?\") . ?\x042c) - ((?J ?E) . ?\x042d) - ((?J ?U) . ?\x042e) - ((?J ?A) . ?\x042f) - ((?a ?=) . ?\x0430) - ((?b ?=) . ?\x0431) - ((?v ?=) . ?\x0432) - ((?g ?=) . ?\x0433) - ((?d ?=) . ?\x0434) - ((?e ?=) . ?\x0435) - ((?z ?%) . ?\x0436) - ((?z ?=) . ?\x0437) - ((?i ?=) . ?\x0438) - ((?j ?=) . ?\x0439) - ((?k ?=) . ?\x043a) - ((?l ?=) . ?\x043b) - ((?m ?=) . ?\x043c) - ((?n ?=) . ?\x043d) - ((?o ?=) . ?\x043e) - ((?p ?=) . ?\x043f) - ((?r ?=) . ?\x0440) - ((?s ?=) . ?\x0441) - ((?t ?=) . ?\x0442) - ((?u ?=) . ?\x0443) - ((?f ?=) . ?\x0444) - ((?h ?=) . ?\x0445) - ((?c ?=) . ?\x0446) - ((?c ?%) . ?\x0447) - ((?s ?%) . ?\x0448) - ((?s ?c) . ?\x0449) - ((?= ?') . ?\x044a) - ((?y ?=) . ?\x044b) - ((?% ?') . ?\x044c) - ((?j ?e) . ?\x044d) - ((?j ?u) . ?\x044e) - ((?j ?a) . ?\x044f) - ((?i ?o) . ?\x0451) - ((?d ?%) . ?\x0452) - ((?g ?%) . ?\x0453) - ((?i ?e) . ?\x0454) - ((?d ?s) . ?\x0455) - ((?i ?i) . ?\x0456) - ((?y ?i) . ?\x0457) - ((?j ?%) . ?\x0458) - ((?l ?j) . ?\x0459) - ((?n ?j) . ?\x045a) - ((?t ?s) . ?\x045b) - ((?k ?j) . ?\x045c) - ((?v ?%) . ?\x045e) - ((?d ?z) . ?\x045f) - ((?Y ?3) . ?\x0462) - ((?y ?3) . ?\x0463) - ((?O ?3) . ?\x046a) - ((?o ?3) . ?\x046b) - ((?F ?3) . ?\x0472) - ((?f ?3) . ?\x0473) - ((?V ?3) . ?\x0474) - ((?v ?3) . ?\x0475) - ((?C ?3) . ?\x0480) - ((?c ?3) . ?\x0481) - ((?G ?3) . ?\x0490) - ((?g ?3) . ?\x0491) - ((?A ?+) . ?\x05d0) - ((?B ?+) . ?\x05d1) - ((?G ?+) . ?\x05d2) - ((?D ?+) . ?\x05d3) - ((?H ?+) . ?\x05d4) - ((?W ?+) . ?\x05d5) - ((?Z ?+) . ?\x05d6) - ((?X ?+) . ?\x05d7) - ((?T ?j) . ?\x05d8) - ((?J ?+) . ?\x05d9) - ((?K ?%) . ?\x05da) - ((?K ?+) . ?\x05db) - ((?L ?+) . ?\x05dc) - ((?M ?%) . ?\x05dd) - ((?M ?+) . ?\x05de) - ((?N ?%) . ?\x05df) - ((?N ?+) . ?\x05e0) - ((?S ?+) . ?\x05e1) - ((?E ?+) . ?\x05e2) - ((?P ?%) . ?\x05e3) - ((?P ?+) . ?\x05e4) - ((?Z ?j) . ?\x05e5) - ((?Z ?J) . ?\x05e6) - ((?Q ?+) . ?\x05e7) - ((?R ?+) . ?\x05e8) - ((?S ?h) . ?\x05e9) - ((?T ?+) . ?\x05ea) - ((?, ?+) . ?\x060c) - ((?\; ?+) . ?\x061b) - ((?? ?+) . ?\x061f) - ((?H ?') . ?\x0621) - ((?a ?M) . ?\x0622) - ((?a ?H) . ?\x0623) - ((?w ?H) . ?\x0624) - ((?a ?h) . ?\x0625) - ((?y ?H) . ?\x0626) - ((?a ?+) . ?\x0627) - ((?b ?+) . ?\x0628) - ((?t ?m) . ?\x0629) - ((?t ?+) . ?\x062a) - ((?t ?k) . ?\x062b) - ((?g ?+) . ?\x062c) - ((?h ?k) . ?\x062d) - ((?x ?+) . ?\x062e) - ((?d ?+) . ?\x062f) - ((?d ?k) . ?\x0630) - ((?r ?+) . ?\x0631) - ((?z ?+) . ?\x0632) - ((?s ?+) . ?\x0633) - ((?s ?n) . ?\x0634) - ((?c ?+) . ?\x0635) - ((?d ?d) . ?\x0636) - ((?t ?j) . ?\x0637) - ((?z ?H) . ?\x0638) - ((?e ?+) . ?\x0639) - ((?i ?+) . ?\x063a) - ((?+ ?+) . ?\x0640) - ((?f ?+) . ?\x0641) - ((?q ?+) . ?\x0642) - ((?k ?+) . ?\x0643) - ((?l ?+) . ?\x0644) - ((?m ?+) . ?\x0645) - ((?n ?+) . ?\x0646) - ((?h ?+) . ?\x0647) - ((?w ?+) . ?\x0648) - ((?j ?+) . ?\x0649) - ((?y ?+) . ?\x064a) - ((?: ?+) . ?\x064b) - ((?\" ?+) . ?\x064c) - ((?= ?+) . ?\x064d) - ((?/ ?+) . ?\x064e) - ((?' ?+) . ?\x064f) - ((?1 ?+) . ?\x0650) - ((?3 ?+) . ?\x0651) - ((?0 ?+) . ?\x0652) - ((?a ?S) . ?\x0670) - ((?p ?+) . ?\x067e) - ((?v ?+) . ?\x06a4) - ((?g ?f) . ?\x06af) - ((?0 ?a) . ?\x06f0) - ((?1 ?a) . ?\x06f1) - ((?2 ?a) . ?\x06f2) - ((?3 ?a) . ?\x06f3) - ((?4 ?a) . ?\x06f4) - ((?5 ?a) . ?\x06f5) - ((?6 ?a) . ?\x06f6) - ((?7 ?a) . ?\x06f7) - ((?8 ?a) . ?\x06f8) - ((?9 ?a) . ?\x06f9) - ((?B ?.) . ?\x1e02) - ((?b ?.) . ?\x1e03) - ((?B ?_) . ?\x1e06) - ((?b ?_) . ?\x1e07) - ((?D ?.) . ?\x1e0a) - ((?d ?.) . ?\x1e0b) - ((?D ?_) . ?\x1e0e) - ((?d ?_) . ?\x1e0f) - ((?D ?,) . ?\x1e10) - ((?d ?,) . ?\x1e11) - ((?F ?.) . ?\x1e1e) - ((?f ?.) . ?\x1e1f) - ((?G ?-) . ?\x1e20) - ((?g ?-) . ?\x1e21) - ((?H ?.) . ?\x1e22) - ((?h ?.) . ?\x1e23) - ((?H ?:) . ?\x1e26) - ((?h ?:) . ?\x1e27) - ((?H ?,) . ?\x1e28) - ((?h ?,) . ?\x1e29) - ((?K ?') . ?\x1e30) - ((?k ?') . ?\x1e31) - ((?K ?_) . ?\x1e34) - ((?k ?_) . ?\x1e35) - ((?L ?_) . ?\x1e3a) - ((?l ?_) . ?\x1e3b) - ((?M ?') . ?\x1e3e) - ((?m ?') . ?\x1e3f) - ((?M ?.) . ?\x1e40) - ((?m ?.) . ?\x1e41) - ((?N ?.) . ?\x1e44) - ((?n ?.) . ?\x1e45) - ((?N ?_) . ?\x1e48) - ((?n ?_) . ?\x1e49) - ((?P ?') . ?\x1e54) - ((?p ?') . ?\x1e55) - ((?P ?.) . ?\x1e56) - ((?p ?.) . ?\x1e57) - ((?R ?.) . ?\x1e58) - ((?r ?.) . ?\x1e59) - ((?R ?_) . ?\x1e5e) - ((?r ?_) . ?\x1e5f) - ((?S ?.) . ?\x1e60) - ((?s ?.) . ?\x1e61) - ((?T ?.) . ?\x1e6a) - ((?t ?.) . ?\x1e6b) - ((?T ?_) . ?\x1e6e) - ((?t ?_) . ?\x1e6f) - ((?V ??) . ?\x1e7c) - ((?v ??) . ?\x1e7d) - ((?W ?!) . ?\x1e80) - ((?W ?`) . ?\x1e80) - ((?w ?!) . ?\x1e81) - ((?w ?`) . ?\x1e81) - ((?W ?') . ?\x1e82) - ((?w ?') . ?\x1e83) - ((?W ?:) . ?\x1e84) - ((?w ?:) . ?\x1e85) - ((?W ?.) . ?\x1e86) - ((?w ?.) . ?\x1e87) - ((?X ?.) . ?\x1e8a) - ((?x ?.) . ?\x1e8b) - ((?X ?:) . ?\x1e8c) - ((?x ?:) . ?\x1e8d) - ((?Y ?.) . ?\x1e8e) - ((?y ?.) . ?\x1e8f) - ((?Z ?>) . ?\x1e90) - ((?z ?>) . ?\x1e91) - ((?Z ?_) . ?\x1e94) - ((?z ?_) . ?\x1e95) - ((?h ?_) . ?\x1e96) - ((?t ?:) . ?\x1e97) - ((?w ?0) . ?\x1e98) - ((?y ?0) . ?\x1e99) - ((?A ?2) . ?\x1ea2) - ((?a ?2) . ?\x1ea3) - ((?E ?2) . ?\x1eba) - ((?e ?2) . ?\x1ebb) - ((?E ??) . ?\x1ebc) - ((?e ??) . ?\x1ebd) - ((?I ?2) . ?\x1ec8) - ((?i ?2) . ?\x1ec9) - ((?O ?2) . ?\x1ece) - ((?o ?2) . ?\x1ecf) - ((?U ?2) . ?\x1ee6) - ((?u ?2) . ?\x1ee7) - ((?Y ?!) . ?\x1ef2) - ((?Y ?`) . ?\x1ef2) - ((?y ?!) . ?\x1ef3) - ((?y ?`) . ?\x1ef3) - ((?Y ?2) . ?\x1ef6) - ((?y ?2) . ?\x1ef7) - ((?Y ??) . ?\x1ef8) - ((?y ??) . ?\x1ef9) - ((?\; ?') . ?\x1f00) - ((?, ?') . ?\x1f01) - ((?\; ?!) . ?\x1f02) - ((?, ?!) . ?\x1f03) - ((?? ?\;) . ?\x1f04) - ((?? ?,) . ?\x1f05) - ((?! ?:) . ?\x1f06) - ((?? ?:) . ?\x1f07) - ((?1 ?N) . ?\x2002) - ((?1 ?M) . ?\x2003) - ((?3 ?M) . ?\x2004) - ((?4 ?M) . ?\x2005) - ((?6 ?M) . ?\x2006) - ((?1 ?T) . ?\x2009) - ((?1 ?H) . ?\x200a) - ((?- ?1) . ?\x2010) - ((?- ?N) . ?\x2013) - ((?- ?M) . ?\x2014) - ((?- ?3) . ?\x2015) - ((?! ?2) . ?\x2016) - ((?= ?2) . ?\x2017) - ((?' ?6) . ?\x2018) - ((?' ?9) . ?\x2019) - ((?. ?9) . ?\x201a) - ((?9 ?') . ?\x201b) - ((?\" ?6) . ?\x201c) - ((?\" ?9) . ?\x201d) - ((?: ?9) . ?\x201e) - ((?9 ?\") . ?\x201f) - ((?/ ?-) . ?\x2020) - ((?/ ?=) . ?\x2021) - ((?o ?o) . ?\x2022) - ((?. ?.) . ?\x2025) - ((?, ?.) . ?\x2026) - ((?% ?0) . ?\x2030) - ((?1 ?') . ?\x2032) - ((?2 ?') . ?\x2033) - ((?3 ?') . ?\x2034) - ((?1 ?\") . ?\x2035) - ((?2 ?\") . ?\x2036) - ((?3 ?\") . ?\x2037) - ((?C ?a) . ?\x2038) - ((?< ?1) . ?\x2039) - ((?> ?1) . ?\x203a) - ((?: ?X) . ?\x203b) - ((?' ?-) . ?\x203e) - ((?/ ?f) . ?\x2044) - ((?0 ?S) . ?\x2070) - ((?4 ?S) . ?\x2074) - ((?5 ?S) . ?\x2075) - ((?6 ?S) . ?\x2076) - ((?7 ?S) . ?\x2077) - ((?8 ?S) . ?\x2078) - ((?9 ?S) . ?\x2079) - ((?+ ?S) . ?\x207a) - ((?- ?S) . ?\x207b) - ((?= ?S) . ?\x207c) - ((?\( ?S) . ?\x207d) - ((?\) ?S) . ?\x207e) - ((?n ?S) . ?\x207f) - ((?0 ?s) . ?\x2080) - ((?1 ?s) . ?\x2081) - ((?2 ?s) . ?\x2082) - ((?3 ?s) . ?\x2083) - ((?4 ?s) . ?\x2084) - ((?5 ?s) . ?\x2085) - ((?6 ?s) . ?\x2086) - ((?7 ?s) . ?\x2087) - ((?8 ?s) . ?\x2088) - ((?9 ?s) . ?\x2089) - ((?+ ?s) . ?\x208a) - ((?- ?s) . ?\x208b) - ((?= ?s) . ?\x208c) - ((?\( ?s) . ?\x208d) - ((?\) ?s) . ?\x208e) - ((?L ?i) . ?\x20a4) - ((?P ?t) . ?\x20a7) - ((?W ?=) . ?\x20a9) - ((?= ?e) . ?\x20ac) - ((?E ?u) . ?\x20ac) - ((?= ?R) . ?\x20bd) - ((?= ?P) . ?\x20bd) - ((?o ?C) . ?\x2103) - ((?c ?o) . ?\x2105) - ((?o ?F) . ?\x2109) - ((?N ?0) . ?\x2116) - ((?P ?O) . ?\x2117) - ((?R ?x) . ?\x211e) - ((?S ?M) . ?\x2120) - ((?T ?M) . ?\x2122) - ((?O ?m) . ?\x2126) - ((?A ?O) . ?\x212b) - ((?1 ?3) . ?\x2153) - ((?2 ?3) . ?\x2154) - ((?1 ?5) . ?\x2155) - ((?2 ?5) . ?\x2156) - ((?3 ?5) . ?\x2157) - ((?4 ?5) . ?\x2158) - ((?1 ?6) . ?\x2159) - ((?5 ?6) . ?\x215a) - ((?1 ?8) . ?\x215b) - ((?3 ?8) . ?\x215c) - ((?5 ?8) . ?\x215d) - ((?7 ?8) . ?\x215e) - ((?1 ?R) . ?\x2160) - ((?2 ?R) . ?\x2161) - ((?3 ?R) . ?\x2162) - ((?4 ?R) . ?\x2163) - ((?5 ?R) . ?\x2164) - ((?6 ?R) . ?\x2165) - ((?7 ?R) . ?\x2166) - ((?8 ?R) . ?\x2167) - ((?9 ?R) . ?\x2168) - ((?a ?R) . ?\x2169) - ((?b ?R) . ?\x216a) - ((?c ?R) . ?\x216b) - ((?1 ?r) . ?\x2170) - ((?2 ?r) . ?\x2171) - ((?3 ?r) . ?\x2172) - ((?4 ?r) . ?\x2173) - ((?5 ?r) . ?\x2174) - ((?6 ?r) . ?\x2175) - ((?7 ?r) . ?\x2176) - ((?8 ?r) . ?\x2177) - ((?9 ?r) . ?\x2178) - ((?a ?r) . ?\x2179) - ((?b ?r) . ?\x217a) - ((?c ?r) . ?\x217b) - ((?< ?-) . ?\x2190) - ((?- ?!) . ?\x2191) - ((?- ?>) . ?\x2192) - ((?- ?v) . ?\x2193) - ((?< ?>) . ?\x2194) - ((?U ?D) . ?\x2195) - ((?< ?=) . ?\x21d0) - ((?= ?>) . ?\x21d2) - ((?= ?=) . ?\x21d4) - ((?F ?A) . ?\x2200) - ((?d ?P) . ?\x2202) - ((?T ?E) . ?\x2203) - ((?/ ?0) . ?\x2205) - ((?D ?E) . ?\x2206) - ((?N ?B) . ?\x2207) - ((?\( ?-) . ?\x2208) - ((?- ?\)) . ?\x220b) - ((?* ?P) . ?\x220f) - ((?+ ?Z) . ?\x2211) - ((?- ?2) . ?\x2212) - ((?- ?+) . ?\x2213) - ((?* ?-) . ?\x2217) - ((?O ?b) . ?\x2218) - ((?S ?b) . ?\x2219) - ((?R ?T) . ?\x221a) - ((?0 ?\() . ?\x221d) - ((?0 ?0) . ?\x221e) - ((?- ?L) . ?\x221f) - ((?- ?V) . ?\x2220) - ((?P ?P) . ?\x2225) - ((?A ?N) . ?\x2227) - ((?O ?R) . ?\x2228) - ((?\( ?U) . ?\x2229) - ((?\) ?U) . ?\x222a) - ((?I ?n) . ?\x222b) - ((?D ?I) . ?\x222c) - ((?I ?o) . ?\x222e) - ((?. ?:) . ?\x2234) - ((?: ?.) . ?\x2235) - ((?: ?R) . ?\x2236) - ((?: ?:) . ?\x2237) - ((?? ?1) . ?\x223c) - ((?C ?G) . ?\x223e) - ((?? ?-) . ?\x2243) - ((?? ?=) . ?\x2245) - ((?? ?2) . ?\x2248) - ((?= ??) . ?\x224c) - ((?H ?I) . ?\x2253) - ((?! ?=) . ?\x2260) - ((?= ?3) . ?\x2261) - ((?= ?<) . ?\x2264) - ((?> ?=) . ?\x2265) - ((?< ?*) . ?\x226a) - ((?* ?>) . ?\x226b) - ((?! ?<) . ?\x226e) - ((?! ?>) . ?\x226f) - ((?\( ?C) . ?\x2282) - ((?\) ?C) . ?\x2283) - ((?\( ?_) . ?\x2286) - ((?\) ?_) . ?\x2287) - ((?0 ?.) . ?\x2299) - ((?0 ?2) . ?\x229a) - ((?- ?T) . ?\x22a5) - ((?. ?P) . ?\x22c5) - ((?: ?3) . ?\x22ee) - ((?. ?3) . ?\x22ef) - ((?E ?h) . ?\x2302) - ((?< ?7) . ?\x2308) - ((?> ?7) . ?\x2309) - ((?7 ?<) . ?\x230a) - ((?7 ?>) . ?\x230b) - ((?N ?I) . ?\x2310) - ((?\( ?A) . ?\x2312) - ((?T ?R) . ?\x2315) - ((?I ?u) . ?\x2320) - ((?I ?l) . ?\x2321) - ((?< ?/) . ?\x2329) - ((?/ ?>) . ?\x232a) - ((?V ?s) . ?\x2423) - ((?1 ?h) . ?\x2440) - ((?3 ?h) . ?\x2441) - ((?2 ?h) . ?\x2442) - ((?4 ?h) . ?\x2443) - ((?1 ?j) . ?\x2446) - ((?2 ?j) . ?\x2447) - ((?3 ?j) . ?\x2448) - ((?4 ?j) . ?\x2449) - ((?1 ?.) . ?\x2488) - ((?2 ?.) . ?\x2489) - ((?3 ?.) . ?\x248a) - ((?4 ?.) . ?\x248b) - ((?5 ?.) . ?\x248c) - ((?6 ?.) . ?\x248d) - ((?7 ?.) . ?\x248e) - ((?8 ?.) . ?\x248f) - ((?9 ?.) . ?\x2490) - ((?h ?h) . ?\x2500) - ((?H ?H) . ?\x2501) - ((?v ?v) . ?\x2502) - ((?V ?V) . ?\x2503) - ((?3 ?-) . ?\x2504) - ((?3 ?_) . ?\x2505) - ((?3 ?!) . ?\x2506) - ((?3 ?/) . ?\x2507) - ((?4 ?-) . ?\x2508) - ((?4 ?_) . ?\x2509) - ((?4 ?!) . ?\x250a) - ((?4 ?/) . ?\x250b) - ((?d ?r) . ?\x250c) - ((?d ?R) . ?\x250d) - ((?D ?r) . ?\x250e) - ((?D ?R) . ?\x250f) - ((?d ?l) . ?\x2510) - ((?d ?L) . ?\x2511) - ((?D ?l) . ?\x2512) - ((?L ?D) . ?\x2513) - ((?u ?r) . ?\x2514) - ((?u ?R) . ?\x2515) - ((?U ?r) . ?\x2516) - ((?U ?R) . ?\x2517) - ((?u ?l) . ?\x2518) - ((?u ?L) . ?\x2519) - ((?U ?l) . ?\x251a) - ((?U ?L) . ?\x251b) - ((?v ?r) . ?\x251c) - ((?v ?R) . ?\x251d) - ((?V ?r) . ?\x2520) - ((?V ?R) . ?\x2523) - ((?v ?l) . ?\x2524) - ((?v ?L) . ?\x2525) - ((?V ?l) . ?\x2528) - ((?V ?L) . ?\x252b) - ((?d ?h) . ?\x252c) - ((?d ?H) . ?\x252f) - ((?D ?h) . ?\x2530) - ((?D ?H) . ?\x2533) - ((?u ?h) . ?\x2534) - ((?u ?H) . ?\x2537) - ((?U ?h) . ?\x2538) - ((?U ?H) . ?\x253b) - ((?v ?h) . ?\x253c) - ((?v ?H) . ?\x253f) - ((?V ?h) . ?\x2542) - ((?V ?H) . ?\x254b) - ((?F ?D) . ?\x2571) - ((?B ?D) . ?\x2572) - ((?T ?B) . ?\x2580) - ((?L ?B) . ?\x2584) - ((?F ?B) . ?\x2588) - ((?l ?B) . ?\x258c) - ((?R ?B) . ?\x2590) - ((?. ?S) . ?\x2591) - ((?: ?S) . ?\x2592) - ((?? ?S) . ?\x2593) - ((?f ?S) . ?\x25a0) - ((?O ?S) . ?\x25a1) - ((?R ?O) . ?\x25a2) - ((?R ?r) . ?\x25a3) - ((?R ?F) . ?\x25a4) - ((?R ?Y) . ?\x25a5) - ((?R ?H) . ?\x25a6) - ((?R ?Z) . ?\x25a7) - ((?R ?K) . ?\x25a8) - ((?R ?X) . ?\x25a9) - ((?s ?B) . ?\x25aa) - ((?S ?R) . ?\x25ac) - ((?O ?r) . ?\x25ad) - ((?U ?T) . ?\x25b2) - ((?u ?T) . ?\x25b3) - ((?P ?R) . ?\x25b6) - ((?T ?r) . ?\x25b7) - ((?D ?t) . ?\x25bc) - ((?d ?T) . ?\x25bd) - ((?P ?L) . ?\x25c0) - ((?T ?l) . ?\x25c1) - ((?D ?b) . ?\x25c6) - ((?D ?w) . ?\x25c7) - ((?L ?Z) . ?\x25ca) - ((?0 ?m) . ?\x25cb) - ((?0 ?o) . ?\x25ce) - ((?0 ?M) . ?\x25cf) - ((?0 ?L) . ?\x25d0) - ((?0 ?R) . ?\x25d1) - ((?S ?n) . ?\x25d8) - ((?I ?c) . ?\x25d9) - ((?F ?d) . ?\x25e2) - ((?B ?d) . ?\x25e3) - ((?* ?2) . ?\x2605) - ((?* ?1) . ?\x2606) - ((?< ?H) . ?\x261c) - ((?> ?H) . ?\x261e) - ((?0 ?u) . ?\x263a) - ((?0 ?U) . ?\x263b) - ((?S ?U) . ?\x263c) - ((?F ?m) . ?\x2640) - ((?M ?l) . ?\x2642) - ((?c ?S) . ?\x2660) - ((?c ?H) . ?\x2661) - ((?c ?D) . ?\x2662) - ((?c ?C) . ?\x2663) - ((?M ?d) . ?\x2669) - ((?M ?8) . ?\x266a) - ((?M ?2) . ?\x266b) - ((?M ?b) . ?\x266d) - ((?M ?x) . ?\x266e) - ((?M ?X) . ?\x266f) - ((?O ?K) . ?\x2713) - ((?X ?X) . ?\x2717) - ((?- ?X) . ?\x2720) - ((?I ?S) . ?\x3000) - ((?, ?_) . ?\x3001) - ((?. ?_) . ?\x3002) - ((?+ ?\") . ?\x3003) - ((?+ ?_) . ?\x3004) - ((?* ?_) . ?\x3005) - ((?\; ?_) . ?\x3006) - ((?0 ?_) . ?\x3007) - ((?< ?+) . ?\x300a) - ((?> ?+) . ?\x300b) - ((?< ?') . ?\x300c) - ((?> ?') . ?\x300d) - ((?< ?\") . ?\x300e) - ((?> ?\") . ?\x300f) - ((?\( ?\") . ?\x3010) - ((?\) ?\") . ?\x3011) - ((?= ?T) . ?\x3012) - ((?= ?_) . ?\x3013) - ((?\( ?') . ?\x3014) - ((?\) ?') . ?\x3015) - ((?\( ?I) . ?\x3016) - ((?\) ?I) . ?\x3017) - ((?- ??) . ?\x301c) - ((?A ?5) . ?\x3041) - ((?a ?5) . ?\x3042) - ((?I ?5) . ?\x3043) - ((?i ?5) . ?\x3044) - ((?U ?5) . ?\x3045) - ((?u ?5) . ?\x3046) - ((?E ?5) . ?\x3047) - ((?e ?5) . ?\x3048) - ((?O ?5) . ?\x3049) - ((?o ?5) . ?\x304a) - ((?k ?a) . ?\x304b) - ((?g ?a) . ?\x304c) - ((?k ?i) . ?\x304d) - ((?g ?i) . ?\x304e) - ((?k ?u) . ?\x304f) - ((?g ?u) . ?\x3050) - ((?k ?e) . ?\x3051) - ((?g ?e) . ?\x3052) - ((?k ?o) . ?\x3053) - ((?g ?o) . ?\x3054) - ((?s ?a) . ?\x3055) - ((?z ?a) . ?\x3056) - ((?s ?i) . ?\x3057) - ((?z ?i) . ?\x3058) - ((?s ?u) . ?\x3059) - ((?z ?u) . ?\x305a) - ((?s ?e) . ?\x305b) - ((?z ?e) . ?\x305c) - ((?s ?o) . ?\x305d) - ((?z ?o) . ?\x305e) - ((?t ?a) . ?\x305f) - ((?d ?a) . ?\x3060) - ((?t ?i) . ?\x3061) - ((?d ?i) . ?\x3062) - ((?t ?U) . ?\x3063) - ((?t ?u) . ?\x3064) - ((?d ?u) . ?\x3065) - ((?t ?e) . ?\x3066) - ((?d ?e) . ?\x3067) - ((?t ?o) . ?\x3068) - ((?d ?o) . ?\x3069) - ((?n ?a) . ?\x306a) - ((?n ?i) . ?\x306b) - ((?n ?u) . ?\x306c) - ((?n ?e) . ?\x306d) - ((?n ?o) . ?\x306e) - ((?h ?a) . ?\x306f) - ((?b ?a) . ?\x3070) - ((?p ?a) . ?\x3071) - ((?h ?i) . ?\x3072) - ((?b ?i) . ?\x3073) - ((?p ?i) . ?\x3074) - ((?h ?u) . ?\x3075) - ((?b ?u) . ?\x3076) - ((?p ?u) . ?\x3077) - ((?h ?e) . ?\x3078) - ((?b ?e) . ?\x3079) - ((?p ?e) . ?\x307a) - ((?h ?o) . ?\x307b) - ((?b ?o) . ?\x307c) - ((?p ?o) . ?\x307d) - ((?m ?a) . ?\x307e) - ((?m ?i) . ?\x307f) - ((?m ?u) . ?\x3080) - ((?m ?e) . ?\x3081) - ((?m ?o) . ?\x3082) - ((?y ?A) . ?\x3083) - ((?y ?a) . ?\x3084) - ((?y ?U) . ?\x3085) - ((?y ?u) . ?\x3086) - ((?y ?O) . ?\x3087) - ((?y ?o) . ?\x3088) - ((?r ?a) . ?\x3089) - ((?r ?i) . ?\x308a) - ((?r ?u) . ?\x308b) - ((?r ?e) . ?\x308c) - ((?r ?o) . ?\x308d) - ((?w ?A) . ?\x308e) - ((?w ?a) . ?\x308f) - ((?w ?i) . ?\x3090) - ((?w ?e) . ?\x3091) - ((?w ?o) . ?\x3092) - ((?n ?5) . ?\x3093) - ((?v ?u) . ?\x3094) - ((?\" ?5) . ?\x309b) - ((?0 ?5) . ?\x309c) - ((?* ?5) . ?\x309d) - ((?+ ?5) . ?\x309e) - ((?a ?6) . ?\x30a1) - ((?A ?6) . ?\x30a2) - ((?i ?6) . ?\x30a3) - ((?I ?6) . ?\x30a4) - ((?u ?6) . ?\x30a5) - ((?U ?6) . ?\x30a6) - ((?e ?6) . ?\x30a7) - ((?E ?6) . ?\x30a8) - ((?o ?6) . ?\x30a9) - ((?O ?6) . ?\x30aa) - ((?K ?a) . ?\x30ab) - ((?G ?a) . ?\x30ac) - ((?K ?i) . ?\x30ad) - ((?G ?i) . ?\x30ae) - ((?K ?u) . ?\x30af) - ((?G ?u) . ?\x30b0) - ((?K ?e) . ?\x30b1) - ((?G ?e) . ?\x30b2) - ((?K ?o) . ?\x30b3) - ((?G ?o) . ?\x30b4) - ((?S ?a) . ?\x30b5) - ((?Z ?a) . ?\x30b6) - ((?S ?i) . ?\x30b7) - ((?Z ?i) . ?\x30b8) - ((?S ?u) . ?\x30b9) - ((?Z ?u) . ?\x30ba) - ((?S ?e) . ?\x30bb) - ((?Z ?e) . ?\x30bc) - ((?S ?o) . ?\x30bd) - ((?Z ?o) . ?\x30be) - ((?T ?a) . ?\x30bf) - ((?D ?a) . ?\x30c0) - ((?T ?i) . ?\x30c1) - ((?D ?i) . ?\x30c2) - ((?T ?U) . ?\x30c3) - ((?T ?u) . ?\x30c4) - ((?D ?u) . ?\x30c5) - ((?T ?e) . ?\x30c6) - ((?D ?e) . ?\x30c7) - ((?T ?o) . ?\x30c8) - ((?D ?o) . ?\x30c9) - ((?N ?a) . ?\x30ca) - ((?N ?i) . ?\x30cb) - ((?N ?u) . ?\x30cc) - ((?N ?e) . ?\x30cd) - ((?N ?o) . ?\x30ce) - ((?H ?a) . ?\x30cf) - ((?B ?a) . ?\x30d0) - ((?P ?a) . ?\x30d1) - ((?H ?i) . ?\x30d2) - ((?B ?i) . ?\x30d3) - ((?P ?i) . ?\x30d4) - ((?H ?u) . ?\x30d5) - ((?B ?u) . ?\x30d6) - ((?P ?u) . ?\x30d7) - ((?H ?e) . ?\x30d8) - ((?B ?e) . ?\x30d9) - ((?P ?e) . ?\x30da) - ((?H ?o) . ?\x30db) - ((?B ?o) . ?\x30dc) - ((?P ?o) . ?\x30dd) - ((?u ?R) . ?\x2515) - ((?U ?r) . ?\x2516) - ((?U ?R) . ?\x2517) - ((?u ?l) . ?\x2518) - ((?u ?L) . ?\x2519) - ((?U ?l) . ?\x251a) - ((?U ?L) . ?\x251b) - ((?v ?r) . ?\x251c) - ((?v ?R) . ?\x251d) - ((?V ?r) . ?\x2520) - ((?V ?R) . ?\x2523) - ((?v ?l) . ?\x2524) - ((?v ?L) . ?\x2525) - ((?V ?l) . ?\x2528) - ((?V ?L) . ?\x252b) - ((?d ?h) . ?\x252c) - ((?d ?H) . ?\x252f) - ((?D ?h) . ?\x2530) - ((?D ?H) . ?\x2533) - ((?u ?h) . ?\x2534) - ((?u ?H) . ?\x2537) - ((?U ?h) . ?\x2538) - ((?U ?H) . ?\x253b) - ((?v ?h) . ?\x253c) - ((?v ?H) . ?\x253f) - ((?V ?h) . ?\x2542) - ((?V ?H) . ?\x254b) - ((?F ?D) . ?\x2571) - ((?B ?D) . ?\x2572) - ((?T ?B) . ?\x2580) - ((?L ?B) . ?\x2584) - ((?F ?B) . ?\x2588) - ((?l ?B) . ?\x258c) - ((?R ?B) . ?\x2590) - ((?. ?S) . ?\x2591) - ((?: ?S) . ?\x2592) - ((?? ?S) . ?\x2593) - ((?f ?S) . ?\x25a0) - ((?O ?S) . ?\x25a1) - ((?R ?O) . ?\x25a2) - ((?R ?r) . ?\x25a3) - ((?R ?F) . ?\x25a4) - ((?R ?Y) . ?\x25a5) - ((?R ?H) . ?\x25a6) - ((?R ?Z) . ?\x25a7) - ((?R ?K) . ?\x25a8) - ((?R ?X) . ?\x25a9) - ((?s ?B) . ?\x25aa) - ((?S ?R) . ?\x25ac) - ((?O ?r) . ?\x25ad) - ((?U ?T) . ?\x25b2) - ((?u ?T) . ?\x25b3) - ((?P ?R) . ?\x25b6) - ((?T ?r) . ?\x25b7) - ((?D ?t) . ?\x25bc) - ((?d ?T) . ?\x25bd) - ((?P ?L) . ?\x25c0) - ((?T ?l) . ?\x25c1) - ((?D ?b) . ?\x25c6) - ((?D ?w) . ?\x25c7) - ((?L ?Z) . ?\x25ca) - ((?0 ?m) . ?\x25cb) - ((?0 ?o) . ?\x25ce) - ((?0 ?M) . ?\x25cf) - ((?0 ?L) . ?\x25d0) - ((?0 ?R) . ?\x25d1) - ((?S ?n) . ?\x25d8) - ((?I ?c) . ?\x25d9) - ((?F ?d) . ?\x25e2) - ((?B ?d) . ?\x25e3) - ((?* ?2) . ?\x2605) - ((?* ?1) . ?\x2606) - ((?< ?H) . ?\x261c) - ((?> ?H) . ?\x261e) - ((?0 ?u) . ?\x263a) - ((?0 ?U) . ?\x263b) - ((?S ?U) . ?\x263c) - ((?F ?m) . ?\x2640) - ((?M ?l) . ?\x2642) - ((?c ?S) . ?\x2660) - ((?c ?H) . ?\x2661) - ((?c ?D) . ?\x2662) - ((?c ?C) . ?\x2663) - ((?M ?d) . ?\x2669) - ((?M ?8) . ?\x266a) - ((?M ?2) . ?\x266b) - ((?M ?b) . ?\x266d) - ((?M ?x) . ?\x266e) - ((?M ?X) . ?\x266f) - ((?O ?K) . ?\x2713) - ((?X ?X) . ?\x2717) - ((?- ?X) . ?\x2720) - ((?I ?S) . ?\x3000) - ((?, ?_) . ?\x3001) - ((?. ?_) . ?\x3002) - ((?+ ?\") . ?\x3003) - ((?+ ?_) . ?\x3004) - ((?* ?_) . ?\x3005) - ((?\; ?_) . ?\x3006) - ((?0 ?_) . ?\x3007) - ((?< ?+) . ?\x300a) - ((?> ?+) . ?\x300b) - ((?< ?') . ?\x300c) - ((?> ?') . ?\x300d) - ((?< ?\") . ?\x300e) - ((?> ?\") . ?\x300f) - ((?\( ?\") . ?\x3010) - ((?\) ?\") . ?\x3011) - ((?= ?T) . ?\x3012) - ((?= ?_) . ?\x3013) - ((?\( ?') . ?\x3014) - ((?\) ?') . ?\x3015) - ((?\( ?I) . ?\x3016) - ((?\) ?I) . ?\x3017) - ((?- ??) . ?\x301c) - ((?A ?5) . ?\x3041) - ((?a ?5) . ?\x3042) - ((?I ?5) . ?\x3043) - ((?i ?5) . ?\x3044) - ((?U ?5) . ?\x3045) - ((?u ?5) . ?\x3046) - ((?E ?5) . ?\x3047) - ((?e ?5) . ?\x3048) - ((?O ?5) . ?\x3049) - ((?o ?5) . ?\x304a) - ((?k ?a) . ?\x304b) - ((?g ?a) . ?\x304c) - ((?k ?i) . ?\x304d) - ((?g ?i) . ?\x304e) - ((?k ?u) . ?\x304f) - ((?g ?u) . ?\x3050) - ((?k ?e) . ?\x3051) - ((?g ?e) . ?\x3052) - ((?k ?o) . ?\x3053) - ((?g ?o) . ?\x3054) - ((?s ?a) . ?\x3055) - ((?z ?a) . ?\x3056) - ((?s ?i) . ?\x3057) - ((?z ?i) . ?\x3058) - ((?s ?u) . ?\x3059) - ((?z ?u) . ?\x305a) - ((?s ?e) . ?\x305b) - ((?z ?e) . ?\x305c) - ((?s ?o) . ?\x305d) - ((?z ?o) . ?\x305e) - ((?t ?a) . ?\x305f) - ((?d ?a) . ?\x3060) - ((?t ?i) . ?\x3061) - ((?d ?i) . ?\x3062) - ((?t ?U) . ?\x3063) - ((?t ?u) . ?\x3064) - ((?d ?u) . ?\x3065) - ((?t ?e) . ?\x3066) - ((?d ?e) . ?\x3067) - ((?t ?o) . ?\x3068) - ((?d ?o) . ?\x3069) - ((?n ?a) . ?\x306a) - ((?n ?i) . ?\x306b) - ((?n ?u) . ?\x306c) - ((?n ?e) . ?\x306d) - ((?n ?o) . ?\x306e) - ((?h ?a) . ?\x306f) - ((?b ?a) . ?\x3070) - ((?p ?a) . ?\x3071) - ((?h ?i) . ?\x3072) - ((?b ?i) . ?\x3073) - ((?p ?i) . ?\x3074) - ((?h ?u) . ?\x3075) - ((?b ?u) . ?\x3076) - ((?p ?u) . ?\x3077) - ((?h ?e) . ?\x3078) - ((?b ?e) . ?\x3079) - ((?p ?e) . ?\x307a) - ((?h ?o) . ?\x307b) - ((?b ?o) . ?\x307c) - ((?p ?o) . ?\x307d) - ((?m ?a) . ?\x307e) - ((?m ?i) . ?\x307f) - ((?m ?u) . ?\x3080) - ((?m ?e) . ?\x3081) - ((?m ?o) . ?\x3082) - ((?y ?A) . ?\x3083) - ((?y ?a) . ?\x3084) - ((?y ?U) . ?\x3085) - ((?y ?u) . ?\x3086) - ((?y ?O) . ?\x3087) - ((?y ?o) . ?\x3088) - ((?r ?a) . ?\x3089) - ((?r ?i) . ?\x308a) - ((?r ?u) . ?\x308b) - ((?r ?e) . ?\x308c) - ((?r ?o) . ?\x308d) - ((?w ?A) . ?\x308e) - ((?w ?a) . ?\x308f) - ((?w ?i) . ?\x3090) - ((?w ?e) . ?\x3091) - ((?w ?o) . ?\x3092) - ((?n ?5) . ?\x3093) - ((?v ?u) . ?\x3094) - ((?\" ?5) . ?\x309b) - ((?0 ?5) . ?\x309c) - ((?* ?5) . ?\x309d) - ((?+ ?5) . ?\x309e) - ((?a ?6) . ?\x30a1) - ((?A ?6) . ?\x30a2) - ((?i ?6) . ?\x30a3) - ((?I ?6) . ?\x30a4) - ((?u ?6) . ?\x30a5) - ((?U ?6) . ?\x30a6) - ((?e ?6) . ?\x30a7) - ((?E ?6) . ?\x30a8) - ((?o ?6) . ?\x30a9) - ((?O ?6) . ?\x30aa) - ((?K ?a) . ?\x30ab) - ((?G ?a) . ?\x30ac) - ((?K ?i) . ?\x30ad) - ((?G ?i) . ?\x30ae) - ((?K ?u) . ?\x30af) - ((?G ?u) . ?\x30b0) - ((?K ?e) . ?\x30b1) - ((?G ?e) . ?\x30b2) - ((?K ?o) . ?\x30b3) - ((?G ?o) . ?\x30b4) - ((?S ?a) . ?\x30b5) - ((?Z ?a) . ?\x30b6) - ((?S ?i) . ?\x30b7) - ((?Z ?i) . ?\x30b8) - ((?S ?u) . ?\x30b9) - ((?Z ?u) . ?\x30ba) - ((?S ?e) . ?\x30bb) - ((?Z ?e) . ?\x30bc) - ((?S ?o) . ?\x30bd) - ((?Z ?o) . ?\x30be) - ((?T ?a) . ?\x30bf) - ((?D ?a) . ?\x30c0) - ((?T ?i) . ?\x30c1) - ((?D ?i) . ?\x30c2) - ((?T ?U) . ?\x30c3) - ((?T ?u) . ?\x30c4) - ((?D ?u) . ?\x30c5) - ((?T ?e) . ?\x30c6) - ((?D ?e) . ?\x30c7) - ((?T ?o) . ?\x30c8) - ((?D ?o) . ?\x30c9) - ((?N ?a) . ?\x30ca) - ((?N ?i) . ?\x30cb) - ((?N ?u) . ?\x30cc) - ((?N ?e) . ?\x30cd) - ((?N ?o) . ?\x30ce) - ((?H ?a) . ?\x30cf) - ((?B ?a) . ?\x30d0) - ((?P ?a) . ?\x30d1) - ((?H ?i) . ?\x30d2) - ((?B ?i) . ?\x30d3) - ((?P ?i) . ?\x30d4) - ((?H ?u) . ?\x30d5) - ((?B ?u) . ?\x30d6) - ((?P ?u) . ?\x30d7) - ((?H ?e) . ?\x30d8) - ((?B ?e) . ?\x30d9) - ((?P ?e) . ?\x30da) - ((?H ?o) . ?\x30db) - ((?B ?o) . ?\x30dc) - ((?P ?o) . ?\x30dd) - ((?M ?a) . ?\x30de) - ((?M ?i) . ?\x30df) - ((?M ?u) . ?\x30e0) - ((?M ?e) . ?\x30e1) - ((?M ?o) . ?\x30e2) - ((?Y ?A) . ?\x30e3) - ((?Y ?a) . ?\x30e4) - ((?Y ?U) . ?\x30e5) - ((?Y ?u) . ?\x30e6) - ((?Y ?O) . ?\x30e7) - ((?Y ?o) . ?\x30e8) - ((?R ?a) . ?\x30e9) - ((?R ?i) . ?\x30ea) - ((?R ?u) . ?\x30eb) - ((?R ?e) . ?\x30ec) - ((?R ?o) . ?\x30ed) - ((?W ?A) . ?\x30ee) - ((?W ?a) . ?\x30ef) - ((?W ?i) . ?\x30f0) - ((?W ?e) . ?\x30f1) - ((?W ?o) . ?\x30f2) - ((?N ?6) . ?\x30f3) - ((?V ?u) . ?\x30f4) - ((?K ?A) . ?\x30f5) - ((?K ?E) . ?\x30f6) - ((?V ?a) . ?\x30f7) - ((?V ?i) . ?\x30f8) - ((?V ?e) . ?\x30f9) - ((?V ?o) . ?\x30fa) - ((?. ?6) . ?\x30fb) - ((?- ?6) . ?\x30fc) - ((?* ?6) . ?\x30fd) - ((?+ ?6) . ?\x30fe) - ((?b ?4) . ?\x3105) - ((?p ?4) . ?\x3106) - ((?m ?4) . ?\x3107) - ((?f ?4) . ?\x3108) - ((?d ?4) . ?\x3109) - ((?t ?4) . ?\x310a) - ((?n ?4) . ?\x310b) - ((?l ?4) . ?\x310c) - ((?g ?4) . ?\x310d) - ((?k ?4) . ?\x310e) - ((?h ?4) . ?\x310f) - ((?j ?4) . ?\x3110) - ((?q ?4) . ?\x3111) - ((?x ?4) . ?\x3112) - ((?z ?h) . ?\x3113) - ((?c ?h) . ?\x3114) - ((?s ?h) . ?\x3115) - ((?r ?4) . ?\x3116) - ((?z ?4) . ?\x3117) - ((?c ?4) . ?\x3118) - ((?s ?4) . ?\x3119) - ((?a ?4) . ?\x311a) - ((?o ?4) . ?\x311b) - ((?e ?4) . ?\x311c) - ((?a ?i) . ?\x311e) - ((?e ?i) . ?\x311f) - ((?a ?u) . ?\x3120) - ((?o ?u) . ?\x3121) - ((?a ?n) . ?\x3122) - ((?e ?n) . ?\x3123) - ((?a ?N) . ?\x3124) - ((?e ?N) . ?\x3125) - ((?e ?r) . ?\x3126) - ((?i ?4) . ?\x3127) - ((?u ?4) . ?\x3128) - ((?i ?u) . ?\x3129) - ((?v ?4) . ?\x312a) - ((?n ?G) . ?\x312b) - ((?g ?n) . ?\x312c) - ((?1 ?c) . ?\x3220) - ((?2 ?c) . ?\x3221) - ((?3 ?c) . ?\x3222) - ((?4 ?c) . ?\x3223) - ((?5 ?c) . ?\x3224) - ((?6 ?c) . ?\x3225) - ((?7 ?c) . ?\x3226) - ((?8 ?c) . ?\x3227) - ((?9 ?c) . ?\x3228) - ((?\s ?\s) . ?\xe000) - ((?/ ?c) . ?\xe001) - ((?U ?A) . ?\xe002) - ((?U ?B) . ?\xe003) - ((?\" ?3) . ?\xe004) - ((?\" ?1) . ?\xe005) - ((?\" ?!) . ?\xe006) - ((?\" ?') . ?\xe007) - ((?\" ?>) . ?\xe008) - ((?\" ??) . ?\xe009) - ((?\" ?-) . ?\xe00a) - ((?\" ?\() . ?\xe00b) - ((?\" ?.) . ?\xe00c) - ((?\" ?:) . ?\xe00d) - ((?\" ?0) . ?\xe00e) - ((?\" ?\") . ?\xe00f) - ((?\" ?<) . ?\xe010) - ((?\" ?,) . ?\xe011) - ((?\" ?\;) . ?\xe012) - ((?\" ?_) . ?\xe013) - ((?\" ?=) . ?\xe014) - ((?\" ?/) . ?\xe015) - ((?\" ?i) . ?\xe016) - ((?\" ?d) . ?\xe017) - ((?\" ?p) . ?\xe018) - ((?\; ?\;) . ?\xe019) - ((?, ?,) . ?\xe01a) - ((?b ?3) . ?\xe01b) - ((?C ?i) . ?\xe01c) - ((?f ?\() . ?\xe01d) - ((?e ?d) . ?\xe01e) - ((?a ?m) . ?\xe01f) - ((?p ?m) . ?\xe020) - ((?F ?l) . ?\xe023) - ((?G ?F) . ?\xe024) - ((?> ?V) . ?\xe025) - ((?! ?*) . ?\xe026) - ((?? ?*) . ?\xe027) - ((?J ?<) . ?\xe028) - ((?f ?f) . ?\xfb00) - ((?f ?i) . ?\xfb01) - ((?f ?l) . ?\xfb02) - ((?f ?t) . ?\xfb05) - ((?s ?t) . ?\xfb06) - ((?~ ?!) . ?\x00a1) - ((?c ?|) . ?\x00a2) - ((?$ ?$) . ?\x00a3) - ((?o ?x) . ?\x00a4) - ((?Y ?-) . ?\x00a5) - ((?| ?|) . ?\x00a6) - ((?c ?O) . ?\x00a9) - ((?- ?,) . ?\x00ac) - ((?- ?=) . ?\x00af) - ((?~ ?o) . ?\x00b0) - ((?2 ?2) . ?\x00b2) - ((?3 ?3) . ?\x00b3) - ((?p ?p) . ?\x00b6) - ((?~ ?.) . ?\x00b7) - ((?1 ?1) . ?\x00b9) - ((?~ ??) . ?\x00bf) - ((?A ?`) . ?\x00c0) - ((?A ?^) . ?\x00c2) - ((?A ?~) . ?\x00c3) - ((?A ?\") . ?\x00c4) - ((?A ?@) . ?\x00c5) - ((?E ?`) . ?\x00c8) - ((?E ?^) . ?\x00ca) - ((?E ?\") . ?\x00cb) - ((?I ?`) . ?\x00cc) - ((?I ?^) . ?\x00ce) - ((?I ?\") . ?\x00cf) - ((?N ?~) . ?\x00d1) - ((?O ?`) . ?\x00d2) - ((?O ?^) . ?\x00d4) - ((?O ?~) . ?\x00d5) - ((?/ ?\\) . ?\x00d7) - ((?U ?`) . ?\x00d9) - ((?U ?^) . ?\x00db) - ((?I ?p) . ?\x00de) - ((?a ?`) . ?\x00e0) - ((?a ?^) . ?\x00e2) - ((?a ?~) . ?\x00e3) - ((?a ?\") . ?\x00e4) - ((?a ?@) . ?\x00e5) - ((?e ?`) . ?\x00e8) - ((?e ?^) . ?\x00ea) - ((?e ?\") . ?\x00eb) - ((?i ?`) . ?\x00ec) - ((?i ?^) . ?\x00ee) - ((?n ?~) . ?\x00f1) - ((?o ?`) . ?\x00f2) - ((?o ?^) . ?\x00f4) - ((?o ?~) . ?\x00f5) - ((?u ?`) . ?\x00f9) - ((?u ?^) . ?\x00fb) - ((?y ?\") . ?\x00ff)) - "Table of default digraphs. -This includes all digraphs defined in RFC 1345, -as well as miscellaneous digraphs for multi-byte characters. -See also `evil-digraphs-table-user'.") - -;;;###autoload -(defun evil-digraph (digraph) - "Convert DIGRAPH to character or list representation. -If DIGRAPH is a list (CHAR1 CHAR2), return the corresponding character; -if DIGRAPH is a character, return the corresponding list. -Searches in `evil-digraphs-table-user' and `evil-digraphs-table'." - (if (listp digraph) - (or (cdr (assoc digraph evil-digraphs-table-user)) - (cdr (assoc digraph evil-digraphs-table)) - (cl-destructuring-bind (char1 char2) digraph - (unless (eq char1 char2) - (or (cdr (assoc (list char2 char1) evil-digraphs-table-user)) - (cdr (assoc (list char2 char1) evil-digraphs-table)))))) - (or (car (rassoc digraph evil-digraphs-table-user)) - (car (rassoc digraph evil-digraphs-table))))) - -(provide 'evil-digraphs) - -;;; evil-digraphs.el ends here diff --git a/.config/emacs/lisp/evil/evil-ex.el b/.config/emacs/lisp/evil/evil-ex.el deleted file mode 100644 index 94edd6e..0000000 --- a/.config/emacs/lisp/evil/evil-ex.el +++ /dev/null @@ -1,940 +0,0 @@ -;;; evil-ex.el --- Ex mode -*- lexical-binding: t; -*- - -;; Author: Frank Fischer <frank fischer at mathematik.tu-chemnitz.de> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; Ex is implemented as an extensible minilanguage, whose grammar -;; is stored in `evil-ex-grammar'. Ex commands are defined with -;; `evil-ex-define-cmd', which creates a binding from a string -;; to an interactive function. It is also possible to define key -;; sequences which execute a command immediately when entered: -;; such shortcuts go in `evil-ex-shortcut-map'. - -;; To provide buffer and filename completion, as well as interactive -;; feedback, Ex defines the concept of an argument handler, specified -;; with `evil-ex-define-argument-type'. In the case of the -;; substitution command (":s/foo/bar"), the handler incrementally -;; highlights matches in the buffer as the substitution is typed. - -;;; Code: - -(require 'evil-common) -(require 'evil-states) - -(declare-function evil-goto-line "evil-commands") - -(eval-when-compile - (defconst evil-ex-grammar - '((expression - (count command argument #'evil-ex-call-command) - ((\? range) command argument #'evil-ex-call-command) - (line #'evil-goto-line) - (sexp #'eval-expression)) - (count - number) - (command #'evil-ex-parse-command) - (binding - "[~&*@<>=:#]+\\|[[:alpha:]_]+\\|!") - (emacs-binding - "[[:alpha:]-][[:alnum:][:punct:]]*") - (argument - ((\? "\\(?:.\\|\n\\)+") #'$1)) - (range - ("%" #'(evil-ex-full-range)) - ("*" #'(evil-ex-last-visual-range)) - ((\? line) "[,;]" (\? line) - #'(let ((l1 $1)) - (save-excursion - (and l1 (string= $2 ";") (goto-line l1)) - (evil-ex-range l1 $3)))) - (line #'evil-ex-range) - ("`" marker-name ",`" marker-name - #'(evil-ex-char-marker-range $2 $4))) - (line - ((\? base) (\? offset) search (\? offset) - #'(save-excursion - (goto-line (evil-ex-line $1 $2)) - (evil-ex-line $3 $4))) - (base (\? offset) #'evil-ex-line) - (nil offset #'evil-ex-line)) - (base - number - ("'" marker-name #'(evil-ex-marker $2)) - search - ("\\^" #'(evil-ex-first-line)) - ("\\$" #'(evil-ex-last-line)) - ("\\." #'(evil-ex-current-line))) - (offset - (+ signed-number #'+)) - ;; TODO - handle offset & ;next-pattern search elements - (search - forward - backward - next - prev - subst) - (forward - ("/" "\\(?:\\\\.\\|[^/]\\)+" "/\\|$" #'(evil-ex-re-fwd $2))) - (backward - ("?" "\\(?:\\\\.\\|[^?]\\)+" "?\\|$" #'(evil-ex-re-bwd $2))) - (marker-name - "[]\\[-a-zA-Z_<>'}{)(]") - (next - "\\\\/" #'(evil-ex-prev-search)) - (prev - "\\\\\\?" #'(evil-ex-prev-search)) - (subst - "\\\\&" #'(evil-ex-prev-search)) - (signed-number - (sign (\? number) #'evil-ex-signed-number)) - (sign - "[+-]" #'intern) - (number - "[0-9]+" #'string-to-number) - (sexp - "(.*)?" #'(car (read-from-string $0)))) - "Grammar for Ex. -An association list of syntactic symbols and their definitions. -The first entry is the start symbol. A symbol's definition may -reference other symbols, but the grammar cannot contain -left recursion. See `evil-parser' for a detailed explanation -of the syntax.") - - (defun evil-parser--dexp (obj) - "Parse a numerical dollar-sign symbol. -Given e.g. $4, return 4." - (when (symbolp obj) - (let ((str (symbol-name obj))) - (when (string-match "\\`\\$\\([0-9]+\\)\\'" str) - (string-to-number (match-string 1 str)))))) - - (defmacro evil-parser (grammar &rest entrypoints) - "Construct a parser for GRAMMAR with ENTRYPOINTS. -The result is a function taking the arguments SYMBOL and SYNTAX, that -parses the text after point. SYMBOL should be one of ENTRYPOINTS. - -If parsing succeeds, point is moved to the end of the parsed text and -a 1-tuple (RESULT) is returned. Otherwise, the return value is nil. - -GRAMMAR is an association list of symbols and their definitions. -A definition is a list of production rules, which are tried in -succession. A production rule can be one of the following: - - nil matches the empty string. - A regular expression matches a substring. - A symbol matches a production for that symbol. - (X Y) matches X followed by Y. - (\\? X) matches zero or one of X. - (* X) matches zero or more of X. - (+ X) matches one or more of X. - (& X) matches X, but does not consume. - (! X) matches anything but X, but does not consume. - -Thus, a simple grammar may look like: - - ((plus \"\\\\+\") ; plus <- \"+\" - (minus \"-\") ; minus <- \"-\" - (operator plus minus)) ; operator <- plus / minus - -All input-consuming rules have a value. A regular expression evaluates -to the text matched, while a list evaluates to a list of values. -The value of a list may be overridden with a semantic action, which is -specified with a #\\='-quoted expression at the end: - - (X Y #\\='foo) - -The value of this rule is the result of calling foo with the values -of X and Y as arguments. Alternatively, the function call may be -specified explicitly: - - (X Y #\\='(foo $1 $2)) - -Here, $1 refers to X and $2 refers to Y. $0 refers to the whole list. -Dollar expressions can also be used directly: - - (X Y #\\='$1) - -This matches X followed by Y, but ignores the value of Y; -the value of the list is the same as the value of X. - -If the SYNTAX argument is non-nil, then all semantic actions -are ignored, and a syntax tree is constructed instead. The -syntax tree obeys the property that all the leaf nodes are -parts of the input string. Thus, by traversing the syntax tree, -one can determine how each character was parsed. - -The following symbols have reserved meanings within a grammar: -`\\?', `*', `+', `&', `!', `function', `alt', `seq' and nil." - (cl-labels - ;; Return code for parsing PRODUCTION. - ((compile - (production) - (pcase production - ('nil '(list (when syntax (point)))) ; Epsilon - ((and (pred stringp) regexp) ; Token - `(when (progn - (skip-chars-forward " \t\n\r") ; Ignore leading whitespace - (looking-at ,regexp)) - (goto-char (match-end 0)) - (list (if syntax (point) (match-string 0))))) - ((and (pred symbolp) symbol) ; Symbol - `(let ((result (,symbol syntax))) - (and syntax result (push ',symbol (car result))) - result)) - (`(function ,fun) ; Function - `(let ((result (funcall #',fun))) - (and syntax result (setcar result (point))) - result)) - ;; Positive lookahead - (`(& . ,rule) `(when ,(compile rule) ,(compile nil))) - ;; Negative lookahead - (`(! . ,rule) `(unless ,(compile rule) ,(compile nil))) - ;; Zero or one - (`(\? . ,(or `(,rule) rule)) (compile `(alt ,rule nil))) - ;; Zero or more - (`(* . ,rules) (compile `(alt (+ ,@rules) nil))) - ;; Lists - ((or `(,(and (or '+ 'alt 'seq) symbol) . ,rules) - (and (pred listp) rules (let symbol 'seq))) - (let ((func (unless (eq symbol 'alt) #'list))) - (pcase (when (> (length rules) 1) (car (last rules))) - (`(function ,x) (setq func x - rules (butlast rules)))) - `(let ((cell - ,(pcase symbol - ('+ ; One or more - (when (cdr rules) (error "Too many `+' rules")) - `(cl-loop for x = ,(compile (car rules)) - while x collect (car x) into result until (eobp) - finally return (when result (list result)))) - ('alt `(or ,@(mapcar #'compile rules))) - ('seq - (cl-loop - for rule in rules collect - (macroexp-let2 nil x (compile rule) - (if (memq (car-safe rule) '(& !)) x - `(when ,x (push (car ,x) result)))) - into items finally return - `(let ((pos (point)) result) - (if (and ,@items) (list (nreverse result)) - (goto-char pos) - nil))))))) - ;; Semantic action - (when (and ',func cell (not syntax)) - (setcar - cell - (let ((result (car cell))) - (ignore result) ; Suppress unused var warning - ,(pcase func - ;; Dollar expression - ((or (pred evil-parser--dexp) (pred listp)) - (dval func)) - ((pred symbolp) - `(,(if (eq symbol 'alt) #'list #'cons) #',func result)) - (_ (error "Invalid semantic action `%S'" func)))))) - cell))))) - ;; Substitute all dollar-sign symbols in X. - ;; Each dollar-sign symbol is replaced with the corresponding - ;; element in RESULT, so that $1 becomes the first element, etc. - ;; The special value $0 is substituted with the whole list RESULT. - (dval - (x) - (if (listp x) (cons #'list (mapcar #'dval x)) - (let ((num (evil-parser--dexp x))) - (cond ((null num) `',x) - ((eq num 0) 'result) - (t `(nth (1- ,num) result))))))) - `(lambda (symbol &optional syntax) - (cl-labels - (,@(cl-loop for (symbol . def) in (eval grammar t) collect - `(,symbol (syntax) ,(compile `(alt . ,def)))) - (evil-ex-parse-command - () - (let* ((result (binding nil)) - (command (car result))) - (cond - ((not result) nil) - ;; Check whether the parsed command is followed by a slash, - ;; dash or number and either the part before is NOT known to be - ;; a binding, or the complete string IS known to be a binding. - ((and (let ((ch (char-after))) - (and ch (or (memq ch '(?- ?/)) (<= ?0 ch ?9)))) - (or (evil-ex-binding - (concat command (buffer-substring (point) (point-max))) t) - (not (evil-ex-binding command t)))) - (backward-char (length command)) - (emacs-binding nil)) - ;; Parse a following "!" as bang only if the command - ;; has the property :ex-bang t. - ((when (eq (char-after) ?!) - (let ((binding (evil-ex-completed-binding command t))) - (and binding (evil-get-command-property binding :ex-bang)))) - (forward-char) - (setcar result (concat command "!")) - result) - (t result))))) - (pcase symbol - ,@(cl-loop for sym in entrypoints collect `(',sym ,(compile sym))) - (_ (error "Unknown entrypoint `%s'" symbol)))))))) - -(defvar evil-ex-argument-types nil - "Association list of argument handlers.") - -(defvar evil-ex-commands nil - "Association list of command bindings and functions.") - -(defvar evil-ex-reverse-range nil - "Whether the current Ex range was entered reversed.") - -(defvar evil--ex-cmd nil - "The current Ex command string.") - -(defvar evil--ex-argument-handler nil - "The argument handler for the current Ex command.") - -(defvar evil--ex-shortcut-command nil - "Interactive command to use instead of an Ex command.") - -(define-error 'evil-ex-error "Ex syntax error") - -(defun evil-ex-p () - "Return non-nil if currently in Ex state." - (when evil-ex-original-buffer t)) - -(evil-define-command evil-ex (&optional initial-input) - "Enter an Ex command. -The Ex command line is initialized with the value of INITIAL-INPUT. If -the command is called interactively the initial input depends on the -current state. In Normal state if a prefix count is given then the -initial input is \".,.+count\", otherwise it is empty. In Visual state -the initial input is the visual region '<,'> or `<,`>. The variable -`evil-ex-initial-input', if non-nil, is appended to the line." - :keep-visual t - :repeat abort - (interactive - (let ((s (concat - (cond - ((and (evil-visual-state-p) - evil-ex-visual-char-range - (memq (evil-visual-type) '(inclusive exclusive))) - "`<,`>") - ((evil-visual-state-p) "'<,'>") - (current-prefix-arg - (let ((arg (prefix-numeric-value current-prefix-arg))) - (cond ((< arg 0) (setq arg (1+ arg))) - ((> arg 0) (setq arg (1- arg)))) - (if (= arg 0) "." (format ".,.%+d" arg))))) - evil-ex-initial-input))) - (list (unless (string= s "") s)))) - (let ((buffer (current-buffer)) - (previous-command (when evil-want-empty-ex-last-command - (car evil-ex-history))) - s evil--ex-cmd evil--ex-argument-handler evil--ex-shortcut-command) - (minibuffer-with-setup-hook - (lambda () - (setq-local evil-ex-original-buffer buffer) - (evil-ex-setup) - (if initial-input (evil--ex-update) - (when previous-command - (add-hook 'pre-command-hook #'evil-ex-remove-default nil t)))) - (setq s (read-from-minibuffer - ":" - (or initial-input - (and previous-command (propertize previous-command 'face 'shadow))) - evil-ex-completion-map nil 'evil-ex-history))) - (if evil--ex-shortcut-command - (call-interactively evil--ex-shortcut-command) - (when (string= s "") (setq s previous-command)) - (unless (string= s "") (evil-ex-execute s))))) - -(defun evil-ex-execute (string) - "Execute STRING as an Ex command." - (eval (or (evil-ex-parse string) (signal 'evil-ex-error string)) t)) - -(defun evil-ex-parse (&optional string syntax entrypoint) - "Parse STRING as an Ex expression and return its evaluation tree. -If STRING is nil, parse the text after point instead. If SYNTAX is -non-nil, return a syntax tree instead. ENTRYPOINT is the start -symbol, which defaults to `expression'." - (if string - (with-temp-buffer - (insert string) - (goto-char (point-min)) - (evil-ex-parse nil syntax entrypoint)) - (let ((result (funcall (evil-parser evil-ex-grammar expression range) - (or entrypoint 'expression) syntax))) - (and result - ;; Disallow incomplete matches (ignore trailing WS) - (not (search-forward "[^ \t\n\r]" nil t)) - (car result))))) - -(defun evil-ex-delete-backward-char () - "Close the minibuffer if it is empty, otherwise call `delete-backward-char'." - (interactive) - (call-interactively - (if (< (minibuffer-prompt-end) (point-max)) - #'delete-backward-char - #'abort-recursive-edit))) - -(cl-defstruct (evil-ex-argument-handler (:type list) (:constructor nil) - (:copier nil) (:predicate nil)) - (runner nil :read-only t) (completer nil :read-only t)) - -(defun evil-ex-setup () - "Initialize Ex minibuffer. -This function registers hooks that are used for the interactive -actions during Ex state." - (add-hook 'after-change-functions #'evil--ex-update nil t) - (add-hook 'minibuffer-exit-hook #'evil-ex-teardown nil t) - (add-hook 'completion-at-point-functions #'evil-ex-completion-at-point nil t)) - -(defsubst evil--ex-bang-p (command) - "Return non-nil if the string COMMAND has a \"!\" suffix." - (and (> (length command) 1) (eq (aref command (1- (length command))) ?!))) - -(defun evil--ex-update (&optional beg _end _old-len) - "Update Ex variables when the minibuffer changes. -This function is usually called from `after-change-functions' -hook. If BEG is non-nil (which is the case when called from -`after-change-functions'), then an error description is shown -in case of incomplete or unknown commands." - (when (and beg (eq this-command #'self-insert-command)) - (let ((cmd (lookup-key evil-ex-shortcut-map (minibuffer-contents-no-properties)))) - (when (commandp cmd) - (setq evil--ex-shortcut-command cmd) - (exit-minibuffer)))) - - (setq evil--ex-cmd nil) - (let ((expr (save-excursion (goto-char (minibuffer-prompt-end)) - (evil-ex-parse))) - func handler current-prefix-arg evil-ex-range evil-ex-bang evil-ex-argument) - (when (eq (car expr) #'evil-ex-call-command) - (with-current-buffer evil-ex-original-buffer - (let* ((range (eval (nth 1 expr) t)) - (count (when (integerp range) range))) - (setq current-prefix-arg count - evil-ex-range (if count (evil-ex-range count count) range) - evil--ex-cmd (eval (nth 2 expr) t) - evil-ex-bang (evil--ex-bang-p evil--ex-cmd) - evil-ex-argument (eval (nth 3 expr) t)))) - (cond - ((not beg)) - ;; Test the current command when called from `after-change-functions' - ((setq func (evil-ex-completed-binding evil--ex-cmd t)) - ;; Update argument handler - (let ((type (evil-get-command-property func :ex-arg))) - (when type (setq handler (cdr (assq type evil-ex-argument-types))))) - (if (eq handler evil--ex-argument-handler) - (let ((runner (evil-ex-argument-handler-runner handler))) - (when runner (funcall runner 'update evil-ex-argument))) - (let ((runner (evil-ex-argument-handler-runner evil--ex-argument-handler))) - (when runner (funcall runner 'stop))) - (setq evil--ex-argument-handler handler) - (let ((runner (evil-ex-argument-handler-runner handler))) - (when runner (funcall runner 'start evil-ex-argument))))) - (t (let* ((evil-ex-complete-emacs-commands 'in-turn) - (prefix (try-completion evil--ex-cmd (evil-ex-completion-table)))) - (cond ((stringp prefix) (evil-ex-echo "Incomplete command")) - ((null prefix) (evil-ex-echo "Unknown command"))))))))) - -(defun evil-ex-teardown () - "Deinitialize Ex minibuffer. -Clean up everything set up by `evil-ex-setup'." - (let ((runner (evil-ex-argument-handler-runner evil--ex-argument-handler))) - (when runner (funcall runner 'stop)))) - -(defvar-local evil--ex-echo-overlay nil - "Overlay for displaying info messages during Ex.") - -(defun evil-ex-echo (string &rest args) - "Display a message after the current Ex command." - ;; Differs from minibuffer-message, which see, in that it does not - ;; use sit-for, since it may be called in the middle of a command. - (unless (or evil-no-display (zerop (length string))) - (let ((string (concat " [" (apply #'format string args) "]"))) - (put-text-property 0 1 'cursor t string) ; Place cursor before message - (put-text-property 1 (length string) 'face 'evil-ex-info string) - (with-selected-window (minibuffer-window) - (if evil--ex-echo-overlay - (move-overlay evil--ex-echo-overlay (point-max) (point-max)) - (setq evil--ex-echo-overlay (make-overlay (point-max) (point-max) nil t t))) - (add-hook 'pre-command-hook #'evil--ex-remove-echo-overlay nil t) - (overlay-put evil--ex-echo-overlay 'after-string string))))) - -(defun evil--ex-remove-echo-overlay () - "Remove echo overlay from Ex minibuffer." - (delete-overlay evil--ex-echo-overlay) - (setq evil--ex-echo-overlay nil) - (remove-hook 'pre-command-hook #'evil--ex-remove-echo-overlay t)) - -(cl-defun evil-ex-completion-at-point () - "Function used for `completion-at-point-functions' in Ex state." - (cl-flet ((fix-beg (b) (min (save-excursion - (+ (goto-char b) (skip-chars-forward " \t\n\r"))) - (point)))) - (pcase (nreverse (evil--ex-syntactic-context)) - ((or (and 'nil (let beg (minibuffer-prompt-end))) - `((expression) (command . ,beg) . ,_) - (and `((expression) (line) . ,_) - (guard (looking-at-p "[ \t\n\r]*\\'")) - (let beg (point)))) - (list (fix-beg beg) (point) (evil-ex-completion-table))) - (`((expression) (argument . ,beg)) - (setq beg (fix-beg beg)) - ;; If it's an autoload, load the function; this allows external - ;; packages to register autoloaded Ex commands which will be - ;; loaded when ex argument completion is triggered. - (let ((binding (evil-ex-binding evil--ex-cmd t))) (autoload-do-load binding)) - - (let* ((binding (evil-ex-completed-binding evil--ex-cmd)) - (arg-type (evil-get-command-property binding :ex-arg)) - (arg-handler (cdr (assq arg-type evil-ex-argument-types)))) - (pcase (evil-ex-argument-handler-completer arg-handler) - (`(collection . ,table) (list beg (point-max) table)) - (`(completion-at-point . ,completer) - (save-restriction (narrow-to-region beg (point-max)) - (funcall completer)))))) - (`((expression) (sexp . ,_)) - (when (fboundp 'elisp-completion-at-point) (elisp-completion-at-point)))))) - -(defun evil-ex-completion-table () - (let ((ex-cmds - (cl-loop - for (cmd . fun) in evil-ex-commands unless (stringp fun) - collect cmd - ;; Append ! to all commands that may take a bang argument - when (evil-get-command-property fun :ex-bang) - collect (concat cmd "!"))) - (emacs-cmds (lambda (str pred action) - (completion-table-with-predicate - obarray #'commandp t str pred action)))) - (cond - ((null evil-ex-complete-emacs-commands) ex-cmds) - ((eq evil-ex-complete-emacs-commands 'in-turn) - (completion-table-in-turn ex-cmds emacs-cmds)) - (t (cl-loop for s in-ref ex-cmds do - (setf s (propertize s 'face 'evil-ex-commands))) - (evil-completion-table-concat ex-cmds emacs-cmds))))) - -(defun evil-completion-table-concat (table1 table2) - (lambda (string pred action) - (cond - ((null action) - (let (matches) - (dolist (table (list table1 table2) (try-completion string matches)) - (let ((x (try-completion string table pred))) - (when x (push (if (eq x 't) string x) matches)))))) - ((eq action t) - (delete-dups - (append (all-completions string table1 pred) - (all-completions string table2 pred)))) - ((eq action 'lambda) - (when (or (test-completion string table1 pred) - (test-completion string table2 pred)) - t)) - ((eq (car-safe action) 'boundaries) - (or (completion-boundaries string table1 pred (cdr action)) - (completion-boundaries string table2 pred (cdr action)))) - ((eq action 'metadata) - '(metadata (display-sort-function . evil-ex-sort-completions)))))) - -(defun evil-ex-sort-completions (completions) - (sort completions - (lambda (str1 str2) - (let ((p1 (eq (get-text-property 0 'face str1) 'evil-ex-commands)) - (p2 (eq (get-text-property 0 'face str2) 'evil-ex-commands))) - (if (eq p1 p2) (string< str1 str2) p1))))) - -(define-obsolete-function-alias 'evil-ex-completion #'completion-at-point "1.15.0") - -(define-obsolete-function-alias - 'evil-ex-command-completion-at-point #'evil-ex-completion-at-point "1.15.0") - -(defalias 'evil-ex-argument-completion-at-point #'ignore) -(make-obsolete - 'evil-ex-argument-completion-at-point #'evil-ex-completion-at-point "1.15.0") - -(define-obsolete-function-alias - 'evil-ex-elisp-completion-at-point #'elisp-completion-at-point "1.15.0") - -(defun evil-ex-define-cmd (cmd function) - "Bind the function FUNCTION to the command CMD." - (if (not (string-match-p "\\[" cmd)) - (evil--add-to-alist evil-ex-commands cmd function) - (string-match "\\(.*\\)\\[\\(.*\\)\\]" cmd) - (let ((mandatory (match-string 1 cmd)) - (optional (match-string 2 cmd))) - (dotimes (n (1+ (length optional))) - (evil--add-to-alist evil-ex-commands - (concat mandatory (substring optional 0 n)) - function))))) - -(defmacro evil-ex-define-argument-type (arg-type doc &rest body) - "Define a new handler for argument-type ARG-TYPE. -DOC is the documentation string. It is followed by a list of keywords -and function: - -:collection COLLECTION - - A collection for completion as required by `all-completions'. - -:completion-at-point FUNC - - Function to be called to initialize a potential completion. FUNC - must match the requirements as described for the variable - `completion-at-point-functions'. When FUNC is called the minibuffer - content is narrowed to exactly match the argument. - -:runner FUNC - - Function to be called when the type of the current argument changes - or when the content of this argument changes. This function should - take one obligatory argument FLAG followed by an optional argument - ARG. FLAG is one of three symbol `start', `stop' or `update'. When - the argument type is recognized for the first time and this handler - is started the FLAG is `start'. If the argument type changes to - something else or ex state finished the handler FLAG is `stop'. If - the content of the argument has changed FLAG is `update'. If FLAG is - either `start' or `update' then ARG is the current value of this - argument. If FLAG is `stop' then arg is nil." - (declare (indent defun) - (doc-string 2) - (debug (&define name - [&optional stringp] - [&rest [keywordp function-form]]))) - (unless (stringp doc) (push doc body)) - (let (runner completer) - (while (keywordp (car body)) - (let ((key (pop body)) - (func (pop body))) - (cond - ((eq key :runner) - (setq runner `#',func)) - ((eq key :collection) - (setq completer `(cons 'collection #',func))) - ((eq key :completion-at-point) - (setq completer `(cons 'completion-at-point #',func)))))) - `(evil--add-to-alist evil-ex-argument-types - ',arg-type (list ,runner ,completer)))) - -(evil-ex-define-argument-type file - "Handle a file argument." - :collection read-file-name-internal) - -(evil-ex-define-argument-type buffer - "Called to complete a buffer name argument." - :collection internal-complete-buffer) - -(declare-function comint-completion-at-point "comint") -(declare-function shell-completion-vars "shell" ()) - -(defvar-local evil--ex-shell-argument-initialized nil - "This variable is set to t if shell command completion has been initialized. -See `evil-ex-init-shell-argument-completion'.") - -(defun evil-ex-init-shell-argument-completion (flag &optional _arg) - "Prepare the current minibuffer for completion of shell commands. -This function must be called from the :runner function of some -argument handler that requires shell completion." - (when (and (eq flag 'start) - (not evil--ex-shell-argument-initialized)) - (setq evil--ex-shell-argument-initialized t) - (require 'shell) - ;; Set up Comint for Shell mode, except - ;; `comint-completion-at-point' will be called manually. - (shell-completion-vars) - (remove-hook 'completion-at-point-functions #'comint-completion-at-point t))) - -(evil-ex-define-argument-type shell - "Shell argument type, supports completion." - :completion-at-point comint-completion-at-point - :runner evil-ex-init-shell-argument-completion) - -(defun evil-ex-file-or-shell-command-completion-at-point () - (if (eq (char-after (point-min)) ?!) - (save-restriction - (narrow-to-region (1+ (point-min)) (point-max)) - (comint-completion-at-point)) - (list (point-min) (point-max) #'read-file-name-internal))) - -(evil-ex-define-argument-type file-or-shell - "File or shell argument type. -If the current argument starts with a ! the rest of the argument -is considered a shell command, otherwise a file-name. Completion -works accordingly." - :completion-at-point evil-ex-file-or-shell-command-completion-at-point - :runner evil-ex-init-shell-argument-completion) - -(defun evil-ex-binding (command &optional noerror) - "Return the final binding of COMMAND." - (let ((binding (if (evil--ex-bang-p command) (substring command 0 -1) - command))) - (while (stringp - (setq binding (cdr (assoc binding evil-ex-commands))))) - (unless binding (setq binding (intern-soft command))) - (if (commandp binding) - (or (command-remapping binding) binding) - (unless noerror (user-error "Unknown command: `%s'" command))))) - -(defun evil-ex-completed-binding (command &optional noerror) - "Return the final binding of the completion of COMMAND." - (let ((completion (try-completion command evil-ex-commands))) - (evil-ex-binding (if (eq completion t) command - (or completion command)) - noerror))) - -;; TODO: extensions like :p :~ <cfile> ... -(defun evil-ex-replace-special-filenames (file-name) - "Replace special symbols in FILE-NAME. -Replaces % by the current file-name, -Replaces # by the alternate file-name in FILE-NAME." - (let ((remote (file-remote-p file-name)) - (current-fname (buffer-file-name)) - (alternate-fname (and (other-buffer) - (buffer-file-name (other-buffer))))) - (setq file-name (or (file-remote-p file-name 'localname) file-name)) - (when current-fname - (setq current-fname (or (file-remote-p current-fname 'localname) - current-fname)) - (setq file-name - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)" - current-fname file-name - t t 2))) - (when alternate-fname - (setq alternate-fname (or (file-remote-p alternate-fname 'localname) - alternate-fname)) - (setq file-name - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)" - alternate-fname file-name - t t 2))) - (setq file-name - (replace-regexp-in-string "\\\\\\([#%]\\)" - "\\1" file-name t)) - (setq file-name (concat remote file-name))) - file-name) - -(defun evil-ex-file-arg () - "Return the current Ex argument as a file name. -This function interprets special file names like # and %." - (unless (zerop (length evil-ex-argument)) - (evil-ex-replace-special-filenames evil-ex-argument))) - -(define-error 'evil-ex-no-previous-cmd "No previous command line") - -(defun evil-ex-repeat (&optional count) - "Repeat the last Ex command." - (interactive "P") - (when count - (goto-char (point-min)) - (forward-line (1- count))) - (cl-loop - with evil-ex-original-buffer = (current-buffer) - for last-cmd in evil-ex-history do - (condition-case nil - (cl-return (let (evil-ex-history) (evil-ex-execute last-cmd))) - (evil-ex-no-previous-cmd)) - finally (signal 'evil-ex-no-previous-cmd nil))) - -(defun evil-ex-call-command (range command argument) - "Execute the given command COMMAND." - (when evil-ex-reverse-range - (setq evil-ex-reverse-range nil) - (unless (y-or-n-p "Backward range given, OK to swap? ") - (user-error ""))) - (let* ((count (when (integerp range) range)) - (current-prefix-arg count) - (evil-ex-range (if count (evil-ex-range count count) range)) - (cmd (evil-ex-completed-binding command)) - (evil-ex-bang (evil--ex-bang-p command)) - (evil-ex-argument argument) - (evil-this-type (evil-type evil-ex-range)) - (evil-ex-point (point)) - (restore-point - (and evil-ex-range - (evil-get-command-property cmd :restore-point) - (if (evil-visual-state-p) evil-visual-beginning evil-ex-point))) - (evil-called-from-ex-p t)) - (evil-exit-visual-state) - (deactivate-mark) - (when evil-ex-range - ;; Set region if an explicit range has been specified - (cl-destructuring-bind (beg end &rest) (evil-expand-range evil-ex-range t) - (goto-char beg) - (set-marker (mark-marker) end))) - (setq this-command cmd) - (let ((mark-active evil-ex-range)) - (run-hooks 'pre-command-hook) - (call-interactively cmd)) - (run-hooks 'post-command-hook) - (when restore-point (goto-char restore-point)))) - -(defun evil-ex-line (base &optional offset) - "Return the line number of BASE plus OFFSET." - (+ (or base (line-number-at-pos)) - (or offset 0))) - -(defun evil-ex-first-line () - "Return the line number of the first line." - (line-number-at-pos (point-min))) - -(defun evil-ex-current-line () - "Return the line number of the current line." - (line-number-at-pos)) - -(defun evil-ex-last-line () - "Return the line number of the last line." - (save-excursion - (goto-char (point-max)) - (when (bolp) - (forward-line -1)) - (line-number-at-pos))) - -(defun evil-ex-range (beg-line &optional end-line) - "Return the first and last position of the current range." - (let* ((beg (if beg-line (evil-line-position beg-line) - (line-beginning-position))) - (end (if end-line (evil-line-position (1+ end-line)) - (save-excursion (goto-char beg) (line-beginning-position 2))))) - (when (< end beg) - (setq evil-ex-reverse-range t) - (evil-swap beg end)) - (evil-range beg end 'line :expanded t))) - -(defun evil-ex-full-range () - "Return a range encompassing the whole buffer." - (evil-range (point-min) (point-max) 'line :expanded t)) - -(defun evil-ex-last-visual-range () - "Return a linewise range of the last visual selection." - (evil-range evil-visual-mark evil-visual-point 'line)) - -(defun evil-ex-marker (marker) - "Return MARKER's line number in the current buffer. -Signal an error if MARKER is in a different buffer." - (setq marker (evil-get-marker - (if (stringp marker) (aref marker 0) marker))) - (if (numberp marker) - (line-number-at-pos marker) - (user-error "Ex does not support markers in other files"))) - -(defun evil-ex-char-marker-range (beg end) - (setq beg (evil-get-marker (if (stringp beg) (aref beg 0) beg)) - end (evil-get-marker (if (stringp end) (aref end 0) end))) - (unless (and (numberp beg) (numberp end)) - (user-error "Ex does not support markers in other files")) - (evil-expand-range - (evil-range beg end - (if (evil-visual-state-p) - (evil-visual-type) - 'inclusive)))) - -(declare-function evil-ex-make-search-pattern "evil-search") - -(defun evil-ex-re-fwd (pattern) - "Search forward for PATTERN. -Return the line number of the match." - (when evil-ex-search-vim-style-regexp - (setq pattern (evil-transform-vim-style-regexp pattern))) - (set-text-properties 0 (length pattern) nil pattern) - (setq evil-ex-search-pattern (evil-ex-make-search-pattern pattern) - evil-ex-search-direction 'forward) - (condition-case err - (save-excursion - (evil-move-beginning-of-line 2) - (when (or (re-search-forward pattern nil t) - (progn - (goto-char (point-min)) - (re-search-forward pattern nil t))) - (line-number-at-pos (match-beginning 0)))) - (invalid-regexp - (evil-ex-echo (cadr err)) - nil))) - -(defun evil-ex-re-bwd (pattern) - "Search backward for PATTERN. -Return the line number of the match." - (when evil-ex-search-vim-style-regexp - (setq pattern (evil-transform-vim-style-regexp pattern))) - (set-text-properties 0 (length pattern) nil pattern) - (setq evil-ex-search-pattern (evil-ex-make-search-pattern pattern) - evil-ex-search-direction 'backward) - (condition-case err - (save-excursion - (evil-move-beginning-of-line) - (when (or (re-search-backward pattern nil t) - (progn - (goto-char (point-max)) - (re-search-backward pattern nil t))) - (line-number-at-pos (match-beginning 0)))) - (invalid-regexp - (evil-ex-echo (cadr err)) - nil))) - -(defun evil-ex-prev-search () - (error "Previous search not yet implemented")) - -(defun evil-ex-signed-number (sign &optional number) - "Return a signed number like -3 and +1. -NUMBER defaults to 1." - (funcall sign (or number 1))) - -(defun evil-ex-command-force-p (command) - "Whether COMMAND accepts the bang argument." - (declare (obsolete evil-get-command-property "1.15.0")) - (let ((binding (evil-ex-completed-binding command t))) - (when binding - (evil-get-command-property binding :ex-bang)))) - -(cl-defun evil--ex-syntactic-context - (&optional (pos (point)) - (tree (save-excursion (goto-char (minibuffer-prompt-end)) - (evil-ex-parse nil t))) - &aux i result) - "Return the syntactical context in TREE of the character at POS. -POS defaults to the current position of point." - ;; Iterate over syntax tree leaves (i.e. the strings), and return - ;; the path to the leaf containing the cursor. Or, if not found, - ;; e.g. because of trailing whitespace, the leaf at most one char - ;; past the rightmost non-empty string. - (cl-labels - ((traverse - (node path) - (while (and (consp node) (symbolp (car node))) - (push (cons (pop node) i) path)) - (if (listp node) - (dolist (child node) (traverse child path)) - ;; NODE is the end position of a parsed string - (when (>= node pos) (cl-return-from evil--ex-syntactic-context path)) - (when (or (null result) (> node i)) - (setq i node - result path))))) - (traverse tree ())) - result) - -(provide 'evil-ex) - -;;; evil-ex.el ends here diff --git a/.config/emacs/lisp/evil/evil-integration.el b/.config/emacs/lisp/evil/evil-integration.el deleted file mode 100644 index 710d69d..0000000 --- a/.config/emacs/lisp/evil/evil-integration.el +++ /dev/null @@ -1,468 +0,0 @@ -;;; evil-integration.el --- Integrate Evil with other modules -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; This provides evil integration for various emacs modes. -;; Additional keybindings (or default state) should go into evil-keybindings.el. - -;;; Code: - -(require 'evil-maps) -(require 'evil-core) -(require 'evil-macros) -(require 'evil-types) -(require 'evil-repeat) - -;;; Evilize some commands - -;; unbound keys should be ignored -(evil-declare-ignore-repeat 'undefined) - -(mapc #'(lambda (cmd) - (evil-set-command-property cmd :keep-visual t) - (evil-declare-not-repeat cmd)) - '(digit-argument - negative-argument - universal-argument - universal-argument-minus - universal-argument-more - universal-argument-other-key)) -(mapc #'evil-declare-not-repeat - '(what-cursor-position)) -(mapc #'evil-declare-change-repeat - '(dabbrev-expand - hippie-expand - quoted-insert)) -(mapc #'evil-declare-abort-repeat - '(balance-windows - eval-expression - execute-extended-command - exit-minibuffer - compile - delete-window - delete-other-windows - find-file-at-point - ffap-other-window - recompile - redo - save-buffer - split-window - split-window-horizontally - split-window-vertically - undo - undo-tree-redo - undo-tree-undo)) - -(evil-set-type #'previous-line 'line) -(evil-set-type #'next-line 'line) - -(dolist (cmd '(keyboard-quit keyboard-escape-quit)) - (evil-set-command-property cmd :suppress-operator t)) - -;;; Mouse -(evil-declare-insert-at-point-repeat 'mouse-yank-primary) -(evil-declare-insert-at-point-repeat 'mouse-yank-secondary) - -;;; key-binding - -;; Calling `keyboard-quit' should cancel repeat -(advice-add 'keyboard-quit :before #'evil-repeat-abort) - -(add-hook 'wdired-mode-hook #'evil-change-to-initial-state) -(advice-add 'wdired-change-to-dired-mode :after - #'evil--change-to-initial-state-with-msg) -(defun evil--change-to-initial-state-with-msg (&rest _) - (evil-change-to-initial-state nil t)) - -;;; Parentheses - -(evil--advice-add 'show-paren-function :around #'evil--match-paren-in-normal-state) -(defun evil--match-paren-in-normal-state (orig-fun &rest args) - "Match parentheses in Normal state." - (if (eq (not (memq 'not evil-highlight-closing-paren-at-point-states)) - (not (memq evil-state evil-highlight-closing-paren-at-point-states))) - (apply orig-fun args) - (let* ((orig-spdf show-paren-data-function) - (show-paren-data-function - (lambda () - (let ((pos (point)) narrow) - (setq - pos (cl-dotimes (i (1+ (* 2 evil-show-paren-range))) - (setq pos (+ pos (if (cl-evenp i) i (- i)))) - (pcase (syntax-class (syntax-after pos)) - (4 (setq narrow pos) (cl-return pos)) - (5 (cl-return (1+ pos)))))) - (when pos - (save-excursion - (goto-char pos) - (save-restriction - (when narrow (narrow-to-region narrow (point-max))) - (funcall orig-spdf)))))))) - (apply orig-fun args)))) - -;;; Undo tree -(eval-after-load 'undo-tree - '(with-no-warnings - (evil-ex-define-cmd "undol[ist]" 'undo-tree-visualize) - (evil-ex-define-cmd "ul" 'undo-tree-visualize) - - (define-key undo-tree-visualizer-mode-map - [remap evil-backward-char] 'undo-tree-visualize-switch-branch-left) - (define-key undo-tree-visualizer-mode-map - [remap evil-forward-char] 'undo-tree-visualize-switch-branch-right) - (define-key undo-tree-visualizer-mode-map - [remap evil-next-line] 'undo-tree-visualize-redo) - (define-key undo-tree-visualizer-mode-map - [remap evil-previous-line] 'undo-tree-visualize-undo) - (define-key undo-tree-visualizer-mode-map - [remap evil-ret] 'undo-tree-visualizer-set) - - (define-key undo-tree-visualizer-selection-mode-map - [remap evil-backward-char] 'undo-tree-visualizer-select-left) - (define-key undo-tree-visualizer-selection-mode-map - [remap evil-forward-char] 'undo-tree-visualizer-select-right) - (define-key undo-tree-visualizer-selection-mode-map - [remap evil-next-line] 'undo-tree-visualizer-select-next) - (define-key undo-tree-visualizer-selection-mode-map - [remap evil-previous-line] 'undo-tree-visualizer-select-previous) - (define-key undo-tree-visualizer-selection-mode-map - [remap evil-ret] 'undo-tree-visualizer-set))) - -;;; Auto-complete -(eval-after-load 'auto-complete - '(progn - (evil-add-command-properties 'auto-complete :repeat 'evil-ac-repeat) - (evil-add-command-properties 'ac-complete :repeat 'evil-ac-repeat) - (evil-add-command-properties 'ac-expand :repeat 'evil-ac-repeat) - (evil-add-command-properties 'ac-next :repeat 'ignore) - (evil-add-command-properties 'ac-previous :repeat 'ignore) - - (defvar evil-ac-prefix-len nil - "The length of the prefix of the current item to be completed.") - - (defvar ac-prefix) - (defun evil-ac-repeat (flag) - "Record the changes for auto-completion." - (cond - ((eq flag 'pre) - (setq evil-ac-prefix-len (length ac-prefix)) - (evil-repeat-start-record-changes)) - ((eq flag 'post) - ;; Add change to remove the prefix - (evil-repeat-record-change (- evil-ac-prefix-len) - "" - evil-ac-prefix-len) - ;; Add change to insert the full completed text - (evil-repeat-record-change - (- evil-ac-prefix-len) - (buffer-substring-no-properties (- evil-repeat-pos - evil-ac-prefix-len) - (point)) - 0) - ;; Finish repeation - (evil-repeat-finish-record-changes)))))) - -;;; Company -(eval-after-load 'company - '(progn - (mapc #'evil-declare-change-repeat - '(company-complete-mouse - company-complete-number - company-complete-selection - company-complete-common)) - - (mapc #'evil-declare-ignore-repeat - '(company-abort - company-select-next - company-select-previous - company-select-next-or-abort - company-select-previous-or-abort - company-select-mouse - company-show-doc-buffer - company-show-location - company-search-candidates - company-filter-candidates)))) - -;;; Eval last sexp -(defun evil--preceding-sexp (command &rest args) - "In Normal- or Motion-state, allow last sexp to end at point." - (save-excursion - (or evil-move-beyond-eol - (eolp) - (not (or (evil-normal-state-p) (evil-motion-state-p))) - (forward-char)) - (apply command args))) -(advice-add 'elisp--preceding-sexp :around #'evil--preceding-sexp) -(advice-add 'pp-last-sexp :around #'evil--preceding-sexp) -(advice-add 'lisp-eval-last-sexp :around #'evil--preceding-sexp) - -;;; Show key -(advice-add 'quail-show-key :around #'evil--in-emacs-state) -(advice-add 'describe-char :around #'evil--in-emacs-state) -(defun evil--in-emacs-state (orig-fun &rest args) - "Temporarily enter Emacs-state and apply ORIG-FUN to ARGS." - (evil-with-state emacs (apply orig-fun args))) - -;;; ace-jump-mode -(declare-function ace-jump-char-mode "ext:ace-jump-mode") -(declare-function ace-jump-word-mode "ext:ace-jump-mode") -(declare-function ace-jump-line-mode "ext:ace-jump-mode") -(defvar ace-jump-mode-scope) - -(defvar evil-ace-jump-active nil) - -(defmacro evil-enclose-ace-jump-for-motion (&rest body) - "Enclose ace-jump to make it suitable for motions. -This includes restricting `ace-jump-mode' to the current window -in visual and operator state, deactivating visual updates, saving -the mark and entering `recursive-edit'." - (declare (indent defun) - (debug t)) - `(let ((old-mark (mark)) - (ace-jump-mode-scope - (if (and (not (memq evil-state '(visual operator))) - (boundp 'ace-jump-mode-scope)) - ace-jump-mode-scope - 'window))) - (remove-hook 'pre-command-hook #'evil-visual-pre-command t) - (remove-hook 'post-command-hook #'evil-visual-post-command t) - (unwind-protect - (let ((evil-ace-jump-active 'prepare)) - (add-hook 'ace-jump-mode-end-hook - #'evil-ace-jump-exit-recursive-edit) - ,@body - (when evil-ace-jump-active - (setq evil-ace-jump-active t) - (recursive-edit))) - (remove-hook 'post-command-hook - #'evil-ace-jump-exit-recursive-edit) - (remove-hook 'ace-jump-mode-end-hook - #'evil-ace-jump-exit-recursive-edit) - (if (evil-visual-state-p) - (progn - (add-hook 'pre-command-hook #'evil-visual-pre-command nil t) - (add-hook 'post-command-hook #'evil-visual-post-command nil t) - (set-mark old-mark)) - (push-mark old-mark))))) - -(advice-add 'ace-jump-done :after #'evil--after-ace-jump-done) -(defun evil--after-ace-jump-done (&rest _) - (when evil-ace-jump-active - (add-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit))) - -(defun evil-ace-jump-exit-recursive-edit () - "Exit a recursive edit caused by an evil jump." - (cond - ((eq evil-ace-jump-active 'prepare) - (setq evil-ace-jump-active nil)) - (evil-ace-jump-active - (remove-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit) - (exit-recursive-edit)))) - -(evil-define-motion evil-ace-jump-char-mode (_count) - "Jump visually directly to a char using ace-jump." - :type inclusive - (evil-without-repeat - (let ((pnt (point)) - (buf (current-buffer))) - (evil-enclose-ace-jump-for-motion - (call-interactively 'ace-jump-char-mode)) - ;; if we jump backwards, motion type is exclusive, analogously - ;; to `evil-find-char-backward' - (when (and (equal buf (current-buffer)) - (< (point) pnt)) - (setq evil-this-type - (cond - ((eq evil-this-type 'exclusive) 'inclusive) - ((eq evil-this-type 'inclusive) 'exclusive))))))) - -(evil-define-motion evil-ace-jump-char-to-mode (_count) - "Jump visually to the char in front of a char using ace-jump." - :type inclusive - (evil-without-repeat - (let ((pnt (point)) - (buf (current-buffer))) - (evil-enclose-ace-jump-for-motion - (call-interactively 'ace-jump-char-mode)) - (if (and (equal buf (current-buffer)) - (< (point) pnt)) - (progn - (or (eobp) (forward-char)) - (setq evil-this-type - (cond - ((eq evil-this-type 'exclusive) 'inclusive) - ((eq evil-this-type 'inclusive) 'exclusive)))) - (backward-char))))) - -(evil-define-motion evil-ace-jump-line-mode (_count) - "Jump visually to the beginning of a line using ace-jump." - :type line - :repeat abort - (evil-without-repeat - (evil-enclose-ace-jump-for-motion - (call-interactively 'ace-jump-line-mode)))) - -(evil-define-motion evil-ace-jump-word-mode (_count) - "Jump visually to the beginning of a word using ace-jump." - :type exclusive - :repeat abort - (evil-without-repeat - (evil-enclose-ace-jump-for-motion - (call-interactively 'ace-jump-word-mode)))) - -(define-key evil-motion-state-map [remap ace-jump-char-mode] #'evil-ace-jump-char-mode) -(define-key evil-motion-state-map [remap ace-jump-line-mode] #'evil-ace-jump-line-mode) -(define-key evil-motion-state-map [remap ace-jump-word-mode] #'evil-ace-jump-word-mode) - -;;; avy -(declare-function avy-goto-word-or-subword-1 "ext:avy") -(declare-function avy-goto-line "ext:avy") -(declare-function avy-goto-char "ext:avy") -(declare-function avy-goto-char-2 "ext:avy") -(declare-function avy-goto-char-2-above "ext:avy") -(declare-function avy-goto-char-2-below "ext:avy") -(declare-function avy-goto-char-in-line "ext:avy") -(declare-function avy-goto-word-0 "ext:avy") -(declare-function avy-goto-word-1 "ext:avy") -(declare-function avy-goto-word-1-above "ext:avy") -(declare-function avy-goto-word-1-below "ext:avy") -(declare-function avy-goto-subword-0 "ext:avy") -(declare-function avy-goto-subword-1 "ext:avy") -(declare-function avy-goto-char-timer "ext:avy") -(defvar avy-all-windows) - -(defmacro evil-enclose-avy-for-motion (&rest body) - "Enclose avy to make it suitable for motions. -Based on `evil-enclose-ace-jump-for-motion'." - (declare (indent defun) - (debug t)) - `(let ((avy-all-windows - (if (and (not (memq evil-state '(visual operator))) - (boundp 'avy-all-windows)) - avy-all-windows - nil))) - ,@body)) - -(defmacro evil-define-avy-motion (command type) - (declare (indent defun) - (debug t)) - (let ((name (intern (format "evil-%s" command)))) - `(evil-define-motion ,name (_count) - ,(format "Evil motion for `%s'." command) - :type ,type - :jump t - :repeat abort - (evil-without-repeat - (evil-enclose-avy-for-motion - (call-interactively ',command)))))) - -;; define evil-avy-* motion commands for avy-* commands -(evil-define-avy-motion avy-goto-char inclusive) -(evil-define-avy-motion avy-goto-char-2 inclusive) -(evil-define-avy-motion avy-goto-char-2-above inclusive) -(evil-define-avy-motion avy-goto-char-2-below inclusive) -(evil-define-avy-motion avy-goto-char-in-line inclusive) -(evil-define-avy-motion avy-goto-char-timer inclusive) -(evil-define-avy-motion avy-goto-line line) -(evil-define-avy-motion avy-goto-line-above line) -(evil-define-avy-motion avy-goto-line-below line) -(evil-define-avy-motion avy-goto-subword-0 exclusive) -(evil-define-avy-motion avy-goto-subword-1 exclusive) -(evil-define-avy-motion avy-goto-symbol-1 exclusive) -(evil-define-avy-motion avy-goto-symbol-1-above exclusive) -(evil-define-avy-motion avy-goto-symbol-1-below exclusive) -(evil-define-avy-motion avy-goto-word-0 exclusive) -(evil-define-avy-motion avy-goto-word-1 exclusive) -(evil-define-avy-motion avy-goto-word-1-above exclusive) -(evil-define-avy-motion avy-goto-word-1-below exclusive) -(evil-define-avy-motion avy-goto-word-or-subword-1 exclusive) - -;; remap avy-* commands to evil-avy-* commands -(dolist (command '(avy-goto-char - avy-goto-char-2 - avy-goto-char-2-above - avy-goto-char-2-below - avy-goto-char-in-line - avy-goto-char-timer - avy-goto-line - avy-goto-line-above - avy-goto-line-below - avy-goto-subword-0 - avy-goto-subword-1 - avy-goto-symbol-1 - avy-goto-symbol-1-above - avy-goto-symbol-1-below - avy-goto-word-0 - avy-goto-word-1 - avy-goto-word-1-above - avy-goto-word-1-below - avy-goto-word-or-subword-1)) - (define-key evil-motion-state-map - (vector 'remap command) (intern-soft (format "evil-%s" command)))) - -;;; nXhtml/mumamo -;; ensure that mumamo does not toggle evil through its globalized mode -(eval-after-load 'mumamo - '(with-no-warnings - (push 'evil-mode-cmhh mumamo-change-major-mode-no-nos))) - -;; visual-line-mode integration -(when evil-respect-visual-line-mode - (evil-define-minor-mode-key 'motion 'visual-line-mode - "j" 'evil-next-visual-line - "gj" 'evil-next-line - "k" 'evil-previous-visual-line - "gk" 'evil-previous-line - "0" 'evil-beginning-of-visual-line - "g0" 'evil-beginning-of-line - "$" 'evil-end-of-visual-line - "g$" 'evil-end-of-line - "V" 'evil-visual-screen-line)) - -;;; abbrev.el -(defun evil-maybe-expand-abbrev () - (when (and abbrev-mode evil-want-abbrev-expand-on-insert-exit) - (expand-abbrev))) - -(eval-after-load 'abbrev - '(add-hook 'evil-insert-state-exit-hook #'evil-maybe-expand-abbrev)) - -;;; ElDoc -(eval-after-load 'eldoc - '(when (fboundp 'eldoc-add-command-completions) - (eldoc-add-command-completions "evil-window-"))) - -;;; XRef -(eval-after-load 'xref - '(progn - (evil-set-command-property 'xref-find-definitions :jump t) - (evil-set-command-property 'xref-find-references :jump t))) - -(provide 'evil-integration) - -;;; evil-integration.el ends here diff --git a/.config/emacs/lisp/evil/evil-jumps.el b/.config/emacs/lisp/evil/evil-jumps.el deleted file mode 100644 index a5ad8ba..0000000 --- a/.config/emacs/lisp/evil/evil-jumps.el +++ /dev/null @@ -1,358 +0,0 @@ -;;; evil-jumps.el --- Jump list implementation -*- lexical-binding: t -*- - -;; Author: Bailey Ling <bling at live.ca> - -;; 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 <http://www.gnu.org/licenses/>. - -(require 'cl-lib) -(require 'evil-core) -(require 'evil-states) - -;;; Code: - -(defgroup evil-jumps nil - "Evil jump list configuration options." - :prefix "evil-jumps" - :group 'evil) - -(defcustom evil-jumps-cross-buffers t - "When non-nil, the jump commands can cross borders between buffers. -Otherwise the jump commands act only within the current buffer." - :type 'boolean) - -(defcustom evil-jumps-max-length 100 - "The maximum number of jumps to keep track of." - :type 'integer) - -(defcustom evil-jumps-pre-jump-hook nil - "Hooks to run just before jumping to a location in the jump list." - :type 'hook) - -(defcustom evil-jumps-post-jump-hook nil - "Hooks to run just after jumping to a location in the jump list." - :type 'hook) - -(defcustom evil-jumps-ignored-file-patterns '("COMMIT_EDITMSG$" "TAGS$") - "List of regexps to exclude file path from inclusion in the jump list." - :type '(repeat string)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defvar savehist-additional-variables) - -(defvar evil--jumps-jumping nil) - -(defvar evil--jumps-jump-command nil - "Set by `evil--jump-backward', used and cleared in the -`post-command-hook' by `evil--jump-handle-buffer-crossing'") - -(eval-when-compile (defvar evil--jumps-debug nil)) - -(defvar evil--jumps-buffer-targets "\\*\\(new\\|scratch\\)\\*" - "Regexp to determine if buffer with `buffer-name' is a valid jump target.") - -(defvar evil--jumps-window-jumps (make-hash-table) - "Hashtable which stores all jumps on a per window basis.") - -(defvar evil-jumps-history nil - "History of `evil-mode' jumps that are persisted with `savehist'.") - -(cl-defstruct evil-jumps-struct - ring - (idx -1) - previous-pos) - -;; Is inlining this really worth it? -(defsubst evil--jumps-message (format &rest args) - (when (eval-when-compile evil--jumps-debug) - (with-current-buffer (get-buffer-create "*evil-jumps*") - (goto-char (point-max)) - (insert (apply #'format format args) "\n")))) - -(defun evil--jumps-get-current (&optional window) - (unless window (setq window (selected-window))) - (let ((jump-struct (gethash window evil--jumps-window-jumps))) - (unless jump-struct - (setq jump-struct (make-evil-jumps-struct)) - (puthash window jump-struct evil--jumps-window-jumps)) - jump-struct)) - -(defun evil--jumps-get-jumps (struct) - (let ((ring (evil-jumps-struct-ring struct))) - (unless ring - (setq ring (make-ring evil-jumps-max-length)) - (setf (evil-jumps-struct-ring struct) ring)) - ring)) - -(defun evil--jumps-get-window-jump-list () - (let ((struct (evil--jumps-get-current))) - (evil--jumps-get-jumps struct))) - -(defun evil--jumps-savehist-load () - (add-to-list 'savehist-additional-variables 'evil-jumps-history) - (let ((ring (make-ring evil-jumps-max-length))) - (cl-loop for jump in (reverse evil-jumps-history) - do (ring-insert ring jump)) - (setf (evil-jumps-struct-ring (evil--jumps-get-current)) ring)) - (add-hook 'savehist-save-hook #'evil--jumps-savehist-sync) - (remove-hook 'savehist-mode-hook #'evil--jumps-savehist-load)) - -(defun evil--jumps-savehist-sync () - "Update the printable value of window jumps for `savehist'." - (setq evil-jumps-history - (delq nil (mapcar #'(lambda (jump) - (let* ((mark (car jump)) - (pos (if (markerp mark) - (marker-position mark) - mark)) - (file-name (cadr jump))) - (when (and (not (file-remote-p file-name)) - (file-exists-p file-name) - pos) - (list pos file-name)))) - (ring-elements (evil--jumps-get-window-jump-list)))))) - -(defun evil--jumps-current-file-name () - "Get the current buffer file name for `evil--jumps-push'." - (or buffer-file-name - (when (derived-mode-p 'dired-mode) default-directory))) - -(defun evil--jumps-jump (idx shift) - (let ((target-list (evil--jumps-get-window-jump-list))) - (evil--jumps-message "jumping from %s by %s" idx shift) - (evil--jumps-message "target list = %s" target-list) - (setq idx (+ idx shift)) - (let ((current-file-name (or (evil--jumps-current-file-name) (buffer-name))) - (size (ring-length target-list))) - (unless evil-jumps-cross-buffers - ;; skip jump marks pointing to other buffers - (while (and (< idx size) (>= idx 0) - (not (string= current-file-name (cadr (ring-ref target-list idx))))) - (setq idx (+ idx shift)))) - (when (and (< idx size) (>= idx 0)) - ;; actual jump - (run-hooks 'evil-jumps-pre-jump-hook) - (let* ((place (ring-ref target-list idx)) - (pos (car place)) - (file-name (cadr place))) - (setq evil--jumps-jumping t) - (unless (string= current-file-name file-name) - (if (string-match-p evil--jumps-buffer-targets file-name) - (switch-to-buffer file-name) - (find-file file-name))) - (setq evil--jumps-jumping nil) - (goto-char pos) - (setf (evil-jumps-struct-idx (evil--jumps-get-current)) idx) - (run-hooks 'evil-jumps-post-jump-hook)))))) - -(defun evil--jumps-push () - "Push the current cursor/file position to the jump list." - (let ((target-list (evil--jumps-get-window-jump-list)) - (file-name (evil--jumps-current-file-name)) - (buffer-name (buffer-name)) - (current-pos (point-marker)) - (first-pos nil) - (first-file-name nil) - (excluded nil)) - (when (and (not file-name) - (string-match-p evil--jumps-buffer-targets buffer-name)) - (setq file-name buffer-name)) - (when file-name - (dolist (pattern evil-jumps-ignored-file-patterns) - (when (string-match-p pattern file-name) - (setq excluded t))) - (unless excluded - (unless (ring-empty-p target-list) - (setq first-pos (car (ring-ref target-list 0))) - (setq first-file-name (car (cdr (ring-ref target-list 0))))) - (unless (and (equal first-pos current-pos) - (equal first-file-name file-name)) - (evil--jumps-message "pushing %s on %s" current-pos file-name) - (ring-insert target-list `(,current-pos ,file-name))))) - (evil--jumps-message "%s %s" - (selected-window) - (and (not (ring-empty-p target-list)) - (ring-ref target-list 0))))) - -(evil-define-command evil-show-jumps () - "Display the contents of the jump list." - :repeat nil - (evil-with-view-list - :name "evil-jumps" - :mode "Evil Jump List" - :format [("Jump" 5 nil) - ("Marker" 8 nil) - ("File/text" 1000 t)] - :entries (let* ((jumps (evil--jumps-savehist-sync)) - (count 0)) - (cl-loop for jump in jumps - collect `(nil [,(number-to-string (cl-incf count)) - ,(number-to-string (car jump)) - (,(cadr jump))]))) - :select-action #'evil--show-jumps-select-action)) - -(defun evil--show-jumps-select-action (jump) - (let ((position (string-to-number (elt jump 1))) - (file (car (elt jump 2)))) - (kill-buffer) - (switch-to-buffer (find-file file)) - (goto-char position))) - -(defun evil-set-jump (&optional pos) - "Set jump point at POS. -POS defaults to point." - (save-excursion - (when (markerp pos) - (set-buffer (marker-buffer pos))) - - (unless (or (region-active-p) (evil-visual-state-p)) - (push-mark pos t)) - - (unless evil--jumps-jumping - ;; clear out intermediary jumps when a new one is set - (let* ((struct (evil--jumps-get-current)) - (target-list (evil--jumps-get-jumps struct)) - (idx (evil-jumps-struct-idx struct))) - (cl-loop repeat idx - do (ring-remove target-list)) - (setf (evil-jumps-struct-idx struct) -1)) - (when pos - (goto-char pos)) - (evil--jumps-push)))) -(put 'evil-set-jump 'permanent-local-hook t) - -(defun evil--jump-backward (count) - (setq evil--jumps-jump-command t) - (let ((count (or count 1))) - (evil-motion-loop (nil count) - (let* ((struct (evil--jumps-get-current)) - (idx (evil-jumps-struct-idx struct))) - (evil--jumps-message "jumping back %s" idx) - (when (= idx -1) - (setq idx 0) - (setf (evil-jumps-struct-idx struct) 0) - (evil--jumps-push)) - (evil--jumps-jump idx 1))))) - -(defun evil--jump-forward (count) - (setq evil--jumps-jump-command t) - (let ((count (or count 1))) - (evil-motion-loop (nil count) - (let* ((struct (evil--jumps-get-current)) - (idx (evil-jumps-struct-idx struct))) - (when (= idx -1) - (setq idx 0) - (setf (evil-jumps-struct-idx struct) 0) - (evil--jumps-push)) - (evil--jumps-jump idx -1))))) - -(defun evil--jumps-window-configuration-hook (&rest _args) - (let* ((window-list (window-list-1 nil nil t)) - (existing-window (selected-window)) - (new-window (previous-window))) - (when (and (not (eq existing-window new-window)) - (> (length window-list) 1)) - (let* ((target-jump-struct (evil--jumps-get-current new-window))) - (if (not (ring-empty-p (evil--jumps-get-jumps target-jump-struct))) - (evil--jumps-message "target window %s already has %s jumps" new-window - (ring-length (evil--jumps-get-jumps target-jump-struct))) - (evil--jumps-message "new target window detected; copying %s to %s" existing-window new-window) - (let* ((source-jump-struct (evil--jumps-get-current existing-window)) - (source-list (evil--jumps-get-jumps source-jump-struct))) - (when (= (ring-length (evil--jumps-get-jumps target-jump-struct)) 0) - (setf (evil-jumps-struct-previous-pos target-jump-struct) (evil-jumps-struct-previous-pos source-jump-struct)) - (setf (evil-jumps-struct-idx target-jump-struct) (evil-jumps-struct-idx source-jump-struct)) - (setf (evil-jumps-struct-ring target-jump-struct) (ring-copy source-list))))))) - ;; delete obsolete windows - (maphash (lambda (key _val) - (unless (member key window-list) - (evil--jumps-message "removing %s" key) - (remhash key evil--jumps-window-jumps))) - evil--jumps-window-jumps))) -(put 'evil--jumps-window-configuration-hook 'permanent-local-hook t) - -(defun evil--jump-hook (&optional command) - "`pre-command-hook' for evil-jumps. -Set jump point if COMMAND has a non-nil `:jump' property. Otherwise, -save the current position in case the command being executed will -change the current buffer." - (setq command (or command this-command)) - (if (evil-get-command-property command :jump) - (evil-set-jump) - (setf (evil-jumps-struct-previous-pos (evil--jumps-get-current)) - (point-marker)))) -(put 'evil--jump-hook 'permanent-local-hook t) - -(defun evil--jump-handle-buffer-crossing () - (let ((jump-command evil--jumps-jump-command)) - (setq evil--jumps-jump-command nil) - (dolist (frame (frame-list)) - (dolist (window (window-list frame)) - (let* ((struct (evil--jumps-get-current window)) - (previous-pos (evil-jumps-struct-previous-pos struct))) - (when previous-pos - (setf (evil-jumps-struct-previous-pos struct) nil) - (if (and - ;; `evil-jump-backward' and 'evil-jump-forward' need - ;; to be handled specially. When jumping backward - ;; multiple times, calling `evil-set-jump' is always - ;; wrong: If you jump back twice and we call - ;; `evil-set-jump' after the second time, we clear - ;; the forward jump list and `evil--jump-forward' - ;; won't work. - - ;; The first time you jump backward, setting a jump - ;; point is sometimes correct. But we don't do it - ;; here because this function is called after - ;; `evil--jump-backward' has updated our position in - ;; the jump list so, again, `evil-set-jump' would - ;; break `evil--jump-forward'. - (not jump-command) - (let ((previous-buffer (marker-buffer previous-pos))) - (and previous-buffer - (not (eq previous-buffer (window-buffer window)))))) - (evil-set-jump previous-pos) - (set-marker previous-pos nil)))))))) -(put 'evil--jump-handle-buffer-crossing 'permanent-local-hook t) - -(if (bound-and-true-p savehist-loaded) - (evil--jumps-savehist-load) - (add-hook 'savehist-mode-hook #'evil--jumps-savehist-load)) - -(defun evil--jumps-install-or-uninstall () - (if evil-local-mode - (progn - (add-hook 'pre-command-hook #'evil--jump-hook nil t) - (add-hook 'post-command-hook #'evil--jump-handle-buffer-crossing nil t) - (add-hook 'next-error-hook #'evil-set-jump nil t) - (add-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook nil t)) - (remove-hook 'pre-command-hook #'evil--jump-hook t) - (remove-hook 'post-command-hook #'evil--jump-handle-buffer-crossing t) - (remove-hook 'next-error-hook #'evil-set-jump t) - (remove-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook t))) - -(add-hook 'evil-local-mode-hook #'evil--jumps-install-or-uninstall) - -(provide 'evil-jumps) - -;;; evil-jumps.el ends here diff --git a/.config/emacs/lisp/evil/evil-keybindings.el b/.config/emacs/lisp/evil/evil-keybindings.el deleted file mode 100644 index 81a8b00..0000000 --- a/.config/emacs/lisp/evil/evil-keybindings.el +++ /dev/null @@ -1,124 +0,0 @@ -;;; evil-keybindings.el --- Add some Evil keybindings to other modules -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; This provides a set of keybindings for other emacs modes. This also includes -;; setting up the initial evil state of those other modes. - -;;; Code: - -(require 'evil-maps) -(require 'evil-core) -(require 'evil-macros) -(require 'evil-types) -(require 'evil-repeat) - -;; etags-select -;; FIXME: probably etags-select should be recomended in docs -(eval-after-load 'etags-select - '(progn - (define-key evil-motion-state-map "g]" 'etags-select-find-tag-at-point))) - -;;; Buffer-menu - -(evil-add-hjkl-bindings Buffer-menu-mode-map 'motion) - -;; dictionary.el - -(evil-add-hjkl-bindings dictionary-mode-map 'motion - "?" 'dictionary-help ; "h" - "C-o" 'dictionary-previous) ; "l" - -;;; Dired - -(eval-after-load 'dired - '(progn - ;; use the standard Dired bindings as a base - (defvar dired-mode-map) - (evil-make-overriding-map dired-mode-map 'normal) - (evil-add-hjkl-bindings dired-mode-map 'normal - "J" 'dired-goto-file ; "j" - "K" 'dired-do-kill-lines ; "k" - "r" 'dired-do-redisplay ; "l" - ;; ":d", ":v", ":s", ":e" - ";" (lookup-key dired-mode-map ":")))) - -;;; ERT - -(evil-add-hjkl-bindings ert-results-mode-map 'motion) - -;;; Info - -(evil-add-hjkl-bindings Info-mode-map 'motion - "0" 'evil-beginning-of-line - (kbd "\M-h") 'Info-help ; "h" - "\C-t" 'Info-history-back ; "l" - "\C-o" 'Info-history-back - " " 'Info-scroll-up - "\C-]" 'Info-follow-nearest-node - (kbd "DEL") 'Info-scroll-down) - -;;; Speedbar - -(evil-add-hjkl-bindings speedbar-mode-map 'motion - "h" 'backward-char - "j" 'speedbar-next - "k" 'speedbar-prev - "l" 'forward-char - "i" 'speedbar-item-info - "r" 'speedbar-refresh - "u" 'speedbar-up-directory - "o" 'speedbar-toggle-line-expansion - (kbd "RET") 'speedbar-edit-line) - -;; Ibuffer -(eval-after-load 'ibuffer - '(progn - (defvar ibuffer-mode-map) - (evil-make-overriding-map ibuffer-mode-map 'normal) - (evil-define-key 'normal ibuffer-mode-map - "j" 'evil-next-line - "k" 'evil-previous-line - (kbd "RET") 'ibuffer-visit-buffer))) - -;;; ag.el -(eval-after-load 'ag - '(progn - (defvar ag-mode-map) - (add-to-list 'evil-motion-state-modes 'ag-mode) - (evil-add-hjkl-bindings ag-mode-map 'motion))) - -;;; ELP - -(advice-add 'elp-results :after #'evil--set-motion-state) -(defun evil--set-motion-state (&rest _) - (evil-motion-state)) - -(provide 'evil-keybindings) - -;;; evil-keybindings.el ends here diff --git a/.config/emacs/lisp/evil/evil-macros.el b/.config/emacs/lisp/evil/evil-macros.el deleted file mode 100644 index 0f7fd59..0000000 --- a/.config/emacs/lisp/evil/evil-macros.el +++ /dev/null @@ -1,772 +0,0 @@ -;;; evil-macros.el --- Macros -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(require 'evil-common) -(require 'evil-states) -(require 'evil-repeat) - -(declare-function evil-ex-p "evil-ex") -(declare-function evil-line-or-visual-line "evil-commands") - -;; set some error codes -(put 'beginning-of-line 'error-conditions '(beginning-of-line error)) -(put 'beginning-of-line 'error-message "Beginning of line") -(put 'end-of-line 'error-conditions '(end-of-line error)) -(put 'end-of-line 'error-message "End of line") -;; we don't want line boundaries to trigger the debugger -;; when `debug-on-error' is t -(cl-pushnew 'beginning-of-line debug-ignored-errors) -(cl-pushnew 'end-of-line debug-ignored-errors) - -(defun evil-motion-range (motion &optional count type) - "Execute a motion and return the buffer positions. -The return value is a list (BEG END TYPE)." - (let ((opoint (point)) - (omark (mark t)) - (obuffer (current-buffer)) - (evil-motion-marker (move-marker (make-marker) (point))) - range) - (evil-with-transient-mark-mode - (evil-narrow-to-field - (unwind-protect - (let ((current-prefix-arg count) - ;; Store type in global variable `evil-this-type'. - ;; If necessary, motions can change their type - ;; during execution by setting this variable. - (evil-this-type - (or type (evil-get-command-property motion :type 'exclusive)))) - (condition-case err - (let ((repeat-type (evil--repeat-type motion))) - (when (functionp repeat-type) (funcall repeat-type 'pre)) - (unless (with-local-quit - (setq range (call-interactively motion)) - t) - (evil-repeat-abort) - (setq quit-flag t)) - (when (functionp repeat-type) (funcall repeat-type 'post))) - (error - (evil-repeat-abort) - ;; some operators depend on succeeding motions, in - ;; particular for `evil-forward-char' (e.g., used by - ;; `evil-substitute'), therefore we let end-of-line - ;; and end-of-buffer pass - (if (memq (car err) '(end-of-line end-of-buffer)) - (message (error-message-string err)) - (signal (car err) (cdr err))))) - (cond - ;; the motion returned a range - ((evil-range-p range)) - ;; the motion made a Visual selection - ((evil-visual-state-p) - (setq range (evil-visual-range))) - ;; the motion made an active region - ((region-active-p) - (setq range (evil-range (region-beginning) (region-end) - evil-this-type))) - ;; default: range from previous position to current - (t (setq range (evil-expand-range - (evil-normalize evil-motion-marker - (point) - evil-this-type))))) - (unless (or (null type) (eq (evil-type range) type)) - (evil-set-type range type) - (evil-expand-range range)) - (evil-set-range-properties range nil) - range) - ;; restore point and mark like `save-excursion', - ;; but only if the motion hasn't disabled the operator - (unless evil-inhibit-operator - (set-buffer obuffer) - (evil-move-mark omark) - (goto-char opoint)) - ;; delete marker so it doesn't slow down editing - (move-marker evil-motion-marker nil)))))) - -(defmacro evil-define-motion (motion args &rest body) - "Define a motion command MOTION. -ARGS is a list of arguments. Motions can have any number of -arguments, but the first (if any) has the predefined meaning of -count. BODY must execute the motion by moving point. - -Optional keyword arguments are: -- `:type' - determines how the motion works after an operator (one of - `inclusive', `line', `block' and `exclusive', or a self-defined - motion type) -- `:jump' - if non-nil, the previous position is stored in the jump - list, so that it can be restored with \ -\\<evil-motion-state-map>\\[evil-jump-backward] - -\(fn MOTION (COUNT ARGS...) DOC [[KEY VALUE]...] BODY...)" - (declare (indent defun) - (doc-string 3) - (debug (&define name lambda-list - [&optional stringp] - [&rest keywordp sexp] - [&optional ("interactive" [&rest form])] - def-body))) - (let (arg doc interactive key keys) - (when args - (setq args `(&optional ,@(delq '&optional args)) - ;; the count is either numerical or nil - interactive '("<c>"))) - ;; collect docstring - (when (and (> (length body) 1) - (or (eq (car-safe (car body)) #'format) - (stringp (car body)))) - (setq doc (pop body))) - ;; collect keywords - (setq keys (plist-put keys :repeat 'motion)) - (while (keywordp (car body)) - (setq key (pop body) - arg (pop body) - keys (plist-put keys key arg))) - ;; collect `interactive' specification - (when (eq (car-safe (car body)) 'interactive) - (setq interactive (cdr (pop body)))) - ;; macro expansion - `(progn - ;; refresh echo area in Eldoc mode - (when ',motion - (eval-after-load 'eldoc - '(and (fboundp 'eldoc-add-command) - (eldoc-add-command ',motion)))) - (evil-define-command ,motion (,@args) - ,@(when doc `(,doc)) ; avoid nil before `interactive' - ,@keys - :keep-visual t - (interactive ,@interactive) - ,@body)))) - -(defmacro evil-narrow-to-line (&rest body) - "Narrow BODY to the current line. -BODY will signal `beginning-of-line' or `end-of-line' upon reaching -the beginning or end of the current line." - (declare (indent defun) (debug t)) - `(cl-destructuring-bind (beg end &rest) (evil-line-expand (point) (point)) - (when (save-excursion (goto-char end) (bolp)) - (setq end (max beg (1- end)))) - ;; Do not include the newline in Normal state - (or evil-move-beyond-eol - (evil-visual-state-p) (evil-operator-state-p) - (setq end (max beg (1- end)))) - (evil-with-restriction beg end - (condition-case err - (progn ,@body) - (beginning-of-buffer - (signal (if (= (point-min) beg) 'beginning-of-line (car err)) - (cdr err))) - (end-of-buffer - (signal (if (= (point-max) end) 'end-of-line (car err)) - (cdr err))))))) - -(defun evil-eobp (&optional pos) - "Whether point is at end-of-buffer with regard to end-of-line." - (save-excursion - (when pos (goto-char pos)) - (cond - ((eobp)) - ;; the rest only pertains to Normal state - ((not (evil-normal-state-p)) nil) - ;; at the end of the last line - ((eolp) - (forward-char) - (eobp)) - ;; at the last character of the last line - (t - (forward-char) - (cond - ((eobp)) - ((eolp) - (forward-char) - (eobp))))))) - -(defun evil-move-beginning (count forward &optional backward) - "Move to the beginning of the COUNT next object. -If COUNT is negative, move to the COUNT previous object. -FORWARD is a function which moves to the end of the object, and -BACKWARD is a function which moves to the beginning. -If one is unspecified, the other is used with a negative argument." - (let* ((count (or count 1)) - (backward (or backward - #'(lambda (count) - (funcall forward (- count))))) - (forward (or forward - #'(lambda (count) - (funcall backward (- count))))) - (opoint (point))) - (cond - ((< count 0) - (when (bobp) - (signal 'beginning-of-buffer nil)) - (unwind-protect - (evil-motion-loop (nil count count) - (funcall backward 1)) - (unless (zerop count) - (goto-char (point-min))))) - ((> count 0) - (when (evil-eobp) - (signal 'end-of-buffer nil)) - ;; Do we need to move past the current object? - (when (<= (save-excursion - (funcall forward 1) - (funcall backward 1) - (point)) - opoint) - (setq count (1+ count))) - (unwind-protect - (evil-motion-loop (nil count count) - (funcall forward 1)) - (if (zerop count) - ;; go back to beginning of object - (funcall backward 1) - (goto-char (point-max))))) - (t count)))) - -(defun evil-move-end (count forward &optional backward inclusive) - "Move to the end of the COUNT next object. -If COUNT is negative, move to the COUNT previous object. -FORWARD is a function which moves to the end of the object, and -BACKWARD is a function which moves to the beginning. -If one is unspecified, the other is used with a negative argument. -If INCLUSIVE is non-nil, then point is placed at the last character -of the object; otherwise it is placed at the end of the object." - (let* ((count (or count 1)) - (backward (or backward - #'(lambda (count) - (funcall forward (- count))))) - (forward (or forward - #'(lambda (count) - (funcall backward (- count))))) - (opoint (point))) - (cond - ((< count 0) - (when (bobp) - (signal 'beginning-of-buffer nil)) - ;; Do we need to move past the current object? - (when (>= (save-excursion - (funcall backward 1) - (funcall forward 1) - (point)) - (if inclusive - (1+ opoint) - opoint)) - (setq count (1- count))) - (unwind-protect - (evil-motion-loop (nil count count) - (funcall backward 1)) - (if (not (zerop count)) - (goto-char (point-min)) - ;; go to end of object - (funcall forward 1) - (when inclusive - (unless (bobp) (backward-char))) - (when (or (evil-normal-state-p) - (evil-motion-state-p)) - (evil-adjust-cursor))))) - ((> count 0) - (when (evil-eobp) - (signal 'end-of-buffer nil)) - (when inclusive - (forward-char)) - (unwind-protect - (evil-motion-loop (nil count count) - (funcall forward 1)) - (if (not (zerop count)) - (goto-char (point-max)) - (when inclusive - (unless (bobp) (backward-char))) - (when (or (evil-normal-state-p) - (evil-motion-state-p)) - (evil-adjust-cursor))))) - (t count)))) - -(defun evil-text-object-make-linewise (range) - "Turn the text object selection RANGE to linewise. -The selection is adjusted in a sensible way so that the selected -lines match the user intent. In particular, whitespace-only parts -at the first and last lines are omitted. This function returns -the new range." - ;; Bug #607 - ;; If new type is linewise and the selection of the - ;; first line consists of whitespace only, the - ;; beginning is moved to the start of the next line. If - ;; the selections of the last line consists of - ;; whitespace only, the end is moved to the end of the - ;; previous line. - (if (eq (evil-type range) 'line) - range - (let ((expanded (plist-get (evil-range-properties range) :expanded)) - (newrange (evil-expand-range range t))) - (save-excursion - ;; skip whitespace at the beginning - (goto-char (evil-range-beginning newrange)) - (skip-chars-forward " \t") - (when (and (not (bolp)) (eolp)) - (evil-set-range-beginning newrange (1+ (point)))) - ;; skip whitepsace at the end - (goto-char (evil-range-end newrange)) - (skip-chars-backward " \t") - (when (and (not (eolp)) (bolp)) - (evil-set-range-end newrange (1- (point)))) - ;; only modify range if result is not empty - (if (> (evil-range-beginning newrange) - (evil-range-end newrange)) - range - (unless expanded - (evil-contract-range newrange)) - newrange))))) - -(defmacro evil-define-text-object (object args &rest body) - "Define a text object command OBJECT. -BODY should return a range (BEG END) to the right of point -if COUNT is positive, and to the left of it if negative. - -Optional keyword arguments: -- `:type' - determines how the range applies after an operator - (`inclusive', `line', `block', and `exclusive', or a self-defined - motion type). -- `:extend-selection' - if non-nil (default), the text object always - enlarges the current selection. Otherwise, it replaces the current - selection. - -\(fn OBJECT (COUNT) DOC [[KEY VALUE]...] BODY...)" - (declare (indent defun) - (doc-string 3) - (debug (&define name lambda-list - [&optional stringp] - [&rest keywordp sexp] - def-body))) - (let* ((args (delq '&optional args)) - (count (or (pop args) 'count)) - (args (when args `(&optional ,@args))) - (interactive '(interactive "<c><v>")) - doc keys) - ;; collect docstring - (when (stringp (car body)) - (setq doc (pop body))) - ;; collect keywords - (setq keys (plist-put keys :extend-selection t)) - (while (keywordp (car body)) - (setq keys (plist-put keys (pop body) (pop body)))) - ;; interactive - (when (eq (car-safe (car body)) 'interactive) - (setq interactive (pop body))) - ;; macro expansion - `(evil-define-motion ,object (,count ,@args) - ,@(when doc `(,doc)) - ,@keys - ,interactive - (setq ,count (or ,count 1)) - (when (/= ,count 0) - ;; FIXME: These let-bindings shadow variables in args - (let ((type (evil-type ',object evil-visual-char)) - (extend (and (evil-visual-state-p) - (evil-get-command-property - ',object :extend-selection - ',(plist-get keys :extend-selection)))) - (dir evil-visual-direction) - mark point range selection) - (cond - ;; Visual state: extend the current selection - ((and (evil-visual-state-p) - (called-interactively-p 'any)) - ;; if we are at the beginning of the Visual selection, - ;; go to the left (negative COUNT); if at the end, - ;; go to the right (positive COUNT) - (setq dir evil-visual-direction - ,count (* ,count dir)) - (setq range (progn ,@body)) - (when (evil-range-p range) - (setq range (evil-expand-range range)) - (evil-set-type range (evil-type range type)) - (setq range (evil-contract-range range)) - ;; the beginning is mark and the end is point - ;; unless the selection goes the other way - (setq mark (evil-range-beginning range) - point (evil-range-end range) - type (evil-type - (if evil-text-object-change-visual-type - range - (evil-visual-range)))) - (when (and (eq type 'line) - (not (eq type (evil-type range)))) - (let ((newrange (evil-text-object-make-linewise range))) - (setq mark (evil-range-beginning newrange) - point (evil-range-end newrange)))) - (when (< dir 0) - (evil-swap mark point)) - ;; select the union - (evil-visual-make-selection mark point type))) - ;; not Visual state: return a pair of buffer positions - (t - (setq range (progn ,@body)) - (unless (evil-range-p range) - (setq ,count (- ,count) - range (progn ,@body))) - (when (evil-range-p range) - (setq selection (evil-range (point) (point) type)) - (if extend - (setq range (evil-range-union range selection)) - (evil-set-type range (evil-type range type))) - ;; possibly convert to linewise - (when (eq evil-this-type-modified 'line) - (setq range (evil-text-object-make-linewise range))) - (evil-set-range-properties range nil) - range)))))))) - -(defmacro evil-define-operator (operator args &rest body) - "Define an operator command OPERATOR. -The operator acts on the range of characters BEG through -END. BODY must execute the operator by potentially manipulating -the buffer contents, or otherwise causing side effects to happen. - -Optional keyword arguments are: -- `:type' - force the input range to be of a given type (`inclusive', - `line', `block', and `exclusive', or a self-defined motion type). -- `:motion' - use a predetermined motion instead of waiting for one - from the keyboard. This does not affect the behavior in visual - state, where selection boundaries are always used. -- `:repeat' - if non-nil (default), then \ - \\<evil-normal-state-map>\\[evil-repeat] will repeat the - operator. -- `:move-point' - if non-nil (default), the cursor will be moved to - the beginning of the range before the body executes -- `:keep-visual' - if non-nil, the selection is not disabled when the - operator is executed in visual state. By default, visual state is - exited automatically. -- `:restore-point' - if non-nil, point is restored when the - operator is executed from ex. - -\(fn OPERATOR (BEG END ARGS...) DOC [[KEY VALUE]...] BODY...)" - (declare (indent defun) - (doc-string 3) - (debug (&define name lambda-list - [&optional stringp] - [&rest keywordp sexp] - [&optional ("interactive" [&rest form])] - def-body))) - (let* ((args (delq '&optional args)) - (interactive (if (> (length args) 2) '("<R>") '("<r>"))) - (args (if (> (length args) 2) - `(,(nth 0 args) ,(nth 1 args) - &optional ,@(nthcdr 2 args)) - args)) - (end-marker (make-symbol "end-marker")) - arg doc key keys visual) - ;; collect docstring - (when (and (> (length body) 1) - (or (eq (car-safe (car-safe body)) 'format) - (stringp (car-safe body)))) - (setq doc (pop body))) - ;; collect keywords - (setq keys (plist-put keys :move-point t)) - (while (keywordp (car-safe body)) - (setq key (pop body) - arg (pop body)) - (cond - ((eq key :keep-visual) - (setq visual arg)) - (t - (setq keys (plist-put keys key arg))))) - ;; collect `interactive' specification - (when (eq (car-safe (car-safe body)) 'interactive) - (setq interactive (cdr-safe (pop body)))) - ;; transform extended interactive specs - (setq interactive (apply #'evil-interactive-form interactive)) - (setq keys (evil-concat-plists keys (cdr-safe interactive)) - interactive (car-safe interactive)) - ;; macro expansion - `(evil-define-command ,operator ,args - ,@(when doc `(,doc)) - ,@keys - :keep-visual t - :suppress-operator t - (interactive - (let* ((props (evil-command-properties ',operator)) - (evil-operator-range-motion - (let ((p (plist-member props :motion))) - ;; :motion nil is equivalent to :motion undefined - (when p (or (cadr p) #'undefined)))) - (evil-operator-range-type (plist-get props :type)) - evil-operator-range-beginning evil-operator-range-end - evil-inhibit-operator) - (setq evil-inhibit-operator-value nil - evil-this-operator this-command - evil-operator-start-col (current-column)) - (prog1 ,interactive - (setq evil-inhibit-operator-value evil-inhibit-operator) - (if ,visual - (when (evil-visual-state-p) (evil-visual-expand-region)) - (setq deactivate-mark t)) - (cond - ((evil-visual-state-p) - (evil-visual-rotate 'upper-left)) - ((plist-get props :move-point) - (when evil-operator-range-beginning - (goto-char evil-operator-range-beginning))))))) - (unwind-protect - (let ((evil-inhibit-operator evil-inhibit-operator-value) - (,end-marker (make-marker))) - (set-marker ,end-marker ,(cadr args)) - (unless (and evil-inhibit-operator - (called-interactively-p 'any)) - ,@body) - (evil-set-marker ?\[ (or ,(car args) (point-max))) - (evil-set-marker ?\] (max (or ,(car args) (point-max)) - (1- (or (marker-position ,end-marker) (point-max))))) - (set-marker ,end-marker nil)) - (setq evil-inhibit-operator-value nil))))) - -;; this is used in the `interactive' specification of an operator command -(defun evil-operator-range (&optional return-type) - "Read a motion from the keyboard and return its buffer positions. -The return value is a list (BEG END), or (BEG END TYPE) if -RETURN-TYPE is non-nil." - (let ((motion (or evil-operator-range-motion - (when evil-called-from-ex-p 'evil-line))) - (type evil-operator-range-type) - range count) - (setq evil-this-type-modified nil) - (cond - ;; Ex command - ((and evil-called-from-ex-p evil-ex-range) - (setq range evil-ex-range)) - ;; Visual selection - ((and (not evil-called-from-ex-p) (evil-visual-state-p)) - (setq range (evil-visual-range))) - ;; active region - ((and (not evil-called-from-ex-p) (region-active-p)) - (setq range (evil-range (region-beginning) (region-end) - (or evil-this-type 'exclusive)))) - ;; motion - (t - (evil-save-echo-area - (evil-save-state - (unless motion - ;; Make linewise operator shortcuts. E.g., "d" yields the - ;; shortcut "dd", and "g?" yields shortcuts "g??" and "g?g?". - (let ((keys (nth 2 (evil-extract-count (this-command-keys))))) - (evil-change-state 'operator) - (cl-loop for keys on (listify-key-sequence keys) do - (define-key evil-operator-shortcut-map - (vconcat keys) #'evil-line-or-visual-line))) - ;; read motion from keyboard - (let ((command (evil-read-motion motion))) - (setq motion (car command) - count (cadr command) - type (or type (nth 2 command))))) - (cond - ((eq motion #'undefined) - (setq range (list nil nil) - motion nil)) - ((or (null motion) ; keyboard-quit - (evil-get-command-property motion :suppress-operator)) - (evil-repeat-abort) - (setq quit-flag t - range (evil-range (point) (point)) ; zero-len range - motion nil)) - (evil-repeat-count - (setq count evil-repeat-count - ;; only the first operator's count is overwritten - evil-repeat-count nil)) - ((or count current-prefix-arg) - ;; multiply operator count and motion count together - (setq count - (* (prefix-numeric-value count) - (prefix-numeric-value current-prefix-arg))))) - (when motion - (let ((evil-state 'operator) - mark-active) - ;; calculate motion range - (setq range (evil-motion-range motion count type)))) - ;; update global variables - (setq evil-this-motion motion - evil-this-motion-count count - type (evil-type range type) - evil-this-type type))))) - (unless (or (null type) (eq (evil-type range) type)) - (evil-contract-range range) - (evil-set-range-type range type) - (evil-expand-range range)) - (setq evil-operator-range-beginning (evil-range-beginning range) - evil-operator-range-end (evil-range-end range) - evil-operator-range-type (evil-type range)) - (setcdr (cdr range) - (when return-type (list (evil-type range)))) - range)) - -(defmacro evil-define-type (type doc &rest body) - "Define type TYPE. -DOC is a general description and shows up in all docstrings. - -Optional keyword arguments: -- `:expand' - expansion function. This function should accept two - positions in the current buffer, BEG and END,and return a pair of - expanded buffer positions. -- `:contract' - the opposite of `:expand'. Optional. -- `:one-to-one' - non-nil if expansion is one-to-one. This means that - `:expand' followed by `:contract' always return the original range. -- `:normalize' - normalization function. This function should accept - two unexpanded positions and adjust them before expansion. May be - used to deal with buffer boundaries. -- `:string' - description function. Takes two buffer positions and - returns a human-readable string. For example \"2 lines\" - -If further keywords and functions are specified, they are assumed to -be transformations on buffer positions, like `:expand' and `:contract'. - -\(fn TYPE DOC [[KEY FUNC]...])" - (declare (indent defun) - (doc-string 2) - (debug (&define name - [&optional stringp] - [&rest [keywordp function-form]]))) - (let ((plist (list :one-to-one t)) ; standard values - args defun-forms func key name string sym val) - ;; keywords - (while (keywordp (car-safe body)) - (setq key (pop body) - val (pop body)) - (if (plist-member plist key) ; not a function - (setq plist (plist-put plist key val)) - (setq func val - sym (intern (replace-regexp-in-string - "^:" "" (symbol-name key))) - name (intern (format "evil-%s-%s" type sym)) - args (car (cdr-safe func)) - string (cadr (cdr-safe func)) - string (if (stringp string) - (format "%s\n\n" string) "") - plist (plist-put plist key `',name)) - (push - (cond - ((eq key :string) - `(defun ,name (beg end &rest properties) - ,(format "Return size of %s from BEG to END \ -with PROPERTIES.\n\n%s%s" type string doc) - (let ((type ',type) - plist range) - (when (and beg end) - (evil-sort beg end) - (save-excursion - (unless (plist-get properties :expanded) - (setq range (apply #'evil-expand - beg end type properties) - beg (evil-range-beginning range) - end (evil-range-end range) - type (evil-type range type) - plist (evil-range-properties range)) - (setq properties - (evil-concat-plists properties plist))) - (or (apply #',func beg end - (when ,(> (length args) 2) - properties)) - "")))))) - (t - `(defun ,name (beg end &rest properties) - ,(format "Perform %s transformation on %s from BEG to END \ -with PROPERTIES.\n\n%s%s" sym type string doc) - (let ((type ',type) - plist range) - (when (and beg end) - (evil-sort beg end) - (save-excursion - (when (memq ,key '(:expand :contract)) - (setq properties - (plist-put properties - :expanded ,(eq key :expand)))) - (setq range (or (apply #',func beg end - (when ,(> (length args) 2) - properties)) - (apply #'evil-range - beg end type properties)) - beg (evil-range-beginning range) - end (evil-range-end range) - type (evil-type range type) - plist (evil-range-properties range)) - (setq properties - (evil-concat-plists properties plist)) - (apply #'evil-range beg end type properties))))))) - defun-forms))) - ;; :one-to-one requires both or neither of :expand and :contract - (when (plist-get plist :expand) - (setq plist (plist-put plist :one-to-one - (and (plist-get plist :contract) - (plist-get plist :one-to-one))))) - `(progn - (evil--add-to-alist evil-type-properties ',type (list ,@plist)) - ,@defun-forms - ',type))) - -(defmacro evil-define-interactive-code (code &rest body) - "Define an interactive code. -PROMPT, if given, is the remainder of the interactive string -up to the next newline. Command properties may be specified -via KEY-VALUE pairs. BODY should evaluate to a list of values. - -\(fn CODE (PROMPT) [[KEY VALUE]...] BODY...)" - (declare (indent defun)) - (let* ((args (and (> (length body) 1) (listp (car body)) - (pop body))) - (doc (when (stringp (car body)) (pop body))) - (properties - (cl-loop while (keywordp (car body)) - collect (pop body) collect (pop body))) - (func (if args - `(lambda ,args - ,@(when doc `(,doc)) - ,@body) - `',(macroexp-progn body)))) - `(eval-and-compile - (evil--add-to-alist - evil-interactive-alist ,code (cons ,func ',properties)) - ,code))) - -;;; Highlighting - -(when (fboundp 'font-lock-add-keywords) - (font-lock-add-keywords - 'emacs-lisp-mode - ;; Match all `evil-define-' forms except `evil-define-key'. - ;; (In the interests of speed, this expression is incomplete - ;; and does not match all three-letter words.) - '(("(\\(evil-\\(?:ex-\\)?define-\ -\\(?:[^ k][^ e][^ y]\\|[-[:word:]]\\{4,\\}\\)\\)\ -\\>[ \f\t\n\r\v]*\\(\\(?:\\sw\\|\\s_\\)+\\)?" - (1 'font-lock-keyword-face) - (2 'font-lock-function-name-face nil t)) - ("(\\(evil-\\(?:delay\\|narrow\\|signal\\|save\\|with\\(?:out\\)?\\)\ -\\(?:-[-[:word:]]+\\)?\\)\\>\[ \f\t\n\r\v]+" - 1 'font-lock-keyword-face) - ("(\\(evil-\\(?:[-[:word:]]\\)*loop\\)\\>[ \f\t\n\r\v]+" - 1 'font-lock-keyword-face)))) - -(provide 'evil-macros) - -;;; evil-macros.el ends here diff --git a/.config/emacs/lisp/evil/evil-maps.el b/.config/emacs/lisp/evil/evil-maps.el deleted file mode 100644 index 6778023..0000000 --- a/.config/emacs/lisp/evil/evil-maps.el +++ /dev/null @@ -1,686 +0,0 @@ -;;; evil-maps.el --- Default keymaps -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(require 'evil-states) -(require 'evil-ex) -(require 'evil-commands) -(require 'evil-command-window) -(require 'evil-common) - -;;; Normal state - -(define-key evil-normal-state-map "a" 'evil-append) -(define-key evil-normal-state-map "A" 'evil-append-line) -(define-key evil-normal-state-map "c" 'evil-change) -(define-key evil-normal-state-map "C" 'evil-change-line) -(define-key evil-normal-state-map "d" 'evil-delete) -(define-key evil-normal-state-map "D" 'evil-delete-line) -(define-key evil-normal-state-map "i" 'evil-insert) -(define-key evil-normal-state-map (kbd "<insert>") 'evil-insert) -(define-key evil-normal-state-map (kbd "<insertchar>") 'evil-insert) -(define-key evil-normal-state-map "I" 'evil-insert-line) -(define-key evil-normal-state-map "J" 'evil-join) -(define-key evil-normal-state-map "m" 'evil-set-marker) -(define-key evil-normal-state-map "o" 'evil-open-below) -(define-key evil-normal-state-map "O" 'evil-open-above) -(define-key evil-normal-state-map "p" 'evil-paste-after) -(define-key evil-normal-state-map "P" 'evil-paste-before) -(define-key evil-normal-state-map "q" 'evil-record-macro) -(define-key evil-normal-state-map "Q" 'evil-execute-last-recorded-macro) -(define-key evil-normal-state-map "r" 'evil-replace) -(define-key evil-normal-state-map "R" 'evil-enter-replace-state) -(define-key evil-normal-state-map "s" 'evil-substitute) -(define-key evil-normal-state-map "S" 'evil-change-whole-line) -(define-key evil-normal-state-map "x" 'evil-delete-char) -(define-key evil-normal-state-map "X" 'evil-delete-backward-char) -(define-key evil-normal-state-map [deletechar] 'evil-delete-char) -(define-key evil-normal-state-map "y" 'evil-yank) -(define-key evil-normal-state-map "Y" 'evil-yank-line) -(define-key evil-normal-state-map "&" 'evil-ex-repeat-substitute) -(define-key evil-normal-state-map "g&" 'evil-ex-repeat-global-substitute) -(define-key evil-normal-state-map "g8" 'what-cursor-position) -(define-key evil-normal-state-map "ga" 'what-cursor-position) -(define-key evil-normal-state-map "gi" 'evil-insert-resume) -(define-key evil-normal-state-map "gI" 'evil-insert-0-line) -(define-key evil-normal-state-map "gJ" 'evil-join-whitespace) -(define-key evil-normal-state-map "gp" 'evil-paste-after-cursor-after) -(define-key evil-normal-state-map "gP" 'evil-paste-before-cursor-after) -(define-key evil-normal-state-map "gq" 'evil-fill-and-move) -(define-key evil-normal-state-map "gw" 'evil-fill) -(define-key evil-normal-state-map "gu" 'evil-downcase) -(define-key evil-normal-state-map "gU" 'evil-upcase) -(define-key evil-normal-state-map "gf" 'find-file-at-point) -(define-key evil-normal-state-map "]f" 'find-file-at-point) -(define-key evil-normal-state-map "[f" 'find-file-at-point) -(define-key evil-normal-state-map "gF" 'evil-find-file-at-point-with-line) -(define-key evil-normal-state-map "]F" 'evil-find-file-at-point-with-line) -(define-key evil-normal-state-map "[F" 'evil-find-file-at-point-with-line) -(define-key evil-normal-state-map "gx" 'browse-url-at-point) -(define-key evil-normal-state-map "g?" 'evil-rot13) -(define-key evil-normal-state-map "g~" 'evil-invert-case) -(define-key evil-normal-state-map "zo" 'evil-open-fold) -(define-key evil-normal-state-map "zO" 'evil-open-fold-rec) -(define-key evil-normal-state-map "zc" 'evil-close-fold) -(define-key evil-normal-state-map "za" 'evil-toggle-fold) -(define-key evil-normal-state-map "zr" 'evil-open-folds) -(define-key evil-normal-state-map "zm" 'evil-close-folds) -(define-key evil-normal-state-map "z=" 'ispell-word) -(define-key evil-normal-state-map "\C-n" 'evil-paste-pop-next) -(define-key evil-normal-state-map "\C-p" 'evil-paste-pop) -(define-key evil-normal-state-map "\C-t" 'pop-tag-mark) -(define-key evil-normal-state-map (kbd "C-.") 'evil-repeat-pop) -(define-key evil-normal-state-map (kbd "M-.") 'evil-repeat-pop-next) -(define-key evil-normal-state-map "." 'evil-repeat) -(define-key evil-normal-state-map "@" 'evil-execute-macro) -(define-key evil-normal-state-map "\"" 'evil-use-register) -(define-key evil-normal-state-map "~" 'evil-invert-char) -(define-key evil-normal-state-map "=" 'evil-indent) -(define-key evil-normal-state-map "<" 'evil-shift-left) -(define-key evil-normal-state-map ">" 'evil-shift-right) -(define-key evil-normal-state-map "ZZ" 'evil-save-modified-and-close) -(define-key evil-normal-state-map "ZQ" 'evil-quit) -(define-key evil-normal-state-map (kbd "DEL") 'evil-backward-char) -(define-key evil-normal-state-map [escape] 'evil-force-normal-state) -(define-key evil-normal-state-map [remap cua-paste-pop] 'evil-paste-pop) -(define-key evil-normal-state-map [remap yank-pop] 'evil-paste-pop) - -;; go to last change -(define-key evil-normal-state-map "g;" 'evil-goto-last-change) -(define-key evil-normal-state-map "g," 'evil-goto-last-change-reverse) - -;; undo -(define-key evil-normal-state-map "u" 'evil-undo) -(define-key evil-normal-state-map "\C-r" 'evil-redo) - -;; window commands -(define-prefix-command 'evil-window-map) -(define-key evil-window-map "b" 'evil-window-bottom-right) -(define-key evil-window-map "c" 'evil-window-delete) -(define-key evil-window-map "f" 'ffap-other-window) -(define-key evil-window-map "h" 'evil-window-left) -(define-key evil-window-map "H" 'evil-window-move-far-left) -(define-key evil-window-map "j" 'evil-window-down) -(define-key evil-window-map "J" 'evil-window-move-very-bottom) -(define-key evil-window-map "k" 'evil-window-up) -(define-key evil-window-map "K" 'evil-window-move-very-top) -(define-key evil-window-map "l" 'evil-window-right) -(define-key evil-window-map "L" 'evil-window-move-far-right) -(define-key evil-window-map "n" 'evil-window-new) -(define-key evil-window-map "o" 'delete-other-windows) -(define-key evil-window-map "p" 'evil-window-mru) -(define-key evil-window-map "q" 'evil-quit) -(define-key evil-window-map "r" 'evil-window-rotate-downwards) -(define-key evil-window-map "R" 'evil-window-rotate-upwards) -(define-key evil-window-map "s" 'evil-window-split) -(define-key evil-window-map "S" 'evil-window-split) -(define-key evil-window-map "t" 'evil-window-top-left) -(when (featurep 'tab-bar) - (define-key evil-window-map "T" 'tab-window-detach)) -(define-key evil-window-map "v" 'evil-window-vsplit) -(define-key evil-window-map "w" 'evil-window-next) -(define-key evil-window-map "W" 'evil-window-prev) -(define-key evil-window-map "x" 'evil-window-exchange) -(define-key evil-window-map "+" 'evil-window-increase-height) -(define-key evil-window-map "-" 'evil-window-decrease-height) -(define-key evil-window-map ":" 'evil-ex) -(define-key evil-window-map "_" 'evil-window-set-height) -(define-key evil-window-map "<" 'evil-window-decrease-width) -(define-key evil-window-map ">" 'evil-window-increase-width) -(define-key evil-window-map "=" 'balance-windows) -(define-key evil-window-map (kbd "C-=") 'balance-windows) -(define-key evil-window-map "|" 'evil-window-set-width) -(define-key evil-window-map [down] 'evil-window-down) -(define-key evil-window-map [up] 'evil-window-up) -(define-key evil-window-map [left] 'evil-window-left) -(define-key evil-window-map [right] 'evil-window-right) -(define-key evil-window-map "\C-b" 'evil-window-bottom-right) -(define-key evil-window-map "\C-c" 'evil-window-delete) -(define-key evil-window-map "\C-f" 'ffap-other-window) -(define-key evil-window-map "\C-h" 'evil-window-left) -(define-key evil-window-map (kbd "C-S-h") 'evil-window-move-far-left) -(define-key evil-window-map "\C-j" 'evil-window-down) -(define-key evil-window-map (kbd "C-S-j") 'evil-window-move-very-bottom) -(define-key evil-window-map "\C-k" 'evil-window-up) -(define-key evil-window-map (kbd "C-S-k") 'evil-window-move-very-top) -(define-key evil-window-map "\C-l" 'evil-window-right) -(define-key evil-window-map (kbd "C-S-l") 'evil-window-move-far-right) -(define-key evil-window-map "\C-n" 'evil-window-new) -(define-key evil-window-map "\C-o" 'delete-other-windows) -(define-key evil-window-map "\C-p" 'evil-window-mru) -(define-key evil-window-map "\C-q" 'evil-quit) -(define-key evil-window-map "\C-r" 'evil-window-rotate-downwards) -(define-key evil-window-map (kbd "C-S-r") 'evil-window-rotate-upwards) -(define-key evil-window-map "\C-s" 'evil-window-split) -(define-key evil-window-map (kbd "C-S-s") 'evil-window-split) -(define-key evil-window-map "\C-t" 'evil-window-top-left) -(define-key evil-window-map "\C-v" 'evil-window-vsplit) -(define-key evil-window-map "\C-w" 'evil-window-next) -(define-key evil-window-map (kbd "C-S-W") 'evil-window-prev) -(define-key evil-window-map "\C-x" 'evil-window-exchange) -(define-key evil-window-map "\C-_" 'evil-window-set-height) -(define-key evil-window-map [C-down] 'evil-window-down) -(define-key evil-window-map [C-up] 'evil-window-up) -(define-key evil-window-map [C-left] 'evil-window-left) -(define-key evil-window-map [C-right] 'evil-window-right) -(define-key evil-window-map "0" 'evil-window-digit-argument) -(define-key evil-window-map "1" 'evil-window-digit-argument) -(define-key evil-window-map "2" 'evil-window-digit-argument) -(define-key evil-window-map "3" 'evil-window-digit-argument) -(define-key evil-window-map "4" 'evil-window-digit-argument) -(define-key evil-window-map "5" 'evil-window-digit-argument) -(define-key evil-window-map "6" 'evil-window-digit-argument) -(define-key evil-window-map "7" 'evil-window-digit-argument) -(define-key evil-window-map "8" 'evil-window-digit-argument) -(define-key evil-window-map "9" 'evil-window-digit-argument) - -(when (featurep 'tab-bar) - (define-key evil-motion-state-map "gt" 'evil-tab-next) - (define-key evil-window-map "gt" 'evil-tab-next) - (define-key evil-motion-state-map "gT" 'tab-bar-switch-to-prev-tab) - (define-key evil-window-map "gT" 'tab-bar-switch-to-prev-tab)) - -;;; Motion state - -;; "0" is a special command when called first -(define-key evil-motion-state-map "0" 'evil-beginning-of-line) -(define-key evil-motion-state-map "1" 'digit-argument) -(define-key evil-motion-state-map "2" 'digit-argument) -(define-key evil-motion-state-map "3" 'digit-argument) -(define-key evil-motion-state-map "4" 'digit-argument) -(define-key evil-motion-state-map "5" 'digit-argument) -(define-key evil-motion-state-map "6" 'digit-argument) -(define-key evil-motion-state-map "7" 'digit-argument) -(define-key evil-motion-state-map "8" 'digit-argument) -(define-key evil-motion-state-map "9" 'digit-argument) -(define-key evil-motion-state-map "b" 'evil-backward-word-begin) -(define-key evil-motion-state-map "B" 'evil-backward-WORD-begin) -(define-key evil-motion-state-map "e" 'evil-forward-word-end) -(define-key evil-motion-state-map "E" 'evil-forward-WORD-end) -(define-key evil-motion-state-map "f" 'evil-find-char) -(define-key evil-motion-state-map "F" 'evil-find-char-backward) -(define-key evil-motion-state-map "G" 'evil-goto-line) -(define-key evil-motion-state-map "h" 'evil-backward-char) -(define-key evil-motion-state-map "H" 'evil-window-top) -(define-key evil-motion-state-map "j" 'evil-next-line) -(define-key evil-motion-state-map "k" 'evil-previous-line) -(define-key evil-motion-state-map "l" 'evil-forward-char) -(define-key evil-motion-state-map " " 'evil-forward-char) -(define-key evil-motion-state-map "K" 'evil-lookup) -(define-key evil-motion-state-map "L" 'evil-window-bottom) -(define-key evil-motion-state-map "M" 'evil-window-middle) -(define-key evil-motion-state-map "n" 'evil-search-next) -(define-key evil-motion-state-map "N" 'evil-search-previous) -(define-key evil-motion-state-map "t" 'evil-find-char-to) -(define-key evil-motion-state-map "T" 'evil-find-char-to-backward) -(define-key evil-motion-state-map "w" 'evil-forward-word-begin) -(define-key evil-motion-state-map "W" 'evil-forward-WORD-begin) -(define-key evil-motion-state-map "y" 'evil-yank) -(define-key evil-motion-state-map "Y" 'evil-yank-line) -(define-key evil-motion-state-map "gd" 'evil-goto-definition) -(define-key evil-motion-state-map "ge" 'evil-backward-word-end) -(define-key evil-motion-state-map "gE" 'evil-backward-WORD-end) -(define-key evil-motion-state-map "gg" 'evil-goto-first-line) -(define-key evil-motion-state-map "gj" 'evil-next-visual-line) -(define-key evil-motion-state-map (vconcat "g" [down]) 'evil-next-visual-line) -(define-key evil-motion-state-map "gk" 'evil-previous-visual-line) -(define-key evil-motion-state-map (vconcat "g" [up]) 'evil-previous-visual-line) -(define-key evil-motion-state-map "g0" 'evil-beginning-of-visual-line) -(define-key evil-motion-state-map "g_" 'evil-last-non-blank) -(define-key evil-motion-state-map "g^" 'evil-first-non-blank-of-visual-line) -(define-key evil-motion-state-map (vconcat "g" [home]) 'evil-first-non-blank-of-visual-line) -(define-key evil-motion-state-map "gm" 'evil-middle-of-visual-line) -(define-key evil-motion-state-map "gM" 'evil-percentage-of-line) -(define-key evil-motion-state-map "go" 'evil-goto-char) -(define-key evil-motion-state-map "g$" 'evil-end-of-visual-line) -(define-key evil-motion-state-map (vconcat "g" [end]) 'evil-end-of-visual-line) -(define-key evil-motion-state-map "g\C-]" 'evil-jump-to-tag) -(define-key evil-motion-state-map "{" 'evil-backward-paragraph) -(define-key evil-motion-state-map "}" 'evil-forward-paragraph) -(define-key evil-motion-state-map "#" 'evil-search-word-backward) -(define-key evil-motion-state-map "g#" 'evil-search-unbounded-word-backward) -(define-key evil-motion-state-map "$" 'evil-end-of-line) -(define-key evil-motion-state-map [end] 'evil-end-of-line) -(define-key evil-motion-state-map [home] 'evil-beginning-of-line) -(define-key evil-motion-state-map "%" 'evil-jump-item) -(define-key evil-motion-state-map "`" 'evil-goto-mark) -(define-key evil-motion-state-map "'" 'evil-goto-mark-line) -(define-key evil-motion-state-map "(" 'evil-backward-sentence-begin) -(define-key evil-motion-state-map ")" 'evil-forward-sentence-begin) -(define-key evil-motion-state-map "]]" 'evil-forward-section-begin) -(define-key evil-motion-state-map "][" 'evil-forward-section-end) -(define-key evil-motion-state-map "[[" 'evil-backward-section-begin) -(define-key evil-motion-state-map "[]" 'evil-backward-section-end) -(define-key evil-motion-state-map "[(" 'evil-previous-open-paren) -(define-key evil-motion-state-map "])" 'evil-next-close-paren) -(define-key evil-motion-state-map "[{" 'evil-previous-open-brace) -(define-key evil-motion-state-map "]}" 'evil-next-close-brace) -(define-key evil-motion-state-map "]'" 'evil-next-mark-line) -(define-key evil-motion-state-map "]`" 'evil-next-mark) -(define-key evil-motion-state-map "['" 'evil-previous-mark-line) -(define-key evil-motion-state-map "[`" 'evil-previous-mark) -(define-key evil-motion-state-map "]s" 'evil-next-flyspell-error) -(define-key evil-motion-state-map "[s" 'evil-prev-flyspell-error) -(define-key evil-motion-state-map "*" 'evil-search-word-forward) -(define-key evil-motion-state-map "g*" 'evil-search-unbounded-word-forward) -(define-key evil-motion-state-map "," 'evil-repeat-find-char-reverse) -(define-key evil-motion-state-map "/" 'evil-search-forward) -(define-key evil-motion-state-map ";" 'evil-repeat-find-char) -(define-key evil-motion-state-map "?" 'evil-search-backward) -(define-key evil-motion-state-map "|" 'evil-goto-column) -(define-key evil-motion-state-map "^" 'evil-first-non-blank) -(define-key evil-motion-state-map "+" 'evil-next-line-first-non-blank) -(define-key evil-motion-state-map "_" 'evil-next-line-1-first-non-blank) -(define-key evil-motion-state-map "-" 'evil-previous-line-first-non-blank) -(define-key evil-motion-state-map "\C-w" 'evil-window-map) -(define-key evil-motion-state-map (kbd "C-6") 'evil-switch-to-windows-last-buffer) -(define-key evil-motion-state-map "\C-]" 'evil-jump-to-tag) -(define-key evil-motion-state-map (kbd "C-b") 'evil-scroll-page-up) -(define-key evil-motion-state-map (kbd "C-e") 'evil-scroll-line-down) -(define-key evil-motion-state-map (kbd "C-f") 'evil-scroll-page-down) -(define-key evil-motion-state-map (kbd "C-o") 'evil-jump-backward) -(define-key evil-motion-state-map (kbd "C-y") 'evil-scroll-line-up) -(define-key evil-motion-state-map (kbd "RET") 'evil-ret) -(define-key evil-motion-state-map "\\" 'evil-execute-in-emacs-state) -(define-key evil-motion-state-map "z^" 'evil-scroll-top-line-to-bottom) -(define-key evil-motion-state-map "z+" 'evil-scroll-bottom-line-to-top) -(define-key evil-motion-state-map "zt" 'evil-scroll-line-to-top) -;; TODO: z RET has an advanced form taking an count before the RET -;; but this requires again a special state with a single command -;; bound to RET -(define-key evil-motion-state-map (vconcat "z" [return]) 'evil-scroll-line-to-top-first-non-blank) -(define-key evil-motion-state-map (kbd "z RET") 'evil-scroll-line-to-top-first-non-blank) -(define-key evil-motion-state-map "zz" 'evil-scroll-line-to-center) -(define-key evil-motion-state-map "z." 'evil-scroll-line-to-center-first-non-blank) -(define-key evil-motion-state-map "zb" 'evil-scroll-line-to-bottom) -(define-key evil-motion-state-map "z-" 'evil-scroll-line-to-bottom-first-non-blank) -(define-key evil-motion-state-map "v" 'evil-visual-char) -(define-key evil-motion-state-map "V" 'evil-visual-line) -(define-key evil-motion-state-map "\C-v" 'evil-visual-block) -(define-key evil-motion-state-map "gv" 'evil-visual-restore) -(define-key evil-motion-state-map (kbd "C-^") 'evil-buffer) -(define-key evil-motion-state-map [left] 'evil-backward-char) -(define-key evil-motion-state-map [right] 'evil-forward-char) -(define-key evil-motion-state-map [up] 'evil-previous-line) -(define-key evil-motion-state-map [down] 'evil-next-line) -(define-key evil-motion-state-map "zl" 'evil-scroll-column-right) -(define-key evil-motion-state-map [?z right] 'evil-scroll-column-right) -(define-key evil-motion-state-map "zh" 'evil-scroll-column-left) -(define-key evil-motion-state-map [?z left] 'evil-scroll-column-left) -(define-key evil-motion-state-map "ze" 'evil-scroll-end-column) -(define-key evil-motion-state-map "zs" 'evil-scroll-start-column) -(define-key evil-motion-state-map "zH" 'evil-scroll-left) -(define-key evil-motion-state-map [?z S-left] 'evil-scroll-left) -(define-key evil-motion-state-map "zL" 'evil-scroll-right) -(define-key evil-motion-state-map [?z S-right] 'evil-scroll-right) -(define-key evil-motion-state-map - (read-kbd-macro evil-toggle-key) 'evil-emacs-state) - -;; text objects -(define-key evil-outer-text-objects-map "w" 'evil-a-word) -(define-key evil-outer-text-objects-map "W" 'evil-a-WORD) -(define-key evil-outer-text-objects-map "s" 'evil-a-sentence) -(define-key evil-outer-text-objects-map "p" 'evil-a-paragraph) -(define-key evil-outer-text-objects-map "b" 'evil-a-paren) -(define-key evil-outer-text-objects-map "(" 'evil-a-paren) -(define-key evil-outer-text-objects-map ")" 'evil-a-paren) -(define-key evil-outer-text-objects-map "[" 'evil-a-bracket) -(define-key evil-outer-text-objects-map "]" 'evil-a-bracket) -(define-key evil-outer-text-objects-map "B" 'evil-a-curly) -(define-key evil-outer-text-objects-map "{" 'evil-a-curly) -(define-key evil-outer-text-objects-map "}" 'evil-a-curly) -(define-key evil-outer-text-objects-map "<" 'evil-an-angle) -(define-key evil-outer-text-objects-map ">" 'evil-an-angle) -(define-key evil-outer-text-objects-map "'" 'evil-a-single-quote) -(define-key evil-outer-text-objects-map "\"" 'evil-a-double-quote) -(define-key evil-outer-text-objects-map "`" 'evil-a-back-quote) -(define-key evil-outer-text-objects-map "t" 'evil-a-tag) -(define-key evil-outer-text-objects-map "o" 'evil-a-symbol) -(define-key evil-inner-text-objects-map "w" 'evil-inner-word) -(define-key evil-inner-text-objects-map "W" 'evil-inner-WORD) -(define-key evil-inner-text-objects-map "s" 'evil-inner-sentence) -(define-key evil-inner-text-objects-map "p" 'evil-inner-paragraph) -(define-key evil-inner-text-objects-map "b" 'evil-inner-paren) -(define-key evil-inner-text-objects-map "(" 'evil-inner-paren) -(define-key evil-inner-text-objects-map ")" 'evil-inner-paren) -(define-key evil-inner-text-objects-map "[" 'evil-inner-bracket) -(define-key evil-inner-text-objects-map "]" 'evil-inner-bracket) -(define-key evil-inner-text-objects-map "B" 'evil-inner-curly) -(define-key evil-inner-text-objects-map "{" 'evil-inner-curly) -(define-key evil-inner-text-objects-map "}" 'evil-inner-curly) -(define-key evil-inner-text-objects-map "<" 'evil-inner-angle) -(define-key evil-inner-text-objects-map ">" 'evil-inner-angle) -(define-key evil-inner-text-objects-map "'" 'evil-inner-single-quote) -(define-key evil-inner-text-objects-map "\"" 'evil-inner-double-quote) -(define-key evil-inner-text-objects-map "`" 'evil-inner-back-quote) -(define-key evil-inner-text-objects-map "t" 'evil-inner-tag) -(define-key evil-inner-text-objects-map "o" 'evil-inner-symbol) -(define-key evil-motion-state-map "gn" 'evil-next-match) -(define-key evil-motion-state-map "gN" 'evil-previous-match) - -(when evil-want-C-i-jump - (define-key evil-motion-state-map (kbd "C-i") 'evil-jump-forward)) - -(when evil-want-C-u-scroll - (define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up)) - -(when evil-want-C-d-scroll - (define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down)) - -(when evil-want-C-g-bindings - (define-key evil-motion-state-map "g\C-g" 'count-words)) - -;;; Visual state - -(define-key evil-visual-state-map "A" 'evil-append) -(define-key evil-visual-state-map "I" 'evil-insert) -(define-key evil-visual-state-map "o" 'exchange-point-and-mark) -(define-key evil-visual-state-map "O" 'evil-visual-exchange-corners) -(define-key evil-visual-state-map "R" 'evil-change-whole-line) -(define-key evil-visual-state-map "u" 'evil-downcase) -(define-key evil-visual-state-map "U" 'evil-upcase) -(define-key evil-visual-state-map "X" 'evil-delete-line) -(define-key evil-visual-state-map "a" evil-outer-text-objects-map) -(define-key evil-visual-state-map "i" evil-inner-text-objects-map) -(define-key evil-visual-state-map (kbd "<insert>") 'undefined) -(define-key evil-visual-state-map (kbd "<insertchar>") 'undefined) -(define-key evil-visual-state-map [remap evil-repeat] 'undefined) -(define-key evil-visual-state-map [escape] 'evil-exit-visual-state) -(define-key evil-visual-state-map "gf" 'evil-find-file-at-point-visual) - -;;; Operator-Pending state - -(define-key evil-operator-state-map "a" evil-outer-text-objects-map) -(define-key evil-operator-state-map "i" evil-inner-text-objects-map) -;; (define-key evil-operator-state-map [escape] 'keyboard-quit) - -;;; Insert state - -(defvar evil-insert-state-bindings - `(([insert] . evil-enter-replace-state) - ("\C-q" . evil-quoted-insert) - ("\C-v" . evil-quoted-insert) - ("\C-k" . evil-insert-digraph) - ("\C-o" . evil-execute-in-normal-state) - ("\C-r" . evil-paste-from-register) - ("\C-y" . evil-copy-from-above) - ("\C-e" . evil-copy-from-below) - ("\C-n" . evil-complete-next) ;; Completion commands - ("\C-p" . evil-complete-previous) ;; don't yet behave correctly - ("\C-x\C-n" . evil-complete-next-line) ;; in replace state - ("\C-x\C-p" . evil-complete-previous-line) ;; TODO - fix this - ("\C-t" . evil-shift-right-line) - ("\C-d" . evil-shift-left-line) - ("\C-a" . evil-paste-last-insertion) - ("\C-@" . evil-paste-last-insertion-and-stop-insert) - ([remap delete-backward-char] . evil-delete-backward-char-and-join) - ([S-left] . evil-backward-word-begin) - ([S-right] . evil-forward-word-begin) - ,(if evil-want-C-w-delete - '("\C-w" . evil-delete-backward-word) - '("\C-w" . evil-window-map)) - ,@(when evil-want-C-u-delete - '(("\C-u" . evil-delete-back-to-indentation))) - ,@(when evil-want-C-h-delete - '(("\C-h" . evil-delete-backward-char-and-join))) - ([mouse-2] . mouse-yank-primary)) - "Evil's bindings for insert & replace states. -Used in `evil-insert-state-map' and `evil-replace-state-map', -excluding <delete>, <escape>, and `evil-toggle-key'.") - -(defun evil-update-insert-state-bindings (&optional _option-name remove force) - "Update bindings in `evil-insert-state-map'. -If no arguments are given add the bindings specified in -`evil-insert-state-bindings'. If REMOVE is non nil, remove only -these bindings. Unless FORCE is non nil, this will not -overwriting existing bindings, which means bindings will not be -added if one already exists for a key and only default bindings -are removed. - -Note that <delete>, <escape> and `evil-toggle-key' are not -included in `evil-insert-state-bindings' by default." - (interactive) - (dolist (binding evil-insert-state-bindings) - (cond - ((and remove - (or force - ;; Only remove if the default binding has not changed - (eq (evil-lookup-key evil-insert-state-map (car binding)) - (cdr binding)))) - (define-key evil-insert-state-map (car binding) nil)) - ((and (null remove) - (or force - ;; Check to see that nothing is bound here before adding - (not (evil-lookup-key evil-insert-state-map (car binding))))) - (define-key evil-insert-state-map (car binding) (cdr binding)))))) - -(define-key evil-insert-state-map [delete] 'delete-char) -(define-key evil-insert-state-map [escape] 'evil-normal-state) -(define-key evil-insert-state-map - (read-kbd-macro evil-toggle-key) 'evil-emacs-state) - -;;; Replace state - -(dolist (binding evil-insert-state-bindings) - (define-key evil-replace-state-map (car binding) (cdr binding))) -(define-key evil-replace-state-map (kbd "DEL") 'evil-replace-backspace) -(when evil-want-C-h-delete - (define-key evil-replace-state-map "\C-h" 'evil-replace-backspace)) -(define-key evil-replace-state-map [escape] 'evil-normal-state) -(define-key evil-replace-state-map [insert] 'evil-append) - -;;; Emacs state - -(define-key evil-emacs-state-map - (read-kbd-macro evil-toggle-key) 'evil-exit-emacs-state) - -(when evil-want-C-w-in-emacs-state - (define-key evil-emacs-state-map "\C-w" 'evil-window-map)) - -;;; Mouse -(define-key evil-motion-state-map [down-mouse-1] 'evil-mouse-drag-region) -(define-key evil-visual-state-map [mouse-2] 'evil-exit-visual-and-repeat) -(define-key evil-normal-state-map [mouse-2] 'mouse-yank-primary) - -;; Ex -(define-key evil-motion-state-map ":" 'evil-ex) -(define-key evil-motion-state-map "!" 'evil-shell-command) - -(evil-ex-define-cmd "e[dit]" 'evil-edit) -(evil-ex-define-cmd "vie[w]" 'evil-view) -(evil-ex-define-cmd "w[rite]" 'evil-write) -(evil-ex-define-cmd "up[date]" 'evil-update) -(evil-ex-define-cmd "wa[ll]" 'evil-write-all) -(evil-ex-define-cmd "sav[eas]" 'evil-save) -(evil-ex-define-cmd "r[ead]" 'evil-read) -(evil-ex-define-cmd "b[uffer]" 'evil-buffer) -(evil-ex-define-cmd "bad[d]" 'evil-buffer-add) -(evil-ex-define-cmd "bn[ext]" 'evil-next-buffer) -(evil-ex-define-cmd "bp[revious]" 'evil-prev-buffer) -(evil-ex-define-cmd "bN[ext]" "bprevious") -(evil-ex-define-cmd "sb[uffer]" 'evil-split-buffer) -(evil-ex-define-cmd "sbn[ext]" 'evil-split-next-buffer) -(evil-ex-define-cmd "sbp[revious]" 'evil-split-prev-buffer) -(evil-ex-define-cmd "sbN[ext]" "sbprevious") -(evil-ex-define-cmd "buffers" 'buffer-menu) -(evil-ex-define-cmd "files" 'evil-show-files) -(evil-ex-define-cmd "ls" "buffers") - -(evil-ex-define-cmd "c[hange]" 'evil-change) -(evil-ex-define-cmd "co[py]" 'evil-copy) -(evil-ex-define-cmd "t" "copy") -(evil-ex-define-cmd "m[ove]" 'evil-move) -(evil-ex-define-cmd "d[elete]" 'evil-ex-delete) -(evil-ex-define-cmd "y[ank]" 'evil-ex-yank) -(evil-ex-define-cmd "pu[t]" 'evil-ex-put) -(evil-ex-define-cmd "go[to]" 'evil-goto-char) -(evil-ex-define-cmd "j[oin]" 'evil-ex-join) -(evil-ex-define-cmd "le[ft]" 'evil-align-left) -(evil-ex-define-cmd "ri[ght]" 'evil-align-right) -(evil-ex-define-cmd "ce[nter]" 'evil-align-center) -(evil-ex-define-cmd "sp[lit]" 'evil-window-split) -(evil-ex-define-cmd "sv[iew]" 'evil-window-split-view) -(evil-ex-define-cmd "vs[plit]" 'evil-window-vsplit) -(evil-ex-define-cmd "new" 'evil-window-new) -(evil-ex-define-cmd "ene[w]" 'evil-buffer-new) -(evil-ex-define-cmd "vne[w]" 'evil-window-vnew) -(evil-ex-define-cmd "clo[se]" 'evil-window-delete) -(evil-ex-define-cmd "on[ly]" 'delete-other-windows) -(evil-ex-define-cmd "q[uit]" 'evil-quit) -(evil-ex-define-cmd "wq" 'evil-save-and-close) -(evil-ex-define-cmd "quita[ll]" 'evil-quit-all) -(evil-ex-define-cmd "qa[ll]" "quitall") -(evil-ex-define-cmd "cq[uit]" 'evil-quit-all-with-error-code) -(evil-ex-define-cmd "wqa[ll]" 'evil-save-and-quit) -(evil-ex-define-cmd "xa[ll]" "wqall") -(evil-ex-define-cmd "x[it]" 'evil-save-modified-and-close) -(evil-ex-define-cmd "exi[t]" 'evil-save-modified-and-close) -(evil-ex-define-cmd "bd[elete]" 'evil-delete-buffer) -(evil-ex-define-cmd "bw[ipeout]" 'evil-delete-buffer) -(evil-ex-define-cmd "g[lobal]" 'evil-ex-global) -(evil-ex-define-cmd "v[global]" 'evil-ex-global-inverted) -(evil-ex-define-cmd "norm[al]" 'evil-ex-normal) -(evil-ex-define-cmd "s[ubstitute]" 'evil-ex-substitute) -(evil-ex-define-cmd "&" 'evil-ex-repeat-substitute) -(evil-ex-define-cmd "&&" 'evil-ex-repeat-substitute-with-flags) -(evil-ex-define-cmd "~" 'evil-ex-repeat-substitute-with-search) -(evil-ex-define-cmd "~&" 'evil-ex-repeat-substitute-with-search-and-flags) -(evil-ex-define-cmd "mat[ch]" 'evil-ex-match) -(evil-ex-define-cmd "registers" 'evil-show-registers) -(evil-ex-define-cmd "di[splay]" "registers") -(evil-ex-define-cmd "ma[rk]" 'evil-set-col-0-mark) -(evil-ex-define-cmd "marks" 'evil-show-marks) -(evil-ex-define-cmd "delm[arks]" 'evil-delete-marks) -(evil-ex-define-cmd "ju[mps]" 'evil-show-jumps) -(evil-ex-define-cmd "noh[lsearch]" 'evil-ex-nohighlight) -(evil-ex-define-cmd "f[ile]" 'evil-show-file-info) -(evil-ex-define-cmd "<" 'evil-shift-left) -(evil-ex-define-cmd ">" 'evil-shift-right) -(evil-ex-define-cmd "=" 'evil-ex-line-number) -(evil-ex-define-cmd "!" 'evil-shell-command) -(evil-ex-define-cmd "@:" 'evil-ex-repeat) -(evil-ex-define-cmd "mak[e]" 'evil-make) -(evil-ex-define-cmd "cc" 'evil-goto-error) -(evil-ex-define-cmd "cfir[st]" 'first-error) -(evil-ex-define-cmd "cr[ewind]" 'first-error) -(evil-ex-define-cmd "cn[ext]" 'next-error) -(evil-ex-define-cmd "cp[revious]" 'previous-error) -(evil-ex-define-cmd "set-initial-state" 'evil-ex-set-initial-state) -(evil-ex-define-cmd "show-digraphs" 'evil-ex-show-digraphs) -(evil-ex-define-cmd "sor[t]" 'evil-ex-sort) -(evil-ex-define-cmd "res[ize]" 'evil-ex-resize) -(evil-ex-define-cmd "u[ndo]" 'evil-undo) -(evil-ex-define-cmd "red[o]" 'evil-redo) -(evil-ex-define-cmd "p[rint]" 'evil-ex-print) -(evil-ex-define-cmd "P[rint]" 'evil-ex-print) -(evil-ex-define-cmd "nu[mber]" 'evil-ex-numbered-print) -(evil-ex-define-cmd "#" 'evil-ex-numbered-print) -(evil-ex-define-cmd "z" 'evil-ex-z) -(evil-ex-define-cmd "ret[ab]" 'evil-retab) - -(when (featurep 'tab-bar) - (evil-ex-define-cmd "tabnew" 'tab-bar-new-tab) - (evil-ex-define-cmd "tabc[lose]" 'tab-bar-close-tab) - (evil-ex-define-cmd "tabo[nly]" 'tab-bar-close-other-tabs) - (evil-ex-define-cmd "tabn[ext]" 'evil-tab-next) - (evil-ex-define-cmd "tabp[revious]" 'tab-bar-switch-to-prev-tab)) - -;; Command-line editing -(define-key evil-command-line-map "\d" #'evil-ex-delete-backward-char) -(define-key evil-command-line-map "\t" #'completion-at-point) -(define-key evil-command-line-map [tab] #'completion-at-point) -(define-key evil-command-line-map "\C-a" #'completion-at-point) -(define-key evil-command-line-map "\C-b" #'move-beginning-of-line) -(define-key evil-command-line-map "\C-c" #'abort-recursive-edit) -(define-key evil-command-line-map "\C-d" #'completion-at-point) -(define-key evil-command-line-map "\C-f" 'evil-command-window) -(define-key evil-command-line-map "\C-g" #'abort-minibuffers) -(define-key evil-command-line-map "\C-k" 'evil-insert-digraph) -(define-key evil-command-line-map "\C-l" #'completion-at-point) -(define-key evil-command-line-map "\C-n" #'next-history-element) -(define-key evil-command-line-map "\C-p" #'previous-history-element) -(define-key evil-command-line-map "\C-r" 'evil-paste-from-register) -(define-key evil-command-line-map "\C-u" 'evil-delete-whole-line) -(define-key evil-command-line-map "\C-v" #'quoted-insert) -(when evil-want-C-w-delete - (define-key evil-command-line-map "\C-w" #'evil-delete-backward-word)) -(define-key evil-command-line-map [escape] #'abort-recursive-edit) -(define-key evil-command-line-map [S-left] #'backward-word) -(define-key evil-command-line-map [S-right] #'forward-word) -(define-key evil-command-line-map [up] #'previous-complete-history-element) -(define-key evil-command-line-map [down] #'next-complete-history-element) -(define-key evil-command-line-map [prior] #'previous-history-element) -(define-key evil-command-line-map [next] #'next-history-element) -(define-key evil-command-line-map [return] #'exit-minibuffer) -(define-key evil-command-line-map (kbd "RET") #'exit-minibuffer) - -;; search command line -(set-keymap-parent evil-ex-search-keymap evil-command-line-map) -(unless evil-want-C-w-delete - (define-key evil-ex-search-keymap "\C-w" 'evil-search-yank-word)) - -;; Ex command line -(set-keymap-parent evil-ex-completion-map evil-command-line-map) - -;; eval prompt (the `=' register) -(define-key evil-eval-map "\C-b" 'move-beginning-of-line) -(define-key evil-eval-map "\C-c" 'abort-recursive-edit) -(define-key evil-eval-map "\C-g" 'abort-recursive-edit) -(define-key evil-eval-map "\C-k" 'evil-insert-digraph) -(define-key evil-eval-map "\C-p" #'previous-complete-history-element) -(define-key evil-eval-map "\C-r" 'evil-paste-from-register) -(define-key evil-eval-map "\C-n" #'next-complete-history-element) -(define-key evil-eval-map "\C-u" 'evil-delete-whole-line) -(define-key evil-eval-map "\C-v" #'quoted-insert) -(define-key evil-eval-map "\C-w" 'evil-delete-backward-word) -(define-key evil-eval-map [escape] 'abort-recursive-edit) -(define-key evil-eval-map [S-left] 'backward-word) -(define-key evil-eval-map [S-right] 'forward-word) -(define-key evil-eval-map [up] 'previous-complete-history-element) -(define-key evil-eval-map [down] 'next-complete-history-element) -(define-key evil-eval-map [prior] 'previous-history-element) -(define-key evil-eval-map [next] 'next-history-element) -(define-key evil-eval-map [return] 'exit-minibuffer) -(define-key evil-eval-map (kbd "RET") 'exit-minibuffer) - -;; evil-read-key -(define-key evil-read-key-map (kbd "ESC") #'keyboard-quit) -(define-key evil-read-key-map (kbd "C-]") #'keyboard-quit) -(define-key evil-read-key-map (kbd "C-g") #'keyboard-quit) -(define-key evil-read-key-map (kbd "C-q") #'evil-read-quoted-char) -(define-key evil-read-key-map (kbd "C-v") #'evil-read-quoted-char) -(define-key evil-read-key-map (kbd "C-k") #'evil-read-digraph-char) -(define-key evil-read-key-map "\r" "\n") - -;; command line window -(evil-define-key* '(normal insert) evil-command-window-mode-map - (kbd "RET") 'evil-command-window-execute) - -(provide 'evil-maps) - -;;; evil-maps.el ends here diff --git a/.config/emacs/lisp/evil/evil-repeat.el b/.config/emacs/lisp/evil/evil-repeat.el deleted file mode 100644 index 75727ef..0000000 --- a/.config/emacs/lisp/evil/evil-repeat.el +++ /dev/null @@ -1,641 +0,0 @@ -;;; evil-repeat.el --- Repeat system -*- lexical-binding: t -*- - -;; Author: Frank Fischer <frank.fischer at mathematik.tu-chemnitz.de> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; A repeat begins when leaving Normal state; it ends when re-entering -;; Normal state. The diagram below shows possible routes between -;; Normal state (N), Insert state (I), Visual state (V), -;; Operator-Pending state (O) and Replace state (R). (Emacs state -;; is an exception: nothing is repeated in that state.) -;; ___ -;; / \ -;; | R | -;; \___/ -;; ^ | -;; | | -;; ___ |___V ___ -;; / \ <------- / \ -------> / \ -;; | V | | N | | O | -;; \___/ -------> \___/ <------- \___/ -;; | | ^ | -;; | | | | -;; | V___| | -;; | / \ | -;; +--------> | I | <--------+ -;; \___/ -;; -;; The recording of a repeat is started in one of two cases: Either a -;; command is about to be executed (in pre-command-hook) or normal -;; state is exited. The recording is stopped whenever a command has -;; been completed and evil is in normal state afterwards. Therefore, -;; a non-inserting command in normal-state is recorded as a single -;; repeat unit. In contrast, if the command leaves normal state and -;; starts insert-state, all commands that are executed until -;; insert-state is left and normal state is reactivated are recorded -;; together in one repeat unit. In other words, a repeat unit consists -;; of all commands that are executed starting and ending in normal -;; state. -;; -;; Not all commands are recorded. There are several commands that are -;; completely ignored and other commands that even abort the currently -;; active recording, e.g., commands that switch buffer. -;; -;; During recording the repeat information is appended to the variable -;; `evil-repeat-info', which is cleared when the recording -;; starts. This accumulated repeat information is put into the -;; `evil-repeat-ring' when the recording is finished. The dot command, -;; `\[evil-repeat]' (`evil-repeat') replays the most recent entry in -;; the ring, preceeding repeats can be replayed using -;; `\[evil-repeat-pop]' (`evil-repeat-pop'). -;; -;; Repeat information can be stored in almost arbitrary form. How the -;; repeat information for each single command is recorded is -;; determined by the :repeat property of the command. This property -;; has the following interpretation: -;; -;; t record commands by storing the key-sequence that invoked it -;; nil ignore this command completely -;; ignore synonym to nil -;; motion command is recorded by storing the key-sequence but only in -;; insert state, otherwise it is ignored. -;; abort stop recording of repeat information immediately -;; change record commands by storing buffer changes -;; SYMBOL if SYMBOL is contained as key in `evil-repeat-types' call -;; the corresponding (function-)value, otherwise call the -;; function associated with SYMBOL. In both cases the -;; function should take exactly one argument which is either -;; `pre', `pre-read-key-sequence' or `post' specifying on -;; whether the function is called before or after the -;; execution of the command. -;; -;; Therefore, using a certain SYMBOL one can write specific repeation -;; functions for each command. -;; -;; Each value of ring `evil-repeat-info', i.e., each single repeat -;; information must be one of the following two possibilities: -;; If element is a sequence, it is regarded as a key-sequence to -;; be repeated. Otherwise the element must be a list -;; (FUNCTION PARAMS ...) which will be called using -;; (apply FUNCTION PARAMS) whenever this repeat is being executed. -;; -;; A user supplied repeat function can use the functions -;; `evil-record-repeat' to append further repeat-information of the -;; form described above to `evil-repeat-info'. See the implementation -;; of `evil-repeat-keystrokes' and `evil-repeat-changes' for examples. -;; -;; The repeat information is executed with `evil-execute-repeat-info', -;; which passes key-sequence elements to `execute-kbd-macro' and -;; executes other elements as defined above. A special version is -;; `evil-execute-repeat-info-with-count'. This function works as -;; `evil-execute-repeat-info', but replaces the count of the first -;; command. This is done by parsing the key-sequence, ignoring all -;; calls to `digit-prefix-argument' and `negative-argument', and -;; prepending the count as a string to the vector of the remaining -;; key-sequence. - -;;; Code: - -(require 'evil-states) - -(defmacro evil-without-repeat (&rest body) - (declare (indent defun) - (debug t)) - `(let ((pre-command-hook (remq 'evil-repeat-pre-hook pre-command-hook)) - (post-command-hook (remq 'evil-repeat-post-hook post-command-hook))) - ,@body - (evil-repeat-abort))) - -(defsubst evil-repeat-recording-p () - "Return non-nil if a recording is in progress." - (eq evil-recording-repeat t)) - -(defun evil-repeat-start () - "Start recording a new repeat into `evil-repeat-info'." - (evil-repeat-reset t) - (evil-repeat-record-buffer) - (when (evil-visual-state-p) - (let* ((range (evil-visual-range)) - (beg (evil-range-beginning range)) - (end (max 1 (1- (evil-range-end range)))) - (nfwdlines (evil-count-lines beg end))) - (evil-repeat-record - (cond - ((eq evil-visual-selection 'char) - (list #'evil-repeat-visual-char - nfwdlines - (- end - (if (zerop nfwdlines) - beg - (save-excursion - (goto-char end) - (line-beginning-position)))))) - ((eq evil-visual-selection 'line) - (list #'evil-repeat-visual-line nfwdlines)) - ((eq evil-visual-selection 'block) - (list #'evil-repeat-visual-block - nfwdlines - (abs (- (evil-column beg) (evil-column end)))))))))) - -(defun evil-repeat-stop () - "Stop recording a repeat. -Update `evil-repeat-ring' with the accumulated changes -in `evil-repeat-info' and clear variables." - (unwind-protect - (when (evil-repeat-recording-p) - (setq evil-repeat-info (evil-normalize-repeat-info evil-repeat-info)) - (when (and evil-repeat-info evil-repeat-ring) - (ring-insert evil-repeat-ring evil-repeat-info))) - (evil-repeat-reset nil))) - -(defun evil-repeat-abort () - "Abort current repeation." - (evil-repeat-reset 'abort)) - -(defun evil-repeat-reset (flag) - "Clear all repeat recording variables. -Set `evil-recording-repeat' to FLAG." - (setq evil-recording-repeat flag - evil-repeat-info nil - evil-repeat-buffer nil)) - -(defsubst evil-repeat-record-position (&optional pos) - "Set `evil-repeat-pos' to POS or point." - (setq evil-repeat-pos (or pos (point)))) - -(defun evil-repeat-record-buffer () - "Set `evil-repeat-buffer' to the current buffer." - (unless (minibufferp) - (setq evil-repeat-buffer (current-buffer)))) - -(defmacro evil-save-repeat-info (&rest body) - "Execute BODY, protecting the values of repeat variables." - (declare (indent defun) - (debug t)) - `(let (evil-repeat-ring - evil-recording-repeat - evil-recording-current-command - evil-repeat-info - evil-repeat-changes - evil-repeat-pos - evil-repeat-keys - evil-repeat-buffer - this-command - last-command) - ,@body)) - -(defun evil-repeat-different-buffer-p (&optional strict) - "Whether the buffer has changed in a repeat. -If STRICT is non-nil, returns t if the previous buffer -is unknown; otherwise returns t only if the previous -buffer is known and different from the current buffer." - (and (or (buffer-live-p evil-repeat-buffer) strict) - (not (minibufferp)) - (not (eq (current-buffer) evil-repeat-buffer)))) - -(defvar evil-repeat-types - '((t . evil-repeat-keystrokes) - (change . evil-repeat-changes) - (motion . evil-repeat-motion) - (insert-at-point . evil-repeat-insert-at-point) - (ignore . nil)) - "Alist of defined repeat-types.") - -(defun evil--repeat-type (command) - "Return the :repeat property of COMMAND." - (when (functionp command) ; ignore keyboard macros - (let* ((type (evil-get-command-property command :repeat t)) - (repeat-type (assq type evil-repeat-types))) - (if repeat-type (cdr repeat-type) type)))) - -(defun evil-repeat-type (command &optional default) - "Return the :repeat property of COMMAND. -If COMMAND doesn't have this property, return DEFAULT." - (declare (obsolete evil--repeat-type "1.15.0")) - (when (functionp command) ; ignore keyboard macros - (let* ((type (evil-get-command-property command :repeat default)) - (repeat-type (assq type evil-repeat-types))) - (if repeat-type (cdr repeat-type) type)))) - -(defun evil-repeat-force-abort-p (repeat-type) - "Whether the current command should abort the recording of repeat information. -Return non-nil if so." - (or (evil-repeat-different-buffer-p) ; ... buffer changed - (eq repeat-type 'abort) ; ... explicitly forced - (eq evil-recording-repeat 'abort) ; ... already aborted - (evil-emacs-state-p) ; ... in Emacs state - (and (evil-mouse-events-p ; ... mouse events - (this-command-keys-vector)) - (null repeat-type)) - (minibufferp))) ; ... minibuffer activated - -(defun evil-repeat-record (info) - "Append INFO to `evil-repeat-info'." - (when (evil-repeat-recording-p) - (setq evil-repeat-info (nconc evil-repeat-info (list info))))) - -;; called from `pre-command-hook' -(defun evil-repeat-pre-hook () - "Prepare the current command for recording the repeation." - (when evil-local-mode - (let ((repeat-type (evil--repeat-type this-command))) - (cond - ;; abort the repeat - ((evil-repeat-force-abort-p repeat-type) - ;; We mark the current record as being aborted, because there - ;; may be further pre-hooks following before the post-hook is - ;; called. - (evil-repeat-abort)) - ;; ignore those commands completely - ((or (null repeat-type) - (evil-mouse-events-p (this-command-keys-vector)))) - ;; record command - (t - ;; In normal-state or visual state, each command is a single - ;; repeation, therefore start a new repeation. - (when (or (evil-normal-state-p) - (evil-visual-state-p)) - (evil-repeat-start)) - (setq evil-recording-current-command t) - (funcall repeat-type 'pre)))))) -(put 'evil-repeat-pre-hook 'permanent-local-hook t) - -;; called from `post-command-hook' -(defun evil-repeat-post-hook () - "Finish recording of repeat-information for the current-command." - (when (and evil-local-mode evil-recording-repeat) - (let ((repeat-type (evil--repeat-type this-command))) - (cond - ;; abort the repeat - ((evil-repeat-force-abort-p repeat-type) - ;; The command has been aborted but is complete, so just reset - ;; the recording state. - (evil-repeat-reset nil)) - ;; ignore if command should not be recorded or the current - ;; command is not being recorded - ((or (null repeat-type) - (not evil-recording-current-command))) - ;; record command - (t - (funcall repeat-type 'post) - ;; In normal state, the repeat sequence is complete, so record it. - (when (evil-normal-state-p) - (evil-repeat-stop))))) - ;; done with recording the current command - (setq evil-recording-current-command nil))) -(put 'evil-repeat-post-hook 'permanent-local-hook t) - -(defun evil-clear-command-keys () - "Clear `this-command-keys' and all information about the current command keys. -Calling this function prevents further recording of the keys that -invoked the current command" - (clear-this-command-keys t) - (setq evil-repeat-keys "")) - -(defun evil-this-command-keys (&optional post-cmd) - "Version of `this-command-keys' with finer control over prefix args." - (vconcat - (let ((arg (if post-cmd current-prefix-arg prefix-arg))) - (and (numberp arg) - ;; Only add prefix if no repeat info recorded yet - (null evil-repeat-info) - (number-to-string arg))) - (this-single-command-keys))) - -(defun evil-repeat-keystrokes (flag) - "Repeation recording function for commands that are repeated by keystrokes." - (cond - ((eq flag 'pre) - (when evil-this-register - (evil-repeat-record - `(set evil-this-register ,evil-this-register))) - (setq evil-repeat-keys (evil-this-command-keys))) - ((memq flag '(post pre-read-key-sequence)) - (evil-repeat-record (if (zerop (length (evil-this-command-keys t))) - evil-repeat-keys - (evil-this-command-keys t))) - ;; erase commands keys to prevent double recording - (evil-clear-command-keys)))) - -(defun evil-repeat-motion (flag) - "Repetition for motions. -Motions are recorded by keystroke but only in Insert state." - (when (memq evil-state '(insert replace)) - (evil-repeat-keystrokes flag))) - -(defun evil-repeat-changes (flag) - "Repeation recording function for commands that are repeated by buffer changes." - (cond - ((eq flag 'pre) - (add-hook 'after-change-functions #'evil-repeat-change-hook nil t) - (evil-repeat-start-record-changes)) - ((eq flag 'post) - (remove-hook 'after-change-functions #'evil-repeat-change-hook t) - (evil-repeat-finish-record-changes)))) - -;; called from the `after-change-functions' hook -(defun evil-repeat-change-hook (beg end length) - "Record change information for current command." - (let ((repeat-type (evil--repeat-type this-command))) - (when (and (evil-repeat-recording-p) - (eq repeat-type 'evil-repeat-changes) - (not (evil-emacs-state-p)) - (not (evil-repeat-different-buffer-p t)) - evil-state) - (unless (evil-repeat-recording-p) - (evil-repeat-start)) - (evil-repeat-record-change (- beg evil-repeat-pos) - (buffer-substring beg end) - length)))) -(put 'evil-repeat-change-hook 'permanent-local-hook t) - -(defun evil-repeat-record-change (relpos ins ndel) - "Record the current buffer changes during a repeat. -If CHANGE is specified, it is added to `evil-repeat-changes'." - (when (evil-repeat-recording-p) - (push (list relpos ins ndel) evil-repeat-changes))) - -(defun evil-repeat-start-record-changes () - "Start the recording of a new set of buffer changes." - (setq evil-repeat-changes nil) - (evil-repeat-record-position)) - -(defun evil-repeat-finish-record-changes () - "Finish the recording of buffer changes and record them as repeat." - (when (evil-repeat-recording-p) - (evil-repeat-record `(evil-execute-change - ,(nreverse evil-repeat-changes) - ,(- (point) evil-repeat-pos))) - (setq evil-repeat-changes nil))) - -(defun evil-repeat-insert-at-point (flag) - "Repeation recording function for commands that insert text in region. -For example `mouse-yank-primary'. This records text insertion when a command -inserts some text in a buffer between (point) and (mark)." - (cond - ((eq flag 'pre) - (add-hook 'after-change-functions #'evil-repeat-insert-at-point-hook nil t)) - ((eq flag 'post) - (remove-hook 'after-change-functions #'evil-repeat-insert-at-point-hook t)))) - -(defun evil-repeat-insert-at-point-hook (beg end _length) - (let ((repeat-type (evil--repeat-type this-command))) - (when (and (evil-repeat-recording-p) - (eq repeat-type 'evil-repeat-insert-at-point) - (not (evil-emacs-state-p)) - (not (evil-repeat-different-buffer-p t)) - evil-state) - (setq evil-repeat-pos beg) - (evil-repeat-record (list 'insert (buffer-substring beg end)))))) -(put 'evil-repeat-insert-at-point-hook 'permanent-local-hook t) - -(defun evil-normalize-repeat-info (repeat-info) - "Concatenate consecutive arrays in REPEAT-INFO. -Return a single array." - (let* ((result (cons nil nil)) - (result-last result) - cur cur-last) - (dolist (rep repeat-info) - (cond - ((null rep)) - ((arrayp rep) - (setq rep (listify-key-sequence rep)) - (cond - (cur - (setcdr cur-last (cons rep nil)) - (setq cur-last (cdr cur-last))) - (t (setq cur (cons rep nil) - cur-last cur)))) - (t - (when cur - (setcdr result-last (cons (apply #'vconcat cur) nil)) - (setq result-last (cdr result-last) - cur nil)) - (setcdr result-last (cons rep nil)) - (setq result-last (cdr result-last))))) - (when cur - (setcdr result-last (cons (apply #'vconcat cur) nil))) - (cdr result))) - -(defun evil-repeat-visual-char (nfwdlines nfwdchars) - "Restore a character visual selection. -If the selection is in a single line, the restored visual -selection covers the same number of characters. If the selection -covers several lines, the restored selection covers the same -number of lines and the same number of characters in the last -line as the original selection." - (evil-visual-char) - (when (> nfwdlines 0) - (forward-line nfwdlines)) - (forward-char nfwdchars)) - -(defun evil-repeat-visual-line (nfwdlines) - "Restore a character visual selection. -If the selection is in a single line, the restored visual -selection covers the same number of characters. If the selection -covers several lines, the restored selection covers the same -number of lines and the same number of characters in the last -line as the original selection." - (evil-visual-line) - (forward-line nfwdlines)) - -(defun evil-repeat-visual-block (nfwdlines nfwdchars) - "Restore a character visual selection. -If the selection is in a single line, the restored visual -selection covers the same number of characters. If the selection -covers several lines, the restored selection covers the same -number of lines and the same number of characters in the last -line as the original selection." - (evil-visual-block) - (let ((col (current-column))) - (forward-line nfwdlines) - (move-to-column (+ col nfwdchars) t))) - -(defun evil-execute-change (changes rel-point) - "Execute as list of changes. - -CHANGES is a list of triples (REL-BEG INSERT-TEXT NDEL). -REL-BEG is the relative position (to point) where the change -takes place. INSERT-TEXT is the text to be inserted at that -position and NDEL the number of characters to be deleted at that -position before insertion. - -REL-POINT is the relative position to point before the changed -where point should be placed after all changes." - (evil-save-repeat-info - (let ((point (point))) - (dolist (change changes) - (goto-char (+ point (nth 0 change))) - (delete-char (nth 2 change)) - (insert (nth 1 change))) - (goto-char (+ point rel-point))))) - -(defun evil-execute-repeat-info (repeat-info) - "Execute a repeat-information REPEAT-INFO." - (evil-save-repeat-info - (dolist (rep repeat-info) - (cond - ((or (arrayp rep) (stringp rep)) - (let ((input-method current-input-method) - (evil-input-method nil)) - (deactivate-input-method) - (unwind-protect - (execute-kbd-macro rep) - (activate-input-method input-method)))) - ((consp rep) - (when (and (= 3 (length rep)) - (eq (nth 0 rep) 'set) - (eq (nth 1 rep) 'evil-this-register) - (>= (nth 2 rep) ?0) - (< (nth 2 rep) ?9)) - (setcar (nthcdr 2 rep) (1+ (nth 2 rep)))) - (apply (car rep) (cdr rep))) - (t (error "Unexpected repeat-info: %S" rep)))))) - -;; TODO: currently we prepend the replacing count before the -;; key-sequence that calls the command. Can we use direct -;; modification of prefix-arg instead? Does it work in -;; conjunction with `execute-kbd-macro'? -(defun evil-execute-repeat-info-with-count (count repeat-info) - "Repeat the repeat-information REPEAT-INFO with the count of -the first command replaced by COUNT. The count is replaced if -and only if COUNT is non-nil." - (evil-save-repeat-info - (cond - ;; do nothing (zero repeating) - ((and count (zerop count))) - ;; replace count - (count - (let ((evil-repeat-count count) - done) - (while (and repeat-info - (arrayp (car repeat-info)) - (not done)) - (let* ((count-and-cmd (evil-extract-count (pop repeat-info)))) - (push (vconcat (number-to-string count) - (nth 2 count-and-cmd) - (nth 3 count-and-cmd)) - repeat-info) - (setq done t))) - (evil-execute-repeat-info repeat-info))) - ;; repeat with original count - (t (evil-execute-repeat-info repeat-info))))) - -;; Keep the compiler happy - this is a buffer local var -(defvar evil--execute-normal-return-state) - -(evil-define-command evil-repeat (count &optional save-point) - "Repeat the last editing command with count replaced by COUNT. -If SAVE-POINT is non-nil, do not move point." - :repeat ignore - :suppress-operator t - (interactive (list current-prefix-arg - (not evil-repeat-move-cursor))) - (cond - ((null evil-repeat-ring) - (error "Already executing repeat")) - (save-point - (save-excursion - (evil-repeat count))) - (t - (unwind-protect - (let ((evil-last-find-temp evil-last-find) - (confirm-kill-emacs t) - (kill-buffer-hook - (cons #'(lambda () - (user-error "Cannot delete buffer in repeat command")) - kill-buffer-hook)) - (undo-pointer buffer-undo-list)) - (evil-with-single-undo - (setq evil-last-repeat (list (point) count undo-pointer)) - (evil-execute-repeat-info-with-count - count (ring-ref evil-repeat-ring 0)) - (setq evil-last-find evil-last-find-temp))) - (if (eq 'evil-execute-in-normal-state last-command) - (evil-change-state evil--execute-normal-return-state) - (evil-normal-state)))))) - -;; TODO: the same issue concerning disabled undos as for `evil-paste-pop' -(evil-define-command evil-repeat-pop (count &optional save-point) - "Replace the just repeated command with a previously executed command. -Only allowed after `evil-repeat', `evil-repeat-pop' or -`evil-repeat-pop-next'. Uses the same repeat count that -was used for the first repeat. - -The COUNT argument inserts the COUNT-th previous kill. -If COUNT is negative, this is a more recent kill." - :repeat nil - :suppress-operator t - (interactive (list (prefix-numeric-value current-prefix-arg) - (not evil-repeat-move-cursor))) - (cond - ((not (and (eq last-command #'evil-repeat) - evil-last-repeat)) - (user-error "Previous command was not evil-repeat: %s" last-command)) - (save-point - (save-excursion - (evil-repeat-pop count))) - (t - (unless (eq buffer-undo-list (nth 2 evil-last-repeat)) - (evil-undo-pop)) - (goto-char (car evil-last-repeat)) - ;; rotate the repeat-ring - (while (> count 0) - (when evil-repeat-ring - (ring-insert-at-beginning evil-repeat-ring - (ring-remove evil-repeat-ring 0))) - (setq count (1- count))) - (while (< count 0) - (when evil-repeat-ring - (ring-insert evil-repeat-ring - (ring-remove evil-repeat-ring))) - (setq count (1+ count))) - (setq this-command #'evil-repeat) - (evil-repeat (cadr evil-last-repeat))))) - -(evil-define-command evil-repeat-pop-next (count &optional save-point) - "Same as `evil-repeat-pop', but with negative COUNT." - :repeat nil - :suppress-operator t - (interactive (list (prefix-numeric-value current-prefix-arg) - (not evil-repeat-move-cursor))) - (evil-repeat-pop (- count) save-point)) - -(defun evil--read-key-sequence-advice (&rest _) - "Record `this-command-keys' before it is overwritten." - (when (and (evil-repeat-recording-p) - evil-recording-current-command) - (let ((repeat-type (evil--repeat-type this-command))) - (when (functionp repeat-type) - (funcall repeat-type 'pre-read-key-sequence))))) - -(advice-add 'read-key-sequence :before #'evil--read-key-sequence-advice) -(advice-add 'read-key-sequence-vector :before #'evil--read-key-sequence-advice) - -(provide 'evil-repeat) - -;;; evil-repeat.el ends here diff --git a/.config/emacs/lisp/evil/evil-search.el b/.config/emacs/lisp/evil/evil-search.el deleted file mode 100644 index c882a8e..0000000 --- a/.config/emacs/lisp/evil/evil-search.el +++ /dev/null @@ -1,1249 +0,0 @@ -;;; evil-search.el --- Search and substitute -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(require 'evil-core) -(require 'evil-common) -(require 'evil-ex) - -(defun evil-select-search-module (option module) - "Change the search module according to MODULE. -If MODULE is `isearch', then Emacs' isearch module is used. -If MODULE is `evil-search', then Evil's own interactive -search module is used." - (let ((search-functions - '(forward - backward - word-forward - word-backward - unbounded-word-forward - unbounded-word-backward - next - previous))) - (dolist (fun search-functions) - (let ((isearch (intern (format "evil-search-%s" fun))) - (evil-search (intern (format "evil-ex-search-%s" fun)))) - (if (eq module 'isearch) - (substitute-key-definition - evil-search isearch evil-motion-state-map) - (substitute-key-definition - isearch evil-search evil-motion-state-map))))) - (set-default option module)) - -;; this customization is here because it requires -;; the knowledge of `evil-select-search-mode' -(defcustom evil-search-module 'isearch - "The search module to be used. May be either `isearch', for -Emacs' isearch module, or `evil-search', for Evil's own -interactive search module. N.b. changing this will not affect keybindings. -To swap out relevant keybindings, see `evil-select-search-module' function." - :type '(radio (const :tag "Emacs built-in isearch." :value isearch) - (const :tag "Evil interactive search." :value evil-search)) - :group 'evil - :set #'evil-select-search-module - :initialize #'evil-custom-initialize-pending-reset) - -(defun evil-push-search-history (string forward) - "Push STRING into the appropriate search history (determined by FORWARD)." - (let ((var (if forward - 'evil-search-forward-history - 'evil-search-backward-history))) - (unless (equal string (car (symbol-value var))) - (push string (symbol-value var))))) - -(defun evil-search-incrementally (forward regexp-p) - "Search incrementally for user-entered text." - (let ((evil-search-prompt (evil-search-prompt forward)) - (isearch-search-fun-function 'evil-isearch-function) - (point (point)) - search-nonincremental-instead) - (setq isearch-forward forward) - (evil-save-echo-area - (evil-without-input-method-hooks - ;; set the input method locally rather than globally to ensure that - ;; isearch clears the input method when it's finished - (setq current-input-method evil-input-method) - (if forward - (isearch-forward regexp-p) - (isearch-backward regexp-p)) - (evil-push-search-history isearch-string forward) - (setq current-input-method nil)) - (when (/= (point) point) - ;; position the point at beginning of the match only if the call to - ;; `isearch' has really moved the point. `isearch' doesn't move the - ;; point only if "C-g" is hit twice to exit the search, in which case we - ;; shouldn't move the point either. - (when (and forward isearch-other-end) - (goto-char isearch-other-end)) - (when (and (eq point (point)) - (not (string= isearch-string ""))) - (if forward - (isearch-repeat-forward) - (isearch-repeat-backward)) - (isearch-exit) - (when (and forward isearch-other-end) - (goto-char isearch-other-end))) - (evil-flash-search-pattern - (evil-search-message isearch-string forward)))))) - -(defun evil-flash-search-pattern (string &optional all) - "Flash last search matches for duration of `evil-flash-delay'. -If ALL is non-nil, flash all matches. STRING is a message -to display in the echo area." - (let ((lazy-highlight-initial-delay 0) - (isearch-search-fun-function 'evil-isearch-function) - (isearch-case-fold-search case-fold-search) - (disable #'(lambda (&optional _arg) (evil-flash-hook t)))) - (when evil-flash-timer - (cancel-timer evil-flash-timer)) - (unless (or (null string) - (string= string "")) - (evil-echo-area-save) - (evil-echo "%s" string) - (isearch-highlight (match-beginning 0) (match-end 0)) - (when all - (setq isearch-lazy-highlight-wrapped nil - isearch-lazy-highlight-start (point) - isearch-lazy-highlight-end (point)) - (isearch-lazy-highlight-new-loop) - (unless isearch-lazy-highlight-overlays - (isearch-lazy-highlight-update))) - (add-hook 'pre-command-hook #'evil-flash-hook nil t) - (add-hook 'evil-operator-state-exit-hook #'evil-flash-hook nil t) - (add-hook 'pre-command-hook #'evil-clean-isearch-overlays nil t) - (setq evil-flash-timer - (run-at-time evil-flash-delay nil disable))))) - -(defun evil-clean-isearch-overlays () - "Clean isearch overlays unless `this-command' is search." - (remove-hook 'pre-command-hook #'evil-clean-isearch-overlays t) - (unless (memq this-command - '(evil-search-backward - evil-search-forward - evil-search-next - evil-search-previous - evil-search-word-backward - evil-search-word-forward)) - (isearch-clean-overlays))) -(put 'evil-clean-isearch-overlays 'permanent-local-hook t) - -(defun evil-flash-hook (&optional force) - "Disable hightlighting if `this-command' is not search. -Disable anyway if FORCE is t." - (when (or force - ;; to avoid flicker, don't disable highlighting - ;; if the next command is also a search command - (not (memq this-command - '(evil-search-backward - evil-search-forward - evil-search-next - evil-search-previous - evil-search-word-backward - evil-search-word-forward)))) - (evil-echo-area-restore) - (isearch-dehighlight) - (setq isearch-lazy-highlight-last-string nil) - (lazy-highlight-cleanup t) - (when evil-flash-timer - (cancel-timer evil-flash-timer))) - (remove-hook 'pre-command-hook #'evil-flash-hook t) - (remove-hook 'evil-operator-state-exit-hook #'evil-flash-hook t)) -(put 'evil-flash-hook 'permanent-local-hook t) - -(defun evil-search-with-predicate (search-fun pred string bound noerror count) - "Execute a search with a predicate function. -SEARCH-FUN is a search function (e.g. `re-search-forward') and -PREDICATE is a two-argument function satisfying the interface of -`isearch-filter-predicate', or `nil'. STRING, BOUND, NOERROR and -COUNT are passed unchanged to SEARCH-FUN. The first match -satisfying the predicate (or `nil') is returned." - (catch 'done - (while t - (let ((result (funcall search-fun string bound noerror count))) - (cond - ((not result) (throw 'done nil)) - ((not pred) (throw 'done result)) - ((funcall pred (match-beginning 0) (match-end 0)) (throw 'done result))))))) - -(defun evil-search-function (&optional forward regexp-p wrap predicate) - "Return a search function. -If FORWARD is nil, search backward, otherwise forward. -If REGEXP-P is non-nil, the input is a regular expression. -If WRAP is non-nil, the search wraps around the top or bottom -of the buffer. -If PREDICATE is non-nil, it must be a function accepting two -arguments: the bounds of a match, returning non-nil if that match is -acceptable." - `(lambda (string &optional bound noerror count) - (let ((start (point)) - (search-fun ',(if regexp-p - (if forward - 're-search-forward - 're-search-backward) - (if forward - 'search-forward - 'search-backward))) - result) - (setq result (evil-search-with-predicate - search-fun ,predicate string - bound ,(if wrap t 'noerror) count)) - (when (and ,wrap (null result)) - (goto-char ,(if forward '(point-min) '(point-max))) - (unwind-protect - (setq result (evil-search-with-predicate - search-fun ,predicate string bound noerror count)) - (unless result - (goto-char start)))) - result))) - -(defun evil-isearch-function () - "Return a search function for use with isearch. -Based on `isearch-regexp' and `isearch-forward'." - (evil-search-function isearch-forward evil-regexp-search evil-search-wrap 'isearch-filter-predicate)) - -(defun evil-search (string forward &optional regexp-p start) - "Search for STRING and highlight matches. -If FORWARD is nil, search backward, otherwise forward. -If REGEXP-P is non-nil, STRING is taken to be a regular expression. -START is the position to search from; if unspecified, it is -one more than the current position." - (when (and (stringp string) - (not (string= string ""))) - (let* ((orig (point)) - (start (or start - (if forward - (min (point-max) (1+ orig)) - orig))) - (isearch-regexp regexp-p) - (isearch-forward forward) - (case-fold-search - (unless (and search-upper-case - (not (isearch-no-upper-case-p string nil))) - case-fold-search)) - (search-func (evil-search-function - forward regexp-p evil-search-wrap 'isearch-filter-predicate))) - ;; no text properties, thank you very much - (set-text-properties 0 (length string) nil string) - ;; position to search from - (goto-char start) - (setq isearch-string string) - (isearch-update-ring string regexp-p) - (condition-case nil - (funcall search-func string) - (search-failed - (goto-char orig) - (user-error "\"%s\": %s not found" - string (if regexp-p "pattern" "string")))) - ;; always position point at the beginning of the match - (goto-char (match-beginning 0)) - ;; determine message for echo area - (cond - ((and forward (< (point) start)) - (when evil-search-wrap-ring-bell (ding)) - (setq string "Search wrapped around BOTTOM of buffer")) - ((and (not forward) (> (point) start)) - (when evil-search-wrap-ring-bell (ding)) - (setq string "Search wrapped around TOP of buffer")) - (t - (setq string (evil-search-message string forward)))) - (evil-flash-search-pattern string t)))) - -(defun evil-search-word (forward unbounded symbol) - "Search for word near point. -If FORWARD is nil, search backward, otherwise forward. If SYMBOL -is non-nil then the functions searches for the symbol at point, -otherwise for the word at point." - (let ((string (car regexp-search-ring))) - (setq isearch-forward forward) - (cond - ((and (memq last-command - '(evil-search-word-forward - evil-search-word-backward)) - (stringp string) - (not (string= string ""))) - (evil-search string forward t)) - (t - (setq string (evil-find-thing forward (if symbol 'symbol 'evil-word))) - (cond - ((null string) - (user-error "No word under point")) - (unbounded - (setq string (regexp-quote string))) - (t - (setq string - (format (if symbol "\\_<%s\\_>" "\\<%s\\>") - (regexp-quote string))))) - (evil-push-search-history string forward) - (evil-search string forward t))))) - -(defun evil--find-thing (forward thing) - "Return a cons of THING near point as a string and its position. -THING should be a symbol understood by `thing-at-point', -e.g. `symbol' or `word'. If FORWARD is nil, search backward, -otherwise forward. Returns nil if nothing is found." - (let ((move (if forward #'forward-char #'backward-char)) - (end (if forward #'eobp #'bobp)) - string) - (save-excursion - (setq string (thing-at-point thing)) - ;; if there's nothing under point, go forwards - ;; (or backwards) to find it - (while (and (null string) (not (funcall end))) - (funcall move) - (setq string (thing-at-point thing))) - (when (stringp string) - (set-text-properties 0 (length string) nil string)) - (when (> (length string) 0) - (cons string (point)))))) - -(defun evil-find-thing (forward thing) - "Return a THING near point as a string. -THING should be a symbol understood by `thing-at-point', -e.g. `symbol' or `word'. If FORWARD is nil, search backward, -otherwise forward. Returns nil if nothing is found." - (car (evil--find-thing forward thing))) - -(defun evil-find-word (forward) - "Return word near point as a string. -If FORWARD is nil, search backward, otherwise forward. Returns -nil if nothing is found." - (evil-find-thing forward 'word)) - -(defun evil-find-symbol (forward) - "Return word near point as a string. -If FORWARD is nil, search backward, otherwise forward. Returns -nil if nothing is found." - (evil-find-thing forward 'symbol)) - -(defun evil-search-prompt (forward) - "Return the search prompt for the given direction." - (if forward "/" "?")) - -(defun evil-search-message (string forward) - "Prefix STRING with the search prompt." - (format "%s%s" (evil-search-prompt forward) string)) - -(advice-add 'isearch-message-prefix :around #'evil--use-search-prompt) -(defun evil--use-search-prompt (orig-fun &rest args) - "Use `evil-search-prompt'." - (or evil-search-prompt - (apply orig-fun args))) - -(advice-add 'isearch-delete-char :around #'evil--exit-search-when-empty) -(defun evil--exit-search-when-empty (orig-fun &rest args) - "Exit search if no search string." - (cond - ((and evil-search-prompt (string= isearch-string "")) - (let (search-nonincremental-instead) - (setq isearch-success nil) - (isearch-exit))) - (t (apply orig-fun args)))) - -(advice-add 'isearch-lazy-highlight-search :around #'evil--without-search-wrap) -(defun evil--without-search-wrap (orig-fun &rest args) - "Never wrap the search in this context." - (let (evil-search-wrap) - (apply orig-fun args))) - -;;; Ex search - -(defun evil-ex-regex-without-case (re) - "Return the regular expression without all occurrences of \\c and \\C." - (evil-transform-regexp re '((?c . "") (?C . "")))) - -(defun evil-ex-regex-case (re default-case) - "Return the case as implied by \\c or \\C in regular expression RE. -If \\c appears anywhere in the pattern, the pattern is case -insensitive. If \\C appears, the pattern is case sensitive. -Only the first occurrence of \\c or \\C is used, all others are -ignored. If neither \\c nor \\C appears in the pattern, the case -specified by DEFAULT-CASE is used. DEFAULT-CASE should be either -`sensitive', `insensitive' or `smart'. In the latter case, the pattern -will be case-sensitive if and only if it contains an upper-case -letter, otherwise it will be case-insensitive." - (cond - ((string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\\\\\([cC]\\)" re) - (if (eq (aref (match-string 1 re) 0) ?c) 'insensitive 'sensitive)) - ((eq default-case 'smart) - (if (isearch-no-upper-case-p re t) 'insensitive 'sensitive)) - (t default-case))) - -;; a pattern -(defun evil-ex-make-substitute-pattern (regexp flags) - "Create a PATTERN for substitution with FLAGS. -This function respects the values of `evil-ex-substitute-case' -and `evil-ex-substitute-global'." - (evil-ex-make-pattern - regexp - (cond ((memq ?i flags) 'insensitive) - ((memq ?I flags) 'sensitive) - ((not evil-ex-substitute-case) evil-ex-search-case) - (t evil-ex-substitute-case)) - (if (memq ?g flags) - (not evil-ex-substitute-global) - evil-ex-substitute-global))) - -(defun evil-ex-make-search-pattern (regexp) - "Create a PATTERN for search. -This function respects the values of `evil-ex-search-case'." - (evil-ex-make-pattern regexp evil-ex-search-case t)) - -(defun evil-ex-make-pattern (regexp case whole-line) - "Create a new search pattern. -REGEXP is the regular expression to be searched for. CASE should -be either `sensitive', `insensitive' for case-sensitive and -case-insensitive search respectively, or `smart'. In the latter case -the pattern is smart-case, i.e. it is automatically sensitive of the -pattern contains an upper case letter, otherwise it is insensitive. -The input REGEXP is considered a Vim-style regular expression if -`evil-ex-search-vim-style-regexp' is non-nil, in which case it is -transformed to an Emacs style regular expression (i.e. certain -backslash-codes are transformed. Otherwise REGEXP must be an Emacs -style regular expression and is not transformed." - (let ((re (evil-ex-regex-without-case regexp)) - (ignore-case (eq (evil-ex-regex-case regexp case) 'insensitive))) - ;; possibly transform regular expression from vim-style to - ;; Emacs-style. - (if (and evil-ex-search-vim-style-regexp - (not (or (string-prefix-p "\\_<" regexp) - (string-suffix-p "\\_>" regexp)))) - (setq re (evil-transform-vim-style-regexp re)) - ;; Even for Emacs regular expressions we translate certain - ;; whitespace sequences - (setq re (evil-transform-regexp re '((?t . "\t") - (?n . "\n") - (?r . "\r"))))) - (list re ignore-case whole-line))) - -(defun evil-ex-pattern-regex (pattern) - "Return the regular expression of a search PATTERN." - (nth 0 pattern)) - -(defun evil-ex-pattern-ignore-case (pattern) - "Return t if and only if PATTERN should ignore case." - (nth 1 pattern)) - -(defun evil-ex-pattern-whole-line (pattern) - "Return t if and only if PATTERN should match all occurences of a line. -Otherwise PATTERN matches only the first occurence." - (nth 2 pattern)) - -;;; Highlight - -(cl-defstruct (evil-ex-hl (:type vector) (:constructor nil) - (:copier nil) (:predicate nil)) - (name nil :read-only t) pattern - (face nil :read-only t) (window nil :read-only t) - (min nil :documentation "The minimal buffer position of the highlight.") - (max nil :documentation "The maximal buffer position of the highlight.") - (match-hook nil :read-only t) (update-hook nil :read-only t) - (overlays nil :documentation "The active overlays of the highlight.")) - -(cl-defun evil-ex-make-hl - (name &key (face 'evil-ex-lazy-highlight) (win (selected-window)) - min max match-hook update-hook) - "Create a new highlight object with name NAME and properties ARGS. -The following properties are supported: -:face The face to be used for the highlighting overlays. -:win The window in which the highlighting should be shown. - Note that the highlight will be visible in all windows showing - the corresponding buffer, but only the matches visible in the - specified window will actually be highlighted. If :win is nil, - the matches in all windows will be highlighted. -:min The minimal buffer position for highlighted matches. -:max The maximal buffer position for highlighted matches. -:match-hook A hook to be called once for each highlight. - The hook must take two arguments, the highlight and - the overlay for that highlight. -:update-hook A hook called once after updating the highlighting - with two arguments, the highlight and a message string - describing the current match status." - (unless (symbolp name) - (user-error "Expected symbol as name of highlight")) - (when (assq name evil-ex-active-highlights-alist) - (evil-ex-delete-hl name)) - (unless evil-ex-active-highlights-alist - (add-hook 'window-scroll-functions - #'evil-ex-hl-update-highlights-scroll nil t) - (add-hook 'window-size-change-functions - #'evil-ex-hl-update-highlights-resize nil)) - (push (cons name (vector name - nil - face - win - min max - match-hook update-hook - nil)) - evil-ex-active-highlights-alist)) - -(defun evil-ex-delete-hl (name) - "Remove the highlighting object with a certain NAME." - (let ((hl (cdr (assq name evil-ex-active-highlights-alist)))) - (when hl - (mapc #'delete-overlay (evil-ex-hl-overlays hl)) - (setq evil-ex-active-highlights-alist - (assq-delete-all name evil-ex-active-highlights-alist)) - (evil-ex-hl-update-highlights)) - (unless evil-ex-active-highlights-alist - (remove-hook 'window-scroll-functions - #'evil-ex-hl-update-highlights-scroll t) - (remove-hook 'window-size-change-functions - #'evil-ex-hl-update-highlights-resize)))) - -(defun evil-ex-hl-active-p (name) - "Whether the highlight with a certain NAME is active." - (and (assq name evil-ex-active-highlights-alist) t)) - -(defun evil-ex-hl-change (name pattern) - "Set the regular expression of highlight NAME to PATTERN." - (let ((hl (cdr (assq name evil-ex-active-highlights-alist)))) - (when hl - (setf (evil-ex-hl-pattern hl) pattern) - (evil-ex-hl-idle-update)))) - -(defun evil-ex-hl-set-region (name beg end &optional _type) - "Set minimal and maximal position of highlight NAME to BEG and END." - (let ((hl (cdr (assq name evil-ex-active-highlights-alist)))) - (when hl - (setf (evil-ex-hl-min hl) beg - (evil-ex-hl-max hl) end) - (evil-ex-hl-idle-update)))) - -(defun evil-ex-hl-get-max (name) - "Return the maximal position of the highlight with name NAME." - (let ((hl (cdr (assq name evil-ex-active-highlights-alist)))) - (and hl (evil-ex-hl-max hl)))) - -(defun evil-ex-hl-update-highlights () - "Update the overlays of all active highlights." - (dolist (hl (mapcar #'cdr evil-ex-active-highlights-alist)) - (let* ((old-ovs (evil-ex-hl-overlays hl)) - new-ovs - (pattern (evil-ex-hl-pattern hl)) - (case-fold-search (evil-ex-pattern-ignore-case pattern)) - (case-replace case-fold-search) - (face (evil-ex-hl-face hl)) - (match-hook (evil-ex-hl-match-hook hl)) - result) - (if pattern - ;; collect all visible ranges - (let (ranges sranges) - (dolist (win (if (eq evil-ex-interactive-search-highlight - 'all-windows) - (get-buffer-window-list (current-buffer) nil t) - (list (evil-ex-hl-window hl)))) - (when (window-live-p win) - (let ((beg (max (window-start win) - (or (evil-ex-hl-min hl) (point-min)))) - (end (min (window-end win) - (or (evil-ex-hl-max hl) (point-max))))) - (when (< beg end) - (push (cons beg end) ranges))))) - (setq ranges (sort ranges #'car-less-than-car)) - (while ranges - (let ((r1 (pop ranges)) - (r2 (pop ranges))) - (cond - ;; last range - ((null r2) (push r1 sranges)) - ;; ranges overlap, union - ((>= (cdr r1) (car r2)) - (push (cons (car r1) - (max (cdr r1) (cdr r2))) - ranges)) - ;; ranges distinct - (t (push r1 sranges) - (push r2 ranges))))) - - ;; run through all ranges - (condition-case lossage - (save-match-data - (dolist (r sranges) - (let ((beg (car r)) - (end (cdr r))) - (save-excursion - (goto-char beg) - ;; set the overlays for the current highlight, - ;; reusing old overlays (if possible) - (while (and (not (eobp)) - (evil-ex-search-find-next-pattern pattern) - (<= (match-end 0) end) - (not (and (= (match-beginning 0) end) - (save-excursion - (goto-char (match-beginning 0)) - (bolp))))) - (let ((ov (or (pop old-ovs) (make-overlay 0 0)))) - (move-overlay ov (match-beginning 0) (match-end 0)) - (overlay-put ov 'face face) - (overlay-put ov 'evil-ex-hl (evil-ex-hl-name hl)) - (overlay-put ov 'priority 1000) - (push ov new-ovs) - (when match-hook (funcall match-hook hl ov))) - (cond - ((not (or (evil-ex-pattern-whole-line pattern) - (save-excursion - (goto-char (match-beginning 0)) - (search-forward "\n" (match-end 0) t)))) - (forward-line)) - ((= (match-beginning 0) (match-end 0)) - (forward-char)) - (t (goto-char (match-end 0)))))))) - (mapc #'delete-overlay old-ovs) - (setf (evil-ex-hl-overlays hl) new-ovs) - (if (or (null pattern) new-ovs) - (setq result t) - ;; Maybe the match could just not be found somewhere else? - (save-excursion - (goto-char (or (evil-ex-hl-min hl) (point-min))) - (if (and (evil-ex-search-find-next-pattern pattern) - (< (match-end 0) (or (evil-ex-hl-max hl) - (point-max)))) - (setq result (format "Match in line %d" - (line-number-at-pos - (match-beginning 0)))) - (setq result "No match"))))) - - (invalid-regexp (setq result (cadr lossage))) - (search-failed (setq result (nth 2 lossage))) - (error (setq result (format "%s" (cadr lossage)))))) - ;; no pattern, remove all highlights - (mapc #'delete-overlay old-ovs) - (setf (evil-ex-hl-overlays hl) new-ovs)) - (when (evil-ex-hl-update-hook hl) - (funcall (evil-ex-hl-update-hook hl) hl result))))) - -(defun evil-ex-search-find-next-pattern (pattern &optional direction) - "Look for the next occurrence of PATTERN in a certain DIRECTION. -Note that this function ignores the whole-line property of PATTERN." - (setq direction (or direction 'forward)) - (let ((case-fold-search (evil-ex-pattern-ignore-case pattern))) - (cond - ((eq direction 'forward) - (re-search-forward (evil-ex-pattern-regex pattern) nil t)) - ((eq direction 'backward) - (let* ((pnt (point)) - (ret (re-search-backward (evil-ex-pattern-regex pattern) nil t)) - (m (and ret (match-data)))) - (if ret - (forward-char) - (goto-char (point-min))) - (let ((fwdret - (re-search-forward (evil-ex-pattern-regex pattern) nil t))) - (cond - ((and fwdret (< (match-beginning 0) pnt)) - (setq ret fwdret) - (goto-char (match-beginning 0))) - (ret - (set-match-data m) - (goto-char (match-beginning 0))) - (t - (goto-char pnt) - ret))))) - (t (user-error "Unknown search direction `%s'" direction))))) - -(defun evil-ex-hl-idle-update () - "Trigger the timer to update the highlights in the current buffer." - (when (and evil-ex-interactive-search-highlight - evil-ex-active-highlights-alist) - (when evil-ex-hl-update-timer - (cancel-timer evil-ex-hl-update-timer)) - (setq evil-ex-hl-update-timer - (run-at-time evil-ex-hl-update-delay nil - #'evil-ex-hl-do-update-highlight - (current-buffer))))) - -(defun evil-ex-hl-do-update-highlight (&optional buffer) - "Timer function for updating the highlights." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (evil-ex-hl-update-highlights))) - (setq evil-ex-hl-update-timer nil)) - -(defun evil-ex-hl-update-highlights-scroll (win _beg) - "Update highlights after scrolling in some window." - (with-current-buffer (window-buffer win) - (evil-ex-hl-idle-update))) -(put 'evil-ex-hl-update-highlights-scroll 'permanent-local-hook t) - -(defun evil-ex-hl-update-highlights-resize (frame) - "Update highlights after resizing a window." - (let ((buffers (delete-dups (mapcar #'window-buffer (window-list frame))))) - (dolist (buf buffers) - (with-current-buffer buf - (evil-ex-hl-idle-update))))) -(put 'evil-ex-hl-update-highlights-resize 'permanent-local-hook t) - -;; interactive search -(defun evil-ex-search-activate-highlight (pattern) - "Activate highlighting of the search pattern set to PATTERN. -This function does nothing if `evil-ex-search-interactive' or -`evil-ex-search-highlight-all' is nil. " - (when (and evil-ex-search-interactive evil-ex-search-highlight-all) - (with-current-buffer (or evil-ex-original-buffer (current-buffer)) - (unless (evil-ex-hl-active-p 'evil-ex-search) - (evil-ex-make-hl 'evil-ex-search - :win (or (minibuffer-selected-window) (selected-window)))) - (when pattern - (evil-ex-hl-change 'evil-ex-search pattern))))) - -(defun evil-ex-search (&optional count) - "Search forward or backward COUNT times for the current Ex search pattern. -The search pattern is determined by `evil-ex-search-pattern', and the -direction by `evil-ex-search-direction'." - (setq evil-ex-search-start-point (point) - evil-ex-last-was-search t - count (or count 1)) - (let ((orig (point)) - wrapped) - (dotimes (_ (or count 1)) - (when (and (eq evil-ex-search-direction 'forward) (not (eobp))) - (forward-char) - ;; maybe skip end-of-line - (and (not evil-move-beyond-eol) (eolp) (not (eobp)) - (forward-char))) - (let ((res (evil-ex-find-next nil nil (not evil-search-wrap)))) - (cond - ((not res) - (goto-char orig) - (signal 'search-failed - (list (evil-ex-pattern-regex evil-ex-search-pattern)))) - ((eq res 'wrapped) (setq wrapped t))))) - (if wrapped - (let (message-log-max) - (when evil-search-wrap-ring-bell (ding)) - (message "Search wrapped"))) - (goto-char (match-beginning 0)) - (setq evil-ex-search-match-beg (match-beginning 0) - evil-ex-search-match-end (match-end 0)) - (evil-ex-search-goto-offset evil-ex-search-offset) - (evil-ex-search-activate-highlight evil-ex-search-pattern))) - -(defun evil-ex-find-next (&optional pattern direction nowrap) - "Search for the next occurrence of the PATTERN in DIRECTION. -PATTERN must be created using `evil-ex-make-pattern', DIRECTION is -either `forward' or `backward'. If NOWRAP is non-nil, the search does -not wrap at buffer boundaries. Furthermore this function only searches -invisible text if `search-invisible' is t. If PATTERN is not specified -the current global pattern `evil-ex-search-pattern' and if DIRECTION -is not specified the current global direction -`evil-ex-search-direction' is used. This function returns t if the -search was successful, nil if it was unsuccessful and `wrapped' if the -search was successful but wrapped around at buffer boundaries." - (setq pattern (or pattern evil-ex-search-pattern) - direction (or direction evil-ex-search-direction)) - (unless (and pattern (evil-ex-pattern-regex pattern)) - (signal 'search-failed (list "No search pattern"))) - (catch 'done - (let (wrapped) - (while t - (if (evil-ex-search-find-next-pattern pattern direction) - (when (or (eq search-invisible t) - (not (isearch-range-invisible - (match-beginning 0) (match-end 0)))) - ;; Successful search and not invisible - (throw 'done (if wrapped 'wrapped t))) - ;; Unsuccessful search - (if nowrap - (throw 'done nil) - (setq nowrap t - wrapped t) - (goto-char (if (eq direction 'forward) - (point-min) - (point-max))))))))) - -(defun evil-ex-search-update (pattern offset beg end) - "Update the highlighting for the search pattern. -PATTERN is the search pattern and OFFSET the associated offset. -BEG and END specify the current match." - (cond - ((and beg end) - ;; update overlay - (if evil-ex-search-overlay - (move-overlay evil-ex-search-overlay beg end) - (setq evil-ex-search-overlay (make-overlay beg end)) - (overlay-put evil-ex-search-overlay 'priority 1001) - (overlay-put evil-ex-search-overlay 'face 'evil-ex-search)) - ;; move point - (goto-char beg) - (evil-ex-search-goto-offset offset) - ;; update highlights - (when evil-ex-search-highlight-all - (evil-ex-hl-change 'evil-ex-search pattern))) - (t - ;; no match - (when evil-ex-search-overlay - ;; remove overlay - (delete-overlay evil-ex-search-overlay) - (setq evil-ex-search-overlay nil)) - ;; no highlights - (when evil-ex-search-highlight-all - (evil-ex-hl-change 'evil-ex-search nil)) - ;; and go to initial position - (goto-char evil-ex-search-start-point)))) - -(defvar evil--ex-search-update-timer nil - "Timer to coalesce `evil-ex-search-update-pattern' calls after pattern changes.") - -(defun evil-ex-search-after-change-function (_beg _end _old-len) - (when evil--ex-search-update-timer - (cancel-timer evil--ex-search-update-timer)) - (setq evil--ex-search-update-timer - (run-with-idle-timer 0 nil #'evil-ex-search-update-pattern))) - -(defun evil-ex-search-start-session () - "Initialize Ex for interactive search." - (add-hook 'pre-command-hook #'evil-ex-remove-default nil t) - (and evil-ex-search-interactive evil-ex-search-incremental - (add-hook 'after-change-functions - #'evil-ex-search-after-change-function nil t)) - (add-hook 'minibuffer-exit-hook #'evil-ex-search-stop-session nil t) - (add-hook 'mouse-leave-buffer-hook #'evil-ex-search-exit) - (evil-ex-search-activate-highlight nil)) - -(defvar evil-ex-search-yank-point nil) - -(defun evil-ex-search-stop-session () - "Stop interactive search." - (with-current-buffer evil-ex-original-buffer - ;; TODO: This is a bad fix to remove duplicates. The duplicates - ;; exist because `isearch-range-invisible' may add a single - ;; overlay multiple times if we are in an unlucky situation - ;; of overlapping overlays. This happens in our case because - ;; of the overlays that are used for (lazy) highlighting. - ;; Perhaps it would be better to disable those overlays - ;; temporarily before calling `isearch-range-invisible'. - (setq isearch-opened-overlays (delete-dups isearch-opened-overlays)) - (isearch-clean-overlays)) - (remove-hook 'mouse-leave-buffer-hook #'evil-ex-search-exit) - (when evil--ex-search-update-timer - (cancel-timer evil--ex-search-update-timer) - (setq evil--ex-search-update-timer nil)) - (when evil-ex-search-overlay - (delete-overlay evil-ex-search-overlay) - (setq evil-ex-search-overlay nil)) - (setq evil-ex-search-yank-point nil)) - -(defun evil-ex-split-search-pattern (pattern direction) - "Split PATTERN in regexp, offset and next-pattern parts. -Return a triplet (REGEXP OFFSET NEXT-SEARCH)." - (if (string-match - (if (eq direction 'forward) - "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(/\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$" - "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(\\?\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$") - pattern) - (list (substring pattern 0 (match-beginning 1)) - (match-string 2 pattern) - (match-string 3 pattern)) - (list pattern nil nil))) - -(defun evil-ex-search-full-pattern (string count direction) - "Search for a full search pattern STRING in DIRECTION. -This function splits STRING into \"pattern/offset/;next-pattern\" -parts and performs the search in DIRECTION which must be either -`forward' or `backward'. The first search is repeated COUNT times. If -the pattern part of STRING is empty, the last global pattern stored in -`evil-ex-search-pattern' is used instead if in addition the offset -part is nil (i.e. no pattern/offset separator), the last global offset -stored in `evil-ex-search-offset' is used as offset. The current match -data will correspond to the last successful match. This function -returns a triplet (RESULT PATTERN OFFSET) where RESULT is one of - - t the search was successful without wrapping - `wrap' the search was successful with wrapping - `empty-pattern' the last pattern was empty - nil the search was unsuccessful - -and PATTERN and OFFSET are the last pattern and offset this -function searched for. Note that this function does not handle -any error conditions." - (setq count (or count 1)) - (catch 'done - (while t - (let* ((res (evil-ex-split-search-pattern string direction)) - (pat (pop res)) - (offset (pop res)) - (next-pat (pop res)) - (orig-pat pat) - new-dir repeat-last wrapped) - (if (> (length pat) 0) - (setq pat (evil-ex-make-search-pattern pat)) - ;; use last pattern if no new pattern has been specified - (setq pat (or evil-ex-search-pattern - (throw 'done (list 'empty-pattern pat offset))) - offset (or offset evil-ex-search-offset))) - (while (> count 0) - (when (eq (or (evil-ex-find-next pat direction - (not evil-search-wrap)) - (throw 'done (list nil pat offset))) - 'wrapped) - (setq wrapped t)) - (setq count (1- count))) - (cond - ;; no next pattern, search complete - ((zerop (length next-pat)) - (evil-ex-search-goto-offset offset) - (throw 'done (list (if wrapped 'wrap t) pat offset))) - ;; single \"?\" or \"/\" means repeat last pattern and finish - ((= 1 (length next-pat)) - (evil-ex-search-goto-offset offset) - (setq new-dir (if (string= "/" next-pat) 'forward 'backward) - count (if (eq direction new-dir) 1 2) - string orig-pat - direction new-dir)) - ;; next non-empty pattern, next search iteration - (t (evil-ex-search-goto-offset offset) - (setq new-dir (if (= (aref next-pat 0) ?/) 'forward 'backward) - repeat-last (when (<= 2 (length next-pat)) - (member (substring next-pat 0 2) '("//" "??"))) - count (if (or (eq direction new-dir) (not repeat-last)) 1 2) - string (if repeat-last - (concat orig-pat (substring next-pat 1)) - (substring next-pat 1)) - direction new-dir))))))) - -(defun evil-ex-search-update-pattern () - "Update the current search pattern." - (let ((pattern-string (minibuffer-contents-no-properties)) - message) - (with-selected-window (minibuffer-selected-window) - (goto-char (1+ evil-ex-search-start-point)) - (condition-case err - (cl-destructuring-bind (success pattern offset) - (evil-ex-search-full-pattern pattern-string - (or evil-ex-search-count 1) - evil-ex-search-direction) - (cond - ((eq success 'wrap) - (evil-ex-search-update pattern offset - (match-beginning 0) (match-end 0)) - (setq message "Wrapped")) - ((eq success 'empty-pattern) - (evil-ex-search-update nil nil nil nil)) - (success - (evil-ex-search-update pattern offset - (match-beginning 0) (match-end 0))) - (t (evil-ex-search-update nil nil nil nil) - (setq message "Search failed")))) - (invalid-regexp - (evil-ex-search-update nil nil nil nil) - (setq message (cadr err))) - (error - (evil-ex-search-update nil nil nil nil) - (setq message (error-message-string err))))) - (when message (evil-ex-echo "%s" message)))) - -(defun evil-ex-search-exit () - "Exit interactive search, keeping lazy highlighting active." - (interactive) - (exit-minibuffer)) - -(defun evil-ex-search-abort () - "Abort interactive search, disabling lazy highlighting." - (interactive) - (evil-ex-delete-hl 'evil-ex-search) - (abort-recursive-edit)) - -(defun evil-ex-search-goto-offset (offset) - "Move point according to search OFFSET and set `evil-this-type' accordingly. -This function assumes that the current match data represents the -current search result." - (unless (zerop (length offset)) - (let ((beg (match-beginning 0)) - (end (match-end 0))) - (save-match-data - (unless (string-match - "^\\([esb]\\)?\\(\\([-+]\\)?\\([0-9]*\\)\\)$" - offset) - (user-error "Invalid search offset: %s" offset)) - (let ((count (if (= (match-beginning 4) (match-end 4)) - (cond - ((not (match-beginning 3)) 0) - ((= (aref offset (match-beginning 3)) ?+) +1) - (t -1)) - (string-to-number (match-string 2 offset))))) - (cond - ((not (match-beginning 1)) - (setq evil-this-type 'line) - (forward-line count)) - ((= (aref offset (match-beginning 1)) ?e) - (goto-char (+ end count -1)) - (setq evil-this-type 'inclusive)) - ((memq (aref offset (match-beginning 1)) '(?s ?b)) - (goto-char (+ beg count)) - (setq evil-this-type 'inclusive)))))))) - -(defun evil-ex-start-search (direction count) - "Start a new search in a certain DIRECTION." - (setq evil-ex-search-count count - evil-ex-search-direction direction - evil-ex-search-start-point (point) - evil-ex-last-was-search t) - ;; store buffer and window where the search started - (let* ((evil-ex-original-buffer (current-buffer)) - ;; read the search string - (minibuffer-local-map evil-ex-search-keymap) - (search-string - (condition-case err - (minibuffer-with-setup-hook #'evil-ex-search-start-session - (read-string - (if (eq evil-ex-search-direction 'forward) "/" "?") - (when evil-ex-search-history - (propertize (car evil-ex-search-history) 'face 'shadow)) - 'evil-ex-search-history)) - (quit - (evil-ex-delete-hl 'evil-ex-search) - (goto-char evil-ex-search-start-point) - (signal (car err) (cdr err)))))) - ;; pattern entered successful - (goto-char (if (eq evil-ex-search-direction 'forward) - (1+ evil-ex-search-start-point) - (1- evil-ex-search-start-point))) - (cl-destructuring-bind (success pattern offset) - (evil-ex-search-full-pattern search-string - evil-ex-search-count - evil-ex-search-direction) - (setq evil-ex-search-pattern pattern - evil-ex-search-offset offset) - (cond - ((memq success '(t wrap)) - (goto-char (match-beginning 0)) - (setq evil-ex-search-match-beg (match-beginning 0) - evil-ex-search-match-end (match-end 0)) - (evil-ex-search-goto-offset offset) - (evil-push-search-history search-string (eq direction 'forward)) - (if evil-ex-search-incremental - (unless evil-ex-search-persistent-highlight - (evil-ex-delete-hl 'evil-ex-search)) - (when evil-ex-search-highlight-all - (evil-ex-search-activate-highlight pattern)))) - (t - (goto-char evil-ex-search-start-point) - (evil-ex-delete-hl 'evil-ex-search) - (signal 'search-failed (list search-string))))))) - -(declare-function evil-ex-search-next "evil-commands") -(defun evil-ex-start-word-search (unbounded direction count &optional symbol) - "Search for the symbol under point. -The search matches the COUNT-th occurrence of the word. If the -UNBOUNDED argument is nil, the search matches only at symbol -boundaries, otherwise it matches anywhere. The DIRECTION -argument should be either `forward' or `backward', determining -the search direction. If SYMBOL is non-nil then the functions -searches for the symbol at point, otherwise for the word at -point." - (let* ((string (or (evil-find-thing (eq direction 'forward) - (if symbol 'symbol 'word)) - (user-error "No word under point"))) - (regex (if unbounded - (regexp-quote string) - (format (if symbol "\\_<%s\\_>" "\\<%s\\>") - (regexp-quote string))))) - (setq evil-ex-search-count count - evil-ex-search-direction direction - evil-ex-search-pattern - (let (evil-ex-search-vim-style-regexp) - (evil-ex-make-search-pattern regex)) - evil-ex-search-offset nil - evil-ex-last-was-search t) - ;; update search history unless this pattern equals the - ;; previous pattern - (unless (equal regex (car evil-ex-search-history)) - (push regex evil-ex-search-history)) - (evil-push-search-history regex (eq direction 'forward))) - (evil-ex-delete-hl 'evil-ex-search) - (evil-ex-search-next count)) - -;; substitute -(evil-ex-define-argument-type substitution - "A substitution pattern argument /pattern/replacement/flags. -This handler highlights the pattern of the current substitution." - :runner - (lambda (flag &optional arg) - (with-current-buffer evil-ex-original-buffer - (cond - ((eq flag 'start) - (evil-ex-make-hl - 'evil-ex-substitute - :face 'evil-ex-substitute-matches - :win (minibuffer-selected-window) - :update-hook #'evil-ex-pattern-update-ex-info - :match-hook (and evil-ex-substitute-interactive-replace - #'evil-ex-pattern-update-replacement)) - (setq flag 'update)) - ((eq flag 'stop) - (evil-ex-delete-hl 'evil-ex-substitute))) - - (when (and (eq flag 'update) - evil-ex-substitute-highlight-all - (> (length arg) 0)) - (condition-case err - (cl-destructuring-bind (pattern replacement _flags) - (evil-ex-get-substitute-info (or arg "") t) - (evil-ex-hl-change 'evil-ex-substitute pattern) - (setq evil-ex-substitute-current-replacement replacement) - (cl-destructuring-bind (beg end &rest) - (if evil-ex-range - (evil-expand-range evil-ex-range t) - (evil-range (line-beginning-position) (line-end-position) - 'line :expanded t)) - (evil-ex-hl-set-region 'evil-ex-substitute beg end))) - (end-of-file (evil-ex-echo "Incomplete replacement")) - (user-error (evil-ex-echo (error-message-string err)))))))) - -(defun evil-ex-pattern-update-ex-info (_hl result) - "Update the Ex info string." - (when (stringp result) - (evil-ex-echo "%s" result))) - -(defun evil-ex-pattern-update-replacement (_hl overlay) - "Update the replacement display." - (let ((repl (if evil-ex-substitute-current-replacement - (evil-match-substitute-replacement - evil-ex-substitute-current-replacement - (not case-replace)) - ""))) - (put-text-property 0 (length repl) - 'face 'evil-ex-substitute-replacement - repl) - (overlay-put overlay 'after-string repl))) - -(defun evil-ex-parse-global (string) - "Parse STRING as a global argument." - (let* ((pattern (nth 0 (evil-delimited-arguments string 2))) - (command (and pattern - (>= (- (length string) (length pattern)) 2) - (substring string (+ (length pattern) 2))))) - ;; use last pattern if none given - (when (zerop (length pattern)) - (setq pattern - (cond - ((and (eq evil-search-module 'evil-search) evil-ex-search-pattern) - (evil-ex-pattern-regex evil-ex-search-pattern)) - ((and (eq evil-search-module 'isearch) (not (zerop (length isearch-string)))) - isearch-string) - (t (user-error "No previous pattern"))))) - (list pattern command))) - -(defun evil-ex-get-substitute-info (string &optional implicit-r) - "Return the substitution info of :substitute argument STRING. -The result is a triplet \(PATTERN REPLACEMENT FLAGS). PATTERN is an -Ex-pattern (see `evil-ex-make-pattern') and REPLACEMENT is a compiled -replacement expression (see `evil-compile-replacement'). The -information returned is the actual substitution information w.r.t. to -special situations like empty patterns or repetition of previous -substitution commands. If IMPLICIT-R is non-nil, then the \"r\" flag -is assumed, i.e. in case of an empty pattern the last search pattern -is used. It is meant for :substitute commands with arguments." - (let (pattern replacement flags using-prev-pattern) - (cond - ((or (string= string "") (string-match-p "\\`[a-zA-Z]" string)) - ;; No pattern, since it starts with a letter which cannot be a - ;; separator: Repeat last substitute. - (setq replacement evil-ex-substitute-replacement) - ;; flags are everything that is not whitespace - (when (string-match "[^[:space:]]+" string) - (setq flags (match-string 0 string)))) - (t (let ((args (evil-delimited-arguments string 3))) - (setq pattern (pop args) - replacement (pop args) - flags (pop args)) - ;; if replacment equals "~" use previous replacement - (setq replacement (if (equal replacement "~") - evil-ex-substitute-replacement - (evil-compile-replacement replacement))) - ;; append implicit "r" flag if required - (when (and implicit-r (not (memq ?r (append flags nil)))) - (setq flags (concat flags "r")))))) - ;; if flags equals "&" add previous flags - (setq flags - (if (and (> (length flags) 0) (= (aref flags 0) ?&)) - (append (substring flags 1) evil-ex-substitute-flags) - (append flags nil))) - ;; if no pattern, use previous pattern, either search or - ;; substitute pattern depending on `evil-ex-last-was-search' and - ;; the r flag - (when (zerop (length pattern)) - (setq pattern - (if (eq evil-search-module 'evil-search) - (if (and evil-ex-last-was-search (memq ?r flags)) - (and evil-ex-search-pattern - (setq using-prev-pattern t) - (evil-ex-pattern-regex evil-ex-search-pattern)) - (and evil-ex-substitute-pattern - (setq using-prev-pattern t) - (evil-ex-pattern-regex evil-ex-substitute-pattern))) - (if (eq case-fold-search t) - isearch-string - (concat isearch-string "\\C"))) - flags (remq ?r flags))) - (when (and using-prev-pattern - (not (evil-ex-pattern-ignore-case evil-ex-search-pattern))) - (setq pattern (concat pattern "\\C"))) - ;; generate pattern - (when pattern - ;; Disable vim-style regexp conversion if using a previous pattern, because - ;; this conversion will already have been done before storing it - (let ((evil-ex-search-vim-style-regexp (and evil-ex-search-vim-style-regexp - (not using-prev-pattern)))) - (setq pattern (evil-ex-make-substitute-pattern pattern flags)))) - (list pattern replacement flags))) - -(defun evil-ex-nohighlight () - "Disable the active search highlightings." - (interactive) - (evil-ex-delete-hl 'evil-ex-substitute) - (evil-ex-delete-hl 'evil-ex-search)) - -(defun evil-search-yank-word () - "Pull next word from buffer into search string." - (interactive) - (let ((minibuf-content (minibuffer-contents-no-properties)) - (word "") start) - (with-current-buffer evil-ex-original-buffer - ;; Start to initial point if C-w have never been hit. - (unless evil-ex-search-yank-point - (if (string= "" minibuf-content) - (setq evil-ex-search-yank-point evil-ex-search-start-point) - (setq evil-ex-search-yank-point (point)))) - (save-excursion - (goto-char evil-ex-search-yank-point) - (setq start (point)) - (when (looking-at-p (regexp-quote minibuf-content)) - (forward-char (length minibuf-content)) - (setq start (point)) - (forward-word)) - (setq word (buffer-substring-no-properties start (point))))) - (and (eq evil-ex-search-case 'smart) - (let (case-fold-search) - (not (string-match-p "[A-Z]" minibuf-content))) - (setq word (downcase word))) - (insert word))) - -(provide 'evil-search) - -;;; evil-search.el ends here diff --git a/.config/emacs/lisp/evil/evil-states.el b/.config/emacs/lisp/evil/evil-states.el deleted file mode 100644 index 499154e..0000000 --- a/.config/emacs/lisp/evil/evil-states.el +++ /dev/null @@ -1,930 +0,0 @@ -;;; evil-states.el --- States -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(require 'evil-core) - -;;; Normal state - -(evil-define-state normal - "Normal state. -AKA \"Command\" state." - :tag " <N> " - :enable (motion) - (cond - ((evil-normal-state-p) - (overwrite-mode -1) - (add-hook 'post-command-hook #'evil-normal-post-command nil t)) - (t - (remove-hook 'post-command-hook #'evil-normal-post-command t)))) - -(defun evil-normal-post-command (&optional command) - "Reset command loop variables in Normal state. -Also prevent point from reaching the end of the line. -If the region is activated, enter Visual state." - (unless (null this-command) - (setq command (or command this-command)) - (when (evil-normal-state-p) - (setq evil-this-type nil - evil-this-operator nil - evil-this-motion nil - evil-this-motion-count nil - evil-inhibit-operator nil - evil-inhibit-operator-value nil) - (unless (memq command '(evil-use-register - digit-argument - negative-argument - universal-argument - universal-argument-minus - universal-argument-more - universal-argument-other-key)) - (setq evil-this-register nil)) - (evil-adjust-cursor)))) -(put 'evil-normal-post-command 'permanent-local-hook t) - -;;; Insert state - -(defun evil-maybe-remove-spaces (&optional do-remove) - "Remove space from newly opened empty line. -This function removes (indentation) spaces that have been -inserted by opening a new empty line. The behavior depends on the -variable `evil-maybe-remove-spaces'. If this variable is nil the -function does nothing. Otherwise the behavior depends on -DO-REMOVE. If DO-REMOVE is non-nil the spaces are -removed. Otherwise `evil-maybe-remove-spaces' is set to nil -unless the last command opened yet another new line. - -This function should be added as a post-command-hook to track -commands opening a new line." - (cond - ((not evil-maybe-remove-spaces) - (remove-hook 'post-command-hook #'evil-maybe-remove-spaces)) - (do-remove - (when (save-excursion - (beginning-of-line) - (looking-at "^\\s-*$")) - (delete-region (line-beginning-position) - (line-end-position))) - (setq evil-maybe-remove-spaces nil) - (remove-hook 'post-command-hook #'evil-maybe-remove-spaces)) - ((not (memq this-command - '(evil-open-above - evil-open-below - evil-append - evil-append-line - evil-change-whole-line - newline - newline-and-indent - indent-and-newline))) - (setq evil-maybe-remove-spaces nil) - (remove-hook 'post-command-hook #'evil-maybe-remove-spaces)))) - -(evil-define-state insert - "Insert state." - :tag " <I> " - :cursor (bar . 2) - :message "-- INSERT --" - :entry-hook (evil-start-track-last-insertion) - :exit-hook (evil-cleanup-insert-state evil-stop-track-last-insertion) - :input-method t - (cond - ((evil-insert-state-p) - (add-hook 'post-command-hook #'evil-maybe-remove-spaces) - (add-hook 'pre-command-hook #'evil-insert-repeat-hook) - (setq evil-maybe-remove-spaces t) - (unless (eq evil-want-fine-undo t) - (evil-start-undo-step))) - (t - (remove-hook 'post-command-hook #'evil-maybe-remove-spaces) - (remove-hook 'pre-command-hook #'evil-insert-repeat-hook) - (evil-maybe-remove-spaces t) - (setq evil-insert-repeat-info evil-repeat-info) - (evil-set-marker ?^ nil t) - (unless (eq evil-want-fine-undo t) - (evil-end-undo-step)) - (when (or (evil-normal-state-p evil-next-state) - (evil-motion-state-p evil-next-state)) - (evil-move-cursor-back - (and (eolp) (not evil-move-beyond-eol))))))) - -(defun evil-insert-repeat-hook () - "Record insertion keys in `evil-insert-repeat-info'." - (setq evil-insert-repeat-info (last evil-repeat-info)) - (remove-hook 'pre-command-hook #'evil-insert-repeat-hook)) -(put 'evil-insert-repeat-hook 'permanent-local-hook t) - -(eval-when-compile - ;; TODO remove this once support for emacs 26 is dropped - (unless (fboundp 'combine-change-calls) - (defmacro combine-change-calls (_beg _end &rest body) `(progn ,@body)))) -(declare-function evil-execute-repeat-info "evil-repeat") -(defun evil-cleanup-insert-state () - "Called when Insert or Replace state is about to be exited. -Handles the repeat-count of the insertion command." - (when evil-insert-count - (let (pre-command-hook post-command-hook) - (dotimes (_ (1- evil-insert-count)) - (when evil-insert-lines - (evil-insert-newline-below) - (when evil-auto-indent - (indent-according-to-mode))) - (evil-execute-repeat-info (cdr evil-insert-repeat-info))))) - (when evil-insert-vcount - (let ((buffer-invisibility-spec - (if (listp buffer-invisibility-spec) - ;; make all lines hidden by hideshow temporarily visible - (cl-remove-if (lambda (x) (eq (or (car-safe x) x) 'hs)) - buffer-invisibility-spec) - buffer-invisibility-spec))) - (cl-destructuring-bind (line col vcount) evil-insert-vcount - (save-excursion - (combine-change-calls ; For performance - (progn (goto-char (point-min)) - (line-beginning-position line)) - (line-end-position (+ line vcount -1)) - (let (pre-command-hook post-command-hook) ; For performance - (dotimes (v (1- vcount)) - (goto-char (point-min)) - (forward-line (+ line v)) - (when (or (not evil-insert-skip-empty-lines) - (not (integerp col)) - (save-excursion - (evil-move-end-of-line) - (>= (current-column) col))) - (if (integerp col) - (move-to-column col t) - (funcall col)) - (dotimes (_ (or evil-insert-count 1)) - (evil-execute-repeat-info (cdr evil-insert-repeat-info))))))))))) - (and evil-want-fine-undo (evil-end-undo-step))) - -;;; Visual state - -;; Visual selections are implemented in terms of types, and are -;; compatible with the Emacs region. This is achieved by "translating" -;; the region to the selected text right before a command is executed. -;; If the command is a motion, the translation is postponed until a -;; non-motion command is invoked (distinguished by the :keep-visual -;; command property). -;; -;; Visual state activates the region, enabling Transient Mark mode if -;; not already enabled. This is only temporay: if Transient Mark mode -;; was disabled before entering Visual state, it is disabled when -;; exiting Visual state. This allows Visual state to harness the -;; "transient" behavior of many commands without overriding the user's -;; preferences in other states. - -(defmacro evil-define-visual-selection (selection doc &rest body) - "Define a Visual selection SELECTION. -Creates a command evil-visual-SELECTION for enabling the selection. -DOC is the function's documentation string. The following keywords -may be specified in BODY: - -:message STRING Status message when enabling the selection. -:type TYPE Type to use (defaults to SELECTION). - -Following the keywords is optional code which is executed each time -the selection is enabled. - -\(fn SELECTION DOC [[KEY VAL]...] BODY...)" - (declare (indent defun) - (doc-string 2) - (debug (&define name stringp - [&rest keywordp sexp] - def-body))) - (let* ((name (intern (format "evil-visual-%s" selection))) - (message (intern (format "%s-message" name))) - (tagvar (intern (format "%s-tag" name))) - (type selection) - (tag " <V> ") - arg key string) - ;; collect keywords - (while (keywordp (car-safe body)) - (setq key (pop body) - arg (pop body)) - (cond - ((eq key :message) - (setq string arg)) - ((eq key :type) - (setq type arg)) - ((eq key :tag) - (setq tag arg)))) - ;; macro expansion - `(progn - (add-to-list 'evil-visual-alist (cons ',selection ',name)) - (defvar ,name ',type ,(format "*%s" doc)) - (defvar ,message ,string ,doc) - (defvar ,tagvar ,tag ,doc) - (evil-define-command ,name (&optional mark point type message) - ,@(when doc `(,doc)) - :keep-visual t - :repeat nil - (interactive - (list nil nil - (if (and (evil-visual-state-p) - (eq evil-visual-selection ',selection)) - 'exit ,name) t)) - (setq evil--region-from-mouse nil) - (if (eq type 'exit) - (evil-exit-visual-state) - (setq type (or type ,name) - evil-visual-selection ',selection) - (evil-visual-make-region mark point type message) - ,@body)) - ',selection))) - -(evil-define-visual-selection char - "Characterwise selection." - :type inclusive - :message "-- VISUAL --" - :tag " <V> ") - -(evil-define-visual-selection line - "Linewise selection." - :message "-- VISUAL LINE --" - :tag " <Vl> ") - -(evil-define-visual-selection screen-line - "Linewise selection in `visual-line-mode'." - :message "-- SCREEN LINE --" - :tag " <Vs> ") - -(evil-define-visual-selection block - "Blockwise selection." - :message "-- VISUAL BLOCK --" - :tag " <Vb> " - (evil-transient-mark -1) - ;; refresh the :corner property - (setq evil-visual-properties - (plist-put evil-visual-properties :corner - (evil-visual-block-corner)))) - -(evil-define-state visual - "Visual state." - :tag 'evil-visual-tag - :enable (motion normal) - :message 'evil-visual-message - (cond - ((evil-visual-state-p) - (evil-save-transient-mark-mode) - (setq select-active-regions nil) - (cond - ((region-active-p) - (if (< (evil-visual-direction) 0) - (evil-visual-select (region-beginning) (region-end) - evil-visual-char - (evil-visual-direction)) - (evil-visual-make-selection (mark t) (point) - evil-visual-char)) - (evil-visual-highlight)) - (t - (evil-visual-make-region (point) (point) evil-visual-char))) - (add-hook 'pre-command-hook #'evil-visual-pre-command nil t) - (add-hook 'post-command-hook #'evil-visual-post-command nil t) - (add-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook nil t)) - (t - ;; Postpone deactivation of region if next state is Insert. - ;; This gives certain insertion commands (auto-pairing characters, - ;; for example) an opportunity to access the region. - (if (and (eq evil-next-state 'insert) - (eq evil-visual-selection 'char)) - (add-hook 'evil-normal-state-entry-hook - #'evil-visual-deactivate-hook nil t) - (evil-visual-deactivate-hook)) - (setq evil-visual-region-expanded nil) - (remove-hook 'pre-command-hook #'evil-visual-pre-command t) - (remove-hook 'post-command-hook #'evil-visual-post-command t) - (remove-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook t) - (evil-visual-highlight -1)))) - -(defun evil-visual-pre-command (&optional command) - "Run before each COMMAND in Visual state. -Expand the region to the selection unless COMMAND is a motion." - (when (evil-visual-state-p) - (setq command (or command this-command)) - (if (and evil-transient-mouse-selection - evil--region-from-mouse - (not (rassq command evil-visual-alist))) - (progn (setq evil--region-from-mouse nil) - (evil-exit-visual-state)) - (when (and evil-transient-mouse-selection - evil--region-from-mouse - (rassq command evil-visual-alist)) - (setq evil-visual-selection nil ;; maintain visual state - evil--region-from-mouse nil)) - (when evil-visual-x-select-timer - (cancel-timer evil-visual-x-select-timer)) - (unless (evil-get-command-property command :keep-visual) - (evil-visual-update-x-selection) - (evil-visual-expand-region - ;; exclude final newline from linewise selection - ;; unless the command has real need of it - (and (eq (evil-visual-type) 'line) - (evil-get-command-property command :exclude-newline))))))) - -(put 'evil-visual-pre-command 'permanent-local-hook t) - -(defun evil-visual-post-command (&optional command) - "Run after each COMMAND in Visual state. -If COMMAND is a motion, refresh the selection; -otherwise exit Visual state." - (when (evil-visual-state-p) - (setq command (or command this-command)) - (if (or quit-flag - (memq command '(keyboard-quit keyboard-escape-quit)) - ;; Is `mark-active' nil for an unexpanded region? - deactivate-mark - (and (not evil-visual-region-expanded) - (not (region-active-p)) - (not (eq evil-visual-selection 'block)) - transient-mark-mode)) - (progn - (evil-exit-visual-state) - (evil-adjust-cursor)) - (if evil-visual-region-expanded - (evil-visual-contract-region) - (evil-visual-refresh)) - (setq evil-visual-x-select-timer - (run-with-idle-timer evil-visual-x-select-timeout nil - #'evil-visual-update-x-selection - (current-buffer))) - (evil-visual-highlight)))) -(put 'evil-visual-post-command 'permanent-local-hook t) - -(defun evil-visual-update-x-selection (&optional buffer) - "Update the X selection with the current visual region of BUFFER." - (let ((buf (or buffer (current-buffer)))) - (when (and evil-visual-update-x-selection-p - (buffer-live-p buf) - (evil-visual-state-p) - (display-selections-p) - (not (eq evil-visual-selection 'block))) - (with-current-buffer buf - (evil-set-selection 'PRIMARY (buffer-substring-no-properties - evil-visual-beginning - evil-visual-end)))))) - -(defun evil-visual-activate-hook (&optional _command) - "Enable Visual state if the region is activated." - (unless (evil-visual-state-p) - (evil-with-delay nil - (post-command-hook nil t "evil-activate-visual-state") - ;; the activation may only be momentary, so re-check - ;; in `post-command-hook' before entering Visual state - (unless (or (evil-visual-state-p) - (evil-insert-state-p) - (evil-emacs-state-p)) - (when (and (region-active-p) - (not deactivate-mark)) - (evil-visual-state)))))) -(put 'evil-visual-activate-hook 'permanent-local-hook t) - -(defun evil-visual-deactivate-hook (&optional command) - "Deactivate the region and restore Transient Mark mode." - (setq command (or command this-command)) - (remove-hook 'deactivate-mark-hook - #'evil-visual-deactivate-hook t) - (remove-hook 'evil-normal-state-entry-hook - #'evil-visual-deactivate-hook t) - (cond - ((and (evil-visual-state-p) command - (not (evil-get-command-property command :keep-visual))) - (setq evil-visual-region-expanded nil) - (evil-exit-visual-state)) - ((not (evil-visual-state-p)) - (evil-active-region -1) - (evil-restore-transient-mark-mode)))) -(put 'evil-visual-deactivate-hook 'permanent-local-hook t) - -(evil-define-command evil-exit-visual-state (&optional later buffer) - "Exit from Visual state to the previous state. -If LATER is non-nil, exit after the current command." - :keep-visual t - :repeat abort - (with-current-buffer (or buffer (current-buffer)) - (when (evil-visual-state-p) - (if later - (setq deactivate-mark t) - (when evil-visual-region-expanded - (evil-visual-contract-region)) - (setq evil-this-register nil - evil-prev-visual-selection evil-visual-selection - evil-prev-visual-mark (copy-marker evil-visual-mark) - evil-prev-visual-point (copy-marker evil-visual-point)) - (evil-change-to-previous-state))))) - -(defun evil-visual-tag (&optional selection) - "Return a mode-line tag for SELECTION. -SELECTION is a kind of selection as defined by -`evil-define-visual-selection', such as `char', `line' -or `block'." - (setq selection (or selection evil-visual-selection)) - (when selection - (symbol-value (intern (format "evil-visual-%s-tag" selection))))) - -(defun evil-visual-message (&optional selection) - "Create an echo area message for SELECTION. -SELECTION is a kind of selection as defined by -`evil-define-visual-selection', such as `char', `line' -or `block'." - (unless selection (setq selection evil-visual-selection)) - (when selection - (let ((message (symbol-value (intern (format "evil-visual-%s-message" - selection))))) - (cond - ((functionp message) (funcall message)) - ((stringp message) (evil-echo "%s" message)))))) - -(defun evil-visual-select (beg end &optional type dir message) - "Create a Visual selection of type TYPE from BEG to END. -Point and mark are positioned so that the resulting selection -has the specified boundaries. If DIR is negative, point precedes mark, -otherwise it succedes it. To specify point and mark directly, -use `evil-visual-make-selection'." - (let* ((range (evil-contract beg end type)) - (mark (evil-range-beginning range)) - (point (evil-range-end range)) - (dir (or dir 1))) - (when (< dir 0) - (evil-swap mark point)) - (evil-visual-make-selection mark point type message))) - -(defun evil-visual-make-selection (mark point &optional type message) - "Create a Visual selection with point at POINT and mark at MARK. -The boundaries of the selection are inferred from these -and the current TYPE. To specify the boundaries and infer -mark and point, use `evil-visual-select' instead." - (let* ((selection (evil-visual-selection-for-type type)) - (func (evil-visual-selection-function selection)) - (prev (and (evil-visual-state-p) evil-visual-selection)) - (mark (evil-normalize-position mark)) - (point (evil-normalize-position point)) - (state evil-state)) - (unless (evil-visual-state-p) - (evil-visual-state)) - (setq evil-visual-selection selection) - (funcall func mark point type - ;; signal a message when changing the selection - (when (or (not (evil-visual-state-p state)) - (not (eq selection prev))) - message)))) - -(defun evil-visual-make-region (mark point &optional type message) - "Create an active region from MARK to POINT. -If TYPE is given, also set the Visual type. -If MESSAGE is given, display it in the echo area." - (interactive) - (let* ((point (or point (point))) - (mark (or mark - (when (or (evil-visual-state-p) - (region-active-p)) - (mark t)) - point))) - (unless (evil-visual-state-p) - (evil-visual-state)) - (evil-active-region 1) - (setq evil-visual-region-expanded nil) - (evil-visual-refresh mark point type) - (cond - ((null evil-echo-state)) - ((stringp message) - (evil-echo "%s" message)) - (message - (cond - ((stringp evil-visual-state-message) - (evil-echo "%s" evil-visual-state-message)) - ((functionp evil-visual-state-message) - (funcall evil-visual-state-message))))))) - -(defun evil-visual-expand-region (&optional exclude-newline) - "Expand the region to the Visual selection. -If EXCLUDE-NEWLINE is non-nil and the selection ends with a newline, -exclude that newline from the region." - (when (and (evil-visual-state-p) - (not evil-visual-region-expanded)) - (let ((mark evil-visual-beginning) - (point evil-visual-end)) - (when (< evil-visual-direction 0) - (evil-swap mark point)) - (setq evil-visual-region-expanded t) - (evil-visual-refresh mark point) - (when (and exclude-newline - (save-excursion - (goto-char evil-visual-end) - (and (bolp) (not (bobp))))) - (if (< evil-visual-direction 0) - (evil-move-mark (max point (1- (mark)))) - (goto-char (max mark (1- (point))))))))) - -(defun evil-visual-contract-region () - "The inverse of `evil-visual-expand-region'. -Create a Visual selection that expands to the current region." - (evil-visual-refresh) - (setq evil-visual-region-expanded nil) - (evil-visual-refresh evil-visual-mark evil-visual-point)) - -(defun evil-visual-refresh (&optional mark point type &rest properties) - "Refresh point, mark and Visual variables. -Refreshes `evil-visual-beginning', `evil-visual-end', -`evil-visual-mark', `evil-visual-point', `evil-visual-selection', -`evil-visual-direction', `evil-visual-properties' and `evil-this-type'." - (let* ((point (or point (point))) - (mark (or mark (mark t) point)) - (dir (evil-visual-direction)) - (type (or type (evil-visual-type evil-visual-selection) - (evil-visual-type))) - range) - (evil-move-mark mark) - (goto-char point) - (setq evil-visual-beginning - (or evil-visual-beginning - (let ((marker (make-marker))) - (move-marker marker (min point mark)))) - evil-visual-end - (or evil-visual-end - (let ((marker (make-marker))) - (set-marker-insertion-type marker t) - (move-marker marker (max point mark)))) - evil-visual-mark - (or evil-visual-mark - (let ((marker (make-marker))) - (move-marker marker mark))) - evil-visual-point - (or evil-visual-point - (let ((marker (make-marker))) - (move-marker marker point)))) - (setq evil-visual-properties - (evil-concat-plists evil-visual-properties properties)) - (cond - (evil-visual-region-expanded - (setq type (or (evil-visual-type) type)) - (move-marker evil-visual-beginning (min point mark)) - (move-marker evil-visual-end (max point mark)) - ;; if the type is one-to-one, we can safely refresh - ;; the unexpanded positions as well - (when (evil-type-property type :one-to-one) - (setq range (apply #'evil-contract point mark type - evil-visual-properties) - mark (evil-range-beginning range) - point (evil-range-end range)) - (when (< dir 0) - (evil-swap mark point)) - (move-marker evil-visual-mark mark) - (move-marker evil-visual-point point))) - (t - (setq range (apply #'evil-expand point mark type - evil-visual-properties) - type (evil-type range type)) - (move-marker evil-visual-beginning (evil-range-beginning range)) - (move-marker evil-visual-end (evil-range-end range)) - (move-marker evil-visual-mark mark) - (move-marker evil-visual-point point))) - (setq evil-visual-direction dir - evil-this-type type))) - -(defun evil-visual-highlight (&optional arg) - "Highlight Visual selection, depending on the Visual type. -With negative ARG, disable highlighting." - (cond - ((and (numberp arg) (< arg 1)) - (when evil-visual-overlay - (delete-overlay evil-visual-overlay) - (setq evil-visual-overlay nil)) - (when evil-visual-block-overlays - (mapc #'delete-overlay evil-visual-block-overlays) - (setq evil-visual-block-overlays nil))) - ((eq evil-visual-selection 'block) - (when evil-visual-overlay - (evil-visual-highlight -1)) - (evil-visual-highlight-block - evil-visual-beginning - evil-visual-end)) - (t - (when evil-visual-block-overlays - (evil-visual-highlight -1)) - (if evil-visual-overlay - (move-overlay evil-visual-overlay - evil-visual-beginning evil-visual-end) - (setq evil-visual-overlay - (make-overlay evil-visual-beginning evil-visual-end))) - (overlay-put evil-visual-overlay 'face 'region) - (overlay-put evil-visual-overlay 'priority 99)))) - -(defun evil-visual-highlight-block (beg end &optional overlays) - "Highlight rectangular region from BEG to END. -Do this by putting an overlay on each line within the rectangle. -Each overlay extends across all the columns of the rectangle. -Reuse overlays where possible to prevent flicker." - (let* ((point (point)) - (overlays (or overlays 'evil-visual-block-overlays)) - (old (symbol-value overlays)) - beg-col end-col new nlines overlay window-beg window-end) - (save-excursion - ;; calculate the rectangular region represented by BEG and END, - ;; but put BEG in the upper-left corner and END in the - ;; lower-right if not already there - (setq beg-col (evil-column beg) - end-col (evil-column end)) - (when (>= beg-col end-col) - (if (= beg-col end-col) - (setq end-col (1+ end-col)) - (evil-swap beg-col end-col)) - (setq beg (progn (goto-char beg) (evil-move-to-column beg-col)) - end (progn (goto-char end) (evil-move-to-column end-col 1)))) - ;; maybe extend end column to EOL - (and (memq this-command '(next-line previous-line evil-use-register)) - (eq temporary-goal-column most-positive-fixnum) - (setq end-col most-positive-fixnum)) - ;; force a redisplay so we can do reliable window - ;; BEG/END calculations - (sit-for 0) - (setq window-beg (max (window-start) beg) - window-end (min (window-end) (1+ end)) - nlines (count-lines window-beg - (min window-end (point-max)))) - ;; iterate over those lines of the rectangle which are - ;; visible in the currently selected window - (goto-char window-beg) - (dotimes (_ nlines) - (let (before after row-beg row-end) - ;; beginning of row - (evil-move-to-column beg-col) - (when (< (current-column) beg-col) - ;; prepend overlay with virtual spaces if unable to - ;; move directly to the first column - (setq before - (propertize - (make-string - (- beg-col (current-column)) ?\s) - 'face - (or (get-text-property (1- (point)) 'face) - 'default)))) - (setq row-beg (point)) - ;; end of row - (evil-move-to-column end-col) - (when (and (not (eolp)) - (< (current-column) end-col)) - ;; append overlay with virtual spaces if unable to - ;; move directly to the last column - (setq after - (propertize - (make-string - (if (= (point) row-beg) - (- end-col beg-col) - (- end-col (current-column))) - ?\s) 'face 'region)) - ;; place cursor on one of the virtual spaces - (if (= point row-beg) - (put-text-property - 0 (min (length after) 1) - 'cursor t after) - (put-text-property - (max 0 (1- (length after))) (length after) - 'cursor t after))) - (setq row-end (min (point) (line-end-position))) - ;; trim old leading overlays - (while (and old - (setq overlay (car old)) - (< (overlay-start overlay) row-beg) - (/= (overlay-end overlay) row-end)) - (delete-overlay overlay) - (setq old (cdr old))) - ;; reuse an overlay if possible, otherwise create one - (cond - ((and old (setq overlay (car old)) - (or (= (overlay-start overlay) row-beg) - (= (overlay-end overlay) row-end))) - (move-overlay overlay row-beg row-end) - (overlay-put overlay 'before-string before) - (overlay-put overlay 'after-string after) - (setq new (cons overlay new) - old (cdr old))) - (t - (setq overlay (make-overlay row-beg row-end)) - (overlay-put overlay 'before-string before) - (overlay-put overlay 'after-string after) - (setq new (cons overlay new))))) - (forward-line 1)) - ;; display overlays - (dolist (overlay new) - (overlay-put overlay 'face 'region) - (overlay-put overlay 'priority 99)) - ;; trim old overlays - (dolist (overlay old) - (delete-overlay overlay)) - (set overlays (nreverse new))))) - -(defun evil-visual-range () - "Return the Visual selection as a range. -This is a list (BEG END TYPE PROPERTIES...), where BEG is the -beginning of the selection, END is the end of the selection, -TYPE is the selection's type, and PROPERTIES is a property list -of miscellaneous selection attributes." - (apply #'evil-range - evil-visual-beginning evil-visual-end - (evil-visual-type) - :expanded t - evil-visual-properties)) - -(defun evil-visual-direction () - "Return direction of Visual selection. -The direction is -1 if point precedes mark and 1 otherwise. -See also the variable `evil-visual-direction', which holds -the direction of the last selection." - (let* ((point (point)) - (mark (or (mark t) point))) - (if (< point mark) -1 1))) - -(defun evil-visual-type (&optional selection) - "Return the type of the Visual selection. -If SELECTION is specified, return the type of that instead." - (or (and (null selection) (evil-visual-state-p) evil-this-type) - (symbol-value (cdr (assq (or selection evil-visual-selection) - evil-visual-alist))))) - -(defun evil-visual-goto-end () - "Go to the last line of the Visual selection. -This position may differ from `evil-visual-end' depending on -the selection type, and is contained in the selection." - (let ((range (evil-contract-range (evil-visual-range)))) - (goto-char (evil-range-end range)))) - -(defun evil-visual-alist () - "Return an association list from types to selection symbols." - (mapcar #'(lambda (e) - (cons (symbol-value (cdr-safe e)) (cdr-safe e))) - evil-visual-alist)) - -(defun evil-visual-selection-function (selection) - "Return a selection function for TYPE. -Default to `evil-visual-make-region'." - (or (cdr-safe (assq selection evil-visual-alist)) - ;; generic selection function - 'evil-visual-make-region)) - -(defun evil-visual-selection-for-type (type) - "Return a Visual selection for TYPE." - (catch 'done - (dolist (selection evil-visual-alist) - (when (memq (symbol-value (cdr selection)) - (list type (evil-visual-type type))) - (throw 'done (car selection)))))) - -(defun evil-visual-block-corner (&optional corner point mark) - "Block corner corresponding to POINT, with MARK in opposite corner. -Depending on POINT and MARK, the return value is `upper-left', -`upper-right', `lower-left' or `lower-right': - - upper-left +---+ upper-right - | | - lower-left +---+ lower-right - -One-column or one-row blocks are ambiguous. In such cases, -the horizontal or vertical component of CORNER is used. -CORNER defaults to `upper-left'." - (let* ((point (or point (point))) - (mark (or mark (mark t))) - (corner (or corner - (when evil-visual-overlay - (overlay-get evil-visual-overlay :corner)) - 'upper-left)) - (point-col (evil-column point)) - (mark-col (evil-column mark)) - (upperp (if (save-excursion (goto-char (min point mark)) - (search-forward "\n" (max point mark) t)) - (< point mark) - (memq corner '(upper-left upper-right)))) - (leftp (if (= point-col mark-col) - (memq corner '(upper-left lower-left)) - (< point-col mark-col)))) - (if upperp - (if leftp 'upper-left 'upper-right) - (if leftp 'lower-left 'lower-right)))) - -;;; Operator-Pending state - -(evil-define-state operator - "Operator-Pending state." - :tag " <O> " - :cursor evil-half-cursor - :enable (evil-operator-shortcut-map operator motion normal)) - -(evil-define-keymap evil-operator-shortcut-map - "Keymap for Operator-Pending shortcuts like \"dd\" and \"gqq\"." - :local t - (setq evil-operator-shortcut-map (make-sparse-keymap)) - (evil-initialize-local-keymaps)) - -;; the half-height "Operator-Pending cursor" cannot be specified -;; as a static `cursor-type' value, since its height depends on -;; the current font size -(defun evil-half-cursor () - "Change cursor to a half-height box. -\(This is really just a thick horizontal bar.)" - (let ((height (/ (window-pixel-height) (* (window-height) 2)))) - (setq cursor-type (cons 'hbar height)))) - -;;; Replace state - -(evil-define-state replace - "Replace state." - :tag " <R> " - :cursor hbar - :message "-- REPLACE --" - :entry-hook (evil-start-track-last-insertion) - :exit-hook (evil-cleanup-insert-state evil-stop-track-last-insertion) - :input-method t - (cond - ((evil-replace-state-p) - (overwrite-mode 1) - (add-hook 'pre-command-hook #'evil-replace-pre-command nil t) - (add-hook 'pre-command-hook #'evil-insert-repeat-hook) - (unless (eq evil-want-fine-undo t) - (evil-start-undo-step))) - (t - (overwrite-mode -1) - (remove-hook 'pre-command-hook #'evil-replace-pre-command t) - (remove-hook 'pre-command-hook #'evil-insert-repeat-hook) - (setq evil-insert-repeat-info evil-repeat-info) - (evil-set-marker ?^ nil t) - (unless (eq evil-want-fine-undo t) - (evil-end-undo-step)) - (evil-move-cursor-back))) - (setq evil-replace-alist nil)) - -(defun evil-replace-pre-command () - "Remember the character under point." - (when (evil-replace-state-p) - (let ((char (unless (eolp) (char-after))) - (prev (assq (point) evil-replace-alist))) - (if prev - (setcdr prev char) - (push (cons (point) char) evil-replace-alist))))) -(put 'evil-replace-pre-command 'permanent-local-hook t) - -(defun evil-replace-backspace () - "Restore character under cursor." - (interactive) - (backward-char) - (let* ((prev (assq (point) evil-replace-alist)) - (char (cdr prev)) - (this-command #'evil-replace-backspace)) - (when prev - (delete-char 1) - (when char (save-excursion (insert char)))))) - -(defun evil-update-replace-alist (opoint count chars-to-delete &optional offset) - "Add CHARS-TO-DELETE chars to evil-replace-alist, starting at OPOINT. -If COUNT is greater than CHARS-TO-DELETE, pad the alist with nils. -Decrement recorded position by optional offset, or 0." - (when (evil-replace-state-p) - (dotimes (c count) - (let ((pos (+ c opoint))) - (add-to-list 'evil-replace-alist - (cons (- pos (or offset 0)) (when (< c chars-to-delete) - (char-after pos)))))))) - -;;; Motion state - -(evil-define-state motion - "Motion state." - :tag " <M> " - :suppress-keymap t) - -;;; Emacs state - -(evil-define-state emacs - "Emacs state." - :tag " <E> " - :message "-- EMACS --" - :input-method t - :intercept-esc nil) - -(provide 'evil-states) - -;;; evil-states.el ends here diff --git a/.config/emacs/lisp/evil/evil-test-helpers.el b/.config/emacs/lisp/evil/evil-test-helpers.el deleted file mode 100644 index c7eeb71..0000000 --- a/.config/emacs/lisp/evil/evil-test-helpers.el +++ /dev/null @@ -1,416 +0,0 @@ -;;; evil-test-helpers.el --- unit test helpers for Evil -*- coding: utf-8; lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> -;; Package-Requires: ((evil "1.15.0")) -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; This file contains helper functions for writing tests for -;; evil-mode. These helpers can also be used by other packages which -;; extend evil-mode. - -;; To write a test use `evil-test-buffer': - -;; (require 'evil-test-helpers) -;; -;; (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 'elp) -(require 'ert) -(require 'evil) - -;;; Code: - -(when (fboundp 'font-lock-add-keywords) - (font-lock-add-keywords 'emacs-lisp-mode - '(("(\\(evil-test-buffer\\)\\>" - 1 font-lock-keyword-face)))) - -(defvar evil-test-point nil - "Marker for point.") -(make-variable-buffer-local 'evil-test-point) -(defvar evil-test-visual-start nil - "Marker for Visual beginning.") -(make-variable-buffer-local 'evil-test-visual-start) -(defvar evil-test-visual-end nil - "Marker for Visual end.") -(make-variable-buffer-local 'evil-test-visual-end) - -(defvaralias 'evil-test-select-enable-clipboard - (if (boundp 'select-enable-clipboard) - 'select-enable-clipboard - 'x-select-enable-clipboard)) - -(defmacro evil-test-buffer (&rest body) - "Execute FORMS in a temporary buffer. -The following optional keywords specify the buffer's properties: - -:state STATE The initial state, defaults to `normal'. -:visual SELECTION The Visual selection, defaults to `char'. -:point-start STRING String for matching beginning of point, - defaults to \"[\". -:point-end STRING String for matching end of point, - defaults to \"]\". -:visual-start STRING String for matching beginning of - Visual selection, defaults to \"<\". -:visual-end STRING String for matching end of - Visual selection, defaults to \">\". - -Then follows one or more forms. If the first form is a string, -it is taken to be a buffer description as passed to -`evil-test-buffer-from-string', and initializes the buffer. -Subsequent string forms validate the buffer. - -If a form is a list of strings or vectors, it is taken to be a -key sequence and is passed to `execute-kbd-macro'. If the form -is \(file FILENAME CONTENTS), then the test fails unless the -contents of FILENAME equal CONTENTS. If the form is \(error -SYMBOL ...) then the test fails unless an error of type SYMBOL is -raised. Remaining forms are evaluated as-is. - -\(fn [[KEY VALUE]...] FORMS...)" - (declare (indent defun)) - (let ((state 'normal) - arg key point-start point-end string - visual visual-start visual-end) - ;; collect keywords - (while (keywordp (car-safe body)) - (setq key (pop body) - arg (pop body)) - (cond - ((eq key :point-start) - (setq point-start (or arg ""))) - ((eq key :point-end) - (setq point-end (or arg ""))) - ((eq key :state) - (setq state arg)) - ((eq key :visual) - (setq visual arg)) - ((eq key :visual-start) - (setq visual-start (or arg ""))) - ((eq key :visual-end) - (setq visual-end (or arg ""))))) - ;; collect buffer initialization - (when (stringp (car-safe body)) - (setq string (pop body))) - ;; macro expansion - `(let ((buffer (evil-test-buffer-from-string - ,string ',state - ,point-start ,point-end - ',visual ,visual-start ,visual-end)) - (kill-ring kill-ring) - (kill-ring-yank-pointer kill-ring-yank-pointer) - evil-test-select-enable-clipboard - message-log-max) - (unwind-protect - (save-window-excursion - (with-current-buffer buffer - ;; necessary for keyboard macros to work - (switch-to-buffer-other-window (current-buffer)) - (buffer-enable-undo) - ;; parse remaining forms - ,@(mapcar - #'(lambda (form) - (let (error-symbol) - (when (and (listp form) - (eq (car-safe form) 'error)) - (setq error-symbol (car-safe (cdr-safe form)) - form (cdr-safe (cdr-safe form)))) - (let ((result - (cond - ((stringp form) - `(evil-test-buffer-string - ,form - ',point-start ',point-end - ',visual-start ',visual-end)) - ((eq (car-safe form) 'file) - `(evil-test-file-contents ,(cadr form) - ,(car (cddr form)))) - ((or (stringp (car-safe form)) - (vectorp (car-safe form)) - (memq (car-safe (car-safe form)) - '(kbd vconcat))) - ;; we need to execute everything as a single - ;; sequence for command loop hooks to work - `(execute-kbd-macro - (apply #'vconcat - (mapcar #'listify-key-sequence - (list ,@form))))) - ((memq (car-safe form) '(kbd vconcat)) - `(execute-kbd-macro ,form)) - (t form)))) - (if error-symbol - `(should-error ,result :type ',error-symbol) - result)))) - body))) - (when (buffer-name buffer) (kill-buffer buffer)))))) - -(defmacro evil-test-selection (string &optional end-string - before-predicate after-predicate) - "Verify that the Visual selection contains STRING." - (declare (indent defun)) - `(progn - (save-excursion - (goto-char (or evil-visual-beginning (region-beginning))) - (evil-test-text nil (or ,string ,end-string) ,before-predicate)) - (save-excursion - (goto-char (or evil-visual-end (region-end))) - (evil-test-text (or ,end-string ,string) nil nil ,after-predicate)))) - -(defun evil-test-buffer-string (string &optional - point-start point-end - visual-start visual-end) - "Validate the current buffer according to STRING. -If STRING contains an occurrence of POINT-START immediately -followed by POINT-END, that position is compared against point. -If STRING contains an occurrence of VISUAL-START followed by -VISUAL-END, those positions are compared against the Visual selection. -POINT-START and POINT-END default to [ and ]. -VISUAL-START and VISUAL-END default to < and >." - (let ((actual-buffer (current-buffer)) - (marker-buffer (evil-test-marker-buffer-from-string - string - point-start point-end - visual-start visual-end)) - before-point after-point string selection) - (unwind-protect - (with-current-buffer marker-buffer - (setq string (buffer-string)) - (when evil-test-point - (setq before-point (buffer-substring (point-min) evil-test-point) - after-point (buffer-substring evil-test-point (point-max)))) - (when (and evil-test-visual-start evil-test-visual-end) - (setq selection (buffer-substring - evil-test-visual-start evil-test-visual-end))) - (with-current-buffer actual-buffer - (if (or before-point after-point) - (evil-test-text before-point after-point) - ;; if the cursor isn't specified, just test the whole buffer - (save-excursion - (goto-char (point-min)) - (evil-test-text nil string #'bobp #'eobp))) - (when selection - (evil-test-selection selection)))) - (kill-buffer marker-buffer)))) - -(defun evil-test-buffer-from-string (string &optional - state - point-start point-end - visual visual-start visual-end) - "Create a new buffer according to STRING. -If STRING contains an occurrence of POINT-START immediately -followed by POINT-END, then point is moved to that position. -If STRING contains an occurrence of VISUAL-START followed by -VISUAL-END, then a Visual selection is created with those boundaries. -POINT-START and POINT-END default to [ and ]. -VISUAL-START and VISUAL-END default to < and >. -STATE is the initial state; it defaults to `normal'. -VISUAL is the Visual selection: it defaults to `char'." - (let ((type (evil-visual-type (or visual 'char))) - (buffer (evil-test-marker-buffer-from-string - string point-start point-end - visual-start visual-end))) - (with-current-buffer buffer - (prog1 buffer - (evil-change-state state) - ;; let the buffer change its major mode without disabling Evil - (add-hook 'after-change-major-mode-hook #'evil-initialize) - (when (and (markerp evil-test-visual-start) - (markerp evil-test-visual-end)) - (evil-visual-select - evil-test-visual-start evil-test-visual-end type) - (when evil-test-point - (goto-char evil-test-point) - (evil-visual-refresh) - (unless (and (= evil-visual-beginning - evil-test-visual-start) - (= evil-visual-end - evil-test-visual-end)) - (evil-visual-select - evil-test-visual-start evil-test-visual-end type -1) - (goto-char evil-test-point) - (evil-visual-refresh)))) - (when (markerp evil-test-point) - (goto-char evil-test-point)))))) - -(defun evil-test-marker-buffer-from-string (string &optional - point-start point-end - visual-start visual-end) - "Create a new marker buffer according to STRING. -If STRING contains an occurrence of POINT-START immediately -followed by POINT-END, that position is stored in the -buffer-local variable `evil-test-point'. Similarly, -if STRING contains an occurrence of VISUAL-START followed by -VISUAL-END, those positions are stored in the variables -`evil-test-visual-beginning' and `evil-test-visual-end'. -POINT-START and POINT-END default to [ and ]. -VISUAL-START and VISUAL-END default to < and >." - (let ((string (or string "")) - (point-start (regexp-quote - (if (characterp point-start) - (string point-start) - (or point-start "[")))) - (point-end (regexp-quote - (if (characterp point-end) - (string point-end) - (or point-end "]")))) - (visual-start (regexp-quote - (if (characterp visual-start) - (string visual-start) - (or visual-start "<")))) - (visual-end (regexp-quote - (if (characterp visual-end) - (string visual-end) - (or visual-end ">"))))) - (with-current-buffer (generate-new-buffer " *test*") - (prog1 (current-buffer) - (save-excursion - (insert string)) - (save-excursion - (when (> (length point-start) 0) - (if (> (length point-end) 0) - (when (re-search-forward - (format "\\(%s\\)[^%s]?\\(%s\\)" - point-start point-end point-end) nil t) - (goto-char (match-beginning 0)) - (delete-region (match-beginning 2) (match-end 2)) - (delete-region (match-beginning 1) (match-end 1)) - (setq evil-test-point - (move-marker (make-marker) (point)))) - (when (re-search-forward point-start nil t) - (goto-char (match-beginning 0)) - (delete-region (match-beginning 0) (match-end 0)) - (setq evil-test-point - (move-marker (make-marker) (point))))))) - (save-excursion - (when (and (> (length visual-start) 0) - (> (length visual-end) 0)) - (when (re-search-forward visual-start nil t) - (goto-char (match-beginning 0)) - (delete-region (match-beginning 0) (match-end 0)) - (setq evil-test-visual-start - (move-marker (make-marker) (point)))) - (when (re-search-forward visual-end nil t) - (goto-char (match-beginning 0)) - (delete-region (match-beginning 0) (match-end 0)) - (setq evil-test-visual-end - (move-marker (make-marker) (point)))))))))) - -(defun evil-test-text (before after &optional before-predicate after-predicate) - "Verify the text around point. -BEFORE is the expected text before point, and AFTER is -the text after point. BEFORE-PREDICATE is a predicate function -to execute at the beginning of the text, and AFTER-PREDICATE -is executed at the end." - (when before - (if (functionp before) - (setq before-predicate before - before nil) - (should (string= (buffer-substring - (max (point-min) (- (point) (length before))) - (point)) - before)))) - (when after - (if (functionp after) - (setq after-predicate after - after nil) - (should (string= (buffer-substring - (point) - (min (point-max) (+ (point) (length after)))) - after)))) - (when before-predicate - (ert-info ((format "Expect `%s' at the beginning" before-predicate)) - (save-excursion - (backward-char (length before)) - (should (funcall before-predicate))))) - (when after-predicate - (ert-info ((format "Expect `%s' at the end" after-predicate)) - (save-excursion - (forward-char (length after)) - (should (funcall after-predicate)))))) - -(defmacro evil-test-region (string &optional end-string - before-predicate after-predicate) - "Verify that the region contains STRING." - (declare (indent defun)) - `(progn - (save-excursion - (goto-char (region-beginning)) - (evil-test-text nil (or ,string ,end-string) ,before-predicate)) - (save-excursion - (goto-char (region-end)) - (evil-test-text (or ,end-string ,string) nil nil ,after-predicate)))) - -(defmacro evil-test-overlay (overlay string &optional end-string - before-predicate after-predicate) - "Verify that OVERLAY contains STRING." - (declare (indent defun)) - `(progn - (save-excursion - (goto-char (overlay-start ,overlay)) - (evil-test-text nil (or ,string ,end-string) ,before-predicate)) - (save-excursion - (goto-char (overlay-end ,overlay)) - (evil-test-text (or ,end-string ,string) nil nil ,after-predicate)))) - -(defmacro evil-with-temp-file (file-var content &rest body) - "Create a temp file with CONTENT and bind its name to FILE-VAR within BODY. -FILE-VAR must be a symbol which contains the name of the -temporary file within the macro body. CONTENT is either a string -to be used as the content of the temporary file or a form to be -executed with the temporary file's buffer as \(current-buffer), -see `with-temp-file'. BODY contains the forms to be executed -while the temporary file exists. The temporary file is deleted at -the end of the execution of BODY." - (declare (indent 2) - (debug (symbolp form body))) - `(let ((,file-var (make-temp-file "evil-test"))) - (with-temp-file ,file-var - ,(if (stringp content) - `(insert ,content) - content)) - ,@body - (delete-file ,file-var))) - -(defun evil-test-file-contents (name contents) - "Ensure that the contents of file with NAME equal CONTENTS." - (with-temp-buffer - (insert-file-contents name) - (should (string= (buffer-string) - contents)))) - -(provide 'evil-test-helpers) - -;;; evil-test-helpers.el ends here diff --git a/.config/emacs/lisp/evil/evil-tests.el b/.config/emacs/lisp/evil/evil-tests.el deleted file mode 100644 index 01af626..0000000 --- a/.config/emacs/lisp/evil/evil-tests.el +++ /dev/null @@ -1,10130 +0,0 @@ -;; evil-tests.el --- unit tests for Evil -*- coding: utf-8; lexical-binding: t; -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; 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. - -;; FIXME: Merely loading an ELisp file should not change Emacs's config! -(setq load-prefer-newer t) - -(require 'cl-lib) -(require 'elp) -(require 'ert) -;; Load non-compiled `evil-ex'. (It defines `evil-parser' - which is -;; needed by `evil-test-parser' - only inside an `eval-when-compile'.) -(require 'evil-ex "evil-ex.el") -(require 'evil) -(require 'evil-digraphs) -(require 'evil-test-helpers) -(require 'ispell) - -;;; 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 (consp profiler) - (setq profiler (car profiler))) - (when profiler - (setq evil-tests-profiler t) - (setq profiler - (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" - (evil-change-state state) - (let ((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 () - "Execute Normal state command in Insert state (`evil-execute-in-normal-state')." - :tags '(evil) - (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 - :state insert - "\n[]" - ("\C-ok") - "[]\n") - (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 "£") #'undefined)) - (ert-info ("Don't insert text") - ;; may or may not signal an error, depending on batch mode - (condition-case nil - (execute-kbd-macro "£££") - (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-info ("Compute shortcuts with original keymaps") - (evil-test-buffer "foo" - (define-key evil-normal-state-local-map (kbd "SPC x") #'evil-delete) - ;; evil-forward-char in motion map should not shadow the executed - ;; evil-delete binding above when populating shortcut map. - ((kbd "SPC x x")) - ""))) - -(ert-deftest evil-test-auxiliary-maps () - "Test auxiliary keymaps" - :tags '(evil state) - ;; `evil-define-key' can't be used on a lexically-scoped keymap var. - (defvar evil--map) - (let ((evil--map (make-sparse-keymap)) aux) - (ert-info ("Create a new auxiliary keymap") - (evil-define-key 'normal evil--map "f" 'foo) - (setq aux (evil-get-auxiliary-keymap evil--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 evil--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)))) - (forward-line) - (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-insert () - "Test `evil-insert' in Visual state." - :tags '(evil insert) - (ert-info ("Repeat insert over empty lines") - (evil-test-buffer :visual line "<\n\n[]>" - ("IX" [escape]) - "X\nX\nX"))) - -(ert-deftest evil-test-visual-append () - "Test `evil-append' in Visual state." - :tags '(evil insert) - (evil-test-buffer "<fo[o]> bar" - ("A_evil rulz " [escape]) - "foo_evil rulz[ ] bar")) - -(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 "foo [b]ar" - ("Ievil rulz " [escape]) - "evil rulz[ ]foo bar") - (ert-info ("With count") - (evil-test-buffer "foo [b]ar" - ("2Ievil rulz " [escape]) - "evil rulz evil rulz[ ]foo bar"))) - -(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")))) - -(ert-deftest evil-test-track-insertion () - "Test that the text of the previous insertion is tracked." - (ert-info ("Moving the cursor starts a new insertion") - (evil-test-buffer - ("iabc" [left] "xxx" [escape] "o\C-a") - "abxxxc\nxxx")) - (ert-info ("Autoindentation should be excluded") - (evil-test-buffer "\(setq x" - (emacs-lisp-mode) - ("o0\)" [escape] "o\C-a") - "(setq x - 0) -0\)"))) - -;;; 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-info ("Repeat search motion with offset") - (evil-select-search-module 'evil-search-module 'evil-search) - (evil-test-buffer - "[f]irst, second, third, fourth" - ("d/, /e" [return]) - "[s]econd, third, fourth" - ("2.") - "[f]ourth"))) - -(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" - ("re'") - "[é]; This buffer is for notes you don't want to save" - ("3rc*") - "ξξ[ξ]This buffer is for notes you don't want to save") - (ert-info ("Repeat replace digraph") - (evil-test-buffer - "ab[c]defghijkl" - ("rW*") - "ab[Ω]defghijkl" - ("fg" "2.") - "abΩdefΩ[Ω]ijkl"))) - (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-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-info ("Repeat append over empty lines") - (evil-test-buffer - "" - ("i" [return] [return] [return] [return] [return] [return] [escape] "gg\C-vGAX" [escape]) - "X\nX\nX\nX\nX\nX\n"))) - -(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-visual-block-insert () - "Test inserting (prepending) in visual block." - :tags '(evil visual insert) - (ert-info ("Prepend and repeat") - (evil-test-buffer - "[a]lpha\nbravo\ncharlie\ndelta\necho\nfoxtrot\ngolf" - ("\C-v" "jj" "I" "zulu" [escape]) - "zul[u]alpha\nzulubravo\nzulucharlie\ndelta\necho\nfoxtrot\ngolf" - ("/delta" [return] ".") - "zulualpha\nzulubravo\nzulucharlie\nzul[u]delta\nzuluecho\nzulufoxtrot\ngolf"))) - -(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-indent () - "Test `evil-indent'" - :tags '(evil visual operator) - (evil-test-buffer - :state visual - "< Line with too much indentation.>" - ("=") - "Line with too much indentation.") - (ert-info ("Can repeat evil-indent without errors") - (evil-test-buffer - "[ ]x\n x" - ("==j.") - "x\nx"))) - -(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<b\nc>\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") - (evil-test-buffer - "1\n2\n3\n4\n5\n6\n7\n8\n9\n1[0]" - (":-5,.y") - "1\n2\n3\n4\n5\n6\n7\n8\n9\n1[0]") - (evil-test-buffer - "1\n2\n3\n4\n[5]\n6\n7\n8\n9\n10" - ("my" "G" ":'y,.y") - "1\n2\n3\n4\n5\n6\n7\n8\n9\n[1]0"))) - -(ert-deftest evil-test-yank-line () - "Test `evil-yank-line'" - :tags '(evil operator) - (ert-info ("Yank line with eof being part of visual selection") - (evil-test-buffer - ";; This is line one -;; This is lin[e] two -;; This is line three" - ("v$Yjp") - ";; This is line one -;; This is line two -;; This is line three -[;]; This is line two"))) - -(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<b\nc>\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 <buffe[r]> is for notes, -and for Lisp evaluation." - ("D") - "and for Lisp [e]valuation.")) - (ert-info ("Act on each line of block selection") - (evil-test-buffer - :visual block - ";; This buffer is for <notes, -;; and for Lisp evaluatio[n]>." - ("D") - ";; This buffer is for[ ] -;; and for Lisp evalua")) - (ert-info ("Yank full block with block selection") - (evil-test-buffer - :visual block - "line1 l<ine1 line1 line1\nline2 line2\nline3 lin>e3 line3\n" - ("D") - "line1 [l]\nline2 l\nline3 l\n" - ("0P") - "ine1 line1 line1line1 l -ine2 line2 l -ine3 line3 line3 l\n")) - (ert-info ("Delete additional whole lines with count") - (evil-test-buffer - "a[a]a\nbbb\nc\n" - ("2D") - "a\nc\n")) - (ert-info ("Delete line with eof being part of visual selection") - (evil-test-buffer - ";; This is line one -;; This is lin[e] two -;; This is line three" - ("v$D") - ";; This is line one -;; This is line three")) - (ert-info ("Deletion in normal state leaves point in the right place") - (evil-test-buffer - "alpha b[r]avo charlie\ndelta echo foxtrot\ngolf hotel india" - (should-not evil-start-of-line) - ("D") - "alpha [b]\ndelta echo foxtrot\ngolf hotel india" - ("/echo" [return] "C" "newtext" [escape]) - "alpha b\ndelta newtex[t]\ngolf hotel india") - (let ((evil-start-of-line t)) - (evil-test-buffer - "alpha b[r]avo charlie\ndelta echo foxtrot\ngolf hotel india" - ("D") - "alpha [b]\ndelta echo foxtrot\ngolf hotel india" - ("/echo" [return] "C" "newtext" [escape]) - "alpha b\ndelta newtex[t]\ngolf hotel india"))) - (ert-info ("Line deletion in visual state leaves point in the right place") - (evil-test-buffer - "alpha [b]ravo charlie\ndelta echo foxtrot\ngolf hotel india" - (should-not evil-start-of-line) - ("vD") - "delta [e]cho foxtrot\ngolf hotel india" - ("vX") - "golf h[o]tel india") - (let ((evil-start-of-line t)) - (evil-test-buffer - "alpha [b]ravo charlie\ndelta echo foxtrot\ngolf hotel india" - ("vD") - "[d]elta echo foxtrot\ngolf hotel india" - ("vX") - "[g]olf hotel india")))) - -(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, and ex command-line." - :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-info ("evil-delete-backward-word in ex command-line") - (evil-test-buffer - "[ ]" - (":normal i" "one-two" (kbd "C-w") (kbd "C-w") [return]) - "on[e]"))) - -(ert-deftest evil-test-visual-X () - "Test `X' in visual state." - :tags '(evil) - (evil-test-buffer - "This is line one\nThis is lin[e] two\nThis is line three" - ("v$oX") - "This is line one\nThis is lin[e] three")) - -(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-line () - "Test `evil-change-line'" - :tags '(evil operator) - (ert-info ("Change line with eof being part of visual selection") - (evil-test-buffer - "This is line one -This is lin[e] two -This is line three" - ("v$C") - "This is line one -[] -This is line three"))) - -(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-info ("Join blank line") - (evil-test-buffer - "(when foo\n[]\n bar)" - (emacs-lisp-mode) - ("J") - "(when foo\n [b]ar)"))) - -(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[]")))) - -(ert-deftest evil-test-operator-set-marks () - "Test `[ and `] are set by operators." - :tags '(evil operator) - (ert-info ("Can go to end of last operated text") - (evil-test-buffer - "alpha br[a]vo charlie" - ("gUiw") - "alpha [B]RAVO charlie" - ("`]") - "alpha BRAV[O] charlie")) - (ert-info ("Can go to end of last operated text") - (evil-test-buffer - "alpha br[a]vo charlie" - ("g?iw$") - "alpha oenib charli[e]" - ("`[") - "alpha [o]enib charlie")) - (ert-info ("Marks are correct after deletion") - (evil-test-buffer - "alpha br[a]vo charlie" - ("daw^") - "[a]lpha charlie" - ("`]") - "alpha [c]harlie" - ("^`[") - "alpha [c]harlie") - (evil-test-buffer - "alpha br[a]vo charlie" - ("D^") - "[a]lpha br" - ("`]") - "alpha b[r]" - ("^`[") - "alpha b[r]"))) - -(ert-deftest evil-test-operator-save-state-for-motion () - "Test that `evil-operator-range' restores state after executing motion." - (evil-test-buffer "abc" - ("dfbix" [escape]) - "xc")) - -;;; 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-info ("Don't mutate register when stripping test props") - (let (indent-tabs-mode) - (evil-test-buffer - "[a]aaaaaaaaaaaa -bbbbbbbb -cccc" - ("\C-vG$yA " "\C-r\"" [escape] "up") - "aaaaaaaaaaaaa[a]aaaaaaaaaaaa -bbbbbbbb bbbbbbbb -cccc cccc")))) - -(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\n1<abcabc3\n1abcabc3\n1abcab[c]>3")) - (ert-info ("Blockwise visual paste of linewise text") - (evil-test-buffer "[a]bc\n123\n123" - ("yy" "jl" "\C-vj" "p") - "abc\n13\n13\nabc")) - (ert-info ("Blockwise visual paste of blockwise text") - (evil-test-buffer "xy\n[z]\n123\n123" - ("\C-vkly2jl\C-vjp") - "xy\nz\n1xy3\n1z 3"))) - -(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]\nword3a 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]\nword3a 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-info ("Normal delete after visual delete doesn't clobber register") - (evil-test-buffer - "[a]lpha bravo charlie delta" - ("vf \"xd" "dw" ";\"xp") - "charlie alpha delta")) - (ert-info ("Choosing register keeps eol anchoring") - (evil-test-buffer - "[a]aaaaa\nbbbbb\ncccc" - ("\C-v" "2j" "$" "\"xy" "G" "o" [escape] "\"xp") - "aaaaaa\nbbbbb\ncccc\n[a]aaaaa\nbbbbb\ncccc"))) - -(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-gp-gP () - (ert-info ("gp and gP are just like p and P but move the cursor forward") - (evil-test-buffer - "[a]lpha bravo charlie" - ("ye" "2f " "gp") - "alpha bravo alpha[c]harlie" - ("2F " "gP") - "alphaalpha[ ]bravo alphacharlie" - ("l" "ve" "gp") - "alphaalpha alpha[ ]alphacharlie")) - (ert-info ("gp linewise") - (evil-test-buffer - "[a]lpha line\nbravo line\ncharlie line\ndelta line\necho line" - ("2yy" "2j") - "alpha line\nbravo line\n[c]harlie line\ndelta line\necho line" - ("gp") - "alpha line\nbravo line\ncharlie line\nalpha line\nbravo line\n[d]elta line\necho line" - (".") - "alpha line\nbravo line\ncharlie line\nalpha line\nbravo line\ndelta line\nalpha line\nbravo line\necho line"))) - -(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[.]" - (error end-of-line "l") - (error end-of-line "10l"))) - (ert-info ("Until end-of-line") - (evil-test-buffer - "[;]; This buffer is for notes." - (error end-of-line "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." - (error beginning-of-line "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-logical-visual-next-line () - "Test alternating between logical and visual next/previous line motions." - :tags '(evil motion) - (skip-unless (and (not noninteractive) (> (window-width) 2))) - (evil-test-buffer "[x]\nyy\n" - (insert (make-string (window-width) ?x)) ; Make first line soft-wrap - (goto-char (point-min)) - ("gjj") - (should (= (current-column) 1)) - ("Gkgk") - (should-not (bolp)))) - -(ert-deftest evil-test-eol-anchoring-with-visual-line-movement () - "Test gj and gk once the cursor is anchored at eol with $." - :tags '(evil motion) - (skip-unless (and (not noninteractive) (> (window-width) 13))) - (evil-test-buffer - "Short [l]ine\nA longer line\nThird line" - ("$gj") - "Short line\nA longer lin[e]\nThird line")) - -(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-info ("Visual state") - (evil-test-buffer - "f[o]o\nbar" - ("v$") - "f<oo\n>bar") - (let ((evil-v$-excludes-newline t)) - (evil-test-buffer - "f[o]o\nbar" - ("v$") - "f<oo>\nbar")))) - -(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" - ("v29go") - "We only need a short bu<ffer [f]>or 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 <stdio.h>" - (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-paren-jump-from-string () - "Test jump to next/prev paren from a string" - :tags '(evil motion) - (evil-test-buffer - "{ - fun(a, \"T[]est\", test()); -} -" - ("[(") - "{ - fun[(]a, \"Test\", test()); -} -" - ("])") - "{ - fun(a, \"Test\", test()[)]; -} -") - (evil-test-buffer - "{ - fun(a, \"T[]est\", test()); -} -" - ("])") - "{ - fun(a, \"Test\", test()[)]; -} -" - ("[(") - "{ - fun[(]a, \"Test\", test()); -} -") - (evil-test-buffer - "{ - fun(a, \"T[]est\", test()); -} -" - ("[{") - "[{] - fun(a, \"Test\", test()); -} -") - (evil-test-buffer - "{ - fun(a, \"T[]est\", test()); -} -" - ("]}") - "{ - fun(a, \"Test\", test()); -[}] -")) - -(ert-deftest evil-test-paren-jump-inside-string-from-string () - "Test jump to next/prev paren inside string from a string" - :tags '(evil motion) - (evil-test-buffer - "{ (\"Test with paren (inside multi (l[e]vel))\", test()); } " - ("[(") - "{ (\"Test with paren (inside multi [(]level))\", test()); } " - ("[(") - "{ (\"Test with paren [(]inside multi (level))\", test()); } ") - (evil-test-buffer - "{ (\"Test with paren (inside multi (l[e]vel))\", test()); } " - ("])") - "{ (\"Test with paren (inside multi (level[)])\", test()); } " - ("])") - "{ (\"Test with paren (inside multi (level)[)]\", test()); } ") - (evil-test-buffer - "{ (\"Test with paren {inside multi {l[e]vel}}\", test()); } " - ("[{") - "{ (\"Test with paren {inside multi [{]level}}\", test()); } " - ("[{") - "{ (\"Test with paren [{]inside multi {level}}\", test()); } ") - (evil-test-buffer - "{ (\"Test with paren {inside multi {l[e]vel}}\", test()); } " - ("]}") - "{ (\"Test with paren {inside multi {level[}]}\", test()); } " - ("]}") - "{ (\"Test with paren {inside multi {level}[}]\", test()); } ")) - -(ert-deftest evil-test-insert-resume () - "Test `evil-insert-resume'" - :tags '(evil motion) - (ert-info ("Can move to last insert location and take a count") - (evil-test-buffer - "alpha bravo [ ]delta echo" - ("i" "charlie" [escape] "^") - "[a]lpha bravo charlie delta echo" - ("2gi" " zulu" [escape]) - "alpha bravo charlie zulu zul[u] delta echo")) - (ert-info ("Can move to `^' marker in visual line state") - (evil-test-buffer - "alpha [b]ravo\ncharlie delta\necho foxtrot" - ("i" [escape] "/foxtrot" [return]) - "alpha bravo\ncharlie delta\necho [f]oxtrot" - ("Vk") - "alpha bravo\ncharl[i]e delta\necho foxtrot" - ("gi") - "alpha [b]ravo\ncharlie delta\necho foxtrot" - ("vd") - "alpha [o]xtrot"))) - -(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-automatic-marks-test () - "Test that certain commands automatically set mark(er)s" - :tags '(evil) - (ert-info ("Visual selection sets angle-bracket marks") - (evil-test-buffer - "alpha br[a]vo charlie" - ("viw" [escape] "$") - "alpha bravo charli[e]" - ("`>") - "alpha brav[o] charlie" - ("`<") - "alpha [b]ravo charlie"))) - -(ert-deftest evil-test-flyspell-motions () - "Test flyspell motions" - :tags '(evil motion) - (skip-unless (condition-case _ (progn (ispell-check-version) t) (error))) - (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") - (evil-test-buffer - "[o]en otw thre" - (flyspell-mode) - (flyspell-buffer) - ("]s") - "oen [o]tw thre" - ("]s") - "oen otw [t]hre" - ("]s") - "[o]en otw thre")) - (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" - (error search-failed "]s")))) - (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) - (error search-failed "]s") - (error search-failed "[s")))) - -;;; 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 - ";; <Thi[s]> buffer is for notes." - (call-interactively object) - ";; <This b[u]>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") - ";; <Thi[s]> buffer is for notes.") - (evil-test-buffer - ";; [T]his buffer is for notes." - ("vaw") - ";; <This[ ]>buffer is for notes.") - (evil-test-buffer - ";; Thi[s] buffer is for notes." - ("viw") - ";; <Thi[s]> buffer is for notes.") - (evil-test-buffer - ";; Thi[s] buffer is for notes." - ("vaw") - ";; <This[ ]>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 - ";; <This[ ]>buffer is for notes." - ("aw") - ";; <This buffer[ ]>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") - (evil-test-buffer - "fo[o]\nbar" - ("diW") - "[\n]bar") - (evil-test-buffer - "foo\n [ ] bar" - ("daw") - "foo\n[]") - (evil-test-buffer - "foo\n [ ] bar" - ("daW") - "foo\n[]")) - (ert-info ("Deleting the only word on a line doesn't delete indentation") - (evil-test-buffer - " [b]ar" - ("daw") - " [ ]") - (evil-test-buffer - " [b]ar" - ("daW") - " [ ]") - (ert-info ("But deleting the final word of many behaves as normal") - (evil-test-buffer - " foo [b]ar" - ("daw") - " fo[o]"))) - (ert-info ("Deleting whitespace on whitepsace only line") - (evil-test-buffer - "foo\n[ ]\nbar" - ("diw") - "foo\n[]\nbar") - (evil-test-buffer - "foo\n[ ]\nbar" - ("daw") - "foo\n[]\nbar"))) - -(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") - "<abcd123[4]>") - (evil-test-buffer - "[a]bcd1234" - ("vaw") - "<abcd123[4]>") - (evil-test-buffer - "[a]bcd漢字" - ("viw") - "<abc[d]>漢字") - (evil-test-buffer - "[a]bcd漢字" - ("vaw") - "<abc[d]>漢字") - (evil-test-buffer - "[a]bcdひらがな" - ("viw") - "<abc[d]>ひらがな") - (evil-test-buffer - "[a]bcdひらがな" - ("vaw") - "<abc[d]>ひらがな") - (evil-test-buffer - "[a]bcdカタカナ" - ("viw") - "<abc[d]>カタカナ") - (evil-test-buffer - "[a]bcdカタカナ" - ("vaw") - "<abc[d]>カタカナ") - (evil-test-buffer - "[a]bcdカタカナ" - ("viw") - "<abcdカタカ[ナ]>") - (evil-test-buffer - "[a]bcdカタカナ" - ("vaw") - "<abcdカタカ[ナ]>") - (evil-test-buffer - "[a]bcdABC" - ("viw") - "<abcdAB[C]>") - (evil-test-buffer - "[a]bcdABC" - ("vaw") - "<abcdAB[C]>") - (evil-test-buffer - "[a]bcd123" - ("viw") - "<abcd12[3]>") - (evil-test-buffer - "[a]bcd123" - ("vaw") - "<abcd12[3]>") - (evil-test-buffer - "[a]bcd한글" - ("viw") - "<abc[d]>한글") - (evil-test-buffer - "[a]bcd한글" - ("vaw") - "<abc[d]>한글") - (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 '<a tes[t]>' for quote objects.") - (evil-test-buffer - "This is \"a '[t]est'\" for quote objects." - ("vi'") - "This is \"a '<tes[t]>'\" 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(") - "(<aa[a]>)") - (evil-test-buffer - "(aaa[)]" - (emacs-lisp-mode) - ("vi(") - "(<aa[a]>)") - (ert-info ("Next to outer delimiter") - (evil-test-buffer - "([(]aaa))" - (emacs-lisp-mode) - ("vi(") - "((<aa[a]>))") - (evil-test-buffer - "((aaa[)])" - (emacs-lisp-mode) - ("vi(") - "((<aa[a]>))"))) - (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 (c<ond) { - do_[s]>omething(); - } -}" - ("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 "}" - "<p><a>f[o]o</a> bar</p>" - ("vit") - "<p><a>{fo[o]}</a> bar</p>")) - (ert-info ("Break out of tags") - (evil-test-buffer - :visual-start "{" - :visual-end "}" - "<a[a]a>bbbb</aaa>" - ("vit") - "<aaa>{bbb[b]}</aaa>") - (evil-test-buffer - :visual-start "{" - :visual-end "}" - "<a[a]a>bbbb</aaa>" - ("vat") - "{<aaa>bbbb</aaa[>]}")) - (ert-info ("Handle quoted strings tags") - (evil-test-buffer - :visual-start "{" - :visual-end "}" - "<html> -<body> -<div id=\"content\"> -\[ ] -<p> -UPDATE -</p> -<p> -test hello <a href=\"/deed.zh\">Creative Commons</a> -</p> -</div> -</body> -</html> -" - ("vit") - "<html> -<body> -<div id=\"content\">{\n \n<p> -UPDATE -</p> -<p> -test hello <a href=\"/deed.zh\">Creative Commons</a> -</p>[\n]}</div> -</body> -</html> -")) - (ert-info ("Handle js arrow fns") - (evil-test-buffer - :visual-start "«" - :visual-end "»" - "<button foo=\"bar\" onClick={() => fnbody()}>inner [t]ext</button>" - ("vit") - "<button foo=\"bar\" onClick={() => fnbody()}>«inner tex[t]»</button>")) - (ert-info ("Inner tag is selected, even when empty") - (evil-test-buffer - :visual-start "«" - :visual-end "»" - "<p>foo<b [c]lass =\"bold\"></b>qux</p>" - ("cit" "bar") - "<p>foo<b class =\"bold\">bar</b>qux</p>"))) - -;;; 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-non-transient-visual-selection () - "Ensure visual charwise selection can be made when transient mark mode is nil." - :tags '(evil visual) - (evil-test-buffer - "Alpha [b]ravo charlie" - (setq-local transient-mark-mode nil) - ("ve") - "Alpha <brav[o]> charlie")) - -(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)) - ";; <Thi[s]> 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") - ";; <Thi[s]> 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-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") - ";; <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") - ";;[ ]<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") - "<[;]; 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-info ("Visual block does not extend up to curswant unless tracking EOL") - (evil-test-buffer - "[a]bc -" - ("\C-vfcjd") - "[b]c -")) - (ert-info ("Pasting visual block") - (evil-test-buffer - "alpha [b]ravo charlie -delta echo foxtrot -golf hotel india -juliet kilo mike" - ("\C-v" "jje" "y" "$" "p") - "alpha bravo charlie[b]rav -delta echo foxtrot echo -golf hotel india otel -juliet kilo mike" - ("G" "o" [escape] "p") - "alpha bravo charliebrav -delta echo foxtrot echo -golf hotel india otel -juliet kilo mike -[b]rav -echo -otel"))) - -(ert-deftest evil-test-visual-restore () - "Test restoring a previous selection" - :tags '(evil visual) - (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 -<alpha bravo\ncharlie delta\n>golf hotel")) - ;; 4 repetitions appears necessary, from manual testing - (ert-info ("Restore previous linewise selection from linewise selection") - (evil-test-buffer - "alpha bravo\nch[a]rlie delta\necho foxtrot\ngolf hotel" - ("V" [escape] "jV") - "alpha bravo\ncharlie delta\n<ec[h]o foxtrot\n>golf hotel" - ("gv") - "alpha bravo\n<ch[a]rlie delta\n>echo foxtrot\ngolf hotel" - ("gv") - "alpha bravo\ncharlie delta\n<ec[h]o foxtrot\n>golf hotel" - ("gv") - "alpha bravo\n<ch[a]rlie delta\n>echo foxtrot\ngolf hotel" - ("gv") - "alpha bravo\ncharlie delta\n<ec[h]o foxtrot\n>golf hotel")) - (ert-info ("Restore between previous charwise selection and linewise selection") - (evil-test-buffer - "alpha bravo\nch[a]rlie delta\necho foxtrot\ngolf hotel" - ("viw" [escape] "jV") - "alpha bravo\ncharlie delta\n<echo f[o]xtrot\n>golf hotel" - ("gv") - "alpha bravo\n<charli[e]> delta\necho foxtrot\ngolf hotel" - ("gv") - "alpha bravo\ncharlie delta\n<echo f[o]xtrot\n>golf hotel" - ("gv") - "alpha bravo\n<charli[e]> delta\necho foxtrot\ngolf hotel" - ("gv") - "alpha bravo\ncharlie delta\n<echo f[o]xtrot\n>golf hotel"))) - -(ert-deftest evil-test-visual-redefine () - "Test redefining a previous selection" - :tags '(evil visual) - (ert-info ("Redefine characterwise selection") - (evil-test-buffer - ";; <[T]his> buffer is for notes." - ([escape] "gv") - ";; <[T]his> buffer is for notes." - ([escape] "2lm<2wm>gv") - ";; Th<is buffer [i]>s for notes.")) - (ert-info ("Redefine linewise selection") - (evil-test-buffer - :visual line - "<[a]lpha bravo ->charlie delta -echo foxtrot -golf hotel" - ([escape] "gv") - "<[a]lpha bravo ->charlie delta -echo foxtrot -golf hotel" - ([escape] "2jm>gv") - "<alpha bravo -charlie delta -[e]cho foxtrot ->golf hotel" - ([escape] "km<gv") - "alpha bravo -<charlie delta -[e]cho foxtrot ->golf hotel")) - (ert-info ("Redefine blockwise selection") - (evil-test-buffer - :visual block - "<alpha bravo -charli[e]> delta -echo foxtrot -golf hotel" - ([escape] "gv") - "<alpha bravo -charli[e]> delta -echo foxtrot -golf hotel" - ([escape] "2jm>gv") - "<alpha bravo -charlie delta -echo foxtrot -golf h[o]>tel" - ([escape] "k0m<gv") - "alpha bravo -charlie delta -<echo foxtrot -golf h[o]>tel"))) - -(ert-deftest evil-test-visual-separate-from-operator-marks () - "Test that visual selection is kept separate from the '[ and '] marks (#1744)." - (evil-test-buffer "x\ny" - ("ylvpjxgv") - "[x]\n")) - -;;; 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)) - (ert-info ("Replace character twice and restore") - (evil-test-buffer "[a]" - ("Rb" [left] "c" [backspace]) - "b")) - (ert-info ("Can give Replace-state a count repeat it") - (evil-test-buffer - "a[l]pha bravo" - ("3Rx" [escape]) - "axx[x]a bravo" - ("wi\C-a") - "axxxa x[]bravo")) - (ert-info ("Replace deletion keeps consistent . register") - (evil-test-buffer - "a[l]pha bravo" - ("Rfop" [backspace] "o" [escape]) - "afo[o]a bravo" - ("A \C-@") - "afooa bravo fo[o]")) - (ert-info ("Replace-state sets ^ mark") - (evil-test-buffer - "a[l]pha bravo" - ("Rxx" [escape] "$") - "axxha brav[o]" - ("`^") - "axx[h]a bravo"))) - -;;; Ex - -(ert-deftest evil-test-ex-parse () - "Test `evil-ex-parse'" - :tags '(evil ex) - (should (equal (evil-ex-parse "5cmd arg") - '(evil-ex-call-command (string-to-number "5") "cmd" "arg"))) - (should (equal (evil-ex-parse "5cmd !arg") - '(evil-ex-call-command (string-to-number "5") "cmd" "!arg"))) - (should (equal (evil-ex-parse "5 arg") - '(evil-ex-call-command (string-to-number "5") "arg" nil))) - (should (equal (evil-ex-parse "+1,+2t-1") - '(evil-ex-call-command - (let ((l1 (evil-ex-line - nil - (+ (evil-ex-signed-number - (intern "+") - (string-to-number "1")))))) - (save-excursion - (and l1 (string= "," ";") (goto-line l1)) - (evil-ex-range - l1 (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) - (cl-flet - ((mk-range - (a b &optional relative) - `(let ((l1 ,(when a `(evil-ex-line ,@a)))) - (save-excursion - (and l1 (string= ,(if relative ";" ",") ";") (goto-line l1)) - (evil-ex-range l1 ,(when b `(evil-ex-line ,@b))))))) - (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) - (mk-range '((string-to-number "5") nil) - '((string-to-number "27") nil)))) - (should (equal (evil-ex-parse "5,$" nil 'range) - (mk-range '((string-to-number "5") nil) - '((evil-ex-last-line) nil)))) - (should (equal (evil-ex-parse "5,'x" nil 'range) - (mk-range '((string-to-number "5") nil) - '((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) - (mk-range '((string-to-number "5") nil) - '(nil (+ (evil-ex-signed-number (intern "+") nil)))))) - (should (equal (evil-ex-parse "5,-" nil 'range) - (mk-range '((string-to-number "5") nil) - '(nil (+ (evil-ex-signed-number (intern "-") nil)))))) - (should (equal (evil-ex-parse "5,4+2-7-3+10-" nil 'range) - (mk-range - '((string-to-number "5") nil) - '((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) - (mk-range - '((evil-ex-current-line) - (+ (evil-ex-signed-number - (intern "-") (string-to-number "2")))) - '((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) - (mk-range - '((evil-ex-marker "a") - (+ (evil-ex-signed-number - (intern "-") (string-to-number "2")))) - '((evil-ex-last-line) - (+ (evil-ex-signed-number - (intern "-") (string-to-number "10"))))))) - (should (equal (evil-ex-parse "'[,']" nil 'range) - (mk-range '((evil-ex-marker "[") nil) - '((evil-ex-marker "]") nil)))) - (should (equal (evil-ex-parse "'{,'}" nil 'range) - (mk-range '((evil-ex-marker "{") nil) - '((evil-ex-marker "}") nil)))) - (should (equal (evil-ex-parse "'(,')" nil 'range) - (mk-range '((evil-ex-marker "(") nil) - '((evil-ex-marker ")") nil)))) - (should (equal (evil-ex-parse ",']" nil 'range) - (mk-range nil '((evil-ex-marker "]") nil)))) - (should (equal (evil-ex-parse ";']" nil 'range) - (mk-range nil '((evil-ex-marker "]") nil) t))) - (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"))))))))) - -(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" [return]) - "abc\n[d]ef4\n\nghi") - (evil-test-buffer - "abc\n[d]ef\n\nghi" - (":s/f\\w*/4" [return]) - "abc\n[d]e4\n\nghi")) - (ert-info ("Substitute doesn't move point if 0 matches") - (evil-test-buffer - "abc\nd[e]f\nghi" - (":%s/nothere/foo" [return]) - "abc\nd[e]f\nghi")) - (ert-info ("Substitute up to EOB works") - (evil-test-buffer "[f]oo" - (":s/foo") - "")) - (ert-info ("Substitute with multi-line replacement") - (evil-test-buffer "x" - (":s/./foo\\nbar") - "foo\n[b]ar")) - (ert-info ("Use replace count in substitution") - (evil-test-buffer "xx" - (":s/./\\#/g") - "01")) - (ert-info ("Substitute with `calc' Lisp expression") - (evil-test-buffer "1 + 2" - (":s/.*/\\,(calc-eval \\0)") - "3"))) - -(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-info ("Substitute with last search, maintaining case sensitivty") - (evil-select-search-module 'evil-search-module 'evil-search) - (evil-test-buffer - "[a]lpha\nbravo\nbravo\ncharlie\nBravo\ndelta" - ("/\\Cbravo" [return]) - "alpha\n[b]ravo\nbravo\ncharlie\nBravo\ndelta" - (":%s//zulu" [return]) - "alpha\nzulu\n[z]ulu\ncharlie\nBravo\ndelta")) - (ert-info ("Repeat magic multiple times") - (let ((evil-magic 'very-magic) - (evil-ex-search-vim-style-regexp t)) - (evil-test-buffer - "[b]ravo, alpha\ndelta, charlie\nfoxtrot, echo\nhotel, golf" - (":s/(.*), (.*)/\\2 \\1" [return]) - "alpha bravo\ndelta, charlie\nfoxtrot, echo\nhotel, golf" - ("j&") - "alpha bravo\ncharlie delta\nfoxtrot, echo\nhotel, golf" - ("j&") - "alpha bravo\ncharlie delta\necho foxtrot\nhotel, golf" - ("j&") - "alpha bravo\ncharlie delta\necho foxtrot\ngolf hotel")))) - -(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 search for start/end of symbol") - (let ((evil-magic 'very-magic)) - (evil-test-buffer - "[a]lpha bravo bra charlie" - ("/bra\\_>" [return]) - "alpha bravo [b]ra charlie"))) - (ert-info ("Can search for literal < and >") - (let ((evil-magic 'very-magic)) - (evil-test-buffer - :visual-start "«" - :visual-end "»" - "[a]lpha bravo <bravo> charlie" - ("/<bravo>" [return]) - "alpha bravo [<]bravo> charlie"))) - (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-info ("Can use C-w yank-word functionality") - (let ((old-val evil-want-C-w-delete)) - (custom-set-variables '(evil-want-C-w-delete nil)) - (evil-test-buffer - "alpha [b]ravo charlie delta bravo echo" - ("/\C-w" [return]) - "alpha bravo charlie delta [b]ravo echo") - (custom-set-variables `(evil-want-C-w-delete ,old-val)))) - (ert-info ("Can use backreferences with vim-style regexp") - (let ((evil-ex-search-vim-style-regexp t)) - (evil-test-buffer - "[a]bacababcacabccadefghij" - ;; Very magic - ("/\\v(.)(.)(.)\\3\\1/e" [return]) - "abacababcacabcc[a]defghij") - (evil-test-buffer - "[a]bacababcacabccadefghij" - ;; Default magic - ("/\\(.\\)\\(.\\)\\(.\\)\\3\\1/e" [return]) - "abacababcacabcc[a]defghij") - (evil-test-buffer - "[a]bacababcac1abcca1defghij" - ;; With literal numbers - ("/\\(.\\)\\(.\\)\\(.\\)\\3\\11/e" [return]) - "abacababcac1abcca[1]defghij"))))) - -(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 '("\\<some\\>")))) - ("*") - "[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 '("\\<some\\>"))))) - (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" "\\<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 () - "Test that Ex forward search, as a motion, can be repeated." - :tags '(evil ex search) - (evil-without-display - (evil-select-search-module 'evil-search-module 'evil-search) - (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 <charli[e]> delta charlie alpha charlie bravo" - ([escape] "b") - "bravo [c]harlie delta charlie alpha charlie bravo" - ("gn") - "bravo <charli[e]> delta charlie alpha charlie bravo" - ([escape] "w") - "bravo charlie [d]elta charlie alpha charlie bravo" - ("gn") - "bravo charlie delta <charli[e]> alpha charlie bravo" - ([escape] "^") - "[b]ravo charlie delta charlie alpha charlie bravo" - ("3gn") - "bravo charlie delta charlie alpha <charli[e]> 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 <charli[e]> delta charlie alpha charlie bravo" - ("gn") - "bravo <charlie delta charli[e]> alpha charlie bravo" - ("o") - "bravo <[c]harlie delta charlie> alpha charlie bravo" - ("gn") - "bravo charli<[e] delta charlie> alpha charlie bravo" - ([escape] "^v2gn") - "<bravo charlie delta charli[e]> 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 <charlie alpha charli[e]> bravo" - ("gN") - "bravo charlie delta <charlie alpha [c]>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 - (":e " name [return]) - "[3]\n2\n1\n" - (":read !echo %" [return] ":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"))) - -(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-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 delete, specifying case sensitivty") - (evil-test-buffer - "[a]lpha bravo charlie\nalpha Bravo charlie\nalpha BRAVO charlie\nalpha delta charlie" - (":g/\\CBravo/d" [return]) - "alpha bravo charlie\n[a]lpha BRAVO charlie\nalpha delta charlie" - (":g/\\cBravo/d" [return]) - "alpha delta charlie")) - (ert-info ("global delete with arg") - (evil-test-buffer - "[n]o 1\nno 2\nno 3\nyes 4\nno 5\nno 6\nno 7\n" - (":g/yes/d2" [return]) - "no 1\nno 2\nno 3\n[n]o 6\nno 7\n")) - (ert-info ("global delete with range") - (evil-test-buffer - "alpha\nbravo\ncharlie\ndelta\ncharlie\necho\ngolf\ncharlie\nhotel" - (":g/charlie/-1d") - "alpha\ncharlie\ncharlie\necho\ncharlie\nhotel")) - (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")) - (ert-info ("pattern sort") - (evil-test-buffer - "[t]e|z|t\nzz|a|y\n" - (":sort /|[a-z]|/ r") - ("zz|a|y\nte|z|t\n")) - (evil-test-buffer - "[a],b\nb,a\n" - (":sort /[^,]*,/") - "b,a\na,b\n") - (evil-test-buffer - "[a],b\nb,a\n" - ("/," [return] ":sort //") - "b,a\na,b\n")) - (ert-info ("numeric sort") - (ert-info ("decimal") - (evil-test-buffer - "27\n027\n2\na\n1\n" - (":sort n") - "a\n1\n2\n27\n027\n")) - (ert-info ("octal") - (evil-test-buffer - "9\n8\n" - (":sort o") - "9\n8\n") - (evil-test-buffer - "777\n776\n7239\n" - (":sort o") - "7239\n776\n777\n")) - (ert-info ("hexadecimal") - (evil-test-buffer - "0xae\n0xb\nae\nad\n" - (":sort x") - "0xb\nad\n0xae\nae\n")))) - -;;; Command line window - -(ert-deftest evil-test-command-window-ex () - "Test command line window for Ex commands." - (let ((evil-ex-history (list "s/foo/baz" "s/foo/bar"))) - (evil-test-buffer "[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" [return]) - "[b]ar baz qux" - (should (equal (car evil-ex-history) "s/foo/qux"))))) - -(ert-deftest evil-test-command-window-noop () - "Test that executing a blank command does nothing." - (evil-test-buffer "[f]oo foo foo" - ("q:") - "[]\n" - ([return]) - "[f]oo foo foo")) - -(ert-deftest evil-test-command-window-search-history () - "Test command window with forward and backward search history." - (let ((evil-search-module 'isearch) - (evil-search-forward-history (list "four" "three" "qux")) - (evil-search-backward-history (list "baz" "bar"))) - (evil-test-buffer "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" - (error 'user-error "q/iNOT THERE" [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." - (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"))) - -;;; Window motions - -(ert-deftest evil-test-window-next-and-prev-respect-window-parameters () - "Test that `evil-window-next' and `evil-window-prev' respect window parameters. -E.g. they do not move to windows that have the `no-other-window' -parameter set." - (save-window-excursion - ;; Make sure there is a single original window and open a second - ;; other window with `no-other-window' set. - (delete-other-windows) - (let* ((this-window (selected-window)) - (other-window (split-window))) - (set-window-parameter other-window 'no-other-window t) - ;; `evil-window-next'/`evil-window-prev' should not switch to - ;; the window with `no-other-window' parameter set. - (evil-window-next nil) - (should (eq (selected-window) this-window)) - (evil-window-prev nil) - (should (eq (selected-window) this-window))))) - -;;; Utilities - -(ert-deftest evil-test-parser () - "Test `evil-parser'" - (with-temp-buffer - (cl-flet - ((parse - (s &rest args) - (erase-buffer) - (insert s) - (goto-char (point-min)) - (apply - (evil-parser - '((number "[0-9]+" #'string-to-number) - (plus "\\+" #'intern) - (minus "-" #'intern) - (operator - plus - minus) - (sign (\? operator)) - (signed-number (sign number)) - (expr - ("foo" (& "bar")) - ("xxx" (! "yyy")) - (number operator number)) - (epsilon nil)) - expr operator plus signed-number number epsilon) - args))) - (ert-info ("Nothing") - (should (equal (parse "1+2" 'epsilon) '(nil)))) - (ert-info ("Symbols") - (should (equal (parse "+" 'plus) '((intern "+")))) - (should (equal (parse "+" 'operator) '((intern "+"))))) - (ert-info ("Leading whitespace") - (should (equal (parse " 1" 'number) '((string-to-number "1"))))) - (ert-info ("Syntax tree") - (should (equal (parse "1" 'signed-number t) - '((signed-number (sign . 1) (number . 2)))))) - (ert-info ("Lookahead") - (should (equal (parse "foobar" 'expr) '((list "foo")))) - (should (null (parse "foobaz" 'expr))) - (should (null (parse "xxxyyy" 'expr))) - (should (equal (parse "xxxzzz" 'expr) '((list "xxx"))))) - (ert-info ("Semantic actions") - (should (equal (parse "1+1" 'expr) - '((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) - (defvar evil--alist) - (let (evil--alist) - (ert-info ("Set properties") - (evil-put-property 'evil--alist 'wibble :foo t) - (should (equal evil--alist '((wibble . (:foo t))))) - (evil-put-property 'evil--alist 'wibble :bar nil) - (should (equal evil--alist '((wibble . (:foo t :bar nil))))) - (evil-put-property 'evil--alist 'wobble :foo nil :bar nil :baz t) - (should (equal evil--alist '((wobble . (:foo nil :bar nil :baz t)) - (wibble . (:foo t :bar nil)))))) - (ert-info ("Get properties") - (should (evil-get-property evil--alist 'wibble :foo)) - (should-not (evil-get-property evil--alist 'wibble :bar)) - (should-not (evil-get-property evil--alist 'wobble :foo)) - (should-not (evil-get-property evil--alist 'wibble :baz)) - (should (equal (evil-get-property evil--alist t :foo) - '((wibble . t) (wobble . nil)))) - (should (equal (evil-get-property evil--alist t :bar) - '((wibble . nil) (wobble . nil)))) - (should (equal (evil-get-property evil--alist t :baz) - '((wobble . t))))))) - -(ert-deftest evil-test-filter-list () - "Test `evil-filter-list'" - :tags '(evil util) - (ert-info ("Return filtered list") - (should (null (evil-filter-list #'null '(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'." - :tags '(evil util) - (ert-info ("Two elements") - (let ((a 2) (b 1)) - (evil-sort a b) - (should (= a 1)) - (should (= b 2)))) - (ert-info ("Three elements") - (let ((a 3) (b 1) (c 2)) - (evil-sort a b c) - (should (= a 1)) - (should (= b 2)) - (should (= c 3)))) - (ert-info ("Four elements") - (let ((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 transferred for key sequences with meta-key" - :tags '(evil esc) - (unless noninteractive - (ert-info ("Test M-<right>") - (evil-test-buffer - "[A]BC DEF GHI JKL MNO" - ("3" (kbd "ESC <right>")) - "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 - "<This region is a keeper>!\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 - <escape>" - :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) - (let ((buf (file-name-nondirectory temp-file))) - (when (get-buffer buf) - (with-current-buffer buf (set-buffer-modified-p nil)) - (kill-buffer buf)))))) - (ert-info ("Jump multiple times between files") - (let ((a (make-temp-file "evil-aa-" nil nil "evil-bb\n\nthis is a")) - (b (make-temp-file "evil-bb-" nil nil "evil-cc\n\nthis is b")) - (c (make-temp-file "evil-cc-" nil nil "this is c"))) - (unwind-protect - (evil-test-buffer - (find-file a) - ("gf" [return]) - "evil-cc\n\nthis is b" - ("gf" [return]) - "this is c" - ("\C-o" "\C-o") - "evil-bb\n\nthis is a" - ("\C-i" "\C-i") - "this is c") - (dolist (f (list a b c)) - (let ((buf (file-name-nondirectory f))) - (when (get-buffer buf) - (with-current-buffer buf (set-buffer-modified-p nil)) - (kill-buffer buf))) - (delete-file f))))))) - -(ert-deftest evil-test-find-file () - :tags '(evil jumps) - (when (memq system-type '(cygwin windows-nt ms-dos)) - (ert-skip "[INFO] GitHub Actions has different userprofile name.")) - (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))) - ("gf") - (should (equal file-name (buffer-file-name)))))) - (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))) - ("0f:lvt$gf") - (should (equal file-name (buffer-file-name)))))) - (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))) - (not (equal line-number (line-number-at-pos))))) - ("gF") - (should (and (equal file-name (buffer-file-name)) - (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))) - (not (equal line-number (line-number-at-pos))) - (not (equal column-number (current-column))))) - ("gF") - (should (and (equal file-name (buffer-file-name)) - (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#") - "#|<this is a test #|with rackety|# multiline - and nestable comments>|#") - (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-kbd-macro () - "Test recording and replaying of macros." - :tags '(evil kbd-macro) - (ert-info ("Execute macro an infinite number of times") - (evil-test-buffer "xxx" - (evil-set-register ?q "ryl") - (error 'end-of-line "\C-u@q") - "yyy"))) - -(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-undo-jump () - "Test that undo adds to the jump list." - :tags '(evil) - (let ((evil--jumps-buffer-targets "\\*\\(new\\|scratch\\|test\\)\\*")) - (ert-info ("Undo adds to the jump list") - (evil-test-buffer - "alpha [b]ravo charlie delta" - ("dw" "w") - "alpha charlie [d]elta" - ("u") - "alpha [b]ravo charlie delta" - ("``") - "alpha bravo charlie [d]elta")))) - -(ert-deftest evil-test-insert-state-undo () - "Test that undo isn't lost when done from insert state." - :tags '(evil) - (skip-unless (version<= "28" emacs-version)) - (let (evil-want-fine-undo) - (customize-set-variable 'evil-undo-system 'undo-redo) - (evil-test-buffer - "alpha [ ]delta" - (evil-define-key* 'insert 'local [f8] 'evil-undo) - ("icharlie" [f8] [escape]) - "alpha[ ] delta" - ("\C-r") - "alpha [c]harlie delta"))) - -(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)))) - -(ert-deftest evil-test-append-to-kbd-macro () - "Test if evil can append to a keyboard macro." - :tags '(evil append to kbd-macro) - (ert-info ("When kbd-macro ends in <escape>") - (evil-test-buffer - (evil-set-register ?a (vconcat "ainserted text" [escape])) - (evil-set-register ?A (vconcat "a appended text" [escape])) - ("@a") - "inserted text appended tex[t]"))) - -(ert-deftest evil-test-paren-jumping () - :tags '(evil paren) - (ert-info ("Test doing motions on parens that you aren't in") - (evil-test-buffer - "[m]ain(argc, argv) char **argv; {" - ("dib" [escape]) - "main([)] char **argv; {") - (evil-test-buffer - "[a]lpha (bravo) charlie " - ("yi(") - "alpha ([b]ravo) charlie " - ("$p") - "alpha (bravo) charlie brav[o]") - (evil-test-buffer - "[a]lpha (bravo (charlie))" - ("2di(") - "alpha (bravo ([)]") - (evil-test-buffer - :point-start "(" - :point-end ")" - "(a)lpha [bravo [charlie]] [bravo]" - ("3di[") - "alpha [bravo [charlie]] [(])") - (evil-test-buffer -"[#]include \"stdlib.h\" -main(argc, argv) char **argv; { - while (1) malloc(0); -}" - ("ci{ return 0;" [escape]) -"#include \"stdlib.h\" -main(argc, argv) char **argv; { - return 0[;] -}"))) - -;;; Core - -(ert-deftest evil-test-initial-state () - "Test `evil-initial-state'" - :tags '(evil core) - ;; FIXME: These have a global effect, so better move them out and give them - ;; a proper namespace prefix. - (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)))) - ;; FIXME: Same as above. - (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)))) - -(ert-deftest evil-test-keep-input-method () - "Test that the input method is preserved when changing the major mode." - :tags '(evil core input-method) - (cl-flet ((use-german-input-method () (set-input-method "german-prefix"))) - (unwind-protect - (progn - (add-hook 'text-mode-hook #'use-german-input-method) - (evil-test-buffer - "[]" - (should (null evil-input-method)) - ("a\"a" [escape]) - "\"[a]" - (text-mode) - (should (equal evil-input-method "german-prefix")) - ("a\"a" [escape]) - "\"a[ä]" - (emacs-lisp-mode) - (should (equal evil-input-method "german-prefix")))) - (remove-hook 'text-mode-hook #'use-german-input-method)))) - -(ert-deftest evil-retab () - "Test the :retab command" - :tags '(evil) - (ert-info ("From tabs to spaces") - (evil-test-buffer - "def foo():\n\twhile True:\n\t\treturn\n" - (setq indent-tabs-mode nil) - (setq tab-width 4) - (":retab" [return]) - "def foo():\n while True:\n return\n")) - (ert-info ("From spaces to tabs") - (evil-test-buffer - "def foo():\n while True:\n return\n" - (setq indent-tabs-mode t) - (setq tab-width 4) - (":retab" [return]) - "def foo():\n\twhile True:\n\t\treturn\n")) - (ert-info ("Specify tab width as an argument") - (evil-test-buffer - "def foo():\n\twhile True:\n\t\treturn\n" - (setq indent-tabs-mode nil) - (setq tab-width 4) - (":retab 2" [return]) - "def foo():\n while True:\n return\n")) - (ert-info ("Invalid argument") - (evil-test-buffer - "def foo():\n\twhile True:\n\t\treturn\n" - (should-error (execute-kbd-macro ":retab foo" [return]))))) - -(ert-deftest evil-retab-visual () - "Test the :retab command on visual line selection. -This test fails in the batch mode (and therefore in the GitHub CI) -but it works fine in `M-x ert-run-tests-interactively'." - :tags '(evil visual) - (skip-unless (not noninteractive)) - (ert-info ("Retab only selected lines") - (evil-test-buffer - "def foo():\n\twhile True:\n\t\treturn\n" - (setq indent-tabs-mode nil) - (setq tab-width 4) - ("Vj" ":retab" [return]) - "def foo():\n while True:\n\t\treturn\n"))) - -(provide 'evil-tests) - -;;; evil-tests.el ends here diff --git a/.config/emacs/lisp/evil/evil-types.el b/.config/emacs/lisp/evil/evil-types.el deleted file mode 100644 index 360316a..0000000 --- a/.config/emacs/lisp/evil/evil-types.el +++ /dev/null @@ -1,465 +0,0 @@ -;;; evil-types.el --- Type system -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; A type defines a transformation on a pair of buffer positions. -;; Types are used by Visual state (character/line/block selection) -;; and Operator-Pending state (character/line/block motions). -;; -;; The basic transformation is "expansion". For example, the `line' -;; type "expands" a pair of positions to whole lines by moving the -;; first position to the beginning of the line and the last position -;; to the end of the line. That expanded selection is what the rest -;; of Emacs sees and acts on. -;; -;; An optional transformation is "contraction", which is the opposite -;; of expansion. If the transformation is one-to-one, expansion -;; followed by contraction always returns the original range. -;; (The `line' type is not one-to-one, as it may expand multiple -;; positions to the same lines.) -;; -;; Another optional transformation is "normalization", which takes -;; two unexpanded positions and adjusts them before expansion. -;; This is useful for cleaning up "invalid" positions. -;; -;; Types are defined at the end of this file using the macro -;; `evil-define-type'. - -(require 'evil-common) -(require 'evil-macros) - -;;; Code: - -;;; Type definitions - -(evil-define-type exclusive - "Return the positions unchanged, with some exceptions. -If the end position is at the beginning of a line, then: - -* If the beginning position is at or before the first non-blank - character on the line, return `line' (expanded). - -* Otherwise, move the end position to the end of the previous - line and return `inclusive' (expanded)." - :normalize (lambda (beg end) - (cond - ((progn - (goto-char end) - (and (/= beg end) (bolp))) - (setq end (max beg (1- end))) - (cond - ((progn - (goto-char beg) - (looking-back "^[ \f\t\v]*" (line-beginning-position))) - (evil-expand beg end 'line)) - (t - (unless evil-cross-lines - (setq end (max beg (1- end)))) - (evil-expand beg end 'inclusive)))) - (t - (evil-range beg end)))) - :string (lambda (beg end) - (let ((width (- end beg))) - (format "%s character%s" width - (if (= width 1) "" "s"))))) - -(evil-define-type inclusive - "Include the character under point. -Handling for `evil-want-visual-char-semi-exclusive' is deprecated, -and will be removed in a future version." - :expand (lambda (beg end) - (if (and (with-no-warnings evil-want-visual-char-semi-exclusive) - (evil-visual-state-p) - (< beg end) - (save-excursion - (goto-char end) - (or (bolp) (eolp)))) - (evil-range beg end 'exclusive) - (evil-range beg (1+ end)))) - :contract (lambda (beg end) - (evil-range beg (max beg (1- end)))) - :normalize (lambda (beg end) - (evil-range beg (if (eq (char-after end) ?\n) - (max beg (1- end)) end))) - :string (lambda (beg end) - (let ((width (- end beg))) - (format "%s character%s" width - (if (= width 1) "" "s"))))) - -(evil-define-type line - "Include whole lines." - :one-to-one nil - :expand (lambda (beg end) - (evil-range - (progn - (goto-char beg) - ;; move to beginning of line as displayed - (evil-move-beginning-of-line) - (point)) - (progn - (goto-char end) - ;; move to the end of line as displayed - (evil-move-end-of-line) - (line-beginning-position 2)))) - :contract (lambda (beg end) - (evil-range beg (max beg (1- end)))) - :string (lambda (beg end) - (let ((height (count-lines beg end))) - (format "%s line%s" height - (if (= height 1) "" "s"))))) - -(evil-define-type screen-line - "Include whole lines, being aware of `visual-line-mode' -when `evil-respect-visual-line-mode' is non-nil." - :one-to-one nil - :expand (lambda (beg end) - (if (not (and evil-respect-visual-line-mode visual-line-mode)) - (evil-line-expand beg end) - (evil-range - (progn - (goto-char beg) - (save-excursion - (beginning-of-visual-line))) - (progn - (goto-char end) - (save-excursion - ;; `beginning-of-visual-line' reverts to the beginning of the - ;; last visual line if the end of the last line is the end of - ;; the buffer. This would prevent selecting the last screen - ;; line. - (if (= (line-beginning-position 2) (point-max)) - (point-max) - (beginning-of-visual-line 2))))))) - :contract (lambda (beg end) - (evil-range beg (max beg (1- end)))) - :string (lambda (beg end) - (let ((height (count-screen-lines beg end))) - (format "%s screen line%s" height - (if (= height 1) "" "s"))))) - -(evil-define-type block - "Like `inclusive', but for rectangles: -the last column is included." - :expand (lambda (beg end &rest properties) - (let ((beg-col (evil-column beg)) - (end-col (evil-column end)) - (corner (plist-get properties :corner))) - ;; Since blocks are implemented as a pair of buffer - ;; positions, expansion is restricted to what the buffer - ;; allows. In the case of a one-column block, there are - ;; two ways to expand it (either move the upper corner - ;; beyond the lower corner, or the lower beyond the - ;; upper), so try out both possibilities when - ;; encountering the end of the line. - (cond - ((= beg-col end-col) - (goto-char end) - (cond - ((eolp) - (goto-char beg) - (if (eolp) - (evil-range beg end) - (evil-range (1+ beg) end))) - ((memq corner '(lower-right upper-right right)) - (evil-range (1+ beg) end)) - (t - (evil-range beg (1+ end))))) - ((< beg-col end-col) - (goto-char end) - (if (eolp) - (evil-range beg end) - (evil-range beg (1+ end)))) - (t - (goto-char beg) - (if (eolp) - (evil-range beg end) - (evil-range (1+ beg) end)))))) - :contract (lambda (beg end) - (let ((beg-col (evil-column beg)) - (end-col (evil-column end))) - (if (> beg-col end-col) - (evil-range (1- beg) end) - (evil-range beg (max beg (1- end)))))) - :string (lambda (beg end) - (let ((height (count-lines - beg - (progn - (goto-char end) - (if (and (bolp) (not (eobp))) - (1+ end) - end)))) - (width (abs (- (evil-column beg) - (evil-column end))))) - (format "%s row%s and %s column%s" - height - (if (= height 1) "" "s") - width - (if (= width 1) "" "s")))) - :rotate (lambda (beg end &rest properties) - "Rotate block according to :corner property. -:corner can be one of `upper-left',``upper-right', `lower-left' -and `lower-right'." - (let ((left (evil-column beg)) - (right (evil-column end)) - (corner (or (plist-get properties :corner) - 'upper-left))) - (evil-sort left right) - (goto-char beg) - (if (memq corner '(upper-right lower-left)) - (move-to-column right) - (move-to-column left)) - (setq beg (point)) - (goto-char end) - (if (memq corner '(upper-right lower-left)) - (move-to-column left) - (move-to-column right)) - (setq end (point)) - (setq properties (plist-put properties - :corner corner)) - (apply #'evil-range beg end properties)))) - -(evil-define-type rectangle - "Like `exclusive', but for rectangles: -the last column is excluded." - :expand (lambda (beg end) - ;; select at least one column - (if (= (evil-column beg) (evil-column end)) - (evil-expand beg end 'block) - (evil-range beg end 'block)))) - -;;; Standard interactive codes - -(evil-define-interactive-code "*" - "Signal error if the buffer is read-only." - (when buffer-read-only - (signal 'buffer-read-only nil))) - -(evil-define-interactive-code "b" (prompt) - "Name of existing buffer." - (list (read-buffer prompt (current-buffer) t))) - -(evil-define-interactive-code "c" - "Read character." - (list (read-char))) - -(evil-define-interactive-code "p" - "Prefix argument converted to number." - (list (prefix-numeric-value current-prefix-arg))) - -(evil-define-interactive-code "P" - "Prefix argument in raw form." - (list current-prefix-arg)) - -;;; Custom interactive codes - -(evil-define-interactive-code "<w>" - "Prefix argument converted to number, possibly multiplied by evil--window-digit." - (let ((prefix-num (prefix-numeric-value current-prefix-arg))) - (if evil--window-digit - (list (* evil--window-digit prefix-num)) - (list prefix-num)))) - -(evil-define-interactive-code "<c>" - "Count." - (list (when current-prefix-arg - (prefix-numeric-value current-prefix-arg)))) - -(evil-define-interactive-code "<vc>" - "Count, but only in visual state. -This should be used by an operator taking a count. In normal -state the count should not be handled by the operator but by the -motion that defines the operator's range. In visual state the -range is specified by the visual region and the count is not used -at all. Thus in the case the operator may use the count -directly." - (list (when (and (evil-visual-state-p) current-prefix-arg) - (prefix-numeric-value - current-prefix-arg)))) - -(evil-define-interactive-code "<wc>" - "Prefix argument converted to number, or nil possibly multiplied by -evil--window-digit." - (let ((prefix-num (prefix-numeric-value current-prefix-arg))) - (list - (cond (evil--window-digit (* evil--window-digit prefix-num)) - (current-prefix-arg prefix-num))))) - -(evil-define-interactive-code "<C>" - "Character read through `evil-read-key'." - (list - (if (evil-operator-state-p) - (evil-without-restriction (evil-read-key)) - (evil-read-key)))) - -(evil-define-interactive-code "<r>" - "Untyped motion range (BEG END)." - (evil-operator-range)) - -(evil-define-interactive-code "<R>" - "Typed motion range (BEG END TYPE)." - (evil-operator-range t)) - -(evil-define-interactive-code "<v>" - "Typed motion range of visual range (BEG END TYPE). -If visual state is inactive then those values are nil." - (if (evil-visual-state-p) - (let ((range (evil-visual-range))) - (list (car range) - (cadr range) - (evil-type range))) - (list nil nil nil))) - -(evil-define-interactive-code "<x>" - "Current register." - (list evil-this-register)) - -(evil-define-interactive-code "<y>" - "Current yank-handler." - (list (evil-yank-handler))) - -(evil-define-interactive-code "<a>" - "Ex argument." - :ex-arg t - (list (when evil-called-from-ex-p evil-ex-argument))) - -(evil-define-interactive-code "<N>" () - "Prefix argument or ex-arg, converted to number" - (list (cond - (current-prefix-arg (prefix-numeric-value current-prefix-arg)) - (evil-ex-argument (string-to-number evil-ex-argument)) - (evil-called-from-ex-p nil) - (t 1)))) - -(evil-define-interactive-code "<f>" - "Ex file argument." - :ex-arg file - (list (when evil-called-from-ex-p (evil-ex-file-arg)))) - -(evil-define-interactive-code "<b>" - "Ex buffer argument." - :ex-arg buffer - (list evil-ex-argument)) - -(evil-define-interactive-code "<sh>" - "Ex shell command argument." - :ex-arg shell - (list evil-ex-argument)) - -(evil-define-interactive-code "<fsh>" - "Ex file or shell command argument." - :ex-arg file-or-shell - (list evil-ex-argument)) - -(evil-define-interactive-code "<sym>" - "Ex symbolic argument." - :ex-arg sym - (list (and evil-ex-argument (intern evil-ex-argument)))) - -(evil-define-interactive-code "<addr>" - "Ex line number." - (list - (when evil-called-from-ex-p - (let ((expr (evil-ex-parse (or evil-ex-argument "")))) - (if (eq (car expr) 'evil-goto-line) - (save-excursion (goto-char evil-ex-point) - (eval (cadr expr) t)) - (user-error "Invalid address")))))) - -(evil-define-interactive-code "<!>" - "Ex bang argument." - :ex-bang t - (list evil-ex-bang)) - -(evil-define-interactive-code "</>" - "Ex delimited argument." - (when evil-called-from-ex-p - (evil-delimited-arguments (or evil-ex-argument "")))) - -(evil-define-interactive-code "<g/>" - "Ex global argument." - (when evil-called-from-ex-p - (evil-ex-parse-global (or evil-ex-argument "")))) - -(evil-define-interactive-code "<s/>" - "Ex substitution argument." - :ex-arg substitution - (when evil-called-from-ex-p - (evil-ex-get-substitute-info (or evil-ex-argument "") t))) - -(evil-define-interactive-code "<xc/>" - "Ex register and count argument, both optional. -Can be used for commands such as :delete [REGISTER] [COUNT] where the -command can be called with either zero, one or two arguments. With one -argument, if it is numeric, it is treated as a COUNT, otherwise, as a -REGISTER." - (when evil-called-from-ex-p - (evil-ex-get-optional-register-and-count evil-ex-argument))) - -(defun evil-ex-get-optional-register-and-count (string) - "Parse STRING as an ex arg with both optional REGISTER and COUNT. -Return a list (REGISTER COUNT)." - (let* ((split-args (split-string (or string ""))) - (arg-count (length split-args)) - (arg0 (car split-args)) - (arg1 (cadr split-args)) - (number-regex "^-?[1-9][0-9]*$") - (register nil) - (count nil)) - (cond - ;; :command REGISTER or :command COUNT - ((= arg-count 1) - (if (string-match-p number-regex arg0) - (setq count arg0) - (setq register arg0))) - ;; :command REGISTER COUNT - ((eq arg-count 2) - (setq register arg0 - count arg1)) - ;; more than 2 args aren't allowed - ((> arg-count 2) - (user-error "Invalid use"))) - - ;; if register is given, check it's valid - (when register - (unless (= (length register) 1) - (user-error "Invalid register")) - (setq register (string-to-char register))) - - ;; if count is given, check it's valid - (when count - (unless (string-match-p number-regex count) - (user-error "Invalid count")) - (setq count (string-to-number count)) - (unless (> count 0) - (user-error "Invalid count"))) - - (list register count))) - -(provide 'evil-types) - -;;; evil-types.el ends here diff --git a/.config/emacs/lisp/evil/evil-vars.el b/.config/emacs/lisp/evil/evil-vars.el deleted file mode 100644 index 291a91a..0000000 --- a/.config/emacs/lisp/evil/evil-vars.el +++ /dev/null @@ -1,2121 +0,0 @@ -;;; evil-vars.el --- Settings and variables -*- lexical-binding: t -*- - -;; Author: Vegard Øye <vegard_oye at hotmail.com> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; 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 <http://www.gnu.org/licenses/>. - -;;; Code: - -(declare-function evil-add-command-properties "evil-common" - (command &rest properties)) -(declare-function evil-update-insert-state-bindings "evil-maps" - (&optional _option-name remove force)) - -;;; Hooks - -(defvar evil-after-load-hook nil - "Functions to be run when loading of Evil is finished. -This hook can be used to execute some initialization routines -when Evil is completely loaded.") - -(defvar evil-after-global-hook nil - "Functions to be run after :global and :vglobal.") - -(defcustom evil-goto-definition-functions - '(evil-goto-definition-imenu - evil-goto-definition-semantic - evil-goto-definition-xref - evil-goto-definition-search) - "List of functions run until success by `evil-goto-definition'." - :type 'hook - :group 'evil) - -;;; Initialization - -(defvar evil-pending-custom-initialize nil - "A list of pending initializations for custom variables. -Each element is a triple (FUNC VAR VALUE). When Evil is -completely loaded then the functions (funcall FUNC VAR VALUE) is -called for each element. FUNC should be a function suitable for -the :initialize property of `defcustom'.") - -(defun evil-custom-initialize-pending-reset (var value) - "Add a pending customization with `custom-initialize-reset'." - (push (list 'custom-initialize-reset var value) - evil-pending-custom-initialize)) - -(defun evil-run-pending-custom-initialize () - "Execute the pending initializations. -See `evil-pending-custom-initialize'." - (dolist (init evil-pending-custom-initialize) - (apply (car init) (cdr init))) - (remove-hook 'evil-after-load-hook #'evil-run-pending-custom-initialize)) -(add-hook 'evil-after-load-hook #'evil-run-pending-custom-initialize) - -;;; Setters - -(defun evil-set-toggle-key (key) - "Set `evil-toggle-key' to KEY. -KEY must be readable by `read-kbd-macro'." - (let ((old-key (read-kbd-macro - (if (boundp 'evil-toggle-key) - evil-toggle-key - "C-z"))) - (key (read-kbd-macro key))) - (with-no-warnings - (dolist (pair '((evil-motion-state-map evil-emacs-state) - (evil-insert-state-map evil-emacs-state) - (evil-emacs-state-map evil-exit-emacs-state))) - (when (boundp (car pair)) - (let ((map (symbol-value (car pair))) - (fun (cadr pair))) - (when (keymapp map) - (define-key map key fun) - (define-key map old-key nil)))))))) - -(defun evil-set-custom-state-maps (var pending-var key _make newlist) - "Change the list of special keymaps. -VAR is the variable containing the list of keymaps. -PENDING-VAR is the variable containing the list of the currently pending - keymaps. -KEY the special symbol to be stored in the keymaps. -MAKE the creation function of the special keymaps. -NEWLIST the list of new special keymaps." - (set-default pending-var newlist) - (when (default-boundp var) - (dolist (map (default-value var)) - (when (and (boundp (car map)) - (keymapp (default-value (car map)))) - (define-key (default-value (car map)) (vector key) nil)))) - (set-default var newlist) - (evil-update-pending-maps)) - -(defun evil-update-pending-maps (&optional _file) - "Try to set pending special keymaps. -This function should be called from an `after-load-functions' -hook." - (let ((maps '((evil-make-overriding-map . evil-pending-overriding-maps) - (evil-make-intercept-map . evil-pending-intercept-maps)))) - (while maps - (let* ((map (pop maps)) - (make (car map)) - (pending-var (cdr map)) - (pending (symbol-value pending-var)) - newlist) - (while pending - (let* ((map (pop pending)) - (kmap (and (boundp (car map)) - (keymapp (symbol-value (car map))) - (symbol-value (car map)))) - (state (cdr map))) - (if kmap - (funcall make kmap state) - (push map newlist)))) - (set-default pending-var newlist))))) - -(defun evil-set-visual-newline-commands (var value) - "Set the value of `evil-visual-newline-commands'. -Setting this variable changes the properties of the appropriate -commands." - (with-no-warnings - (when (default-boundp var) - (dolist (cmd (default-value var)) - (evil-set-command-property cmd :exclude-newline nil))) - (set-default var value) - (dolist (cmd (default-value var)) - (evil-set-command-property cmd :exclude-newline t)))) - -(defun evil-set-custom-motions (var values) - "Set the list of motion commands." - (with-no-warnings - (when (default-boundp var) - (dolist (motion (default-value var)) - (evil-add-command-properties motion :keep-visual nil :repeat nil))) - (set-default var values) - (mapc #'evil-declare-motion (default-value var)))) - -;;; Customization group - -(defgroup evil nil - "Extensible vi layer." - :group 'emulations - :prefix 'evil-) - -(defcustom evil-auto-indent t - "\\<evil-normal-state-map> -Whether to auto-indent when opening lines with \\[evil-open-below] \ -and \\[evil-open-above]." - :type 'boolean - :group 'evil) - -(defcustom evil-shift-width 4 - "\\<evil-normal-state-map> -The number of columns by which a line is shifted. -This applies to the shifting operators \\[evil-shift-right] and \ -\\[evil-shift-left]." - :type 'integer - :safe #'integerp - :group 'evil) - -(defcustom evil-shift-round t - "\\<evil-normal-state-map> -Whether shifting rounds to the nearest multiple. -If non-nil, \\[evil-shift-right] and \\[evil-shift-left] adjust line -indentation to the nearest multiple of `evil-shift-width'." - :type 'boolean - :group 'evil) - -(defcustom evil-indent-convert-tabs t - "\\<evil-normal-state-map> -If non-nil, the \\[evil-indent] operator converts between leading tabs and spaces. -Whether tabs are converted to spaces or vice versa depends on the -value of `indent-tabs-mode'." - :type 'boolean - :group 'evil) - -(defcustom evil-default-cursor t - "The default cursor. -May be a cursor type as per `cursor-type', a color string as passed -to `set-cursor-color', a zero-argument function for changing the -cursor, or a list of the above. - -nil is interpreted as t; if you want the nil `cursor-type' (i.e., -you want to disable the cursor), set this variable to (list nil)." - :type '(set symbol (cons symbol symbol) string function) - :group 'evil) - -(defvar evil-force-cursor nil - "Overwrite the current states default cursor.") - -(defcustom evil-start-of-line nil - "Analogue of vim's `startofline'. -If nil, preserve column when making relevant movements of the cursor. -Otherwise, move the cursor to the start of the line." - :type 'boolean - :group 'evil) - -(defcustom evil-repeat-move-cursor t - "\\<evil-normal-state-map> -Whether repeating commands with \\[evil-repeat] may move the cursor. -If nil, the original cursor position is preserved, even if the command -normally would have moved the cursor." - :type 'boolean - :group 'evil) - -(defcustom evil-cross-lines nil - "\\<evil-motion-state-map> -Whether horizontal motions may move to other lines. If non-nil, -certain motions that conventionally operate in a single line may move -the cursor to other lines. Otherwise, they are restricted to the -current line. This applies to \\[evil-backward-char], \ -\\[evil-forward-char], \\[evil-find-char], \ -\\[evil-find-char-backward], \\[evil-find-char-to], \ -\\[evil-find-char-to-backward], \ -\\<evil-normal-state-map>\\[evil-invert-char]." - :type 'boolean - :group 'evil) - -(defcustom evil-backspace-join-lines t - "Whether backward delete in insert state may join lines." - :type 'boolean - :group 'evil) - -(defcustom evil-move-cursor-back t - "Whether the cursor is moved backwards when exiting insert state. -If non-nil, the cursor moves \"backwards\" when exiting insert state, -so that it ends up on the character to the left. Otherwise it remains -in place, on the character to the right. - -See also `evil-move-beyond-eol'." - :type 'boolean - :group 'evil) - -(defcustom evil-move-beyond-eol nil - "Whether the cursor can move past the end of the line. -If non-nil, the cursor is allowed to move one character past the -end of the line, as in Emacs." - :type 'boolean - :group 'evil) - -(defcustom evil-respect-visual-line-mode nil - "\\<evil-motion-state-map> -Whether movement commands respect `visual-line-mode'. -If non-nil, `visual-line-mode' is generally respected when it is -on. In this case, motions such as \\[evil-next-line] and -\\[evil-previous-line] navigate by visual lines (on the screen) rather -than \"physical\" lines (defined by newline characters). If nil, -the setting of `visual-line-mode' is ignored. - -This variable must be set before Evil is loaded." - :type 'boolean - :group 'evil) - -(defcustom evil-repeat-find-to-skip-next t - "Whether a repeat of t or T should skip an adjacent character." - :type 'boolean - :group 'evil) - -(defcustom evil-kbd-macro-suppress-motion-error nil - "\\<evil-motion-state-map> -Whether left/right motions signal errors in keyboard macros. -This variable only affects beginning-of-line or end-of-line errors -regarding the motions \\[evil-backward-char] and \\[evil-forward-char] -respectively. This may be desired since such errors cause macro -definition or execution to be terminated. There are four -possibilities: - -- `record': errors are suppressed when recording macros, but not when - replaying them. -- `replay': errors are suppressed when replaying macros, but not when - recording them. -- `t': errors are suppressed in both cases. -- `nil': errors are never suppressed." - :type '(radio (const :tag "No" :value nil) - (const :tag "Record" :value record) - (const :tag "Replay" :value replay) - (const :tag "Both" :value t)) - :group 'evil) - -(defcustom evil-track-eol t - "\\<evil-motion-state-map> -Whether \\[evil-end-of-line] \"sticks\" the cursor to the end of the line. -If non-nil, vertical motions after \\[evil-end-of-line] maintain the cursor at the -end of the line, even if the target line is longer. This is analogous -to `track-eol', but respects Evil's interpretation of end-of-line." - :type 'boolean - :group 'evil) - -(defcustom evil-mode-line-format 'before - "The position of the state tag in the mode line. -If set to `before' or `after', the tag is placed at the beginning -or the end of the mode-line, respectively. If nil, there is no -tag. Otherwise it should be a cons cell (WHERE . WHICH), where -WHERE is either `before' or `after', and WHICH is a symbol in -`mode-line-format'. The tag is then placed before or after that -symbol, respectively." - :type '(radio :value 'before - (const :tag "No tag" nil) - (const before) - (const after) - (cons :tag "Next to symbol" - (choice :value after - (const before) - (const after)) - symbol)) - :group 'evil) - -(defcustom evil-mouse-word 'evil-word - "The thing-at-point symbol for double click selection. -The double-click starts visual state in a special word selection -mode. This symbol is used to determine the words to be -selected. Possible values are `evil-word' or `evil-WORD'." - :type 'symbol - :group 'evil) - -(defcustom evil-bigword "^ \t\r\n" - "The set of characters to be interpreted as WORD boundaries. -This is enclosed with square brackets and used as a regular -expression. By default, whitespace characters are considered -WORD boundaries." - :type 'string - :group 'evil) - -(defcustom evil-want-fine-undo nil - "Whether actions are undone in several steps. -There are two possible choices: nil (\"no\") means that all -changes made during insert state, including a possible delete -after a change operation, are collected in a single undo step. -Non-nil (\"yes\") means that undo steps are determined according -to Emacs heuristics, and no attempt is made to aggregate changes. - -For backward compatibility purposes, the value `fine' is -interpreted as `nil'. This option was removed because it did not -work consistently." - :type '(radio (const :tag "No" :value nil) - (const :tag "Fine (obsolete)" :value fine) - (const :tag "Yes" :value t)) - :group 'evil) - -(defcustom evil-regexp-search t - "\\<evil-motion-state-map> -Whether to use regular expressions for searching in \ -\\[evil-search-forward] and \\[evil-search-backward]." - :type 'boolean - :group 'evil) - -(defcustom evil-search-wrap t - "\\<evil-motion-state-map> -Whether search with \\[evil-search-forward] and \ -\\[evil-search-backward] wraps around the buffer. -If this is non-nil, search stops at the buffer boundaries." - :type 'boolean - :group 'evil) - -(defcustom evil-flash-delay 2 - "\\<evil-motion-state-map> -Time in seconds to flash search matches after \\[evil-search-next] and \ -\\[evil-search-previous]." - :type 'number - :group 'evil) - -(defcustom evil-auto-balance-windows t - "If non-nil window creation and deletion trigger rebalancing." - :type 'boolean - :group 'evil) - -(defcustom evil-split-window-below nil - "If non-nil split windows are created below." - :type 'boolean - :group 'evil) - -(defcustom evil-vsplit-window-right nil - "If non-nil vertically split windows with are created to the right." - :type 'boolean - :group 'evil) - -(defcustom evil-esc-delay 0.01 - "The time, in seconds, to wait for another key after escape. -If no further event arrives during this time, the event is -translated to `ESC'. Otherwise, it is translated according to -`input-decode-map'. This does not apply in Emacs state, and may -also be inhibited by setting `evil-inhibit-esc'." - :type 'number - :group 'evil) - -(defvar evil-esc-mode nil - "Non-nil if `evil-esc-mode' is enabled.") - -(defvar evil-esc-map nil - "Original ESC prefix map in `input-decode-map'. -Used by `evil-esc-mode'.") - -(defvar evil-inhibit-esc nil - "If non-nil, the \"\\e\" event will never be translated to `escape'.") - -(defcustom evil-intercept-esc 'always - "Whether Evil should intercept the escape key. -In the terminal, escape and a meta key sequence both generate the -same event. In order to distingush these, Evil uses -`input-decode-map'. It is not necessary to do this in a graphical -Emacs session. However, if you prefer to use \"C-[\" as escape (which -is identical to the terminal escape key code), this interception must -also happen in graphical Emacs sessions. Set this variable to -`always', t (only in the terminal) or nil (never intercept)." - :type '(radio (const :tag "Never" :value nil) - (const :tag "In terminal only" :value t) - (const :tag "Always" :value always)) - :group 'evil) - -(defcustom evil-show-paren-range 0 - "The maximum distance between point and a parenthesis -which causes the parenthesis to be highlighted." - :type 'integer - :group 'evil) - -(defcustom evil-ex-hl-update-delay 0.02 - "Time in seconds of idle before updating search highlighting. -Setting this to a period shorter than that of keyboard's repeat -rate allows highlights to update while scrolling." - :type 'number - :group 'evil) - -(defcustom evil-highlight-closing-paren-at-point-states - '(not emacs insert replace) - "The states in which the closing parenthesis at point should be highlighted. -All states listed here highlight the closing parenthesis at -point (which is Vim's default behavior). All others highlight the -parenthesis before point (which is Emacs default behavior). If -this list contains the symbol `not' then its meaning is inverted, -i.e. all states listed here highlight the closing parenthesis -before point." - :type '(repeat symbol) - :group 'evil) - -(defcustom evil-kill-on-visual-paste t - "Whether pasting in visual state adds the replaced text to the -kill ring, making it the default for the next paste. The default -replicates the default Vim behavior for `p'. This value is flipped by -`evil-paste-before' (\\[evil-paste-before])." - :type 'boolean - :group 'evil) - -(defcustom evil-want-C-i-jump t - "Whether `C-i' jumps forward in the jump list (like Vim). -Otherwise, `C-i' inserts a tab character." - :type 'boolean - :group 'evil - :set #'(lambda (sym value) - (set-default sym value) - (when (boundp 'evil-motion-state-map) - (cond - ((and (not value) - (eq (lookup-key evil-motion-state-map (kbd "C-i")) - 'evil-jump-forward)) - (define-key evil-motion-state-map (kbd "C-i") nil)) - ((and value - (not (lookup-key evil-motion-state-map (kbd "C-i")))) - (define-key evil-motion-state-map (kbd "C-i") - 'evil-jump-forward)))))) - -(defcustom evil-want-C-u-scroll nil - "Whether `C-u' scrolls up (like Vim). -Otherwise, `C-u' applies a prefix argument. The binding of -`C-u' mirrors Emacs behaviour by default due to the relative -ubiquity of prefix arguments." - :type 'boolean - :group 'evil - :set #'(lambda (sym value) - (set-default sym value) - (when (boundp 'evil-motion-state-map) - (cond - ((and (not value) - (eq (lookup-key evil-motion-state-map (kbd "C-u")) - 'evil-scroll-up)) - (define-key evil-motion-state-map (kbd "C-u") nil)) - ((and value - (not (lookup-key evil-motion-state-map (kbd "C-u")))) - (define-key evil-motion-state-map (kbd "C-u") - 'evil-scroll-up)))))) - -(defcustom evil-want-C-d-scroll t - "Whether `C-d' scrolls down (like Vim)." - :type 'boolean - :group 'evil - :set #'(lambda (sym value) - (set-default sym value) - (when (boundp 'evil-motion-state-map) - (cond - ((and (not value) - (eq (lookup-key evil-motion-state-map (kbd "C-d")) - 'evil-scroll-down)) - (define-key evil-motion-state-map (kbd "C-d") nil)) - ((and value - (not (lookup-key evil-motion-state-map (kbd "C-d")))) - (define-key evil-motion-state-map (kbd "C-d") - 'evil-scroll-down)))))) - -(defcustom evil-want-C-u-delete nil - "Whether `C-u' deletes back to indentation in insert state. -Otherwise, `C-u' applies a prefix argument. The binding of -`C-u' mirrors Emacs behaviour by default due to the relative -ubiquity of prefix arguments." - :type 'boolean - :group 'evil - :set #'(lambda (sym value) - (set-default sym value) - (when (and (boundp 'evil-insert-state-map) - (boundp 'evil-replace-state-map)) - (cond - ((and (not value) - (eq (lookup-key evil-insert-state-map (kbd "C-u")) - 'evil-delete-back-to-indentation)) - (define-key evil-insert-state-map (kbd "C-u") nil) - (define-key evil-replace-state-map (kbd "C-u") nil)) - ((and value - (not (lookup-key evil-insert-state-map (kbd "C-u")))) - (define-key evil-insert-state-map (kbd "C-u") - 'evil-delete-back-to-indentation) - (define-key evil-replace-state-map (kbd "C-u") - 'evil-delete-back-to-indentation)))))) - -(defcustom evil-want-C-w-delete t - "Whether `C-w' deletes a word in Insert/Ex/Search state." - :type 'boolean - :group 'evil - :set (lambda (sym value) - (set-default sym value) - (when (and (boundp 'evil-insert-state-map) - (boundp 'evil-replace-state-map)) - (cond - ((and (not value) - (eq (lookup-key evil-insert-state-map (kbd "C-w")) - 'evil-delete-backward-word)) - (define-key evil-insert-state-map (kbd "C-w") 'evil-window-map) - (define-key evil-replace-state-map (kbd "C-w") 'evil-window-map)) - ((and value - (eq (lookup-key evil-insert-state-map (kbd "C-w")) - 'evil-window-map)) - (define-key evil-insert-state-map (kbd "C-w") 'evil-delete-backward-word) - (define-key evil-replace-state-map (kbd "C-w") 'evil-delete-backward-word)))) - (when (boundp 'evil-command-line-map) - (cond - ((and (not value) - (eq (lookup-key evil-command-line-map (kbd "C-w")) - 'evil-delete-backward-word)) - (define-key evil-command-line-map (kbd "C-w") nil)) - ((and value - (null (lookup-key evil-command-line-map (kbd "C-w")))) - (define-key evil-command-line-map (kbd "C-w") 'evil-delete-backward-word)))) - (when (boundp 'evil-ex-search-keymap) - (cond - ((and (not value) - (null (lookup-key evil-ex-search-keymap (kbd "C-w")))) - (define-key evil-ex-search-keymap (kbd "C-w") 'evil-search-yank-word)) - ((and value - (eq (lookup-key evil-ex-search-keymap (kbd "C-w")) - 'evil-search-yank-word)) - (define-key evil-ex-search-keymap (kbd "C-w") nil)))))) - -(defcustom evil-want-C-h-delete nil - "Whether `C-h' deletes a char in Insert state." - :type 'boolean - :group 'evil - :set #'(lambda (sym value) - (set-default sym value) - (when (and (boundp 'evil-insert-state-map) - (boundp 'evil-replace-state-map)) - (cond - ((and (not value) - (eq (lookup-key evil-insert-state-map (kbd "C-h")) - 'evil-delete-backward-char-and-join)) - (define-key evil-insert-state-map (kbd "C-h") nil) - (define-key evil-replace-state-map (kbd "C-h") nil)) - ((and value - (not (lookup-key evil-insert-state-map (kbd "C-h")))) - (define-key evil-insert-state-map (kbd "C-h") - 'evil-delete-backward-char-and-join) - (define-key evil-replace-state-map (kbd "C-h") - 'evil-replace-backspace)))))) - -(defcustom evil-want-C-g-bindings nil - "Whether `C-g' postfix can be used in bindings." - :type 'boolean - :group 'evil) - -(defcustom evil-want-C-w-in-emacs-state nil - "Whether `C-w' prefixes windows commands in Emacs state." - :type 'boolean - :group 'evil - :set #'(lambda (sym value) - (set-default sym value) - (when (boundp 'evil-emacs-state-map) - (cond - ((and (not value) - (eq (lookup-key evil-emacs-state-map (kbd "C-w")) - 'evil-window-map)) - (define-key evil-emacs-state-map (kbd "C-w") nil)) - ((and value - (not (lookup-key evil-emacs-state-map (kbd "C-w")))) - (define-key evil-emacs-state-map (kbd "C-w") 'evil-window-map)))))) - -(defcustom evil-want-change-word-to-end t - "Whether `cw' behaves like `ce'." - :type 'boolean - :group 'evil) - -(defcustom evil-want-Y-yank-to-eol nil - "Whether `Y' yanks to the end of the line. -The default behavior is to yank the whole line, like Vim." - :group 'evil - :type 'boolean - :initialize #'evil-custom-initialize-pending-reset - :set #'(lambda (sym value) - (set-default sym value) - (evil-add-command-properties - 'evil-yank-line - :motion (if value - 'evil-end-of-line-or-visual-line - 'evil-line-or-visual-line)))) - -(defcustom evil-disable-insert-state-bindings nil - "Whether insert state bindings should be used. -Bindings for escape, delete and `evil-toggle-key' are always -available. If this is non-nil, default Emacs bindings are by and -large accessible in insert state." - :group 'evil - :type 'boolean - :initialize #'evil-custom-initialize-pending-reset - :set #'(lambda (sym value) - (set-default sym value) - (evil-update-insert-state-bindings sym value))) - -(defcustom evil-echo-state t - "Whether to signal the current state in the echo area." - :type 'boolean - :group 'evil) - -(defcustom evil-complete-all-buffers t - "\\<evil-insert-state-map> -Whether completion looks for matches in all buffers. -This applies to \\[evil-complete-next] and \\[evil-complete-previous] \ -in insert state." - :type 'boolean - :group 'evil) - -(defcustom evil-search-wrap-ring-bell nil - "Whether to ring the bell when search wraps around the buffer." - :type 'boolean - :group 'evil) - -(defvar dabbrev-search-these-buffers-only) -(defvar dabbrev-case-distinction) -(defcustom evil-complete-next-func - #'(lambda (arg) - (require 'dabbrev) - (let ((dabbrev-search-these-buffers-only - (unless evil-complete-all-buffers - (list (current-buffer)))) - dabbrev-case-distinction) - (condition-case nil - (if (eq last-command this-command) - (dabbrev-expand nil) - (dabbrev-expand (- (abs (or arg 1))))) - (error (dabbrev-expand nil))))) - "Completion function used by \ -\\<evil-insert-state-map>\\[evil-complete-next]." - :type 'function - :group 'evil) - -(defcustom evil-complete-previous-func - #'(lambda (arg) - (require 'dabbrev) - (let ((dabbrev-search-these-buffers-only - (unless evil-complete-all-buffers - (list (current-buffer)))) - dabbrev-case-distinction) - (dabbrev-expand arg))) - "Completion function used by \ -\\<evil-insert-state-map>\\[evil-complete-previous]." - :type 'function - :group 'evil) - -(defcustom evil-complete-next-minibuffer-func 'minibuffer-complete - "Minibuffer completion function used by \ -\\<evil-insert-state-map>\\[evil-complete-next]." - :type 'function - :group 'evil) - -(defcustom evil-complete-previous-minibuffer-func 'minibuffer-complete - "Minibuffer completion function used by \ -\\<evil-insert-state-map>\\[evil-complete-previous]." - :type 'function - :group 'evil) - -(defcustom evil-complete-next-line-func - #'(lambda (arg) - (let ((hippie-expand-try-functions-list - '(try-expand-line - try-expand-line-all-buffers))) - (hippie-expand arg))) - "Minibuffer completion function used by \ -\\<evil-insert-state-map>\\[evil-complete-next-line]." - :type 'function - :group 'evil) - -(defcustom evil-complete-previous-line-func - evil-complete-next-line-func - "Minibuffer completion function used by \ -\\<evil-insert-state-map>\\[evil-complete-previous-line]." - :type 'function - :group 'evil) - -(defcustom evil-lookup-func #'woman - "Lookup function used by \ -\"\\<evil-motion-state-map>\\[evil-lookup]\"." - :type 'function - :group 'evil) - -(defcustom evil-toggle-key "C-z" - "The key used to change to and from Emacs state. -Must be readable by `read-kbd-macro'. For example: \"C-z\"." - :type 'string - :group 'evil - :set #'(lambda (sym value) - (evil-set-toggle-key value) - (set-default sym value))) - -(defcustom evil-default-state 'normal - "The default Evil state. -This is the state a buffer starts in when it is not otherwise -configured (see `evil-set-initial-state' and -`evil-buffer-regexps'). The value may be one of `normal', -`insert', `visual', `replace', `operator', `motion' and `emacs'." - :type 'symbol - :group 'evil) - -(defcustom evil-buffer-regexps - '(("^ \\*load\\*" . nil)) - "Regular expressions determining the initial state for a buffer. -Entries have the form (REGEXP . STATE), where REGEXP is a regular -expression matching the buffer's name and STATE is one of `normal', -`insert', `visual', `replace', `operator', `motion', `emacs' and -`nil'. If STATE is `nil', Evil is disabled in the buffer." - :type '(alist :key-type string :value-type symbol) - :group 'evil) - -(defcustom evil-emacs-state-modes - '(5x5-mode - archive-mode - bbdb-mode - biblio-selection-mode - blackbox-mode - bookmark-bmenu-mode - bookmark-edit-annotation-mode - browse-kill-ring-mode - bs-mode - bubbles-mode - bzr-annotate-mode - calc-mode - cfw:calendar-mode - completion-list-mode - Custom-mode - custom-theme-choose-mode - debugger-mode - delicious-search-mode - desktop-menu-blist-mode - desktop-menu-mode - doc-view-mode - dun-mode - dvc-bookmarks-mode - dvc-diff-mode - dvc-info-buffer-mode - dvc-log-buffer-mode - dvc-revlist-mode - dvc-revlog-mode - dvc-status-mode - dvc-tips-mode - ediff-mode - ediff-meta-mode - efs-mode - Electric-buffer-menu-mode - emms-browser-mode - emms-mark-mode - emms-metaplaylist-mode - emms-playlist-mode - ess-help-mode - etags-select-mode - fj-mode - gc-issues-mode - gdb-breakpoints-mode - gdb-disassembly-mode - gdb-frames-mode - gdb-locals-mode - gdb-memory-mode - gdb-registers-mode - gdb-threads-mode - gist-list-mode - git-rebase-mode - gnus-article-mode - gnus-browse-mode - gnus-group-mode - gnus-server-mode - gnus-summary-mode - gomoku-mode - google-maps-static-mode - ibuffer-mode - jde-javadoc-checker-report-mode - magit-cherry-mode - magit-diff-mode - magit-log-mode - magit-log-select-mode - magit-popup-mode - magit-popup-sequence-mode - magit-process-mode - magit-reflog-mode - magit-refs-mode - magit-revision-mode - magit-stash-mode - magit-stashes-mode - magit-status-mode - mh-folder-mode - monky-mode - mpuz-mode - mu4e-main-mode - mu4e-headers-mode - mu4e-view-mode - notmuch-hello-mode - notmuch-search-mode - notmuch-show-mode - notmuch-tree-mode - occur-mode - org-agenda-mode - package-menu-mode - pdf-outline-buffer-mode - pdf-view-mode - proced-mode - rcirc-mode - rebase-mode - recentf-dialog-mode - reftex-select-bib-mode - reftex-select-label-mode - reftex-toc-mode - sldb-mode - slime-inspector-mode - slime-thread-control-mode - slime-xref-mode - snake-mode - solitaire-mode - sr-buttons-mode - sr-mode - sr-tree-mode - sr-virtual-mode - tar-mode - tetris-mode - tla-annotate-mode - tla-archive-list-mode - tla-bconfig-mode - tla-bookmarks-mode - tla-branch-list-mode - tla-browse-mode - tla-category-list-mode - tla-changelog-mode - tla-follow-symlinks-mode - tla-inventory-file-mode - tla-inventory-mode - tla-lint-mode - tla-logs-mode - tla-revision-list-mode - tla-revlog-mode - tla-tree-lint-mode - tla-version-list-mode - twittering-mode - urlview-mode - vc-annotate-mode - vc-dir-mode - vc-git-log-view-mode - vc-hg-log-view-mode - vc-svn-log-view-mode - vm-mode - vm-summary-mode - w3m-mode - wab-compilation-mode - xgit-annotate-mode - xgit-changelog-mode - xgit-diff-mode - xgit-revlog-mode - xhg-annotate-mode - xhg-log-mode - xhg-mode - xhg-mq-mode - xhg-mq-sub-mode - xhg-status-extra-mode) - "Modes that should come up in Emacs state." - :type '(repeat symbol) - :group 'evil) - -(defcustom evil-insert-state-modes - '(comint-mode - erc-mode - eshell-mode - geiser-repl-mode - gud-mode - inferior-apl-mode - inferior-caml-mode - inferior-emacs-lisp-mode - inferior-j-mode - inferior-python-mode - inferior-scheme-mode - inferior-sml-mode - internal-ange-ftp-mode - haskell-interactive-mode - prolog-inferior-mode - racket-repl-mode - reb-mode - shell-mode - slime-repl-mode - term-mode - utop-mode - wdired-mode) - "Modes that should come up in Insert state." - :type '(repeat symbol) - :group 'evil) - -(defcustom evil-motion-state-modes - '(apropos-mode - Buffer-menu-mode - calendar-mode - color-theme-mode - command-history-mode - compilation-mode - dictionary-mode - ert-results-mode - help-mode - Info-mode - Man-mode - speedbar-mode - undo-tree-visualizer-mode - woman-mode) - "Modes that should come up in Motion state." - :type '(repeat symbol) - :group 'evil) - -(defvar evil-pending-overriding-maps nil - "An alist of pending overriding maps.") - -(defvar evil-pending-intercept-maps nil - "An alist of pending intercept maps.") - -(defcustom evil-overriding-maps '() - "Keymaps that should override Evil maps. -Entries have the form (MAP-VAR . STATE), where MAP-VAR is -a keymap variable and STATE is the state whose bindings -should be overridden. If STATE is nil, all states are -overridden." - :type '(alist :key-type symbol :value-type symbol) - :group 'evil - :set #'(lambda (var values) - (set-default var values) - (evil-set-custom-state-maps 'evil-overriding-maps - 'evil-pending-overriding-maps - 'override-state - 'evil-make-overriding-map - values)) - :initialize #'evil-custom-initialize-pending-reset) - -(add-hook 'after-load-functions #'evil-update-pending-maps) - -(defcustom evil-intercept-maps - '((edebug-mode-map . nil)) - "Keymaps that should intercept Evil maps. -Entries have the form (MAP-VAR . STATE), where MAP-VAR is -a keymap variable and STATE is the state whose bindings -should be intercepted. If STATE is nil, all states are -intercepted." - :type '(alist :key-type symbol :value-type symbol) - :group 'evil - :set #'(lambda (var values) - (set-default var values) - (evil-set-custom-state-maps 'evil-intercept-maps - 'evil-pending-intercept-maps - 'intercept-state - 'evil-make-intercept-map - values)) - :initialize #'evil-custom-initialize-pending-reset) - -(defcustom evil-motions - '(back-to-indentation - backward-char - backward-list - backward-paragraph - backward-sentence - backward-sexp - backward-up-list - backward-word - beginning-of-buffer - beginning-of-defun - beginning-of-line - beginning-of-visual-line - c-beginning-of-defun - c-end-of-defun - diff-file-next - diff-file-prev - diff-hunk-next - diff-hunk-prev - down-list - end-of-buffer - end-of-defun - end-of-line - end-of-visual-line - exchange-point-and-mark - forward-char - forward-list - forward-paragraph - forward-sentence - forward-sexp - forward-word - goto-char - goto-last-change - ibuffer-backward-line - ibuffer-forward-line - isearch-abort - isearch-cancel - isearch-complete - isearch-del-char - isearch-delete-char - isearch-edit-string - isearch-exit - isearch-highlight-regexp - isearch-occur - isearch-other-control-char - isearch-other-meta-char - isearch-printing-char - isearch-query-replace - isearch-query-replace-regexp - isearch-quote-char - isearch-repeat-backward - isearch-repeat-forward - isearch-ring-advance - isearch-ring-retreat - isearch-toggle-case-fold - isearch-toggle-input-method - isearch-toggle-regexp - isearch-toggle-specified-input-method - isearch-toggle-word - isearch-yank-char - isearch-yank-kill - isearch-yank-line - isearch-yank-word-or-char - keyboard-quit - left-char - left-word - mouse-drag-region - mouse-save-then-kill - mouse-set-point - mouse-set-region - mwheel-scroll - move-beginning-of-line - move-end-of-line - next-error - next-line - paredit-backward - paredit-backward-down - paredit-backward-up - paredit-forward - paredit-forward-down - paredit-forward-up - pop-global-mark - pop-tag-mark - pop-to-mark-command - previous-error - previous-line - right-char - right-word - scroll-down - scroll-down-command - scroll-up - scroll-up-command - sgml-skip-tag-backward - sgml-skip-tag-forward - up-list) - "Non-Evil commands to initialize to motions." - :type '(repeat symbol) - :group 'evil - :set #'evil-set-custom-motions - :initialize #'evil-custom-initialize-pending-reset) - -(defcustom evil-visual-newline-commands - '(LaTeX-section - TeX-font) - "Commands excluding the trailing newline of a Visual Line selection. -These commands work better without this newline." - :type '(repeat symbol) - :group 'evil - :set #'evil-set-visual-newline-commands - :initialize #'evil-custom-initialize-pending-reset) - -(defcustom evil-want-visual-char-semi-exclusive nil - "DEPRECATED. Will be removed in a future version. -Prefer to set `evil-v$-excludes-newline' to non-nil. - -Visual character selection to beginning/end of line is exclusive. -If non nil then an inclusive visual character selection which -ends at the beginning or end of a line is turned into an -exclusive selection. Thus if the selected (inclusive) range ends -at the beginning of a line it is changed to not include the first -character of that line, and if the selected range ends at the end -of a line it is changed to not include the newline character of -that line." - :type 'boolean - :group 'evil) -(make-obsolete-variable - 'evil-want-visual-char-semi-exclusive - "Semi-exclusivity prevents selecting text + 1st char of next line, -without having to introduce new niche functionality. -Prefer to set `evil-v$-excludes-newline' to non-nil." - "1.15.0") - -(defcustom evil-v$-excludes-newline nil - "If non-nil, `evil-end-of-line' does not move as far as to include -the `\n' char at eol. This makes `v$' consistent with `$' used as a -motion (e.g. `v$y' is consistent with `y$' in normal state)." - :type 'boolean - :group 'evil) - -(defcustom evil-text-object-change-visual-type t - "Text objects change the current visual state type. -If non-nil then a text-object changes the type of the visual state to -its default selection type (e.g. a word object always changes to -charwise visual state). Otherwise the current visual state type is -preserved." - :type 'boolean - :group 'evil) - -(defgroup evil-cjk nil - "CJK support" - :prefix "evil-cjk-" - :group 'evil) - -(defcustom evil-cjk-emacs-word-boundary nil - "Determine word boundary exactly the same way as Emacs does." - :type 'boolean - :group 'evil-cjk) - -(defcustom evil-cjk-word-separating-categories - '(;; Kanji - (?C . ?H) (?C . ?K) (?C . ?k) (?C . ?A) (?C . ?G) - ;; Hiragana - (?H . ?C) (?H . ?K) (?H . ?k) (?H . ?A) (?H . ?G) - ;; Katakana - (?K . ?C) (?K . ?H) (?K . ?k) (?K . ?A) (?K . ?G) - ;; half-width Katakana - (?k . ?C) (?k . ?H) (?k . ?K) ; (?k . ?A) (?k . ?G) - ;; full-width alphanumeric - (?A . ?C) (?A . ?H) (?A . ?K) ; (?A . ?k) (?A . ?G) - ;; full-width Greek - (?G . ?C) (?G . ?H) (?G . ?K) ; (?G . ?k) (?G . ?A) - ) - "List of pair (cons) of categories to determine word boundary -used in `evil-cjk-word-boundary-p'. See the documentation of -`word-separating-categories'. Use `describe-categories' to see -the list of categories." - :type '(alist :key-type (choice character (const nil)) - :value-type (choice character (const nil))) - :group 'evil-cjk) - -(defcustom evil-cjk-word-combining-categories - '(;; default value in word-combining-categories - (nil . ?^) (?^ . nil) - ;; Roman - (?r . ?k) (?r . ?A) (?r . ?G) - ;; half-width Katakana - (?k . ?r) (?k . ?A) (?k . ?G) - ;; full-width alphanumeric - (?A . ?r) (?A . ?k) (?A . ?G) - ;; full-width Greek - (?G . ?r) (?G . ?k) (?G . ?A) - ) - "List of pair (cons) of categories to determine word boundary -used in `evil-cjk-word-boundary-p'. See the documentation of -`word-combining-categories'. Use `describe-categories' to see the -list of categories." - :type '(alist :key-type (choice character (const nil)) - :value-type (choice character (const nil))) - :group 'evil-cjk) - -(defcustom evil-ex-complete-emacs-commands 'in-turn - "TAB-completion for Emacs commands in ex command line. -This variable determines when Emacs commands are considered for -completion, always, never, or only if no Evil ex command is -available for completion." - :group 'evil - :type '(radio (const :tag "Only if no ex-command." :value in-turn) - (const :tag "Never" :value nil) - (const :tag "Always" :value t))) - -(defface evil-ex-commands '(( nil - :underline t - :slant italic)) - "Face for the Evil command in completion in ex mode." - :group 'evil) - -(defface evil-ex-info '(( ((supports :slant)) - :slant italic - :foreground "red")) - "Face for the info message in ex mode." - :group 'evil) - -(defcustom evil-ex-visual-char-range nil - "Type of default ex range in visual char state. -If non-nil the default range when starting an ex command from -character visual state is `<,`> otherwise it is '<,'>. In the -first case the ex command will be passed a region covering only -the visual selection. In the second case the passed region will -be extended to contain full lines." - :group 'evil - :type 'boolean) - -(defvar evil--ex-global-active-p nil - "If the :global command is running. -Used to change the behaviour of certain commands like :print.") - -(defvar evil--ex-print-accumulator "" - "Used by :print etc. to accumulate a string when invoked by :global etc.") - -;; Searching -(defcustom evil-symbol-word-search nil - "If nil then * and # search for words otherwise for symbols." - :group 'evil - :type 'boolean) - -(defcustom evil-magic t - "Meaning which characters in a pattern are magic. -The meaning of those values is the same as in Vim. Note that it -only has influence if the Evil search module is chosen in -`evil-search-module'." - :group 'evil - :type '(radio (const :tag "Very magic." :value very-magic) - (const :tag "Magic" :value t) - (const :tag "Nomagic" :value nil) - (const :tag "Very nomagic" :value very-nomagic))) - -(defcustom evil-ex-search-vim-style-regexp nil - "If non-nil Vim-style backslash codes are supported in search patterns. -See `evil-transform-vim-style-regexp' for the supported backslash -codes. Note that this only affects the search command if -`evil-search-module' is set to `evil-search'. The isearch module -always uses plain Emacs regular expressions." - :type 'boolean - :group 'evil) - -(defcustom evil-ex-interactive-search-highlight 'all-windows - "Determine in which windows the interactive highlighting should be shown." - :type '(radio (const :tag "All windows." all-windows) - (const :tag "Selected window." selected-window) - (const :tag "Disable highlighting." nil)) - :group 'evil) - -(defcustom evil-ex-search-persistent-highlight t - "If non-nil matches remain highlighted when the search ends." - :type 'boolean - :group 'evil) - -(defcustom evil-ex-search-case 'smart - "The case behaviour of the search command. -Smart case means that the pattern is case sensitive if and only -if it contains an upper case letter, otherwise it is case -insensitive." - :type '(radio (const :tag "Case sensitive." sensitive) - (const :tag "Case insensitive." insensitive) - (const :tag "Smart case." smart)) - :group 'evil) - -(defcustom evil-ex-substitute-case nil - "The case behaviour of the search command. -Smart case means that the pattern is case sensitive if and only -if it contains an upper case letter, otherwise it is case -insensitive. If nil then the setting of `evil-ex-search-case' is -used." - :type '(radio (const :tag "Same as interactive search." nil) - (const :tag "Case sensitive." sensitive) - (const :tag "Case insensitive." insensitive) - (const :tag "Smart case." smart)) - :group 'evil) - -(defcustom evil-ex-search-interactive t - "If t search is interactive." - :type 'boolean - :group 'evil) - -(defcustom evil-ex-search-incremental t - "If t, use incremental search. Note that this only affects the -search command if `evil-search-module' is set to `evil-search'." - :type 'boolean - :group 'evil) - -(defcustom evil-ex-search-highlight-all t - "If t and interactive search is enabled, all matches are -highlighted." - :type 'boolean - :group 'evil) - -(defcustom evil-ex-substitute-highlight-all t - "If t all matches for the substitute pattern are highlighted." - :type 'boolean - :group 'evil) - -(defcustom evil-ex-substitute-interactive-replace t - "If t and substitute patterns are highlighted, -the replacement is shown interactively." - :type 'boolean - :group 'evil) - -(defcustom evil-ex-substitute-global nil - "If non-nil substitute patterns are global by default. -Standardly (if this variable is nil) a substitution works only on the -first match of the pattern in a line unless the \"g\" flag is -given, in which case the substitution happens on all matches in the -line. If this option is non-nil, this behavior is reversed." - :type 'boolean - :group 'evil) - -(defface evil-ex-search '((t :inherit isearch)) - "Face for interactive search." - :group 'evil) - -(defface evil-ex-lazy-highlight '((t :inherit lazy-highlight)) - "Face for highlighting all matches in interactive search." - :group 'evil) - -(defface evil-ex-substitute-matches '((t :inherit lazy-highlight)) - "Face for interactive substitute matches." - :group 'evil) - -(defface evil-ex-substitute-replacement '((((supports :underline)) - :underline t - :foreground "red")) - "Face for interactive replacement text." - :group 'evil) - -(defcustom evil-command-window-height 7 - "Height (in lines) of the command line window. -Set to 0 to use the default height for `split-window'." - :type 'integer - :group 'evil) - -(defcustom evil-display-shell-error-in-message nil - "Show error output of a shell command in the error buffer. -If this variable is non-nil the error output of a shell command -goes to the messages buffer instead of being mixed with the -regular output. This happens only if the exit status of the -command is non-zero." - :type 'boolean - :group 'evil) - -(defcustom evil-want-abbrev-expand-on-insert-exit t - "If non-nil abbrevs will be expanded when leaving insert state -like in Vim, if `abbrev-mode' is on." - :type 'boolean - :group 'evil) - -;;; Variables - -(defmacro evil-define-local-var (symbol &optional initvalue docstring) - "Define SYMBOL as permanent buffer local variable, and return SYMBOL. -The parameters are the same as for `defvar', but the variable -SYMBOL is made permanent buffer local." - (declare (indent defun) - (doc-string 3) - (debug (symbolp &optional form stringp))) - `(progn - (defvar ,symbol ,initvalue ,docstring) - (make-variable-buffer-local ',symbol) - (put ',symbol 'permanent-local t))) - -(evil-define-local-var evil-scroll-count 0 - "Hold last used prefix for `evil-scroll-up' -and `evil-scroll-down'. -Determine how many lines should be scrolled. -Default value is 0 - scroll half the screen.") - -(evil-define-local-var evil-state nil - "The current Evil state. -To change the state, use `evil-change-state' -or call the state function (e.g., `evil-normal-state').") - -;; these may be used inside `evil-define-state' -(evil-define-local-var evil-next-state nil - "The Evil state being switched to.") - -(evil-define-local-var evil-previous-state-alist nil - "For Each evil state the Evil state being switched from.") - -(evil-define-local-var evil-previous-state nil - "The Evil state being switched from.") - -(defvar evil-execute-in-emacs-state-buffer nil - "The buffer of the latest `evil-execute-in-emacs-state'. -When this command is being executed the current buffer is stored -in this variable. This is necessary in case the Emacs-command to -be called changes the current buffer.") - -(evil-define-local-var evil-mode-line-tag nil - "Mode-Line indicator for the current state.") -(put 'evil-mode-line-tag 'risky-local-variable t) - -(defvar evil-global-keymaps-alist nil - "Association list of keymap variables. -Entries have the form (MODE . KEYMAP), where KEYMAP -is the variable containing the keymap for MODE.") - -(defvar evil-local-keymaps-alist nil - "Association list of keymap variables that must be -reinitialized in each buffer. Entries have the form -\(MODE . KEYMAP), where KEYMAP is the variable containing -the keymap for MODE.") - -(defvar evil-minor-mode-keymaps-alist nil - "Association list of Evil states to minor-mode keymap alists. -Entries have the form (STATE . MODE-MAP-ALIST), where -MODE-MAP-ALIST is an alist taking the form of -`minor-mode-map-alist'.") - -(defvar evil-state-properties nil - "Specifications made by `evil-define-state'. -Entries have the form (STATE . PLIST), where PLIST is a property -list specifying various aspects of the state. To access a property, -use `evil-state-property'.") - -(evil-define-local-var evil-mode-map-alist nil - "Association list of keymaps to use for Evil modes. -Elements have the form (MODE . KEYMAP), with the first keymaps -having higher priority.") - -(defvar evil-change-commands '(evil-change) - "Commands that wrap or replace `evil-change'. -This list exists to apply an inconsistency with vim's change command -to commands that wrap or redefine it. See emacs-evil/evil#916.") - -(defvar evil-transient-vars '(cua-mode transient-mark-mode select-active-regions) - "List of variables pertaining to Transient Mark mode.") - -(defvar evil-transient-vals nil - "Association list of old values for Transient Mark mode variables. -Entries have the form (VARIABLE VALUE LOCAL), where LOCAL is -whether the variable was previously buffer-local.") - -(defvar evil-no-display nil - "If non-nil, various Evil displays are inhibited. -Use the macro `evil-without-display' to set this variable.") - -(defvar evil-type-properties nil - "Specifications made by `evil-define-type'. -Entries have the form (TYPE . PLIST), where PLIST is a property -list specifying functions for handling the type: expanding it, -describing it, etc.") - -(defvar evil-interactive-alist nil - "Association list of Evil-specific interactive codes.") - -(evil-define-local-var evil-motion-marker nil - "Marker for storing the starting position of a motion.") - -(evil-define-local-var evil-this-type nil - "Current motion type.") - -(evil-define-local-var evil-this-type-modified nil - "Non-nil iff current motion type has been modified by the user. -If the type has been modified, this variable contains the new -type.") - -(evil-define-local-var evil-this-register nil - "Current register.") - -(defvar evil-last-=-register-input nil - "Most recent input from the `=' register. A string.") - -(defvar evil-this-macro nil - "Current macro register.") - -(evil-define-local-var evil-this-operator nil - "Current operator.") - -(evil-define-local-var evil-this-motion nil - "Current motion.") - -(evil-define-local-var evil-this-motion-count nil - "Current motion count.") - -;; In light of `evil-last-recorded-register' this should probably -;; be renamed to `evil-last-executed-register' but that may break configs -(defvar evil-last-register nil - "The last executed register.") - -(defvar evil-last-recorded-register nil - "The last recorded register.") - -(defvar evil-inhibit-operator nil - "Inhibit current operator. -If an operator calls a motion and the motion sets this variable -to t, the operator code is not executed.") - -(defvar evil-inhibit-operator-value nil - "This variable is used to transfer the value -of `evil-inhibit-operator' from one local scope to another.") - -;; used by `evil-define-operator' -(defvar evil-operator-range-beginning nil - "Beginning of `evil-operator-range'.") - -(defvar evil-operator-range-end nil - "End of `evil-operator-range'.") - -(defvar evil-operator-range-type nil - "Type of `evil-operator-range'.") - -(defvar evil-operator-range-motion nil - "Motion of `evil-operator-range'.") - -(defvar evil-operator-start-col nil - "Used to restore column (where possible) after an operator has moved it.") - -(defvar evil-restriction-stack nil - "List of previous restrictions. -Using `evil-with-restriction' stores the previous values of -`point-min' and `point-max' as a pair in this list.") - -(evil-define-local-var evil-markers-alist - '((?\( . evil-backward-sentence-begin) - (?\) . evil-forward-sentence-begin) - (?{ . evil-backward-paragraph) - (?} . evil-forward-paragraph) - (?' . evil-jump-backward-swap) - (?` . evil-jump-backward-swap) - (?< . evil-visual-beginning) - (?> . evil-visual-goto-end) - (?. . (lambda () - (let (last-command) - (goto-last-change nil))))) - "Association list for markers. -Entries have the form (CHAR . DATA), where CHAR is the marker's -name and DATA is either a marker object as returned by `make-marker', -a variable, a movement function, or a cons cell (STRING NUMBER), -where STRING is a file path and NUMBER is a buffer position. -The global value of this variable holds markers available from -every buffer, while the buffer-local value holds markers available -only in the current buffer.") - -(defconst evil-suppress-map (make-keymap) - "Full keymap disabling default bindings to `self-insert-command'.") -(suppress-keymap evil-suppress-map t) - -(defvar evil-read-key-map (make-sparse-keymap) - "Keymap active during `evil-read-key'. -This keymap can be used to bind some commands during the -execution of `evil-read-key' which is usually used to read a -character argument for some commands, e.g. `evil-replace'.") - -;; TODO: customize size of ring -(defvar evil-repeat-ring (make-ring 10) - "A ring of repeat-informations to repeat the last command.") - -(defvar evil-recording-repeat nil - "Whether we are recording a repeat.") - -(defvar evil-recording-current-command nil - "Whether we are recording the current command for repeat.") - -(defvar evil-repeat-changes nil - "Accumulated buffer changes in reverse order for change-tracking commands.") - -(defvar evil-repeat-info nil - "Information accumulated during current repeat.") - -(defvar evil-repeat-buffer nil - "The buffer in which the repeat started. -If the buffer is changed, the repeat is cancelled.") - -(defvar evil-repeat-pos nil - "The point position at the start of a change-tracking command.") - -(defvar evil-repeat-keys nil - "The keys that invoked the current command.") - -(defvar evil-last-repeat nil - "Information about the latest repeat command. -This is a list of three elements (POINT COUNT UNDO-POINTER), -where POINT is the position of point before the latest repeat, -COUNT the count-argument of the latest repeat command and -UNDO-POINTER the head of the undo-list before the last command -has been repeated.") - -(defvar evil-repeat-count nil - "The explicit count when repeating a command.") - -(defvar evil-maybe-remove-spaces nil - "Flag to determine if newly inserted spaces should be removed. -See the function `evil-maybe-remove-spaces'.") - -(evil-define-local-var evil-insert-count nil - "The explicit count passed to a command starting Insert or Replace state.") - -(evil-define-local-var evil-insert-vcount nil - "The information about the number of following lines the -insertion should be repeated. This is list (LINE COLUMN COUNT) -where LINE is the line-number where the original insertion -started and COLUMN is either a number or function determining the -column where the repeated insertions should take place. COUNT is -number of repeats (including the original insertion).") - -(defvar evil-insert-skip-empty-lines nil - "Non-nil of the current insertion should not take place on - lines at which the insertion point is behind the end of the - line.") - -(evil-define-local-var evil-insert-lines nil - "Non-nil if the current insertion command is a line-insertion -command o or O.") - -(evil-define-local-var evil-insert-repeat-info nil - "Repeat information accumulated during an insertion.") - -(evil-define-local-var evil-replace-alist nil - "Association list of characters overwritten in Replace state. -The format is (POS . CHAR).") - -(evil-define-local-var evil-echo-area-message nil - "Previous value of `current-message'.") - -(defvar evil-write-echo-area nil - "If set to t inside `evil-save-echo-area', then the echo area -is not restored.") - -(defvar evil-last-find nil - "A pair (FUNCTION . CHAR) describing the lastest character - search command.") - -(defvar evil-last-paste nil - "Information about the latest paste. -This should be a list (CMD COUNT POINT BEG END FIRSTVISUAL) where -CMD is the last paste-command (`evil-paste-before', -`evil-paste-after' or `evil-visual-paste'), COUNT is the repeat -count of the paste, POINT is the position of point before the -paste, BEG end END are the region of the inserted -text. FIRSTVISUAL is t if and only if the previous command was -the first visual paste (i.e. before any paste-pop).") - -(evil-define-local-var evil-last-undo-entry nil - "Information about the latest undo entry in the buffer. -This should be a pair (OBJ . CONS) where OBJ is the entry as an -object, and CONS is a copy of the entry.") - -(evil-define-local-var evil-current-insertion nil - "Information about the latest insertion in insert state. -This should be a pair (BEG . END) that describes the -buffer-region of the newly inserted text.") - -(defvar evil-last-insertion nil - "The last piece of inserted text.") - -(defvar evil-last-small-deletion nil - "The last piece of deleted text. -The text should be less than a line.") - -(defvar evil-was-yanked-without-register t - "Whether text being saved to the numbered-register ring was -not deleted and not yanked to a specific register.") - -(defvar evil-paste-count nil - "The count argument of the current paste command.") - -(defvar evil--cursor-after nil - "Internal flag for gp & gP.") - -(defvar evil-temporary-undo nil - "When undo is disabled in current buffer. -Certain commands depending on undo use this variable -instead of `buffer-undo-list'.") - -(evil-define-local-var evil-undo-list-pointer nil - "Everything up to this mark is united in the undo-list.") - -(defvar evil-in-single-undo nil - "Set to non-nil if the current undo steps are connected.") - -(defvar evil-flash-timer nil - "Timer for flashing search results.") - -(defvar evil-search-prompt nil - "String to use for search prompt.") - -(defvar evil-search-forward-history nil - "History of forward searches.") - -(defvar evil-search-backward-history nil - "History of backward searches.") - -(defvar evil-inner-text-objects-map (make-sparse-keymap) - "Keymap for inner text objects.") - -(defvar evil-outer-text-objects-map (make-sparse-keymap) - "Keymap for outer text objects.") - -(defvar evil-window-map (make-sparse-keymap) - "Keymap for window-related commands.") - -(evil-define-local-var evil-input-method nil - "Input method used in Insert state and Emacs state.") - -;;; Visual state - -(evil-define-local-var evil-visual-beginning nil - "The beginning of the Visual selection, a marker.") - -(evil-define-local-var evil-visual-end nil - "The end of the Visual selection, a marker.") - -(evil-define-local-var evil-visual-point nil - "The position of point in Visual state, a marker.") - -(evil-define-local-var evil-visual-mark nil - "The position of mark in Visual state, a marker.") - -(evil-define-local-var evil-visual-selection nil - "The kind of Visual selection. -This is a selection as defined by `evil-define-visual-selection'.") - -(evil-define-local-var evil-prev-visual-point nil - "The previous position of point in Visual state, a marker.") - -(evil-define-local-var evil-prev-visual-mark nil - "The previous position of mark in Visual state, a marker.") - -(evil-define-local-var evil-prev-visual-selection nil - "The previous kind of Visual selection. -This is a selection as defined by `evil-define-visual-selection'.") - -;; we could infer the direction by comparing `evil-visual-mark' -;; and `evil-visual-point', but destructive operations may -;; displace the markers -(evil-define-local-var evil-visual-direction 0 - "Whether point follows mark in Visual state. -Negative if point precedes mark, otherwise positive. -See also the function `evil-visual-direction'.") - -(evil-define-local-var evil-visual-properties nil - "Property list of miscellaneous Visual properties.") - -(evil-define-local-var evil-visual-region-expanded nil - "Whether the region matches the Visual selection. -That is, whether the positions of point and mark have been -expanded to coincide with the selection's boundaries. -This makes the selection available to functions acting -on Emacs' region.") - -(defvar evil-transient-mouse-selection nil - "Whether the region selected by the mouse is discarded by the next command. -By default, the region is not discarded. If non-nil, exit visual state -immediately before the next command. To use the region selected by the mouse, -execute a command which would usually enter visual state, such as -\\[evil-visual-char] or \\[evil-visual-block].") - -(defvar evil--region-from-mouse nil - "Whether the region was set by the mouse.") - -(evil-define-local-var evil-visual-overlay nil - "Overlay for highlighting the Visual selection. -Not used for blockwise selections, in which case -see `evil-visual-block-overlays'.") - -(evil-define-local-var evil-visual-block-overlays nil - "Overlays for Visual Block selection, one for each line. -They are reused to minimize flicker.") - -(defvar evil-visual-alist nil - "Association list of Visual selection functions. -Elements have the form (NAME . FUNCTION).") - -(evil-define-local-var evil-visual-x-select-timer nil - "Timer for updating the X selection in visual state.") - -(defvar evil-visual-x-select-timeout 0.1 - "Time in seconds for the update of the X selection.") - -(declare-function origami-open-all-nodes "ext:origami.el") -(declare-function origami-close-all-nodes "ext:origami.el") -(declare-function origami-toggle-node "ext:origami.el") -(declare-function origami-open-node "ext:origami.el") -(declare-function origami-open-node-recursively "ext:origami.el") -(declare-function origami-close-node "ext:origami.el") - -(defvar evil-fold-list - `(((vdiff-mode) - :open-all vdiff-open-all-folds - :close-all vdiff-close-all-folds - :toggle ,(lambda () (call-interactively 'vdiff-toggle-fold)) - :open ,(lambda () (call-interactively 'vdiff-open-fold)) - :open-rec ,(lambda () (call-interactively 'vdiff-open-fold)) - :close ,(lambda () (call-interactively 'vdiff-close-fold))) - ((vdiff-3way-mode) - :open-all vdiff-open-all-folds - :close-all vdiff-close-all-folds - :toggle ,(lambda () (call-interactively 'vdiff-toggle-fold)) - :open ,(lambda () (call-interactively 'vdiff-open-fold)) - :open-rec ,(lambda () (call-interactively 'vdiff-open-fold)) - :close ,(lambda () (call-interactively 'vdiff-close-fold))) - ((hs-minor-mode) - :open-all hs-show-all - :close-all hs-hide-all - :toggle hs-toggle-hiding - :open hs-show-block - :open-rec nil - :close hs-hide-block) - ((hide-ifdef-mode) - :open-all show-ifdefs - :close-all hide-ifdefs - :toggle nil - :open show-ifdef-block - :open-rec nil - :close hide-ifdef-block) - ((outline-mode - outline-minor-mode - org-mode - markdown-mode) - :open-all show-all - :close-all ,(lambda () - (with-no-warnings (hide-sublevels 1))) - :toggle outline-toggle-children - :open ,(lambda () - (with-no-warnings - (show-entry) - (show-children))) - :open-rec show-subtree - :close hide-subtree) - ((origami-mode) - :open-all ,(lambda () (origami-open-all-nodes (current-buffer))) - :close-all ,(lambda () (origami-close-all-nodes (current-buffer))) - :toggle ,(lambda () (origami-toggle-node (current-buffer) (point))) - :open ,(lambda () (origami-open-node (current-buffer) (point))) - :open-rec ,(lambda () (origami-open-node-recursively (current-buffer) (point))) - :close ,(lambda () (origami-close-node (current-buffer) (point))))) - "Actions to be performed for various folding operations. - -The value should be a list of fold handlers, were a fold handler has -the format: - - ((MODES) PROPERTIES) - -MODES acts as a predicate, containing the symbols of all major or -minor modes for which the handler should match. For example: - - \\='((outline-minor-mode org-mode) ...) - -would match for either outline-minor-mode or org-mode, even though the -former is a minor mode and the latter is a major. - -PROPERTIES specifies possible folding actions and the functions to be -applied in the event of a match on one (or more) of the MODES; the -supported properties are: - - - `:open-all' - Open all folds. - - `:close-all' - Close all folds. - - `:toggle' - Toggle the display of the fold at point. - - `:open' - Open the fold at point. - - `:open-rec' - Open the fold at point recursively. - - `:close' - Close the fold at point. - -Each value must be a function. A value of `nil' will cause the action -to be ignored for that respective handler. For example: - - `((org-mode) - :close-all nil - :open ,(lambda () - (show-entry) - (show-children)) - :close hide-subtree) - -would ignore `:close-all' actions and invoke the provided functions on -`:open' or `:close'.") - -;;; Ex - -(define-obsolete-variable-alias 'evil-ex-map 'evil-ex-shortcut-map "1.15.0") -(defvar evil-ex-shortcut-map (make-sparse-keymap) - "Keymap for Ex. -Key sequences bound in this map are immediately executed.") - -;; Intentionally does not inherit from `minibuffer-local-map', as users -;; are encouraged to instead set this as the parent of that keymap. -(defvar evil-command-line-map (make-sparse-keymap) - "Keymap used for the various Evil command-lines. -Modifying this keymap corresponds to using the \":cmap\" Vim command. -See `evil-ex-completion-map' and `evil-ex-search-keymap' which inherit -from this keymap.") - -(defvar evil-ex-completion-map (make-sparse-keymap) - "Keymap for Ex.") - -(defvar evil-ex-initial-input nil - "Additional initial content of the Ex command line. -This content of this variable is appended to the Ex command line -when Ex is started interactively.") - -(defvar evil-ex-history nil - "History of Ex commands.") - -(define-obsolete-variable-alias - 'evil-ex-current-buffer 'evil-ex-original-buffer "1.15.0") -(defvar evil-ex-original-buffer nil - "Buffer that was current when the Evil command line was started.") - -(defvar evil-ex-point nil - "The point position when the Ex command was called.") - -(defvar evil-called-from-ex-p nil - "Non-nil if a command is currently being called as an Ex command.") - -(defvar evil-ex-range nil - "The current range of the Ex command.") - -(defvar evil-ex-bang nil - "The \"!\" argument of the current Ex command.") - -(defvar evil-ex-argument nil - "The current argument of the Ex command.") - -(defvar evil-previous-shell-command nil - "The last shell command.") - -;; Eval -(defvar evil-eval-history nil - "History of eval input, from the `=' register.") - -(defvar evil-eval-map (make-sparse-keymap) - "Keymap for eval input.") - -;; Searching -(defvar evil-ex-search-history nil - "The history for the search command.") - -(defvar evil-ex-search-direction nil - "The direction of the current search, either `forward' or `backward'.") - -(defvar evil-ex-search-count nil - "The count of the current search.") - -(defvar evil-ex-search-start-point nil - "The point where the search started.") - -(defvar evil-ex-search-overlay nil - "The overlay for the current search result.") - -(defvar evil-ex-search-pattern nil - "The last search pattern.") - -(defvar evil-ex-search-offset nil - "The last search offset.") - -(defvar evil-ex-search-match-beg nil - "The beginning position of the last match.") - -(defvar evil-ex-search-match-end nil - "The end position of the last match.") - -(defvar evil-ex-substitute-pattern nil - "The last substitute pattern.") - -(defvar evil-ex-substitute-replacement nil - "The last substitute replacement.") - -(defvar evil-ex-substitute-flags nil - "The last substitute flags.") - -(defvar evil-ex-substitute-current-replacement nil - "The actual replacement.") - -(defvar evil-ex-last-was-search nil - "Non-nil if the previous was a search. -Otherwise the previous command is assumed as substitute.") - -;; The lazy-highlighting framework -(evil-define-local-var evil-ex-active-highlights-alist nil - "An alist of currently active highlights.") - -(evil-define-local-var evil-ex-hl-update-timer nil - "Time used for updating highlights.") - -(defvar evil-ex-search-keymap (make-sparse-keymap) - "Keymap used in ex-search-mode.") - -(defcustom evil-want-empty-ex-last-command t - "Whether to default to evil-ex-previous-command at empty ex prompt." - :type 'boolean - :group 'evil) - -(defconst evil-version - (eval-when-compile - (with-temp-buffer - (let ((dir (file-name-directory (or load-file-name - byte-compile-current-file)))) - ;; git repository - (if (and (file-exists-p (concat dir "/.git")) - (ignore-errors - (zerop (call-process "git" nil '(t nil) nil - "rev-parse" - "--short" "HEAD")))) - (progn - (goto-char (point-min)) - (concat "evil-git-" - (buffer-substring (point-min) - (line-end-position)))) - ;; no repo, use plain version - "1.15.0")))) - "The current version of Evil") - -(defcustom evil-want-integration t - "Whether to load evil-integration.el. -This variable must be set before Evil is loaded." - :type 'boolean - :group 'evil) - -(defcustom evil-want-keybinding t - "Whether to load evil-keybindings.el. - -This loads a set of keybindings for evil in other modes as well as -setting the initial evil state in those modes. - -This variable must be set before evil is loaded." - :type 'boolean - :group 'evil) - -(defcustom evil-want-minibuffer nil - "Whether to enable Evil in minibuffer(s)." - :type 'boolean - :group 'evil - :set #'(lambda (sym value) - (set-default sym value) - (if value - (add-hook 'minibuffer-setup-hook 'evil-initialize) - (remove-hook 'minibuffer-setup-hook 'evil-initialize)))) - -(defun evil--redo-placeholder (_count) - (user-error "Customize `evil-undo-system' for redo functionality.")) - -(defvar evil-undo-function #'undo - "Function to be used by `evil-undo'. -Customized via `evil-undo-system'.") - -(defvar evil-redo-function #'evil--redo-placeholder - "Function to be used by `evil-redo'. -Customized via `evil-undo-system'.") - -(defun evil-set-undo-system (system) - "Set `evil-undo-function' and `evil-redo-function' by SYSTEM." - (cond - ((not system) - (setq evil-undo-function #'undo - evil-redo-function #'evil--redo-placeholder)) - ((eq system 'undo-redo) - (setq evil-undo-function #'undo-only - evil-redo-function #'undo-redo)) - ((eq system 'undo-tree) - (setq evil-undo-function 'undo-tree-undo - evil-redo-function 'undo-tree-redo)) - ((eq system 'undo-fu) - (setq evil-undo-function 'undo-fu-only-undo - evil-redo-function 'undo-fu-only-redo)) - (t (error "Unknown undo system `%s'" system)))) - -(defcustom evil-undo-system nil - "Undo system Evil should use. -If equal to `undo-tree' or `undo-fu', those packages must be -installed. If equal to `undo-tree', `undo-tree-mode' must also be -activated. If equal to `undo-redo', Evil uses commands natively -available in Emacs 28." - :type '(choice (const :tag "Vanilla undo" nil) - (const undo-redo) - (const undo-tree) - (const undo-fu)) - :group 'evil - :set #'(lambda (sym value) - (evil-set-undo-system value) - (set-default sym value))) - -(defcustom evil-visual-update-x-selection-p t - "Whether to update the X PRIMARY selection with the current visual region." - :type 'boolean - :group 'evil) - -(defun evil-version () - (interactive) - (message "Evil version %s" evil-version)) - -(provide 'evil-vars) - -;;; evil-vars.el ends here diff --git a/.config/emacs/lisp/evil/evil.el b/.config/emacs/lisp/evil/evil.el deleted file mode 100644 index 757a564..0000000 --- a/.config/emacs/lisp/evil/evil.el +++ /dev/null @@ -1,158 +0,0 @@ -;;; evil.el --- Extensible vi layer -*- lexical-binding: t; -*- - -;; The following list of authors was kept up to date until the beginning of -;; 2017, when evil moved under new maintainers. For authors since then, please -;; consult the git logs. - -;; Alessandro Piras <laynor at gmail.com> -;; Alexander Baier <alexander.baier at mailbox.org> -;; Antono Vasiljev <antono.vasiljev at gmail.com> -;; Bailey Ling <bling at live.ca> -;; Barry O'Reilly <gundaetiapo at gmail.com> -;; Christoph Lange <langec at web.de> -;; Daniel Reiter <danieltreiter at gmail.com> -;; Eivind Fonn <evfonn at gmail.com> -;; Emanuel Evans <emanuel.evans at gmail.com> -;; Eric Siegel <siegel.eric at gmail.com> -;; Eugene Yaremenko <w3techplayground at gmail.com> -;; Frank Fischer <frank-fischer at shadow-soft.de> -;; Frank Terbeck <ft at bewatermyfriend.org> -;; Gordon Gustafson <gordon3.14 at gmail.com> -;; Herbert Jones <jones.herbert at gmail.com> -;; Jonas Bernoulli <jonas at bernoul.li> -;; Jonathan Claggett <jclaggett at lonocloud.com> -;; José A. Romero L. <escherdragon at gmail.com> -;; Justin Burkett <justin at burkett.cc> -;; Lars Andersen <expez at expez.com> -;; Lintaro Ina <tarao.gnn at gmail.com> -;; Lukasz Wrzosek <wrzoski at mail.com> -;; Marian Schubert <maio at netsafe.cz> -;; Matthew Malcomson <> -;; Michael Markert <markert.michael at googlemail.com> -;; Mike Gerwitz <mikegerwitz at gnu.org> -;; Nikolai Weibull <now at bitwi.se> -;; phaebz <phaebz at gmail.com> -;; ralesi <scio62 at gmail.com> -;; Rodrigo Setti <rodrigosetti at gmail.com> -;; Sanel Zukan <sanelz at gmail.com> -;; Sarah Brofeldt <sarah at thinkmonster.(none)> -;; Simon Hafner <hafnersimon at gmail.com> -;; Stefan Wehr <mail at stefanwehr.de> -;; Sune Simonsen <sune.simonsen at jayway.com> -;; Thomas Hisch <thomas at opentech.at> -;; Tim Harper <timcharper at gmail.com> -;; Tom Willemse <tom at ryuslash.org> -;; Trevor Murphy <trevor.m.murphy at gmail.com> -;; Ulrich Müller <ulm at gentoo.org> -;; Vasilij Schneidermann <v.schneidermann at gmail.com> -;; Vegard Øye <vegard_oye at hotmail.com> -;; Winfred Lu <winfred.lu at gmail.com> -;; Wolfgang Jenkner <wjenkner at inode.at> -;; Xiao Hanyu <xiaohanyu1988 at gmail.com> -;; York Zhao <yzhao at telecor.com> - -;; The following line is included for NonGNU ELPA's build script: -;; Maintainer: Tom Dalziel <tom.dalziel@gmail.com> - -;; Maintainers: The emacs-evil team. <https://github.com/orgs/emacs-evil/people> -;; To get in touch, please use the bug tracker or the -;; mailing list (see below). -;; Created: 2011-03-01 -;; Version: 1.15.0 -;; Package-Requires: ((emacs "24.1") (cl-lib "0.5") (goto-chg "1.6") (nadvice "0.3")) -;; Keywords: emulations -;; URL: https://github.com/emacs-evil/evil -;; Repository: https://github.com/emacs-evil/evil.git -;; EmacsWiki: http://www.emacswiki.org/emacs/Evil -;; Bug tracker: https://github.com/emacs-evil/evil/issues -;; If you have bug reports, suggestions or patches, please -;; create an issue at the bug tracker (open for everyone). -;; Other discussions (tips, extensions) go to the mailing list. -;; Mailing list: <implementations-list at lists.ourproject.org> -;; Subscribe: http://tinyurl.com/implementations-list -;; Newsgroup: nntp://news.gmane.org/gmane.emacs.vim-emulation -;; Archives: http://dir.gmane.org/gmane.emacs.vim-emulation -;; You don't have to subscribe to post; we usually reply -;; within a few days and CC our replies back to you. -;; -;; This file is NOT part of GNU Emacs. - -;;; License: - -;; This file is part of Evil. -;; -;; Evil is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. -;; -;; Evil is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with Evil. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; Evil is an extensible vi layer for Emacs. It emulates the main -;; features of Vim, and provides facilities for writing custom -;; extensions. -;; -;; Evil lives in a Git repository. To obtain Evil, do -;; -;; git clone git://github.com/emacs-evil/evil.git -;; -;; Move Evil to ~/.emacs.d/evil (or somewhere else in the `load-path'). -;; Then add the following lines to ~/.emacs: -;; -;; (add-to-list 'load-path "~/.emacs.d/evil") -;; (require 'evil) -;; (evil-mode 1) -;; -;; Evil requires undo-redo (Emacs 28), undo-fu or undo-tree for redo -;; functionality. Otherwise, Evil uses regular Emacs undo. -;; -;; https://codeberg.org/ideasman42/emacs-undo-fu -;; https://melpa.org/#/undo-fu -;; https://gitlab.com/tsc25/undo-tree -;; https://elpa.gnu.org/packages/undo-tree.html -;; -;; Evil requires `goto-last-change' and `goto-last-change-reverse' -;; function for the corresponding motions g; g, as well as the -;; last-change-register `.'. One package providing these functions is -;; goto-chg.el: -;; -;; https://github.com/emacs-evil/goto-chg -;; https://melpa.org/#/goto-chg -;; https://elpa.nongnu.org/nongnu/goto-chg.html -;; -;; Without this package the corresponding motions will raise an error. - -;;; Code: - -(require 'evil-vars) -(require 'evil-common) -(require 'evil-core) -(require 'evil-states) -(require 'evil-repeat) -(require 'evil-macros) -(require 'evil-search) -(require 'evil-ex) -(require 'evil-types) -(require 'evil-commands) -(require 'evil-jumps) -(require 'evil-maps) - -(when evil-want-integration - (require 'evil-integration)) - -(when evil-want-keybinding - (require 'evil-keybindings)) - -(run-hooks 'evil-after-load-hook) - -(provide 'evil) - -;;; evil.el ends here diff --git a/.config/emacs/lisp/evil/scripts/evil-extract-docstrings b/.config/emacs/lisp/evil/scripts/evil-extract-docstrings deleted file mode 100755 index 55dbd79..0000000 --- a/.config/emacs/lisp/evil/scripts/evil-extract-docstrings +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env -S emacs --script - -(setq cur-path (file-name-directory load-file-name)) - -(add-to-list 'load-path (expand-file-name ".." cur-path)) -(require 'evil) -(require 'evil-digraphs) -(require 'json) -(require 'help) - -(defun mark-command-keys (string) - "Mark key bindings in STRING with the \":kbd:\" Sphinx role." - (when string - (cl-loop - for prev = 0 then pos until (>= prev (length string)) - for pos = (next-single-property-change prev 'face string (length string)) - concat - (let ((s (substring string prev pos))) - (if (eq (get-text-property prev 'face string) 'help-key-binding) - (format ":kbd:`%s`" s) - s))))) - -(let (vars) - (mapatoms - (lambda (sym) - (when (string-prefix-p "evil-" (symbol-name sym)) - (let ((default (eval (car (get sym 'standard-value))))) - (push `(,sym (default . ,(cond - ((consp default) (format "%S" default)) - ((symbolp default) (symbol-name default)) - (t default))) - (local . ,(local-variable-if-set-p sym)) - (default-type . ,(type-of default)) - (var-docstring . ,(mark-command-keys (documentation-property sym 'variable-documentation))) - (fn-docstring . ,(ignore-errors (mark-command-keys (documentation sym)))) - (arglist . ,(help-function-arglist sym)) - (functionp . ,(functionp sym)) - (macrop . ,(macrop sym))) - vars))))) - (with-temp-file (expand-file-name "../doc/docstringdb.json" cur-path) - (insert (json-encode vars)))) diff --git a/.config/emacs/lisp/evil/scripts/evil-release-stable b/.config/emacs/lisp/evil/scripts/evil-release-stable deleted file mode 100755 index c075903..0000000 --- a/.config/emacs/lisp/evil/scripts/evil-release-stable +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env ruby - -# Copyright (c) 2015 Frank Fischer <frank-fischer@shadow-soft.de> -# -# This program is free software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/> - - -# This script releases a new (minor) stable release given that some -# new commits on the stable branch since the last tag exist. - -Dir.chdir File.dirname(__FILE__) - -def die(msg = "Failed") - STDERR.puts msg - exit 1 -end - -def run(cmd) - system(cmd) or die(cmd) -end - -run 'hg pull' -run 'hg update -r stable' - -tag = `hg tags`.split("\n").select{|line| line =~ /^\d+\.\d+\.\d+/}.map do |line| - tag, rev = line.split - major, minor, tiny = tag.split(/\./).map(&:to_i) - [major, minor, tiny, rev[/\d+/].to_i] -end.max - -tag or die 'No tagged revision found' - -stable = `hg log -r 'branch(stable) and not file("../.hgtags") and not ..tag("re:\\d+\\.\\d+\\.\\d+")' | wc -l`.to_i != 0 - -if stable - new_tag = "#{tag[0]}.#{tag[1]}.#{tag[2]+1}" - run "make -C .. nversion VERSION='#{new_tag}'" - run "hg commit -m 'update version to #{new_tag}'" - run "hg tag -m 'version #{new_tag}' -r stable #{new_tag}" - run "hg push -r stable" -end diff --git a/.config/emacs/lisp/evil/scripts/evilupdate b/.config/emacs/lisp/evil/scripts/evilupdate deleted file mode 100755 index 27e832b..0000000 --- a/.config/emacs/lisp/evil/scripts/evilupdate +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/emacs --script -;;; evilupate.el -- Publishing script for Evil - -;;; Header: - -;; This file is not part of Emacs - -;; Author: Frank Fischer <frank-fischer@shadow-soft.de> -;; Maintainer: Frank Fischer <frank-fischer@shadow-soft.de> -;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (s "1.9.0") (f "0.17.2") yaoddmuse) - -;; The contents of this file are subject to the GPL License, Version 3.0. - -;; Copyright (C) 2015, 2016, Frank Fischer - -;; This program is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; This is a small script to update Evil's version at certain places: -;; -;; - topic of the IRC channel #evil-mode in irc.libera.chat -;; - EmacsWiki page -;; - header of all source files -;; - the ELPA package file -;; -;; The script should be invoked with the new version string -;; -;; evil-update.el 1.2.3 -;; - -;;; Code: - -(package-initialize) - -(require 'f) -(require 'erc) -(require 'yaoddmuse) - -(defconst evilupdate-irc-nick "lyrobot") -(defconst evilupdate-irc-channel "#evil-mode") -(defconst evilupdate-irc-topic - "Evil = Extensible vi layer for Emacs | Current version: VERSION | https://github.com/emacs-evil/evil | If you don't get an answer here, please use the mailing-list implementations-list@lists.ourproject.org") -(defconst evilupdate-wiki-page "Evil") -(defvar evilupdate-version "1.0.0") -(defvar evilupdate-done nil) - -(defun evilupdate-wait () - "Wait until `evilupdate-done' is set to t." - (while (not evilupdate-done) - (sleep-for 1)) - (setq evilupdate-done nil)) - -(defun evilupdate-done () - "Set `evilupdate-done' to t to stop the corresponding `evilupdate-wait'." - (setq evilupdate-done t)) - -(defun evilupdate-update-irc () - "Update the topic of the IRC channel." - (let ((erc-nick evilupdate-irc-nick) - (erc-autojoin-channels-alist nil) - (auth-sources nil)) - (erc-tls :server "irc.libera.chat" :port "6697" :nick evilupdate-irc-nick) - (add-hook 'erc-join-hook - (lambda () - (let (case-fold-search) - (erc-set-topic (replace-regexp-in-string "VERSION" - evilupdate-version - evilupdate-irc-topic - nil t))) - (erc-quit-server "") - (sleep-for 5) - (evilupdate-done))) - (erc-join-channel evilupdate-irc-channel) - (evilupdate-wait))) - -(defun evilupdate-wiki-trace (page-buffer-name) - "Callback for updating the EmacsWiki page in buffer PAGE-BUFFER-NAME." - (with-current-buffer page-buffer-name - (goto-char (point-min)) - (when (re-search-forward "Current stable version: \\*\\*\\([^*]*\\)\\*\\*") - (goto-char (match-beginning 1)) - (delete-region (match-beginning 1) (match-end 1)) - (insert evilupdate-version) - (yaoddmuse-post-buffer (current-buffer) evilupdate-version nil) - (evilupdate-done)))) - -(unless (require 'nadvice nil t) - (defadvice yaoddmuse-display-page (around evilupdate activate) - (evilupdate-wiki-trace (ad-get-arg 0)))) - -(defun evilupdate-update-emacswiki () - "Update the version information on the EmacsWiki page." - (setq yaoddmuse-wikis - '(("EmacsWiki" "https://www.emacswiki.org/emacs" utf-8 "uihnscuskc=1;"))) - (when (featurep 'nadvice) - (advice-add 'yaoddmuse-display-page :after 'evilupdate-wiki-trace)) - (yaoddmuse-edit "EmacsWiki" evilupdate-wiki-page t) - (evilupdate-wait)) - -(defun evilupdate-update-regexp (file regexp) - "Update version tag in FILE. -The version tag is defined by the REGEXP, in particular by the first -match group." - (find-file file) - (goto-char (point-min)) - (when (re-search-forward regexp nil t) - (goto-char (match-beginning 1)) - (delete-region (match-beginning 1) (match-end 1)) - (insert evilupdate-version) - (save-buffer))) - -(defun evilupdate-update-files () - "Replace version comments in all source files." - (dolist (file (f-glob "*.el")) - (evilupdate-update-regexp file ";;\\s-*Version:\\s-*\\([^\n]+\\)"))) - -(defun evilupdate-update-pkg () - "Replace version in package file." - (evilupdate-update-regexp "evil-pkg.el" "\"evil\"[ \t\n\r]*\"\\([^\"]+\\)\"")) - -(defun evilupdate-update-var () - "Replace version in `evil-version' variable." - (evilupdate-update-regexp - "evil-vars.el" - "t \"\\([^\"]*\\)\"[) \n\r\t]*\"The current version of Evil")) - -(defun evilupdate-update-news () - "Send an posting to the mailing list." - (shell-command (concat "thunderbird -compose \"newsgroups=gmane.emacs.vim-emulation,preselectid=id2,subject='[ANN] Evil version " evilupdate-version " released',body='" - "Evil version " evilupdate-version " has been released. - -The stable version can be installed from MELPA stable [1] and NonGNU ELPA [2]. -The latest development version is available from MELPA [3]. - -The Evil developers. - -[1] http://stable.melpa.org -[2] https://elpa.nongnu.org/nongnu/evil.html -[3] http://melpa.org -'\""))) - -(defun evilupdate-update (version nonews) - "Update Evil to VERSION. -If NONEWS is non-nil do not post a message to the newsgroup." - (setq evilupdate-cnt 0) - (setq evilupdate-version version) - (evilupdate-update-emacswiki) - (evilupdate-update-irc) - (evilupdate-update-files) - (evilupdate-update-pkg) - (evilupdate-update-var) - (unless nonews (evilupdate-update-news))) - -(cond - ((= (length argv) 2) - (unless (equal (car argv) "nonews") - (user-error "Usage: evilupdate.el [-n] VERSION")) - (evilupdate-update (cadr argv) t)) - ((= (length argv) 1) - (evilupdate-update (cadr argv))) - (t - (user-error "Usage: evilupdate.el [-n] VERSION"))) - -;;; evilupdate.el ends here |
