"Cannot open load file" error when loading autoload file - emacs

I have a file functions called "myloaddefs.el". It has magic coments and forms under them just like the one below.
;;;###autoload
(defun an-awesome-function '()
(interactive)
"A descriptive comment." t)
;;; other descriptive comments and forms...
It's full path is ~/.emacs.d/core/myloaddefs.el.
I also have an autoloads file whose full path is ~/.emacs.d/.local/autoloads.el. I store its path in the variable my-autoload-file.
Before calling update-file-autoloads, my-autoload-file only has an empty comment ;; (making sure it's non-empty to avoid an error). Calling update-file-autoloads as I do below returns nil. And it when I check the my-autoload-file it was indeed updated with autoloads. Loading the 'my-autoload-filereturnst` and also seems successful.
(update-file-autoloads (concat my-core-dir "myloaddefs.el") t my-autoload-file) ; => nil
(load-file my-autoload-file) ; => t
However after calling an autoloaded interactive function with, M-x an-awesome-function I get "Cannot open load file: no such file or directory" "../core/myautoloads". This confuses me greatly because the directory and the file do exist. What could be wrong here?

The path to your autoload file needs to be on your load path since you are using relative paths to load the libraries (eg. ../core/autoloads). I would use expand-file-name anywhere you are creating a path instead of building them using concat.
Try (push (expand-file-name ".local" "~") load-path) prior to calling an-awesome-function (whose definition is incorrect).

Related

How do I get the currently matched line from a compilation-error-regexp-alist file function?

I'm running a command with compile so I can link from error messages to the associated source, but I need to transform a chunk of the content of matched lines to get the file to link to. (The line shows a clojure namespace, like foo-bar.quux, which needs to be transformed into foo_bar/quux.clj.)
The documentation of compilation-error-regexp-alist says, in part,
Each elt has the form (REGEXP FILE [LINE COLUMN TYPE HYPERLINK HIGHLIGHT...]). ... FILE can also have the form (FILE FORMAT...), where the FORMATs (e.g. \"%s.c\") will be applied in turn to the recognized file
name, until a file of that name is found. Or FILE can also be a function that returns (FILENAME) or (RELATIVE-FILENAME . DIRNAME). In the former case, FILENAME may be relative or absolute.
When I add entries to compilation-error-regexp-alist-alist and compilation-error-regexp-alist with a function in FILE position, my function is called with no arguments. How do I get the matched line inside that function?
Opening compile.el and then searching with C-s (funcall jumped me to:
(setq file (if (functionp file) (funcall file)
(match-string-no-properties file))))
which seems to be the relevant spot and shows that the functions is indeed called with no arguments and that the match-data is still very much valid, so you can extract the file name with (match-string <the-file-sub-group>).

emacs: load-path and require (cannot open load file)

I've got "Cannot open load file" error at (require 'org-mime) while load-path variable seems to be all right:
load-path is a variable defined in `C source code'.
Its value is
("/home/alexey/.emacs.d/elpa/bbdb-20130526.1945" "/home/alexey/.emacs.d/elpa/org-mime-20120112" "/home/alexey/.emacs.d/elpa/smex-20130421.2153" "/usr/share/emacs/24.3/site-lisp" "/usr/share/emacs/site-lisp" "/usr/share/emacs/24.3/lisp
...
Curiously, the remedy looks like this (.emacs):
(add-to-list 'load-path "~/.emacs.d/elpa/org-mime-20120112")
It isn't merely ugly: it's dysfunctional, because the versioned path is subject to change. But why the error?
There is an interesting issue that happens when you load a file that requires another file -- the file that is required must be loaded in chronological order before the next file. For example, if B requires A then A must be placed higher up in chronological order so that when B loads, A is already loaded.
I've had really good luck with this type of setup. Most files end with el or elc, so I'm not sure why you want to load a file with a different or no extension, but it is certainly possible to do that if you want.
(let* ((root.d "~/") (sub-dir (concat root.d ".emacs.d/")))
(load-file (concat sub-dir "init.el"))
(setq load-path
(append `(,root.d ,sub-dir
,(concat sub-dir "elpa/yasnippet")
) load-path)))

Setting byte-compile-dest-file-function

I want to set the destination directory for emacs lisp byte compilation using relative path such as ../foo. I figured out I should use byte-compile-dest-file-function, but do not know how to set it. How can I set it?
To set the byte-compile-dest-function variable, you can use either customize-variable interactively, or setq in your init file. Since you'll have to write a function doing the job either way, I would recommand the latter, so that everything is in the same place in your init file.
For example:
(defun my-dest-function (filename)
(concat (file-name-directory filename)
"../"
(file-name-sans-extension (file-name-nondirectory filename))
".elc"))
(setq byte-compile-dest-file-function 'my-dest-function)
You can find it using C-h v followed by that variable name.
(defcustom byte-compile-dest-file-function nil
"Function for the function `byte-compile-dest-file' to call.
It should take one argument, the name of an Emacs Lisp source
file name, and return the name of the compiled file."
:group 'bytecomp
:type '(choice (const nil) function)
:version "23.2")
You can see that it is a customizable variable, so you can change it's value to "function".
EDIT: I am not so sure this is the variable you want to change. In fact, you can see that it deals with the variable directories often, I don't see how to set a certain directory where all the .elc's should go.

Emacs: Set tab indent for just one file on the fly

I work on an open source project where the creator sets his tab-indents to 2 spaces.
I'd like to just enable it on the fly for the one file I work on and not other files of the same type. There must be something like M-x set-tab-indent. It is a JavaScript file ending in .js.
I know I can use:
(setq-default tab-width int)
inside my .emacs file, but I rather just call an M-x command to set it and forget it during my duration of working on this file. I tried M-x apropos and Google but couldn't find the specific command.
Thanks.
You can make the variable js-indent-level local to the buffer using:
M-x make-variable-buffer-local <RET> js-indent-level <RET>
Then you can set that variable in the buffer using:
M-x set-variable <RET> js-indent-level <RET> 2
The easiest way to do this for a single buffer is to use M-x set-variable.
Type M-x set-variable and press enter
When prompted for the variable to set, set tab-width then press enter
You'll be prompted with the line Set tab-width (buffer-local) to value:.
Put the value you want, then hit enter
The buffer should instantly be updated with the new value.
You could also use file local variables to automate omrib's solution for that one file, by adding this to it:
// Local Variables:
// js-indent-level: 2
// indent-tabs-mode: nil
// End:
Create a file ".dir-locals.el" in the project's directory and fill it like this:
((nil . ((tab-width . 2))))
This will take care of setting tab-width automatically and you don't have to modify the actual file (which is likely version-controlled.)
See the manual for more information about the format. I believe this requires Emacs 23.
As indicated by others, one issue with the File Local Variables approach is that you need to modify the file, and that's not ideal if you need to keep those declarations out of version control.
If you want the variables to apply to all files under a given directory, then Directory Local Variables is obviously the way to go, and you can implement that with either a .dir-locals.el file, or by calling (dir-locals-set-directory-class):
http://www.emacswiki.org/emacs/DirectoryVariables
http://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html
I prefer the directory class approach myself, and I was thinking that it's a shame that there isn't an analogous approach for file local variables, but I found that the directory class code actually works perfectly with files, and the only issue is that dir-locals-set-directory-class calls file-name-as-directory on its argument, which prevents it from being matched, due to the trailing slash.
The following therefore is a way to configure directory local variables for a single file, without modifying the file itself, or affecting other files under the same parent directory.
(defun my-file-locals-set-directory-class (file class &optional mtime)
"Enable 'directory local' classes for individual files,
by allowing non-directories in `dir-locals-directory-cache'.
Adapted from `dir-locals-set-directory-class'."
(setq file (expand-file-name file))
(unless (assq class dir-locals-class-alist)
(error "No such class `%s'" (symbol-name class)))
(push (list file class mtime) dir-locals-directory-cache))
(dir-locals-set-class-variables
'my-javascript-class
'((nil . ((js-indent-level . 2)
(indent-tabs-mode . nil)))))
(my-file-locals-set-directory-class
"path/to/the/file.js" 'my-javascript-class)
I use a snippet of code in my init.el that tries to auto-detect files that use 2-space indents, and switch Emacs's indentation for that file to 2 spaces when it sees such files:
(add-hook 'js-mode-hook
(lambda ()
(when (string-match-p "^ [A-Za-z]" (buffer-string))
(make-variable-buffer-local 'js-indent-level)
(set-variable 'js-indent-level 2))))

How can I check if a file exists using Emacs Lisp?

I would like emacs to mark files that are generated as read-only when they're opened. The part of the puzzle that I'm missing is how to check if a file "exists". I currently have the following:
;;
;; get file extension
;;
(defun get-ext (file-name)
(car (cdr (split-string file-name "\\."))))
;;
;; get the base name of the file
;;
(defun base-name (file-name)
(car (split-string file-name "\\.")))
;;
;; if an 'lzz' file exists for this header, mark it as read only
;;
(defun mark-read-only ()
(if (string= (get-ext (cur-file)) "h")
(if ( ??file-exists??? (concat (base-name (cur-file)) ".lzz") )
(toggle-read-only))))
What can I use for "???file-exists???"?
Once I find this, I'll add "mark-read-only" to the appropriate hook (which I think is the find-file-hook).
BACKGROUND
We use lzz as a code generator to simplify our C/C++ development process. Briefly, lzz takes a single input file (which looks very like C/C++) and generates header and source files as appropriate.
By default, lzz includes #line directives so that the debugger points to the original source and not the generated source, however, to reduce compilation dependencies we normally disable these directives in header files. The result is that when debugging templates or inline functions, the debugger normally points to the generated header file and not the original source file.
This is not a big deal, however, recently I've found that when debugging I'll make a quick modification to the displayed file and then I'll rebuild. Of course this normally means that the change I made disappears because the file I edited is generated and so the changes are "blown away" during the library rebuild.
SOLUTION
Thanks to everyone for their help and comments. A special thanks to cobbal for pointing out the correct function to use.
Here's the resulting code (with updates based on the other comments here too):
(defun cur-file ()
"Return the filename (without directory) of the current buffer"
(file-name-nondirectory (buffer-file-name (current-buffer)))
)
(defun mark-generated-as-read-only ()
"Mark generated source files as read only.
Mark generated files (lzz or gz) read only to avoid accidental updates."
(if
(or (string= (file-name-extension (cur-file)) "h")
(string= (file-name-extension (cur-file)) "cpp"))
(cond
(
(file-exists-p (concat (file-name-sans-extension (cur-file)) ".lzz"))
(toggle-read-only))
(
(file-exists-p (concat (file-name-sans-extension (cur-file)) ".gz") )
(toggle-read-only))
)
)
)
try file-exists-p
"Return t if file filename exists (whether or not you can read it.)".
Note that it's not spesific to files and works for directories too.
Depending on what you need, you might want file-readable-p instead of file-exists-p.
Apropos will only get you so far. Icicles provides apropos completion and progressive completion which let you find help easily for command, function, variable, etc. names that match subparts in an arbitrary order (is it file-exists-p or exists-file-p?).
Use f.el, modern library for file and directory manipulation. You can use f-exists?, f-file?, f-directory? and many other predicates. The library is better than standard functions, because it's every file related function you'll ever need under one namespace.