[Top][All Lists]

[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 01:21:30 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Thunderbird/41.0

Hi Stephen,

We've discussed this before: I think this approach adds too much infrastructure (like forces through bits of "flat" project support, which aren't optimal for most of the projects I know of).

Why not just implement completion on file paths relative to the project root? The user could input a base file name, if they like, and TAB would expand it to one of the relative paths if it's unique, or allow them to input a directory. You won't need any other uniquification then.

On 09/15/2015 11:23 PM, Stephen Leake wrote:
Attached is a patch that implements find-file-project, with completion
of file-name on the project search path. It handles duplicate filenames
by uniquifying them witht trailing directory names.

Maybe call it find-file-in-project?

The patch also adds small projects for elisp and global, to show that
this approach works for multiple backends.

I don't see the elisp backend.

Regarding global, is there no related semantic-symref-tool command? Maybe it would make sense to implement this in a generic fashion.

> I can break this into smaller commits on master, if that seems like a
good idea.

If you want to test it out, please commit it to a feature branch instead.

I didn't add a NEWS entry. I don't think we are putting project related
changes in NEWS yet, since it is all new in Emacs 25. But the
file-name-all-completion change needs a NEWS entry.

We will add NEWS entries before the release.

+(defun find-file-complete-global (filename)
+  "Prompt for completion of FILENAME in a Gnu global project."
+    (setq filename
+         (completing-read
+          "file: " ;; prompt
+          (completion-table-with-cache #'find-file-complete-global-table) ;; 
+          nil ;; predicate
+          t ;; require match
+          filename
+          ))

I don't think each implementation should do its own completing-read. Rather, they should just return the completion table from a generic method. E.g. (cl-defmethod project-file-completion-table ...).

+    ;; and the user completes to the first, the following global call
+    ;; will return both. The desired result is always the shortest.

I'd say the better match wins (not the shortest path), but if you want to add sorting, completion-metadata can include display-sort-function.

+;;; project.el integration
+(defun project-try-global (dir)
+  (when (cedet-gnu-global-version-check t)
+    (let ((root (locate-dominating-file dir "GTAGS")))
+      (when root
+       (list 'global root)))))
+(cl-defmethod project-find-file ((prj (head global)) filename)
+  (let ((default-directory (file-name-as-directory (nth 1 prj))))
+    (find-file (find-file-complete-global filename))))

...if you're sure it's a good idea. After all, GNU Global is just a tool, it doesn't (and cannot) know too much about a project.

If it's used as just-another project implementation, you won't be able to integrate it with some more advanced kind of project definition.

+(defconst find-file-uniquify-regexp "^\\(.*\\)<\\(.*\\)>"
+  "Regexp matching uniqufied file name.
+Match 1 is the filename, match 2 is the relative directory.")

This is way complicated. completion-at-point interface will help with typing, no real need to shorten the file names.

Another benefit of delegating all that to a completion table, is that different kinds of frontends would be able to use it.

+;; Conversion between recursive and flat paths.
+(defun project--directory-directories-1 (dir ignore-regexp)
+(defun project--directory-directories-recurse (dir ignore-regexp)
+(defun project-recursive-ignores-to-flat (recursive-path ignore-dirs)
+(defun project-flat-to-recursive-ignores (flat-path)
+(cl-defgeneric project-ignore-dirs (_prj)
> ...
+(cl-defgeneric project-flat-search-path (prj)

Do you really need all this?

+  ;; FIXME: do we need both project-ignores and project-ignore-files-globs?

Just having project-ignores should suffice.

reply via email to

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