前回の記事
概要
Zenn CLIには、 VS Code に統合する非公式の拡張 VS Code Zenn Editorがあり、Zenn の記事作成に非常に重宝している。
Qiita CLI にも同様の拡張があれば、便利そうなのだが、今のところ、該当する拡張機能を見つけることができない。
せめて、各記事をファイル名ではなく、title で表示するツリービューは欲しい。
そこで自分で拡張機能を作成してみるという試みです。
前回は、ツリービューを表示するところまで実装しました。今回は、npx qiita new
を呼び出し、新規記事用のファイルを作成し、テキストエディタで開くところまで実装します。
作成したソースはGitHub で公開しています。
npx qiita new を呼び出すコマンドの定義
package.json
で npx qiita new
を呼び出すコマンドの定義をします。
"commands": [
{
"command": "qiita-editor.create-new",
"title": "Qiita Editor: Create New",
"icon": "$(file-text)"
}
],
"icon"
に "$(file-text)"
のように指定すると Visual Studio Code 内臓のアイコンを使用できます。
コマンドを呼び出すメニュー(ボタン)の定義
package.json
で "commands"
と同じレベルの "menus"
で定義します。
"menus": {
"view/title": [
{
"command": "qiita-editor.create-new",
"when": "qiita-editor.activated && view == qiita",
"group": "navigation"
}
]
},
"view/title"
というコンテキストを指定することで自前のツリービューのタイトル部分にボタンを作成できます。
qiita-cli を操作するクラスの作成
src\qiitacli\qiitaCli.ts
で qiita-cli
を操作するクラスを定義しました。
import * as vscode from "vscode";
import * as childProcess from "child_process";
import which from "which";
import * as process from "process";
import path from "path";
export class QiitaCli {
private npxPath: string = "";
constructor() {
const env = Object.assign({}, process.env);
which("npx", { path: env.PATH}).then((value) => {
this.npxPath = value;
}).catch((reason) => {
console.log(reason);
});
}
public new_article() {
let intervalId = setInterval(() => {
if (this.npxPath.length > 0 && vscode.workspace.workspaceFolders) {
const qiitaProcess = childProcess.spawn(this.npxPath, ["qiita", "new"], {
cwd: vscode.workspace.workspaceFolders[0].uri.fsPath,
shell: process.platform === 'win32',
windowsHide: true,
stdio: ["pipe", "pipe", "inherit"]
});
qiitaProcess.stdout.setEncoding('utf-8');
qiitaProcess.on("error", (err) => {
console.log(err);
});
qiitaProcess.stdout.on("data", (data) => {
vscode.window.showInformationMessage(data);
});
clearInterval(intervalId);
}
}, 1000);
}
}
new_article
メソッドで npx qiita new
を実行します。本家 VS Code Zenn Editor とは、異なり、npx
経由で qiita-cli
を実行するようにしています。
npx
のフルパスを得るのに多少時間がかかるため、setInterval
で処理を遅延させています。
npx qiita new
を実行する際、作業ディレクトリが qiita-cli
をインストールしているリポジトリになっていないと失敗するので vscode.workspace.workspaceFolders[0].uri.fsPath
で指定しています。
childProcess.spawn
に与えるオプションで windowHide
を有効にするとコマンドプロンプトの表示を抑制できます。
childProcess
の標準出力を読み込む際、デフォルトはBuffer
(バイト列)なので qiitaProcess.stdout.setEncoding('utf-8');
を事前に実行しておくことで UTF-8 文字列として読み込むことができるようにしています。
qiitaProcess.stdout.on("data", (data) => {
vscode.window.showInformationMessage(data);
});
この部分で npx qiita new
の出力を Visual Studio Code に情報メッセージとして表示させています。
コマンドの登録
src\extension.ts
の activate
関数で定義したコマンドを登録し、実行時に QiitaCli
クラスの new_article
メソッドを呼び出すようにします。
context.subscriptions.push(
vscode.commands.registerCommand("qiita-editor.create-new", () => {
cli.new_article();
})
);
ツリービュー更新の仕組みを実装
src\treeView\qiitaTreeViewProvider.ts
で定義している QiitaTreeViewProvider
クラスにツリービュー更新の仕組みを実装します。
private _onDidChangeTreeData: vscode.EventEmitter<any> = new vscode.EventEmitter<any>();
readonly onDidChangeTreeData: vscode.Event<any> = this._onDidChangeTreeData.event;
public refresh() {
this._onDidChangeTreeData.fire(undefined);
}
VS Code Extension Samples の ftpExplorer の仕組みを拝借しました。
ファイルの新規作成を監視しテキストエディタ開く
src\treeView\qiitaTreeViewProvider.ts
にて、ファイルの新規作成を監視し、Drafts
ノードにファイル名を追加し、テキストエディタ開くようにします。
if (vscode.workspace && vscode.workspace.workspaceFolders) {
this.watcher = vscode.workspace.createFileSystemWatcher(
new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], "public/*.md")
);
this.watcher.onDidCreate(async (e) => {
const article = new QiitaTreeItem(path.basename(e.fsPath) , e.path);
this.drafts.addChild(article);
this.refresh();
const doc = await vscode.workspace.openTextDocument(e.path);
await vscode.window.showTextDocument(doc, vscode.ViewColumn.One, true);
});
}
これで npx qiita new
で作成されたファイルを捕捉し、ツリービューに追加するとともにテキストエディタで開けるようになりました。
今後の ToDo
他に良い拡張機能が見つかれば、開発を辞めてしまうかもしれませんが…
-
ノードに更新日時
updated_at
を持たせ、更新日時順にソートさせるようにする。 - ファイル更新時にツリービューが更新できるようにする。
-
npx qiita new
をボタンで実行できるようにする。 - 記事の絞り込みができるようにしたい。
-
npx qiita publish
をボタンで実行できるようにする。 - ファイルアップロードのリンクを開けるようにする。
- モジュール分割を適切にしたい。
-
非同期処理をマジメにやる…
参考文献
- Product Icon Reference | Visual Studio Code Extension API
- Child process | Node.js v24.6.0 Documentation
- child_process.spawnを理解する #Node.js - Qiita
- npm token create --jsonをchild_processで実行しつつ、結果のトークンはコンソールに表示しない方法 #JavaScript - Qiita
- vscode-extension-samples/tree-view-sample/src/ftpExplorer.ts at 986bcc700dee6cc4d1e6d4961a316eead110fb21 · microsoft/vscode-extension-samples
- workspace.createFileSystemWatcher - VS Code API | Visual Studio Code Extension API