0

Subtract a buffer's (the file's) size from a variable before killing it. Emacs 26.

(defvar cumulative-open-bytes '0 )

(defun buffer-settings-calc-bytes ()
  (interactive)
  (let ((current-open-file-size (file-attribute-size (file-attributes buffer-file-name))))
    (setq cumulative-open-bytes (- current-open-file-size cumulative-open-bytes))
    (message (propertize (format "Cumulative Open Bytes: (%d) after closing %s (%d bytes)." 
                                  cumulative-open-bytes buffer-file-name current-open-file-size) 
                         'face 'warning))))

(add-hook 'kill-buffer-hook 'buffer-settings-calc-bytes)

Results in the following message:
setq: Wrong type argument: number-or-marker-p, nil
This appears just after the string message from the function.

I have tried setq in place of the let, and removing interactive. Emacs will not load with the above, and evaluating it in place breaks most navigation and buffer features.

Notably toggle-debug-on-error.

The following also appears invoking arbitrary commands in addition to the above:
Error running timer: (wrong-type-argument number-or-marker-p nil)

Is this a local binding issue? How should this hook be set?

  • Um, where do you get file-attribute-size from? This isn't defined here on Emacs 25.1. – wasamasa Feb 17 '17 at 8:29
  • Emacs 26.0.50.1 – Austin Feb 17 '17 at 21:01
1

What happens here is that you try to use a non-number when subtracting numbers, more specifically nil. Your code assumes buffer-file-name always returns a file name pointing to a file you can query the attributes from which is wrong, buffers don't have to point at files and can return nil in this case. Your hook must handle this case to not error out prematurely:

(defvar my-cumulative-open-bytes 0)

(defun my-buffer-settings-calc-bytes ()
  (let ((size (nth 7 (file-attributes buffer-file-name))))
    (when size
      (setq my-cumulative-open-bytes (- size my-cumulative-open-bytes))
      (message
       (propertize
        (format "Cumulative Open Bytes: (%d) after closing %s (%d bytes)."
                my-cumulative-open-bytes buffer-file-name size)
        'face 'warning)))))

(add-hook 'kill-buffer-hook 'my-buffer-settings-calc-bytes)

PS: This hook might slow down your Emacs as it's run when every single temporary buffer is killed, so consider achieving your goal in a different way.

  • That's a really good point. I appreciate the insight. – Austin Feb 17 '17 at 21:03

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.