Who is setting the modified flag on my files in Emacs? - emacs

Over the course of the last few years I've been slowly growing my Emacs configuration, adding bits and pieces, add new modes etc. Around a year ago a problem started to occur regularly: some code is setting the modified bit on my buffers. It doesn't actually change anything, it just sets this flags. It is slightly annoying since each time I run compile or save-some-buffers I have to manually discard the changes in these buffers to reset the modified bit. How can I find the offending code?

Contrary to phils, I expect that your modified-p flag is not set by set-buffer-modified-p but rather by actual changes to the buffer. The reason this is possible is that text-properties are treated by Emacs as belonging to the content of the buffer, so changing them sets the modified-p flag, even tho in many cases the result is invisible and even if it is visible it is generally not perceived by the user as a modification (which users generally understand as something like "affects the file when I save the buffer").
So, most of the code that sets text-properties needs to be careful to reset the modified-p flag afterwards. The best way to do that is usually by wrapping the code that sets the properties inside a with-silent-modification.
One way try to track down the culprit is by trying to undo the modification (e.g. with C-/), but of course, if the modification is not visible, undoing it won't be visible either. So instead you may want to look at C-h v buffer-undo-list RET which is the internal data used to keep track of the modifications. With luck, not only was the modified-p set but the undo-list as well, and that list will tell you what was changed. For example, that list could look like (nil (nil face nil 12345708 . 12345713)) which means that the change was to set the face property to a new value between positions 12345708 and 12345713 and that the old value of that property was nil (that's the 3rd nil in the above). Sometimes looking at the affected positions with M-: (goto-char 12345708) RET is sufficient to figure out who's to blame. Othertimes looking at M-: (get-text-property 12345708 'face) RET, which gives you the new value that was set, is more useful.

If something really is explicitly setting the buffer as modified without changing anything, then I guess it ought to be calling set-buffer-modified-p.
I was originally going to suggest debug-on-entry for set-buffer-modified-p, but a cursory test showed that was extremely disruptive in general, so here's a way you can indicate which buffers you are interested in:
(defvar my-debug-set-buffer-modified-p-buffers nil)
(defadvice set-buffer-modified-p
(before my-debug-set-buffer-modified-p-advice)
(when (memq (current-buffer) my-debug-set-buffer-modified-p-buffers)
(debug)))
(ad-activate 'set-buffer-modified-p)
(defun my-debug-set-buffer-modified-p (buffer)
(interactive (list (current-buffer)))
(if (memq buffer my-debug-set-buffer-modified-p-buffers)
(progn (setq my-debug-set-buffer-modified-p-buffers
(delq buffer my-debug-set-buffer-modified-p-buffers))
(message "Disabled for %s" buffer))
(add-to-list 'my-debug-set-buffer-modified-p-buffers buffer)
(message "Enabled for %s" buffer)))

Related

Overriding buffer-read-only in a region

I want most of a buffer to be read-only, except for one small region (part of a line).
I first tried something like
(setq buffer-read-only t)
(let ((inhibit-read-only t))
(add-text-properties start end '(read-only nil)))
but apparently buffer-read-only takes precedence over the read-only property.
I now have buffer-read-only set to nil, and set the read-only property to t on everything except the editable region. (Or read-only nil is regarded as a no-op.)
Is there a better way?
EDIT:
A more detailed description of my use case is that I want my buffer to display the output of an asynchronous process. The output is mostly for read-only viewing. However, a small part of a line is editable. This part will become input to the process if it is run again.
There's no simple way to do what you need in Emacs 24 and earlier. I agree with your solution to mark everything with the read-only property except the parts that you want to be editable.
Emacs 25 will have the inhibit-read-only property, which does exactly what you want. It was implemented by larsi on 16 November, and is used by eww.

elisp code clobbering a buffer, instead of saving off elsewhere... why?

I'm having some difficulties when trying to set something up that saves some persistent state, so that I can use the data between emacs invocations.
Using as a starting point some code from another question, I came up with the following little code snippet for something I'm wanting to do:
(defmacro with-output-to-file (path &rest body)
"record output of commands in body to file"
`(save-excursion
(let* ((buf (find-file-noselect ,path))
(standard-output buf))
(set-buffer buf)
(erase-buffer)
,#body
(save-buffer)
(kill-buffer))))
I then have a function that uses this, like:
(defun my-save-some-data ()
(with-output-to-file my-data-save-file
(prin1 my-data)))
EDIT: These both follow code like the following (previously, these were both setq; thanks to a comment from #phils for inspiring me to switch them to devfar and defcustom):
; note: my actual variable names (and filename value) are different;
; changed for example sake:
(defvar my-data (make-hash-table :test 'equal) "Data for a thing")
(defcustom my-data-save-file "~/tmp/my-data.el" "File to save my data to")
(Note: I also have a function to read the data back in, which happens automatically at load time, or on demand.)
I've set that up to run in a few circumstances (maybe too many? maybe poor choices? Anyway, this is what I set up):
(add-hook 'auto-save-hook 'my-save-some-data)
(add-hook 'kill-emacs-hook 'my-save-some-data)
(add-hook 'post-gc-hook 'my-save-some-data)
Most of the time, this works fine. However, every once in a while, I'm getting a problem where the data gets written to one of my previously-open buffers (killing all previous content there!), and then that buffer gets killed, with the saved changes.
Suffice it to say, this is highly annoying, as the buffer where this happens is frequently somewhere where I've been doing some work, and not necessarily checked it in yet.
I tried altering the macro above, replacing from (set-buffer buf) on with:
(with-current-buffer buf ; because set-buffer wasn't working??
(erase-buffer)
,#body
(if (eq buf (current-buffer))
(progn
(save-buffer)
(kill-buffer))
(message "buffer changed?!"))))))
This has somehow managed to cause it to append to the buffer, instead of overwriting it... so my if statement does seem to be working to some degree... however I don't see the message in my *Messages* buffer, so... I'm not quite sure what's going on.
One thing I think I've noticed (though it's hard to be certain, since I may not be actively paying attention when this happens) is that this happens in a not-then-currently-active buffer, rather than a buffer I'm currently editing.
So, the questions:
Am I doing something wrong here?
Are there other/better ways of doing this?
Are there standard ways to save state in a programatic way, that I could be using? (I poked around a bit in apropos, but failed to find anything... though perhaps I just don't know what to look for.)
What can I do to help myself track this down? (is there a way I can set breakpoints or something?)
Are there other protections I could use in code like this?
Any other thoughts welcome. I'm adding some more (message) forms in hopes of getting more debugging info in the mean time.
UPDATE: I've figured out that this only happens with the post-gc-hook. I don't know if my variables were somehow getting clobbered (and perhaps switching to defvar and defcustom will solve that?), or if there's some sort of obscure bug in the post-gc-hook processing... checking for reproducing the test-case with this latest change.
You can indeed set breakpoints, an easy way to do this is to put (edebug) in the place where you want to break. Then you can use, n for next, SPC for step, and e to eval. You can read more about edebug here.
So you can set a conditional breakpoint as a protection/warning, like this, before your call to (set-buffer):
(when (get-file-buffer my-data-save-file)
(read-from-minibuffer
(format "Warning: %s is already being visited by a buffer, contents will be overwritten! Entering edebug" my-data-save-file))
(edebug))
This will warn you and then enter the debugger if a file you are visiting in some buffer is about to be overwritten by your macro, where you can inspect what is going on.
Here is part the docstring of find-file-no-select:
Read file FILENAME into a buffer and return the buffer.
If a buffer exists visiting FILENAME, return that one, but
verify that the file has not changed since visited or saved.
My guess is that the my-data-save-file is already being visited by a buffer, so that is the buffer that is returned (and subsequently overwritten). But you can really find out what is happening with (edebug).
Just a quick reply to some of what you said. Your message never appears probably because you test whether the buffer of with-current-buffer is the current-buffer, which it always is, unless body changes the current buffer.
But you are right to use with-current-buffer instead of save-excursion followed by set-buffer.
As for other ways: why not put your data in a temporary buffer and then use write-file or append-to-fileor write-region?
FWIW, I tried your code briefly and saw no problem. But I just tried a simple (prin1 (symbol-function 'my-save-some-data)) for the body and a constant file name for the file. I tried with pre-existing file or not, and with pre-existing buffer or not, and with pre-existing unsaved modified buffer or not.
Are you testing with the interpreted code (e.g., macro present) or byte-compiled code?

fix an auto-complete-mode and linum-mode annoyance

I'm using auto-complete-mode which I think is totally fantastic. I'm also a big fan of linum-mode but I've got a very irritating issue when the two are used together, especially when I'm working in a new buffer (or a buffer with very few lines).
Basically the buffer is 'x' lines long but when auto-complete kicks in it "adds" lines to the buffer, so linum-mode keeps switching, for example, between displaying line numbers on one column or two columns, depending on whether auto-complete is suggesting a completion or not.
So you type a sentence and you see your buffer's content frantically shifting from left to right at every keypress. It is really annoying.
I take it the solution involves configuring the linum-format variable but I don't know how.
Ideally it would be great if my linum-format was:
dynamic
right-aligned
considering there are 'y' more lines to the buffer than what the buffer actually has
My rationale being that auto-complete shall not suggest more than 'y' suggestion and that, hence, the two shall start playing nicely together.
For example, if 'y' is set to 20 and my buffer has 75 lines, then linum should use two columns: because no matter where I am auto-complete shall not make the buffer 'bigger' than 99 lines.
On the contrary, if 'y' is still set to 20 and my buffer has 95 lines, then linum should use three columns because otherwise if I'm near the end of the buffer and auto-complete kicks in my buffer shall start "wobbling" left and right when I type.
I'd rather not hardcode "3 columns wide" for linum.
I guess using "dynamic but always at least two columns" would somehow fix most annoyances but still something as I described would be great.
P.S: I realize that my 'fix' would imply that linum would always display on at least two columns, and I'm fine with that... As long as it stays right-aligned and use 2, 3 or 4 columns depending on the need.
Simply put the following line in .emacs which resolves this issue. It is in auto-complete.el.
(ac-linum-workaround)
I've written a couple of previous answers on modifying the linum-mode output, which you could probably adapt to your purposes.
Relative Line Numbers In Emacs
Colorize current line number
Edit: Here's the most basic version of that code (also on EmacsWiki, albeit somewhat buried), which doesn't modify the default output at all, but uses the techniques from those other answers to be more efficient than the default code. That's probably a more useful starting point for you.
(defvar my-linum-format-string "%4d")
(add-hook 'linum-before-numbering-hook 'my-linum-get-format-string)
(defun my-linum-get-format-string ()
(let* ((width (length (number-to-string
(count-lines (point-min) (point-max)))))
(format (concat "%" (number-to-string width) "d")))
(setq my-linum-format-string format)))
(setq linum-format 'my-linum-format)
(defun my-linum-format (line-number)
(propertize (format my-linum-format-string line-number) 'face 'linum))
Just have the same problem, after seeing 'patching the source' I believe it could be done with advice. Here is what I come up with
(defadvice linum-update
(around tung/suppress-linum-update-when-popup activate)
(unless (ac-menu-live-p)
ad-do-it))
I would like to use popup-live-p as mentioned but unfortunately it requires the variable for the popup, which we couldn't know in advance.
Update:
I ended up patching the source for linum.el. I added an extra hook that runs before updates.
Here's the patched file: linum.el (github)
Here's the code I have in my init.el:
;; Load custom linum.
(load-file "~/.emacs.d/linum.el")
;; Suppress line number updates while auto-complete window
;; is displayed.
(add-hook 'linum-before-update-hook
'(lambda ()
(when auto-complete-mode
(if (ac-menu-live-p)
(setq linum-suppress-updates t)
(setq linum-suppress-updates nil)))))
Hope it helps!

Emacs: How to intelligently handle buffer-modified when setting text properties?

The documentation on Text Properties says:
Since text properties are considered part of the contents of the buffer (or string), and can affect how a buffer looks on the screen, any change in buffer text properties marks the buffer as modified.
First, I don't understand that policy. Can anyone explain? The text props are not actually saved in the file, when the buffer is saved. So why mark the buffer as modified? For me, buffer-modified indicates "some changes have not yet been saved." but understanding the policy is just for my own amusement.
More importantly, is there an already-established way that, in code, I can change syntax text properties on the text in a buffer, while keeping the buffer-modified flag set to whatever it was, prior to those changes? I'm thinking of something like save-excursion.
It would be pretty easy to write, but this seems like a common case and I'd like to use the standard function, if possible.
For more on the scenario - I have a mode that does a full text scan and sets syntax-table properties on the text. After opening a buffer, the scan runs, but it results in a buffer with buffer-modified set to t .
As always, thanks.
Newer versions of Emacs include the macro "with-silent-modifications" for this:
C-h f with-silent-modifications
------------------------------------------------------
with-silent-modifications is a Lisp macro in `subr.el'.
(with-silent-modifications &rest BODY)
Execute BODY, pretending it does not modify the buffer.
If BODY performs real modifications to the buffer's text, other
than cosmetic ones, undo data may become corrupted.
Typically used around modifications of text-properties which do not really
affect the buffer's content.
Wait! I found this in cc-defs.el
;; The following is essentially `save-buffer-state' from lazy-lock.el.
;; It ought to be a standard macro.
(defmacro c-save-buffer-state (varlist &rest body)
"Bind variables according to VARLIST (in `let*' style) and eval BODY,
then restore the buffer state under the assumption that no significant
modification has been made in BODY. A change is considered
significant if it affects the buffer text in any way that isn't
completely restored again. Changes in text properties like `face' or
`syntax-table' are considered insignificant. This macro allows text
properties to be changed, even in a read-only buffer.
This macro should be placed around all calculations which set
\"insignificant\" text properties in a buffer, even when the buffer is
known to be writeable. That way, these text properties remain set
even if the user undoes the command which set them.
This macro should ALWAYS be placed around \"temporary\" internal buffer
changes \(like adding a newline to calculate a text-property then
deleting it again\), so that the user never sees them on his
`buffer-undo-list'. See also `c-tentative-buffer-changes'.
However, any user-visible changes to the buffer \(like auto-newlines\)
must not be within a `c-save-buffer-state', since the user then
wouldn't be able to undo them.
The return value is the value of the last form in BODY."
`(let* ((modified (buffer-modified-p)) (buffer-undo-list t)
(inhibit-read-only t) (inhibit-point-motion-hooks t)
before-change-functions after-change-functions
deactivate-mark
buffer-file-name buffer-file-truename ; Prevent primitives checking
; for file modification
,#varlist)
(unwind-protect
(progn ,#body)
(and (not modified)
(buffer-modified-p)
(set-buffer-modified-p nil)))))
Perhaps it is simply because they are considered a part of the string... (like the docs say). Remember, Emacs is buffer-centric, not file-centric, so the fact that the contents get saved out on disk is somewhat irrelevant (when thinking buffer-centric).
Also, the properties are undo-able, and that definitely fits with having the buffer marked as modified.
I don't know that there is a standard way of saving the buffer-modified state, but I do see one in the pabbrev.el library:
(defmacro pabbrev-save-buffer-modified-p (&rest body)
"Eval BODY without affected buffer modification status"
`(let ((buffer-modified (buffer-modified-p))
(buffer-undo-list t))
,#body
(set-buffer-modified-p buffer-modified)))
It doesn't protect against nonlocal exits, so perhaps you'd want to add a call to unwind-protect, like so:
(defmacro save-buffer-modified-p (&rest body)
"Eval BODY without affected buffer modification status"
`(let ((buffer-modified (buffer-modified-p))
(buffer-undo-list t))
(unwind-protect
,#body
(set-buffer-modified-p buffer-modified))))

How do you list the active minor modes in emacs?

How do you list the active minor modes in emacs?
C-h m or M-x describe-mode shows all the active minor modes (and major mode) and a brief description of each.
A list of all the minor mode commands is stored in the variable minor-mode-list. Finding out whether they're active or not is usually done by checking the variable of the same name. So you can do something like this:
(defun which-active-modes ()
"Give a message of which minor modes are enabled in the current buffer."
(interactive)
(let ((active-modes))
(mapc (lambda (mode) (condition-case nil
(if (and (symbolp mode) (symbol-value mode))
(add-to-list 'active-modes mode))
(error nil) ))
minor-mode-list)
(message "Active modes are %s" active-modes)))
Note: this only works for the current buffer (because the minor modes might be only enabled in certain buffers).
describe-mode can somehow come up with a list of enabled minor modes, why couldn't I? So after reading its source code I realized that it gets the list of active minor modes from both minor-mode-list and minor-mode-alist. Using 3rd-party dash.el list manipulation library I came with this code:
(--filter (and (boundp it) (symbol-value it)) minor-mode-list)
So, for example, to disable all minor modes, use -each:
(--each (--filter (and (boundp it) (symbol-value it)) minor-mode-list)
(funcall it -1))
Don't forget to save the list of minor modes in a variable, otherwise you would have to restart Emacs or enable them by memory.
If you want to programmatically do something with all buffers that have a certain mode active, then the best, most minimalistic, cleanest, built-in solution is as follows:
(dolist ($buf (buffer-list (current-buffer)))
(with-current-buffer $buf
(when some-buffer-local-minor-or-major-mode-variable-you-want-to-find
(message "x %s" $buf))))
It does the following:
Retrieve a list of all buffers via buffer-list, with the currently active buffer at the head of the list (so it's treated first, usually what you want, but leave out the current-buffer parameter if you don't care).
Loop through the buffer list and assign each buffer name to the variable $buf.
Use with-current-buffer $buf to tell Emacs that all code within the body should run as if it was running inside buffer $buf instead of whatever buffer you're really displaying on screen.
when <some mode variable> is the correct way to check if a mode is enabled; you can also use if and other such methods. Either way, the goal is to check if a minor or major-mode's main mode variable is set in the buffer. Almost all modes define a variable via "defining" a mode, which automatically causes them to create a buffer-local variable named after the mode, which is how this works. And if they don't have a standard variable, look at their own source code to see how their "toggle" code determines how to toggle them on and off. 99% of them use the existence of their modename's variable (and if they don't, I suggest reporting that as a bug to the mode's author). For example, to check if a buffer has whitespace-mode active, you would say when whitespace-mode.
After that, it just outputs a message to the Messages buffer, with an "x" and the name of the buffer that had the mode active. That's where you'd put your own code, to do whatever you wanted to do with the discovered buffer.
Enjoy! Onwards to greater and cleaner lisp code!
Here is a simple alternative snippet similar to some of the methods that have already been addressed in other answers:
(delq nil
(mapcar
(lambda (x)
(let ((car-x (car x)))
(when (and (symbolp car-x) (symbol-value car-x))
x)))
minor-mode-alist))
If you just want to know if a particular minor mode (say, evil-mode) is active in the buffer, you could evaluate the following:
(when (member 'evil-mode minor-mode-list)
(message "`evil-mode' is active!"))