From d5151cbc463abd992455994ae7e02db32b8e7300 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 4 Oct 2024 14:39:50 +0300 Subject: [PATCH] Fix 'list-tags' when invoked from a non-file buffer This use case was broken by the improvement that attempts to offer the current buffer's file name as the default file whose tags to list. * lisp/progmodes/etags.el (tags--get-current-buffer-name-in-tags-file): Doc fix. Return nil if no file is associated with the current buffer, and avoid signaling an error if 'buffer-file-name' returns nil. (Bug#37611) (list-tags): Doc fix. Signal an error if the user specifies no file name at the prompt. * doc/emacs/maintaining.texi (List Identifiers): Fix wording of the documentation of 'list-tags'. (cherry picked from commit e9dcf0c57ddea6a3ac3136e82cdb740326e735d4) --- doc/emacs/maintaining.texi | 15 +++++++-------- lisp/progmodes/etags.el | 37 +++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 74ee4db00fe..713bded25ad 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -2672,14 +2672,13 @@ loaded, this command can use it to generate completion candidates. @xref{Symbol Completion}. @findex list-tags - @kbd{M-x list-tags} reads the name of one of the files covered by -the selected tags table, and displays a list of tags defined in that -file. Do not include a directory as part of the file name unless the -file name recorded in the tags table includes a directory. This -command works only with the etags backend, and requires a tags table -for the project to be available. @xref{Tags Tables}. If used -interactively, the default tag is file name of the current buffer if -used interactively. + @kbd{M-x list-tags} reads the name of one of the files covered by the +selected tags table, with completion, and displays the list of tags +defined in that file; it offers the current buffer's file name as the +default file whose tags to list. Do not include a directory as part of +the file name unless the file name recorded in the tags table includes a +directory. This command works only with the etags backend, and requires +a tags table for the project to be available. @xref{Tags Tables}. @findex tags-next-file @kbd{M-x tags-next-file} visits files covered by the selected tags table. diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index 90b0259696d..22fdcf17c98 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -1883,27 +1883,40 @@ description of the arguments." (try-completion string (tags-table-files) predicate)))) (defun tags--get-current-buffer-name-in-tags-file () - "Get the file name that the current buffer corresponds in the tags file." - (let ((tag-dir - (save-excursion - (visit-tags-table-buffer) - (file-name-directory (buffer-file-name))))) - (file-relative-name (buffer-file-name) tag-dir))) + "Return file name that corresponds to the current buffer in the tags table. +This returns the file name which corresponds to the current buffer relative +to the directory of the current tags table (see `visit-tags-table-buffer'). +If no file is associated with the current buffer, this function returns nil." + (let ((buf-fname (buffer-file-name))) + ;; FIXME: Are there interesting cases where 'buffer-file-name' + ;; returns nil, but there's some file we expect to find in TAGS that + ;; is associated with the buffer? The obvious cases of Dired and + ;; Info buffers are not interesting for TAGS, but are there any + ;; others? + (if buf-fname + (let ((tag-dir + (save-excursion + (visit-tags-table-buffer) + (file-name-directory buf-fname)))) + (file-relative-name buf-fname tag-dir))))) ;;;###autoload (defun list-tags (file &optional _next-match) "Display list of tags in file FILE. -This searches only the first table in the list, and no included -tables. FILE should be as it appeared in the `etags' command, -usually without a directory specification. If called -interactively, FILE defaults to the file name of the current -buffer." +Interactively, prompt for FILE, with completion, offering the current +buffer's file name as the defaul. +This command searches only the first table in the list of tags tables, +and does not search included tables. +FILE should be as it was submitted to the `etags' command, which usually +means relative to the directory of the tags table file." (interactive (list (completing-read "List tags in file: " 'tags-complete-tags-table-file nil t - ;; Default FILE to the current buffer. + ;; Default FILE to the current buffer's file. (tags--get-current-buffer-name-in-tags-file)))) + (if (string-empty-p file) + (user-error "You must specify a file name")) (with-output-to-temp-buffer "*Tags List*" (princ (substitute-command-keys "Tags in file `")) (tags-with-face 'highlight (princ file)) -- 2.39.2