Merge master

This commit is contained in:
Garen Torikian
2013-04-09 14:54:17 -05:00
13 changed files with 186 additions and 56 deletions

View File

@@ -7,7 +7,7 @@
"ctags": "0.3.0",
"oniguruma": "0.8.0",
"mkdirp": "0.3.5",
"git-utils": "0.11.0",
"git-utils": "0.12.0",
"underscore": "1.4.4",
"d3": "3.0.8",
"coffee-cache": "0.1.0",

View File

@@ -341,6 +341,35 @@ describe "EditSession", ->
editSession.moveCursorToEndOfWord()
expect(editSession.getCursorBufferPosition()).toEqual [11, 8]
describe ".moveCursorToBeginningOfNextWord()", ->
it "moves the cursor before the first character of the next word", ->
editSession.setCursorBufferPosition [0,6]
editSession.addCursorAtBufferPosition [1,11]
editSession.addCursorAtBufferPosition [2,0]
[cursor1, cursor2, cursor3] = editSession.getCursors()
editSession.moveCursorToBeginningOfNextWord()
expect(cursor1.getBufferPosition()).toEqual [0, 14]
expect(cursor2.getBufferPosition()).toEqual [1, 13]
expect(cursor3.getBufferPosition()).toEqual [2, 4]
it "does not blow up when there is no next word", ->
editSession.setCursorBufferPosition [Infinity, Infinity]
endPosition = editSession.getCursorBufferPosition()
editSession.moveCursorToBeginningOfNextWord()
expect(editSession.getCursorBufferPosition()).toEqual endPosition
it "treats lines with only whitespace as a word", ->
editSession.setCursorBufferPosition([9, 4])
editSession.moveCursorToBeginningOfNextWord()
expect(editSession.getCursorBufferPosition()).toEqual [10, 0]
it "works when the current line is blank", ->
editSession.setCursorBufferPosition([10, 0])
editSession.moveCursorToBeginningOfNextWord()
expect(editSession.getCursorBufferPosition()).toEqual [11, 9]
describe ".getCurrentParagraphBufferRange()", ->
it "returns the buffer range of the current paragraph, delimited by blank lines or the beginning / end of the file", ->
buffer.setText """
@@ -619,6 +648,25 @@ describe "EditSession", ->
expect(selection2.getBufferRange()).toEqual [[3,48], [3,50]]
expect(selection2.isReversed()).toBeFalsy()
describe ".selectToBeginningOfNextWord()", ->
it "selects text from cusor position to beginning of next word", ->
editSession.setCursorScreenPosition [0,4]
editSession.addCursorAtScreenPosition [3,48]
editSession.selectToBeginningOfNextWord()
expect(editSession.getCursors().length).toBe 2
[cursor1, cursor2] = editSession.getCursors()
expect(cursor1.getBufferPosition()).toEqual [0,14]
expect(cursor2.getBufferPosition()).toEqual [3,51]
expect(editSession.getSelections().length).toBe 2
[selection1, selection2] = editSession.getSelections()
expect(selection1.getBufferRange()).toEqual [[0,4], [0,14]]
expect(selection1.isReversed()).toBeFalsy()
expect(selection2.getBufferRange()).toEqual [[3,48], [3,51]]
expect(selection2.isReversed()).toBeFalsy()
describe ".selectWord()", ->
describe "when the cursor is inside a word", ->
it "selects the entire word", ->

View File

@@ -198,3 +198,31 @@ describe "Window", ->
expect(deserialize({ deserializer: 'Foo', version: 3, name: 'Bar' })).toBeUndefined()
expect(deserialize({ deserializer: 'Foo', version: 1, name: 'Bar' })).toBeUndefined()
expect(deserialize({ deserializer: 'Foo', name: 'Bar' })).toBeUndefined()
describe "drag and drop", ->
buildDragEvent = (type, files) ->
dataTransfer =
files: files
data: {}
setData: (key, value) -> @data[key] = value
getData: (key) -> @data[key]
event = $.Event(type)
event.originalEvent = { dataTransfer }
event.preventDefault = ->
event.stopPropagation = ->
event
describe "when a file is dragged to window", ->
it "opens it", ->
spyOn(atom, "open")
event = buildDragEvent("drop", [ {path: "/fake1"}, {path: "/fake2"} ])
window.onDrop(event)
expect(atom.open.callCount).toBe 2
describe "when a non-file is dragged to window", ->
it "does nothing", ->
spyOn(atom, "open")
event = buildDragEvent("drop", [])
window.onDrop(event)
expect(atom.open).not.toHaveBeenCalled()

View File

@@ -178,6 +178,10 @@ class Cursor
if position = @getEndOfCurrentWordBufferPosition()
@setBufferPosition(position)
moveToBeginningOfNextWord: ->
if position = @getBeginningOfNextWordBufferPosition()
@setBufferPosition(position)
getBeginningOfCurrentWordBufferPosition: (options = {}) ->
allowPrevious = options.allowPrevious ? true
currentBufferPosition = @getBufferPosition()
@@ -205,7 +209,20 @@ class Cursor
if not endOfWordPosition?.isEqual(currentBufferPosition)
stop()
endOfWordPosition or currentBufferPosition
endOfWordPosition ? currentBufferPosition
getBeginningOfNextWordBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
start = if @isSurroundedByWhitespace() then currentBufferPosition else @getEndOfCurrentWordBufferPosition()
scanRange = [start, @editSession.getEofBufferPosition()]
beginningOfNextWordPosition = null
@editSession.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
beginningOfNextWordPosition = range.start
stop()
beginningOfNextWordPosition or currentBufferPosition
# Public: Gets the word located under the cursor.
#
# options - An object with properties based on {Cursor.getBeginningOfCurrentWordBufferPosition}.

View File

@@ -766,23 +766,23 @@ class EditSession
# 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...)
@@ -792,83 +792,83 @@ class EditSession
# 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...)
# Public: Returns `true` if there are multiple cursors in the edit session.
#
# Returns a {Boolean}.
@@ -1090,6 +1090,9 @@ class EditSession
moveCursorToEndOfWord: ->
@moveCursors (cursor) -> cursor.moveToEndOfWord()
moveCursorToBeginningOfNextWord: ->
@moveCursors (cursor) -> cursor.moveToBeginningOfNextWord()
moveCursors: (fn) ->
fn(cursor) for cursor in @getCursors()
@mergeCursors()
@@ -1184,6 +1187,10 @@ class EditSession
selectToEndOfWord: ->
@expandSelectionsForward (selection) => selection.selectToEndOfWord()
# Public: Selects all the text from the current cursor position to the beginning of the next word.
selectToBeginningOfNextWord: ->
@expandSelectionsForward (selection) => selection.selectToBeginningOfNextWord()
# Public: Selects the current word.
selectWord: ->
@expandSelectionsForward (selection) => selection.selectWord()

View File

@@ -130,10 +130,12 @@ class Editor extends View
'editor:move-to-first-character-of-line': @moveCursorToFirstCharacterOfLine
'editor:move-to-beginning-of-word': @moveCursorToBeginningOfWord
'editor:move-to-end-of-word': @moveCursorToEndOfWord
'editor:move-to-beginning-of-next-word': @moveCursorToBeginningOfNextWord
'editor:select-to-end-of-line': @selectToEndOfLine
'editor:select-to-beginning-of-line': @selectToBeginningOfLine
'editor:select-to-end-of-word': @selectToEndOfWord
'editor:select-to-beginning-of-word': @selectToBeginningOfWord
'editor:select-to-beginning-of-next-word': @selectToBeginningOfNextWord
'editor:add-selection-below': @addSelectionBelow
'editor:add-selection-above': @addSelectionAbove
'editor:select-line': @selectLine
@@ -211,7 +213,8 @@ class Editor extends View
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.
# Public: Moves the cursor to the beginning of the next word.
moveCursorToBeginningOfNextWord: -> @activeEditSession.moveCursorToBeginningOfNextWord()
moveCursorToTop: -> @activeEditSession.moveCursorToTop()
# Public: Moves every cursor to the bottom of the buffer.
moveCursorToBottom: -> @activeEditSession.moveCursorToBottom()
@@ -233,6 +236,7 @@ class Editor extends View
setCursorScreenPosition: (position, options) -> @activeEditSession.setCursorScreenPosition(position, options)
# Public: Duplicates the current line.
duplicateLine: -> @activeEditSession.duplicateLine()
joinLine: -> @activeEditSession.joinLine()
getCursorScreenPosition: -> @activeEditSession.getCursorScreenPosition()
# Public: Gets the current screen row.
#
@@ -292,7 +296,8 @@ class Editor extends View
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.
# Public: Selects all the text from the current cursor position to the beginning of the next word.
selectToBeginningOfNextWord: -> @activeEditSession.selectToBeginningOfNextWord()
selectWord: -> @activeEditSession.selectWord()
selectLine: -> @activeEditSession.selectLine()
selectToScreenPosition: (position) -> @activeEditSession.selectToScreenPosition(position)
@@ -342,7 +347,7 @@ class Editor extends View
# options - A set of options equivalent to {Selection.indent}.
indent: (options) -> @activeEditSession.indent(options)
# Public: TODO
autoIndent: -> @activeEditSession.autoIndentSelectedRows()
autoIndent: (options) -> @activeEditSession.autoIndentSelectedRows()
# Public: Indents the selected rows.
indentSelectedRows: -> @activeEditSession.indentSelectedRows()
# Public: Outdents the selected rows.

View File

@@ -95,11 +95,7 @@ class Git
@isStatusNew(@getPathStatus(path))
relativize: (path) ->
workingDirectory = @getWorkingDirectory()
if workingDirectory and path.indexOf("#{workingDirectory}/") is 0
path.substring(workingDirectory.length + 1)
else
path
@getRepo().relativize(path)
getShortHead: ->
@getRepo().getShortHead()

View File

@@ -152,6 +152,9 @@ class Selection
selectToEndOfWord: ->
@modifySelection => @cursor.moveToEndOfWord()
selectToBeginningOfNextWord: ->
@modifySelection => @cursor.moveToBeginningOfNextWord()
addSelectionBelow: ->
range = (@goalBufferRange ? @getBufferRange()).copy()
nextRow = range.end.row + 1

View File

@@ -25,12 +25,6 @@ window.setUpEnvironment = ->
$(document).on 'keydown', keymap.handleKeyEvent
keymap.bindDefaultKeys()
ignoreEvents = (e) ->
e.preventDefault()
e.stopPropagation()
$(document).on 'dragover', ignoreEvents
$(document).on 'drop', ignoreEvents
requireStylesheet 'reset'
requireStylesheet 'atom'
requireStylesheet 'overlay'
@@ -50,6 +44,7 @@ window.startup = ->
console.warn "Failed to install `atom` binary"
handleWindowEvents()
handleDragDrop()
config.load()
keymap.loadBundledKeymaps()
atom.loadThemes()
@@ -93,6 +88,18 @@ window.handleWindowEvents = ->
$(window).command 'window:close', => confirmClose()
$(window).command 'window:reload', => reload()
window.handleDragDrop = ->
$(document).on 'dragover', (e) ->
e.preventDefault()
e.stopPropagation()
$(document).on 'drop', onDrop
window.onDrop = (e) ->
e.preventDefault()
e.stopPropagation()
for file in e.originalEvent.dataTransfer.files
atom.open(file.path)
window.deserializeWindowState = ->
RootView = require 'root-view'
Project = require 'project'

View File

@@ -27,6 +27,8 @@ class AutocompleteView extends SelectList
handleEvents: ->
@editor.on 'editor:path-changed', => @setCurrentBuffer(@editor.getBuffer())
@editor.command 'autocomplete:attach', => @attach()
@editor.command 'autocomplete:next', => @selectNextItem()
@editor.command 'autocomplete:previous', => @selectPreviousItem()
@miniEditor.preempt 'textInput', (e) =>
text = e.originalEvent.data

View File

@@ -15,12 +15,19 @@ module.exports =
console.warn("Can not render markdown for '#{editSession.getUri() ? 'untitled'}'")
return
if nextPane = activePane.getNextPane()
if preview = nextPane.itemForUri("markdown-preview:#{editSession.getPath()}")
nextPane.showItem(preview)
preview.fetchRenderedMarkdown()
else
nextPane.showItem(new MarkdownPreviewView(editSession.buffer))
{previewPane, previewItem} = @getExistingPreview(editSession)
if previewItem?
previewPane.showItem(previewItem)
previewItem.fetchRenderedMarkdown()
else if nextPane = activePane.getNextPane()
nextPane.showItem(new MarkdownPreviewView(editSession.buffer))
else
activePane.splitRight(new MarkdownPreviewView(editSession.buffer))
activePane.focus()
getExistingPreview: (editSession) ->
uri = "markdown-preview:#{editSession.getPath()}"
for previewPane in rootView.getPanes()
previewItem = previewPane.itemForUri(uri)
return {previewPane, previewItem} if previewItem?
{}

View File

@@ -77,11 +77,8 @@ class TabBarView extends View
(@paneContainer.getPanes().length > 1) or (@pane.getItems().length > 1)
onDragStart: (event) =>
unless @shouldAllowDrag(event)
event.preventDefault()
return
event.originalEvent.dataTransfer.setData 'atom-event', 'true'
if @shouldAllowDrag()
event.originalEvent.dataTransfer.setData 'atom-event', 'true'
el = $(event.target).closest('.sortable')
el.addClass 'is-dragging'
@@ -91,8 +88,15 @@ class TabBarView extends View
paneIndex = @paneContainer.indexOfPane(pane)
event.originalEvent.dataTransfer.setData 'from-pane-index', paneIndex
item = @pane.getItems()[el.index()]
if item.getPath?
event.originalEvent.dataTransfer.setData 'text/uri-list', 'file://' + item.getPath()
event.originalEvent.dataTransfer.setData 'text/plain', item.getPath()
onDragEnd: (event) =>
@find(".is-dragging").removeClass 'is-dragging'
@children('.is-drop-target').removeClass 'is-drop-target'
@children('.drop-target-is-after').removeClass 'drop-target-is-after'
onDragOver: (event) =>
unless event.originalEvent.dataTransfer.getData('atom-event') is 'true'
@@ -120,8 +124,6 @@ class TabBarView extends View
return
event.stopPropagation()
@children('.is-drop-target').removeClass 'is-drop-target'
@children('.drop-target-is-after').removeClass 'drop-target-is-after'
dataTransfer = event.originalEvent.dataTransfer
fromIndex = parseInt(dataTransfer.getData('sortable-index'))

View File

@@ -279,8 +279,8 @@ describe "TabBarView", ->
expect(pane2.activeItem).toBe item1
expect(pane2.focus).toHaveBeenCalled()
describe 'when a non-tab is dragged to pane', ->
it 'has no effect', ->
describe "when a non-tab is dragged to pane", ->
it "has no effect", ->
expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"]
expect(pane.getItems()).toEqual [item1, editSession1, item2]
expect(pane.activeItem).toBe item2
@@ -294,3 +294,11 @@ describe "TabBarView", ->
expect(pane.activeItem).toBe item2
expect(pane.focus).not.toHaveBeenCalled()
describe "when a tab is dragged out of application", ->
it "should carry file's information", ->
[dragStartEvent, dropEvent] = buildDragEvents(tabBar.tabAtIndex(1), tabBar.tabAtIndex(1))
tabBar.onDragStart(dragStartEvent)
expect(dragStartEvent.originalEvent.dataTransfer.getData("text/plain")).toEqual editSession1.getPath()
expect(dragStartEvent.originalEvent.dataTransfer.getData("text/uri-list")).toEqual 'file://' + editSession1.getPath()