Den 2014-10-08 16:13, Jürgen Krämer skrev:
>
> Hi,
>
> BPJ schrieb am 08.10.2014 um 16:00:
>> Den 2014-10-02 16:33, Tim Chase skrev:
>>> On 2014-10-02 16:17, BPJ wrote:
>>>> The other day I felt the need for a command/function which did
>>>> a :substitute on a *copy* of each line matching its search pattern
>>>> and inserted that copy below the original, unmodified line. I soon
>>>> realized that it would be much easier to first make a copy of each
>>>> (unmodified) line, then execute the :substitute on the original
>>>> line, and lastly insert the unmodified copy above the original line
>>>> if the original line had been modified, as determined by comparing
>>>> the possibly modified original line to the always unmodified copy.
>>>>
>>>> I soon found that I also had a use case for getting the modified
>>>> line above the unmodified one, so I needed a way to tell the
>>>> command/function to do that -- obviously a bang on the command and
>>>> an extra argument on the function.
>>> [snip]
>>>> Originally I intended the command to behave similarly to :global,
>>>> defaulting to operating on the whole buffer unless an explicit
>>>> range was given, but I soon found that I sometimes wanted to find
>>>> eligible lines using :global itself and a pattern different from
>>>> the substitution pattern, and doing this with -nargs=% ended in
>>>> disaster, as the range given to :global was invisible to my
>>>> command, so my command operated on the whole file anyway (I should
>>>> have realized that to begin with, I realize! :-) The solution was
>>>> to use -range instead of -range=% and use an empty pattern on
>>>> the :AS argument if I use :g and want to use the same pattern on :s
>>>>
>>>> I now have the following questions:
>>>>
>>>> * (How) can I make this simpler? (Obviously)
>>>>
>>>> * (How) can I restore the original :g-like default behavior and
>>>> still be able to use an actual :g with a separate pattern when I
>>>> want to? N.B. that the -nargs=1 is important to me: I don't want
>>>> to have to do an extra level of escaping in the :s expression!
>>>
>>> These two can be combined into one answer. For your initial case,
>>> I'd use
>>>
>>> :g/^/t.|s/foo/bar/ge
>>>
>>> (the "e" flag suppresses the error in the event the line doesn't
>>> contain "foo")
>>>
>>> which can of course be limited by range:
>>>
>>> :'<,'>g/^/t.|s/foo/bar/ge
>>>
>>> or to a subset of lines containing "baz"
>>>
>>> :g/baz/t.|s/foo/bar/ge
>>>
>>
>> [Back from a rather bad cold...]
>>
>> Thanks for the reply!
>>
>> I had tried the `:g/something/t.|s/foo/bar/ge` trick, but it does what
>> I want only when the `:g` pattern and the `:s` pattern are the same;
>> otherwise it copies all lines which match the `:g` pattern, whether
>> the `:s` does anything to that line or not, the whole point of my
>> function being to avoid just that and copy only lines which are
>> actually affected by the `:s` -- i.e where the `:s` pattern matches,
>> so there is an ecological niche for my function anyway. I guess the
>> only way to preserve marks on the original line is to always copy it,
>> apply the `:s` to the copy and then delete the copy again if it is
>> still identical to the original line, which seems terribly wasteful
>> even if it makes the function simpler:
>
> you can move the `:s` pattern to the `:g` part and reuse it by
> specifying an empty pattern for `:s`, e.g.
>
> :g/foo/t.|s//bar/g
>
> This ensures that only those lines are copied which will be modified by `:s`.
I have been perfectly aware of that all along, but there are cases
where it makes perfect sense for the :g pattern and the :s pattern
to be different -- where you want to change :s matches in and copy
only lines which *also* match a :g pattern different from the :s
pattern: trivially, you want to
make a copy with 'bar' substituted for 'foo' of all lines
containing *both *'foo' and 'baz' -- that does *not* mean that you
want to make scopies of lines containing 'baz' but not containing
'foo': usually you do *not* want that!
/bpj
--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Wednesday, October 8, 2014
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment