Skip to content

Commit 5e25232

Browse files
committed
feat(terminal): add "Open in Integrated Terminal" to project context menu
Adds an "Integrated Terminal" option to the "Open in" submenu in both the project tree and working set context menus. Opens a new terminal at the selected file's directory (or folder itself if a directory is selected). Refactors cwd resolution into a reusable _toNativePath helper.
1 parent 2c2a9be commit 5e25232

4 files changed

Lines changed: 45 additions & 16 deletions

File tree

src/command/Commands.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,8 @@ define(function (require, exports, module) {
348348

349349
/** Shows current file in OS Terminal */
350350
exports.NAVIGATE_OPEN_IN_TERMINAL = "navigate.openInTerminal";
351+
/** Opens integrated terminal at the selected file/folder path */
352+
exports.NAVIGATE_OPEN_IN_INTEGRATED_TERMINAL = "navigate.openInIntegratedTerminal";
351353

352354
/** Shows current file in open powershell in Windows os */
353355
exports.NAVIGATE_OPEN_IN_POWERSHELL = "navigate.openInPowerShell";

src/command/DefaultMenus.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ define(function (require, exports, module) {
315315
let subMenu = workingset_cmenu.addSubMenu(Strings.CMD_OPEN_IN, Commands.OPEN_IN_SUBMENU_WS);
316316
subMenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_OS);
317317
subMenu.addMenuItem(Commands.NAVIGATE_OPEN_IN_TERMINAL);
318+
subMenu.addMenuItem(Commands.NAVIGATE_OPEN_IN_INTEGRATED_TERMINAL);
318319
if (brackets.platform === "win") {
319320
subMenu.addMenuItem(Commands.NAVIGATE_OPEN_IN_POWERSHELL);
320321
}
@@ -358,6 +359,7 @@ define(function (require, exports, module) {
358359
let subMenu = project_cmenu.addSubMenu(Strings.CMD_OPEN_IN, Commands.OPEN_IN_SUBMENU);
359360
subMenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_OS);
360361
subMenu.addMenuItem(Commands.NAVIGATE_OPEN_IN_TERMINAL);
362+
subMenu.addMenuItem(Commands.NAVIGATE_OPEN_IN_INTEGRATED_TERMINAL);
361363
if (brackets.platform === "win") {
362364
subMenu.addMenuItem(Commands.NAVIGATE_OPEN_IN_POWERSHELL);
363365
}

src/extensionsIntegrated/Terminal/main.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -242,34 +242,46 @@ define(function (require, exports, module) {
242242
/**
243243
* Create a new terminal with the default shell
244244
*/
245-
async function _createNewTerminal() {
245+
async function _createNewTerminal(cwdOverride) {
246246
const shell = ShellProfiles.getDefaultShell();
247-
return _createNewTerminalWithShell(shell);
247+
return _createNewTerminalWithShell(shell, cwdOverride);
248+
}
249+
250+
/**
251+
* Convert a VFS path to a native platform path suitable for use as cwd.
252+
* Strips trailing slashes (posix_spawnp can fail with them).
253+
*/
254+
function _toNativePath(vfsPath) {
255+
let cwd = vfsPath;
256+
const tauriPrefix = Phoenix.VFS.getTauriDir();
257+
if (cwd.startsWith(tauriPrefix)) {
258+
cwd = Phoenix.fs.getTauriPlatformPath(cwd);
259+
}
260+
if (cwd.length > 1 && (cwd.endsWith("/") || cwd.endsWith("\\"))) {
261+
cwd = cwd.slice(0, -1);
262+
}
263+
return cwd;
248264
}
249265

250266
/**
251267
* Create a new terminal with a specific shell profile
268+
* @param {Object} shell - Shell profile to use
269+
* @param {string} [cwdOverride] - Optional VFS path to use as cwd instead of project root
252270
*/
253-
async function _createNewTerminalWithShell(shell) {
271+
async function _createNewTerminalWithShell(shell, cwdOverride) {
254272
if (!shell) {
255273
console.error("Terminal: No shell available");
256274
return;
257275
}
258276

259-
// Get project root as cwd, converting VFS path to native platform path
260-
const projectRoot = ProjectManager.getProjectRoot();
277+
// Get cwd: use override if provided, otherwise fall back to project root
261278
let cwd;
262-
if (projectRoot) {
263-
const fullPath = projectRoot.fullPath;
264-
const tauriPrefix = Phoenix.VFS.getTauriDir();
265-
if (fullPath.startsWith(tauriPrefix)) {
266-
cwd = Phoenix.fs.getTauriPlatformPath(fullPath);
267-
} else {
268-
cwd = fullPath;
269-
}
270-
// Remove trailing slash/backslash (posix_spawnp can fail with trailing slashes)
271-
if (cwd.length > 1 && (cwd.endsWith("/") || cwd.endsWith("\\"))) {
272-
cwd = cwd.slice(0, -1);
279+
if (cwdOverride) {
280+
cwd = _toNativePath(cwdOverride);
281+
} else {
282+
const projectRoot = ProjectManager.getProjectRoot();
283+
if (projectRoot) {
284+
cwd = _toNativePath(projectRoot.fullPath);
273285
}
274286
}
275287

@@ -626,6 +638,18 @@ define(function (require, exports, module) {
626638
// Register commands
627639
CommandManager.register("New Terminal", CMD_NEW_TERMINAL, _createNewTerminal);
628640
CommandManager.register(Strings.CMD_VIEW_TERMINAL, CMD_VIEW_TERMINAL, _showTerminal);
641+
CommandManager.register(Strings.CMD_OPEN_IN_INTEGRATED_TERMINAL,
642+
Commands.NAVIGATE_OPEN_IN_INTEGRATED_TERMINAL, function () {
643+
const entry = ProjectManager.getSelectedItem();
644+
let cwdPath;
645+
if (entry) {
646+
cwdPath = entry.isDirectory ? entry.fullPath : entry.parentPath;
647+
} else {
648+
const projectRoot = ProjectManager.getProjectRoot();
649+
cwdPath = projectRoot ? projectRoot.fullPath : undefined;
650+
}
651+
_createNewTerminal(cwdPath);
652+
});
629653

630654
// Terminal context menu commands
631655
CommandManager.register(Strings.CMD_COPY, CMD_TERMINAL_COPY, function () {

src/nls/root/strings.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ define({
686686
"CMD_SHOW_IN_FINDER": "macOS Finder",
687687
"CMD_SHOW_IN_FILE_MANAGER": "File Manager",
688688
"CMD_OPEN_IN_TERMINAL_DO_NOT_TRANSLATE": "Terminal",
689+
"CMD_OPEN_IN_INTEGRATED_TERMINAL": "Integrated Terminal",
689690
"CMD_OPEN_IN_CMD": "Command Prompt",
690691
"CMD_OPEN_IN_POWER_SHELL": "PowerShell",
691692
"CMD_OPEN_IN_DEFAULT_APP": "System Default App",

0 commit comments

Comments
 (0)