@adecore/editor 0.43.0 → 0.44.1
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.js +1 -0
- 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/smart-keys.js +1 -0
- package/dist/text-queries.d.ts +10 -0
- package/dist/text-queries.js +24 -0
- package/dist/types.d.ts +24 -1
- package/package.json +2 -2
- package/src/controller.ts +1 -0
- 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/smart-keys.ts +1 -0
- package/src/text-queries.ts +45 -0
- package/src/types.ts +42 -1
package/dist/controller.js
CHANGED
|
@@ -336,6 +336,7 @@ export class InputController {
|
|
|
336
336
|
indentGuides: settings.guides,
|
|
337
337
|
smartSemicolon: keys.smartSemicolon,
|
|
338
338
|
smartArrow: keys.smartArrow,
|
|
339
|
+
templateLiterals: keys.templateLiterals,
|
|
339
340
|
language: settings.language ?? 'plaintext',
|
|
340
341
|
camelCase: keys.camelHumps,
|
|
341
342
|
visualLine: (offset) => this.view.rowOf(offset),
|
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),
|
package/dist/smart-keys.js
CHANGED
|
@@ -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';
|
|
@@ -66,6 +66,7 @@ export interface EditorSmartKeys {
|
|
|
66
66
|
readonly indentOnPaste: boolean;
|
|
67
67
|
readonly smartSemicolon: boolean;
|
|
68
68
|
readonly smartArrow: boolean;
|
|
69
|
+
readonly templateLiterals: boolean;
|
|
69
70
|
readonly camelHumps: boolean;
|
|
70
71
|
}
|
|
71
72
|
export interface EditorFoldSymbol {
|
|
@@ -139,6 +140,24 @@ export interface EditorContentChange {
|
|
|
139
140
|
readonly range: EditorRange;
|
|
140
141
|
readonly text: string;
|
|
141
142
|
}
|
|
143
|
+
export interface EditorTextPlace {
|
|
144
|
+
readonly language: string;
|
|
145
|
+
readonly kind: TextPlaceKind;
|
|
146
|
+
}
|
|
147
|
+
export interface EditorPostfixOperand {
|
|
148
|
+
readonly range: EditorRange;
|
|
149
|
+
readonly statement: boolean;
|
|
150
|
+
}
|
|
151
|
+
export interface EditorSurroundShape {
|
|
152
|
+
readonly range: EditorRange;
|
|
153
|
+
readonly statements: boolean;
|
|
154
|
+
readonly expression: boolean;
|
|
155
|
+
}
|
|
156
|
+
export interface EditorUnwrapTarget {
|
|
157
|
+
readonly kind: UnwrapKind;
|
|
158
|
+
readonly range: EditorRange;
|
|
159
|
+
readonly edits: readonly EditorContentChange[];
|
|
160
|
+
}
|
|
142
161
|
export interface EditorCopy {
|
|
143
162
|
readonly text: string;
|
|
144
163
|
readonly wholeLines: boolean;
|
|
@@ -420,6 +439,10 @@ export interface Editor {
|
|
|
420
439
|
onFontSizeChange?(listener: (size: number | null) => void): () => void;
|
|
421
440
|
setReadOnly(readOnly: boolean, reason?: string): void;
|
|
422
441
|
isReadOnly?(): boolean;
|
|
442
|
+
placeAt?(position: EditorPosition): EditorTextPlace;
|
|
443
|
+
postfixOperands?(dot: EditorPosition): readonly EditorPostfixOperand[];
|
|
444
|
+
surroundShape?(range: EditorRange): EditorSurroundShape | null;
|
|
445
|
+
unwrapTargets?(position: EditorPosition): readonly EditorUnwrapTarget[];
|
|
423
446
|
runCommand(command: EditorRunCommand): boolean;
|
|
424
447
|
focus(): void;
|
|
425
448
|
dispose(): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adecore/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.1",
|
|
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.1",
|
|
58
58
|
"linkedom": "^0.18.14",
|
|
59
59
|
"shiki": "^4.5.0"
|
|
60
60
|
},
|
package/src/controller.ts
CHANGED
|
@@ -425,6 +425,7 @@ export class InputController {
|
|
|
425
425
|
indentGuides: settings.guides,
|
|
426
426
|
smartSemicolon: keys.smartSemicolon,
|
|
427
427
|
smartArrow: keys.smartArrow,
|
|
428
|
+
templateLiterals: keys.templateLiterals,
|
|
428
429
|
language: settings.language ?? 'plaintext',
|
|
429
430
|
camelCase: keys.camelHumps,
|
|
430
431
|
visualLine: (offset) => this.view.rowOf(offset),
|
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>>>;
|
package/src/smart-keys.ts
CHANGED
|
@@ -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
|
|
|
@@ -150,6 +150,8 @@ export interface EditorSmartKeys {
|
|
|
150
150
|
readonly smartSemicolon: boolean;
|
|
151
151
|
/* In PHP a `-` typed after a variable, a member or a `)` or `]` becomes `->`. */
|
|
152
152
|
readonly smartArrow: boolean;
|
|
153
|
+
/* In JavaScript and TypeScript a `${` typed in a quoted string makes it a template literal. */
|
|
154
|
+
readonly templateLiterals: boolean;
|
|
153
155
|
/* Moving by word also stops inside `camelCase` and `snake_case` words. Off. */
|
|
154
156
|
readonly camelHumps: boolean;
|
|
155
157
|
}
|
|
@@ -288,6 +290,37 @@ export interface EditorContentChange {
|
|
|
288
290
|
readonly text: string;
|
|
289
291
|
}
|
|
290
292
|
|
|
293
|
+
/* What the text at a position is written in, with embedded regions resolved, and whether it is code, a comment or a string. */
|
|
294
|
+
export interface EditorTextPlace {
|
|
295
|
+
readonly language: string;
|
|
296
|
+
readonly kind: TextPlaceKind;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* An expression that ends right before a dot. */
|
|
300
|
+
export interface EditorPostfixOperand {
|
|
301
|
+
/* The expression, without the whitespace before the dot. */
|
|
302
|
+
readonly range: EditorRange;
|
|
303
|
+
/* Whether it starts a statement; only the widest operand can. */
|
|
304
|
+
readonly statement: boolean;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* What a range can be surrounded with: whole statements, one expression, both or neither. */
|
|
308
|
+
export interface EditorSurroundShape {
|
|
309
|
+
/* The range after trimming whitespace, widened past a trailing line comment for statements. */
|
|
310
|
+
readonly range: EditorRange;
|
|
311
|
+
readonly statements: boolean;
|
|
312
|
+
readonly expression: boolean;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* A construct around a position that can be unwrapped or removed. */
|
|
316
|
+
export interface EditorUnwrapTarget {
|
|
317
|
+
readonly kind: UnwrapKind;
|
|
318
|
+
/* The whole construct, for a preview. */
|
|
319
|
+
readonly range: EditorRange;
|
|
320
|
+
/* Small edits in the coordinates of the text before them, which `applyEdits` takes as they are. */
|
|
321
|
+
readonly edits: readonly EditorContentChange[];
|
|
322
|
+
}
|
|
323
|
+
|
|
291
324
|
/* What a copy or cut put on the clipboard. */
|
|
292
325
|
export interface EditorCopy {
|
|
293
326
|
readonly text: string;
|
|
@@ -843,6 +876,14 @@ export interface Editor {
|
|
|
843
876
|
setReadOnly(readOnly: boolean, reason?: string): void;
|
|
844
877
|
/* Whether the editor refuses edits. Optional so an editor from before it still fits. */
|
|
845
878
|
isReadOnly?(): boolean;
|
|
879
|
+
/* 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. */
|
|
880
|
+
placeAt?(position: EditorPosition): EditorTextPlace;
|
|
881
|
+
/* Every expression that ends right before the `.` at `dot`, innermost first. Optional so an editor from before it still fits. */
|
|
882
|
+
postfixOperands?(dot: EditorPosition): readonly EditorPostfixOperand[];
|
|
883
|
+
/* What a range can be surrounded with; null for a blank range. Optional so an editor from before it still fits. */
|
|
884
|
+
surroundShape?(range: EditorRange): EditorSurroundShape | null;
|
|
885
|
+
/* What can be unwrapped or removed around a position, innermost first. Optional so an editor from before it still fits. */
|
|
886
|
+
unwrapTargets?(position: EditorPosition): readonly EditorUnwrapTarget[];
|
|
846
887
|
/* Runs an editing command on every caret, as its key would. False when it changed nothing. */
|
|
847
888
|
runCommand(command: EditorRunCommand): boolean;
|
|
848
889
|
focus(): void;
|