     unless existingLineElement
       lineElement = @buildLineElementForScreenRow(actualRow)
       @renderedLines.append(lineElement)
-    left = @positionLeftForLineAndColumn(lineElement, column)
+    left = @positionLeftForLineAndColumn(lineElement, actualRow, column)
     unless existingLineElement
       @renderedLines[0].removeChild(lineElement)
     { top: row * @lineHeight, left }
 
-  positionLeftForLineAndColumn: (lineElement, column) ->
-    lineCache = @pixelLeftCache.get(lineElement)
-    @pixelLeftCache.set(lineElement, lineCache = {}) unless lineCache?
-
-    return lineCache[column] if lineCache[column]?
-
-    delta = 0
-    iterator = document.createNodeIterator(lineElement, NodeFilter.SHOW_TEXT, acceptNode: -> NodeFilter.FILTER_ACCEPT)
+  positionLeftForLineAndColumn: (lineElement, screenRow, column) ->
+    return 0 if column == 0
+
+    bufferRow = @bufferRowsForScreenRows(screenRow)[0] ? screenRow
+    tokenizedLine = @activeEditSession.displayBuffer.tokenizedBuffer.tokenizedLines[bufferRow]
+
+    left = 0
+    index = 0
+    for token in tokenizedLine.tokens
+      for char in token.value
+        return left if index >= column
+
+        val = @checkCharacterWidthCache(token.scopes, char)
+        if val?
+          left += val
+        else
+          return @measureToColumn(lineElement, tokenizedLine, column)
+
+        index++
+    left
+
+  scopesForColumn: (tokenizedLine, column) ->
+    index = 0
+    for token in tokenizedLine.tokens
+      for char in token.value
+        return token.scopes if index == column
+        index++
+    null
+
+  measureToColumn: (lineElement, tokenizedLine, column) ->
+    left = oldLeft = index = 0
+    iterator = document.createNodeIterator(lineElement, NodeFilter.SHOW_TEXT, TEXT_NODE_FILTER)
+
+    returnLeft = null
+
     while textNode = iterator.nextNode()
-      nextDelta = delta + textNode.textContent.length
-      if nextDelta >= column
-        offset = column - delta
-        break
-      delta = nextDelta
-
-    MEASURE_RANGE.setEnd(textNode, offset)
-    MEASURE_RANGE.collapse()
-    left = MEASURE_RANGE.getClientRects()[0].left - Math.floor(@scrollView.offset().left) + Math.floor(@scrollLeft())
-
-    lineCache[column] = left
-    left
+      content = textNode.textContent
+
+      for char, i in content
+
+        # Dont return right away, finish caching the whole line
+        returnLeft = left if index == column
+        oldLeft = left
+
+        scopes = @scopesForColumn(tokenizedLine, index)
+        cachedVal = @checkCharacterWidthCache(scopes, char)
+
+        if cachedVal?
+          left = oldLeft + cachedVal
+        else
+          # i + 1 to measure to the end of the current character
+          MEASURE_RANGE.setEnd(textNode, i + 1)
+          MEASURE_RANGE.collapse()
+          left = MEASURE_RANGE.getClientRects()[0].left - Math.floor(@scrollView.offset().left) + Math.floor(@scrollLeft())
+
+          @setCharacterWidthCache(scopes, char, left - oldLeft) if scopes?
+
+        index++
+
+    returnLeft ? left
+
+  checkCharacterWidthCache: (scopes, char) ->
+    scopes ?= NO_SCOPE
+    obj = Editor.characterWidthCache
+    for scope in scopes
+      obj = obj[scope]
+      return null unless obj?
+    obj[char]
+
+  setCharacterWidthCache: (scopes, char, val) ->
+    scopes ?= NO_SCOPE
+    obj = Editor.characterWidthCache
+    for scope in scopes
+      obj[scope] ?= {}
+      obj = obj[scope]
+    obj[char] = val
+
+  clearCharacterWidthCache: ->
+    Editor.characterWidthCache = {}
 
   pixelOffsetForScreenPosition: (position) ->
     {top, left} = @pixelPositionForScreenPosition(position)

  # fontSize - A {Number} indicating the font size in pixels.
  setFontSize: (fontSize) ->
    @css('font-size', "#{fontSize}px}")
    if @isOnDom()
      @redraw()
    else

        currentLine = clearLine(currentLine)

  clearLine: (lineElement) =>
    next = lineElement.nextSibling
    @renderedLines[0].removeChild(lineElement)
    next
