@oh-my-pi/pi-tui 18.1.10 → 18.1.12
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/dist/types/autocomplete.d.ts +7 -0
- package/dist/types/mouse.d.ts +6 -1
- package/package.json +3 -3
- package/src/autocomplete.ts +14 -2
- package/src/components/editor.ts +9 -4
- package/src/mouse.ts +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.1.12] - 2026-09-06
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Avoid inserting a trailing space when auto-completing directory paths with `@`, and keep autocomplete open when accepting a directory with Tab or Enter.
|
|
10
|
+
- Horizontal wheel reports (the sideways drift of a two-finger trackpad scroll) no longer decode as a vertical wheel direction, so fullscreen selectors such as `/copy` and the rewind picker stop jumping up and back down at the end of a scroll gesture.
|
|
11
|
+
|
|
5
12
|
## [18.1.9] - 2026-09-04
|
|
6
13
|
|
|
7
14
|
### Added
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function findLeadingSlashCommandStart(text: string): number | null;
|
|
8
8
|
export declare function findTrailingSlashCommandStart(text: string): number | null;
|
|
9
|
+
/**
|
|
10
|
+
* Whether an autocomplete value represents a directory: trailing slash or
|
|
11
|
+
* backslash, optionally followed by a closing quote for quoted paths.
|
|
12
|
+
* Shared by the provider suffix logic and the editor chain-on-accept
|
|
13
|
+
* behavior so Tab and Enter acceptance stay in sync.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isDirectoryCompletionValue(value: string): boolean;
|
|
9
16
|
export interface AutocompleteItem {
|
|
10
17
|
value: string;
|
|
11
18
|
label: string;
|
package/dist/types/mouse.d.ts
CHANGED
|
@@ -17,7 +17,12 @@ export interface SgrMouseEvent {
|
|
|
17
17
|
row: number;
|
|
18
18
|
/** True for a release report (`m` suffix). */
|
|
19
19
|
release: boolean;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Vertical wheel direction: -1 up, 1 down, null when not a vertical wheel
|
|
22
|
+
* event. Horizontal wheel reports (buttons 66/67, the sideways drift of a
|
|
23
|
+
* two-finger trackpad scroll) are not a direction: treating them as one
|
|
24
|
+
* scrolled the selectors up and back down at the end of a gesture.
|
|
25
|
+
*/
|
|
21
26
|
wheel: -1 | 1 | null;
|
|
22
27
|
/** True when the pointer moved (hover or drag) rather than clicked. */
|
|
23
28
|
motion: boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-tui",
|
|
4
|
-
"version": "18.1.
|
|
4
|
+
"version": "18.1.12",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Stencil Labs, Inc.",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@oh-my-pi/pi-natives": "18.1.
|
|
41
|
-
"@oh-my-pi/pi-utils": "18.1.
|
|
40
|
+
"@oh-my-pi/pi-natives": "18.1.12",
|
|
41
|
+
"@oh-my-pi/pi-utils": "18.1.12"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"kitty-vt-wasm": "^0.2.0"
|
package/src/autocomplete.ts
CHANGED
|
@@ -111,6 +111,16 @@ function parsePathPrefix(prefix: string): { rawPrefix: string; isAtPrefix: boole
|
|
|
111
111
|
return { rawPrefix: prefix, isAtPrefix: false, isQuotedPrefix: false };
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Whether an autocomplete value represents a directory: trailing slash or
|
|
116
|
+
* backslash, optionally followed by a closing quote for quoted paths.
|
|
117
|
+
* Shared by the provider suffix logic and the editor chain-on-accept
|
|
118
|
+
* behavior so Tab and Enter acceptance stay in sync.
|
|
119
|
+
*/
|
|
120
|
+
export function isDirectoryCompletionValue(value: string): boolean {
|
|
121
|
+
return /[\\/]["']?$/.test(value);
|
|
122
|
+
}
|
|
123
|
+
|
|
114
124
|
function buildCompletionValue(
|
|
115
125
|
path: string,
|
|
116
126
|
options: { isDirectory: boolean; isAtPrefix: boolean; isQuotedPrefix: boolean },
|
|
@@ -738,14 +748,16 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
|
738
748
|
beforePrefix = currentLine.slice(0, cursorCol - liveAtPrefix.length);
|
|
739
749
|
}
|
|
740
750
|
// This is a file attachment completion
|
|
741
|
-
const
|
|
751
|
+
const isDirectory = isDirectoryCompletionValue(item.value);
|
|
752
|
+
const suffix = isDirectory ? "" : " ";
|
|
753
|
+
const newLine = `${beforePrefix + item.value}${suffix}${afterCursor}`;
|
|
742
754
|
const newLines = [...lines];
|
|
743
755
|
newLines[cursorLine] = newLine;
|
|
744
756
|
|
|
745
757
|
return {
|
|
746
758
|
lines: newLines,
|
|
747
759
|
cursorLine,
|
|
748
|
-
cursorCol: beforePrefix.length + item.value.length +
|
|
760
|
+
cursorCol: beforePrefix.length + item.value.length + suffix.length,
|
|
749
761
|
};
|
|
750
762
|
}
|
|
751
763
|
|
package/src/components/editor.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type AutocompleteProvider,
|
|
5
5
|
findLeadingSlashCommandStart,
|
|
6
6
|
findTrailingSlashCommandStart,
|
|
7
|
+
isDirectoryCompletionValue,
|
|
7
8
|
midPromptSkillTokenMatches,
|
|
8
9
|
SKILL_NAMESPACE,
|
|
9
10
|
} from "../autocomplete";
|
|
@@ -1467,7 +1468,8 @@ export class Editor implements Component, Focusable {
|
|
|
1467
1468
|
return;
|
|
1468
1469
|
}
|
|
1469
1470
|
if (selected && this.#autocompleteProvider) {
|
|
1470
|
-
const
|
|
1471
|
+
const shouldChainAutocomplete =
|
|
1472
|
+
this.#isSlashCommandNameAutocompleteSelection() || isDirectoryCompletionValue(selected.value);
|
|
1471
1473
|
const result = this.#autocompleteProvider.applyCompletion(
|
|
1472
1474
|
this.#state.lines,
|
|
1473
1475
|
this.#state.cursorLine,
|
|
@@ -1489,8 +1491,8 @@ export class Editor implements Component, Focusable {
|
|
|
1489
1491
|
|
|
1490
1492
|
result.onApplied?.();
|
|
1491
1493
|
|
|
1492
|
-
if (
|
|
1493
|
-
void this.#tryTriggerAutocomplete();
|
|
1494
|
+
if (shouldChainAutocomplete) {
|
|
1495
|
+
queueMicrotask(() => void this.#tryTriggerAutocomplete());
|
|
1494
1496
|
}
|
|
1495
1497
|
}
|
|
1496
1498
|
return;
|
|
@@ -1543,6 +1545,7 @@ export class Editor implements Component, Focusable {
|
|
|
1543
1545
|
} else {
|
|
1544
1546
|
if (selected && this.#autocompleteProvider) {
|
|
1545
1547
|
const shouldChainSlashCommandAutocomplete = this.#isSlashCommandNameAutocompleteSelection();
|
|
1548
|
+
const shouldChainDirectoryCompletion = isDirectoryCompletionValue(selected.value);
|
|
1546
1549
|
const result = this.#autocompleteProvider.applyCompletion(
|
|
1547
1550
|
this.#state.lines,
|
|
1548
1551
|
this.#state.cursorLine,
|
|
@@ -1563,7 +1566,9 @@ export class Editor implements Component, Focusable {
|
|
|
1563
1566
|
}
|
|
1564
1567
|
|
|
1565
1568
|
result.onApplied?.();
|
|
1566
|
-
if (
|
|
1569
|
+
if (shouldChainDirectoryCompletion) {
|
|
1570
|
+
queueMicrotask(() => void this.#tryTriggerAutocomplete());
|
|
1571
|
+
} else if (shouldChainSlashCommandAutocomplete && this.#isCompletedSlashCommandAtCursor()) {
|
|
1567
1572
|
void this.#tryTriggerAutocomplete();
|
|
1568
1573
|
}
|
|
1569
1574
|
}
|
package/src/mouse.ts
CHANGED
|
@@ -18,7 +18,12 @@ export interface SgrMouseEvent {
|
|
|
18
18
|
row: number;
|
|
19
19
|
/** True for a release report (`m` suffix). */
|
|
20
20
|
release: boolean;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Vertical wheel direction: -1 up, 1 down, null when not a vertical wheel
|
|
23
|
+
* event. Horizontal wheel reports (buttons 66/67, the sideways drift of a
|
|
24
|
+
* two-finger trackpad scroll) are not a direction: treating them as one
|
|
25
|
+
* scrolled the selectors up and back down at the end of a gesture.
|
|
26
|
+
*/
|
|
22
27
|
wheel: -1 | 1 | null;
|
|
23
28
|
/** True when the pointer moved (hover or drag) rather than clicked. */
|
|
24
29
|
motion: boolean;
|
|
@@ -38,7 +43,7 @@ export function parseSgrMouse(data: string): SgrMouseEvent | null {
|
|
|
38
43
|
const col = Number(match[2]) - 1;
|
|
39
44
|
const row = Number(match[3]) - 1;
|
|
40
45
|
const release = match[4] === "m";
|
|
41
|
-
const wheel = button & 64 ? ((button & 1 ? 1 : -1) as 1 | -1) : null;
|
|
46
|
+
const wheel = button & 64 && !(button & 2) ? ((button & 1 ? 1 : -1) as 1 | -1) : null;
|
|
42
47
|
const motion = (button & 32) !== 0 && wheel === null;
|
|
43
48
|
const leftClick = !release && wheel === null && !motion && (button & 3) === 0;
|
|
44
49
|
return { button, col, row, release, wheel, motion, leftClick };
|