💫

vscode拡張機能でGUIベースのアプリ配置ツールを作るための機能名

2024/08/07に公開

vscodeでアプリの配置を変更する拡張機能を作ろうと思ったときにAIに質問した内容をメモとして残します
(動作未確認を含む)

要件
・macOS上で機能するvscode拡張機能を提供する
・web版のvscodeで動作する
・HTMLベースのGUIを実装する
・.pycetra.mdのファイルを開いたとき、自動的にGUIを開く
・.pycetra.mdのファイルを開いたとき、そのファイルのデータをGUIに表示する
・GUI側からvscode拡張側へデータを送る
・起動しているアプリの座標を取得する
・起動しているアプリの座標を更新することで、操作スペース(Spaces)内/間をアプリが移動する
・アプリの使用中に、ターミナルを開かない

アプリのGUIとしてweb viewを使用

・要件:HTMLベースのGUIを実装する

const panel = vscode.window.createWebviewPanel

web版のvscodeでアプリが動くようにする設定

・要件: web版のvscodeで動作する
package.json

"browser": "./dist/extension.js",

テキストドキュメントが開かれたときに発生するイベント

・要件:.pycetra.mdのファイルを開いたとき、自動的にGUIを開く

vscode.workspace.onDidOpenTextDocument

vscode拡張側からGUI側へデータを送る

・要件:.pycetra.mdのファイルを開いたとき、そのファイルのデータをGUIに表示する

const panel = vscode.window.createWebviewPanel
panel.webview.postMessage

apple scriptの結果をpythonへ渡す

・要件:起動しているアプリの座標を取得する
・要件:起動しているアプリの座標を更新することで、操作スペース(Spaces)内/間をアプリが移動する

const { exec } = require('child_process');

async function runAppleScript(scriptPath) {
    return new Promise((resolve, reject) => {
        exec(`osascript ${scriptPath}`, (error, stdout, stderr) => {
            if (error) {
                reject(`エラー: ${error.message}`);
            } else if (stderr) {
                reject(`標準エラー: ${stderr}`);
            } else {
                resolve(stdout.trim());
            }
        });
    });
}

async function runPythonScript(scriptPath, arg) {
    return new Promise((resolve, reject) => {
        exec(`python ${scriptPath} "${arg}"`, (error, stdout, stderr) => {
            if (error) {
                reject(`エラー: ${error.message}`);
            } else if (stderr) {
                reject(`標準エラー: ${stderr}`);
            } else {
                resolve(stdout.trim());
            }
        });
    });
}


const appleScriptResult = await runAppleScript('path/to/your/example.scpt');
console.log(`AppleScript Result: ${appleScriptResult}`);

const pythonResult = await runPythonScript('path/to/your/script.py', appleScriptResult);
console.log(`Python Script Result: ${pythonResult}`);

(Pythonの処理の中でアプリの座標を計算して座標を更新する。)

ファイルの内容を同期的に読み取る

fs.readFileSync

macで特定のアプリを移動する

・要件:起動しているアプリの座標を更新することで、操作スペース(Spaces)内/間をアプリが移動する
例: Finder

osascript -e 'tell application "Finder" to set bounds of window 3 to {100, 100, 800, 600}'

起動中のアプリ名を取得

・要件:起動しているアプリの座標を取得する

例1: すべてのアプリ

osascript -e 'tell application "System Events" to get {name} of (every process whose background only is false)'


{name} のみでなく、{name, index}など複数の情報にするとアクセシビリティが必要になってしまうためNG

例2: Finder

osascript -e 'tell application "Finder" to get {index, name} of windows'

操作スペースをまたいでアプリを移動

・要件:起動しているアプリの座標を更新することで、操作スペース(Spaces)内/間をアプリが移動する
操作スペース(Spaces)を跨いで移動する機能をosascriptに見つけられなかった。
他のツールですが、yabaiを使うとアプリをスペースを跨いで移動させることができました。

brew install koekeishiya/formulae/yabai
brew services start yabai
brew install jq

// yabaiへアクセシビリティを許可しておく
yabai -m query --windows | jq -r '.[] | select(.app == "Finder") | .id' | xargs -I{} yabai -m window {} --space 3

ターミナルを開かずにコマンドを実行

・要件:アプリの使用中に、ターミナルを開かない

const { execSync, exec } = require('child_process');

web view側からvscode側へpostMessage

・要件:GUI側からvscode拡張側へデータを送る

document.addEventListener('DOMContentLoaded', (event) => {
    vscode.postMessage({
        command: 'init_message',
    });
});

キーワード

  • ウィンドウマネージャ: yabai, Amethyst, xmonad
  • ステージマネージャ: macOS Venturaの組み込みのウィンドウマネージャ
  • 画面分割ツール: ShiftIt, Spectacle, Magnet, BetterSnapTool
GitHubで編集を提案

Discussion