diff --git a/lib/find.coffee b/lib/find.coffee index f20018e4..4dba4888 100644 --- a/lib/find.coffee +++ b/lib/find.coffee @@ -10,6 +10,11 @@ ProjectFindView = require './project-find-view' ResultsModel = require './project/results-model' ResultsPaneView = require './project/results-pane' +# To convert previous (and now unused) config setting "openProjectFindResultsInRightPane" +if atom.config.get('find-and-replace.openProjectFindResultsInRightPane') + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'right pane') + atom.config.unset('find-and-replace.openProjectFindResultsInRightPane') + module.exports = activate: ({findOptions, findHistory, replaceHistory, pathsHistory}={}) -> atom.workspace.addOpener (filePath) -> diff --git a/lib/project-find-view.coffee b/lib/project-find-view.coffee index 4100fc77..5fce4c1e 100644 --- a/lib/project-find-view.coffee +++ b/lib/project-find-view.coffee @@ -299,7 +299,9 @@ class ProjectFindView extends View showResultPane: -> options = {searchAllPanes: true} - options.split = 'right' if atom.config.get('find-and-replace.openProjectFindResultsInRightPane') + switch atom.config.get('find-and-replace.openProjectFindResultsInANewPane') + when 'right pane' then options.split = 'right' + when 'bottom pane' then options.split = 'down' atom.workspace.open(ResultsPaneView.URI, options) onFinishedReplacing: (results) -> diff --git a/lib/project/match-view.coffee b/lib/project/match-view.coffee index 485b7593..a45255eb 100644 --- a/lib/project/match-view.coffee +++ b/lib/project/match-view.coffee @@ -43,8 +43,10 @@ class MatchView extends View @matchText.removeClass('highlight-error').addClass('highlight-info') confirm: (options = {}) -> - openInRightPane = atom.config.get('find-and-replace.openProjectFindResultsInRightPane') - options.split = 'left' if openInRightPane + openInNewPane = atom.config.get('find-and-replace.openProjectFindResultsInANewPane') + switch openInNewPane + when 'right pane' then options = {split: 'left'} + when 'bottom pane' then options = {split: 'up'} editorPromise = atom.workspace.open(@filePath, options) editorPromise.then (editor) => editor.setSelectedBufferRange(@match.range, autoscroll: true) diff --git a/package.json b/package.json index 869fe2fd..d6c6db93 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "repository": "https://github.com/atom/find-and-replace", "engines": { - "atom": "*" + "atom": ">=1.2.0" }, "dependencies": { "atom-space-pen-views": "^2.1.0", @@ -51,9 +51,11 @@ "default": false, "description": "Focus the editor and select the next match when a file search is executed. If no matches are found, the editor will not be focused." }, - "openProjectFindResultsInRightPane": { - "type": "boolean", - "default": false, + "openProjectFindResultsInANewPane": { + "type": "string", + "default": "no", + "enum": ["no", "right pane", "bottom pane"], + "title": "Open Results in a new pane", "description": "When a project-wide search is executed, open the results in a split pane instead of a tab in the same pane." }, "closeFindPanelAfterSearch": { diff --git a/spec/project-find-view-spec.coffee b/spec/project-find-view-spec.coffee index fd4a1efe..f351f2af 100644 --- a/spec/project-find-view-spec.coffee +++ b/spec/project-find-view-spec.coffee @@ -27,7 +27,7 @@ describe 'ProjectFindView', -> atom.project.setPaths([path.join(__dirname, 'fixtures')]) jasmine.attachToDOM(workspaceElement) - atom.config.set('find-and-replace.openProjectFindResultsInRightPane', false) + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'no') activationPromise = atom.packages.activatePackage("find-and-replace").then (options) -> mainModule = options.mainModule mainModule.createViews() @@ -329,9 +329,22 @@ describe 'ProjectFindView', -> workspaceElement.style.height = '1000px' atom.commands.dispatch editorView, 'project-find:show' - it "splits when option is true", -> + it "splits when option is right", -> initialPane = atom.workspace.getActivePane() - atom.config.set('find-and-replace.openProjectFindResultsInRightPane', true) + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'right pane') + projectFindView.findEditor.setText('items') + atom.commands.dispatch(projectFindView[0], 'core:confirm') + + waitsForPromise -> + searchPromise + + runs -> + pane1 = atom.workspace.getActivePane() + expect(pane1).not.toBe initialPane + + it "splits when option is bottom", -> + initialPane = atom.workspace.getActivePane() + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'bottom pane') projectFindView.findEditor.setText('items') atom.commands.dispatch(projectFindView[0], 'core:confirm') @@ -354,8 +367,8 @@ describe 'ProjectFindView', -> pane1 = atom.workspace.getActivePane() expect(pane1).toBe initialPane - it "can be duplicated", -> - atom.config.set('find-and-replace.openProjectFindResultsInRightPane', true) + it "can be duplicated on the right", -> + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'right pane') projectFindView.findEditor.setText('items') atom.commands.dispatch(projectFindView[0], 'core:confirm') @@ -379,6 +392,31 @@ describe 'ProjectFindView', -> expect(resultsPaneView2.querySelector('.preview-count').innerHTML).toEqual resultsPaneView1.querySelector('.preview-count').innerHTML + it "can be duplicated at the bottom", -> + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'bottom pane') + projectFindView.findEditor.setText('items') + atom.commands.dispatch(projectFindView[0], 'core:confirm') + + waitsForPromise -> + searchPromise + + runs -> + resultsPaneView1 = atom.views.getView(getExistingResultsPane()) + pane1 = atom.workspace.getActivePane() + pane1.splitDown(copyActiveItem: true) + + pane2 = atom.workspace.getActivePane() + resultsPaneView2 = atom.views.getView(pane2.itemForURI(ResultsPaneView.URI)) + + expect(pane1).not.toBe pane2 + expect(resultsPaneView1).not.toBe resultsPaneView2 + + length = resultsPaneView1.querySelectorAll('li > ul > li').length + expect(length).toBeGreaterThan 0 + expect(resultsPaneView2.querySelectorAll('li > ul > li')).toHaveLength length + + expect(resultsPaneView2.querySelector('.preview-count').innerHTML).toEqual resultsPaneView1.querySelector('.preview-count').innerHTML + describe "serialization", -> it "serializes if the case, regex and whole word options", -> atom.commands.dispatch editorView, 'project-find:show' @@ -1375,9 +1413,9 @@ describe 'ProjectFindView', -> expect(projectFindView.pathsEditor).not.toHaveClass('is-focused') describe "panel opening", -> - describe "when a panel is already open", -> + describe "when a panel is already open on the right", -> beforeEach -> - atom.config.set('find-and-replace.openProjectFindResultsInRightPane', true) + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'right pane') waitsForPromise -> atom.workspace.open('sample.js') @@ -1408,6 +1446,39 @@ describe 'ProjectFindView', -> runs -> expect(workspaceElement.querySelectorAll('.preview-pane').length).toBe(1) + describe "when a panel is already open at the bottom", -> + beforeEach -> + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'bottom pane') + + waitsForPromise -> + atom.workspace.open('sample.js') + + runs -> + editor = atom.workspace.getActiveTextEditor() + editorView = atom.views.getView(editor) + atom.commands.dispatch(workspaceElement, 'project-find:show') + + waitsForPromise -> + activationPromise + + runs -> + projectFindView.findEditor.setText('items') + atom.commands.dispatch(projectFindView[0], 'core:confirm') + + waitsForPromise -> + searchPromise + + it "doesn't open another panel even if the active pane is horizontally split", -> + atom.commands.dispatch(editorView, 'pane:split-right') + projectFindView.findEditor.setText('items') + atom.commands.dispatch(projectFindView[0], 'core:confirm') + + waitsForPromise -> + searchPromise + + runs -> + expect(workspaceElement.querySelectorAll('.preview-pane').length).toBe(1) + describe "when language-javascript is active", -> beforeEach -> waitsForPromise -> diff --git a/spec/results-view-spec.coffee b/spec/results-view-spec.coffee index 64c484ff..96d6fc20 100644 --- a/spec/results-view-spec.coffee +++ b/spec/results-view-spec.coffee @@ -445,25 +445,35 @@ describe 'ResultsView', -> expect(editor.isPending()).toBe false expect(atom.views.getView(editor)).toHaveFocus() - describe "when `openProjectFindResultsInRightPane` option is true", -> + describe "when `openProjectFindResultsInANewPane` option is no", -> beforeEach -> - atom.config.set('find-and-replace.openProjectFindResultsInRightPane', true) + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'no') it "always opens the file in the left pane", -> + spyOn(atom.workspace, 'open').andCallThrough() + atom.commands.dispatch resultsView.element, 'core:move-down' + atom.commands.dispatch resultsView.element, 'core:confirm' + expect(atom.workspace.open.mostRecentCall.args[1]).toEqual {} + + describe "when `openProjectFindResultsInANewPane` option is right pane", -> + beforeEach -> + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'right pane') + + it "does not specify a pane to split", -> spyOn(atom.workspace, 'open').andCallThrough() atom.commands.dispatch resultsView.element, 'core:move-down' atom.commands.dispatch resultsView.element, 'core:confirm' expect(atom.workspace.open.mostRecentCall.args[1].split).toBe 'left' - describe "when `openProjectFindResultsInRightPane` option is false", -> + describe "when `openProjectFindResultsInANewPane` option is bottom pane", -> beforeEach -> - atom.config.set('find-and-replace.openProjectFindResultsInRightPane', false) + atom.config.set('find-and-replace.openProjectFindResultsInANewPane', 'bottom pane') it "does not specify a pane to split", -> spyOn(atom.workspace, 'open').andCallThrough() atom.commands.dispatch resultsView.element, 'core:move-down' atom.commands.dispatch resultsView.element, 'core:confirm' - expect(atom.workspace.open.mostRecentCall.args[1]).toEqual {} + expect(atom.workspace.open.mostRecentCall.args[1].split).toBe 'up' describe "arrowing through the list", -> it "arrows through the entire list without selecting paths and overshooting the boundaries", ->