@@ -6,29 +6,20 @@ import {
6
6
} from "@cursorless/common" ;
7
7
import { isEqual } from "lodash" ;
8
8
import {
9
+ SUPPORTED_ENTRY_TYPES ,
9
10
NeedsInitialTalonUpdateError ,
10
11
SpokenFormEntry ,
11
12
TalonSpokenForms ,
12
13
} from "../scopeProviders/SpokenFormEntry" ;
13
14
import { ide } from "../singletons/ide.singleton" ;
14
15
import { SpokenFormMap , SpokenFormMapEntry } from "./SpokenFormMap" ;
15
- import { SpokenFormType } from "./SpokenFormType" ;
16
+ import { SpokenFormMapKeyTypes , SpokenFormType } from "./SpokenFormType" ;
16
17
import {
17
18
defaultSpokenFormInfoMap ,
18
19
defaultSpokenFormMap ,
19
20
} from "./defaultSpokenFormMap" ;
20
21
import { DefaultSpokenFormMapEntry } from "./defaultSpokenFormMap.types" ;
21
22
22
- /**
23
- * The types of entries for which we currently support getting custom spoken
24
- * forms from Talon.
25
- */
26
- const ENTRY_TYPES = [
27
- "simpleScopeTypeType" ,
28
- "customRegex" ,
29
- "pairedDelimiter" ,
30
- ] as const ;
31
-
32
23
type Writable < T > = {
33
24
- readonly [ K in keyof T ] : T [ K ] ;
34
25
} ;
@@ -110,61 +101,17 @@ export class CustomSpokenForms {
110
101
return ;
111
102
}
112
103
113
- for ( const entryType of ENTRY_TYPES ) {
114
- const customEntries = Object . fromEntries (
115
- allCustomEntries
116
- . filter ( ( entry ) => entry . type === entryType )
117
- . map ( ( { id, spokenForms } ) => [ id , spokenForms ] ) ,
104
+ for ( const entryType of SUPPORTED_ENTRY_TYPES ) {
105
+ updateEntriesForType (
106
+ this . spokenFormMap_ ,
107
+ entryType ,
108
+ defaultSpokenFormInfoMap [ entryType ] ,
109
+ Object . fromEntries (
110
+ allCustomEntries
111
+ . filter ( ( entry ) => entry . type === entryType )
112
+ . map ( ( { id, spokenForms } ) => [ id , spokenForms ] ) ,
113
+ ) ,
118
114
) ;
119
-
120
- const defaultEntries : Partial < Record < string , DefaultSpokenFormMapEntry > > =
121
- defaultSpokenFormInfoMap [ entryType ] ;
122
-
123
- /**
124
- * The ids of the entries to include in the spoken form map. We need a
125
- * union of the ids from the default entry and the custom entry. The custom
126
- * entry could be missing private entries, or it could be missing entries
127
- * because the Talon side is old. The default entry could be missing entries
128
- * like custom regexes, where the user can create arbitrary ids.
129
- */
130
- const ids = Array . from (
131
- new Set ( [
132
- ...Object . keys ( defaultEntries ) ,
133
- ...Object . keys ( customEntries ) ,
134
- ] ) ,
135
- ) ;
136
- // FIXME: How to avoid the type assertions here?
137
- this . spokenFormMap_ [ entryType ] = Object . fromEntries (
138
- ids . map ( ( id ) : [ SpokenFormType , SpokenFormMapEntry ] => {
139
- const { defaultSpokenForms = [ ] , isPrivate = false } =
140
- defaultEntries [ id ] ?? { } ;
141
- const customSpokenForms = customEntries [ id ] ;
142
- if ( customSpokenForms != null ) {
143
- return [
144
- id as SpokenFormType ,
145
- {
146
- defaultSpokenForms,
147
- spokenForms : customSpokenForms ,
148
- requiresTalonUpdate : false ,
149
- isCustom : isEqual ( defaultSpokenForms , customSpokenForms ) ,
150
- isPrivate,
151
- } ,
152
- ] ;
153
- } else {
154
- return [
155
- id as SpokenFormType ,
156
- {
157
- defaultSpokenForms,
158
- spokenForms : [ ] ,
159
- // If it's not a private spoken form, then it's a new scope type
160
- requiresTalonUpdate : ! isPrivate ,
161
- isCustom : false ,
162
- isPrivate,
163
- } ,
164
- ] ;
165
- }
166
- } ) ,
167
- ) as any ;
168
115
}
169
116
170
117
this . customSpokenFormsInitialized_ = true ;
@@ -180,3 +127,53 @@ export class CustomSpokenForms {
180
127
181
128
dispose = this . disposer . dispose ;
182
129
}
130
+
131
+ function updateEntriesForType < T extends SpokenFormType > (
132
+ spokenFormMapToUpdate : Writable < SpokenFormMap > ,
133
+ key : T ,
134
+ defaultEntries : Partial <
135
+ Record < SpokenFormMapKeyTypes [ T ] , DefaultSpokenFormMapEntry >
136
+ > ,
137
+ customEntries : Partial < Record < SpokenFormMapKeyTypes [ T ] , string [ ] > > ,
138
+ ) {
139
+ /**
140
+ * The ids of the entries to include in the spoken form map. We need a
141
+ * union of the ids from the default entry and the custom entry. The custom
142
+ * entry could be missing private entries, or it could be missing entries
143
+ * because the Talon side is old. The default entry could be missing entries
144
+ * like custom regexes, where the user can create arbitrary ids.
145
+ */
146
+ const ids = Array . from (
147
+ new Set ( [ ...Object . keys ( defaultEntries ) , ...Object . keys ( customEntries ) ] ) ,
148
+ ) as SpokenFormMapKeyTypes [ T ] [ ] ;
149
+
150
+ const obj : Partial < Record < SpokenFormMapKeyTypes [ T ] , SpokenFormMapEntry > > = { } ;
151
+ for ( const id of ids ) {
152
+ const { defaultSpokenForms = [ ] , isPrivate = false } =
153
+ defaultEntries [ id ] ?? { } ;
154
+ const customSpokenForms = customEntries [ id ] ;
155
+
156
+ obj [ id ] =
157
+ customSpokenForms == null
158
+ ? // No entry for the given id. This either means that the user needs to
159
+ // update Talon, or it's a private spoken form.
160
+ {
161
+ defaultSpokenForms,
162
+ spokenForms : [ ] ,
163
+ // If it's not a private spoken form, then it's a new scope type
164
+ requiresTalonUpdate : ! isPrivate ,
165
+ isCustom : false ,
166
+ isPrivate,
167
+ }
168
+ : // We have an entry for the given id
169
+ {
170
+ defaultSpokenForms,
171
+ spokenForms : customSpokenForms ,
172
+ requiresTalonUpdate : false ,
173
+ isCustom : isEqual ( defaultSpokenForms , customSpokenForms ) ,
174
+ isPrivate,
175
+ } ;
176
+ }
177
+
178
+ spokenFormMapToUpdate [ key ] = obj as SpokenFormMap [ T ] ;
179
+ }
0 commit comments