4

Say I have a command that operates on the entire buffer.

The simple solution is to:

  • Run the command taking the entire buffer as input.
  • Store the output.
  • Clear the current buffer.
  • Insert the new contents.

The problem with this is it's quite slow and it seems the undo system stores a lot of data for this operation.

In cases where only a few changes are made - is there a way to only apply changes - in a way doesn't require the heavy operation of replacing the entire contents?

Something like creating a diff and applying it, instead of replacing the entire buffer, however it need not use the diff format.

Or do I need to write my own code to detect differences and apply them as edits?

Drew
  • 75,699
  • 9
  • 109
  • 225
ideasman42
  • 8,375
  • 1
  • 28
  • 105
  • 1
    It's not very clear what you're trying to do. – Drew Dec 12 '19 at 05:28
  • AFAIU, the goal is to transform the contents of buffer A to match the contents of buffer B without changing the text which is identical in both buffers. Hence "Something like creating a diff and applying it, instead of replacing the entire buffer". – phils Dec 12 '19 at 05:58
  • I would expect a solution based on `diff` and `diff-apply-hunk` to be a sensible approach here. I don't know that it would be a *lighter* approach as such, but I think it would *tend* to achieve the aim of not using so much undo data. – phils Dec 12 '19 at 06:07
  • 1
    I just learned something I didn't know. When calling `(diff OLD NEW &optional SWITCHES NO-ASYNC)`, `OLD` and `NEW` can each be buffers (despite the docstring indicating they must be files). I discovered this courtesy of the `diff-buffer-with-file` implementation, which passes a buffer object. The `diff` function uses `diff-file-local-copy` to create a local temp file as necessary. – phils Dec 12 '19 at 06:11
  • 2
    (Documentation bug report raised. Hopefully fixed for 27.1) – phils Dec 12 '19 at 06:48

1 Answers1

5

Emacs-26 introduced replace-buffer-contents specifically to do that job.

But use it with care: it works well when there are few differences, but if the new content happens to be completely different from the old it can be a lot more costly.

Stefan
  • 26,154
  • 3
  • 46
  • 84