emacs-devel
[Top][All Lists]
Advanced

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

Re: Generation of tags for the current project on the fly


From: Eli Zaretskii
Subject: Re: Generation of tags for the current project on the fly
Date: Fri, 12 Jan 2018 11:01:06 +0200

> From: Dmitry Gutov <address@hidden>
> Date: Fri, 12 Jan 2018 04:02:06 +0300
> 
> Here's an idea I've been working on. We generate tags for all files the 
> current project contains (except the ignored ones) when the user calls 
> one of the xref commands, but hasn't explicitly visited any tags table.
> 
> The result is used until they make a change in a file somewhere and save 
> the buffer, then the generated table is discarded.

Why discard it after the first save?  The tags table is probably still
very much valid.  I'd not discard it until either of the following
happens:

  . we fail to find a tag
  . the user visits a tags table explicitly
  . the user switches to a different project(?)

> I think it will be helpful for new users (who don't really know how to 
> generate tags), as well as people who are used to certain other editors 
> performing the indexing automatically, in small-to-medium sized 
> projects. With some effort, we could implement re-indexing and 
> invalidation on a more granular level (so it's usable in bigger projects 
> too), but transitioning to GNU Global would probably be better.

We could offer generating a tags table if we don't find one in the
tree, instead of generating it automatically.  I think this would be a
better UI and UX, especially given the time it could take to generate
TAGS (see below).

> For reference, indexing the Emacs sources takes ~1.1sec here.

Was that with cold cache or warm cache?

"make TAGS" takes about 9 sec here with a warm cache, and this is an
SSD disk.  On fencepost.gnu.org, a (somewhat slow) GNU/Linux system,
it took 12 sec with a cold cache and 4 sec with a warm cache.  And
Emacs is not a large project; I wonder what would happen in larger
ones, like GCC or glibc.

IOW, I don't think this is so fast that we could do that without user
approval.

> +         (extensions '("rb" "js" "py" "pl" "el" "c" "cpp" "cc" "h" "hh" "hpp"
> +                       "java" "go" "cl" "lisp" "prolog" "php" "erl" "hrl"
> +                       "F" "f" "f90" "for" "cs" "a" "asm" "ads" "adb" "ada"))
> +         (file-regexp (format "\\.%s\\'" (regexp-opt extensions))))
> +    (setq etags--project-tags-file (make-temp-file "emacs-project-tags-"))
> +    (with-temp-buffer
> +      (mapc (lambda (f)
> +              (when (string-match-p file-regexp f)
> +                (insert f "\n")))
> +            files)
> +      (shell-command-on-region (point-min) (point-max)
> +                               (format "%s - -o %s" etags-command 
> etags--project-tags-file)
> +                               nil nil "*etags-project-tags-errors*" t))))

I don't understand why you didn't use the commonly used form:

   find . -name "*.rb" -o -name "*.js" ... | etags -o- -

Doing things the way you did raises issues with encoding of file
names, which could cause subtle problem in rare use cases.  I think
using 'find' is also faster.

More generally, I think doing this that way is not TRT, at least not
by default.  "make TAGS" in Emacs will produce a much richer tags
table than your method, because our Makefiles use regexps to augment
the automatic tagging in etags.  So I think we should first try to
invoke the TAGS target of a Makefile in the tree, if one exists, and
only use the naïve command as fallback.  And perhaps we should also
provide some customization for the command to be used (but that will
obviously not help newbies who didn't yet customize the project they
are working on).

Thanks.



reply via email to

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