diff --git a/gulpfile.js/index.js b/gulpfile.js/index.js index 3cf6f3427e..961ea91419 100644 --- a/gulpfile.js/index.js +++ b/gulpfile.js/index.js @@ -533,8 +533,8 @@ function _computeCacheManifest(baseDir, filePaths) { totalSize = Math.round(totalSize/1024); // KB console.log("Total size of cache in KB: ", totalSize); - if(totalSize > 75000){ - throw new Error("The total size of the src or dist folder core assets exceeds 75MB." + + if(totalSize > 78000){ + throw new Error("The total size of the src or dist folder core assets exceeds 78MB." + "\nPlease review and trim storage. This significantly impacts the distribution size." + "\nEither trim down the size or increase the limit after careful review."); } @@ -909,7 +909,8 @@ function _renameExtensionConcatAsExtensionJSInDist(extensionName) { } const minifyableExtensions = ["CloseOthers", "CodeFolding", "DebugCommands", "Git", - "HealthData", "JavaScriptCodeHints", "JavaScriptRefactoring", "QuickView", "TypeScriptSupport"]; + "HealthData", "JavaScriptCodeHints", "JavaScriptRefactoring", "PHPSupport", "QuickView", + "TypeScriptSupport"]; // extensions that nned not be minified either coz they are single file extensions or some other reason. const nonMinifyExtensions = ["CSSAtRuleCodeHints", "CSSCodeHints", "CSSPseudoSelectorHints", "DarkTheme", "DocCommentHints", "HandlebarsSupport", "HTMLCodeHints", diff --git a/src-node/lsp-client.js b/src-node/lsp-client.js index 423167df03..0bbfd0bdce 100644 --- a/src-node/lsp-client.js +++ b/src-node/lsp-client.js @@ -218,15 +218,27 @@ exports.startServer = async function startServer(params) { return { success: true, message: "already running", serverId }; } - // Prefer a server bundled in node_modules/.bin, otherwise fall back to PATH. + // Command resolution, in order: + // 1. An absolute path to a .js entry (e.g. a user-installed server like intelephense living + // outside src-node) runs on our own node runtime - process.execPath is phnode itself, the + // same spawn-self pattern _npmInstallInFolder and the ESLint service use. This sidesteps + // node_modules/.bin shims entirely (they are sh scripts / .cmd on Windows). + // 2. A server bundled in src-node/node_modules/.bin. + // 3. Fall back to PATH. let commandPath = command; - const localBinPath = path.join(NODE_MODULES_BIN, command); - if (fs.existsSync(localBinPath)) { - commandPath = localBinPath; + let spawnArgs = args; + if (path.isAbsolute(command) && command.endsWith('.js')) { + spawnArgs = [command, ...args]; + commandPath = process.execPath; + } else { + const localBinPath = path.join(NODE_MODULES_BIN, command); + if (fs.existsSync(localBinPath)) { + commandPath = localBinPath; + } } return new Promise((resolve, reject) => { - const serverProcess = spawn(commandPath, args, { stdio: ['pipe', 'pipe', 'pipe'] }); + const serverProcess = spawn(commandPath, spawnArgs, { stdio: ['pipe', 'pipe', 'pipe'] }); const parser = createParser(serverId); const serverState = { diff --git a/src/extensions/default/DefaultExtensions.json b/src/extensions/default/DefaultExtensions.json index 7076ad7306..68032c2994 100644 --- a/src/extensions/default/DefaultExtensions.json +++ b/src/extensions/default/DefaultExtensions.json @@ -28,7 +28,8 @@ ], "desktopOnly": [ "Git", - "TypeScriptSupport" + "TypeScriptSupport", + "PHPSupport" ], "warnExtensionStoreExtensions": { "description": "list extension ids here that you want to show this warning in extension store: 'You may not need this extension. Phoenix comes built in with this feature.'", diff --git a/src/extensions/default/HTMLCodeHints/html-lint.js b/src/extensions/default/HTMLCodeHints/html-lint.js index f858fe57f6..5e22436504 100644 --- a/src/extensions/default/HTMLCodeHints/html-lint.js +++ b/src/extensions/default/HTMLCodeHints/html-lint.js @@ -80,12 +80,25 @@ define(function (require, exports, module) { * Run JSLint on the current document. Reports results to the main UI. Displays * a gold star when no errors are found. */ + // html-validate cannot tokenize php blocks ("failed to tokenize , = ... ?> and an unterminated ... at EOF (pure-php files lint clean). + function _blankPhpRegions(text) { + return text.replace(/<\?(?:php|=)?[\s\S]*?(?:\?>|$)/g, function (block) { + return block.replace(/[^\n]/g, " "); + }); + } + async function lintOneFile(text, fullPath) { return new Promise((resolve, reject)=>{ if(configErrorMessage){ resolve({ errors: _getLinterConfigFileErrorMsg() }); return; } + if(/\.(php\d?|phtml?|phps|ctp)$/i.test(fullPath)) { + text = _blankPhpRegions(text); + } IndexingWorker.execPeer("htmlLint", { text, filePath: fullPath, diff --git a/src/extensions/default/HTMLCodeHints/main.js b/src/extensions/default/HTMLCodeHints/main.js index ccbee8c02a..ef2c8fec36 100644 --- a/src/extensions/default/HTMLCodeHints/main.js +++ b/src/extensions/default/HTMLCodeHints/main.js @@ -93,6 +93,14 @@ define(function (require, exports, module) { if (enabled) { this.editor = editor; + // php files are mixed-mode: their HTML regions report "html" at the cursor and are + // served through the html registration. So a cursor whose language is actually "php" + // is inside real PHP code (), where markup abbreviations are never right - + // typing `addition(` there must not summon an Emmet hint. + if (editor.getLanguageForSelection().getId() === "php") { + return false; + } + // check the context before showing emmet hints, because we don't want to show // emmet hints when its a Attribute name or value // cause for those cases AttrHints should handle it diff --git a/src/extensions/default/HTMLCodeHints/unittests.js b/src/extensions/default/HTMLCodeHints/unittests.js index 84d870dccd..73f4afbb06 100644 --- a/src/extensions/default/HTMLCodeHints/unittests.js +++ b/src/extensions/default/HTMLCodeHints/unittests.js @@ -695,6 +695,35 @@ define(function (require, exports, module) { describe("Emmet hint provider", function () { + it("should not offer emmet inside php code regions, only in html regions of php files", function () { + // php is a mixed mode: regions are real PHP (emmet is never right + // there - e.g. typing `addition(`), while the surrounding markup is HTML where + // emmet must keep working. + const phpContent = "\n" + + "