Merge remote-tracking branch 'origin/master' into cj-add-user-keymap-file

This commit is contained in:
probablycorey
2013-10-28 10:04:48 -07:00
11 changed files with 128 additions and 69 deletions

View File

@@ -23,8 +23,7 @@
"guid": "0.0.10",
"jasmine-focused": "~0.15.0",
"mkdirp": "0.3.5",
"less": "git://github.com/nathansobo/less.js.git",
"less-cache": "0.8.0",
"less-cache": "0.9.0",
"nslog": "0.1.0",
"oniguruma": "0.21.0",
"optimist": "0.4.0",
@@ -52,7 +51,7 @@
"grunt-cson": "0.5.0",
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-less": "~0.6.4",
"grunt-contrib-less": "~0.8.0",
"walkdir": "0.0.7",
"ws": "0.4.27",
"js-yaml": "~2.1.0",

View File

@@ -34,7 +34,7 @@ var commands = [
joinCommands('cd vendor/apm', 'npm install --silent .'),
'npm install --silent vendor/apm',
echoNewLine,
'node vendor/apm/bin/apm install --silent',
'node node_modules/.bin/apm install --silent'
];
checkDependencies()

View File

@@ -10,31 +10,31 @@ if (process.platform != 'darwin')
var homeDir = process.platform == 'win32' ? process.env.USERPROFILE : process.env.HOME;
function readEnvironmentVariables(callback) {
var credenticalsPath = '/var/lib/jenkins/config/atomcredentials';
fs.readFile(credenticalsPath, function(error, data) {
if (!error) {
var lines = String(data).trim().split('\n');
for (i in lines) {
var parts = lines[i].split('=');
var key = parts[0].trim();
var value = parts[1].trim().substr(1, parts[1].length - 2);
process.env[key] = value;
}
function readEnvironmentVariables() {
var credentialsPath = '/var/lib/jenkins/config/atomcredentials';
try {
var credentials = fs.readFileSync(credentialsPath, 'utf8');
var lines = credentials.trim().split('\n');
for (i in lines) {
var parts = lines[i].split('=');
var key = parts[0].trim();
var value = parts[1].trim().substr(1, parts[1].length - 2);
process.env[key] = value;
}
// Do not quit when got error.
callback(null);
});
} catch(error) { }
}
var async = require('async');
async.series([
readEnvironmentVariables,
cp.safeExec.bind(global, 'node script/bootstrap'),
require('rimraf').bind(global, path.join(homeDir, '.atom')),
cp.safeExec.bind(global, 'git clean -dff'),
cp.safeExec.bind(global, 'node node_modules/.bin/apm clean'),
cp.safeExec.bind(global, 'node node_modules/.bin/grunt ci --stack --no-color'),
], function(error) {
process.exit(error ? 1 : 0);
});
readEnvironmentVariables();
cp.safeExec.bind(global, 'node script/bootstrap', function(error) {
if (error)
process.exit(1);
var async = require('async');
async.series([
require('rimraf').bind(global, path.join(homeDir, '.atom')),
cp.safeExec.bind(global, 'git clean -dff'),
cp.safeExec.bind(global, 'node node_modules/.bin/apm clean'),
cp.safeExec.bind(global, 'node node_modules/.bin/grunt ci --stack --no-color'),
], function(error) {
process.exit(error ? 1 : 0);
});
})();

View File

@@ -32,6 +32,18 @@ describe "LanguageMode", ->
expect(buffer.lineForRow(6)).toBe " // current < pivot ? left.push(current) : right.push(current);"
expect(buffer.lineForRow(7)).toBe " // }"
buffer.setText('\tvar i;')
languageMode.toggleLineCommentsForBufferRows(0, 0)
expect(buffer.lineForRow(0)).toBe "\t// var i;"
buffer.setText('var i;')
languageMode.toggleLineCommentsForBufferRows(0, 0)
expect(buffer.lineForRow(0)).toBe "// var i;"
buffer.setText(' var i;')
languageMode.toggleLineCommentsForBufferRows(0, 0)
expect(buffer.lineForRow(0)).toBe " // var i;"
describe "fold suggestion", ->
describe ".doesBufferRowStartFold(bufferRow)", ->
it "returns true only when the buffer row starts a foldable region", ->

View File

@@ -5,7 +5,6 @@ describe "TextBuffer replication", ->
beforeEach ->
buffer1 = project.buildBufferSync('sample.js')
buffer1.insert([0, 0], 'changed\n')
doc1 = buffer1.getState()
doc2 = doc1.clone(new Site(2))
doc1.connect(doc2)
@@ -14,6 +13,9 @@ describe "TextBuffer replication", ->
waitsFor ->
buffer1.loaded and buffer2.loaded
runs ->
buffer1.insert([0, 0], 'changed\n')
afterEach ->
buffer1.destroy()
buffer2.destroy()

View File

@@ -949,24 +949,48 @@ describe 'TextBuffer', ->
expect(buffer2.getText()).toBe(buffer.getText())
describe "when the serialized buffer had unsaved changes", ->
it "restores the previous unsaved state of the buffer", ->
previousText = buffer.getText()
buffer.setText("abc")
describe "when the disk contents were changed since serialization", ->
it "loads the disk contents instead of the previous unsaved state", ->
buffer.release()
state = buffer.serialize()
expect(state.getObject('text')).toBe 'abc'
filePath = temp.openSync('atom').path
fs.writeSync(filePath, "words")
{buffer} = project.openSync(filePath)
buffer.setText("BUFFER CHANGE")
buffer2 = deserialize(state, {project})
state = buffer.serialize()
expect(state.getObject('text')).toBe 'BUFFER CHANGE'
fs.writeSync(filePath, "DISK CHANGE")
waitsFor ->
buffer2.cachedDiskContents
buffer2 = deserialize(state, {project})
runs ->
expect(buffer2.getPath()).toBe(buffer.getPath())
expect(buffer2.getText()).toBe(buffer.getText())
expect(buffer2.isModified()).toBeTruthy()
buffer2.setText(previousText)
expect(buffer2.isModified()).toBeFalsy()
waitsFor ->
buffer2.cachedDiskContents
runs ->
expect(buffer2.getPath()).toBe(buffer.getPath())
expect(buffer2.getText()).toBe("DISK CHANGE")
expect(buffer2.isModified()).toBeFalsy()
describe "when the disk contents are the same since serialization", ->
it "restores the previous unsaved state of the buffer", ->
previousText = buffer.getText()
buffer.setText("abc")
state = buffer.serialize()
expect(state.getObject('text')).toBe 'abc'
buffer2 = deserialize(state, {project})
waitsFor ->
buffer2.cachedDiskContents
runs ->
expect(buffer2.getPath()).toBe(buffer.getPath())
expect(buffer2.getText()).toBe(buffer.getText())
expect(buffer2.isModified()).toBeTruthy()
buffer2.setText(previousText)
expect(buffer2.isModified()).toBeFalsy()
describe "when the serialized buffer was unsaved and had no path", ->
it "restores the previous unsaved state of the buffer", ->

View File

@@ -350,7 +350,8 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains surrogate pairs", ->
beforeEach ->
atom.activatePackage('language-javascript', sync: true)
buffer = project.buildBufferSync 'sample-with-pairs.js', """
buffer = project.buildBufferSync 'sample-with-pairs.js'
buffer.setText """
'abc\uD835\uDF97def'
//\uD835\uDF97xyz
"""
@@ -389,7 +390,8 @@ describe "TokenizedBuffer", ->
atom.activatePackage('language-ruby-on-rails', sync: true)
atom.activatePackage('language-ruby', sync: true)
buffer = project.bufferForPathSync(null, "<div class='name'><%= User.find(2).full_name %></div>")
buffer = project.bufferForPathSync()
buffer.setText "<div class='name'><%= User.find(2).full_name %></div>"
tokenizedBuffer = new TokenizedBuffer({buffer})
tokenizedBuffer.setGrammar(syntax.selectGrammar('test.erb'))
fullyTokenize(tokenizedBuffer)

View File

@@ -1,3 +1,4 @@
crypto = require 'crypto'
path = require 'path'
pathWatcher = require 'pathwatcher'
Q = require 'q'
@@ -68,6 +69,9 @@ class File
else
@cachedContents
@setDigest(@cachedContents)
@cachedContents
# Public: Reads the contents of the file.
#
# * flushCache:
@@ -101,12 +105,19 @@ class File
promise = Q(@cachedContents)
promise.then (contents) =>
@setDigest(contents)
@cachedContents = contents
# Public: Returns whether the file exists.
exists: ->
fsUtils.exists(@getPath())
setDigest: (contents) ->
@digest = crypto.createHash('sha1').update(contents ? '').digest('hex')
getDigest: ->
@digest ? @setDigest(@readSync())
# Private:
handleNativeChangeEvent: (eventType, path) ->
if eventType is "delete"

View File

@@ -84,8 +84,14 @@ class LanguageMode
else
indent = @minIndentLevelForRowRange(start, end)
indentString = @editSession.buildIndentString(indent)
tabLength = @editSession.getTabLength()
indentRegex = new RegExp("(\t|[ ]{#{tabLength}}){#{Math.floor(indent)}}")
for row in [start..end]
buffer.change([[row, 0], [row, indentString.length]], indentString + commentStartString)
line = buffer.lineForRow(row)
if indentLength = line.match(indentRegex)?[0].length
buffer.insert([row, indentLength], commentStartString)
else
buffer.change([[row, 0], [row, indentString.length]], indentString + commentStartString)
# Folds all the foldable lines in the buffer.
foldAll: ->

View File

@@ -224,13 +224,13 @@ class Project
existingBuffer?.isModified()
# Private: Only to be used in specs
bufferForPathSync: (filePath, text) ->
bufferForPathSync: (filePath) ->
absoluteFilePath = @resolve(filePath)
if filePath
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
existingBuffer ? @buildBufferSync(absoluteFilePath, text)
existingBuffer ? @buildBufferSync(absoluteFilePath)
# Private: Given a file path, this retrieves or creates a new {TextBuffer}.
#
@@ -238,23 +238,22 @@ class Project
# `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 a promise that resolves to the {TextBuffer}.
bufferForPath: (filePath, text) ->
bufferForPath: (filePath) ->
absoluteFilePath = @resolve(filePath)
if absoluteFilePath
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
Q(existingBuffer ? @buildBuffer(absoluteFilePath, text))
Q(existingBuffer ? @buildBuffer(absoluteFilePath))
# Private:
bufferForId: (id) ->
_.find @buffers, (buffer) -> buffer.id is id
# Private: DEPRECATED
buildBufferSync: (absoluteFilePath, initialText) ->
buffer = new TextBuffer({project: this, filePath: absoluteFilePath, initialText})
buildBufferSync: (absoluteFilePath) ->
buffer = new TextBuffer({project: this, filePath: absoluteFilePath})
buffer.loadSync()
@addBuffer(buffer)
buffer
@@ -265,8 +264,8 @@ class Project
# text - The {String} text to use as a buffer
#
# Returns a promise that resolves to the {TextBuffer}.
buildBuffer: (absoluteFilePath, initialText) ->
buffer = new TextBuffer({project: this, filePath: absoluteFilePath, initialText})
buildBuffer: (absoluteFilePath) ->
buffer = new TextBuffer({project: this, filePath: absoluteFilePath})
buffer.load().then (buffer) =>
@addBuffer(buffer)
buffer

View File

@@ -1,3 +1,4 @@
crypto = require 'crypto'
{Emitter, Subscriber} = require 'emissary'
guid = require 'guid'
Q = require 'q'
@@ -38,8 +39,8 @@ class TextBuffer
# Creates a new buffer.
#
# path - A {String} representing the file path
# initialText - A {String} setting the starting text
# * optionsOrState - An {Object} or a telepath.Document
# + filePath - A {String} representing the file path
constructor: (optionsOrState={}, params={}) ->
if optionsOrState instanceof telepath.Document
{@project} = params
@@ -47,9 +48,9 @@ class TextBuffer
@id = @state.get('id')
filePath = @state.get('relativePath')
@text = @state.get('text')
@loadFromDisk = @state.get('isModified') == false
@useSerializedText = @state.get('isModified') != false
else
{@project, filePath, initialText} = optionsOrState
{@project, filePath} = optionsOrState
@text = site.createDocument(initialText ? '', shareStrings: true)
@id = guid.create().toString()
@state = site.createDocument
@@ -57,7 +58,6 @@ class TextBuffer
deserializer: @constructor.name
version: @constructor.version
text: @text
@loadFromDisk = not initialText
@loaded = false
@subscribe @text, 'changed', @handleTextChange
@@ -68,14 +68,19 @@ class TextBuffer
loadSync: ->
@updateCachedDiskContentsSync()
@reload() if @loadFromDisk
@text.clearUndoStack()
@finishLoading()
load: ->
@updateCachedDiskContents().then =>
@reload() if @loadFromDisk
@text.clearUndoStack()
this
@updateCachedDiskContents().then => @finishLoading()
finishLoading: ->
@loaded = true
if @useSerializedText and @state.get('diskContentsDigest') == @file?.getDigest()
@emitModifiedStatusChanged(true)
else
@reload()
@text.clearUndoStack()
this
### Internal ###
@@ -108,6 +113,7 @@ class TextBuffer
serialize: ->
state = @state.clone()
state.set('isModified', @isModified())
state.set('diskContentsDigest', @file.getDigest()) if @file
for marker in state.get('text').getMarkers() when marker.isRemote()
marker.destroy()
state
@@ -158,13 +164,11 @@ class TextBuffer
# Private: Rereads the contents of the file, and stores them in the cache.
updateCachedDiskContentsSync: ->
@loaded = true
@cachedDiskContents = @file?.readSync() ? ""
# Private: Rereads the contents of the file, and stores them in the cache.
updateCachedDiskContents: ->
Q(@file?.read() ? "").then (contents) =>
@loaded = true
@cachedDiskContents = contents
# Gets the file's basename--that is, the file without any directory information.