Skip to content

Commit 5348815

Browse files
authored
Merge pull request #1 from DocSpring/nathan/atomic-identifiers
2 parents c6d1e45 + 19e4a4f commit 5348815

Some content is hidden

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

51 files changed

+2478
-125
lines changed

.taskmaster/docs/atomic-prd.txt

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# Atomic Identifiers Feature - Product Requirements Document
2+
3+
## Executive Summary
4+
Add support for treating certain identifiers as "atomic" - indivisible units that should not have word boundaries detected during case transformations. This solves the problem where compound brand names like "DocSpring" or "GitHub" need to maintain their identity as single words in all case styles.
5+
6+
## Problem Statement
7+
Currently, when renaming identifiers like "DocSpring" or "GitHub", renamify detects word boundaries and generates variants like:
8+
- `doc_spring` (snake_case)
9+
- `doc-spring` (kebab-case)
10+
- `DOC_SPRING` (SCREAMING_SNAKE_CASE)
11+
12+
However, these brand names should be treated as single, indivisible units:
13+
- `docspring` (snake_case)
14+
- `docspring` (kebab-case)
15+
- `DOCSPRING` (SCREAMING_SNAKE_CASE)
16+
- `DocSpring` (PascalCase - the only time there is a word break)
17+
18+
This is similar to Rails' `inflect.acronym` feature, but for compound words that aren't acronyms.
19+
20+
## User Stories
21+
22+
### Story 1: CLI User with Atomic Identifiers
23+
As a developer renaming "HubGit" to "GitHub" in my codebase,
24+
I want to specify that both names are atomic,
25+
So that `hubgit_api` becomes `github_api` (not `git_hub_api`).
26+
27+
### Story 2: Project with Persistent Atomic Configuration
28+
As a team maintaining a project with brand names like "DocSpring",
29+
I want to configure these as atomic in a config file,
30+
So that all team members automatically get correct renaming behavior.
31+
32+
### Story 3: VS Code Extension User
33+
As a VS Code user,
34+
I want checkboxes to mark search/replace terms as atomic,
35+
So that I can control word boundary detection visually.
36+
37+
### Story 4: Partial Atomic Matching
38+
As a developer with "FormAPIController" in my code,
39+
I want atomic "FormAPI" to match and replace the atomic portion correctly,
40+
So that it becomes "DocSpringController" (not "DocSpringAPIController").
41+
42+
## Functional Requirements
43+
44+
### 1. Core Atomic Detection
45+
- When an identifier is marked as atomic, it should be treated as a single token
46+
- Atomic identifiers should not have internal word boundaries detected
47+
- The atomic property applies to the identifier wherever it appears (standalone or as part of larger identifiers)
48+
49+
### 2. CLI Flags
50+
- `--atomic` - Both search and replace are atomic
51+
- `--atomic-search` - Only search term is atomic
52+
- `--atomic-replace` - Only replace term is atomic
53+
- `--no-atomic` - Override config, treat as normal
54+
- `--no-atomic-search` - Override config for search term
55+
- `--no-atomic-replace` - Override config for replace term
56+
- Error if user specifies both `--atomic` and `--atomic-search`/`--atomic-replace`
57+
58+
### 3. Configuration File
59+
- Support `atomic = ["DocSpring", "GitHub", "GitHub"]` in `.renamify/config.toml`
60+
- Config entries are case-insensitive matched (PascalCase in config matches all cases)
61+
- Config auto-applies when matching identifiers are used
62+
- CLI flags override config settings
63+
64+
### 4. Variant Generation
65+
For atomic identifier "DocSpring":
66+
- Generate only: `DocSpring`, `docspring`, `DOCSPRING`
67+
- Do NOT generate: `doc_spring`, `DOC_SPRING`, `doc-spring`, `docSpring`
68+
69+
### 5. Compound Identifier Handling
70+
When "FormAPI" is atomic:
71+
- `FormAPIController` → `DocSpringController`
72+
- `form_api_client` → `docspring_client`
73+
- `FORMAPI_TOKEN` → `DOCSPRING_TOKEN`
74+
- The atomic portion is preserved as a unit within larger identifiers
75+
76+
### 6. VS Code Extension
77+
- Add "Atomic" checkbox under Search field with tooltip
78+
- Add "Atomic" checkbox under Replace field with tooltip
79+
- Tooltips explain: "Treat as indivisible (no word boundaries)"
80+
- Pre-check boxes if terms match config entries
81+
82+
### 7. MCP Server
83+
- Add `atomicSearch: boolean` parameter
84+
- Add `atomicReplace: boolean` parameter
85+
- Read and respect `.renamify/config.toml` atomic entries
86+
87+
## Technical Requirements
88+
89+
### 1. Case Model Refactoring
90+
- Split `case_model.rs` into smaller modules (it's currently 1100 lines)
91+
- Create `atomic.rs` module for atomic-specific logic
92+
- Maintain backward compatibility
93+
94+
### 2. Token Generation
95+
- Modify `parse_to_tokens` to accept atomic hints
96+
- When atomic, return single token regardless of internal capitals
97+
- Preserve existing behavior when not atomic
98+
99+
### 3. Variant Map Generation
100+
- Update `generate_variant_map` to accept atomic flags
101+
- Generate limited variants for atomic identifiers
102+
- Handle mixed atomic/non-atomic scenarios
103+
104+
### 4. Testing
105+
- Unit tests for atomic token parsing
106+
- Integration tests for compound identifiers
107+
- End-to-end tests with real examples (DocSpring, GitHub)
108+
- Performance tests to ensure no regression
109+
110+
## Non-Functional Requirements
111+
112+
### 1. Performance
113+
- Atomic detection should not significantly impact scan performance
114+
- Config file parsing should be cached
115+
116+
### 2. Documentation
117+
- Create "Atomic Identifiers" page in Features section
118+
- Include examples of when to use atomic mode
119+
- Document config file format
120+
121+
### 3. Error Handling
122+
- Clear error messages for conflicting flags
123+
- Warn if atomic identifier contains delimiters
124+
125+
## Acceptance Criteria
126+
127+
### Test Case 1: Basic Atomic Renaming
128+
```bash
129+
renamify rename GitLab GitHub --atomic
130+
```
131+
- `git_lab_api` → `GitHub_api`
132+
- `GIT_LAB_TOKEN` → `GitHub_TOKEN`
133+
- `GitLabController` → `GitHubController`
134+
135+
### Test Case 2: Config File Auto-Application
136+
`.renamify/config.toml`:
137+
```toml
138+
atomic = ["DocSpring"]
139+
```
140+
```bash
141+
renamify rename DocSpring Helper
142+
```
143+
- `docspring_api` → `helper_api` (NOT `doc_spring_api` → `helper_api`)
144+
145+
### Test Case 3: Partial Identifier Matching
146+
```bash
147+
renamify rename FormAPI DocSpring --atomic
148+
```
149+
- `FormAPIController` → `DocSpringController`
150+
- `useFormAPIHook` → `useDocSpringHook`
151+
152+
### Test Case 4: Override Config
153+
`.renamify/config.toml`:
154+
```toml
155+
atomic = ["DocSpring"]
156+
```
157+
```bash
158+
renamify rename DocSpring doc_spring --no-atomic-search
159+
```
160+
- `DocSpring` → `doc_spring` (word boundary detected due to override)
161+
162+
## Implementation Plan
163+
164+
### Phase 1: Core Support (Week 1)
165+
1. Refactor case_model.rs into modules
166+
2. Implement atomic token parsing
167+
3. Update variant generation
168+
4. Add comprehensive tests
169+
170+
### Phase 2: CLI Integration (Week 1)
171+
1. Add CLI flags
172+
2. Implement config file support
173+
3. Wire up to plan operation
174+
4. Add integration tests
175+
176+
### Phase 3: UI Integration (Week 2)
177+
1. Update VS Code extension
178+
2. Update MCP server
179+
3. Add tooltips and help text
180+
4. End-to-end testing
181+
182+
### Phase 4: Documentation (Week 2)
183+
1. Create atomic identifiers documentation
184+
2. Update existing docs with atomic examples
185+
3. Add to README and help text
186+
187+
## Success Metrics
188+
- All test cases pass
189+
- No performance regression (scan time within 5% of baseline)
190+
- User feedback positive on solving word boundary issues
191+
- Documentation clear (no support questions about basic usage)
192+
193+
## Risks and Mitigations
194+
195+
### Risk 1: Breaking Changes
196+
**Mitigation**: Atomic mode is opt-in, existing behavior unchanged by default
197+
198+
### Risk 2: Performance Impact
199+
**Mitigation**: Early detection during parsing, benchmark before/after
200+
201+
### Risk 3: User Confusion
202+
**Mitigation**: Clear documentation, intuitive naming ("atomic"), helpful tooltips
203+
204+
## Future Enhancements
205+
- Support for regex patterns in atomic config
206+
- Auto-detection of likely atomic identifiers based on casing patterns
207+
- Project-specific dictionaries of atomic terms
208+
- Integration with language-specific naming conventions

CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ Exit codes:
136136

137137
- append only with checksums and revert info
138138

139+
`.renamify/config.toml`
140+
141+
- Project configuration including atomic identifiers
142+
- `atomic = ["DocSpring", "GitHub", "GitHub"]` - identifiers treated as indivisible units
143+
139144
## Search and plan algorithm
140145

141146
1. Detect input case of `<old>` and `<new>`

docs/astro.config.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ export default defineConfig({
6363
label: 'Resolving Case Ambiguity',
6464
slug: 'features/ambiguity-resolution',
6565
},
66+
{
67+
label: 'Atomic Identifiers',
68+
slug: 'features/atomic-identifiers',
69+
},
6670
],
6771
},
6872
{

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ renamify plan <OLD> <NEW> [PATHS]... [OPTIONS]
5858
- `--exclude-acronyms <ACRONYMS>` - Exclude specific acronyms from detection
5959
- `--only-acronyms <ACRONYMS>` - Only use these acronyms, ignore defaults
6060

61+
### Atomic Mode
62+
63+
"Atomic" means treating a search or replace identifier as a single unit,
64+
not splitting it into separate components. E.g. GitHub → github, not git_hub
65+
66+
- `--atomic` - Treat both search and replace terms as indivisible units
67+
- `--atomic-search` - Only treat search term as atomic
68+
- `--atomic-replace` - Only treat replace term as atomic
69+
- `--no-atomic` - Disable atomic mode (override config)
70+
- `--no-atomic-search` - Disable atomic for search term
71+
- `--no-atomic-replace` - Disable atomic for replace term
72+
6173
### Display Options
6274

6375
- `--fixed-table-width` - Use fixed column widths in table output for consistent
@@ -171,6 +183,19 @@ renamify plan old_name new_name src/ tests/
171183
renamify plan old_name new_name --dry-run
172184
```
173185

186+
### Atomic Mode
187+
188+
```bash
189+
# Treat compound words as single units
190+
renamify plan DocSpring FormAPI --atomic
191+
192+
# Only search term is atomic
193+
renamify plan DocSpring form_api --atomic-search
194+
195+
# Only replace term is atomic
196+
renamify plan doc_spring FormAPI --atomic-replace
197+
```
198+
174199
### Excluding Lines by Pattern
175200

176201
```bash

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ renamify rename <OLD> <NEW> [PATHS]... [OPTIONS]
6767
- `--exclude-acronyms <ACRONYMS>` - Exclude specific acronyms from detection
6868
- `--only-acronyms <ACRONYMS>` - Only use these acronyms, ignore defaults
6969

70+
### Atomic Mode
71+
72+
"Atomic" means treating a search or replace identifier as a single unit,
73+
not splitting it into separate components. E.g. GitHub → github, not git_hub
74+
75+
- `--atomic` - Treat both search and replace terms as indivisible units
76+
- `--atomic-search` - Only treat search term as atomic
77+
- `--atomic-replace` - Only treat replace term as atomic
78+
- `--no-atomic` - Disable atomic mode (override config)
79+
- `--no-atomic-search` - Disable atomic for search term
80+
- `--no-atomic-replace` - Disable atomic for replace term
81+
7082
### Display Options
7183

7284
- `--fixed-table-width` - Use fixed column widths in table output for consistent
@@ -114,6 +126,16 @@ renamify rename oldApi newApi \
114126
--exclude "**/*test*,node_modules/**"
115127
```
116128

129+
### Atomic Mode
130+
131+
```bash
132+
# Treat compound words as single units
133+
renamify rename DocSpring FormAPI --atomic
134+
135+
# Without --atomic, DocSpring would match doc_spring in snake_case
136+
# With --atomic, DocSpring only matches docspring (as single unit)
137+
```
138+
117139
### Case Style Control
118140

119141
```bash

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ Available styles: `snake`, `kebab`, `camel`, `pascal`, `screaming-snake`,
5454
- `--ignore-ambiguous` - Ignore mixed-case/ambiguous identifiers that don't
5555
match standard patterns
5656

57+
### Atomic Mode
58+
59+
- `--atomic` - Treat the search term as an indivisible unit (no word boundaries)
60+
- `--atomic-search` - Same as `--atomic` for search command
61+
- `--no-atomic` - Disable atomic mode (override config)
62+
- `--no-atomic-search` - Same as `--no-atomic` for search command
63+
5764
### Output Control
5865

5966
- `--preview <format>` - Preview format: `table`, `diff`, `matches`, `summary`
@@ -132,6 +139,15 @@ renamify search myFunction --no-rename-paths
132139
renamify search cleanName --ignore-ambiguous
133140
```
134141

142+
### Atomic Search
143+
144+
Search for compound words as single units:
145+
146+
```bash
147+
# DocSpring will match as a whole word, not doc_spring
148+
renamify search DocSpring --atomic
149+
```
150+
135151
### JSON Output for Processing
136152

137153
```bash

0 commit comments

Comments
 (0)