How do I make an interactive command automatically available? - emacs

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.

Related

irony-mode does not pick up include paths

I've recently started using irony-mode for completion in emacs (24.3.1). However, I seem unable to add additional system include paths to package.
I have this code in my config:
(defun ac-cc-mode-clang-hooks ()
(yas/minor-mode-on)
(auto-complete-mode 1)
;; avoid enabling irony-mode in modes that inherits c-mode, e.g: php-mode
(when (member major-mode irony-known-modes)
(irony-mode 1))
;; set compiler flags to include header files
(setq irony-compile-flags '("-Iinc"))
(irony-reload-flags))
(add-hook 'c++-mode-hook 'ac-cc-mode-clang-hooks)
(add-hook 'c-mode-hook 'ac-cc-mode-clang-hooks)
irony-mode is loaded correctly and completion works perfectly for include paths which the compiler knows explicitly (i.e. everything printed by echo "" | g++ -v -x c++ -E -) but the additional include path inc is not picked up (does not matter whether its a relative or absolute path).
However, if I add the information to the .clang_complete file and load it using C-c C-b the include path is recognised and used. Obviously this is a less than ideal setup because
I don't want to create a .clang_complete file for each single piece of code I'm working on
The .clang_complete file is not loaded automatically.
Is there some working method (which does not involve a per-project setup, I don't want to create project management files for each piece of code) for telling irony-mode where to look for header files?
You can take a look here: https://github.com/Sarcasm/irony-mode#i-got-an-error-due-to-stdargh-how-to-solve-this
The variable irony-libclang-additional-flags should meet your needs.
It should work without calling irony-reload-flags.
It's not a buffer-local variable though, so you don't need to put it in the hook.
I would recommend the following:
(setq irony-libclang-additional-flags
(append '("-I" "inc") irony-libclang-additional-flags))

Load and evaluate file from .emacs

I work on many different machines and VMs, each of which might have their own needs regarding options for .emacs. I have a Git repository / subdirectory .common-system with a second Emacs Lisp file .common-system/emacs containing common definitions used for all my systems.
What changes can I make to .emacs which will load and eval my secondary definition file automagically? Bonus points for keeping the secondary file out of my buffer list after startup.
Have you tried:
(load-file ".common-system/emacs")
It works better (as Stefan suggests) if you specify the full path to the file, something like
(load-file "~/.common-system/emacs")
If you stick with you current repository layout, using load-file (as suggested by others) is the way to go.
However, if you name your top-level directory .emacs.d and place the file init.el in it, Emacs will find it and run it automatically. That way, you don't have to hand-edit a .emacs file on each system you use.
You use a (cond), dispatching on variables such as user-login-name, system-type and system-name
(cond
((equal user-login-name
"myname")
;; Stuff
)
((equal system-type 'gnu/linux)
(require 'some-file)
;; some-file, could be any file in load-path, named some-file.el, and ending
;; with (provide 'some-file)
))

Emacs c-mode autoloading failed

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.

emacs23 / elisp: how to properly autoload this library?

I am upgrading to emacs23. I find that my emacs.el loads much more slowly.
It's my own fault really... I have a lot of stuff in there.
So I am also trying to autoload everything possible that is currently "required" by my emacs.el.
I have a module that exposes 12 entry points - interactive functions I can call.
Is the correct approach to have 12 calls to autoload in order to insure that the module is loaded regardless of which function I call? Are there any problems with this approach? Will it present performance issues?
If not that approach, then what?
What you really want is to get the autoloads generated for you automatically, so that your .emacs file remains pristine. Most packages have the ;;;###autoload lines in them already, and if not, you can easily add them.
To manage this, you can put all the packages in a directory, say ~/emacs/lisp, and in there have a file named update-auto-loads.el which contains:
;; put this path into the load-path automatically
;;;###autoload
(progn
(setq load-path (cons (file-name-directory load-file-name) load-path)))
;;;###autoload
(defun update-autoloads-in-package-area (&optional file)
"Update autoloads for files in the diretory containing this file."
(interactive)
(let ((base (file-truename
(file-name-directory
(symbol-file 'update-autoloads-in-package-area 'defun)))))
(require 'autoload) ;ironic, i know
(let ((generated-autoload-file (concat base "loaddefs.el")))
(when (not (file-exists-p generated-autoload-file))
(with-current-buffer (find-file-noselect generated-autoload-file)
(insert ";;") ;; create the file with non-zero size to appease autoload
(save-buffer)))
(cd base)
(if file
(update-file-autoloads file)
(update-autoloads-from-directories base)))))
;;;###autoload
(defun update-autoloads-for-file-in-package-area (file)
(interactive "f")
(update-autoloads-in-package-area file))
If you add 'update-autoloads-in-package-area to your kill-emacs-hook, then the loaddefs.el will automatically be updated every time you exit Emacs.
And, to tie it all together, add this to your .emacs:
(load-file "~/emacs/lisp/loaddefs.el")
Now, when you download a new package, just save it in the ~/emacs/lisp directory, update the loaddefs via M-x update-autoloads-in-package-area (or exit emacs), and it'll be available the next time you run Emacs. No more changes to your .emacs to load things.
See this question for other alternatives to speeding up Emacs startup: How can I make Emacs start-up faster?
Well, who cares how slowly it starts?
Fire it up via emacs --daemon & and then connect using either one of
emacsclient -c /some/file.ext, or
emacsclient -nw
I created aliases for both these as emx and emt, respectively. Continuing once editing session is so much saner...
Ideally you shouldn't have any load or require in your .emacs file.
You should be using autoload instead...
e.g.
(autoload 'slime-selector "slime" t)
You will need to use eval-after-load to do any library specific config, but the upshot is that you won't need to wait for all this to load up front, or cause errors on versions of Emacs that don't have the same functionality. (e.g. Terminal based, or a different platform etc.)
While this may not affect you right now, chances are, in future you will want to use the same config on all machines / environments where you use Emacs, so it's a very good thing to have your config ready to fly.
Also use (start-server) and open external files into Emacs using emacsclient - So you avoid restarting Emacs.

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)