11

In my vimrc I have <C-H>, <C-J>, <C-K> and <C-L> mapped to navigate between split windows in normal mode. When I use diff mode I only ever have windows in vertical splits, so I'd like to re-purpose <C-J> and <C-K> to jump to the previous/next diff.

:help diff mentions &diff when using vimdiff to determine whether you are in diff mode. It looks like this also gets set when you start a diff from an existing vim session, so I assume I should leverage this somehow to re-set the mappings, but I'm not exactly sure how. Based on my 2 second test just before posting this, I tried checking &diff in my vimrc and performing the mapping as needed, but as I suspected the vimrc doesn't get read in again when going into diff mode from an existing vim session.

What would be the best way to detect going to/from diff mode and re-setting the mappings accordingly?

1
  • looking for a similar thing but when using fugitive Nov 3, 2021 at 18:28

2 Answers 2

21

You can create an expression mapping that checks &diff. This is done using the <expr> keyword.

Example

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, <C-J> will be like ]c (jump to start of next change); otherwise, it will be like <C-W>j (move to window below).

3
  • 1
    Would the &diff flag only be detected if vim starts in diff mode, say vim -d ... or also if you open a buffer in diff mode from within Vim already (say :diffthis or equivalent)?
    – gented
    Nov 4, 2020 at 10:57
  • @gented, I think this command, as it stands, operates at the moment it is run, and never again (unless you reaload the source file where the command is). Probably this is a command you would put in a more complex logic, if you want it to behave dynamically.
    – Enlico
    Jan 29, 2021 at 21:54
  • The <expr> modifier makes it so that the expression is evaluated every time the mapping is invoked. The result of the expression is a string, which is interpreted as keystrokes.
    – tommcdo
    Jan 31, 2021 at 15:06
3

I use this feature to change the highligting during diffs.

if &diff

    " Your setting you want to set when using diff mode.
    "

endif
2
  • 3
    You can execute this block regardless of the value of &diff. The Diff* syntax groups are only used for diff. Furthermore, there's no guarantee that this will be re-evaluated when diff mode is entered interactively.
    – tommcdo
    Mar 23, 2015 at 20:57
  • @tommcdo: I removed the example stuff. But the re-evaluation stuff I was unaware of (mainly because I don't switch modes, I ether run as vim or as vimdiff). Mar 23, 2015 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.