From 35da574a54cad2f960906ed81ac616a1efc71848 Mon Sep 17 00:00:00 2001
From: 844196 <844196@users.noreply.github.com>
Date: Tue, 22 Jul 2025 01:37:45 +0900
Subject: [PATCH] :boom: (init): Change command interface
---
README.md | 9 +++++----
src/init.ts | 46 ++++++++++++++++++++++++++++++++--------------
src/widget.eta | 33 ++++++++++++++++++++++++++-------
3 files changed, 63 insertions(+), 25 deletions(-)
diff --git a/README.md b/README.md
index 2a06799..d8c78ef 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
wk
-:keyboard: which-key like menu for shell
+:keyboard: which-key like menu for zsh
## :package: Installation
@@ -14,14 +14,15 @@
2. Activate in `$ZDOTDIR/.zshrc`:
```shell
- # Register a widget with the name "_wk_widget", and bind it to the ^G.
- eval "$(wk init --bindkey '^G')"
+ # Bind space as the leader key and comma as the major-leader key.
+ # The major-prefix "m" is used for the major menu.
+ eval "$(wk init --leader ' ' --major-leader ',' --major-prefix 'm')"
```
3. Restart zsh.
> [!TIP]
-> If you want to register only the widget, change it as follows:
+> If you want to register only the widgets, change it as follows:
>
> ```shell
> eval "$(wk init)"
diff --git a/src/init.ts b/src/init.ts
index 45c6485..5e231fd 100644
--- a/src/init.ts
+++ b/src/init.ts
@@ -2,28 +2,46 @@ import WIDGET_TEMPLATE from './widget.eta' with { type: 'text' }
import { Eta } from '@eta-dev/eta'
import { Command } from '@cliffy/command'
+function shellQuote(key: string) {
+ return key === "'" ? `"'"` : `'${key}'`
+}
+
export const initCommand = new Command()
.description('Render the widget for zsh.')
.option(
- '--bindkey ',
- `
- The key to bind the widget to.
- The widget is triggered only when a key is pressed while the prompt buffer is empty.
-
- If you want the widget to be triggered regardless of the state of the prompt buffer, add the --bindkey-global option.
- `,
+ '--leader ',
+ 'Key to trigger the wk.',
+ )
+ .option(
+ '--major-leader ',
+ 'Key to trigger the wk major-prefix menu.',
+ )
+ .option('--major-prefix ', 'Prefix used for entries shown when major-leader is pressed.', {
+ default: 'm',
+ })
+ .option('--bind-global', 'Bind leader and major-leader even when the prompt buffer is not empty.')
+ .example(
+ 'eval "$(wk init)"',
+ 'Register the which-key widget without any key bindings.',
+ )
+ .example(
+ `eval "$(wk init --leader '^G')"`,
+ 'Bind the Ctrl+G as the leader key.',
+ )
+ .example(
+ `eval "$(wk init --leader ' ' --major-leader ',' --major-prefix 'm')"`,
+ `Bind space as the leader key and comma as the major-leader key.
+The major-prefix "m" is used for the major menu.`,
)
- .option('--bindkey-global', 'Whether to bind the widget globally.', { default: false, depends: ['bindkey'] })
- .example('eval "$(wk init)"', 'Register the widget without binding it to a key.')
- .example(`eval "$(wk init --bindkey ',')"`, 'Register the widget and bind it to the key `,`.')
- .example(`eval "$(wk init --bindkey '^G' --bindkey-global)"`, 'Register the widget and bind it to Ctrl-G globally.')
- .action(({ bindkey, bindkeyGlobal }) => {
+ .action(({ leader, majorLeader, majorPrefix, bindGlobal = false }) => {
const eta = new Eta()
const rendered = eta.renderString(WIDGET_TEMPLATE, {
wk_path: Deno.execPath(),
- bindkey,
- bindkeyGlobal,
+ leader: leader === undefined ? undefined : shellQuote(leader),
+ majorLeader: majorLeader === undefined ? undefined : shellQuote(majorLeader),
+ majorPrefix: shellQuote(majorPrefix),
+ bindGlobal,
})
console.log(rendered)
diff --git a/src/widget.eta b/src/widget.eta
index d4cf40c..b82b6f8 100644
--- a/src/widget.eta
+++ b/src/widget.eta
@@ -45,19 +45,38 @@ _wk_widget() {
}
zle -N _wk_widget
-<% if (!it.bindkeyGlobal) { %>
-_wk_or_self_insert() {
+_wk_widget_major() {
+ zle _wk_widget -- --inputs <%~ it.majorPrefix %>
+
+}
+zle -N _wk_widget_major
+
+<% if (it.leader !== undefined) { %>
+<% if (!it.bindGlobal) { %>
+_wk_self_insert_or_wk() {
if [[ -z "$BUFFER" ]]; then
zle _wk_widget
else
zle self-insert
fi
}
-zle -N _wk_or_self_insert
+zle -N _wk_self_insert_or_wk
+<% } %>
+
+bindkey <%~ it.leader %> <%= it.bindGlobal ? '_wk_widget' : '_wk_self_insert_or_wk' %>
+<% } %>
+
+<% if (it.majorLeader !== undefined) { %>
+<% if (!it.bindGlobal) { %>
+_wk_self_insert_or_wk_major() {
+ if [[ -z "$BUFFER" ]]; then
+ zle _wk_widget_major
+ else
+ zle self-insert
+ fi
+}
+zle -N _wk_self_insert_or_wk_major
<% } %>
-<% if (typeof it.bindkey === 'string' && it.bindkey === "'") { %>
-bindkey "'" <%= it.bindkeyGlobal ? '_wk_widget' : '_wk_or_self_insert' %>
-<% } else if (typeof it.bindkey === 'string' && it.bindkey !== '') { %>
-bindkey '<%~ it.bindkey %>' <%= it.bindkeyGlobal ? '_wk_widget' : '_wk_or_self_insert' %>
+bindkey <%~ it.majorLeader %> <%= it.bindGlobal ? '_wk_widget_major' : '_wk_self_insert_or_wk_major' %>
<% } %>