How can a .emacs file be made idempotent? - emacs

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.

Related

Portacle Lisp : Slime-repl-sbcl prompt keep auto-scrolling back

as the title said, I am learning common lisp right now and using portacle, following Practical Common Lisp by Peter Seibel.
I found it quite annoying that the Slime-repl-sbcl buffer keep the writing at the end of the screen (using C-l or C-v doesn't help since once I try to execute an expression it will roll back to the end of the screen)
Is there anywhere to improve this? (should I just write on a text file and compile it? the only similar subject I found was about Cider repl and couldn't understand it, since I am still new to lisp)
Thank you for your time
I would like this fixed too. No solution yet. In slime-repl.el, I found:
scroll-conservatively (variable):
A value of zero means always recenter point if it moves off screen.
my test wasn't conclusive.
slime-display-output-buffer (function), which calls slime-repl-show-maximum-output, which role is to
Put the end of the buffer at the bottom of the window.
I rewrote slime-display-output-buffer without this call, but that wasn't conclusive either.
Maybe I tested badly.
(I'm making this answer a wiki)
You would indeed typically write in a source file, and compile each expression separately. Use the REPL only to test functions or do simple computations. To compile functions (or really, any toplevel expression), use C-c C-c - bound to slime-compile-defun by default - when the point (= your cursor) is inside the function's code. The REPL will then "know" of it, so you can test it there, but as it is now written in file, you can also modify it without having to copy/paste anything ! Just make sure to recompile functions that you modify !
If you want to compile/load entire files at once, look at the other compilation commands, e.g. slime-compile-and-load-file (see the SLIME manual, and its Compilation section)
For your problem: there is Emacs variable, named comint-scroll-to-bottom-on-input (or something along those lines, can't remember exactly ...) which enables the behaviour you are seeing, so that you don't have to scroll back to enter new expressions. It is possible that SLIME has another variable which configuring this behaviour for its REPL; in that case, it would probably be named almost the same, and you can set it to nil to disable it.
Finally, don't hesitate to look at the other tools provided by SLIME ! For example, it comes with an "inspector" (see the relevant section), that you can use instead of evaluating expressions such as *db* in the REPL. In that simple case, it makes no real difference, but if you start having - say - hash-tables or different structures/classes, it becomes an incredible tool for interactive development, to examine the internal of almost everything, redefine things directly from within the inspector without needing complex accessors, and so on.

Emacs-lisp hooks for detecting change of active buffer?

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'

Is it possible to turn off the enforced vertical alignment in clojure-mode?

I'm using Emacs 25.1, with the latest stable release of clojure-mode. When clojure-mode (not in other major modes like js2-mode) is turned on, everything is strictly aligned, no extra whitespace is allowed before any forms. For example,
(def
last (fn ^:static last [x]
(if (next x)
(recur (next x))
(first x))))
I can't insert a space (automatically removed after insertion) before the first non-whitespace character on each line. This kind of behavior is just not desirable to me. I tried changing the variables in the Clojure group, but nothing seemed to work. How can I turn this behavior off?
It isn't exactly clear what you mean, but I suspect you are referring to the way
Clojure will align forms in things like let bindings so that all the symbols and
values being bound are aligned i.e.
(let [a-val1 (something-1)
another-val (something-2)
final-col 12]
(do-some-stuff))
rather than
(let [a-val1 (something-1)
another val (something-2)
final-col 12]
(do-some-stuff))
If this is the case, then there are a few things you can try.
Look at the variable clojure-align-forms-automatically
clojure-align-forms-automatically is a variable defined in
‘clojure-mode.el’. Its value is t Original value was nil
This variable is safe as a file local variable if its value
satisfies the predicate ‘booleanp’.
Documentation: If non-nil, vertically align some forms automatically.
Automatically means it is done as part of indenting code. This
applies to binding forms (‘clojure-align-binding-forms’), to cond
forms (‘clojure-align-cond-forms’) and to map literals. For instance,
selecting a map a hitting ‘M-x indent-for-tab-command’ will align the
values like this:
{:some-key 10
:key2 20}
You can customize this variable.
This variable was introduced, or its default value was changed, in
version 5.1 of the clojure-mode package.
The other variable which you might want to look at is clojure-indent-style
clojure-indent-style is a variable defined in ‘clojure-mode.el’. Its
value is ‘:always-align’
This variable is safe as a file local variable if its value
satisfies the predicate ‘keywordp’.
Documentation: Indentation style to use for function forms and macro
forms. There are two cases of interest configured by this variable.
Case (A) is when at least one function argument is on the same line as the function name.
Case (B) is the opposite (no arguments are on the same line as the function name). Note that the body of macros is not affected by
this variable, it is always indented by ‘lisp-body-indent’ (default
2) spaces.
Note that this variable configures the indentation of function forms
(and function-like macros), it does not affect macros that already use
special indentation rules.
The possible values for this variable are keywords indicating how to
indent function forms.
‘:always-align’ - Follow the same rules as ‘lisp-mode’. All
args are vertically aligned with the first arg in case (A),
and vertically aligned with the function name in case (B).
For instance:
(reduce merge
some-coll)
(reduce
merge
some-coll)
‘:always-indent’ - All args are indented like a macro body.
(reduce merge
some-coll)
(reduce
merge
some-coll)
‘:align-arguments’ - Case (A) is indented like ‘lisp’, and
case (B) is indented like a macro body.
(reduce merge
some-coll)
(reduce
merge
some-coll)
You can customize this variable.
This variable was introduced, or its default value was changed, in
version 5.2.0 of the clojure-mode package.
There are some other alignment/indentation variables which you may also want to
check out - try M-x customize-group clojure-mode and M-x customize-group
cider to browse and see if anything is relevant. You might also find
something relevant on the cider documentation site. In particular, look at the
manual section on indentation
UPDATE EDIT: Based on additional information from the OP communicated in comments, I
decided to edit and extend this answer. I've left the original response as I
feel it may be useful to others who search and find the OPs question. However,
with the additional info in the comments, I don't think the answer addresses the
OPs actual issue, so have extended the answer below which I hope will help.
Some Emacs modes are more rigid or enforce code format more strictly than
others. This is particularly the case with vary regular languages like Clojure
(and most lisps generally) whee the syntax is minimal and the rules regarding
code indentation are easier to define and tend to have wide consensus.
The situation for the OP is further complicated because they are using a
pre-defined Emacs configuration - in this case Steve Purcell's emacs.d,
which is one of my favourite pre-defined or canned Emacs configurations. The
one drawback with these pre-defined configurations is that they will turn on and
define many optional features of the Emacs editor which may or may not be
in-line with user personal preferences. Emacs tends to have a vary conservative
position when it comes to new features or enhancements. Often, they are disabled
by default to avoid impacting new users. The cost for this conservative approach
is that over time, Emacs can seem primitive or less feature rich compared to
other editors to new users who expect some of this behaviour to be enabled by
default. By using a canned configuration, you get one person's preferred setup
without having to go through the often long and difficult process of doing it
yourself. The downside is that when it does not match with the user's
expectations, the user does not have the knowledge or understanding to make the
changes and it is difficult to get help because others don't know/understand
what their configuration is already.
As an example how using these pre-defined setups can complicated matters, when I
last looked at the Purcell configuration, it used the ELPA package
aggressive-indent, which enforces more rigid indentation rules and it could
well be this package rather than clojure-mode which is enforcing the rigid
indentation rule.
The OP mentions they are concerned regarding this auto-formatting as it could
cause problems when contributing to other projects and issues with
auto-formatting making the code look like there has been more changes than has
actually occurred due to the version control picking up the whitespace
adjustments. This issue mainly comes up over differences due to the use of tabs
and spaces. to a large extent, such issues are less frequent these days as most
version control systems can be configured to ignore whitespace changes.
In this case, my recommendation is to do nothing for now as there isn't a real
issue yet. Continue to use the canned configuration and continue to ask
questions, but also spend some time trying to learn and understand the
configuration. At some point, once your comfortable with Emacs, you will likely
want to re-configure the system to better meet your own personal taste. By this
time, you will have a better understanding of Emacs, the various options it has
and the way different modes work. When you run into specific real issues which
you cannot solve, then post another question. It is likely at that point, you
will have concrete information and someone will be able to provide specific
help.

Design pattern on mutually dependent .el files

As a package size grows, the readability of the code decreased. The best practice is to separate the package into different files according to their functions. Sometimes, the files need variables and functions of each other.
Example:
foo.el
(defvar foo-data-path "~/foo/data/")
(foo-log-write 'somedata)
foo-log.el
(defvar foo-logfile (concat foo-data-path "foo.log"))
(defun foo-log-write (data)
;; Write to log file
)
As foo.el use function from foo-log-write, I put (require 'foo-log) in foo.el.
In foo-log.el, it uses foo-data-path from foo.el, should I also put (require 'foo) in it?
The syntax checker always complains reference to free variable if I don't add (require 'foo).
There are two techniques I've seen to handle the situation you describe. It should be noted that you can get into a circular dependency problem is your not careful. While you can have require in a file multiple times, if they are mutually dependent and if your 'provide lines are at the end, you can easily end up in a loop.
The two solutions I've used successfully are
(Preferred). Factor out the mutually dependent code into a 3rd file and have the other two require that file.
When all else fails and you cannot factor things out and cannot avoid the mutual dependency, make sure that at least one of the files has the provide statement at the beginning. This is not normally a good idea because if your file errors out before it finishes loading, you will appear to have satisfied the require, but not everything you expect to have been loaded will be.
The second technique helps break the infinite loop because you have satisfied one of the provide requirements. The problem with having the provide at the end of the file (where it normally should be) is that you do not satisfy the require request until the file has been fully loaded. However, if the file has a require for another file, it will first load that file before continuing to load the first file. If that second file also has a require and that require is to the first file, emacs will start loading the first file again until it hits the require for the second file and around the loop we go.
by putting the provide at the beginning of the file, the next time it hits a require for that file it will not try to load it as it will believe it has already been loaded. the loop is broken.

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?