Project 2: The JSON Surgeon (Text Objects)
Perform precise, structural edits on JSON using text objects and operators without breaking syntax.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Level 2: Intermediate |
| Time Estimate | 6-10 hours |
| Main Programming Language | JSON |
| Alternative Programming Languages | YAML |
| Coolness Level | Level 2: Precision Tooling |
| Business Potential | 3: Data cleaner |
| Prerequisites | Basic motions, search, Normal/Insert mode |
| Key Topics | Text objects, change/delete operators, delimiters |
1. Learning Objectives
By completing this project, you will:
- Edit JSON values using text objects without damaging quotes or braces.
- Use operator + text object grammar to delete and change nested structures.
- Remove or reorder array elements while preserving commas.
- Use search + repeat to apply changes across a file.
- Build confidence in structural edits without visual selection.
2. All Theory Needed (Per-Concept Breakdown)
2.1 Text Objects and Delimiter Awareness
Fundamentals
Text objects are Vim’s way of selecting meaning rather than coordinates. In JSON, structure is expressed by delimiters: quotes, brackets, braces, and commas. Text objects like i", a", i{, a{, i], and a] let you target the inside or the whole container without counting characters. This is essential for JSON because one stray deletion can break the structure.
The “inner” (i) and “around” (a) variants define how much you include. i" means the string without quotes; a" includes the quotes. i{ selects the body of an object; a{ includes the braces. Knowing this difference is how you remove a whole object safely or change a value without touching punctuation.
Deep Dive into the concept
Text objects are context-aware. They do not care where you are inside the object; they find the nearest matching delimiters. This makes them resilient to cursor placement. In JSON, where nested objects and arrays are common, this matters because you are often not on the first character of the value you want to change. Text objects reduce risk by making your command based on structure rather than position.
There is a subtle but powerful distinction between motions and objects. A motion like w or e is about moving the cursor. A text object is about selecting a region. When you combine an operator with a text object, you are not moving then acting; you are acting on a semantic region. This is why ci" is so reliable for JSON values: it ignores how long the value is and focuses on the object boundaries.
How this fits on projects
- You will use
ci"to change JSON values safely. - You will use
da{anddi]to remove structures without breaking the file.
Definitions & key terms
- Text object: A semantic region defined by structure, not position.
- Inner (
i) vs Around (a): Exclude vs include delimiters. - Delimiter: Characters that define structure (quotes, braces, brackets).
Mental model diagram (ASCII)
"value" -> i" selects value, a" selects "value"
{ ... } -> i{ selects inside, a{ selects braces + inside
[ ... ] -> i] selects inside, a] selects brackets + inside

How it works (step-by-step)
- Place the cursor anywhere inside a JSON value or container.
- Choose an operator (
c,d,y). - Choose
ioradepending on whether delimiters should remain. - Vim expands the region to the nearest matching delimiters and applies the operator.
Minimal concrete example
ci"admin<Esc> " change string value
ca{ " change entire object including braces
di] " delete inside array (keeps brackets)
Common misconceptions
- “You must be at the start”: Text objects work anywhere inside.
- “Text objects are only for Visual mode”: They work with operators directly.
- “Inner/around are interchangeable”: They change whether delimiters survive.
Check-your-understanding questions
- What does
ci"do in JSON, and why is it safer thancw? - When would you use
da{instead ofdi{? - What does
a]include?
Check-your-understanding answers
- It changes the content inside quotes without touching the quotes themselves.
- Use
da{when you want to remove the entire object including braces. - The brackets and everything inside them.
Real-world applications
- Editing API payloads in config files.
- Safely changing values in large JSON documents.
- Removing objects in data migrations.
Where you’ll apply it
- See Section 3.4 Example Usage / Output and Section 5.10 Implementation Phases in this project.
- Also used in: Project 3: Code Refactor and Project 6: HTML Tag Wrapper.
References
:help text-objects- “Practical Vim” Ch. 4
Key insights
Text objects let you edit structure without counting characters.
Summary
JSON is all structure. Text objects are your safest and fastest way to operate on that structure without breaking it.
Homework/Exercises to practice the concept
- Change three JSON string values using
ci". - Delete an entire object with
da{and observe the commas.
Solutions to the homework/exercises
- Place the cursor inside each string and run
ci"newvalue<Esc>. - Place the cursor inside the object and use
da{to remove it.
2.2 Operator Grammar for Structural Editing
Fundamentals
Operators define what you do; text objects define what you operate on. In JSON editing, the most common operators are change (c), delete (d), and yank (y). The grammar is always the same: operator + text object. When you master this, you can refactor JSON without leaving Normal mode.
The change operator is especially powerful because it deletes the selection and puts you in Insert mode immediately. This means you can replace a value in one command and then repeat it with .. The delete operator removes a region but keeps you in Normal mode, which is useful for removing objects or array elements while continuing navigation.
Deep Dive into the concept
Structural editing in JSON often fails because of commas. Vim’s operator grammar gives you control over whether you include delimiters or not. For example, deleting an array element with di] removes the content but leaves the brackets. If you need to remove an element including a trailing comma, you might use da, or dt, first, then delete the element. The point is that the grammar makes you explicit about your intent.
Another deep detail is that some operators have linewise behavior when doubled (dd, yy). This matters when you are editing pretty-printed JSON, because you might prefer to delete whole lines rather than partial structures. Choosing between structural text objects and linewise operators is part of the skill.
How this fits on projects
- You will use
cwithi"to change values. - You will use
dwitha{anda[to remove structures safely.
Definitions & key terms
- Operator: The action (change, delete, yank).
- Operator-pending: The state after typing an operator, waiting for a target.
- Linewise: Operator applies to full lines (e.g.,
dd).
Mental model diagram (ASCII)
[operator] + [text object] -> [structural change]
c i" -> change string value
d a{ -> delete object with braces

How it works (step-by-step)
- Choose the operator based on intent (change vs delete).
- Choose the text object that matches the structure.
- Apply the operator and verify the JSON remains valid.
- Repeat with
.if the change pattern repeats.
Minimal concrete example
ci"admin<Esc>
da{ " delete entire object
.` " repeat last change on next value
Common misconceptions
- “Visual mode is safer”: Operator + text object is usually safer.
- “Change requires extra steps”:
calready enters Insert mode. - “Dot repeat only works sometimes”: It works if the change is a single command.
Check-your-understanding questions
- Why is
ci"more repeatable thandi"theni? - What does
dddo in a pretty-printed JSON file? - How do you delete an object including braces?
Check-your-understanding answers
- It is a single command and can be repeated with
.. - It deletes the entire current line.
- Use
da{.
Real-world applications
- Refactoring config files at scale.
- Editing API fixtures or test data quickly.
- Cleaning up JSON logs.
Where you’ll apply it
- See Section 3.2 Functional Requirements and Section 7.1 Frequent Mistakes in this project.
- Also used in: Project 10: Search-Replace Master.
References
:help operator- “Practical Vim” Ch. 1
Key insights
Operators let you express intent; text objects make it safe.
Summary
Operator grammar is the backbone of structural editing. JSON becomes safe to edit when you act on objects, not on characters.
Homework/Exercises to practice the concept
- Replace five JSON values using
ci"and repeat with.. - Delete an object using
da{and fix trailing commas if needed.
Solutions to the homework/exercises
- Use search to find each value, then
.to repeat. - After
da{, remove the dangling comma withxorda,.
2.3 Structural Safety: Commas, Arrays, and Registers
Fundamentals
JSON validity depends on punctuation. Commas separate elements, and missing or extra commas break the file. When editing arrays, you must consider whether you are removing the element, the separator, or both. Registers help you avoid overwriting important text when you need to paste values elsewhere.
A simple rule: deleting an element in the middle of an array should usually delete the element and its trailing comma. Deleting the last element should delete the preceding comma. Understanding this prevents syntax errors. Registers become useful when you want to copy a value and reuse it without clobbering the default register with deletions.
Deep Dive into the concept
The safest strategy is to think of commas as belonging to the element that precedes them. If you remove an element in the middle, remove its trailing comma. If you remove the last element, remove the preceding comma. Vim gives you fine control: da, will delete through the comma, while di] deletes inside brackets but leaves commas. You can mix operations: use di] to clear an array, then paste new values from a register.
Registers are critical because delete operations overwrite the default register. If you plan to paste a value later, yank it into a named register first (e.g., "ayiw). Then you can delete freely without losing the saved value. For JSON editing, this is especially useful when you need to copy a key or a value across multiple objects.
How this fits on projects
- You will remove array elements while preserving valid commas.
- You will reuse values by yanking into named registers.
Definitions & key terms
- Separator: A comma that separates JSON elements.
- Named register: A lettered register (
"ato"z) that preserves content. - Default register: The unnamed register overwritten by deletes/yanks.
Mental model diagram (ASCII)
["a", "b", "c"]
^ element + comma belongs together
delete middle -> remove "b",

How it works (step-by-step)
- Identify if the element is middle or last.
- Use
da,for middle elements (removes trailing comma). - Use
di]then delete a preceding comma for last elements. - Yank reusable values into named registers before deleting.
Minimal concrete example
"ayiw " yank word into register a
/"b"<Enter>
da, " delete element plus trailing comma
"ap " paste from register a
Common misconceptions
- “Deleting inside brackets is enough”: It may leave invalid commas.
- “Registers are only for advanced users”: Named registers save time and prevent mistakes.
- “JSON is too strict for Vim”: Text objects make it safe.
Check-your-understanding questions
- What happens if you delete only the element but not its comma?
- Why use a named register for JSON edits?
- How do you delete the last element in an array safely?
Check-your-understanding answers
- You likely leave an extra comma, which breaks JSON.
- Deletes overwrite the default register; named registers preserve values.
- Delete the element, then remove the preceding comma.
Real-world applications
- Editing large JSON configs or API payloads.
- Cleaning data exports or fixtures.
- Moving data fields between objects.
Where you’ll apply it
- See Section 3.6 Edge Cases and Section 5.8 Hints in Layers in this project.
- Also used in: Project 5: Log Parser.
References
:help registers- “Practical Vim” Ch. 10
Key insights
Commas are part of the structure; handle them explicitly.
Summary
Structural safety in JSON is all about punctuation and registers. When you treat commas and registers intentionally, you stop breaking the file.
Homework/Exercises to practice the concept
- Delete a middle element in an array without breaking JSON.
- Yank a value into register
aand paste it into another object.
Solutions to the homework/exercises
- Use
da,on the element, then check the array syntax. "ayiwto yank, then"apto paste.
3. Project Specification
3.1 What You Will Build
You will build a set of JSON editing drills that transform a nested payload into a new version using only Vim motions, text objects, and operators. The deliverable is a before/after JSON pair plus a short command log describing the key edits.
3.2 Functional Requirements
- Input File: Create
payload.jsonwith nested objects and arrays. - Value Changes: Update at least 8 string or numeric values using text objects.
- Structural Edits: Remove at least 2 objects and 2 array elements safely.
- Search Workflow: Use
/andnto repeat changes across similar keys. - Command Log: Record the exact Vim commands used for each change.
3.3 Non-Functional Requirements
- Safety: The JSON must remain valid after each change.
- Repeatability: Changes should be repeatable using
.where possible. - Clarity: The command log must be understandable to another learner.
3.4 Example Usage / Output
# Before
{"role": "guest", "tags": ["trial", "low-priority"]}
# Commands
ci"admin<Esc>
/low-priority<Enter>
da]
# After
{"role": "admin", "tags": ["trial"]}
3.5 Data Formats / Schemas / Protocols
Use standard JSON with nested objects and arrays. Example schema:
{
"user": { "name": "", "role": "", "tags": [] },
"active": true,
"limits": { "max": 0, "min": 0 }
}
3.6 Edge Cases
- Removing the last element in an array.
- Changing a value that appears multiple times.
- Nested objects two or three levels deep.
- Mixed quotes and escaped characters.
3.7 Real World Outcome
You will have a JSON file that remains valid after multiple structural edits, plus a command log proving you used text objects.
3.7.1 How to Run (Copy/Paste)
vim payload.json
3.7.2 Golden Path Demo (Deterministic)
- Search for
"role". - Use
ci"admin<Esc>. - Search for
"tags"and usedi]to remove an element.
Expected result:
"role": "admin",
"tags": ["trial"]
3.7.3 Failure Demo (Deterministic)
If you delete an element without its comma, JSON becomes invalid:
"tags": ["trial", ]
3.7.4 If CLI
Not applicable.
3.7.5 If Web App
Not applicable.
3.7.6 If API
Not applicable.
3.7.7 If Library
Not applicable.
3.7.8 If TUI
ASCII layout while editing:
+--------------------------------------+
| payload.json |
| { |
| "user": { |
| "name": "John", |
| "role": "|guest", |
| "tags": ["trial", "low"] |
| } |
| } |
| -- NORMAL -- |
+--------------------------------------+


Key interactions:
ci"to change stringsda{to delete objects/pattern+nto repeat
4. Solution Architecture
4.1 High-Level Design
+----------------+ +-------------------+ +--------------------+
| JSON Payload | -> | Vim Commands | -> | Validated Output |
+----------------+ +-------------------+ +--------------------+

4.2 Key Components
| Component | Responsibility | Key Decisions |
|---|---|---|
| Payload file | Provide nested structure | Include arrays + objects |
| Command log | Track edits and commands | Keep chronological order |
| Validation step | Ensure JSON validity | Use jq . if available |
4.3 Data Structures (No Full Code)
CommandLogEntry:
- location (line/field)
- command sequence
- expected result
4.4 Algorithm Overview
Key Algorithm: Safe Structural Edit
- Search for target key.
- Use text object to select value or container.
- Apply operator (
cord). - Repeat with
.when pattern repeats.
Complexity Analysis:
- Time: O(k) keystrokes per edit
- Space: O(1)
5. Implementation Guide
5.1 Development Environment Setup
# Use a JSON formatter for validation (optional)
command -v jq
5.2 Project Structure
json-surgeon/
|-- payload.json
|-- payload_after.json
`-- command_log.md
5.3 The Core Question You’re Answering
“How do I edit structured data without breaking its structure?”
5.4 Concepts You Must Understand First
- Inner vs around text objects (
i"vsa") - Change vs delete operators (
cvsd) - Handling commas in arrays
5.5 Questions to Guide Your Design
- Is this change best done with
ci"orcaw? - Do I need to remove a comma with the element?
- Can I repeat the same edit with
.?
5.6 Thinking Exercise
Given "status": "pending", write the shortest command to change it to approved.
5.7 The Interview Questions They’ll Ask
- “What is the difference between
ci"andda"?” - “How do you delete an object including braces?”
- “What does
a[select?”
5.8 Hints in Layers
Hint 1: Use inner objects for values
ci" keeps quotes intact.
Hint 2: Use around objects for deletion
da{ removes an entire object safely.
Hint 3: Watch commas
da, removes the separator too.
Hint 4: Repeat
Use n . to apply the same change to the next key.
5.9 Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| Text objects | “Practical Vim” | Ch. 4 |
| Operators | “Practical Vim” | Ch. 1 |
5.10 Implementation Phases
Phase 1: Payload Preparation (1-2 hours)
Goals:
- Create a nested JSON payload with arrays.
- Identify fields to change.
Tasks:
- Write a JSON file with at least 3 nested objects.
- Add an array with 5 elements.
Checkpoint: JSON validates with jq ..
Phase 2: Structural Edits (3-4 hours)
Goals:
- Perform changes using text objects.
- Record commands.
Tasks:
- Change 8 values using
ci"orci]. - Delete 2 objects with
da{. - Remove 2 array elements using
da,.
Checkpoint: JSON still validates after each change.
Phase 3: Repeatability (1-2 hours)
Goals:
- Use dot repeat and search patterns.
Tasks:
- Apply a repeated change with
n .at least 5 times. - Write down a repeatable sequence in the command log.
Checkpoint: You can explain why the sequence is repeatable.
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Validation | Manual / jq |
Use jq |
Immediate feedback |
| Deleting elements | di] / da, |
da, for middle elements |
Removes separator safely |
| Repetition | Manual / . |
Use . |
Faster and consistent |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Validity checks | Ensure JSON remains valid | jq . payload.json |
| Repeatability | Confirm dot repeat works | n . across keys |
| Structural edits | Verify object removal | Delete an object and revalidate |
6.2 Critical Test Cases
- Middle array deletion: Remove element plus comma.
- Nested object deletion: Delete a child object with
da{}. - Repeated value change: Apply
n .across multiple keys.
6.3 Test Data
{"tags": ["alpha", "beta", "gamma"], "role": "guest"}
7. Common Pitfalls & Debugging
7.1 Frequent Mistakes
| Pitfall | Symptom | Solution |
|---|---|---|
| Broken commas | JSON fails to parse | Delete element + comma (da,) |
| Wrong object deleted | Missing braces or fields | Use a{ instead of i{ |
| Lost yanked value | Cannot paste previous text | Use named registers |
7.2 Debugging Strategies
- Validate with
jqafter each major edit. - Use
uto undo quickly when a structural edit goes wrong.
7.3 Performance Traps
- Overusing visual mode for repeated edits.
- Counting characters instead of using text objects.
8. Extensions & Challenges
8.1 Beginner Extensions
- Replace all boolean values using
ciw. - Practice
di"on multiple strings.
8.2 Intermediate Extensions
- Convert an array of objects into a different shape.
- Use registers to move a value between objects.
8.3 Advanced Extensions
- Perform the same edits on a minified JSON file.
- Use macros to apply the same change across arrays.
9. Real-World Connections
9.1 Industry Applications
- Editing configuration files on servers without a JSON editor.
- Quickly patching API payloads during debugging.
9.2 Related Open Source Projects
- jq: Command-line JSON processor; complement to Vim edits.
- Vim: Built-in text objects make JSON editing viable without plugins.
9.3 Interview Relevance
- Demonstrates ability to edit structured data safely under pressure.
10. Resources
10.1 Essential Reading
- “Practical Vim” Ch. 4 (text objects)
- “Practical Vim” Ch. 1 (operators)
10.2 Video Resources
- Vim text objects tutorials
- Vimcasts on structured editing
10.3 Tools & Documentation
:help text-objects:help operator
10.4 Related Projects in This Series
11. Self-Assessment Checklist
11.1 Understanding
- I can explain
i"vsa". - I can describe how to delete an object without breaking JSON.
- I can explain why commas matter in arrays.
11.2 Implementation
- All required edits are complete.
- JSON validates after each change.
- Command log is complete and readable.
11.3 Growth
- I can apply the same workflow to YAML or config files.
- I can teach someone how to use text objects for JSON.
12. Submission / Completion Criteria
Minimum Viable Completion:
- Changed 8 values using text objects.
- Deleted 2 objects and 2 array elements safely.
- Provided a command log.
Full Completion:
- All minimum criteria plus:
- Used
.to repeat a change at least 5 times. - Validated JSON with
jqor similar tool.
Excellence (Going Above & Beyond):
- Completed edits on a minified JSON file without reformatting.
- Demonstrated safe edits under time pressure (5-minute drill).