mirror of
https://github.com/atom/atom.git
synced 2026-01-23 05:48:10 -05:00
Merge branch 'master' into cj-update-docs
This commit is contained in:
@@ -20,6 +20,7 @@ module.exports = (grunt) ->
|
||||
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
|
||||
shellAppDir = path.join(buildDir, appName)
|
||||
appDir = path.join(shellAppDir, 'resources', 'app')
|
||||
atomShellDownloadDir = path.join(os.tmpdir(), 'atom-cached-atom-shells')
|
||||
else
|
||||
appName = 'Atom.app'
|
||||
tmpDir = '/tmp'
|
||||
@@ -28,6 +29,7 @@ module.exports = (grunt) ->
|
||||
shellAppDir = path.join(buildDir, appName)
|
||||
contentsDir = path.join(shellAppDir, 'Contents')
|
||||
appDir = path.join(contentsDir, 'Resources', 'app')
|
||||
atomShellDownloadDir = '/tmp/atom-cached-atom-shells'
|
||||
|
||||
installDir = path.join(installRoot, appName)
|
||||
|
||||
@@ -168,6 +170,12 @@ module.exports = (grunt) ->
|
||||
_.extend(context, parsed.attributes)
|
||||
parsed.body
|
||||
|
||||
'download-atom-shell':
|
||||
version: packageJson.atomShellVersion
|
||||
outputDir: 'atom-shell'
|
||||
downloadDir: atomShellDownloadDir
|
||||
rebuild: true # rebuild native modules after atom-shell is updated
|
||||
|
||||
shell:
|
||||
'kill-atom':
|
||||
command: 'pkill -9 Atom'
|
||||
@@ -183,13 +191,14 @@ module.exports = (grunt) ->
|
||||
grunt.loadNpmTasks('grunt-contrib-coffee')
|
||||
grunt.loadNpmTasks('grunt-contrib-less')
|
||||
grunt.loadNpmTasks('grunt-markdown')
|
||||
grunt.loadNpmTasks('grunt-download-atom-shell')
|
||||
grunt.loadNpmTasks('grunt-shell')
|
||||
grunt.loadTasks('tasks')
|
||||
|
||||
grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson'])
|
||||
grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint'])
|
||||
grunt.registerTask('test', ['shell:kill-atom', 'run-specs'])
|
||||
grunt.registerTask('ci', ['update-atom-shell', 'build', 'set-development-version', 'lint', 'test'])
|
||||
grunt.registerTask('deploy', ['partial-clean', 'update-atom-shell', 'build', 'codesign'])
|
||||
grunt.registerTask('ci', ['download-atom-shell', 'build', 'set-development-version', 'lint', 'test'])
|
||||
grunt.registerTask('deploy', ['partial-clean', 'download-atom-shell', 'build', 'codesign'])
|
||||
grunt.registerTask('docs', ['markdown:guides', 'build-docs'])
|
||||
grunt.registerTask('default', ['update-atom-shell', 'build', 'set-development-version', 'install'])
|
||||
grunt.registerTask('default', ['download-atom-shell', 'build', 'set-development-version', 'install'])
|
||||
|
||||
13
LICENSE.md
Normal file
13
LICENSE.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2013 GitHub Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -206,7 +206,7 @@ specific parts of the interface, like adding a file in the tree-view:
|
||||
'context-menu':
|
||||
'.tree-view':
|
||||
'Add file': 'tree-view:add-file'
|
||||
'#workspace-view':
|
||||
'.workspace':
|
||||
'Inspect Element': 'core:inspect'
|
||||
```
|
||||
|
||||
|
||||
@@ -34,16 +34,21 @@
|
||||
'escape': 'editor:consolidate-selections'
|
||||
|
||||
# allow standard input fields to work correctly
|
||||
'input:not(.hidden-input), .native-key-bindings':
|
||||
'body .native-key-bindings':
|
||||
'tab': 'core:focus-next'
|
||||
'shift-tab': 'core:focus-previous'
|
||||
'enter': 'native!'
|
||||
'backspace': 'native!'
|
||||
'shift-backspace': 'native!'
|
||||
'delete': 'native!'
|
||||
'left': 'native!'
|
||||
'right': 'native!'
|
||||
'shift-left': 'native!'
|
||||
'shift-right': 'native!'
|
||||
'backspace': 'native!'
|
||||
'shift-backspace': 'native!'
|
||||
'delete': 'native!'
|
||||
'alt-left': 'native!'
|
||||
'alt-right': 'native!'
|
||||
'alt-shift-left': 'native!'
|
||||
'alt-shift-right': 'native!'
|
||||
'ctrl-b': 'native!'
|
||||
'ctrl-f': 'native!'
|
||||
'ctrl-F': 'native!'
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
'cmd-k cmd-9': 'editor:fold-at-indent-level-9'
|
||||
|
||||
# allow standard input fields to work correctly
|
||||
'body.platform-darwin input:not(.hidden-input), body.platform-darwin .native-key-bindings':
|
||||
'body.platform-darwin .native-key-bindings':
|
||||
'cmd-z': 'native!'
|
||||
'cmd-Z': 'native!'
|
||||
'cmd-x': 'native!'
|
||||
|
||||
@@ -165,7 +165,6 @@
|
||||
{ label: "Install &update", command: 'application:install-update', visible: false }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Documentation', command: 'application:open-documentation' }
|
||||
{ label: 'Report an &Issue', command: 'application:report-issue' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
}
|
||||
|
||||
37
package.json
37
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"version": "39.0.0",
|
||||
"version": "0.40.0",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -9,7 +9,13 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"atomShellVersion": "0.6.11",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache",
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.7.3",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"bootstrap": "git://github.com/benogle/bootstrap.git",
|
||||
@@ -35,7 +41,7 @@
|
||||
"season": "0.14.0",
|
||||
"semver": "1.1.4",
|
||||
"space-pen": "2.0.1",
|
||||
"telepath": "0.45.0",
|
||||
"telepath": "0.45.1",
|
||||
"temp": "0.5.0",
|
||||
"underscore-plus": "0.3.0"
|
||||
},
|
||||
@@ -64,9 +70,9 @@
|
||||
"rimraf": "~2.2.2"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-light-ui": "0.9.0",
|
||||
"atom-light-ui": "0.11.0",
|
||||
"atom-light-syntax": "0.6.0",
|
||||
"atom-dark-ui": "0.9.0",
|
||||
"atom-dark-ui": "0.10.0",
|
||||
"atom-dark-syntax": "0.6.0",
|
||||
"base16-tomorrow-dark-theme": "0.6.0",
|
||||
"solarized-dark-syntax": "0.4.0",
|
||||
@@ -75,23 +81,24 @@
|
||||
"autoflow": "0.11.0",
|
||||
"autosave": "0.9.0",
|
||||
"bookmarks": "0.15.0",
|
||||
"bracket-matcher": "0.14.0",
|
||||
"bracket-matcher": "0.15.0",
|
||||
"command-logger": "0.8.0",
|
||||
"command-palette": "0.11.0",
|
||||
"dev-live-reload": "0.18.0",
|
||||
"editor-stats": "0.8.0",
|
||||
"exception-reporting": "0.8.0",
|
||||
"find-and-replace": "0.54.0",
|
||||
"feedback": "0.9.0",
|
||||
"find-and-replace": "0.55.0",
|
||||
"fuzzy-finder": "0.27.0",
|
||||
"gists": "0.12.0",
|
||||
"git-diff": "0.19.0",
|
||||
"github-sign-in": "0.13.0",
|
||||
"go-to-line": "0.12.0",
|
||||
"grammar-selector": "0.13.0",
|
||||
"image-view": "0.9.0",
|
||||
"image-view": "0.10.0",
|
||||
"keybinding-resolver": "0.6.0",
|
||||
"link": "0.10.0",
|
||||
"markdown-preview": "0.21.0",
|
||||
"link": "0.11.0",
|
||||
"markdown-preview": "0.22.0",
|
||||
"metrics": "0.12.0",
|
||||
"package-generator": "0.23.0",
|
||||
"release-notes": "0.13.0",
|
||||
@@ -100,13 +107,14 @@
|
||||
"spell-check": "0.17.0",
|
||||
"status-bar": "0.23.0",
|
||||
"styleguide": "0.17.0",
|
||||
"symbols-view": "0.26.0",
|
||||
"tabs": "0.14.1",
|
||||
"symbols-view": "0.27.0",
|
||||
"tabs": "0.15.0",
|
||||
"terminal": "0.23.0",
|
||||
"timecop": "0.11.0",
|
||||
"to-the-hubs": "0.15.0",
|
||||
"tree-view": "0.41.0",
|
||||
"tree-view": "0.42.0",
|
||||
"visual-bell": "0.6.0",
|
||||
"welcome": "0.1.0",
|
||||
"whitespace": "0.10.0",
|
||||
"wrap-guide": "0.8.0",
|
||||
"language-c": "0.2.0",
|
||||
@@ -141,7 +149,8 @@
|
||||
"language-todo": "0.2.0",
|
||||
"language-toml": "0.7.0",
|
||||
"language-xml": "0.2.0",
|
||||
"language-yaml": "0.1.0"
|
||||
"language-yaml": "0.1.0",
|
||||
"grunt-download-atom-shell": "0.1.1"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
Binary file not shown.
@@ -2730,21 +2730,6 @@ describe "EditorView", ->
|
||||
expect(buffer.lineForRow(15)).toBeUndefined()
|
||||
expect(editorView.getCursorBufferPosition()).toEqual [13, 0]
|
||||
|
||||
describe "editor:save-debug-snapshot", ->
|
||||
it "saves the state of the rendered lines, the display buffer, and the buffer to a file of the user's choosing", ->
|
||||
saveDialogCallback = null
|
||||
spyOn(atom, 'showSaveDialog').andCallFake (callback) -> saveDialogCallback = callback
|
||||
spyOn(fs, 'writeFileSync')
|
||||
|
||||
editorView.trigger 'editor:save-debug-snapshot'
|
||||
|
||||
statePath = path.join(temp.dir, 'state')
|
||||
expect(atom.showSaveDialog).toHaveBeenCalled()
|
||||
saveDialogCallback(statePath)
|
||||
expect(fs.writeFileSync).toHaveBeenCalled()
|
||||
expect(fs.writeFileSync.argsForCall[0][0]).toBe statePath
|
||||
expect(typeof fs.writeFileSync.argsForCall[0][1]).toBe 'string'
|
||||
|
||||
describe "when the escape key is pressed on the editor view", ->
|
||||
it "clears multiple selections if there are any, and otherwise allows other bindings to be handled", ->
|
||||
atom.keymap.bindKeys 'name', '.editor', 'escape': 'test-event'
|
||||
@@ -2847,3 +2832,22 @@ describe "EditorView", ->
|
||||
setEditorWidthInChars(editorView, 100)
|
||||
$(window).trigger 'resize'
|
||||
expect(editorView.editor.getSoftWrapColumn()).toBe 100
|
||||
|
||||
describe "character width caching", ->
|
||||
describe "when soft wrap is enabled", ->
|
||||
it "correctly calculates the the position left for a column", ->
|
||||
editor.setSoftWrap(true)
|
||||
editorView.setText('lllll 00000')
|
||||
editorView.setFontFamily('serif')
|
||||
editorView.setFontSize(10)
|
||||
editorView.attachToDom()
|
||||
editorView.setWidthInChars(5)
|
||||
|
||||
expect(editorView.pixelPositionForScreenPosition([0, 5]).left).toEqual 15
|
||||
expect(editorView.pixelPositionForScreenPosition([1, 5]).left).toEqual 25
|
||||
|
||||
# Check that widths are actually being cached
|
||||
spyOn(editorView, 'measureToColumn').andCallThrough()
|
||||
editorView.pixelPositionForScreenPosition([0, 5])
|
||||
editorView.pixelPositionForScreenPosition([1, 5])
|
||||
expect(editorView.measureToColumn.callCount).toBe 0
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Start the crash reporter before anything else.
|
||||
require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub')
|
||||
|
||||
try
|
||||
require '../src/window'
|
||||
Atom = require '../src/atom'
|
||||
|
||||
@@ -352,6 +352,10 @@ class Atom
|
||||
getVersion: ->
|
||||
app.getVersion()
|
||||
|
||||
# Public: Gets the user agent of the atom instance.
|
||||
getUserAgent: ->
|
||||
"GitHubAtom/#{app.getVersion()}"
|
||||
|
||||
# Public: Get the directory path to Atom's configuration area.
|
||||
#
|
||||
# Returns the absolute path to ~/.atom
|
||||
|
||||
@@ -349,8 +349,8 @@ class AtomApplication
|
||||
# A Boolean which controls whether any newly opened windows should be in
|
||||
# dev mode or not.
|
||||
promptForPath: ({devMode}={}) ->
|
||||
pathsToOpen = dialog.showOpenDialog title: 'Open', properties: ['openFile', 'openDirectory', 'multiSelections', 'createDirectory']
|
||||
@openPaths({pathsToOpen, devMode})
|
||||
dialog.showOpenDialog title: 'Open', properties: ['openFile', 'openDirectory', 'multiSelections', 'createDirectory'], (pathsToOpen) =>
|
||||
@openPaths({pathsToOpen, devMode})
|
||||
|
||||
# Public: If an update is available, it returns the new version string
|
||||
# otherwise it returns null.
|
||||
|
||||
@@ -67,9 +67,7 @@ delegate.browserMainParts.preMainMessageLoopRun = ->
|
||||
global.devResourcePath = path.join(app.getHomeDir(), 'github', 'atom')
|
||||
|
||||
setupCrashReporter = ->
|
||||
crashReporter.setCompanyName 'GitHub'
|
||||
crashReporter.setSubmissionUrl 'https://speakeasy.githubapp.com/submit_crash_log'
|
||||
crashReporter.setAutoSubmit true
|
||||
crashReporter.start(productName: 'Atom', companyName: 'GitHub')
|
||||
|
||||
setupAutoUpdater = ->
|
||||
autoUpdater.setFeedUrl 'https://speakeasy.githubapp.com/apps/27/appcast.xml'
|
||||
@@ -92,11 +90,11 @@ parseCommandLine = ->
|
||||
options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.')
|
||||
args = options.argv
|
||||
|
||||
if args.h
|
||||
if args.help
|
||||
process.stdout.write(options.help())
|
||||
process.exit(0)
|
||||
|
||||
if args.v
|
||||
if args.version
|
||||
process.stdout.write("#{version}\n")
|
||||
process.exit(0)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class ContextMenuManager
|
||||
@devModeDefinitions = {}
|
||||
@activeElement = null
|
||||
|
||||
@devModeDefinitions['#workspace-view'] = [
|
||||
@devModeDefinitions['.workspace'] = [
|
||||
label: 'Inspect Element'
|
||||
command: 'application:inspect'
|
||||
executeAtBuild: (e) ->
|
||||
|
||||
@@ -584,12 +584,6 @@ class DisplayBuffer
|
||||
line = @lineForRow(row).text
|
||||
console.log row, line, line.length
|
||||
|
||||
getDebugSnapshot: ->
|
||||
lines = ["Display Buffer:"]
|
||||
for screenLine, row in @linesForRows(0, @getLastRow())
|
||||
lines.push "#{row}: #{screenLine.text}"
|
||||
lines.join('\n')
|
||||
|
||||
### Internal ###
|
||||
|
||||
handleTokenizedBufferChange: (tokenizedBufferChange) =>
|
||||
|
||||
@@ -206,7 +206,6 @@ class EditorView extends View
|
||||
'editor:duplicate-line': @duplicateLine
|
||||
'editor:join-line': @joinLine
|
||||
'editor:toggle-indent-guide': => atom.config.toggle('editor.showIndentGuide')
|
||||
'editor:save-debug-snapshot': @saveDebugSnapshot
|
||||
'editor:toggle-line-numbers': => atom.config.toggle('editor.showLineNumbers')
|
||||
'editor:scroll-to-cursor': @scrollToCursorPosition
|
||||
|
||||
@@ -613,31 +612,34 @@ class EditorView extends View
|
||||
# {Delegates to: Editor.getPath}
|
||||
getPath: -> @editor?.getPath()
|
||||
|
||||
# {Delegates to: TextBuffer.getLineCount}
|
||||
# {Delegates to: Editor.transact}
|
||||
transact: (fn) -> @editor.transact(fn)
|
||||
|
||||
# {Delegates to: TextBuffer.getLineCount}
|
||||
getLineCount: -> @getBuffer().getLineCount()
|
||||
|
||||
# {Delegates to: TextBuffer.getLastRow}
|
||||
# {Delegates to: TextBuffer.getLastRow}
|
||||
getLastBufferRow: -> @getBuffer().getLastRow()
|
||||
|
||||
# {Delegates to: TextBuffer.getTextInRange}
|
||||
# {Delegates to: TextBuffer.getTextInRange}
|
||||
getTextInRange: (range) -> @getBuffer().getTextInRange(range)
|
||||
|
||||
# {Delegates to: TextBuffer.getEofPosition}
|
||||
# {Delegates to: TextBuffer.getEofPosition}
|
||||
getEofPosition: -> @getBuffer().getEofPosition()
|
||||
|
||||
# {Delegates to: TextBuffer.lineForRow}
|
||||
# {Delegates to: TextBuffer.lineForRow}
|
||||
lineForBufferRow: (row) -> @getBuffer().lineForRow(row)
|
||||
|
||||
# {Delegates to: TextBuffer.lineLengthForRow}
|
||||
# {Delegates to: TextBuffer.lineLengthForRow}
|
||||
lineLengthForBufferRow: (row) -> @getBuffer().lineLengthForRow(row)
|
||||
|
||||
# {Delegates to: TextBuffer.rangeForRow}
|
||||
# {Delegates to: TextBuffer.rangeForRow}
|
||||
rangeForBufferRow: (row) -> @getBuffer().rangeForRow(row)
|
||||
|
||||
# {Delegates to: TextBuffer.scanInRange}
|
||||
# {Delegates to: TextBuffer.scanInRange}
|
||||
scanInBufferRange: (args...) -> @getBuffer().scanInRange(args...)
|
||||
|
||||
# {Delegates to: TextBuffer.backwardsScanInRange}
|
||||
# {Delegates to: TextBuffer.backwardsScanInRange}
|
||||
backwardsScanInBufferRange: (args...) -> @getBuffer().backwardsScanInRange(args...)
|
||||
|
||||
### Internal ###
|
||||
@@ -975,9 +977,11 @@ class EditorView extends View
|
||||
@setWidthInChars()
|
||||
@editor.setSoftWrap(not @editor.getSoftWrap())
|
||||
|
||||
# Private:
|
||||
calculateWidthInChars: ->
|
||||
Math.floor(@scrollView.width() / @charWidth)
|
||||
|
||||
# Private:
|
||||
calculateHeightInLines: ->
|
||||
Math.ceil($(window).height() / @lineHeight)
|
||||
|
||||
@@ -1062,6 +1066,7 @@ class EditorView extends View
|
||||
super
|
||||
atom.workspaceView?.focus()
|
||||
|
||||
# Private:
|
||||
beforeRemove: ->
|
||||
@trigger 'editor:will-be-removed'
|
||||
@removed = true
|
||||
@@ -1588,36 +1593,32 @@ class EditorView extends View
|
||||
@renderedLines[0].removeChild(lineElement)
|
||||
{ top: row * @lineHeight, left }
|
||||
|
||||
positionLeftForLineAndColumn: (lineElement, screenRow, column) ->
|
||||
return 0 if column == 0
|
||||
positionLeftForLineAndColumn: (lineElement, screenRow, screenColumn) ->
|
||||
return 0 if screenColumn == 0
|
||||
|
||||
bufferRow = @bufferRowsForScreenRows(screenRow, screenRow)[0] ? screenRow
|
||||
bufferColumn = @bufferPositionForScreenPosition([screenRow, screenColumn]).column
|
||||
tokenizedLine = @editor.displayBuffer.tokenizedBuffer.tokenizedLines[bufferRow]
|
||||
|
||||
left = 0
|
||||
index = 0
|
||||
startIndex = @bufferPositionForScreenPosition([screenRow, 0]).column
|
||||
for token in tokenizedLine.tokens
|
||||
for char in token.value
|
||||
return left if index >= column
|
||||
return left if index >= bufferColumn
|
||||
|
||||
val = @getCharacterWidthCache(token.scopes, char)
|
||||
if val?
|
||||
left += val
|
||||
else
|
||||
return @measureToColumn(lineElement, tokenizedLine, column)
|
||||
if index >= startIndex
|
||||
val = @getCharacterWidthCache(token.scopes, char)
|
||||
if val?
|
||||
left += val
|
||||
else
|
||||
return @measureToColumn(lineElement, tokenizedLine, screenColumn, startIndex)
|
||||
|
||||
index++
|
||||
left
|
||||
|
||||
scopesForColumn: (tokenizedLine, column) ->
|
||||
index = 0
|
||||
for token in tokenizedLine.tokens
|
||||
for char in token.value
|
||||
return token.scopes if index == column
|
||||
index++
|
||||
null
|
||||
|
||||
measureToColumn: (lineElement, tokenizedLine, column) ->
|
||||
# Private:
|
||||
measureToColumn: (lineElement, tokenizedLine, screenColumn, lineStartBufferColumn) ->
|
||||
left = oldLeft = index = 0
|
||||
iterator = document.createNodeIterator(lineElement, NodeFilter.SHOW_TEXT, TextNodeFilter)
|
||||
|
||||
@@ -1631,13 +1632,13 @@ class EditorView extends View
|
||||
|
||||
for char, i in content
|
||||
# Don't continue caching long lines :racehorse:
|
||||
break if index > LongLineLength and column < index
|
||||
break if index > LongLineLength and screenColumn < index
|
||||
|
||||
# Dont return right away, finish caching the whole line
|
||||
returnLeft = left if index == column
|
||||
returnLeft = left if index == screenColumn
|
||||
oldLeft = left
|
||||
|
||||
scopes = @scopesForColumn(tokenizedLine, index)
|
||||
scopes = tokenizedLine.tokenAtBufferColumn(lineStartBufferColumn + index)?.scopes
|
||||
cachedCharWidth = @getCharacterWidthCache(scopes, char)
|
||||
|
||||
if cachedCharWidth?
|
||||
@@ -1656,12 +1657,13 @@ class EditorView extends View
|
||||
|
||||
# Assume all the characters are the same width when dealing with long
|
||||
# lines :racehorse:
|
||||
return column * cachedCharWidth if index > LongLineLength
|
||||
return screenColumn * cachedCharWidth if index > LongLineLength
|
||||
|
||||
index++
|
||||
|
||||
returnLeft ? left
|
||||
|
||||
# Private:
|
||||
getCharacterWidthCache: (scopes, char) ->
|
||||
scopes ?= NoScope
|
||||
obj = EditorView.characterWidthCache
|
||||
@@ -1670,6 +1672,7 @@ class EditorView extends View
|
||||
return null unless obj?
|
||||
obj[char]
|
||||
|
||||
# Private:
|
||||
setCharacterWidthCache: (scopes, char, val) ->
|
||||
scopes ?= NoScope
|
||||
obj = EditorView.characterWidthCache
|
||||
@@ -1678,6 +1681,7 @@ class EditorView extends View
|
||||
obj = obj[scope]
|
||||
obj[char] = val
|
||||
|
||||
# Private:
|
||||
clearCharacterWidthCache: ->
|
||||
EditorView.characterWidthCache = {}
|
||||
|
||||
@@ -1845,30 +1849,12 @@ class EditorView extends View
|
||||
logCursorScope: ->
|
||||
console.log @editor.getCursorScopes()
|
||||
|
||||
transact: (fn) -> @editor.transact(fn)
|
||||
beginTransaction: -> @editor.beginTransaction()
|
||||
|
||||
commitTransaction: -> @editor.commitTransaction()
|
||||
|
||||
abortTransaction: -> @editor.abortTransaction()
|
||||
|
||||
saveDebugSnapshot: ->
|
||||
atom.showSaveDialog (path) =>
|
||||
fs.writeFileSync(path, @getDebugSnapshot()) if path
|
||||
|
||||
getDebugSnapshot: ->
|
||||
[
|
||||
"Debug Snapshot: #{@getPath()}"
|
||||
@getRenderedLinesDebugSnapshot()
|
||||
@editor.getDebugSnapshot()
|
||||
@getBuffer().getDebugSnapshot()
|
||||
].join('\n\n')
|
||||
|
||||
getRenderedLinesDebugSnapshot: ->
|
||||
lines = ['Rendered Lines:']
|
||||
firstRenderedScreenRow = @firstRenderedScreenRow
|
||||
@renderedLines.find('.line').each (n) ->
|
||||
lines.push "#{firstRenderedScreenRow + n}: #{$(this).text()}"
|
||||
lines.join('\n')
|
||||
|
||||
logScreenLines: (start, end) ->
|
||||
@editor.logScreenLines(start, end)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ TextMateScopeSelector = require('first-mate').ScopeSelector
|
||||
|
||||
# Public: The core model of Atom.
|
||||
#
|
||||
# An {Editor} represents a unique view of each document, with it's own
|
||||
# An {Editor} represents a unique view of each document, with its own
|
||||
# {Cursor}s and scroll position.
|
||||
#
|
||||
# For instance if a user creates a split, Atom creates a second {Editor}
|
||||
@@ -1251,11 +1251,9 @@ class Editor
|
||||
|
||||
# Public: Transposes the current text selections.
|
||||
#
|
||||
# FIXME: I have no idea what this function does.
|
||||
#
|
||||
# This only works if there is more than one selection. Each selection is transferred
|
||||
# to the position of the selection after it. The last selection is transferred to the
|
||||
# position of the first.
|
||||
# The text in each selection is reversed so `abcd` would become `dcba`. The
|
||||
# characters before and after the cursor are swapped when the selection is
|
||||
# empty so `x|y` would become `y|x` where `|` is the cursor location.
|
||||
transpose: ->
|
||||
@mutateSelectedText (selection) =>
|
||||
if selection.isEmpty()
|
||||
@@ -1437,10 +1435,3 @@ class Editor
|
||||
# Private:
|
||||
getSelectionMarkerAttributes: ->
|
||||
type: 'selection', editorId: @id, invalidate: 'never'
|
||||
|
||||
# Private:
|
||||
getDebugSnapshot: ->
|
||||
[
|
||||
@displayBuffer.getDebugSnapshot()
|
||||
@displayBuffer.tokenizedBuffer.getDebugSnapshot()
|
||||
].join('\n\n')
|
||||
|
||||
@@ -226,6 +226,10 @@ class PackageManager
|
||||
{@packageDependencies} = JSON.parse(fs.readFileSync(metadataPath)) ? {}
|
||||
@packageDependencies ?= {}
|
||||
|
||||
# Temporarily ignore 'grunt-download-atom-shell' here, should remove this
|
||||
# when it became a public npm module.
|
||||
delete @packageDependencies['grunt-download-atom-shell']
|
||||
|
||||
@packageDependencies
|
||||
|
||||
# Public: Get an array of all the available package paths.
|
||||
|
||||
@@ -70,7 +70,7 @@ class PaneAxis extends View
|
||||
child.detach()
|
||||
|
||||
getContainer: ->
|
||||
@closest('#panes').view()
|
||||
@closest('.panes').view()
|
||||
|
||||
getActivePaneItem: ->
|
||||
@getActivePane()?.activeItem
|
||||
|
||||
@@ -16,7 +16,7 @@ class PaneContainer extends View
|
||||
container
|
||||
|
||||
@content: ->
|
||||
@div id: 'panes'
|
||||
@div class: 'panes'
|
||||
|
||||
initialize: (state) ->
|
||||
@destroyedItemStates = []
|
||||
|
||||
@@ -412,7 +412,7 @@ class Pane extends View
|
||||
|
||||
# Private:
|
||||
getContainer: ->
|
||||
@closest('#panes').view()
|
||||
@closest('.panes').view()
|
||||
|
||||
# Private:
|
||||
copyActiveItem: ->
|
||||
|
||||
@@ -105,18 +105,6 @@ class Project extends telepath.Model
|
||||
getRootDirectory: ->
|
||||
@rootDirectory
|
||||
|
||||
# Public: Determines if a path is ignored via Atom configuration.
|
||||
isPathIgnored: (path) ->
|
||||
for segment in path.split("/")
|
||||
ignoredNames = atom.config.get("core.ignoredNames") or []
|
||||
return true if _.contains(ignoredNames, segment)
|
||||
|
||||
@ignoreRepositoryPath(path)
|
||||
|
||||
# Public: Determines if a given path is ignored via repository configuration.
|
||||
ignoreRepositoryPath: (repositoryPath) ->
|
||||
atom.config.get("core.hideGitIgnoredFiles") and @repo?.isPathIgnored(path.join(@getPath(), repositoryPath))
|
||||
|
||||
# Public: Given a uri, this resolves it relative to the project directory. If
|
||||
# the path is already absolute or if it is prefixed with a scheme, it is
|
||||
# returned unchanged.
|
||||
@@ -193,11 +181,13 @@ class Project extends telepath.Model
|
||||
getBuffers: ->
|
||||
new Array(@buffers.getValues()...)
|
||||
|
||||
# Private: Is the buffer for the given path modified?
|
||||
isPathModified: (filePath) ->
|
||||
@findBufferForPath(@resolve(filePath))?.isModified()
|
||||
|
||||
# Private:
|
||||
findBufferForPath: (filePath) ->
|
||||
_.find @buffers.getValues(), (buffer) -> buffer.getPath() == filePath
|
||||
_.find @buffers.getValues(), (buffer) -> buffer.getPath() == filePath
|
||||
|
||||
# Private: Only to be used in specs
|
||||
bufferForPathSync: (filePath) ->
|
||||
|
||||
@@ -25,7 +25,10 @@ class SelectList extends View
|
||||
inputThrottle: 50
|
||||
cancelling: false
|
||||
|
||||
# Public:
|
||||
# Public: Initialize the select list view.
|
||||
#
|
||||
# This method can be overridden by subclasses but `super` should always
|
||||
# be called.
|
||||
initialize: ->
|
||||
@miniEditor.getBuffer().on 'changed', => @schedulePopulateList()
|
||||
@miniEditor.hiddenInput.on 'focusout', => @cancel() unless @cancelling
|
||||
@@ -57,12 +60,16 @@ class SelectList extends View
|
||||
@populateList() if @isOnDom()
|
||||
@scheduleTimeout = setTimeout(populateCallback, @inputThrottle)
|
||||
|
||||
# Public:
|
||||
setArray: (@array) ->
|
||||
# Public: Set the array of items to display in the list.
|
||||
#
|
||||
# * array: The array of model elements to display in the list.
|
||||
setArray: (@array=[]) ->
|
||||
@populateList()
|
||||
@setLoading()
|
||||
|
||||
# Public:
|
||||
# Public: Set the error message to display.
|
||||
#
|
||||
# * message: The error message.
|
||||
setError: (message='') ->
|
||||
if message.length is 0
|
||||
@error.text('').hide()
|
||||
@@ -70,7 +77,9 @@ class SelectList extends View
|
||||
@setLoading()
|
||||
@error.text(message).show()
|
||||
|
||||
# Public:
|
||||
# Public: Set the loading message to display.
|
||||
#
|
||||
# * message: The loading message.
|
||||
setLoading: (message='') ->
|
||||
if message.length is 0
|
||||
@loading.text("")
|
||||
@@ -81,11 +90,18 @@ class SelectList extends View
|
||||
@loading.text(message)
|
||||
@loadingArea.show()
|
||||
|
||||
# Public:
|
||||
# Public: Get the filter query to use when fuzzy filtering the visible
|
||||
# elements.
|
||||
#
|
||||
# By default this method returns the text in the mini editor but it can be
|
||||
# overridden by subclasses if needed.
|
||||
#
|
||||
# Returns a {String} to use when fuzzy filtering the elements to display.
|
||||
getFilterQuery: ->
|
||||
@miniEditor.getText()
|
||||
|
||||
# Public:
|
||||
# Public: Build the DOM elements using the array from the last call to
|
||||
# {.setArray}.
|
||||
populateList: ->
|
||||
return unless @array?
|
||||
|
||||
@@ -109,7 +125,12 @@ class SelectList extends View
|
||||
else
|
||||
@setError(@getEmptyMessage(@array.length, filteredArray.length))
|
||||
|
||||
# Public:
|
||||
# Public: Get the message to display when there are no items.
|
||||
#
|
||||
# Subclasses may override this method to customize the message.
|
||||
#
|
||||
# * itemCount: The number of items in the array specified to {.setArray}
|
||||
# * filteredItemCount: The number of items that pass the fuzzy filter test.
|
||||
getEmptyMessage: (itemCount, filteredItemCount) -> 'No matches found'
|
||||
|
||||
# Private:
|
||||
@@ -124,14 +145,14 @@ class SelectList extends View
|
||||
item = @list.find('li:first') unless item.length
|
||||
@selectItem(item)
|
||||
|
||||
# Public:
|
||||
# Private:
|
||||
selectItem: (item) ->
|
||||
return unless item.length
|
||||
@list.find('.selected').removeClass('selected')
|
||||
item.addClass 'selected'
|
||||
@scrollToItem(item)
|
||||
|
||||
# Public:
|
||||
# Private:
|
||||
scrollToItem: (item) ->
|
||||
scrollTop = @list.scrollTop()
|
||||
desiredTop = item.position().top + scrollTop
|
||||
@@ -142,15 +163,19 @@ class SelectList extends View
|
||||
else if desiredBottom > @list.scrollBottom()
|
||||
@list.scrollBottom(desiredBottom)
|
||||
|
||||
# Public:
|
||||
# Public: Get the selected DOM element.
|
||||
#
|
||||
# Call {.getSelectedElement} to get the selected model element.
|
||||
getSelectedItem: ->
|
||||
@list.find('li.selected')
|
||||
|
||||
# Public:
|
||||
# Public: Get the selected model element.
|
||||
#
|
||||
# Call {.getSelectedItem} to get the selected DOM element.
|
||||
getSelectedElement: ->
|
||||
@getSelectedItem().data('select-list-element')
|
||||
|
||||
# Public:
|
||||
# Private:
|
||||
confirmSelection: ->
|
||||
element = @getSelectedElement()
|
||||
if element?
|
||||
@@ -158,6 +183,13 @@ class SelectList extends View
|
||||
else
|
||||
@cancel()
|
||||
|
||||
# Public: Callback function for when a selection is made.
|
||||
#
|
||||
# This method should be overridden by subclasses.
|
||||
#
|
||||
# * element: The selected model element.
|
||||
confirmed: (element) ->
|
||||
|
||||
# Private:
|
||||
attach: ->
|
||||
@storeFocusedElement()
|
||||
@@ -173,12 +205,12 @@ class SelectList extends View
|
||||
else
|
||||
atom.workspaceView.focus()
|
||||
|
||||
# Public:
|
||||
# Private:
|
||||
cancelled: ->
|
||||
@miniEditor.setText('')
|
||||
@miniEditor.updateDisplay()
|
||||
|
||||
# Public:
|
||||
# Public: Cancel and close the select list dialog.
|
||||
cancel: ->
|
||||
@list.empty()
|
||||
@cancelling = true
|
||||
|
||||
@@ -670,9 +670,3 @@ class TextBuffer extends telepath.Model
|
||||
for row in [start..end]
|
||||
line = @lineForRow(row)
|
||||
console.log row, line, line.length
|
||||
|
||||
getDebugSnapshot: ->
|
||||
lines = ['TextBuffer:']
|
||||
for row in [0..@getLastRow()]
|
||||
lines.push "#{row}: #{@lineForRow(row)}"
|
||||
lines.join('\n')
|
||||
|
||||
@@ -322,9 +322,3 @@ class TokenizedBuffer
|
||||
for row in [start..end]
|
||||
line = @lineForScreenRow(row).text
|
||||
console.log row, line, line.length
|
||||
|
||||
getDebugSnapshot: ->
|
||||
lines = ["Tokenized Buffer:"]
|
||||
for screenLine, row in @linesForScreenRows(0, @getLastRow())
|
||||
lines.push "#{row}: #{screenLine.text}"
|
||||
lines.join('\n')
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Like sands through the hourglass, so are the days of our lives.
|
||||
startTime = Date.now()
|
||||
|
||||
# Start the crash reporter before anything else.
|
||||
require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub')
|
||||
|
||||
require './window'
|
||||
|
||||
Atom = require './atom'
|
||||
|
||||
@@ -54,10 +54,10 @@ class WorkspaceView extends View
|
||||
|
||||
# Private:
|
||||
@content: (state) ->
|
||||
@div id: 'workspace', tabindex: -1, =>
|
||||
@div id: 'horizontal', outlet: 'horizontal', =>
|
||||
@div id: 'vertical', outlet: 'vertical', =>
|
||||
@div outlet: 'panes'
|
||||
@div class: 'workspace', tabindex: -1, =>
|
||||
@div class: 'horizontal', outlet: 'horizontal', =>
|
||||
@div class: 'vertical', outlet: 'vertical', =>
|
||||
@div class: 'panes', outlet: 'panes'
|
||||
|
||||
# Private:
|
||||
@deserialize: (state) ->
|
||||
|
||||
@@ -21,19 +21,19 @@ h6 {
|
||||
font-family: @font-family;
|
||||
}
|
||||
|
||||
#workspace {
|
||||
.workspace {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background-color: @app-background-color;
|
||||
font-family: @font-family;
|
||||
|
||||
#horizontal {
|
||||
.horizontal {
|
||||
display: -webkit-flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#vertical {
|
||||
.vertical {
|
||||
display: -webkit-flex;
|
||||
-webkit-flex: 1;
|
||||
-webkit-flex-flow: column;
|
||||
@@ -45,7 +45,7 @@ h6 {
|
||||
content: ""; // This is not a space, it is a skull and crossbones
|
||||
}
|
||||
|
||||
padding: @component-icon-padding;
|
||||
padding: 0 @component-icon-padding;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
@@ -57,7 +57,7 @@ h6 {
|
||||
}
|
||||
}
|
||||
|
||||
#panes {
|
||||
.panes {
|
||||
position: relative;
|
||||
-webkit-flex: 1;
|
||||
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
|
||||
request = require 'request'
|
||||
formidable = require 'formidable'
|
||||
unzip = require 'unzip'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn, mkdir, rm, cp} = require('./task-helpers')(grunt)
|
||||
|
||||
accessToken = null
|
||||
getTokenFromKeychain = (callback) ->
|
||||
accessToken ?= process.env['ATOM_ACCESS_TOKEN']
|
||||
if accessToken
|
||||
callback(null, accessToken)
|
||||
return
|
||||
|
||||
spawn {cmd: 'security', args: ['-q', 'find-generic-password', '-ws', 'GitHub API Token']}, (error, result, code) ->
|
||||
accessToken = result.stdout unless error?
|
||||
callback(error, accessToken)
|
||||
|
||||
callAtomShellReposApi = (path, callback) ->
|
||||
getTokenFromKeychain (error, accessToken) ->
|
||||
if error
|
||||
callback(error)
|
||||
return
|
||||
|
||||
options =
|
||||
url: "https://api.github.com/repos/atom/atom-shell#{path}"
|
||||
proxy: process.env.http_proxy || process.env.https_proxy
|
||||
headers:
|
||||
authorization: "token #{accessToken}"
|
||||
accept: 'application/vnd.github.manifold-preview'
|
||||
'user-agent': 'Atom'
|
||||
|
||||
request options, (error, response, body) ->
|
||||
if not error?
|
||||
body = JSON.parse(body)
|
||||
error = new Error(body.message) if response.statusCode != 200
|
||||
callback(error, response, body)
|
||||
|
||||
findReleaseIdFromAtomShellVersion = (version, callback) ->
|
||||
callAtomShellReposApi '/releases', (error, response, data) ->
|
||||
if error?
|
||||
grunt.log.error('GitHub API failed to access atom-shell releases')
|
||||
callback(error)
|
||||
else
|
||||
for release in data when release.tag_name is version
|
||||
callback(null, release.id)
|
||||
return
|
||||
grunt.log.error("There is no #{version} release of atom-shell")
|
||||
callback(false)
|
||||
|
||||
getAtomShellDownloadUrl = (version, releaseId, callback) ->
|
||||
callAtomShellReposApi "/releases/#{releaseId}/assets", (error, response, data) ->
|
||||
if error?
|
||||
grunt.log.error("Cannot get assets of atom-shell's #{version} release")
|
||||
callback(error)
|
||||
else
|
||||
filename = "atom-shell-#{version}-#{process.platform}.zip"
|
||||
for asset in data when asset.name is filename and asset.state is 'uploaded'
|
||||
callback(null, asset.url)
|
||||
return
|
||||
grunt.log.error("Cannot get url of atom-shell's release asset")
|
||||
callback(false)
|
||||
|
||||
getAtomShellVersion = ->
|
||||
versionPath = path.join('atom-shell', 'version')
|
||||
if grunt.file.isFile(versionPath)
|
||||
grunt.file.read(versionPath).trim()
|
||||
else
|
||||
null
|
||||
|
||||
getTempDir = ->
|
||||
if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
|
||||
getCachePath = (version) ->
|
||||
path.join(getTempDir(), 'atom-cached-atom-shells', version)
|
||||
|
||||
isAtomShellVersionCached = (version) ->
|
||||
grunt.file.isFile(getCachePath(version), 'version')
|
||||
|
||||
getDownloadOptions = (version, url, callback) ->
|
||||
options =
|
||||
url: url
|
||||
followRedirect: false
|
||||
proxy: process.env.http_proxy || process.env.https_proxy
|
||||
|
||||
# Only set headers for GitHub host, the url could also be a S3 link and
|
||||
# setting headers for it would make the request fail.
|
||||
if require('url').parse(url).hostname is 'api.github.com'
|
||||
getTokenFromKeychain (error, accessToken) ->
|
||||
options.headers =
|
||||
authorization: "token #{accessToken}"
|
||||
accept: 'application/octet-stream'
|
||||
'user-agent': 'Atom'
|
||||
|
||||
callback(error, options)
|
||||
else
|
||||
callback(null, options)
|
||||
|
||||
downloadAtomShell = (version, url, callback) ->
|
||||
getDownloadOptions version, url, (error, options) ->
|
||||
if error
|
||||
callback(error)
|
||||
return
|
||||
|
||||
inputStream = request(options)
|
||||
inputStream.on 'response', (response) ->
|
||||
if response.statusCode is 302
|
||||
# Manually handle redirection so headers would not be sent for S3.
|
||||
downloadAtomShell(version, response.headers.location, callback)
|
||||
else if response.statusCode is 200
|
||||
grunt.verbose.writeln("Downloading atom-shell version #{version.cyan}")
|
||||
cacheDirectory = getCachePath(version)
|
||||
rm(cacheDirectory)
|
||||
mkdir(cacheDirectory)
|
||||
|
||||
form = new formidable.IncomingForm()
|
||||
form.uploadDir = cacheDirectory
|
||||
form.maxFieldsSize = 100 * 1024 * 1024
|
||||
form.on 'file', (name, file) ->
|
||||
cacheFile = path.join(cacheDirectory, 'atom-shell.zip')
|
||||
fs.renameSync(file.path, cacheFile)
|
||||
callback(null, cacheFile)
|
||||
form.parse response, (error) ->
|
||||
if error
|
||||
grunt.log.error("atom-shell #{version.cyan} failed to download")
|
||||
else
|
||||
if response.statusCode is 404
|
||||
grunt.log.error("atom-shell #{version.cyan} not found")
|
||||
else
|
||||
grunt.log.error("atom-shell #{version.cyan} request failed")
|
||||
callback(false)
|
||||
|
||||
downloadAtomShellOfVersion = (version, callback) ->
|
||||
findReleaseIdFromAtomShellVersion version, (error, releaseId) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
getAtomShellDownloadUrl version, releaseId, (error, url) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
downloadAtomShell version, url, callback
|
||||
|
||||
unzipAtomShell = (zipPath, callback) ->
|
||||
grunt.verbose.writeln('Unzipping atom-shell')
|
||||
directoryPath = path.dirname(zipPath)
|
||||
|
||||
if process.platform is 'darwin'
|
||||
# The zip archive of darwin build contains symbol links, only the "unzip"
|
||||
# command can handle it correctly.
|
||||
spawn {cmd: 'unzip', args: [zipPath, '-d', directoryPath]}, (error) ->
|
||||
rm(zipPath)
|
||||
callback(error)
|
||||
else
|
||||
fileStream = fs.createReadStream(zipPath)
|
||||
fileStream.on('error', callback)
|
||||
zipStream = fileStream.pipe(unzip.Extract(path: directoryPath))
|
||||
zipStream.on('error', callback)
|
||||
zipStream.on 'close', ->
|
||||
rm(zipPath)
|
||||
callback(null)
|
||||
|
||||
rebuildNativeModules = (previousVersion, callback) ->
|
||||
newVersion = getAtomShellVersion()
|
||||
if newVersion and newVersion isnt previousVersion
|
||||
grunt.verbose.writeln("Rebuilding native modules for new atom-shell version #{newVersion.cyan}.")
|
||||
cmd = path.join('node_modules', '.bin', 'apm')
|
||||
cmd += ".cmd" if process.platform is 'win32'
|
||||
spawn {cmd, args: ['rebuild']}, (error) -> callback(error)
|
||||
else
|
||||
callback()
|
||||
|
||||
installAtomShell = (version) ->
|
||||
rm('atom-shell')
|
||||
cp(getCachePath(version), 'atom-shell')
|
||||
|
||||
grunt.registerTask 'update-atom-shell', 'Update atom-shell', ->
|
||||
done = @async()
|
||||
{atomShellVersion} = grunt.file.readJSON('package.json')
|
||||
if atomShellVersion
|
||||
atomShellVersion = "v#{atomShellVersion}"
|
||||
currentAtomShellVersion = getAtomShellVersion()
|
||||
if atomShellVersion isnt currentAtomShellVersion
|
||||
if isAtomShellVersionCached(atomShellVersion)
|
||||
grunt.verbose.writeln("Installing cached atom-shell #{atomShellVersion.cyan}")
|
||||
installAtomShell(atomShellVersion)
|
||||
rebuildNativeModules(currentAtomShellVersion, done)
|
||||
else
|
||||
downloadAtomShellOfVersion atomShellVersion, (error, zipPath) ->
|
||||
if error?
|
||||
done(error)
|
||||
else if zipPath?
|
||||
unzipAtomShell zipPath, (error) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
grunt.verbose.writeln("Installing atom-shell #{atomShellVersion.cyan}")
|
||||
installAtomShell(atomShellVersion)
|
||||
rebuildNativeModules(currentAtomShellVersion, done)
|
||||
else
|
||||
done(false)
|
||||
else
|
||||
done()
|
||||
else
|
||||
grunt.log.error("atom-shell version missing from package.json")
|
||||
done(false)
|
||||
2
vendor/apm
vendored
2
vendor/apm
vendored
Submodule vendor/apm updated: 809d8d42f7...49b1e740f6
Reference in New Issue
Block a user