3

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.

Sparx
  • 1,111
  • 9
  • 20

1 Answers1

2

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))))
lawlist
  • 18,826
  • 5
  • 37
  • 118
  • 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 '15 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 '15 at 15:05