8

If I startup emacs 24.5.2 with emacs -Q and do M-x eshell, then run:

$ which rm
eshell/rm is a compiled Lisp function in `em-unix.el'

I get the eshell version. But if I C-h v eshell-prefer-lisp-functions I see the value is nil. Yet the documentation states:

If you would prefer to use the built-in commands instead of the external commands, set eshell-prefer-lisp-functions to t.

Is this a bug? I thought the docs might be backwards so I tried setting the variable to t, but the behavior stays the same, I continue getting the eshell implementation rather than the version in /bin.

  • I wonder if the problem is with which. If you do rm --version, what do you get? – zck Dec 21 '15 at 19:26
  • @zck I get what I would get from /bin/rm, but the whole reason I started investigating this is because I rm'd a large directory which caused all of emacs to freeze, indicating it's using the eshell version. I believe the eshell versions fallback to the system version when they encounter an unrecognized argument for compatibility sake, so I think the fact that it outputs the coreutils' rm version info is actually misleading, and it is using the eshell version. – Joseph Garvin Dec 21 '15 at 19:28
  • Well, that's confusing. Wish I could help more. – zck Dec 21 '15 at 19:48
  • Why not use direct command instead of relying on prefer settings? For example: $ *rm filename. Starting * will make eshell skip looking for built-in commands. This method is useful for bypassing built-in commands no matter what the prefer settings. – Emacs User Dec 27 '15 at 5:26
4

Eshell always prefers Lisp functions. eshell-prefer-lisp-functions only affects the interpretation of *rm, not the interpretation of rm.

Source: the source code… From Emacs 24.3:

(defun eshell-plain-command (command args)
  (let* ((esym (eshell-find-alias-function command))
    …
    (if (and …
             (or esym eshell-prefer-lisp-functions
                 (not (eshell-search-path command))))
        (eshell-lisp-command sym args)
      (eshell-external-command command args))))

eshell-find-alias-function looks up a function under the eshell/ prefix. There's similar logic in eshell/which.

The variable's documentation is downright misleading, and the manual is rather misleading too. I guess the behavior is by design (after all, why would you define an eshell function if it's not to use it?), so it's a documentation bug.

To invoke the external utility, call /bin/rm, or, provided that you left eshell-prefer-lisp-functions set to nil, call *rm*. If you want rm to always invoke the external utility, you can define an alias: alias rm "rm $*" (thanks GDP2).

  • This is a bug report, not an answer. Delete the response or amend it with a workable solution. – Emacs User Dec 27 '15 at 17:05
  • 2
    Emacs User: What are you talking about? The question is "Why does eshell prefer lisp functions even when eshell-prefer-lisp-functions is nil?" and this is 100% an answer to that question. – phils Dec 28 '15 at 8:19
  • "The only way to make rm always invoke the external command is to ensure that there's no function called eshell/rm. (That, or of course advising or redefining some of Eshell's code.)" That's not the only way to make rm invoke the external command. As documented in the manual, you could make an alias which points rm to *rm (see also emacs.stackexchange.com/a/880/10761). – GDP2 Jul 19 '16 at 20:32
  • @Gilles No problem. – GDP2 Jul 19 '16 at 22:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.