Automatically Reload a File in LISP When a Command Is Entered - lisp

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.

Related

Determine how library or feature was loaded

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)

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 find which file provide(d) the feature in emacs elisp

Currently i am using the load-history variable to find the file from which a feature came from.
suppose to find the file the feature gnus came from.
I execute the following code in scratch buffer which prints filename and the symbols in separate lines consecutively.
(dolist (var load-history)
(princ (format "%s\n" (car var)))
(princ (format "\t%s\n" (cdr var))))
and then search for "(provide . gnus)" and then move the point to the start of line(Ctrl+A).
The file name in the previous line is the file from which the feature came from.
Is there any thing wrong with this method, or does a better method exist.
I don't really know what you're trying to do with this, but here are some notes.
Your method is fine. Any way to hack your own solution to a problem is good in my book.
#Tom is correct that you shouldn't really need to do this, because the problem is already solved for you by the help system. i.e. C-h f
But that's not so interesting. Let's say you really want an automatic, more elegant solution. You want a function -- locate-feature with this signature:
(defun locate-feature (feature)
"Return file-name as string where `feature' was provided"
...)
Method 1 load-history approach
I'll just describe the steps I took to solve this:
You've already got the most important part -- find the variable with the information you need.
I notice immediately that this variable has a lot of data. If I insert it into a buffer as a single line, Emacs will not be happy, because it's notoriously bad at handling long lines. I know that the prett-print package will be able to format this data nicely. So I open up my *scratch* buffer and run
M-: (insert (pp-to-string load-history))
I can now see the data structure I'm dealing with. It seems to be (in pseudo code):
((file-name
((defun|t|provide . symbol)|symbol)*)
...)
Now I just write the function
(eval-when-compile (require 'cl))
(defun locate-feature (feature)
"Return file name as string where `feature' was provided"
(interactive "Sfeature: ")
(dolist (file-info load-history)
(mapc (lambda (element)
(when (and (consp element)
(eq (car element) 'provide)
(eq (cdr element) feature))
(when (called-interactively-p 'any)
(message "%s defined in %s" feature (car file-info)))
(return (car file-info))))
(cdr file-info))))
The code here is pretty straight forward. Ask Emacs about the functions you don't understand.
Method 2 help approach
Method one works for features. But what if by I want to know where any
available function is defined? Not just features.
C-h f already tells me that, but I want the file-name in a string, not all of the verbose help text. I want this:
(defun locate-function (func)
"Return file-name as string where `func' was defined or will be autoloaded"
...)
Here we go.
C-h f is my starting point, but I really want to read the code that defines describe-function. I do this:
C-h k C-h f C-x o tab enter
Now I'm in help-fns.el at the definition of describe-function. I want to work only with this function definition. So narrowing is in order:
C-x n d
I have a hunch that the interesting command will have "find" or "locate" in its name, so I use occur to search for interesting lines:
M-s o find\|locate
No matches. Hmmm. Not a lot of lines in this defun. describe-function-1 seems to be doing the real work, so we try that.
I can visit the definition of describe-function-1 via C-h f. But I already have the file open. imenu is available now:
C-x n w M-x imenu desc*1 tab enter
Narrow and search again:
C-x n d M-s o up enter
I see find-lisp-object-file-name which looks promising.
After reading C-h f find-lisp-object-file-name I come up with:
(defun locate-function (func)
"Return file-name as string where `func' was defined or will be autoloaded"
(interactive "Ccommand: ")
(let ((res (find-lisp-object-file-name func (symbol-function func))))
(when (called-interactively-p 'any)
(message "%s defined in %s" func res))
res))
Now go have some fun exploring Emacs.
There is locate-library for that.
Try...
M-: (locate-library "my-feature")
eg: (locate-library "gnus")
Just use symbol-file. It scan load-history which has format:
Each entry has the form `(provide . FEATURE)',
`(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)',
`(defface . SYMBOL)', or `(t . SYMBOL)'. Entries like `(t . SYMBOL)'
may precede a `(defun . FUNCTION)' entry, and means that SYMBOL was an
autoload before this file redefined it as a function. In addition,
entries may also be single symbols, which means that SYMBOL was
defined by `defvar' or `defconst'.
So call it as:
(symbol-file 'scheme 'provide) ; Who provide feature.
(symbol-file 'nxml-mode-hook 'defvar) ; Where variable defined.
(symbol-file 'message-send 'defun) ; Where function defined.
(symbol-file 'scheme) ; Look for symbol despite its type.
There is nothing wrong with it, but why is it simpler than getting help on a key or a function? If you use a gnus command for example and you want to know where it comes from then you can use C-h k and it tells you from which elisp file its definition comes.

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.

How do I include files in DrScheme?

I'm using DrScheme to work through SICP, and I've noticed that certain procedures (for example, square) get used over and over. I'd like to put these in a separate file so that I can include them in other programs without having to rewrite them every time, but I can't seem to figure out how to do this.
I've tried:
(load filename)
(load (filename))
(load ~/path-to-directory/filename)
(require filename)
(require ~/path-to-directory/filename)
(require path-from-root/filename)
None of these works. Obviously I'm grasping at straws -- any help is much appreciated.
It's not clear from your question what language level you're using; certain legacy languages may make certain mechanisms unavailable.
The best inclusion/abstraction mechanism is that of modules.
First, set your language level to "module". Then, if I have these two files in the same directory:
File uses-square.ss:
#lang scheme
(require "square.ss")
(define (super-duper x) (square (square x)))
File square.ss :
#lang scheme
(provide square)
(define (square x) (* x x))
Then I can hit "run" on the "uses-square.ss" buffer and everything will work the way you'd expect.
Caveat: untested code.
I believe you are looking for:
(include "relative/path/to/scheme/file.scm")
The (require) expression is for loading modules.
In MIT/GNU Scheme, you can load a file with something like this:
(load "c:\\sample-directory\\sample-file.scm")
But I do not know if it works in DrScheme.
(require "~/path-to-directory/filename")