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' %> <% } %>