无法理解一行Emacs Lisp代码

4

这行代码是

function info() { 
    emacs -eval "(progn (setq Man-notify-method 'bully) (info \"$1\"))" 
}

我从手册中了解到

Progn

progn是`C源代码'中的一个特殊形式。

Setq

setq是`C源代码'中的一个特殊形式。(setq SYM VAL SYM VAL ...)

将每个SYM设置为其VAL的值。这些符号SYM是变量;它们是字面的(不会被计算)。VAL的值是表达式;它们会被计算。因此,(setq x (1+ y)) 设置x'(1+y)'的值。第二个VAL在设置第一个SYM之后才计算,以此类推;每个VAL都可以使用早期在setq'中设置的变量的新值。返回setq'表单的值是最后一个VAL的值。

$1似乎是用户在命令man之后给出的第一个参数的引用。

'bully似乎是一个随机变量。

Man-notify-method似乎是当执行man命令时运行的动作函数。

-eval似乎是一条计算语句,告诉Emacs运行随后的语句。

然而,我并不完全确定这个函数。

我需要理解这个函数,因为我想将我的bash代码绑定到man的操作函数上。 Man-notify-method似乎是该操作函数,至少在Emacs中是这样的。

你如何理解Emacs Lisp的这一行?

2个回答

12

您发布的代码是shell脚本和elisp的组合。

function info()
{
    emacs -eval "(progn (setq Man-notify-method 'bully) (info \"$1\"))"
}

这定义了一个名为info的shell脚本函数。它有1个参数,命名为$1。当您调用此函数(例如从另一个shell脚本中),参数的值将替换$1,并按顺序运行指定的命令。因此,如果您像这样调用它:

info("something")

Shell将执行这个命令:

emacs -eval "(progn (setq Man-notify-method 'bully) (info \"something\"))"

这将使用两个参数调用emacs可执行文件,-eval和包含嵌入转义引号的命令字符串。 这要求emacs调用以下elisp代码:
(progn (setq Man-notify-method 'bully) (info "something"))

progn是一种特殊形式。特殊形式对待它们的参数与普通函数调用有所不同。你可以在GNU Emacs Lisp参考手册的第10.1章找到progn的文档。 progn是一种简单的结构,用于按顺序执行一系列语句。你可能需要这样做的原因是当你想要执行多个语句时,但上下文只期望单个语句。

例如,一个if语句需要3个(或更多)参数:要评估的条件、如果为真则要评估的表达式和如果为假则要评估的表达式。如果提供了多于3个参数,则后续参数属于else分支。如果你想在true分支中使用多个语句,你必须使用progn

(if condition
   (progn first-statement-if-true
          second-statement-if-true)
   first-statement-if-false
   second-statement-if-false
)

在这种情况下,如果condition为真,则将评估first-statement-if-truesecond-statement-if-true。否则,将评估first-statement-if-falsesecond-statement-if-false
因此,您的代码将按顺序评估两个语句(setq Man-notify-method 'bully)(info "something")setq是另一种特殊形式。请参阅chapter 11.8了解其文档。它只是将第一个参数命名的变量设置为第二个参数的值。第一个参数不会被评估 - 它被直接使用。
以单引号开头的值(例如'bully)不会被评估。有关引用的详细信息,请参阅chapter 9.3。因此,(setq Man-notify-method)将变量命名为Man-notify-method并将其设置为字面标记bully(这是一种称为符号的数据类型,与字符串"bully"不同)。

我找不到关于info函数的文档,你可以通过输入C-h f 函数名称在emacs中获取任何给定函数的帮助。所以,通过输入C-h f info,我得到了以下内容:

info是`info'中一个交互式自动加载的Lisp函数。
[参数列表在函数定义加载之前不可用。]
进入Info,文档浏览器。 可选参数FILE指定要检查的文件;默认值为Info的顶级目录。 从程序调用,FILE可以指定形式为`(FILENAME)NODENAME'的Info节点。
在交互使用中,前缀参数将该命令指向从minibuffer读取文件名。
Info文件的搜索路径在变量`Info-directory-list'中。 顶级Info目录由该路径中所有目录中名为`dir'的所有文件组成。

在线参考手册非常有用,而emacs的交互式帮助也是必不可少的。如果您不理解特定功能的作用,请输入C-h f


6
PROGN会按顺序评估表达式,并返回最后一个表达式的返回值。
SETQ是基本赋值运算符。
INFO进入emacs信息浏览器。
因此,这首先将符号'bully分配给变量Man-notify-method,然后进入信息浏览器。'bully可能是函数的名称,而Man-notify-method是信息浏览器查找某些通知的调用函数的位置(警告:我只是猜测)。
我猜您将不得不定义自己的函数,以像这样调用您的shell命令:
(defun my-cmd ()
  (call-process   ; Look up the syntax in the emacs lisp manual
  ))

然后将其符号分配给Man-notify-method:
(setq Man-notify-method 'my-cmd)

我接受这个答案,因为它很简洁。Adam的答案也非常好。--- 谢谢你们的回答! - Léo Léopold Hertz 준영

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接