mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
Should I regret a lack of better commit messages?
This commit is contained in:
@@ -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())
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = $('<pre class="line" style="position: absolute; visibility: hidden;"><span>x</span></div>')
|
||||
@renderedLines.append(fragment)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Range = require 'range'
|
||||
Point = require 'point'
|
||||
|
||||
# Public: Represents a fold in the {Gutter}.
|
||||
# Public: Represents a fold that's hiding text from the screen.
|
||||
#
|
||||
# Folds hide away text from the screen. They're the primary reason
|
||||
# that screen ranges and buffer ranges vary.
|
||||
# Folds are the primary reason that screen ranges and buffer ranges vary. Their
|
||||
# creation is managed by the {DisplayBuffer}.
|
||||
module.exports =
|
||||
class Fold
|
||||
@idCounter: 1
|
||||
|
||||
@@ -3,6 +3,9 @@ Range = require 'range'
|
||||
$ = require 'jquery'
|
||||
_ = require 'underscore'
|
||||
|
||||
# Public: Represents the portion of the {Editor} containing row numbers.
|
||||
#
|
||||
# The gutter also indicates if rows are folded.
|
||||
module.exports =
|
||||
class Gutter extends View
|
||||
|
||||
@@ -15,6 +18,7 @@ class Gutter extends View
|
||||
lastScreenRow: -1
|
||||
highestNumberWidth: null
|
||||
|
||||
# Internal:
|
||||
afterAttach: (onDom) ->
|
||||
return if @attached or not onDom
|
||||
@attached = true
|
||||
@@ -34,6 +38,7 @@ class Gutter extends View
|
||||
beforeRemove: ->
|
||||
$(document).off(".gutter-#{@getEditor().id}")
|
||||
|
||||
# Internal:
|
||||
handleMouseEvents: (e) ->
|
||||
editor = @getEditor()
|
||||
startRow = editor.screenPositionFromMouseEvent(e).row
|
||||
@@ -52,9 +57,13 @@ class Gutter extends View
|
||||
$(document).on "mousemove.gutter-#{@getEditor().id}", moveHandler
|
||||
$(document).one "mouseup.gutter-#{@getEditor().id}", => $(document).off 'mousemove', moveHandler
|
||||
|
||||
# Public: Defines whether to show the gutter or not.
|
||||
#
|
||||
# showLineNumbers - A {Boolean} which, if `false`, hides the gutter
|
||||
setShowLineNumbers: (showLineNumbers) ->
|
||||
if showLineNumbers then @lineNumbers.show() else @lineNumbers.hide()
|
||||
|
||||
# Internal:
|
||||
updateLineNumbers: (changes, renderFrom, renderTo) ->
|
||||
if renderFrom < @firstScreenRow or renderTo > @lastScreenRow
|
||||
performUpdate = true
|
||||
@@ -67,7 +76,8 @@ class Gutter extends View
|
||||
break
|
||||
|
||||
@renderLineNumbers(renderFrom, renderTo) if performUpdate
|
||||
|
||||
|
||||
# Internal:
|
||||
renderLineNumbers: (startScreenRow, endScreenRow) ->
|
||||
editor = @getEditor()
|
||||
maxDigits = editor.getLineCount().toString().length
|
||||
@@ -93,6 +103,7 @@ class Gutter extends View
|
||||
@highlightedRows = null
|
||||
@highlightLines()
|
||||
|
||||
# Internal:
|
||||
removeLineHighlights: ->
|
||||
return unless @highlightedLineNumbers
|
||||
for line in @highlightedLineNumbers
|
||||
@@ -100,6 +111,7 @@ class Gutter extends View
|
||||
line.classList.remove('cursor-line-no-selection')
|
||||
@highlightedLineNumbers = null
|
||||
|
||||
# Internal:
|
||||
addLineHighlight: (row, emptySelection) ->
|
||||
return if row < @firstScreenRow or row > @lastScreenRow
|
||||
@highlightedLineNumbers ?= []
|
||||
@@ -108,6 +120,7 @@ class Gutter extends View
|
||||
highlightedLineNumber.classList.add('cursor-line-no-selection') if emptySelection
|
||||
@highlightedLineNumbers.push(highlightedLineNumber)
|
||||
|
||||
# Internal:
|
||||
highlightLines: ->
|
||||
if @getEditor().getSelection().isEmpty()
|
||||
row = @getEditor().getCursorScreenPosition().row
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
fsUtils = require 'fs-utils'
|
||||
_ = require 'underscore'
|
||||
|
||||
# Public: Manages the states between {Editor}s, images, and the project as a whole.
|
||||
#
|
||||
# Essentially, the graphical version of a {EditSession}.
|
||||
module.exports=
|
||||
class ImageEditSession
|
||||
registerDeserializer(this)
|
||||
@@ -48,9 +51,20 @@ class ImageEditSession
|
||||
else
|
||||
'untitled'
|
||||
|
||||
# Public: Retrieves the URI of the current image.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getUri: -> @path
|
||||
|
||||
# Public: Retrieves the path of the current image.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getPath: -> @path
|
||||
|
||||
# Public: Compares two `ImageEditSession`s to determine equality.
|
||||
#
|
||||
# Equality is based on the condition that the two URIs are the same.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
isEqual: (other) ->
|
||||
other instanceof ImageEditSession and @getUri() is other.getUri()
|
||||
|
||||
@@ -2,6 +2,7 @@ ScrollView = require 'scroll-view'
|
||||
_ = require 'underscore'
|
||||
$ = require 'jquery'
|
||||
|
||||
# Public: Renders images in the {Editor}.
|
||||
module.exports =
|
||||
class ImageView extends ScrollView
|
||||
|
||||
@@ -28,6 +29,7 @@ class ImageView extends ScrollView
|
||||
@command 'image-view:zoom-out', => @zoomOut()
|
||||
@command 'image-view:reset-zoom', => @resetZoom()
|
||||
|
||||
# Internal:
|
||||
afterAttach: (onDom) ->
|
||||
return unless onDom
|
||||
|
||||
@@ -38,6 +40,7 @@ class ImageView extends ScrollView
|
||||
@active = @is(pane.activeView)
|
||||
@centerImage() if @active and not wasActive
|
||||
|
||||
# Public: Places the image in the center of the {Editor}.
|
||||
centerImage: ->
|
||||
return unless @loaded and @isVisible()
|
||||
|
||||
@@ -46,6 +49,9 @@ class ImageView extends ScrollView
|
||||
'left': Math.max((@width() - @image.outerWidth()) / 2, 0)
|
||||
@image.show()
|
||||
|
||||
# Public: Indicates the path of the image.
|
||||
#
|
||||
# path - A {String} for the new image path.
|
||||
setPath: (path) ->
|
||||
if path?
|
||||
if @image.attr('src') isnt path
|
||||
@@ -54,12 +60,18 @@ class ImageView extends ScrollView
|
||||
else
|
||||
@image.hide()
|
||||
|
||||
# Internal:
|
||||
setModel: (imageEditSession) ->
|
||||
@setPath(imageEditSession?.getPath())
|
||||
|
||||
|
||||
# Public: Retrieve's the {Editor}'s pane.
|
||||
#
|
||||
# Returns a {Pane}.
|
||||
getPane: ->
|
||||
@parent('.item-views').parent('.pane').view()
|
||||
|
||||
# Internal:
|
||||
adjustSize: (factor) ->
|
||||
return unless @loaded and @isVisible()
|
||||
|
||||
@@ -69,12 +81,19 @@ class ImageView extends ScrollView
|
||||
@image.height(newHeight)
|
||||
@centerImage()
|
||||
|
||||
# Public: Zooms the image out.
|
||||
#
|
||||
# This is done by a factor of `0.9`.
|
||||
zoomOut: ->
|
||||
@adjustSize(0.9)
|
||||
|
||||
# Public: Zooms the image in.
|
||||
#
|
||||
# This is done by a factor of `1.1`.
|
||||
zoomIn: ->
|
||||
@adjustSize(1.1)
|
||||
|
||||
# Public: Zooms the image to its normal width and height.
|
||||
resetZoom: ->
|
||||
return unless @loaded and @isVisible()
|
||||
|
||||
|
||||
@@ -5,6 +5,19 @@ CSON = require 'cson'
|
||||
|
||||
BindingSet = require 'binding-set'
|
||||
|
||||
# Internal: Associates keymaps with actions.
|
||||
#
|
||||
# Keymaps are defined in a CSON format. A typical keymap looks something like this:
|
||||
#
|
||||
# ```cson
|
||||
# 'body':
|
||||
# 'ctrl-l': 'package:do-something'
|
||||
#'.someClass':
|
||||
# 'enter': 'package:confirm'
|
||||
# ```
|
||||
#
|
||||
# As a key, you define the DOM element you want to work on, using CSS notation. For that
|
||||
# key, you define one or more key:value pairs, associating keystrokes with a command to execute.
|
||||
module.exports =
|
||||
class Keymap
|
||||
bindingSets: null
|
||||
@@ -12,10 +25,12 @@ class Keymap
|
||||
bindingSetsByFirstKeystroke: null
|
||||
queuedKeystrokes: null
|
||||
|
||||
# Internal:
|
||||
constructor: ->
|
||||
@bindingSets = []
|
||||
@bindingSetsByFirstKeystroke = {}
|
||||
|
||||
# Internal:
|
||||
bindDefaultKeys: ->
|
||||
@add
|
||||
'body':
|
||||
@@ -31,31 +46,37 @@ class Keymap
|
||||
$(document).command 'open', => atom.open()
|
||||
$(document).command 'open-dev', => atom.openDev()
|
||||
|
||||
# Internal:
|
||||
loadBundledKeymaps: ->
|
||||
@loadDirectory(fsUtils.resolveOnLoadPath('keymaps'))
|
||||
|
||||
loadUserKeymaps: ->
|
||||
@loadDirectory(fsUtils.join(config.configDirPath, 'keymaps'))
|
||||
|
||||
# Internal: Loads all the keys in a package.
|
||||
loadDirectory: (directoryPath) ->
|
||||
@load(filePath) for filePath in fsUtils.list(directoryPath, ['.cson', '.json'])
|
||||
|
||||
|
||||
# Internal: Loads keys at a specific path.
|
||||
load: (path) ->
|
||||
@add(path, CSON.readObject(path))
|
||||
|
||||
|
||||
# Internal: Force adds a keymapping.
|
||||
add: (args...) ->
|
||||
name = args.shift() if args.length > 1
|
||||
keymap = args.shift()
|
||||
for selector, bindings of keymap
|
||||
@bindKeys(name, selector, bindings)
|
||||
|
||||
|
||||
# Internal: Removes a keymapping by name.
|
||||
remove: (name) ->
|
||||
for bindingSet in @bindingSets.filter((bindingSet) -> bindingSet.name is name)
|
||||
_.remove(@bindingSets, bindingSet)
|
||||
for keystrokes of bindingSet.commandsByKeystrokes
|
||||
keystroke = keystrokes.split(' ')[0]
|
||||
_.remove(@bindingSetsByFirstKeystroke[keystroke], bindingSet)
|
||||
|
||||
|
||||
# Internal:
|
||||
bindKeys: (args...) ->
|
||||
name = args.shift() if args.length > 2
|
||||
[selector, bindings] = args
|
||||
@@ -65,7 +86,8 @@ class Keymap
|
||||
keystroke = keystrokes.split(' ')[0] # only index by first keystroke
|
||||
@bindingSetsByFirstKeystroke[keystroke] ?= []
|
||||
@bindingSetsByFirstKeystroke[keystroke].push(bindingSet)
|
||||
|
||||
|
||||
# Internal:
|
||||
unbindKeys: (selector, bindings) ->
|
||||
bindingSet = _.detect @bindingSets, (bindingSet) ->
|
||||
bindingSet.selector is selector and bindingSet.bindings is bindings
|
||||
@@ -73,7 +95,8 @@ class Keymap
|
||||
if bindingSet
|
||||
console.log "binding set", bindingSet
|
||||
_.remove(@bindingSets, bindingSet)
|
||||
|
||||
|
||||
# Internal:
|
||||
bindingsForElement: (element) ->
|
||||
keystrokeMap = {}
|
||||
currentNode = $(element)
|
||||
@@ -85,6 +108,7 @@ class Keymap
|
||||
|
||||
keystrokeMap
|
||||
|
||||
# Internal:
|
||||
handleKeyEvent: (event) =>
|
||||
event.keystrokes = @multiKeystrokeStringForEvent(event)
|
||||
isMultiKeystroke = @queuedKeystrokes?
|
||||
@@ -113,6 +137,7 @@ class Keymap
|
||||
return false if isMultiKeystroke
|
||||
return false if firstKeystroke is 'tab'
|
||||
|
||||
# Internal:
|
||||
bindingSetsForNode: (node, candidateBindingSets = @bindingSets) ->
|
||||
bindingSets = candidateBindingSets.filter (set) -> node.is(set.selector)
|
||||
bindingSets.sort (a, b) ->
|
||||
@@ -121,6 +146,7 @@ class Keymap
|
||||
else
|
||||
b.specificity - a.specificity
|
||||
|
||||
# Internal:
|
||||
triggerCommandEvent: (keyEvent, commandName) ->
|
||||
keyEvent.target = rootView[0] if keyEvent.target == document.body and window.rootView
|
||||
commandEvent = $.Event(commandName)
|
||||
@@ -132,6 +158,7 @@ class Keymap
|
||||
$(keyEvent.target).trigger(commandEvent)
|
||||
aborted
|
||||
|
||||
# Internal:
|
||||
multiKeystrokeStringForEvent: (event) ->
|
||||
currentKeystroke = @keystrokeStringForEvent(event)
|
||||
if @queuedKeystrokes
|
||||
@@ -163,6 +190,7 @@ class Keymap
|
||||
|
||||
[modifiers..., key].join('-')
|
||||
|
||||
# Internal:
|
||||
keyFromCharCode: (charCode) ->
|
||||
switch charCode
|
||||
when 8 then 'backspace'
|
||||
|
||||
@@ -44,6 +44,8 @@ class LanguageMode
|
||||
#
|
||||
# startRow - The row {Number} to start at
|
||||
# endRow - The row {Number} to end at
|
||||
#
|
||||
# Returns an {Array} of the commented {Ranges}.
|
||||
toggleLineCommentsForBufferRows: (start, end) ->
|
||||
scopes = @editSession.scopesForBufferPosition([start, 0])
|
||||
return unless commentStartString = syntax.getProperty(scopes, "editor.commentStart")
|
||||
|
||||
@@ -25,10 +25,21 @@ class LineMap
|
||||
|
||||
for screenLine in maxLengthCandidates
|
||||
@maxScreenLineLength = Math.max(@maxScreenLineLength, screenLine.text.length)
|
||||
|
||||
|
||||
# Public: Gets the line for the given screen row.
|
||||
#
|
||||
# screenRow - A {Number} indicating the screen row.
|
||||
#
|
||||
# Returns a {String}.
|
||||
lineForScreenRow: (row) ->
|
||||
@screenLines[row]
|
||||
|
||||
# Public: Gets the lines for the given screen row boundaries.
|
||||
#
|
||||
# start - A {Number} indicating the beginning screen row.
|
||||
# end - A {Number} indicating the ending screen row.
|
||||
#
|
||||
# Returns an {Array} of {String}s.
|
||||
linesForScreenRows: (startRow, endRow) ->
|
||||
@screenLines[startRow..endRow]
|
||||
|
||||
@@ -166,6 +177,7 @@ class LineMap
|
||||
end = @bufferPositionForScreenPosition(screenRange.end)
|
||||
new Range(start, end)
|
||||
|
||||
# Internal:
|
||||
logLines: (start=0, end=@screenLineCount() - 1)->
|
||||
for row in [start..end]
|
||||
line = @lineForScreenRow(row).text
|
||||
|
||||
@@ -3,13 +3,15 @@ $ = require 'jquery'
|
||||
|
||||
module.exports =
|
||||
class PaneAxis extends View
|
||||
# Internal:
|
||||
@deserialize: ({children}) ->
|
||||
childViews = children.map (child) -> deserialize(child)
|
||||
new this(childViews)
|
||||
|
||||
# Internal:
|
||||
initialize: (children=[]) ->
|
||||
@append(children...)
|
||||
|
||||
# Internal:
|
||||
serialize: ->
|
||||
deserializer: @className()
|
||||
children: @childViewStates()
|
||||
|
||||
@@ -141,12 +141,12 @@ class Project
|
||||
# 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}.
|
||||
# Public: Given a path to a file, this constructs and associates a new `EditSession`, showing the file.
|
||||
#
|
||||
# filePath - The {String} path of the file to associate with
|
||||
# editSessionOptions - Options that you can pass to the `EditSession` constructor
|
||||
#
|
||||
# Returns an {EditSession}.
|
||||
# Returns either an {EditSession} (for text) or {ImageEditSession} (for images).
|
||||
buildEditSession: (filePath, editSessionOptions={}) ->
|
||||
if ImageEditSession.canOpen(filePath)
|
||||
new ImageEditSession(filePath)
|
||||
|
||||
@@ -13,6 +13,7 @@ PaneRow = require 'pane-row'
|
||||
PaneContainer = require 'pane-container'
|
||||
EditSession = require 'edit-session'
|
||||
|
||||
# Public: The container for the entire Atom application.
|
||||
module.exports =
|
||||
class RootView extends View
|
||||
registerDeserializers(this, Pane, PaneRow, PaneColumn, Editor)
|
||||
@@ -78,9 +79,11 @@ class RootView extends View
|
||||
deserializer: 'RootView'
|
||||
panes: @panes.serialize()
|
||||
|
||||
# Public: Shows a dialog asking if the pane was _really_ meant to be closed.
|
||||
confirmClose: ->
|
||||
@panes.confirmClose()
|
||||
|
||||
# Internal:
|
||||
handleFocus: (e) ->
|
||||
if @getActivePane()
|
||||
@getActivePane().focus()
|
||||
@@ -93,10 +96,13 @@ class RootView extends View
|
||||
false
|
||||
else
|
||||
true
|
||||
|
||||
# Internal:
|
||||
afterAttach: (onDom) ->
|
||||
@focus() if onDom
|
||||
|
||||
# Public: Given a filepath, this opens it in Atom.
|
||||
#
|
||||
# Returns the `EditSession` for the file URI.
|
||||
open: (path, options = {}) ->
|
||||
changeFocus = options.changeFocus ? true
|
||||
path = project.resolve(path) if path?
|
||||
@@ -111,6 +117,7 @@ class RootView extends View
|
||||
activePane.focus() if changeFocus
|
||||
editSession
|
||||
|
||||
# Public: Updates the application's title, based on whichever file is open.
|
||||
updateTitle: ->
|
||||
if projectPath = project.getPath()
|
||||
if item = @getActivePaneItem()
|
||||
@@ -120,12 +127,21 @@ class RootView extends View
|
||||
else
|
||||
@setTitle('untitled')
|
||||
|
||||
# Public: Sets the application's title.
|
||||
#
|
||||
# Returns a {String}.
|
||||
setTitle: (title) ->
|
||||
document.title = title
|
||||
|
||||
# Public: Retrieves all of the application's {Editor}s.
|
||||
#
|
||||
# Returns an {Array} of {Editor}s.
|
||||
getEditors: ->
|
||||
@panes.find('.pane > .item-views > .editor').map(-> $(this).view()).toArray()
|
||||
|
||||
# Public: Retrieves all of the modified buffers that are open and unsaved.
|
||||
#
|
||||
# Returns an {Array} of {Buffer}s.
|
||||
getModifiedBuffers: ->
|
||||
modifiedBuffers = []
|
||||
for pane in @getPanes()
|
||||
@@ -133,9 +149,15 @@ class RootView extends View
|
||||
modifiedBuffers.push item.buffer if item.buffer.isModified()
|
||||
modifiedBuffers
|
||||
|
||||
# Public: Retrieves all of the paths to open files.
|
||||
#
|
||||
# Returns an {Array} of {String}s.
|
||||
getOpenBufferPaths: ->
|
||||
_.uniq(_.flatten(@getEditors().map (editor) -> editor.getOpenBufferPaths()))
|
||||
|
||||
# Public: Retrieves the pane that's currently open.
|
||||
#
|
||||
# Returns an {Pane}.
|
||||
getActivePane: ->
|
||||
@panes.getActivePane()
|
||||
|
||||
@@ -149,29 +171,51 @@ class RootView extends View
|
||||
focusNextPane: -> @panes.focusNextPane()
|
||||
getFocusedPane: -> @panes.getFocusedPane()
|
||||
|
||||
# Internal: Destroys everything.
|
||||
remove: ->
|
||||
editor.remove() for editor in @getEditors()
|
||||
project.destroy()
|
||||
super
|
||||
|
||||
# Public: Saves all of the open buffers.
|
||||
saveAll: ->
|
||||
@panes.saveAll()
|
||||
|
||||
# Public: Fires a callback on each open {Pane}.
|
||||
#
|
||||
# callback - A {Function} to call
|
||||
eachPane: (callback) ->
|
||||
@panes.eachPane(callback)
|
||||
|
||||
# Public: Retrieves all of the open {Pane}s.
|
||||
#
|
||||
# Returns an {Array} of {Pane}.
|
||||
getPanes: ->
|
||||
@panes.getPanes()
|
||||
|
||||
# Public: Given a {Pane}, this fetches its ID.
|
||||
#
|
||||
# pane - An open {Pane}
|
||||
#
|
||||
# Returns a {Number}.
|
||||
indexOfPane: (pane) ->
|
||||
@panes.indexOfPane(pane)
|
||||
|
||||
# Public: Fires a callback on each open {Editor}.
|
||||
#
|
||||
# callback - A {Function} to call
|
||||
eachEditor: (callback) ->
|
||||
callback(editor) for editor in @getEditors()
|
||||
@on 'editor:attached', (e, editor) -> callback(editor)
|
||||
|
||||
# Public: Fires a callback on each open {EditSession}.
|
||||
#
|
||||
# callback - A {Function} to call
|
||||
eachEditSession: (callback) ->
|
||||
project.eachEditSession(callback)
|
||||
|
||||
# Public: Fires a callback on each open {Buffer}.
|
||||
#
|
||||
# callback - A {Function} to call
|
||||
eachBuffer: (callback) ->
|
||||
project.eachBuffer(callback)
|
||||
|
||||
@@ -450,17 +450,29 @@ class Selection
|
||||
[start, end] = @getBufferRowRange()
|
||||
@editSession.autoIndentBufferRows(start, end)
|
||||
|
||||
# Public: Wraps the selected lines in comments.
|
||||
#
|
||||
# Returns an {Array} of the commented {Ranges}.
|
||||
toggleLineComments: ->
|
||||
@editSession.toggleLineCommentsForBufferRows(@getBufferRowRange()...)
|
||||
|
||||
# Public: Performs a cut operation on the selection, until the end of the line.
|
||||
#
|
||||
# maintainPasteboard - A {Boolean} indicating TODO
|
||||
cutToEndOfLine: (maintainPasteboard) ->
|
||||
@selectToEndOfLine() if @isEmpty()
|
||||
@cut(maintainPasteboard)
|
||||
|
||||
# Public: Performs a cut operation on the selection.
|
||||
#
|
||||
# maintainPasteboard - A {Boolean} indicating TODO
|
||||
cut: (maintainPasteboard=false) ->
|
||||
@copy(maintainPasteboard)
|
||||
@delete()
|
||||
|
||||
# Public: Performs a copy operation on the selection.
|
||||
#
|
||||
# maintainPasteboard - A {Boolean} indicating TODO
|
||||
copy: (maintainPasteboard=false) ->
|
||||
return if @isEmpty()
|
||||
text = @editSession.buffer.getTextInRange(@getBufferRange())
|
||||
@@ -472,6 +484,7 @@ class Selection
|
||||
|
||||
pasteboard.write(text, metadata)
|
||||
|
||||
# Public: Folds the selection.
|
||||
fold: ->
|
||||
range = @getBufferRange()
|
||||
@editSession.createFold(range.start.row, range.end.row)
|
||||
|
||||
@@ -16,6 +16,7 @@ class Syntax
|
||||
syntax.grammarOverridesByPath = grammarOverridesByPath
|
||||
syntax
|
||||
|
||||
# Internal:
|
||||
constructor: ->
|
||||
@nullGrammar = new NullGrammar
|
||||
@grammars = [@nullGrammar]
|
||||
@@ -24,6 +25,7 @@ class Syntax
|
||||
@scopedPropertiesIndex = 0
|
||||
@scopedProperties = []
|
||||
|
||||
# Internal:
|
||||
serialize: ->
|
||||
{ deserializer: @constructor.name, @grammarOverridesByPath }
|
||||
|
||||
|
||||
@@ -498,9 +498,19 @@ class Buffer
|
||||
|
||||
matches
|
||||
|
||||
# Public: Scans for text in the buffer, calling a function on each match.
|
||||
#
|
||||
# regex - A {RegExp} representing the text to find
|
||||
# iterator - A {Function} that's called on each match
|
||||
scan: (regex, iterator) ->
|
||||
@scanInRange(regex, @getRange(), iterator)
|
||||
|
||||
# Public: Scans for text in a given range, calling a function on each match.
|
||||
#
|
||||
# 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
|
||||
# reverse - A {Boolean} indicating if the search should be backwards (default: `false`)
|
||||
scanInRange: (regex, range, iterator, reverse=false) ->
|
||||
range = @clipRange(range)
|
||||
global = regex.global
|
||||
@@ -538,6 +548,11 @@ class Buffer
|
||||
|
||||
break unless global and keepLooping
|
||||
|
||||
# Public: Scans for text in a given range _backwards_, calling a function on each match.
|
||||
#
|
||||
# regex - A {RegExp} representing the text to find
|
||||
# range - A {Range} in the buffer to search within
|
||||
# iterator - A {Function} that's called on each match
|
||||
backwardsScanInRange: (regex, range, iterator) ->
|
||||
@scanInRange regex, range, iterator, true
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class TokenizedBuffer
|
||||
invalidRows: null
|
||||
visible: false
|
||||
|
||||
# Internal:
|
||||
constructor: (@buffer, { @languageMode, @tabLength }) ->
|
||||
@tabLength ?= 2
|
||||
@id = @constructor.idCounter++
|
||||
@@ -33,9 +34,15 @@ class TokenizedBuffer
|
||||
setVisible: (@visible) ->
|
||||
@tokenizeInBackground() if @visible
|
||||
|
||||
# Public: Retrieves the current tab length.
|
||||
#
|
||||
# Returns a {Number}.
|
||||
getTabLength: ->
|
||||
@tabLength
|
||||
|
||||
# Public: Specifies the tab length.
|
||||
#
|
||||
# tabLength - A {Number} that defines the new tab length.
|
||||
setTabLength: (@tabLength) ->
|
||||
lastRow = @buffer.getLastRow()
|
||||
@screenLines = @buildPlaceholderScreenLinesForRows(0, lastRow)
|
||||
|
||||
@@ -10,7 +10,7 @@ require 'space-pen-extensions'
|
||||
deserializers = {}
|
||||
deferredDeserializers = {}
|
||||
|
||||
# This method is called in any window needing a general environment, including specs
|
||||
# Internal: This method is called in any window needing a general environment, including specs
|
||||
window.setUpEnvironment = ->
|
||||
Config = require 'config'
|
||||
Syntax = require 'syntax'
|
||||
@@ -35,7 +35,7 @@ window.setUpEnvironment = ->
|
||||
if nativeStylesheetPath = fsUtils.resolveOnLoadPath(process.platform, ['css', 'less'])
|
||||
requireStylesheet(nativeStylesheetPath)
|
||||
|
||||
# This method is only called when opening a real application window
|
||||
# Internal: This method is only called when opening a real application window
|
||||
window.startup = ->
|
||||
directory = _.find ['/opt/boxen', '/opt/github', '/usr/local'], (dir) -> fsUtils.isDirectory(dir)
|
||||
if directory
|
||||
@@ -213,5 +213,6 @@ window.profile = (description, fn) ->
|
||||
console.profileEnd(description)
|
||||
value
|
||||
|
||||
# Public: Shows a dialog asking if the window was _really_ meant to be closed.
|
||||
confirmClose = ->
|
||||
rootView.confirmClose().done -> window.close()
|
||||
|
||||
Reference in New Issue
Block a user