guess.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. const path = require('path')
  2. const shellQuote = require('shell-quote')
  3. const childProcess = require('child_process')
  4. // Map from full process name to binary that starts the process
  5. // We can't just re-use full process name, because it will spawn a new instance
  6. // of the app every time
  7. const COMMON_EDITORS_OSX = require('./editor-info/osx')
  8. const COMMON_EDITORS_LINUX = require('./editor-info/linux')
  9. const COMMON_EDITORS_WIN = require('./editor-info/windows')
  10. module.exports = function guessEditor (specifiedEditor) {
  11. if (specifiedEditor) {
  12. return shellQuote.parse(specifiedEditor)
  13. }
  14. // We can find out which editor is currently running by:
  15. // `ps x` on macOS and Linux
  16. // `Get-Process` on Windows
  17. try {
  18. if (process.platform === 'darwin') {
  19. const output = childProcess.execSync('ps x').toString()
  20. const processNames = Object.keys(COMMON_EDITORS_OSX)
  21. for (let i = 0; i < processNames.length; i++) {
  22. const processName = processNames[i]
  23. if (output.indexOf(processName) !== -1) {
  24. return [COMMON_EDITORS_OSX[processName]]
  25. }
  26. }
  27. } else if (process.platform === 'win32') {
  28. const output = childProcess
  29. .execSync('powershell -Command "Get-Process | Select-Object Path"', {
  30. stdio: ['pipe', 'pipe', 'ignore']
  31. })
  32. .toString()
  33. const runningProcesses = output.split('\r\n')
  34. for (let i = 0; i < runningProcesses.length; i++) {
  35. // `Get-Process` sometimes returns empty lines
  36. if (!runningProcesses[i]) {
  37. continue
  38. }
  39. const fullProcessPath = runningProcesses[i].trim()
  40. const shortProcessName = path.basename(fullProcessPath)
  41. if (COMMON_EDITORS_WIN.indexOf(shortProcessName) !== -1) {
  42. return [fullProcessPath]
  43. }
  44. }
  45. } else if (process.platform === 'linux') {
  46. // --no-heading No header line
  47. // x List all processes owned by you
  48. // -o comm Need only names column
  49. const output = childProcess
  50. .execSync('ps x --no-heading -o comm --sort=comm')
  51. .toString()
  52. const processNames = Object.keys(COMMON_EDITORS_LINUX)
  53. for (let i = 0; i < processNames.length; i++) {
  54. const processName = processNames[i]
  55. if (output.indexOf(processName) !== -1) {
  56. return [COMMON_EDITORS_LINUX[processName]]
  57. }
  58. }
  59. }
  60. } catch (error) {
  61. // Ignore...
  62. }
  63. // Last resort, use old skool env vars
  64. if (process.env.VISUAL) {
  65. return [process.env.VISUAL]
  66. } else if (process.env.EDITOR) {
  67. return [process.env.EDITOR]
  68. }
  69. return [null]
  70. }