From d35a4aa35d36cd5072f7cccbe2cb1595bcbe9e70 Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 27 Jun 2017 17:16:02 +0200 Subject: [PATCH] Auto-detect running editor on Windows for error overlay (#2552) * Auto-detect running editor on Windows for error overlay * Ignore process output if powershell call fails * Support Notepad++ --- packages/react-dev-utils/launchEditor.js | 73 +++++++++++++++++------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/packages/react-dev-utils/launchEditor.js b/packages/react-dev-utils/launchEditor.js index 0cc170fb615..5622c1c1248 100644 --- a/packages/react-dev-utils/launchEditor.js +++ b/packages/react-dev-utils/launchEditor.js @@ -8,12 +8,12 @@ */ 'use strict'; -var fs = require('fs'); -var path = require('path'); -var child_process = require('child_process'); -var os = require('os'); -var chalk = require('chalk'); -var shellQuote = require('shell-quote'); +const fs = require('fs'); +const path = require('path'); +const child_process = require('child_process'); +const os = require('os'); +const chalk = require('chalk'); +const shellQuote = require('shell-quote'); function isTerminalEditor(editor) { switch (editor) { @@ -28,7 +28,7 @@ function isTerminalEditor(editor) { // Map from full process name to binary that starts the process // We can't just re-use full process name, because it will spawn a new instance // of the app every time -var COMMON_EDITORS = { +const COMMON_EDITORS_OSX = { '/Applications/Atom.app/Contents/MacOS/Atom': 'atom', '/Applications/Atom Beta.app/Contents/MacOS/Atom Beta': '/Applications/Atom Beta.app/Contents/MacOS/Atom Beta', '/Applications/Sublime Text.app/Contents/MacOS/Sublime Text': '/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl', @@ -36,6 +36,13 @@ var COMMON_EDITORS = { '/Applications/Visual Studio Code.app/Contents/MacOS/Electron': 'code', }; +const COMMON_EDITORS_WIN = [ + 'Code.exe', + 'atom.exe', + 'sublime_text.exe', + 'notepad++.exe', +]; + function addWorkspaceToArgumentsIfExists(args, workspace) { if (workspace) { args.unshift(workspace); @@ -44,7 +51,7 @@ function addWorkspaceToArgumentsIfExists(args, workspace) { } function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) { - var editorBasename = path.basename(editor).replace(/\.(exe|cmd|bat)$/i, ''); + const editorBasename = path.basename(editor).replace(/\.(exe|cmd|bat)$/i, ''); switch (editorBasename) { case 'vim': case 'mvim': @@ -54,11 +61,14 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) { case 'Atom Beta': case 'subl': case 'sublime': + case 'sublime_text': case 'wstorm': case 'appcode': case 'charm': case 'idea': return [fileName + ':' + lineNumber]; + case 'notepad++': + return ['-n' + lineNumber, fileName]; case 'joe': case 'emacs': case 'emacsclient': @@ -68,6 +78,7 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) { case 'mine': return ['--line', lineNumber, fileName]; case 'code': + case 'Code': return addWorkspaceToArgumentsIfExists( ['-g', fileName + ':' + lineNumber], workspace @@ -94,21 +105,41 @@ function guessEditor() { return shellQuote.parse(process.env.REACT_EDITOR); } - // Using `ps x` on OSX we can find out which editor is currently running. - // Potentially we could use similar technique for Windows and Linux - if (process.platform === 'darwin') { - try { - var output = child_process.execSync('ps x').toString(); - var processNames = Object.keys(COMMON_EDITORS); - for (var i = 0; i < processNames.length; i++) { - var processName = processNames[i]; + // Using `ps x` on OSX or `Get-Process` on Windows we can find out which editor is currently running. + // Potentially we could use similar technique for Linux + try { + if (process.platform === 'darwin') { + const output = child_process.execSync('ps x').toString(); + const processNames = Object.keys(COMMON_EDITORS_OSX); + for (let i = 0; i < processNames.length; i++) { + const processName = processNames[i]; if (output.indexOf(processName) !== -1) { - return [COMMON_EDITORS[processName]]; + return [COMMON_EDITORS_OSX[processName]]; + } + } + } else if (process.platform === 'win32') { + const output = child_process + .execSync('powershell -Command "Get-Process | Select-Object Path"', { + stdio: ['pipe', 'pipe', 'ignore'], + }) + .toString(); + const runningProcesses = output.split('\r\n'); + for (let i = 0; i < runningProcesses.length; i++) { + // `Get-Process` sometimes returns empty lines + if (!runningProcesses[i]) { + continue; + } + + const fullProcessPath = runningProcesses[i].trim(); + const shortProcessName = path.basename(fullProcessPath); + + if (COMMON_EDITORS_WIN.indexOf(shortProcessName) !== -1) { + return [fullProcessPath]; } } - } catch (error) { - // Ignore... } + } catch (error) { + // Ignore... } // Last resort, use old skool env vars @@ -146,7 +177,7 @@ function printInstructions(fileName, errorMessage) { console.log(); } -var _childProcess = null; +let _childProcess = null; function launchEditor(fileName, lineNumber) { if (!fs.existsSync(fileName)) { return; @@ -178,7 +209,7 @@ function launchEditor(fileName, lineNumber) { fileName = path.relative('', fileName); } - var workspace = null; + let workspace = null; if (lineNumber) { args = args.concat( getArgumentsForLineNumber(editor, fileName, lineNumber, workspace)