[Top][All Lists]

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

Re: project.el semantics

From: Stephen Leake
Subject: Re: project.el semantics
Date: Sun, 08 Nov 2015 01:11:27 -0600
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (windows-nt)

Dmitry Gutov <address@hidden> writes:

> Please see the commit 9776972 inside the branch project-next. I intend
> to merge it into master in a day or two.

The new project.el has:

(defvar project-library-roots-function 'etags-library-roots
  "Function that returns a list of library roots.

It should return a list of directories that contain source files
related to the current buffer.  Depending on the language, it
should include the headers search path, load path, class path,
and so on.

And later:

(cl-defgeneric project-library-roots (project)
  "Return the list of source root directories.

It's the list of directories outside of the current project that
contain related source files.

Project-specific version of `project-library-roots-function',
which see.  Unless it knows better, a specialized implementation
should use the value returned by that function."

These are inconsistent.

It would be best for the project-library-roots-function doc string to
_only_ refer to cl-defgeneric (ie, "default implementation of
`project-libary-roots'"), so you don't have duplicate documentation that
gets out of sync.

And then:

(cl-defgeneric project-roots (project)
  "Return the list of directory roots belonging to the current project.

Most often it's just one directory, which contains the project
file and everything else in the project.  But in more advanced
configurations, a project can span multiple directories.

The rule of tumb for whether to include a directory here, and not
in `project-library-roots', is whether its contents are meant to
be edited together with the rest of the project.

The directory names should be absolute.")

You seem to be trying to establish a difference between "a single
project" and "the libraries used by a project". Better terminology would
be "top level project" and "dependencies"; not all dependencies are
libraries. It would be helpful to make this distinction more explicit.

The default implementation of project-library-roots makes the lists
disjoint, so the doc strings should say that. In particular,
"load path" and "class path" contain _both_ the top level project and
the dependencies, so project-library-roots should _not_ be the same as
"load path" or "class path".

The advice in project-roots on "include here but not there" should
mention top-level vs dependencies.

On the other hand, `project-library-roots ((project (head vc))' does
_not_ make them disjoint, so there is a bug here somewhere.

The new function `project-find-regexp' is not consistent with other
usage; other project- search functions search both top level and

> Also see the FIXME commentary above project-library-roots-function;
> it's waiting for the public opinion. Though it's not really about
> source vs documentation as much as about different kinds of sources.

That FIXME: says, in part:

;; FIXME: Using the current approach, we don't have access to the
;; "library roots" of language A from buffers of language B, which
;; seems desirable in multi-language projects, at least for some
;; potential uses, like "jump to a file in project or library".

emacs-lisp-mode makes project-library-roots-function buffer-local,
which makes it language-specific. That's an argument for overriding the
default implementation of project-library-roots to do something more
useful. Which is what `project-library-roots ((project (head vc))' does,
for example. Which means that the behavior of projects in an elisp file
that happens to be in a vc directory is different from one that is not. 

No other language mode sets project-library-roots-function.

The root cause of this problem is trying to infer a project in an elisp
file. This makes sense in general, because an elisp file implies the use
of load-path, which is the main part of defining a project. A better way
is to provide a project-find-function that returns an elisp-project
object in elisp buffers; then elisp-project can override
project-library-roots to return load-path; it could also add the emacs C
sources if they are available.

That leaves the default behavior in non-elisp files that are also not in
a vc directory; they currently use 'etags-library-roots. You could
change the default definition of project-library-roots to use
etags-library-roots directly, but it seems better to have a variable for

I would delete the advice that overriding functions should use
project-library-roots-function; the main reason to override is to do
something different.

I have no problems merging this branch to master; it makes things better
in most places, and no worse in any. Howver, it would be best to clean
up the inconsistencies above first.

-- Stephe

reply via email to

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