UNPKG

7.13 kBJavaScriptView Raw
1"use strict";
2/* --------------------------------------------------------------------------------------------
3 * Copyright (c) Microsoft Corporation. All rights reserved.
4 * Licensed under the MIT License. See License.txt in the project root for license information.
5 * ------------------------------------------------------------------------------------------ */
6Object.defineProperty(exports, "__esModule", { value: true });
7exports.TextDocuments = void 0;
8const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
9/**
10 * A manager for simple text documents. The manager requires at a minimum that
11 * the server registered for the following text document sync events in the
12 * initialize handler or via dynamic registration:
13 *
14 * - open and close events.
15 * - change events.
16 *
17 * Registering for save and will save events is optional.
18 */
19class TextDocuments {
20 /**
21 * Create a new text document manager.
22 */
23 constructor(configuration) {
24 this._configuration = configuration;
25 this._syncedDocuments = new Map();
26 this._onDidChangeContent = new vscode_languageserver_protocol_1.Emitter();
27 this._onDidOpen = new vscode_languageserver_protocol_1.Emitter();
28 this._onDidClose = new vscode_languageserver_protocol_1.Emitter();
29 this._onDidSave = new vscode_languageserver_protocol_1.Emitter();
30 this._onWillSave = new vscode_languageserver_protocol_1.Emitter();
31 }
32 /**
33 * An event that fires when a text document managed by this manager
34 * has been opened.
35 */
36 get onDidOpen() {
37 return this._onDidOpen.event;
38 }
39 /**
40 * An event that fires when a text document managed by this manager
41 * has been opened or the content changes.
42 */
43 get onDidChangeContent() {
44 return this._onDidChangeContent.event;
45 }
46 /**
47 * An event that fires when a text document managed by this manager
48 * will be saved.
49 */
50 get onWillSave() {
51 return this._onWillSave.event;
52 }
53 /**
54 * Sets a handler that will be called if a participant wants to provide
55 * edits during a text document save.
56 */
57 onWillSaveWaitUntil(handler) {
58 this._willSaveWaitUntil = handler;
59 }
60 /**
61 * An event that fires when a text document managed by this manager
62 * has been saved.
63 */
64 get onDidSave() {
65 return this._onDidSave.event;
66 }
67 /**
68 * An event that fires when a text document managed by this manager
69 * has been closed.
70 */
71 get onDidClose() {
72 return this._onDidClose.event;
73 }
74 /**
75 * Returns the document for the given URI. Returns undefined if
76 * the document is not managed by this instance.
77 *
78 * @param uri The text document's URI to retrieve.
79 * @return the text document or `undefined`.
80 */
81 get(uri) {
82 return this._syncedDocuments.get(uri);
83 }
84 /**
85 * Returns all text documents managed by this instance.
86 *
87 * @return all text documents.
88 */
89 all() {
90 return Array.from(this._syncedDocuments.values());
91 }
92 /**
93 * Returns the URIs of all text documents managed by this instance.
94 *
95 * @return the URI's of all text documents.
96 */
97 keys() {
98 return Array.from(this._syncedDocuments.keys());
99 }
100 /**
101 * Listens for `low level` notification on the given connection to
102 * update the text documents managed by this instance.
103 *
104 * Please note that the connection only provides handlers not an event model. Therefore
105 * listening on a connection will overwrite the following handlers on a connection:
106 * `onDidOpenTextDocument`, `onDidChangeTextDocument`, `onDidCloseTextDocument`,
107 * `onWillSaveTextDocument`, `onWillSaveTextDocumentWaitUntil` and `onDidSaveTextDocument`.
108 *
109 * Use the corresponding events on the TextDocuments instance instead.
110 *
111 * @param connection The connection to listen on.
112 */
113 listen(connection) {
114 connection.__textDocumentSync = vscode_languageserver_protocol_1.TextDocumentSyncKind.Incremental;
115 const disposables = [];
116 disposables.push(connection.onDidOpenTextDocument((event) => {
117 const td = event.textDocument;
118 const document = this._configuration.create(td.uri, td.languageId, td.version, td.text);
119 this._syncedDocuments.set(td.uri, document);
120 const toFire = Object.freeze({ document });
121 this._onDidOpen.fire(toFire);
122 this._onDidChangeContent.fire(toFire);
123 }));
124 disposables.push(connection.onDidChangeTextDocument((event) => {
125 const td = event.textDocument;
126 const changes = event.contentChanges;
127 if (changes.length === 0) {
128 return;
129 }
130 const { version } = td;
131 if (version === null || version === undefined) {
132 throw new Error(`Received document change event for ${td.uri} without valid version identifier`);
133 }
134 let syncedDocument = this._syncedDocuments.get(td.uri);
135 if (syncedDocument !== undefined) {
136 syncedDocument = this._configuration.update(syncedDocument, changes, version);
137 this._syncedDocuments.set(td.uri, syncedDocument);
138 this._onDidChangeContent.fire(Object.freeze({ document: syncedDocument }));
139 }
140 }));
141 disposables.push(connection.onDidCloseTextDocument((event) => {
142 let syncedDocument = this._syncedDocuments.get(event.textDocument.uri);
143 if (syncedDocument !== undefined) {
144 this._syncedDocuments.delete(event.textDocument.uri);
145 this._onDidClose.fire(Object.freeze({ document: syncedDocument }));
146 }
147 }));
148 disposables.push(connection.onWillSaveTextDocument((event) => {
149 let syncedDocument = this._syncedDocuments.get(event.textDocument.uri);
150 if (syncedDocument !== undefined) {
151 this._onWillSave.fire(Object.freeze({ document: syncedDocument, reason: event.reason }));
152 }
153 }));
154 disposables.push(connection.onWillSaveTextDocumentWaitUntil((event, token) => {
155 let syncedDocument = this._syncedDocuments.get(event.textDocument.uri);
156 if (syncedDocument !== undefined && this._willSaveWaitUntil) {
157 return this._willSaveWaitUntil(Object.freeze({ document: syncedDocument, reason: event.reason }), token);
158 }
159 else {
160 return [];
161 }
162 }));
163 disposables.push(connection.onDidSaveTextDocument((event) => {
164 let syncedDocument = this._syncedDocuments.get(event.textDocument.uri);
165 if (syncedDocument !== undefined) {
166 this._onDidSave.fire(Object.freeze({ document: syncedDocument }));
167 }
168 }));
169 return vscode_languageserver_protocol_1.Disposable.create(() => { disposables.forEach(disposable => disposable.dispose()); });
170 }
171}
172exports.TextDocuments = TextDocuments;