From acbacae6d50b7a44cf712a170cb9216955b5476b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 13 Jan 2016 18:23:22 -0700 Subject: [PATCH] Use TokenizedBuffer as a text decoration layer and render tags --- src/display-buffer.coffee | 1 + src/lines-tile-component.coffee | 23 +++++++++++++++++------ src/text-editor-presenter.coffee | 15 ++++++++++----- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 5cae0a23a..096afaa60 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -52,6 +52,7 @@ class DisplayBuffer extends Model }) @buffer = @tokenizedBuffer.buffer @displayLayer = @buffer.addDisplayLayer({tabLength: @getTabLength()}) + @displayLayer.setTextDecorationLayer(@tokenizedBuffer) @charWidthsByScope = {} @defaultMarkerLayer = @displayLayer.addMarkerLayer() @decorationsById = {} diff --git a/src/lines-tile-component.coffee b/src/lines-tile-component.coffee index f4712dfb6..7d106f9b2 100644 --- a/src/lines-tile-component.coffee +++ b/src/lines-tile-component.coffee @@ -125,7 +125,7 @@ class LinesTileComponent screenRowForNode: (node) -> parseInt(node.dataset.screenRow) buildLineNode: (id) -> - {screenRow, words, decorationClasses} = @newTileState.lines[id] + {screenRow, decorationClasses} = @newTileState.lines[id] lineNode = @domElementPool.buildElement("div", "line") lineNode.dataset.screenRow = screenRow @@ -183,12 +183,23 @@ class LinesTileComponent @currentLineTextNodes.push(textNode) setLineInnerNodes: (id, lineNode) -> - {words} = @newTileState.lines[id] + {tokens} = @newTileState.lines[id] lineLength = 0 - for word in words when word.length > 0 - lineLength += word.length - textNode = @domElementPool.buildText(word.replace(/\s/g, NBSPCharacter)) - lineNode.appendChild(textNode) + openScopeNode = lineNode + for token in tokens when token.text.length > 0 + {closeTags, openTags, text} = token + + for scope in closeTags + openScopeNode = openScopeNode.parentElement + + for scope in openTags + newScopeNode = @domElementPool.buildElement("span", scope.replace(/\.+/g, ' ')) + openScopeNode.appendChild(newScopeNode) + openScopeNode = newScopeNode + + lineLength += text.length + textNode = @domElementPool.buildText(text.replace(/\s/g, NBSPCharacter)) + openScopeNode.appendChild(textNode) @currentLineTextNodes.push(textNode) if lineLength is 0 diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 5d2b2c335..54ea000bd 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -133,8 +133,9 @@ class TextEditorPresenter @shouldUpdateDecorations = true observeModel: -> - @disposables.add @model.displayLayer.onDidChangeTextSync (change) => - @invalidateLines(change) + @disposables.add @model.displayLayer.onDidChangeSync (changes) => + for change in changes + @invalidateLines(change) @shouldUpdateDecorations = true @emitDidUpdateState() @@ -395,7 +396,7 @@ class TextEditorPresenter else tileState.lines[line.id] = screenRow: screenRow - words: line.words + tokens: line.tokens decorationClasses: @lineDecorationClassesForRow(screenRow) for id, line of tileState.lines @@ -1028,10 +1029,14 @@ class TextEditorPresenter @linesById.delete(lineId) buildLine: (screenRow) -> - line = {id: @lineIdCounter++, words: []} + line = {id: @lineIdCounter++, tokens: []} @tokenIterator.seekToScreenRow(screenRow) loop - line.words.push(@tokenIterator.getText()) + line.tokens.push({ + text: @tokenIterator.getText(), + closeTags: @tokenIterator.getCloseTags(), + openTags: @tokenIterator.getOpenTags() + }) break unless @tokenIterator.moveToSuccessor() break unless @tokenIterator.getStartScreenPosition().row is screenRow line