diff --git a/spec/extensions/command-interpreter-spec.coffee b/spec/extensions/command-interpreter-spec.coffee index 11cf661c3..414948c4c 100644 --- a/spec/extensions/command-interpreter-spec.coffee +++ b/spec/extensions/command-interpreter-spec.coffee @@ -204,20 +204,21 @@ describe "CommandInterpreter", -> expect(cursors[1].getBufferPosition()).toEqual [6, 65] expect(cursors[2].getBufferPosition()).toEqual [7, 5] - it "loops through current selections and selects text matching the regex", -> - waitsForPromise -> - editSession.setSelectedBufferRange [[3,0], [3,62]] - editSession.addSelectionForBufferRange [[6,0], [6,65]] - interpreter.eval('x/current', editSession) + describe "when text is initially selected", -> + it "loops through current selections and selects text matching the regex", -> + waitsForPromise -> + editSession.setSelectedBufferRange [[3,0], [3,62]] + editSession.addSelectionForBufferRange [[6,0], [6,65]] + interpreter.eval('x/current', editSession) - runs -> - selections = editSession.getSelections() - expect(selections.length).toBe 4 + runs -> + selections = editSession.getSelections() + expect(selections.length).toBe 4 - expect(selections[0].getBufferRange()).toEqual [[3,31], [3,38]] - expect(selections[1].getBufferRange()).toEqual [[6,6], [6,13]] - expect(selections[2].getBufferRange()).toEqual [[6,34], [6,41]] - expect(selections[3].getBufferRange()).toEqual [[6,56], [6,63]] + expect(selections[0].getBufferRange()).toEqual [[3,31], [3,38]] + expect(selections[1].getBufferRange()).toEqual [[6,6], [6,13]] + expect(selections[2].getBufferRange()).toEqual [[6,34], [6,41]] + expect(selections[3].getBufferRange()).toEqual [[6,56], [6,63]] describe "substitution", -> it "does nothing if there are no matches", -> diff --git a/spec/extensions/command-panel-spec.coffee b/spec/extensions/command-panel-spec.coffee index b60116196..0997ac316 100644 --- a/spec/extensions/command-panel-spec.coffee +++ b/spec/extensions/command-panel-spec.coffee @@ -13,7 +13,7 @@ describe "CommandPanel", -> commandPanel = requireExtension('command-panel') afterEach -> - rootView.remove() + rootView.deactivate() describe "serialization", -> it "preserves the command panel's mini editor text and visibility across reloads", -> @@ -119,6 +119,21 @@ describe "CommandPanel", -> expect(buffer.lineForRow(0)).toMatch /quicktorta/ expect(buffer.lineForRow(1)).toMatch /var torta/ + describe "when the command returns operations to be previewed", -> + fit "displays a preview of the operations above the mini-editor", -> + rootView.attachToDom() + editor.remove() + + rootView.trigger 'command-panel:toggle' + + commandPanel.miniEditor.insertText + + waitsForPromise -> commandPanel.execute('X x/a+/') + + runs -> + expect(commandPanel).toBeVisible() + expect(commandPanel.previewList).toBeVisible() + describe "if the command is malformed", -> it "adds and removes an error class to the command panel and does not close it", -> rootView.trigger 'command-panel:toggle' diff --git a/src/extensions/command-panel/command-panel.coffee b/src/extensions/command-panel/command-panel.coffee index 0cbde9cb2..da44344bd 100644 --- a/src/extensions/command-panel/command-panel.coffee +++ b/src/extensions/command-panel/command-panel.coffee @@ -2,6 +2,7 @@ CommandInterpreter = require 'command-panel/command-interpreter' RegexAddress = require 'command-panel/commands/regex-address' CompositeCommand = require 'command-panel/commands/composite-command' +PreviewItem = require 'command-panel/preview-item' Editor = require 'editor' {SyntaxError} = require('pegjs').parser @@ -16,6 +17,9 @@ class CommandPanel extends View else @instance = new CommandPanel(rootView) + @deactivate: -> + @instance.detach() + @serialize: -> text: @instance.miniEditor.getText() visible: @instance.hasParent() @@ -27,8 +31,10 @@ class CommandPanel extends View @content: -> @div class: 'command-panel', => - @div ':', class: 'prompt', outlet: 'prompt' - @subview 'miniEditor', new Editor(mini: true) + @ol class: 'preview-list', outlet: 'previewList' + @div class: 'prompt-and-editor', => + @div ':', class: 'prompt', outlet: 'prompt' + @subview 'miniEditor', new Editor(mini: true) commandInterpreter: null history: null @@ -54,16 +60,25 @@ class CommandPanel extends View attach: (text='') -> @rootView.append(this) + @previewList.hide() @miniEditor.focus() @miniEditor.setText(text) detach: -> @rootView.focus() + if @previewedOperations + operation.destroy() for operation in @previewedOperations super execute: (command = @miniEditor.getText()) -> try - @commandInterpreter.eval(command, @rootView.getActiveEditSession()) + @commandInterpreter.eval(command, @rootView.getActiveEditSession()).done (operations) => + @history.push(command) + @historyIndex = @history.length + if operations?.length + @populatePreviewList(operations) + else + @detach() catch error if error instanceof SyntaxError @flashError() @@ -71,9 +86,12 @@ class CommandPanel extends View else throw error - @history.push(command) - @historyIndex = @history.length - @detach() + populatePreviewList: (operations) -> + @previewedOperations = operations + @previewList.empty() + for operation in operations + @previewList.append(new PreviewItem(operation)) + @previewList.show() navigateBackwardInHistory: -> return if @historyIndex == 0 diff --git a/src/extensions/command-panel/commands/composite-command.coffee b/src/extensions/command-panel/commands/composite-command.coffee index c15cc9e2f..395c4ce11 100644 --- a/src/extensions/command-panel/commands/composite-command.coffee +++ b/src/extensions/command-panel/commands/composite-command.coffee @@ -21,10 +21,10 @@ class CompositeCommand @executeCommands(remainingCommands, project, editSession, nextRanges).done -> deferred.resolve() else - editSession?.clearAllSelections() unless currentCommand.preserveSelections if currentCommand.previewOperations deferred.resolve(operations) else + editSession?.clearAllSelections() unless currentCommand.preserveSelections for operation in operations operation.execute(editSession) operation.destroy() diff --git a/src/extensions/command-panel/operation.coffee b/src/extensions/command-panel/operation.coffee index 0f47201dc..154d1b4d9 100644 --- a/src/extensions/command-panel/operation.coffee +++ b/src/extensions/command-panel/operation.coffee @@ -14,6 +14,9 @@ class Operation @buffer.change(@getBufferRange(), @newText) if @newText editSession.addSelectionForBufferRange(@getBufferRange()) unless @preserveSelection + preview: -> + "sad :-(" + destroy: -> @buffer.release() @anchorRange.destroy() \ No newline at end of file diff --git a/src/extensions/command-panel/preview-item.coffee b/src/extensions/command-panel/preview-item.coffee new file mode 100644 index 000000000..a9b75c9ef --- /dev/null +++ b/src/extensions/command-panel/preview-item.coffee @@ -0,0 +1,8 @@ +{View} = require 'space-pen' + +module.exports = +class PreviewItem extends View + @content: (operation) -> + @li => + @span operation.getPath() + @span operation.preview() diff --git a/static/command-panel.css b/static/command-panel.css index faa942f54..50d218159 100644 --- a/static/command-panel.css +++ b/static/command-panel.css @@ -4,6 +4,14 @@ width: 100%; background: #515151; padding: 3px; +} + +.command-panel .preview-list { + max-height: 300px; + overflow: auto; +} + +.command-panel .prompt-and-editor { display: -webkit-box; }