11import type {
22 Edit ,
33 EditableTextEditor ,
4+ EmittableIDE ,
45 GeneralizedRange ,
5- InMemoryTextDocument ,
66 OpenLinkOptions ,
77 Range ,
88 RevealLineAt ,
9- Selection ,
9+ SelectionOffsets ,
1010 SetSelectionsOpts ,
11+ TextDocument ,
1112 TextEditor ,
1213 TextEditorOptions ,
1314} from "@cursorless/common" ;
14- import { selectionsEqual } from "@cursorless/common" ;
15- import type { Talon } from "../types/talon.types" ;
16- import { setSelections } from "./setSelections" ;
17- import type { TalonJsIDE } from "./TalonJsIDE" ;
18- import { talonJsPerformEdits } from "./talonJsPerformEdits" ;
19-
20- export class TalonJsEditor implements EditableTextEditor {
21- options : TextEditorOptions = {
22- tabSize : 4 ,
23- insertSpaces : true ,
24- } ;
25-
26- isActive = true ;
27-
28- constructor (
29- private talon : Talon ,
30- private ide : TalonJsIDE ,
31- public id : string ,
32- public document : InMemoryTextDocument ,
33- public visibleRanges : Range [ ] ,
34- public selections : Selection [ ] ,
35- ) { }
15+ import { Selection , selectionsEqual } from "@cursorless/common" ;
16+ import { URI } from "vscode-uri" ;
17+ import { InMemoryTextDocument } from "./InMemoryTextDocument" ;
18+
19+ interface Params {
20+ ide : EmittableIDE ;
21+ languageId ?: string ;
22+ content ?: string ;
23+ options ?: TextEditorOptions ;
24+ visibleRanges ?: Range [ ] ;
25+ selections ?: Selection [ ] | SelectionOffsets [ ] ;
26+ }
27+
28+ export class InMemoryTextEditor implements EditableTextEditor {
29+ private static nextId = 0 ;
30+
31+ private readonly ide : EmittableIDE ;
32+ readonly id : string ;
33+ readonly isActive = true ;
34+ readonly document : InMemoryTextDocument ;
35+ readonly options : TextEditorOptions ;
36+ readonly visibleRanges : Range [ ] ;
37+ selections : Selection [ ] ;
38+
39+ constructor ( {
40+ ide,
41+ languageId = "plaintext" ,
42+ content = "" ,
43+ visibleRanges,
44+ selections,
45+ options,
46+ } : Params ) {
47+ this . ide = ide ;
48+ this . id = String ( InMemoryTextEditor . nextId ++ ) ;
49+ const uri = URI . parse ( `InMemoryTextEditor://${ this . id } ` ) ;
50+ this . document = new InMemoryTextDocument ( uri , languageId , content ) ;
51+
52+ if ( visibleRanges != null ) {
53+ if ( visibleRanges . length === 0 ) {
54+ throw new Error ( "Visible ranges must be non-empty" ) ;
55+ }
56+ this . visibleRanges = visibleRanges ;
57+ } else {
58+ this . visibleRanges = [ this . document . range ] ;
59+ }
60+
61+ if ( selections != null ) {
62+ if ( selections . length === 0 ) {
63+ throw new Error ( "Selections must be non-empty" ) ;
64+ }
65+ this . selections = selections . map ( ( s ) => {
66+ return s instanceof Selection ? s : createSelection ( this . document , s ) ;
67+ } ) ;
68+ } else {
69+ this . selections = [ new Selection ( 0 , 0 , 0 , 0 ) ] ;
70+ }
71+
72+ this . options = options ?? {
73+ insertSpaces : true ,
74+ tabSize : 4 ,
75+ } ;
76+ }
3677
3778 isEqual ( other : TextEditor ) : boolean {
3879 return this . id === other . id ;
@@ -42,14 +83,24 @@ export class TalonJsEditor implements EditableTextEditor {
4283 selections : Selection [ ] ,
4384 _opts ?: SetSelectionsOpts ,
4485 ) : Promise < void > {
86+ if ( selections . length === 0 ) {
87+ throw new Error ( "Selections must be non-empty" ) ;
88+ }
4589 if ( ! selectionsEqual ( this . selections , selections ) ) {
46- await setSelections ( this . talon , this . document , selections ) ;
4790 this . selections = selections ;
91+ this . ide . emitDidChangeTextEditorSelection ( {
92+ textEditor : this ,
93+ selections : selections ,
94+ } ) ;
4895 }
4996 }
5097
5198 edit ( edits : Edit [ ] ) : Promise < boolean > {
52- talonJsPerformEdits ( this . talon , this . ide , this . document , edits ) ;
99+ const changes = this . document . edit ( edits ) ;
100+ this . ide . emitDidChangeTextDocument ( {
101+ document : this . document ,
102+ contentChanges : changes ,
103+ } ) ;
53104 return Promise . resolve ( true ) ;
54105 }
55106
@@ -179,3 +230,10 @@ export class TalonJsEditor implements EditableTextEditor {
179230 throw Error ( "gitUnstageRange: not implemented" ) ;
180231 }
181232}
233+
234+ function createSelection ( document : TextDocument , selection : SelectionOffsets ) {
235+ return new Selection (
236+ document . positionAt ( selection . anchor ) ,
237+ document . positionAt ( selection . active ) ,
238+ ) ;
239+ }
0 commit comments