Emacs-lisp hooks for detecting change of active buffer? - emacs

I am trying to execute when the active buffer has changed by either
Changing the buffer in the current window (e.g. C-x <left>).
Switching to another window (C-x o).
Switching to another frame.
Are their hooks suitable for detecting this?
What I figured out so far
Looking through the Standard Hooks I found the following options, none of which quite do what I want:
buffer-list-update-hook is called for both (1) and (2). It is however unsuitable, because it is run before the buffer is changed, while I want to know what the current-buffer after the change is.
window-configuration-change-hook can be used to detect a change of the buffer displayed in the current window, and it is run after the change, as needed. It is however not run for M-x other-window.
mouse-leave-buffer-hook seems viable for detecting mouse-based window switching, but it gets called a bit often (for me four times upon switching windows with the mouse, three times before and once after switching), which requires additional logical to prevent multiple execution.
post-command-hook would be viable but a bit heavy handed, risking significant slow-down of the editor by even minor bugs.
Since my action would need to use with-selected-window, which triggers these hooks, care has to be taken to avoid endless loops where the hook triggers itself.

Judging from the comments, the answer to this question is “No, there is no such hook.”
Additionally, some of the hooks mentioned in my question, are also triggered by changes, which are not user-visible, such as temporary changes due to with-current-buffer and with-selected-window.
However, using post-command-hook has proven to be a non-issue for performance, since the required state-check is cheap.
Alternative
Probably obvious, but stated for completeness.
Store state information in a global variable, in a frame-parameter, in a window-parameter or in a buffer-local variable, whichever is most applicable to the use-case. In my use-case, this necessary unique state is was defined by current-buffer, current-window, and in one case line-beginning-position.*
In post-command-hook, check if the state has changed, possibly skipping
even that, if this-command is self-insert-command.
If it has, perform the intended action and update the stored state.
* line-number-at-pos is unsuitable, because it counts lines by iterating over the buffer from point-min to point, making it generally cheap, but not cheap enough to be executed after every typed character.

Emacs27.1 introduce a new variable called `window-buffer-change-functions'

Related

How can a .emacs file be made idempotent?

No matter how many times I reload my .emacs file,
M-x load-file RET ~/.emacs RET
I want the results to be the same as the first time. I want to make my .emacs file be idempotent.
Motivation
I know I can surgically evaluate a region (C-c C-r), a defun (C-M-x), or the last sexp (C-x C-e). I often take such a more refined approach when making small changes. However, when re-working a .emacs file, I sometimes want to check results of the change conclusively by reloading the entire .emacs file. Restarting emacs each time gets old quick, especially when doing major .emacs housekeeping.
Specific Steps
What specific steps must I take to update my .emacs file to replace non-idempotent operations with idempotent ones?
For example,
Search for "-hook" and replace direct additions to hooks with calls to add-hook, which
will not re-add a function to the hook if already there.
Replace toggling of any flags with direct setting or clearing. Beware of ?? in particular.
...
A comprehensive check-and-correct list would be ideal, but any key individual checks that occur to you would be helpful as well.
I don't know as it's possible to ensure this completely, as most .emacs files depend on libraries which may not have idempotent initialization routines. However, there are a few useful tricks to reduce problems:
Use named functions for add-hook, and keybindings instead of anonymous functions. For add-hook in particular, this allows it to swap out the existing reference.
Careful use of defvar, by default the body is only evaluated if the variable is undefined. C-M-x on a defvar will re-eval the body, but eval-buffer will not if the variable is already initialized.
Careful use of (quote function) instead of function to reference a named function instead of the value of the function. See Anonymous Functions for more advanced discussion about this.
Remember that require will only load the corresponding library the first time it is executed, it will not re-eval on repeated calls as load does. Autoload also uses require to load the corresponding library.
Prefer add-to-list instead of cons to only add an element if it doesn't exist.
For older mode activation, make sure to use (mode-name-mode t) to activate instead of the toggle function. Likewise for turn-on- minor mode functions instead of the mode toggle.
Guard blocks that do have side effects if executed repeatedly. In particular for server mode, (unless (server-running-p) (server-start)), and similar guards for installing packages.
Being careful about side effects in eval-after-load or custom mode hooks. Remember the default mode hooks run when a mode is first enabled, and on each subsequent buffer, but will not rerun in existing buffers when the hook function is modified. eval-after-load is less likely to trip things up, it's still important to remember when it's evaluated.
Related to #2, makunbound may be useful if a chain of vars that depend on each other need to be re-evaluated, as it will force the defvar to always execute on evaluation of the file.
Running eval-buffer on an init file should be as idempotent as possible, but it's important to remember that emacs lisp is fond of side effects and state. While it's possible to ameliorate this to some extent, re-evaling init will never return emacs to the state it was when it first started.
Limit yourself to things you know are idempotent:
defun.
setq to a constant.
add-to-list with a constant.
add-hook, but preferably adding a symbol rather than a lambda expression.
enabling/disabling a minor mode.
wrapping some of the above in conditions.
Of course idempotent doesn't actually mean that the result is the same as re-starting (e.g. removing a setq and then re-evaluating your .emacs won't remove the effect of the previous setq), but the above is pretty much the principles I try to follow in my own ~/.emacs.
In addition to what others have said, load (e.g. require) libraries, including 3rd-party libraries, whose loading is idempotent.
Yes, to find that out for a given library you might need to either read the code or experiment. But nowadays libraries are supposed to be idempotent (or close to it), and many are.

How to perform auto-completion queries in background?

I'm very excited of emacs auto-completion mode. But my codebase is big, and sometimes, when i type, and it tries to ssuggest a completion, it searchs through all possible words, and hangs. It is very annoying.
Is there a way to run the search in background in parallel process, so emacs would still response to user actions. And only if the point holds on the place when the query is finished, suggest auto completion?
Like, the keyboard input is a primary process, and can never be delayed, and autocompletion works as a residual on machine resources.
emacs-jedi exactly does that for Python auto-completion. You can send a request to the background process using the init property and then store the result somewhere. In the candidate property, you can process the stored result to pass it to auto-complete. Here is the ac-source definition. Please look at the source for details.
(ac-define-source jedi-direct
'((candidates . jedi:ac-direct-matches)
(prefix . jedi:ac-direct-prefix)
(init . jedi:complete-request)
(requires . -1)))
emacs-ipython-notebook also uses similar technique but I guess emacs-jedi is easier to read.

Refining key-chord.el triggering

I do really like key-chord.el but I'd need it to only trigger when I start pressing keystrokes after a short delay during which I didn't do anything elapsed. I'd like to know if it's easy to modify key-chord.el to do that.
Why I want that is simple and I'll try to explain it as easily as I can:
I do want keychords to be assigned to keys that are on my "strong" fingers (no pinky) and that are on my home row (I do touch-type). Hence I'm potentially creating quite a few keychords which may clash with common words / code when I'm typing.
I realized that everytime there's a clash (i.e. keychords kicking in while I didn't want to) it's because I'm in the process of frenziedly modifying the buffer.
Here's an example...
I'm a fast typist so if I'm entering, say, "held", there is never going to be a long delay between when I add the 'e' of "held" and when I then type the 'l'. So in this case it should be "obvious" that I do not want key-chord to kick in when I type 'ld'. However if there's a pause and if 'ld' is an assigned key-chord and then I hit 'ld', then it is very unlikely that I'm writing code / text that would be starting with 'ld'. So in this later case (and because I have assigned 'ld' to a key-chord), I do want it to kick in.
Now don't get me wrong: I'm not sayin this would eliminate every single possible clash in every single case. All I'm saying is that, in my case, this would probably eliminate 99.9% of the (already rare) clashes. The "time lost" should one clash still occur after this change to key-chord would be negligible compared to the amount of time key-chord is making me gain.
The code to key-chord.el is very small so maybe such an addition wouldn't be too hard?
Does anyone have an idea as to how if it would be easy to modify key-chord.el to provide such a feature? (I hope I explained correctly what I want to do)
Here's the code to key-chord.el and half of it is comments:
http://emacswiki.org/emacs/key-chord.el
The Idle Timer mechanism should be able to facilitate this.
C-hig (elisp) Idle Timers RET
I'll leave it to you (or someone else) to figure out the details. Offhand thoughts are:
enable the Key Chord functionality via an idle timer
use post-command-hook to disable it again
That might be all that is needed?
I see two timings at play here
time before the chord (between the letter before the chord and the chord. If short enough, no chord)
time after the chord (if new letter quickly typed, no chord)
The second type of timing is probably more natural, and easy to get used to. If one type the chord, a short timeout before it executes can be accepted. (This is not what you asked for and would not solve the "ld" example. But it could potentially solve the problem with letter combinations that may appear in the beginning of words.)
The first type of timing is probably harder to get used to. When one have completed typing a word and the next thing is to type a chord, I suspect it is not a natural instinct to make a short pause. If one uses the chord often, one is likely to type it quickly, and get annoyed if it is not recognized (and the two chars are inserted into the text instead). What I want to say is, I am not sure a timing before the chord will solve the problem to a satisfactory degree.
As for the implementation of such a timing. The way the state machine in the key-chord-input-method function is currently structured, it would grow exponentially with the number of timers to consider (if I recall correctly). I.e. there would be at least about a dozen new lines of code.
To experiment with the functionality, try phils suggestion in the other answer: a post command that disables chords, and an idle timer that, after a fraction of a second, enables them again. A quick and dirty way to disable and enable chords, without actually changing minor mode, would be to set the input-method-function variable.
Code for test purpose only. It assumes, but does not check, that key-chord-mode version 0.5 is loaded and enabled:
;; Helper functions to be used in timers and hooks
(defun my-enable-chords () (setq input-method-function 'key-chord-input-method))
(defun my-disable-chords () (setq input-method-function nil))
;; Start test
(add-hook 'post-command-hook 'my-disable-chords)
(setq my-timer (run-with-idle-timer 0.3 'repeat 'my-enable-chords))
;; Finish test
(remove-hook 'post-command-hook 'my-disable-chords)
(cancel-timer my-timer)

In Emacs, what's the canonical way to protect vital buffers like *scratch* and *Messages* from ever being killed?

I was reading this question and the answers are a convoluted mess (timer function REALLY?)
In any case, I don't care about recreating these buffers, as that is trivial. But these buffers contain information which should never be deleted, and because they don't have associated filenames, they are usually killed without confirmation.
I do have a solution in mind, but I want to see if someone has a more "canonical" one.
jtahlborn provided the most canonical solution, except the "keep-buffers" package is showing its age has some issues:
You had to specify whether all protected buffers are to be buried and erased (erased buffers can be recovered with `undo') when killed, or just buried when killed.
member is reimplemented as find-in-list less efficiently.
Helper functions that didn't really help.
I made the the protected-list an alist that associates regexp to erase-action, and deleted the useless (IMO) code. By default, "scratch" is erased when killed, "Messages" is never erased or killed.
See github
You can try adding a function to the kill-buffer-query-functions variable that checks the current buffer, if it is scratch or Messages then return nil. I've never tried this before but it should prevent them from getting killed.
Edit: Here's an example of using kill-buffer-query-functions that allows you to protect specific buffers: http://www.emacswiki.org/emacs/protbuf-by-name.el
i use the keep-buffers utility.
In addition to what has been said by others --
*scratch* is in no way a "vital" buffer. And by default nothing and no one automatically writes anything to *scratch* or modifies anything there.
(FWIW, I tend to use an ordinary Emacs-Lisp mode file buffer instead of *scratch*. One reason is that I do typically want to save it at some point. (Another reason: I prefer that C-j do what it does in Emacs-Lisp mode. Yes, I could change just that key binding, but instead I keep *scratch* for some kinds of interaction, but typically not for a coding sandbox.)
*Messages* is a different story.
But how are you accidentally deleting *Messages*? In decades of using Emacs I don't think I've ever accidentally killed *Messages*. What's the scenario to produce the problem you are looking for a solution to?

How can I run an elisp function asynchronously?

for those who don't know, imenu is a thing in emacs that lets a mode insert one or more menu items into the menu bar. The most common usage is to make a "table of contents" accessible from a drop-down menu, so the user can quickly jump to declarations of functions or classes or sections in a document, etc.
imenu has a couple different ways of working - in the first and more commonly used way, a major mode provides regexps to imenu, and imenu uses those regexps to perform the scan of the buffer and build the index. A major mode sets this up by putting the list of regexps into imenu-generic-expression. The second way is for the major mode to perform its own scan. It can do this by instead setting the variable imenu-create-index-function to the name of a function defined by themode, which returns a list containing the table of contents.
I'm doing the latter - imenu-create-index-function - but sometimes the fn takes a looong time to run, say 3 or 4 seconds or more, which freezes the UI. If I make the operation asynchronous, that would solve that problem.
I know about asynch processes. The scan logic is implemented in elisp. Is it possible to run elisp in an asynch process? If so, how?
Or, is there a way to run regular elisp asynchronously in emacs, without resorting to an asynch process?
I think the way font-lock does it is, it fontifies on idle. It keeps state and fontifies a little at a time, always remembering where it left off, what else needs to be fontified, what has changed since the last fontification run, etc. Is my understanding correct? Maybe I could use this incremental approach .
Recommendations?
To run elisp asynchronously you can use either run-with-idle-timer or run-with-timer. I imagine you'll want the idle version. Check the documentation links for more details.
Note: If the code takes 3 or 4 seconds to run, it'll still take that long (and freeze your Emacs while it runs), so if you can break the work up into small enough chunks that it only takes .5 seconds or so at a time, that might work well.
One package that I use all the time, pabbrev.el, uses idle timers really well - I never notice it running. That might be a good package to examine to see how it breaks up the work (it is scanning all open buffers and building up a word frequency list).
The answers posted by TreyJackson and jeremiahd were valid back in year 2011. Now, in 2018, here is a link to the emacs documentation for asynchronous processes.
You can run elisp in an asynch process by spawning emacs in batch mode as the process, see http://www.emacswiki.org/emacs/BatchMode . Other than that, there's basically nothing as far as I know.
It looks like http://nschum.de/src/emacs/async-eval/ basically wraps the boilerplate necessary to do this. No clue if it's actively maintained or anything though.