I'm trying to understand how vimdiff work.
Here I tried to diff two simple files. The 1st:
abcdefghijklmnopqrstuvwxyz
foo
abcdefghijklmnopqrstuvwxyz iii
bar
The 2nd:
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
Here is result from diffmerge utility:
And here is result from vim:
Note that vim doesn't see the similarity between abc...xyz and abc...xyz iii lines and doesn't arrange them visually on one line.
Is there some settings to improve vimdiff in such cases?
As pointed out in the comments, vim uses the external utility diff which doesn't do word diffs nor can it find moved-and-modified lines.
Even resorting to diffexpr is unsatisfactory, since Vim expects the data from the external utility to be in a "ed" style diff. This rules out using alternative diff utilities that make word or even char based diffs, like diffmerge.
The workaround some industrious plugin authors have cooked up is to wrap the results of these more sophisticated diffs and translate their output into the "ed" style diff for Vim to consume. I know of two such plugins which take this approach: chardiff and vim-diff-enhanced. Both give you word diffs. In addition, Vim-diff-enhanced allows you to toggle between various diff algorithms (myers, histogram, patience) so one may decide which diff produces the best result on a case by case basis.
I use vim-diff-enhanced, and it is better than the default diff but still not great. (note: it depends on git.) For example, I tried your test, as described in the question, and it did NOT recognize that lines 5 and 3 were the same (even with :set diffopt+=iwhite). Although, if I removed or added something to line 2 of your first sample file, then vimdiff matched the results you obtained from diffmerge.
Related
vimdiff file1 file2
besides differences shows also same lines from both files. Is it possible to hide them? How to do it?
As Vim is a text editor (not a specialized diff viewer), the full contents of both files are kept (so you can do edits and persist them). Vim usually just "hides" multiple identical lines by folding them away; they are still present, just not visible.
You can influence how many identical lines are kept around changes (default: 6 lines above and below) via the context value of the 'diffopt' option. So, to completely fold all identical lines:
:set diffopt+=context:0
It is still showing common lines if common line is going in sequence with different. one after another
The solution suggested by Ingo Karkat worked perfectly in Linux. Thanks for sharing it. However, it's not working on Mac.
I've got two c++ files that I want to diff with vimdiff. One of them has a lot more function definitions at the start, before both have a common function that I'm actually interested in. However, vimdiff seems incapable to ignore all the function defs before the common one (perhaps because of different arguments).
Is there any way I can give a hint to vimdiff that, say, line xxx in file1.cxx is equals to line yyy in file2.cxx?
I'm open for alternative solutions without vimdiff, but they must be on linux and very preferably command line, since I'm ssh-ing and any graphical interface is a bit uncomfortable.
Vim just delegates the actual work of comparing the files to the external diff utility, cp. :help diff-diffexpr. The help page also shows how a different utility can be used. Unfortunately, I'm not aware of any more "intelligent" or configurable diff tool that would help in your situation.
A workaround might be (temporarily) removing the excess functions that you're not interested in, anyway. With the BlockDiff plugin, you don't actually need to modify the files. Just select the interesting lines in both windows and execute :[range]BlockDiff on them. Only those sections will then be diffed in a separate tab page. (The plugin mentions this requires a GUI, but Vim in a terminal supports tab pages just as well.)
Summary
Is there a "find similar snippets" plugin is available for VIM, OR ALTERNATIVELY,
is there a plugin for vim which could easily be extended to do this efficiently?
Details
I realize this is a strange question to ask without context, so here is the context. I'm open to other solutions to the same problem if a "vim plugin" isn't ideal.
I generally do a lot of grepping when working on a new project. Is there a way inside of vim, that i can "grep" and display several snippets (the 2 lines above/below) for a particular string which im currently highlighting.
Clarification: For example, in this post, If i highlighted "inside of vim", I'd like to see (in the VIM window) the results of grep -r -B 2 -A 2 "inside of vim".
The hard part here is of course (1) the visualization pop up and (2) having the shortcut to type when text is selected, otherwise its easy to grep for this kind of thing in a separate terminal. I generally find "CTRL+N" is VERY useful largely because the 2nd dimension it adds for auto-completion, and im mostly looking for an extension of it which shows a glimpse of similar code snippets in other files of a directory.
You probably want the CtrlSF plugin. Try it, you'll be impressed.
On a side note, CtrlSF can make use of ack and ag. These are essentially improved versions of grep, tuned up for programming. Take a look at those too, they will change your programming life for the better.
There are also Ack and Ag plugins that can interface Vim with ack and ag directly, which work by putting the output of said programs in quickfix lists. However, CtrlSF does all that and much more.
In ruby methaprogramming we have special types of comments within multiline string that will be evaluate. They looks like this: https://github.com/rails/rails/blob/8775ffa37231d381cba34f0ecacb8a7bbcf0573f/activesupport/lib/active_support/memoizable.rb#L77
This string divided line by line on two parts: string with interpolate that will be evaluate on the left side and example of code on the right side. Manually type this comments is a hard work. It requires many manual indentation.
Is there some plugins or tools in vim that help with code this type of comments?
First of all, get to know the features that make life easier for stuff like this in vim:
Visual block mode
blockwise-visual
blockwise operators
virtualedit; You can move the cursor to positions where there isn't any text. This is called "virtual space". The user guide has extensive samples talking about editing ascii tables (similar to your situation in some ways):
Here are two approaches:
Assuming that the vertical split is always in a fixed column (like 84 in this sample):
/\%84v#\zs
will locate the vertical divider bar. Now you can operate on that, e.g.
Quick and dirty: Fold comments pairwise
This results in the comment lines being folded right after the 'template' line:
:g//s//\r /
Note: the (9) spaces have been chosen to match the starting indent level of the OP's sample. IRL, you could use indent('.') to figure out how many spaces programmatically
Presto:
To recombine:
:g//join!
Possibly combined with something to 'eat' the redundant indent (9 spaces)
:g//j!|norm! n9x
Alternatives:
I'd usually opt to split the blocks into physical files instead. Recombining them will take more effort, but editing is much more comfortable and you can leverage vim's diffmode.
Just a quick starter:
ggn<C-v>ND
:tabnew | 0put
:tabprev
gvVxgvVd
:tabnext | vert new | 0put
put the windows in diffmode:
:windo diffthis
Now you can edit both windows independently, with live diff highlighting.
Let me know if you would like more input on this strategy. I might try my hand at recombining from the split temp-window configuration.
I need to read through some gigantic log files on a Linux system. There's a lot of clutter in the logs. At the moment I'm doing something like this:
cat logfile.txt | grep -v "IgnoreThis\|IgnoreThat" | less
But it's cumbersome -- every time I want to add another filter, I need to quit less and edit the command line. Some of the filters are relatively complicated and may be multi-line.
I'd like some way to apply filters as I am reading through the log, and a way to save these filters somewhere.
Is there a tool that can do this for me? I can't install new software so hopefully it's something that would already be installed -- e.g., less, vi, something in a Python or Perl lib, etc.
Changing the code that generates the log to generate less is not an option.
Use &pattern command within less.
From the man page for less
&pattern
Display only lines which match the pattern; lines which do not
match the pattern are not displayed. If pattern is empty (if
you type & immediately followed by ENTER), any filtering is
turned off, and all lines are displayed. While filtering is in
effect, an ampersand is displayed at the beginning of the
prompt, as a reminder that some lines in the file may be hidden.
Certain characters are special as in the / command:
^N or !
Display only lines which do NOT match the pattern.
^R Don't interpret regular expression metacharacters; that
is, do a simple textual comparison.
Try the multitail tool - as well as letting you view multile logs at once, I'm pretty sure it lets you apply regex filters interactively.
Based on ghostdog74's answer and the less manpage, I came up with this:
~/.bashrc:
export LESSOPEN='|~/less-filter.sh %s'
export LESS=-R # to allow ANSI colors
~/less-filter.sh:
#!/bin/sh
case "$1" in
*logfile*.log*) ~/less-filter.sed < $1
;;
esac
~/less-filter.sed:
/deleteLinesLikeThis/d # to filter out lines
s/this/that/ # to change text on lines (useful to colorize using ANSI escapes)
Then:
less logfileFooBar.log.1 -- applies the filter applies automatically.
cat logfileFooBar.log.1 | less -- to see the log without filtering
This is adequate for now but I would still like to be able to edit the filters on the fly.
see the man page of less. there are some options you can use to search for words for example. It has line editing mode as well.
There's an application by Casstor Software Solutions called LogFilter (www.casstor.com) that can edit Windows/Mac/Linux text files and can easily perform file filtering. It supports multiple filters as well as regular expressions. I think it might be what you're looking for.