Tab characters render as atomic tokens containing spaces

This commit is contained in:
Corey Johnson & Nathan Sobo
2012-04-05 15:22:57 -06:00
parent 4550f017c3
commit 84ba78c55d
6 changed files with 55 additions and 10 deletions

View File

@@ -137,3 +137,20 @@ describe "Highlighter", ->
[event] = changeHandler.argsForCall[0]
expect(event.oldRange).toEqual new Range([2, 0], [5, buffer.lineForRow(7).length])
expect(event.newRange).toEqual new Range([2, 0], [7, buffer.lineForRow(7).length])
describe "when the buffer contains tab characters", ->
beforeEach ->
buffer = new Buffer(require.resolve('fixtures/sample-with-tabs.coffee'))
highlighter = new Highlighter(buffer)
it "always renders each tab as its own atomic token containing atom.tabText", ->
screenLine0 = highlighter.lineForScreenRow(0)
expect(screenLine0.text).toBe "# Econ 101#{atom.tabText}"
{ tokens } = screenLine0
expect(tokens.length).toBe 2
expect(tokens[0].value).toBe "# Econ 101"
expect(tokens[1].value).toBe atom.tabText
expect(tokens[1].type).toBe tokens[0].type
expect(tokens[1].isAtomic).toBeTruthy()
expect(highlighter.lineForScreenRow(2).text).toBe "#{atom.tabText} buy()#{atom.tabText}while supply > demand"

View File

@@ -604,6 +604,12 @@ describe "Renderer", ->
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]
expect(renderer.clipScreenPosition([0, 1])).toEqual [0, 0]
expect(renderer.clipScreenPosition([0, atom.tabText.length])).toEqual [0, atom.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]])
@@ -611,6 +617,12 @@ describe "Renderer", ->
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", ->
buffer.insert([0, 0], '\t')
expect(renderer.clipScreenPosition([0, 0], skipAtomicTokens: true)).toEqual [0, 0]
expect(renderer.clipScreenPosition([0, 1], skipAtomicTokens: true)).toEqual [0, atom.tabText.length]
expect(renderer.clipScreenPosition([0, atom.tabText.length], skipAtomicTokens: true)).toEqual [0, atom.tabText.length]
describe ".bufferRowsForScreenRows()", ->
it "returns the buffer rows corresponding to each screen row in the given range", ->
renderer.setMaxLineLength(50)

View File

@@ -1,4 +1,4 @@
# Econ 101
# Econ 101
if this.studyingEconomics
buy() while supply > demand
sell() until supply > demand

View File

@@ -56,8 +56,12 @@ class Highlighter
tokenizer = @buffer.getMode().getTokenizer()
line = @buffer.lineForRow(row)
{tokens, state} = tokenizer.getLineTokens(line, state)
tokens = tokens.map (tokenProperties) -> new Token(tokenProperties)
new ScreenLineFragment(tokens, line, [1, 0], [1, 0], { state })
tokenObjects = []
for tokenProperties in tokens
token = new Token(tokenProperties)
tokenObjects.push(token.breakOutTabCharacters()...)
text = _.pluck(tokenObjects, 'value').join('')
new ScreenLineFragment(tokenObjects, text, [1, 0], [1, 0], { state })
lineForScreenRow: (row) ->
@screenLines[row]

View File

@@ -45,19 +45,21 @@ class ScreenLineFragment
new ScreenLineFragment(tokens, text, screenDelta, bufferDelta, {state: other.state})
clipColumn: (column, { skipAtomicTokens }) ->
column = Math.min(column, @text.length)
textLength = @text.length
column = Math.min(column, textLength)
currentColumn = 0
for token in @tokens
nextColumn = token.value.length + currentColumn
break if nextColumn >= column
currentColumn = nextColumn
tokenStartColumn = currentColumn
tokenEndColumn = tokenStartColumn + token.value.length
break if tokenEndColumn > column
currentColumn = tokenEndColumn
if token?.isAtomic
if skipAtomicTokens and column > currentColumn
nextColumn
if skipAtomicTokens and column > tokenStartColumn
tokenEndColumn
else
currentColumn
tokenStartColumn
else
column

View File

@@ -13,3 +13,13 @@ class Token
value1 = @value.substring(0, splitIndex)
value2 = @value.substring(splitIndex)
[new Token(value: value1, type: @type), new Token(value: value2, type: @type)]
breakOutTabCharacters: ->
for substring in @value.match(/([^\t]+|\t)/g)
if substring == '\t'
@buildTabToken()
else
new Token(value: substring, type: @type)
buildTabToken: ->
new Token(value: atom.tabText, type: @type, isAtomic: true)