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