aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/xtext/ContentAssistService.ts
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-08-12 19:54:46 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-08-12 19:54:46 +0200
commitd22c3b0c257f5daf5b401988a35ab9ce981a2341 (patch)
tree0a661c927c37b52197326d1c05e211daf9bd19e5 /subprojects/frontend/src/xtext/ContentAssistService.ts
parentfix(language): rule parsing test (diff)
downloadrefinery-d22c3b0c257f5daf5b401988a35ab9ce981a2341.tar.gz
refinery-d22c3b0c257f5daf5b401988a35ab9ce981a2341.tar.zst
refinery-d22c3b0c257f5daf5b401988a35ab9ce981a2341.zip
refactor(frontend): move from Webpack to Vite
Also overhaulds the building and linting for frontend assets.
Diffstat (limited to 'subprojects/frontend/src/xtext/ContentAssistService.ts')
-rw-r--r--subprojects/frontend/src/xtext/ContentAssistService.ts86
1 files changed, 55 insertions, 31 deletions
diff --git a/subprojects/frontend/src/xtext/ContentAssistService.ts b/subprojects/frontend/src/xtext/ContentAssistService.ts
index bedd3b5c..dce2a902 100644
--- a/subprojects/frontend/src/xtext/ContentAssistService.ts
+++ b/subprojects/frontend/src/xtext/ContentAssistService.ts
@@ -8,8 +8,9 @@ import type { Transaction } from '@codemirror/state';
8import escapeStringRegexp from 'escape-string-regexp'; 8import escapeStringRegexp from 'escape-string-regexp';
9 9
10import { implicitCompletion } from '../language/props'; 10import { implicitCompletion } from '../language/props';
11import type { UpdateService } from './UpdateService'; 11import getLogger from '../utils/getLogger';
12import { getLogger } from '../utils/logger'; 12
13import type UpdateService from './UpdateService';
13import type { ContentAssistEntry } from './xtextServiceResults'; 14import type { ContentAssistEntry } from './xtextServiceResults';
14 15
15const PROPOSALS_LIMIT = 1000; 16const PROPOSALS_LIMIT = 1000;
@@ -48,10 +49,13 @@ function findToken({ pos, state }: CompletionContext): IFoundToken | null {
48 }; 49 };
49} 50}
50 51
51function shouldCompleteImplicitly(token: IFoundToken | null, context: CompletionContext): boolean { 52function shouldCompleteImplicitly(
52 return token !== null 53 token: IFoundToken | null,
53 && token.implicitCompletion 54 context: CompletionContext,
54 && context.pos - token.from >= 2; 55): boolean {
56 return (
57 token !== null && token.implicitCompletion && context.pos - token.from >= 2
58 );
55} 59}
56 60
57function computeSpan(prefix: string, entryCount: number): RegExp { 61function computeSpan(prefix: string, entryCount: number): RegExp {
@@ -78,23 +82,29 @@ function createCompletion(entry: ContentAssistEntry): Completion {
78 case 'SNIPPET': 82 case 'SNIPPET':
79 boost = -90; 83 boost = -90;
80 break; 84 break;
81 default: { 85 default:
82 // Penalize qualified names (vs available unqualified names). 86 {
83 const extraSegments = entry.proposal.match(/::/g)?.length || 0; 87 // Penalize qualified names (vs available unqualified names).
84 boost = Math.max(-5 * extraSegments, -50); 88 const extraSegments = entry.proposal.match(/::/g)?.length || 0;
85 } 89 boost = Math.max(-5 * extraSegments, -50);
90 }
86 break; 91 break;
87 } 92 }
88 return { 93 const completion: Completion = {
89 label: entry.proposal, 94 label: entry.proposal,
90 detail: entry.description,
91 info: entry.documentation,
92 type: entry.kind?.toLowerCase(), 95 type: entry.kind?.toLowerCase(),
93 boost, 96 boost,
94 }; 97 };
98 if (entry.documentation !== undefined) {
99 completion.info = entry.documentation;
100 }
101 if (entry.description !== undefined) {
102 completion.detail = entry.description;
103 }
104 return completion;
95} 105}
96 106
97export class ContentAssistService { 107export default class ContentAssistService {
98 private readonly updateService: UpdateService; 108 private readonly updateService: UpdateService;
99 109
100 private lastCompletion: CompletionResult | null = null; 110 private lastCompletion: CompletionResult | null = null;
@@ -117,7 +127,7 @@ export class ContentAssistService {
117 options: [], 127 options: [],
118 }; 128 };
119 } 129 }
120 let range: { from: number, to: number }; 130 let range: { from: number; to: number };
121 let prefix = ''; 131 let prefix = '';
122 if (tokenBefore === null) { 132 if (tokenBefore === null) {
123 range = { 133 range = {
@@ -139,17 +149,20 @@ export class ContentAssistService {
139 log.trace('Returning cached completion result'); 149 log.trace('Returning cached completion result');
140 // Postcondition of `shouldReturnCachedCompletion`: `lastCompletion !== null` 150 // Postcondition of `shouldReturnCachedCompletion`: `lastCompletion !== null`
141 return { 151 return {
142 ...this.lastCompletion as CompletionResult, 152 ...(this.lastCompletion as CompletionResult),
143 ...range, 153 ...range,
144 }; 154 };
145 } 155 }
146 this.lastCompletion = null; 156 this.lastCompletion = null;
147 const entries = await this.updateService.fetchContentAssist({ 157 const entries = await this.updateService.fetchContentAssist(
148 resource: this.updateService.resourceName, 158 {
149 serviceType: 'assist', 159 resource: this.updateService.resourceName,
150 caretOffset: context.pos, 160 serviceType: 'assist',
151 proposalsLimit: PROPOSALS_LIMIT, 161 caretOffset: context.pos,
152 }, context); 162 proposalsLimit: PROPOSALS_LIMIT,
163 },
164 context,
165 );
153 if (context.aborted) { 166 if (context.aborted) {
154 return { 167 return {
155 ...range, 168 ...range,
@@ -175,7 +188,7 @@ export class ContentAssistService {
175 } 188 }
176 189
177 private shouldReturnCachedCompletion( 190 private shouldReturnCachedCompletion(
178 token: { from: number, to: number, text: string } | null, 191 token: { from: number; to: number; text: string } | null,
179 ): boolean { 192 ): boolean {
180 if (token === null || this.lastCompletion === null) { 193 if (token === null || this.lastCompletion === null) {
181 return false; 194 return false;
@@ -185,11 +198,16 @@ export class ContentAssistService {
185 if (!lastTo) { 198 if (!lastTo) {
186 return true; 199 return true;
187 } 200 }
188 const [transformedFrom, transformedTo] = this.mapRangeInclusive(lastFrom, lastTo); 201 const [transformedFrom, transformedTo] = this.mapRangeInclusive(
189 return from >= transformedFrom 202 lastFrom,
190 && to <= transformedTo 203 lastTo,
191 && validFor instanceof RegExp 204 );
192 && validFor.exec(text) !== null; 205 return (
206 from >= transformedFrom &&
207 to <= transformedTo &&
208 validFor instanceof RegExp &&
209 validFor.exec(text) !== null
210 );
193 } 211 }
194 212
195 private shouldInvalidateCachedCompletion(transaction: Transaction): boolean { 213 private shouldInvalidateCachedCompletion(transaction: Transaction): boolean {
@@ -200,7 +218,10 @@ export class ContentAssistService {
200 if (!lastTo) { 218 if (!lastTo) {
201 return true; 219 return true;
202 } 220 }
203 const [transformedFrom, transformedTo] = this.mapRangeInclusive(lastFrom, lastTo); 221 const [transformedFrom, transformedTo] = this.mapRangeInclusive(
222 lastFrom,
223 lastTo,
224 );
204 let invalidate = false; 225 let invalidate = false;
205 transaction.changes.iterChangedRanges((fromA, toA) => { 226 transaction.changes.iterChangedRanges((fromA, toA) => {
206 if (fromA < transformedFrom || toA > transformedTo) { 227 if (fromA < transformedFrom || toA > transformedTo) {
@@ -210,7 +231,10 @@ export class ContentAssistService {
210 return invalidate; 231 return invalidate;
211 } 232 }
212 233
213 private mapRangeInclusive(lastFrom: number, lastTo: number): [number, number] { 234 private mapRangeInclusive(
235 lastFrom: number,
236 lastTo: number,
237 ): [number, number] {
214 const changes = this.updateService.computeChangesSinceLastUpdate(); 238 const changes = this.updateService.computeChangesSinceLastUpdate();
215 const transformedFrom = changes.mapPos(lastFrom); 239 const transformedFrom = changes.mapPos(lastFrom);
216 const transformedTo = changes.mapPos(lastTo, 1); 240 const transformedTo = changes.mapPos(lastTo, 1);