mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
Update textbuffer
This commit is contained in:
@@ -8,7 +8,7 @@ UndoManager = require 'undo-manager'
|
||||
BufferChangeOperation = require 'buffer-change-operation'
|
||||
BufferMarker = require 'buffer-marker'
|
||||
|
||||
# Public: Represents the contents of a file.
|
||||
# Represents the contents of a file.
|
||||
#
|
||||
# The `Buffer` is often associated with a {File}. However, this is not always
|
||||
# the case, as a `Buffer` could be an unsaved chunk of text.
|
||||
@@ -29,7 +29,7 @@ class Buffer
|
||||
invalidMarkers: null
|
||||
refcount: 0
|
||||
|
||||
# Public: Creates a new buffer.
|
||||
# Creates a new buffer.
|
||||
#
|
||||
# path - A {String} representing the file path
|
||||
# initialText - A {String} setting the starting text
|
||||
@@ -95,17 +95,17 @@ class Buffer
|
||||
|
||||
@file.on "moved", =>
|
||||
@trigger "path-changed", this
|
||||
|
||||
|
||||
### Public ###
|
||||
|
||||
# Public: Identifies if the buffer belongs to multiple editors.
|
||||
# Identifies if the buffer belongs to multiple editors.
|
||||
#
|
||||
# For example, if the {Editor} was split.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
# Returns a {Boolean}.
|
||||
hasMultipleEditors: -> @refcount > 1
|
||||
|
||||
# Public: Reloads a file in the {EditSession}.
|
||||
# Reloads a file in the {EditSession}.
|
||||
#
|
||||
# Essentially, this performs a force read of the file.
|
||||
reload: ->
|
||||
@@ -115,25 +115,25 @@ class Buffer
|
||||
@triggerModifiedStatusChanged(false)
|
||||
@trigger 'reloaded'
|
||||
|
||||
# Public: Rereads the contents of the file, and stores them in the cache.
|
||||
# Rereads the contents of the file, and stores them in the cache.
|
||||
#
|
||||
# Essentially, this performs a force read of the file on disk.
|
||||
updateCachedDiskContents: ->
|
||||
@cachedDiskContents = @file.read()
|
||||
|
||||
# Public: Gets the file's basename--that is, the file without any directory information.
|
||||
# Gets the file's basename--that is, the file without any directory information.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getBaseName: ->
|
||||
@file?.getBaseName()
|
||||
|
||||
# Public: Retrieves the path for the file.
|
||||
# Retrieves the path for the file.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getPath: ->
|
||||
@file?.getPath()
|
||||
|
||||
# Public: Sets the path for the file.
|
||||
# Sets the path for the file.
|
||||
#
|
||||
# path - A {String} representing the new file path
|
||||
setPath: (path) ->
|
||||
@@ -146,7 +146,7 @@ class Buffer
|
||||
|
||||
@trigger "path-changed", this
|
||||
|
||||
# Public: Retrieves the current buffer's file extension.
|
||||
# Retrieves the current buffer's file extension.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getExtension: ->
|
||||
@@ -155,25 +155,25 @@ class Buffer
|
||||
else
|
||||
null
|
||||
|
||||
# Public: Retrieves the cached buffer contents.
|
||||
# Retrieves the cached buffer contents.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getText: ->
|
||||
@cachedMemoryContents ?= @getTextInRange(@getRange())
|
||||
|
||||
# Public: Replaces the current buffer contents.
|
||||
# Replaces the current buffer contents.
|
||||
#
|
||||
# text - A {String} containing the new buffer contents.
|
||||
setText: (text) ->
|
||||
@change(@getRange(), text, normalizeLineEndings: false)
|
||||
|
||||
# Public: Gets the range of the buffer contents.
|
||||
# Gets the range of the buffer contents.
|
||||
#
|
||||
# Returns a new {Range}, from `[0, 0]` to the end of the buffer.
|
||||
getRange: ->
|
||||
new Range([0, 0], [@getLastRow(), @getLastLine().length])
|
||||
|
||||
# Public: Given a range, returns the lines of text within it.
|
||||
# Given a range, returns the lines of text within it.
|
||||
#
|
||||
# range - A {Range} object specifying your points of interest
|
||||
#
|
||||
@@ -193,13 +193,13 @@ class Buffer
|
||||
|
||||
return multipleLines.join ''
|
||||
|
||||
# Public: Gets all the lines in a file.
|
||||
# Gets all the lines in a file.
|
||||
#
|
||||
# Returns an {Array} of {String}s.
|
||||
getLines: ->
|
||||
@lines
|
||||
|
||||
# Public: Given a row, returns the line of text.
|
||||
# Given a row, returns the line of text.
|
||||
#
|
||||
# row - A {Number} indicating the row.
|
||||
#
|
||||
@@ -213,7 +213,7 @@ class Buffer
|
||||
suggestedLineEndingForRow: (row) ->
|
||||
@lineEndingForRow(row) ? @lineEndingForRow(row - 1)
|
||||
|
||||
# Public: Given a row, returns the length of the line of text.
|
||||
# Given a row, returns the length of the line of text.
|
||||
#
|
||||
# row - A {Number} indicating the row.
|
||||
#
|
||||
@@ -224,10 +224,10 @@ class Buffer
|
||||
lineEndingLengthForRow: (row) ->
|
||||
(@lineEndingForRow(row) ? '').length
|
||||
|
||||
# Public: Given a buffer row, this retrieves the range for that line.
|
||||
# Given a buffer row, this retrieves the range for that line.
|
||||
#
|
||||
# row - A {Number} identifying the row
|
||||
# options - A hash with one key, `includeNewline`, which specifies whether you
|
||||
# options - A hash with one key, `includeNewline`, which specifies whether you
|
||||
# want to include the trailing newline
|
||||
#
|
||||
# Returns a {Range}.
|
||||
@@ -237,25 +237,25 @@ class Buffer
|
||||
else
|
||||
new Range([row, 0], [row, @lineLengthForRow(row)])
|
||||
|
||||
# Public: Gets the number of lines in a file.
|
||||
# Gets the number of lines in a file.
|
||||
#
|
||||
# Returns a {Number}.
|
||||
getLineCount: ->
|
||||
@getLines().length
|
||||
|
||||
# Public: Gets the row number of the last line.
|
||||
# Gets the row number of the last line.
|
||||
#
|
||||
# Returns a {Number}.
|
||||
getLastRow: ->
|
||||
@getLines().length - 1
|
||||
|
||||
# Public: Finds the last line in the current buffer.
|
||||
# Finds the last line in the current buffer.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getLastLine: ->
|
||||
@lineForRow(@getLastRow())
|
||||
|
||||
# Public: Finds the last point in the current buffer.
|
||||
# Finds the last point in the current buffer.
|
||||
#
|
||||
# Returns a {Point} representing the last position.
|
||||
getEofPosition: ->
|
||||
@@ -278,13 +278,13 @@ class Buffer
|
||||
|
||||
new Point(row, index)
|
||||
|
||||
# Public: Given a row, this deletes it from the buffer.
|
||||
# Given a row, this deletes it from the buffer.
|
||||
#
|
||||
# row - A {Number} representing the row to delete
|
||||
deleteRow: (row) ->
|
||||
@deleteRows(row, row)
|
||||
|
||||
# Public: Deletes a range of rows from the buffer.
|
||||
# Deletes a range of rows from the buffer.
|
||||
#
|
||||
# start - A {Number} representing the starting row
|
||||
# end - A {Number} representing the ending row
|
||||
@@ -303,36 +303,29 @@ class Buffer
|
||||
|
||||
@delete(new Range(startPoint, endPoint))
|
||||
|
||||
# Public: Adds text to the end of the buffer.
|
||||
# Adds text to the end of the buffer.
|
||||
#
|
||||
# text - A {String} of text to add
|
||||
append: (text) ->
|
||||
@insert(@getEofPosition(), text)
|
||||
|
||||
# Public: Adds text to a specific point in the buffer
|
||||
# Adds text to a specific point in the buffer
|
||||
#
|
||||
# point - A {Point} in the buffer to insert into
|
||||
# text - A {String} of text to add
|
||||
insert: (point, text) ->
|
||||
@change(new Range(point, point), text)
|
||||
|
||||
# Public: Deletes text from the buffer
|
||||
# Deletes text from the buffer
|
||||
#
|
||||
# range - A {Range} whose text to delete
|
||||
delete: (range) ->
|
||||
@change(range, '')
|
||||
|
||||
# Internal:
|
||||
change: (oldRange, newText, options) ->
|
||||
oldRange = Range.fromObject(oldRange)
|
||||
operation = new BufferChangeOperation({buffer: this, oldRange, newText, options})
|
||||
range = @pushOperation(operation)
|
||||
range
|
||||
|
||||
# Public: Given a position, this clips it to a real position.
|
||||
# Given a position, this clips it to a real position.
|
||||
#
|
||||
# For example, if `position`'s row exceeds the row count of the buffer,
|
||||
# or if its column goes beyond a line's length, this "sanitizes" the value
|
||||
# or if its column goes beyond a line's length, this "sanitizes" the value
|
||||
# to a real position.
|
||||
#
|
||||
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
|
||||
@@ -346,11 +339,11 @@ class Buffer
|
||||
column = Math.max(position.column, 0)
|
||||
column = Math.min(@lineLengthForRow(row), column)
|
||||
new Point(row, column)
|
||||
|
||||
# Public: Given a range, this clips it to a real range.
|
||||
|
||||
# Given a range, this clips it to a real range.
|
||||
#
|
||||
# For example, if `range`'s row exceeds the row count of the buffer,
|
||||
# or if its column goes beyond a line's length, this "sanitizes" the value
|
||||
# or if its column goes beyond a line's length, this "sanitizes" the value
|
||||
# to a real range.
|
||||
#
|
||||
# range - The {Point} to clip
|
||||
@@ -364,33 +357,23 @@ class Buffer
|
||||
prefix: @lines[range.start.row][0...range.start.column]
|
||||
suffix: @lines[range.end.row][range.end.column..]
|
||||
|
||||
# Internal:
|
||||
pushOperation: (operation, editSession) ->
|
||||
if @undoManager
|
||||
@undoManager.pushOperation(operation, editSession)
|
||||
else
|
||||
operation.do()
|
||||
|
||||
# Internal:
|
||||
transact: (fn) -> @undoManager.transact(fn)
|
||||
|
||||
# Public: Undos the last operation.
|
||||
# Undos the last operation.
|
||||
#
|
||||
# editSession - The {EditSession} associated with the buffer.
|
||||
undo: (editSession) -> @undoManager.undo(editSession)
|
||||
|
||||
# Public: Redos the last operation.
|
||||
# Redos the last operation.
|
||||
#
|
||||
# editSession - The {EditSession} associated with the buffer.
|
||||
redo: (editSession) -> @undoManager.redo(editSession)
|
||||
commit: -> @undoManager.commit()
|
||||
abort: -> @undoManager.abort()
|
||||
|
||||
# Public: Saves the buffer.
|
||||
# Saves the buffer.
|
||||
save: ->
|
||||
@saveAs(@getPath()) if @isModified()
|
||||
|
||||
# Public: Saves the buffer at a specific path.
|
||||
# Saves the buffer at a specific path.
|
||||
#
|
||||
# path - The path to save at.
|
||||
saveAs: (path) ->
|
||||
@@ -403,7 +386,7 @@ class Buffer
|
||||
@triggerModifiedStatusChanged(false)
|
||||
@trigger 'saved'
|
||||
|
||||
# Public: Identifies if the buffer was modified.
|
||||
# Identifies if the buffer was modified.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
isModified: ->
|
||||
@@ -412,12 +395,12 @@ class Buffer
|
||||
else
|
||||
not @isEmpty()
|
||||
|
||||
# Public: Identifies if a buffer is in a git conflict with `HEAD`.
|
||||
# Identifies if a buffer is in a git conflict with `HEAD`.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
isInConflict: -> @conflict
|
||||
|
||||
# Public: Identifies if a buffer is empty.
|
||||
# Identifies if a buffer is empty.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
isEmpty: -> @lines.length is 1 and @lines[0].length is 0
|
||||
@@ -425,13 +408,13 @@ class Buffer
|
||||
getMarkers: ->
|
||||
_.values(@validMarkers)
|
||||
|
||||
# Public: Retrieves the quantity of markers in a buffer.
|
||||
# Retrieves the quantity of markers in a buffer.
|
||||
#
|
||||
# Returns a {Number}.
|
||||
getMarkerCount: ->
|
||||
_.size(@validMarkers)
|
||||
|
||||
# Public: Constructs a new marker at a given range.
|
||||
# Constructs a new marker at a given range.
|
||||
#
|
||||
# range - The marker {Range} (representing the distance between the head and tail)
|
||||
# options - Options to pass to the {BufferMarker} constructor
|
||||
@@ -446,7 +429,7 @@ class Buffer
|
||||
@validMarkers[marker.id] = marker
|
||||
marker.id
|
||||
|
||||
# Public: Constructs a new marker at a given position.
|
||||
# Constructs a new marker at a given position.
|
||||
#
|
||||
# position - The marker {Point}; there won't be a tail
|
||||
# options - Options to pass to the {BufferMarker} constructor
|
||||
@@ -455,7 +438,7 @@ class Buffer
|
||||
markPosition: (position, options) ->
|
||||
@markRange([position, position], _.defaults({noTail: true}, options))
|
||||
|
||||
# Public: Removes the marker with the given id.
|
||||
# Removes the marker with the given id.
|
||||
#
|
||||
# id - The {Number} of the ID to remove
|
||||
destroyMarker: (id) ->
|
||||
@@ -468,7 +451,7 @@ class Buffer
|
||||
setMarkerPosition: (args...) ->
|
||||
@setMarkerHeadPosition(args...)
|
||||
|
||||
# Public: Retrieves the position of the marker's head.
|
||||
# Retrieves the position of the marker's head.
|
||||
#
|
||||
# id - A {Number} representing the marker to check
|
||||
#
|
||||
@@ -476,7 +459,7 @@ class Buffer
|
||||
getMarkerHeadPosition: (id) ->
|
||||
@validMarkers[id]?.getHeadPosition()
|
||||
|
||||
# Public: Sets the position of the marker's head.
|
||||
# Sets the position of the marker's head.
|
||||
#
|
||||
# id - A {Number} representing the marker to change
|
||||
# position - The new {Point} to place the head
|
||||
@@ -488,7 +471,7 @@ class Buffer
|
||||
setMarkerHeadPosition: (id, position, options) ->
|
||||
@validMarkers[id]?.setHeadPosition(position)
|
||||
|
||||
# Public: Retrieves the position of the marker's tail.
|
||||
# Retrieves the position of the marker's tail.
|
||||
#
|
||||
# id - A {Number} representing the marker to check
|
||||
#
|
||||
@@ -496,7 +479,7 @@ class Buffer
|
||||
getMarkerTailPosition: (id) ->
|
||||
@validMarkers[id]?.getTailPosition()
|
||||
|
||||
# Public: Sets the position of the marker's tail.
|
||||
# Sets the position of the marker's tail.
|
||||
#
|
||||
# id - A {Number} representing the marker to change
|
||||
# position - The new {Point} to place the tail
|
||||
@@ -508,15 +491,15 @@ class Buffer
|
||||
setMarkerTailPosition: (id, position, options) ->
|
||||
@validMarkers[id]?.setTailPosition(position)
|
||||
|
||||
# Public: Retrieves the {Range} between a marker's head and its tail.
|
||||
#
|
||||
# Retrieves the {Range} between a marker's head and its tail.
|
||||
#
|
||||
# id - A {Number} representing the marker to check
|
||||
#
|
||||
# Returns a {Range}.
|
||||
getMarkerRange: (id) ->
|
||||
@validMarkers[id]?.getRange()
|
||||
|
||||
# Public: Sets the marker's range, potentialy modifying both its head and tail.
|
||||
# Sets the marker's range, potentialy modifying both its head and tail.
|
||||
#
|
||||
# id - A {Number} representing the marker to change
|
||||
# range - The new {Range} the marker should cover
|
||||
@@ -526,7 +509,7 @@ class Buffer
|
||||
setMarkerRange: (id, range, options) ->
|
||||
@validMarkers[id]?.setRange(range, options)
|
||||
|
||||
# Public: Sets the marker's tail to the same position as the marker's head.
|
||||
# Sets the marker's tail to the same position as the marker's head.
|
||||
#
|
||||
# This only works if there isn't already a tail position.
|
||||
#
|
||||
@@ -536,13 +519,13 @@ class Buffer
|
||||
placeMarkerTail: (id) ->
|
||||
@validMarkers[id]?.placeTail()
|
||||
|
||||
# Public: Removes the tail from the marker.
|
||||
# Removes the tail from the marker.
|
||||
#
|
||||
# id - A {Number} representing the marker to change
|
||||
clearMarkerTail: (id) ->
|
||||
@validMarkers[id]?.clearTail()
|
||||
|
||||
# Public: Identifies if the ending position of a marker is greater than the starting position.
|
||||
# Identifies if the ending position of a marker is greater than the starting position.
|
||||
#
|
||||
# This can happen when, for example, you highlight text "up" in a {Buffer}.
|
||||
#
|
||||
@@ -552,7 +535,7 @@ class Buffer
|
||||
isMarkerReversed: (id) ->
|
||||
@validMarkers[id]?.isReversed()
|
||||
|
||||
# Public: Identifies if the marker's head position is equal to its tail.
|
||||
# Identifies if the marker's head position is equal to its tail.
|
||||
#
|
||||
# id - A {Number} representing the marker to check
|
||||
#
|
||||
@@ -560,14 +543,14 @@ class Buffer
|
||||
isMarkerRangeEmpty: (id) ->
|
||||
@validMarkers[id]?.isRangeEmpty()
|
||||
|
||||
# Public: Sets a callback to be fired whenever a marker is changed.
|
||||
# Sets a callback to be fired whenever a marker is changed.
|
||||
#
|
||||
# id - A {Number} representing the marker to watch
|
||||
# callback - A {Function} to execute
|
||||
observeMarker: (id, callback) ->
|
||||
@validMarkers[id]?.observe(callback)
|
||||
|
||||
# Public: Given a buffer position, this finds all markers that contain the position.
|
||||
# Given a buffer position, this finds all markers that contain the position.
|
||||
#
|
||||
# bufferPosition - A {Point} to check
|
||||
#
|
||||
@@ -579,7 +562,7 @@ class Buffer
|
||||
ids.push(id) if marker.containsPoint(bufferPosition)
|
||||
ids
|
||||
|
||||
# Public: Identifies if a character sequence is within a certain range.
|
||||
# Identifies if a character sequence is within a certain range.
|
||||
#
|
||||
# regex - The {RegExp} to check
|
||||
# startIndex - The starting row {Number}
|
||||
@@ -609,14 +592,14 @@ class Buffer
|
||||
|
||||
matches
|
||||
|
||||
# Public: Scans for text in the buffer, calling a function on each match.
|
||||
# Scans for text in the buffer, calling a function on each match.
|
||||
#
|
||||
# regex - A {RegExp} representing the text to find
|
||||
# iterator - A {Function} that's called on each match
|
||||
scan: (regex, iterator) ->
|
||||
@scanInRange(regex, @getRange(), iterator)
|
||||
|
||||
# Public: Scans for text in a given range, calling a function on each match.
|
||||
# Scans for text in a given range, calling a function on each match.
|
||||
#
|
||||
# regex - A {RegExp} representing the text to find
|
||||
# range - A {Range} in the buffer to search within
|
||||
@@ -659,7 +642,7 @@ class Buffer
|
||||
|
||||
break unless global and keepLooping
|
||||
|
||||
# Public: Scans for text in a given range _backwards_, calling a function on each match.
|
||||
# Scans for text in a given range _backwards_, calling a function on each match.
|
||||
#
|
||||
# regex - A {RegExp} representing the text to find
|
||||
# range - A {Range} in the buffer to search within
|
||||
@@ -667,7 +650,7 @@ class Buffer
|
||||
backwardsScanInRange: (regex, range, iterator) ->
|
||||
@scanInRange regex, range, iterator, true
|
||||
|
||||
# Public: Given a row, identifies if it is blank.
|
||||
# Given a row, identifies if it is blank.
|
||||
#
|
||||
# row - A row {Number} to check
|
||||
#
|
||||
@@ -675,7 +658,7 @@ class Buffer
|
||||
isRowBlank: (row) ->
|
||||
not /\S/.test @lineForRow(row)
|
||||
|
||||
# Public: Given a row, this finds the next row above it that's empty.
|
||||
# Given a row, this finds the next row above it that's empty.
|
||||
#
|
||||
# startRow - A {Number} identifying the row to start checking at
|
||||
#
|
||||
@@ -689,7 +672,7 @@ class Buffer
|
||||
return row unless @isRowBlank(row)
|
||||
null
|
||||
|
||||
# Public: Given a row, this finds the next row that's blank.
|
||||
# Given a row, this finds the next row that's blank.
|
||||
#
|
||||
# startRow - A row {Number} to check
|
||||
#
|
||||
@@ -702,7 +685,7 @@ class Buffer
|
||||
return row unless @isRowBlank(row)
|
||||
null
|
||||
|
||||
# Public: Identifies if the buffer has soft tabs anywhere.
|
||||
# Identifies if the buffer has soft tabs anywhere.
|
||||
#
|
||||
# Returns a {Boolean},
|
||||
usesSoftTabs: ->
|
||||
@@ -711,21 +694,34 @@ class Buffer
|
||||
return match[0][0] != '\t'
|
||||
undefined
|
||||
|
||||
# Public: Checks out the current `HEAD` revision of the file.
|
||||
# Checks out the current `HEAD` revision of the file.
|
||||
checkoutHead: ->
|
||||
path = @getPath()
|
||||
return unless path
|
||||
git?.checkoutHead(path)
|
||||
|
||||
# Public: Checks to see if a file exists.
|
||||
# Checks to see if a file exists.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
fileExists: ->
|
||||
@file? && @file.exists()
|
||||
|
||||
|
||||
### Internal ###
|
||||
|
||||
change: (oldRange, newText, options) ->
|
||||
oldRange = Range.fromObject(oldRange)
|
||||
operation = new BufferChangeOperation({buffer: this, oldRange, newText, options})
|
||||
range = @pushOperation(operation)
|
||||
range
|
||||
|
||||
pushOperation: (operation, editSession) ->
|
||||
if @undoManager
|
||||
@undoManager.pushOperation(operation, editSession)
|
||||
else
|
||||
operation.do()
|
||||
|
||||
transact: (fn) -> @undoManager.transact(fn)
|
||||
|
||||
scheduleModifiedEvents: ->
|
||||
clearTimeout(@stoppedChangingTimeout) if @stoppedChangingTimeout
|
||||
stoppedChangingCallback = =>
|
||||
|
||||
Reference in New Issue
Block a user