Add "Continuous Reflow" mode

This commit is contained in:
Antonio Scandurra 2015-09-07 13:25:13 +02:00
parent fef79a6b49
commit 9eed6c7834
5 changed files with 83 additions and 1 deletions

View File

@ -450,6 +450,31 @@ describe "TextEditorComponent", ->
nextAnimationFrame()
expect(component.lineNodeForScreenRow(10).innerHTML).toBe '<span class="indent-guide"><span class="invisible-character">C</span></span><span class="invisible-character">E</span>'
it "keeps rebuilding lines when continuous reflow is on", ->
atom.config.set("editor.continuousReflow", true)
nextAnimationFrame()
oldLineNodes = componentNode.querySelectorAll(".line")
advanceClock(10)
expect(nextAnimationFrame).toBe(noAnimationFrame)
advanceClock(component.presenter.minimumReflowInterval - 10)
nextAnimationFrame()
newLineNodes = componentNode.querySelectorAll(".line")
expect(oldLineNodes).not.toEqual(newLineNodes)
oldLineNodes = newLineNodes
atom.config.set("editor.continuousReflow", false)
nextAnimationFrame()
newLineNodes = componentNode.querySelectorAll(".line")
expect(oldLineNodes).toEqual(newLineNodes)
advanceClock(component.presenter.minimumReflowInterval)
expect(nextAnimationFrame).toBe(noAnimationFrame)
describe "when soft wrapping is enabled", ->
beforeEach ->
editor.setText "a line that wraps \n"
@ -827,6 +852,31 @@ describe "TextEditorComponent", ->
expect(componentNode.querySelector('.gutter').style.display).toBe ''
expect(component.lineNumberNodeForScreenRow(3)?).toBe true
it "keeps rebuilding line numbers when continuous reflow is on", ->
atom.config.set("editor.continuousReflow", true)
nextAnimationFrame()
oldLineNodes = componentNode.querySelectorAll(".line-number")
advanceClock(10)
expect(nextAnimationFrame).toBe(noAnimationFrame)
advanceClock(component.presenter.minimumReflowInterval - 10)
nextAnimationFrame()
newLineNodes = componentNode.querySelectorAll(".line-number")
expect(oldLineNodes).not.toEqual(newLineNodes)
oldLineNodes = newLineNodes
atom.config.set("editor.continuousReflow", false)
nextAnimationFrame()
newLineNodes = componentNode.querySelectorAll(".line-number")
expect(oldLineNodes).toEqual(newLineNodes)
advanceClock(component.presenter.minimumReflowInterval)
expect(nextAnimationFrame).toBe(noAnimationFrame)
describe "fold decorations", ->
describe "rendering fold decorations", ->
it "adds the foldable class to line numbers when the line is foldable", ->

View File

@ -217,6 +217,10 @@ module.exports =
type: 'boolean'
default: process.platform isnt 'darwin'
description: 'Increase/decrease the editor font size when pressing the Ctrl key and scrolling the mouse up/down.'
continuousReflow:
type: 'boolean'
default: false
description: 'Track down expensive layouts or style recalculations by continously reflowing the editor. (Has performance overhead)'
if process.platform in ['win32', 'linux']
module.exports.core.properties.autoHideMenuBar =

View File

@ -62,6 +62,9 @@ class LineNumberGutterComponent extends TiledComponent
buildComponentForTile: (id) -> new LineNumbersTileComponent({id})
shouldRecreateAllTilesOnUpdate: ->
@newState.continuousReflow
###
Section: Private Methods
###

View File

@ -32,7 +32,7 @@ class LinesComponent extends TiledComponent
@domNode
shouldRecreateAllTilesOnUpdate: ->
@oldState.indentGuidesVisible isnt @newState.indentGuidesVisible
@oldState.indentGuidesVisible isnt @newState.indentGuidesVisible or @newState.continuousReflow
beforeUpdateSync: (state) ->
if @newState.maxHeight isnt @oldState.maxHeight

View File

@ -11,6 +11,7 @@ class TextEditorPresenter
mouseWheelScreenRow: null
scopedCharacterWidthsChangeCount: 0
overlayDimensions: {}
minimumReflowInterval: 200
constructor: (params) ->
{@model, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @boundingClientRect, @windowWidth, @windowHeight, @gutterWidth} = params
@ -35,6 +36,7 @@ class TextEditorPresenter
@observeConfig()
@buildState()
@startBlinkingCursors() if @focused
@startReflowing() if @continuousReflow
@updating = false
destroy: ->
@ -72,6 +74,7 @@ class TextEditorPresenter
@updateStartRow()
@updateEndRow()
@updateCommonGutterState()
@updateReflowState()
@updateFocusedState() if @shouldUpdateFocusedState
@updateHeightState() if @shouldUpdateHeightState
@ -169,6 +172,7 @@ class TextEditorPresenter
observeConfig: ->
configParams = {scope: @model.getRootScopeDescriptor()}
@continuousReflow = atom.config.get('editor.continuousReflow', configParams)
@scrollPastEnd = atom.config.get('editor.scrollPastEnd', configParams)
@showLineNumbers = atom.config.get('editor.showLineNumbers', configParams)
@showIndentGuide = atom.config.get('editor.showIndentGuide', configParams)
@ -199,6 +203,16 @@ class TextEditorPresenter
@emitDidUpdateState()
@configDisposables.add atom.config.onDidChange 'editor.continuousReflow', configParams, ({newValue}) =>
@continuousReflow = newValue
if @continuousReflow
@startReflowing()
else
@stopReflowing()
@emitDidUpdateState()
didChangeGrammar: ->
@observeConfig()
@shouldUpdateContentState = true
@ -254,6 +268,17 @@ class TextEditorPresenter
@resetTrackedUpdates()
updateReflowState: ->
@state.content.continuousReflow = @continuousReflow
@lineNumberGutter.continuousReflow = @continuousReflow
startReflowing: ->
@reflowingInterval = setInterval(@emitDidUpdateState.bind(this), @minimumReflowInterval)
stopReflowing: ->
clearInterval(@reflowingInterval)
@reflowingInterval = null
updateFocusedState: ->
@state.focused = @focused