diff --git a/src/command/Commands.js b/src/command/Commands.js index 9b3416c339b..0cde9f49ddf 100644 --- a/src/command/Commands.js +++ b/src/command/Commands.js @@ -96,6 +96,7 @@ define(function (require, exports, module) { exports.NAVIGATE_NEXT_DOC = "navigate.nextDoc"; exports.NAVIGATE_PREV_DOC = "navigate.prevDoc"; exports.NAVIGATE_SHOW_IN_FILE_TREE = "navigate.showInFileTree"; + exports.NAVIGATE_SHOW_IN_OS = "navigate.showInOS"; exports.NAVIGATE_QUICK_OPEN = "navigate.quickOpen"; exports.NAVIGATE_GOTO_DEFINITION = "navigate.gotoDefinition"; exports.NAVIGATE_GOTO_LINE = "navigate.gotoLine"; diff --git a/src/command/DefaultMenus.js b/src/command/DefaultMenus.js index 941a17a91a3..e88b04a29c1 100644 --- a/src/command/DefaultMenus.js +++ b/src/command/DefaultMenus.js @@ -179,6 +179,7 @@ define(function (require, exports, module) { project_cmenu.addMenuItem(Commands.FILE_NEW); project_cmenu.addMenuItem(Commands.FILE_NEW_FOLDER); project_cmenu.addMenuItem(Commands.FILE_RENAME); + project_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_OS); project_cmenu.addMenuDivider(); project_cmenu.addMenuItem(Commands.EDIT_FIND_IN_SUBTREE); @@ -187,6 +188,7 @@ define(function (require, exports, module) { working_set_cmenu.addMenuItem(Commands.FILE_SAVE); working_set_cmenu.addMenuItem(Commands.FILE_RENAME); working_set_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_FILE_TREE); + working_set_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_OS); working_set_cmenu.addMenuDivider(); working_set_cmenu.addMenuItem(Commands.EDIT_FIND_IN_SUBTREE); working_set_cmenu.addMenuDivider(); diff --git a/src/document/DocumentCommandHandlers.js b/src/document/DocumentCommandHandlers.js index 327b2e9a7b8..3d490f57f7c 100644 --- a/src/document/DocumentCommandHandlers.js +++ b/src/document/DocumentCommandHandlers.js @@ -342,9 +342,11 @@ define(function (require, exports, module) { fileNewInProgress = true; // Determine the directory to put the new file - // If a file is currently selected, put it next to it. - // If a directory is currently selected, put it in it. - // If nothing is selected, put it at the root of the project + // If a file is currently selected in the tree, put it next to it. + // If a directory is currently selected in the tree, put it in it. + // If nothing is selected in the tree, put it at the root of the project + // (Note: 'selected' may be an item that's selected in the working set and not the tree; but in that case + // ProjectManager.createNewItem() ignores the baseDir we give it and falls back to the project root on its own) var baseDir, selected = ProjectManager.getSelectedItem() || ProjectManager.getProjectRoot(); @@ -766,15 +768,18 @@ define(function (require, exports, module) { ); } - /** Show a textfield to rename whatever is currently selected in the sidebar (working set OR tree) */ + /** Show a textfield to rename whatever is currently selected in the sidebar (or current doc if nothing else selected) */ function handleFileRename() { - // Prefer selected tree item (which could be a folder); else use current file + // Prefer selected sidebar item (which could be a folder) var entry = ProjectManager.getSelectedItem(); if (!entry) { + // Else use current file (not selected in ProjectManager if not visible in tree or working set) var doc = DocumentManager.getCurrentDocument(); entry = doc && doc.file; } - ProjectManager.renameItemInline(entry); + if (entry) { + ProjectManager.renameItemInline(entry); + } } /** Closes the window, then quits the app */ @@ -840,6 +845,19 @@ define(function (require, exports, module) { ProjectManager.showInTree(DocumentManager.getCurrentDocument().file); } + /** Show the selected sidebar (tree or working set) item in Finder/Explorer */ + function handleShowInOS() { + var entry = ProjectManager.getSelectedItem(); + if (entry) { + brackets.app.showOSFolder(entry.fullPath, function (err) { + if (err) { + console.error("Error showing '" + entry.fullPath + "' in OS folder:", err); + } + }); + } + } + + // Init DOM elements AppInit.htmlReady(function () { var $titleContainerToolbar = $("#titlebar"); @@ -876,6 +894,7 @@ define(function (require, exports, module) { CommandManager.register(Strings.CMD_NEXT_DOC, Commands.NAVIGATE_NEXT_DOC, handleGoNextDoc); CommandManager.register(Strings.CMD_PREV_DOC, Commands.NAVIGATE_PREV_DOC, handleGoPrevDoc); CommandManager.register(Strings.CMD_SHOW_IN_TREE, Commands.NAVIGATE_SHOW_IN_FILE_TREE, handleShowInTree); + CommandManager.register(Strings.CMD_SHOW_IN_OS, Commands.NAVIGATE_SHOW_IN_OS, handleShowInOS); // Listen for changes that require updating the editor titlebar $(DocumentManager).on("dirtyFlagChange", handleDirtyChange); diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index e3774ffbe71..f45c097d6a6 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -243,6 +243,7 @@ define({ "CMD_NEXT_DOC" : "Next Document", "CMD_PREV_DOC" : "Previous Document", "CMD_SHOW_IN_TREE" : "Show in File Tree", + "CMD_SHOW_IN_OS" : "Show in OS", // Debug menu commands "DEBUG_MENU" : "Debug", diff --git a/src/project/ProjectManager.js b/src/project/ProjectManager.js index ec8b8efa132..bb268432da4 100644 --- a/src/project/ProjectManager.js +++ b/src/project/ProjectManager.js @@ -175,18 +175,35 @@ define(function (require, exports, module) { } /** - * Returns the FileEntry or DirectoryEntry corresponding to the selected item, or null - * if no item is selected. - * + * Returns the FileEntry or DirectoryEntry corresponding to the item selected in the file tree, or null + * if no item is selected in the tree (though the working set may still have a selection; use + * getSelectedItem() to get the selection regardless of whether it's in the tree or working set). * @return {?Entry} */ - function getSelectedItem() { + function _getTreeSelectedItem() { var selected = _projectTree.jstree("get_selected"); if (selected) { return selected.data("entry"); } return null; } + + /** + * Returns the FileEntry or DirectoryEntry corresponding to the item selected in the sidebar panel, whether in + * the file tree OR in the working set; or null if no item is selected anywhere in the sidebar. + * May NOT be identical to the current Document - a folder may be selected in the sidebar, or the sidebar may not + * have the current document visible in the tree & working set. + * @return {?Entry} + */ + function getSelectedItem() { + // Prefer file tree selection, else use working set selection + var selectedEntry = _getTreeSelectedItem(); + if (!selectedEntry) { + var doc = DocumentManager.getCurrentDocument(); + selectedEntry = (doc && doc.file); + } + return selectedEntry; + } function _fileViewFocusChange() { _redraw(true); @@ -691,6 +708,7 @@ define(function (require, exports, module) { function (error, entries) { if (entries) { // some but not all entries failed to load, so render what we can + console.warn("Error reading a subset of folder " + dirEntry); processEntries(entries); } else { Dialogs.showModalDialog( diff --git a/src/search/FindInFiles.js b/src/search/FindInFiles.js index 626f8116e02..db101b7e6a7 100644 --- a/src/search/FindInFiles.js +++ b/src/search/FindInFiles.js @@ -431,13 +431,7 @@ define(function (require, exports, module) { /** Search within the file/subtree defined by the sidebar selection */ function doFindInSubtree() { - // Prefer project tree selection, else use working set selection var selectedEntry = ProjectManager.getSelectedItem(); - if (!selectedEntry) { - var doc = DocumentManager.getCurrentDocument(); - selectedEntry = (doc && doc.file); - } - doFindInFiles(selectedEntry); }