VS Codeの拡張機能で自分用のツールを作ってみた
はじめに
Javaを書き続けて、それなりにキャリアを重ねてきた僕ですが、とある事情で久しぶりに C言語 を書くことになりました。
ちょっと学習課題が込み入ってくると、当然のように
「IDEと連動したデバッガが使いたい」
「毎回同じコードや設定を書くのは避けたい」
という欲が出てきます。
VS Codeはとても優秀なツールで、確かにそれぞれの機能は提供してくれています。 でも……
やれ settings.json
だの launch.json
だの、「わかってるだろ?」と言わんばかりに VS Code の作法を要求してきます。
僕はCの勉強がしたいのであって、VS Codeの勉強がしたいんじゃないっ!!
はい、こうなりますよね。
そこで、少しでもこの苦行を楽にする方法を考えました。この記事では、その方法と、僕がどう考えてこの仕組みを作ったのかをまとめようと思います。
50手前のおじさんの考えなので、今の若い人に役立つかはわかりませんが……
読んだ人が「ちょっと得した気分」になってくれたらうれしいな♪
ちょっとC言語の勉強始めると困ること
さて、ひょんなことからまたC言語を使い始めたのですが、すでに他の言語を使ってるからなのか、C言語がとても自由に感じる。自由すぎて怖い。
前提環境
とりあえず、どんな環境で勉強しているか共有しないと明後日の方向に話が行きそうなので、一旦共有させてください。
項目 | 記述 | 備考 |
---|---|---|
OS | Ubuntu LTS 24.04 | タダだからw |
Cコンパイラ | GNU Compiler Collection | タダだから。僕は昔からこれ |
エディタ(IDE) | Visual Studio Code | ただだからw。Emacs使いたいんだけど、環境作って時間が溶けそう |
ビルドツール | make | gccと組み合わせるならこれでしょう。ant搭乗前のjavaもこれ使ってたな。 |
デバッガ | gdb | 定番ですよね |
基本昔からタダで使えることを重視して選択しています。
そういえばそもそもLinuxを初めて触ったのも、無料でGCC使えるからだったもんなぁ(25年前)。
僕の困ったあれやこれや。
IDE から デバッグ実行できない。(やりにくい)
テストを書いたら、デバッガで処理を差しはさみながら1行ずつ実行してみたい瞬間ってありますよね。
printf
をたくさん書いてもいいんですけど、
いらない処理てんこ盛りになってソースがどんどん読みづらくなる……。
外部コマンドで gdb
を使ってもいいんだけど、
- ソースを書く
- コマンドプロンプトでデバッガを起動
- 該当箇所をソースで確認しながら、行番号を指定
- 実行 → 戻ってソース修正 → また手動でブレーク設定……
なんかgdb使うためだけに1冊の本が書けそうです。
いまどき、こんな手順やります?
昔は当たり前だった作業も、今のIDE世代にはもう苦行です。
これは極個人的な経験ですが、古いシステムでC言語で実装している場合に、関数の単体テストができずに、テスト仕様書に「gdb使って、処理を止めつつ変数の値を変えて」テストする項目がごまんとあります。もちろん、実行時の変数状態なども全部手動でのダンプ。エビデンスとして補完するという地獄の作業です。いや他に方法がないのなら、どんなに自分が無駄だと思ってもやらなければいけません。お仕事ですから。でも!!僕の勉強はお仕事ではありません!
勘違いしないでほしいのはgdbそのものはとても重要な技術で、今でも変わらず利用しています。車輪の再発名はそもそも避けるべきなので「gdbなんてやめて他のイケてるやり方使おうぜ」とは1mmも言っていないということです。現に、VS Codeとgdbの環境で使っているわけで。これから紹介するのは**もっと楽に使えたらいいよね。そうしようね!!**という提案にすぎません。
ちょうどいいことに、VS Codeにはエディタとgdbを連動させてくれるプラグインがあります。使わない手はありません。でも。。。。利用するためにはlaunch.json等を「手動で」用意する必要があります。1回ならともかく何度も何度も書きたくありません。同じものを書いているつもりでも書き間違えて時間をロスするなど普通に起こりえますので、品質の観点でもよろしくありません。
プロジェクトを作成しにくい
僕は同じディレクトリ構成を作成物ごとに用意してプログラムを書くのが好きです。
例えば、こんな感じに:
chap1/
├── ex1/
│ ├── src/
│ ├── include/
│ ├── test/
│ ├── Makefile
│ └── output/
├── ex2/
│ ├── src/
│ ├── include/
│ ├── test/
│ ├── Makefile
│ └── output/
それぞれの実験コードや演習課題を完全に分離し、 個別にビルド・デバッグ・テストできるようにしたい。
でも、これが毎回大変。
- 同じ
src/
、include/
、test/
、output/
を毎回作る -
Makefile
を毎回作る -
.vscode/
にlaunch.json
とtasks.json
を作る - 必要なら
Doxygen
の設定ファイルも……
やってられん!
しかも、ちょっとディレクトリ名が違うとMakefileのパス修正とか発生する。やっていれば「コピペして直せばいいや」となるけど
「Cの勉強」じゃなくて「VS Codeの準備作業の修行」になってくる。
そんなの、人間のやることじゃない。コンピュータにやらせるべき!! そうです!!やってもらいましょう!
どうすれば実現できるかな?
とりあえず、ぱっと考え付く作り方とそのメリットデメリットを整理します。
案 | 方法 | メリット | デメリット |
---|---|---|---|
案1 | 過去プロジェクトのコピペ | - 手軽ですぐできる - 新しいツールの習得が不要 |
- 毎回手作業でミスが起こりやすい - 作業が「VS Code準備」中心になる - JSONやMakefileのパス修正ミスが頻発 |
案2 | VS Codeスニペットやテンプレ化 | - コピペよりミスが減る - 好きな構成をテンプレート化できる |
- スニペット作成や管理が手間 - フォルダ作成などは手動 - 適用忘れや崩壊リスク |
案3 | PythonやShellなどでCLIツールを作る | - 自動化可能 - フォルダやファイルの作成は得意 - VS Code以外でも使える |
- VS Codeのlaunch.jsonやtasks.jsonの作成は難しい - デバッガ連携や拡張との統合が手間 |
案4 | VS Code拡張機能を作る | - 完全自動で作業ミスゼロ - 勉強対象を「C言語」に集中できる - launch.jsonやtasks.jsonも完全制御 |
- 最初の開発コストが高い - TypeScriptとVS Code APIの学習が必要 |
ここでは案4を採用します。理由はまぁ、メリットがデメリットを上回るからですが、本音は僕が楽しいからです。 ←これが大切。
さて、作ってみようか
ちょっと待て。。。Visual Studioの拡張機能ってどうやって作るの?
まず「拡張機能」といっても、大規模なIDEの内部に埋め込むプラグインのようなものとは少し違います。VS Codeの拡張機能は**「JavaScript(またはTypeScript)」で作るミニアプリ**のような存在です。
主にやることは:
-
コマンドやUI部品を登録
-
ユーザーの操作に反応する処理を書く
-
ファイルやフォルダの操作を行う
-
必要なら外部プログラム(gccやmakeなど)を呼び出す
こんな感じです。
基本構造
VS Code拡張機能の構造はざっくりこんな感じ。
my-extension/
├── src/
│ ├── extension.ts // メインロジック
│ └── 他のヘルパーTS
├── package.json // コマンドや設定の宣言
├── tsconfig.json // TypeScriptの設定
├── template/ // 作成するCプロジェクトの雛形
├── .vscode/ // 開発用の設定(launch.jsonなど)
└── その他(READMEなど)
このプロジェクトを作りながら拡張機能を作成していきます。
環境構築
まずは、開発環境を構築し、最初の拡張機能を作ってみましょう。とはいってもいきなりでは難しいので、ほとんど何も動かない、名前だけの拡張機能です。
前提環境
項目 | 前提内容 | 備考 |
---|---|---|
OS | Windows | 開発用のPC 好みに応じて変更可能。 |
開発言語 | Typescript/JavaScript/node |
-
Node.js をインストール
https://nodejs.org/ja/download/ -
VS Code をインストール
https://code.visualstudio.com/
次に、VS Code公式の Yeoman Generator を使って拡張機能の開発環境をセットアップします。
npm install -g yo generator-code
yo code
npm installでnpmバージョンのエラーに遭遇したら
npm notice
npm notice New major version of npm available! 10.9.2 -> 11.3.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.3.0
npm notice To update run: npm install -g npm@11.3.0
npm notice
これはnpmのバージョンが古いことに起因するえらーです。エラーメッセージ内の指示通り、以下のコマンドを実行して新しいバージョンのnpmを導入しましょう
npm install -g npm@11.3.0
yo codeは対話式のプロジェクトジェネレータですので、作りたいソフトウェアに合わせて適切に回答します。
質問 | 内容 | 推奨回答例 |
---|---|---|
What type of extension do you want to create? | 拡張機能の種類 | New Extension (TypeScript) |
What’s the name of your extension? | 拡張機能の名前 | your_project_name |
What’s the identifier of your extension? | パッケージID(npmのname) | yourprojectname |
What’s the description of your extension? | 説明 | Cプロジェクトの自動生成ツール |
Initialize a git repository? | gitリポジトリを初期化 | Yes |
Which builder to use? | 利用するプロジェクトビルダを選択 | unbundledを選択 |
Which package manager to use? | npm か yarn | npm |
なお、言語に関しては今回は「TypeScript」を選びましょう。なぜならVisual Studio Codeの拡張機能開発には型があった方が絶対に楽だからです(経験談)。
正常にひな型が生成されると以下のようなメッセージが表示されます。
Your extension o2labo-c-project-bootstrapper has been created!
To start editing with Visual Studio Code, use:
code o2labo-c-project-bootstrapper
To package your extension, use:
vsce package
For more information, see https://code.visualstudio.com/api/get-started/your-first-extension.
ソースの役割
さて、プロジェクトのひな型ができあがりました。以下のようなファイル/フォルダ構成になっていると思います。
作られるディレクトリ構成(例)
your_project_name/
├── .vscode/
├── src/extension.ts
├── test/
├── package.json
├── tsconfig.json
├── .gitignore
├── vsc-extension-quickstart.md
ここまでで、拡張機能を作成するための環境が完成しました。今はすべてのファイルの意味を理解し覚える必要はありません。重要な以下のファイル/ディレクトリの用途だけ理解するようにしてください。
ファイル/ディレクトリ | 内容・役割 |
---|---|
src/extension.ts |
メインの拡張機能コード。エントリポイント(activate() )と終了処理(deactivate() )を書く。 |
package.json |
拡張機能の設定情報。コマンド名、アクティベーション条件、依存パッケージなどを定義。 |
out/ |
TypeScriptをコンパイルして生成されるJavaScriptファイル群。 |
ここに記載のないディレクトリについてはおいおい理解するようにしてください。
とりあえずパッケージだけしてみる。
プロジェクトの雛形ができたので、まずは何も実装せずに VS Code拡張機能のパッケージング を体験してみましょう。your_project_nameディレクトリに移動し、以下のコマンドを実行します。
npm install -g @vscode/vsce
vsce package
あれ?エラー??
これはREADMEにまだ未記載の事項がある事を示すエラーです。READMEの内容を正しくエディットするのも大切ですが。今回はただの動作確認なので、以下の様に某頭部を削除します。
削除後、再度vscp package
しましょう。あれ?今度はワーニングです。これはいずれ来る拡張機能を公開する日のために、リポジトリを紐づけて管理しなさいという警告ですが
本日はとりあえず動かしてみたいだけなので丁重に無視します。
yを選択し、Enterを押下します。
あ・・また警告です。これは拡張機能のライセンス条項を記載するファイルが不在であることを示していますが。。
本日はとりあえず動かして。。ryo
yを選択肢てEnterを押下すると。。。
あぁ、やっと完了しました。your_project_name-0.0.1.vsix ファイルが生成されています。
自分のVS Codeにインストールしてみる。
生成された .vsixファイルをインストールしてみます。
>code --install-extension yourprojectname-0.0.1.vsix
Installing extensions...
Extension 'yourprojectname-0.0.1.vsix' was successfully installed.
成功すると、VS Codeの拡張機能一覧に自作の機能が表示されます!
早速確認しましょう。VS Codeを起動して左のアイコンをの中から①「拡張機能」を選択します。名称で絞り込むために②検索バーに「Project」を入力し絞り込みます。
おめでとうございます!your_project_nameプロジェクトが確認できました。
ここまでのソースコードはGit Hubで公開しています。必要に応じてご利用ください。
まとめ
さぁ、環境が作られ、ツールが動作するところまで到達しましたが、長くなったので一旦中締めとします。
今回は
-
C言語の学習で感じた不便さ(デバッガの手動設定、毎回のプロジェクト構成作成の手間)
-
自動化の方法の検討(コピペからVS Code拡張機能までの4案と比較)
-
VS Code拡張機能の開発環境構築
- yo codeを使ったひな型作成
- vsceでのパッケージ作成)
- 自作拡張機能をVS Codeにインストール
といったことを行いました。これで「Cの勉強をしているのにVS Codeの設定ばかりしている状態」から脱出するための第一歩を踏み出せました。
しばらくは「Cの勉強をしたいはずなのに、VS Codeの拡張機能ばかり作っている」となりすが、飽きずにお付き合いください。
次回予告
次回はいよいよ
-
プロジェクト作成コマンドの実装方針の策定
-
プロジェクト作成コマンドの機能実装
を行います。使い勝手のいいツールを作って自分のC言語開発の効率のを爆上げを目指しながら、VS Codeの拡張機能の作り方をサクッと勉強していきましょう。お楽しみに。