内容简介:Last weekend, I was tasked with refactoring the 96 unit tests onHere's a small sample of what had to be done (note the lines prefixed with the arrow):had to be converted to:
Last weekend, I was tasked with refactoring the 96 unit
tests on ruma-events
to use strictly typed json objects using serde_json::json!
instead of raw strings. It was rather painless thanks to
vim :)
Here's a small sample of what had to be done (note the lines prefixed with the arrow):
→ use serde_json::{from_str}; #[test] fn deserialize() { assert_eq!( → from_str::<Action>(r#"{"set_tweak": "highlight"}"#), Action::SetTweak(Tweak::Highlight { value: true }) ); }
had to be converted to:
→ use serde_json::{from_value}; #[test] fn deserialize() { assert_eq!( → from_value::<Action>(json!({"set_tweak": "highlight"})), Action::SetTweak(Tweak::Highlight { value: true }) ); }
The arglist
For the initial pass, I decided to handle imports, this was
a simple find and replace operation, done to all the files
containing tests. Luckily, modules (and therefore files)
containing tests in Rust are annotated with the #[cfg(test)]
attribute. I opened all such files:
# `grep -l pattern files` lists all the files # matching the pattern vim $(grep -l 'cfg\(test\)' ./**/*.rs) # expands to something like: vim push_rules.rs room/member.rs key/verification/lib.rs
Starting vim with more than one file at the shell prompt
populates the arglist. Hit :args
to see the list of
files currently ready to edit. The square [brackets]
indicate the current file. Navigate through the arglist
with :next
and :prev
. I use tpope's vim-unimpaired, which adds ]a
and [a
, mapped to :next
and :prev
.
All that's left to do is the find and replace, for which we
will be using vim's argdo
, applying a substitution to
every file in the arglist:
:argdo s/from_str/from_value/g
The quickfix list
Next up, replacing r#" ... "#
with json!( ... )
. I
couldn't search and replace that trivially, so I went with a
macro callinstead, starting with the cursor on
‘r’, represented by the caret, in my attempt to breakdown
the process:
BUFFER: r#" ... "#; ^ ACTION: vllsjson!( BUFFER json!( ... "#; ^ ACTION: <esc>$F# BUFFER: json!( ... "#; ^ ACTION: vhs)<esc> BUFFER: json!( ... );
Here's the recordedmacro in all its glory: vllsjson!(<esc>$F#vhs)<esc>
.
Great! So now we just go ahead, find every occurrence of r#
and apply the macro right? Unfortunately, there were
more than a few occurrences of raw strings that had to stay
raw strings. Enter, the quickfix list.
The idea behind the quickfix list is to jump from one position in a file to another (maybe in a different file), much like how the arglist lets you jump from one file to another.
One of the easiest ways to populate this list with a bunch
of positions is to use vimgrep
:
# basic usage :vimgrep pattern files # search for raw strings :vimgrep 'r#' ./**/*.rs
Like :next
and :prev
, you can navigate the quickfix list
with :cnext
and :cprev
. Every time you move up or down
the list, vim indicates your index:
(1 of 131): r#"{"set_tweak": "highlight"}"#;
And just like argdo
, you can cdo
to apply commands to every
match in the quickfix list:
:cdo norm! @q
But, I had to manually pick out matches, and it involved some button mashing.
External Filtering
Some code reviews later, I was asked to format all the json
inside the json!
macro. All you have to do is pass a
visual selection through a pretty json printer. Select the
range to be formatted in visual mode, and hit :
, you will
notice the command line displaying what seems to be
gibberish:
:'<,'>
'<
and '>
are marks
. More
specifically, they are marks that vim sets automatically
every time you make a visual selection, denoting the start
and end of the selection.
A range is one or more line specifiers separated by a ,
:
:1,7 lines 1 through 7 :32 just line 32 :. the current line :.,$ the current line to the last line :'a,'b mark 'a' to mark 'b'
Most :
commands can be prefixed by ranges. :help
usr_10.txt
for more on that.
Alright, lets pass json through python -m json.tool
, a
json formatter that accepts stdin
(note the use of !
to
make use of an external program):
:'<,'>!python -m json.tool
Unfortunately that didn't quite work for me because the range included some non-json text as well, a mix of regex and macros helped fix that. I think you get the drift.
Another fun filter I use from time to time is :!sort
, to
sort css attributes, or :!uniq
to remove repeated imports.
以上所述就是小编给大家介绍的《Rapid Refactoring With Vim》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
图片转BASE64编码
在线图片转Base64编码工具
HSV CMYK 转换工具
HSV CMYK互换工具