@adecore/editor 0.43.0 → 0.44.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/engine.js +14 -0
- package/dist/fake.d.ts +5 -1
- package/dist/fake.js +15 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/keymap-table.d.ts +6 -1
- package/dist/keymap-table.js +7 -1
- package/dist/text-queries.d.ts +10 -0
- package/dist/text-queries.js +24 -0
- package/dist/types.d.ts +23 -1
- package/package.json +2 -2
- package/src/engine.ts +23 -0
- package/src/fake.ts +24 -1
- package/src/index.ts +5 -0
- package/src/keymap-table.ts +12 -1
- package/src/text-queries.ts +45 -0
- package/src/types.ts +40 -1
package/dist/engine.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { changedSpans, DocumentModel, replacementText } from '@adecore/editor-core';
|
|
2
2
|
import { MAX_REPLACEMENT_CHARACTERS } from './search-protocol.js';
|
|
3
|
+
import { placeAt, postfixOperands, surroundShape, unwrapTargets } from './text-queries.js';
|
|
3
4
|
import { GrammarPreparation } from './grammar-preparation.js';
|
|
4
5
|
import { InputController } from './controller.js';
|
|
5
6
|
import { resolveSmartKeys } from './smart-keys.js';
|
|
@@ -784,6 +785,19 @@ class SmartEditor {
|
|
|
784
785
|
isReadOnly() {
|
|
785
786
|
return this.settings.readOnly;
|
|
786
787
|
}
|
|
788
|
+
placeAt(position) {
|
|
789
|
+
return placeAt(this.model, this, position, this.settings.language ?? 'plaintext');
|
|
790
|
+
}
|
|
791
|
+
postfixOperands(dot) {
|
|
792
|
+
return postfixOperands(this.model, this, dot, this.settings.language ?? 'plaintext');
|
|
793
|
+
}
|
|
794
|
+
surroundShape(range) {
|
|
795
|
+
return surroundShape(this.model, this, range, this.settings.language ?? 'plaintext');
|
|
796
|
+
}
|
|
797
|
+
unwrapTargets(position) {
|
|
798
|
+
const unit = this.settings.insertSpaces ? ' '.repeat(this.settings.tabSize) : '\t';
|
|
799
|
+
return unwrapTargets(this.model, this, position, this.settings.language ?? 'plaintext', unit);
|
|
800
|
+
}
|
|
787
801
|
runCommand(command) {
|
|
788
802
|
return this.controller.command(command);
|
|
789
803
|
}
|
package/dist/fake.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Editor, EditorAttributionHover, EditorAttributionMark, EditorBlock, EditorCodeBlockOptions, EditorLineAction, EditorReplacement, EditorLineHighlight, LineToken, EditorChangeMark, EditorCodeVision, EditorClick, EditorClickHandler, EditorContextMenu, EditorContentChange, EditorEngine, EditorFindQuery, EditorFindState, EditorReplaceOptions, EditorGutterAction, EditorGutterMarker, EditorHighlight, EditorHover, EditorIndentation, EditorGhostText, EditorInlayClick, EditorInlayClickHandler, EditorInlayHint, EditorInlayTarget, EditorKeyHandler, EditorInputPopup, EditorMarker, EditorMessages, EditorOptions, EditorPosition, EditorRemoteCursor, EditorRange, EditorReveal, EditorRect, EditorRunCommand, EditorSelectionRanges, EditorFoldHints, EditorFoldOutline, EditorFolds, EditorSemanticToken, EditorSmartKeys, EditorApplyEditsOptions, EditorCopy, EditorPasteOptions, EditorTextChange, EditorTrackedRange, EditorTheme, EditorWhitespaceCleanup, EditorWidget } from './types.ts';
|
|
1
|
+
import type { Editor, EditorAttributionHover, EditorAttributionMark, EditorBlock, EditorCodeBlockOptions, EditorLineAction, EditorReplacement, EditorLineHighlight, LineToken, EditorChangeMark, EditorCodeVision, EditorClick, EditorClickHandler, EditorContextMenu, EditorContentChange, EditorEngine, EditorFindQuery, EditorFindState, EditorReplaceOptions, EditorGutterAction, EditorGutterMarker, EditorHighlight, EditorHover, EditorIndentation, EditorGhostText, EditorInlayClick, EditorInlayClickHandler, EditorInlayHint, EditorInlayTarget, EditorKeyHandler, EditorInputPopup, EditorMarker, EditorMessages, EditorOptions, EditorPosition, EditorPostfixOperand, EditorSurroundShape, EditorTextPlace, EditorUnwrapTarget, EditorRemoteCursor, EditorRange, EditorReveal, EditorRect, EditorRunCommand, EditorSelectionRanges, EditorFoldHints, EditorFoldOutline, EditorFolds, EditorSemanticToken, EditorSmartKeys, EditorApplyEditsOptions, EditorCopy, EditorPasteOptions, EditorTextChange, EditorTrackedRange, EditorTheme, EditorWhitespaceCleanup, EditorWidget } from './types.ts';
|
|
2
2
|
import { type Listener } from './listeners.ts';
|
|
3
3
|
export declare class FakeEditor implements Editor {
|
|
4
4
|
readonly element: HTMLElement;
|
|
@@ -257,6 +257,10 @@ export declare class FakeEditor implements Editor {
|
|
|
257
257
|
zoomTo(size: number | null): void;
|
|
258
258
|
setReadOnly(readOnly: boolean, reason?: string): void;
|
|
259
259
|
isReadOnly(): boolean;
|
|
260
|
+
placeAt(position: EditorPosition): EditorTextPlace;
|
|
261
|
+
postfixOperands(dot: EditorPosition): readonly EditorPostfixOperand[];
|
|
262
|
+
surroundShape(range: EditorRange): EditorSurroundShape | null;
|
|
263
|
+
unwrapTargets(position: EditorPosition): readonly EditorUnwrapTarget[];
|
|
260
264
|
readonly commands: EditorRunCommand[];
|
|
261
265
|
runCommand(command: EditorRunCommand): boolean;
|
|
262
266
|
focus(): void;
|
package/dist/fake.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { emit, subscribe } from './listeners.js';
|
|
2
|
-
import { changedSpan, changedSpans } from '@adecore/editor-core';
|
|
2
|
+
import { changedSpan, changedSpans, DocumentModel } from '@adecore/editor-core';
|
|
3
|
+
import { placeAt, postfixOperands, surroundShape, unwrapTargets } from './text-queries.js';
|
|
3
4
|
import { mapTrackedRange } from './tracked-range.js';
|
|
4
5
|
const LINE_BREAK = /\r\n|\r|\n/g;
|
|
5
6
|
/* Where each line starts and where its text ends, before its line break: `\r\n`, a lone `\r` or `\n`, as the real document counts them. */
|
|
@@ -918,6 +919,19 @@ export class FakeEditor {
|
|
|
918
919
|
isReadOnly() {
|
|
919
920
|
return this.readOnly;
|
|
920
921
|
}
|
|
922
|
+
placeAt(position) {
|
|
923
|
+
return placeAt(new DocumentModel(this.text), this, position, this.language ?? 'plaintext');
|
|
924
|
+
}
|
|
925
|
+
postfixOperands(dot) {
|
|
926
|
+
return postfixOperands(new DocumentModel(this.text), this, dot, this.language ?? 'plaintext');
|
|
927
|
+
}
|
|
928
|
+
surroundShape(range) {
|
|
929
|
+
return surroundShape(new DocumentModel(this.text), this, range, this.language ?? 'plaintext');
|
|
930
|
+
}
|
|
931
|
+
unwrapTargets(position) {
|
|
932
|
+
const unit = this.indentation.insertSpaces ? ' '.repeat(this.indentation.tabSize) : '\t';
|
|
933
|
+
return unwrapTargets(new DocumentModel(this.text), this, position, this.language ?? 'plaintext', unit);
|
|
934
|
+
}
|
|
921
935
|
/* The commands run, in order; of its own the fake carries out only undo and redo. */
|
|
922
936
|
commands = [];
|
|
923
937
|
runCommand(command) {
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ export { AGENT_COLORS } from './attribution.ts';
|
|
|
3
3
|
export { findDocComments, MAX_DOC_COMMENTS, type DocComment } from '@adecore/editor-core';
|
|
4
4
|
export { DEFAULT_TODO_WORDS, findTodos, type TodoMatch, type TodoOptions } from '@adecore/editor-core';
|
|
5
5
|
export { detectIndentation, type DetectedIndentation } from '@adecore/editor-core';
|
|
6
|
+
export { commentSyntax, type CommentSyntax } from '@adecore/editor-core';
|
|
6
7
|
export { createSmartEditorEngine } from './engine.ts';
|
|
7
8
|
export { rememberCopy } from './controller.ts';
|
|
8
9
|
export { DEFAULT_SMART_KEYS } from './smart-keys.ts';
|
|
9
10
|
export { shikiScopeColors, shikiTokenizers } from './shiki.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';
|
|
11
|
+
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, EditorPostfixOperand, EditorSurroundShape, EditorTextPlace, EditorUnwrapTarget, 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
|
@@ -3,6 +3,7 @@ export { AGENT_COLORS } from './attribution.js';
|
|
|
3
3
|
export { findDocComments, MAX_DOC_COMMENTS } from '@adecore/editor-core';
|
|
4
4
|
export { DEFAULT_TODO_WORDS, findTodos } from '@adecore/editor-core';
|
|
5
5
|
export { detectIndentation } from '@adecore/editor-core';
|
|
6
|
+
export { commentSyntax } from '@adecore/editor-core';
|
|
6
7
|
export { createSmartEditorEngine } from './engine.js';
|
|
7
8
|
export { rememberCopy } from './controller.js';
|
|
8
9
|
export { DEFAULT_SMART_KEYS } from './smart-keys.js';
|
package/dist/keymap-table.d.ts
CHANGED
|
@@ -97,6 +97,11 @@ export declare const KEYMAP: {
|
|
|
97
97
|
readonly renameSymbol: KeyBinding;
|
|
98
98
|
readonly organizeImports: KeyBinding;
|
|
99
99
|
readonly formatDocument: KeyBinding;
|
|
100
|
+
readonly insertLiveTemplate: KeyBinding;
|
|
101
|
+
readonly surroundWith: KeyBinding;
|
|
102
|
+
readonly surroundWithLiveTemplate: KeyBinding;
|
|
103
|
+
readonly unwrap: KeyBinding;
|
|
104
|
+
readonly saveAsLiveTemplate: KeyBinding;
|
|
100
105
|
readonly wrapWithAbbreviation: KeyBinding;
|
|
101
106
|
readonly selectionToChat: KeyBinding;
|
|
102
107
|
readonly inlineEdit: KeyBinding;
|
|
@@ -123,7 +128,7 @@ export declare const KEYMAP: {
|
|
|
123
128
|
readonly replace: KeyBinding;
|
|
124
129
|
};
|
|
125
130
|
export type KeymapId = keyof typeof KEYMAP;
|
|
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';
|
|
131
|
+
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' | 'insertLiveTemplate' | 'surroundWith' | 'surroundWithLiveTemplate' | 'unwrap' | 'saveAsLiveTemplate' | 'typeHierarchy';
|
|
127
132
|
export type Keymap = Readonly<Record<Exclude<KeymapId, OptionalKeymapId>, KeyBinding> & Partial<Record<OptionalKeymapId, KeyBinding>>>;
|
|
128
133
|
export type KeymapOverrides = Partial<Record<KeymapId, Partial<KeyBinding>>>;
|
|
129
134
|
export declare const KEYMAP_IDS: KeymapId[];
|
package/dist/keymap-table.js
CHANGED
|
@@ -100,7 +100,13 @@ export const KEYMAP = {
|
|
|
100
100
|
renameSymbol: bind('Shift+F6'),
|
|
101
101
|
organizeImports: bind('Ctrl+Alt+O'),
|
|
102
102
|
formatDocument: bind('Mod+Alt+L'),
|
|
103
|
-
|
|
103
|
+
insertLiveTemplate: bind('Mod+J'),
|
|
104
|
+
surroundWith: bind('Mod+Alt+T'),
|
|
105
|
+
surroundWithLiveTemplate: bind('Mod+Alt+J'),
|
|
106
|
+
unwrap: bind('Mod+Shift+Delete'),
|
|
107
|
+
saveAsLiveTemplate: bind(null),
|
|
108
|
+
// Surround with Emmet has no chord of its own: it is a row of Surround with Live Template, which has this one.
|
|
109
|
+
wrapWithAbbreviation: bind(null),
|
|
104
110
|
selectionToChat: bind(null),
|
|
105
111
|
inlineEdit: bind(null),
|
|
106
112
|
suggestInline: bind(null),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DocumentModel } from '@adecore/editor-core';
|
|
2
|
+
import type { EditorPosition, EditorPostfixOperand, EditorRange, EditorSurroundShape, EditorTextPlace, EditorUnwrapTarget } from './types.ts';
|
|
3
|
+
export interface Coordinates {
|
|
4
|
+
positionAt(offset: number): EditorPosition;
|
|
5
|
+
offsetAt(position: EditorPosition): number;
|
|
6
|
+
}
|
|
7
|
+
export declare function placeAt(model: DocumentModel, coordinates: Coordinates, position: EditorPosition, language: string): EditorTextPlace;
|
|
8
|
+
export declare function postfixOperands(model: DocumentModel, coordinates: Coordinates, dot: EditorPosition, language: string): EditorPostfixOperand[];
|
|
9
|
+
export declare function surroundShape(model: DocumentModel, coordinates: Coordinates, range: EditorRange, language: string): EditorSurroundShape | null;
|
|
10
|
+
export declare function unwrapTargets(model: DocumentModel, coordinates: Coordinates, position: EditorPosition, language: string, indentUnit: string): EditorUnwrapTarget[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
function rangeOf(coordinates, from, to) {
|
|
2
|
+
return { start: coordinates.positionAt(from), end: coordinates.positionAt(to) };
|
|
3
|
+
}
|
|
4
|
+
export function placeAt(model, coordinates, position, language) {
|
|
5
|
+
return model.placeAt(coordinates.offsetAt(position), language);
|
|
6
|
+
}
|
|
7
|
+
export function postfixOperands(model, coordinates, dot, language) {
|
|
8
|
+
const at = coordinates.offsetAt(dot);
|
|
9
|
+
return model.postfixOperands(at, language).map((operand) => ({
|
|
10
|
+
range: rangeOf(coordinates, operand.from, operand.from + model.slice(operand.from, at).trimEnd().length),
|
|
11
|
+
statement: operand.statement
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
export function surroundShape(model, coordinates, range, language) {
|
|
15
|
+
const shape = model.surroundShape(coordinates.offsetAt(range.start), coordinates.offsetAt(range.end), language);
|
|
16
|
+
return shape === null ? null : { range: rangeOf(coordinates, shape.from, shape.to), statements: shape.statements, expression: shape.expression };
|
|
17
|
+
}
|
|
18
|
+
export function unwrapTargets(model, coordinates, position, language, indentUnit) {
|
|
19
|
+
return model.unwrapTargets(coordinates.offsetAt(position), language, indentUnit).map((target) => ({
|
|
20
|
+
kind: target.kind,
|
|
21
|
+
range: rangeOf(coordinates, target.range.from, target.range.to),
|
|
22
|
+
edits: target.edits.map((edit) => ({ range: rangeOf(coordinates, edit.from, edit.to), text: edit.text }))
|
|
23
|
+
}));
|
|
24
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EditorSearchClientOptions } from './search-client.ts';
|
|
2
2
|
import type { Keymap } from './keymap-table.ts';
|
|
3
|
-
import type { EditorCommand, FoldRole, WhitespaceCleanupOptions } from '@adecore/editor-core';
|
|
3
|
+
import type { EditorCommand, FoldRole, TextPlaceKind, UnwrapKind, WhitespaceCleanupOptions } from '@adecore/editor-core';
|
|
4
4
|
export type { EditorCommand, FoldRole };
|
|
5
5
|
export type EditorWhitespaceCleanup = WhitespaceCleanupOptions;
|
|
6
6
|
export type EditorFoldOutline = 'off' | 'hover' | 'always';
|
|
@@ -139,6 +139,24 @@ export interface EditorContentChange {
|
|
|
139
139
|
readonly range: EditorRange;
|
|
140
140
|
readonly text: string;
|
|
141
141
|
}
|
|
142
|
+
export interface EditorTextPlace {
|
|
143
|
+
readonly language: string;
|
|
144
|
+
readonly kind: TextPlaceKind;
|
|
145
|
+
}
|
|
146
|
+
export interface EditorPostfixOperand {
|
|
147
|
+
readonly range: EditorRange;
|
|
148
|
+
readonly statement: boolean;
|
|
149
|
+
}
|
|
150
|
+
export interface EditorSurroundShape {
|
|
151
|
+
readonly range: EditorRange;
|
|
152
|
+
readonly statements: boolean;
|
|
153
|
+
readonly expression: boolean;
|
|
154
|
+
}
|
|
155
|
+
export interface EditorUnwrapTarget {
|
|
156
|
+
readonly kind: UnwrapKind;
|
|
157
|
+
readonly range: EditorRange;
|
|
158
|
+
readonly edits: readonly EditorContentChange[];
|
|
159
|
+
}
|
|
142
160
|
export interface EditorCopy {
|
|
143
161
|
readonly text: string;
|
|
144
162
|
readonly wholeLines: boolean;
|
|
@@ -420,6 +438,10 @@ export interface Editor {
|
|
|
420
438
|
onFontSizeChange?(listener: (size: number | null) => void): () => void;
|
|
421
439
|
setReadOnly(readOnly: boolean, reason?: string): void;
|
|
422
440
|
isReadOnly?(): boolean;
|
|
441
|
+
placeAt?(position: EditorPosition): EditorTextPlace;
|
|
442
|
+
postfixOperands?(dot: EditorPosition): readonly EditorPostfixOperand[];
|
|
443
|
+
surroundShape?(range: EditorRange): EditorSurroundShape | null;
|
|
444
|
+
unwrapTargets?(position: EditorPosition): readonly EditorUnwrapTarget[];
|
|
423
445
|
runCommand(command: EditorRunCommand): boolean;
|
|
424
446
|
focus(): void;
|
|
425
447
|
dispose(): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adecore/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"test": "bun test --conditions=source"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@adecore/editor-core": "0.
|
|
57
|
+
"@adecore/editor-core": "0.44.0",
|
|
58
58
|
"linkedom": "^0.18.14",
|
|
59
59
|
"shiki": "^4.5.0"
|
|
60
60
|
},
|
package/src/engine.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { changedSpans, DocumentModel, type EditorSnapshot, type FoldHints, replacementText } from '@adecore/editor-core';
|
|
2
2
|
import { MAX_REPLACEMENT_CHARACTERS } from './search-protocol.ts';
|
|
3
|
+
import { placeAt, postfixOperands, surroundShape, unwrapTargets } from './text-queries.ts';
|
|
3
4
|
import { GrammarPreparation } from './grammar-preparation.ts';
|
|
4
5
|
import { InputController } from './controller.ts';
|
|
5
6
|
import { resolveSmartKeys } from './smart-keys.ts';
|
|
@@ -43,6 +44,10 @@ import type {
|
|
|
43
44
|
EditorMessages,
|
|
44
45
|
EditorOptions,
|
|
45
46
|
EditorPosition,
|
|
47
|
+
EditorPostfixOperand,
|
|
48
|
+
EditorSurroundShape,
|
|
49
|
+
EditorTextPlace,
|
|
50
|
+
EditorUnwrapTarget,
|
|
46
51
|
EditorRemoteCursor,
|
|
47
52
|
EditorRange,
|
|
48
53
|
EditorReveal,
|
|
@@ -1067,6 +1072,24 @@ class SmartEditor implements Editor {
|
|
|
1067
1072
|
return this.settings.readOnly;
|
|
1068
1073
|
}
|
|
1069
1074
|
|
|
1075
|
+
placeAt(position: EditorPosition): EditorTextPlace {
|
|
1076
|
+
return placeAt(this.model, this, position, this.settings.language ?? 'plaintext');
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
postfixOperands(dot: EditorPosition): readonly EditorPostfixOperand[] {
|
|
1080
|
+
return postfixOperands(this.model, this, dot, this.settings.language ?? 'plaintext');
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
surroundShape(range: EditorRange): EditorSurroundShape | null {
|
|
1084
|
+
return surroundShape(this.model, this, range, this.settings.language ?? 'plaintext');
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
unwrapTargets(position: EditorPosition): readonly EditorUnwrapTarget[] {
|
|
1088
|
+
const unit = this.settings.insertSpaces ? ' '.repeat(this.settings.tabSize) : '\t';
|
|
1089
|
+
|
|
1090
|
+
return unwrapTargets(this.model, this, position, this.settings.language ?? 'plaintext', unit);
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1070
1093
|
runCommand(command: EditorRunCommand): boolean {
|
|
1071
1094
|
return this.controller.command(command);
|
|
1072
1095
|
}
|
package/src/fake.ts
CHANGED
|
@@ -34,6 +34,10 @@ import type {
|
|
|
34
34
|
EditorMessages,
|
|
35
35
|
EditorOptions,
|
|
36
36
|
EditorPosition,
|
|
37
|
+
EditorPostfixOperand,
|
|
38
|
+
EditorSurroundShape,
|
|
39
|
+
EditorTextPlace,
|
|
40
|
+
EditorUnwrapTarget,
|
|
37
41
|
EditorRemoteCursor,
|
|
38
42
|
EditorRange,
|
|
39
43
|
EditorReveal,
|
|
@@ -55,7 +59,8 @@ import type {
|
|
|
55
59
|
EditorWidget
|
|
56
60
|
} from './types.ts';
|
|
57
61
|
import { emit, type Listener, subscribe } from './listeners.ts';
|
|
58
|
-
import { changedSpan, changedSpans } from '@adecore/editor-core';
|
|
62
|
+
import { changedSpan, changedSpans, DocumentModel } from '@adecore/editor-core';
|
|
63
|
+
import { placeAt, postfixOperands, surroundShape, unwrapTargets } from './text-queries.ts';
|
|
59
64
|
import { mapTrackedRange } from './tracked-range.ts';
|
|
60
65
|
|
|
61
66
|
interface OffsetSelection {
|
|
@@ -1270,6 +1275,24 @@ export class FakeEditor implements Editor {
|
|
|
1270
1275
|
return this.readOnly;
|
|
1271
1276
|
}
|
|
1272
1277
|
|
|
1278
|
+
placeAt(position: EditorPosition): EditorTextPlace {
|
|
1279
|
+
return placeAt(new DocumentModel(this.text), this, position, this.language ?? 'plaintext');
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
postfixOperands(dot: EditorPosition): readonly EditorPostfixOperand[] {
|
|
1283
|
+
return postfixOperands(new DocumentModel(this.text), this, dot, this.language ?? 'plaintext');
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
surroundShape(range: EditorRange): EditorSurroundShape | null {
|
|
1287
|
+
return surroundShape(new DocumentModel(this.text), this, range, this.language ?? 'plaintext');
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
unwrapTargets(position: EditorPosition): readonly EditorUnwrapTarget[] {
|
|
1291
|
+
const unit = this.indentation.insertSpaces ? ' '.repeat(this.indentation.tabSize) : '\t';
|
|
1292
|
+
|
|
1293
|
+
return unwrapTargets(new DocumentModel(this.text), this, position, this.language ?? 'plaintext', unit);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1273
1296
|
/* The commands run, in order; of its own the fake carries out only undo and redo. */
|
|
1274
1297
|
readonly commands: EditorRunCommand[] = [];
|
|
1275
1298
|
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { AGENT_COLORS } from './attribution.ts';
|
|
|
3
3
|
export { findDocComments, MAX_DOC_COMMENTS, type DocComment } from '@adecore/editor-core';
|
|
4
4
|
export { DEFAULT_TODO_WORDS, findTodos, type TodoMatch, type TodoOptions } from '@adecore/editor-core';
|
|
5
5
|
export { detectIndentation, type DetectedIndentation } from '@adecore/editor-core';
|
|
6
|
+
export { commentSyntax, type CommentSyntax } from '@adecore/editor-core';
|
|
6
7
|
export { createSmartEditorEngine } from './engine.ts';
|
|
7
8
|
export { rememberCopy } from './controller.ts';
|
|
8
9
|
export { DEFAULT_SMART_KEYS } from './smart-keys.ts';
|
|
@@ -64,6 +65,10 @@ export type {
|
|
|
64
65
|
EditorApplyEditsOptions,
|
|
65
66
|
EditorCopy,
|
|
66
67
|
EditorPasteOptions,
|
|
68
|
+
EditorPostfixOperand,
|
|
69
|
+
EditorSurroundShape,
|
|
70
|
+
EditorTextPlace,
|
|
71
|
+
EditorUnwrapTarget,
|
|
67
72
|
EditorTextChange,
|
|
68
73
|
EditorTrackedRange,
|
|
69
74
|
EditorRunCommand,
|
package/src/keymap-table.ts
CHANGED
|
@@ -123,7 +123,13 @@ export const KEYMAP = {
|
|
|
123
123
|
renameSymbol: bind('Shift+F6'),
|
|
124
124
|
organizeImports: bind('Ctrl+Alt+O'),
|
|
125
125
|
formatDocument: bind('Mod+Alt+L'),
|
|
126
|
-
|
|
126
|
+
insertLiveTemplate: bind('Mod+J'),
|
|
127
|
+
surroundWith: bind('Mod+Alt+T'),
|
|
128
|
+
surroundWithLiveTemplate: bind('Mod+Alt+J'),
|
|
129
|
+
unwrap: bind('Mod+Shift+Delete'),
|
|
130
|
+
saveAsLiveTemplate: bind(null),
|
|
131
|
+
// Surround with Emmet has no chord of its own: it is a row of Surround with Live Template, which has this one.
|
|
132
|
+
wrapWithAbbreviation: bind(null),
|
|
127
133
|
selectionToChat: bind(null),
|
|
128
134
|
inlineEdit: bind(null),
|
|
129
135
|
suggestInline: bind(null),
|
|
@@ -182,6 +188,11 @@ export type OptionalKeymapId =
|
|
|
182
188
|
| 'codeBlockStartWithSelection'
|
|
183
189
|
| 'codeBlockEndWithSelection'
|
|
184
190
|
| 'wrapWithAbbreviation'
|
|
191
|
+
| 'insertLiveTemplate'
|
|
192
|
+
| 'surroundWith'
|
|
193
|
+
| 'surroundWithLiveTemplate'
|
|
194
|
+
| 'unwrap'
|
|
195
|
+
| 'saveAsLiveTemplate'
|
|
185
196
|
| 'typeHierarchy';
|
|
186
197
|
|
|
187
198
|
export type Keymap = Readonly<Record<Exclude<KeymapId, OptionalKeymapId>, KeyBinding> & Partial<Record<OptionalKeymapId, KeyBinding>>>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { DocumentModel } from '@adecore/editor-core';
|
|
2
|
+
import type { EditorPosition, EditorPostfixOperand, EditorRange, EditorSurroundShape, EditorTextPlace, EditorUnwrapTarget } from './types.ts';
|
|
3
|
+
|
|
4
|
+
/* How an editor turns the offsets of the text model into positions and back. */
|
|
5
|
+
export interface Coordinates {
|
|
6
|
+
positionAt(offset: number): EditorPosition;
|
|
7
|
+
offsetAt(position: EditorPosition): number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function rangeOf(coordinates: Coordinates, from: number, to: number): EditorRange {
|
|
11
|
+
return { start: coordinates.positionAt(from), end: coordinates.positionAt(to) };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function placeAt(model: DocumentModel, coordinates: Coordinates, position: EditorPosition, language: string): EditorTextPlace {
|
|
15
|
+
return model.placeAt(coordinates.offsetAt(position), language);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function postfixOperands(model: DocumentModel, coordinates: Coordinates, dot: EditorPosition, language: string): EditorPostfixOperand[] {
|
|
19
|
+
const at = coordinates.offsetAt(dot);
|
|
20
|
+
|
|
21
|
+
return model.postfixOperands(at, language).map((operand) => ({
|
|
22
|
+
range: rangeOf(coordinates, operand.from, operand.from + model.slice(operand.from, at).trimEnd().length),
|
|
23
|
+
statement: operand.statement
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function surroundShape(model: DocumentModel, coordinates: Coordinates, range: EditorRange, language: string): EditorSurroundShape | null {
|
|
28
|
+
const shape = model.surroundShape(coordinates.offsetAt(range.start), coordinates.offsetAt(range.end), language);
|
|
29
|
+
|
|
30
|
+
return shape === null ? null : { range: rangeOf(coordinates, shape.from, shape.to), statements: shape.statements, expression: shape.expression };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function unwrapTargets(
|
|
34
|
+
model: DocumentModel,
|
|
35
|
+
coordinates: Coordinates,
|
|
36
|
+
position: EditorPosition,
|
|
37
|
+
language: string,
|
|
38
|
+
indentUnit: string
|
|
39
|
+
): EditorUnwrapTarget[] {
|
|
40
|
+
return model.unwrapTargets(coordinates.offsetAt(position), language, indentUnit).map((target) => ({
|
|
41
|
+
kind: target.kind,
|
|
42
|
+
range: rangeOf(coordinates, target.range.from, target.range.to),
|
|
43
|
+
edits: target.edits.map((edit) => ({ range: rangeOf(coordinates, edit.from, edit.to), text: edit.text }))
|
|
44
|
+
}));
|
|
45
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EditorSearchClientOptions } from './search-client.ts';
|
|
2
2
|
import type { Keymap } from './keymap-table.ts';
|
|
3
|
-
import type { EditorCommand, FoldRole, WhitespaceCleanupOptions } from '@adecore/editor-core';
|
|
3
|
+
import type { EditorCommand, FoldRole, TextPlaceKind, UnwrapKind, WhitespaceCleanupOptions } from '@adecore/editor-core';
|
|
4
4
|
|
|
5
5
|
export type { EditorCommand, FoldRole };
|
|
6
6
|
|
|
@@ -288,6 +288,37 @@ export interface EditorContentChange {
|
|
|
288
288
|
readonly text: string;
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
+
/* What the text at a position is written in, with embedded regions resolved, and whether it is code, a comment or a string. */
|
|
292
|
+
export interface EditorTextPlace {
|
|
293
|
+
readonly language: string;
|
|
294
|
+
readonly kind: TextPlaceKind;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/* An expression that ends right before a dot. */
|
|
298
|
+
export interface EditorPostfixOperand {
|
|
299
|
+
/* The expression, without the whitespace before the dot. */
|
|
300
|
+
readonly range: EditorRange;
|
|
301
|
+
/* Whether it starts a statement; only the widest operand can. */
|
|
302
|
+
readonly statement: boolean;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* What a range can be surrounded with: whole statements, one expression, both or neither. */
|
|
306
|
+
export interface EditorSurroundShape {
|
|
307
|
+
/* The range after trimming whitespace, widened past a trailing line comment for statements. */
|
|
308
|
+
readonly range: EditorRange;
|
|
309
|
+
readonly statements: boolean;
|
|
310
|
+
readonly expression: boolean;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* A construct around a position that can be unwrapped or removed. */
|
|
314
|
+
export interface EditorUnwrapTarget {
|
|
315
|
+
readonly kind: UnwrapKind;
|
|
316
|
+
/* The whole construct, for a preview. */
|
|
317
|
+
readonly range: EditorRange;
|
|
318
|
+
/* Small edits in the coordinates of the text before them, which `applyEdits` takes as they are. */
|
|
319
|
+
readonly edits: readonly EditorContentChange[];
|
|
320
|
+
}
|
|
321
|
+
|
|
291
322
|
/* What a copy or cut put on the clipboard. */
|
|
292
323
|
export interface EditorCopy {
|
|
293
324
|
readonly text: string;
|
|
@@ -843,6 +874,14 @@ export interface Editor {
|
|
|
843
874
|
setReadOnly(readOnly: boolean, reason?: string): void;
|
|
844
875
|
/* Whether the editor refuses edits. Optional so an editor from before it still fits. */
|
|
845
876
|
isReadOnly?(): boolean;
|
|
877
|
+
/* What the text at a position is written in and whether it is code, a comment or a string. Optional so an editor from before it still fits. */
|
|
878
|
+
placeAt?(position: EditorPosition): EditorTextPlace;
|
|
879
|
+
/* Every expression that ends right before the `.` at `dot`, innermost first. Optional so an editor from before it still fits. */
|
|
880
|
+
postfixOperands?(dot: EditorPosition): readonly EditorPostfixOperand[];
|
|
881
|
+
/* What a range can be surrounded with; null for a blank range. Optional so an editor from before it still fits. */
|
|
882
|
+
surroundShape?(range: EditorRange): EditorSurroundShape | null;
|
|
883
|
+
/* What can be unwrapped or removed around a position, innermost first. Optional so an editor from before it still fits. */
|
|
884
|
+
unwrapTargets?(position: EditorPosition): readonly EditorUnwrapTarget[];
|
|
846
885
|
/* Runs an editing command on every caret, as its key would. False when it changed nothing. */
|
|
847
886
|
runCommand(command: EditorRunCommand): boolean;
|
|
848
887
|
focus(): void;
|