all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Etags completion problem for local tags table
@ 2008-02-19 23:27 Radey Shouman
  0 siblings, 0 replies; 4+ messages in thread
From: Radey Shouman @ 2008-02-19 23:27 UTC (permalink / raw)
  To: gnu-emacs-bug

In (at least) emacs 22.1, completing reads for find-tag and list-tags
will use the global tags table list even if a local tags file has
been specified using a prefix argument for visit-tags-table.

To reproduce, visit two files, in the first buffer visit a tags file
globally, in the second a different tags file locally.  From the
second buffer, try M.[TAB] .  The tag list displayed will correspond
to the first, globally visited, tags file.

A patch that works for me is appended.

*** etags.el.dist	2007-01-21 03:20:46.000000000 -0500
--- etags.el	2008-02-19 17:46:44.592353300 -0500
***************
*** 257,262 ****
--- 257,264 ----
    "Function to do the work of `tags-included-tables' (which see).")
  (defvar verify-tags-table-function nil
    "Function to return t iff current buffer contains valid tags file.")
+ (defvar etags-calling-buffer nil
+   "Buffer from which a completing read was made, so we can determine the appropriate tags file to visit.")
  \f
  ;; Initialize the tags table in the current buffer.
  ;; Returns non-nil iff it is a valid tags table.  On
***************
*** 315,321 ****
        (setq file tags-file-name)))
    (if local
        ;; Set the local value of tags-file-name.
!       (set (make-local-variable 'tags-file-name) file)
      ;; Set the global value of tags-file-name.
      (setq-default tags-file-name file)))
  
--- 317,325 ----
        (setq file tags-file-name)))
    (if local
        ;; Set the local value of tags-file-name.
!       (progn
!         (set (make-local-variable 'tags-file-name) file)
!         (set (make-local-variable 'tags-table-list) nil))
      ;; Set the global value of tags-file-name.
      (setq-default tags-file-name file)))
  
***************
*** 751,756 ****
--- 755,762 ----
  	  (let (current-table combined-table)
  	    (message "Making tags completion table for %s..." buffer-file-name)
  	    (save-excursion
+               (if etags-calling-buffer
+                   (set-buffer etags-calling-buffer))
  	      ;; Iterate over the current list of tags tables.
  	      (while (visit-tags-table-buffer (and combined-table t))
  		;; Find possible completions in this table.
***************
*** 772,777 ****
--- 778,785 ----
  ;; but builds tags-completion-table on demand.
  (defun tags-complete-tag (string predicate what)
    (save-excursion
+     (if etags-calling-buffer
+         (set-buffer etags-calling-buffer))
      ;; If we need to ask for the tag table, allow that.
      (let ((enable-recursive-minibuffers t))
        (visit-tags-table-buffer))
***************
*** 781,787 ****
  \f
  ;; Read a tag name from the minibuffer with defaulting and completion.
  (defun find-tag-tag (string)
!   (let* ((completion-ignore-case (if (memq tags-case-fold-search '(t nil))
  				     tags-case-fold-search
  				   case-fold-search))
  	 (default (funcall (or find-tag-default-function
--- 789,796 ----
  \f
  ;; Read a tag name from the minibuffer with defaulting and completion.
  (defun find-tag-tag (string)
!   (let* ((etags-calling-buffer (current-buffer))
!          (completion-ignore-case (if (memq tags-case-fold-search '(t nil))
  				     tags-case-fold-search
  				   case-fold-search))
  	 (default (funcall (or find-tag-default-function
***************
*** 1834,1839 ****
--- 1843,1850 ----
  \f
  (defun tags-complete-tags-table-file (string predicate what)
    (save-excursion
+     (if etags-calling-buffer
+         (set-buffer etags-calling-buffer))
      ;; If we need to ask for the tag table, allow that.
      (let ((enable-recursive-minibuffers t))
        (visit-tags-table-buffer))




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

* Re: Etags completion problem for local tags table
       [not found] <mailman.7663.1203474863.18990.bug-gnu-emacs@gnu.org>
@ 2008-04-04  0:55 ` Stefan Monnier
  2008-04-24 19:03 ` Radey Shouman
       [not found] ` <mailman.10789.1209074215.18990.bug-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 4+ messages in thread
From: Stefan Monnier @ 2008-04-04  0:55 UTC (permalink / raw)
  To: Radey Shouman; +Cc: gnu-emacs-bug

> In (at least) emacs 22.1, completing reads for find-tag and list-tags
> will use the global tags table list even if a local tags file has
> been specified using a prefix argument for visit-tags-table.

> To reproduce, visit two files, in the first buffer visit a tags file
> globally, in the second a different tags file locally.  From the
> second buffer, try M.[TAB] .  The tag list displayed will correspond
> to the first, globally visited, tags file.

> A patch that works for me is appended.

Thank you, it should be fixed on the trunk now,


        Stefan




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

* Re: Etags completion problem for local tags table
       [not found] <mailman.7663.1203474863.18990.bug-gnu-emacs@gnu.org>
  2008-04-04  0:55 ` Stefan Monnier
@ 2008-04-24 19:03 ` Radey Shouman
       [not found] ` <mailman.10789.1209074215.18990.bug-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 4+ messages in thread
From: Radey Shouman @ 2008-04-24 19:03 UTC (permalink / raw)
  To: gnu-emacs-bug

Radey Shouman <shouman@comcast.net> writes:

> In (at least) emacs 22.1, completing reads for find-tag and list-tags
> will use the global tags table list even if a local tags file has
> been specified using a prefix argument for visit-tags-table.
> 
> To reproduce, visit two files, in the first buffer visit a tags file
> globally, in the second a different tags file locally.  From the
> second buffer, try M.[TAB] .  The tag list displayed will correspond
> to the first, globally visited, tags file.

The patch presented earlier had problems - the root issue is that
variables tags-file-name and tags-table-list are used for returning
information from functions which may change the current buffer.

One manifestation of the problem can be seen by setting a local tags
file using C-uM-x visit-tags-table twice in the same buffer.  The
second attempt will fail to set a local tags table, but will set the
global tags table.

This patch also modifies visit-tags-table so that it will remove a
local tags table if present in the buffer in which it is called to set
a global tags table.  This is arguably not a bug fix, but seems much
less suprising than the current behavior.

*** etags.el.dist	2007-01-21 03:20:46.000000000 -0500
--- etags.el	2008-04-24 09:57:37.660821100 -0400
***************
*** 257,262 ****
--- 257,264 ----
    "Function to do the work of `tags-included-tables' (which see).")
  (defvar verify-tags-table-function nil
    "Function to return t iff current buffer contains valid tags file.")
+ (defvar etags-calling-buffer nil
+   "Buffer from which a completing read was made, so we can determine the appropriate tags file to visit.")
  \f
  ;; Initialize the tags table in the current buffer.
  ;; Returns non-nil iff it is a valid tags table.  On
***************
*** 305,323 ****
    ;; Calling visit-tags-table-buffer with tags-file-name set to FILE will
    ;; initialize a buffer for FILE and set tags-file-name to the
    ;; fully-expanded name.
!   (let ((tags-file-name file))
      (save-excursion
        (or (visit-tags-table-buffer file)
  	  (signal 'file-error (list "Visiting tags table"
  				    "file does not exist"
! 				    file)))
!       ;; Set FILE to the expanded name.
!       (setq file tags-file-name)))
    (if local
        ;; Set the local value of tags-file-name.
        (set (make-local-variable 'tags-file-name) file)
      ;; Set the global value of tags-file-name.
!     (setq-default tags-file-name file)))
  
  (defun tags-table-check-computed-list ()
    "Compute `tags-table-computed-list' from `tags-table-list' if necessary."
--- 307,335 ----
    ;; Calling visit-tags-table-buffer with tags-file-name set to FILE will
    ;; initialize a buffer for FILE and set tags-file-name to the
    ;; fully-expanded name.
!   (let (table-list)
!     (let ((tags-file-name file)
!           (tags-table-list tags-table-list))
        (save-excursion
          (or (visit-tags-table-buffer file)
              (signal 'file-error (list "Visiting tags table"
                                        "file does not exist"
!                                       file))))
!       ;; Set FILE to the expanded name.  Note that we have to do this from the original
!       ;; buffer, in case tags-file-name or tags-table-list are buffer-local.
!       (setq file tags-file-name
!             table-list tags-table-list))
! 
      (if local
          ;; Set the local value of tags-file-name.
+         (progn
            (set (make-local-variable 'tags-file-name) file)
+           (set (make-local-variable 'tags-table-list) table-list))
        ;; Set the global value of tags-file-name.
!       (kill-local-variable 'tags-file-name)
!       (kill-local-variable 'tags-table-list)
!       (setq tags-file-name file
!             tags-table-list table-list))))
  
  (defun tags-table-check-computed-list ()
    "Compute `tags-table-computed-list' from `tags-table-list' if necessary."
***************
*** 444,459 ****
  	  (revert-buffer t t)
  	  (tags-table-mode)))
      (and (file-exists-p file)
! 	 (progn
  	   (set-buffer (find-file-noselect file))
  	   (or (string= file buffer-file-name)
  	       ;; find-file-noselect has changed the file name.
  	       ;; Propagate the change to tags-file-name and tags-table-list.
  	       (let ((tail (member file tags-table-list)))
  		 (if tail
  		     (setcar tail buffer-file-name))
  		 (if (eq file tags-file-name)
! 		     (setq tags-file-name buffer-file-name))))
  	   (tags-table-mode)))))
  
  ;; Subroutine of visit-tags-table-buffer.  Search the current tags tables
--- 456,475 ----
  	  (revert-buffer t t)
  	  (tags-table-mode)))
      (and (file-exists-p file)
! 	 (let ((obuf (current-buffer)))
  	   (set-buffer (find-file-noselect file))
  	   (or (string= file buffer-file-name)
  	       ;; find-file-noselect has changed the file name.
  	       ;; Propagate the change to tags-file-name and tags-table-list.
+                ;; We have to do this in the buffer current when we were called
+                ;; because tags-table-list and tags-file-name may be buffer local.
+                (save-excursion
+                  (set-buffer obuf)
                   (let ((tail (member file tags-table-list)))
                     (if tail
                         (setcar tail buffer-file-name))
                     (if (eq file tags-file-name)
!                        (setq tags-file-name buffer-file-name)))))
  	   (tags-table-mode)))))
  
  ;; Subroutine of visit-tags-table-buffer.  Search the current tags tables
***************
*** 538,543 ****
--- 554,564 ----
   `tags-file-name', `tags-table-list', `tags-table-list-pointer'.
  Returns t if it visits a tags table, or nil if there are no more in the list."
  
+   ;; We may be called from a minibuffer if invoked during completion.
+   ;; this can be a problem when the tags tables are buffer-local.
+   (if etags-calling-buffer
+       (set-buffer etags-calling-buffer))
+ 
    ;; Set tags-file-name to the tags table file we want to visit.
    (cond ((eq cont 'same)
  	 ;; Use the ambient value of tags-file-name.
***************
*** 781,787 ****
  \f
  ;; Read a tag name from the minibuffer with defaulting and completion.
  (defun find-tag-tag (string)
!   (let* ((completion-ignore-case (if (memq tags-case-fold-search '(t nil))
  				     tags-case-fold-search
  				   case-fold-search))
  	 (default (funcall (or find-tag-default-function
--- 802,809 ----
  \f
  ;; Read a tag name from the minibuffer with defaulting and completion.
  (defun find-tag-tag (string)
!   (let* ((etags-calling-buffer (current-buffer))
!          (completion-ignore-case (if (memq tags-case-fold-search '(t nil))
  				     tags-case-fold-search
  				   case-fold-search))
  	 (default (funcall (or find-tag-default-function




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

* Re: Etags completion problem for local tags table
       [not found] ` <mailman.10789.1209074215.18990.bug-gnu-emacs@gnu.org>
@ 2008-04-29 20:08   ` Radey Shouman
  0 siblings, 0 replies; 4+ messages in thread
From: Radey Shouman @ 2008-04-29 20:08 UTC (permalink / raw)
  To: gnu-emacs-bug

Radey Shouman <shouman@comcast.net> writes:

> Radey Shouman <shouman@comcast.net> writes:
> 
> > In (at least) emacs 22.1, completing reads for find-tag and list-tags
> > will use the global tags table list even if a local tags file has
> > been specified using a prefix argument for visit-tags-table.
> > 
> > To reproduce, visit two files, in the first buffer visit a tags file
> > globally, in the second a different tags file locally.  From the
> > second buffer, try M.[TAB] .  The tag list displayed will correspond
> > to the first, globally visited, tags file.
> 
> The patch presented earlier had problems - the root issue is that
> variables tags-file-name and tags-table-list are used for returning
> information from functions which may change the current buffer.
> 
> One manifestation of the problem can be seen by setting a local tags
> file using C-uM-x visit-tags-table twice in the same buffer.  The
> second attempt will fail to set a local tags table, but will set the
> global tags table.
> 
> This patch also modifies visit-tags-table so that it will remove a
> local tags table if present in the buffer in which it is called to set
> a global tags table.  This is arguably not a bug fix, but seems much
> less suprising than the current behavior.

Yet another patch, this one additionally fixes tags-query-replace and
other users of next-file.  The current etags.el fails when using
tags-query-replace with buffer-local tags tables (expand-file is
called with an argument of nil).


*** /local/emacs/emacs-22.1/lisp/progmodes/etags.el.dist	2007-01-21 03:20:46.000000000 -0500
--- etags.el	2008-04-28 15:05:35.044759300 -0400
***************
*** 257,262 ****
--- 257,264 ----
    "Function to do the work of `tags-included-tables' (which see).")
  (defvar verify-tags-table-function nil
    "Function to return t iff current buffer contains valid tags file.")
+ (defvar etags-calling-buffer nil
+   "Buffer from which a completing read was made, so we can determine the appropriate tags file to visit.")
  \f
  ;; Initialize the tags table in the current buffer.
  ;; Returns non-nil iff it is a valid tags table.  On
***************
*** 305,323 ****
    ;; Calling visit-tags-table-buffer with tags-file-name set to FILE will
    ;; initialize a buffer for FILE and set tags-file-name to the
    ;; fully-expanded name.
!   (let ((tags-file-name file))
!     (save-excursion
!       (or (visit-tags-table-buffer file)
! 	  (signal 'file-error (list "Visiting tags table"
! 				    "file does not exist"
! 				    file)))
!       ;; Set FILE to the expanded name.
!       (setq file tags-file-name)))
!   (if local
!       ;; Set the local value of tags-file-name.
!       (set (make-local-variable 'tags-file-name) file)
!     ;; Set the global value of tags-file-name.
!     (setq-default tags-file-name file)))
  
  (defun tags-table-check-computed-list ()
    "Compute `tags-table-computed-list' from `tags-table-list' if necessary."
--- 307,335 ----
    ;; Calling visit-tags-table-buffer with tags-file-name set to FILE will
    ;; initialize a buffer for FILE and set tags-file-name to the
    ;; fully-expanded name.
!   (let (table-list)
!     (let ((tags-file-name file)
!           (tags-table-list tags-table-list))
!       (save-excursion
!         (or (visit-tags-table-buffer file)
!             (signal 'file-error (list "Visiting tags table"
!                                       "file does not exist"
!                                       file))))
!       ;; Set FILE to the expanded name.  Note that we have to do this from the original
!       ;; buffer, in case tags-file-name or tags-table-list are buffer-local.
!       (setq file tags-file-name
!             table-list tags-table-list))
! 
!     (if local
!         ;; Set the local value of tags-file-name.
!         (progn
!           (set (make-local-variable 'tags-file-name) file)
!           (set (make-local-variable 'tags-table-list) table-list))
!       ;; Set the global value of tags-file-name.
!       (kill-local-variable 'tags-file-name)
!       (kill-local-variable 'tags-table-list)
!       (setq tags-file-name file
!             tags-table-list table-list))))
  
  (defun tags-table-check-computed-list ()
    "Compute `tags-table-computed-list' from `tags-table-list' if necessary."
***************
*** 444,459 ****
  	  (revert-buffer t t)
  	  (tags-table-mode)))
      (and (file-exists-p file)
! 	 (progn
  	   (set-buffer (find-file-noselect file))
  	   (or (string= file buffer-file-name)
  	       ;; find-file-noselect has changed the file name.
  	       ;; Propagate the change to tags-file-name and tags-table-list.
! 	       (let ((tail (member file tags-table-list)))
! 		 (if tail
! 		     (setcar tail buffer-file-name))
! 		 (if (eq file tags-file-name)
! 		     (setq tags-file-name buffer-file-name))))
  	   (tags-table-mode)))))
  
  ;; Subroutine of visit-tags-table-buffer.  Search the current tags tables
--- 456,475 ----
  	  (revert-buffer t t)
  	  (tags-table-mode)))
      (and (file-exists-p file)
! 	 (let ((obuf (current-buffer)))
  	   (set-buffer (find-file-noselect file))
  	   (or (string= file buffer-file-name)
  	       ;; find-file-noselect has changed the file name.
  	       ;; Propagate the change to tags-file-name and tags-table-list.
!                ;; We have to do this in the buffer current when we were called
!                ;; because tags-table-list and tags-file-name may be buffer local.
!                (save-excursion
!                  (set-buffer obuf)
!                  (let ((tail (member file tags-table-list)))
!                    (if tail
!                        (setcar tail buffer-file-name))
!                    (if (eq file tags-file-name)
!                        (setq tags-file-name buffer-file-name)))))
  	   (tags-table-mode)))))
  
  ;; Subroutine of visit-tags-table-buffer.  Search the current tags tables
***************
*** 538,543 ****
--- 554,564 ----
   `tags-file-name', `tags-table-list', `tags-table-list-pointer'.
  Returns t if it visits a tags table, or nil if there are no more in the list."
  
+   ;; We may be called from a minibuffer if invoked during completion.
+   ;; this can be a problem when the tags tables are buffer-local.
+   (if etags-calling-buffer
+       (set-buffer etags-calling-buffer))
+ 
    ;; Set tags-file-name to the tags table file we want to visit.
    (cond ((eq cont 'same)
  	 ;; Use the ambient value of tags-file-name.
***************
*** 781,787 ****
  \f
  ;; Read a tag name from the minibuffer with defaulting and completion.
  (defun find-tag-tag (string)
!   (let* ((completion-ignore-case (if (memq tags-case-fold-search '(t nil))
  				     tags-case-fold-search
  				   case-fold-search))
  	 (default (funcall (or find-tag-default-function
--- 802,809 ----
  \f
  ;; Read a tag name from the minibuffer with defaulting and completion.
  (defun find-tag-tag (string)
!   (let* ((etags-calling-buffer (current-buffer))
!          (completion-ignore-case (if (memq tags-case-fold-search '(t nil))
  				     tags-case-fold-search
  				   case-fold-search))
  	 (default (funcall (or find-tag-default-function
***************
*** 1658,1682 ****
  	((eq initialize t)
  	 ;; Initialize the list from the tags table.
  	 (save-excursion
! 	   ;; Visit the tags table buffer to get its list of files.
! 	   (visit-tags-table-buffer)
! 	   ;; Copy the list so we can setcdr below, and expand the file
! 	   ;; names while we are at it, in this buffer's default directory.
! 	   (setq next-file-list (mapcar 'expand-file-name (tags-table-files)))
! 	   ;; Iterate over all the tags table files, collecting
! 	   ;; a complete list of referenced file names.
! 	   (while (visit-tags-table-buffer t)
! 	     ;; Find the tail of the working list and chain on the new
! 	     ;; sublist for this tags table.
! 	     (let ((tail next-file-list))
! 	       (while (cdr tail)
! 		 (setq tail (cdr tail)))
! 	       ;; Use a copy so the next loop iteration will not modify the
! 	       ;; list later returned by (tags-table-files).
! 	       (if tail
! 		   (setcdr tail (mapcar 'expand-file-name (tags-table-files)))
! 		 (setq next-file-list (mapcar 'expand-file-name
! 					      (tags-table-files))))))))
  	(t
  	 ;; Initialize the list by evalling the argument.
  	 (setq next-file-list (eval initialize))))
--- 1680,1705 ----
  	((eq initialize t)
  	 ;; Initialize the list from the tags table.
  	 (save-excursion
!            (let ((etags-calling-buffer (current-buffer)))
!              ;; Visit the tags table buffer to get its list of files.
!              (visit-tags-table-buffer)
!              ;; Copy the list so we can setcdr below, and expand the file
!              ;; names while we are at it, in this buffer's default directory.
!              (setq next-file-list (mapcar 'expand-file-name (tags-table-files)))
!              ;; Iterate over all the tags table files, collecting
!              ;; a complete list of referenced file names.
!              (while (visit-tags-table-buffer t)
!                ;; Find the tail of the working list and chain on the new
!                ;; sublist for this tags table.
!                (let ((tail next-file-list))
!                  (while (cdr tail)
!                    (setq tail (cdr tail)))
!                  ;; Use a copy so the next loop iteration will not modify the
!                  ;; list later returned by (tags-table-files).
!                  (if tail
!                      (setcdr tail (mapcar 'expand-file-name (tags-table-files)))
!                    (setq next-file-list (mapcar 'expand-file-name
!                                                 (tags-table-files)))))))))
  	(t
  	 ;; Initialize the list by evalling the argument.
  	 (setq next-file-list (eval initialize))))




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

end of thread, other threads:[~2008-04-29 20:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-19 23:27 Etags completion problem for local tags table Radey Shouman
     [not found] <mailman.7663.1203474863.18990.bug-gnu-emacs@gnu.org>
2008-04-04  0:55 ` Stefan Monnier
2008-04-24 19:03 ` Radey Shouman
     [not found] ` <mailman.10789.1209074215.18990.bug-gnu-emacs@gnu.org>
2008-04-29 20:08   ` Radey Shouman

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.