Byte compiling emacs lisp is pretty useful, as it generates compiler warnings that, though sometimes cryptic, always point at an error or unfinished tasks, such as missing imports or unimplemented functions.
However, I cannot find a way to generate custom compiler-warnings that integrate well with the *Compile-Log* buffer, i.e. that show the position of the error like
mymodule.el:247:1:Warning: Unused lexical variable `file-name'
E.g. I'm using the subsequent code for placing todo items that raise compile-time messages:
(eval-when-compile
(defmacro TODO (string)
`(eval-when-compile
(message "TODO: %s" ,string))))
However, I cannot find a way to add information (at compile-time) on
file name
line-number
At load-time the variable load-file-name is available, but it is nil at compile-time. The variable default-directory is defined at compile-time but doesn't help in this case.
For the line-number I know no method at all.
When using (warn ...) instead, I get something like
Warning (emacs): TODO: Complete or remove
i.e. no position information at all. If I use (error ...), I get the line number etc displayed automatically, but compilation stops instead of showing all errors and warnings, so it is not a viable solution either.
Update
A partial solution seems to be
(funcall (if byte-compile-current-file 'byte-compile-warn 'warn) FORMAT [ARGS ...])
You need to use the internal variables byte-compile-current-file (the name of the file being compiled) and byte-compile-read-position (the character position at the start of the last read).
Alternatively, you can try the function byte-compile-warning-prefix which inserts the file:line prefix in the *Warnings* buffer.
Either way, you are on your own, messing with the Emacs internals; SO is your only friend. :-)
Indeed, that was a problem. And even byte-compile-read-position is fairly poor because it's not yet up-to-date when the macro is expanded. In Emacs's trunk there is macroexp--warn-and-return, tho as the -- implies, it's currently still considered internal. E.g.
(defmacro TODO (string)
(macroexp--warn-and-return
(format "TODO: %s" string)
nil))
To understand how to use it, you have to understand that it works by returning a special piece of code which makes the byte-compiler later on (when the line-info is available) emit the message.
Related
Here's the setup:
(defun square (x)
(* x x))
;; square
(symbol-function 'square)
;; (lambda (x) (* x x))
(byte-compile 'square)
;; #[(x) "\211_\207" [x] 2]
(symbol-function 'square)
;; #[(x) "\211_\207" [x] 2]
Is there a way to get the source (lambda (x) (* x x)) after square has been byte-compiled?
The two uses that I can think of are inlining the current function call
and doing a debug-step-in.
I've tried messing with find-definition-noselect to get the source,
but I wonder if there's a better way, because it sometimes raises
(error "Don't know where ... is defined")
Emacs keeps track of which function name is defined in which file (this info is kept in load-history). To find the definition, Emacs looks in load-history and if the function is listed there, it looks for the corresponding source file and then in that file looks for something that looks like a likely definition of the function (using regexps). That's what find-definition-noselect does.
As for the source code, no in general Emacs does not keep the source definition. If you define the function with cl-defsubst, then the source is kept around, but otherwise it isn't. For Edebugging, having the source wouldn't help anyway (because Edebug needs not just the source cod but also the precise location of each sub-expression); for plain debugging the source is not really needed either (you can always click on the function's name to jump to the source); for inlining the source is not needed either (the byte-compiler can inline at the source-code level, indeed, but it can just as well inline at the byte-code level).
There is no way to obtain the source of a function object. Byte compilation is no injective function, so you cannot revert it. Even disregarding macro expansion, there is no direct mapping from opcodes to Lisp expressions.
I do not see use cases for this anyway.
Debugging
To step into functions for debugging, navigate to its definition (i.e. find-definition) and instrument the definition for debugging (e.g. with edebug). That's the only way to reasonably debug Emacs Lisp functions. You can't use the contents of the function cell for debugging, because it's subject to macro expansion.
As such, the function cell may look completely different from the actual definition. If you find a bug in the function cell, you'll struggle to find the same bug in the actual function definition.
Inlining
For inlining, use macros or defsubst to define inline functions in Emacs Lisp. However, be careful to not accidentally expose these on the public interface of your library, since compile time inline functions impose a compile time dependency onto your library, so a dependent library needs to be recompiled for every release of your library. And since package.el doesn't support that yet, macros and substitutions can easily cause havoc.
I am trying to program GNU Emacs 23 to issue require commands lazily, on demand, instead of up front in my .emacs file. If I wanted to delay the execution of a load command, I could use autoload. But require and load take different sorts of arguments.
Is there a predefined function that does for require the same job that autoload does for load? And if not, what tools would people recommend that I use to roll my own?
There is not difference between require and load with regards to autoload. require is just a frontend to load, which more or less comes down to:
(defun require (feature &optional filename noerror)
(unless (featurep feature)
(let ((filename (or filename (symbol-name feature))))
(load filename noerror))))
As you can see, the symbol name given to require is equal to the filename given to load. As a matter of fact, the first (require 'foo) evaluated in an Emacs session is equivalent to (load "foo").
Thus, you can just use (auto-load 'foo-function "foo") for foo-function from the library foo, that you can load with (require 'foo).
One more answer to help clarify (this was a little verbose for a comment):
autoload says "if this function isn't already defined, then load this file (if and when the function is called)."
require says "if this library isn't already loaded, then load this file (immediately)."
Note in particular that you don't need to use require to load a library; that's simply the way you ensure that you don't load it again (assuming you don't want to do that). The (provide 'FEATURE) expression in the library will be evaluated no matter how the library was loaded, which lets any future require know that it doesn't need to do anything.
It's a similar situation for autoload -- if the file has already been loaded (and therefore the function in question properly defined), then the autoload no longer has any effect.
What kind of "demand" do you have in mind for your "on demand"?
If a given command or other function needs (or soft-needs) a given library, then that function itself can use (require 'foo) or (require 'foo nil t). The library will be loaded on demand from that function.
Consider also whether you might need to load the file more than once, i.e., reload it in some situations, whether or not it has already been loaded.
For #2, for instance, my code that uses a library of Lisp macros, icicles-mac.el does not just use require, because I want to make sure that if a user gets a new version of that library (e.g., downloads a new source version and byte-compiles it) then that new version is used whenever s?he byte-compiles another library that needs it. (This is important -- when a library of macros changes, other libraries that use those macros generally need to be recompiled after loading the new macros file.) For that, instead of just (require 'icicles-mac) I use this:
(eval-when-compile
(or (condition-case nil
(load-library "icicles-mac") ; Use load-library to ensure latest .elc.
(error nil))
(require 'icicles-mac))) ; Require, so can load separately if not on `load-path'.
How do you go about solving this problem?
Suppose I want to write a function that does the following: if the user has library X installed, then use function X-function, otherwise - skip?
What I tried:
(when (symbol-function 'X-function)
(X-function))
I'm getting a warning for this code - so what is the right way?
How about this:
(when (fboundp 'X-function)
(X-function))
The docs at http://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Cells.html says about symbol-function
If the symbol's function cell is void, a void-function error is signaled.
I'm guessing that is what you are seeing. On the other hand, fboundp just returns t or nil depending on whether the function exists.
The way to suppress this compiler warning is with something like:
(declare-function X-function "ext:X-library.el")
(when (fboundp 'X-function)
(X-function))
Here X-library is the name of the library that X-function is defined in when the library is there. The byte-compiler will then do the following:
It will look for the library in the load path.
If it finds it, it will check that the function has been defined.
If it does not find the library it will assume that it will be when the library is there and pass on without error.
Thus if there is no X-library it won't complain, but if there is one and it does not define the function then it will. This means that if an updated version of the library does not contain X-function then you will know when you try to re-compile your code.
If you look up the documentation for declare-function you will find that it can also check the argument list of functions.
Incidentally If you get similar warnings about undeclared variables you can suppress these with:
(defvar X-variable)
However it is important not to set the variable even if you know what value the library sets it to as this could change in a later version.
This gives you one version of the program that works whether or not X-library is present. You might prefer to have two versions, one for when X-library is present and one for when it is not. This can be done with a macro:
(defmacro run? (function &rest args)
"Expand to function call if function exists."
(when (fboundp `,function)
`(,function ,#args)))
Now instead of a call like:
(X-function a1 a2 a3)
You write:
(run? X-function a1 a2 a3)
If you compile it with X-library present this expands to the call to X-function. If the library is not present then it expands to nothing at all. You will not need the declare-function in any case. This gives two different versions, but it should be more efficient because the decisions as to whether the library is there or not are taken at compile time not run time.
One small caveat. If you go for this second solution you must either compile the whole program in the X-library environment or outside it. If you try loading the library half way through the program then when interpreted it will work as you might expect with the macro expanding differently before and after the load. But in a compiled program a macro is only expanded once. The test test for the library is in code that does the expanding not in the expansion, so the macro will not work the same before and after the load.
Another case when you can get the warning that a function cannot be found is when you define a function programmatically and use fset to set it. The following example illustrates this and what to do about it:
(eval-and-compile
(fset 'my-function1 (lambda () nil)))
(my-function1)
(fset 'my-function2 (lambda () nil))
(my-function2)
(my-function3)
(eval-and-compile
(fset 'my-function3 (lambda () nil)))
If you compile this you get the warnings:
Warning: the function `my-function2' is not known to be defined.
and:
Warning: the function `my-function3' might not be defined at runtime.
The second warning goes away if you re-compile the code a second time in the same Emacs session, but the first doesn't.
What is happening here is this: When the compiler sees eval-and-compile, it first evaluates the body of the in the current Emacs session and then compiles it. Having evaluated the code, Emacs knows about the programmatically defined function.
In the case of function1, the byte compiler sees the function call after Emacs has evaluated the form and so you don't get any warnings.
In the case of function2 the byte compiler never knows the functions is defined so you always get a warning.
In the case of function3, the first time round, the bite compiler doesn't know the function exists when it sees the function call. By the end of the compilation it knows the function exists but it isn't intelligent enough to work out how it knows so you get a different warning. However, if you re-compile it in the same Emacs session, it does know so the warning goes away.
Note that eval-and-compile, like eval-with-compile, look like a progn to the Emacs interpreter.
I'm using emacs + auctex for all my TeXing needs and I'm very satisfied with the workflow. However, there's one thing bothering me. Whenver I compile a document (possible consisting of multiple files) and there's a missing reference auctex prints this annoying message
LaTeX Warning: Reference `fig:MyMissingLabel' on page 42 undefined on input line 37.
and that's it. No shortcut for jumping to the missing reference, nada!
I'm aware that I could enable debugging of warnings, however, this is not really suitable in case the document produces other warnings which I don't want to debugĀ¹.
I'd like to have a defun which cycles the point to the locations of the missing references. Thus I have not found anything online, maybe one of you guys can help?
Thanks in advance!
elemakil
[1] E.g. some packages report warnings when not loaded with a version number or something. I don't want to debug this. I'd like to correct my references!
The shorcuts in AUCTeX allow you to jump to an error.
The missing references are warnings.
You can activate your desired behavior by treating warnings as errors with TeX-toggle-debug-warnings which is bound to C-c C-t C-w.
This question is old, but here's my take. First, define the function
(defun my-ignore-TeX-warnings (type file line text &rest more)
(setq ref "LaTeX Warning: Reference")
(not (string-match-p ref text)))
Then customize the two variables TeX-ignore-warnings and TeX-suppress-ignored-warnings - e.g.,
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(TeX-ignore-warnings 'my-ignore-TeX-warnings)
'(TeX-suppress-ignored-warnings t))
Note: heed the warning above - i.e., you should only have one custom-set-variables.
Put the code into your ~/.emacs or similar file. Then, enable TeX-toggle-debug-warnings or through the menu Command->TeXing options->Debug warnings.
Cycling through errors with C-` will include undefined references. One could extend the code above to also select undefined citations.
Yours,
Christian
Good day, when load any source file into editor i get following message:
File mode specification error: (wrong-type-argument stringp nil)
and flymake simply not working then.
Starting with --init-debug does not improve anythong. Any idea how to debug the cause of problem ?
This general error is thrown when a Lisp function actually expects a string argument but receives a nil.
Try setting (setq debug-on-error t) at the top of your .emacs to get a stack-trace showing you which string is nil. In case the error is caused by FlyMake settings in your .emacs: here is a good introduction.
The deeper reason for wrong-type-argument exceptions is that Lisp functions have no prototypes and cannot rely on the interpreter; they're always defined and hence need to parse their arguments on their own.
The Emacs Lisp interpreter itself does not perform type checking on
the actual arguments passed to functions when they are called. [...]
It is therefore up to the individual function to test whether each
actual argument belongs to a type that the function can use.
For more information see Type Predicates in the Emacs Lisp Reference Manual.