mirror of
https://github.com/atom/atom.git
synced 2026-01-23 05:48:10 -05:00
Merge branch 'master' into mc-expose-bindings
This commit is contained in:
@@ -151,7 +151,7 @@ module.exports = (grunt) ->
|
||||
|
||||
shell:
|
||||
'kill-atom':
|
||||
command: 'pkill Atom'
|
||||
command: 'pkill -9 Atom'
|
||||
options:
|
||||
stdout: false
|
||||
stderr: false
|
||||
|
||||
30
package.json
30
package.json
@@ -9,7 +9,7 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"atomShellVersion": "0.4.9",
|
||||
"atomShellVersion": "0.5.1",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"bootstrap": "git://github.com/twbs/bootstrap.git#v3.0.0",
|
||||
@@ -22,41 +22,40 @@
|
||||
"mkdirp": "0.3.5",
|
||||
"less": "git://github.com/nathansobo/less.js.git",
|
||||
"less-cache": "0.8.0",
|
||||
"nak": "0.2.18",
|
||||
"nslog": "0.1.0",
|
||||
"oniguruma": "0.20.0",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "0.5.0",
|
||||
"patrick": "0.4.0",
|
||||
"pegjs": "0.7.0",
|
||||
"plist": "git://github.com/nathansobo/node-plist.git",
|
||||
"rimraf": "2.1.4",
|
||||
"scandal": "0.2.0",
|
||||
"season": "0.13.0",
|
||||
"semver": "1.1.4",
|
||||
"space-pen": "1.2.0",
|
||||
"tantamount": "0.3.0",
|
||||
"telepath": "0.4.0",
|
||||
"telepath": "0.6.0",
|
||||
"temp": "0.5.0",
|
||||
"underscore": "1.4.4",
|
||||
|
||||
"atom-light-ui": "0.2.1",
|
||||
"atom-light-syntax": "0.2.0",
|
||||
"atom-dark-ui": "0.2.0",
|
||||
"atom-dark-syntax": "0.2.0",
|
||||
"atom-light-ui": "0.3.0",
|
||||
"atom-light-syntax": "0.3.0",
|
||||
"atom-dark-ui": "0.3.0",
|
||||
"atom-dark-syntax": "0.3.0",
|
||||
"base16-tomorrow-dark-theme": "0.1.0",
|
||||
"solarized-dark-syntax": "0.1.0",
|
||||
"solarized-dark-syntax": "0.2.0",
|
||||
|
||||
"archive-view": "0.7.0",
|
||||
"autocomplete": "0.5.0",
|
||||
"autoflow": "0.2.0",
|
||||
"bookmarks": "0.3.0",
|
||||
"bracket-matcher": "0.4.0",
|
||||
"collaboration": "0.11.0",
|
||||
"collaboration": "0.16.0",
|
||||
"command-logger": "0.3.0",
|
||||
"command-palette": "0.3.0",
|
||||
"editor-stats": "0.2.0",
|
||||
"exception-reporting": "0.1.0",
|
||||
"find-and-replace": "0.11.0",
|
||||
"find-and-replace": "0.16.0",
|
||||
"fuzzy-finder": "0.5.0",
|
||||
"gfm": "0.4.0",
|
||||
"git-diff": "0.3.0",
|
||||
@@ -67,16 +66,16 @@
|
||||
"image-view": "0.5.0",
|
||||
"link": "0.2.0",
|
||||
"markdown-preview": "0.3.0",
|
||||
"metrics": "0.1.1",
|
||||
"metrics": "0.3.0",
|
||||
"package-generator": "0.8.0",
|
||||
"settings-view": "0.22.0",
|
||||
"settings-view": "0.23.0",
|
||||
"snippets": "0.5.0",
|
||||
"spell-check": "0.5.0",
|
||||
"status-bar": "0.7.0",
|
||||
"symbols-view": "0.5.0",
|
||||
"tabs": "0.4.0",
|
||||
"terminal": "0.9.0",
|
||||
"timecop": "0.2.0",
|
||||
"timecop": "0.4.0",
|
||||
"to-the-hubs": "0.3.0",
|
||||
"toml": "0.2.0",
|
||||
"tree-view": "0.6.0",
|
||||
@@ -118,6 +117,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"biscotto": "0.0.17",
|
||||
"fstream": "0.1.24",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "0.0.6",
|
||||
@@ -138,6 +138,6 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "true",
|
||||
"test": "grunt test"
|
||||
"test": "script/test"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ class AtomReporter extends View
|
||||
|
||||
clearTimeout @timeoutId if @timeoutId?
|
||||
@specPopup.show()
|
||||
spec = _.find(window.timedSpecs, (spec) -> description is spec.name)
|
||||
spec = _.find(window.timedSpecs, ({fullName}) -> description is fullName)
|
||||
description = "#{description} #{spec.time}ms" if spec
|
||||
@specPopup.text description
|
||||
{left, top} = element.offset()
|
||||
|
||||
@@ -63,6 +63,15 @@ describe "Editor", ->
|
||||
expect(editor).not.toMatchSelector ':focus'
|
||||
expect(editor.hiddenInput).toMatchSelector ':focus'
|
||||
|
||||
it "does not scroll the editor (regression)", ->
|
||||
editor.attachToDom(heightInLines: 2)
|
||||
editor.selectAll()
|
||||
editor.hiddenInput.blur()
|
||||
editor.focus()
|
||||
|
||||
expect(editor.hiddenInput).toMatchSelector ':focus'
|
||||
expect($(editor[0]).scrollTop()).toBe 0
|
||||
|
||||
describe "when the hidden input is focused / unfocused", ->
|
||||
it "assigns the isFocused flag on the editor and also adds/removes the .focused css class", ->
|
||||
editor.attachToDom()
|
||||
|
||||
3
spec/fixtures/git/working-dir/.gitignore
vendored
3
spec/fixtures/git/working-dir/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
ignored.txt
|
||||
poop
|
||||
ignored.txt
|
||||
|
||||
1
spec/fixtures/git/working-dir/git.git/HEAD
vendored
Normal file
1
spec/fixtures/git/working-dir/git.git/HEAD
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ref: refs/heads/master
|
||||
6
spec/fixtures/git/working-dir/git.git/config
vendored
Normal file
6
spec/fixtures/git/working-dir/git.git/config
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
||||
BIN
spec/fixtures/git/working-dir/git.git/index
vendored
Normal file
BIN
spec/fixtures/git/working-dir/git.git/index
vendored
Normal file
Binary file not shown.
BIN
spec/fixtures/git/working-dir/git.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7
vendored
Normal file
BIN
spec/fixtures/git/working-dir/git.git/objects/65/a457425a679cbe9adf0d2741785d3ceabb44a7
vendored
Normal file
Binary file not shown.
BIN
spec/fixtures/git/working-dir/git.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
vendored
Normal file
BIN
spec/fixtures/git/working-dir/git.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
vendored
Normal file
Binary file not shown.
BIN
spec/fixtures/git/working-dir/git.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1
vendored
Normal file
BIN
spec/fixtures/git/working-dir/git.git/objects/ef/046e9eecaa5255ea5e9817132d4001724d6ae1
vendored
Normal file
Binary file not shown.
1
spec/fixtures/git/working-dir/git.git/refs/heads/master
vendored
Normal file
1
spec/fixtures/git/working-dir/git.git/refs/heads/master
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ef046e9eecaa5255ea5e9817132d4001724d6ae1
|
||||
@@ -1,3 +1,4 @@
|
||||
temp = require 'temp'
|
||||
Git = require '../src/git'
|
||||
{fs} = require 'atom'
|
||||
path = require 'path'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
temp = require 'temp'
|
||||
fstream = require 'fstream'
|
||||
Project = require '../src/project'
|
||||
{_, fs} = require 'atom'
|
||||
path = require 'path'
|
||||
@@ -232,33 +234,37 @@ describe "Project", ->
|
||||
|
||||
describe ".scan(options, callback)", ->
|
||||
describe "when called with a regex", ->
|
||||
it "calls the callback with all regex matches in all files in the project", ->
|
||||
matches = []
|
||||
it "calls the callback with all regex results in all files in the project", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
project.scan /(a)+/, (match) -> matches.push(match)
|
||||
project.scan /(a)+/, (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(matches[0]).toEqual
|
||||
path: project.resolve('a')
|
||||
match: 'aaa'
|
||||
expect(results).toHaveLength(3)
|
||||
expect(results[0].filePath).toBe project.resolve('a')
|
||||
expect(results[0].matches).toHaveLength(3)
|
||||
expect(results[0].matches[0]).toEqual
|
||||
matchText: 'aaa'
|
||||
lineText: 'aaa bbb'
|
||||
lineTextOffset: 0
|
||||
range: [[0, 0], [0, 3]]
|
||||
|
||||
expect(matches[1]).toEqual
|
||||
path: project.resolve('a')
|
||||
match: 'aa'
|
||||
range: [[1, 3], [1, 5]]
|
||||
|
||||
it "works with with escaped literals (like $ and ^)", ->
|
||||
matches = []
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
project.scan /\$\w+/, (match) -> matches.push(match)
|
||||
project.scan /\$\w+/, (result) -> results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(matches.length).toBe 1
|
||||
expect(results.length).toBe 1
|
||||
|
||||
{filePath, matches} = results[0]
|
||||
expect(filePath).toBe project.resolve('a')
|
||||
expect(matches).toHaveLength 1
|
||||
expect(matches[0]).toEqual
|
||||
path: project.resolve('a')
|
||||
match: '$bill'
|
||||
matchText: '$bill'
|
||||
lineText: 'dollar$bill'
|
||||
lineTextOffset: 0
|
||||
range: [[2, 6], [2, 11]]
|
||||
|
||||
it "works on evil filenames", ->
|
||||
@@ -267,12 +273,12 @@ describe "Project", ->
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
project.scan /evil/, (result) ->
|
||||
paths.push(result.path)
|
||||
matches.push(result.match)
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 5
|
||||
matches.forEach (match) -> expect(match).toEqual 'evil'
|
||||
matches.forEach (match) -> expect(match.matchText).toEqual 'evil'
|
||||
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
|
||||
expect(paths[1]).toMatch /file with spaces.txt$/
|
||||
expect(paths[2]).toMatch /goddam\nnewlines$/m
|
||||
@@ -280,57 +286,63 @@ describe "Project", ->
|
||||
expect(path.basename(paths[4])).toBe "utfa\u0306.md"
|
||||
|
||||
it "ignores case if the regex includes the `i` flag", ->
|
||||
matches = []
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
project.scan /DOLLAR/i, (match) -> matches.push(match)
|
||||
project.scan /DOLLAR/i, (result) -> results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(matches).toHaveLength 1
|
||||
|
||||
it "handles breaks in the search subprocess's output following the filename", ->
|
||||
spyOn(BufferedProcess.prototype, 'bufferStream')
|
||||
|
||||
iterator = jasmine.createSpy('iterator')
|
||||
project.scan /a+/, iterator
|
||||
|
||||
stdout = BufferedProcess.prototype.bufferStream.argsForCall[0][1]
|
||||
stdout ":#{path.join(__dirname, 'fixtures', 'dir', 'a')}\n"
|
||||
stdout "1;0 3:aaa bbb\n2;3 2:cc aa cc\n"
|
||||
|
||||
expect(iterator.argsForCall[0][0]).toEqual
|
||||
path: project.resolve('a')
|
||||
match: 'aaa'
|
||||
range: [[0, 0], [0, 3]]
|
||||
|
||||
expect(iterator.argsForCall[1][0]).toEqual
|
||||
path: project.resolve('a')
|
||||
match: 'aa'
|
||||
range: [[1, 3], [1, 5]]
|
||||
expect(results).toHaveLength 1
|
||||
|
||||
describe "when the core.excludeVcsIgnoredPaths config is truthy", ->
|
||||
[projectPath, ignoredPath] = []
|
||||
|
||||
beforeEach ->
|
||||
projectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
|
||||
ignoredPath = path.join(projectPath, 'ignored.txt')
|
||||
fs.writeSync(ignoredPath, 'this match should not be included')
|
||||
sourceProjectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
|
||||
projectPath = path.join(temp.mkdirSync("atom"))
|
||||
|
||||
writerStream = fstream.Writer(projectPath)
|
||||
fstream.Reader(sourceProjectPath).pipe(writerStream)
|
||||
|
||||
waitsFor (done) ->
|
||||
writerStream.on 'close', done
|
||||
writerStream.on 'error', done
|
||||
|
||||
runs ->
|
||||
fs.rename(path.join(projectPath, 'git.git'), path.join(projectPath, '.git'))
|
||||
ignoredPath = path.join(projectPath, 'ignored.txt')
|
||||
fs.writeSync(ignoredPath, 'this match should not be included')
|
||||
|
||||
afterEach ->
|
||||
fs.remove(ignoredPath) if fs.exists(ignoredPath)
|
||||
fs.remove(projectPath) if fs.exists(projectPath)
|
||||
|
||||
it "excludes ignored files", ->
|
||||
project.setPath(projectPath)
|
||||
config.set('core.excludeVcsIgnoredPaths', true)
|
||||
paths = []
|
||||
matches = []
|
||||
resultHandler = jasmine.createSpy("result found")
|
||||
waitsForPromise ->
|
||||
project.scan /match/, (result) ->
|
||||
paths.push(result.path)
|
||||
matches.push(result.match)
|
||||
project.scan /match/, (results) ->
|
||||
resultHandler()
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 0
|
||||
expect(matches.length).toBe 0
|
||||
expect(resultHandler).not.toHaveBeenCalled()
|
||||
|
||||
it "includes only files when a directory filter is specified", ->
|
||||
projectPath = path.join(path.join(__dirname, 'fixtures', 'dir'))
|
||||
project.setPath(projectPath)
|
||||
|
||||
filePath = path.join(projectPath, 'a-dir', 'oh-git')
|
||||
|
||||
paths = []
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
project.scan /aaa/, paths: ['a-dir/'], (result) ->
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 1
|
||||
expect(paths[0]).toBe filePath
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
it "includes files and folders that begin with a '.'", ->
|
||||
projectPath = '/tmp/atom-tests/folder-with-dot-file'
|
||||
@@ -341,8 +353,8 @@ describe "Project", ->
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
project.scan /match this/, (result) ->
|
||||
paths.push(result.path)
|
||||
matches.push(result.match)
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 1
|
||||
@@ -350,17 +362,16 @@ describe "Project", ->
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
it "excludes values in core.ignoredNames", ->
|
||||
projectPath = '/tmp/atom-tests/folder-with-dot-git/.git'
|
||||
filePath = path.join(projectPath, 'test.txt')
|
||||
fs.writeSync(filePath, 'match this')
|
||||
project.setPath(projectPath)
|
||||
paths = []
|
||||
matches = []
|
||||
projectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
|
||||
ignoredNames = config.get("core.ignoredNames")
|
||||
ignoredNames.push("a")
|
||||
config.set("core.ignoredNames", ignoredNames)
|
||||
|
||||
resultHandler = jasmine.createSpy("result found")
|
||||
waitsForPromise ->
|
||||
project.scan /match/, (result) ->
|
||||
paths.push(result.path)
|
||||
matches.push(result.match)
|
||||
project.scan /dollar/, (results) ->
|
||||
console.log results
|
||||
resultHandler()
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 0
|
||||
expect(matches.length).toBe 0
|
||||
expect(resultHandler).not.toHaveBeenCalled()
|
||||
|
||||
@@ -602,6 +602,17 @@ describe 'TextBuffer', ->
|
||||
it "clips the range to the end of the buffer", ->
|
||||
expect(buffer.getTextInRange([[12], [13, Infinity]])).toBe buffer.lineForRow(12)
|
||||
|
||||
describe ".scan(regex, fn)", ->
|
||||
it "retunrns lineText and lineTextOffset", ->
|
||||
matches = []
|
||||
buffer.scan /current/, (match) ->
|
||||
matches.push(match)
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
expect(matches[0].matchText).toEqual 'current'
|
||||
expect(matches[0].lineText).toEqual ' var pivot = items.shift(), current, left = [], right = [];'
|
||||
expect(matches[0].lineTextOffset).toBe 0
|
||||
|
||||
describe ".scanInRange(range, regex, fn)", ->
|
||||
describe "when given a regex with a ignore case flag", ->
|
||||
it "does a case-insensitive search", ->
|
||||
|
||||
@@ -53,6 +53,7 @@ class TimeReporter extends jasmine.Reporter
|
||||
window.timedSpecs.push
|
||||
description: @description
|
||||
time: duration
|
||||
fullName: spec.getFullName()
|
||||
|
||||
if timedSuites[@suite]
|
||||
window.timedSuites[@suite] += duration
|
||||
|
||||
@@ -93,8 +93,8 @@ class AtomApplication
|
||||
fs.unlinkSync socketPath if fs.existsSync(socketPath)
|
||||
server = net.createServer (connection) =>
|
||||
connection.on 'data', (data) =>
|
||||
{pathsToOpen, pidToKillWhenClosed, newWindow} = JSON.parse(data)
|
||||
@openPaths({pathsToOpen, pidToKillWhenClosed, newWindow})
|
||||
options = JSON.parse(data)
|
||||
@openPaths(options)
|
||||
|
||||
server.listen socketPath
|
||||
server.on 'error', (error) -> console.error 'Application server failed', error
|
||||
|
||||
@@ -28,41 +28,44 @@ class AtomPackage extends Package
|
||||
getType: -> 'atom'
|
||||
|
||||
load: ->
|
||||
try
|
||||
@metadata = Package.loadMetadata(@path)
|
||||
if @isTheme()
|
||||
@stylesheets = []
|
||||
@keymaps = []
|
||||
@menus = []
|
||||
@grammars = []
|
||||
@scopedProperties = []
|
||||
else
|
||||
@loadKeymaps()
|
||||
@loadMenus()
|
||||
@loadStylesheets()
|
||||
@loadGrammars()
|
||||
@loadScopedProperties()
|
||||
|
||||
if @metadata.activationEvents?
|
||||
@registerDeferredDeserializers()
|
||||
@measure 'loadTime', =>
|
||||
try
|
||||
@metadata = Package.loadMetadata(@path)
|
||||
if @isTheme()
|
||||
@stylesheets = []
|
||||
@keymaps = []
|
||||
@menus = []
|
||||
@grammars = []
|
||||
@scopedProperties = []
|
||||
else
|
||||
@requireMainModule()
|
||||
@loadKeymaps()
|
||||
@loadMenus()
|
||||
@loadStylesheets()
|
||||
@loadGrammars()
|
||||
@loadScopedProperties()
|
||||
|
||||
catch e
|
||||
console.warn "Failed to load package named '#{@name}'", e.stack ? e
|
||||
if @metadata.activationEvents?
|
||||
@registerDeferredDeserializers()
|
||||
else
|
||||
@requireMainModule()
|
||||
|
||||
catch e
|
||||
console.warn "Failed to load package named '#{@name}'", e.stack ? e
|
||||
this
|
||||
|
||||
activate: ({immediate}={}) ->
|
||||
@loadStylesheets() if @isTheme()
|
||||
@activateResources()
|
||||
if @metadata.activationEvents? and not immediate
|
||||
@subscribeToActivationEvents()
|
||||
else
|
||||
@activateNow()
|
||||
@measure 'activateTime', =>
|
||||
@loadStylesheets() if @isTheme()
|
||||
@activateResources()
|
||||
if @metadata.activationEvents? and not immediate
|
||||
@subscribeToActivationEvents()
|
||||
else
|
||||
@activateNow()
|
||||
|
||||
activateNow: ->
|
||||
try
|
||||
@activateConfig()
|
||||
@activateStylesheets()
|
||||
if @requireMainModule()
|
||||
@mainModule.activate(atom.getPackageState(@name) ? {})
|
||||
@mainActivated = true
|
||||
@@ -78,11 +81,13 @@ class AtomPackage extends Package
|
||||
@mainModule.activateConfig?()
|
||||
@configActivated = true
|
||||
|
||||
activateStylesheets: ->
|
||||
type = if @metadata.theme then 'theme' else 'bundled'
|
||||
applyStylesheet(stylesheetPath, content, type) for [stylesheetPath, content] in @stylesheets
|
||||
|
||||
activateResources: ->
|
||||
keymap.add(keymapPath, map) for [keymapPath, map] in @keymaps
|
||||
atom.contextMenu.add(menuPath, map['context-menu']) for [menuPath, map] in @menus
|
||||
type = if @metadata.theme then 'theme' else 'bundled'
|
||||
applyStylesheet(stylesheetPath, content, type) for [stylesheetPath, content] in @stylesheets
|
||||
syntax.addGrammar(grammar) for grammar in @grammars
|
||||
for [scopedPropertiesPath, selector, properties] in @scopedProperties
|
||||
syntax.addProperties(scopedPropertiesPath, selector, properties)
|
||||
|
||||
@@ -42,10 +42,7 @@ class AtomWindow
|
||||
@openPath(pathToOpen, initialLine)
|
||||
|
||||
setupNodePath: (resourcePath) ->
|
||||
paths = [
|
||||
'exports'
|
||||
'node_modules'
|
||||
]
|
||||
paths = ['exports', 'node_modules']
|
||||
paths = paths.map (relativePath) -> path.resolve(resourcePath, relativePath)
|
||||
process.env['NODE_PATH'] = paths.join path.delimiter
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ crypto = require 'crypto'
|
||||
path = require 'path'
|
||||
dialog = remote.require 'dialog'
|
||||
app = remote.require 'app'
|
||||
telepath = require 'telepath'
|
||||
{Document} = require 'telepath'
|
||||
ThemeManager = require './theme-manager'
|
||||
ContextMenuManager = require './context-menu-manager'
|
||||
|
||||
@@ -34,9 +34,7 @@ window.atom =
|
||||
activatePackage: (name, options) ->
|
||||
if pack = @loadPackage(name, options)
|
||||
@activePackages[pack.name] = pack
|
||||
startTime = new Date().getTime()
|
||||
pack.activate(options)
|
||||
pack.activateTime = new Date().getTime() - startTime
|
||||
pack
|
||||
|
||||
deactivatePackages: ->
|
||||
@@ -73,9 +71,7 @@ window.atom =
|
||||
|
||||
if packagePath = @resolvePackagePath(name)
|
||||
return pack if pack = @getLoadedPackage(name)
|
||||
startTime = new Date().getTime()
|
||||
pack = Package.load(packagePath, options)
|
||||
pack.loadTime = new Date().getTime() - startTime
|
||||
if pack.metadata.theme
|
||||
@themes.register(pack)
|
||||
else
|
||||
@@ -249,34 +245,28 @@ window.atom =
|
||||
if windowStatePath = @getWindowStatePath()
|
||||
if fsUtils.exists(windowStatePath)
|
||||
try
|
||||
windowStateJson = fsUtils.read(windowStatePath)
|
||||
documentStateJson = fsUtils.read(windowStatePath)
|
||||
catch error
|
||||
console.warn "Error reading window state: #{windowStatePath}", error.stack, error
|
||||
else
|
||||
windowStateJson = @getLoadSettings().windowState
|
||||
documentStateJson = @getLoadSettings().windowState
|
||||
|
||||
try
|
||||
windowState = JSON.parse(windowStateJson or '{}')
|
||||
documentState = JSON.parse(documentStateJson) if documentStateJson?
|
||||
catch error
|
||||
console.warn "Error parsing window state: #{windowStatePath}", error.stack, error
|
||||
|
||||
{site, document} = windowState ? {}
|
||||
if site? and document?
|
||||
window.site = telepath.Site.deserialize(site)
|
||||
window.site.deserializeDocument(document) ? window.site.createDocument({})
|
||||
else
|
||||
window.site = new telepath.Site(1)
|
||||
window.site.createDocument({})
|
||||
doc = Document.deserialize(state: documentState) if documentState?
|
||||
doc ?= Document.create()
|
||||
window.site = doc.site # TODO: Remove this when everything is using telepath models
|
||||
doc
|
||||
|
||||
saveWindowState: ->
|
||||
windowState =
|
||||
site: site.serialize()
|
||||
document: @getWindowState().serialize()
|
||||
windowStateJson = JSON.stringify(windowState)
|
||||
windowState = @getWindowState()
|
||||
if windowStatePath = @getWindowStatePath()
|
||||
fsUtils.writeSync(windowStatePath, "#{windowStateJson}\n")
|
||||
windowState.saveSync(path: windowStatePath)
|
||||
else
|
||||
@getLoadSettings().windowState = windowStateJson
|
||||
@getLoadSettings().windowState = JSON.stringify(windowState.serialize())
|
||||
|
||||
getWindowState: (keyPath) ->
|
||||
@windowState ?= @loadWindowState()
|
||||
|
||||
@@ -117,6 +117,7 @@ class EditSession
|
||||
project.setPath(path.dirname(@getPath())) unless project.getPath()?
|
||||
@trigger "title-changed"
|
||||
@trigger "path-changed"
|
||||
@subscribe @buffer, "contents-modified", => @trigger "contents-modified"
|
||||
@subscribe @buffer, "contents-conflicted", => @trigger "contents-conflicted"
|
||||
@subscribe @buffer, "modified-status-changed", => @trigger "modified-status-changed"
|
||||
@preserveCursorPositionOnBufferReload()
|
||||
@@ -376,6 +377,9 @@ class EditSession
|
||||
# {Delegates to: TextBuffer.lineLengthForRow}
|
||||
lineLengthForBufferRow: (row) -> @buffer.lineLengthForRow(row)
|
||||
|
||||
# {Delegates to: TextBuffer.scan}
|
||||
scan: (args...) -> @buffer.scan(args...)
|
||||
|
||||
# {Delegates to: TextBuffer.scanInRange}
|
||||
scanInBufferRange: (args...) -> @buffer.scanInRange(args...)
|
||||
|
||||
|
||||
@@ -640,6 +640,7 @@ class Editor extends View
|
||||
@hiddenInput.on 'focusout', =>
|
||||
@isFocused = false
|
||||
@removeClass 'is-focused'
|
||||
@hiddenInput.offset(top: 0, left: 0)
|
||||
|
||||
@underlayer.on 'mousedown', (e) =>
|
||||
@renderedLines.trigger(e)
|
||||
|
||||
@@ -105,8 +105,11 @@ module.exports =
|
||||
# Identifies how many events are registered.
|
||||
#
|
||||
# Returns a {Number}.
|
||||
subscriptionCount: ->
|
||||
getSubscriptionCount: ->
|
||||
count = 0
|
||||
for name, handlers of @eventHandlersByEventName
|
||||
count += handlers.length
|
||||
count
|
||||
|
||||
# Deprecated
|
||||
subscriptionCount: -> @getSubscriptionCount()
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
startTime = new Date().getTime()
|
||||
|
||||
autoUpdater = require 'auto-updater'
|
||||
crashReporter = require 'crash-reporter'
|
||||
delegate = require 'atom-delegate'
|
||||
app = require 'app'
|
||||
fs = require 'fs'
|
||||
module = require 'module'
|
||||
path = require 'path'
|
||||
optimist = require 'optimist'
|
||||
nslog = require 'nslog'
|
||||
dialog = require 'dialog'
|
||||
_ = require 'underscore'
|
||||
|
||||
console.log = (args...) ->
|
||||
nslog(args.map((arg) -> JSON.stringify(arg)).join(" "))
|
||||
@@ -45,14 +47,15 @@ delegate.browserMainParts.preMainMessageLoopRun = ->
|
||||
require('coffee-script')
|
||||
if args.devMode
|
||||
require(path.join(args.resourcePath, 'src', 'coffee-cache'))
|
||||
require('module').globalPaths.push(path.join(args.resourcePath, 'src'))
|
||||
module.globalPaths.push(path.join(args.resourcePath, 'src'))
|
||||
else
|
||||
appSrcPath = path.resolve(process.argv[0], "../../Resources/app/src")
|
||||
require('module').globalPaths.push(appSrcPath)
|
||||
module.globalPaths.push(appSrcPath)
|
||||
|
||||
AtomApplication = require 'atom-application'
|
||||
|
||||
AtomApplication.open(args)
|
||||
console.log("App load time: #{new Date().getTime() - startTime}ms")
|
||||
|
||||
global.devResourcePath = path.join(app.getHomeDir(), 'github', 'atom')
|
||||
|
||||
|
||||
@@ -39,3 +39,9 @@ class Package
|
||||
|
||||
isTheme: ->
|
||||
!!@metadata?.theme
|
||||
|
||||
# Private:
|
||||
measure: (key, fn) ->
|
||||
startTime = new Date().getTime()
|
||||
fn()
|
||||
@[key] = new Date().getTime() - startTime
|
||||
|
||||
@@ -10,7 +10,7 @@ TextBuffer = require './text-buffer'
|
||||
EditSession = require './edit-session'
|
||||
EventEmitter = require './event-emitter'
|
||||
Directory = require './directory'
|
||||
BufferedNodeProcess = require './buffered-node-process'
|
||||
Task = require './task'
|
||||
Git = require './git'
|
||||
|
||||
# Public: Represents a project that's opened in Atom.
|
||||
@@ -278,65 +278,30 @@ class Project
|
||||
#
|
||||
# * regex:
|
||||
# A RegExp to search with
|
||||
# * options:
|
||||
# - paths: an {Array} of glob patterns to search within
|
||||
# * iterator:
|
||||
# A Function callback on each file found
|
||||
scan: (regex, iterator) ->
|
||||
bufferedData = ""
|
||||
state = 'readingPath'
|
||||
filePath = null
|
||||
|
||||
readPath = (line) ->
|
||||
if /^[0-9,; ]+:/.test(line)
|
||||
state = 'readingLines'
|
||||
else if /^:/.test line
|
||||
filePath = line.substr(1)
|
||||
else
|
||||
filePath += ('\n' + line)
|
||||
|
||||
readLine = (line) ->
|
||||
if line.length == 0
|
||||
state = 'readingPath'
|
||||
filePath = null
|
||||
else
|
||||
colonIndex = line.indexOf(':')
|
||||
matchInfo = line.substring(0, colonIndex)
|
||||
lineText = line.substring(colonIndex + 1)
|
||||
readMatches(matchInfo, lineText)
|
||||
|
||||
readMatches = (matchInfo, lineText) ->
|
||||
[lineNumber, matchPositionsText] = matchInfo.match(/(\d+);(.+)/)[1..]
|
||||
row = parseInt(lineNumber) - 1
|
||||
matchPositions = matchPositionsText.split(',').map (positionText) -> positionText.split(' ').map (pos) -> parseInt(pos)
|
||||
|
||||
for [column, length] in matchPositions
|
||||
range = new Range([row, column], [row, column + length])
|
||||
match = lineText.substr(column, length)
|
||||
iterator({path: filePath, range, match})
|
||||
scan: (regex, options={}, iterator) ->
|
||||
if _.isFunction(options)
|
||||
iterator = options
|
||||
options = {}
|
||||
|
||||
deferred = $.Deferred()
|
||||
errors = []
|
||||
stderr = (data) ->
|
||||
errors.push(data)
|
||||
stdout = (data) ->
|
||||
lines = data.split('\n')
|
||||
lines.pop() # the last segment is a spurious '' because data always ends in \n due to bufferLines: true
|
||||
for line in lines
|
||||
readPath(line) if state is 'readingPath'
|
||||
readLine(line) if state is 'readingLines'
|
||||
exit = (code) ->
|
||||
if code is 0
|
||||
deferred.resolve()
|
||||
else
|
||||
console.error("Project scan failed: #{code}", errors.join('\n'))
|
||||
deferred.reject({command, code})
|
||||
|
||||
command = require.resolve('.bin/nak')
|
||||
args = ['--hidden', '--ackmate', regex.source, @getPath()]
|
||||
ignoredNames = config.get('core.ignoredNames') ? []
|
||||
args.unshift('--ignore', ignoredNames.join(',')) if ignoredNames.length > 0
|
||||
args.unshift('--ignoreCase') if regex.ignoreCase
|
||||
args.unshift('--addVCSIgnores') if config.get('core.excludeVcsIgnoredPaths')
|
||||
new BufferedNodeProcess({command, args, stdout, stderr, exit})
|
||||
searchOptions =
|
||||
ignoreCase: regex.ignoreCase
|
||||
inclusions: options.paths
|
||||
includeHidden: true
|
||||
excludeVcsIgnores: config.get('core.excludeVcsIgnoredPaths')
|
||||
exclusions: config.get('core.ignoredNames')
|
||||
|
||||
task = Task.once require.resolve('./scan-handler'), @getPath(), regex.source, searchOptions, ->
|
||||
deferred.resolve()
|
||||
|
||||
task.on 'scan:result-found', (result) =>
|
||||
iterator(result)
|
||||
|
||||
deferred
|
||||
|
||||
# Private:
|
||||
|
||||
@@ -126,7 +126,8 @@ class RootView extends View
|
||||
@command 'pane:reopen-closed-item', =>
|
||||
@panes.reopenItem()
|
||||
|
||||
_.nextTick => atom.setFullScreen(@state.get('fullScreen'))
|
||||
if @state.get('fullScreen')
|
||||
_.nextTick => atom.setFullScreen(true)
|
||||
|
||||
# Private:
|
||||
serialize: ->
|
||||
@@ -173,8 +174,10 @@ class RootView extends View
|
||||
initialLine = options.initialLine
|
||||
path = project.relativize(path)
|
||||
if activePane = @getActivePane()
|
||||
editSession = activePane.itemForUri(path) if path
|
||||
editSession ?= project.open(path, {initialLine})
|
||||
if path
|
||||
editSession = activePane.itemForUri(path) ? project.open(path, {initialLine})
|
||||
else
|
||||
editSession = project.open()
|
||||
activePane.showItem(editSession)
|
||||
else
|
||||
editSession = project.open(path, {initialLine})
|
||||
|
||||
15
src/scan-handler.coffee
Normal file
15
src/scan-handler.coffee
Normal file
@@ -0,0 +1,15 @@
|
||||
{PathSearcher, PathScanner, search} = require 'scandal'
|
||||
|
||||
module.exports = (rootPath, regexSource, options) ->
|
||||
callback = @async()
|
||||
|
||||
searcher = new PathSearcher()
|
||||
scanner = new PathScanner(rootPath, options)
|
||||
|
||||
searcher.on 'results-found', (result) ->
|
||||
emit('scan:result-found', result)
|
||||
|
||||
flags = "g"
|
||||
flags += "i" if options.ignoreCase
|
||||
regex = new RegExp(regexSource, flags)
|
||||
search regex, scanner, searcher, callback
|
||||
@@ -6,6 +6,7 @@ File = require './file'
|
||||
EventEmitter = require './event-emitter'
|
||||
Subscriber = require './subscriber'
|
||||
guid = require 'guid'
|
||||
{P} = require 'scandal'
|
||||
|
||||
# Private: Represents the contents of a file.
|
||||
#
|
||||
@@ -501,7 +502,10 @@ class TextBuffer
|
||||
# regex - A {RegExp} representing the text to find
|
||||
# iterator - A {Function} that's called on each match
|
||||
scan: (regex, iterator) ->
|
||||
@scanInRange(regex, @getRange(), iterator)
|
||||
@scanInRange regex, @getRange(), (result) =>
|
||||
result.lineText = @lineForRow(result.range.start.row)
|
||||
result.lineTextOffset = 0
|
||||
iterator(result)
|
||||
|
||||
# Scans for text in a given range, calling a function on each match.
|
||||
#
|
||||
@@ -538,7 +542,8 @@ class TextBuffer
|
||||
range = new Range(startPosition, endPosition)
|
||||
keepLooping = true
|
||||
replacementText = null
|
||||
iterator({match, range, stop, replace })
|
||||
matchText = match[0]
|
||||
iterator({ match, matchText, range, stop, replace })
|
||||
|
||||
if replacementText?
|
||||
@change(range, replacementText)
|
||||
|
||||
@@ -29,18 +29,20 @@ class TextMatePackage extends Package
|
||||
getType: -> 'textmate'
|
||||
|
||||
load: ({sync}={}) ->
|
||||
@metadata = Package.loadMetadata(@path, true)
|
||||
@measure 'loadTime', =>
|
||||
@metadata = Package.loadMetadata(@path, true)
|
||||
|
||||
if sync
|
||||
@loadGrammarsSync()
|
||||
@loadScopedPropertiesSync()
|
||||
else
|
||||
TextMatePackage.getLoadQueue().push(this)
|
||||
if sync
|
||||
@loadGrammarsSync()
|
||||
@loadScopedPropertiesSync()
|
||||
else
|
||||
TextMatePackage.getLoadQueue().push(this)
|
||||
|
||||
activate: ->
|
||||
syntax.addGrammar(grammar) for grammar in @grammars
|
||||
for { selector, properties } in @scopedProperties
|
||||
syntax.addProperties(@path, selector, properties)
|
||||
@measure 'activateTime', =>
|
||||
syntax.addGrammar(grammar) for grammar in @grammars
|
||||
for { selector, properties } in @scopedProperties
|
||||
syntax.addProperties(@path, selector, properties)
|
||||
|
||||
activateConfig: -> # noop
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ class ThemeManager
|
||||
getActiveThemes: ->
|
||||
_.clone(@activeThemes)
|
||||
|
||||
# Internal-only:
|
||||
getLoadedThemes: ->
|
||||
_.clone(@loadedThemes)
|
||||
|
||||
# Internal-only:
|
||||
unload: ->
|
||||
removeStylesheet(@userStylesheetPath) if @userStylesheetPath?
|
||||
|
||||
@@ -28,6 +28,9 @@ _.mixin
|
||||
escapeRegExp: (string) ->
|
||||
string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
|
||||
|
||||
escapeAttribute: (string) ->
|
||||
string.replace(/"/g, '"').replace(/\n/g, '')
|
||||
|
||||
humanizeEventName: (eventName, eventDoc) ->
|
||||
[namespace, event] = eventName.split(':')
|
||||
return _.undasherize(namespace) unless event?
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Like sands through the hourglass, so are the days of our lives.
|
||||
date = new Date().getTime()
|
||||
startTime = new Date().getTime()
|
||||
|
||||
require './atom'
|
||||
require './window'
|
||||
|
||||
window.setUpEnvironment('editor')
|
||||
window.startEditorWindow()
|
||||
console.log "Load time: #{new Date().getTime() - date}"
|
||||
console.log "Window load time: #{new Date().getTime() - startTime}ms"
|
||||
|
||||
@@ -14,7 +14,7 @@ class WindowEventHandler
|
||||
@reloadRequested = false
|
||||
|
||||
@subscribe ipc, 'command', (command, args...) ->
|
||||
$(window).trigger(command, args...)
|
||||
$(document.activeElement).trigger(command, args...)
|
||||
|
||||
@subscribe ipc, 'context-command', (command, args...) ->
|
||||
$(atom.contextMenu.activeElement).trigger(command, args...)
|
||||
|
||||
Reference in New Issue
Block a user