Merge remote-tracking branch 'origin/master' into cj-expose-resizing-to-editor

This commit is contained in:
probablycorey
2014-06-17 17:22:10 -07:00
19 changed files with 182 additions and 69 deletions

View File

@@ -11,6 +11,9 @@ propose changes to this document in a pull request.
## Submitting Issues
* Check the [debugging guide](https://atom.io/docs/latest/debugging) for tips
on debugging. You might be able to find the cause of the problem and fix
things yourself.
* Include the version of Atom you are using and the OS.
* Include screenshots and animated GIFs whenever possible; they are immensely
helpful.

View File

@@ -1,5 +1,6 @@
fs = require 'fs'
path = require 'path'
_ = require 'underscore-plus'
module.exports = (grunt) ->
{cp, isAtomPackage, mkdir, rm} = require('./task-helpers')(grunt)
@@ -48,16 +49,22 @@ module.exports = (grunt) ->
path.join('bootstrap', 'docs')
path.join('bootstrap', 'examples')
path.join('pegjs', 'examples')
# Add .* to avoid matching hunspell_dictionaries.
path.join('spellchecker', 'vendor', 'hunspell', '.*')
path.join('plist', 'tests')
path.join('xmldom', 'test')
path.join('jasmine-reporters', 'ext')
path.join('build', 'Release', 'obj.target')
path.join('build', 'Release', 'obj')
path.join('build', 'Release', '.deps')
path.join('vendor', 'apm')
path.join('resources', 'mac')
path.join('resources', 'win')
]
ignoredPaths = ignoredPaths.map (ignoredPath) -> _.escapeRegExp(ignoredPath)
# Add .* to avoid matching hunspell_dictionaries.
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'vendor', 'hunspell') + path.sep)}.*"
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.*\\.pdb"
# Hunspell dictionaries are only not needed on OS X.
if process.platform is 'darwin'
ignoredPaths.push path.join('spellchecker', 'vendor', 'hunspell_dictionaries')

View File

@@ -8,11 +8,17 @@ GitHub = require 'github-releases'
request = require 'request'
grunt = null
maxReleases = 10
assets = [
{assetName: 'atom-mac.zip', sourceName: 'Atom.app'}
{assetName: 'atom-mac-symbols.zip', sourceName: 'Atom.breakpad.syms'}
]
if process.platform is 'darwin'
assets = [
{assetName: 'atom-mac.zip', sourceName: 'Atom.app'}
{assetName: 'atom-mac-symbols.zip', sourceName: 'Atom.breakpad.syms'}
]
else
assets = [
{assetName: 'atom-windows.zip', sourceName: 'Atom'}
]
commitSha = process.env.JANKY_SHA1
token = process.env.ATOM_ACCESS_TOKEN
defaultHeaders =
@@ -23,7 +29,6 @@ module.exports = (gruntObject) ->
grunt = gruntObject
grunt.registerTask 'publish-build', 'Publish the built app', ->
return unless process.platform is 'darwin'
return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master'
done = @async()
@@ -45,10 +50,13 @@ logError = (message, error, details) ->
zipApps = (buildDir, assets, callback) ->
zip = (directory, sourceName, assetName, callback) ->
if process.platform is 'win32'
zipCommand = "C:/psmodules/7z.exe a -r #{assetName} #{sourceName}"
else
zipCommand = "zip -r --symlinks #{assetName} #{sourceName}"
options = {cwd: directory, maxBuffer: Infinity}
child_process.exec "zip -r --symlinks #{assetName} #{sourceName}", options, (error, stdout, stderr) ->
if error?
logError("Zipping #{sourceName} failed", error, stderr)
child_process.exec zipCommand, options, (error, stdout, stderr) ->
logError("Zipping #{sourceName} failed", error, stderr) if error?
callback(error)
tasks = []

View File

@@ -7,6 +7,7 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
* OS with 64-bit or 32-bit architecture
* C++ toolchain
* on Ubuntu/Debian: `sudo apt-get install build-essential`
* on Fedora: `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel`
* [node.js](http://nodejs.org/download/) v0.10.x
* [Ubuntu/Debian/Mint instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os)
* [Fedora instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora)
@@ -20,6 +21,9 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses Python 2
* This command may require `sudo` depending on how you have
[configured npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
* Git
* on Ubuntu/Debian: `sudo apt-get install git`
* on Fedora: `sudo yum install git-core`
## Instructions

View File

@@ -51,5 +51,13 @@ fix this, you probably need to fiddle with your system PATH.
* Try moving the repository to `C:\atom`. Most likely, the path is too long.
See [issue #2200](https://github.com/atom/atom/issues/2200).
* `error MSB4025: The project file could not be loaded. Invalid character in the given encoding.`
* These can occur because your home directory (`%USERPROFILE%`) has non-ASCII
characters in it. This is a bug in [gyp](https://code.google.com/p/gyp/)
which is used to build native node modules and there is no known workaround.
* https://github.com/TooTallNate/node-gyp/issues/297
* https://code.google.com/p/gyp/issues/detail?id=393
### Windows build error reports in atom/atom
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows.

View File

@@ -1,6 +1,13 @@
# Debugging
Atom provides several tools to help you understand unexpected behavior and debug problems. This guide describes some of those tools and a few approaches to help you debug and provide more helpful information when [submitting issues].
Atom provides several tools to help you understand unexpected behavior and debug problems. This guide describes some of those tools and a few approaches to help you debug and provide more helpful information when [submitting issues]:
* [Update to the latest version](#update-to-the-latest-version)
* [Check Atom and package settings](#check-atom-and-package-settings)
* [Check the keybindings](#check-the-keybindings)
* [Check if the problem shows up in safe mode](#check-if-the-problem-shows-up-in-safe-mode)
* [Check your config files](#check-your-config-files)
* [Check for errors in the developer tools](#check-for-errors-in-the-developer-tools)
## Update to the latest version

View File

@@ -109,6 +109,7 @@
submenu: [
{ label: 'Add Selection Above', command: 'editor:add-selection-above' }
{ label: 'Add Selection Below', command: 'editor:add-selection-below' }
{ label: 'Single Selection', command: 'editor:consolidate-selections'}
{ label: 'Split into Lines', command: 'editor:split-selections-into-lines'}
{ type: 'separator' }
{ label: 'Select to Top', command: 'core:select-to-top' }

View File

@@ -108,6 +108,7 @@
{ label: 'Add Selection &Above', command: 'editor:add-selection-above' }
{ label: 'Add Selection &Below', command: 'editor:add-selection-below' }
{ label: 'S&plit into Lines', command: 'editor:split-selections-into-lines'}
{ label: 'Single Selection', command: 'editor:consolidate-selections'}
{ type: 'separator' }
{ label: 'Select to &Top', command: 'core:select-to-top' }
{ label: 'Select to Botto&m', command: 'core:select-to-bottom' }

View File

@@ -127,6 +127,7 @@
{ label: 'Add Selection &Above', command: 'editor:add-selection-above' }
{ label: 'Add Selection &Below', command: 'editor:add-selection-below' }
{ label: 'S&plit into Lines', command: 'editor:split-selections-into-lines'}
{ label: 'Single Selection', command: 'editor:consolidate-selections'}
{ type: 'separator' }
{ label: 'Select to &Top', command: 'core:select-to-top' }
{ label: 'Select to Botto&m', command: 'core:select-to-bottom' }

View File

@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.104.0",
"version": "0.105.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -17,7 +17,7 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.13.0",
"atomShellVersion": "0.13.1",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^0.27.0",
@@ -48,14 +48,14 @@
"react-atom-fork": "^0.10.0",
"reactionary-atom-fork": "^0.9.0",
"runas": "^0.5",
"scandal": "0.15.2",
"scandal": "0.15.3",
"scoped-property-store": "^0.9.0",
"scrollbar-style": "^0.4.0",
"season": "^1.0.2",
"semver": "1.1.4",
"serializable": "^1",
"space-pen": "3.2.0",
"temp": "0.5.0",
"temp": "0.7.0",
"text-buffer": "^2.3.0",
"theorist": "^1",
"underscore-plus": "^1.4.1",
@@ -74,8 +74,8 @@
"autoflow": "0.17.0",
"autosave": "0.14.0",
"background-tips": "0.14.0",
"bookmarks": "0.24.0",
"bracket-matcher": "0.45.0",
"bookmarks": "0.25.0",
"bracket-matcher": "0.47.0",
"command-palette": "0.22.0",
"deprecation-cop": "0.7.0",
"dev-live-reload": "0.31.0",
@@ -89,25 +89,25 @@
"image-view": "0.35.0",
"keybinding-resolver": "0.18.0",
"link": "0.22.0",
"markdown-preview": "0.76.0",
"markdown-preview": "0.82.0",
"metrics": "0.32.0",
"open-on-github": "0.28.0",
"package-generator": "0.30.0",
"package-generator": "0.31.0",
"release-notes": "0.32.0",
"settings-view": "0.121.0",
"settings-view": "0.127.0",
"snippets": "0.45.0",
"spell-check": "0.37.0",
"status-bar": "0.40.0",
"styleguide": "0.29.0",
"symbols-view": "0.55.0",
"symbols-view": "0.56.0",
"tabs": "0.41.0",
"timecop": "0.19.0",
"tree-view": "0.100.0",
"tree-view": "0.103.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.16.0",
"whitespace": "0.22.0",
"wrap-guide": "0.18.0",
"language-c": "0.17.0",
"language-c": "0.18.0",
"language-coffee-script": "0.22.0",
"language-css": "0.17.0",
"language-gfm": "0.39.0",
@@ -125,7 +125,7 @@
"language-php": "0.15.0",
"language-property-list": "0.7.0",
"language-python": "0.18.0",
"language-ruby": "0.27.0",
"language-ruby": "0.29.0",
"language-ruby-on-rails": "0.14.0",
"language-sass": "0.13.0",
"language-shellscript": "0.8.0",
@@ -135,7 +135,7 @@
"language-todo": "0.10.0",
"language-toml": "0.12.0",
"language-xml": "0.14.0",
"language-yaml": "0.6.0"
"language-yaml": "0.7.0"
},
"private": true,
"scripts": {

View File

@@ -10,6 +10,8 @@ function executeCommands(commands, done, index) {
index = (index == undefined ? 0 : index);
if (index < commands.length) {
var command = commands[index];
if (command.message)
console.log(command.message);
var options = null;
if (typeof command !== 'string') {
options = command.options;
@@ -36,12 +38,10 @@ function bootstrap() {
var npmFlags = ' --userconfig=' + path.resolve('.npmrc') + ' ';
var packagesToDedupe = ['fs-plus', 'humanize-plus', 'oniguruma', 'roaster', 'season', 'grim'];
var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo';
var commands = [
{command: initialNpmCommand + npmFlags + 'install --quiet', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
{command: npmPath + npmFlags + 'install --quiet', options: {cwd: apmInstallPath, ignoreStdout: true}},
echoNewLine,
{command: initialNpmCommand + npmFlags + 'install --quiet', message: 'Installing build modules...', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
{command: npmPath + npmFlags + 'install --quiet', message: 'Installing apm...', options: {cwd: apmInstallPath, ignoreStdout: true}},
apmPath + ' clean ' + apmFlags,
apmPath + ' install --quiet ' + apmFlags,
apmPath + ' dedupe --quiet ' + apmFlags + ' ' + packagesToDedupe.join(' '),

View File

@@ -19,12 +19,18 @@ function loadEnvironmentVariables(filePath) {
var value = parts[1].trim().substr(1, parts[1].length - 2);
process.env[key] = value;
}
} catch(error) { }
} catch(error) {
console.error("Failed to load environment variables: " + filePath, error.code);
}
}
function readEnvironmentVariables() {
loadEnvironmentVariables('/var/lib/jenkins/config/atomcredentials')
loadEnvironmentVariables('/var/lib/jenkins/config/xcodekeychain')
if (process.platform === 'win32')
loadEnvironmentVariables(path.resolve('/jenkins/config/atomcredentials'));
else {
loadEnvironmentVariables('/var/lib/jenkins/config/atomcredentials');
loadEnvironmentVariables('/var/lib/jenkins/config/xcodekeychain');
}
}
readEnvironmentVariables();

View File

@@ -2,6 +2,7 @@ path = require 'path'
_ = require 'underscore-plus'
{convertStackTrace} = require 'coffeestack'
{View, $, $$} = require '../src/space-pen-extensions'
grim = require 'grim'
sourceMaps = {}
formatStackTrace = (spec, message='', stackTrace) ->
@@ -52,6 +53,11 @@ class AtomReporter extends View
@div outlet: "message", class: 'message'
@div outlet: "results", class: 'results'
@div outlet: "deprecations", class: 'status alert alert-warning', style: 'display: none', =>
@span outlet: 'deprecationStatus', '0 deprecations'
@div class: 'deprecation-toggle'
@div outlet: 'deprecationList', class: 'deprecation-list'
startedAt: null
runningSpecCount: 0
completeSpecCount: 0
@@ -59,6 +65,7 @@ class AtomReporter extends View
failedCount: 0
skippedCount: 0
totalSpecCount: 0
deprecationCount: 0
@timeoutId: 0
reportRunnerStarting: (runner) ->
@@ -88,6 +95,29 @@ class AtomReporter extends View
reportSpecStarting: (spec) ->
@specStarted(spec)
addDeprecations: (spec) ->
deprecations = grim.getDeprecations()
@deprecationCount += deprecations.length
@deprecations.show() if @deprecationCount > 0
if @deprecationCount is 1
@deprecationStatus.text("1 deprecation")
else
@deprecationStatus.text("#{@deprecationCount} deprecations")
for deprecation in deprecations
@deprecationList.append $$ ->
@div class: 'padded', =>
@div class: 'result-message fail deprecation-message', deprecation.message
for stack in deprecation.stacks
fullStack = stack.map ({functionName, location}) ->
if functionName is '<unknown>'
" at #{location}"
else
" at #{functionName} (#{location})"
@pre class: 'stack-trace padded', formatStackTrace(spec, deprecation.message, fullStack.join('\n'))
grim.clearDeprecations()
handleEvents: ->
$(document).on "click", ".spec-toggle", ({currentTarget}) =>
element = $(currentTarget)
@@ -96,6 +126,13 @@ class AtomReporter extends View
element.toggleClass('folded')
false
$(document).on "click", ".deprecation-toggle", ({currentTarget}) =>
element = $(currentTarget)
deprecationList = $(document).find('.deprecation-list')
deprecationList.toggle()
element.toggleClass('folded')
false
updateSpecCounts: ->
if @skippedCount
specCount = "#{@completeSpecCount - @skippedCount}/#{@totalSpecCount - @skippedCount} (#{@skippedCount} skipped)"
@@ -175,6 +212,7 @@ class AtomReporter extends View
specView = new SpecResultView(spec)
specView.attach()
@failedCount++
@addDeprecations(spec)
class SuiteResultView extends View
@content: ->

View File

@@ -1199,28 +1199,31 @@ describe "EditorComponent", ->
beforeEach ->
inputNode = node.querySelector('.hidden-input')
buildTextInputEvent = ({data, target}) ->
event = new Event('textInput')
event.data = data
Object.defineProperty(event, 'target', get: -> target)
event
it "inserts the newest character in the input's value into the buffer", ->
inputNode.value = 'x'
inputNode.dispatchEvent(new Event('input'))
node.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'xvar quicksort = function () {'
inputNode.value = 'xy'
inputNode.dispatchEvent(new Event('input'))
node.dispatchEvent(buildTextInputEvent(data: 'y', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'xyvar quicksort = function () {'
it "replaces the last character if the length of the input's value doesn't increase, as occurs with the accented character menu", ->
inputNode.value = 'u'
inputNode.dispatchEvent(new Event('input'))
node.dispatchEvent(buildTextInputEvent(data: 'u', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'uvar quicksort = function () {'
inputNode.value = 'ü'
inputNode.dispatchEvent(new Event('input'))
# simulate the accented character suggestion's selection of the previous character
inputNode.setSelectionRange(0, 1)
node.dispatchEvent(buildTextInputEvent(data: 'ü', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'üvar quicksort = function () {'
it "does not handle input events when input is disabled", ->
component.setInputEnabled(false)
inputNode.value = 'x'
inputNode.dispatchEvent(new Event('input'))
node.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'
describe "commands", ->

View File

@@ -114,9 +114,10 @@ class Cursor extends Model
# Public: Get the RegExp used by the cursor to determine what a "word" is.
#
# options: An {Object} with the following keys:
# options: An optional {Object} with the following keys:
# :includeNonWordCharacters - A {Boolean} indicating whether to include
# non-word characters in the regex.
# (default: true)
#
# Returns a {RegExp}.
wordRegExp: ({includeNonWordCharacters}={})->

View File

@@ -84,7 +84,6 @@ EditorComponent = React.createClass
ref: 'input'
className: 'hidden-input'
style: hiddenInputStyle
onInput: @onInput
onFocus: @onInputFocused
onBlur: @onInputBlurred
@@ -268,6 +267,7 @@ EditorComponent = React.createClass
node = @getDOMNode()
node.addEventListener 'mousewheel', @onMouseWheel
node.addEventListener 'focus', @onFocus # For some reason, React's built in focus events seem to bubble
node.addEventListener 'textInput', @onTextInput
scrollViewNode = @refs.scrollView.getDOMNode()
scrollViewNode.addEventListener 'scroll', @onScrollViewScroll
@@ -393,6 +393,26 @@ EditorComponent = React.createClass
onFocus: ->
@refs.input.focus()
onTextInput: (event) ->
return unless @isInputEnabled()
{editor} = @props
inputNode = event.target
# Work around of the accented character suggestion feature in OS X.
# Text input fires before a character is inserted, and if the browser is
# replacing the previous un-accented character with an accented variant, it
# will select backward over it.
selectedLength = inputNode.selectionEnd - inputNode.selectionStart
editor.selectLeft() if selectedLength is 1
editor.insertText(event.data)
inputNode.value = event.data
# If we prevent the insertion of a space character, then the browser
# interprets the spacebar keypress as a page-down command.
event.preventDefault() unless event.data is ' '
onInputFocused: ->
@setState(focused: true)
@@ -453,19 +473,9 @@ EditorComponent = React.createClass
scrollViewNode.scrollTop = 0
scrollViewNode.scrollLeft = 0
onInput: (char, replaceLastCharacter) ->
return unless @inputEnabled
{editor} = @props
if replaceLastCharacter
editor.transact ->
editor.selectLeft()
editor.insertText(char)
else
editor.insertText(char)
onMouseDown: (event) ->
return unless event.button is 0 # only handle the left mouse button
{editor} = @props
{detail, shiftKey, metaKey} = event
screenPosition = @screenPositionForMouseEvent(event)

View File

@@ -368,6 +368,8 @@ class EditorView extends View
false if @isFocused
@overlayer.on 'mousedown', (e) =>
return unless e.which is 1 # only handle the left mouse button
@overlayer.hide()
clickedElement = document.elementFromPoint(e.pageX, e.pageY)
@overlayer.show()
@@ -567,7 +569,7 @@ class EditorView extends View
@scrollTop(scrollTop)
@subscribe @editor, 'scroll-left-changed', (scrollLeft) =>
@scrollLeft(scrollLeft)
@scrollView.scrollLeft(scrollLeft)
@subscribe @editor, 'soft-wrap-changed', (softWrap) =>
@setSoftWrap(softWrap)

View File

@@ -1,4 +1,3 @@
punycode = require 'punycode'
{last, isEqual} = require 'underscore-plus'
React = require 'react-atom-fork'
{input} = require 'reactionary-atom-fork'
@@ -17,7 +16,6 @@ InputComponent = React.createClass
componentDidMount: ->
@getDOMNode().addEventListener 'paste', @onPaste
@getDOMNode().addEventListener 'input', @onInput
@getDOMNode().addEventListener 'compositionupdate', @onCompositionUpdate
# Don't let text accumulate in the input forever, but avoid excessive reflows
@@ -36,15 +34,6 @@ InputComponent = React.createClass
onPaste: (e) ->
e.preventDefault()
onInput: (e) ->
e.stopPropagation()
valueCharCodes = punycode.ucs2.decode(@getDOMNode().value)
valueLength = valueCharCodes.length
replaceLastChar = valueLength is @lastValueLength
@lastValueLength = valueLength
lastChar = String.fromCharCode(last(valueCharCodes))
@props.onInput?(lastChar, replaceLastChar)
onFocus: ->
@props.onFocus?()

View File

@@ -135,6 +135,10 @@ body {
padding: 5px 0 5px 0;
}
.result-message.deprecation-message {
color: #f0ad4e;
}
.stack-trace {
font-size: 12px;
margin: 5px 0 0 0;
@@ -174,4 +178,24 @@ body {
// overflow: hidden;
}
}
.deprecation-toggle {
.octicon(fold);
float: right;
cursor: pointer;
opacity: 0;
color: #999;
&.folded {
.octicon(unfold);
}
}
.deprecation-toggle:hover {
color: #333;
}
&:hover .deprecation-toggle {
opacity: 1;
}
}