@gajae-code/tui 0.15.5 → 0.15.6
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/CHANGELOG.md +7 -0
- package/package.json +3 -3
- package/src/autocomplete.ts +27 -10
- package/src/components/editor.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.15.6] - 2026-08-30
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Composer file autocomplete now keeps the `@` fuzzy/chosung path reachable from explicit Tab and while Korean query characters are typed, without changing ordinary path-prefix completion.
|
|
10
|
+
|
|
5
11
|
## [0.15.5] - 2026-08-29
|
|
6
12
|
|
|
7
13
|
### Added
|
|
8
14
|
|
|
9
15
|
- `@` fuzzy file search supports Hangul chosung (초성) matching: a bare consonant matches any syllable with that initial, so `@ㅎㄱ` finds `한글.txt`. Literal and full-syllable matches keep ranking above chosung matches.
|
|
16
|
+
|
|
10
17
|
## [0.15.4] - 2026-08-29
|
|
11
18
|
|
|
12
19
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/tui",
|
|
4
|
-
"version": "0.15.
|
|
4
|
+
"version": "0.15.6",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"fmt": "biome format --write ."
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@gajae-code/natives": "0.15.
|
|
40
|
-
"@gajae-code/utils": "0.15.
|
|
39
|
+
"@gajae-code/natives": "0.15.6",
|
|
40
|
+
"@gajae-code/utils": "0.15.6",
|
|
41
41
|
"lru-cache": "11.3.6",
|
|
42
42
|
"marked": "18.0.6"
|
|
43
43
|
},
|
package/src/autocomplete.ts
CHANGED
|
@@ -17,6 +17,7 @@ async function fuzzyFindNative(): Promise<NativeFuzzyFind> {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const PATH_DELIMITERS = new Set([" ", "\t", '"', "'", "="]);
|
|
20
|
+
const MAX_AUTOCOMPLETE_SUGGESTIONS = 100;
|
|
20
21
|
|
|
21
22
|
function isAbsolutePathLike(value: string): boolean {
|
|
22
23
|
return path.isAbsolute(value) || path.win32.isAbsolute(value);
|
|
@@ -408,16 +409,7 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
|
408
409
|
// Check for @ file reference (fuzzy search) - must be after a delimiter or at start
|
|
409
410
|
const atPrefix = this.#extractAtPrefix(textBeforeCursor);
|
|
410
411
|
if (atPrefix) {
|
|
411
|
-
const
|
|
412
|
-
const suggestions =
|
|
413
|
-
rawPrefix.length > 0
|
|
414
|
-
? await this.#getFuzzyFileSuggestions(rawPrefix, { isQuotedPrefix })
|
|
415
|
-
: await this.#getFileSuggestions("@");
|
|
416
|
-
if (suggestions.length === 0 && rawPrefix.length > 0) {
|
|
417
|
-
const fallback = await this.#getFileSuggestions(atPrefix);
|
|
418
|
-
if (fallback.length === 0) return null;
|
|
419
|
-
return { items: fallback, prefix: atPrefix };
|
|
420
|
-
}
|
|
412
|
+
const suggestions = await this.#getAtFileSuggestions(atPrefix);
|
|
421
413
|
if (suggestions.length === 0) return null;
|
|
422
414
|
|
|
423
415
|
return {
|
|
@@ -907,6 +899,23 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
|
907
899
|
}
|
|
908
900
|
}
|
|
909
901
|
|
|
902
|
+
async #getAtFileSuggestions(atPrefix: string): Promise<AutocompleteItem[]> {
|
|
903
|
+
const prefixSuggestions = await this.#getFileSuggestions(atPrefix);
|
|
904
|
+
const { rawPrefix, isQuotedPrefix } = parsePathPrefix(atPrefix);
|
|
905
|
+
if (rawPrefix.length === 0) return prefixSuggestions.slice(0, MAX_AUTOCOMPLETE_SUGGESTIONS);
|
|
906
|
+
|
|
907
|
+
const fuzzySuggestions = await this.#getFuzzyFileSuggestions(rawPrefix, { isQuotedPrefix });
|
|
908
|
+
const seen = new Set(fuzzySuggestions.map(item => item.value));
|
|
909
|
+
return [
|
|
910
|
+
...fuzzySuggestions,
|
|
911
|
+
...prefixSuggestions.filter(item => {
|
|
912
|
+
if (seen.has(item.value)) return false;
|
|
913
|
+
seen.add(item.value);
|
|
914
|
+
return true;
|
|
915
|
+
}),
|
|
916
|
+
].slice(0, MAX_AUTOCOMPLETE_SUGGESTIONS);
|
|
917
|
+
}
|
|
918
|
+
|
|
910
919
|
// Force file completion (called on Tab key) - always returns suggestions
|
|
911
920
|
async getForceFileSuggestions(
|
|
912
921
|
lines: string[],
|
|
@@ -922,6 +931,14 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
|
922
931
|
}
|
|
923
932
|
|
|
924
933
|
// Force extract path prefix - this will always return something
|
|
934
|
+
const atPrefix = this.#extractAtPrefix(textBeforeCursor);
|
|
935
|
+
if (atPrefix !== null) {
|
|
936
|
+
const suggestions = await this.#getAtFileSuggestions(atPrefix);
|
|
937
|
+
if (suggestions.length === 0) return null;
|
|
938
|
+
|
|
939
|
+
return { items: suggestions, prefix: atPrefix };
|
|
940
|
+
}
|
|
941
|
+
|
|
925
942
|
const pathMatch = this.#extractPathPrefix(textBeforeCursor, true);
|
|
926
943
|
if (pathMatch !== null) {
|
|
927
944
|
const suggestions = await this.#getFileSuggestions(pathMatch);
|
package/src/components/editor.ts
CHANGED
|
@@ -1994,7 +1994,7 @@ export class Editor implements Component, Focusable {
|
|
|
1994
1994
|
this.#tryTriggerAutocomplete();
|
|
1995
1995
|
}
|
|
1996
1996
|
// Also auto-trigger when typing letters/path chars in a completable context
|
|
1997
|
-
else if (/[
|
|
1997
|
+
else if (/[\p{L}0-9.\-_/]/u.test(char)) {
|
|
1998
1998
|
const currentLine = this.#state.lines[this.#state.cursorLine] || "";
|
|
1999
1999
|
const textBeforeCursor = currentLine.slice(0, this.#state.cursorCol);
|
|
2000
2000
|
// Check if we're in a slash command or inline slash token
|