opencode-quotes-plugin 1.1.0 → 1.2.0
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 +6 -4
- package/package.json +26 -1
- package/quotes.ts +1 -1
- package/tui.tsx +88 -31
package/README.md
CHANGED
|
@@ -8,10 +8,12 @@ A motivational quotes plugin for OpenCode.
|
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Run:
|
|
12
|
+
```bash
|
|
13
|
+
opencode plugin opencode-quotes-plugin -g
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This will install the plugin globally.
|
|
15
17
|
|
|
16
18
|
## Usage
|
|
17
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-quotes-plugin",
|
|
3
|
-
"
|
|
3
|
+
"description": "A motivational quotes plugin for OpenCode",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"opencode",
|
|
6
|
+
"opencode-cli",
|
|
7
|
+
"opencode-ai",
|
|
8
|
+
"opentui",
|
|
9
|
+
"plugin",
|
|
10
|
+
"motivational",
|
|
11
|
+
"inspirational",
|
|
12
|
+
"motivation",
|
|
13
|
+
"inspiration",
|
|
14
|
+
"quotes",
|
|
15
|
+
"opentui",
|
|
16
|
+
"openai",
|
|
17
|
+
"codex",
|
|
18
|
+
"anthropic",
|
|
19
|
+
"claude-code",
|
|
20
|
+
"claude",
|
|
21
|
+
"gemini",
|
|
22
|
+
"copilot"
|
|
23
|
+
],
|
|
24
|
+
"version": "1.2.0",
|
|
4
25
|
"type": "module",
|
|
5
26
|
"exports": {
|
|
6
27
|
"./tui": {
|
|
@@ -30,5 +51,9 @@
|
|
|
30
51
|
"@types/bun": "latest",
|
|
31
52
|
"solid-js": "^1.9.12",
|
|
32
53
|
"typescript": "^5.9.3"
|
|
54
|
+
},
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/aerovato/opencode-quotes-plugin"
|
|
33
58
|
}
|
|
34
59
|
}
|
package/quotes.ts
CHANGED
|
@@ -22,7 +22,7 @@ export const QUOTES = [
|
|
|
22
22
|
"Energy and persistence conquer all things. — Benjamin Franklin",
|
|
23
23
|
"If you can't fly then run, if you can't run then walk, if you can't walk then crawl. But whatever you do, you have to keep moving forward. — Martin Luther King Jr.",
|
|
24
24
|
"You just can't beat the person who never gives up. — Babe Ruth",
|
|
25
|
-
"We choose to go to the moon ...,
|
|
25
|
+
"We choose to go to the moon ..., because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too. — John F. Kennedy",
|
|
26
26
|
"Failure is simply the opportunity to begin again, this time more intelligently. — Henry Ford",
|
|
27
27
|
"The impediment to action advances action. What stands in the way becomes the way. — Marcus Aurelius",
|
|
28
28
|
"Difficulties strengthen the mind, as labor does the body. — Seneca",
|
package/tui.tsx
CHANGED
|
@@ -1,46 +1,103 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type {
|
|
4
|
+
TuiPlugin,
|
|
5
|
+
TuiPluginModule,
|
|
6
|
+
TuiThemeCurrent,
|
|
7
|
+
} from "@opencode-ai/plugin/tui";
|
|
8
|
+
import { createMemo, For, Show } from "solid-js";
|
|
5
9
|
|
|
6
|
-
import { QUOTES } from "./quotes"
|
|
10
|
+
import { QUOTES } from "./quotes";
|
|
11
|
+
import { TextAttributes } from "@opentui/core";
|
|
12
|
+
import { useTerminalDimensions } from "@opentui/solid";
|
|
7
13
|
|
|
8
|
-
|
|
14
|
+
const MAX_QUOTES_WIDTH = 66;
|
|
15
|
+
|
|
16
|
+
function wordWrap(text: string, maxWidth: number): string[] {
|
|
17
|
+
const words = text.split(" ");
|
|
18
|
+
if (words.length === 0) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const totalLen = text.length;
|
|
22
|
+
const targetCharsPerLine = Math.ceil(
|
|
23
|
+
totalLen / Math.ceil(totalLen / maxWidth),
|
|
24
|
+
);
|
|
25
|
+
const lines: string[] = [];
|
|
26
|
+
let wordIndex = 0;
|
|
27
|
+
let accumulatedWidth = 0;
|
|
28
|
+
|
|
29
|
+
while (wordIndex < words.length) {
|
|
30
|
+
let capacity = Math.min(
|
|
31
|
+
targetCharsPerLine + accumulatedWidth + (wordIndex === 0 ? 4 : 0),
|
|
32
|
+
maxWidth,
|
|
33
|
+
);
|
|
34
|
+
let line = words[wordIndex]!;
|
|
35
|
+
wordIndex++;
|
|
36
|
+
while (wordIndex < words.length) {
|
|
37
|
+
const test = line + " " + words[wordIndex]!;
|
|
38
|
+
if (test.length <= capacity) {
|
|
39
|
+
line = test;
|
|
40
|
+
wordIndex++;
|
|
41
|
+
} else {
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
lines.push(line);
|
|
46
|
+
accumulatedWidth = capacity - line.length;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return lines;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function Quotes(props: { theme: TuiThemeCurrent }) {
|
|
9
53
|
const quote = QUOTES[Math.floor(Math.random() * QUOTES.length)]!;
|
|
10
|
-
const split = quote.split("—");
|
|
11
|
-
const author = split.at(-1)?.trim();
|
|
54
|
+
const split = quote.split("—");
|
|
55
|
+
const author = split.at(-1)?.trim() || "";
|
|
12
56
|
const text = split.slice(0, -1).join("—").trim();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
57
|
+
|
|
58
|
+
const dimensions = useTerminalDimensions();
|
|
59
|
+
const lines = createMemo(() =>
|
|
60
|
+
wordWrap(text, Math.min(MAX_QUOTES_WIDTH, dimensions().width - 8)),
|
|
61
|
+
);
|
|
16
62
|
|
|
17
63
|
return (
|
|
18
|
-
<box
|
|
19
|
-
<
|
|
20
|
-
{
|
|
21
|
-
|
|
64
|
+
<box width="100%" flexDirection="column">
|
|
65
|
+
<For each={lines()}>
|
|
66
|
+
{line => (
|
|
67
|
+
<text alignSelf="center" style={{ fg: props.theme.text }}>
|
|
68
|
+
{line}
|
|
69
|
+
</text>
|
|
70
|
+
)}
|
|
71
|
+
</For>
|
|
22
72
|
<text
|
|
23
|
-
alignSelf={
|
|
24
|
-
|
|
73
|
+
alignSelf={"center"}
|
|
74
|
+
attributes={TextAttributes.DIM}
|
|
75
|
+
style={{ fg: props.theme.accent }}
|
|
25
76
|
>
|
|
26
|
-
|
|
77
|
+
<em>- {author}</em>
|
|
27
78
|
</text>
|
|
28
79
|
</box>
|
|
29
|
-
)
|
|
80
|
+
);
|
|
30
81
|
}
|
|
31
82
|
|
|
32
83
|
function View(props: { show: boolean; theme: TuiThemeCurrent }) {
|
|
33
84
|
return (
|
|
34
|
-
<box
|
|
85
|
+
<box
|
|
86
|
+
minHeight={4}
|
|
87
|
+
width="100%"
|
|
88
|
+
maxWidth={MAX_QUOTES_WIDTH}
|
|
89
|
+
alignItems="center"
|
|
90
|
+
paddingY={2}
|
|
91
|
+
>
|
|
35
92
|
<Show when={props.show}>
|
|
36
|
-
<
|
|
93
|
+
<Quotes theme={props.theme} />
|
|
37
94
|
</Show>
|
|
38
95
|
</box>
|
|
39
|
-
)
|
|
96
|
+
);
|
|
40
97
|
}
|
|
41
98
|
|
|
42
|
-
const tui: TuiPlugin = async
|
|
43
|
-
api.plugins.deactivate("internal:home-tips")
|
|
99
|
+
const tui: TuiPlugin = async api => {
|
|
100
|
+
api.plugins.deactivate("internal:home-tips");
|
|
44
101
|
|
|
45
102
|
api.command.register(() => [
|
|
46
103
|
{
|
|
@@ -50,22 +107,22 @@ const tui: TuiPlugin = async (api) => {
|
|
|
50
107
|
category: "System",
|
|
51
108
|
hidden: api.route.current.name !== "home",
|
|
52
109
|
onSelect() {
|
|
53
|
-
api.kv.set("tips_hidden", !api.kv.get("tips_hidden", false))
|
|
54
|
-
api.ui.dialog.clear()
|
|
110
|
+
api.kv.set("tips_hidden", !api.kv.get("tips_hidden", false));
|
|
111
|
+
api.ui.dialog.clear();
|
|
55
112
|
},
|
|
56
113
|
},
|
|
57
|
-
])
|
|
114
|
+
]);
|
|
58
115
|
|
|
59
116
|
api.slots.register({
|
|
60
117
|
order: 100,
|
|
61
118
|
slots: {
|
|
62
119
|
home_bottom() {
|
|
63
|
-
const hidden = createMemo(() => api.kv.get("tips_hidden", false))
|
|
64
|
-
const show = createMemo(() => !hidden())
|
|
65
|
-
return <View show={show()} theme={api.theme.current}
|
|
120
|
+
const hidden = createMemo(() => api.kv.get("tips_hidden", false));
|
|
121
|
+
const show = createMemo(() => !hidden());
|
|
122
|
+
return <View show={show()} theme={api.theme.current} />;
|
|
66
123
|
},
|
|
67
124
|
},
|
|
68
|
-
})
|
|
69
|
-
}
|
|
125
|
+
});
|
|
126
|
+
};
|
|
70
127
|
|
|
71
|
-
export default { id: "opencode-quotes-plugin", tui } satisfies TuiPluginModule
|
|
128
|
+
export default { id: "opencode-quotes-plugin", tui } satisfies TuiPluginModule;
|