all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stephen Leake <stephen_leake@stephe-leake.org>
To: Dmitry Gutov <dgutov@yandex.ru>
Cc: emacs-devel <emacs-devel@gnu.org>
Subject: Re: make project--find-in-file generic, add interactive filename to project-find-file
Date: Thu, 28 Jan 2016 05:06:37 -0600	[thread overview]
Message-ID: <86k2mu7yki.fsf@stephe-leake.org> (raw)
In-Reply-To: <86si1i813n.fsf@stephe-leake.org> (Stephen Leake's message of "Thu, 28 Jan 2016 04:11:56 -0600")

[-- Attachment #1: Type: text/plain, Size: 744 bytes --]

Stephen Leake <stephen_leake@stephe-leake.org> writes:

> Dmitry Gutov <dgutov@yandex.ru> writes:
>
>> On 01/28/2016 04:04 AM, Stephen Leake wrote:
>>> Any objections to the attached patch?
>>
>
>> - More importantly, the new generic function should not do too much.
>> It should return a completion table, which can dispatch to ede,
>> ada-mode, or any other facility. I believe we've went over this a
>> couple of times already.
>
> So instead of computing `table' in project--find-file-in, it would
> call (project--file-completion-table dirs project). The default
> implementation of `project--file-completion-table' would be the code
> using `find-program'.
>
> I'll give that a try.

That works nicely; new patch attached.

-- 
-- Stephe

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: project-find-file-patch.diff --]
[-- Type: text/x-patch, Size: 4840 bytes --]

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 85f3907..41dc810 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -154,6 +154,14 @@ project--find-in-directory
     vc-directory-exclusion-list)
    grep-find-ignored-files))
 
+(cl-defgeneric project--file-completion-table (_project _dirs)
+  "Return a completion table for files in directories DIRS in PROJECT.
+If non-nil, DIRS is a list of absolute directories; it should be some
+subset of the project roots and external roots. If nil, the backend
+uses all the directories it knows about.
+PROJECT is used to find the project ignores and other project meta-data."
+  )
+
 (defgroup project-vc nil
   "Project implementation using the VC package."
   :version "25.1"
@@ -313,51 +321,57 @@ project--find-regexp-in
 
 ;;;###autoload
 (defun project-find-file ()
-  "Visit a file in the current project's roots.
-
-This is like `find-file', but it limits the file-name completion
-candidates to the files within the current project roots."
+  "Visit a file (with completion) in the current project's roots.
+The completion default is the filename at point, if one is
+recognized."
   (interactive)
   (let* ((pr (project-current t))
          (dirs (project-roots pr)))
-    (project--find-file-in dirs pr)))
+    (project--find-file-in (thing-at-point 'filename) dirs pr)))
 
 ;;;###autoload
 (defun project-or-external-find-file ()
   "Visit a file in the current project's roots or external roots.
-
-This is like `find-file', but it limits the file-name completion
-candidates to the files within the current project roots and external roots."
+The completion default is the filename at point, if one is
+recognized."
   (interactive)
   (let* ((pr (project-current t))
          (dirs (append
                 (project-roots pr)
                 (project-external-roots pr))))
-    (project--find-file-in dirs pr)))
+    (project--find-file-in (thing-at-point 'filename) dirs pr)))
 
 ;; FIXME: Uniquely abbreviate the roots?
-(defun project--find-file-in (dirs project)
+(cl-defmethod project--file-completion-table (project dirs)
+  "Default implementation using `find-program'."
   (require 'xref)
-  (let* ((all-files
-          (cl-mapcan
-           (lambda (dir)
-             (let ((command
-                    (format "%s %s %s -type f -print0"
-                            find-program
-                            dir
-                            (xref--find-ignores-arguments
-                             (project-ignores project dir)
-                             (expand-file-name dir)))))
-               (split-string (shell-command-to-string command) "\0" t)))
-           dirs))
-         (table (lambda (string pred action)
-                  (cond
-                   ((eq action 'metadata)
-                    '(metadata . ((category . project-file))))
-                   (t
-                    (complete-with-action action all-files string pred))))))
-    (find-file
-     (completing-read "Find file: " table nil t))))
+  (let ((all-files
+	 (cl-mapcan
+	  (lambda (dir)
+	    (let ((command
+		   (format "%s %s %s -type f -print0"
+			   find-program
+			   dir
+			   (xref--find-ignores-arguments
+			    (project-ignores project dir)
+			    (expand-file-name dir)))))
+	      (split-string (shell-command-to-string command) "\0" t)))
+	  dirs)))
+    (lambda (string pred action)
+      (cond
+       ((eq action 'metadata)
+	'(metadata . ((category . project-file))))
+       (t
+	(complete-with-action action all-files string pred))))
+    ))
+
+(defun project--find-file-in (filename dirs project)
+  "Complete FILENAME in DIRS in PROJECT, visit the file."
+  (find-file
+   (completing-read
+    (format "Find file (%s): " filename)
+    (project--file-completion-table project dirs)
+    nil t nil nil filename)))
 
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 267853d..2fd7297 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -854,6 +854,7 @@ xref-etags-mode
 (declare-function semantic-symref-find-references-by-name "semantic/symref")
 (declare-function semantic-find-file-noselect "semantic/fw")
 (declare-function grep-expand-template "grep")
+(defvar ede-minor-mode) ;; ede.el
 
 (defun xref-collect-references (symbol dir)
   "Collect references to SYMBOL inside DIR.
@@ -948,6 +949,9 @@ xref--rgrep-command
    (xref--find-ignores-arguments ignores dir)))
 
 (defun xref--find-ignores-arguments (ignores dir)
+  "Convert IGNORES and DIR to a list of arguments for 'find'.
+IGNORES is a list of glob patterns.  DIR is an absolute
+directory, used as the root of the ignore globs."
   ;; `shell-quote-argument' quotes the tilde as well.
   (cl-assert (not (string-match-p "\\`~" dir)))
   (when ignores

  parent reply	other threads:[~2016-01-28 11:06 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-28  1:04 make project--find-in-file generic, add interactive filename to project-find-file Stephen Leake
2016-01-28  9:21 ` Dmitry Gutov
2016-01-28 10:11   ` Stephen Leake
2016-01-28 10:36     ` Dmitry Gutov
2016-01-28 13:14       ` Stefan Monnier
2016-01-28 19:32         ` Dmitry Gutov
2016-01-28 21:11           ` Stefan Monnier
2016-01-28 21:22             ` Dmitry Gutov
2016-01-28 22:44               ` Stefan Monnier
2016-01-29  2:10                 ` Dmitry Gutov
2016-01-29  2:57                   ` Stefan Monnier
2016-01-29  4:20                     ` Dmitry Gutov
2016-01-29 14:05                       ` Stefan Monnier
2016-01-29 21:53                         ` Dmitry Gutov
2016-01-31  6:18                           ` Stefan Monnier
2016-01-31 14:02                             ` Dmitry Gutov
2016-01-31 14:23                               ` Stefan Monnier
2016-02-01  8:08                                 ` Dmitry Gutov
2016-02-01 13:40                                   ` Stefan Monnier
2016-01-29  2:05             ` Dmitry Gutov
2016-01-29  2:55               ` Stefan Monnier
2016-01-29  4:11                 ` Dmitry Gutov
2016-01-29 14:03                   ` Stefan Monnier
2016-01-29 21:35                     ` Dmitry Gutov
2016-01-30  2:07                       ` Stefan Monnier
2016-01-30 23:32               ` Juri Linkov
2016-01-31  0:40                 ` Dmitry Gutov
2016-01-28 11:06     ` Stephen Leake [this message]
2016-01-28 11:11       ` Stephen Leake
2016-01-29  2:18       ` Dmitry Gutov
2016-01-29 23:55         ` Stephen Leake
2016-01-30  0:15           ` Dmitry Gutov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86k2mu7yki.fsf@stephe-leake.org \
    --to=stephen_leake@stephe-leake.org \
    --cc=dgutov@yandex.ru \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.