How to use the command comby (with examples)
comby is a powerful tool for structural code search and replace that supports many programming languages. It allows users to match and rewrite code templates, perform matching and print matches, and even rewrite code in-place. This article will provide examples of different use cases of the comby command, along with explanations and motivations for each example.
Use case 1: Match and rewrite templates, and print changes
Code:
comby 'assert_eq!(:[a], :[b])' 'assert_eq!(:[b], :[a])' .rs
Motivation: By using comby to match and rewrite code templates, we can easily swap the arguments of a assert_eq!
macro in Rust. This can be useful when we want to switch the order of the expected and actual values in our assertion.
Arguments:
'assert_eq!(:[a], :[b])'
: The match pattern, which specifies the code template we are looking for. It matches any occurrence of theassert_eq!
macro with two arguments,:[a]
and:[b]
.'assert_eq!(:[b], :[a])'
: The rewrite pattern, which describes how the matching code templates should be rewritten. It swaps the positions of:[a]
and:[b]
in theassert_eq!
macro.'.rs'
: The target file or folder to search for matching code templates. In this case, we are searching for theassert_eq!
macro in Rust files.
Example output:
Original code:
assert_eq!(expected_value, actual_value);
Transformed code:
assert_eq!(actual_value, expected_value);
Use case 2: Match and rewrite with rewrite properties
Code:
comby 'assert_eq!(:[a], :[b])' 'assert_eq!(:[b].Capitalize, :[a])' .rs
Motivation: In some situations, we may want to modify the arguments of a matching code template while rewriting it. By using rewrite properties, we can easily capitalize the second argument of the assert_eq!
macro in Rust.
Arguments:
'assert_eq!(:[a], :[b])'
: The match pattern, which matches theassert_eq!
macro with two arguments,:[a]
and:[b]
.'assert_eq!(:[b].Capitalize, :[a])'
: The rewrite pattern, which modifies the matching code templates. Here, we capitalize the second argument,:[b]
, using the.Capitalize
rewrite property.'.rs'
: The target files or folder to search for matching code templates. In this case, we are searching for theassert_eq!
macro in Rust files.
Example output:
Original code:
assert_eq!(expected_value, actual_value);
Transformed code:
assert_eq!(expected_value, Actual_value);
Use case 3: Match and rewrite in-place
Code:
comby -in-place 'match_pattern' 'rewrite_pattern'
Motivation: Sometimes, we may want to modify the code directly in the original files instead of printing the changes. The -in-place
option allows us to perform matching and rewriting in-place, saving our modifications directly to the original files.
Arguments:
'match_pattern'
: The match pattern that describes the code template we want to match.'rewrite_pattern'
: The rewrite pattern that specifies how the matching code should be rewritten.
Example output: N/A
Note: The -in-place
option modifies the original files, so the output is not explicitly shown.
Use case 4: Only perform matching and print matches
Code:
comby -match-only 'match_pattern' ""
Motivation: In certain scenarios, we may only be interested in finding the occurrences of a specific code template rather than making any modifications. The -match-only
option allows us to perform matching and print out the matches without any rewriting.
Arguments:
'match_pattern'
: The match pattern that defines the code template we want to match.""
: An empty rewrite pattern, as we are not performing any rewriting. This argument is required but does not have any effect when using-match-only
.
Example output:
Match: assert_eq!(expected_value, actual_value)
Match: assert_eq!(expected_value2, actual_value2)
Conclusion:
The comby command provides flexible capabilities for code search and replace. It allows developers to easily match and rewrite code templates, perform matching and print matches, and even modify code in-place. By leveraging these different use cases, developers can efficiently automate various code transformations and improve their workflow.