Copilot基本機能
この章では、GitHub Copilotのコード補完機能、複数候補の表示、コメントからのコード生成について学びます。
基本的な動作
Section titled “基本的な動作”コードを入力すると、Copilotが続きを予測して提案します:
// 入力中...function calculateTax(price, rate) { // ここでCopilotが提案 ↓ return price * rate;}| キー | 動作 |
|---|---|
Tab | 提案を採用 |
Esc | 提案を却下 |
Ctrl+] | 次の候補を表示 |
Ctrl+[ | 前の候補を表示 |
Alt+] | 次の単語のみ採用 |
インラインでの提案
Section titled “インラインでの提案”# 入力def send_email(to, subject, body): # Copilotの提案(グレーで表示) import smtplib from email.mime.text import MIMEText
msg = MIMEText(body) msg['Subject'] = subject msg['To'] = to
# Tab で採用複数候補の表示
Section titled “複数候補の表示”Copilot パネル
Section titled “Copilot パネル”Ctrl+Enter(Mac: Cmd+Enter)で複数の候補を一覧表示:
// function sort(arr) で候補を表示
// 候補1: クイックソートfunction sort(arr) { if (arr.length <= 1) return arr; const pivot = arr[0]; const left = arr.slice(1).filter(x => x < pivot); const right = arr.slice(1).filter(x => x >= pivot); return [...sort(left), pivot, ...sort(right)];}
// 候補2: バブルソートfunction sort(arr) { for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr.length - i - 1; j++) { if (arr[j] > arr[j + 1]) { [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; } } } return arr;}
// 候補3: 組み込みメソッド使用function sort(arr) { return [...arr].sort((a, b) => a - b);}パネル内で:
- 上下キーで候補を移動
EnterまたはAcceptで採用Escで閉じる
コメントからのコード生成
Section titled “コメントからのコード生成”関数の自動生成
Section titled “関数の自動生成”// ユーザーIDからユーザー情報を取得する関数// APIエンドポイント: /api/users/:id// 戻り値: { id, name, email, createdAt }async function getUserById(id) { const response = await fetch(`/api/users/${id}`); if (!response.ok) { throw new Error(`Failed to fetch user: ${response.status}`); } return response.json();}詳細なコメントで精度向上
Section titled “詳細なコメントで精度向上”# CSVファイルを読み込んでDataFrameに変換する関数# 引数:# - file_path: CSVファイルのパス# - encoding: 文字エンコーディング(デフォルト: utf-8)# - skip_rows: スキップする先頭行数(デフォルト: 0)# 戻り値: pandas DataFrame# 例外: ファイルが存在しない場合はFileNotFoundError
def read_csv_to_dataframe(file_path, encoding='utf-8', skip_rows=0): import pandas as pd
if not os.path.exists(file_path): raise FileNotFoundError(f"File not found: {file_path}")
return pd.read_csv( file_path, encoding=encoding, skiprows=skip_rows )テストコードの生成
Section titled “テストコードの生成”// テスト対象の関数function add(a, b) { return a + b;}
// add関数のテストを書く// - 正の数同士の加算// - 負の数を含む加算// - 0を含む加算// - 小数点を含む加算
describe('add', () => { test('adds positive numbers', () => { expect(add(2, 3)).toBe(5); });
test('adds negative numbers', () => { expect(add(-1, -2)).toBe(-3); });
test('adds with zero', () => { expect(add(5, 0)).toBe(5); });
test('adds decimal numbers', () => { expect(add(0.1, 0.2)).toBeCloseTo(0.3); });});コンテキストの活用
Section titled “コンテキストの活用”ファイル全体のコンテキスト
Section titled “ファイル全体のコンテキスト”Copilotは現在のファイル全体を参照します:
// ファイル上部で定義interface User { id: string; name: string; email: string; role: 'admin' | 'user';}
// 下部でUser型を使う関数を書くと、// Copilotは上部の型定義を参照して適切な提案をするfunction formatUser(user: User): string { return `${user.name} (${user.email}) - ${user.role}`;}関連ファイルのコンテキスト
Section titled “関連ファイルのコンテキスト”開いているタブのファイルも参照されます:
# 開いているファイル- types.ts(型定義)- api.ts(API関数)- utils.ts(ユーティリティ)
# 新しいファイルで# これらの型や関数を使うコードを書くと# 適切な提案が得られやすいプロジェクトの慣習を学習
Section titled “プロジェクトの慣習を学習”// プロジェクトで既存のコードconst fetchUser = async (id) => { const res = await api.get(`/users/${id}`); return res.data;};
// 同じパターンで新しい関数を書くと// 既存のスタイルに合わせた提案がされるconst fetchProduct = async (id) => { const res = await api.get(`/products/${id}`); return res.data;};効果的な使い方
Section titled “効果的な使い方”命名で意図を伝える
Section titled “命名で意図を伝える”# 曖昧な名前 → 曖昧な提案def process(data): # ...
# 明確な名前 → 適切な提案def validate_email_format(email: str) -> bool: import re pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' return bool(re.match(pattern, email))段階的に書く
Section titled “段階的に書く”// 一度に全部書かせるより、段階的に
// Step 1: 関数シグネチャasync function uploadFile(file, options) {
// Step 2: バリデーション(コメントで指示) // ファイルサイズをチェック(最大10MB) if (file.size > 10 * 1024 * 1024) { throw new Error('File size exceeds 10MB limit'); }
// Step 3: メイン処理 // S3にアップロード const formData = new FormData(); formData.append('file', file); // ...}エラーハンドリングの追加
Section titled “エラーハンドリングの追加”// 基本実装を書いた後、エラーハンドリングを追加async function fetchData(url: string) { // try-catchでエラーハンドリング // リトライは3回まで // タイムアウトは5秒
let attempts = 0; const maxAttempts = 3; const timeout = 5000;
while (attempts < maxAttempts) { try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeout);
const response = await fetch(url, { signal: controller.signal }); clearTimeout(timeoutId);
if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); }
return await response.json(); } catch (error) { attempts++; if (attempts >= maxAttempts) { throw new Error(`Failed after ${maxAttempts} attempts: ${error.message}`); } await new Promise(resolve => setTimeout(resolve, 1000 * attempts)); } }}言語別のTips
Section titled “言語別のTips”JavaScript/TypeScript
Section titled “JavaScript/TypeScript”// JSDocコメントで型情報を伝える/** * ユーザーを検索する * @param {string} query - 検索クエリ * @param {Object} options - オプション * @param {number} options.limit - 取得件数 * @param {number} options.offset - オフセット * @returns {Promise<User[]>} ユーザーの配列 */async function searchUsers(query, options = {}) { // Copilotが型情報を参照して適切な実装を提案}Python
Section titled “Python”# 型ヒントで意図を伝えるfrom typing import List, Dict, Optional
def process_items( items: List[Dict[str, any]], filter_key: Optional[str] = None) -> List[Dict[str, any]]: """ アイテムリストを処理する
Args: items: 処理対象のアイテムリスト filter_key: フィルタリングするキー
Returns: 処理済みのアイテムリスト """ if filter_key: return [item for item in items if filter_key in item] return items-- テーブル構造をコメントで説明-- users テーブル: id, name, email, created_at-- orders テーブル: id, user_id, total, status, created_at
-- 過去30日間で最も注文金額が多いユーザートップ10SELECT u.id, u.name, SUM(o.total) as total_amountFROM users uJOIN orders o ON u.id = o.user_idWHERE o.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)GROUP BY u.id, u.nameORDER BY total_amount DESCLIMIT 10;中級者向けTips
Section titled “中級者向けTips”カスタムショートカット
Section titled “カスタムショートカット”VS Code の keybindings.json:
[ { "key": "ctrl+shift+space", "command": "github.copilot.generate", "when": "editorTextFocus" }, { "key": "ctrl+shift+c", "command": "github.copilot.toggleCopilot" }]インラインChat
Section titled “インラインChat”VS Code で Ctrl+I でインラインChatを起動:
// 選択したコードに対して// "この関数をTypeScriptに変換して" と指示
// 変換前function add(a, b) { return a + b;}
// 変換後function add(a: number, b: number): number { return a + b;}提案の質を上げるテクニック
Section titled “提案の質を上げるテクニック”// 1. 具体的な例を示す// 入力例: "hello" → 出力例: "Hello"function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1);}
// 2. 制約を明記// 制約: 配列は空でない、要素は全て正の整数function findMax(arr) { return Math.max(...arr);}
// 3. エッジケースを列挙// エッジケース: 空文字列、null、undefined、特殊文字function sanitize(input) { if (!input) return ''; return input.replace(/[<>&"']/g, char => ({ '<': '<', '>': '>', '&': '&', '"': '"', "'": ''' }[char]));}| 機能 | 操作 | 用途 |
|---|---|---|
| 単一補完 | 入力中に自動表示 | 日常的なコーディング |
| 複数候補 | Ctrl+Enter | 複数のアプローチを比較 |
| コメント生成 | コメント → Tab | 新規関数の作成 |
| インラインChat | Ctrl+I | 選択コードの変換 |
コード補完のベストプラクティス
Section titled “コード補完のベストプラクティス”- 明確な命名: 関数名・変数名で意図を伝える
- コメント活用: 詳細なコメントで精度向上
- 型情報: TypeScript/型ヒントを活用
- 段階的に: 一度に全部ではなく段階的に生成
- レビュー必須: 生成されたコードは必ず確認
採用/却下の判断基準
Section titled “採用/却下の判断基準”✅ 採用すべき場合:- コードが正確で意図通り- セキュリティ上の問題がない- プロジェクトの規約に準拠
❌ 却下すべき場合:- 非推奨のAPIを使用- セキュリティリスクがある- 既存のコードと整合性がない次の章では、Copilot Chatについて学びます。
Q1. Copilotの補完候補を受け入れるキーは何ですか?
Q2. Copilotで複数の補完候補を表示するには?
Q3. コメントからコードを生成するCopilotの機能を活用するには?