mirror of
https://github.com/atom/atom.git
synced 2026-01-23 22:08:08 -05:00
Merge remote-tracking branch 'origin/master' into win-bootstrap-native-modules
This commit is contained in:
10
package.json
10
package.json
@@ -75,13 +75,13 @@
|
||||
"autoflow": "0.5.0",
|
||||
"bookmarks": "0.8.0",
|
||||
"bracket-matcher": "0.7.0",
|
||||
"collaboration": "0.28.0",
|
||||
"collaboration": "0.30.0",
|
||||
"command-logger": "0.6.0",
|
||||
"command-palette": "0.5.0",
|
||||
"command-palette": "0.6.0",
|
||||
"dev-live-reload": "0.11.0",
|
||||
"editor-stats": "0.5.0",
|
||||
"exception-reporting": "0.5.0",
|
||||
"find-and-replace": "0.31.0",
|
||||
"find-and-replace": "0.32.0",
|
||||
"fuzzy-finder": "0.15.0",
|
||||
"gfm": "0.5.0",
|
||||
"git-diff": "0.12.0",
|
||||
@@ -106,7 +106,7 @@
|
||||
"timecop": "0.7.0",
|
||||
"to-the-hubs": "0.8.0",
|
||||
"toml": "0.3.0",
|
||||
"tree-view": "0.20.0",
|
||||
"tree-view": "0.21.0",
|
||||
"visual-bell": "0.3.0",
|
||||
"whitespace": "0.7.0",
|
||||
"wrap-guide": "0.4.0",
|
||||
@@ -120,7 +120,7 @@
|
||||
"language-html": "0.1.0",
|
||||
"language-hyperlink": "0.2.0",
|
||||
"language-java": "0.1.0",
|
||||
"language-javascript": "0.1.0",
|
||||
"language-javascript": "0.2.0",
|
||||
"language-json": "0.1.0",
|
||||
"language-less": "0.1.0",
|
||||
"language-make": "0.1.0",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
var safeExec = require('./utils/child-process-wrapper.js').safeExec;
|
||||
var exec = require('child_process').exec;
|
||||
var path = require('path');
|
||||
|
||||
// Executes an array of commands one by one.
|
||||
@@ -17,6 +18,15 @@ function joinCommands() {
|
||||
return Array.prototype.slice.call(arguments, 0).join(commandSeparator);
|
||||
}
|
||||
|
||||
function checkDependencies() {
|
||||
exec("cmake -h", function(error) {
|
||||
if (error) {
|
||||
console.error("Error: cmake is required to build Atom.")
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo';
|
||||
var commands = [
|
||||
'git submodule --quiet sync',
|
||||
@@ -27,5 +37,6 @@ var commands = [
|
||||
'node vendor/apm/bin/apm install --silent',
|
||||
];
|
||||
|
||||
checkDependencies()
|
||||
process.chdir(path.dirname(__dirname));
|
||||
executeCommands(commands, process.exit);
|
||||
|
||||
@@ -8,7 +8,7 @@ set -ex
|
||||
cd "$(dirname "$0")/../.."
|
||||
rm -fr node_modules
|
||||
./script/bootstrap
|
||||
./node_modules/.bin/grunt --build-dir="$BUILT_PRODUCTS_DIR" deploy
|
||||
./node_modules/.bin/grunt --no-color --build-dir="$BUILT_PRODUCTS_DIR" deploy
|
||||
|
||||
echo "TARGET_BUILD_DIR=$BUILT_PRODUCTS_DIR"
|
||||
echo "FULL_PRODUCT_NAME=Atom.app"
|
||||
|
||||
@@ -300,7 +300,7 @@ class AtomApplication
|
||||
if pack.urlMain
|
||||
packagePath = @packages.resolvePackagePath(packageName)
|
||||
bootstrapScript = path.resolve(packagePath, pack.urlMain)
|
||||
new AtomWindow({bootstrapScript, @resourcePath, devMode, urlToOpen, initialSize: getFocusedWindowSize()})
|
||||
new AtomWindow({bootstrapScript, @resourcePath, devMode, urlToOpen, initialSize: @getFocusedWindowSize()})
|
||||
else
|
||||
console.log "Package '#{pack.name}' does not have a url main: #{urlToOpen}"
|
||||
else
|
||||
|
||||
@@ -1,23 +1,46 @@
|
||||
BufferedProcess = require './buffered-process'
|
||||
path = require 'path'
|
||||
|
||||
# Public: Like BufferedProcess, but accepts a node script instead of an
|
||||
# executable, on Unix which allows running scripts and executables, this seems
|
||||
# unnecessary, but on Windows we have to separate scripts from executables since
|
||||
# it doesn't support shebang strings.
|
||||
# Public: Like {BufferedProcess}, but accepts a Node script instead of an
|
||||
# executable.
|
||||
#
|
||||
# This may seem unnecessary but on Windows we have to have separate executables
|
||||
# for each script without this since Windows doesn't support shebang strings.
|
||||
module.exports =
|
||||
class BufferedNodeProcess extends BufferedProcess
|
||||
# Executes the given Node script.
|
||||
#
|
||||
# * options
|
||||
# + command:
|
||||
# The path to the Javascript script to execute.
|
||||
# + args:
|
||||
# The array of arguments to pass to the script (optional).
|
||||
# + options:
|
||||
# The options Object to pass to Node's `ChildProcess.spawn` (optional).
|
||||
# + stdout:
|
||||
# The callback that receives a single argument which contains the
|
||||
# standard output of the script. The callback is called as data is
|
||||
# received but it's buffered to ensure only complete lines are passed
|
||||
# until the source stream closes. After the source stream has closed
|
||||
# all remaining data is sent in a final call (optional).
|
||||
# + stderr:
|
||||
# The callback that receives a single argument which contains the
|
||||
# standard error of the script. The callback is called as data is
|
||||
# received but it's buffered to ensure only complete lines are passed
|
||||
# until the source stream closes. After the source stream has closed
|
||||
# all remaining data is sent in a final call (optional).
|
||||
# + exit:
|
||||
# The callback which receives a single argument containing the exit
|
||||
# status (optional).
|
||||
constructor: ({command, args, options, stdout, stderr, exit}) ->
|
||||
node =
|
||||
if process.platform is 'darwin'
|
||||
# On OS X we use the helper process to run script, because it doesn't
|
||||
# create an icon on the Dock.
|
||||
# Use a helper to prevent an icon from appearing on the Dock
|
||||
path.resolve(process.resourcesPath, '..', 'Frameworks',
|
||||
'Atom Helper.app', 'Contents', 'MacOS', 'Atom Helper')
|
||||
else
|
||||
process.execPath
|
||||
|
||||
# Tell atom-shell to run like upstream node.
|
||||
options ?= {}
|
||||
options.env ?= Object.create(process.env)
|
||||
options.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = 1
|
||||
|
||||
@@ -1,28 +1,35 @@
|
||||
ChildProcess = require 'child_process'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
# Public: A wrapper which provides buffering for ChildProcess.
|
||||
# Public: A wrapper which provides line buffering for Node's ChildProcess.
|
||||
module.exports =
|
||||
class BufferedProcess
|
||||
process: null
|
||||
killed: false
|
||||
|
||||
# Executes the given command.
|
||||
# Executes the given executable.
|
||||
#
|
||||
# * options
|
||||
# + command:
|
||||
# The command to execute.
|
||||
# The path to the executable to execute.
|
||||
# + args:
|
||||
# The arguments for the given command.
|
||||
# The array of arguments to pass to the script (optional).
|
||||
# + options:
|
||||
# The options to pass to ChildProcess.
|
||||
# The options Object to pass to Node's `ChildProcess.spawn` (optional).
|
||||
# + stdout:
|
||||
# The callback to receive stdout data.
|
||||
# The callback that receives a single argument which contains the
|
||||
# standard output of the script. The callback is called as data is
|
||||
# received but it's buffered to ensure only complete lines are passed
|
||||
# until the source stream closes. After the source stream has closed
|
||||
# all remaining data is sent in a final call (optional).
|
||||
# + stderr:
|
||||
# The callback to receive stderr data.
|
||||
# The callback that receives a single argument which contains the
|
||||
# standard error of the script. The callback is called as data is
|
||||
# received but it's buffered to ensure only complete lines are passed
|
||||
# until the source stream closes. After the source stream has closed
|
||||
# all remaining data is sent in a final call (optional).
|
||||
# + exit:
|
||||
# The callback to receive exit status.
|
||||
# The callback which receives a single argument containing the exit
|
||||
# status (optional).
|
||||
constructor: ({command, args, options, stdout, stderr, exit}={}) ->
|
||||
options ?= {}
|
||||
@process = ChildProcess.spawn(command, args, options)
|
||||
|
||||
@@ -211,12 +211,12 @@ class Config
|
||||
previousValue = _.clone(value)
|
||||
callback(value, {previous})
|
||||
|
||||
subscription = { cancel: => @off 'updated', updateCallback }
|
||||
@on "updated.#{keyPath.replace(/\./, '-')}", updateCallback
|
||||
eventName = "updated.#{keyPath.replace(/\./, '-')}"
|
||||
subscription = { cancel: => @off eventName, updateCallback }
|
||||
@on eventName, updateCallback
|
||||
callback(value) if options.callNow ? true
|
||||
subscription
|
||||
|
||||
|
||||
# Public: Unobserve all callbacks on a given key
|
||||
#
|
||||
# keyPath - The {String} name of the key to unobserve
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
fsUtils = require './fs-utils'
|
||||
pathWatcher = require 'pathwatcher'
|
||||
@@ -13,40 +12,45 @@ class Directory
|
||||
path: null
|
||||
realPath: null
|
||||
|
||||
# Public: Configures an new Directory instance, no files are accessed.
|
||||
# Public: Configures a new Directory instance, no files are accessed.
|
||||
#
|
||||
# * path:
|
||||
# A {String} representing the file directory
|
||||
# A String containing the absolute path to the directory.
|
||||
# + symlink:
|
||||
# A {Boolean} indicating if the path is a symlink
|
||||
# A Boolean indicating if the path is a symlink (defaults to false).
|
||||
constructor: (@path, @symlink=false) ->
|
||||
@on 'first-contents-changed-subscription-will-be-added', =>
|
||||
# Triggered by emissary, when a new contents-changed listener attaches
|
||||
@subscribeToNativeChangeEvents()
|
||||
|
||||
@on 'last-contents-changed-subscription-removed', =>
|
||||
# Triggered by emissary, when the last contents-changed listener detaches
|
||||
@unsubscribeFromNativeChangeEvents()
|
||||
|
||||
# Public: Returns the basename of the directory.
|
||||
getBaseName: ->
|
||||
path.basename(@path)
|
||||
|
||||
# Public: Returns the directory's path.
|
||||
# Public: Returns the directory's symbolic path.
|
||||
#
|
||||
# FIXME what is the difference between real path and path?
|
||||
# This may include unfollowed symlinks or relative directory entries. Or it
|
||||
# may be fully resolved, it depends on what you give it.
|
||||
getPath: -> @path
|
||||
|
||||
# Public: Returns this directory's real path.
|
||||
# Public: Returns this directory's completely resolved path.
|
||||
#
|
||||
# FIXME what is the difference between real path and path?
|
||||
# All relative directory entries are removed and symlinks are resolved to
|
||||
# their final destination.
|
||||
getRealPath: ->
|
||||
unless @realPath?
|
||||
try
|
||||
@realPath = fs.realpathSync(@path)
|
||||
@realPath = fsUtils.realpathSync(@path)
|
||||
catch e
|
||||
@realPath = @path
|
||||
@realPath
|
||||
|
||||
# Public: Returns whether the given path is inside this directory.
|
||||
# Public: Returns whether the given path (real or symbolic) is inside this
|
||||
# directory.
|
||||
contains: (pathToCheck) ->
|
||||
return false unless pathToCheck
|
||||
|
||||
@@ -76,15 +80,15 @@ class Directory
|
||||
#
|
||||
# Note: It follows symlinks.
|
||||
#
|
||||
# Returns an {Array} of {Files}.
|
||||
# Returns an Array of {Files}.
|
||||
getEntries: ->
|
||||
directories = []
|
||||
files = []
|
||||
for entryPath in fsUtils.listSync(@path)
|
||||
try
|
||||
stat = fs.lstatSync(entryPath)
|
||||
stat = fsUtils.lstatSync(entryPath)
|
||||
symlink = stat.isSymbolicLink()
|
||||
stat = fs.statSync(entryPath) if symlink
|
||||
stat = fsUtils.statSync(entryPath) if symlink
|
||||
catch e
|
||||
continue
|
||||
if stat.isDirectory()
|
||||
|
||||
@@ -5,10 +5,10 @@ Q = require 'q'
|
||||
_ = require 'underscore-plus'
|
||||
fsUtils = require './fs-utils'
|
||||
|
||||
# Public: Represents an individual file in the editor.
|
||||
# Public: Represents an individual file.
|
||||
#
|
||||
# This class shouldn't be created directly, instead you should create a
|
||||
# {Directory} and access the {File} objects that it creates.
|
||||
# You should probably create a {Directory} and access the {File} objects that
|
||||
# it creates, rather than instantiating the {File} class directly.
|
||||
module.exports =
|
||||
class File
|
||||
Emitter.includeInto(this)
|
||||
@@ -16,10 +16,10 @@ class File
|
||||
path: null
|
||||
cachedContents: null
|
||||
|
||||
# Private: Creates a new file.
|
||||
# Public: Creates a new file.
|
||||
#
|
||||
# * path:
|
||||
# A String representing the file path
|
||||
# A String containing the absolute path to the file
|
||||
# * symlink:
|
||||
# A Boolean indicating if the path is a symlink (default: false)
|
||||
constructor: (@path, @symlink=false) ->
|
||||
@@ -27,15 +27,18 @@ class File
|
||||
|
||||
@handleEventSubscriptions()
|
||||
|
||||
# Private: Subscribes to file system notifications when necessary.
|
||||
handleEventSubscriptions: ->
|
||||
eventNames = ['contents-changed', 'moved', 'removed']
|
||||
|
||||
subscriptionsAdded = eventNames.map (eventName) -> "first-#{eventName}-subscription-will-be-added"
|
||||
@on subscriptionsAdded.join(' '), =>
|
||||
# Only subscribe when a listener of eventName attaches (triggered by emissary)
|
||||
@subscribeToNativeChangeEvents() if @exists()
|
||||
|
||||
subscriptionsRemoved = eventNames.map (eventName) -> "last-#{eventName}-subscription-removed"
|
||||
@on subscriptionsRemoved.join(' '), =>
|
||||
# Detach when the last listener of eventName detaches (triggered by emissary)
|
||||
subscriptionsEmpty = _.every eventNames, (eventName) => @getSubscriptionCount(eventName) is 0
|
||||
@unsubscribeFromNativeChangeEvents() if subscriptionsEmpty
|
||||
|
||||
@@ -100,7 +103,7 @@ class File
|
||||
promise.then (contents) =>
|
||||
@cachedContents = contents
|
||||
|
||||
# Public: Returns whether a file exists.
|
||||
# Public: Returns whether the file exists.
|
||||
exists: ->
|
||||
fsUtils.exists(@getPath())
|
||||
|
||||
|
||||
@@ -7,9 +7,22 @@ rimraf = require 'rimraf'
|
||||
path = require 'path'
|
||||
|
||||
# Public: Useful extensions to node's built-in fs module
|
||||
#
|
||||
# Important, this extends Node's builtin in ['fs' module][fs], which means that you
|
||||
# can do anything that you can do with Node's 'fs' module plus a few extra
|
||||
# functions that we've found to be helpful.
|
||||
#
|
||||
# [fs]: http://nodejs.org/api/fs.html
|
||||
fsExtensions =
|
||||
# Make the given path absolute by resolving it against the
|
||||
# current working directory.
|
||||
# Public: Make the given path absolute by resolving it against the current
|
||||
# working directory.
|
||||
#
|
||||
# * relativePath:
|
||||
# The String containing the relative path. If the path is prefixed with
|
||||
# '~', it will be expanded to the current user's home directory.
|
||||
#
|
||||
# Returns the absolute path or the relative path if it's unable to determine
|
||||
# it's realpath.
|
||||
absolute: (relativePath) ->
|
||||
return null unless relativePath?
|
||||
|
||||
@@ -25,11 +38,12 @@ fsExtensions =
|
||||
catch e
|
||||
relativePath
|
||||
|
||||
# Returns true if a file or folder at the specified path exists.
|
||||
# Public: Returns true if a file or folder at the specified path exists.
|
||||
exists: (pathToCheck) ->
|
||||
# TODO: rename to existsSync
|
||||
pathToCheck? and fs.statSyncNoException(pathToCheck) isnt false
|
||||
|
||||
# Returns true if the specified path is a directory that exists.
|
||||
# Public: Returns true if the given path exists and is a directory.
|
||||
isDirectorySync: (directoryPath) ->
|
||||
return false unless directoryPath?.length > 0
|
||||
if stat = fs.statSyncNoException(directoryPath)
|
||||
@@ -37,6 +51,7 @@ fsExtensions =
|
||||
else
|
||||
false
|
||||
|
||||
# Public: Asynchronously checks that the given path exists and is a directory.
|
||||
isDirectory: (directoryPath, done) ->
|
||||
return done(false) unless directoryPath?.length > 0
|
||||
fs.exists directoryPath, (exists) ->
|
||||
@@ -49,7 +64,7 @@ fsExtensions =
|
||||
else
|
||||
done(false)
|
||||
|
||||
# Returns true if the specified path is a regular file that exists.
|
||||
# Public: Returns true if the specified path exists and is a file.
|
||||
isFileSync: (filePath) ->
|
||||
return false unless filePath?.length > 0
|
||||
if stat = fs.statSyncNoException(filePath)
|
||||
@@ -57,7 +72,7 @@ fsExtensions =
|
||||
else
|
||||
false
|
||||
|
||||
# Returns true if the specified path is executable.
|
||||
# Public: Returns true if the specified path is executable.
|
||||
isExecutableSync: (pathToCheck) ->
|
||||
return false unless pathToCheck?.length > 0
|
||||
if stat = fs.statSyncNoException(pathToCheck)
|
||||
@@ -65,8 +80,14 @@ fsExtensions =
|
||||
else
|
||||
false
|
||||
|
||||
# Returns an array with the paths of the files and folders
|
||||
# contained in the directory path.
|
||||
# Public: Returns an Array with the paths of the files and directories
|
||||
# contained within the directory path. It is not recursive.
|
||||
#
|
||||
# * rootPath:
|
||||
# The absolute path to the directory to list.
|
||||
# * extensions:
|
||||
# An array of extensions to filter the results by. If none are given, none
|
||||
# are filtered (optional).
|
||||
listSync: (rootPath, extensions) ->
|
||||
return [] unless @isDirectorySync(rootPath)
|
||||
paths = fs.readdirSync(rootPath)
|
||||
@@ -74,6 +95,16 @@ fsExtensions =
|
||||
paths = paths.map (childPath) -> path.join(rootPath, childPath)
|
||||
paths
|
||||
|
||||
# Public: Asynchronously lists the files and directories in the given path.
|
||||
# The listing is not recursive.
|
||||
#
|
||||
# * rootPath:
|
||||
# The absolute path to the directory to list.
|
||||
# * extensions:
|
||||
# An array of extensions to filter the results by. If none are given, none
|
||||
# are filtered (optional)
|
||||
# * callback:
|
||||
# The function to call
|
||||
list: (rootPath, rest...) ->
|
||||
extensions = rest.shift() if rest.length > 1
|
||||
done = rest.shift()
|
||||
@@ -85,6 +116,7 @@ fsExtensions =
|
||||
paths = paths.map (childPath) -> path.join(rootPath, childPath)
|
||||
done(null, paths)
|
||||
|
||||
# Private: Returns only the paths which end with one of the given extensions.
|
||||
filterExtensions: (paths, extensions) ->
|
||||
extensions = extensions.map (ext) ->
|
||||
if ext is ''
|
||||
@@ -93,6 +125,7 @@ fsExtensions =
|
||||
'.' + ext.replace(/^\./, '')
|
||||
paths.filter (pathToCheck) -> _.include(extensions, path.extname(pathToCheck))
|
||||
|
||||
# Deprecated: No one currently uses this.
|
||||
listTreeSync: (rootPath) ->
|
||||
paths = []
|
||||
onPath = (childPath) ->
|
||||
@@ -101,22 +134,34 @@ fsExtensions =
|
||||
@traverseTreeSync(rootPath, onPath, onPath)
|
||||
paths
|
||||
|
||||
# Public: Moves the file or directory to the target synchronously.
|
||||
move: (source, target) ->
|
||||
# TODO: This should be renamed to moveSync
|
||||
fs.renameSync(source, target)
|
||||
|
||||
# Remove the file or directory at the given path.
|
||||
# Public: Removes the file or directory at the given path synchronously.
|
||||
remove: (pathToRemove) ->
|
||||
# TODO: This should be renamed to removeSync
|
||||
rimraf.sync(pathToRemove)
|
||||
|
||||
# Open, read, and close a file, returning the file's contents.
|
||||
# Public: Open, read, and close a file, returning the file's contents
|
||||
# synchronously.
|
||||
read: (filePath) ->
|
||||
# TODO: This should be renamed to readSync
|
||||
fs.readFileSync(filePath, 'utf8')
|
||||
|
||||
# Open, write, flush, and close a file, writing the given content.
|
||||
# Public: Open, write, flush, and close a file, writing the given content
|
||||
# synchronously.
|
||||
#
|
||||
# It also creates the necessary parent directories.
|
||||
writeSync: (filePath, content) ->
|
||||
mkdirp.sync(path.dirname(filePath))
|
||||
fs.writeFileSync(filePath, content)
|
||||
|
||||
# Public: Open, write, flush, and close a file, writing the given content
|
||||
# asynchronously.
|
||||
#
|
||||
# It also creates the necessary parent directories.
|
||||
write: (filePath, content, callback) ->
|
||||
mkdirp path.dirname(filePath), (error) ->
|
||||
if error?
|
||||
@@ -124,6 +169,7 @@ fsExtensions =
|
||||
else
|
||||
fs.writeFile(filePath, content, callback)
|
||||
|
||||
# Public: Copies the given path asynchronously.
|
||||
copy: (sourcePath, destinationPath, done) ->
|
||||
mkdirp path.dirname(destinationPath), (error) ->
|
||||
if error?
|
||||
@@ -145,11 +191,23 @@ fsExtensions =
|
||||
|
||||
sourceStream.pipe(destinationStream)
|
||||
|
||||
# Create a directory at the specified path including any missing parent
|
||||
# directories.
|
||||
# Public: Create a directory at the specified path including any missing
|
||||
# parent directories synchronously.
|
||||
makeTree: (directoryPath) ->
|
||||
# TODO: rename to makeTreeSync
|
||||
mkdirp.sync(directoryPath) if directoryPath and not @exists(directoryPath)
|
||||
|
||||
# Public: Recursively walk the given path and execute the given functions
|
||||
# synchronously.
|
||||
#
|
||||
# * rootPath:
|
||||
# The String containing the directory to recurse into.
|
||||
# * onFile:
|
||||
# The function to execute on each file, receives a single argument the
|
||||
# absolute path.
|
||||
# * onDirectory:
|
||||
# The function to execute on each directory, receives a single argument the
|
||||
# absolute path (defaults to onFile)
|
||||
traverseTreeSync: (rootPath, onFile, onDirectory=onFile) ->
|
||||
return unless @isDirectorySync(rootPath)
|
||||
|
||||
@@ -167,6 +225,17 @@ fsExtensions =
|
||||
|
||||
traverse(rootPath, onFile, onDirectory)
|
||||
|
||||
# Public: Recursively walk the given path and execute the given functions
|
||||
# asynchronously.
|
||||
#
|
||||
# * rootPath:
|
||||
# The String containing the directory to recurse into.
|
||||
# * onFile:
|
||||
# The function to execute on each file, receives a single argument the
|
||||
# absolute path.
|
||||
# * onDirectory:
|
||||
# The function to execute on each directory, receives a single argument the
|
||||
# absolute path (defaults to onFile)
|
||||
traverseTree: (rootPath, onFile, onDirectory, onDone) ->
|
||||
fs.readdir rootPath, (error, files) ->
|
||||
if error
|
||||
@@ -194,10 +263,28 @@ fsExtensions =
|
||||
queue.drain = onDone
|
||||
queue.push(path.join(rootPath, file)) for file in files
|
||||
|
||||
# Public: Hashes the contents of the given file.
|
||||
#
|
||||
# * pathToDigest:
|
||||
# The String containing the absolute path.
|
||||
#
|
||||
# Returns a String containing the MD5 hexadecimal hash.
|
||||
md5ForPath: (pathToDigest) ->
|
||||
contents = fs.readFileSync(pathToDigest)
|
||||
require('crypto').createHash('md5').update(contents).digest('hex')
|
||||
|
||||
# Public: Finds a relative path among the given array of paths.
|
||||
#
|
||||
# * loadPaths:
|
||||
# An Array of absolute and relative paths to search.
|
||||
# * pathToResolve:
|
||||
# The string containing the path to resolve.
|
||||
# * extensions:
|
||||
# An array of extensions to pass to {resolveExtensions} in which case
|
||||
# pathToResolve should not contain an extension (optional).
|
||||
#
|
||||
# Returns the absolute path of the file to be resolved if it's found and
|
||||
# undefined otherwise.
|
||||
resolve: (args...) ->
|
||||
extensions = args.pop() if _.isArray(_.last(args))
|
||||
pathToResolve = args.pop()
|
||||
@@ -218,10 +305,22 @@ fsExtensions =
|
||||
return @absolute(candidatePath) if @exists(candidatePath)
|
||||
undefined
|
||||
|
||||
# Deprecated:
|
||||
resolveOnLoadPath: (args...) ->
|
||||
loadPaths = Module.globalPaths.concat(module.paths)
|
||||
@resolve(loadPaths..., args...)
|
||||
|
||||
# Public: Finds the first file in the given path which matches the extension
|
||||
# in the order given.
|
||||
#
|
||||
# * pathToResolve:
|
||||
# The String containing relative or absolute path of the file in question
|
||||
# without the extension or '.'.
|
||||
# * extensions:
|
||||
# The ordered Array of extensions to try.
|
||||
#
|
||||
# Returns the absolute path of the file if it exists with any of the given
|
||||
# extensions, otherwise it's undefined.
|
||||
resolveExtension: (pathToResolve, extensions) ->
|
||||
for extension in extensions
|
||||
if extension == ""
|
||||
@@ -231,6 +330,7 @@ fsExtensions =
|
||||
return @absolute(pathWithExtension) if @exists(pathWithExtension)
|
||||
undefined
|
||||
|
||||
# Public: Returns true for extensions associated with compressed files.
|
||||
isCompressedExtension: (ext) ->
|
||||
_.indexOf([
|
||||
'.gz'
|
||||
@@ -240,6 +340,7 @@ fsExtensions =
|
||||
'.zip'
|
||||
], ext, true) >= 0
|
||||
|
||||
# Public: Returns true for extensions associated with image files.
|
||||
isImageExtension: (ext) ->
|
||||
_.indexOf([
|
||||
'.gif'
|
||||
@@ -249,9 +350,27 @@ fsExtensions =
|
||||
'.tiff'
|
||||
], ext, true) >= 0
|
||||
|
||||
# Public: Returns true for extensions associated with pdf files.
|
||||
isPdfExtension: (ext) ->
|
||||
ext is '.pdf'
|
||||
|
||||
# Public: Returns true for extensions associated with binary files.
|
||||
isBinaryExtension: (ext) ->
|
||||
_.indexOf([
|
||||
'.DS_Store'
|
||||
'.a'
|
||||
'.o'
|
||||
'.so'
|
||||
'.woff'
|
||||
], ext, true) >= 0
|
||||
|
||||
# Public: Returns true for files named similarily to 'README'
|
||||
isReadmePath: (readmePath) ->
|
||||
extension = path.extname(readmePath)
|
||||
base = path.basename(readmePath, extension).toLowerCase()
|
||||
base is 'readme' and (extension is '' or @isMarkdownExtension(extension))
|
||||
|
||||
# Private: Used by isReadmePath.
|
||||
isMarkdownExtension: (ext) ->
|
||||
_.indexOf([
|
||||
'.markdown'
|
||||
@@ -262,24 +381,30 @@ fsExtensions =
|
||||
'.ron'
|
||||
], ext, true) >= 0
|
||||
|
||||
isBinaryExtension: (ext) ->
|
||||
_.indexOf([
|
||||
'.DS_Store'
|
||||
'.a'
|
||||
'.o'
|
||||
'.so'
|
||||
'.woff'
|
||||
], ext, true) >= 0
|
||||
# Public: Reads and returns CSON, JSON or Plist files and returns the
|
||||
# corresponding Object.
|
||||
readObjectSync: (objectPath) ->
|
||||
CSON = require 'season'
|
||||
if CSON.isObjectPath(objectPath)
|
||||
CSON.readFileSync(objectPath)
|
||||
else
|
||||
@readPlistSync(objectPath)
|
||||
|
||||
isReadmePath: (readmePath) ->
|
||||
extension = path.extname(readmePath)
|
||||
base = path.basename(readmePath, extension).toLowerCase()
|
||||
base is 'readme' and (extension is '' or @isMarkdownExtension(extension))
|
||||
# Public: Reads and returns CSON, JSON or Plist files and calls the specified
|
||||
# callback with the corresponding Object.
|
||||
readObject: (objectPath, done) ->
|
||||
CSON = require 'season'
|
||||
if CSON.isObjectPath(objectPath)
|
||||
CSON.readFile(objectPath, done)
|
||||
else
|
||||
@readPlist(objectPath, done)
|
||||
|
||||
# Private: Used by readObjectSync.
|
||||
readPlistSync: (plistPath) ->
|
||||
plist = require 'plist'
|
||||
plist.parseStringSync(@read(plistPath))
|
||||
|
||||
# Private: Used by readObject.
|
||||
readPlist: (plistPath, done) ->
|
||||
plist = require 'plist'
|
||||
fs.readFile plistPath, 'utf8', (error, contents) ->
|
||||
@@ -291,18 +416,4 @@ fsExtensions =
|
||||
catch parseError
|
||||
done(parseError)
|
||||
|
||||
readObjectSync: (objectPath) ->
|
||||
CSON = require 'season'
|
||||
if CSON.isObjectPath(objectPath)
|
||||
CSON.readFileSync(objectPath)
|
||||
else
|
||||
@readPlistSync(objectPath)
|
||||
|
||||
readObject: (objectPath, done) ->
|
||||
CSON = require 'season'
|
||||
if CSON.isObjectPath(objectPath)
|
||||
CSON.readFile(objectPath, done)
|
||||
else
|
||||
@readPlist(objectPath, done)
|
||||
|
||||
module.exports = _.extend({}, fs, fsExtensions)
|
||||
|
||||
@@ -74,6 +74,7 @@ class Git
|
||||
@subscribeToBuffer(buffer) for buffer in project.getBuffers()
|
||||
@subscribe project, 'buffer-created', (buffer) => @subscribeToBuffer(buffer)
|
||||
|
||||
# Private: Subscribes to buffer events.
|
||||
subscribeToBuffer: (buffer) ->
|
||||
bufferStatusHandler = =>
|
||||
if path = buffer.getPath()
|
||||
@@ -82,8 +83,8 @@ class Git
|
||||
@subscribe buffer, 'reloaded', bufferStatusHandler
|
||||
@subscribe buffer, 'destroyed', => @unsubscribe(buffer)
|
||||
|
||||
# Public: Destroy this `Git` object. This destroys any tasks and
|
||||
# subscriptions and releases the underlying libgit2 repository handle.
|
||||
# Public: Destroy this `Git` object. This destroys any tasks and subscriptions
|
||||
# and releases the underlying libgit2 repository handle.
|
||||
destroy: ->
|
||||
if @statusTask?
|
||||
@statusTask.terminate()
|
||||
@@ -114,7 +115,8 @@ class Git
|
||||
|
||||
# Public: Returns the status of a single path in the repository.
|
||||
#
|
||||
# * path: A String defining a relative path
|
||||
# * path:
|
||||
# A String defining a relative path
|
||||
#
|
||||
# Returns a {Number}, FIXME representing what?
|
||||
getPathStatus: (path) ->
|
||||
@@ -128,24 +130,23 @@ class Git
|
||||
@emit 'status-changed', path, pathStatus
|
||||
pathStatus
|
||||
|
||||
# Public: Determines if the given path is ignored.
|
||||
# Public: Returns true if the given path is ignored.
|
||||
isPathIgnored: (path) -> @getRepo().isIgnored(@relativize(path))
|
||||
|
||||
# Public: Determine if the given status indicates modification.
|
||||
# Public: Returns true if the given status indicates modification.
|
||||
isStatusModified: (status) -> @getRepo().isStatusModified(status)
|
||||
|
||||
# Public: Determine if the given path is modified.
|
||||
# Public: Returns true if the given path is modified.
|
||||
isPathModified: (path) -> @isStatusModified(@getPathStatus(path))
|
||||
|
||||
# Public: Determine if the given status indicates a new path.
|
||||
# Public: Returns true if the given status indicates a new path.
|
||||
isStatusNew: (status) -> @getRepo().isStatusNew(status)
|
||||
|
||||
# Public: Determine if the given path is new.
|
||||
# Public: Returns true if the given path is new.
|
||||
isPathNew: (path) -> @isStatusNew(@getPathStatus(path))
|
||||
|
||||
# Public: Is the project at the root of this repository?
|
||||
#
|
||||
# Returns true if at the root, false if in a subfolder of the repository.
|
||||
# Public: Returns true if at the root, false if in a subfolder of the
|
||||
# repository.
|
||||
isProjectAtRoot: ->
|
||||
@projectAtRoot ?= project.relativize(@getWorkingDirectory()) is ''
|
||||
|
||||
@@ -170,9 +171,10 @@ class Git
|
||||
# git checkout HEAD -- <path>
|
||||
# ```
|
||||
#
|
||||
# path - The String path to checkout
|
||||
# * path:
|
||||
# The String path to checkout
|
||||
#
|
||||
# Returns a {Boolean} that's `true` if the method was successful.
|
||||
# Returns a Boolean that's true if the method was successful.
|
||||
checkoutHead: (path) ->
|
||||
headCheckedOut = @getRepo().checkoutHead(@relativize(path))
|
||||
@getPathStatus(path) if headCheckedOut
|
||||
@@ -180,10 +182,12 @@ class Git
|
||||
|
||||
# Public: Checks out a branch in your repository.
|
||||
#
|
||||
# reference - The {String} reference to checkout
|
||||
# create - A {Boolean} value which, if `true` creates the new reference if it doesn't exist.
|
||||
# * reference:
|
||||
# The String reference to checkout
|
||||
# * create:
|
||||
# A Boolean value which, if true creates the new reference if it doesn't exist.
|
||||
#
|
||||
# Returns a {Boolean} that's `true` if the method was successful.
|
||||
# Returns a Boolean that's true if the method was successful.
|
||||
checkoutReference: (reference, create) ->
|
||||
@getRepo().checkoutReference(reference, create)
|
||||
|
||||
@@ -204,7 +208,7 @@ class Git
|
||||
# * path:
|
||||
# The String path to check
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
# Returns a Boolean.
|
||||
isSubmodule: (path) -> @getRepo().isSubmodule(@relativize(path))
|
||||
|
||||
# Public: Retrieves the status of a directory.
|
||||
@@ -252,7 +256,7 @@ class Git
|
||||
# Returns a String.
|
||||
getUpstreamBranch: -> @getRepo().getUpstreamBranch()
|
||||
|
||||
# Public: ?
|
||||
# Public: Returns the current SHA for the given reference.
|
||||
getReferenceTarget: (reference) -> @getRepo().getReferenceTarget(reference)
|
||||
|
||||
# Public: Gets all the local and remote references.
|
||||
@@ -261,13 +265,15 @@ class Git
|
||||
# can be an array of strings containing the reference names.
|
||||
getReferences: -> @getRepo().getReferences()
|
||||
|
||||
# Public: ?
|
||||
# Public: Returns the number of commits behind the current branch is from the
|
||||
# default remote branch.
|
||||
getAheadBehindCount: (reference) -> @getRepo().getAheadBehindCount(reference)
|
||||
|
||||
# Public: ?
|
||||
# Public: Returns true if the given branch exists.
|
||||
hasBranch: (branch) -> @getReferenceTarget("refs/heads/#{branch}")?
|
||||
|
||||
# Private:
|
||||
# Private: Refreshes the current git status in an outside process and
|
||||
# asynchronously updates the relevant properties.
|
||||
refreshStatus: ->
|
||||
@statusTask = Task.once require.resolve('./repository-status-handler'), @getPath(), ({statuses, upstream, branch}) =>
|
||||
statusesUnchanged = _.isEqual(statuses, @statuses) and _.isEqual(upstream, @upstream) and _.isEqual(branch, @branch)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Like sands through the hourglass, so are the days of our lives.
|
||||
startTime = new Date().getTime()
|
||||
startTime = Date.now()
|
||||
|
||||
require './window'
|
||||
|
||||
@@ -7,4 +7,4 @@ Atom = require './atom'
|
||||
window.atom = new Atom()
|
||||
window.setUpEnvironment('editor')
|
||||
window.startEditorWindow()
|
||||
console.log "Window load time: #{new Date().getTime() - startTime}ms"
|
||||
console.log "Window load time: #{Date.now() - startTime}ms"
|
||||
|
||||
@@ -14,7 +14,11 @@ class WindowEventHandler
|
||||
@reloadRequested = false
|
||||
|
||||
@subscribe ipc, 'command', (command, args...) ->
|
||||
$(document.activeElement).trigger(command, args...)
|
||||
activeElement = document.activeElement
|
||||
# Use root view if body has focus
|
||||
if activeElement is document.body and atom.rootView?
|
||||
activeElement = atom.rootView
|
||||
$(activeElement).trigger(command, args...)
|
||||
|
||||
@subscribe ipc, 'context-command', (command, args...) ->
|
||||
$(atom.contextMenu.activeElement).trigger(command, args...)
|
||||
|
||||
Reference in New Issue
Block a user