LineWrapper.splitTokens handles the cases I can think of

Basically... splitTokens will never put whitespace at the beginning of
wrapped display line. It also splits tokens without regard for
whitespace if the token has no whitespace but is too wide to display on
a single line.
This commit is contained in:
Nathan Sobo
2012-02-08 21:37:35 -07:00
parent 34922a18fe
commit 2dcdf82fc9
2 changed files with 79 additions and 18 deletions

View File

@@ -42,22 +42,46 @@ class LineWrapper
while tokens.length
nextToken = tokens[0]
if length + nextToken.value.length > @maxLength
# keep any leading whitespace on current line
if match = /\b/.exec(nextToken.value)
if match.index > 0
tokens[0..0] = @splitTokenAt(nextToken, match.index)
else
break
tokenFragments = @splitBoundaryToken(nextToken, @maxLength - length)
[token1, token2] = tokenFragments
tokens[0..0] = _.compact(tokenFragments)
break unless token1
nextToken = tokens.shift()
length += nextToken.value.length
screenLine.push nextToken
[screenLine].concat @splitTokens(tokens)
splitTokenAt: (token, index) ->
{ type, value} = token
value1 = value.substring(0, index)
value2 = value.substring(index)
splitBoundaryToken: (token, boundaryIndex) ->
{ value } = token
# if no whitespace, split it all to next line if it will fit.
# if it's longer than the max width, chop it without regard for whitespace.
unless /\s/.test(value)
if value.length > @maxLength
return @splitTokenAt(token, boundaryIndex)
else
return [null, token]
# if only whitespace, keep it all on current line.
return [token, null] unless /\w/.test(value)
# if words + whitespace, try to split on start of word closest to the boundary
wordStart = /\b\w/g
while match = wordStart.exec(value)
breakIndex = match.index
break if breakIndex > boundaryIndex
# if the only word start is at the beginning of the token, put the whole token on the next line
return [null, token] if breakIndex == 0
@splitTokenAt(token, breakIndex)
splitTokenAt: (token, splitIndex) ->
{ type, value } = token
value1 = value.substring(0, splitIndex)
value2 = value.substring(splitIndex)
[{value: value1, type }, {value: value2, type}]
buildWrappedLineForBufferRow: (bufferRow) ->