diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee index 94fb00e2c..ff61d2ba8 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)*" 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 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' diff --git a/package.json b/package.json index d20e7636a..f8213b354 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.9", "oniguruma": "^5", "pathwatcher": "~6.2", "property-accessors": "^1.1.3", @@ -107,17 +107,17 @@ "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", + "tabs": "0.93.1", "timecop": "0.33.1", - "tree-view": "0.206.0", + "tree-view": "0.206.2", "update-package-dependencies": "0.10.0", "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", 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" %* ) 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/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/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index ecb7bd820..466d1b501 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1186,14 +1186,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 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/git-repository-async.js b/src/git-repository-async.js index aacd482f7..37131dd24 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,39 +16,19 @@ 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 // repository. static get DestroyedErrorName () { - return 'GitRepositoryAsync.destroyed' + return Repository.DestroyedErrorName } 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) { @@ -78,23 +45,22 @@ 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 // 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 +73,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 +88,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 +100,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 +117,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 +145,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 +155,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 +175,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 +185,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 +199,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 +212,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 +223,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 +234,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 +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.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 +259,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 +271,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 +284,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 +294,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 +304,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 +315,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 +328,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 +344,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 +352,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 +361,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 +370,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 +380,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 +390,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 +400,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 +416,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 +431,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 +452,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 +463,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 +482,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 +494,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 +505,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 +515,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 +525,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 +551,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) - }) - }) - } } 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) 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 } -} diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 19fddb2e1..710a9e342 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -108,7 +108,6 @@ class TextEditor extends Model state.displayLayer = state.buffer.getDisplayLayer(state.displayLayerId) ? state.buffer.addDisplayLayer() state.selectionsMarkerLayer = state.displayLayer.getMarkerLayer(state.selectionsMarkerLayerId) state.config = atomEnvironment.config - state.notificationManager = atomEnvironment.notifications state.packageManager = atomEnvironment.packages state.clipboard = atomEnvironment.clipboard state.viewRegistry = atomEnvironment.views @@ -129,18 +128,12 @@ class TextEditor extends Model @softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, @tabLength, @softWrapped, @decorationManager, @selectionsMarkerLayer, @buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, @largeFileMode, @config, - @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, grammar, @showInvisibles, @autoHeight, @scrollPastEnd + @packageManager, @clipboard, @viewRegistry, @grammarRegistry, + @project, @assert, @applicationDelegate, grammar, @showInvisibles, @autoHeight, @scrollPastEnd, + @editorWidthInChars, @tokenizedBuffer, @ignoreInvisibles, @displayLayer } = params - { - tabLength, @editorWidthInChars, @tokenizedBuffer, buffer, @ignoreInvisibles, - @largeFileMode, @config, @assert, @grammarRegistry, @packageManager, @displayLayer - } = 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? @@ -163,7 +156,7 @@ class TextEditor extends Model @buffer ?= new TextBuffer @tokenizedBuffer ?= new TokenizedBuffer({ - tabLength, @buffer, @largeFileMode, @config, + @tabLength, @buffer, @largeFileMode, @config, @grammarRegistry, @packageManager, @assert }) @displayLayer ?= @buffer.addDisplayLayer() @@ -596,7 +589,7 @@ class TextEditor extends Model softTabs = @getSoftTabs() newEditor = new TextEditor({ @buffer, selectionsMarkerLayer, @tabLength, softTabs, - suppressCursorCreation: true, @config, @notificationManager, @packageManager, + suppressCursorCreation: true, @config, @packageManager, @firstVisibleScreenRow, @firstVisibleScreenColumn, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate, displayLayer @@ -3023,13 +3016,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() tokenForBufferPosition: (bufferPosition) -> @tokenizedBuffer.tokenForPosition(bufferPosition) 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)