Project 1: The "Keyboard Warrior" Refactoring Kata

Project 1: The “Keyboard Warrior” Refactoring Kata

Project Overview

Attribute Value
Difficulty Beginner
Time Estimate Weekend
Main Language Text / Regex
Knowledge Area Editor Navigation / Multi-cursor Editing
Prerequisites Basic understanding of any programming language

Learning Objectives

By completing this project, you will:

  1. Master multi-cursor editing for simultaneous text manipulation
  2. Internalize keyboard shortcuts for navigation, selection, and refactoring
  3. Understand the difference between text-based find/replace and semantic refactoring
  4. Build muscle memory for flow-state coding without mouse interruption
  5. Learn VS Code’s command system and the Command Palette

The Core Question

“How can I refactor code at the speed of thought without breaking my flow state?”


Deep Theoretical Foundation

Why Keyboard-First Development Matters

The mouse is a productivity killer. Research on human-computer interaction shows that every time you move your hand from the keyboard to the mouse, you lose 0.5-1 second. Over a day of coding, that adds up to 30+ minutes of wasted time. But the real cost isn’t time—it’s cognitive context switching.

When you reach for the mouse, you break your mental model of the code. Your brain shifts from “thinking about logic” to “thinking about cursor position.” This micro-interruption compounds. Studies on programmer productivity show that it takes 10-15 minutes to regain deep focus after an interruption. The mouse creates dozens of tiny interruptions per hour.

The Command Palette: Universal Interface

VS Code’s architecture is built around commands. Every action—formatting, refactoring, git operations, navigation—is a command with a unique identifier. The Command Palette (Cmd+Shift+P / Ctrl+Shift+P) is a fuzzy-searchable list of ALL registered commands.

User types: "git commit"
     ↓
Command Palette searches ALL registered commands
     ↓
Matches: "git.commit", "git.commitAll", "git.commitStaged"
     ↓
User selects one
     ↓
VS Code executes: vscode.commands.executeCommand('git.commit')
     ↓
The Git extension's handler function runs

Key Insight: If you don’t know the shortcut for something, the Command Palette is your escape hatch. Type what you want to do in plain English—VS Code will find it.

Multi-Cursor Editing: Parallel Text Manipulation

VS Code allows multiple cursors to be active simultaneously. Each cursor acts independently—when you type, delete, or paste, it happens at ALL cursor positions at once.

Core Multi-Cursor Commands:

  • Cmd+D (macOS) / Ctrl+D (Windows/Linux): Add next occurrence of selection to cursors
  • Cmd+Shift+L / Ctrl+Shift+L: Select ALL occurrences of current selection
  • Option+Click / Alt+Click: Add cursor at clicked position
  • Option+Cmd+Up/Down / Ctrl+Alt+Up/Down: Add cursor above/below

When to use multi-cursor vs refactoring:

  • Multi-cursor: Simple, mechanical edits (adding quotes, changing syntax)
  • Refactoring (F2): Semantic changes (renaming variables, extracting functions)

The difference is scope-awareness. Cmd+D selects text that looks the same. F2 rename understands meaning—it won’t rename a variable user inside a string "user" or in an unrelated scope.

Symbol Navigation: Thinking in Structure

VS Code understands code structure through the Language Server Protocol. Instead of scrolling through a 2000-line file, you can jump directly to symbols.

Navigation Commands:

  • Cmd+T / Ctrl+T: Go to Symbol in Workspace (searches all files)
  • Cmd+Shift+O / Ctrl+Shift+O: Go to Symbol in File (outline view)
  • F12: Go to Definition
  • Shift+F12: Find All References
  • Option+F12 / Alt+F12: Peek Definition (inline preview)
  • Cmd+G / Ctrl+G: Go to Line Number

Selection Expansion: Smart Selection

Instead of manually selecting characters or words, use Expand Selection to grow the selection to the next logical boundary.

Ctrl+Shift+Cmd+Right Arrow (macOS) or Shift+Alt+Right Arrow (Windows/Linux)

Expansion sequence:

  1. Word → 2. Expression → 3. Statement → 4. Block → 5. Function

Example: Cursor inside calculateTotal(a, b, c):

  • Press 1x: selects calculateTotal
  • Press 2x: selects calculateTotal(a, b, c)
  • Press 3x: selects the full statement including const result = ...

Project Specification

What You’re Building

A complete refactoring workflow documentation using ONLY keyboard shortcuts. You will take a messy codebase, refactor it without touching the mouse, and document every shortcut used.

Deliverables

  1. Refactored Code: A JavaScript/TypeScript file transformed from messy to clean
  2. Shortcut Log: Document every keyboard shortcut used during the refactoring
  3. Personal Cheat Sheet: A markdown file with YOUR most-used shortcuts
  4. Timing Comparison: Before/after timing of a refactoring task with and without keyboard-only workflow

Success Criteria

  • Complete a refactoring session without using the mouse
  • Use at least 10 different keyboard shortcuts
  • Successfully rename a variable using F2 (scope-aware)
  • Extract a function using Cmd+. code actions
  • Navigate to a symbol in another file using Cmd+T
  • Use multi-cursor to edit 5+ locations simultaneously

Solution Architecture

Conceptual Design

Your refactoring workflow should follow this mental model:

┌─────────────────────────────────────────────────────────────┐
│                   KEYBOARD-FIRST WORKFLOW                    │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  1. NAVIGATION (Finding what to change)                     │
│     ├── Cmd+P: Open file by name                            │
│     ├── Cmd+T: Go to symbol in workspace                    │
│     ├── Cmd+Shift+O: Go to symbol in file                   │
│     └── F12: Jump to definition                             │
│                                                              │
│  2. SELECTION (Choosing what to change)                     │
│     ├── Cmd+D: Select next occurrence                       │
│     ├── Cmd+Shift+L: Select all occurrences                 │
│     └── Expand Selection: Smart boundary selection          │
│                                                              │
│  3. TRANSFORMATION (Making the change)                      │
│     ├── F2: Rename symbol (scope-aware)                     │
│     ├── Cmd+.: Quick fix / code actions                     │
│     ├── Multi-cursor typing: Parallel edits                 │
│     └── Cmd+Shift+K: Delete entire line                     │
│                                                              │
│  4. VERIFICATION (Confirming the change)                    │
│     ├── Shift+F12: Find all references                      │
│     ├── Cmd+Shift+M: Open problems panel                    │
│     └── Ctrl+-: Navigate back to previous location          │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Workflow Phases

Phase 1: Navigation Before changing code, you need to find it. Use file search (Cmd+P), symbol search (Cmd+T), and definition jumping (F12) to locate targets.

Phase 2: Selection Select the text to change. Use Cmd+D for incremental selection, Cmd+Shift+L for bulk selection, or Expand Selection for structural selection.

Phase 3: Transformation Apply the change. Use F2 for renames, Cmd+. for code actions, or simply type (all cursors receive the input).

Phase 4: Verification Confirm the change worked. Use Shift+F12 to see all references, Cmd+Shift+M to check for problems.


Phased Implementation Guide

Phase 1: Environment Setup (30 minutes)

Goal: Prepare your practice environment.

  1. Install the “Learn VS Code Shortcuts” extension (optional but helpful—shows shortcuts as you use commands)

  2. Create a practice file with intentionally messy code:

// practice.js - Intentionally messy code for refactoring practice

function processUser(u) {
  console.log(u.name);
  console.log(u.email);
  let result = u.age > 18 ? "adult" : "minor";
  console.log(result);
  return result;
}

function handleData(d) {
  console.log("Processing data...");
  for (var i = 0; i < d.length; i++) {
    console.log("Item: " + d[i]);
    var x = d[i] * 2;
    console.log("Doubled: " + x);
  }
  console.log("Done!");
}

function calculate(a, b, c) {
  var sum = a + b + c;
  var avg = sum / 3;
  var max = a > b ? (a > c ? a : c) : (b > c ? b : c);
  return {sum: sum, avg: avg, max: max};
}
  1. Print the VS Code keyboard shortcut cheatsheet for your OS from the official site

Phase 2: Basic Navigation Mastery (1 hour)

Goal: Navigate without scrolling or clicking.

Exercises:

  1. File Navigation
    • Press Cmd+P, type “practice”, press Enter
    • Time yourself: Can you open any file in under 2 seconds?
  2. Line Navigation
    • Press Cmd+G, type “15”, press Enter
    • Practice jumping to specific lines
  3. Symbol Navigation
    • Press Cmd+Shift+O to see file outline
    • Jump between functions using the outline
  4. Definition Jumping
    • In line 2, place cursor on u.name
    • Press F12 (would jump to definition if u were defined elsewhere)
    • Press Ctrl+- to go back

Checkpoint: You should be able to navigate a 500-line file without touching the scrollbar.

Phase 3: Multi-Cursor Editing (1 hour)

Goal: Edit multiple locations simultaneously.

Exercises:

  1. Select Next Occurrence
    • Select the word console in the file
    • Press Cmd+D repeatedly to add each occurrence
    • Type logger to replace all at once
  2. Select All Occurrences
    • Select var
    • Press Cmd+Shift+L to select ALL
    • Type const (will replace all if variables aren’t reassigned—some will be errors!)
  3. Add Cursors Manually
    • Hold Option and click at the end of lines 2, 3, 4
    • Type ; at all three positions simultaneously
  4. Column Selection
    • Select multiple lines
    • Press Shift+Option+I to add cursors at the END of each line

Checkpoint: You should be able to rename a variable across 10 occurrences in under 5 seconds.

Phase 4: Semantic Refactoring (1 hour)

Goal: Use language-aware refactoring tools.

Exercises:

  1. Rename Symbol
    • Place cursor on u in processUser
    • Press F2
    • Type user
    • Press Enter
    • Observe: Only u parameters are renamed, not other u variables
  2. Extract Function
    • Select lines 2-3 (the console.log calls)
    • Press Cmd+.
    • Choose “Extract to function in module scope”
    • Name it logUserInfo
  3. Extract Variable
    • Select the ternary expression u.age > 18 ? "adult" : "minor"
    • Press Cmd+.
    • Choose “Extract to constant in enclosing scope”
    • Name it ageCategory
  4. Quick Fixes
    • Add // @ts-check at the top of the file
    • Notice TypeScript errors appear
    • Press Cmd+. on errors to see available fixes

Checkpoint: You should be able to extract a function and rename variables without typing the name more than once.

Phase 5: Complete Refactoring Kata (2 hours)

Goal: Refactor the entire practice file using only keyboard.

Starting Code (same as Phase 1):

function processUser(u) {
  console.log(u.name);
  console.log(u.email);
  let result = u.age > 18 ? "adult" : "minor";
  console.log(result);
  return result;
}

Target Code (what you’re aiming for):

function processUser(user) {
  logUserInfo(user);
  const ageCategory = categorizeAge(user.age);
  console.log(ageCategory);
  return ageCategory;
}

function logUserInfo(user) {
  console.log(user.name);
  console.log(user.email);
}

function categorizeAge(age) {
  return age > 18 ? "adult" : "minor";
}

Step-by-Step Keyboard Sequence:

  1. F2 on u → type user → Enter (rename parameter)
  2. Select lines 2-3 → Cmd+. → Extract to function → type logUserInfo
  3. Select ternary expression → Cmd+. → Extract to constant → type ageCategory
  4. Cmd+. on ageCategory → Extract to function → type categorizeAge
  5. F2 on result → type ageCategory

Testing Strategy

Manual Testing Checklist

  • Can navigate to any function in under 2 seconds
  • Can select all occurrences of a word in under 1 second
  • Rename symbol changes all semantic occurrences, not string literals
  • Extract function creates properly scoped helper function
  • No mouse usage during entire refactoring session

Performance Benchmarks

Task With Mouse Keyboard-Only Target
Open specific file 3-5 sec <1 sec <1 sec
Jump to function 5-10 sec <2 sec <2 sec
Rename variable (5 occurrences) 15-30 sec <5 sec <5 sec
Extract function 60+ sec <10 sec <10 sec

Common Pitfalls and Debugging

Pitfall 1: Using Cmd+D Instead of F2 for Renaming

Problem: You select all occurrences of user with Cmd+D and type a new name. But it also changes "user" inside strings and comments.

Solution: Use F2 for semantic renaming. It understands scope and won’t touch strings or comments.

Pitfall 2: Forgetting to Go Back

Problem: You jump to a definition with F12, but can’t find your way back.

Solution: Use Ctrl+- (macOS) or Alt+Left Arrow (Windows) to navigate back through your cursor history.

Pitfall 3: Multi-Cursor Chaos

Problem: You have 20 cursors and make a typo—now there are 20 typos.

Solution: Press Escape to exit multi-cursor mode. Use Cmd+Z to undo (undoes ALL cursor edits).

Pitfall 4: Selection Expansion Goes Too Far

Problem: Expand Selection selected the entire file when you wanted just a statement.

Solution: Use Ctrl+Shift+Cmd+Left Arrow (Shrink Selection) to go back one level.


Extensions and Challenges

Extension 1: Custom Keybindings

Create a keybindings.json entry for a shortcut you use frequently but doesn’t have a binding:

{
  "key": "cmd+shift+r",
  "command": "editor.action.refactor",
  "when": "editorTextFocus"
}

Extension 2: Macro-Style Editing

Install the “Multi-Command” extension and create a macro that:

  1. Selects the current line
  2. Cuts it
  3. Moves to the previous line
  4. Pastes (effectively moving the line up)

Extension 3: No-Mouse Challenge

Unplug your mouse for an entire coding session. Document every moment you got stuck and find the keyboard solution.


Real-World Connections

Code Review Efficiency

When reviewing a PR with 500+ lines:

  1. Cmd+Shift+F to search for patterns
  2. Cmd+D to select all instances of a problematic variable
  3. Shift+F12 to see all references before suggesting a rename

Pair Programming

When pair programming, keyboard-only navigation is faster to dictate:

  • “Go to the processUser function” → partner presses Cmd+T, types processUser
  • “Select all uses of result” → partner presses Cmd+D repeatedly

Technical Interviews

Interviewers notice keyboard fluency. It demonstrates:

  • Deep tool knowledge
  • Focus on efficiency
  • Professional-level development skills

Interview Questions

  1. “How do you refactor code efficiently without introducing bugs?”

    Answer: “I use language-aware refactoring tools like VS Code’s F2 rename and Cmd+. extract method. These use the Language Server Protocol to understand scope, so they don’t accidentally rename unrelated variables. For mechanical transformations, I use multi-cursor editing.”

  2. “What’s the difference between Find-Replace and Refactoring?”

    Answer: “Find-Replace is text-based and doesn’t understand code structure. Refactoring is syntax-aware. If I rename a function parameter with Find-Replace, it might change string literals or comments that happen to have the same text. Refactoring only changes the actual symbol.”

  3. “How do you navigate a large codebase without relying on a mouse?”

    Answer: “I use Cmd+T to search for symbols across the workspace, Cmd+P to open files by name, and F12 to jump to definitions. For exploring code, I use Shift+F12 to see all references. For file-level navigation, Cmd+Shift+O shows an outline.”


Resources

Essential Reading

Book Author Relevant Chapters
Visual Studio Code: End-to-End Editing and Debugging Tools Bruce Johnson Ch 2 (Command Palette), Ch 3 (Editing), Ch 4 (Navigation)
Visual Studio Code Distilled Alessandro Del Sole Ch 3 (Editing Code), Ch 4 (Multi-cursor Editing)
Refactoring: Improving the Design of Existing Code Martin Fowler Ch 1 (Refactoring Principles), Ch 6 (Extract Function)
The Pragmatic Programmer David Thomas, Andrew Hunt Tip 22 (Use a Single Editor Well)

Official Documentation


Self-Assessment Checklist

Before considering this project complete, verify:

  • I can navigate to any file/symbol without using the mouse
  • I understand the difference between Cmd+D and F2
  • I can use Expand Selection to select logical code blocks
  • I can extract a function using code actions
  • I have documented my personal shortcut cheat sheet
  • I can complete a full refactoring session keyboard-only
  • I know how to customize keybindings for my workflow

Next Project: P02-time-travel-debugger-configuration.md