mirror of
https://github.com/godotengine/godot-vscode-plugin.git
synced 2025-12-31 13:48:24 +03:00
Reorganize extension entrypoint (#505)
* Combine godot-tools.ts into extension.ts to put the extension's major components at the same level
This commit is contained in:
14
package-lock.json
generated
14
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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(/</g, '<').replace(/\u00a0/g, ' ');
|
||||
}
|
||||
},
|
||||
|
||||
type: function (o) {
|
||||
return Object.prototype.toString.call(o).slice(8, -1);
|
||||
},
|
||||
|
||||
objId: function (obj) {
|
||||
if (!obj['__id']) {
|
||||
Object.defineProperty(obj, '__id', { value: ++uniqueId });
|
||||
}
|
||||
return obj['__id'];
|
||||
},
|
||||
|
||||
// Deep clone a language definition (e.g. to extend it)
|
||||
clone: function deepClone(o, visited) {
|
||||
var clone, id, type = _.util.type(o);
|
||||
visited = visited || {};
|
||||
|
||||
switch (type) {
|
||||
case 'Object':
|
||||
id = _.util.objId(o);
|
||||
if (visited[id]) {
|
||||
return visited[id];
|
||||
}
|
||||
clone = {};
|
||||
visited[id] = clone;
|
||||
|
||||
for (var key in o) {
|
||||
if (o.hasOwnProperty(key)) {
|
||||
clone[key] = deepClone(o[key], visited);
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
|
||||
case 'Array':
|
||||
id = _.util.objId(o);
|
||||
if (visited[id]) {
|
||||
return visited[id];
|
||||
}
|
||||
clone = [];
|
||||
visited[id] = clone;
|
||||
|
||||
o.forEach(function (v, i) {
|
||||
clone[i] = deepClone(v, visited);
|
||||
});
|
||||
|
||||
return clone;
|
||||
|
||||
default:
|
||||
return o;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
languages: {
|
||||
extend: function (id, redef) {
|
||||
var lang = _.util.clone(_.languages[id]);
|
||||
|
||||
for (var key in redef) {
|
||||
lang[key] = redef[key];
|
||||
}
|
||||
|
||||
return lang;
|
||||
},
|
||||
|
||||
/**
|
||||
* Insert a token before another token in a language literal
|
||||
* As this needs to recreate the object (we cannot actually insert before keys in object literals),
|
||||
* we cannot just provide an object, we need an object and a key.
|
||||
* @param inside The key (or language id) of the parent
|
||||
* @param before The key to insert before.
|
||||
* @param insert Object with the key/value pairs to insert
|
||||
* @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
|
||||
*/
|
||||
insertBefore: function (inside, before, insert, root) {
|
||||
root = root || _.languages;
|
||||
var grammar = root[inside];
|
||||
var ret = {};
|
||||
|
||||
for (var token in grammar) {
|
||||
if (grammar.hasOwnProperty(token)) {
|
||||
|
||||
if (token == before) {
|
||||
for (var newToken in insert) {
|
||||
if (insert.hasOwnProperty(newToken)) {
|
||||
ret[newToken] = insert[newToken];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do not insert token which also occur in insert. See #1525
|
||||
if (!insert.hasOwnProperty(token)) {
|
||||
ret[token] = grammar[token];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var old = root[inside];
|
||||
root[inside] = ret;
|
||||
|
||||
// Update references in other language definitions
|
||||
_.languages.DFS(_.languages, function(key, value) {
|
||||
if (value === old && key != inside) {
|
||||
this[key] = ret;
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
// Traverse a language definition with Depth First Search
|
||||
DFS: function DFS(o, callback, type, visited) {
|
||||
visited = visited || {};
|
||||
|
||||
var objId = _.util.objId;
|
||||
|
||||
for (var i in o) {
|
||||
if (o.hasOwnProperty(i)) {
|
||||
callback.call(o, i, o[i], type || i);
|
||||
|
||||
var property = o[i],
|
||||
propertyType = _.util.type(property);
|
||||
|
||||
if (propertyType === 'Object' && !visited[objId(property)]) {
|
||||
visited[objId(property)] = true;
|
||||
DFS(property, callback, null, visited);
|
||||
}
|
||||
else if (propertyType === 'Array' && !visited[objId(property)]) {
|
||||
visited[objId(property)] = true;
|
||||
DFS(property, callback, i, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {},
|
||||
|
||||
highlightAll: function(async, callback) {
|
||||
_.highlightAllUnder(document, async, callback);
|
||||
},
|
||||
|
||||
highlightAllUnder: function(container, async, callback) {
|
||||
var env = {
|
||||
callback: callback,
|
||||
selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
|
||||
};
|
||||
|
||||
_.hooks.run('before-highlightall', env);
|
||||
|
||||
var elements = container.querySelectorAll(env.selector);
|
||||
|
||||
for (var i=0, element; element = elements[i++];) {
|
||||
_.highlightElement(element, async === true, env.callback);
|
||||
}
|
||||
},
|
||||
|
||||
highlightElement: function(element, async, callback) {
|
||||
// Find language
|
||||
var language = getLanguage(element);
|
||||
var grammar = _.languages[language];
|
||||
|
||||
// Set language on the element, if not present
|
||||
element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
|
||||
|
||||
// Set language on the parent, for styling
|
||||
var parent = element.parentNode;
|
||||
if (parent && parent.nodeName.toLowerCase() === 'pre') {
|
||||
parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
|
||||
}
|
||||
|
||||
var code = element.textContent;
|
||||
|
||||
var env = {
|
||||
element: element,
|
||||
language: language,
|
||||
grammar: grammar,
|
||||
code: code
|
||||
};
|
||||
|
||||
function insertHighlightedCode(highlightedCode) {
|
||||
env.highlightedCode = highlightedCode;
|
||||
|
||||
_.hooks.run('before-insert', env);
|
||||
|
||||
env.element.innerHTML = env.highlightedCode;
|
||||
|
||||
_.hooks.run('after-highlight', env);
|
||||
_.hooks.run('complete', env);
|
||||
callback && callback.call(env.element);
|
||||
}
|
||||
|
||||
_.hooks.run('before-sanity-check', env);
|
||||
|
||||
if (!env.code) {
|
||||
_.hooks.run('complete', env);
|
||||
callback && callback.call(env.element);
|
||||
return;
|
||||
}
|
||||
|
||||
_.hooks.run('before-highlight', env);
|
||||
|
||||
if (!env.grammar) {
|
||||
insertHighlightedCode(_.util.encode(env.code));
|
||||
return;
|
||||
}
|
||||
|
||||
if (async && _self.Worker) {
|
||||
var worker = new Worker(_.filename);
|
||||
|
||||
worker.onmessage = function(evt) {
|
||||
insertHighlightedCode(evt.data);
|
||||
};
|
||||
|
||||
worker.postMessage(JSON.stringify({
|
||||
language: env.language,
|
||||
code: env.code,
|
||||
immediateClose: true
|
||||
}));
|
||||
}
|
||||
else {
|
||||
insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
|
||||
}
|
||||
},
|
||||
|
||||
highlight: function (text, grammar, language) {
|
||||
var env = {
|
||||
code: text,
|
||||
grammar: grammar,
|
||||
language: language
|
||||
};
|
||||
_.hooks.run('before-tokenize', env);
|
||||
env.tokens = _.tokenize(env.code, env.grammar);
|
||||
_.hooks.run('after-tokenize', env);
|
||||
return Token.stringify(_.util.encode(env.tokens), env.language);
|
||||
},
|
||||
|
||||
matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
|
||||
for (var token in grammar) {
|
||||
if (!grammar.hasOwnProperty(token) || !grammar[token]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var patterns = grammar[token];
|
||||
patterns = Array.isArray(patterns) ? patterns : [patterns];
|
||||
|
||||
for (var j = 0; j < patterns.length; ++j) {
|
||||
if (target && target == token + ',' + j) {
|
||||
return;
|
||||
}
|
||||
|
||||
var pattern = patterns[j],
|
||||
inside = pattern.inside,
|
||||
lookbehind = !!pattern.lookbehind,
|
||||
greedy = !!pattern.greedy,
|
||||
lookbehindLength = 0,
|
||||
alias = pattern.alias;
|
||||
|
||||
if (greedy && !pattern.pattern.global) {
|
||||
// Without the global flag, lastIndex won't work
|
||||
var flags = pattern.pattern.toString().match(/[imsuy]*$/)[0];
|
||||
pattern.pattern = RegExp(pattern.pattern.source, flags + 'g');
|
||||
}
|
||||
|
||||
pattern = pattern.pattern || pattern;
|
||||
|
||||
// Don’t cache length as it changes during the loop
|
||||
for (var i = index, pos = startPos; i < strarr.length; pos += strarr[i].length, ++i) {
|
||||
|
||||
var str = strarr[i];
|
||||
|
||||
if (strarr.length > 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 + '</' + env.tag + '>';
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
;
|
||||
205
src/extension.ts
205
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;
|
||||
|
||||
tools = new GodotTools(context);
|
||||
tools.activate();
|
||||
debuggerContext.register_debugger(context);
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
attemptSettingsUpdate(context);
|
||||
|
||||
lspClientManager = new ClientConnectionManager(context);
|
||||
linkProvider = new GDDocumentLinkProvider(context);
|
||||
scenePreviewManager = new ScenePreviewProvider();
|
||||
|
||||
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<void> {
|
||||
return new Promise<void>((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<void>(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<void>((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<string>("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<string>("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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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<void>(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<void>((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<string>("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<string>("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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user