Search code examples
emacselisp

Why is "goto-line" in Emacs for interactive use only?


What problem can happen if the goto-line function is used in a non-interactive elisp program? Its docstring gives a warning saying that:

This function is usually the wrong thing to use in a Lisp program. What you probably want instead is something like:

(goto-char (point-min)) (forward-line (1- N))

Moreover, when I try to byte-compile-file my init file including goto-line, I get a unpleasant warning like this once again:

.emacs:170:19:Warning: `goto-line' used from Lisp code
That command is designed for interactive use only

Is using goto-line in a non-interactive program really so dangerous? Relatedly, why is the suggested forward-line solution preferable?


Solution

  • Firstly, this prevents Elisp programmers from fall into bad habits -- writing inefficient code in a line-number centric way. i.e. instead of using (forward-line 1) calculating the current line number, incrementing, and using goto-line.

    From this mailing list article:

    In a nutshell, the reason why goto-line should not be a frequently used command is that normally there's no reason to want to get to line number N unless you have a program that told you there's something interesting on that line.

    Secondly, goto-line manipulates the user's environment in addition to moving the point (i.e. push-mark). For non-interactive use, this may not be what you want. On the other hand if having considered all this, you believe goto-line is exactly what you need, then just call it like this:

    (defun foo ()
      (interactive)
      (with-no-warnings
        (goto-line N)))
    

    And you won't get any compiler warnings.