diff --git a/client/src/extension.ts b/client/src/extension.ts index 8fb2ce7..1d3a68e 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -7,6 +7,7 @@ import { StatusBarAlignment, ThemeColor, StatusBarItem, + Uri, } from "vscode"; import { @@ -17,6 +18,8 @@ import { ExecuteCommandRequest, } from "vscode-languageclient/node"; +import { objectToSnake } from "ts-case-convert"; + let client: LanguageClient; //拡張機能を立ち上げたときに呼び出す関数 @@ -74,6 +77,75 @@ export function activate(context: ExtensionContext) { }), ); + type OptionsRecord = Record; + + const isFileExists = async (uri: Uri): Promise => { + try { + await workspace.fs.stat(uri); + return true; + } catch (_) { + return false; + } + }; + + context.subscriptions.push( + commands.registerCommand( + "uroborosql-fmt.sync-config-file-with-extension-config", + async () => { + // uroborosql-fmt の設定を取得 + const vsCodeConfig = workspace.getConfiguration("uroborosql-fmt"); + + // Default value of `uroborosql-fmt.configurationFilePath` is "". + const vsCodeConfigPath: string = vsCodeConfig.get( + "configurationFilePath", + ); + const configFilePath = + vsCodeConfigPath !== "" ? vsCodeConfigPath : ".uroborosqlfmtrc.json"; + + // VSCodeで開いているディレクトリを取得 + // 開いていない場合はエラーを出して終了 + const folders = workspace.workspaceFolders; + if (folders === undefined) { + window.showErrorMessage( + "Error: Open the folder before executing this command.", + ); + return; + } + const folderPath = folders[0].uri; + const configFileFullPath = Uri.joinPath(folderPath, configFilePath); + + // 設定値 `configurationFilePath` の除外・ value が null のエントリを除外・ WorkSpaceConfiguration が持つメソッドと内部オブジェクトを除外 + const formattingConfig: OptionsRecord = Object.fromEntries( + Object.entries(vsCodeConfig).filter( + ([key, value]) => + key !== "configurationFilePath" && + value !== null && + typeof value !== "function" && + typeof value !== "object", + ), + ); + + let existingConfig: OptionsRecord; + if (await isFileExists(configFileFullPath)) { + const file = await workspace.fs.readFile(configFileFullPath); + existingConfig = JSON.parse(file.toString()); + } else { + existingConfig = {}; + } + + // 明示的に設定したものだけを上書きする + const merged = { + ...existingConfig, + ...objectToSnake(formattingConfig), + }; + const content = JSON.stringify(merged, null, 2); + + const blob: Uint8Array = Buffer.from(content); + await workspace.fs.writeFile(configFileFullPath, blob); + }, + ), + ); + // ステータスバーの作成と表示 const statusBar = createStatusBar(); statusBar.show(); diff --git a/package.json b/package.json index f41a93d..b64d136 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,10 @@ { "command": "uroborosql-fmt.uroborosql-format", "title": "format sql" + }, + { + "command": "uroborosql-fmt.sync-config-file-with-extension-config", + "title": "Synchronize uroborosql-fmt config file with Extension config" } ], "configuration": {