4

I have a read-only file that I open in Emacs. I have created a keyboard shortcut to hide some regions of the file. For example:

(defun hide-beginning ()
  (interactive)
  (setq buffer-read-only nil)
  (put-text-property 1 10 'invisible t)
  (setq buffer-read-only t)
  )

However, when I exit the buffer with kill-buffer or rather ido-kill-buffer, I get the question

Buffer myfile.txt modified; kill anyway? (yes or no)

How can this question be avoided?

5
  • 1
    If you only care about changes that occur in this function, you can probably use buffer-modified-p and set-buffer-modified-p to store the modified state and restore it after changing the properties.
    – ChrisR
    Commented Dec 2, 2014 at 19:59
  • Thanks it works perfectly! I just put (set-buffer-modified-p nil) after I changed the property.. Commented Dec 2, 2014 at 20:02
  • @ChrisR: I didn't see your comment before posting. Could you post your comment as an answer so that it could be accepted?
    – Dan
    Commented Dec 2, 2014 at 20:05
  • 1
    @HåkonHægland You might want to save value of calling buffer-modified-p at the beginning of the function. That way, if something else modifies the buffer, you will still be prompted about it.
    – zck
    Commented Dec 2, 2014 at 21:36
  • If you're setting text properties which aren't meant to be saved in a file or copied and yanked, you should probably use overlays instead of text properties. See also What are overlays for, and how do they differ from text properties? Commented Dec 4, 2014 at 2:20

3 Answers 3

5

If you only care about changes that occur in this function, you can use buffer-modified-p and set-buffer-modified-p to store the modified state and restore it after changing the properties.

2

The manual notes that you can use set-buffer-modified-p with a nil argument to flag the buffer as unmodified. Hence, if you want your function not to modify the buffer, you could do the following:

(defun hide-beginning ()
  (interactive)
  (let ((buffer-read-only nil)
        (buffer-modified (buffer-modified-p)))
    (put-text-property 1 10 'invisible t)
    (set-buffer-modified-p buffer-modified)))
4
  • Thanks! Don't you need to restore buffer-read-only at the end of the function? Commented Dec 2, 2014 at 20:09
  • 1
    @HåkonHægland: when you let-bind buffer-read-only, you are binding it dynamically for the lifespan of the function -- basically, you're temporarily overriding its value.
    – Dan
    Commented Dec 2, 2014 at 20:12
  • 2
    @HåkonHægland the best approach is to letbind inhibit-read-only to t. That will cover more cases than just setting buffer-read-only to nil.
    – Malabarba
    Commented Dec 2, 2014 at 20:48
  • 2
    Unconditionally marking the buffer as unmodified is very dangerous. You should do that only if the buffer was unmodified in the first place, otherwise this has a high risk of resulting in unsaved changes sooner or later. Commented Dec 4, 2014 at 0:23
2

The macro with-silent-modifications (in subr.el) seems to exist for exactly this use case:

Execute BODY, pretending it does not modify the buffer.
...
Typically used around modifications of text-properties which do
not really affect the buffer's content.

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.