❌ Niejasne
“Ulepsz to” “Napraw to” “Optymalizuj”
Edycja inline (Ctrl+K) to miejsce, gdzie język naturalny spotyka się z precyzyjną transformacją kodu. Te 15 wskazówek nauczą cię władać tą potężną funkcją od szybkich poprawek po wyrafinowane operacje refaktoryzacji.
Twoje zaznaczenie określa zakres transformacji:
// Zaznacz tylko instrukcję return:return data;
// Ctrl+K: "Dodaj sprawdzenie null"// Wynik wpływa tylko na return:return data || [];
// Zaznacz całą funkcję:function fetchUser(id) { const user = db.find(id); return user;}
// Ctrl+K: "Dodaj obsługę błędów i async/await"// Wynik przekształca całą funkcję:async function fetchUser(id) { try { const user = await db.find(id); if (!user) { throw new Error(`User ${id} not found`); } return user; } catch (error) { console.error('Error fetching user:', error); throw error; }}
// Kursor w pustej linii, brak zaznaczenia// Ctrl+K: "Utwórz funkcję do walidacji adresów email"
// Generuje nowy kod w miejscu kursora:function isValidEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email);}
Przekształć niejasne żądania w precyzyjne instrukcje:
❌ Niejasne
“Ulepsz to” “Napraw to” “Optymalizuj”
✅ Konkretne
“Dodaj walidację wejścia dla null i pustych stringów” “Przekonwertuj callbacki na async/await” “Wyodrębnij magiczne liczby jako nazwane stałe”
Przykładowe transformacje:
// Oryginałfunction calc(x, y) { return x * 0.1 + y * 0.15;}
// Niejasne: "Zrób to jaśniejsze"// Konkretne: "Wyodrębnij stawki podatkowe jako stałe i dodaj walidację parametrów"
// Wynik:const TAX_RATE_BASE = 0.1;const TAX_RATE_ADDITIONAL = 0.15;
function calc(x, y) { if (typeof x !== 'number' || typeof y !== 'number') { throw new TypeError('Oba parametry muszą być liczbami'); } return x * TAX_RATE_BASE + y * TAX_RATE_ADDITIONAL;}
Odwołuj się do otaczającego kodu w swoich instrukcjach:
// Zaznacz funkcjęasync function createUser(data) { return db.users.insert(data);}
// Ctrl+K: "Dodaj taką samą walidację jak funkcja updateUser powyżej"// Cursor spogląda na updateUser i stosuje podobną walidację
// Lub bądź jawny odnośnie wzorców:// "Dodaj walidację pasującą do naszego standardowego wzorca API z Joi"
Buduj złożone transformacje stopniowo:
Każda edycja buduje na poprzedniej, utrzymując kontekst:
// Oryginałfunction process(items) { return items.filter(i => i.price > 100).map(i => i.price * 1.2);}
// Po połączonych edycjach:/** * Przetwarza elementy przez filtrowanie i stosowanie narzutu * @param items - Tablica elementów z właściwością price * @returns Tablica dostosowanych cen dla elementów premium */const PREMIUM_THRESHOLD = 100;const MARKUP_RATE = 1.2;
function process(items: Array<{price: number}>): number[] { try { if (!Array.isArray(items)) { throw new TypeError('Items musi być tablicą'); }
return items .filter(item => item.price > PREMIUM_THRESHOLD) .map(item => item.price * MARKUP_RATE); } catch (error) { console.error('Błąd przetwarzania elementów:', error); return []; }}
Edycja inline rozpoznaje i stosuje wzorce:
// Zaznacz wiele podobnych funkcjigetUserById(id) { return db.users.find(id); }getPostById(id) { return db.posts.find(id); }getCommentById(id) { return db.comments.find(id); }
// Ctrl+K: "Przekonwertuj na generyczną funkcję factory"// Wynik:function createFindById(collection) { return (id) => db[collection].find(id);}
const getUserById = createFindById('users');const getPostById = createFindById('posts');const getCommentById = createFindById('comments');
Edycja inline doskonale radzi sobie z transformacjami strukturalnymi:
// Zaznacz:const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
// Ctrl+K: "Przekonwertuj na obiekt indeksowany przez id"// Wynik:const users = { 1: { id: 1, name: 'Alice' }, 2: { id: 2, name: 'Bob' }};
// Zaznacz:function loadData(callback) { fs.readFile('data.json', (err, data) => { if (err) callback(err); else callback(null, JSON.parse(data)); });}
// Ctrl+K: "Przekonwertuj na Promise"// Wynik:function loadData() { return new Promise((resolve, reject) => { fs.readFile('data.json', (err, data) => { if (err) reject(err); else resolve(JSON.parse(data)); }); });}
Używaj edycji inline do ulepszeń wydajności:
// Zaznacz nieefektywny kod:function findDuplicates(arr) { const duplicates = []; for (let i = 0; i < arr.length; i++) { for (let j = i + 1; j < arr.length; j++) { if (arr[i] === arr[j] && !duplicates.includes(arr[i])) { duplicates.push(arr[i]); } } } return duplicates;}
// Ctrl+K: "Optymalizuj używając Set dla złożoności O(n)"// Wynik:function findDuplicates(arr) { const seen = new Set(); const duplicates = new Set();
for (const item of arr) { if (seen.has(item)) { duplicates.add(item); } else { seen.add(item); } }
return Array.from(duplicates);}
Przekształcaj kod aby implementować konkretne wzorce:
// Zaznacz klasę z bezpośrednimi zależnościami:class OrderService { constructor() { this.database = new Database(); this.emailer = new EmailService(); this.logger = new Logger(); }}
// Ctrl+K: "Zastosuj wzorzec dependency injection"// Wynik:class OrderService { constructor(database, emailer, logger) { this.database = database; this.emailer = emailer; this.logger = logger; }}
// Z definicjami interfejsów:interface IDatabase { /* ... */ }interface IEmailService { /* ... */ }interface ILogger { /* ... */ }
class OrderService { constructor( private database: IDatabase, private emailer: IEmailService, private logger: ILogger ) {}}
Dziel złożony kod na moduły:
// Zaznacz dużą funkcję// Ctrl+K: "Wyodrębnij logikę walidacji do oddzielnych funkcji"
// Lub bardziej konkretnie:// "Wyodrębnij każdy krok do nazwanej funkcji podążając za zasadą pojedynczej odpowiedzialności"
Przekształcaj funkcje w w pełni przetestowany kod:
// Zaznacz funkcję:export function parsePrice(priceString: string): number { const cleaned = priceString.replace(/[$,]/g, ''); return parseFloat(cleaned);}
// Ctrl+K: "Dodaj kompleksowe przypadki testowe włączając przypadki brzegowe"// Generuje (w pliku testowym):describe('parsePrice', () => { it('powinien parsować podstawowe stringi cen', () => { expect(parsePrice('$10.99')).toBe(10.99); expect(parsePrice('$1,234.56')).toBe(1234.56); });
it('powinien obsługiwać przypadki brzegowe', () => { expect(parsePrice('$0')).toBe(0); expect(parsePrice('$0.01')).toBe(0.01); expect(parsePrice('$.99')).toBe(0.99); });
it('powinien obsługiwać nieprawidłowe wejścia', () => { expect(parsePrice('')).toBe(NaN); expect(parsePrice('abc')).toBe(NaN); expect(parsePrice('$')).toBe(NaN); });
it('powinien obsługiwać duże liczby', () => { expect(parsePrice('$1,000,000.00')).toBe(1000000); });});
Generuj dokumentację świadomą kontekstu:
// Zaznacz złożoną funkcję// Ctrl+K: "Dodaj JSDoc z przykładami opartymi na implementacji"
// Edycja inline analizuje kod i generuje:/** * Oblicza odsetki składane od inwestycji * @param {number} principal - Początkowa kwota inwestycji * @param {number} rate - Roczna stopa procentowa (jako dziesiętna, np. 0.05 dla 5%) * @param {number} time - Okres inwestycji w latach * @param {number} n - Liczba składań odsetek rocznie * @returns {number} Końcowa kwota po odsetkach składanych * * @example * // Oblicz miesięczne odsetki składane dla $1000 przy 5% przez 2 lata * calculateCompoundInterest(1000, 0.05, 2, 12); // Zwraca 1104.94 * * @example * // Oblicz roczne odsetki składane * calculateCompoundInterest(5000, 0.03, 10, 1); // Zwraca 6719.58 */
Przekształcaj optymistyczny kod w kod gotowy na produkcję:
// Zaznacz:async function fetchUserData(userId) { const response = await fetch(`/api/users/${userId}`); const data = await response.json(); return data;}
// Ctrl+K: "Dodaj kompleksową obsługę błędów z logiką retry"// Wynik:async function fetchUserData(userId, maxRetries = 3) { if (!userId) { throw new Error('userId jest wymagane'); }
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const response = await fetch(`/api/users/${userId}`);
if (!response.ok) { if (response.status === 404) { throw new Error(`Użytkownik ${userId} nie został znaleziony`); } throw new Error(`Błąd HTTP! status: ${response.status}`); }
const data = await response.json(); return data;
} catch (error) { lastError = error;
if (attempt < maxRetries && !error.message.includes('nie został znaleziony')) { console.warn(`Próba ${attempt} nie powiodła się, ponawiam...`); await new Promise(resolve => setTimeout(resolve, 1000 * attempt) ); } } }
throw new Error(`Niepowodzenie po ${maxRetries} próbach: ${lastError.message}`);}
Edycja inline może zidentyfikować i obsłużyć przypadki brzegowe:
// Zaznacz funkcję, która potrzebuje obsługi przypadków brzegowych// Ctrl+K: "Dodaj obsługę przypadków brzegowych dla null, undefined, pustych tablic i wartości granicznych"
Naciśnij Alt+Enter
zamiast Enter
dla szybkich pytań:
// Zaznacz kodconst result = data?.user?.profile?.email || 'default@example.com';
// Ctrl+K, następnie Alt+Enter: "Co robi ?."// Cursor wyjaśnia optional chaining bez modyfikowania kodu
Porada pro Używaj szybkich pytań do zrozumienia kodu przed jego transformacją.
Twórz potężne przepływy pracy:
Inline Edit → Tab
Użyj edycji inline do rozpoczęcia refaktoryzacji, następnie Tab do ukończenia podobnych wzorców
Inline Edit → Agent
Użyj edycji inline do lokalnych zmian, następnie Agent do aktualizacji całego projektu
Wyszukiwanie → Inline Edit
Znajdź wszystkie wystąpienia, następnie grupowo przekształć z edycją inline
Przykładowy przepływ pracy:
1. Wyszukaj wszystkie instrukcje "console.log"2. Zaznacz każdą grupę wyników3. Ctrl+K: "Zamień na odpowiednie wywołania logger.debug"4. Przejrzyj i zastosuj zmiany
✅ Rób:
❌ Nie rób:
Wyzwanie refaktoryzacji: Weź 50-liniową funkcję i podziel ją na mniejsze funkcje używając tylko edycji inline.
Wyzwanie bezpieczeństwa typów: Przekonwertuj plik JavaScript na TypeScript z właściwymi typami używając połączonych edycji inline.
Zastosowanie wzorca: Zastosuj trzy różne wzorce projektowe do klasy używając edycji inline.
Generowanie testów: Wygeneruj kompletne pokrycie testów dla modułu używając edycji inline.
Opanowałeś precyzyjną transformację kodu z edycją inline. Teraz eksploruj Optymalizacja agent i chat, aby obsługiwać złożone operacje na wielu plikach i wykorzystywać AI do podejmowania decyzji architektonicznych.