Editor API
Editor APIは、テキストエディターとの包括的な相互作用機能を提供し、テキストの操作、選択の管理、装飾の適用、エディターの動作の制御を可能にします。
概要
Editor APIを使用すると、以下のことができます:
- テキストドキュメントの読み取りと編集
- カーソル位置と選択範囲の管理
- テキスト装飾とハイライトの適用
- エディターの表示設定の制御
- エディターイベントの処理
- カスタムエディター機能の実装
- 複数エディターの管理
- エディターレイアウトの制御
基本的な使用方法
テキスト操作
typescript
import { TraeAPI } from '@trae/api';
// アクティブエディターを取得
const editor = TraeAPI.window.activeTextEditor;
if (editor) {
const document = editor.document;
// ドキュメント情報を取得
console.log('ファイル名:', document.fileName);
console.log('言語ID:', document.languageId);
console.log('行数:', document.lineCount);
console.log('変更されているか:', document.isDirty);
// テキストを編集
await editor.edit(editBuilder => {
// 行の末尾にテキストを挿入
const lastLine = document.lineAt(document.lineCount - 1);
editBuilder.insert(lastLine.range.end, '\n// 新しい行が追加されました');
// 特定の位置にテキストを挿入
const position = new TraeAPI.Position(0, 0);
editBuilder.insert(position, '// ファイルの先頭にコメント\n');
// テキストを置換
const range = new TraeAPI.Range(1, 0, 1, 10);
editBuilder.replace(range, '置換されたテキスト');
// テキストを削除
const deleteRange = new TraeAPI.Range(2, 0, 3, 0);
editBuilder.delete(deleteRange);
});
}
// 新しいドキュメントを作成
async function createNewDocument() {
const document = await TraeAPI.workspace.openTextDocument({
content: '// 新しいファイル\nconsole.log("Hello, World!");',
language: 'javascript'
});
// エディターで開く
const editor = await TraeAPI.window.showTextDocument(document);
return editor;
}
// ファイルを開く
async function openFile(filePath: string) {
const document = await TraeAPI.workspace.openTextDocument(filePath);
const editor = await TraeAPI.window.showTextDocument(document);
return editor;
}選択とカーソル管理
typescript
class SelectionManager {
private editor: TraeAPI.TextEditor;
constructor(editor: TraeAPI.TextEditor) {
this.editor = editor;
this.setupSelectionListeners();
}
private setupSelectionListeners() {
// 選択変更をリッスン
TraeAPI.window.onDidChangeTextEditorSelection(event => {
if (event.textEditor === this.editor) {
console.log('選択が変更されました:', {
selections: event.selections,
kind: event.kind
});
this.handleSelectionChange(event.selections);
}
});
}
private handleSelectionChange(selections: TraeAPI.Selection[]) {
for (const selection of selections) {
console.log('選択範囲:', {
start: selection.start,
end: selection.end,
isEmpty: selection.isEmpty,
isSingleLine: selection.isSingleLine,
isReversed: selection.isReversed
});
}
}
// カーソルを特定の位置に移動
moveCursorTo(line: number, character: number): void {
const position = new TraeAPI.Position(line, character);
const selection = new TraeAPI.Selection(position, position);
this.editor.selection = selection;
// ビューポートをカーソル位置に移動
this.editor.revealRange(selection, TraeAPI.TextEditorRevealType.InCenter);
}
// テキストを選択
selectText(startLine: number, startChar: number, endLine: number, endChar: number): void {
const start = new TraeAPI.Position(startLine, startChar);
const end = new TraeAPI.Position(endLine, endChar);
const selection = new TraeAPI.Selection(start, end);
this.editor.selection = selection;
this.editor.revealRange(selection, TraeAPI.TextEditorRevealType.InCenterIfOutsideViewport);
}
// 複数選択を設定
setMultipleSelections(ranges: Array<{startLine: number, startChar: number, endLine: number, endChar: number}>): void {
const selections = ranges.map(range => {
const start = new TraeAPI.Position(range.startLine, range.startChar);
const end = new TraeAPI.Position(range.endLine, range.endChar);
return new TraeAPI.Selection(start, end);
});
this.editor.selections = selections;
}
// 行全体を選択
selectLine(lineNumber: number): void {
const line = this.editor.document.lineAt(lineNumber);
const selection = new TraeAPI.Selection(line.range.start, line.range.end);
this.editor.selection = selection;
}
// 単語を選択
selectWordAt(position: TraeAPI.Position): void {
const wordRange = this.editor.document.getWordRangeAtPosition(position);
if (wordRange) {
const selection = new TraeAPI.Selection(wordRange.start, wordRange.end);
this.editor.selection = selection;
}
}
// 選択されたテキストを取得
getSelectedText(): string {
const selection = this.editor.selection;
return this.editor.document.getText(selection);
}
// すべての選択されたテキストを取得
getAllSelectedText(): string[] {
return this.editor.selections.map(selection =>
this.editor.document.getText(selection)
);
}
// 選択範囲を拡張
expandSelection(direction: 'up' | 'down' | 'left' | 'right', amount: number = 1): void {
const selection = this.editor.selection;
let newEnd = selection.end;
switch (direction) {
case 'up':
newEnd = newEnd.translate(-amount, 0);
break;
case 'down':
newEnd = newEnd.translate(amount, 0);
break;
case 'left':
newEnd = newEnd.translate(0, -amount);
break;
case 'right':
newEnd = newEnd.translate(0, amount);
break;
}
this.editor.selection = new TraeAPI.Selection(selection.start, newEnd);
}
// 現在の行を選択
selectCurrentLine(): void {
const position = this.editor.selection.active;
this.selectLine(position.line);
}
// 段落を選択
selectParagraph(): void {
const position = this.editor.selection.active;
const document = this.editor.document;
// 段落の開始を見つける
let startLine = position.line;
while (startLine > 0 && document.lineAt(startLine - 1).text.trim() !== '') {
startLine--;
}
// 段落の終了を見つける
let endLine = position.line;
while (endLine < document.lineCount - 1 && document.lineAt(endLine + 1).text.trim() !== '') {
endLine++;
}
const start = new TraeAPI.Position(startLine, 0);
const end = document.lineAt(endLine).range.end;
this.editor.selection = new TraeAPI.Selection(start, end);
}
}
// 選択マネージャーを初期化
const activeEditor = TraeAPI.window.activeTextEditor;
if (activeEditor) {
const selectionManager = new SelectionManager(activeEditor);
}テキスト装飾
typescript
class TextDecorationManager {
private editor: TraeAPI.TextEditor;
private decorationTypes: Map<string, TraeAPI.TextEditorDecorationType> = new Map();
constructor(editor: TraeAPI.TextEditor) {
this.editor = editor;
this.initializeDecorationTypes();
}
private initializeDecorationTypes() {
// エラーハイライト用の装飾タイプ
const errorDecorationType = TraeAPI.window.createTextEditorDecorationType({
backgroundColor: 'rgba(255, 0, 0, 0.1)',
border: '1px solid red',
borderRadius: '2px',
overviewRulerColor: 'red',
overviewRulerLane: TraeAPI.OverviewRulerLane.Right,
light: {
backgroundColor: 'rgba(255, 0, 0, 0.05)'
},
dark: {
backgroundColor: 'rgba(255, 0, 0, 0.15)'
}
});
this.decorationTypes.set('error', errorDecorationType);
// 警告ハイライト用の装飾タイプ
const warningDecorationType = TraeAPI.window.createTextEditorDecorationType({
backgroundColor: 'rgba(255, 165, 0, 0.1)',
border: '1px solid orange',
borderRadius: '2px',
overviewRulerColor: 'orange',
overviewRulerLane: TraeAPI.OverviewRulerLane.Right
});
this.decorationTypes.set('warning', warningDecorationType);
// 情報ハイライト用の装飾タイプ
const infoDecorationType = TraeAPI.window.createTextEditorDecorationType({
backgroundColor: 'rgba(0, 0, 255, 0.1)',
border: '1px solid blue',
borderRadius: '2px',
overviewRulerColor: 'blue',
overviewRulerLane: TraeAPI.OverviewRulerLane.Right
});
this.decorationTypes.set('info', infoDecorationType);
// ハイライト用の装飾タイプ
const highlightDecorationType = TraeAPI.window.createTextEditorDecorationType({
backgroundColor: 'rgba(255, 255, 0, 0.3)',
overviewRulerColor: 'yellow',
overviewRulerLane: TraeAPI.OverviewRulerLane.Center
});
this.decorationTypes.set('highlight', highlightDecorationType);
// 行番号装飾用の装飾タイプ
const lineNumberDecorationType = TraeAPI.window.createTextEditorDecorationType({
isWholeLine: true,
backgroundColor: 'rgba(0, 255, 0, 0.1)',
gutterIconPath: TraeAPI.Uri.file('/path/to/icon.svg'),
gutterIconSize: 'contain'
});
this.decorationTypes.set('lineNumber', lineNumberDecorationType);
// カスタムCSS装飾
const customDecorationType = TraeAPI.window.createTextEditorDecorationType({
before: {
contentText: '→ ',
color: 'gray',
fontWeight: 'bold'
},
after: {
contentText: ' ←',
color: 'gray'
},
textDecoration: 'underline dotted'
});
this.decorationTypes.set('custom', customDecorationType);
}
// 装飾を適用
applyDecoration(
type: string,
ranges: TraeAPI.Range[],
options?: { hoverMessage?: string; renderOptions?: any }
): void {
const decorationType = this.decorationTypes.get(type);
if (!decorationType) {
console.error(`装飾タイプ '${type}' が見つかりません`);
return;
}
const decorationOptions: TraeAPI.DecorationOptions[] = ranges.map(range => ({
range,
hoverMessage: options?.hoverMessage,
renderOptions: options?.renderOptions
}));
this.editor.setDecorations(decorationType, decorationOptions);
}
// エラーをハイライト
highlightErrors(errors: Array<{ range: TraeAPI.Range; message: string }>): void {
const decorationOptions: TraeAPI.DecorationOptions[] = errors.map(error => ({
range: error.range,
hoverMessage: `エラー: ${error.message}`
}));
const errorDecorationType = this.decorationTypes.get('error')!;
this.editor.setDecorations(errorDecorationType, decorationOptions);
}
// 検索結果をハイライト
highlightSearchResults(searchTerm: string): void {
const document = this.editor.document;
const text = document.getText();
const ranges: TraeAPI.Range[] = [];
let match;
const regex = new RegExp(searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
while ((match = regex.exec(text)) !== null) {
const startPos = document.positionAt(match.index);
const endPos = document.positionAt(match.index + match[0].length);
ranges.push(new TraeAPI.Range(startPos, endPos));
}
this.applyDecoration('highlight', ranges, {
hoverMessage: `検索結果: "${searchTerm}"`
});
}
// 行をハイライト
highlightLines(lineNumbers: number[], message?: string): void {
const ranges = lineNumbers.map(lineNumber => {
const line = this.editor.document.lineAt(lineNumber);
return line.range;
});
this.applyDecoration('lineNumber', ranges, {
hoverMessage: message || 'ハイライトされた行'
});
}
// 単語をハイライト
highlightWord(word: string): void {
const document = this.editor.document;
const ranges: TraeAPI.Range[] = [];
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
const text = line.text;
let index = 0;
while ((index = text.indexOf(word, index)) !== -1) {
const start = new TraeAPI.Position(i, index);
const end = new TraeAPI.Position(i, index + word.length);
ranges.push(new TraeAPI.Range(start, end));
index += word.length;
}
}
this.applyDecoration('highlight', ranges, {
hoverMessage: `単語: "${word}"`
});
}
// すべての装飾をクリア
clearAllDecorations(): void {
for (const decorationType of this.decorationTypes.values()) {
this.editor.setDecorations(decorationType, []);
}
}
// 特定の装飾タイプをクリア
clearDecoration(type: string): void {
const decorationType = this.decorationTypes.get(type);
if (decorationType) {
this.editor.setDecorations(decorationType, []);
}
}
// 装飾タイプを破棄
dispose(): void {
for (const decorationType of this.decorationTypes.values()) {
decorationType.dispose();
}
this.decorationTypes.clear();
}
// カスタム装飾を作成
createCustomDecoration(
name: string,
options: TraeAPI.DecorationRenderOptions
): void {
const decorationType = TraeAPI.window.createTextEditorDecorationType(options);
this.decorationTypes.set(name, decorationType);
}
// 動的装飾(アニメーション効果)
animateDecoration(type: string, ranges: TraeAPI.Range[], duration: number = 1000): void {
this.applyDecoration(type, ranges);
setTimeout(() => {
this.clearDecoration(type);
}, duration);
}
}
// テキスト装飾マネージャーを初期化
const activeEditor = TraeAPI.window.activeTextEditor;
if (activeEditor) {
const decorationManager = new TextDecorationManager(activeEditor);
// 使用例
decorationManager.highlightSearchResults('function');
decorationManager.highlightLines([0, 5, 10], 'ブックマークされた行');
}エディター設定とビュー制御
typescript
class EditorViewController {
private editor: TraeAPI.TextEditor;
constructor(editor: TraeAPI.TextEditor) {
this.editor = editor;
this.setupViewListeners();
}
private setupViewListeners() {
// ビューポート変更をリッスン
TraeAPI.window.onDidChangeTextEditorVisibleRanges(event => {
if (event.textEditor === this.editor) {
console.log('表示範囲が変更されました:', event.visibleRanges);
}
});
// エディターオプション変更をリッスン
TraeAPI.window.onDidChangeTextEditorOptions(event => {
if (event.textEditor === this.editor) {
console.log('エディターオプションが変更されました:', event.options);
}
});
// ビューカラム変更をリッスン
TraeAPI.window.onDidChangeTextEditorViewColumn(event => {
if (event.textEditor === this.editor) {
console.log('ビューカラムが変更されました:', event.viewColumn);
}
});
}
// エディターオプションを設定
setEditorOptions(options: Partial<TraeAPI.TextEditorOptions>): void {
this.editor.options = {
...this.editor.options,
...options
};
}
// タブサイズを設定
setTabSize(size: number): void {
this.setEditorOptions({ tabSize: size });
}
// インデントタイプを設定
setIndentType(useSpaces: boolean): void {
this.setEditorOptions({ insertSpaces: useSpaces });
}
// 行番号表示を切り替え
toggleLineNumbers(): void {
// 注意:これはエディター設定であり、ワークスペース設定を通じて制御されます
const config = TraeAPI.workspace.getConfiguration('editor');
const current = config.get<string>('lineNumbers', 'on');
const newValue = current === 'on' ? 'off' : 'on';
config.update('lineNumbers', newValue, TraeAPI.ConfigurationTarget.Workspace);
}
// 単語の折り返しを切り替え
toggleWordWrap(): void {
const config = TraeAPI.workspace.getConfiguration('editor');
const current = config.get<string>('wordWrap', 'off');
const newValue = current === 'off' ? 'on' : 'off';
config.update('wordWrap', newValue, TraeAPI.ConfigurationTarget.Workspace);
}
// 特定の行にスクロール
scrollToLine(lineNumber: number, position: 'top' | 'center' | 'bottom' = 'center'): void {
const line = this.editor.document.lineAt(lineNumber);
const revealType = position === 'top' ? TraeAPI.TextEditorRevealType.AtTop :
position === 'bottom' ? TraeAPI.TextEditorRevealType.Default :
TraeAPI.TextEditorRevealType.InCenter;
this.editor.revealRange(line.range, revealType);
}
// 範囲を表示
revealRange(range: TraeAPI.Range, revealType: TraeAPI.TextEditorRevealType = TraeAPI.TextEditorRevealType.Default): void {
this.editor.revealRange(range, revealType);
}
// 表示範囲を取得
getVisibleRanges(): TraeAPI.Range[] {
return this.editor.visibleRanges;
}
// エディターが表示されているかチェック
isVisible(): boolean {
return this.editor.visibleRanges.length > 0;
}
// エディターのビューカラムを取得
getViewColumn(): TraeAPI.ViewColumn | undefined {
return this.editor.viewColumn;
}
// フォントサイズを変更
changeFontSize(delta: number): void {
const config = TraeAPI.workspace.getConfiguration('editor');
const currentSize = config.get<number>('fontSize', 14);
const newSize = Math.max(8, Math.min(72, currentSize + delta));
config.update('fontSize', newSize, TraeAPI.ConfigurationTarget.Global);
}
// ズームレベルを設定
setZoomLevel(level: number): void {
const config = TraeAPI.workspace.getConfiguration('window');
config.update('zoomLevel', level, TraeAPI.ConfigurationTarget.Global);
}
// ミニマップの表示を切り替え
toggleMinimap(): void {
const config = TraeAPI.workspace.getConfiguration('editor.minimap');
const current = config.get<boolean>('enabled', true);
config.update('enabled', !current, TraeAPI.ConfigurationTarget.Workspace);
}
// 空白文字の表示を切り替え
toggleRenderWhitespace(): void {
const config = TraeAPI.workspace.getConfiguration('editor');
const current = config.get<string>('renderWhitespace', 'selection');
const newValue = current === 'none' ? 'all' : 'none';
config.update('renderWhitespace', newValue, TraeAPI.ConfigurationTarget.Workspace);
}
// インデントガイドの表示を切り替え
toggleIndentGuides(): void {
const config = TraeAPI.workspace.getConfiguration('editor');
const current = config.get<boolean>('renderIndentGuides', true);
config.update('renderIndentGuides', !current, TraeAPI.ConfigurationTarget.Workspace);
}
// エディターのテーマを変更
changeTheme(themeId: string): void {
const config = TraeAPI.workspace.getConfiguration('workbench');
config.update('colorTheme', themeId, TraeAPI.ConfigurationTarget.Global);
}
// 分割ビューでエディターを開く
async openInSplitView(viewColumn: TraeAPI.ViewColumn): Promise<TraeAPI.TextEditor> {
return await TraeAPI.window.showTextDocument(this.editor.document, {
viewColumn: viewColumn,
preserveFocus: false,
preview: false
});
}
// エディターを閉じる
async closeEditor(): Promise<void> {
await TraeAPI.commands.executeCommand('workbench.action.closeActiveEditor');
}
// すべてのエディターを閉じる
async closeAllEditors(): Promise<void> {
await TraeAPI.commands.executeCommand('workbench.action.closeAllEditors');
}
// エディターグループを分割
async splitEditor(direction: 'horizontal' | 'vertical' = 'vertical'): Promise<void> {
const command = direction === 'horizontal' ?
'workbench.action.splitEditorDown' :
'workbench.action.splitEditor';
await TraeAPI.commands.executeCommand(command);
}
}
// エディタービューコントローラーを初期化
const activeEditor = TraeAPI.window.activeTextEditor;
if (activeEditor) {
const viewController = new EditorViewController(activeEditor);
// 使用例
viewController.setTabSize(2);
viewController.scrollToLine(50, 'center');
viewController.changeFontSize(2);
}エディターイベント処理
typescript
class EditorEventHandler {
private disposables: TraeAPI.Disposable[] = [];
constructor() {
this.setupEventListeners();
}
private setupEventListeners() {
// アクティブエディター変更
this.disposables.push(
TraeAPI.window.onDidChangeActiveTextEditor(editor => {
if (editor) {
console.log('アクティブエディターが変更されました:', editor.document.fileName);
this.onActiveEditorChanged(editor);
} else {
console.log('アクティブエディターがありません');
}
})
);
// テキスト変更
this.disposables.push(
TraeAPI.workspace.onDidChangeTextDocument(event => {
console.log('ドキュメントが変更されました:', {
fileName: event.document.fileName,
changes: event.contentChanges.length,
reason: event.reason
});
this.onTextDocumentChanged(event);
})
);
// ドキュメント保存
this.disposables.push(
TraeAPI.workspace.onDidSaveTextDocument(document => {
console.log('ドキュメントが保存されました:', document.fileName);
this.onDocumentSaved(document);
})
);
// ドキュメントを開く
this.disposables.push(
TraeAPI.workspace.onDidOpenTextDocument(document => {
console.log('ドキュメントが開かれました:', document.fileName);
this.onDocumentOpened(document);
})
);
// ドキュメントを閉じる
this.disposables.push(
TraeAPI.workspace.onDidCloseTextDocument(document => {
console.log('ドキュメントが閉じられました:', document.fileName);
this.onDocumentClosed(document);
})
);
// カーソル位置変更
this.disposables.push(
TraeAPI.window.onDidChangeTextEditorSelection(event => {
console.log('選択が変更されました:', {
editor: event.textEditor.document.fileName,
selections: event.selections.length,
kind: event.kind
});
this.onSelectionChanged(event);
})
);
}
private onActiveEditorChanged(editor: TraeAPI.TextEditor): void {
// アクティブエディター変更時の処理
const document = editor.document;
// 言語固有の処理
switch (document.languageId) {
case 'javascript':
case 'typescript':
this.setupJavaScriptFeatures(editor);
break;
case 'python':
this.setupPythonFeatures(editor);
break;
case 'html':
this.setupHTMLFeatures(editor);
break;
}
// ファイルサイズチェック
if (document.getText().length > 1000000) { // 1MB以上
TraeAPI.window.showWarningMessage('大きなファイルです。パフォーマンスが低下する可能性があります。');
}
}
private onTextDocumentChanged(event: TraeAPI.TextDocumentChangeEvent): void {
const document = event.document;
// 変更内容を分析
for (const change of event.contentChanges) {
console.log('変更詳細:', {
range: change.range,
text: change.text,
rangeLength: change.rangeLength
});
// 特定のパターンを検出
if (change.text.includes('TODO')) {
this.highlightTODOs(document);
}
if (change.text.includes('console.log')) {
this.highlightConsoleStatements(document);
}
}
// 自動保存の実装
if (document.isDirty && this.shouldAutoSave(document)) {
this.autoSave(document);
}
}
private onDocumentSaved(document: TraeAPI.TextDocument): void {
// 保存後の処理
console.log(`ファイル "${document.fileName}" が保存されました`);
// 保存統計を更新
this.updateSaveStatistics(document);
// 自動フォーマット
if (this.shouldAutoFormat(document)) {
this.formatDocument(document);
}
// リンターを実行
this.runLinter(document);
}
private onDocumentOpened(document: TraeAPI.TextDocument): void {
// ドキュメントを開いた時の処理
console.log(`ファイル "${document.fileName}" が開かれました`);
// ファイル統計を更新
this.updateFileStatistics(document);
// 最近使用したファイルリストを更新
this.updateRecentFiles(document);
}
private onDocumentClosed(document: TraeAPI.TextDocument): void {
// ドキュメントを閉じた時の処理
console.log(`ファイル "${document.fileName}" が閉じられました`);
// 未保存の変更があるかチェック
if (document.isDirty) {
TraeAPI.window.showWarningMessage(
`ファイル "${document.fileName}" に未保存の変更があります。`
);
}
// リソースをクリーンアップ
this.cleanupDocumentResources(document);
}
private onSelectionChanged(event: TraeAPI.TextEditorSelectionChangeEvent): void {
const editor = event.textEditor;
const selections = event.selections;
// 選択されたテキストの統計
const selectedText = selections.map(selection =>
editor.document.getText(selection)
).join('\n');
if (selectedText.length > 0) {
console.log('選択されたテキスト統計:', {
文字数: selectedText.length,
行数: selectedText.split('\n').length,
単語数: selectedText.split(/\s+/).filter(word => word.length > 0).length
});
}
// 選択範囲に基づく機能
if (selections.length === 1 && !selections[0].isEmpty) {
this.highlightSimilarText(editor, selectedText);
}
}
// ヘルパーメソッド
private setupJavaScriptFeatures(editor: TraeAPI.TextEditor): void {
// JavaScript固有の機能を設定
console.log('JavaScript機能を設定中...');
}
private setupPythonFeatures(editor: TraeAPI.TextEditor): void {
// Python固有の機能を設定
console.log('Python機能を設定中...');
}
private setupHTMLFeatures(editor: TraeAPI.TextEditor): void {
// HTML固有の機能を設定
console.log('HTML機能を設定中...');
}
private highlightTODOs(document: TraeAPI.TextDocument): void {
// TODOコメントをハイライト
console.log('TODOコメントをハイライト中...');
}
private highlightConsoleStatements(document: TraeAPI.TextDocument): void {
// console.logステートメントをハイライト
console.log('console.logステートメントをハイライト中...');
}
private shouldAutoSave(document: TraeAPI.TextDocument): boolean {
// 自動保存の条件をチェック
const config = TraeAPI.workspace.getConfiguration('files');
return config.get<string>('autoSave', 'off') !== 'off';
}
private async autoSave(document: TraeAPI.TextDocument): Promise<void> {
try {
await document.save();
console.log('自動保存が完了しました');
} catch (error) {
console.error('自動保存に失敗しました:', error);
}
}
private shouldAutoFormat(document: TraeAPI.TextDocument): boolean {
const config = TraeAPI.workspace.getConfiguration('editor');
return config.get<boolean>('formatOnSave', false);
}
private async formatDocument(document: TraeAPI.TextDocument): Promise<void> {
try {
await TraeAPI.commands.executeCommand('editor.action.formatDocument');
console.log('ドキュメントのフォーマットが完了しました');
} catch (error) {
console.error('フォーマットに失敗しました:', error);
}
}
private runLinter(document: TraeAPI.TextDocument): void {
// リンターを実行
console.log('リンターを実行中...');
}
private updateSaveStatistics(document: TraeAPI.TextDocument): void {
// 保存統計を更新
console.log('保存統計を更新中...');
}
private updateFileStatistics(document: TraeAPI.TextDocument): void {
// ファイル統計を更新
console.log('ファイル統計を更新中...');
}
private updateRecentFiles(document: TraeAPI.TextDocument): void {
// 最近使用したファイルリストを更新
console.log('最近使用したファイルリストを更新中...');
}
private cleanupDocumentResources(document: TraeAPI.TextDocument): void {
// ドキュメントリソースをクリーンアップ
console.log('ドキュメントリソースをクリーンアップ中...');
}
private highlightSimilarText(editor: TraeAPI.TextEditor, selectedText: string): void {
// 類似テキストをハイライト
console.log('類似テキストをハイライト中...');
}
// リソースを破棄
dispose(): void {
this.disposables.forEach(disposable => disposable.dispose());
this.disposables = [];
}
}
// エディターイベントハンドラーを初期化
const eventHandler = new EditorEventHandler();APIリファレンス
コアインターフェース
typescript
interface TextEditor {
readonly document: TextDocument;
selection: Selection;
selections: Selection[];
readonly visibleRanges: Range[];
options: TextEditorOptions;
readonly viewColumn?: ViewColumn;
edit(callback: (editBuilder: TextEditorEdit) => void): Thenable<boolean>;
insertSnippet(snippet: SnippetString, location?: Position | Range | Position[] | Range[]): Thenable<boolean>;
setDecorations(decorationType: TextEditorDecorationType, rangesOrOptions: Range[] | DecorationOptions[]): void;
revealRange(range: Range, revealType?: TextEditorRevealType): void;
show(column?: ViewColumn): void;
hide(): void;
}
interface TextDocument {
readonly uri: Uri;
readonly fileName: string;
readonly isUntitled: boolean;
readonly languageId: string;
readonly version: number;
readonly isDirty: boolean;
readonly isClosed: boolean;
readonly lineCount: number;
save(): Thenable<boolean>;
getText(range?: Range): string;
getWordRangeAtPosition(position: Position, regex?: RegExp): Range | undefined;
lineAt(line: number): TextLine;
positionAt(offset: number): Position;
offsetAt(position: Position): number;
validateRange(range: Range): Range;
validatePosition(position: Position): Position;
}
interface TextEditorEdit {
replace(location: Position | Range | Selection, value: string): void;
insert(location: Position, value: string): void;
delete(location: Range | Selection): void;
setEndOfLine(endOfLine: EndOfLine): void;
}
interface Selection extends Range {
readonly anchor: Position;
readonly active: Position;
readonly isReversed: boolean;
}
interface TextEditorDecorationType {
readonly key: string;
dispose(): void;
}ベストプラクティス
- パフォーマンス: 大きなファイルでは遅延読み込みとバッチ処理を使用
- メモリ管理: 不要な装飾とイベントリスナーを適切に破棄
- ユーザーエクスペリエンス: 長時間の操作には進行状況を表示
- エラーハンドリング: ファイル操作の失敗を適切に処理
- 設定: ユーザー設定を尊重し、適切なデフォルト値を提供
- アクセシビリティ: スクリーンリーダーと互換性のある装飾を使用
- テスト: さまざまなファイルタイプとサイズでテスト
- ドキュメント: API使用方法の明確な例を提供
関連API
- Workspace API - ファイル操作用
- Commands API - エディターコマンド用
- Debugging API - デバッグ統合用