|
| 1 | +/** |
| 2 | + * Default local terminal bookmarks seeded on a brand new install. |
| 3 | + * |
| 4 | + * Only shells that are actually present on this machine are included, and |
| 5 | + * each one carries the exec field of the running platform (execWindows on |
| 6 | + * Windows, execMac on macOS, execLinux elsewhere), see app/server/session-local.js. |
| 7 | + * |
| 8 | + * The builders below are pure and take already resolved exec paths, so the |
| 9 | + * Windows branch stays testable from macOS/Linux CI. |
| 10 | + */ |
| 11 | + |
| 12 | +import path from 'path' |
| 13 | +import { |
| 14 | + isWin, |
| 15 | + isMac, |
| 16 | + resolveExec, |
| 17 | + resolveWinDirExec, |
| 18 | + firstExisting |
| 19 | +} from './detect-shells.js' |
| 20 | + |
| 21 | +// POSIX shells worth a one click local terminal, platform default first |
| 22 | +const posixShells = isMac |
| 23 | + ? ['zsh', 'bash', 'fish'] |
| 24 | + : ['bash', 'zsh', 'fish'] |
| 25 | + |
| 26 | +const colors = { |
| 27 | + bash: '#4EAA25', |
| 28 | + zsh: '#2E86DE', |
| 29 | + fish: '#8E44AD', |
| 30 | + 'cmd.exe': '#607D8B', |
| 31 | + PowerShell: '#2E5C8A', |
| 32 | + 'PowerShell 7': '#3B78C3', |
| 33 | + WSL: '#E95420', |
| 34 | + 'Git Bash': '#F05033' |
| 35 | +} |
| 36 | + |
| 37 | +const fallbackColor = '#0088cc' |
| 38 | + |
| 39 | +/** |
| 40 | + * @param {object} conf |
| 41 | + * @param {string} conf.id stable bookmark id |
| 42 | + * @param {string} conf.title bookmark title |
| 43 | + * @param {string} conf.execProp execWindows / execMac / execLinux |
| 44 | + * @param {string} conf.execArgsProp matching args field |
| 45 | + * @param {string} conf.exec resolved shell |
| 46 | + * @param {string} conf.description bookmark description |
| 47 | + */ |
| 48 | +function build ({ id, title, execProp, execArgsProp, exec, description }) { |
| 49 | + return { |
| 50 | + _id: id, |
| 51 | + title, |
| 52 | + type: 'local', |
| 53 | + description, |
| 54 | + color: colors[title] || fallbackColor, |
| 55 | + [execProp]: exec, |
| 56 | + [execArgsProp]: [] |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +function findPowerShell7 () { |
| 61 | + const inPath = resolveExec('pwsh') |
| 62 | + if (inPath) { |
| 63 | + return inPath |
| 64 | + } |
| 65 | + const programFiles = process.env.ProgramFiles || 'C:\\Program Files' |
| 66 | + const programFiles86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)' |
| 67 | + return firstExisting([ |
| 68 | + path.join(programFiles, 'PowerShell', '7', 'pwsh.exe'), |
| 69 | + path.join(programFiles86, 'PowerShell', '7', 'pwsh.exe') |
| 70 | + ]) |
| 71 | +} |
| 72 | + |
| 73 | +function findGitBash () { |
| 74 | + const programFiles = process.env.ProgramFiles || 'C:\\Program Files' |
| 75 | + const programFiles86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)' |
| 76 | + const localAppData = process.env.LOCALAPPDATA || '' |
| 77 | + const found = firstExisting([ |
| 78 | + path.join(programFiles, 'Git', 'bin', 'bash.exe'), |
| 79 | + path.join(programFiles86, 'Git', 'bin', 'bash.exe'), |
| 80 | + localAppData && path.join(localAppData, 'Programs', 'Git', 'bin', 'bash.exe') |
| 81 | + ]) |
| 82 | + return found || resolveExec('bash') |
| 83 | +} |
| 84 | + |
| 85 | +/** |
| 86 | + * @param {object} execs resolved Windows exec values, '' when missing |
| 87 | + * @param {string} execs.cmd cmd.exe |
| 88 | + * @param {string} execs.powershell Windows PowerShell |
| 89 | + * @param {string} execs.pwsh PowerShell 7 |
| 90 | + * @param {string} execs.wsl wsl.exe |
| 91 | + * @param {string} execs.gitBash Git Bash |
| 92 | + */ |
| 93 | +function buildWindowsBookmarks (execs) { |
| 94 | + const candidates = [ |
| 95 | + { |
| 96 | + id: 'default-local-cmd', |
| 97 | + title: 'cmd.exe', |
| 98 | + exec: execs.cmd, |
| 99 | + description: 'Local terminal running the Windows command prompt' |
| 100 | + }, |
| 101 | + { |
| 102 | + id: 'default-local-powershell', |
| 103 | + title: 'PowerShell', |
| 104 | + exec: execs.powershell, |
| 105 | + description: 'Local terminal running Windows PowerShell' |
| 106 | + }, |
| 107 | + { |
| 108 | + id: 'default-local-pwsh', |
| 109 | + title: 'PowerShell 7', |
| 110 | + exec: execs.pwsh, |
| 111 | + description: 'Local terminal running PowerShell 7 (pwsh.exe)' |
| 112 | + }, |
| 113 | + { |
| 114 | + id: 'default-local-wsl', |
| 115 | + title: 'WSL', |
| 116 | + exec: execs.wsl, |
| 117 | + // wsl.exe is the only entry point: WSL2 is selected per distro, there |
| 118 | + // is no separate wsl2.exe binary |
| 119 | + description: 'Local terminal running the default WSL distribution (wsl.exe, add -d <distro> to pick one)' |
| 120 | + }, |
| 121 | + { |
| 122 | + id: 'default-local-git-bash', |
| 123 | + title: 'Git Bash', |
| 124 | + exec: execs.gitBash, |
| 125 | + description: 'Local terminal running Git Bash' |
| 126 | + } |
| 127 | + ] |
| 128 | + return candidates |
| 129 | + .filter(d => d.exec) |
| 130 | + .map(d => build({ |
| 131 | + id: d.id, |
| 132 | + title: d.title, |
| 133 | + execProp: 'execWindows', |
| 134 | + execArgsProp: 'execWindowsArgs', |
| 135 | + exec: d.exec, |
| 136 | + description: d.description |
| 137 | + })) |
| 138 | +} |
| 139 | + |
| 140 | +function getWindowsBookmarks () { |
| 141 | + return buildWindowsBookmarks({ |
| 142 | + cmd: resolveWinDirExec('System32/cmd.exe'), |
| 143 | + powershell: resolveWinDirExec('System32/WindowsPowerShell/v1.0/powershell.exe'), |
| 144 | + pwsh: findPowerShell7(), |
| 145 | + wsl: resolveWinDirExec('System32/wsl.exe'), |
| 146 | + gitBash: findGitBash() |
| 147 | + }) |
| 148 | +} |
| 149 | + |
| 150 | +/** |
| 151 | + * @param {string} shell bare shell name |
| 152 | + * @param {string} execProp execMac / execLinux |
| 153 | + * @param {string} execArgsProp matching args field |
| 154 | + * @param {string} exec resolved shell |
| 155 | + */ |
| 156 | +function buildPosixBookmark (shell, execProp, execArgsProp, exec) { |
| 157 | + return build({ |
| 158 | + id: `default-local-${shell}`, |
| 159 | + title: shell, |
| 160 | + execProp, |
| 161 | + execArgsProp, |
| 162 | + exec, |
| 163 | + description: `Local terminal running ${shell}` |
| 164 | + }) |
| 165 | +} |
| 166 | + |
| 167 | +function getPosixBookmarks () { |
| 168 | + const execProp = isMac ? 'execMac' : 'execLinux' |
| 169 | + const execArgsProp = isMac ? 'execMacArgs' : 'execLinuxArgs' |
| 170 | + return posixShells |
| 171 | + .map(name => [name, resolveExec(name)]) |
| 172 | + .filter(([, exec]) => exec) |
| 173 | + .map(([name, exec]) => buildPosixBookmark(name, execProp, execArgsProp, exec)) |
| 174 | +} |
| 175 | + |
| 176 | +function getDefaultLocalBookmarks () { |
| 177 | + return isWin ? getWindowsBookmarks() : getPosixBookmarks() |
| 178 | +} |
| 179 | + |
| 180 | +export { |
| 181 | + getDefaultLocalBookmarks, |
| 182 | + getWindowsBookmarks, |
| 183 | + getPosixBookmarks, |
| 184 | + buildWindowsBookmarks, |
| 185 | + buildPosixBookmark, |
| 186 | + posixShells |
| 187 | +} |
0 commit comments