From dbf7214670b9f625a718f8f5a71b8ffff63e22a5 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Tue, 22 Mar 2016 17:26:30 -0700 Subject: [PATCH 01/11] Fix clean command to actually work when paths missing --- script/clean | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/script/clean b/script/clean index 0c947baf2..cc4933f95 100755 --- a/script/clean +++ b/script/clean @@ -1,11 +1,10 @@ #!/usr/bin/env node -var cp = require('./utils/child-process-wrapper.js'); +var childProcess = require('./utils/child-process-wrapper.js'); var fs = require('fs'); var path = require('path'); var os = require('os'); var isWindows = process.platform === 'win32'; -var removeCommand = isWindows ? 'rmdir /S /Q ' : 'rm -rf '; var productName = require('../package.json').productName; process.chdir(path.dirname(__dirname)); @@ -13,10 +12,10 @@ var home = process.env[isWindows ? 'USERPROFILE' : 'HOME']; var tmpdir = os.tmpdir(); // Windows: Use START as a way to ignore error if Atom.exe isnt running -var killatom = isWindows ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true'; +var killAtomCommand = isWindows ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true'; +//childProcess.safeExec(killAtomCommand); -var commands = [ - killatom, +var pathsToRemove = [ [__dirname, '..', 'node_modules'], [__dirname, '..', 'build', 'node_modules'], [__dirname, '..', 'apm', 'node_modules'], @@ -32,37 +31,30 @@ var commands = [ [home, '.atom', 'electron'], [tmpdir, 'atom-build'], [tmpdir, 'atom-cached-atom-shells'], -]; -var run = function() { - var next = commands.shift(); - if (!next) - process.exit(0); +].map(function(pathSegments) { + return path.resolve.apply(null, pathSegments); +}); - if (Array.isArray(next)) { - var pathToRemove = path.resolve.apply(path.resolve, next); - if (fs.existsSync(pathToRemove)) { - if (isWindows) { - removeFolderRecursive(pathToRemove); - } else { - next = removeCommand + pathToRemove; - cp.safeExec(next, run); - } - } - else { - return run(); - } +pathsToRemove.forEach(function(pathToRemove) { + if (fs.existsSync(pathToRemove)) { + removePath(pathToRemove); } - else - cp.safeExec(next, run); -}; -run(); +}); + +function removePath(pathToRemove) { + if (isWindows) { + removePathOnWindows(pathToRemove); + } else { + childProcess.safeExec('rm -rf ' + pathToRemove); + } +} // Windows has a 260-char path limit for rmdir etc. Just recursively delete in Node. -var removeFolderRecursive = function(folderPath) { +function removePathOnWindows(folderPath) { fs.readdirSync(folderPath).forEach(function(entry, index) { var entryPath = path.join(folderPath, entry); if (fs.lstatSync(entryPath).isDirectory()) { - removeFolderRecursive(entryPath); + removePathOnWindows(entryPath); } else { fs.unlinkSync(entryPath); } From de6ab3b814cd305523f0ae95314fc2bc19e28f51 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Tue, 22 Mar 2016 17:26:41 -0700 Subject: [PATCH 02/11] Exclude PATH entries with msbuild.exe to fix node-gyp on Windows --- script/build | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/script/build b/script/build index a40a02e13..ca5569d0f 100755 --- a/script/build +++ b/script/build @@ -2,9 +2,24 @@ var cp = require('./utils/child-process-wrapper.js'); var runGrunt = require('./utils/run-grunt.js'); var path = require('path'); +var fs = require('fs'); process.chdir(path.dirname(__dirname)); +if (process.platform === 'win32') { + process.env['PATH'] = process.env['PATH'] + .split(';') + .filter(function(p) { + if (fs.existsSync(path.resolve(p, 'msbuild.exe'))) { + console.log('Excluding "' + p + '" from PATH to avoid msbuild.exe mismatch') + return false; + } else { + return true; + } + }) + .join(';'); +} + cp.safeExec('node script/bootstrap', function() { // build/node_modules/.bin/grunt "$@" var args = process.argv.slice(2); From 2a7344091d74de66f77a366ee963eb82bba00cb4 Mon Sep 17 00:00:00 2001 From: Isaac Salier-Hellendag Date: Wed, 23 Mar 2016 19:18:02 -0700 Subject: [PATCH 03/11] Avoid setting hidden input value on textInput Atom currently sets the `value` of the input on every `textInput` event, in an effort to appropriately handle changes made via the OSX diacritic menu (for accents, umlauts, etc). The drawback of this is approach is that updating the value of the input will trigger layout and a subsequent layer tree update. To resolve this, here is my proposal: - Track a flag for `keypress` events. When the diacritic menu is used, there are two `textInput` events, with no `keypress` in between. Therefore, when no `keypress` has occurred just prior to a `textInput`, the editor model can select the previous character to be replaced by the new accented character. - Track a flag for `compositionstart` events. When a user is in IME mode, the diacritic menu cannot be used, so the editor can skip the backward selection. Test Plan: Tested in a plaintext file. - Type Latin characters, verify proper character insertion. - Press and hold a. Diacritic menu appears. Select an option using the keyboard or mouse. Verify that the `a` is replaced by an accented `a`, with no extra characters. - Type test strings in Katakana, 2-Set Korean, Telex (Vietnamese), Simplified Pinyin. Verify that characters are inserted correctly while composing, and after committing strings. --- src/text-editor-component.coffee | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 9b091100d..50851279b 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -244,6 +244,7 @@ class TextEditorComponent listenForDOMEvents: -> @domNode.addEventListener 'mousewheel', @onMouseWheel @domNode.addEventListener 'textInput', @onTextInput + @domNode.addEventListener 'keypress', @onKeyPress @scrollViewNode.addEventListener 'mousedown', @onMouseDown @scrollViewNode.addEventListener 'scroll', @onScrollViewScroll @@ -266,6 +267,7 @@ class TextEditorComponent checkpoint = null @domNode.addEventListener 'compositionstart', => + @imeMode = true checkpoint = @editor.createCheckpoint() @domNode.addEventListener 'compositionupdate', (event) => @editor.insertText(event.data, select: true) @@ -319,26 +321,27 @@ class TextEditorComponent if @mounted @presenter.setFocused(false) + onKeyPress: (event) => + @detectedKeyPress = true + onTextInput: (event) => event.stopPropagation() - - # If we prevent the insertion of a space character, then the browser - # interprets the spacebar keypress as a page-down command. - event.preventDefault() unless event.data is ' ' + event.preventDefault() return unless @isInputEnabled() - inputNode = event.target + # Workaround of the accented character suggestion feature in OS X. + # This will only occur when the user is not composing in IME mode. + # When the user selects a modified character from the OSX menu, `textInput` + # will occur twice, once for the initial character, and once for the + # modified character. However, only a single keypress will have fired. If + # this is the case, select backward to replace the original character. + if not @imeMode and not @detectedKeyPress + @editor.selectLeft() - # Work around of the accented character suggestion feature in OS X. - # Text input fires before a character is inserted, and if the browser is - # replacing the previous un-accented character with an accented variant, it - # will select backward over it. - selectedLength = inputNode.selectionEnd - inputNode.selectionStart - @editor.selectLeft() if selectedLength is 1 - - insertedRange = @editor.insertText(event.data, groupUndo: true) - inputNode.value = event.data if insertedRange + @editor.insertText(event.data, groupUndo: true) + @detectedKeyPress = false + @imeMode = false onVerticalScroll: (scrollTop) => return if @updateRequested or scrollTop is @presenter.getScrollTop() From a99ee14ac0be502d6e18b56b8b9b84a5c1c472e9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 4 Apr 2016 17:47:36 -0600 Subject: [PATCH 04/11] Make accented character menu detection work with left/right arrow keys --- spec/text-editor-component-spec.js | 3 ++- src/text-editor-component.coffee | 29 +++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 1d1e4eb9f..30bc9251c 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -3767,11 +3767,12 @@ describe('TextEditorComponent', function () { expect(editor.lineTextForBufferRow(0)).toBe('xyvar quicksort = function () {') }) - it('replaces the last character if the length of the input\'s value does not increase, as occurs with the accented character menu', async function () { + it('replaces the last character if the textInput event is followed by one or more additional keydown events, which occurs when the accented character menu is shown', async function () { componentNode.dispatchEvent(buildTextInputEvent({ data: 'u', target: inputNode })) + componentNode.dispatchEvent(new KeyboardEvent('keydown')) await nextViewUpdatePromise() expect(editor.lineTextForBufferRow(0)).toBe('uvar quicksort = function () {') diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 50851279b..8e91557c8 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -244,13 +244,28 @@ class TextEditorComponent listenForDOMEvents: -> @domNode.addEventListener 'mousewheel', @onMouseWheel @domNode.addEventListener 'textInput', @onTextInput - @domNode.addEventListener 'keypress', @onKeyPress @scrollViewNode.addEventListener 'mousedown', @onMouseDown @scrollViewNode.addEventListener 'scroll', @onScrollViewScroll + @detectAccentedCharacterMenu() @listenForIMEEvents() @trackSelectionClipboard() if process.platform is 'linux' + detectAccentedCharacterMenu: -> + # We need to get clever to detect when the accented character menu is + # opened on OS X. Usually, every keydown event that could cause input is + # paired with a corresponding keypress. However, when pressing and holding + # long enough to open the accented character menu causes additional keydown + # events to fire that aren't followed by their own keypress and textInput + # events. We exploit this by assuming the accented character menu is open + # until a subsequent keypress event proves otherwise. + @domNode.addEventListener 'keydown', (event) => + unless event.keyCode is 229 # Skip keydown events associated with IME compositionupdate events + @openedAccentedCharacterMenu = true + + @domNode.addEventListener 'keypress', => + @openedAccentedCharacterMenu = false + listenForIMEEvents: -> # The IME composition events work like this: # @@ -267,7 +282,9 @@ class TextEditorComponent checkpoint = null @domNode.addEventListener 'compositionstart', => - @imeMode = true + if @openedAccentedCharacterMenu + @editor.selectLeft() + @openedAccentedCharacterMenu = false checkpoint = @editor.createCheckpoint() @domNode.addEventListener 'compositionupdate', (event) => @editor.insertText(event.data, select: true) @@ -321,9 +338,6 @@ class TextEditorComponent if @mounted @presenter.setFocused(false) - onKeyPress: (event) => - @detectedKeyPress = true - onTextInput: (event) => event.stopPropagation() event.preventDefault() @@ -336,12 +350,11 @@ class TextEditorComponent # will occur twice, once for the initial character, and once for the # modified character. However, only a single keypress will have fired. If # this is the case, select backward to replace the original character. - if not @imeMode and not @detectedKeyPress + if @openedAccentedCharacterMenu @editor.selectLeft() + @openedAccentedCharacterMenu = false @editor.insertText(event.data, groupUndo: true) - @detectedKeyPress = false - @imeMode = false onVerticalScroll: (scrollTop) => return if @updateRequested or scrollTop is @presenter.getScrollTop() From 9eff3a952b90900f106604ade3e52828e083b0e1 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 4 Apr 2016 20:18:59 -0400 Subject: [PATCH 05/11] :arrow_up: language-ruby@0.68.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a630dabfc..3089c4418 100644 --- a/package.json +++ b/package.json @@ -138,7 +138,7 @@ "language-php": "0.37.0", "language-property-list": "0.8.0", "language-python": "0.43.1", - "language-ruby": "0.68.4", + "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", "language-sass": "0.46.0", "language-shellscript": "0.21.1", From f638bcbb6d97a27a90d9d8b780659eb61d87de55 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 4 Apr 2016 18:56:08 -0600 Subject: [PATCH 06/11] =?UTF-8?q?Don=E2=80=99t=20assume=20the=20accented?= =?UTF-8?q?=20character=20menu=20on=20every=20IME=20event?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/text-editor-component.coffee | 35 +++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 8e91557c8..b76a23ddc 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -254,18 +254,43 @@ class TextEditorComponent detectAccentedCharacterMenu: -> # We need to get clever to detect when the accented character menu is # opened on OS X. Usually, every keydown event that could cause input is - # paired with a corresponding keypress. However, when pressing and holding + # followed by a corresponding keypress. However, pressing and holding # long enough to open the accented character menu causes additional keydown # events to fire that aren't followed by their own keypress and textInput - # events. We exploit this by assuming the accented character menu is open - # until a subsequent keypress event proves otherwise. + # events. + # + # Therefore, we assume the accented character menu has been deployed if, + # before observing any keyup event, we observe events in the following + # sequence: + # + # keydown(keyCode: X), keypress, keydown(codeCode: X) + # + # The keyCode X must be the same in the keydown events that bracket the + # keypress, meaning we're *holding* the _same_ key we intially pressed. + # Got that? + lastKeydown = null + lastKeydownBeforeKeypress = null + @domNode.addEventListener 'keydown', (event) => - unless event.keyCode is 229 # Skip keydown events associated with IME compositionupdate events - @openedAccentedCharacterMenu = true + if lastKeydownBeforeKeypress + if lastKeydownBeforeKeypress.keyCode is event.keyCode + @openedAccentedCharacterMenu = true + lastKeydownBeforeKeypress = null + else + lastKeydown = event @domNode.addEventListener 'keypress', => + lastKeydownBeforeKeypress = lastKeydown + lastKeydown = null + + # This cancels the accented character behavior if we type a key normally + # with the menu open. @openedAccentedCharacterMenu = false + @domNode.addEventListener 'keyup', => + lastKeydownBeforeKeypress = null + lastKeydown = null + listenForIMEEvents: -> # The IME composition events work like this: # From 9833e54ec349d9503c1facac44ad8b7e6bc09bc0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 4 Apr 2016 19:22:44 -0600 Subject: [PATCH 07/11] Fix typo --- src/text-editor-component.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index b76a23ddc..12f481be5 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -263,7 +263,7 @@ class TextEditorComponent # before observing any keyup event, we observe events in the following # sequence: # - # keydown(keyCode: X), keypress, keydown(codeCode: X) + # keydown(keyCode: X), keypress, keydown(keyCode: X) # # The keyCode X must be the same in the keydown events that bracket the # keypress, meaning we're *holding* the _same_ key we intially pressed. From 402a335eefa8c15b95c917496d29c740a4a1535f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 4 Apr 2016 19:50:39 -0600 Subject: [PATCH 08/11] Fix accented character menu spec --- spec/text-editor-component-spec.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 30bc9251c..b031cba33 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -3745,6 +3745,21 @@ describe('TextEditorComponent', function () { return event } + function buildKeydownEvent ({keyCode, target}) { + let event = new KeyboardEvent('keydown') + Object.defineProperty(event, 'keyCode', { + get: function () { + return keyCode + } + }) + Object.defineProperty(event, 'target', { + get: function () { + return target + } + }) + return event + } + let inputNode beforeEach(function () { @@ -3767,12 +3782,12 @@ describe('TextEditorComponent', function () { expect(editor.lineTextForBufferRow(0)).toBe('xyvar quicksort = function () {') }) - it('replaces the last character if the textInput event is followed by one or more additional keydown events, which occurs when the accented character menu is shown', async function () { - componentNode.dispatchEvent(buildTextInputEvent({ - data: 'u', - target: inputNode - })) - componentNode.dispatchEvent(new KeyboardEvent('keydown')) + it('replaces the last character if a keypress event is bracketed by keydown events with matching keyCodes, which occurs when the accented character menu is shown', async function () { + componentNode.dispatchEvent(buildKeydownEvent({keyCode: 85, target: inputNode})) + componentNode.dispatchEvent(buildTextInputEvent({data: 'u', target: inputNode})) + componentNode.dispatchEvent(new KeyboardEvent('keypress')) + componentNode.dispatchEvent(buildKeydownEvent({keyCode: 85, target: inputNode})) + componentNode.dispatchEvent(new KeyboardEvent('keyup')) await nextViewUpdatePromise() expect(editor.lineTextForBufferRow(0)).toBe('uvar quicksort = function () {') From fd3789223c16307925511c1c586b130980aac317 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 4 Apr 2016 19:53:41 -0600 Subject: [PATCH 09/11] :arrow_up: status-bar --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3089c4418..4c03b3916 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "settings-view": "0.235.1", "snippets": "1.0.2", "spell-check": "0.67.0", - "status-bar": "1.2.0", + "status-bar": "1.2.1", "styleguide": "0.45.2", "symbols-view": "0.112.0", "tabs": "0.92.0", From b3ea0a6494be5da732bce61bc76946c43149ecbb Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 5 Apr 2016 16:40:06 -0600 Subject: [PATCH 10/11] :arrow_up: bookmarks --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c03b3916..4e5fce85a 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "autoflow": "0.27.0", "autosave": "0.23.1", "background-tips": "0.26.0", - "bookmarks": "0.38.2", + "bookmarks": "0.38.3", "bracket-matcher": "0.82.0", "command-palette": "0.38.0", "deprecation-cop": "0.54.1", From 26ddee4a05a4539d89dd03a26bfdb7968454a19b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 5 Apr 2016 16:40:15 -0600 Subject: [PATCH 11/11] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4e5fce85a..6c796a711 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.29.1", + "autocomplete-plus": "2.29.2", "autocomplete-snippets": "1.10.0", "autoflow": "0.27.0", "autosave": "0.23.1",