0

Say I am in a directory with the filetree below, where gold.txt is a file I would like to compare each of the other .txt files against, one at a time.

.
├── gold.txt
└── to-compare
    ├── compare1.txt
    ├── compare2.txt
    ├── compare3.txt
    ├── ...
    ...

Currently my idea of the workflow would be:

  • I open (n)vim in diff mode with nvim -d to-compare/compare1.txt gold.txt, and open up a netrw split with :Lexplore, so I can easily swap out other files to compare to gold.txt.
  • I see the difference between compare1 and gold as in the image below. Nice.
  • I switch to compare2.txt in the middle window by selecting it in netrw and pressing enter
  • Now, to see the difference between compare2 and gold, I need to do diffoff! and then diffthis on both of the windows.
  • To compare compare3 with gold, I have to do this again.

I'd really like to just be able to quickly tap through the list of files in to-compare/, quickly seeing how & where each one differs with gold.txt, without having to type diffoff and diffthis a bunch of times.

That is, I'd like to put my cursor in the leftmost split in the image below, and whenever I select the next file I'd like to compare (or by selecting it and typing enter, or p for preview or whatever), I'd like see the diff with the other file that's open.

enter image description here

I'm sure there are many options for how to do this. I'm not wed to netrw or anything else about this workflow. Is there an easy way to do what I want to do?

5
  • 1
    Are you familiar with key mapping (:h mapping)? You can trigger multiple commands with a keystroke or two.
    – B Layer
    Sep 24 at 20:50
  • ah, okay, so I suppose I can do something like this: :noremap <leader>d :diffoff!<cr> :diffthis<cr> <c-w>w :diffthis<cr> <c-w>W and then type <leader>d to diff the current window with the next window. I felt there would be an easier way, but that's not so hard, is it.
    – postylem
    Sep 24 at 23:47
  • 1
    Yes but a few things. 1) It's nnoremap if it's a key map to be pressed in Normal mode. 2) You can separate commands with \| or <bar> instead of <cr>. The bar (aka pipe) character | is Vim's command separator. In mappings you must escape it, though. 3) To use Normal mode commands in a mapping mixed with Ex commands use :normal[!]. Alternatively, almost all Normal mode ctrl-w commands have Ex equivalents. See :h :wincmd.
    – B Layer
    Sep 25 at 0:39
  • 1
    And, yes, that may be a lot to absorb but once you're used to it you'll find that key mappings are the simplest, quickest form of automation. (Some would argue that macros are but those are ugly to edit/maintain. Best for one-offs.) Welcome to Vi&Vim SE, btw (10 months after the fact but your first post :)
    – B Layer
    Sep 25 at 0:46
  • Thanks @BLayer. This is useful. I am not comfortable with making mappings on the fly. So, taking your advice, perhaps something like this is more reasonable: :nnoremap <leader>d <Cmd>diffoff! \| diffthis \| wincmd w \| diffthis \| wincmd W<cr> to diff the current window with whatever's in the next window, as a reusable command I can save.
    – postylem
    Sep 25 at 16:04
1
  1. Open first file
:e gold.txt
:diffthis
  1. Create new empty window
:vnew
  1. Create arglist and open the first item
:arglocal to-compare/*.txt

3a. Add it into "diff"

:diffthis
  1. Move to the next buffer
:diffoff | next | diffthis
  1. Repeat previous step with @: until done
4
  • Thanks! This is a nice example of how to use an arglocal list. I've never really used the arg list like this before (I'd just assumed it was the arguments used when invoking vim, not something I'd be able wrangle to my own ends). However, for my workflow, I think I need to :diffoff so I don't end up comparing multiple files at the same time, so step 4 would be :diffoff | next | diffthis, right?
    – postylem
    Sep 25 at 15:53
  • @postylem Yes, although, to say the truth, I don't quite understand why. All these options are window-local, not buffer-local.
    – Matt
    Sep 25 at 16:35
  • Huh. I assumed that diff mode displays difference between buffers where diffthis is set. It seems to behave that way (like if I am getting the diff between two buffers in two vertical splits, and then switch one split to a new file, and get do :diffthis, it still also displays differences with the original buffer, which isn't open in any window). Is that what you would expect?
    – postylem
    Sep 25 at 18:07
  • 1
    @postylem Yes, that's right. Of course, one can automate this with something like aug test | exe 'au! BufWinLeave if &diff | diffoff | endif' | aug end But I don't quite understand why it's not like this out of the box.
    – Matt
    Sep 26 at 6:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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