关于lisp:Elisp-09库

10次阅读

共计 1718 个字符,预计需要花费 5 分钟才能阅读完成。

上一章:文本跨行提取

从第 1 章就定义了的 princ\' 函数被我一路应用至今,我始终感觉它很有用途,特地是在我调试程序的时候。我抵赖,用这种方法调试程序很原始。不过,筷子也很原始。为了不再张贴残缺的代码之时附上它的定义,我决定建设一个 Elisp 库,用于寄存它的定义以及今后我定义的其余函数。

库文件

我将这个库的全副代码寄存在一份名为 newbie.el 文件里,目前只有 princ\' 的定义:

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

然而,newbie.el 该当放在何处?

EMACSLOADPATH

零碎环境变量 EMACSLOADPATH 可为库文件指定门路。假如我将 newbie.el 放在 $HOME/.my-scripts/elisp 目录里,那么在我的机器上,因为我用的 Shell 是 Bash,因而可在 $HOME/.bashrc 文件里设定

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

在以后终端里执行

$ source $HOME/.bashrc

或从新关上一个终端窗口,令上述设定失效。

库的载入

假如我要写一个 foo.el 程序,它须要调用 newbie.el 里定义的函数 princ\',只需在调用 princ\' 之前,载入 newbie.el 即可。例如

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

在终端执行 foo.el 程序,

$ emacs -Q --script foo.el

程序输入

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

load 函数是 Elisp 的内建函数,它的第一个参数是库文件名,然而没有扩展名。因为 load 函数会在 $EMACSLOADPATH 指定的目录中主动搜寻三种库文件。对于上例,load 函数会依序搜寻 newbie.elc,newbie.el,newbie.ext 这三个文件,只有搜到其中之一,搜寻过程便终止,而后将搜到的文件内容载入至以后程序。newbie.ext 中的「ext」取决于零碎平台,在 Linux 零碎里,「ext」是「so」;在 Windows 零碎里,「ext」是「dll」;亦即 newbie.ext 能够是 C 语言接口的共享库。没错,Elisp 能够载入 C 库,然而须要为它们编写接口绑定,这是后话,暂且不表。

如果不心愿程序执行时在终端输入库的加载信息,只需令 load 函数的第三个参数为 t

(load "newbie" nil t)

其中,第 2 个参数是被迫写上的,因为没有第 2,怎么会有第 3 呢?第 2 个参数如果是 nilload 函数在搜寻不到待载入的库文件时会在终端里输入错误信息,否则不会。

load-path

零碎变量 EMACSLOADPATH 的设定,依赖于具体的操作系统。不依赖操作系统的库文件搜寻门路的设定办法也是有的。Emacs 有个全局变量 load-path,它是列表。

如果我将 foo.el 程序修改为

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

执行该程序,在我的机器上会失去以下后果:

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

不难发现,我通过 EMACSLOADPATH 设定的门路也被退出到了这个列表。

用 Elisp 语言如何操纵列表,当初应该是不废吹灰之力,因而将 foo.el 程序写成

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

没什么理由不会在终端里输入

Hello world!

不过,Elisp 对列表提供了几个能够增加元素的函数,例如 push。以下代码

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

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

等价。

结语

能少些一些代码,很不错。

正文完
 0