完成イメージ
ソース
extension.tsに以下を記載。
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('decorator sample is activated');
let timeout: NodeJS.Timer | undefined = undefined;
const FullWidthSpaceDecorationType = vscode.window.createTextEditorDecorationType({
borderWidth: '2px',
borderStyle: 'solid',
overviewRulerColor: '#ff0000',
overviewRulerLane: vscode.OverviewRulerLane.Full,
light: {
// this color will be used in light color themes
borderColor: 'darkblue',
},
dark: {
// this color will be used in dark color themes
borderColor: 'lightblue',
},
});
const HalfWidthSpaceDecorationType = vscode.window.createTextEditorDecorationType({
borderWidth: '1px',
borderStyle: 'solid',
overviewRulerLane: vscode.OverviewRulerLane.Full,
light: {
// this color will be used in light color themes
overviewRulerColor: 'tan',
borderColor: 'tan',
},
dark: {
// this color will be used in dark color themes
overviewRulerColor: 'lemonchiffon',
borderColor: 'lemonchiffon',
},
});
let activeEditor = vscode.window.activeTextEditor;
function updateDecorations() {
if (!activeEditor) {
return;
}
// 連続する半角、全角の正規表現を定義
const hwSpaceRegEx = /[ ]+/g;
const fwSpaceRegEx = /[\u3000]+/g;
// テキストを取得
const text = activeEditor.document.getText();
const halfWidthSpaces: vscode.DecorationOptions[] = [];
const fullWidthSpaces: vscode.DecorationOptions[] = [];
let match;
// 半角文字をデコレーション
while ((match = hwSpaceRegEx.exec(text))) {
const startPos = activeEditor.document.positionAt(match.index);
const endPos = activeEditor.document.positionAt(match.index + match[0].length);
const decoration = {
range: new vscode.Range(startPos, endPos),
hoverMessage: '半角文字: **' + match[0].length + '**',
};
halfWidthSpaces.push(decoration);
}
activeEditor.setDecorations(HalfWidthSpaceDecorationType, halfWidthSpaces);
// 全角文字をデコレーション
while ((match = fwSpaceRegEx.exec(text))) {
const startPos = activeEditor.document.positionAt(match.index);
const endPos = activeEditor.document.positionAt(match.index + match[0].length);
const decoration = {
range: new vscode.Range(startPos, endPos),
hoverMessage: '全角文字: **' + match[0].length + '**',
};
fullWidthSpaces.push(decoration);
}
activeEditor.setDecorations(FullWidthSpaceDecorationType, fullWidthSpaces);
}
function triggerUpdateDecorations(throttle = false) {
if (timeout) {
clearTimeout(timeout);
timeout = undefined;
}
if (throttle) {
timeout = setTimeout(updateDecorations, 500);
} else {
updateDecorations();
}
}
if (activeEditor) {
triggerUpdateDecorations();
}
vscode.window.onDidChangeActiveTextEditor(
(editor) => {
activeEditor = editor;
if (editor) {
triggerUpdateDecorations();
}
},
null,
context.subscriptions
);
vscode.workspace.onDidChangeTextDocument(
(event) => {
if (activeEditor && event.document === activeEditor.document) {
triggerUpdateDecorations(true);
}
},
null,
context.subscriptions
);
}