Skip to main content
Inline Editing provides surgical, AI-powered code modifications using the replace_in_file tool. Make targeted changes to specific functions, variables, or code sections without rewriting entire files.
Inline editing in action

How It Works

Inline Editing uses a SEARCH/REPLACE block pattern for precise modifications:
// SEARCH
function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price, 0)
}

// REPLACE
function calculateTotal(items: Item[]): number {
  return items.reduce((sum, item) => sum + item.price, 0)
}
The AI:
  1. Searches for the exact code block in the file
  2. Replaces it with the modified version
  3. Preserves surrounding code untouched
  4. Handles auto-formatting automatically
Inline Editing is powered by the replace_in_file tool, designed for efficiency and precision.

When to Use Inline Editing

Inline Editing excels at:

Function Updates

Modify function implementations, signatures, or logic

Variable Renames

Change variable names throughout a file

Import Statements

Add, remove, or modify imports

Type Annotations

Add TypeScript types to existing code

Bug Fixes

Fix specific issues without touching working code

Refactoring

Update patterns across a file
For major restructuring or creating new files, use write_to_file instead. See Inline Editing vs write_to_file.

SEARCH/REPLACE Syntax

Single Block

Modify one section of code:
<SEARCH>
existing code to find
</SEARCH>
<REPLACE>
new code to insert
</REPLACE>

Multiple Blocks

Make several changes in one operation:
<SEARCH>
import { useState } from 'react'
</SEARCH>
<REPLACE>
import { useState, useEffect } from 'react'
</REPLACE>

<SEARCH>
const [count, setCount] = useState(0)
</SEARCH>
<REPLACE>
const [count, setCount] = useState(0)

useEffect(() => {
  console.log('Count changed:', count)
}, [count])
</REPLACE>
Best Practice: Use a single replace_in_file call with multiple SEARCH/REPLACE blocks rather than multiple separate calls.
See: src/core/prompts/system-prompt/components/editing_files.ts:75

Inline Editing vs write_to_file

Use when:
  • Making small, localized changes
  • Updating specific functions or sections
  • File content is mostly unchanged
  • You need surgical precision
Advantages:
  • More efficient (no need to send full file)
  • Lower chance of errors
  • Preserves unchanged sections perfectly
  • Safer for large files
Example use cases:
  • Fix a bug in one function
  • Add a new import
  • Update variable names
  • Modify configuration values
See: src/core/prompts/system-prompt/components/editing_files.ts:59

Auto-Formatting Handling

Inline Editing intelligently handles editor auto-formatting:
1

Initial Edit

AI makes the change using replace_in_file.
2

Editor Formats

Your editor (Prettier, ESLint, etc.) auto-formats the file:
  • Adjusts indentation
  • Converts quotes
  • Organizes imports
  • Adds/removes semicolons
3

AI Receives Updated State

The tool response includes the final formatted content:
{
  "success": true,
  "finalContent": "// File after auto-formatting"
}
4

Subsequent Edits Adapt

Future edits use the formatted version as reference.
Critical: The AI must use the post-formatting content for subsequent SEARCH blocks. This is especially important when making multiple edits to the same file.
See: src/core/prompts/system-prompt/components/editing_files.ts:5

Auto-Formatting Examples

Common transformations your editor might apply:
Before (AI writes):
function example() {
    return true
}
After (Editor formats with 2 spaces):
function example() {
  return true
}
Before:
const name = "John"
After (Prettier with single quotes):
const name = 'John'
Before:
import { z } from './utils'
import React from 'react'
import { Button } from './Button'
After (Sorted and grouped):
import React from 'react'

import { Button } from './Button'
import { z } from './utils'
Before:
const config = {
  name: 'app',
  version: '1.0.0'
}
After (With trailing commas):
const config = {
  name: 'app',
  version: '1.0.0',
}

Best Practices

Be Specific in SEARCH Blocks

<SEARCH>
const items = []
</SEARCH>
Problem: Might match multiple locations or wrong variable.

Include Surrounding Context

<SEARCH>
return result
</SEARCH>
Problem: Many functions might have this line.

Handle Edge Cases

If a file has similar code blocks, include unique identifiers:
<SEARCH>
// User validation
function validate(data) {
  return data.isValid
}
</SEARCH>
The comment makes it unique from other validate functions.
Avoid SEARCH blocks with timestamps or IDs:<SEARCH>const id = 12345</SEARCH><SEARCH>const id = userId // Current user</SEARCH>
Match exact whitespace in SEARCH blocks:
<SEARCH>
function example() {
    // 4 spaces indentation
    return true
}
</SEARCH>

Workflow Tips

1

Assess Scope

Before editing, determine if changes are localized or widespread.
2

Choose Tool

Use replace_in_file for targeted edits, write_to_file for major changes.
3

Stack Multiple Edits

Combine related changes into a single replace_in_file call:
// Example: Add import and use component
// SEARCH/REPLACE 1: Add import
// SEARCH/REPLACE 2: Add component usage
4

Verify Changes

Review the diff after each edit to ensure correctness.
5

Use Updated Content

For subsequent edits, reference the final formatted state from previous operations.
See: src/core/prompts/system-prompt/components/editing_files.ts:71

Advanced Techniques

Multi-Line Replacements

Replace entire blocks while preserving structure:
<SEARCH>
interface User {
  id: string
  name: string
}
</SEARCH>
<REPLACE>
interface User {
  id: string
  name: string
  email: string
  createdAt: Date
}
</REPLACE>

Conditional Logic Updates

Modify complex conditional statements:
<SEARCH>
if (user.role === 'admin') {
  return true
}
return false
</SEARCH>
<REPLACE>
if (user.role === 'admin' || user.permissions.includes('manage_users')) {
  return true
}
return false
</REPLACE>

Pattern Replacements

Change recurring patterns:
<SEARCH>
console.log('Debug:', data)
</SEARCH>
<REPLACE>
logger.debug('Data:', data)
</REPLACE>
Repeat for each occurrence in the file.

Common Use Cases

Add TypeScript Types

// SEARCH
function process(data) {
  return data.map(item => item.value)
}

// REPLACE
function process(data: DataItem[]): number[] {
  return data.map(item => item.value)
}

Update Imports

// SEARCH
import { Component } from './Component'

// REPLACE
import { Component } from '@/components/Component'

Fix ESLint Issues

// SEARCH
const unused = 5

// REPLACE
// const unused = 5 // Temporarily disabled

Refactor Function Names

// SEARCH
function getData() {
  return fetchUserData()
}

// REPLACE
function fetchData() {
  return fetchUserData()
}

Error Handling

Search Block Not Found

Error: SEARCH block not found in file Causes:
  • Whitespace mismatch
  • File was auto-formatted since last read
  • Searching for old content
Solution:
  1. Read the file again to get current state
  2. Copy exact content including whitespace
  3. Use more surrounding context

Multiple Matches Found

Error: SEARCH block matches multiple locations Solution:
  • Add more context to make the match unique
  • Include function name, comments, or surrounding code
  • Use variable names or string literals as anchors

File Changed Externally

Error: File modified externally during operation Solution:
  • Refresh file content
  • Retry the operation
  • Use version control to resolve conflicts

Performance Considerations

Inline Editing is faster because:
  • Sends only SEARCH/REPLACE blocks
  • Doesn’t need full file content
  • Less token usage
  • Faster processing
Example:
  • Full file: 500 lines = ~15,000 tokens
  • Inline edit: 20 lines = ~600 tokens
  • 25x reduction in tokens

Configuration

Editor Settings

Configure your editor for optimal inline editing:
// .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  // HAI Build will adapt to these settings
}

Ignore Formatting

For CLI environments with no auto-formatting:
{
  "hai.inlineEdit.assumeNoFormatting": true
}
See: src/core/prompts/system-prompt/components/editing_files.ts:84

Troubleshooting

  • Verify file isn’t read-only
  • Check file permissions
  • Ensure no syntax errors in REPLACE block
  • Confirm SEARCH block exactly matches file content
  • Add more context to SEARCH block
  • Include unique identifiers (comments, variable names)
  • Read file first to verify current state
  • Use function/class names as anchors
  • Disable auto-format temporarily
  • Match current file formatting in SEARCH blocks
  • Use the post-format content from tool responses
  • Configure consistent formatting rules

Next Steps

AI-Powered Coding

Learn how the AI decides when to use inline editing

File Identification

Discover files to edit with smart search

Auto Approve

Auto-approve safe inline edits for faster workflows

Checkpoints

Roll back inline edits if needed

Build docs developers (and LLMs) love