From b76a00672080b1cacb6cf88e01863c135c22fdc0 Mon Sep 17 00:00:00 2001 From: fscherwi Date: Sun, 22 Nov 2015 16:56:32 +0100 Subject: [PATCH 01/38] :arrow_up: pathwatcher --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b22887bf0..e12f7785b 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "normalize-package-data": "^2.0.0", "nslog": "^3", "oniguruma": "^5", - "pathwatcher": "~6.2", + "pathwatcher": "~6.3", "property-accessors": "^1.1.3", "random-words": "0.0.1", "resolve": "^1.1.6", From 77dcf37ee3587f18356943f46c28462ef9bd93a5 Mon Sep 17 00:00:00 2001 From: Giuseppe Piscopo Date: Thu, 21 Apr 2016 01:53:11 +0200 Subject: [PATCH 02/38] extract process spawning from squirrel-update --- spec/spawner-spec.coffee | 57 +++++++++++++++++++++++++ spec/squirrel-update-spec.coffee | 68 +++++++++++++----------------- src/browser/spawner.coffee | 36 ++++++++++++++++ src/browser/squirrel-update.coffee | 38 +++-------------- 4 files changed, 128 insertions(+), 71 deletions(-) create mode 100644 spec/spawner-spec.coffee create mode 100644 src/browser/spawner.coffee diff --git a/spec/spawner-spec.coffee b/spec/spawner-spec.coffee new file mode 100644 index 000000000..4ae2149e5 --- /dev/null +++ b/spec/spawner-spec.coffee @@ -0,0 +1,57 @@ +ChildProcess = require 'child_process' +Spawner = require '../src/browser/spawner' + +describe "Spawner", -> + beforeEach -> + # Prevent any commands from actually running and affecting the host + originalSpawn = ChildProcess.spawn + + harmlessSpawn = + # Just spawn something that won't actually modify the host + if process.platform is 'win32' + originalSpawn('dir') + else + originalSpawn('ls') + + spyOn(ChildProcess, 'spawn').andCallFake (command, args, callback) -> + harmlessSpawn + + it "invokes passed callback", -> + someCallback = jasmine.createSpy('someCallback') + + Spawner.spawn('some-command', 'some-args', someCallback) + + waitsFor -> + someCallback.callCount is 1 + + it "spawns passed command with arguments", -> + actualCommand = null + actualArgs = null + + # Redefine fake invocation, so to remember passed arguments + jasmine.unspy(ChildProcess, 'spawn') + spyOn(ChildProcess, 'spawn').andCallFake (command, args) -> + actualCommand = command + actualArgs = args + harmlessSpawn + + expectedCommand = 'some-command' + expectedArgs = 'some-args' + someCallback = jasmine.createSpy('someCallback') + + Spawner.spawn(expectedCommand, expectedArgs, someCallback) + + expect(actualCommand).toBe expectedCommand + expect(actualArgs).toBe expectedArgs + + it "ignores errors by spawned process", -> + # Redefine fake invocation, so to cause an error + jasmine.unspy(ChildProcess, 'spawn') + spyOn(ChildProcess, 'spawn').andCallFake -> throw new Error("EBUSY") + + someCallback = jasmine.createSpy('someCallback') + + expect(Spawner.spawn('some-command', 'some-args', someCallback)).toBe undefined + + waitsFor -> + someCallback.callCount is 1 diff --git a/spec/squirrel-update-spec.coffee b/spec/squirrel-update-spec.coffee index e3891ed1c..e11fb1f00 100644 --- a/spec/squirrel-update-spec.coffee +++ b/spec/squirrel-update-spec.coffee @@ -1,39 +1,22 @@ -ChildProcess = require 'child_process' {EventEmitter} = require 'events' fs = require 'fs-plus' path = require 'path' temp = require 'temp' SquirrelUpdate = require '../src/browser/squirrel-update' +Spawner = require '../src/browser/spawner' describe "Windows Squirrel Update", -> tempHomeDirectory = null - originalSpawn = ChildProcess.spawn - - harmlessSpawn = -> - # Just spawn something that won't actually modify the host - if process.platform is 'win32' - originalSpawn('dir') - else - originalSpawn('ls') beforeEach -> # Prevent the actual 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 - spyOn(ChildProcess, 'spawn').andCallFake (command, args) -> - harmlessSpawn() - - it "ignores errors spawning Squirrel", -> - jasmine.unspy(ChildProcess, 'spawn') - spyOn(ChildProcess, 'spawn').andCallFake -> throw new Error("EBUSY") - - app = quit: jasmine.createSpy('quit') - expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true - - waitsFor -> - app.quit.callCount is 1 + # Prevent any spawned command from actually running and affecting the host + spyOn(Spawner, 'spawn').andCallFake (command, args, callback) -> + # do nothing on command, just run passed callback + invokeCallback callback it "quits the app on all squirrel events", -> app = quit: jasmine.createSpy('quit') @@ -69,51 +52,52 @@ describe "Windows Squirrel Update", -> describe "Desktop shortcut", -> desktopShortcutPath = '/non/existing/path' - + beforeEach -> desktopShortcutPath = path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk') - jasmine.unspy(ChildProcess, 'spawn') - spyOn(ChildProcess, 'spawn').andCallFake (command, args) -> + jasmine.unspy(Spawner, 'spawn') + spyOn(Spawner, 'spawn').andCallFake (command, args, callback) -> if path.basename(command) is 'Update.exe' and args?[0] is '--createShortcut' - fs.writeFileSync(path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk'), '') - harmlessSpawn() + fs.writeFileSync(desktopShortcutPath, '') else - throw new Error("API not mocked") - + # simply ignore other commands + + invokeCallback callback + it "does not exist before install", -> expect(fs.existsSync(desktopShortcutPath)).toBe false - + describe "on install", -> beforeEach -> app = quit: jasmine.createSpy('quit') SquirrelUpdate.handleStartupEvent(app, '--squirrel-install') waitsFor -> app.quit.callCount is 1 - + it "creates desktop shortcut", -> expect(fs.existsSync(desktopShortcutPath)).toBe true - + describe "when shortcut is deleted and then app is updated", -> beforeEach -> fs.removeSync(desktopShortcutPath) expect(fs.existsSync(desktopShortcutPath)).toBe false - + app = quit: jasmine.createSpy('quit') SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated') waitsFor -> app.quit.callCount is 1 - + it "does not recreate shortcut", -> expect(fs.existsSync(desktopShortcutPath)).toBe false - + describe "when shortcut is kept and app is updated", -> beforeEach -> app = quit: jasmine.createSpy('quit') SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated') waitsFor -> app.quit.callCount is 1 - + it "still has desktop shortcut", -> expect(fs.existsSync(desktopShortcutPath)).toBe true @@ -125,7 +109,13 @@ describe "Windows Squirrel Update", -> SquirrelUpdate.restartAtom(app) expect(app.quit.callCount).toBe 1 - expect(ChildProcess.spawn.callCount).toBe 0 + expect(Spawner.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' + expect(Spawner.spawn.callCount).toBe 1 + expect(path.basename(Spawner.spawn.argsForCall[0][0])).toBe 'atom.cmd' + +# Run passed callback as Spawner.spawn() would do +invokeCallback = (callback) -> + error = null + stdout = '' + callback?(error, stdout) diff --git a/src/browser/spawner.coffee b/src/browser/spawner.coffee new file mode 100644 index 000000000..edf93182e --- /dev/null +++ b/src/browser/spawner.coffee @@ -0,0 +1,36 @@ +ChildProcess = require 'child_process' + +# Spawn a command and invoke the callback when it completes with an error +# and the output from standard out. +# +# * `command` The underlying OS command {String} to execute. +# * `args` (optional) The {Array} with arguments to be passed to command. +# * `callback` (optional) The {Function} to call after the command has run. It will be invoked with arguments: +# * `error` (optional) An {Error} object returned by the command, `null` if no error was thrown. +# * `code` Error code returned by the command. +# * `stdout` The {String} output text generated by the command. +# * `stdout` The {String} output text generated by the command. +# +# Returns `undefined`. +exports.spawn = (command, args, callback) -> + stdout = '' + + try + spawnedProcess = ChildProcess.spawn(command, args) + catch error + # Spawn can throw an error + process.nextTick -> callback?(error, stdout) + return + + spawnedProcess.stdout.on 'data', (data) -> stdout += data + + error = null + spawnedProcess.on 'error', (processError) -> error ?= processError + spawnedProcess.on 'close', (code, signal) -> + error ?= new Error("Command failed: #{signal ? code}") if code isnt 0 + error?.code ?= code + error?.stdout ?= stdout + callback?(error, stdout) + # This is necessary if using Powershell 2 on Windows 7 to get the events to raise + # http://stackoverflow.com/questions/9155289/calling-powershell-from-nodejs + spawnedProcess.stdin.end() diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index 9d6f772db..7afc7641f 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -1,6 +1,6 @@ -ChildProcess = require 'child_process' fs = require 'fs-plus' path = require 'path' +Spawner = require './spawner' appFolder = path.resolve(process.execPath, '..') rootAtomFolder = path.resolve(appFolder, '..') @@ -25,35 +25,9 @@ backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom applicationsKeyPath = 'HKCU\\Software\\Classes\\Applications\\atom.exe' environmentKeyPath = 'HKCU\\Environment' -# Spawn a command and invoke the callback when it completes with an error -# and the output from standard out. -spawn = (command, args, callback) -> - stdout = '' - - try - spawnedProcess = ChildProcess.spawn(command, args) - catch error - # Spawn can throw an error - process.nextTick -> callback?(error, stdout) - return - - spawnedProcess.stdout.on 'data', (data) -> stdout += data - - error = null - spawnedProcess.on 'error', (processError) -> error ?= processError - spawnedProcess.on 'close', (code, signal) -> - error ?= new Error("Command failed: #{signal ? code}") if code isnt 0 - error?.code ?= code - error?.stdout ?= stdout - callback?(error, stdout) - # This is necessary if using Powershell 2 on Windows 7 to get the events to raise - # http://stackoverflow.com/questions/9155289/calling-powershell-from-nodejs - spawnedProcess.stdin.end() - - # Spawn reg.exe and callback when it completes spawnReg = (args, callback) -> - spawn(regPath, args, callback) + Spawner.spawn(regPath, args, callback) # Spawn powershell.exe and callback when it completes spawnPowershell = (args, callback) -> @@ -69,16 +43,16 @@ spawnPowershell = (args, callback) -> args.unshift('RemoteSigned') args.unshift('-ExecutionPolicy') args.unshift('-noprofile') - spawn(powershellPath, args, callback) + Spawner.spawn(powershellPath, args, callback) # Spawn setx.exe and callback when it completes spawnSetx = (args, callback) -> - spawn(setxPath, args, callback) + Spawner.spawn(setxPath, args, callback) # Spawn the Update.exe with the given arguments and invoke the callback when # the command completes. spawnUpdate = (args, callback) -> - spawn(updateDotExe, args, callback) + Spawner.spawn(updateDotExe, args, callback) # Install the Open with Atom explorer context menu items via the registry. installContextMenu = (callback) -> @@ -220,7 +194,7 @@ exports.existsSync = -> exports.restartAtom = (app) -> if projectPath = global.atomApplication?.lastFocusedWindow?.projectPath args = [projectPath] - app.once 'will-quit', -> spawn(path.join(binFolder, 'atom.cmd'), args) + app.once 'will-quit', -> Spawner.spawn(path.join(binFolder, 'atom.cmd'), args) app.quit() # Handle squirrel events denoted by --squirrel-* command line arguments. From 63c45cc8fd7d37903178c2e994b0e6e24a247046 Mon Sep 17 00:00:00 2001 From: Giuseppe Piscopo Date: Thu, 21 Apr 2016 03:25:09 +0200 Subject: [PATCH 03/38] extract Windows registry operations from squirrel-update --- spec/spawner-spec.coffee | 2 +- spec/squirrel-update-spec.coffee | 24 ++++++++---- src/browser/squirrel-update.coffee | 54 ++------------------------ src/browser/win-registry.coffee | 62 ++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 59 deletions(-) create mode 100644 src/browser/win-registry.coffee diff --git a/spec/spawner-spec.coffee b/spec/spawner-spec.coffee index 4ae2149e5..daa804bbb 100644 --- a/spec/spawner-spec.coffee +++ b/spec/spawner-spec.coffee @@ -13,7 +13,7 @@ describe "Spawner", -> else originalSpawn('ls') - spyOn(ChildProcess, 'spawn').andCallFake (command, args, callback) -> + spyOn(ChildProcess, 'spawn').andCallFake (command, args, callback) -> harmlessSpawn it "invokes passed callback", -> diff --git a/spec/squirrel-update-spec.coffee b/spec/squirrel-update-spec.coffee index e11fb1f00..ecfd780d6 100644 --- a/spec/squirrel-update-spec.coffee +++ b/spec/squirrel-update-spec.coffee @@ -4,8 +4,15 @@ path = require 'path' temp = require 'temp' SquirrelUpdate = require '../src/browser/squirrel-update' Spawner = require '../src/browser/spawner' +WinRegistry = require '../src/browser/win-registry' -describe "Windows Squirrel Update", -> +# Run passed callback as Spawner.spawn() would do +invokeCallback = (callback) -> + error = null + stdout = '' + callback?(error, stdout) + +fdescribe "Windows Squirrel Update", -> tempHomeDirectory = null beforeEach -> @@ -14,10 +21,17 @@ describe "Windows Squirrel Update", -> spyOn(fs, 'getHomeDirectory').andReturn(tempHomeDirectory) # Prevent any spawned command from actually running and affecting the host - spyOn(Spawner, 'spawn').andCallFake (command, args, callback) -> + spyOn(Spawner, 'spawn').andCallFake (command, args, callback) -> # do nothing on command, just run passed callback invokeCallback callback + # Prevent any actual change to Windows registry + for own method of WinRegistry + # all WinRegistry APIs share the same signature + spyOn(WinRegistry, method).andCallFake (callback) -> + # do nothing on registry, just run passed callback + invokeCallback callback + it "quits the app on all squirrel events", -> app = quit: jasmine.createSpy('quit') @@ -113,9 +127,3 @@ describe "Windows Squirrel Update", -> app.emit('will-quit') expect(Spawner.spawn.callCount).toBe 1 expect(path.basename(Spawner.spawn.argsForCall[0][0])).toBe 'atom.cmd' - -# Run passed callback as Spawner.spawn() would do -invokeCallback = (callback) -> - error = null - stdout = '' - callback?(error, stdout) diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index 7afc7641f..58bcf2db9 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -1,6 +1,7 @@ fs = require 'fs-plus' path = require 'path' Spawner = require './spawner' +WinRegistry = require './win-registry' appFolder = path.resolve(process.execPath, '..') rootAtomFolder = path.resolve(appFolder, '..') @@ -10,25 +11,12 @@ exeName = path.basename(process.execPath) if process.env.SystemRoot system32Path = path.join(process.env.SystemRoot, 'System32') - regPath = path.join(system32Path, 'reg.exe') powershellPath = path.join(system32Path, 'WindowsPowerShell', 'v1.0', 'powershell.exe') setxPath = path.join(system32Path, 'setx.exe') else - regPath = 'reg.exe' powershellPath = 'powershell.exe' setxPath = 'setx.exe' -# Registry keys used for context menu -fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom' -directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom' -backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom' -applicationsKeyPath = 'HKCU\\Software\\Classes\\Applications\\atom.exe' -environmentKeyPath = 'HKCU\\Environment' - -# Spawn reg.exe and callback when it completes -spawnReg = (args, callback) -> - Spawner.spawn(regPath, args, callback) - # Spawn powershell.exe and callback when it completes spawnPowershell = (args, callback) -> # set encoding and execute the command, capture the output, and return it via .NET's console in order to have consistent UTF-8 encoding @@ -54,30 +42,6 @@ spawnSetx = (args, callback) -> spawnUpdate = (args, callback) -> Spawner.spawn(updateDotExe, args, callback) -# Install the Open with Atom explorer context menu items via the registry. -installContextMenu = (callback) -> - addToRegistry = (args, callback) -> - args.unshift('add') - args.push('/f') - spawnReg(args, callback) - - installFileHandler = (callback) -> - args = ["#{applicationsKeyPath}\\shell\\open\\command", '/ve', '/d', "\"#{process.execPath}\" \"%1\""] - addToRegistry(args, callback) - - installMenu = (keyPath, arg, callback) -> - args = [keyPath, '/ve', '/d', 'Open with Atom'] - addToRegistry args, -> - args = [keyPath, '/v', 'Icon', '/d', "\"#{process.execPath}\""] - addToRegistry args, -> - args = ["#{keyPath}\\command", '/ve', '/d', "\"#{process.execPath}\" \"#{arg}\""] - addToRegistry(args, callback) - - installMenu fileKeyPath, '%1', -> - installMenu directoryKeyPath, '%1', -> - installMenu backgroundKeyPath, '%V', -> - installFileHandler(callback) - # Get the user's PATH environment variable registry value. getPath = (callback) -> spawnPowershell ['[environment]::GetEnvironmentVariable(\'Path\',\'User\')'], (error, stdout) -> @@ -87,16 +51,6 @@ getPath = (callback) -> pathOutput = stdout.replace(/^\s+|\s+$/g, '') callback(null, pathOutput) -# Uninstall the Open with Atom explorer context menu items via the registry. -uninstallContextMenu = (callback) -> - deleteFromRegistry = (keyPath, callback) -> - spawnReg(['delete', keyPath, '/f'], callback) - - deleteFromRegistry fileKeyPath, -> - deleteFromRegistry directoryKeyPath, -> - deleteFromRegistry backgroundKeyPath, -> - deleteFromRegistry(applicationsKeyPath, callback) - # Add atom and apm to the PATH # # This is done by adding .cmd shims to the root bin folder in the Atom @@ -202,19 +156,19 @@ exports.handleStartupEvent = (app, squirrelCommand) -> switch squirrelCommand when '--squirrel-install' createShortcuts -> - installContextMenu -> + WinRegistry.installContextMenu -> addCommandsToPath -> app.quit() true when '--squirrel-updated' updateShortcuts -> - installContextMenu -> + WinRegistry.installContextMenu -> addCommandsToPath -> app.quit() true when '--squirrel-uninstall' removeShortcuts -> - uninstallContextMenu -> + WinRegistry.uninstallContextMenu -> removeCommandsFromPath -> app.quit() true diff --git a/src/browser/win-registry.coffee b/src/browser/win-registry.coffee new file mode 100644 index 000000000..f4b81b377 --- /dev/null +++ b/src/browser/win-registry.coffee @@ -0,0 +1,62 @@ +path = require 'path' +Spawner = require './spawner' + +if process.env.SystemRoot + system32Path = path.join(process.env.SystemRoot, 'System32') + regPath = path.join(system32Path, 'reg.exe') +else + regPath = 'reg.exe' + +# Registry keys used for context menu +fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom' +directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom' +backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom' +applicationsKeyPath = 'HKCU\\Software\\Classes\\Applications\\atom.exe' + +# Spawn reg.exe and callback when it completes +spawnReg = (args, callback) -> + Spawner.spawn(regPath, args, callback) + +# Install the Open with Atom explorer context menu items via the registry. +# +# * `callback` The {Function} to call after registry operation is done. +# It will be invoked with the same arguments provided by {Spawner.spawn}. +# +# Returns `undefined`. +exports.installContextMenu = (callback) -> + addToRegistry = (args, callback) -> + args.unshift('add') + args.push('/f') + spawnReg(args, callback) + + installFileHandler = (callback) -> + args = ["#{applicationsKeyPath}\\shell\\open\\command", '/ve', '/d', "\"#{process.execPath}\" \"%1\""] + addToRegistry(args, callback) + + installMenu = (keyPath, arg, callback) -> + args = [keyPath, '/ve', '/d', 'Open with Atom'] + addToRegistry args, -> + args = [keyPath, '/v', 'Icon', '/d', "\"#{process.execPath}\""] + addToRegistry args, -> + args = ["#{keyPath}\\command", '/ve', '/d', "\"#{process.execPath}\" \"#{arg}\""] + addToRegistry(args, callback) + + installMenu fileKeyPath, '%1', -> + installMenu directoryKeyPath, '%1', -> + installMenu backgroundKeyPath, '%V', -> + installFileHandler(callback) + +# Uninstall the Open with Atom explorer context menu items via the registry. +# +# * `callback` The {Function} to call after registry operation is done. +# It will be invoked with the same arguments provided by {Spawner.spawn}. +# +# Returns `undefined`. +exports.uninstallContextMenu = (callback) -> + deleteFromRegistry = (keyPath, callback) -> + spawnReg(['delete', keyPath, '/f'], callback) + + deleteFromRegistry fileKeyPath, -> + deleteFromRegistry directoryKeyPath, -> + deleteFromRegistry backgroundKeyPath, -> + deleteFromRegistry(applicationsKeyPath, callback) From bebaf1bdb08db56a527c625d6c537e356a33cf16 Mon Sep 17 00:00:00 2001 From: Giuseppe Piscopo Date: Thu, 28 Apr 2016 09:24:37 +0200 Subject: [PATCH 04/38] extract Windows PowerShell operations from squirrel-update --- spec/squirrel-update-spec.coffee | 3 ++- src/browser/squirrel-update.coffee | 32 +++--------------------- src/browser/win-powershell.coffee | 39 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 src/browser/win-powershell.coffee diff --git a/spec/squirrel-update-spec.coffee b/spec/squirrel-update-spec.coffee index ecfd780d6..4a6936a50 100644 --- a/spec/squirrel-update-spec.coffee +++ b/spec/squirrel-update-spec.coffee @@ -4,6 +4,7 @@ path = require 'path' temp = require 'temp' SquirrelUpdate = require '../src/browser/squirrel-update' Spawner = require '../src/browser/spawner' +WinPowerShell = require '../src/browser/win-powershell' WinRegistry = require '../src/browser/win-registry' # Run passed callback as Spawner.spawn() would do @@ -12,7 +13,7 @@ invokeCallback = (callback) -> stdout = '' callback?(error, stdout) -fdescribe "Windows Squirrel Update", -> +describe "Windows Squirrel Update", -> tempHomeDirectory = null beforeEach -> diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index 58bcf2db9..a1bfc5359 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -2,6 +2,7 @@ fs = require 'fs-plus' path = require 'path' Spawner = require './spawner' WinRegistry = require './win-registry' +WinPowerShell = require './win-powershell' appFolder = path.resolve(process.execPath, '..') rootAtomFolder = path.resolve(appFolder, '..') @@ -11,28 +12,10 @@ exeName = path.basename(process.execPath) if process.env.SystemRoot system32Path = path.join(process.env.SystemRoot, 'System32') - powershellPath = path.join(system32Path, 'WindowsPowerShell', 'v1.0', 'powershell.exe') setxPath = path.join(system32Path, 'setx.exe') else - powershellPath = 'powershell.exe' setxPath = 'setx.exe' -# Spawn powershell.exe and callback when it completes -spawnPowershell = (args, callback) -> - # set encoding and execute the command, capture the output, and return it via .NET's console in order to have consistent UTF-8 encoding - # http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell - # to address https://github.com/atom/atom/issues/5063 - args[0] = """ - [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 - $output=#{args[0]} - [Console]::WriteLine($output) - """ - args.unshift('-command') - args.unshift('RemoteSigned') - args.unshift('-ExecutionPolicy') - args.unshift('-noprofile') - Spawner.spawn(powershellPath, args, callback) - # Spawn setx.exe and callback when it completes spawnSetx = (args, callback) -> Spawner.spawn(setxPath, args, callback) @@ -42,15 +25,6 @@ spawnSetx = (args, callback) -> spawnUpdate = (args, callback) -> Spawner.spawn(updateDotExe, args, callback) -# Get the user's PATH environment variable registry value. -getPath = (callback) -> - spawnPowershell ['[environment]::GetEnvironmentVariable(\'Path\',\'User\')'], (error, stdout) -> - if error? - return callback(error) - - pathOutput = stdout.replace(/^\s+|\s+$/g, '') - callback(null, pathOutput) - # Add atom and apm to the PATH # # This is done by adding .cmd shims to the root bin folder in the Atom @@ -88,7 +62,7 @@ addCommandsToPath = (callback) -> installCommands (error) -> return callback(error) if error? - getPath (error, pathEnv) -> + WinPowerShell.getPath (error, pathEnv) -> return callback(error) if error? pathSegments = pathEnv.split(/;+/).filter (pathSegment) -> pathSegment @@ -99,7 +73,7 @@ addCommandsToPath = (callback) -> # Remove atom and apm from the PATH removeCommandsFromPath = (callback) -> - getPath (error, pathEnv) -> + WinPowerShell.getPath (error, pathEnv) -> return callback(error) if error? pathSegments = pathEnv.split(/;+/).filter (pathSegment) -> diff --git a/src/browser/win-powershell.coffee b/src/browser/win-powershell.coffee new file mode 100644 index 000000000..f3e73bc8a --- /dev/null +++ b/src/browser/win-powershell.coffee @@ -0,0 +1,39 @@ +path = require 'path' +Spawner = require './spawner' + +if process.env.SystemRoot + system32Path = path.join(process.env.SystemRoot, 'System32') + powershellPath = path.join(system32Path, 'WindowsPowerShell', 'v1.0', 'powershell.exe') +else + powershellPath = 'powershell.exe' + +# Spawn powershell.exe and callback when it completes +spawnPowershell = (args, callback) -> + # Set encoding and execute the command, capture the output, and return it + # via .NET's console in order to have consistent UTF-8 encoding. + # See http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell + # to address https://github.com/atom/atom/issues/5063 + args[0] = """ + [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 + $output=#{args[0]} + [Console]::WriteLine($output) + """ + args.unshift('-command') + args.unshift('RemoteSigned') + args.unshift('-ExecutionPolicy') + args.unshift('-noprofile') + Spawner.spawn(powershellPath, args, callback) + +# Get the user's PATH environment variable registry value. +# +# * `callback` The {Function} to call after registry operation is done. +# It will be invoked with the same arguments provided by {Spawner.spawn}. +# +# Returns the user's path {String}. +exports.getPath = (callback) -> + spawnPowershell ['[environment]::GetEnvironmentVariable(\'Path\',\'User\')'], (error, stdout) -> + if error? + return callback(error) + + pathOutput = stdout.replace(/^\s+|\s+$/g, '') + callback(null, pathOutput) From 07bf40879d0526f4255726e5c63d3720dcb75037 Mon Sep 17 00:00:00 2001 From: Giuseppe Piscopo Date: Thu, 28 Apr 2016 19:25:54 +0200 Subject: [PATCH 05/38] Fix coffeelint error on trailing whitespace --- src/browser/win-powershell.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/win-powershell.coffee b/src/browser/win-powershell.coffee index f3e73bc8a..29925a7c1 100644 --- a/src/browser/win-powershell.coffee +++ b/src/browser/win-powershell.coffee @@ -9,7 +9,7 @@ else # Spawn powershell.exe and callback when it completes spawnPowershell = (args, callback) -> - # Set encoding and execute the command, capture the output, and return it + # Set encoding and execute the command, capture the output, and return it # via .NET's console in order to have consistent UTF-8 encoding. # See http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell # to address https://github.com/atom/atom/issues/5063 From c929bb687421241ed3df1d7b68288a5086074ceb Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 4 May 2016 22:18:34 -0400 Subject: [PATCH 06/38] :arrow_up: language-xml@0.34.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4a8591ae5..0a3c8e1bc 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ "language-text": "0.7.1", "language-todo": "0.27.0", "language-toml": "0.18.0", - "language-xml": "0.34.5", + "language-xml": "0.34.6", "language-yaml": "0.26.0" }, "private": true, From d06da3f47046643292c0a451be5ca51c67436a1b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 5 May 2016 09:10:36 +0200 Subject: [PATCH 07/38] Reset display layer when editor.atomicSoftTabs changes --- spec/text-editor-spec.coffee | 24 ++++++++++++++++++++++++ src/text-editor.coffee | 1 + 2 files changed, 25 insertions(+) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 8f4231323..be24baa01 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5268,6 +5268,30 @@ describe "TextEditor", -> coffeeEditor.insertText("\n") expect(coffeeEditor.lineTextForBufferRow(2)).toBe "" + describe "editor.atomicSoftTabs", -> + it "skips tab-length runs of leading whitespace when moving the cursor", -> + atom.config.set('editor.tabLength', 4) + + atom.config.set('editor.atomicSoftTabs', true) + editor.setCursorScreenPosition([2, 3]) + expect(editor.getCursorScreenPosition()).toEqual [2, 4] + + atom.config.set('editor.atomicSoftTabs', false) + editor.setCursorScreenPosition([2, 3]) + expect(editor.getCursorScreenPosition()).toEqual [2, 3] + + atom.config.set('editor.atomicSoftTabs', true) + editor.setCursorScreenPosition([2, 3]) + expect(editor.getCursorScreenPosition()).toEqual [2, 4] + + atom.config.set('editor.atomicSoftTabs', false, scopeSelector: '.source.foo') + editor.setCursorScreenPosition([2, 3]) + expect(editor.getCursorScreenPosition()).toEqual [2, 4] + + atom.config.set('editor.atomicSoftTabs', false, scopeSelector: '.source.js') + editor.setCursorScreenPosition([2, 3]) + expect(editor.getCursorScreenPosition()).toEqual [2, 3] + describe ".destroy()", -> it "destroys marker layers associated with the text editor", -> selectionsMarkerLayerId = editor.selectionsMarkerLayer.id diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 9607f3437..54f65ceda 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -230,6 +230,7 @@ class TextEditor extends Model @scopedConfigSubscriptions = subscriptions = new CompositeDisposable scopeDescriptor = @getRootScopeDescriptor() + subscriptions.add @config.onDidChange 'editor.atomicSoftTabs', scope: scopeDescriptor, @resetDisplayLayer.bind(this) subscriptions.add @config.onDidChange 'editor.tabLength', scope: scopeDescriptor, @resetDisplayLayer.bind(this) subscriptions.add @config.onDidChange 'editor.invisibles', scope: scopeDescriptor, @resetDisplayLayer.bind(this) subscriptions.add @config.onDidChange 'editor.showInvisibles', scope: scopeDescriptor, @resetDisplayLayer.bind(this) From 87c75ddfc4b4e9bf4767617f5ea97f6c93637f2c Mon Sep 17 00:00:00 2001 From: fscherwi Date: Thu, 5 May 2016 18:40:57 +0200 Subject: [PATCH 08/38] :arrow_up: pathwatcher@6.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e12f7785b..b739d9dc5 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "normalize-package-data": "^2.0.0", "nslog": "^3", "oniguruma": "^5", - "pathwatcher": "~6.3", + "pathwatcher": "~6.5", "property-accessors": "^1.1.3", "random-words": "0.0.1", "resolve": "^1.1.6", From 32fcadd82264ae3218844f82ee14e263b0f02a40 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Mon, 1 Feb 2016 21:40:43 -0800 Subject: [PATCH 09/38] :memo: Update to v1.4 of Contributor Covenent Code of Conduct --- CODE_OF_CONDUCT.md | 48 +++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 444ce0b4c..c7d7eeb14 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,24 +1,46 @@ -# Contributor Code of Conduct +# Contributor Covenant Code of Conduct -As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. +## Our Pledge -We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members Examples of unacceptable behavior by participants include: -- The use of sexualized language or imagery -- Personal attacks -- Trolling or insulting/derogatory comments -- Public or private harassment -- Publishing other's private information, such as physical or electronic addresses, without explicit permission -- Other unethical or unprofessional conduct +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. -By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. +## Scope -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident. +## Enforcement -This Code of Conduct is adapted from the Contributor Covenant, version 1.3.0, available from http://contributor-covenant.org/version/1/3/0/ +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ From 8d59f39a2aa93e446c14d1841636160fae68a432 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 5 May 2016 14:09:53 -0700 Subject: [PATCH 10/38] :arrow_up: notifications@0.64.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a3c8e1bc..31500e4fb 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "link": "0.31.1", "markdown-preview": "0.158.0", "metrics": "0.53.1", - "notifications": "0.63.2", + "notifications": "0.64.0", "open-on-github": "1.1.0", "package-generator": "1.0.0", "settings-view": "0.236.0", From c31ade978cf3f8035b51ebc368fee0a344462865 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 5 May 2016 18:39:31 -0700 Subject: [PATCH 11/38] :arrow_up: bracket-matcher@0.82.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f63c34b21..5f5a62c6d 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.23.1", "background-tips": "0.26.0", "bookmarks": "0.41.0", - "bracket-matcher": "0.82.0", + "bracket-matcher": "0.82.1", "command-palette": "0.38.0", "deprecation-cop": "0.54.1", "dev-live-reload": "0.47.0", From e3790b8f20f96e17c2ad5cad3ed53b41e4f23377 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 6 May 2016 14:11:47 +0200 Subject: [PATCH 12/38] :memo: Do not mention persistent option for mark...Range methods --- src/text-editor.coffee | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 54f65ceda..051fd76b8 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -1702,8 +1702,6 @@ class TextEditor extends Model # operations, but uses more time and memory. (default: false) # * `reversed` (optional) {Boolean} Creates the marker in a reversed # orientation. (default: false) - # * `persistent` (optional) {Boolean} Whether to include this marker when - # serializing the buffer. (default: true) # * `invalidate` (optional) {String} Determines the rules by which changes # to the buffer *invalidate* the marker. (default: 'overlap') It can be # any of the following strategies, in order of fragility: @@ -1737,8 +1735,6 @@ class TextEditor extends Model # operations, but uses more time and memory. (default: false) # * `reversed` (optional) {Boolean} Creates the marker in a reversed # orientation. (default: false) - # * `persistent` (optional) {Boolean} Whether to include this marker when - # serializing the buffer. (default: true) # * `invalidate` (optional) {String} Determines the rules by which changes # to the buffer *invalidate* the marker. (default: 'overlap') It can be # any of the following strategies, in order of fragility: From aab92787efeca711022d7a228cea2d0d7b794773 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 6 May 2016 13:19:53 -0400 Subject: [PATCH 13/38] :arrow_up: fuzzy-finder@1.0.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f5a62c6d..b1d0e3ba9 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.22.0", "exception-reporting": "0.38.1", - "fuzzy-finder": "1.0.5", + "fuzzy-finder": "1.0.6", "git-diff": "1.0.1", "find-and-replace": "0.198.0", "go-to-line": "0.30.0", From 5907a190ebce46390b7d1771636f352313fc18ed Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 7 May 2016 17:23:19 -0400 Subject: [PATCH 14/38] :arrow_up: language-c@0.51.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b1d0e3ba9..482e8d61c 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "welcome": "0.34.0", "whitespace": "0.32.2", "wrap-guide": "0.38.1", - "language-c": "0.51.4", + "language-c": "0.51.5", "language-clojure": "0.20.0", "language-coffee-script": "0.47.0", "language-csharp": "0.12.1", From 72905f1895405db0b5bc893e8df5f7fad078cc63 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 7 May 2016 17:23:42 -0400 Subject: [PATCH 15/38] :arrow_up: language-perl@0.35.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 482e8d61c..82686b0ec 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "language-make": "0.22.0", "language-mustache": "0.13.0", "language-objective-c": "0.15.1", - "language-perl": "0.34.0", + "language-perl": "0.35.0", "language-php": "0.37.0", "language-property-list": "0.8.0", "language-python": "0.43.1", From 7ec70514895cc9ef0187b20c65e0426a1e959dfb Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 7 May 2016 17:24:06 -0400 Subject: [PATCH 16/38] :arrow_up: language-python@0.43.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82686b0ec..02a9775c7 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "language-perl": "0.35.0", "language-php": "0.37.0", "language-property-list": "0.8.0", - "language-python": "0.43.1", + "language-python": "0.43.2", "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", "language-sass": "0.49.0", From edcd33841719f10ae332af1c720e8825415bffdf Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 7 May 2016 17:24:28 -0400 Subject: [PATCH 17/38] :arrow_up: language-shellscript@0.22.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 02a9775c7..45c757e12 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", "language-sass": "0.49.0", - "language-shellscript": "0.22.0", + "language-shellscript": "0.22.1", "language-source": "0.9.0", "language-sql": "0.21.0", "language-text": "0.7.1", From e3c0e12ce70471985621228b43bae3a8983ef030 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 9 May 2016 22:05:26 -0400 Subject: [PATCH 18/38] :arrow_up: language-shellscript@0.22.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45c757e12..a56d3ad63 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", "language-sass": "0.49.0", - "language-shellscript": "0.22.1", + "language-shellscript": "0.22.2", "language-source": "0.9.0", "language-sql": "0.21.0", "language-text": "0.7.1", From ffd0c586bf133b1481dda1885e2cfacb88c9fb57 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 9 May 2016 22:06:28 -0400 Subject: [PATCH 19/38] :arrow_up: language-sass@0.51.1 Closes #11695 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a56d3ad63..9d3fc7f18 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "language-python": "0.43.2", "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", - "language-sass": "0.49.0", + "language-sass": "0.51.1", "language-shellscript": "0.22.2", "language-source": "0.9.0", "language-sql": "0.21.0", From 405f28f726f018a378e5f336abdbcbfd58d6d013 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Tue, 10 May 2016 16:32:13 -0700 Subject: [PATCH 20/38] Handle spaces in relative path to atom.sh on bash/win, fixes #11732 --- resources/win/atom.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/win/atom.sh b/resources/win/atom.sh index cd90ff8fb..99dd90bea 100644 --- a/resources/win/atom.sh +++ b/resources/win/atom.sh @@ -1,5 +1,5 @@ #!/bin/sh -pushd $(dirname "$0") > /dev/null +pushd "$(dirname "$0")" > /dev/null ATOMCMD=""$(pwd -W)"/atom.cmd" popd > /dev/null cmd.exe //c "$ATOMCMD" "$@" From a33757c5f7ff198fa4c57baaffe7f995227efa89 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 11 May 2016 13:57:51 +0200 Subject: [PATCH 21/38] attach msi to release --- build/tasks/publish-build-task.coffee | 2 +- spec/fixtures/sample.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index 19061db02..0a18c9c23 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -74,7 +74,7 @@ getAssets = -> ] when 'win32' assets = [{assetName: 'atom-windows.zip', sourcePath: appName}] - for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{version}-full.nupkg", "atom-#{version}-delta.nupkg"] + for squirrelAsset in ['AtomSetup.exe', 'AtomSetup.msi', 'RELEASES', "atom-#{version}-full.nupkg", "atom-#{version}-delta.nupkg"] cp path.join(buildDir, 'installer', squirrelAsset), path.join(buildDir, squirrelAsset) assets.push({assetName: squirrelAsset, sourcePath: assetName}) assets diff --git a/spec/fixtures/sample.txt b/spec/fixtures/sample.txt index 9701a96c5..0a2b6a502 100644 --- a/spec/fixtures/sample.txt +++ b/spec/fixtures/sample.txt @@ -1 +1 @@ -Some textSome textSome text. +Some textSome textSome textSome text. From aebacfcfc64d89457ac14e3f5a17f299563ab185 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 11 May 2016 17:05:43 +0200 Subject: [PATCH 22/38] not sure how that got in there --- spec/fixtures/sample.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/fixtures/sample.txt b/spec/fixtures/sample.txt index 0a2b6a502..9701a96c5 100644 --- a/spec/fixtures/sample.txt +++ b/spec/fixtures/sample.txt @@ -1 +1 @@ -Some textSome textSome textSome text. +Some textSome textSome text. From a81ffbf3b2fef408445c9f52c6a0843863a32432 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Thu, 12 May 2016 17:21:33 +0200 Subject: [PATCH 23/38] :arrow_up:fuzzy-finder@1.1.0 https://github.com/atom/fuzzy-finder/pull/204 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d3fc7f18..69196e059 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.22.0", "exception-reporting": "0.38.1", - "fuzzy-finder": "1.0.6", + "fuzzy-finder": "1.1.0", "git-diff": "1.0.1", "find-and-replace": "0.198.0", "go-to-line": "0.30.0", From 0cdbb0928fb66ad1e83d0391a0b705b9c856937f Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 12 May 2016 10:42:24 -0700 Subject: [PATCH 24/38] :arrow_up: fuzzy-finder@1.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69196e059..08b8c527c 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.22.0", "exception-reporting": "0.38.1", - "fuzzy-finder": "1.1.0", + "fuzzy-finder": "1.2.0", "git-diff": "1.0.1", "find-and-replace": "0.198.0", "go-to-line": "0.30.0", From ad7e839bfc7ac4faa578961850f9e593feb1a3bc Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 12 May 2016 13:21:46 -0700 Subject: [PATCH 25/38] :arrow_up: settings-view@0.236.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 08b8c527c..75d2abf90 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "notifications": "0.64.0", "open-on-github": "1.1.0", "package-generator": "1.0.0", - "settings-view": "0.236.0", + "settings-view": "0.236.1", "snippets": "1.0.2", "spell-check": "0.67.1", "status-bar": "1.2.6", From e1a200a7b4434910793e0a6760822d501705beb0 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 12 May 2016 13:53:41 -0700 Subject: [PATCH 26/38] :arrow_up: autocomplete-snippets@1.11.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 75d2abf90..c8ab489ab 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "autocomplete-css": "0.11.1", "autocomplete-html": "0.7.2", "autocomplete-plus": "2.31.0", - "autocomplete-snippets": "1.10.0", + "autocomplete-snippets": "1.11.0", "autoflow": "0.27.0", "autosave": "0.23.1", "background-tips": "0.26.0", From b6891b2860708376509189665f22e95c32d42963 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Fri, 13 May 2016 16:57:43 +0200 Subject: [PATCH 27/38] :arrow_up:tabs@0.94.0 https://github.com/atom/tabs/pull/231 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c8ab489ab..83826480e 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.2.6", "styleguide": "0.45.2", "symbols-view": "0.113.0", - "tabs": "0.93.2", + "tabs": "0.94.0", "timecop": "0.33.1", "tree-view": "0.206.2", "update-package-dependencies": "0.10.0", From 8beb4c238b1e0b30e4a25b1628a07ea073c6b650 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 13 May 2016 11:37:49 -0700 Subject: [PATCH 28/38] :arrow_up: tabs@0.95.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83826480e..d512e3ddf 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.2.6", "styleguide": "0.45.2", "symbols-view": "0.113.0", - "tabs": "0.94.0", + "tabs": "0.95.0", "timecop": "0.33.1", "tree-view": "0.206.2", "update-package-dependencies": "0.10.0", From a5c6f2746a32634a2cb850f873ed9b3b0f06645b Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 13 May 2016 13:50:09 -0700 Subject: [PATCH 29/38] Add Devtron to the Developer Tools window --- package.json | 1 + src/atom-environment.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/package.json b/package.json index d512e3ddf..526857445 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "clear-cut": "^2.0.1", "coffee-script": "1.8.0", "color": "^0.7.3", + "devtron": "1.1.0", "event-kit": "^1.5.0", "find-parent-dir": "^0.3.0", "first-mate": "^5.1.1", diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index da3e989f2..1d60872df 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -790,6 +790,7 @@ class AtomEnvironment extends Model # Returns a {Promise} that resolves when the DevTools have been opened or # closed. toggleDevTools: -> + require("devtron").install() @applicationDelegate.toggleWindowDevTools() # Extended: Execute code in dev tools. From 16fb2da8953344b95531dbf1e92c8a752b234261 Mon Sep 17 00:00:00 2001 From: Daniel Mountford Date: Fri, 13 May 2016 22:30:33 +0100 Subject: [PATCH 30/38] Update link to solarized-dark-syntax The existing link to https://github.com/atom/solarized-dark 404s --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0aa249c18..4b5e4db9a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,7 +62,7 @@ Here's a list of the big ones: * [git-diff](https://github.com/atom/git-diff) - Git change indicators shown in the editor's gutter. * [language-javascript](https://github.com/atom/language-javascript) - all bundled languages are packages too, and each one has a separate package `language-[name]`. Use these for feedback on syntax highlighting issues that only appear for a specific language. * [one-dark-ui](https://github.com/atom/one-dark-ui) - the default UI styling for anything but the text editor. UI theme packages (i.e. packages with a `-ui` suffix) provide only styling and it's possible that a bundled package is responsible for a UI issue. There are other other bundled UI themes, such as [one-light-ui](https://github.com/atom/one-light-ui). -* [one-dark-syntax](https://github.com/atom/one-dark-syntax) - the default syntax highlighting styles applied for all languages. There are other other bundled syntax themes, such as [solarized-dark](https://github.com/atom/solarized-dark). You should use these packages for reporting issues that appear in many languages, but disappear if you change to another syntax theme. +* [one-dark-syntax](https://github.com/atom/one-dark-syntax) - the default syntax highlighting styles applied for all languages. There are other other bundled syntax themes, such as [solarized-dark](https://github.com/atom/solarized-dark-syntax). You should use these packages for reporting issues that appear in many languages, but disappear if you change to another syntax theme. * [apm](https://github.com/atom/apm) - the `apm` command line tool (Atom Package Manager). You should use this repository for any contributions related to the `apm` tool and to publishing packages. * [atom.io](https://github.com/atom/atom.io) - the repository for feedback on the [Atom.io website](https://atom.io) and the [Atom.io package API](https://github.com/atom/atom/blob/master/docs/apm-rest-api.md) used by [apm](https://github.com/atom/apm). From f9039a35f6ba14e6ba334b86a3a839a92eb27d2e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 14 May 2016 17:28:54 +0200 Subject: [PATCH 31/38] Refactor `isRowVisible` to `isRowRendered` There's a distinction to make between rendered and visible rows, and we were using the former as if it was the latter. In particular, if a tile is visible, all its rows get rendered on screen, even though they might not necessarily be visible by the user. --- src/text-editor-component.coffee | 8 ++++---- src/text-editor-presenter.coffee | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 8c20055ed..048033a20 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -491,7 +491,7 @@ class TextEditorComponent screenPosition = Point.fromObject(screenPosition) screenPosition = @editor.clipScreenPosition(screenPosition) if clip - unless @presenter.isRowVisible(screenPosition.row) + unless @presenter.isRowRendered(screenPosition.row) @presenter.setScreenRowsToMeasure([screenPosition.row]) unless @linesComponent.lineNodeForScreenRow(screenPosition.row)? @@ -503,7 +503,7 @@ class TextEditorComponent screenPositionForPixelPosition: (pixelPosition) -> row = @linesYardstick.measuredRowForPixelPosition(pixelPosition) - if row? and not @presenter.isRowVisible(row) + if row? and not @presenter.isRowRendered(row) @presenter.setScreenRowsToMeasure([row]) @updateSyncPreMeasurement() @@ -513,9 +513,9 @@ class TextEditorComponent pixelRectForScreenRange: (screenRange) -> rowsToMeasure = [] - unless @presenter.isRowVisible(screenRange.start.row) + unless @presenter.isRowRendered(screenRange.start.row) rowsToMeasure.push(screenRange.start.row) - unless @presenter.isRowVisible(screenRange.end.row) + unless @presenter.isRowRendered(screenRange.end.row) rowsToMeasure.push(screenRange.end.row) if rowsToMeasure.length > 0 diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 01a0293f6..1f48bc4fa 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1550,8 +1550,8 @@ class TextEditorPresenter getVisibleRowRange: -> [@startRow, @endRow] - isRowVisible: (row) -> - @startRow <= row < @endRow + isRowRendered: (row) -> + @getStartTileRow() <= row < @constrainRow(@getEndTileRow() + @tileSize) isOpenTagCode: (tagCode) -> @displayLayer.isOpenTagCode(tagCode) From 78cc959280cc43c1ec45150e9dd9625c271f8c50 Mon Sep 17 00:00:00 2001 From: Daniel Mountford Date: Sun, 15 May 2016 13:08:27 +0100 Subject: [PATCH 32/38] Update link text to match URL --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b5e4db9a..ff48740b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,7 +62,7 @@ Here's a list of the big ones: * [git-diff](https://github.com/atom/git-diff) - Git change indicators shown in the editor's gutter. * [language-javascript](https://github.com/atom/language-javascript) - all bundled languages are packages too, and each one has a separate package `language-[name]`. Use these for feedback on syntax highlighting issues that only appear for a specific language. * [one-dark-ui](https://github.com/atom/one-dark-ui) - the default UI styling for anything but the text editor. UI theme packages (i.e. packages with a `-ui` suffix) provide only styling and it's possible that a bundled package is responsible for a UI issue. There are other other bundled UI themes, such as [one-light-ui](https://github.com/atom/one-light-ui). -* [one-dark-syntax](https://github.com/atom/one-dark-syntax) - the default syntax highlighting styles applied for all languages. There are other other bundled syntax themes, such as [solarized-dark](https://github.com/atom/solarized-dark-syntax). You should use these packages for reporting issues that appear in many languages, but disappear if you change to another syntax theme. +* [one-dark-syntax](https://github.com/atom/one-dark-syntax) - the default syntax highlighting styles applied for all languages. There are other other bundled syntax themes, such as [solarized-dark-syntax](https://github.com/atom/solarized-dark-syntax). You should use these packages for reporting issues that appear in many languages, but disappear if you change to another syntax theme. * [apm](https://github.com/atom/apm) - the `apm` command line tool (Atom Package Manager). You should use this repository for any contributions related to the `apm` tool and to publishing packages. * [atom.io](https://github.com/atom/atom.io) - the repository for feedback on the [Atom.io website](https://atom.io) and the [Atom.io package API](https://github.com/atom/atom/blob/master/docs/apm-rest-api.md) used by [apm](https://github.com/atom/apm). From f36e148accd332f1bdff549af66ac3e1b1921c23 Mon Sep 17 00:00:00 2001 From: Robert Stanfield Date: Sun, 15 May 2016 20:45:45 -0400 Subject: [PATCH 33/38] When using the event editor:copy-selection, it pastes at the cursor rather than the beginning of the line (see #11542) --- src/text-editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 051fd76b8..740f9e5f3 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -3007,7 +3007,7 @@ class TextEditor extends Model maintainClipboard = false for selection in @getSelectionsOrderedByBufferPosition() if not selection.isEmpty() - selection.copy(maintainClipboard, true) + selection.copy(maintainClipboard, false) maintainClipboard = true return From b5b324875e000809e06574ce8f8b0d17f04d0bc3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 16 May 2016 10:41:55 +0200 Subject: [PATCH 34/38] Don't render line-numbers corresponding to lines that need measuring Rendering those line numbers in the gutter isn't useful, and it puts unneeded pressure to the DOM. In the process of changing `updateLineNumbersState`, we have also refactored it to stop relying on row ranges being contiguous. This allows that code path to be: 1. Less error-prone, because we were trying to access rows that weren't actually rendered, thus potentially throwing errors when measuring non-contiguous screen rows that weren't visible. 2. Tighter, because we can just iterate over each screen row and ask for its soft-wrap descriptor. --- spec/text-editor-presenter-spec.coffee | 12 ++++--- src/text-editor-presenter.coffee | 47 +++++++------------------- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 8cdc4e61a..5a91c74f5 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -2805,16 +2805,20 @@ describe "TextEditorPresenter", -> editor.setSoftWrapped(true) editor.setDefaultCharWidth(1) editor.setEditorWidthInChars(51) - presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineHeight: 10, tileSize: 2) + presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineHeight: 10, tileSize: 3) + presenter.setScreenRowsToMeasure([9, 11]) - expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined() - expectValues lineNumberStateForScreenRow(presenter, 2), {screenRow: 2, bufferRow: 2, softWrapped: false} + expect(lineNumberStateForScreenRow(presenter, 2)).toBeUndefined() expectValues lineNumberStateForScreenRow(presenter, 3), {screenRow: 3, bufferRow: 3, softWrapped: false} expectValues lineNumberStateForScreenRow(presenter, 4), {screenRow: 4, bufferRow: 3, softWrapped: true} expectValues lineNumberStateForScreenRow(presenter, 5), {screenRow: 5, bufferRow: 4, softWrapped: false} expectValues lineNumberStateForScreenRow(presenter, 6), {screenRow: 6, bufferRow: 7, softWrapped: false} expectValues lineNumberStateForScreenRow(presenter, 7), {screenRow: 7, bufferRow: 8, softWrapped: false} - expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined() + expectValues lineNumberStateForScreenRow(presenter, 8), {screenRow: 8, bufferRow: 8, softWrapped: true} + expect(lineNumberStateForScreenRow(presenter, 9)).toBeUndefined() + expect(lineNumberStateForScreenRow(presenter, 10)).toBeUndefined() + expect(lineNumberStateForScreenRow(presenter, 11)).toBeUndefined() + expect(lineNumberStateForScreenRow(presenter, 12)).toBeUndefined() it "updates when the editor's content changes", -> editor.foldBufferRow(4) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 1f48bc4fa..95c46e5bf 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -601,42 +601,19 @@ class TextEditorPresenter tileState.lineNumbers ?= {} visibleLineNumberIds = {} - startRow = screenRows[screenRows.length - 1] - endRow = Math.min(screenRows[0] + 1, @model.getScreenLineCount()) + for screenRow in screenRows when @isRowRendered(screenRow) + lineId = @linesByScreenRow.get(screenRow).id + {bufferRow, softWrappedAtStart: softWrapped} = @displayLayer.softWrapDescriptorForScreenRow(screenRow) + foldable = not softWrapped and @model.isFoldableAtBufferRow(bufferRow) + decorationClasses = @lineNumberDecorationClassesForRow(screenRow) + blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) + blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight + if screenRow % @tileSize isnt 0 + blockDecorationsAfterPreviousScreenRowHeight = @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) - @lineHeight - @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow - 1) + blockDecorationsHeight += blockDecorationsAfterPreviousScreenRowHeight - if startRow > 0 - rowBeforeStartRow = startRow - 1 - lastBufferRow = @model.bufferRowForScreenRow(rowBeforeStartRow) - else - lastBufferRow = null - - if endRow > startRow - bufferRows = @model.bufferRowsForScreenRows(startRow, endRow - 1) - previousBufferRow = -1 - foldable = false - for bufferRow, i in bufferRows - # don't compute foldability more than once per buffer row - if previousBufferRow isnt bufferRow - foldable = @model.isFoldableAtBufferRow(bufferRow) - previousBufferRow = bufferRow - - if bufferRow is lastBufferRow - softWrapped = true - else - lastBufferRow = bufferRow - softWrapped = false - - screenRow = startRow + i - lineId = @linesByScreenRow.get(screenRow).id - decorationClasses = @lineNumberDecorationClassesForRow(screenRow) - blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) - blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight - if screenRow % @tileSize isnt 0 - blockDecorationsAfterPreviousScreenRowHeight = @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) - @lineHeight - @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow - 1) - blockDecorationsHeight += blockDecorationsAfterPreviousScreenRowHeight - - tileState.lineNumbers[lineId] = {screenRow, bufferRow, softWrapped, decorationClasses, foldable, blockDecorationsHeight} - visibleLineNumberIds[lineId] = true + tileState.lineNumbers[lineId] = {screenRow, bufferRow, softWrapped, decorationClasses, foldable, blockDecorationsHeight} + visibleLineNumberIds[lineId] = true for id of tileState.lineNumbers delete tileState.lineNumbers[id] unless visibleLineNumberIds[id] From c13346a455043f317b5a85e77543419f168ed9fd Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 16 May 2016 11:23:54 +0200 Subject: [PATCH 35/38] Show folded marker in the first screen row of a soft-wrapped buffer row --- spec/text-editor-presenter-spec.coffee | 29 +++++++++++++++++++------- src/text-editor-presenter.coffee | 4 +--- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 8cdc4e61a..af0260b95 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -3069,15 +3069,28 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'a' expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toContain 'a' - it "applies the 'folded' decoration only to the initial screen row of a soft-wrapped buffer row", -> - editor.setSoftWrapped(true) - editor.setDefaultCharWidth(1) - editor.setEditorWidthInChars(15) - editor.foldBufferRange([[0, 20], [0, 22]]) - presenter = buildPresenter(explicitHeight: 35, scrollTop: 0, tileSize: 2) + describe "when a fold spans a single soft-wrapped buffer row", -> + it "applies the 'folded' decoration only to its initial screen row", -> + editor.setSoftWrapped(true) + editor.setDefaultCharWidth(1) + editor.setEditorWidthInChars(20) + editor.foldBufferRange([[0, 20], [0, 22]]) + editor.foldBufferRange([[0, 10], [0, 14]]) + presenter = buildPresenter(explicitHeight: 35, scrollTop: 0, tileSize: 2) - expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'folded' - expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull() + expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain('folded') + expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull() + + describe "when a fold is at the end of a soft-wrapped buffer row", -> + it "applies the 'folded' decoration only to its initial screen row", -> + editor.setSoftWrapped(true) + editor.setDefaultCharWidth(1) + editor.setEditorWidthInChars(25) + editor.foldBufferRow(1) + presenter = buildPresenter(explicitHeight: 35, scrollTop: 0, tileSize: 2) + + expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toContain('folded') + expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull() describe ".foldable", -> it "marks line numbers at the start of a foldable region as foldable", -> diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 01a0293f6..1a7723128 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1153,13 +1153,11 @@ class TextEditorPresenter if rangeIsReversed headScreenPosition = screenRange.start - headBufferPosition = bufferRange.start else headScreenPosition = screenRange.end - headBufferPosition = bufferRange.end if properties.class is 'folded' and Decoration.isType(properties, 'line-number') - screenRow = @model.screenRowForBufferRow(headBufferPosition.row) + screenRow = @model.screenRowForBufferRow(bufferRange.start.row) @lineNumberDecorationsByScreenRow[screenRow] ?= {} @lineNumberDecorationsByScreenRow[screenRow][decorationId] = properties else From a18369586096191b4ceb22db123d4dbc9fe154d7 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 16 May 2016 13:36:46 +0200 Subject: [PATCH 36/38] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d512e3ddf..80aa134e3 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "9.0.0", + "text-buffer": "9.1.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 655b332a967bf6f302364ba29c1dac3d458303a8 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Mon, 16 May 2016 11:36:35 -0700 Subject: [PATCH 37/38] :arrow_up: settings-view@0.237.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4400d8f15..ef05af5d3 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "notifications": "0.64.0", "open-on-github": "1.1.0", "package-generator": "1.0.0", - "settings-view": "0.236.1", + "settings-view": "0.237.0", "snippets": "1.0.2", "spell-check": "0.67.1", "status-bar": "1.2.6", From 7bcd7f58f94a91c8940258a88a717bfb03d50177 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 17 May 2016 09:25:42 +0200 Subject: [PATCH 38/38] :arrow_up: tree-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef05af5d3..36321e369 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "symbols-view": "0.113.0", "tabs": "0.95.0", "timecop": "0.33.1", - "tree-view": "0.206.2", + "tree-view": "0.207.0", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2",