opencode-next-prompt 0.0.4 → 0.0.5
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/README.md +1 -2
- package/dist/index.js +2 -6
- package/dist/ui.d.ts +1 -3
- package/dist/ui.js +1 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ Restart opencode. The package and its dependencies are installed automatically.
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
21
|
- After each reply, a suggested next message appears at the input in gray
|
|
22
|
-
- Press
|
|
22
|
+
- Press the accept key (**↓** by default) while the input is empty to fill it; with text in the input, the key keeps its normal cursor behavior
|
|
23
23
|
- Typing hides the suggestion; clearing the input re-shows it
|
|
24
24
|
|
|
25
25
|
## Config
|
|
@@ -37,7 +37,6 @@ Restart opencode. The package and its dependencies are installed automatically.
|
|
|
37
37
|
| Key | Default | Description |
|
|
38
38
|
|---|---|---|
|
|
39
39
|
| `acceptKey` | `down` | Key to accept the suggestion (only effective while the input is empty) |
|
|
40
|
-
| `position` | `right` | Where the suggestion shows: `left` inside the input; `right` below-right of the input |
|
|
41
40
|
| `timeoutMs` | `20000` | Per-prediction timeout; the suggestion is dropped on timeout |
|
|
42
41
|
|
|
43
42
|
## How it works
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { InputRenderable } from "@opentui/core";
|
|
2
2
|
import { createSuggestionStore } from "./state.js";
|
|
3
3
|
import { createPredictor } from "./predict.js";
|
|
4
|
-
import {
|
|
4
|
+
import { renderSuggestionPlaceholder } from "./ui.js";
|
|
5
5
|
const DEFAULT_OPTIONS = {
|
|
6
6
|
acceptKey: "down",
|
|
7
|
-
position: "right",
|
|
8
7
|
timeoutMs: 20_000,
|
|
9
8
|
};
|
|
10
9
|
const opencodeNextPrompt = async (api, rawOptions) => {
|
|
@@ -118,13 +117,10 @@ const opencodeNextPrompt = async (api, rawOptions) => {
|
|
|
118
117
|
{ key: options.acceptKey, cmd: "next-prompt.accept", preventDefault: false, fallthrough: true },
|
|
119
118
|
],
|
|
120
119
|
});
|
|
121
|
-
const inputEmpty = options.position === "right" ? createInputEmpty(api) : undefined;
|
|
122
120
|
api.slots.register({
|
|
123
121
|
id: "opencode-next-prompt",
|
|
124
122
|
slots: {
|
|
125
|
-
session_prompt_right: (ctx, props) => options.
|
|
126
|
-
? renderSuggestionSlot(ctx, props, store.read, options.acceptKey, inputEmpty)
|
|
127
|
-
: renderSuggestionPlaceholder(api, props, store.read, options.acceptKey),
|
|
123
|
+
session_prompt_right: (ctx, props) => renderSuggestionPlaceholder(api, props, store.read, options.acceptKey),
|
|
128
124
|
},
|
|
129
125
|
});
|
|
130
126
|
};
|
package/dist/ui.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { JSX } from "@opentui/solid";
|
|
2
|
-
import type { TuiPluginApi
|
|
2
|
+
import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
|
|
3
3
|
import type { Accessor } from "solid-js";
|
|
4
4
|
import type { SuggestionState } from "./state.ts";
|
|
5
5
|
export type PromptSlotProps = {
|
|
6
6
|
session_id: string;
|
|
7
7
|
};
|
|
8
8
|
export declare function renderSuggestionPlaceholder(api: TuiPluginApi, props: PromptSlotProps, state: Accessor<SuggestionState>, acceptKey: string): JSX.Element;
|
|
9
|
-
export declare function createInputEmpty(api: TuiPluginApi): Accessor<boolean>;
|
|
10
|
-
export declare function renderSuggestionSlot(ctx: TuiSlotContext, props: PromptSlotProps, state: Accessor<SuggestionState>, acceptKey: string, inputEmpty: Accessor<boolean>): JSX.Element;
|
package/dist/ui.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createEffect, createSignal, onCleanup } from "solid-js";
|
|
1
|
+
import { createEffect, onCleanup } from "solid-js";
|
|
3
2
|
import { InputRenderable, TextareaRenderable } from "@opentui/core";
|
|
4
3
|
const ARROW_KEYS = {
|
|
5
4
|
right: "→",
|
|
@@ -28,37 +27,3 @@ export function renderSuggestionPlaceholder(api, props, state, acceptKey) {
|
|
|
28
27
|
});
|
|
29
28
|
return null;
|
|
30
29
|
}
|
|
31
|
-
export function createInputEmpty(api) {
|
|
32
|
-
const [inputEmpty, setInputEmpty] = createSignal(true);
|
|
33
|
-
const apply = () => {
|
|
34
|
-
const editor = api.renderer.currentFocusedEditor;
|
|
35
|
-
setInputEmpty(editor === null || (!(editor instanceof InputRenderable) && editor.editBuffer.getText() === ""));
|
|
36
|
-
};
|
|
37
|
-
const offs = new Set();
|
|
38
|
-
const subscribe = (editor) => {
|
|
39
|
-
if (!editor)
|
|
40
|
-
return;
|
|
41
|
-
const handler = () => apply();
|
|
42
|
-
editor.editBuffer.on("content-changed", handler);
|
|
43
|
-
editor.editBuffer.on("cursor-changed", handler);
|
|
44
|
-
offs.add(() => {
|
|
45
|
-
editor.editBuffer.off("content-changed", handler);
|
|
46
|
-
editor.editBuffer.off("cursor-changed", handler);
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
api.renderer.on("focused_editor", (current) => {
|
|
50
|
-
offs.forEach((off) => off());
|
|
51
|
-
offs.clear();
|
|
52
|
-
subscribe(current);
|
|
53
|
-
apply();
|
|
54
|
-
});
|
|
55
|
-
subscribe(api.renderer.currentFocusedEditor);
|
|
56
|
-
apply();
|
|
57
|
-
return inputEmpty;
|
|
58
|
-
}
|
|
59
|
-
export function renderSuggestionSlot(ctx, props, state, acceptKey, inputEmpty) {
|
|
60
|
-
const current = state();
|
|
61
|
-
if (current.kind !== "ready" || current.sessionID !== props.session_id || !inputEmpty())
|
|
62
|
-
return null;
|
|
63
|
-
return _jsx("text", { fg: ctx.theme.current.textMuted, children: `[${displayKey(acceptKey)}] ${current.text}` });
|
|
64
|
-
}
|
package/package.json
CHANGED