* replace-regexp from A to B?
@ 2018-08-26 14:40 Rodolfo Medina
2018-08-26 15:50 ` Yuri Khan
[not found] ` <87wosd0yoe.fsf@himinbjorg.adminart.net>
0 siblings, 2 replies; 14+ messages in thread
From: Rodolfo Medina @ 2018-08-26 14:40 UTC (permalink / raw)
To: help-gnu-emacs
Hi all...
Is it possible, and how?, to perform a replace-regexp from a certain point,
e.g. the current one, or from a certain word/expression, up to the next
occurrence of a certain other word/expression...? In my case, with MusiXTeX
documents, the starting point should be the TeX command `\startpiece' and the
final one `\Endpiece'. So I could replace strings/expressions within a single
musical piece without going out of it.
Thanks for any help,
Rodolfo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: replace-regexp from A to B?
2018-08-26 14:40 replace-regexp from A to B? Rodolfo Medina
@ 2018-08-26 15:50 ` Yuri Khan
2018-08-28 7:13 ` Rodolfo Medina
[not found] ` <87wosd0yoe.fsf@himinbjorg.adminart.net>
1 sibling, 1 reply; 14+ messages in thread
From: Yuri Khan @ 2018-08-26 15:50 UTC (permalink / raw)
To: rodolfo.medina; +Cc: help-gnu-emacs
On Sun, Aug 26, 2018 at 9:40 PM Rodolfo Medina <rodolfo.medina@gmail.com> wrote:
> Is it possible, and how?, to perform a replace-regexp from a certain point,
> e.g. the current one, or from a certain word/expression, up to the next
> occurrence of a certain other word/expression...? In my case, with MusiXTeX
> documents, the starting point should be the TeX command `\startpiece' and the
> final one `\Endpiece'. So I could replace strings/expressions within a single
> musical piece without going out of it.
I’d decompose the problem into two.
1. Mark the piece enclosing the point as a region.
2. Do an ordinary ‘replace-regexp’ or ‘query-replace-regexp’ in the region.
To solve (1), I’d first look if the major mode recognizes pieces as a
construct analogous to a function in a programming language, by
invoking ‘mark-defun’ and looking if it marks the whole piece. If it
does, problem solved; you can query-and-replace in current piece by
doing ‘C-M-h M-%’ or ‘C-M-h C-M-%’; or, if you want to do multiple
replacements in a piece, first narrow to it with ‘C-x n d’, then do
all your replacements, then widen back with ‘C-x n w’.
If the major mode does not have any useful notion of defun, I’d define
my own and arrange for it to be used by the major mode:
(defun my-musixtex-beginning-of-piece (arg)
(if (> arg 0)
(dotimes arg (re-search-backward "\\\\startpiece\\>"))
(dotimes (- arg) (re-search-forward "\\\\startpiece\\>"))))
(defun my-musixtex-end-of-piece ()
(re-search-forward "\\\\Endpiece\\>"))
(defun my-musixtex-init-defun ()
(setq-local beginning-of-defun-function
#'my-musixtex-beginning-of-piece)
(setq-local end-of-defun-function
#'my-musixtex-end-of-piece))
;; change the mode hook variable name to suit your major mode
(add-hook 'musixtex-mode-hook #'my-musixtex-init-defun)
If the major mode does have a useful idea of defun, I’d then just
write a function like this:
(defun my-musixtex-mark-piece ()
(interactive)
(let* ((end (re-search-forward "\\\\Endpiece\\>"))
(begin (search-backward "\\\\startpiece\\>")))
(push-mark end nil t)
(goto-char begin)))
and bind it to a convenient key probably involving the letter ‘h’ and
a few modifiers and/or prefix keys (because ‘mark-paragraph’ is on
‘M-h’, ‘mark-defun’ on ‘C-M-h’ and ‘mark-whole-buffer’ on ‘C-x h’).
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: replace-regexp from A to B?
[not found] <mailman.5556.1535294433.1292.help-gnu-emacs@gnu.org>
@ 2018-08-26 16:02 ` Emanuel Berg
2018-08-26 17:54 ` Rodolfo Medina
[not found] ` <mailman.5566.1535306070.1292.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 14+ messages in thread
From: Emanuel Berg @ 2018-08-26 16:02 UTC (permalink / raw)
To: help-gnu-emacs
Rodolfo Medina wrote:
> Is it possible, and how?, to perform
> a replace-regexp from a certain point, e.g.
> the current one, or from a certain
> word/expression, up to the next occurrence of
> a certain other word/expression...? In my
> case, with MusiXTeX documents, the starting
> point should be the TeX command `\startpiece'
> and the final one `\Endpiece'. So I could
> replace strings/expressions within a single
> musical piece without going out of it.
You can set the region manually and then use
a function with
(goto-char START)
(while (re-search-forward REGEXP STOP t)
(replace-match TO-STRING nil nil))
where START is (region-beginning) and STOP is
(region-end). First check if there is a region
with (use-region-p) !
Or if you want it fully automated make a search
for "\startpiece" and set START, then make
a search for "\Endpiece" and set STOP. Do this
in Elisp as well.
But then you'd have to supply them (the
delimitators) as arguments so it won't
necessarily be faster because you'd have to
type them each time rather than to set
the region.
If they (the delimitators) are always the same
you could hard-code them, of course. Then it'll
be very fast to invoke :)
--
underground experts united
http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: replace-regexp from A to B?
2018-08-26 16:02 ` replace-regexp from A to B? Emanuel Berg
@ 2018-08-26 17:54 ` Rodolfo Medina
[not found] ` <mailman.5566.1535306070.1292.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 14+ messages in thread
From: Rodolfo Medina @ 2018-08-26 17:54 UTC (permalink / raw)
To: help-gnu-emacs
Emanuel Berg <moasen@zoho.com> writes:
> Rodolfo Medina wrote:
>
>> Is it possible, and how?, to perform
>> a replace-regexp from a certain point, e.g.
>> the current one, or from a certain
>> word/expression, up to the next occurrence of
>> a certain other word/expression...? In my
>> case, with MusiXTeX documents, the starting
>> point should be the TeX command `\startpiece'
>> and the final one `\Endpiece'. So I could
>> replace strings/expressions within a single
>> musical piece without going out of it.
>
> You can set the region manually and then use
> a function with
>
> (goto-char START)
> (while (re-search-forward REGEXP STOP t)
> (replace-match TO-STRING nil nil))
>
> where START is (region-beginning) and STOP is
> (region-end). First check if there is a region
> with (use-region-p) !
>
> Or if you want it fully automated make a search
> for "\startpiece" and set START, then make
> a search for "\Endpiece" and set STOP. Do this
> in Elisp as well.
>
> But then you'd have to supply them (the
> delimitators) as arguments so it won't
> necessarily be faster because you'd have to
> type them each time rather than to set
> the region.
>
> If they (the delimitators) are always the same
> you could hard-code them, of course. Then it'll
> be very fast to invoke :)
Thanks, Yuri and Emanuel... I've seen that a single MusiXTeX piece can be
considered as a tex paragraph, because no blank line should be inserted into
it... So I can perform my replace-regexp with the `M-h' prefix so applying it
only to the current paragraph/piece...
Rodolfo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: replace-regexp from A to B?
[not found] ` <mailman.5566.1535306070.1292.help-gnu-emacs@gnu.org>
@ 2018-08-26 19:35 ` Emanuel Berg
2018-08-26 19:42 ` mixing argument types (was: Re: replace-regexp from A to B?) Emanuel Berg
0 siblings, 1 reply; 14+ messages in thread
From: Emanuel Berg @ 2018-08-26 19:35 UTC (permalink / raw)
To: help-gnu-emacs
Rodolfo Medina wrote:
> Thanks, Yuri and Emanuel... I've seen that
> a single MusiXTeX piece can be considered as
> a tex paragraph, because no blank line should
> be inserted into it... So I can perform my
> replace-regexp with the `M-h' prefix so
> applying it only to the current
> paragraph/piece...
So you can do this already with
`replace-regexp'! Writing my previous answer,
I had an itchy feeling it was already there
somewhere... But who would have thought to look
at replace-regexp of all places? Err, good that
you found it anyway :)
Technically speaking tho, and I think you
already know this, `M-h' isn't a prefix to the
next function but just a command to set the
region. Once there, replace-regexp acts on it,
but it doesn't matter in what manner you set it
prior to that.
Not to say there's anything wrong with using
M-h, of course.
--
underground experts united
http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 14+ messages in thread
* mixing argument types (was: Re: replace-regexp from A to B?)
2018-08-26 19:35 ` Emanuel Berg
@ 2018-08-26 19:42 ` Emanuel Berg
2018-08-26 20:23 ` mixing argument types Stefan Monnier
[not found] ` <mailman.5572.1535315139.1292.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 14+ messages in thread
From: Emanuel Berg @ 2018-08-26 19:42 UTC (permalink / raw)
To: help-gnu-emacs
>> Thanks, Yuri and Emanuel... I've seen that
>> a single MusiXTeX piece can be considered as
>> a tex paragraph, because no blank line
>> should be inserted into it... So I can
>> perform my replace-regexp with the `M-h'
>> prefix so applying it only to the current
>> paragraph/piece...
>
> So you can do this already with
> `replace-regexp'! Writing my previous answer,
> I had an itchy feeling it was already there
> somewhere... But who would have thought to
> look at replace-regexp of all places? Err,
> good that you found it anyway :)
>
> Technically speaking tho, and I think you
> already know this, `M-h' isn't a prefix to
> the next function but just a command to set
> the region. Once there, replace-regexp acts
> on it, but it doesn't matter in what manner
> you set it prior to that.
>
> Not to say there's anything wrong with using
> M-h, of course.
This brings me to something I have thought
about a couple of times, namely what is the
right way to write the interactive
specification of a function that reads
argument(s) from the minibuffer, AND, if
available, act on the region as well?
(defun do-a-on-b (a b &optional start stop)
(interactive
;; check (use-region-p)
(list
;; ask for a
;; ask for b
start
stop)
;; ...
)
;; ...
;; do it
)
?
--
underground experts united
http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: mixing argument types
2018-08-26 19:42 ` mixing argument types (was: Re: replace-regexp from A to B?) Emanuel Berg
@ 2018-08-26 20:23 ` Stefan Monnier
[not found] ` <mailman.5572.1535315139.1292.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 14+ messages in thread
From: Stefan Monnier @ 2018-08-26 20:23 UTC (permalink / raw)
To: help-gnu-emacs
> (defun do-a-on-b (a b &optional start stop)
> (interactive
> ;; check (use-region-p)
> (list
> ;; ask for a
> ;; ask for b
> start
> stop)
> ;; ...
> )
The interactive spec can't use `start` and `stop` like you did, since
it (the interactive spec) is what is used to find the arguments to pass
to the function (i.e. to find `start`, `stop, `a`, and `b`).
So you'd write:
(defun do-a-on-b (a b &optional start stop)
(interactive
(list
(completing-read "Give me A: " '("foo" "bar"))
(read-file-name "Give me B:")
(region-beginning)
(region-end)))
...)
-- Stefan
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: mixing argument types
[not found] ` <mailman.5572.1535315139.1292.help-gnu-emacs@gnu.org>
@ 2018-08-26 21:09 ` Emanuel Berg
2018-08-27 13:06 ` Rodolfo Medina
[not found] ` <mailman.5588.1535375213.1292.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 14+ messages in thread
From: Emanuel Berg @ 2018-08-26 21:09 UTC (permalink / raw)
To: help-gnu-emacs
Stefan Monnier wrote:
> So you'd write:
>
> (defun do-a-on-b (a b &optional start stop)
> (interactive
> (list
> (completing-read "Give me A: " '("foo" "bar"))
> (read-file-name "Give me B:")
> (region-beginning)
> (region-end)))
> ...)
Great, thanks!
--
underground experts united
http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: mixing argument types
2018-08-26 21:09 ` Emanuel Berg
@ 2018-08-27 13:06 ` Rodolfo Medina
[not found] ` <mailman.5588.1535375213.1292.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 14+ messages in thread
From: Rodolfo Medina @ 2018-08-27 13:06 UTC (permalink / raw)
To: help-gnu-emacs
Emanuel Berg <moasen@zoho.com> writes:
> Stefan Monnier wrote:
>
>> So you'd write:
>>
>> (defun do-a-on-b (a b &optional start stop)
>> (interactive
>> (list
>> (completing-read "Give me A: " '("foo" "bar"))
>> (read-file-name "Give me B:")
>> (region-beginning)
>> (region-end)))
>> ...)
>
> Great, thanks!
What does `A' stand for...? And foo and bar...? And region-beginning/end...?
Excuse my unexperienced requests of explanation...
Thanks...
Rodolfo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: mixing argument types
[not found] ` <mailman.5588.1535375213.1292.help-gnu-emacs@gnu.org>
@ 2018-08-27 19:08 ` Emanuel Berg
2018-08-27 20:07 ` Emanuel Berg
1 sibling, 0 replies; 14+ messages in thread
From: Emanuel Berg @ 2018-08-27 19:08 UTC (permalink / raw)
To: help-gnu-emacs
Rodolfo Medina wrote:
> What does `A' stand for...? And foo and
> bar...? And region-beginning/end...?
A and B doesn't stand for anything in
particular, but it can stand for a lot of
things, anything that fits. Likewise with foo
and bar: programmers use them sort of like
x and y in algebra, but not in exactly the same
way, more like telling "don't mind us, this
piece of code is carrying some other point
across, only formally, without us, it won't
work".
Sometimes foo and bar make their way into real
software, because people forget to replace them
after first being lazy failing to come up with
a name that describes what is happening. It is
most often better not to use them at all when
writing real programs.
Here, we use it as a way to describe the
mechanism of a function and its arguments, i.e.
the function itself, without any connections to
what it would do in a real program in the
real world.
--
underground experts united
http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: mixing argument types
[not found] ` <mailman.5588.1535375213.1292.help-gnu-emacs@gnu.org>
2018-08-27 19:08 ` Emanuel Berg
@ 2018-08-27 20:07 ` Emanuel Berg
2018-08-28 7:29 ` Rodolfo Medina
1 sibling, 1 reply; 14+ messages in thread
From: Emanuel Berg @ 2018-08-27 20:07 UTC (permalink / raw)
To: help-gnu-emacs
Rodolfo Medina wrote:
> And region-beginning/end...?
You can set the mark with C-SPC
(`set-mark-command'), and then move point (the
cursor) around with the usual keys. You should
now see the effect of this in the buffer.
The area covered is called the region. Often,
functions operate on this region because it is
a natural way to specify what part of the
buffer should be affected by a command: first
the user sets the region, then the command is
invoked, and because there is a region, the
command affects that, rather than the whole
buffer (or something else, depending on the
command).
In Elisp code, you can find out if there is
a region with (use-region-p). You can even,
right now reading this, evaluate that (with
`C-x C-e', `eval-last-sexp') with and without
a region: it should evaluate to t or nil
accordingly.
In the Elisp code, if there is a region you use
`region-beginning' and `region-end' to delimit
the part of the buffer it covers.
--
underground experts united
http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: replace-regexp from A to B?
2018-08-26 15:50 ` Yuri Khan
@ 2018-08-28 7:13 ` Rodolfo Medina
0 siblings, 0 replies; 14+ messages in thread
From: Rodolfo Medina @ 2018-08-28 7:13 UTC (permalink / raw)
To: help-gnu-emacs
Yuri Khan <yurivkhan@gmail.com> writes:
> On Sun, Aug 26, 2018 at 9:40 PM Rodolfo Medina <rodolfo.medina@gmail.com> wrote:
>
>> Is it possible, and how?, to perform a replace-regexp from a certain point,
>> e.g. the current one, or from a certain word/expression, up to the next
>> occurrence of a certain other word/expression...? In my case, with MusiXTeX
>> documents, the starting point should be the TeX command `\startpiece' and
>> the final one `\Endpiece'. So I could replace strings/expressions within a
>> single musical piece without going out of it.
>
> I’d decompose the problem into two.
>
> 1. Mark the piece enclosing the point as a region.
> 2. Do an ordinary ‘replace-regexp’ or ‘query-replace-regexp’ in the region.
>
> To solve (1), I’d first look if the major mode recognizes pieces as a
> construct analogous to a function in a programming language, by
> invoking ‘mark-defun’ and looking if it marks the whole piece. If it
> does, problem solved; you can query-and-replace in current piece by
> doing ‘C-M-h M-%’ or ‘C-M-h C-M-%’; or, if you want to do multiple
> replacements in a piece, first narrow to it with ‘C-x n d’, then do
> all your replacements, then widen back with ‘C-x n w’.
>
> If the major mode does not have any useful notion of defun, I’d define
> my own and arrange for it to be used by the major mode:
>
> (defun my-musixtex-beginning-of-piece (arg)
> (if (> arg 0)
> (dotimes arg (re-search-backward "\\\\startpiece\\>"))
> (dotimes (- arg) (re-search-forward "\\\\startpiece\\>"))))
>
> (defun my-musixtex-end-of-piece ()
> (re-search-forward "\\\\Endpiece\\>"))
>
> (defun my-musixtex-init-defun ()
> (setq-local beginning-of-defun-function
> #'my-musixtex-beginning-of-piece)
> (setq-local end-of-defun-function
> #'my-musixtex-end-of-piece))
>
> ;; change the mode hook variable name to suit your major mode
> (add-hook 'musixtex-mode-hook #'my-musixtex-init-defun)
>
>
> If the major mode does have a useful idea of defun, I’d then just
> write a function like this:
>
> (defun my-musixtex-mark-piece ()
> (interactive)
> (let* ((end (re-search-forward "\\\\Endpiece\\>"))
> (begin (search-backward "\\\\startpiece\\>")))
> (push-mark end nil t)
> (goto-char begin)))
>
> and bind it to a convenient key probably involving the letter ‘h’ and
> a few modifiers and/or prefix keys (because ‘mark-paragraph’ is on
> ‘M-h’, ‘mark-defun’ on ‘C-M-h’ and ‘mark-whole-buffer’ on ‘C-x h’).
Thanks... In my case, `C-M-h' does not select all the music piece but only
portions of it... Nevertheless, your second solution:
(defun my-musixtex-mark-piece ()
(interactive)
(let* ((end (re-search-forward "\\\\Endpiece\\>"))
(begin (search-backward "\\startpiece")))
(push-mark end nil t)
(goto-char begin)))
(with only two backslashes, instead of 4, before `startpiece', and nothing else
after `startpiece') seems to well select my music piece... Your first
solution, in particular
(defun my-musixtex-beginning-of-piece (arg)
(if (> arg 0)
(dotimes arg (re-search-backward "\\\\startpiece\\>"))
(dotimes (- arg) (re-search-forward "\\\\startpiece\\>"))))
gives error when evaluated with `C-x C-e'...
Rodolfo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: replace-regexp from A to B?
[not found] ` <87wosd0yoe.fsf@himinbjorg.adminart.net>
@ 2018-08-28 7:15 ` Rodolfo Medina
0 siblings, 0 replies; 14+ messages in thread
From: Rodolfo Medina @ 2018-08-28 7:15 UTC (permalink / raw)
To: help-gnu-emacs
hw <hw@adminart.net> writes:
> Rodolfo Medina <rodolfo.medina@gmail.com> writes:
>
>> Is it possible, and how?, to perform a replace-regexp from a certain point,
>> e.g. the current one, or from a certain word/expression, up to the next
>> occurrence of a certain other word/expression...? In my case, with MusiXTeX
>> documents, the starting point should be the TeX command `\startpiece' and
>> the final one `\Endpiece'. So I could replace strings/expressions within a
>> single musical piece without going out of it.
>
> The function is (by default?) limited to the current region, i. e. you
> can mark the area of text you want to perform the replacement in and,
> with the mark active, do the replacement. It won't replace anything
> outside of the region then. I usually use (query-replace) like that.
Yes, clear now, thanks...
Rodolfo
> You may want to look into (transient-mark-mode) and enable it.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: mixing argument types
2018-08-27 20:07 ` Emanuel Berg
@ 2018-08-28 7:29 ` Rodolfo Medina
0 siblings, 0 replies; 14+ messages in thread
From: Rodolfo Medina @ 2018-08-28 7:29 UTC (permalink / raw)
To: help-gnu-emacs
Emanuel Berg <moasen@zoho.com> writes:
> Rodolfo Medina wrote:
>
>> And region-beginning/end...?
>
> You can set the mark with C-SPC
> (`set-mark-command'), and then move point (the
> cursor) around with the usual keys. You should
> now see the effect of this in the buffer.
> The area covered is called the region. Often,
> functions operate on this region because it is
> a natural way to specify what part of the
> buffer should be affected by a command: first
> the user sets the region, then the command is
> invoked, and because there is a region, the
> command affects that, rather than the whole
> buffer (or something else, depending on the
> command).
>
> In Elisp code, you can find out if there is
> a region with (use-region-p). You can even,
> right now reading this, evaluate that (with
> `C-x C-e', `eval-last-sexp') with and without
> a region: it should evaluate to t or nil
> accordingly.
>
> In the Elisp code, if there is a region you use
> `region-beginning' and `region-end' to delimit
> the part of the buffer it covers.
Thanks you... Clear, now.
Rodolfo
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2018-08-28 7:29 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <mailman.5556.1535294433.1292.help-gnu-emacs@gnu.org>
2018-08-26 16:02 ` replace-regexp from A to B? Emanuel Berg
2018-08-26 17:54 ` Rodolfo Medina
[not found] ` <mailman.5566.1535306070.1292.help-gnu-emacs@gnu.org>
2018-08-26 19:35 ` Emanuel Berg
2018-08-26 19:42 ` mixing argument types (was: Re: replace-regexp from A to B?) Emanuel Berg
2018-08-26 20:23 ` mixing argument types Stefan Monnier
[not found] ` <mailman.5572.1535315139.1292.help-gnu-emacs@gnu.org>
2018-08-26 21:09 ` Emanuel Berg
2018-08-27 13:06 ` Rodolfo Medina
[not found] ` <mailman.5588.1535375213.1292.help-gnu-emacs@gnu.org>
2018-08-27 19:08 ` Emanuel Berg
2018-08-27 20:07 ` Emanuel Berg
2018-08-28 7:29 ` Rodolfo Medina
2018-08-26 14:40 replace-regexp from A to B? Rodolfo Medina
2018-08-26 15:50 ` Yuri Khan
2018-08-28 7:13 ` Rodolfo Medina
[not found] ` <87wosd0yoe.fsf@himinbjorg.adminart.net>
2018-08-28 7:15 ` Rodolfo Medina
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).