vim has this functionality built in (with the correct command line flag).
vim -d <file1> <file2>
This opens each file in a view and highlights the differences.
Any code that is identical is folded away so you do not need to look at identical code or scroll through huge chunks of identical code.
But there is also a wrapper application vimdiff ...
There is DirDiff.vim plugin (GitHub) to diff and merge two directories recursively.
It performs a recursive diff on two directories and generate a diff
"window". Based on that window you can perform various diff operations
such as opening two files in Vim's diff mode, copy the file or
directory recursively to the other, or remove the directory tree ...
To go along with @janos's answer, you can set an autocmd to automatically press those keys when the window is resized (put this in your .vimrc without the leading colon if you want it to apply every time you open Vim):
:autocmd VimResized * wincmd =
Here are the docs for the VimResized autocmd.
You can use Ctrlw-x. From :he CTRL-W_x:
CTRL-W x CTRL-W_x CTRL-W_CTRL-X
CTRL-W CTRL-X Without count: Exchange current window with next one. If there
is no next window, exchange with previous window.
With count: Exchange current window with Nth window (first
The colors are controlled by these four highlight groups (:help hl-DiffAdd):
DiffAdd diff mode: Added line
DiffChange diff mode: Changed line
DiffDelete diff mode: Deleted line
DiffText diff mode: Changed text within a changed line
These are typically defined by a color scheme, but you can customize them in your ~/.vimrc (after the :colorscheme ...
If you are editing an open file and want to compare it to another file without closing the current one:
Open the new file in split screen:
For vertical split:
or horizontal split:
Switch cursors to different split screen:
Invoke "diff mode" in file:
Switch to other file and invoke "diff mode":
I normally use git on the command line.
But when there is a merge conflict I use Vim to resolve them with (personally I do it with with the fugitive plugin). Note: fugitive is good for a lot of git manipulation from within Vim. My favorite feature is the 3 way diff of a merge conflict.
git supports this in vimdiff via git mergetool. I have installed ...
One quick fix is to disable syntax highlighting. Sometimes the code syntax highlighting will cause the foreground text to be the same color as the vimdiff background color, making the text "invisible".
If you want to automatically do this for vimdiff, then add this to the end of your ~/.vimrc:
You can create an expression mapping that checks &diff. This is done using the <expr> keyword.
nnoremap <expr> <C-J> &diff ? ']c' : '<C-W>j'
With this, each time you type <C-J>, the expression &diff ? ']c' : '<C-W>h' is evaluated, and the result (a string) is used for your map. So, in diff-mode, <...
I don't think this can be done by Vim itself. From :h view-diffs (emphasis mine):
hl-DiffText DiffText Changed text inside a Changed line. Vim
finds the first character that is different,
and the last character that is different
(searching from the end ...
As Christian Brabandt suggested in a comment, this can be caused by the 'cursorbind' setting.
From :help 'cursorbind':
When this option is set, as the cursor in the current
window moves other cursorbound windows (windows that also have
this option set) move their cursors to the corresponding line and
You can use :verbose set cursorbind? to ...
As you would switch any other window, <c-w>x or <c-w>r are two options.
Having only two windows opended <c-w>k will switch them and leave the cursor in the window where it was before the switch (i.e. if before the switch the focused window is on the left, after the switch it will be on the left).
<c-w>x will switch the windows and ...
:help diff covers this:
In your .vimrc file you could do something special when Vim was started in
diff mode. You could use a construct like this:
setup for diff mode
setup for non-diff mode
I have a syntax/diff.vim (that I source manually) with the following contents:
hi DiffText cterm=none ctermfg=Black ctermbg=Red gui=none guifg=Black guibg=Red
hi DiffChange cterm=none ctermfg=Black ctermbg=LightMagenta gui=none guifg=Black guibg=LightMagenta
I find the following commands much more intuitive than Ctrlw-x.
The following commands can be used to change the window layout. For example,
when there are two vertically split windows, CTRL-W K will change that in
horizontally split windows. CTRL-W H does it the other way around.
CTRL-W K Move the ...
You can do this:
The :bufdo command runs a given command on all buffers. It works by cycling through all buffers and executing the command, so you will end up on the last buffer.
From the help:
Note: While this command is executing, the Syntax autocommand event is disabled by adding it to 'eventignore'. This considerably speeds ...
I think the most likely culprit is another buffer still in diff-mode. This can happen if you're looking at multiple diffs, one after another, and don't turn off diff-mode between diffs.
Disable diff-mode in irrelevant buffers
The solution is to find the offending buffer(s) and turn off diff-mode with :diffoff. If you don't want to search for it, you can ...
I used the trick from this SO question to see what the command line was, and got this:
:exe '!tr "\0" " " </proc/' . getpid() . '/cmdline'
:!tr "\0" " " </proc/23932/cmdline
gvim -f -d -c wincmd J foo ./foo_LOCAL_23800 ./foo_BASE_23800 ./foo_REMOTE_23800
So the trick is using Ctrl-WJ (via :wincmd):
This is controlled with the shortmess option; specifically, set shortmess=Ot seems to do the trick for me.
Meaning of the Ot flags:
O message for reading a file overwrites any previous message.
Also for quickfix message (e.g., ":cn").
t truncate file message at the start if it is too long to fit
on the command-...
]c doesn't jump to the first difference, it jumps to the next difference. If your first difference is on the first line, ]c would jump to the the second one which is not what you want. One could work around that with ]c[c (jump to next difference then jump to previous).
$ vim -d -c 'norm ]c[c' filea fileb
seems to do what you want.
I don't ...
You have a few questions, some explicit and some implicit. I'll try to answer them in order:
What Do These Commands Do?
You're running two commands:
highlight DiffChange cterm=none ctermfg=fg ctermbg=Red gui=none guifg=fg guibg=Red
highlight Normal term=none cterm=none ctermfg=White ctermbg=Black gui=none guifg=White guibg=Black
Both of these commands ...
DiffAdd and DiffDelete are only used when actually performing a diff ($ vim -d foo.txt bar.txt, $ vimdiff foo.txt bar.txt, $ git mergetool, etc.); those highlight groups are totally irrelevant, here.
The highlight groups used for added and deleted lines when reading a diff file are diffAdded and diffRemoved.
Adding the lines below between line 272 and line ...
You could add this to your .vimrc:
command! -nargs=1 -complete=file Diffsplit diffsplit <args> | wincmd p
This create a Diffsplit command (note the capitalized D) which takes one argument and accept file names as completion.
The command will create the diffsplit with the argument provided and use the command windcm p to go back to the initial file.
Not exactly what you asked, but may find this useful: Splice plugin: a Vim plugin for resolving conflicts during three-way merge.
It has a nice demo screencast on Vimeo.
If you are going to stick with the default vimdiff you could create a function to retrieve the buffer number for the surronding windows and use them to call :diffget twice: