Skip to content

Commit 049a0f5

Browse files
dfishburnvim-scripts
authored andcommitted
Version 1.5
NF: The yankring now respects the cpoptions setting, if 'y' is included and you press '.', the previous yank command is executed and added to the yankring. You can also add this behaviour by setting this in your |vimrc|: let g:yankring_dot_repeat_yank = 1 NF: Duplicates will not be added to the yankring by default. If a duplicate is found, the element will be moved to the top of the yankring. This can be controlled by setting this in your |vimrc|: let g:yankring_ignore_duplicate = 0 (1 is default) BF: Regression from version 1.4, the '.' operator may incorrectly insert garbage.
1 parent 2cf30ed commit 049a0f5

File tree

2 files changed

+151
-29
lines changed

2 files changed

+151
-29
lines changed

doc/yankring.txt

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ For instructions on installing this file, type
4343
5.8 YRPop.............................: |YRPop-example|
4444
5.9 Visual modes......................: |yankring-visual-example|
4545
5.10 Using ranges......................: |YRYankRange-example|
46+
5.11 :global...........................: |global-example|
4647
6. History................................: |yankring-history|
4748

4849
==============================================================================
@@ -101,6 +102,21 @@ For instructions on installing this file, type
101102
in the yankring to the fit the size of the Vim window, so that
102103
a single element does not display over multiple lines. >
103104
let g:yankring_max_display = 70
105+
yankring_dot_repeat_yank
106+
< Default: Based on the Vim cpoption setting
107+
By default Vim will not repeat (using '.') yanking of text. This can
108+
be controlled via the |'cpoptions'| setting. The yankring now respects
109+
the cpoptions setting, if 'y' is included and you press '.', the
110+
previous yank command is repeated and added to the yankring.
111+
You can also add this behaviour by setting this in your |vimrc|: >
112+
let g:yankring_dot_repeat_yank = 1
113+
yankring_ignore_duplicate
114+
< Default: 1
115+
Duplicates will not be added to the yankring by default. If a
116+
duplicate is found, that element will be moved to the top of the
117+
yankring (using YRSetTop). This can be controlled by setting this in
118+
your |vimrc|: >
119+
let g:yankring_ignore_duplicate = 0
104120
yankring_map_dot
105121
< Default: 1
106122
If the '.' (repeat) command should be mapped by the yankring.
@@ -746,17 +762,41 @@ For instructions on installing this file, type
746762
:1,4YRYankRange
747763
:3,$YRDeleteRange
748764
:YRShow
765+
<
766+
*global-example*
767+
Using Vim's |:global| command can be very useful at times. The example
768+
adds all rows (in a buffer) to the yankring if they have a certain
769+
phrase: >
770+
:g/addme/YRYankCount 'yy'
771+
< This is the breakdown for the above command: >
772+
:g - for each line in the buffer
773+
/addme - check if the string "addme" is in the line
774+
/YRYankCount 'yy' - Ask the yankring to execute the 'yy' command
749775
750776
751777
==============================================================================
752778
6. History *yankring-history*
753779

780+
1.5: March 30, 2005:
781+
NF: The yankring now respects the cpoptions setting, if 'y' is
782+
included and you press '.', the previous yank command is executed
783+
and added to the yankring. You can also add this behaviour by
784+
setting this in your |vimrc|: >
785+
let g:yankring_dot_repeat_yank = 1
786+
< NF: Duplicates will not be added to the yankring by default. If
787+
a duplicate is found, the element will be moved to the top
788+
of the yankring. This can be controlled by setting this in
789+
your |vimrc|: >
790+
let g:yankring_ignore_duplicate = 0 (1 is default)
791+
< BF: Regression from version 1.4, the '.' operator may incorrectly
792+
insert garbage.
793+
754794
1.4: March 28, 2005:
755795
NF: YRToggle has been updated. If you toggle the yankring off
756796
(disable) the maps it creates are removed. Calling YRToggle
757797
again will recreate the maps. This truly disables the yankring,
758798
where the previous version attempted to do this via code.
759-
BF: Using the '.' operator was not corrected replaying operations
799+
BF: Using the '.' operator was not correctly replaying operations
760800
that did not move text in some way (g~t_) changed the case
761801
of the text but a '.' did not replay it.
762802
BF: When replacing previously pasted text the yankring did not

plugin/yankring.vim

Lines changed: 110 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
" yankring.vim - Yank / Delete Ring for Vim
22
" ---------------------------------------------------------------
3-
" Version: 1.4
3+
" Version: 1.5
44
" Authors: David Fishburn <[email protected]>
5-
" Last Modified: Fri Mar 25 2005 11:14:00 PM
5+
" Last Modified: Tue Mar 29 2005 3:06:25 PM
66
" Script: http://www.vim.org/scripts/script.php?script_id=1234
77
" Based On: Mocked up version by Yegappan Lakshmanan
88
" http://groups.yahoo.com/group/vim/post?act=reply&messageNum=34406
@@ -18,7 +18,7 @@ if v:version < 602
1818
finish
1919
endif
2020

21-
let loaded_yankring = 14
21+
let loaded_yankring = 15
2222

2323
" Allow the user to override the # of yanks/deletes recorded
2424
if !exists('g:yankring_max_history')
@@ -42,6 +42,20 @@ if !exists('g:yankring_max_display')
4242
let g:yankring_max_display = 0
4343
endif
4444

45+
" Controls whether the . operator will repeat yank operations
46+
" The default is based on cpoptions: |cpo-y|
47+
" y A yank command can be redone with ".".
48+
if !exists('g:yankring_dot_repeat_yank')
49+
let g:yankring_dot_repeat_yank = (&cpoptions=~'y'?1:0)
50+
endif
51+
52+
" Only adds unique items to the yankring.
53+
" If the item already exists, that element is set as the
54+
" top of the yankring.
55+
if !exists('g:yankring_ignore_duplicate')
56+
let g:yankring_ignore_duplicate = 1
57+
endif
58+
4559
" Allow the user to specify what characters to use for the mappings.
4660
if !exists('g:yankring_n_keys')
4761
let g:yankring_n_keys = 'yy,dd,yw,dw,ye,de,yE,dE,yiw,diw,yaw,daw,y$,d$,Y,D,yG,dG,ygg,dgg'
@@ -68,6 +82,14 @@ if !exists('g:yankring_paste_n_akey')
6882
let g:yankring_paste_n_akey = 'p'
6983
endif
7084

85+
if !exists('g:yankring_paste_v_bkey')
86+
let g:yankring_paste_v_bkey = 'P'
87+
endif
88+
89+
if !exists('g:yankring_paste_v_akey')
90+
let g:yankring_paste_v_akey = 'p'
91+
endif
92+
7193
if !exists('g:yankring_replace_n_pkey')
7294
let g:yankring_replace_n_pkey = '<C-P>'
7395
endif
@@ -297,6 +319,10 @@ function! s:YRClear()
297319
let s:yr_prev_vis_lend = 0
298320
let s:yr_prev_vis_cstart = 0
299321
let s:yr_prev_vis_cend = 0
322+
323+
" This is used to determine if the visual selection should be
324+
" reset prior to issuing the YRReplace
325+
let s:yr_prev_vis_mode = 0
300326
endfunction
301327

302328

@@ -394,6 +420,23 @@ endfunction
394420
" Adds this value to the yankring.
395421
function! s:YRRecord(value)
396422

423+
if g:yankring_ignore_duplicate == 1
424+
" Ensure the element is not already in the yankring
425+
let iter = s:yr_count
426+
427+
let elem = s:yr_paste_idx
428+
" let iter = s:yr_count
429+
while iter > 0
430+
if getreg(a:value) == s:yr_elem_{elem}
431+
exec "YRSetTop ".elem
432+
" echomsg "YR: Same as element: ".elem
433+
return
434+
endif
435+
let iter = iter - 1
436+
let elem = s:YRGetNextElem(elem, -1)
437+
endwhile
438+
endif
439+
397440
let s:yr_elem_{s:yr_next_idx} = getreg(a:value)
398441
let s:yr_elem_type_{s:yr_next_idx} = getregtype(a:value)
399442
let s:yr_paste_idx = s:yr_next_idx
@@ -427,7 +470,8 @@ function! s:YRSetPrevOP(op_code, count, reg)
427470
let s:yr_prev_chg_cstart = col("'[")
428471
let s:yr_prev_chg_cend = col("']")
429472

430-
" TODO
473+
" If storing the last change position (using '[, '])
474+
" is not good enough, then another option is to:
431475
" Use :redir on the :changes command
432476
" and grab the last item. Store this value
433477
" and compare it is YRDoRepeat.
@@ -458,6 +502,15 @@ function! s:YRDoRepeat()
458502
\ s:yr_prev_chg_cend == col("']")
459503
let dorepeat = 1
460504
endif
505+
" If we are going to repeat check to see if the
506+
" previous command was a yank operation. If so determine
507+
" if yank operations are allowed to be repeated.
508+
if dorepeat == 1 && s:yr_prev_op_code =~ '^y'
509+
" This value be default is set based on cpoptions.
510+
if g:yankring_dot_repeat_yank == 0
511+
let dorepeat = 0
512+
endif
513+
endif
461514
return dorepeat
462515
endfunction
463516

@@ -589,7 +642,7 @@ endfunction
589642

590643
" Paste from either the yankring or from a specified register
591644
" Optionally a count can be provided, so paste the same value 10 times
592-
function! s:YRPaste(replace_last_paste_selection, nextvalue, direction)
645+
function! s:YRPaste(replace_last_paste_selection, nextvalue, direction, ...)
593646
" Disabling the yankring removes the default maps.
594647
" But there are some maps the user can create on their own, and
595648
" these would most likely call this function. So place an extra
@@ -603,44 +656,56 @@ function! s:YRPaste(replace_last_paste_selection, nextvalue, direction)
603656
let default_buffer = ((&clipboard=='unnamed')?'*':'"')
604657
let v_count = v:count
605658

659+
" Default command mode to normal mode 'n'
660+
let cmd_mode = 'n'
661+
if a:0 > 0
662+
" Change to visual mode, if command executed via
663+
" a visual map
664+
let cmd_mode = ((a:1 == 'v') ? 'v' : 'n')
665+
endif
666+
606667
" User has decided to bypass the yankring and specify a specific
607668
" register
608669
if user_register != default_buffer
609670
if a:replace_last_paste_selection == 1
610-
" Supports this for example - 5p
611-
exec "normal! ".
612-
\ (
613-
\ (v_count > 0)?(v_count):'').
614-
\ (a:direction =~ 'b'?
615-
\ (g:yankring_replace_n_pkey):
616-
\ (g:yankring_replace_n_nkey)
617-
\ )
671+
echomsg 'YR: A register cannot be specified in replace mode'
672+
return
618673
else
619674
exec "normal! ".
620-
\ ((v_count > 0)?(v_count):'').
621-
\ (user_register==default_buffer?'':'"'.user_register).
622-
\ (a:direction =~ 'b'?'P':'p')
675+
\ ((cmd_mode=='n') ? "" : "gv").
676+
\ ((v_count > 0)?(v_count):'').
677+
\ (user_register==default_buffer?'':'"'.user_register).
678+
\ (a:direction =~ 'b'?'P':'p')
623679
endif
624-
let s:yr_paste_dir = a:direction
680+
let s:yr_paste_dir = a:direction
681+
let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1)
625682
return
626683
endif
627684

628685
" Try to second guess the user to make these mappings less intrusive.
629686
" If the user hits paste compare the contents of the paste register
630687
" to the current entry in the yankring. If they are different, lets
631688
" assume the user wants the contents of the paste register.
632-
" So if they pressed yw (yank word) and hit paste, the yankring
689+
" So if they pressed [yt ] (yank to space) and hit paste, the yankring
633690
" would not have the word in it, so assume they want the word pasted.
634691
if a:replace_last_paste_selection != 1
635692
if s:yr_count > 0
636693
if getreg(default_buffer) != s:yr_elem_{s:yr_paste_idx}
637-
exec 'normal! '.(a:direction =~ 'b'?'P':'p')
638-
let s:yr_paste_dir = a:direction
694+
exec "normal! ".
695+
\ ((cmd_mode=='n') ? "" : "gv").
696+
\ ((v_count > 0)?(v_count):'').
697+
\ (a:direction =~ 'b'?'P':'p')
698+
let s:yr_paste_dir = a:direction
699+
let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1)
639700
return
640701
endif
641702
else
642-
exec 'normal! '.(a:direction =~ 'b'?'P':'p')
643-
let s:yr_paste_dir = a:direction
703+
exec "normal! ".
704+
\ ((cmd_mode=='n') ? "" : "gv").
705+
\ ((v_count > 0)?(v_count):'').
706+
\ (a:direction =~ 'b'?'P':'p')
707+
let s:yr_paste_dir = a:direction
708+
let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1)
644709
return
645710
endif
646711
endif
@@ -678,10 +743,13 @@ function! s:YRPaste(replace_last_paste_selection, nextvalue, direction)
678743

679744
" First undo the previous paste
680745
exec "normal! u"
746+
" Check if the visual selection should be reselected
681747
" Next paste the correct item from the ring
682748
" This is done as separate statements since it appeared that if
683749
" there was nothing to undo, the paste never happened.
684-
exec "normal! ".((s:yr_paste_dir =~ 'b')?'P':'p')
750+
exec "normal! ".
751+
\ ((s:yr_prev_vis_mode==0) ? "" : "gv").
752+
\ ((s:yr_paste_dir =~ 'b')?'P':'p')
685753
call setreg(default_buffer, save_reg, save_reg_type)
686754
call s:YRSetPrevOP('', '', '')
687755
else
@@ -694,16 +762,18 @@ function! s:YRPaste(replace_last_paste_selection, nextvalue, direction)
694762
\ , s:yr_elem_{s:yr_paste_idx}
695763
\ , s:yr_elem_type_{s:yr_paste_idx})
696764
exec "normal! ".
697-
\ (
698-
\ ((v_count > 0)?(v_count):'').
699-
\ ((a:direction =~ 'b')?'P':'p')
700-
\ )
765+
\ ((cmd_mode=='n') ? "" : "gv").
766+
\ (
767+
\ ((v_count > 0)?(v_count):'').
768+
\ ((a:direction =~ 'b')?'P':'p')
769+
\ )
701770
call setreg(default_buffer, save_reg, save_reg_type)
702771
call s:YRSetPrevOP(
703772
\ ((a:direction =~ 'b')?'P':'p')
704773
\ , v_count
705774
\ , default_buffer)
706-
let s:yr_paste_dir = a:direction
775+
let s:yr_paste_dir = a:direction
776+
let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1)
707777
endif
708778

709779
endfunction
@@ -752,6 +822,12 @@ function! YRMapsCreate()
752822
if g:yankring_paste_n_akey != ''
753823
exec 'nnoremap <silent>'.g:yankring_paste_n_akey." :<C-U>YRPaste 'a'<CR>"
754824
endif
825+
if g:yankring_paste_v_bkey != ''
826+
exec 'vnoremap <silent>'.g:yankring_paste_v_bkey." :<C-U>YRPaste 'b', 'v'<CR>"
827+
endif
828+
if g:yankring_paste_v_akey != ''
829+
exec 'vnoremap <silent>'.g:yankring_paste_v_akey." :<C-U>YRPaste 'a', 'v'<CR>"
830+
endif
755831
if g:yankring_replace_n_pkey != ''
756832
exec 'nnoremap <silent>'.g:yankring_replace_n_pkey." :<C-U>YRReplace '-1', 'b'<CR>"
757833
endif
@@ -806,6 +882,12 @@ function! YRMapsDelete()
806882
if g:yankring_paste_n_akey != ''
807883
exec 'nunmap '.g:yankring_paste_n_akey
808884
endif
885+
if g:yankring_paste_v_bkey != ''
886+
exec 'vunmap '.g:yankring_paste_v_bkey
887+
endif
888+
if g:yankring_paste_v_akey != ''
889+
exec 'vunmap '.g:yankring_paste_v_akey
890+
endif
809891
if g:yankring_replace_n_pkey != ''
810892
exec 'nunmap '.g:yankring_replace_n_pkey
811893
endif

0 commit comments

Comments
 (0)