unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* `Q' in Dired - be able to skip the rest of one file and move on to the next
@ 2008-01-02  7:34 Drew Adams
  2008-01-03  9:50 ` Richard Stallman
  0 siblings, 1 reply; 20+ messages in thread
From: Drew Adams @ 2008-01-02  7:34 UTC (permalink / raw)
  To: Emacs-Devel

Let me know if I'm overlooking something, but AFAIK:

`Q' in Dired just runs query-replace-regexp over the marked files. In
effect, it treats all of those files together as one big file. That means,
for instance, that you cannot use it to easily confirm a couple changes in
one file and then skip the other occurrences in that file, move on to the
next file, and so on.

AFAICT, you must always visit each occurrence in one file before moving on
to the next file. (Or else you can of course quit altogether, unmark the
file you're through with, and then hit `Q' again.)

Is this correct? If so, what do you use for this? I used to use `Q' quite a
lot, but it's been a while. I guess I'm so used to Icicles that I've gotten
spoiled. (In Icicles, you can directly access search hits that you might
want to replace, without going through them in order, and you can remove
selected hits from consideration, including all those remaining for a given
file.)

What about adding something to `Q' that lets you move on to the next file,
without quitting query-replacing altogether?

I suggested a while back that you be able to do replacement using `grep'
output, and IIRC Kim implemented that, so I guess that using that feature
together with `grep-find' would provide something like what I'm suggesting,
but it would still be good to be able to do it from within `Q'.

I'm surprised that this isn't already available (if it isn't), since it
seems like a natural extension of query-replace to multiple files: You can
skip the rest of a normal query-replace, so you should be able to skip q-r
for the rest of a file, but without quitting q-r altogether.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move on to the next
  2008-01-02  7:34 `Q' in Dired - be able to skip the rest of one file and move on to the next Drew Adams
@ 2008-01-03  9:50 ` Richard Stallman
  2008-01-03 10:11   ` Andreas Schwab
  2008-01-03 15:56   ` Luc Teirlinck
  0 siblings, 2 replies; 20+ messages in thread
From: Richard Stallman @ 2008-01-03  9:50 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel

    AFAICT, you must always visit each occurrence in one file before moving on
    to the next file. (Or else you can of course quit altogether, unmark the
    file you're through with, and then hit `Q' again.)

I agree it would be good to have a way to skip to the start of the next file.
A natural interface for this would be to unmark each file just before starting
to search that file.  Then, quitting the command and resuming it will skip
that file.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move on to the next
  2008-01-03  9:50 ` Richard Stallman
@ 2008-01-03 10:11   ` Andreas Schwab
  2008-01-03 10:27     ` Miles Bader
  2008-01-03 15:56   ` Luc Teirlinck
  1 sibling, 1 reply; 20+ messages in thread
From: Andreas Schwab @ 2008-01-03 10:11 UTC (permalink / raw)
  To: rms; +Cc: Drew Adams, emacs-devel

Richard Stallman <rms@gnu.org> writes:

> I agree it would be good to have a way to skip to the start of the next file.
> A natural interface for this would be to unmark each file just before starting
> to search that file.  Then, quitting the command and resuming it will skip
> that file.

On the other hand, if you plan to do many operations on the same list of
files you don't want them to be automatically unmarked.  No dired
operation does that currently.

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] 20+ messages in thread

* Re: `Q' in Dired - be able to skip the rest of one file and move on to the next
  2008-01-03 10:11   ` Andreas Schwab
@ 2008-01-03 10:27     ` Miles Bader
  2008-01-03 16:17       ` Drew Adams
  0 siblings, 1 reply; 20+ messages in thread
From: Miles Bader @ 2008-01-03 10:27 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: rms, Drew Adams, emacs-devel

Andreas Schwab <schwab@suse.de> writes:
>> A natural interface for this would be to unmark each file just before starting
>> to search that file.  Then, quitting the command and resuming it will skip
>> that file.
>
> On the other hand, if you plan to do many operations on the same list of
> files you don't want them to be automatically unmarked.  No dired
> operation does that currently.

I often use the direct Q command multiple times in a row on the same set
of files.

The query-replace "!" command currently does "the right thing" (for the
positive case) when using as part of a Q invocation -- it replaces all
remaining entries in the current file, and then starts prompting again
in the text file.

So perhaps a new query-replace command, like "N" could be added, that
skips the rest of the file, but continues prompting in the next file?
For normal query-replace usage it would be equivalent to "q", but that
seems OK...

-Miles

-- 
Suburbia: where they tear out the trees and then name streets after them.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move on to the next
  2008-01-03  9:50 ` Richard Stallman
  2008-01-03 10:11   ` Andreas Schwab
@ 2008-01-03 15:56   ` Luc Teirlinck
  2008-01-03 16:18     ` `Q' in Dired - be able to skip the rest of one file and move onto " Drew Adams
  1 sibling, 1 reply; 20+ messages in thread
From: Luc Teirlinck @ 2008-01-03 15:56 UTC (permalink / raw)
  To: rms; +Cc: drew.adams, emacs-devel

Richard Stallman wrote:

   I agree it would be good to have a way to skip to the start of the
   next file.

There is such a way right now:

M-> M-,

More than good enough for me.

   A natural interface for this would be to unmark each file just
   before starting to search that file.  Then, quitting the command
   and resuming it will skip that file.

Yes, but the file would stay unmarked.  If I mark files, I often want
to perform several operations in sequence on them.  Anyway, quitting
and resuming seems at least at much work as M-> M-, (which is only two
keystrokes to begin with).

Sincerely,

Luc.

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

* RE: `Q' in Dired - be able to skip the rest of one file and move on to the next
  2008-01-03 10:27     ` Miles Bader
@ 2008-01-03 16:17       ` Drew Adams
  0 siblings, 0 replies; 20+ messages in thread
From: Drew Adams @ 2008-01-03 16:17 UTC (permalink / raw)
  To: Miles Bader, Andreas Schwab; +Cc: rms, emacs-devel

> So perhaps a new query-replace command, like "N" could be added, that
> skips the rest of the file, but continues prompting in the next file?
> For normal query-replace usage it would be equivalent to "q", but that
> seems OK...

That's what I was thinking of.

But the use case Richard raised is also useful - it avoids needing to quit,
unmark, and resume.

Perhaps there could be two different keys, one to skip to the next file and
the other to unmark this file and skip to the next.

More or less the same thing applies to `A', I think. But the UI is
different, so the solution might be different.

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

* RE: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-03 15:56   ` Luc Teirlinck
@ 2008-01-03 16:18     ` Drew Adams
  2008-01-03 21:32       ` Juri Linkov
  2008-01-05  5:54       ` Richard Stallman
  0 siblings, 2 replies; 20+ messages in thread
From: Drew Adams @ 2008-01-03 16:18 UTC (permalink / raw)
  To: Luc Teirlinck, rms; +Cc: emacs-devel

>    I agree it would be good to have a way to skip to the start of the
>    next file.
>
> There is such a way right now:
>
> M-> M-,
>
> More than good enough for me.

You're right, but I'm not sure it would occur to most people. Maybe it's a
tip worth documenting in the case of `Q' and `A'?

Even so, it might not be bad to provide a key to skip to the next file
without exiting query-replace.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-03 16:18     ` `Q' in Dired - be able to skip the rest of one file and move onto " Drew Adams
@ 2008-01-03 21:32       ` Juri Linkov
  2008-01-04  2:11         ` Bastien
  2008-01-05  5:54       ` Richard Stallman
  1 sibling, 1 reply; 20+ messages in thread
From: Juri Linkov @ 2008-01-03 21:32 UTC (permalink / raw)
  To: Drew Adams; +Cc: teirllm, rms, emacs-devel

> Even so, it might not be bad to provide a key to skip to the next file
> without exiting query-replace.

Another problem I have with `Q' is that it requires typing `!' in every
file to replace all occurrences.  So if I want to replace all occurrences
in ALL marked files at once without a query, I need typing `!' as many times
as there are marked files.

Maybe, when started by `Q', query-replace should apply `!' to all marked files,
and a new key `Y' should replace all remaining occurrences in the current file,
and a new key `N' should skip the current file as Miles has already proposed.

-- 
Juri Linkov
http://www.jurta.org/emacs/

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-03 21:32       ` Juri Linkov
@ 2008-01-04  2:11         ` Bastien
  2008-07-15  0:27           ` Juri Linkov
  0 siblings, 1 reply; 20+ messages in thread
From: Bastien @ 2008-01-04  2:11 UTC (permalink / raw)
  To: Juri Linkov; +Cc: teirllm, rms, Drew Adams, emacs-devel

Juri Linkov <juri@jurta.org> writes:

>> Even so, it might not be bad to provide a key to skip to the next file
>> without exiting query-replace.
>
> Another problem I have with `Q' is that it requires typing `!' in every
> file to replace all occurrences.  So if I want to replace all occurrences
> in ALL marked files at once without a query, I need typing `!' as many times
> as there are marked files.
>
> Maybe, when started by `Q', query-replace should apply `!' to all marked files,
> and a new key `Y' should replace all remaining occurrences in the current file,
> and a new key `N' should skip the current file as Miles has already proposed.

Agreed.  

There is also this little annoyance: when replacing all occurrences in
the *last* marked file, hitting `!' always returns this error:
 
  "All files processed"

-- 
Bastien

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-03 16:18     ` `Q' in Dired - be able to skip the rest of one file and move onto " Drew Adams
  2008-01-03 21:32       ` Juri Linkov
@ 2008-01-05  5:54       ` Richard Stallman
  2008-01-08  0:21         ` Juri Linkov
  1 sibling, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2008-01-05  5:54 UTC (permalink / raw)
  To: Drew Adams; +Cc: teirllm, emacs-devel

    You're right, but I'm not sure it would occur to most people. Maybe it's a
    tip worth documenting in the case of `Q' and `A'?

I will put that in the Emacs Manual
unless someone else does it first.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-05  5:54       ` Richard Stallman
@ 2008-01-08  0:21         ` Juri Linkov
  2008-01-08  0:33           ` Drew Adams
  2008-01-08  2:12           ` Luc Teirlinck
  0 siblings, 2 replies; 20+ messages in thread
From: Juri Linkov @ 2008-01-08  0:21 UTC (permalink / raw)
  To: rms; +Cc: teirllm, drew.adams, emacs-devel

>     You're right, but I'm not sure it would occur to most people. Maybe it's a
>     tip worth documenting in the case of `Q' and `A'?
>
> I will put that in the Emacs Manual
> unless someone else does it first.

I think this is too weird trick to quit the query-replace operation with M->
and resume it with tags-loop-continue M-,.  Maybe instead of this we should
try implementing native (i.e. without using etags) multi-file query-replace
similar to recently implemented multi-file isearch?

-- 
Juri Linkov
http://www.jurta.org/emacs/

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

* RE: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-08  0:21         ` Juri Linkov
@ 2008-01-08  0:33           ` Drew Adams
  2008-01-08 19:08             ` Richard Stallman
  2008-01-09  0:48             ` Juri Linkov
  2008-01-08  2:12           ` Luc Teirlinck
  1 sibling, 2 replies; 20+ messages in thread
From: Drew Adams @ 2008-01-08  0:33 UTC (permalink / raw)
  To: Juri Linkov, rms; +Cc: teirllm, emacs-devel

> I think this is too weird trick to quit the query-replace
> operation with M-> and resume it with tags-loop-continue M-,.
> Maybe instead of this we should try implementing native
> (i.e. without using etags) multi-file query-replace
> similar to recently implemented multi-file isearch?

What was wrong with your first suggestion (and Miles's):

>> Maybe, when started by `Q', query-replace should apply `!' to all
>> marked files, and a new key `Y' should replace all remaining
>> occurrences in the current file, and a new key `N' should skip
>> the current file as Miles has already proposed.

But I'd keep the single-file meaning of all keys, including `!', and use a
different key to replace all remaining occurrences in this file and the
other files. It's not good for a key (e.g. `!') to change meaning, depending
on whether one file or several are searched.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-08  0:21         ` Juri Linkov
  2008-01-08  0:33           ` Drew Adams
@ 2008-01-08  2:12           ` Luc Teirlinck
  2008-01-09  0:54             ` Juri Linkov
  1 sibling, 1 reply; 20+ messages in thread
From: Luc Teirlinck @ 2008-01-08  2:12 UTC (permalink / raw)
  To: juri; +Cc: rms, drew.adams, emacs-devel

Juri Linkov wrote:

   I think this is too weird trick to quit the query-replace operation
   with M-> and resume it with tags-loop-continue M-,

It is not a "trick", but a special case of a (to me) routine way to
skip a series of occurrences known to be irrelevant by simply moving
over them.  You can (and I routinely do), use not just M->, but _any_
motion command for that purpose.  I have no idea what is "weird",
unnatural or wrong about that.  It certainly is very useful.

Sincerely,

Luc.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-08  0:33           ` Drew Adams
@ 2008-01-08 19:08             ` Richard Stallman
  2008-01-09  0:48             ` Juri Linkov
  1 sibling, 0 replies; 20+ messages in thread
From: Richard Stallman @ 2008-01-08 19:08 UTC (permalink / raw)
  To: Drew Adams; +Cc: juri, teirllm, emacs-devel

I think that M-> M-, is so easy that there is no sense defining
an additional command to provide another way.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-08  0:33           ` Drew Adams
  2008-01-08 19:08             ` Richard Stallman
@ 2008-01-09  0:48             ` Juri Linkov
  2008-01-09  1:47               ` Drew Adams
  1 sibling, 1 reply; 20+ messages in thread
From: Juri Linkov @ 2008-01-09  0:48 UTC (permalink / raw)
  To: Drew Adams; +Cc: teirllm, rms, emacs-devel

>> I think this is too weird trick to quit the query-replace
>> operation with M-> and resume it with tags-loop-continue M-,.
>> Maybe instead of this we should try implementing native
>> (i.e. without using etags) multi-file query-replace
>> similar to recently implemented multi-file isearch?
>
> What was wrong with your first suggestion (and Miles's):
>
>>> Maybe, when started by `Q', query-replace should apply `!' to all
>>> marked files, and a new key `Y' should replace all remaining
>>> occurrences in the current file, and a new key `N' should skip
>>> the current file as Miles has already proposed.

That's exactly what I meant in the latest proposal: to implement
multi-file query-replace with additional keys: a key to replace
remaining occurrences in the current file, and a key to skip to
the next file.

How else this is possible to do given that query-replace doesn't
depend on etags?

> But I'd keep the single-file meaning of all keys, including `!', and use a
> different key to replace all remaining occurrences in this file and the
> other files. It's not good for a key (e.g. `!') to change meaning, depending
> on whether one file or several are searched.

`!' in single-file context means to replace all remaining occurrences
that would be fine to apply the same meaning in multi-file context.
Any other keys could be applied only to the current file since
this is an additional separation in search-replace space.

-- 
Juri Linkov
http://www.jurta.org/emacs/

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-08  2:12           ` Luc Teirlinck
@ 2008-01-09  0:54             ` Juri Linkov
  0 siblings, 0 replies; 20+ messages in thread
From: Juri Linkov @ 2008-01-09  0:54 UTC (permalink / raw)
  To: Luc Teirlinck; +Cc: rms, drew.adams, emacs-devel

>    I think this is too weird trick to quit the query-replace operation
>    with M-> and resume it with tags-loop-continue M-,
>
> It is not a "trick", but a special case of a (to me) routine way to
> skip a series of occurrences known to be irrelevant by simply moving
> over them.  You can (and I routinely do), use not just M->, but _any_
> motion command for that purpose.  I have no idea what is "weird",
> unnatural or wrong about that.  It certainly is very useful.

This is useful but unnatural comparing to clean user interfaces I have seen
that have an option to skip to the next file, and additional buttons like
"Yes to All" and "No to All".

Currently in Emacs calling tags-loop-continue can be hardly described as
a clean way to resume query-replace.  And it also doesn't work in
single-file context which would be confusing.

-- 
Juri Linkov
http://www.jurta.org/emacs/

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

* RE: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-09  0:48             ` Juri Linkov
@ 2008-01-09  1:47               ` Drew Adams
  0 siblings, 0 replies; 20+ messages in thread
From: Drew Adams @ 2008-01-09  1:47 UTC (permalink / raw)
  To: Juri Linkov; +Cc: teirllm, rms, emacs-devel

> > But I'd keep the single-file meaning of all keys, including
> > `!', and use a different key to replace all remaining
> > occurrences in this file and the other files. It's not good
> > for a key (e.g. `!') to change meaning, depending
> > on whether one file or several are searched.
>
> `!' in single-file context means to replace all remaining occurrences
> that would be fine to apply the same meaning in multi-file context.
> Any other keys could be applied only to the current file since
> this is an additional separation in search-replace space.

An additional separation of the space or an extension of the single-file
behavior to additional files? There are different ways to look at it.

You can consider `!' as something that affects the whole search space or
something that affects only the current file.

It can be argued either way, but I think the more conservative
interpretation is better. Less of a mess (change from the previous state) if
you misinterpret the meaning.

I don't really care much, either way. One thing this discussion points out
is that the user could be confused either way about `!', so the doc had
better be clear.

Anyway, Richard has already decided that `M-> M-,' is adequate.

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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-01-04  2:11         ` Bastien
@ 2008-07-15  0:27           ` Juri Linkov
  2008-07-15  7:38             ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 20+ messages in thread
From: Juri Linkov @ 2008-07-15  0:27 UTC (permalink / raw)
  To: emacs-devel

>>> Even so, it might not be bad to provide a key to skip to the next file
>>> without exiting query-replace.
>>
>> Another problem I have with `Q' is that it requires typing `!' in every
>> file to replace all occurrences.  So if I want to replace all occurrences
>> in ALL marked files at once without a query, I need typing `!' as many times
>> as there are marked files.
>>
>> Maybe, when started by `Q', query-replace should apply `!' to all marked files,
>> and a new key `Y' should replace all remaining occurrences in the current file,
>> and a new key `N' should skip the current file as Miles has already proposed.
>
> Agreed.

I see that this useful feature is not yet implemented, so I have
made a patch that implements multi-file query-replace UI.

It defines a new keymap `multi-query-replace-map' that inherits from
`query-replace-map' and defines two multi-file keys "Y" and "N".
"Y" means to replace all remaining matches in all remaining buffers,
(this key is better than redefining the old behavior of "!").
And "N" skips remaining matches in the current buffer and continues
with the next buffer (so in addition to "No for this file" it also has
"Next file" mnemonics).

Index: lisp/replace.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/replace.el,v
retrieving revision 1.273
diff -c -r1.273 replace.el
*** lisp/replace.el	29 Jun 2008 16:09:08 -0000	1.273
--- lisp/replace.el	15 Jul 2008 00:27:02 -0000
***************
*** 1372,1377 ****
--- 1372,1391 ----
  `exit', `act-and-exit', `edit', `delete-and-edit', `recenter',
  `automatic', `backup', `exit-prefix', and `help'.")
  
+ (defvar multi-query-replace-map
+   (let ((map (make-sparse-keymap)))
+     (set-keymap-parent map query-replace-map)
+     (define-key map "Y" 'automatic-all)
+     (define-key map "N" 'exit-current)
+     map)
+   "Keymap that defines additional bindings for multi-buffer operations.
+ It extends its parent map `query-replace-map' with new bindings to
+ operate on a set of buffers/files.  The difference with its parent map
+ is the additional answers `automatic-all' to replace all remaining
+ matches in all remaining buffers with no more questions, and
+ `exit-current' to skip remaining matches in the current buffer
+ and to continue with the next buffer in the sequence.")
+ 
  (defun replace-match-string-symbols (n)
    "Process a list (and any sub-lists), expanding certain symbols.
  Symbol  Expands To
***************
*** 1702,1708 ****
  				     query-replace-help)))
  			   (with-current-buffer standard-output
  			     (help-mode))))
! 			((eq def 'exit)
  			 (setq keep-going nil)
  			 (setq done t))
  			((eq def 'backup)
--- 1716,1722 ----
  				     query-replace-help)))
  			   (with-current-buffer standard-output
  			     (help-mode))))
! 			((or (eq def 'exit) (eq def 'exit-current))
  			 (setq keep-going nil)
  			 (setq done t))
  			((eq def 'backup)
***************
*** 1744,1750 ****
  				   real-match-data (replace-match-data
  						    t real-match-data)
  				   replaced t)))
! 			((eq def 'automatic)
  			 (or replaced
  			     (setq noedit
  				   (replace-match-maybe-edit
--- 1758,1764 ----
  				   real-match-data (replace-match-data
  						    t real-match-data)
  				   replaced t)))
! 			((or (eq def 'automatic) (eq def 'automatic-all))
  			 (or replaced
  			     (setq noedit
  				   (replace-match-maybe-edit

Index: lisp/progmodes/etags.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/progmodes/etags.el,v
retrieving revision 1.211
diff -c -r1.211 etags.el
*** lisp/progmodes/etags.el	7 Jun 2008 02:37:37 -0000	1.211
--- lisp/progmodes/etags.el	15 Jul 2008 00:27:08 -0000
***************
*** 1865,1872 ****
  			      ;; to the beginning of it so perform-replace
  			      ;; will see it.
  			      (goto-char (match-beginning 0))))
! 	tags-loop-operate `(perform-replace ',from ',to t t ',delimited))
    (tags-loop-continue (or file-list-form t)))
  \f
  (defun tags-complete-tags-table-file (string predicate what) ; Doc string?
    (save-excursion
--- 1865,1896 ----
  			      ;; to the beginning of it so perform-replace
  			      ;; will see it.
  			      (goto-char (match-beginning 0))))
! 	tags-loop-operate `(tags-query-replace-loop-operate
! 			    ',from ',to ',delimited))
    (tags-loop-continue (or file-list-form t)))
+ 
+ (defun tags-query-replace-loop-operate (from to delimited)
+   "Call `perform-replace' with the logic of multi-file operations.
+ Used for `tags-loop-operate' in `tags-query-replace'."
+   (let* (
+ 	 ;; def-pre is a key typed in the previous call of perform-replace
+ 	 (def-pre (lookup-key multi-query-replace-map
+ 			      (vector last-input-char)))
+ 	 ;; If the last typed key was automatic-all, don't ask
+ 	 ;; more questions in next files
+ 	 (query-flag (not (eq def-pre 'automatic-all)))
+ 	 (ret (perform-replace from to query-flag t delimited nil
+ 			       multi-query-replace-map))
+ 	 ;; def-post is a key typed in the new call of perform-replace
+ 	 (def-post (lookup-key multi-query-replace-map
+ 			       (vector last-input-char))))
+     (or
+      ;; Return non-nil exit code from `perform-replace'
+      ret
+      ;; Or return t if a multi-file operation key was typed
+      (eq def-post 'exit-current)
+      (eq def-post 'automatic-all))))
+ 
  \f
  (defun tags-complete-tags-table-file (string predicate what) ; Doc string?
    (save-excursion

-- 
Juri Linkov
http://www.jurta.org/emacs/




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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-07-15  0:27           ` Juri Linkov
@ 2008-07-15  7:38             ` Lennart Borgman (gmail)
  2008-07-20  0:33               ` Juri Linkov
  0 siblings, 1 reply; 20+ messages in thread
From: Lennart Borgman (gmail) @ 2008-07-15  7:38 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

Juri Linkov wrote:
>>>> Even so, it might not be bad to provide a key to skip to the next file
>>>> without exiting query-replace.
>>> Another problem I have with `Q' is that it requires typing `!' in every
>>> file to replace all occurrences.  So if I want to replace all occurrences
>>> in ALL marked files at once without a query, I need typing `!' as many times
>>> as there are marked files.
>>>
>>> Maybe, when started by `Q', query-replace should apply `!' to all marked files,
>>> and a new key `Y' should replace all remaining occurrences in the current file,
>>> and a new key `N' should skip the current file as Miles has already proposed.
>> Agreed.
> 
> I see that this useful feature is not yet implemented, so I have
> made a patch that implements multi-file query-replace UI.


Thanks for implementing this.




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

* Re: `Q' in Dired - be able to skip the rest of one file and move onto the next
  2008-07-15  7:38             ` Lennart Borgman (gmail)
@ 2008-07-20  0:33               ` Juri Linkov
  0 siblings, 0 replies; 20+ messages in thread
From: Juri Linkov @ 2008-07-20  0:33 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: emacs-devel

>> I see that this useful feature is not yet implemented, so I have
>> made a patch that implements multi-file query-replace UI.
>
> Thanks for implementing this.

I now have a better patch where all multi-file processing was moved to
`perform-replace', so external packages like etags.el only need to add
`multi-query-replace-map' as the `map' argument of `perform-replace'.

Index: lisp/progmodes/etags.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/progmodes/etags.el,v
retrieving revision 1.211
diff -c -r1.211 etags.el
*** lisp/progmodes/etags.el	7 Jun 2008 02:37:37 -0000	1.211
--- lisp/progmodes/etags.el	20 Jul 2008 00:27:14 -0000
***************
*** 1865,1871 ****
  			      ;; to the beginning of it so perform-replace
  			      ;; will see it.
  			      (goto-char (match-beginning 0))))
! 	tags-loop-operate `(perform-replace ',from ',to t t ',delimited))
    (tags-loop-continue (or file-list-form t)))
  \f
  (defun tags-complete-tags-table-file (string predicate what) ; Doc string?
--- 1865,1872 ----
  			      ;; to the beginning of it so perform-replace
  			      ;; will see it.
  			      (goto-char (match-beginning 0))))
! 	tags-loop-operate `(perform-replace ',from ',to t t ',delimited
! 					    nil multi-query-replace-map))
    (tags-loop-continue (or file-list-form t)))
  \f
  (defun tags-complete-tags-table-file (string predicate what) ; Doc string?

Index: lisp/replace.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/replace.el,v
retrieving revision 1.273
diff -c -r1.273 replace.el
*** lisp/replace.el	29 Jun 2008 16:09:08 -0000	1.273
--- lisp/replace.el	20 Jul 2008 00:32:42 -0000
***************
*** 1372,1377 ****
--- 1372,1391 ----
  `exit', `act-and-exit', `edit', `delete-and-edit', `recenter',
  `automatic', `backup', `exit-prefix', and `help'.")
  
+ (defvar multi-query-replace-map
+   (let ((map (make-sparse-keymap)))
+     (set-keymap-parent map query-replace-map)
+     (define-key map "Y" 'automatic-all)
+     (define-key map "N" 'exit-current)
+     map)
+   "Keymap that defines additional bindings for multi-buffer operations.
+ It extends its parent map `query-replace-map' with new bindings to
+ operate on a set of buffers/files.  The difference with its parent map
+ is the additional answers `automatic-all' to replace all remaining
+ matches in all remaining buffers with no more questions, and
+ `exit-current' to skip remaining matches in the current buffer
+ and to continue with the next buffer in the sequence.")
+ 
  (defun replace-match-string-symbols (n)
    "Process a list (and any sub-lists), expanding certain symbols.
  Symbol  Expands To
***************
*** 1527,1532 ****
--- 1541,1547 ----
           (stack nil)
           (replace-count 0)
           (nonempty-match nil)
+ 	 (multi-file nil)
  
           ;; If non-nil, it is marker saying where in the buffer to stop.
           (limit nil)
***************
*** 1548,1553 ****
--- 1563,1573 ----
        (goto-char (min start end))
        (deactivate-mark))
  
+     ;; If last typed key in previous call of multi-file perform-replace
+     ;; was `automatic-all', don't ask more questions in next files
+     (when (eq (lookup-key map (vector last-input-char)) 'automatic-all)
+       (setq query-flag nil multi-file t))
+ 
      ;; REPLACEMENTS is either a string, a list of strings, or a cons cell
      ;; containing a function and its first argument.  The function is
      ;; called to generate each replacement like this:
***************
*** 1705,1710 ****
--- 1725,1732 ----
  			((eq def 'exit)
  			 (setq keep-going nil)
  			 (setq done t))
+ 			((eq def 'exit-current)
+ 			 (setq multi-file t keep-going nil done t))
  			((eq def 'backup)
  			 (if stack
  			     (let ((elt (pop stack)))
***************
*** 1744,1757 ****
  				   real-match-data (replace-match-data
  						    t real-match-data)
  				   replaced t)))
! 			((eq def 'automatic)
  			 (or replaced
  			     (setq noedit
  				   (replace-match-maybe-edit
  				    next-replacement nocasify literal
  				    noedit real-match-data)
  				   replace-count (1+ replace-count)))
! 			 (setq done t query-flag nil replaced t))
  			((eq def 'skip)
  			 (setq done t))
  			((eq def 'recenter)
--- 1766,1780 ----
  				   real-match-data (replace-match-data
  						    t real-match-data)
  				   replaced t)))
! 			((or (eq def 'automatic) (eq def 'automatic-all))
  			 (or replaced
  			     (setq noedit
  				   (replace-match-maybe-edit
  				    next-replacement nocasify literal
  				    noedit real-match-data)
  				   replace-count (1+ replace-count)))
! 			 (setq done t query-flag nil replaced t)
! 			 (if (eq def 'automatic-all) (setq multi-file t)))
  			((eq def 'skip)
  			 (setq done t))
  			((eq def 'recenter)
***************
*** 1838,1844 ****
  	(message "Replaced %d occurrence%s"
  		 replace-count
  		 (if (= replace-count 1) "" "s")))
!     (and keep-going stack)))
  
  (defvar replace-overlay nil)
  
--- 1861,1867 ----
  	(message "Replaced %d occurrence%s"
  		 replace-count
  		 (if (= replace-count 1) "" "s")))
!     (or (and keep-going stack) multi-file)))
  
  (defvar replace-overlay nil)

-- 
Juri Linkov
http://www.jurta.org/emacs/




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

end of thread, other threads:[~2008-07-20  0:33 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-02  7:34 `Q' in Dired - be able to skip the rest of one file and move on to the next Drew Adams
2008-01-03  9:50 ` Richard Stallman
2008-01-03 10:11   ` Andreas Schwab
2008-01-03 10:27     ` Miles Bader
2008-01-03 16:17       ` Drew Adams
2008-01-03 15:56   ` Luc Teirlinck
2008-01-03 16:18     ` `Q' in Dired - be able to skip the rest of one file and move onto " Drew Adams
2008-01-03 21:32       ` Juri Linkov
2008-01-04  2:11         ` Bastien
2008-07-15  0:27           ` Juri Linkov
2008-07-15  7:38             ` Lennart Borgman (gmail)
2008-07-20  0:33               ` Juri Linkov
2008-01-05  5:54       ` Richard Stallman
2008-01-08  0:21         ` Juri Linkov
2008-01-08  0:33           ` Drew Adams
2008-01-08 19:08             ` Richard Stallman
2008-01-09  0:48             ` Juri Linkov
2008-01-09  1:47               ` Drew Adams
2008-01-08  2:12           ` Luc Teirlinck
2008-01-09  0:54             ` Juri Linkov

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