Merge branch 'master' into mc-release-notes

This commit is contained in:
Matt Colyer
2013-09-30 10:51:05 -07:00
9 changed files with 76 additions and 13 deletions

View File

@@ -1,3 +1,5 @@
* Improved: Faster and better looking find and replace
* Improved: Double-click selection behavior between word/non-word
* Added: Solarized theme now bundled by default
* Added: Base16 Tomorrow Dark theme now bundled by default

View File

@@ -16,8 +16,6 @@
styleguides
* Include thoughtfully worded [Jasmine](http://pivotal.github.com/jasmine/)
specs
* Style new elements in both the light and dark default themes when
appropriate
* Add 3rd-party packages as a `package.json` dependency
* Commit messages are in the present tense
* Commit messages that improve the format of the code start with :lipstick:

View File

@@ -1 +0,0 @@
All themes in this directory will be automatically loaded

View File

@@ -9,7 +9,7 @@
"bugs": {
"url": "https://github.com/atom/atom/issues"
},
"atomShellVersion": "0.5.1",
"atomShellVersion": "0.5.3",
"dependencies": {
"async": "0.2.6",
"bootstrap": "git://github.com/twbs/bootstrap.git#v3.0.0",

View File

@@ -181,7 +181,6 @@ describe "Config", ->
expect(fs.exists(config.configDirPath)).toBeTruthy()
expect(fs.exists(path.join(config.configDirPath, 'packages'))).toBeTruthy()
expect(fs.exists(path.join(config.configDirPath, 'snippets'))).toBeTruthy()
expect(fs.exists(path.join(config.configDirPath, 'themes'))).toBeTruthy()
expect(fs.isFileSync(path.join(config.configDirPath, 'config.cson'))).toBeTruthy()
describe ".loadUserConfig()", ->

View File

@@ -440,6 +440,29 @@ describe "Editor", ->
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [3, 12], originalEvent: {detail: 1}, shiftKey: true)
expect(editor.getSelectedBufferRange()).toEqual [[3, 10], [3, 12]]
describe "when clicking between a word and a non-word", ->
it "selects the word", ->
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [1, 21], originalEvent: {detail: 1})
editor.renderedLines.trigger 'mouseup'
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [1, 21], originalEvent: {detail: 2})
editor.renderedLines.trigger 'mouseup'
expect(editor.getSelectedText()).toBe "function"
editor.setCursorBufferPosition([0, 0])
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [1, 22], originalEvent: {detail: 1})
editor.renderedLines.trigger 'mouseup'
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [1, 22], originalEvent: {detail: 2})
editor.renderedLines.trigger 'mouseup'
expect(editor.getSelectedText()).toBe "items"
editor.setCursorBufferPosition([0, 0])
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [0, 28], originalEvent: {detail: 1})
editor.renderedLines.trigger 'mouseup'
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [0, 28], originalEvent: {detail: 2})
editor.renderedLines.trigger 'mouseup'
expect(editor.getSelectedText()).toBe "{"
describe "triple/quardruple/etc-click", ->
it "selects the line under the cursor", ->
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)

View File

@@ -4,6 +4,7 @@ _ = require './underscore-extensions'
Package = require './package'
ipc = require 'ipc'
remote = require 'remote'
shell = require 'shell'
crypto = require 'crypto'
path = require 'path'
dialog = remote.require 'dialog'
@@ -284,6 +285,9 @@ window.atom =
crashRenderProcess: ->
process.crash()
beep: ->
shell.beep()
requireUserInitScript: ->
userInitScriptPath = path.join(config.configDirPath, "user.coffee")
try

View File

@@ -102,10 +102,21 @@ class Cursor
# Public: Returns the visibility of the cursor.
isVisible: -> @visible
# Public: Returns a RegExp of what the cursor considers a "word"
wordRegExp: ->
nonWordCharacters = config.get("editor.nonWordCharacters")
new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(nonWordCharacters)}]+|[#{_.escapeRegExp(nonWordCharacters)}]+", "g")
# Public: Get the RegExp used by the cursor to determine what a "word" is.
#
# * options:
# + includeNonWordCharacters:
# A Boolean indicating whether to include non-word characters in the regex.
#
# Returns a RegExp.
wordRegExp: ({includeNonWordCharacters}={})->
includeNonWordCharacters ?= true
nonWordCharacters = config.get('editor.nonWordCharacters')
segments = ["^[\t ]*$"]
segments.push("[^\\s#{_.escapeRegExp(nonWordCharacters)}]+")
if includeNonWordCharacters
segments.push("[#{_.escapeRegExp(nonWordCharacters)}]+")
new RegExp(segments.join("|"), "g")
# Public: Identifies if this cursor is the last in the {EditSession}.
#
@@ -126,6 +137,25 @@ class Cursor
range = [[row, Math.min(0, column - 1)], [row, Math.max(0, column + 1)]]
/^\s+$/.test @editSession.getTextInBufferRange(range)
# Public: Returns whether the cursor is currently between a word and non-word
# character. The non-word characters are defined by the
# `editor.nonWordCharacters` config value.
#
# This method returns false if the character before or after the cursor is
# whitespace.
#
# Returns a Boolean.
isBetweenWordAndNonWord: ->
return false if @isAtBeginningOfLine() or @isAtEndOfLine()
{row, column} = @getBufferPosition()
range = [[row, column - 1], [row, column + 1]]
[before, after] = @editSession.getTextInBufferRange(range)
return false if /\s/.test(before) or /\s/.test(after)
nonWordCharacters = config.get('editor.nonWordCharacters').split('')
_.contains(nonWordCharacters, before) isnt _.contains(nonWordCharacters, after)
# Public: Returns whether this cursor is between a word's start and end.
isInsideWord: ->
{row, column} = @getBufferPosition()
@@ -280,6 +310,9 @@ class Cursor
# * options:
# + wordRegex:
# A RegExp indicating what constitutes a "word" (default: {.wordRegExp})
# + includeNonWordCharacters:
# A Boolean indicating whether to include non-word characters in the
# default word regex. Has no effect if wordRegex is set.
#
# Returns a {Range}.
getBeginningOfCurrentWordBufferPosition: (options = {}) ->
@@ -289,7 +322,7 @@ class Cursor
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]
beginningOfWordPosition = null
@editSession.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
@editSession.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) =>
if range.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious
beginningOfWordPosition = range.start
if not beginningOfWordPosition?.isEqual(currentBufferPosition)
@@ -297,7 +330,7 @@ class Cursor
beginningOfWordPosition or currentBufferPosition
# Public: Retrieves buffer position of previous word boundry. It might be on
# Public: Retrieves buffer position of previous word boundary. It might be on
# the current word, or the previous word.
getPreviousWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
@@ -319,7 +352,7 @@ class Cursor
beginningOfWordPosition or currentBufferPosition
# Public: Retrieves buffer position of the next word boundry. It might be on
# Public: Retrieves buffer position of the next word boundary. It might be on
# the current word, or the previous word.
getMoveNextWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
@@ -345,6 +378,9 @@ class Cursor
# * options:
# + wordRegex:
# A RegExp indicating what constitutes a "word" (default: {.wordRegExp})
# + includeNonWordCharacters:
# A Boolean indicating whether to include non-word characters in the
# default word regex. Has no effect if wordRegex is set.
#
# Returns a {Range}.
getEndOfCurrentWordBufferPosition: (options = {}) ->
@@ -353,7 +389,7 @@ class Cursor
scanRange = [currentBufferPosition, @editSession.getEofBufferPosition()]
endOfWordPosition = null
@editSession.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
@editSession.scanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) =>
if range.start.isLessThanOrEqual(currentBufferPosition) or allowNext
endOfWordPosition = range.end
if not endOfWordPosition?.isEqual(currentBufferPosition)

View File

@@ -115,6 +115,8 @@ class Selection
selectWord: ->
options = {}
options.wordRegex = /[\t ]*/ if @cursor.isSurroundedByWhitespace()
if @cursor.isBetweenWordAndNonWord()
options.includeNonWordCharacters = false
@setBufferRange(@cursor.getCurrentWordBufferRange(options))
@wordwise = true