有没有办法检查 Emacs Lisp 函数何时添加到 Emacs?

Is there an way to check when an Emacs Lisp function was added to Emacs?

我是 Emacs 包的作者,偶尔​​在处理我的包时,我会遇到一个看起来很有用的函数并在我的代码中使用它。然后,在我发布后不久,有人使用旧的 Emacs 版本(但仍然是我想要支持的版本)会报告该功能未定义,我才意识到这个功能最近才被添加到最新版本的 Emacs 中,并被迫恢复更改 (example)。那么,有什么方法可以查看首次添加特定功能的Emacs版本吗?或者更好的是,一种读取我的整个 elisp 文件并报告它需要的最低 Emacs 版本的方法以及为什么?

我想蛮力解决方案是安装我想要支持的每个 Emacs 版本,并用它们中的每一个测试编译我的包。所以我想问一下有没有更好的方法。

文件 etc/NEWS 及其旧版本的兄弟文件 NEWS.[12]* 包含自新石器时代以来每个 Emacs 版本的非常详细的更改历史记录。 (最老的——也许可以预见——不太详细。)

很遗憾,此信息不是机器可读的形式;但您仍然可以四处寻找信息,但精度不尽如人意。

这是我拼凑的一个快速而肮脏的 Awk 脚本。

#!/bin/sh

# Path to your emacs etc directory
emacs_etc=$HOME/git/emacs-snapshot/etc

# Reverse the order of the wildcard matches so we search newest to oldest
printf '%s\n' $emacs_etc/NEWS.[12]* $emacs_etc/NEWS |
tac |

xargs awk -v fn="" 'BEGIN { regex="^[*]+ New .*" fn }
    /^\*[^*]/ { version=$NF }
    [=10=]~regex { print version ":" [=10=]; exit 0 }
    END { exit 1 }'

这有点不准确,因为它要求条目以 New 开头(这在较新的条目中似乎有些一致,但在较旧的条目中不太一致)并且它会找到一个前缀搜索字符串,不一定完全匹配。

但是,您正在查找的更改与此预期格式不匹配。 The commit which added set-default-toplevel-value just added a free-form notice to NEWS 其中没有提到它引入了一个新变量。

为了真正找到它,我将它定位在源代码树 (src/eval.c) 中,并在包含直接指向相关提交的定义的行中直接 git blame。 (在一般情况下,您可能需要分层剥离提交;幸运的是,对于这种事情,Git 有 fairly good support。)

如果你想知道引入特定功能时的Emacs版本,对于较新版本的Emacs(版本18及更高版本),则可以在etc目录下的NEWS文件中搜索。

https://git.savannah.gnu.org/cgit/emacs.git

克隆最新的 Emacs 版本 git repo

然后你可以在emacs/etc目录中grep搜索包含NEWS文件的函数名:

NEWS       NEWS.18    NEWS.20    NEWS.22    NEWS.24    NEWS.26
NEWS.1-17  NEWS.19    NEWS.21    NEWS.23    NEWS.25    NEWS.27

这将取决于您要查找的内容,但如果您要查找的名称足够可辨,您应该可以在其中找到一些内容。

我使用出色的 ripgrep 工具寻找与函数 string-to-syntax 和宏 defvar-local 相关的信息,这就是我得到的:

> rg string-to-syntax
NEWS.21
3031:** The new function `string-to-syntax' can be used to translate syntax
3038:  (string-to-syntax "()")
> 
> rg defvar-local
NEWS.24
2189:** New macros `setq-local' and `defvar-local'.
>