I am begining to develop my own Emacs environment, I have a custom init.el (as below) that loads libraries from my user directory and ignores the installed directories. I have not placed any of the Amusement or Mail lisp libraries in the User directory but they are still appearing in auto-complete lists. This is because they are being defined as auto-load functions. How do I prevent these auto-load functions from being created? I don't want to individually remove each unwanted function as this is cumbersome and wasteful.
Help info on an unwanted function;
5x5 is an interactive autoloaded Lisp function.
It is bound to <menu-bar> <tools> <games> <5x5>.
my init.el;
(setq inhibit-defaul-init 1)
(setq load-path (list
(expand-file-name "~/.emacs.d/")
(expand-file-name "~/.emacs.d/lisp/")
(expand-file-name "~/.emacs.d/lisp/emacs-lisp/")
(expand-file-name "~/.emacs.d/lisp/eshell/")
(expand-file-name "~/.emacs.d/lisp/net/")
(expand-file-name "~/.emacs.d/lisp/nxml")
(expand-file-name "~/.emacs.d/lisp/org")
(expand-file-name "~/.emacs.d/lisp/term")
(expand-file-name "~/.emacs.d/lisp/textmodes")
(expand-file-name "~/.emacs.d/lisp/usrl")
(expand-file-name "~/.emacs.d/lisp/")
)
)
You can unbind autoloaded functions in the same way that you can unbind normal functions, so you could effectively remove 5x5 and other unwanted autoloaded functions from the running system like this:
(mapc
(lambda (func) (fmakunbound func))
'(5x5 5x5-crack-randomly 5x5-crack-mutating-current 5x5-crack-mutating-best 5x5-crack-xor-mutate 5x5-crack))
For autoloaded variables, you would use makunbound instead of fmakunbound.
To obtain a list of likely suspects, you could use
M-x find-library RET loaddefs RET
M-x occur RET ^(autoload RET
The loadhist library might also be of interest.
Edit:
Actually, inspecting the autoload file seems like a fairly safe method of establishing whether or not you want to eliminate something. I believe this is only usable with functions, however; as far as I can see, other kinds of autoloaded objects are just defined immediately by loaddefs. You could make assumptions based on symbol-name, but I wouldn't recommend it (but then I wouldn't do any of this, so YMMV).
(defvar my-unwanted-libraries
'("5x5" "snake" "hanoi" "tetris")
"Unbind all autoloaded functions for these libraries.")
(defun my-unbind-unwanted-autoload-functions ()
"Unbind all unwanted autoloaded functions."
(interactive)
(do-symbols (symbol)
(let* ((function (and (fboundp symbol)
(symbol-function symbol)))
(file (and function
(consp function)
(eq (car function) 'autoload)
(cadr function))))
(when (and file (member file my-unwanted-libraries))
(fmakunbound symbol)))))
Since most of Emacs is written in Emacs Lisp, and as much as possible is auto-loaded, you cannot easily remove the functions set up for auto loading. For example, c++-mode is an autoloaded function, so getting rid of all autoloaded functions would prevent you from using c++-mode (unless you'd added your own copy).
Probably the best way to do what you are asking is to build your own Emacs executable, and restrict what gets put into the Emacs executable itself. This is documented here. You could simply remove the directories/libraries you don't want, and rebuild. The newly generated autoload file wouldn't contain references to the functions in those libraries, and you'd be all set.
Note: you may inadvertently remove libraries that are used by Emacs that you don't realize. For example, M-x report-emacs-bug uses Email...
Is there a particular reason you want to remove these autoloaded functions? If you feel they're cluttering up completions, there are many many completion libraries you can use to customize what you see.
Related
How can I determine where the load point is for an emacs library? For example, I'm trying to track down and remove any runtime requires of subr-x during initialization, so I'd like to know which library loaded it.
The load-history lists loaded files along with the requires they made when they were loaded, but doesn't seem to provide information about any requires that weren't evaluated initially, but may have been later.
As a simple example, if I M-xload-file "/path/to/the/following/test.el"
(defun my-f ()
(require 'misc))
(provide 'my-test)
I see the first entry in load-history is
("/path/to/test.el"
(defun . my-f)
(provide . my-test))
Then, evaluating (my-f), adds an entry for "misc.el", but there is no indication where it was loaded from (neither is the above entry updated).
How can I find that out?
How can I determine where the load point is for an emacs library?
You can't. There are many reasons an Emacs library will be loaded, for example,
autoload
C-x C-e some lisp code
M-: some lisp code
M-x load-library
For example, I'm trying to track down and remove any runtime requires of subr-x during initialization, so I'd like to know which library loaded it.
Use C-h v load-history, the order is meaningful, for example, your init file loads foo.el, and foo.el requires bar.el, then bar.el requires subr-x.el, load-history should looks like
(foo.el bar.el subr-x.el)
It's not an elegant solution, but worked for me.
As a starting point, that seems works fine for my purposes, I ended up "watching" for an initial call by load or require to a specific library. It's easy to get the name of the file where the require/load took place when an actual load is in progress and load-file-name is defined.
I was less interested in other cases, eg. interactive evaluation, but the following still works -- at least after very minimal testing, it just dumps a backtrace instead of the filename. From the backtrace, it's not hard to find the calling function, and if desired, the calling function's file could presumably be found with symbol-file.
Running the following locates loads/requires of subr-x, reporting in the message buffer the filenames of packages where it was loaded and dumping backtraces around deferred loading locations.
emacs -q -l /path/to/this.el -f find-initial-load
(require 'cl-lib)
(defvar path-to-init-file "~/.emacs.d/init.elc")
(defun find-load-point (lib &optional continue)
"During the first `require' or `load', print `load-file-name' when defined.
Otherwise, dump a backtrace around the loading call.
If CONTINUE is non-nil, don't stop after first load."
(let* ((lib-sym (intern lib))
(lib-path (or (locate-library lib) lib))
(load-syms (mapcar
(lambda (s)
(cons s (intern (format "%s#watch-%s" s lib-sym))))
'(require load)))
(cleanup (unless continue
(cl-loop for (ls . n) in load-syms
collect `(advice-remove ',ls ',n)))))
(pcase-dolist (`(,load-sym . ,name) load-syms)
(advice-add
load-sym :around
(defalias `,name
`(lambda (f sym &rest args)
(when (or (equal sym ',lib-sym)
(and (stringp sym)
(or (string= sym ,lib)
(file-equal-p sym ',lib-path))))
,#cleanup
(prin1 (or (and load-in-progress
(format "%s => %s" ',lib-sym load-file-name))
(backtrace))))
(apply f sym args)))))))
(defun find-initial-load ()
"Call with 'emacs -q -l /this/file.el -f find-initial-load'."
(find-load-point "subr-x" 'continue)
(load path-to-init-file))
;; test that deferred requires still get reported
(defun my-f () (require 'subr-x))
(add-hook 'emacs-startup-hook #'my-f)
I have a function:
(defun function-name (&optional args) ... <unknown content>)
I redefine it with
(defun function-name (&optional args) ... my own content)
Can I somehow after some time remove my own version of function-name and stay with the first one?
No, you cannot.
Save/Restore
You can save the definition yourself before redefining the function:
Common Lisp:
(defparameter *old-def* (fdefinition 'function-name))
(defun function-name ...)
...
(setf (fdefinition 'function-name) *old-def*)
Emacs Lisp:
(defconst *old-def* (symbol-function 'function-name))
(defun function-name ...)
...
(fset 'function-name *old-def*)
Reload
Or, if you know where the function was defined, you can reload the definition:
Common Lisp:
(load "file-name")
Emacs Lisp: same as above or M-x load-library RET.
Reeval
Or, if you know the original definition, you can reevaluate it, by pasting it at the Common Lisp prompt or by visiting the file with the definition in Emacs and evaluating the defun using C-M-x, as suggested by #Drew in a comment.
Note that it's risky to redefine other libraries' or Emacs' own functions, since you don't know what else depends on them working exactly as expected. If at all possible, use a different name. If not, provide copious documentation warning prominently about the redefinitions. Also, did you check first whether the existing function can be tweaked to your satisfaction using predefined hooks that run before or after it or by customizing any particular user options?
Not the way you do it, but you can get what you want by using an advice instead of a new definition. E.g.
(defadvice function-name (around my-overrride activate)
... my own content)
after the above you can recover the old behavior by deactivating the advice. Using the new advice system in Emacs-24.4 this would look like:
(defun my-function-name (&optional args) ... my own content)
(add-advice 'function-name :override #'my-function-name)
which can be reverted with
(remove-advice 'function-name #'my-function-name)
I use flymake in Emacs to check code written in several languages. However, I can't see any way to use flymake on elisp itself.
I'm aware of elint-current-buffer, and byte-compile-file, which both give useful warnings about undefined variables etc. Oddly, they don't always give the same errors: for example, elint doesn't warn about (require 'cl). I've also tried auto-compile-mode (available on MELPA) but this still writes the warnings to a separate buffer.
I would really like my elisp code to be underlined when I make mistakes, as I type. How do I do this? I've configured flymake before, but that was with external programs, not Emacs itself.
The Emacs wiki has this to say about flymake for emacs lisp, though it doesn't seem very complete.
flycheck supports Emacs Lisp "out of the box", though.
Erefactor is pretty decent, and available from the wiki as well as melpa: http://www.emacswiki.org/emacs/erefactor.el
I also like to run checkdoc post-save:
(defun emagician/run-checkdoc ()
"run checkdoc on save if it is an elisp file"
(if (and (eq major-mode 'emacs-lisp-mode)
(> (length buffer-file-name)
(length package-user-dir))
(not (string= (concat package-user-dir "/")
(substring buffer-file-name 0 (+ 1 (length package-user-dir))))))
(checkdoc)))
(add-hook 'after-save-hook 'emagician/run-checkdoc)
Now there is elisp-flymake-byte-compile backend for flymake built in.
To enable add this to config:
(add-hook 'emacs-lisp-mode-hook #'flymake-mode)
https://stackoverflow.com/a/663636/391104
(defun my-c++-mode-hook ()
(setq c-basic-offset 4)
(c-set-offset 'substatement-open 0))
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
Based on my investigation, I just need to add the above code into my .emacs and then it works magically.
Q1> What does defun my-c++-mode-hook () mean? a function definition in lisp?
Q2> What is the usage of following line? where should I trigger it or it is run automatically by emacs
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
Thank you
Q1: Yes, this is a function definition (hence defun). The second symbol is the name, which has the suffix '-hook' to indicate to humans that it is intended to be used as a hook. It could be given (almost) any arbitrary name without changing its behaviour. The empty () indicates the function takes no arguments. Everything else is the body of the function.
Q2: Basically, this adds a pointer to the previous function to the list of functions that are called when ever c++-mode is started. Whenever you start a mode, the Emacs looks for the mode hook, running all the functions in it. Both the function definition and the add-hook line need to go in your .emacs, and they will be run automatically when you start emacs.
To wrap your head around elisp, the introduction is highly recommended. It ships with emacs, and can be accessed from the info system: C-h i, then look for Elisp Introduction.
I would like to make a gradual switch from GNU Emacs to Xemacs. Are there tricks I can use to have the two play well?
Currently, I see the following issues:
xemacs alters .emacs
The two do not like each others .elc files.
Thanks!
Interesting, most appear to be moving in the other direction as I believe XEmacs to be fairly dormant (based on activity of the xemacs-announce list). Simple packages can co-exist, but many folks have given up making their packages work in both XEmacs and Emacs.
But, in answer to your question, to get your .emacs to work in both, I'd start writing a some routines to do function translation between the two. For example, at one point I needed this to get my .emacs to work in XEmacs:
(if (not (fboundp 'tags-table-files))
(defun tags-table-files ()
(tag-table-files tags-file-name)))
Other things were triggered on the Emacs variant, which I stored in a variable GNU:
(setq GNU (not (string-match "XEmacs\\|Lucid" (emacs-version))))
(if GNU
(do-emacs-thing)
(do-xemacs-thing))
I was keeping compiled .emacs files and did this:
(setq compiled-dot-emacs-name (format ".emacs-%d%s" emacs-major-version
(if GNU "" "X")))
Regarding compiled packages, I'd probably store all the .el files in one directory (say emacs-lisp), but have an xemacs variant (xemacs-lisp) with symlinks to the .el files. And then you just byte compile each directory from the appropriate Emacs variant, and make sure to have your load-path point to the right one.
The Emacs wiki has a page on Emacs versus XEmacs which might be a good starting point to figure out other tips to make them cohabitate. Specifically, there's a page for customizing both.
I don't use xemacs, but newer GNU emacs will check for .emacs.d/init.el as well, so maybe moving .emacs stuff to init.el makes sense. Additionally you can link it to .xemacs/init.el if you manage to keep your customization applicable for both.
There is also a discussion on what emacs to prefer on emacswiki.
I started a slow move from Xemacs to Emacs a while ago. I now use both on a daily basis. To make the transition smoother (one set of init files), I stole the following .emacs file from http://xemacs.seanm.ca/_emacs (but the link is now dead).
(setq user-init-file
(expand-file-name "init.el"
(expand-file-name ".xemacs" "~")))
(setq custom-file
(expand-file-name "custom.el"
(expand-file-name ".xemacs" "~")))
(if (file-exists-p user-init-file)
(load-file user-init-file))
(if (file-exists-p custom-file)
(load-file custom-file))
My ~/.xemacs/init.el starts off with:
(unless (boundp 'running-xemacs)
(defvar running-xemacs nil))
(setq load-path (cons "~/.elisp" load-path)) ; packages for both emacsen
(if running-xemacs
(setq load-path (cons "~/.elisp/xemacs" load-path)) ; packages for Xemacs only
(setq load-path (cons "~/.elisp/gnuemacs" load-path))) ; packages for Gnuemacs only
From then on it is pretty obvious what I have (the occasional (if running-xemacs) ...). I also deleted all the .elc files from ~/.elisp, but I presume that Trey Jackson's suggestion will work.
on modern systems i do not see the need for precompiled elisp files anymore. The benefit in looking and on the fly changing the .el-files is much more higher.
.emacs: put your own defines in .emacs_startup (or which name you prefere) and put all your gnu-enmacs stuff there and put a conditional load in your .emacs