From 8cd48004dd68d5ea3e4d4f0fada256aa1b83186d Mon Sep 17 00:00:00 2001 From: Willem Van Lint Date: Sat, 9 Apr 2016 18:42:18 -0700 Subject: [PATCH 001/111] Fixed positioning for overlay --- src/text-editor-presenter.coffee | 12 +++++++----- static/text-editor-light.less | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index ef1b403c3..e5a9cd589 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -459,19 +459,21 @@ class TextEditorPresenter pixelPosition = @pixelPositionForScreenPosition(screenPosition) - top = pixelPosition.top + @lineHeight - left = pixelPosition.left + @gutterWidth + # Fixed positioning. + top = @boundingClientRect.top + pixelPosition.top + @lineHeight + left = @boundingClientRect.left + pixelPosition.left + @gutterWidth if overlayDimensions = @overlayDimensions[decoration.id] {itemWidth, itemHeight, contentMargin} = overlayDimensions - rightDiff = left + @boundingClientRect.left + itemWidth + contentMargin - @windowWidth + rightDiff = left + itemWidth + contentMargin - @windowWidth left -= rightDiff if rightDiff > 0 - leftDiff = left + @boundingClientRect.left + contentMargin + leftDiff = left + contentMargin left -= leftDiff if leftDiff < 0 - if top + @boundingClientRect.top + itemHeight > @windowHeight and top - (itemHeight + @lineHeight) >= 0 + if top + itemHeight > @windowHeight and + top - (itemHeight + @lineHeight) >= 0 top -= itemHeight + @lineHeight pixelPosition.top = top diff --git a/static/text-editor-light.less b/static/text-editor-light.less index 7fafade1e..f5429fd7f 100644 --- a/static/text-editor-light.less +++ b/static/text-editor-light.less @@ -15,7 +15,7 @@ atom-text-editor[mini] { } atom-overlay { - position: absolute; + position: fixed; display: block; z-index: 4; } From 04ff6e461108e0488cda1a731d5041b3148d8fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20L=C3=A1zaro=20Gallego?= Date: Thu, 14 Apr 2016 16:14:39 +0200 Subject: [PATCH 002/111] Fixes #4126 for fish-shell --- src/environment-helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/environment-helpers.js b/src/environment-helpers.js index e2baeb26b..151796f06 100644 --- a/src/environment-helpers.js +++ b/src/environment-helpers.js @@ -58,7 +58,7 @@ function getFromShell () { function needsPatching (options = { platform: process.platform, env: process.env }) { if (options.platform === 'darwin' && !options.env.PWD) { let shell = getUserShell() - if (shell.endsWith('csh') || shell.endsWith('tcsh')) { + if (shell.endsWith('csh') || shell.endsWith('tcsh') || shell.endsWith('fish')) { return false } return true From 9b8cb237574bcec33101260334175622d5535d61 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 15 Apr 2016 10:48:35 -0700 Subject: [PATCH 003/111] Preserve the process.env magic for Windows --- src/environment-helpers.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/environment-helpers.js b/src/environment-helpers.js index e2baeb26b..8039e8537 100644 --- a/src/environment-helpers.js +++ b/src/environment-helpers.js @@ -67,9 +67,19 @@ function needsPatching (options = { platform: process.platform, env: process.env return false } +// Fix for #11302 because `process.env` on Windows is a magic object that offers case-insensitive +// environment variable matching. +function cloneEnv (env) { + for (var key in process.env) { + delete process.env[key] + } + + Object.assign(process.env, env) +} + function normalize (options = {}) { if (options && options.env) { - process.env = options.env + cloneEnv(options.env) } if (!options.env) { @@ -85,8 +95,8 @@ function normalize (options = {}) { // in #4126. Retain the original in case someone needs it. let shellEnv = getFromShell() if (shellEnv && shellEnv.PATH) { - process._originalEnv = process.env - process.env = shellEnv + process._originalEnv = Object.assign({}, process.env) + cloneEnv(shellEnv) } } } @@ -96,7 +106,7 @@ function replace (env) { return } - process.env = env + cloneEnv(env) } export default { getFromShell, needsPatching, normalize, replace } From 99e716f9ed2142e83c9d73b45aba42735d40ad94 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 15 Apr 2016 11:25:05 -0700 Subject: [PATCH 004/111] Fix specs failures on Windows including paths --- spec/atom-environment-spec.coffee | 6 ++++-- spec/git-repository-async-spec.js | 2 +- spec/git-spec.coffee | 2 +- spec/project-spec.coffee | 2 +- spec/spec-helper.coffee | 26 ++++++++++++++++---------- spec/text-editor-component-spec.js | 4 ++-- spec/text-editor-spec.coffee | 14 ++++++++------ spec/theme-manager-spec.coffee | 8 ++++---- spec/workspace-spec.coffee | 21 +++++++++++++++------ 9 files changed, 52 insertions(+), 33 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 5fd4b11f1..846083b0e 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -28,8 +28,10 @@ describe "AtomEnvironment", -> atom.setSize(originalSize.width, originalSize.height) it 'sets the size of the window, and can retrieve the size just set', -> - atom.setSize(100, 400) - expect(atom.getSize()).toEqual width: 100, height: 400 + newWidth = originalSize.width + 12 + newHeight = originalSize.height + 23 + atom.setSize(newWidth, newHeight) + expect(atom.getSize()).toEqual width: newWidth, height: newHeight describe ".isReleasedVersion()", -> it "returns false if the version is a SHA and true otherwise", -> diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 0442248e1..251734448 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -103,7 +103,7 @@ describe('GitRepositoryAsync', () => { it('returns the repository path for a repository path', async () => { repo = openFixture('master.git') const repoPath = await repo.getPath() - expect(repoPath).toBe(path.join(__dirname, 'fixtures', 'git', 'master.git')) + expect(repoPath).toBePath(path.join(__dirname, 'fixtures', 'git', 'master.git')) }) }) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 3afd4da75..87aeab12a 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -33,7 +33,7 @@ describe "GitRepository", -> waitsForPromise -> repo.async.getPath().then(onSuccess) runs -> - expect(onSuccess.mostRecentCall.args[0]).toBe(repoPath) + expect(onSuccess.mostRecentCall.args[0]).toBePath(repoPath) describe "new GitRepository(path)", -> it "throws an exception when no repository is found", -> diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 499efd017..953cf103e 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -526,7 +526,7 @@ describe "Project", -> expect(atom.project.getDirectories()[1].contains(inputPath)).toBe true expect(atom.project.relativizePath(inputPath)).toEqual [ atom.project.getPaths()[1], - 'somewhere/something.txt' + path.join('somewhere', 'something.txt') ] describe ".contains(path)", -> diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 1194f2f76..78a47ab0b 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -172,8 +172,8 @@ jasmine.useRealClock = -> addCustomMatchers = (spec) -> spec.addMatchers toBeInstanceOf: (expected) -> - notText = if @isNot then " not" else "" - this.message = => "Expected #{jasmine.pp(@actual)} to#{notText} be instance of #{expected.name} class" + beOrNotBe = if @isNot then "not be" else "be" + this.message = => "Expected #{jasmine.pp(@actual)} to #{beOrNotBe} instance of #{expected.name} class" @actual instanceof expected toHaveLength: (expected) -> @@ -181,32 +181,38 @@ addCustomMatchers = (spec) -> this.message = => "Expected object #{@actual} has no length method" false else - notText = if @isNot then " not" else "" - this.message = => "Expected object with length #{@actual.length} to#{notText} have length #{expected}" + haveOrNotHave = if @isNot then "not have" else "have" + this.message = => "Expected object with length #{@actual.length} to #{haveOrNotHave} length #{expected}" @actual.length is expected toExistOnDisk: (expected) -> - notText = this.isNot and " not" or "" - @message = -> return "Expected path '" + @actual + "'" + notText + " to exist." + toOrNotTo = this.isNot and "not to" or "to" + @message = -> return "Expected path '#{@actual}' #{toOrNotTo} exist." fs.existsSync(@actual) toHaveFocus: -> - notText = this.isNot and " not" or "" + toOrNotTo = this.isNot and "not to" or "to" if not document.hasFocus() console.error "Specs will fail because the Dev Tools have focus. To fix this close the Dev Tools or click the spec runner." - @message = -> return "Expected element '" + @actual + "' or its descendants" + notText + " to have focus." + @message = -> return "Expected element '#{@actual}' or its descendants #{toOrNotTo} have focus." element = @actual element = element.get(0) if element.jquery element is document.activeElement or element.contains(document.activeElement) toShow: -> - notText = if @isNot then " not" else "" + toOrNotTo = this.isNot and "not to" or "to" element = @actual element = element.get(0) if element.jquery - @message = -> return "Expected element '#{element}' or its descendants#{notText} to show." + @message = -> return "Expected element '#{element}' or its descendants #{toOrNotTo} show." element.style.display in ['block', 'inline-block', 'static', 'fixed'] + toBePath: (expected) -> + actualPath = path.normalize(@actual) + expectedPath = path.normalize(expected) + @message = -> return "Expected path '#{actualPath}' to be equal to '#{expectedPath}'." + actualPath is expectedPath + window.waitsForPromise = (args...) -> label = null if args.length > 1 diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index b031cba33..c1b2f8f46 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4028,9 +4028,9 @@ describe('TextEditorComponent', function () { component.setFontSize(10) await nextViewUpdatePromise() expect(editor.getDefaultCharWidth()).toBeCloseTo(6, 0) - expect(editor.getKoreanCharWidth()).toBeCloseTo(9, 0) + expect(editor.getKoreanCharWidth()).toBeCloseTo(10, 0) expect(editor.getDoubleWidthCharWidth()).toBe(10) - expect(editor.getHalfWidthCharWidth()).toBe(5) + expect(editor.getHalfWidthCharWidth()).toBeCloseTo(6, 5) }) }) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 4de7168b7..7d85f1cad 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -182,17 +182,19 @@ describe "TextEditor", -> expect(editor1.getLongTitle()).toBe "readme \u2014 sample-theme-1" expect(editor2.getLongTitle()).toBe "readme \u2014 sample-theme-2" - it "returns '' when opened files have identical file and dir names", -> + it "returns '' when opened files have identical file names in subdirectories", -> editor1 = null editor2 = null + path1 = path.join('sample-theme-1', 'src', 'js') + path2 = path.join('sample-theme-2', 'src', 'js') waitsForPromise -> - atom.workspace.open(path.join('sample-theme-1', 'src', 'js', 'main.js')).then (o) -> + atom.workspace.open(path.join(path1, 'main.js')).then (o) -> editor1 = o - atom.workspace.open(path.join('sample-theme-2', 'src', 'js', 'main.js')).then (o) -> + atom.workspace.open(path.join(path2, 'main.js')).then (o) -> editor2 = o runs -> - expect(editor1.getLongTitle()).toBe "main.js \u2014 sample-theme-1/src/js" - expect(editor2.getLongTitle()).toBe "main.js \u2014 sample-theme-2/src/js" + expect(editor1.getLongTitle()).toBe "main.js \u2014 #{path1}" + expect(editor2.getLongTitle()).toBe "main.js \u2014 #{path2}" it "returns '' when opened files have identical file and same parent dir name", -> editor1 = null @@ -204,7 +206,7 @@ describe "TextEditor", -> editor2 = o runs -> expect(editor1.getLongTitle()).toBe "main.js \u2014 js" - expect(editor2.getLongTitle()).toBe "main.js \u2014 js/plugin" + expect(editor2.getLongTitle()).toBe "main.js \u2014 " + path.join('js', 'plugin') it "notifies ::onDidChangeTitle observers when the underlying buffer path changes", -> observed = [] diff --git a/spec/theme-manager-spec.coffee b/spec/theme-manager-spec.coffee index ea0ca19e6..0ab8a58b3 100644 --- a/spec/theme-manager-spec.coffee +++ b/spec/theme-manager-spec.coffee @@ -175,7 +175,7 @@ describe "atom.themes", -> expect(styleElementAddedHandler).toHaveBeenCalled() element = document.querySelector('head style[source-path*="css.css"]') - expect(element.getAttribute('source-path')).toBe atom.themes.stringToId(cssPath) + expect(element.getAttribute('source-path')).toBePath atom.themes.stringToId(cssPath) expect(element.textContent).toBe fs.readFileSync(cssPath, 'utf8') # doesn't append twice @@ -194,7 +194,7 @@ describe "atom.themes", -> expect(document.querySelectorAll('head style').length).toBe lengthBefore + 1 element = document.querySelector('head style[source-path*="sample.less"]') - expect(element.getAttribute('source-path')).toBe atom.themes.stringToId(lessPath) + expect(element.getAttribute('source-path')).toBePath atom.themes.stringToId(lessPath) expect(element.textContent).toBe """ #header { color: #4d926f; @@ -213,9 +213,9 @@ describe "atom.themes", -> it "supports requiring css and less stylesheets without an explicit extension", -> atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'css') - expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toBe atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('css.css')) + expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toBePath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('css.css')) atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'sample') - expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toBe atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less')) + expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toBePath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less')) document.querySelector('head style[source-path*="css.css"]').remove() document.querySelector('head style[source-path*="sample.less"]').remove() diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 97139f6bb..fc22f07c3 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -80,7 +80,8 @@ describe "Workspace", -> expect(untitledEditor.getText()).toBe("An untitled editor.") expect(atom.workspace.getActiveTextEditor().getPath()).toBe editor3.getPath() - expect(document.title).toMatch ///^#{path.basename(editor3.getLongTitle())}\ \u2014\ #{atom.project.getPaths()[0]}/// + pathEscaped = escapeStringRegex(atom.project.getPaths()[0]) + expect(document.title).toMatch ///^#{path.basename(editor3.getLongTitle())}\ \u2014\ #{pathEscaped}/// describe "where there are no open panes or editors", -> it "constructs the view with no open editors", -> @@ -833,25 +834,29 @@ describe "Workspace", -> describe "when there is an active pane item", -> it "sets the title to the pane item's title plus the project path", -> item = atom.workspace.getActivePaneItem() - expect(document.title).toMatch ///^#{item.getTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// + pathEscaped = escapeStringRegex(atom.project.getPaths()[0]) + expect(document.title).toMatch ///^#{item.getTitle()}\ \u2014\ #{pathEscaped}/// describe "when the title of the active pane item changes", -> it "updates the window title based on the item's new title", -> editor = atom.workspace.getActivePaneItem() editor.buffer.setPath(path.join(temp.dir, 'hi')) - expect(document.title).toMatch ///^#{editor.getTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// + pathEscaped = escapeStringRegex(atom.project.getPaths()[0]) + expect(document.title).toMatch ///^#{editor.getTitle()}\ \u2014\ #{pathEscaped}/// describe "when the active pane's item changes", -> it "updates the title to the new item's title plus the project path", -> atom.workspace.getActivePane().activateNextItem() item = atom.workspace.getActivePaneItem() - expect(document.title).toMatch ///^#{item.getTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// + pathEscaped = escapeStringRegex(atom.project.getPaths()[0]) + expect(document.title).toMatch ///^#{item.getTitle()}\ \u2014\ #{pathEscaped}/// describe "when the last pane item is removed", -> it "updates the title to contain the project's path", -> atom.workspace.getActivePane().destroy() expect(atom.workspace.getActivePaneItem()).toBeUndefined() - expect(document.title).toMatch ///^#{atom.project.getPaths()[0]}/// + pathEscaped = escapeStringRegex(atom.project.getPaths()[0]) + expect(document.title).toMatch ///^#{pathEscaped}/// describe "when an inactive pane's item changes", -> it "does not update the title", -> @@ -875,7 +880,8 @@ describe "Workspace", -> }) workspace2.deserialize(atom.workspace.serialize(), atom.deserializers) item = workspace2.getActivePaneItem() - expect(document.title).toMatch ///^#{item.getLongTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// + pathEscaped = escapeStringRegex(atom.project.getPaths()[0]) + expect(document.title).toMatch ///^#{item.getLongTitle()}\ \u2014\ #{pathEscaped}/// workspace2.destroy() describe "document edited status", -> @@ -1610,3 +1616,6 @@ describe "Workspace", -> runs -> expect(pane.getPendingItem()).toBeFalsy() + + escapeStringRegex = (str) -> + str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') From 6d80dfe2280d782ade6ec43c04792fdeb2960624 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 15 Apr 2016 12:59:57 -0700 Subject: [PATCH 005/111] Make the clone function more generic --- src/environment-helpers.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/environment-helpers.js b/src/environment-helpers.js index 8039e8537..eac2b9c0a 100644 --- a/src/environment-helpers.js +++ b/src/environment-helpers.js @@ -68,18 +68,19 @@ function needsPatching (options = { platform: process.platform, env: process.env } // Fix for #11302 because `process.env` on Windows is a magic object that offers case-insensitive -// environment variable matching. -function cloneEnv (env) { - for (var key in process.env) { - delete process.env[key] +// environment variable matching. By always cloning to `process.env` we prevent breaking the +// underlying functionality. +function clone (to, from) { + for (var key in to) { + delete to[key] } - Object.assign(process.env, env) + Object.assign(to, from) } function normalize (options = {}) { if (options && options.env) { - cloneEnv(options.env) + clone(process.env, options.env) } if (!options.env) { @@ -96,7 +97,7 @@ function normalize (options = {}) { let shellEnv = getFromShell() if (shellEnv && shellEnv.PATH) { process._originalEnv = Object.assign({}, process.env) - cloneEnv(shellEnv) + clone(process.env, shellEnv) } } } @@ -106,7 +107,7 @@ function replace (env) { return } - cloneEnv(env) + clone(process.env, env) } export default { getFromShell, needsPatching, normalize, replace } From 30d4b937571c9e1fdbf46d0d0c71d284e56dc788 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 15 Apr 2016 19:56:25 -0700 Subject: [PATCH 006/111] :arrow_up: notifications@0.63.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 62bb8d5f1..8c0abfbf6 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.1", + "notifications": "0.63.2", "open-on-github": "1.1.0", "package-generator": "1.0.0", "settings-view": "0.235.1", From 8ece1ee90929d7635d25bc76ea5f3aca442e977e Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 15 Apr 2016 20:00:21 -0700 Subject: [PATCH 007/111] :arrow_up: tabs@0.92.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c0abfbf6..a44453cf0 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.2.3", "styleguide": "0.45.2", "symbols-view": "0.112.0", - "tabs": "0.92.1", + "tabs": "0.92.2", "timecop": "0.33.1", "tree-view": "0.206.0", "update-package-dependencies": "0.10.0", From e41b9f00fb7dc58299ab83aa111480960ab62ded Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Fri, 15 Apr 2016 21:23:00 -0700 Subject: [PATCH 008/111] Correctly autoindent single newline in Selection#insertText --- spec/selection-spec.coffee | 5 +++++ src/selection.coffee | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/selection-spec.coffee b/spec/selection-spec.coffee index 319e2d438..8830f4188 100644 --- a/spec/selection-spec.coffee +++ b/spec/selection-spec.coffee @@ -91,3 +91,8 @@ describe "Selection", -> expect(buffer.lineForRow(0)).toBe " " expect(buffer.lineForRow(1)).toBe " " expect(buffer.lineForRow(2)).toBe "" + + it "auto-indents if only a newline is inserted", -> + selection.setBufferRange [[2, 0], [3, 0]] + selection.insertText("\n", autoIndent: true) + expect(buffer.lineForRow(2)).toBe " " diff --git a/src/selection.coffee b/src/selection.coffee index e208ea55a..8d93d2fa1 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -378,7 +378,7 @@ class Selection extends Model indentAdjustment = @editor.indentLevelForLine(precedingText) - options.indentBasis @adjustIndent(remainingLines, indentAdjustment) - if options.autoIndent and NonWhitespaceRegExp.test(text) and not NonWhitespaceRegExp.test(precedingText) and remainingLines.length > 0 + if options.autoIndent and (text is '\n' or NonWhitespaceRegExp.test(text)) and not NonWhitespaceRegExp.test(precedingText) and remainingLines.length > 0 autoIndentFirstLine = true firstLine = precedingText + firstInsertedLine desiredIndentLevel = @editor.languageMode.suggestedIndentForLineAtBufferRow(oldBufferRange.start.row, firstLine) From 7160461ebcf8f3638476aeb13f728f4166d0bfa9 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Sat, 16 Apr 2016 11:00:46 -0700 Subject: [PATCH 009/111] Copy active item when splitting from TextEditor context menu --- menus/darwin.cson | 8 ++++---- menus/linux.cson | 8 ++++---- menus/win32.cson | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/menus/darwin.cson b/menus/darwin.cson index 53cc4cbc4..bb3ce0acf 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -228,10 +228,10 @@ {label: 'Delete', command: 'core:delete'} {label: 'Select All', command: 'core:select-all'} {type: 'separator'} - {label: 'Split Up', command: 'pane:split-up'} - {label: 'Split Down', command: 'pane:split-down'} - {label: 'Split Left', command: 'pane:split-left'} - {label: 'Split Right', command: 'pane:split-right'} + {label: 'Split Up', command: 'pane:split-up-and-copy-active-item'} + {label: 'Split Down', command: 'pane:split-down-and-copy-active-item'} + {label: 'Split Left', command: 'pane:split-left-and-copy-active-item'} + {label: 'Split Right', command: 'pane:split-right-and-copy-active-item'} {label: 'Close Pane', command: 'pane:close'} {type: 'separator'} ] diff --git a/menus/linux.cson b/menus/linux.cson index be11c1430..b84fc8053 100644 --- a/menus/linux.cson +++ b/menus/linux.cson @@ -204,10 +204,10 @@ {label: 'Delete', command: 'core:delete'} {label: 'Select All', command: 'core:select-all'} {type: 'separator'} - {label: 'Split Up', command: 'pane:split-up'} - {label: 'Split Down', command: 'pane:split-down'} - {label: 'Split Left', command: 'pane:split-left'} - {label: 'Split Right', command: 'pane:split-right'} + {label: 'Split Up', command: 'pane:split-up-and-copy-active-item'} + {label: 'Split Down', command: 'pane:split-down-and-copy-active-item'} + {label: 'Split Left', command: 'pane:split-left-and-copy-active-item'} + {label: 'Split Right', command: 'pane:split-right-and-copy-active-item'} {label: 'Close Pane', command: 'pane:close'} {type: 'separator'} ] diff --git a/menus/win32.cson b/menus/win32.cson index 738b52f00..323db5d18 100644 --- a/menus/win32.cson +++ b/menus/win32.cson @@ -207,10 +207,10 @@ {label: 'Delete', command: 'core:delete'} {label: 'Select All', command: 'core:select-all'} {type: 'separator'} - {label: 'Split Up', command: 'pane:split-up'} - {label: 'Split Down', command: 'pane:split-down'} - {label: 'Split Left', command: 'pane:split-left'} - {label: 'Split Right', command: 'pane:split-right'} + {label: 'Split Up', command: 'pane:split-up-and-copy-active-item'} + {label: 'Split Down', command: 'pane:split-down-and-copy-active-item'} + {label: 'Split Left', command: 'pane:split-left-and-copy-active-item'} + {label: 'Split Right', command: 'pane:split-right-and-copy-active-item'} {label: 'Close Pane', command: 'pane:close'} {type: 'separator'} ] From af5cb863de32089ddf9ab9b89f28c61e1ff3653c Mon Sep 17 00:00:00 2001 From: Riley Dallas Date: Mon, 18 Apr 2016 10:12:05 -0500 Subject: [PATCH 010/111] :memo: Update links in keymap.cson comments --- dot-atom/keymap.cson | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dot-atom/keymap.cson b/dot-atom/keymap.cson index 10ad345d4..fd7c4f96e 100644 --- a/dot-atom/keymap.cson +++ b/dot-atom/keymap.cson @@ -18,15 +18,15 @@ # 'ctrl-p': 'core:move-down' # # You can find more information about keymaps in these guides: -# * https://atom.io/docs/latest/using-atom-basic-customization#customizing-key-bindings -# * https://atom.io/docs/latest/behind-atom-keymaps-in-depth +# * http://flight-manual.atom.io/using-atom/sections/basic-customization/#_customizing_keybindings +# * http://flight-manual.atom.io/behind-atom/sections/keymaps-in-depth/ # # If you're having trouble with your keybindings not working, try the # Keybinding Resolver: `Cmd+.` on OS X and `Ctrl+.` on other platforms. See the # Debugging Guide for more information: -# * https://atom.io/docs/latest/hacking-atom-debugging#check-the-keybindings +# * http://flight-manual.atom.io/hacking-atom/sections/debugging/#check-the-keybindings # # This file uses CoffeeScript Object Notation (CSON). # If you are unfamiliar with CSON, you can read more about it in the # Atom Flight Manual: -# https://atom.io/docs/latest/using-atom-basic-customization#cson +# http://flight-manual.atom.io/using-atom/sections/basic-customization/#_cson From b2aad098e118e6d1ba637a6088b1c831e5c0e402 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Sat, 16 Apr 2016 11:14:21 -0700 Subject: [PATCH 011/111] Correctly autoindent \r\n in Selection#insertText --- spec/selection-spec.coffee | 5 +++++ src/selection.coffee | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/selection-spec.coffee b/spec/selection-spec.coffee index 8830f4188..18095d6f8 100644 --- a/spec/selection-spec.coffee +++ b/spec/selection-spec.coffee @@ -96,3 +96,8 @@ describe "Selection", -> selection.setBufferRange [[2, 0], [3, 0]] selection.insertText("\n", autoIndent: true) expect(buffer.lineForRow(2)).toBe " " + + it "auto-indents if only a carriage return + newline is inserted", -> + selection.setBufferRange [[2, 0], [3, 0]] + selection.insertText("\r\n", autoIndent: true) + expect(buffer.lineForRow(2)).toBe " " diff --git a/src/selection.coffee b/src/selection.coffee index 8d93d2fa1..2937baaee 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -378,7 +378,8 @@ class Selection extends Model indentAdjustment = @editor.indentLevelForLine(precedingText) - options.indentBasis @adjustIndent(remainingLines, indentAdjustment) - if options.autoIndent and (text is '\n' or NonWhitespaceRegExp.test(text)) and not NonWhitespaceRegExp.test(precedingText) and remainingLines.length > 0 + textIsAutoIndentable = text is '\n' or text is '\r\n' or NonWhitespaceRegExp.test(text) + if options.autoIndent and textIsAutoIndentable and not NonWhitespaceRegExp.test(precedingText) and remainingLines.length > 0 autoIndentFirstLine = true firstLine = precedingText + firstInsertedLine desiredIndentLevel = @editor.languageMode.suggestedIndentForLineAtBufferRow(oldBufferRange.start.row, firstLine) From 92fd313a6ac5f19a52494139ec0921b6cff88d4c Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 18 Apr 2016 16:29:58 -0400 Subject: [PATCH 012/111] :arrow_up: language-gfm@0.86.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a44453cf0..b4b228009 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "language-coffee-script": "0.46.1", "language-csharp": "0.12.1", "language-css": "0.36.1", - "language-gfm": "0.85.0", + "language-gfm": "0.86.0", "language-git": "0.12.1", "language-go": "0.42.0", "language-html": "0.44.1", From 73f65fc8218bd5f16eabb602fc8228290308004c Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 18 Apr 2016 16:30:43 -0400 Subject: [PATCH 013/111] :arrow_up: language-xml@0.34.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b4b228009..ef5835306 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.4", + "language-xml": "0.34.5", "language-yaml": "0.25.2" }, "private": true, From ee4ca3fd6cd7cee084a9afb8f1e280a165394844 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 18 Apr 2016 16:32:20 -0400 Subject: [PATCH 014/111] :arrow_up: language-sql@0.21.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef5835306..128c40e43 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "language-sass": "0.46.0", "language-shellscript": "0.21.1", "language-source": "0.9.0", - "language-sql": "0.20.0", + "language-sql": "0.21.0", "language-text": "0.7.1", "language-todo": "0.27.0", "language-toml": "0.18.0", From 89bc3c888800711e0dbd3ca82d8b5c272d86d54d Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 18 Apr 2016 17:31:35 -0400 Subject: [PATCH 015/111] :arrow_up: language-git@0.13.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 128c40e43..4bad84f77 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "language-csharp": "0.12.1", "language-css": "0.36.1", "language-gfm": "0.86.0", - "language-git": "0.12.1", + "language-git": "0.13.0", "language-go": "0.42.0", "language-html": "0.44.1", "language-hyperlink": "0.16.0", From 8516f1914e676a3daf4d47ac7537a2c779aa49da Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Mon, 18 Apr 2016 15:20:18 -0700 Subject: [PATCH 016/111] :arrow_up: fuzzy-finder@1.0.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4bad84f77..1dc192378 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.38.1", - "fuzzy-finder": "1.0.4", + "fuzzy-finder": "1.0.5", "git-diff": "1.0.1", "find-and-replace": "0.198.0", "go-to-line": "0.30.0", From 53b516a6ec21b7f7e26b4577e1e3fd1759520eb5 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 18 Apr 2016 20:48:34 -0700 Subject: [PATCH 017/111] Quote spaces in paths on Win cmd line --- resources/win/atom.cmd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/win/atom.cmd b/resources/win/atom.cmd index a1af5cd53..8a4fed05c 100644 --- a/resources/win/atom.cmd +++ b/resources/win/atom.cmd @@ -2,6 +2,7 @@ SET EXPECT_OUTPUT= SET WAIT= +SET PSARGS=%* FOR %%a IN (%*) DO ( IF /I "%%a"=="-f" SET EXPECT_OUTPUT=YES @@ -25,7 +26,7 @@ FOR %%a IN (%*) DO ( IF "%EXPECT_OUTPUT%"=="YES" ( SET ELECTRON_ENABLE_LOGGING=YES IF "%WAIT%"=="YES" ( - powershell -noexit "%~dp0\..\..\atom.exe" --pid=$pid %* ; wait-event + powershell -noexit "Start-Process -FilePath \"%~dp0\..\..\atom.exe\" -ArgumentList \"--pid=$pid $env:PSARGS\" ; wait-event" ) ELSE ( "%~dp0\..\..\atom.exe" %* ) From 1500381ac9216bd533199f5b59460b5ac596527c Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Tue, 19 Apr 2016 14:25:44 -0700 Subject: [PATCH 018/111] Tweaks to the specs improvements from feedback --- spec/git-repository-async-spec.js | 2 +- spec/git-spec.coffee | 2 +- spec/spec-helper.coffee | 2 +- spec/text-editor-component-spec.js | 32 +++++++++++++++++++++++------- spec/theme-manager-spec.coffee | 8 ++++---- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 251734448..224280b39 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -103,7 +103,7 @@ describe('GitRepositoryAsync', () => { it('returns the repository path for a repository path', async () => { repo = openFixture('master.git') const repoPath = await repo.getPath() - expect(repoPath).toBePath(path.join(__dirname, 'fixtures', 'git', 'master.git')) + expect(repoPath).toEqualPath(path.join(__dirname, 'fixtures', 'git', 'master.git')) }) }) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 87aeab12a..7d9e9bbd4 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -33,7 +33,7 @@ describe "GitRepository", -> waitsForPromise -> repo.async.getPath().then(onSuccess) runs -> - expect(onSuccess.mostRecentCall.args[0]).toBePath(repoPath) + expect(onSuccess.mostRecentCall.args[0]).toEqualPath(repoPath) describe "new GitRepository(path)", -> it "throws an exception when no repository is found", -> diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 78a47ab0b..9c4e09da0 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -207,7 +207,7 @@ addCustomMatchers = (spec) -> @message = -> return "Expected element '#{element}' or its descendants #{toOrNotTo} show." element.style.display in ['block', 'inline-block', 'static', 'fixed'] - toBePath: (expected) -> + toEqualPath: (expected) -> actualPath = path.normalize(@actual) expectedPath = path.normalize(expected) @message = -> return "Expected path '#{actualPath}' to be equal to '#{expectedPath}'." diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index c1b2f8f46..1b3a7b5c8 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4022,15 +4022,33 @@ describe('TextEditorComponent', function () { }) }) - describe('when changing the font', async function () { - it('measures the default char, the korean char, the double width char and the half width char widths', async function () { - expect(editor.getDefaultCharWidth()).toBeCloseTo(12, 0) + describe('when decreasing the fontSize', async function () { + it('decreases the widths of the korean char, the double width char and the half width char', async function () { + originalDefaultCharWidth = editor.getDefaultCharWidth() + koreanDefaultCharWidth = editor.getKoreanCharWidth() + doubleWidthDefaultCharWidth = editor.getDoubleWidthCharWidth() + halfWidthDefaultCharWidth = editor.getHalfWidthCharWidth() component.setFontSize(10) await nextViewUpdatePromise() - expect(editor.getDefaultCharWidth()).toBeCloseTo(6, 0) - expect(editor.getKoreanCharWidth()).toBeCloseTo(10, 0) - expect(editor.getDoubleWidthCharWidth()).toBe(10) - expect(editor.getHalfWidthCharWidth()).toBeCloseTo(6, 5) + expect(editor.getDefaultCharWidth()).toBeLessThan(originalDefaultCharWidth) + expect(editor.getKoreanCharWidth()).toBeLessThan(koreanDefaultCharWidth) + expect(editor.getDoubleWidthCharWidth()).toBeLessThan(doubleWidthDefaultCharWidth) + expect(editor.getHalfWidthCharWidth()).toBeLessThan(halfWidthDefaultCharWidth) + }) + }) + + describe('when increasing the fontSize', function() { + it('increases the widths of the korean char, the double width char and the half width char', async function () { + originalDefaultCharWidth = editor.getDefaultCharWidth() + koreanDefaultCharWidth = editor.getKoreanCharWidth() + doubleWidthDefaultCharWidth = editor.getDoubleWidthCharWidth() + halfWidthDefaultCharWidth = editor.getHalfWidthCharWidth() + component.setFontSize(25) + await nextViewUpdatePromise() + expect(editor.getDefaultCharWidth()).toBeGreaterThan(originalDefaultCharWidth) + expect(editor.getKoreanCharWidth()).toBeGreaterThan(koreanDefaultCharWidth) + expect(editor.getDoubleWidthCharWidth()).toBeGreaterThan(doubleWidthDefaultCharWidth) + expect(editor.getHalfWidthCharWidth()).toBeGreaterThan(halfWidthDefaultCharWidth) }) }) diff --git a/spec/theme-manager-spec.coffee b/spec/theme-manager-spec.coffee index 0ab8a58b3..47b848809 100644 --- a/spec/theme-manager-spec.coffee +++ b/spec/theme-manager-spec.coffee @@ -175,7 +175,7 @@ describe "atom.themes", -> expect(styleElementAddedHandler).toHaveBeenCalled() element = document.querySelector('head style[source-path*="css.css"]') - expect(element.getAttribute('source-path')).toBePath atom.themes.stringToId(cssPath) + expect(element.getAttribute('source-path')).toEqualPath atom.themes.stringToId(cssPath) expect(element.textContent).toBe fs.readFileSync(cssPath, 'utf8') # doesn't append twice @@ -194,7 +194,7 @@ describe "atom.themes", -> expect(document.querySelectorAll('head style').length).toBe lengthBefore + 1 element = document.querySelector('head style[source-path*="sample.less"]') - expect(element.getAttribute('source-path')).toBePath atom.themes.stringToId(lessPath) + expect(element.getAttribute('source-path')).toEqualPath atom.themes.stringToId(lessPath) expect(element.textContent).toBe """ #header { color: #4d926f; @@ -213,9 +213,9 @@ describe "atom.themes", -> it "supports requiring css and less stylesheets without an explicit extension", -> atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'css') - expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toBePath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('css.css')) + expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toEqualPath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('css.css')) atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'sample') - expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toBePath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less')) + expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toEqualPath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less')) document.querySelector('head style[source-path*="css.css"]').remove() document.querySelector('head style[source-path*="sample.less"]').remove() From 405a16ecdc2e08ed1ce044a5c5992655ade2301e Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 19 Apr 2016 20:38:25 -0400 Subject: [PATCH 019/111] :arrow_up: language-java@0.18.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1dc192378..84ec5a36e 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "language-go": "0.42.0", "language-html": "0.44.1", "language-hyperlink": "0.16.0", - "language-java": "0.17.0", + "language-java": "0.18.0", "language-javascript": "0.110.0", "language-json": "0.18.0", "language-less": "0.29.3", From 9feb27e10775dca6f6722c5b1e7ddc771bd8086c Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 19 Apr 2016 20:39:24 -0400 Subject: [PATCH 020/111] :arrow_up: language-sass@0.47.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 84ec5a36e..7c9e37363 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "language-python": "0.43.1", "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", - "language-sass": "0.46.0", + "language-sass": "0.47.0", "language-shellscript": "0.21.1", "language-source": "0.9.0", "language-sql": "0.21.0", From 89a5d01968a6615558d15706ded86dec29652cdc Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 19 Apr 2016 20:40:12 -0400 Subject: [PATCH 021/111] :arrow_up: language-coffee-script@0.47.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c9e37363..436534d72 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "wrap-guide": "0.38.1", "language-c": "0.51.3", "language-clojure": "0.20.0", - "language-coffee-script": "0.46.1", + "language-coffee-script": "0.47.0", "language-csharp": "0.12.1", "language-css": "0.36.1", "language-gfm": "0.86.0", From 25895e1364c83325407213f545e513ac3b5d3a5a Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 19 Apr 2016 20:40:49 -0400 Subject: [PATCH 022/111] :arrow_up: language-yaml@0.26.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 436534d72..19cc758e7 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ "language-todo": "0.27.0", "language-toml": "0.18.0", "language-xml": "0.34.5", - "language-yaml": "0.25.2" + "language-yaml": "0.26.0" }, "private": true, "scripts": { From ea5ad4ae59833789ebbfb7d60e8d9c6a895284cc Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 19 Apr 2016 21:31:53 -0400 Subject: [PATCH 023/111] Coffeescript comment tokenization no longer matches the newline character --- spec/tokenized-buffer-spec.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 88c095f68..7a1f4d221 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -445,13 +445,12 @@ describe "TokenizedBuffer", -> expect(screenLine0.text).toBe "# Econ 101#{tabAsSpaces}" {tokens} = screenLine0 - expect(tokens.length).toBe 4 + expect(tokens.length).toBe 3 expect(tokens[0].value).toBe "#" expect(tokens[1].value).toBe " Econ 101" expect(tokens[2].value).toBe tabAsSpaces expect(tokens[2].scopes).toEqual tokens[1].scopes expect(tokens[2].isAtomic).toBeTruthy() - expect(tokens[3].value).toBe "" expect(tokenizedBuffer.tokenizedLineForRow(2).text).toBe "#{tabAsSpaces} buy()#{tabAsSpaces}while supply > demand" From 1e147fbaf161c27d4382f63b32303a6b2250321b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 20 Apr 2016 09:33:04 +0200 Subject: [PATCH 024/111] :arrow_up: about --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 19cc758e7..8fbc557d4 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "one-light-syntax": "1.2.0", "solarized-dark-syntax": "1.0.2", "solarized-light-syntax": "1.0.2", - "about": "1.5.0", + "about": "1.5.1", "archive-view": "0.61.1", "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.1", From 9ff5fb21fb0cccea293e43a36d3c04edd989df6c Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 20 Apr 2016 07:30:34 -0400 Subject: [PATCH 025/111] :arrow_up: language-make@0.22.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8fbc557d4..0cd63e918 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "language-javascript": "0.110.0", "language-json": "0.18.0", "language-less": "0.29.3", - "language-make": "0.21.1", + "language-make": "0.22.0", "language-mustache": "0.13.0", "language-objective-c": "0.15.1", "language-perl": "0.34.0", From 196bc53e6bef729c4925e0ae3789c3360def8dfd Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 20 Apr 2016 09:57:41 -0700 Subject: [PATCH 026/111] Ensure Windows Bash script works on all versions --- resources/win/atom.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/win/atom.sh b/resources/win/atom.sh index 7380bf122..cd90ff8fb 100644 --- a/resources/win/atom.sh +++ b/resources/win/atom.sh @@ -1,2 +1,5 @@ #!/bin/sh -$(dirname "$0")/atom.cmd "$@" +pushd $(dirname "$0") > /dev/null +ATOMCMD=""$(pwd -W)"/atom.cmd" +popd > /dev/null +cmd.exe //c "$ATOMCMD" "$@" From eb739cd025b7914b97a1476e1140f6866563c0b6 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 20 Apr 2016 12:40:45 -0700 Subject: [PATCH 027/111] Add `build-and-sign` grunt task for codesigning Atom --- build/Gruntfile.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index f8ee607e5..73279779c 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -298,6 +298,7 @@ module.exports = (grunt) -> unless process.platform is 'linux' or grunt.option('no-install') defaultTasks.push 'install' grunt.registerTask('default', defaultTasks) + grunt.registerTask('build-and-sign', ['download-electron', 'download-electron-chromedriver', 'build', 'set-version', 'generate-asar', 'codesign:app', 'install']) getDefaultChannelAndReleaseBranch = (version) -> if version.match(/dev/) or isBuildingPR() From aa96d471609e6c804222252ea13e3fd1fca3bfe3 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 21 Apr 2016 12:36:45 -0400 Subject: [PATCH 028/111] First pass --- package.json | 2 +- src/git-repository-async.js | 689 +++--------------------------------- 2 files changed, 46 insertions(+), 645 deletions(-) diff --git a/package.json b/package.json index 0cd63e918..3fa4a72d3 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,9 @@ "less-cache": "0.23", "line-top-index": "0.2.0", "marked": "^0.3.4", - "nodegit": "0.12.2", "normalize-package-data": "^2.0.0", "nslog": "^3", + "ohnogit": "0.0.8", "oniguruma": "^5", "pathwatcher": "~6.2", "property-accessors": "^1.1.3", diff --git a/src/git-repository-async.js b/src/git-repository-async.js index aacd482f7..6b91572d2 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -1,20 +1,7 @@ 'use babel' -import fs from 'fs-plus' -import path from 'path' -import Git from 'nodegit' -import ResourcePool from './resource-pool' -import {Emitter, CompositeDisposable, Disposable} from 'event-kit' - -const modifiedStatusFlags = Git.Status.STATUS.WT_MODIFIED | Git.Status.STATUS.INDEX_MODIFIED | Git.Status.STATUS.WT_DELETED | Git.Status.STATUS.INDEX_DELETED | Git.Status.STATUS.WT_TYPECHANGE | Git.Status.STATUS.INDEX_TYPECHANGE -const newStatusFlags = Git.Status.STATUS.WT_NEW | Git.Status.STATUS.INDEX_NEW -const deletedStatusFlags = Git.Status.STATUS.WT_DELETED | Git.Status.STATUS.INDEX_DELETED -const indexStatusFlags = Git.Status.STATUS.INDEX_NEW | Git.Status.STATUS.INDEX_MODIFIED | Git.Status.STATUS.INDEX_DELETED | Git.Status.STATUS.INDEX_RENAMED | Git.Status.STATUS.INDEX_TYPECHANGE -const ignoredStatusFlags = 1 << 14 // TODO: compose this from libgit2 constants -const submoduleMode = 57344 // TODO: compose this from libgit2 constants - -// Just using this for _.isEqual and _.object, we should impl our own here -import _ from 'underscore-plus' +import {Repository} from 'ohnogit' +import {CompositeDisposable, Disposable} from 'event-kit' // For the most part, this class behaves the same as `GitRepository`, with a few // notable differences: @@ -29,7 +16,7 @@ export default class GitRepositoryAsync { } static get Git () { - return Git + return Repository.Git } // The name of the error thrown when an action is attempted on a destroyed @@ -39,29 +26,9 @@ export default class GitRepositoryAsync { } constructor (_path, options = {}) { - // We'll serialize our access manually. - Git.setThreadSafetyStatus(Git.THREAD_SAFETY.DISABLED) + this.repo = Repository.open(_path, options) - this.emitter = new Emitter() this.subscriptions = new CompositeDisposable() - this.pathStatusCache = {} - this.path = null - - // NB: These needs to happen before the following .openRepository call. - this.openedPath = _path - this._openExactPath = options.openExactPath || false - - this.repoPromise = this.openRepository() - // NB: We don't currently _use_ the pooled object. But by giving it one - // thing, we're really just serializing all the work. Down the road, we - // could open multiple connections to the repository. - this.repoPool = new ResourcePool([this.repoPromise]) - - this.isCaseInsensitive = fs.isCaseInsensitive() - this.upstream = {} - this.submodules = {} - - this._refreshingPromise = Promise.resolve() let {refreshOnWindowFocus = true} = options if (refreshOnWindowFocus) { @@ -83,18 +50,12 @@ export default class GitRepositoryAsync { // This destroys any tasks and subscriptions and releases the underlying // libgit2 repository handle. This method is idempotent. destroy () { - if (this.emitter) { - this.emitter.emit('did-destroy') - this.emitter.dispose() - this.emitter = null - } + this.repo.destroy() if (this.subscriptions) { this.subscriptions.dispose() this.subscriptions = null } - - this.repoPromise = null } // Event subscription @@ -107,7 +68,7 @@ export default class GitRepositoryAsync { // // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. onDidDestroy (callback) { - return this.emitter.on('did-destroy', callback) + return this.repo.onDidDestroy(callback) } // Public: Invoke the given callback when a specific file's status has @@ -122,7 +83,7 @@ export default class GitRepositoryAsync { // // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. onDidChangeStatus (callback) { - return this.emitter.on('did-change-status', callback) + return this.repo.onDidChangeStatus(callback) } // Public: Invoke the given callback when a multiple files' statuses have @@ -134,7 +95,7 @@ export default class GitRepositoryAsync { // // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. onDidChangeStatuses (callback) { - return this.emitter.on('did-change-statuses', callback) + return this.repo.onDidChangeStatuses(callback) } // Repository details @@ -151,25 +112,13 @@ export default class GitRepositoryAsync { // Public: Returns a {Promise} which resolves to the {String} path of the // repository. getPath () { - return this.getRepo().then(repo => { - if (!this.path) { - this.path = repo.path().replace(/\/$/, '') - } - - return this.path - }) + return this.repo.getPath() } // Public: Returns a {Promise} which resolves to the {String} working // directory path of the repository. getWorkingDirectory (_path) { - return this.getRepo(_path).then(repo => { - if (!repo.cachedWorkdir) { - repo.cachedWorkdir = repo.workdir() - } - - return repo.cachedWorkdir - }) + return this.repo.getWorkingDirectory() } // Public: Returns a {Promise} that resolves to true if at the root, false if @@ -191,8 +140,7 @@ export default class GitRepositoryAsync { // // Returns a {Promise} which resolves to the relative {String} path. relativizeToWorkingDirectory (_path) { - return this.getWorkingDirectory() - .then(wd => this.relativize(_path, wd)) + return this.repo.relativizeToWorkingDirectory(_path) } // Public: Makes a path relative to the repository's working directory. @@ -202,78 +150,13 @@ export default class GitRepositoryAsync { // // Returns the relative {String} path. relativize (_path, workingDirectory) { - // The original implementation also handled null workingDirectory as it - // pulled it from a sync function that could return null. We require it - // to be passed here. - let openedWorkingDirectory - if (!_path || !workingDirectory) { - return _path - } - - // If the opened directory and the workdir differ, this is a symlinked repo - // root, so we have to do all the checks below twice--once against the realpath - // and one against the opened path - const opened = this.openedPath.replace(/\/\.git$/, '') - if (path.relative(opened, workingDirectory) !== '') { - openedWorkingDirectory = opened - } - - if (process.platform === 'win32') { - _path = _path.replace(/\\/g, '/') - } else { - if (_path[0] !== '/') { - return _path - } - } - - workingDirectory = workingDirectory.replace(/\/$/, '') - - // Depending on where the paths come from, they may have a '/private/' - // prefix. Standardize by stripping that out. - _path = _path.replace(/^\/private\//i, '/') - workingDirectory = workingDirectory.replace(/^\/private\//i, '/') - - const originalPath = _path - const originalWorkingDirectory = workingDirectory - if (this.isCaseInsensitive) { - _path = _path.toLowerCase() - workingDirectory = workingDirectory.toLowerCase() - } - - if (_path.indexOf(workingDirectory) === 0) { - return originalPath.substring(originalWorkingDirectory.length + 1) - } else if (_path === workingDirectory) { - return '' - } - - if (openedWorkingDirectory) { - openedWorkingDirectory = openedWorkingDirectory.replace(/\/$/, '') - openedWorkingDirectory = openedWorkingDirectory.replace(/^\/private\//i, '/') - - const originalOpenedWorkingDirectory = openedWorkingDirectory - if (this.isCaseInsensitive) { - openedWorkingDirectory = openedWorkingDirectory.toLowerCase() - } - - if (_path.indexOf(openedWorkingDirectory) === 0) { - return originalPath.substring(originalOpenedWorkingDirectory.length + 1) - } else if (_path === openedWorkingDirectory) { - return '' - } - } - - return _path + return this.repo.relativize(_path, workingDirectory) } // Public: Returns a {Promise} which resolves to whether the given branch // exists. hasBranch (branch) { - return this.repoPool.enqueue(() => { - return this.getRepo() - .then(repo => repo.getBranch(branch)) - .then(branch => branch != null) - .catch(_ => false) - }) + return this.repo.hasBranch(branch) } // Public: Retrieves a shortened version of the HEAD reference value. @@ -287,11 +170,7 @@ export default class GitRepositoryAsync { // // Returns a {Promise} which resolves to a {String}. getShortHead (_path) { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => repo.getCurrentBranch()) - .then(branch => branch.shorthand()) - }) + return this.repo.getShortHead(_path) } // Public: Is the given path a submodule in the repository? @@ -301,19 +180,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} that resolves true if the given path is a submodule in // the repository. isSubmodule (_path) { - return this.relativizeToWorkingDirectory(_path) - .then(relativePath => { - return this.repoPool.enqueue(() => { - return this.getRepo() - .then(repo => repo.index()) - .then(index => { - const entry = index.getByPath(relativePath) - if (!entry) return false - - return entry.mode === submoduleMode - }) - }) - }) + return this.repo.isSubmodule(_path) } // Public: Returns the number of commits behind the current branch is from the @@ -327,18 +194,7 @@ export default class GitRepositoryAsync { // * `ahead` The {Number} of commits ahead. // * `behind` The {Number} of commits behind. getAheadBehindCount (reference, _path) { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => Promise.all([repo, repo.getBranch(reference)])) - .then(([repo, local]) => { - const upstream = Git.Branch.upstream(local) - return Promise.all([repo, local, upstream]) - }) - .then(([repo, local, upstream]) => { - return Git.Graph.aheadBehind(repo, local.target(), upstream.target()) - }) - .catch(_ => ({ahead: 0, behind: 0})) - }) + return this.repo.getAheadBehindCount(reference, _path) } // Public: Get the cached ahead/behind commit counts for the current branch's @@ -351,15 +207,7 @@ export default class GitRepositoryAsync { // * `ahead` The {Number} of commits ahead. // * `behind` The {Number} of commits behind. getCachedUpstreamAheadBehindCount (_path) { - return this.relativizeToWorkingDirectory(_path) - .then(relativePath => this._submoduleForPath(_path)) - .then(submodule => { - if (submodule) { - return submodule.getCachedUpstreamAheadBehindCount(_path) - } else { - return this.upstream - } - }) + return this.repo.getCachedUpstreamAheadBehindCount(_path) } // Public: Returns the git configuration value specified by the key. @@ -370,12 +218,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to the {String} git configuration value // specified by the key. getConfigValue (key, _path) { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => repo.configSnapshot()) - .then(config => config.getStringBuf(key)) - .catch(_ => null) - }) + return this.repo.getConfigValue(key, _path) } // Public: Get the URL for the 'origin' remote. @@ -386,7 +229,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to the {String} origin url of the // repository. getOriginURL (_path) { - return this.getConfigValue('remote.origin.url', _path) + return this.repo.getOriginalURL(_path) } // Public: Returns the upstream branch for the current HEAD, or null if there @@ -398,11 +241,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to a {String} branch name such as // `refs/remotes/origin/master`. getUpstreamBranch (_path) { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => repo.getCurrentBranch()) - .then(branch => Git.Branch.upstream(branch)) - }) + return this.getUpstreamBranch(_path) } // Public: Gets all the local and remote references. @@ -415,25 +254,7 @@ export default class GitRepositoryAsync { // * `remotes` An {Array} of remote reference names. // * `tags` An {Array} of tag reference names. getReferences (_path) { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => repo.getReferences(Git.Reference.TYPE.LISTALL)) - .then(refs => { - const heads = [] - const remotes = [] - const tags = [] - for (const ref of refs) { - if (ref.isTag()) { - tags.push(ref.name()) - } else if (ref.isRemote()) { - remotes.push(ref.name()) - } else if (ref.isBranch()) { - heads.push(ref.name()) - } - } - return {heads, remotes, tags} - }) - }) + return this.repo.getReferences(_path) } // Public: Get the SHA for the given reference. @@ -445,11 +266,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to the current {String} SHA for the // given reference. getReferenceTarget (reference, _path) { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => Git.Reference.nameToId(repo, reference)) - .then(oid => oid.tostrS()) - }) + return this.repo.getReferenceTarget(reference, _path) } // Reading Status @@ -462,9 +279,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to a {Boolean} that's true if the `path` // is modified. isPathModified (_path) { - return this.relativizeToWorkingDirectory(_path) - .then(relativePath => this._getStatus([relativePath])) - .then(statuses => statuses.some(status => status.isModified())) + return this.repo.isPathModified(_path) } // Public: Resolves true if the given path is new. @@ -474,9 +289,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to a {Boolean} that's true if the `path` // is new. isPathNew (_path) { - return this.relativizeToWorkingDirectory(_path) - .then(relativePath => this._getStatus([relativePath])) - .then(statuses => statuses.some(status => status.isNew())) + return this.repo.isPathNew(_path) } // Public: Is the given path ignored? @@ -486,17 +299,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to a {Boolean} that's true if the `path` // is ignored. isPathIgnored (_path) { - return this.getWorkingDirectory() - .then(wd => { - return this.repoPool.enqueue(() => { - return this.getRepo() - .then(repo => { - const relativePath = this.relativize(_path, wd) - return Git.Ignore.pathIsIgnored(repo, relativePath) - }) - .then(ignored => Boolean(ignored)) - }) - }) + return this.repo.isPathIgnored(_path) } // Get the status of a directory in the repository's working directory. @@ -507,18 +310,7 @@ export default class GitRepositoryAsync { // value can be passed to {::isStatusModified} or {::isStatusNew} to get more // information. getDirectoryStatus (directoryPath) { - return this.relativizeToWorkingDirectory(directoryPath) - .then(relativePath => { - const pathspec = relativePath + '/**' - return this._getStatus([pathspec]) - }) - .then(statuses => { - return Promise.all(statuses.map(s => s.statusBit())).then(bits => { - return bits - .filter(b => b > 0) - .reduce((status, bit) => status | bit, 0) - }) - }) + return this.repo.getDirectoryStatus(directoryPath) } // Refresh the status bit for the given path. @@ -531,27 +323,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to a {Number} which is the refreshed // status bit for the path. refreshStatusForPath (_path) { - let relativePath - return this.getWorkingDirectory() - .then(wd => { - relativePath = this.relativize(_path, wd) - return this._getStatus([relativePath]) - }) - .then(statuses => { - const cachedStatus = this.pathStatusCache[relativePath] || 0 - const status = statuses[0] ? statuses[0].statusBit() : Git.Status.STATUS.CURRENT - if (status !== cachedStatus) { - if (status === Git.Status.STATUS.CURRENT) { - delete this.pathStatusCache[relativePath] - } else { - this.pathStatusCache[relativePath] = status - } - - this.emitter.emit('did-change-status', {path: _path, pathStatus: status}) - } - - return status - }) + return this.repo.refreshStatusForPath(_path) } // Returns a Promise that resolves to the status bit of a given path if it has @@ -567,8 +339,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to a status {Number} or null if the // path is not in the cache. getCachedPathStatus (_path) { - return this.relativizeToWorkingDirectory(_path) - .then(relativePath => this.pathStatusCache[relativePath]) + return this.repo.getCachedPathStatus(_path) } // Public: Get the cached statuses for the repository. @@ -576,7 +347,7 @@ export default class GitRepositoryAsync { // Returns an {Object} of {Number} statuses, keyed by {String} working // directory-relative file names. getCachedPathStatuses () { - return this.pathStatusCache + return this.repo.pathStatusCache } // Public: Returns true if the given status indicates modification. @@ -585,7 +356,7 @@ export default class GitRepositoryAsync { // // Returns a {Boolean} that's true if the `statusBit` indicates modification. isStatusModified (statusBit) { - return (statusBit & modifiedStatusFlags) > 0 + return this.repo.isStatusModified(statusBit) } // Public: Returns true if the given status indicates a new path. @@ -594,7 +365,7 @@ export default class GitRepositoryAsync { // // Returns a {Boolean} that's true if the `statusBit` indicates a new path. isStatusNew (statusBit) { - return (statusBit & newStatusFlags) > 0 + return this.repo.isStatusNew(statusBit) } // Public: Returns true if the given status indicates the path is staged. @@ -604,7 +375,7 @@ export default class GitRepositoryAsync { // Returns a {Boolean} that's true if the `statusBit` indicates the path is // staged. isStatusStaged (statusBit) { - return (statusBit & indexStatusFlags) > 0 + return this.repo.isStatusStaged(statusBit) } // Public: Returns true if the given status indicates the path is ignored. @@ -614,7 +385,7 @@ export default class GitRepositoryAsync { // Returns a {Boolean} that's true if the `statusBit` indicates the path is // ignored. isStatusIgnored (statusBit) { - return (statusBit & ignoredStatusFlags) > 0 + return this.repo.isStatusIgnored(statusBit) } // Public: Returns true if the given status indicates the path is deleted. @@ -624,7 +395,7 @@ export default class GitRepositoryAsync { // Returns a {Boolean} that's true if the `statusBit` indicates the path is // deleted. isStatusDeleted (statusBit) { - return (statusBit & deletedStatusFlags) > 0 + return this.repo.isStatusDeleted(statusBit) } // Retrieving Diffs @@ -640,40 +411,7 @@ export default class GitRepositoryAsync { // * `added` The {Number} of added lines. // * `deleted` The {Number} of deleted lines. getDiffStats (_path) { - return this.getWorkingDirectory(_path) - .then(wd => { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => Promise.all([repo, repo.getHeadCommit()])) - .then(([repo, headCommit]) => Promise.all([repo, headCommit.getTree()])) - .then(([repo, tree]) => { - const options = new Git.DiffOptions() - options.contextLines = 0 - options.flags = Git.Diff.OPTION.DISABLE_PATHSPEC_MATCH - options.pathspec = this.relativize(_path, wd) - if (process.platform === 'win32') { - // Ignore eol of line differences on windows so that files checked in - // as LF don't report every line modified when the text contains CRLF - // endings. - options.flags |= Git.Diff.OPTION.IGNORE_WHITESPACE_EOL - } - return Git.Diff.treeToWorkdir(repo, tree, options) - }) - .then(diff => this._getDiffLines(diff)) - .then(lines => { - const stats = {added: 0, deleted: 0} - for (const line of lines) { - const origin = line.origin() - if (origin === Git.Diff.LINE.ADDITION) { - stats.added++ - } else if (origin === Git.Diff.LINE.DELETION) { - stats.deleted++ - } - } - return stats - }) - }) - }) + return this.repo.getDiffStats(_path) } // Public: Retrieves the line diffs comparing the `HEAD` version of the given @@ -688,30 +426,7 @@ export default class GitRepositoryAsync { // * `oldLines` The {Number} of lines in the old hunk. // * `newLines` The {Number} of lines in the new hunk getLineDiffs (_path, text) { - return this.getWorkingDirectory(_path) - .then(wd => { - let relativePath = null - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => { - relativePath = this.relativize(_path, wd) - return repo.getHeadCommit() - }) - .then(commit => commit.getEntry(relativePath)) - .then(entry => entry.getBlob()) - .then(blob => { - const options = new Git.DiffOptions() - options.contextLines = 0 - if (process.platform === 'win32') { - // Ignore eol of line differences on windows so that files checked in - // as LF don't report every line modified when the text contains CRLF - // endings. - options.flags = Git.Diff.OPTION.IGNORE_WHITESPACE_EOL - } - return this._diffBlobToBuffer(blob, text, options) - }) - }) - }) + return this.repo.getLineDiffs(_path, text) } // Checking Out @@ -732,19 +447,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} that resolves or rejects depending on whether the // method was successful. checkoutHead (_path) { - return this.getWorkingDirectory(_path) - .then(wd => { - return this.repoPool.enqueue(() => { - return this.getRepo(_path) - .then(repo => { - const checkoutOptions = new Git.CheckoutOptions() - checkoutOptions.paths = [this.relativize(_path, wd)] - checkoutOptions.checkoutStrategy = Git.Checkout.STRATEGY.FORCE | Git.Checkout.STRATEGY.DISABLE_PATHSPEC_MATCH - return Git.Checkout.head(repo, checkoutOptions) - }) - }) - }) - .then(() => this.refreshStatusForPath(_path)) + return this.repo.checkoutHead(_path) } // Public: Checks out a branch in your repository. @@ -755,19 +458,7 @@ export default class GitRepositoryAsync { // // Returns a {Promise} that resolves if the method was successful. checkoutReference (reference, create) { - return this.repoPool.enqueue(() => { - return this.getRepo() - .then(repo => repo.checkoutBranch(reference)) - }) - .catch(error => { - if (create) { - return this._createBranch(reference) - .then(_ => this.checkoutReference(reference, false)) - } else { - throw error - } - }) - .then(_ => null) + return this.repo.checkoutReference(reference, create) } // Private @@ -786,107 +477,10 @@ export default class GitRepositoryAsync { return this.checkoutHead(filePath) } - // Create a new branch with the given name. + // Refreshes the git status. // - // * `name` The {String} name of the new branch. - // - // Returns a {Promise} which resolves to a {NodeGit.Ref} reference to the - // created branch. - _createBranch (name) { - return this.repoPool.enqueue(() => { - return this.getRepo() - .then(repo => Promise.all([repo, repo.getHeadCommit()])) - .then(([repo, commit]) => repo.createBranch(name, commit)) - }) - } - - // Get all the hunks in the diff. - // - // * `diff` The {NodeGit.Diff} whose hunks should be retrieved. - // - // Returns a {Promise} which resolves to an {Array} of {NodeGit.Hunk}. - _getDiffHunks (diff) { - return diff.patches() - .then(patches => Promise.all(patches.map(p => p.hunks()))) // patches :: Array - .then(hunks => _.flatten(hunks)) // hunks :: Array> - } - - // Get all the lines contained in the diff. - // - // * `diff` The {NodeGit.Diff} use lines should be retrieved. - // - // Returns a {Promise} which resolves to an {Array} of {NodeGit.Line}. - _getDiffLines (diff) { - return this._getDiffHunks(diff) - .then(hunks => Promise.all(hunks.map(h => h.lines()))) - .then(lines => _.flatten(lines)) // lines :: Array> - } - - // Diff the given blob and buffer with the provided options. - // - // * `blob` The {NodeGit.Blob} - // * `buffer` The {String} buffer. - // * `options` The {NodeGit.DiffOptions} - // - // Returns a {Promise} which resolves to an {Array} of {Object}s which have - // the following keys: - // * `oldStart` The {Number} of the old starting line. - // * `newStart` The {Number} of the new starting line. - // * `oldLines` The {Number} of old lines. - // * `newLines` The {Number} of new lines. - _diffBlobToBuffer (blob, buffer, options) { - const hunks = [] - const hunkCallback = (delta, hunk, payload) => { - hunks.push({ - oldStart: hunk.oldStart(), - newStart: hunk.newStart(), - oldLines: hunk.oldLines(), - newLines: hunk.newLines() - }) - } - - return Git.Diff.blobToBuffer(blob, null, buffer, null, options, null, null, hunkCallback, null) - .then(_ => hunks) - } - - // Get the current branch and update this.branch. - // - // Returns a {Promise} which resolves to a {boolean} indicating whether the - // branch name changed. - _refreshBranch () { - return this.repoPool.enqueue(() => { - return this.getRepo() - .then(repo => repo.getCurrentBranch()) - .then(ref => ref.name()) - .then(branchName => { - const changed = branchName !== this.branch - this.branch = branchName - return changed - }) - }) - } - - // Refresh the cached ahead/behind count with the given branch. - // - // * `branchName` The {String} name of the branch whose ahead/behind should be - // used for the refresh. - // - // Returns a {Promise} which will resolve to a {boolean} indicating whether - // the ahead/behind count changed. - _refreshAheadBehindCount (branchName) { - return this.getAheadBehindCount(branchName) - .then(counts => { - const changed = !_.isEqual(counts, this.upstream) - this.upstream = counts - return changed - }) - } - - // Get the status for this repository. - // - // Returns a {Promise} that will resolve to an object of {String} paths to the - // {Number} status. - _getRepositoryStatus () { + // Returns a {Promise} which will resolve to {null} when refresh is complete. + refreshStatus () { let projectPathsPromises = [Promise.resolve('')] if (this.project) { projectPathsPromises = this.project.getPaths() @@ -895,163 +489,7 @@ export default class GitRepositoryAsync { return Promise.all(projectPathsPromises) .then(paths => paths.map(p => p.length > 0 ? p + '/**' : '*')) - .then(projectPaths => { - return this._getStatus(projectPaths.length > 0 ? projectPaths : null) - }) - .then(statuses => { - const statusPairs = statuses.map(status => [status.path(), status.statusBit()]) - return _.object(statusPairs) - }) - } - - // Get the status for the given submodule. - // - // * `submodule` The {GitRepositoryAsync} for the submodule. - // - // Returns a {Promise} which resolves to an {Object}, keyed by {String} - // repo-relative {Number} statuses. - async _getSubmoduleStatus (submodule) { - // At this point, we've called submodule._refreshSubmodules(), which would - // have refreshed the status on *its* submodules, etc. So we know that its - // cached path statuses are up-to-date. - // - // Now we just need to hoist those statuses into our repository by changing - // their paths to be relative to us. - - const statuses = submodule.getCachedPathStatuses() - const repoRelativeStatuses = {} - const submoduleRepo = await submodule.getRepo() - const submoduleWorkDir = submoduleRepo.workdir() - for (const relativePath in statuses) { - const statusBit = statuses[relativePath] - const absolutePath = path.join(submoduleWorkDir, relativePath) - const repoRelativePath = await this.relativizeToWorkingDirectory(absolutePath) - repoRelativeStatuses[repoRelativePath] = statusBit - } - - return repoRelativeStatuses - } - - // Refresh the list of submodules in the repository. - // - // Returns a {Promise} which resolves to an {Object} keyed by {String} - // submodule names with {GitRepositoryAsync} values. - async _refreshSubmodules () { - const repo = await this.getRepo() - const wd = await this.getWorkingDirectory() - const submoduleNames = await repo.getSubmoduleNames() - for (const name of submoduleNames) { - const alreadyExists = Boolean(this.submodules[name]) - if (alreadyExists) continue - - const submodule = await Git.Submodule.lookup(repo, name) - const absolutePath = path.join(wd, submodule.path()) - const submoduleRepo = GitRepositoryAsync.open(absolutePath, {openExactPath: true, refreshOnWindowFocus: false}) - this.submodules[name] = submoduleRepo - } - - for (const name in this.submodules) { - const repo = this.submodules[name] - const gone = submoduleNames.indexOf(name) < 0 - if (gone) { - repo.destroy() - delete this.submodules[name] - } else { - try { - await repo.refreshStatus() - } catch (e) { - // libgit2 will sometimes report submodules that aren't actually valid - // (https://github.com/libgit2/libgit2/issues/3580). So check the - // validity of the submodules by removing any that fail. - repo.destroy() - delete this.submodules[name] - } - } - } - - return _.values(this.submodules) - } - - // Get the status for the submodules in the repository. - // - // Returns a {Promise} that will resolve to an object of {String} paths to the - // {Number} status. - _getSubmoduleStatuses () { - return this._refreshSubmodules() - .then(repos => { - return Promise.all(repos.map(repo => this._getSubmoduleStatus(repo))) - }) - .then(statuses => _.extend({}, ...statuses)) - } - - // Refresh the cached status. - // - // Returns a {Promise} which will resolve to a {boolean} indicating whether - // any statuses changed. - _refreshStatus () { - return Promise.all([this._getRepositoryStatus(), this._getSubmoduleStatuses()]) - .then(([repositoryStatus, submoduleStatus]) => { - const statusesByPath = _.extend({}, repositoryStatus, submoduleStatus) - const changed = !_.isEqual(this.pathStatusCache, statusesByPath) - this.pathStatusCache = statusesByPath - return changed - }) - } - - // Refreshes the git status. - // - // Returns a {Promise} which will resolve to {null} when refresh is complete. - refreshStatus () { - const status = this._refreshStatus() - const branch = this._refreshBranch() - const aheadBehind = branch.then(() => this._refreshAheadBehindCount(this.branch)) - - this._refreshingPromise = this._refreshingPromise.then(_ => { - return Promise.all([status, branch, aheadBehind]) - .then(([statusChanged, branchChanged, aheadBehindChanged]) => { - if (this.emitter && (statusChanged || branchChanged || aheadBehindChanged)) { - this.emitter.emit('did-change-statuses') - } - - return null - }) - // Because all these refresh steps happen asynchronously, it's entirely - // possible the repository was destroyed while we were working. In which - // case we should just swallow the error. - .catch(e => { - if (this._isDestroyed()) { - return null - } else { - return Promise.reject(e) - } - }) - .catch(e => { - console.error('Error refreshing repository status:') - console.error(e) - return Promise.reject(e) - }) - }) - return this._refreshingPromise - } - - // Get the submodule for the given path. - // - // Returns a {Promise} which resolves to the {GitRepositoryAsync} submodule or - // null if it isn't a submodule path. - async _submoduleForPath (_path) { - let relativePath = await this.relativizeToWorkingDirectory(_path) - for (const submodulePath in this.submodules) { - const submoduleRepo = this.submodules[submodulePath] - if (relativePath === submodulePath) { - return submoduleRepo - } else if (relativePath.indexOf(`${submodulePath}/`) === 0) { - relativePath = relativePath.substring(submodulePath.length + 1) - const innerSubmodule = await submoduleRepo._submoduleForPath(relativePath) - return innerSubmodule || submoduleRepo - } - } - - return null + .then(pathspecs => this.repo.refreshStatus(pathspecs)) } // Get the NodeGit repository for the given path. @@ -1062,16 +500,7 @@ export default class GitRepositoryAsync { // // Returns a {Promise} which resolves to the {NodeGit.Repository}. getRepo (_path) { - if (this._isDestroyed()) { - const error = new Error('Repository has been destroyed') - error.name = GitRepositoryAsync.DestroyedErrorName - return Promise.reject(error) - } - - if (!_path) return this.repoPromise - - return this._submoduleForPath(_path) - .then(submodule => submodule ? submodule.getRepo() : this.repoPromise) + return this.repo.getRepo(_path) } // Open a new instance of the underlying {NodeGit.Repository}. @@ -1081,11 +510,7 @@ export default class GitRepositoryAsync { // // Returns the new {NodeGit.Repository}. openRepository () { - if (this._openExactPath) { - return Git.Repository.open(this.openedPath) - } else { - return Git.Repository.openExt(this.openedPath, 0, '') - } + return this.repo.openRepository() } // Section: Private @@ -1095,7 +520,7 @@ export default class GitRepositoryAsync { // // Returns a {Boolean}. _isDestroyed () { - return this.repoPromise == null + return this.repo._isDestroyed() } // Subscribe to events on the given buffer. @@ -1121,28 +546,4 @@ export default class GitRepositoryAsync { this.subscriptions.add(bufferSubscriptions) } - - // Get the status for the given paths. - // - // * `paths` The {String} paths whose status is wanted. If undefined, get the - // status for the whole repository. - // - // Returns a {Promise} which resolves to an {Array} of {NodeGit.StatusFile} - // statuses for the paths. - _getStatus (paths) { - return this.repoPool.enqueue(() => { - return this.getRepo() - .then(repo => { - const opts = { - flags: Git.Status.OPT.INCLUDE_UNTRACKED | Git.Status.OPT.RECURSE_UNTRACKED_DIRS - } - - if (paths) { - opts.pathspec = paths - } - - return repo.getStatusExt(opts) - }) - }) - } } From ea57a25a3fd865be35c053710ba0b75d4bf85bc2 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 21 Apr 2016 13:08:10 -0400 Subject: [PATCH 029/111] :arrow_up: ohnogit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3fa4a72d3..d50a888ed 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "marked": "^0.3.4", "normalize-package-data": "^2.0.0", "nslog": "^3", - "ohnogit": "0.0.8", + "ohnogit": "0.0.9", "oniguruma": "^5", "pathwatcher": "~6.2", "property-accessors": "^1.1.3", From 809d194f316e0a966a8d13c38ff57d8ec94d6f9a Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 21 Apr 2016 13:17:35 -0400 Subject: [PATCH 030/111] Update the tests --- spec/git-repository-async-spec.js | 11 +++++------ src/git-repository-async.js | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 224280b39..d36b9fd58 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -3,7 +3,6 @@ import fs from 'fs-plus' import path from 'path' import temp from 'temp' -import Git from 'nodegit' import {it, beforeEach, afterEach} from './async-spec-helpers' @@ -47,7 +46,7 @@ describe('GitRepositoryAsync', () => { let threw = false try { - await repo.repoPromise + await repo.getRepo() } catch (e) { threw = true } @@ -64,19 +63,19 @@ describe('GitRepositoryAsync', () => { }) it('returns the repository when not given a path', async () => { - const nodeGitRepo1 = await repo.repoPromise + const nodeGitRepo1 = await repo.getRepo() const nodeGitRepo2 = await repo.getRepo() expect(nodeGitRepo1.workdir()).toBe(nodeGitRepo2.workdir()) }) it('returns the repository when given a non-submodule path', async () => { - const nodeGitRepo1 = await repo.repoPromise + const nodeGitRepo1 = await repo.getRepo() const nodeGitRepo2 = await repo.getRepo('README') expect(nodeGitRepo1.workdir()).toBe(nodeGitRepo2.workdir()) }) it('returns the submodule repository when given a submodule path', async () => { - const nodeGitRepo1 = await repo.repoPromise + const nodeGitRepo1 = await repo.getRepo() const nodeGitRepo2 = await repo.getRepo('jstips') expect(nodeGitRepo1.workdir()).not.toBe(nodeGitRepo2.workdir()) @@ -303,7 +302,7 @@ describe('GitRepositoryAsync', () => { await repo.getPathStatus(filePath) expect(statusHandler.callCount).toBe(1) - const status = Git.Status.STATUS.WT_MODIFIED + const status = GitRepositoryAsync.Git.Status.STATUS.WT_MODIFIED expect(statusHandler.argsForCall[0][0]).toEqual({path: filePath, pathStatus: status}) fs.writeFileSync(filePath, 'abc') diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 6b91572d2..8201b6f6f 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -22,7 +22,7 @@ export default class GitRepositoryAsync { // The name of the error thrown when an action is attempted on a destroyed // repository. static get DestroyedErrorName () { - return 'GitRepositoryAsync.destroyed' + return Repository.DestroyedErrorName } constructor (_path, options = {}) { From 866a26a754ad87b2977a5ac27ed4a01be82b2c7c Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 21 Apr 2016 13:25:14 -0400 Subject: [PATCH 031/111] Update the ignore paths for ohnogit. --- build/tasks/build-task.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee index 9164f8dab..544b09753 100644 --- a/build/tasks/build-task.coffee +++ b/build/tasks/build-task.coffee @@ -54,9 +54,9 @@ module.exports = (grunt) -> # so that it doesn't becomes larger than it needs to be. ignoredPaths = [ path.join('git-utils', 'deps') - path.join('nodegit', 'vendor') - path.join('nodegit', 'node_modules', 'node-pre-gyp') - path.join('nodegit', 'node_modules', '.bin') + path.join('ohnogit', 'node_modules', 'nodegit', 'vendor') + path.join('ohnogit', 'node_modules', 'nodegit', 'node_modules', 'node-pre-gyp') + path.join('ohnogit', 'node_modules', 'nodegit', 'node_modules', '.bin') path.join('oniguruma', 'deps') path.join('less', 'dist') path.join('bootstrap', 'docs') @@ -122,9 +122,9 @@ module.exports = (grunt) -> # Ignore *.cc and *.h files from native modules ignoredPaths.push "#{_.escapeRegExp(path.join('ctags', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{_.escapeRegExp(path.join('git-utils', 'src') + path.sep)}.*\\.(cc|h)*" - ignoredPaths.push "#{_.escapeRegExp(path.join('nodegit', 'src') + path.sep)}.*\\.(cc|h)?" - ignoredPaths.push "#{_.escapeRegExp(path.join('nodegit', 'generate') + path.sep)}.*\\.(cc|h)?" - ignoredPaths.push "#{_.escapeRegExp(path.join('nodegit', 'include') + path.sep)}.*\\.(cc|h)?" + ignoredPaths.push "#{_.escapeRegExp(path.join('ohnogit', 'node_modules', 'nodegit', 'src') + path.sep)}.*\\.(cc|h)?" + ignoredPaths.push "#{_.escapeRegExp(path.join('ohnogit', 'node_modules', 'nodegit', 'generate') + path.sep)}.*\\.(cc|h)?" + ignoredPaths.push "#{_.escapeRegExp(path.join('ohnogit', 'node_modules', 'nodegit', 'include') + path.sep)}.*\\.(cc|h)?" ignoredPaths.push "#{_.escapeRegExp(path.join('keytar', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{_.escapeRegExp(path.join('nslog', 'src') + path.sep)}.*\\.(cc|h)*" ignoredPaths.push "#{_.escapeRegExp(path.join('oniguruma', 'src') + path.sep)}.*\\.(cc|h)*" From c0eb8baae0c16a0cd015f5bfa4a2a2b0c501f486 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 21 Apr 2016 13:55:43 -0400 Subject: [PATCH 032/111] Provide _refreshingPromise. --- src/git-repository-async.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 8201b6f6f..37131dd24 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -45,6 +45,11 @@ export default class GitRepositoryAsync { } } + // This exists to provide backwards compatibility. + get _refreshingPromise () { + return this.repo._refreshingPromise + } + // Public: Destroy this {GitRepositoryAsync} object. // // This destroys any tasks and subscriptions and releases the underlying From 3574613fa32242ef72016785f2333d9dc5d1ce4c Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 21 Apr 2016 14:19:24 -0400 Subject: [PATCH 033/111] Don't need resource pool anymore. --- spec/resource-pool-spec.js | 66 -------------------------------------- src/resource-pool.js | 57 -------------------------------- 2 files changed, 123 deletions(-) delete mode 100644 spec/resource-pool-spec.js delete mode 100644 src/resource-pool.js diff --git a/spec/resource-pool-spec.js b/spec/resource-pool-spec.js deleted file mode 100644 index 27893360a..000000000 --- a/spec/resource-pool-spec.js +++ /dev/null @@ -1,66 +0,0 @@ -/** @babel */ - -import ResourcePool from '../src/resource-pool' - -import {it} from './async-spec-helpers' - -describe('ResourcePool', () => { - let queue - - beforeEach(() => { - queue = new ResourcePool([{}]) - }) - - describe('.enqueue', () => { - it('calls the enqueued function', async () => { - let called = false - await queue.enqueue(() => { - called = true - return Promise.resolve() - }) - expect(called).toBe(true) - }) - - it('forwards values from the inner promise', async () => { - const result = await queue.enqueue(() => Promise.resolve(42)) - expect(result).toBe(42) - }) - - it('forwards errors from the inner promise', async () => { - let threw = false - try { - await queue.enqueue(() => Promise.reject(new Error('down with the sickness'))) - } catch (e) { - threw = true - } - expect(threw).toBe(true) - }) - - it('continues to dequeue work after a promise has been rejected', async () => { - try { - await queue.enqueue(() => Promise.reject(new Error('down with the sickness'))) - } catch (e) {} - - const result = await queue.enqueue(() => Promise.resolve(42)) - expect(result).toBe(42) - }) - - it('queues up work', async () => { - let resolve = null - queue.enqueue(() => { - return new Promise((resolve_, reject) => { - resolve = resolve_ - }) - }) - - expect(queue.getQueueDepth()).toBe(0) - - queue.enqueue(() => new Promise((resolve, reject) => {})) - - expect(queue.getQueueDepth()).toBe(1) - resolve() - - waitsFor(() => queue.getQueueDepth() === 0) - }) - }) -}) diff --git a/src/resource-pool.js b/src/resource-pool.js deleted file mode 100644 index ae7cb71d0..000000000 --- a/src/resource-pool.js +++ /dev/null @@ -1,57 +0,0 @@ -/** @babel */ - -// Manages a pool of some resource. -export default class ResourcePool { - constructor (pool) { - this.pool = pool - - this.queue = [] - } - - // Enqueue the given function. The function will be given an object from the - // pool. The function must return a {Promise}. - enqueue (fn) { - let resolve = null - let reject = null - const wrapperPromise = new Promise((resolve_, reject_) => { - resolve = resolve_ - reject = reject_ - }) - - this.queue.push(this.wrapFunction(fn, resolve, reject)) - - this.dequeueIfAble() - - return wrapperPromise - } - - wrapFunction (fn, resolve, reject) { - return (resource) => { - const promise = fn(resource) - promise - .then(result => { - resolve(result) - this.taskDidComplete(resource) - }, error => { - reject(error) - this.taskDidComplete(resource) - }) - } - } - - taskDidComplete (resource) { - this.pool.push(resource) - - this.dequeueIfAble() - } - - dequeueIfAble () { - if (!this.pool.length || !this.queue.length) return - - const fn = this.queue.shift() - const resource = this.pool.shift() - fn(resource) - } - - getQueueDepth () { return this.queue.length } -} From 4a0c9467854016c6ee20e8906e9b9c9dceb3179c Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 21 Apr 2016 15:29:50 -0400 Subject: [PATCH 034/111] :arrow_up: status-bar@1.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d50a888ed..a9a5314fd 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "settings-view": "0.235.1", "snippets": "1.0.2", "spell-check": "0.67.1", - "status-bar": "1.2.3", + "status-bar": "1.2.4", "styleguide": "0.45.2", "symbols-view": "0.112.0", "tabs": "0.92.2", From 53c52342e5eac36a3dbe6020c3798b6ffb535289 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 21 Apr 2016 13:36:50 -0700 Subject: [PATCH 035/111] Add Ctrl+F4 keybinding for Linux --- keymaps/linux.cson | 1 + 1 file changed, 1 insertion(+) diff --git a/keymaps/linux.cson b/keymaps/linux.cson index 7d67e2ce5..1f78739a9 100644 --- a/keymaps/linux.cson +++ b/keymaps/linux.cson @@ -27,6 +27,7 @@ 'ctrl-n': 'application:new-file' 'ctrl-s': 'core:save' 'ctrl-S': 'core:save-as' + 'ctrl-f4': 'core:close' 'ctrl-w': 'core:close' 'ctrl-z': 'core:undo' 'ctrl-y': 'core:redo' From d276f93a233423375496da79682afa838387bc75 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Apr 2016 11:12:15 +0200 Subject: [PATCH 036/111] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0cd63e918..9b79835b0 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": "8.4.6", + "text-buffer": "8.5.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 6fc3a364e1c43921fe0987e4e91ca254b364d33e Mon Sep 17 00:00:00 2001 From: Riley Dallas Date: Fri, 22 Apr 2016 09:30:45 -0500 Subject: [PATCH 037/111] :memo: Update CSON documentation link in snippets.cson --- dot-atom/snippets.cson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot-atom/snippets.cson b/dot-atom/snippets.cson index eb8f1b22a..cd66bba04 100644 --- a/dot-atom/snippets.cson +++ b/dot-atom/snippets.cson @@ -18,4 +18,4 @@ # This file uses CoffeeScript Object Notation (CSON). # If you are unfamiliar with CSON, you can read more about it in the # Atom Flight Manual: -# https://atom.io/docs/latest/using-atom-basic-customization#cson +# http://flight-manual.atom.io/using-atom/sections/basic-customization/#_cson From 58e1953e43e206788706087a813396915f470316 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 22 Apr 2016 12:07:19 -0700 Subject: [PATCH 038/111] Win32 build now installs to localappdata. Admin elevation now smart. --- build/Gruntfile.coffee | 2 +- build/tasks/install-task.coffee | 20 ++++++++++++++++---- docs/build-instructions/windows.md | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 73279779c..16e0ed5d6 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -57,7 +57,7 @@ module.exports = (grunt) -> homeDir = process.env.USERPROFILE contentsDir = shellAppDir appDir = path.join(shellAppDir, 'resources', 'app') - installDir ?= path.join(process.env.ProgramFiles, appName) + installDir ?= path.join(process.env.LOCALAPPDATA, appName, 'app-dev') killCommand = 'taskkill /F /IM atom.exe' else if process.platform is 'darwin' homeDir = process.env.HOME diff --git a/build/tasks/install-task.coffee b/build/tasks/install-task.coffee index 2d9054385..19fd3d383 100644 --- a/build/tasks/install-task.coffee +++ b/build/tasks/install-task.coffee @@ -16,10 +16,22 @@ module.exports = (grunt) -> {description} = grunt.config.get('atom.metadata') if process.platform is 'win32' - runas ?= require 'runas' - copyFolder = path.resolve 'script', 'copy-folder.cmd' - if runas('cmd', ['/c', copyFolder, shellAppDir, installDir], admin: true) isnt 0 - grunt.log.error("Failed to copy #{shellAppDir} to #{installDir}") + done = @async() + fs.access(installDir, fs.W_OK, (err) -> + adminRequired = true if err + if adminRequired + grunt.log.ok("User does not have write access to #{installDir}, elevating to admin") + runas ?= require 'runas' + copyFolder = path.resolve 'script', 'copy-folder.cmd' + + if runas('cmd', ['/c', copyFolder, shellAppDir, installDir], admin: adminRequired) isnt 0 + grunt.log.error("Failed to copy #{shellAppDir} to #{installDir}") + else + grunt.log.ok("Installed into #{installDir}") + + done() + ) + else if process.platform is 'darwin' rm installDir mkdir path.dirname(installDir) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index 3ec28f139..d0e101ba0 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -34,7 +34,7 @@ git clone https://github.com/atom/atom/ cd atom script/build ``` -This will create the Atom application in the `out\Atom` folder as well as copy it to a folder named `Atom` within `Program Files`. +This will create the Atom application in the `out\Atom` folder as well as copy it to a subfolder of your user profile (e.g. `c:\Users\Bob`) called `AppData\Local\atom\app-dev`. ### `script/build` Options * `--install-dir` - Creates the final built application in this directory. Example (trailing slash is optional): From 11170696d54f28ac8c7bbc67c89030610ee3e4a9 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Fri, 22 Apr 2016 18:10:53 -0400 Subject: [PATCH 039/111] :arrow_up: tree-view@0.206.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b07b4190f..1b6994fed 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.112.0", "tabs": "0.92.2", "timecop": "0.33.1", - "tree-view": "0.206.0", + "tree-view": "0.206.1", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2", From 8e78441e3287a781cda6e95a785557c22f3f183f Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 22 Apr 2016 15:16:08 -0700 Subject: [PATCH 040/111] :arrow_up: tabs@0.92.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1b6994fed..9317866ef 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.2.4", "styleguide": "0.45.2", "symbols-view": "0.112.0", - "tabs": "0.92.2", + "tabs": "0.92.3", "timecop": "0.33.1", "tree-view": "0.206.1", "update-package-dependencies": "0.10.0", From e5e1226ac062ca67cb291e2a3cfe72a1ac6122be Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 23 Apr 2016 11:49:20 -0400 Subject: [PATCH 041/111] :arrow_up: language-c@0.51.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9317866ef..98dbd7385 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.3", + "language-c": "0.51.4", "language-clojure": "0.20.0", "language-coffee-script": "0.47.0", "language-csharp": "0.12.1", From cf79619292fcad749fccf56c8179c656c04727dc Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Sat, 23 Apr 2016 18:31:07 -0700 Subject: [PATCH 042/111] :arrow_up: tree-view@0.206.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 98dbd7385..94478dbf0 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.112.0", "tabs": "0.92.3", "timecop": "0.33.1", - "tree-view": "0.206.1", + "tree-view": "0.206.2", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2", From f6f5c93b01a5a867b048f3da2baa8fac931b653a Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Sat, 23 Apr 2016 18:31:27 -0700 Subject: [PATCH 043/111] :arrow_up: tabs@0.93.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94478dbf0..9dd47b12b 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.2.4", "styleguide": "0.45.2", "symbols-view": "0.112.0", - "tabs": "0.92.3", + "tabs": "0.93.0", "timecop": "0.33.1", "tree-view": "0.206.2", "update-package-dependencies": "0.10.0", From 4825d7ee4b6fcf53b8a9df674a91b07fd4c7edcd Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Sat, 23 Apr 2016 20:15:31 -0700 Subject: [PATCH 044/111] :arrow_up: tabs@0.93.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9dd47b12b..957d262f0 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.2.4", "styleguide": "0.45.2", "symbols-view": "0.112.0", - "tabs": "0.93.0", + "tabs": "0.93.1", "timecop": "0.33.1", "tree-view": "0.206.2", "update-package-dependencies": "0.10.0", From 8bf34d45d7f4857788b63ea094d12dc7f95eb8ee Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:12:07 -0400 Subject: [PATCH 045/111] Don't require notification manager in TextEditor Instead expose getCursorScope and let users outside the text editor show the notification. --- src/text-editor.coffee | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 0d1b3795e..9d81f7dd0 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -79,7 +79,6 @@ class TextEditor extends Model state.displayBuffer = displayBuffer state.selectionsMarkerLayer = displayBuffer.getMarkerLayer(state.selectionsMarkerLayerId) state.config = atomEnvironment.config - state.notificationManager = atomEnvironment.notifications state.packageManager = atomEnvironment.packages state.clipboard = atomEnvironment.clipboard state.viewRegistry = atomEnvironment.views @@ -100,12 +99,11 @@ class TextEditor extends Model @softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, - @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, + @packageManager, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate, grammar, showInvisibles, @autoHeight, @scrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? - throw new Error("Must pass a notificationManager parameter when constructing TextEditors") unless @notificationManager? throw new Error("Must pass a packageManager parameter when constructing TextEditors") unless @packageManager? throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard? throw new Error("Must pass a viewRegistry parameter when constructing TextEditors") unless @viewRegistry? @@ -520,7 +518,7 @@ class TextEditor extends Model softTabs = @getSoftTabs() newEditor = new TextEditor({ @buffer, displayBuffer, selectionsMarkerLayer, @tabLength, softTabs, - suppressCursorCreation: true, @config, @notificationManager, @packageManager, + suppressCursorCreation: true, @config, @packageManager, @firstVisibleScreenRow, @firstVisibleScreenColumn, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate }) @@ -2827,13 +2825,9 @@ class TextEditor extends Model @commentScopeSelector ?= new TextMateScopeSelector('comment.*') @commentScopeSelector.matches(@scopeDescriptorForBufferPosition([bufferRow, match.index]).scopes) - logCursorScope: -> - scopeDescriptor = @getLastCursor().getScopeDescriptor() - list = scopeDescriptor.scopes.toString().split(',') - list = list.map (item) -> "* #{item}" - content = "Scopes at Cursor\n#{list.join('\n')}" - - @notificationManager.addInfo(content, dismissable: true) + # Get the scope descriptor at the cursor. + getCursorScope: -> + @getLastCursor().getScopeDescriptor() # {Delegates to: DisplayBuffer.tokenForBufferPosition} tokenForBufferPosition: (bufferPosition) -> @displayBuffer.tokenForBufferPosition(bufferPosition) From 48e49061e6bdece8d2f128987a71649aecbea7c9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:12:20 -0400 Subject: [PATCH 046/111] Don't need to pass in the notification manager anymore. --- src/workspace.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index b8ed79fd6..838a1dcec 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -564,7 +564,7 @@ class Workspace extends Model # Returns a {TextEditor}. buildTextEditor: (params) -> params = _.extend({ - @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, + @config, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate }, params) new TextEditor(params) From 694af93009b5339171cb8f5f98b572a99bc11024 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:12:38 -0400 Subject: [PATCH 047/111] Implement the show cursor scope functionality in the default commands. --- src/atom-environment.coffee | 2 +- src/register-default-commands.coffee | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index ffff564ba..cf54ee0bc 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -255,7 +255,7 @@ class AtomEnvironment extends Model @deserializers.add(TextBuffer) registerDefaultCommands: -> - registerDefaultCommands({commandRegistry: @commands, @config, @commandInstaller}) + registerDefaultCommands({commandRegistry: @commands, @config, @commandInstaller, notificationManager: @notifications}) registerDefaultViewProviders: -> @views.addViewProvider Workspace, (model, env) -> diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index bb3630117..4f329e943 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,6 +1,6 @@ {ipcRenderer} = require 'electron' -module.exports = ({commandRegistry, commandInstaller, config}) -> +module.exports = ({commandRegistry, commandInstaller, config, notificationManager}) -> commandRegistry.add 'atom-workspace', 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() 'pane:show-previous-recently-used-item': -> @getModel().getActivePane().activatePreviousRecentlyUsedItem() @@ -187,7 +187,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> 'editor:fold-at-indent-level-7': -> @foldAllAtIndentLevel(6) 'editor:fold-at-indent-level-8': -> @foldAllAtIndentLevel(7) 'editor:fold-at-indent-level-9': -> @foldAllAtIndentLevel(8) - 'editor:log-cursor-scope': -> @logCursorScope() + 'editor:log-cursor-scope': -> showCursorScope(@getCursorScope(), notificationManager) 'editor:copy-path': -> @copyPathToClipboard(false) 'editor:copy-project-path': -> @copyPathToClipboard(true) 'editor:toggle-indent-guide': -> config.set('editor.showIndentGuide', not config.get('editor.showIndentGuide')) @@ -232,3 +232,10 @@ stopEventPropagationAndGroupUndo = (config, commandListeners) -> model.transact config.get('editor.undoGroupingInterval'), -> commandListener.call(model, event) newCommandListeners + +showCursorScope = (descriptor, notificationManager) -> + list = descriptor.scopes.toString().split(',') + list = list.map (item) -> "* #{item}" + content = "Scopes at Cursor\n#{list.join('\n')}" + + notificationManager.addInfo(content, dismissable: true) From d494f065df90065c0b784ded343b1baac1bede4d Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:12:42 -0400 Subject: [PATCH 048/111] Update the spec. --- spec/text-editor-spec.coffee | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 7d85f1cad..9dcb61285 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1189,14 +1189,10 @@ describe "TextEditor", -> cursor2 = editor.addCursorAtBufferPosition([1, 4]) expect(cursor2.marker).toBe cursor1.marker - describe '.logCursorScope()', -> - beforeEach -> - spyOn(atom.notifications, 'addInfo') - - it 'opens a notification', -> - editor.logCursorScope() - - expect(atom.notifications.addInfo).toHaveBeenCalled() + describe '.getCursorScope()', -> + it 'returns the current scope', -> + descriptor = editor.getCursorScope() + expect(descriptor.scopes).toContain ('source.js') describe "selection", -> selection = null From 956e037681d023877147a15da1916f5d1737963f Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:20:54 -0400 Subject: [PATCH 049/111] But without the space. --- spec/text-editor-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 9dcb61285..bc08b3f0e 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1192,7 +1192,7 @@ describe "TextEditor", -> describe '.getCursorScope()', -> it 'returns the current scope', -> descriptor = editor.getCursorScope() - expect(descriptor.scopes).toContain ('source.js') + expect(descriptor.scopes).toContain('source.js') describe "selection", -> selection = null From 6b309be6dac0ee8e2ac3028a36f7d92526f8ec11 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:49:43 -0400 Subject: [PATCH 050/111] Propagate a did-use-grammar event out of the tokenized buffer. --- src/display-buffer.coffee | 3 +++ src/text-editor.coffee | 3 +++ src/tokenized-buffer.coffee | 5 ++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index d01ad03c9..717ab5e4f 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -137,6 +137,9 @@ class DisplayBuffer extends Model onDidChangeGrammar: (callback) -> @tokenizedBuffer.onDidChangeGrammar(callback) + onDidUseGrammar: (callback) -> + @tokenizedBuffer.onDidUseGrammar(callback) + onDidTokenize: (callback) -> @tokenizedBuffer.onDidTokenize(callback) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 9d81f7dd0..aaa63b2e5 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -325,6 +325,9 @@ class TextEditor extends Model onDidChangeGrammar: (callback) -> @emitter.on 'did-change-grammar', callback + onDidUseGrammar: (callback) -> + @displayBuffer.onDidUseGrammar(callback) + # Extended: Calls your `callback` when the result of {::isModified} changes. # # * `callback` {Function} diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 5c62f9ecd..1188aeaf0 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -126,9 +126,12 @@ class TokenizedBuffer extends Model @disposables.add(@configSubscriptions) @retokenizeLines() - @packageManager.triggerActivationHook("#{grammar.packageName}:grammar-used") + @emitter.emit 'did-use-grammar', grammar @emitter.emit 'did-change-grammar', grammar + onDidUseGrammar: (callback) -> + @emitter.on 'did-use-grammar', callback + getGrammarSelectionContent: -> @buffer.getTextInRange([[0, 0], [10, 0]]) From e8a4f38c6945f0f50691a46f3c73b3582fb781c5 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:50:14 -0400 Subject: [PATCH 051/111] Don't need to pass the package manager through anymore. --- src/display-buffer.coffee | 7 +++---- src/text-editor.coffee | 8 +++----- src/tokenized-buffer.coffee | 3 +-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 717ab5e4f..ccc68535f 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -35,7 +35,6 @@ class DisplayBuffer extends Model state.config = atomEnvironment.config state.assert = atomEnvironment.assert state.grammarRegistry = atomEnvironment.grammars - state.packageManager = atomEnvironment.packages new this(state) constructor: (params={}) -> @@ -43,7 +42,7 @@ class DisplayBuffer extends Model { tabLength, @editorWidthInChars, @tokenizedBuffer, @foldsMarkerLayer, buffer, - ignoreInvisibles, @largeFileMode, @config, @assert, @grammarRegistry, @packageManager + ignoreInvisibles, @largeFileMode, @config, @assert, @grammarRegistry } = params @emitter = new Emitter @@ -51,7 +50,7 @@ class DisplayBuffer extends Model @tokenizedBuffer ?= new TokenizedBuffer({ tabLength, buffer, ignoreInvisibles, @largeFileMode, @config, - @grammarRegistry, @packageManager, @assert + @grammarRegistry, @assert }) @buffer = @tokenizedBuffer.buffer @charWidthsByScope = {} @@ -122,7 +121,7 @@ class DisplayBuffer extends Model foldsMarkerLayer = @foldsMarkerLayer.copy() new DisplayBuffer({ @buffer, tabLength: @getTabLength(), @largeFileMode, @config, @assert, - @grammarRegistry, @packageManager, foldsMarkerLayer + @grammarRegistry, foldsMarkerLayer }) updateAllScreenLines: -> diff --git a/src/text-editor.coffee b/src/text-editor.coffee index aaa63b2e5..865026e20 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -79,7 +79,6 @@ class TextEditor extends Model state.displayBuffer = displayBuffer state.selectionsMarkerLayer = displayBuffer.getMarkerLayer(state.selectionsMarkerLayerId) state.config = atomEnvironment.config - state.packageManager = atomEnvironment.packages state.clipboard = atomEnvironment.clipboard state.viewRegistry = atomEnvironment.views state.grammarRegistry = atomEnvironment.grammars @@ -99,12 +98,11 @@ class TextEditor extends Model @softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, - @packageManager, @clipboard, @viewRegistry, @grammarRegistry, + @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate, grammar, showInvisibles, @autoHeight, @scrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? - throw new Error("Must pass a packageManager parameter when constructing TextEditors") unless @packageManager? throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard? throw new Error("Must pass a viewRegistry parameter when constructing TextEditors") unless @viewRegistry? throw new Error("Must pass a grammarRegistry parameter when constructing TextEditors") unless @grammarRegistry? @@ -127,7 +125,7 @@ class TextEditor extends Model buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ buffer, tabLength, softWrapped, ignoreInvisibles: @mini or not showInvisibles, largeFileMode, - @config, @assert, @grammarRegistry, @packageManager + @config, @assert, @grammarRegistry }) @buffer = @displayBuffer.buffer @selectionsMarkerLayer ?= @addMarkerLayer(maintainHistory: true) @@ -521,7 +519,7 @@ class TextEditor extends Model softTabs = @getSoftTabs() newEditor = new TextEditor({ @buffer, displayBuffer, selectionsMarkerLayer, @tabLength, softTabs, - suppressCursorCreation: true, @config, @packageManager, + suppressCursorCreation: true, @config, @firstVisibleScreenRow, @firstVisibleScreenColumn, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate }) diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 1188aeaf0..f01498b68 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -29,14 +29,13 @@ class TokenizedBuffer extends Model state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) state.config = atomEnvironment.config state.grammarRegistry = atomEnvironment.grammars - state.packageManager = atomEnvironment.packages state.assert = atomEnvironment.assert new this(state) constructor: (params) -> { @buffer, @tabLength, @ignoreInvisibles, @largeFileMode, @config, - @grammarRegistry, @packageManager, @assert, grammarScopeName + @grammarRegistry, @assert, grammarScopeName } = params @emitter = new Emitter From b1301a5f7416236a99cbe6203c91284f7d486355 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 14:50:34 -0400 Subject: [PATCH 052/111] Trigger the activation hook outside the text editor. --- src/workspace.coffee | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 838a1dcec..a54ace2a2 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -550,9 +550,15 @@ class Workspace extends Model @project.bufferForPath(filePath, options).then (buffer) => editor = @buildTextEditor(_.extend({buffer, largeFileMode}, options)) disposable = atom.textEditors.add(editor) - editor.onDidDestroy -> disposable.dispose() + grammarSubscription = editor.onDidUseGrammar(@handleDidUseGrammar.bind(this)) + editor.onDidDestroy -> + grammarSubscription.dispose() + disposable.dispose() editor + handleDidUseGrammar: (grammar) -> + @packageManager.triggerActivationHook("#{grammar.packageName}:grammar-used") + # Public: Returns a {Boolean} that is `true` if `object` is a `TextEditor`. # # * `object` An {Object} you want to perform the check against. From 02bbb140529357db559610011a4ba60a5b19771c Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 15:02:16 -0400 Subject: [PATCH 053/111] Better method name --- src/workspace.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index a54ace2a2..c8567489d 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -550,13 +550,13 @@ class Workspace extends Model @project.bufferForPath(filePath, options).then (buffer) => editor = @buildTextEditor(_.extend({buffer, largeFileMode}, options)) disposable = atom.textEditors.add(editor) - grammarSubscription = editor.onDidUseGrammar(@handleDidUseGrammar.bind(this)) + grammarSubscription = editor.onDidUseGrammar(@activateGrammar.bind(this)) editor.onDidDestroy -> grammarSubscription.dispose() disposable.dispose() editor - handleDidUseGrammar: (grammar) -> + activateGrammar: (grammar) -> @packageManager.triggerActivationHook("#{grammar.packageName}:grammar-used") # Public: Returns a {Boolean} that is `true` if `object` is a `TextEditor`. From 9014634b3a7d3591c68b66c3259cb410fbaabfd3 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 15:09:03 -0400 Subject: [PATCH 054/111] Just use the already existing change grammar event. --- src/display-buffer.coffee | 3 --- src/text-editor.coffee | 3 --- src/tokenized-buffer.coffee | 4 ---- src/workspace.coffee | 2 +- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index ccc68535f..109b791a1 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -136,9 +136,6 @@ class DisplayBuffer extends Model onDidChangeGrammar: (callback) -> @tokenizedBuffer.onDidChangeGrammar(callback) - onDidUseGrammar: (callback) -> - @tokenizedBuffer.onDidUseGrammar(callback) - onDidTokenize: (callback) -> @tokenizedBuffer.onDidTokenize(callback) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 865026e20..aeb5ebe5c 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -323,9 +323,6 @@ class TextEditor extends Model onDidChangeGrammar: (callback) -> @emitter.on 'did-change-grammar', callback - onDidUseGrammar: (callback) -> - @displayBuffer.onDidUseGrammar(callback) - # Extended: Calls your `callback` when the result of {::isModified} changes. # # * `callback` {Function} diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index f01498b68..38e92f247 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -125,12 +125,8 @@ class TokenizedBuffer extends Model @disposables.add(@configSubscriptions) @retokenizeLines() - @emitter.emit 'did-use-grammar', grammar @emitter.emit 'did-change-grammar', grammar - onDidUseGrammar: (callback) -> - @emitter.on 'did-use-grammar', callback - getGrammarSelectionContent: -> @buffer.getTextInRange([[0, 0], [10, 0]]) diff --git a/src/workspace.coffee b/src/workspace.coffee index c8567489d..96ba00259 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -550,7 +550,7 @@ class Workspace extends Model @project.bufferForPath(filePath, options).then (buffer) => editor = @buildTextEditor(_.extend({buffer, largeFileMode}, options)) disposable = atom.textEditors.add(editor) - grammarSubscription = editor.onDidUseGrammar(@activateGrammar.bind(this)) + grammarSubscription = editor.onDidChangeGrammar(@activateGrammar.bind(this)) editor.onDidDestroy -> grammarSubscription.dispose() disposable.dispose() From 2266f1e3b67a054f2a816dfe9a21876f4f1ebd82 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 15:15:31 -0400 Subject: [PATCH 055/111] Revert "Just use the already existing change grammar event." This reverts commit 9014634b3a7d3591c68b66c3259cb410fbaabfd3. --- src/display-buffer.coffee | 3 +++ src/text-editor.coffee | 3 +++ src/tokenized-buffer.coffee | 4 ++++ src/workspace.coffee | 2 +- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 109b791a1..ccc68535f 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -136,6 +136,9 @@ class DisplayBuffer extends Model onDidChangeGrammar: (callback) -> @tokenizedBuffer.onDidChangeGrammar(callback) + onDidUseGrammar: (callback) -> + @tokenizedBuffer.onDidUseGrammar(callback) + onDidTokenize: (callback) -> @tokenizedBuffer.onDidTokenize(callback) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index aeb5ebe5c..865026e20 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -323,6 +323,9 @@ class TextEditor extends Model onDidChangeGrammar: (callback) -> @emitter.on 'did-change-grammar', callback + onDidUseGrammar: (callback) -> + @displayBuffer.onDidUseGrammar(callback) + # Extended: Calls your `callback` when the result of {::isModified} changes. # # * `callback` {Function} diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 38e92f247..f01498b68 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -125,8 +125,12 @@ class TokenizedBuffer extends Model @disposables.add(@configSubscriptions) @retokenizeLines() + @emitter.emit 'did-use-grammar', grammar @emitter.emit 'did-change-grammar', grammar + onDidUseGrammar: (callback) -> + @emitter.on 'did-use-grammar', callback + getGrammarSelectionContent: -> @buffer.getTextInRange([[0, 0], [10, 0]]) diff --git a/src/workspace.coffee b/src/workspace.coffee index 96ba00259..c8567489d 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -550,7 +550,7 @@ class Workspace extends Model @project.bufferForPath(filePath, options).then (buffer) => editor = @buildTextEditor(_.extend({buffer, largeFileMode}, options)) disposable = atom.textEditors.add(editor) - grammarSubscription = editor.onDidChangeGrammar(@activateGrammar.bind(this)) + grammarSubscription = editor.onDidUseGrammar(@activateGrammar.bind(this)) editor.onDidDestroy -> grammarSubscription.dispose() disposable.dispose() From eaf6036a2c76bc94ed01e93a24f400fce65c018e Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 15:34:37 -0400 Subject: [PATCH 056/111] Wait a tick before sending the event. --- src/tokenized-buffer.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index f01498b68..b1b0749b4 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -125,9 +125,14 @@ class TokenizedBuffer extends Model @disposables.add(@configSubscriptions) @retokenizeLines() - @emitter.emit 'did-use-grammar', grammar + @emitter.emit 'did-change-grammar', grammar + # Delay this to the next tick to ensure whoever created the buffer has the + # change to listen for this event before we send it. + process.nextTick => + @emitter.emit 'did-use-grammar', grammar + onDidUseGrammar: (callback) -> @emitter.on 'did-use-grammar', callback From cf1b4e22172c9bd512fba0d0947b064eaa0be10c Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 15:34:44 -0400 Subject: [PATCH 057/111] Another new name. --- src/workspace.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index c8567489d..975300ae4 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -550,13 +550,13 @@ class Workspace extends Model @project.bufferForPath(filePath, options).then (buffer) => editor = @buildTextEditor(_.extend({buffer, largeFileMode}, options)) disposable = atom.textEditors.add(editor) - grammarSubscription = editor.onDidUseGrammar(@activateGrammar.bind(this)) + grammarSubscription = editor.onDidUseGrammar(@handleGrammarUsed.bind(this)) editor.onDidDestroy -> grammarSubscription.dispose() disposable.dispose() editor - activateGrammar: (grammar) -> + handleGrammarUsed: (grammar) -> @packageManager.triggerActivationHook("#{grammar.packageName}:grammar-used") # Public: Returns a {Boolean} that is `true` if `object` is a `TextEditor`. From 6852d6e91c290e104b3f10ad66116e9660210781 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 15:34:46 -0400 Subject: [PATCH 058/111] Test it. --- spec/workspace-spec.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index fc22f07c3..c61a57bf4 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1619,3 +1619,15 @@ describe "Workspace", -> escapeStringRegex = (str) -> str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + + describe "grammar activation", -> + it "activates grammars", -> + editor = null + + atom.workspace.handleGrammarUsed = jasmine.createSpy() + + waitsForPromise -> atom.workspace.open('sample-with-comments.js').then (o) -> editor = o + runs -> + atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee') + editor.reloadGrammar() + waitsFor -> atom.workspace.handleGrammarUsed.callCount is 1 From 759d64501d1b1b80611b29a435ef14ef45f9919e Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 16:07:49 -0400 Subject: [PATCH 059/111] Better test. --- spec/workspace-spec.coffee | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index c61a57bf4..b84e873da 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1617,17 +1617,21 @@ describe "Workspace", -> runs -> expect(pane.getPendingItem()).toBeFalsy() - escapeStringRegex = (str) -> - str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - describe "grammar activation", -> - it "activates grammars", -> + beforeEach -> + waitsForPromise -> + atom.packages.activatePackage('language-javascript') + + it "notifies the workspace of which grammar is used", -> editor = null - atom.workspace.handleGrammarUsed = jasmine.createSpy() + grammarUsed = jasmine.createSpy() + atom.workspace.handleGrammarUsed = grammarUsed waitsForPromise -> atom.workspace.open('sample-with-comments.js').then (o) -> editor = o + waitsFor -> grammarUsed.callCount is 1 runs -> - atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee') - editor.reloadGrammar() - waitsFor -> atom.workspace.handleGrammarUsed.callCount is 1 + expect(grammarUsed.argsForCall[0][0].name).toBe 'JavaScript' + + escapeStringRegex = (str) -> + str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') From 58d8e6bca8d5f0c6e2bd6e26b48c3d98d5612b20 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 16:11:38 -0400 Subject: [PATCH 060/111] Typo --- src/tokenized-buffer.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index b1b0749b4..7e3c4fe49 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -129,7 +129,7 @@ class TokenizedBuffer extends Model @emitter.emit 'did-change-grammar', grammar # Delay this to the next tick to ensure whoever created the buffer has the - # change to listen for this event before we send it. + # chance to listen for this event before we send it. process.nextTick => @emitter.emit 'did-use-grammar', grammar From 3a63f90ab2469a61975ecc084c36d41270b26938 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 16:24:27 -0400 Subject: [PATCH 061/111] We just say getElement now. --- src/text-editor.coffee | 50 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 865026e20..bd0c9f9f8 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -486,12 +486,12 @@ class TextEditor extends Model onDidChangeScrollTop: (callback) -> Grim.deprecate("This is now a view method. Call TextEditorElement::onDidChangeScrollTop instead.") - @viewRegistry.getView(this).onDidChangeScrollTop(callback) + @getElement().onDidChangeScrollTop(callback) onDidChangeScrollLeft: (callback) -> Grim.deprecate("This is now a view method. Call TextEditorElement::onDidChangeScrollLeft instead.") - @viewRegistry.getView(this).onDidChangeScrollLeft(callback) + @getElement().onDidChangeScrollLeft(callback) onDidRequestAutoscroll: (callback) -> @displayBuffer.onDidRequestAutoscroll(callback) @@ -3133,24 +3133,24 @@ class TextEditor extends Model scrollToTop: -> Grim.deprecate("This is now a view method. Call TextEditorElement::scrollToTop instead.") - @viewRegistry.getView(this).scrollToTop() + @getElement().scrollToTop() scrollToBottom: -> Grim.deprecate("This is now a view method. Call TextEditorElement::scrollToTop instead.") - @viewRegistry.getView(this).scrollToBottom() + @getElement().scrollToBottom() scrollToScreenRange: (screenRange, options) -> @displayBuffer.scrollToScreenRange(screenRange, options) getHorizontalScrollbarHeight: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getHorizontalScrollbarHeight instead.") - @viewRegistry.getView(this).getHorizontalScrollbarHeight() + @getElement().getHorizontalScrollbarHeight() getVerticalScrollbarWidth: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getVerticalScrollbarWidth instead.") - @viewRegistry.getView(this).getVerticalScrollbarWidth() + @getElement().getVerticalScrollbarWidth() pageUp: -> @moveUp(@getRowsPerPage()) @@ -3217,11 +3217,11 @@ class TextEditor extends Model pixelPositionForBufferPosition: (bufferPosition) -> Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForBufferPosition` instead") - @viewRegistry.getView(this).pixelPositionForBufferPosition(bufferPosition) + @getElement().pixelPositionForBufferPosition(bufferPosition) pixelPositionForScreenPosition: (screenPosition) -> Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForScreenPosition` instead") - @viewRegistry.getView(this).pixelPositionForScreenPosition(screenPosition) + @getElement().pixelPositionForScreenPosition(screenPosition) getSelectionMarkerAttributes: -> {type: 'selection', invalidate: 'never'} @@ -3250,7 +3250,7 @@ class TextEditor extends Model @displayBuffer.setHeight(height) else Grim.deprecate("This is now a view method. Call TextEditorElement::setHeight instead.") - @viewRegistry.getView(this).setHeight(height) + @getElement().setHeight(height) getHeight: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getHeight instead.") @@ -3263,7 +3263,7 @@ class TextEditor extends Model @displayBuffer.setWidth(width) else Grim.deprecate("This is now a view method. Call TextEditorElement::setWidth instead.") - @viewRegistry.getView(this).setWidth(width) + @getElement().setWidth(width) getWidth: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getWidth instead.") @@ -3307,77 +3307,77 @@ class TextEditor extends Model getScrollTop: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollTop instead.") - @viewRegistry.getView(this).getScrollTop() + @getElement().getScrollTop() setScrollTop: (scrollTop) -> Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollTop instead.") - @viewRegistry.getView(this).setScrollTop(scrollTop) + @getElement().setScrollTop(scrollTop) getScrollBottom: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollBottom instead.") - @viewRegistry.getView(this).getScrollBottom() + @getElement().getScrollBottom() setScrollBottom: (scrollBottom) -> Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollBottom instead.") - @viewRegistry.getView(this).setScrollBottom(scrollBottom) + @getElement().setScrollBottom(scrollBottom) getScrollLeft: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollLeft instead.") - @viewRegistry.getView(this).getScrollLeft() + @getElement().getScrollLeft() setScrollLeft: (scrollLeft) -> Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollLeft instead.") - @viewRegistry.getView(this).setScrollLeft(scrollLeft) + @getElement().setScrollLeft(scrollLeft) getScrollRight: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollRight instead.") - @viewRegistry.getView(this).getScrollRight() + @getElement().getScrollRight() setScrollRight: (scrollRight) -> Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollRight instead.") - @viewRegistry.getView(this).setScrollRight(scrollRight) + @getElement().setScrollRight(scrollRight) getScrollHeight: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollHeight instead.") - @viewRegistry.getView(this).getScrollHeight() + @getElement().getScrollHeight() getScrollWidth: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollWidth instead.") - @viewRegistry.getView(this).getScrollWidth() + @getElement().getScrollWidth() getMaxScrollTop: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getMaxScrollTop instead.") - @viewRegistry.getView(this).getMaxScrollTop() + @getElement().getMaxScrollTop() intersectsVisibleRowRange: (startRow, endRow) -> Grim.deprecate("This is now a view method. Call TextEditorElement::intersectsVisibleRowRange instead.") - @viewRegistry.getView(this).intersectsVisibleRowRange(startRow, endRow) + @getElement().intersectsVisibleRowRange(startRow, endRow) selectionIntersectsVisibleRowRange: (selection) -> Grim.deprecate("This is now a view method. Call TextEditorElement::selectionIntersectsVisibleRowRange instead.") - @viewRegistry.getView(this).selectionIntersectsVisibleRowRange(selection) + @getElement().selectionIntersectsVisibleRowRange(selection) screenPositionForPixelPosition: (pixelPosition) -> Grim.deprecate("This is now a view method. Call TextEditorElement::screenPositionForPixelPosition instead.") - @viewRegistry.getView(this).screenPositionForPixelPosition(pixelPosition) + @getElement().screenPositionForPixelPosition(pixelPosition) pixelRectForScreenRange: (screenRange) -> Grim.deprecate("This is now a view method. Call TextEditorElement::pixelRectForScreenRange instead.") - @viewRegistry.getView(this).pixelRectForScreenRange(screenRange) + @getElement().pixelRectForScreenRange(screenRange) ### Section: Utility From 1c6d9728c49c754a459c50af20eab4bc5f93b576 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 16:25:36 -0400 Subject: [PATCH 062/111] Don't need to pass packageManager in anymore. --- src/workspace.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 975300ae4..9a52dc937 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -570,8 +570,8 @@ class Workspace extends Model # Returns a {TextEditor}. buildTextEditor: (params) -> params = _.extend({ - @config, @packageManager, @clipboard, @viewRegistry, - @grammarRegistry, @project, @assert, @applicationDelegate + @config, @clipboard, @viewRegistry, @grammarRegistry, + @project, @assert, @applicationDelegate }, params) new TextEditor(params) From 8d7f1b8fba62694677aeeb16d3c6870a6ddeb323 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 16:26:28 -0400 Subject: [PATCH 063/111] Don't need to pass view registry through anymore. --- src/text-editor.coffee | 7 ++----- src/workspace.coffee | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index bd0c9f9f8..e30696479 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -80,7 +80,6 @@ class TextEditor extends Model state.selectionsMarkerLayer = displayBuffer.getMarkerLayer(state.selectionsMarkerLayerId) state.config = atomEnvironment.config state.clipboard = atomEnvironment.clipboard - state.viewRegistry = atomEnvironment.views state.grammarRegistry = atomEnvironment.grammars state.project = atomEnvironment.project state.assert = atomEnvironment.assert.bind(atomEnvironment) @@ -97,14 +96,12 @@ class TextEditor extends Model { @softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, - @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, - @clipboard, @viewRegistry, @grammarRegistry, + @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @clipboard, @grammarRegistry, @project, @assert, @applicationDelegate, grammar, showInvisibles, @autoHeight, @scrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard? - throw new Error("Must pass a viewRegistry parameter when constructing TextEditors") unless @viewRegistry? throw new Error("Must pass a grammarRegistry parameter when constructing TextEditors") unless @grammarRegistry? throw new Error("Must pass a project parameter when constructing TextEditors") unless @project? throw new Error("Must pass an assert parameter when constructing TextEditors") unless @assert? @@ -521,7 +518,7 @@ class TextEditor extends Model @buffer, displayBuffer, selectionsMarkerLayer, @tabLength, softTabs, suppressCursorCreation: true, @config, @firstVisibleScreenRow, @firstVisibleScreenColumn, - @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate + @clipboard, @grammarRegistry, @project, @assert, @applicationDelegate }) newEditor diff --git a/src/workspace.coffee b/src/workspace.coffee index 9a52dc937..c6ab13faf 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -570,7 +570,7 @@ class Workspace extends Model # Returns a {TextEditor}. buildTextEditor: (params) -> params = _.extend({ - @config, @clipboard, @viewRegistry, @grammarRegistry, + @config, @packageManager, @clipboard, @grammarRegistry, @project, @assert, @applicationDelegate }, params) new TextEditor(params) From 856697e55f7815cb78b7138c3b2fb59d93c8a403 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 16:31:28 -0400 Subject: [PATCH 064/111] Uh we seriously don't need package manager. Not sure how that slipped back in there. --- src/workspace.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index c6ab13faf..8f973d2fa 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -570,7 +570,7 @@ class Workspace extends Model # Returns a {TextEditor}. buildTextEditor: (params) -> params = _.extend({ - @config, @packageManager, @clipboard, @grammarRegistry, + @config, @clipboard, @grammarRegistry, @project, @assert, @applicationDelegate }, params) new TextEditor(params) From 5cf532ebe889b809a465c85333cb5e89643d756b Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 17:02:36 -0400 Subject: [PATCH 065/111] Move checkoutHeadRevision to Workspace. --- src/register-default-commands.coffee | 2 +- src/text-editor.coffee | 19 ------------------- src/workspace.coffee | 19 +++++++++++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 4f329e943..035750363 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -204,7 +204,7 @@ module.exports = ({commandRegistry, commandInstaller, config, notificationManage 'editor:newline-below': -> @insertNewlineBelow() 'editor:newline-above': -> @insertNewlineAbove() 'editor:toggle-line-comments': -> @toggleLineCommentsInSelection() - 'editor:checkout-head-revision': -> @checkoutHeadRevision() + 'editor:checkout-head-revision': -> atom.workspace.checkoutHeadRevision(this) 'editor:move-line-up': -> @moveLineUp() 'editor:move-line-down': -> @moveLineDown() 'editor:move-selection-left': -> @moveSelectionLeft() diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e30696479..85e285f8a 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -712,25 +712,6 @@ class TextEditor extends Model # via {Pane::saveItemAs}. getSaveDialogOptions: -> {} - checkoutHeadRevision: -> - if @getPath() - checkoutHead = => - @project.repositoryForDirectory(new Directory(@getDirectoryPath())) - .then (repository) => - repository?.async.checkoutHeadForEditor(this) - - if @config.get('editor.confirmCheckoutHeadRevision') - @applicationDelegate.confirm - message: 'Confirm Checkout HEAD Revision' - detailedMessage: "Are you sure you want to discard all changes to \"#{@getFileName()}\" since the last Git commit?" - buttons: - OK: checkoutHead - Cancel: null - else - checkoutHead() - else - Promise.resolve(false) - ### Section: Reading Text ### diff --git a/src/workspace.coffee b/src/workspace.coffee index 8f973d2fa..9e662c984 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -1085,3 +1085,22 @@ class Workspace extends Model inProcessFinished = true checkFinished() + + checkoutHeadRevision: (editor) -> + if editor.getPath() + checkoutHead = => + @project.repositoryForDirectory(new Directory(editor.getDirectoryPath())) + .then (repository) => + repository?.async.checkoutHeadForEditor(editor) + + if @config.get('editor.confirmCheckoutHeadRevision') + @applicationDelegate.confirm + message: 'Confirm Checkout HEAD Revision' + detailedMessage: "Are you sure you want to discard all changes to \"#{editor.getFileName()}\" since the last Git commit?" + buttons: + OK: checkoutHead + Cancel: null + else + checkoutHead() + else + Promise.resolve(false) From 9fa669b2937a7d985a80fa16e96853ba98578889 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 17:02:51 -0400 Subject: [PATCH 066/111] Set the initial path after saving in Project. --- src/project.coffee | 4 ++++ src/text-editor.coffee | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/project.coffee b/src/project.coffee index 93a3ed496..70d5b93a2 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -391,6 +391,10 @@ class Project extends Model subscribeToBuffer: (buffer) -> buffer.onDidDestroy => @removeBuffer(buffer) + buffer.onDidChangePath => + console.log('did change path! ' + buffer.getPath()) + unless @getPaths().length > 0 + @setPaths([path.dirname(buffer.getPath())]) buffer.onWillThrowWatchError ({error, handle}) => handle() @notificationManager.addWarning """ diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 85e285f8a..4ed926848 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -166,8 +166,6 @@ class TextEditor extends Model subscribeToBuffer: -> @buffer.retain() @disposables.add @buffer.onDidChangePath => - unless @project.getPaths().length > 0 - @project.setPaths([path.dirname(@getPath())]) @emitter.emit 'did-change-title', @getTitle() @emitter.emit 'did-change-path', @getPath() @disposables.add @buffer.onDidChangeEncoding => From 7ed4d60967277a4dc890b2066522f52df7a09e0d Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 17:03:26 -0400 Subject: [PATCH 067/111] Don't need to pass Project around anymore. --- src/text-editor.coffee | 6 ++---- src/workspace.coffee | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 4ed926848..b9996bd8d 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -81,7 +81,6 @@ class TextEditor extends Model state.config = atomEnvironment.config state.clipboard = atomEnvironment.clipboard state.grammarRegistry = atomEnvironment.grammars - state.project = atomEnvironment.project state.assert = atomEnvironment.assert.bind(atomEnvironment) state.applicationDelegate = atomEnvironment.applicationDelegate editor = new this(state) @@ -97,13 +96,12 @@ class TextEditor extends Model @softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @clipboard, @grammarRegistry, - @project, @assert, @applicationDelegate, grammar, showInvisibles, @autoHeight, @scrollPastEnd + @assert, @applicationDelegate, grammar, showInvisibles, @autoHeight, @scrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard? throw new Error("Must pass a grammarRegistry parameter when constructing TextEditors") unless @grammarRegistry? - throw new Error("Must pass a project parameter when constructing TextEditors") unless @project? throw new Error("Must pass an assert parameter when constructing TextEditors") unless @assert? @firstVisibleScreenRow ?= 0 @@ -516,7 +514,7 @@ class TextEditor extends Model @buffer, displayBuffer, selectionsMarkerLayer, @tabLength, softTabs, suppressCursorCreation: true, @config, @firstVisibleScreenRow, @firstVisibleScreenColumn, - @clipboard, @grammarRegistry, @project, @assert, @applicationDelegate + @clipboard, @grammarRegistry, @assert, @applicationDelegate }) newEditor diff --git a/src/workspace.coffee b/src/workspace.coffee index 9e662c984..29c497b99 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -571,7 +571,7 @@ class Workspace extends Model buildTextEditor: (params) -> params = _.extend({ @config, @clipboard, @grammarRegistry, - @project, @assert, @applicationDelegate + @assert, @applicationDelegate }, params) new TextEditor(params) From fdb439be9c6c99da9c1edeb8d456487a4ccb9a0f Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 17:09:07 -0400 Subject: [PATCH 068/111] Call through to the underlying repo. --- src/git-repository-async.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 37131dd24..26840b822 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -246,7 +246,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to a {String} branch name such as // `refs/remotes/origin/master`. getUpstreamBranch (_path) { - return this.getUpstreamBranch(_path) + return this.repo.getUpstreamBranch(_path) } // Public: Gets all the local and remote references. From 8d26fe133aeaf9682027c36ed0736b75476020f7 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 25 Apr 2016 17:10:39 -0400 Subject: [PATCH 069/111] s/original/origin --- src/git-repository-async.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 26840b822..b691994bc 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -234,7 +234,7 @@ export default class GitRepositoryAsync { // Returns a {Promise} which resolves to the {String} origin url of the // repository. getOriginURL (_path) { - return this.repo.getOriginalURL(_path) + return this.repo.getOriginURL(_path) } // Public: Returns the upstream branch for the current HEAD, or null if there From 891071196f35de2edfd3fd712937a90f0ceb427b Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 25 Apr 2016 15:28:22 -0700 Subject: [PATCH 070/111] Ensure atom.cmd with --wait returns exit code of 0 for git commit usage #11605 --- resources/win/atom.cmd | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/win/atom.cmd b/resources/win/atom.cmd index 8a4fed05c..73c4ddb01 100644 --- a/resources/win/atom.cmd +++ b/resources/win/atom.cmd @@ -27,6 +27,7 @@ IF "%EXPECT_OUTPUT%"=="YES" ( SET ELECTRON_ENABLE_LOGGING=YES IF "%WAIT%"=="YES" ( powershell -noexit "Start-Process -FilePath \"%~dp0\..\..\atom.exe\" -ArgumentList \"--pid=$pid $env:PSARGS\" ; wait-event" + exit 0 ) ELSE ( "%~dp0\..\..\atom.exe" %* ) From f589bdd8d9cd5d7b0d05c5ab5c4ccc55482a44d4 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 09:22:38 -0400 Subject: [PATCH 071/111] Add a remote to the fixture. --- spec/fixtures/git/repo-with-submodules/git.git/config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/fixtures/git/repo-with-submodules/git.git/config b/spec/fixtures/git/repo-with-submodules/git.git/config index ab57cc5f1..209e37653 100644 --- a/spec/fixtures/git/repo-with-submodules/git.git/config +++ b/spec/fixtures/git/repo-with-submodules/git.git/config @@ -5,6 +5,9 @@ logallrefupdates = true ignorecase = true precomposeunicode = true +[remote "origin"] + url = git@github.com:atom/some-repo-i-guess.git + fetch = +refs/heads/*:refs/remotes/origin/* [submodule "jstips"] url = https://github.com/loverajoel/jstips [submodule "You-Dont-Need-jQuery"] From f86a15e5fca34cee1351dbeeb5108719b6915282 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 09:22:56 -0400 Subject: [PATCH 072/111] Spec for getOriginURL --- spec/git-repository-async-spec.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index d36b9fd58..77ff1a4b5 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -877,4 +877,16 @@ describe('GitRepositoryAsync', () => { }) }) }) + + describe('.getOriginURL()', () => { + beforeEach(() => { + const workingDirectory = copyRepository('repo-with-submodules') + repo = GitRepositoryAsync.open(workingDirectory) + }) + + it('returns the origin URL', async () => { + const URL = await repo.getOriginURL() + expect(URL).toBe('git@github.com:atom/some-repo-i-guess.git') + }) + }) }) From ff43d917be636f486de059e07a02bd636180fb5b Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 09:23:54 -0400 Subject: [PATCH 073/111] Lower case --- spec/git-repository-async-spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 77ff1a4b5..75f6848aa 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -885,8 +885,8 @@ describe('GitRepositoryAsync', () => { }) it('returns the origin URL', async () => { - const URL = await repo.getOriginURL() - expect(URL).toBe('git@github.com:atom/some-repo-i-guess.git') + const url = await repo.getOriginURL() + expect(url).toBe('git@github.com:atom/some-repo-i-guess.git') }) }) }) From 33a9240fe18ef01b5e223d9029da87e2f563c57f Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 09:45:56 -0400 Subject: [PATCH 074/111] :arrow_up: ohnogit@0.0.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 957d262f0..89a042915 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "marked": "^0.3.4", "normalize-package-data": "^2.0.0", "nslog": "^3", - "ohnogit": "0.0.9", + "ohnogit": "0.0.11", "oniguruma": "^5", "pathwatcher": "~6.2", "property-accessors": "^1.1.3", From e16e987e08ba30f5853c8ab9428a061663304862 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 09:46:04 -0400 Subject: [PATCH 075/111] Give the fixture a remote --- spec/fixtures/git/repo-with-submodules/git.git/config | 3 +++ .../repo-with-submodules/git.git/refs/remotes/origin/master | 1 + 2 files changed, 4 insertions(+) create mode 100644 spec/fixtures/git/repo-with-submodules/git.git/refs/remotes/origin/master diff --git a/spec/fixtures/git/repo-with-submodules/git.git/config b/spec/fixtures/git/repo-with-submodules/git.git/config index 209e37653..ff94b83d6 100644 --- a/spec/fixtures/git/repo-with-submodules/git.git/config +++ b/spec/fixtures/git/repo-with-submodules/git.git/config @@ -5,6 +5,9 @@ logallrefupdates = true ignorecase = true precomposeunicode = true +[branch "master"] + remote = origin + merge = refs/heads/master [remote "origin"] url = git@github.com:atom/some-repo-i-guess.git fetch = +refs/heads/*:refs/remotes/origin/* diff --git a/spec/fixtures/git/repo-with-submodules/git.git/refs/remotes/origin/master b/spec/fixtures/git/repo-with-submodules/git.git/refs/remotes/origin/master new file mode 100644 index 000000000..3507a23dc --- /dev/null +++ b/spec/fixtures/git/repo-with-submodules/git.git/refs/remotes/origin/master @@ -0,0 +1 @@ +d2b0ad9cbc6f6c4372e8956e5cc5af771b2342e5 From 67c7c60dcc874c22e86282a87bc302f1de06e7f0 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 09:49:03 -0400 Subject: [PATCH 076/111] Test getUpstreamBranch --- spec/git-repository-async-spec.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 75f6848aa..1fbe537d5 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -889,4 +889,22 @@ describe('GitRepositoryAsync', () => { expect(url).toBe('git@github.com:atom/some-repo-i-guess.git') }) }) + + describe('.getUpstreamBranch()', () => { + it('returns null when there is no upstream branch', async () => { + const workingDirectory = copyRepository() + repo = GitRepositoryAsync.open(workingDirectory) + + const upstream = await repo.getUpstreamBranch() + expect(upstream).toBe(null) + }) + + it('returns the upstream branch', async () => { + const workingDirectory = copyRepository('repo-with-submodules') + repo = GitRepositoryAsync.open(workingDirectory) + + const upstream = await repo.getUpstreamBranch() + expect(upstream).toBe('refs/remotes/origin/master') + }) + }) }) From 0541755ac8cf5f16792e081213234b5e868fbb84 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 09:49:38 -0400 Subject: [PATCH 077/111] Consistent indentation. --- spec/fixtures/git/repo-with-submodules/git.git/config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/fixtures/git/repo-with-submodules/git.git/config b/spec/fixtures/git/repo-with-submodules/git.git/config index ff94b83d6..323ba7d9b 100644 --- a/spec/fixtures/git/repo-with-submodules/git.git/config +++ b/spec/fixtures/git/repo-with-submodules/git.git/config @@ -9,8 +9,8 @@ remote = origin merge = refs/heads/master [remote "origin"] - url = git@github.com:atom/some-repo-i-guess.git - fetch = +refs/heads/*:refs/remotes/origin/* + url = git@github.com:atom/some-repo-i-guess.git + fetch = +refs/heads/*:refs/remotes/origin/* [submodule "jstips"] url = https://github.com/loverajoel/jstips [submodule "You-Dont-Need-jQuery"] From 5d7c2fc8bae0b48cf35581ec613f42ff81a72481 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 10:32:41 -0400 Subject: [PATCH 078/111] Just observe the grammar. --- src/display-buffer.coffee | 3 --- src/text-editor.coffee | 3 --- src/tokenized-buffer.coffee | 8 -------- src/workspace.coffee | 2 +- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index ccc68535f..109b791a1 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -136,9 +136,6 @@ class DisplayBuffer extends Model onDidChangeGrammar: (callback) -> @tokenizedBuffer.onDidChangeGrammar(callback) - onDidUseGrammar: (callback) -> - @tokenizedBuffer.onDidUseGrammar(callback) - onDidTokenize: (callback) -> @tokenizedBuffer.onDidTokenize(callback) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 865026e20..aeb5ebe5c 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -323,9 +323,6 @@ class TextEditor extends Model onDidChangeGrammar: (callback) -> @emitter.on 'did-change-grammar', callback - onDidUseGrammar: (callback) -> - @displayBuffer.onDidUseGrammar(callback) - # Extended: Calls your `callback` when the result of {::isModified} changes. # # * `callback` {Function} diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 7e3c4fe49..065715806 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -128,14 +128,6 @@ class TokenizedBuffer extends Model @emitter.emit 'did-change-grammar', grammar - # Delay this to the next tick to ensure whoever created the buffer has the - # chance to listen for this event before we send it. - process.nextTick => - @emitter.emit 'did-use-grammar', grammar - - onDidUseGrammar: (callback) -> - @emitter.on 'did-use-grammar', callback - getGrammarSelectionContent: -> @buffer.getTextInRange([[0, 0], [10, 0]]) diff --git a/src/workspace.coffee b/src/workspace.coffee index 9a52dc937..7e67de97d 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -550,7 +550,7 @@ class Workspace extends Model @project.bufferForPath(filePath, options).then (buffer) => editor = @buildTextEditor(_.extend({buffer, largeFileMode}, options)) disposable = atom.textEditors.add(editor) - grammarSubscription = editor.onDidUseGrammar(@handleGrammarUsed.bind(this)) + grammarSubscription = editor.observeGrammar(@handleGrammarUsed.bind(this)) editor.onDidDestroy -> grammarSubscription.dispose() disposable.dispose() From 97328749995349305a6f25725584f2afd6d167d8 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 11:02:01 -0400 Subject: [PATCH 079/111] Don't log anymore. --- src/project.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/project.coffee b/src/project.coffee index 70d5b93a2..bf64753cf 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -392,7 +392,6 @@ class Project extends Model subscribeToBuffer: (buffer) -> buffer.onDidDestroy => @removeBuffer(buffer) buffer.onDidChangePath => - console.log('did change path! ' + buffer.getPath()) unless @getPaths().length > 0 @setPaths([path.dirname(buffer.getPath())]) buffer.onWillThrowWatchError ({error, handle}) => From e1c17ed8563b6ce0c20a65634c5a3f14d7539f3a Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 11:17:20 -0400 Subject: [PATCH 080/111] :arrow_up: status-bar@1.2.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 89a042915..627a411e1 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "settings-view": "0.235.1", "snippets": "1.0.2", "spell-check": "0.67.1", - "status-bar": "1.2.4", + "status-bar": "1.2.5", "styleguide": "0.45.2", "symbols-view": "0.112.0", "tabs": "0.93.1", From 53b7a20ad7e45960365b01d31f309be5f178b8cd Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 11:40:56 -0400 Subject: [PATCH 081/111] :arrow_up: status-bar@1.2.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 627a411e1..2874eaeb0 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "settings-view": "0.235.1", "snippets": "1.0.2", "spell-check": "0.67.1", - "status-bar": "1.2.5", + "status-bar": "1.2.6", "styleguide": "0.45.2", "symbols-view": "0.112.0", "tabs": "0.93.1", From 40d77613502f01b11c2ba36115acdab6aeb29080 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 11:48:52 -0400 Subject: [PATCH 082/111] Bail if we don't have a grammar yet. --- src/workspace.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/workspace.coffee b/src/workspace.coffee index 7e67de97d..c8be01fef 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -557,6 +557,8 @@ class Workspace extends Model editor handleGrammarUsed: (grammar) -> + return unless grammar? + @packageManager.triggerActivationHook("#{grammar.packageName}:grammar-used") # Public: Returns a {Boolean} that is `true` if `object` is a `TextEditor`. From 5fd556ac58f8e2406f6943bec25628b5d0f67169 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 14:55:37 -0400 Subject: [PATCH 083/111] We need Directory now. --- src/workspace.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/workspace.coffee b/src/workspace.coffee index 1458ac9cd..1cc79f1ce 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -4,6 +4,7 @@ path = require 'path' {join} = path {Emitter, Disposable, CompositeDisposable} = require 'event-kit' fs = require 'fs-plus' +{Directory} = require 'pathwatcher' DefaultDirectorySearcher = require './default-directory-searcher' Model = require './model' TextEditor = require './text-editor' From a7606710c012e23d342210d66a25c4741eef1bee Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 14:55:43 -0400 Subject: [PATCH 084/111] Don't need Directory anymore. --- src/text-editor.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index a2ecb3663..a61afea17 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -9,7 +9,6 @@ Cursor = require './cursor' Model = require './model' Selection = require './selection' TextMateScopeSelector = require('first-mate').ScopeSelector -{Directory} = require "pathwatcher" GutterContainer = require './gutter-container' TextEditorElement = require './text-editor-element' From aa9e8ab620d55de235b1b7bb097b70a64903bca5 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 14:56:00 -0400 Subject: [PATCH 085/111] Update the spec. --- spec/text-editor-spec.coffee | 22 ---------------------- spec/workspace-spec.coffee | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index bc08b3f0e..e5e58a5cc 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5727,28 +5727,6 @@ describe "TextEditor", -> expect(handler).toHaveBeenCalledWith 'OK' expect(editor.getPlaceholderText()).toBe 'OK' - describe ".checkoutHeadRevision()", -> - it "reverts to the version of its file checked into the project repository", -> - atom.config.set("editor.confirmCheckoutHeadRevision", false) - - editor.setCursorBufferPosition([0, 0]) - editor.insertText("---\n") - expect(editor.lineTextForBufferRow(0)).toBe "---" - - waitsForPromise -> - editor.checkoutHeadRevision() - - runs -> - expect(editor.lineTextForBufferRow(0)).toBe "var quicksort = function () {" - - describe "when there's no repository for the editor's file", -> - it "doesn't do anything", -> - editor = atom.workspace.buildTextEditor() - editor.setText("stuff") - editor.checkoutHeadRevision() - - waitsForPromise -> editor.checkoutHeadRevision() - describe 'gutters', -> describe 'the TextEditor constructor', -> it 'creates a line-number gutter', -> diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index b84e873da..6fa8001aa 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1633,5 +1633,31 @@ describe "Workspace", -> runs -> expect(grammarUsed.argsForCall[0][0].name).toBe 'JavaScript' + describe ".checkoutHeadRevision()", -> + editor = null + beforeEach -> + atom.config.set("editor.confirmCheckoutHeadRevision", false) + + waitsForPromise -> atom.workspace.open('sample-with-comments.js').then (o) -> editor = o + + it "reverts to the version of its file checked into the project repository", -> + editor.setCursorBufferPosition([0, 0]) + editor.insertText("---\n") + expect(editor.lineTextForBufferRow(0)).toBe "---" + + waitsForPromise -> + atom.workspace.checkoutHeadRevision(editor) + + runs -> + expect(editor.lineTextForBufferRow(0)).toBe "" + + describe "when there's no repository for the editor's file", -> + it "doesn't do anything", -> + editor = atom.workspace.buildTextEditor() + editor.setText("stuff") + atom.workspace.checkoutHeadRevision(editor) + + waitsForPromise -> atom.workspace.checkoutHeadRevision(editor) + escapeStringRegex = (str) -> str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') From e038ff326085317cc55e07782cd2be3f2da313eb Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 16:04:41 -0400 Subject: [PATCH 086/111] Remove applicationDelegate from TextEditor --- src/text-editor.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index a61afea17..4c5b8a956 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -81,7 +81,6 @@ class TextEditor extends Model state.clipboard = atomEnvironment.clipboard state.grammarRegistry = atomEnvironment.grammars state.assert = atomEnvironment.assert.bind(atomEnvironment) - state.applicationDelegate = atomEnvironment.applicationDelegate editor = new this(state) if state.registered disposable = atomEnvironment.textEditors.add(editor) @@ -95,7 +94,7 @@ class TextEditor extends Model @softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @clipboard, @grammarRegistry, - @assert, @applicationDelegate, grammar, showInvisibles, @autoHeight, @scrollPastEnd + @assert, grammar, showInvisibles, @autoHeight, @scrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -510,7 +509,7 @@ class TextEditor extends Model @buffer, displayBuffer, selectionsMarkerLayer, @tabLength, softTabs, suppressCursorCreation: true, @config, @firstVisibleScreenRow, @firstVisibleScreenColumn, - @clipboard, @grammarRegistry, @assert, @applicationDelegate + @clipboard, @grammarRegistry, @assert }) newEditor From 46c97ee2b2fbfeb1210118087dcd754cc8f793b4 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 16:14:25 -0400 Subject: [PATCH 087/111] Provide a default assert implementation if one isn't passed in. --- src/text-editor.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index a61afea17..6ceedf943 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -101,8 +101,8 @@ class TextEditor extends Model throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard? throw new Error("Must pass a grammarRegistry parameter when constructing TextEditors") unless @grammarRegistry? - throw new Error("Must pass an assert parameter when constructing TextEditors") unless @assert? + @assert ?= @defaultAssert.bind(this) @firstVisibleScreenRow ?= 0 @firstVisibleScreenColumn ?= 0 @emitter = new Emitter @@ -3365,6 +3365,9 @@ class TextEditor extends Model @emitter.emit 'will-insert-text', willInsertEvent result + defaultAssert: (condition, message, callback) -> + condition + ### Section: Language Mode Delegated Methods ### From c3bfba0e53f06d2e6b68d8df07d03b9a614babe9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 26 Apr 2016 16:15:30 -0400 Subject: [PATCH 088/111] We don't need to pass in an app delegate here anymore. --- src/workspace.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 1cc79f1ce..f75f00bc6 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -573,8 +573,7 @@ class Workspace extends Model # Returns a {TextEditor}. buildTextEditor: (params) -> params = _.extend({ - @config, @clipboard, @grammarRegistry, - @assert, @applicationDelegate + @config, @clipboard, @grammarRegistry, @assert }, params) new TextEditor(params) From 6bb5e09af92f18ad101bcbee42b50f68d9da741f Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 26 Apr 2016 16:46:00 -0400 Subject: [PATCH 089/111] :arrow_up: language-shellscript@0.22.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2874eaeb0..51d1f06e8 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.47.0", - "language-shellscript": "0.21.1", + "language-shellscript": "0.22.0", "language-source": "0.9.0", "language-sql": "0.21.0", "language-text": "0.7.1", From 3b204d404f4cb6216bedc0afa9c4035f8245e4a8 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Tue, 26 Apr 2016 15:46:47 -0700 Subject: [PATCH 090/111] :arrow_up: apm@1.9.3 --- apm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm/package.json b/apm/package.json index 6623876f9..4ddb4dabe 100644 --- a/apm/package.json +++ b/apm/package.json @@ -6,6 +6,6 @@ "url": "https://github.com/atom/atom.git" }, "dependencies": { - "atom-package-manager": "1.9.2" + "atom-package-manager": "1.9.3" } } From e0688bef1ab96e75baa417c52dcaee01590c49c0 Mon Sep 17 00:00:00 2001 From: David Elliott Date: Tue, 26 Apr 2016 16:15:41 -0700 Subject: [PATCH 091/111] Ctrl-o opens last directory where you opened a file --- src/browser/atom-application.coffee | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 69eff1845..38c2a354a 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -58,6 +58,7 @@ class AtomApplication resourcePath: null version: null quitting: false + lastFilePathOpened: null exit: (status) -> app.exit(status) @@ -655,6 +656,7 @@ class AtomApplication # :window - An {AtomWindow} to use for opening a selected file path. promptForPathToOpen: (type, {devMode, safeMode, window}) -> @promptForPath type, (pathsToOpen) => + @lastFilePathOpened = pathsToOpen[0] if pathsToOpen.length > 0 @openPaths({pathsToOpen, devMode, safeMode, window}) promptForPath: (type, callback) -> @@ -680,8 +682,8 @@ class AtomApplication when 'folder' then 'Open Folder' else 'Open' - if process.platform is 'linux' - if projectPath = @lastFocusedWindow?.projectPath - openOptions.defaultPath = projectPath + # If a file was previously opened, set default path to open there again. + if @lastFilePathOpened? and type is 'file' + openOptions.defaultPath = @lastFilePathOpened dialog.showOpenDialog(parentWindow, openOptions, callback) From 5db3280bf04dce58684ecaec26ee044f05de9780 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 11:59:05 -0400 Subject: [PATCH 092/111] Provide openedPath For backward compatibility with GitRepoAsync before moving to ohnogit. --- src/git-repository-async.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index b691994bc..66b73ba77 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -50,6 +50,10 @@ export default class GitRepositoryAsync { return this.repo._refreshingPromise } + get openedPath () { + return this.repo.openedPath + } + // Public: Destroy this {GitRepositoryAsync} object. // // This destroys any tasks and subscriptions and releases the underlying From 30d6353fd8e46af780bd6b47da585b62b10eddfa Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 12:03:29 -0400 Subject: [PATCH 093/111] Spec for openedPath. --- spec/git-repository-async-spec.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 1fbe537d5..fcb528819 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -55,6 +55,14 @@ describe('GitRepositoryAsync', () => { }) }) + describe('openedPath', () => { + it('is the path passed to .open', () => { + const workingDirPath = copyRepository() + repo = GitRepositoryAsync.open(workingDirPath) + expect(repo.openedPath).toBe(workingDirPath) + }) + }) + describe('.getRepo()', () => { beforeEach(() => { const workingDirectory = copySubmoduleRepository() From a279db5568707e5c17009735eea4d72295a0eed8 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 12:50:13 -0400 Subject: [PATCH 094/111] Failing test. --- spec/git-spec.coffee | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 7d9e9bbd4..82e371146 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -289,6 +289,16 @@ describe "GitRepository", -> expect(repo.isStatusModified(status)).toBe true expect(repo.isStatusNew(status)).toBe false + it 'caches statuses that were looked up synchronously', -> + originalContent = 'undefined' + fs.writeFileSync(modifiedPath, 'making this path modified') + repo.getPathStatus('file.txt') + + fs.writeFileSync(modifiedPath, originalContent) + waitsForPromise -> repo.refreshStatus() + runs -> + expect(repo.isStatusModified(repo.getCachedPathStatus(modifiedPath))).toBeFalsy() + describe "buffer events", -> [editor] = [] From 69e97204d51ec412f0b81acf1eb89369aed08a15 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 12:50:27 -0400 Subject: [PATCH 095/111] Test for undefinedness instead of 0. --- src/git-repository.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/git-repository.coffee b/src/git-repository.coffee index a04124b78..cea000efc 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -369,7 +369,10 @@ class GitRepository @getCachedRelativePathStatus(relativePath) getCachedRelativePathStatus: (relativePath) -> - @statusesByPath[relativePath] ? @async.getCachedPathStatuses()[relativePath] + cachedStatus = @statusesByPath[relativePath] + return cachedStatus if cachedStatus? + + @async.getCachedPathStatuses()[relativePath] # Public: Returns true if the given status indicates modification. # From b4733732dcf45546e976160508e4100339f7f7f8 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 27 Apr 2016 10:35:39 -0700 Subject: [PATCH 096/111] :arrow_up: autocomplete-plus@2.30.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 51d1f06e8..1802e8bd1 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.1", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.29.2", + "autocomplete-plus": "2.30.0", "autocomplete-snippets": "1.10.0", "autoflow": "0.27.0", "autosave": "0.23.1", From 6ec5cf497b0357657cffd30b5ad89bc6b909c7a2 Mon Sep 17 00:00:00 2001 From: David Elliott Date: Wed, 27 Apr 2016 10:52:57 -0700 Subject: [PATCH 097/111] :bug: Ctrl-O opens file dialog in directory of currently active editor --- src/browser/atom-application.coffee | 32 ++++++++++++++++------------ src/register-default-commands.coffee | 12 ++++++----- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 38c2a354a..b40dbfaad 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -58,7 +58,6 @@ class AtomApplication resourcePath: null version: null quitting: false - lastFilePathOpened: null exit: (status) -> app.exit(status) @@ -171,11 +170,6 @@ class AtomApplication @on 'application:quit', -> app.quit() @on 'application:new-window', -> @openPath(getLoadSettings()) @on 'application:new-file', -> (@focusedWindow() ? this).openPath() - @on 'application:open', -> @promptForPathToOpen('all', getLoadSettings()) - @on 'application:open-file', -> @promptForPathToOpen('file', getLoadSettings()) - @on 'application:open-folder', -> @promptForPathToOpen('folder', getLoadSettings()) - @on 'application:open-dev', -> @promptForPathToOpen('all', devMode: true) - @on 'application:open-safe', -> @promptForPathToOpen('all', safeMode: true) @on 'application:inspect', ({x, y, atomWindow}) -> atomWindow ?= @focusedWindow() atomWindow?.browserWindow.inspectElement(x, y) @@ -256,6 +250,15 @@ class AtomApplication ipcMain.on 'command', (event, command) => @emit(command) + ipcMain.on 'open-command', (event, command, args...) => + switch command + when 'application:open' then @promptForPathToOpen('all', getLoadSettings()) + when 'application:open-file' then @promptForPathToOpen('file', getLoadSettings(), args[0]) + when 'application:open-folder' then @promptForPathToOpen('folder', getLoadSettings()) + when 'application:open-dev' then @promptForPathToOpen('all', devMode: true) + when 'application:open-safe' then @promptForPathToOpen('all', safeMode: true) + else console.log "Invalid open-command received: " + command + ipcMain.on 'window-command', (event, command, args...) -> win = BrowserWindow.fromWebContents(event.sender) win.emit(command, args...) @@ -654,12 +657,13 @@ class AtomApplication # :safeMode - A Boolean which controls whether any newly opened windows # should be in safe mode or not. # :window - An {AtomWindow} to use for opening a selected file path. - promptForPathToOpen: (type, {devMode, safeMode, window}) -> - @promptForPath type, (pathsToOpen) => - @lastFilePathOpened = pathsToOpen[0] if pathsToOpen.length > 0 - @openPaths({pathsToOpen, devMode, safeMode, window}) + # :path - An optional String which controls the default path to which the + # file dialog opens. + promptForPathToOpen: (type, {devMode, safeMode, window}, path=null) -> + @promptForPath type, ((pathsToOpen) => + @openPaths({pathsToOpen, devMode, safeMode, window})), path - promptForPath: (type, callback) -> + promptForPath: (type, callback, path) -> properties = switch type when 'file' then ['openFile'] @@ -682,8 +686,8 @@ class AtomApplication when 'folder' then 'Open Folder' else 'Open' - # If a file was previously opened, set default path to open there again. - if @lastFilePathOpened? and type is 'file' - openOptions.defaultPath = @lastFilePathOpened + # File dialog defaults to project directory of currently active editor + if path? and type is 'file' + openOptions.defaultPath = path dialog.showOpenDialog(parentWindow, openOptions, callback) diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 035750363..e0b08abdc 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -31,11 +31,13 @@ module.exports = ({commandRegistry, commandInstaller, config, notificationManage 'application:unhide-all-applications': -> ipcRenderer.send('command', 'application:unhide-all-applications') 'application:new-window': -> ipcRenderer.send('command', 'application:new-window') 'application:new-file': -> ipcRenderer.send('command', 'application:new-file') - 'application:open': -> ipcRenderer.send('command', 'application:open') - 'application:open-file': -> ipcRenderer.send('command', 'application:open-file') - 'application:open-folder': -> ipcRenderer.send('command', 'application:open-folder') - 'application:open-dev': -> ipcRenderer.send('command', 'application:open-dev') - 'application:open-safe': -> ipcRenderer.send('command', 'application:open-safe') + 'application:open': -> ipcRenderer.send('open-command', 'application:open') + 'application:open-file': -> + defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] + ipcRenderer.send('open-command', 'application:open-file', defaultPath) + 'application:open-folder': -> ipcRenderer.send('open-command', 'application:open-folder') + 'application:open-dev': -> ipcRenderer.send('open-command', 'application:open-dev') + 'application:open-safe': -> ipcRenderer.send('open-command', 'application:open-safe') 'application:add-project-folder': -> atom.addProjectFolder() 'application:minimize': -> ipcRenderer.send('command', 'application:minimize') 'application:zoom': -> ipcRenderer.send('command', 'application:zoom') From c0adf125ecaf2100a4e3bd584565d5c6c5435fad Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 16:05:00 -0400 Subject: [PATCH 098/111] Reset the cache before calling the callback. --- src/git-repository.coffee | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/git-repository.coffee b/src/git-repository.coffee index cea000efc..28455c983 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -166,12 +166,10 @@ class GitRepository # # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. onDidChangeStatuses: (callback) -> - @async.onDidChangeStatuses -> - # Defer the callback to the next tick so that we've reset - # `@statusesByPath` by the time it's called. Otherwise reads from within - # the callback could be inconsistent. - # See https://github.com/atom/atom/issues/11396 - process.nextTick callback + @async.onDidChangeStatuses => + @branch = @async?.branch + @statusesByPath = {} + callback() ### Section: Repository Details @@ -369,10 +367,7 @@ class GitRepository @getCachedRelativePathStatus(relativePath) getCachedRelativePathStatus: (relativePath) -> - cachedStatus = @statusesByPath[relativePath] - return cachedStatus if cachedStatus? - - @async.getCachedPathStatuses()[relativePath] + @statusesByPath[relativePath] ? @async.getCachedPathStatuses()[relativePath] # Public: Returns true if the given status indicates modification. # @@ -499,10 +494,7 @@ class GitRepository # # Returns a promise that resolves when the repository has been refreshed. refreshStatus: -> - asyncRefresh = @async.refreshStatus().then => - @statusesByPath = {} - @branch = @async?.branch - + asyncRefresh = @async.refreshStatus() syncRefresh = new Promise (resolve, reject) => @handlerPath ?= require.resolve('./repository-status-handler') From 630b8c69a603e69351864bb6fd851e1e9b4ef063 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 16:24:29 -0400 Subject: [PATCH 099/111] Fix the test. --- spec/git-spec.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 82e371146..88c5c9a86 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -295,7 +295,12 @@ describe "GitRepository", -> repo.getPathStatus('file.txt') fs.writeFileSync(modifiedPath, originalContent) - waitsForPromise -> repo.refreshStatus() + + statusHandler = jasmine.createSpy('statusHandler') + repo.onDidChangeStatuses statusHandler + repo.refreshStatus() + + waitsFor -> statusHandler.callCount > 0 runs -> expect(repo.isStatusModified(repo.getCachedPathStatus(modifiedPath))).toBeFalsy() From 4727d6611e53cb8454a77ad607973a2c8efa8885 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 17:06:37 -0400 Subject: [PATCH 100/111] Revert "Fix the test." This reverts commit 630b8c69a603e69351864bb6fd851e1e9b4ef063. --- spec/git-spec.coffee | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 88c5c9a86..82e371146 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -295,12 +295,7 @@ describe "GitRepository", -> repo.getPathStatus('file.txt') fs.writeFileSync(modifiedPath, originalContent) - - statusHandler = jasmine.createSpy('statusHandler') - repo.onDidChangeStatuses statusHandler - repo.refreshStatus() - - waitsFor -> statusHandler.callCount > 0 + waitsForPromise -> repo.refreshStatus() runs -> expect(repo.isStatusModified(repo.getCachedPathStatus(modifiedPath))).toBeFalsy() From d11e30579b3203bc179018dacd91441ce37a4fff Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 17:17:09 -0400 Subject: [PATCH 101/111] Manually emit the change event. --- src/git-repository.coffee | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/git-repository.coffee b/src/git-repository.coffee index 28455c983..a92a03a89 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -166,10 +166,7 @@ class GitRepository # # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. onDidChangeStatuses: (callback) -> - @async.onDidChangeStatuses => - @branch = @async?.branch - @statusesByPath = {} - callback() + @emitter.on 'did-change-statuses', callback ### Section: Repository Details @@ -494,7 +491,23 @@ class GitRepository # # Returns a promise that resolves when the repository has been refreshed. refreshStatus: -> - asyncRefresh = @async.refreshStatus() + statusesChanged = false + subscription = @async.onDidChangeStatuses -> + subscription?.dispose() + subscription = null + + statusesChanged = true + + asyncRefresh = @async.refreshStatus().then => + subscription?.dispose() + subscription = null + + @branch = @async?.branch + @statusesByPath = {} + + if statusesChanged + @emitter.emit 'did-change-statuses' + syncRefresh = new Promise (resolve, reject) => @handlerPath ?= require.resolve('./repository-status-handler') From cd8b28da4da588b4bf63d410da6a14f96adbc8d9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 27 Apr 2016 22:40:34 -0400 Subject: [PATCH 102/111] Document why --- src/git-repository.coffee | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/git-repository.coffee b/src/git-repository.coffee index a92a03a89..fcbc40830 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -492,6 +492,11 @@ class GitRepository # Returns a promise that resolves when the repository has been refreshed. refreshStatus: -> statusesChanged = false + + # Listen for `did-change-statuses` so we know if something changed. But we + # need to wait to propagate it until after we've set the branch and cleared + # the `statusesByPath` cache. So just set a flag, and we'll emit the event + # after refresh is done. subscription = @async.onDidChangeStatuses -> subscription?.dispose() subscription = null From 3b5bcf1c0dc71eaccb0ee29b648d8285706ecf37 Mon Sep 17 00:00:00 2001 From: livelazily Date: Mon, 25 Apr 2016 22:23:40 +0800 Subject: [PATCH 103/111] :bug: Wait for connection end to get completed data; --- src/browser/atom-application.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 69eff1845..3255b0a19 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -138,7 +138,11 @@ class AtomApplication return unless @socketPath? @deleteSocketFile() server = net.createServer (connection) => - connection.on 'data', (data) => + data = '' + connection.on 'data', (chunk) -> + data = data + chunk + + connection.on 'end', => options = JSON.parse(data) @openWithOptions(options) From 76d8421963e1712f13c2808f1a2725011322080e Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 28 Apr 2016 09:50:01 -0400 Subject: [PATCH 104/111] Inline the no-op assert. --- src/text-editor.coffee | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e3300a3b2..8779cd973 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -101,7 +101,7 @@ class TextEditor extends Model throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard? throw new Error("Must pass a grammarRegistry parameter when constructing TextEditors") unless @grammarRegistry? - @assert ?= @defaultAssert.bind(this) + @assert ?= (condition) -> condition @firstVisibleScreenRow ?= 0 @firstVisibleScreenColumn ?= 0 @emitter = new Emitter @@ -3364,9 +3364,6 @@ class TextEditor extends Model @emitter.emit 'will-insert-text', willInsertEvent result - defaultAssert: (condition, message, callback) -> - condition - ### Section: Language Mode Delegated Methods ### From 2f1268dc7ca9ab773837499d4a938064978919ac Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 28 Apr 2016 11:36:17 -0400 Subject: [PATCH 105/111] Move copyPathToClipboard to the default commands. --- src/atom-environment.coffee | 2 +- src/register-default-commands.coffee | 11 ++++++++--- src/text-editor.coffee | 6 ------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index cf54ee0bc..f50ae9d5b 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -255,7 +255,7 @@ class AtomEnvironment extends Model @deserializers.add(TextBuffer) registerDefaultCommands: -> - registerDefaultCommands({commandRegistry: @commands, @config, @commandInstaller, notificationManager: @notifications}) + registerDefaultCommands({commandRegistry: @commands, @config, @commandInstaller, notificationManager: @notifications, @project, @clipboard}) registerDefaultViewProviders: -> @views.addViewProvider Workspace, (model, env) -> diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 035750363..1cb3d99b5 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,6 +1,6 @@ {ipcRenderer} = require 'electron' -module.exports = ({commandRegistry, commandInstaller, config, notificationManager}) -> +module.exports = ({commandRegistry, commandInstaller, config, notificationManager, project, clipboard}) -> commandRegistry.add 'atom-workspace', 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() 'pane:show-previous-recently-used-item': -> @getModel().getActivePane().activatePreviousRecentlyUsedItem() @@ -188,8 +188,8 @@ module.exports = ({commandRegistry, commandInstaller, config, notificationManage 'editor:fold-at-indent-level-8': -> @foldAllAtIndentLevel(7) 'editor:fold-at-indent-level-9': -> @foldAllAtIndentLevel(8) 'editor:log-cursor-scope': -> showCursorScope(@getCursorScope(), notificationManager) - 'editor:copy-path': -> @copyPathToClipboard(false) - 'editor:copy-project-path': -> @copyPathToClipboard(true) + 'editor:copy-path': -> copyPathToClipboard(this, project, clipboard, false) + 'editor:copy-project-path': -> copyPathToClipboard(this, project, clipboard, true) 'editor:toggle-indent-guide': -> config.set('editor.showIndentGuide', not config.get('editor.showIndentGuide')) 'editor:toggle-line-numbers': -> config.set('editor.showLineNumbers', not config.get('editor.showLineNumbers')) 'editor:scroll-to-cursor': -> @scrollToCursorPosition() @@ -239,3 +239,8 @@ showCursorScope = (descriptor, notificationManager) -> content = "Scopes at Cursor\n#{list.join('\n')}" notificationManager.addInfo(content, dismissable: true) + +copyPathToClipboard = (editor, project, clipboard, relative) -> + if filePath = editor.getPath() + filePath = project.relativize(filePath) if relative + clipboard.write(filePath) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 8779cd973..9976e5906 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -669,12 +669,6 @@ class TextEditor extends Model # Essential: Returns {Boolean} `true` if this editor has no content. isEmpty: -> @buffer.isEmpty() - # Copies the current file path to the native clipboard. - copyPathToClipboard: (relative = false) -> - if filePath = @getPath() - filePath = atom.project.relativize(filePath) if relative - @clipboard.write(filePath) - ### Section: File Operations ### From 398ae4491ec8b4a03f3d47343c410c46788975ef Mon Sep 17 00:00:00 2001 From: David Elliott Date: Thu, 28 Apr 2016 11:13:07 -0700 Subject: [PATCH 106/111] :art: Removed application:open-dev and application:open-safe from new method. --- src/browser/atom-application.coffee | 7 ++++--- src/register-default-commands.coffee | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index b40dbfaad..f39c50ce4 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -170,6 +170,8 @@ class AtomApplication @on 'application:quit', -> app.quit() @on 'application:new-window', -> @openPath(getLoadSettings()) @on 'application:new-file', -> (@focusedWindow() ? this).openPath() + @on 'application:open-dev', -> @promptForPathToOpen('all', devMode: true) + @on 'application:open-safe', -> @promptForPathToOpen('all', safeMode: true) @on 'application:inspect', ({x, y, atomWindow}) -> atomWindow ?= @focusedWindow() atomWindow?.browserWindow.inspectElement(x, y) @@ -251,12 +253,11 @@ class AtomApplication @emit(command) ipcMain.on 'open-command', (event, command, args...) => + defaultPath = args[0] if args.length > 0 switch command when 'application:open' then @promptForPathToOpen('all', getLoadSettings()) - when 'application:open-file' then @promptForPathToOpen('file', getLoadSettings(), args[0]) + when 'application:open-file' then @promptForPathToOpen('file', getLoadSettings(), defaultPath) when 'application:open-folder' then @promptForPathToOpen('folder', getLoadSettings()) - when 'application:open-dev' then @promptForPathToOpen('all', devMode: true) - when 'application:open-safe' then @promptForPathToOpen('all', safeMode: true) else console.log "Invalid open-command received: " + command ipcMain.on 'window-command', (event, command, args...) -> diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index e0b08abdc..b2dc1fd68 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -36,8 +36,8 @@ module.exports = ({commandRegistry, commandInstaller, config, notificationManage defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] ipcRenderer.send('open-command', 'application:open-file', defaultPath) 'application:open-folder': -> ipcRenderer.send('open-command', 'application:open-folder') - 'application:open-dev': -> ipcRenderer.send('open-command', 'application:open-dev') - 'application:open-safe': -> ipcRenderer.send('open-command', 'application:open-safe') + 'application:open-dev': -> ipcRenderer.send('command', 'application:open-dev') + 'application:open-safe': -> ipcRenderer.send('command', 'application:open-safe') 'application:add-project-folder': -> atom.addProjectFolder() 'application:minimize': -> ipcRenderer.send('command', 'application:minimize') 'application:zoom': -> ipcRenderer.send('command', 'application:zoom') From 7d463d9dd02fb60990690b8e32d16b75ea820137 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 28 Apr 2016 15:30:38 -0700 Subject: [PATCH 107/111] :arrow_up: about@1.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1802e8bd1..87083ddd7 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "one-light-syntax": "1.2.0", "solarized-dark-syntax": "1.0.2", "solarized-light-syntax": "1.0.2", - "about": "1.5.1", + "about": "1.5.2", "archive-view": "0.61.1", "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.1", From e2fa948ac8e541ecefe7fcdfac4f87535486a004 Mon Sep 17 00:00:00 2001 From: David Elliott Date: Fri, 29 Apr 2016 08:20:52 -0700 Subject: [PATCH 108/111] :bug: Add support for Mac and Open Folder dialog. --- src/browser/atom-application.coffee | 6 +++--- src/register-default-commands.coffee | 11 ++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index f39c50ce4..f90afad83 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -255,9 +255,9 @@ class AtomApplication ipcMain.on 'open-command', (event, command, args...) => defaultPath = args[0] if args.length > 0 switch command - when 'application:open' then @promptForPathToOpen('all', getLoadSettings()) + when 'application:open' then @promptForPathToOpen('all', getLoadSettings(), defaultPath) when 'application:open-file' then @promptForPathToOpen('file', getLoadSettings(), defaultPath) - when 'application:open-folder' then @promptForPathToOpen('folder', getLoadSettings()) + when 'application:open-folder' then @promptForPathToOpen('folder', getLoadSettings(), defaultPath) else console.log "Invalid open-command received: " + command ipcMain.on 'window-command', (event, command, args...) -> @@ -688,7 +688,7 @@ class AtomApplication else 'Open' # File dialog defaults to project directory of currently active editor - if path? and type is 'file' + if path? openOptions.defaultPath = path dialog.showOpenDialog(parentWindow, openOptions, callback) diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index b2dc1fd68..74da2786e 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,6 +1,7 @@ {ipcRenderer} = require 'electron' module.exports = ({commandRegistry, commandInstaller, config, notificationManager}) -> + commandRegistry.add 'atom-workspace', 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() 'pane:show-previous-recently-used-item': -> @getModel().getActivePane().activatePreviousRecentlyUsedItem() @@ -31,11 +32,15 @@ module.exports = ({commandRegistry, commandInstaller, config, notificationManage 'application:unhide-all-applications': -> ipcRenderer.send('command', 'application:unhide-all-applications') 'application:new-window': -> ipcRenderer.send('command', 'application:new-window') 'application:new-file': -> ipcRenderer.send('command', 'application:new-file') - 'application:open': -> ipcRenderer.send('open-command', 'application:open') - 'application:open-file': -> + 'application:open': -> + defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] + ipcRenderer.send('open-command', 'application:open', defaultPath) + 'application:open-file': -> defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] ipcRenderer.send('open-command', 'application:open-file', defaultPath) - 'application:open-folder': -> ipcRenderer.send('open-command', 'application:open-folder') + 'application:open-folder': -> + defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] + ipcRenderer.send('open-command', 'application:open-folder', defaultPath) 'application:open-dev': -> ipcRenderer.send('command', 'application:open-dev') 'application:open-safe': -> ipcRenderer.send('command', 'application:open-safe') 'application:add-project-folder': -> atom.addProjectFolder() From 6c9d7ecc2884075655e1583129afc99aa75dea47 Mon Sep 17 00:00:00 2001 From: David Elliott Date: Fri, 29 Apr 2016 08:39:14 -0700 Subject: [PATCH 109/111] Remove random space --- src/register-default-commands.coffee | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 74da2786e..086a55497 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,7 +1,6 @@ {ipcRenderer} = require 'electron' module.exports = ({commandRegistry, commandInstaller, config, notificationManager}) -> - commandRegistry.add 'atom-workspace', 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() 'pane:show-previous-recently-used-item': -> @getModel().getActivePane().activatePreviousRecentlyUsedItem() @@ -32,13 +31,13 @@ module.exports = ({commandRegistry, commandInstaller, config, notificationManage 'application:unhide-all-applications': -> ipcRenderer.send('command', 'application:unhide-all-applications') 'application:new-window': -> ipcRenderer.send('command', 'application:new-window') 'application:new-file': -> ipcRenderer.send('command', 'application:new-file') - 'application:open': -> + 'application:open': -> defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] ipcRenderer.send('open-command', 'application:open', defaultPath) - 'application:open-file': -> + 'application:open-file': -> defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] ipcRenderer.send('open-command', 'application:open-file', defaultPath) - 'application:open-folder': -> + 'application:open-folder': -> defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0] ipcRenderer.send('open-command', 'application:open-folder', defaultPath) 'application:open-dev': -> ipcRenderer.send('command', 'application:open-dev') From b975c1ffc188a3b3fcee112a7b22a54c76089325 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Fri, 29 Apr 2016 18:15:41 -0400 Subject: [PATCH 110/111] :arrow_up: language-sass@0.48.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 87083ddd7..e19a1c8f8 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "language-python": "0.43.1", "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", - "language-sass": "0.47.0", + "language-sass": "0.48.0", "language-shellscript": "0.22.0", "language-source": "0.9.0", "language-sql": "0.21.0", From 8d9324e234d8a73ff5681cab1129f9f796f6a529 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Fri, 29 Apr 2016 18:30:19 -0400 Subject: [PATCH 111/111] :arrow_up: language-sass@0.49.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e19a1c8f8..8aad494e4 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "language-python": "0.43.1", "language-ruby": "0.68.5", "language-ruby-on-rails": "0.25.0", - "language-sass": "0.48.0", + "language-sass": "0.49.0", "language-shellscript": "0.22.0", "language-source": "0.9.0", "language-sql": "0.21.0",