Load file with a relative path - lisp

I am trying to load a file in Lisp from a file in the same directory using a relative path.
My file structure looks like this:
repo/
subdir/
main.lisp
test.lisp
In main.lisp I have a number of function definitions, and in test.lisp I want to test the functions.
I have tried using (load "main.lisp") and (load "main") in test.lisp, as well as a number of variations on the pathname (i.e., including ./ before the filename) but both times I get the following error (where <filename> is the filename passed to the load function):
File-error in function LISP::INTERNAL-LOAD: "<filename>" does not exist.
Is it possible to load main.lisp using a relative path?
It may be worth noting that I am running CMUCL and executing the code using SublimeREPL inside of Sublime Text 3.

When a file is being loaded, the variable *LOAD-PATHNAME* is bound to the pathname of the file being loaded, and *LOAD-TRUENAME* to its truename.
So, to load a file in the same directory with the file currently being loaded, you can say
(load (merge-pathnames "main.lisp" *load-truename*))

jlahd's answer is excellent.
If you need to make different pathname calculations, you can do it with the built-in functions:
(let* ((p1 (pathname "test.lisp")) ; not fully specified
(name1 (pathname-name p1)) ; the name "test"
(type1 (pathname-type p1)) ; the type "lisp"
(p2 #p"/Users/joswig/Documents/bar.text") ; a complete pathname
(dir2 (pathname-directory p2))) ; (:ABSOLUTE "Users" "joswig" "Documents")
; now let's construct a new pathname
(make-pathname :name name1
:type type1
:directory (append dir2 (list "Lisp")) ; we append a dir
:defaults p2)) ; all the defaults
; relevant when the filesystem supports
; host, device or version
The result: #P"/Users/joswig/Documents/Lisp/test.lisp".
Usually to reuse something like above, one turn it into a utility function...

Related

How can I iterate a function with a parameter there the parameter is filename in lisp?

I have 20 text files in a folder and I couldn’t find any solution how my main function which has only one parameter invoke those files(the extensions of files are “txt”). I tried with wildcard but I get always pathnames. My foldername is textfiles which includes 20 files and I can't have any argument either when I run the program.
You can try the following:
(defun my-func (dir)
(setq pathname (make-pathname :name :wild :type "txt" :defaults (pathname dir)))
(loop
for file in (directory pathname) do
(print (file-namestring file))))
If you want to print the full path of a file you can use namestring instead of file-namestring.

"Cannot open load file" error when loading autoload file

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).

Call function in another lisp file

I have to write a game in Lisp. In order to make it clear, I wanted to split the code in different .lisp files.
How can I call a function out of a function in the other file?
E.g. file1.lisp has a function called function1 and file2.lisp has a function called function2.
How can I call function2 out of function1?
Thanks!
Just so you know, there are a variety of different Lisp systems. I'll post the answer for Common Lisp.
The naive way is to use (load "filename.lisp"), but that doesn't really work very well after a while. Therefore...
Common Lisp has a library called "ASDF", which handles packaging and file management. There's a bit of setup to ASDF.
Create directory where ASDF looks for files.
Add this information to my Lisp system's init file.
I use this in my .sbclrc file (assuming that I created a .asdf file in ~) :
(pushnew "~/.asdf/" asdf:*central-registry* :test #'equal)
I usually use a previously built ASDF file and then modify it.
Here's a sample ASDF file's contents:
(asdf:defsystem #:cl-linq
:depends-on ( #:alexandria #:anaphora)
:components ((:file "cl-linq"))
:name "cl-linq"
:version "0.1"
:maintainer "Paul Nathan"
:author "Paul Nathan"
:licence "LLGPL"
:description "CL LINQ style interface with strains of SQL"
:long-description
"DSL for managing and querying datasets in a SQL/LINQ style
syntax. cl-linq provides a simple and usable set of primitives to
make data examination straightforward. ")
I put this code in a file cl-linq.asd next to my source code (cl-linq.lisp from the component "cl-linq" in the defsystem) and then symlink the cl-linq.asd file to my ~/.asdf/ directory.
Within my cl-linq.lisp file I include this:
(defpackage :cl-linq
(:use
:common-lisp
:anaphora)
(:export
#:query
#:cl-linq-select))
(in-package :cl-linq)
So for your case, I would have 2 components; each with their own defpackage form, exporting the functions out that the other package needed.
For the examples, I've taken the code from CL-LINQ, a project of mine. You are quite free to use it as a template.
This is for Emacs Lisp (aka elisp)
Create a file at this location: ~/.emacs.d/init.el
Create a file at this location: ~/.emacs.d/file1.el
Create a file at this location: ~/.emacs.d/file2.el
Now, open up ~/.emacs.d/init.el and write (and then save):
(load "~/.emacs.d/file1.el")
(load "~/.emacs.d/file2.el")
(defun run-both-functions ()
(interactive)
(switch-to-buffer "*Messages*")
(first-function)
(sit-for 2)
(second-function))
Now, open up ~/.emacs.d/file1.el and write (and then save):
(defun first-function ()
(message "My name is Fred."))
Now, open up ~/.emacs.d/file2.el and write (and then save):
(defun second-function ()
(message "My name is George."))
Now, restart Emacs and type: M-x run-both-functions RET
Any functions that you put into any of the three (3) files mentioned above will be accessible to other functions. You will note that run-both-functions includes an (interactive) statement, which means that the user can call the function with M-x or a keyboard shortcut.
If you use the function load it can be useful to not specify the file type.
Loading files: fasl or source
Instead of (load "foo.lisp") one can call (load "foo"). Typically Common Lisp provides the feature of compiling Lisp files to fasl (fast load) files. Those are usually pre-compiled byte code or native code. Typically the Common Lisp implementation will load the compiled code if a file exists for it. This saves time (because compiled code usually can be loaded much faster than Lisp source code) and the code usually is faster (because a file compiler has compiled it).
Often one uses a function to load the compiled file if it is newer, or first compile the source file to a new compiled file.
Loading a file, based on the current file being loaded
In (load "foo") the file foo is not a complete filename. For example we don't know the directory where it is loaded from. This depends on things like the value of *default-pathname-defaults* or in some implementations on a current directory (typical for Unix systems). It may be useful to load the file based on the file we are currently loading - if loading one file triggers more files to be loaded. For this Common Lisp has the variables *load-pathname* and *load-truename* (which is the real filename as used with the filesystem).
To load a file foo in the same directory as the currently loaded file call:
(load (merge-pathnames "foo" *load-pathname*))
To load a file foo in a subdirectory bar of the same directory as the currently loaded file call:
(load (merge-pathnames "bar/foo" *load-pathname*))
With Common Lisp I done it like this:
In file1.lisp I define a function sayHello and export that function under the package name helloLisp
(defpackage :helloLisp
(:use :common-lisp)
(:export #:sayHello))
(in-package :helloLisp)
(defun sayHello () (print "Hello!"))
In the file file2.lisp I require this file like that:
(require "helloLisp" "./file1.lisp")
(helloLisp:sayHello)
Tested with SBCL 1.4.11

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>).

Importing files in Emacs Lisp/Emacs configuration file in the same directory

I have a couple of emacs configuration files. I was going to consolidate them down into a common file and then a couple other files that import the common file. Then have their own functions. I was just going to have them all as .emacsCommon in my home folder but when I write:
(require '.emacsCommon)
it doesn't load the function. What is the right way to do this??
Cheers
Use 'load-file' to load a EmacsLisp file
(load-file "./.emacsCommon")
If you want to use require, you should add (provide 'foo) at the end of a file named foo.el. If that file is on the load-path, you can then use (require 'foo) to load this file, and add the feature (foo) to the feature list. (The printname of 'foo, the feature name, is used as a filename here.)
Since your filename has a leading dot, and doesn't end in .el, you should give the filename as an argument to require though:
(require 'foo ".foo")
Note, that you could also just use load or load-file.