The variable mode-name
is freea buffer-local variable that is also bound inside your lambdafunction sandric/kill-buffers-by-major-mode
. Under dynamic scoping, it appearsthat means that the relevant value is destroyed whenof mode-name
seen by your initially current buffer is killed, and subsequentcode will change when you change buffers use the value of the global variable of the same name. My guess is that(in this weird interaction is probably because that variable iscase, when you kill the current buffer-local). See the warning here about let
bindings; it also applies to function arguments.
Whatever the exact cause, thisThis problem goes away if lambda is a proper closure; i.e.,for me if you define the function in ais defined using lexical scope, but according to lexically-scoped filethe manual. To do that, just put
-*- lexical-binding: t; -*-
anywhere on the first line of the file.
If you'd prefer not to do that, you could instead usethis is undefined behavior and using a special variable such as evalmode-name
to define just this oneas a function lexically, like this:argument is discouraged.
(eval
'(defun sandric/kill-buffers-by-major-mode (mode-name)
"Kill open buffers by major mode name"
(interactive)
(mapc (lambda (buffer)
(when (eq mode-name (buffer-local-value 'major-mode buffer))
(kill-buffer buffer)))
(buffer-list)))
:lexical)
Or you could simplySo the correct solution is just to change the name of your function argument from mode-name
to a different nameanother symbol that is unlikelynot defined as buffer-local.
(Thanks to already beTobias for explaining the details of the problematic interaction in usethe comments; my previous explanation was very sketchy, and I made some unfounded assumptions about what was causing the problem.)