From f43b19edf370415a38b1aa5dc5c4be3d2f611255 Mon Sep 17 00:00:00 2001 From: amix Date: Mon, 4 Jun 2012 17:20:39 -0400 Subject: [PATCH] Downgraded to version 1.2 of YankRing (the neweset version has a huge bug with visual mode paste p and P) --- sources_forked/yankring/doc/yankring.txt | 1475 +++++++++++ sources_forked/yankring/plugin/yankring.vim | 2544 +++++++++++++++++++ sources_plugins/YankRing | 1 - 3 files changed, 4019 insertions(+), 1 deletion(-) create mode 100755 sources_forked/yankring/doc/yankring.txt create mode 100755 sources_forked/yankring/plugin/yankring.vim delete mode 160000 sources_plugins/YankRing diff --git a/sources_forked/yankring/doc/yankring.txt b/sources_forked/yankring/doc/yankring.txt new file mode 100755 index 00000000..9e2287c7 --- /dev/null +++ b/sources_forked/yankring/doc/yankring.txt @@ -0,0 +1,1475 @@ +*yankring.txt* For Vim version 7.0. + +Author: David Fishburn September 16, 2011 +Version: 12.0 + +For instructions on installing this file, type + :help add-local-help |add-local-help| inside Vim. + +Homepage: http://vim.sourceforge.net/script.php?script_id=1234 + + +============================================================================== +1. Contents *yankring* *yankring-contents* + + 1. Contents...............................: |yankring-contents| + 2. Description............................: |yankring-description| + 3. Configuration..........................: |yankring-configure| + 3.1 Global Variables...................: |yankring-globals| + 3.2 Default Keys.......................: |yankring-mappings| + 3.3 Customizing Maps...................: |yankring-custom-maps| + 3.4 Customizing Menus..................: |yankring-custom-menus| + 4. Using the YankRing Window..............: |yankring-window| + 5. Commands...............................: |yankring-commands| + 5.1 YRToggle..........................: |YRToggle| + 5.2 YRClear...........................: |YRClear| + 5.3 YRShow............................: |YRShow| + 5.5 YRGetElem.........................: |YRGetElem| + 5.6 YRGetMultiple.....................: |YRGetMultiple| + 5.7 YRPush............................: |YRPush| + 5.8 YRPop.............................: |YRPop| + 5.9 YRYankCount.......................: |YRYankCount| + 5.10 YRYankRange.......................: |YRYankRange| + 5.11 YRDeleteRange.....................: |YRDeleteRange| + 5.12 YRPaste...........................: |YRPaste| + 5.13 YRReplace.........................: |YRReplace| + 5.14 YRMapsCreate......................: |YRMapsCreate| + 5.15 YRMapsDelete......................: |YRMapsDelete| + 5.16 YRSearch..........................: |YRSearch| + 5.17 YRRunAfterMaps....................: |yankring-custom-maps| + 6. Tutorial...............................: |yankring-tutorial| + 6.1 YRShow............................: |YRShow-example| + 6.2 YRReplace.........................: |YRReplace-example| + 6.3 YRPush............................: |YRPush-example| + 6.4 YRClear...........................: |YRClear-example| + 6.8 YRPop.............................: |YRPop-example| + 6.9 Visual modes......................: |yankring-visual-example| + 6.10 Using ranges......................: |YRYankRange-example| + 6.11 :global...........................: |global-example| + 6.12 YRSearch..........................: |YRSearch-example| + 7. History................................: |yankring-history| + + +============================================================================== +2. Description *yankring-description* + +Vim already maintains a list of numbered registers containing the last 9 +deletes. These previous deletes can be referenced using [register]p, so +"1p will paste the last delete, "2p the 2nd last delete. For more +information see |quote_number|. + +Vim does not provide any mechanism to reference previously yanked text. +In Emacs this feature is called the "kill ring". + +The YankRing plugin allows the user to configure the number of yanked +and deleted text. After text has been pasted, it can be replaced with +a previous value from the yankring. + +As of version 3.0, the yankring's content will persist (by default) +between starting and stopping Vim. + +The plugin can be toggled on and off, and supports: + Ranges + Registers + Counts + All visual modes + All motions + All text-objects + +If you have any suggestions for the improvement of this plugin, see the +yankring.vim file for my email address. Suggestions / bug reports are +always welcome. + +For details on the changes between versions see |yankring-history|. + + +============================================================================== +3. Configuration *yankring-configure* + +The YankRing allows the user to choose which keys are to be assigned to +the various commands. By default, the YankRing chose keys identical +with Vim's standard behaviour/keys. + +3.1 Global Variables *yankring-globals* + +You can customize the YankRing by setting various global variables in +your |.vimrc|. +> + yankring_max_history +< Default: 100 + Controls how many elements to save in the yankring. > + let g:yankring_max_history = 100 + yankring_min_element_length +< Default: 1 + If the yanked element has a length less than this value + if will not be added to the YankRing. This can be useful if + you want to bypass single letter deletes by adding the + following to your .vimrc: > + let g:yankring_min_element_length = 2 + yankring_max_element_length +< Default: 1048576 (1M) + Will truncate a new entry to the specified maximum. If + g:yankring_max_element_length is set to 0, there is no limit. > + let g:yankring_max_element_length = 4194304 " 4M + yankring_max_display +< Default: 500 + When the YankRing window is opened, each element is displayed on a + separate line. Since each yank could be very large, the display of + the element is limited to the above default. > + let g:yankring_max_display = 70 + yankring_enabled +< Default: 1 + If you do not want to YankRing enabled by default, set this + variable in your |vimrc|. > + let g:yankring_enabled = 0 " Disables the yankring + yankring_persist +< Default: 1 + If you have enabled the storing of global variables in the |viminfo| + file, the YankRing will be default persist the contents of the ring + between starting and stopping Vim. To disable this feature: > + let g:yankring_persist = 0 + yankring_share_between_instances +< Default: 1 + By default, any instance of Vim will share the same yankring + history file. But if want each instance to have their own history + you can set this option to 0. Setting g:yankring_persist = 0 and + g:yankring_share_between_instances = 0 will ensure no 2 instances + of Vim share the same YankRing history AND the history is not + remembered the next time Vim is started. > + let g:yankring_share_between_instances = 0 + yankring_dot_repeat_yank +< Default: Based on the Vim cpoption setting + By default Vim will not repeat (using '.') yanking of text. This can + be controlled via the |'cpoptions'| setting. The YankRing now respects + the cpoptions setting, if 'y' is included and you press '.', the + previous yank command is repeated and added to the yankring. + You can also add this behaviour by setting this in your |vimrc|: > + let g:yankring_dot_repeat_yank = 1 + yankring_ignore_duplicate +< Default: 1 + Duplicates will not be added to the YankRing by default. If a + duplicate is found, that 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 + yankring_map_dot +< Default: 1 + If the '.' (repeat) command should be mapped by the yankring. Since + most of the normal commands yy,dd,dw,... are mapped by the yankring, + if g:yankring_map_dot is false the . operator will not repeat these + operations. The YankRing tracks several of the internal Vim registers + and decides whether an action was the result of the YankRing or an + action outside of it. If the previous action was a result of the + yankring, it will be executed again. If it was an action outside of + the yankring, it asks Vim to repeat the command. > + let g:yankring_map_dot = 1 + yankring_paste_using_g +< Default: 1 + By default [p] and [P] are mapped to interact with the yankring. This + option controls whether [gp] and [gP] are also mapped. Setting this + option to 0 will not create these maps. > + let g:yankring_paste_using_g = 1 + yankring_window_use_separate +< Default: 1 + This is a new feature as of the 2.0 release. The YankRing now uses a + separate split buffer to display the yankring. There are many buffer + specific maps that allow you to operate over the various elements from + within the yankring. Setting this option to 0, uses the 1.0 + interface. > + let g:yankring_window_use_separate = 0 + yankring_window_auto_close +< Default: 1 + By default once you choose an option in the YankRing buffer, the + action is performed and the buffer window is closed, returning you to + the original buffer. This option can be toggled from within the + YankRing buffer by pressing [a]. The YankRing buffer status line + visually indicates where auto close is enabled or disabled. There are + many times where you need to paste (or delete) many items from the + yankring. Pressing [a], disables auto close, allows you to paste many + items, and finally you can press [a] to re-enable auto close, followed + by [q] to quit the buffer window. > + let g:yankring_window_auto_close = 1 + yankring_window_use_horiz +< Default: 1 + When the YankRing window is opened, it uses a horizontal split at the + bottom of the Vim window. It can optionally use a vertical split by + setting this option to 0. > + let g:yankring_window_use_horiz = 0 " Use vertical split + yankring_window_height +< Default: 1 + If using a horizontal split, this option controls how high to make + the window. > + let g:yankring_window_height = 8 + yankring_window_width +< Default: 1 + If using a vertical split, this option controls how wide to make the + window. > + let g:yankring_window_width = 30 + yankring_window_use_bottom +< Default: 1 + If using a horizontal split, this option control whether the window is + opened at the top or bottom of the Vim window. Setting this option to + 0 forces the window to open at the top of the Vim window. > + let g:yankring_window_use_bottom = 1 + yankring_window_use_right +< Default: 1 + If using a vertical split, this option control whether the window is + opened on the left or right side of the Vim window. To force the + window to open on the left side, set this option to 0. > + let g:yankring_window_use_right = 1 + yankring_window_increment +< Default: 1 + If using a vertical split the default width of the vertical window may + be too narrow to view enough of the elements. Pressing [] will + increase the size of the window by this number of columns. Pressing + [] again will toggle it back to the original size. > + let g:yankring_window_increment = 50 + yankring_manage_numbered_reg +< Default: 0 + Vim already maintains a list of numbered registers containing the last + yanked item and the previous 9 deletes. These items can be referenced + using [register]p, so "0p will paste the last yank, "1p will paste the + last delete, "2p the 2nd last delete. For more information see + |quote_number|. + If you wish the YankRing to maintain these numbered registers so + the top 10 elements in the YankRing are in the numbered reqisters 0-9 + you can put the following in your |vimrc| > + let g:yankring_manage_numbered_reg = 1 + yankring_ignore_operator +< Default: 'g~ gu gU ! = gq g? > < zf g@' + There are a number of Vim operations which do not change any + registers, and therefore should not be captured by the yankring. + This list is used to ignore the appropriate operators. + You can put the following in your |vimrc| > + let g:yankring_ignore_operator = 'g~ gu gU ! = gq g? > < zf g@' + yankring_history_dir +< Default: $HOME + The YankRing stores the text in a file. This global variable + allows you to customize where the file(s) will be stored. + You can put the following in your |vimrc| > + let g:yankring_history_dir = '$VIM' + yankring_history_file +< Default: 'yankring_history' + The history filename prefix can be controlled by setting this + variable. + You can put the following in your |vimrc| > + let g:yankring_history_file = 'my_yankring_history_file' + yankring_clipboard_monitor +< Default: 1 + When flipping between applications I find I often copy text + and attempt to use it inside of Vim. This is typically easy + by simply using "+p, but there are times when I will repeatedly + want to use the same text later on. By default, the YankRing + will detect when Vim regains focus and check if the clipboard + has changed since it last checked. If so, it will add the contents + of the clipboard to the YankRing. To disable this feature + you can put the following in your |vimrc| > + let g:yankring_clipboard_monitor = 0 + yankring_paste_check_default_buffer +< Default: 1 + If the default register has changed without the YankRing registering + the change the YankRing will paste the top item from the history + rather than what is currently in the default register. + This option allows you to control the behaviour. Plugins can + intentionally change the default buffer which the YankRing has + no way to noticing. To disable this feature you can put the following + in your |vimrc| > + let g:yankring_paste_check_default_buffer = 0 + yankring_default_menu_mode +< - Menus are useful for a number of reasons: + See a list of available commands. + Remember what the shortcut maps are. + Have a floating menu when using the plugin a lot. + Quick reference guide. + There are four settings that will control the placement + of the menu: + "0": Turns the menu off. + "1": Turns the 'Yankring' menu on with no menu shortcut. + "2": Turns the 'Yankring 'menu on with -y as the shortcut. + "3": Turns the 'Plugin -> YankRing' menu on with -y as + the shortcut. + This option defaults to a value of 3 and can be changed + by adding the following to your vimrc: > + :let g:yankring_default_menu_mode = 3 + yankring_menu_root +< - Can be used in conjuction with g:yankring_default_menu_mode = 3 but + it also allows you to control the fullname and location of the + YankRing menu. To create the menu: 'MyPlugins -> YankRing' you + can create the following variable: > + :let g:yankring_menu_root = 'MyPlugin.&YankRing' + yankring_menu_priority +< - Menus are created in a documented order by Vim (|menu-priority|). + This option allows you to override the setting and shift the + YankRing menu item to the left between the Edit and Tools menu. > + :let g:yankring_menu_priority = 30 + +< +3.2 Default Keys *yankring-mappings* + +You can choose to override the default keys by creating these global +variables in your |vimrc|. +> + yankring_n_keys +< n - normal mode + Default Vim 7.2: + 'Y D x X' + Default Vim 7.1 and below: + 'x yy dd yw dw ye de yE dE yiw diw yaw daw y$ d$ Y D yG dG ygg dgg' + + With the introduction of some new features in Vim 7.2 it is no longer + necessary to list all cmds which the YankRing will act upon. + The yankring_n_keys only lists actions which an omap cannot be used. + Using the yankring_separator, the above list is parsed and + individual mappings are created. For each of the above normal + commands the YankRing will include the text those commands + acted upon. There are many ways to accomplish the same result + in Vim, if you do not see a common key stroke you regularly use + simply add the following to your |vimrc| with the additional + keys you wished mapped. > + let g:yankring_n_keys = 'Y D x X' + yankring_o_keys +< o - omap mode + Default: + Standard motions: 'b B w W e E d y $ G ;' + Vim text objects: ' 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`' + + As of Vim 7.2 omaps are used to capture changes to the registers + in Vim. All of the standard motion commands are captured. + New to YankRing 5.0 all default Vim text objects are also + captured. + Using the yankring_separator, the above list is parsed and + individual mappings are created. For each of the above normal + commands the YankRing will include the text those commands + acted upon. There are many ways to accomplish the same result + in Vim, if you do not see a common key stroke you regularly use + simply add the following to your |vimrc| with the additional + keys you wished mapped. > + let g:yankring_o_keys = 'b B w W e E d y $ G ; iw iW aw aW' + yankring_zap_keys +< Default: 'f F t T / ?' + omaps are enough for most operations except for f and t. + These motions prompt the user for a character or string which + they should act upon. These must be treated as a special case + in YankRing. > + let g:yankring_zap_keys = 'f t' + yankring_ignore_operator +< Default: 'g~ gu gU ! = gq g? > < zf g@' + There are certain motions which do not update any registers + in Vim. If the registers are not changed, there is nothing + the YankRing can capture. This list instructs the YankRing + to ignore any action for these keys. > + let g:yankring_ignore_operator = 'g~ gu gU' + yankring_v_key +< v - visual mode + Default: y + Yanks visually select text. > + yankring_del_v_key +< n - normal mode + Default: d + The visually select text is included in the YankRing and deleted. > + yankring_paste_n_bkey +< n - normal mode + b - before + Default: P + The default Vim paste key will retrieve from the yankring. This + will paste the text BEFORE the current position. + There is a special check to see if the text in the default paste + register is the same as what is in the current position of the + yankring. If it is not, we assume the user used some other + mechanism to yank text (ie yt). If this is the case + we paste the text in the default paste buffer. Using the + text can be replaced with the current entry from the yankring. + Since there are many ways to do things in Vim, this provides + the best integration. > + yankring_paste_n_akey +< n - normal mode + a - after + Default: p + The default Vim paste key will retrieve from the yankring. This + will paste the text AFTER the current position. + There is a special check to see if the text in the default paste + register is the same as what is in the current position of the + yankring. If it is not, we assume the user used some other + mechanism to yank text (ie yt). If this is the case + we paste the text in the default paste buffer. Using the + text can be replaced with the current entry from the yankring. + Since there are many ways to do things in Vim, this provides + the best integration. > + yankring_paste_v_key +< n - normal mode + Default: p + This will replace the visually select text with the contents + from the yankring. See yankring_paste_n_akey for additional + details. > + yankring_replace_n_pkey +< n - normal mode + Default: + If you do not want to open the YankRing window to choose your + selection, then you can paste (as usual) then use a YankRing + mapping to cycle through items in the YankRing. This is especially + useful if you know you recently used the text you are looking for. + If you wish to cycle through the yankring, replacing the previously + pasted text with the previous yanked text you can repeatedly press + (or whatever keystroke you choose to map it to). This map + moves backwards through the yankring, so you will retrieve your + most recent yank. + + I prefer not to use since I like using that key to cycle + through all the matches in the QuickFix window. You can add + something similar to this in your |.vimrc| to get similar + functionality. + + On Windows use the ALT-< character to move through the YankRing. + To determine what character # these are go into insert mode + in a new buffer. Press CTRL-V then ALT and the < key. + Leave insert mode, move the cursor onto the character + and press ga. This will display the decimal, hex and octal + representation of the character. In this case it is 172. > + if has('win32') + let g:yankring_replace_n_pkey = '' + let g:yankring_replace_n_nkey = '' + " Instead map these keys to moving through items in the quickfix window. + nnoremap :cp + nnoremap :cn + endif +< Other users have also stated that this will work: > + let g:yankring_replace_n_pkey = '' + let g:yankring_replace_n_nkey = '' + yankring_replace_n_nkey +< n - normal mode + Default: + If you do not want to open the YankRing window to choose your + selection, then you can paste (as usual) then use a YankRing + mapping to cycle through items in the YankRing. This is especially + useful if you know you recently used the text you are looking for. + If you wish to cycle through the yankring, replacing the previously + pasted text with the next yanked text you can repeatedly press + (or whatever keystroke you choose to map it to). This map + moves forwards through the YankRing, so you will retrieve your + most recent yank. + + I prefer not to use since I like using that key to cycle + through all the matches in the QuickFix window. You can add + something similar to this in your |.vimrc| to get similar + functionality. + + On Windows use the ALT-> character to move through the YankRing. + To determine what character # these are go into insert mode + in a new buffer. Press CTRL-V then ALT and the > key. + Leave insert mode, move the cursor onto the character + and press ga. This will display the decimal, hex and octal + representation of the character. In this case it is 174. > + if has('win32') + let g:yankring_replace_n_pkey = '' + let g:yankring_replace_n_nkey = '' + " Instead map these keys to moving through items in the quickfix window. + nnoremap :cp + nnoremap :cn + endif +< Other users have also stated that this will work: > + let g:yankring_replace_n_pkey = '' + let g:yankring_replace_n_nkey = '' + +3.3 Customizing Maps *yankring-custom-maps* + +The YankRing plugin uses the yankring_n_keys global variable to create +a number of defaults maps. The maps are of the form: > + nnoremap Y :YRYankCount 'Y' +< +When capital Y is pressed, the YankRing will execute 'Y' and capture the +output from Vim. But there are cases where you do not want the default +behaviour of Vim, since you have customized some of these maps. + +In this case, I usually map Y to be |y$|, which makes it consistent with +the |D| and |C| operators. The way yankring_n_keys works does not allow +me to customize this behaviour. Since many people may like to customize +the behaviour of these maps the YankRing will check to see if a +function called YRRunAfterMaps() exists. If it does, it will call +this function after it has created the maps. So in my case, I created +the following function in my |vimrc|: > + function! YRRunAfterMaps() + nnoremap Y :YRYankCount 'y$' + endfunction +< +You can do anything you need in this function. > + nnoremap Y :YRYankCount 'y$' +< +This line remaps Y (which the user presses) to the YRYankCount command. The +YRYankCount tells Vim to execute y$ instead. + +3.4 Customizing Menus *yankring-custom-menus* + +There are several global variables which can be created in your vimrc to +allow you to customize where and what is displayed for the YankRing menu. +Simply look up the following global variables: > + yankring_default_menu_mode + yankring_menu_root + yankring_menu_priority + + +============================================================================== +4. Using the YankRing Window: *yankring-window* + +This is a new feature as of the 2.0 release. The YankRing uses a +separate split buffer to display the yankring. There are many buffer +specific maps that allow you to operate over the various elements from +within the yankring. + +To display the YankRing buffer you can issue the :YRShow command. For +convience you can map a key, , to this command: > + :nnoremap :YRShow + +Status line~ +The first line in the YankRing window is the status line. > + AutoClose=1;ClipboardMonitor=1;Cmds:p,P,d,r,s,a,c,u,q,,;Help=? +< +Help=?, pressing [?] will toggle the display of available commands the +yankring window supports. Pressing [?] again will remove the additional +items. + +AutoClose=1 indicates the window will close when an action is performed +against elements within the yankring. If you wish to perform multiple +yankring operations press [a] to toggle the auto close feature off. Use the +commands below and when finished you can press [a] to toggle auto close on and +press [q] to close the window. The Cmds displayed are simply reminders of +the available keys. + +ClipboardMonitor=1 indicates the YankRing will monitor the clipboard (+) +during Focus change events. If the clipboard has changed since the YankRing +last checked, the contents are added to the YankRing. Pressing [c] allows +you to quickly toggle this setting since it may not be useful at times. + +YankRing window key list~ +The following table lists the description of the keys that can be used +in the YankRing window. + + Key Description~ + p Puts text after the cursor. In visual mode, all elements + selected will be pasted. + P Puts text before the cursor. In visual mode, all elements + selected will be pasted. + gp Just like "p", but leave the cursor just after the new text. + gP Just like "P", but leave the cursor just after the new text. + Just like "p". + Just like "p". + <2-LeftMouse> Just like "p". Normal mode only. + d Removes the element from the yankring. In visual mode all + elements selected will be removed. + r Just like "p", but in visual mode if many lines are selected + it will paste these in reverse order. + s Prompts you for a regex to search the YankRing and display + only matching items. + a Toggles the g:yankring_window_auto_close setting. + u Updates the YankRing window. + q Closes the YankRing window. + Toggles the width of the vertical window by the + g:yankring_window_increment setting. + ? Toggles the display of the help. + + +============================================================================== +5. Commands: *yankring-commands* + +The predefined mappings call some specific commands with special parameters. +If you are going to create additional maps, it is important you mirror +the same parameters. Most of these commands have been made obsolete by +the YankRing window, since it incorporates the functionality below, but +through maps against a buffer, instead of commands. This makes it much easier +to use. + + +5.1 YRToggle *YRToggle* + Allows you to enable and disable the YankRing quickly. This + command will remove the default maps and recreate them. + + Examples: > + :YRToggle " Toggles it + :YRToggle 1 " Enables it + :YRToggle 0 " Disables it +< + +5.2 YRClear *YRClear* + Clears all elements from the yankring. + See also |YRClear-example|. + + +5.3 YRShow *YRShow* + Similar to |:register|, will display all the entries in the yankring. + The element at the top will be the next element pasted from the + yankring. + + Examples: > + :YRShow " Shows all entries in the yankring + + --- YankRing --- + Elem Content + 1 five^@ + 2 four^@ + 3 three^@ + 4 two^@ + 5 one^@ +< + +5.5 YRGetElem *YRGetElem* + This command has two modes. If no parameters are provided, it + becomes interactive. It uses YRShow to display the list and + allows you to choose which element to paste. If a parameter + is supplied it will paste that element from the yankring. If the + number specified is outside of the YankRing an error is returned. + You may want to create a separate mapping for this call. > + nnoremap yr :YRGetElem +< See also |YRSearch|. + + Examples: + Assume there are 10 elements in the YankRing and element 6 is + at the top of the ring. > + :YRGetElem " Interactive mode, you choose from a list + :YRGetElem 4 " Will paste element 5. + :YRGetElem 12 " Will paste element 6. + :YRGetElem 99 " Error, invalid choice is reported + :YRGetElem 0 " Error, invalid choice is reported + + +5.6 YRGetMultiple *YRGetMultiple* + Will paste many elements from the YankRing in one command. + If the number specified is 1 or less, it is assumed you want + just the current element pasted. If the number specified is + greater than or equal to the number of elements in the yankring, + it is assumed you want all elements pasted. If a ! is included + as part of the command, paste the items in reverse order. + See the |yankring-tutorial| for more examples. + + Examples: + Assume there are 10 elements in the YankRing. > + :YRGetMultiple 4 " Will paste elements 1,2,3,4 + :YRGetMultiple! 4 " Will paste elements 4,3,2,1 + :YRGetMultiple " Will paste element 1 + :YRGetMultiple 12 " Will paste elements 1,2,...,10 + :YRGetMultiple 99 " Will paste elements 1,2,...,10 + :YRGetMultiple 0 " Will paste element 1 + + +5.7 YRPush *YRPush* + Allows the user to "push" additional entries into the yankring. + If you yanked text via a key mapping which does not use the + YankRing (or there is text on the clipboard) you can use this + command to add the text to the yankring. + + Examples: > + :YRPush " Push the " register's contents + :YRPush '*' " Push the "* register's contents (clipboard) + :YRPush '+' " Push the "+ register's contents (clipboard) + :YRPush 'a' " Push the "a register's contents +< See also |YRPush-example|. + + +5.8 YRPop *YRPop* + Allows you to pop any elements from the yankring. If no parameters + are provided, the 1st element is removed from the yankring. The + command optionally takes a second parameter to specify how many + elements to pop. The default value is 1. + + Examples: > + :YRPop " Removes the highest numbered element from the + yankring + :YRPop 3 " Removes the 3rd element from the yankring + :YRPop 3,5 " Removes 5 elements from the YankRing beginning + at element 3 +< See also |YRPop-example|. + + +5.9 YRYankCount *YRYankCount* + This command has the most mappings created for it. If you are + in normal mode and you are not specifying a range, this command + will add the text to the yankring. + + The goal of this command is to allow the YankRing to be integrated + as seamlessly as possible with Vim. So it supports counts and + registers. If you create a mapping to it, you must pass as a + parameter the action you want Vim to perform. You could do the + following: > + nnoremap \test :YRYankCount 'dd' +< This map is executed when you hit the '\test' keystrokes, but + it will actually delete the current line and add it to the + yankring. + + The following are the default mappings: > + nnoremap yy :YRYankCount 'yy' + nnoremap dd :YRYankCount 'dd' + nnoremap yw :YRYankCount 'yw' + nnoremap dw :YRYankCount 'dw' + nnoremap ye :YRYankCount 'ye' + nnoremap de :YRYankCount 'de' + nnoremap yiw :YRYankCount 'yiw' + nnoremap diw :YRYankCount 'diw' + nnoremap Y :YRYankCount 'Y' + nnoremap D :YRYankCount 'D' + nnoremap y$ :YRYankCount 'y$' + nnoremap d$ :YRYankCount 'd$' + nnoremap yG :YRYankCount 'yG' + nnoremap dG :YRYankCount 'dG' +< + Examples: + yy - Adds the current line to the yankring. + dd - Adds the current line to the YankRing and deletes it. + 5yw - Adds 5 words to the yankring. + "ade - Deletes the word, and puts it into both the yankring + and the "a register. + 10"zyy - Places 10 lines into both the YankRing and the "z + register. + See also |yankring-tutorial|. + + +5.10 YRYankRange *YRYankRange* + This command by default is only called in visual mode. All + visual modes (|characterwise-visual|, |linewise-visual|, + |blockwise-visual|) are supported. Any visually selected text + is added to the yankring. You can also call this command + directly using a range. + + Examples: + Visual mode + ----------- + Press v (to enter visual mode), highlight want you want, + press y (to yank the selected area). + Repeat using V and Control-V. + + Normal mode + ----------- > + :5,20YRYankRange " Will yank lines 5-20 into the yankring + :5,20YRDeleteRange " Will delete lines 5-20 and add them to + the yankring +< See also |YRYankRange-example|. + + +5.11 YRDeleteRange *YRDeleteRange* + This command is identical to YRYankRange, except the range is + also deleted. + + +5.12 YRPaste *YRPaste* + This command will paste elements from the yankring. By default it has + been mapped to p and P to match Vim's native key strokes. The text + pasted is exactly what was yanked, including newline characters and + blockwise-visual mode behaviours. It supports counts and registers. + + Examples: + p " Paste the current element from the YankRing after the cursor + P " Paste the current element from the YankRing before the cursor + 5p " Paste the current element from the YankRing after the cursor + 5 times + "ap " Ignore the YankRing and paste the contents of register "a + 5"ap " Ignore the YankRing and paste the contents of register "a + 5 times + See also |yankring-tutorial|. + + +5.13 YRReplace *YRReplace* + The purpose of the YankRing is to gain access to previously yanked + (or deleted) elements. This command will replace the previously + paste with a different entry from the yankring. + By default, I choose (P for previous) to replace the last paste + while moving backwards through the yankring. (N for next) + replaces the last paste while moving forward through the yankring. + + Examples: + See the |yankring-tutorial| for examples. + + +5.14 YRMapsCreate *YRMapsCreate* + This public function is responsible for creating the maps which + enable the yankring. This function is called by the YRToggle + command. + + +5.15 YRMapsDelete *YRMapsDelete* + This public function removes the YankRing maps and disables + the yankring. This function is called by the YRToggle command. + + +5.16 YRSearch *YRSearch* + This command is similar to |YRGetElem|. The command takes + one parameter which is a regular expression. Similar to + YRGetElem, it will display all items in the YankRing that match + the regular expression. It is also interactive, and will + prompt you to enter which match you wish pasted. + See also |YRSearch-example|. + + +============================================================================== +6. Tutorial *yankring-tutorial* + +To understand how to use the yankring, the following example will +demonstrate the various features. Assume you have created the following +mapping: > + nnoremap :YRShow +< + Assume we have this buffer: > + one + two + three + four + five +< *YRShow-example* + Now yank (yy) each line separately starting at line 1. + Display the contents of the YankRing by executing the command + YRShow, or pressing . The contents of the YankRing is + displayed in a new buffer. The size, location and type of buffer + is configurable via various options. See section 3 for more details. > + :YRShow or F11 + --- YankRing --- + Elem Content + 1 five^@ + 2 four^@ + 3 three^@ + 4 two^@ + 5 one^@ +< Since we yanked the text starting at line 1 and finishing at + line 5, the most current YankRing element is the last one, the + contents of line 5. "five^@" is displayed, the "^@" is a + newline character (since we issued a "yy"). + + *yankring-window-example* + At this point, you have two options. You can choose which element + from the YankRing you wish to paste and press or 'p' or 'P' + and a variety of other options, see |yankring-window|. After pressing + the key, the YankRing window will close (default behaviour). Pressing + '?' will display additional help for the commands that are active within + the YankRing window. Pressing '?' will toggle the help. + + You do not need to interact with the YankRing using the YankRing window. + Using the window makes many tasks must easier, but for speed using some + of the other maps can be preferrable if you know what you have yanked / + deleted recently. It was designed to work with Vim in the usual manner. + You can press, 'p', to paste the last item in yanked or deleted. + + Close the YankRing window by pressing 'q' or F11 (which toggles it). + + *YRReplace-example* + Now, go to the end of the file and press 'p'. The resulting + buffer appears as: > + one + two + three + four + five + five +< + Assume you did not want 'five", but a different entry from within the + yankring. moves backwards through the yankring, it will replace + the previous pasted text with a different item from the yankring. This + allows you to quickly iterate through different elements. is the + default mapping, this can be user defined. See the following options for + more details: > + yankring_replace_n_nkey, yankring_replace_n_pkey +< + After pressing the buffer results in: > + one + two + three + four + five + four +< Now press 2. This would be the same as pressing + two times in a row. This results in: > + one + two + three + four + five + two +< Now press to move forwards through the yankring, + this results in: > + one + two + three + four + five + three +< Display the contents of the yankring. > + :YRShow + --- YankRing --- + Elem Content + 1 five^@ + 2 four^@ + 3 three^@ + 4 two^@ + 5 one^@ +< + Now lets yank some text with a key stroke that has not been + mapped to the yankring. Place your cursor at the start of + line 4. Press 'ytr', yank-to-(to the character r), which yanks + the 'fou' letters (no newline character). Now press p. Here is + the result: > + one + two + three + ffouour + five + three +< This is good, even though the keys 'ytr' has not been mapped + to YRYankCount, the YankRing still pasted the most recently + yanked text. Since the text did not have a newline character + the 'fou' was inserted after the 'f'. + + Now replace that previous paste with the current element from + the YankRing by pressing . This is the result: > + one + two + three + four + one + five + three +< The #1 entry in the YankRing is still the line "five@". When + choosing the next entry, it wraps around to the last entry in + the yankring, element #5. The 'fou' was replaced with 'one^@'. + Since it had a newline character in it (when it was yanked) the + newline is included when it is pasted. + + *YRPush-example* + Assume you need to paste text from the system clipboard, and this + is text you will need routinely. We can simulate this by running + this command (see |quote+|): > + :let @+ = "From the clipboard\n" + :echo @+ + +< With the cursor at the start of the line with the word 'five', press 'p'. + We still have pasted the 'fou' which is in the default paste buffer. > + one + two + three + four + two + ffouive + three +< We have the option of getting the text from the clipboard directly + with the following. > + First undo the previous change - u + Next - "+p +< The line changes since we bypassed the yankring, and specified + which register to get the text from: > + four + five + From the clipboard + three +< replaces this with the #1 entry in the yankring: > + four + five + five + three +< Now add the contents of the clipboard to the yankring: > + :YRPush '+' +< Move the cursor to the last row 'three' and press 'p'. The result is: > + four + five + one + three + From the clipboard +< YRPush '+' adds the value of the register '+' to the yankring, but it + also adds its contents to the default Vim paste buffer. So pressing + 'p' pasted this text. Adding a new value to the YankRing we have + repositioned it which you can see with: > + :YRShow or F11 + --- YankRing --- + Elem Content + 1 From the clipboard^@ + 2 five^@ + 3 four^@ + 4 three^@ + 5 two^@ + 6 one^@ +< *YRClear-example* + Now we will clear the yankring, and begin over again. Delete all lines + from the buffer and replace them with the original rows: > + one + two + three + four + five +< Now run this command to clear the YankRing to start over: > + :YRClear +< + Issue a 'yy' on each of the 5 lines. If you run the YRShow command you + should see the following: > + :YRShow or F11 + --- YankRing --- + Elem Content + 1 five^@ + 2 four^@ + 3 three^@ + 4 two^@ + 5 one^@ +< *any-item-example* + If you need to quickly browse the YankRing to determine which element you + wish to paste you can simply press 'p' or or on any element + displayed in the YankRing window. Press '?' for more detailed description + of the commands available. + + Using the YankRing window can be much faster if you do not want to cycle + through the YankRing using and to find the element. + + *multiple-items-example* + There are times when you need to move through a buffer capturing many + different lines (or snippets of code) and eventually want to switch + buffers and paste these elements. With some advance planning you can do + this without the YankRing by issuing commands of the form: > + "ayy + "Ayy +< When specifying the register using UPPERCASE, Vim appends the yanked text + to register "a, instead of replacing it. Many times you forget the + advance planning (or didn't even know about this great feature) you can + use the YankRing window to do this easily. If this is the current + yankring: > + :YRShow or F11 + --- YankRing --- + Elem Content + 1 five^@ + 2 four^@ + 3 three^@ + 4 two^@ + 5 one^@ +< The YankRing works in |visual-mode|. To demonstrate move the cursor in + the buffer to the line with 'two'. Press 'F11' to display the yankring + window. Move the cursor to element 2, press 'V' to enable + |linewise-visual| mode and then press 'j' twice. This should have + visually highlighted elements 2,3,4. Press 'p' to paste all the + highlighted elements: > + one + two + four + three + two + three + four + five +< You can see here it has pasted four, three, two after the second line of + the buffer. Now press 'u' to undo our last change. Leave the cursor + on the second line 'two'. Press 'F11' to show the YankRing again. + Visually select the same lines, but this time press 'r' instead of 'p'. + 'r' is for reverse, so it will paste the following: > + one + two + two + three + four + three + four + five +< + *YRGetMultiple-example* + The same behaviour listed above (by visually selecting items in the + YankRing window) can be achieved using the YRGetMultiple command. + Assume there are 10 elements in the YankRing. > + :YRGetMultiple 4 " Will paste elements 1,2,3,4 + :YRGetMultiple! 4 " Will paste elements 4,3,2,1 + :YRGetMultiple " Will paste element 1 + :YRGetMultiple 12 " Will paste elements 1,2,...,10 + :YRGetMultiple 99 " Will paste elements 1,2,...,10 + :YRGetMultiple 0 " Will paste element 1 +< + *YRSearch-example* + The default size of the YankRing is 100 elements. It can be + tedious searching through the YankRing to find the element you + need. YRSearch is similar to YRShow except it will limit the + items displayed to only those items matching the regex provided. > + :YRShow + --- YankRing --- + Elem Content + 1 Three Mississippi + 2 Two Mississippi + 3 One Mississippi + 4 @", '\\/.*$^~[]' ) + :YRSearch Mississippi + --- YankRing --- + Elem Content + 1 Three Mississippi + 2 Two Mississippi + 3 One Mississippi +< Consider some items which require escaping the search string: > + :YRSearch @", '\\ + --- YankRing --- + Elem Content + 1 @", '\\/.*$^~[]' ) +< Forward slashes and various other symbols require escapes, in this + case the slash was not escaped enough: > + :YRSearch @", '\\/ + --- YankRing --- + Elem Content +< There are enough escapes this time: > + :YRSearch @", '\\\\/ + --- YankRing --- + Elem Content + 1 @", '\\/.*$^~[]' ) +< Period, star, dollar and so on require one slash: > + :YRSearch @", '\\\\/\.\*\$\^\~\[\] + --- YankRing --- + Elem Content + 1 @", '\\/.*$^~[]' ) + +< *YRPop-example* + You can remove any element from the YankRing by pressing pressing 'd' from + within the YankRing window. Visual mode is also supported to remove more + than one element at a time. > + :YRShow + --- YankRing --- + Elem Content + 1 four^@ + 2 three^@ + 3 two^@ + 4 one^@ +< Visually select elements 2,3. Press 'd', the result is: > + :YRShow + --- YankRing --- + Elem Content + 1 four^@ + 2 one^@ + +< *yankring-visual-example* + There are 3 visual modes and all are supported. Any visually selected + text is added to the yankring. You can try the various modes. Move + the cursor to inside the buffer (not the YankRing window). + + |characterwise-visual| + Go to line 1, press 'v' and move using the cursor keys until you have + highlighted some text. Then press y to yank the visually selected + area. Pressing p with paste the yanked region. + + |linewise-visual| + Go to line 2, press 'V' and move using the cursor keys until you have + highlighted some text. Notice the entire line is selected (including + the carriage returns). Then press y to yank the visually selected + area. Pressing p with paste the yanked region. + + |blockwise-visual| + Go to line 3 column 4, press CTRL-V and move to the right using the + cursor keys until you have highlighted some text. Then press y to + yank the visually selected area. Pressing p with paste the yanked + region. Notice the pasted text retained its blockwise visual + characteristics. + + *YRYankRange-example* + YRYankRange is called during visual modes, but it is also possible to + use this via the command line. > + :1,4YRYankRange + :3,$YRDeleteRange + :YRShow +< + *global-example* + Using Vim's |:global| command can be very useful at times. The example + adds all rows (in a buffer) to the YankRing if they have a certain + phrase: > + :g/addme/YRYankCount 'yy' +< This is the breakdown for the above command: > + :g - for each line in the buffer + /addme - check if the string "addme" is in the line + /YRYankCount 'yy' - Ask the YankRing to execute the 'yy' command + + +============================================================================== +7. History *yankring-history* + + 12.0: September 16, 2011 + NF: Added support for the clipboard option "unnamedplus" which was + added after 7.3 (Hong Xu). + NF: When displaying the YankRing using YRShow, a new command "R" + has been added to display all of Vim's registers [0-9a-z]. + BF: YRMapsDelete did not remove the normal mode @ map, which + interfers with recorded macros (Philippe Vaucher ). + + 11.0: August 09, 2010 + NF: Documented the global variables to customize the location + of the YankRing menu. + NF: The YankRing menu now shows the maps used for the default + actions to help learn them more easily. + NF: Added g:yankring_menu_root and g:yankring_menu_priority + (David Barsam). + NF: Added a warning indicating a stored value has been truncated + based on g:yankring_max_element_length and a new option to + suppress this warning, g:yankring_warn_on_truncate (Hans-Günter). + BF: The YRAfterMaps() function (if it exists) was not re-run if + YRToggle was used to disable and enable the YankRing. + BF: Multibyte strings may not have been pasted correctly (Dr. Chip). + BF: When pasting a string of 1111's, and additional -1 could also + be included in the output. + + 10.0: January 31, 2010 + NF: Change the buffer name to [YankRing] to resemble other + non-user buffers. + NF: Added g:yankring_min_element_length which can prevent + items from being added to the YankRing if they are too small. + For example, single character deletes (Vedran M). + BF: When shifting focus back to Vim, the YankRing may incorrectly + report: "YR:Failed to change to the yankring buffer, + please contact author". + BF: When entering Vim for the first time and hitting "p" + nothing was pasted (Mark Huiskes). + BF: When entering Vim for the first time and the + yankring_clipboard_monitor = 1, the clipboard entry + was not automatically added to the yankring. + BF: When overriding the default and setting + g:yankring_window_use_bottom = 0, the YankRing would + report the error (Sergey Khorev): + E21: Cannot make changes, 'modifiable' is off + + 9.0: August 29, 2009: + BF: You cannot execute a macro with ":normal @a". It is still + not possible, but you can execute it with ":normal! @a" + (A S Budden). + BF: When g:yankring_persist = 0 the YankRing could go into + an infinite loop (A S Budden). + BF: When replaying a macro which used any of the zap + keys (f,F,t,T,/,?) you were prompted again for the + string to match on (Ovidiu C). + BF: When checking the clipboard for changes + (g:yankring_clipboard_monitor == 1) only add the item + if it is not already in the ring. Previously, the item + was moved to the top of the YankRing each time you flipped + focus. + + 8.0: December 21, 2008: + NF: Changed the implementation of YRGetSearch() (David Liang). + BF: Under some unknown circumstances, the yankring can fail + to change to the correct buffer. Put in code to double + check and abort. + BF: Yanking and pasting a line which ends in a backslash + resulted in the backslash being replaced by "@@@". + BF: When repeating a command (".") which used any of the zap + keys (f,F,t,T,/,?) you were prompted again for the + string to match on (Vasilii Pascal). + + 7.0: November 14, 2008: + NF: Added support for the / and ? motions so that y/search is + supported (Vasilii Pascal). + NF: When the YankRing window is displayed (or updated) an additional + check is made against the default register. If it has changed + since the YankRing recorded it, the value will be added to the + history. + NF: Added support for more motions h, j, k, l, H, M, L, ^, 0, -, +, _. + And a pile of g motions g_, g^, gm, g$, gk, gj, gg, ge, gE. + NF: The YankRing window will display a message it is operating + in a limited mode if not using Vim 7.2 or the correct patch + level. + BF: Correction to some internal code which could lead to an + endless loop (John Beckett). + BF: Opening and closing the YankRing window with "set report=0" + reported "1 line less" messages (Bill McCarthy). + BF: Changed the default value of g:yankring_paste_check_default_buffer + to check if the default paste buffer has changed when pressing + 'p'. For example, if a plugin has changed the default registers + it will be pasted rather than the top item from the YankRing. + BF: YRMapsDelete did not remove all the maps created by the YankRing. + BF: Under particular circumstances, yanking text with embedded @ + characters were not properly stored and retrieved from the + YankRing (Andrew Long). + BF: Changed to use xmaps instead of vmaps so that the maps only work + in visual mode and not select mode (David Liang). + + 6.1: October 31, 2008: + BF: If the g:yankring_history_dir contains spaces (default on + Windows) an error was reported. A simple work around was to + let g:yankring_history_dir = 'c:\Vim' or no spaces (Matt). + + 6.0: October 25, 2008: + NF: The YankRing now maintains the history in a file. This means + if you are running multiple instances of Vim, they all see + the same yankring. + NF: The location and name of the file is configurable by the user. + NF: The g:yankring_separator is no longer used and has been removed. + NF: The g:yankring_max_element_length can be used to limit the size + of an element in the yankring. + NF: The g:yankring_share_between_instances can be used to indicate + whether each instance of Vim running on a machine should share + the history file or whether each should have their own + individual history file. + NF: The g:yankring_clipboard_monitor can be used to indicate + whether changes to the system clipboard should be added to the + YankRing (default is on). + NF: The YankRing window can toggle the clipboard monitor by pressing + 'c'. See the help in the window by pressing ?. + NF: Added some highlighting to the YankRing window (Marty Grenfell). + + 5.0: September 21, 2008: + NF: The YankRing can recognize certain Vim commands which do not + change the contents of a buffer and not attempt to capture it. + NF: The global variables which allow you to customize the behaviour + are now space separated instead of comma separated. This + provides greater flexibility but will require you to modify + your vimrc (if you have customized it). (Andy Wokula) + BF: If using from within insert mode, the YankRing inserted + characters into the buffer instead of capturing the changes, + this was fixed by Andy Wokula (Agathoklis Hatzimanikas). + BF: The YankRing did not properly account for all the different + forms of counts "5yy" worked but "y5y" did not (Edwin Shao). + + 4.1: August 9, 2008: + NF: The YankRing now allows you to override which operators should + be ignored (yankring_ignore_operator). By default this is + set for the standard Vim operators which do not modify any + registers (Examples: = and gu) (Andy Wokula). + NF: The YankRing did not map v_x (Matt Tolton). + BF: The expression register (quote=) was not accounted for correctly + (Agathoklis Hatzimanikas). + BF: Using the v:operator variable must be escaped when used in + a regular expression. + + 4.0: June 24, 2008: + NF: The YankRing by default now captures all |text-objects| and + all motions (|motion.txt|) which Vim supports. Version 3.0 only + supported a subset of the basic motion commands. + NF: Prior to this version only predefined maps triggered the + capture of data into the yankring. These maps only supported + yanks and deletes. The YankRing now also supports + operator-pending mode, which allows a greater range of operations + to be automatically captured and added to the yankring. + Operating pending mode functionality requires Vim 7.2 or Vim 7.1 + with patch #205. If using Vim 7.1 you can determine this with: + echo has("patch205") + NF: Prior to this version only yanks and deletes were registered + in the yankring. Changes are now also captured into the + yankring. + NF: The YankRing will also capture the system cliboard when focus is + returned to the vim window. This is useful if you copy text + between applications. + NF: The YankRing window always opened bottom horizontal. Now it + can be opened top or bottom and horizontal or vertically. + This can be controlled via variables in your .vimrc. + BF: The YankRing has an option to persist between instances + of Vim by storing the values in global variables within + the viminfo. This has led to some unusual ordering of + items in the ring from conflicts between instances. + This option has been turn off by default. + BF: Their was an issue with yanking using y$. + + 3.1: September 10, 2007: + NF: YRClear will now unlet all global variables it uses to store + the data if the persist storage is specified (the default). + Large values in the viminfo file could possibly affect other + applications. + + 3.0: September 7, 2007: + NF: Converted the YankRing to use the new Vim7's List object which + means it is no longer compatible with Vim6. + NF: By default the YankRing will now maintain the yankring's items + persistently by default. It does this via the |viminfo| file. + This means the contents of the YankRing rely on the internal + variables of only 1 Vim instance. + BF: YRToggle was not unmapping 'gp' and 'gP'. + BF: YRSearch prompted the user for a regex even if one was provided + on the command line. + BF: If g:yankring_manage_numbered_reg is enabled, the "." operator + did not correctly repeat the previous action (Pedro DeRose). + + 2.2: November 1, 2005: + NF: Added 'x' to the list of yankring_n_keys. This is very useful + in visual mode since it can delete a lot of characters. + + 2.2: October 19, 2005: + BF: If you pressed '?' to toggle the display of the help in the + YankRing window, the window would close. This also applied to + 'a', which allowed you to toggle the autoclose feature. + + 2.1: October 11, 2005: + NF: Added the ability for the YankRing to override Vim's numbered + registers. Instead of the numbered registers holding the last + yanked value, and the 9 previous deletes, they will now reflect + the top 10 items in the yankring. This allows you to reference + them directly with "5p. + + 2.0: August 20, 2005: + NF: Much improved usability, the YankRing now has a "GUI" to service + the yankring. If YRShow or YRSearch is used, a split buffer is + opened which displays all the elements in the yankring. There + are a number of maps that allow you to interact with the + contents. The window can be positioned vertically or + horizontally as well as being sized all through options + specified in your vimrc. + NF: YRPop can now delete any items from the yankring, rather + that just from the top. + NF: YRSetTop has been removed, it is no longer required as the + internal representation of the YankRing has changed. + BF: If g:yankring_ignore_duplicate is set (which is the default) + you could get some unpredicable results when moving + backwards and forwards ( and ) through the + previous values. + + 1.7: June 10, 2005: + BF: The expression register support added in version 1.6 used + getreg('='), which has the side effect of executing the + expression register. Depending on what was in the register + this could have unusual results. Changed to use histget(). + + 1.6: April 20, 2005: + NF: YRSearch is similar to YRGetElem. Given a regular expression + it will interactively display all the elements in the yankring + that match the regular expression. You can enter the number + of the element to paste it. If you have many elements within + the yankring, this can help you identify them more easily. + NF: Updated the default history size from 30 to 100, which is + partially the reason for the YRSearch command. + NF: By default it supports "gp" and "gP", in addition to "p" and "P". + NF: Added support for the expression register (:h quote=). Here + is an example of how it is used: + "="X"P + + 1.5: March 30, 2005: + 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.4: March 28, 2005: + NF: YRToggle has been updated. If you toggle the YankRing off + (disable) the maps it creates are removed. Calling YRToggle + again will recreate the maps. This truly disables the yankring, + where the previous version attempted to do this via code. + BF: Using the '.' operator was not correctly replaying operations + that did not move text in some way (g~t_) changed the case + of the text but a '.' did not replay it. + BF: When replacing previously pasted text the YankRing did not + respect what key was used to paste the text originally. + All replaced items were pasted using 'p', even if you had + originally pasted the text with 'P'. + + 1.3: March 16, 2005: + BF: The '.' operator did not handle the <<, >> shift operator. + Pressing '.' would result in the previous YankRing operation + instead of repeating the shift. + + 1.2: March 14, 2005: + NF: Added support for '.' operator to repeat the last change. + NF: Changed YRGetElem to show the contents of the yankring + and allow you to choose which element you want pasted. + It is only interactive if you do not provide a parameter. + NF: Added 'ygg,dgg' default maps by extending the yankring_n_keys + variable. + + 1.1: March 09, 2005: + NF: Added support for the black hole register |quote_|. + NF: Custom Maps allows the user to more finely tune the yankring + maps to perform whatever action they require. This function, + YRRunAfterMaps(), is run automatically after the YankRing + creates it's default mappings. See |yankring-custom-maps|. + NF: Added some more default maps by extending the yankring_n_keys + variable. It now contains: + yy,dd,yw,dw,ye,de,yE,dE,yiw,diw,yaw,daw,y$,d$,Y,D,yG,dG + NOTE: You can easily extend these default mappings by + creating this global variable in your |vimrc|, you do not + have to wait for the plugin to be updated. + NF: Added support for Dr. Chips GetLatestVimScripts plugin. + BF: The check for g:yankring_n_keys was incorrect, so it was not + possible to override the default maps. + + 1.0: March 08, 2005: + NF: Initial release. + +vim: ts=4 ft=help tw=78 diff --git a/sources_forked/yankring/plugin/yankring.vim b/sources_forked/yankring/plugin/yankring.vim new file mode 100755 index 00000000..57695138 --- /dev/null +++ b/sources_forked/yankring/plugin/yankring.vim @@ -0,0 +1,2544 @@ +" yankring.vim - Yank / Delete Ring for Vim +" --------------------------------------------------------------- +" Version: 12.0 +" Authors: David Fishburn +" Last Modified: 2011 Jun 14 +" 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('loaded_yankring') || &cp + finish +endif + +if v:version < 700 + echomsg 'yankring: You need at least Vim 7.0' + finish +endif + +let loaded_yankring = 120 + +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) +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 lines 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 , 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 = (&cpoptions=~'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 + +" 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_buffer = 1 +endif + +if !exists('g:yankring_replace_n_pkey') + let g:yankring_replace_n_pkey = '' +endif + +if !exists('g:yankring_replace_n_nkey') + let g:yankring_replace_n_nkey = '' +endif + +if !exists('g:yankring_clipboard_monitor') + let g:yankring_clipboard_monitor = (has('clipboard')?1:0) +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_name = '[YankRing]' +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 = '\%(\\\)\@ 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() + else + call s:YRMapsDelete() + 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, '\%(\\\)\@max_display)? + \ (strpart(elem,0,max_display). + \ '...'): + \ elem + \ ) + \ ) + + return "" +endfunction + + +" Enables or disables the yankring +function! s:YRShow(...) + " 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" + hide + + " 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 + + 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_buffer == 1 + let save_reg = 0 + let register = ((&clipboard=~'unnamed')?'+':'"') + + if &clipboard =~ 'unnamed' && getreg('+') != s:yr_prev_clipboard + 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 +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 + let c = getchar() + if c =~ '^\d\+$' + let c = nr2char(c) + echomsg msg.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 == "\" +" " return c +" " endif +" " if c == "\" +" " 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 s:yr_count == 0 + call s:YRWarningMsg('YR: yankring is empty') + return -1 + endif + + let default_buffer = ((&clipboard=~'unnamed')?'+':'"') + + 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')?'+':'"') + call setreg(default_buffer + \ , s:YRGetValElemNbr((elem), 'v') + \ , s:YRGetValElemNbr((elem), 't') + \ ) + exec "normal! ".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 s:yr_count == 0 + call s:YRWarningMsg('YR: yankring is empty') + return + endif + + " If the user provided a range, exit after that many + " have been displayed + let max = 1 + if a:0 == 1 + " If no yank command has been supplied, assume it is + " a full line yank + 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 = 0 + else + let increment = -1 + let elem = (max - 1) + 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. + " digits the element # is + 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 len(valid_choices) == 0 + 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 len(valid_choices) > 0 + 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 = 0 + 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 = '' + let s:yr_prev_reg_small = '' + let s:yr_prev_reg_insert = '' + let s:yr_prev_reg_expres = '' + let s:yr_prev_clipboard = '' + 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 == 0 + " 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. +" There is no need physically unlet each variable. +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)) + if &clipboard =~ 'unnamed' && 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')?'+':'"') + 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')?'+':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 register =~ '[+*]' + let s:yr_prev_clipboard = @+ + 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() + + return "" +endfunction + + +" Adds this value to the yankring. +function! YRRecord3() + let register = '"' + + " 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')?'+':register) + + 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 + + if s:yr_remove_omap_dot == 1 + call s:YRMapsCreate('add_only_zap_keys') + endif + + " Add item to list + " This will also account for duplicates. + call s:YRMRUAdd( 's:yr_history_list' + \ , getreg(register) + \ , getregtype(register) + \ ) + + if register =~ '[+*]' + let s:yr_prev_clipboard = @+ + 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() + + return "" +endfunction + + +" Record the operation for the dot operator +function! s:YRSetPrevOP(op_code, count, reg, mode) + let s:yr_prev_op_code = a:op_code + let s:yr_prev_op_mode = a:mode + let s:yr_prev_count = a:count + let s:yr_prev_changenr = changenr() + let s:yr_prev_reg = a:reg + let s:yr_prev_reg_unnamed = getreg('"') + let s:yr_prev_reg_small = getreg('-') + let s:yr_prev_reg_insert = getreg('.') + let s:yr_prev_vis_lstart = line("'<") + let s:yr_prev_vis_lend = line("'>") + let s:yr_prev_vis_cstart = col("'<") + let s:yr_prev_vis_cend = col("'>") + let s:yr_prev_reg_expres = histget('=', -1) + + if a:mode == 'n' + " In normal mode, the change has already + " occurred, therefore we can mark the + " actual position of the change. + let s:yr_prev_chg_lstart = line("'[") + let s:yr_prev_chg_lend = line("']") + let s:yr_prev_chg_cstart = col("'[") + let s:yr_prev_chg_cend = col("']") + else + " If in operator pending mode, the change + " has not yet occurred. Therefore we cannot + " use the '[ and ]' markers. But we can + " store the current line position. + let s:yr_prev_chg_lstart = line(".") + let s:yr_prev_chg_lend = line(".") + let s:yr_prev_chg_cstart = col(".") + let s:yr_prev_chg_cend = col(".") + endif + + " If storing the last change position (using '[, ']) + " is not good enough, then another option is to: + " Use :redir on the :changes command + " and grab the last item. Store this value + " and compare it is YRDoRepeat. +endfunction + + +" Adds this value to the yankring. +function! s:YRDoRepeat() + let dorepeat = 0 + + if s:yr_has_voperator == 1 + " Let Vim handle the repeat, just capture the updates + " as usual. + return 0 + endif + + if s:yr_prev_op_code =~ '^c' + " You cannot repeat change operations, let Vim's + " standard mechanism handle these, or the user will + " be prompted again, instead of repeating the + " previous change. + return 0 + endif + + if g:yankring_manage_numbered_reg == 1 + " When resetting the numbered register we are + " must ignore the comparision of the " register. + if s:yr_prev_reg_small == getreg('-') && + \ s:yr_prev_reg_insert == getreg('.') && + \ s:yr_prev_reg_expres == histget('=', -1) && + \ s:yr_prev_vis_lstart == line("'<") && + \ s:yr_prev_vis_lend == line("'>") && + \ s:yr_prev_vis_cstart == col("'<") && + \ s:yr_prev_vis_cend == col("'>") && + \ s:yr_prev_chg_lstart == line("'[") && + \ s:yr_prev_chg_lend == line("']") && + \ s:yr_prev_chg_cstart == col("'[") && + \ s:yr_prev_chg_cend == col("']") + let dorepeat = 1 + endif + else + " Check the previously recorded value of the registers + " if they are the same, we need to reissue the previous + " yankring command. + " If any are different, the user performed a command + " command that did not involve the yankring, therefore + " we should just issue the standard "normal! ." to repeat it. + if s:yr_prev_reg_unnamed == getreg('"') && + \ s:yr_prev_reg_small == getreg('-') && + \ s:yr_prev_reg_insert == getreg('.') && + \ s:yr_prev_reg_expres == histget('=', -1) && + \ s:yr_prev_vis_lstart == line("'<") && + \ s:yr_prev_vis_lend == line("'>") && + \ s:yr_prev_vis_cstart == col("'<") && + \ s:yr_prev_vis_cend == col("'>") + let dorepeat = 1 + endif + if dorepeat == 1 && s:yr_prev_op_mode == 'n' + " Hmm, not sure why I was doing this now + " so I will remove it + " let dorepeat = 0 + " if s:yr_prev_chg_lstart == line("'[") && + " \ s:yr_prev_chg_lend == line("']") && + " \ s:yr_prev_chg_cstart == col("'[") && + " \ s:yr_prev_chg_cend == col("']") + " let dorepeat = 1 + " endif + elseif dorepeat == 1 && s:yr_prev_op_mode == 'o' + " Hmm, not sure why I was doing this now + " so I will remove it + " let dorepeat = 0 + " if s:yr_prev_chg_lstart == line("'[") && + " \ s:yr_prev_chg_lend == line("']") && + " \ s:yr_prev_chg_cstart == col("'[") && + " \ s:yr_prev_chg_cend == col("']") + " let dorepeat = 1 + " endif + endif + endif + + " " If another change has happened that was not part of the + " " yankring we cannot replay it (from the yankring). Use + " " the standard ".". + " " If the previous op was a change, do not use the yankring + " " to repeat it. + " " changenr() is buffer specific, so anytime you move to + " " a different buffer you will definitely perform a + " " standard "." + " " Any previous op that was a change, must be replaced using "." + " " since we do not want the user prompted to enter text again. + " if s:yr_prev_changenr == changenr() && s:yr_prev_op_code !~ '^c' + " let dorepeat = 1 + " endif + + " If we are going to repeat check to see if the + " previous command was a yank operation. If so determine + " if yank operations are allowed to be repeated. + if dorepeat == 1 && s:yr_prev_op_code =~ '^y' + " This value be default is set based on cpoptions. + if g:yankring_dot_repeat_yank == 0 + let dorepeat = 0 + endif + endif + return dorepeat +endfunction + + +" Manages the Vim's numbered registers +function! s:YRSetNumberedReg() + + let i = 0 + + while i <= 10 + if i > s:yr_count + break + endif + + call setreg( (i) + \ , s:YRGetValElemNbr((i),'v') + \ , s:YRGetValElemNbr((i),'t') + \ ) + let i += 1 + endwhile + + " There are a few actions that Vim automatically takes + " when modifying the numbered registers. + " Modifying register 1 - changes the named register. + " It is impossible to set register 2 to a value, since Vim will change it. + + " This will at least preserve the default register + let @" = @0 +endfunction + + +" This internal function will add and subtract values from a starting +" point and return the correct element number. It takes into account +" the circular nature of the yankring. +function! s:YRGetNextElem(start, iter) + + let needed_elem = a:start + a:iter + + " The yankring is a ring, so if an element is + " requested beyond the number of elements, we + " must wrap around the ring. + if needed_elem > s:yr_count + let needed_elem = needed_elem % s:yr_count + endif + + if needed_elem == 0 + " Can happen at the end or beginning of the ring + if a:iter == -1 + " Wrap to the bottom of the ring + let needed_elem = s:yr_count + else + " Wrap to the top of the ring + let needed_elem = 1 + endif + elseif needed_elem < 1 + " As we step backwards through the ring we could ask for a negative + " value, this will wrap it around to the end + let needed_elem = s:yr_count + endif + + return needed_elem + +endfunction + + +" Lets Vim natively perform the operation and then stores what +" was yanked (or deleted) into the yankring. +" Supports this for example - 5"ayy +" +" This is a legacy function now since the release of Vim 7.2 +" and the use of omaps with YankRing 5.0 and above. +" If Vim 7.1 has patch205, then the new omaps and the v:operator +" variable is used instead. +function! s:YRYankCount(...) range + + let user_register = s:YRRegister() + let v_count = v:count + + " Default yank command to the entire line + let op_code = 'yy' + if a:0 > 0 + " If no yank command has been supplied, assume it is + " a full line yank + let op_code = ((a:1 == '') ? op_code : a:1) + endif + + if op_code == '.' + if s:YRDoRepeat() == 1 + if s:yr_prev_op_code != '' + let op_code = s:yr_prev_op_code + let v_count = s:yr_prev_count + let user_register = s:yr_prev_reg + endif + else + " Set this flag so that YRRecord will + " ignore repeats + let s:yr_prev_repeating = 1 + exec "normal! ." + return + endif + else + let s:yr_prev_repeating = 0 + endif + + " Supports this for example - 5"ayy + " A delete operation will still place the items in the + " default registers as well as the named register + exec "normal! ". + \ ((v_count > 0)?(v_count):''). + \ (user_register=='"'?'':'"'.user_register). + \ op_code + + if user_register == '_' + " Black hole register, ignore recording the operation + return + endif + + call s:YRSetPrevOP(op_code, v_count, user_register, 'n') + + call YRRecord(user_register) +endfunction + + +" Handles ranges. There are visual ranges and command line ranges. +" Visual ranges are easy, since we pass through and let Vim deal +" with those directly. +" Command line ranges means we must yank the entire line, and not +" just a portion of it. +function! s:YRYankRange(do_delete_selection, ...) range + + let user_register = s:YRRegister() + let default_buffer = ((&clipboard=~'unnamed')?'+':'"') + + " Default command mode to normal mode 'n' + let cmd_mode = 'n' + if a:0 > 0 + " Change to visual mode, if command executed via + " a visual map + let cmd_mode = ((a:1 == 'v') ? 'v' : 'n') + endif + + if cmd_mode == 'v' + " We are yanking either an entire line, or a range + exec "normal! gv". + \ (user_register==default_buffer?'':'"'.user_register). + \ 'y' + if a:do_delete_selection == 1 + exec "normal! gv". + \ (user_register==default_buffer?'':'"'.user_register). + \ 'd' + endif + else + " In normal mode, always yank the complete line, since this + " command is for a range. YRYankCount is used for parts + " of a single line + if a:do_delete_selection == 1 + exec a:firstline . ',' . a:lastline . 'delete '.user_register + else + exec a:firstline . ',' . a:lastline . 'yank ' . user_register + endif + endif + + if user_register == '_' + " Black hole register, ignore + return + endif + + call s:YRSetPrevOP('', '', user_register, 'n') + call YRRecord(user_register) +endfunction + + +" Paste from either the yankring or from a specified register +" Optionally a count can be provided, so paste the same value 10 times +function! s:YRPaste(replace_last_paste_selection, nextvalue, direction, ...) + " Disabling the yankring removes the default maps. + " But there are some maps the user can create on their own, and + " these would most likely call this function. So place an extra + " check and display a message. + if g:yankring_enabled == 0 + call s:YRWarningMsg( + \ 'YR: The yankring is currently disabled, use YRToggle.' + \ ) + return + endif + + + let user_register = s:YRRegister() + let default_buffer = ((&clipboard =~ 'unnamed')?'+':'"') + let v_count = v:count + + " Default command mode to normal mode 'n' + let cmd_mode = 'n' + if a:0 > 0 + " Change to visual mode, if command executed via + " a visual map + let cmd_mode = ((a:1 == 'v') ? 'v' : 'n') + endif + + " User has decided to bypass the yankring and specify a specific + " register + if user_register != default_buffer + if a:replace_last_paste_selection == 1 + call s:YRWarningMsg( 'YR: A register cannot be specified in replace mode' ) + return + else + " Check for the expression register, in this special case + " we must copy it's evaluation into the default buffer and paste + if user_register == '=' + " Save the default register since Vim will only + " allow the expression register to be pasted once + " and will revert back to the default buffer + let save_default_reg = @" + call setreg(default_buffer, eval(histget('=', -1)) ) + else + let user_register = '"'.user_register + endif + exec "normal! ". + \ ((cmd_mode=='n') ? "" : "gv"). + \ ((v_count > 0)?(v_count):''). + \ ((user_register=='=')?'':user_register). + \ a:direction + if user_register == '=' + let @" = save_default_reg + endif + " In this case, we have bypassed the yankring + " If the user hits next or previous we want the + " next item pasted to be the top of the yankring. + let s:yr_last_paste_idx = 0 + endif + let s:yr_paste_dir = a:direction + let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1) + return + endif + + " Try to second guess the user to make these mappings less intrusive. + " If the user hits paste, compare the contents of the paste register + " to the current entry in the yankring. If they are different, lets + " assume the user wants the contents of the paste register. + " So if they pressed [yt ] (yank to space) and hit paste, the yankring + " would not have the word in it, so assume they want the word pasted. + if a:replace_last_paste_selection != 1 + if s:yr_count > 0 || (default_buffer == '+' && len(@+) == 0) + " Only check the default buffer is the user wants us to. + " This was necessary prior to version 4.0 since we did not + " capture as many items as 4.0 and above does. (A. Budden) + if g:yankring_paste_check_default_buffer == 1 && + \ getreg(default_buffer) != s:yr_prev_reg_unnamed + " The user has performed a yank / delete operation + " outside of the yankring maps. First, add this + " value to the yankring. + call YRRecord(default_buffer) + " Now, use the most recently yanked text, rather than the + " value from the yankring. + exec "normal! ". + \ ((cmd_mode=='n') ? "" : "gv"). + \ ((v_count > 0)?(v_count):''). + \ a:direction + let s:yr_paste_dir = a:direction + let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1) + + " In this case, we have bypassed the yankring + " If the user hits next or previous we want the + " next item pasted to be the top of the yankring. + let s:yr_last_paste_idx = 0 + return + endif + else + exec "normal! ". + \ ((cmd_mode=='n') ? "" : "gv"). + \ ((v_count > 0)?(v_count):''). + \ a:direction + let s:yr_paste_dir = a:direction + let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1) + return + endif + endif + + if s:yr_count == 0 || (default_buffer == '+' && len(@+) == 0) + " Nothing to paste + return + endif + + if a:replace_last_paste_selection == 1 + " Replacing the previous put + let start = line("'[") + let end = line("']") + + if start != line('.') + call s:YRWarningMsg( 'YR: You must paste text first, before you can replace' ) + return + endif + + if start == 0 || end == 0 + return + endif + + " If a count was provided (ie 5), multiply the + " nextvalue accordingly and position the next paste index + let which_elem = a:nextvalue * ((v_count > 0)?(v_count):1) * -1 + let s:yr_last_paste_idx = s:YRGetNextElem( + \ s:yr_last_paste_idx, which_elem + \ ) + + let save_reg = getreg(default_buffer) + let save_reg_type = getregtype(default_buffer) + call setreg( default_buffer + \ , s:YRGetValElemNbr((s:yr_last_paste_idx-1),'v') + \ , s:YRGetValElemNbr((s:yr_last_paste_idx-1),'t') + \ ) + + " First undo the previous paste + exec "normal! u" + " Check if the visual selection should be reselected + " Next paste the correct item from the ring + " This is done as separate statements since it appeared that if + " there was nothing to undo, the paste never happened. + exec "normal! ". + \ ((s:yr_prev_vis_mode==0) ? "" : "gv"). + \ s:yr_paste_dir + call setreg(default_buffer, save_reg, save_reg_type) + call s:YRSetPrevOP('', '', '', 'n') + else + " User hit p or P + " Supports this for example - 5"ayy + " And restores the current register + let save_reg = getreg(default_buffer) + let save_reg_type = getregtype(default_buffer) + let s:yr_last_paste_idx = 1 + call setreg(default_buffer + \ , s:YRGetValElemNbr(0,'v') + \ , s:YRGetValElemNbr(0,'t') + \ ) + exec "normal! ". + \ ((cmd_mode=='n') ? "" : "gv"). + \ ( + \ ((v_count > 0)?(v_count):''). + \ a:direction + \ ) + call setreg(default_buffer, save_reg, save_reg_type) + call s:YRSetPrevOP( + \ a:direction + \ , v_count + \ , default_buffer + \ , 'n' + \ ) + let s:yr_paste_dir = a:direction + let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1) + endif + +endfunction + + +" Handle any omaps +function! YRMapsExpression(sid, motion, ...) + let cmds = a:motion + " echomsg "YRMapsE:".localtime() + " echomsg "YRMapsE 1:".cmds.":".v:operator.":".s:yr_maps_created_zap + + if (a:motion =~ '\.' && s:yr_remove_omap_dot == 1) || a:motion =~ '@' + " If we are repeating a series of commands we must + " unmap the _zap_ keys so that the user is not + " prompted when a command is replayed. + " These maps must be re-instated in YRRecord3() + " after the action of the replay is completed. + call s:YRMapsDelete('remove_only_zap_keys') + endif + + " Check if we are in operator-pending mode + if a:motion =~ '\('.substitute(g:yankring_zap_keys, ' ', '\\|', 'g').'\)' + if a:motion =~ '\(/\|?\)' + let zapto = (a:0==0 ? "" : input("YR:Enter string:")) + if zapto != "" + let zapto = zapto . "\" + else + let zapto = "\" + endif + else + let zapto = (a:0==0 ? "" : s:YRGetChar()) + endif + + if zapto == "\" + " Abort if the user hits Control C + call s:YRWarningMsg( "YR:Aborting command:".v:operator.a:motion ) + return "\" + endif + + let cmds = cmds . zapto + endif + + " There are a variety of commands which do not change the + " registers, so these operators should be ignored when + " determining which operations to record + " Simple example is '=' which simply formats the + " the selected text. + if ' \('.escape(join(split(g:yankring_ignore_operator), '\|'), '/.*~$^[]' ).'\) ' !~ escape(v:operator, '/.*~$^[]') + " Check if we are performing an action that will + " take us into insert mode + if '[cCsS]' !~ escape(v:operator, '/.*~$^[]') && a:motion !~ '@' + " if '[cCsS]' !~ escape(v:operator, '/.*~$^[]') + " If we have not entered insert mode, feed the call + " to record the current change when the function ends. + " This is necessary since omaps do not update registers + " until the function completes. + " The InsertLeave event will handle the motions + " that place us in insert mode and record the + " changes when insert mode ends. + let cmds .= a:sid. "yrrecord" + endif + endif + + " This will not work since we are already executing an expression + " if a:motion =~ '@' + " let cmds = 'normal! ' . cmds + " endif + + " echomsg "YRMapsE 5:".a:motion.":'".cmds."':".s:yr_maps_created_zap + return cmds + +endfunction + + +" Handle macros (@). +" This routine is not used, YRMapsExpression is used to +" handle the @ symbol. +" function! s:YRMapsMacro(bang, ...) range +" " If we are repeating a series of commands we must +" " unmap the _zap_ keys so that the user is not +" " prompted when a command is replayed. +" " These maps must be re-instated in YRRecord3() +" " after the action of the replay is completed. +" call s:YRMapsDelete('remove_only_zap_keys') +" +" " let zapto = (a:0==0 ? "" : s:YRGetChar()) +" let zapto = s:YRGetChar() +" +" if zapto == "\" +" " Abort if the user hits Control C +" call s:YRWarningMsg( "YR:Aborting command:".v:operator.a:motion ) +" return "" +" endif +" +" let v_count = v:count +" " If no count was specified it will have a value of 0 +" " so set it to at least 1 +" let v_count = ((v_count > 0)?(v_count):'') +" +" let range = '' +" if a:firstline != a:lastline +" let rannge = a:firstline.','.a:lastline +" endif +" +" let cmd = range."normal! ".v_count.'@'.zapto +" " DEBUG +" " echomsg cmd +" exec cmd +" +" call s:YRMapsCreate('add_only_zap_keys') +" endfunction + + +" Create the default maps +function! s:YRMapsCreate(...) + " 7.1.patch205 introduces the v:operator function which was + " essential to gain the omap support. + if s:yr_has_voperator == 1 + let s:yr_remove_omap_dot = 1 + for key in split(g:yankring_zap_keys) + try + if key != '@' + exec 'omap ' key 'YRMapsExpression("", "'. key. '", 1)' + endif + catch + endtry + endfor + endif + + silent! nmap @ YRMapsExpression("", "@", "1") + + let s:yr_maps_created_zap = 1 + + if a:0 > 0 + " We have only removed the _zap_ keys temporarily + " so abandon further changes. + return + endif + + " 7.1.patch205 introduces the v:operator function which was essential + " to gain the omap support. + if s:yr_has_voperator == 1 + let s:yr_remove_omap_dot = 1 + " Set option to add and remove _zap_ keys when + " repeating commands + let o_maps = split(g:yankring_o_keys) + " Loop through and prompt the user for all buffer connection parameters. + for key in o_maps + exec 'omap ' key 'YRMapsExpression("", "'. escape(key,'\"'). '")' + endfor + endif + + " Iterate through a space separated list of mappings and create + " calls to the YRYankCount function + let n_maps = split(g:yankring_n_keys) + " Loop through and prompt the user for all buffer connection parameters. + for key in n_maps + " exec 'nnoremap '.key." :YRYankCount '".key."'" + " exec 'nnoremap '.key." :YRYankCount '".key."'" + " Andy Wokula's suggestion + exec 'nmap' key key."yrrecord" + endfor + + if g:yankring_map_dot == 1 + if s:yr_has_voperator == 1 + nmap . YRMapsExpression("", ".") + else + nnoremap . :YRYankCount '.' + endif + endif + + if g:yankring_v_key != '' + exec 'xnoremap '.g:yankring_v_key." :YRYankRange 'v'" + endif + if g:yankring_del_v_key != '' + for v_map in split(g:yankring_del_v_key) + if strlen(v_map) > 0 + try + exec 'xnoremap '.v_map." :YRDeleteRange 'v'" + catch + endtry + endif + endfor + endif + if g:yankring_paste_n_bkey != '' + exec 'nnoremap '.g:yankring_paste_n_bkey." :YRPaste 'P'" + if g:yankring_paste_using_g == 1 + exec 'nnoremap g'.g:yankring_paste_n_bkey." :YRPaste 'gP'" + endif + endif + if g:yankring_paste_n_akey != '' + exec 'nnoremap '.g:yankring_paste_n_akey." :YRPaste 'p'" + if g:yankring_paste_using_g == 1 + exec 'nnoremap g'.g:yankring_paste_n_akey." :YRPaste 'gp'" + endif + endif + if g:yankring_paste_v_bkey != '' + exec 'xnoremap '.g:yankring_paste_v_bkey." :YRPaste 'P', 'v'" + endif + if g:yankring_paste_v_akey != '' + exec 'xnoremap '.g:yankring_paste_v_akey." :YRPaste 'p', 'v'" + endif + if g:yankring_replace_n_pkey != '' + exec 'nnoremap '.g:yankring_replace_n_pkey." :YRReplace '-1', 'P'" + endif + if g:yankring_replace_n_nkey != '' + exec 'nnoremap '.g:yankring_replace_n_nkey." :YRReplace '1', 'p'" + endif + + let g:yankring_enabled = 1 + let s:yr_maps_created = 1 + + if exists('*YRRunAfterMaps') + " This will allow you to override the default maps if necessary + call YRRunAfterMaps() + endif +endfunction + + +" Create the default maps +function! s:YRMapsDelete(...) + + let o_maps = split(g:yankring_zap_keys) + for key in o_maps + try + if key != '@' + silent! exec 'ounmap' key + endif + catch + endtry + endfor + + let s:yr_maps_created_zap = 0 + + if a:0 > 0 + " We have only removed the _zap_ keys temporarily + " so abandon further changes. + return + endif + + " Iterate through a space separated list of mappings and create + " calls to an appropriate YankRing function + let n_maps = split(g:yankring_n_keys) + " Loop through and prompt the user for all buffer connection parameters. + for key in n_maps + try + silent! exec 'nunmap' key + catch + endtry + endfor + + let o_maps = split(g:yankring_o_keys) + for key in o_maps + try + silent! exec 'ounmap' key + catch + endtry + endfor + + if g:yankring_map_dot == 1 + silent! exec "nunmap ." + endif + if g:yankring_v_key != '' + silent! exec 'vunmap '.g:yankring_v_key + endif + if g:yankring_del_v_key != '' + for v_map in split(g:yankring_del_v_key) + if strlen(v_map) > 0 + try + silent! exec 'vunmap '.v_map + catch + endtry + endif + endfor + endif + if g:yankring_paste_n_bkey != '' + silent! exec 'nunmap '.g:yankring_paste_n_bkey + if g:yankring_paste_using_g == 1 + silent! exec 'nunmap g'.g:yankring_paste_n_bkey + endif + endif + if g:yankring_paste_n_akey != '' + silent! exec 'nunmap '.g:yankring_paste_n_akey + if g:yankring_paste_using_g == 1 + silent! exec 'nunmap g'.g:yankring_paste_n_akey + endif + endif + if g:yankring_paste_v_bkey != '' + silent! exec 'vunmap '.g:yankring_paste_v_bkey + endif + if g:yankring_paste_v_akey != '' + silent! exec 'vunmap '.g:yankring_paste_v_akey + endif + if g:yankring_replace_n_pkey != '' + silent! exec 'nunmap '.g:yankring_replace_n_pkey + endif + if g:yankring_replace_n_nkey != '' + silent! exec 'nunmap '.g:yankring_replace_n_nkey + endif + + silent! exec 'nunmap @' + + let g:yankring_enabled = 0 + let s:yr_maps_created = 0 +endfunction + +function! s:YRGetValElemNbr( position, type ) + let needed_elem = a:position + + " The List which contains the items in the yankring + " history is also ordered, most recent at the top + let elem = s:YRMRUGet('s:yr_history_list', needed_elem) + + if a:type == 't' + let elem = matchstr(elem, '^.*,\zs.*$') + else + let elem = matchstr(elem, '^.*\ze,.*$') + if s:yr_history_version == 'v1' + " Match three @@@ in a row as long as it is not + " preceeded by a @@@ + " v1 + 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 + endif + + return elem +endfunction + +function! s:YRMRUReset( mru_list ) + let {a:mru_list} = [] + + return 1 +endfunction + +function! s:YRMRUSize( mru_list ) + return len({a:mru_list}) +endfunction + +function! s:YRMRUElemFormat( element, element_type ) + let elem = a:element + if g:yankring_max_element_length != 0 + let elem = strpart(a:element, 0, g:yankring_max_element_length) + if (g:yankring_warn_on_truncate > 0) + let bytes = len (a:element) - len(elem) + if (bytes > 0) + call s:YRWarningMsg("Yankring truncated its element by ". + \ bytes. + \ " bytes due to a g:yankring_max_element_length of ". + \ g:yankring_max_element_length + \ ) + endif + endif + endif + if s:yr_history_version == 'v1' + let elem = escape(elem, '@') + let elem = substitute(elem, "\n", s:yr_history_v1_nl, 'g') + else + let elem = substitute(elem, "\n", s:yr_history_v2_nl, 'g') + endif + " Append the regtype to the end so we have it available + let elem = elem.",".a:element_type + + return elem +endfunction + +function! s:YRMRUHas( mru_list, find_str ) + " This function will find a string and return the element # + let find_idx = index({a:mru_list}, a:find_str) + + return find_idx +endfunction + +function! s:YRMRUGet( mru_list, position ) + " This function will return the value of the item at a:position + " Find the value of one element + let value = get({a:mru_list}, a:position, -2) + + return value +endfunction + +function! s:YRMRUAdd( mru_list, element, element_type ) + " Only add new items if they do not already exist in the MRU. + " If the item is found, move it to the start of the MRU. + let found = -1 + " let elem = a:element + " if g:yankring_max_element_length != 0 + " let elem = strpart(a:element, 0, g:yankring_max_element_length) + " endif + " if s:yr_history_version == 'v1' + " let elem = escape(elem, '@') + " let elem = substitute(elem, "\n", s:yr_history_v1_nl, 'g') + " else + " let elem = substitute(elem, "\n", s:yr_history_v2_nl, 'g') + " endif + " " Append the regtype to the end so we have it available + " let elem = elem.",".a:element_type + + if strlen(a:element) < g:yankring_min_element_length + return 1 + endif + + let elem = s:YRMRUElemFormat(a:element, a:element_type) + + " Refresh the List + call s:YRHistoryRead() + + let found = s:YRMRUHas(a:mru_list, elem) + + " Special case for efficiency, if it is first item in the + " List, do nothing + if found != 0 + if found != -1 + " Remove found item since we will add it to the top + call remove({a:mru_list}, found) + endif + call insert({a:mru_list}, elem, 0) + call s:YRHistorySave() + endif + + return 1 +endfunction + +function! s:YRMRUDel( mru_list, elem_nbr ) + if a:elem_nbr >= 0 && a:elem_nbr < s:yr_count + call remove({a:mru_list}, a:elem_nbr) + call s:YRHistorySave() + endif + + return 1 +endfunction + +function! s:YRHistoryDelete() + let s:yr_history_list = [] + let yr_filename = s:yr_history_file_{s:yr_history_version} + + if filereadable(yr_filename) + let rc = delete(yr_filename) + if rc != 0 + call s:YRErrorMsg( + \ 'YRHistoryDelete: Unable to delete the yankring history file: '. + \ yr_filename + \ ) + endif + endif + + return 0 +endfunction + +function! s:YRHistoryRead() + let refresh_needed = 1 + let yr_history_list = [] + let yr_filename = s:yr_history_file_{s:yr_history_version} + + if filereadable(yr_filename) + let last_upd = getftime(yr_filename) + + if s:yr_history_last_upd != 0 && last_upd <= s:yr_history_last_upd + let refresh_needed = 0 + endif + + if refresh_needed == 1 + let s:yr_history_list = readfile(yr_filename) + let s:yr_history_last_upd = last_upd + let s:yr_count = len(s:yr_history_list) + return + else + return + endif + else + if s:yr_history_version == 'v2' + " Check to see if an upgrade is required + " else, let the empty yr_history_list be returned. + if filereadable(s:yr_history_file_v1) + " Perform upgrade to v2 of the history file + call s:YRHistoryUpgrade('v1') + return + endif + endif + endif + + let s:yr_history_list = yr_history_list + call s:YRHistorySave() + +endfunction + +function! s:YRHistorySave() + let yr_filename = s:yr_history_file_{s:yr_history_version} + + if len(s:yr_history_list) > g:yankring_max_history + " Remove items which exceed the max # specified + call remove(s:yr_history_list, g:yankring_max_history) + endif + + let rc = writefile(s:yr_history_list, yr_filename) + + if rc == 0 + let s:yr_history_last_upd = getftime(yr_filename) + let s:yr_count = len(s:yr_history_list) + else + call s:YRErrorMsg( + \ 'YRHistorySave: Unable to save yankring history file: '. + \ yr_filename + \ ) + endif +endfunction + +function! s:YRHistoryUpgrade(version) + if a:version == 'v1' + if filereadable(s:yr_history_file_v1) + let v1_list = readfile(s:yr_history_file_v1) + let v2_list = [] + for elem in v1_list + " Restore from version 1 + let elem = substitute(elem, s:yr_history_v1_nl_pat, "\n", 'g') + let elem = substitute(elem, '\\@', '@', 'g') + " Encode to version 2 + let elem = substitute(elem, "\n", s:yr_history_v2_nl, 'g') + call add(v2_list, elem) + endfor + let s:yr_history_list = v2_list + call s:YRHistorySave() + call s:YRWarningMsg( + \ "YR:History file:". + \ s:yr_history_file_v1. + \ ' has been upgraded.' + \ ) + endif + endif +endfunction + +" YRWindowUpdate +" Checks if the yankring window is already open. +" If it is, it will refresh it. +function! s:YRWindowUpdate() + let orig_win_bufnr = bufwinnr('%') + + " Switch to the yankring buffer + " only if it is already visible + if bufwinnr(s:yr_buffer_id) != -1 + call s:YRShow(0) + " Switch back to the original buffer + exec orig_win_bufnr . "wincmd w" + endif +endfunction + +" YRWindowStatus +" Displays a brief command list and option settings. +" It also will toggle the Help text. +function! s:YRWindowStatus(show_help) + let full_help = 0 + let orig_win_bufnr = bufwinnr('%') + let yr_win_bufnr = bufwinnr(s:yr_buffer_id) + + if yr_win_bufnr == -1 + " Do not update the window status since the + " yankring is not currently displayed. + return "" + endif + " Switch to the yankring buffer + if orig_win_bufnr != yr_win_bufnr + " If the buffer is visible, switch to it + exec yr_win_bufnr . "wincmd w" + endif + + let msg = 'AutoClose='.g:yankring_window_auto_close. + \ ';ClipboardMonitor='.g:yankring_clipboard_monitor. + \ ';Cmds:,[g]p,[g]P,d,r,s,a,c,u,R,q,;Help=?'. + \ (s:yr_search==""?"":';SearchRegEx='.s:yr_search) + + if s:yr_has_voperator == 0 + let msg = msg . "\nYankRing has limited functionality without Vim 7.2 or higher" + endif + + " Toggle help by checking the first line of the buffer + if a:show_help == 1 && getline(1) !~ 'selection' + let full_help = 1 + let msg = + \ '" : [p]aste selection'."\n". + \ '" double-click : [p]aste selection'."\n". + \ '" [g]p : [g][p]aste selection'."\n". + \ '" [g]P : [g][P]aste selection'."\n". + \ '" r : [p]aste selection in reverse order'."\n". + \ '" s : [s]earch the yankring for text'."\n". + \ '" u : [u]pdate display show YankRing'."\n". + \ '" R : [R]egisters display'."\n". + \ '" a : toggle [a]utoclose setting'."\n". + \ '" c : toggle [c]lipboard monitor setting'."\n". + \ '" q : [q]uit / close the yankring window'."\n". + \ '" ? : Remove help text'."\n". + \ '" : toggles the width of the window'."\n". + \ '" Visual mode is supported for above commands'."\n". + \ msg + endif + + let saveMod = &modifiable + + " Go to the top of the buffer and remove any previous status + " Use the blackhole register so it does not affect the yankring + setlocal modifiable + exec 0 + silent! exec 'norm! "_d/^---'."\n" + call histdel("search", -1) + + silent! 0put =msg + + " Erase it's contents to the blackhole + silent! exec '%g/^\s*$/delete _' + call histdel("search", -1) + + call cursor(1,1) + if full_help == 0 + call search('^\d', 'W') + endif + + let &modifiable = saveMod + + if orig_win_bufnr != s:yr_buffer_id + exec orig_win_bufnr . "wincmd w" + endif +endfunction + +" YRWindowOpen +" Display the Most Recently Used file list in a temporary window. +function! s:YRWindowOpen(results) + + " Setup the cpoptions properly for the maps to work + let old_cpoptions = &cpoptions + set cpoptions&vim + setlocal cpoptions-=a,A + + " Save the current buffer number. The yankring will switch back to + " this buffer when an action is taken. + let s:yr_buffer_last = bufnr('%') + let s:yr_buffer_last_winnr = winnr() + + if bufwinnr(s:yr_buffer_id) == -1 + if g:yankring_window_use_horiz == 1 + if g:yankring_window_use_bottom == 1 + let location = 'botright' + else + let location = 'topleft' + " Creating the new window will offset all other + " window numbers. Account for that so we switch + " back to the correct window. + let s:yr_buffer_last_winnr = s:yr_buffer_last_winnr + 1 + endif + let win_size = g:yankring_window_height + else + " Open a horizontally split window. Increase the window size, if + " needed, to accomodate the new window + if g:yankring_window_width && + \ &columns < (80 + g:yankring_window_width) + " one extra column is needed to include the vertical split + let &columns = &columns + g:yankring_window_width + 1 + let s:yr_winsize_chgd = 1 + else + let s:yr_winsize_chgd = 0 + endif + + if g:yankring_window_use_right == 1 + " Open the window at the rightmost place + let location = 'botright vertical' + else + " Open the window at the leftmost place + let location = 'topleft vertical' + " Creating the new window will offset all other + " window numbers. Account for that so we switch + " back to the correct window. + let s:yr_buffer_last_winnr = s:yr_buffer_last_winnr + 1 + endif + let win_size = g:yankring_window_width + endif + + " Special consideration was involved with these sequence + " of commands. + " First, split the current buffer. + " Second, edit a new file. + " Third record the buffer number. + " If a different sequence is followed when the yankring + " buffer is closed, Vim's alternate buffer is the yanking + " instead of the original buffer before the yankring + " was shown. + let cmd_mod = '' + if v:version >= 700 + let cmd_mod = 'keepalt ' + endif + exec 'silent! ' . cmd_mod . location . ' ' . win_size . 'split ' + + " Using :e and hide prevents the alternate buffer + " from being changed. + exec ":e " . escape(s:yr_buffer_name, ' ') + " Save buffer id + let s:yr_buffer_id = bufnr('%') + 0 + else + " If the buffer is visible, switch to it + exec bufwinnr(s:yr_buffer_id) . "wincmd w" + endif + + " Perform a double check to ensure we have entered the correct + " buffer since we don't want to do the %d_ in the wrong buffer! + if (bufnr('%') + 0) != s:yr_buffer_id + call s:YRWarningMsg( + \ "YR:Failed to change to the yankring buffer, please contact author id:". + \ s:yr_buffer_id. + \ ' last:'.s:yr_buffer_last + \ ) + return -1 + endif + + " Mark the buffer as scratch + setlocal buftype=nofile + setlocal bufhidden=hide + setlocal noswapfile + setlocal nowrap + setlocal nonumber + setlocal nobuflisted + setlocal noreadonly + setlocal modifiable + + " set up syntax highlighting + syn match yankringTitle #^--- YankRing ---$#hs=s+4,he=e-4 + syn match yankringHeaders #^Elem Content$# + syn match yankringItemNumber #^\d\+# + + syn match yankringKey #^AutoClose.*#hs=e-6 + syn match yankringKey #^AutoClose.*\[g\]p#hs=e-3 contains=yankringKey + syn match yankringKey #^AutoClose.*\[p\]P#hs=e-3 contains=yankringKey + syn match yankringKey #^AutoClose.*,d,#hs=e-1,he=e-1 contains=yankringKey + syn match yankringKey #^AutoClose.*,r,#hs=e-1,he=e-1 contains=yankringKey + syn match yankringKey #^AutoClose.*,s,#hs=e-1,he=e-1 contains=yankringKey + syn match yankringKey #^AutoClose.*,a,#hs=e-1,he=e-1 contains=yankringKey + syn match yankringKey #^AutoClose.*,c,#hs=e-1,he=e-1 contains=yankringKey + syn match yankringKey #^AutoClose.*,u,#hs=e-1,he=e-1 contains=yankringKey + syn match yankringKey #^AutoClose.*,q,#hs=e-1,he=e-1 contains=yankringKey + syn match yankringKey #^AutoClose.*#hs=e-6 contains=yankringKey + syn match yankringKey #^AutoClose.*?$#hs=e contains=yankringKey + + syn match yankringKey #^".*:#hs=s+1,he=e-1 + syn match yankringHelp #^".*$# contains=yankringKey + + hi link yankringTitle directory + hi link yankringHeaders keyword + hi link yankringItemNumber constant + hi link yankringKey identifier + hi link yankringHelp string + + " Clear all existing maps for this buffer + " We should do this for all maps, but I am not sure how to do + " this for this buffer/window only without affecting all the + " other buffers. + mapclear + " Create a mapping to act upon the yankring + nnoremap <2-LeftMouse> :call YRWindowActionN('p' ,'n') + nnoremap :call YRWindowActionN('p' ,'n') + xnoremap :call YRWindowAction ('p' ,'v') + nnoremap p :call YRWindowActionN('p' ,'n') + xnoremap p :call YRWindowAction ('p' ,'v') + nnoremap P :call YRWindowActionN('P' ,'n') + xnoremap P :call YRWindowAction ('P' ,'v') + nnoremap gp :call YRWindowActionN('gp','n') + xnoremap gp :call YRWindowAction ('gp','v') + nnoremap gP :call YRWindowActionN('gP','n') + xnoremap gP :call YRWindowAction ('gP','v') + nnoremap d :call YRWindowActionN('d' ,'n') + xnoremap d :call YRWindowAction ('d' ,'v') + xnoremap r :call YRWindowAction ('r' ,'v') + nnoremap s :call YRWindowAction ('s' ,'n') + nnoremap a :call YRWindowAction ('a' ,'n') + nnoremap c :call YRWindowAction ('c' ,'n') + nnoremap ? :call YRWindowAction ('?' ,'n') + nnoremap u :call YRWindowAction ('u' ,'n') + nnoremap q :call YRWindowAction ('q' ,'n') + nnoremap R :call YRWindowAction ('R' ,'n') + nnoremap \|:silent exec 'vertical resize '. + \ ( + \ g:yankring_window_use_horiz!=1 && winwidth('.') > g:yankring_window_width + \ ?(g:yankring_window_width) + \ :(winwidth('.') + g:yankring_window_increment) + \ ) + + " Erase it's contents to the blackhole + silent! exec '%delete _' + + " Display the status line / help + call s:YRWindowStatus(0) + exec 'normal! G' + + " Display the contents of the yankring + silent! put =a:results + + if getline('$') == '' + " Erase last blank line + silent! exec '$delete _' + endif + + " Move the cursor to the first line with an element + exec 0 + call search('^\d','W') + + setlocal nomodifiable + " + " Restore the previous cpoptions settings + let &cpoptions = old_cpoptions + +endfunction + +function! s:YRWindowActionN(op, cmd_mode) + let v_count = v:count + " If no count was specified it will have a value of 0 + " so set it to at least 1 + let v_count = ((v_count > 0)?(v_count):1) + + if v_count > 1 + if !exists("b:yankring_show_range_error") + let b:yankring_show_range_error = v_count + else + let b:yankring_show_range_error = b:yankring_show_range_error - 1 + endif + + if b:yankring_show_range_error == 1 + call s:YRWarningMsg("YR:Use visual mode if you need to specify a count") + unlet b:yankring_show_range_error + endif + return + endif + + call s:YRWindowAction(a:op, a:cmd_mode) + let v_count = v_count - 1 + + if g:yankring_window_auto_close == 1 && v_count == 0 && a:op != 'd' + " If autoclose is set close the window unless + " you are removing items from the YankRing + exec 'bdelete '.s:yr_buffer_id + return "" + endif + + return "" +endfunction + +function! s:YRWindowAction(op, cmd_mode) range + let default_buffer = ((&clipboard=~'unnamed')?'+':'"') + let opcode = a:op + let lines = [] + let v_count = v:count + let cmd_mode = a:cmd_mode + let firstline = a:firstline + let lastline = a:lastline + + if a:lastline < a:firstline + let firstline = a:lastline + let lastline = a:firstline + endif + + if cmd_mode == 'n' + let v_count = 1 + " If a count was provided (5p), we want to repeat the paste + " 5 times, but this also alters the a:firstline and a:lastline + " ranges, which while in normal mode we do not want + let lastline = firstline + endif + " If no count was specified it will have a value of 0 + " so set it to at least 1 + let v_count = ((v_count > 0)?(v_count):1) + + if '[dr]' =~ opcode + " Reverse the order of the lines to act on + let begin = lastline + while begin >= firstline + call add(lines, getline(begin)) + let begin = begin - 1 + endwhile + else + " Process the selected items in order + let begin = firstline + while begin <= lastline + call add(lines, getline(begin)) + let begin = begin + 1 + endwhile + endif + + if opcode ==# 'q' + " Close the yankring window + if s:yr_winsize_chgd == 1 + " Adjust the Vim window width back to the width + " it was before we showed the yankring window + let &columns= &columns - (g:yankring_window_width) + endif + + " Hide the YankRing window + hide + + if bufwinnr(s:yr_buffer_last) != -1 + " If the buffer is visible, switch to it + exec s:yr_buffer_last_winnr . "wincmd w" + endif + + return + elseif opcode ==# 's' + " Switch back to the original buffer + exec s:yr_buffer_last_winnr . "wincmd w" + + call s:YRSearch() + return + elseif opcode ==# 'u' + " Switch back to the original buffer + exec s:yr_buffer_last_winnr . "wincmd w" + + call s:YRShow(0) + return + elseif opcode ==# 'R' + " Switch back to the original buffer + exec s:yr_buffer_last_winnr . "wincmd w" + + call s:YRShow(0, 'R') + return + elseif opcode ==# 'a' + let l:curr_line = line(".") + " Toggle the auto close setting + let g:yankring_window_auto_close = + \ (g:yankring_window_auto_close == 1?0:1) + " Display the status line / help + call s:YRWindowStatus(0) + call cursor(l:curr_line,0) + return + elseif opcode ==# 'c' + let l:curr_line = line(".") + " Toggle the clipboard monitor setting + let g:yankring_clipboard_monitor = + \ (g:yankring_clipboard_monitor == 1?0:1) + " Display the status line / help + call s:YRWindowStatus(0) + call cursor(l:curr_line,0) + return + elseif opcode ==# '?' + " Display the status line / help + call s:YRWindowStatus(1) + return + endif + + " Switch back to the original buffer + exec s:yr_buffer_last_winnr . "wincmd w" + + " Intentional case insensitive comparision + if opcode =~? 'p' + let cmd = 'YRGetElem ' + let parms = ", '".opcode."' " + elseif opcode ==? 'r' + let opcode = 'p' + let cmd = 'YRGetElem ' + let parms = ", 'p' " + elseif opcode ==# 'd' + let cmd = 'YRPop ' + let parms = "" + endif + + " Only execute this code if we are operating on elements + " within the yankring + if '[auq?]' !~# opcode + while v_count > 0 + " let iter = 0 + " let index = 0 + for line in lines + let elem = matchstr(line, '^\d\+') + if elem > 0 + if elem > 0 && elem <= s:yr_count + " if iter > 0 && opcode =~# 'p' + if opcode =~# 'p' + " Move to the end of the last pasted item + " only if pasting after (not above) + " '] + endif + exec cmd . elem . parms + " let iter += 1 + endif + endif + endfor + let v_count = v_count - 1 + endwhile + + if opcode ==# 'd' + call s:YRShow(0) + return "" + endif + + if g:yankring_window_auto_close == 1 && cmd_mode == 'v' + exec 'bdelete '.s:yr_buffer_id + return "" + endif + + endif + + return "" + +endfunction + +function! s:YRWarningMsg(msg) + echohl WarningMsg + echomsg a:msg + echohl None +endfunction + +function! s:YRErrorMsg(msg) + echohl ErrorMsg + echomsg a:msg + echohl None +endfunction + +function! s:YRWinLeave() + " Track which window we are last in. We will use this information + " to determine where we need to paste any contents, or which + " buffer to return to. + + if s:yr_buffer_id < 0 + " The yankring window has never been activated + return + endif + + if winbufnr(winnr()) == s:yr_buffer_id + " Ignore leaving the yankring window + return + endif + + if bufwinnr(s:yr_buffer_id) != -1 + " YankRing window is visible, so save off the previous buffer ids + let s:yr_buffer_last_winnr = winnr() + let s:yr_buffer_last = winbufnr(s:yr_buffer_last_winnr) + " else + " let s:yr_buffer_last_winnr = -1 + " let s:yr_buffer_last = -1 + endif +endfunction + +function! s:YRFocusGained() + if g:yankring_clipboard_monitor == 1 + " If the clipboard has changed record it inside the yankring + " echomsg "YRFocusGained[".len(@+)."][".@+.']['.s:yr_prev_clipboard.']' + if len(@+) > 0 && @+ != s:yr_prev_clipboard + let elem = s:YRMRUElemFormat( + \ getreg('+') + \ , getregtype('+') + \ ) + let found = s:YRMRUHas('s:yr_history_list', elem) + + " Only add the item to the "top" of the ring if it is + " not in the ring already. + if found == -1 + call YRRecord("+") + " silent! call YRRecord("+") + endif + endif + + " If the yankring window is open, refresh it + call s:YRWindowUpdate() + endif +endfunction + +function! s:YRInsertLeave() + " The YankRing uses omaps to execute the prescribed motion + " and then appends to the motion a call to a YankRing + " function to record the contents of the changed register. + " + " We cannot append a function call to the end of a motion + " that results in Insert mode. For example, any command + " like 'cw' enters insert mode. Appending a function call + " after the w, simply writes out the call as if the user + " typed it. + " + " Using the InsertLeave event, allows us to capture the + " contents of any changed register after it completes. + + call YRRecord(s:YRRegister()) + + " When performing a change (not a yank or delete) + " it is not possible to call yrrecord at the end + " of the command (or it's contents will be inserted + " into the buffer instead of executed). + " So, when using ".", we have to remove the _zap_ + " keys and then re-add them back again after we + " record the updates. + if s:yr_remove_omap_dot == 1 + call s:YRMapsCreate('add_only_zap_keys') + endif + +endfunction + +" Deleting autocommands first is a good idea especially if we want to reload +" the script without restarting vim. +" Call YRFocusGained to check if the clipboard has been updated +augroup YankRing + autocmd! + autocmd VimEnter * :if has('clipboard') | call YRFocusGained() | endif + autocmd WinLeave * :call YRWinLeave() + autocmd FocusGained * :if has('clipboard') | call YRFocusGained() | endif + autocmd InsertLeave * :call YRInsertLeave() + autocmd User YRSetNumberedReg :call YRSetNumberedReg() + " autocmd User YRSetNumberedReg :let i = 0 | while i <= 10 | if i > s:yr_count | break | endif | call setreg( (i), s:YRGetValElemNbr((i),'v'), s:YRGetValElemNbr((i),'t') ) | let i += 1 | endwhile +augroup END + + +" copy register +inoremap