diff --git a/Rakefile b/Rakefile index a6abfc1eb..2cbb0d9a0 100644 --- a/Rakefile +++ b/Rakefile @@ -86,7 +86,7 @@ end desc "Remove any 'fit' or 'fdescribe' focus directives from the specs" task :nof do - system %{find . -name *spec.coffee | xargs sed -E -i "" "s/f(it|describe) +(['\\"])/\\1 \\2/g"} + system %{find . -name *spec.coffee | xargs sed -E -i "" "s/f+(it|describe) +(['\\"])/\\1 \\2/g"} end task :"verify-prerequisites" do diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index f4214a30a..797d0b214 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -927,8 +927,6 @@ describe "Editor", -> editor.visibleLines.trigger 'mouseup' expect(editor.getSelectedText()).toBe " return sort(left).concat(pivot).concat(sort(right));" - editor.logLines() - # Quad click point = [12, 3] editor.visibleLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 1}) @@ -2425,22 +2423,18 @@ describe "Editor", -> expect(editor.getSelection().isEmpty()).toBeTruthy() expect(editor.getCursorScreenPosition()).toEqual [5, 0] - # describe "when a fold placeholder is clicked", -> - # it "removes the associated fold and places the cursor at its beginning", -> - # editor.getSelection().setBufferRange(new Range([4, 29], [7, 4])) - # editor.trigger 'fold-selection' + describe "when a fold placeholder line is clicked", -> + it "removes the associated fold and places the cursor at its beginning", -> + editor.getSelection().setBufferRange(new Range([3, 0], [9, 0])) + editor.trigger 'fold-selection' - # editor.find('.fold-placeholder .ellipsis').mousedown() + editor.find('.fold.line').mousedown() - # expect(editor.find('.fold-placeholder')).not.toExist() - # expect(editor.visibleLines.find('.line:eq(5)').text()).toBe ' current = items.shift();' + expect(editor.find('.fold')).not.toExist() + expect(editor.visibleLines.find('.line:eq(4)').text()).toMatch /4-+/ + expect(editor.visibleLines.find('.line:eq(5)').text()).toMatch /5/ - # expect(editor.getCursorBufferPosition()).toEqual [4, 29] - - # describe "when there is nothing on a line except a fold placeholder", -> - # it "follows the placeholder with a non-breaking space to ensure the line has the proper height", -> - # editor.createFold([[1, 0], [1, 30]]) - # expect(editor.visibleLines.find('.line:eq(1)').html()).toMatch / $/ + expect(editor.getCursorBufferPosition()).toEqual [3, 0] describe "editor-path-change event", -> it "emits event when buffer's path is changed", -> diff --git a/spec/app/renderer-spec.coffee b/spec/app/renderer-spec.coffee index 99575012e..901e6aee8 100644 --- a/spec/app/renderer-spec.coffee +++ b/spec/app/renderer-spec.coffee @@ -43,98 +43,6 @@ describe "Renderer", -> expect(renderer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], ' expect(renderer.lineForRow(4).text).toBe 'right = [];' - describe "when a fold is created on the last screen line of a wrapped buffer line", -> - it "inserts the placeholder in the correct location and fires a change event", -> - fold = renderer.createFold([[3, 52], [3, 56]]) - expect(renderer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], ' - expect(renderer.lineForRow(4).text).toBe 'r... = [];' - expect(renderer.lineForRow(5).text).toBe ' while(items.length > 0) {' - - expect(changeHandler).toHaveBeenCalled() - [[event]]= changeHandler.argsForCall - expect(event.oldRange).toEqual([[3, 0], [4, 11]]) - expect(event.newRange).toEqual([[3, 0], [4, 10]]) - - changeHandler.reset() - fold.destroy() - - expect(renderer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], ' - expect(renderer.lineForRow(4).text).toBe 'right = [];' - expect(renderer.lineForRow(5).text).toBe ' while(items.length > 0) {' - - expect(changeHandler).toHaveBeenCalled() - [[event]]= changeHandler.argsForCall - expect(event.oldRange).toEqual([[3, 0], [4, 10]]) - expect(event.newRange).toEqual([[3, 0], [4, 11]]) - - describe "when a fold is created on the penultimate screen line of a wrapped buffer line", -> - beforeEach -> - renderer.setMaxLineLength(36) - changeHandler.reset() - - it "inserts the placeholder in the correct location and fires a change event", -> - fold = renderer.createFold([[6, 29], [6, 33]]) - expect(renderer.lineForRow(8).text).toBe " current < pivot ? " - expect(renderer.lineForRow(9).text).toBe "left....(current) : " - expect(renderer.lineForRow(10).text).toBe "right.push(current);" - - expect(changeHandler).toHaveBeenCalled() - [[event]]= changeHandler.argsForCall - expect(event.oldRange).toEqual([[8, 0], [10, 20]]) - expect(event.newRange).toEqual([[8, 0], [10, 20]]) - - changeHandler.reset() - fold.destroy() - - expect(changeHandler).toHaveBeenCalled() - [[event]]= changeHandler.argsForCall - expect(event.oldRange).toEqual([[8, 0], [10, 20]]) - expect(event.newRange).toEqual([[8, 0], [10, 20]]) - - describe "when a fold ends on the penultimate screen line of a wrapped buffer line", -> - beforeEach -> - renderer.setMaxLineLength(36) - changeHandler.reset() - - it "inserts the placeholder in the correct location and fires a change event", -> - fold = renderer.createFold([[5, 0], [6, 29]]) - expect(renderer.lineForRow(6).text).toBe " while(items.length > 0) {" - expect(renderer.lineForRow(7).text).toBe "...push(current) : " - expect(renderer.lineForRow(8).text).toBe "right.push(current);" - - expect(changeHandler).toHaveBeenCalled() - [[event]]= changeHandler.argsForCall - expect(event.oldRange).toEqual([[7, 0], [10, 20]]) - expect(event.newRange).toEqual([[7, 0], [8, 20]]) - - changeHandler.reset() - fold.destroy() - - expect(changeHandler).toHaveBeenCalled() - [[event]]= changeHandler.argsForCall - expect(event.oldRange).toEqual([[7, 0], [8, 20]]) - expect(event.newRange).toEqual([[7, 0], [10, 20]]) - - describe "when there is a fold placeholder straddling the max length boundary", -> - it "wraps the line before the fold placeholder", -> - renderer.createFold([[3, 49], [6, 1]]) - - expect(renderer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = []' - expect(renderer.lineForRow(4).text).toBe '... current < pivot ? left.push(current) : ' - expect(renderer.lineForRow(5).text).toBe 'right.push(current);' - expect(renderer.lineForRow(6).text).toBe ' }' - - renderer.createFold([[6, 56], [8, 15]]) - expect(renderer.lineForRow(5).text).toBe 'right.push(...(left).concat(pivot).concat(sort(rig' - expect(renderer.lineForRow(6).text).toBe 'ht));' - expect(renderer.lineForRow(7).text).toBe ' };' - - describe "when there is a fold placeholder ending at the max length boundary", -> - it "wraps the line after the fold placeholder", -> - renderer.createFold([[3, 47], [3, 51]]) - expect(renderer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = ...' - expect(renderer.lineForRow(4).text).toBe 'right = [];' - describe "when the buffer changes", -> describe "when buffer lines are updated", -> describe "when the update makes a soft-wrapped line shorter than the max line length", -> @@ -437,53 +345,26 @@ describe "Renderer", -> expect(event.newRange).toEqual [[1, 0], [1, 9]] describe "position translation", -> - describe "when there is single fold spanning multiple lines", -> - it "translates positions to account for folded lines and characters and the placeholder", -> - renderer.createFold([[4, 29], [7, 4]]) + it "translates positions to account for folded lines and characters and the placeholder", -> + renderer.createFold(4, 7) - # preceding fold: identity - expect(renderer.screenPositionForBufferPosition([3, 0])).toEqual [3, 0] - expect(renderer.screenPositionForBufferPosition([4, 0])).toEqual [4, 0] - expect(renderer.screenPositionForBufferPosition([4, 29])).toEqual [4, 29] + # preceding fold: identity + expect(renderer.screenPositionForBufferPosition([3, 0])).toEqual [3, 0] + expect(renderer.screenPositionForBufferPosition([4, 0])).toEqual [4, 0] - expect(renderer.bufferPositionForScreenPosition([3, 0])).toEqual [3, 0] - expect(renderer.bufferPositionForScreenPosition([4, 0])).toEqual [4, 0] - expect(renderer.bufferPositionForScreenPosition([4, 29])).toEqual [4, 29] + expect(renderer.bufferPositionForScreenPosition([3, 0])).toEqual [3, 0] + expect(renderer.bufferPositionForScreenPosition([4, 0])).toEqual [4, 0] - # inside of fold: translate to the start of the fold - expect(renderer.screenPositionForBufferPosition([4, 35])).toEqual [4, 29] - expect(renderer.screenPositionForBufferPosition([5, 5])).toEqual [4, 29] + # inside of fold: translate to the start of the fold + expect(renderer.screenPositionForBufferPosition([4, 35])).toEqual [4, 0] + expect(renderer.screenPositionForBufferPosition([5, 5])).toEqual [4, 0] - # following fold, on last line of fold - expect(renderer.screenPositionForBufferPosition([7, 4])).toEqual [4, 32] - expect(renderer.bufferPositionForScreenPosition([4, 32])).toEqual [7, 4] + # following fold + expect(renderer.screenPositionForBufferPosition([8, 0])).toEqual [5, 0] + expect(renderer.screenPositionForBufferPosition([11, 2])).toEqual [8, 2] - # # following fold, subsequent line - expect(renderer.screenPositionForBufferPosition([8, 0])).toEqual [5, 0] - expect(renderer.screenPositionForBufferPosition([11, 13])).toEqual [8, 13] - - expect(renderer.bufferPositionForScreenPosition([5, 0])).toEqual [8, 0] - expect(renderer.bufferPositionForScreenPosition([9, 2])).toEqual [12, 2] - - describe "when there is a single fold spanning a single line", -> - it "translates positions to account for folded characters and the placeholder", -> - renderer.createFold([[4, 10], [4, 15]]) - - expect(renderer.screenPositionForBufferPosition([4, 5])).toEqual [4, 5] - expect(renderer.bufferPositionForScreenPosition([4, 5])).toEqual [4, 5] - - expect(renderer.screenPositionForBufferPosition([4, 15])).toEqual [4, 13] - expect(renderer.bufferPositionForScreenPosition([4, 13])).toEqual [4, 15] - - expect(renderer.screenPositionForBufferPosition([4, 20])).toEqual [4, 18] - expect(renderer.bufferPositionForScreenPosition([4, 18])).toEqual [4, 20] - - describe "when there is a fold on a wrapped line", -> - it "translates positions accounting for both the fold and the wrapped line", -> - renderer.setMaxLineLength(50) - renderer.createFold([[3, 51], [3, 58]]) - expect(renderer.screenPositionForBufferPosition([3, 58])).toEqual [4, 3] - expect(renderer.bufferPositionForScreenPosition([4, 3])).toEqual [3, 58] + expect(renderer.bufferPositionForScreenPosition([5, 0])).toEqual [8, 0] + expect(renderer.bufferPositionForScreenPosition([9, 2])).toEqual [12, 2] describe ".clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", -> beforeEach -> @@ -514,6 +395,10 @@ describe "Renderer", -> expect(renderer.clipScreenPosition([0, 30], wrapBeyondNewlines: true)).toEqual [1, 0] expect(renderer.clipScreenPosition([0, 1000], wrapBeyondNewlines: true)).toEqual [1, 0] + it "wraps positions in the middle of fold lines to the next screen line", -> + renderer.createFold(3, 5) + expect(renderer.clipScreenPosition([3, 5], wrapBeyondNewlines: true)).toEqual [4, 0] + describe "when wrapAtSoftNewlines is false (the default)", -> it "clips positions at the end of soft-wrapped lines to the character preceding the end of the line", -> expect(renderer.clipScreenPosition([3, 50])).toEqual [3, 50] @@ -521,11 +406,6 @@ describe "Renderer", -> expect(renderer.clipScreenPosition([3, 58])).toEqual [3, 50] expect(renderer.clipScreenPosition([3, 1000])).toEqual [3, 50] - describe "if there is a fold placeholder at the very end of the screen line", -> - it "clips positions at the end of the screen line to the position preceding the placeholder", -> - renderer.createFold([[3, 47], [3, 51]]) - expect(renderer.clipScreenPosition([3, 50])).toEqual [3, 47] - describe "when wrapAtSoftNewlines is true", -> it "wraps positions at the end of soft-wrapped lines to the next screen line", -> expect(renderer.clipScreenPosition([3, 50], wrapAtSoftNewlines: true)).toEqual [3, 50] @@ -534,12 +414,6 @@ describe "Renderer", -> expect(renderer.clipScreenPosition([3, 1000], wrapAtSoftNewlines: true)).toEqual [4, 0] describe "when skipAtomicTokens is false (the default)", -> - it "clips screen positions in the middle of fold placeholders to the to the beginning of fold placeholders", -> - renderer.createFold([[3, 55], [3, 59]]) - expect(renderer.clipScreenPosition([4, 5])).toEqual [4, 4] - expect(renderer.clipScreenPosition([4, 6])).toEqual [4, 4] - expect(renderer.clipScreenPosition([4, 7])).toEqual [4, 7] - it "clips screen positions in the middle of atomic tab characters to the beginning of the character", -> buffer.insert([0, 0], '\t') expect(renderer.clipScreenPosition([0, 0])).toEqual [0, 0] @@ -547,13 +421,7 @@ describe "Renderer", -> expect(renderer.clipScreenPosition([0, tabText.length])).toEqual [0, tabText.length] describe "when skipAtomicTokens is true", -> - it "wraps the screen positions in the middle of fold placeholders to the end of the placeholder", -> - renderer.createFold([[3, 55], [3, 59]]) - expect(renderer.clipScreenPosition([4, 4], skipAtomicTokens: true)).toEqual [4, 4] - expect(renderer.clipScreenPosition([4, 5], skipAtomicTokens: true)).toEqual [4, 7] - expect(renderer.clipScreenPosition([4, 6], skipAtomicTokens: true)).toEqual [4, 7] - - it "clips screen positions in the middle of atomic tab characters to the beginning of the character", -> + it "clips screen positions in the middle of atomic tab characters to the end of the character", -> buffer.insert([0, 0], '\t') expect(renderer.clipScreenPosition([0, 0], skipAtomicTokens: true)).toEqual [0, 0] expect(renderer.clipScreenPosition([0, 1], skipAtomicTokens: true)).toEqual [0, tabText.length] diff --git a/src/app/editor.coffee b/src/app/editor.coffee index b1b345d46..fbcb0cab9 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -173,8 +173,8 @@ class Editor extends View @isFocused = false @removeClass 'focused' - @visibleLines.on 'mousedown', '.fold-placeholder', (e) => - @destroyFold($(e.currentTarget).attr('foldId')) + @visibleLines.on 'mousedown', '.fold.line', (e) => + @destroyFold($(e.currentTarget).attr('fold-id')) false @visibleLines.on 'mousedown', (e) => @@ -464,9 +464,11 @@ class Editor extends View $$ -> for line in lines - lineClass = 'line' - lineClass += ' fold' if line.fold? - @div class: lineClass, => + if fold = line.fold + lineAttributes = { class: 'fold line', 'fold-id': fold.id } + else + lineAttributes = { class: 'line' } + @div lineAttributes, => if line.text == '' @raw ' ' if line.text == '' else @@ -690,7 +692,7 @@ class Editor extends View destroyFold: (foldId) -> fold = @renderer.foldsById[foldId] fold.destroy() - @setCursorBufferPosition(fold.start) + @setCursorBufferPosition([fold.startRow, 0]) splitLeft: -> @pane()?.splitLeft(@copy()).wrappedView diff --git a/src/app/line-map.coffee b/src/app/line-map.coffee index 2b95436df..3e12a71f2 100644 --- a/src/app/line-map.coffee +++ b/src/app/line-map.coffee @@ -121,8 +121,8 @@ class LineMap targetDelta = traversalResult[targetDeltaType] return targetDelta unless lastLineFragment - maxSourceColumn = sourceDelta.column + lastLineFragment.text.length - maxTargetColumn = targetDelta.column + lastLineFragment.text.length + maxSourceColumn = sourceDelta.column + lastLineFragment.textLength() + maxTargetColumn = targetDelta.column + lastLineFragment.textLength() if lastLineFragment.isSoftWrapped() and sourcePosition.column >= maxSourceColumn if wrapAtSoftNewlines diff --git a/src/app/screen-line-fragment.coffee b/src/app/screen-line-fragment.coffee index 3b9a1d0df..8dfdde1e2 100644 --- a/src/app/screen-line-fragment.coffee +++ b/src/app/screen-line-fragment.coffee @@ -49,8 +49,7 @@ class ScreenLineFragment translateColumn: (sourceDeltaType, targetDeltaType, sourceColumn, options={}) -> { skipAtomicTokens } = options - textLength = @text.length - sourceColumn = Math.min(sourceColumn, textLength) + sourceColumn = Math.min(sourceColumn, @textLength()) currentSourceColumn = 0 currentTargetColumn = 0 @@ -72,6 +71,12 @@ class ScreenLineFragment remainingColumns = sourceColumn - currentSourceColumn currentTargetColumn + remainingColumns + textLength: -> + if @fold + textLength = 0 + else + textLength = @text.length + isSoftWrapped: -> @screenDelta.row == 1 and @bufferDelta.row == 0 diff --git a/vendor/jasmine-focused.js b/vendor/jasmine-focused.js index b59bbac85..c10b1b976 100644 --- a/vendor/jasmine-focused.js +++ b/vendor/jasmine-focused.js @@ -1,20 +1,45 @@ -var fdescribe = function(description, specDefinitions) { - jasmine.getEnv().focus = true +var setGlobalFocusPriority = function(priority) { + env = jasmine.getEnv(); + if (!env.focusPriority) env.focusPriority = 1; + if (priority > env.focusPriority) env.focusPriority = priority; +}; + +var fdescribe = function(description, specDefinitions, priority) { + if (!priority) priority = 1; + setGlobalFocusPriority(priority) var suite = describe(description, specDefinitions); - suite.focus = true; + suite.focusPriority = priority; return suite; }; -var fit = function(description, definition) { - jasmine.getEnv().focus = true +var ffdescribe = function(description, specDefinitions) { + fdescribe(description, specDefinitions, 2); +}; + +var fffdescribe = function(description, specDefinitions) { + fdescribe(description, specDefinitions, 3); +}; + +var fit = function(description, definition, priority) { + if (!priority) priority = 1; + setGlobalFocusPriority(priority); var spec = it(description, definition); - spec.focus = true; + spec.focusPriority = priority; return spec; }; +var ffit = function(description, specDefinitions) { + fit(description, specDefinitions, 2); +}; + +var fffit = function(description, specDefinitions) { + fit(description, specDefinitions, 3); +}; + var fSpecFilter = function(specOrSuite) { - if (!jasmine.getEnv().focus) return true; - if (specOrSuite.focus) return true; + globalFocusPriority = jasmine.getEnv().focusPriority; + if (!globalFocusPriority) return true; + if (specOrSuite.focusPriority >= globalFocusPriority) return true; var parent = specOrSuite.parentSuite || specOrSuite.suite; if (!parent) return false; @@ -29,7 +54,7 @@ jasmine.AtomReporter.prototype.specFilter = function(spec) { paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); } - if (!paramMap.spec && !jasmine.getEnv().focus) { + if (!paramMap.spec && !jasmine.getEnv().focusPriority) { return true; }