1

I want to change a magic number (or a time stamp) in a file buffer on each save. The position of the magic number in the buffer can be given through a regex with a keyword or similar.

Is there any package for this? I tried auto-insert which comes with Emacs 26, but this seems to only update on file buffer creation, not on each save.

I preferably would like to enable this on a per-file basis through file local variables.

I tried a custom hack via before-save-hook, but struggled to add a function to this hook through afile variable declaration.

3

C-h f time-stamp:

time-stamp is an autoloaded interactive compiled Lisp function in
`time-stamp.el'.

(time-stamp)

  Probably introduced at or before Emacs version 19.31.

Update the time stamp string(s) in the buffer.
A template in a file can be automatically updated with a new time stamp
every time you save the file.  Add this line to your init file:
    (add-hook 'before-save-hook 'time-stamp)
or customize `before-save-hook' through Custom.

If you want to do this in the local variables section, you need to use the 'eval' functionality. e.g. assuming a .c file:

/* Local Variables: */
/* eval: (add-hook 'before-save-hook 'time-stamp 0 t) */
/* End: */

will cause the local value of before-save-hook to containg time-stamp.

  • This works, thanks. However I cannot figure out how to set add time-stamp to before-save-hook in the file-local variables at the end of the file. – halloleo Jun 28 '19 at 1:25
  • I'm not sure I understand what you're trying to do with file-local-variables. If you put the 'add-hook' in your init file, 'time-stamp' will run every time you save a buffer. For files which don't have a time-stamp template in the first 8 lines, nothing will be done, for files which do the time-stamp will be updated – rpluim Jun 28 '19 at 8:58
  • Sure, but that's exactly what I want to avoid: That all files with the time-stamp template are updated on save. Therfore I thought a buffer local before-save-hook set in the file-local variables would do the trick - but I cannot figure out how to add to hooks in the file-local variables... – halloleo Jun 28 '19 at 13:02
  • Cool, eval does the trick. Thanks! – halloleo Jun 30 '19 at 8:31
2

Easily done via a file-local variable save-count. The only drawback is that you cannot define the format of the magick number freely but you are bound to the format of file-local variables.

(defvar save-count nil
  "To be used as file-local variable.
Number of times the buffer file has been saved.")

(put 'save-count 'safe-local-variable #'numberp)

(defun start-save-count (&optional remove)
  "Start counting saves for the current buffer file."
  (interactive "P")
  (if remove
      (delete-file-local-variable 'save-count)
    (add-file-local-variable 'save-count 0))
  (normal-mode))

(defun update-save-count ()
  "Increment file local variable `save-count' if its value is a number."
  (when (numberp save-count)
    (cl-incf save-count)
    (save-excursion
      (add-file-local-variable 'save-count save-count))))


(add-hook 'before-save-hook #'update-save-count)

If you do not set the value of save-count to a number you do not get the counter.

That offers you several possibilities:

  • Preferred way: You can call M-x start-save-count. That command adds save-count to the list of file local variables in the current buffer. It also runs normal-mode for that variable to become effective.
  • You can just add a file local variable save-count with numeric value to your file. This will automatically be incremented on saves.
  • You can globally set save-count to a numeric value. In that case all buffers will get such a value on first save.
  • You can set the buffer-local value of save-count with (setq-local save-count 0). Then you get the save count just for that buffer file.
  • Thanks for chiming in, but I want to change a magic number given as characters in the buffer itself - and this number should be updated on every save. I don't need a variable with a number... – halloleo Jun 28 '19 at 14:06
  • @halloleo Have you really tried it? The value is stored as value of the file local variable in the file! That is a character sequence in the file! – Tobias Jun 28 '19 at 14:08
  • @halloleo I have added a command start-save-count to ease the application. Just open any text file where you want to start counting the saves and call M-x start-save-count. Everything other will work automatically. – Tobias Jun 28 '19 at 14:23
  • @halloleo Note, the motivation for my answer was 1st: the word increase in the title of the question and 2nd: the phrase magic number in the text before you added "(or a time-stamp)". – Tobias Jun 28 '19 at 16:09
  • Sorry, Tobias, I hadn't tried it. Now I have and indeed it increments the value text of the variable in the buffer. Pretty nifty! – halloleo Jun 30 '19 at 3:24

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.