     else
       column
 
-  screenColumnForBufferColumn: (bufferColumn, options) ->
-    bufferColumn = bufferColumn - @startBufferColumn
+  screenColumnForBufferColumn: (targetBufferColumn, options) ->
+    bufferColumn = @startBufferColumn
     screenColumn = 0
-    currentBufferColumn = 0
-    for token in @tokens
-      break if currentBufferColumn + token.bufferDelta > bufferColumn
-      screenColumn += token.screenDelta
-      currentBufferColumn += token.bufferDelta
-    @clipScreenColumn(screenColumn + (bufferColumn - currentBufferColumn))
-
-  bufferColumnForScreenColumn: (screenColumn, options) ->
+    for tag, index in @tags
+      if tag > 0
+        switch @specialTokens[index]
+          when HardTab
+            bufferDelta = 1
+            screenDelta = tag
+          when SoftWrapIndent
+            bufferDelta = 0
+            screenDelta = tag
+          else
+            bufferDelta = screenDelta = tag
+
+        nextBufferColumn = bufferColumn + bufferDelta
+        if nextBufferColumn > targetBufferColumn
+          overshoot = targetBufferColumn - bufferColumn
+          bufferColumn += overshoot
+          screenColumn += Math.min(screenDelta, overshoot)
+          break
+        else
+          bufferColumn = nextBufferColumn
+          screenColumn += screenDelta
+
+    screenColumn
+
+  bufferColumnForScreenColumn: (targetScreenColumn) ->
     bufferColumn = @startBufferColumn
-    currentScreenColumn = 0
-    for token in @tokens
-      break if currentScreenColumn + token.screenDelta > screenColumn
-      bufferColumn += token.bufferDelta
-      currentScreenColumn += token.screenDelta
-    bufferColumn + (screenColumn - currentScreenColumn)
+    screenColumn = 0
+    for tag, index in @tags
+      if tag > 0
+        switch @specialTokens[index]
+          when HardTab
+            bufferDelta = 1
+            screenDelta = tag
+          when SoftWrapIndent
+            bufferDelta = 0
+            screenDelta = tag
+          else
+            bufferDelta = screenDelta = tag
+
+        nextScreenColumn = screenColumn + screenDelta
+        if nextScreenColumn > targetScreenColumn
+          overshoot = targetScreenColumn - screenColumn
+          screenColumn += overshoot
+          bufferColumn += Math.min(bufferDelta, overshoot)
+          break
+        else
+          screenColumn = nextScreenColumn
+          bufferColumn += bufferDelta
+
+    bufferColumn
 
   getMaxScreenColumn: ->
     if @fold


      return maxColumn

  buildSoftWrapIndentationTokens: (token, hangingIndent) ->
    totalIndentSpaces = (@indentLevel * @tabLength) + hangingIndent
    indentTokens = []
    while totalIndentSpaces > 0
      tokenLength = Math.min(@tabLength, totalIndentSpaces)
      indentToken = token.buildSoftWrapIndentationToken(tokenLength)
      indentTokens.push(indentToken)
      totalIndentSpaces -= tokenLength

    indentTokens

  softWrapAt: (column, hangingIndent) ->
    return [null, this] if column is 0


        when PairedCharacter
          tokenProperties.isAtomic = true
          tokenProperties.hasPairedCharacter = true
        when SoftWrapIndent
          tokenProperties.isAtomic = true
          tokenProperties.isSoftWrapIndentation = true

      if offset < @firstNonWhitespaceIndex
        tokenProperties.firstNonWhitespaceIndex =
