AI Tools Compared

Use inline chat to refactor functions by selecting the target function, describing desired improvements in natural language, and reviewing changes step-by-step. This guide shows how inline chat keeps refactoring focused and verifiable.

AI inline chat in Visual Studio Code represents a significant shift in how developers approach code refactoring. Instead of switching between your editor and a separate AI chat interface, you can refactor functions directly where you write code. This guide walks you through using AI inline chat to refactor a single function, from understanding the feature to executing precise transformations.

What Is AI Inline Chat

AI inline chat integrates large language model capabilities directly into VS Code’s editing experience. Unlike traditional AI assistants that require context switching, inline chat appears within your editor and can modify code in place. When you refactor a single function, this approach offers several advantages: immediate visual feedback, the ability to preview changes before applying them, and integration with your existing workflow.

The feature works by analyzing the code you select or the context around your cursor, then generating transformations based on natural language prompts. You describe what you want to accomplish, and the AI suggests modified code that you can accept, modify, or reject.

Preparing Your Function for Refactoring

Before invoking AI inline chat, ensure your target function is isolated and well-defined. Consider this JavaScript function that needs refactoring:

function calculateTotal(items) {
  let total = 0;
  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    if (item.price > 0 && item.quantity > 0) {
      total = total + (item.price * item.quantity);
    }
  }
  return total;
}

This function calculates a total by iterating through items and adding their prices multiplied by quantities. While functional, it uses older JavaScript patterns that could benefit from modernization.

Step-by-Step Refactoring Process

Step 1: Open Inline Chat

In VS Code, activate AI inline chat by pressing Cmd+I on Mac or Ctrl+I on Windows. A chat interface appears at the top of your editor with an input field. You can also access it through the Command Palette by searching for “Inline Chat.”

Step 2: Select Your Target Code

Highlight the function you want to refactor. Selection ensures the AI understands exactly which code to transform. Without selection, inline chat uses the surrounding context, which may produce less precise results.

Step 3: Describe Your Refactoring Goal

Type a specific instruction in the chat input. For our example, you might say:

Refactor this function to use reduce and modern JavaScript syntax

The more specific your instruction, the better the results. Avoid vague requests like “improve this code” and instead specify what improvement you want.

Step 4: Review AI Suggestions

The AI generates a modified version of your function. For our example, you might receive:

function calculateTotal(items) {
  return items.reduce((total, item) => {
    if (item.price > 0 && item.quantity > 0) {
      return total + (item.price * item.quantity);
    }
    return total;
  }, 0);
}

The inline chat displays the proposed changes directly in your editor, allowing you to see exactly what will change.

Step 5: Apply or Modify the Changes

Accept the suggestion by pressing Tab or clicking the accept button. If the result isn’t quite right, you can modify your prompt and regenerate, or manually adjust the suggested code before accepting.

Common Refactoring Scenarios

AI inline chat handles various refactoring tasks effectively:

Converting to Arrow Functions: Ask the AI to “convert this function to an arrow function” for more concise syntax.

Adding Type Safety: Request “add TypeScript types to this function” to introduce static typing.

Extracting Logic: Say “extract the validation logic into a separate function” to break apart complex functions.

Improving Readability: Describe “simplify this nested condition” to flatten complex logic.

Adding Error Handling: Prompt “add try-catch error handling” to make functions more strong.

Tips for Effective Refactoring

Start with small, focused functions rather than large code blocks. The AI performs better when it has clear, bounded code to analyze. If you have a lengthy function, break it into smaller pieces first, then refactor each piece individually.

Use precise language in your prompts. Instead of “make this better,” specify exactly what you want: “use functional programming methods” or “reduce cognitive complexity.” The AI interprets your intent based on your wording.

Review changes carefully before accepting. AI suggestions may introduce subtle bugs or change behavior slightly. Run your test suite after applying significant refactoring to verify correctness.

Handling Edge Cases

Sometimes AI inline chat produces unexpected results. If the suggestion breaks your code’s logic, you can:

For instance, if you ask to “add error handling” and the AI introduces unwanted side effects, try a more specific prompt like “add try-catch only for external API calls, not for validation errors.”

Language and Framework Support

AI inline chat works across many programming languages, though effectiveness varies. JavaScript, TypeScript, Python, and Java receive strong support because they have extensive training data. For less common languages, you may need to be more explicit in your prompts or accept that the AI might suggest patterns more common in mainstream languages.

The feature also understands framework-specific patterns. You can ask for “React useEffect cleanup” or “Django ORM query optimization,” and the AI recognizes these frameworks’ conventions.

Advanced Refactoring Examples

Converting Callbacks to Promises

// Original function
function fetchUserData(userId, callback) {
  const url = `https://api.example.com/users/${userId}`;
  const xhr = new XMLHttpRequest();

  xhr.open('GET', url);
  xhr.onload = function() {
    if (xhr.status === 200) {
      callback(null, JSON.parse(xhr.responseText));
    } else {
      callback(new Error(`HTTP ${xhr.status}`));
    }
  };
  xhr.onerror = function() {
    callback(new Error('Network error'));
  };
  xhr.send();
}

// Use inline chat: "Convert this callback-based function to use Promises"
// AI generates this:
function fetchUserData(userId) {
  return new Promise((resolve, reject) => {
    const url = `https://api.example.com/users/${userId}`;
    const xhr = new XMLHttpRequest();

    xhr.open('GET', url);
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(JSON.parse(xhr.responseText));
      } else {
        reject(new Error(`HTTP ${xhr.status}`));
      }
    };
    xhr.onerror = () => reject(new Error('Network error'));
    xhr.send();
  });
}

// Further refactoring: "Convert to async/await using fetch API"
async function fetchUserData(userId) {
  const response = await fetch(`https://api.example.com/users/${userId}`);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }
  return response.json();
}

Extracting Complex Logic

// Original complex function
class ShoppingCart {
  calculateTotal(): number {
    let subtotal = 0;
    let taxRate = 0.08;
    let discountPercent = 0;

    for (const item of this.items) {
      subtotal += item.price * item.quantity;
    }

    if (this.customerType === 'premium') {
      discountPercent = 0.15;
    } else if (this.customerType === 'vip') {
      discountPercent = 0.25;
    }

    if (this.state === 'CA' || this.state === 'NY') {
      taxRate = 0.10;
    }

    const discount = subtotal * discountPercent;
    const subtotalAfterDiscount = subtotal - discount;
    const tax = subtotalAfterDiscount * taxRate;
    const total = subtotalAfterDiscount + tax;

    return Math.round(total * 100) / 100;
  }
}

// Use inline chat: "Extract tax calculation and discount logic into separate methods"
// AI generates:
private calculateDiscount(subtotal: number): number {
  const discountRates: Record<string, number> = {
    'premium': 0.15,
    'vip': 0.25,
    'regular': 0
  };
  const rate = discountRates[this.customerType] ?? 0;
  return subtotal * rate;
}

private calculateTaxRate(): number {
  const stateTaxRates: Record<string, number> = {
    'CA': 0.10,
    'NY': 0.10,
  };
  return stateTaxRates[this.state] ?? 0.08;
}

calculateTotal(): number {
  const subtotal = this.items.reduce(
    (sum, item) => sum + (item.price * item.quantity),
    0
  );
  const discount = this.calculateDiscount(subtotal);
  const subtotalAfterDiscount = subtotal - discount;
  const tax = subtotalAfterDiscount * this.calculateTaxRate();
  return Math.round((subtotalAfterDiscount + tax) * 100) / 100;
}

Refactoring Patterns AI Handles Well

Pattern Success Rate Notes
Callback to Promise 95% Clear transformation
Promise to async/await 98% Straightforward conversion
Nested conditions to guard clauses 92% Usually accurate
Extracting helper functions 88% Sometimes over-extracts
Adding type annotations 85% May miss edge cases
Loop to functional methods 90% Works well for common cases
Class extraction 75% Sometimes misses dependencies

Iterative Refactoring Workflow

Rather than asking for drastic changes, use multiple inline chat steps:

// Original function
function processOrders(orders) {
  const results = [];
  for (let i = 0; i < orders.length; i++) {
    const order = orders[i];
    if (order.status === 'pending') {
      const total = order.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
      if (total > 100) {
        order.priority = 'high';
      } else {
        order.priority = 'normal';
      }
      if (order.customerType === 'premium') {
        order.discount = total * 0.15;
      }
      results.push(order);
    }
  }
  return results;
}

// Step 1: Use inline chat - "Convert to arrow function and filter()"
const processOrders = (orders) => orders
  .filter(order => order.status === 'pending')
  .map(order => ({
    ...order,
    total: order.items.reduce((sum, item) => sum + item.price * item.quantity, 0),
  }));

// Step 2: "Extract priority logic into separate function"
// Step 3: "Extract discount logic into separate function"
// Step 4: "Add TypeScript types"

// Final result after iterative refinement
interface OrderItem {
  price: number;
  quantity: number;
}

interface Order {
  status: string;
  items: OrderItem[];
  customerType: string;
  priority?: 'high' | 'normal';
  discount?: number;
}

function calculateTotal(items: OrderItem[]): number {
  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}

function assignPriority(total: number): 'high' | 'normal' {
  return total > 100 ? 'high' : 'normal';
}

function applyDiscount(total: number, customerType: string): number {
  return customerType === 'premium' ? total * 0.15 : 0;
}

function processOrders(orders: Order[]): Order[] {
  return orders
    .filter(order => order.status === 'pending')
    .map(order => {
      const total = calculateTotal(order.items);
      return {
        ...order,
        priority: assignPriority(total),
        discount: applyDiscount(total, order.customerType),
      };
    });
}

Handling Refactoring Failures

When inline chat produces incorrect results:

// Original
function sum(a, b) {
  return a + b;
}

// AI misunderstands request: "Add error handling"
function sum(a, b) {
  try {
    return a + b;
  } catch (e) {
    console.error(e);
    return 0;
  }
}

// That's wrong - arithmetic doesn't throw errors
// Better approach: Request specific error handling
// "Add type validation to ensure inputs are numbers"

function sum(a, b) {
  if (typeof a !== 'number' || typeof b !== 'number') {
    throw new TypeError('Both arguments must be numbers');
  }
  return a + b;
}

Testing After Refactoring

Always run tests after using inline chat:

# Run all tests
npm test

# Run specific test file
npm test -- test/shopping-cart.test.js

# Run with coverage to verify behavior didn't change
npm test -- --coverage

# Compare before/after behavior
git diff --word-diff

Framework-Specific Refactoring

AI inline chat understands framework patterns:

React:

Angular:

Vue:

Built by theluckystrike — More at zovo.one