From fc24df5be327b1ff7643f648c5f68910231cc7a4 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sat, 14 Mar 2015 14:18:18 -0700 Subject: [PATCH 1/5] use TextEditorElement for VimCommandModeInputView --- lib/view-models/search-view-model.coffee | 8 ++-- .../vim-command-mode-input-view.coffee | 37 +++++++++---------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/view-models/search-view-model.coffee b/lib/view-models/search-view-model.coffee index 9f30066e..2a1b66d0 100644 --- a/lib/view-models/search-view-model.coffee +++ b/lib/view-models/search-view-model.coffee @@ -6,11 +6,11 @@ class SearchViewModel extends ViewModel super(@searchMotion, class: 'search') @historyIndex = -1 - @view.editor.on('core:move-up', @increaseHistorySearch) - @view.editor.on('core:move-down', @decreaseHistorySearch) + atom.commands.add(@view.editorElement, 'core:move-up', @increaseHistorySearch) + atom.commands.add(@view.editorElement, 'core:move-down', @decreaseHistorySearch) restoreHistory: (index) -> - @view.editor.setText(@history(index).value) + @view.editorElement.getModel().setText(@history(index).value) history: (index) -> @vimState.getSearchHistoryItem(index) @@ -24,7 +24,7 @@ class SearchViewModel extends ViewModel if @historyIndex <= 0 # get us back to a clean slate @historyIndex = -1 - @view.editor.setText('') + @view.editorElement.getModel().setText('') else @historyIndex -= 1 @restoreHistory(@historyIndex) diff --git a/lib/view-models/vim-command-mode-input-view.coffee b/lib/view-models/vim-command-mode-input-view.coffee index f4e966e5..060e0b20 100644 --- a/lib/view-models/vim-command-mode-input-view.coffee +++ b/lib/view-models/vim-command-mode-input-view.coffee @@ -4,16 +4,21 @@ module.exports = class VimCommandModeInputView extends View @content: -> @div class: 'command-mode-input', => - @div class: 'editor-container', outlet: 'editorContainer', => - @subview 'editor', new TextEditorView(mini: true) + @div class: 'editor-container', outlet: 'editorContainer' initialize: (@viewModel, opts = {})-> if opts.class? @editorContainer.addClass opts.class if opts.hidden + # TODO: this no longer works with atom-text-editor @editorContainer.addClass 'hidden-input' + @editorElement = document.createElement "atom-text-editor" + @editorElement.classList.add('editor') + @editorElement.getModel().setMini(true) + @editorContainer.append(@editorElement) + @singleChar = opts.singleChar @defaultText = opts.defaultText ? '' @@ -24,35 +29,29 @@ class VimCommandModeInputView extends View handleEvents: -> if @singleChar? - @editor.find('input').on 'textInput', @autosubmit - @editor.on 'core:confirm', @confirm - @editor.on 'core:cancel', @cancel - @editor.find('input').on 'blur', @cancel - - stopHandlingEvents: -> - if @singleChar? - @editor.find('input').off 'textInput', @autosubmit - @editor.off 'core:confirm', @confirm - @editor.off 'core:cancel', @cancel - @editor.find('input').off 'blur', @cancel - - autosubmit: (event) => - @editor.setText(event.originalEvent.data) + atom.commands.add(@editorElement, 'textInput', @autoSubmit) + else + atom.commands.add(@editorElement, 'editor:newline', @confirm) + atom.commands.add(@editorElement, 'core:confirm', @confirm) + atom.commands.add(@editorElement, 'core:cancel', @cancel) + atom.commands.add(@editorElement, 'blur', @cancel) + + autoSubmit: (event) => + @editorElement.getModel().setText(event.data) @confirm() confirm: => - @value = @editor.getText() or @defaultText + @value = @editorElement.getModel().getText() or @defaultText @viewModel.confirm(@) @remove() focus: => - @editorContainer.find('.editor').focus() + @editorElement.focus() cancel: (e) => @viewModel.cancel(@) @remove() remove: => - @stopHandlingEvents() atom.workspace.getActivePane().activate() @panel.destroy() From 947548542a0fce6d2dd9bc4f69c2d7d814026290 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 18 Mar 2015 14:43:58 -0700 Subject: [PATCH 2/5] Bind textInput listener w/ DOM API, not atom.commands --- lib/view-models/vim-command-mode-input-view.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/view-models/vim-command-mode-input-view.coffee b/lib/view-models/vim-command-mode-input-view.coffee index 060e0b20..2860c235 100644 --- a/lib/view-models/vim-command-mode-input-view.coffee +++ b/lib/view-models/vim-command-mode-input-view.coffee @@ -1,4 +1,4 @@ -{View, TextEditorView} = require 'atom' +{View} = require 'atom' module.exports = class VimCommandModeInputView extends View @@ -29,7 +29,7 @@ class VimCommandModeInputView extends View handleEvents: -> if @singleChar? - atom.commands.add(@editorElement, 'textInput', @autoSubmit) + @editorElement.addEventListener('textInput', @autoSubmit) else atom.commands.add(@editorElement, 'editor:newline', @confirm) atom.commands.add(@editorElement, 'core:confirm', @confirm) From 39939dc6c66a7c8f649688199789d1c88c3ae0bb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 18 Mar 2015 14:44:55 -0700 Subject: [PATCH 3/5] Make specs use TextEditorElement, not TextEditorView --- spec/motions-spec.coffee | 93 +++++++++++++++++--------------------- spec/operators-spec.coffee | 4 +- spec/vim-state-spec.coffee | 4 +- 3 files changed, 46 insertions(+), 55 deletions(-) diff --git a/spec/motions-spec.coffee b/spec/motions-spec.coffee index 67e6cd96..c9fd04ac 100644 --- a/spec/motions-spec.coffee +++ b/spec/motions-spec.coffee @@ -19,10 +19,15 @@ describe "Motions", -> helpers.keydown(key, options) commandModeInputKeydown = (key, opts = {}) -> - opts.element = editor.commandModeInputView.editor.find('input').get(0) + opts.element = editor.commandModeInputView.editorElement opts.raw = true keydown(key, opts) + submitCommandModeInputText = (text) -> + commandEditor = editor.commandModeInputView.editorElement + commandEditor.getModel().setText(text) + atom.commands.dispatch(commandEditor, "core:confirm") + describe "simple motions", -> beforeEach -> editor.setText("12345\nabcd\nABCDE") @@ -966,8 +971,7 @@ describe "Motions", -> it "moves the cursor to the specified search pattern", -> keydown('/') - editor.commandModeInputView.editor.setText 'def' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'def' expect(editor.getCursorBufferPosition()).toEqual [1, 0] expect(pane.activate).toHaveBeenCalled() @@ -975,16 +979,14 @@ describe "Motions", -> it "loops back around", -> editor.setCursorBufferPosition([3, 0]) keydown('/') - editor.commandModeInputView.editor.setText 'def' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'def' expect(editor.getCursorBufferPosition()).toEqual [1, 0] it "uses a valid regex as a regex", -> keydown('/') # Cycle through the 'abc' on the first line with a character pattern - editor.commandModeInputView.editor.setText '[abc]' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText '[abc]' expect(editor.getCursorBufferPosition()).toEqual [0, 1] keydown('n') expect(editor.getCursorBufferPosition()).toEqual [0, 2] @@ -993,8 +995,7 @@ describe "Motions", -> # Go straight to the literal [abc editor.setText("abc\n[abc]\n") keydown('/') - editor.commandModeInputView.editor.setText '[abc' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText '[abc' expect(editor.getCursorBufferPosition()).toEqual [1, 0] keydown('n') expect(editor.getCursorBufferPosition()).toEqual [1, 0] @@ -1003,8 +1004,7 @@ describe "Motions", -> editor.setText('one two three') keydown('v') keydown('/') - editor.commandModeInputView.editor.setText 'th' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'th' expect(editor.getCursorBufferPosition()).toEqual [0, 9] keydown('d') expect(editor.getText()).toBe 'hree' @@ -1013,8 +1013,7 @@ describe "Motions", -> editor.setText('line1\nline2\nline3') keydown('v') keydown('/') - editor.commandModeInputView.editor.setText 'line' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'line' {start, end} = editor.getSelectedBufferRange() expect(start.row).toEqual 0 expect(end.row).toEqual 1 @@ -1030,38 +1029,33 @@ describe "Motions", -> keydown('/') it "works in case sensitive mode", -> - editor.commandModeInputView.editor.setText 'ABC' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'ABC' expect(editor.getCursorBufferPosition()).toEqual [2, 0] keydown('n') expect(editor.getCursorBufferPosition()).toEqual [2, 0] it "works in case insensitive mode", -> - editor.commandModeInputView.editor.setText '\\cAbC' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText '\\cAbC' expect(editor.getCursorBufferPosition()).toEqual [1, 0] keydown('n') expect(editor.getCursorBufferPosition()).toEqual [2, 0] it "works in case insensitive mode wherever \\c is", -> - editor.commandModeInputView.editor.setText 'AbC\\c' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'AbC\\c' expect(editor.getCursorBufferPosition()).toEqual [1, 0] keydown('n') expect(editor.getCursorBufferPosition()).toEqual [2, 0] it "uses case insensitive search if useSmartcaseForSearch is true and searching lowercase", -> atom.config.set 'vim-mode.useSmartcaseForSearch', true - editor.commandModeInputView.editor.setText 'abc' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'abc' expect(editor.getCursorBufferPosition()).toEqual [1, 0] keydown('n') expect(editor.getCursorBufferPosition()).toEqual [2, 0] it "uses case sensitive search if useSmartcaseForSearch is true and searching uppercase", -> atom.config.set 'vim-mode.useSmartcaseForSearch', true - editor.commandModeInputView.editor.setText 'ABC' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'ABC' expect(editor.getCursorBufferPosition()).toEqual [2, 0] keydown('n') expect(editor.getCursorBufferPosition()).toEqual [2, 0] @@ -1073,8 +1067,7 @@ describe "Motions", -> beforeEach -> keydown('/') - editor.commandModeInputView.editor.setText 'def' - editor.commandModeInputView.editor.trigger 'core:confirm' + submitCommandModeInputText 'def' describe "the n keybinding", -> it "repeats the last search", -> @@ -1093,15 +1086,13 @@ describe "Motions", -> it "composes with operators", -> keydown('d') keydown('/') - editor.commandModeInputView.editor.setText('def') - editor.commandModeInputView.editor.trigger('core:confirm') + submitCommandModeInputText('def') expect(editor.getText()).toEqual "def\nabc\ndef\n" it "repeats correctly with operators", -> keydown('d') keydown('/') - editor.commandModeInputView.editor.setText('def') - editor.commandModeInputView.editor.trigger('core:confirm') + submitCommandModeInputText('def') keydown('.') expect(editor.getText()).toEqual "def\n" @@ -1109,15 +1100,13 @@ describe "Motions", -> describe "when reversed as ?", -> it "moves the cursor backwards to the specified search pattern", -> keydown('?') - editor.commandModeInputView.editor.setText('def') - editor.commandModeInputView.editor.trigger('core:confirm') + submitCommandModeInputText('def') expect(editor.getCursorBufferPosition()).toEqual [3, 0] describe "repeating", -> beforeEach -> keydown('?') - editor.commandModeInputView.editor.setText('def') - editor.commandModeInputView.editor.trigger('core:confirm') + submitCommandModeInputText('def') describe 'the n keybinding', -> it "repeats the last search backwards", -> @@ -1132,36 +1121,38 @@ describe "Motions", -> expect(editor.getCursorBufferPosition()).toEqual [1, 0] describe "using search history", -> + commandEditor = null + beforeEach -> keydown('/') - editor.commandModeInputView.editor.setText('def') - editor.commandModeInputView.editor.trigger('core:confirm') + submitCommandModeInputText('def') expect(editor.getCursorBufferPosition()).toEqual [1, 0] keydown('/') - editor.commandModeInputView.editor.setText('abc') - editor.commandModeInputView.editor.trigger('core:confirm') + submitCommandModeInputText('abc') expect(editor.getCursorBufferPosition()).toEqual [2, 0] + commandEditor = editor.commandModeInputView.editorElement + it "allows searching history in the search field", -> keydown('/') - editor.commandModeInputView.editor.trigger('core:move-up') - expect(editor.commandModeInputView.editor.getText()).toEqual('abc') - editor.commandModeInputView.editor.trigger('core:move-up') - expect(editor.commandModeInputView.editor.getText()).toEqual('def') - editor.commandModeInputView.editor.trigger('core:move-up') - expect(editor.commandModeInputView.editor.getText()).toEqual('def') + atom.commands.dispatch(commandEditor, 'core:move-up') + expect(commandEditor.getModel().getText()).toEqual('abc') + atom.commands.dispatch(commandEditor, 'core:move-up') + expect(commandEditor.getModel().getText()).toEqual('def') + atom.commands.dispatch(commandEditor, 'core:move-up') + expect(commandEditor.getModel().getText()).toEqual('def') it "resets the search field to empty when scrolling back", -> keydown('/') - editor.commandModeInputView.editor.trigger('core:move-up') - expect(editor.commandModeInputView.editor.getText()).toEqual('abc') - editor.commandModeInputView.editor.trigger('core:move-up') - expect(editor.commandModeInputView.editor.getText()).toEqual('def') - editor.commandModeInputView.editor.trigger('core:move-down') - expect(editor.commandModeInputView.editor.getText()).toEqual('abc') - editor.commandModeInputView.editor.trigger('core:move-down') - expect(editor.commandModeInputView.editor.getText()).toEqual '' + atom.commands.dispatch(commandEditor, 'core:move-up') + expect(commandEditor.getModel().getText()).toEqual('abc') + atom.commands.dispatch(commandEditor, 'core:move-up') + expect(commandEditor.getModel().getText()).toEqual('def') + atom.commands.dispatch(commandEditor, 'core:move-down') + expect(commandEditor.getModel().getText()).toEqual('abc') + atom.commands.dispatch(commandEditor, 'core:move-down') + expect(commandEditor.getModel().getText()).toEqual '' describe "the * keybinding", -> beforeEach -> diff --git a/spec/operators-spec.coffee b/spec/operators-spec.coffee index 25ef2e5b..825d881f 100644 --- a/spec/operators-spec.coffee +++ b/spec/operators-spec.coffee @@ -19,7 +19,7 @@ describe "Operators", -> helpers.keydown(key, options) commandModeInputKeydown = (key, opts = {}) -> - opts.element = editor.commandModeInputView.editor.find('input').get(0) + opts.element = editor.commandModeInputView.editorElement opts.raw = true keydown(key, opts) @@ -1241,7 +1241,7 @@ describe "Operators", -> it "replaces a single character with a line break", -> keydown('r') - editor.commandModeInputView.editor.trigger 'core:confirm' + atom.commands.dispatch(editor.commandModeInputView.editorElement, 'core:confirm') expect(editor.getText()).toBe '\n2\n\n4\n\n' expect(editor.getCursorBufferPositions()).toEqual [[1, 0], [3, 0]] diff --git a/spec/vim-state-spec.coffee b/spec/vim-state-spec.coffee index 0ede42d4..9bb21b0d 100644 --- a/spec/vim-state-spec.coffee +++ b/spec/vim-state-spec.coffee @@ -21,7 +21,7 @@ describe "VimState", -> helpers.keydown(key, options) commandModeInputKeydown = (key, opts = {}) -> - opts.element = editor.commandModeInputView.editor.find('input').get(0) + opts.element = editor.commandModeInputView.editorElement opts.raw = true keydown(key, opts) @@ -152,7 +152,7 @@ describe "VimState", -> keydown('r') expect(vimState.mode).toBe 'command' expect(vimState.opStack.length).toBe 0 - commandModeInputKeydown('escape') + atom.commands.dispatch(editor.commandModeInputView.editorElement, "core:cancel") keydown('d') expect(editor.getText()).toBe '012345\nabcdef' From 2d3c72ad1649d623aa178bd8f529653c69b63850 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 18 Mar 2015 21:20:18 -0700 Subject: [PATCH 4/5] Auto-confirm command-mode input view via model events --- lib/view-models/vim-command-mode-input-view.coffee | 7 ++----- spec/motions-spec.coffee | 4 +--- spec/operators-spec.coffee | 4 +--- spec/text-objects-spec.coffee | 4 +--- spec/vim-state-spec.coffee | 4 +--- 5 files changed, 6 insertions(+), 17 deletions(-) diff --git a/lib/view-models/vim-command-mode-input-view.coffee b/lib/view-models/vim-command-mode-input-view.coffee index 2860c235..8024b5a3 100644 --- a/lib/view-models/vim-command-mode-input-view.coffee +++ b/lib/view-models/vim-command-mode-input-view.coffee @@ -29,17 +29,14 @@ class VimCommandModeInputView extends View handleEvents: -> if @singleChar? - @editorElement.addEventListener('textInput', @autoSubmit) + @editorElement.getModel().getBuffer().onDidChange (e) => + @confirm() if e.newText else atom.commands.add(@editorElement, 'editor:newline', @confirm) atom.commands.add(@editorElement, 'core:confirm', @confirm) atom.commands.add(@editorElement, 'core:cancel', @cancel) atom.commands.add(@editorElement, 'blur', @cancel) - autoSubmit: (event) => - @editorElement.getModel().setText(event.data) - @confirm() - confirm: => @value = @editorElement.getModel().getText() or @defaultText @viewModel.confirm(@) diff --git a/spec/motions-spec.coffee b/spec/motions-spec.coffee index c9fd04ac..e1108a6f 100644 --- a/spec/motions-spec.coffee +++ b/spec/motions-spec.coffee @@ -19,9 +19,7 @@ describe "Motions", -> helpers.keydown(key, options) commandModeInputKeydown = (key, opts = {}) -> - opts.element = editor.commandModeInputView.editorElement - opts.raw = true - keydown(key, opts) + editor.commandModeInputView.editorElement.getModel().setText(key) submitCommandModeInputText = (text) -> commandEditor = editor.commandModeInputView.editorElement diff --git a/spec/operators-spec.coffee b/spec/operators-spec.coffee index 825d881f..4de958f1 100644 --- a/spec/operators-spec.coffee +++ b/spec/operators-spec.coffee @@ -19,9 +19,7 @@ describe "Operators", -> helpers.keydown(key, options) commandModeInputKeydown = (key, opts = {}) -> - opts.element = editor.commandModeInputView.editorElement - opts.raw = true - keydown(key, opts) + editor.commandModeInputView.editorElement.getModel().setText(key) describe "cancelling operations", -> it "does not throw an error even if no operation is pending", -> diff --git a/spec/text-objects-spec.coffee b/spec/text-objects-spec.coffee index d529f5df..fdc1f7cd 100644 --- a/spec/text-objects-spec.coffee +++ b/spec/text-objects-spec.coffee @@ -19,9 +19,7 @@ describe "TextObjects", -> helpers.keydown(key, options) commandModeInputKeydown = (key, opts = {}) -> - opts.element = editor.commandModeInputView.editor.find('input').get(0) - opts.raw = true - keydown(key, opts) + editor.commandModeInputView.editorElement.getModel().setText(key) describe "the 'iw' text object", -> beforeEach -> diff --git a/spec/vim-state-spec.coffee b/spec/vim-state-spec.coffee index 9bb21b0d..2e0548b0 100644 --- a/spec/vim-state-spec.coffee +++ b/spec/vim-state-spec.coffee @@ -21,9 +21,7 @@ describe "VimState", -> helpers.keydown(key, options) commandModeInputKeydown = (key, opts = {}) -> - opts.element = editor.commandModeInputView.editorElement - opts.raw = true - keydown(key, opts) + editor.commandModeInputView.editorElement.getModel().setText(key) describe "initialization", -> it "puts the editor in command-mode initially by default", -> From 96b4dc71b869fc292581377c936eed75c3f1de72 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 18 Mar 2015 21:20:40 -0700 Subject: [PATCH 5/5] Don't use hidden-input CSS class to hide command input --- lib/view-models/vim-command-mode-input-view.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/view-models/vim-command-mode-input-view.coffee b/lib/view-models/vim-command-mode-input-view.coffee index 8024b5a3..4231c729 100644 --- a/lib/view-models/vim-command-mode-input-view.coffee +++ b/lib/view-models/vim-command-mode-input-view.coffee @@ -11,8 +11,7 @@ class VimCommandModeInputView extends View @editorContainer.addClass opts.class if opts.hidden - # TODO: this no longer works with atom-text-editor - @editorContainer.addClass 'hidden-input' + @editorContainer.height(0) @editorElement = document.createElement "atom-text-editor" @editorElement.classList.add('editor')