How do you list the active minor modes in emacs? - 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!"))

Related

How to make `C-x b RET` switch to previous buffer even if it's already shown in another frame?

Edit: What the poster calls a "window", Emacs calls a "frame". I fixed the title.
Concisely, the question is: in a window, how do I switch quickly to a buffer previously visited in that window, even if it's already opened in another window?
A more detailed description follows.
Normally, in order to switch window to previous buffer one just types C-x b RET. That is, the default argument to switch-to-buffer (or ido-switch-buffer) is the previous buffer.
This is not, however, the case when that (previous) buffer is already shown in another window. That's exactly what bugs me.
Let's consider an example. Suppose I have three buffers (A, B and C) and two windows showing buffers A and B (C is not visible at this point).
Then I open buffer A in the second window, too. So, now I have buffer A shown in both windows. Then I switch (C-x b RET) to B again. After that, C-x b RET will bring me not to A, but to C because A is already shown in the other window.
How do I make C-x b RET behave more consistently?
Update
After this problem had been solved, I realized I needed more: namely, for point position to be remembered per-window, not per buffer. Luckily, there're ready-made solutions:
winpoint
per-window-point
They're quite similar; for a discussion of differences see here.
I've found a fix for switch-to-buffer. It eventually calls
(other-buffer (current-buffer))
while in order to fix your problem, the call needs to look like this:
(other-buffer (current-buffer) t)
i.e. the visible-ok argument needs to be t.
Here's an advice to have it always at t. Hopefully it won't break other stuff that uses other-buffer:
(defadvice other-buffer (around fix-switch-to-buffer
(&optional buffer visible-ok frame) activate)
(setq visible-ok t)
ad-do-it)
Note that ido-switch-to-buffer uses a different machinery, so a different method is needed to fix it.
update: fix for ido-switch-to-buffer
I needed to re-define ido-make-buffer-list:
(defun ido-make-buffer-list (default)
(let* ((ido-current-buffers (list (buffer-name (current-buffer))))
(ido-temp-list (ido-make-buffer-list-1 (selected-frame) ido-current-buffers)))
(if ido-temp-list
(nconc ido-temp-list ido-current-buffers)
(setq ido-temp-list ido-current-buffers))
(if default
(setq ido-temp-list
(cons default (delete default ido-temp-list))))
(if (bound-and-true-p ido-enable-virtual-buffers)
(ido-add-virtual-buffers-to-list))
(run-hooks 'ido-make-buffer-list-hook)
ido-temp-list))
The diff is just one line, but it's too messy to advice it.
update: use new advice system for other-buffer
The old stuff should still work for quite a while, but here's the new approach:
(defun other-buffer-advice (orig-fun &optional buffer visible-ok frame)
(funcall orig-fun buffer t frame))
(advice-add 'other-buffer :around #'other-buffer-advice)
;; (advice-remove 'other-buffer :around #'other-buffer-advice)
Instead of advising the built-in function other-buffer, you can pre-select visible buffers using a package.
1 Using Ivy
If you're using Ivy, you can use abo-abo's approach to override the lower-use function ivy-switch-buffer.
(defun user/ivy-switch-buffer ()
"Switch to another buffer with visible-ok preselection."
(interactive)
(ivy-read "Switch to buffer: " #'internal-complete-buffer
:keymap ivy-switch-buffer-map
:preselect (buffer-name (other-buffer (current-buffer) t))
:action #'ivy--switch-buffer-action
:matcher #'ivy--switch-buffer-matcher
:caller 'ivy-switch-buffer))
(advice-add 'ivy-switch-buffer :override #'user/ivy-switch-buffer)
2 Using Ido mode
2.1 Switching to a buffer shown in another frame
If by "window" you really mean "frame" (i.e., you'd like to ido-switch-buffer to a buffer that is currently shown in another frame), then ido-mode gives you the behavior you're looking for when you change ido-default-buffer-method from its default value of raise-frame to selected-window:
(setq ido-default-buffer-method 'selected-window)
Emacs constructs an independent buffer list for each frame, so the only thing you have to do is to configure Ido to avoid jumping to another frame when you switch buffers.
2.2 Switching to a buffer that is shown in another window inside the same frame
To get this behavior across windows within the same frame, you should hook a function that reorders the buffer list onto ido-make-buffer-list-hook.
From ido.el:
;; Changing the list of files
;; --------------------------
;; By default, the list of current files is most recent first,
;; oldest last, with the exception that the files visible in the
;; current frame are put at the end of the list. A hook exists to
;; allow other functions to order the list. For example, if you add:
;;
;; (add-hook 'ido-make-buffer-list-hook 'ido-summary-buffers-to-end)
;;
;; then all files matching "Summary" are moved to the end of the
;; list. (I find this handy for keeping the INBOX Summary and so on
;; out of the way.) It also moves files matching "output\*$" to the
;; end of the list (these are created by AUCTeX when compiling.)
;; Other functions could be made available which alter the list of
;; matching files (either deleting or rearranging elements.)

How to make region transient in elisp when in transient-mark-mode

I wrote an elisp macro that preserves the region when in transient-mark-mode:
(defmacro keep-region (command)
"Wrap command in code that saves and restores the region"
(letrec ((command-name (symbol-name command))
(advice-name (concat command-name "-keep-region")))
`(progn
(defadvice ,command (around ,(intern advice-name))
(let (deactivate-mark)
(save-excursion
ad-do-it)))
(ad-activate (quote ,command)))))
(keep-region replace-string)
(keep-region replace-regexp)
This preserves the region for commands that are advised using the keep-region macro; very helpful when you want to make multiple replacements in a selected block.
The problem is that after running a command that has been advised using this macro, the region loses its transient nature; subsequent movement commands extend the region, rather than deselecting it.
How can I programmatically re-enable the transience of the marked region?
From C-h f transient-mark-mode:
Transient Mark mode is a global minor mode. When enabled, the
region is highlighted whenever the mark is active. The mark is
"deactivated" by changing the buffer, and after certain other
operations that set the mark but whose main purpose is something
else--for example, incremental search, <, and >.
Hence, activate-mark after exchange-point-and-mark should restore the transient nature of the mark.
I am not sure, though, why you are using exchange-point-and-mark here, and why you are calling it twice. In my opinion, just saving (point) and (mark) in a let-binding and restoring them after ad-do-it would be easier. push-mark and pop-mark might help as well, since the latter automatically reactivates the mark anyway.
The problem is that after running a command that has been advised using this macro, the region loses its transient nature; subsequent movement commands extend the region, rather than deselecting it.
You should rather talk about "shift-selected nature": movement commands extending the region is what happens when the mark is activated in the "normal" way.
The shift-select status is stored inside the transient-mark-mode variable, and is modified by someone (handle-shift-selection?) who doesn't care about the value of deactivate-mark. We can get around this by saving the value of transient-mark-mode:
(defmacro keep-region (command)
"Wrap command in code that saves and restores the region"
(letrec ((command-name (symbol-name command))
(advice-name (concat command-name "-keep-region")))
`(progn
(defadvice ,command (around ,(intern advice-name))
(let ((deactivate-mark nil)
(transient-mark-mode transient-mark-mode))
(save-excursion
ad-do-it)))
(ad-activate (quote ,command)))))
transient-mark-mode is a variable defined in `buffer.c'.
...
Lisp programs may give this variable certain special values:
...
A value of (only . OLDVAL) enables Transient Mark mode temporarily. After any subsequent point motion command that is not
shift-translated, or any other action that would normally deactivate
the mark (e.g. buffer modification), the value of
`transient-mark-mode' is set to OLDVAL.
Just remove your calls to exchange-point-and-mark. The preservation is done by the deactive-mark let-binding anyway.

Preserving buffer-face-mode when switching major-modes

Once in a while I manually set the font-family and size different from the default, and I use buffer-face-mode to do it. (To be exact I use the mouse & pick one from the dialog box.) Once I set it, I'd like it to stay set for that buffer, even if I change modes, so I tried a customization. The idea was to add a change-major-mode-hook (which runs just before buffer-locals get killed) that would save the buffer face, if it is set, in a function to be called later- that much seems to work. But then that function seems to be called too soon, and when the mode change is over, buffer-face-mode is not active.
Here's the customization I cam up with so far
(defun my-preserve-bufface-cmmh ()
"Keep the state of buffer-face-mode between major-mode changes"
(if (and (local-variable-p 'buffer-face-mode) buffer-face-mode)
(delay-mode-hooks
(message "face is %s" buffer-face-mode-face) ; Just to show me it has the right face
(let ((my-inner-face buffer-face-mode-face))
(run-mode-hooks
(message "inner %s" my-inner-face) ; it still has the right face here
(setq buffer-face-mode-face my-inner-face)
(buffer-face-mode))))))
(add-hook 'change-major-mode-hook
'my-preserve-bufface-cmmh)
The messages both run and show a custom face, as they should, when I'm changing major-mode in a buffer with the minor-mode buffer-face-mode set. I had thought the combination of delay-mode-hooks ... run-mode-hooks would make setq buffer-face-mode-face ... (buffer-face-mode) run after the new mode was set up, but apparently not.
Is this customization "close"/salvageable for my wants? Is there a cleaner way?
The first thing is that delayed-mode-hooks is itself a local variable.
That means, if you set it by (delay-mode-hooks (run-mode-hooks ...)) in change-major-mode-hook
this will have no effect since it is killed instantaneously.
The second thing is that the stuff within your run-mode-hooks is
evaluated within my-preserve-bufface-cmmh. It should be defined as a back-quoted hook function
`(lambda () ...) where you splice in the values you want to keep.
The alternative would be to use lexical binding (which google).
The 2nd thing is demonstrated in the following example (to be evaluated step-by-step):
(defun test (str)
(let ((mytest (concat "hello " str)))
(add-hook 'my-own-hook `(lambda () (message "mytest:%S" ,mytest)))))
(test "you")
(run-hooks 'my-own-hook)
(test "world")
(run-hooks 'my-own-hook)
(put :myface 'test)
If you want to keep the font buffer-local you have to use a local variable that survives kill-all-local-variables such as buffer-file-name. You can hook a property there:
Edit: Even if the symbol has a buffer local value its properties are not buffer local. Thus, the previous approach did not work. Better: Create your own permanent buffer-local variable:
(defvar-local my-preserve-bufface nil
"Keep the state of buffer-face-mode between major-mode changes")
(put 'my-preserve-bufface 'permanent-local t)
(defun my-preserve-bufface-put ()
"Keep the state of buffer-face-mode between major-mode changes"
(and (local-variable-p 'buffer-face-mode)
buffer-face-mode
(setq my-preserve-bufface buffer-face-mode-face)))
(defun my-preserve-bufface-get ()
"Keep the state of buffer-face-mode between major-mode changes"
(and my-preserve-bufface
(setq buffer-face-mode-face my-preserve-bufface)
(buffer-face-mode)))
(add-hook 'change-major-mode-hook 'my-preserve-bufface-put)
(add-hook 'after-change-major-mode-hook 'my-preserve-bufface-get)
Thanks for the educational comments and especially the answer/example from #user2708138, which I am going to accept because it does answer the question.
Yet I am also going to answer my own question, since I did come up with working code that is a more general solution. I went down this path after finding I also wanted my font-size changes maintained and that they were from text-scale-mode, one more minor-mode to keep. This code reads a list of minor-modes to preserve, without my having to figure out which variables they use. (It isn't too hard for a human to figure them out, but I wanted to try having emacs do it).
Alas there is no function I know of to retrieve the variables used by a minor-mode, but the modes I'm interested in use the convention minor-mode-var-name, so this code just filters buffer-local variables for that pattern.
; Save & restore minor modes I wish to be "permanent" if set
(setq my-preserve-minor-modes '(buffer-face-mode text-scale-mode))
(defun my-preserve-minor-modes-cmmh ()
"Keep the state of desired-permanent minor modes between major-mode changes. Assumes that associated buffer-local minor-mode variables to save begin with `minor-mode-'"
(setq my-restore-minor-modes-acmmh nil)
(dolist (mm my-preserve-minor-modes)
(when (and (local-variable-p mm) (symbol-value mm))
(push mm my-restore-minor-modes-acmmh)))
(when my-restore-minor-modes-acmmh
(add-hook 'after-change-major-mode-hook 'my-restore-minor-modes-acmmh)
; Predicate-list showing if symbol starts with a preserved mode
(let ((mm-p-l `(lambda (locvar-nm)
(or ,#(mapcar (lambda (mm)
`(and (< ,(length (symbol-name mm))
(length locvar-nm))
(string-prefix-p ,(symbol-name mm)
locvar-nm)))
my-restore-minor-modes-acmmh)))))
; For each found minor mode, create fn to restore its buf-local variables
(dolist (locvar (buffer-local-variables))
(if (and (listp locvar) (funcall mm-p-l (symbol-name (car locvar))))
(push `(lambda()(setq ,(car locvar) ',(cdr locvar)))
my-restore-minor-modes-acmmh))))))
(defun my-restore-minor-modes-acmmh ()
"After major-mode change, restore minor-mode state, and remove self from hook. It restores state by calling the function stored in the variable my-restore-minor-modes-acmmh."
(remove-hook 'after-change-major-mode-hook 'my-restore-minor-modes-acmmh)
(dolist (restore-f my-restore-minor-modes-acmmh) (funcall restore-f)))
(add-hook 'change-major-mode-hook 'my-preserve-minor-modes-cmmh)
I did know about the permanent-local property but I wasn't sure about any unwanted side-effects... probably unwarranted paranoia on my part!
My answer could be improved if there is ever a way to get a list of variables for a minor mode, or by having the user specify an alist of variables per minor mode- in either case we wouldn't have to loop over buffer-local-variables anymore, and maybe simply making those all permanent-local would be all we need, simplifying the code quite a bit. Anyway, figuring all this out (with your help & looking at the fine manual) was quite educational.

Emacs make ibuffer filter per frame

I use ibuffer as well as have opened several frames. The very frequent use-case of mine for ibuffer is to filter the list (C-x C-b) of buffers by name/filename. The catch is that filter works in the same way for all frame (it is predicted I believe). I'd want to have to apply filter for ibuffer listing per each frame I have.
E.g. in a first frame I'd like to see list of buffers filtered by a filename, in a second one filtered by mode.
Looking around ibuffer.el I have discovered an entity called ibuffer-filtering-qualifiers which holds an associative list of currently applied filters. I have tried played:
(let ((ibuffer-filtering-qualifiers '())) ;;; Imitate that there are no filters applied
(call-interactively 'ibuffer))
But this was not worked for me.
Could you please point me out how to achieve such desired behavior of ibuffer?
The function ibuffer-update uses the buffer-list, which includes all frames. Modifying ibuffer-update from using buffer-list to (frame-parameter (selected-frame) 'buffer-list) approaches the behavior you are seeking. An ibuffer filter based upon that same concept should also be possible.
In my opinion, the per frame buffer list (frame-parameter (selected-frame) 'buffer-list) is not the best method to associate buffers with frames because it gets modified too easily. The best method I have seen is frame-bufs by Al Parker:  https://github.com/alpaker/Frame-Bufs  This has been updated to work with a current version of Emacs, however, I am using a slightly modified version to suit my own needs.
So, the easiest method that I am aware to answer your question is to use a combination of frame-bufs by Al Parker, and use the frame-bufs-buffer-list within ibuffer-update. That gives you the best of both worlds. Here is an example that will give you a nice ibuffer with only the buffers associated with a given frame -- all other buffers will not be displayed. [FYI:  frame-bufs also sorts by mode or by file name.]
(require 'ibuffer)
(defalias 'ibuffer-update 'lawlist-ibuffer-update)
(defun lawlist-ibuffer-update (arg &optional silent)
"Regenerate the list of all buffers.
Prefix arg non-nil means to toggle whether buffers that match
`ibuffer-maybe-show-predicates' should be displayed.
If optional arg SILENT is non-nil, do not display progress messages."
(interactive "P")
(if arg
(setq ibuffer-display-maybe-show-predicates
(not ibuffer-display-maybe-show-predicates)))
(ibuffer-forward-line 0)
;; (let* ((bufs (buffer-list))
(let* ((bufs (frame-parameter (selected-frame) 'frame-bufs-buffer-list))
(blist (ibuffer-filter-buffers
(current-buffer)
(if (and
(cadr bufs)
(eq ibuffer-always-show-last-buffer
:nomini)
(minibufferp (cadr bufs)))
(cl-caddr bufs)
(cadr bufs))
(ibuffer-current-buffers-with-marks bufs)
ibuffer-display-maybe-show-predicates)))
(and (null blist)
(featurep 'ibuf-ext)
ibuffer-filtering-qualifiers
(message "No buffers! (note: filtering in effect)"))
(unless silent
(message "Updating buffer list..."))
(ibuffer-redisplay-engine blist arg)
(unless silent
(message "Updating buffer list...done")))
(if (eq ibuffer-shrink-to-minimum-size 'onewindow)
(ibuffer-shrink-to-fit t)
(when ibuffer-shrink-to-minimum-size
(ibuffer-shrink-to-fit)))
(ibuffer-forward-line 0)
;; I tried to update this automatically from the mode-line-process format,
;; but changing nil-ness of header-line-format while computing
;; mode-line-format is asking a bit too much it seems. --Stef
(setq header-line-format
(and ibuffer-use-header-line
ibuffer-filtering-qualifiers
ibuffer-header-line-format)))
The issue you have is not that the ibuffer works in the same way for all frames. The issue is that the ibuffer buffer is the same for all the frames (each frame has a separate window (with its cursor) showing your ibuffer unique instance).
A simple solution is to clone the ibuffer buffer (M-x clone-buffer). And that is: you have two different buffers and you can apply filters to them independently.

Dedicated misc buffer in Emacs (autocomplete, function info etc.)

I have been wondering for a very long time now: how to get a dedicated misc buffer in Emacs?
Auto-completion, function descriptions and perhaps documentation all can go there without ending up somewhere unexpected, but instead at a predefined location (a quarter of the screen perhaps?).
(I'm assuming you mean a dedicated window instead of a dedicated buffer.) If you keep a window open without doing any other window-splitting commands, help/repl buffers will automatically use it. You can change the size of the window as described in this question.
If you want to do be able to do normal window manipulation but have help windows be a certain size, I suggest you investigate temp-buffer-show-hook, a hook that is run when temporary buffers (such as help buffers) are shown. I haven't tried it, but it would probably be possible to set it to a function that arranges your window configuration in a particular way.
Here is what I do in One On One, to define a dedicated *Help* frame:
;; *Help* frame
(if 1on1-*Help*-frame-flag
(add-to-list
'special-display-buffer-names
(list "*Help*" '1on1-display-*Help*-frame
(list (cons 'background-color 1on1-help-frame-background)
(cons 'mouse-color 1on1-help-frame-mouse+cursor-color)
(cons 'cursor-color 1on1-help-frame-mouse+cursor-color)
'(height . 40))))
(setq special-display-buffer-names
(1on1-remove-if (lambda (elt) (equal "*Help*" (car elt)))
special-display-buffer-names)))
(defun 1on1-display-*Help*-frame (buf &optional args)
"Display *Help* buffer in its own frame.
`special-display-function' is used to do the actual displaying.
BUF and ARGS are the arguments to `special-display-function'."
(let ((old-ptr-shape (and (boundp 'x-pointer-shape) x-pointer-shape))
return-window)
(when (boundp 'x-pointer-xterm) (setq x-pointer-shape x-pointer-xterm))
(setq return-window (select-window (funcall special-display-function buf args)))
(raise-frame)
(setq x-pointer-shape old-ptr-shape)
return-window))
You don't need all of those details (pointer shapes etc.), but that gives you the idea. The main thing is to put *Help* on special-display-buffer-names. That's really all you need to do.
The 1on1-* variables used for the frame parameters here are pretty obvious. The *-remove-if function is a standard remove-if. The complete code is here: oneonone.el.