From 50e045212b5da21fed3ef3cae5c15b4b475e5be9 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 26 Mar 2014 13:57:04 -0700 Subject: [PATCH 1/3] Measure the rendered char width instead of the buffer char MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If invisibles are turned on, the buffer char and the rendered char may differ in size. For example, if `☃` is used as the tab invisible its width is probably larger than the width of a `\t` Closes #1724 --- src/editor-view.coffee | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/editor-view.coffee b/src/editor-view.coffee index 2a28b6d83..2be2aca2a 100644 --- a/src/editor-view.coffee +++ b/src/editor-view.coffee @@ -1338,14 +1338,17 @@ class EditorView extends View return 0 if screenColumn == 0 tokenizedLine = @editor.displayBuffer.lineForRow(screenRow) + textContent = lineElement.textContent left = 0 index = 0 for token in tokenizedLine.tokens - for char in token.value + for bufferChar in token.value return left if index >= screenColumn - val = @getCharacterWidthCache(token.scopes, char) + # Invisibles might cause renderedChar to be different than bufferChar + renderedChar = textContent[index] + val = @getCharacterWidthCache(token.scopes, renderedChar) if val? left += val else From c46238f7951daa3c765376f1ee40a063c809478c Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 26 Mar 2014 13:57:12 -0700 Subject: [PATCH 2/3] Add spec --- spec/editor-view-spec.coffee | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/editor-view-spec.coffee b/spec/editor-view-spec.coffee index 26c52dbb5..4a800ce2d 100644 --- a/spec/editor-view-spec.coffee +++ b/spec/editor-view-spec.coffee @@ -2894,6 +2894,21 @@ describe "EditorView", -> for rowNumber in [1..5] expect(editorView.lineElementForScreenRow(rowNumber).text()).toBe buffer.lineForRow(rowNumber) + it "correctly calculates the position left for non-monospaced invisibles", -> + window.debugContent = true + editorView.setShowInvisibles(true) + editorView.setInvisibles tab: '♘' + editor.setText('\tx') + + editorView.setFontFamily('serif') + editorView.setFontSize(10) + editorView.attachToDom() + editorView.setWidthInChars(5) + + expect(editorView.pixelPositionForScreenPosition([0, 0]).left).toEqual 0 + expect(editorView.pixelPositionForScreenPosition([0, 1]).left).toEqual 10 + expect(editorView.pixelPositionForScreenPosition([0, 2]).left).toEqual 13 + describe "when the window is resized", -> it "updates the active edit session with the current soft wrap column", -> editorView.attachToDom() From aa02bc1aaf4d07fb0b40fec4442a0746fe7302b5 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 26 Mar 2014 14:16:24 -0700 Subject: [PATCH 3/3] Remove window.debugContent Whoops! --- spec/editor-view-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/editor-view-spec.coffee b/spec/editor-view-spec.coffee index 4a800ce2d..ab3b1a99d 100644 --- a/spec/editor-view-spec.coffee +++ b/spec/editor-view-spec.coffee @@ -2895,7 +2895,6 @@ describe "EditorView", -> expect(editorView.lineElementForScreenRow(rowNumber).text()).toBe buffer.lineForRow(rowNumber) it "correctly calculates the position left for non-monospaced invisibles", -> - window.debugContent = true editorView.setShowInvisibles(true) editorView.setInvisibles tab: '♘' editor.setText('\tx')