From d3b2c5227c98192fc89a72e06c9637c9e39f524a Mon Sep 17 00:00:00 2001 From: Daelon Suzuka Date: Fri, 13 Oct 2023 14:33:26 -0400 Subject: [PATCH] Reorganize extension entrypoint (#505) * Combine godot-tools.ts into extension.ts to put the extension's major components at the same level --- package-lock.json | 14 + package.json | 1 + src/deps/prism/prism.js | 573 ------------------------------- src/extension.ts | 205 ++++++++++- src/godot-tools.ts | 213 ------------ src/lsp/NativeDocumentManager.ts | 2 +- src/settings_updater.ts | 11 +- 7 files changed, 216 insertions(+), 803 deletions(-) delete mode 100644 src/deps/prism/prism.js delete mode 100644 src/godot-tools.ts diff --git a/package-lock.json b/package-lock.json index d1df7157c..78e3cf632 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "global": "^4.4.0", "marked": "^4.0.11", "net": "^1.0.2", + "prismjs": "^1.17.1", "terminate": "^2.5.0", "vscode-debugadapter": "^1.38.0", "vscode-languageclient": "^7.0.0", @@ -1758,6 +1759,14 @@ "node": ">=6" } }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -3710,6 +3719,11 @@ "tunnel-agent": "^0.6.0" } }, + "prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", diff --git a/package.json b/package.json index 62784de2c..0f58a798b 100644 --- a/package.json +++ b/package.json @@ -590,6 +590,7 @@ "global": "^4.4.0", "marked": "^4.0.11", "net": "^1.0.2", + "prismjs": "^1.17.1", "terminate": "^2.5.0", "vscode-debugadapter": "^1.38.0", "vscode-languageclient": "^7.0.0", diff --git a/src/deps/prism/prism.js b/src/deps/prism/prism.js deleted file mode 100644 index 190cce5d1..000000000 --- a/src/deps/prism/prism.js +++ /dev/null @@ -1,573 +0,0 @@ -/* PrismJS 1.17.1 -https://prismjs.com/download.html#themes=prism */ -var _self = (typeof window !== 'undefined') - ? window // if in browser - : ( - (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) - ? self // if in worker - : {} // if in node js - ); - -/** - * Prism: Lightweight, robust, elegant syntax highlighting - * MIT license http://www.opensource.org/licenses/mit-license.php/ - * @author Lea Verou http://lea.verou.me - */ - -var Prism = (function (_self){ - -// Private helper vars -var lang = /\blang(?:uage)?-([\w-]+)\b/i; -var uniqueId = 0; - -/** - * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class. - * - * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned. - * - * @param {Element} element - * @returns {string} - */ -function getLanguage(element) { - while (element && !lang.test(element.className)) { - element = element.parentNode; - } - if (element) { - return (element.className.match(lang) || [, 'none'])[1].toLowerCase(); - } - return 'none'; -} - - -var _ = { - manual: _self.Prism && _self.Prism.manual, - disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler, - util: { - encode: function (tokens) { - if (tokens instanceof Token) { - return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); - } else if (Array.isArray(tokens)) { - return tokens.map(_.util.encode); - } else { - return tokens.replace(/&/g, '&').replace(/ text.length) { - // Something went terribly wrong, ABORT, ABORT! - return; - } - - if (str instanceof Token) { - continue; - } - - if (greedy && i != strarr.length - 1) { - pattern.lastIndex = pos; - var match = pattern.exec(text); - if (!match) { - break; - } - - var from = match.index + (lookbehind && match[1] ? match[1].length : 0), - to = match.index + match[0].length, - k = i, - p = pos; - - for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) { - p += strarr[k].length; - // Move the index i to the element in strarr that is closest to from - if (from >= p) { - ++i; - pos = p; - } - } - - // If strarr[i] is a Token, then the match starts inside another Token, which is invalid - if (strarr[i] instanceof Token) { - continue; - } - - // Number of tokens to delete and replace with the new match - delNum = k - i; - str = text.slice(pos, p); - match.index -= pos; - } else { - pattern.lastIndex = 0; - - var match = pattern.exec(str), - delNum = 1; - } - - if (!match) { - if (oneshot) { - break; - } - - continue; - } - - if(lookbehind) { - lookbehindLength = match[1] ? match[1].length : 0; - } - - var from = match.index + lookbehindLength, - match = match[0].slice(lookbehindLength), - to = from + match.length, - before = str.slice(0, from), - after = str.slice(to); - - var args = [i, delNum]; - - if (before) { - ++i; - pos += before.length; - args.push(before); - } - - var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy); - - args.push(wrapped); - - if (after) { - args.push(after); - } - - Array.prototype.splice.apply(strarr, args); - - if (delNum != 1) - _.matchGrammar(text, strarr, grammar, i, pos, true, token + ',' + j); - - if (oneshot) - break; - } - } - } - }, - - tokenize: function(text, grammar) { - var strarr = [text]; - - var rest = grammar.rest; - - if (rest) { - for (var token in rest) { - grammar[token] = rest[token]; - } - - delete grammar.rest; - } - - _.matchGrammar(text, strarr, grammar, 0, 0, false); - - return strarr; - }, - - hooks: { - all: {}, - - add: function (name, callback) { - var hooks = _.hooks.all; - - hooks[name] = hooks[name] || []; - - hooks[name].push(callback); - }, - - run: function (name, env) { - var callbacks = _.hooks.all[name]; - - if (!callbacks || !callbacks.length) { - return; - } - - for (var i=0, callback; callback = callbacks[i++];) { - callback(env); - } - } - }, - - Token: Token -}; - -_self.Prism = _; - -function Token(type, content, alias, matchedStr, greedy) { - this.type = type; - this.content = content; - this.alias = alias; - // Copy of the full string this token was created from - this.length = (matchedStr || '').length|0; - this.greedy = !!greedy; -} - -Token.stringify = function(o, language) { - if (typeof o == 'string') { - return o; - } - - if (Array.isArray(o)) { - return o.map(function(element) { - return Token.stringify(element, language); - }).join(''); - } - - var env = { - type: o.type, - content: Token.stringify(o.content, language), - tag: 'span', - classes: ['token', o.type], - attributes: {}, - language: language - }; - - if (o.alias) { - var aliases = Array.isArray(o.alias) ? o.alias : [o.alias]; - Array.prototype.push.apply(env.classes, aliases); - } - - _.hooks.run('wrap', env); - - var attributes = Object.keys(env.attributes).map(function(name) { - return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; - }).join(' '); - - return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + ''; -}; - -if (!_self.document) { - if (!_self.addEventListener) { - // in Node.js - return _; - } - - if (!_.disableWorkerMessageHandler) { - // In worker - _self.addEventListener('message', function (evt) { - var message = JSON.parse(evt.data), - lang = message.language, - code = message.code, - immediateClose = message.immediateClose; - - _self.postMessage(_.highlight(code, _.languages[lang], lang)); - if (immediateClose) { - _self.close(); - } - }, false); - } - - return _; -} - -//Get current script and highlight -var script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); - -if (script) { - _.filename = script.src; - - if (script.hasAttribute('data-manual')) { - _.manual = true; - } -} - -if (!_.manual) { - function highlightAutomaticallyCallback() { - if (!_.manual) { - _.highlightAll(); - } - } - - if(document.readyState !== 'loading') { - if (window.requestAnimationFrame) { - window.requestAnimationFrame(highlightAutomaticallyCallback); - } else { - window.setTimeout(highlightAutomaticallyCallback, 16); - } - } - else { - document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); - } -} - -return _; - -})(_self); - -if (typeof module !== 'undefined' && module.exports) { - module.exports = Prism; -} - -// hack for components to work correctly in node.js -if (typeof global !== 'undefined') { - global.Prism = Prism; -} -; diff --git a/src/extension.ts b/src/extension.ts index 812cc31b9..71a5fe591 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,24 +1,201 @@ -import { ExtensionContext } from "vscode"; -import { GodotTools } from "./godot-tools"; -import { shouldUpdateSettings, updateOldStyleSettings, updateStoredVersion } from "./settings_updater"; -import debuggerContext = require("./debugger/debugger_context"); +import * as fs from "fs"; +import * as path from "path"; +import * as vscode from "vscode"; +import { attemptSettingsUpdate } from "./settings_updater"; +import { register_debugger } from "./debugger/debugger_context"; +import { GDDocumentLinkProvider } from "./document_link_provider"; +import { ClientConnectionManager } from "./lsp/ClientConnectionManager"; +import { ScenePreviewProvider } from "./scene_preview_provider"; +import { + get_configuration, + set_configuration, + find_file, + find_project_file, + register_command +} from "./utils"; -let tools: GodotTools = null; +const TOOL_NAME = "GodotTools"; -export function activate(context: ExtensionContext) { - if (shouldUpdateSettings(context)) { - updateOldStyleSettings(); - } - updateStoredVersion(context); +let lspClientManager: ClientConnectionManager = null; +let linkProvider: GDDocumentLinkProvider = null; +let scenePreviewManager: ScenePreviewProvider = null; + +export function activate(context: vscode.ExtensionContext) { + attemptSettingsUpdate(context); + + lspClientManager = new ClientConnectionManager(context); + linkProvider = new GDDocumentLinkProvider(context); + scenePreviewManager = new ScenePreviewProvider(); + + register_debugger(context); - tools = new GodotTools(context); - tools.activate(); - debuggerContext.register_debugger(context); + context.subscriptions.push( + register_command("openEditor", () => { + open_workspace_with_editor("-e").catch(err => vscode.window.showErrorMessage(err)); + }), + register_command("runProject", () => { + open_workspace_with_editor().catch(err => vscode.window.showErrorMessage(err)); + }), + register_command("runProjectDebug", () => { + open_workspace_with_editor("--debug-collisions --debug-navigation").catch(err => vscode.window.showErrorMessage(err)); + }), + register_command("copyResourcePathContext", copy_resource_path), + register_command("copyResourcePath", copy_resource_path), + register_command("openTypeDocumentation", open_type_documentation), + register_command("switchSceneScript", switch_scene_script), + ) } export function deactivate(): Thenable { return new Promise((resolve, reject) => { - tools.deactivate(); + lspClientManager.client.stop(); resolve(); }); } + +function copy_resource_path(uri: vscode.Uri) { + if (!uri) { + uri = vscode.window.activeTextEditor.document.uri; + } + + const project_dir = path.dirname(find_project_file(uri.fsPath)); + if (project_dir === null) { + return; + } + + let relative_path = path.normalize(path.relative(project_dir, uri.fsPath)); + relative_path = relative_path.split(path.sep).join(path.posix.sep); + relative_path = "res://" + relative_path; + + vscode.env.clipboard.writeText(relative_path); +} + +function open_type_documentation() { + lspClientManager.client.open_documentation(); +} + +async function switch_scene_script() { + let path = vscode.window.activeTextEditor.document.uri.fsPath; + + if (path.endsWith(".tscn")) { + path = path.replace(".tscn", ".gd"); + } else if (path.endsWith(".gd")) { + path = path.replace(".gd", ".tscn"); + } + + const file = await find_file(path); + if (file) { + vscode.window.showTextDocument(file); + } +} + +function open_workspace_with_editor(params = "") { + return new Promise(async (resolve, reject) => { + let valid = false; + let project_dir = ''; + let project_file = ''; + + if (vscode.workspace.workspaceFolders != undefined) { + const files = await vscode.workspace.findFiles("**/project.godot"); + if (files) { + project_file = files[0].fsPath; + project_dir = path.dirname(project_file); + let cfg = project_file; + valid = (fs.existsSync(cfg) && fs.statSync(cfg).isFile()); + } + } + if (valid) { + run_editor(`--path "${project_dir}" ${params}`).then(() => resolve()).catch(err => { + reject(err); + }); + } else { + reject("Current workspace is not a Godot project"); + } + }); +} + +function run_editor(params = "") { + // TODO: rewrite this entire function + return new Promise((resolve, reject) => { + const run_godot = (path: string, params: string) => { + const is_powershell_path = (path?: string) => { + const POWERSHELL = "powershell.exe"; + const POWERSHELL_CORE = "pwsh.exe"; + return path && (path.endsWith(POWERSHELL) || path.endsWith(POWERSHELL_CORE)); + }; + const escape_command = (cmd: string) => { + const cmdEsc = `"${cmd}"`; + if (process.platform === "win32") { + const shell_plugin = vscode.workspace.getConfiguration("terminal.integrated.shell"); + + if (shell_plugin) { + const shell = shell_plugin.get("windows"); + if (shell) { + if (is_powershell_path(shell)) { + return `&${cmdEsc}`; + } else { + return cmdEsc; + } + } + } + + const POWERSHELL_SOURCE = "PowerShell"; + const default_profile = vscode.workspace.getConfiguration("terminal.integrated.defaultProfile"); + if (default_profile) { + const profile_name = default_profile.get("windows"); + if (profile_name) { + if (POWERSHELL_SOURCE === profile_name) { + return `&${cmdEsc}`; + } + const profiles = vscode.workspace.getConfiguration("terminal.integrated.profiles.windows"); + const profile = profiles.get<{ source?: string, path?: string }>(profile_name); + if (profile) { + if (POWERSHELL_SOURCE === profile.source || is_powershell_path(profile.path)) { + return `&${cmdEsc}`; + } else { + return cmdEsc; + } + } + } + } + // default for Windows if nothing is set is PowerShell + return `&${cmdEsc}`; + + } + return cmdEsc; + }; + let existingTerminal = vscode.window.terminals.find(t => t.name === TOOL_NAME); + if (existingTerminal) { + existingTerminal.dispose(); + } + let terminal = vscode.window.createTerminal(TOOL_NAME); + let editorPath = escape_command(path); + let cmmand = `${editorPath} ${params}`; + terminal.sendText(cmmand, true); + terminal.show(); + resolve(); + }; + + // TODO: This config doesn't exist anymore + let editorPath = get_configuration("editorPath"); + if (!fs.existsSync(editorPath) || !fs.statSync(editorPath).isFile()) { + vscode.window.showOpenDialog({ + openLabel: "Run", + filters: process.platform === "win32" ? { "Godot Editor Binary": ["exe", "EXE"] } : undefined + }).then((uris: vscode.Uri[]) => { + if (!uris) { + return; + } + let path = uris[0].fsPath; + if (!fs.existsSync(path) || !fs.statSync(path).isFile()) { + reject("Invalid editor path to run the project"); + } else { + run_godot(path, params); + set_configuration("editorPath", path); + } + }); + } else { + run_godot(editorPath, params); + } + }); +} diff --git a/src/godot-tools.ts b/src/godot-tools.ts deleted file mode 100644 index 8327c6b6d..000000000 --- a/src/godot-tools.ts +++ /dev/null @@ -1,213 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as vscode from "vscode"; -import { GDDocumentLinkProvider } from "./document_link_provider"; -import { ClientConnectionManager } from "./lsp/ClientConnectionManager"; -import { ScenePreviewProvider } from "./scene_preview_provider"; -import { - get_configuration, - set_configuration, - find_file, - find_project_file, - register_command -} from "./utils"; - -const TOOL_NAME = "GodotTools"; - -export class GodotTools { - private context: vscode.ExtensionContext; - - private lspClientManager: ClientConnectionManager = null; - private linkProvider: GDDocumentLinkProvider = null; - private scenePreviewManager: ScenePreviewProvider = null; - - constructor(p_context: vscode.ExtensionContext) { - this.context = p_context; - - this.lspClientManager = new ClientConnectionManager(p_context); - this.linkProvider = new GDDocumentLinkProvider(p_context); - } - - public activate() { - register_command("openEditor", () => { - this.open_workspace_with_editor("-e").catch(err => vscode.window.showErrorMessage(err)); - }); - register_command("runProject", () => { - this.open_workspace_with_editor().catch(err => vscode.window.showErrorMessage(err)); - }); - register_command("runProjectDebug", () => { - this.open_workspace_with_editor("--debug-collisions --debug-navigation").catch(err => vscode.window.showErrorMessage(err)); - }); - register_command("setSceneFile", this.set_scene_file.bind(this)); - register_command("copyResourcePathContext", this.copy_resource_path.bind(this)); - register_command("copyResourcePath", this.copy_resource_path.bind(this)); - register_command("openTypeDocumentation", this.open_type_documentation.bind(this)); - register_command("switchSceneScript", this.switch_scene_script.bind(this)); - - this.scenePreviewManager = new ScenePreviewProvider(); - } - - public deactivate() { - this.lspClientManager.client.stop(); - } - - private open_workspace_with_editor(params = "") { - return new Promise(async (resolve, reject) => { - let valid = false; - let project_dir = ''; - let project_file = ''; - - if (vscode.workspace.workspaceFolders != undefined) { - const files = await vscode.workspace.findFiles("**/project.godot"); - if (files) { - project_file = files[0].fsPath; - project_dir = path.dirname(project_file); - let cfg = project_file; - valid = (fs.existsSync(cfg) && fs.statSync(cfg).isFile()); - } - } - if (valid) { - this.run_editor(`--path "${project_dir}" ${params}`).then(() => resolve()).catch(err => { - reject(err); - }); - } else { - reject("Current workspace is not a Godot project"); - } - }); - } - - private copy_resource_path(uri: vscode.Uri) { - if (!uri) { - uri = vscode.window.activeTextEditor.document.uri; - } - - const project_dir = path.dirname(find_project_file(uri.fsPath)); - if (project_dir === null) { - return; - } - - let relative_path = path.normalize(path.relative(project_dir, uri.fsPath)); - relative_path = relative_path.split(path.sep).join(path.posix.sep); - relative_path = "res://" + relative_path; - - vscode.env.clipboard.writeText(relative_path); - } - - private open_type_documentation() { - this.lspClientManager.client.open_documentation(); - } - - private async switch_scene_script() { - let path = vscode.window.activeTextEditor.document.uri.fsPath; - - if (path.endsWith(".tscn")) { - path = path.replace(".tscn", ".gd"); - } else if (path.endsWith(".gd")) { - path = path.replace(".gd", ".tscn"); - } - - const file = await find_file(path); - if (file) { - vscode.window.showTextDocument(file); - } - } - - private set_scene_file(uri: vscode.Uri) { - let right_clicked_scene_path = uri.fsPath; - let scene_config = get_configuration("sceneFileConfig"); - if (scene_config == right_clicked_scene_path) { - scene_config = ""; - } - else { - scene_config = right_clicked_scene_path; - } - - set_configuration("sceneFileConfig", scene_config); - } - - private run_editor(params = "") { - // TODO: rewrite this entire function - return new Promise((resolve, reject) => { - const run_godot = (path: string, params: string) => { - const is_powershell_path = (path?: string) => { - const POWERSHELL = "powershell.exe"; - const POWERSHELL_CORE = "pwsh.exe"; - return path && (path.endsWith(POWERSHELL) || path.endsWith(POWERSHELL_CORE)); - }; - const escape_command = (cmd: string) => { - const cmdEsc = `"${cmd}"`; - if (process.platform === "win32") { - const shell_plugin = vscode.workspace.getConfiguration("terminal.integrated.shell"); - - if (shell_plugin) { - const shell = shell_plugin.get("windows"); - if (shell) { - if (is_powershell_path(shell)) { - return `&${cmdEsc}`; - } else { - return cmdEsc; - } - } - } - - const POWERSHELL_SOURCE = "PowerShell"; - const default_profile = vscode.workspace.getConfiguration("terminal.integrated.defaultProfile"); - if (default_profile) { - const profile_name = default_profile.get("windows"); - if (profile_name) { - if (POWERSHELL_SOURCE === profile_name) { - return `&${cmdEsc}`; - } - const profiles = vscode.workspace.getConfiguration("terminal.integrated.profiles.windows"); - const profile = profiles.get<{ source?: string, path?: string }>(profile_name); - if (profile) { - if (POWERSHELL_SOURCE === profile.source || is_powershell_path(profile.path)) { - return `&${cmdEsc}`; - } else { - return cmdEsc; - } - } - } - } - // default for Windows if nothing is set is PowerShell - return `&${cmdEsc}`; - - } - return cmdEsc; - }; - let existingTerminal = vscode.window.terminals.find(t => t.name === TOOL_NAME); - if (existingTerminal) { - existingTerminal.dispose(); - } - let terminal = vscode.window.createTerminal(TOOL_NAME); - let editorPath = escape_command(path); - let cmmand = `${editorPath} ${params}`; - terminal.sendText(cmmand, true); - terminal.show(); - resolve(); - }; - - // TODO: This config doesn't exist anymore - let editorPath = get_configuration("editorPath"); - if (!fs.existsSync(editorPath) || !fs.statSync(editorPath).isFile()) { - vscode.window.showOpenDialog({ - openLabel: "Run", - filters: process.platform === "win32" ? { "Godot Editor Binary": ["exe", "EXE"] } : undefined - }).then((uris: vscode.Uri[]) => { - if (!uris) { - return; - } - let path = uris[0].fsPath; - if (!fs.existsSync(path) || !fs.statSync(path).isFile()) { - reject("Invalid editor path to run the project"); - } else { - run_godot(path, params); - set_configuration("editorPath", path); - } - }); - } else { - run_godot(editorPath, params); - } - }); - } -} diff --git a/src/lsp/NativeDocumentManager.ts b/src/lsp/NativeDocumentManager.ts index 9394783f0..dfd12f6f6 100644 --- a/src/lsp/NativeDocumentManager.ts +++ b/src/lsp/NativeDocumentManager.ts @@ -3,7 +3,7 @@ import * as ls from "vscode-languageclient"; import { EventEmitter } from "events"; import { MessageIO } from "./MessageIO"; import { NotificationMessage } from "vscode-jsonrpc"; -import * as Prism from "../deps/prism/prism"; +import * as Prism from "prismjs"; import * as marked from "marked"; import { get_configuration, register_command } from "../utils"; import { diff --git a/src/settings_updater.ts b/src/settings_updater.ts index 54713af32..db0c63492 100644 --- a/src/settings_updater.ts +++ b/src/settings_updater.ts @@ -11,7 +11,7 @@ const OLD_SETTINGS_CONVERSIONS = [ ["godot_tools.reconnect_attempts", "godotTools.lsp.autoReconnect.attempts"], ["godot_tools.force_visible_collision_shapes", "godotTools.forceVisibleCollisionShapes"], ["godot_tools.force_visible_nav_mesh", "godotTools.forceVisibleNavMesh"], - ["godot_tools.native_symbol_placement", "godotTooPtabls.nativeSymbolPlacement"], + ["godot_tools.native_symbol_placement", "godotTools.nativeSymbolPlacement"], ["godot_tools.scenePreview.previewRelatedScenes", "godotTools.scenePreview.previewRelatedScenes"] ]; @@ -55,7 +55,14 @@ export function updateStoredVersion(context: vscode.ExtensionContext) { * in `context.globalState`, meaning it was either just installed, * or updated from a version <1.4.0. Otherwise, returns `false`. */ -export function shouldUpdateSettings(context: vscode.ExtensionContext) : boolean { +export function shouldUpdateSettings(context: vscode.ExtensionContext): boolean { const localVersion: string | undefined = context.globalState.get("previousVersion"); return localVersion === undefined; } + +export function attemptSettingsUpdate(context: vscode.ExtensionContext) { + if (shouldUpdateSettings(context)) { + updateOldStyleSettings(); + } + updateStoredVersion(context); +}