@difizen/libro-code-editor 0.1.1 → 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/es/code-editor-info-manager.d.ts +7 -0
- package/es/code-editor-info-manager.d.ts.map +1 -0
- package/es/code-editor-info-manager.js +32 -0
- package/es/code-editor-manager.d.ts +67 -0
- package/es/code-editor-manager.d.ts.map +1 -0
- package/es/code-editor-manager.js +130 -0
- package/es/{model.d.ts → code-editor-model.d.ts} +2 -2
- package/es/code-editor-model.d.ts.map +1 -0
- package/es/{model.js → code-editor-model.js} +1 -3
- package/es/{code-editor.d.ts → code-editor-protocol.d.ts} +70 -145
- package/es/code-editor-protocol.d.ts.map +1 -0
- package/es/{code-editor.js → code-editor-protocol.js} +17 -15
- package/es/code-editor-settings.d.ts +34 -0
- package/es/code-editor-settings.d.ts.map +1 -0
- package/es/code-editor-settings.js +225 -0
- package/es/code-editor-view.d.ts +26 -14
- package/es/code-editor-view.d.ts.map +1 -1
- package/es/code-editor-view.js +108 -72
- package/es/index.d.ts +5 -3
- package/es/index.d.ts.map +1 -1
- package/es/index.js +6 -4
- package/es/mimetype.d.ts.map +1 -1
- package/es/mimetype.js +3 -0
- package/es/module.d.ts.map +1 -1
- package/es/module.js +5 -2
- package/package.json +4 -5
- package/src/code-editor-info-manager.ts +25 -0
- package/src/code-editor-manager.ts +86 -0
- package/src/{model.ts → code-editor-model.ts} +4 -4
- package/src/{code-editor.ts → code-editor-protocol.ts} +136 -189
- package/src/code-editor-settings.ts +214 -0
- package/src/code-editor-view.tsx +93 -49
- package/src/index.spec.ts +1 -3
- package/src/index.ts +5 -3
- package/src/mimetype.ts +3 -0
- package/src/module.ts +13 -2
- package/es/code-editor.d.ts.map +0 -1
- package/es/completer/completer-protocol.d.ts +0 -210
- package/es/completer/completer-protocol.d.ts.map +0 -1
- package/es/completer/completer-protocol.js +0 -34
- package/es/model.d.ts.map +0 -1
- package/src/completer/completer-protocol.ts +0 -259
|
@@ -1,50 +1,19 @@
|
|
|
1
1
|
import type { JSONObject } from '@difizen/libro-common';
|
|
2
|
-
import type { Disposable, Event } from '@difizen/mana-app';
|
|
3
|
-
import type {
|
|
4
|
-
DidChangeConfigurationParams,
|
|
5
|
-
ServerCapabilities,
|
|
6
|
-
} from 'vscode-languageserver-protocol';
|
|
2
|
+
import type { Disposable, Event, ThemeType } from '@difizen/mana-app';
|
|
7
3
|
|
|
8
|
-
import type { IModel } from './model.js';
|
|
4
|
+
import type { IModel } from './code-editor-model.js';
|
|
9
5
|
|
|
10
6
|
/**
|
|
11
|
-
*
|
|
12
|
-
*/
|
|
13
|
-
export interface ILSPEditor {
|
|
14
|
-
/**
|
|
15
|
-
* CodeEditor getter.
|
|
16
|
-
*
|
|
17
|
-
* It will return `null` if the editor is not yet instantiated;
|
|
18
|
-
* e.g. to support windowed notebook.
|
|
19
|
-
*/
|
|
20
|
-
getEditor(): IEditor | null;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Promise getter that resolved when the editor is instantiated.
|
|
24
|
-
*/
|
|
25
|
-
ready(): Promise<IEditor>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Reveal the code editor in viewport.
|
|
29
|
-
*
|
|
30
|
-
* ### Notes
|
|
31
|
-
* The promise will resolve when the editor is instantiated and in
|
|
32
|
-
* the viewport.
|
|
33
|
-
*/
|
|
34
|
-
reveal(): Promise<IEditor>;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* A zero-based position in the editor.
|
|
7
|
+
* A one-based position in the editor.
|
|
39
8
|
*/
|
|
40
9
|
export interface IPosition extends JSONObject {
|
|
41
10
|
/**
|
|
42
|
-
* The cursor line number.
|
|
11
|
+
* The cursor line number. one-based.
|
|
43
12
|
*/
|
|
44
13
|
readonly line: number;
|
|
45
14
|
|
|
46
15
|
/**
|
|
47
|
-
* The cursor column number.
|
|
16
|
+
* The cursor column number. one-based.
|
|
48
17
|
*/
|
|
49
18
|
readonly column: number;
|
|
50
19
|
}
|
|
@@ -148,6 +117,11 @@ export interface ISelectionOwner {
|
|
|
148
117
|
*/
|
|
149
118
|
uuid: string;
|
|
150
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Return selection value, if no range, return primary position value
|
|
122
|
+
*/
|
|
123
|
+
getSelectionValue: (range?: IRange) => string | undefined;
|
|
124
|
+
|
|
151
125
|
/**
|
|
152
126
|
* Returns the primary position of the cursor, never `null`.
|
|
153
127
|
*/
|
|
@@ -194,6 +168,23 @@ export interface ISelectionOwner {
|
|
|
194
168
|
* document.
|
|
195
169
|
*/
|
|
196
170
|
setSelections: (selections: IRange[]) => void;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Replaces selection with the given text.
|
|
174
|
+
*/
|
|
175
|
+
replaceSelection: (text: string, range: IRange) => void;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Replaces selection with the given text.
|
|
179
|
+
*/
|
|
180
|
+
replaceSelections: (edits: { text: string; range: IRange }[]) => void;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* highlight search matches
|
|
184
|
+
* @param matches
|
|
185
|
+
* @param currentIndex
|
|
186
|
+
*/
|
|
187
|
+
highlightMatches: (matches: SearchMatch[], currentIndex: number | undefined) => void;
|
|
197
188
|
}
|
|
198
189
|
|
|
199
190
|
/**
|
|
@@ -274,13 +265,13 @@ export interface IEditor extends ISelectionOwner, Disposable {
|
|
|
274
265
|
* @returns The value of the line.
|
|
275
266
|
*
|
|
276
267
|
* #### Notes
|
|
277
|
-
* Lines are
|
|
268
|
+
* Lines are 1-based, and accessing a line out of range returns
|
|
278
269
|
* `undefined`.
|
|
279
270
|
*/
|
|
280
271
|
getLine: (line: number) => string | undefined;
|
|
281
272
|
|
|
282
273
|
/**
|
|
283
|
-
* Find an offset for the given position.
|
|
274
|
+
* Find an zero-based offset for the given position.
|
|
284
275
|
*
|
|
285
276
|
* @param position - The position of interest.
|
|
286
277
|
*
|
|
@@ -289,15 +280,15 @@ export interface IEditor extends ISelectionOwner, Disposable {
|
|
|
289
280
|
*/
|
|
290
281
|
getOffsetAt: (position: IPosition) => number;
|
|
291
282
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
283
|
+
/**
|
|
284
|
+
* Find a position for the given offset.
|
|
285
|
+
*
|
|
286
|
+
* @param offset - The offset of interest.
|
|
287
|
+
*
|
|
288
|
+
* @returns The position at the offset, clamped to the extent of the
|
|
289
|
+
* editor contents.
|
|
290
|
+
*/
|
|
291
|
+
getPositionAt: (offset: number) => IPosition | undefined;
|
|
301
292
|
|
|
302
293
|
/**
|
|
303
294
|
* Undo one edit (if any undo events are stored).
|
|
@@ -334,6 +325,38 @@ export interface IEditor extends ISelectionOwner, Disposable {
|
|
|
334
325
|
*/
|
|
335
326
|
resizeToFit: () => void;
|
|
336
327
|
|
|
328
|
+
// /**
|
|
329
|
+
// * Add a keydown handler to the editor.
|
|
330
|
+
// *
|
|
331
|
+
// * @param handler - A keydown handler.
|
|
332
|
+
// *
|
|
333
|
+
// * @returns A disposable that can be used to remove the handler.
|
|
334
|
+
// */
|
|
335
|
+
// addKeydownHandler: (handler: KeydownHandler) => Disposable;
|
|
336
|
+
|
|
337
|
+
// /**
|
|
338
|
+
// * Reveals the given position in the editor.
|
|
339
|
+
// *
|
|
340
|
+
// * @param position - The desired position to reveal.
|
|
341
|
+
// */
|
|
342
|
+
// revealPosition: (position: IPosition) => void;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Reveals the given selection in the editor.
|
|
346
|
+
*
|
|
347
|
+
* @param position - The desired selection to reveal.
|
|
348
|
+
*/
|
|
349
|
+
revealSelection: (selection: IRange) => void;
|
|
350
|
+
|
|
351
|
+
// /**
|
|
352
|
+
// * Get the window coordinates given a cursor position.
|
|
353
|
+
// *
|
|
354
|
+
// * @param position - The desired position.
|
|
355
|
+
// *
|
|
356
|
+
// * @returns The coordinates of the position.
|
|
357
|
+
// */
|
|
358
|
+
// getCoordinateForPosition: (position: IPosition) => ICoordinate;
|
|
359
|
+
|
|
337
360
|
/**
|
|
338
361
|
* Get the cursor position given window coordinates.
|
|
339
362
|
*
|
|
@@ -344,18 +367,38 @@ export interface IEditor extends ISelectionOwner, Disposable {
|
|
|
344
367
|
*/
|
|
345
368
|
getPositionForCoordinate: (coordinate: ICoordinate) => IPosition | null;
|
|
346
369
|
|
|
370
|
+
// /**
|
|
371
|
+
// * Get a list of tokens for the current editor text content.
|
|
372
|
+
// */
|
|
373
|
+
// getTokens: () => IToken[];
|
|
374
|
+
|
|
375
|
+
// /**
|
|
376
|
+
// * Get the token at a given editor position.
|
|
377
|
+
// */
|
|
378
|
+
// getTokenAt: (offset: number) => IToken;
|
|
379
|
+
|
|
380
|
+
// /**
|
|
381
|
+
// * Get the token a the cursor position.
|
|
382
|
+
// */
|
|
383
|
+
// getTokenAtCursor: () => IToken;
|
|
384
|
+
|
|
385
|
+
// /**
|
|
386
|
+
// * Inserts a new line at the cursor position and indents it.
|
|
387
|
+
// */
|
|
388
|
+
// newIndentedLine: () => void;
|
|
389
|
+
|
|
347
390
|
onModalChange: Event<boolean>;
|
|
391
|
+
|
|
392
|
+
dispose: () => void;
|
|
348
393
|
}
|
|
349
394
|
|
|
350
|
-
|
|
351
|
-
* A factory used to create a code editor.
|
|
352
|
-
*/
|
|
353
|
-
export type CodeEditorFactory = (options: IEditorOptions) => IEditor;
|
|
395
|
+
export type EditorTheme = Record<ThemeType, string>;
|
|
354
396
|
|
|
355
397
|
/**
|
|
356
398
|
* The configuration options for an editor.
|
|
357
399
|
*/
|
|
358
400
|
export interface IEditorConfig {
|
|
401
|
+
theme: EditorTheme;
|
|
359
402
|
/**
|
|
360
403
|
* Half-period in milliseconds used for cursor blinking.
|
|
361
404
|
* By setting this to zero, blinking can be disabled.
|
|
@@ -454,22 +497,35 @@ export interface IEditorConfig {
|
|
|
454
497
|
highlightActiveLineGutter?: boolean;
|
|
455
498
|
|
|
456
499
|
placeholder?: HTMLElement | string;
|
|
500
|
+
|
|
501
|
+
lspEnabled: boolean;
|
|
502
|
+
|
|
503
|
+
paddingTop: number;
|
|
504
|
+
|
|
505
|
+
paddingBottom: number;
|
|
506
|
+
|
|
507
|
+
scrollBarHeight: number;
|
|
457
508
|
}
|
|
458
509
|
|
|
459
510
|
/**
|
|
460
511
|
* The default configuration options for an editor.
|
|
461
512
|
*/
|
|
462
|
-
export const defaultConfig: IEditorConfig = {
|
|
513
|
+
export const defaultConfig: Required<IEditorConfig> = {
|
|
514
|
+
theme: {
|
|
515
|
+
light: 'light',
|
|
516
|
+
dark: 'dark',
|
|
517
|
+
hc: 'hc-mana',
|
|
518
|
+
},
|
|
463
519
|
// Order matters as gutters will be sorted by the configuration order
|
|
464
520
|
autoClosingBrackets: true,
|
|
465
521
|
cursorBlinkRate: 530,
|
|
466
522
|
fontFamily: null,
|
|
467
|
-
fontSize:
|
|
523
|
+
fontSize: 13,
|
|
468
524
|
handlePaste: true,
|
|
469
525
|
insertSpaces: true,
|
|
470
526
|
lineHeight: null,
|
|
471
527
|
lineNumbers: true,
|
|
472
|
-
lineWrap: '
|
|
528
|
+
lineWrap: 'off',
|
|
473
529
|
matchBrackets: true,
|
|
474
530
|
readOnly: false,
|
|
475
531
|
editable: true,
|
|
@@ -477,10 +533,15 @@ export const defaultConfig: IEditorConfig = {
|
|
|
477
533
|
rulers: [],
|
|
478
534
|
showTrailingSpace: false,
|
|
479
535
|
wordWrapColumn: 80,
|
|
480
|
-
codeFolding:
|
|
536
|
+
codeFolding: true,
|
|
481
537
|
foldGutter: true,
|
|
482
538
|
styleActiveLine: false,
|
|
483
539
|
highlightActiveLineGutter: false,
|
|
540
|
+
lspEnabled: true,
|
|
541
|
+
paddingTop: 12,
|
|
542
|
+
paddingBottom: 18,
|
|
543
|
+
scrollBarHeight: 0,
|
|
544
|
+
placeholder: '',
|
|
484
545
|
};
|
|
485
546
|
|
|
486
547
|
export type TooltipProviderOption = { cursorPosition: number };
|
|
@@ -498,134 +559,6 @@ export type CompletionProvider = (
|
|
|
498
559
|
option: CompletionProviderOption,
|
|
499
560
|
) => Promise<CompletionReply>;
|
|
500
561
|
|
|
501
|
-
export type LSPProviderResult = {
|
|
502
|
-
virtualDocument: IVirtualDocument;
|
|
503
|
-
lspConnection: ILspConnection;
|
|
504
|
-
editor: ILSPEditor;
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
export type LSPProvider = () => Promise<LSPProviderResult>;
|
|
508
|
-
|
|
509
|
-
export interface Position {
|
|
510
|
-
/**
|
|
511
|
-
* Line number
|
|
512
|
-
*/
|
|
513
|
-
line: number;
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* Position of character in line
|
|
517
|
-
*/
|
|
518
|
-
ch: number;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* is_* attributes are there only to enforce strict interface type checking
|
|
523
|
-
*/
|
|
524
|
-
export interface ISourcePosition extends Position {
|
|
525
|
-
isSource: true;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
export interface IEditorPosition extends Position {
|
|
529
|
-
isEditor: true;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
export interface IVirtualPosition extends Position {
|
|
533
|
-
isVirtual: true;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
export interface IRootPosition extends ISourcePosition {
|
|
537
|
-
isRoot: true;
|
|
538
|
-
}
|
|
539
|
-
export interface IVirtualDocument {
|
|
540
|
-
uri: string;
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Get the corresponding editor of the virtual line.
|
|
544
|
-
*/
|
|
545
|
-
getEditorAtVirtualLine: (pos: IVirtualPosition) => ILSPEditor;
|
|
546
|
-
transformEditorToVirtual: (
|
|
547
|
-
editor: ILSPEditor,
|
|
548
|
-
position: IEditorPosition,
|
|
549
|
-
) => IVirtualPosition | null;
|
|
550
|
-
ttransformVirtualToEditor: (
|
|
551
|
-
virtualPosition: IVirtualPosition,
|
|
552
|
-
) => IEditorPosition | null;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
export interface IDocumentInfo {
|
|
556
|
-
/**
|
|
557
|
-
* URI of the virtual document.
|
|
558
|
-
*/
|
|
559
|
-
uri: string;
|
|
560
|
-
|
|
561
|
-
/**
|
|
562
|
-
* Version of the virtual document.
|
|
563
|
-
*/
|
|
564
|
-
version: number;
|
|
565
|
-
|
|
566
|
-
/**
|
|
567
|
-
* Text content of the document.
|
|
568
|
-
*/
|
|
569
|
-
text: string;
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* Language id of the document.
|
|
573
|
-
*/
|
|
574
|
-
languageId: string;
|
|
575
|
-
}
|
|
576
|
-
export interface ILspConnection {
|
|
577
|
-
/**
|
|
578
|
-
* Is the language server is connected?
|
|
579
|
-
*/
|
|
580
|
-
isConnected: boolean;
|
|
581
|
-
/**
|
|
582
|
-
* Is the language server is initialized?
|
|
583
|
-
*/
|
|
584
|
-
isInitialized: boolean;
|
|
585
|
-
|
|
586
|
-
/**
|
|
587
|
-
* Is the language server is connected and initialized?
|
|
588
|
-
*/
|
|
589
|
-
isReady: boolean;
|
|
590
|
-
|
|
591
|
-
/**
|
|
592
|
-
* Initialize a connection over a web socket that speaks the LSP protocol
|
|
593
|
-
*/
|
|
594
|
-
connect(socket: WebSocket): void;
|
|
595
|
-
|
|
596
|
-
/**
|
|
597
|
-
* Close the connection
|
|
598
|
-
*/
|
|
599
|
-
close(): void;
|
|
600
|
-
|
|
601
|
-
// This should support every method from https://microsoft.github.io/language-server-protocol/specification
|
|
602
|
-
/**
|
|
603
|
-
* The initialize request tells the server which options the client supports
|
|
604
|
-
*/
|
|
605
|
-
sendInitialize(): void;
|
|
606
|
-
/**
|
|
607
|
-
* Inform the server that the document was opened
|
|
608
|
-
*/
|
|
609
|
-
sendOpen(documentInfo: IDocumentInfo): void;
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Sends the full text of the document to the server
|
|
613
|
-
*/
|
|
614
|
-
sendChange(documentInfo: IDocumentInfo): void;
|
|
615
|
-
|
|
616
|
-
/**
|
|
617
|
-
* Send save notification to the server.
|
|
618
|
-
*/
|
|
619
|
-
sendSaved(documentInfo: IDocumentInfo): void;
|
|
620
|
-
|
|
621
|
-
/**
|
|
622
|
-
* Send configuration change to the server.
|
|
623
|
-
*/
|
|
624
|
-
sendConfigurationChange(settings: DidChangeConfigurationParams): void;
|
|
625
|
-
|
|
626
|
-
provides(provider: keyof ServerCapabilities): boolean;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
562
|
/**
|
|
630
563
|
* The options used to initialize an editor.
|
|
631
564
|
*/
|
|
@@ -643,17 +576,17 @@ export interface IEditorOptions {
|
|
|
643
576
|
/**
|
|
644
577
|
* The desired uuid for the editor.
|
|
645
578
|
*/
|
|
646
|
-
uuid?: string
|
|
579
|
+
uuid?: string;
|
|
647
580
|
|
|
648
581
|
/**
|
|
649
582
|
* The default selection style for the editor.
|
|
650
583
|
*/
|
|
651
|
-
selectionStyle?: Partial<IEditorSelectionStyle
|
|
584
|
+
selectionStyle?: Partial<IEditorSelectionStyle>;
|
|
652
585
|
|
|
653
586
|
/**
|
|
654
587
|
* The configuration options for the editor.
|
|
655
588
|
*/
|
|
656
|
-
config?: Partial<IEditorConfig
|
|
589
|
+
config?: Partial<IEditorConfig>;
|
|
657
590
|
|
|
658
591
|
// /**
|
|
659
592
|
// * The configuration options for the editor.
|
|
@@ -661,7 +594,21 @@ export interface IEditorOptions {
|
|
|
661
594
|
// translator?: ITranslator;
|
|
662
595
|
|
|
663
596
|
//
|
|
664
|
-
tooltipProvider?: TooltipProvider
|
|
665
|
-
completionProvider?: CompletionProvider
|
|
666
|
-
|
|
597
|
+
tooltipProvider?: TooltipProvider;
|
|
598
|
+
completionProvider?: CompletionProvider;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Base search match interface
|
|
603
|
+
*/
|
|
604
|
+
export interface SearchMatch {
|
|
605
|
+
/**
|
|
606
|
+
* Text of the exact match itself
|
|
607
|
+
*/
|
|
608
|
+
readonly text: string;
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Start location of the match (in a text, this is the column)
|
|
612
|
+
*/
|
|
613
|
+
position: number;
|
|
667
614
|
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import {
|
|
2
|
+
inject,
|
|
3
|
+
singleton,
|
|
4
|
+
ApplicationContribution,
|
|
5
|
+
DisposableCollection,
|
|
6
|
+
Emitter,
|
|
7
|
+
ConfigurationContribution,
|
|
8
|
+
ConfigurationService,
|
|
9
|
+
} from '@difizen/mana-app';
|
|
10
|
+
import type {
|
|
11
|
+
Disposable,
|
|
12
|
+
ConfigurationNode,
|
|
13
|
+
ConfigurationStorage,
|
|
14
|
+
} from '@difizen/mana-app';
|
|
15
|
+
import { l10n } from '@difizen/mana-l10n';
|
|
16
|
+
|
|
17
|
+
import type { IEditorConfig } from './code-editor-protocol.js';
|
|
18
|
+
import { defaultConfig } from './code-editor-protocol.js';
|
|
19
|
+
|
|
20
|
+
declare global {
|
|
21
|
+
interface ObjectConstructor {
|
|
22
|
+
typedKeys<T>(obj: T): (keyof T)[];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
Object.typedKeys = Object.keys as any;
|
|
26
|
+
|
|
27
|
+
const LibroUserSettingStorage: ConfigurationStorage = {
|
|
28
|
+
id: '__libro.user.storage__',
|
|
29
|
+
priority: 100,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const FontSize: ConfigurationNode<number> = {
|
|
33
|
+
id: 'libro.user.codeeditor.fontsize',
|
|
34
|
+
description: l10n.t('代码编辑区域字体大小'),
|
|
35
|
+
title: l10n.t('代码字号'),
|
|
36
|
+
type: 'inputnumber',
|
|
37
|
+
defaultValue: defaultConfig.fontSize ?? 13,
|
|
38
|
+
schema: {
|
|
39
|
+
type: 'number',
|
|
40
|
+
},
|
|
41
|
+
storage: LibroUserSettingStorage,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const LineHeight: ConfigurationNode<number> = {
|
|
45
|
+
id: 'libro.user.codeeditor.lineheight',
|
|
46
|
+
description: l10n.t('代码编辑区域字体行高'),
|
|
47
|
+
title: l10n.t('代码行高'),
|
|
48
|
+
type: 'inputnumber',
|
|
49
|
+
defaultValue: defaultConfig.lineHeight ?? 20,
|
|
50
|
+
schema: {
|
|
51
|
+
type: 'number',
|
|
52
|
+
},
|
|
53
|
+
storage: LibroUserSettingStorage,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const TabSize: ConfigurationNode<number> = {
|
|
57
|
+
id: 'libro.user.codeeditor.tabsize',
|
|
58
|
+
description: l10n.t('tab转换为几个空格大小'),
|
|
59
|
+
title: l10n.t('tab大小'),
|
|
60
|
+
type: 'inputnumber',
|
|
61
|
+
defaultValue: defaultConfig.tabSize ?? 4,
|
|
62
|
+
schema: {
|
|
63
|
+
type: 'number',
|
|
64
|
+
},
|
|
65
|
+
storage: LibroUserSettingStorage,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const InsertSpaces: ConfigurationNode<boolean> = {
|
|
69
|
+
id: 'libro.user.codeeditor.insertspaces',
|
|
70
|
+
description: l10n.t('输入tab是否转换为空格'),
|
|
71
|
+
title: l10n.t('tab转空格'),
|
|
72
|
+
type: 'checkbox',
|
|
73
|
+
defaultValue: defaultConfig.insertSpaces,
|
|
74
|
+
schema: {
|
|
75
|
+
type: 'boolean',
|
|
76
|
+
},
|
|
77
|
+
storage: LibroUserSettingStorage,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const LineWarp: ConfigurationNode<'wordWrapColumn' | 'off' | 'on' | 'bounded'> = {
|
|
81
|
+
id: 'libro.user.codeeditor.linewarp',
|
|
82
|
+
description: l10n.t(`自动换行策略:
|
|
83
|
+
- "off", lines will never wrap.
|
|
84
|
+
- "on", lines will wrap at the viewport border.
|
|
85
|
+
- "wordWrapColumn", lines will wrap at 'wordWrapColumn'.
|
|
86
|
+
- "bounded", lines will wrap at minimum between viewport width and wordWrapColumn.`),
|
|
87
|
+
title: l10n.t('自动换行'),
|
|
88
|
+
type: 'select',
|
|
89
|
+
defaultValue: defaultConfig.lineWrap,
|
|
90
|
+
schema: {
|
|
91
|
+
type: 'string',
|
|
92
|
+
enum: ['off', 'on', 'wordWrapColumn', 'bounded'],
|
|
93
|
+
},
|
|
94
|
+
storage: LibroUserSettingStorage,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const WordWrapColumn: ConfigurationNode<number> = {
|
|
98
|
+
id: 'libro.user.codeeditor.wordWrapColumn',
|
|
99
|
+
description: l10n.t('开启自动换行后,自动换行的列数'),
|
|
100
|
+
title: l10n.t('自动换行列数'),
|
|
101
|
+
type: 'inputnumber',
|
|
102
|
+
defaultValue: defaultConfig.wordWrapColumn,
|
|
103
|
+
schema: {
|
|
104
|
+
type: 'number',
|
|
105
|
+
},
|
|
106
|
+
storage: LibroUserSettingStorage,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const LSPEnabled: ConfigurationNode<boolean> = {
|
|
110
|
+
id: 'libro.user.codeeditor.lspenabled',
|
|
111
|
+
description: l10n.t(
|
|
112
|
+
'开启语言服务后,编辑器能提供更多辅助编码能力,包括:自动提示、代码诊断、hover提示、格式化、代码跳转、重命名等等(需要使用带有lsp服务的容器, 详情请咨询 @沧浪)',
|
|
113
|
+
),
|
|
114
|
+
title: l10n.t('开启语言服务'),
|
|
115
|
+
type: 'checkbox',
|
|
116
|
+
defaultValue: defaultConfig.lspEnabled,
|
|
117
|
+
schema: {
|
|
118
|
+
type: 'boolean',
|
|
119
|
+
},
|
|
120
|
+
storage: LibroUserSettingStorage,
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const CodeEditorSetting: {
|
|
124
|
+
[key in keyof IEditorConfig]?: ConfigurationNode<any>;
|
|
125
|
+
} = {
|
|
126
|
+
fontSize: FontSize,
|
|
127
|
+
tabSize: TabSize,
|
|
128
|
+
insertSpaces: InsertSpaces,
|
|
129
|
+
lineHeight: LineHeight,
|
|
130
|
+
lineWrap: LineWarp,
|
|
131
|
+
wordWrapColumn: WordWrapColumn,
|
|
132
|
+
lspEnabled: LSPEnabled,
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
@singleton({ contrib: [ConfigurationContribution, ApplicationContribution] })
|
|
136
|
+
export class CodeEditorSettings
|
|
137
|
+
implements ConfigurationContribution, ApplicationContribution, Disposable
|
|
138
|
+
{
|
|
139
|
+
protected readonly configurationService: ConfigurationService;
|
|
140
|
+
|
|
141
|
+
protected codeEditorSettingsChangeEmitter = new Emitter<{
|
|
142
|
+
key: keyof IEditorConfig;
|
|
143
|
+
value: any;
|
|
144
|
+
}>();
|
|
145
|
+
|
|
146
|
+
onCodeEditorSettingsChange = this.codeEditorSettingsChangeEmitter.event;
|
|
147
|
+
|
|
148
|
+
protected toDispose = new DisposableCollection();
|
|
149
|
+
|
|
150
|
+
protected useSettings: Partial<IEditorConfig> | undefined;
|
|
151
|
+
|
|
152
|
+
constructor(
|
|
153
|
+
@inject(ConfigurationService)
|
|
154
|
+
configurationService: ConfigurationService,
|
|
155
|
+
) {
|
|
156
|
+
this.configurationService = configurationService;
|
|
157
|
+
}
|
|
158
|
+
registerConfigurations() {
|
|
159
|
+
return [
|
|
160
|
+
FontSize,
|
|
161
|
+
TabSize,
|
|
162
|
+
InsertSpaces,
|
|
163
|
+
LineHeight,
|
|
164
|
+
LineWarp,
|
|
165
|
+
WordWrapColumn,
|
|
166
|
+
LSPEnabled,
|
|
167
|
+
];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async onStart() {
|
|
171
|
+
this.useSettings = await this.fetchUserEditorSettings();
|
|
172
|
+
this.handleEditorSettingsChange();
|
|
173
|
+
}
|
|
174
|
+
getUserEditorSettings(): Partial<IEditorConfig> | undefined {
|
|
175
|
+
return this.useSettings;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
protected async fetchUserEditorSettings(): Promise<Partial<IEditorConfig>> {
|
|
179
|
+
const result: Partial<IEditorConfig> = {};
|
|
180
|
+
Object.typedKeys(CodeEditorSetting).forEach(async (key) => {
|
|
181
|
+
result[key] = await this.configurationService.get(CodeEditorSetting[key]!);
|
|
182
|
+
});
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
protected handleEditorSettingsChange() {
|
|
187
|
+
this.toDispose.push(
|
|
188
|
+
this.configurationService.onConfigurationValueChange((e) => {
|
|
189
|
+
// const ids = Object.values(CodeEditorSetting).map(item => item.id);
|
|
190
|
+
const match = Object.entries(CodeEditorSetting).find(
|
|
191
|
+
(item) => item[1].id === e.key,
|
|
192
|
+
);
|
|
193
|
+
if (match) {
|
|
194
|
+
this.codeEditorSettingsChangeEmitter.fire({
|
|
195
|
+
key: match[0] as any,
|
|
196
|
+
value: e.value,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}),
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
protected isDisposed = false;
|
|
204
|
+
get disposed() {
|
|
205
|
+
return this.isDisposed;
|
|
206
|
+
}
|
|
207
|
+
dispose() {
|
|
208
|
+
if (this.disposed) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
this.toDispose.dispose();
|
|
212
|
+
this.isDisposed = true;
|
|
213
|
+
}
|
|
214
|
+
}
|