-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathyankring.vim
2885 lines (2485 loc) · 98.1 KB
/
yankring.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
" yankring.vim - Yank / Delete Ring for Vim
" ---------------------------------------------------------------
" Version: 19.0
" Author: David Fishburn <dfishburn dot vim at gmail dot com>
" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
" Last Modified: 2015 Jul 27
" Script: http://www.vim.org/scripts/script.php?script_id=1234
" Based On: Mocked up version by Yegappan Lakshmanan
" http://groups.yahoo.com/group/vim/post?act=reply&messageNum=34406
" License: GPL (Gnu Public License)
" GetLatestVimScripts: 1234 1 :AutoInstall: yankring.vim
if exists('g:loaded_yankring')
finish
endif
if v:version < 700
echomsg 'yankring: You need at least Vim 7.0'
finish
endif
let g:loaded_yankring = 190
" Turn on support for line continuations when creating the script
let s:cpo_save = &cpo
set cpo&vim
let s:yr_has_voperator = 0
if v:version > 701 || ( v:version == 701 && has("patch205") )
let s:yr_has_voperator = 1
endif
if !exists('g:yankring_history_dir')
let g:yankring_history_dir = expand('$HOME')
else
" let g:yankring_history_dir = expand(g:yankring_history_dir)
for dir in split(g:yankring_history_dir, ",")
if isdirectory(expand(dir))
let g:yankring_history_dir = expand(dir)
break
endif
endfor
endif
if !exists('g:yankring_buffer_name')
let g:yankring_buffer_name = '[YankRing]'
endif
if !exists('g:yankring_history_file')
let g:yankring_history_file = 'yankring_history'
endif
" Allow the user to override the # of yanks/deletes recorded
if !exists('g:yankring_max_history')
let g:yankring_max_history = 100
elseif g:yankring_max_history < 0
let g:yankring_max_history = 100
endif
" Specify the minimum length of 1 entry
if !exists('g:yankring_min_element_length')
let g:yankring_min_element_length = 1
endif
" Specify the maximum length of 1 entry (1MB default)
if !exists('g:yankring_max_element_length')
let g:yankring_max_element_length = 1048576
endif
" Warn if truncation occurs
if !exists('g:yankring_warn_on_truncate')
let g:yankring_warn_on_truncate = 1
endif
" Allow the user to specify if the plugin is enabled or not
if !exists('g:yankring_enabled')
let g:yankring_enabled = 1
endif
" Specify max display length for each element for YRShow
if !exists('g:yankring_max_display')
let g:yankring_max_display = 0
endif
" Check if yankring should persist between Vim instances
if !exists('g:yankring_persist')
let g:yankring_persist = 1
endif
" Check if yankring share 1 file between all instances of Vim
if !exists('g:yankring_share_between_instances')
let g:yankring_share_between_instances = 1
endif
" Specify whether the results of the ring should be displayed
" in a separate buffer window instead of the use of echo
if !exists('g:yankring_window_use_separate')
let g:yankring_window_use_separate = 1
endif
" Specifies whether the window is closed after an action
" is performed
if !exists('g:yankring_window_auto_close')
let g:yankring_window_auto_close = 1
endif
" When displaying the buffer, how many lines should it be
if !exists('g:yankring_window_height')
let g:yankring_window_height = 8
endif
" When displaying the buffer, how many columns should it be
if !exists('g:yankring_window_width')
let g:yankring_window_width = 30
endif
" When displaying the buffer, where it should be placed
if !exists('g:yankring_window_use_horiz')
let g:yankring_window_use_horiz = 1
endif
" When displaying the buffer, where it should be placed
if !exists('g:yankring_window_use_bottom')
let g:yankring_window_use_bottom = 1
endif
" When displaying the buffer, where it should be placed
if !exists('g:yankring_window_use_right')
let g:yankring_window_use_right = 1
endif
" If the user presses <space>, toggle the width of the window
if !exists('g:yankring_window_increment')
let g:yankring_window_increment = 50
endif
" Controls whether the . operator will repeat yank operations
" The default is based on cpoptions: |cpo-y|
" y A yank command can be redone with ".".
if !exists('g:yankring_dot_repeat_yank')
let g:yankring_dot_repeat_yank = (s:cpo_save=~'y'?1:0)
endif
" Only adds unique items to the yankring.
" If the item already exists, that element is set as the
" top of the yankring.
if !exists('g:yankring_ignore_duplicate')
let g:yankring_ignore_duplicate = 1
endif
" Determine whether to record inserted data
if !exists('g:yankring_record_insert')
let g:yankring_record_insert = 0
endif
" Vim automatically manages the numbered registers:
" 0 - last yanked text
" 1-9 - last deleted items
" If this option is turned on, the yankring will manage the
" values in them.
if !exists('g:yankring_manage_numbered_reg')
let g:yankring_manage_numbered_reg = 0
endif
" Allow the user to specify what characters to use for the mappings.
if !exists('g:yankring_n_keys')
" 7.1.patch205 introduces the v:operator function which was essential
" to gain the omap support.
if s:yr_has_voperator == 1
" Use omaps for the rest of the functionality
let g:yankring_n_keys = 'Y D x X'
else
let g:yankring_n_keys = 'x yy dd yw dw ye de yE dE yiw diw yaw daw y$ d$ Y D yG dG ygg dgg'
endif
endif
" Allow the user to specify what operator pending motions to map
if !exists('g:yankring_o_keys')
" o-motions and text objects, without zap-to-char motions
let g:yankring_o_keys = 'b B w W e E d h j k l H M L y G ^ 0 $ , ;'
let g:yankring_o_keys .= ' g_ g^ gm g$ gk gj gg ge gE - + _ '
let g:yankring_o_keys .= ' iw iW aw aW as is ap ip a] a[ i] i[ a) a( ab i) i( ib a> a< i> i< at it a} a{ aB i} i{ iB a" a'' a` i" i'' i`'
endif
if !exists('g:yankring_zap_keys')
let g:yankring_zap_keys = 'f F t T / ?'
endif
" Allow the user to specify what operator pending motions to map
if !exists('g:yankring_ignore_operator')
let g:yankring_ignore_operator = 'g~ gu gU ! = gq g? > < zf g@'
endif
let g:yankring_ignore_operator = ' '.g:yankring_ignore_operator.' '
" Whether we should map the . operator
if !exists('g:yankring_map_dot')
let g:yankring_map_dot = 1
endif
" Whether we sould map the "g" paste operators
if !exists('g:yankring_paste_using_g')
let g:yankring_paste_using_g = 1
endif
if !exists('g:yankring_v_key')
let g:yankring_v_key = 'y'
endif
if !exists('g:yankring_del_v_key')
let g:yankring_del_v_key = 'd x'
endif
if !exists('g:yankring_paste_n_bkey')
let g:yankring_paste_n_bkey = 'P'
endif
if !exists('g:yankring_paste_n_akey')
let g:yankring_paste_n_akey = 'p'
endif
if !exists('g:yankring_paste_v_bkey')
let g:yankring_paste_v_bkey = 'P'
endif
if !exists('g:yankring_paste_v_akey')
let g:yankring_paste_v_akey = 'p'
endif
if exists('g:yankring_paste_check_default_buffer')
let g:yankring_paste_check_default_register = g:yankring_paste_check_default_buffer
endif
if !exists('g:yankring_paste_check_default_register')
let g:yankring_paste_check_default_register = 1
endif
if !exists('g:yankring_replace_n_pkey')
let g:yankring_replace_n_pkey = '<C-P>'
endif
if !exists('g:yankring_replace_n_nkey')
let g:yankring_replace_n_nkey = '<C-N>'
endif
if !exists('g:yankring_clipboard_monitor')
let g:yankring_clipboard_monitor = (has('clipboard')?1:0)
endif
if !exists('g:yankring_manual_clipboard_check')
let g:yankring_manual_clipboard_check = 0
if g:yankring_clipboard_monitor == 1
if has("gui_running")
" FocusGained event will take care of
" monitoring the clipboard.
let g:yankring_manual_clipboard_check = 0
else
" If the GUI is not running and the user wants to monitor the
" clipboard, we need to manually check for clipboard entries as
" the FocusGained event does not fire in console mode.
let g:yankring_manual_clipboard_check = 1
endif
endif
endif
if !exists('g:yankring_default_menu_mode')
let g:yankring_default_menu_mode = 3
endif
" Script variables for the yankring buffer
let s:yr_buffer_last_winnr = -1
let s:yr_buffer_last = -1
let s:yr_buffer_id = -1
let s:yr_search = ''
let s:yr_remove_omap_dot = 0
let s:yr_history_version = 'v2'
let s:yr_history_v1_nl = '@@@'
let s:yr_history_v1_nl_pat = '\%(\\\)\@<!@@@'
let s:yr_history_v2_nl = "\2" " Use double quotes for a special character
let s:yr_history_v2_nl_pat = "\2"
let s:yr_history_last_upd = 0
if g:yankring_persist == 1
let s:yr_history_file_v1 =
\ g:yankring_history_dir.'/'.
\ g:yankring_history_file.
\ (g:yankring_share_between_instances==1?'':'_'.v:servername).
\ '.txt'
let s:yr_history_file_v2 =
\ g:yankring_history_dir.'/'.
\ g:yankring_history_file.
\ (g:yankring_share_between_instances==1?'':'_'.v:servername).
\ '_v2.txt'
endif
" Vim window size is changed by the yankring plugin or not
let s:yr_winsize_chgd = 0
let s:yr_maps_created = 0
let s:yr_maps_created_zap = 0
let s:yr_last_motion = ''
" Enables or disables the yankring
function! s:YRToggle(...)
" Default the current state to toggle
let new_state = ((g:yankring_enabled == 1) ? 0 : 1)
" Allow the user to specify if enabled
if a:0 > 0
let new_state = ((a:1 == 1) ? 1 : 0)
endif
" YRToggle accepts an integer value to specify the state
if new_state == g:yankring_enabled
return
elseif new_state == 1
call s:YRMapsCreate()
call s:YRWarningMsg('YR: The YankRing is now enabled')
else
call s:YRMapsDelete()
call s:YRWarningMsg('YR: The YankRing is now disabled')
endif
endfunction
" Enables or disables the yankring
function! s:YRDisplayElem(disp_nbr, script_var)
if g:yankring_max_display == 0
if g:yankring_window_use_separate == 1
let max_display = 500
else
let max_display = g:yankring_window_width +
\ g:yankring_window_increment -
\ 12
endif
else
let max_display = g:yankring_max_display
endif
let elem = matchstr(a:script_var, '^.*\ze,.*$')
if s:yr_history_version == 'v1'
" v1
" let elem = substitute(elem, '\%(\\\)\@<!@@@', '\\n', 'g')
" v2
let elem = substitute(elem, s:yr_history_v1_nl_pat, '\\n', 'g')
let elem = substitute(elem, '\\@', '@', 'g')
else
let elem = substitute(elem, s:yr_history_v2_nl_pat, '\\n', 'g')
endif
let length = strlen(elem)
" Fancy trick to align them all regardless of how many
" digits the element # is
return a:disp_nbr.
\ strtrans(
\ strpart(" ",0,(6-strlen(a:disp_nbr+1))).
\ (
\ (length>max_display)?
\ (strpart(elem,0,max_display).
\ '...'):
\ elem
\ )
\ )
return ""
endfunction
" Enables or disables the yankring
function! s:YRShow(...)
" Prevent recursion
if exists('s:yankring_showing') && s:yankring_showing == 1
" call s:YRWarningMsg('YR: YRShow aborting for recursion')
return
endif
if g:yankring_enabled == 0
call s:YRWarningMsg('YR: The YankRing is disabled, use YRToggle to re-enable')
return
endif
" Prevent recursion
let s:yankring_showing = 1
" If the GUI is not running, we need to manually check for clipboard
" entries as the FocusGained event does not fire in console mode.
if g:yankring_manual_clipboard_check == 1
call s:YRCheckClipboard()
endif
" If no parameter was provided assume the user wants to
" toggle the display.
let toggle = 1
if a:0 > 0
let toggle = matchstr(a:1, '\d\+')
endif
let show_registers = 0
if a:0 > 1 && a:2 ==# 'R'
let show_registers = 1
endif
if toggle == 1
if bufwinnr(s:yr_buffer_id) > -1
" If the YankRing window is already open close it
exec bufwinnr(s:yr_buffer_id) . "wincmd w"
" Quit the YankRing
call s:YRWindowAction('q', 'n')
" Switch back to the window which the YankRing
" window was opened from
if bufwinnr(s:yr_buffer_last) != -1
" If the buffer is visible, switch to it
exec s:yr_buffer_last_winnr . "wincmd w"
endif
" Prevent recursion
let s:yankring_showing = 0
return
endif
endif
" Reset the search string, since this is automatically called
" if the yankring window is open. A previous search must be
" cleared since we do not want to show new items. The user can
" always run the search again.
let s:yr_search = ""
" It is possible for registers to be changed outside of the
" maps of the YankRing. Perform this quick check when we
" show the contents (or when it is refreshed).
if g:yankring_paste_check_default_register == 1
let save_reg = 0
let register = ((&clipboard=~'\<unnamed\>')?'*':((&clipboard=~'\<unnamedplus\>' && has('unnamedplus'))?'+':'"'))
if &clipboard =~ '\<unnamed\>' && getreg('*') != s:yr_prev_clipboard_star
let save_reg = 1
endif
if has('unnamedplus') && &clipboard =~ '\<unnamedplus\>' && getreg('+') != s:yr_prev_clipboard_plus
let save_reg = 1
endif
if register == '"' && getreg('"') != s:yr_prev_reg_unnamed
let save_reg = 1
endif
if save_reg == 1
" The user has performed a yank / delete operation
" outside of the yankring maps. Add this
" value to the yankring.
call YRRecord(register)
endif
endif
" List is shown in order of replacement
" assuming using previous yanks
let output = "--- YankRing ---\n"
let output = output . (show_registers == 1 ? 'Reg ' : 'Elem')." Content\n"
if show_registers == 1
for reg_name in map( range(char2nr('0'), char2nr('9')) +
\ (range(char2nr('a'), char2nr('z')))
\, 'nr2char(v:val)'
\ )
let output = output . s:YRDisplayElem(reg_name, getreg(reg_name).',') . "\n"
endfor
else
call s:YRHistoryRead()
let disp_item_nr = 1
for elem in s:yr_history_list
let output = output . s:YRDisplayElem(disp_item_nr, elem) . "\n"
let disp_item_nr += 1
endfor
endif
if g:yankring_window_use_separate == 1
call s:YRWindowOpen(output)
else
echo output
endif
" Prevent recursion
let s:yankring_showing = 0
endfunction
" Used in omaps if a following character is required
" like with motions (f,t)
function! s:YRGetChar()
let msg = "YR:Enter character:"
" echomsg msg
echo msg
let c = getchar()
if c =~ '^\d\+$'
let c = nr2char(c)
" echomsg msg.c
echon c
endif
return c
endfunction
" Used in omaps if a following string is required
" like with motions (/,?)
" function! s:YRGetSearch()
" " let msg = "YR:Enter string:"
" " echomsg msg
" let str = input("YR:Enter string:")
" " let str = ''
" " while 1==1
" " let c = getchar()
" " if c =~ '^\d\+$'
" " let c = nr2char(c)
" " if c == "\<C-C>"
" " return c
" " endif
" " if c == "\<CR>"
" " break
" " endif
" " let str = str.c
" " echomsg msg.str
" " else
" " break
" " endif
" " endwhile
" return str
" endfunction
" Paste a certain item from the yankring
" If no parameter is provided, this function becomes interactive. It will
" display the list (using YRShow) and allow the user to choose an element.
function! s:YRGetElem(...)
if g:yankring_manual_clipboard_check == 1
call s:YRCheckClipboard()
endif
if s:yr_count == 0
call s:YRWarningMsg('YR: yankring is empty')
return -1
endif
let default_buffer = ((&clipboard=~'\<unnamed\>')?'*':((&clipboard=~'\<unnamedplus\>' && has('unnamedplus'))?'+':'"'))
let direction = 'p'
if a:0 > 1
" If the user indicated to paste above or below
" let direction = ((a:2 ==# 'P') ? 'P' : 'p')
if a:2 =~ '\<\(p\|gp\|P\|gP\)\>'
let direction = a:2
endif
endif
" Check to see if a specific value has been provided
let elem = 0
if a:0 > 0
" Ensure we get only the numeric value (trim it)
let elem = matchstr(a:1, '\d\+')
let elem = elem - 1
else
" If no parameter was supplied display the yankring
" and prompt the user to enter the value they want pasted.
call s:YRShow(0)
if g:yankring_window_use_separate == 1
" The window buffer is used instead of command line
return
endif
let elem = input("Enter # to paste:")
" Ensure we get only the numeric value (trim it)
let elem = matchstr(elem, '\d\+')
if elem == ''
" They most likely pressed enter without entering a value
return
endif
let elem = elem - 1
endif
if elem < 0 || elem >= s:yr_count
call s:YRWarningMsg("YR: Invalid choice:".elem)
return -1
endif
let default_buffer = ((&clipboard=~'\<unnamed\>')?'*':((&clipboard=~'\<unnamedplus\>' && has('unnamedplus'))?'+':'"'))
call setreg(default_buffer
\ , s:YRGetValElemNbr((elem), 'v')
\ , s:YRGetValElemNbr((elem), 't')
\ )
exec 'normal! "'.default_buffer.direction
" Set the previous action as a paste in case the user
" press . to repeat
call s:YRSetPrevOP('p', '', default_buffer, 'n')
endfunction
" Starting the top of the ring it will paste x items from it
function! s:YRGetMultiple(reverse_order, ...)
if g:yankring_manual_clipboard_check == 1
call s:YRCheckClipboard()
endif
if s:yr_count == 0
call s:YRWarningMsg('YR: yankring is empty')
return
endif
let max = 1
if a:0 == 1
" If the user provided a range, exit after that many
" have been displayed
let max = matchstr(a:1, '\d\+')
endif
if max > s:yr_count
" Default to all items if they specified a very high value
let max = s:yr_count
endif
" Base the increment on the sort order of the results
let increment = ((a:reverse_order==0)?(1):(-1))
if a:reverse_order == 0
let increment = 1
let elem = 1
else
let increment = -1
let elem = max
endif
if a:0 > 1
let iter = 1
while iter <= a:0
let elem = (a:{iter} - 1)
call s:YRGetElem(elem)
let iter = iter + 1
endwhile
else
while max > 0
" Paste the first item, and move on to the next.
call s:YRGetElem(elem)
let elem = elem + increment
let max = max - 1
endwhile
endif
endfunction
" Given a regular expression, check each element within
" the yankring, display only the matching items and prompt
" the user for which item to paste
function! s:YRSearch(...)
if s:yr_count == 0
call s:YRWarningMsg('YR: yankring is empty')
return
endif
let s:yr_search = ""
" If the user provided a range, exit after that many
" have been displayed
if a:0 == 0 || (a:0 == 1 && a:1 == "")
let s:yr_search = input('Enter [optional] regex:')
else
let s:yr_search = a:1
endif
if s:yr_search == ""
" Show the entire yankring
call s:YRShow(0)
return
endif
" List is shown in order of replacement
" assuming using previous yanks
let output = "--- YankRing ---\n"
let output = output . "Elem Content\n"
let valid_choices = []
let search_result = filter(copy(s:yr_history_list), "v:val =~ '".s:yr_search."'")
let disp_item_nr = 1
for elem in s:yr_history_list
if elem =~ s:yr_search
let output = output . s:YRDisplayElem(disp_item_nr, elem) . "\n"
call add(valid_choices, disp_item_nr.'')
endif
let disp_item_nr += 1
endfor
if empty(valid_choices)
let output = output . "Search for [".s:yr_search."] did not match any items "
endif
if g:yankring_window_use_separate == 1
call s:YRWindowOpen(output)
else
if !empty(valid_choices)
echo output
let elem = input("Enter # to paste:")
" Ensure we get only the numeric value (trim it)
let elem = matchstr(elem, '\d\+')
if elem == ''
" They most likely pressed enter without entering a value
return
endif
if index(valid_choices, elem) != -1
exec 'YRGetElem ' . elem
else
" User did not choose one of the elements that were found
" Remove leading ,
call s:YRWarningMsg( "YR: Item[" . elem . "] not found, only valid choices are[" .
\ join(valid_choices, ',') .
\ "]"
\ )
return -1
endif
else
call s:YRWarningMsg( "YR: The pattern [" .
\ s:yr_search .
\ "] does not match any items in the yankring"
\ )
endif
endif
endfunction
" Resets the common script variables for managing the ring.
function! s:YRReset()
call s:YRHistoryDelete()
" Update the history file
call s:YRHistorySave()
endfunction
" Clears the yankring by simply setting the # of items in it to 0.
" There is no need physically unlet each variable.
function! s:YRInit(...)
let s:yr_next_idx = 0
let s:yr_last_paste_idx = 1
let s:yr_count = 0
let s:yr_history_last_upd = 0
let s:yr_history_list = []
let s:yr_paste_dir = 'p'
" For the . op support
let s:yr_prev_op_code = ''
let s:yr_prev_op_mode = 'n'
let s:yr_prev_count = ''
let s:yr_prev_reg = ''
let s:yr_prev_reg_unnamed = getreg('"')
let s:yr_prev_reg_small = ''
let s:yr_prev_reg_insert = ''
let s:yr_prev_reg_expres = ''
let s:yr_prev_clipboard_star = ''
let s:yr_prev_clipboard_plus = ''
let s:yr_prev_vis_lstart = 0
let s:yr_prev_vis_lend = 0
let s:yr_prev_vis_cstart = 0
let s:yr_prev_vis_cend = 0
let s:yr_prev_changenr = 0
let s:yr_prev_repeating = 0
" This is used to determine if the visual selection should be
" reset prior to issuing the YRReplace
let s:yr_prev_vis_mode = 0
if a:0 == 0 && g:yankring_persist != 1
" The user wants the yankring reset each time Vim is started
call s:YRClear()
endif
call s:YRHistoryRead()
endfunction
" Clears the yankring by simply setting the # of items in it to 0.
function! s:YRClear()
call s:YRReset()
call s:YRInit('DoNotClear')
" If the yankring window is open, refresh it
call s:YRWindowUpdate()
endfunction
" Determine which register the user wants to use
" For example the 'a' register: "ayy
function! s:YRRegister()
" v:register can be blank in some (unknown) cases
" so test for this condition and return the
" default register
let user_register = ((v:register=='')?('"'):(v:register))
let clipboard_default = matchstr( &clipboard, '\<unnamed\w*\>' )
" clipboard can have a comma separated list of values.
" Depending on which order the unnamed is referenced
" determines which register to use.
" set clipboard=unnamedplus,unnamed
" set clipboard=unnamed,unnamedplus
if clipboard_default == '\<unnamed\>' && user_register == '"'
let user_register = '*'
endif
if has('unnamedplus') && clipboard_default == '\<unnamedplus\>' && user_register == '"'
let user_register = '+'
endif
return user_register
endfunction
" Allows you to push a new item on the yankring. Useful if something
" is in the clipboard and you want to add it to the yankring.
" Or if you yank something that is not mapped.
function! s:YRPush(...)
let user_register = s:YRRegister()
if a:0 > 0
" If no yank command has been supplied, assume it is
" a full line yank
let user_register = ((a:1 == '') ? user_register : a:1)
endif
" If we are pushing something on to the yankring, add it to
" the default buffer as well so the next item pasted will
" be the item pushed
let default_buffer = ((&clipboard=~'\<unnamed\>')?'*':((&clipboard=~'\<unnamedplus\>' && has('unnamedplus'))?'+':'"'))
call setreg(default_buffer, getreg(user_register),
\ getregtype(user_register))
call s:YRSetPrevOP('', '', '', 'n')
call YRRecord(user_register)
endfunction
" Allows you to pop off any element from the yankring.
" If no parameters are provided the first element is removed.
" If a vcount is provided, that many elements are removed
" from the top.
function! s:YRPop(...)
if s:yr_count == 0
call s:YRWarningMsg('YR: yankring is empty')
return
endif
let v_count = 1
if a:0 > 1
let v_count = a:2
endif
" If the user provided a parameter, remove that element
" from the yankring.
" If no parameter was provided assume the first element.
let elem_index = 0
if a:0 > 0
" Get the element # from the parameter
let elem_index = matchstr(a:1, '\d\+')
let elem_index = elem_index - 1
endif
" If the user entered a count, then remove that many
" elements from the ring.
while v_count > 0
call s:YRMRUDel('s:yr_history_list', elem_index)
let v_count = v_count - 1
endwhile
" If the yankring window is open, refresh it
call s:YRWindowUpdate()
endfunction
" Adds this value to the yankring.
function! YRRecord(...)
let register = '"'
if a:0 > 0
" If no yank command has been supplied, assume it is
" a full line yank
let register = ((a:1 == '') ? register : a:1)
endif
" v:register can be blank in some (unknown) cases
" if v:register == '' || v:register == '_'
if v:register == '_'
" Black hole register, ignore recording the operation
return ""
endif
let register = ((&clipboard=~'\<unnamed\>')?'*':((&clipboard=~'\<unnamedplus\>' && has('unnamedplus'))?'+':register))
" let s:yr_prev_changenr = changenr()
if register == '"'
" If the change has occurred via an omap, we must delay
" the capture of the default register until this event
" since register updates are not reflected until the
" omap function completes
let s:yr_prev_reg_unnamed = getreg('"')
let s:yr_prev_reg_small = getreg('-')
endif
" Add item to list
" This will also account for duplicates.
call s:YRMRUAdd( 's:yr_history_list'
\ , getreg(register)
\ , getregtype(register)
\ )
if g:yankring_clipboard_monitor == 1
let s:yr_prev_clipboard_plus = getreg('+')
let s:yr_prev_clipboard_star = getreg('*')
endif
" Manage the numbered registers
if g:yankring_manage_numbered_reg == 1
" Allow the user to define an autocmd to dynamically
" setup their connection information.
silent! doautocmd User YRSetNumberedReg
endif
" If the yankring window is open, refresh it
call s:YRWindowUpdate()
" Reset the past paste entry to the top of the ring.
" When the user hits replace last entry it should
" start from the top (not from the last previous
" replace) after capturing a new value in the YankRing.
let s:yr_last_paste_idx = 1
return ""
endfunction
" Adds this value to the yankring.
function! YRRecord3(...)
let register = '"'
if a:0 > 0 && a:1 != ''
let register = a:1
else
" v:register can be blank in some (unknown) cases
" if v:register == '' || v:register == '_'
if v:register == '_'
" Black hole register, ignore recording the operation
return ""
endif
let register = s:YRRegister()
if &clipboard =~ '\<unnamed\>' && register == '*'
" unnamed A variant of "unnamed" flag which uses the clipboard
" register '*' (|quote|) for all operations except yank.
" Yank shall copy the text into register '*' when "unnamed"
" is included.
"
let register = '*'
" The + and * registers are not modified by yank operations.
" We do not know what operation triggered this event so do a
" simple check if the register values have changed.
" If not, check it against the " register. Use which ever
" one has changed.
if s:yr_prev_clipboard_star == '' || getreg(register) == s:yr_prev_clipboard_star
if getreg('"') != getreg(register)
let register = '"'
endif
endif
endif
if has('unnamedplus') && &clipboard =~ '\<unnamedplus\>' && register == '+'
" unnamedplus A variant of "unnamed" flag which uses the clipboard
" register '+' (|quoteplus|) instead of register '*' for all
" operations except yank. Yank shall copy the text into
" register '+' and also into '*' when "unnamed" is included.
"
let register = '+'
" The + and * registers are not modified by yank operations.
" We do not know what operation triggered this event so do a
" simple check if the register values have changed.
" If not, check it against the " register. Use which ever
" one has changed.
if s:yr_prev_clipboard_plus == '' || getreg(register) == s:yr_prev_clipboard_plus
if getreg('"') != getreg(register)
let register = '"'
endif
endif
endif
endif
if register == '"'
" If the change has occurred via an omap, we must delay
" the capture of the default register until this event
" since register updates are not reflected until the
" omap function completes
let s:yr_prev_reg_unnamed = getreg('"')
let s:yr_prev_reg_small = getreg('-')
endif