vscode の lua デバッガーに

https://marketplace.visualstudio.com/items?itemName=tomblind.local-lua-debugger-vscode を使っていたのだが、

launch.jsonargs\\ が入るとエラーで起動できない。 Windows で作業しているので、稀によくファイルパスの指定に \\ が入る。

DebugAdapter を作っていたら、直し方がわかった

https://github.com/ousttrue/local-lua-debugger-vscode/commit/0f3974b73964b2e34f90a21de9757a57d6746eb4

PR

https://github.com/tomblind/local-lua-debugger-vscode/pull/37

Linux では動かんかったらしく、別の方法で修正してくれた。

👍 0.2.2 https://github.com/tomblind/local-lua-debugger-vscode/blob/master/CHANGELOG.md

自前で DebugAdapter 作ってみることにした。

https://github.com/ousttrue/luada

途中まで実装したのだが、

  • luajit.exe + luada.lua

という構成よりは、

  • luada.exe

の方が取り回しがよくて、それなら lua 成分をもっと減らして JSON-RPC 制御も c++ なり rust なりにして lua 埋め込み型の exe が作りやすそう。 元々、 スタンドアロンの lua インタプリタと組み合わせて使う lua スクリプトという方向性で実装していたのだが、 luajit-2.1.0-beta3 一辺倒になりつつあるので気分が変わってきたのであった。 これに関しては、今の構成でできるところまでやってみよう。

VSCode の Extension を作る

手順通りに初期化した。npm は最新版に更新したほうがよいぽい。

MockDebug

を読む。

というサンプルがある。

いくつかの機能をまとめて提供する必要がありそう。

  • launch.json の設定

  • DebugAdapter 本体

  • DebugAdapter を起動する

実装してみる

Extension の activate

適当にイベントを登録して

    // package.json
    "activationEvents": [
        "onDebug",
        "onDebugInitialConfigurations",
        "onDebugDynamicConfigurations",
        "onDebugResolve:lua",
        "onLanguage:lua"
    ],

activate されることを確認

// src/extension.ts
export function activate(context: vscode.ExtensionContext) {
    console.log('activate luada');
}

Launch

    "contributes": {
        "breakpoints": [
            {
                "language": "lua"
            }
        ],
        "debuggers": [
            {
                "type": "luada",
                "label": "LuaDA",
                "languages": [
                    "lua"
                ],
                // launch.json のテンプレート
                "initialConfigurations": [
                    {
                        "type": "luada",
                        "name": "launch luada",
                        "request": "launch",
                        "program": "${workspaceFolder}/main.lua",
                        "args": []
                    }
                ],
                // request: launch に対して可能な property の定義
                "configurationAttributes": {
                    "launch": {
                        "properties": {
                            "program": {
                                "type": "string",
                                "markdownDescription": "Lua program to debug - set this to the path of the script",
                                "default": "${workspaceFolder}/main.lua"
                            },                            
                            "arg": {
                                "type": "array",
                                "markdownDescription": "Command line argument, arg[1] ... arg[n]",
                                "default": []
                            }                            
                        }
                    }
                }
            }
        ]
    },
  • activate で DebugAdapterDescriptorFactory を登録

  • launch で createDebugAdapterDescriptor を実行する

src/extensions.ts

import * as vscode from 'vscode';


function createDebugAdapterDescriptorFactory(context: vscode.ExtensionContext): vscode.DebugAdapterDescriptorFactory {
    return {
        createDebugAdapterDescriptor(
            session: vscode.DebugSession,
            executable: vscode.DebugAdapterExecutable | undefined
        ): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
            console.log('launch luada');
            const runtime = "exe";
            const runtimeArgs: string[] = [];
            //
            // デバッグアダプターを起動する
            // 起動したアダプターと vscode は、標準入出力で JSON-RPC により DebugAdapterProtocol で通信する。
            //
            return new vscode.DebugAdapterExecutable(runtime, runtimeArgs);
        }
    };
}

export function activate(context: vscode.ExtensionContext) {
    console.log('activate luada');
    context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('luada', createDebugAdapterDescriptorFactory(context)));
}

export function deactivate() { }

Debug Adapter の実装

https://microsoft.github.io/debug-adapter-protocol/specification

を見て粛々と実装する。

Output Event

vscode の DebugConsole に出力されるので早期に作ると print debug の助けになる。

Logger

  • DebugAdapterProtocol のやりとりすべてを記録する機能をアダプター側で作るべし。無いとデバッグ困難に。

https://github.com/Microsoft/vscode-debugadapter-node/blob/main/adapter/src/loggingDebugSession.ts

VSIX に出力

https://code.visualstudio.com/api/working-with-extensions/publishing-extension

vsce を使う。

package.json に追加。

    "publisher": "ousttrue",
    "repository": {
        "type": "git",
        "url": "https://github.com/ousttrue/luada.git"
    },
$ npx vsce package

参考

https://github.com/actboy168/lua-debug

  • vscode.DebugAdapterExecutable

https://github.com/tomblind/local-lua-debugger-vscode

  • vscode.DebugAdapterServer

  • TypeScript で vscode.DebugAdapterServer を new

  • vscode と DebugAdapterServer が DAP で通信

  • DebugAdapterServer が lua を spawn もしている

20210729lua

luv