@adecore/editor-react 0.17.0 → 0.18.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/completion-model.d.ts +1 -0
- package/dist/completion-model.js +13 -0
- package/dist/completion.js +6 -1
- package/package.json +5 -5
- package/src/completion-model.ts +16 -0
- package/src/completion.ts +7 -0
|
@@ -4,6 +4,7 @@ import type { CompletionDocs } from './popups.ts';
|
|
|
4
4
|
import { type SnippetStop } from './snippet.ts';
|
|
5
5
|
export declare function isIdentifierCharacter(character: string): boolean;
|
|
6
6
|
export declare function identifierPrefix(before: string): string;
|
|
7
|
+
export declare function opensCompletion(before: string, text: string): boolean;
|
|
7
8
|
export interface MatchDetail {
|
|
8
9
|
readonly score: number;
|
|
9
10
|
readonly positions: readonly number[];
|
package/dist/completion-model.js
CHANGED
|
@@ -21,6 +21,19 @@ export function identifierPrefix(before) {
|
|
|
21
21
|
lastPrefix = characters.slice(start).join('');
|
|
22
22
|
return lastPrefix;
|
|
23
23
|
}
|
|
24
|
+
const OPENS_VALUE = /(?:[-=!<>&|?+*/%^:,]|(?:^|[^\p{L}\p{N}_$])(?:return|new|case|in|of|instanceof|typeof|keyof|await|yield|throw|extends|implements|as|is|not|and|or|echo|print|use|import|from|clone))$/u;
|
|
25
|
+
const NOT_A_VALUE = /(?:\+\+|--|\/\/|\/\*\*?|^\s*[-+*])$/;
|
|
26
|
+
/*
|
|
27
|
+
* Whether `text`, typed after `before` on its line, puts the caret where a value or a name comes next, so the list
|
|
28
|
+
* opens without a word typed: an opening bracket, or a space after an operator, a comma or a keyword. A comment
|
|
29
|
+
* opener, a list marker and `++` or `--` open nothing.
|
|
30
|
+
*/
|
|
31
|
+
export function opensCompletion(before, text) {
|
|
32
|
+
if (text === '(' || text === '()' || text === '[' || text === '[]') {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return text === ' ' && OPENS_VALUE.test(before) && !NOT_A_VALUE.test(before);
|
|
36
|
+
}
|
|
24
37
|
function run(start, length) {
|
|
25
38
|
return Array.from({ length }, (_, offset) => start + offset);
|
|
26
39
|
}
|
package/dist/completion.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StaleResultError } from '@adecore/lsp';
|
|
2
2
|
import { comparePositions, shiftPosition } from './diagnostics-model.js';
|
|
3
|
-
import { completionDocsOf, identifierPrefix, insertionOf, isIdentifierCharacter, itemsOf, matchedCharacters, mirroredInsertions, prefixFor, qualifiersOf, rankCompletions } from './completion-model.js';
|
|
3
|
+
import { completionDocsOf, identifierPrefix, insertionOf, isIdentifierCharacter, itemsOf, matchedCharacters, mirroredInsertions, opensCompletion, prefixFor, qualifiersOf, rankCompletions } from './completion-model.js';
|
|
4
4
|
import { PARAMETER_HINTS_COMMAND, isCallItem, planCall, withParentheses } from './completion-call.js';
|
|
5
5
|
import { RecentChoices, recentChoicesOf } from './recent-choices.js';
|
|
6
6
|
import { shikiLanguageOf } from './language-ids.js';
|
|
@@ -281,6 +281,11 @@ export class CompletionFeature {
|
|
|
281
281
|
this.close();
|
|
282
282
|
this.beginRequest({ triggerKind: 2, triggerCharacter: last }, 0);
|
|
283
283
|
}
|
|
284
|
+
else if (isEmpty(range) &&
|
|
285
|
+
opensCompletion(this.language.editor.textInRange({ start: { line: range.start.line, character: 0 }, end: range.start }), text)) {
|
|
286
|
+
this.close();
|
|
287
|
+
this.beginRequest({ triggerKind: 1 }, START_DELAY_MS);
|
|
288
|
+
}
|
|
284
289
|
else if (this.isOpen) {
|
|
285
290
|
if (text === '' || typedIdentifier) {
|
|
286
291
|
this.refilter();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adecore/editor-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Language-enabled editors, feature coordination and React popups over injected language services.",
|
|
6
6
|
"license": "FSL-1.1-MIT",
|
|
@@ -57,9 +57,9 @@
|
|
|
57
57
|
"test": "bun test --conditions=source"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@adecore/editor": "0.
|
|
61
|
-
"@adecore/lsp": "0.
|
|
62
|
-
"@adecore/merge": "0.
|
|
60
|
+
"@adecore/editor": "0.18.1",
|
|
61
|
+
"@adecore/lsp": "0.18.1",
|
|
62
|
+
"@adecore/merge": "0.18.1",
|
|
63
63
|
"zustand": "^5.0.15",
|
|
64
64
|
"lucide-react": "^1.47.0",
|
|
65
65
|
"react-markdown": "^10.1.0",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"remark-breaks": "^4.0.0"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@adecore/ui": "^0.
|
|
70
|
+
"@adecore/ui": "^0.18.1",
|
|
71
71
|
"react": "^19.3.0",
|
|
72
72
|
"react-dom": "^19.3.0",
|
|
73
73
|
"i18next": "^26.4.2",
|
package/src/completion-model.ts
CHANGED
|
@@ -29,6 +29,22 @@ export function identifierPrefix(before: string): string {
|
|
|
29
29
|
return lastPrefix;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
const OPENS_VALUE =
|
|
33
|
+
/(?:[-=!<>&|?+*/%^:,]|(?:^|[^\p{L}\p{N}_$])(?:return|new|case|in|of|instanceof|typeof|keyof|await|yield|throw|extends|implements|as|is|not|and|or|echo|print|use|import|from|clone))$/u;
|
|
34
|
+
const NOT_A_VALUE = /(?:\+\+|--|\/\/|\/\*\*?|^\s*[-+*])$/;
|
|
35
|
+
|
|
36
|
+
/*
|
|
37
|
+
* Whether `text`, typed after `before` on its line, puts the caret where a value or a name comes next, so the list
|
|
38
|
+
* opens without a word typed: an opening bracket, or a space after an operator, a comma or a keyword. A comment
|
|
39
|
+
* opener, a list marker and `++` or `--` open nothing.
|
|
40
|
+
*/
|
|
41
|
+
export function opensCompletion(before: string, text: string): boolean {
|
|
42
|
+
if (text === '(' || text === '()' || text === '[' || text === '[]') {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return text === ' ' && OPENS_VALUE.test(before) && !NOT_A_VALUE.test(before);
|
|
46
|
+
}
|
|
47
|
+
|
|
32
48
|
export interface MatchDetail {
|
|
33
49
|
/* Lower is better. */
|
|
34
50
|
readonly score: number;
|
package/src/completion.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
itemsOf,
|
|
11
11
|
matchedCharacters,
|
|
12
12
|
mirroredInsertions,
|
|
13
|
+
opensCompletion,
|
|
13
14
|
prefixFor,
|
|
14
15
|
qualifiersOf,
|
|
15
16
|
rankCompletions,
|
|
@@ -312,6 +313,12 @@ export class CompletionFeature {
|
|
|
312
313
|
if (text.length > 0 && triggers.includes(last) && text.length === 1) {
|
|
313
314
|
this.close();
|
|
314
315
|
this.beginRequest({ triggerKind: 2, triggerCharacter: last }, 0);
|
|
316
|
+
} else if (
|
|
317
|
+
isEmpty(range) &&
|
|
318
|
+
opensCompletion(this.language.editor.textInRange({ start: { line: range.start.line, character: 0 }, end: range.start }), text)
|
|
319
|
+
) {
|
|
320
|
+
this.close();
|
|
321
|
+
this.beginRequest({ triggerKind: 1 }, START_DELAY_MS);
|
|
315
322
|
} else if (this.isOpen) {
|
|
316
323
|
if (text === '' || typedIdentifier) {
|
|
317
324
|
this.refilter();
|