unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Generation of tags for the current project on the fly
@ 2018-01-12  1:02 Dmitry Gutov
  2018-01-12  9:01 ` Eli Zaretskii
  0 siblings, 1 reply; 49+ messages in thread
From: Dmitry Gutov @ 2018-01-12  1:02 UTC (permalink / raw)
  To: emacs-devel

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

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.

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.

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

What do people think?

See the attached patch.

[-- Attachment #2: project-auto-tags.diff --]
[-- Type: text/x-patch, Size: 2796 bytes --]

diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index a31668e1ba..b0c398ec8e 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -2109,7 +2109,9 @@ etags-xref-find-definitions-tag-order
   "Tag order used in `xref-backend-definitions' to look for definitions.")
 
 ;;;###autoload
-(defun etags--xref-backend () 'etags)
+(defun etags--xref-backend ()
+  (etags--maybe-use-project-tags)
+  'etags)
 
 (cl-defmethod xref-backend-identifier-at-point ((_backend (eql etags)))
   (find-tag--default))
@@ -2180,6 +2182,53 @@ xref-make-etags-location
     (nth 1 tag-info)))
 
 \f
+;;; Simple tags generation, with automatic invalidation
+
+(defvar etags--project-tags-file nil)
+
+(defun etags--maybe-use-project-tags ()
+  (let (proj)
+    (when (and (not (or tags-file-name
+                        tags-table-list))
+               (setq proj (project-current)))
+      (etags--project-tags-generate proj)
+      ;; Invalidate the scanned tags after any change is written to disk.
+      (add-hook 'after-save-hook #'etags--project-tags-cleanup)
+      (visit-tags-table etags--project-tags-file)
+      ;; Explicit return, this is no backend function.
+      nil)))
+
+(defun etags--project-tags-generate (proj)
+  (let* ((root (cl-find default-directory
+                        (project-roots proj)
+                        :test #'file-in-directory-p))
+         (default-directory root)
+         (files (all-completions "" (project-file-completion-table proj (list root))))
+         (etags-command (executable-find "etags"))
+         ;; FIXME: List all extensions, or wait for etags fix.
+         ;; http://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00323.html
+         (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))))
+
+(defun etags--project-tags-cleanup ()
+  (when etags--project-tags-file
+    (delete-file etags--project-tags-file)
+    (setq tags-file-name nil
+          tags-table-list nil
+          etags--project-tags-file nil))
+  (remove-hook 'after-save-hook #'etags--project-tags-cleanup))
+
 (provide 'etags)
 
 ;;; etags.el ends here

^ permalink raw reply related	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2020-12-08 22:26 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-12  1:02 Generation of tags for the current project on the fly Dmitry Gutov
2018-01-12  9:01 ` Eli Zaretskii
2018-01-12 13:52   ` Dmitry Gutov
2018-01-12 18:52     ` Eli Zaretskii
2018-01-14  2:05       ` Dmitry Gutov
2018-01-14 16:21         ` Eli Zaretskii
2018-01-15  1:44           ` Dmitry Gutov
2018-01-15  5:37             ` Eli Zaretskii
2018-01-15 18:50               ` Dmitry Gutov
2018-01-16 17:50                 ` Eli Zaretskii
2018-01-16 21:56                   ` Dmitry Gutov
2018-01-17 15:40                     ` Eli Zaretskii
2018-01-17 19:43                       ` Dmitry Gutov
2018-01-17 20:12                         ` Eli Zaretskii
2018-01-17 22:19                           ` Dmitry Gutov
2018-01-17 22:28                             ` Dmitry Gutov
2018-01-17 22:02                 ` Tom Tromey
2018-01-17 22:44                   ` Dmitry Gutov
2018-01-17 23:20                     ` Tom Tromey
2018-01-18  0:14                       ` Dmitry Gutov
2018-01-18  1:30                         ` Dmitry Gutov
2018-01-19  1:21                         ` Dmitry Gutov
2018-01-20 22:15                           ` Tom Tromey
2018-01-20 23:57                           ` Tom Tromey
2018-01-21 12:26                             ` Dmitry Gutov
2018-01-30  4:45                               ` Tom Tromey
2018-02-04 23:32                                 ` Dmitry Gutov
2018-01-30  5:05                               ` Tom Tromey
2018-02-04 23:40                                 ` Dmitry Gutov
2018-02-05 17:06                                   ` Eli Zaretskii
2018-02-05 20:10                                     ` Dmitry Gutov
2018-02-06 19:36                                       ` Eli Zaretskii
2018-02-06 20:41                                         ` Dmitry Gutov
2018-02-07  3:26                                           ` Eli Zaretskii
2018-02-07  9:47                                             ` Dmitry Gutov
2018-02-07 21:30                                               ` Tom Tromey
2018-02-09  9:41                                                 ` Dmitry Gutov
2018-02-08 20:31                                               ` John Yates
2018-02-09  0:22                                                 ` Dmitry Gutov
2020-12-08 22:26                       ` Dmitry Gutov
2018-01-17 11:08               ` Dmitry Gutov
2018-01-15  1:50           ` John Yates
2018-01-15  5:42             ` Eli Zaretskii
2018-01-15 15:01               ` Dmitry Gutov
2018-01-15 17:21                 ` Eli Zaretskii
2018-01-15 17:45                   ` Dmitry Gutov
2018-01-15 20:56                     ` Matthias Meulien
2018-01-15 21:44                       ` Dmitry Gutov
2018-01-15 16:33               ` John Yates

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).