From 5ee388cede96f79453c5fc1e4b5c998a8b2a048f Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Thu, 18 Apr 2013 18:50:22 -0700 Subject: [PATCH] Get it to a proper 80% --- src/app/atom-package.coffee | 5 + src/app/binding-set.coffee | 4 + src/app/buffer-change-operation.coffee | 4 + src/app/buffer-marker.coffee | 82 +++++++-- src/app/cursor.coffee | 18 +- src/app/display-buffer-marker.coffee | 68 +++++++- src/app/display-buffer.coffee | 226 +++++++++++++++++++++++-- src/app/edit-session.coffee | 194 +++++++++++++++++++-- src/app/editor.coffee | 60 ++++++- src/app/git.coffee | 39 +++-- src/app/language-mode.coffee | 4 + src/app/null-grammar.coffee | 3 + src/app/package.coffee | 3 + src/app/pane-row.coffee | 7 +- src/app/screen-line.coffee | 7 + src/app/selection.coffee | 2 +- src/app/syntax.coffee | 7 +- src/app/text-buffer.coffee | 132 +++++++++++++-- src/app/text-mate-grammar.coffee | 8 + src/app/text-mate-package.coffee | 4 + src/app/text-mate-theme.coffee | 4 + src/app/theme.coffee | 4 + src/app/tokenized-buffer.coffee | 8 +- src/app/undo-manager.coffee | 1 - 24 files changed, 792 insertions(+), 102 deletions(-) diff --git a/src/app/atom-package.coffee b/src/app/atom-package.coffee index 9013d461a..5aa89e281 100644 --- a/src/app/atom-package.coffee +++ b/src/app/atom-package.coffee @@ -5,6 +5,11 @@ _ = require 'underscore' $ = require 'jquery' CSON = require 'cson' + +### +# Internal: Loads and resolves packages. # +### + module.exports = class AtomPackage extends Package metadata: null diff --git a/src/app/binding-set.coffee b/src/app/binding-set.coffee index 9fadc8756..a13c564c1 100644 --- a/src/app/binding-set.coffee +++ b/src/app/binding-set.coffee @@ -5,6 +5,10 @@ fsUtils = require 'fs-utils' Specificity = require 'specificity' PEG = require 'pegjs' +### +# Internal # +### + module.exports = class BindingSet diff --git a/src/app/buffer-change-operation.coffee b/src/app/buffer-change-operation.coffee index cbbf68b0a..2dc6ccb08 100644 --- a/src/app/buffer-change-operation.coffee +++ b/src/app/buffer-change-operation.coffee @@ -1,6 +1,10 @@ Range = require 'range' _ = require 'underscore' +### +# Internal # +### + module.exports = class BufferChangeOperation buffer: null diff --git a/src/app/buffer-marker.coffee b/src/app/buffer-marker.coffee index d232a11cd..4a6e35af1 100644 --- a/src/app/buffer-marker.coffee +++ b/src/app/buffer-marker.coffee @@ -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 diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index bf7eaa73f..e2905fdb7 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -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()]) diff --git a/src/app/display-buffer-marker.coffee b/src/app/display-buffer-marker.coffee index fdea2cf4d..d88f67bdc 100644 --- a/src/app/display-buffer-marker.coffee +++ b/src/app/display-buffer-marker.coffee @@ -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 diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index a3cfe3224..ee7daac27 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -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) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index ce6b241e7..7100c5429 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -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) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index fbe6694ba..202f817cf 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -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 = $('') @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 diff --git a/src/app/git.coffee b/src/app/git.coffee index b8cef0275..7c15a55ac 100644 --- a/src/app/git.coffee +++ b/src/app/git.coffee @@ -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 diff --git a/src/app/language-mode.coffee b/src/app/language-mode.coffee index afe271085..2ad48459d 100644 --- a/src/app/language-mode.coffee +++ b/src/app/language-mode.coffee @@ -5,6 +5,10 @@ require 'underscore-extensions' EventEmitter = require 'event-emitter' Subscriber = require 'subscriber' +### +# Internal # +### + module.exports = class LanguageMode buffer = null diff --git a/src/app/null-grammar.coffee b/src/app/null-grammar.coffee index 2f2a37108..8b5e7b3e4 100644 --- a/src/app/null-grammar.coffee +++ b/src/app/null-grammar.coffee @@ -1,5 +1,8 @@ Token = require 'token' +### +# Internal # +### module.exports = class NullGrammar name: 'Null Grammar' diff --git a/src/app/package.coffee b/src/app/package.coffee index b3f3333e0..d4b72a446 100644 --- a/src/app/package.coffee +++ b/src/app/package.coffee @@ -1,5 +1,8 @@ fsUtils = require 'fs-utils' +### +# Internal # +### module.exports = class Package @build: (path) -> diff --git a/src/app/pane-row.coffee b/src/app/pane-row.coffee index 1db337994..d1030cd68 100644 --- a/src/app/pane-row.coffee +++ b/src/app/pane-row.coffee @@ -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" diff --git a/src/app/screen-line.coffee b/src/app/screen-line.coffee index 739d23eff..99a0424fb 100644 --- a/src/app/screen-line.coffee +++ b/src/app/screen-line.coffee @@ -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 diff --git a/src/app/selection.coffee b/src/app/selection.coffee index 206b83757..e7b69a2a3 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -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) diff --git a/src/app/syntax.coffee b/src/app/syntax.coffee index c5d0a75cb..c7076fbd2 100644 --- a/src/app/syntax.coffee +++ b/src/app/syntax.coffee @@ -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 } diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index eee35ccd5..cc1cc1901 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -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()] diff --git a/src/app/text-mate-grammar.coffee b/src/app/text-mate-grammar.coffee index 95d52db1c..62caed59d 100644 --- a/src/app/text-mate-grammar.coffee +++ b/src/app/text-mate-grammar.coffee @@ -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()] diff --git a/src/app/text-mate-package.coffee b/src/app/text-mate-package.coffee index 10156f4ba..80961754c 100644 --- a/src/app/text-mate-package.coffee +++ b/src/app/text-mate-package.coffee @@ -5,6 +5,10 @@ _ = require 'underscore' TextMateGrammar = require 'text-mate-grammar' async = require 'async' +### +# Internal # +### + module.exports = class TextMatePackage extends Package @testName: (packageName) -> diff --git a/src/app/text-mate-theme.coffee b/src/app/text-mate-theme.coffee index 3054b0633..c032ec620 100644 --- a/src/app/text-mate-theme.coffee +++ b/src/app/text-mate-theme.coffee @@ -3,6 +3,10 @@ fsUtils = require 'fs-utils' plist = require 'plist' Theme = require 'theme' +### +# Internal # +### + module.exports = class TextMateTheme extends Theme @testPath: (path) -> diff --git a/src/app/theme.coffee b/src/app/theme.coffee index da038e391..d6ebdff6b 100644 --- a/src/app/theme.coffee +++ b/src/app/theme.coffee @@ -1,5 +1,9 @@ fsUtils = require 'fs-utils' +### +# Internal # +### + module.exports = class Theme @stylesheets: null diff --git a/src/app/tokenized-buffer.coffee b/src/app/tokenized-buffer.coffee index 14a53b3bb..35d38bff4 100644 --- a/src/app/tokenized-buffer.coffee +++ b/src/app/tokenized-buffer.coffee @@ -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()) diff --git a/src/app/undo-manager.coffee b/src/app/undo-manager.coffee index 16ee55aa2..d5f914ea8 100644 --- a/src/app/undo-manager.coffee +++ b/src/app/undo-manager.coffee @@ -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