From 1fe6c498ac8692e433ac84d0a4d3250eea94e074 Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Wed, 14 May 2014 13:30:18 +0100 Subject: [PATCH] Make hard tabs align to columns. --- src/token.coffee | 30 +++++++++++++++++++----------- src/tokenized-line.coffee | 8 ++++++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/token.coffee b/src/token.coffee index 5f1baab1d..d6cde6856 100644 --- a/src/token.coffee +++ b/src/token.coffee @@ -42,16 +42,19 @@ class Token whitespaceRegexForTabLength: (tabLength) -> WhitespaceRegexesByTabLength[tabLength] ?= new RegExp("([ ]{#{tabLength}})|(\t)|([^\t]+)", "g") - breakOutAtomicTokens: (tabLength, breakOutLeadingSoftTabs) -> + breakOutAtomicTokens: (tabLength, breakOutLeadingSoftTabs, startColumn) -> if @hasSurrogatePair outputTokens = [] + column = startColumn for token in @breakOutSurrogatePairs() + nextColumn += token.value.length if token.isAtomic outputTokens.push(token) else - outputTokens.push(token.breakOutAtomicTokens(tabLength, breakOutLeadingSoftTabs)...) + outputTokens.push(token.breakOutAtomicTokens(tabLength, breakOutLeadingSoftTabs, column)...) breakOutLeadingSoftTabs = token.isOnlyWhitespace() if breakOutLeadingSoftTabs + column = nextColumn outputTokens else @@ -64,17 +67,21 @@ class Token outputTokens = [] regex = @whitespaceRegexForTabLength(tabLength) + column = startColumn while match = regex.exec(@value) [fullMatch, softTab, hardTab] = match + token = null if softTab and breakOutLeadingSoftTabs - outputTokens.push(@buildSoftTabToken(tabLength)) + token = @buildSoftTabToken(tabLength) else if hardTab breakOutLeadingSoftTabs = false - outputTokens.push(@buildHardTabToken(tabLength)) + token = @buildHardTabToken(tabLength, column) else breakOutLeadingSoftTabs = false value = match[0] - outputTokens.push(new Token({value, @scopes})) + token = new Token({value, @scopes}) + column += token.value.length + outputTokens.push(token) outputTokens @@ -105,17 +112,18 @@ class Token isAtomic: true ) - buildHardTabToken: (tabLength) -> - @buildTabToken(tabLength, true) + buildHardTabToken: (tabLength, column) -> + @buildTabToken(tabLength, true, column) buildSoftTabToken: (tabLength) -> - @buildTabToken(tabLength, false) + @buildTabToken(tabLength, false, 0) - buildTabToken: (tabLength, isHardTab) -> + buildTabToken: (tabLength, isHardTab, column) -> + tabStop = tabLength - column % tabLength new Token( - value: _.multiplyString(" ", tabLength) + value: _.multiplyString(" ", tabStop) scopes: @scopes - bufferDelta: if isHardTab then 1 else tabLength + bufferDelta: if isHardTab then 1 else tabStop isAtomic: true isHardTab: isHardTab ) diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index 1bbec7972..02a77c2e1 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -5,8 +5,8 @@ idCounter = 1 module.exports = class TokenizedLine constructor: ({tokens, @lineEnding, @ruleStack, @startBufferColumn, @fold, @tabLength, @indentLevel}) -> - @tokens = @breakOutAtomicTokens(tokens) @startBufferColumn ?= 0 + @tokens = @breakOutAtomicTokens(tokens) @text = _.pluck(@tokens, 'value').join('') @bufferDelta = _.sum(_.pluck(@tokens, 'bufferDelta')) @id = idCounter++ @@ -113,8 +113,12 @@ class TokenizedLine breakOutAtomicTokens: (inputTokens) -> outputTokens = [] breakOutLeadingSoftTabs = true + column = @startBufferColumn for token in inputTokens - outputTokens.push(token.breakOutAtomicTokens(@tabLength, breakOutLeadingSoftTabs)...) + newTokens = token.breakOutAtomicTokens(@tabLength, breakOutLeadingSoftTabs, column) + for newToken in newTokens + column += newToken.value.length + outputTokens.push(newTokens...) breakOutLeadingSoftTabs = token.isOnlyWhitespace() if breakOutLeadingSoftTabs outputTokens