emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: find-file-project


From: Dmitry Gutov
Subject: Re: find-file-project
Date: Wed, 16 Sep 2015 20:25:12 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Thunderbird/41.0

On 09/16/2015 07:41 PM, Stephen Leake wrote:

By "root" I guess you mean the argument "dir", since that is an element
of the recursive project-search-path.

Yes. A root, or a search-path element.

project-search-path returns (".../dir1" ".../dir2" ".../dir3"); thus

As documented, project-search-path should return absolute file names. Though it's not terribly important for this example, since the code below could call file-relative-name first.

project-ignores is only called with one of these three values. (I'm
ignoring project-roots, because I don't understand when it would be
different from project-search-path).

Indeed, the logic should be pretty similar. But the external project-search-path entries usually doesn't have any ignored directories, whereas there are often ignored dirs inside project-roots, usually configured via .gitignore or the project file.

The user wants to ignore "*/*.elc", "*/*.dvi", "*/*.exe",
"dir2/dir21/obj/*", "dir2/dir21/*.text", "dir3/dir31/*.dvi".

So one implementation of project-ignores could be:

(cond
  ((string-equal dir ".../dir1")
   '("*.elc" "*.dvi" "*.exe"))

  ((string-equal dir ".../dir2")
   '("*.elc" "*.dvi" "*.exe" "./dir2/dir21/obj/" "dir2/dir21/*.text"))

  ((string-equal dir ".../dir3")
   '("*.elc" "*.dvi" "*.exe" "./dir3/dir31/*.dvi"))

)

I suppose. Or you could simply return the whole list each time, and leave it to 'find' to apply the ignores appropriately. Not sure what the performance hit will be. There might be false positives as well.

Then find-file-path-completion-table could take a recursive
project-search-path as the "path" argument, and recurse thru the
directory tree, calling project-ignores at each directory, with a parent
directory from project-search-path as the argument, and comparing the
path of each file - relative to the parent directory - to the glob
patterns.

I would just call 'find' for each "root" directory, pass it the appropriate ignores each time, and then parse its output.

If you must traverse the trees in Lisp, holding on to the ignores list of each tree root seems like a trivial optimization.

For example, when processing dir2/dir21, it calls (project-ignores
"dir2"), and compares "./dir2/dir21/obj/" to "dir2/dir21/obj", and
"*.exe" to "dir2/dir21/foo.exe", both yeilding "ignore".

Is that right?

It could, though the paths will be absolute.

I gather this was designed to match the semantics of find?

Yes, it's to be compatible with both 'find' and '.gitignore' formats. The notion of "anchoring to root" comes from .gitignore.

Since the compare for directories is different from that for files, it
would simplify the use of project-ignores (at least for this use case)
if it was split into project-ignore-files and project-ignore-dirs. Or
took an arg to specify that.

Well... an entry that doesn't end with a slash, in .gitignore, will ignore both files and directories with that name.

So for full compatibility, we'd have to include all ignore-files entries into the ignore-dirs entries. That's pretty awkward.

I was stuck on using a flat path for find-file-path-completion-table
because I started out trying to reuse locate-file-completion-table. But
now that I'm implementing the completion function from scratch, and it
is reading the disk and ignoring some files anyway, it does make more
sense start with a recursive path.

Thank you. I was hoping you'd come to that conclusion.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]