はじめに

CursorのTab補完は、単一行の補完にとどまらず、複数行の編集やファイル間のジャンプといった高度な機能を備えています。これらの機能を使いこなすことで、大規模なリファクタリングや複数ファイルにまたがる編集を効率的に行えるようになります。

本記事では、Tab補完の高度な機能を習得し、AI駆動開発の生産性を最大化することを目指します。この記事を読むことで、以下のことができるようになります。

  • 複数行にまたがる編集候補を効率的に活用できる
  • ファイル内・ファイル間のジャンプ機能でシームレスな編集ができる
  • TypeScript/Pythonの自動インポート機能を活用できる
  • Peek内でのTab補完を使いこなせる
  • スニペットや定型文と組み合わせた効率的なコーディングができる

実行環境と前提条件

本記事の内容を実践するための環境要件は以下のとおりです。

項目 要件
オペレーティングシステム Windows 10以上、macOS 10.15以上、Ubuntu 20.04以上/Debian 10以上
Cursor バージョン 2.3以降(2025年12月時点の安定版)
インターネット接続 必須(AIモデル利用に必要)

前提条件

  • Cursorがインストールされ、アカウントでログイン済みであること
  • Tab補完の基本操作(Tab/Esc/Ctrl+Right)を理解していること
  • TypeScriptまたはPythonの基礎知識があると自動インポート機能の理解が深まります

期待される結果

本記事の手順を完了すると、以下の状態になります。

  • 複数行編集とジャンプ機能を使った高速リファクタリングができる
  • 自動インポート機能でimport文の手動追加から解放される
  • Peek内編集でコード参照と修正を同時に行える
  • 定型的なコードパターンの入力が大幅に効率化される

複数行にまたがる編集候補の活用

CursorのTab補完は、単一行だけでなく複数行にわたる編集を一括で提案します。これは従来のコード補完では実現できなかった機能です。

複数行編集が提案される場面

Tab補完が複数行の編集を提案するのは、以下のような場面です。

  • 関数やクラスの実装を新規作成する場合
  • 条件分岐やループ構造を追加する場合
  • 既存コードのリファクタリングで複数箇所を変更する必要がある場合
  • テストケースを追加する場合
1
2
3
4
5
6
// 関数シグネチャを入力すると、実装全体が提案される
function validateEmail(email: string): boolean {
  // ↓ Tab補完が複数行を一括で提案
  // const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  // return emailRegex.test(email);
}

複数行提案の確認と受け入れ

複数行の提案が表示された場合、ゴーストテキストは複数行にわたって表示されます。提案全体を確認してからTabキーを押すことで、すべての行が一括で適用されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 複数行のゴーストテキスト例
interface User {
  // id: string;
  // name: string;
  // email: string;
  // createdAt: Date;
  // updatedAt: Date;
}

// Tab押下後
interface User {
  id: string;
  name: string;
  email: string;
  createdAt: Date;
  updatedAt: Date;
}

部分的な受け入れ

複数行の提案の一部だけを採用したい場合は、Ctrl+Rightによる単語単位の受け入れを活用します。必要な部分まで受け入れ、残りは手動で入力または修正できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 提案
// const result = await fetchData(url);
// console.log(result);
// return result;

// Ctrl+Rightで "const result = await fetchData(url);" まで受け入れ
const result = await fetchData(url);
// 以降は自分でカスタマイズ
if (!result) {
  throw new Error('Data not found');
}
return result;

ファイル内ジャンプ機能

Tab補完は、ファイル内の次の編集箇所を予測し、自動的にカーソルを移動させます。これにより、関連する複数箇所の編集をシームレスに行えます。

ファイル内ジャンプの動作

編集を行った後にTabキーを押すと、Tab補完は次に編集が必要と予測される箇所を特定し、そこへジャンプします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 例: 関数名を変更した場合

// 変更前
function getUserById(id: string) {
  return database.users.find(user => user.id === id);
}

// getUserByIdをgetUserByEmailに変更
function getUserByEmail(email: string) {  // ← ここを編集

// Tab押下後、次の編集箇所にジャンプ
function getUserByEmail(email: string) {
  return database.users.find(user => user.email === email);  // ← ここにジャンプ
}

連鎖的な編集フロー

ファイル内ジャンプを活用すると、リファクタリング作業が大幅に効率化されます。

  1. 最初の編集箇所を変更
  2. Tabで次の関連箇所にジャンプ
  3. 提案を確認してTab/Escで対応
  4. さらにTabで次の箇所へ
  5. 必要な編集がすべて完了するまで繰り返す
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 変数名のリネーム例

// 変更前
const userName = 'Alice';
console.log(userName);
const greeting = `Hello, ${userName}!`;

// userNameをdisplayNameに変更
const displayName = 'Alice';  // ← 編集開始
// Tab → 次の使用箇所にジャンプして提案
console.log(displayName);  // ← Tab受け入れ
// Tab → さらに次の使用箇所にジャンプ
const greeting = `Hello, ${displayName}!`;  // ← Tab受け入れ

ファイル間ジャンプ機能

Tab補完の最も強力な機能の1つが、ファイルをまたいだ編集の予測とジャンプです。関連する複数のファイルを横断して編集を行う際に威力を発揮します。

ファイル間ジャンプの動作

現在のファイルでの編集が別のファイルにも影響する場合、Tab補完はファイル間のジャンプを提案します。提案が発生すると、画面下部にポータルウィンドウが表示されます。

┌─────────────────────────────────────────────────────┐
│ ポータルウィンドウ                                    │
│ src/services/userService.ts:25                       │
│ export function getUserById → getUserByEmail         │
└─────────────────────────────────────────────────────┘

ファイル間ジャンプの活用シーン

ファイル間ジャンプは、以下のような場面で特に有効です。

シーン 説明
関数シグネチャの変更 関数の引数や戻り値を変更した際、呼び出し元も自動更新
インターフェース/型の変更 型定義を変更した際、その型を使用するファイルも更新
定数・設定値の変更 共通定数を変更した際、参照箇所も更新
クラスメソッドの変更 メソッドを変更した際、継承先やインスタンス使用箇所も更新

実践例:関数シグネチャの変更

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// src/utils/format.ts
// 引数を追加
export function formatDate(date: Date, locale: string = 'ja-JP'): string {
  return date.toLocaleDateString(locale);
}

// Tab押下後、ポータルウィンドウが表示
// src/components/DateDisplay.tsx への移動を提案

// src/components/DateDisplay.tsx
// Tab受け入れで自動的にファイルを開き、該当箇所へジャンプ
const formatted = formatDate(new Date(), 'ja-JP');  // ← 引数追加の提案

ファイル間ジャンプのワークフロー

flowchart LR
    A[ファイルAで編集] --> B{関連する変更が<br>他ファイルにある?}
    B -->|Yes| C[ポータルウィンドウ表示]
    C --> D[Tabでジャンプ]
    D --> E[ファイルBで編集提案]
    E --> F{さらに関連変更<br>がある?}
    F -->|Yes| C
    F -->|No| G[編集完了]
    B -->|No| G

TypeScript/Pythonの自動インポート

Tab補完は、TypeScriptとPythonにおいて、不足しているimport文を自動的に追加する機能を備えています。

自動インポートの仕組み

別ファイルで定義されたモジュールやメソッドを使用する際、Tab補完は該当するimport文を自動的に提案します。提案を受け入れると、ファイル先頭に適切なimport文が追加されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// src/components/UserCard.tsx
// Userをインポートせずに使用を開始

const UserCard = ({ user }: { user: User }) => {  // ← Userを入力
  // Tab補完がimport文を提案
  // import { User } from '../types/user';
};

// Tab受け入れ後
import { User } from '../types/user';

const UserCard = ({ user }: { user: User }) => {
  // ...
};

TypeScriptでの自動インポート設定

TypeScriptの自動インポートを有効にするには、Cursor設定で「Imports」オプションを有効化します。

  1. Cursor Settingsを開く
  2. 「Tab」セクションを選択
  3. 「Imports」を有効化

Pythonでの自動インポート設定

Pythonの自動インポートはベータ機能として提供されています。

  1. Cursor Settingsを開く
  2. 「Tab」セクションを選択
  3. 「Auto Import for Python (beta)」を有効化
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# src/services/data_processor.py

# pandasをインポートせずに使用を開始
df = pd.DataFrame(data)  # ← pd.を入力
# Tab補完がimport文を提案
# import pandas as pd

# Tab受け入れ後
import pandas as pd

df = pd.DataFrame(data)

自動インポートが動作しない場合

自動インポートが正しく機能しない場合は、以下を確認してください。

  • プロジェクトに適切な言語サーバーや拡張機能がインストールされているか
  • Ctrl+.(Quick Fix)でimportの候補が表示されるか
  • TypeScript/Python用の拡張機能が正しく設定されているか

Peek内でのTab活用

Tab補完は、Go to Definition(定義へ移動)やGo to Type Definition(型定義へ移動)のPeekビュー内でも動作します。

Peekビューとは

Peekビューは、現在のエディタを離れることなく、関数や型の定義を確認・編集できる機能です。F12キーでPeekビューを開けます。

┌─────────────────────────────────────────────────────┐
│ 現在のファイル                                        │
│ const result = calculateTax(price);                  │
│                      ↓ F12押下                       │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Peek: src/utils/tax.ts                          │ │
│ │ function calculateTax(price: number): number {  │ │
│ │   return price * 0.1;                           │ │
│ │ }                                               │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘

Peek内でのTab補完活用

Peekビュー内でTab補完を使用すると、定義の変更と呼び出し元の更新を一連の流れで行えます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 使用例: 関数の引数を追加

// Step 1: 呼び出し元でF12を押してPeekビューを開く
const tax = calculateTax(price);  // ← ここでF12

// Step 2: Peekビュー内で関数を編集
function calculateTax(price: number, rate: number = 0.1): number {
  return price * rate;
}

// Step 3: Tabを押すと呼び出し元に戻り、引数追加の提案が表示される
const tax = calculateTax(price, 0.08);  // ← Tab補完の提案

Vim連携

Vimモードを使用している場合、gd(Go to Definition)とTab補完を組み合わせることで、定義へのジャンプ、編集、参照の解決までを一連の流れで行えます。

gd → 定義にジャンプ → 編集 → Tab → 呼び出し元を更新 → Tab → 次の参照へ

スニペット・定型文との組み合わせ

Tab補完とスニペット機能を組み合わせることで、定型的なコードパターンの入力をさらに効率化できます。

スニペットの活用

VS Code/Cursorのスニペット機能で定型文を登録しておくと、Tab補完がその文脈を理解してより適切な提案を行います。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// .vscode/snippets.code-snippets
{
  "React Functional Component": {
    "prefix": "rfc",
    "body": [
      "interface ${1:Component}Props {",
      "  $2",
      "}",
      "",
      "export const ${1:Component} = ({ $3 }: ${1:Component}Props) => {",
      "  return (",
      "    <div>",
      "      $0",
      "    </div>",
      "  );",
      "};"
    ]
  }
}

スニペット展開後のTab補完

スニペットを展開した後、Tab補完がコンテキストを理解して実装を提案します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// "rfc"と入力してスニペットを展開
interface UserCardProps {
  // ← Tab補完がプロパティを提案
  // user: User;
  // onClick?: () => void;
}

export const UserCard = ({ user, onClick }: UserCardProps) => {
  return (
    <div>
      // ← Tab補完が実装を提案
      // <h2>{user.name}</h2>
      // <p>{user.email}</p>
      // <button onClick={onClick}>View Details</button>
    </div>
  );
};

定型パターンの学習

Tab補完は、プロジェクト内で繰り返し使用されるパターンを学習します。同じ構造のコードを複数回書くと、次回からはより正確な提案が得られます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// エラーハンドリングパターンの例

// 1回目(手動で記述)
try {
  const result = await fetchUser(id);
  return result;
} catch (error) {
  console.error('Failed to fetch user:', error);
  throw error;
}

// 2回目以降(Tab補完が学習したパターンを提案)
try {
  const result = await fetchProduct(id);
  // ↓ Tab補完が同じパターンを提案
  // return result;
// } catch (error) {
//   console.error('Failed to fetch product:', error);
//   throw error;
// }

高度な設定とカスタマイズ

Tab補完の高度な機能を最大限活用するための設定を紹介します。

推奨設定

設定項目 推奨値 理由
Cursor Tab 有効 複数行候補を表示するため
Partial Accepts 有効 単語単位の受け入れを可能にするため
Imports 有効 TypeScriptの自動インポートのため
Auto Import for Python 有効 Pythonの自動インポートのため
Whitespace-Only Suggestions 無効 不要なフォーマット提案を減らすため

パフォーマンス最適化

大規模なプロジェクトでTab補完のレスポンスを維持するには、以下の点に注意します。

  • コードベースインデックスが完了していることを確認
  • 不要なファイルを.cursorignoreで除外
  • 大きなバイナリファイルや生成ファイルを除外
# .cursorignore
node_modules/
dist/
build/
*.min.js
*.bundle.js

トラブルシューティング

ファイル間ジャンプが動作しない

ファイル間ジャンプが期待どおりに動作しない場合は、以下を確認してください。

  1. コードベースインデックスが完了しているか(ステータスバーで確認)
  2. 関連ファイルがワークスペースに含まれているか
  3. 言語サーバーが正しく動作しているか

自動インポートで誤ったモジュールが提案される

複数のモジュールで同名のエクスポートがある場合、意図しないモジュールからのインポートが提案されることがあります。この場合は以下の対策が有効です。

  • tsconfig.jsonpaths設定を適切に構成
  • 名前空間インポートの使用を検討
  • Rulesファイルでインポート規約を明示

まとめ

CursorのTab補完は、基本的なコード補完を超えて、複数行編集、ファイル間ジャンプ、自動インポートといった高度な機能を提供します。本記事で解説した機能を活用することで、AI駆動開発の生産性を大幅に向上させることができます。

機能 効果
複数行編集 関数やクラスの実装を一括で生成
ファイル内ジャンプ 関連箇所を自動で検出して連鎖的に編集
ファイル間ジャンプ プロジェクト全体でシームレスなリファクタリング
自動インポート import文の手動追加から解放
Peek内Tab 定義と参照を一連の流れで編集

これらの機能を日常的に活用することで、CursorのAI駆動開発の真価を発揮できます。次のステップとして、Cursor Agentとの連携やインライン編集機能の活用を学ぶことで、さらに高度な開発ワークフローを構築できます。

参考リンク