Socket
Socket
Sign inDemoInstall

nuclide-commons-atom

Package Overview
Dependencies
Maintainers
5
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nuclide-commons-atom - npm Package Compare versions

Comparing version 0.7.1 to 0.7.2

__atom_tests__/ActiveEditorRegistry-test.js

308

ActiveEditorRegistry.js

@@ -1,146 +0,119 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _RxMin = require("rxjs/bundles/Rx.min.js");
function _debounced() {
const data = require("./debounced");
_debounced = function () {
return data;
};
return data;
}
function _UniversalDisposable() {
const data = _interopRequireDefault(require("nuclide-commons/UniversalDisposable"));
_UniversalDisposable = function () {
return data;
};
return data;
}
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
function _observable() {
const data = require("nuclide-commons/observable");
_observable = function () {
return data;
};
return data;
}
function _log4js() {
const data = require("log4js");
var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _debounced;
_log4js = function () {
return data;
};
function _load_debounced() {return _debounced = require('./debounced');}var _UniversalDisposable;
return data;
}
function _paneItem() {
const data = require("./pane-item");
_paneItem = function () {
return data;
};
return data;
}
function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _event;
function _load_event() {return _event = require('nuclide-commons/event');}var _observable;
function _load_observable() {return _observable = require('nuclide-commons/observable');}var _log4js;
function _ProviderRegistry() {
const data = _interopRequireDefault(require("./ProviderRegistry"));
function _load_log4js() {return _log4js = require('log4js');}var _ProviderRegistry;
_ProviderRegistry = function () {
return data;
};
function _load_ProviderRegistry() {return _ProviderRegistry = _interopRequireDefault(require('./ProviderRegistry'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict-local
* @format
*/
/**
* ActiveEditorRegistry provides abstractions for creating services that operate
* on text editor contents.
*/
const DEFAULT_CONFIG = {
updateOnEdit: true }; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/ /**
* ActiveEditorRegistry provides abstractions for creating services that operate
* on text editor contents.
*/function getConcreteConfig(config) {return Object.assign({}, DEFAULT_CONFIG, config);}class ActiveEditorRegistry {
updateOnEdit: true
};
function getConcreteConfig(config) {
return Object.assign({}, DEFAULT_CONFIG, config);
}
constructor(
resultFunction,
config = {},
eventSources = {})
{
class ActiveEditorRegistry {
constructor(resultFunction, config = {}, eventSources = {}) {
this._config = getConcreteConfig(config);
this._resultFunction = resultFunction;
this._providerRegistry = new (_ProviderRegistry || _load_ProviderRegistry()).default();
this._newProviderEvents = new _rxjsBundlesRxMinJs.Subject();
this._providerRegistry = new (_ProviderRegistry().default)();
this._newProviderEvents = new _RxMin.Subject();
this._resultsStream = this._createResultsStream({
activeEditors:
eventSources.activeEditors || (0, (_debounced || _load_debounced()).observeActiveEditorsDebounced)(),
changesForEditor:
eventSources.changesForEditor || (
editor => (0, (_debounced || _load_debounced()).editorChangesDebounced)(editor)),
savesForEditor:
eventSources.savesForEditor || (
editor => {
return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback =>
editor.onDidSave(callback)).
mapTo(undefined);
}) });
activeEditors: eventSources.activeEditors || (0, _debounced().observeActiveEditorsDebounced)(),
changesForEditor: eventSources.changesForEditor || (editor => (0, _debounced().editorChangesDebounced)(editor)),
savesForEditor: eventSources.savesForEditor || (editor => {
return (0, _event().observableFromSubscribeFunction)(callback => editor.onDidSave(callback)).mapTo(undefined);
})
});
}

@@ -150,4 +123,6 @@

this._providerRegistry.addProvider(provider);
this._newProviderEvents.next();
return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {
return new (_UniversalDisposable().default)(() => {
this._providerRegistry.removeProvider(provider);

@@ -164,8 +139,6 @@ });

if (editor == null) {
return _rxjsBundlesRxMinJs.Observable.of(editor);
return _RxMin.Observable.of(editor);
}
return _rxjsBundlesRxMinJs.Observable.concat(
_rxjsBundlesRxMinJs.Observable.of(editor),
this._newProviderEvents.mapTo(editor));
return _RxMin.Observable.concat(_RxMin.Observable.of(editor), this._newProviderEvents.mapTo(editor));
});

@@ -175,48 +148,44 @@ const results = repeatedEditors.switchMap(editorArg => {

const editor = editorArg;
if (editor == null) {
return _rxjsBundlesRxMinJs.Observable.of({ kind: 'not-text-editor' });
return _RxMin.Observable.of({
kind: 'not-text-editor'
});
}
return _rxjsBundlesRxMinJs.Observable.concat(
// Emit a pane change event first, so that clients can do something while waiting for a
return _RxMin.Observable.concat( // Emit a pane change event first, so that clients can do something while waiting for a
// provider to give a result.
_rxjsBundlesRxMinJs.Observable.of({
_RxMin.Observable.of({
kind: 'pane-change',
editor }),
_rxjsBundlesRxMinJs.Observable.fromPromise(
this._getResultForEditor(this._getProviderForEditor(editor), editor)),
this._resultsForEditor(editor, eventSources));
editor
}), // wait for pending panes to no longer be pending, or if they're not,
// get the result right away.
((0, _paneItem().isPending)(editor) ? (0, _paneItem().observePendingStateEnd)(editor).take(1) : _RxMin.Observable.of(null)).ignoreElements(), _RxMin.Observable.fromPromise(this._getResultForEditor(this._getProviderForEditor(editor), editor)), this._resultsForEditor(editor, eventSources));
});
return (0, (_observable || _load_observable()).cacheWhileSubscribed)(results);
return (0, _observable().cacheWhileSubscribed)(results);
}
_resultsForEditor(
editor,
eventSources)
{
_resultsForEditor(editor, eventSources) {
// It's possible that the active provider for an editor changes over time.
// Thus, we have to subscribe to both edits and saves.
return _rxjsBundlesRxMinJs.Observable.merge(
eventSources.changesForEditor(editor).map(() => 'edit'),
eventSources.savesForEditor(editor).map(() => 'save')).
flatMap(event => {
return _RxMin.Observable.merge(eventSources.changesForEditor(editor).map(() => 'edit'), eventSources.savesForEditor(editor).map(() => 'save')).flatMap(event => {
const provider = this._getProviderForEditor(editor);
if (provider != null) {
let updateOnEdit = provider.updateOnEdit;
// Fall back to the config's updateOnEdit if not provided.
let updateOnEdit = provider.updateOnEdit; // Fall back to the config's updateOnEdit if not provided.
if (updateOnEdit == null) {
updateOnEdit = this._config.updateOnEdit;
}
if (updateOnEdit !== (event === 'edit')) {
return _rxjsBundlesRxMinJs.Observable.empty();
return _RxMin.Observable.empty();
}
}
return _rxjsBundlesRxMinJs.Observable.concat(
// $FlowIssue: {kind: edit | save} <=> {kind: edit} | {kind: save}
_rxjsBundlesRxMinJs.Observable.of({ kind: event, editor }),
_rxjsBundlesRxMinJs.Observable.fromPromise(this._getResultForEditor(provider, editor)));
return _RxMin.Observable.concat( // $FlowIssue: {kind: edit | save} <=> {kind: edit} | {kind: save}
_RxMin.Observable.of({
kind: event,
editor
}), _RxMin.Observable.fromPromise(this._getResultForEditor(provider, editor)));
});

@@ -229,29 +198,28 @@ }

_getResultForEditor(
provider,
editor)
{var _this = this;return (0, _asyncToGenerator.default)(function* () {
if (provider == null) {
return {
kind: 'no-provider',
grammar: editor.getGrammar() };
async _getResultForEditor(provider, editor) {
if (provider == null) {
return {
kind: 'no-provider',
grammar: editor.getGrammar()
};
}
}
try {
return {
kind: 'result',
result: yield _this._resultFunction(provider, editor),
provider,
editor };
try {
return {
kind: 'result',
result: await this._resultFunction(provider, editor),
provider,
editor
};
} catch (e) {
(0, _log4js().getLogger)(this.constructor.name).error(`Error from provider for ${editor.getGrammar().scopeName}`, e);
return {
provider,
kind: 'provider-error'
};
}
}
} catch (e) {
(0, (_log4js || _load_log4js()).getLogger)(_this.constructor.name).error(
`Error from provider for ${editor.getGrammar().scopeName}`,
e);
}
return {
provider,
kind: 'provider-error' };
}})();
}}exports.default = ActiveEditorRegistry;
exports.default = ActiveEditorRegistry;

@@ -1,34 +0,33 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = consumeFirstProvider;
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
consumeFirstProvider; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/ /**
* The module formerly known as "service-hub-plus". Provides a workaround for
* https://github.com/atom/service-hub/issues/6
*/function consumeFirstProvider(keyPath, version = '0.0.0') {return new Promise((resolve, reject) => {const subscription = atom.packages.serviceHub.consume(keyPath, version, provider => {process.nextTick(() => {resolve(provider);subscription.dispose();});});
/**
* The module formerly known as "service-hub-plus". Provides a workaround for
* https://github.com/atom/service-hub/issues/6
*/
function consumeFirstProvider(keyPath, version = '0.0.0') {
return new Promise((resolve, reject) => {
const subscription = atom.packages.serviceHub.consume(keyPath, version, provider => {
process.nextTick(() => {
resolve(provider);
subscription.dispose();
});
});
});
}

@@ -1,311 +0,274 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.showMenuForEvent = showMenuForEvent;
exports.default = void 0;
function _UniversalDisposable() {
const data = _interopRequireDefault(require("nuclide-commons/UniversalDisposable"));
_UniversalDisposable = function () {
return data;
};
return data;
}
var _electron = require("electron");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
/**
* This class represents a collection of context menu items that have been registered with Atom's
* ContextMenuManager under a single CSS selector. These items are ordered based on the specified
* priority with which they are added to this object. (The CSS selector is either specified
* explicitly via the `cssSelector` property of the RootMenuOptions passed to the constructor, or
* implicitly via the `parent` property of the SubmenuOptions passed to the constructor.)
*
* This is in contrast to Atom's ContextMenuManager, which relies on the specificity of the CSS
* selector for a menu item to determine its precedence. The motivation behind this approach is to
* provide a total order on menu item ordering rather than a partial order. As such, this class
* serves as an adapter between the numeric priority model and ContextMenuManager's model.
*
* Note that this class also provides support for submenu items. This requires Atom 1.6 or later
* because it relies on this fix: https://github.com/atom/atom/pull/10486.
*/
class ContextMenu {
/**
* List of items that have been added to this context menu in the order they were added.
* Note that this list does not get sorted: only a filtered version of it does.
* Further, this list is mutated heavily, but it is never reassigned.
*/
/**
* This is the Disposable that represents adding all of this object's menu items to Atom's own
* ContextMenuManager. When a new item is added to this object, we must remove all of the items
* that we previously added to the ContextMenuManager and then re-add them based on the new
* ordering of priorities that results from the new item.
*/
constructor(menuOptions) {
this._menuOptions = menuOptions;
this._items = [];
this._needsSort = false;
this._sort = this._sort.bind(this);
this._disposable = null;
}
/**
* @return true if this menu does not contain any items; otherwise, returns false. Note this will
* return true if it contains only empty submenu items.
*/
isEmpty() {
return this._items.length === 0;
}
/**
* Adds the specified item to this contenxt menu.
*
* Items with lower priority values appear earlier in the context menu
* (i.e., items appear in numerical order with respect to priority).
*
* @return object whose dispose() method can be used to remove the menu item from this object.
*/
addItem(item, priority) {
const value = {
type: 'item',
item,
priority
};
return this._addItemToList(value);
}
/**
* Adds the specified submenu to this contenxt menu.
*
* Items with lower priority values appear earlier in the context menu
* (i.e., items appear in numerical order with respect to priority).
*
* @return object whose dispose() method can be used to remove the submenu from this object.
*/
addSubmenu(contextMenu, priority) {
const value = {
type: 'menu',
menu: contextMenu,
priority
};
return this._addItemToList(value);
}
_addItemToList(value) {
this._items.push(value);
this._needsSort = true;
process.nextTick(this._sort); // TODO(mbolin): Ideally, this Disposable should be garbage-collected if this ContextMenu is
// disposed.
return new (_UniversalDisposable().default)(() => {
const index = this._items.indexOf(value);
this._items.splice(index, 1); // We need to invoke _sort for the management of this._disposable and atom.contextMenu.add.
this._needsSort = true;
this._sort();
});
}
/**
* This method must be invoked after this._items has been modified. If necessary, it will remove
* all items that this object previously registered with Atom's ContextMenuManager. Then it will
* re-register everything in this._items once it has been sorted.
*/
_sort() {
if (!this._needsSort) {
return;
}
this._needsSort = false;
if (this._disposable != null) {
this._disposable.dispose();
}
const menuOptions = this._menuOptions;
if (menuOptions.type === 'root') {
const items = this._sortAndFilterItems();
this._disposable = atom.contextMenu.add({
[menuOptions.cssSelector]: items.map(this._contextMenuItemForInternalItem, this)
});
} else if (menuOptions.type === 'submenu') {
// Tell the parent menu to sort itself.
menuOptions.parent._needsSort = true;
menuOptions.parent._sort();
}
}
/** Translates this object's internal representation of a menu item to Atom's representation. */
_contextMenuItemForInternalItem(internalItem) {
if (internalItem.type === 'item') {
return internalItem.item;
} else if (internalItem.type === 'menu') {
// Note that due to our own strict renaming rules, this must be a private method instead of a
// static function because of the access to _menuOptions and _items.
const menuOptions = internalItem.menu._menuOptions;
if (!(menuOptions.type === 'submenu')) {
throw new Error("Invariant violation: \"menuOptions.type === 'submenu'\"");
}
const items = internalItem.menu._sortAndFilterItems();
return {
label: menuOptions.label,
submenu: items.map(this._contextMenuItemForInternalItem, this),
shouldDisplay: menuOptions.shouldDisplay
};
} else {
if (!false) {
throw new Error("Invariant violation: \"false\"");
}
}
}
_sortAndFilterItems() {
const items = this._items.filter(item => {
if (item.type === 'item') {
return true;
} else if (item.type === 'menu') {
const contextMenu = item.menu;
return !contextMenu.isEmpty();
}
});
items.sort(compareInternalItems);
return items;
}
/** Removes all items this object has added to Atom's ContextMenuManager. */
dispose() {
this._needsSort = false;
if (this._disposable != null) {
this._disposable.dispose();
}
this._items.length = 0;
}
static isEventFromContextMenu(event) {
// Context menu commands contain a specific `detail` parameter:
// https://github.com/atom/atom/blob/v1.15.0/src/main-process/context-menu.coffee#L17
return (// $FlowFixMe(>=0.68.0) Flow suppress (T27187857)
Array.isArray(event.detail) && // flowlint-next-line sketchy-null-mixed:off
event.detail[0] && event.detail[0].contextCommand
);
}
}
/** Comparator used to sort menu items by priority: lower priorities appear earlier. */
exports.default = ContextMenu;
function compareInternalItems(a, b) {
return a.priority - b.priority;
}
/**
* Shows the provided menu template. This will result in [an extra call to `templateForEvent()`][1],
* but it means that we still go through `showMenuForEvent()`, maintaining its behavior wrt
* (a)synchronousness. See atom/atom#13398.
*
* [1]: https://github.com/atom/atom/blob/v1.13.0/src/context-menu-manager.coffee#L200
*/
function showMenuForEvent(event, menuTemplate) {
if (!(_electron.remote != null)) {
throw new Error("Invariant violation: \"remote != null\"");
}
const win = _electron.remote.getCurrentWindow();
const originalEmit = win.emit;
const restore = () => {
win.emit = originalEmit;
};
win.emit = (eventType, ...args) => {
if (eventType !== 'context-menu') {
return originalEmit(eventType, ...args);
}
const result = originalEmit('context-menu', menuTemplate);
restore();
return result;
};
showMenuForEvent = showMenuForEvent;var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _electron = require('electron');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /**
* This class represents a collection of context menu items that have been registered with Atom's
* ContextMenuManager under a single CSS selector. These items are ordered based on the specified
* priority with which they are added to this object. (The CSS selector is either specified
* explicitly via the `cssSelector` property of the RootMenuOptions passed to the constructor, or
* implicitly via the `parent` property of the SubmenuOptions passed to the constructor.)
*
* This is in contrast to Atom's ContextMenuManager, which relies on the specificity of the CSS
* selector for a menu item to determine its precedence. The motivation behind this approach is to
* provide a total order on menu item ordering rather than a partial order. As such, this class
* serves as an adapter between the numeric priority model and ContextMenuManager's model.
*
* Note that this class also provides support for submenu items. This requires Atom 1.6 or later
* because it relies on this fix: https://github.com/atom/atom/pull/10486.
*/ /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/class ContextMenu {/**
* List of items that have been added to this context menu in the order they were added.
* Note that this list does not get sorted: only a filtered version of it does.
* Further, this list is mutated heavily, but it is never reassigned.
*/constructor(menuOptions) {this._menuOptions = menuOptions;this._items = [];this._needsSort = false;this._sort = this._sort.bind(this);this._disposable = null;} /**
* @return true if this menu does not contain any items; otherwise, returns false. Note this will
* return true if it contains only empty submenu items.
*/ /**
* This is the Disposable that represents adding all of this object's menu items to Atom's own
* ContextMenuManager. When a new item is added to this object, we must remove all of the items
* that we previously added to the ContextMenuManager and then re-add them based on the new
* ordering of priorities that results from the new item.
*/isEmpty() {return this._items.length === 0;} /**
* Adds the specified item to this contenxt menu.
*
* Items with lower priority values appear earlier in the context menu
* (i.e., items appear in numerical order with respect to priority).
*
* @return object whose dispose() method can be used to remove the menu item from this object.
*/addItem(item, priority) {const value = { type: 'item', item, priority };return this._addItemToList(value);} /**
* Adds the specified submenu to this contenxt menu.
*
* Items with lower priority values appear earlier in the context menu
* (i.e., items appear in numerical order with respect to priority).
*
* @return object whose dispose() method can be used to remove the submenu from this object.
*/addSubmenu(contextMenu, priority) {const value = { type: 'menu', menu: contextMenu, priority };return this._addItemToList(value);}_addItemToList(value) {this._items.push(value);this._needsSort = true;process.nextTick(this._sort); // TODO(mbolin): Ideally, this Disposable should be garbage-collected if this ContextMenu is
// disposed.
return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {const index = this._items.indexOf(value);this._items.splice(index, 1); // We need to invoke _sort for the management of this._disposable and atom.contextMenu.add.
this._needsSort = true;this._sort();});} /**
* This method must be invoked after this._items has been modified. If necessary, it will remove
* all items that this object previously registered with Atom's ContextMenuManager. Then it will
* re-register everything in this._items once it has been sorted.
*/_sort() {if (!this._needsSort) {return;}this._needsSort = false;if (this._disposable != null) {this._disposable.dispose();}const menuOptions = this._menuOptions;if (menuOptions.type === 'root') {const items = this._sortAndFilterItems();this._disposable = atom.contextMenu.add({ [menuOptions.cssSelector]: items.map(this._contextMenuItemForInternalItem, this) });} else if (menuOptions.type === 'submenu') {// Tell the parent menu to sort itself.
menuOptions.parent._needsSort = true;menuOptions.parent._sort();}} /** Translates this object's internal representation of a menu item to Atom's representation. */_contextMenuItemForInternalItem(internalItem) {if (internalItem.type === 'item') {return internalItem.item;} else if (internalItem.type === 'menu') {// Note that due to our own strict renaming rules, this must be a private method instead of a
// static function because of the access to _menuOptions and _items.
const menuOptions = internalItem.menu._menuOptions;if (!(menuOptions.type === 'submenu')) {throw new Error('Invariant violation: "menuOptions.type === \'submenu\'"');}const items = internalItem.menu._sortAndFilterItems();return { label: menuOptions.label, submenu: items.map(this._contextMenuItemForInternalItem, this), shouldDisplay: menuOptions.shouldDisplay };} else {if (!false) {throw new Error('Invariant violation: "false"');}}}_sortAndFilterItems() {const items = this._items.filter(item => {if (item.type === 'item') {return true;} else if (item.type === 'menu') {const contextMenu = item.menu;return !contextMenu.isEmpty();}});items.sort(compareInternalItems);return items;} /** Removes all items this object has added to Atom's ContextMenuManager. */dispose() {this._needsSort = false;if (this._disposable != null) {this._disposable.dispose();}this._items.length = 0;}static isEventFromContextMenu(event) {// Context menu commands contain a specific `detail` parameter:
// https://github.com/atom/atom/blob/v1.15.0/src/main-process/context-menu.coffee#L17
return (// $FlowFixMe(>=0.68.0) Flow suppress (T27187857)
Array.isArray(event.detail) && // flowlint-next-line sketchy-null-mixed:off
event.detail[0] && event.detail[0].contextCommand);}}exports.default = ContextMenu; /** Comparator used to sort menu items by priority: lower priorities appear earlier. */function compareInternalItems(a, b) {return a.priority - b.priority;} /**
* Shows the provided menu template. This will result in [an extra call to `templateForEvent()`][1],
* but it means that we still go through `showMenuForEvent()`, maintaining its behavior wrt
* (a)synchronousness. See atom/atom#13398.
*
* [1]: https://github.com/atom/atom/blob/v1.13.0/src/context-menu-manager.coffee#L200
*/function showMenuForEvent(event, menuTemplate) {if (!(_electron.remote != null)) {throw new Error('Invariant violation: "remote != null"');}const win = _electron.remote.getCurrentWindow();const originalEmit = win.emit;const restore = () => {win.emit = originalEmit;};win.emit = (eventType, ...args) => {if (eventType !== 'context-menu') {return originalEmit(eventType, ...args);}const result = originalEmit('context-menu', menuTemplate);restore();return result;};atom.contextMenu.showForEvent(event);return new (_UniversalDisposable || _load_UniversalDisposable()).default(restore);}
atom.contextMenu.showForEvent(event);
return new (_UniversalDisposable().default)(restore);
}

@@ -1,26 +0,29 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createPaneContainer;
createPaneContainer; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function createPaneContainer() {const instance = typeof atom.workspace.getCenter === 'function' ? atom.workspace.getCenter().paneContainer : atom.workspace.paneContainer;const PaneContainer = instance.constructor;return new PaneContainer({ viewRegistry: atom.views, config: atom.config, applicationDelegate: atom.applicationDelegate, notificationManager: atom.notifications,
deserializerManager: atom.deserializers });
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
function createPaneContainer() {
const instance = typeof atom.workspace.getCenter === 'function' ? atom.workspace.getCenter().paneContainer : atom.workspace.paneContainer;
const PaneContainer = instance.constructor;
return new PaneContainer({
viewRegistry: atom.views,
config: atom.config,
applicationDelegate: atom.applicationDelegate,
notificationManager: atom.notifications,
deserializerManager: atom.deserializers
});
}

@@ -1,102 +0,117 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createPackage;
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
/**
* Create an Atom package from an Activation constructor.
*
* Atom packages are obstensibly singletons, however they contain `activate()` and `deactivate()`
* lifecycle methods which can be called multiple times. There's no use-case (so far as we know) for
* invoking any other package methods while a package is not activated. Therefore, it makes more
* sense to build packages as instances, constructed when a package is activated and destroyed when
* the package is deactivated.
*
* Atom uses a plain `require` to load the module, and not babel's `require` interop. So if
* `createPackage` were used as `export default createPackage(..)`, then Atom wouldn't be
* able to find any package methods because the ES Module transform would output
* `module.exports.default = {..};`. To workaround this, the module's `module.exports` is passed
* to `createPackage` so we can attach whatever properties to it.
*
* It was a conscious decision to use `createPackage(module.exports, Activation)` instead of
* `module.exports = createPackage(Activation)`, to avoid code style misunderstandings wrt
* CommonJS vs ES Modules.
*/
function createPackage(moduleExports, Activation) {
let activation = null; // Proxy method calls on the package to the activation object.
for (const property of getPropertyList(Activation.prototype)) {
if (typeof Activation.prototype[property] !== 'function') {
continue;
}
if (property === 'constructor') {
continue;
}
if (property === 'initialize') {
throw new Error('Your activation class contains an "initialize" method, but that work should be done in the' + ' constructor.');
}
createPackage; /**
* Create an Atom package from an Activation constructor.
*
* Atom packages are obstensibly singletons, however they contain `activate()` and `deactivate()`
* lifecycle methods which can be called multiple times. There's no use-case (so far as we know) for
* invoking any other package methods while a package is not activated. Therefore, it makes more
* sense to build packages as instances, constructed when a package is activated and destroyed when
* the package is deactivated.
*
* Atom uses a plain `require` to load the module, and not babel's `require` interop. So if
* `createPackage` were used as `export default createPackage(..)`, then Atom wouldn't be
* able to find any package methods because the ES Module transform would output
* `module.exports.default = {..};`. To workaround this, the module's `module.exports` is passed
* to `createPackage` so we can attach whatever properties to it.
*
* It was a conscious decision to use `createPackage(module.exports, Activation)` instead of
* `module.exports = createPackage(Activation)`, to avoid code style misunderstandings wrt
* CommonJS vs ES Modules.
*/function createPackage(moduleExports, Activation) {let activation = null; // Proxy method calls on the package to the activation object.
for (const property of getPropertyList(Activation.prototype)) {if (typeof Activation.prototype[property] !== 'function') {continue;}if (property === 'constructor') {continue;}if (property === 'initialize') {throw new Error('Your activation class contains an "initialize" method, but that work should be done in the' + ' constructor.');}
if (property === 'deactivate') {
throw new Error(
'Your activation class contains an "deactivate" method. Please use "dispose" instead.');
throw new Error('Your activation class contains an "deactivate" method. Please use "dispose" instead.');
}
moduleExports[property] = function (...args) {if (!(
activation != null)) {throw new Error('Package not initialized');}
moduleExports[property] = function (...args) {
if (!(activation != null)) {
throw new Error('Package not initialized');
}
return activation[property](...args);
};
}
/**
* Calling `initialize()` creates a new instance.
*/
/**
* Calling `initialize()` creates a new instance.
*/
moduleExports.initialize = initialState => {if (!(
activation == null)) {throw new Error('Package already initialized');}
moduleExports.initialize = initialState => {
if (!(activation == null)) {
throw new Error('Package already initialized');
}
activation = new Activation(initialState);
};
/**
* The `deactivate()` method is special-cased to null our activation instance reference.
*/
/**
* The `deactivate()` method is special-cased to null our activation instance reference.
*/
moduleExports.deactivate = () => {if (!(
activation != null)) {throw new Error('Package not initialized');}
moduleExports.deactivate = () => {
if (!(activation != null)) {
throw new Error('Package not initialized');
}
if (typeof activation.dispose === 'function') {
activation.dispose();
}
activation = null;
};
} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function getPrototypeChain(prototype) {let currentPrototype = prototype;const prototypes = [];while (currentPrototype != null) {prototypes.push(currentPrototype);currentPrototype = Object.getPrototypeOf(currentPrototype);}return prototypes;}
}
function getPrototypeChain(prototype) {
let currentPrototype = prototype;
const prototypes = [];
while (currentPrototype != null) {
prototypes.push(currentPrototype);
currentPrototype = Object.getPrototypeOf(currentPrototype);
}
return prototypes;
}
/**
* List the properties (including inherited ones) of the provided prototype, excluding the ones
* inherited from `Object`.
*/
* List the properties (including inherited ones) of the provided prototype, excluding the ones
* inherited from `Object`.
*/
function getPropertyList(prototype) {
const properties = [];
for (const proto of getPrototypeChain(prototype)) {

@@ -106,2 +121,3 @@ if (proto === Object.prototype) {

}
for (const property of Object.getOwnPropertyNames(proto)) {

@@ -111,3 +127,4 @@ properties.push(property);

}
return properties;
}

@@ -1,110 +0,109 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.observeActivePaneItemDebounced = observeActivePaneItemDebounced;
exports.observeActiveEditorsDebounced = observeActiveEditorsDebounced;
exports.editorChangesDebounced = editorChangesDebounced;
exports.editorScrollTopDebounced = editorScrollTopDebounced;
exports.observeTextEditorsPositions = observeTextEditorsPositions;
function _observable() {
const data = require("nuclide-commons/observable");
_observable = function () {
return data;
};
return data;
}
var _RxMin = require("rxjs/bundles/Rx.min.js");
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
function _textEditor() {
const data = require("./text-editor");
_textEditor = function () {
return data;
};
return data;
}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
/**
* Often, we may want to respond to Atom events, but only after a buffer period
* of no change.
* For example, Atom provides Workspace::onDidChangeActivePaneItem, but we may
* want to know not when the active pane item has changed, buth when it has
* stopped changing.
* This file provides methods to do this.
*/
const DEFAULT_PANE_DEBOUNCE_INTERVAL_MS = 100;
const DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS = 300;
const DEFAULT_POSITION_DEBOUNCE_INTERVAL_MS = 300;
function observeActivePaneItemDebounced(debounceInterval = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS) {
return (0, _event().observableFromSubscribeFunction)(callback => {
if (atom.workspace.getCenter != null) {
return atom.workspace.getCenter().observeActivePaneItem(callback);
}
return atom.workspace.observeActivePaneItem(callback);
}).let((0, _observable().fastDebounce)(debounceInterval));
}
function observeActiveEditorsDebounced(debounceInterval = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS) {
return observeActivePaneItemDebounced(debounceInterval).map(paneItem => {
return (0, _textEditor().isValidTextEditor)(paneItem) ? paneItem : null;
});
}
function editorChangesDebounced(editor, debounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS) {
return (0, _event().observableFromSubscribeFunction)(callback => editor.getBuffer().onDidChangeText(() => callback())) // Debounce manually rather than using editor.onDidStopChanging so that the debounce time is
// configurable.
.let((0, _observable().fastDebounce)(debounceInterval));
}
function editorScrollTopDebounced(editor, debounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS) {
return (0, _event().observableFromSubscribeFunction)(callback => atom.views.getView(editor).onDidChangeScrollTop(callback)).let((0, _observable().fastDebounce)(debounceInterval));
}
// Yields null when the current pane is not an editor,
// otherwise yields events on each move of the primary cursor within any Editor.
function observeTextEditorsPositions(editorDebounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS, positionDebounceInterval = DEFAULT_POSITION_DEBOUNCE_INTERVAL_MS) {
return observeActiveEditorsDebounced(editorDebounceInterval).switchMap(editor => {
return editor == null ? _RxMin.Observable.of(null) : (0, _textEditor().getCursorPositions)(editor).let((0, _observable().fastDebounce)(positionDebounceInterval)).map(position => {
if (!(editor != null)) {
throw new Error("Invariant violation: \"editor != null\"");
}
observeActivePaneItemDebounced = observeActivePaneItemDebounced;exports.
observeActiveEditorsDebounced = observeActiveEditorsDebounced;exports.
editorChangesDebounced = editorChangesDebounced;exports.
editorScrollTopDebounced = editorScrollTopDebounced;exports.
observeTextEditorsPositions = observeTextEditorsPositions;var _observable;function _load_observable() {return _observable = require('nuclide-commons/observable');}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _textEditor;function _load_textEditor() {return _textEditor = require('./text-editor');} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/ /**
* Often, we may want to respond to Atom events, but only after a buffer period
* of no change.
* For example, Atom provides Workspace::onDidChangeActivePaneItem, but we may
* want to know not when the active pane item has changed, buth when it has
* stopped changing.
* This file provides methods to do this.
*/const DEFAULT_PANE_DEBOUNCE_INTERVAL_MS = 100;const DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS = 300;const DEFAULT_POSITION_DEBOUNCE_INTERVAL_MS = 300;function observeActivePaneItemDebounced(debounceInterval = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS) {return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => {if (atom.workspace.getCenter != null) {return atom.workspace.getCenter().observeActivePaneItem(callback);}return atom.workspace.observeActivePaneItem(callback);}).let((0, (_observable || _load_observable()).fastDebounce)(debounceInterval));}function observeActiveEditorsDebounced(debounceInterval = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS) {return observeActivePaneItemDebounced(debounceInterval).map(paneItem => {if ((0, (_textEditor || _load_textEditor()).isValidTextEditor)(paneItem)) {// Flow cannot understand the type refinement provided by the isValidTextEditor function,
// so we have to cast.
return paneItem;}return null;});}function editorChangesDebounced(editor, debounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS) {return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => editor.getBuffer().onDidChangeText(() => callback())) // Debounce manually rather than using editor.onDidStopChanging so that the debounce time is
// configurable.
.let((0, (_observable || _load_observable()).fastDebounce)(debounceInterval));}function editorScrollTopDebounced(editor, debounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS) {return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => atom.views.getView(editor).onDidChangeScrollTop(callback)).let((0, (_observable || _load_observable()).fastDebounce)(debounceInterval));} // Yields null when the current pane is not an editor,
// otherwise yields events on each move of the primary cursor within any Editor.
function observeTextEditorsPositions(editorDebounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS, positionDebounceInterval = DEFAULT_POSITION_DEBOUNCE_INTERVAL_MS) {return observeActiveEditorsDebounced(editorDebounceInterval).switchMap(editor => {return editor == null ? _rxjsBundlesRxMinJs.Observable.of(null) : (0, (_textEditor || _load_textEditor()).getCursorPositions)(editor).let((0, (_observable || _load_observable()).fastDebounce)(positionDebounceInterval)).map(position => {if (!(editor != null)) {throw new Error('Invariant violation: "editor != null"');}return { editor, position };});});}
return {
editor,
position
};
});
});
}

@@ -1,27 +0,33 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getDebuggerService = getDebuggerService;
function _consumeFirstProvider() {
const data = _interopRequireDefault(require("./consumeFirstProvider"));
_consumeFirstProvider = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
getDebuggerService = getDebuggerService;var _consumeFirstProvider;function _load_consumeFirstProvider() {return _consumeFirstProvider = _interopRequireDefault(require('./consumeFirstProvider'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function getDebuggerService() {return (0, (_consumeFirstProvider || _load_consumeFirstProvider()).default)('debugger.remote');}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict-local
* @format
*/
function getDebuggerService() {
return (0, _consumeFirstProvider().default)('debugger.remote');
}

@@ -1,23 +0,27 @@

"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.destroyItemWhere = destroyItemWhere;
destroyItemWhere = destroyItemWhere; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function destroyItemWhere(predicate) {atom.workspace.getPanes().forEach(pane => {pane.getItems().forEach(item => {if (predicate(item)) {pane.destroyItem(item, true);}});});}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict
* @format
*/
function destroyItemWhere(predicate) {
atom.workspace.getPanes().forEach(pane => {
pane.getItems().forEach(item => {
if (predicate(item)) {
pane.destroyItem(item, true);
}
});
});
}

@@ -1,25 +0,33 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = dockForLocation;
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict
* @format
*/
// Return the dock for a pane if the pane is in a dock (i.e. not in the center.)
function dockForLocation(location) {
switch (location) {
case 'bottom':
return atom.workspace.getBottomDock();
case 'left':
return atom.workspace.getLeftDock();
case 'right':
return atom.workspace.getRightDock();
}
dockForLocation; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/ // Return the dock for a pane if the pane is in a dock (i.e. not in the center.)
function dockForLocation(location) {switch (location) {case 'bottom':return atom.workspace.getBottomDock();case 'left':return atom.workspace.getLeftDock();case 'right':return atom.workspace.getRightDock();}return null;}
return null;
}

@@ -1,36 +0,44 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _RxMin = require("rxjs/bundles/Rx.min.js");
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
/**
* A wrapper over Atom's config functions for use with FeatureLoader.
* Each individual loaded package's config is a subconfig of the root package.
*/
let packageName = null;
/**
* Sets the root package name.
* This gets automatically called from FeatureLoader.
*/
function setPackageName(name) {
packageName = name;
}
function getPackageName() {
if (!(packageName != null)) {
throw new Error('No package name available');
}
return packageName;
}
var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/ /**
* A wrapper over Atom's config functions for use with FeatureLoader.
* Each individual loaded package's config is a subconfig of the root package.
*/let packageName = null; /**
* Sets the root package name.
* This gets automatically called from FeatureLoader.
*/function setPackageName(name) {packageName = name;}function getPackageName() {if (!(packageName != null)) {throw new Error('No package name available');}return packageName;}
function formatKeyPath(keyPath) {

@@ -40,142 +48,102 @@ if (packageName == null) {

}
return `${packageName}.${keyPath}`;
}
/*
* Returns the value of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.get` exception `keyPath` is not optional. To get the entire config object, use
* `atom.config.get`.
*
* Note: This is intentionally typed as mixed, this way each call site has to
* first cast it as any and it is obvious that this is an area that is not safe
* and flow will not proceed if the callsite doesn't do it.
*
* Example:
* const config: MyConfigType = (featureConfig.get('config-name'): any);
*/
function get(
keyPath,
options)
* Returns the value of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.get` exception `keyPath` is not optional. To get the entire config object, use
* `atom.config.get`.
*
* Note: This is intentionally typed as mixed, this way each call site has to
* first cast it as any and it is obvious that this is an area that is not safe
* and flow will not proceed if the callsite doesn't do it.
*
* Example:
* const config: MyConfigType = (featureConfig.get('config-name'): any);
*/
{
function get(keyPath, options) {
// atom.config.get will crash if the second arg is present and undefined.
// It does not crash if the second arg is missing.
return atom.config.get(
formatKeyPath(keyPath),
...(options == null ? [] : [options]));
return atom.config.get(formatKeyPath(keyPath), ...(options == null ? [] : [options]));
}
function getWithDefaults(
keyPath,
defaults,
options)
{
function getWithDefaults(keyPath, defaults, options) {
const current = get(keyPath, options);
return current == null ? defaults : current;
}
/*
* Gets the schema of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.getSchema`.
*/
/*
* Gets the schema of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.getSchema`.
*/
function getSchema(keyPath) {
return atom.config.getSchema(formatKeyPath(keyPath));
}
/*
* Similar to `atom.config.observe` except arguments are required, and options cannot be given.
*
* To observe changes on the entire config, use `atom.config.observe`.
*/
function observe(keyPath, optionsOrCallback, callback) {
return atom.config.observe(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1));
}
/*
* Similar to `atom.config.observe` except arguments are required, and options cannot be given.
*
* To observe changes on the entire config, use `atom.config.observe`.
*/
function observe(
keyPath,
callback)
{
return atom.config.observe(formatKeyPath(keyPath), callback);
}
* Behaves similarly to the `observe` function, but returns a stream of values, rather
* then receiving a callback.
*/
/*
* Behaves similarly to the `observe` function, but returns a stream of values, rather
* then receiving a callback.
*/
function observeAsStream(keyPath) {
return _rxjsBundlesRxMinJs.Observable.create(observer => {
const disposable = observe(keyPath, observer.next.bind(observer));
function observeAsStream(keyPath, options = {}) {
return _RxMin.Observable.create(observer => {
const disposable = observe(keyPath, options, observer.next.bind(observer));
return disposable.dispose.bind(disposable);
});
}
/*
* Takes and returns the same types as `atom.config.onDidChange` except `keyPath` is not optional.
* To listen to changes on all key paths, use `atom.config.onDidChange`.
*/
function onDidChange(
keyPath,
optionsOrCallback,
callback)
{
return atom.config.onDidChange(
formatKeyPath(keyPath),
...Array.prototype.slice.call(arguments, 1));
* Takes and returns the same types as `atom.config.onDidChange` except `keyPath` is not optional.
* To listen to changes on all key paths, use `atom.config.onDidChange`.
*/
function onDidChange(keyPath, optionsOrCallback, callback) {
return atom.config.onDidChange(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1));
}
/*
* Sets the value of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.set`.
*/
function set(
keyPath,
value,
options)
* Sets the value of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.set`.
*/
function set(keyPath, value, options) {
return atom.config.set(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1));
}
/*
* Sets the schema of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.setSchema`.
*/
{
return atom.config.set(
formatKeyPath(keyPath),
...Array.prototype.slice.call(arguments, 1));
}
/*
* Sets the schema of a setting for a Nuclide feature key. Takes and returns the same types as
* `atom.config.setSchema`.
*/
function setSchema(keyPath, schema) {
return atom.config.setSchema(
formatKeyPath(keyPath),
...Array.prototype.slice.call(arguments, 1));
return atom.config.setSchema(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1));
}
/*
* Restores a setting for a Nuclide feature key to its default value. Takes and returns the same
* types as `atom.config.set`.
*/
function unset(
keyPath,
options)
* Restores a setting for a Nuclide feature key to its default value. Takes and returns the same
* types as `atom.config.set`.
*/
function unset(keyPath, options) {
return atom.config.unset(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1));
}
/**
* Returns `true` if the feature with the given name is disabled either directly or because the
* container package itself is disabled.
*/
{
return atom.config.unset(
formatKeyPath(keyPath),
...Array.prototype.slice.call(arguments, 1));
}
/**
* Returns `true` if the feature with the given name is disabled either directly or because the
* container package itself is disabled.
*/
function isFeatureDisabled(name) {

@@ -185,9 +153,7 @@ if (packageName == null) {

}
return (
atom.packages.isPackageDisabled(packageName) ||
!atom.config.get(`${packageName}.use.${name}`));
}exports.default =
return atom.packages.isPackageDisabled(packageName) || !atom.config.get(`${packageName}.use.${name}`);
}
{
var _default = {
formatKeyPath,

@@ -205,2 +171,4 @@ setPackageName,

unset,
isFeatureDisabled };
isFeatureDisabled
};
exports.default = _default;

@@ -1,49 +0,74 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _idx;
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.INITIAL_FEATURE_GROUP = exports.REQUIRED_FEATURE_GROUP = void 0;
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
function _UniversalDisposable() {
const data = _interopRequireDefault(require("nuclide-commons/UniversalDisposable"));
_UniversalDisposable = function () {
return data;
};
return data;
}
function _nullthrows() {
const data = _interopRequireDefault(require("nullthrows"));
_nullthrows = function () {
return data;
};
return data;
}
function _activatePackages() {
const data = _interopRequireDefault(require("./experimental-packages/activatePackages"));
_activatePackages = function () {
return data;
};
return data;
}
function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _UniversalDisposable;
function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _nullthrows;
function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _featureConfig;
function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('./feature-config'));}
var _path2 = _interopRequireDefault(require('path'));var _collection;
function _load_collection() {return _collection = require('nuclide-commons/collection');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
function _featureConfig() {
const data = _interopRequireDefault(require("./feature-config"));
_featureConfig = function () {
return data;
};
return data;
}
var _path2 = _interopRequireDefault(require("path"));
function _collection() {
const data = require("nuclide-commons/collection");
_collection = function () {
return data;
};
return data;
}
var _RxMin = require("rxjs/bundles/Rx.min.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const ALWAYS_ENABLED = 'always'; // eslint-disable-line rulesdir/prefer-nuclide-uri
/**

@@ -59,34 +84,39 @@ * Copyright (c) 2017-present, Facebook, Inc.

* @format
*/ /* global localStorage */const NEVER_ENABLED = 'never';const DEFAULT = 'default';const { devMode } = atom.getLoadSettings();class FeatureLoader {
*/
/* global localStorage */
// eslint-disable-line nuclide-internal/prefer-nuclide-uri
const ALWAYS_ENABLED = 'always';
const NEVER_ENABLED = 'never';
const DEFAULT = 'default';
const {
devMode
} = atom.getLoadSettings();
const REQUIRED_FEATURE_GROUP = 'nuclide-required';
exports.REQUIRED_FEATURE_GROUP = REQUIRED_FEATURE_GROUP;
const INITIAL_FEATURE_GROUP = 'nuclide-core';
exports.INITIAL_FEATURE_GROUP = INITIAL_FEATURE_GROUP;
constructor({ features, path: _path, featureGroups }) {this._featureGroupMap = new (_collection || _load_collection()).MultiMap();this._currentPackageState = new Set();
class FeatureLoader {
constructor({
features,
path: _path,
featureGroups
}) {
this._deferringFeatureActivation = true;
this._currentlyActiveFeatures = new Set();
this._path = _path;
this._features = features;
this._loadDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default();
this._features = reorderFeatures(features);
this._loadDisposable = new (_UniversalDisposable().default)();
this._pkgName = packageNameFromPath(this._path);
this._featureGroups = featureGroups == null ? {} : featureGroups;
this._featureGroups = groupFeatures(this._features, featureGroups == null ? {} : featureGroups);
} // Build the config. Should occur with root package's load
// Constructs the map from feature groups to features.
this.constructFeatureGroupMap();
this._config = {
use: {
title: 'Enabled Features',
description: 'Enable and disable individual features',
type: 'object',
collapsed: true,
properties: {} } };
load() {
if (!!this._loadDisposable.disposed) {
throw new Error("Invariant violation: \"!this._loadDisposable.disposed\"");
}
}
// Build the config. Should occur with root package's load
load() {if (!
!this._loadDisposable.disposed) {throw new Error('Invariant violation: "!this._loadDisposable.disposed"');}
// Add a dummy deserializer. This forces Atom to load Nuclide's main module
patchPackageManager(); // Add a dummy deserializer. This forces Atom to load Nuclide's main module
// (this file) when the package is loaded, which is super important because

@@ -101,10 +131,11 @@ // this module loads all of the Nuclide features. We could accomplish the same

// [1] https://github.com/atom/atom/blob/v1.9.8/src/package.coffee#L442
this._loadDisposable.add(
atom.deserializers.add({
this._loadDisposable.add(atom.deserializers.add({
name: `${this._pkgName}.ForceMainModuleLoad`,
deserialize() {} }));
deserialize() {}
}));
//
_featureConfig().default.setPackageName(this._pkgName); //
// Build the "config" object. This determines the config defaults and

@@ -117,255 +148,175 @@ // it's what is shown by the Settings view. It includes:

//
this._features.forEach(feature => {
const featurePkg = feature.pkg;
const name = packageNameFromPath(feature.path);
// Migrate the current feature (from boolean on/off to enumerated states).
this.migrateFeature(feature);
const setting = {
title:
featurePkg.displayName == null ?
`Enable the "${name}" feature` :
`Enable ${featurePkg.displayName}`,
description: featurePkg.description || '',
type: 'string',
enum: [
{ value: ALWAYS_ENABLED, description: 'Always enabled' },
{ value: NEVER_ENABLED, description: 'Never enabled' },
{
value: DEFAULT,
description: 'Only when in an enabled package group' }],
this._config = buildConfig(this._features); // Load enabled features. This needs to be done during Atom's load phase to
// make sure that deserializers are registered, etc.
// https://github.com/atom/atom/blob/v1.1.0/src/atom-environment.coffee#L625-L631
// https://atom.io/docs/api/latest/PackageManager
const featuresToLoad = this.getEnabledFeatures();
default: getFeatureDefaultValue(feature) };
this._loadDisposable.add( // Nesting loads within loads leads to reverse activation order- that is, if
// the root package loads feature packages, then the feature package activations will
// happen before the root package's. So we wait until the root package is done loading,
// but before it activates, to load the features.
didLoadPackage(this._pkgName).subscribe(() => {
// Load "regular" feature packages.
featuresToLoad.forEach(feature => {
atom.packages.loadPackage(feature.path);
});
}), // Load "experimental" format packages.
didLoadPackage(this._pkgName).switchMap(() => _RxMin.Observable.create(() => new (_UniversalDisposable().default)((0, _activatePackages().default)([...featuresToLoad])))).subscribe());
const featureNames = new Set(this._features.map(feature => feature.pkg.name)); // Ensure that the root package is initialized before all of its features. This is important
// because the root package defines the config for all managed features and we need to make
// sure that it's present before they're initialized (i.e. before their deserializers are
// called).
// $FlowIssue: Need to upstream this.
if (devMode) {
if (featurePkg.providedServices) {
const provides = Object.keys(featurePkg.providedServices).join(', ');
setting.description += `<br/>**Provides:** _${provides}_`;
}
if (featurePkg.consumedServices) {
const consumes = Object.keys(featurePkg.consumedServices).join(', ');
setting.description += `<br/>**Consumes:** _${consumes}_`;
}
const onWillInitializePackageDisposable = atom.packages.onWillInitializePackage(pack => {
if (featureNames.has(pack.name)) {
onWillInitializePackageDisposable.dispose();
const rootPackage = atom.packages.getLoadedPackage(this._pkgName);
(0, _nullthrows().default)(rootPackage).initializeIfNeeded();
}
});
this._config.use.properties[name] = setting;
this._loadDisposable.add(onWillInitializePackageDisposable); // Clean up when the package is unloaded.
// Merge in the feature's config
const featurePkgConfig =
featurePkg.atomConfig ||
featurePkg.nuclide && featurePkg.nuclide.config;
if (featurePkgConfig) {
this._config[name] = {
type: 'object',
title: featurePkg.displayName,
description: featurePkg.description,
collapsed: true,
properties: {} };
Object.keys(featurePkgConfig).forEach(key => {
this._config[name].properties[key] = Object.assign({},
featurePkgConfig[key], {
title: featurePkgConfig[key].title || key });
});
this._loadDisposable.add(atom.packages.onDidUnloadPackage(pack => {
if (pack.name === this._pkgName) {
this._loadDisposable.dispose();
}
});
}));
}
(_featureConfig || _load_featureConfig()).default.setPackageName(this._pkgName);
activate() {
if (!(this._activationDisposable == null)) {
throw new Error("Invariant violation: \"this._activationDisposable == null\"");
}
// Nesting loads within loads leads to reverse activation order- that is, if
// the root package loads feature packages, then the feature package activations will
// happen before the root package's. So we wait until the root package is done loading,
// but before it activates, to load the features.
const initialLoadDisposable = atom.packages.onDidLoadPackage(pack => {
if (pack.name !== this._pkgName) {
return;
}
const rootPackage = atom.packages.getLoadedPackage(this._pkgName);
// Load all the features. This needs to be done during Atom's load phase to
// make sure that deserializers are registered, etc.
// https://github.com/atom/atom/blob/v1.1.0/src/atom-environment.coffee#L625-L631
// https://atom.io/docs/api/latest/PackageManager
this._features.forEach(feature => {
if (this.shouldEnable(feature)) {
atom.packages.loadPackage(feature.path);
}
});if (!(
initialLoadDisposable != null)) {throw new Error('Invariant violation: "initialLoadDisposable != null"');}
this._loadDisposable.remove(initialLoadDisposable);
initialLoadDisposable.dispose();
});
this._loadDisposable.add(initialLoadDisposable);
}
activate() {if (!(
this._activationDisposable == null)) {throw new Error('Invariant violation: "this._activationDisposable == null"');}
const rootPackage = atom.packages.getLoadedPackage(this._pkgName);if (!(
rootPackage != null)) {throw new Error('Invariant violation: "rootPackage != null"');}
// This is a failsafe in case the `.ForceMainModuleLoad` deserializer
if (!(rootPackage != null)) {
throw new Error("Invariant violation: \"rootPackage != null\"");
} // This is a failsafe in case the `.ForceMainModuleLoad` deserializer
// defined above does not register in time, or if the defer key has been set
// w/o our knowledge. This can happen during OSS upgrades.
localStorage.removeItem(
rootPackage.getCanDeferMainModuleRequireStorageKey());
// Hack time!! Atom's repository APIs are synchronous. Any package that tries to use them before
// we've had a chance to provide our implementation are going to get wrong answers. The correct
// thing to do would be to always go through an async API that awaits until
// `atom.packages.onDidActivateInitialPackages()` completes. However, we have some legacy sync
// codepaths that make that difficult. As a temporary (I hope) workaround, we prioritize
// activation of the features that provide this service.
const originalOrder = new Map(
this._features.map((feature, i) => [feature, i]));
localStorage.removeItem(rootPackage.getCanDeferMainModuleRequireStorageKey());
this.updateActiveFeatures(); // Watch things that should trigger reevaluation of active features. Note that we do this
// *after* the initial `updateActiveFeatures()` call because that could trigger one of these
// events.
this._features.sort((a, b) => {
const aIsRepoProvider = packageIsRepositoryProvider(a.pkg);
const bIsRepoProvider = packageIsRepositoryProvider(b.pkg);
if (aIsRepoProvider !== bIsRepoProvider) {
return aIsRepoProvider ? -1 : 1;
}
const aIndex = (0, (_nullthrows || _load_nullthrows()).default)(originalOrder.get(a));
const bIndex = (0, (_nullthrows || _load_nullthrows()).default)(originalOrder.get(b));
return aIndex - bIndex;
});
this._activationDisposable = new (_UniversalDisposable().default)(atom.config.onDidChange(this.getUseKeyPath(), () => {
this.updateActiveFeatures();
}), atom.config.onDidChange(this.getEnabledFeatureGroupsKeyPath(), () => {
this.updateActiveFeatures();
}), _RxMin.Observable.merge(didAddFirstPath, didAddFirstTextEditor).take(1).subscribe(() => {
// Hopefully we've opened a project so we don't have to load all the features.
this._deferringFeatureActivation = false;
this.updateActiveFeatures();
}));
}
this._features.forEach(feature => {
// Since the migration from bool to enum occurs before the config defaults
// are changed, the user's config gets filled with every Nuclide feature.
// Since these values are already the default, this `config.set`
// removes these uneccessary values from the user's config file.
// TODO: When enough users have migrated, this should be removed along with the enum migration.
atom.config.set(
this.useKeyPathForFeature(feature),
atom.config.get(this.useKeyPathForFeature(feature)));
updateActiveFeatures() {
// `updateActiveFeatures()` can't be called recursively. If it is, just warn and bail.
if (this._featureBeingActivated != null) {
// eslint-disable-next-line no-console
console.warn(`Activating ${this._featureBeingActivated.pkg.name} caused a` + ' reevaluation of active features.');
return;
}
if (this._featureBeingDeactivated != null) {
// eslint-disable-next-line no-console
console.warn(`Deactivating ${this._featureBeingDeactivated.pkg.name} caused a` + ' reevaluation of active features.');
return;
}
if (this.shouldEnable(feature)) {
atom.packages.activatePackage(feature.path);
}
});
// Watch the config to manage toggling features
this._activationDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(
atom.config.onDidChange(this.useKeyPath(), event =>
this.updateActiveFeatures()),
atom.config.onDidChange(this.useKeyPathForFeatureGroup(), event =>
this.updateActiveFeatures()));
this.updateActiveFeatures();
this.updateActiveFeaturesNow();
}
/**
* Enable and disable the correct features according to the current configuration.
*/
updateActiveFeatures() {
const featureState = atom.config.get(this.useKeyPath());
const featureGroupState = atom.config.get(this.useKeyPathForFeatureGroup());
// we know featureGroupState must be ?Array, and featureState must
// be ?Object, since it's in our schema. However, flow thinks it's a mixed type,
// since it doesn't know about the schema enforcements. $FlowIgnore.
const desiredState = this.getDesiredState(featureState, featureGroupState);
updateActiveFeaturesNow() {
const enabledFeatures = this.getEnabledFeatures();
const featuresToActivate = (0, _collection().setUnion)(this._featureGroups.get(REQUIRED_FEATURE_GROUP), this._deferringFeatureActivation ? (0, _collection().setIntersect)(enabledFeatures, this._featureGroups.get(INITIAL_FEATURE_GROUP)) : enabledFeatures); // Enable all packages in featuresToActivate but not in currentState.
// Disable all packages not in featuresToActivate but in currentState.
// Enable all packages in desiredState but not in currentState.
// Disable all packages not in desiredState but in currentState.
for (const feature of desiredState) {
if (!this._currentPackageState.has(feature)) {
for (const feature of featuresToActivate) {
if (!this._currentlyActiveFeatures.has(feature)) {
this._featureBeingActivated = feature;
atom.packages.activatePackage(feature.path);
this._featureBeingActivated = null;
}
}
for (const feature of this._currentPackageState) {
if (!desiredState.has(feature)) {
for (const feature of this._currentlyActiveFeatures) {
if (!featuresToActivate.has(feature)) {
this._featureBeingDeactivated = feature;
safeDeactivate(feature);
this._featureBeingDeactivated = null;
}
}
this._currentPackageState = desiredState;
this._currentlyActiveFeatures = featuresToActivate;
}
deactivate() {if (!(
deactivate() {
if (!(this._activationDisposable && !this._activationDisposable.disposed)) {
throw new Error("Invariant violation: \"this._activationDisposable && !this._activationDisposable.disposed\"");
}
this._activationDisposable && !this._activationDisposable.disposed)) {throw new Error('Invariant violation: "this._activationDisposable && !this._activationDisposable.disposed"');}
this._features.forEach(feature => {
this._currentlyActiveFeatures.forEach(feature => {
// Deactivate the package, but don't serialize. That needs to be done in a separate phase so that
// we don't end up disconnecting a service and then serializing the disconnected state.
safeDeactivate(feature, true);
});if (!
});
this._activationDisposable) {throw new Error('Invariant violation: "this._activationDisposable"');} // reasserting for flow
this._currentlyActiveFeatures = new Set();
if (!this._activationDisposable) {
throw new Error("Invariant violation: \"this._activationDisposable\"");
} // reasserting for flow
this._activationDisposable.dispose();
this._activationDisposable = null;
}
/**
* Determine which features are enabled based on the current state of the configuration. This set
* is then used to load and activate the features.
*/
getDesiredState(
featureState,
featureGroupState)
{
// Figure out which features should be enabled:
// * Add all packages in nuclide.use
// * Remove any feature not in an active featureGroup.
let groupedPackages;
if (featureGroupState != null) {
groupedPackages = (0, (_collection || _load_collection()).setUnion)(
...featureGroupState.map(featureGroup =>
this._featureGroupMap.get(featureGroup)));
getEnabledFeatures() {
// we know enabledFeatureGroups must be ?Array, and useFeatureRules must be ?UseFeatureRules,
// since it's in our schema. However, flow thinks it's a mixed type, since it doesn't know about
const useFeatureRules = atom.config.get(this.getUseKeyPath());
const enabledFeatureGroups = atom.config.get(this.getEnabledFeatureGroupsKeyPath());
const featuresInEnabledGroups = enabledFeatureGroups == null ? new Set(this._features) // If featuregroups is undefined, assume all features should be enabled.
: (0, _collection().setUnion)(...enabledFeatureGroups.map(featureGroup => this._featureGroups.get(featureGroup)));
const requiredFeatures = this._featureGroups.get(REQUIRED_FEATURE_GROUP) || new Set(); // If a feature is "always enabled", it should be on whether or not a feature-group includes it.
// If a feature is "default", it should be on if and only if a feature-group includes it.
} else {
// If featuregroups is empty or undefined, assume all features should be enabled.
groupedPackages = new Set(this._features);
}
return new Set(this._features.filter(feature => {
var _ref;
// If a feature is "always enabled", it should be on whether or not a feature-group includes it.
// If a feature is "default", it should be on if and only if a feature-group includes it.
return new Set(
this._features.filter(feature => {
const state = featureState[packageNameFromPath(feature.path)];
return (
state === ALWAYS_ENABLED ||
groupedPackages.has(feature) && state === DEFAULT ||
state === true);
const featureName = packageNameFromPath(feature.path);
const rawRule = (_ref = useFeatureRules) != null ? _ref[featureName] : _ref;
const rule = rawRule == null ? getFeatureDefaultValue(feature) : rawRule;
return rule === ALWAYS_ENABLED || rule === true || featuresInEnabledGroups.has(feature) && rule === DEFAULT || requiredFeatures.has(feature);
}));
}
constructFeatureGroupMap() {
/*
* Construct a map from feature name to feature. The _featureGroupMap
* must contain the true feature objects, but featureGroups.cson only has
* the feature names.
*/
const featureMap = new Map();
this._features.forEach(feature => {
featureMap.set(_path2.default.basename(feature.path), feature);
});
for (const key of Object.keys(this._featureGroups)) {
if (Array.isArray(this._featureGroups[key])) {
const featuresForKey = this._featureGroups[key].
map(featureName => featureMap.get(featureName)).
filter(Boolean);
if (featuresForKey != null) {
this._featureGroupMap.set(key, featuresForKey);
}
}
getConfig() {
if (!(this._config != null)) {
throw new Error("Invariant violation: \"this._config != null\"");
}
}
getFeatureGroups() {
return this._featureGroupMap;
}
getConfig() {
return this._config;

@@ -383,75 +334,20 @@ }

useKeyPathForFeature(feature) {
return `${this._pkgName}.use.${packageNameFromPath(feature.path)}`;
}
useKeyPath() {
getUseKeyPath() {
return `${this._pkgName}.use`;
}
useKeyPathForFeatureGroup() {
getEnabledFeatureGroupsKeyPath() {
return `${this._pkgName}.enabledFeatureGroups`;
}
shouldEnable(feature) {
const name = packageNameFromPath(feature.path);
const currentState = atom.config.get(this.useKeyPathForFeature(feature));
switch (currentState) {
// Previously, this setting was a boolean. They should be migrated but handle it just in case.
case true:
case false:
return currentState;
case ALWAYS_ENABLED:
return true;
case NEVER_ENABLED:
return false;
case DEFAULT:
// TODO: This will become dependent on project configuration.
return true;
default:
// This default will trigger if the user explicitly
// sets a package's state to undefined or to a non-enum value.
// If this is the case, set to false if it begins with sample- and true otherwise.
return !name.startsWith('sample-');}
}
}
exports.default = FeatureLoader;
migrateFeature(feature) {
const keyPath = this.useKeyPathForFeature(feature);
const currentState = atom.config.get(keyPath);
const setTo = this.getValueForFeatureToEnumMigration(currentState, feature);
if (setTo !== currentState) {
atom.config.set(keyPath, setTo);
}
}
function safeDeactivate(feature, suppressSerialization = false) {
const name = packageNameFromPath(feature.path);
getValueForFeatureToEnumMigration(
currentState,
feature)
{
const name = packageNameFromPath(feature.path);
switch (currentState) {
case true:
return name.startsWith('sample-') ? ALWAYS_ENABLED : DEFAULT;
case false:
return name.startsWith('sample-') ? DEFAULT : NEVER_ENABLED;
case ALWAYS_ENABLED:
case NEVER_ENABLED:
case DEFAULT:if (!(
typeof currentState === 'string')) {throw new Error('Invariant violation: "typeof currentState === \'string\'"');}
return currentState;
default:
return getFeatureDefaultValue(feature);}
}}exports.default = FeatureLoader;
function safeDeactivate(
feature,
suppressSerialization = false)
{
const name = packageNameFromPath(feature.path);
try {
const pack = atom.packages.getLoadedPackage(name);
if (pack != null) {

@@ -468,3 +364,3 @@ atom.packages.deactivatePackage(name, suppressSerialization);

const name = packageNameFromPath(feature.path);
return name.startsWith('sample-') ? NEVER_ENABLED : DEFAULT;
return name.startsWith('sample-') || name.startsWith('fb-sample-') ? NEVER_ENABLED : DEFAULT;
}

@@ -474,4 +370,6 @@

const name = packageNameFromPath(feature.path);
try {
const pack = atom.packages.getActivePackage(name);
if (pack != null) {

@@ -485,6 +383,6 @@ // Serialize the package

}
}
} // this could be inlined into its use above, but this makes the intent more
// explicit, and unifies it in the case this ever needs to change.
// this could be inlined into its use above, but this makes the intent more
// explicit, and unifies it in the case this ever needs to change.
function packageNameFromPath(pkgPath) {

@@ -494,4 +392,195 @@ return _path2.default.basename(pkgPath);

function packageIsRepositoryProvider(pkg) {var _ref, _ref2;
return Boolean((_ref = pkg) != null ? (_ref2 = _ref.providedServices) != null ? _ref2['atom.repository-provider'] : _ref2 : _ref);
}
function packageIsRepositoryProvider(pkg) {
var _ref2;
return Boolean((_ref2 = pkg) != null ? (_ref2 = _ref2.providedServices) != null ? _ref2['atom.repository-provider'] : _ref2 : _ref2);
}
function buildConfig(features) {
const config = {
use: {
title: 'Enabled Features',
description: 'Enable and disable individual features',
type: 'object',
collapsed: true,
properties: {}
}
};
features.forEach(feature => {
const featurePkg = feature.pkg;
const name = packageNameFromPath(feature.path);
const setting = {
title: featurePkg.displayName == null ? `Enable the "${name}" feature` : `Enable ${featurePkg.displayName}`,
description: featurePkg.description || '',
type: 'string',
enum: [{
value: ALWAYS_ENABLED,
description: 'Always enabled'
}, {
value: NEVER_ENABLED,
description: 'Never enabled'
}, {
value: DEFAULT,
description: 'Only when in an enabled package group'
}],
default: getFeatureDefaultValue(feature)
};
if (devMode) {
if (featurePkg.providedServices) {
const provides = Object.keys(featurePkg.providedServices).join(', ');
setting.description += `<br/>**Provides:** _${provides}_`;
}
if (featurePkg.consumedServices) {
const consumes = Object.keys(featurePkg.consumedServices).join(', ');
setting.description += `<br/>**Consumes:** _${consumes}_`;
}
}
config.use.properties[name] = setting; // Merge in the feature's config
const featurePkgConfig = featurePkg.atomConfig || featurePkg.nuclide && featurePkg.nuclide.config;
if (featurePkgConfig) {
config[name] = {
type: 'object',
title: featurePkg.displayName,
description: featurePkg.description,
collapsed: true,
properties: {}
};
Object.keys(featurePkgConfig).forEach(key => {
config[name].properties[key] = Object.assign({}, featurePkgConfig[key], {
title: featurePkgConfig[key].title || key
});
});
}
});
return config;
}
/**
* Hack time!! Atom's repository APIs are synchronous. Any package that tries to use them before
* we've had a chance to provide our implementation are going to get wrong answers. The correct
* thing to do would be to always go through an async API that awaits until
* `atom.packages.onDidActivateInitialPackages()` completes. However, we have some legacy sync
* codepaths that make that difficult. As a temporary (I hope) workaround, we prioritize
* activation of the features that provide this service.
*/
function reorderFeatures(features_) {
const features = features_.slice();
const originalOrder = new Map(features.map((feature, i) => [feature, i]));
features.sort((a, b) => {
const aIsRepoProvider = packageIsRepositoryProvider(a.pkg);
const bIsRepoProvider = packageIsRepositoryProvider(b.pkg);
if (aIsRepoProvider !== bIsRepoProvider) {
return aIsRepoProvider ? -1 : 1;
}
const aIndex = (0, _nullthrows().default)(originalOrder.get(a));
const bIndex = (0, _nullthrows().default)(originalOrder.get(b));
return aIndex - bIndex;
});
return features;
}
/**
* Construct a map whose keys are feature group names and values are sets of features belonging to
* the group.
*/
function groupFeatures(features, rawFeatureGroups) {
const namesToFeatures = new Map();
features.forEach(feature => {
namesToFeatures.set(_path2.default.basename(feature.path), feature);
});
const featureGroups = new (_collection().MultiMap)();
for (const key of Object.keys(rawFeatureGroups)) {
if (Array.isArray(rawFeatureGroups[key])) {
const featuresForKey = rawFeatureGroups[key].map(featureName => namesToFeatures.get(featureName)).filter(Boolean);
if (featuresForKey != null) {
featureGroups.set(key, featuresForKey);
}
}
}
return featureGroups;
}
/**
* Patch the package manager and packages to (1) implement `onWillInitializePackage` and (2) call
* `registerConfigSchemaFromMainModule()` when a package is initialized (to guarantee its config
* schema is ready when its deserializers are called). This should be removed once these changes
* are upstreamed.
*/
function patchPackageManager() {
if (atom.packages.onWillInitializePackage == null && !atom.packages.__onWillInitializePackagePatched) {
atom.packages.onWillInitializePackage = function (callback) {
atom.packages.__onWillInitializePackagePatched = true;
return this.emitter.on('will-initialize-package', callback);
};
}
if (!atom.packages.__packageLookupPatched) {
atom.packages.__packageLookupPatched = true;
const loadPackage = atom.packages.loadPackage;
atom.packages.loadPackage = function (nameOrPath, ...args) {
const pack = loadPackage.call(this, nameOrPath, ...args);
if (pack == null) {
return null;
}
patchPackage(pack);
return pack;
};
const getLoadedPackage = atom.packages.getLoadedPackage;
atom.packages.getLoadedPackage = function (name, ...args) {
const pack = getLoadedPackage.call(this, name, ...args);
if (pack == null) {
return null;
}
patchPackage(pack);
return pack;
};
}
}
function patchPackage(pack) {
if (pack.__initializeIfNeededPatched) {
return;
}
pack.__initializeIfNeededPatched = true;
const initializeIfNeeded = pack.initializeIfNeeded;
pack.initializeIfNeeded = function () {
if (this.mainInitialized) {
return;
}
if (atom.packages.__onWillInitializePackagePatched) {
// If we didn't apply our patch for this, Atom is already dispatching the event.
atom.packages.emitter.emit('will-initialize-package', pack);
}
this.registerConfigSchemaFromMainModule();
return initializeIfNeeded.call(this);
};
}
const didLoadPackage = pkgName => (0, _event().observableFromSubscribeFunction)(cb => atom.packages.onDidLoadPackage(cb)).startWith(null).filter(() => atom.packages.getLoadedPackage(pkgName) != null).take(1);
const didAddFirstPath = (0, _event().observableFromSubscribeFunction)(cb => atom.project.onDidChangePaths(cb)).startWith(null).filter(() => atom.project.getDirectories().length > 0).take(1);
const didAddFirstTextEditor = (0, _event().observableFromSubscribeFunction)(cb => atom.workspace.getCenter().onDidAddTextEditor(cb)).startWith(null).filter(() => atom.workspace.getCenter().getTextEditors().length > 0).take(1);

@@ -1,21 +0,20 @@

"use strict";Object.defineProperty(exports, "__esModule", { value: true });
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict
* @format
*/
class FocusBoomerang {
recordFocus() {

@@ -28,4 +27,4 @@ if (this._focus != null) {

node: document.activeElement,
pane: atom.workspace.getActivePane() };
pane: atom.workspace.getActivePane()
};
}

@@ -37,3 +36,8 @@

}
const { node, pane } = this._focus;
const {
node,
pane
} = this._focus;
if (node != null && document.body != null && document.body.contains(node)) {

@@ -43,15 +47,10 @@ node.focus();

}
if (pane != null) {
if (pane != null && !pane.isDestroyed()) {
pane.activate();
}
}}exports.default = FocusBoomerang; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
}
}
exports.default = FocusBoomerang;

@@ -1,31 +0,44 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getElementFilePath;
function _textEditor() {
const data = require("./text-editor");
_textEditor = function () {
return data;
};
return data;
}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
function getElementFilePath(element, fallbackToActiveTextEditor = false) {
let el = element;
while (el != null) {
if (el.dataset != null && el.dataset.path != null) {
return el.dataset.path;
} // $FlowFixMe(>=0.68.0) Flow suppress (T27187857)
if (typeof el.getModel === 'function') {
const model = el.getModel();
if ((0, _textEditor().isValidTextEditor)(model)) {
const path = model.getPath();
getElementFilePath;var _textEditor;function _load_textEditor() {return _textEditor = require('./text-editor');} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function getElementFilePath(element, fallbackToActiveTextEditor = false) {let el = element;while (el != null) {if (el.dataset != null && el.dataset.path != null) {return el.dataset.path;} // $FlowFixMe(>=0.68.0) Flow suppress (T27187857)
if (typeof el.getModel === 'function') {const model = el.getModel();
if ((0, (_textEditor || _load_textEditor()).isValidTextEditor)(model)) {
const path = model.getPath();
if (path != null) {

@@ -36,11 +49,15 @@ return path;

}
el = el.parentElement;
}
if (fallbackToActiveTextEditor) {
const editor = atom.workspace.getActiveTextEditor();
if (editor != null && (0, (_textEditor || _load_textEditor()).isValidTextEditor)(editor)) {
if (editor != null) {
return editor.getPath();
}
}
return null;
}

@@ -1,36 +0,36 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getFragmentGrammar;
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict
* @format
*/
/**
* Some grammars should use a specialized grammar for code fragments
* (namely PHP, since it's wildly different depending on the presence of a <?php opening).
*/
const FRAGMENT_GRAMMARS = Object.freeze({
'text.html.hack': 'source.hackfragment',
'text.html.php': 'source.hackfragment'
});
function getFragmentGrammar(grammar) {
if (FRAGMENT_GRAMMARS.hasOwnProperty(grammar.scopeName)) {
const fragmentGrammar = FRAGMENT_GRAMMARS[grammar.scopeName];
return atom.grammars.grammarForScopeName(fragmentGrammar) || grammar;
}
getFragmentGrammar; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/ /**
* Some grammars should use a specialized grammar for code fragments
* (namely PHP, since it's wildly different depending on the presence of a <?php opening).
*/const FRAGMENT_GRAMMARS = Object.freeze({ 'text.html.hack': 'source.hackfragment', 'text.html.php': 'source.hackfragment' });function getFragmentGrammar(grammar) {if (FRAGMENT_GRAMMARS.hasOwnProperty(grammar.scopeName)) {const fragmentGrammar = FRAGMENT_GRAMMARS[grammar.scopeName];return atom.grammars.grammarForScopeName(fragmentGrammar) || grammar;}return grammar;}
return grammar;
}

@@ -1,148 +0,157 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.goToLocation = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.goToLocation = goToLocation;
exports.goToLocationInEditor = goToLocationInEditor;
exports.observeNavigatingEditors = observeNavigatingEditors;
function _log4js() {
const data = require("log4js");
_log4js = function () {
return data;
};
return data;
}
var _RxMin = require("rxjs/bundles/Rx.min.js");
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict-local
* @format
*/
/**
* Opens the given file.
*
* Optionally include a line and column to navigate to. If a line is given, by default it will
* center it in the opened text editor.
*
* This should be preferred over `atom.workspace.open()` in typical cases. The motivations are:
* - We call `atom.workspace.open()` with the `searchAllPanes` option. This looks in other panes for
* the current file, rather just opening a new copy in the current pane. People often forget this
* option which typically leads to a subpar experience for people who use multiple panes.
* - When moving around in the current file, `goToLocation` explicitly publishes events that the nav
* stack uses.
*
* Currently, `atom.workspace.open()` should be used only in these cases:
* - When the URI to open is not a file URI. For example, if we want to open some tool like find
* references in a pane.
* - When we want to open an untitled file (providing no file argument). Currently, goToLocation
* requires a file to open.
* - When we want to open a file as a pending pane item. Currently goToLocation cannot do this.
*
* In these cases, you may disable the lint rule against `atom.workspace.open` by adding the
* following comment above its use:
* // eslint-disable-next-line nuclide-internal/atom-apis
*/
async function goToLocation(file, options) {
var _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
const center_ = (_ref = options) != null ? _ref.center : _ref;
const center = center_ == null ? true : center_;
const moveCursor_ = (_ref2 = options) != null ? _ref2.moveCursor : _ref2;
const moveCursor = moveCursor_ == null ? true : moveCursor_;
const activatePane_ = (_ref3 = options) != null ? _ref3.activatePane : _ref3;
const activatePane = activatePane_ == null ? true : activatePane_;
const activateItem = (_ref4 = options) != null ? _ref4.activateItem : _ref4;
const line = (_ref5 = options) != null ? _ref5.line : _ref5;
const column = (_ref6 = options) != null ? _ref6.column : _ref6;
const pending = (_ref7 = options) != null ? _ref7.pending : _ref7; // Prefer going to the current editor rather than the leftmost editor.
const currentEditor = atom.workspace.getActiveTextEditor();
if (currentEditor != null && currentEditor.getPath() === file) {
const paneContainer = atom.workspace.paneContainerForItem(currentEditor);
if (!(paneContainer != null)) {
throw new Error("Invariant violation: \"paneContainer != null\"");
}
if (activatePane) {
paneContainer.activate();
}
/**
* Opens the given file.
*
* Optionally include a line and column to navigate to. If a line is given, by default it will
* center it in the opened text editor.
*
* This should be preferred over `atom.workspace.open()` in typical cases. The motivations are:
* - We call `atom.workspace.open()` with the `searchAllPanes` option. This looks in other panes for
* the current file, rather just opening a new copy in the current pane. People often forget this
* option which typically leads to a subpar experience for people who use multiple panes.
* - When moving around in the current file, `goToLocation` explicitly publishes events that the nav
* stack uses.
*
* Currently, `atom.workspace.open()` should be used only in these cases:
* - When the URI to open is not a file URI. For example, if we want to open some tool like find
* references in a pane.
* - When we want to open an untitled file (providing no file argument). Currently, goToLocation
* requires a file to open.
* - When we want to open a file as a pending pane item. Currently goToLocation cannot do this.
*
* In these cases, you may disable the lint rule against `atom.workspace.open` by adding the
* following comment above its use:
* // eslint-disable-next-line rulesdir/atom-apis
*/ /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/let goToLocation = exports.goToLocation = (() => {var _ref8 = (0, _asyncToGenerator.default)(function* (file, options) {var _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;const center_ = (_ref = options) != null ? _ref.center : _ref;const center = center_ == null ? true : center_;const moveCursor_ = (_ref2 = options) != null ? _ref2.moveCursor : _ref2;const moveCursor = moveCursor_ == null ? true : moveCursor_;const activatePane_ = (_ref3 = options) != null ? _ref3.activatePane : _ref3;const activatePane = activatePane_ == null ? true : activatePane_;
const activateItem = (_ref4 = options) != null ? _ref4.activateItem : _ref4;
const line = (_ref5 = options) != null ? _ref5.line : _ref5;
const column = (_ref6 = options) != null ? _ref6.column : _ref6;
const pending = (_ref7 = options) != null ? _ref7.pending : _ref7;
// Prefer going to the current editor rather than the leftmost editor.
const currentEditor = atom.workspace.getActiveTextEditor();
if (currentEditor != null && currentEditor.getPath() === file) {
const paneContainer = atom.workspace.paneContainerForItem(currentEditor);if (!(
paneContainer != null)) {throw new Error('Invariant violation: "paneContainer != null"');}
if (activatePane) {
paneContainer.activate();
}
if (line != null) {
goToLocationInEditor(currentEditor, {
line,
column: column == null ? 0 : column,
center,
moveCursor });
} else {if (!(
column == null)) {throw new Error('goToLocation: Cannot specify just column');}
}
return currentEditor;
if (line != null) {
goToLocationInEditor(currentEditor, {
line,
column: column == null ? 0 : column,
center,
moveCursor
});
} else {
// Obviously, calling goToLocation isn't a viable alternative here :P
// eslint-disable-next-line rulesdir/atom-apis
const editor = yield atom.workspace.open(file, {
initialLine: line,
initialColumn: column,
searchAllPanes: true,
activatePane,
activateItem,
pending });
// TODO(T28305560) Investigate offenders for this error
if (editor == null) {
const tmp = {};
Error.captureStackTrace(tmp);
const error = Error(`atom.workspace.open returned null on ${file}`);
(0, (_log4js || _load_log4js()).getLogger)('goToLocation').error(error);
throw error;
if (!(column == null)) {
throw new Error('goToLocation: Cannot specify just column');
}
if (center && line != null) {
editor.scrollToBufferPosition([line, column], { center: true });
}
return editor;
}
});return function goToLocation(_x, _x2) {return _ref8.apply(this, arguments);};})();exports.
return currentEditor;
} else {
// Obviously, calling goToLocation isn't a viable alternative here :P
// eslint-disable-next-line nuclide-internal/atom-apis
const editor = await atom.workspace.open(file, {
initialLine: line,
initialColumn: column,
searchAllPanes: true,
activatePane,
activateItem,
pending
}); // TODO(T28305560) Investigate offenders for this error
if (editor == null) {
const tmp = {};
Error.captureStackTrace(tmp);
const error = Error(`atom.workspace.open returned null on ${file}`);
(0, _log4js().getLogger)('goToLocation').error(error);
throw error;
}
if (center && line != null) {
editor.scrollToBufferPosition([line, column], {
center: true
});
}
return editor;
}
}
const goToLocationSubject = new _RxMin.Subject();
// Scrolls to the given line/column at the given editor
// broadcasts the editor instance on an observable (subject) available
// through the getGoToLocation
function goToLocationInEditor(editor, options) {
const center = options.center == null ? true : options.center;
const moveCursor = options.moveCursor == null ? true : options.moveCursor;
const {
line,
column
} = options;
if (moveCursor) {
editor.setCursorBufferPosition([line, column]);
}
if (center) {
editor.scrollToBufferPosition([line, column], {
center: true
});
}
goToLocationSubject.next(editor);
}
goToLocationInEditor = goToLocationInEditor;exports.
observeNavigatingEditors = observeNavigatingEditors;var _log4js;function _load_log4js() {return _log4js = require('log4js');}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _idx;function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}const goToLocationSubject = new _rxjsBundlesRxMinJs.Subject(); // Scrolls to the given line/column at the given editor
// broadcasts the editor instance on an observable (subject) available
// through the getGoToLocation
function goToLocationInEditor(editor, options) {const center = options.center == null ? true : options.center;const moveCursor = options.moveCursor == null ? true : options.moveCursor;const { line, column } = options;if (moveCursor) {editor.setCursorBufferPosition([line, column]);}if (center) {editor.scrollToBufferPosition([line, column], { center: true });}goToLocationSubject.next(editor);}function observeNavigatingEditors() {return goToLocationSubject;}
function observeNavigatingEditors() {
return goToLocationSubject;
}

@@ -1,68 +0,77 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = humanizePath;
function _nuclideUri() {
const data = _interopRequireDefault(require("nuclide-commons/nuclideUri"));
_nuclideUri = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
/**
* Format a path for display. After the path is humanized, it should no longer be treated like a
* parsable, navigable path; it's just for display.
*
* Note that this (intentionally) provides different results based on the projects currently open in
* Atom. If you have multiple directories open, the result will be prefixed with one of their names.
* If you only have one, it won't.
*/
function humanizePath(path, options) {
var _ref, _ref2;
const isDirectory = (_ref = options) != null ? _ref.isDirectory : _ref;
const rootPaths = ((_ref2 = options) != null ? _ref2.rootPaths : _ref2) || atom.project.getDirectories().map(dir => dir.getPath());
const normalized = normalizePath(path, isDirectory);
let resolved;
for (const rootPath of rootPaths) {
const normalizedDir = _nuclideUri().default.normalizeDir(rootPath);
if (_nuclideUri().default.contains(normalizedDir, normalized)) {
resolved = normalized.substr(normalizedDir.length);
const rootName = _nuclideUri().default.basename(normalizedDir); // If the path is a root or there's more than one root, include the root's name.
humanizePath;var _idx;function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /**
* Format a path for display. After the path is humanized, it should no longer be treated like a
* parsable, navigable path; it's just for display.
*
* Note that this (intentionally) provides different results based on the projects currently open in
* Atom. If you have multiple directories open, the result will be prefixed with one of their names.
* If you only have one, it won't.
*/function humanizePath(path, options) {var _ref, _ref2;const isDirectory = (_ref = options) != null ? _ref.isDirectory : _ref;
const rootPaths =
((_ref2 = options) != null ? _ref2.rootPaths : _ref2) ||
atom.project.getDirectories().map(dir => dir.getPath());
const normalized = normalizePath(path, isDirectory);
let resolved;
for (const rootPath of rootPaths) {
const normalizedDir = (_nuclideUri || _load_nuclideUri()).default.normalizeDir(rootPath);
if ((_nuclideUri || _load_nuclideUri()).default.contains(normalizedDir, normalized)) {
resolved = normalized.substr(normalizedDir.length);
const rootName = (_nuclideUri || _load_nuclideUri()).default.basename(normalizedDir);
// If the path is a root or there's more than one root, include the root's name.
if (normalized === normalizedDir) {
return (_nuclideUri || _load_nuclideUri()).default.normalizeDir(rootName);
return _nuclideUri().default.normalizeDir(rootName);
}
if (rootPaths.length > 1) {
return (_nuclideUri || _load_nuclideUri()).default.join(rootName, resolved);
return _nuclideUri().default.join(rootName, resolved);
}
return resolved;
}
}
} // It's not in one of the project directories so return the full (normalized)
// path run through nuclideUriToDisplayString to remove nuclide:// etc.
// It's not in one of the project directories so return the full (normalized)
// path run through nuclideUriToDisplayString to remove nuclide:// etc.
return (_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(normalized);
} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function normalizePath(path, isDirectory_) {const isDirectory = isDirectory_ == null ? (_nuclideUri || _load_nuclideUri()).default.endsWithSeparator(path) : isDirectory_;return isDirectory ? (_nuclideUri || _load_nuclideUri()).default.normalizeDir(path) : (_nuclideUri || _load_nuclideUri()).default.normalize(path);}
return _nuclideUri().default.nuclideUriToDisplayString(normalized);
}
function normalizePath(path, isDirectory_) {
const isDirectory = isDirectory_ == null ? _nuclideUri().default.endsWithSeparator(path) : isDirectory_;
return isDirectory ? _nuclideUri().default.normalizeDir(path) : _nuclideUri().default.normalize(path);
}

@@ -1,37 +0,36 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.bufferPositionForMouseEvent = bufferPositionForMouseEvent;
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict
* @format
*/
function bufferPositionForMouseEvent(event, editor = null) {
const _editor = editor || atom.workspace.getActiveTextEditor();
if (!(_editor != null)) {
throw new Error("Invariant violation: \"_editor != null\"");
}
const view = atom.views.getView(_editor);
const component = view.component;
if (!(component != null)) {
throw new Error("Invariant violation: \"component != null\"");
} // Beware, screenPositionForMouseEvent is not a public api and may change in future versions.
bufferPositionForMouseEvent = bufferPositionForMouseEvent;function bufferPositionForMouseEvent(
event,
editor = null)
{
const _editor = editor || atom.workspace.getActiveTextEditor();if (!(
_editor != null)) {throw new Error('Invariant violation: "_editor != null"');}
const view = atom.views.getView(_editor);
const component = view.component;if (!(
component != null)) {throw new Error('Invariant violation: "component != null"');}
// Beware, screenPositionForMouseEvent is not a public api and may change in future versions.
const screenPosition = component.screenPositionForMouseEvent(event);
return _editor.bufferPositionForScreenPosition(screenPosition);
} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
}

@@ -1,88 +0,120 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = observePaneItemVisibility;
exports.observeVisibleItems = observeVisibleItems;
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
function _memoizeUntilChanged() {
const data = _interopRequireDefault(require("nuclide-commons/memoizeUntilChanged"));
_memoizeUntilChanged = function () {
return data;
};
return data;
}
function _collection() {
const data = require("nuclide-commons/collection");
_collection = function () {
return data;
};
return data;
}
var _RxMin = require("rxjs/bundles/Rx.min.js");
function _shallowequal() {
const data = _interopRequireDefault(require("shallowequal"));
_shallowequal = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
// TODO(T17495608): Currently, docks don't have a way of observing their visibility so this will
// have some false positives when an item is its pane's active item but its dock is hidden.
function observePaneItemVisibility(item) {
patchDocks();
const workspaceEl = atom.workspace.getElement();
return _RxMin.Observable.combineLatest( // atom.workspace.reset() (in tests) resets all the panes.
// Pass in the workspace dom element to act as a cache-breaker.
observeActiveItems(workspaceEl), observePaneContainerVisibilities(workspaceEl)).map(([activeItems, locationVisibilities]) => {
// If it's not active, it's not visible.
if (!activeItems.has(item)) {
return false;
} // If it's active, it's only visible if its container is.
const paneContainer = atom.workspace.paneContainerForItem(item);
return paneContainer == null ? false : locationVisibilities[paneContainer.getLocation()];
}).distinctUntilChanged();
}
observePaneItemVisibility;exports.
function observeVisibleItems() {
patchDocks();
const workspaceEl = atom.workspace.getElement();
return _RxMin.Observable.combineLatest(observeActiveItems(workspaceEl), observePaneContainerVisibilities(workspaceEl)).map(([activeItems, locationVisibilities]) => {
// If it's not active, it's not visible.
// If it's active, it's only visible if its container is.
return (0, _collection().setFilter)(activeItems, item => {
const paneContainer = atom.workspace.paneContainerForItem(item);
const location = paneContainer && paneContainer.getLocation();
return location ? Boolean(locationVisibilities[location]) : false;
});
});
}
observeVisibleItems = observeVisibleItems;var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _memoizeUntilChanged;function _load_memoizeUntilChanged() {return _memoizeUntilChanged = _interopRequireDefault(require('nuclide-commons/memoizeUntilChanged'));}var _collection;function _load_collection() {return _collection = require('nuclide-commons/collection');}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _shallowequal;function _load_shallowequal() {return _shallowequal = _interopRequireDefault(require('shallowequal'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} // TODO(T17495608): Currently, docks don't have a way of observing their visibility so this will
// have some false positives when an item is its pane's active item but its dock is hidden.
function observePaneItemVisibility(item) {patchDocks();const workspaceEl = atom.workspace.getElement();return _rxjsBundlesRxMinJs.Observable.combineLatest( // atom.workspace.reset() (in tests) resets all the panes.
// Pass in the workspace dom element to act as a cache-breaker.
observeActiveItems(workspaceEl), observePaneContainerVisibilities(workspaceEl)).map(([activeItems, locationVisibilities]) => {// If it's not active, it's not visible.
if (!activeItems.has(item)) {return false;} // If it's active, it's only visible if its container is.
const paneContainer = atom.workspace.paneContainerForItem(item);return paneContainer == null ? false : locationVisibilities[paneContainer.getLocation()];}).distinctUntilChanged();} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function observeVisibleItems() {patchDocks();const workspaceEl = atom.workspace.getElement();return _rxjsBundlesRxMinJs.Observable.combineLatest(observeActiveItems(workspaceEl), observePaneContainerVisibilities(workspaceEl)).map(([activeItems, locationVisibilities]) => {// If it's not active, it's not visible.
// If it's active, it's only visible if its container is.
return (0, (_collection || _load_collection()).setFilter)(activeItems, item => {const paneContainer = atom.workspace.paneContainerForItem(item);const location = paneContainer && paneContainer.getLocation();return location ? Boolean(locationVisibilities[location]) : false;});});}const observeActiveItems = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(_cacheKey => {
const observeActiveItems = (0, _memoizeUntilChanged().default)(_cacheKey => {
// An observable that emits `{pane, item}` whenever the active item of a pane changes.
const itemActivations = _rxjsBundlesRxMinJs.Observable.merge(
...atom.workspace.getPaneContainers().map(paneContainer => {
const itemActivations = _RxMin.Observable.merge(...atom.workspace.getPaneContainers().map(paneContainer => {
const observePanes = paneContainer.observePanes.bind(paneContainer);
return (0, (_event || _load_event()).observableFromSubscribeFunction)(observePanes).flatMap(pane => {
const paneDestroyed = (0, (_event || _load_event()).observableFromSubscribeFunction)(
pane.onDidDestroy.bind(pane));
const activeItems = (0, (_event || _load_event()).observableFromSubscribeFunction)(
pane.observeActiveItem.bind(pane)).
takeUntil(paneDestroyed);
return _rxjsBundlesRxMinJs.Observable.concat(
activeItems.map(item => ({ pane, item })),
_rxjsBundlesRxMinJs.Observable.of({ pane, item: null }));
return (0, _event().observableFromSubscribeFunction)(observePanes).flatMap(pane => {
const paneDestroyed = (0, _event().observableFromSubscribeFunction)(pane.onDidDestroy.bind(pane));
const activeItems = (0, _event().observableFromSubscribeFunction)(pane.observeActiveItem.bind(pane)).takeUntil(paneDestroyed);
return _RxMin.Observable.concat(activeItems.map(item => ({
pane,
item
})), _RxMin.Observable.of({
pane,
item: null
}));
});
}));
})); // Create a map of panes to their active items. We could look this up by examining the workspace
// every time; this is an optimization.
// Create a map of panes to their active items. We could look this up by examining the workspace
// every time; this is an optimization.
const panesToActiveItem = itemActivations.scan((acc, { pane, item }) => {
const panesToActiveItem = itemActivations.scan((acc, {
pane,
item
}) => {
if (item == null) {

@@ -93,31 +125,26 @@ acc.delete(pane);

}
return acc;
}, new Map());
return (
panesToActiveItem
// When dragging items between panes, they'll be quickly deactivated and activated again. To
// avoid doing extra work, we debounce and use the rAF scheduler.
.debounceTime(0, _rxjsBundlesRxMinJs.Scheduler.animationFrame).
map(map => new Set(map.values())).
share());
});
// Create an observable that contains the current visibility state of each dock, but where the
return panesToActiveItem // When dragging items between panes, they'll be quickly deactivated and activated again. To
// avoid doing extra work, we debounce and use the rAF scheduler.
.debounceTime(0, _RxMin.Scheduler.animationFrame).map(map => new Set(map.values())) // $FlowIgnore: this is just not listed in the flow-typed defs
.shareReplay(1);
}); // Create an observable that contains the current visibility state of each dock, but where the
// "false" values are delayed to account for the time it takes to animate the dock closed.
const observePaneContainerVisibilities = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(_cacheKey => {
const visibilitiesByDock = ['left', 'right', 'bottom'].map(loc =>
dockStateChanges.
filter(({ location }) => location === loc).
switchMap(
({ location, visible }) =>
// Delay the "false" values so they don't occur while the dock is being animated closed.
visible ?
_rxjsBundlesRxMinJs.Observable.of({ location, visible }) :
_rxjsBundlesRxMinJs.Observable.of({ location, visible }).delay(300)).
distinctUntilKeyChanged('visible'));
const observePaneContainerVisibilities = (0, _memoizeUntilChanged().default)(_cacheKey => {
const visibilitiesByDock = ['left', 'right', 'bottom'].map(loc => dockStateChanges.filter(({
location
}) => location === loc).switchMap(({
location,
visible
}) => // Delay the "false" values so they don't occur while the dock is being animated closed.
visible ? _RxMin.Observable.of({
location,
visible
}) : _RxMin.Observable.of({
location,
visible
}).delay(300)).distinctUntilKeyChanged('visible'));
const initialVisibilities = {

@@ -128,26 +155,20 @@ // The center is always visible.

right: atom.workspace.getRightDock().isVisible(),
bottom: atom.workspace.getBottomDock().isVisible() };
bottom: atom.workspace.getBottomDock().isVisible()
}; // Accumulate the dock visibilities.
const visibilityStates = _RxMin.Observable.merge(...visibilitiesByDock).scan((acc, {
location,
visible
}) => Object.assign({}, acc, {
[location]: visible
}), initialVisibilities).startWith(initialVisibilities).distinctUntilChanged(_shallowequal().default).publishReplay(1);
// Accumulate the dock visibilities.
const visibilityStates = _rxjsBundlesRxMinJs.Observable.merge(...visibilitiesByDock).
scan(
(acc, { location, visible }) => Object.assign({},
acc, {
[location]: visible }),
initialVisibilities).
startWith(initialVisibilities).
distinctUntilChanged((_shallowequal || _load_shallowequal()).default).
publishReplay(1);
visibilityStates.connect();
return visibilityStates;
});
}); // HACK: Monkey-patch Docks in order to observe visibility toggling.
// TODO: Use `Dock::observeVisibility` once atom/atom#14736 is in our lowest-supported version
// HACK: Monkey-patch Docks in order to observe visibility toggling.
// TODO: Use `Dock::observeVisibility` once atom/atom#14736 is in our lowest-supported version
let docksPatched = false;
const dockStateChanges = new _rxjsBundlesRxMinJs.Subject();
const dockStateChanges = new _RxMin.Subject();
function patchDocks() {

@@ -157,17 +178,19 @@ if (docksPatched || typeof atom.workspace.getLeftDock !== 'function') {

}
docksPatched = true;
const ctor = atom.workspace.getLeftDock().constructor;
const proto = ctor.prototype;
// $FlowIgnore
const originalSetState = proto.setState;
// $FlowIgnore
const proto = ctor.prototype; // $FlowIgnore
const originalSetState = proto.setState; // $FlowIgnore
proto.setState = function (newState, ...args) {
originalSetState.call(this, newState, ...args);
if (newState.hasOwnProperty('visible')) {
dockStateChanges.next({
location: this.getLocation(),
visible: newState.visible });
visible: newState.visible
});
}
};
}
{
"name": "nuclide-commons-atom",
"version": "0.7.1",
"version": "0.7.2",
"description": "Common Nuclide node modules (for use with Atom only).",

@@ -11,16 +11,21 @@ "author": "NEEDS OWNER",

"prepublish": "../scripts/prepublish.sh",
"test": "atom --dev --test spec"
"test": "true"
},
"atomTestRunner": "../scripts/atom-test-runner.js",
"dependencies": {
"async-to-generator": "1.1.0",
"escape-string-regexp": "1.0.5",
"idb-keyval": "2.3.0",
"idx": "1.2.0",
"lodash": "4.17.10",
"log4js": "1.1.1",
"nuclide-commons": "0.7.1",
"lru-cache": "4.0.2",
"nuclide-commons": "0.7.2",
"nullthrows": "1.0.0",
"redux-logger": "3.0.6",
"rxjs": "5.5.5",
"season": "6.0.2",
"semver": "5.3.0",
"shallowequal": "0.2.2"
"shallowequal": "0.2.2",
"toml": "2.3.3",
"vscode-jsonrpc": "3.3.0"
},

@@ -27,0 +32,0 @@ "devDependencies": {

@@ -1,31 +0,41 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isPending = isPending;
exports.observePendingStateEnd = observePendingStateEnd;
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
function isPending(paneItem) {
const pane = atom.workspace.paneForItem(paneItem);
return pane && pane.getPendingItem() === paneItem;
}
function observePendingStateEnd(paneItem) {
if (!(typeof paneItem.onDidTerminatePendingState === 'function')) {
throw new Error('paneItem must implement onDidTerminatePendingState method');
}
isPending = isPending;exports.
observePendingStateEnd = observePendingStateEnd;var _event;function _load_event() {return _event = require('nuclide-commons/event');} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function isPending(paneItem) {const pane = atom.workspace.paneForItem(paneItem);return pane && pane.getPendingItem() === paneItem;}function observePendingStateEnd(paneItem) {if (!(typeof paneItem.onDidTerminatePendingState === 'function')) {throw new Error('paneItem must implement onDidTerminatePendingState method');}return (0, (_event || _load_event()).observableFromSubscribeFunction)(paneItem.onDidTerminatePendingState.bind(paneItem));}
return (0, _event().observableFromSubscribeFunction)(paneItem.onDidTerminatePendingState.bind(paneItem));
}

@@ -1,25 +0,8 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = parseOpenable;
parseOpenable; // From the nuclide-fuzzy-filename-provider module
// TODO: Remove that module when Dash and openables replace it
/**

@@ -35,2 +18,14 @@ * Copyright (c) 2017-present, Facebook, Inc.

* @format
*/function parseOpenable(query) {const [uri, line, column] = query.split(/:+/);const lineNumber = parseInt(line, 10);const columnNumber = parseInt(column, 10);return { uri, line: !Number.isNaN(lineNumber) ? lineNumber - 1 : undefined, column: !Number.isNaN(columnNumber) ? columnNumber - 1 : undefined };}
*/
// From the nuclide-fuzzy-filename-provider module
// TODO: Remove that module when Dash and openables replace it
function parseOpenable(query) {
const [uri, line, column] = query.split(/:+/);
const lineNumber = parseInt(line, 10);
const columnNumber = parseInt(column, 10);
return {
uri,
line: !Number.isNaN(lineNumber) ? lineNumber - 1 : undefined,
column: !Number.isNaN(columnNumber) ? columnNumber - 1 : undefined
};
}

@@ -1,184 +0,210 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getValidProjectPaths = getValidProjectPaths;
exports.getAtomProjectRelativePath = getAtomProjectRelativePath;
exports.getAtomProjectRootPath = getAtomProjectRootPath;
exports.relativizePathWithDirectory = relativizePathWithDirectory;
exports.getDirectoryForPath = getDirectoryForPath;
exports.getFileForPath = getFileForPath;
exports.observeProjectPaths = observeProjectPaths;
exports.observeProjectPathsAll = observeProjectPathsAll;
exports.onDidChangeProjectPath = onDidChangeProjectPath;
exports.onDidAddProjectPath = onDidAddProjectPath;
exports.onDidRemoveProjectPath = onDidRemoveProjectPath;
exports.observeRemovedHostnames = observeRemovedHostnames;
exports.observeAddedHostnames = observeAddedHostnames;
var _atom = require("atom");
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
function _nuclideUri() {
const data = _interopRequireDefault(require("nuclide-commons/nuclideUri"));
_nuclideUri = function () {
return data;
};
return data;
}
function _observable() {
const data = require("nuclide-commons/observable");
_observable = function () {
return data;
};
return data;
}
var _RxMin = require("rxjs/bundles/Rx.min.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
function getValidProjectPaths() {
return atom.project.getDirectories().filter(directory => {
// If a remote directory path is a local `Directory` instance, the project path
// isn't yet ready for consumption.
if (_nuclideUri().default.isRemote(directory.getPath()) && directory instanceof _atom.Directory) {
return false;
}
return true;
}).map(directory => directory.getPath());
}
function getAtomProjectRelativePath(path) {
const [projectPath, relativePath] = atom.project.relativizePath(path);
if (!projectPath) {
return null;
}
return relativePath;
}
function getAtomProjectRootPath(path) {
const [projectPath] = atom.project.relativizePath(path);
return projectPath;
}
/**
* Like `atom.project.relativizePath`, except it returns the `Directory` rather than the path.
* It also works for non-children, i.e. this can return `../../x`.
*
* This is intended to be used as a way to get a File object for any path
* without worrying about remote vs. local paths.
*/
function relativizePathWithDirectory(path) {
for (const directory of atom.project.getDirectories()) {
try {
const relativePath = _nuclideUri().default.relative(directory.getPath(), path);
return [directory, relativePath];
} catch (e) {// We have a remote-local mismatch or hostname mismatch.
}
}
return [null, path];
}
function getDirectoryForPath(path) {
const [directory, relativePath] = relativizePathWithDirectory(path);
if (directory == null) {
return null;
}
return directory.getSubdirectory(relativePath);
}
function getFileForPath(path) {
const [directory, relativePath] = relativizePathWithDirectory(path);
if (directory == null) {
return null;
}
return directory.getFile(relativePath);
}
function observeProjectPaths(callback) {
getValidProjectPaths().forEach(existingPath => callback(existingPath, true));
return onDidChangeProjectPath(callback);
}
function observeProjectPathsAll(callback) {
let projectPaths = getValidProjectPaths();
let changing = false;
callback(projectPaths);
return atom.project.onDidChangePaths(() => {
if (changing) {
throw new Error('Cannot update projects in the middle of an update');
}
changing = true;
projectPaths = getValidProjectPaths();
callback(projectPaths);
changing = false;
});
}
function onDidChangeProjectPath(callback) {
let projectPaths = getValidProjectPaths();
let changing = false;
return observeProjectPathsAll(newProjectPaths => {
if (changing) {
throw new Error('Cannot update projects in the middle of an update');
}
changing = true; // Check to see if the change was the addition of a project.
for (const newProjectPath of newProjectPaths) {
if (!projectPaths.includes(newProjectPath)) {
callback(newProjectPath, true);
}
} // Check to see if the change was the deletion of a project.
getAtomProjectRelativePath = getAtomProjectRelativePath;exports.
for (const projectPath of projectPaths) {
if (!newProjectPaths.includes(projectPath)) {
callback(projectPath, false);
}
}
changing = false;
projectPaths = newProjectPaths;
});
}
function onDidAddProjectPath(callback) {
return onDidChangeProjectPath((projectPath, added) => {
if (added) {
callback(projectPath);
}
});
}
function onDidRemoveProjectPath(callback) {
return onDidChangeProjectPath((projectPath, added) => {
if (!added) {
callback(projectPath);
}
});
}
function observeHostnames() {
return (atom.packages.initialPackagesActivated ? _RxMin.Observable.of(null) : (0, _event().observableFromSubscribeFunction)(atom.packages.onDidActivateInitialPackages.bind(atom.packages))).switchMap(() => (0, _event().observableFromSubscribeFunction)(atom.project.onDidChangePaths.bind(atom.project)).startWith(null).map(() => new Set(atom.project.getPaths().filter(_nuclideUri().default.isRemote).map(_nuclideUri().default.getHostname))).let((0, _observable().diffSets)()));
}
function observeRemovedHostnames() {
return observeHostnames().flatMap(diff => _RxMin.Observable.from(diff.removed));
}
getAtomProjectRootPath = getAtomProjectRootPath;exports.
relativizePathWithDirectory = relativizePathWithDirectory;exports.
getDirectoryForPath = getDirectoryForPath;exports.
getFileForPath = getFileForPath;exports.
observeProjectPaths = observeProjectPaths;exports.
onDidAddProjectPath = onDidAddProjectPath;exports.
onDidRemoveProjectPath = onDidRemoveProjectPath;exports.
observeRemovedHostnames = observeRemovedHostnames;exports.
observeAddedHostnames = observeAddedHostnames;var _atom = require('atom');var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _observable;function _load_observable() {return _observable = require('nuclide-commons/observable');}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function getValidProjectPaths() {return atom.project.getDirectories().filter(directory => {// If a remote directory path is a local `Directory` instance, the project path
// isn't yet ready for consumption.
if ((_nuclideUri || _load_nuclideUri()).default.isRemote(directory.getPath()) && directory instanceof _atom.Directory) {return false;}return true;}).map(directory => directory.getPath());}function getAtomProjectRelativePath(path) {const [projectPath, relativePath] = atom.project.relativizePath(path);if (!projectPath) {return null;}return relativePath;}function getAtomProjectRootPath(path) {const [projectPath] = atom.project.relativizePath(path);return projectPath;} /**
* Like `atom.project.relativizePath`, except it returns the `Directory` rather than the path.
* It also works for non-children, i.e. this can return `../../x`.
*
* This is intended to be used as a way to get a File object for any path
* without worrying about remote vs. local paths.
*/function relativizePathWithDirectory(path) {for (const directory of atom.project.getDirectories()) {try {const relativePath = (_nuclideUri || _load_nuclideUri()).default.relative(directory.getPath(), path);return [directory, relativePath];} catch (e) {// We have a remote-local mismatch or hostname mismatch.
}}return [null, path];}function getDirectoryForPath(path) {const [directory, relativePath] = relativizePathWithDirectory(path);if (directory == null) {return null;}return directory.getSubdirectory(relativePath);}function getFileForPath(path) {const [directory, relativePath] = relativizePathWithDirectory(path);if (directory == null) {return null;}return directory.getFile(relativePath);}function observeProjectPaths(callback) {getValidProjectPaths().forEach(callback);return onDidAddProjectPath(callback);}function onDidAddProjectPath(callback) {let projectPaths = getValidProjectPaths();let changing = false;return atom.project.onDidChangePaths(() => {if (changing) {throw new Error('Cannot update projects in the middle of an update');}changing = true;const newProjectPaths = getValidProjectPaths();for (const newProjectPath of newProjectPaths) {if (!projectPaths.includes(newProjectPath)) {callback(newProjectPath);}}changing = false;projectPaths = newProjectPaths;});}function onDidRemoveProjectPath(callback) {let projectPaths = getValidProjectPaths();let changing = false;return atom.project.onDidChangePaths(() => {if (changing) {throw new Error('Cannot update projects in the middle of an update');}changing = true;const newProjectPaths = getValidProjectPaths();for (const projectPath of projectPaths) {if (!newProjectPaths.includes(projectPath)) {callback(projectPath);}}changing = false;projectPaths = newProjectPaths;});}function observeHostnames() {return (atom.packages.initialPackagesActivated ? _rxjsBundlesRxMinJs.Observable.of(null) : (0, (_event || _load_event()).observableFromSubscribeFunction)(atom.packages.onDidActivateInitialPackages.bind(atom.packages))).switchMap(() => (0, (_event || _load_event()).observableFromSubscribeFunction)(atom.project.onDidChangePaths.bind(atom.project)).startWith(null).map(() => new Set(atom.project.getPaths().filter((_nuclideUri || _load_nuclideUri()).default.isRemote).map((_nuclideUri || _load_nuclideUri()).default.getHostname))).let((0, (_observable || _load_observable()).diffSets)()));}function observeRemovedHostnames() {return observeHostnames().flatMap(diff => _rxjsBundlesRxMinJs.Observable.from(diff.removed));}function observeAddedHostnames() {return observeHostnames().flatMap(diff => _rxjsBundlesRxMinJs.Observable.from(diff.added));}
function observeAddedHostnames() {
return observeHostnames().flatMap(diff => _RxMin.Observable.from(diff.added));
}

@@ -1,25 +0,32 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _UniversalDisposable;
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _UniversalDisposable() {
const data = _interopRequireDefault(require("nuclide-commons/UniversalDisposable"));
_UniversalDisposable = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
class ProviderRegistry {
constructor() {

@@ -30,4 +37,3 @@ this._providers = [];

addProvider(provider) {
const index = this._providers.findIndex(
p => provider.priority > p.priority);
const index = this._providers.findIndex(p => provider.priority > p.priority);

@@ -39,3 +45,4 @@ if (index === -1) {

}
return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {
return new (_UniversalDisposable().default)(() => {
this.removeProvider(provider);

@@ -47,2 +54,3 @@ });

const index = this._providers.indexOf(provider);
if (index !== -1) {

@@ -67,27 +75,20 @@ this._providers.splice(index, 1);

}
return null;
}
/**
* Iterates over all providers matching the grammar, in priority order.
*/
/**
* Iterates over all providers matching the grammar, in priority order.
*/
*findAllProviders(grammar) {
for (const provider of this._providers) {
if (
provider.grammarScopes == null ||
provider.grammarScopes.indexOf(grammar) !== -1)
{
if (provider.grammarScopes == null || provider.grammarScopes.indexOf(grammar) !== -1) {
yield provider;
}
}
}}exports.default = ProviderRegistry; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
}
}
exports.default = ProviderRegistry;

@@ -1,95 +0,158 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.wordAtPosition = wordAtPosition;
exports.trimRange = trimRange;
exports.getWordFromMouseEvent = getWordFromMouseEvent;
exports.getWordFromCursorOrSelection = getWordFromCursorOrSelection;
var _atom = require("atom");
function _range() {
const data = require("nuclide-commons/range");
_range = function () {
return data;
};
return data;
}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict-local
* @format
*/
/**
* Finds the word at the position. You can either provide a word regex yourself,
* or have Atom use the word regex in force at the scopes at that position,
* in which case it uses the optional includeNonWordCharacters, default true.
* (I know that's a weird default but it follows Atom's convention...)
*/
function wordAtPosition(editor, position, wordRegex) {
let wordRegex_;
if (wordRegex instanceof RegExp) {
wordRegex_ = wordRegex;
} else {
// What is the word regex associated with the position? We'd like to use
// atom$Cursor.wordRegExp, except that function gets the regex associated
// with the editor's current cursor while we want the regex associated with
// the specific position. So we re-implement it ourselves...
const nonWordChars = editor.getNonWordCharacters(position);
const escaped = nonWordChars.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); // We copied this escaping regex from atom$Cursor.wordRegexp, rather than
// using the library function 'escapeStringRegExp'. That's because the
// library function doesn't escape the hyphen character and so is
// unsuitable for use inside a range.
let r = `^[\t ]*$|[^\\s${escaped}]+`;
if (wordRegex == null || wordRegex.includeNonWordCharacters) {
r += `|[${escaped}]+`;
}
wordRegex_ = new RegExp(r, 'g');
}
return (0, _range().wordAtPositionFromBuffer)(editor.getBuffer(), position, wordRegex_);
}
/**
* Gets the trimmed range from a given range, i.e. moves the start and end points
* to the first and last non-whitespace characters (or specified regex)
* within the range respectively.
*
* @param editor the editor containing the range
* @param rangeToTrim the range to trim
* @param stopRegex stop trimming when the first match is found for this regex,
* defaults to first non-whitespace character
* @return atom$Range the trimmed range
*/
function trimRange(editor, rangeToTrim, stopRegex = /\S/) {
const buffer = editor.getBuffer();
let {
start,
end
} = rangeToTrim;
buffer.scanInRange(stopRegex, rangeToTrim, ({
range,
stop
}) => {
start = range.start;
stop();
});
buffer.backwardsScanInRange(stopRegex, rangeToTrim, ({
range,
stop
}) => {
end = range.end;
stop();
});
return new _atom.Range(start, end);
}
function getSingleWordAtPosition(editor, position) {
const match = wordAtPosition(editor, position); // We should only receive a single identifier from a single point.
if (match == null || match.wordMatch.length !== 1) {
return null;
}
return match.wordMatch[0];
}
/**
* Gets the word being right-clicked on in a MouseEvent. A good use case for
* this is performing an action on a word from a context menu.
*
* @param editor the editor containing the word where the MouseEvent occurred
* from
* @param event the MouseEvent containing the screen position of the click
*/
function getWordFromMouseEvent(editor, event) {
// We can't immediately get the identifier right-clicked on from
// the MouseEvent. Using its target element content would work in
// some cases but wouldn't work if there was additional content
// in the same element, such as in a comment.
const component = editor.getElement().component;
if (!component) {
throw new Error("Invariant violation: \"component\"");
} // This solution doesn't feel ideal but it is the way hyperclick does it.
wordAtPosition = wordAtPosition;exports.
const point = component.screenPositionForMouseEvent(event);
return getSingleWordAtPosition(editor, point);
}
/**
* Attempts to get a word from the last selection or cursor. A good use case for
* this is performing an action on an 'active' word after a command is triggered
* via a keybinding.
*
* @param editor the editor containing the 'active' word when the keybinding is
* triggered
*/
function getWordFromCursorOrSelection(editor) {
const selection = editor.getSelectedText();
if (selection && selection.length > 0) {
return selection;
} // There was no selection so we can go ahead and try the cursor position.
trimRange = trimRange;var _atom = require('atom');var _range;function _load_range() {return _range = require('nuclide-commons/range');}var _textEditor;function _load_textEditor() {return _textEditor = require('./text-editor');} /**
* Finds the word at the position. You can either provide a word regex yourself,
* or have Atom use the word regex in force at the scopes at that position,
* in which case it uses the optional includeNonWordCharacters, default true.
* (I know that's a weird default but it follows Atom's convention...)
*/function wordAtPosition(editor, position, wordRegex) {let wordRegex_;if (wordRegex instanceof RegExp) {wordRegex_ = wordRegex;} else {// What is the word regex associated with the position? We'd like to use
// atom$Cursor.wordRegExp, except that function gets the regex associated
// with the editor's current cursor while we want the regex associated with
// the specific position. So we re-implement it ourselves...
const nonWordChars = (0, (_textEditor || _load_textEditor()).getNonWordCharacters)(editor, position);const escaped = nonWordChars.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); // We copied this escaping regex from atom$Cursor.wordRegexp, rather than
// using the library function 'escapeStringRegExp'. That's because the
// library function doesn't escape the hyphen character and so is
// unsuitable for use inside a range.
let r = `^[\t ]*$|[^\\s${escaped}]+`;if (wordRegex == null || wordRegex.includeNonWordCharacters) {r += `|[${escaped}]+`;}wordRegex_ = new RegExp(r, 'g');}return (0, (_range || _load_range()).wordAtPositionFromBuffer)(editor.getBuffer(), position, wordRegex_);} /**
* Gets the trimmed range from a given range, i.e. moves the start and end points
* to the first and last non-whitespace characters (or specified regex)
* within the range respectively.
*
* @param editor the editor containing the range
* @param rangeToTrim the range to trim
* @param stopRegex stop trimming when the first match is found for this regex,
* defaults to first non-whitespace character
* @return atom$Range the trimmed range
*/ /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function trimRange(editor, rangeToTrim, stopRegex = /\S/) {const buffer = editor.getBuffer();let { start, end } = rangeToTrim;buffer.scanInRange(stopRegex, rangeToTrim, ({ range, stop }) => {start = range.start;stop();});buffer.backwardsScanInRange(stopRegex, rangeToTrim, ({ range, stop }) => {end = range.end;stop();});return new _atom.Range(start, end);}
const point = editor.getCursorScreenPosition();
return getSingleWordAtPosition(editor, point);
}

@@ -1,57 +0,30 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default =
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createLoggerMiddleware;
function _reduxLogger() {
const data = require("redux-logger");
_reduxLogger = function () {
return data;
};
return data;
}
function _featureConfig() {
const data = _interopRequireDefault(require("./feature-config"));
_featureConfig = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
createLoggerMiddleware;var _reduxLogger;function _load_reduxLogger() {return _reduxLogger = require('redux-logger');}var _featureConfig;function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('./feature-config'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /*
To turn on debug console logging for the feature you are debugging, add to your config.cson:
"*":
"nuclide":
"redux-debug-loggers": [
"<YOUR_APP_NAME>"
]
*/ // More options can be found here if you wish to enable them:
// https://github.com/evgenyrodionov/redux-logger#options
/**

@@ -67,2 +40,13 @@ * Copyright (c) 2017-present, Facebook, Inc.

* @format
*/const enabledLoggers = (_featureConfig || _load_featureConfig()).default.getWithDefaults('redux-debug-loggers', []);const noopMiddleware = store => next => action => next(action);function createLoggerMiddleware(appName, loggerConfig) {if (!enabledLoggers.includes(appName)) {return noopMiddleware;}return (0, (_reduxLogger || _load_reduxLogger()).createLogger)(loggerConfig);}
*/
const enabledLoggers = _featureConfig().default.getWithDefaults('redux-debug-loggers', []);
const noopMiddleware = store => next => action => next(action);
function createLoggerMiddleware(appName, loggerConfig) {
if (!enabledLoggers.includes(appName)) {
return noopMiddleware;
}
return (0, _reduxLogger().createLogger)(loggerConfig);
}

@@ -1,22 +0,58 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.jasmineAttachWorkspace = jasmineAttachWorkspace;
exports.attachWorkspace = attachWorkspace;
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict
* @format
*/
// Attach the Atom workspace to the DOM, and give it a reasonable size.
// This is important for tests that touch the text editor in 1.19+, as they'll have a height of 0
// unless properly attached with a valid viewport.
// NOTE: for Jest tests use `attachWorkspace()` function from this file
function jasmineAttachWorkspace() {
jasmine.attachToDOM(atom.views.getView(atom.workspace)); // Set the testing window dimensions (smallish, yet realistic).
const styleCSS = `
height: 600px;
width: 1000px;
`;
const content = document.querySelector('#jasmine-content');
if (!(content != null)) {
throw new Error("Invariant violation: \"content != null\"");
}
content.setAttribute('style', styleCSS); // Unset the 'top' attribute of the spec reporter to make the full window visible.
// This is purely for developer convenience when running specs in a visible window.
const specReporter = document.querySelector('.spec-reporter-container');
if (specReporter != null) {
specReporter.setAttribute('style', 'top: inherit');
}
}
function attachWorkspace() {
const container = document.createElement('div');
container.id = 'test-container';
if (!document.body) {
throw new Error("Invariant violation: \"document.body\"");
}
document.body.appendChild(container);
container.appendChild(atom.views.getView(atom.workspace)); // Set the testing window dimensions (smallish, yet realistic).
jasmineAttachWorkspace = jasmineAttachWorkspace; // Attach the Atom workspace to the DOM, and give it a reasonable size.
// This is important for tests that touch the text editor in 1.19+, as they'll have a height of 0
// unless properly attached with a valid viewport.
function jasmineAttachWorkspace() {jasmine.attachToDOM(atom.views.getView(atom.workspace)); // Set the testing window dimensions (smallish, yet realistic).
const styleCSS = `

@@ -26,22 +62,16 @@ height: 600px;

`;
const content = document.querySelector('#jasmine-content');if (!(
content != null)) {throw new Error('Invariant violation: "content != null"');}
content.setAttribute('style', styleCSS);
const content = document.querySelector('#test-container');
// Unset the 'top' attribute of the spec reporter to make the full window visible.
if (!(content != null)) {
throw new Error("Invariant violation: \"content != null\"");
}
content.setAttribute('style', styleCSS); // Unset the 'top' attribute of the spec reporter to make the full window visible.
// This is purely for developer convenience when running specs in a visible window.
const specReporter = document.querySelector('.spec-reporter-container');
if (specReporter != null) {
specReporter.setAttribute('style', 'top: inherit');
}
} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
}

@@ -1,47 +0,31 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toUnifiedDiff = toUnifiedDiff;
var _atom = require("atom");
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict-local
* @format
*/
function toUnifiedDiff(filename, buffer, edits, contextRows = 1) {
const hunks = getHunks(buffer, edits, contextRows);
return [`--- ${filename}`, `+++ ${filename}`].concat(mapHunkToString(buffer, hunks, contextRows)).join('\n');
}
function getHunks(buffer, edits, contextRows) {
return edits.sort((e1, e2) => e1.oldRange.compare(e2.oldRange)).reduce((mergedEdits, nextEdit) => {
const edit = mergedEdits[mergedEdits.length - 1];
toUnifiedDiff = toUnifiedDiff;var _atom = require('atom');function toUnifiedDiff(
filename,
buffer,
edits,
contextRows = 1)
{
const hunks = getHunks(buffer, edits, contextRows);
return [`--- ${filename}`, `+++ ${filename}`].
concat(mapHunkToString(buffer, hunks, contextRows)).
join('\n');
} /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function getHunks(buffer, edits, contextRows) {return edits.sort((e1, e2) => e1.oldRange.compare(e2.oldRange)).reduce((mergedEdits, nextEdit) => {const edit = mergedEdits[mergedEdits.length - 1];
if (
edit &&
nextEdit.oldRange.start.row <= edit.oldRange.end.row + contextRows)
{
if (edit && nextEdit.oldRange.start.row <= edit.oldRange.end.row + contextRows) {
mergedEdits[mergedEdits.length - 1] = mergeEdit(buffer, edit, nextEdit);

@@ -51,27 +35,23 @@ } else {

}
return mergedEdits;
}, []).
map(edit => {
}, []).map(edit => {
const oldRange = edit.oldRange;
const rows = oldRange.getRows();
const newText =
buffer.lineForRow(rows[0]).substring(0, oldRange.start.column) +
edit.newText +
buffer.lineForRow(rows[rows.length - 1]).substring(oldRange.end.column);
const newText = buffer.lineForRow(rows[0]).substring(0, oldRange.start.column) + edit.newText + buffer.lineForRow(rows[rows.length - 1]).substring(oldRange.end.column);
const newLines = newText.split(/\r\n|\r|\n/);
return { rows, newLines };
return {
rows,
newLines
};
});
}
function mergeEdit(
buffer,
e1,
e2)
{if (!
e1.oldRange.end.isLessThanOrEqual(e2.oldRange.start)) {throw new Error('Invariant violation: "e1.oldRange.end.isLessThanOrEqual(e2.oldRange.start)"');}
function mergeEdit(buffer, e1, e2) {
if (!e1.oldRange.end.isLessThanOrEqual(e2.oldRange.start)) {
throw new Error("Invariant violation: \"e1.oldRange.end.isLessThanOrEqual(e2.oldRange.start)\"");
}
const mergedEdit = {};
mergedEdit.newText =
e1.newText +
buffer.getTextInRange(new _atom.Range(e1.oldRange.end, e2.oldRange.start)) +
e2.newText;
mergedEdit.newText = e1.newText + buffer.getTextInRange(new _atom.Range(e1.oldRange.end, e2.oldRange.start)) + e2.newText;
mergedEdit.oldRange = e1.oldRange.union(e2.oldRange);

@@ -81,7 +61,3 @@ return mergedEdit;

function mapHunkToString(
buffer,
hunks,
contextRows)
{
function mapHunkToString(buffer, hunks, contextRows) {
// This requires storing some state across the map() to compute the row

@@ -91,11 +67,17 @@ // numbers correctly.

return hunks.map(hunk => {
const { rows, newLines } = hunk;
const {
rows,
newLines
} = hunk;
const beforeRows = [];
const afterRows = [];
for (let i = 1; i <= contextRows; i++) {
const beforeRow = rows[0] - i;
const afterRow = rows[rows.length - 1] + i;
if (beforeRow >= 0) {
beforeRows.unshift(beforeRow);
}
if (afterRow <= buffer.getLastRow()) {

@@ -105,2 +87,3 @@ afterRows.push(afterRow);

}
const oldBeginRow = rows[0] - beforeRows.length + 1;

@@ -110,7 +93,4 @@ const oldRowLength = rows.length + beforeRows.length + afterRows.length;

const newRowLength = newLines.length + beforeRows.length + afterRows.length;
const parts = [];
parts.push(
`@@ -${oldBeginRow},${oldRowLength} +${newBeginRow},${newRowLength} @@`);
parts.push(`@@ -${oldBeginRow},${oldRowLength} +${newBeginRow},${newRowLength} @@`);
beforeRows.forEach(row => {

@@ -117,0 +97,0 @@ parts.push(' ' + buffer.lineForRow(row));

@@ -1,116 +0,135 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.applyTextEditsForMultipleFiles = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyTextEditsForMultipleFiles = applyTextEditsForMultipleFiles;
exports.applyTextEdits = applyTextEdits;
exports.applyTextEditsToBuffer = applyTextEditsToBuffer;
function _log4js() {
const data = require("log4js");
_log4js = function () {
return data;
};
return data;
}
function _textEditor() {
const data = require("./text-editor");
_textEditor = function () {
return data;
};
return data;
}
function _goToLocation() {
const data = require("./go-to-location");
_goToLocation = function () {
return data;
};
return data;
}
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict-local
* @format
*/
/**
* Attempts to apply the given patches for multiple files. Accepts a Map as input
* with file paths as keys and a corresponding array of TextEdits as values.
*
* It is an error to send overlapping text-edits. All text-edits describe changes
* made to the initial document version. The order of the edits does not matter
* as they will be sorted before they are applied.
*
* All changes will be applied to the buffers but not saved. If a file is not
* currently open, it will be opened.
*
* If a change is undone (Cmd+Z), only the changes of the current
* file will be undone. All of the changes for that file will be undone at once.
*
* Returns true if the application was successful, otherwise false. If any of
* the changes fail, for ANY file, then none of the changes are applied.
*/
async function applyTextEditsForMultipleFiles(changes) {
const paths = Array.from(changes.keys()); // NOTE: There is a race here. If the file contents change while the
// editors are being opened, then the ranges of the TextEdits will be off.
// However, currently this is only used to applyEdits to open files.
const editors = await Promise.all(paths.map(async path => (0, _goToLocation().goToLocation)(path)));
const checkpoints = editors.map(editor => {
if (!(editor != null)) {
throw new Error("Invariant violation: \"editor != null\"");
}
const buffer = editor.getBuffer();
return [buffer, buffer.createCheckpoint()];
});
const allOkay = paths.reduce((successSoFar, path) => {
const edits = changes.get(path);
return successSoFar && edits != null && applyTextEdits(path, ...edits);
}, true);
if (!allOkay) {
checkpoints.forEach(([buffer, checkPoint]) => {
buffer.revertToCheckpoint(checkPoint);
return false;
});
}
return allOkay;
}
/**
* Attempts to apply the given patches to the given file.
*
* It is an error to send overlapping edits. The order of the edits does not
* matter (they will be sorted before they are applied).
*
* The file must be currently open in Atom, and the changes will be applied to the buffer but not
* saved.
*
* Returns true if the application was successful, otherwise false (e.g. if the oldText did not
* match).
*/
function applyTextEdits(path, ...edits) {
const sortedEdits = sortEdits(edits);
const editor = (0, _textEditor().existingEditorForUri)(path);
if (!(editor != null)) {
throw new Error("Invariant violation: \"editor != null\"");
}
return applySortedTextEditsToBuffer(editor.getBuffer(), sortedEdits);
}
/**
* Attempts to apply the given patches for multiple files. Accepts a Map as input
* with file paths as keys and a corresponding array of TextEdits as values.
*
* It is an error to send overlapping text-edits. All text-edits describe changes
* made to the initial document version. The order of the edits does not matter
* as they will be sorted before they are applied.
*
* All changes will be applied to the buffers but not saved. If a file is not
* currently open, it will be opened.
*
* If a change is undone (Cmd+Z), only the changes of the current
* file will be undone. All of the changes for that file will be undone at once.
*
* Returns true if the application was successful, otherwise false. If any of
* the changes fail, for ANY file, then none of the changes are applied.
*/let applyTextEditsForMultipleFiles = exports.applyTextEditsForMultipleFiles = (() => {var _ref = (0, _asyncToGenerator.default)(
function* (
changes)
{
const paths = Array.from(changes.keys());
// NOTE: There is a race here. If the file contents change while the
// editors are being opened, then the ranges of the TextEdits will be off.
// However, currently this is only used to applyEdits to open files.
const editors = yield Promise.all(
paths.map((() => {var _ref2 = (0, _asyncToGenerator.default)(function* (path) {return (0, (_goToLocation || _load_goToLocation()).goToLocation)(path);});return function (_x2) {return _ref2.apply(this, arguments);};})()));
const checkpoints = editors.map(function (editor) {if (!(
editor != null)) {throw new Error('Invariant violation: "editor != null"');}
const buffer = editor.getBuffer();
return [buffer, buffer.createCheckpoint()];
});
const allOkay = paths.reduce(function (successSoFar, path) {
const edits = changes.get(path);
return successSoFar && edits != null && applyTextEdits(path, ...edits);
}, true);
if (!allOkay) {
checkpoints.forEach(function ([buffer, checkPoint]) {
buffer.revertToCheckpoint(checkPoint);
return false;
});
}
return allOkay;
});return function applyTextEditsForMultipleFiles(_x) {return _ref.apply(this, arguments);};})();
/**
* Attempts to apply the given patches to the given file.
*
* It is an error to send overlapping edits. The order of the edits does not
* matter (they will be sorted before they are applied).
*
* The file must be currently open in Atom, and the changes will be applied to the buffer but not
* saved.
*
* Returns true if the application was successful, otherwise false (e.g. if the oldText did not
* match).
*/ /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/exports.applyTextEdits = applyTextEdits;exports.
applyTextEditsToBuffer = applyTextEditsToBuffer;var _log4js;function _load_log4js() {return _log4js = require('log4js');}var _textEditor;function _load_textEditor() {return _textEditor = require('./text-editor');}var _goToLocation;function _load_goToLocation() {return _goToLocation = require('./go-to-location');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function applyTextEdits(path, ...edits) {const sortedEdits = sortEdits(edits);const editor = (0, (_textEditor || _load_textEditor()).existingEditorForUri)(path);if (!(editor != null)) {throw new Error('Invariant violation: "editor != null"');}return applySortedTextEditsToBuffer(editor.getBuffer(), sortedEdits);}function applyTextEditsToBuffer(
buffer,
edits)
{
function applyTextEditsToBuffer(buffer, edits) {
return applySortedTextEditsToBuffer(buffer, sortEdits(edits));
}
function applySortedTextEditsToBuffer(
buffer,
edits)
{
function applySortedTextEditsToBuffer(buffer, edits) {
// For every edit, the start of its range will be after the end of the
// previous edit's range.
if (editsOverlap(edits)) {
(0, (_log4js || _load_log4js()).getLogger)('text-edit').warn(
'applyTextEdits was called with overlapping edits.');
(0, _log4js().getLogger)('text-edit').warn('applyTextEdits was called with overlapping edits.');
return false;
} // Special-case whole-buffer changes to minimize disruption.
return false;
}
// Special-case whole-buffer changes to minimize disruption.
if (edits.length === 1 && edits[0].oldRange.isEqual(buffer.getRange())) {

@@ -120,2 +139,3 @@ if (edits[0].oldText != null && edits[0].oldText !== buffer.getText()) {

}
buffer.setTextViaDiff(edits[0].newText);

@@ -125,9 +145,9 @@ return true;

const checkpoint = buffer.createCheckpoint();
const checkpoint = buffer.createCheckpoint(); // Iterate through in reverse order. Edits earlier in the file can move around text later in the
// file, so to avoid conflicts edits should be applied last first.
// Iterate through in reverse order. Edits earlier in the file can move around text later in the
// file, so to avoid conflicts edits should be applied last first.
for (let i = edits.length - 1; i >= 0; i--) {
const edit = edits[i];
const success = applyToBuffer(buffer, edit);
if (!success) {

@@ -149,2 +169,3 @@ buffer.revertToCheckpoint(checkpoint);

const lineLength = buffer.lineLengthForRow(edit.oldRange.start.row);
if (edit.oldRange.end.column > lineLength) {

@@ -154,4 +175,6 @@ return false;

}
if (edit.oldText != null) {
const currentText = buffer.getTextInRange(edit.oldRange);
if (currentText !== edit.oldText) {

@@ -161,17 +184,15 @@ return false;

}
buffer.setTextInRange(edit.oldRange, edit.newText);
return true;
}
} // Returns whether an array of sorted TextEdits contain an overlapping range.
// Returns whether an array of sorted TextEdits contain an overlapping range.
function editsOverlap(sortedEdits) {
for (let i = 0; i < sortedEdits.length - 1; i++) {
if (
sortedEdits[i].oldRange.end.isGreaterThan(
sortedEdits[i + 1].oldRange.start))
{
if (sortedEdits[i].oldRange.end.isGreaterThan(sortedEdits[i + 1].oldRange.start)) {
return true;
}
}
return false;

@@ -182,6 +203,3 @@ }

// stable sort (preserve order of edits starting in the same location)
return edits.
map((edit, i) => [edit, i]).
sort(([e1, i1], [e2, i2]) => e1.oldRange.compare(e2.oldRange) || i1 - i2).
map(([edit]) => edit);
return edits.map((edit, i) => [edit, i]).sort(([e1, i1], [e2, i2]) => e1.oldRange.start.compare(e2.oldRange.start) || e1.oldRange.end.compare(e2.oldRange.end) || i1 - i2).map(([edit]) => edit);
}

@@ -1,296 +0,217 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.existingEditorForUri = existingEditorForUri;
exports.existingEditorForBuffer = existingEditorForBuffer;
exports.getViewOfEditor = getViewOfEditor;
exports.getScrollTop = getScrollTop;
exports.setScrollTop = setScrollTop;
exports.setPositionAndScroll = setPositionAndScroll;
exports.getCursorPositions = getCursorPositions;
exports.observeEditorDestroy = observeEditorDestroy;
exports.enforceReadOnlyEditor = enforceReadOnlyEditor;
exports.enforceSoftWrap = enforceSoftWrap;
exports.isValidTextEditor = isValidTextEditor;
exports.centerScrollToBufferLine = centerScrollToBufferLine;
var _atom = require("atom");
function _UniversalDisposable() {
const data = _interopRequireDefault(require("nuclide-commons/UniversalDisposable"));
_UniversalDisposable = function () {
return data;
};
return data;
}
var _RxMin = require("rxjs/bundles/Rx.min.js");
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
/**
* Returns a text editor that has the given path open, or null if none exists. If there are multiple
* text editors for this path, one is chosen arbitrarily.
*/
function existingEditorForUri(path) {
// This isn't ideal but realistically iterating through even a few hundred editors shouldn't be a
// real problem. And if you have more than a few hundred you probably have bigger problems.
for (const editor of atom.workspace.getTextEditors()) {
if (editor.getPath() === path) {
return editor;
}
}
return null;
}
/**
* Returns a text editor that has the given buffer open, or null if none exists. If there are
* multiple text editors for this buffer, one is chosen arbitrarily.
*/
function existingEditorForBuffer(buffer) {
// This isn't ideal but realistically iterating through even a few hundred editors shouldn't be a
// real problem. And if you have more than a few hundred you probably have bigger problems.
for (const editor of atom.workspace.getTextEditors()) {
if (editor.getBuffer() === buffer) {
return editor;
}
}
return null;
}
function getViewOfEditor(editor) {
return atom.views.getView(editor);
}
function getScrollTop(editor) {
return getViewOfEditor(editor).getScrollTop();
}
function setScrollTop(editor, scrollTop) {
getViewOfEditor(editor).setScrollTop(scrollTop);
}
/**
* Does a best effort to set an editor pane to a given cursor position & scroll.
* Does not ensure that the current cursor position is visible.
*
* Can be used with editor.getCursorBufferPosition() & getScrollTop() to restore
* an editors cursor and scroll.
*/
function setPositionAndScroll(editor, position, scrollTop) {
editor.setCursorBufferPosition(position, {
autoscroll: false
});
setScrollTop(editor, scrollTop);
}
function getCursorPositions(editor) {
return _RxMin.Observable.defer(() => {
// This will behave strangely in the face of multiple cursors. Consider supporting multiple
// cursors in the future.
const cursor = editor.getCursors()[0];
if (!(cursor != null)) {
throw new Error("Invariant violation: \"cursor != null\"");
}
return _RxMin.Observable.merge(_RxMin.Observable.of(cursor.getBufferPosition()), (0, _event().observableFromSubscribeFunction)(cursor.onDidChangePosition.bind(cursor)).map(event => event.newBufferPosition));
});
}
existingEditorForUri = existingEditorForUri;exports.
function observeEditorDestroy(editor) {
return (0, _event().observableFromSubscribeFunction)(editor.onDidDestroy.bind(editor)).map(event => editor).take(1);
} // As of the introduction of atom.workspace.buildTextEditor(), it is no longer possible to
// subclass TextEditor to create a ReadOnlyTextEditor. Instead, the way to achieve this effect
// is to create an ordinary TextEditor and then override any methods that would allow it to
// change its contents.
// TODO: https://github.com/atom/atom/issues/9237.
function enforceReadOnlyEditor(textEditor, readOnlyExceptions = ['append', 'setText']) {
// Cancel insert events to prevent typing in the text editor and disallow editing (read-only).
const willInsertTextDisposable = textEditor.onWillInsertText(event => {
event.cancel();
});
return new (_UniversalDisposable().default)(willInsertTextDisposable, // `setText` & `append` are the only exceptions that's used to set the read-only text.
enforceReadOnlyBuffer(textEditor.getBuffer(), readOnlyExceptions));
}
function enforceReadOnlyBuffer(textBuffer, readOnlyExceptions = []) {
const noop = () => {}; // All user edits use `transact` - so, mocking this will effectively make the editor read-only.
const originalApplyChange = textBuffer.applyChange;
const originalReadOnlyExceptionFunctions = {};
textBuffer.applyChange = noop;
readOnlyExceptions.forEach(passReadOnlyException);
function passReadOnlyException(functionName) {
const buffer = textBuffer;
const originalFunction = buffer[functionName];
originalReadOnlyExceptionFunctions[functionName] = originalFunction;
buffer[functionName] = function () {
textBuffer.applyChange = originalApplyChange;
const result = originalFunction.apply(textBuffer, arguments);
textBuffer.applyChange = noop;
return result;
};
}
return new (_UniversalDisposable().default)(() => {
textBuffer.applyChange = originalApplyChange;
const buffer = textBuffer;
readOnlyExceptions.forEach(functionName => buffer[functionName] = originalReadOnlyExceptionFunctions[functionName]);
});
} // Turn off soft wrap setting for these editors so diffs properly align.
// Some text editor register sometimes override the set soft wrapping
// after mounting an editor to the workspace - here, that's watched and reset to `false`.
function enforceSoftWrap(editor, enforcedSoftWrap) {
editor.setSoftWrapped(enforcedSoftWrap);
return editor.onDidChangeSoftWrapped(softWrapped => {
if (softWrapped !== enforcedSoftWrap) {
// Reset the overridden softWrap to `false` once the operation completes.
process.nextTick(() => {
if (!editor.isDestroyed()) {
editor.setSoftWrapped(enforcedSoftWrap);
}
});
}
});
}
/**
* Checks if an object (typically an Atom pane) is a TextEditor.
* Could be replaced with atom.workspace.isValidTextEditor,
* but Flow doesn't support %checks in methods yet.
*/
function isValidTextEditor(item) {
return item instanceof _atom.TextEditor;
}
existingEditorForBuffer = existingEditorForBuffer;exports.
getViewOfEditor = getViewOfEditor;exports.
getScrollTop = getScrollTop;exports.
setScrollTop = setScrollTop;exports.
setPositionAndScroll = setPositionAndScroll;exports.
getCursorPositions = getCursorPositions;exports.
observeEditorDestroy = observeEditorDestroy;exports.
enforceReadOnlyEditor = enforceReadOnlyEditor;exports.
enforceSoftWrap = enforceSoftWrap;exports.
observeTextEditors = observeTextEditors;exports.
isValidTextEditor = isValidTextEditor;exports.
centerScrollToBufferLine = centerScrollToBufferLine;exports.
getNonWordCharacters = getNonWordCharacters;var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _semver;function _load_semver() {return _semver = _interopRequireDefault(require('semver'));}var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /**
* Returns a text editor that has the given path open, or null if none exists. If there are multiple
* text editors for this path, one is chosen arbitrarily.
*/function existingEditorForUri(path) {// This isn't ideal but realistically iterating through even a few hundred editors shouldn't be a
// real problem. And if you have more than a few hundred you probably have bigger problems.
for (const editor of atom.workspace.getTextEditors()) {if (editor.getPath() === path) {return editor;}}return null;} /**
* Returns a text editor that has the given buffer open, or null if none exists. If there are
* multiple text editors for this buffer, one is chosen arbitrarily.
*/ /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/function existingEditorForBuffer(buffer) {// This isn't ideal but realistically iterating through even a few hundred editors shouldn't be a
// real problem. And if you have more than a few hundred you probably have bigger problems.
for (const editor of atom.workspace.getTextEditors()) {if (editor.getBuffer() === buffer) {return editor;}}return null;}function getViewOfEditor(editor) {return atom.views.getView(editor);}function getScrollTop(editor) {return getViewOfEditor(editor).getScrollTop();}function setScrollTop(editor, scrollTop) {getViewOfEditor(editor).setScrollTop(scrollTop);} /**
* Does a best effort to set an editor pane to a given cursor position & scroll.
* Does not ensure that the current cursor position is visible.
*
* Can be used with editor.getCursorBufferPosition() & getScrollTop() to restore
* an editors cursor and scroll.
*/function setPositionAndScroll(editor, position, scrollTop) {editor.setCursorBufferPosition(position, { autoscroll: false });setScrollTop(editor, scrollTop);}function getCursorPositions(editor) {return _rxjsBundlesRxMinJs.Observable.defer(() => {// This will behave strangely in the face of multiple cursors. Consider supporting multiple
// cursors in the future.
const cursor = editor.getCursors()[0];if (!(cursor != null)) {throw new Error('Invariant violation: "cursor != null"');}return _rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.of(cursor.getBufferPosition()), (0, (_event || _load_event()).observableFromSubscribeFunction)(cursor.onDidChangePosition.bind(cursor)).map(event => event.newBufferPosition));});}function observeEditorDestroy(editor) {return (0, (_event || _load_event()).observableFromSubscribeFunction)(editor.onDidDestroy.bind(editor)).map(event => editor).take(1);} // As of the introduction of atom.workspace.buildTextEditor(), it is no longer possible to
// subclass TextEditor to create a ReadOnlyTextEditor. Instead, the way to achieve this effect
// is to create an ordinary TextEditor and then override any methods that would allow it to
// change its contents.
// TODO: https://github.com/atom/atom/issues/9237.
function enforceReadOnlyEditor(textEditor, readOnlyExceptions = ['append', 'setText']) {// Cancel insert events to prevent typing in the text editor and disallow editing (read-only).
const willInsertTextDisposable = textEditor.onWillInsertText(event => {event.cancel();});return new (_UniversalDisposable || _load_UniversalDisposable()).default(willInsertTextDisposable, // `setText` & `append` are the only exceptions that's used to set the read-only text.
enforceReadOnlyBuffer(textEditor.getBuffer(), readOnlyExceptions));}function enforceReadOnlyBuffer(textBuffer, readOnlyExceptions = []) {const noop = () => {}; // All user edits use `transact` - so, mocking this will effectively make the editor read-only.
const originalApplyChange = textBuffer.applyChange;const originalReadOnlyExceptionFunctions = {};textBuffer.applyChange = noop;readOnlyExceptions.forEach(passReadOnlyException);function passReadOnlyException(functionName) {const buffer = textBuffer;const originalFunction = buffer[functionName];originalReadOnlyExceptionFunctions[functionName] = originalFunction;buffer[functionName] = function () {textBuffer.applyChange = originalApplyChange;const result = originalFunction.apply(textBuffer, arguments);textBuffer.applyChange = noop;return result;};}return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {textBuffer.applyChange = originalApplyChange;const buffer = textBuffer;readOnlyExceptions.forEach(functionName => buffer[functionName] = originalReadOnlyExceptionFunctions[functionName]);});} // Turn off soft wrap setting for these editors so diffs properly align.
// Some text editor register sometimes override the set soft wrapping
// after mounting an editor to the workspace - here, that's watched and reset to `false`.
function enforceSoftWrap(editor, enforcedSoftWrap) {editor.setSoftWrapped(enforcedSoftWrap);return editor.onDidChangeSoftWrapped(softWrapped => {if (softWrapped !== enforcedSoftWrap) {// Reset the overridden softWrap to `false` once the operation completes.
process.nextTick(() => {if (!editor.isDestroyed()) {editor.setSoftWrapped(enforcedSoftWrap);}});}});} /**
* Small wrapper around `atom.workspace.observeTextEditors` that filters out
* uninitialized remote editors. Most callers should use this one instead.
*/function observeTextEditors(callback) {// The one place where atom.workspace.observeTextEditors needs to be used.
// eslint-disable-next-line rulesdir/atom-apis
return atom.workspace.observeTextEditors(editor => {if (isValidTextEditor(editor)) {callback(editor);}});} /**
* Checks if an object (typically an Atom pane) is a TextEditor with a non-broken path.
*/function isValidTextEditor(item) {// eslint-disable-next-line rulesdir/atom-apis
if (atom.workspace.isTextEditor(item)) {return !(_nuclideUri || _load_nuclideUri()).default.isBrokenDeserializedUri(item.getPath());}return false;}function centerScrollToBufferLine(textEditorElement, bufferLineNumber) {const textEditor = textEditorElement.getModel();const pixelPositionTop = textEditorElement.pixelPositionForBufferPosition([bufferLineNumber, 0]).top; // Manually calculate the scroll location, instead of using
function centerScrollToBufferLine(textEditorElement, bufferLineNumber) {
const textEditor = textEditorElement.getModel();
const pixelPositionTop = textEditorElement.pixelPositionForBufferPosition([bufferLineNumber, 0]).top; // Manually calculate the scroll location, instead of using
// `textEditor.scrollToBufferPosition([lineNumber, 0], {center: true})`
// because that API to wouldn't center the line if it was in the visible screen range.
const scrollTop = pixelPositionTop + textEditor.getLineHeightInPixels() / 2 - textEditorElement.clientHeight / 2;textEditorElement.setScrollTop(Math.max(scrollTop, 1));textEditorElement.focus();textEditor.setCursorBufferPosition([bufferLineNumber, 0], { autoscroll: false });}function getNonWordCharacters(editor, position) {if ((_semver || _load_semver()).default.gte(atom.getVersion(), '1.24.0-beta0')) {return editor.getNonWordCharacters(position);} else {// This used to take a scope descriptor.
const scope = position == null ? null : editor.scopeDescriptorForBufferPosition(position);return editor.getNonWordCharacters(scope);}}
const scrollTop = pixelPositionTop + textEditor.getLineHeightInPixels() / 2 - textEditorElement.clientHeight / 2;
textEditorElement.setScrollTop(Math.max(scrollTop, 1));
textEditorElement.focus();
textEditor.setCursorBufferPosition([bufferLineNumber, 0], {
autoscroll: false
});
}

@@ -1,382 +0,359 @@

'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.__TEST__ = exports.TextEventDispatcher = undefined;exports.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.observeTextEditorEvents = observeTextEditorEvents;
exports.__TEST__ = exports.TextEventDispatcher = void 0;
var _RxMin = require("rxjs/bundles/Rx.min.js");
function _debounce() {
const data = _interopRequireDefault(require("nuclide-commons/debounce"));
_debounce = function () {
return data;
};
return data;
}
function _event() {
const data = require("nuclide-commons/event");
_event = function () {
return data;
};
return data;
}
function _UniversalDisposable() {
const data = _interopRequireDefault(require("nuclide-commons/UniversalDisposable"));
_UniversalDisposable = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* strict-local
* @format
*/
// A reload changes the text in the buffer, so it should trigger a refresh.
const FILE_CHANGE_EVENTS = ['did-change', 'did-reload', 'did-open']; // A reload basically indicates that an external program saved the file, so
// it should trigger a refresh.
const FILE_SAVE_EVENTS = ['did-save', 'did-reload', 'did-open'];
/**
* Stores callbacks keyed on grammar and event, to allow for easy retrieval when
* we need to dispatch to all callbacks registered for a given (grammar, event)
* pair.
*/
class TextCallbackContainer {
// grammar -> event -> callback
// invariant: no empty maps or sets (they should be removed instead)
// event -> callback
// invariant: no keys mapping to empty sets (they should be removed instead)
constructor() {
this._callbacks = new Map();
this._allGrammarCallbacks = new Map();
}
getCallbacks(grammar, event) {
const eventMap = this._callbacks.get(grammar);
const callbacksForGrammar = this._getCallbacksFromEventMap(eventMap, event);
const callbacksForAll = this._getCallbacksFromEventMap(this._allGrammarCallbacks, event);
const resultSet = new Set();
const add = callback => {
resultSet.add(callback);
};
callbacksForGrammar.forEach(add);
callbacksForAll.forEach(add);
return resultSet;
}
isEmpty() {
return this._callbacks.size === 0 && this._allGrammarCallbacks.size === 0;
}
_getCallbacksFromEventMap(eventMap, event) {
if (!eventMap) {
return new Set();
}
const callbackSet = eventMap.get(event);
if (!callbackSet) {
return new Set();
}
return callbackSet;
}
addCallback(grammarScopes, events, callback) {
if (grammarScopes === 'all') {
this._addToEventMap(this._allGrammarCallbacks, events, callback);
} else {
for (const grammarScope of grammarScopes) {
let eventMap = this._callbacks.get(grammarScope);
if (!eventMap) {
eventMap = new Map();
this._callbacks.set(grammarScope, eventMap);
}
this._addToEventMap(eventMap, events, callback);
}
}
} // remove the callbacks, maintaining the invariant that there should be no
// empty maps or sets in this._callbacks
removeCallback(grammarScopes, events, callback) {
if (grammarScopes === 'all') {
this._removeFromEventMap(this._allGrammarCallbacks, events, callback);
} else {
for (const grammarScope of grammarScopes) {
const eventMap = this._callbacks.get(grammarScope);
if (!eventMap) {
throw new Error("Invariant violation: \"eventMap\"");
}
this._removeFromEventMap(eventMap, events, callback);
if (eventMap.size === 0) {
this._callbacks.delete(grammarScope);
}
}
}
}
_addToEventMap(eventMap, events, callback) {
for (const event of events) {
let callbackSet = eventMap.get(event);
if (!callbackSet) {
callbackSet = new Set();
eventMap.set(event, callbackSet);
}
callbackSet.add(callback);
}
}
_removeFromEventMap(eventMap, events, callback) {
for (const event of events) {
const callbackSet = eventMap.get(event);
if (!callbackSet) {
throw new Error("Invariant violation: \"callbackSet\"");
}
callbackSet.delete(callback);
if (callbackSet.size === 0) {
eventMap.delete(event);
}
}
}
}
/**
* Meant to make it simple and easy for a DiagnosticProvider to subscribe to
* relevant events. Currently provides two methods, onFileChange and onFileSave.
* A DiagnosticProvider will typically subscribe to only one, depending on
* whether it wants to be notified whenever a file changes or only when it is
* saved.
*
* Both methods take two arguments:
* - An Iterable of grammars for which the DiagnosticProvider can provide
* diagnostics.
* - The callback to be called on a text event.
*
* A TextEventDispatcher will be subscribed to text events if and only if it has
* subscribers of its own. If all subscribers unsubscribe, it will unsubscribe
* from Atom's text events.
*
*/
class TextEventDispatcher {
constructor() {
this._callbackContainer = new TextCallbackContainer();
this._editorListenerDisposable = null;
this._pendingEvents = new WeakMap();
}
_onEvents(grammarScopes, events, callback) {
if (this._callbackContainer.isEmpty()) {
this._registerEditorListeners();
} // Sometimes these events get triggered several times in succession
// (particularly on startup).
const debouncedCallback = (0, _debounce().default)(callback, 50, true);
this._callbackContainer.addCallback(grammarScopes, events, debouncedCallback);
const disposables = new (_UniversalDisposable().default)(() => {
this._callbackContainer.removeCallback(grammarScopes, events, debouncedCallback);
if (this._callbackContainer.isEmpty()) {
this._deregisterEditorListeners();
}
});
return disposables;
}
onFileChange(grammarScopes, callback) {
return this._onEvents(grammarScopes, FILE_CHANGE_EVENTS, callback);
}
onAnyFileChange(callback) {
return this._onEvents('all', FILE_CHANGE_EVENTS, callback);
}
onFileSave(grammarScopes, callback) {
return this._onEvents(grammarScopes, FILE_SAVE_EVENTS, callback);
}
onAnyFileSave(callback) {
return this._onEvents('all', FILE_SAVE_EVENTS, callback);
}
_registerEditorListeners() {
if (!this._editorListenerDisposable) {
this._editorListenerDisposable = new (_UniversalDisposable().default)();
} // Whenever the active pane item changes, we check to see if there are any
// pending events for the newly-focused TextEditor.
this._getEditorListenerDisposable().add(atom.workspace.onDidChangeActivePaneItem(() => {
const currentEditor = atom.workspace.getActiveTextEditor();
if (currentEditor) {
const pendingEvents = this._pendingEvents.get(currentEditor.getBuffer());
if (pendingEvents) {
for (const event of pendingEvents) {
this._dispatchEvents(currentEditor, event);
}
this._pendingEvents.delete(currentEditor.getBuffer());
}
}
}));
this._getEditorListenerDisposable().add(atom.workspace.observeTextEditors(editor => {
const buffer = editor.getBuffer();
const makeDispatch = event => {
return () => {
this._dispatchEvents(editor, event);
};
};
this._getEditorListenerDisposable().addUntilDestroyed(editor, buffer.onDidStopChanging(makeDispatch('did-change')), buffer.onDidSave(makeDispatch('did-save')), buffer.onDidReload(makeDispatch('did-reload'))); // During reload, many text editors are opened simultaneously.
// Due to the debounce on the event callback, this means that many editors never receive
// a 'did-open' event. To work around this, defer editor open events so that simultaneous
// open events are properly registered as pending.
setImmediate(() => this._dispatchEvents(editor, 'did-open'));
}));
}
_deregisterEditorListeners() {
if (this._editorListenerDisposable) {
this._getEditorListenerDisposable().dispose();
this._editorListenerDisposable = null;
}
}
_dispatchEvents(editor, event) {
const currentEditor = atom.workspace.getActiveTextEditor();
if (currentEditor && editor === currentEditor) {
const callbacks = this._callbackContainer.getCallbacks(editor.getGrammar().scopeName, event);
for (const callback of callbacks) {
callback(editor);
} // We want to avoid storing pending events if this event was generated by
// the same buffer as the current editor, to avoid duplicating events when
// multiple panes have the same file open.
} else if (!currentEditor || editor.getBuffer() !== currentEditor.getBuffer()) {
// Trigger this event next time we switch to an editor with this buffer.
const buffer = editor.getBuffer();
let events = this._pendingEvents.get(buffer);
if (!events) {
events = new Set();
this._pendingEvents.set(buffer, events);
}
events.add(event);
}
}
_getEditorListenerDisposable() {
const disposable = this._editorListenerDisposable;
if (!disposable) {
throw new Error('TextEventDispatcher disposable is not initialized');
}
return disposable;
}
}
exports.TextEventDispatcher = TextEventDispatcher;
function observeTextEditorEvents(grammarScopes, events) {
return _RxMin.Observable.defer(() => {
const dispatcher = new TextEventDispatcher();
if (events === 'changes') {
if (grammarScopes === 'all') {
return (0, _event().observableFromSubscribeFunction)(cb => dispatcher.onAnyFileChange(cb));
} else {
return (0, _event().observableFromSubscribeFunction)(cb => dispatcher.onFileChange(grammarScopes, cb));
}
} else {
if (grammarScopes === 'all') {
return (0, _event().observableFromSubscribeFunction)(cb => dispatcher.onAnyFileSave(cb));
} else {
return (0, _event().observableFromSubscribeFunction)(cb => dispatcher.onFileSave(grammarScopes, cb));
}
}
});
}
observeTextEditorEvents = observeTextEditorEvents;var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _debounce;function _load_debounce() {return _debounce = _interopRequireDefault(require('nuclide-commons/debounce'));}var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _textEditor;function _load_textEditor() {return _textEditor = require('./text-editor');}var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} // A reload changes the text in the buffer, so it should trigger a refresh.
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/const FILE_CHANGE_EVENTS = ['did-change', 'did-reload', 'did-open']; // A reload basically indicates that an external program saved the file, so
// it should trigger a refresh.
const FILE_SAVE_EVENTS = ['did-save', 'did-reload', 'did-open']; /**
* Stores callbacks keyed on grammar and event, to allow for easy retrieval when
* we need to dispatch to all callbacks registered for a given (grammar, event)
* pair.
*/class TextCallbackContainer {// grammar -> event -> callback
// invariant: no empty maps or sets (they should be removed instead)
constructor() {this._callbacks = new Map();this._allGrammarCallbacks = new Map();} // event -> callback
// invariant: no keys mapping to empty sets (they should be removed instead)
getCallbacks(grammar, event) {const eventMap = this._callbacks.get(grammar);const callbacksForGrammar = this._getCallbacksFromEventMap(eventMap, event);const callbacksForAll = this._getCallbacksFromEventMap(this._allGrammarCallbacks, event);const resultSet = new Set();const add = callback => {resultSet.add(callback);};callbacksForGrammar.forEach(add);callbacksForAll.forEach(add);return resultSet;}isEmpty() {return this._callbacks.size === 0 && this._allGrammarCallbacks.size === 0;}_getCallbacksFromEventMap(eventMap, event) {if (!eventMap) {return new Set();}const callbackSet = eventMap.get(event);if (!callbackSet) {return new Set();}return callbackSet;}addCallback(grammarScopes, events, callback) {if (grammarScopes === 'all') {this._addToEventMap(this._allGrammarCallbacks, events, callback);} else {for (const grammarScope of grammarScopes) {let eventMap = this._callbacks.get(grammarScope);if (!eventMap) {eventMap = new Map();this._callbacks.set(grammarScope, eventMap);}this._addToEventMap(eventMap, events, callback);}}} // remove the callbacks, maintaining the invariant that there should be no
// empty maps or sets in this._callbacks
removeCallback(grammarScopes, events, callback) {if (grammarScopes === 'all') {this._removeFromEventMap(this._allGrammarCallbacks, events, callback);} else {for (const grammarScope of grammarScopes) {const eventMap = this._callbacks.get(grammarScope);if (!eventMap) {throw new Error('Invariant violation: "eventMap"');}this._removeFromEventMap(eventMap, events, callback);if (eventMap.size === 0) {this._callbacks.delete(grammarScope);}}}}_addToEventMap(eventMap, events, callback) {for (const event of events) {let callbackSet = eventMap.get(event);if (!callbackSet) {callbackSet = new Set();eventMap.set(event, callbackSet);}callbackSet.add(callback);}}_removeFromEventMap(eventMap, events, callback) {for (const event of events) {const callbackSet = eventMap.get(event);if (!callbackSet) {throw new Error('Invariant violation: "callbackSet"');}callbackSet.delete(callback);if (callbackSet.size === 0) {eventMap.delete(event);}}}} /**
* Meant to make it simple and easy for a DiagnosticProvider to subscribe to
* relevant events. Currently provides two methods, onFileChange and onFileSave.
* A DiagnosticProvider will typically subscribe to only one, depending on
* whether it wants to be notified whenever a file changes or only when it is
* saved.
*
* Both methods take two arguments:
* - An Iterable of grammars for which the DiagnosticProvider can provide
* diagnostics.
* - The callback to be called on a text event.
*
* A TextEventDispatcher will be subscribed to text events if and only if it has
* subscribers of its own. If all subscribers unsubscribe, it will unsubscribe
* from Atom's text events.
*
*/class TextEventDispatcher {constructor() {this._callbackContainer = new TextCallbackContainer();this._editorListenerDisposable = null;this._pendingEvents = new WeakMap();}_onEvents(grammarScopes, events, callback) {if (this._callbackContainer.isEmpty()) {this._registerEditorListeners();} // Sometimes these events get triggered several times in succession
// (particularly on startup).
const debouncedCallback = (0, (_debounce || _load_debounce()).default)(callback, 50, true);this._callbackContainer.addCallback(grammarScopes, events, debouncedCallback);const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {this._callbackContainer.removeCallback(grammarScopes, events, debouncedCallback);if (this._callbackContainer.isEmpty()) {this._deregisterEditorListeners();}});return disposables;}onFileChange(grammarScopes, callback) {return this._onEvents(grammarScopes, FILE_CHANGE_EVENTS, callback);}onAnyFileChange(callback) {return this._onEvents('all', FILE_CHANGE_EVENTS, callback);}onFileSave(grammarScopes, callback) {return this._onEvents(grammarScopes, FILE_SAVE_EVENTS, callback);}onAnyFileSave(callback) {return this._onEvents('all', FILE_SAVE_EVENTS, callback);}_registerEditorListeners() {if (!this._editorListenerDisposable) {this._editorListenerDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default();} // Whenever the active pane item changes, we check to see if there are any
// pending events for the newly-focused TextEditor.
this._getEditorListenerDisposable().add(atom.workspace.onDidChangeActivePaneItem(() => {const currentEditor = atom.workspace.getActiveTextEditor();if (currentEditor) {const pendingEvents = this._pendingEvents.get(currentEditor.getBuffer());if (pendingEvents) {for (const event of pendingEvents) {this._dispatchEvents(currentEditor, event);}this._pendingEvents.delete(currentEditor.getBuffer());}}}));this._getEditorListenerDisposable().add((0, (_textEditor || _load_textEditor()).observeTextEditors)(editor => {const buffer = editor.getBuffer();const makeDispatch = event => {return () => {this._dispatchEvents(editor, event);};};this._getEditorListenerDisposable().add(buffer.onDidStopChanging(makeDispatch('did-change')));this._getEditorListenerDisposable().add(buffer.onDidSave(makeDispatch('did-save')));this._getEditorListenerDisposable().add(buffer.onDidReload(makeDispatch('did-reload'))); // During reload, many text editors are opened simultaneously.
// Due to the debounce on the event callback, this means that many editors never receive
// a 'did-open' event. To work around this, defer editor open events so that simultaneous
// open events are properly registered as pending.
setImmediate(() => this._dispatchEvents(editor, 'did-open'));}));}_deregisterEditorListeners() {if (this._editorListenerDisposable) {this._getEditorListenerDisposable().dispose();this._editorListenerDisposable = null;}}_dispatchEvents(editor, event) {const currentEditor = atom.workspace.getActiveTextEditor();if (currentEditor && editor === currentEditor) {const callbacks = this._callbackContainer.getCallbacks(editor.getGrammar().scopeName, event);for (const callback of callbacks) {callback(editor);} // We want to avoid storing pending events if this event was generated by
// the same buffer as the current editor, to avoid duplicating events when
// multiple panes have the same file open.
} else if (!currentEditor || editor.getBuffer() !== currentEditor.getBuffer()) {// Trigger this event next time we switch to an editor with this buffer.
const buffer = editor.getBuffer();let events = this._pendingEvents.get(buffer);if (!events) {events = new Set();this._pendingEvents.set(buffer, events);}events.add(event);}}_getEditorListenerDisposable() {const disposable = this._editorListenerDisposable;if (!disposable) {throw new Error('TextEventDispatcher disposable is not initialized');}return disposable;}}exports.TextEventDispatcher = TextEventDispatcher;function observeTextEditorEvents(grammarScopes, events) {return _rxjsBundlesRxMinJs.Observable.defer(() => {const dispatcher = new TextEventDispatcher();if (events === 'changes') {if (grammarScopes === 'all') {return (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => dispatcher.onAnyFileChange(cb));} else {return (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => dispatcher.onFileChange(grammarScopes, cb));}} else {if (grammarScopes === 'all') {return (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => dispatcher.onAnyFileSave(cb));} else {return (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => dispatcher.onFileSave(grammarScopes, cb));}}});}const __TEST__ = exports.__TEST__ = { TextCallbackContainer };
const __TEST__ = {
TextCallbackContainer
};
exports.__TEST__ = __TEST__;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc