Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions .tours/intro.tour

This file was deleted.

87 changes: 87 additions & 0 deletions .tours/linter.tour
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"$schema": "https://aka.ms/codetour-schema",
"title": "Linter",
"steps": [
{
"file": "server/src/server.ts",
"description": "正規表現を用いて,2文字以上の大文字を検出する.",
"line": 100,
"selection": {
"start": {
"line": 72,
"character": 1
},
"end": {
"line": 100,
"character": 3
}
},
"title": "コード検証機能の編集"
},
{
"file": "server/src/server.ts",
"description": "CodeActionなど修正コマンドで利用するモジュールを取得する",
"line": 15,
"selection": {
"start": {
"line": 4,
"character": 1
},
"end": {
"line": 15,
"character": 33
}
},
"title": "利用するモジュールの取得"
},
{
"file": "server/src/server.ts",
"description": "サーバーの初期化でコードをワンクリックで修正する`QuickFix`を定義する.",
"line": 59,
"selection": {
"start": {
"line": 53,
"character": 1
},
"end": {
"line": 59,
"character": 6
}
},
"title": "サーバー初期化設定の編集"
},
{
"file": "server/src/server.ts",
"description": "コードに対して関数を実行するCodeActionのリストを定義",
"line": 149,
"selection": {
"start": {
"line": 149,
"character": 1
},
"end": {
"line": 149,
"character": 40
}
},
"title": "CodeActionの宣言"
},
{
"file": "server/src/server.ts",
"description": "生成した各警告に該当する文字を小文字に修正するCode Actionsを定義する.",
"line": 176,
"selection": {
"start": {
"line": 150,
"character": 1
},
"end": {
"line": 176,
"character": 6
}
},
"title": "CodeAction内容の定義"
}
],
"ref": "linter"
}
39 changes: 8 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
# vscode-language-server-template README
# vscode-language-server-template Linter版 README

"vscode-language-server-template"のREADMEテンプレートです。
実装の内容に従って以下のコンテンツを追加してください。
"vscode-language-server-template"を用いたLinterを作成します。

## 機能

拡張機能の特徴を記入してください。
可能であればスクリーンショットを記載してください。

> Tip: 多くの人気拡張機能は動画を用意しています。利用動画があると使い方を直感的に理解できるようになります。

## 必要環境

必要な依存関係や環境設定があればここに記入してください。

## 設定

拡張機能で利用する設定があればここに記入してください。
![Usage](./usage.gif)

例:

本拡張機能は以下を[設定](https://code.visualstudio.com/docs/getstarted/settings)可能です:

* `sampleserver.enable`: 拡張機能を 有効/無効 にする。標準では有効になっています。

## コマンド

コマンドを作成している場合はここに記入してください。

例:

本拡張機能は以下のコマンドから呼び出すことができます:
## 機能

`Fix all auto-fixable problems`: ソースコードを上の警告を修正する。
* コード検証機能
* 3文字以上の大文字を検出します。
* コード修正機能
* 警告箇所を小文字に修正します
111 changes: 93 additions & 18 deletions server/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
'use strict';

import {
CodeAction,
CodeActionKind,
createConnection,
Diagnostic,
DiagnosticSeverity,
ProposedFeatures,
Range,
TextDocuments,
TextDocumentEdit,
TextDocumentSyncKind,
TextEdit,
VersionedTextDocumentIdentifier
} from 'vscode-languageserver/node';
import { TextDocument } from 'vscode-languageserver-textdocument';

// コマンド識別子
namespace CommandIDs {
export const fix = 'sample.fix';
}

// サーバー接続オブジェクトを作成する。この接続にはNodeのIPC(プロセス間通信)を利用する
// LSPの全機能を提供する
const connection = createConnection(ProposedFeatures.all);
Expand Down Expand Up @@ -39,7 +49,14 @@ connection.onInitialize((_params, _cancel, progress) => {
save: {
includeText: false,
}
}
},
codeActionProvider: {
codeActionKinds: [CodeActionKind.QuickFix],
resolveProvider: true
},
executeCommandProvider: {
commands: [CommandIDs.fix],
},
},
};
});
Expand All @@ -51,23 +68,36 @@ connection.onInitialize((_params, _cancel, progress) => {
function validate(doc: TextDocument) {
// 警告などの状態を管理するリスト
const diagnostics: Diagnostic[] = [];
// 0行目(エディタ上の行番号は1から)の端から端までに警告
const range: Range = {start: {line: 0, character: 0},
end: {line: 0, character: Number.MAX_VALUE}};
// 警告を追加する
const diagnostic: Diagnostic = {
// 警告範囲
range: range,
// 警告メッセージ
message: 'Hello world',
// 警告の重要度、Error, Warning, Information, Hintのいずれかを選ぶ
severity: DiagnosticSeverity.Warning,
// 警告コード、警告コードを識別するために使用する
code: '',
// 警告を発行したソース、例: eslint, typescript
source: 'sample',
};
diagnostics.push(diagnostic);

// 2つ以上並んでいるアルファベット大文字を検出
const text = doc.getText();
// 検出するための正規表現 (正規表現テスト: https://regex101.com/r/wXZbr9/1)
const pattern = /\b[A-Z]{2,}\b/g;
let m: RegExpExecArray | null;

// 正規表現にマッチした文字列すべてを対象にする
while ((m = pattern.exec(text)) !== null) {
// 対象の位置から正規表現にマッチした文字までを対象にする
const range: Range = {
start: doc.positionAt(m.index),
end: doc.positionAt(m.index + m[0].length),
};
// 警告を追加する;
const diagnostic: Diagnostic = {
// 警告範囲
range: range,
// 警告メッセージ
message: `${m[0]} is all UPPERCASE.`,
// 警告の重要度、Error, Warning, Information, Hintのいずれかを選ぶ
severity: DiagnosticSeverity.Warning,
// 警告コード、警告コードを識別するために使用する
code: '',
// 警告を発行したソース、例: eslint, typescript
source: 'sample',
};
// 警告リストに警告内容を追加
diagnostics.push(diagnostic);
}
//接続に警告を通知する
connection.sendDiagnostics({ uri: doc.uri, diagnostics });
}
Expand Down Expand Up @@ -102,6 +132,51 @@ function setupDocumentsListeners() {
// 警告を削除する
connection.sendDiagnostics({ uri: uri, diagnostics: []});
});

// Code Actionを追加する
connection.onCodeAction((params) => {
// sampleから生成した警告のみを対象とする
const diagnostics = params.context.diagnostics.filter((diag) => diag.source === 'sample');

connection.console.info(`Code Actions is added`);
// 対象ファイルを取得する
const textDocument = documents.get(params.textDocument.uri);

// 対象ファイルが存在しない場合は終了する
if (textDocument === undefined || diagnostics.length === 0) {
return [];
}
const codeActions: CodeAction[] = [];
// 各警告に対してアクションを生成する
diagnostics.forEach((diag) => {
// アクションのメッセージ
const title = 'Fix to lower case';
// 警告範囲の文字列取得
const originalText = textDocument.getText(diag.range);
// 該当箇所を小文字に変更
const edits = [TextEdit.replace(diag.range, originalText.toLowerCase())];

const textDocumentIdentifier: VersionedTextDocumentIdentifier = {
uri: textDocument.uri,
version: textDocument.version};
const editPattern = {
documentChanges: [
TextDocumentEdit.create(textDocumentIdentifier, edits)
]
};
// コードアクションを生成
const fixAction = CodeAction.create(
title,
editPattern,
CodeActionKind.QuickFix);
// コードアクションと警告を関連付ける
fixAction.diagnostics = [diag];
fixAction.isPreferred = true;
codeActions.push(fixAction);
});

return codeActions;
});
}

// Listen on the connection
Expand Down
Binary file added usage.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.