Get it to a proper 80%

This commit is contained in:
Garen Torikian
2013-04-18 18:50:22 -07:00
parent 5d7b4ec04b
commit 5ee388cede
24 changed files with 792 additions and 102 deletions

View File

@@ -5,6 +5,11 @@ _ = require 'underscore'
$ = require 'jquery'
CSON = require 'cson'
###
# Internal: Loads and resolves packages. #
###
module.exports =
class AtomPackage extends Package
metadata: null

View File

@@ -5,6 +5,10 @@ fsUtils = require 'fs-utils'
Specificity = require 'specificity'
PEG = require 'pegjs'
###
# Internal #
###
module.exports =
class BindingSet

View File

@@ -1,6 +1,10 @@
Range = require 'range'
_ = require 'underscore'
###
# Internal #
###
module.exports =
class BufferChangeOperation
buffer: null

View File

@@ -10,10 +10,23 @@ class BufferMarker
suppressObserverNotification: false
invalidationStrategy: null
###
# Internal #
###
constructor: ({@id, @buffer, range, @invalidationStrategy, noTail, reverse}) ->
@invalidationStrategy ?= 'contains'
@setRange(range, {noTail, reverse})
###
# Public #
###
# Public: Sets the marker's range, potentialy modifying both its head and tail.
#
# range - The new {Range} the marker should cover
# options - A hash of options with the following keys:
# :reverse - if `true`, the marker is reversed; that is, its tail is "above" the head
# :noTail - if `true`, the marker doesn't have a tail
setRange: (range, options={}) ->
@consolidateObserverNotifications false, =>
range = Range.fromObject(range)
@@ -32,19 +45,39 @@ class BufferMarker
isReversed: ->
@tailPosition? and @headPosition.isLessThan(@tailPosition)
# Public: Identifies if the marker's head position is equal to its tail.
#
# Returns a {Boolean}.
isRangeEmpty: ->
@getHeadPosition().isEqual(@getTailPosition())
# Public: Retrieves the {Range} between a marker's head and its tail.
#
# Returns a {Range}.
getRange: ->
if @tailPosition
new Range(@tailPosition, @headPosition)
else
new Range(@headPosition, @headPosition)
# Public: Retrieves the position of the marker's head.
#
# Returns a {Point}.
getHeadPosition: -> @headPosition
# Public: Retrieves the position of the marker's tail.
#
# Returns a {Point}.
getTailPosition: -> @tailPosition ? @getHeadPosition()
# Public: Sets the position of the marker's head.
#
# newHeadPosition - The new {Point} to place the head
# options - A hash with the following keys:
# :clip - if `true`, the point is [clipped]{Buffer.clipPosition}
# :bufferChanged - if `true`, indicates that the {Buffer} should trigger an event that it's changed
#
# Returns a {Point} representing the new head position.
setHeadPosition: (newHeadPosition, options={}) ->
oldHeadPosition = @getHeadPosition()
newHeadPosition = Point.fromObject(newHeadPosition)
@@ -55,6 +88,14 @@ class BufferMarker
@notifyObservers({oldHeadPosition, newHeadPosition, bufferChanged})
@headPosition
# Public: Sets the position of the marker's tail.
#
# newHeadPosition - The new {Point} to place the tail
# options - A hash with the following keys:
# :clip - if `true`, the point is [clipped]{Buffer.clipPosition}
# :bufferChanged - if `true`, indicates that the {Buffer} should trigger an event that it's changed
#
# Returns a {Point} representing the new tail position.
setTailPosition: (newTailPosition, options={}) ->
oldTailPosition = @getTailPosition()
newTailPosition = Point.fromObject(newTailPosition)
@@ -65,21 +106,52 @@ class BufferMarker
@notifyObservers({oldTailPosition, newTailPosition, bufferChanged})
@tailPosition
# Public: Retrieves the starting position of the marker.
#
# Returns a {Point}.
getStartPosition: ->
@getRange().start
# Public: Retrieves the ending position of the marker.
#
# Returns a {Point}.
getEndPosition: ->
@getRange().end
# Public: 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.
#
# Returns a {Point} representing the new tail position.
placeTail: ->
@setTailPosition(@getHeadPosition()) unless @tailPosition
# Public: Removes the tail from the marker.
clearTail: ->
oldTailPosition = @getTailPosition()
@tailPosition = null
newTailPosition = @getTailPosition()
@notifyObservers({oldTailPosition, newTailPosition, bufferChanged: false})
# Public: Identifies if a {Point} is within the marker.
#
# Returns a {Boolean}.
containsPoint: (point) ->
@getRange().containsPoint(point)
# Public: Sets a callback to be fired whenever a marker is changed.
observe: (callback) ->
@on 'changed', callback
cancel: => @unobserve(callback)
# Public: Removes the fired callback whenever a marker changes.
unobserve: (callback) ->
@off 'changed', callback
###
# Internal #
###
tryToInvalidate: (changedRange) ->
betweenStartAndEnd = @getRange().containsRange(changedRange, exclusive: false)
containsStart = changedRange.containsPoint(@getStartPosition(), exclusive: true)
@@ -127,16 +199,6 @@ class BufferMarker
[newRow, newColumn]
observe: (callback) ->
@on 'changed', callback
cancel: => @unobserve(callback)
unobserve: (callback) ->
@off 'changed', callback
containsPoint: (point) ->
@getRange().containsPoint(point)
notifyObservers: ({oldHeadPosition, newHeadPosition, oldTailPosition, newTailPosition, bufferChanged} = {}) ->
return if @suppressObserverNotification

View File

@@ -45,6 +45,13 @@ class Cursor
@editSession.removeCursor(this)
@trigger 'destroyed'
changePosition: (options, fn) ->
@goalColumn = null
@clearSelection()
@needsAutoscroll = options.autoscroll ? @isLastCursor()
unless fn()
@trigger 'autoscrolled' if @needsAutoscroll
###
# Public #
###
@@ -81,13 +88,7 @@ class Cursor
getBufferPosition: ->
@editSession.getMarkerHeadBufferPosition(@marker)
changePosition: (options, fn) ->
@goalColumn = null
@clearSelection()
@needsAutoscroll = options.autoscroll ? @isLastCursor()
unless fn()
@trigger 'autoscrolled' if @needsAutoscroll
# Public: If the marker range is empty, the cursor is marked as being visible.
updateVisibility: ->
@setVisible(@editSession.isMarkerRangeEmpty(@marker))
@@ -343,6 +344,9 @@ class Cursor
new Range([startRow, 0], [endRow, @editSession.lineLengthForBufferRow(endRow)])
# Public: Retrieves the characters that constitute a word preceeding the current cursor position.
#
# Returns a {String}.
getCurrentWordPrefix: ->
@editSession.getTextInBufferRange([@getBeginningOfCurrentWordBufferPosition(), @getBufferPosition()])

View File

@@ -20,63 +20,117 @@ class DisplayBufferMarker
# Public #
###
# Public: Gets the screen range of the display marker.
#
# Returns a {Range}.
getScreenRange: ->
@displayBuffer.screenRangeForBufferRange(@getBufferRange(), wrapAtSoftNewlines: true)
# Public: Modifies the screen range of the display marker.
#
# screenRange - The new {Range} to use
# options - A hash of options matching those found in {BufferMarker.setRange}
setScreenRange: (screenRange, options) ->
@setBufferRange(@displayBuffer.bufferRangeForScreenRange(screenRange, options), options)
@setBufferRange(@displayBuffer.bufferRangeForScreenRange(screenRange), options)
# Public: Gets the buffer range of the display marker.
#
# Returns a {Range}.
getBufferRange: ->
@buffer.getMarkerRange(@id)
# Public: Modifies the buffer range of the display marker.
#
# screenRange - The new {Range} to use
# options - A hash of options matching those found in {BufferMarker.setRange}
setBufferRange: (bufferRange, options) ->
@buffer.setMarkerRange(@id, bufferRange, options)
# Public: Retrieves the screen position of the marker's head.
#
# Returns a {Point}.
getHeadScreenPosition: ->
@headScreenPosition ?= @displayBuffer.screenPositionForBufferPosition(@getHeadBufferPosition(), wrapAtSoftNewlines: true)
# Public: Sets the screen position of the marker's head.
#
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setHeadScreenPosition: (screenPosition, options) ->
screenPosition = @displayBuffer.clipScreenPosition(screenPosition, options)
@setHeadBufferPosition(@displayBuffer.bufferPositionForScreenPosition(screenPosition, options))
# Public: Retrieves the buffer position of the marker's head.
#
# Returns a {Point}.
getHeadBufferPosition: ->
@buffer.getMarkerHeadPosition(@id)
# Public: Sets the buffer position of the marker's head.
#
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setHeadBufferPosition: (bufferPosition) ->
@buffer.setMarkerHeadPosition(@id, bufferPosition)
# Public: Retrieves the screen position of the marker's tail.
#
# Returns a {Point}.
getTailScreenPosition: ->
@tailScreenPosition ?= @displayBuffer.screenPositionForBufferPosition(@getTailBufferPosition(), wrapAtSoftNewlines: true)
# Public: Sets the screen position of the marker's tail.
#
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setTailScreenPosition: (screenPosition, options) ->
screenPosition = @displayBuffer.clipScreenPosition(screenPosition, options)
@setTailBufferPosition(@displayBuffer.bufferPositionForScreenPosition(screenPosition, options))
# Public: Retrieves the buffer position of the marker's tail.
#
# Returns a {Point}.
getTailBufferPosition: ->
@buffer.getMarkerTailPosition(@id)
# Public: Sets the buffer position of the marker's tail.
#
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setTailBufferPosition: (bufferPosition) ->
@buffer.setMarkerTailPosition(@id, bufferPosition)
# Public: 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.
#
# Returns a {Point} representing the new tail position.
placeTail: ->
@buffer.placeMarkerTail(@id)
# Public: Removes the tail from the marker.
clearTail: ->
@buffer.clearMarkerTail(@id)
###
# Internal #
###
# Public: Sets a callback to be fired whenever the marker is changed.
#
# callback - A {Function} to execute
observe: (callback) ->
@observeBufferMarkerIfNeeded()
@on 'changed', callback
cancel: => @unobserve(callback)
# Public: Removes the callback that's fired whenever the marker changes.
#
# callback - A {Function} to remove
unobserve: (callback) ->
@off 'changed', callback
@unobserveBufferMarkerIfNeeded()
###
# Internal #
###
observeBufferMarkerIfNeeded: ->
return if @subscriptionCount()
@getHeadScreenPosition() # memoize current value

View File

@@ -35,7 +35,6 @@ class DisplayBuffer
@tokenizedBuffer.on 'changed', @handleTokenizedBufferChange
@buffer.on 'markers-updated', @handleMarkersUpdated
buildLineMap: ->
@lineMap = new LineMap
@lineMap.insertAtScreenRow 0, @buildLinesForBufferRows(0, @buffer.getLastRow())
@@ -173,11 +172,22 @@ class DisplayBuffer
fold
# Public: Given a {Fold}, determines if it is contained within another fold.
#
# fold - The {Fold} to check
#
# Returns the contaiing {Fold} (if it exists), `null` otherwise.
isFoldContainedByActiveFold: (fold) ->
for row, folds of @activeFolds
for otherFold in folds
return otherFold if fold != otherFold and fold.isContainedByFold(otherFold)
# Public: Given a starting and ending row, tries to find an existing fold.
#
# startRow - A {Number} representing a fold's starting row
# endRow - A {Number} representing a fold's ending row
#
# Returns a {Fold} (if it exists).
foldFor: (startRow, endRow) ->
_.find @activeFolds[startRow] ? [], (fold) ->
fold.startRow == startRow and fold.endRow == endRow
@@ -190,17 +200,6 @@ class DisplayBuffer
for fold in new Array(folds...)
fold.destroy() if fold.getBufferRange().containsRow(bufferRow)
registerFold: (fold) ->
@activeFolds[fold.startRow] ?= []
@activeFolds[fold.startRow].push(fold)
@foldsById[fold.id] = fold
unregisterFold: (bufferRow, fold) ->
folds = @activeFolds[bufferRow]
_.remove(folds, fold)
delete @foldsById[fold.id]
delete @activeFolds[bufferRow] if folds.length == 0
# Public: Given a buffer row, this returns the largest fold that starts there.
#
# Largest is defined as the fold whose difference between its start and end points
@@ -239,19 +238,35 @@ class DisplayBuffer
largestFold = fold if fold.endRow >= bufferRow
largestFold
# Public: Given a buffer range, this converts it into a screen range.
#
# bufferRange - A {Range} consisting of buffer positions
#
# Returns a {Range}.
screenLineRangeForBufferRange: (bufferRange) ->
@expandScreenRangeToLineEnds(
@lineMap.screenRangeForBufferRange(
@expandBufferRangeToLineEnds(bufferRange)))
# Public: Given a buffer row, this converts it into a screen row.
#
# bufferRow - A {Number} representing a buffer row
#
# Returns a {Number}.
screenRowForBufferRow: (bufferRow) ->
@lineMap.screenPositionForBufferPosition([bufferRow, 0]).row
lastScreenRowForBufferRow: (bufferRow) ->
@lineMap.screenPositionForBufferPosition([bufferRow, Infinity]).row
# Public: Given a screen row, this converts it into a buffer row.
#
# screenRow - A {Number} representing a screen row
#
# Returns a {Number}.
bufferRowForScreenRow: (screenRow) ->
@lineMap.bufferPositionForScreenPosition([screenRow, 0]).row
# Public: Given a buffer range, this converts it into a screen position.
#
# bufferRange - The {Range} to convert
@@ -259,6 +274,7 @@ class DisplayBuffer
# Returns a {Range}.
screenRangeForBufferRange: (bufferRange) ->
@lineMap.screenRangeForBufferRange(bufferRange)
# Public: Given a screen range, this converts it into a buffer position.
#
# screenRange - The {Range} to convert
@@ -296,6 +312,7 @@ class DisplayBuffer
# Returns a {Point}.
screenPositionForBufferPosition: (position, options) ->
@lineMap.screenPositionForBufferPosition(position, options)
# Public: Given a buffer range, this converts it into a screen position.
#
# screenPosition - An object that represents a buffer position. It can be either
@@ -328,6 +345,19 @@ class DisplayBuffer
setTabLength: (tabLength) ->
@tokenizedBuffer.setTabLength(tabLength)
# Public: 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
# to a real position.
#
# position - The {Point} to clip
# options - A hash with the following values:
# :wrapBeyondNewlines - if `true`, continues wrapping past newlines
# :wrapAtSoftNewlines - if `true`, continues wrapping past soft newlines
# :screenLine - if `true`, indicates that you're using a line number, not a row number
#
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
clipScreenPosition: (position, options) ->
@lineMap.clipScreenPosition(position, options)
@@ -335,6 +365,17 @@ class DisplayBuffer
# Internal #
###
registerFold: (fold) ->
@activeFolds[fold.startRow] ?= []
@activeFolds[fold.startRow].push(fold)
@foldsById[fold.id] = fold
unregisterFold: (bufferRow, fold) ->
folds = @activeFolds[bufferRow]
_.remove(folds, fold)
delete @foldsById[fold.id]
delete @activeFolds[bufferRow] if folds.length == 0
destroyFold: (fold) ->
@unregisterFold(fold.startRow, fold)
@@ -385,10 +426,6 @@ class DisplayBuffer
@pendingChangeEvent = null
@triggerChanged(event, false)
###
# Public #
###
buildLineForBufferRow: (bufferRow) ->
@buildLinesForBufferRows(bufferRow, bufferRow)
@@ -425,6 +462,17 @@ class DisplayBuffer
lineFragments
###
# Public #
###
# Public: Given a line, finds the point where it would wrap.
#
# line - The {String} to check
# softWrapColumn - The {Number} where you want soft wrapping to occur
#
# Returns a {Number} representing the `line` position where the wrap would take place.
# Returns `null` if a wrap wouldn't occur.
findWrapColumn: (line, softWrapColumn) ->
return unless line.length > softWrapColumn
@@ -439,96 +487,240 @@ class DisplayBuffer
return column + 1 if /\s/.test(line[column])
return softWrapColumn
# Public: Given a range in screen coordinates, this expands it to the start and end of a line
#
# screenRange - The {Range} to expand
#
# Returns a new {Range}.
expandScreenRangeToLineEnds: (screenRange) ->
screenRange = Range.fromObject(screenRange)
{ start, end } = screenRange
new Range([start.row, 0], [end.row, @lineMap.lineForScreenRow(end.row).text.length])
# Public: Given a range in buffer coordinates, this expands it to the start and end of a line
#
# screenRange - The {Range} to expand
#
# Returns a new {Range}.
expandBufferRangeToLineEnds: (bufferRange) ->
bufferRange = Range.fromObject(bufferRange)
{ start, end } = bufferRange
new Range([start.row, 0], [end.row, Infinity])
# Public: Calculates a {Range} representing the start of the {Buffer} until the end.
#
# Returns a {Range}.
rangeForAllLines: ->
new Range([0, 0], @clipScreenPosition([Infinity, Infinity]))
# Public: Retrieves a {DisplayBufferMarker} based on its id.
#
# id - A {Number} representing a marker id
#
# Returns the {DisplayBufferMarker} (if it exists).
getMarker: (id) ->
@markers[id] ? new DisplayBufferMarker({id, displayBuffer: this})
# Public: Retrieves the active markers in the buffer.
#
# Returns an {Array} of existing {DisplayBufferMarker}s.
getMarkers: ->
_.values(@markers)
# Public: Constructs a new marker at the given screen range.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markScreenRange: (args...) ->
bufferRange = @bufferRangeForScreenRange(args.shift())
@markBufferRange(bufferRange, args...)
# Public: Constructs a new marker at the given buffer range.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markBufferRange: (args...) ->
@buffer.markRange(args...)
# Public: Constructs a new marker at the given screen position.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markScreenPosition: (screenPosition, options) ->
@markBufferPosition(@bufferPositionForScreenPosition(screenPosition), options)
# Public: Constructs a new marker at the given buffer position.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markBufferPosition: (bufferPosition, options) ->
@buffer.markPosition(bufferPosition, options)
# Public: Removes the marker with the given id.
#
# id - The {Number} of the ID to remove
destroyMarker: (id) ->
@buffer.destroyMarker(id)
delete @markers[id]
# Public: Gets the screen range of the display marker.
#
# id - The {Number} of the ID to check
#
# Returns a {Range}.
getMarkerScreenRange: (id) ->
@getMarker(id).getScreenRange()
# Public: Modifies the screen range of the display marker.
#
# id - The {Number} of the ID to change
# screenRange - The new {Range} to use
# options - A hash of options matching those found in {BufferMarker.setRange}
setMarkerScreenRange: (id, screenRange, options) ->
@getMarker(id).setScreenRange(screenRange, options)
# Public: Gets the buffer range of the display marker.
#
# id - The {Number} of the ID to check
#
# Returns a {Range}.
getMarkerBufferRange: (id) ->
@getMarker(id).getBufferRange()
# Public: Modifies the buffer range of the display marker.
#
# id - The {Number} of the ID to change
# screenRange - The new {Range} to use
# options - A hash of options matching those found in {BufferMarker.setRange}
setMarkerBufferRange: (id, bufferRange, options) ->
@getMarker(id).setBufferRange(bufferRange, options)
# Public: Retrieves the screen position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerScreenPosition: (id) ->
@getMarkerHeadScreenPosition(id)
# Public: Retrieves the buffer position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerBufferPosition: (id) ->
@getMarkerHeadBufferPosition(id)
# Public: Retrieves the screen position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerHeadScreenPosition: (id) ->
@getMarker(id).getHeadScreenPosition()
# Public: Sets the screen position of the marker's head.
#
# id - The {Number} of the ID to change
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerHeadScreenPosition: (id, screenPosition, options) ->
@getMarker(id).setHeadScreenPosition(screenPosition, options)
# Public: Retrieves the buffer position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerHeadBufferPosition: (id) ->
@getMarker(id).getHeadBufferPosition()
# Public: Sets the buffer position of the marker's head.
#
# id - The {Number} of the ID to check
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerHeadBufferPosition: (id, bufferPosition) ->
@getMarker(id).setHeadBufferPosition(bufferPosition)
# Public: Retrieves the screen position of the marker's tail.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerTailScreenPosition: (id) ->
@getMarker(id).getTailScreenPosition()
# Public: Sets the screen position of the marker's tail.
#
# id - The {Number} of the ID to change
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerTailScreenPosition: (id, screenPosition, options) ->
@getMarker(id).setTailScreenPosition(screenPosition, options)
# Public: Retrieves the buffer position of the marker's tail.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerTailBufferPosition: (id) ->
@getMarker(id).getTailBufferPosition()
# Public: Sets the buffer position of the marker's tail.
#
# id - The {Number} of the ID to check
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerTailBufferPosition: (id, bufferPosition) ->
@getMarker(id).setTailBufferPosition(bufferPosition)
# Public: 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.
#
# id - A {Number} representing the marker to change
#
# Returns a {Point} representing the new tail position.
placeMarkerTail: (id) ->
@getMarker(id).placeTail()
# Public: Removes the tail from the marker.
#
# id - A {Number} representing the marker to change
clearMarkerTail: (id) ->
@getMarker(id).clearTail()
# Public: 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}.
#
# id - A {Number} representing the marker to check
#
# Returns a {Boolean}.
isMarkerReversed: (id) ->
@buffer.isMarkerReversed(id)
# Public: Identifies if the marker's head position is equal to its tail.
#
# id - A {Number} representing the marker to check
#
# Returns a {Boolean}.
isMarkerRangeEmpty: (id) ->
@buffer.isMarkerRangeEmpty(id)
# Public: 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) ->
@getMarker(id).observe(callback)

View File

@@ -160,7 +160,7 @@ class EditSession
# Public: Defines the limit at which the buffer begins to soft wrap text.
#
# softWrapColumn - A {Number} defining the soft wrap limit.
# softWrapColumn - A {Number} defining the soft wrap limit
setSoftWrapColumn: (@softWrapColumn) -> @displayBuffer.setSoftWrapColumn(@softWrapColumn)
# Public: Defines whether to use soft tabs.
#
@@ -192,8 +192,27 @@ class EditSession
#
# tabLength - A {Number} that defines the new tab length.
setTabLength: (tabLength) -> @displayBuffer.setTabLength(tabLength)
# Public: 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
# to a real position.
#
# position - The {Point} to clip
#
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
clipBufferPosition: (bufferPosition) -> @buffer.clipPosition(bufferPosition)
# Public: 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
# to a real range.
#
# range - The {Point} to clip
#
# Returns the new, clipped {Point}. Note that this could be the same as `range` if no clipping was performed.
clipBufferRange: (range) -> @buffer.clipRange(range)
# Public: Given a buffer row, this retrieves the indentation level.
@@ -350,7 +369,19 @@ class EditSession
#
# Returns a {Range}.
bufferRangeForScreenRange: (screenRange) -> @displayBuffer.bufferRangeForScreenRange(screenRange)
# Public: 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
# to a real position.
#
# position - The {Point} to clip
# options - A hash with the following values:
# :wrapBeyondNewlines - if `true`, continues wrapping past newlines
# :wrapAtSoftNewlines - if `true`, continues wrapping past soft newlines
# :screenLine - if `true`, indicates that you're using a line number, not a row number
#
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options)
# Public: Gets the line for the given screen row.
#
@@ -475,6 +506,13 @@ class EditSession
outdentSelectedRows: ->
@mutateSelectedText (selection) -> selection.outdentSelectedRows()
# Public: Wraps the lines within a selection in comments.
#
# If the language doesn't have comments, nothing happens.
#
# selection - The {Selection} to comment
#
# Returns an {Array} of the commented {Ranges}.
toggleLineCommentsInSelection: ->
@mutateSelectedText (selection) -> selection.toggleLineComments()
@@ -603,20 +641,20 @@ class EditSession
createFold: (startRow, endRow) ->
@displayBuffer.createFold(startRow, endRow)
# Public: Removes any folds found that contain the given buffer row.
# Public: Removes any {Fold}s found that contain the given buffer row.
#
# bufferRow - The buffer row {Number} to check against
destroyFoldsContainingBufferRow: (bufferRow) ->
@displayBuffer.destroyFoldsContainingBufferRow(bufferRow)
# Public: Removes any folds found that intersect the given buffer row.
# Public: Removes any {Fold}s found that intersect the given buffer row.
#
# bufferRow - The buffer row {Number} to check against
destroyFoldsIntersectingBufferRange: (bufferRange) ->
for row in [bufferRange.start.row..bufferRange.end.row]
@destroyFoldsContainingBufferRow(row)
# Public: Given the id of a fold, this removes it.
# Public: Given the id of a {Fold}, this removes it.
#
# foldId - The fold id {Number} to remove
destroyFold: (foldId) ->
@@ -671,7 +709,7 @@ class EditSession
# Public: Given a buffer row, this returns a suggested indentation level.
#
# The indentation level provided is based on the current {LanguageMode}.
# The indentation level provided is based on the current language.
#
# bufferRow - A {Number} indicating the buffer row
#
@@ -839,18 +877,45 @@ class EditSession
# Public #
###
# Public: Constructs a new marker at the given screen range.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markScreenRange: (args...) ->
@displayBuffer.markScreenRange(args...)
# Public: Constructs a new marker at the given buffer range.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markBufferRange: (args...) ->
@displayBuffer.markBufferRange(args...)
# Public: Constructs a new marker at the given screen position.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markScreenPosition: (args...) ->
@displayBuffer.markScreenPosition(args...)
# Public: Constructs a new marker at the given buffer position.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
#
# Returns a {Number} representing the new marker's ID.
markBufferPosition: (args...) ->
@displayBuffer.markBufferPosition(args...)
# Public: Removes the marker with the given id.
#
# id - The {Number} of the ID to remove
destroyMarker: (args...) ->
@displayBuffer.destroyMarker(args...)
@@ -860,65 +925,156 @@ class EditSession
getMarkerCount: ->
@buffer.getMarkerCount()
# Public: Gets the screen range of the display marker.
#
# id - The {Number} of the ID to check
#
# Returns a {Range}.
getMarkerScreenRange: (args...) ->
@displayBuffer.getMarkerScreenRange(args...)
# Public: Modifies the screen range of the display marker.
#
# id - The {Number} of the ID to change
# screenRange - The new {Range} to use
# options - A hash of options matching those found in {BufferMarker.setRange}
setMarkerScreenRange: (args...) ->
@displayBuffer.setMarkerScreenRange(args...)
# Public: Gets the buffer range of the display marker.
#
# id - The {Number} of the ID to check
#
# Returns a {Range}.
getMarkerBufferRange: (args...) ->
@displayBuffer.getMarkerBufferRange(args...)
# Public: Modifies the buffer range of the display marker.
#
# id - The {Number} of the ID to check
# screenRange - The new {Range} to use
# options - A hash of options matching those found in {BufferMarker.setRange}
setMarkerBufferRange: (args...) ->
@displayBuffer.setMarkerBufferRange(args...)
# Public: Retrieves the screen position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerScreenPosition: (args...) ->
@displayBuffer.getMarkerScreenPosition(args...)
# Public: Retrieves the buffer position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerBufferPosition: (args...) ->
@displayBuffer.getMarkerBufferPosition(args...)
# Public: Retrieves the screen position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerHeadScreenPosition: (args...) ->
@displayBuffer.getMarkerHeadScreenPosition(args...)
# Public: Sets the screen position of the marker's head.
#
# id - The {Number} of the ID to change
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerHeadScreenPosition: (args...) ->
@displayBuffer.setMarkerHeadScreenPosition(args...)
# Public: Retrieves the buffer position of the marker's head.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerHeadBufferPosition: (args...) ->
@displayBuffer.getMarkerHeadBufferPosition(args...)
# Public: Sets the buffer position of the marker's head.
#
# id - The {Number} of the ID to check
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerHeadBufferPosition: (args...) ->
@displayBuffer.setMarkerHeadBufferPosition(args...)
# Public: Retrieves the screen position of the marker's tail.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerTailScreenPosition: (args...) ->
@displayBuffer.getMarkerTailScreenPosition(args...)
# Public: Sets the screen position of the marker's tail.
#
# id - The {Number} of the ID to change
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerTailScreenPosition: (args...) ->
@displayBuffer.setMarkerTailScreenPosition(args...)
# Public: Retrieves the buffer position of the marker's tail.
#
# id - The {Number} of the ID to check
#
# Returns a {Point}.
getMarkerTailBufferPosition: (args...) ->
@displayBuffer.getMarkerTailBufferPosition(args...)
# Public: Sets the buffer position of the marker's tail.
#
# id - The {Number} of the ID to change
# screenRange - The new {Point} to use
# options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition}
setMarkerTailBufferPosition: (args...) ->
@displayBuffer.setMarkerTailBufferPosition(args...)
# Public: 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: (args...) ->
@displayBuffer.observeMarker(args...)
# Public: 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.
#
# id - A {Number} representing the marker to change
#
# Returns a {Point} representing the new tail position.
placeMarkerTail: (args...) ->
@displayBuffer.placeMarkerTail(args...)
# Public: Removes the tail from the marker.
#
# id - A {Number} representing the marker to change
clearMarkerTail: (args...) ->
@displayBuffer.clearMarkerTail(args...)
# Public: Identifies if markers are reversed, that is, they are highlighting "up."
# Public: Identifies if the ending position of a marker is greater than the starting position.
#
# args - {String}s specifying the id of a {BufferMarker}
# This can happen when, for example, you highlight text "up" in a {Buffer}.
#
# id - A {Number} representing the marker to check
#
# Returns a {Boolean}.
isMarkerReversed: (args...) ->
@displayBuffer.isMarkerReversed(args...)
# Public: Identifies if the marker's head position is equal to its tail.
#
# id - A {Number} representing the marker to check
#
# Returns a {Boolean}.
isMarkerRangeEmpty: (args...) ->
@displayBuffer.isMarkerRangeEmpty(args...)
@@ -928,9 +1084,9 @@ class EditSession
hasMultipleCursors: ->
@getCursors().length > 1
# Public: Retrieves an array of all the cursors.
# Public: Retrieves all the cursors.
#
# Returns a {[Cursor]}.
# Returns an {Array} of {Cursor}s.
getCursors: -> new Array(@cursors...)
# Public: Retrieves a single cursor
@@ -1131,7 +1287,7 @@ class EditSession
getCursorBufferPosition: ->
@getCursor().getBufferPosition()
# Public: Gets the screen range of the most recently added {Selection}.
# Public: Gets the screen range of the most recently added {Selection}.
#
# Returns a {Range}.
getSelectedScreenRange: ->
@@ -1350,10 +1506,14 @@ class EditSession
else
false
# Public: Given a buffer position, this finds all markers that contain the position.
#
# bufferPosition - A {Point} to check
#
# Returns an {Array} of {Numbers}, representing marker IDs containing `bufferPosition`.
markersForBufferPosition: (bufferPosition) ->
@buffer.markersForPosition(bufferPosition)
# Internal:
mergeCursors: ->
positions = []
for cursor in @getCursors()
@@ -1398,12 +1558,12 @@ class EditSession
# Public: Retrieves the current {EditSession}'s grammar.
#
# Returns a {String} indicating the {LanguageMode}'s grammar rules.
# Returns a {String} indicating the language's grammar rules.
getGrammar: -> @languageMode.grammar
# Public: Sets the current {EditSession}'s grammar.
#
# grammar - A {String} indicating the {LanguageMode}'s grammar rules.
# grammar - A {String} indicating the language's grammar rules.
setGrammar: (grammar) ->
@languageMode.setGrammar(grammar)

View File

@@ -434,9 +434,6 @@ class Editor extends View
undo: -> @activeEditSession.undo()
# Public: Redos the last {Buffer} change.
redo: -> @activeEditSession.redo()
transact: (fn) -> @activeEditSession.transact(fn)
commit: -> @activeEditSession.commit()
abort: -> @activeEditSession.abort()
# Public: Creates a new fold between two row numbers.
#
# startRow - The row {Number} to start folding at
@@ -452,8 +449,15 @@ class Editor extends View
foldAll: -> @activeEditSession.foldAll()
# Public: Unfolds all the rows.
unfoldAll: -> @activeEditSession.unfoldAll()
# Public: Folds the most recent selection.
foldSelection: -> @activeEditSession.foldSelection()
# Public: Given the id of a {Fold}, this removes it.
#
# foldId - The fold id {Number} to remove
destroyFold: (foldId) -> @activeEditSession.destroyFold(foldId)
# Public: Removes any {Fold}s found that contain the given buffer row.
#
# bufferRow - The buffer row {Number} to check against
destroyFoldsContainingBufferRow: (bufferRow) -> @activeEditSession.destroyFoldsContainingBufferRow(bufferRow)
# Public: Determines if the given screen row is folded.
#
@@ -489,6 +493,9 @@ class Editor extends View
#
# Returns a {Number}.
screenLineCount: -> @activeEditSession.screenLineCount()
# Public: Defines the limit at which the buffer begins to soft wrap text.
#
# softWrapColumn - A {Number} defining the soft wrap limit
setSoftWrapColumn: (softWrapColumn) ->
softWrapColumn ?= @calcSoftWrapColumn()
@activeEditSession.setSoftWrapColumn(softWrapColumn) if softWrapColumn
@@ -500,6 +507,19 @@ class Editor extends View
#
# Returns a {String}.
getLastScreenRow: -> @activeEditSession.getLastScreenRow()
# Public: 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
# to a real position.
#
# position - The {Point} to clip
# options - A hash with the following values:
# :wrapBeyondNewlines - if `true`, continues wrapping past newlines
# :wrapAtSoftNewlines - if `true`, continues wrapping past soft newlines
# :screenLine - if `true`, indicates that you're using a line number, not a row number
#
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
clipScreenPosition: (screenPosition, options={}) -> @activeEditSession.clipScreenPosition(screenPosition, options)
# Public: Given a buffer position, this converts it into a screen position.
@@ -867,6 +887,9 @@ class Editor extends View
scrollToBottom: ->
@scrollBottom(@screenLineCount() * @lineHeight)
# Public: Scrolls the editor to the position of the most recently added cursor.
#
# The editor is also centered.
scrollToCursorPosition: ->
@scrollToBufferPosition(@getCursorBufferPosition(), center: true)
@@ -934,6 +957,11 @@ class Editor extends View
else if desiredLeft < @scrollView.scrollLeft()
@scrollView.scrollLeft(desiredLeft)
# Public: Given a buffer range, this highlights all the folds within that range
#
# "Highlighting" essentially just adds the `selected` class to the line
#
# bufferRange - The {Range} to check
highlightFoldsContainingBufferRange: (bufferRange) ->
screenLines = @linesForScreenRows(@firstRenderedScreenRow, @lastRenderedScreenRow)
for screenLine, i in screenLines
@@ -1110,7 +1138,10 @@ class Editor extends View
appendToLinesView: (view) ->
@overlayer.append(view)
# Internal:
###
# Internal #
###
calculateDimensions: ->
fragment = $('<div class="line" style="position: absolute; visibility: hidden;"><span>x</span></div>')
@renderedLines.append(fragment)
@@ -1360,6 +1391,10 @@ class Editor extends View
@renderedLines.css('padding-bottom', paddingBottom)
@gutter.lineNumbers.css('padding-bottom', paddingBottom)
###
# Public #
###
# Public: Retrieves the number of the row that is visible and currently at the top of the editor.
#
# Returns a {Number}.
@@ -1380,7 +1415,10 @@ class Editor extends View
isScreenRowVisible: (row) ->
@getFirstVisibleScreenRow() <= row <= @getLastVisibleScreenRow()
# Internal:
###
# Internal #
###
handleScreenLinesChange: (change) ->
@pendingChanges.push(change)
@requestDisplayUpdate()
@@ -1487,6 +1525,10 @@ class Editor extends View
toggleLineCommentsInSelection: ->
@activeEditSession.toggleLineCommentsInSelection()
###
# Public #
###
# Public: Converts a buffer position to a pixel position.
#
# position - An object that represents a buffer position. It can be either
@@ -1580,13 +1622,13 @@ class Editor extends View
# Public: Retrieves the current {EditSession}'s grammar.
#
# Returns a {String} indicating the {LanguageMode}'s grammar rules.
# Returns a {String} indicating the language's grammar rules.
getGrammar: ->
@activeEditSession.getGrammar()
# Public: Sets the current {EditSession}'s grammar. This only works for mini-editors.
#
# grammar - A {String} indicating the {LanguageMode}'s grammar rules.
# grammar - A {String} indicating the language's grammar rules.
setGrammar: (grammar) ->
throw new Error("Only mini-editors can explicity set their grammar") unless @mini
@activeEditSession.setGrammar(grammar)
@@ -1622,6 +1664,10 @@ class Editor extends View
# Internal #
###
transact: (fn) -> @activeEditSession.transact(fn)
commit: -> @activeEditSession.commit()
abort: -> @activeEditSession.abort()
saveDebugSnapshot: ->
atom.showSaveDialog (path) =>
fsUtils.write(path, @getDebugSnapshot()) if path

View File

@@ -213,19 +213,6 @@ class Git
isSubmodule: (path) ->
@getRepo().isSubmodule(@relativize(path))
# Internal:
refreshStatus: ->
if @statusTask?
@statusTask.off()
@statusTask.one 'task-completed', =>
@statusTask = null
@refreshStatus()
else
@statusTask = new RepositoryStatusTask(this)
@statusTask.one 'task-completed', =>
@statusTask = null
@statusTask.start()
# Public: Retrieves the status of a directory.
#
# path - The {String} path to check
@@ -242,12 +229,36 @@ class Git
#
# This is similar to the commit numbers reported by `git status` when a remote tracking branch exists.
#
# Returnsan object with two keys, `ahead` and `behind`. These will always be greater than 0.
# Returns an object with two keys, `ahead` and `behind`. These will always be greater than zero.
getAheadBehindCounts: ->
@getRepo().getAheadBehindCount()
# Public: Retrieves the line diffs comparing the `HEAD` version of the given path and the given text.
#
# This is similar to the commit numbers reported by `git status` when a remote tracking branch exists.
#
# path - The {String} path (relative to the repository)
# text - The {String} to compare against the `HEAD` contents
#
# Returns an object with two keys, `ahead` and `behind`. These will always be greater than zero.
getLineDiffs: (path, text) ->
@getRepo().getLineDiffs(@relativize(path), text)
###
# Internal #
###
refreshStatus: ->
if @statusTask?
@statusTask.off()
@statusTask.one 'task-completed', =>
@statusTask = null
@refreshStatus()
else
@statusTask = new RepositoryStatusTask(this)
@statusTask.one 'task-completed', =>
@statusTask = null
@statusTask.start()
_.extend Git.prototype, Subscriber
_.extend Git.prototype, EventEmitter

View File

@@ -5,6 +5,10 @@ require 'underscore-extensions'
EventEmitter = require 'event-emitter'
Subscriber = require 'subscriber'
###
# Internal #
###
module.exports =
class LanguageMode
buffer = null

View File

@@ -1,5 +1,8 @@
Token = require 'token'
###
# Internal #
###
module.exports =
class NullGrammar
name: 'Null Grammar'

View File

@@ -1,5 +1,8 @@
fsUtils = require 'fs-utils'
###
# Internal #
###
module.exports =
class Package
@build: (path) ->

View File

@@ -2,14 +2,15 @@ $ = require 'jquery'
_ = require 'underscore'
PaneAxis = require 'pane-axis'
###
# Internal #
###
module.exports =
class PaneRow extends PaneAxis
@content: ->
@div class: 'row'
# Public: Retrieves the pane class name.
#
# Returns a {String}.
className: ->
"PaneRow"

View File

@@ -1,5 +1,9 @@
_ = require 'underscore'
###
# Internal #
###
module.exports =
class ScreenLine
constructor: ({tokens, @lineEnding, @ruleStack, @bufferRows, @startBufferColumn, @fold, tabLength}) ->
@@ -104,6 +108,9 @@ class ScreenLine
breakOutLeadingWhitespace = token.isOnlyWhitespace() if breakOutLeadingWhitespace
outputTokens
# Public: Determins if the current line is commented.
#
# Returns a {Boolean}.
isComment: ->
for token in @tokens
continue if token.scopes.length is 1

View File

@@ -70,7 +70,7 @@ class Selection
# Public: Modifies the screen range for the selection.
#
# screenRange - The new {Range} to select
# screenRange - The new {Range} to use
# options - A hash of options matching those found in {.setBufferRange}
setScreenRange: (screenRange, options) ->
@setBufferRange(@editSession.bufferRangeForScreenRange(screenRange), options)

View File

@@ -6,17 +6,19 @@ fsUtils = require 'fs-utils'
EventEmitter = require 'event-emitter'
NullGrammar = require 'null-grammar'
###
# Internal #
###
module.exports =
class Syntax
registerDeserializer(this)
# Internal:
@deserialize: ({grammarOverridesByPath}) ->
syntax = new Syntax()
syntax.grammarOverridesByPath = grammarOverridesByPath
syntax
# Internal:
constructor: ->
@nullGrammar = new NullGrammar
@grammars = [@nullGrammar]
@@ -25,7 +27,6 @@ class Syntax
@scopedPropertiesIndex = 0
@scopedProperties = []
# Internal:
serialize: ->
{ deserializer: @constructor.name, @grammarOverridesByPath }

View File

@@ -333,6 +333,13 @@ class Buffer
range = @pushOperation(operation)
range
# Public: 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
# to a real position.
#
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
clipPosition: (position) ->
position = Point.fromObject(position)
eofPosition = @getEofPosition()
@@ -343,7 +350,16 @@ 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.
#
# 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
# to a real range.
#
# range - The {Point} to clip
#
# Returns the new, clipped {Point}. Note that this could be the same as `range` if no clipping was performed.
clipRange: (range) ->
range = Range.fromObject(range)
new Range(@clipPosition(range.start), @clipPosition(range.end))
@@ -417,6 +433,12 @@ class Buffer
getMarkerCount: ->
_.size(@validMarkers)
# Public: 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
#
# Returns a {Number} representing the new marker's ID.
markRange: (range, options={}) ->
marker = new BufferMarker(_.defaults({
id: (@nextMarkerId++).toString()
@@ -426,9 +448,18 @@ class Buffer
@validMarkers[marker.id] = marker
marker.id
# Public: 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
#
# Returns a {Number} representing the new marker's ID.
markPosition: (position, options) ->
@markRange([position, position], _.defaults({noTail: true}, options))
# Public: Removes the marker with the given id.
#
# id - The {Number} of the ID to remove
destroyMarker: (id) ->
delete @validMarkers[id]
delete @invalidMarkers[id]
@@ -439,39 +470,110 @@ class Buffer
setMarkerPosition: (args...) ->
@setMarkerHeadPosition(args...)
# Public: Retrieves the position of the marker's head.
#
# id - A {Number} representing the marker to check
#
# Returns a {Point}, or `null` if the marker does not exist.
getMarkerHeadPosition: (id) ->
@validMarkers[id]?.getHeadPosition()
# Public: Sets the position of the marker's head.
#
# id - A {Number} representing the marker to change
# position - The new {Point} to place the head
# options - A hash with the following keys:
# :clip - if `true`, the point is [clipped]{Buffer.clipPosition}
# :bufferChanged - if `true`, indicates that the {Buffer} should trigger an event that it's changed
#
# Returns a {Point} representing the new head position.
setMarkerHeadPosition: (id, position, options) ->
@validMarkers[id]?.setHeadPosition(position)
# Public: Retrieves the position of the marker's tail.
#
# id - A {Number} representing the marker to check
#
# Returns a {Point}, or `null` if the marker does not exist.
getMarkerTailPosition: (id) ->
@validMarkers[id]?.getTailPosition()
# Public: Sets the position of the marker's tail.
#
# id - A {Number} representing the marker to change
# position - The new {Point} to place the tail
# options - A hash with the following keys:
# :clip - if `true`, the point is [clipped]{Buffer.clipPosition}
# :bufferChanged - if `true`, indicates that the {Buffer} should trigger an event that it's changed
#
# Returns a {Point} representing the new tail position.
setMarkerTailPosition: (id, position, options) ->
@validMarkers[id]?.setTailPosition(position)
# Public: 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.
#
# id - A {Number} representing the marker to change
# range - The new {Range} the marker should cover
# options - A hash of options with the following keys:
# :reverse - if `true`, the marker is reversed; that is, its tail is "above" the head
# :noTail - if `true`, the marker doesn't have a tail
setMarkerRange: (id, range, options) ->
@validMarkers[id]?.setRange(range, options)
# Public: 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.
#
# id - A {Number} representing the marker to change
#
# Returns a {Point} representing the new tail position.
placeMarkerTail: (id) ->
@validMarkers[id]?.placeTail()
# Public: 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.
#
# This can happen when, for example, you highlight text "up" in a {Buffer}.
#
# id - A {Number} representing the marker to check
#
# Returns a {Boolean}.
isMarkerReversed: (id) ->
@validMarkers[id]?.isReversed()
# Public: Identifies if the marker's head position is equal to its tail.
#
# id - A {Number} representing the marker to check
#
# Returns a {Boolean}.
isMarkerRangeEmpty: (id) ->
@validMarkers[id]?.isRangeEmpty()
# Public: 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.
#
# bufferPosition - A {Point} to check
#
# Returns an {Array} of {Numbers}, representing marker IDs containing `bufferPosition`.
markersForPosition: (bufferPosition) ->
bufferPosition = Point.fromObject(bufferPosition)
ids = []
@@ -479,6 +581,13 @@ class Buffer
ids.push(id) if marker.containsPoint(bufferPosition)
ids
# Public: Identifies if a character sequence is within a certain range.
#
# regex - The {RegExp} to check
# startIndex - The starting row {Number}
# endIndex - The ending row {Number}
#
# Returns an {Array} of {RegExp}s, representing the matches
matchesInCharacterRange: (regex, startIndex, endIndex) ->
text = @getText()
matches = []
@@ -610,7 +719,17 @@ class Buffer
return unless path
git?.checkoutHead(path)
# Internal:
# Public: Checks to see if a file exists.
#
# Returns a {Boolean}.
fileExists: ->
@file? && @file.exists()
###
# Internal #
###
scheduleModifiedEvents: ->
clearTimeout(@stoppedChangingTimeout) if @stoppedChangingTimeout
stoppedChangingCallback = =>
@@ -620,25 +739,16 @@ class Buffer
@triggerModifiedStatusChanged(modifiedStatus)
@stoppedChangingTimeout = setTimeout(stoppedChangingCallback, @stoppedChangingDelay)
# Internal:
triggerModifiedStatusChanged: (modifiedStatus) ->
return if modifiedStatus is @previousModifiedStatus
@previousModifiedStatus = modifiedStatus
@trigger 'modified-status-changed', modifiedStatus
# Public: Checks to see if a file exists.
#
# Returns a {Boolean}.
fileExists: ->
@file? && @file.exists()
# Internal:
logLines: (start=0, end=@getLastRow())->
for row in [start..end]
line = @lineForRow(row)
console.log row, line, line.length
# Internal:
getDebugSnapshot: ->
lines = ['Buffer:']
for row in [0..@getLastRow()]

View File

@@ -6,6 +6,10 @@ Token = require 'token'
nodePath = require 'path'
pathSplitRegex = new RegExp("[#{nodePath.sep}.]")
###
# Internal #
###
module.exports =
class TextMateGrammar
@readFromPath: (path) ->
@@ -346,6 +350,10 @@ class Pattern
tokens
###
# Internal #
###
shiftCapture = (captureIndices) ->
[captureIndices.shift(), captureIndices.shift(), captureIndices.shift()]

View File

@@ -5,6 +5,10 @@ _ = require 'underscore'
TextMateGrammar = require 'text-mate-grammar'
async = require 'async'
###
# Internal #
###
module.exports =
class TextMatePackage extends Package
@testName: (packageName) ->

View File

@@ -3,6 +3,10 @@ fsUtils = require 'fs-utils'
plist = require 'plist'
Theme = require 'theme'
###
# Internal #
###
module.exports =
class TextMateTheme extends Theme
@testPath: (path) ->

View File

@@ -1,5 +1,9 @@
fsUtils = require 'fs-utils'
###
# Internal #
###
module.exports =
class Theme
@stylesheets: null

View File

@@ -5,6 +5,10 @@ Token = require 'token'
Range = require 'range'
Point = require 'point'
###
# Internal #
###
module.exports =
class TokenizedBuffer
@idCounter: 1
@@ -18,7 +22,6 @@ class TokenizedBuffer
invalidRows: null
visible: false
# Internal:
constructor: (@buffer, { @languageMode, @tabLength }) ->
@tabLength ?= 2
@id = @constructor.idCounter++
@@ -163,7 +166,6 @@ class TokenizedBuffer
token = @screenLines[position.row].tokenAtBufferColumn(position.column)
token.scopes
# Internal:
destroy: ->
@buffer.off ".tokenized-buffer#{@id}"
@@ -233,13 +235,11 @@ class TokenizedBuffer
getLastRow: ->
@buffer.getLastRow()
# Internal:
logLines: (start=0, end=@buffer.getLastRow()) ->
for row in [start..end]
line = @lineForScreenRow(row).text
console.log row, line, line.length
# Internal:
getDebugSnapshot: ->
lines = ["Tokenized Buffer:"]
for screenLine, row in @linesForScreenRows(0, @getLastRow())

View File

@@ -2,7 +2,6 @@ _ = require 'underscore'
# Internal: The object in charge of managing redo and undo operations.
module.exports =
class UndoManager
undoHistory: null
redoHistory: null