Qestion: Is there a way to make eshell/rm (especially) either display a completion buffer even for few files or remove the . and .. entries for eshell/rm.

Background (and some ranting):

So I learned the hard way that in eshell/ls and eshell/rm tab completes differently. While eshell/ls has the behavior I expect(sortof) eshell/rm has a rater "disturbing" querk...

lets say you have ~/Download/this_dir/somefile.txt

You go to $ ls ~/Download/this_dir/ and tab complete ls will complete to the file. However, if you do the same with rm it will cycle through the following outputs

$ rm ~/Download/this_dir/somefile.txt
$ rm ~/Download/this_dir/./
$ rm ~/Download/this_dir/../

notice the last entry points to the parent directory (ouch). I (may be to my own fault) if I expect only one file in this directory press tab a number of times just to make sure I am at the top which made me cycle to the parent directory entry, which is hard to see if the filepath/name is long and hit enter.

Additional Investigation

I realized that the TAB key is bound to pcomplete which is discussed here but I haven't found the exact thing to help me.


1 Answer 1


The following analysis/example applies to *nix operating systems:

eshell/rm and eshell/ls are elisp implementations of rm and ls. They do not control the functionality of completions within eshell.

The function pcomplete/rm within pcmpl-unix.el uses pcomplete-all-entries instead of pcomplete-entries. The difference is that the former let-binds as nil the variables pcomplete-file-ignore and pcomplete-dir-ignore.

If the user loads the module em-cmpl, then pcomplete-file-ignore is set locally to the value of eshell-cmpl-file-ignore and pcomplete-dir-ignore is set locally to the value of eshell-cmpl-dir-ignore.

Because the original poster has not specified whether the library/module em-cmpl has been loaded, the following example simply hard-codes the value for pcomplete-file-ignore and pcomplete-dir-ignore. As alluded to above, we want to be able to take advantage of the variables to ignore files and directores -- so we use pcomplete-entries instead of pcomplete-all-entries.

(require 'pcmpl-unix)

(defun pcomplete/rm ()
  "Completion for `rm'."
  (let* (
      (pcomplete-file-ignore nil)
      (pcomplete-dir-ignore "^../$\\|^./$")
      (pcomplete-help "(fileutils)rm invocation"))
    (pcomplete-opt "dfirRv")
    (while (pcomplete-here (pcomplete-entries) nil 'expand-file-name))))
  • Thanks for the answer. I'm on a *nix system and also just verified that em-cmpl library loads when I run M-x eshell. I will look in to the variables you suggested and see if I need to redefine pcomplete/rm
    – Sparx
    Aug 17, 2015 at 12:43
  • 1
    You should look at pcomplete-all-entries to see how it binds pcomplete-file-ignore to nil and pcomplete-dir-ignore to nil. If you continue to permit pcomplete/rm to use pcomplete-all-entries instead of pcomplete-entries, then changing the value of the variables will never have the intended effect. The name of the function at issue strongly hints at its intended purpose -- i.e. all of the entries.
    – lawlist
    Aug 17, 2015 at 15:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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