diff --git a/README.md b/README.md index 85a87914..ea93e17d 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,27 @@ There are two versions: I would, of course, recommend using the awesome version. + ## How to install the Awesome version? + The awesome version includes a lot of great plugins, configurations and color schemes that make Vim a lot better. To install it simply do following from your terminal: - git clone --depth=1 https://github.com/amix/vimrc.git ~/.vim_runtime - sh ~/.vim_runtime/install_awesome_vimrc.sh + git clone --depth=1 https://github.com/amix/vimrc.git ~/.vim_runtime + sh ~/.vim_runtime/install_awesome_vimrc.sh + + +## Fonts + +I recommend using [IBM Plex Mono font](https://ibm.github.io/type/) (it's an open-source and awesome font that can make your code beautiful). The Awesome vimrc is already setup to try to use it. + +Some other fonts that Awesome will try to use: + +* [Hack](http://sourcefoundry.org/hack/) +* [Source Code Pro](https://adobe-fonts.github.io/source-code-pro/) -I also recommend using [the Hack font](http://sourcefoundry.org/hack/) (it's a free and awesome font designed for source code). The Awesome vimrc is already setup to try to use it. ## How to install the Basic version? + The basic version is just one file and no plugins. Just copy [basic.vim](https://github.com/amix/vimrc/blob/master/vimrcs/basic.vim) and paste it into your vimrc. The basic version is useful to install on remote servers where you don't need many plugins, and you don't do many edits. @@ -37,6 +49,7 @@ Use [msysgit](http://msysgit.github.com/) to checkout the repository and run the If you have vim aliased as `vi` instead of `vim`, make sure to either alias it: `alias vi=vim`. Otherwise, `apt-get install vim` + ## How to update to latest version? Just do a git rebase! diff --git a/sources_non_forked/YankRing.vim/README b/sources_non_forked/YankRing.vim/README new file mode 100644 index 00000000..656c2472 --- /dev/null +++ b/sources_non_forked/YankRing.vim/README @@ -0,0 +1,127 @@ +This is a mirror of http://www.vim.org/scripts/script.php?script_id=1234 + +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 previous yanked, deleted or changed text. In Emacs this feature is called the "kill ring". + +The YankRing plugin allows the user to configure the number of yanked, deleted and changed text. A split window can be used to choose which element(s) from the yankring you wish to paste. Alternately after text has been pasted (using p), it can be replaced with a previous value from the yankring with a single key stroke. + +The captured text is stored in a file (location configurable) and is instantly available (also configurable) to any other instance of Vim also running on the same machine. This can especially be useful on *nix machines when you are sshed in running Vim in multiple terminals. + +Storing the capture text in a file allows the text to be shared easily between multiple instances of Vim running in X, Windows, SSH or Screen. + +A tutorial is included to take you through the various features of the plugin. After you have installed the plugin just run: + :h yankring.txt + :h yankring-tutorial + +The yankring can be interacted with in two ways: a GUI or via maps. + +The yankring supports all of Vim motions and text-objects. There are very few new keystrokes the user must learn. One keystroke to open the yankring to choose which item to paste is all that is required. It has been designed work seamlessly with Vim + +All the mappings and behaviours are configurable via global variables you can optionally specify in your vimrc. + +The plugin can be toggled on and off, and supports: + Ranges + Registers + Counts + All visual modes (characterwise, linewise and blockwise) + All motions + All text-objects + +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. + cw - Changes the word and stores the previous value in the yankring. +10"zyy - Places 10 lines into both the yankring and the "z register. + :1,4YRYankRange - Similar to 1,4y + :3,$YRDeleteRange - Similar to 3,$d + +If you wish to paste previous values from the yankring and do not want to use the GUI, there are only two additional maps you must learn (these are configurable via your vimrc if needed). The purpose of the yankring is to gain access to previously yanked (or deleted) elements. The YRReplace command will replace the previously pasted text with a different entry from the yankring. By default, I choose (P for previous) to replace the text last pasted while moving backwards through your previous text from the yankring and (N for next) to replace the previous paste while moving forward through the yankring. + +A separate buffer window to allow you to easily interact with the contents of the yankring. The window is similar to many other plugins: TagList, SelectBuf and so on. You can use the mouse or standard Vim keys (p, gp, P, ...). Visual mode is used to support counts, pasting multiple times and reversing the order of pasted elements. + +The GUI significantly simplifies your interaction with the yankring for basic functions. But often it useful to take advantage of the more powerful features of the yankring. + +Here is a small section from the tutorial (using maps) so you have some idea of how you interact with the plugin gaining access to previous yanks. Using the GUI for basic operations is self explanatory. + +:h yankring-tutorial + +---- Partial Tutorial ---- +To understand how to use the yankring, the following example should demonstrate the various features. + +Assume we have this buffer: + one + two + three + four + five + +Now yank (yy) each line separately starting at line 1. Display the +contents of the yankring. + :YRShow + --- YankRing --- + Elem Content + 5 five^@ + 4 four^@ + 3 three^@ + 2 two^@ + 1 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"). + +Now, go to the end of the file and press p. The resulting buffer appears as: + one + two + three + four + five + five +Now press to move backwards through the yankring, this 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 + +You can create a map to display a buffer displaying the yankring's contents: + nnoremap :YRShow + +YRShow creates a new split buffer (you can configure where it should be and it's size) + :YRShow + AutoClose=1;Cmds:,[g]p,[p]P,d,r,a,u,q,;Help=? + --- YankRing --- + Elem Content + 3 three^@ + 2 two^@ + 1 one^@ + 5 five^@ + 4 four^@ +You can simply hit "p", , double click on an item and it will be pasted into your document. The window will automatically close (by default) after you have made a choice. The element will be pasted into the correct buffer if you have multiple split windows. + +You can paste multiple items using visual mode. +You can also remove items from the yankring. + +---- Partial Tutorial ---- + +Concentrating on the last line of the buffer you could see how we were able to replace our pasted text with lines yanked previously. This is a feature Vim only has for deletes, and is limited to 9. This plugin enables the same features for both yanks, deletes and changes, the size of the history is configurable. + + + + diff --git a/sources_non_forked/YankRing.vim/doc/yankring.txt b/sources_non_forked/YankRing.vim/doc/yankring.txt new file mode 100644 index 00000000..dafcba3f --- /dev/null +++ b/sources_non_forked/YankRing.vim/doc/yankring.txt @@ -0,0 +1,1662 @@ +*yankring.txt* For Vim version 7.0. + +Author: David Fishburn July 27, 2015 +Version: 19.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 YRCheckClipboard..................: |:YRCheckClipboard| + 5.18 YRRunAfterMaps....................: |:YRRunAfterMaps| + 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 when 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_record_insert +< Default: 0 + If you want text you insert to be recorded in the YankRing you can + enable this feature two ways. From within the YankRing window you can + press [i]. The YankRing buffer status line visually indicates when + recording inserts is enabled or disabled. To enable this option + at Vim startup, put the following in your .vimrc: > + let g:yankring_record_insert = 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: 8 + If using a horizontal split, this option controls how high to make + the window. > + let g:yankring_window_height = 8 + yankring_window_width +< Default: 30 + 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. + This can be a comma separated list, which is useful if your + .vimrc is shared across different machines. If multipe directories + are specified, the first valid directory will be used. + 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. This is accomplished by the + use of the FocusGained Vim event for the GUI Vim. For console + Vims, the FocusGained event does not fire, so additional logic + is added to deal with it. To disable this feature + you can put the following in your |vimrc| > + let g:yankring_clipboard_monitor = 0 + yankring_manual_clipboard_check +< Default: 0 + If running in console mode, Vim's FocusGained event will not + fire as we flip back and forth between windows. This normally + instructs the YankRing to check for updates to the system + clipboard. When this option is set, the YankRing will check + the clipboard under many different circumstances: + Adding a new entry to the YankRing + Replacing a previous paste + Showing the YankRing window + If the YankRing is setup to check the clipboard and the + GUI is not running, this option will be enabled by default. + To disable this feature you can put the following in your |vimrc| > + let g:yankring_manual_clipboard_check = 0 + yankring_paste_check_default_register +< 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_register = 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 +convenience 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:[g]p,[g]P,1-9,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 the option, +yankring_window_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 the option, yankring_clipboard_monitor, since it may not +be useful at times. + +Inserts=0 indicates the YankRing will recorder newly inserted text +rather than just deletes and changes. Pressing [i] toggles the option +yankring_record_insert. + +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. + 1-9 Shortcut to paste the n'th number from the YankRing. + 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 items 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 previous + 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. + + On the Windows platform, I use ALT-< and ALT-> to move back and + forwards through the yankring instead of C-P and C-N. ALT-< is + actually ALT-, since I do not press the Shift key to get the <. + + To do this, I added the following to my .vimrc: + " Do not map the default and keys + " These two characters are the ALT-< and ALT->. + " 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, they are + " 172 and 174. + if has('win32') + let g:yankring_replace_n_pkey = '' + let g:yankring_replace_n_nkey = '' + endif + +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|. + +5.17 YRCheckClipboard *:YRCheckClipboard* + Normally the GUI Vims will automatically (via autocmds) + check for changes to the system clipboard and add any new + changes to the YankRing. Most console Vim's do not fire + the required autocmds. This command will perform the check + manually. + +5.18 YRRunAfterMaps *:YRRunAfterMaps* + See the following section |yankring-custom-maps|. + + +============================================================================== +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 preferable 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. + + As a short cut, when using the YankRing window, you can press the numbers + 1-9 to paste that item directly and close the YankRing window. This can + be faster than navigating to the correct line number and pressing 'p'. + + *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* + + 19.0: July 27, 2015 + NF: Updated documentation displayed in the YankRing window when + pressing ? to explain the Insert=0 status (Oskar Kvist). + + 18.0: September 24, 2013 + NF: Handle the @: command (Lingnan Dai). + NF: Added new global option to specify the YankRing buffer name, + g:yankring_buffer_name (Štefan Sakalík). + BF: Did not properly highlight new commands in the YankRing + window (Thilo Six). + + 17.0: April 28, 2013 + NF: The yankring_history_dir option can now take a comma separated + list. First valid directory found will be used (Alex Bel). + NF: YankRing can now monitor inserted text and place it in the ring. + This is disabled by default, but can be enabled either through + the YankRing window or via your .vimrc using the new option: + g:yankring_record_insert = 1 (Alexandre Viau). + BF: When g:yankring_persist = 0, the YankRing was still reading + and writing to the yankring file (Vladimir Marek). + BF: The YankRing menu entry, "Replace with Next", was performing + the "Replace with Previous" action (Thilo Six). + + 16.0: January 20, 2013 + BF: YankRing could report "YR: A register cannot be specified in + replace mode" when using clipboard = unnamed or unnamedplus. + This can often happen when fetching previous values from + the YankRing (i.e. or ). + + 15.0: January 2, 2013 + NF: Automatically turn off relativenumber for the YankRing + window (Emma Tramp). + NF: The YankRing window supports 1-9 to choose to paste those + items for quicker access to the top 9 items. + BF: When re-executing a macro using @ and the macro + used f, F, t, T, a "Press ENTER to continue" prompt + was displayed (Greg Sexton). + BF: Some documentation updates and script tweaks (Dominique Pellé). + BF: The 0 register was updated during delete operations + (Christian Brabandt). + BF: When running a macro (@a), pressing @ displays a YankRing prompt + (YR:Enter character:) to choose which macro name to run. This + prompt was displayed twice leading to a "Press ENTER or type + command to continue" Vim message. This change suppresses + the "Press ENTER" message (Greg Sexton). + BF: The YankRing prevented you from re-running the last macro + using @@. + BF: YRToggle (to disable / enable the YankRing) did not + unmap @. + BF: When prompted for a macro to run, if an invalid value was + provided, Vim could report "E354: Invalid register name". + BF: When using a Vim instance with < 80 columns and using a + horizontal YankRing window after opening and closing the + YankRing window the Vim window did not shrink back to + its original size (Eric Weir). + BF: Updated documented values of yankring_window_height and + yankring_window_width (Paul). + BF: It was not possible to paste from the * register if the + clipboard option contains unnamedplus before unnamed + (Marcin Szamotulski). + + 14.0: April 1, 2012 + NF: The YankRing window supports 1-9 to choose to paste those + items for quicker access to the top 9 items. + NF: The YankRing now maps the @ key to run macros. Not all actions + performed during the macro are recorded by the YankRing + as a number of items had to be unmapped to support the replay + of actions which can prompt the user for input (i.e. t and f) + (Asis Hallab). + BF: When flipping between applications the system clipboard + was not added to the YankRing in all cases. + BF: The YankRing could report E121: Undefined variable: + g:yankring_manual_clipboard_check (Thilo Six). + BF: The YankRing could report: E132: Function call depth is higher + than 'maxfuncdepth'. When executing a YRClear or YRPop or + when flipping between applications (Marcin Szamotulski). + BF: Strange behaviour when opening the YankRing with + :e [YankRing] instead of :YRShow (Marcin Szamotulski). + + 13.0: February 5, 2012 + NF: [p, ]p, [P, ]P are now supported within the YankRing + window (Alexandre Provencio). + NF: When using the console version of Vim the yankring was not + detecting the "+ register automatically as the FocusGained + event does not fire in console mode. When new elements are + added or the YankRing is shown the clipboard will be + checked for new values (Giuseppe Rota). + NF: Added a new option, g:yankring_manual_clipboard_check which + when enabled will manually check for clipboard changes at + certain times within the YankRing. This option is not used + if the GUI is running as the FocusGained will perform checks + at appropriate times (Erik Westrup). + BF: With clipboard=unnamed replacing the previous paste with a + different value from the YankRing did not work in all cases + (Chris Lott). + BF: Under certain conditions the YankRing would still check + the system clipboard even if g:yankring_clipboard_monitor == 0. + This can lead to delays when attempting to access the + clipboard when running in console mode. Starting Vim with + the -X switch removes the delay (Erik Westrup). + BF: Incorrect syntax setting cpoptions (Thilo Six). + + 12.0: October 15, 2011 + NF: A console Vim does not necessarily react to a FocusGained event + which means as you switch Focus back and forth between a + console Vim, the YankRing's feature to automatically gather + changes to the system clipboard is not triggered. Now special + processing takes place in various spots when you are not running + Vim with a GUI, to check for changes to the clipboard. Those + already running a GUI Vim, are unaffected by this change + (Giuseppe Rota). + NF: New command, YRCheckClipboard, which allows you to force + the YankRing to check the system clipboard and if the + value is not present already in the YankRing, it will add it. + This is typically done automatically, but certain console + Vim's do not receive the necessary events for automation. + BF: Some additional changes were required for the "unnamedplus" + support. + BF: YRGetMultiple reported an error, though typically you would + use YRShow to paste the items. + + 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 + interferes 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 clipboard 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 turned 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_non_forked/YankRing.vim/plugin/yankring.vim b/sources_non_forked/YankRing.vim/plugin/yankring.vim new file mode 100644 index 00000000..3cc67806 --- /dev/null +++ b/sources_non_forked/YankRing.vim/plugin/yankring.vim @@ -0,0 +1,2885 @@ +" yankring.vim - Yank / Delete Ring for Vim +" --------------------------------------------------------------- +" Version: 19.0 +" Author: David Fishburn +" Maintainer: David Fishburn +" Last Modified: 2015 Jul 27 +" Script: http://www.vim.org/scripts/script.php?script_id=1234 +" Based On: Mocked up version by Yegappan Lakshmanan +" http://groups.yahoo.com/group/vim/post?act=reply&messageNum=34406 +" License: GPL (Gnu Public License) +" GetLatestVimScripts: 1234 1 :AutoInstall: yankring.vim + +if exists('g:loaded_yankring') + finish +endif + +if v:version < 700 + echomsg 'yankring: You need at least Vim 7.0' + finish +endif + +let g:loaded_yankring = 190 + +" Turn on support for line continuations when creating the script +let s:cpo_save = &cpo +set cpo&vim + +let s:yr_has_voperator = 0 +if v:version > 701 || ( v:version == 701 && has("patch205") ) + let s:yr_has_voperator = 1 +endif + +if !exists('g:yankring_history_dir') + let g:yankring_history_dir = expand('$HOME') +else + " let g:yankring_history_dir = expand(g:yankring_history_dir) + for dir in split(g:yankring_history_dir, ",") + if isdirectory(expand(dir)) + let g:yankring_history_dir = expand(dir) + break + endif + endfor +endif + +if !exists('g:yankring_buffer_name') + let g:yankring_buffer_name = '[YankRing]' +endif + +if !exists('g:yankring_history_file') + let g:yankring_history_file = 'yankring_history' +endif + +" Allow the user to override the # of yanks/deletes recorded +if !exists('g:yankring_max_history') + let g:yankring_max_history = 100 +elseif g:yankring_max_history < 0 + let g:yankring_max_history = 100 +endif + +" Specify the minimum length of 1 entry +if !exists('g:yankring_min_element_length') + let g:yankring_min_element_length = 1 +endif + +" Specify the maximum length of 1 entry (1MB default) +if !exists('g:yankring_max_element_length') + let g:yankring_max_element_length = 1048576 +endif + +" Warn if truncation occurs +if !exists('g:yankring_warn_on_truncate') + let g:yankring_warn_on_truncate = 1 +endif + +" Allow the user to specify if the plugin is enabled or not +if !exists('g:yankring_enabled') + let g:yankring_enabled = 1 +endif + +" Specify max display length for each element for YRShow +if !exists('g:yankring_max_display') + let g:yankring_max_display = 0 +endif + +" Check if yankring should persist between Vim instances +if !exists('g:yankring_persist') + let g:yankring_persist = 1 +endif + +" Check if yankring share 1 file between all instances of Vim +if !exists('g:yankring_share_between_instances') + let g:yankring_share_between_instances = 1 +endif + +" Specify whether the results of the ring should be displayed +" in a separate buffer window instead of the use of echo +if !exists('g:yankring_window_use_separate') + let g:yankring_window_use_separate = 1 +endif + +" Specifies whether the window is closed after an action +" is performed +if !exists('g:yankring_window_auto_close') + let g:yankring_window_auto_close = 1 +endif + +" When displaying the buffer, how many lines should it be +if !exists('g:yankring_window_height') + let g:yankring_window_height = 8 +endif + +" When displaying the buffer, how many columns should it be +if !exists('g:yankring_window_width') + let g:yankring_window_width = 30 +endif + +" When displaying the buffer, where it should be placed +if !exists('g:yankring_window_use_horiz') + let g:yankring_window_use_horiz = 1 +endif + +" When displaying the buffer, where it should be placed +if !exists('g:yankring_window_use_bottom') + let g:yankring_window_use_bottom = 1 +endif + +" When displaying the buffer, where it should be placed +if !exists('g:yankring_window_use_right') + let g:yankring_window_use_right = 1 +endif + +" If the user presses , toggle the width of the window +if !exists('g:yankring_window_increment') + let g:yankring_window_increment = 50 +endif + +" Controls whether the . operator will repeat yank operations +" The default is based on cpoptions: |cpo-y| +" y A yank command can be redone with ".". +if !exists('g:yankring_dot_repeat_yank') + let g:yankring_dot_repeat_yank = (s:cpo_save=~'y'?1:0) +endif + +" Only adds unique items to the yankring. +" If the item already exists, that element is set as the +" top of the yankring. +if !exists('g:yankring_ignore_duplicate') + let g:yankring_ignore_duplicate = 1 +endif + +" Determine whether to record inserted data +if !exists('g:yankring_record_insert') + let g:yankring_record_insert = 0 +endif + +" Vim automatically manages the numbered registers: +" 0 - last yanked text +" 1-9 - last deleted items +" If this option is turned on, the yankring will manage the +" values in them. +if !exists('g:yankring_manage_numbered_reg') + let g:yankring_manage_numbered_reg = 0 +endif + +" Allow the user to specify what characters to use for the mappings. +if !exists('g:yankring_n_keys') + " 7.1.patch205 introduces the v:operator function which was essential + " to gain the omap support. + if s:yr_has_voperator == 1 + " Use omaps for the rest of the functionality + let g:yankring_n_keys = 'Y D x X' + else + let g:yankring_n_keys = 'x yy dd yw dw ye de yE dE yiw diw yaw daw y$ d$ Y D yG dG ygg dgg' + endif +endif + +" Allow the user to specify what operator pending motions to map +if !exists('g:yankring_o_keys') + " o-motions and text objects, without zap-to-char motions + let g:yankring_o_keys = 'b B w W e E d h j k l H M L y G ^ 0 $ , ;' + let g:yankring_o_keys .= ' g_ g^ gm g$ gk gj gg ge gE - + _ ' + let g:yankring_o_keys .= ' iw iW aw aW as is ap ip a] a[ i] i[ a) a( ab i) i( ib a> a< i> i< at it a} a{ aB i} i{ iB a" a'' a` i" i'' i`' +endif + +if !exists('g:yankring_zap_keys') + let g:yankring_zap_keys = 'f F t T / ?' +endif + +" Allow the user to specify what operator pending motions to map +if !exists('g:yankring_ignore_operator') + let g:yankring_ignore_operator = 'g~ gu gU ! = gq g? > < zf g@' +endif +let g:yankring_ignore_operator = ' '.g:yankring_ignore_operator.' ' + +" Whether we should map the . operator +if !exists('g:yankring_map_dot') + let g:yankring_map_dot = 1 +endif + +" Whether we sould map the "g" paste operators +if !exists('g:yankring_paste_using_g') + let g:yankring_paste_using_g = 1 +endif + +if !exists('g:yankring_v_key') + let g:yankring_v_key = 'y' +endif + +if !exists('g:yankring_del_v_key') + let g:yankring_del_v_key = 'd x' +endif + +if !exists('g:yankring_paste_n_bkey') + let g:yankring_paste_n_bkey = 'P' +endif + +if !exists('g:yankring_paste_n_akey') + let g:yankring_paste_n_akey = 'p' +endif + +if !exists('g:yankring_paste_v_bkey') + let g:yankring_paste_v_bkey = 'P' +endif + +if !exists('g:yankring_paste_v_akey') + let g:yankring_paste_v_akey = 'p' +endif + +if exists('g:yankring_paste_check_default_buffer') + let g:yankring_paste_check_default_register = g:yankring_paste_check_default_buffer +endif + +if !exists('g:yankring_paste_check_default_register') + let g:yankring_paste_check_default_register = 1 +endif + +if !exists('g:yankring_replace_n_pkey') + let g:yankring_replace_n_pkey = '' +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_manual_clipboard_check') + let g:yankring_manual_clipboard_check = 0 + if g:yankring_clipboard_monitor == 1 + if has("gui_running") + " FocusGained event will take care of + " monitoring the clipboard. + let g:yankring_manual_clipboard_check = 0 + else + " If the GUI is not running and the user wants to monitor the + " clipboard, we need to manually check for clipboard entries as + " the FocusGained event does not fire in console mode. + let g:yankring_manual_clipboard_check = 1 + endif + endif +endif + +if !exists('g:yankring_default_menu_mode') + let g:yankring_default_menu_mode = 3 +endif + +" Script variables for the yankring buffer +let s:yr_buffer_last_winnr = -1 +let s:yr_buffer_last = -1 +let s:yr_buffer_id = -1 +let s:yr_search = '' +let s:yr_remove_omap_dot = 0 +let s:yr_history_version = 'v2' +let s:yr_history_v1_nl = '@@@' +let s:yr_history_v1_nl_pat = '\%(\\\)\@ 0 + let new_state = ((a:1 == 1) ? 1 : 0) + endif + + " YRToggle accepts an integer value to specify the state + if new_state == g:yankring_enabled + return + elseif new_state == 1 + call s:YRMapsCreate() + call s:YRWarningMsg('YR: The YankRing is now enabled') + else + call s:YRMapsDelete() + call s:YRWarningMsg('YR: The YankRing is now disabled') + endif +endfunction + +" Enables or disables the yankring +function! s:YRDisplayElem(disp_nbr, script_var) + if g:yankring_max_display == 0 + if g:yankring_window_use_separate == 1 + let max_display = 500 + else + let max_display = g:yankring_window_width + + \ g:yankring_window_increment - + \ 12 + endif + else + let max_display = g:yankring_max_display + endif + + let elem = matchstr(a:script_var, '^.*\ze,.*$') + if s:yr_history_version == 'v1' + " v1 + " let elem = substitute(elem, '\%(\\\)\@max_display)? + \ (strpart(elem,0,max_display). + \ '...'): + \ elem + \ ) + \ ) + + return "" +endfunction + +" Enables or disables the yankring +function! s:YRShow(...) + " Prevent recursion + if exists('s:yankring_showing') && s:yankring_showing == 1 + " call s:YRWarningMsg('YR: YRShow aborting for recursion') + return + endif + + if g:yankring_enabled == 0 + call s:YRWarningMsg('YR: The YankRing is disabled, use YRToggle to re-enable') + return + endif + + " Prevent recursion + let s:yankring_showing = 1 + + " If the GUI is not running, we need to manually check for clipboard + " entries as the FocusGained event does not fire in console mode. + if g:yankring_manual_clipboard_check == 1 + call s:YRCheckClipboard() + endif + + " If no parameter was provided assume the user wants to + " toggle the display. + let toggle = 1 + if a:0 > 0 + let toggle = matchstr(a:1, '\d\+') + endif + + let show_registers = 0 + if a:0 > 1 && a:2 ==# 'R' + let show_registers = 1 + endif + + if toggle == 1 + if bufwinnr(s:yr_buffer_id) > -1 + " If the YankRing window is already open close it + exec bufwinnr(s:yr_buffer_id) . "wincmd w" + " Quit the YankRing + call s:YRWindowAction('q', 'n') + + " Switch back to the window which the YankRing + " window was opened from + if bufwinnr(s:yr_buffer_last) != -1 + " If the buffer is visible, switch to it + exec s:yr_buffer_last_winnr . "wincmd w" + endif + + " Prevent recursion + let s:yankring_showing = 0 + + return + endif + endif + + " Reset the search string, since this is automatically called + " if the yankring window is open. A previous search must be + " cleared since we do not want to show new items. The user can + " always run the search again. + let s:yr_search = "" + + " It is possible for registers to be changed outside of the + " maps of the YankRing. Perform this quick check when we + " show the contents (or when it is refreshed). + if g:yankring_paste_check_default_register == 1 + let save_reg = 0 + let register = ((&clipboard=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':'"')) + + if &clipboard =~ '\' && getreg('*') != s:yr_prev_clipboard_star + let save_reg = 1 + endif + if has('unnamedplus') && &clipboard =~ '\' && getreg('+') != s:yr_prev_clipboard_plus + let save_reg = 1 + endif + if register == '"' && getreg('"') != s:yr_prev_reg_unnamed + let save_reg = 1 + endif + + if save_reg == 1 + " The user has performed a yank / delete operation + " outside of the yankring maps. Add this + " value to the yankring. + call YRRecord(register) + endif + endif + + " List is shown in order of replacement + " assuming using previous yanks + let output = "--- YankRing ---\n" + let output = output . (show_registers == 1 ? 'Reg ' : 'Elem')." Content\n" + + if show_registers == 1 + for reg_name in map( range(char2nr('0'), char2nr('9')) + + \ (range(char2nr('a'), char2nr('z'))) + \, 'nr2char(v:val)' + \ ) + let output = output . s:YRDisplayElem(reg_name, getreg(reg_name).',') . "\n" + endfor + else + call s:YRHistoryRead() + let disp_item_nr = 1 + for elem in s:yr_history_list + let output = output . s:YRDisplayElem(disp_item_nr, elem) . "\n" + let disp_item_nr += 1 + endfor + endif + + if g:yankring_window_use_separate == 1 + call s:YRWindowOpen(output) + else + echo output + endif + + " Prevent recursion + let s:yankring_showing = 0 +endfunction + + +" Used in omaps if a following character is required +" like with motions (f,t) +function! s:YRGetChar() + let msg = "YR:Enter character:" + " echomsg msg + echo msg + let c = getchar() + if c =~ '^\d\+$' + let c = nr2char(c) + " echomsg msg.c + echon c + endif + return c +endfunction + + +" Used in omaps if a following string is required +" like with motions (/,?) +" function! s:YRGetSearch() +" " let msg = "YR:Enter string:" +" " echomsg msg +" let str = input("YR:Enter string:") +" " let str = '' +" " while 1==1 +" " let c = getchar() +" " if c =~ '^\d\+$' +" " let c = nr2char(c) +" " if c == "\" +" " 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 g:yankring_manual_clipboard_check == 1 + call s:YRCheckClipboard() + endif + + if s:yr_count == 0 + call s:YRWarningMsg('YR: yankring is empty') + return -1 + endif + + let default_buffer = ((&clipboard=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':'"')) + + let direction = 'p' + if a:0 > 1 + " If the user indicated to paste above or below + " let direction = ((a:2 ==# 'P') ? 'P' : 'p') + if a:2 =~ '\<\(p\|gp\|P\|gP\)\>' + let direction = a:2 + endif + endif + + " Check to see if a specific value has been provided + let elem = 0 + if a:0 > 0 + " Ensure we get only the numeric value (trim it) + let elem = matchstr(a:1, '\d\+') + let elem = elem - 1 + else + " If no parameter was supplied display the yankring + " and prompt the user to enter the value they want pasted. + call s:YRShow(0) + + if g:yankring_window_use_separate == 1 + " The window buffer is used instead of command line + return + endif + + let elem = input("Enter # to paste:") + + " Ensure we get only the numeric value (trim it) + let elem = matchstr(elem, '\d\+') + + if elem == '' + " They most likely pressed enter without entering a value + return + endif + + let elem = elem - 1 + endif + + if elem < 0 || elem >= s:yr_count + call s:YRWarningMsg("YR: Invalid choice:".elem) + return -1 + endif + + let default_buffer = ((&clipboard=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':'"')) + call setreg(default_buffer + \ , s:YRGetValElemNbr((elem), 'v') + \ , s:YRGetValElemNbr((elem), 't') + \ ) + exec 'normal! "'.default_buffer.direction + + " Set the previous action as a paste in case the user + " press . to repeat + call s:YRSetPrevOP('p', '', default_buffer, 'n') + +endfunction + + +" Starting the top of the ring it will paste x items from it +function! s:YRGetMultiple(reverse_order, ...) + if g:yankring_manual_clipboard_check == 1 + call s:YRCheckClipboard() + endif + + if s:yr_count == 0 + call s:YRWarningMsg('YR: yankring is empty') + return + endif + + let max = 1 + if a:0 == 1 + " If the user provided a range, exit after that many + " have been displayed + let max = matchstr(a:1, '\d\+') + endif + if max > s:yr_count + " Default to all items if they specified a very high value + let max = s:yr_count + endif + + " Base the increment on the sort order of the results + let increment = ((a:reverse_order==0)?(1):(-1)) + if a:reverse_order == 0 + let increment = 1 + let elem = 1 + else + let increment = -1 + let elem = max + endif + + if a:0 > 1 + let iter = 1 + while iter <= a:0 + let elem = (a:{iter} - 1) + call s:YRGetElem(elem) + let iter = iter + 1 + endwhile + else + while max > 0 + " Paste the first item, and move on to the next. + call s:YRGetElem(elem) + let elem = elem + increment + let max = max - 1 + endwhile + endif +endfunction + + +" Given a regular expression, check each element within +" the yankring, display only the matching items and prompt +" the user for which item to paste +function! s:YRSearch(...) + if s:yr_count == 0 + call s:YRWarningMsg('YR: yankring is empty') + return + endif + + let s:yr_search = "" + " If the user provided a range, exit after that many + " have been displayed + if a:0 == 0 || (a:0 == 1 && a:1 == "") + let s:yr_search = input('Enter [optional] regex:') + else + let s:yr_search = a:1 + endif + + if s:yr_search == "" + " Show the entire yankring + call s:YRShow(0) + return + endif + + " List is shown in order of replacement + " assuming using previous yanks + let output = "--- YankRing ---\n" + let output = output . "Elem Content\n" + let valid_choices = [] + + let search_result = filter(copy(s:yr_history_list), "v:val =~ '".s:yr_search."'") + + let disp_item_nr = 1 + + for elem in s:yr_history_list + if elem =~ s:yr_search + let output = output . s:YRDisplayElem(disp_item_nr, elem) . "\n" + call add(valid_choices, disp_item_nr.'') + endif + let disp_item_nr += 1 + endfor + + if empty(valid_choices) + let output = output . "Search for [".s:yr_search."] did not match any items " + endif + + if g:yankring_window_use_separate == 1 + call s:YRWindowOpen(output) + else + if !empty(valid_choices) + echo output + let elem = input("Enter # to paste:") + + " Ensure we get only the numeric value (trim it) + let elem = matchstr(elem, '\d\+') + + if elem == '' + " They most likely pressed enter without entering a value + return + endif + + if index(valid_choices, elem) != -1 + exec 'YRGetElem ' . elem + else + " User did not choose one of the elements that were found + " Remove leading , + call s:YRWarningMsg( "YR: Item[" . elem . "] not found, only valid choices are[" . + \ join(valid_choices, ',') . + \ "]" + \ ) + return -1 + endif + + else + call s:YRWarningMsg( "YR: The pattern [" . + \ s:yr_search . + \ "] does not match any items in the yankring" + \ ) + endif + endif + +endfunction + + +" Resets the common script variables for managing the ring. +function! s:YRReset() + call s:YRHistoryDelete() + " Update the history file + call s:YRHistorySave() +endfunction + + +" Clears the yankring by simply setting the # of items in it to 0. +" There is no need physically unlet each variable. +function! s:YRInit(...) + let s:yr_next_idx = 0 + let s:yr_last_paste_idx = 1 + let s:yr_count = 0 + let s:yr_history_last_upd = 0 + let s:yr_history_list = [] + let s:yr_paste_dir = 'p' + + " For the . op support + let s:yr_prev_op_code = '' + let s:yr_prev_op_mode = 'n' + let s:yr_prev_count = '' + let s:yr_prev_reg = '' + let s:yr_prev_reg_unnamed = getreg('"') + let s:yr_prev_reg_small = '' + let s:yr_prev_reg_insert = '' + let s:yr_prev_reg_expres = '' + let s:yr_prev_clipboard_star = '' + let s:yr_prev_clipboard_plus = '' + let s:yr_prev_vis_lstart = 0 + let s:yr_prev_vis_lend = 0 + let s:yr_prev_vis_cstart = 0 + let s:yr_prev_vis_cend = 0 + let s:yr_prev_changenr = 0 + let s:yr_prev_repeating = 0 + + " This is used to determine if the visual selection should be + " reset prior to issuing the YRReplace + let s:yr_prev_vis_mode = 0 + + if a:0 == 0 && g:yankring_persist != 1 + " The user wants the yankring reset each time Vim is started + call s:YRClear() + endif + + call s:YRHistoryRead() +endfunction + + +" Clears the yankring by simply setting the # of items in it to 0. +function! s:YRClear() + call s:YRReset() + call s:YRInit('DoNotClear') + + " If the yankring window is open, refresh it + call s:YRWindowUpdate() +endfunction + + +" Determine which register the user wants to use +" For example the 'a' register: "ayy +function! s:YRRegister() + " v:register can be blank in some (unknown) cases + " so test for this condition and return the + " default register + let user_register = ((v:register=='')?('"'):(v:register)) + let clipboard_default = matchstr( &clipboard, '\' ) + + " clipboard can have a comma separated list of values. + " Depending on which order the unnamed is referenced + " determines which register to use. + " set clipboard=unnamedplus,unnamed + " set clipboard=unnamed,unnamedplus + if clipboard_default == '\' && user_register == '"' + let user_register = '*' + endif + if has('unnamedplus') && clipboard_default == '\' && 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=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':'"')) + call setreg(default_buffer, getreg(user_register), + \ getregtype(user_register)) + + call s:YRSetPrevOP('', '', '', 'n') + call YRRecord(user_register) +endfunction + + +" Allows you to pop off any element from the yankring. +" If no parameters are provided the first element is removed. +" If a vcount is provided, that many elements are removed +" from the top. +function! s:YRPop(...) + if s:yr_count == 0 + call s:YRWarningMsg('YR: yankring is empty') + return + endif + + let v_count = 1 + if a:0 > 1 + let v_count = a:2 + endif + + " If the user provided a parameter, remove that element + " from the yankring. + " If no parameter was provided assume the first element. + let elem_index = 0 + if a:0 > 0 + " Get the element # from the parameter + let elem_index = matchstr(a:1, '\d\+') + let elem_index = elem_index - 1 + endif + + " If the user entered a count, then remove that many + " elements from the ring. + while v_count > 0 + call s:YRMRUDel('s:yr_history_list', elem_index) + let v_count = v_count - 1 + endwhile + + " If the yankring window is open, refresh it + call s:YRWindowUpdate() +endfunction + + +" Adds this value to the yankring. +function! YRRecord(...) + + let register = '"' + if a:0 > 0 + " If no yank command has been supplied, assume it is + " a full line yank + let register = ((a:1 == '') ? register : a:1) + endif + + " v:register can be blank in some (unknown) cases + " if v:register == '' || v:register == '_' + if v:register == '_' + " Black hole register, ignore recording the operation + return "" + endif + + let register = ((&clipboard=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':register)) + + " let s:yr_prev_changenr = changenr() + if register == '"' + " If the change has occurred via an omap, we must delay + " the capture of the default register until this event + " since register updates are not reflected until the + " omap function completes + let s:yr_prev_reg_unnamed = getreg('"') + let s:yr_prev_reg_small = getreg('-') + endif + + " Add item to list + " This will also account for duplicates. + call s:YRMRUAdd( 's:yr_history_list' + \ , getreg(register) + \ , getregtype(register) + \ ) + + if g:yankring_clipboard_monitor == 1 + let s:yr_prev_clipboard_plus = getreg('+') + let s:yr_prev_clipboard_star = getreg('*') + endif + + " Manage the numbered registers + if g:yankring_manage_numbered_reg == 1 + " Allow the user to define an autocmd to dynamically + " setup their connection information. + silent! doautocmd User YRSetNumberedReg + endif + + " If the yankring window is open, refresh it + call s:YRWindowUpdate() + + " Reset the past paste entry to the top of the ring. + " When the user hits replace last entry it should + " start from the top (not from the last previous + " replace) after capturing a new value in the YankRing. + let s:yr_last_paste_idx = 1 + + return "" +endfunction + + +" Adds this value to the yankring. +function! YRRecord3(...) + let register = '"' + + if a:0 > 0 && a:1 != '' + let register = a:1 + else + " v:register can be blank in some (unknown) cases + " if v:register == '' || v:register == '_' + if v:register == '_' + " Black hole register, ignore recording the operation + return "" + endif + + let register = s:YRRegister() + + if &clipboard =~ '\' && register == '*' + " unnamed A variant of "unnamed" flag which uses the clipboard + " register '*' (|quote|) for all operations except yank. + " Yank shall copy the text into register '*' when "unnamed" + " is included. + " + let register = '*' + + " The + and * registers are not modified by yank operations. + " We do not know what operation triggered this event so do a + " simple check if the register values have changed. + " If not, check it against the " register. Use which ever + " one has changed. + if s:yr_prev_clipboard_star == '' || getreg(register) == s:yr_prev_clipboard_star + if getreg('"') != getreg(register) + let register = '"' + endif + endif + endif + + if has('unnamedplus') && &clipboard =~ '\' && register == '+' + " unnamedplus A variant of "unnamed" flag which uses the clipboard + " register '+' (|quoteplus|) instead of register '*' for all + " operations except yank. Yank shall copy the text into + " register '+' and also into '*' when "unnamed" is included. + " + let register = '+' + + " The + and * registers are not modified by yank operations. + " We do not know what operation triggered this event so do a + " simple check if the register values have changed. + " If not, check it against the " register. Use which ever + " one has changed. + if s:yr_prev_clipboard_plus == '' || getreg(register) == s:yr_prev_clipboard_plus + if getreg('"') != getreg(register) + let register = '"' + endif + endif + endif + endif + + if register == '"' + " If the change has occurred via an omap, we must delay + " the capture of the default register until this event + " since register updates are not reflected until the + " omap function completes + let s:yr_prev_reg_unnamed = getreg('"') + let s:yr_prev_reg_small = getreg('-') + endif + + 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 g:yankring_clipboard_monitor == 1 + let s:yr_prev_clipboard_plus = getreg('+') + let s:yr_prev_clipboard_star = getreg('*') + endif + + " Manage the numbered registers + if g:yankring_manage_numbered_reg == 1 + " Allow the user to define an autocmd to dynamically + " setup their connection information. + silent! doautocmd User YRSetNumberedReg + endif + + " If the yankring window is open, refresh it + call s:YRWindowUpdate() + + " Reset the past paste entry to the top of the ring. + " When the user hits replace last entry it should + " start from the top (not from the last previous + " replace) after capturing a new value in the YankRing. + let s:yr_last_paste_idx = 1 + + return "" +endfunction + + +" 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 comparison 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=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':'"')) + + " 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 a:do_delete_selection == 1 + " Save register 0 + " Register 0 should only be changed by yank operations + " if we are deleting text, this could inadvertently + " update this register. + let zero_register = [0, getreg(0), getregtype('0')] + endif + + if cmd_mode == 'v' + " We are yanking either an entire line, or a range + " We want to yank the text first (even in a delete) since + " the rules around which registers get updated are a bit + " complicated. For deletes, it depends on how large + " the delete is for which registers get updated. + 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 a:do_delete_selection == 1 + " Restore register zero + call call('setreg', zero_register) + 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, ...) + if g:yankring_manual_clipboard_check == 1 + call s:YRCheckClipboard() + endif + + " 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_register = ((&clipboard=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':'"')) + let default_register = '"' + let clipboard_default = matchstr( &clipboard, '\' ) + if has('unnamedplus') && clipboard_default == '\' && (v:register == '' || v:register == '"') + let default_register = '+' + endif + if clipboard_default =~ '\' && (v:register == '' || v:register == '"') + let default_register = '*' + endif + 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 + + 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 which_elem = matchstr(a:nextvalue, '-\?\d\+') * ((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_register) + let save_reg_type = getregtype(default_register) + call setreg( default_register + \ , 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"). + \ '"'.default_register. + \ s:yr_paste_dir + call setreg(default_register, save_reg, save_reg_type) + call s:YRSetPrevOP('', '', '', 'n') + + return + endif + + " User has decided to bypass the yankring and specify a specific + " register + if user_register != default_register + " if a:replace_last_paste_selection == 1 + " call s:YRWarningMsg( 'YR: A register cannot be specified in replace mode' ) + " return + " endif + + " 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_register, 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 = 1 + + 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. + " The user could have: + " let @" = 'test string' + " would not be in the yankring as no mapping triggered this action. + if a:replace_last_paste_selection != 1 + " 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_register == 1 + if ( default_register == '"' && getreg(default_register) != s:yr_prev_reg_unnamed ) + " There are only a couple of scenarios where this would happen + " 1. set clipboard = unnamed[plus] + " The user performs an action which changes the + " unnamed register (i.e. x - delete character) + " 2. Any type of direct manipulation of the registers + " let @" = 'something' + " 3. Something changed the system clipboard outside of Vim + if getreg('"') != s:yr_prev_reg_unnamed + let default_register = '"' + endif + + " The user has performed a yank / delete operation + " outside of the yankring maps. First, add this + " value to the yankring. + call YRRecord(default_register) + elseif ( default_register == '+' && + \ !empty(getreg(default_register)) && + \ getreg(default_register) != s:yr_prev_clipboard_plus + \ ) + + " The user has performed a yank / delete operation + " outside of the yankring maps. First, add this + " value to the yankring. + call YRRecord(default_register) + elseif ( default_register == '*' && + \ !empty(getreg(default_register)) && + \ getreg(default_register) != s:yr_prev_clipboard_star + \ ) + + " The user has performed a yank / delete operation + " outside of the yankring maps. First, add this + " value to the yankring. + call YRRecord(default_register) + endif + endif + + exec "normal! ". + \ ((cmd_mode=='n') ? "" : "gv"). + \ ((v_count > 0)?(v_count):''). + \ '"'.default_register. + \ a:direction + let s:yr_paste_dir = a:direction + let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1) + return + endif + + " if s:yr_count > 0 || ( + " \ default_register != '"' && + " \ empty(getreg(default_register)) + " \ ) + " " Nothing to paste + " return + " endif + + " User hit p or P + " Supports this for example - 5"ayy + " And restores the current register + let save_reg = getreg(default_register) + let save_reg_type = getregtype(default_register) + let s:yr_last_paste_idx = 1 + call setreg(default_register + \ , s:YRGetValElemNbr(0,'v') + \ , s:YRGetValElemNbr(0,'t') + \ ) + exec "normal! ". + \ ((cmd_mode=='n') ? "" : "gv"). + \ ((v_count > 0)?(v_count):''). + \ '"'.default_register. + \ a:direction + call setreg(default_register, save_reg, save_reg_type) + call s:YRSetPrevOP( + \ a:direction + \ , v_count + \ , default_register + \ , 'n' + \ ) + let s:yr_paste_dir = a:direction + let s:yr_prev_vis_mode = ((cmd_mode=='n') ? 0 : 1) + +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 ".a:motion + 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 + + " YRRecord3() will use this value to determine what operation + " the user just initiated. + let s:yr_last_motion = cmds + + " echomsg "YRMapsE 5:".a:motion.":'".cmds."':".s:yr_maps_created_zap + return cmds + +endfunction + + +" Handle macros (@). +function! s:YRMapsMacro(bang, ...) + " 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') + + " Greg Sexton indicated the use of nr2char() removes + " a "Press ENTER ..." prompt when executing a macro. + " let zapto = nr2char(getchar()) + " 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 macro" ) + return "" + endif + + if zapto !~ '\(\w\|@\|:\)' + " Abort if the user does not specify a register + call s:YRWarningMsg( "YR:No register specified, aborting macro" ) + 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 + let cmd = "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") + silent! nmap @ :YRMapsMacro + + 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 !empty(v_map) + 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 + " Why not remove the @ map? + 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 !empty(v_map) + 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 + " preceded 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) + let s:yr_count = len({a:mru_list}) + 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) + let s:yr_count = len({a:mru_list}) + call s:YRHistorySave() + endif + + return 1 +endfunction + +function! s:YRHistoryDelete() + let s:yr_history_list = [] + let s:yr_count = 0 + + if g:yankring_persist != 1 + return + endif + 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() + if g:yankring_persist != 1 + return + endif + 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() + + 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, (len(s:yr_history_list)-1)) + let s:yr_count = len(s:yr_history_list) + endif + + if g:yankring_persist != 1 + return + endif + + let yr_filename = s:yr_history_file_{s:yr_history_version} + let rc = writefile(s:yr_history_list, yr_filename) + + if rc == 0 + let s:yr_history_last_upd = getftime(yr_filename) + 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. + \ ';Inserts='.g:yankring_record_insert. + \ ';Cmds:,[g]p,[g]P,1-9,d,r,s,a,c,i,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". + \ '" 1-9 : Paste # entry from the YankRing (shortcut for speed)'."\n". + \ '" d : [d]elete item from the YankRing'."\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". + \ '" i : toggle [i]nsert recording'."\n". + \ '" q : [q]uit / close the yankring window'."\n". + \ '" ? : Remove help text'."\n". + \ '" : toggles the width of the window'."\n". + \ '" AutoClose : See yankring.txt, yankring_window_auto_close'."\n". + \ '" ClipboardMonitor: See yankring.txt, yankring_clipboard_monitor'."\n". + \ '" Inserts : See yankring.txt, yankring_record_insert'."\n". + \ '" YankRing Version: '.g:loaded_yankring."\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 + " and to not set the alternate buffer + let old_cpoptions = &cpoptions + set cpoptions&vim + set cpoptions-=a + set cpoptions-=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 accommodate the new window + if g:yankring_window_width && + \ &columns < (80 + g:yankring_window_width) + " Store the previous window size of the YankRing + let s:yr_winsize_chgd = &columns + " One extra column is needed to include the vertical split + let &columns = &columns + g:yankring_window_width + 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(g:yankring_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 nospell + setlocal modifiable + if v:version >= 703 + setlocal norelativenumber + endif + + " 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.*\[g\]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.*,i,#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.*,R,#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') + nnoremap [p :call YRWindowActionN('[p' , 'n') + nnoremap ]p :call YRWindowActionN(']p' , 'n') + xnoremap p :call YRWindowAction ('p' , 'v') + xnoremap [p :call YRWindowAction ('[p' , 'v') + xnoremap ]p :call YRWindowAction (']p' , 'v') + nnoremap P :call YRWindowActionN('P' , 'n') + nnoremap [P :call YRWindowActionN('[P' , 'n') + nnoremap ]P :call YRWindowActionN(']P' , 'n') + xnoremap P :call YRWindowAction ('P' , 'v') + xnoremap [P :call YRWindowAction ('[P' , 'v') + 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 i :call YRWindowAction ('i' , 'n') + nnoremap ? :call YRWindowAction ('?' , 'n') + nnoremap u :call YRWindowAction ('u' , 'n') + nnoremap q :call YRWindowAction ('q' , 'n') + nnoremap R :call YRWindowAction ('R' , 'n') + nnoremap 1 :call YRWindowAction ('q' ,'n'):call YRGetElem(1) + nnoremap 2 :call YRWindowAction ('q' ,'n'):call YRGetElem(2) + nnoremap 3 :call YRWindowAction ('q' ,'n'):call YRGetElem(3) + nnoremap 4 :call YRWindowAction ('q' ,'n'):call YRGetElem(4) + nnoremap 5 :call YRWindowAction ('q' ,'n'):call YRGetElem(5) + nnoremap 6 :call YRWindowAction ('q' ,'n'):call YRGetElem(6) + nnoremap 7 :call YRWindowAction ('q' ,'n'):call YRGetElem(7) + nnoremap 8 :call YRWindowAction ('q' ,'n'):call YRGetElem(8) + nnoremap 9 :call YRWindowAction ('q' ,'n'):call YRGetElem(9) + 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=~'\')?'*':((&clipboard=~'\' && has('unnamedplus'))?'+':'"')) + 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 '\<[drP]\>' =~# 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 > 0 + " Adjust the Vim window width back to the width + " it was before we showed the yankring window + let &columns = s:yr_winsize_chgd + " Reset the indicator the window size was changed + let s:yr_winsize_chgd = 0 + 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 ==# 'i' + let l:curr_line = line(".") + " Toggle the auto close setting + let g:yankring_record_insert = + \ (g:yankring_record_insert == 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 comparison + 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 the user to their last known position, assuming + " it is still available after the delete + if firstline < line("$") + call cursor(firstline,0) + else + call cursor(line("$"),0) + endif + 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() + " FocusGained is not available in general by console vim. + " There are some terminal windows which support it though. + " This thread on vim_use covers some of it: + " http://groups.google.com/group/vim_use/browse_thread/thread/8dd3fb054ee922c6/59bee226473a9eea?lnk=gst&q=console+FocusGained#59bee226473a9eea + " http://groups.google.com/group/vim_dev/browse_thread/thread/ba58fb493a3cf4ba/dc1a22ba1e92579d?lnk=gst&q=terminal+FocusGained#dc1a22ba1e92579d + " Does not work: + " urxvt terminal + " Works: + " GTK2 GUI, on Fedora 11, both as gvim and as vim in a GNOME Terminal + " + " Simple test, create the following autocmd and gain and loose focus in + " the terminal: + " autocmd FocusLost * echomsg "focus lost" + " autocmd FocusGained * echomsg "focus gained" + call s:YRCheckClipboard() + + " If the yankring window is open, refresh it + call s:YRWindowUpdate() +endfunction + +function! s:YRCheckClipboard() + if g:yankring_clipboard_monitor == 1 + " If the clipboard has changed record it inside the yankring + " echomsg "YRCheckClipboard[".len(@*)."][".@*.']['.s:yr_prev_clipboard_star.']' + if has('unnamedplus') && &clipboard =~ '\' + if !empty(@+) && @+ != s:yr_prev_clipboard_plus + 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 YRRecord3("+") + endif + let s:yr_prev_clipboard_plus = @+ + endif + else + if !empty(@*) && @* != s:yr_prev_clipboard_star + 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 YRRecord3("*") + endif + let s:yr_prev_clipboard_star = @* + endif + endif + 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 + + " Check if we should record inserted text + if g:yankring_record_insert == 1 + if !empty(@.) && @. != s:yr_prev_reg_insert + 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 YRRecord3(".") + endif + let s:yr_prev_reg_insert = @. + endif + 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