
comby
by umutbasal
SKILL.md
name: comby description: Structural code search and refactoring using comby, a tool for matching and rewriting code based on syntax structure rather than regex. Use when performing code refactoring, renaming patterns across files, finding/replacing function calls with specific argument patterns, migrating APIs, transforming function signatures, or any task requiring syntax-aware code transformation. Triggers include requests to refactor code, rename functions/variables across codebase, find and replace code patterns, migrate deprecated APIs, update naming conventions, remove debug statements, or modernize code patterns.
Comby - Structural Code Search and Rewrite
Comby matches and rewrites code using structural templates instead of regex. It understands balanced delimiters, strings, and comments, making it ideal for safe code refactoring.
Installation Check
Verify comby is installed:
which comby || echo "Install: brew install comby (macOS) or bash <(curl -sL get-comby.netlify.app) (Linux)"
Quick Start
Basic Pattern
# Preview changes (dry run)
comby 'oldFunc(:[args])' 'newFunc(:[args])' .go
# Apply changes
comby 'oldFunc(:[args])' 'newFunc(:[args])' .go -i
# Specific directory
comby 'oldFunc(:[args])' 'newFunc(:[args])' -d src/ .go -i
# Review interactively
comby 'oldFunc(:[args])' 'newFunc(:[args])' .go -review
Common Workflow
- Test pattern - Run without
-ito preview - Review diff - Add
-diffflag for patch output - Apply carefully - Use
-ito modify files in-place - Verify - Run tests after refactoring
Core Concepts
Stdin/Stdout Usage
When using -stdin for input, add -stdout for plain rewritten output:
# With -stdout flag for plain output
echo 'hello' | comby ':[x]' ':[x].Capitalize' -stdin -stdout
# Output: Hello
# Without -stdout: outputs colored diff format (default)
echo 'hello' | comby ':[x]' ':[x].Capitalize' -stdin
# Output: (colored diff)
Match Holes
Holes capture varying parts of code:
| Syntax | Matches | Example |
|---|---|---|
:[hole] | Everything (lazy, balanced) | :[args] in func(a, b) captures a, b |
:[[hole]] | Identifiers only (\w+) | :[[name]] matches myFunc not my-func |
:[hole~\d+] | Regex pattern | Matches only digits |
... | Anonymous (don't care) | func(...) matches any args |
Rewrite with Properties
Transform captured values:
# Convert naming conventions
comby ':[[func]]' ':[func].lowerCamelCase' .py -i
comby ':[[var]]' ':[var].UPPER_SNAKE_CASE' .c -i
# Add file context
comby 'log(:[msg])' 'log(":[msg].file.name: " + :[msg])' .js -i
Common properties: .Capitalize, .lowercase, .UPPERCASE, .lowerCamelCase, .UpperCamelCase, .lower_snake_case, .UPPER_SNAKE_CASE, .length, .file
See references/syntax.md for complete syntax reference.
Rules for Constraints
Add conditions with -rule:
# Only match when equal
comby 'if (:[x] == :[y])' '' -rule 'where :[x] == :[y]' .c -match-only
# Only match specific values (pattern includes quotes to match string literals)
comby 'log(":[level]", ":[msg]")' 'logger(":[level]", ":[msg]")' \
-rule 'where :[level] == "ERROR"' .py -i
# Pattern matching (pattern includes quotes to match string literals)
comby 'func(":[arg]")' 'newfunc(":[arg]")' \
-rule 'where match :[arg] { | "error" -> true }' .go -i
See references/rules.md for complete rule system.
Essential Flags
| Flag | Purpose |
|---|---|
-i | Apply changes in-place |
-d dir | Target directory |
-f .ext | Filter by extension |
-match-only | Show matches without rewriting |
-diff | Generate unified diff |
-review | Interactive approval |
-rule 'where ...' | Add constraints |
-matcher .lang | Force language parser |
-stdin / -stdout | Pipe input/output |
-json-lines | JSON output for scripting |
Common Patterns
Rename Function/Method
comby 'oldFunc(:[args])' 'newFunc(:[args])' .go -i
comby ':[obj].oldMethod(:[args])' ':[obj].newMethod(:[args])' .js -i
Update Function Signature
# Add parameter
comby 'fetch(:[url])' 'fetch(:[url], { timeout: 5000 })' .js -i
# Reorder parameters
comby 'func(:[a], :[b])' 'func(:[b], :[a])' .py -i
API Migration
# Deprecated to new API
comby 'oldAPI.call(:[args])' 'newAPI.execute(:[args])' .js -i
# Method chaining change
comby ':[obj].old(:[x]).chain(:[y])' ':[obj].new(:[x], :[y])' .rs -i
Remove Debug Code
comby 'console.log(:[args])' '' .js -i
comby 'dbg!(:[expr])' ':[expr]' .rs -i
comby 'print(:[args])' '' .py -i
Update Naming Conventions
# snake_case to camelCase
comby ':[[var]]' ':[var].lowerCamelCase' .js -i
# camelCase to snake_case
comby ':[[var]]' ':[var].lower_snake_case' .py -i
Field/Property Rename
comby ':[obj].oldField' ':[obj].newField' .ts -i
comby ':[var]["old_key"]' ':[var]["new_key"]' .py -i
See references/examples.md for comprehensive refactoring examples.
Configuration Files
Create comby.toml for multiple patterns:
[rename-function]
match = "oldFunc(:[args])"
rewrite = "newFunc(:[args])"
[remove-debug]
match = "console.log(:[args])"
rewrite = ""
[update-import]
match = "from old_module import :[name]"
rewrite = "from new_module import :[name]"
rule = "where :[name] != 'excluded'"
Run: comby -config comby.toml -f .js -d directory/ -i
Language Support
Auto-detects by extension:
- C-family: C, C++, C#, Java, JavaScript, TypeScript, Go, Rust
- Dynamic: Python, Ruby, PHP, Perl
- Functional: OCaml, Haskell, Elixir, Erlang
- Markup: HTML, XML, JSON, YAML
- Other: SQL, Bash, LaTeX
Force language: -matcher .rs (use correct names from comby -list) or use -matcher .generic for unsupported languages.
Best Practices
- Always test first: Run without
-ito preview changes - Use version control: Commit before large refactorings
- Start narrow: Test on one file, then expand to directory
- Review diffs: Use
-diffor-reviewfor verification - Combine with git:
git grep -l 'pattern' | xargs comby ... -i - Escape properly: Use
\\dfor regex digit class in shell - Run tests: Validate after each refactoring step
Structural Matching Details
Comby understands:
- Balanced delimiters:
(),[],{},<>(language-aware) - String literals: Respects quotes and escape sequences
- Comments: Skips language-specific comment syntax
Example: func(:[args]) correctly matches func(foo(x), bar(y)) capturing nested calls.
Playground
Test patterns interactively: https://comby.live
Resources
- references/syntax.md - Complete syntax reference (holes, properties, identifiers)
- references/rules.md - Rule system (equality, pattern matching, regex)
- references/examples.md - Common refactoring patterns by use case
Troubleshooting
Pattern doesn't match?
- Check whitespace (usually flexible but test variations)
- Try
:[[hole]]for identifiers instead of:[hole] - Use
-matcher .genericif language detection fails - Test at https://comby.live
Too many matches?
- Make holes more specific: use
:[[id]]instead of:[any] - Add
-ruleconstraints - Use regex holes:
:[num~\d+]
Changes not applying?
- Verify
-iflag is present - Check file permissions
- Use
-diffto see what would change
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon
