mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge pull request #1237 from atom/ks-hard-tab-cache
Fix caching of hard tabs
This commit is contained in:
@@ -1158,7 +1158,8 @@ describe "EditorView", ->
|
||||
line0 = editorView.renderedLines.find('.line:first')
|
||||
span0_0 = line0.children('span:eq(0)').children('span:eq(0)')
|
||||
expect(span0_0).toMatchSelector '.hard-tab'
|
||||
expect(span0_0.text()).toBe ' '
|
||||
expect(span0_0.text()).toBe ' '
|
||||
expect(span0_0.text().length).toBe editor.getTabLength()
|
||||
|
||||
it "wraps leading whitespace in a span", ->
|
||||
line1 = editorView.renderedLines.find('.line:eq(1)')
|
||||
@@ -2851,3 +2852,17 @@ describe "EditorView", ->
|
||||
editorView.pixelPositionForScreenPosition([0, 5])
|
||||
editorView.pixelPositionForScreenPosition([1, 5])
|
||||
expect(editorView.measureToColumn.callCount).toBe 0
|
||||
|
||||
describe "when the editor contains hard tabs", ->
|
||||
it "correctly calculates the the position left for a column", ->
|
||||
editorView.setText('\ttest')
|
||||
editorView.attachToDom()
|
||||
|
||||
expect(editorView.pixelPositionForScreenPosition([0, editor.getTabLength()]).left).toEqual 20
|
||||
expect(editorView.pixelPositionForScreenPosition([0, editor.getTabLength() + 1]).left).toEqual 30
|
||||
|
||||
# Check that widths are actually being cached
|
||||
spyOn(editorView, 'measureToColumn').andCallThrough()
|
||||
editorView.pixelPositionForScreenPosition([0, editor.getTabLength()])
|
||||
editorView.pixelPositionForScreenPosition([0, editor.getTabLength() + 1])
|
||||
expect(editorView.measureToColumn.callCount).toBe 0
|
||||
|
||||
@@ -1596,29 +1596,25 @@ class EditorView extends View
|
||||
positionLeftForLineAndColumn: (lineElement, screenRow, screenColumn) ->
|
||||
return 0 if screenColumn == 0
|
||||
|
||||
bufferRow = @bufferRowsForScreenRows(screenRow, screenRow)[0] ? screenRow
|
||||
bufferColumn = @bufferPositionForScreenPosition([screenRow, screenColumn]).column
|
||||
tokenizedLine = @editor.displayBuffer.tokenizedBuffer.tokenizedLines[bufferRow]
|
||||
tokenizedLine = @editor.displayBuffer.lineForRow(screenRow)
|
||||
|
||||
left = 0
|
||||
index = 0
|
||||
startIndex = @bufferPositionForScreenPosition([screenRow, 0]).column
|
||||
for token in tokenizedLine.tokens
|
||||
for char in token.value
|
||||
return left if index >= bufferColumn
|
||||
return left if index >= screenColumn
|
||||
|
||||
if index >= startIndex
|
||||
val = @getCharacterWidthCache(token.scopes, char)
|
||||
if val?
|
||||
left += val
|
||||
else
|
||||
return @measureToColumn(lineElement, tokenizedLine, screenColumn, startIndex)
|
||||
val = @getCharacterWidthCache(token.scopes, char)
|
||||
if val?
|
||||
left += val
|
||||
else
|
||||
return @measureToColumn(lineElement, tokenizedLine, screenColumn)
|
||||
|
||||
index++
|
||||
left
|
||||
|
||||
# Private:
|
||||
measureToColumn: (lineElement, tokenizedLine, screenColumn, lineStartBufferColumn) ->
|
||||
measureToColumn: (lineElement, tokenizedLine, screenColumn) ->
|
||||
left = oldLeft = index = 0
|
||||
iterator = document.createNodeIterator(lineElement, NodeFilter.SHOW_TEXT, TextNodeFilter)
|
||||
|
||||
@@ -1638,7 +1634,7 @@ class EditorView extends View
|
||||
returnLeft = left if index == screenColumn
|
||||
oldLeft = left
|
||||
|
||||
scopes = tokenizedLine.tokenAtBufferColumn(lineStartBufferColumn + index)?.scopes
|
||||
scopes = tokenizedLine.tokenAtBufferColumn(index)?.scopes
|
||||
cachedCharWidth = @getCharacterWidthCache(scopes, char)
|
||||
|
||||
if cachedCharWidth?
|
||||
@@ -1666,7 +1662,7 @@ class EditorView extends View
|
||||
# Private:
|
||||
getCharacterWidthCache: (scopes, char) ->
|
||||
scopes ?= NoScope
|
||||
obj = EditorView.characterWidthCache
|
||||
obj = @constructor.characterWidthCache
|
||||
for scope in scopes
|
||||
obj = obj[scope]
|
||||
return null unless obj?
|
||||
@@ -1675,7 +1671,7 @@ class EditorView extends View
|
||||
# Private:
|
||||
setCharacterWidthCache: (scopes, char, val) ->
|
||||
scopes ?= NoScope
|
||||
obj = EditorView.characterWidthCache
|
||||
obj = @constructor.characterWidthCache
|
||||
for scope in scopes
|
||||
obj[scope] ?= {}
|
||||
obj = obj[scope]
|
||||
@@ -1683,7 +1679,7 @@ class EditorView extends View
|
||||
|
||||
# Private:
|
||||
clearCharacterWidthCache: ->
|
||||
EditorView.characterWidthCache = {}
|
||||
@constructor.characterWidthCache = {}
|
||||
|
||||
pixelOffsetForScreenPosition: (position) ->
|
||||
{top, left} = @pixelPositionForScreenPosition(position)
|
||||
|
||||
@@ -135,9 +135,8 @@ class Token
|
||||
classes = 'hard-tab'
|
||||
classes += ' indent-guide' if hasIndentGuide
|
||||
classes += ' invisible-character' if invisibles.tab
|
||||
html = @value.replace StartCharacterRegex, (match) =>
|
||||
match = invisibles.tab ? match
|
||||
"<span class='#{classes}'>#{@escapeString(match)}</span>"
|
||||
value = if invisibles.tab then @value.replace(StartCharacterRegex, invisibles.tab) else @value
|
||||
html = "<span class='#{classes}'>#{@escapeString(value)}</span>"
|
||||
else
|
||||
startIndex = 0
|
||||
endIndex = @value.length
|
||||
|
||||
Reference in New Issue
Block a user