Determine how library or feature was loaded - emacs

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)

Related

How to display file while still in find-file-hook

Currently, I use find-file-hook to invoke a lengthy compilation/checking of that file. I have therefore to wait for some time to actually see the file. What I would like to do instead is to be able to view (not edit) the file already while the checker is running, thus creating the illusion of instantaneous compilation. How can I do this?
Using find-file-hook means your code will run on every file you open; are you
sure you want this? It may make more sense to create a new major or minor mode
for the type of file you want to run your validation on and then use the
corresponding mode hook. For instance, if you wanted to check all .chk files
(with your new major mode inheriting from prog-mode):
(define-derived-mode check-mode prog-mode "Checker")
(add-to-list 'auto-mode-alist '("\\.chk\\'" . check-mode))
(add-hook 'check-mode-hook 'check-mode-computation-hook)
As for the actual hook, this code (going off phils' comment) works for me:
;;; -*- lexical-binding: t -*-
(defun slow-computation ()
(dotimes (i 10000000)
(+ i 1)))
(defun check-mode-computation-hook ()
(let ((cb (current-buffer))
(ro buffer-read-only))
(setq-local buffer-read-only t)
(run-at-time .1 nil
(lambda ()
(with-current-buffer cb
(message "Loading...")
(slow-computation)
(setq-local buffer-read-only ro)
(message "Loaded!"))))))
Note, though, that though this will display the file, emacs will still be frozen
until it finishes its processing, as
emacs doesn't actually support multithreading. To get around this, you may
have to use a library like async, deferred, or concurrent.
You should considered using Flycheck which provides async syntax checking for most programming languages and provides a nice API for implementing new/custom checkers.

How to determine whether a package is installed in elisp?

I want to customize environment while the specific package is installed properly. How to check whether some package is installed in elisp?
Something like this?:
(if (require 'ecb)
(progn (setq ....))
(message "ECB not installed!"))
tripleee's answer is a handy example of error handling, but unnecessary in this instance.
(when (require 'some-library nil 'noerror)
do-things)
That 'noerror can be any non-nil value, but of course it's more descriptive this way. I often see :noerror used as well, but I've no idea if there's any particular advantage to using a keyword argument over a symbol (comments, anyone? I'm quite interested to know).
require is a built-in function in C source code.
(require FEATURE &optional FILENAME NOERROR)
If feature FEATURE is not loaded, load it from FILENAME.
If FEATURE is not a member of the list features, then the feature
is not loaded; so load the file FILENAME.
If FILENAME is omitted, the printname of FEATURE is used as the file name,
and load will try to load this name appended with the suffix .elc or
.el, in that order. The name without appended suffix will not be used.
See get-load-suffixes for the complete list of suffixes.
If the optional third argument NOERROR is non-nil,
then return nil if the file is not found instead of signaling an error.
Normally the return value is FEATURE.
The normal messages at start and end of loading FILENAME are suppressed.
The (require) will throw an error if it fails. That should really be all you need.
If you want to configure ECB's behavior only when it is available, look primarily into adding stuff to ecb-hook -- this is the normal way to configure an Emacs package conditionally.
If no hook is available, or you want to roll it by hand for some reason, try something like
(eval-after-load 'ecb '(setq ecb-be-more-like-better-yes-p t))
If you really really want to roll this by hand, you can trap the error from a failed require like this:
(condition-case nil
(progn
(require 'ecb)
(setq ecb-be-more-like-better-yes-p t) )
(file-error (message "ECB not available; not configuring") ))
Note that the condition-case will catch any file-error from inside the progn so you want to make sure you don't do any other file operations inside. Ultimately you may want to put just the require inside a condition-case and use that as the condition for your original if form, but this is already getting out of hand ...
(if (condition-case nil (require 'ecb) (error nil))
(setq ecb-be-more-like-better-yes-p t)
(message "ECB not available; not configuring") )
Why not using "featurep"?
(featurep FEATURE &optional SUBFEATURE)
Return t if FEATURE is present in this Emacs.
(if (featurep 'ecb)
(message "ECB is there!"))
For people wondering how to check if a package.el package is installed, use package-installed-p.
Four years late on this question, but... here's a simple macro that will do this for you.
(defmacro when-feature-loaded (feature &rest body)
"Executes BODY if and only if FEATURE is loaded."
(declare (indent defun))
`(when (featurep ,module)
#,body))
For example:
(when-feature-loaded 'foo
(message "foo is loaded!"))
Here's another version with an "else" case, in case you need to handle that as well.
(defmacro if-feature-loaded (module then-form else-form)
"Executes THEN-FORM if and only if MODULE is already loaded, otherwise executes ELSE-FORM."
(declare (indent 2))
`(if (featurep ,module)
,then-form
,else-form))
The simplest answer is to use require and eval-after-load as stated in other answers.
However that is not always convenient, such as in a function called by a mode hook that wants to activate another minor mode but only if the package for it is installed. In this case featurep is relevant.
Emacs packages increasingly use autoload to improve startup time. If you test for the presence of a package by using require then you are wearing the cost of loading the file(s). If using ELPA/MELPA/Marmalade packages (available by default since version 24) then many packages may be available in an as-yet unloaded state, but a package foo with autoloads will provide a feature foo-autoloads. I wrote a function that is useful for testing whether a package is available in terms of already being loaded or set to autoload.
(defun autofeaturep (feature)
"For a feature symbol 'foo, return a result equivalent to:
(or (featurep 'foo-autoloads) (featurep 'foo))
Does not support subfeatures."
(catch 'result
(let ((feature-name (symbol-name feature)))
(unless (string-match "-autoloads$" feature-name)
(let ((feature-autoloads (intern-soft (concat feature-name "-autoloads"))))
(when (and feature-autoloads (featurep feature-autoloads))
(throw 'result t))))
(featurep feature))))
N.B.: Using (require ..) will load the package, which defeats the benefit of autoloads (deferred loading).
I use this in my code to configure functions which are autoloaded:
(when (fboundp 'some-function)
...)
Example
I have this in my init.el:
(when (fboundp 'ace-select-window)
(keymap-global-set "M-s-u" 'ace-select-window))
If you have ace-window installed, you can test this yourself by copying it into your own init file, restarting Emacs, and running:
(autoloadp (symbol-function 'ace-select-window))
It should return T. Then run the command, and execute that snippet again; it should return nil.
(newbie tip: Hit altshift:, then enter that, and press enter)
This avoids loading your package just to configure it (which is the point of autoloading).
(newbie tip nr 2: using fbound is for functions; use boundp for values)

Automatically Reload a File in LISP When a Command Is Entered

I'm learning LISP for a class. I have a basic workflow setup in Ubuntu with my LISP file in VIM and an interactive LISP prompt in a terminal that I'm using to test code as I write it. Is there a way to get LISP to load a specific file every time I type a command? It's getting a bit tiring having to constantly input (load 'initial-code.cl) (yes, even when I am using the terminal's history).
Can always try:
(let (fn)
(defun l (&optional filename)
(if filename
(setf fn filename))
(load fn)))
Works like this:
[2]> (l "x.lisp")
;; Loading file x.lisp ...
;; Loaded file x.lisp
T
[3]> (l)
;; Loading file x.lisp ...
;; Loaded file x.lisp
T
[4]>
Pretty simple.
You can also do something like:
(defun go ()
(load "project.lisp")
(yourfunc 'your 'parameters))
Then you just type (go) and it reloads your file and calls your main entry point.
Or even combine them:
(defun gogo (&rest args)
(l) ;; call (l "file.lisp") first to initialize it
(apply #'yourfunc args))
then you can change your parameters easily
(gogo 1 2)
(gogo 2 4)
Ya know, it's lisp. Don't like something, change it.
With more time, you can write a simple wrapper that can build these on the fly. But you get the idea.
Most Lisp programmers would encourage you to use SLIME.
If you like Eclipse, there is also a Lisp plugin.
I know this doesn't really answer your question, but at least you can be aware of some alternatives.
You can try slimv, it is like slime for vim.

Emacs incorrectly looking for .el instead of .elc

I recently started using django-html-mumamo-mode which is part of nXhtml in emacs and everything seems to work except that when I start writing javascript code in an html page, I get the warning/error
Can't find library /usr/share/emacs/23.2/lisp/progmodes/js.el
I checked in that folder and all of the files have the .elc extension including js.elc, which is probably why emacs can't find it. Can I change something to make emacs just load the .elc file?
Edit: This continues to occur if I run M-x load-library js or M-x load-library js.elc
Edit2: I have confirmed that load-suffixes is set to ("el" "elc"), and that js.elc is in the progmodes folder, which is in load-path and that all users have read permissions for that file. I am using emacs version 23.2.1, and when I set debug-on-error to t I got a traceback, and it looks like the following part contains the error:
error("Can't find library %s" "/usr/share/emacs/23.2/lisp/progmodes/js.el")
find-library-name("/usr/share/emacs/23.2/lisp/progmodes/js.el")
find-function-search-for-symbol(js-indent-line nil "/usr/share/emacs/23.2/lisp/progmodes/js.elc")
(let* ((lib ...) (where ...) (buf ...) (pos ...)) (with-current-buffer buf (let ... ... ... ...)) (put fun (quote mumamo-evaled) t))
(if (get fun (quote mumamo-evaled)) nil (let* (... ... ... ...) (with-current-buffer buf ...) (put fun ... t)))
(unless (get fun (quote mumamo-evaled)) (let* (... ... ... ...) (with-current-buffer buf ...) (put fun ... t)))
(progn (unless (get fun ...) (let* ... ... ...)))
(if mumamo-stop-widen (progn (unless ... ...)))
(when mumamo-stop-widen (unless (get fun ...) (let* ... ... ...)))
Notably, the third line contains a reference to the correct file, but it ends up trying to load the wrong one. Has anyone seen this kind of thing before or have any idea how to fix it?
If you read the section in the Emacs manual on "How Programs Do Loading, the js.elc file should be loaded if normal library -loading commands (e.g. - "require", "autoload", "load-file", etc) are being used. Some things to do to debug this:
Does your userid have system security permissions to access the js.el file in that location?
If you type M-x emacs-version, what version of Emacs are you running?
The "load-library" command searches for lisp files in the "load-path". When you examine the contents of your load-path, is the specified directory in it?
Set the variable "debug-on-error" to "t" and re-attempt to write javascript code in an html page - when the error occurs, check the source line where the error occurs and, if it's not apparent from that what is causing the problem, post an update to your question with a few lines of the source where the error occurred as well as the stack trace that was produced by Emacs.
EDIT: Ok, now that you've added the stack trace, it's possible to see why the error is occurring. Here are the key lines from the "find-function-search-for-symbol" function (which is the function where the error is occurring in):
(when (string-match "\\.el\\(c\\)\\'" library)
(setq library (substring library 0 (match-beginning 1))))
;; Strip extension from .emacs.el to make sure symbol is searched in
;; .emacs too.
(when (string-match "\\.emacs\\(.el\\)" library)
(setq library (substring library 0 (match-beginning 1))))
(let* ((filename (find-library-name library))
In line#2, the function is setting the library name equal to the "*.elc" library name minus the "c" (e.g. it's converting it from "/usr/share/emacs/23.2/lisp/progmodes/js.elc" to "/usr/share/emacs/23.2/lisp/progmodes/js.el". Then, in line#7 of the above code, it's trying to find that source member (and failing as it doesn't exist). Looking further at the stack trace, the key line is:
(if (get fun (quote mumamo-evaled)) nil (let* (... ... ... ...) (with-current-buffer buf ...) (put fun ... t)))
which is called in the nXhtml "mumamo-funcall-evaled" function. The author of nXhtml obviously has not considered that the ".elc" file may exist but that the ".el" is not in the same directory. It appears that he used to distribute js.el with nXhtml but stopped doing so since it is now shipped with most recent Emacs distributions. So, in his environment, he probably has the ".el" files in the same directory as the ".elc" files and hasn't encountered this problem.So, you should probably do 2 things:
Notify the author of the nXhtml library so that he can fix the bug in his code.
Copy the necessary ".el" source files to "/usr/share/emacs/23.2/lisp/progmodes/" so that you don't get the error. Alternatively, you may choose to re-install js.el (and possibly some other modules) in another directory and put that directory ahead of "/usr/share/emacs/23.2/lisp/progmodes/" in your "load-path".
Doing #1 will get the problem fixed in the long-term while doing #2 should let you use nXhtml in the short-term.
Check your value of load-suffixes
C-h v load-suffixes. You probably want this to be something like (".elc" ".el"). If it is make sure that your mode hasn't set it to something weird, or bound it dynamically.

Emacs custom command line argument

From the documentation I can see I can access command line arguments (command-line-args).
I'd like to add my own arguments but Emacs complains at start up that it doesn't recognize them.
E.g.
emacs -my_argument
I get:
command-line-1: Unknown option `-my_argument'
What's a proper way to define my custom arguments and provide information to my Emacs session?
Is there a way to pop an argument from a command line?
Add something like this to your ~/.emacs, ~/.emacs.el, or ~/.emacs.d/init.el file:
(defun my-argument-fn (switch)
(message "i was passed -my_argument"))
(add-to-list 'command-switch-alist '("-my_argument" . my-argument-fn))
Then you can execute emacs -my_argument and it should print i was passed -my_argument to the minibuffer. You can find more information in the GNU elisp reference.
As stated in another post you can add your custom switches to command-switch-alist and emacs will call the handler function for any matching switch passed in on the command line. However, this operation is done after your .emacs file has been evaluated. This is fine for most cases but you may wish for a command line argument to alter the execution path or behaviour of your .emacs evaluation; I often do this to enable/disable configuration chunks (mainly for debugging).
To achieve this you can read command-line-args and check for your switch manually and then delete it from the list, this will stop emacs complaining about an unknown argument.
(setq my-switch-found (member "-myswitch" command-line-args))
(setq command-line-args (delete "-myswitch" command-line-args))
Which can alter your .emacs evaluation like so:
(unless my-switch-found
(message "Didn't find inhibit switch, loading some config.")
...)
And you could build this into a single step:
;; This was written in SO text-box, not been tested.
(defun found-custom-arg (switch)
(let ((found-switch (member switch command-line-args)))
(setq command-line-args (delete switch command-line-args))
found-switch))
(unless (found-custom-arg "-myswitch")
(message "Loading config...")
...)
For those who are interested, here is a code snip to show how to process custom arguments in Emacs lisp. In this case, I am processing an argument --suffix / -S to variable _suffix.
I pulled the idea from a BSD-Lite Script Emacs script.
(setq _suffix nil)
;; Process cli args
(while command-line-args-left
(setq k (car command-line-args-left))
(setq command-line-args-left (cdr command-line-args-left))
(setq command-line-args (delete k command-line-args))
(cond
(or (string-equal k "--cs-suffix")
(string-equal k "-S"))
(setq _suffix (intern (car command-line-args-left)))
(setq command-line-args-left (cdr command-line-args-left))
(setq command-line-args (delete _suffix command-line-args))
)))
This will roll through command-line-args-left and remove them all from command-line-args which will prevent Emacs from complaining.