@adecore/editor 0.41.1 → 0.43.0
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/dist/controller.d.ts +13 -2
- package/dist/controller.js +110 -9
- package/dist/editor.css +19 -0
- package/dist/engine.js +82 -5
- package/dist/fake.d.ts +31 -2
- package/dist/fake.js +100 -3
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/keymap-table.d.ts +28 -1
- package/dist/keymap-table.js +34 -3
- package/dist/keymap.js +23 -1
- package/dist/layout.d.ts +2 -0
- package/dist/layout.js +6 -1
- package/dist/outline.d.ts +1 -0
- package/dist/outline.js +10 -0
- package/dist/overview.d.ts +1 -1
- package/dist/paint.js +12 -2
- package/dist/todos.d.ts +23 -0
- package/dist/todos.js +86 -0
- package/dist/types.d.ts +34 -3
- package/dist/view.d.ts +17 -0
- package/dist/view.js +113 -12
- package/dist/zoom.d.ts +18 -0
- package/dist/zoom.js +41 -0
- package/package.json +2 -2
- package/src/controller.ts +150 -11
- package/src/editor.css +19 -0
- package/src/engine.ts +103 -5
- package/src/fake.ts +132 -3
- package/src/index.ts +7 -0
- package/src/keymap-table.ts +63 -4
- package/src/keymap.ts +23 -1
- package/src/layout.ts +9 -1
- package/src/outline.ts +13 -0
- package/src/overview.ts +1 -1
- package/src/paint.ts +11 -2
- package/src/todos.ts +111 -0
- package/src/types.ts +76 -4
- package/src/view.ts +143 -13
- package/src/zoom.ts +62 -0
package/dist/fake.js
CHANGED
|
@@ -148,6 +148,8 @@ export class FakeEditor {
|
|
|
148
148
|
this.readOnly = options.readOnly ?? false;
|
|
149
149
|
this.readOnlyReason = options.readOnlyReason;
|
|
150
150
|
this.label = options.label ?? 'Code editor';
|
|
151
|
+
this.todoWords = options.todoWords;
|
|
152
|
+
this.fontSize = options.fontSize ?? null;
|
|
151
153
|
this.revealedLine = options.line ?? null;
|
|
152
154
|
this.column = options.column ?? null;
|
|
153
155
|
this.scrollTop = options.scrollTop ?? null;
|
|
@@ -572,9 +574,66 @@ export class FakeEditor {
|
|
|
572
574
|
setLabel(label) {
|
|
573
575
|
this.label = label;
|
|
574
576
|
}
|
|
577
|
+
todoWords;
|
|
578
|
+
setTodoWords(words) {
|
|
579
|
+
this.todoWords = [...words];
|
|
580
|
+
}
|
|
575
581
|
setFoldHints(hints) {
|
|
576
582
|
this.foldHints = hints;
|
|
577
583
|
}
|
|
584
|
+
declarations = null;
|
|
585
|
+
setDeclarations(positions) {
|
|
586
|
+
this.declarations = positions;
|
|
587
|
+
}
|
|
588
|
+
navigations = new Set();
|
|
589
|
+
onNavigate(listener) {
|
|
590
|
+
return subscribe(this.navigations, listener);
|
|
591
|
+
}
|
|
592
|
+
/* Stands for a command that navigated: tells the listeners the caret left `from`. */
|
|
593
|
+
navigate(from) {
|
|
594
|
+
emit(this.navigations, from);
|
|
595
|
+
}
|
|
596
|
+
hasFocus() {
|
|
597
|
+
return this.focused;
|
|
598
|
+
}
|
|
599
|
+
copies = new Set();
|
|
600
|
+
onCopy(listener) {
|
|
601
|
+
return subscribe(this.copies, listener);
|
|
602
|
+
}
|
|
603
|
+
/* Stands for a copy or cut of a person: tells the listeners what went on the clipboard. */
|
|
604
|
+
copy(text, wholeLines = false, cut = false) {
|
|
605
|
+
emit(this.copies, { text, wholeLines, cut });
|
|
606
|
+
}
|
|
607
|
+
/* Every paste a host asked for, with its options. */
|
|
608
|
+
pastes = [];
|
|
609
|
+
/* Puts the text at every caret, one line per caret when the lines are as many as the carets, and leaves the carets behind it. */
|
|
610
|
+
paste(text, options) {
|
|
611
|
+
this.assertLive();
|
|
612
|
+
this.pastes.push({ text, options });
|
|
613
|
+
if (this.readOnly || text === '') {
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
const lines = text.split('\n');
|
|
617
|
+
const selections = [...this.selections].sort((left, right) => Math.min(left.anchor, left.head) - Math.min(right.anchor, right.head));
|
|
618
|
+
const perCaret = lines.length === selections.length;
|
|
619
|
+
const edits = selections.map((selection, index) => ({
|
|
620
|
+
from: Math.min(selection.anchor, selection.head),
|
|
621
|
+
to: Math.max(selection.anchor, selection.head),
|
|
622
|
+
text: perCaret ? lines[index] : text
|
|
623
|
+
}));
|
|
624
|
+
return this.edit(edits, 'command', false, () => {
|
|
625
|
+
let shift = 0;
|
|
626
|
+
return edits.map((edit) => {
|
|
627
|
+
const caret = edit.from + shift + edit.text.length;
|
|
628
|
+
shift += edit.text.length - (edit.to - edit.from);
|
|
629
|
+
return { anchor: caret, head: caret };
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
wordSources = null;
|
|
634
|
+
setWordSources(source) {
|
|
635
|
+
this.wordSources = source;
|
|
636
|
+
}
|
|
578
637
|
setSmartKeys(keys) {
|
|
579
638
|
this.smartKeys = keys;
|
|
580
639
|
}
|
|
@@ -595,10 +654,17 @@ export class FakeEditor {
|
|
|
595
654
|
setMarkers(markers) {
|
|
596
655
|
this.markers = markers;
|
|
597
656
|
}
|
|
598
|
-
/* What the host drew as hints last. */
|
|
657
|
+
/* What the host drew as hints last, every owner's together. */
|
|
599
658
|
inlayHints = [];
|
|
600
|
-
|
|
601
|
-
|
|
659
|
+
inlayOwners = new Map();
|
|
660
|
+
setInlayHints(hints, owner = 'default') {
|
|
661
|
+
if (hints.length === 0) {
|
|
662
|
+
this.inlayOwners.delete(owner);
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
this.inlayOwners.set(owner, hints);
|
|
666
|
+
}
|
|
667
|
+
this.inlayHints = [...this.inlayOwners.values()].flat();
|
|
602
668
|
}
|
|
603
669
|
inlayHovers = new Set();
|
|
604
670
|
inlayHandlers = new Set();
|
|
@@ -810,12 +876,41 @@ export class FakeEditor {
|
|
|
810
876
|
}));
|
|
811
877
|
return this.edit(ordered, 'command', options.mergeUndo === true, place);
|
|
812
878
|
}
|
|
879
|
+
/* The options of every cleanup asked for, in order; the fake changes no text for them. */
|
|
880
|
+
cleanups = [];
|
|
881
|
+
/* How often the text was marked as saved, by a cleanup or on its own. */
|
|
882
|
+
savedMarks = 0;
|
|
883
|
+
cleanUpWhitespace(options) {
|
|
884
|
+
this.cleanups.push({ ...options });
|
|
885
|
+
this.markSaved();
|
|
886
|
+
return false;
|
|
887
|
+
}
|
|
888
|
+
markSaved() {
|
|
889
|
+
this.savedMarks += 1;
|
|
890
|
+
}
|
|
813
891
|
setTheme(theme) {
|
|
814
892
|
this.theme = theme;
|
|
815
893
|
}
|
|
816
894
|
refreshFont() {
|
|
817
895
|
this.fontRefreshes += 1;
|
|
818
896
|
}
|
|
897
|
+
/* The size `setFontSize` set, null for the page's. */
|
|
898
|
+
fontSize = null;
|
|
899
|
+
fontSizeListeners = new Set();
|
|
900
|
+
setFontSize(size) {
|
|
901
|
+
this.fontSize = size;
|
|
902
|
+
}
|
|
903
|
+
getFontSize() {
|
|
904
|
+
return this.fontSize ?? 13;
|
|
905
|
+
}
|
|
906
|
+
onFontSizeChange(listener) {
|
|
907
|
+
return subscribe(this.fontSizeListeners, listener);
|
|
908
|
+
}
|
|
909
|
+
/* What a person zooming would do: the new size goes to the listeners. */
|
|
910
|
+
zoomTo(size) {
|
|
911
|
+
this.fontSize = size;
|
|
912
|
+
emit(this.fontSizeListeners, size);
|
|
913
|
+
}
|
|
819
914
|
setReadOnly(readOnly, reason) {
|
|
820
915
|
this.readOnly = readOnly;
|
|
821
916
|
this.readOnlyReason = reason;
|
|
@@ -837,6 +932,8 @@ export class FakeEditor {
|
|
|
837
932
|
this.changes.clear();
|
|
838
933
|
this.textChanges.clear();
|
|
839
934
|
this.carets.clear();
|
|
935
|
+
this.navigations.clear();
|
|
936
|
+
this.copies.clear();
|
|
840
937
|
this.hovers.clear();
|
|
841
938
|
this.inlayHovers.clear();
|
|
842
939
|
this.inlayHandlers.clear();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export { MAX_REPLACEMENT_PAGE, MAX_REPLACEMENT_CHARACTERS } from './search-protocol.ts';
|
|
2
2
|
export { AGENT_COLORS } from './attribution.ts';
|
|
3
3
|
export { findDocComments, MAX_DOC_COMMENTS, type DocComment } from '@adecore/editor-core';
|
|
4
|
+
export { DEFAULT_TODO_WORDS, findTodos, type TodoMatch, type TodoOptions } from '@adecore/editor-core';
|
|
5
|
+
export { detectIndentation, type DetectedIndentation } from '@adecore/editor-core';
|
|
4
6
|
export { createSmartEditorEngine } from './engine.ts';
|
|
7
|
+
export { rememberCopy } from './controller.ts';
|
|
5
8
|
export { DEFAULT_SMART_KEYS } from './smart-keys.ts';
|
|
6
9
|
export { shikiScopeColors, shikiTokenizers } from './shiki.ts';
|
|
7
|
-
export type { Editor, EditorAttributionHover, EditorAttributionMark, EditorMarkColor, EditorBlock, EditorChangeKind, EditorChangeMark, EditorCodeVision, EditorCodeVisionEntry, EditorClick, EditorCodeBlockOptions, EditorClickHandler, EditorCommand, EditorContextMenu, EditorEngine, EditorFindQuery, EditorFoldHints, EditorFoldRangeHint, EditorFoldOutline, EditorFoldRange, EditorFoldSymbol, EditorFolds, EditorFindState, EditorReplaceOptions, EditorGutterAction, EditorGutterIcon, EditorGutterMarker, EditorReplacement, EditorIndentation, EditorContentChange, EditorHighlight, EditorHighlightKind, EditorHover, EditorGhostText, EditorInlayClick, EditorInlayClickHandler, EditorInlayHint, EditorInlayTarget, EditorKeyHandler, EditorLineAction, EditorLineHighlight, EditorMarker, EditorInputPopup, EditorMessages, EditorMarkerSeverity, EditorReveal, EditorRect, EditorSmartKeys, EditorOptions, EditorPosition, EditorRemoteCursor, EditorRange, EditorApplyEditsOptions, EditorTextChange, EditorTrackedRange, EditorRunCommand, EditorSelectionRanges, EditorTheme, EditorViewCommand, EditorWidget, FoldRole, KeyChord, LineToken, LineTokenKind, ScopeColorSource, ScopeColors, ScopeStyle, EditorSemanticToken, LineTokenizer, SmartEditorEngineOptions, TokenizedLine, TokenizerSource } from './types.ts';
|
|
10
|
+
export type { Editor, EditorAttributionHover, EditorAttributionMark, EditorMarkColor, EditorBlock, EditorChangeKind, EditorChangeMark, EditorCodeVision, EditorCodeVisionEntry, EditorClick, EditorCodeBlockOptions, EditorClickHandler, EditorCommand, EditorContextMenu, EditorEngine, EditorFindQuery, EditorFoldHints, EditorFoldRangeHint, EditorFoldOutline, EditorFoldRange, EditorFoldSymbol, EditorFolds, EditorFindState, EditorReplaceOptions, EditorGutterAction, EditorGutterIcon, EditorGutterMarker, EditorReplacement, EditorIndentation, EditorContentChange, EditorHighlight, EditorHighlightKind, EditorHover, EditorGhostText, EditorInlayClick, EditorInlayClickHandler, EditorInlayHint, EditorInlayTarget, EditorKeyHandler, EditorLineAction, EditorLineHighlight, EditorMarker, EditorInputPopup, EditorMessages, EditorMarkerSeverity, EditorReveal, EditorRect, EditorSmartKeys, EditorOptions, EditorPosition, EditorRemoteCursor, EditorRange, EditorApplyEditsOptions, EditorCopy, EditorPasteOptions, EditorTextChange, EditorTrackedRange, EditorRunCommand, EditorSelectionRanges, EditorTheme, EditorViewCommand, EditorWhitespaceCleanup, EditorWidget, EditorZoom, FoldRole, KeyChord, LineToken, LineTokenKind, ScopeColorSource, ScopeColors, ScopeStyle, EditorSemanticToken, LineTokenizer, SmartEditorEngineOptions, TokenizedLine, TokenizerSource } from './types.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { MAX_REPLACEMENT_PAGE, MAX_REPLACEMENT_CHARACTERS } from './search-protocol.js';
|
|
2
2
|
export { AGENT_COLORS } from './attribution.js';
|
|
3
3
|
export { findDocComments, MAX_DOC_COMMENTS } from '@adecore/editor-core';
|
|
4
|
+
export { DEFAULT_TODO_WORDS, findTodos } from '@adecore/editor-core';
|
|
5
|
+
export { detectIndentation } from '@adecore/editor-core';
|
|
4
6
|
export { createSmartEditorEngine } from './engine.js';
|
|
7
|
+
export { rememberCopy } from './controller.js';
|
|
5
8
|
export { DEFAULT_SMART_KEYS } from './smart-keys.js';
|
|
6
9
|
export { shikiScopeColors, shikiTokenizers } from './shiki.js';
|
package/dist/keymap-table.d.ts
CHANGED
|
@@ -18,17 +18,39 @@ export declare const KEYMAP: {
|
|
|
18
18
|
readonly deleteLine: KeyBinding;
|
|
19
19
|
readonly moveLineUp: KeyBinding;
|
|
20
20
|
readonly moveLineDown: KeyBinding;
|
|
21
|
+
readonly moveStatementUp: KeyBinding;
|
|
22
|
+
readonly moveStatementDown: KeyBinding;
|
|
21
23
|
readonly toggleLineComment: KeyBinding;
|
|
22
24
|
readonly toggleBlockComment: KeyBinding;
|
|
23
25
|
readonly joinLines: KeyBinding;
|
|
24
26
|
readonly startNewLine: KeyBinding;
|
|
27
|
+
readonly completeCurrentStatement: KeyBinding;
|
|
28
|
+
readonly hippieCompletion: KeyBinding;
|
|
29
|
+
readonly hippieBackwardCompletion: KeyBinding;
|
|
25
30
|
readonly startNewLineBefore: KeyBinding;
|
|
26
31
|
readonly splitLine: KeyBinding;
|
|
27
32
|
readonly toggleCase: KeyBinding;
|
|
28
33
|
readonly autoIndentLines: KeyBinding;
|
|
34
|
+
readonly sortLines: KeyBinding;
|
|
35
|
+
readonly reverseLines: KeyBinding;
|
|
36
|
+
readonly uniqueLines: KeyBinding;
|
|
37
|
+
readonly convertIndentsToSpaces: KeyBinding;
|
|
38
|
+
readonly convertIndentsToTabs: KeyBinding;
|
|
29
39
|
readonly expandSelection: KeyBinding;
|
|
30
40
|
readonly shrinkSelection: KeyBinding;
|
|
31
41
|
readonly matchBrace: KeyBinding;
|
|
42
|
+
readonly methodUp: KeyBinding;
|
|
43
|
+
readonly methodDown: KeyBinding;
|
|
44
|
+
readonly lastEditLocation: KeyBinding;
|
|
45
|
+
readonly nextEditLocation: KeyBinding;
|
|
46
|
+
readonly pasteFromHistory: KeyBinding;
|
|
47
|
+
readonly pasteAsPlainText: KeyBinding;
|
|
48
|
+
readonly nextChange: KeyBinding;
|
|
49
|
+
readonly previousChange: KeyBinding;
|
|
50
|
+
readonly codeBlockStart: KeyBinding;
|
|
51
|
+
readonly codeBlockEnd: KeyBinding;
|
|
52
|
+
readonly codeBlockStartWithSelection: KeyBinding;
|
|
53
|
+
readonly codeBlockEndWithSelection: KeyBinding;
|
|
32
54
|
readonly selectNextOccurrence: KeyBinding;
|
|
33
55
|
readonly unselectOccurrence: KeyBinding;
|
|
34
56
|
readonly selectAllOccurrences: KeyBinding;
|
|
@@ -64,6 +86,9 @@ export declare const KEYMAP: {
|
|
|
64
86
|
readonly expandAllToLevel3: KeyBinding;
|
|
65
87
|
readonly expandAllToLevel4: KeyBinding;
|
|
66
88
|
readonly expandAllToLevel5: KeyBinding;
|
|
89
|
+
readonly increaseFontSize: KeyBinding;
|
|
90
|
+
readonly decreaseFontSize: KeyBinding;
|
|
91
|
+
readonly resetFontSize: KeyBinding;
|
|
67
92
|
readonly triggerCompletion: KeyBinding;
|
|
68
93
|
readonly parameterInfo: KeyBinding;
|
|
69
94
|
readonly quickInfo: KeyBinding;
|
|
@@ -72,6 +97,7 @@ export declare const KEYMAP: {
|
|
|
72
97
|
readonly renameSymbol: KeyBinding;
|
|
73
98
|
readonly organizeImports: KeyBinding;
|
|
74
99
|
readonly formatDocument: KeyBinding;
|
|
100
|
+
readonly wrapWithAbbreviation: KeyBinding;
|
|
75
101
|
readonly selectionToChat: KeyBinding;
|
|
76
102
|
readonly inlineEdit: KeyBinding;
|
|
77
103
|
readonly suggestInline: KeyBinding;
|
|
@@ -83,6 +109,7 @@ export declare const KEYMAP: {
|
|
|
83
109
|
readonly peekDefinition: KeyBinding;
|
|
84
110
|
readonly peekReferences: KeyBinding;
|
|
85
111
|
readonly callHierarchy: KeyBinding;
|
|
112
|
+
readonly typeHierarchy: KeyBinding;
|
|
86
113
|
readonly toggleRenderedDocs: KeyBinding;
|
|
87
114
|
readonly historyBack: KeyBinding;
|
|
88
115
|
readonly historyForward: KeyBinding;
|
|
@@ -96,7 +123,7 @@ export declare const KEYMAP: {
|
|
|
96
123
|
readonly replace: KeyBinding;
|
|
97
124
|
};
|
|
98
125
|
export type KeymapId = keyof typeof KEYMAP;
|
|
99
|
-
export type OptionalKeymapId = 'toggleRenderedDocs';
|
|
126
|
+
export type OptionalKeymapId = 'toggleRenderedDocs' | 'increaseFontSize' | 'decreaseFontSize' | 'resetFontSize' | 'sortLines' | 'reverseLines' | 'uniqueLines' | 'convertIndentsToSpaces' | 'convertIndentsToTabs' | 'completeCurrentStatement' | 'hippieCompletion' | 'hippieBackwardCompletion' | 'moveStatementUp' | 'moveStatementDown' | 'lastEditLocation' | 'nextEditLocation' | 'methodUp' | 'methodDown' | 'pasteFromHistory' | 'pasteAsPlainText' | 'nextChange' | 'previousChange' | 'codeBlockStart' | 'codeBlockEnd' | 'codeBlockStartWithSelection' | 'codeBlockEndWithSelection' | 'wrapWithAbbreviation' | 'typeHierarchy';
|
|
100
127
|
export type Keymap = Readonly<Record<Exclude<KeymapId, OptionalKeymapId>, KeyBinding> & Partial<Record<OptionalKeymapId, KeyBinding>>>;
|
|
101
128
|
export type KeymapOverrides = Partial<Record<KeymapId, Partial<KeyBinding>>>;
|
|
102
129
|
export declare const KEYMAP_IDS: KeymapId[];
|
package/dist/keymap-table.js
CHANGED
|
@@ -15,17 +15,41 @@ export const KEYMAP = {
|
|
|
15
15
|
deleteLine: bind('Mod+Backspace', 'Mod+Y'),
|
|
16
16
|
moveLineUp: bind('Alt+Shift+ArrowUp'),
|
|
17
17
|
moveLineDown: bind('Alt+Shift+ArrowDown'),
|
|
18
|
+
moveStatementUp: bind('Mod+Shift+ArrowUp'),
|
|
19
|
+
moveStatementDown: bind('Mod+Shift+ArrowDown'),
|
|
18
20
|
toggleLineComment: bind('Mod+/'),
|
|
19
21
|
toggleBlockComment: bind('Mod+Alt+/', 'Mod+Shift+/'),
|
|
20
22
|
joinLines: bind('Ctrl+Shift+J'),
|
|
21
23
|
startNewLine: bind('Shift+Enter'),
|
|
24
|
+
completeCurrentStatement: bind('Mod+Shift+Enter'),
|
|
25
|
+
hippieCompletion: bind('Alt+/'),
|
|
26
|
+
hippieBackwardCompletion: bind('Alt+Shift+/'),
|
|
22
27
|
startNewLineBefore: bind('Mod+Alt+Enter'),
|
|
23
28
|
splitLine: bind('Mod+Enter'),
|
|
24
29
|
toggleCase: bind('Mod+Shift+U'),
|
|
25
30
|
autoIndentLines: bind('Ctrl+Alt+I'),
|
|
31
|
+
// The platform binds no chord to these, so they live in the menu and the palette.
|
|
32
|
+
sortLines: bind(null),
|
|
33
|
+
reverseLines: bind(null),
|
|
34
|
+
uniqueLines: bind(null),
|
|
35
|
+
convertIndentsToSpaces: bind(null),
|
|
36
|
+
convertIndentsToTabs: bind(null),
|
|
26
37
|
expandSelection: bind('Alt+ArrowUp', 'Ctrl+W'),
|
|
27
|
-
|
|
38
|
+
// Off macOS Alt+ArrowDown is Next Method, as in IntelliJ, so Shrink Selection takes its own chord there.
|
|
39
|
+
shrinkSelection: bind('Alt+ArrowDown', 'Ctrl+Shift+W'),
|
|
28
40
|
matchBrace: bind('Ctrl+M', 'Ctrl+Shift+M'),
|
|
41
|
+
methodUp: bind('Ctrl+Shift+ArrowUp', 'Alt+ArrowUp'),
|
|
42
|
+
methodDown: bind('Ctrl+Shift+ArrowDown', 'Alt+ArrowDown'),
|
|
43
|
+
lastEditLocation: bind('Mod+Shift+Backspace'),
|
|
44
|
+
nextEditLocation: bind(null),
|
|
45
|
+
pasteFromHistory: bind('Mod+Shift+V'),
|
|
46
|
+
pasteAsPlainText: bind('Mod+Alt+Shift+V'),
|
|
47
|
+
nextChange: bind('Ctrl+Alt+Shift+ArrowDown'),
|
|
48
|
+
previousChange: bind('Ctrl+Alt+Shift+ArrowUp'),
|
|
49
|
+
codeBlockStart: bind('Mod+Alt+[', 'Ctrl+['),
|
|
50
|
+
codeBlockEnd: bind('Mod+Alt+]', 'Ctrl+]'),
|
|
51
|
+
codeBlockStartWithSelection: bind('Mod+Alt+Shift+[', 'Ctrl+Shift+['),
|
|
52
|
+
codeBlockEndWithSelection: bind('Mod+Alt+Shift+]', 'Ctrl+Shift+]'),
|
|
29
53
|
selectNextOccurrence: bind('Ctrl+G', 'Alt+J'),
|
|
30
54
|
unselectOccurrence: bind('Ctrl+Shift+G', 'Alt+Shift+J'),
|
|
31
55
|
selectAllOccurrences: bind('Meta+Ctrl+G', 'Ctrl+Alt+Shift+J'),
|
|
@@ -45,9 +69,10 @@ export const KEYMAP = {
|
|
|
45
69
|
smartEnd: bind('Meta+ArrowRight', null),
|
|
46
70
|
selectSmartEnd: bind('Meta+Shift+ArrowRight', null),
|
|
47
71
|
textStart: bind('Meta+ArrowUp', null),
|
|
48
|
-
|
|
72
|
+
// IntelliJ binds Cmd+Shift+ArrowUp and ArrowDown to Move Statement on macOS, where Cmd+Shift+Home and End still select to the text edges.
|
|
73
|
+
selectTextStart: bind(null),
|
|
49
74
|
textEnd: bind('Meta+ArrowDown', null),
|
|
50
|
-
selectTextEnd: bind(
|
|
75
|
+
selectTextEnd: bind(null),
|
|
51
76
|
collapse: bind('Mod+-'),
|
|
52
77
|
expand: bind('Mod+='),
|
|
53
78
|
collapseAll: bind('Mod+Shift+-'),
|
|
@@ -63,6 +88,10 @@ export const KEYMAP = {
|
|
|
63
88
|
expandAllToLevel3: bind(null),
|
|
64
89
|
expandAllToLevel4: bind(null),
|
|
65
90
|
expandAllToLevel5: bind(null),
|
|
91
|
+
// The platform binds no chord to these, and the zoom chords of other editors are the fold keys here.
|
|
92
|
+
increaseFontSize: bind(null),
|
|
93
|
+
decreaseFontSize: bind(null),
|
|
94
|
+
resetFontSize: bind(null),
|
|
66
95
|
triggerCompletion: bind('Ctrl+Space'),
|
|
67
96
|
parameterInfo: bind('Mod+P'),
|
|
68
97
|
quickInfo: bind('Ctrl+J', 'Ctrl+Q'),
|
|
@@ -71,6 +100,7 @@ export const KEYMAP = {
|
|
|
71
100
|
renameSymbol: bind('Shift+F6'),
|
|
72
101
|
organizeImports: bind('Ctrl+Alt+O'),
|
|
73
102
|
formatDocument: bind('Mod+Alt+L'),
|
|
103
|
+
wrapWithAbbreviation: bind('Mod+Alt+J'),
|
|
74
104
|
selectionToChat: bind(null),
|
|
75
105
|
inlineEdit: bind(null),
|
|
76
106
|
suggestInline: bind(null),
|
|
@@ -82,6 +112,7 @@ export const KEYMAP = {
|
|
|
82
112
|
peekDefinition: bind('Alt+Space', 'Ctrl+Shift+I'),
|
|
83
113
|
peekReferences: bind('Alt+F7'),
|
|
84
114
|
callHierarchy: bind('Ctrl+Alt+H'),
|
|
115
|
+
typeHierarchy: bind('Ctrl+H'),
|
|
85
116
|
toggleRenderedDocs: bind('Ctrl+Alt+Q'),
|
|
86
117
|
historyBack: bind('Mod+[', 'Ctrl+Alt+ArrowLeft'),
|
|
87
118
|
historyForward: bind('Mod+]', 'Ctrl+Alt+ArrowRight'),
|
package/dist/keymap.js
CHANGED
|
@@ -16,17 +16,36 @@ const ACTIONS = {
|
|
|
16
16
|
deleteLine: command('deleteLine'),
|
|
17
17
|
moveLineUp: command('moveLineUp'),
|
|
18
18
|
moveLineDown: command('moveLineDown'),
|
|
19
|
+
moveStatementUp: command('moveStatementUp'),
|
|
20
|
+
moveStatementDown: command('moveStatementDown'),
|
|
19
21
|
toggleLineComment: command('toggleLineComment'),
|
|
20
22
|
toggleBlockComment: command('toggleBlockComment'),
|
|
21
23
|
joinLines: command('joinLines'),
|
|
22
24
|
startNewLine: command('startNewLine'),
|
|
25
|
+
completeCurrentStatement: command('completeCurrentStatement'),
|
|
26
|
+
hippieCompletion: command('hippieCompletion'),
|
|
27
|
+
hippieBackwardCompletion: command('hippieBackwardCompletion'),
|
|
23
28
|
startNewLineBefore: command('startNewLineBefore'),
|
|
24
29
|
splitLine: command('splitLine'),
|
|
25
30
|
toggleCase: command('toggleCase'),
|
|
26
31
|
autoIndentLines: command('autoIndentLines'),
|
|
32
|
+
sortLines: command('sortLines'),
|
|
33
|
+
reverseLines: command('reverseLines'),
|
|
34
|
+
uniqueLines: command('uniqueLines'),
|
|
35
|
+
convertIndentsToSpaces: command('convertIndentsToSpaces'),
|
|
36
|
+
convertIndentsToTabs: command('convertIndentsToTabs'),
|
|
27
37
|
expandSelection: command('expandSelection'),
|
|
28
38
|
shrinkSelection: command('shrinkSelection'),
|
|
29
39
|
matchBrace: { type: 'bracket' },
|
|
40
|
+
methodUp: view('methodUp'),
|
|
41
|
+
methodDown: view('methodDown'),
|
|
42
|
+
pasteAsPlainText: view('pasteAsPlainText'),
|
|
43
|
+
nextChange: view('nextChange'),
|
|
44
|
+
previousChange: view('previousChange'),
|
|
45
|
+
codeBlockStart: command('codeBlockStart'),
|
|
46
|
+
codeBlockEnd: command('codeBlockEnd'),
|
|
47
|
+
codeBlockStartWithSelection: command('codeBlockStartWithSelection'),
|
|
48
|
+
codeBlockEndWithSelection: command('codeBlockEndWithSelection'),
|
|
30
49
|
selectNextOccurrence: command('selectNextOccurrence'),
|
|
31
50
|
unselectOccurrence: command('unselectOccurrence'),
|
|
32
51
|
selectAllOccurrences: command('selectAllOccurrences'),
|
|
@@ -59,7 +78,10 @@ const ACTIONS = {
|
|
|
59
78
|
expandAllToLevel3: view('expandAllToLevel3'),
|
|
60
79
|
expandAllToLevel4: view('expandAllToLevel4'),
|
|
61
80
|
expandAllToLevel5: view('expandAllToLevel5'),
|
|
62
|
-
toggleColumnMode: view('toggleColumnMode')
|
|
81
|
+
toggleColumnMode: view('toggleColumnMode'),
|
|
82
|
+
increaseFontSize: view('increaseFontSize'),
|
|
83
|
+
decreaseFontSize: view('decreaseFontSize'),
|
|
84
|
+
resetFontSize: view('resetFontSize')
|
|
63
85
|
};
|
|
64
86
|
const PUNCTUATION_CODES = {
|
|
65
87
|
',': 'Comma',
|
package/dist/layout.d.ts
CHANGED
package/dist/layout.js
CHANGED
|
@@ -11,6 +11,8 @@ export function subRowBand(top, subRows, lineHeight, window, block = 1) {
|
|
|
11
11
|
last: Math.min(subRows - 1, Math.ceil((last + 1) / block) * block - 1)
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
+
/* The side of a swatch in pixels, without its gaps. */
|
|
15
|
+
export const SWATCH_SIZE = 12;
|
|
14
16
|
export const TEXT_PADDING = 0;
|
|
15
17
|
export const BOTTOM_PADDING = 8;
|
|
16
18
|
export const RIGHT_PADDING = 16;
|
|
@@ -154,9 +156,12 @@ export function scanDenseLine(line, metrics, limit, lineInlays) {
|
|
|
154
156
|
flushRun(offset);
|
|
155
157
|
const inlay = lineInlays[nextInlay++];
|
|
156
158
|
const shown = visibleBidi(inlay.text);
|
|
159
|
+
const gaps = (inlay.gapLeft ?? 0) + (inlay.gapRight ?? 0);
|
|
157
160
|
const width = inlay.composition || inlay.ghost
|
|
158
161
|
? metrics.measureText(shown)
|
|
159
|
-
:
|
|
162
|
+
: inlay.swatch !== undefined
|
|
163
|
+
? SWATCH_SIZE + gaps
|
|
164
|
+
: Math.max(8, metrics.measureInlay(shown) + 12) + gaps;
|
|
160
165
|
geometry.inlays.push({ inlay, x, width, subRow: row });
|
|
161
166
|
x += width;
|
|
162
167
|
}
|
package/dist/outline.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export declare class Outline {
|
|
|
37
37
|
setStructure(entries: OutlineEntry[]): void;
|
|
38
38
|
setProvided(blocks: readonly EditorBlock[] | null, document: OutlineDocument): void;
|
|
39
39
|
edited(batches: readonly (readonly DocumentChange[])[]): void;
|
|
40
|
+
declarationStops(document: OutlineDocument): number[];
|
|
40
41
|
blocks(document: OutlineDocument): readonly OutlineBlock[];
|
|
41
42
|
}
|
|
42
43
|
export interface StickyRows {
|
package/dist/outline.js
CHANGED
|
@@ -140,6 +140,16 @@ export class Outline {
|
|
|
140
140
|
this.provided = this.provided === null ? null : move(this.provided);
|
|
141
141
|
this.version++;
|
|
142
142
|
}
|
|
143
|
+
/* Where the named blocks of the structure declare their name, in no order: the stops of Method Up and Down. */
|
|
144
|
+
declarationStops(document) {
|
|
145
|
+
return this.structure.flatMap((entry) => {
|
|
146
|
+
if (entry.name === undefined) {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
const header = document.getLine(document.positionAt(entry.from).line);
|
|
150
|
+
return [header.start + Math.max(0, header.text.indexOf(entry.name))];
|
|
151
|
+
});
|
|
152
|
+
}
|
|
143
153
|
/* Outermost first. Of two blocks that start on one line, only the larger one. */
|
|
144
154
|
blocks(document) {
|
|
145
155
|
if (this.cache?.version !== this.version) {
|
package/dist/overview.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type OverviewKind = 'added' | 'modified' | 'deleted' | 'find' | 'find-current' | 'occurrence' | 'info' | 'warning' | 'error';
|
|
1
|
+
export type OverviewKind = 'added' | 'modified' | 'deleted' | 'find' | 'find-current' | 'occurrence' | 'todo' | 'info' | 'warning' | 'error';
|
|
2
2
|
export interface OverviewSpan {
|
|
3
3
|
kind: OverviewKind;
|
|
4
4
|
top: number;
|
package/dist/paint.js
CHANGED
|
@@ -102,10 +102,20 @@ export function lineElement(document, geometry, tokens, lineHeight, band, whites
|
|
|
102
102
|
continue;
|
|
103
103
|
}
|
|
104
104
|
const span = document.createElement('span');
|
|
105
|
-
span.className = box.inlay.ghost
|
|
105
|
+
span.className = box.inlay.ghost
|
|
106
|
+
? 'se-ghost'
|
|
107
|
+
: box.inlay.composition
|
|
108
|
+
? 'se-composition'
|
|
109
|
+
: box.inlay.swatch !== undefined
|
|
110
|
+
? 'se-inlay se-swatch'
|
|
111
|
+
: 'se-inlay';
|
|
106
112
|
span.dataset.inlayId = box.inlay.id;
|
|
107
113
|
const { parts } = box.inlay;
|
|
108
|
-
if (
|
|
114
|
+
if (box.inlay.swatch !== undefined) {
|
|
115
|
+
span.style.backgroundColor = box.inlay.swatch;
|
|
116
|
+
span.setAttribute('aria-label', box.inlay.text);
|
|
117
|
+
}
|
|
118
|
+
else if (parts === undefined) {
|
|
109
119
|
span.textContent = visibleBidi(box.inlay.text);
|
|
110
120
|
}
|
|
111
121
|
else {
|
package/dist/todos.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DocumentModel, type TodoMatch } from '@adecore/editor-core';
|
|
2
|
+
import type { LineToken } from './types.ts';
|
|
3
|
+
export type TodoMark = TodoMatch & {
|
|
4
|
+
readonly text: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class TodoMarks {
|
|
7
|
+
private readonly model;
|
|
8
|
+
private readonly changed;
|
|
9
|
+
private words;
|
|
10
|
+
private language;
|
|
11
|
+
private revision;
|
|
12
|
+
private readonly lines;
|
|
13
|
+
private timer;
|
|
14
|
+
private all;
|
|
15
|
+
version: number;
|
|
16
|
+
constructor(model: DocumentModel, changed: () => void);
|
|
17
|
+
get marks(): readonly TodoMark[];
|
|
18
|
+
configure(language: string | undefined, words: readonly string[] | undefined): void;
|
|
19
|
+
styled(line: number, base: readonly LineToken[] | null): readonly LineToken[] | null;
|
|
20
|
+
schedule(): void;
|
|
21
|
+
refresh(): void;
|
|
22
|
+
dispose(): void;
|
|
23
|
+
}
|
package/dist/todos.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DEFAULT_TODO_WORDS } from '@adecore/editor-core';
|
|
2
|
+
import { overlayTokens } from './semantic.js';
|
|
3
|
+
const TODO_COLOR = 'var(--editor-todo)';
|
|
4
|
+
const ITALIC = 1;
|
|
5
|
+
/* The marks in the scroll track read the whole document, so they wait for a pause in editing as the folds do. */
|
|
6
|
+
const TODO_DELAY_MS = 300;
|
|
7
|
+
const TODO_LIMIT = 2_000_000;
|
|
8
|
+
const CACHED_LINES = 600;
|
|
9
|
+
/*
|
|
10
|
+
* The TODO comments of a view: drawn in their own color over the grammar's on the lines being painted,
|
|
11
|
+
* and listed for the whole document a moment after the last edit, for the ticks in the scroll track.
|
|
12
|
+
*/
|
|
13
|
+
export class TodoMarks {
|
|
14
|
+
model;
|
|
15
|
+
changed;
|
|
16
|
+
words = DEFAULT_TODO_WORDS;
|
|
17
|
+
/* Empty until the first `configure`, which reads the document. */
|
|
18
|
+
language = '';
|
|
19
|
+
revision = -1;
|
|
20
|
+
lines = new Map();
|
|
21
|
+
timer;
|
|
22
|
+
all = [];
|
|
23
|
+
/* Counts every new list, so a painter can tell its ticks are stale. */
|
|
24
|
+
version = 0;
|
|
25
|
+
constructor(model, changed) {
|
|
26
|
+
this.model = model;
|
|
27
|
+
this.changed = changed;
|
|
28
|
+
}
|
|
29
|
+
get marks() {
|
|
30
|
+
return this.all;
|
|
31
|
+
}
|
|
32
|
+
configure(language, words) {
|
|
33
|
+
const nextLanguage = language ?? 'plaintext';
|
|
34
|
+
const nextWords = words ?? DEFAULT_TODO_WORDS;
|
|
35
|
+
if (nextLanguage === this.language && nextWords.join('\n') === this.words.join('\n')) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.language = nextLanguage;
|
|
39
|
+
this.words = nextWords;
|
|
40
|
+
this.revision = -1;
|
|
41
|
+
this.refresh();
|
|
42
|
+
}
|
|
43
|
+
/* The line's tokens with its TODOs drawn over them, the same array for as long as neither changed. */
|
|
44
|
+
styled(line, base) {
|
|
45
|
+
if (this.words.length === 0) {
|
|
46
|
+
return base;
|
|
47
|
+
}
|
|
48
|
+
const revision = this.model.getRevision();
|
|
49
|
+
if (revision !== this.revision || this.lines.size > CACHED_LINES) {
|
|
50
|
+
this.revision = revision;
|
|
51
|
+
this.lines.clear();
|
|
52
|
+
}
|
|
53
|
+
const cached = this.lines.get(line);
|
|
54
|
+
if (cached !== undefined && cached.base === base) {
|
|
55
|
+
return cached.result;
|
|
56
|
+
}
|
|
57
|
+
const matches = this.model.findTodos(this.language, { words: this.words }, line, line);
|
|
58
|
+
let result = base;
|
|
59
|
+
if (matches.length > 0) {
|
|
60
|
+
const { start, end } = this.model.getLine(line);
|
|
61
|
+
const spans = matches.map((match) => ({ from: match.from - start, to: match.to - start, color: TODO_COLOR, fontStyle: ITALIC }));
|
|
62
|
+
result = overlayTokens(base ?? [{ length: end - start, color: '', fontStyle: 0 }], spans);
|
|
63
|
+
}
|
|
64
|
+
this.lines.set(line, { base, result });
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
schedule() {
|
|
68
|
+
clearTimeout(this.timer);
|
|
69
|
+
this.timer = setTimeout(() => this.refresh(), TODO_DELAY_MS);
|
|
70
|
+
}
|
|
71
|
+
/* Reads the TODOs of the whole document now, which otherwise waits for a pause in editing. */
|
|
72
|
+
refresh() {
|
|
73
|
+
clearTimeout(this.timer);
|
|
74
|
+
const found = this.words.length === 0 || this.model.getLength() > TODO_LIMIT ? [] : this.model.findTodos(this.language, { words: this.words });
|
|
75
|
+
const next = found.map((match) => ({ ...match, text: this.model.slice(match.from, match.to) }));
|
|
76
|
+
if (next.length === 0 && this.all.length === 0) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.all = next;
|
|
80
|
+
this.version++;
|
|
81
|
+
this.changed();
|
|
82
|
+
}
|
|
83
|
+
dispose() {
|
|
84
|
+
clearTimeout(this.timer);
|
|
85
|
+
}
|
|
86
|
+
}
|