【小ネタ】AIにVSCodeの設定ファイルの書き方などを尋ねてみると良かったです

もちろん裏取りは必要ですが、エディターの設定ファイルをどう書くのかAIに聞いてみるのも面白かったです。特にエディターは「○○みたいにしたい」というのを言語化して、どう調べれば良いのかわからなかったので今後も助けてくれそうな気がしています。
2023.06.06

こんにちは。AWS事業本部コンサルティング部に所属している今泉(@bun76235104)です。

今回は超がつくほどのの小ネタなのですが、生成系のAIにVSCodeの設定周りについて聞いたり、作業をお願いしたらとても快適だったので使い方の一旦を紹介します。

やってみたことは以下のとおりです。

  • 独自スニペット用のJSON文字列を書いてもらう
  • キーボードショートカットの設定(keybindings.json)の書き方を教えてもらう
  • 設定ファイル(settings.json)の書き方を教えてもらう

実際にやってみた

今回試している環境は以下のとおりです。

  • 試してみたツール
    • Raycast AI(有料ツール)
    • ChatGPT(Web版)
  • モデル: GPT-3.5-turbo

独自スニペット用の設定を書いてもらう

背景

私は趣味で競技プログラミングを楽しんでおります。

競技プログラミングでは素早く正確にコードを書く力が求められるため、任意の処理や計算をスニペットとして登録しておき、さっと取り出したいことがあります。

VSCodeではユーザーが任意のスニペットを登録できるのですが、以下のようなクラスをスニペットとして登録する場合に、以下のようなJSONを書く必要があり手間がかかっていました。

import math

# 2次元平面上でベクトルに関する便利なメソッドをまとめているクラス
class Vector2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Vector2D(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Vector2D(self.x - other.x, self.y - other.y)

    def __mul__(self, scalar):
        return Vector2D(self.x * scalar, self.y * scalar)

    def __truediv__(self, scalar):
        return Vector2D(self.x / scalar, self.y / scalar)

    def dot(self, other):
        return self.x * other.x + self.y * other.y

    def cross(self, other):
        return self.x * other.y - self.y * other.x

    def length(self):
        return math.sqrt(self.x ** 2 + self.y ** 2)

    def normalized(self):
        length = self.length()
        if length == 0:
            return Vector2D(0, 0)
        return self / length

    def angle(self, other):
        return math.acos(self.dot(other) / (self.length() * other.length()))

    def __repr__(self):
        return f"Vector2D({self.x}, {self.y})"

これをスニペットとして登録するために以下のような文字列を設定ファイルに追記する必要があります。

{
    "my-vector2d-class": {
        "prefix": "my-vector2d-class",
        "body": [
            "import math",
            "",
            "class Vector2D:",
            "    def __init__(self, x, y):",
            "        self.x = x",
            "        self.y = y",
            "",
            "    def __add__(self, other):",
            "        return Vector2D(self.x + other.x, self.y + other.y)",
            "",
            "    def __sub__(self, other):",
            "        return Vector2D(self.x - other.x, self.y - other.y)",
            "",
            "    def __mul__(self, scalar):",
            "        return Vector2D(self.x * scalar, self.y * scalar)",
            "",
            "    def __truediv__(self, scalar):",
            "        return Vector2D(self.x / scalar, self.y / scalar)",
            "",
            "    def dot(self, other):",
            "        return self.x * other.x + self.y * other.y",
            "",
            "    def cross(self, other):",
            "        return self.x * other.y - self.y * other.x",
            "",
            "    def length(self):",
            "        return math.sqrt(self.x ** 2 + self.y ** 2)",
            "",
            "    def normalized(self):",
            "        length = self.length()",
            "        if length == 0:",
            "            return Vector2D(0, 0)",
            "        return self / length",
            "",
            "    def angle(self, other):",
            "        return math.acos(self.dot(other) / (self.length() * other.length()))",
            "",
            "    def __repr__(self):",
            "        return f\"Vector2D({self.x}, {self.y})\""
        ],
        "description": "My Vector2D class"
    }
}

手動でやるとかなり面倒ですよね?

AIに頼んでみた

以下のように雑な文章で頼んでみました。

【私の指示】

  • 以下に渡すコードについてVSCodeの独自スニペットとして登録したいです。
  • JSONの書き方を示してください。なおインデントや空欄はタブではなくスペースを使ってください。
  • (先ほど記載したPythonコードを記載)

すると以下のように返答をくれました。

【回答】

  • 以下は、VSCodeの独自スニペットとして登録するためのJSONの例です。この例では、my-vector2d-classという名前のスニペットを定義しています。
{
    "my-vector2d-class": {
        "prefix": "my-vector2d-class",
        "body": [
            "import math",
            "",
            "class Vector2D:",
            "\tdef __init__(self, x, y):",
            "\t\tself.x = x",
            "\t\tself.y = y",
            "",
            "\tdef __add__(self, other):",
            "\t\treturn Vector2D(self.x + other.x, self.y + other.y)",
            "",
            "\tdef __sub__(self, other):",
            "\t\treturn Vector2D(self.x - other.x, self.y - other.y)",
            "",
            "\tdef __mul__(self, scalar):",
            "\t\treturn Vector2D(self.x * scalar, self.y * scalar)",
            "",
            "\tdef __truediv__(self, scalar):",
            "\t\treturn Vector2D(self.x / scalar, self.y / scalar)",
            "",
            "\tdef dot(self, other):",
            "\t\treturn self.x * other.x + self.y * other.y",
            "",
            "\tdef cross(self, other):",
            "\t\treturn self.x * other.y - self.y * other.x",
            "",
            "\tdef length(self):",
            "\t\treturn math.sqrt(self.x ** 2 + self.y ** 2)",
            "",
            "\tdef normalized(self):",
            "\t\tlength = self.length()",
            "\t\tif length == 0:",
            "\t\t\treturn Vector2D(0, 0)",
            "\t\treturn self / length",
            "",
            "\tdef angle(self, other):",
            "\t\treturn math.acos(self.dot(other) / (self.length() * other.length()))",
            "",
            "\tdef __repr__(self):",
            "\t\treturn f\"Vector2D({self.x}, {self.y})\""
        ],
        "description": "My Vector2D class"
    }
}
  • この例では、prefixプロパティにはスニペットのトリガーとなるテキストを設定し、bodyプロパティにはスニペットの内容を配列形式で定義しています。
  • 各行は文字列として定義され、エスケープが必要な場合はバックスラッシュを使用してください。
  • また、インデントにはスペースを使用してください。
  • descriptionプロパティは、スニペットの説明を設定するために使用されます。このプロパティは省略可能です。 スニペットを登録するには、以下の手順に従ってください。
  1. VSCodeを開きます。
  2. FileニューからPrences>User Snippetsを選択します。
  3. python.jsonを選択します(Pythonのスニペットを登録する場合)。
  4. my-vector2d-classという名前のオブジェクトを追加します。追加するプロパティは、上記のJSONの例に従って設定してください。
  5. 変更を保存します。 スニペットを使用するには、エディタでprefixプロパティに設定したテキストを入力し、tabキーを押します。すると、bodyプロパティに定義したコードが挿入されます。

【指示の追加】

タブではなくインデントにはスペースを使って欲しかったのですが、指示が伝わっていないようでした。

ということで以下のように指示を追加しました。

  • インデントや空欄はタブではなくスペースを使ってください

すると以下のように求めていた形でJSONを例示してくれました。

【回答】

  • 申し訳ありません。前回の回答でタブを使用してしまいました。以下は、スペースを使用したJSONの例です。
{
    "my-vector2d-class": {
        "prefix": "my-vector2d-class",
        "body": [
            "import math",
            "",
            "class Vector2D:",
            "    def __init__(self, x, y):",
            "        self.x = x",
            "        self.y = y",
            "",
            "    def __add__(self, other):",
            "        return Vector2D(self.x + other.x, self.y + other.y)",
            "",
            "    def __sub__(self, other):",
            "        return Vector2D(self.x - other.x, self.y - other.y)",
            "",
            "    def __mul__(self, scalar):",
            "        return Vector2D(self.x * scalar, self.y * scalar)",
            "",
            "    def __truediv__(self, scalar):",
            "        return Vector2D(self.x / scalar, self.y / scalar)",
            "",
            "    def dot(self, other):",
            "        return self.x * other.x + self.y * other.y",
            "",
            "    def cross(self, other):",
            "        return self.x * other.y - self.y * other.x",
            "",
            "    def length(self):",
            "        return math.sqrt(self.x ** 2 + self.y ** 2)",
            "",
            "    def normalized(self):",
            "        length = self.length()",
            "        if length == 0:",
            "            return Vector2D(0, 0)",
            "        return self / length",
            "",
            "    def angle(self, other):",
            "        return math.acos(self.dot(other) / (self.length() * other.length()))",
            "",
            "    def __repr__(self):",
            "        return f\"Vector2D({self.x}, {self.y})\""
        ],
        "description": "My Vector2D class"
    }
}

実際にPythonファイルを開いて試してみたら、意図するスニペットとなっておりとても助かりました。

キーボードショートカットの設定を教えてもらう

背景

VSCodeにはユーザー独自のキーボードショートカットが追記できることをご存じでしょうか?

参考: Visual Studio Code Key Bindings

この際keybindings.jsonというファイルに設定を記載することで、細かな条件でショートカットキーを設定できます。

でも、複雑な条件とかだと調べながら書かないとわからないですよね。

私は以前Vim - Visual Studio Marketplaceの拡張機能を利用していて、いくつか独自のショートカット設定に悩んだことがあったので、ちょっと試してみました。

AIに頼んでみた

VSCodeのVim拡張利用環境でちょっと複雑なショートカットをJSONで表現するようにお願いしてみました。

【私の依頼】

  • VSCodeでVimの拡張機能を利用しています。
  • Vim拡張利用時のVisualモード利用の際に、sa 'を押下することで選択中の文字列が'で囲まれるようにするkeybindings.jsonの設定を教えてください

【回答】

  • Visual Studio CodeでVim拡張機能を利用している場合、Visualモードで選択中の文字列を'で囲むためにはkeybindings.jsonファイルを編集します。
  {
    "key": "s a '",
    "command": "editor.action.insertSnippet",
    "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Visual'",
    "args": {
      "snippet": "'${TM_SELECTED_TEXT}'"
    }
  }

この時点で知らなかったのですが${TM_SELECTED_TEXT}はSnippetで利用できる変数のようですね。

実際に設定してみると、意図した動作になっていたようで感心しました。(実際は私はVSCode Neovim - Visual Studio Marketplaceの設定で上記動作を実現しているため、長時間この設定を試したわけではありません)

設定ファイル(settings.json)の書き方を教えてもらう

背景

VSCodeではsettings.jsonに設定情報を記述することで、各種設定値を自由度高く設定することができます。

例えばファイル保存時のフォーマットを特定の言語ファイルでのみ有効にすることも可能です。

これについても、言語ごとの良さげな設定がわからなかったので例示してもらうことにしました。

AIに頼んでみた

【私の指示】

  • VSCodeでTypeScriptの設定をしようとしています。 言語がTypeScriptの時だけ保存時に自動でフォーマットを実行するsettings.jsonの書き方を教えてください

【回答】

以下のようにJSONの例を出してくれました。

実際これを設定することで、TypeScriptのファイルの保存時にのみあらかじめ設定したフォーマッタが適用されます。

{
  // 本来以下のバックスラッシュは不要ですので、実際に利用する際は削除してください
  "\[typescript\]": {
    "editor.formatOnSave": true
  }
}

また、以下のように.tsx.d.tsのためにアドバイスまでくれました。

  • なお、この設定はTypeScriptの拡張子が.ts場合に適用されます。もし.tsx.d.tsなどの拡張子にも適用したい場合は、 の代わりに [typescriptreact] や[typescriptdeclaration] などの言語識別子を追加してください。

気が利いていてすごいなぁ。(子どものような感想)

もうちょっと難しいことも聞いてみました。

【追加の指示】

  • TypeScriptでコーディングするにあたって、おすすめのsetting.jsonの設定を教えてください。一つ一つの設定の意味もコメントしてください。また、フォーマットは拡張機能を利用して世界でもよく使われるフォーマッタを適用できるようにしてください

【回答内容】

以下のように答えてくれました。

{
    // 本来以下のバックスラッシュは不要ですので、実際に利用する際は削除してください
  "\[typescript\]": {
    "editor.formatOnSave": true,
    "editor.tabSize": 2,
    "editor.insertSpaces": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // メモ: 個人的にこれは不要
  "editor.formatOnType": true,
  "editor.wordWrap": "on",
  "editor.wordWrapColumn": 80,
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true,
    // 本来以下のバックスラッシュは不要ですので、実際に利用する際は削除してください
  "[\typescriptreact\]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 本来以下のバックスラッシュは不要ですので、実際に利用する際は削除してください
  "[\json\]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // メモ: テーマは別に自分で決めたいのでいいです
  "workbench.colorTheme": "Default Light+"
}

個人的に何点か気になるところはありますが、それなりに気を使った回答をしてくれてますね。

個人の感想ですが全般において、設定をそのまま使うよりも、「○○っていう設定はsettings.jsonでどのように書けば良い?」のような質問が良いかもしれません。

さいごに

とっても小ネタでしたが、読んでいただきありがとうございます。

みなさんOpenAIなど色々とツールを使いこなされているかと思いますが、何かの参考になれば幸いです。

以上、今泉でした。