Skip to content

Commit d5fbce9

Browse files
committed
huge amount of work on fixing issues with ambiguity and adding much smarter heuristics, updated docs
1 parent 11af9ee commit d5fbce9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2925
-566
lines changed

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ See [MCP Server documentation](https://docspring.github.io/renamify/mcp/overview
4646

4747
## Features
4848

49-
- **Smart Case Conversion**: Automatically detects and converts between different case styles (snake_case, kebab-case, camelCase, PascalCase, SCREAMING_SNAKE_CASE, Train-Case, Title Case, dot.case)
49+
- **Smart Case Conversion**: Automatically detects and converts between different case styles (snake_case, kebab-case, camelCase, PascalCase, SCREAMING_SNAKE_CASE, Train-Case, Title Case, dot.case, lowercase, UPPERCASE)
5050
- **Safe by default**: Plan → Review → Apply workflow prevents accidents
5151
- **Built-in undo/redo**: Full history tracking separate from git. No need to git stash or commit with `--no-verify` before renaming.
5252
- **File and directory renaming**: Rename everything in one atomic operation
@@ -73,6 +73,12 @@ renamify plan myProject betterName --preview diff
7373
# Exclude matches in comments and TODO lines
7474
renamify plan old_name new_name --exclude-matching-lines '^//'
7575
renamify plan old_name new_name --exclude-matching-lines '(TODO|FIXME)'
76+
77+
# Skip renaming files and directories
78+
renamify plan old_name new_name --no-rename-paths
79+
80+
# Ignore ambiguous/mixed-case identifiers
81+
renamify plan old_name new_name --ignore-ambiguous
7682
```
7783

7884
## Demo
@@ -138,6 +144,7 @@ The MCP server and VS Code extension depend on the CLI and must maintain version
138144
- **Patch version**: Independent, can be any value
139145

140146
#### Examples
147+
141148
- CLI `2.3.1` → MCP `2.0.5` ✅ (major matches, minor 0 ≤ 3)
142149
- CLI `2.3.1` → MCP `2.3.9` ✅ (major matches, minor 3 ≤ 3)
143150
- CLI `2.3.1` → MCP `2.4.0` ❌ (minor 4 > 3, might use unavailable features)
@@ -146,6 +153,7 @@ The MCP server and VS Code extension depend on the CLI and must maintain version
146153
### Version Check
147154

148155
The CLI provides version information via:
156+
149157
```bash
150158
renamify version --output json
151159
# {"name":"renamify","version":"0.1.0"}
@@ -217,16 +225,10 @@ cargo clippy --all-targets --all-features
217225
git commit # lefthook will run checks pre-commit
218226
```
219227

220-
## Help Wanted
228+
### Contributing
221229

222-
- **Package Managers**: Help us get Renamify into Homebrew, AUR, Scoop, Chocolatey, etc.
223-
- **Language-Specific Features**: Contribute language-aware renaming (imports, modules, namespaces)
224230
- **Documentation**: Help improve our docs, add more examples, fix any inaccuracies
225231
- **Bug Reports**: Found an issue? Please [report it](https://github.com/DocSpring/renamify/issues)!
226-
227-
### Contributing
228-
229-
- Open an issue if you find a bug or have a feature request
230232
- PRs welcome! All checks must pass (formatting, linting, tests)
231233
- We use [lefthook](https://github.com/evilmartians/lefthook) for git hooks
232234

docs/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.2.0",
2+
"version": "0.1.0",
33
"configurations": [
44
{
55
"command": "./node_modules/.bin/astro dev",

docs/astro.config.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export default defineConfig({
4141
{ label: "Self-Hosting Demo", slug: "self-hosting-demo" },
4242
{ label: "Quick Start", slug: "quick-start" },
4343
{
44-
label: "Why Not Search and Replace?",
45-
slug: "why-not-search-and-replace",
44+
label: "Rename vs. Replace",
45+
slug: "rename-vs-replace",
4646
},
4747
{ label: "FAQ", link: "/#frequently-asked-questions" },
4848
],
@@ -71,6 +71,7 @@ export default defineConfig({
7171
},
7272
{ label: "Safety Features", slug: "features/safety" },
7373
{ label: "Filtering and Ignore Rules", slug: "features/filtering" },
74+
{ label: "Resolving Case Ambiguity", slug: "features/ambiguity-resolution" },
7475
],
7576
},
7677
{
@@ -79,6 +80,7 @@ export default defineConfig({
7980
{ label: "init", slug: "commands/init" },
8081
{ label: "search", slug: "commands/search" },
8182
{ label: "rename", slug: "commands/rename" },
83+
{ label: "replace", slug: "commands/replace" },
8284
{ label: "plan", slug: "commands/plan" },
8385
{ label: "apply", slug: "commands/apply" },
8486
{ label: "dry-run", slug: "commands/dry-run" },

docs/src/content/docs/commands/plan.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ renamify plan <OLD> <NEW> [PATHS]... [OPTIONS]
2929
- `--exclude <PATTERNS>` - Skip files matching these glob patterns
3030
- `--no-rename-files` - Don't rename matching files
3131
- `--no-rename-dirs` - Don't rename matching directories
32+
- `--no-rename-paths` - Don't rename files or directories (equivalent to --no-rename-files --no-rename-dirs)
3233

3334
### Case Styles
3435
- `--exclude-styles <STYLES>` - Exclude specific case styles from the default set

docs/src/content/docs/commands/rename.mdx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ renamify rename <OLD> <NEW> [PATHS]... [OPTIONS]
3030
- `--exclude <PATTERNS>` - Skip files matching these glob patterns
3131
- `--no-rename-files` - Don't rename matching files
3232
- `--no-rename-dirs` - Don't rename matching directories
33+
- `--no-rename-paths` - Don't rename files or directories (equivalent to --no-rename-files --no-rename-dirs)
3334

3435
### Root Directory
3536
- `--rename-root` - Allow renaming the root project directory (requires confirmation)
@@ -39,6 +40,7 @@ renamify rename <OLD> <NEW> [PATHS]... [OPTIONS]
3940
- `--exclude-styles <STYLES>` - Exclude specific case styles from the default set
4041
- `--include-styles <STYLES>` - Add additional case styles to the active set
4142
- `--only-styles <STYLES>` - Use only these case styles, ignoring defaults
43+
- `--ignore-ambiguous` - Ignore mixed-case/ambiguous identifiers that don't match standard patterns
4244

4345
### Match Control
4446
- `--exclude-match <PATTERNS>` - Skip specific matches (e.g., compound words to ignore)
@@ -118,6 +120,18 @@ renamify rename config settings \
118120
--exclude-match ConfigurationManager,ConfigService
119121
```
120122

123+
### Content-Only Rename (No Path Changes)
124+
```bash
125+
# Only modify file contents, don't rename files or directories
126+
renamify rename old_api new_api --no-rename-paths
127+
```
128+
129+
### Ignore Ambiguous Identifiers
130+
```bash
131+
# Skip mixed-case identifiers that don't match standard patterns
132+
renamify rename userName user_name --ignore-ambiguous
133+
```
134+
121135
## Interactive Flow
122136

123137
When you run `rename`, this is what happens:
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
---
2+
title: renamify replace
3+
description: Simple regex or literal string replacement across your codebase
4+
---
5+
6+
The `replace` command performs straightforward search-and-replace operations using regular expressions or literal strings. Unlike the `rename` command which handles case transformations, `replace` is for mechanical replacements where you control the exact pattern and replacement.
7+
8+
## Usage
9+
10+
```bash
11+
renamify replace <PATTERN> <REPLACEMENT> [PATHS]... [OPTIONS]
12+
```
13+
14+
## Arguments
15+
16+
- `<PATTERN>` - Search pattern (regex by default, literal with --no-regex)
17+
- `<REPLACEMENT>` - Replacement string (supports $1, $2 capture groups in regex mode)
18+
- `[PATHS]...` - Search paths (files or directories)
19+
20+
## Options
21+
22+
### Pattern Mode
23+
- `--no-regex` - Treat pattern as literal string instead of regex
24+
25+
### Preview and Confirmation
26+
- `--preview <FORMAT>` - Show preview before confirmation (table, diff, json, none) [default: table]
27+
- `--dry-run` - Show preview only, don't apply changes
28+
- `--yes` / `-y` - Skip confirmation prompt and apply immediately
29+
- `--large` - Acknowledge large changes (>500 files or >100 renames)
30+
31+
### File Processing
32+
- `--include <PATTERNS>` - Only process files matching these glob patterns
33+
- `--exclude <PATTERNS>` - Skip files matching these glob patterns
34+
- `--no-rename-files` - Don't rename matching files
35+
- `--no-rename-dirs` - Don't rename matching directories
36+
- `--no-rename-paths` - Don't rename files or directories
37+
38+
### Line Filtering
39+
- `--exclude-matching-lines <REGEX>` - Skip matches on lines matching this regex pattern
40+
41+
### Safety and Git
42+
- `--commit` - Create a git commit after applying changes
43+
- `--force-with-conflicts` - Force apply even with conflicts
44+
45+
### Unrestricted Mode
46+
- `-u` - Disable .gitignore files
47+
- `-uu` - Disable all ignore files, include hidden files
48+
- `-uuu` - Disable all ignore files, include hidden files, process binary files
49+
50+
## Examples
51+
52+
### Basic Regex Replacement
53+
54+
```bash
55+
# Update version numbers with regex
56+
renamify replace 'version: "(\d+)\.(\d+)\.(\d+)"' 'version: "$1.$2.4"'
57+
58+
# Update import paths with capture groups
59+
renamify replace 'from "\./(.*)"' 'from "@local/$1"'
60+
61+
# Fix method names
62+
renamify replace 'get([A-Z]\w+)ById' 'find$1ById'
63+
```
64+
65+
### Literal String Mode
66+
67+
```bash
68+
# Fix a typo without escaping special characters
69+
renamify replace --no-regex 'array[index]' 'array.at(index)'
70+
71+
# Update exact strings
72+
renamify replace --no-regex 'Copyright (c) 2024' 'Copyright (c) 2025'
73+
74+
# Replace configuration values
75+
renamify replace --no-regex 'localhost:3000' 'api.example.com'
76+
```
77+
78+
### File Type Specific
79+
80+
```bash
81+
# Only in JavaScript files
82+
renamify replace 'console\.log' 'logger.debug' --include "**/*.js"
83+
84+
# Exclude test files
85+
renamify replace 'OLD_API' 'NEW_API' --exclude "**/*.test.*"
86+
```
87+
88+
### With Line Filtering
89+
90+
```bash
91+
# Skip commented lines
92+
renamify replace 'TODO' 'DONE' --exclude-matching-lines '^\s*//'
93+
94+
# Only in import statements
95+
renamify replace '"lodash"' '"lodash-es"' --include "**/*.ts" \
96+
--exclude-matching-lines '^(?!import)'
97+
```
98+
99+
### Large Codebase
100+
101+
```bash
102+
# Acknowledge large changes
103+
renamify replace 'OldComponent' 'NewComponent' --large
104+
105+
# Dry run first to see scope
106+
renamify replace 'deprecated' 'legacy' --dry-run
107+
```
108+
109+
## Regex Features
110+
111+
The replace command uses Rust's regex crate, which supports:
112+
113+
### Capture Groups
114+
115+
```bash
116+
# Swap parameters
117+
renamify replace 'fn\((\w+), (\w+)\)' 'fn($2, $1)'
118+
119+
# Extract and reformat
120+
renamify replace 'user_(\d+)_profile' 'profile/user/$1'
121+
```
122+
123+
### Character Classes
124+
125+
```bash
126+
# Match any whitespace
127+
renamify replace '\s+' ' '
128+
129+
# Match word boundaries
130+
renamify replace '\btest\b' 'spec'
131+
```
132+
133+
### Quantifiers
134+
135+
```bash
136+
# Optional trailing comma
137+
renamify replace ',?\s*\]' ']'
138+
139+
# One or more digits
140+
renamify replace 'id:\d+' 'id:REDACTED'
141+
```
142+
143+
### Lookarounds
144+
145+
```bash
146+
# Positive lookahead
147+
renamify replace '(\w+)(?=\()' 'async $1'
148+
149+
# Negative lookbehind
150+
renamify replace '(?<!\\)n' '\\n'
151+
```
152+
153+
## Important Notes
154+
155+
### No Case Transformation
156+
157+
Unlike `rename`, the `replace` command does NOT:
158+
- Transform between case styles (snake_case, camelCase, etc.)
159+
- Respect token boundaries
160+
- Handle acronyms specially
161+
- Generate style variants
162+
163+
If you need these features, use the `rename` command instead.
164+
165+
### File Renaming
166+
167+
When pattern matches in filenames:
168+
- Files are renamed after content changes
169+
- Directories are renamed depth-first
170+
- Collisions are detected and reported
171+
172+
### Escaping in Regex Mode
173+
174+
Common patterns that need escaping:
175+
- Dots: `\.` for literal dot
176+
- Parentheses: `\(` and `\)` for literal
177+
- Square brackets: `\[` and `\]`
178+
- Special chars: `\$`, `\^`, `\*`, `\+`, `\?`
179+
180+
Use `--no-regex` to avoid escaping entirely.
181+
182+
## Comparison with rename
183+
184+
| Task | Use `rename` | Use `replace` |
185+
|------|--------------|---------------|
186+
| Rename a variable across case styles |||
187+
| Update version numbers |||
188+
| Fix typos |||
189+
| Refactor class names |||
190+
| Update config values |||
191+
| Change import paths |||
192+
| Rename functions preserving style |||
193+
194+
## Interactive Flow
195+
196+
Similar to `rename`, the replace command follows this flow:
197+
198+
1. **Scanning**: Searches for pattern matches
199+
2. **Preview**: Shows planned changes in chosen format
200+
3. **Confirmation**: Prompts "Apply these changes? [y/N]:"
201+
4. **Apply**: Makes changes atomically
202+
5. **Results**: Shows operation ID for undo
203+
204+
## Exit Codes
205+
206+
- `0` - Success
207+
- `1` - Conflicts detected (use `--force-with-conflicts` to override)
208+
- `2` - Invalid input or arguments
209+
- `3` - Internal error or system issue
210+
211+
## See Also
212+
213+
- [rename](./rename) - Case-aware identifier renaming
214+
- [plan](./plan) - Create a replacement plan without applying
215+
- [undo](./undo) - Revert the last operation

docs/src/content/docs/commands/search.mdx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,22 @@ renamify search <term> [paths...] [options]
2929
- `--include-styles <styles>` - Include additional case styles (title, dot)
3030
- `--only-styles <styles>` - Use only these case styles (overrides defaults)
3131

32-
Available styles: `original`, `snake`, `kebab`, `camel`, `pascal`, `screaming-snake`, `train`, `screaming-train`, `title`, `dot`
32+
Available styles: `snake`, `kebab`, `camel`, `pascal`, `screaming-snake`, `train`, `screaming-train`, `title`, `dot`, `lower`, `upper`
3333

3434
### Line Filtering
3535

3636
- `--exclude-matching-lines <regex>` - Skip matches on lines matching this regex pattern
3737

38+
### File and Directory Renaming
39+
40+
- `--no-rename-files` - Don't include file renames in search results
41+
- `--no-rename-dirs` - Don't include directory renames in search results
42+
- `--no-rename-paths` - Don't include any file or directory renames (equivalent to --no-rename-files --no-rename-dirs)
43+
44+
### Case Detection
45+
46+
- `--ignore-ambiguous` - Ignore mixed-case/ambiguous identifiers that don't match standard patterns
47+
3848
### Output Control
3949

4050
- `--preview <format>` - Preview format: `table`, `diff`, `matches`, `summary` (default: summary)
@@ -98,6 +108,18 @@ renamify search myIdentifier --only-styles snake,kebab
98108
renamify search importantFunction --exclude-matching-lines "^\\s*//"
99109
```
100110

111+
### Search Without File Renames
112+
113+
```bash
114+
renamify search myFunction --no-rename-paths
115+
```
116+
117+
### Ignore Ambiguous Identifiers
118+
119+
```bash
120+
renamify search cleanName --ignore-ambiguous
121+
```
122+
101123
### JSON Output for Processing
102124

103125
```bash

0 commit comments

Comments
 (0)