1

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? – Christian Brabandt May 3 '18 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. – user1685095 May 3 '18 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. – Christian Brabandt May 3 '18 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 – Christian Brabandt May 3 '18 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. – user1685095 May 3 '18 at 19:53
2

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.:

:30,40!yapf
| improve this answer | |
  • Unfortunately yapf does need the whole content. – user1685095 May 3 '18 at 9:04
  • How about %!yapf -l 30-40 then? – Rich May 3 '18 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. – user1685095 May 3 '18 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. – user1685095 May 3 '18 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 May 3 '18 at 11:07

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.