@difizen/libro-lsp 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/es/adapters/adapter.d.ts +255 -0
- package/es/adapters/adapter.d.ts.map +1 -0
- package/es/adapters/adapter.js +647 -0
- package/es/adapters/notebook-adapter.d.ts +150 -0
- package/es/adapters/notebook-adapter.d.ts.map +1 -0
- package/es/adapters/notebook-adapter.js +588 -0
- package/es/adapters/status-message.d.ts +48 -0
- package/es/adapters/status-message.d.ts.map +1 -0
- package/es/adapters/status-message.js +110 -0
- package/es/connection-manager.d.ts +199 -0
- package/es/connection-manager.d.ts.map +1 -0
- package/es/connection-manager.js +685 -0
- package/es/connection.d.ts +149 -0
- package/es/connection.d.ts.map +1 -0
- package/es/connection.js +591 -0
- package/es/extractors/index.d.ts +4 -0
- package/es/extractors/index.d.ts.map +1 -0
- package/es/extractors/index.js +6 -0
- package/es/extractors/manager.d.ts +31 -0
- package/es/extractors/manager.d.ts.map +1 -0
- package/es/extractors/manager.js +90 -0
- package/es/extractors/text-extractor.d.ts +56 -0
- package/es/extractors/text-extractor.d.ts.map +1 -0
- package/es/extractors/text-extractor.js +72 -0
- package/es/extractors/types.d.ts +68 -0
- package/es/extractors/types.d.ts.map +1 -0
- package/es/extractors/types.js +1 -0
- package/es/feature.d.ts +29 -0
- package/es/feature.d.ts.map +1 -0
- package/es/feature.js +85 -0
- package/es/index.d.ts +19 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +21 -0
- package/es/lsp-app-contribution.d.ts +19 -0
- package/es/lsp-app-contribution.d.ts.map +1 -0
- package/es/lsp-app-contribution.js +155 -0
- package/es/lsp-protocol.d.ts +10 -0
- package/es/lsp-protocol.d.ts.map +1 -0
- package/es/lsp-protocol.js +1 -0
- package/es/lsp.d.ts +136 -0
- package/es/lsp.d.ts.map +1 -0
- package/es/lsp.js +141 -0
- package/es/manager.d.ts +142 -0
- package/es/manager.d.ts.map +1 -0
- package/es/manager.js +423 -0
- package/es/module.d.ts +3 -0
- package/es/module.d.ts.map +1 -0
- package/es/module.js +21 -0
- package/es/plugin.d.ts +56 -0
- package/es/plugin.d.ts.map +1 -0
- package/es/plugin.js +0 -0
- package/es/positioning.d.ts +66 -0
- package/es/positioning.d.ts.map +1 -0
- package/es/positioning.js +96 -0
- package/es/schema.d.ts +240 -0
- package/es/schema.d.ts.map +1 -0
- package/es/schema.js +0 -0
- package/es/tokens.d.ts +677 -0
- package/es/tokens.d.ts.map +1 -0
- package/es/tokens.js +183 -0
- package/es/utils.d.ts +33 -0
- package/es/utils.d.ts.map +1 -0
- package/es/utils.js +168 -0
- package/es/virtual/document.d.ts +546 -0
- package/es/virtual/document.d.ts.map +1 -0
- package/es/virtual/document.js +1263 -0
- package/es/ws-connection/server-capability-registration.d.ts +19 -0
- package/es/ws-connection/server-capability-registration.d.ts.map +1 -0
- package/es/ws-connection/server-capability-registration.js +51 -0
- package/es/ws-connection/types.d.ts +76 -0
- package/es/ws-connection/types.d.ts.map +1 -0
- package/es/ws-connection/types.js +1 -0
- package/es/ws-connection/ws-connection.d.ts +105 -0
- package/es/ws-connection/ws-connection.d.ts.map +1 -0
- package/es/ws-connection/ws-connection.js +301 -0
- package/package.json +67 -0
- package/src/adapters/adapter.ts +611 -0
- package/src/adapters/notebook-adapter.ts +463 -0
- package/src/adapters/status-message.ts +93 -0
- package/src/connection-manager.ts +626 -0
- package/src/connection.ts +570 -0
- package/src/extractors/index.ts +6 -0
- package/src/extractors/manager.ts +82 -0
- package/src/extractors/text-extractor.ts +94 -0
- package/src/extractors/types.ts +78 -0
- package/src/feature.ts +60 -0
- package/src/index.spec.ts +10 -0
- package/src/index.ts +21 -0
- package/src/lsp-app-contribution.ts +83 -0
- package/src/lsp-protocol.ts +10 -0
- package/src/lsp.ts +160 -0
- package/src/manager.ts +358 -0
- package/src/module.ts +32 -0
- package/src/plugin.ts +62 -0
- package/src/positioning.ts +121 -0
- package/src/schema.ts +249 -0
- package/src/tokens.ts +843 -0
- package/src/utils.ts +109 -0
- package/src/virtual/document.ts +1250 -0
- package/src/ws-connection/server-capability-registration.ts +77 -0
- package/src/ws-connection/types.ts +102 -0
- package/src/ws-connection/ws-connection.ts +320 -0
|
@@ -0,0 +1,1263 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
3
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
4
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
5
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
6
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
7
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
8
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
9
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
10
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
11
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
12
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
13
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
14
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
15
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
16
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
17
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
18
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
19
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
20
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
21
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
22
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
23
|
+
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
24
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
25
|
+
// Copyright (c) Jupyter Development Team.
|
|
26
|
+
// Distributed under the terms of the Modified BSD License.
|
|
27
|
+
|
|
28
|
+
import { Emitter } from '@difizen/mana-app';
|
|
29
|
+
import { DocumentConnectionManager } from "../connection-manager.js";
|
|
30
|
+
import { DefaultMap, untilReady } from "../utils.js";
|
|
31
|
+
/**
|
|
32
|
+
* Check if given position is within range.
|
|
33
|
+
* Both start and end are inclusive.
|
|
34
|
+
* @param position
|
|
35
|
+
* @param range
|
|
36
|
+
*/
|
|
37
|
+
export function isWithinRange(position, range) {
|
|
38
|
+
if (range.start.line === range.end.line) {
|
|
39
|
+
return position.line === range.start.line && position.column >= range.start.column && position.column <= range.end.column;
|
|
40
|
+
}
|
|
41
|
+
return position.line === range.start.line && position.column >= range.start.column && position.line < range.end.line || position.line > range.start.line && position.column <= range.end.column && position.line === range.end.line || position.line > range.start.line && position.line < range.end.line;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A virtual implementation of IDocumentInfo
|
|
46
|
+
*/
|
|
47
|
+
export var VirtualDocumentInfo = /*#__PURE__*/function () {
|
|
48
|
+
/**
|
|
49
|
+
* Creates an instance of VirtualDocumentInfo.
|
|
50
|
+
* @param document - the virtual document need to
|
|
51
|
+
* be wrapped.
|
|
52
|
+
*/
|
|
53
|
+
function VirtualDocumentInfo(document) {
|
|
54
|
+
_classCallCheck(this, VirtualDocumentInfo);
|
|
55
|
+
/**
|
|
56
|
+
* Current version of the virtual document.
|
|
57
|
+
*/
|
|
58
|
+
this.version = 0;
|
|
59
|
+
this._document = document;
|
|
60
|
+
}
|
|
61
|
+
_createClass(VirtualDocumentInfo, [{
|
|
62
|
+
key: "text",
|
|
63
|
+
get:
|
|
64
|
+
/**
|
|
65
|
+
* Get the text content of the virtual document.
|
|
66
|
+
*/
|
|
67
|
+
function get() {
|
|
68
|
+
return this._document.value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get the uri of the virtual document, if the document is not available,
|
|
73
|
+
* it returns an empty string, users need to check for the length of returned
|
|
74
|
+
* value before using it.
|
|
75
|
+
*/
|
|
76
|
+
}, {
|
|
77
|
+
key: "uri",
|
|
78
|
+
get: function get() {
|
|
79
|
+
var uris = DocumentConnectionManager.solveUris(this._document, this.languageId);
|
|
80
|
+
if (!uris) {
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
83
|
+
return uris.document;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get the language identifier of the document.
|
|
88
|
+
*/
|
|
89
|
+
}, {
|
|
90
|
+
key: "languageId",
|
|
91
|
+
get: function get() {
|
|
92
|
+
return this._document.language;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The wrapped virtual document.
|
|
97
|
+
*/
|
|
98
|
+
}]);
|
|
99
|
+
return VirtualDocumentInfo;
|
|
100
|
+
}();
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* A notebook can hold one or more virtual documents; there is always one,
|
|
104
|
+
* "root" document, corresponding to the language of the kernel. All other
|
|
105
|
+
* virtual documents are extracted out of the notebook, based on magics,
|
|
106
|
+
* or other syntax constructs, depending on the kernel language.
|
|
107
|
+
*
|
|
108
|
+
* Virtual documents represent the underlying code in a single language,
|
|
109
|
+
* which has been parsed excluding interactive kernel commands (magics)
|
|
110
|
+
* which could be misunderstood by the specific LSP server.
|
|
111
|
+
*
|
|
112
|
+
* VirtualDocument has no awareness of the notebook or editor it lives in,
|
|
113
|
+
* however it is able to transform its content back to the notebook space,
|
|
114
|
+
* as it keeps editor coordinates for each virtual line.
|
|
115
|
+
*
|
|
116
|
+
* The notebook/editor aware transformations are preferred to be placed in
|
|
117
|
+
* VirtualEditor descendants rather than here.
|
|
118
|
+
*
|
|
119
|
+
* No dependency on editor implementation (such as CodeMirrorEditor)
|
|
120
|
+
* is allowed for VirtualEditor.
|
|
121
|
+
*/
|
|
122
|
+
export var VirtualDocument = /*#__PURE__*/function () {
|
|
123
|
+
function VirtualDocument(options) {
|
|
124
|
+
_classCallCheck(this, VirtualDocument);
|
|
125
|
+
/**
|
|
126
|
+
* Number of blank lines appended to the virtual document between
|
|
127
|
+
* each cell.
|
|
128
|
+
*/
|
|
129
|
+
this.blankLinesBetweenCells = 2;
|
|
130
|
+
this._isDisposed = false;
|
|
131
|
+
this._foreignDocumentClosed = new Emitter();
|
|
132
|
+
this._foreignDocumentOpened = new Emitter();
|
|
133
|
+
this._changed = new Emitter();
|
|
134
|
+
this.options = options;
|
|
135
|
+
this.path = this.options.path;
|
|
136
|
+
this.fileExtension = options.fileExtension;
|
|
137
|
+
this.hasLspSupportedFile = options.hasLspSupportedFile;
|
|
138
|
+
this.parent = options.parent;
|
|
139
|
+
this.language = options.language;
|
|
140
|
+
this.virtualLines = new Map();
|
|
141
|
+
this.sourceLines = new Map();
|
|
142
|
+
this.foreignDocuments = new Map();
|
|
143
|
+
this._editorToSourceLine = new Map();
|
|
144
|
+
this._foreignCodeExtractors = options.foreignCodeExtractors;
|
|
145
|
+
this.standalone = options.standalone || false;
|
|
146
|
+
this.instanceId = VirtualDocument.instancesCount;
|
|
147
|
+
VirtualDocument.instancesCount += 1;
|
|
148
|
+
this.unusedStandaloneDocuments = new DefaultMap(function () {
|
|
149
|
+
return new Array();
|
|
150
|
+
});
|
|
151
|
+
this._remainingLifetime = 6;
|
|
152
|
+
this.unusedDocuments = new Set();
|
|
153
|
+
this.documentInfo = new VirtualDocumentInfo(this);
|
|
154
|
+
this.updateManager = new UpdateManager(this);
|
|
155
|
+
this.updateManager.updateBegan(this._updateBeganSlot, this);
|
|
156
|
+
this.updateManager.blockAdded(this._blockAddedSlot, this);
|
|
157
|
+
this.updateManager.updateFinished(this._updateFinishedSlot, this);
|
|
158
|
+
this.clear();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Convert from code editor position into code mirror position.
|
|
163
|
+
*/
|
|
164
|
+
_createClass(VirtualDocument, [{
|
|
165
|
+
key: "isDisposed",
|
|
166
|
+
get:
|
|
167
|
+
/**
|
|
168
|
+
* Line number of the last line in the real document.
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Line number of the last line in the virtual document.
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* the remote document uri, version and other server-related info
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Parent of the current virtual document.
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The language identifier of the document.
|
|
185
|
+
*/
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Being standalone is relevant to foreign documents
|
|
189
|
+
* and defines whether following chunks of code in the same
|
|
190
|
+
* language should be appended to this document (false, not standalone)
|
|
191
|
+
* or should be considered separate documents (true, standalone)
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Path to the document.
|
|
196
|
+
*/
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* File extension of the document.
|
|
200
|
+
*/
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Notebooks or any other aggregates of documents are not supported
|
|
204
|
+
* by the LSP specification, and we need to make appropriate
|
|
205
|
+
* adjustments for them, pretending they are simple files
|
|
206
|
+
* so that the LSP servers do not refuse to cooperate.
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Map holding the children `VirtualDocument` .
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* The update manager object.
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Unique id of the virtual document.
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Test whether the document is disposed.
|
|
223
|
+
*/
|
|
224
|
+
function get() {
|
|
225
|
+
return this._isDisposed;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Signal emitted when the foreign document is closed
|
|
230
|
+
*/
|
|
231
|
+
}, {
|
|
232
|
+
key: "foreignDocumentClosed",
|
|
233
|
+
get: function get() {
|
|
234
|
+
return this._foreignDocumentClosed.event;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Signal emitted when the foreign document is opened
|
|
239
|
+
*/
|
|
240
|
+
}, {
|
|
241
|
+
key: "foreignDocumentOpened",
|
|
242
|
+
get: function get() {
|
|
243
|
+
return this._foreignDocumentOpened.event;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Signal emitted when the foreign document is changed
|
|
248
|
+
*/
|
|
249
|
+
}, {
|
|
250
|
+
key: "changed",
|
|
251
|
+
get: function get() {
|
|
252
|
+
return this._changed.event;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Id of the virtual document.
|
|
257
|
+
*/
|
|
258
|
+
}, {
|
|
259
|
+
key: "virtualId",
|
|
260
|
+
get: function get() {
|
|
261
|
+
// for easier debugging, the language information is included in the ID:
|
|
262
|
+
return this.standalone ? this.instanceId + '(' + this.language + ')' : this.language;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Return the ancestry to this document.
|
|
267
|
+
*/
|
|
268
|
+
}, {
|
|
269
|
+
key: "ancestry",
|
|
270
|
+
get: function get() {
|
|
271
|
+
if (!this.parent) {
|
|
272
|
+
return [this];
|
|
273
|
+
}
|
|
274
|
+
return this.parent.ancestry.concat([this]);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Return the id path to the virtual document.
|
|
279
|
+
*/
|
|
280
|
+
}, {
|
|
281
|
+
key: "idPath",
|
|
282
|
+
get: function get() {
|
|
283
|
+
if (!this.parent) {
|
|
284
|
+
return this.virtualId;
|
|
285
|
+
}
|
|
286
|
+
return this.parent.idPath + '-' + this.virtualId;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Get the uri of the virtual document.
|
|
291
|
+
*/
|
|
292
|
+
}, {
|
|
293
|
+
key: "uri",
|
|
294
|
+
get: function get() {
|
|
295
|
+
var encodedPath = encodeURI(this.path);
|
|
296
|
+
if (!this.parent) {
|
|
297
|
+
return encodedPath;
|
|
298
|
+
}
|
|
299
|
+
return encodedPath + '.' + this.idPath + '.' + this.fileExtension;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Get the text value of the document
|
|
304
|
+
*/
|
|
305
|
+
}, {
|
|
306
|
+
key: "value",
|
|
307
|
+
get: function get() {
|
|
308
|
+
var linesPadding = '\n'.repeat(this.blankLinesBetweenCells);
|
|
309
|
+
return this.lineBlocks.join(linesPadding);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Get the last line in the virtual document
|
|
314
|
+
*/
|
|
315
|
+
}, {
|
|
316
|
+
key: "lastLine",
|
|
317
|
+
get: function get() {
|
|
318
|
+
var linesInLastBlock = this.lineBlocks[this.lineBlocks.length - 1].split('\n');
|
|
319
|
+
return linesInLastBlock[linesInLastBlock.length - 1];
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get the root document of current virtual document.
|
|
324
|
+
*/
|
|
325
|
+
}, {
|
|
326
|
+
key: "root",
|
|
327
|
+
get: function get() {
|
|
328
|
+
return this.parent ? this.parent.root : this;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Dispose the virtual document.
|
|
333
|
+
*/
|
|
334
|
+
}, {
|
|
335
|
+
key: "dispose",
|
|
336
|
+
value: function dispose() {
|
|
337
|
+
if (this._isDisposed) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
this._isDisposed = true;
|
|
341
|
+
this.parent = null;
|
|
342
|
+
this.closeAllForeignDocuments();
|
|
343
|
+
this.updateManager.dispose();
|
|
344
|
+
// clear all the maps
|
|
345
|
+
|
|
346
|
+
this.foreignDocuments.clear();
|
|
347
|
+
this.sourceLines.clear();
|
|
348
|
+
this.unusedDocuments.clear();
|
|
349
|
+
this.unusedStandaloneDocuments.clear();
|
|
350
|
+
this.virtualLines.clear();
|
|
351
|
+
|
|
352
|
+
// just to be sure - if anything is accessed after disposal (it should not) we
|
|
353
|
+
// will get altered by errors in the console AND this will limit memory leaks
|
|
354
|
+
|
|
355
|
+
this.documentInfo = null;
|
|
356
|
+
this.lineBlocks = null;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Clear the virtual document and all related stuffs
|
|
361
|
+
*/
|
|
362
|
+
}, {
|
|
363
|
+
key: "clear",
|
|
364
|
+
value: function clear() {
|
|
365
|
+
var _iterator = _createForOfIteratorHelper(this.foreignDocuments.values()),
|
|
366
|
+
_step;
|
|
367
|
+
try {
|
|
368
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
369
|
+
var document = _step.value;
|
|
370
|
+
document.clear();
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// TODO - deep clear (assure that there is no memory leak)
|
|
374
|
+
} catch (err) {
|
|
375
|
+
_iterator.e(err);
|
|
376
|
+
} finally {
|
|
377
|
+
_iterator.f();
|
|
378
|
+
}
|
|
379
|
+
this.unusedStandaloneDocuments.clear();
|
|
380
|
+
this.unusedDocuments = new Set();
|
|
381
|
+
this.virtualLines.clear();
|
|
382
|
+
this.sourceLines.clear();
|
|
383
|
+
this.lastVirtualLine = 0;
|
|
384
|
+
this.lastSourceLine = 0;
|
|
385
|
+
this.lineBlocks = [];
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Get the virtual document from the cursor position of the source
|
|
390
|
+
* document
|
|
391
|
+
* @param position - position in source document
|
|
392
|
+
*/
|
|
393
|
+
}, {
|
|
394
|
+
key: "documentAtSourcePosition",
|
|
395
|
+
value: function documentAtSourcePosition(position) {
|
|
396
|
+
var sourceLine = this.sourceLines.get(position.line);
|
|
397
|
+
if (!sourceLine) {
|
|
398
|
+
return this;
|
|
399
|
+
}
|
|
400
|
+
var sourcePositionCe = {
|
|
401
|
+
line: sourceLine.editorLine,
|
|
402
|
+
column: position.ch
|
|
403
|
+
};
|
|
404
|
+
var _iterator2 = _createForOfIteratorHelper(sourceLine.foreignDocumentsMap),
|
|
405
|
+
_step2;
|
|
406
|
+
try {
|
|
407
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
408
|
+
var _step2$value = _slicedToArray(_step2.value, 2),
|
|
409
|
+
range = _step2$value[0],
|
|
410
|
+
document = _step2$value[1].virtualDocument;
|
|
411
|
+
if (isWithinRange(sourcePositionCe, range)) {
|
|
412
|
+
var sourcePositionCm = {
|
|
413
|
+
line: sourcePositionCe.line - range.start.line,
|
|
414
|
+
ch: sourcePositionCe.column - range.start.column
|
|
415
|
+
};
|
|
416
|
+
return document.documentAtSourcePosition(sourcePositionCm);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
} catch (err) {
|
|
420
|
+
_iterator2.e(err);
|
|
421
|
+
} finally {
|
|
422
|
+
_iterator2.f();
|
|
423
|
+
}
|
|
424
|
+
return this;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Detect if the input source position is belong to the current
|
|
429
|
+
* virtual document.
|
|
430
|
+
*
|
|
431
|
+
* @param sourcePosition - position in the source document
|
|
432
|
+
*/
|
|
433
|
+
}, {
|
|
434
|
+
key: "isWithinForeign",
|
|
435
|
+
value: function isWithinForeign(sourcePosition) {
|
|
436
|
+
var sourceLine = this.sourceLines.get(sourcePosition.line);
|
|
437
|
+
var sourcePositionCe = {
|
|
438
|
+
line: sourceLine.editorLine,
|
|
439
|
+
column: sourcePosition.ch
|
|
440
|
+
};
|
|
441
|
+
var _iterator3 = _createForOfIteratorHelper(sourceLine.foreignDocumentsMap),
|
|
442
|
+
_step3;
|
|
443
|
+
try {
|
|
444
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
445
|
+
var _step3$value = _slicedToArray(_step3.value, 1),
|
|
446
|
+
range = _step3$value[0];
|
|
447
|
+
if (isWithinRange(sourcePositionCe, range)) {
|
|
448
|
+
return true;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
} catch (err) {
|
|
452
|
+
_iterator3.e(err);
|
|
453
|
+
} finally {
|
|
454
|
+
_iterator3.f();
|
|
455
|
+
}
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Compute the position in root document from the position of
|
|
461
|
+
* a child editor.
|
|
462
|
+
*
|
|
463
|
+
* @param editor - the active editor.
|
|
464
|
+
* @param position - position in the active editor.
|
|
465
|
+
*/
|
|
466
|
+
}, {
|
|
467
|
+
key: "transformFromEditorToRoot",
|
|
468
|
+
value: function transformFromEditorToRoot(editor, position) {
|
|
469
|
+
if (!this._editorToSourceLine.has(editor)) {
|
|
470
|
+
console.warn('Editor not found in _editorToSourceLine map');
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
var shift = this._editorToSourceLine.get(editor);
|
|
474
|
+
return _objectSpread(_objectSpread({}, position), {}, {
|
|
475
|
+
line: position.line + shift
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Compute the position in virtual document from the position of
|
|
481
|
+
* a child editor.
|
|
482
|
+
*
|
|
483
|
+
* @param editor - the active editor.
|
|
484
|
+
* @param position - position in the active editor.
|
|
485
|
+
*/
|
|
486
|
+
}, {
|
|
487
|
+
key: "transformEditorToVirtual",
|
|
488
|
+
value: function transformEditorToVirtual(editor, position) {
|
|
489
|
+
var rootPosition = this.transformFromEditorToRoot(editor, position);
|
|
490
|
+
if (!rootPosition) {
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
return this.virtualPositionAtDocument(rootPosition);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Compute the position in the virtual document from the position
|
|
498
|
+
* in the source document.
|
|
499
|
+
*
|
|
500
|
+
* @param sourcePosition - position in source document
|
|
501
|
+
*/
|
|
502
|
+
}, {
|
|
503
|
+
key: "virtualPositionAtDocument",
|
|
504
|
+
value: function virtualPositionAtDocument(sourcePosition) {
|
|
505
|
+
var sourceLine = this.sourceLines.get(sourcePosition.line);
|
|
506
|
+
if (!sourceLine) {
|
|
507
|
+
throw new Error('Source line not mapped to virtual position');
|
|
508
|
+
}
|
|
509
|
+
var virtualLine = sourceLine.virtualLine;
|
|
510
|
+
|
|
511
|
+
// position inside the cell (block)
|
|
512
|
+
var sourcePositionCe = {
|
|
513
|
+
line: sourceLine.editorLine,
|
|
514
|
+
column: sourcePosition.ch
|
|
515
|
+
};
|
|
516
|
+
var _iterator4 = _createForOfIteratorHelper(sourceLine.foreignDocumentsMap),
|
|
517
|
+
_step4;
|
|
518
|
+
try {
|
|
519
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
520
|
+
var _step4$value = _slicedToArray(_step4.value, 2),
|
|
521
|
+
range = _step4$value[0],
|
|
522
|
+
content = _step4$value[1];
|
|
523
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
524
|
+
var _virtualLine = content.virtualLine,
|
|
525
|
+
document = content.virtualDocument;
|
|
526
|
+
if (isWithinRange(sourcePositionCe, range)) {
|
|
527
|
+
// position inside the foreign document block
|
|
528
|
+
var sourcePositionCm = {
|
|
529
|
+
line: sourcePositionCe.line - range.start.line,
|
|
530
|
+
ch: sourcePositionCe.column - range.start.column
|
|
531
|
+
};
|
|
532
|
+
if (document.isWithinForeign(sourcePositionCm)) {
|
|
533
|
+
return this.virtualPositionAtDocument(sourcePositionCm);
|
|
534
|
+
} else {
|
|
535
|
+
// where in this block in the entire foreign document?
|
|
536
|
+
sourcePositionCm.line += _virtualLine;
|
|
537
|
+
return sourcePositionCm;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} catch (err) {
|
|
542
|
+
_iterator4.e(err);
|
|
543
|
+
} finally {
|
|
544
|
+
_iterator4.f();
|
|
545
|
+
}
|
|
546
|
+
return {
|
|
547
|
+
ch: sourcePosition.ch,
|
|
548
|
+
line: virtualLine
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Append a code block to the end of the virtual document.
|
|
554
|
+
*
|
|
555
|
+
* @param block - block to be appended
|
|
556
|
+
* @param editorShift - position shift in source
|
|
557
|
+
* document
|
|
558
|
+
* @param [virtualShift] - position shift in
|
|
559
|
+
* virtual document.
|
|
560
|
+
*/
|
|
561
|
+
}, {
|
|
562
|
+
key: "appendCodeBlock",
|
|
563
|
+
value: function appendCodeBlock(block) {
|
|
564
|
+
var editorShift = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
565
|
+
line: 0,
|
|
566
|
+
column: 0
|
|
567
|
+
};
|
|
568
|
+
var virtualShift = arguments.length > 2 ? arguments[2] : undefined;
|
|
569
|
+
var cellCode = block.value;
|
|
570
|
+
var ceEditor = block.ceEditor;
|
|
571
|
+
if (this.isDisposed) {
|
|
572
|
+
console.warn('Cannot append code block: document disposed');
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
var sourceCellLines = cellCode.split('\n');
|
|
576
|
+
var _this$prepareCodeBloc = this.prepareCodeBlock(block, editorShift),
|
|
577
|
+
lines = _this$prepareCodeBloc.lines,
|
|
578
|
+
foreignDocumentsMap = _this$prepareCodeBloc.foreignDocumentsMap;
|
|
579
|
+
for (var i = 0; i < lines.length; i++) {
|
|
580
|
+
this.virtualLines.set(this.lastVirtualLine + i, {
|
|
581
|
+
skipInspect: [],
|
|
582
|
+
editor: ceEditor,
|
|
583
|
+
// TODO this is incorrect, wont work if something was extracted
|
|
584
|
+
sourceLine: this.lastSourceLine + i
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
for (var _i = 0; _i < sourceCellLines.length; _i++) {
|
|
588
|
+
this.sourceLines.set(this.lastSourceLine + _i, {
|
|
589
|
+
editorLine: _i,
|
|
590
|
+
editorShift: {
|
|
591
|
+
line: editorShift.line - ((virtualShift === null || virtualShift === void 0 ? void 0 : virtualShift.line) || 0),
|
|
592
|
+
column: _i === 0 ? editorShift.column - ((virtualShift === null || virtualShift === void 0 ? void 0 : virtualShift.column) || 0) : 0
|
|
593
|
+
},
|
|
594
|
+
// TODO: move those to a new abstraction layer (DocumentBlock class)
|
|
595
|
+
editor: ceEditor,
|
|
596
|
+
foreignDocumentsMap: foreignDocumentsMap,
|
|
597
|
+
// TODO this is incorrect, wont work if something was extracted
|
|
598
|
+
virtualLine: this.lastVirtualLine + _i
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
this.lastVirtualLine += lines.length;
|
|
602
|
+
|
|
603
|
+
// one empty line is necessary to separate code blocks, next 'n' lines are to silence linters;
|
|
604
|
+
// the final cell does not get the additional lines (thanks to the use of join, see below)
|
|
605
|
+
|
|
606
|
+
this.lineBlocks.push(lines.join('\n') + '\n');
|
|
607
|
+
|
|
608
|
+
// adding the virtual lines for the blank lines
|
|
609
|
+
for (var _i2 = 0; _i2 < this.blankLinesBetweenCells; _i2++) {
|
|
610
|
+
this.virtualLines.set(this.lastVirtualLine + _i2, {
|
|
611
|
+
skipInspect: [this.idPath],
|
|
612
|
+
editor: ceEditor,
|
|
613
|
+
sourceLine: null
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
this.lastVirtualLine += this.blankLinesBetweenCells;
|
|
617
|
+
this.lastSourceLine += sourceCellLines.length;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Extract a code block into list of string in supported language and
|
|
622
|
+
* a map of foreign document if any.
|
|
623
|
+
* @param block - block to be appended
|
|
624
|
+
* @param editorShift - position shift in source document
|
|
625
|
+
*/
|
|
626
|
+
}, {
|
|
627
|
+
key: "prepareCodeBlock",
|
|
628
|
+
value: function prepareCodeBlock(block) {
|
|
629
|
+
var editorShift = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
630
|
+
line: 0,
|
|
631
|
+
column: 0
|
|
632
|
+
};
|
|
633
|
+
var _this$extractForeignC = this.extractForeignCode(block, editorShift),
|
|
634
|
+
cellCodeKept = _this$extractForeignC.cellCodeKept,
|
|
635
|
+
foreignDocumentsMap = _this$extractForeignC.foreignDocumentsMap;
|
|
636
|
+
var lines = cellCodeKept.split('\n');
|
|
637
|
+
return {
|
|
638
|
+
lines: lines,
|
|
639
|
+
foreignDocumentsMap: foreignDocumentsMap
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Extract the foreign code from input block by using the registered
|
|
645
|
+
* extractors.
|
|
646
|
+
* @param block - block to be appended
|
|
647
|
+
* @param editorShift - position shift in source document
|
|
648
|
+
*/
|
|
649
|
+
}, {
|
|
650
|
+
key: "extractForeignCode",
|
|
651
|
+
value: function extractForeignCode(block, editorShift) {
|
|
652
|
+
var foreignDocumentsMap = new Map();
|
|
653
|
+
var cellCode = block.value;
|
|
654
|
+
var extractorsForAnyLang = this._foreignCodeExtractors.getExtractors(block.type, null);
|
|
655
|
+
var extractorsForCurrentLang = this._foreignCodeExtractors.getExtractors(block.type, this.language);
|
|
656
|
+
for (var _i3 = 0, _arr = [].concat(_toConsumableArray(extractorsForAnyLang), _toConsumableArray(extractorsForCurrentLang)); _i3 < _arr.length; _i3++) {
|
|
657
|
+
var extractor = _arr[_i3];
|
|
658
|
+
if (!extractor.hasForeignCode(cellCode, block.type)) {
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
var results = extractor.extractForeignCode(cellCode);
|
|
662
|
+
var keptCellCode = '';
|
|
663
|
+
var _iterator5 = _createForOfIteratorHelper(results),
|
|
664
|
+
_step5;
|
|
665
|
+
try {
|
|
666
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
667
|
+
var result = _step5.value;
|
|
668
|
+
if (result.foreignCode !== null) {
|
|
669
|
+
// result.range should only be null if result.foregin_code is null
|
|
670
|
+
if (result.range === null) {
|
|
671
|
+
console.warn('Failure in foreign code extraction: `range` is null but `foreign_code` is not!');
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
var foreignDocument = this.chooseForeignDocument(extractor);
|
|
675
|
+
foreignDocumentsMap.set(result.range, {
|
|
676
|
+
virtualLine: foreignDocument.lastVirtualLine,
|
|
677
|
+
virtualDocument: foreignDocument,
|
|
678
|
+
editor: block.ceEditor
|
|
679
|
+
});
|
|
680
|
+
var foreignShift = {
|
|
681
|
+
line: editorShift.line + result.range.start.line,
|
|
682
|
+
column: editorShift.column + result.range.start.column
|
|
683
|
+
};
|
|
684
|
+
foreignDocument.appendCodeBlock({
|
|
685
|
+
value: result.foreignCode,
|
|
686
|
+
ceEditor: block.ceEditor,
|
|
687
|
+
type: 'code'
|
|
688
|
+
}, foreignShift, result.virtualShift);
|
|
689
|
+
}
|
|
690
|
+
if (result.hostCode !== null) {
|
|
691
|
+
keptCellCode += result.hostCode;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
// not breaking - many extractors are allowed to process the code, one after each other
|
|
695
|
+
// (think JS and CSS in HTML, or %R inside of %%timeit).
|
|
696
|
+
} catch (err) {
|
|
697
|
+
_iterator5.e(err);
|
|
698
|
+
} finally {
|
|
699
|
+
_iterator5.f();
|
|
700
|
+
}
|
|
701
|
+
cellCode = keptCellCode;
|
|
702
|
+
}
|
|
703
|
+
return {
|
|
704
|
+
cellCodeKept: cellCode,
|
|
705
|
+
foreignDocumentsMap: foreignDocumentsMap
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Close a foreign document and disconnect all associated signals
|
|
711
|
+
*/
|
|
712
|
+
}, {
|
|
713
|
+
key: "closeForeign",
|
|
714
|
+
value: function closeForeign(document) {
|
|
715
|
+
this._foreignDocumentClosed.fire({
|
|
716
|
+
foreignDocument: document,
|
|
717
|
+
parentHost: this
|
|
718
|
+
});
|
|
719
|
+
// remove it from foreign documents list
|
|
720
|
+
this.foreignDocuments.delete(document.virtualId);
|
|
721
|
+
// and delete the documents within it
|
|
722
|
+
document.closeAllForeignDocuments();
|
|
723
|
+
|
|
724
|
+
// document.foreignDocumentClosed.disconnect(this.forwardClosedSignal, this);
|
|
725
|
+
// document.foreignDocumentOpened.disconnect(this.forwardOpenedSignal, this);
|
|
726
|
+
document.dispose();
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Close all foreign documents.
|
|
731
|
+
*/
|
|
732
|
+
}, {
|
|
733
|
+
key: "closeAllForeignDocuments",
|
|
734
|
+
value: function closeAllForeignDocuments() {
|
|
735
|
+
var _iterator6 = _createForOfIteratorHelper(this.foreignDocuments.values()),
|
|
736
|
+
_step6;
|
|
737
|
+
try {
|
|
738
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
739
|
+
var document = _step6.value;
|
|
740
|
+
this.closeForeign(document);
|
|
741
|
+
}
|
|
742
|
+
} catch (err) {
|
|
743
|
+
_iterator6.e(err);
|
|
744
|
+
} finally {
|
|
745
|
+
_iterator6.f();
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Close all expired documents.
|
|
751
|
+
*/
|
|
752
|
+
}, {
|
|
753
|
+
key: "closeExpiredDocuments",
|
|
754
|
+
value: function closeExpiredDocuments() {
|
|
755
|
+
var _iterator7 = _createForOfIteratorHelper(this.unusedDocuments.values()),
|
|
756
|
+
_step7;
|
|
757
|
+
try {
|
|
758
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
759
|
+
var document = _step7.value;
|
|
760
|
+
document.remainingLifetime -= 1;
|
|
761
|
+
if (document.remainingLifetime <= 0) {
|
|
762
|
+
document.dispose();
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
} catch (err) {
|
|
766
|
+
_iterator7.e(err);
|
|
767
|
+
} finally {
|
|
768
|
+
_iterator7.f();
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Transform the position of the source to the editor
|
|
774
|
+
* position.
|
|
775
|
+
*
|
|
776
|
+
* @param pos - position in the source document
|
|
777
|
+
* @return position in the editor.
|
|
778
|
+
*/
|
|
779
|
+
}, {
|
|
780
|
+
key: "transformSourceToEditor",
|
|
781
|
+
value: function transformSourceToEditor(pos) {
|
|
782
|
+
var sourceLine = this.sourceLines.get(pos.line);
|
|
783
|
+
var editorLine = sourceLine.editorLine;
|
|
784
|
+
var editorShift = sourceLine.editorShift;
|
|
785
|
+
return {
|
|
786
|
+
// only shift column in the line beginning the virtual document (first list of the editor in cell magics, but might be any line of editor in line magics!)
|
|
787
|
+
ch: pos.ch + (editorLine === 0 ? editorShift.column : 0),
|
|
788
|
+
line: editorLine + editorShift.line
|
|
789
|
+
// TODO or:
|
|
790
|
+
// line: pos.line + editor_shift.line - this.first_line_of_the_block(editor)
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Transform the position in the virtual document to the
|
|
796
|
+
* editor position.
|
|
797
|
+
* Can be null because some lines are added as padding/anchors
|
|
798
|
+
* to the virtual document and those do not exist in the source document
|
|
799
|
+
* and thus they are absent in the editor.
|
|
800
|
+
*/
|
|
801
|
+
}, {
|
|
802
|
+
key: "transformVirtualToEditor",
|
|
803
|
+
value: function transformVirtualToEditor(virtualPosition) {
|
|
804
|
+
var sourcePosition = this.transformVirtualToSource(virtualPosition);
|
|
805
|
+
if (!sourcePosition) {
|
|
806
|
+
return null;
|
|
807
|
+
}
|
|
808
|
+
return this.transformSourceToEditor(sourcePosition);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Transform the position in the virtual document to the source.
|
|
813
|
+
* Can be null because some lines are added as padding/anchors
|
|
814
|
+
* to the virtual document and those do not exist in the source document.
|
|
815
|
+
*/
|
|
816
|
+
}, {
|
|
817
|
+
key: "transformVirtualToSource",
|
|
818
|
+
value: function transformVirtualToSource(position) {
|
|
819
|
+
var line = this.virtualLines.get(position.line).sourceLine;
|
|
820
|
+
if (line === null) {
|
|
821
|
+
return null;
|
|
822
|
+
}
|
|
823
|
+
return {
|
|
824
|
+
ch: position.ch,
|
|
825
|
+
line: line
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Get the corresponding editor of the virtual line.
|
|
831
|
+
*/
|
|
832
|
+
}, {
|
|
833
|
+
key: "getEditorAtVirtualLine",
|
|
834
|
+
value: function getEditorAtVirtualLine(pos) {
|
|
835
|
+
var line = pos.line;
|
|
836
|
+
// tolerate overshot by one (the hanging blank line at the end)
|
|
837
|
+
if (!this.virtualLines.has(line)) {
|
|
838
|
+
line -= 1;
|
|
839
|
+
}
|
|
840
|
+
return this.virtualLines.get(line).editor;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Get the corresponding editor of the source line
|
|
845
|
+
*/
|
|
846
|
+
}, {
|
|
847
|
+
key: "getEditorAtSourceLine",
|
|
848
|
+
value: function getEditorAtSourceLine(pos) {
|
|
849
|
+
return this.sourceLines.get(pos.line).editor;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* Recursively emits changed signal from the document or any descendant foreign document.
|
|
854
|
+
*/
|
|
855
|
+
}, {
|
|
856
|
+
key: "maybeEmitChanged",
|
|
857
|
+
value: function maybeEmitChanged() {
|
|
858
|
+
if (this.value !== this.previousValue) {
|
|
859
|
+
this._changed.fire(this);
|
|
860
|
+
}
|
|
861
|
+
this.previousValue = this.value;
|
|
862
|
+
var _iterator8 = _createForOfIteratorHelper(this.foreignDocuments.values()),
|
|
863
|
+
_step8;
|
|
864
|
+
try {
|
|
865
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
866
|
+
var document = _step8.value;
|
|
867
|
+
document.maybeEmitChanged();
|
|
868
|
+
}
|
|
869
|
+
} catch (err) {
|
|
870
|
+
_iterator8.e(err);
|
|
871
|
+
} finally {
|
|
872
|
+
_iterator8.f();
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* When this counter goes down to 0, the document will be destroyed and the associated connection will be closed;
|
|
878
|
+
* This is meant to reduce the number of open connections when a a foreign code snippet was removed from the document.
|
|
879
|
+
*
|
|
880
|
+
* Note: top level virtual documents are currently immortal (unless killed by other means); it might be worth
|
|
881
|
+
* implementing culling of unused documents, but if and only if JupyterLab will also implement culling of
|
|
882
|
+
* idle kernels - otherwise the user experience could be a bit inconsistent, and we would need to invent our own rules.
|
|
883
|
+
*/
|
|
884
|
+
}, {
|
|
885
|
+
key: "remainingLifetime",
|
|
886
|
+
get: function get() {
|
|
887
|
+
if (!this.parent) {
|
|
888
|
+
return Infinity;
|
|
889
|
+
}
|
|
890
|
+
return this._remainingLifetime;
|
|
891
|
+
},
|
|
892
|
+
set: function set(value) {
|
|
893
|
+
if (this.parent) {
|
|
894
|
+
this._remainingLifetime = value;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* Virtual lines keep all the lines present in the document AND extracted to the foreign document.
|
|
900
|
+
*/
|
|
901
|
+
}, {
|
|
902
|
+
key: "chooseForeignDocument",
|
|
903
|
+
value:
|
|
904
|
+
/**
|
|
905
|
+
* Get the foreign document that can be opened with the input extractor.
|
|
906
|
+
*/
|
|
907
|
+
function chooseForeignDocument(extractor) {
|
|
908
|
+
var foreignDocument;
|
|
909
|
+
// if not standalone, try to append to existing document
|
|
910
|
+
var foreignExists = this.foreignDocuments.has(extractor.language);
|
|
911
|
+
if (!extractor.standalone && foreignExists) {
|
|
912
|
+
foreignDocument = this.foreignDocuments.get(extractor.language);
|
|
913
|
+
} else {
|
|
914
|
+
// if (previous document does not exists) or (extractor produces standalone documents
|
|
915
|
+
// and no old standalone document could be reused): create a new document
|
|
916
|
+
foreignDocument = this.openForeign(extractor.language, extractor.standalone, extractor.fileExtension);
|
|
917
|
+
}
|
|
918
|
+
return foreignDocument;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Create a foreign document from input language and file extension.
|
|
923
|
+
*
|
|
924
|
+
* @param language - the required language
|
|
925
|
+
* @param standalone - the document type is supported natively by LSP?
|
|
926
|
+
* @param fileExtension - File extension.
|
|
927
|
+
*/
|
|
928
|
+
}, {
|
|
929
|
+
key: "openForeign",
|
|
930
|
+
value: function openForeign(language, standalone, fileExtension) {
|
|
931
|
+
var _this = this;
|
|
932
|
+
var document = new VirtualDocument(_objectSpread(_objectSpread({}, this.options), {}, {
|
|
933
|
+
parent: this,
|
|
934
|
+
standalone: standalone,
|
|
935
|
+
fileExtension: fileExtension,
|
|
936
|
+
language: language
|
|
937
|
+
}));
|
|
938
|
+
var context = {
|
|
939
|
+
foreignDocument: document,
|
|
940
|
+
parentHost: this
|
|
941
|
+
};
|
|
942
|
+
this._foreignDocumentOpened.fire(context);
|
|
943
|
+
// pass through any future signals
|
|
944
|
+
document.foreignDocumentClosed(function () {
|
|
945
|
+
return _this.forwardClosedSignal(context);
|
|
946
|
+
});
|
|
947
|
+
document.foreignDocumentOpened(function () {
|
|
948
|
+
return _this.forwardOpenedSignal(context);
|
|
949
|
+
});
|
|
950
|
+
this.foreignDocuments.set(document.virtualId, document);
|
|
951
|
+
return document;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* Forward the closed signal from the foreign document to the host document's
|
|
956
|
+
* signal
|
|
957
|
+
*/
|
|
958
|
+
}, {
|
|
959
|
+
key: "forwardClosedSignal",
|
|
960
|
+
value: function forwardClosedSignal(context) {
|
|
961
|
+
this._foreignDocumentClosed.fire(context);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
/**
|
|
965
|
+
* Forward the opened signal from the foreign document to the host document's
|
|
966
|
+
* signal
|
|
967
|
+
*/
|
|
968
|
+
}, {
|
|
969
|
+
key: "forwardOpenedSignal",
|
|
970
|
+
value: function forwardOpenedSignal(context) {
|
|
971
|
+
this._foreignDocumentOpened.fire(context);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Slot of the `updateBegan` signal.
|
|
976
|
+
*/
|
|
977
|
+
}, {
|
|
978
|
+
key: "_updateBeganSlot",
|
|
979
|
+
value: function _updateBeganSlot() {
|
|
980
|
+
this._editorToSourceLineNew = new Map();
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Slot of the `blockAdded` signal.
|
|
985
|
+
*/
|
|
986
|
+
}, {
|
|
987
|
+
key: "_blockAddedSlot",
|
|
988
|
+
value: function _blockAddedSlot(blockData) {
|
|
989
|
+
this._editorToSourceLineNew.set(blockData.block.ceEditor, blockData.virtualDocument.lastSourceLine);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Slot of the `updateFinished` signal.
|
|
994
|
+
*/
|
|
995
|
+
}, {
|
|
996
|
+
key: "_updateFinishedSlot",
|
|
997
|
+
value: function _updateFinishedSlot() {
|
|
998
|
+
this._editorToSourceLine = this._editorToSourceLineNew;
|
|
999
|
+
}
|
|
1000
|
+
}], [{
|
|
1001
|
+
key: "ceToCm",
|
|
1002
|
+
value: function ceToCm(position) {
|
|
1003
|
+
return {
|
|
1004
|
+
line: position.line,
|
|
1005
|
+
ch: position.column
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
}]);
|
|
1009
|
+
return VirtualDocument;
|
|
1010
|
+
}();
|
|
1011
|
+
VirtualDocument.instancesCount = 0;
|
|
1012
|
+
/**
|
|
1013
|
+
* Create foreign documents if available from input virtual documents.
|
|
1014
|
+
* @param virtualDocument - the virtual document to be collected
|
|
1015
|
+
* @return - Set of generated foreign documents
|
|
1016
|
+
*/
|
|
1017
|
+
export function collectDocuments(virtualDocument) {
|
|
1018
|
+
var collected = new Set();
|
|
1019
|
+
collected.add(virtualDocument);
|
|
1020
|
+
var _iterator9 = _createForOfIteratorHelper(virtualDocument.foreignDocuments.values()),
|
|
1021
|
+
_step9;
|
|
1022
|
+
try {
|
|
1023
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
1024
|
+
var foreign = _step9.value;
|
|
1025
|
+
var foreignLanguages = collectDocuments(foreign);
|
|
1026
|
+
foreignLanguages.forEach(collected.add, collected);
|
|
1027
|
+
}
|
|
1028
|
+
} catch (err) {
|
|
1029
|
+
_iterator9.e(err);
|
|
1030
|
+
} finally {
|
|
1031
|
+
_iterator9.f();
|
|
1032
|
+
}
|
|
1033
|
+
return collected;
|
|
1034
|
+
}
|
|
1035
|
+
export var UpdateManager = /*#__PURE__*/function () {
|
|
1036
|
+
// eslint-disable-next-line @typescript-eslint/parameter-properties, @typescript-eslint/no-parameter-properties
|
|
1037
|
+
function UpdateManager(virtualDocument) {
|
|
1038
|
+
_classCallCheck(this, UpdateManager);
|
|
1039
|
+
this.virtualDocument = virtualDocument;
|
|
1040
|
+
this._isDisposed = false;
|
|
1041
|
+
/**
|
|
1042
|
+
* Promise resolved when the updating process finishes.
|
|
1043
|
+
*/
|
|
1044
|
+
this._updateDone = new Promise(function (resolve) {
|
|
1045
|
+
resolve();
|
|
1046
|
+
});
|
|
1047
|
+
/**
|
|
1048
|
+
* Virtual documents update guard.
|
|
1049
|
+
*/
|
|
1050
|
+
this._isUpdateInProgress = false;
|
|
1051
|
+
/**
|
|
1052
|
+
* Update lock to prevent multiple updates are applied at the same time.
|
|
1053
|
+
*/
|
|
1054
|
+
this._updateLock = false;
|
|
1055
|
+
this._blockAdded = new Emitter();
|
|
1056
|
+
this._documentUpdated = new Emitter();
|
|
1057
|
+
this._updateBegan = new Emitter();
|
|
1058
|
+
this._updateFinished = new Emitter();
|
|
1059
|
+
this.documentUpdated(this._onUpdated);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* Promise resolved when the updating process finishes.
|
|
1064
|
+
*/
|
|
1065
|
+
_createClass(UpdateManager, [{
|
|
1066
|
+
key: "updateDone",
|
|
1067
|
+
get: function get() {
|
|
1068
|
+
return this._updateDone;
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Test whether the document is disposed.
|
|
1072
|
+
*/
|
|
1073
|
+
}, {
|
|
1074
|
+
key: "isDisposed",
|
|
1075
|
+
get: function get() {
|
|
1076
|
+
return this._isDisposed;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Signal emitted when a code block is added to the document.
|
|
1081
|
+
*/
|
|
1082
|
+
}, {
|
|
1083
|
+
key: "blockAdded",
|
|
1084
|
+
get: function get() {
|
|
1085
|
+
return this._blockAdded.event;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* Signal emitted by the editor that triggered the update,
|
|
1090
|
+
* providing the root document of the updated documents.
|
|
1091
|
+
*/
|
|
1092
|
+
}, {
|
|
1093
|
+
key: "documentUpdated",
|
|
1094
|
+
get: function get() {
|
|
1095
|
+
return this._documentUpdated.event;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* Signal emitted when the update is started
|
|
1100
|
+
*/
|
|
1101
|
+
}, {
|
|
1102
|
+
key: "updateBegan",
|
|
1103
|
+
get: function get() {
|
|
1104
|
+
return this._updateBegan.event;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Signal emitted when the update is finished
|
|
1109
|
+
*/
|
|
1110
|
+
}, {
|
|
1111
|
+
key: "updateFinished",
|
|
1112
|
+
get: function get() {
|
|
1113
|
+
return this._updateFinished.event;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
/**
|
|
1117
|
+
* Dispose the class
|
|
1118
|
+
*/
|
|
1119
|
+
}, {
|
|
1120
|
+
key: "dispose",
|
|
1121
|
+
value: function dispose() {
|
|
1122
|
+
if (this._isDisposed) {
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
this._isDisposed = true;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* Execute provided callback within an update-locked context, which guarantees that:
|
|
1130
|
+
* - the previous updates must have finished before the callback call, and
|
|
1131
|
+
* - no update will happen when executing the callback
|
|
1132
|
+
* @param fn - the callback to execute in update lock
|
|
1133
|
+
*/
|
|
1134
|
+
}, {
|
|
1135
|
+
key: "withUpdateLock",
|
|
1136
|
+
value: function () {
|
|
1137
|
+
var _withUpdateLock = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(fn) {
|
|
1138
|
+
var _this2 = this;
|
|
1139
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
1140
|
+
while (1) switch (_context.prev = _context.next) {
|
|
1141
|
+
case 0:
|
|
1142
|
+
_context.next = 2;
|
|
1143
|
+
return untilReady(function () {
|
|
1144
|
+
return _this2._canUpdate();
|
|
1145
|
+
}, 12, 10).then(function () {
|
|
1146
|
+
try {
|
|
1147
|
+
_this2._updateLock = true;
|
|
1148
|
+
fn();
|
|
1149
|
+
} catch (ex) {
|
|
1150
|
+
console.error(ex);
|
|
1151
|
+
} finally {
|
|
1152
|
+
_this2._updateLock = false;
|
|
1153
|
+
}
|
|
1154
|
+
return;
|
|
1155
|
+
});
|
|
1156
|
+
case 2:
|
|
1157
|
+
case "end":
|
|
1158
|
+
return _context.stop();
|
|
1159
|
+
}
|
|
1160
|
+
}, _callee);
|
|
1161
|
+
}));
|
|
1162
|
+
function withUpdateLock(_x) {
|
|
1163
|
+
return _withUpdateLock.apply(this, arguments);
|
|
1164
|
+
}
|
|
1165
|
+
return withUpdateLock;
|
|
1166
|
+
}()
|
|
1167
|
+
/**
|
|
1168
|
+
* Update all the virtual documents, emit documents updated with root document if succeeded,
|
|
1169
|
+
* and resolve a void promise. The promise does not contain the text value of the root document,
|
|
1170
|
+
* as to avoid an easy trap of ignoring the changes in the virtual documents.
|
|
1171
|
+
*/
|
|
1172
|
+
}, {
|
|
1173
|
+
key: "updateDocuments",
|
|
1174
|
+
value: function () {
|
|
1175
|
+
var _updateDocuments = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(blocks) {
|
|
1176
|
+
var _this3 = this;
|
|
1177
|
+
var update;
|
|
1178
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
1179
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
1180
|
+
case 0:
|
|
1181
|
+
update = new Promise(function (resolve, reject) {
|
|
1182
|
+
// defer the update by up to 50 ms (10 retrials * 5 ms break),
|
|
1183
|
+
// awaiting for the previous update to complete.
|
|
1184
|
+
untilReady(function () {
|
|
1185
|
+
return _this3._canUpdate();
|
|
1186
|
+
}, 10, 5).then(function () {
|
|
1187
|
+
if (_this3.isDisposed || !_this3.virtualDocument) {
|
|
1188
|
+
resolve();
|
|
1189
|
+
}
|
|
1190
|
+
try {
|
|
1191
|
+
_this3._isUpdateInProgress = true;
|
|
1192
|
+
_this3._updateBegan.fire(blocks);
|
|
1193
|
+
_this3.virtualDocument.clear();
|
|
1194
|
+
var _iterator10 = _createForOfIteratorHelper(blocks),
|
|
1195
|
+
_step10;
|
|
1196
|
+
try {
|
|
1197
|
+
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
1198
|
+
var codeBlock = _step10.value;
|
|
1199
|
+
_this3._blockAdded.fire({
|
|
1200
|
+
block: codeBlock,
|
|
1201
|
+
virtualDocument: _this3.virtualDocument
|
|
1202
|
+
});
|
|
1203
|
+
_this3.virtualDocument.appendCodeBlock(codeBlock);
|
|
1204
|
+
}
|
|
1205
|
+
} catch (err) {
|
|
1206
|
+
_iterator10.e(err);
|
|
1207
|
+
} finally {
|
|
1208
|
+
_iterator10.f();
|
|
1209
|
+
}
|
|
1210
|
+
_this3._updateFinished.fire(blocks);
|
|
1211
|
+
if (_this3.virtualDocument) {
|
|
1212
|
+
_this3._documentUpdated.fire(_this3.virtualDocument);
|
|
1213
|
+
_this3.virtualDocument.maybeEmitChanged();
|
|
1214
|
+
}
|
|
1215
|
+
resolve();
|
|
1216
|
+
} catch (e) {
|
|
1217
|
+
console.warn('Documents update failed:', e);
|
|
1218
|
+
reject(e);
|
|
1219
|
+
} finally {
|
|
1220
|
+
_this3._isUpdateInProgress = false;
|
|
1221
|
+
}
|
|
1222
|
+
return;
|
|
1223
|
+
}).catch(console.error);
|
|
1224
|
+
});
|
|
1225
|
+
this._updateDone = update;
|
|
1226
|
+
return _context2.abrupt("return", update);
|
|
1227
|
+
case 3:
|
|
1228
|
+
case "end":
|
|
1229
|
+
return _context2.stop();
|
|
1230
|
+
}
|
|
1231
|
+
}, _callee2, this);
|
|
1232
|
+
}));
|
|
1233
|
+
function updateDocuments(_x2) {
|
|
1234
|
+
return _updateDocuments.apply(this, arguments);
|
|
1235
|
+
}
|
|
1236
|
+
return updateDocuments;
|
|
1237
|
+
}()
|
|
1238
|
+
}, {
|
|
1239
|
+
key: "_onUpdated",
|
|
1240
|
+
value:
|
|
1241
|
+
/**
|
|
1242
|
+
* Once all the foreign documents were refreshed, the unused documents (and their connections)
|
|
1243
|
+
* should be terminated if their lifetime has expired.
|
|
1244
|
+
*/
|
|
1245
|
+
function _onUpdated(rootDocument) {
|
|
1246
|
+
try {
|
|
1247
|
+
rootDocument.closeExpiredDocuments();
|
|
1248
|
+
} catch (e) {
|
|
1249
|
+
console.warn('Failed to close expired documents');
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* Check if the document can be updated.
|
|
1255
|
+
*/
|
|
1256
|
+
}, {
|
|
1257
|
+
key: "_canUpdate",
|
|
1258
|
+
value: function _canUpdate() {
|
|
1259
|
+
return !this.isDisposed && !this._isUpdateInProgress && !this._updateLock;
|
|
1260
|
+
}
|
|
1261
|
+
}]);
|
|
1262
|
+
return UpdateManager;
|
|
1263
|
+
}();
|