How to remove "Toggling multi-web-mode off; better pass an explicit argument" message in Emacs? - emacs

I have noticed, from a while, that every time I run emacs in multi-web-mode I get the following message:"Toggling multi-web-mode off; better pass an explicit argument".
Why do I get that? multi-web-mode is not toggled off because I use it and it works fine, but I keep getting this message all the time.
How can I fix this little trouble?
This is my code in my .emacs file where "multi-web-mode" appears (I am using Emacs 23.4):
(require 'multi-web-mode)
(setq mweb-default-major-mode 'html-mode)
(setq mweb-tags '((c++-mode "<\\?php\\|<\\? \\|<\\?=" "\\?>")
(ecmascript-mode "<script +\\(type=\"text/javascript\"\\|language=\"javascript\"\\)[^>]*>" "</script>")
(css-mode "<style +type=\"text/css\"[^>]*>" "</style>")))
(setq mweb-filename-extensions '("php" "htm" "html" "ctp" "phtml" "php4" "php5"))
(multi-web-global-mode 1)
(add-to-list 'auto-mode-alist '("\\.php\\'" . multi-web-mode))
(add-to-list 'auto-mode-alist '("\\.html\\'" . multi-web-mode))

Well it sounds like somewhere there's some code causing this mode to be called, non-interactively, with no arguments: (multi-web-mode). A common cause would be specifying a mode function symbol for use as a callback, rather than specifying a function which will call that mode function (with an argument).
This certainly used to be bad form, as it would indeed act as a toggle, just as it does in the interactive case (e.g. M-x multi-web-mode). Since Emacs 24, however, it is actually safe to do (at least for modes defined with the standard macros), as a non-interactive call with no argument to a mode function now always means 'enable'. This might account for the fact that you're not actually seeing a problem.
I don't think stock Emacs has ever generated such a message, so I would presume it's multi-web-mode itself which is detecting and reporting on this. It may need to be updated to reflect the change in Emacs 24. (Edit: looks like I was wrong about that; I guess Emacs 23.4 did produce this warning.)
Your simplest fix is probably to show us any lines from your config which mention multi-web-mode, so someone can show you how to change it to ensure that it passes an explicit argument (which is typically 1 to enable a mode).
Edit: Okay, your problem is that multi-web-mode is a minor mode (as opposed to a major mode), but you have specified it in auto-mode-alist which is a mechanism for mapping filename patterns to major modes.
So the cause is exactly as I suggested above when I said "A common cause would be specifying a mode function symbol for use as a callback", as those auto-mode-alist entries will result in a call to (multi-web-mode).
It appears to me that multi-web-global-mode handles enabling the minor mode as required, so you just need to remove the bad auto-mode-alist entries.

Related

emacs doremi: to change color-themes

I'm trying to get doremi working in emacs. Specifically, at this stage, to allow me to quickly scroll through a condensed list of color-themes and see each theme as I go through it. For this I would use the 'M-x doremi-color-themes+' command.
What I've done:
Installed color-themes (successfull)
Installed doremi.el, doremi-cmd.el, ring+.el and added
(add-to-list 'loadpath "~/elisp/themes")
(add-to-list 'loadpath "~/elisp/doremi/")
(require 'color-theme)
(color-theme-initialize)
(color-theme-classic)
;; create a list of color themes to scroll through using 'doremi-cmd
(setq my-color-themes (list 'color-theme-classic
'color-theme-retro-green
'color-theme-gray30
'color-theme-subtle-hacker
'color-theme-jonadabian-slate))
(require 'doremi)
(require 'doremi-cmd)
(require 'ring+)
to the .emacs file.
What emacs does:
When I type the comand 'M-x doremi-color-themes+' into the mini-buffer it seems to accept that I've given it a valid command and tells me to use the and arrow keys to move through the list. But when I do that all that happens is the cursor moves up and down in the active window. No changing of color-themes.
Being somewhat new to emacs (and especially customising it) I'm sure I have missed a step or put something in the wrong place. Perhaps there's some sort of (setq 'bla-bla-bla (...)) I need to do?
Sorry for your trouble. Please state your Emacs version (M-x emacs-version), and your version of color-theme.el.
You do not need to require library ring+.el if you use Emacs 23 or later (its code was included in GnuEmacs 23.)
You do not need to use (color-theme-initialize) or (color-theme-classic). The former is done automatically by doremi-color-themes+.
Try starting from emacs -Q (i.e., no init file, ~/.emacs), to be sure there is no interference from stuff in your init file.
Your variable my-color-themes is not referenced anywhere. Instead of defining that variable, just customize user option doremi-color-themes. (Or leave its value nil, which means that all color themes will be cycled through.)
Feel free to contact me by email if you continue to have a problem. Or continue here, if you prefer.
[Just to be sure: you are using color-theme.el, right? There is a lot of confusion out there between Emacs "custom themes" and color themes. Do Re Mi supports both, but they are different critters.]
After a bit for back and forth with #Drew we found a solution to the problem.
It turned out the major problem was that I was using emacs in 'terminal mode' rather than as a GUI application. Bare in mind I'm using a mac.
In the context of Terminal, my arrow keys send escape sequences and so doremi cannot read the event as intended. So it just escapes and applies the message to the active buffer.
There is an answer.
By adding the following lines to my .emacs file (or whatever your init file for emacs is) I was able to redirect doremi to use two other keys. ie. not the up and down arrows.
(setq doremi-down-keys '(?n))
(setq doremi-up-keys '(?p))
Doing this tells doremi to use 'n' as the down key and 'p' as the up key. And all works just fine.
Because I am only new to the world of programming and computing I may often use incorrect terminology. If this is the case please let me know and I will edit accordingly for clarity and consistency.

The major mode name of emacs-lisp

I want to load emacs init files faster, so I use the 'eval-after-load.
For example, when I load clojure file, I just put
(eval-after-load 'clojure-mode
'do-something)
It works.
But when I try
(eval-after-load 'emacs-lisp-mode
'do-something)
It doesn't work. I wonder to know the right major mode name of emacs-lisp.
Thanks.
Please read the documentation of eval-after-load:
eval-after-load LIBRARY FORM
This function arranges to evaluate form at the end of loading the file LIBRARY, each time LIBRARY is loaded. If LIBRARY is already loaded, it evaluates form right away. Don't forget to quote form!
[…] LIBRARY can also be a feature (i.e., a symbol), in which case form is evaluated at the end of any file where (provide LIBRARY) is called.
You have to pass the name of the file or library, which defines the major mode, as argument.
While some modes are defined in files of the same name (e.g. clojure-mode in clojure-mode.el), many files a different name, especially if the actually define multiple major modes.
emacs-lisp-mode is defined in lisp-mode.el, along with some other modes for Emacs Lisp editing (e.g. lisp-mode as a generic Lisp language mode, or lisp-interaction-mode for *scratch* buffers).
Hence, use (eval-after-load 'lisp-mode …)
Also, you have to give a single sexp as second argument, so you'll likely want to use (eval-after-load 'lisp-mode '(do-something)), to call the function do-something.
If you are using a snapshot build of Emacs, use with-eval-after-load, i.e. (with-eval-after-load 'lisp-mode (do-something)). It allows for more than a single form, and doesn't require quoting.
Just eval with M-: the variable major-mode. It actually is emacs-lisp-mode.
Note that *scratch* is actually in lisp-interaction-mode.
As to what you're trying to do, use (eval-after-load "lisp-mode").
As explained by #lunaryom, the arg passed to eval-after-load is not a function name but a feature name, which is basically a file name. So you need to find the name of the file from which the function is loaded.
We could provide a feature like eval-after-defun, and indeed it might be a good idea to do so. If you'd like such a thing, ask for it via M-x report-emacs-bug.

How to keep dir-local variables when switching major modes?

I'm committing to a project where standard indentations and tabs are 3-chars wide, and it's using a mix of HTML, PHP, and JavaScript. Since I use Emacs for everything, and only want the 3-char indentation for this project, I set up a ".dir-locals.el" file at the root of the project to apply to all files/all modes under it:
; Match projets's default indent of 3 spaces per level- and don't add tabs
(
(nil .
(
(tab-width . 3)
(c-basic-offset . 3)
(indent-tabs-mode . nil)
))
)
Which works fine when I first open a file. The problem happens when switching major modes- for example to work on a chunk of literal HTML inside of a PHP file. Then I lose all the dir-local variables.
I've also tried explicitly stating all of the modes I use in ".dir-locals.el", and adding to my .emacs file "dir-locals-set-class-variables / dir-locals-set-directory-class". I'm glad to say they all behave consistently, initially setting the dir-local variables, and then losing them as I switch the major mode.
I'm using GNU Emacs 24.3.1.
What's an elegant way of reloading dir-local variables upon switching a buffer's major-mode?
-- edit -- Thanks for the excellent answers and commentary both Aaron and phils! After posting here, I thought it "smelled" like a bug, so entered a report to GNU- will send them a reference to these discussions.
As per comments to Aaron Miller's answer, here is an overview of what happens when a mode function is called (with an explanation of derived modes); how calling a mode manually differs from Emacs calling it automatically; and where after-change-major-mode-hook and hack-local-variables fit into this, in the context of the following suggested code:
(add-hook 'after-change-major-mode-hook 'hack-local-variables)
After visiting a file, Emacs calls normal-mode which "establishes the proper major mode and buffer-local variable bindings" for the buffer. It does this by first calling set-auto-mode, and immediately afterwards calling hack-local-variables, which determines all the directory-local and file-local variables for the buffer, and sets their values accordingly.
For details of how set-auto-mode chooses the mode to call, see C-hig (elisp) Auto Major Mode RET. It actually involves some early local-variable interaction (it needs to check for a mode variable, so there's a specific look-up for that which happens before the mode is set), but the 'proper' local variable processing happens afterwards.
When the selected mode function is actually called, there's a clever sequence of events which is worth detailing. This requires us to understand a little about "derived modes" and "delayed mode hooks"...
Derived modes, and mode hooks
The majority of major modes are defined with the macro define-derived-mode. (Of course there's nothing stopping you from simply writing (defun foo-mode ...) and doing whatever you want; but if you want to ensure that your major mode plays nicely with the rest of Emacs, you'll use the standard macros.)
When you define a derived mode, you must specify the parent mode which it derives from. If the mode has no logical parent, you still use this macro to define it (in order to get all the standard benefits), and you simply specify nil for the parent. Alternatively you could specify fundamental-mode as the parent, as the effect is much the same as for nil, as we shall see momentarily.
define-derived-mode then defines the mode function for you using a standard template, and the very first thing that happens when the mode function is called is:
(delay-mode-hooks
(PARENT-MODE)
,#body
...)
or if no parent is set:
(delay-mode-hooks
(kill-all-local-variables)
,#body
...)
As fundamental-mode itself calls (kill-all-local-variables) and then immediately returns when called in this situation, the effect of specifying it as the parent is equivalent to if the parent were nil.
Note that kill-all-local-variables runs change-major-mode-hook before doing anything else, so that will be the first hook which is run during this whole sequence (and it happens while the previous major mode is still active, before any of the code for the new mode has been evaluated).
So that's the first thing that happens. The very last thing that the mode function does is to call (run-mode-hooks MODE-HOOK) for its own MODE-HOOK variable (this variable name is literally the mode function's symbol name with a -hook suffix).
So if we consider a mode named child-mode which is derived from parent-mode which is derived from grandparent-mode, the whole chain of events when we call (child-mode) looks something like this:
(delay-mode-hooks
(delay-mode-hooks
(delay-mode-hooks
(kill-all-local-variables) ;; runs change-major-mode-hook
,#grandparent-body)
(run-mode-hooks 'grandparent-mode-hook)
,#parent-body)
(run-mode-hooks 'parent-mode-hook)
,#child-body)
(run-mode-hooks 'child-mode-hook)
What does delay-mode-hooks do? It simply binds the variable delay-mode-hooks, which is checked by run-mode-hooks. When this variable is non-nil, run-mode-hooks just pushes its argument onto a list of hooks to be run at some future time, and returns immediately.
Only when delay-mode-hooks is nil will run-mode-hooks actually run the hooks. In the above example, this is not until (run-mode-hooks 'child-mode-hook) is called.
For the general case of (run-mode-hooks HOOKS), the following hooks run in sequence:
change-major-mode-after-body-hook
delayed-mode-hooks (in the sequence in which they would otherwise have run)
HOOKS (being the argument to run-mode-hooks)
after-change-major-mode-hook
So when we call (child-mode), the full sequence is:
(run-hooks 'change-major-mode-hook) ;; actually the first thing done by
(kill-all-local-variables) ;; <-- this function
,#grandparent-body
,#parent-body
,#child-body
(run-hooks 'change-major-mode-after-body-hook)
(run-hooks 'grandparent-mode-hook)
(run-hooks 'parent-mode-hook)
(run-hooks 'child-mode-hook)
(run-hooks 'after-change-major-mode-hook)
Back to local variables...
Which brings us back to after-change-major-mode-hook and using it to call hack-local-variables:
(add-hook 'after-change-major-mode-hook 'hack-local-variables)
We can now see clearly that if we do this, there are two possible sequences of note:
We manually change to foo-mode:
(foo-mode)
=> (kill-all-local-variables)
=> [...]
=> (run-hooks 'after-change-major-mode-hook)
=> (hack-local-variables)
We visit a file for which foo-mode is the automatic choice:
(normal-mode)
=> (set-auto-mode)
=> (foo-mode)
=> (kill-all-local-variables)
=> [...]
=> (run-hooks 'after-change-major-mode-hook)
=> (hack-local-variables)
=> (hack-local-variables)
Is it a problem that hack-local-variables runs twice? Maybe, maybe not. At minimum it's slightly inefficient, but that's probably not a significant concern for most people. For me, the main thing is that I wouldn't want to rely upon this arrangement always being fine in all situations, as it's certainly not the expected behaviour.
(Personally I do actually cause this to happen in certain specific cases, and it works just fine; but of course those cases are easily tested -- whereas doing this as standard means that all cases are affected, and testing is impractical.)
So I would propose a small tweak to the technique, so that our additional call to the function does not happen if normal-mode is executing:
(defvar my-hack-local-variables-after-major-mode-change t
"Whether to process local variables after a major mode change.
Disabled by advice if the mode change is triggered by `normal-mode',
as local variables are processed automatically in that instance.")
(defadvice normal-mode (around my-do-not-hack-local-variables-twice)
"Prevents `after-change-major-mode-hook' from processing local variables.
See `my-after-change-major-mode-hack-local-variables'."
(let ((my-hack-local-variables-after-major-mode-change nil))
ad-do-it))
(ad-activate 'normal-mode)
(add-hook 'after-change-major-mode-hook
'my-after-change-major-mode-hack-local-variables)
(defun my-after-change-major-mode-hack-local-variables ()
"Callback function for `after-change-major-mode-hook'."
(when my-hack-local-variables-after-major-mode-change
(hack-local-variables)))
Disadvantages to this?
The major one is that you can no longer change the mode of a buffer which sets its major mode using a local variable. Or rather, it will be changed back immediately as a result of the local variable processing.
That's not impossible to overcome, but I'm going to call it out of scope for the moment :)
Be warned that I have not tried this, so it may produce undesired results ranging from your dir-local variables not being applied, to Emacs attempting to strangle your cat; by any sensible definition of how Emacs should behave, this is almost certainly cheating. On the other hand, it's all in the standard library, so it can't be that much of a sin. (I hope.)
Evaluate the following:
(add-hook 'after-change-major-mode-hook
'hack-dir-local-variables-non-file-buffer)
From then on, when you change major modes, dir-local variables should (I think) be reapplied immediately after the change.
If it doesn't work or you don't like it, you can undo it without restarting Emacs by replacing 'add-hook' with 'remove-hook' and evaluating the form again.
My take on this:
(add-hook 'after-change-major-mode-hook #'hack-local-variables)
and either
(defun my-normal-mode-advice
(function &rest ...)
(let ((after-change-major-mode-hook
(remq #'hack-local-variables after-change-major-mode-hook)))
(apply function ...)))
if you can live with the annoying
Making after-change-major-mode-hook buffer-local while locally let-bound!
message or
(defun my-normal-mode-advice
(function &rest ...)
(remove-hook 'after-change-major-mode-hook #'hack-local-variables)
(unwind-protect
(apply function ...)
(add-hook 'after-change-major-mode-hook #'hack-local-variables)))
otherwise and finally
(advice-add #'normal-mode :around #'my-normal-mode-advice)

How to call interactive Emacs Lisp function with a prefix argument, from another Emacs Lisp function?

I want to write an Emacs Lisp function that will turn on flyspell-mode regardless of the current state of the mode. Function flyspell-mode-on is deprecated. The documentation suggests that a positive prefix argument will turn flyspell-mode, but unfortunately running
(flyspell-mode 1)
results in an error message:
Wrong number of arguments: (lambda (flyspell-mode 1)), 0
If I could figure out how to call flyspell-mode with a prefix argument, I believe I could solve this problem.
The most relevant section I can find in the Emacs Lisp manual is the section entitled "Interactive Call", which describes such commands as call-interactively. This is emphatically not what I want.
(The ultimate problem I am trying to solve is to create a mode hook that turns on the mode regardless of its current state.)
N.B. The title of the question emacs lisp call function with prefix argument programmatically makes it appear to be related, but that question was asking about how to create an interactive command, and the issue was ultimately resolved by using call-interactively.
EDIT: This question is moot; I have found an alternate solution to my original problem:
(add-hook 'text-mode-hook
(function (lambda ()
(require 'flyspell)
(if flyspell-mode nil (flyspell-mode)))))
But I would still like to know how to call an Emacs Lisp function with a prefix argument, from another Emacs Lisp function, with nothing interactive.
UPDATE: Perhaps I should have asked why I was getting that error message...
It looks like your version of Flyspell mode does not follow the minor mode conventions, which require that you can turn on a minor mode with (name-of-mode t) or any positive prefix argument, turn it off with (name-of-mode 0) any negative prefix argument, and toggle it with (name-of-mode nil).
If you have the latest version of Flyspell, a bug report might be in order. I have the version shipped with GNU Emacs 23.2 on my machine, and it respects the convention. My version also defines two functions turn-on-flyspell and turn-off-flyspell, both trivial wrappers around flyspell-mode; functions with such names are common, but not official conventions. The functions flyspell-mode-on and flyspell-mode-off are apparently intended for internal use.
As a general matter, commands read the current prefix argument from the current-prefix-arg variable. Don't confuse that with prefix-arg, which is the value for the next command (only a few commands like universal-argument touch this variable). Thus, if you need to pass a prefix argument when calling a function, bind or set current-prefix-arg.
(let ((current-prefix-arg t))
(flyspell-mode))
If you are not calling a function interactively, then the (interactive) declaration is not used to obtain the arguments.
In the vast majority of cases, you do not need to worry about whether an argument can be a "prefix argument" for non-interactive calls; just check the function documentation, and pass the value you need for whatever it is you want to do.
If for some reason you do need to replicate sending a prefix argument in a non-interactive context, you will need to check that function's (interactive) declaration and determine exactly how it is using that argument, and ensure that you replicate that behaviour for the argument you do pass.
For full details, see:
C-hf interactive RET
M-: (info "(elisp) Prefix Command Arguments") RET
In more complex cases where the function changes its behaviour based on the current-prefix-arg variable, you may be able to set that variable directly.
(let ((current-prefix-arg '(4)))
(foo current-prefix-arg))
I can think of this.. Should be more better
(call-interactively (lambda ()
(interactive)
(flyspell-mode '(4))))
UPDATE:
I can run this directly.. what am i missing from the question.?
(flyspell-mode '(4))
EDITED: Removed quote for lambda expression (I added this note because SX forces an edit to be at least six characters long, so this can be deleted).
FWIW, the `flyspell-mode' function has accepted an argument (as in "(flyspell-mode 1)") at least since Emacs-21, so I don't know how you got that error.
But while I'm here, I might as well point out that (add-hook 'text-mode-hook 'flyspell-mode) has changed meaning in Emacs-24: instead of meaning "toggle flyspell-mode in text modes" it will now mean "enable flyspell-mode in text modes". It's a backward-incompatible change, but I believe it will fix more latent bugs than it will introduce.
See my comment for the fix to the source of your problem. As for the answer to your question, the way the prefix arg is turned into some kind of Lisp argument depends on the interactive spec, so the only way to do it reliably (i.e. without prior knowledge such as the fact that it's a minor mode function) is to call the function interactively:
(let ((current-prefix-arg '(4)))
(call-interactively 'flyspell-mode))
I'm not Emacs and Elisp master (yet ;)) but I think in this case you may use Ctrl-u 1 Alt-x flyspell-mode.

Entering a minor mode with a major mode in Emacs

This question may be a duplicate of this question, but I can't get the following to work properly in my emacs.
I am trying to enter minor mode mlint-mode whenever I enter major mode matlab-mode (both modes available at their SourceForge page). I have the following in my .emacs file:
(add-hook 'matlab-mode-hook
(function (lambda()
(mlint-mode))))
which looks like the answer to the question I linked above. When opening a .m file, I get the following error:
File mode specification error: (void-function mlint-mode)
Could someone please assist in helping me write the correct hook to enter mlint-mode when I open a .m file? FWIW, I'm running emacs 23.1.50.1.
I think the correct name is mlint-minor-mode. Also, remember to ensure that all matlab stuff is known by Emacs, this can be done using:
(require 'matlab-load)
As a side note, it is typically a bad idea to use lambda functions in hooks. If you inspect the value of the hook you will see a lot of unrelated things. Also, if you modify your lambda expression and re-add it, both the old and the new version will be on the hook.
Instead, you can do something like:
(defun my-matlab-hook ()
(mlint-minor-mode 1))
(add-hook 'matlab-mode-hook 'my-matlab-hook)
The "1" is ensures that mlint mode is turned on or stay on if enabled earlier.