*diffchar.txt* Highlight the exact differences, based on characters and words > ____ _ ____ ____ _____ _ _ _____ ____ | | | || || || || | | || _ || _ | | _ || || __|| __|| || | | || | | || | || | | | || || |__ | |__ | __|| |_| || |_| || |_||_ | |_| || || __|| __|| | | || || __ | | || || | | | | |__ | _ || _ || | | | |____| |_||_| |_| |_____||_| |_||_| |_||_| |_| < Last Change: 2016/03/09 Version: 6.1 Author: Rick Howe ----------------------------------------------------------------------------- INTRODUCTION *diffchar* This plugin has been developed in order to make diff mode more useful. Vim highlights all the text in between the first and last different characters on a changed line. But this plugin will find the exact differences between them, character by character - so called DiffChar. For example, in diff mode: ( [DiffText], ) > (window A) The [quick brown fox jumps over the lazy] dog. (window B) The [lazy fox jumps over the quick brown] dog. < this plugin will exactly show the changed and added units: > (window A) The [quick] fox jumps over the [lazy] dog. (window B) The [lazy] fox jumps over the [quick] dog. < This plugin will synchronously show/reset the highlights of the exact differences as soon as the diff mode starts/ends since a |g:DiffModeSync| is enabled as a default. It synchronously works as well on your custom diff tool (e.g. git-diff) when you have specified it to the 'diffexpr' option. In non-diff mode or when the |g:DiffModeSync| is disabled, you can toggle to show/reset the diff highlights by pressing or or using |:TDChar| command. To show or reset them, use |:SDChar| or |:RDChar| command. In diff mode, the corresponding changed lines are compared between two windows. In non-diff mode, the same lines are compared among them. You can set a matching color to a |g:DiffColors| to make it easy to recognize the corresponding changed units between two windows. As a default, all the changed units are highlighted with DiffText. In addition, DiffAdd is always used for the added units and both the previous and next character of the deleted units are underlined. This plugin traces the differences based on a |g:DiffUnit|. Its default is 'Word1' and it handles a \w\+ word and a \W character as a difference unit. There are other types of word provided and you can also set 'Char' to compare character by character. While showing the exact differences, you can use ]b or ]e to jump cursor to the start or end position of the next difference unit, and [b or [e to the start or end position of the previous unit. Then this plugin echoes the corresponding difference unit with the assigned color as a message. Those keymaps, and are configurable in your vimrc and so on. This plugin attempts to keep the exact differences updated while editing since a |g:DiffUpdate| is enabled as a default. However, a total number of lines are changed (after some lines are added/deleted), all the diff highlights will be cleared and you will need to manually show them again to update. This plugin has been using "An O(NP) Sequence Comparison Algorithm" developed by S.Wu, et al., which always finds an optimum sequence quickly. But for longer lines and less-similar files, it takes time to complete the diff tracing. To make it more efficient, this plugin splits the tracing with the external diff command. Firstly applies the internal O(NP) algorithm. If not completed within the time specified by a |g:DiffSplitTime|, continuously switches to the diff command at that point, and then joins both results. This approach provides a stable performance and reasonable accuracy, because the diff command effectively optimizes between them. Its default is 100 ms, which would be useful for smaller files. If prefer to always apply the internal algorithm for accuracy (or the diff command for performance), set some large value (or 0) to it. This plugin sets the DiffCharExpr() to the 'diffexpr' option, if it is empty. It also uses the |g:DiffSplitTime| and splits the tracing between the internal algorithm and the external diff command. If prefer to leave the 'diffexpr' option as empty, set 0 to a |g:DiffExpr|. This plugin works on each tab page individually. You can use a tab page variable (t:), instead of a global one (g:), to specify different options on each tab page. This plugin has been always positively supporting mulltibyte characters. ----------------------------------------------------------------------------- COMMANDS *diffchar-commands* :[range]SDChar - Show the highlights of difference units for [range] :[range]RDChar - Reset the highlights of difference units for [range] :[range]TDChar - Toggle to show/reset the highlights for [range] ----------------------------------------------------------------------------- KEYMAPS *diffchar-keymaps* ToggleDiffCharAllLines (default: ) Toggle to show/reset the highlights for all/selected lines ToggleDiffCharCurrentLine (default: ) Toggle to show/reset the highlights for current/selected lines JumpDiffCharPrevStart (default: [b) Jump cursor to the start position of the previous difference unit JumpDiffCharNextStart (default: ]b) Jump cursor to the start position of the next difference unit JumpDiffCharPrevEnd (default: [e) Jump cursor to the end position of the previous difference unit JumpDiffCharNextEnd (default: ]e) Jump cursor to the end position of the next difference unit ----------------------------------------------------------------------------- OPTIONS *diffchar-options* |g:DiffUnit|, |t:DiffUnit| Type of difference unit 'Word1' : \w\+ word and any \W single character (default) 'Word2' : non-space and space words 'Word3' : \< or \> character class boundaries 'Char' : any single character 'CSV(,)' : separated by characters such as ',', ';', and '\t' |g:DiffColors|, |t:DiffColors| Matching colors for changed unit pairs (always DiffAdd for added units) 0 : always DiffText (default) 1 : 4 colors in fixed order 2 : 8 colors in fixed order 3 : 16 colors in fixed order 100 : all available colors in dynamic random order |g:DiffUpdate|, |t:DiffUpdate| (available on vim 7.4) Interactively updating the diff highlights while editing 1 : enable (default) 0 : disable |g:DiffSplitTime|, |t:DiffSplitTime| A time length (ms) to apply the internal algorithm first 0 ~ : (100 as default) |g:DiffModeSync|, |t:DiffModeSync| Synchronously show/reset with diff mode 1 : enable (default) 0 : disable |g:DiffExpr| Set DiffCharExpr() to the 'diffexpr' option 1 : enable (default) 0 : disable ----------------------------------------------------------------------------- CHANGE HISTORY *diffchar-history* Update : 6.1 * Improved a workaround for vim 7.4.682 (at update 5.1) not to disappear vim's DiffChange/DiffText highlights in other tab pages. * Improved to handle diff tracing only once in one diff session when more than 2 buffers become diff mode and DiffModeSync is enabled. * Fixed to correctly reset diffchar highlights on a split window when the window is closed. Update : 6.0 * Defined a new :TDChar command to toggle the highlights for specified range, and make it possible to select a block of lines in visual mode and toggle them by using . * Changed the default value of g:DiffUnit from 'Char' to 'Word1', where \w\+ is handled as a single difference unit, to make more sense to usual case. * Changed the default value of g:DiffSplitTime from 500 to 100 to switch more quickly and changed to check the time more often (unit-by-unit, not line-by-line) to detect the time limit earlier. * Changed to use the g:DiffSplitTime, instead of the number of lines as an argument, in the DiffCharExpr() to switch to the diff command as accurately as specified. * Improved the way to analyze the output of the diff command quickly. * Enhanced to interactively update the highlights faster while editing when g:DiffUpdate is enabled. * Changed the position of a pair cursor for a deleted unit on either its previous or next character instead of both. * Fixed to ignore white spaces at line end when iwhite is specified in the 'diffopt' option. * Fixed to enable to use a t:DiffModeSync tab page variable as well as its global one. Update : 5.5 * Introduced g:DiffModeSync to synchronously show/reset the highlights as the diff mode starts/ends, which also works on your custom diff tool. * Changed to enable g:DiffUpdate as a default and then interactively update the highlights while editing. * Enhanced to draw and delete the highlights faster by specifying as many position parameters as possible in one matchaddpos() and matchadd() call. * Changed to select current window and next diff mode window (if present) whose buffer is different at initialize. * Fixed: - caused an error on getwinvar() in vim 7.3. - in non-gVim, did not show a matching pair cursor when jumping the cursor by using [e or ]b, depending on a color scheme. - sometimes failed to toggle the highlights when using or in diff mode windows. - did not interactively update the highlight of all the lines when multiple lines were changed at once if g:DiffUpdate = 1. Update : 5.4 * Enhanced to show a position of a deleted unit with underline on its previous and next characters. This position is where a unit is added between those characters in another diffchar window. * Improved to be able to change this plugin's global variables anytime. * Changed to select current window and then the next (wincmd w) window whose buffer is different. Update : 5.3 * Performance improved for long lines and some defects fixed when the diff command is used for the diff tracing. Update : 5.2 * Enhanced to provide a stable performance even for less-similar long files. The new approach applies this plugin's algorithm first, and if not completed within the specified time, continuously splits the tracing with the diff command, and join both results. * Fixed: when diff command does not choose minimal algorithm and it shows the equivalent lines as "changed", this plugin sometimes makes an error. * Fixed: if file encoding is not same as buffer encoding, a difference may not be correctly detected in DiffCharExpr(). Update : 5.1 * Since vim 7.4.682, it has become impossible to overwrite the vim's diff highlights with this plugin. Then, for example, DiffText bold typeface will be left in all the diff highlighted lines (for more info, see https://groups.google.com/forum/?hl=en_US#!topic/vim_use/1jQnbTva2fY). This update provides a workaround to reduce its effect and to show the differences mostly same as before. Update : 5.0 * Significantly improved the way to trace and show the differences and make them 1.5 ~ 2.0 times faster. * Introduced g:DiffMaxRatio (and t:DiffMaxRatio), a maximum difference ratio to trace (100% as default). Once exceeds, the diff tracing is recursively split and helps to keep performance instead of diff accuracy. * Discontinued other difference algorithms (OND and Basic) than the ONP, then g:DiffAlgorithm no longer supported. * Improved to allow to specify one or more characters for 'CSV(c)' in g:DiffUnit (and t:DiffUnit). For example, 'CSV(,:\t)' will split the units by a comma, colon, and tab. Use '\\' for a backslash. Update : 4.9 * Fixed DiffCharExpr() to check the number of total lines, not different lines only, of both windows and apply either internal algorithm or external diff command, in order to keep the appropriate performance for large files. Update : 4.81 * Enhanced to make DiffCharExpr() a bit faster by using uniq() or so. Update : 4.8 * Enhanced to set the threshold value on DiffCharExpr() to check how many differences and then apply either of internal algorithm or external diff command. The default for 'diffexpr' option using DiffCharExpr() is changed to use this threshold, 200 - apply internal if less than 200 differences, apply external if more. * Changed the way to select windows when more than 2 windows in the page. - automatically select the diff mode's next (wincmd w) window, if any, in addition to the current window - can select any of split windows as vim can do for diff Update : 4.7 * Enhanced to set DiffCharExpr() to the 'diffexpr' option, if it is empty. When diff mode begins, vim calls this function which finds differences by this plugin's internal diff algorithm (default) and then initially shows the exact differences (default). You can also explicitly set this function to the option with different arguments. * Enhanced to make the key mappings configurable. For example, the default can be modified by: nmap your_favorite_key ToggleDiffCharAllLines * Fixed to correctly adjust the position of difference units when 'diffopt' iwhite option is enabled. Update : 4.6 * Fixed to correctly show the colors of changed units in one-by-one defined order of g:DiffColors. Since an added unit was improperly counted as changed one, some colors were skipped and not shown. The first changed unit is now always highlighted with DiffText in any color mode. Update : 4.5 * Fixed to trace the differences until the end of the units. Previously the last same units were skipped, so last added units were sometimes shown as changed ones (eg: the last "swift brown" on above were shown as changed units but now shows "brown" as added ones). * Enhanced to use your global variables if defined in vimrc. Update : 4.4 * Enhanced to follow 'diffopt' icase and iwhite options for both diff and non-diff modes (ignorecase option is not used). Previously, it has been always case and space/tab sensitive. * Implemented to highlight the difference units using a new matchaddpos() function, introduced in 7.4.330, when available to draw faster. Update : 4.3 * Enhanced to differently show added/deleted/changed difference units with original diff highlightings. - added units will be always highlighted with DiffAdd. - changed units will be highlighted based on the g:DiffColors (and t:DiffColors) variable, but DiffText is always used for the first changed unit. - when jumping cursor by [b/]b or [e/]e on the added unit, it highlights around the corresponding deleted units with a cursor-type color in another window, and echoes a diff-delete filler with DiffDelete, along with common characters on both sides (e.g. a-----b). Update : 4.2 * Enhanced to update the highlighted DiffChar units while editing. A g:DiffUpdate (and t:DiffUpdate) variable enables and disables (default) this update behavior. If a text line was added/deleted, reset all the highlightings. This feature is available on vim 7.4. Update : 4.1 * Implemented to echo a matching difference unit with its color when jumping cursor by [b/]b or [e/]e. * Fixed defects: not using the new uniq() function introduced in vim 7.4. Update : 4.0 * Enhanced to easily find a corresponding pair of each difference unit. - each unit pair will be shown in individual same color on both windows. A g:DiffColors (and t:DiffColors) variable is a type of matching colors, 0 (default) for always 1 color as before, 1/2/3 for 4/8/16 colors in fixed order, and 100 for all available colors in dynamic random order. - when jumping cursor by [b/]b or [e/]e in either window, the start or end position of a matching unit will be highlighted with a cursor-type color in another window. Update : 3.6 * Added two g:DiffUnit (and t:DiffUnit) types. 'Word3' will split at the \< or \> boundaries, which can separate based on the character class like CJK, Hiragana, Katakana, Hangul, full width symbols and so on. And 'CSV(c)' will split the units by a specified character 'c'. For example, 'CSV(,)' and 'CSV(\t)' can be used for comma and tab separated text. Update : 3.5 * Fixed defects: DiffChar highlighting units do not override/hide hlsearch. Update : 3.4 * Enhanced to support individual DiffChar handling on each tab page. Difference unit and algorithm can also be set page by page using tab page local variables, t:DiffUnit and t:DiffAlgorithm. Update : 3.3 * Enhanced to jump cursor to the DiffChar highlighting units. Sample keymaps ]b and [b will move cursor forwards to the next and backwards to the previous start positions. And ]e and [e will move to the end positions. Update : 3.2 * Enhanced to follow diff mode without any limitations. Compare between the corresponding DiffChange lines on both windows and properly handle DiffAdd and DiffDelete lines. Update : 3.1 * Enhanced to show/reset/toggle DiffChar highlightings on individual line by line. * Implemented the window layout handling. - the DiffChar'ed windows will remain the highlightings even if the window position is rotated/replaced/moved and another new window opens. - if either DiffChar'ed window is closed, reset all the DiffChar highlightings on another window. * Removed limitations: - when more than 2 windows exist, current and next (wincmd w) windows will be selected. - if the specified numbers of lines are different in both windows, ignore the redundant lines and continue to compare the text on the same lines. - RDChar sample command has a range attribute (e.g. %RDChar). * Fixed defects: - reset just DiffChar highlightings only and remain others. Update : 3.0 * Implemented word by word differences. A g:DiffUnit variable is a type of a difference unit. Its default is 'Char', which will trace character by character as before. 'Word1' will split into \w\+ words and any \W single characters. And 'Word2' will separate the units at the \s\+ space boundaries. * Improved the performance around 10%. Update : 2.1 * Coding changes in the O(NP) function for readability. Update : 2.0 * Implemented the O(NP) and O(ND) Difference algorithms to improve the performance. This update uses the O(NP) by default, and can be changed to the O(ND) if necessary, or to the basic algorithm implemented in the initial version. vim:tw=78:ts=8:ft=help:norl: