Emacs c-mode autoloading failed - emacs

I want to load my file named "my-c-setup.el" when the c-mode is loading. So, I'm using the function "autoload".
With my python setup, it works well :
lang.el
(autoload 'python-mode "my-python-setup" "" t)
my-python-setup.el
(require 'python)
; ...
I'm trying to do the same with the c-mode, but i does not work :
lang.el
(autoload 'c-mode "my-c-setup" "" t)
my-c-setup.el
(setq c-basic-offset 4)
; ...
When I try to open a file in c-mode (test.c for example), I have the following error :
File mode specification error: (error "Autoloading failed to define function c-mode")

Autoload is not what you're looking for. What it does is simply load some code the first time it is needed, which is a handy way to extend Emacs' functionality while still keeping the start-up time low.
To solve your problem, we gotta think about what you really want to do: do you simply want some of your code to be loaded at some point, or do you want buffer-local customizations for ever buffer that is in c-mode?
If you simply want Emacs to load your code at start-up, either put your code directly into your .emacs file or use load-file or require instead of autoload:
load-file simply takes a file name, loads the lisp code in that file and evaluates it. So if your code is in a file named "/path/to/my-c-setup.el", you could put the following line in your .emacs, and the code will be loaded on every start-up:
(load-file "/path/to/my-c-setup.el")
Perhaps you don't want to give the absolute path name for every file you load. In that case, you could use the function load-library instead which is similar to load-file but tries to find the given filename in any of the directories stored in the variable load-path:
(add-to-list 'load-path "/path/to")
(load-library "my-c-setup.el")
The advantage is that you have to do the add-to-list part only once, and all subsequent calls to load-library will be able to find code in that directory.
An alternative way is the provide/require mechanism: you can make your .el-file "provide" some feature by putting a (provide 'feature) call in it, e.g.
(provide 'my-c-mode-customizations)
Then put an according (require 'feature) in your .emacs file, and your code will be loaded as well:
(require 'my-c-mode-customizations)
However, if you want your code only be loaded when c-mode is activated on a buffer, the way to achieve that is through Emacs' Hook mechanism:
A hook is a variable where you can
store a function or functions to be
called on a particular occasion by an
existing program.
Most major modes provide a customizable hook variable to which you can add functions that will be called whenever the major mode is invoked. For instance, c-mode provides c-mode-hook. In order for your own customizations to be called whenever c-mode is turned on for a buffer, put them in a function, say, my-c-mode-customizations and add the following line to your .emacs file:
(add-hook 'c-mode-hook 'my-c-mode-customizations)
Of course, you still need autoload for Emacs to actually find the definition of that function.

Lisp's autoload does not call a function when a file is loaded but tells lisp that the function is available and that the given file provides it. Whenever someone calls the (not yet defined) function, the file is loaded.
I think that c-mode is already defined and thus fails to re-register.

Autoload doesn't do what you think it does.
http://www.gnu.org/software/emacs/elisp/html_node/Autoload.html
What you probably want are mode-hooks or eval-after-load.
See eval-after-load vs. mode hook for the difference between the two.

Related

How do I make an interactive command automatically available?

I feel like this question is super basic, but I haven't been able to figure out how to automatically make a simple interactive command available in an Emacs session...
This is in ~/random/exploration/exploration.el.
;;; Code:
;;;###autoload
(defun exploration ()
"a test package"
(interactive)
(message "hi"))
(provide 'exploration)
;;; exploration.el ends here
This is in init.el:
(add-to-list 'load-path (expand-file-name "~/random/exploration"))
exploration isn't available via M-x though. I have to do M-: (require 'exploration) before it appears.
How would I make this command available automatically, like plugins do? I've been poring over the docs for load-path and autoload but can't figure out how to make this happen.
I want to do this so I can put other functions in exploration.el and have them only available after the user first does M-x exploration. That implies that exploration needs to be autoloaded.
Comments on any redundancies in what I've done here, or tips on how I could have debugged this on my own would also be welcome.
The ;;;###autloload comment is just a comment. When Emacs is built (or a suitably intelligent package manager installs your code as a package) it generates an actual autoload, but outside of that, you need to do it yourself.
(autoload 'exploration "exploration" nil t)
Specify an explicit path in the second parameter and you won't actually need the load-path manipulation to accomplish what you describe.
See also https://www.gnu.org/software/emacs/manual/html_node/eintr/Autoload.html
You have to either load the file instead of adding it to the load-path or you need to put (require 'exploration) to your init.el file after adding the folder to the load-path.
Use autoload function:
(autoload 'exploration "exploration")
If you don't modify load-path, you need an absolute path as the second argument.
Alternatively, install your script as a package, either through MELPA (assuming you can get it there), or locally with package-install-file. This will take care about autoloads for you.

How to use the same file extension for different major-modes

I use a custom version of org-mode called lawlist-org-mode -- every function and variable have the prefix lawlist- and the modified version has many custom features that are not available in the stock version. Occasionally, I like to use the stock org-mode version -- however, that requires manually modifying the auto-mode-alist and then restarting Emacs. This is necessary due to the function and variable org-agenda-files and the check that org-mode performs to verify that the proper major-mode is present. Is there an efficient method to modify this programmatically depending upon the function being called?
The stock org-mode needs this entry:
(add-to-list 'auto-mode-alist '("\\.todo\\'" . org-mode))
The custom version called lawlist-org-mode needs this entry:
(add-to-list 'auto-mode-alist '("\\.todo\\'" . lawlist-org-mode))
Examples:
If I call M-x org-agenda, the .todo files needs to be in org-mode.
If I call M-x lawlist-org-agenda, the .todo file needs to be in lawlist-org-mode.
Some Ideas:  The org-agenda-files are generally accessed by org-agenda functions using the following lines of code -- (org-agenda-files nil 'ifmode) . . . (while (setq file (pop files)). Perhaps modifying the function org-agenda-files would be an option?
The FUNCTION part of an auto-mode-alist entry (i.e., the cdr) is just a function. It is called, in principle to set up a major mode. But it can do anything.
In particular, you could have an entry ("\\.todo\\'" . foo), where function foo conditionally calls either lawlist-org-mode or org-mode.
E.g, it could use lawlist-org-mode when the moon is full and org-mode otherwise. Or it could test a global variable, which you set when you want to switch from one to the other. And so on.
At least that's my reading of the auto-mode-alist doc string. I've never tried it.

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 load yasnippets on condition

I am doing some Drupal programming and have created yasnippets for common functions: db_select, db_delete etc.
I want to load them only when I am working on a Drupal file and not for a common php file. The task is this:
given a list of yasnippet files and the path of the currently opening file
if(path contains '/sites/all/modules')
{
load all the snippets from the list
}
How to do it?
You have two options:
Create a new mode called drupal-mode that inherits everything from php-mode and then define snippets for that mode, check out Derived Modes in the Emacs Manual on how to do that
Add a function to the find-file hook that checks to see if the current buffer is in a particular directory and then load the snippets you want
Either way you'll be doing things based on the current directory or filename.
find-file-hook example
I haven't tested this code but the concept is there. You'll probably have to check the yas/load-directory-1 function to something else or mess around with parameters.
(defun load-drupal-snippets ()
(when (string-match-p "/sites/all/modules" (file-name-directory (buffer-file-name)))
(yas--load-directory-1 "/path/to/drupal/snippets/" 'php-mode 'text-mode)))
(add-hook 'find-file-hook 'load-drupal-snippets)

In Emacs, how can I load a certain file when (require 'x) is called?

I need CEDET for eassist (eassist-list-methods is quite handy). In eassist.el there's the line
(require 'semantic)
which fails if CEDET isn't loaded. The thing is that I don't need CEDET all the time and it takes a long time to load so I want to defer loading it until I call eassist-list-methods.
Is there a way to run
(load "cedet")
when semantic (or something else that is provided by CEDET) is required?
I'm looking for a simple solution that doesn't change eassist.el.
Genehack is probably right; I'm being too literal in answering the question. The best way to handle something like this is to figure out which function(s) are required by external code, and add autoloads for them.
But if autoload won't work in your case, the normal way to do something when a file is loaded is to do
(eval-after-load "semantic" '(load "cedet"))
But I just noticed that you say that semantic.el fails to load if CEDET hasn't been loaded first. As implied by the name, eval-after-load runs the code after the specified file is loaded.
You can try finding a different file to trigger loading, instead of using semantic.el. (Perhaps some other file that semantic.el requires.)
If necessary, you could hook into require:
(defadvice require (before CEDET-require activate)
(if (eq 'semantic (ad-get-arg 0))
(load "cedet")))
Although (load "cedet") should probably be (require 'cedet), or you'll wind up reloading it every time. (I'm not sure if CEDET has a (provide 'cedet), so I didn't do it that way in my example.)
Note that putting advice on require will not do anything if semantic has already been loaded, so you may need to check (featurep 'semantic) first and load cedet.el immediately if necessary.
Assuming you have all the CEDET stuff in your load-path something like:
(autoload 'eassist-list-methods "cedet" nil t)
in your .emacs.d/init.el (or other init file) should do the trick.
I might be misunderstanding you, but if not the answer is autoload: you want to load eassist.el only when you invoke one of its commands. When it loads it will load semantic or CEDET or whatever it needs -- that's not your problem (it should be taken care of by the design of library eassist.el).
(autoload 'eassist-list-methods "eassist" nil t)