diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index 8b4c40ff1..b7812b1f6 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -8,8 +8,26 @@ LeadingWhitespaceRegex = /^\s*/ TrailingWhitespaceRegex = /\s*$/ RepeatedSpaceRegex = /[ ]/g CommentScopeRegex = /(\b|\.)comment/ +TabCharCode = 9 +SpaceCharCode = 32 +SpaceString = ' ' +TabStringsByLength = { + 1: ' ' + 2: ' ' + 3: ' ' + 4: ' ' +} + idCounter = 1 +getTabString = (length) -> + TabStringsByLength[length] ?= buildTabString(length) + +buildTabString = (length) -> + string = SpaceString + string += SpaceString for i in [1...length] by 1 + string + module.exports = class TokenizedLine endOfLineInvisibles: null @@ -53,18 +71,18 @@ class TokenizedLine # advance to next token tag tokenIndex++ while @tags[tokenIndex] < 0 - character = @text[bufferColumn] + charCode = @text.charCodeAt(bufferColumn) # split out unicode surrogate pairs if isPairedCharacter(@text, bufferColumn) prefix = tokenOffset suffix = @tags[tokenIndex] - tokenOffset - 2 - splitTokens = [] - splitTokens.push(prefix) if prefix > 0 - splitTokens.push(2) - splitTokens.push(suffix) if suffix > 0 - @tags.splice(tokenIndex, 1, splitTokens...) + i = tokenIndex + @tags.splice(i, 1) + @tags.splice(i++, 0, prefix) if prefix > 0 + @tags.splice(i++, 0, 2) + @tags.splice(i, 0, suffix) if suffix > 0 firstNonWhitespaceColumn ?= screenColumn lastNonWhitespaceColumn = screenColumn + 1 @@ -79,7 +97,7 @@ class TokenizedLine tokenOffset = 0 # split out leading soft tabs - else if character is ' ' + else if charCode is SpaceCharCode if firstNonWhitespaceColumn? substringEnd += 1 else @@ -90,7 +108,8 @@ class TokenizedLine @tags.splice(tokenIndex + 1, 0, suffix) if suffix > 0 if @invisibles?.space - text += @text.substring(substringStart, substringEnd) if substringEnd > substringStart + if substringEnd > substringStart + text += @text.substring(substringStart, substringEnd) substringStart = substringEnd text += @invisibles.space substringStart += 1 @@ -102,28 +121,29 @@ class TokenizedLine tokenOffset++ # expand hard tabs to the next tab stop - else if character is '\t' - text += @text.substring(substringStart, substringEnd) if substringEnd > substringStart + else if charCode is TabCharCode + if substringEnd > substringStart + text += @text.substring(substringStart, substringEnd) substringStart = substringEnd tabLength = @tabLength - (screenColumn % @tabLength) if @invisibles?.tab text += @invisibles.tab + text += getTabString(tabLength - 1) if tabLength > 1 else - text += ' ' - text += ' ' for i in [1...tabLength] by 1 + text += getTabString(tabLength) substringStart += 1 substringEnd += 1 prefix = tokenOffset suffix = @tags[tokenIndex] - tokenOffset - 1 - splitTokens = [] - splitTokens.push(prefix) if prefix > 0 - splitTokens.push(tabLength) - splitTokens.push(suffix) if suffix > 0 - @tags.splice(tokenIndex, 1, splitTokens...) + i = tokenIndex + @tags.splice(i, 1) + @tags.splice(i++, 0, prefix) if prefix > 0 + @tags.splice(i++, 0, tabLength) + @tags.splice(i, 0, suffix) if suffix > 0 screenColumn += tabLength bufferColumn++