Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Don't construct buffer lines in getClipColumnDelta
Browse files Browse the repository at this point in the history
If a buffer has extremely long lines, calling getLineForRow to build a 
JS string for the line can be extremely expensive. Instead, we just 
index into the buffer one character at a time.

Co-Authored-By: Rafael Oleza <rafeca@users.noreply.github.com>
  • Loading branch information
Nathan Sobo and rafeca committed Jun 7, 2019
1 parent a6ac229 commit 695de0b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"mkdirp": "^0.5.1",
"pathwatcher": "8.0.2",
"serializable": "^1.0.3",
"superstring": "2.3.6",
"superstring": "2.4.0",
"underscore-plus": "^1.0.0"
},
"standard": {
Expand Down
25 changes: 12 additions & 13 deletions src/display-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,12 +542,11 @@ class DisplayLayer {
}

getClipColumnDelta (bufferPosition, clipDirection) {
var {row: bufferRow, column: bufferColumn} = bufferPosition
var bufferLine = this.buffer.lineForRow(bufferRow)
var {row, column} = bufferPosition

// Treat paired unicode characters as atomic...
var previousCharacter = bufferLine[bufferColumn - 1]
var character = bufferLine[bufferColumn]
var character = this.buffer.getCharacterAtPosition(bufferPosition)
var previousCharacter = this.buffer.getCharacterAtPosition([row, column - 1])
if (previousCharacter && character && isCharacterPair(previousCharacter, character)) {
if (clipDirection === 'closest' || clipDirection === 'backward') {
return -1
Expand All @@ -560,27 +559,27 @@ class DisplayLayer {

if (!this.atomicSoftTabs) return 0

if (bufferColumn * this.ratioForCharacter(' ') > this.softWrapColumn) {
if (column * this.ratioForCharacter(' ') > this.softWrapColumn) {
return 0
}

for (let column = bufferColumn; column >= 0; column--) {
if (bufferLine[column] !== ' ') return 0
for (let position = {row, column}; position.column >= 0; position.column--) {
if (this.buffer.getCharacterAtPosition(position) !== ' ') return 0
}

var previousTabStop = bufferColumn - (bufferColumn % this.tabLength)
if (bufferColumn === previousTabStop) return 0
var previousTabStop = column - (column % this.tabLength)
if (column === previousTabStop) return 0
var nextTabStop = previousTabStop + this.tabLength

// If there is a non-whitespace character before the next tab stop,
// don't this whitespace as a soft tab
for (let column = bufferColumn; column < nextTabStop; column++) {
if (bufferLine[column] !== ' ') return 0
for (let position = {row, column}; position.column < nextTabStop; position.column++) {
if (this.buffer.getCharacterAtPosition(position) !== ' ') return 0
}

var clippedColumn
if (clipDirection === 'closest') {
if (bufferColumn - previousTabStop > this.tabLength / 2) {
if (column - previousTabStop > this.tabLength / 2) {
clippedColumn = nextTabStop
} else {
clippedColumn = previousTabStop
Expand All @@ -591,7 +590,7 @@ class DisplayLayer {
clippedColumn = nextTabStop
}

return clippedColumn - bufferColumn
return clippedColumn - column
}

getText (startRow, endRow) {
Expand Down
4 changes: 4 additions & 0 deletions src/text-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,10 @@ class TextBuffer {
return this.cachedText
}

getCharacterAtPosition (position) {
return this.buffer.getCharacterAtPosition(Point.fromObject(position))
}

// Public: Get the text in a range.
//
// * `range` A {Range}
Expand Down

0 comments on commit 695de0b

Please # to comment.