• Stars
    star
    684
  • Rank 66,068 (Top 2 %)
  • Language
    Vim Script
  • Created over 11 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simplified clipboard functionality for Vim

vim-easyclip

NOTE

This plugin is considered more or less "done". Minor bug fixes will be applied but otherwise it will just remain stable. For modern versions of vim (Vim 8+ or Neovim) it has been split up into three different plugins instead: vim-cutlass, vim-yoink, and vim-subversive

Simplified clipboard functionality for Vim.

Author: Steve Vermeulen, based on work by Max Brunsfeld

EasyClip is a plugin for Vim which contains a collection of clipboard related functionality with the goal of making using the clipboard in Vim simpler and more intuitive without losing any of its power.

A good starting point for the motivation behind this Vim plugin can be found in Drew Neil's post Registers: The Good, the Bad, and the Ugly Parts

Table Of Contents

Installation

I recommend loading your plugins with neobundle or vundle or pathogen

This plugin also requires that you have Tim Pope's repeat.vim plugin installed

Black Hole Redirection

By default, Vim's built-in delete operator will yank the deleted text in addition to just deleting it. This works great when you want to cut text and paste it somewhere else, but in many other cases it can make things more difficult. For example, if you want to make some tiny edit to fix formatting after cutting some text, you either have to have had the foresight to use a named register, or specify the black hole register explicitly to do your formatting. This plugin solves that problem by redirecting all change and delete operations to the black hole register and introducing a new operator, 'cut' (by default this is mapped to the m key for 'move').

There is simply no need to clutter up the yank history with every single edit, when you almost always know at the time you are deleting text whether it's something that is worth keeping around or not.

NOTE As a result of the above, by default easyclip will shadow an important vim function: The Add Mark key (m). Therefore either you will want to use a different key for the 'cut' operator (see options section below for this) or remap something else to 'add mark'. For example, to use gm for 'add mark' instead of m, include the following in your vimrc:

nnoremap gm m

Substitution Operator

Because replacing text is such a common operation, EasyClip includes a motion for it. It is essentially equivalent to doing a change operation then pasting using the specified register. For example, assuming you have mapped this motion to the s key, to paste over the word under the cursor you would type siw, or to paste inside brackets, si(, etc.

It can also take a register to use for the substitution (eg. "asip), and is fully repeatable using the . key.

NOTE This feature is off by default. To use, you have to either enable the option g:EasyClipUseSubstituteDefaults (in which case it will be mapped to the s key) or map the key/keys of your choice to the <plug> mappings found in substitute.vim.

Yank Buffer

EasyClip allows you to yank and cut things without worrying about losing text that you copied previously. It achieves this by storing all yanks into a buffer, which you can cycle through forward or backwards to choose the yank that you want

This works very similar to the way YankRing and YankStack work, in that you can use a key binding to toggle between different yanks immediately after triggering a paste or substitute. (Most of the functionality is actually taken and adapted from Yankstack, with changes to make it work with substitute)

By default, the keys to toggle the paste are mapped to <CTRL-N> and <CTRL-P> (similar to yankring). For example, executing p<CTRL-P> will paste, then toggle it to the most recent yank before that. You can continue toggling forwards/backwards in the yank history to replace the most recent paste as much as you want. Note that the toggle action will of course not be included in the undo history. That is, pressing undo after any number of swaps will undo the paste and not each swap.

This method of toggling the chosen yank after paste will probably be your primary method of digging back into the yank buffer. Note that in this case the yank buffer is unchanged. What this means for example is that you can toggle a given paste back using <CTRL-P> 10 times, then if you perform a new paste in a different location it will still use the most recent yank (and not the final yank you arrived at after 10 swaps).

Alternatively, you can execute keys [y or ]y to navigate the yank buffer 'head' forwards or backwards. In this case the change will be permanent. That is, pressing [y[yp will paste the third most recent yank. Subsequent pastes will use the same yank, until you go forwards again using ]y.

NOTE: The [y and ]y mappings are not on by default (map them manually).

You can view the full list of yanks at any time by running the command :Yanks

Note that you can swap substitution operations in the same way as paste.

Every time the yank buffer changes, it also populates all the numbered registers. "1 is therefore the previous yank, "2 is the yank before that, etc. This is similar to how the numbered registers work by default (but a bit more sane). (Credit to Drew Neil for the suggestion)

Also, see g:EasyClipPreserveCursorPositionAfterYank option below for an optional non standard customization to yank

Paste

By default EasyClip preserves the default vim paste behaviour, which is the following:

  • p (lowercase) pastes text after the current line if the pasted text is multiline (or after the current character if non-multiline)
  • P (uppercase) behaves the same except acts before the current line (or before the current character if non-multiline)

When the text is multi-line, the cursor is placed at the start of the new text. When the paste is non-multiline, the cursor is placed at the end.

Alternatively, you can enable the option g:EasyClipAlwaysMoveCursorToEndOfPaste to have the cursor positioned at the end in both cases (off by default). Note that when this option is enabled, the beginning of the multi-line text is added to the jumplist, so you can still return to the start of the paste by pressing <CTRL-O> (and this applies to multi-line substitutions as well)

Another non-standard option is g:EasyClipAutoFormat (off by default), which will automatically format text immediately after it is pasted. This can be useful when pasting text from one indent level to another.

When auto-format is enabled, you can also map a key to toggle between the formatted paste and unformatted paste. For example, you might include something like the following in your .vimrc:

nmap <leader>cf <plug>EasyClipToggleFormattedPaste

Then anytime you want to view the original formatting you can type <leader>cf directly after paste. You can also continuing hitting <leader>cf again to toggle between format/unformatted. I find that in most cases I want to always auto-format, and for every other case I can cancel the auto-format immediately afterwards using this plug mapping.

Easy Clip also includes a mapping for insert mode paste, which automatically turns on 'paste' mode for the duration of the paste. Using 'paste' mode will work much more intuitively when pasting text with multiple lines while in insert mode. You can enable this by including something similar to the following in your .vimrc:

imap <c-v> <plug>EasyClipInsertModePaste

Note: If you have a custom mapping for pastetoggle, this may cause conflicts. To preserve the functionality of your existing custom map, you may want to enable the option g:EasyClipUseGlobalPasteToggle. See the comment at the top of Paste.vim for a more detailed explanation.

For convenience, there is also a plug for command mode paste, which you can enable with the following

cmap <c-v> <plug>EasyClipCommandModePaste

There is also the :IPaste command (aka interactive paste) which allows you to enter the yank index buffer you want to paste from. This can be useful if you are looking for an old yank and don't want to cycle back many times to find it. In these cases, execute :IPaste, then the entire yank buffer will be printed, then enter the index of the row in the printed table you want to paste from.

Persistent yank history and sharing clipboard between concurrent Vim instances

EasyClip can automatically store the yank history to file, so that it can be restored the next time you start Vim. Storing it to file also allows other active Vim instances to seamlessly share the same clipboard and yank history.

You can enable this feature by enabling the option g:EasyClipShareYanks (NOTE: off by default). You can also customize where the yank history file gets stored (see options section below)

Note that this feature can be slow in some cases and this is why it is off by default.

Clipboard setting

Vim's built-in setting for clipboard can be set to one of the following:

  1. set clipboard=
  2. set clipboard=unnamed
  3. set clipboard=unnamedplus
  4. set clipboard=unnamed,unnamedplus

Leaving it as (1) which is Vim's default, will cause all yank/delete/paste operations to use the " register. The only drawback here is that whenever you want to copy/paste something from another application, you have to explicitly access the system clipboard, which is represented by the * register. For example, to copy the current line to the system clipboard, you would type "*yy. And to paste some text copied from another window, you would type "*p

To avoid this extra work, you can use option (2) and set it to unnamed. This will cause all yank/delete/paste operations to use the system register *. This way, you can copy something in Vim then immediately paste it into another application. And vice versa when returning to vim.

I recommend using one of these two options. I personally use option (2).

When option (3) is enabled, both Vim and EasyClip will use the + register as its default.

Option (4) is the same as option (3), except Vim will also automatically copy the contents of the + register to the * register.

Options

EasyClip can be easily customized to whatever mappings you wish, using the following options:

g:EasyClipAutoFormat - Default: 0. Set this to 1 to enable auto-formatting pasting text

g:EasyClipYankHistorySize - Default: 50. Change this to limit yank history

g:EasyClipCopyExplicitRegisterToDefault - Default: 0. When set to 0, easy-clip will not change the default register clipboard when an explicit register is given. For example, when set to 0, if you type "ayip it will copy the current paragraph to the a register, but it will not affect the default register, so typing p will work the same as it did before the above command. When set to 1, typing "ayip will copy the paragraph to both.

g:EasyClipAlwaysMoveCursorToEndOfPaste - Default: 0. Set this to 1 to always position cursor at the end of the pasted text for both multi-line and non-multiline pastes.

g:EasyClipPreserveCursorPositionAfterYank - Default 0 (ie. disabled). Vim's default behaviour is to position the cursor at the beginning of the yanked text, which is consistent with other motions. However if you prefer the cursor position to remain unchanged when performing yanks, enable this option.

g:EasyClipShareYanks - Default: 0 (ie. disabled). When enabled, yank history is saved to file, which allows other concurrent Vim instances to automatically share the yank history, and also allows yank history to be automatically restored when restarting vim.

g:EasyClipShareYanksFile - Default: '.easyclip'. The name of the file to save the yank history to when g:EasyClipShareYanks is enabled.

g:EasyClipShareYanksDirectory - Default: '$HOME'. The directory to use to store the file with name given by g:EasyClipShareYanksFile setting. Only applicable when g:EasyClipShareYanks option is enabled.

g:EasyClipShowYanksWidth - Default: 80 - The width to display for each line when the Yanks command is executed

You can also disable the default mappings by setting one or more of the following to zero. By default they are set to 1 (ie. enabled)

`g:EasyClipUseYankDefaults`

`g:EasyClipUseCutDefaults`

`g:EasyClipUsePasteDefaults`

`g:EasyClipEnableBlackHoleRedirect`

`g:EasyClipUsePasteToggleDefaults`

One exception to the above is substitute, which is 0 by default (ie. disabled)

`g:EasyClipUseSubstituteDefaults`

To change from the default mappings, you can disable one of the options above and then map to the specific <plug> mappings of your choice. For example, to change the mapping for cut (by default set to m) to x, include the following in your vimrc:`

let g:EasyClipUseCutDefaults = 0

nmap x <Plug>MoveMotionPlug
xmap x <Plug>MoveMotionXPlug
nmap xx <Plug>MoveMotionLinePlug

Or to change the bindings for toggling paste from <CTRL-N> and <CTRL-P> to <CTRL-D> and <CTRL-F> include the following:

let g:EasyClipUsePasteToggleDefaults = 0

nmap <c-f> <plug>EasyClipSwapPasteForward
nmap <c-d> <plug>EasyClipSwapPasteBackwards

Or to use gs for substitute include the following: (in this case you don't need to turn off the default since the default is already disabled)

nmap <silent> gs <plug>SubstituteOverMotionMap
nmap gss <plug>SubstituteLine
xmap gs <plug>XEasyClipPaste

For reference, or other kinds of mappings, see the Plugs section of the file with the name of the operation you wish to remap (vim-easy-clip/autoload/substitute.vim / move.vim / yank.vim /etc.)

Note that EasyClip will only enable a default mapping if it hasn't already been mapped to something in your .vimrc.

Default Key Mappings

d<motion> - Delete over the given motion and do not change clipboard

dd - Delete the line and do not change clipboard

D - Delete from cursor to the end of the line and do not change clipboard

dD - Delete the contents of line except the newline character (that is, make it blank) and do not change clipboard

x - Delete the character under cursor and do not change clipboard

s - Delete the character under cursor then enter insert mode and do not change clipboard

S - Delete the line under cursor then enter insert mode and do not change clipboard

c<motion> - Enter insert mode over top the given area and do not change clipboard

cc - Enter insert mode over top the current line and do not change clipboard

C - Enter insert mode from cursor to the end of the line and do not change clipboard

p - Paste from specified register. Inserts after current line if text is multiline, after current character if text is non-multiline. Leaves cursor at end of pasted text.

P - Same as p except inserts text before current line/character

<leader>p - Same as p except does not auto-format text. This is only relevant if the auto-format option is enabled

<leader>P - Same as P except does not auto-format text. This is only relevant if the auto-format option is enabled

gp - Same as p but preserves the current cursor position

gP - Same as P but preserves the current cursor position

g<leader>P - Same as <leader>P but preserves the current cursor position

g<leader>p - Same as <leader>p but preserves the current cursor position

m<motion> - Delete over the given motion and copy text to clipboard

mm - Delete the current line and copy text to clipboard

NOTE: M is NOT mapped by default. If you want it, include the following in your .vimrc:

nmap M <Plug>MoveMotionEndOfLinePlug

<CTRL-P> - Rotate the previous paste forward in yank buffer. Note that this binding will only work if executed immediately after a paste

<CTRL-N> - Rotate the previous paste backward in yank buffer. Note that this binding will only work if executed immediately after a paste

[y - Go backward in the yank buffer. This can be executed at any time to modify order of yanks in the yank buffer (though I would recommend just using <CTRL-P> instead)

]y - Go forward in the yank buffer. This can be executed at any time to modify order of yanks in the yank buffer (though I would recommend just using <CTRL-N> instead)

Y - Copy text from cursor position to the end of line to the clipboard

When the option g:EasyClipUseSubstituteDefaults is enabled, the following mappings are added:

s<motion> - Substitute over the given motion with specified register (or default register if unspecified). Note that this only applies if the g:EasyClipUseSubstituteDefaults option is set.

ss - Substitute over the current line with specified register (or default register if unspecified). Note that this only applies if the g:EasyClipUseSubstituteDefaults option is set.

gs - Same as s but preserves the current cursor position.

Custom Yanks

If you have custom yanks that occur in your vimrc or elsewhere and would like them to be included in the yank history, you should call the EasyClip#Yank(). For example, to add a binding to yank the current file name you could add the following to your .vimrc:

nnoremap <leader>yf :call EasyClip#Yank(expand('%'))<cr>

Another way to do the above (which is necessary if you don't control the yank yourself), is to do the following:

nnoremap <leader>yf :EasyClipBeforeYank<cr>:let @*=expand('%')<cr>:EasyClipOnYanksChanged<cr>

Also, worth noting is the Paste command which takes an index and pastes the yank at that index. For example, executing :Paste 0 is equivalent to p, :Paste 1 is equivalent to "1p, etc. For use within scripting, there is also the corresponding method EasyClip#PasteIndex which like the command takes an index as parameter. For the P equivalent, there is also a PasteBefore command and EasyClip#PasteIndexBefore method.

Another method worth noting is EasyClip#GetYankAtIndex which returns the text for the yank at a given index.

Feedback

Feel free to email all feedback/criticism/suggestions to [email protected]. Or, feel free to create a github issue.

Changelog

2.4 (2015-11-19)

  • Added interactive paste by executing command :PasteI
  • Added :Paste and :PasteBefore commands, and also the corresponding methods EasyClip#PasteIndex and EasyClip#PasteIndexBefore

2.3 (2015-03-14)

  • Bug fixes to visual mode paste
  • Added plug mapping to toggle paste between format/unformatted

2.2 (2015-01-27)

  • Bug fixes
  • Removed the 'system sync' option since using unnamed register is sufficient for this
  • Added support for persistent/shared yanks

2.1 (2013-12-06)

  • Bug fixes
  • Disabled substitution operator by default
  • Added numbered registers

2.0 (2013-09-22)

  • Many bug fixes
  • Yankring/Yankstack style post-paste swap
  • RSPEC unit tests added for stability

1.2 (2013-09-22)

  • More bug fixes

1.1 (2013-09-03)

  • Bunch of bug fixes

1.0 (2013-07-08)

  • Initial release

License

Distributed under the same terms as Vim itself. See the vim license.

More Repositories

1

vim-yoink

Vim plugin that maintains a yank history to cycle between when pasting
Vim Script
366
star
2

vimpeccable

Neovim plugin that allows you to easily map keys directly to lua code inside your init.lua
Lua
359
star
3

text-to-colorscheme

Neovim colorschemes generated on the fly with a text prompt using ChatGPT
Lua
295
star
4

vim-subversive

Vim plugin providing operator motions to quickly replace text
Vim Script
286
star
5

vim-macrobatics

Plugin for Vim that makes it easier to record / play / edit macros
Vim Script
81
star
6

nvim-moonmaker

Moonscript plugin support for neovim
Lua
67
star
7

UnityCoroutinesWithoutMonoBehaviours

C#
47
star
8

nvim-teal-maker

Neovim plugin that adds plugin support for teal language
Lua
32
star
9

vim-NotableFt

Vim Script
29
star
10

vim-extended-ft

Vim Script
26
star
11

lusc

Structured Async/Concurrency for Lua
Lua
17
star
12

nvim-marksman

Quick and efficient file finder for neovim
Python
17
star
13

nvim-lusc

Structured Async/Concurrency in Neovim
Lua
13
star
14

tea-leaves

A language server for the Teal language
Lua
12
star
15

logexpert

C#
8
star
16

unifind

Simple generic fuzzy finder for unity editor
C#
8
star
17

lusc_luv

Lua
5
star
18

VimDriver

Python
5
star
19

vimpeccable-lua-vimrc-advanced-example

Lua
4
star
20

vimpeccable-lua-vimrc-example

Lua
4
star
21

nvim-moonmaker-example

Moonscript plugin support example for neovim
MoonScript
3
star
22

CebuGameJam

C#
3
star
23

lua_bazel_rules

Bazel rules to build and run lua scripts
Starlark
2
star
24

vim-quickfixdo

Vim Script
2
star
25

ncm2-yoink

Vim Script
2
star
26

tlcheck

Simple command line tool to type check a given teal file/directory
Lua
2
star
27

HalifaxGameJam2012

C#
1
star
28

GradleCompositeBuildBugExample

Groovy
1
star
29

lastfm_script

Python
1
star
30

buck2_lua_rules

Buck2 rules for Lua and Teal
Starlark
1
star
31

vimpeccable-moonscript-vimrc-example

MoonScript
1
star
32

vimpeccable-moonscript-vimrc-advanced-example

MoonScript
1
star
33

uniscon

A simple implementation of structured concurrency for Unity game engine
C#
1
star
34

svelto-doofus-sample

C#
1
star