From 60660300593cdafb6cd45416a074be5c7b79c81e Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Mon, 1 Apr 2013 09:49:53 -0700 Subject: [PATCH 01/51] Test it out --- src/app/editor.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 42effb3a7..1f98c6549 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -163,7 +163,13 @@ class Editor extends View do (name, method) => @command name, => method.call(this); false + # Public: Retrieves a single cursor + # + # Returns [Cursor]. getCursor: -> @activeEditSession.getCursor() + # Public: Retrieves a list of all the cursors. + # + # Returns {[Cursor]}. getCursors: -> @activeEditSession.getCursors() addCursorAtScreenPosition: (screenPosition) -> @activeEditSession.addCursorAtScreenPosition(screenPosition) addCursorAtBufferPosition: (bufferPosition) -> @activeEditSession.addCursorAtBufferPosition(bufferPosition) From 0b6c817f0adf7cd9de194525187a1036f1d834d6 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 2 Apr 2013 14:00:56 -0700 Subject: [PATCH 02/51] First drop of comments --- src/app/edit-session.coffee | 30 +++++++++++++++++++++++++ src/app/editor.coffee | 44 ++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index e14baa16a..9535662fb 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -371,6 +371,7 @@ class EditSession toggleLineCommentsForBufferRows: (start, end) -> @languageMode.toggleLineCommentsForBufferRows(start, end) + # Public: Moves the selected line up one row. moveLineUp: -> selection = @getSelectedBufferRange() return if selection.start.row is 0 @@ -404,6 +405,7 @@ class EditSession @setSelectedBufferRange(selection.translate([-1]), preserveFolds: true) + # Public: Moves the selected line down one row. moveLineDown: -> selection = @getSelectedBufferRange() lastRow = @buffer.getLastRow() @@ -553,18 +555,37 @@ class EditSession isMarkerReversed: (args...) -> @displayBuffer.isMarkerReversed(args...) + # Public: Returns `true` if there are multiple cursors in the edit session. + # + # Returns a {Boolean}. hasMultipleCursors: -> @getCursors().length > 1 + # Public: Retrieves an array of all the cursors. + # + # Returns a {[Cursor]}. getCursors: -> new Array(@cursors...) + # Public: Retrieves a single cursor + # + # Returns a {Cursor}. getCursor: -> _.last(@cursors) + # Public: Adds a cursor at the provided `screenPosition`. + # + # screenPosition - An {Array} of two numbers: the screen row, and the screen column. + # + # Returns the new {Cursor}. addCursorAtScreenPosition: (screenPosition) -> marker = @markScreenPosition(screenPosition, invalidationStrategy: 'never') @addSelection(marker).cursor + # Public: Adds a cursor at the provided `bufferPosition`. + # + # bufferPosition - An {Array} of two numbers: the buffer row, and the buffer column. + # + # Returns the new {Cursor}. addCursorAtBufferPosition: (bufferPosition) -> marker = @markBufferPosition(bufferPosition, invalidationStrategy: 'never') @addSelection(marker).cursor @@ -686,30 +707,39 @@ class EditSession getWordUnderCursor: (options) -> @getTextInBufferRange(@getCursor().getCurrentWordBufferRange(options)) + # Public: Moves every cursor up one row. moveCursorUp: (lineCount) -> @moveCursors (cursor) -> cursor.moveUp(lineCount) + # Public: Moves every cursor down one row. moveCursorDown: (lineCount) -> @moveCursors (cursor) -> cursor.moveDown(lineCount) + # Public: Moves every cursor left one column. moveCursorLeft: -> @moveCursors (cursor) -> cursor.moveLeft() + # Public: Moves every cursor right one column. moveCursorRight: -> @moveCursors (cursor) -> cursor.moveRight() + # Public: Moves every cursor to the top of the buffer. moveCursorToTop: -> @moveCursors (cursor) -> cursor.moveToTop() + # Public: Moves every cursor to the bottom of the buffer. moveCursorToBottom: -> @moveCursors (cursor) -> cursor.moveToBottom() + # Public: Moves every cursor to the beginning of the line. moveCursorToBeginningOfLine: -> @moveCursors (cursor) -> cursor.moveToBeginningOfLine() + # Public: Moves every cursor to the first non-whitespace character of the line. moveCursorToFirstCharacterOfLine: -> @moveCursors (cursor) -> cursor.moveToFirstCharacterOfLine() + # Public: Moves every cursor to the end of the line. moveCursorToEndOfLine: -> @moveCursors (cursor) -> cursor.moveToEndOfLine() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 1f98c6549..f51748a5e 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -10,6 +10,7 @@ fs = require 'fs-utils' $ = require 'jquery' _ = require 'underscore' +# Public: Represents the visual pane in Atom. module.exports = class Editor extends View @configDefaults: @@ -56,6 +57,13 @@ class Editor extends View newSelections: null redrawOnReattach: false + # Public: The constructor for setting up an `Editor` instance. + # + # editSessionOrOptions - Either an {EditSession}, or an object with one property, `mini`. + # If `mini` is `true`, a "miniature" `EditSession` is constructed. + # Typically, this is ideal for scenarios where you need an Atom editor, + # but without all the chrome, like scrollbars, gutter, _e.t.c._. + # initialize: (editSessionOrOptions) -> if editSessionOrOptions instanceof EditSession editSession = editSessionOrOptions @@ -87,6 +95,9 @@ class Editor extends View else throw new Error("Must supply an EditSession or mini: true") + # Internal: Sets up the core Atom commands. + # + # Some commands are excluded from mini-editors. bindKeys: -> editorBindings = 'core:move-left': @moveCursorLeft @@ -165,27 +176,54 @@ class Editor extends View # Public: Retrieves a single cursor # - # Returns [Cursor]. + # Returns a {Cursor}. getCursor: -> @activeEditSession.getCursor() - # Public: Retrieves a list of all the cursors. + # Public: Retrieves an array of all the cursors. # - # Returns {[Cursor]}. + # Returns a {[Cursor]}. getCursors: -> @activeEditSession.getCursors() + # Public: Adds a cursor at the provided `screenPosition`. + # + # screenPosition - An {Array} of two numbers: the screen row, and the screen column. + # + # Returns the new {Cursor}. addCursorAtScreenPosition: (screenPosition) -> @activeEditSession.addCursorAtScreenPosition(screenPosition) + # Public: Adds a cursor at the provided `bufferPosition`. + # + # bufferPosition - An {Array} of two numbers: the buffer row, and the buffer column. + # + # Returns the new {Cursor}. addCursorAtBufferPosition: (bufferPosition) -> @activeEditSession.addCursorAtBufferPosition(bufferPosition) + # Public: Moves every cursor up one row. moveCursorUp: -> @activeEditSession.moveCursorUp() + # Public: Moves every cursor down one row. moveCursorDown: -> @activeEditSession.moveCursorDown() + # Public: Moves every cursor left one column. moveCursorLeft: -> @activeEditSession.moveCursorLeft() + # Public: Moves every cursor right one column. moveCursorRight: -> @activeEditSession.moveCursorRight() + # Public: Moves every cursor to the beginning of the current word. moveCursorToBeginningOfWord: -> @activeEditSession.moveCursorToBeginningOfWord() + # Public: Moves every cursor to the end of the current word. moveCursorToEndOfWord: -> @activeEditSession.moveCursorToEndOfWord() + # Public: Moves every cursor to the top of the buffer. moveCursorToTop: -> @activeEditSession.moveCursorToTop() + # Public: Moves every cursor to the bottom of the buffer. moveCursorToBottom: -> @activeEditSession.moveCursorToBottom() + # Public: Moves every cursor to the beginning of the line. moveCursorToBeginningOfLine: -> @activeEditSession.moveCursorToBeginningOfLine() + # Public: Moves every cursor to the first non-whitespace character of the line. moveCursorToFirstCharacterOfLine: -> @activeEditSession.moveCursorToFirstCharacterOfLine() + # Public: Moves every cursor to the end of the line. moveCursorToEndOfLine: -> @activeEditSession.moveCursorToEndOfLine() + # Public: Moves the selected line up one row. moveLineUp: -> @activeEditSession.moveLineUp() + # Public: Moves the selected line down one row. moveLineDown: -> @activeEditSession.moveLineDown() + # Public: Sets the cursor based on a given screen position. + # + # position - An {Array} of two numbers: the screen row, and the screen column. + # options - An object with the following properties: setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options) duplicateLine: -> @activeEditSession.duplicateLine() getCursorScreenPosition: -> @activeEditSession.getCursorScreenPosition() From 83c6975d34b701d3b0a3ee4b6f093b8c2f9f6719 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 2 Apr 2013 16:47:30 -0700 Subject: [PATCH 03/51] Add a rake task, of course --- Rakefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Rakefile b/Rakefile index f4fa7f69e..f092f705d 100644 --- a/Rakefile +++ b/Rakefile @@ -114,6 +114,10 @@ task :tags do system %{find src native cef vendor -not -name "*spec.coffee" -type f -print0 | xargs -0 ctags} end +task :docs do + system %{./biscotto src/app/} +end + def application_path applications = FileList["#{BUILD_DIR}/**/Atom.app"] if applications.size == 0 From bd1b407a4b71d0a668b5402949226d3fc30aefde Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 2 Apr 2013 17:30:11 -0700 Subject: [PATCH 04/51] Add that rake task --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index f092f705d..644328b6a 100644 --- a/Rakefile +++ b/Rakefile @@ -115,7 +115,7 @@ task :tags do end task :docs do - system %{./biscotto src/app/} + system %{./biscotto -j ~/Development/biscotto/out.json src/app/} end def application_path From da59785c76a09794e6ceb3d8028421ce92d40733 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 2 Apr 2013 17:30:25 -0700 Subject: [PATCH 05/51] Dummy package placeholder --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 8141637a0..0f5e86783 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,10 @@ "space-pen": "git://github.com/nathansobo/space-pen.git" }, + "devDependencies": { + "biscotto": "0.0.2" + }, + "private": true, "scripts": { From 3d076daf54ce23cc1d8c87384da85821f4f93744 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 2 Apr 2013 17:54:34 -0700 Subject: [PATCH 06/51] More updates --- src/app/editor.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index f51748a5e..4d2ef6823 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -225,7 +225,10 @@ class Editor extends View # position - An {Array} of two numbers: the screen row, and the screen column. # options - An object with the following properties: setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options) + # Public: Duplicates the current line. duplicateLine: -> @activeEditSession.duplicateLine() + # Public: Duplicates the current line. + getCursorScreenPosition: -> @activeEditSession.getCursorScreenPosition() getCursorScreenRow: -> @activeEditSession.getCursorScreenRow() setCursorBufferPosition: (position, options) -> @activeEditSession.setCursorBufferPosition(position, options) From 9e38537239e7154e5e5b8bff5027dcb9389303f4 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Thu, 4 Apr 2013 18:54:36 -0700 Subject: [PATCH 07/51] Hella docs, we're up to 10% coverage --- src/app/cursor.coffee | 25 +++++-- src/app/edit-session.coffee | 130 ++++++++++++++++++++++++++++++++---- src/app/editor.coffee | 120 +++++++++++++++++++++++++++++++-- 3 files changed, 252 insertions(+), 23 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 5708d4bf7..4b994f75b 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -37,18 +37,31 @@ class Cursor @editSession.destroyMarker(@marker) @editSession.removeCursor(this) @trigger 'destroyed' - + # Public: Moves a cursor to a given screen position. + # + # position - An {Array} of two numbers: the screen row, and the screen column. + # options - An object with properties based on {Cursor.changePosition} + # setScreenPosition: (screenPosition, options={}) -> @changePosition options, => @editSession.setMarkerHeadScreenPosition(@marker, screenPosition, options) + # Public: Gets the current screen position. + # + # Returns an {Array} of two numbers: the screen row, and the screen column. getScreenPosition: -> @editSession.getMarkerHeadScreenPosition(@marker) - + # Public: Moves a cursor to a given buffer position. + # + # position - An {Array} of two numbers: the screen row, and the screen column. + # options - An object with properties based on {Cursor.changePosition} + # setBufferPosition: (bufferPosition, options={}) -> @changePosition options, => @editSession.setMarkerHeadBufferPosition(@marker, bufferPosition, options) - + # Public: Gets the current buffer position. + # + # Returns an {Array} of two numbers: the buffer row, and the buffer column. getBufferPosition: -> @editSession.getMarkerHeadBufferPosition(@marker) @@ -188,7 +201,11 @@ class Cursor stop() endOfWordPosition or currentBufferPosition - + # Public: Gets the word located under the cursor. + # + # options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}. + # + # Returns a {String}. getCurrentWordBufferRange: (options={}) -> startOptions = _.extend(_.clone(options), allowPrevious: false) endOptions = _.extend(_.clone(options), allowNext: false) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 9535662fb..1a15144f2 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -171,10 +171,30 @@ class EditSession screenRangeForBufferRange: (range) -> @displayBuffer.screenRangeForBufferRange(range) bufferRangeForScreenRange: (range) -> @displayBuffer.bufferRangeForScreenRange(range) clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options) + # Public: Gets the line for the given screen row. + # + # screenRow - A {Number} indicating the screen row. + # + # Returns a {String}. lineForScreenRow: (row) -> @displayBuffer.lineForRow(row) + # Public: Gets the lines for the given screen row boundaries. + # + # start - A {Number} indicating the beginning screen row. + # start - A {Number} indicating the ending screen row. + # + # Returns an {Array} of {String}s. linesForScreenRows: (start, end) -> @displayBuffer.linesForRows(start, end) + # Public: Gets the number of screen rows. + # + # Returns a {Number}. screenLineCount: -> @displayBuffer.lineCount() + # Public: Gets the length of the longest screen line. + # + # Returns a {Number}. maxScreenLineLength: -> @displayBuffer.maxLineLength() + # Public: Gets the text in the last screen row. + # + # Returns a {String}. getLastScreenRow: -> @displayBuffer.getLastRow() bufferRowsForScreenRows: (startRow, endRow) -> @displayBuffer.bufferRowsForScreenRows(startRow, endRow) scopesForBufferPosition: (bufferPosition) -> @displayBuffer.scopesForBufferPosition(bufferPosition) @@ -186,19 +206,25 @@ class EditSession shouldAutoIndentPastedText: -> config.get("editor.autoIndentOnPaste") - + # Public: Inserts text at the current cursor positions. + # + # text - A {String} representing the text to insert. + # options - A set of options equivalent to {Selection.insertText}. insertText: (text, options={}) -> options.autoIndent ?= @shouldAutoIndent() @mutateSelectedText (selection) -> selection.insertText(text, options) + # Public: Inserts a new line at the current cursor positions. insertNewline: -> @insertText('\n') + # Public: Inserts a new line below the current cursor positions. insertNewlineBelow: -> @transact => @moveCursorToEndOfLine() @insertNewline() + # Public: Inserts a new line above the current cursor positions. insertNewlineAbove: -> @transact => onFirstLine = @getCursorBufferPosition().row is 0 @@ -207,31 +233,42 @@ class EditSession @insertNewline() @moveCursorUp() if onFirstLine + # Public: Indents the current line. + # + # options - A set of options equivalent to {Selection.indent}. indent: (options={})-> options.autoIndent ?= @shouldAutoIndent() @mutateSelectedText (selection) -> selection.indent(options) + # Public: Performs a backspace, removing the character found behind the cursor position. backspace: -> @mutateSelectedText (selection) -> selection.backspace() + # Public: Performs a backspace to the beginning of the current word, removing characters found there. backspaceToBeginningOfWord: -> @mutateSelectedText (selection) -> selection.backspaceToBeginningOfWord() + # Public: Performs a backspace to the beginning of the current line, removing characters found there. backspaceToBeginningOfLine: -> @mutateSelectedText (selection) -> selection.backspaceToBeginningOfLine() + # Public: Performs a delete, removing the character found behind the cursor position. delete: -> @mutateSelectedText (selection) -> selection.delete() + # Public: Performs a delete to the end of the current word, removing characters found there. deleteToEndOfWord: -> @mutateSelectedText (selection) -> selection.deleteToEndOfWord() + # Public: Performs a delete to the end of the current line, removing characters found there. deleteLine: -> @mutateSelectedText (selection) -> selection.deleteLine() + # Public: Indents the selected rows. indentSelectedRows: -> @mutateSelectedText (selection) -> selection.indentSelectedRows() + # Public: Outdents the selected rows. outdentSelectedRows: -> @mutateSelectedText (selection) -> selection.outdentSelectedRows() @@ -245,24 +282,32 @@ class EditSession return unless @softTabs @scanInRange /\t/, bufferRange, (match, range, {replace}) => replace(@getTabText()) + # Public: Performs a cut to the end of the current line. + # + # Characters are removed, but the text remains in the clipboard. cutToEndOfLine: -> maintainPasteboard = false @mutateSelectedText (selection) -> selection.cutToEndOfLine(maintainPasteboard) maintainPasteboard = true + # Public: Cuts the selected text. cutSelectedText: -> maintainPasteboard = false @mutateSelectedText (selection) -> selection.cut(maintainPasteboard) maintainPasteboard = true + # Public: Copies the selected text. copySelectedText: -> maintainPasteboard = false for selection in @getSelections() selection.copy(maintainPasteboard) maintainPasteboard = true + # Public: Pastes the text in the clipboard. + # + # options - A set of options equivalent to {Selection.insertText}. pasteText: (options={}) -> options.normalizeIndent ?= true options.autoIndent ?= @shouldAutoIndentPastedText() @@ -272,9 +317,11 @@ class EditSession @insertText(text, options) + # Public: Undos the last {Buffer} change. undo: -> @buffer.undo(this) + # Public: Redos the last {Buffer} change. redo: -> @buffer.redo(this) @@ -299,12 +346,15 @@ class EditSession abort: -> @buffer.abort() + # Public: Folds all the rows. foldAll: -> @displayBuffer.foldAll() + # Public: Unfolds all the rows. unfoldAll: -> @displayBuffer.unfoldAll() + # Public: Folds the current row. foldCurrentRow: -> bufferRow = @bufferPositionForScreenPosition(@getCursorScreenPosition()).row @foldBufferRow(bufferRow) @@ -312,6 +362,7 @@ class EditSession foldBufferRow: (bufferRow) -> @displayBuffer.foldBufferRow(bufferRow) + # Public: Unfolds the current row. unfoldCurrentRow: -> bufferRow = @bufferPositionForScreenPosition(@getCursorScreenPosition()).row @unfoldBufferRow(bufferRow) @@ -337,13 +388,22 @@ class EditSession fold.destroy() @setCursorBufferPosition([fold.startRow, 0]) + # Public: Determines if the given row that the cursor is at is folded. + # + # Returns `true` if the row is folded, `false` otherwise. isFoldedAtCursorRow: -> @isFoldedAtScreenRow(@getCursorScreenRow()) - + # Public: Determines if the given buffer row is folded. + # + # screenRow - A {Number} indicating the buffer row. + # Returns `true` if the buffer row is folded, `false` otherwise. isFoldedAtBufferRow: (bufferRow) -> screenRow = @screenPositionForBufferPosition([bufferRow]).row @isFoldedAtScreenRow(screenRow) - + # Public: Determines if the given screen row is folded. + # + # screenRow - A {Number} indicating the screen row. + # Returns `true` if the screen row is folded, `false` otherwise. isFoldedAtScreenRow: (screenRow) -> @lineForScreenRow(screenRow)?.fold? @@ -637,15 +697,20 @@ class EditSession @addSelectionForBufferRange(bufferRange, options) @mergeIntersectingSelections(options) + # Public: Unselects a given selection. + # + # selection - The {Selection} to remove. removeSelection: (selection) -> _.remove(@selections, selection) + # Public: Clears every selection. TODO clearSelections: -> lastSelection = @getLastSelection() for selection in @getSelections() when selection != lastSelection selection.destroy() lastSelection.clear() + # Public: Clears every selection. TODO clearAllSelections: -> selection.destroy() for selection in @getSelections() @@ -670,19 +735,33 @@ class EditSession selectionIntersectsBufferRange: (bufferRange) -> _.any @getSelections(), (selection) -> selection.intersectsBufferRange(bufferRange) - + # Public: Moves every cursor to a given screen position. + # + # position - An {Array} of two numbers: the screen row, and the screen column. + # options - An object with properties based on {Cursor.changePosition} + # setCursorScreenPosition: (position, options) -> @moveCursors (cursor) -> cursor.setScreenPosition(position, options) - + # Public: Gets the current screen position. + # + # Returns an {Array} of two numbers: the screen row, and the screen column. getCursorScreenPosition: -> @getCursor().getScreenPosition() - + # Public: Gets the current cursor's screen row. + # + # Returns the screen row. getCursorScreenRow: -> @getCursor().getScreenRow() - + # Public: Moves every cursor to a given buffer position. + # + # position - An {Array} of two numbers: the buffer row, and the buffer column. + # options - An object with properties based on {Cursor.changePosition} + # setCursorBufferPosition: (position, options) -> @moveCursors (cursor) -> cursor.setBufferPosition(position, options) - + # Public: Gets the current buffer position. + # + # Returns an {Array} of two numbers: the buffer row, and the buffer column. getCursorBufferPosition: -> @getCursor().getBufferPosition() @@ -694,7 +773,9 @@ class EditSession getSelectedBufferRanges: -> selection.getBufferRange() for selection in @getSelectionsOrderedByBufferPosition() - + # Public: Gets the currently selected text. + # + # Returns a {String}. getSelectedText: -> @getLastSelection().getText() @@ -703,7 +784,11 @@ class EditSession getCurrentParagraphBufferRange: -> @getCursor().getCurrentParagraphBufferRange() - + # Public: Gets the word located under the cursor. + # + # options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}. + # + # Returns a {String}. getWordUnderCursor: (options) -> @getTextInBufferRange(@getCursor().getCurrentWordBufferRange(options)) @@ -753,41 +838,57 @@ class EditSession fn(cursor) for cursor in @getCursors() @mergeCursors() + # Public: Selects the text from the current cursor position to a given position. + # + # position - An instance of {Point}, with a given `row` and `column`. selectToScreenPosition: (position) -> lastSelection = @getLastSelection() lastSelection.selectToScreenPosition(position) @mergeIntersectingSelections(reverse: lastSelection.isReversed()) - + # Public: Selects the text one position right of the cursor. selectRight: -> @expandSelectionsForward (selection) => selection.selectRight() - + # Public: Selects the text one position left of the cursor. selectLeft: -> @expandSelectionsBackward (selection) => selection.selectLeft() + # Public: Selects all the text one position above the cursor. selectUp: -> @expandSelectionsBackward (selection) => selection.selectUp() + # Public: Selects all the text one position below the cursor. selectDown: -> @expandSelectionsForward (selection) => selection.selectDown() + # Public: Selects all the text from the current cursor position to the top of the buffer. selectToTop: -> @expandSelectionsBackward (selection) => selection.selectToTop() + # Public: Selects all the text in the buffer. selectAll: -> @expandSelectionsForward (selection) => selection.selectAll() + # Public: Selects all the text from the current cursor position to the bottom of the buffer. selectToBottom: -> @expandSelectionsForward (selection) => selection.selectToBottom() + # Public: Selects all the text from the current cursor position to the beginning of the line. selectToBeginningOfLine: -> @expandSelectionsBackward (selection) => selection.selectToBeginningOfLine() + # Public: Selects all the text from the current cursor position to the end of the line. selectToEndOfLine: -> @expandSelectionsForward (selection) => selection.selectToEndOfLine() + # Public: Selects the current line. selectLine: -> @expandSelectionsForward (selection) => selection.selectLine() + # Public: Transposes the current text selections. + # + # This only works if there is more than one selection. Each selection is transferred + # to the position of the selection after it. The last selection is transferred to the + # position of the first. transpose: -> @mutateSelectedText (selection) => if selection.isEmpty() @@ -799,21 +900,26 @@ class EditSession else selection.insertText selection.getText().split('').reverse().join('') + # Public: Turns the current selection into upper case. upperCase: -> @replaceSelectedText selectWordIfEmpty:true, (text) => text.toUpperCase() + # Public: Turns the current selection into lower case. lowerCase: -> @replaceSelectedText selectWordIfEmpty:true, (text) => text.toLowerCase() expandLastSelectionOverLine: -> @getLastSelection().expandOverLine() + # Public: Selects all the text from the current cursor position to the beginning of the word. selectToBeginningOfWord: -> @expandSelectionsBackward (selection) => selection.selectToBeginningOfWord() + # Public: Selects all the text from the current cursor position to the end of the word. selectToEndOfWord: -> @expandSelectionsForward (selection) => selection.selectToEndOfWord() + # Public: Selects the current word. selectWord: -> @expandSelectionsForward (selection) => selection.selectWord() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 4d2ef6823..4ee4ecc5c 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -223,90 +223,197 @@ class Editor extends View # Public: Sets the cursor based on a given screen position. # # position - An {Array} of two numbers: the screen row, and the screen column. - # options - An object with the following properties: + # options - An object with properties based on {Cursor.changePosition}. + # setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options) # Public: Duplicates the current line. duplicateLine: -> @activeEditSession.duplicateLine() - # Public: Duplicates the current line. - + # Public: Gets the current screen position. + # + # Returns an {Array} of two numbers: the screen row, and the screen column. getCursorScreenPosition: -> @activeEditSession.getCursorScreenPosition() + # Public: Gets the current screen row. + # + # Returns a {Number}. getCursorScreenRow: -> @activeEditSession.getCursorScreenRow() + # Public: Sets the cursor based on a given buffer position. + # + # position - An {Array} of two numbers: the buffer row, and the buffer column. + # options - An object with properties based on {Cursor.changePosition}. + # setCursorBufferPosition: (position, options) -> @activeEditSession.setCursorBufferPosition(position, options) + # Public: Gets the current buffer position. + # + # Returns an {Array} of two numbers: the buffer row, and the buffer column. getCursorBufferPosition: -> @activeEditSession.getCursorBufferPosition() getCurrentParagraphBufferRange: -> @activeEditSession.getCurrentParagraphBufferRange() + # Public: Gets the word located under the cursor. + # + # options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}. + # + # Returns a {String}. getWordUnderCursor: (options) -> @activeEditSession.getWordUnderCursor(options) getSelection: (index) -> @activeEditSession.getSelection(index) getSelections: -> @activeEditSession.getSelections() getSelectionsOrderedByBufferPosition: -> @activeEditSession.getSelectionsOrderedByBufferPosition() getLastSelectionInBuffer: -> @activeEditSession.getLastSelectionInBuffer() + # Public: Gets the currently selected text. + # + # Returns a {String}. getSelectedText: -> @activeEditSession.getSelectedText() getSelectedBufferRanges: -> @activeEditSession.getSelectedBufferRanges() getSelectedBufferRange: -> @activeEditSession.getSelectedBufferRange() setSelectedBufferRange: (bufferRange, options) -> @activeEditSession.setSelectedBufferRange(bufferRange, options) setSelectedBufferRanges: (bufferRanges, options) -> @activeEditSession.setSelectedBufferRanges(bufferRanges, options) addSelectionForBufferRange: (bufferRange, options) -> @activeEditSession.addSelectionForBufferRange(bufferRange, options) + # Public: Selects the text one position right of the cursor. selectRight: -> @activeEditSession.selectRight() + # Public: Selects the text one position left of the cursor. selectLeft: -> @activeEditSession.selectLeft() + # Public: Selects all the text one position above the cursor. selectUp: -> @activeEditSession.selectUp() + # Public: Selects all the text one position below the cursor. selectDown: -> @activeEditSession.selectDown() + # Public: Selects all the text from the current cursor position to the top of the buffer. selectToTop: -> @activeEditSession.selectToTop() + # Public: Selects all the text from the current cursor position to the bottom of the buffer. selectToBottom: -> @activeEditSession.selectToBottom() + # Public: Selects all the text in the buffer. selectAll: -> @activeEditSession.selectAll() + # Public: Selects all the text from the current cursor position to the beginning of the line. selectToBeginningOfLine: -> @activeEditSession.selectToBeginningOfLine() + # Public: Selects all the text from the current cursor position to the end of the line. selectToEndOfLine: -> @activeEditSession.selectToEndOfLine() + # Public: Selects all the text from the current cursor position to the beginning of the word. selectToBeginningOfWord: -> @activeEditSession.selectToBeginningOfWord() + # Public: Selects all the text from the current cursor position to the end of the word. selectToEndOfWord: -> @activeEditSession.selectToEndOfWord() + # Public: Selects the current word. selectWord: -> @activeEditSession.selectWord() + # Public: Selects the text from the current cursor position to a given position. + # + # position - An instance of {Point}, with a given `row` and `column`. selectToScreenPosition: (position) -> @activeEditSession.selectToScreenPosition(position) + # Public: Transposes the current text selections. + # + # This only works if there is more than one selection. Each selection is transferred + # to the position of the selection after it. The last selection is transferred to the + # position of the first. transpose: -> @activeEditSession.transpose() + # Public: Turns the current selection into upper case. upperCase: -> @activeEditSession.upperCase() + # Public: Turns the current selection into lower case. lowerCase: -> @activeEditSession.lowerCase() + # Public: Clears every selection. TODO clearSelections: -> @activeEditSession.clearSelections() + # Public: Performs a backspace, removing the character found behind the cursor position. backspace: -> @activeEditSession.backspace() + # Public: Performs a backspace to the beginning of the current word, removing characters found there. backspaceToBeginningOfWord: -> @activeEditSession.backspaceToBeginningOfWord() + # Public: Performs a backspace to the beginning of the current line, removing characters found there. backspaceToBeginningOfLine: -> @activeEditSession.backspaceToBeginningOfLine() + # Public: Performs a delete, removing the character found ahead the cursor position. delete: -> @activeEditSession.delete() + # Public: Performs a delete to the end of the current word, removing characters found there. deleteToEndOfWord: -> @activeEditSession.deleteToEndOfWord() + # Public: Performs a delete to the end of the current line, removing characters found there. deleteLine: -> @activeEditSession.deleteLine() + # Public: Performs a cut to the end of the current line. + # + # Characters are removed, but the text remains in the clipboard. cutToEndOfLine: -> @activeEditSession.cutToEndOfLine() + # Public: Inserts text at the current cursor positions. + # + # text - A {String} representing the text to insert. + # options - A set of options equivalent to {Selection.insertText}. insertText: (text, options) -> @activeEditSession.insertText(text, options) + # Public: Inserts a new line at the current cursor positions. insertNewline: -> @activeEditSession.insertNewline() + # Public: Inserts a new line below the current cursor positions. insertNewlineBelow: -> @activeEditSession.insertNewlineBelow() + # Public: Inserts a new line above the current cursor positions. insertNewlineAbove: -> @activeEditSession.insertNewlineAbove() + # Public: Indents the current line. + # + # options - A set of options equivalent to {Selection.indent}. indent: (options) -> @activeEditSession.indent(options) - autoIndent: (options) -> @activeEditSession.autoIndentSelectedRows(options) + # Public: TODO + autoIndent: -> @activeEditSession.autoIndentSelectedRows() + # Public: Indents the selected rows. indentSelectedRows: -> @activeEditSession.indentSelectedRows() + # Public: Outdents the selected rows. outdentSelectedRows: -> @activeEditSession.outdentSelectedRows() + # Public: Cuts the selected text. cutSelection: -> @activeEditSession.cutSelectedText() + # Public: Copies the selected text. copySelection: -> @activeEditSession.copySelectedText() - paste: -> @activeEditSession.pasteText() + # Public: Pastes the text in the clipboard. + # + # options - A set of options equivalent to {Selection.insertText}. + paste: (options) -> @activeEditSession.pasteText(options) + # Public: Undos the last {Buffer} change. undo: -> @activeEditSession.undo() + # Public: Redos the last {Buffer} change. redo: -> @activeEditSession.redo() transact: (fn) -> @activeEditSession.transact(fn) commit: -> @activeEditSession.commit() abort: -> @activeEditSession.abort() createFold: (startRow, endRow) -> @activeEditSession.createFold(startRow, endRow) + # Public: Folds the current row. foldCurrentRow: -> @activeEditSession.foldCurrentRow() + # Public: Unfolds the current row. unfoldCurrentRow: -> @activeEditSession.unfoldCurrentRow() + # Public: Folds all the rows. foldAll: -> @activeEditSession.foldAll() + # Public: Unfolds all the rows. unfoldAll: -> @activeEditSession.unfoldAll() foldSelection: -> @activeEditSession.foldSelection() destroyFold: (foldId) -> @activeEditSession.destroyFold(foldId) destroyFoldsContainingBufferRow: (bufferRow) -> @activeEditSession.destroyFoldsContainingBufferRow(bufferRow) + # Public: Determines if the given screen row is folded. + # + # screenRow - A {Number} indicating the screen row. + # Returns `true` if the screen row is folded, `false` otherwise. isFoldedAtScreenRow: (screenRow) -> @activeEditSession.isFoldedAtScreenRow(screenRow) + # Public: Determines if the given buffer row is folded. + # + # screenRow - A {Number} indicating the buffer row. + # Returns `true` if the buffer row is folded, `false` otherwise. isFoldedAtBufferRow: (bufferRow) -> @activeEditSession.isFoldedAtBufferRow(bufferRow) + # Public: Determines if the given row that the cursor is at is folded. + # + # Returns `true` if the row is folded, `false` otherwise. isFoldedAtCursorRow: -> @activeEditSession.isFoldedAtCursorRow() + # Public: Gets the line for the given screen row. + # + # screenRow - A {Number} indicating the screen row. + # + # Returns a {String}. lineForScreenRow: (screenRow) -> @activeEditSession.lineForScreenRow(screenRow) + # Public: Gets the lines for the given screen row boundaries. + # + # start - A {Number} indicating the beginning screen row. + # start - A {Number} indicating the ending screen row. + # + # Returns an {Array} of {String}s. linesForScreenRows: (start, end) -> @activeEditSession.linesForScreenRows(start, end) + # Public: Gets the number of screen rows. + # + # Returns a {Number}. screenLineCount: -> @activeEditSession.screenLineCount() setSoftWrapColumn: (softWrapColumn) -> softWrapColumn ?= @calcSoftWrapColumn() @activeEditSession.setSoftWrapColumn(softWrapColumn) if softWrapColumn - + # Public: Gets the length of the longest screen line. + # + # Returns a {Number}. maxScreenLineLength: -> @activeEditSession.maxScreenLineLength() + # Public: Gets the text in the last screen row. + # + # Returns a {String}. getLastScreenRow: -> @activeEditSession.getLastScreenRow() clipScreenPosition: (screenPosition, options={}) -> @activeEditSession.clipScreenPosition(screenPosition, options) screenPositionForBufferPosition: (position, options) -> @activeEditSession.screenPositionForBufferPosition(position, options) @@ -314,7 +421,6 @@ class Editor extends View screenRangeForBufferRange: (range) -> @activeEditSession.screenRangeForBufferRange(range) bufferRangeForScreenRange: (range) -> @activeEditSession.bufferRangeForScreenRange(range) bufferRowsForScreenRows: (startRow, endRow) -> @activeEditSession.bufferRowsForScreenRows(startRow, endRow) - getLastScreenRow: -> @activeEditSession.getLastScreenRow() logCursorScope: -> console.log @activeEditSession.getCursorScopes() From 003813f39d925320d4aec6285c561907816c6dd9 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 5 Apr 2013 13:54:56 -0700 Subject: [PATCH 08/51] Add statsOnly task --- Rakefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Rakefile b/Rakefile index 644328b6a..907b48bc3 100644 --- a/Rakefile +++ b/Rakefile @@ -114,10 +114,16 @@ task :tags do system %{find src native cef vendor -not -name "*spec.coffee" -type f -print0 | xargs -0 ctags} end +desc "Builds the API docs" task :docs do system %{./biscotto -j ~/Development/biscotto/out.json src/app/} end +desc "Lists the stats for API doc coverage" +task :docsStats do + system %{./biscotto --statsOnly src/app/} +end + def application_path applications = FileList["#{BUILD_DIR}/**/Atom.app"] if applications.size == 0 From fe0dc8181a961c4a358eb8a877eacfe55838245c Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 5 Apr 2013 14:33:58 -0700 Subject: [PATCH 09/51] More doc updates--now at 15% --- src/app/edit-session.coffee | 12 +++++ src/app/editor.coffee | 90 ++++++++++++++++++++++++++++++++++++- src/app/text-buffer.coffee | 36 ++++++++++++++- 3 files changed, 136 insertions(+), 2 deletions(-) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 1a15144f2..3ee9fa269 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -151,7 +151,13 @@ class EditSession save: -> @buffer.save() saveAs: (path) -> @buffer.saveAs(path) + # Public: Retrieves the current buffer's file extension. + # + # Returns a {String}. getFileExtension: -> @buffer.getExtension() + # Public: Retrieves the current buffer's file path. + # + # Returns a {String}. getPath: -> @buffer.getPath() getUri: -> @getPath() isBufferRowBlank: (bufferRow) -> @buffer.isRowBlank(bufferRow) @@ -977,8 +983,14 @@ class EditSession @setCursorBufferPosition(cursorPosition) if cursorPosition cursorPosition = null + # Public: Retrieves the current {EditSession}'s grammar. + # + # Returns a {String} indicating the {LanguageMode}'s grammar rules. getGrammar: -> @languageMode.grammar + # Public: Sets the current {EditSession}'s grammar. + # + # grammar - A {String} indicating the {LanguageMode}'s grammar rules. setGrammar: (grammar) -> @languageMode.grammar = grammar @handleGrammarChange() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 4ee4ecc5c..ec82da464 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -424,24 +424,39 @@ class Editor extends View logCursorScope: -> console.log @activeEditSession.getCursorScopes() - + # Public: Emulates the "page down" key, where the last row of a buffer scrolls to become the first. pageDown: -> newScrollTop = @scrollTop() + @scrollView[0].clientHeight @activeEditSession.moveCursorDown(@getPageRows()) @scrollTop(newScrollTop, adjustVerticalScrollbar: true) + + # Public: Emulates the "page up" key, where the frst row of a buffer scrolls to become the last. pageUp: -> newScrollTop = @scrollTop() - @scrollView[0].clientHeight @activeEditSession.moveCursorUp(@getPageRows()) @scrollTop(newScrollTop, adjustVerticalScrollbar: true) + # Public: Gets the number of actual page rows existing in an editor. + # + # Returns a {Number}. getPageRows: -> Math.max(1, Math.ceil(@scrollView[0].clientHeight / @lineHeight)) + # Public: Set whether invisible characters are shown. + # + # showInvisibles - A {Boolean} which, if `true`, show invisible characters setShowInvisibles: (showInvisibles) -> return if showInvisibles == @showInvisibles @showInvisibles = showInvisibles @resetDisplay() + # Public: Defines which characters are invisible. + # + # invisibles - A hash defining the invisible characters: The defaults are: + # :eol - `\u00ac` + # :space - `\u00b7` + # :tab - `\u00bb` + # :cr - `\u00a4` setInvisibles: (@invisibles={}) -> _.defaults @invisibles, eol: '\u00ac' @@ -450,20 +465,54 @@ class Editor extends View cr: '\u00a4' @resetDisplay() + # Public: Sets whether you want to show the indentation guides. + # + # showIndentGuide - A {Boolean} you can set to `true` if you want to see the indentation guides. setShowIndentGuide: (showIndentGuide) -> return if showIndentGuide == @showIndentGuide @showIndentGuide = showIndentGuide @resetDisplay() + # Public: Checks out the current HEAD revision of the file. checkoutHead: -> @getBuffer().checkoutHead() + # Public: Replaces the current buffer contents. + # + # text - A {String} containing the new buffer contents. setText: (text) -> @getBuffer().setText(text) + # Public: Retrieves the current buffer contents. + # + # Returns a {String}. getText: -> @getBuffer().getText() + # Public: Retrieves the current buffer's file path. + # + # Returns a {String}. getPath: -> @activeEditSession?.getPath() + # Public: Gets the number of lines in a file. + # + # Returns a {Number}. getLineCount: -> @getBuffer().getLineCount() + # Public: Gets the row number of the last line. + # + # Returns a {Number}. getLastBufferRow: -> @getBuffer().getLastRow() + # Public: Given a range, returns the lines of text within it. + # + # range - A {Range} object specifying your points of interest + # + # Returns a {String} of the combined lines. getTextInRange: (range) -> @getBuffer().getTextInRange(range) getEofPosition: -> @getBuffer().getEofPosition() + # Public: Given a row, returns the line of text. + # + # row - A {Number} indicating the row. + # + # Returns a {String}. lineForBufferRow: (row) -> @getBuffer().lineForRow(row) + # Public: Given a row, returns the length of the line of text. + # + # row - A {Number} indicating the row. + # + # Returns a {Number}. lineLengthForBufferRow: (row) -> @getBuffer().lineLengthForRow(row) rangeForBufferRow: (row) -> @getBuffer().rangeForRow(row) scanInRange: (args...) -> @getBuffer().scanInRange(args...) @@ -477,6 +526,7 @@ class Editor extends View @observeConfig 'editor.fontSize', (fontSize) => @setFontSize(fontSize) @observeConfig 'editor.fontFamily', (fontFamily) => @setFontFamily(fontFamily) + # Internal: Responsible for handling events made to the editor. handleEvents: -> @on 'focus', => @hiddenInput.focus() @@ -614,12 +664,21 @@ class Editor extends View if @attached and @activeEditSession.buffer.isInConflict() _.defer => @showBufferConflictAlert(@activeEditSession) # Display after editSession has a chance to display + # Internal: Retrieves the currently active session. + # + # Returns an {EditSession}. getModel: -> @activeEditSession + # Internal: Set the new active session. + # + # editSession - The new {EditSession} to use. setModel: (editSession) -> @edit(editSession) + # Public: Retrieves the {EditSession}'s buffer. + # + # Returns the current {Buffer}. getBuffer: -> @activeEditSession.buffer showBufferConflictAlert: (editSession) -> @@ -721,9 +780,11 @@ class Editor extends View @activeEditSession.setScrollTop(@scrollTop()) @activeEditSession.setScrollLeft(@scrollView.scrollLeft()) + # Public: Activates soft tabs in the editor. toggleSoftTabs: -> @activeEditSession.setSoftTabs(not @activeEditSession.softTabs) + # Public: Activates soft wraps in the editor. toggleSoftWrap: -> @setSoftWrap(not @activeEditSession.getSoftWrap()) @@ -733,6 +794,11 @@ class Editor extends View else Infinity + # Public: Sets the soft wrap column for the editor. + # + # softWrap - A {Boolean} which, if `true`, sets soft wraps + # softWrapColumn - A {Number} indicating the length of a line in the editor when soft + # wrapping turns on setSoftWrap: (softWrap, softWrapColumn=undefined) -> @activeEditSession.setSoftWrap(softWrap) @setSoftWrapColumn(softWrapColumn) if @attached @@ -745,6 +811,9 @@ class Editor extends View @removeClass 'soft-wrap' $(window).off 'resize', @_setSoftWrapColumn + # Public: Sets the font size for the editor. + # + # fontSize - A {Number} indicating the font size in pixels. setFontSize: (fontSize) -> headTag = $("head") styleTag = headTag.find("style.font-size") @@ -759,9 +828,15 @@ class Editor extends View else @redrawOnReattach = @attached + # Public: Retrieves the font size for the editor. + # + # Returns a {Number} indicating the font size in pixels. getFontSize: -> parseInt(@css("font-size")) + # Public: Sets the font family for the editor. + # + # fontFamily - A {String} identifying the CSS `font-family`, setFontFamily: (fontFamily) -> return if fontFamily == undefined headTag = $("head") @@ -773,11 +848,16 @@ class Editor extends View styleTag.text(".editor {font-family: #{fontFamily}}") @redraw() + # Public: Gets the font family for the editor. + # + # Returns a {String} identifying the CSS `font-family`, getFontFamily: -> @css("font-family") + # Public: Clears the CSS `font-family` property from the editor. clearFontFamily: -> $('head style.editor-font-family').remove() + # Public: Clears the CSS `font-family` property from the editor. redraw: -> return unless @hasParent() return unless @attached @@ -1282,6 +1362,7 @@ class Editor extends View new Point(row, column) + # Public: Highlights the current line the cursor is on. highlightCursorLine: -> return if @mini @@ -1292,14 +1373,21 @@ class Editor extends View else @highlightedLine = null + # Public: Retrieves the current {EditSession}'s grammar. + # + # Returns a {String} indicating the {LanguageMode}'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. setGrammar: (grammar) -> throw new Error("Only mini-editors can explicity set their grammar") unless @mini @activeEditSession.setGrammar(grammar) @handleGrammarChange() + # Public: Reloads the current grammar. reloadGrammar: -> grammarChanged = @activeEditSession.reloadGrammar() @handleGrammarChange() if grammarChanged diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index bd06299d2..42f25a72d 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -100,21 +100,35 @@ class Buffer @trigger "path-changed", this + # Public: Retrieves the current buffer's file extension. + # + # Returns a {String}. getExtension: -> if @getPath() @getPath().split('/').pop().split('.').pop() else null + # Public: Retrieves the cached buffer contents. + # + # Returns a {String}. getText: -> @cachedMemoryContents ?= @getTextInRange(@getRange()) + # Public: Replaces the current buffer contents. + # + # text - A {String} containing the new buffer contents. setText: (text) -> @change(@getRange(), text, normalizeLineEndings: false) getRange: -> new Range([0, 0], [@getLastRow(), @getLastLine().length]) + # Public: Given a range, returns the lines of text within it. + # + # range - A {Range} object specifying your points of interest + # + # Returns a {String} of the combined lines. getTextInRange: (range) -> range = @clipRange(range) if range.start.row == range.end.row @@ -130,9 +144,17 @@ class Buffer return multipleLines.join '' + # Public: Gets all the lines in a file. + # + # Returns an {Array} of {String}s. getLines: -> @lines + # Public: Given a row, returns the line of text. + # + # row - A {Number} indicating the row. + # + # Returns a {String}. lineForRow: (row) -> @lines[row] @@ -141,7 +163,12 @@ class Buffer suggestedLineEndingForRow: (row) -> @lineEndingForRow(row) ? @lineEndingForRow(row - 1) - + + # Public: Given a row, returns the length of the line of text. + # + # row - A {Number} indicating the row. + # + # Returns a {Number}. lineLengthForRow: (row) -> @lines[row].length @@ -154,9 +181,15 @@ class Buffer else new Range([row, 0], [row, @lineLengthForRow(row)]) + # Public: Gets the number of lines in a file. + # + # Returns a {Number}. getLineCount: -> @getLines().length + # Public: Gets the row number of the last line. + # + # Returns a {Number}. getLastRow: -> @getLines().length - 1 @@ -425,6 +458,7 @@ class Buffer return match[0][0] != '\t' undefined + # Public: Checks out the current HEAD revision of the file. checkoutHead: -> path = @getPath() return unless path From f2698bc6a9969b35c954408af7e60f9d0396bbfc Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Mon, 8 Apr 2013 02:14:45 -0500 Subject: [PATCH 10/51] More updates --- src/app/display-buffer.coffee | 6 ++ src/app/edit-session.coffee | 149 +++++++++++++++++++++++++++++++++- src/app/editor.coffee | 4 +- src/app/line-map.coffee | 2 +- src/app/text-buffer.coffee | 37 ++++++++- 5 files changed, 192 insertions(+), 6 deletions(-) diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index 0f24a235d..b85704972 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -222,9 +222,15 @@ class DisplayBuffer scopesForBufferPosition: (bufferPosition) -> @tokenizedBuffer.scopesForPosition(bufferPosition) + # Public: Retrieves the current tab length. + # + # Returns a {Number}. getTabLength: -> @tokenizedBuffer.getTabLength() + # Public: Specifies the tab length. + # + # tabLength - A {Number} that defines the new tab length. setTabLength: (tabLength) -> @tokenizedBuffer.setTabLength(tabLength) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 3ee9fa269..43c79a39b 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -58,15 +58,24 @@ class EditSession @subscribe syntax, 'grammars-loaded', => @reloadGrammar() + # Internal getViewClass: -> require 'editor' + # Public: Retrieves the filename of the open file. + # + # Returns a {String}. getTitle: -> if path = @getPath() fs.base(path) else 'untitled' + # Public: Retrieves the filename of the open file, followed by a dash, then the file's directory. + # + # If the file is brand new, the title is `untitled`. + # + # Returns a {String}. getLongTitle: -> if path = @getPath() fileName = fs.base(path) @@ -93,9 +102,21 @@ class EditSession scrollLeft: @getScrollLeft() cursorScreenPosition: @getCursorScreenPosition().serialize() + # Internal: Creates a copy of the current {EditSession}. + # + # Returns an identical `EditSession`. copy: -> EditSession.deserialize(@serialize(), @project) + # Public: Compares two `EditSession`s to determine equality. + # + # Equality is based on the condition that: + # + # * the two {Buffer}s are the same + # * the two `scrollTop` and `scrollLeft` property are the same + # * the two {Cursor} screen positions are the same + # + # Returns a {Boolean}. isEqual: (other) -> return false unless other instanceof EditSession @buffer == other.buffer and @@ -103,37 +124,88 @@ class EditSession @scrollLeft == other.getScrollLeft() and @getCursorScreenPosition().isEqual(other.getCursorScreenPosition()) + setVisible: (visible) -> @displayBuffer.setVisible(visible) + # Public: Defines the value of the `EditSession`'s `scrollTop` property. + # + # scrollTop - A {Number} defining the `scrollTop`, in pixels. setScrollTop: (@scrollTop) -> + # Public: Gets the value of the `EditSession`'s `scrollTop` property. + # + # Returns a {Number} defining the `scrollTop`, in pixels. getScrollTop: -> @scrollTop + # Public: Defines the value of the `EditSession`'s `scrollLeft` property. + # + # scrollLeft - A {Number} defining the `scrollLeft`, in pixels. setScrollLeft: (@scrollLeft) -> + # Public: Gets the value of the `EditSession`'s `scrollLeft` property. + # + # Returns a {Number} defining the `scrollLeft`, in pixels. getScrollLeft: -> @scrollLeft + # Public: Defines the limit at which the buffer begins to soft wrap text. + # + # softWrapColumn - A {Number} defining the soft wrap limit. setSoftWrapColumn: (@softWrapColumn) -> @displayBuffer.setSoftWrapColumn(@softWrapColumn) + # Public: Defines whether to use soft tabs. + # + # softTabs - A {Boolean} which, if `true`, indicates that you want soft tabs. setSoftTabs: (@softTabs) -> - + # Public: Retrieves whether soft tabs are enabled. + # + # Returns a {Boolean}. getSoftWrap: -> @softWrap + # Public: Defines whether to use soft wrapping of text. + # + # softTabs - A {Boolean} which, if `true`, indicates that you want soft wraps. setSoftWrap: (@softWrap) -> + # Public: Retrieves that character used to indicate a tab. + # + # If soft tabs are enabled, this is a space (`" "`) times the {.getTabLength} value. + # Otherwise, it's a tab (`\t`). + # + # Returns a {String}. getTabText: -> @buildIndentString(1) + # Public: Retrieves the current tab length. + # + # Returns a {Number}. getTabLength: -> @displayBuffer.getTabLength() + + # Public: Specifies the tab length. + # + # tabLength - A {Number} that defines the new tab length. setTabLength: (tabLength) -> @displayBuffer.setTabLength(tabLength) clipBufferPosition: (bufferPosition) -> @buffer.clipPosition(bufferPosition) + # Public: Given a buffer row, this retrieves the indentation level. + # + # bufferRow - A {Number} indicating the buffer row. + # + # Returns the indentation level as a {Number}. indentationForBufferRow: (bufferRow) -> @indentLevelForLine(@lineForBufferRow(bufferRow)) + # Public: This specifies the new indentation level for a buffer row. + # + # bufferRow - A {Number} indicating the buffer row. + # newLevel - A {Number} indicating the new indentation level. setIndentationForBufferRow: (bufferRow, newLevel) -> currentLevel = @indentationForBufferRow(bufferRow) currentIndentString = @buildIndentString(currentLevel) newIndentString = @buildIndentString(newLevel) @buffer.change([[bufferRow, 0], [bufferRow, currentIndentString.length]], newIndentString) + # Internal: Given a line, this gets the indentation level. + # + # line - A {String} in the current {Buffer}. + # + # Returns a {Number}. indentLevelForLine: (line) -> if match = line.match(/^[\t ]+/) leadingWhitespace = match[0] @@ -143,13 +215,18 @@ class EditSession else 0 + # Internal: Constructs the string used for tabs. buildIndentString: (number) -> if @softTabs _.multiplyString(" ", number * @getTabLength()) else _.multiplyString("\t", Math.floor(number)) + # Public: Saves the buffer. save: -> @buffer.save() + # Public: Saves the buffer at a specific path. + # + # path - The path to save at. saveAs: (path) -> @buffer.saveAs(path) # Public: Retrieves the current buffer's file extension. # @@ -159,22 +236,88 @@ class EditSession # # Returns a {String}. getPath: -> @buffer.getPath() + # Public: Retrieves the current buffer's file path. + # + # Returns a {String}. getUri: -> @getPath() + # Public: Given a buffer row, identifies if it is blank. + # + # bufferRow - A buffer row {Number} to check + # + # Returns a {Boolean}. isBufferRowBlank: (bufferRow) -> @buffer.isRowBlank(bufferRow) + # Public: Given a buffer row, this finds the next row that's blank. + # + # bufferRow - A buffer row {Number} to check + # + # Returns a {Number}, or `null` if there's no other blank row. nextNonBlankBufferRow: (bufferRow) -> @buffer.nextNonBlankRow(bufferRow) + # Public: Finds the last point in the current buffer. + # + # Returns a {Point} representing the last position. getEofBufferPosition: -> @buffer.getEofPosition() + # Public: Finds the last line in the current buffer. + # + # Returns a {Number}. getLastBufferRow: -> @buffer.getLastRow() + # Public: Given a buffer row, this retrieves the range for that line. + # + # row - A {Number} identifying the row + # options - A hash with one key, `includeNewline`, which specifies whether you + # want to include the trailing newline + # + # Returns a {Range}. bufferRangeForBufferRow: (row, options) -> @buffer.rangeForRow(row, options) + # Public: Given a buffer row, this retrieves that line. + # + # row - A {Number} identifying the row + # + # Returns a {String}. lineForBufferRow: (row) -> @buffer.lineForRow(row) + # Public: Given a buffer row, this retrieves that line's length. + # + # row - A {Number} identifying the row + # + # Returns a {Number}. lineLengthForBufferRow: (row) -> @buffer.lineLengthForRow(row) scanInRange: (args...) -> @buffer.scanInRange(args...) backwardsScanInRange: (args...) -> @buffer.backwardsScanInRange(args...) + # Public: Identifies if the buffer was modified. + # + # Returns a {Boolean}. isModified: -> @buffer.isModified() + # Public: Identifies if the buffer has editors. + # + # Returns a {Boolean}. hasEditors: -> @buffer.hasEditors() + # Public: Given a buffer position, this converts it into a screen position. + # + # bufferPosition - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # Returns a {Point}. screenPositionForBufferPosition: (bufferPosition, options) -> @displayBuffer.screenPositionForBufferPosition(bufferPosition, 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 + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # Returns a {Point}. bufferPositionForScreenPosition: (screenPosition, options) -> @displayBuffer.bufferPositionForScreenPosition(screenPosition, options) + # Public: Given a buffer range, this converts it into a screen position. + # + # range - The {Range} to convert + # + # Returns a {Range}. screenRangeForBufferRange: (range) -> @displayBuffer.screenRangeForBufferRange(range) + # Public: Given a screen range, this converts it into a buffer position. + # + # range - The {Range} to convert + # + # Returns a {Range}. bufferRangeForScreenRange: (range) -> @displayBuffer.bufferRangeForScreenRange(range) clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options) # Public: Gets the line for the given screen row. @@ -186,7 +329,7 @@ class EditSession # Public: Gets the lines for the given screen row boundaries. # # start - A {Number} indicating the beginning screen row. - # start - A {Number} indicating the ending screen row. + # end - A {Number} indicating the ending screen row. # # Returns an {Array} of {String}s. linesForScreenRows: (start, end) -> @displayBuffer.linesForRows(start, end) @@ -402,6 +545,7 @@ class EditSession # Public: Determines if the given buffer row is folded. # # screenRow - A {Number} indicating the buffer row. + # # Returns `true` if the buffer row is folded, `false` otherwise. isFoldedAtBufferRow: (bufferRow) -> screenRow = @screenPositionForBufferPosition([bufferRow]).row @@ -409,6 +553,7 @@ class EditSession # Public: Determines if the given screen row is folded. # # screenRow - A {Number} indicating the screen row. + # # Returns `true` if the screen row is folded, `false` otherwise. isFoldedAtScreenRow: (screenRow) -> @lineForScreenRow(screenRow)?.fold? diff --git a/src/app/editor.coffee b/src/app/editor.coffee index ec82da464..a7e360ea7 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -375,11 +375,13 @@ class Editor extends View # Public: Determines if the given screen row is folded. # # screenRow - A {Number} indicating the screen row. + # # Returns `true` if the screen row is folded, `false` otherwise. isFoldedAtScreenRow: (screenRow) -> @activeEditSession.isFoldedAtScreenRow(screenRow) # Public: Determines if the given buffer row is folded. # # screenRow - A {Number} indicating the buffer row. + # # Returns `true` if the buffer row is folded, `false` otherwise. isFoldedAtBufferRow: (bufferRow) -> @activeEditSession.isFoldedAtBufferRow(bufferRow) # Public: Determines if the given row that the cursor is at is folded. @@ -396,7 +398,7 @@ class Editor extends View # Public: Gets the lines for the given screen row boundaries. # # start - A {Number} indicating the beginning screen row. - # start - A {Number} indicating the ending screen row. + # end - A {Number} indicating the ending screen row. # # Returns an {Array} of {String}s. linesForScreenRows: (start, end) -> @activeEditSession.linesForScreenRows(start, end) diff --git a/src/app/line-map.coffee b/src/app/line-map.coffee index f58333835..74541e7db 100644 --- a/src/app/line-map.coffee +++ b/src/app/line-map.coffee @@ -111,7 +111,7 @@ class LineMap [screenRow, screenLines] bufferPositionForScreenPosition: (screenPosition, options) -> - { row, column } = @clipScreenPosition(Point.fromObject(screenPosition)) + { row, column } = @clipScreenPosition(Point.fromObject(screenPosition), options) [bufferRow, screenLine] = @bufferRowAndScreenLineForScreenRow(row) bufferColumn = screenLine.bufferColumnForScreenColumn(column) new Point(bufferRow, bufferColumn) diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index 42f25a72d..bd8f15a2d 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -56,6 +56,9 @@ class Buffer @destroy() if @refcount <= 0 this + # Public: Identifies if the buffer has editors. + # + # Returns a {Boolean}. hasEditors: -> @refcount > 1 subscribeToFile: -> @@ -163,7 +166,7 @@ class Buffer suggestedLineEndingForRow: (row) -> @lineEndingForRow(row) ? @lineEndingForRow(row - 1) - + # Public: Given a row, returns the length of the line of text. # # row - A {Number} indicating the row. @@ -174,7 +177,14 @@ class Buffer lineEndingLengthForRow: (row) -> (@lineEndingForRow(row) ? '').length - + + # Public: Given a buffer row, this retrieves the range for that line. + # + # row - A {Number} identifying the row + # options - A hash with one key, `includeNewline`, which specifies whether you + # want to include the trailing newline + # + # Returns a {Range}. rangeForRow: (row, { includeNewline } = {}) -> if includeNewline and row < @getLastRow() new Range([row, 0], [row + 1, 0]) @@ -193,9 +203,15 @@ class Buffer getLastRow: -> @getLines().length - 1 + # Public: Finds the last line in the current buffer. + # + # Returns a {String}. getLastLine: -> @lineForRow(@getLastRow()) + # Public: Finds the last point in the current buffer. + # + # Returns a {Point} representing the last position. getEofPosition: -> lastRow = @getLastRow() new Point(lastRow, @lineLengthForRow(lastRow)) @@ -280,9 +296,13 @@ class Buffer commit: -> @undoManager.commit() abort: -> @undoManager.abort() + # Public: Saves the buffer. save: -> @saveAs(@getPath()) if @isModified() + # Public: Saves the buffer at a specific path. + # + # path - The path to save at. saveAs: (path) -> unless path then throw new Error("Can't save buffer with no file path") @@ -293,6 +313,9 @@ class Buffer @triggerModifiedStatusChanged(false) @trigger 'saved' + # Public: Identifies if the buffer was modified. + # + # Returns a {Boolean}. isModified: -> if @file @getText() != @cachedDiskContents @@ -434,6 +457,11 @@ class Buffer backwardsScanInRange: (regex, range, iterator) -> @scanInRange regex, range, iterator, true + # Public: Given a row, identifies if it is blank. + # + # row - A row {Number} to check + # + # Returns a {Boolean}. isRowBlank: (row) -> not /\S/.test @lineForRow(row) @@ -445,6 +473,11 @@ class Buffer return row unless @isRowBlank(row) null + # Public: Given a row, this finds the next row that's blank. + # + # startRow - A row {Number} to check + # + # Returns a {Number}, or `null` if there's no other blank row. nextNonBlankRow: (startRow) -> lastRow = @getLastRow() if startRow < lastRow From d042fadab1d1b35ecd9e89dad409b8884550770b Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 01:18:12 -0500 Subject: [PATCH 11/51] More updates --- src/app/display-buffer.coffee | 64 ++++++++++++++++++++++++-- src/app/edit-session.coffee | 87 +++++++++++++++++++++++++++++++---- src/app/language-mode.coffee | 26 +++++++++++ src/app/line-map.coffee | 29 ++++++++++-- 4 files changed, 191 insertions(+), 15 deletions(-) diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index b85704972..ede8dff76 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -90,6 +90,9 @@ class DisplayBuffer endRow = currentRow return [startRow, endRow] if startRow isnt endRow + # Public: Given a buffer row, this folds it. + # + # bufferRow - A {Number} indicating the buffer row foldBufferRow: (bufferRow) -> for currentRow in [bufferRow..0] rowRange = @rowRangeForCommentAtBufferRow(currentRow) @@ -103,9 +106,16 @@ class DisplayBuffer return + # Public: Given a buffer row, this unfolds it. + # + # bufferRow - A {Number} indicating the buffer row unfoldBufferRow: (bufferRow) -> @largestFoldContainingBufferRow(bufferRow)?.destroy() + # Public: Creates a new fold between two row numbers. + # + # startRow - The row {Number} to start folding at + # endRow - The row {Number} to end the fold createFold: (startRow, endRow) -> return fold if fold = @foldFor(startRow, endRow) fold = new Fold(this, startRow, endRow) @@ -154,6 +164,9 @@ class DisplayBuffer @triggerChanged({ start, end, screenDelta, bufferDelta }) + # Public: Removes any folds found that contain the given buffer row. + # + # bufferRow - The buffer row {Number} to check against destroyFoldsContainingBufferRow: (bufferRow) -> for row, folds of @activeFolds for fold in new Array(folds...) @@ -170,13 +183,37 @@ class DisplayBuffer 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 + # are the greatest. + # + # bufferRow - A {Number} indicating the buffer row + # + # Returns a {Fold}. largestFoldStartingAtBufferRow: (bufferRow) -> return unless folds = @activeFolds[bufferRow] (folds.sort (a, b) -> b.endRow - a.endRow)[0] + # Public: Given a screen row, this returns the largest fold that starts there. + # + # Largest is defined as the fold whose difference between its start and end points + # are the greatest. + # + # screenRow - A {Number} indicating the screen row + # + # Returns a {Fold}. largestFoldStartingAtScreenRow: (screenRow) -> @largestFoldStartingAtBufferRow(@bufferRowForScreenRow(screenRow)) + # Public: Given a buffer row, this returns the largest fold that includes it. + # + # Largest is defined as the fold whose difference between its start and end points + # are the greatest. + # + # bufferRow - A {Number} indicating the buffer row + # + # Returns a {Fold}. largestFoldContainingBufferRow: (bufferRow) -> largestFold = null for currentBufferRow in [bufferRow..0] @@ -197,10 +234,18 @@ class DisplayBuffer bufferRowForScreenRow: (screenRow) -> @lineMap.bufferPositionForScreenPosition([screenRow, 0]).row - + # Public: Given a buffer range, this converts it into a screen position. + # + # bufferRange - The {Range} to convert + # + # 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 + # + # Returns a {Range}. bufferRangeForScreenRange: (screenRange) -> @lineMap.bufferRangeForScreenRange(screenRange) @@ -213,9 +258,22 @@ class DisplayBuffer maxLineLength: -> @lineMap.maxScreenLineLength + # Public: Given a buffer position, this converts it into a screen position. + # + # bufferPosition - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # 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 + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # Returns a {Point}. bufferPositionForScreenPosition: (position, options) -> @lineMap.bufferPositionForScreenPosition(position, options) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 43c79a39b..0feb06762 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -58,7 +58,7 @@ class EditSession @subscribe syntax, 'grammars-loaded', => @reloadGrammar() - # Internal + # Internal: getViewClass: -> require 'editor' @@ -309,16 +309,16 @@ class EditSession bufferPositionForScreenPosition: (screenPosition, options) -> @displayBuffer.bufferPositionForScreenPosition(screenPosition, options) # Public: Given a buffer range, this converts it into a screen position. # - # range - The {Range} to convert + # bufferRange - The {Range} to convert # # Returns a {Range}. - screenRangeForBufferRange: (range) -> @displayBuffer.screenRangeForBufferRange(range) + screenRangeForBufferRange: (bufferRange) -> @displayBuffer.screenRangeForBufferRange(bufferRange) # Public: Given a screen range, this converts it into a buffer position. # - # range - The {Range} to convert + # screenRange - The {Range} to convert # # Returns a {Range}. - bufferRangeForScreenRange: (range) -> @displayBuffer.bufferRangeForScreenRange(range) + bufferRangeForScreenRange: (screenRange) -> @displayBuffer.bufferRangeForScreenRange(screenRange) clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options) # Public: Gets the line for the given screen row. # @@ -349,10 +349,14 @@ class EditSession scopesForBufferPosition: (bufferPosition) -> @displayBuffer.scopesForBufferPosition(bufferPosition) getCursorScopes: -> @getCursor().getScopes() logScreenLines: (start, end) -> @displayBuffer.logLines(start, end) - + # Public: Determines whether the {Editor} will auto indent rows. + # + # Returns a {Boolean}. shouldAutoIndent: -> config.get("editor.autoIndent") - + # Public: Determines whether the {Editor} will auto indent pasted text. + # + # Returns a {Boolean}. shouldAutoIndentPastedText: -> config.get("editor.autoIndentOnPaste") # Public: Inserts text at the current cursor positions. @@ -474,6 +478,7 @@ class EditSession redo: -> @buffer.redo(this) + # Internal: transact: (fn) -> isNewTransaction = @buffer.transact() oldSelectedRanges = @getSelectedBufferRanges() @@ -485,6 +490,7 @@ class EditSession @commit() if isNewTransaction result + # Internal: commit: -> newSelectedRanges = @getSelectedBufferRanges() @pushOperation @@ -492,6 +498,7 @@ class EditSession editSession?.setSelectedBufferRanges(newSelectedRanges) @buffer.commit() + # Internal: abort: -> @buffer.abort() @@ -508,6 +515,9 @@ class EditSession bufferRow = @bufferPositionForScreenPosition(@getCursorScreenPosition()).row @foldBufferRow(bufferRow) + # Public: Given a buffer row, this folds it. + # + # bufferRow - A {Number} indicating the buffer row foldBufferRow: (bufferRow) -> @displayBuffer.foldBufferRow(bufferRow) @@ -516,22 +526,39 @@ class EditSession bufferRow = @bufferPositionForScreenPosition(@getCursorScreenPosition()).row @unfoldBufferRow(bufferRow) + # Public: Given a buffer row, this unfolds it. + # + # bufferRow - A {Number} indicating the buffer row unfoldBufferRow: (bufferRow) -> @displayBuffer.unfoldBufferRow(bufferRow) + # Public: Folds all selections. foldSelection: -> selection.fold() for selection in @getSelections() + # Public: Creates a new fold between two row numbers. + # + # startRow - The row {Number} to start folding at + # endRow - The row {Number} to end the fold createFold: (startRow, endRow) -> @displayBuffer.createFold(startRow, endRow) + # Public: Removes any folds 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. + # + # 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. + # + # foldId - The fold id {Number} to remove destroyFold: (foldId) -> fold = @displayBuffer.foldsById[foldId] fold.destroy() @@ -542,14 +569,16 @@ class EditSession # Returns `true` if the row is folded, `false` otherwise. isFoldedAtCursorRow: -> @isFoldedAtScreenRow(@getCursorScreenRow()) + # Public: Determines if the given buffer row is folded. # - # screenRow - A {Number} indicating the buffer row. + # bufferRow - A {Number} indicating the buffer row. # # Returns `true` if the buffer row is folded, `false` otherwise. isFoldedAtBufferRow: (bufferRow) -> screenRow = @screenPositionForBufferPosition([bufferRow]).row @isFoldedAtScreenRow(screenRow) + # Public: Determines if the given screen row is folded. # # screenRow - A {Number} indicating the screen row. @@ -558,27 +587,69 @@ class EditSession isFoldedAtScreenRow: (screenRow) -> @lineForScreenRow(screenRow)?.fold? + # Public: Given a buffer row, this returns the largest fold that includes it. + # + # Largest is defined as the fold whose difference between its start and end points + # are the greatest. + # + # bufferRow - A {Number} indicating the buffer row + # + # Returns a {Fold}. largestFoldContainingBufferRow: (bufferRow) -> @displayBuffer.largestFoldContainingBufferRow(bufferRow) + # Public: Given a screen row, this returns the largest fold that starts there. + # + # Largest is defined as the fold whose difference between its start and end points + # are the greatest. + # + # screenRow - A {Number} indicating the screen row + # + # Returns a {Fold}. largestFoldStartingAtScreenRow: (screenRow) -> @displayBuffer.largestFoldStartingAtScreenRow(screenRow) + # Public: Given a buffer row, this returns a suggested indentation level. + # + # The indentation level provided is based on the current {LangugaeMode}. + # + # bufferRow - A {Number} indicating the buffer row + # + # Returns a {Number}. suggestedIndentForBufferRow: (bufferRow) -> @languageMode.suggestedIndentForBufferRow(bufferRow) + # Public: Indents all the rows between two buffer rows. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at autoIndentBufferRows: (startRow, endRow) -> @languageMode.autoIndentBufferRows(startRow, endRow) + # Public: Given a buffer row, this indents it. + # + # bufferRow - The row {Number} autoIndentBufferRow: (bufferRow) -> @languageMode.autoIndentBufferRow(bufferRow) + # Public: Given a buffer row, this increases the indentation. + # + # bufferRow - The row {Number} autoIncreaseIndentForBufferRow: (bufferRow) -> @languageMode.autoIncreaseIndentForBufferRow(bufferRow) + # Public: Given a buffer row, this decreases the indentation. + # + # bufferRow - The row {Number} autoDecreaseIndentForRow: (bufferRow) -> @languageMode.autoDecreaseIndentForBufferRow(bufferRow) + # Public: Wraps the lines between two rows in comments. + # + # If the language doesn't have comments, nothing happens. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at toggleLineCommentsForBufferRows: (start, end) -> @languageMode.toggleLineCommentsForBufferRows(start, end) diff --git a/src/app/language-mode.coffee b/src/app/language-mode.coffee index dc13fae18..0197047be 100644 --- a/src/app/language-mode.coffee +++ b/src/app/language-mode.coffee @@ -21,6 +21,12 @@ class LanguageMode throw new Error("No grammar found for path: #{path}") unless @grammar previousGrammar isnt @grammar + # Public: Wraps the lines between two rows in comments. + # + # If the language doesn't have comment, nothing happens. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at toggleLineCommentsForBufferRows: (start, end) -> scopes = @editSession.scopesForBufferPosition([start, 0]) return unless commentStartString = syntax.getProperty(scopes, "editor.commentStart") @@ -83,6 +89,13 @@ class LanguageMode [bufferRow, foldEndRow] + # Public: Given a buffer row, this returns a suggested indentation level. + # + # The indentation level provided is based on the current {LangugaeMode}. + # + # bufferRow - A {Number} indicating the buffer row + # + # Returns a {Number}. suggestedIndentForBufferRow: (bufferRow) -> currentIndentLevel = @editSession.indentationForBufferRow(bufferRow) scopes = @editSession.scopesForBufferPosition([bufferRow, 0]) @@ -102,13 +115,23 @@ class LanguageMode Math.max(desiredIndentLevel, currentIndentLevel) + # Public: Indents all the rows between two buffer row numbers. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at autoIndentBufferRows: (startRow, endRow) -> @autoIndentBufferRow(row) for row in [startRow..endRow] + # Public: Given a buffer row, this indents it. + # + # bufferRow - The row {Number} autoIndentBufferRow: (bufferRow) -> @autoIncreaseIndentForBufferRow(bufferRow) @autoDecreaseIndentForBufferRow(bufferRow) + # Public: Given a buffer row, this increases the indentation. + # + # bufferRow - The row {Number} autoIncreaseIndentForBufferRow: (bufferRow) -> precedingRow = @buffer.previousNonBlankRow(bufferRow) return unless precedingRow? @@ -124,6 +147,9 @@ class LanguageMode if desiredIndentLevel > currentIndentLevel @editSession.setIndentationForBufferRow(bufferRow, desiredIndentLevel) + # Public: Given a buffer row, this decreases the indentation. + # + # bufferRow - The row {Number} autoDecreaseIndentForBufferRow: (bufferRow) -> scopes = @editSession.scopesForBufferPosition([bufferRow, 0]) increaseIndentRegex = @increaseIndentRegexForScopes(scopes) diff --git a/src/app/line-map.coffee b/src/app/line-map.coffee index 74541e7db..992304d21 100644 --- a/src/app/line-map.coffee +++ b/src/app/line-map.coffee @@ -76,7 +76,14 @@ class LineMap else column = screenLine.clipScreenColumn(column, options) new Point(row, column) - + + # Public: Given a buffer position, this converts it into a screen position. + # + # bufferPosition - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # Returns a {Point}. screenPositionForBufferPosition: (bufferPosition, options={}) -> { row, column } = Point.fromObject(bufferPosition) [screenRow, screenLines] = @screenRowAndScreenLinesForBufferRow(row) @@ -109,7 +116,13 @@ class LineMap currentBufferRow = nextBufferRow [screenRow, screenLines] - + # Public: Given a buffer range, this converts it into a screen position. + # + # screenPosition - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # Returns a {Point}. bufferPositionForScreenPosition: (screenPosition, options) -> { row, column } = @clipScreenPosition(Point.fromObject(screenPosition), options) [bufferRow, screenLine] = @bufferRowAndScreenLineForScreenRow(row) @@ -125,13 +138,21 @@ class LineMap bufferRow += screenLine.bufferRows [bufferRow, screenLine] - + # Public: Given a buffer range, this converts it into a screen position. + # + # bufferRange - The {Range} to convert + # + # Returns a {Range}. screenRangeForBufferRange: (bufferRange) -> bufferRange = Range.fromObject(bufferRange) start = @screenPositionForBufferPosition(bufferRange.start) end = @screenPositionForBufferPosition(bufferRange.end) new Range(start, end) - + # Public: Given a screen range, this converts it into a buffer position. + # + # screenRange - The {Range} to convert + # + # Returns a {Range}. bufferRangeForScreenRange: (screenRange) -> screenRange = Range.fromObject(screenRange) start = @bufferPositionForScreenPosition(screenRange.start) From 19c347903aba74a07b54346642eb297ca32e3cd6 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 14:49:41 -0500 Subject: [PATCH 12/51] Add stats tasks --- Rakefile | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Rakefile b/Rakefile index f120bf455..709d5f63a 100644 --- a/Rakefile +++ b/Rakefile @@ -114,14 +114,16 @@ task :tags do system %{find src native cef vendor -not -name "*spec.coffee" -type f -print0 | xargs -0 ctags} end -desc "Builds the API docs" -task :docs do - system %{./biscotto -j ~/Development/biscotto/out.json src/app/} -end +namespace :docs do + desc "Builds the API docs" + task :build do + system %{./biscotto -j ~/Development/biscotto/out.json src/app/} + end -desc "Lists the stats for API doc coverage" -task :docsStats do - system %{./biscotto --statsOnly src/app/} + desc "Lists the stats for API doc coverage" + task :stats do + system %{./biscotto --statsOnly src/app/} + end end def application_path From 5dc1ddd5b51e4ce42ec3ebe0aec9707944416464 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 14:49:51 -0500 Subject: [PATCH 13/51] Remove invalid biscotto for now --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 54c1598bc..32e01f6d5 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { - "biscotto": "0.0.2" + }, "private": true, From 49e42c05107c49cb4b7edd82252b0f6e167e9063 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 14:49:58 -0500 Subject: [PATCH 14/51] Updates --- src/app/edit-session.coffee | 79 ++++++++++++++++++++++++++----------- src/app/text-buffer.coffee | 6 +-- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index e75e27fa8..2bea93c01 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -723,6 +723,7 @@ class EditSession @setSelectedBufferRange(selection.translate([1]), preserveFolds: true) + # Public: Duplicates the current line. duplicateLine: -> return unless @getSelection().isEmpty() @@ -746,9 +747,11 @@ class EditSession @setCursorScreenPosition(@getCursorScreenPosition().translate([1])) @foldCurrentRow() if cursorRowFolded + # Internal: mutateSelectedText: (fn) -> @transact => fn(selection) for selection in @getSelections() + # Internal: replaceSelectedText: (options={}, fn) -> {selectWordIfEmpty} = options @mutateSelectedText (selection) => @@ -760,81 +763,109 @@ class EditSession selection.insertText(fn(text)) selection.setBufferRange(range) + # Internal: pushOperation: (operation) -> @buffer.pushOperation(operation, this) - + + # Internal: markScreenRange: (args...) -> @displayBuffer.markScreenRange(args...) - + + # Internal: markBufferRange: (args...) -> @displayBuffer.markBufferRange(args...) - + + # Internal: markScreenPosition: (args...) -> @displayBuffer.markScreenPosition(args...) - + + # Internal: markBufferPosition: (args...) -> @displayBuffer.markBufferPosition(args...) - + + # Internal: destroyMarker: (args...) -> @displayBuffer.destroyMarker(args...) + # Public: Gets the number of markers in the buffer. + # + # Returns a {Number}. getMarkerCount: -> @buffer.getMarkerCount() - + + # Internal: getMarkerScreenRange: (args...) -> @displayBuffer.getMarkerScreenRange(args...) - + + # Internal: setMarkerScreenRange: (args...) -> @displayBuffer.setMarkerScreenRange(args...) - + + # Internal: getMarkerBufferRange: (args...) -> @displayBuffer.getMarkerBufferRange(args...) - + + # Internal: setMarkerBufferRange: (args...) -> @displayBuffer.setMarkerBufferRange(args...) - + + # Internal: getMarkerScreenPosition: (args...) -> @displayBuffer.getMarkerScreenPosition(args...) - + + # Internal: getMarkerBufferPosition: (args...) -> @displayBuffer.getMarkerBufferPosition(args...) - + + # Internal: getMarkerHeadScreenPosition: (args...) -> @displayBuffer.getMarkerHeadScreenPosition(args...) - + + # Internal: setMarkerHeadScreenPosition: (args...) -> @displayBuffer.setMarkerHeadScreenPosition(args...) - + + # Internal: getMarkerHeadBufferPosition: (args...) -> @displayBuffer.getMarkerHeadBufferPosition(args...) - + + # Internal: setMarkerHeadBufferPosition: (args...) -> @displayBuffer.setMarkerHeadBufferPosition(args...) - + + # Internal: getMarkerTailScreenPosition: (args...) -> @displayBuffer.getMarkerTailScreenPosition(args...) - + + # Internal: setMarkerTailScreenPosition: (args...) -> @displayBuffer.setMarkerTailScreenPosition(args...) - + + # Internal: getMarkerTailBufferPosition: (args...) -> @displayBuffer.getMarkerTailBufferPosition(args...) - + + # Internal: setMarkerTailBufferPosition: (args...) -> @displayBuffer.setMarkerTailBufferPosition(args...) - + + # Internal: observeMarker: (args...) -> @displayBuffer.observeMarker(args...) - + + # Internal: placeMarkerTail: (args...) -> @displayBuffer.placeMarkerTail(args...) - + + # Internal: clearMarkerTail: (args...) -> @displayBuffer.clearMarkerTail(args...) - + + # Internal: isMarkerReversed: (args...) -> @displayBuffer.isMarkerReversed(args...) - + + # Internal: isMarkerRangeEmpty: (args...) -> @displayBuffer.isMarkerRangeEmpty(args...) diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index bfd0dad5d..25c8aab56 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -42,9 +42,9 @@ class Buffer @setText(initialText) @updateCachedDiskContents() else if fsUtils.exists(path) - @reload() - else - @setText('') + @reload() + else + @setText('') else @setText(initialText ? '') From dbd924cfb0b1c26b093e3e3be8eaf183cad333f3 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 16:20:49 -0500 Subject: [PATCH 15/51] Stash --- src/app/edit-session.coffee | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index eeb7906f0..1d3694c6f 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -904,12 +904,22 @@ class EditSession marker = @markBufferPosition(bufferPosition, invalidationStrategy: 'never') @addSelection(marker).cursor + # Public: Adds a cursor to the `EditSession`. + # + # marker - The marker where the cursor should be added + # + # Returns the new {Cursor}. addCursor: (marker) -> cursor = new Cursor(editSession: this, marker: marker) @cursors.push(cursor) @trigger 'cursor-added', cursor cursor + # Public: Removes a cursor from the `EditSession`. + # + # cursor - The cursor to remove + # + # Returns the array of {Cursor}s, minus the one just removed. removeCursor: (cursor) -> _.remove(@cursors, cursor) From abbda0643af3ec5c6e2e6d591f6c9c96bd826df3 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 18:02:24 -0500 Subject: [PATCH 16/51] Specify more namespaces --- Rakefile | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/Rakefile b/Rakefile index 709d5f63a..a9bec3456 100644 --- a/Rakefile +++ b/Rakefile @@ -115,14 +115,26 @@ task :tags do end namespace :docs do - desc "Builds the API docs" - task :build do - system %{./biscotto -j ~/Development/biscotto/out.json src/app/} - end + namespace :build do + desc "Builds the API docs in src/app" + task :app do + system %{./biscotto src/app/} + end - desc "Lists the stats for API doc coverage" - task :stats do - system %{./biscotto --statsOnly src/app/} + desc "Lists the stats for API doc coverage in src/app" + task :stats do + system %{./biscotto --statsOnly src/app/} + end + + desc "Builds the API docs in src/package" + task :package do + system %{./biscotto src/package/} + end + + desc "Lists the stats for API doc coverage in src/package" + task :stats do + system %{./biscotto --statsOnly src/package/} + end end end From 756bb5604f4a6ec46653f4dc45efd98533b01294 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 18:03:29 -0500 Subject: [PATCH 17/51] Add API doc spec --- spec/app/atom-spec.coffee | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/app/atom-spec.coffee b/spec/app/atom-spec.coffee index 82a3d7672..56e5ef2d1 100644 --- a/spec/app/atom-spec.coffee +++ b/spec/app/atom-spec.coffee @@ -321,3 +321,14 @@ describe "the `atom` global", -> expect(atom.sendMessageToBrowserProcess.callCount).toBe 1 expect(atom.sendMessageToBrowserProcess.argsForCall[0][1][0]).toBe "A2" atom.sendMessageToBrowserProcess.simulateConfirmation('Next') + + + fdescribe "API documentation", -> + it "meets a minimum threshold", -> + versionHandler = jasmine.createSpy("versionHandler") + atom.getVersion(versionHandler) + waitsFor -> + versionHandler.callCount > 0 + + runs -> + expect(versionHandler.argsForCall[0][0]).toBeDefined() \ No newline at end of file From fad987c0f31b7660193892cc11cf15ca1def6a85 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Tue, 9 Apr 2013 18:03:39 -0500 Subject: [PATCH 18/51] More updates--25% --- src/app/edit-session.coffee | 82 ++++++++++++++++++++++++++++++++++-- src/app/editor.coffee | 69 +++++++++++++++++++++++++++++- src/app/language-mode.coffee | 2 +- 3 files changed, 148 insertions(+), 5 deletions(-) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 1d3694c6f..192077668 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -297,6 +297,7 @@ class EditSession # # Returns a {Point}. screenPositionForBufferPosition: (bufferPosition, options) -> @displayBuffer.screenPositionForBufferPosition(bufferPosition, 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 @@ -305,18 +306,21 @@ class EditSession # # Returns a {Point}. bufferPositionForScreenPosition: (screenPosition, options) -> @displayBuffer.bufferPositionForScreenPosition(screenPosition, options) + # Public: Given a buffer range, this converts it into a screen position. # # bufferRange - The {Range} to convert # # Returns a {Range}. screenRangeForBufferRange: (bufferRange) -> @displayBuffer.screenRangeForBufferRange(bufferRange) + # Public: Given a screen range, this converts it into a buffer position. # # screenRange - The {Range} to convert # # Returns a {Range}. bufferRangeForScreenRange: (screenRange) -> @displayBuffer.bufferRangeForScreenRange(screenRange) + clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options) # Public: Gets the line for the given screen row. # @@ -347,16 +351,19 @@ class EditSession scopesForBufferPosition: (bufferPosition) -> @displayBuffer.scopesForBufferPosition(bufferPosition) getCursorScopes: -> @getCursor().getScopes() logScreenLines: (start, end) -> @displayBuffer.logLines(start, end) + # Public: Determines whether the {Editor} will auto indent rows. # # Returns a {Boolean}. shouldAutoIndent: -> config.get("editor.autoIndent") + # Public: Determines whether the {Editor} will auto indent pasted text. # # Returns a {Boolean}. shouldAutoIndentPastedText: -> config.get("editor.autoIndentOnPaste") + # Public: Inserts text at the current cursor positions. # # text - A {String} representing the text to insert. @@ -429,6 +436,9 @@ class EditSession autoIndentSelectedRows: -> @mutateSelectedText (selection) -> selection.autoIndentSelectedRows() + # Given a buffer range, this converts all `\t` characters to the appopriate {.getTabText} value. + # + # bufferRange - The {Range} to perform the replace in normalizeTabsInBufferRange: (bufferRange) -> return unless @softTabs @scanInBufferRange /\t/, bufferRange, ({replace}) => replace(@getTabText()) @@ -609,7 +619,7 @@ class EditSession # Public: Given a buffer row, this returns a suggested indentation level. # - # The indentation level provided is based on the current {LangugaeMode}. + # The indentation level provided is based on the current {LanguageMode}. # # bufferRow - A {Number} indicating the buffer row # @@ -919,10 +929,16 @@ class EditSession # # cursor - The cursor to remove # - # Returns the array of {Cursor}s, minus the one just removed. + # Returns the removed {Cursor}. removeCursor: (cursor) -> _.remove(@cursors, cursor) + # Public: Creates a new selection at the given marker. + # + # marker - The marker to highlight + # options - A hash of options that pertain to the {Selection} constructor. + # + # Returns the new {Selection}. addSelection: (marker, options={}) -> unless options.preserveFolds @destroyFoldsIntersectingBufferRange(@getMarkerBufferRange(marker)) @@ -939,6 +955,12 @@ class EditSession @trigger 'selection-added', selection selection + # Public: Given a buffer range, adds a new selection for it. + # + # bufferRange - A {Range} in the buffer + # options - A hash of options + # + # Returns the new {Selection}. addSelectionForBufferRange: (bufferRange, options={}) -> options = _.defaults({invalidationStrategy: 'never'}, options) marker = @markBufferRange(bufferRange, options) @@ -972,6 +994,7 @@ class EditSession @consolidateSelections() @getSelection().clear() + # Internal: consolidateSelections: -> selections = @getSelections() if selections.length > 1 @@ -980,27 +1003,50 @@ class EditSession else false + # Public: Gets all the selections. + # + # Returns an {Array} of {Selection}s. getSelections: -> new Array(@selections...) - + + # Public: Gets the selection at the specified index. + # + # index - The id {Number} of the selection + # + # Returns a {Selection}. getSelection: (index) -> index ?= @selections.length - 1 @selections[index] + # Public: Gets the last selection, _i.e._ the most recently added. + # + # Returns a {Selection}. getLastSelection: -> _.last(@selections) + # Public: Gets all selections, ordered by position in the buffer. + # + # Returns an {Array} of {Selection}s. getSelectionsOrderedByBufferPosition: -> @getSelections().sort (a, b) -> aRange = a.getBufferRange() bRange = b.getBufferRange() aRange.end.compare(bRange.end) + # Public: Gets the very last selection, as it's ordered in the buffer. + # + # Returns a {Selection}. getLastSelectionInBuffer: -> _.last(@getSelectionsOrderedByBufferPosition()) + # Public: Determines if a given buffer range is included in a selection. + # + # bufferRange - The {Range} you're checking against + # + # Returns a {Boolean}. selectionIntersectsBufferRange: (bufferRange) -> _.any @getSelections(), (selection) -> selection.intersectsBufferRange(bufferRange) + # Public: Moves every cursor to a given screen position. # # position - An {Array} of two numbers: the screen row, and the screen column. @@ -1008,16 +1054,19 @@ class EditSession # setCursorScreenPosition: (position, options) -> @moveCursors (cursor) -> cursor.setScreenPosition(position, options) + # Public: Gets the current screen position. # # Returns an {Array} of two numbers: the screen row, and the screen column. getCursorScreenPosition: -> @getCursor().getScreenPosition() + # Public: Gets the current cursor's screen row. # # Returns the screen row. getCursorScreenRow: -> @getCursor().getScreenRow() + # Public: Moves every cursor to a given buffer position. # # position - An {Array} of two numbers: the buffer row, and the buffer column. @@ -1025,30 +1074,47 @@ class EditSession # setCursorBufferPosition: (position, options) -> @moveCursors (cursor) -> cursor.setBufferPosition(position, options) + # Public: Gets the current buffer position. # # Returns an {Array} of two numbers: the buffer row, and the buffer column. getCursorBufferPosition: -> @getCursor().getBufferPosition() + # Public: Gets the screen range of the last (most recently added) {Selection}. + # + # Returns a {Range}. getSelectedScreenRange: -> @getLastSelection().getScreenRange() + # Public: Gets the buffer range of the last (most recently added) {Selection}. + # + # Returns a {Range}. getSelectedBufferRange: -> @getLastSelection().getBufferRange() + # Public: Gets the buffer range of the last {Selection} in the buffer. + # + # Returns a {Range}. getSelectedBufferRanges: -> selection.getBufferRange() for selection in @getSelectionsOrderedByBufferPosition() + # Public: Gets the currently selected text. # # Returns a {String}. getSelectedText: -> @getLastSelection().getText() + # Public: Given a buffer range, this retrieves the text in that range. + # + # range - The {Range} you're interested in + # + # Returns a {String} of the combined lines. getTextInBufferRange: (range) -> @buffer.getTextInRange(range) getCurrentParagraphBufferRange: -> + @getCursor().getCurrentParagraphBufferRange() # Public: Gets the word located under the cursor. # @@ -1094,15 +1160,19 @@ class EditSession moveCursorToEndOfLine: -> @moveCursors (cursor) -> cursor.moveToEndOfLine() + # Public: Moves every cursor to the beginning of the current word. moveCursorToBeginningOfWord: -> @moveCursors (cursor) -> cursor.moveToBeginningOfWord() + # Public: Moves every cursor to the end of the current word. moveCursorToEndOfWord: -> @moveCursors (cursor) -> cursor.moveToEndOfWord() + # Public: Moves every cursor to the beginning of the next word. moveCursorToBeginningOfNextWord: -> @moveCursors (cursor) -> cursor.moveToBeginningOfNextWord() + # Internal: moveCursors: (fn) -> fn(cursor) for cursor in @getCursors() @mergeCursors() @@ -1114,9 +1184,11 @@ class EditSession lastSelection = @getLastSelection() lastSelection.selectToScreenPosition(position) @mergeIntersectingSelections(reverse: lastSelection.isReversed()) + # Public: Selects the text one position right of the cursor. selectRight: -> @expandSelectionsForward (selection) => selection.selectRight() + # Public: Selects the text one position left of the cursor. selectLeft: -> @expandSelectionsBackward (selection) => selection.selectLeft() @@ -1248,6 +1320,7 @@ class EditSession @mergeIntersectingSelections(options) return + # Internal: inspect: -> JSON.stringify @serialize() @@ -1270,13 +1343,16 @@ class EditSession setGrammar: (grammar) -> @languageMode.setGrammar(grammar) + # Public: Reloads the current grammar. reloadGrammar: -> @languageMode.reloadGrammar() + # Internal: handleGrammarChange: -> @unfoldAll() @trigger 'grammar-changed' + # Internal: getDebugSnapshot: -> [ @displayBuffer.getDebugSnapshot() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 663144eea..52710248b 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -425,9 +425,37 @@ class Editor extends View # Returns a {String}. getLastScreenRow: -> @activeEditSession.getLastScreenRow() clipScreenPosition: (screenPosition, options={}) -> @activeEditSession.clipScreenPosition(screenPosition, options) + + # Public: Given a buffer position, this converts it into a screen position. + # + # bufferPosition - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # Returns a {Point}. screenPositionForBufferPosition: (position, options) -> @activeEditSession.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 + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - The same options available to {LineMap.clipScreenPosition}. + # + # Returns a {Point}. bufferPositionForScreenPosition: (position, options) -> @activeEditSession.bufferPositionForScreenPosition(position, options) + + # Public: Given a buffer range, this converts it into a screen position. + # + # bufferRange - The {Range} to convert + # + # Returns a {Range}. screenRangeForBufferRange: (range) -> @activeEditSession.screenRangeForBufferRange(range) + + # Public: Given a screen range, this converts it into a buffer position. + # + # screenRange - The {Range} to convert + # + # Returns a {Range}. bufferRangeForScreenRange: (range) -> @activeEditSession.bufferRangeForScreenRange(range) bufferRowsForScreenRows: (startRow, endRow) -> @activeEditSession.bufferRowsForScreenRows(startRow, endRow) getLastScreenRow: -> @activeEditSession.getLastScreenRow() @@ -520,7 +548,7 @@ class Editor extends View lineForBufferRow: (row) -> @getBuffer().lineForRow(row) # Public: Given a row, returns the length of the line of text. # - # row - A {Number} indicating the row. + # row - A {Number} indicating the row # # Returns a {Number}. lineLengthForBufferRow: (row) -> @getBuffer().lineLengthForRow(row) @@ -612,6 +640,7 @@ class Editor extends View else @gutter.addClass('drop-shadow') + # Internal: selectOnMousemoveUntilMouseup: -> lastMoveEvent = null moveHandler = (event = lastMoveEvent) => @@ -630,6 +659,7 @@ class Editor extends View @activeEditSession.finalizeSelections() @syncCursorAnimations() + # Internal: afterAttach: (onDom) -> return unless onDom @redraw() if @redrawOnReattach @@ -652,6 +682,7 @@ class Editor extends View @trigger 'editor:attached', [this] + # Internal: edit: (editSession) -> return if editSession is @activeEditSession @@ -698,6 +729,7 @@ class Editor extends View # Returns the current {Buffer}. getBuffer: -> @activeEditSession.buffer + # Internal: showBufferConflictAlert: (editSession) -> atom.confirm( editSession.getPath(), @@ -706,6 +738,7 @@ class Editor extends View "Cancel" ) + # Internal: scrollTop: (scrollTop, options={}) -> return @cachedScrollTop or 0 unless scrollTop? maxScrollTop = @verticalScrollbar.prop('scrollHeight') - @verticalScrollbar.height() @@ -722,21 +755,38 @@ class Editor extends View if options?.adjustVerticalScrollbar ? true @verticalScrollbar.scrollTop(scrollTop) + # Internal: scrollBottom: (scrollBottom) -> if scrollBottom? @scrollTop(scrollBottom - @scrollView.height()) else @scrollTop() + @scrollView.height() + # Public: Scrolls the editor to the bottom. scrollToBottom: -> @scrollBottom(@screenLineCount() * @lineHeight) + # Public: Scrolls the editor to the given buffer position. + # + # bufferPosition - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - A hash matching the options available to {.scrollToPixelPosition} scrollToBufferPosition: (bufferPosition, options) -> @scrollToPixelPosition(@pixelPositionForBufferPosition(bufferPosition), options) + # Public: Scrolls the editor to the given screen position. + # + # screenPosition - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - A hash matching the options available to {.scrollToPixelPosition} scrollToScreenPosition: (screenPosition, options) -> @scrollToPixelPosition(@pixelPositionForScreenPosition(screenPosition), options) + # Public: Scrolls the editor to the given pixel position. + # + # bufferPosition - An object that represents a pixel position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # options - A hash matching the options available to {.scrollVertically} scrollToPixelPosition: (pixelPosition, options) -> return unless @attached @scrollVertically(pixelPosition, options) @@ -1315,9 +1365,21 @@ class Editor extends View toggleLineCommentsInSelection: -> @activeEditSession.toggleLineCommentsInSelection() + # Public: Converts a buffer position to a pixel position. + # + # position - An object that represents a buffer position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # + # Returns an object with two values: `top` and `left`, representing the pixel positions. pixelPositionForBufferPosition: (position) -> @pixelPositionForScreenPosition(@screenPositionForBufferPosition(position)) + # Public: Converts a screen position to a pixel position. + # + # position - An object that represents a screen position. It can be either + # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} + # + # Returns an object with two values: `top` and `left`, representing the pixel positions. pixelPositionForScreenPosition: (position) -> return { top: 0, left: 0 } unless @isOnDom() and @isVisible() {row, column} = Point.fromObject(position) @@ -1432,10 +1494,12 @@ class Editor extends View path = @getPath() pasteboard.write(path) if path? + # Internal: saveDebugSnapshot: -> atom.showSaveDialog (path) => fsUtils.write(path, @getDebugSnapshot()) if path + # Internal: getDebugSnapshot: -> [ "Debug Snapshot: #{@getPath()}" @@ -1444,6 +1508,7 @@ class Editor extends View @getBuffer().getDebugSnapshot() ].join('\n\n') + # Internal: getRenderedLinesDebugSnapshot: -> lines = ['Rendered Lines:'] firstRenderedScreenRow = @firstRenderedScreenRow @@ -1451,9 +1516,11 @@ class Editor extends View lines.push "#{firstRenderedScreenRow + n}: #{$(this).text()}" lines.join('\n') + # Internal: logScreenLines: (start, end) -> @activeEditSession.logScreenLines(start, end) + # Internal: logRenderedLines: -> @renderedLines.find('.line').each (n) -> console.log n, $(this).text() diff --git a/src/app/language-mode.coffee b/src/app/language-mode.coffee index d8f9a2c47..ac82579ed 100644 --- a/src/app/language-mode.coffee +++ b/src/app/language-mode.coffee @@ -104,7 +104,7 @@ class LanguageMode # Public: Given a buffer row, this returns a suggested indentation level. # - # The indentation level provided is based on the current {LangugaeMode}. + # The indentation level provided is based on the current {LanguageMode}. # # bufferRow - A {Number} indicating the buffer row # From 79562f51fdc836874d24a760531060306b38de9c Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 01:28:50 -0500 Subject: [PATCH 19/51] Some more low hanging fruit --- src/app/cursor.coffee | 102 +++++++++++++++++++++++++++++++++-- src/app/edit-session.coffee | 1 + src/app/editor.coffee | 4 +- src/app/git.coffee | 103 +++++++++++++++++++++++++++++++++++- src/app/point.coffee | 86 ++++++++++++++++++++++++++++++ src/app/range.coffee | 87 ++++++++++++++++++++++++++++++ 6 files changed, 376 insertions(+), 7 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 336591d95..ddeda573b 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -3,6 +3,7 @@ Range = require 'range' EventEmitter = require 'event-emitter' _ = require 'underscore' +# Public: The `Cursor` class represents the little blinking line identifying where text can be inserted. module.exports = class Cursor screenPosition: null @@ -38,34 +39,40 @@ class Cursor @editSession.destroyMarker(@marker) @editSession.removeCursor(this) @trigger 'destroyed' + # Public: Moves a cursor to a given screen position. # - # position - An {Array} of two numbers: the screen row, and the screen column. - # options - An object with properties based on {Cursor.changePosition} + # screenPosition - An {Array} of two numbers: the screen row, and the screen column. + # options - An object with the following keys: + # :autoscroll - A {Boolean} which, if `true`, scrolls the {EditSession} to wherever the cursor moves to # setScreenPosition: (screenPosition, options={}) -> @changePosition options, => @editSession.setMarkerHeadScreenPosition(@marker, screenPosition, options) - # Public: Gets the current screen position. + # Public: Gets the screen position of the cursor. # # Returns an {Array} of two numbers: the screen row, and the screen column. getScreenPosition: -> @editSession.getMarkerHeadScreenPosition(@marker) + # Public: Moves a cursor to a given buffer position. # - # position - An {Array} of two numbers: the screen row, and the screen column. - # options - An object with properties based on {Cursor.changePosition} + # bufferPosition - An {Array} of two numbers: the buffer row, and the buffer column. + # options - An object with the following keys: + # :autoscroll - A {Boolean} which, if `true`, scrolls the {EditSession} to wherever the cursor moves to # setBufferPosition: (bufferPosition, options={}) -> @changePosition options, => @editSession.setMarkerHeadBufferPosition(@marker, bufferPosition, options) + # Public: Gets the current buffer position. # # Returns an {Array} of two numbers: the buffer row, and the buffer column. getBufferPosition: -> @editSession.getMarkerHeadBufferPosition(@marker) + # Internal: changePosition: (options, fn) -> @goalColumn = null @clearSelection() @@ -73,82 +80,125 @@ class Cursor unless fn() @trigger 'autoscrolled' if @needsAutoscroll + # Internal: updateVisibility: -> @setVisible(@editSession.isMarkerRangeEmpty(@marker)) + # Public: Sets the visibility of the cursor. + # + # visible - A {Boolean} indicating whether the cursor should be visible setVisible: (visible) -> if @visible != visible @visible = visible @needsAutoscroll ?= true if @visible and @isLastCursor() @trigger 'visibility-changed', @visible + # Public: Retrieves the visibility of the cursor. + # + # Returns a {Boolean}. isVisible: -> @visible + # Public: Identifies what the cursor considers a "word" RegExp. + # + # Returns a {RegExp}. wordRegExp: -> nonWordCharacters = config.get("editor.nonWordCharacters") new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(nonWordCharacters)}]+|[#{_.escapeRegExp(nonWordCharacters)}]+", "g") + # Public: Identifies if this cursor is the last in the {EditSession}. + # + # Returns a {Boolean}. isLastCursor: -> this == @editSession.getCursor() + # Public: Identifies if the cursor is surrounded by whitespace. + # + # "Surrounded" here means that all characters before and after the cursor is whitespace. + # + # Returns a {Boolean}. isSurroundedByWhitespace: -> {row, column} = @getBufferPosition() range = [[row, Math.min(0, column - 1)], [row, Math.max(0, column + 1)]] /^\s+$/.test @editSession.getTextInBufferRange(range) + # Public: Removes the setting for auto-scroll. clearAutoscroll: -> @needsAutoscroll = null + # Public: Deselects whatever the cursor is selecting. clearSelection: -> if @selection @selection.goalBufferRange = null @selection.clear() unless @selection.retainSelection + # Public: Retrieves the cursor's screen row. + # + # Returns a {Number}. getScreenRow: -> @getScreenPosition().row + # Public: Retrieves the cursor's screen column. + # + # Returns a {Number}. getScreenColumn: -> @getScreenPosition().column + # Public: Retrieves the cursor's buffer row. + # + # Returns a {Number}. getBufferRow: -> @getBufferPosition().row + # Public: Retrieves the cursor's buffer column. + # + # Returns a {Number}. getBufferColumn: -> @getBufferPosition().column + # Public: Retrieves the cursor's buffer row text. + # + # Returns a {String}. getCurrentBufferLine: -> @editSession.lineForBufferRow(@getBufferRow()) + # Public: Moves the cursor up one screen row. moveUp: (rowCount = 1) -> { row, column } = @getScreenPosition() column = @goalColumn if @goalColumn? @setScreenPosition({row: row - rowCount, column: column}) @goalColumn = column + # Public: Moves the cursor down one screen row. moveDown: (rowCount = 1) -> { row, column } = @getScreenPosition() column = @goalColumn if @goalColumn? @setScreenPosition({row: row + rowCount, column: column}) @goalColumn = column + # Public: Moves the cursor left one screen column. moveLeft: -> { row, column } = @getScreenPosition() [row, column] = if column > 0 then [row, column - 1] else [row - 1, Infinity] @setScreenPosition({row, column}) + # Public: Moves the cursor right one screen column. moveRight: -> { row, column } = @getScreenPosition() @setScreenPosition([row, column + 1], skipAtomicTokens: true, wrapBeyondNewlines: true, wrapAtSoftNewlines: true) + # Public: Moves the cursor to the top of the buffer. moveToTop: -> @setBufferPosition([0,0]) + # Public: Moves the cursor to the bottom of the buffer. moveToBottom: -> @setBufferPosition(@editSession.getEofBufferPosition()) + # Public: Moves the cursor to the beginning of the buffer line. moveToBeginningOfLine: -> @setBufferPosition([@getBufferRow(), 0]) + # Public: Moves the cursor to the beginning of the first character in the line. moveToFirstCharacterOfLine: -> position = @getBufferPosition() scanRange = @getCurrentLineBufferRange() @@ -159,6 +209,7 @@ class Cursor newPosition = [position.row, 0] if newPosition.isEqual(position) @setBufferPosition(newPosition) + # Public: Moves the cursor to the beginning of the buffer line, skipping all whitespace. skipLeadingWhitespace: -> position = @getBufferPosition() scanRange = @getCurrentLineBufferRange() @@ -168,20 +219,30 @@ class Cursor @setBufferPosition(endOfLeadingWhitespace) if endOfLeadingWhitespace.isGreaterThan(position) + # Public: Moves the cursor to the end of the buffer line. moveToEndOfLine: -> @setBufferPosition([@getBufferRow(), Infinity]) + # Public: Moves the cursor to the beginning of the word. moveToBeginningOfWord: -> @setBufferPosition(@getBeginningOfCurrentWordBufferPosition()) + # Public: Moves the cursor to the end of the word. moveToEndOfWord: -> if position = @getEndOfCurrentWordBufferPosition() @setBufferPosition(position) + # Public: Moves the cursor to the beginning of the next word. moveToBeginningOfNextWord: -> if position = @getBeginningOfNextWordBufferPosition() @setBufferPosition(position) + # Public: Retrieves the buffer position of where the current word starts. + # + # options - A hash with one option: + # :wordRegex - A {RegExp} indicating what constitutes a "word" (default: {wordRegExp}) + # + # Returns a {Range}. getBeginningOfCurrentWordBufferPosition: (options = {}) -> allowPrevious = options.allowPrevious ? true currentBufferPosition = @getBufferPosition() @@ -197,6 +258,12 @@ class Cursor beginningOfWordPosition or currentBufferPosition + # Public: Retrieves the buffer position of where the current word ends. + # + # options - A hash with one option: + # :wordRegex - A {RegExp} indicating what constitutes a "word" (default: {wordRegExp}) + # + # Returns a {Range}. getEndOfCurrentWordBufferPosition: (options = {}) -> allowNext = options.allowNext ? true currentBufferPosition = @getBufferPosition() @@ -211,6 +278,12 @@ class Cursor endOfWordPosition ? currentBufferPosition + # Public: Retrieves the buffer position of where the next word starts. + # + # options - A hash with one option: + # :wordRegex - A {RegExp} indicating what constitutes a "word" (default: {wordRegExp}) + # + # Returns a {Range}. getBeginningOfNextWordBufferPosition: (options = {}) -> currentBufferPosition = @getBufferPosition() start = if @isSurroundedByWhitespace() then currentBufferPosition else @getEndOfCurrentWordBufferPosition() @@ -233,9 +306,19 @@ class Cursor endOptions = _.extend(_.clone(options), allowNext: false) new Range(@getBeginningOfCurrentWordBufferPosition(startOptions), @getEndOfCurrentWordBufferPosition(endOptions)) + # Public: Retrieves the range for the current line. + # + # options - A hash with the same keys as {EditSession.bufferRangeForBufferRow} + # + # Returns a {Range}. getCurrentLineBufferRange: (options) -> @editSession.bufferRangeForBufferRow(@getBufferRow(), options) + # Public: Retrieves the range for the current paragraph. + # + # A paragraph is defined as a block of text surrounded by two empty lines. + # + # Returns a {Range}. getCurrentParagraphBufferRange: -> row = @getBufferRow() return unless /\w/.test(@editSession.lineForBufferRow(row)) @@ -256,15 +339,24 @@ class Cursor getCurrentWordPrefix: -> @editSession.getTextInBufferRange([@getBeginningOfCurrentWordBufferPosition(), @getBufferPosition()]) + # Public: Identifies if the cursor is at the start of a line. + # + # Returns a {Boolean}. isAtBeginningOfLine: -> @getBufferPosition().column == 0 + # Public: Retrieves the indentation level of the current line. + # + # Returns a {Number}. getIndentLevel: -> if @editSession.softTabs @getBufferColumn() / @editSession.getTabLength() else @getBufferColumn() + # Public: Identifies if the cursor is at the end of a line. + # + # Returns a {Boolean}. isAtEndOfLine: -> @getBufferPosition().isEqual(@getCurrentLineBufferRange().end) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 192077668..55d8ac789 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -10,6 +10,7 @@ Range = require 'range' _ = require 'underscore' fsUtils = require 'fs-utils' +# Public: `EditSession`s manage the states between file {Buffers}, and the project as a whole. module.exports = class EditSession registerDeserializer(this) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 52710248b..dff8f920e 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -10,7 +10,9 @@ fsUtils = require 'fs-utils' $ = require 'jquery' _ = require 'underscore' -# Public: Represents the visual pane in Atom. +# Public: Represents the entire visual pane in Atom. +# +# The Editor manages the {EditSession}, which manages the file buffers. module.exports = class Editor extends View @configDefaults: diff --git a/src/app/git.coffee b/src/app/git.coffee index b01cf826b..175746237 100644 --- a/src/app/git.coffee +++ b/src/app/git.coffee @@ -5,8 +5,18 @@ EventEmitter = require 'event-emitter' RepositoryStatusTask = require 'repository-status-task' GitUtils = require 'git-utils' +# Public: Represents the underlying git operations performed by Atom. +# +# Ultimately, this is an overlay to the native [git-utils](https://github.com/atom/node-git) model. module.exports = class Git + # Public: Creates a new `Git` instance. + # + # path - The git repository to open + # options - A hash with one key: + # :refreshOnWindowFocus - A {Boolean} that identifies if the windows should refresh + # + # Returns a new {Git} object. @open: (path, options) -> return null unless path try @@ -40,16 +50,24 @@ class Git @subscribe buffer, 'saved', bufferStatusHandler @subscribe buffer, 'reloaded', bufferStatusHandler + # Public: Retrieves the git repository. + # + # Returns a new `Repository`. getRepo: -> unless @repo? throw new Error("Repository has been destroyed") @repo + # Public: Reread the index to update any values that have changed since the last time the index was read. refreshIndex: -> @getRepo().refreshIndex() - + + # Public: Retrieves the path of the repository. + # + # Returns a {String}. getPath: -> @path ?= fsUtils.absolute(@getRepo().getPath()) + # Internal: destroy: -> if @statusTask? @statusTask.abort() @@ -62,12 +80,25 @@ class Git @unsubscribe() + # Public: Retrieves the working directory of the repository. + # + # Returns a {String}. getWorkingDirectory: -> @getRepo().getWorkingDirectory() + # Public: Retrieves the reference or SHA-1 that `HEAD` points to. + # + # This can be `refs/heads/master`, or a full SHA-1 if the repository is in a detached `HEAD` state. + # + # Returns a {String}. getHead: -> @getRepo().getHead() ? '' + # Public: Retrieves the status of a single path in the repository. + # + # path - An {String} defining a relative path + # + # Returns a {Number}. getPathStatus: (path) -> currentPathStatus = @statuses[path] ? 0 pathStatus = @getRepo().getStatus(@relativize(path)) ? 0 @@ -79,38 +110,98 @@ class Git @trigger 'status-changed', path, pathStatus pathStatus + # Public: Identifies if a path is ignored. + # + # path - The {String} path to check + # + # Returns a {Boolean}. isPathIgnored: (path) -> @getRepo().isIgnored(@relativize(path)) + # Public: Identifies if a value represents a status code. + # + # status - The code {Number} to check + # + # Returns a {Boolean}. isStatusModified: (status) -> @getRepo().isStatusModified(status) + # Public: Identifies if a path was modified. + # + # path - The {String} path to check + # + # Returns a {Boolean}. isPathModified: (path) -> @isStatusModified(@getPathStatus(path)) + # Public: Identifies if a status code represents a new path. + # + # status - The code {Number} to check + # + # Returns a {Boolean}. isStatusNew: (status) -> @getRepo().isStatusNew(status) + # Public: Identifies if a path is new. + # + # path - The {String} path to check + # + # Returns a {Boolean}. isPathNew: (path) -> @isStatusNew(@getPathStatus(path)) + # Public: Makes a path relative to the repository's working directory. + # + # path - The {String} path to convert + # + # Returns a {String}. relativize: (path) -> @getRepo().relativize(path) + # Public: Retrieves a shortened version of {.getHead}. + # + # This removes the leading segments of `refs/heads`, `refs/tags`, or `refs/remotes`. + # It also shortenes the SHA-1 of a detached `HEAD` to 7 characters. + # + # Returns a {String}. getShortHead: -> @getRepo().getShortHead() + # Public: Restore the contents of a path in the working directory and index to the version at `HEAD`. + # + # This is essentially the same as running: + # ``` + # git reset HEAD -- + # git checkout HEAD -- + # ``` + # + # path - The {String} path to checkout + # + # Returns a {Boolean} that's `true` if the method was successful. checkoutHead: (path) -> headCheckedOut = @getRepo().checkoutHead(@relativize(path)) @getPathStatus(path) if headCheckedOut headCheckedOut + # Public: Retrieves the number of lines added and removed to a path. + # + # This compares the working directory contents of the path to the `HEAD` version. + # + # path - The {String} path to check + # + # Returns an object with two keys, `added` and `deleted`. These will always be greater than 0. getDiffStats: (path) -> @getRepo().getDiffStats(@relativize(path)) + # Public: Identifies if a path is a submodule. + # + # path - The {String} path to check + # + # Returns a {Boolean}. isSubmodule: (path) -> @getRepo().isSubmodule(@relativize(path)) + # Internal: refreshStatus: -> if @statusTask? @statusTask.off() @@ -123,6 +214,11 @@ class Git @statusTask = null @statusTask.start() + # Public: Retrieves the status of a directory. + # + # path - The {String} path to check + # + # Returns a {Number} representing the status. getDirectoryStatus: (directoryPath) -> directoryPath = "#{directoryPath}/" directoryStatus = 0 @@ -130,6 +226,11 @@ class Git directoryStatus |= status if path.indexOf(directoryPath) is 0 directoryStatus + # Public: Retrieves the number of commits the `HEAD` branch is ahead/behind the remote branch it is tracking. + # + # 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. getAheadBehindCounts: -> @getRepo().getAheadBehindCount() diff --git a/src/app/point.coffee b/src/app/point.coffee index 6dd3eca27..0af4ddfff 100644 --- a/src/app/point.coffee +++ b/src/app/point.coffee @@ -1,7 +1,16 @@ _ = require 'underscore' +# Public: Represents a coordinate in the editor. +# +# Each `Point` is actually an object with two properties: `row` and `column`. module.exports = class Point + + # Public: Constructs a `Point` from a given object. + # + # object - This can be an {Array} (`[startRow, startColumn, endRow, endColumn]`) or an object `{row, column}` + # + # Returns the new {Point}. @fromObject: (object) -> if object instanceof Point object @@ -13,6 +22,15 @@ class Point new Point(row, column) + # Public: Identifies which `Point` is smaller. + # + # "Smaller" means that both the `row` and `column` values of one `Point` are less than or equal + # to the other. + # + # point1 - The first {Point} to check + # point2 - The second {Point} to check + # + # Returns the smaller {Point}. @min: (point1, point2) -> point1 = @fromObject(point1) point2 = @fromObject(point2) @@ -21,11 +39,25 @@ class Point else point2 + # Public: Creates a new `Point` object. + # + # row - A {Number} indicating the row (default: 0) + # column - A {Number} indicating the column (default: 0) + # + # Returns a {Point}, constructor: (@row=0, @column=0) -> + # Public: Creates an identical copy of the `Point`. + # + # Returns a duplicate {Point}. copy: -> new Point(@row, @column) + # Public: Adds the `column`s of two `Point`s together. + # + # other - The {Point} to add with + # + # Returns the new {Point}. add: (other) -> other = Point.fromObject(other) row = @row + other.row @@ -36,10 +68,24 @@ class Point new Point(row, column) + # Public: Moves a `Point`. + # + # In other words, the `row` values and `column` values are added to each other. + # + # other - The {Point} to add with + # + # Returns the new {Point}. translate: (other) -> other = Point.fromObject(other) new Point(@row + other.row, @column + other.column) + # Public: Creates two new `Point`s, split down a `column` value. + # + # In other words, given a point, this creates `Point(0, column)` and `Point(row, column)`. + # + # column - The {Number} to split at + # + # Returns an {Array} of two {Point}s. splitAt: (column) -> if @row == 0 rightColumn = @column - column @@ -48,6 +94,17 @@ class Point [new Point(0, column), new Point(@row, rightColumn)] + # Internal: Compares two `Point`s. + # + # other - The {Point} to compare against + # + # Returns a {Number} matching the following rules: + # * If the first `row` is greater than `other.row`, returns `1`. + # * If the first `row` is less than `other.row`, returns `-1`. + # * If the first `column` is greater than `other.column`, returns `1`. + # * If the first `column` is less than `other.column`, returns `-1`. + # + # Otherwise, returns `0`. compare: (other) -> if @row > other.row 1 @@ -61,31 +118,60 @@ class Point else 0 + # Public: Identifies if two `Point`s are equal. + # + # other - The {Point} to compare against + # + # Returns a {Boolean}. isEqual: (other) -> return false unless other other = Point.fromObject(other) @row == other.row and @column == other.column + # Public: Identifies if one `Point` is less than another. + # + # other - The {Point} to compare against + # + # Returns a {Boolean}. isLessThan: (other) -> @compare(other) < 0 + # Public: Identifies if one `Point` is less than or equal to another. + # + # other - The {Point} to compare against + # + # Returns a {Boolean}. isLessThanOrEqual: (other) -> @compare(other) <= 0 + # Public: Identifies if one `Point` is greater than another. + # + # other - The {Point} to compare against + # + # Returns a {Boolean}. isGreaterThan: (other) -> @compare(other) > 0 + # Public: Identifies if one `Point` is greater than or equal to another. + # + # other - The {Point} to compare against + # + # Returns a {Boolean}. isGreaterThanOrEqual: (other) -> @compare(other) >= 0 + # Internal: inspect: -> "(#{@row}, #{@column})" + # Internal: toString: -> "#{@row},#{@column}" + # Internal: toArray: -> [@row, @column] + # Internal: serialize: -> @toArray() diff --git a/src/app/range.coffee b/src/app/range.coffee index d72ef6514..6847dd6da 100644 --- a/src/app/range.coffee +++ b/src/app/range.coffee @@ -1,8 +1,20 @@ Point = require 'point' _ = require 'underscore' +# Public: Indicates a region within the editor. +# +# To better visualize how this works, imagine a rectangle. +# Each quadrant of the rectangle is analogus to a range, as ranges contain a +# starting row and a starting column, as well as an ending row, and an ending column. +# +# Each `Range` is actually constructed of two `Point` objects, labelled `start` and `end`. module.exports = class Range + # Public: Constructs a `Range` from a given object. + # + # object - This can be an {Array} (`[startRow, startColumn, endRow, endColumn]`) or an object `{start: Point, end: Point}` + # + # Returns the new {Range}. @fromObject: (object) -> if _.isArray(object) new Range(object...) @@ -11,6 +23,13 @@ class Range else new Range(object.start, object.end) + # Public: Constructs a `Range` from a {Point}, and the delta values beyond that point. + # + # point - A {Point} to start with + # rowDelta - A {Number} indicating how far from the starting {Point} the range's row should be + # columnDelta - A {Number} indicating how far from the starting {Point} the range's column should be + # + # Returns the new {Range}. @fromPointWithDelta: (point, rowDelta, columnDelta) -> pointA = Point.fromObject(point) pointB = new Point(point.row + rowDelta, point.column + columnDelta) @@ -27,40 +46,86 @@ class Range @start = pointB @end = pointA + # Public: Creates an identical copy of the `Range`. + # + # Returns a duplicate {Range}. copy: -> new Range(@start.copy(), @end.copy()) + # Public: Identifies if two `Range`s are equal. + # + # All four points (`start.row`, `start.column`, `end.row`, `end.column`) must be + # equal for this method to return `true`. + # + # other - A different {Range} to check against + # + # Returns a {Boolean}. isEqual: (other) -> if _.isArray(other) and other.length == 2 other = new Range(other...) other.start.isEqual(@start) and other.end.isEqual(@end) + # Public: Identifies if the `Range` is on the same line. + # + # In other words, if `start.row` is equal to `end.row`. + # + # Returns a {Boolean}. isSingleLine: -> @start.row == @end.row + # Public: Identifies if two `Range`s are on the same line. + # + # other - A different {Range} to check against + # + # Returns a {Boolean}. coversSameRows: (other) -> @start.row == other.start.row && @end.row == other.end.row + # Internal: inspect: -> "[#{@start.inspect()} - #{@end.inspect()}]" + # Public: Adds a new point to the `Range`s `start` and `end`. + # + # point - A new {Point} to add + # + # Returns the new {Range}. add: (point) -> new Range(@start.add(point), @end.add(point)) translate: (startPoint, endPoint=startPoint) -> new Range(@start.translate(startPoint), @end.translate(endPoint)) + # Public: Identifies if two `Range`s intersect each other. + # + # otherRange - A different {Range} to check against + # + # Returns a {Boolean}. intersectsWith: (otherRange) -> if @start.isLessThanOrEqual(otherRange.start) @end.isGreaterThanOrEqual(otherRange.start) else otherRange.intersectsWith(this) + # Public: Identifies if a second `Range` is contained within a first. + # + # otherRange - A different {Range} to check against + # options - A hash with a single option: + # :exclusive - A {Boolean} which, if `true`, indicates that no {Point}s in the `Range` can be equal + # + # Returns a {Boolean}. containsRange: (otherRange, {exclusive} = {}) -> { start, end } = Range.fromObject(otherRange) @containsPoint(start, {exclusive}) and @containsPoint(end, {exclusive}) + # Public: Identifies if a `Range` contains a {Point}. + # + # point - A {Point} to check against + # options - A hash with a single option: + # :exclusive - A {Boolean} which, if `true`, indicates that no {Point}s in the `Range` can be equal + # + # Returns a {Boolean}. containsPoint: (point, {exclusive} = {}) -> point = Point.fromObject(point) if exclusive @@ -68,17 +133,36 @@ class Range else point.isGreaterThanOrEqual(@start) and point.isLessThanOrEqual(@end) + # Public: Identifies if a `Range` contains a row. + # + # row - A row {Number} to check against + # options - A hash with a single option: + # + # Returns a {Boolean}. containsRow: (row) -> @start.row <= row <= @end.row + # Public: Constructs a union between two `Range`s. + # + # otherRange - A different {Range} to unionize with + # + # Returns the new {Range}. union: (otherRange) -> start = if @start.isLessThan(otherRange.start) then @start else otherRange.start end = if @end.isGreaterThan(otherRange.end) then @end else otherRange.end new Range(start, end) + # Public: Identifies if a `Range` is empty. + # + # A `Range` is empty if its start {Point} matches its end. + # + # Returns a {Boolean}. isEmpty: -> @start.isEqual(@end) + # Public: Calculates the difference between a `Range`s `start` and `end` points. + # + # Returns a {Point}. toDelta: -> rows = @end.row - @start.row if rows == 0 @@ -87,5 +171,8 @@ class Range columns = @end.column new Point(rows, columns) + # Public: Calculates the number of rows a `Range`s contains. + # + # Returns a {Number}. getRowCount: -> @end.row - @start.row + 1 From f677e6633c1cbec987bd94ec754e7d19c0ce70bc Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 02:20:45 -0500 Subject: [PATCH 20/51] Fix doc tasks --- Rakefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Rakefile b/Rakefile index a9bec3456..ffb21c054 100644 --- a/Rakefile +++ b/Rakefile @@ -126,14 +126,14 @@ namespace :docs do system %{./biscotto --statsOnly src/app/} end - desc "Builds the API docs in src/package" - task :package do - system %{./biscotto src/package/} + desc "Builds the API docs in src/packages" + task :packages do + system %{./biscotto src/packages/} end - desc "Lists the stats for API doc coverage in src/package" + desc "Lists the stats for API doc coverage in src/packages" task :stats do - system %{./biscotto --statsOnly src/package/} + system %{./biscotto --statsOnly src/packages/} end end end From 742a28ca9c5f0dc010421ec96907ab7d7e3ece6e Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 02:20:55 -0500 Subject: [PATCH 21/51] Define file stuff --- src/app/directory.coffee | 24 +++++++++++- src/app/file.coffee | 38 +++++++++++++++++- src/app/pasteboard.coffee | 13 +++++++ src/app/text-buffer.coffee | 80 +++++++++++++++++++++++++++++++++++++- 4 files changed, 151 insertions(+), 4 deletions(-) diff --git a/src/app/directory.coffee b/src/app/directory.coffee index aadc75a94..7972dc5b9 100644 --- a/src/app/directory.coffee +++ b/src/app/directory.coffee @@ -5,17 +5,35 @@ pathWatcher = require 'pathwatcher' File = require 'file' EventEmitter = require 'event-emitter' +# Public: Represents a directory in the project. +# +# Directories contain an array of {File}s. module.exports = class Directory path: null + # Public: Creates a new directory. + # + # path - A {String} representing the file directory + # symlink - A {Boolean} indicating if the path is a symlink (default: false) constructor: (@path, @symlink=false) -> + # Public: Retrieves the basename of the directory. + # + # Returns a {String}. getBaseName: -> fsUtils.base(@path) + # Public: Retrieves the directory's path. + # + # Returns a {String}. getPath: -> @path + # Public: Retrieves the file entries in the directory. + # + # This does follow symlinks. + # + # Returns an {Array} of {Files}. getEntries: -> directories = [] files = [] @@ -33,16 +51,20 @@ class Directory directories.concat(files) + # Internal: afterSubscribe: -> @subscribeToNativeChangeEvents() if @subscriptionCount() == 1 + # Internal: afterUnsubscribe: -> @unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0 + # Internal: subscribeToNativeChangeEvents: -> @watchSubscription = pathWatcher.watch @path, (eventType) => @trigger "contents-changed" if eventType is "change" - + + # Internal: unsubscribeFromNativeChangeEvents: -> if @watchSubscription? @watchSubscription.close() diff --git a/src/app/file.coffee b/src/app/file.coffee index ec06ef189..7fd04463c 100644 --- a/src/app/file.coffee +++ b/src/app/file.coffee @@ -5,29 +5,55 @@ fsUtils = require 'fs-utils' pathWatcher = require 'pathwatcher' _ = require 'underscore' +# Public: Represents an individual file in the editor. +# +# The entry point for this class is in two locations: +# * {Buffer}, which associates text contents with a file +# * {Directory}, which associcates the children of a directory as files module.exports = class File path: null cachedContents: null + # Public: Creates a new file. + # + # path - A {String} representing the file path + # symlink - A {Boolean} indicating if the path is a symlink (default: false) constructor: (@path, @symlink=false) -> try if fs.statSync(@path).isDirectory() throw new Error("#{@path} is a directory") + # Public: Sets the path for the file. + # + # path - A {String} representing the new file path setPath: (@path) -> + # Public: Retrieves the path for the file. + # + # Returns a {String}. getPath: -> @path + # Public: Gets the file's basename--that is, the file without any directory information. + # + # Returns a {String}. getBaseName: -> fsUtils.base(@path) + # Public: Writes (and saves) new contents to the file. + # + # text - A {String} representing the new contents. write: (text) -> previouslyExisted = @exists() @cachedContents = text fsUtils.write(@getPath(), text) @subscribeToNativeChangeEvents() if not previouslyExisted and @subscriptionCount() > 0 + # Public: Reads the file. + # + # flushCache - A {Boolean} indicating if the cache should be erased--_i.e._, a force read is performed + # + # Returns a {String}. read: (flushCache)-> if not @exists() @cachedContents = null @@ -36,15 +62,21 @@ class File else @cachedContents + # Public: Checks to see if a file exists. + # + # Returns a {Boolean}. exists: -> fsUtils.exists(@getPath()) + # Internal: afterSubscribe: -> @subscribeToNativeChangeEvents() if @exists() and @subscriptionCount() == 1 - + + # Internal: afterUnsubscribe: -> @unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0 + # Internal: handleNativeChangeEvent: (eventType, path) -> if eventType is "delete" @unsubscribeFromNativeChangeEvents() @@ -58,9 +90,11 @@ class File return if oldContents == newContents @trigger 'contents-changed' + # Internal: detectResurrectionAfterDelay: -> _.delay (=> @detectResurrection()), 50 + # Internal: detectResurrection: -> if @exists() @subscribeToNativeChangeEvents() @@ -69,10 +103,12 @@ class File @cachedContents = null @trigger "removed" + # Internal: subscribeToNativeChangeEvents: -> @watchSubscription = pathWatcher.watch @path, (eventType, path) => @handleNativeChangeEvent(eventType, path) + # Internal: unsubscribeFromNativeChangeEvents: -> if @watchSubscription @watchSubscription.close() diff --git a/src/app/pasteboard.coffee b/src/app/pasteboard.coffee index 404b48216..91ff0d074 100644 --- a/src/app/pasteboard.coffee +++ b/src/app/pasteboard.coffee @@ -1,17 +1,30 @@ crypto = require 'crypto' +# Public: Represents the clipboard used for copying and pasting in Atom. module.exports = class Pasteboard signatureForMetadata: null + # Internal: Creates and `md5` hash of some text. + # + # text - A {String} to encrypt. + # + # Returns an encrypted {String}. md5: (text) -> crypto.createHash('md5').update(text, 'utf8').digest('hex') + # Public: Saves from the clipboard. + # + # text - A {String} to store + # metadata - An object of additional info to associate with the text write: (text, metadata) -> @signatureForMetadata = @md5(text) @metadata = metadata $native.writeToPasteboard(text) + # Public: Loads from the clipboard. + # + # Returns an {Array}. The first index is the saved text, and the second is any metadata associated with the text. read: -> text = $native.readFromPasteboard() value = [text] diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index 25c8aab56..8a8dc75b5 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -8,6 +8,10 @@ UndoManager = require 'undo-manager' BufferChangeOperation = require 'buffer-change-operation' BufferMarker = require 'buffer-marker' +# Public: Represents the contents of a file. +# +# The `Buffer` is often associated with a {File}. However, this is not always +# the case, as a `Buffer` could be an unsaved chunk of text. module.exports = class Buffer @idCounter = 1 @@ -28,6 +32,10 @@ class Buffer @deserialize: ({path, text}) -> project.bufferForPath(path, text) + # Public: Creates a new buffer. + # + # path - A {String} representing the file path + # initialText - A {String} setting the starting text constructor: (path, initialText) -> @id = @constructor.idCounter++ @nextMarkerId = 1 @@ -72,6 +80,7 @@ class Buffer hasMultipleEditors: -> @refcount > 1 + # Internal: subscribeToFile: -> @file.on "contents-changed", => if @isModified() @@ -88,6 +97,9 @@ class Buffer @file.on "moved", => @trigger "path-changed", this + # Public: Reloads a file in the {EditSession}. + # + # Essentially, this performs a force read of the file. reload: -> @trigger 'will-reload' @updateCachedDiskContents() @@ -95,15 +107,27 @@ class Buffer @triggerModifiedStatusChanged(false) @trigger 'reloaded' + # Public: Rereads the contents of the file, and stores them in the cache. + # + # Essentially, this performs a force read of the file on disk. updateCachedDiskContents: -> @cachedDiskContents = @file.read() + # Public: Gets the file's basename--that is, the file without any directory information. + # + # Returns a {String}. getBaseName: -> @file?.getBaseName() + # Public: Retrieves the path for the file. + # + # Returns a {String}. getPath: -> @file?.getPath() + # Public: Sets the path for the file. + # + # path - A {String} representing the new file path setPath: (path) -> return if path == @getPath() @@ -135,6 +159,9 @@ class Buffer setText: (text) -> @change(@getRange(), text, normalizeLineEndings: false) + # Public: Gets the range of the buffer contents. + # + # Returns a new {Range}, from `[0, 0]` to the end of the buffer. getRange: -> new Range([0, 0], [@getLastRow(), @getLastLine().length]) @@ -243,9 +270,16 @@ class Buffer new Point(row, index) + # Public: Given a row, this deletes it from the buffer. + # + # row - A {Number} representing the row to delete deleteRow: (row) -> @deleteRows(row, row) + # Public: Deletes a range of rows from the buffer. + # + # start - A {Number} representing the starting row + # end - A {Number} representing the ending row deleteRows: (start, end) -> startPoint = null endPoint = null @@ -261,15 +295,26 @@ class Buffer @delete(new Range(startPoint, endPoint)) + # Public: Adds text to the end of the buffer. + # + # text - A {String} of text to add append: (text) -> @insert(@getEofPosition(), text) + # Public: Adds text to a specific point in the buffer + # + # point - A {Point} in the buffer to insert into + # text - A {String} of text to add insert: (point, text) -> @change(new Range(point, point), text) + # Public: Deletes text from the buffer + # + # range - A {Range} whose text to delete delete: (range) -> @change(range, '') + # Internal: change: (oldRange, newText, options) -> oldRange = Range.fromObject(oldRange) operation = new BufferChangeOperation({buffer: this, oldRange, newText, options}) @@ -295,14 +340,22 @@ class Buffer prefix: @lines[range.start.row][0...range.start.column] suffix: @lines[range.end.row][range.end.column..] + # Internal: pushOperation: (operation, editSession) -> if @undoManager @undoManager.pushOperation(operation, editSession) else operation.do() + # Internal: transact: (fn) -> @undoManager.transact(fn) + # Public: Undos the last operation. + # + # editSession - The {EditSession} associated with the buffer. undo: (editSession) -> @undoManager.undo(editSession) + # Public: Redos the last operation. + # + # editSession - The {EditSession} associated with the buffer. redo: (editSession) -> @undoManager.redo(editSession) commit: -> @undoManager.commit() abort: -> @undoManager.abort() @@ -333,13 +386,22 @@ class Buffer else not @isEmpty() + # Public: Identifies if a buffer is in a git conflict with `HEAD`. + # + # Returns a {Boolean}. isInConflict: -> @conflict + # Public: Identifies if a buffer is empty. + # + # Returns a {Boolean}. isEmpty: -> @lines.length is 1 and @lines[0].length is 0 getMarkers: -> _.values(@validMarkers) + # Public: Retrieves the quantity of markers in a buffer. + # + # Returns a {Number}. getMarkerCount: -> _.size(@validMarkers) @@ -479,6 +541,12 @@ class Buffer isRowBlank: (row) -> not /\S/.test @lineForRow(row) + # Public: Given a row, this finds the next row above it that's empty. + # + # startRow - A {Number} identifying the row to start checking at + # + # Returns the row {Number} of the first blank row. + # Returns `null` if there's no other blank row. previousNonBlankRow: (startRow) -> return null if startRow == 0 @@ -491,7 +559,8 @@ class Buffer # # startRow - A row {Number} to check # - # Returns a {Number}, or `null` if there's no other blank row. + # Returns the row {Number} of the next blank row. + # Returns `null` if there's no other blank row. nextNonBlankRow: (startRow) -> lastRow = @getLastRow() if startRow < lastRow @@ -499,18 +568,22 @@ class Buffer return row unless @isRowBlank(row) null + # Public: Identifies if the buffer has soft tabs anywhere. + # + # Returns a {Boolean}, usesSoftTabs: -> for line in @getLines() if match = line.match(/^\s/) return match[0][0] != '\t' undefined - # Public: Checks out the current HEAD revision of the file. + # Public: Checks out the current `HEAD` revision of the file. checkoutHead: -> path = @getPath() return unless path git?.checkoutHead(path) + # Internal: scheduleModifiedEvents: -> clearTimeout(@stoppedChangingTimeout) if @stoppedChangingTimeout stoppedChangingCallback = => @@ -520,6 +593,7 @@ class Buffer @triggerModifiedStatusChanged(modifiedStatus) @stoppedChangingTimeout = setTimeout(stoppedChangingCallback, @stoppedChangingDelay) + # Internal: triggerModifiedStatusChanged: (modifiedStatus) -> return if modifiedStatus is @previousModifiedStatus @previousModifiedStatus = modifiedStatus @@ -531,11 +605,13 @@ class Buffer 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()] From ec3a137a1a0ee88157901562f50916fcca3b437e Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 02:27:42 -0500 Subject: [PATCH 22/51] Doc events --- src/app/event-emitter.coffee | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/app/event-emitter.coffee b/src/app/event-emitter.coffee index 3abcb74ac..cd7bbccda 100644 --- a/src/app/event-emitter.coffee +++ b/src/app/event-emitter.coffee @@ -1,6 +1,16 @@ _ = require 'underscore' +# Public: Provides a list of functions that can be used in Atom for event management. +# +# Each event can have more than one handler; that is, an event can trigger multiple functions. module.exports = + # Public: Associates an event name with a function to perform. + # + # This is called endlessly, until the event is turned {.off}. The {.on} method + # calls an `eventName` only once. + # + # eventName - A {String} name identifying an event + # handler - A {Function} that's executed when the event is triggered on: (eventName, handler) -> [eventName, namespace] = eventName.split('.') @@ -17,6 +27,10 @@ module.exports = @afterSubscribe?() + # Public: Associates an event name with a function to perform only once. + # + # eventName - A {String} name identifying an event + # handler - A {Function} that's executed when the event is triggered one: (eventName, handler) -> oneShotHandler = (args...) => @off(eventName, oneShotHandler) @@ -24,6 +38,10 @@ module.exports = @on eventName, oneShotHandler + # Public: Triggers a registered event. + # + # eventName - A {String} name identifying an event + # args - Any additional arguments to pass over to the event `handler` trigger: (eventName, args...) -> if @queuedEvents @queuedEvents.push [eventName, args...] @@ -37,6 +55,10 @@ module.exports = if handlers = @eventHandlersByEventName?[eventName] handlers.forEach (handler) -> handler(args...) + # Public: Stops executing handlers for a registered event. + # + # eventName - A {String} name identifying an event + # handler - The {Function} to remove from the event. If not provided, all handlers are removed. off: (eventName='', handler) -> [eventName, namespace] = eventName.split('.') eventName = undefined if eventName == '' @@ -67,17 +89,22 @@ module.exports = @afterUnsubscribe?() if @subscriptionCount() < subscriptionCountBefore + # Public: When called, stops triggering any event. pauseEvents: -> @pauseCount ?= 0 if @pauseCount++ == 0 @queuedEvents ?= [] + # Public: When called, resumes triggering events. resumeEvents: -> if --@pauseCount == 0 queuedEvents = @queuedEvents @queuedEvents = null @trigger(event...) for event in queuedEvents + # Public: Identifies how many events are registered. + # + # Returns a `number`. subscriptionCount: -> count = 0 for name, handlers of @eventHandlersByEventName From c5557500a980afe592f99b3eb924bc0c701b032a Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 18:01:54 -0500 Subject: [PATCH 23/51] Add more to specs --- Rakefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index dde454e25..6f46f3294 100644 --- a/Rakefile +++ b/Rakefile @@ -117,9 +117,9 @@ task :tags do end namespace :docs do - namespace :build do + namespace :app do desc "Builds the API docs in src/app" - task :app do + task :build do system %{./biscotto src/app/} end @@ -127,9 +127,11 @@ namespace :docs do task :stats do system %{./biscotto --statsOnly src/app/} end + end + namespace :packages do desc "Builds the API docs in src/packages" - task :packages do + task :build do system %{./biscotto src/packages/} end From 1142ae89aa9725084718d0bc5af61f4ddc7db461 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 18:02:13 -0500 Subject: [PATCH 24/51] Update spec --- spec/app/atom-spec.coffee | 42 ++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/spec/app/atom-spec.coffee b/spec/app/atom-spec.coffee index 56e5ef2d1..c9fec1901 100644 --- a/spec/app/atom-spec.coffee +++ b/spec/app/atom-spec.coffee @@ -2,6 +2,9 @@ $ = require 'jquery' RootView = require 'root-view' {$$} = require 'space-pen' fsUtils = require 'fs-utils' +Exec = require('child_process').exec +_ = require 'underscore' +Project = require 'project' describe "the `atom` global", -> beforeEach -> @@ -324,11 +327,40 @@ describe "the `atom` global", -> fdescribe "API documentation", -> - it "meets a minimum threshold", -> - versionHandler = jasmine.createSpy("versionHandler") - atom.getVersion(versionHandler) + it "meets a minimum threshold for /app (with no errors)", -> + docRunner = jasmine.createSpy("docRunner") + Exec "cd #{project.resolve('../..')} && rake docs:app:stats", docRunner waitsFor -> - versionHandler.callCount > 0 + docRunner.callCount > 0 runs -> - expect(versionHandler.argsForCall[0][0]).toBeDefined() \ No newline at end of file + # error + expect(docRunner.argsForCall[0][0]).toBeNull() + + results = docRunner.argsForCall[0][1].split("\n") + results.pop() + + coverage = parseFloat _.last(results).match(/.+?%/) + expect(coverage).toBeGreaterThan 85 + + # stderr + expect(docRunner.argsForCall[0][2]).toBe '' + + it "meets a minimum threshold for /packages (with no errors)", -> + docRunner = jasmine.createSpy("docRunner") + Exec "cd #{project.resolve('../..')} && rake docs:packages:stats", docRunner + waitsFor -> + docRunner.callCount > 0 + + runs -> + # error + expect(docRunner.argsForCall[0][0]).toBeNull() + + results = docRunner.argsForCall[0][1].split("\n") + results.pop() + + coverage = parseFloat _.last(results).match(/.+?%/) + expect(coverage).toBeGreaterThan 85 + + # stderr + expect(docRunner.argsForCall[0][2]).toBe '' \ No newline at end of file From bd00c5d53dd0542e5e4c3fd01e878fa0cc337390 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 18:04:14 -0500 Subject: [PATCH 25/51] stash --- src/app/project.coffee | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/app/project.coffee b/src/app/project.coffee index 8ff23f274..81849224d 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -9,6 +9,10 @@ EventEmitter = require 'event-emitter' Directory = require 'directory' BufferedProcess = require 'buffered-process' +# Public: Represents a project that's opened in Atom. +# +# Ultimately, a project is a git directory that's been opened. It's a collection +# of directories and files that you can operate on. module.exports = class Project registerDeserializer(this) @@ -35,9 +39,15 @@ class Project destroy: -> editSession.destroy() for editSession in @getEditSessions() + # Public: Retrieves the project path. + # + # Returns a {String}. getPath: -> @rootDirectory?.path + # Public: Sets the project path. + # + # path - A {String} representing the new path setPath: (path) -> @rootDirectory?.off() @@ -49,9 +59,15 @@ class Project @trigger "path-changed" + # Public: Retrieves the name of the root directory. + # + # Returns a {String}. getRootDirectory: -> @rootDirectory + # Public: Retrieves the names of every file (that's not `git ignore`d) in the project. + # + # Returns an {Array} of {String}s. getFilePaths: -> deferred = $.Deferred() paths = [] @@ -61,6 +77,11 @@ class Project deferred.resolve(paths) deferred.promise() + # Public: Identifies if a path is ignored. + # + # path - The {String} name of the path to check + # + # Returns a {Boolean}. isPathIgnored: (path) -> for segment in path.split("/") ignoredNames = config.get("core.ignoredNames") or [] @@ -68,6 +89,11 @@ class Project @ignoreRepositoryPath(path) + # Public: Identifies if a path is ignored. + # + # path - The {String} name of the path to check + # + # Returns a {Boolean}. ignoreRepositoryPath: (path) -> config.get("core.hideGitIgnoredFiles") and git?.isPathIgnored(fsUtils.join(@getPath(), path)) From 8bcb01383cbc6db46c281b5c8b360dd689a151cf Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Wed, 10 Apr 2013 18:16:54 -0500 Subject: [PATCH 26/51] Add Project --- src/app/project.coffee | 66 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/src/app/project.coffee b/src/app/project.coffee index 81849224d..cf1f2a230 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -97,26 +97,57 @@ class Project ignoreRepositoryPath: (path) -> config.get("core.hideGitIgnoredFiles") and git?.isPathIgnored(fsUtils.join(@getPath(), path)) + # Public: Given a path, this resolves it relative to the project directory. + # + # filePath - The {String} name of the path to convert + # + # Returns a {String}. resolve: (filePath) -> filePath = fsUtils.join(@getPath(), filePath) unless filePath[0] == '/' fsUtils.absolute filePath + # Public: Given a path, this makes it relative to the project directory. + # + # filePath - The {String} name of the path to convert + # + # Returns a {String}. relativize: (fullPath) -> return fullPath unless fullPath.lastIndexOf(@getPath()) is 0 fullPath.replace(@getPath(), "").replace(/^\//, '') + # Public: Identifies if the project is using soft tabs. + # + # Returns a {Boolean}. getSoftTabs: -> @softTabs + + # Public: Sets the project to use soft tabs. + # + # softTabs - A {Boolean} which, if `true`, sets soft tabs setSoftTabs: (@softTabs) -> + # Public: Identifies if the project is using soft wrapping. + # + # Returns a {Boolean}. getSoftWrap: -> @softWrap + + # Public: Sets the project to use soft wrapping. + # + # softTabs - A {Boolean} which, if `true`, sets soft wrapping setSoftWrap: (@softWrap) -> + # Public: Given a path to a file, this constructs and associates a new {EditSession}. + # + # filePath - The {String} path of the file to associate with + # editSessionOptions - Options that you can pass to the `EditSession` constructor + # + # Returns an {EditSession}. buildEditSession: (filePath, editSessionOptions={}) -> if ImageEditSession.canOpen(filePath) new ImageEditSession(filePath) else @buildEditSessionForBuffer(@bufferForPath(filePath), editSessionOptions) + # Internal: buildEditSessionForBuffer: (buffer, editSessionOptions) -> options = _.extend(@defaultEditSessionOptions(), editSessionOptions) options.project = this @@ -126,27 +157,39 @@ class Project @trigger 'edit-session-created', editSession editSession + # Internal: defaultEditSessionOptions: -> tabLength: @tabLength softTabs: @getSoftTabs() softWrap: @getSoftWrap() + # Public: Retrieves all the {EditSession}s in the project; that is, the `EditSession`s for all open files. + # + # Returns an {Array} of {EditSession}s. getEditSessions: -> new Array(@editSessions...) + # Internal: eachEditSession: (callback) -> callback(editSession) for editSession in @getEditSessions() @on 'edit-session-created', (editSession) -> callback(editSession) - + + # Public: Removes an {EditSession} association from the project. + # + # Returns the removed {EditSession}. removeEditSession: (editSession) -> _.remove(@editSessions, editSession) - + + # Public: Retrieves all the {Buffer}s in the project; that is, the buffers for all open files. + # + # Returns an {Array} of {Buffer}s. getBuffers: -> buffers = [] for editSession in @editSessions when not _.include(buffers, editSession.buffer) buffers.push editSession.buffer buffers + # Internal: eachBuffer: (args...) -> subscriber = args.shift() if args.length > 1 callback = args.shift() @@ -157,6 +200,15 @@ class Project else @on 'buffer-created', (buffer) -> callback(buffer) + # Public: Given a file path, this retrieves or creates a new {Buffer}. + # + # If the `filePath` already has a `buffer`, that value is used instead. Otherwise, + # `text` is used as the contents of the new buffer. + # + # filePath - A {String} representing a path. If `null`, an "Untitled" buffer is created. + # text - The {String} text to use as a buffer, if the file doesn't have any contents + # + # Returns the {Buffer}. bufferForPath: (filePath, text) -> if filePath? filePath = @resolve(filePath) @@ -166,6 +218,12 @@ class Project else @buildBuffer(null, text) + # Public: Given a file path, this sets its {Buffer}. + # + # filePath - A {String} representing a path + # text - The {String} text to use as a buffer + # + # Returns the {Buffer}. buildBuffer: (filePath, text) -> buffer = new Buffer(filePath, text) @buffers.push buffer @@ -175,6 +233,10 @@ class Project removeBuffer: (buffer) -> _.remove(@buffers, buffer) + # Public: Performs a search across all the files in the project. + # + # regex - A {RegExp} to search with + # iterator - A {Function} callback on each file found scan: (regex, iterator) -> bufferedData = "" state = 'readingPath' From e0e49367567efb62e24cef1f5d0a532334e7f794 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Thu, 11 Apr 2013 02:14:24 -0500 Subject: [PATCH 27/51] Update spec --- spec/app/atom-spec.coffee | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/spec/app/atom-spec.coffee b/spec/app/atom-spec.coffee index c9fec1901..f36d3392f 100644 --- a/spec/app/atom-spec.coffee +++ b/spec/app/atom-spec.coffee @@ -340,7 +340,10 @@ describe "the `atom` global", -> results = docRunner.argsForCall[0][1].split("\n") results.pop() - coverage = parseFloat _.last(results).match(/.+?%/) + errors = parseInt results.pop().match(/\d+/) + expect(errors).toBe 0 + + coverage = parseFloat results.pop().match(/.+?%/) expect(coverage).toBeGreaterThan 85 # stderr @@ -359,7 +362,10 @@ describe "the `atom` global", -> results = docRunner.argsForCall[0][1].split("\n") results.pop() - coverage = parseFloat _.last(results).match(/.+?%/) + errors = parseInt results.pop().match(/\d+/) + expect(errors).toBe 0 + + coverage = parseFloat results.pop().match(/.+?%/) expect(coverage).toBeGreaterThan 85 # stderr From bb8f5bb40c7ed4e9d560ccc0bff8cf65c1b48fd8 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Thu, 11 Apr 2013 02:29:48 -0500 Subject: [PATCH 28/51] Fix errors --- src/app/atom-theme.coffee | 5 +++++ src/app/config.coffee | 4 ++++ src/app/cursor.coffee | 4 ++-- src/app/display-buffer.coffee | 4 ++-- src/app/edit-session.coffee | 22 +++++++++++----------- src/app/editor.coffee | 22 +++++++++++----------- src/app/git.coffee | 2 +- src/app/line-map.coffee | 5 +++-- src/app/scroll-view.coffee | 7 +++++++ 9 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/app/atom-theme.coffee b/src/app/atom-theme.coffee index c679298a1..d0de2eaa0 100644 --- a/src/app/atom-theme.coffee +++ b/src/app/atom-theme.coffee @@ -2,12 +2,17 @@ fsUtils = require 'fs-utils' Theme = require 'theme' CSON = require 'cson' +# Internal: Represents a theme that Atom can use. module.exports = class AtomTheme extends Theme + # Internal: Given a path, this loads it as a stylesheet. + # + # stylesheetPath - A {String} to a stylesheet loadStylesheet: (stylesheetPath)-> @stylesheets[stylesheetPath] = window.loadStylesheet(stylesheetPath) + # Internal: Loads the stylesheets found in a `package.cson` file. load: -> if fsUtils.extension(@path) in ['.css', '.less'] @loadStylesheet(@path) diff --git a/src/app/config.coffee b/src/app/config.coffee index 79cb4d35e..dee2052a5 100644 --- a/src/app/config.coffee +++ b/src/app/config.coffee @@ -11,6 +11,10 @@ vendoredThemesDirPath = fsUtils.join(resourcePath, "vendor/themes") userThemesDirPath = fsUtils.join(configDirPath, "themes") userPackagesDirPath = fsUtils.join(configDirPath, "packages") +# Public: Handles all of Atom's configuration details. +# +# This includes loading and setting options, as well as reading from the +# user's configuration file. module.exports = class Config configDirPath: configDirPath diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index ddeda573b..56c0f117f 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -298,7 +298,7 @@ class Cursor # Public: Gets the word located under the cursor. # - # options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}. + # options - An object with properties based on {#getBeginningOfCurrentWordBufferPosition}. # # Returns a {String}. getCurrentWordBufferRange: (options={}) -> @@ -308,7 +308,7 @@ class Cursor # Public: Retrieves the range for the current line. # - # options - A hash with the same keys as {EditSession.bufferRangeForBufferRow} + # options - A hash with the same keys as {EditSession#bufferRangeForBufferRow} # # Returns a {Range}. getCurrentLineBufferRange: (options) -> diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index 84c0197fb..d123e791b 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -262,7 +262,7 @@ class DisplayBuffer # # bufferPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {LineMap#clipScreenPosition}. # # Returns a {Point}. screenPositionForBufferPosition: (position, options) -> @@ -271,7 +271,7 @@ class DisplayBuffer # # screenPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {LineMap#clipScreenPosition}. # # Returns a {Point}. bufferPositionForScreenPosition: (position, options) -> diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 55d8ac789..c51d5095e 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -10,7 +10,7 @@ Range = require 'range' _ = require 'underscore' fsUtils = require 'fs-utils' -# Public: `EditSession`s manage the states between file {Buffers}, and the project as a whole. +# Public: `EditSession`s manage the states between file {Buffer}s, and the project as a whole. module.exports = class EditSession registerDeserializer(this) @@ -168,7 +168,7 @@ class EditSession # Public: Retrieves that character used to indicate a tab. # - # If soft tabs are enabled, this is a space (`" "`) times the {.getTabLength} value. + # If soft tabs are enabled, this is a space (`" "`) times the {#getTabLength} value. # Otherwise, it's a tab (`\t`). # # Returns a {String}. @@ -294,7 +294,7 @@ class EditSession # # bufferPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {LineMap#clipScreenPosition}. # # Returns a {Point}. screenPositionForBufferPosition: (bufferPosition, options) -> @displayBuffer.screenPositionForBufferPosition(bufferPosition, options) @@ -303,7 +303,7 @@ class EditSession # # screenPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {LineMap#clipScreenPosition}. # # Returns a {Point}. bufferPositionForScreenPosition: (screenPosition, options) -> @displayBuffer.bufferPositionForScreenPosition(screenPosition, options) @@ -368,7 +368,7 @@ class EditSession # Public: Inserts text at the current cursor positions. # # text - A {String} representing the text to insert. - # options - A set of options equivalent to {Selection.insertText}. + # options - A set of options equivalent to {Selection#insertText}. insertText: (text, options={}) -> options.autoIndent ?= @shouldAutoIndent() @mutateSelectedText (selection) -> selection.insertText(text, options) @@ -394,7 +394,7 @@ class EditSession # Public: Indents the current line. # - # options - A set of options equivalent to {Selection.indent}. + # options - A set of options equivalent to {Selection#indent}. indent: (options={})-> options.autoIndent ?= @shouldAutoIndent() @mutateSelectedText (selection) -> selection.indent(options) @@ -437,7 +437,7 @@ class EditSession autoIndentSelectedRows: -> @mutateSelectedText (selection) -> selection.autoIndentSelectedRows() - # Given a buffer range, this converts all `\t` characters to the appopriate {.getTabText} value. + # Given a buffer range, this converts all `\t` characters to the appopriate {#getTabText} value. # # bufferRange - The {Range} to perform the replace in normalizeTabsInBufferRange: (bufferRange) -> @@ -469,7 +469,7 @@ class EditSession # Public: Pastes the text in the clipboard. # - # options - A set of options equivalent to {Selection.insertText}. + # options - A set of options equivalent to {Selection#insertText}. pasteText: (options={}) -> options.normalizeIndent ?= true options.autoIndent ?= @shouldAutoIndentPastedText() @@ -1051,7 +1051,7 @@ class EditSession # Public: Moves every cursor to a given screen position. # # position - An {Array} of two numbers: the screen row, and the screen column. - # options - An object with properties based on {Cursor.changePosition} + # options - An object with properties based on {Cursor#changePosition} # setCursorScreenPosition: (position, options) -> @moveCursors (cursor) -> cursor.setScreenPosition(position, options) @@ -1071,7 +1071,7 @@ class EditSession # Public: Moves every cursor to a given buffer position. # # position - An {Array} of two numbers: the buffer row, and the buffer column. - # options - An object with properties based on {Cursor.changePosition} + # options - An object with properties based on {Cursor#changePosition} # setCursorBufferPosition: (position, options) -> @moveCursors (cursor) -> cursor.setBufferPosition(position, options) @@ -1119,7 +1119,7 @@ class EditSession @getCursor().getCurrentParagraphBufferRange() # Public: Gets the word located under the cursor. # - # options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}. + # options - An object with properties based on {Cursor#getBeginningOfCurrentWordBufferPosition}. # # Returns a {String}. getWordUnderCursor: (options) -> diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 7b4c9fb55..c717dba0b 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -234,7 +234,7 @@ class Editor extends View # Public: Sets the cursor based on a given screen position. # # position - An {Array} of two numbers: the screen row, and the screen column. - # options - An object with properties based on {Cursor.changePosition}. + # options - An object with properties based on {Cursor#changePosition}. # setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options) # Public: Duplicates the current line. @@ -248,7 +248,7 @@ class Editor extends View # Public: Sets the cursor based on a given buffer position. # # position - An {Array} of two numbers: the buffer row, and the buffer column. - # options - An object with properties based on {Cursor.changePosition}. + # options - An object with properties based on {Cursor#changePosition}. # setCursorBufferPosition: (position, options) -> @activeEditSession.setCursorBufferPosition(position, options) # Public: Gets the current buffer position. @@ -258,7 +258,7 @@ class Editor extends View getCurrentParagraphBufferRange: -> @activeEditSession.getCurrentParagraphBufferRange() # Public: Gets the word located under the cursor. # - # options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}. + # options - An object with properties based on {Cursor#getBeginningOfCurrentWordBufferPosition}. # # Returns a {String}. getWordUnderCursor: (options) -> @activeEditSession.getWordUnderCursor(options) @@ -336,7 +336,7 @@ class Editor extends View # Public: Inserts text at the current cursor positions. # # text - A {String} representing the text to insert. - # options - A set of options equivalent to {Selection.insertText}. + # options - A set of options equivalent to {Selection#insertText}. insertText: (text, options) -> @activeEditSession.insertText(text, options) # Public: Inserts a new line at the current cursor positions. insertNewline: -> @activeEditSession.insertNewline() @@ -347,7 +347,7 @@ class Editor extends View insertNewlineAbove: -> @activeEditSession.insertNewlineAbove() # Public: Indents the current line. # - # options - A set of options equivalent to {Selection.indent}. + # options - A set of options equivalent to {Selection#indent}. indent: (options) -> @activeEditSession.indent(options) # Public: TODO autoIndent: (options) -> @activeEditSession.autoIndentSelectedRows() @@ -361,7 +361,7 @@ class Editor extends View copySelection: -> @activeEditSession.copySelectedText() # Public: Pastes the text in the clipboard. # - # options - A set of options equivalent to {Selection.insertText}. + # options - A set of options equivalent to {Selection#insertText}. paste: (options) -> @activeEditSession.pasteText(options) # Public: Undos the last {Buffer} change. undo: -> @activeEditSession.undo() @@ -433,7 +433,7 @@ class Editor extends View # # bufferPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {LineMap#clipScreenPosition}. # # Returns a {Point}. screenPositionForBufferPosition: (position, options) -> @activeEditSession.screenPositionForBufferPosition(position, options) @@ -442,7 +442,7 @@ class Editor extends View # # screenPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {LineMap#clipScreenPosition}. # # Returns a {Point}. bufferPositionForScreenPosition: (position, options) -> @activeEditSession.bufferPositionForScreenPosition(position, options) @@ -776,7 +776,7 @@ class Editor extends View # # bufferPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - A hash matching the options available to {.scrollToPixelPosition} + # options - A hash matching the options available to {#scrollToPixelPosition} scrollToBufferPosition: (bufferPosition, options) -> @scrollToPixelPosition(@pixelPositionForBufferPosition(bufferPosition), options) @@ -784,7 +784,7 @@ class Editor extends View # # screenPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - A hash matching the options available to {.scrollToPixelPosition} + # options - A hash matching the options available to {#scrollToPixelPosition} scrollToScreenPosition: (screenPosition, options) -> @scrollToPixelPosition(@pixelPositionForScreenPosition(screenPosition), options) @@ -792,7 +792,7 @@ class Editor extends View # # bufferPosition - An object that represents a pixel position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - A hash matching the options available to {.scrollVertically} + # options - A hash matching the options available to {#scrollVertically} scrollToPixelPosition: (pixelPosition, options) -> return unless @attached @scrollVertically(pixelPosition, options) diff --git a/src/app/git.coffee b/src/app/git.coffee index 02cafde74..7edcbaed1 100644 --- a/src/app/git.coffee +++ b/src/app/git.coffee @@ -158,7 +158,7 @@ class Git relativize: (path) -> @getRepo().relativize(path) - # Public: Retrieves a shortened version of {.getHead}. + # Public: Retrieves a shortened version of {#getHead}. # # This removes the leading segments of `refs/heads`, `refs/tags`, or `refs/remotes`. # It also shortenes the SHA-1 of a detached `HEAD` to 7 characters. diff --git a/src/app/line-map.coffee b/src/app/line-map.coffee index 992304d21..d5dc662ac 100644 --- a/src/app/line-map.coffee +++ b/src/app/line-map.coffee @@ -81,7 +81,7 @@ class LineMap # # bufferPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {#clipScreenPosition}. # # Returns a {Point}. screenPositionForBufferPosition: (bufferPosition, options={}) -> @@ -120,7 +120,7 @@ class LineMap # # screenPosition - An object that represents a buffer position. It can be either # an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point} - # options - The same options available to {LineMap.clipScreenPosition}. + # options - The same options available to {#clipScreenPosition}. # # Returns a {Point}. bufferPositionForScreenPosition: (screenPosition, options) -> @@ -138,6 +138,7 @@ class LineMap bufferRow += screenLine.bufferRows [bufferRow, screenLine] + # Public: Given a buffer range, this converts it into a screen position. # # bufferRange - The {Range} to convert diff --git a/src/app/scroll-view.coffee b/src/app/scroll-view.coffee index f89a5c5da..398dbca25 100644 --- a/src/app/scroll-view.coffee +++ b/src/app/scroll-view.coffee @@ -1,6 +1,13 @@ {View} = require 'space-pen' + +# Public: Represents a view that scrolls. +# +# This `View` subclass listens to events such as `page-up`, `page-down`, +# `move-to-top`, and `move-to-bottom`. module.exports = class ScrollView extends View + + # Internal: The constructor. initialize: -> @on 'core:page-up', => @pageUp() @on 'core:page-down', => @pageDown() From 7e5b6bf5c47b29d7f67e41b730247ff91346f15f Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Thu, 11 Apr 2013 21:11:12 -0500 Subject: [PATCH 29/51] Massive updates --- src/app/config.coffee | 4 ++++ src/app/cursor.coffee | 2 ++ src/app/edit-session.coffee | 6 ++++-- src/app/editor.coffee | 6 ++++-- src/app/git.coffee | 5 +++++ src/app/image-edit-session.coffee | 4 +++- src/app/language-mode.coffee | 6 +++++- src/app/pane-container.coffee | 1 + src/app/pane-row.coffee | 3 +++ src/app/project.coffee | 6 ++++++ src/app/range.coffee | 4 ++++ src/app/root-view.coffee | 6 +++++- src/app/select-list.coffee | 1 + src/app/text-buffer.coffee | 3 +++ 14 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/app/config.coffee b/src/app/config.coffee index dee2052a5..336b00f4f 100644 --- a/src/app/config.coffee +++ b/src/app/config.coffee @@ -25,6 +25,7 @@ class Config settings: null configFileHasErrors: null + # Internal: constructor: -> @defaultSettings = core: _.clone(require('root-view').configDefaults) @@ -33,6 +34,7 @@ class Config @configFilePath = fsUtils.resolve(configDirPath, 'config', ['json', 'cson']) @configFilePath ?= fsUtils.join(configDirPath, 'config.cson') + # Internal: initializeConfigDirectory: -> return if fsUtils.exists(@configDirPath) @@ -52,10 +54,12 @@ class Config fsUtils.write(configPath, fsUtils.read(path)) fsUtils.traverseTreeSync(bundledThemesDirPath, onThemeDirFile, (path) -> true) + # Internal: load: -> @initializeConfigDirectory() @loadUserConfig() + # Internal: loadUserConfig: -> if fsUtils.exists(@configFilePath) try diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 56c0f117f..bbf8895ca 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -12,6 +12,7 @@ class Cursor visible: true needsAutoscroll: null + # Internal: constructor: ({@editSession, @marker}) -> @updateVisibility() @editSession.observeMarker @marker, (e) => @@ -34,6 +35,7 @@ class Cursor @editSession.trigger 'cursor-moved', movedEvent @needsAutoscroll = true + # Internal: destroy: -> @destroyed = true @editSession.destroyMarker(@marker) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index c51d5095e..1770e3b5f 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -17,6 +17,7 @@ class EditSession @version: 1 + # Internal: @deserialize: (state) -> session = project.buildEditSessionForBuffer(Buffer.deserialize(state.buffer)) if !session? @@ -36,6 +37,7 @@ class EditSession softTabs: true softWrap: false + # Internal: constructor: ({@project, @buffer, tabLength, softTabs, @softWrap }) -> @softTabs = @buffer.usesSoftTabs() ? softTabs ? true @languageMode = new LanguageMode(this, @buffer.getExtension()) @@ -1051,7 +1053,7 @@ class EditSession # Public: Moves every cursor to a given screen position. # # position - An {Array} of two numbers: the screen row, and the screen column. - # options - An object with properties based on {Cursor#changePosition} + # options - An object with properties based on {Cursor#setScreenPosition} # setCursorScreenPosition: (position, options) -> @moveCursors (cursor) -> cursor.setScreenPosition(position, options) @@ -1071,7 +1073,7 @@ class EditSession # Public: Moves every cursor to a given buffer position. # # position - An {Array} of two numbers: the buffer row, and the buffer column. - # options - An object with properties based on {Cursor#changePosition} + # options - An object with properties based on {Cursor#setBufferPosition} # setCursorBufferPosition: (position, options) -> @moveCursors (cursor) -> cursor.setBufferPosition(position, options) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index c717dba0b..67164e833 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -26,6 +26,7 @@ class Editor extends View @nextEditorId: 1 + # Internal: Establishes the DOM for the editor. @content: (params) -> @div class: @classes(params), tabindex: -1, => @subview 'gutter', new Gutter @@ -37,6 +38,7 @@ class Editor extends View @div class: 'vertical-scrollbar', outlet: 'verticalScrollbar', => @div outlet: 'verticalScrollbarContent' + # Internal: Defines the classes available to the editor. @classes: ({mini} = {}) -> classes = ['editor'] classes.push 'mini' if mini @@ -234,7 +236,7 @@ class Editor extends View # Public: Sets the cursor based on a given screen position. # # position - An {Array} of two numbers: the screen row, and the screen column. - # options - An object with properties based on {Cursor#changePosition}. + # options - An object with properties based on {Cursor#setScreenPosition}. # setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options) # Public: Duplicates the current line. @@ -248,7 +250,7 @@ class Editor extends View # Public: Sets the cursor based on a given buffer position. # # position - An {Array} of two numbers: the buffer row, and the buffer column. - # options - An object with properties based on {Cursor#changePosition}. + # options - An object with properties based on {Cursor#setBufferPosition}. # setCursorBufferPosition: (position, options) -> @activeEditSession.setCursorBufferPosition(position, options) # Public: Gets the current buffer position. diff --git a/src/app/git.coffee b/src/app/git.coffee index 7edcbaed1..740901760 100644 --- a/src/app/git.coffee +++ b/src/app/git.coffee @@ -28,6 +28,11 @@ class Git upstream: null statusTask: null + # Internal: Creates a new `Git` object. + # + # path - The {String} representing the path to your git working directory + # options - A hash with the following keys: + # :refreshOnWindowFocus - If `true`, {#refreshIndex} and {#refreshStatus} are called on focus constructor: (path, options={}) -> @repo = GitUtils.open(path) unless @repo? diff --git a/src/app/image-edit-session.coffee b/src/app/image-edit-session.coffee index f0e25318a..32ab2c867 100644 --- a/src/app/image-edit-session.coffee +++ b/src/app/image-edit-session.coffee @@ -12,13 +12,15 @@ class ImageEditSession '.jpg' '.png' ], fsUtils.extension(path), true) >= 0 - + + # Internal: @deserialize: (state) -> if fsUtils.exists(state.path) project.buildEditSession(state.path) else console.warn "Could not build edit session for path '#{state.path}' because that file no longer exists" + # Internal: Establishes a new image viewer. constructor: (@path) -> serialize: -> diff --git a/src/app/language-mode.coffee b/src/app/language-mode.coffee index ac82579ed..870334aa3 100644 --- a/src/app/language-mode.coffee +++ b/src/app/language-mode.coffee @@ -12,13 +12,17 @@ class LanguageMode editSession = null currentGrammarScore: null + # Public: Sets up a `LanguageMode` for the given {EditSession}. + # + # editSession - The {EditSession} to associate with constructor: (@editSession) -> @buffer = @editSession.buffer @reloadGrammar() @subscribe syntax, 'grammar-added', (grammar) => newScore = grammar.getScore(@buffer.getPath(), @buffer.getText()) @setGrammar(grammar, newScore) if newScore > @currentGrammarScore - + + # Internal: destroy: -> @unsubscribe() diff --git a/src/app/pane-container.coffee b/src/app/pane-container.coffee index 8bcaa45fb..c0a0c4315 100644 --- a/src/app/pane-container.coffee +++ b/src/app/pane-container.coffee @@ -6,6 +6,7 @@ module.exports = class PaneContainer extends View registerDeserializer(this) + # Internal: @deserialize: ({root}) -> container = new PaneContainer container.append(deserialize(root)) if root diff --git a/src/app/pane-row.coffee b/src/app/pane-row.coffee index ce7a09f82..1db337994 100644 --- a/src/app/pane-row.coffee +++ b/src/app/pane-row.coffee @@ -7,6 +7,9 @@ class PaneRow extends PaneAxis @content: -> @div class: 'row' + # Public: Retrieves the pane class name. + # + # Returns a {String}. className: -> "PaneRow" diff --git a/src/app/project.coffee b/src/app/project.coffee index cf1f2a230..747ab3222 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -17,6 +17,7 @@ module.exports = class Project registerDeserializer(this) + # Internal: @deserialize: (state) -> new Project(state.path) @@ -27,15 +28,20 @@ class Project editSessions: null ignoredPathRegexes: null + # Public: Establishes a new project at a given path. + # + # path - The {String} name of the path constructor: (path) -> @setPath(path) @editSessions = [] @buffers = [] + # Internal: serialize: -> deserializer: 'Project' path: @getPath() + # Internal: destroy: -> editSession.destroy() for editSession in @getEditSessions() diff --git a/src/app/range.coffee b/src/app/range.coffee index 6847dd6da..1aac76c70 100644 --- a/src/app/range.coffee +++ b/src/app/range.coffee @@ -35,6 +35,10 @@ class Range pointB = new Point(point.row + rowDelta, point.column + columnDelta) new Range(pointA, pointB) + # Public: Creates a new `Range` object based on two {Point}s. + # + # pointA - The first {Point} (default: `0, 0`) + # pointB - The second {Point} (default: `0, 0`) constructor: (pointA = new Point(0, 0), pointB = new Point(0, 0)) -> pointA = Point.fromObject(pointA) pointB = Point.fromObject(pointB) diff --git a/src/app/root-view.coffee b/src/app/root-view.coffee index 6b4bf73bb..188f07f5d 100644 --- a/src/app/root-view.coffee +++ b/src/app/root-view.coffee @@ -23,16 +23,19 @@ class RootView extends View ignoredNames: [".git", ".svn", ".DS_Store"] disabledPackages: [] + # Internal: @content: ({panes}={}) -> @div id: 'root-view', => @div id: 'horizontal', outlet: 'horizontal', => @div id: 'vertical', outlet: 'vertical', => @subview 'panes', panes ? new PaneContainer - + + # Internal: @deserialize: ({ panes }) -> panes = deserialize(panes) if panes?.deserializer is 'PaneContainer' new RootView({panes}) + # Internal: initialize: -> @command 'toggle-dev-tools', => atom.toggleDevTools() @on 'focus', (e) => @handleFocus(e) @@ -69,6 +72,7 @@ class RootView extends View @command 'pane:reopen-closed-item', => @panes.reopenItem() + # Internal: serialize: -> version: RootView.version deserializer: 'RootView' diff --git a/src/app/select-list.coffee b/src/app/select-list.coffee index 9dbbd077a..e5ac69970 100644 --- a/src/app/select-list.coffee +++ b/src/app/select-list.coffee @@ -19,6 +19,7 @@ class SelectList extends View inputThrottle: 50 cancelling: false + # Internal: initialize: -> requireStylesheet 'select-list' diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index 8a8dc75b5..90f5b4ba1 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -29,6 +29,7 @@ class Buffer invalidMarkers: null refcount: 0 + # Internal: @deserialize: ({path, text}) -> project.bufferForPath(path, text) @@ -58,6 +59,7 @@ class Buffer @undoManager = new UndoManager(this) + # Internal: destroy: -> throw new Error("Destroying buffer twice with path '#{@getPath()}'") if @destroyed @file?.off() @@ -73,6 +75,7 @@ class Buffer @destroy() if @refcount <= 0 this + # Internal: serialize: -> deserializer: 'TextBuffer' path: @getPath() From 6963503d6f9e6ecd282319846631157767d67d65 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 14:23:43 -0500 Subject: [PATCH 30/51] Finish config --- src/app/config.coffee | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/app/config.coffee b/src/app/config.coffee index 336b00f4f..455901565 100644 --- a/src/app/config.coffee +++ b/src/app/config.coffee @@ -13,8 +13,8 @@ userPackagesDirPath = fsUtils.join(configDirPath, "packages") # Public: Handles all of Atom's configuration details. # -# This includes loading and setting options, as well as reading from the -# user's configuration file. +# This includes loading and setting default options, as well as reading from the +# user's configuration file. module.exports = class Config configDirPath: configDirPath @@ -70,15 +70,30 @@ class Config console.error "Failed to load user config '#{@configFilePath}'", e.message console.error e.stack + # Public: Retrieves the setting for the given key. + # + # keyPath - The {String} name of the key to retrieve + # + # Returns the value from Atom's default settings, the user's configuration file, + # or `null` if the key doesn't exist in either. get: (keyPath) -> _.valueForKeyPath(@settings, keyPath) ? _.valueForKeyPath(@defaultSettings, keyPath) + # Public: Sets the value for a configuration setting. + # + # This value is stored in Atom's internal configuration file. + # + # keyPath - The {String} name of the key + # value - The value of the setting + # + # Returns the `value`. set: (keyPath, value) -> _.setValueForKeyPath(@settings, keyPath, value) @update() value + # Internal: setDefaults: (keyPath, defaults) -> keys = keyPath.split('.') hash = @defaultSettings @@ -89,6 +104,13 @@ class Config _.extend hash, defaults @update() + # Public: Establishes an event listener for a given key. + # + # Whenever the value of the key is changed, a callback is fired. + # + # keyPath - The {String} name of the key to watch + # callback - The {Function} that fires when the. It is given a single argument, `value`, + # which is the new value of `keyPath`. observe: (keyPath, callback) -> value = @get(keyPath) previousValue = _.clone(value) @@ -103,11 +125,13 @@ class Config callback(value) subscription + # Internal: update: -> return if @configFileHasErrors @save() @trigger 'updated' + # Internal: save: -> CSON.writeObject(@configFilePath, @settings) From e412eb16afbd5c4232feae97f15b4a48f95a26c3 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 14:36:59 -0500 Subject: [PATCH 31/51] Add a proper output dir --- Rakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index 6f46f3294..cf59775a9 100644 --- a/Rakefile +++ b/Rakefile @@ -120,7 +120,7 @@ namespace :docs do namespace :app do desc "Builds the API docs in src/app" task :build do - system %{./biscotto src/app/} + system %{./biscotto -o docs/api src/app/} end desc "Lists the stats for API doc coverage in src/app" @@ -132,7 +132,7 @@ namespace :docs do namespace :packages do desc "Builds the API docs in src/packages" task :build do - system %{./biscotto src/packages/} + system %{./biscotto -o docs/api src/packages/} end desc "Lists the stats for API doc coverage in src/packages" From 0c5e38680dbce00231a156a5f530eb536bc9be59 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 14:37:21 -0500 Subject: [PATCH 32/51] Internalize a bunch of methods --- src/app/cursor-view.coffee | 1 + src/app/display-buffer-marker.coffee | 1 + src/app/display-buffer.coffee | 1 + src/app/edit-session.coffee | 2 ++ src/app/gutter.coffee | 6 ++++++ src/app/image-edit-session.coffee | 12 ++++++++++++ src/app/image-view.coffee | 3 +++ src/app/pane-column.coffee | 3 +++ src/app/pane-container.coffee | 3 +++ src/app/pane.coffee | 3 +++ src/app/range.coffee | 9 +++++++++ src/app/select-list.coffee | 2 ++ src/app/selection-view.coffee | 2 ++ src/app/syntax.coffee | 1 + src/app/tokenized-buffer.coffee | 6 ++++++ src/app/undo-manager.coffee | 1 + 16 files changed, 56 insertions(+) diff --git a/src/app/cursor-view.coffee b/src/app/cursor-view.coffee index 03fae93de..3cef15ba2 100644 --- a/src/app/cursor-view.coffee +++ b/src/app/cursor-view.coffee @@ -5,6 +5,7 @@ _ = require 'underscore' module.exports = class CursorView extends View + # Internal: @content: -> @pre class: 'cursor idle', => @raw ' ' diff --git a/src/app/display-buffer-marker.coffee b/src/app/display-buffer-marker.coffee index c8ed1648a..e794af009 100644 --- a/src/app/display-buffer-marker.coffee +++ b/src/app/display-buffer-marker.coffee @@ -9,6 +9,7 @@ class DisplayBufferMarker tailScreenPosition: null valid: true + # Internal: constructor: ({@id, @displayBuffer}) -> @buffer = @displayBuffer.buffer diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index d123e791b..b0166d3f2 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -19,6 +19,7 @@ class DisplayBuffer foldsById: null markers: null + # Internal: constructor: (@buffer, options={}) -> @id = @constructor.idCounter++ @languageMode = options.languageMode diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 1770e3b5f..99eb3621b 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -68,6 +68,8 @@ class EditSession # Public: Retrieves the filename of the open file. # + # This is `'untitled'` if the file is new and not saved to the disk. + # # Returns a {String}. getTitle: -> if path = @getPath() diff --git a/src/app/gutter.coffee b/src/app/gutter.coffee index 76bf22cad..9b16710e7 100644 --- a/src/app/gutter.coffee +++ b/src/app/gutter.coffee @@ -5,6 +5,8 @@ _ = require 'underscore' module.exports = class Gutter extends View + + # Internal: @content: -> @div class: 'gutter', => @div outlet: 'lineNumbers', class: 'line-numbers' @@ -22,9 +24,13 @@ class Gutter extends View @getEditor().on 'selection:changed', highlightLines @on 'mousedown', (e) => @handleMouseEvents(e) + # Public: Retrieves the containing {Editor}. + # + # Returns an {Editor}. getEditor: -> @parentView + # Internal: beforeRemove: -> $(document).off(".gutter-#{@getEditor().id}") diff --git a/src/app/image-edit-session.coffee b/src/app/image-edit-session.coffee index 32ab2c867..14607e84f 100644 --- a/src/app/image-edit-session.coffee +++ b/src/app/image-edit-session.coffee @@ -5,6 +5,11 @@ module.exports= class ImageEditSession registerDeserializer(this) + # Public: Identifies if a path can be opened by the image viewer. + # + # path - The {String} name of the path to check + # + # Returns a {Boolean}. @canOpen: (path) -> _.indexOf([ '.gif' @@ -23,13 +28,20 @@ class ImageEditSession # Internal: Establishes a new image viewer. constructor: (@path) -> + # Internal: serialize: -> deserializer: 'ImageEditSession' path: @path + # Internal: getViewClass: -> require 'image-view' + # Public: Retrieves the filename of the open file. + # + # This is `'untitled'` if the file is new and not saved to the disk. + # + # Returns a {String}. getTitle: -> if path = @getPath() fsUtils.base(path) diff --git a/src/app/image-view.coffee b/src/app/image-view.coffee index 0db56b20a..ff1e2cc99 100644 --- a/src/app/image-view.coffee +++ b/src/app/image-view.coffee @@ -4,10 +4,13 @@ $ = require 'jquery' module.exports = class ImageView extends ScrollView + + # Internal: @content: -> @div class: 'image-view', tabindex: -1, => @img outlet: 'image' + # Internal: initialize: (imageEditSession) -> super diff --git a/src/app/pane-column.coffee b/src/app/pane-column.coffee index 43ba40cbb..d795e0cb7 100644 --- a/src/app/pane-column.coffee +++ b/src/app/pane-column.coffee @@ -4,9 +4,12 @@ PaneAxis = require 'pane-axis' module.exports = class PaneColumn extends PaneAxis + + # Internal: @content: -> @div class: 'column' + # Internal: className: -> "PaneColumn" diff --git a/src/app/pane-container.coffee b/src/app/pane-container.coffee index c0a0c4315..06db6890d 100644 --- a/src/app/pane-container.coffee +++ b/src/app/pane-container.coffee @@ -13,12 +13,15 @@ class PaneContainer extends View container.removeEmptyPanes() container + # Internal: The DOM of the pane container. @content: -> @div id: 'panes' + # Internal: initialize: -> @destroyedItemStates = [] + # Internal: serialize: -> deserializer: 'PaneContainer' root: @getRoot()?.serialize() diff --git a/src/app/pane.coffee b/src/app/pane.coffee index 166fd7e90..56e550787 100644 --- a/src/app/pane.coffee +++ b/src/app/pane.coffee @@ -6,10 +6,13 @@ PaneColumn = require 'pane-column' module.exports = class Pane extends View + + # Internal: Defines the pane's DOM. @content: (wrappedView) -> @div class: 'pane', => @div class: 'item-views', outlet: 'itemViews' + # Internal: @deserialize: ({items, focused, activeItemUri}) -> deserializedItems = _.compact(items.map((item) -> deserialize(item))) pane = new Pane(deserializedItems...) diff --git a/src/app/range.coffee b/src/app/range.coffee index 1aac76c70..2b82cc3bd 100644 --- a/src/app/range.coffee +++ b/src/app/range.coffee @@ -98,6 +98,15 @@ class Range add: (point) -> new Range(@start.add(point), @end.add(point)) + # Public: Moves a `Range`. + # + # In other words, the starting and ending `row` values, and the starting and ending + # `column` values, are added to each other. + # + # startPoint - The {Point} to move the `Range`s `start` by + # endPoint - The {Point} to move the `Range`s `end` by + # + # Returns the new {Range}. translate: (startPoint, endPoint=startPoint) -> new Range(@start.translate(startPoint), @end.translate(endPoint)) diff --git a/src/app/select-list.coffee b/src/app/select-list.coffee index e5ac69970..30e42a894 100644 --- a/src/app/select-list.coffee +++ b/src/app/select-list.coffee @@ -5,6 +5,8 @@ fuzzyFilter = require 'fuzzy-filter' module.exports = class SelectList extends View + + # Internal: Establishes the DOM for the selection list. @content: -> @div class: @viewClass(), => @subview 'miniEditor', new Editor(mini: true) diff --git a/src/app/selection-view.coffee b/src/app/selection-view.coffee index 4b66e3d97..2adcf7627 100644 --- a/src/app/selection-view.coffee +++ b/src/app/selection-view.coffee @@ -4,6 +4,8 @@ Range = require 'range' module.exports = class SelectionView extends View + + # Internal: Establishes the DOM for the selection view. @content: -> @div class: 'selection' diff --git a/src/app/syntax.coffee b/src/app/syntax.coffee index 3aebccbb8..d952ab84f 100644 --- a/src/app/syntax.coffee +++ b/src/app/syntax.coffee @@ -10,6 +10,7 @@ module.exports = class Syntax registerDeserializer(this) + # Internal: @deserialize: ({grammarOverridesByPath}) -> syntax = new Syntax() syntax.grammarOverridesByPath = grammarOverridesByPath diff --git a/src/app/tokenized-buffer.coffee b/src/app/tokenized-buffer.coffee index f35c94680..d84973c59 100644 --- a/src/app/tokenized-buffer.coffee +++ b/src/app/tokenized-buffer.coffee @@ -156,6 +156,7 @@ class TokenizedBuffer token = @screenLines[position.row].tokenAtBufferColumn(position.column) token.scopes + # Internal: destroy: -> @buffer.off ".tokenized-buffer#{@id}" @@ -219,14 +220,19 @@ class TokenizedBuffer stop() position + # Public: Gets the row number of the last line. + # + # Returns a {Number}. 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 fc5b73e00..d8aaaa70b 100644 --- a/src/app/undo-manager.coffee +++ b/src/app/undo-manager.coffee @@ -7,6 +7,7 @@ class UndoManager redoHistory: null currentTransaction: null + # Internal: constructor: -> @clear() From b2637aae57254dee3143ec9cdb44d2b97217e69a Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 14:38:59 -0500 Subject: [PATCH 33/51] Don't add stats --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index af9371e4d..2279ee8a6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ tags /cef/ /sources.gypi /node/ +docs/api/missing.txt From 286e70cc5722f74b428f087cd4a4dd5834708ad2 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 15:17:11 -0500 Subject: [PATCH 34/51] Hella Editor updates --- src/app/cursor.coffee | 2 +- src/app/display-buffer.coffee | 9 +++ src/app/edit-session.coffee | 55 ++++++++++++++---- src/app/editor.coffee | 104 ++++++++++++++++++++++++++++++++-- src/app/line-map.coffee | 8 ++- src/app/text-buffer.coffee | 5 ++ 6 files changed, 167 insertions(+), 16 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index bbf8895ca..0c2be3f4f 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -318,7 +318,7 @@ class Cursor # Public: Retrieves the range for the current paragraph. # - # A paragraph is defined as a block of text surrounded by two empty lines. + # A paragraph is defined as a block of text surrounded by empty lines. # # Returns a {Range}. getCurrentParagraphBufferRange: -> diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index b0166d3f2..9855c53f6 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -62,6 +62,12 @@ class DisplayBuffer getLines: -> @lineMap.linesForScreenRows(0, @lineMap.lastScreenRow()) + # Public: Given a starting and ending row, this converts every row into a buffer position. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at (default: {#getLastRow}) + # + # Returns an {Array} of {Range}s. bufferRowsForScreenRows: (startRow, endRow) -> @lineMap.bufferRowsForScreenRows(startRow, endRow) @@ -253,6 +259,9 @@ class DisplayBuffer lineCount: -> @lineMap.screenLineCount() + # Public: Gets the number of the last row in the buffer. + # + # Returns a {Number}. getLastRow: -> @lineCount() - 1 diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 99eb3621b..134632519 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -90,6 +90,7 @@ class EditSession else 'untitled' + # Internal: destroy: -> return if @destroyed @destroyed = true @@ -102,6 +103,7 @@ class EditSession @trigger 'destroyed' @off() + # Internal: serialize: -> deserializer: 'EditSession' version: @constructor.version @@ -291,7 +293,11 @@ class EditSession lineLengthForBufferRow: (row) -> @buffer.lineLengthForRow(row) scanInBufferRange: (args...) -> @buffer.scanInRange(args...) backwardsScanInBufferRange: (args...) -> @buffer.backwardsScanInRange(args...) + # Public: Identifies if the {Buffer} is modified (and not saved). + # + # Returns a {Boolean}. isModified: -> @buffer.isModified() + # Internal: shouldPromptToSave: -> @isModified() and not @buffer.hasMultipleEditors() # Public: Given a buffer position, this converts it into a screen position. @@ -348,10 +354,16 @@ class EditSession # # Returns a {Number}. maxScreenLineLength: -> @displayBuffer.maxLineLength() - # Public: Gets the text in the last screen row. + # Public: Gets the number of the last row in the buffer. # - # Returns a {String}. + # Returns a {Number}. getLastScreenRow: -> @displayBuffer.getLastRow() + # Public: Given a starting and ending row, this converts every row into a buffer position. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at (default: {#getLastScreenRow}) + # + # Returns an {Array} of {Range}s. bufferRowsForScreenRows: (startRow, endRow) -> @displayBuffer.bufferRowsForScreenRows(startRow, endRow) scopesForBufferPosition: (bufferPosition) -> @displayBuffer.scopesForBufferPosition(bufferPosition) getCursorScopes: -> @getCursor().getScopes() @@ -739,6 +751,8 @@ class EditSession @setSelectedBufferRange(selection.translate([1]), preserveFolds: true) # Public: Duplicates the current line. + # + # If more than one cursor is present, only the most recently added one is considered. duplicateLine: -> return unless @getSelection().isEmpty() @@ -960,7 +974,7 @@ class EditSession @trigger 'selection-added', selection selection - # Public: Given a buffer range, adds a new selection for it. + # Public: Given a buffer range, this adds a new selection for it. # # bufferRange - A {Range} in the buffer # options - A hash of options @@ -971,9 +985,17 @@ class EditSession marker = @markBufferRange(bufferRange, options) @addSelection(marker, options) + # Public: Given a buffer range, this removes all previous selections and creates a new selection for it. + # + # bufferRange - A {Range} in the buffer + # options - A hash of options setSelectedBufferRange: (bufferRange, options) -> @setSelectedBufferRanges([bufferRange], options) + # Public: Given an array of buffer ranges, this removes all previous selections and creates new selections for them. + # + # bufferRanges - An {Array} of {Range}s in the buffer + # options - A hash of options setSelectedBufferRanges: (bufferRanges, options={}) -> throw new Error("Passed an empty array to setSelectedBufferRanges") unless bufferRanges.length @@ -1028,7 +1050,7 @@ class EditSession getLastSelection: -> _.last(@selections) - # Public: Gets all selections, ordered by position in the buffer. + # Public: Gets all selections, ordered by their position in the buffer. # # Returns an {Array} of {Selection}s. getSelectionsOrderedByBufferPosition: -> @@ -1080,27 +1102,29 @@ class EditSession setCursorBufferPosition: (position, options) -> @moveCursors (cursor) -> cursor.setBufferPosition(position, options) - # Public: Gets the current buffer position. + # Public: Gets the current buffer position of the cursor. # # Returns an {Array} of two numbers: the buffer row, and the buffer column. getCursorBufferPosition: -> @getCursor().getBufferPosition() - # Public: Gets the screen range of the last (most recently added) {Selection}. + # Public: Gets the screen range of the most recently added {Selection}. # # Returns a {Range}. getSelectedScreenRange: -> @getLastSelection().getScreenRange() - # Public: Gets the buffer range of the last (most recently added) {Selection}. + # Public: Gets the buffer range of the most recently added {Selection}. # # Returns a {Range}. getSelectedBufferRange: -> @getLastSelection().getBufferRange() - # Public: Gets the buffer range of the last {Selection} in the buffer. + # Public: Gets the buffer ranges of all the {Selection}s. # - # Returns a {Range}. + # This is ordered by their buffer position. + # + # Returns an {Array} of {Range}s. getSelectedBufferRanges: -> selection.getBufferRange() for selection in @getSelectionsOrderedByBufferPosition() @@ -1118,9 +1142,14 @@ class EditSession getTextInBufferRange: (range) -> @buffer.getTextInRange(range) + # Public: Retrieves the range for the current paragraph. + # + # A paragraph is defined as a block of text surrounded by empty lines. + # + # Returns a {Range}. getCurrentParagraphBufferRange: -> - @getCursor().getCurrentParagraphBufferRange() + # Public: Gets the word located under the cursor. # # options - An object with properties based on {Cursor#getBeginningOfCurrentWordBufferPosition}. @@ -1230,9 +1259,11 @@ class EditSession selectLine: -> @expandSelectionsForward (selection) => selection.selectLine() + # Public: Moves the current selection down one row. addSelectionBelow: -> @expandSelectionsForward (selection) => selection.addSelectionBelow() + # Public: Moves the current selection up one row. addSelectionAbove: -> @expandSelectionsBackward (selection) => selection.addSelectionAbove() @@ -1260,6 +1291,10 @@ class EditSession lowerCase: -> @replaceSelectedText selectWordIfEmpty:true, (text) => text.toLowerCase() + # Public: Joins the current line with the one below it. + # + # Multiple cursors are considered equally. If there's a selection in the editor, + # all the lines are joined together. joinLine: -> @mutateSelectedText (selection) -> selection.joinLine() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 67164e833..c58a49554 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -220,6 +220,7 @@ class Editor extends View moveCursorToEndOfWord: -> @activeEditSession.moveCursorToEndOfWord() # Public: Moves the cursor to the beginning of the next word. moveCursorToBeginningOfNextWord: -> @activeEditSession.moveCursorToBeginningOfNextWord() + # Public: Moves every cursor to the top of the buffer. moveCursorToTop: -> @activeEditSession.moveCursorToTop() # Public: Moves every cursor to the bottom of the buffer. moveCursorToBottom: -> @activeEditSession.moveCursorToBottom() @@ -240,8 +241,17 @@ class Editor extends View # setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options) # Public: Duplicates the current line. + # + # If more than one cursor is present, only the most recently added one is considered. duplicateLine: -> @activeEditSession.duplicateLine() + # Public: Joins the current line with the one below it. + # + # Multiple cursors are considered equally. If there's a selection in the editor, + # all the lines are joined together. joinLine: -> @activeEditSession.joinLine() + # Public: Gets the current screen position. + # + # Returns an {Array} of two numbers: the screen row, and the screen column. getCursorScreenPosition: -> @activeEditSession.getCursorScreenPosition() # Public: Gets the current screen row. # @@ -253,10 +263,15 @@ class Editor extends View # options - An object with properties based on {Cursor#setBufferPosition}. # setCursorBufferPosition: (position, options) -> @activeEditSession.setCursorBufferPosition(position, options) - # Public: Gets the current buffer position. + # Public: Gets the current buffer position of the cursor. # # Returns an {Array} of two numbers: the buffer row, and the buffer column. getCursorBufferPosition: -> @activeEditSession.getCursorBufferPosition() + # Public: Retrieves the range for the current paragraph. + # + # A paragraph is defined as a block of text surrounded by empty lines. + # + # Returns a {Range}. getCurrentParagraphBufferRange: -> @activeEditSession.getCurrentParagraphBufferRange() # Public: Gets the word located under the cursor. # @@ -264,19 +279,54 @@ class Editor extends View # # Returns a {String}. getWordUnderCursor: (options) -> @activeEditSession.getWordUnderCursor(options) - + # Public: Gets the selection at the specified index. + # + # index - The id {Number} of the selection + # + # Returns a {Selection}. getSelection: (index) -> @activeEditSession.getSelection(index) + # Public: Gets the last selection, _i.e._ the most recently added. + # + # Returns a {Selection}. getSelections: -> @activeEditSession.getSelections() + # Public: Gets all selections, ordered by their position in the buffer. + # + # Returns an {Array} of {Selection}s. getSelectionsOrderedByBufferPosition: -> @activeEditSession.getSelectionsOrderedByBufferPosition() + # Public: Gets the very last selection, as it's ordered in the buffer. + # + # Returns a {Selection}. getLastSelectionInBuffer: -> @activeEditSession.getLastSelectionInBuffer() # Public: Gets the currently selected text. # # Returns a {String}. getSelectedText: -> @activeEditSession.getSelectedText() + # Public: Gets the buffer ranges of all the {Selection}s. + # + # This is ordered by their buffer position. + # + # Returns an {Array} of {Range}s. getSelectedBufferRanges: -> @activeEditSession.getSelectedBufferRanges() + # Public: Gets the buffer range of the most recently added {Selection}. + # + # Returns a {Range}. getSelectedBufferRange: -> @activeEditSession.getSelectedBufferRange() - setSelectedBufferRange: (bufferRange, options) -> @activeEditSession.setSelectedBufferRange(bufferRange, options) + # Public: Given a buffer range, this removes all previous selections and creates a new selection for it. + # + # bufferRange - A {Range} in the buffer + # options - A hash of options + setSelectedBufferRange: (bufferRange, options) -> @activeEditSession.setSelectedBufferRange(bufferRange, options) + # Public: Given an array of buffer ranges, this removes all previous selections and creates new selections for them. + # + # bufferRanges - An {Array} of {Range}s in the buffer + # options - A hash of options setSelectedBufferRanges: (bufferRanges, options) -> @activeEditSession.setSelectedBufferRanges(bufferRanges, options) + # Public: Given a buffer range, this adds a new selection for it. + # + # bufferRange - A {Range} in the buffer + # options - A hash of options + # + # Returns the new {Selection}. addSelectionForBufferRange: (bufferRange, options) -> @activeEditSession.addSelectionForBufferRange(bufferRange, options) # Public: Selects the text one position right of the cursor. selectRight: -> @activeEditSession.selectRight() @@ -296,15 +346,23 @@ class Editor extends View selectToBeginningOfLine: -> @activeEditSession.selectToBeginningOfLine() # Public: Selects all the text from the current cursor position to the end of the line. selectToEndOfLine: -> @activeEditSession.selectToEndOfLine() + # Public: Moves the current selection down one row. addSelectionBelow: -> @activeEditSession.addSelectionBelow() + # Public: Moves the current selection up one row. addSelectionAbove: -> @activeEditSession.addSelectionAbove() + # Public: Selects all the text from the current cursor position to the beginning of the word. selectToBeginningOfWord: -> @activeEditSession.selectToBeginningOfWord() # Public: Selects all the text from the current cursor position to the end of the word. selectToEndOfWord: -> @activeEditSession.selectToEndOfWord() # Public: Selects all the text from the current cursor position to the beginning of the next word. selectToBeginningOfNextWord: -> @activeEditSession.selectToBeginningOfNextWord() + # Public: Selects the current word. selectWord: -> @activeEditSession.selectWord() + # Public: Selects the current line. selectLine: -> @activeEditSession.selectLine() + # Public: Selects the text from the current cursor position to a given position. + # + # position - An instance of {Point}, with a given `row` and `column`. selectToScreenPosition: (position) -> @activeEditSession.selectToScreenPosition(position) # Public: Transposes the current text selections. # @@ -342,6 +400,7 @@ class Editor extends View insertText: (text, options) -> @activeEditSession.insertText(text, options) # Public: Inserts a new line at the current cursor positions. insertNewline: -> @activeEditSession.insertNewline() + # Internal: consolidateSelections: (e) -> e.abortKeyBinding() unless @activeEditSession.consolidateSelections() # Public: Inserts a new line below the current cursor positions. insertNewlineBelow: -> @activeEditSession.insertNewlineBelow() @@ -462,9 +521,18 @@ class Editor extends View # # Returns a {Range}. bufferRangeForScreenRange: (range) -> @activeEditSession.bufferRangeForScreenRange(range) + # Public: Given a starting and ending row, this converts every row into a buffer position. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at (default: {#getLastScreenRow}) + # + # Returns an {Array} of {Range}s. bufferRowsForScreenRows: (startRow, endRow) -> @activeEditSession.bufferRowsForScreenRows(startRow, endRow) + # Public: Gets the number of the last row in the buffer. + # + # Returns a {Number}. getLastScreenRow: -> @activeEditSession.getLastScreenRow() - + # Internal: logCursorScope: -> console.log @activeEditSession.getCursorScopes() # Public: Emulates the "page down" key, where the last row of a buffer scrolls to become the first. @@ -544,6 +612,9 @@ class Editor extends View # # Returns a {String} of the combined lines. getTextInRange: (range) -> @getBuffer().getTextInRange(range) + # Public: Finds the last point in the current buffer. + # + # Returns a {Point} representing the last position. getEofPosition: -> @getBuffer().getEofPosition() # Public: Given a row, returns the line of text. # @@ -557,10 +628,18 @@ class Editor extends View # # Returns a {Number}. lineLengthForBufferRow: (row) -> @getBuffer().lineLengthForRow(row) + # Public: Given a buffer row, this retrieves the range for that line. + # + # row - A {Number} identifying the row + # options - A hash with one key, `includeNewline`, which specifies whether you + # want to include the trailing newline + # + # Returns a {Range}. rangeForBufferRow: (row) -> @getBuffer().rangeForRow(row) scanInBufferRange: (args...) -> @getBuffer().scanInRange(args...) backwardsScanInBufferRange: (args...) -> @getBuffer().backwardsScanInRange(args...) + # Internal: configure: -> @observeConfig 'editor.showLineNumbers', (showLineNumbers) => @gutter.setShowLineNumbers(showLineNumbers) @observeConfig 'editor.showInvisibles', (showInvisibles) => @setShowInvisibles(showInvisibles) @@ -954,6 +1033,9 @@ class Editor extends View splitDown: (items...) -> @getPane()?.splitDown(items...).activeView + # Public: Retrieve's the `Editor`'s pane. + # + # Returns a {Pane}. getPane: -> @parent('.item-views').parent('.pane').view() @@ -1258,15 +1340,27 @@ class Editor extends View @renderedLines.css('padding-bottom', paddingBottom) @gutter.lineNumbers.css('padding-bottom', paddingBottom) + # Public: Retrieves the number of the row that is visible and currently at the top of the editor. + # + # Returns a {Number}. getFirstVisibleScreenRow: -> Math.floor(@scrollTop() / @lineHeight) + # Public: Retrieves the number of the row that is visible and currently at the top of the editor. + # + # Returns a {Number}. getLastVisibleScreenRow: -> Math.max(0, Math.ceil((@scrollTop() + @scrollView.height()) / @lineHeight) - 1) + # Public: Given a row number, identifies if it is currently visible. + # + # row - A row {Number} to check + # + # Returns a {Boolean}. isScreenRowVisible: (row) -> @getFirstVisibleScreenRow() <= row <= @getLastVisibleScreenRow() + # Internal: handleScreenLinesChange: (change) -> @pendingChanges.push(change) @requestDisplayUpdate() @@ -1488,6 +1582,7 @@ class Editor extends View @on event, => callback(this, event) + # Internal: Replaces all the currently selected text. replaceSelectedText: (replaceFn) -> selection = @getSelection() return false if selection.isEmpty() @@ -1498,6 +1593,7 @@ class Editor extends View @insertText(text, select: true) true + # Public: Copies the current file path to the native clipboard. copyPathToPasteboard: -> path = @getPath() pasteboard.write(path) if path? diff --git a/src/app/line-map.coffee b/src/app/line-map.coffee index d5dc662ac..8815a5c34 100644 --- a/src/app/line-map.coffee +++ b/src/app/line-map.coffee @@ -31,7 +31,13 @@ class LineMap linesForScreenRows: (startRow, endRow) -> @screenLines[startRow..endRow] - + + # Public: Given a starting and ending row, this converts every row into a buffer position. + # + # startRow - The row {Number} to start at + # endRow - The row {Number} to end at (default: {#lastScreenRow}) + # + # Returns an {Array} of {Range}s. bufferRowsForScreenRows: (startRow, endRow=@lastScreenRow()) -> bufferRows = [] bufferRow = 0 diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index 90f5b4ba1..143e65b19 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -81,6 +81,11 @@ class Buffer path: @getPath() text: @getText() if @isModified() + # Public: Identifies if the buffer belongs to multiple editors. + # + # For example, if the {Editor} was split. + # + # Returns a {Boolean}. hasMultipleEditors: -> @refcount > 1 # Internal: From f3b7874007e2f46439345cad1781f3e99a98fac8 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 15:54:56 -0500 Subject: [PATCH 35/51] Get a good chunk of Selection} --- src/app/buffer-marker.coffee | 5 +++ src/app/cursor.coffee | 2 + src/app/edit-session.coffee | 16 ++++--- src/app/selection.coffee | 86 ++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 6 deletions(-) diff --git a/src/app/buffer-marker.coffee b/src/app/buffer-marker.coffee index ebc843546..6aa013e01 100644 --- a/src/app/buffer-marker.coffee +++ b/src/app/buffer-marker.coffee @@ -24,6 +24,11 @@ class BufferMarker @setTailPosition(range.start) unless options.noTail @setHeadPosition(range.end) + # 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}. + # + # Returns a {Boolean}. isReversed: -> @tailPosition? and @headPosition.isLessThan(@tailPosition) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 0c2be3f4f..3f5785fbc 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -4,6 +4,8 @@ EventEmitter = require 'event-emitter' _ = require 'underscore' # Public: The `Cursor` class represents the little blinking line identifying where text can be inserted. +# +# Cursors have some metadata attached in the form of a {BufferMarker}. module.exports = class Cursor screenPosition: null diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 134632519..5369a1e34 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -381,10 +381,10 @@ class EditSession shouldAutoIndentPastedText: -> config.get("editor.autoIndentOnPaste") - # Public: Inserts text at the current cursor positions. + # Public: Inserts text at the current cursor positions # # text - A {String} representing the text to insert. - # options - A set of options equivalent to {Selection#insertText}. + # options - A set of options equivalent to {Selection#insertText} insertText: (text, options={}) -> options.autoIndent ?= @shouldAutoIndent() @mutateSelectedText (selection) -> selection.insertText(text, options) @@ -427,7 +427,7 @@ class EditSession backspaceToBeginningOfLine: -> @mutateSelectedText (selection) -> selection.backspaceToBeginningOfLine() - # Public: Performs a delete, removing the character found behind the cursor position. + # Public: Performs a delete, removing the character found ahead of the cursor position. delete: -> @mutateSelectedText (selection) -> selection.delete() @@ -435,7 +435,7 @@ class EditSession deleteToEndOfWord: -> @mutateSelectedText (selection) -> selection.deleteToEndOfWord() - # Public: Performs a delete to the end of the current line, removing characters found there. + # Public: Deletes the entire line. deleteLine: -> @mutateSelectedText (selection) -> selection.deleteLine() @@ -890,7 +890,11 @@ class EditSession clearMarkerTail: (args...) -> @displayBuffer.clearMarkerTail(args...) - # Internal: + # Public: Identifies if markers are reversed, that is, they are highlighting "up." + # + # args - {String}s specifying the id of a {BufferMarker} + # + # Returns a {Boolean}. isMarkerReversed: (args...) -> @displayBuffer.isMarkerReversed(args...) @@ -1211,7 +1215,7 @@ class EditSession fn(cursor) for cursor in @getCursors() @mergeCursors() - # Public: Selects the text from the current cursor position to a given position. + # Public: Selects the text from the current cursor position to a given screen position. # # position - An instance of {Point}, with a given `row` and `column`. selectToScreenPosition: (position) -> diff --git a/src/app/selection.coffee b/src/app/selection.coffee index c3f91eb69..8b12d66ac 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -2,6 +2,7 @@ Range = require 'range' EventEmitter = require 'event-emitter' _ = require 'underscore' +# Public: Represents a selection in the {EditSession}. module.exports = class Selection cursor: null @@ -12,6 +13,7 @@ class Selection wordwise: false needsAutoscroll: null + # Internal: constructor: ({@cursor, @marker, @editSession, @goalBufferRange}) -> @cursor.selection = this @editSession.observeMarker @marker, => @screenRangeChanged() @@ -19,6 +21,7 @@ class Selection @cursor = null @destroy() + # Internal: destroy: -> return if @destroyed @destroyed = true @@ -26,33 +29,60 @@ class Selection @trigger 'destroyed' unless @editSession.destroyed @cursor?.destroy() + # Internal: finalize: -> @initialScreenRange = null unless @initialScreenRange?.isEqual(@getScreenRange()) if @isEmpty() @wordwise = false @linewise = false + # Public: Identifies if the selection is highlighting anything. + # + # Returns a {Boolean}. isEmpty: -> @getBufferRange().isEmpty() + # Public: Identifies if the selection is reversed, that is, it is highlighting "up." + # + # Returns a {Boolean}. isReversed: -> @editSession.isMarkerReversed(@marker) + # Public: Identifies if the selection is a single line. + # + # Returns a {Boolean}. isSingleScreenLine: -> @getScreenRange().isSingleLine() + # Internal: clearAutoscroll: -> @needsAutoscroll = null + # Public: Retrieves the screen range for the selection. + # + # Returns a {Range}. getScreenRange: -> @editSession.getMarkerScreenRange(@marker) + # Public: Modifies the screen range for the selection. + # + # screenRange - The new {Range} to select + # options - A hash of options matching those found in {#setBufferRange} setScreenRange: (screenRange, options) -> @setBufferRange(@editSession.bufferRangeForScreenRange(screenRange), options) + # Public: Retrieves the buffer range for the selection. + # + # Returns a {Range}. getBufferRange: -> @editSession.getMarkerBufferRange(@marker) + # Public: Modifies the buffer range for the selection. + # + # screenRange - The new {Range} to select + # options - A hash of options with the following keys: + # :preserveFolds - if `true`, the fold settings are preserved after the selection moves + # :autoscroll - if `true`, the {EditSession} scrolls to the new selection setBufferRange: (bufferRange, options={}) -> bufferRange = Range.fromObject(bufferRange) @needsAutoscroll = options.autoscroll @@ -62,6 +92,9 @@ class Selection @cursor.needsAutoscroll = false if options.autoscroll? @editSession.setMarkerBufferRange(@marker, bufferRange, options) + # Public: Retrieves the starting and ending buffer rows the selection is highlighting. + # + # Returns an {Array} of two {Number}s: the starting row, and the ending row. getBufferRowRange: -> range = @getBufferRange() start = range.start.row @@ -69,16 +102,24 @@ class Selection end = Math.max(start, end - 1) if range.end.column == 0 [start, end] + # Internal: screenRangeChanged: -> screenRange = @getScreenRange() @trigger 'screen-range-changed', screenRange + # Public: Retrieves the text in the selection. + # + # Returns a {String}. getText: -> @editSession.buffer.getTextInRange(@getBufferRange()) + # Public: Clears the selection, moving the marker to move to the head. clear: -> @editSession.clearMarkerTail(@marker) + # Public: Modifies the selection to mark the current word. + # + # Returns a {Range}. selectWord: -> options = {} options.wordRegex = /[\t ]*/ if @cursor.isSurroundedByWhitespace() @@ -90,6 +131,9 @@ class Selection expandOverWord: -> @setBufferRange(@getBufferRange().union(@cursor.getCurrentWordBufferRange())) + # Public: Selects an entire line in the {Buffer}. + # + # row - The line {Number} to select (default: the row of the cursor) selectLine: (row=@cursor.getBufferPosition().row) -> range = @editSession.bufferRangeForBufferRow(row, includeNewline: true) @setBufferRange(range) @@ -101,6 +145,9 @@ class Selection range = @getBufferRange().union(@cursor.getCurrentLineBufferRange(includeNewline: true)) @setBufferRange(range) + # Public: Selects the text from the current cursor position to a given screen position. + # + # position - An instance of {Point}, with a given `row` and `column`. selectToScreenPosition: (position) -> @modifySelection => if @initialScreenRange @@ -116,45 +163,61 @@ class Selection else if @wordwise @expandOverWord() + # Public: Selects the text from the current cursor position to a given buffer position. + # + # position - An instance of {Point}, with a given `row` and `column`. selectToBufferPosition: (position) -> @modifySelection => @cursor.setBufferPosition(position) + # Public: Selects the text one position right of the cursor. selectRight: -> @modifySelection => @cursor.moveRight() + # Public: Selects the text one position left of the cursor. selectLeft: -> @modifySelection => @cursor.moveLeft() + # Public: Selects all the text one position above the cursor. selectUp: -> @modifySelection => @cursor.moveUp() + # Public: Selects all the text one position below the cursor. selectDown: -> @modifySelection => @cursor.moveDown() + # Public: Selects all the text from the current cursor position to the top of the buffer. selectToTop: -> @modifySelection => @cursor.moveToTop() + # Public: Selects all the text from the current cursor position to the bottom of the buffer. selectToBottom: -> @modifySelection => @cursor.moveToBottom() + # Public: Selects all the text in the buffer. selectAll: -> @setBufferRange(@editSession.buffer.getRange(), autoscroll: false) + # Public: Selects all the text from the current cursor position to the beginning of the line. selectToBeginningOfLine: -> @modifySelection => @cursor.moveToBeginningOfLine() + # Public: Selects all the text from the current cursor position to the end of the line. selectToEndOfLine: -> @modifySelection => @cursor.moveToEndOfLine() + # Public: Selects all the text from the current cursor position to the beginning of the word. selectToBeginningOfWord: -> @modifySelection => @cursor.moveToBeginningOfWord() + # Public: Selects all the text from the current cursor position to the end of the word. selectToEndOfWord: -> @modifySelection => @cursor.moveToEndOfWord() + # Public: Selects all the text from the current cursor position to the beginning of the next word. selectToBeginningOfNextWord: -> @modifySelection => @cursor.moveToBeginningOfNextWord() + # Public: Moves the selection down one row. addSelectionBelow: -> range = (@goalBufferRange ? @getBufferRange()).copy() nextRow = range.end.row + 1 @@ -172,6 +235,7 @@ class Selection @editSession.addSelectionForBufferRange(range, goalBufferRange: range, suppressMerge: true) break + # Public: Moves the selection up one row. addSelectionAbove: -> range = (@goalBufferRange ? @getBufferRange()).copy() previousRow = range.end.row - 1 @@ -189,6 +253,13 @@ class Selection @editSession.addSelectionForBufferRange(range, goalBufferRange: range, suppressMerge: true) break + # Public: Replaces text at the current selection. + # + # text - A {String} representing the text to add + # options - A hash containing the following options: + # :normalizeIndent - TODO + # :select - if `true`, selects the newly added text + # :autoIndent - if `true`, indents the newly added text appropriately insertText: (text, options={}) -> oldBufferRange = @getBufferRange() @editSession.destroyFoldsContainingBufferRow(oldBufferRange.end.row) @@ -210,6 +281,10 @@ class Selection newBufferRange + # Public: Indents the selection. + # + # options - A hash with one key, `autoIndent`. If `true`, the indentation is + # performed appropriately. Otherwise, {EditSession#getTabText} is used indent: ({ autoIndent }={})-> { row, column } = @cursor.getBufferPosition() @@ -225,6 +300,7 @@ class Selection else @indentSelectedRows() + # Public: If the selection spans multiple rows, indents all of them. indentSelectedRows: -> [start, end] = @getBufferRowRange() for row in [start..end] @@ -270,6 +346,7 @@ class Selection desiredIndentString = @editSession.buildIndentString(desiredIndentLevel) line.replace(/^[\t ]*/, desiredIndentString) + # Public: Performs a backspace, removing the character found behind the selection. backspace: -> if @isEmpty() and not @editSession.isFoldedAtScreenRow(@cursor.getScreenRow()) if @cursor.isAtBeginningOfLine() and @editSession.isFoldedAtScreenRow(@cursor.getScreenRow() - 1) @@ -279,10 +356,12 @@ class Selection @deleteSelectedText() + # Public: Performs a backspace to the beginning of the current word, removing characters found there. backspaceToBeginningOfWord: -> @selectToBeginningOfWord() if @isEmpty() @deleteSelectedText() + # Public: Performs a backspace to the beginning of the current line, removing characters found there. backspaceToBeginningOfLine: -> if @isEmpty() and @cursor.isAtBeginningOfLine() @selectLeft() @@ -290,6 +369,7 @@ class Selection @selectToBeginningOfLine() @deleteSelectedText() + # Public: Performs a delete, removing the character found ahead of the cursor position. delete: -> if @isEmpty() if @cursor.isAtEndOfLine() and fold = @editSession.largestFoldStartingAtScreenRow(@cursor.getScreenRow() + 1) @@ -298,10 +378,12 @@ class Selection @selectRight() @deleteSelectedText() + # Public: Performs a delete to the end of the current word, removing characters found there. deleteToEndOfWord: -> @selectToEndOfWord() if @isEmpty() @deleteSelectedText() + # Public: Deletes the selected text. deleteSelectedText: -> bufferRange = @getBufferRange() if fold = @editSession.largestFoldContainingBufferRow(bufferRange.end.row) @@ -311,6 +393,7 @@ class Selection @editSession.buffer.delete(bufferRange) unless bufferRange.isEmpty() @cursor?.setBufferPosition(bufferRange.start) + # Public: Deletes the line. deleteLine: -> if @isEmpty() start = @cursor.getScreenRow() @@ -327,6 +410,9 @@ class Selection end-- @editSession.buffer.deleteRows(start, end) + # Public: Joins the current line with the one below it. + # + # If there selection spans more than one line, all the lines are joined together. joinLine: -> selectedRange = @getBufferRange() if selectedRange.isEmpty() From 37b3784129a99098bd2bba578a4bdefada19905c Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 21:10:57 -0500 Subject: [PATCH 36/51] Finish Selections, add Fold --- src/app/fold.coffee | 27 +++++++++++++++++++++++++++ src/app/selection.coffee | 14 ++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/app/fold.coffee b/src/app/fold.coffee index 50e5d34ba..93fe276d3 100644 --- a/src/app/fold.coffee +++ b/src/app/fold.coffee @@ -1,6 +1,10 @@ Range = require 'range' Point = require 'point' +# Public: Represents a fold in the {Gutter}. +# +# Folds hide away text from the screen. They're the primary reason +# that screen ranges and buffer ranges vary. module.exports = class Fold @idCounter: 1 @@ -9,15 +13,23 @@ class Fold startRow: null endRow: null + # Internal: constructor: (@displayBuffer, @startRow, @endRow) -> @id = @constructor.idCounter++ + # Internal: destroy: -> @displayBuffer.destroyFold(this) + # Internal: inspect: -> "Fold(#{@startRow}, #{@endRow})" + # Public: Retrieves the buffer row range that a fold occupies. + # + # includeNewline - A {Boolean} which, if `true`, includes the trailing newline + # + # Returns a {Range}. getBufferRange: ({includeNewline}={}) -> if includeNewline end = [@endRow + 1, 0] @@ -26,9 +38,13 @@ class Fold new Range([@startRow, 0], end) + # Public: Retrieves the number of buffer rows a fold occupies. + # + # Returns a {Number}. getBufferRowCount: -> @endRow - @startRow + 1 + # Internal: handleBufferChange: (event) -> oldStartRow = @startRow @@ -43,12 +59,23 @@ class Fold @displayBuffer.unregisterFold(oldStartRow, this) @displayBuffer.registerFold(this) + # Public: Identifies if a {Range} occurs within a fold. + # + # range - A {Range} to check + # + # Returns a {Boolean}. isContainedByRange: (range) -> range.start.row <= @startRow and @endRow <= range.end.row + # Public: Identifies if a fold is nested within a fold. + # + # fold - A {Fold} to check + # + # Returns a {Boolean}. isContainedByFold: (fold) -> @isContainedByRange(fold.getBufferRange()) + # Internal: getRowDelta: (event, row) -> { newRange, oldRange } = event diff --git a/src/app/selection.coffee b/src/app/selection.coffee index 8b12d66ac..f334634a2 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -492,12 +492,26 @@ class Selection placeTail: -> @editSession.placeMarkerTail(@marker) + # Public: Identifies if a selection intersects with a given buffer range. + # + # bufferRange - A {Range} to check against + # + # Returns a {Boolean}. intersectsBufferRange: (bufferRange) -> @getBufferRange().intersectsWith(bufferRange) + # Public: Identifies if a selection intersects with another selection. + # + # otherSelection - A `Selection` to check against + # + # Returns a {Boolean}. intersectsWith: (otherSelection) -> @getBufferRange().intersectsWith(otherSelection.getBufferRange()) + # Public: Merges two selections together. + # + # otherSelection - A `Selection` to merge with + # options - A hash of options matching those found in {#setBufferRange} merge: (otherSelection, options) -> @setBufferRange(@getBufferRange().union(otherSelection.getBufferRange()), options) if @goalBufferRange and otherSelection.goalBufferRange From 8bd02358d22ad03ff976a7b534ea1c07840bc252 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Fri, 12 Apr 2013 22:35:54 -0500 Subject: [PATCH 37/51] Should I regret a lack of better commit messages? --- src/app/cursor.coffee | 3 ++ src/app/display-buffer.coffee | 38 +++++++++++++++++++++++-- src/app/edit-session.coffee | 29 ++++++++++++++++++- src/app/editor.coffee | 17 ++++++++++++ src/app/fold.coffee | 6 ++-- src/app/gutter.coffee | 15 +++++++++- src/app/image-edit-session.coffee | 14 ++++++++++ src/app/image-view.coffee | 19 +++++++++++++ src/app/keymap.coffee | 40 +++++++++++++++++++++++---- src/app/language-mode.coffee | 2 ++ src/app/line-map.coffee | 14 +++++++++- src/app/pane-axis.coffee | 4 ++- src/app/project.coffee | 4 +-- src/app/root-view.coffee | 46 ++++++++++++++++++++++++++++++- src/app/selection.coffee | 13 +++++++++ src/app/syntax.coffee | 2 ++ src/app/text-buffer.coffee | 15 ++++++++++ src/app/tokenized-buffer.coffee | 7 +++++ src/app/window.coffee | 5 ++-- 19 files changed, 273 insertions(+), 20 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 3f5785fbc..985ac2ebc 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -364,6 +364,9 @@ class Cursor isAtEndOfLine: -> @getBufferPosition().isEqual(@getCurrentLineBufferRange().end) + # Public: Retrieves the grammar's token scopes for the line. + # + # Returns an {Array} of {String}s. getScopes: -> @editSession.scopesForBufferPosition(@getBufferPosition()) diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index 9855c53f6..9a420b0f2 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -34,6 +34,7 @@ class DisplayBuffer setVisible: (visible) -> @tokenizedBuffer.setVisible(visible) + # Internal: buildLineMap: -> @lineMap = new LineMap @lineMap.insertAtScreenRow 0, @buildLinesForBufferRows(0, @buffer.getLastRow()) @@ -45,6 +46,9 @@ class DisplayBuffer @trigger 'changed', eventProperties @resumeMarkerObservers() + # Public: Defines the limit at which the buffer begins to soft wrap text. + # + # softWrapColumn - A {Number} defining the soft wrap limit. setSoftWrapColumn: (@softWrapColumn) -> start = 0 end = @getLastRow() @@ -52,13 +56,27 @@ class DisplayBuffer screenDelta = @getLastRow() - end bufferDelta = 0 @triggerChanged({ start, end, screenDelta, bufferDelta }) - + + # Public: Gets the line for the given screen row. + # + # screenRow - A {Number} indicating the screen row. + # + # Returns a {String}. lineForRow: (row) -> @lineMap.lineForScreenRow(row) + # Public: Gets the lines for the given screen row boundaries. + # + # startRow - A {Number} indicating the beginning screen row. + # endRow - A {Number} indicating the ending screen row. + # + # Returns an {Array} of {String}s. linesForRows: (startRow, endRow) -> @lineMap.linesForScreenRows(startRow, endRow) + # Public: Gets the lines in the buffer. + # + # Returns an {Array} of {String}s. getLines: -> @lineMap.linesForScreenRows(0, @lineMap.lastScreenRow()) @@ -123,6 +141,8 @@ class DisplayBuffer # # startRow - The row {Number} to start folding at # endRow - The row {Number} to end the fold + # + # Returns the new {Fold}. createFold: (startRow, endRow) -> return fold if fold = @foldFor(startRow, endRow) fold = new Fold(this, startRow, endRow) @@ -256,6 +276,9 @@ class DisplayBuffer bufferRangeForScreenRange: (screenRange) -> @lineMap.bufferRangeForScreenRange(screenRange) + # Public: Gets the number of lines in the buffer. + # + # Returns a {Number}. lineCount: -> @lineMap.screenLineCount() @@ -265,6 +288,9 @@ class DisplayBuffer getLastRow: -> @lineCount() - 1 + # Public: Gets the length of the longest screen line. + # + # Returns a {Number}. maxLineLength: -> @lineMap.maxScreenLineLength @@ -286,7 +312,12 @@ class DisplayBuffer # Returns a {Point}. bufferPositionForScreenPosition: (position, options) -> @lineMap.bufferPositionForScreenPosition(position, options) - + + # Public: Retrieves the grammar's token scopes for a buffer position. + # + # bufferPosition - A {Point} in the {Buffer} + # + # Returns an {Array} of {String}s. scopesForBufferPosition: (bufferPosition) -> @tokenizedBuffer.scopesForPosition(bufferPosition) @@ -490,13 +521,16 @@ class DisplayBuffer for marker in @getMarkers() marker.notifyObservers(bufferChanged: false) + # Internal: destroy: -> @tokenizedBuffer.destroy() @buffer.off 'markers-updated', @handleMarkersUpdated + # Internal: logLines: (start, end) -> @lineMap.logLines(start, end) + # Internal: getDebugSnapshot: -> lines = ["Display Buffer:"] for screenLine, row in @lineMap.linesForScreenRows(0, @getLastRow()) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 5369a1e34..d19bca65d 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -10,7 +10,7 @@ Range = require 'range' _ = require 'underscore' fsUtils = require 'fs-utils' -# Public: `EditSession`s manage the states between file {Buffer}s, and the project as a whole. +# Public: An `EditSession` manages the states between {Editor}s, {Buffer}s, and the project as a whole. module.exports = class EditSession registerDeserializer(this) @@ -250,6 +250,9 @@ class EditSession # # Returns a {String}. getBuffer: -> @buffer + # Public: Retrieves the current buffer's URI. + # + # Returns a {String}. getUri: -> @getPath() # Public: Given a buffer row, identifies if it is blank. # @@ -291,7 +294,17 @@ class EditSession # # Returns a {Number}. lineLengthForBufferRow: (row) -> @buffer.lineLengthForRow(row) + # Public: Scans for text in the buffer, calling a function on each match. + # + # regex - A {RegExp} representing the text to find + # range - A {Range} in the buffer to search within + # iterator - A {Function} that's called on each match scanInBufferRange: (args...) -> @buffer.scanInRange(args...) + # Public: Scans for text in the buffer _backwards_, calling a function on each match. + # + # regex - A {RegExp} representing the text to find + # range - A {Range} in the buffer to search within + # iterator - A {Function} that's called on each match backwardsScanInBufferRange: (args...) -> @buffer.backwardsScanInRange(args...) # Public: Identifies if the {Buffer} is modified (and not saved). # @@ -365,8 +378,17 @@ class EditSession # # Returns an {Array} of {Range}s. bufferRowsForScreenRows: (startRow, endRow) -> @displayBuffer.bufferRowsForScreenRows(startRow, endRow) + # Public: Retrieves the grammar's token scopes for a buffer position. + # + # bufferPosition - A {Point} in the {Buffer} + # + # Returns an {Array} of {String}s. scopesForBufferPosition: (bufferPosition) -> @displayBuffer.scopesForBufferPosition(bufferPosition) + # Public: Retrieves the grammar's token scopes for the line with the most recently added cursor. + # + # Returns an {Array} of {String}s. getCursorScopes: -> @getCursor().getScopes() + # Internal: logScreenLines: (start, end) -> @displayBuffer.logLines(start, end) # Public: Determines whether the {Editor} will auto indent rows. @@ -565,6 +587,8 @@ class EditSession # # startRow - The row {Number} to start folding at # endRow - The row {Number} to end the fold + # + # Returns the new {Fold}. createFold: (startRow, endRow) -> @displayBuffer.createFold(startRow, endRow) @@ -675,6 +699,8 @@ class EditSession # # startRow - The row {Number} to start at # endRow - The row {Number} to end at + # + # Returns an {Array} of the commented {Ranges}. toggleLineCommentsForBufferRows: (start, end) -> @languageMode.toggleLineCommentsForBufferRows(start, end) @@ -1334,6 +1360,7 @@ class EditSession markersForBufferPosition: (bufferPosition) -> @buffer.markersForPosition(bufferPosition) + # Internal: mergeCursors: -> positions = [] for cursor in @getCursors() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index c58a49554..7092fddf0 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -431,6 +431,12 @@ class Editor extends View 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 + # endRow - The row {Number} to end the fold + # + # Returns the new {Fold}. createFold: (startRow, endRow) -> @activeEditSession.createFold(startRow, endRow) # Public: Folds the current row. foldCurrentRow: -> @activeEditSession.foldCurrentRow() @@ -636,7 +642,17 @@ class Editor extends View # # Returns a {Range}. rangeForBufferRow: (row) -> @getBuffer().rangeForRow(row) + # Public: Scans for text in the buffer, calling a function on each match. + # + # regex - A {RegExp} representing the text to find + # range - A {Range} in the buffer to search within + # iterator - A {Function} that's called on each match scanInBufferRange: (args...) -> @getBuffer().scanInRange(args...) + # Public: Scans for text in the buffer _backwards_, calling a function on each match. + # + # regex - A {RegExp} representing the text to find + # range - A {Range} in the buffer to search within + # iterator - A {Function} that's called on each match backwardsScanInBufferRange: (args...) -> @getBuffer().backwardsScanInRange(args...) # Internal: @@ -1090,6 +1106,7 @@ class Editor extends View appendToLinesView: (view) -> @overlayer.append(view) + # Internal: calculateDimensions: -> fragment = $('