Initial commit

This commit is contained in:
2016-12-27 19:38:56 -07:00
commit bace104fdd
1636 changed files with 125236 additions and 0 deletions

View File

@@ -0,0 +1 @@
/doc/tags

View File

@@ -0,0 +1,2 @@
--color
--format d

View File

@@ -0,0 +1,11 @@
sudo: false
language: ruby
addons:
apt:
packages:
- vim-gtk
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"

View File

@@ -0,0 +1,109 @@
## 2.2 (06/10/2013)
Bugfixes:
- Fix plugin break in PASTE mode. This fixes #44.
## 2.1 (04/26/2013)
Bugfixes:
- Fix 1 regression where cursors could potentially get out of sync in insert mode
Features:
- Added some logic to debug latency. Fanning out to 30 cursors in insert mode with my vimrc took over 300ms. It's like than 20ms with a plain vimrc. Need to debug what setting is causing the slowing down in insert mode and inform users.
## 2.0 (04/24/2013)
Bugfixes:
- Fix inconsistent undo behavior. Changes made in multicursor insert mode are now undone together. This fixes #22.
- Single key commands that do not terminate properly no longer cause ghostly cursors to linger on screen. An error message is now displayed informing the user the number of cursor locations that the input cannot be properly played back at. This fixes #28.
## 1.16 (04/23/2013)
Features:
- Add integration tests using vimrunner. Hook up travis-ci to run continous integration on commit.
## 1.15 (04/22/2013)
Bugfixes:
- Fix plugin causing error bell. This fixes #29.
## 1.14 (04/22/2013)
Features:
- Allow users to separate start key from next key. (credit: @xanderman)
## 1.13 (04/22/2013)
Bugfixes:
- Add support for switching to visual line mode from inside multicursor mode
- Fix highlight issue where extra character at end of line is highlighted for visual selections covering more than 2 lines.
## 1.12 (04/19/2013)
Bugfixes:
- Fix tab character causing highlight errors. This fixes #18 and fixes #32
## 1.11 (04/18/2013)
Bugfixes:
- Fix regression where `C-n` doesn't exhibit correct behavior when all matches have been found
- Clear echo messages when a new input is received
## 1.10 (04/17/2013)
Bugfixes:
- `O` works now in normal mode. This fixes #24
- Turn on `lazyredraw` during multicursor mode to prevent the sluggish screen redraws
Features:
- Add command **MultipleCursorsFind** to add multiple virtual cursors using regexp. This closes #20
## 1.9 (04/17/2013)
Bugfixes:
- Fix starting multicursor mode in visual line mode. This fixes #25
- Major refactoring to avoid getting in and out of visual mode as much as possible
## 1.8 (04/16/2013)
Bugfixes:
- Fix regression that causes call stack to explode with too many cursors
## 1.7 (04/15/2013)
Bugfixes:
- Finally fix the annoying highlighting problem when the last virtual cursor is on the last character of the line. The solution is a hack, but it should be harmless
## 1.6 (04/15/2013)
Bugfixes:
- Stop chaining dictionary function calls. This fixes #10 and #11
## 1.5 (04/15/2013)
Bugfixes:
- Exit Vim's visual mode before waiting for user's next input. This fixes #14
## 1.4 (04/14/2013)
Bugfixes:
- Don't use clearmatches(). It clears highlighting from other plugins. This fixes #13
## 1.3 (04/14/2013)
Bugfixes:
- Change mapping from using expression-quote syntax to using raw strings
## 1.2 (04/14/2013)
Bugfixes:
- Restore view when exiting from multicursor mode. This fixes #5
- Remove the unnecessary user level mapping for 'prev' and 'skip' in visual mode, since we can purely detect those keys from multicursor mode
## 1.1 (04/14/2013)
Bugfixes:
- Stop hijacking escape key in normal mode. This fixes #1, #2, and #3
## 1.0 (04/13/2013)
Initial release

View File

@@ -0,0 +1,23 @@
# Problems summary
## Expected
## Environment Information
* OS:
* Neovim/Vim/Gvim version:
## Provide a minimal .vimrc with less than 50 lines
" Your minimal.vimrc
## Generate a logfile if appropriate
1. export NVIM_PYTHON_LOG_FILE=/tmp/log
2. export NVIM_PYTHON_LOG_LEVEL=DEBUG
3. nvim -u minimal.vimrc
4. recreate your issue
5. cat /tmp/log_{PID}
## Screen shot (if possible)
## Upload the log file

View File

@@ -0,0 +1,4 @@
source 'https://rubygems.org'
gem 'vimrunner'
gem 'rake'
gem 'rspec'

View File

@@ -0,0 +1,30 @@
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.2.5)
rake (10.4.2)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.1)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
vimrunner (0.3.1)
PLATFORMS
ruby
DEPENDENCIES
rake
rspec
vimrunner
BUNDLED WITH
1.10.6

View File

@@ -0,0 +1,20 @@
Copyright 2013 Terry Ma
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,244 @@
# vim-multiple-cursors
[![Build Status](https://travis-ci.org/terryma/vim-multiple-cursors.svg)](https://travis-ci.org/terryma/vim-multiple-cursors)
[![Issue Stats](http://issuestats.com/github/terryma/vim-multiple-cursors/badge/pr?style=flat)](http://issuestats.com/github/terryma/vim-multiple-cursors)
[![Issue Stats](http://issuestats.com/github/terryma/vim-multiple-cursors/badge/issue?style=flat)](http://issuestats.com/github/terryma/vim-multiple-cursors)
## Contents
- [About](#about)
- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Mapping](#mapping)
- [Settings](#settings)
- [Interactions with other plugins](#interactions-with-other-plugins)
- [Highlight](#highlight)
- *[FAQ](#faq)*
- *[Known issues](#known-issues)*
- *[Issue creation requirements](#issue-creation-requirements)*
- [Changelog](#changelog)
- [Contributing](#contributing)
- [Credit](#credit)
###Contributors
- [eapache](https://github.com/eapache)
- [aschrab](https://github.com/aschrab)
- [kristijanhusak](https://github.com/kristijanhusak)
- [faceleg](https://github.com/faceleg)
## About
[There](https://github.com/paradigm/vim-multicursor) [have](https://github.com/felixr/vim-multiedit) [been](https://github.com/hlissner/vim-multiedit) [many](https://github.com/adinapoli/vim-markmultiple) [attempts](https://github.com/AndrewRadev/multichange.vim) at bringing Sublime Text's awesome [multiple selection][sublime-multiple-selection] feature into Vim, but none so far have been in my opinion a faithful port that is simplistic to use, yet powerful and intuitive enough for an existing Vim user. [vim-multiple-cursors] is yet another attempt at that.
### It's great for quick refactoring
![Example1](assets/example1.gif?raw=true)
Vim command sequence: `2Gfp<C-n><C-n><C-n>cname`
### Add a cursor to each line of your visual selection
![Example2](assets/example2.gif?raw=true)
Vim command sequence: `2Gvip<C-n>i"<Right><Right><Right>",<Esc>vipJ$r]Idays = [`
### Do it backwards too! This is not just a replay of the above gif :)
![Example3](assets/example3.gif?raw=true)
Vim command sequence: `2Gdf[$r,0f,v<C-n>…<C-n>c<CR><Up><Del><Right><Right><Right><Del>`
### Add multiple cursors using regexes
![Example4](assets/example4.gif?raw=true)
To see what keystrokes are used for the above examples, see [the wiki page](https://github.com/terryma/vim-multiple-cursors/wiki/Keystrokes-for-example-gifs).
## Features
- Live update in Insert mode
- One key to rule it all! See [Quick Start](#quick-start) on what the key does in different scenarios
- Works in Normal, Insert, and Visual mode for any commands (including
multi-key commands, assuming you set `g:multicursor_insert_maps` and
`g:multicursor_normal_maps`; see Settings below for details)
## Installation
Install using [Pathogen], [Vundle], [Neobundle], or your favorite Vim package manager.
Requires vim 7.4 or later for full functionality.
## Quick Start
Out of the box, all you need to know is a single key `Ctrl-n`. Pressing the key in Normal mode highlights the current word under the cursor in Visual mode and places a virtual cursor at the end of it. Pressing it again finds the next occurrence and places another virtual cursor at the end of the visual selection. If you select multiple lines in Visual mode, pressing the key puts a virtual cursor at every line and leaves you in Normal mode.
After you've marked all your locations with `Ctrl-n`, you can change the visual selection with normal Vim motion commands in Visual mode. You could go to Normal mode by pressing `v` and wield your motion commands there. Single key command to switch to Insert mode such as `c` or `s` from Visual mode or `i`, `a`, `I`, `A` in Normal mode should work without any issues.
At any time, you can press `<Esc>` to exit back to regular Vim.
Two additional keys are also mapped:
- `Ctrl-p` in Visual mode will remove the current virtual cursor and go back to the previous virtual cursor location. This is useful if you are trigger happy with `Ctrl-n` and accidentally went too far.
- `Ctrl-x` in Visual mode will remove the current virtual cursor and skip to the next virtual cursor location. This is useful if you don't want the current selection to be a candidate to operate on later.
You can also add multiple cursors using a regular expression. The command `MultipleCursorsFind` accepts a range and a pattern, and it will create a virtual cursor at the end of every match within the range. If no range is passed in, then it defaults to the entire buffer.
**NOTE:** If at any time you have lingering cursors on screen, you can press `Ctrl-n` in Normal mode and it will remove all prior cursors before starting a new one.
## Mapping
Out of the box, only the single key `Ctrl-n` is mapped in regular Vim's Normal mode and Visual mode to provide the functionality mentioned above. `Ctrl-n`, `Ctrl-p`, `Ctrl-x`, and `<Esc>` are mapped in the special multicursor mode once you've added at least one virtual cursor to the buffer. If you don't like the plugin taking over your favorite key bindings, you can turn off the default with
```viml
let g:multi_cursor_use_default_mapping=0
```
You can then map the 'next', 'previous', 'skip', and 'exit' keys like the following:
```viml
" Default mapping
let g:multi_cursor_next_key='<C-n>'
let g:multi_cursor_prev_key='<C-p>'
let g:multi_cursor_skip_key='<C-x>'
let g:multi_cursor_quit_key='<Esc>'
```
By default, the 'next' key is also used to enter multicursor mode. If you want to use a different key to start multicursor mode than for selecting the next location, do like the following:
```viml
" Map start key separately from next key
let g:multi_cursor_start_key='<F6>'
```
Note that when multicursor mode is started, it selects current word with boundaries, i.e. it behaves like `*`. If you want to avoid word boundaries in Normal mode (as `g*` does) but still have old behaviour up your sleeve, you can do the following:
```viml
let g:multi_cursor_start_key='<C-n>'
let g:multi_cursor_start_word_key='g<C-n>'
```
In this configuration `<C-n>` will start multicursor mode without word boundaries (but only in Normal mode, as it does not make much sense to use it in Visual mode). Old behaviour with word boundaries is still available using `g<C-n>`.
**IMPORTANT:** Please note that currently only single keystrokes and special keys can be mapped. This means that a mapping like `<Leader>n` will NOT work correctly. For a list of special keys that are supported, see `help :key-notation`
**NOTE:** Please make sure to always map something to `g:multi_cursor_quit_key`, otherwise you'll have a tough time quitting from multicursor mode.
**NOTE:** Prior to version 1.3, the recommended way to map the keys is using the expression quote syntax in Vim, using something like `"\<C-n>"` or `"\<Esc>"` (see h: expr-quote). After 1.3, the recommended way is to use a raw string like above. If your key mappings don't appear to work, give the new syntax a try.
You can also map your own keys to quit, if ``g:multi_cursor_quit_key`` won't work:
```
let g:multi_cursor_quit_key='<C-c>'
nnoremap <C-c> :call multiple_cursors#quit()<CR>
```
## Settings
Currently there are four additional global settings one can tweak:
### ```g:multi_cursor_exit_from_visual_mode``` (Default: 1)
If set to 0, then pressing `g:multi_cursor_quit_key` in _Visual_ mode will not quit and delete all existing cursors. This is useful if you want to press Escape and go back to Normal mode, and still be able to operate on all the cursors.
### ```g:multi_cursor_exit_from_insert_mode``` (Default: 1)
If set to 0, then pressing `g:multi_cursor_quit_key` in _Insert_ mode will not quit and delete all existing cursors. This is useful if you want to press Escape and go back to Normal mode, and still be able to operate on all the cursors.
### ```g:multi_cursor_insert_maps``` (Default: `{}`)
Any key in this map (values are ignored) will cause multi-cursor _Insert_ mode
to pause for `timeoutlen` waiting for map completion just like normal vim.
Otherwise keys mapped in insert mode are ignored when multiple cursors are
active. For example, setting it to `{'\':1}` will make insert-mode mappings
beginning with the default leader key work in multi-cursor mode. You have to
manually set this because vim doesn't provide a way to see which keys _start_
mappings.
### ```g:multi_cursor_normal_maps``` (Default: see below)
Default value: `{'!':1, '@':1, '=':1, 'q':1, 'r':1, 't':1, 'T':1, 'y':1, '[':1, ']':1, '\':1, 'd':1, 'f':1, 'F':1, 'g':1, '"':1, 'z':1, 'c':1, 'm':1, '<':1, '>':1}`
Any key in this map (values are ignored) will cause multi-cursor _Normal_ mode
to pause for map completion just like normal vim. Otherwise keys mapped in
normal mode will "fail to replay" when multiple cursors are active. For example,
changing it from `{}` to `{'d':1}` makes normal-mode mappings beginning with `d`
(such as `dw` to delete a word) work in multi-cursor mode.
### ```g:multi_cursor_visual_maps``` (Default: see below)
Default value: `{'i':1, 'a':1, 'f':1, 'F':1, 't':1, 'T':1}`
Any key in this map (values are ignored) will cause multi-cursor _Visual_ mode
to pause for map completion just like normal vim. Otherwise keys mapped in
visual mode will "fail to replay" when multiple cursors are active. For example,
changing it from `{}` to `{'i':1}` makes visual-mode mappings beginning with `i`
(such as `it` to select an "inner tag block") work in multi-cursor mode.
The default list contents should work for anybody, unless they have remapped a
key from an operator-pending command to a non-operator-pending command or
vice versa.
These keys must be manually listed because vim doesn't provide a way to
automatically see which keys _start_ mappings, and trying to run motion commands
such as `j` as if they were operator-pending commands can break things.
### Interactions with other plugins
### ```Multiple_cursors_before/Multiple_cursors_after``` (Default: `nothing`)
Other plugins may trigger on keypresses when in insert mode. These plugins
generally provide a means to toggle their active state. These hooks allow
the user to provide functions in their .vimrc to do this when multiple-cursor-mode
is entered.
For example, if you are using [Neocomplete](https://github.com/Shougo/neocomplete.vim),
add this to your vimrc to prevent conflict:
```viml
" Called once right before you start selecting multiple cursors
function! Multiple_cursors_before()
if exists(':NeoCompleteLock')==2
exe 'NeoCompleteLock'
endif
endfunction
" Called once only when the multiple selection is canceled (default <Esc>)
function! Multiple_cursors_after()
if exists(':NeoCompleteUnlock')==2
exe 'NeoCompleteUnlock'
endif
endfunction
```
With this locking and unlocking we prevent neocomplete to trigger it's function calls until we are finished with multiple cursors editing.
### Highlight
The plugin uses the highlight group `multiple_cursors_cursor` and `multiple_cursors_visual` to highlight the virtual cursors and their visual selections respectively. You can customize them by putting something similar like the following in your vimrc:
```viml
" Default highlighting (see help :highlight and help :highlight-link)
highlight multiple_cursors_cursor term=reverse cterm=reverse gui=reverse
highlight link multiple_cursors_visual Visual
```
## FAQ
#### **Q** <kbd>CTRL</kbd>+<kbd>n</kbd> doesn't seem to work in gVIM?
**A** Try setting `set selection=inclusive` in your `~/.gvimrc`
#### **Q** How can I select `n` keywords with several keystrokes? I have tried `200<C-n>` which does not work.
**A** You can use :MultipleCursorsFind keyword. I have this binding in my vimrc:
```VimL
nnoremap <silent> <M-j> :MultipleCursorsFind <C-R>/<CR>
vnoremap <silent> <M-j> :MultipleCursorsFind <C-R>/<CR>
```
This allows one to a) search for the keyword using `*` b) turn search results into cursors with `Alt-j`.
## Known Issues
- Select mode is not implemented
## Issue Creation Requirements
This is a community supported project. Contributor's time is precious and limited. To ensure your issue is not closed out of hand, please ensure it meets the requirements outlined in [CONTRIBUTING.md](CONTRIBUTING.md).
## Changelog
See [CHANGELOG.md](CHANGELOG.md)
## Contributing
As one can see, there're still many issues to be resolved, patches and suggestions are always welcome! A list of open feature requests can be found [here](../../issues?labels=enhancement&state=open).
Running the test suite requires ruby and rake as well as vim of course. On Mac
OS, [MacVim](https://code.google.com/p/macvim/) is known to work.
## Credit
Obviously inspired by Sublime Text's [multiple selection][sublime-multiple-selection] feature, also encouraged by Emac's [multiple cursors][emacs-multiple-cursors] implementation by Magnar Sveen
[vim-multiple-cursors]:http://github.com/terryma/vim-multiple-cursors
[sublime-multiple-selection]:http://www.sublimetext.com/docs/2/multiple_selection_with_the_keyboard.html
[Pathogen]:http://github.com/tpope/vim-pathogen
[Vundle]:http://github.com/gmarik/vundle
[Neobundle]:http://github.com/Shougo/neobundle.vim
[emacs-multiple-cursors]:https://github.com/magnars/multiple-cursors.el
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/terryma/vim-multiple-cursors/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

View File

@@ -0,0 +1,11 @@
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec) do |t|
t.pattern = 'spec/multiple_cursors_spec.rb'
end
RSpec::Core::RakeTask.new(:benchmark) do |t|
t.pattern = 'spec/benchmark_spec.rb'
end
task :default => :spec

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 KiB

View File

@@ -0,0 +1,253 @@
*vim-multiple-cursors.txt* True Sublime Text multiple selection in Vim
____ _ __
____ ___ __ __/ / /_(_)___ / /__ _______ ________________ __________
/ __ `__ \/ / / / / __/ / __ \/ / _ \ / ___/ / / / ___/ ___/ __ \/ ___/ ___/
/ / / / / / /_/ / / /_/ / /_/ / / __/ / /__/ /_/ / / (__ ) /_/ / / (__ )
/_/ /_/ /_/\__,_/_/\__/_/ .___/_/\___/ \___/\__,_/_/ /____/\____/_/ /____/
/_/
Reference Manual~
==============================================================================
CONTENTS *multiple-cursors-contents*
1.Intro...................................|multiple-cursors-intro|
2.Usage...................................|multiple-cursors-usage|
3.Mappings................................|multiple-cursors-mappings|
4.Global Options..........................|multiple-cursors-global-options|
5.Issues..................................|multiple-cursors-issues|
6.Contributing............................|multiple-cursors-contributing|
7.License.................................|multiple-cursors-license|
8.Credit..................................|multiple-cursors-credit|
9.References..............................|multiple-cursors-references|
==============================================================================
1. Intro *multiple-cursors-intro*
There [1] have [2] been [3] many [4] attempts [5] at bringing Sublime Text's
awesome multiple selection [6] feature into Vim, but none so far have been in
my opinion a faithful port that is simplistic to use, yet powerful and
intuitive enough for an existing Vim user. *vim-multiple-cursors* is yet
another attempt at that.
==============================================================================
2. Usage *multiple-cursors-usage*
Out of the box, all you need to know is a single key CTRL-N. Pressing the key
in Normal mode highlights the current word under the cursor in Visual mode and
places a virtual cursor at the end of it. Pressing it again finds the next
ocurrence and places another virtual cursor at the end of the visual
selection. If you select multiple lines in Visual mode, pressing the key puts
a virtual cursor at every line and leaves you in Normal mode.
After you've marked all your locations with CTRL-N, you can change the visual
selection with normal Vim motion commands in Visual mode. You could go to
Normal mode by pressing v and wield your motion commands there. Single key
command to switch to Insert mode such as `c` or `s` from Visual mode or `i`,
`a`, `I`, `A` in Normal mode should work without any issues.
At any time, you can press <Esc> to exit back to regular Vim.
Two additional keys are also mapped:
CTRL-P in Visual mode will remove the current virtual cursor and go back to
the previous virtual cursor location. This is useful if you are trigger happy
with Ctrl-n and accidentally went too far.
CTRL-X in Visual mode will remove the current virtual cursor and skip to the
next virtual cursor location. This is useful if you don't want the current
selection to be a candidate to operate on later.
You can also add multiple cursors using a regular expression. The command
*MultipleCursorsFind* accepts a range and a pattern, and it will create a
virtual cursor at the end of every match within the range. If no range is
passed in, then it defaults to the entire buffer.
NOTE: If at any time you have lingering cursors on screen, you can press
CTRL-N in Normal mode and it will remove all prior cursors before starting a
new one.
==============================================================================
3. Mappings *multiple-cursors-mappings*
*g:multi_cursor_use_default_mapping* (Default: 1)
Out of the box, only the single key CTRL-N is mapped in regular Vim's Normal
mode and Visual mode to provide the functionality mentioned above. CTRL-N,
CTRL-P, CTRL-X, and <ESC> are mapped in the special multicursor mode once
you've added at least one virtual cursor to the buffer. If you don't like the
plugin taking over your favorite key bindings, you can turn off the default
with >
let g:multi_cursor_use_default_mapping=0
<
*g:multi_cursor_next_key* (Default: '<C-n>')
*g:multi_cursor_prev_key* (Default: '<C-p>')
*g:multi_cursor_skip_key* (Default: '<C-x>')
*g:multi_cursor_quit_key* (Default: '<Esc>')
You can map the 'next', 'previous', 'skip', and 'exit' keys like the
following: >
" Default mapping
let g:multi_cursor_next_key='<C-n>'
let g:multi_cursor_prev_key='<C-p>'
let g:multi_cursor_skip_key='<C-x>'
let g:multi_cursor_quit_key='<Esc>'
<
*g:multi_cursor_start_key* (Default: 'g:multi_cursor_next_key')
By default, the same key is used to enter multicursor mode as to select the
next cursor location. If you want to use a different key to start multicursor
mode than for selecting the next location, do like the following: >
" Map start key separately from next key
let g:multi_cursor_start_key='<F6>'
<
*g:multi_cursor_start_word_key*
When multicursor mode is started, it selects current word without
boundaries, i.e. it behaves like `g*`. If you want to use word boundaries in
Normal mode (as `*` does) but still have old behaviour up your sleeve, you can
do the following: >
let g:multi_cursor_start_key='g<C-n>'
let g:multi_cursor_start_word_key='<C-n>'
<
In this configuration <C-n> will start multicursor mode using word boundaries
(but only in Normal mode, as it does not make much sense to use it in Visual
mode). Old behaviour without word boundaries is still available using
g<C-n>.
IMPORTANT: Please note that currently only single keystrokes and special
keys can be mapped. This contraint is also the reason why multikey commands
such as `ciw` do not work and cause unexpected behavior in Normal mode. This
means that a mapping like `<Leader>n` will NOT work correctly. For a list of
special keys that are supported, see |key-notation|
NOTE: Please make sure to always map something to |g:multi_cursor_quit_key|,
otherwise you'll have a tough time quitting from multicursor mode.
NOTE: Prior to version 1.3, the recommended way to map the keys is using the
expression quote syntax in Vim, using something like `"\<C-n>"` or `"\<Esc>"`
(see h: expr-quote). After 1.3, the recommended way is to use a raw string
like above. If your key mappings don't appear to work, give the new syntax a
try.
==============================================================================
4. Global Options *multiple-cursors-global-options*
Currently there are four additional global settings one can tweak:
*g:multi_cursor_exit_from_visual_mode* (Default: 1)
If set to 0, then pressing |g:multi_cursor_quit_key| in Visual mode will not
quit and delete all existing cursors. This is useful if you want to press
Escape and go back to Normal mode, and still be able to operate on all the
cursors.
*g:multi_cursor_exit_from_insert_mode* (Default: 1)
If set to 0, then pressing |g:multi_cursor_quit_key| in Insert mode will not
quit and delete all existing cursors. This is useful if you want to press
Escape and go back to Normal mode, and still be able to operate on all the
cursors.
*g:multi_cursor_insert_maps* (Default: `{}`)
Any key in this map (values are ignored) will cause multi-cursor _Insert_ mode
to pause for `timeoutlen` waiting for map completion just like normal vim.
Otherwise keys mapped in insert mode are ignored when multiple cursors are
active. For example, setting it to `{'\':1}` will make insert-mode mappings
beginning with the default leader key work in multi-cursor mode. You have to
manually set this because vim doesn't provide a way to see which keys _start_
mappings.
*g:multi_cursor_normal_maps* (Default: see below)
Default value: `{'!':1, '@':1, '=':1, 'q':1, 'r':1, 't':1, 'T':1, 'y':1, '[':1, ']':1, '\':1, 'd':1, 'f':1, 'F':1, 'g':1, '"':1, 'z':1, 'c':1, 'm':1, '<':1, '>':1}`
Any key in this map (values are ignored) will cause multi-cursor _Normal_ mode
to pause for map completion just like normal vim. Otherwise keys mapped in
normal mode will "fail to replay" when multiple cursors are active. For example,
changing it from `{}` to `{'d':1}` makes normal-mode mappings beginning with `d`
(such as `dw` to delete a word) work in multi-cursor mode.
*g:multi_cursor_visual_maps* (Default: )
Default value: `{'i':1, 'a':1, 'f':1, 'F':1, 't':1, 'T':1}`
Any key in this map (values are ignored) will cause multi-cursor _Visual_ mode
to pause for map completion just like normal vim. Otherwise keys mapped in
visual mode will "fail to replay" when multiple cursors are active. For example,
changing it from `{}` to `{'i':1}` makes visual-mode mappings beginning with `i`
(such as `it` to select an "inner tag block") work in multi-cursor mode.
The default list contents should work for anybody, unless they have remapped a
key from an operator-pending command to a non-operator-pending command or
vice versa.
These keys must be manually listed because vim doesn't provide a way to
automatically see which keys _start_ mappings, and trying to run motion commands
such as `j` as if they were operator-pending commands can break things.
The plugin uses the highlight group `multiple_cursors_cursor` and
`multiple_cursors_visual` to highlight the virtual cursors and their visual
selections respectively. You can customize them by putting something similar
like the following in your vimrc: >
" Default highlighting (see help :highlight and help :highlight-link)
highlight multiple_cursors_cursor term=reverse cterm=reverse gui=reverse
highlight link multiple_cursors_visual Visual
<
==============================================================================
5. Issues *multiple-cursors-issues*
- Multi key commands like ciw do not work at the moment
- All user input typed before Vim is able to fan out the last operation to all
cursors is lost. This is a implementation decision to keep the input
perfectly synced in all locations, at the cost of potentially losing user
input.
- Select mode is not implemented
==============================================================================
6. Contributing *multiple-cursors-contributing*
The project is hosted on Github. Patches, feature requests and suggestions are
always welcome!
Find the latest version of the plugin here:
http://github.com/terryma/vim-multiple-cursors
==============================================================================
7. License *multiple-cursors-license*
The project is licensed under the MIT license [7]. Copyrigth 2013 Terry Ma
==============================================================================
8. Credit *multiple-cursors-credit*
The plugin is obviously inspired by Sublime Text's awesome multiple selection
[6] feature. Some inspiration was also taken from Emac's multiple cursors [8]
implementation.
==============================================================================
9. References *multiple-cursors-references*
[1] https://github.com/paradigm/vim-multicursor
[2] https://github.com/felixr/vim-multiedit
[3] https://github.com/hlissner/vim-multiedit
[4] https://github.com/adinapoli/vim-markmultiple
[5] https://github.com/AndrewRadev/multichange.vim
[6] http://www.sublimetext.com/docs/2/multiple_selection_with_the_keyboard.html
[7] http://opensource.org/licenses/MIT
[8] https://github.com/magnars/multiple-cursors.el
vim:tw=78:sw=4:ft=help:norl:

View File

@@ -0,0 +1,89 @@
"===============================================================================
" File: multiple_cursors.vim
" Author: Terry Ma
" Description: Emulate Sublime Text's multi selection feature
" Potential Features:
" - Create a blinking cursor effect? Good place to do it would be instead of
" waiting for user input, cycle through the highlight
" - Integrate with the status line? Maybe show a special multicursor mode?
" - Support mouse? Ctrl/Cmd click to set cursor?
"===============================================================================
let s:save_cpo = &cpo
set cpo&vim
function! s:init_settings(settings)
for [key, value] in items(a:settings)
let sub = ''
if type(value) == 0
let sub = '%d'
elseif type(value) == 1
let sub = '"%s"'
endif
let fmt = printf("let g:multi_cursor_%%s=get(g:, 'multi_cursor_%%s', %s)",
\ sub)
exec printf(fmt, key, key, value)
endfor
endfunction
" Settings
let s:settings = {
\ 'exit_from_visual_mode': 1,
\ 'exit_from_insert_mode': 1,
\ 'use_default_mapping': 1,
\ 'debug_latency': 0,
\ }
let s:settings_if_default = {
\ 'quit_key': '<Esc>',
\ 'next_key': '<C-n>',
\ 'prev_key': '<C-p>',
\ 'skip_key': '<C-x>',
\ }
let s:default_insert_maps = {}
let s:default_normal_maps = {'!':1, '@':1, '=':1, 'q':1, 'r':1, 't':1, 'T':1, 'y':1, '[':1, ']':1, '\':1, 'd':1, 'f':1, 'F':1, 'g':1, '"':1, 'z':1, 'c':1, 'm':1, '<':1, '>':1}
let s:default_visual_maps = {'i':1, 'a':1, 'f':1, 'F':1, 't':1, 'T':1}
let g:multi_cursor_insert_maps =
\ get(g:, 'multi_cursor_insert_maps', s:default_insert_maps)
let g:multi_cursor_normal_maps =
\ get(g:, 'multi_cursor_normal_maps', s:default_normal_maps)
let g:multi_cursor_visual_maps =
\ get(g:, 'multi_cursor_visual_maps', s:default_visual_maps)
call s:init_settings(s:settings)
if g:multi_cursor_use_default_mapping
call s:init_settings(s:settings_if_default)
endif
if !exists('g:multi_cursor_start_word_key')
if exists('g:multi_cursor_start_key')
let g:multi_cursor_start_word_key = g:multi_cursor_start_key
elseif exists('g:multi_cursor_next_key')
let g:multi_cursor_start_word_key = g:multi_cursor_next_key
endif
endif
" External mappings
if exists('g:multi_cursor_start_key')
exec 'nnoremap <silent> '.g:multi_cursor_start_key.
\' :call multiple_cursors#new("n", 0)<CR>'
exec 'xnoremap <silent> '.g:multi_cursor_start_key.
\' :<C-u>call multiple_cursors#new("v", 0)<CR>'
endif
if exists('g:multi_cursor_start_word_key')
exec 'nnoremap <silent> '.g:multi_cursor_start_word_key.
\' :call multiple_cursors#new("n", 1)<CR>'
" In Visual mode word boundary is not used
exec 'xnoremap <silent> '.g:multi_cursor_start_word_key.
\' :<C-u>call multiple_cursors#new("v", 0)<CR>'
endif
" Commands
command! -nargs=1 -range=% MultipleCursorsFind
\ call multiple_cursors#find(<line1>, <line2>, <q-args>)
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@@ -0,0 +1,142 @@
require 'vimrunner'
require 'vimrunner/rspec'
Vimrunner::RSpec.configure do |config|
# Use a single Vim instance for the test suite. Set to false to use an
# instance per test (slower, but can be easier to manage).
config.reuse_server = false
# Decide how to start a Vim instance. In this block, an instance should be
# spawned and set up with anything project-specific.
config.start_vim do
# vim = Vimrunner.start
# vim = Vimrunner::Server.new("/usr/local/bin/vim").start
# Or, start a GUI instance:
vim = Vimrunner.start_gvim
# Setup your plugin in the Vim instance
plugin_path = File.expand_path('../..', __FILE__)
vim.add_plugin(plugin_path, 'plugin/multiple_cursors.vim')
# The returned value is the Client available in the tests.
vim
end
end
def set_file_content(string)
string = normalize_string_indent(string)
File.open(filename, 'w'){ |f| f.write(string) }
vim.edit filename
end
def get_file_content()
vim.write
IO.read(filename).strip
end
def before(string)
set_file_content(string)
end
def after(string)
get_file_content().should eq normalize_string_indent(string)
type ":q<CR>"
end
def type(string)
string.scan(/<.*?>|./).each do |key|
if /<.*>/.match(key)
vim.feedkeys "\\#{key}"
else
vim.feedkeys key
end
end
sleep 0.2
end
describe "Multiple Cursors" do
let(:filename) { 'test.txt' }
let(:options) { [] }
specify "#benchmark" do
before <<-EOF
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
EOF
# type ':profile start /tmp/test.result<CR>'
# type ':profile! file *multiple_cursors.vim<CR>'
type ':let g:multi_cursor_debug_latency=1<CR>'
type 'VG<C-n>Vchellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello<Esc>'
type ':echo multiple_cursors#get_latency_debug_file()<CR>'
sleep 3
latency_file = vim.command 'echo multiple_cursors#get_latency_debug_file()'
puts 'latency file = ' + latency_file
after <<-EOF
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
EOF
end
end

View File

@@ -0,0 +1,800 @@
require 'spec_helper'
def set_file_content(string)
string = normalize_string_indent(string)
File.open(filename, 'w'){ |f| f.write(string) }
vim.edit filename
end
def get_file_content()
vim.write
IO.read(filename).strip
end
def before(string)
options.each { |x| vim.command(x) }
set_file_content(string)
end
def after(string)
expect(get_file_content()).to eq normalize_string_indent(string)
end
def type(string)
string.scan(/<.*?>|./).each do |key|
if /<.*>/.match(key)
vim.feedkeys "\\#{key}"
else
vim.feedkeys key
end
end
end
describe "Multiple Cursors op pending & exit from insert|visual mode" do
let(:filename) { 'test.txt' }
let(:options) { ['let g:multi_cursor_exit_from_insert_mode = 0',
'let g:multi_cursor_exit_from_visual_mode = 0'] }
# the default value of g:multi_cursor_normal_maps already works
# for testing operator-pending
specify "#paste from unnamed register to 3 cursors" do
before <<-EOF
yankme
a b c
a b c
a b c
EOF
type 'yiwj<C-n><C-n><C-n>vwwp<Esc>'
after <<-EOF
yankme
a b cyankme
a b cyankme
a b cyankme
EOF
end
specify "#paste buffer normal caw then p" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vwcaw<Esc>bP<Esc>'
after <<-EOF
jan hello world
feb hello world
mar hello world
EOF
end
specify "#paste buffer normal C then ABC then p" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vwCABC <Esc>p<Esc>'
after <<-EOF
hello ABC jan world
hello ABC feb world
hello ABC mar world
EOF
end
specify "#paste buffer normal daw then P" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vwdawbP<Esc>'
after <<-EOF
jan hello world
feb hello world
mar hello world
EOF
end
specify "#paste buffer normal D then P" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vwwhDbhP<Esc>'
after <<-EOF
hello world jan
hello world feb
hello world mar
EOF
end
specify "#paste buffer normal s then p" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vws1<Esc>p<Esc>'
after <<-EOF
hello 1jan world
hello 1feb world
hello 1mar world
EOF
end
end
describe "Multiple Cursors when normal_maps is empty" do
let(:filename) { 'test.txt' }
let(:options) { ['let g:multi_cursor_normal_maps = {}'] }
# Operator-pending commands are handled correctly thanks to their inclusion
# in `g:multi_cursor_normal_maps`.
#
# When an operator-pending command like 'd' is missing from that setting's
# value, then it should result in a no-op, but we should still remain in
# multicursor mode.
specify "#normal mode 'd'" do
before <<-EOF
hello
hello
EOF
type '<C-n><C-n>vdx<Esc>'
after <<-EOF
hell
hell
EOF
end
end
describe "Multiple Cursors when visual_maps is empty" do
let(:filename) { 'test.txt' }
let(:options) { ['let g:multi_cursor_visual_maps = {}'] }
# Operator-pending commands are handled correctly thanks to their inclusion
# in `g:multi_cursor_visual_maps`.
#
# When an operator-pending command like 'f' is missing from that setting's
# value, then it should result in a no-op, but we should still remain in
# multicursor mode.
specify "#visual mode 'i'" do
before <<-EOF
hello world x
hello world x
EOF
type 'fw<C-n><C-n>fx<Esc>'
after <<-EOF
hello x
hello x
EOF
end
end
describe "Multiple Cursors" do
let(:filename) { 'test.txt' }
let(:options) { ['set autoindent'] }
specify "#paste buffer normal x then p" do
before <<-EOF
jan
feb
mar
EOF
type '<C-v>jj<C-n>xp<Esc>'
after <<-EOF
ajn
efb
amr
EOF
end
specify "#paste buffer visual y then p" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vwvelywhp<Esc>'
after <<-EOF
hello jan jan world
hello feb feb world
hello mar mar world
EOF
end
specify "#paste buffer initial visual y then P" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type 'wywb<C-n><C-n><C-n>p<Esc>'
after <<-EOF
jan jan world
jan feb world
jan mar world
EOF
end
specify "#paste buffer visual y then P" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vwvely^P<Esc>'
after <<-EOF
jan hello jan world
feb hello feb world
mar hello mar world
EOF
end
specify "#paste buffer visual Y then P" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>vwvY^P<Esc>'
after <<-EOF
hello jan world
hello jan world
hello feb world
hello feb world
hello mar world
hello mar world
EOF
end
specify "#multiline replacement" do
before <<-EOF
hello
hello
hello
EOF
type '<C-n><C-n><C-n>cworld<Esc>'
after <<-EOF
world
world
world
EOF
end
specify "#single line replacement" do
before <<-EOF
hello hello hello
EOF
type '<C-n><C-n><C-n>cworld<Esc>'
after <<-EOF
world world world
EOF
end
specify "#mixed line replacement" do
before <<-EOF
hello hello
hello
EOF
type '<C-n><C-n><C-n>cworld<Esc>'
after <<-EOF
world world
world
EOF
end
specify "#new line in insert mode" do
before <<-EOF
hello
hello
EOF
type '<C-n><C-n>chello<CR>world<Esc>'
after <<-EOF
hello
world
hello
world
EOF
end
specify "#new line in insert mode middle of line" do
before <<-EOF
hello world
hello world
EOF
type '<C-n><C-n>vlxi<cr><Esc>'
after <<-EOF
hello
world
hello
world
EOF
end
specify "#multiple new lines on one line in insert mode" do
before <<-EOF
'a','b','c','d','e'
EOF
type 'f,v<C-n><C-n><C-n>c<CR><Esc>'
after <<-EOF
'a'
'b'
'c'
'd'
'e'
EOF
end
specify "#multiple new lines on one line in insert mode with indents" do
before <<-EOF
'a','b','c','d','e'
EOF
type '4i<Space><Esc>f,v<C-n><C-n><C-n>c<CR><Esc>:%s/^/^<CR>'
after <<-EOF
^ 'a'
^ 'b'
^ 'c'
^ 'd'
^ 'e'
EOF
end
specify "#normal mode 'o'" do
before <<-EOF
hello
hello
EOF
type '<C-n><C-n>voworld<Esc>'
after <<-EOF
hello
world
hello
world
EOF
end
specify "#normal mode 'O'" do
before <<-EOF
hello
hello
EOF
type '<C-n><C-n>vOworld<Esc>'
after <<-EOF
world
hello
world
hello
EOF
end
specify "#find command basic" do
before <<-EOF
hello
hello
EOF
vim.normal ':MultipleCursorsFind hello<CR>'
type 'cworld<Esc>'
after <<-EOF
world
world
EOF
end
specify "#find command start-of-line" do
before <<-EOF
hello
world
hello
world
EOF
vim.normal ':MultipleCursorsFind ^<CR>'
type 'Ibegin<Esc>'
after <<-EOF
beginhello
beginworld
begin
beginhello
beginworld
EOF
end
specify "#find command end-of-line" do
before <<-EOF
hello
world
hello
world
EOF
vim.normal ':MultipleCursorsFind $<CR>'
type 'Iend<Esc>'
after <<-EOF
helloend
worldend
end
helloend
worldend
EOF
end
specify "#visual line mode replacement" do
before <<-EOF
hello world
hello world
EOF
type '<C-n><C-n>Vchi!<Esc>'
after <<-EOF
hi!
hi!
EOF
end
specify "#skip key" do
before <<-EOF
hello
hello
hello
EOF
type '<C-n><C-n><C-x>cworld<Esc>'
after <<-EOF
world
hello
world
EOF
end
specify "#prev key" do
before <<-EOF
hello
hello
hello
EOF
type '<C-n><C-n><C-n><C-p>cworld<Esc>'
after <<-EOF
world
world
hello
EOF
end
specify "#visual mode 'i'" do
before <<-EOF
hi (hello world jan) bye
hi (hello world feb) bye
hi (hello world mar) bye
EOF
type 'fw<C-n><C-n><C-n>ibcone<Esc>'
after <<-EOF
hi (one) bye
hi (one) bye
hi (one) bye
EOF
end
specify "#visual mode 'a'" do
before <<-EOF
hi (hello world jan) bye
hi (hello world feb) bye
hi (hello world mar) bye
EOF
type 'fw<C-n><C-n><C-n>abcone<Esc>'
after <<-EOF
hi one bye
hi one bye
hi one bye
EOF
end
specify "#visual mode 'f'" do
before <<-EOF
hi (hello world jan) bye
hi (hello world feb) bye
hi (hello world mar) bye
EOF
type 'fw<C-n><C-n><C-n>f)cone<Esc>'
after <<-EOF
hi (hello one bye
hi (hello one bye
hi (hello one bye
EOF
end
specify "#visual mode 'F'" do
before <<-EOF
hi (hello world jan) bye
hi (hello world feb) bye
hi (hello world mar) bye
EOF
type 'fw<C-n><C-n><C-n>F(cbefore<Esc>'
after <<-EOF
hi beforeorld jan) bye
hi beforeorld feb) bye
hi beforeorld mar) bye
EOF
end
specify "#visual mode 't'" do
before <<-EOF
hello.jan
hello hi.feb
hello hi bye.mar
EOF
type '<C-n><C-n><C-n>t.cone<Esc>'
after <<-EOF
one.jan
one.feb
one.mar
EOF
end
specify "#visual mode 'T'" do
before <<-EOF
jan.world
feb.hi world
mar.bye hi world
EOF
type 'fw<C-n><C-n><C-n>T.cbefore<Esc>'
after <<-EOF
jan.beforeorld
feb.beforeorld
mar.beforeorld
EOF
end
specify "#visual line mode 'f'" do
before <<-EOF
hello jan world
hello feb world
hello mar world
EOF
type '<C-n><C-n><C-n>VfwvAafter<Esc>'
after <<-EOF
hello jan wafterorld
hello feb wafterorld
hello mar wafterorld
EOF
end
specify "#visual mode 'I'" do
before <<-EOF
hello world jan
hello world feb
hello world mar
EOF
type 'w<C-n><C-n><C-n>Ibefore<Esc>'
after <<-EOF
hello beforeworld jan
hello beforeworld feb
hello beforeworld mar
EOF
end
specify "#visual mode 'A'" do
before <<-EOF
hello world jan
hello world feb
hello world mar
EOF
type 'w<C-n><C-n><C-n>Aafter<Esc>'
after <<-EOF
hello worldafter jan
hello worldafter feb
hello worldafter mar
EOF
end
specify "#resize regions visual mode 'I'" do
before <<-EOF
hello world jan
hello world feb
hello world mar
EOF
type 'w<C-n><C-n><C-n>hhhIbefore<Esc>'
after <<-EOF
hello beforeworld jan
hello beforeworld feb
hello beforeworld mar
EOF
end
specify "#resize regions visual mode 'A'" do
before <<-EOF
hello world jan
hello world feb
hello world mar
EOF
type 'w<C-n><C-n><C-n>hhhAbefore<Esc>'
after <<-EOF
hello wobeforerld jan
hello wobeforerld feb
hello wobeforerld mar
EOF
end
specify "#no word boundries visual mode 'I'" do
before <<-EOF
hello hibye world
hello hibye world
hello hibye world
EOF
vim.normal ':MultipleCursorsFind bye<CR>'
type 'Ibefore<Esc>'
after <<-EOF
hello hibeforebye world
hello hibeforebye world
hello hibeforebye world
EOF
end
specify "#variable-length regions visual mode 'I'" do
before <<-EOF
hello hii world
hello hiiii world
hello hiiiiii world
EOF
vim.normal ':MultipleCursorsFind \<hi*\><CR>'
type 'Ibefore<Esc>'
after <<-EOF
hello beforehii world
hello beforehiiii world
hello beforehiiiiii world
EOF
end
specify "#normal mode 'I'" do
before <<-EOF
hello
hello
EOF
type '<C-n><C-n>vIworld <Esc>'
after <<-EOF
world hello
world hello
EOF
end
specify "#normal mode 'A'" do
before <<-EOF
hello
hello
EOF
type '<C-n><C-n>vA world<Esc>'
after <<-EOF
hello world
hello world
EOF
end
specify "#undo" do
before <<-EOF
hello
hello
EOF
type '<C-n><C-n>cworld<Esc>u'
after <<-EOF
hello
hello
EOF
end
specify "#multiline visual mode" do
before <<-EOF
hello
hello
EOF
type 'Vj<C-n>A world<Esc>'
after <<-EOF
hello world
hello world
EOF
end
specify "#set paste mode" do
before <<-EOF
hello
hello
EOF
type ':set paste<CR><C-n><C-n>cworld<Esc>:set nopaste<CR>'
after <<-EOF
world
world
EOF
end
end

View File

@@ -0,0 +1,25 @@
require 'vimrunner'
require 'vimrunner/rspec'
Vimrunner::RSpec.configure do |config|
# Use a single Vim instance for the test suite. Set to false to use an
# instance per test (slower, but can be easier to manage).
config.reuse_server = false
# Decide how to start a Vim instance. In this block, an instance should be
# spawned and set up with anything project-specific.
config.start_vim do
# vim = Vimrunner.start
# Or, start a GUI instance:
vim = Vimrunner.start_gvim
# Setup your plugin in the Vim instance
plugin_path = File.expand_path('../..', __FILE__)
vim.add_plugin(plugin_path, 'plugin/multiple_cursors.vim')
# The returned value is the Client available in the tests.
vim
end
end