Preface: I don’t know how long it takes to learn ELISP

The previous chapter: text cross – line extraction

I’ve been using the princ\’ function since Chapter 1, and I’ve found it useful all the time, especially when I’m debugging programs. I’ll admit, this is a primitive way to debug a program. But chopsticks are also primitive. In order not to post the complete code with its definition, I decided to build an Elisp library to store its definition and other functions that I would define in the future.

The library files

I store all the code for this library in a file called newbie.el. Currently, only the definition of princ\’ is available:

(defun princ\' (x)
  (princ x)
  (princ "\n"))

But where should Newbie. el go?

EMACSLOADPATH

The system environment variable EMACSLOADPATH specifies the path to a library file. If I put newbie.el in the $HOME/.my-scripts/elisp directory, then on my machine, since I’m using the Shell Bash, I can set it in the $HOME/.bashrc file

export EMACSLOADPATH=$HOME/.my-scripts/elisp:$EMACSLOADPATH

Executes in the current terminal

$ source $HOME/.bashrc

Or re-open a terminal window for the above Settings to take effect.

Base load

Suppose I want to write a program called foo.el that needs to call the function printc \’ defined in newbie.el. Just load newbie.el before calling printc \’. For example,

(load "newbie") (princ\' "Hello world!" )

Execute the foo.el program at the terminal,

$ emacs -Q --script foo.el

Program output

Loading /home/garfileo/.my-scripts/elisp/newbie.el (source)...
Hello world!

The load function is built into Elisp and takes the library filename as its first argument, but it has no extension. Because the load function automatically searches for three library files in the directory specified by $EMACSLOADPATH. For the above example, the load function searches newbie.elc, newbie.el, and newbie.ext in sequence. If one of these files is found, the search is terminated and the contents of the found file are loaded into the current program. The “ext” in newbie.ext depends on the platform. In Linux, “ext” is “so”; On Windows, “ext” is “DLL”; That is, newbie.ext can be a shared library for a C language interface. Yes, Elisp can load C libraries, but you need to write interface bindings for them, but that’s another story.

If you don’t want to print library load information at the terminal when the program is executed, you can simply make the third parameter of the load function t:

(load "newbie" nil t)

The second argument is forced, because there is no second argument, how can there be a third argument? If the second parameter is nil, the load function will print an error message in the terminal when it fails to search for the library to be loaded. Otherwise, it will not.

load-path

The setting of the system variable EMACSloadPath depends on the operating system. There are ways to set the search path for libraries independent of the operating system. Emacs has a global variable, load-path, which is a list.

If I change the foo.el program to

(load "newbie" nil t)
(princ\' load-path)

Execute this program and get the following results on my machine:

(/ home/garfileo /. My - scripts/elisp/usr/share/emacs / 27.2 / lisp...).

It’s easy to see that the path I set through my EMACSLOADPATH is also added to the list.

How to manipulate lists in Elisp should now be a no-win situation, so write foo.el as

(setq load-path (cons "$HOME/.my-scripts/elisp" load-path)) (load "newbie" nil t) (princ\' "Hello world!" )

Is there any reason why it shouldn’t output in the terminal

Hello world!

However, Elisp provides several functions to add elements to the list, such as push. The following code

(push "$HOME/.my-scripts/elisp" load-path)

with

(setq load-path (cons "$HOME/.my-scripts/elisp" load-path))

Equivalence.

conclusion

It’s nice to type less code.

Next chapter: macros