unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: etags.el tags-search use global syntax table
@ 2007-07-17 11:49 Francesco Potorti`
  0 siblings, 0 replies; 9+ messages in thread
From: Francesco Potorti` @ 2007-07-17 11:49 UTC (permalink / raw)
  To: Emacs developers

isaac.to@gmail.com:
>When using AucTeX to edit some LaTeX files, I want to search for some
>word globally.  My version is not new enough to support inter-file
>searching directly, so I've used tags-search.  I'm searching for
>something like "\bx\b".  It turned out that some of the matches are
>missed, because $ is considered as a word (as in the fundamental
>mode).  This is out of my expectation, since it is a LaTeX file and in
>the LaTeX mode of AucTeX, $ is considered not a word.  Perhaps when
>Emacs performs a tags-search it do it in a temp buffer which does not
>have the correct mode loaded?  I consider this a bug in etags.

This is indeed a bug in etags.el that was present in Emacs 21 and is
still there in Emacs 22.  It has nothing to do with Auctex, but pops up
whenever:
- you start a tags-search
- the file where you should see a match is not currently visited
- the search in Fundamental mode gives different results from the search
  in the proper mode of the buffer

The reason is that the next-file function in etags.el loads non-visited
files in a temporary buffer with insert-file-contents, rather than using
find-file, so the mode remains Fundamental.  I am not sure why it is so.
These are the relevant lines at the end of next-file:

      ;; Like find-file, but avoids random warning messages.
      (set-buffer (get-buffer-create " *next-file*"))
      (kill-all-local-variables)
      (erase-buffer)
      (setq new next)
      (insert-file-contents new nil))

Generally speaking, tags-search looks for all files in the TAGS file: if
they are visited, they are searched and when no match is found point is
restored.  If they are not visited, they are loaded into a temporary
buffer which is overwritten when no matches are found.  However, search
in this buffer is performed in Fundamental mode.

The cure is to use the syntax table relative to the natural mode of the
file when doing the search.  Is it really necessary to avoid using
find-file?  If yes, how can one guess the right syntax table and apply
it to the temporary buffer?

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

* Re: etags.el tags-search use global syntax table
       [not found] ` <E1IB1MF-0008Id-Cg@fencepost.gnu.org>
@ 2007-07-18 12:54   ` Francesco Potorti`
  2007-07-18 13:38     ` Andreas Schwab
  2007-07-19  4:25     ` Richard Stallman
  0 siblings, 2 replies; 9+ messages in thread
From: Francesco Potorti` @ 2007-07-18 12:54 UTC (permalink / raw)
  To: rms; +Cc: Emacs developers

>    The reason is that the next-file function in etags.el loads non-visited
>    files in a temporary buffer with insert-file-contents, rather than using
>    find-file, so the mode remains Fundamental.  I am not sure why it is so.
>
>There are two reasons for this.  One is that some major modes can be
>rather intrusive in what they do.  The other is that visiting a file
>is much slower.
>
>Of course, it was all based on the idea that it wouldn't really matter
>for searching, and if it actually finds a match, then it visits the
>file properly.  This bug shows that the major mode does matter in some
>cases for searching.
>
>I am not sure whether it is better to fix this bug or not.
>If it is a big slowdown, we are better off not fixing it.

A reasonable compromise would be using for searching the same syntax
table of the buffer that is current when the tags-search command is
issued.  This would not work in various situations, but would work in
most cases, and probably would work in many more cases than the current
situation.

If nothing smarter comes up and no one does it first, I'll try to
implement that in the next days.

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

* Re: etags.el tags-search use global syntax table
  2007-07-18 12:54   ` etags.el tags-search use global syntax table Francesco Potorti`
@ 2007-07-18 13:38     ` Andreas Schwab
  2007-07-18 14:21       ` Francesco Potorti`
  2007-07-19  4:25     ` Richard Stallman
  1 sibling, 1 reply; 9+ messages in thread
From: Andreas Schwab @ 2007-07-18 13:38 UTC (permalink / raw)
  To: Francesco Potorti`; +Cc: rms, Emacs developers

Francesco Potorti` <pot@gnu.org> writes:

> A reasonable compromise would be using for searching the same syntax
> table of the buffer that is current when the tags-search command is
> issued.  This would not work in various situations, but would work in
> most cases, and probably would work in many more cases than the current
> situation.

You can initiate a tags search from any buffer, independent of the list
of files indexed by the tags file, thus you may get different results
depending on where you started it.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: etags.el tags-search use global syntax table
  2007-07-18 13:38     ` Andreas Schwab
@ 2007-07-18 14:21       ` Francesco Potorti`
  0 siblings, 0 replies; 9+ messages in thread
From: Francesco Potorti` @ 2007-07-18 14:21 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: rms, Emacs developers

>> A reasonable compromise would be using for searching the same syntax
>> table of the buffer that is current when the tags-search command is
>> issued.  This would not work in various situations, but would work in
>> most cases, and probably would work in many more cases than the current
>> situation.
>
>You can initiate a tags search from any buffer, independent of the list
>of files indexed by the tags file, thus you may get different results
>depending on where you started it.

Yes.  Until now we have two different ways to go:

1. Leave everything as it is.  This means that invoking tags-search on
   Latex files will not recover the "\bx\b" pattern even if some of the
   files contain the "$x = y*z" string, no matter form where you start
   the search

2. Apply the change I propose.  This means that the search will recover
   the desiderd pattern in the usual case of starting the search from a
   Latex buffer, but will not recover it if you start the search from a
   text buffer

Does anyone have any opinion on the above alternatives, or any
additional alternative to suggest?

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

* Re: etags.el tags-search use global syntax table
  2007-07-18 12:54   ` etags.el tags-search use global syntax table Francesco Potorti`
  2007-07-18 13:38     ` Andreas Schwab
@ 2007-07-19  4:25     ` Richard Stallman
  2007-07-19 16:49       ` Francesco Potorti`
  1 sibling, 1 reply; 9+ messages in thread
From: Richard Stallman @ 2007-07-19  4:25 UTC (permalink / raw)
  To: Francesco Potorti`; +Cc: emacs-devel

    A reasonable compromise would be using for searching the same syntax
    table of the buffer that is current when the tags-search command is
    issued.

That is not always right.  If you want to fix this, I'm sure you could
make etags first look up auto-mode-alist manually, without actually setting
the major mode, then have its own alist mapping mode functions into
syntax tables.

Or it could actually apply the major mode.  That might still be a lot
faster than visiting the file.  If (get MODE 'mode-class) is `special'
then it would not apply the major mode.

You could try that, and see if the slowdown is enough to be a real
reason not to do it.

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

* Re: etags.el tags-search use global syntax table
  2007-07-19  4:25     ` Richard Stallman
@ 2007-07-19 16:49       ` Francesco Potorti`
  2007-07-20 13:42         ` Richard Stallman
  0 siblings, 1 reply; 9+ messages in thread
From: Francesco Potorti` @ 2007-07-19 16:49 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

This is a first try at applying the major mode to files that are loaded
by etags.el's next-file.  It works in the single test case I tried.  If
I am following the correct road, I will check that nothing is broken by
these changes and I will make speed tests, so please comment.

================================================================
--- etags.el	25 Feb 2007 15:54:43 +0100	1.194
+++ etags.el	19 Jul 2007 18:40:46 +0200	
@@ -1701,10 +1701,11 @@ if the file was newly read in, the value
 	(set-buffer (find-file-noselect next novisit))
       ;; Like find-file, but avoids random warning messages.
       (set-buffer (get-buffer-create " *next-file*"))
-      (kill-all-local-variables)
       (erase-buffer)
       (setq new next)
-      (insert-file-contents new nil))
+      (insert-file-contents new nil)
+      (let ((buffer-file-name new))
+	(set-auto-mode t (list 'special))))
     new))
 
 (defvar tags-loop-operate nil
================================================================

The above works because I modified set-auto-mode to accept one more
optional argument, as detailed in the following addition to the help
string:

+The optional argument KEEP-IF-CLASS is a list of symbols. If the
+major mode has any of these symbols in its mode-class property, or if
+one the symbols in the list is t, we do not set the major mode."

================================================================
--- files.el	19 Jul 2007 18:00:42 +0200	1.913
+++ files.el	19 Jul 2007 18:46:14 +0200	
@@ -2218,8 +2218,8 @@ If FUNCTION is nil, then it is not calle
   "Upper limit on `magic-mode-alist' regexp matches.
 Also applies to `magic-fallback-mode-alist'.")
 
-(defun set-auto-mode (&optional keep-mode-if-same)
-  "Select major mode appropriate for current buffer.
+(defun set-auto-mode (&optional keep-if-same keep-if-class)
+  "Select major mode appropriate for current buffer and return it.
 
 To find the right major mode, this function checks for a -*- mode tag,
 checks if it uses an interpreter listed in `interpreter-mode-alist',
@@ -2233,9 +2233,13 @@ Local Variables section of the file; for
 If `enable-local-variables' is nil, this function does not check for a
 -*- mode tag.
 
-If the optional argument KEEP-MODE-IF-SAME is non-nil, then we
+If the optional argument KEEP-IF-SAME is non-nil, then we
 set the major mode only if that would change it.  In other words
-we don't actually set it to the same mode the buffer already has."
+we don't actually set it to the same mode the buffer already has.
+
+The optional argument KEEP-IF-CLASS is a list of symbols. If the
+major mode has any of these symbols in its mode-class property, or if
+one the symbols in the list is t, we do not set the major mode."
   ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
   (let (end done mode modes)
     ;; Find a -*- mode tag
@@ -2270,7 +2274,7 @@ we don't actually set it to the same mod
 	    (if (not (functionp mode))
 		(message "Ignoring unknown mode `%s'" mode)
 	      (setq done t)
-	      (or (set-auto-mode-0 mode keep-mode-if-same)
+	      (or (setq mode (set-auto-mode-0 mode keep-if-same keep-if-class))
 		  ;; continuing would call minor modes again, toggling them off
 		  (throw 'nop nil))))))
     ;; If we didn't, look for an interpreter specified in the first line.
@@ -2287,11 +2291,11 @@ we don't actually set it to the same mod
 	    done (assoc (file-name-nondirectory mode)
 			interpreter-mode-alist))
       ;; If we found an interpreter mode to use, invoke it now.
-      (if done
-	  (set-auto-mode-0 (cdr done) keep-mode-if-same)))
+      (when done
+	(setq mode (set-auto-mode-0 (cdr done) keep-if-same keep-if-class))))
     ;; Next try matching the buffer beginning against magic-mode-alist.
     (unless done
-      (if (setq done (save-excursion
+      (when (setq done (save-excursion
 		       (goto-char (point-min))
 		       (save-restriction
 			 (narrow-to-region (point-min)
@@ -2302,7 +2306,7 @@ we don't actually set it to the same mod
 					  (if (functionp re)
 					      (funcall re)
 					    (looking-at re)))))))
-	  (set-auto-mode-0 done keep-mode-if-same)))
+	(setq mode (set-auto-mode-0 done keep-if-same keep-if-class))))
     ;; Next compare the filename against the entries in auto-mode-alist.
     (unless done
       (if buffer-file-name
@@ -2335,11 +2339,11 @@ we don't actually set it to the same mod
 			name (substring name 0 (match-beginning 0)))
 		(setq name))
 	      (when mode
-		(set-auto-mode-0 mode keep-mode-if-same)
+		(setq mode (set-auto-mode-0 mode keep-if-same keep-if-class))
 		(setq done t))))))
     ;; Next try matching the buffer beginning against magic-fallback-mode-alist.
     (unless done
-      (if (setq done (save-excursion
+      (when (setq done (save-excursion
 		       (goto-char (point-min))
 		       (save-restriction
 			 (narrow-to-region (point-min)
@@ -2350,20 +2354,28 @@ we don't actually set it to the same mod
 					  (if (functionp re)
 					      (funcall re)
 					    (looking-at re)))))))
-	  (set-auto-mode-0 done keep-mode-if-same)))))
+	(setq mode (set-auto-mode-0 done keep-if-same keep-if-class))))
+    mode))
 
-;; When `keep-mode-if-same' is set, we are working on behalf of
+;; When `keep-if-same' is set, we are working on behalf of
 ;; set-visited-file-name.  In that case, if the major mode specified is the
 ;; same one we already have, don't actually reset it.  We don't want to lose
 ;; minor modes such as Font Lock.
-(defun set-auto-mode-0 (mode &optional keep-mode-if-same)
+(defun set-auto-mode-0 (mode &optional keep-if-same keep-if-class)
   "Apply MODE and return it.
-If optional arg KEEP-MODE-IF-SAME is non-nil, MODE is chased of
+If optional arg KEEP-IF-SAME is non-nil, MODE is chased of
 any aliases and compared to current major mode.  If they are the
-same, do nothing and return nil."
-  (unless (and keep-mode-if-same
+same, do nothing and return nil.
+
+The optional argument KEEP-IF-CLASS is a list of symbols. If the
+major mode has any of these symbols in its mode-class property, or if
+one the symbols in the list is t, we do not set the major mode."
+  (unless (or
+	   (and keep-if-same
 	       (eq (indirect-function mode)
 		   (indirect-function major-mode)))
+	   (memq t keep-if-class)
+	   (memq (get mode 'mode-class) keep-if-class))
     (when mode
       (funcall mode)
       mode)))
================================================================

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

* Re: etags.el tags-search use global syntax table
  2007-07-19 16:49       ` Francesco Potorti`
@ 2007-07-20 13:42         ` Richard Stallman
  2007-07-21 16:58           ` Francesco Potorti`
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Stallman @ 2007-07-20 13:42 UTC (permalink / raw)
  To: Francesco Potorti`; +Cc: emacs-devel

    +The optional argument KEEP-IF-CLASS is a list of symbols. If the
    +major mode has any of these symbols in its mode-class property, or if
    +one the symbols in the list is t, we do not set the major mode."

I am not sure what that means.  Does it mean that if I pass (t foo)
for KEEP-IF-CLASS, then set-auto-mode will certainly not set the major
mode?

That is what the words seem to say -- but it doesn't seem useful.
What's the point of calling set-auto-mode and never setting the major mode?

Also, if you want a way to do that, why make the signal be a list
containing t?  Why not just pass t as the argument?  Why make it a
list if the rest of the list is irrelevant?

One other question.  Since set-auto-mode doesn't look at mode: local
bindings, is it sufficient?


Aside from that, it looks good.  Next question is how fast it runs.

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

* Re: etags.el tags-search use global syntax table
  2007-07-20 13:42         ` Richard Stallman
@ 2007-07-21 16:58           ` Francesco Potorti`
  2007-07-22 10:05             ` Richard Stallman
  0 siblings, 1 reply; 9+ messages in thread
From: Francesco Potorti` @ 2007-07-21 16:58 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

>    +The optional argument KEEP-IF-CLASS is a list of symbols. If the
>    +major mode has any of these symbols in its mode-class property, or if
>    +one the symbols in the list is t, we do not set the major mode."
>
>I am not sure what that means.  Does it mean that if I pass (t foo)
>for KEEP-IF-CLASS, then set-auto-mode will certainly not set the major
>mode?

Yes.

>That is what the words seem to say -- but it doesn't seem useful.
>What's the point of calling set-auto-mode and never setting the major mode?

Those three lines were meant to present the gist of the change, that is,
an abstract of the following patch.  But I made another change, that is,
the patched set-auto-mode returns the chosen mode.  I think this may be
useful for programs that want to know which mode a buffer should be in,
but do not want to set it.

>Also, if you want a way to do that, why make the signal be a list
>containing t?  Why not just pass t as the argument?  Why make it a
>list if the rest of the list is irrelevant?

Yes, passing just t would certainly be clearer.  I thought that having
always a list would be simpler to use and possibly more flexible, but I
would certainly make that change if you think it is best.

>One other question.  Since set-auto-mode doesn't look at mode: local
>bindings, is it sufficient?

Well, no, it is not.  I had overlooked that problem, thanks.

>Aside from that, it looks good.  Next question is how fast it runs.

When I manage to find some more time, I'll look into the mode: local
bindings and do some speed tests.  

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

* Re: etags.el tags-search use global syntax table
  2007-07-21 16:58           ` Francesco Potorti`
@ 2007-07-22 10:05             ` Richard Stallman
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Stallman @ 2007-07-22 10:05 UTC (permalink / raw)
  To: Francesco Potorti`; +Cc: emacs-devel

      But I made another change, that is,
    the patched set-auto-mode returns the chosen mode.  I think this may be
    useful for programs that want to know which mode a buffer should be in,
    but do not want to set it.

    >Also, if you want a way to do that, why make the signal be a list
    >containing t?  Why not just pass t as the argument?  Why make it a
    >list if the rest of the list is irrelevant?

    Yes, passing just t would certainly be clearer.  I thought that having
    always a list would be simpler to use and possibly more flexible, but I
    would certainly make that change if you think it is best.

Please use just t for that meaning, and document why it's useful.

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

end of thread, other threads:[~2007-07-22 10:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <E1IAlXn-000690-C1@tucano.isti.cnr.it>
     [not found] ` <E1IB1MF-0008Id-Cg@fencepost.gnu.org>
2007-07-18 12:54   ` etags.el tags-search use global syntax table Francesco Potorti`
2007-07-18 13:38     ` Andreas Schwab
2007-07-18 14:21       ` Francesco Potorti`
2007-07-19  4:25     ` Richard Stallman
2007-07-19 16:49       ` Francesco Potorti`
2007-07-20 13:42         ` Richard Stallman
2007-07-21 16:58           ` Francesco Potorti`
2007-07-22 10:05             ` Richard Stallman
2007-07-17 11:49 Francesco Potorti`

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).