/
editor.ts
358 lines (315 loc) · 9.94 KB
/
editor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
// *****************************************************************************
// Copyright (C) 2018 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
import { Position, Range, Location } from '@theia/core/shared/vscode-languageserver-protocol';
import * as lsp from '@theia/core/shared/vscode-languageserver-protocol';
import URI from '@theia/core/lib/common/uri';
import { Event, Disposable, TextDocumentContentChangeDelta, Reference, isObject } from '@theia/core/lib/common';
import { Saveable, Navigatable, Widget } from '@theia/core/lib/browser';
import { EditorDecoration } from './decorations/editor-decoration';
export { Position, Range, Location };
export const TextEditorProvider = Symbol('TextEditorProvider');
export type TextEditorProvider = (uri: URI) => Promise<TextEditor>;
export interface TextEditorDocument extends lsp.TextDocument, Saveable, Disposable {
getLineContent(lineNumber: number): string;
getLineMaxColumn(lineNumber: number): number;
/**
* @since 1.8.0
*/
findMatches?(options: FindMatchesOptions): FindMatch[];
/**
* Creates a valid position. If the position is outside of the backing document, this method will return a position that is ensured to be inside the document and valid.
* For example, when the `position` is `{ line: 1, character: 0 }` and the document is empty, this method will return with `{ line: 0, character: 0 }`.
*/
toValidPosition(position: Position): Position;
/**
* Creates a valid range. If the `range` argument is outside of the document, this method will return with a new range that does not exceed the boundaries of the document.
* For example, if the argument is `{ start: { line: 1, character: 0 }, end: { line: 1, character: 0 } }` and the document is empty, the return value is
* `{ start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }`.
*/
toValidRange(range: Range): Range;
}
// Refactoring
export { TextDocumentContentChangeDelta };
export interface TextDocumentChangeEvent {
readonly document: TextEditorDocument;
readonly contentChanges: TextDocumentContentChangeDelta[];
}
/**
* Type of hit element with the mouse in the editor.
* Copied from monaco editor.
*/
export enum MouseTargetType {
/**
* Mouse is on top of an unknown element.
*/
UNKNOWN = 0,
/**
* Mouse is on top of the textarea used for input.
*/
TEXTAREA = 1,
/**
* Mouse is on top of the glyph margin
*/
GUTTER_GLYPH_MARGIN = 2,
/**
* Mouse is on top of the line numbers
*/
GUTTER_LINE_NUMBERS = 3,
/**
* Mouse is on top of the line decorations
*/
GUTTER_LINE_DECORATIONS = 4,
/**
* Mouse is on top of the whitespace left in the gutter by a view zone.
*/
GUTTER_VIEW_ZONE = 5,
/**
* Mouse is on top of text in the content.
*/
CONTENT_TEXT = 6,
/**
* Mouse is on top of empty space in the content (e.g. after line text or below last line)
*/
CONTENT_EMPTY = 7,
/**
* Mouse is on top of a view zone in the content.
*/
CONTENT_VIEW_ZONE = 8,
/**
* Mouse is on top of a content widget.
*/
CONTENT_WIDGET = 9,
/**
* Mouse is on top of the decorations overview ruler.
*/
OVERVIEW_RULER = 10,
/**
* Mouse is on top of a scrollbar.
*/
SCROLLBAR = 11,
/**
* Mouse is on top of an overlay widget.
*/
OVERLAY_WIDGET = 12,
/**
* Mouse is outside of the editor.
*/
OUTSIDE_EDITOR = 13,
}
export interface MouseTarget {
/**
* The target element
*/
readonly element?: Element;
/**
* The target type
*/
readonly type: MouseTargetType;
/**
* The 'approximate' editor position
*/
readonly position?: Position;
/**
* Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line).
*/
readonly mouseColumn: number;
/**
* The 'approximate' editor range
*/
readonly range?: Range;
/**
* Some extra detail.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
readonly detail: any;
}
export interface EditorMouseEvent {
readonly event: MouseEvent;
readonly target: MouseTarget;
}
export const enum EncodingMode {
/**
* Instructs the encoding support to encode the current input with the provided encoding
*/
Encode,
/**
* Instructs the encoding support to decode the current input with the provided encoding
*/
Decode
}
/**
* Options for searching in an editor.
*/
export interface FindMatchesOptions {
/**
* The string used to search. If it is a regular expression, set `isRegex` to true.
*/
searchString: string;
/**
* Used to indicate that `searchString` is a regular expression.
*/
isRegex: boolean;
/**
* Force the matching to match lower/upper case exactly.
*/
matchCase: boolean;
/**
* Force the matching to match entire words only.
*/
matchWholeWord: boolean;
/**
* Limit the number of results.
*/
limitResultCount?: number;
}
/**
* Representation of a find match.
*/
export interface FindMatch {
/**
* The textual match.
*/
readonly matches: string[];
/**
* The range for the given match.
*/
readonly range: Range;
}
export interface TextEditor extends Disposable, TextEditorSelection, Navigatable {
readonly node: HTMLElement;
readonly uri: URI;
readonly isReadonly: boolean;
readonly document: TextEditorDocument;
readonly onDocumentContentChanged: Event<TextDocumentChangeEvent>;
cursor: Position;
readonly onCursorPositionChanged: Event<Position>;
selection: Range;
readonly onSelectionChanged: Event<Range>;
/**
* The text editor should be revealed,
* otherwise it won't receive the focus.
*/
focus(): void;
blur(): void;
isFocused(): boolean;
readonly onFocusChanged: Event<boolean>;
readonly onMouseDown: Event<EditorMouseEvent>;
readonly onScrollChanged: Event<void>;
getVisibleRanges(): Range[];
revealPosition(position: Position, options?: RevealPositionOptions): void;
revealRange(range: Range, options?: RevealRangeOptions): void;
/**
* Rerender the editor.
*/
refresh(): void;
/**
* Resize the editor to fit its node.
*/
resizeToFit(): void;
setSize(size: Dimension): void;
/**
* Applies given new decorations, and removes old decorations identified by ids.
*
* @returns identifiers of applied decorations, which can be removed in next call.
*/
deltaDecorations(params: DeltaDecorationParams): string[];
/**
* Gets all the decorations for the lines between `startLineNumber` and `endLineNumber` as an array.
* @param startLineNumber The start line number.
* @param endLineNumber The end line number.
* @return An array with the decorations.
*/
getLinesDecorations(startLineNumber: number, endLineNumber: number): EditorDecoration[];
getVisibleColumn(position: Position): number;
/**
* Replaces the text of source given in ReplaceTextParams.
* @param params: ReplaceTextParams
*/
replaceText(params: ReplaceTextParams): Promise<boolean>;
/**
* Execute edits on the editor.
* @param edits: edits created with `lsp.TextEdit.replace`, `lsp.TextEdit.insert`, `lsp.TextEdit.del`
*/
executeEdits(edits: lsp.TextEdit[]): boolean;
storeViewState(): object;
restoreViewState(state: object): void;
detectLanguage(): void;
setLanguage(languageId: string): void;
readonly onLanguageChanged: Event<string>;
/**
* Gets the encoding of the input if known.
*/
getEncoding(): string;
/**
* Sets the encoding for the input for saving.
*/
setEncoding(encoding: string, mode: EncodingMode): void;
readonly onEncodingChanged: Event<string>;
}
export interface Dimension {
width: number;
height: number;
}
export interface TextEditorSelection {
uri: URI
cursor?: Position
selection?: Range
}
export interface RevealPositionOptions {
vertical: 'auto' | 'center' | 'centerIfOutsideViewport';
horizontal?: boolean;
}
export interface RevealRangeOptions {
at: 'auto' | 'center' | 'top' | 'centerIfOutsideViewport';
}
export interface DeltaDecorationParams {
oldDecorations: string[];
newDecorations: EditorDecoration[];
}
export interface ReplaceTextParams {
/**
* the source to edit
*/
source: string;
/**
* the replace operations
*/
replaceOperations: ReplaceOperation[];
}
export interface ReplaceOperation {
/**
* the position that shall be replaced
*/
range: Range;
/**
* the text to replace with
*/
text: string;
}
export namespace TextEditorSelection {
export function is(arg: unknown): arg is TextEditorSelection {
return isObject<TextEditorSelection>(arg) && arg.uri instanceof URI;
}
}
export namespace CustomEditorWidget {
export function is(arg: Widget | undefined): arg is CustomEditorWidget {
return !!arg && 'modelRef' in arg;
}
}
export interface CustomEditorWidget extends Widget {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
readonly modelRef: Reference<any>;
}