I love that you demonstrated how to use the quickfix list.
But here’s how to trivially search and replace that string, for the curious:
Step 1. match the string: /r#"[^#]*#/
In English this says, Find (/) a string starting with r#", followed by anything that is not # ([^#]), as many times as you can (*) until you DO find find a #.
Step 2. Search and replace: :%s/r#"\([^#]*\)#/json!(\1)/c
This is :%s, a global search (more specifically a search with a range of %, which is the whole file), followed by the same search string from above with \( ... \) grouping added so we can remember the bit between the #s later. Then replace it with json!(\1) where \1 is the bit we remembered from \( ... \). Finally the trailing c stands for “confirm” and it will ask each time whether you want to perform the substitution.
Then you can do an argdo or a buffdo, or otherwise find some way to run that in all buffers: :argdo norm! @:
Tip: when crafting searches and commands, know that they are respectively saved to the / and : registers. So after performing a search, you can "/p to paste your search to a buffer to edit it. And you can @: to repeat a command. Anything you can do with registers and macros, you can do with the search and command registers.
Tip: if you do a search, and then want to do a search and replace, instead of retyping the search again into :s/old/new (or typing :s/<c-r>//new as you just learned to do, since searches are saved in the search register) you can simply :s//new because the search and replace command will auto-insert the most recent search if the search term is omitted.
The only reason I went with a macro was because I am not too familiar with regexes, would that work for strings that contain a # in them? something like r#"#room:matrix.org"#?
With that added wrinkle, what my eye settles on is the final #) of the line from_str::<Action>(r#"{"set_tweak": "highlight"}"#),, and it feels like it’s even easier to match on that.
Here’s a search: /r#".*#)/. This is finding a string starting with r#", followed by a bunch of anything (.*), followed by #). This will work for strings that contain a # in them.
so your final search and replace should be something like this: :%s/r#"\(.*\)#)/json!(\1)/c
I think I’d still go regex for this one. Although macros would obviously also do the trick just fine.
If your content (the stuff in [^<delimiter>] contains a delimiter, you have a pretty classic problem that regexes technically can’t solve (PCRE I think can, but technically those are more general than regular expressions proper, as I understand it).
I think I would’ve also gone w/ the macro approach here, if only because it makes the process more interactive so I can selectively apply a re-usable edit. You can do similar w/ :s and & to do a substitution and then repeat that substitution, but doing a @@ and encoding the :next into the macro is also really nice, it leaves you with either hitting the @@ to apply or the :next to skip (in my case it’s @@ and C to apply/skip once I’ve recorded the macro).
I love that you demonstrated how to use the quickfix list.
But here’s how to trivially search and replace that string, for the curious:
Step 1. match the string:
/r#"[^#]*#/
In English this says, Find (
/
) a string starting withr#"
, followed by anything that is not#
([^#]
), as many times as you can (*
) until you DO find find a#
.Step 2. Search and replace:
:%s/r#"\([^#]*\)#/json!(\1)/c
This is
:%s
, a global search (more specifically a search with a range of%
, which is the whole file), followed by the same search string from above with\( ... \)
grouping added so we can remember the bit between the#
s later. Then replace it withjson!(\1)
where\1
is the bit we remembered from\( ... \)
. Finally the trailingc
stands for “confirm” and it will ask each time whether you want to perform the substitution.Then you can do an argdo or a buffdo, or otherwise find some way to run that in all buffers:
:argdo norm! @:
Tip: when crafting searches and commands, know that they are respectively saved to the
/
and:
registers. So after performing a search, you can"/p
to paste your search to a buffer to edit it. And you can@:
to repeat a command. Anything you can do with registers and macros, you can do with the search and command registers.Tip: if you do a search, and then want to do a search and replace, instead of retyping the search again into
:s/old/new
(or typing:s/<c-r>//new
as you just learned to do, since searches are saved in the search register) you can simply:s//new
because the search and replace command will auto-insert the most recent search if the search term is omitted.The only reason I went with a macro was because I am not too familiar with regexes, would that work for strings that contain a
#
in them? something liker#"#room:matrix.org"#
?Thank you for your detailed reply!
You’re welcome! I love vim and I love regex.
With that added wrinkle, what my eye settles on is the final
#)
of the linefrom_str::<Action>(r#"{"set_tweak": "highlight"}"#),
, and it feels like it’s even easier to match on that.Here’s a search:
/r#".*#)/
. This is finding a string starting withr#"
, followed by a bunch of anything (.*
), followed by#)
. This will work for strings that contain a#
in them.so your final search and replace should be something like this:
:%s/r#"\(.*\)#)/json!(\1)/c
I think I’d still go regex for this one. Although macros would obviously also do the trick just fine.
No, it wouldn’t, but the general regex pattern for a delimited string that doesn’t contain it’s delimiters is:
If your content (the stuff in
[^<delimiter>]
contains a delimiter, you have a pretty classic problem that regexes technically can’t solve (PCRE I think can, but technically those are more general than regular expressions proper, as I understand it).I think I would’ve also gone w/ the macro approach here, if only because it makes the process more interactive so I can selectively apply a re-usable edit. You can do similar w/
:s
and&
to do a substitution and then repeat that substitution, but doing a@@
and encoding the:next
into the macro is also really nice, it leaves you with either hitting the@@
to apply or the:next
to skip (in my case it’s@@
andC
to apply/skip once I’ve recorded the macro).Very useful, I didn’t know about arglists before. Also, calling
!uniq
to remove repeated imports is genius.I found some helpful hints in here, thank you!