I want to use yapf to reformat parts of python buffers.

Yapf can take input from stdin yapf -l 30-40. This would produce output that is the whole buffer but with lines 30-40 reformatted. I can then generate diff between the file.py as it is in vim buffer and yapf output. But I don't know how to apply this diff to a current buffer inside of formatexpr.

  • 3
    have you checked the :diffpatch command? Commented May 3, 2018 at 12:23
  • 1
    I did. That's why I'm asking how to make it work inplace instead of creating new buffer with patched content. Commented May 3, 2018 at 14:19
  • 3
    Well, you did not mention it in your question and it should be possible to filter the file through a program, that patches its input and produces the desired output. Second, you might want to evaluate the 'patchexpr' option, that might also work. Commented May 3, 2018 at 14:28
  • 3
    sure, patch :) running diff -N |patch works just fine. Besides, you can also throw some vimscript at the problem, temporarily save the buffer, apply the patch and reload the file from the disk Commented May 3, 2018 at 14:59
  • 1
    Chris, I think you don't understand what I want because I've been too specific in my question. Reloading file from disk would result in the same problem @Rich answer have. Wrong undo history and cursor jumps. I want to be able to reformat parts of files, like a paragraph with correct undo history without my cursor jumping on undo etc. Am I clear now? I don't think your suggestions will achieve this. Commented May 3, 2018 at 19:53

1 Answer 1


Vim provides a filter feature aimed at this sort of problem. This allows you to pass content from Vim into an external tool, and then replace that content with the tool's output.

The documentation can be found at :help filter, but to replace the entire contents of your file with the output of your yapf command you can use the command:

:%!yapf -l 30-40

For commands that don't require the entire content of the buffer as input, you can use a range with a filter (See :help :range!). e.g.:

  • Unfortunately yapf does need the whole content. Commented May 3, 2018 at 9:04
  • How about %!yapf -l 30-40 then?
    – Rich
    Commented May 3, 2018 at 9:18
  • I've tried that. It makes vim think that last change was to change the whole buffer. Which moves the cursor and is inconvenient. Commented May 3, 2018 at 9:41
  • 1
    First off all cursor still jumps around, second I repeat it makes vim think that I've changed the whole buffer, so when I undo cursor jumps to the first line. Commented May 3, 2018 at 10:33
  • @user1685095 Okay. I'm going to leave my answer up anyway, in case it helps other people in the future that don't have precisely the same requirements as you.
    – Rich
    Commented May 3, 2018 at 11:07

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.