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`. Regards, Jürgen -- Sometimes I think the surest sign that intelligent life exists elsewhere in the universe is that none of it has tried to contact us. (Calvin) -- -- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
