3

I am the author of an Emacs package, and occasionally when working on my package, I will come across a useful-looking function and use it in my code. Then, shortly after I release, someone using an older Emacs version (but still a version that I want to support) will report that the function is not defined, and I realize that this function has only recently been added in the latest version of Emacs, and am forced to revert the change (example). So, is there any way to check the version of Emacs in which a specific function was first added? Or better yet, a way to read my whole elisp file and report the minimum version of Emacs it would require and why?

I suppose the brute-force solution would be to install every version of Emacs I want to support and test-compile my package with each of them. So I'm asking if there's a better way that.

Ryan C. Thompson
  • 40,856
  • 28
  • 97
  • 159
  • 2
    I think the usual solution to this problem is to byte-compile your file with the oldest Emacs you want to support, and look at the warnings. OTOH, letting your users do this job for you has the advantage that it additionally gives you feedback about which versions of Emacs you should still care about. – Stefan Dec 02 '15 at 14:37

2 Answers2

2

The file etc/NEWS and its siblings for older versions NEWS.[12]* contains very detailed change history for every Emacs version since the neolithic age. (The oldest ones are -- perhaps predictably -- somewhat less detailed.)

Unfortunately, this information is not in machine readable form; but you could still grep around for the information with some less-than-perfect precision.

Here is a quick and dirty Awk script I cobbled together.

#!/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="$1" 'BEGIN { regex="^[*]+ New .*" fn }
    /^\*[^*]/ { version=$NF }
    $0~regex { print version ":" $0; exit 0 }
    END { exit 1 }'

This is slightly inexact in that it requires the entry to begin with New (this seems to be somewhat consistent in the newer entries, but less so in the older ones) and it will find a prefix of the search string, not necessarily an exact match.

However, the change you are looking for does not match this expected format. The commit which added set-default-toplevel-value just added a free-form notice to NEWS which does not mention that it introduced a new variable.

To actually find it, I located it in the source tree (src/eval.c) and a straightforward git blame on the line which contains the definition pointed straight to the pertinent commit. (In the general case, you might need to peel off commits in layers; fortunately, Git has fairly good support for this kind of thing.)

Community
  • 1
  • 1
tripleee
  • 175,061
  • 34
  • 275
  • 318
0

If you want to know the version of Emacs when a specific function was introduced, for relatively recent version of Emacs (version 18 and later), then you could search into the NEWS files located in the etc directory.

Clone the latest Emacs version git repo from https://git.savannah.gnu.org/cgit/emacs.git

Then you can grep search the function name in the emacs/etc directory with contains the NEWS files:

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

It will depend on what your looking for, but if the name your looking for is distinguishable enough you should find something in there.

Using the excellent ripgrep tool I was looking for that info related to the function string-to-syntax and the macro defvar-local, and this is what I got:

> 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'.
> 
PRouleau
  • 150
  • 6