diff --git a/.github/workflows/panvimdoc.yml b/.github/workflows/panvimdoc.yml index 0094ef4..68b244f 100644 --- a/.github/workflows/panvimdoc.yml +++ b/.github/workflows/panvimdoc.yml @@ -11,13 +11,14 @@ jobs: name: pandoc to vimdoc steps: - uses: actions/checkout@v2 - - uses: kdheepak/panvimdoc@main + - uses: kdheepak/panvimdoc@v4.0.0 with: vimdoc: hydra # The following are all optional pandoc: "README.md" # Input pandoc file version: "NVIM v0.9.4" # Vim version number toc: true # Table of contents + shiftheadinglevelby: -1 - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: "Auto generate docs" diff --git a/README.md b/README.md index bd42460..9b621b5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Hydra.nvim - + -This is the Neovim implementation of the famous [Emacs Hydra](https://github.com/abo-abo/hydra) -package. +This is the Neovim implementation of the famous [Emacs +Hydra](https://github.com/abo-abo/hydra) package. ## Description for Poets @@ -19,336 +19,361 @@ heads can be called in succession with only a short extension. The Hydra is vanquished once Hercules, any binding that isn't the Hydra's head, arrives. Note that Hercules, besides vanquishing the Hydra, will still serve his original purpose, -calling his proper command. This makes the Hydra very seamless. +calling his proper command. This makes the Hydra very seamless. ## Description for Pragmatics Imagine you want to change the size of your current window. Vim allows you to do it with `+`, `-`, `<`, `>` bindings. So, you have to press -`+++<<<...` as many times as you need -(I know about count prefixes, but I was never fond of them). -Hydra allows you to press `` just once and then get access to any `...` bindings -without pressing the prefix again: `+++++--<<<<`. -Or buffer side scrolling: instead of `zlzlzlzlzlzl...` press `zlllllllllhhhl` to freely -scroll buffer left and right. Any key other than bind to a hydra will stop hydra -state and do what they should. +`+++<<<...` as many times as you need (I know about count +prefixes, but I was never fond of them). Hydra allows you to press `` just once and +then get access to any `...` bindings without pressing the prefix again: +`+++++--<<<<`. Or buffer side scrolling: instead of `zlzlzlzlzlzl...` press +`zlllllllllhhhl` to freely scroll buffer left and right. Any key other than bind to +a hydra will stop hydra state and do what they should. Hydra also allows assigning a custom hint to such group of keybindings to allows you an easy glance at what you can do. If you want to quickly understand the concept, you can watch [the original Emacs Hydra video demo](https://www.youtube.com/watch?v=_qZliI1BKzI) - - - - - -* [Sample Hydras](#sample-hydras) - * [Side scroll](#side-scroll) - * [Git submode](#git-submode) - * [Telescope menu](#telescope-menu) - * [Frequently used options](#frequently-used-options) - * [More hydras](#more-hydras) -* [Installation](#installation) -* [How to create hydra](#how-to-create-hydra) - * [`name`](#name) - * [`mode`](#mode) - * [`body`](#body) - * [`config`](#config) - * [`exit`](#exit) - * [`foreign_keys`](#foreign_keys) - * [`color`](#color) - * [More about colors concept](#more-about-colors-concept) - * [Amaranth color](#amaranth-color) - * [Blue and teal colors](#blue-and-teal-colors) - * [Pink color](#pink-color) - * [`buffer`](#buffer) - * [`invoke_on_body`](#invoke_on_body) - * [`desc`](#desc) - * [`on_enter` and `on_exit`](#on_enter-and-on_exit) - * [meta-accessors](#meta-accessors) - * [`on_key`](#on_key) - * [`timeout`](#timeout) - * [`hint`](#hint) - * [Hydra's heads](#hydras-heads) - * [`head`](#head) - * [`rhs`](#rhs) - * [`opts`](#opts) - * [`private`](#private) - * [`exit`](#exit-1) - * [`exit_before`](#exit_before) - * [`on_key`](#on_key-1) - * [`desc`](#desc-1) - * [`expr`, `silent`](#expr-silent) - * [`nowait`](#nowait) - * [`mode`](#mode-1) - * [`hint`](#hint-1) -* [Public methods](#public-methods) -* [Highlight](#highlight) -* [Keymap utility functions](#keymap-utility-functions) -* [Statusline](#statusline) -* [Drawbacks](#drawbacks) -* [How it works under the hood](#how-it-works-under-the-hood) - - -## Sample Hydras - -### Side scroll - -Simple hydra to scroll screen to the side with auto generated hint. - -![](https://user-images.githubusercontent.com/13056013/174493857-eb30b9a9-9078-40f8-a076-bc290acc26bf.png) -```lua -local Hydra = require('hydra') + + +- [Installation](#installation) +- [Creating a New Hydra](#creating-a-new-hydra) +- [Config](#config) +- [Hint](#hint) + - [Hint Configuration](#hint-configuration) +- [Heads](#heads) +- [Colors](#colors) + - [Amaranth](#amaranth) + - [Blue and Teal](#blue-and-teal) + - [Pink](#pink) +- [Hooks](#hooks) + - [Meta Accessors](#meta-accessors) +- [Public methods](#public-methods) +- [Highlights](#highlights) +- [Keymap Utility Functions](#keymap-utility-functions) +- [Statusline](#statusline) +- [Limitations](#limitations) +- [How it works under the hood](#how-it-works-under-the-hood) + + -Hydra({ - name = 'Side scroll', - mode = 'n', - body = 'z', - heads = { - { 'h', '5zh' }, - { 'l', '5zl', { desc = '←/→' } }, - { 'H', 'zH' }, - { 'L', 'zL', { desc = 'half screen ←/→' } }, - } -}) +## Installation + +To install with [lazy.nvim](https://github.com/folke/lazy.nvim) use: + +```lua +{ + "nvimtools/hydra.nvim", + config = function() + -- create hydras in here + end +} ``` -### Git submode +## Creating a New Hydra -A full fledged git "submode". +To create a hydra you need to call Hydra's constructor with a parameters table of the +form: - +```lua +local Hydra = require("hydra") +Hydra({ + -- string? only used in auto-generated hint + name = "Hydra's name", -[Link to the code](https://github.com/nvimtools/hydra.nvim/wiki/Git) + -- string | string[] modes where the hydra exists, same as `vim.keymap.set()` accepts + mode = "n", -![](https://user-images.githubusercontent.com/13056013/175947218-d1b70266-9964-48c9-aaae-75195501ef7e.png) + -- string? key required to activate the hydra, when excluded, you can use + -- Hydra:activate() + body = "o", -### Telescope menu + -- these are explained below + hint = [[ ... ]], + config = { ... }, + heads = { ... }, +}) +``` -You can also create a fancy menu to easy recall seldom used mappings. +The more complex fields are described below: -[Link to the code](https://github.com/nvimtools/hydra.nvim/wiki/Telescope) +- [hint](#hint) +- [config](#config) +- [heads](#heads) -![](https://user-images.githubusercontent.com/13056013/179405895-b5206124-b091-42a4-ba5d-95bbc3e1b61b.png) +## Config +With this table, you can set the behavior of the whole hydra. -### Frequently used options +```lua +config = { + -- see :h hydra-heads + exit = false, -- set the default exit value for each head in the hydra -[Link to the code](https://github.com/nvimtools/hydra.nvim/wiki/Vim-Options) + -- decides what to do when a key which doesn't belong to any head is pressed + -- nil: hydra exits and foreign key behaves normally, as if the hydra wasn't active + -- "warn": hydra stays active, issues a warning and doesn't run the foreign key + -- "run": hydra stays active, runs the foreign key + foreign_keys = nil, -![](https://user-images.githubusercontent.com/13056013/179405898-190c609c-3474-4809-a59b-a11e6da4e4ed.png) + -- see `:h hydra-colors` + color = "red", -- "red" | "amaranth" | "teal" | "pink" + -- define a hydra for the given buffer, pass `true` for current buf + buffer = nil, -### More hydras + -- when true, summon the hydra after pressing only the `body` keys. Normally a head is + -- required + invoke_on_body = false, -You can find more hydras in the [wiki](https://github.com/nvimtools/hydra.nvim/wiki). -Feel free to add your own or edit the existing ones! + -- description used for the body keymap when `invoke_on_body` is true + desc = nil, -- when nil, "[Hydra] .. name" is used -## Installation + -- see :h hydra-hooks + on_enter = nil, -- called when the hydra is activated + on_exit = nil, -- called before the hydra is deactivated + on_key = nil, -- called after every hydra head -To install with [packer](https://github.com/wbthomason/packer.nvim) use: + -- timeout after which the hydra is automatically disabled. Calling any head + -- will refresh the timeout + -- true: timeout set to value of 'timeoutlen' (:h 'timeoutlen') + -- 5000: set to desired number of milliseconds + timeout = false, -- by default hydras wait forever -```lua -use 'nvimtools/hydra.nvim' + -- see :h hydra-hint-hint-configuration + hint = false, +} ``` -To install with [lazy.nvim](https://github.com/folke/lazy.nvim) use: -```lua -require("lazy").setup({"nvimtools/hydra.nvim"}) -``` +## Hint -## How to create hydra +The hint for a hydra can let you know that it's active, and remind you of the hydra's +heads. -To create hydra you need to call Hydra's constructor with input parameters table of the -next form: +The string for the hint is passed directly to the hydra: ```lua -local Hydra = require('hydra') Hydra({ - name = "Hydra's name", - hint = [[...]] -- multiline string - config = {...} - mode = 'n', - body = 'o', - heads = {...}, + hint = [[ some multiline string ]] }) ``` -Each of the fields of this table is described in details below. +By default, a one line hint is generated and displayed in the cmdline. Heads and their +descriptions are placed in the order they were passed into the `heads` table. Heads with +`{opts = {desc = false}}` don't appear in auto-generated hints. -### `name` -`string` (optional) +Values in the hint string are parsed with the following rules: -The name of the hydra. Not necessary, used only in auto-generated hint. +- anything between `_` is considered a head, and will be highlighted with the + corresponding head [color](#colors). +- `^` is treated as an empty char and can be used to help align the hint (normally used + on lines that don't have as many underscores as lines above or below) +- `%{val}` is a dynamic value, a function named `val` is called and its return value + inserted into the hint + - Updated each time a head is called + - Pass these functions to `config.hint.funcs` (discussed below) + - There are built-in functions located here: [this + file](https://github.com/nvimtools/hydra.nvim/blob/main/lua/hydra/hint/vim-options.lua) -### `mode` -`string | string[]`\ -default: `"n"` +**Heads not in the manually created hint, will be automatically added to the bottom of the +hint window, following the same rules as auto-generated hint. You can avoid this with +`{desc = false}`** -Mode or modes in which this hydra will exist. Same format as `vim.keymap.set()` accepts. +### Hint Configuration -### `body` -`string` (optional) +The hint is configured with the `hint` key on the [config](#config) table. You can disable +the hint by setting this value to `false`. -To summon the hydra you need to press in sequence keys corresponds to `body` + any `head`. -For example, if body is `z` and heads are: `a`, `b`, `c`, you can invoke hydra with any of -the `za`, `zb`, `zc` keybindings. +```lua +Hydra({ + config = { + -- either a table like below, or `false` to disable the hint + hint = { + -- "window" | "cmdline" | "statusline" + -- "window" : show hint in a floating window + -- "cmdline" : show hint in the echo area + -- "statusline": show auto-generated hint in the status line + type = "window", -- defaults to "window" if `hint` is passed to the hydra + -- otherwise defaults to "cmdline" + + -- set the position of the hint window. one of: + -- top-left | top | top-right + -- -------------+----------+-------------- + -- middle-left | middle | middle-right + -- -------------+----------+-------------- + -- bottom-left | bottom | bottom-right + position = "bottom", + + -- Offset of the floating window from the nearest editor border + offset = 0, + + -- options passed to `nvim_open_win()`, see :h nvim_open_win() + -- Lets you set border, header, footer, etc etc. + float_opts = { + -- row, col, height, width, relative, and anchor should not be + -- overridden + style = "minimal", + focusable = false, + noautocmd = true, + }, + + -- show the hydras name (or "HYDRA:" if not given a name), at the + -- beginning of an auto-generated hint + show_name = true, + + -- Table from function names to function. Functions should return + -- a string. These functions can be used in hints with %{func_name} + -- more in :h hydra-hint + funcs = {}, + } + } +}) +``` -Hydra without body can only be summoned through `Hydra:activate()` method. +## Heads -### `config` +Each Hydra's head has the form: -`table` +```lua +{ head, rhs, opts } +``` -With this table, you can set the behavior of the whole hydra, which later can be -customized for each head particularly. Below is a list of all options. +Similar to the `vim.keymap.set()` function. ---- +The `head` is the "lhs" of the mapping (given as a string). These are the keys you press +to perform the action. -#### `exit` -`boolean`\ -default: `false`\ -parent table: `config` +The `rhs` is the action that gets performed. It can be a string, function or `nil`. when +nil, the action is a no-op. -The `exit` option (heads can override it) defines what will happen after executing head's -command: +The `opts` table is empty by default. -- `exit = false` (the default) means that the hydra state will continue — you'll still see - the hint and be able to use hydra bindings; -- `exit = true` means that the hydra state will stop. +```lua +opts = { + -- "When the hydra hides, this head does not stick out" + -- Private heads are unreachable outside of the hydra state. + private = false, -#### `foreign_keys` -`"warn" | "run" | nil`\ -default: `nil`\ -parent table: `config` + -- When true, stops the hydra after executing this head + -- NOTE: + -- - All exit heads are private + -- - If no exit head is specified, esc is set by default + exit = false, -The `foreign_keys` option belongs to the body and decides what to do when a key is pressed -that doesn't belong to any head: + -- Like exit, but stops the hydra BEFORE executing the command + exit_before = false, -- `foreign_keys = nil` (the default) means that the hydra state will stop and the foreign - key will do whatever it was supposed to do if there was no hydra state. -- `foreign_keys = "warn"` will not stop the hydra state, but instead will issue a warning - without running the foreign key. -- `foreign_keys = "run"` will not stop the hydra state, and try to run the foreign key. + -- when set to false, config.on_key isn't run after this head + ok_key = true, -#### `color` -`"red" | "amaranth" | "teal" | "pink"`\ -default: `"red"`\ -parent table: `config` + -- string | false - value shown in auto-generated hint. When false, this key + -- doesn't show up in the auto-generated hint + desc = nil, -The `color` option is a shortcut for both `exit` and `foreign_keys` options and aggregates -them in the following way: + -- same as the builtin map options + expr = false, -- :h :map-expression + silent = false, -- :h :map-silent - | color | toggle | - |----------+------------------------------------| - | red | | - | blue | exit = true | - | amaranth | foreign_keys = 'warn' | - | teal | foreign_keys = 'warn', exit = true | - | pink | foreign_keys = 'run' | + -- \/ For Pink Hydras only \/ -- -It's also a trick to make you instantly aware of the current hydra keys that you're about -to press: the keys will be highlighted with the appropriate color. + -- allows binding a key which will immediately perform its action and not wait + -- `timeoutlen` for a possible continuation + nowait = false, -**Note:** The `exit` and `foreign_keys` options are higher priority than `color` option -and can't be overridden by it. I.e, if manually set values of `exit` and `foreign_keys` -options contradict the color option value, then exactly thees values will be taken into -account and for `color` option the matching value will be automatically set + -- Override `mode` for this head + mode = "n", +} +``` + +## Colors + +The `color` option is a shortcut for determining the `exit` and `foreign_keys` options. It +sets them in the following way: -##### More about colors concept +| color | values | +| -------- | ---------------------------------- | +| red | | +| blue | exit = true | +| amaranth | foreign_keys = 'warn' | +| teal | foreign_keys = 'warn', exit = true | +| pink | foreign_keys = 'run' | -Each hydra head has a basic associated color, red or blue, that determines whether or not -the hydra will continue after the head is called: +> [!NOTE] +> The `exit` and `foreign_keys` options are higher priority than the `color` option and +> can't be overridden by it. I.e, if manually set values of `exit` and `foreign_keys` +> contradict the `color` value, then the `color` value is ignored -- red head will execute the command and continue the state -- blue head will execute the command and stop the state +Colors are also used to highlight heads in the hint, so you know how they will behave. -They may have a reddish or a bluish face that isn't exactly red or blue, but that's what -they are underneath. +Each hydra head has a _basic_ associated color, red or blue, that determines whether or +not the hydra will continue after the head is called: -Overall, the hydra body can have one of five variants of the basic colors: amaranth, teal, -pink, red, blue. They (according to basic color) determines the default behavior of -all the heads; and determines what happens when a key that is not associated to a -head is pressed. The following table summarizes the effects of the different colors. +- reddish head will execute the command and continue the state +- blueish head will execute the command and stop the state + +The hydra body can be one of five variants of the basic colors: amaranth, teal, pink, red, +blue. They (according to basic color) determine the default behavior of all the heads; and +determine what happens when a foreign key is pressed. The following table summarizes the +effects of the different colors. | Body Color | Basic color | Executing NON-HEAD | Executing HEAD | -|------------|-------------|-----------------------|----------------| -| amaranth | red | Disallow and Continue | Continue | -| teal | blue | Disallow and Continue | Quit | -| pink | red | Allow and Continue | Continue | -| red | red | Allow and Quit | Continue | -| blue | blue | Allow and Quit | Quit | +| ---------- | ----------- | --------------------- | -------------- | +| amaranth | red | Disallow and Continue | Continue | +| teal | blue | Disallow and Continue | Quit | +| pink | red | Allow and Continue | Continue | +| red | red | Allow and Quit | Continue | +| blue | blue | Allow and Quit | Quit | -##### Amaranth color +### Amaranth -The amaranth color wasn't chosen by accident because it is the variation of the red color, -but it has the sense underneath. According to [Wikipedia](http://en.wikipedia.org/wiki/Amaranth): +The amaranth color wasn't chosen at random just because it is a variation of the color +red. There is some lore — according to +[Wikipedia](http://en.wikipedia.org/wiki/Amaranth): > The word amaranth comes from the Greek word amaranton, meaning "unwilting" (from the -> verb marainesthai, meaning "wilt"). The word was applied to amaranth because it -> did not soon fade and so symbolized immortality. +> verb marainesthai, meaning "wilt"). The word was applied to amaranth because it did not +> soon fade and so symbolized immortality. Hydras with amaranth body are impossible to quit with any binding except a blue head. -##### Blue and teal colors +### Blue and Teal A blue hydra has little sense in Vim since it works exactly like standard Vim multi-key keybinding with addition you can add a custom hint to it. -A teal hydra working the same way, except it blocks all other keys which are not hydra -heads, what can be useful. - -##### Pink color - -Pink hydra is of a different nature. It is a [key-layer](https://github.com/nvimtools/hydra.nvim/tree/main/lua/hydra/layer) -inside, so all keys except overwritten are work as usual. Even `[count]` prefixes. - -#### `buffer` -`true | number`\ -parent table: `config` +A teal hydra works the same way, except it blocks all keys which are not hydra heads, +which can be useful. -Define hydra only for particular buffer. If `true` — the current buffer will be used. +### Pink -#### `invoke_on_body` +Pink hydra is of a different nature. It is +a [key-layer](https://github.com/nvimtools/hydra.nvim/tree/main/lua/hydra/layer) inside, +so all keys except overwritten are work as usual. Even `[count]` prefixes. -`boolean`\ -default: `false`\ -parent table: `config` +## Hooks -By default, to invoke the hydra you need to press in sequence keys corresponds to `body` + -any non-private `head` (about private heads see later). -This option allows you to summon hydra by pressing only the `body` keys. +There are three hooks currently, `on_enter`, `on_exit`, and `on_key`. These fire when +you'd expect, and they're set on a per hydra basis. The `on_enter` function is called in +such a way that gives you access to [meta-accessors](#meta-accessors). -#### `desc` +### Meta Accessors -`string`\ -default: `[Hydra]` + name \ -parent table: `config` - -If you set `invoke_on_body` option, then you can pass here the description for the hydra -body key sequence. - -#### `on_enter` and `on_exit` -parent table: `config` - -Functions that will be called on enter and on exit hydra. - -##### meta-accessors - -Inside the `on_enter` functions the `vim.o`, `vim.go`, `vim.bo` and `vim.wo` -[meta-accessors](https://github.com/nanotee/nvim-lua-guide#using-meta-accessors) -are redefined to work the way you think they should. If you want some option value to be -temporary changed while Hydra is active, you need just set it with one of this -meta-accessor in the `on_enter` function. And that's it. No need to set it back in -`on_exit` function. All other will be done automatically in the backstage. +Inside a function passed as `on_enter`, the `vim.o`, `vim.go`, `vim.bo` and `vim.wo` +[meta-accessors](https://github.com/nanotee/nvim-lua-guide#using-meta-accessors) are +redefined to work the way you think they should. If you want some option value to be +temporary changed while Hydra is active, you need just set it with one of the +meta-accessors in the `on_enter` function... and that's it. No need to set it back in +`on_exit` function. ```lua config = { on_enter = function() print('Hydra enter') - vim.bo.modifiable = false -- temporary set `nomodifiable` while Hydra is active + vim.bo.modifiable = false -- temporarily set `nomodifiable` while Hydra is active end, on_exit = function() print('Hydra exit') @@ -357,258 +382,43 @@ config = { } ``` -#### `on_key` -parent table: `config` - -Function that will be called **after** every hydra head. - -#### `timeout` -`boolean | number` -parent table: `config` - -The `timeout` option set a timer after which the hydra will be automatically -disabled. Calling any head will refresh the timer. (see `:help timeout`, `:help timeoutlen`) - -- `timeout = true` — enable timer and set its to `'timeoutlen'` option value; -- `timeout = false` — disabled timer: the hydra will wait as long as you want, - until you manually cancel it; -- `timeout = 5000` — set timer to desired amount of milliseconds. - -#### `hint` -`table | false` -parent table: `config` - -If `false` — doesn't show hint. Or a table with settings for manually- or auto-generated -hint. - - - **`type`** `"window" | "cmdline" | "statusline"` (default: if hint passed: `"window"`, else: `"cmdline"`) - - - `"window"` — show hint in a floating window; - - - `"cmdline"` — show hint in a echo area; - - - `"statusline"` — show auto-generated hint in the statusline. If hint is passed, - then this value will be ignored and `"window"` will be used. - - - **`position`** `string` (default: `"bottom"`)\ - (valid when `type` is `"window"`) - - Set the position of the hint. Should be one from the next table: - - ``` - top-left | top | top-right - -------------+----------+-------------- - middle-left | middle | middle-right - -------------+----------+-------------- - bottom-left | bottom | bottom-right - ``` - - - **`offset`** `number` (default: `0`)\ - (valid when `type` is `"window"`) - - The offset from the nearest editor border. - - - **`float_opts`** `table` - (valid when `type` is `"window"`) - - Options passed to `nvim_open_win()`, see `:h nvim_open_win()`. This is how you set the - border. Values set here are merged with the following defaults: - - ```lua - { - -- row, col, height, width, relative, and anchor should not be overridden - style = 'minimal', - focusable = false, - noautocmd = true, - } - ``` - - - **`show_name`** `boolean` (default: `true`) - - Show hydras name or `HYDRA:` label at the beginning of an auto-generated hint. - - - **`funcs`** `table` ([built-in functions](https://github.com/nvimtools/hydra.nvim/blob/main/lua/hydra/hint/vim-options.lua)) - - Table where keys are function names and values are functions them self. Each - function should return string. This functions can be required from `hint` with - `%{func_name}` syntax. - -### Hydra's heads - -Each hydra's head has the form: - -```lua -{ head, rhs, opts } -``` - -which is pretty-much compares to the signature of the `vim.keymap.set()` function. - -#### `head` -`string` - -The `lhs` (left-hand-side) of the mapping, i.e the keys you press to call an action. - -#### `rhs` -`string | function | nil` - -Right-hand-side of the mapping. Can be `nil` which means just do nothing, but if you also -want to pass `opts` table, you need to pass `nil` explicitly. - -#### `opts` -`table` - -A table with head options to tune its behavior. - -##### `private` -`boolean` - -When the hydra hides (not active), the private head does not bounce outside. - -I.e., the private head is unreachable outside of the hydra state. - -##### `exit` -`boolean` - -Stop the hydra state after executing a command corresponds to such head. - -**Note:** All exit heads are also private. - -**Note:** If no `exit` head is specified, the `` key will be set by default. - -**Note:** Remind that `rhs` can be `nil`, so the pure escape head looks like this: -```lua -{ '', nil, { exit = true } } -``` - -##### `exit_before` -`boolean` - -Like the previous option, stops hydra state but BEFORE executing a command corresponds to -head. - -##### `on_key` -`boolean` - -If `false` `config.on_key` function won't be executed after this head. - -##### `desc` -`string | false` - -The description that will be shown in the auto-generated part of the hint. -If `false` won't be show in the hint window - -##### `expr`, `silent` -`boolean` - -Built-in map arguments. See: - -- `:help :map-` -- `:help :map-` - -##### `nowait` -`boolean` - -Only relevant for `pink` hydra. For all others will be skipped. The `pink` hydra is -a [layer](https://github.com/nvimtools/hydra.nvim/tree/main/lua/hydra/layer) inside, -and Layer binds its keymaps buffer local, which makes flag `nowait` available. See `:help -:map-`. - -This allows, for example bind exit key: - -```lua -config = { - color = 'pink', -} -... -heads = { - { 'q', nil, { nowait = true } } - ... -} -``` - -which will exit layer, without waiting `&timeoutlen` milliseconds for possible continuation. - -##### `mode` -`string | string[]` - -Overwrite `mode` field for this particular head. -Only relevant for `pink` hydra, for all others will be ignored. - -### `hint` -`multiline string` - -You can create any hint you wish. - - horizontal | vertical -:----------:|:--------: -![](https://user-images.githubusercontent.com/13056013/174572353-ffa1961d-39ab-4b29-be31-f71196fc91cf.png) | ![](https://user-images.githubusercontent.com/13056013/174571913-898b4d23-393b-4bda-8358-44acf5ce9b71.png) - -To highlight a key, just wrap it in underscores. Note that the key must belong to one of -the heads. The key will be highlighted with the color that is appropriate to the behavior -of the key, i.e. if the key will make the hydra exit, the color will be blue. - -To insert an empty character, use `^`. It won't be rendered. The only use of it is to have -your code aligned as nicely as the result. - -You can also create a Lua functions which returns a string and place it in -`config.hint.funcs` table under some key which will be used as a function name. Than -you can require this function from the `hint` wrap its name (key in the table) with -`%{...}`. The result of the function will be inserted in that place in the hint when it -will be shown. And later this function will be called every time when hydra head will be -pressed and the hint will be updated with the function result string. Some functions are -already built-in, you can find them in -[this file](https://github.com/nvimtools/hydra.nvim/blob/main/lua/hydra/hint/vim-options.lua). -You may submit or request some others which you think may be useful. -The using of this feature is shown in [options hydra](https://github.com/nvimtools/hydra.nvim/wiki/Vim-Options). - -If you pass no `hint`, then one line hint will be generated automatically. The keys and -their descriptions will be placed in the order heads were passed in the `heads` table. -Heads with `desc = false` in `opts` table will be skipped. - -Every head that won't be found in the manually created hint, will be automatically added -at the bottom of the hint window according to rules of auto generated hint. - ## Public methods -- `Hydra:activate()` — a public method, which serves to activate hydra programmatically; -- `Hydra:exit()` — exit hydra if it is active. +- `Hydra:activate()` — activate the hydra programmatically +- `Hydra:exit()` — exit the hydra if it is active -## Highlight +## Highlights -Hydra defines next highlight groups with their defaults: +Hydra defines these highlight groups with their defaults colors: -``` -HydraRed #FF5733 -HydraBlue #5EBCF6 -HydraAmaranth #ff1757 -HydraTeal #00a1a1 -HydraPink #ff55de -``` +- `HydraRed` — `fg = #FF5733` +- `HydraBlue` — `fg = #5EBCF6` +- `HydraAmaranth` — `fg = #ff1757` +- `HydraTeal` — `fg = #00a1a1` +- `HydraPink` — `fg = #ff55de` -- `HydraHint` — linked to `NormalFloat`, defines the fore- and background of the hint window; -- `HydraBorder` — linked to `FloatBorder`, defines the fore- and background of the border. +- `HydraHint` — linked to `NormalFloat`, defines the fore- and background of the hint + window; +- `HydraBorder` — linked to `FloatBorder`, defines the fore- and background of the border. - `HydraTitle` — linked to `FloatTitle`, hl for the window title - `HydraFooter` — linked to `FloatFooter`, hl for the window footer (only in nvim 0.10.0+) -## Keymap utility functions +## Keymap Utility Functions -Utility functions to use in keymaps. Can be required from the next table: -```lua -require('hydra.keymap-util') -``` +Utility functions to use in keymaps, required with `require("hydra.keymap-util")` - `cmd(command)` - Get a string and wrap it in ``, ``. I.e.: - ``` - cmd(vsplit) -> "vsplit" + Get a string and wrap it in ``, `` + + ```lua + cmd("vsplit") == "vsplit" ``` - **param:** `command` : `string`\ - **return:** `string` - `pcmd(try_cmd, catch?, catch_cmd?)` Protected `cmd`. Examples explain better: + ``` pcmd("wincmd k", "E11", "close") -> "try | wincmd k | catch /^Vim\%((\a\+)\)\=:E11:/ | close | endtry" @@ -619,15 +429,17 @@ require('hydra.keymap-util') pcmd("close") -> "try | close | catch | endtry" ``` + See: `:help exception-handling` **params:** - * `try_cmd` : `string` - * `catch` : `string` (optional) — String of the form `E` + some digits, like `E12` or `E444`. - * `catch_cmd` : `string` (optional) + - `try_cmd` : `string` + - `catch` : `string` (optional) — String of the form `E` + some digits, like `E12` or + `E444`. + - `catch_cmd` : `string` (optional) - **return:** `string` + **return:** `string` ## Statusline @@ -637,22 +449,25 @@ you to integrate Hydra in your statusline: - `is_active()` — returns `true` if there is an active hydra; - `get_name()` — get the name of an active hydra if it has it; - `get_color()` — get the color of an active hydra; -- `get_hint()` — get an active hydra's statusline hint. Return not `nil` only when +- `get_hint()` — get an active hydra's statusline hint. Return not `nil` only when `config.hint` is set to `false.` -## Drawbacks +## Limitations -`[count]` is not supported in a red, amaranth and teal hydras (see `:help count`). -But supported in pink hydra since it is a [layer](https://github.com/nvimtools/hydra.nvim/tree/main/lua/hydra/layer). +`[count]` is not supported in a red, amaranth and teal hydras (see `:help count`). But +supported in pink hydra since it is +a [layer](https://github.com/nvimtools/hydra.nvim/tree/main/lua/hydra/layer). ## How it works under the hood -You can read about the internal mechanics in the [CONTRIBUTING](https://github.com/nvimtools/hydra.nvim/blob/main/CONTRIBUTING.md) +You can read about the internal mechanics in +[CONTRIBUTING.md](https://github.com/nvimtools/hydra.nvim/blob/main/CONTRIBUTING.md) ## Thanks - [anuvyklack](https://github.com/anuvyklack/) for creating the original hydra.nvim that this is forked from -- [hydra](https://github.com/abo-abo/hydra) for existing +- The original Emacs [hydra](https://github.com/abo-abo/hydra), for the concept this is + based on diff --git a/doc/hydra.txt b/doc/hydra.txt index 18a26a4..0fe22d0 100644 --- a/doc/hydra.txt +++ b/doc/hydra.txt @@ -1,32 +1,37 @@ -*hydra.txt* For NVIM v0.9.4 Last change: 2023 December 28 +*hydra.txt* For NVIM v0.9.4 Last change: 2023 December 31 ============================================================================== Table of Contents *hydra-table-of-contents* -1. Hydra.nvim |hydra-hydra.nvim| - - Description for Poets |hydra-hydra.nvim-description-for-poets| - - Description for Pragmatics |hydra-hydra.nvim-description-for-pragmatics| - - Sample Hydras |hydra-hydra.nvim-sample-hydras| - - Installation |hydra-hydra.nvim-installation| - - How to create hydra |hydra-hydra.nvim-how-to-create-hydra| - - Public methods |hydra-hydra.nvim-public-methods| - - Highlight |hydra-hydra.nvim-highlight| - - Keymap utility functions |hydra-hydra.nvim-keymap-utility-functions| - - Statusline |hydra-hydra.nvim-statusline| - - Drawbacks |hydra-hydra.nvim-drawbacks| - - How it works under the hood |hydra-hydra.nvim-how-it-works-under-the-hood| - - Thanks |hydra-hydra.nvim-thanks| - -============================================================================== -1. Hydra.nvim *hydra-hydra.nvim* - +1. Description for Poets |hydra-description-for-poets| +2. Description for Pragmatics |hydra-description-for-pragmatics| +3. Installation |hydra-installation| +4. Creating a New Hydra |hydra-creating-a-new-hydra| +5. Config |hydra-config| +6. Hint |hydra-hint| + - Hint Configuration |hydra-hint-hint-configuration| +7. Heads |hydra-heads| +8. Colors |hydra-colors| + - Amaranth |hydra-colors-amaranth| + - Blue and Teal |hydra-colors-blue-and-teal| + - Pink |hydra-colors-pink| +9. Hooks |hydra-hooks| + - Meta Accessors |hydra-hooks-meta-accessors| +10. Public methods |hydra-public-methods| +11. Highlights |hydra-highlights| +12. Keymap Utility Functions |hydra-keymap-utility-functions| +13. Statusline |hydra-statusline| +14. Limitations |hydra-limitations| +15. How it works under the hood |hydra-how-it-works-under-the-hood| +16. Thanks |hydra-thanks| This is the Neovim implementation of the famous Emacs Hydra package. -DESCRIPTION FOR POETS *hydra-hydra.nvim-description-for-poets* +============================================================================== +1. Description for Poets *hydra-description-for-poets* Once you summon the Hydra through the prefixed binding (the body + any one head), all heads can be called in succession with only a short extension. @@ -37,7 +42,8 @@ serve his original purpose, calling his proper command. This makes the Hydra very seamless. -DESCRIPTION FOR PRAGMATICS *hydra-hydra.nvim-description-for-pragmatics* +============================================================================== +2. Description for Pragmatics *hydra-description-for-pragmatics* Imagine you want to change the size of your current window. Vim allows you to do it with `+`, `-`, `<`, `>` bindings. So, you have to @@ -55,252 +61,278 @@ allows you an easy glance at what you can do. If you want to quickly understand the concept, you can watch the original Emacs Hydra video demo -- |hydra-sample-hydras| - - |hydra-side-scroll| - - |hydra-git-submode| - - |hydra-telescope-menu| - - |hydra-frequently-used-options| - - |hydra-more-hydras| -- |hydra-installation| -- |hydra-how-to-create-hydra| - - |hydra-`name`| - - |hydra-`mode`| - - |hydra-`body`| - - |hydra-`config`| - - |hydra-`exit`| - - |hydra-`foreign_keys`| - - |hydra-`color`| - - |hydra-more-about-colors-concept| - - |hydra-amaranth-color| - - |hydra-blue-and-teal-colors| - - |hydra-pink-color| - - |hydra-`buffer`| - - |hydra-`invoke_on_body`| - - |hydra-`desc`| - - |hydra-`on_enter`-and-`on_exit`| - - |hydra-meta-accessors| - - |hydra-`on_key`| - - |hydra-`timeout`| - - |hydra-`hint`| - - |hydra-hydra’s-heads| - - |hydra-`head`| - - |hydra-`rhs`| - - |hydra-`opts`| - - |hydra-`private`| - - |hydra-`exit`| - - |hydra-`exit_before`| - - |hydra-`on_key`| - - |hydra-`desc`| - - |hydra-`expr`,-`silent`| - - |hydra-`nowait`| - - |hydra-`mode`| - - |hydra-`hint`| -- |hydra-public-methods| -- |hydra-highlight| -- |hydra-keymap-utility-functions| -- |hydra-statusline| -- |hydra-drawbacks| -- |hydra-how-it-works-under-the-hood| - - -SAMPLE HYDRAS *hydra-hydra.nvim-sample-hydras* - - -SIDE SCROLL ~ - -Simple hydra to scroll screen to the side with auto generated hint. - - - ->lua - local Hydra = require('hydra') - - Hydra({ - name = 'Side scroll', - mode = 'n', - body = 'z', - heads = { - { 'h', '5zh' }, - { 'l', '5zl', { desc = '←/→' } }, - { 'H', 'zH' }, - { 'L', 'zL', { desc = 'half screen ←/→' } }, - } - }) -< - - -GIT SUBMODE ~ - -A full fledged git "submode". - -Link to the code - - - - -TELESCOPE MENU ~ - -You can also create a fancy menu to easy recall seldom used mappings. - -Link to the code - - - - -FREQUENTLY USED OPTIONS ~ - -Link to the code - - - -MORE HYDRAS ~ - -You can find more hydras in the wiki -. Feel free to add your own or -edit the existing ones! - - -INSTALLATION *hydra-hydra.nvim-installation* - -To install with packer use: - ->lua - use 'nvimtools/hydra.nvim' -< +============================================================================== +3. Installation *hydra-installation* To install with lazy.nvim use: >lua - require("lazy").setup({"nvimtools/hydra.nvim"}) + { + "nvimtools/hydra.nvim", + config = function() + -- create hydras in here + end + } < -HOW TO CREATE HYDRA *hydra-hydra.nvim-how-to-create-hydra* +============================================================================== +4. Creating a New Hydra *hydra-creating-a-new-hydra* -To create hydra you need to call Hydra’s constructor with input parameters -table of the next form: +To create a hydra you need to call Hydra’s constructor with a parameters +table of the form: >lua - local Hydra = require('hydra') + local Hydra = require("hydra") Hydra({ + -- string? only used in auto-generated hint name = "Hydra's name", - hint = [[...]] -- multiline string - config = {...} - mode = 'n', - body = 'o', - heads = {...}, + + -- string | string[] modes where the hydra exists, same as `vim.keymap.set()` accepts + mode = "n", + + -- string? key required to activate the hydra, when excluded, you can use + -- Hydra:activate() + body = "o", + + -- these are explained below + hint = [[ ... ]], + config = { ... }, + heads = { ... }, }) < -Each of the fields of this table is described in details below. - - -NAME ~ - -`string` (optional) - -The name of the hydra. Not necessary, used only in auto-generated hint. - +The more complex fields are described below: -MODE ~ +- |hydra-hint| +- |hydra-config| +- |hydra-heads| -`string | string[]` default: `"n"` -Mode or modes in which this hydra will exist. Same format as `vim.keymap.set()` -accepts. +============================================================================== +5. Config *hydra-config* +With this table, you can set the behavior of the whole hydra. -BODY ~ +>lua + config = { + -- see :h hydra-heads + exit = false, -- set the default exit value for each head in the hydra + + -- decides what to do when a key which doesn't belong to any head is pressed + -- nil: hydra exits and foreign key behaves normally, as if the hydra wasn't active + -- "warn": hydra stays active, issues a warning and doesn't run the foreign key + -- "run": hydra stays active, runs the foreign key + foreign_keys = nil, + + -- see `:h hydra-colors` + color = "red", -- "red" | "amaranth" | "teal" | "pink" + + -- define a hydra for the given buffer, pass `true` for current buf + buffer = nil, + + -- when true, summon the hydra after pressing only the `body` keys. Normally a head is + -- required + invoke_on_body = false, + + -- description used for the body keymap when `invoke_on_body` is true + desc = nil, -- when nil, "[Hydra] .. name" is used + + -- see :h hydra-hooks + on_enter = nil, -- called when the hydra is activated + on_exit = nil, -- called before the hydra is deactivated + on_key = nil, -- called after every hydra head + + -- timeout after which the hydra is automatically disabled. Calling any head + -- will refresh the timeout + -- true: timeout set to value of 'timeoutlen' (:h 'timeoutlen') + -- 5000: set to desired number of milliseconds + timeout = false, -- by default hydras wait forever + + -- see :h hydra-hint-hint-configuration + hint = false, + } +< -`string` (optional) -To summon the hydra you need to press in sequence keys corresponds to `body` + -any `head`. For example, if body is `z` and heads are: `a`, `b`, `c`, you can -invoke hydra with any of the `za`, `zb`, `zc` keybindings. +============================================================================== +6. Hint *hydra-hint* -Hydra without body can only be summoned through `Hydra:activate()` method. +The hint for a hydra can let you know that it’s active, and remind you of the +hydra’s heads. +The string for the hint is passed directly to the hydra: -CONFIG ~ +>lua + Hydra({ + hint = [[ some multiline string ]] + }) +< -`table` +By default, a one line hint is generated and displayed in the cmdline. Heads +and their descriptions are placed in the order they were passed into the +`heads` table. Heads with `{opts = {desc = false}}` don’t appear in +auto-generated hints. -With this table, you can set the behavior of the whole hydra, which later can -be customized for each head particularly. Below is a list of all options. +Values in the hint string are parsed with the following rules: ------------------------------------------------------------------------------- +- anything between `_` is considered a head, and will be highlighted with the + corresponding head |hydra-color|. +- `^` is treated as an empty char and can be used to help align the hint (normally used + on lines that don’t have as many underscores as lines above or below) +- `%{val}` is a dynamic value, a function named `val` is called and its return value + inserted into the hint + - Updated each time a head is called + - Pass these functions to `config.hint.funcs` (discussed below) + - There are built-in functions located here: this + file -EXIT +**Heads not in the manually created hint, will be automatically added to the +bottom of the hint window, following the same rules as auto-generated hint. You +can avoid this with {desc = false}** -`boolean` default: `false` parent table: `config` -The `exit` option (heads can override it) defines what will happen after -executing head’s command: +HINT CONFIGURATION *hydra-hint-hint-configuration* -- `exit = false` (the default) means that the hydra state will continue — you’ll still see - the hint and be able to use hydra bindings; -- `exit = true` means that the hydra state will stop. +The hint is configured with the `hint` key on the |hydra-config| table. You can +disable the hint by setting this value to `false`. +>lua + Hydra({ + config = { + -- either a table like below, or `false` to disable the hint + hint = { + -- "window" | "cmdline" | "statusline" + -- "window" : show hint in a floating window + -- "cmdline" : show hint in the echo area + -- "statusline": show auto-generated hint in the status line + type = "window", -- defaults to "window" if `hint` is passed to the hydra + -- otherwise defaults to "cmdline" + + -- set the position of the hint window. one of: + -- top-left | top | top-right + -- -------------+----------+-------------- + -- middle-left | middle | middle-right + -- -------------+----------+-------------- + -- bottom-left | bottom | bottom-right + position = "bottom", + + -- Offset of the floating window from the nearest editor border + offset = 0, + + -- options passed to `nvim_open_win()`, see :h nvim_open_win() + -- Lets you set border, header, footer, etc etc. + float_opts = { + -- row, col, height, width, relative, and anchor should not be + -- overridden + style = "minimal", + focusable = false, + noautocmd = true, + }, + + -- show the hydras name (or "HYDRA:" if not given a name), at the + -- beginning of an auto-generated hint + show_name = true, + + -- Table from function names to function. Functions should return + -- a string. These functions can be used in hints with %{func_name} + -- more in :h hydra-hint + funcs = {}, + } + } + }) +< -FOREIGN_KEYS -`"warn" | "run" | nil` default: `nil` parent table: `config` +============================================================================== +7. Heads *hydra-heads* -The `foreign_keys` option belongs to the body and decides what to do when a key -is pressed that doesn’t belong to any head: +Each Hydra’s head has the form: -- `foreign_keys = nil` (the default) means that the hydra state will stop and the foreign - key will do whatever it was supposed to do if there was no hydra state. -- `foreign_keys = "warn"` will not stop the hydra state, but instead will issue a warning - without running the foreign key. -- `foreign_keys = "run"` will not stop the hydra state, and try to run the foreign key. +>lua + { head, rhs, opts } +< +Similar to the `vim.keymap.set()` function. -COLOR +The `head` is the "lhs" of the mapping (given as a string). These are the keys +you press to perform the action. -`"red" | "amaranth" | "teal" | "pink"` default: `"red"` parent table: `config` +The `rhs` is the action that gets performed. It can be a string, function or +`nil`. when nil, the action is a no-op. -The `color` option is a shortcut for both `exit` and `foreign_keys` options and -aggregates them in the following way: +The `opts` table is empty by default. -> - | color | toggle | - |----------+------------------------------------| - | red | | - | blue | exit = true | - | amaranth | foreign_keys = 'warn' | - | teal | foreign_keys = 'warn', exit = true | - | pink | foreign_keys = 'run' | +>lua + opts = { + -- "When the hydra hides, this head does not stick out" + -- Private heads are unreachable outside of the hydra state. + private = false, + + -- When true, stops the hydra after executing this head + -- NOTE: + -- - All exit heads are private + -- - If no exit head is specified, esc is set by default + exit = false, + + -- Like exit, but stops the hydra BEFORE executing the command + exit_before = false, + + -- when set to false, config.on_key isn't run after this head + ok_key = true, + + -- string | false - value shown in auto-generated hint. When false, this key + -- doesn't show up in the auto-generated hint + desc = nil, + + -- same as the builtin map options + expr = false, -- :h :map-expression + silent = false, -- :h :map-silent + + -- \/ For Pink Hydras only \/ -- + + -- allows binding a key which will immediately perform its action and not wait + -- `timeoutlen` for a possible continuation + nowait = false, + + -- Override `mode` for this head + mode = "n", + } < -It’s also a trick to make you instantly aware of the current hydra keys that -you’re about to press: the keys will be highlighted with the appropriate -color. -**Note:** The `exit` and `foreign_keys` options are higher priority than -`color` option and can’t be overridden by it. I.e, if manually set values of -`exit` and `foreign_keys` options contradict the color option value, then -exactly thees values will be taken into account and for `color` option the -matching value will be automatically set - - -MORE ABOUT COLORS CONCEPT - -Each hydra head has a basic associated color, red or blue, that determines +============================================================================== +8. Colors *hydra-colors* + +The `color` option is a shortcut for determining the `exit` and `foreign_keys` +options. It sets them in the following way: + + color values + ---------- ------------------------------------ + red + blue exit = true + amaranth foreign_keys = ‘warn’ + teal foreign_keys = ‘warn’, exit = true + pink foreign_keys = ‘run’ + + [!NOTE] The `exit` and `foreign_keys` options are higher priority than the + `color` option and can’t be overridden by it. I.e, if manually set values of + `exit` and `foreign_keys` contradict the `color` value, then the `color` value + is ignored +Colors are also used to highlight heads in the hint, so you know how they will +behave. + +Each hydra head has a _basic_ associated color, red or blue, that determines whether or not the hydra will continue after the head is called: -- red head will execute the command and continue the state -- blue head will execute the command and stop the state +- reddish head will execute the command and continue the state +- blueish head will execute the command and stop the state -They may have a reddish or a bluish face that isn’t exactly red or blue, but -that’s what they are underneath. - -Overall, the hydra body can have one of five variants of the basic colors: -amaranth, teal, pink, red, blue. They (according to basic color) determines the -default behavior of all the heads; and determines what happens when a key that -is not associated to a head is pressed. The following table summarizes the -effects of the different colors. +The hydra body can be one of five variants of the basic colors: amaranth, teal, +pink, red, blue. They (according to basic color) determine the default behavior +of all the heads; and determine what happens when a foreign key is pressed. The +following table summarizes the effects of the different colors. Body Color Basic color Executing NON-HEAD Executing HEAD ------------ ------------- ----------------------- ---------------- @@ -310,10 +342,10 @@ effects of the different colors. red red Allow and Quit Continue blue blue Allow and Quit Quit -AMARANTH COLOR +AMARANTH *hydra-colors-amaranth* -The amaranth color wasn’t chosen by accident because it is the variation of -the red color, but it has the sense underneath. According to Wikipedia +The amaranth color wasn’t chosen at random just because it is a variation of +the color red. There is some lore — according to Wikipedia : @@ -324,69 +356,46 @@ Hydras with amaranth body are impossible to quit with any binding except a blue head. -BLUE AND TEAL COLORS +BLUE AND TEAL *hydra-colors-blue-and-teal* A blue hydra has little sense in Vim since it works exactly like standard Vim multi-key keybinding with addition you can add a custom hint to it. -A teal hydra working the same way, except it blocks all other keys which are -not hydra heads, what can be useful. +A teal hydra works the same way, except it blocks all keys which are not hydra +heads, which can be useful. -PINK COLOR +PINK *hydra-colors-pink* Pink hydra is of a different nature. It is a key-layer inside, so all keys except overwritten are work as usual. Even `[count]` prefixes. -BUFFER - -`true | number` parent table: `config` - -Define hydra only for particular buffer. If `true` — the current buffer will -be used. - - -INVOKE_ON_BODY - -`boolean` default: `false` parent table: `config` - -By default, to invoke the hydra you need to press in sequence keys corresponds -to `body` + any non-private `head` (about private heads see later). This option -allows you to summon hydra by pressing only the `body` keys. - - -DESC - -`string` default: `[Hydra]` + name parent table: `config` - -If you set `invoke_on_body` option, then you can pass here the description for -the hydra body key sequence. - - -ON_ENTER AND ON_EXIT - -parent table: `config` +============================================================================== +9. Hooks *hydra-hooks* -Functions that will be called on enter and on exit hydra. +There are three hooks currently, `on_enter`, `on_exit`, and `on_key`. These +fire when you’d expect, and they’re set on a per hydra basis. The +`on_enter` function is called in such a way that gives you access to +|hydra-meta-accessors|. -META-ACCESSORS +META ACCESSORS *hydra-hooks-meta-accessors* -Inside the `on_enter` functions the `vim.o`, `vim.go`, `vim.bo` and `vim.wo` -meta-accessors -are redefined to work the way you think they should. If you want some option -value to be temporary changed while Hydra is active, you need just set it with -one of this meta-accessor in the `on_enter` function. And that’s it. No need -to set it back in `on_exit` function. All other will be done automatically in -the backstage. +Inside a function passed as `on_enter`, the `vim.o`, `vim.go`, `vim.bo` and +`vim.wo` meta-accessors + are redefined +to work the way you think they should. If you want some option value to be +temporary changed while Hydra is active, you need just set it with one of the +meta-accessors in the `on_enter` function… and that’s it. No need to set it +back in `on_exit` function. >lua config = { on_enter = function() print('Hydra enter') - vim.bo.modifiable = false -- temporary set `nomodifiable` while Hydra is active + vim.bo.modifiable = false -- temporarily set `nomodifiable` while Hydra is active end, on_exit = function() print('Hydra exit') @@ -396,281 +405,43 @@ the backstage. < -ON_KEY - -parent table: `config` - -Function that will be called **after** every hydra head. - - -TIMEOUT - -`boolean | number` parent table: `config` - -The `timeout` option set a timer after which the hydra will be automatically -disabled. Calling any head will refresh the timer. (see `:help timeout`, `:help -timeoutlen`) - -- `timeout = true` — enable timer and set its to `'timeoutlen'` option value; -- `timeout = false` — disabled timer: the hydra will wait as long as you want, - until you manually cancel it; -- `timeout = 5000` — set timer to desired amount of milliseconds. - - -HINT - -`table | false` parent table: `config` - -If `false` — doesn’t show hint. Or a table with settings for manually- or -auto-generated hint. - -- **type** `"window" | "cmdline" | "statusline"` (default: if hint passed: - `"window"`, else: `"cmdline"`) - - `"window"` — show hint in a floating window; - - `"cmdline"` — show hint in a echo area; - - `"statusline"` — show auto-generated hint in the statusline. If hint is - passed, then this value will be ignored and `"window"` will be used. -- **position** `string` (default: `"bottom"`) (valid when `type` is `"window"`) - Set the position of the hint. Should be one from the next table: - > - top-left | top | top-right - -------------+----------+-------------- - middle-left | middle | middle-right - -------------+----------+-------------- - bottom-left | bottom | bottom-right - < -- **offset** `number` (default: `0`) (valid when `type` is `"window"`) - The offset from the nearest editor border. -- **float_opts** `table` (valid when `type` is `"window"`) - Options passed to `nvim_open_win()`, see |nvim_open_win()|. This is how you set - the border. Values set here are merged with the following defaults: - >lua - { - -- row, col, height, width, relative, and anchor should not be overridden - style = 'minimal', - focusable = false, - noautocmd = true, - } - < -- **show_name** `boolean` (default: `true`) - Show hydras name or `HYDRA:` label at the beginning of an auto-generated hint. -- **funcs** `table` (built-in functions - ) - Table where keys are function names and values are functions them self. Each - function should return string. This functions can be required from `hint` with - `%{func_name}` syntax. - - -HYDRA’S HEADS ~ - -Each hydra’s head has the form: - ->lua - { head, rhs, opts } -< - -which is pretty-much compares to the signature of the `vim.keymap.set()` -function. - - -HEAD - -`string` - -The `lhs` (left-hand-side) of the mapping, i.e the keys you press to call an -action. - - -RHS - -`string | function | nil` - -Right-hand-side of the mapping. Can be `nil` which means just do nothing, but -if you also want to pass `opts` table, you need to pass `nil` explicitly. - - -OPTS - -`table` - -A table with head options to tune its behavior. - - -PRIVATE - -`boolean` - -When the hydra hides (not active), the private head does not bounce outside. -I.e., the private head is unreachable outside of the hydra state. - - -EXIT - -`boolean` - -Stop the hydra state after executing a command corresponds to such head. - -**Note:** All exit heads are also private. - -**Note:** If no `exit` head is specified, the `` key will be set by -default. - -**Note:** Remind that `rhs` can be `nil`, so the pure escape head looks like -this: - ->lua - { '', nil, { exit = true } } -< - - -EXIT_BEFORE - -`boolean` - -Like the previous option, stops hydra state but BEFORE executing a command -corresponds to head. - - -ON_KEY - -`boolean` - -If `false` `config.on_key` function won’t be executed after this head. - - -DESC - -`string | false` - -The description that will be shown in the auto-generated part of the hint. If -`false` won’t be show in the hint window - - -EXPR, SILENT - -`boolean` - -Built-in map arguments. See: - -- `:help :map-` -- `:help :map-` - - -NOWAIT - -`boolean` - -Only relevant for `pink` hydra. For all others will be skipped. The `pink` -hydra is a layer - inside, and -Layer binds its keymaps buffer local, which makes flag `nowait` available. See -`:help :map-`. - -This allows, for example bind exit key: - ->lua - config = { - color = 'pink', - } - ... - heads = { - { 'q', nil, { nowait = true } } - ... - } -< - -which will exit layer, without waiting `&timeoutlen` milliseconds for possible -continuation. - - -MODE - -`string | string[]` - -Overwrite `mode` field for this particular head. Only relevant for `pink` -hydra, for all others will be ignored. - - -HINT ~ - -`multiline string` - -You can create any hint you wish. - - ----------------------------------------------------------------------- - horizontal vertical - -------------------------------------- -------------------------------- - [] [] - - ----------------------------------------------------------------------- -To highlight a key, just wrap it in underscores. Note that the key must belong -to one of the heads. The key will be highlighted with the color that is -appropriate to the behavior of the key, i.e. if the key will make the hydra -exit, the color will be blue. - -To insert an empty character, use `^`. It won’t be rendered. The only use of -it is to have your code aligned as nicely as the result. - -You can also create a Lua functions which returns a string and place it in -`config.hint.funcs` table under some key which will be used as a function name. -Than you can require this function from the `hint` wrap its name (key in the -table) with `%{...}`. The result of the function will be inserted in that place -in the hint when it will be shown. And later this function will be called every -time when hydra head will be pressed and the hint will be updated with the -function result string. Some functions are already built-in, you can find them -in this file -. -You may submit or request some others which you think may be useful. The using -of this feature is shown in options hydra -. - -If you pass no `hint`, then one line hint will be generated automatically. The -keys and their descriptions will be placed in the order heads were passed in -the `heads` table. Heads with `desc = false` in `opts` table will be skipped. - -Every head that won’t be found in the manually created hint, will be -automatically added at the bottom of the hint window according to rules of auto -generated hint. - - -PUBLIC METHODS *hydra-hydra.nvim-public-methods* - -- `Hydra:activate()` — a public method, which serves to activate hydra programmatically; -- `Hydra:exit()` — exit hydra if it is active. - - -HIGHLIGHT *hydra-hydra.nvim-highlight* +============================================================================== +10. Public methods *hydra-public-methods* -Hydra defines next highlight groups with their defaults: +- `Hydra:activate()` — activate the hydra programmatically +- `Hydra:exit()` — exit the hydra if it is active -> - HydraRed #FF5733 - HydraBlue #5EBCF6 - HydraAmaranth #ff1757 - HydraTeal #00a1a1 - HydraPink #ff55de -< -- `HydraHint` — linked to `NormalFloat`, defines the fore- and background of the hint window; -- `HydraBorder` — linked to `FloatBorder`, defines the fore- and background of the border. +============================================================================== +11. Highlights *hydra-highlights* + +Hydra defines these highlight groups with their defaults colors: + +- `HydraRed` — `fg = #FF5733` +- `HydraBlue` — `fg = #5EBCF6` +- `HydraAmaranth` — `fg = #ff1757` +- `HydraTeal` — `fg = #00a1a1` +- `HydraPink` — `fg = #ff55de` +- `HydraHint` — linked to `NormalFloat`, defines the fore- and background of + the hint window; +- `HydraBorder` — linked to `FloatBorder`, defines the fore- and background of + the border. - `HydraTitle` — linked to `FloatTitle`, hl for the window title -- `HydraFooter` — linked to `FloatFooter`, hl for the window footer (only in nvim 0.10.0+) +- `HydraFooter` — linked to `FloatFooter`, hl for the window footer (only in + nvim 0.10.0+) -KEYMAP UTILITY FUNCTIONS *hydra-hydra.nvim-keymap-utility-functions* +============================================================================== +12. Keymap Utility Functions *hydra-keymap-utility-functions* -Utility functions to use in keymaps. Can be required from the next table: - ->lua - require('hydra.keymap-util') -< +Utility functions to use in keymaps, required with +`require("hydra.keymap-util")` - `cmd(command)` - Get a string and wrap it in ``, ``. I.e.: - > - cmd(vsplit) -> "vsplit" + Get a string and wrap it in ``, `` + >lua + cmd("vsplit") == "vsplit" < - **param:** `command` : `string` **return:** `string` - `pcmd(try_cmd, catch?, catch_cmd?)` Protected `cmd`. Examples explain better: > @@ -686,12 +457,14 @@ Utility functions to use in keymaps. Can be required from the next table: See: `:help exception-handling` **params:** - `try_cmd` : `string` - - `catch` : `string` (optional) — String of the form `E` + some digits, like `E12` or `E444`. + - `catch` : `string` (optional) — String of the form `E` + some digits, like `E12` or + `E444`. - `catch_cmd` : `string` (optional) **return:** `string` -STATUSLINE *hydra-hydra.nvim-statusline* +============================================================================== +13. Statusline *hydra-statusline* In the statusline module `require('hydra.statusline')` there are functions that can help you to integrate Hydra in your statusline: @@ -703,32 +476,28 @@ can help you to integrate Hydra in your statusline: `config.hint` is set to `false.` -DRAWBACKS *hydra-hydra.nvim-drawbacks* +============================================================================== +14. Limitations *hydra-limitations* `[count]` is not supported in a red, amaranth and teal hydras (see `:help count`). But supported in pink hydra since it is a layer . -HOW IT WORKS UNDER THE HOOD *hydra-hydra.nvim-how-it-works-under-the-hood* +============================================================================== +15. How it works under the hood *hydra-how-it-works-under-the-hood* -You can read about the internal mechanics in the CONTRIBUTING +You can read about the internal mechanics in CONTRIBUTING.md -THANKS *hydra-hydra.nvim-thanks* +============================================================================== +16. Thanks *hydra-thanks* - anuvyklack for creating the original hydra.nvim that this is forked from -- hydra for existing - -============================================================================== -2. Links *hydra-links* - -1. **: https://user-images.githubusercontent.com/13056013/174493857-eb30b9a9-9078-40f8-a076-bc290acc26bf.png -2. **: https://user-images.githubusercontent.com/13056013/175947218-d1b70266-9964-48c9-aaae-75195501ef7e.png -3. **: https://user-images.githubusercontent.com/13056013/179405895-b5206124-b091-42a4-ba5d-95bbc3e1b61b.png -4. **: https://user-images.githubusercontent.com/13056013/179405898-190c609c-3474-4809-a59b-a11e6da4e4ed.png +- The original Emacs hydra , for the concept this is + based on Generated by panvimdoc