Using Copilot Chat for Explanations and Refactoring
Copilot Chat extends beyond code completion to provide a conversational interface for understanding, explaining, and improving your code. It's like having a knowledgeable colleague available 24/7.
Accessing Copilot Chat
VS Code
- Chat Panel: Click the Copilot icon in the sidebar or press
Ctrl+Shift+I/Cmd+Shift+I - Inline Chat: Select code and press
Ctrl+I/Cmd+Ifor contextual chat - Quick Chat: Press
Ctrl+Shift+Pand type "Copilot Chat"
JetBrains IDEs
- Chat Panel: Go to View → Tool Windows → GitHub Copilot Chat
- Inline: Select code, right-click, and choose GitHub Copilot → Start Chat
Chat Commands (Slash Commands)
Copilot Chat supports special commands that trigger specific behaviors:
| Command | Purpose | Example |
|---|---|---|
/explain | Explain selected code | /explain this recursive function |
/fix | Suggest fixes for problems | /fix this null pointer error |
/tests | Generate tests | /tests for the UserService class |
/doc | Generate documentation | /doc for this API endpoint |
/simplify | Simplify complex code | /simplify this nested conditional |
/optimize | Improve performance | /optimize this database query |
/new | Start a new chat session | /new |
/clear | Clear chat history | /clear |
Explaining Code
Understanding Unfamiliar Code
Select confusing code and ask Copilot to explain it:
// Select this code and type: /explain
const debounce = (fn, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
};
Copilot will explain:
- What debouncing is and why it's useful
- How the closure captures
timeoutId - What
fn.apply(this, args)does - When you'd use this pattern
Understanding Error Messages
Paste an error and ask for help:
"I'm getting this error:
TypeError: Cannot read property 'map' of undefined
Here's my code:
function renderItems(items) {
return items.map(item => <li>{item.name}</li>);
}
What's wrong and how do I fix it?"
Copilot explains the issue (items might be undefined) and suggests solutions like default parameters or optional chaining.
Refactoring with Chat
Inline Chat Refactoring
Select code, press Ctrl+I / Cmd+I, and describe the refactoring:
# Original code - select it
if status == 'active':
return True
elif status == 'inactive':
return False
elif status == 'pending':
return None
else:
raise ValueError('Unknown status')
# Type: "Convert to a dictionary lookup"
# Copilot suggests:
STATUS_MAP = {
'active': True,
'inactive': False,
'pending': None,
}
def get_status_value(status):
if status not in STATUS_MAP:
raise ValueError('Unknown status')
return STATUS_MAP[status]
Common Refactoring Requests
Convert callback to async/await:
// Ask: "Convert this callback-based code to async/await"
// Before:
function fetchData(callback) {
api.get('/data', (err, response) => {
if (err) callback(err);
else callback(null, response.data);
});
}
// After (Copilot suggestion):
async function fetchData() {
const response = await api.get('/data');
return response.data;
}
Extract function:
# Ask: "Extract the validation logic into a separate function"
# Before:
def process_order(order):
if not order.get('items'):
raise ValueError('Order must have items')
if order.get('total', 0) <= 0:
raise ValueError('Order total must be positive')
# ... rest of processing
# After:
def validate_order(order):
if not order.get('items'):
raise ValueError('Order must have items')
if order.get('total', 0) <= 0:
raise ValueError('Order total must be positive')
def process_order(order):
validate_order(order)
# ... rest of processing
Add error handling:
// Ask: "Add proper error handling to this async function"
// Before:
async function saveUser(user: User) {
const result = await database.insert('users', user);
return result;
}
// After:
async function saveUser(user: User): Promise<SaveResult> {
try {
const result = await database.insert('users', user);
return { success: true, data: result };
} catch (error) {
console.error('Failed to save user:', error);
return { success: false, error: error.message };
}
}
Code Reviews with Chat
Ask Copilot to review your code for issues:
"Review this function for potential bugs, security issues, and improvements:
function authenticateUser(username, password) {
const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;
const user = db.execute(query);
if (user) {
return { token: generateToken(user.id) };
}
return null;
}
"
Copilot might identify:
- SQL injection vulnerability (string interpolation in query)
- Plain text password storage issue
- Missing input validation
- No rate limiting
Architecture and Design Discussions
Use Chat for higher-level discussions:
"I'm building a notification system that needs to:
- Send emails, SMS, and push notifications
- Handle retries for failed deliveries
- Support scheduling notifications for later
- Track delivery status
What design patterns would you recommend? Should I use a queue?"
Copilot can discuss:
- Strategy pattern for different notification channels
- Queue systems like Redis or RabbitMQ
- Retry strategies with exponential backoff
- Database schema for tracking status
Contextual Questions
Copilot Chat understands your open files and workspace:
"Looking at my current file:
- What does the processPayment function do?
- Why is there a retry loop in line 45?
- What happens if the API returns a 429 error?"
It uses the visible code to provide contextual answers.
Multi-Turn Conversations
Build on previous messages for complex tasks:
You: "How should I structure a REST API for a todo app?"
Copilot: [Suggests endpoints like GET /todos, POST /todos, etc.]
You: "What about filtering and pagination?"
Copilot: [Extends the previous answer with query parameters]
You: "Generate the Express.js routes for this"
Copilot: [Provides complete implementation]
Learning and Exploration
Use Chat to learn new concepts:
"Explain the difference between:
- useMemo and useCallback in React
- When should I use each one?
- Show me examples where using the wrong one would cause issues"
Or explore technologies:
"I'm considering using Redis for caching in my Node.js app.
- What are the main use cases?
- How does it compare to in-memory caching?
- What are the gotchas I should know about?"
Effective Chat Prompts
Be Specific About Context
// Less effective:
"How do I fix this?"
// More effective:
"I'm getting a TypeScript error TS2345 on line 23 where I pass
a string to a function expecting a number. The string comes from
user input. What's the best way to handle this conversion safely?"
Include Relevant Code
"Given this interface:
interface Config {
apiUrl: string;
timeout: number;
retries?: number;
}
How do I create a function that merges a partial config with defaults?"
Ask for Alternatives
"Show me three different ways to implement a singleton pattern in TypeScript,
with pros and cons of each approach"
Chat Limitations to Remember
- Context window limits - Very long conversations may lose early context
- No file system access - Chat can't read files you haven't shared
- No execution - It can't run code to verify suggestions
- Knowledge cutoff - May not know about very recent library updates
- Potential hallucinations - May suggest non-existent APIs or methods
Summary
Copilot Chat transforms how you interact with code:
- Use
/explainto understand unfamiliar code - Use inline chat (
Ctrl+I) for quick refactoring - Ask for code reviews to catch bugs and security issues
- Discuss architecture for design guidance
- Build on conversations for complex, multi-step tasks
- Be specific in your questions for better answers
Combined with inline suggestions, Chat makes Copilot a comprehensive coding assistant that can help with everything from syntax questions to architectural decisions.
Next, you'll learn how to use Copilot specifically for writing tests and documentation.
Cuestionario
Discussion
Sign in to join the discussion.

