tags:

views:

233

answers:

3

I have lots of directories filled with a bunch of TeX documents. So, there's lots of files with the same base filename and different extensions. Only one of them, though, is editable. I'd like a way to convince Emacs that if I'm in a directory where I've got

document.tex
document.log
document.pdf
document.bbl
document.aux
...

and I'm in the minibuffer and do

~/Documents/.../doc<TAB>

it fills in 'document.tex', because that's the only really properly editable document in that directory. Anybody know of a good way to do that?

+1  A: 

Probably the easiest way to do this in your case is just to customize the variable "completion-ignored-extensions".

However, this will mean that emacs always ignores things like ".log" and ".pdf" which may not be what you want. If you want it to be more selective, you may have to effectively re-implement the function file-name-completion.

simon
+1  A: 

If you are open to installing a large-ish library and reading some documentation, you could take a look at Icicles and define a sort function that meets your needs. An alternative is ido whose wiki page has an example of sorting by mtime, which should be easy to change to sort by a function of the filename extension.

Jouni K. Seppänen
+4  A: 

I've written some code that should do what you want. The basic idea is to set the variable 'completion-ignored-extensions to match the extensions you want to skip, but only when there are .tex files present. This code does that.

(defadvice find-file-read-args (around find-file-read-args-limit-choices activate)
  "set some stuff up for controlling extensions when tab completing"
  (let ((completion-ignored-extensions completion-ignored-extensions)
        (find-file-limit-choices t))
    ad-do-it))

(defadvice minibuffer-complete (around minibuffer-complete-limit-choices nil activate)
  "When in find-file, check for files of extension .tex, and if they're found, ignore .log .pdf .bbl .aux"
  (let ((add-or-remove
     (if (and (boundp 'find-file-limit-choices) find-file-limit-choices
       (save-excursion
  (let ((b (progn (beginning-of-line) (point)))
        (e (progn (end-of-line) (point))))
    (directory-files (file-name-directory (buffer-substring-no-properties b e)) nil "\\.tex$"))))
  'add-to-list
       'remove)))
(mapc (lambda (e) (setq completion-ignored-extensions
   (funcall add-or-remove 'completion-ignored-extensions e)))
      '(".log" ".pdf" ".bbl" ".aux")))
  ad-do-it)

Enjoy.

Trey Jackson
I'm getting an undefined function error for 'mapcq' -- is that provided by an elisp package I should load?
Charles Pence
I should mention I tried 'mapc' and 'mapchar' and neither worked. This looks great, though, thanks!
Charles Pence
The mapcq was a typo, i fixed it. mapc worked for me in that the code does what I expected. One issue might be that the code isn't activated, perhaps. Try adding a (y-or-n-p "Running?") just before the mapc line, and when you do TAB, you should be prompted. If you're not, then the advice isn't activated (for some reason), and you can try adding (ad-activate 'minibuffer-complete-limit-choices). I didn't need that when I tested this in a vanilla emacs.
Trey Jackson
That's got it! Works wonderfully, with mapc and a slightly longer list of ignored extensions (which is my fault, of course).Thanks so much!
Charles Pence