1
1
" yankring.vim - Yank / Delete Ring for Vim
2
2
" ---------------------------------------------------------------
3
- " Version: 1.4
3
+ " Version: 1.5
4
4
" 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
6
6
" Script: http://www.vim.org/scripts/script.php?script_id=1234
7
7
" Based On: Mocked up version by Yegappan Lakshmanan
8
8
" http://groups.yahoo.com/group/vim/post?act=reply&messageNum=34406
@@ -18,7 +18,7 @@ if v:version < 602
18
18
finish
19
19
endif
20
20
21
- let loaded_yankring = 14
21
+ let loaded_yankring = 15
22
22
23
23
" Allow the user to override the # of yanks/deletes recorded
24
24
if ! exists (' g:yankring_max_history' )
@@ -42,6 +42,20 @@ if !exists('g:yankring_max_display')
42
42
let g: yankring_max_display = 0
43
43
endif
44
44
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
+
45
59
" Allow the user to specify what characters to use for the mappings.
46
60
if ! exists (' g:yankring_n_keys' )
47
61
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')
68
82
let g: yankring_paste_n_akey = ' p'
69
83
endif
70
84
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
+
71
93
if ! exists (' g:yankring_replace_n_pkey' )
72
94
let g: yankring_replace_n_pkey = ' <C-P>'
73
95
endif
@@ -297,6 +319,10 @@ function! s:YRClear()
297
319
let s: yr_prev_vis_lend = 0
298
320
let s: yr_prev_vis_cstart = 0
299
321
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
300
326
endfunction
301
327
302
328
@@ -394,6 +420,23 @@ endfunction
394
420
" Adds this value to the yankring.
395
421
function ! s: YRRecord (value)
396
422
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
+
397
440
let s: yr_elem_ {s: yr_next_idx } = getreg (a: value )
398
441
let s: yr_elem_type_ {s: yr_next_idx } = getregtype (a: value )
399
442
let s: yr_paste_idx = s: yr_next_idx
@@ -427,7 +470,8 @@ function! s:YRSetPrevOP(op_code, count, reg)
427
470
let s: yr_prev_chg_cstart = col (" '[" )
428
471
let s: yr_prev_chg_cend = col (" ']" )
429
472
430
- " TODO
473
+ " If storing the last change position (using '[, '])
474
+ " is not good enough, then another option is to:
431
475
" Use :redir on the :changes command
432
476
" and grab the last item. Store this value
433
477
" and compare it is YRDoRepeat.
@@ -458,6 +502,15 @@ function! s:YRDoRepeat()
458
502
\ s: yr_prev_chg_cend == col (" ']" )
459
503
let dorepeat = 1
460
504
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
461
514
return dorepeat
462
515
endfunction
463
516
@@ -589,7 +642,7 @@ endfunction
589
642
590
643
" Paste from either the yankring or from a specified register
591
644
" 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, ... )
593
646
" Disabling the yankring removes the default maps.
594
647
" But there are some maps the user can create on their own, and
595
648
" these would most likely call this function. So place an extra
@@ -603,44 +656,56 @@ function! s:YRPaste(replace_last_paste_selection, nextvalue, direction)
603
656
let default_buffer = ((&clipboard == ' unnamed' )?' *' :' "' )
604
657
let v_count = v: count
605
658
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
+
606
667
" User has decided to bypass the yankring and specify a specific
607
668
" register
608
669
if user_register != default_buffer
609
670
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
618
673
else
619
674
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' )
623
679
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 )
625
682
return
626
683
endif
627
684
628
685
" Try to second guess the user to make these mappings less intrusive.
629
686
" If the user hits paste compare the contents of the paste register
630
687
" to the current entry in the yankring. If they are different, lets
631
688
" 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
633
690
" would not have the word in it, so assume they want the word pasted.
634
691
if a: replace_last_paste_selection != 1
635
692
if s: yr_count > 0
636
693
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 )
639
700
return
640
701
endif
641
702
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 )
644
709
return
645
710
endif
646
711
endif
@@ -678,10 +743,13 @@ function! s:YRPaste(replace_last_paste_selection, nextvalue, direction)
678
743
679
744
" First undo the previous paste
680
745
exec " normal! u"
746
+ " Check if the visual selection should be reselected
681
747
" Next paste the correct item from the ring
682
748
" This is done as separate statements since it appeared that if
683
749
" 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' )
685
753
call setreg (default_buffer, save_reg, save_reg_type)
686
754
call s: YRSetPrevOP (' ' , ' ' , ' ' )
687
755
else
@@ -694,16 +762,18 @@ function! s:YRPaste(replace_last_paste_selection, nextvalue, direction)
694
762
\ , s: yr_elem_ {s: yr_paste_idx }
695
763
\ , s: yr_elem_type_ {s: yr_paste_idx })
696
764
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
+ \ )
701
770
call setreg (default_buffer, save_reg, save_reg_type)
702
771
call s: YRSetPrevOP (
703
772
\ ((a: direction = ~ ' b' )?' P' :' p' )
704
773
\ , v_count
705
774
\ , 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 )
707
777
endif
708
778
709
779
endfunction
@@ -752,6 +822,12 @@ function! YRMapsCreate()
752
822
if g: yankring_paste_n_akey != ' '
753
823
exec ' nnoremap <silent>' .g: yankring_paste_n_akey ." :<C-U>YRPaste 'a'<CR>"
754
824
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
755
831
if g: yankring_replace_n_pkey != ' '
756
832
exec ' nnoremap <silent>' .g: yankring_replace_n_pkey ." :<C-U>YRReplace '-1', 'b'<CR>"
757
833
endif
@@ -806,6 +882,12 @@ function! YRMapsDelete()
806
882
if g: yankring_paste_n_akey != ' '
807
883
exec ' nunmap ' .g: yankring_paste_n_akey
808
884
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
809
891
if g: yankring_replace_n_pkey != ' '
810
892
exec ' nunmap ' .g: yankring_replace_n_pkey
811
893
endif
0 commit comments