mirror of
https://github.com/atom/atom.git
synced 2026-01-24 14:28:14 -05:00
Merge pull request #1297 from atom/bo-diff-reload
Apply text to buffer via diff on reload
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
"clear-cut": "0.2.0",
|
||||
"coffee-script": "1.6.3",
|
||||
"coffeestack": "0.6.0",
|
||||
"diff": "git://github.com/benogle/jsdiff.git",
|
||||
"emissary": "0.19.0",
|
||||
"first-mate": "0.5.0",
|
||||
"fs-plus": "0.11.0",
|
||||
|
||||
@@ -113,10 +113,17 @@ describe 'TextBuffer', ->
|
||||
|
||||
runs ->
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
expect(event.oldRange).toEqual [[0, 0], [0, 5]]
|
||||
expect(event.oldRange).toEqual [[0, 0], [0, 0]]
|
||||
expect(event.newRange).toEqual [[0, 0], [0, 6]]
|
||||
expect(event.oldText).toBe "first"
|
||||
expect(event.oldText).toBe ""
|
||||
expect(event.newText).toBe "second"
|
||||
|
||||
[event] = changeHandler.argsForCall[1]
|
||||
expect(event.oldRange).toEqual [[0, 6], [0, 11]]
|
||||
expect(event.newRange).toEqual [[0, 6], [0, 6]]
|
||||
expect(event.oldText).toBe "first"
|
||||
expect(event.newText).toBe ""
|
||||
|
||||
expect(buffer.isModified()).toBeFalsy()
|
||||
|
||||
describe "when the buffer's memory contents differ from the *previous* disk contents", ->
|
||||
@@ -454,6 +461,68 @@ describe 'TextBuffer', ->
|
||||
expect(event.oldRange).toEqual expectedPreRange
|
||||
expect(event.newRange).toEqual [[0, 0], [1, 14]]
|
||||
|
||||
describe ".setTextViaDiff(text)", ->
|
||||
it "can change the entire contents of the buffer when there are no newlines", ->
|
||||
buffer.setText('BUFFER CHANGE')
|
||||
newText = 'DISK CHANGE'
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
describe "with standard newlines", ->
|
||||
it "can change the entire contents of the buffer with no newline at the end", ->
|
||||
newText = "I know you are.\nBut what am I?"
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "can change the entire contents of the buffer with a newline at the end", ->
|
||||
newText = "I know you are.\nBut what am I?\n"
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "can change a few lines at the beginning in the buffer", ->
|
||||
newText = buffer.getText().replace(/function/g, 'omgwow')
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "can change a few lines in the middle of the buffer", ->
|
||||
newText = buffer.getText().replace(/shift/g, 'omgwow')
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "can adds a newline at the end", ->
|
||||
newText = buffer.getText() + '\n'
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
describe "with windows newlines", ->
|
||||
beforeEach ->
|
||||
buffer.setText(buffer.getText().replace(/\n/g, '\r\n'))
|
||||
|
||||
it "adds a newline at the end", ->
|
||||
newText = buffer.getText() + '\r\n'
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "changes the entire contents of the buffer with smaller content with no newline at the end", ->
|
||||
newText = "I know you are.\r\nBut what am I?"
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "changes the entire contents of the buffer with smaller content with newline at the end", ->
|
||||
newText = "I know you are.\r\nBut what am I?\r\n"
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "changes a few lines at the beginning in the buffer", ->
|
||||
newText = buffer.getText().replace(/function/g, 'omgwow')
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
it "changes a few lines in the middle of the buffer", ->
|
||||
newText = buffer.getText().replace(/shift/g, 'omgwow')
|
||||
buffer.setTextViaDiff(newText)
|
||||
expect(buffer.getText()).toBe newText
|
||||
|
||||
describe ".save()", ->
|
||||
saveBuffer = null
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
_ = require 'underscore-plus'
|
||||
diff = require 'diff'
|
||||
Q = require 'q'
|
||||
{P} = require 'scandal'
|
||||
telepath = require 'telepath'
|
||||
@@ -133,7 +134,7 @@ class TextBuffer extends telepath.Model
|
||||
# Sets the buffer's content to the cached disk contents
|
||||
reload: ->
|
||||
@emit 'will-reload'
|
||||
@setText(@cachedDiskContents)
|
||||
@setTextViaDiff(@cachedDiskContents)
|
||||
@emitModifiedStatusChanged(false)
|
||||
@emit 'reloaded'
|
||||
|
||||
@@ -198,6 +199,52 @@ class TextBuffer extends telepath.Model
|
||||
setText: (text) ->
|
||||
@change(@getRange(), text, normalizeLineEndings: false)
|
||||
|
||||
# Private: Replaces the current buffer contents. Only apply the differences.
|
||||
#
|
||||
# text - A {String} containing the new buffer contents.
|
||||
setTextViaDiff: (text) ->
|
||||
currentText = @getText()
|
||||
return if currentText == text
|
||||
|
||||
endsWithNewline = (str) ->
|
||||
/[\r\n]+$/g.test(str)
|
||||
|
||||
computeBufferColumn = (str) ->
|
||||
newlineIndex = Math.max(str.lastIndexOf('\n'), str.lastIndexOf('\r'))
|
||||
if endsWithNewline(str)
|
||||
0
|
||||
else if newlineIndex == -1
|
||||
str.length
|
||||
else
|
||||
str.length - newlineIndex - 1
|
||||
|
||||
@transact =>
|
||||
row = 0
|
||||
column = 0
|
||||
currentPosition = [0, 0]
|
||||
|
||||
lineDiff = diff.diffLines(currentText, text)
|
||||
changeOptions = normalizeLineEndings: false
|
||||
|
||||
for change in lineDiff
|
||||
lineCount = change.value.match(/\n/g)?.length ? 0
|
||||
currentPosition[0] = row
|
||||
currentPosition[1] = column
|
||||
|
||||
if change.added
|
||||
@change([currentPosition, currentPosition], change.value, changeOptions)
|
||||
row += lineCount
|
||||
column = computeBufferColumn(change.value)
|
||||
|
||||
else if change.removed
|
||||
endRow = row + lineCount
|
||||
endColumn = column + computeBufferColumn(change.value)
|
||||
@change([currentPosition, [endRow, endColumn]], '', changeOptions)
|
||||
|
||||
else
|
||||
row += lineCount
|
||||
column = computeBufferColumn(change.value)
|
||||
|
||||
# Gets the range of the buffer contents.
|
||||
#
|
||||
# Returns a new {Range}, from `[0, 0]` to the end of the buffer.
|
||||
|
||||
Reference in New Issue
Block a user