Comparar commits
56 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| b9b7646d4b | |||
| d885fb2d13 | |||
| f5ae96820a | |||
| 435fee1433 | |||
| c96f976162 | |||
| 5115540f8e | |||
| d642553351 | |||
| fa090345a8 | |||
| 55d291ffde | |||
| 48f63926ab | |||
| b0501c9cb2 | |||
| 355ab1eb2f | |||
| 28ac51d140 | |||
| d6210b24d9 | |||
| b0731afd4c | |||
| 1c81aa90c0 | |||
| bbf6930061 | |||
| 3d149eb9d1 | |||
| 5a8b96b180 | |||
| 5add777291 | |||
| f866e69704 | |||
| b27b4387fc | |||
| 1f850f0af1 | |||
| 9f1bbc54de | |||
| e7d34d4b83 | |||
| c5a15fb50e | |||
| 7a251f5432 | |||
| dc2a453986 | |||
| fdd55dfd27 | |||
| 5147fb6a8b | |||
| 9bbbb58084 | |||
| 9ad080cd31 | |||
| 509976fa18 | |||
| aad5700418 | |||
| 09a0773043 | |||
| 2ea92cf0e5 | |||
| 9a2cc36c6b | |||
| 965a6243e1 | |||
| 503fa30c28 | |||
| b8f239cd39 | |||
| 231da60e13 | |||
| a47719eb53 | |||
| 9f851e55d1 | |||
| ab89776f01 | |||
| 2cea51b50e | |||
| 4e4794f3fd | |||
| ac6fbf100d | |||
| 8c8e866a97 | |||
| f859ad5fc5 | |||
| d30cf35a16 | |||
| c35fb90653 | |||
| 73df017d83 | |||
| 0e1ef201c1 | |||
| be4d23aa13 | |||
| c58606907a | |||
| c489a4662b |
@@ -59,6 +59,8 @@ window in dev mode. To open a Dev Mode Atom window run `atom --dev .` in the
|
||||
terminal, use `cmd-shift-o` or use the _View > Developer > Open in Dev Mode_
|
||||
menu. When you edit your theme, changes will instantly be reflected!
|
||||
|
||||
> Note: It's advised to _not_ specify a `font-family` in your syntax theme because it will override the Font Family field in Atom's settings. If you still like to recommend a font that goes well with your theme, we recommend you do so in your README.
|
||||
|
||||
## Creating an Interface Theme
|
||||
|
||||
Interface themes **must** provide a `ui-variables.less` file which contains all
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
'atom-text-editor, .overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
|
||||
+1
-1
@@ -160,7 +160,7 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
'atom-text-editor, .overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
'atom-text-editor, .overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
|
||||
+9
-9
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.160.0",
|
||||
"version": "0.162.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"reactionary-atom-fork": "^1.0.0",
|
||||
"runas": "1.0.1",
|
||||
"scandal": "1.0.3",
|
||||
"scoped-property-store": "^0.15.2",
|
||||
"scoped-property-store": "^0.15.3",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"season": "^1.0.2",
|
||||
"semver": "2.2.1",
|
||||
@@ -63,7 +63,7 @@
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.8.2",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.6.3",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
@@ -73,7 +73,7 @@
|
||||
"atom-light-ui": "0.36.0",
|
||||
"base16-tomorrow-dark-theme": "0.22.0",
|
||||
"base16-tomorrow-light-theme": "0.5.0",
|
||||
"solarized-dark-syntax": "0.27.0",
|
||||
"solarized-dark-syntax": "0.29.0",
|
||||
"solarized-light-syntax": "0.13.0",
|
||||
"archive-view": "0.40.0",
|
||||
"autocomplete": "0.34.0",
|
||||
@@ -91,7 +91,7 @@
|
||||
"fuzzy-finder": "0.62.0",
|
||||
"git-diff": "0.45.0",
|
||||
"go-to-line": "0.27.0",
|
||||
"grammar-selector": "0.38.0",
|
||||
"grammar-selector": "0.40.0",
|
||||
"image-view": "0.44.0",
|
||||
"incompatible-packages": "0.16.0",
|
||||
"keybinding-resolver": "0.24.0",
|
||||
@@ -101,20 +101,20 @@
|
||||
"notifications": "0.18.0",
|
||||
"open-on-github": "0.31.0",
|
||||
"package-generator": "0.33.0",
|
||||
"release-notes": "0.39.0",
|
||||
"release-notes": "0.40.0",
|
||||
"settings-view": "0.161.0",
|
||||
"snippets": "0.59.0",
|
||||
"spell-check": "0.45.0",
|
||||
"status-bar": "0.53.0",
|
||||
"status-bar": "0.54.0",
|
||||
"styleguide": "0.36.0",
|
||||
"symbols-view": "0.70.0",
|
||||
"tabs": "0.58.0",
|
||||
"timecop": "0.24.0",
|
||||
"tree-view": "0.138.0",
|
||||
"tree-view": "0.139.0",
|
||||
"update-package-dependencies": "0.7.0",
|
||||
"welcome": "0.21.0",
|
||||
"whitespace": "0.27.0",
|
||||
"wrap-guide": "0.26.0",
|
||||
"wrap-guide": "0.27.0",
|
||||
"language-c": "0.33.0",
|
||||
"language-clojure": "0.9.0",
|
||||
"language-coffee-script": "0.38.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package: <%= name %>
|
||||
Version: <%= version %>
|
||||
Depends: gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
|
||||
Depends: git, gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
|
||||
Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
|
||||
@@ -9,3 +9,4 @@ docker run \
|
||||
--env JANKY_BRANCH="$JANKY_BRANCH" \
|
||||
--env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \
|
||||
atom-rpm /atom/script/rpmbuild
|
||||
docker rmi atom-rpm
|
||||
|
||||
+41
-11
@@ -406,11 +406,11 @@ describe "Config", ->
|
||||
it "fires the callback every time the observed value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2'})
|
||||
|
||||
describe 'when a keyPath is not specified', ->
|
||||
beforeEach ->
|
||||
@@ -424,15 +424,21 @@ describe "Config", ->
|
||||
it "fires the callback every time any value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
|
||||
expect(observeHandler).toHaveBeenCalled()
|
||||
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe("value 2")
|
||||
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe("value 1")
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
|
||||
expect(observeHandler).toHaveBeenCalled()
|
||||
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe("value 1")
|
||||
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe("value 2")
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.set('foo.bar.int', 1)
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 1, oldValue: undefined, keyPath: 'foo.bar.int'})
|
||||
expect(observeHandler).toHaveBeenCalled()
|
||||
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.int).toBe(1)
|
||||
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.int).toBe(undefined)
|
||||
|
||||
describe ".observe(keyPath)", ->
|
||||
[observeHandler, observeSubscription] = []
|
||||
@@ -454,6 +460,10 @@ describe "Config", ->
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1")
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.loadUserConfig()
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined)
|
||||
|
||||
it "fires the callback when the observed value is deleted", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', undefined)
|
||||
@@ -482,6 +492,26 @@ describe "Config", ->
|
||||
atom.config.set('foo.bar.baz', "value 10")
|
||||
expect(bazCatHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe ".transact(callback)", ->
|
||||
changeSpy = null
|
||||
|
||||
beforeEach ->
|
||||
changeSpy = jasmine.createSpy('onDidChange callback')
|
||||
atom.config.onDidChange("foo.bar.baz", changeSpy)
|
||||
|
||||
it "allows only one change event for the duration of the given callback", ->
|
||||
atom.config.transact ->
|
||||
atom.config.set("foo.bar.baz", 1)
|
||||
atom.config.set("foo.bar.baz", 2)
|
||||
atom.config.set("foo.bar.baz", 3)
|
||||
|
||||
expect(changeSpy.callCount).toBe(1)
|
||||
expect(changeSpy.argsForCall[0][0]).toEqual(newValue: 3, oldValue: undefined)
|
||||
|
||||
it "does not emit an event if no changes occur while paused", ->
|
||||
atom.config.transact ->
|
||||
expect(changeSpy).not.toHaveBeenCalled()
|
||||
|
||||
describe ".initializeConfigDirectory()", ->
|
||||
beforeEach ->
|
||||
if fs.existsSync(dotAtomPath)
|
||||
@@ -1185,25 +1215,25 @@ describe "Config", ->
|
||||
atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy()
|
||||
|
||||
atom.config.set("foo.bar.baz", 12)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1 = atom.config.addScopedSettings("a", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2 = atom.config.addScopedSettings("b", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12})
|
||||
changeSpy.reset()
|
||||
|
||||
atom.config.set("foo.bar.baz", undefined)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined, keyPath})
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined})
|
||||
changeSpy.reset()
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
ChildProcess = require 'child_process'
|
||||
{EventEmitter} = require 'events'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
SquirrelUpdate = require '../src/browser/squirrel-update'
|
||||
|
||||
describe "Windows squirrel updates", ->
|
||||
tempHomeDirectory = null
|
||||
|
||||
beforeEach ->
|
||||
# Prevent the actually home directory from being manipulated
|
||||
tempHomeDirectory = temp.mkdirSync('atom-temp-home-')
|
||||
spyOn(fs, 'getHomeDirectory').andReturn(tempHomeDirectory)
|
||||
|
||||
# Prevent any commands from actually running and affecting the host
|
||||
originalSpawn = ChildProcess.spawn
|
||||
spyOn(ChildProcess, 'spawn').andCallFake (command, args) ->
|
||||
if path.basename(command) is 'Update.exe' and args?[0] is '--createShortcut'
|
||||
fs.writeFileSync(path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk'), '')
|
||||
|
||||
# Just spawn something that won't actually modify the host
|
||||
if process.platform is 'win32'
|
||||
originalSpawn('dir')
|
||||
else
|
||||
originalSpawn('ls')
|
||||
|
||||
it "quits the app on all squirrel events", ->
|
||||
app = quit: jasmine.createSpy('quit')
|
||||
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-uninstall')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-obsolete')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--not-squirrel')).toBe false
|
||||
|
||||
it "keeps the desktop shortcut deleted on updates if it was previously deleted after install", ->
|
||||
desktopShortcutPath = path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk')
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe false
|
||||
|
||||
app = quit: jasmine.createSpy('quit')
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
app.quit.reset()
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe true
|
||||
fs.removeSync(desktopShortcutPath)
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe false
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(fs.existsSync(desktopShortcutPath)).toBe false
|
||||
|
||||
describe ".restartAtom", ->
|
||||
it "quits the app and spawns a new one", ->
|
||||
app = new EventEmitter()
|
||||
app.quit = jasmine.createSpy('quit')
|
||||
|
||||
SquirrelUpdate.restartAtom(app)
|
||||
expect(app.quit.callCount).toBe 1
|
||||
|
||||
expect(ChildProcess.spawn.callCount).toBe 0
|
||||
app.emit('will-quit')
|
||||
expect(ChildProcess.spawn.callCount).toBe 1
|
||||
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'atom.cmd'
|
||||
@@ -1612,6 +1612,22 @@ describe "TextEditorComponent", ->
|
||||
expect(nextAnimationFrame).toBe noAnimationFrame
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[2, 4], [6, 8]]
|
||||
|
||||
describe "when the editor is destroyed while dragging", ->
|
||||
it "cleans up the handlers for window.mouseup and window.mousemove", ->
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1))
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 8]), which: 1))
|
||||
nextAnimationFrame()
|
||||
|
||||
spyOn(window, 'removeEventListener').andCallThrough()
|
||||
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 10]), which: 1))
|
||||
editor.destroy()
|
||||
nextAnimationFrame()
|
||||
|
||||
call.args.pop() for call in window.removeEventListener.calls
|
||||
expect(window.removeEventListener).toHaveBeenCalledWith('mouseup')
|
||||
expect(window.removeEventListener).toHaveBeenCalledWith('mousemove')
|
||||
|
||||
describe "when a line is folded", ->
|
||||
beforeEach ->
|
||||
editor.foldBufferRow 4
|
||||
@@ -2697,26 +2713,35 @@ describe "TextEditorComponent", ->
|
||||
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
|
||||
|
||||
describe "middle mouse paste on Linux", ->
|
||||
it "pastes the previously selected text", ->
|
||||
originalPlatform = null
|
||||
|
||||
beforeEach ->
|
||||
originalPlatform = process.platform
|
||||
Object.defineProperty process, 'platform', value: 'linux'
|
||||
|
||||
afterEach ->
|
||||
Object.defineProperty process, 'platform', value: originalPlatform
|
||||
|
||||
it "pastes the previously selected text at the clicked location", ->
|
||||
jasmine.unspy(window, 'setTimeout')
|
||||
clipboardWrittenTo = false
|
||||
spyOn(require('ipc'), 'send').andCallFake (eventName, selectedText) ->
|
||||
if eventName is 'write-text-to-selection-clipboard'
|
||||
require('clipboard').writeText(selectedText, 'selection')
|
||||
clipboardWrittenTo = true
|
||||
|
||||
atom.clipboard.write('')
|
||||
component.listenForMiddleMousePaste()
|
||||
|
||||
editor.setCursorBufferPosition([10, 0])
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
|
||||
|
||||
expect(atom.clipboard.read()).toBe ''
|
||||
expect(editor.lineTextForBufferRow(10)).toBe ''
|
||||
|
||||
component.trackSelectionClipboard()
|
||||
editor.setSelectedBufferRange([[1, 6], [1, 10]])
|
||||
editor.setCursorBufferPosition([10, 0])
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
|
||||
|
||||
expect(atom.clipboard.read()).toBe 'sort'
|
||||
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
|
||||
waitsFor ->
|
||||
clipboardWrittenTo
|
||||
|
||||
runs ->
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([10, 0]), button: 1))
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([10, 0]), which: 2))
|
||||
expect(atom.clipboard.read()).toBe 'sort'
|
||||
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
|
||||
|
||||
buildMouseEvent = (type, properties...) ->
|
||||
properties = extend({bubbles: true, cancelable: true}, properties...)
|
||||
|
||||
@@ -9,7 +9,7 @@ class AutoUpdater
|
||||
|
||||
quitAndInstall: ->
|
||||
if SquirrelUpdate.existsSync()
|
||||
SquirrelUpdate.restartAtom()
|
||||
SquirrelUpdate.restartAtom(require('app'))
|
||||
else
|
||||
require('auto-updater').quitAndInstall()
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ fs.lstatSyncNoException = (pathToStat) ->
|
||||
start = ->
|
||||
if process.platform is 'win32'
|
||||
SquirrelUpdate = require './squirrel-update'
|
||||
return if SquirrelUpdate.handleStartupEvent()
|
||||
squirrelCommand = process.argv[1]
|
||||
return if SquirrelUpdate.handleStartupEvent(app, squirrelCommand)
|
||||
|
||||
args = parseCommandLine()
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
app = require 'app'
|
||||
ChildProcess = require 'child_process'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
@@ -166,12 +165,29 @@ removeCommandsFromPath = (callback) ->
|
||||
|
||||
# Create a desktop and start menu shortcut by using the command line API
|
||||
# provided by Squirrel's Update.exe
|
||||
createShortcut = (callback) ->
|
||||
createShortcuts = (callback) ->
|
||||
spawnUpdate(['--createShortcut', exeName], callback)
|
||||
|
||||
# Update the desktop and start menu shortcuts by using the command line API
|
||||
# provided by Squirrel's Update.exe
|
||||
updateShortcuts = (callback) ->
|
||||
if homeDirectory = fs.getHomeDirectory()
|
||||
desktopShortcutPath = path.join(homeDirectory, 'Desktop', 'Atom.lnk')
|
||||
# Check if the desktop shortcut has been previously deleted and
|
||||
# and keep it deleted if it was
|
||||
fs.exists desktopShortcutPath, (desktopShortcutExists) ->
|
||||
createShortcuts ->
|
||||
if desktopShortcutExists
|
||||
callback()
|
||||
else
|
||||
# Remove the unwanted desktop shortcut that was recreated
|
||||
fs.unlink(desktopShortcutPath, callback)
|
||||
else
|
||||
createShortcuts(callback)
|
||||
|
||||
# Remove the desktop and start menu shortcuts by using the command line API
|
||||
# provided by Squirrel's Update.exe
|
||||
removeShortcut = (callback) ->
|
||||
removeShortcuts = (callback) ->
|
||||
spawnUpdate(['--removeShortcut', exeName], callback)
|
||||
|
||||
exports.spawn = spawnUpdate
|
||||
@@ -181,21 +197,29 @@ exports.existsSync = ->
|
||||
fs.existsSync(updateDotExe)
|
||||
|
||||
# Restart Atom using the version pointed to by the atom.cmd shim
|
||||
exports.restartAtom = ->
|
||||
app.once 'will-quit', -> spawn(path.join(binFolder, 'atom.cmd'))
|
||||
exports.restartAtom = (app) ->
|
||||
if projectPath = global.atomApplication?.lastFocusedWindow?.projectPath
|
||||
args = [projectPath]
|
||||
app.once 'will-quit', -> spawn(path.join(binFolder, 'atom.cmd'), args)
|
||||
app.quit()
|
||||
|
||||
# Handle squirrel events denoted by --squirrel-* command line arguments.
|
||||
exports.handleStartupEvent = ->
|
||||
switch process.argv[1]
|
||||
when '--squirrel-install', '--squirrel-updated'
|
||||
createShortcut ->
|
||||
exports.handleStartupEvent = (app, squirrelCommand) ->
|
||||
switch squirrelCommand
|
||||
when '--squirrel-install'
|
||||
createShortcuts ->
|
||||
installContextMenu ->
|
||||
addCommandsToPath ->
|
||||
app.quit()
|
||||
true
|
||||
when '--squirrel-updated'
|
||||
updateShortcuts ->
|
||||
installContextMenu ->
|
||||
addCommandsToPath ->
|
||||
app.quit()
|
||||
true
|
||||
when '--squirrel-uninstall'
|
||||
removeShortcut ->
|
||||
removeShortcuts ->
|
||||
uninstallContextMenu ->
|
||||
removeCommandsFromPath ->
|
||||
app.quit()
|
||||
|
||||
+35
-17
@@ -318,6 +318,7 @@ class Config
|
||||
@configFileHasErrors = false
|
||||
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
|
||||
@configFilePath ?= path.join(@configDirPath, 'config.cson')
|
||||
@transactDepth = 0
|
||||
|
||||
###
|
||||
Section: Config Subscription
|
||||
@@ -614,6 +615,19 @@ class Config
|
||||
getUserConfigPath: ->
|
||||
@configFilePath
|
||||
|
||||
# Extended: Suppress calls to handler functions registered with {::onDidChange}
|
||||
# and {::observe} for the duration of `callback`. After `callback` executes,
|
||||
# handlers will be called once if the value for their key-path has changed.
|
||||
#
|
||||
# * `callback` {Function} to execute while suppressing calls to handlers.
|
||||
transact: (callback) ->
|
||||
@transactDepth++
|
||||
try
|
||||
callback()
|
||||
finally
|
||||
@transactDepth--
|
||||
@emitChangeEvent()
|
||||
|
||||
###
|
||||
Section: Deprecated
|
||||
###
|
||||
@@ -749,7 +763,7 @@ class Config
|
||||
resetUserSettings: (newSettings) ->
|
||||
unless isPlainObject(newSettings)
|
||||
@settings = {}
|
||||
@emitter.emit 'did-change'
|
||||
@emitChangeEvent()
|
||||
return
|
||||
|
||||
if newSettings.global?
|
||||
@@ -800,19 +814,22 @@ class Config
|
||||
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
|
||||
value = undefined if _.isEqual(defaultValue, value)
|
||||
|
||||
oldValue = _.clone(@get(keyPath))
|
||||
_.setValueForKeyPath(@settings, keyPath, value)
|
||||
newValue = @get(keyPath)
|
||||
@emitter.emit 'did-change', {oldValue, newValue, keyPath} unless _.isEqual(newValue, oldValue)
|
||||
@emitChangeEvent()
|
||||
|
||||
observeKeyPath: (keyPath, options, callback) ->
|
||||
callback(_.clone(@get(keyPath))) unless options.callNow == false
|
||||
@emitter.on 'did-change', (event) =>
|
||||
callback(event.newValue) if keyPath? and @isSubKeyPath(keyPath, event?.keyPath)
|
||||
callback(@get(keyPath))
|
||||
@onDidChangeKeyPath keyPath, (event) -> callback(event.newValue)
|
||||
|
||||
onDidChangeKeyPath: (keyPath, callback) ->
|
||||
@emitter.on 'did-change', (event) =>
|
||||
callback(event) if not keyPath? or (keyPath? and @isSubKeyPath(keyPath, event?.keyPath))
|
||||
oldValue = @get(keyPath)
|
||||
|
||||
didChange = =>
|
||||
newValue = @get(keyPath)
|
||||
callback({oldValue, newValue}) unless _.isEqual(oldValue, newValue)
|
||||
oldValue = newValue
|
||||
|
||||
@emitter.on 'did-change', didChange
|
||||
|
||||
isSubKeyPath: (keyPath, subKeyPath) ->
|
||||
return false unless keyPath? and subKeyPath?
|
||||
@@ -821,10 +838,8 @@ class Config
|
||||
_.isEqual(pathTokens, pathSubTokens)
|
||||
|
||||
setRawDefault: (keyPath, value) ->
|
||||
oldValue = _.clone(@get(keyPath))
|
||||
_.setValueForKeyPath(@defaultSettings, keyPath, value)
|
||||
newValue = @get(keyPath)
|
||||
@emitter.emit 'did-change', {oldValue, newValue, keyPath} unless _.isEqual(newValue, oldValue)
|
||||
@emitChangeEvent()
|
||||
|
||||
setDefaults: (keyPath, defaults) ->
|
||||
if defaults? and isPlainObject(defaults)
|
||||
@@ -882,20 +897,23 @@ class Config
|
||||
Section: Private Scoped Settings
|
||||
###
|
||||
|
||||
emitChangeEvent: ->
|
||||
@emitter.emit 'did-change' unless @transactDepth > 0
|
||||
|
||||
resetUserScopedSettings: (newScopedSettings) ->
|
||||
@usersScopedSettings?.dispose()
|
||||
@usersScopedSettings = new CompositeDisposable
|
||||
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', newScopedSettings, @usersScopedSettingPriority)
|
||||
@emitter.emit 'did-change'
|
||||
@emitChangeEvent()
|
||||
|
||||
addScopedSettings: (source, selector, value, options) ->
|
||||
settingsBySelector = {}
|
||||
settingsBySelector[selector] = value
|
||||
disposable = @scopedSettingsStore.addProperties(source, settingsBySelector, options)
|
||||
@emitter.emit 'did-change'
|
||||
@emitChangeEvent()
|
||||
new Disposable =>
|
||||
disposable.dispose()
|
||||
@emitter.emit 'did-change'
|
||||
@emitChangeEvent()
|
||||
|
||||
setRawScopedValue: (selector, keyPath, value) ->
|
||||
if keyPath?
|
||||
@@ -906,7 +924,7 @@ class Config
|
||||
settingsBySelector = {}
|
||||
settingsBySelector[selector] = value
|
||||
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', settingsBySelector, @usersScopedSettingPriority)
|
||||
@emitter.emit 'did-change'
|
||||
@emitChangeEvent()
|
||||
|
||||
getRawScopedValue: (scopeDescriptor, keyPath) ->
|
||||
scopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor)
|
||||
@@ -928,7 +946,7 @@ class Config
|
||||
oldValue = @get(scopeDescriptor, keyPath)
|
||||
didChange = =>
|
||||
newValue = @get(scopeDescriptor, keyPath)
|
||||
callback({oldValue, newValue, keyPath}) unless _.isEqual(oldValue, newValue)
|
||||
callback({oldValue, newValue}) unless _.isEqual(oldValue, newValue)
|
||||
oldValue = newValue
|
||||
|
||||
@emitter.on 'did-change', didChange
|
||||
|
||||
@@ -329,7 +329,8 @@ class PackageManager
|
||||
@packageActivators.push([activator, types])
|
||||
|
||||
activatePackages: (packages) ->
|
||||
@activatePackage(pack.name) for pack in packages
|
||||
atom.config.transact =>
|
||||
@activatePackage(pack.name) for pack in packages
|
||||
@observeDisabledPackages()
|
||||
|
||||
# Activate a single package by name
|
||||
@@ -344,7 +345,8 @@ class PackageManager
|
||||
|
||||
# Deactivate all packages
|
||||
deactivatePackages: ->
|
||||
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
|
||||
atom.config.transact =>
|
||||
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
|
||||
@unobserveDisabledPackages()
|
||||
|
||||
# Deactivate the package with the given name
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
_ = require 'underscore-plus'
|
||||
child_process = require 'child_process'
|
||||
{fork} = require 'child_process'
|
||||
{Emitter} = require 'emissary'
|
||||
|
||||
# Extended: Run a node script in a separate process.
|
||||
@@ -98,7 +98,7 @@ class Task
|
||||
taskPath = taskPath.replace(/\\/g, "\\\\")
|
||||
|
||||
env = _.extend({}, process.env, {taskPath, userAgent: navigator.userAgent})
|
||||
@childProcess = child_process.fork '--eval', [bootstrap], {env, cwd: __dirname}
|
||||
@childProcess = fork '--eval', [bootstrap], {env, cwd: __dirname}
|
||||
|
||||
@on "task:log", -> console.log(arguments...)
|
||||
@on "task:warn", -> console.warn(arguments...)
|
||||
|
||||
@@ -404,7 +404,7 @@ TextEditorComponent = React.createClass
|
||||
window.addEventListener 'resize', @requestHeightAndWidthMeasurement
|
||||
|
||||
@listenForIMEEvents()
|
||||
@listenForMiddleMousePaste() if process.platform is 'linux'
|
||||
@trackSelectionClipboard() if process.platform is 'linux'
|
||||
|
||||
listenForIMEEvents: ->
|
||||
node = @getDOMNode()
|
||||
@@ -432,21 +432,21 @@ TextEditorComponent = React.createClass
|
||||
editor.insertText(selectedText, select: true, undo: 'skip')
|
||||
event.target.value = ''
|
||||
|
||||
listenForMiddleMousePaste: ->
|
||||
clipboard = require 'clipboard'
|
||||
|
||||
@refs.scrollView.getDOMNode().addEventListener 'mouseup', ({which}) =>
|
||||
return unless which is 2
|
||||
|
||||
if selection = clipboard.readText('selection')
|
||||
@props.editor.insertText(selection)
|
||||
|
||||
@subscribe @props.editor.onDidChangeSelectionRange =>
|
||||
if selectedText = @props.editor.getSelectedText()
|
||||
# Listen for selection changes and store the currently selected text
|
||||
# in the selection clipboard. This is only applicable on Linux.
|
||||
trackSelectionClipboard: ->
|
||||
timeoutId = null
|
||||
{editor} = @props
|
||||
writeSelectedTextToSelectionClipboard = =>
|
||||
return if editor.isDestroyed()
|
||||
if selectedText = editor.getSelectedText()
|
||||
# This uses ipc.send instead of clipboard.writeText because
|
||||
# clipboard.writeText is a sync ipc call on Linux and that
|
||||
# will slow down selections.
|
||||
ipc.send('write-text-to-selection-clipboard', selectedText)
|
||||
@subscribe editor.onDidChangeSelectionRange ->
|
||||
clearTimeout(timeoutId)
|
||||
timeoutId = setTimeout(writeSelectedTextToSelectionClipboard)
|
||||
|
||||
observeConfig: ->
|
||||
@subscribe atom.config.observe 'editor.useHardwareAcceleration', @setUseHardwareAcceleration
|
||||
@@ -560,7 +560,11 @@ TextEditorComponent = React.createClass
|
||||
scrollViewNode.scrollLeft = 0
|
||||
|
||||
onMouseDown: (event) ->
|
||||
return unless event.button is 0 # only handle the left mouse button
|
||||
unless event.button is 0 or (event.button is 1 and process.platform is 'linux')
|
||||
# Only handle mouse down events for left mouse button on all platforms
|
||||
# and middle mouse button on Linux since it pastes the selection clipboard
|
||||
return
|
||||
|
||||
return if event.target?.classList.contains('horizontal-scrollbar')
|
||||
|
||||
{editor} = @props
|
||||
@@ -750,10 +754,12 @@ TextEditorComponent = React.createClass
|
||||
lastMousePosition = {}
|
||||
animationLoop = =>
|
||||
@requestAnimationFrame =>
|
||||
if dragging
|
||||
if dragging and @isMounted()
|
||||
screenPosition = @screenPositionForMouseEvent(lastMousePosition)
|
||||
dragHandler(screenPosition)
|
||||
animationLoop()
|
||||
else if not @isMounted()
|
||||
stopDragging()
|
||||
|
||||
onMouseMove = (event) ->
|
||||
lastMousePosition.clientX = event.clientX
|
||||
@@ -767,11 +773,20 @@ TextEditorComponent = React.createClass
|
||||
# Stop dragging when cursor enters dev tools because we can't detect mouseup
|
||||
onMouseUp() if event.which is 0
|
||||
|
||||
onMouseUp = ->
|
||||
onMouseUp = (event) ->
|
||||
stopDragging()
|
||||
editor.finalizeSelections()
|
||||
pasteSelectionClipboard(event)
|
||||
|
||||
stopDragging = ->
|
||||
dragging = false
|
||||
window.removeEventListener('mousemove', onMouseMove)
|
||||
window.removeEventListener('mouseup', onMouseUp)
|
||||
editor.finalizeSelections()
|
||||
|
||||
pasteSelectionClipboard = (event) ->
|
||||
if event?.which is 2 and process.platform is 'linux'
|
||||
if selection = require('clipboard').readText('selection')
|
||||
editor.insertText(selection)
|
||||
|
||||
window.addEventListener('mousemove', onMouseMove)
|
||||
window.addEventListener('mouseup', onMouseUp)
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário