summaryrefslogtreecommitdiff
path: root/doc/pages/hooks.asciidoc
blob: f03576365650656f621da2178efd84c2d12b1c51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
= Hooks

== Description

Commands can be registered to be executed when certain events arise. To
register a hook use the following command:

------------------------------------------------------------------
hook [<switches>] <scope> <hook_name> <filtering_regex> <commands>
------------------------------------------------------------------

*scope* can be one of *global*, *buffer* or *window* (See
<<scopes#,`:doc scopes`>>).

*hook_name* must be one of the hook names in the list below, like `InsertKey`
or `BufSetOption`.

*filtering_regex* must match the entire parameter string in order for the
commands to be executed.

*command* is a string containing the commands to execute when the hook
is called.

For *switches*, see <<commands#hooks,`:doc commands hooks`>>.

If a hook is registered with the `-group` switch, it can later be removed with
the `remove-hooks` command:

----------------------------
remove-hooks <scope> <group>
----------------------------

This command removes all hooks originally registered in *scope* whose
`-group` switch matches the regex *group*.

For example to automatically use line numbering with .cc files, use the
following command:

--------------------------------------------------------------
hook global WinCreate .*\.cc %{ add-highlighter number-lines }
--------------------------------------------------------------

== Default hooks

The parameter string associated with each hook is described after the hook
name. Hooks with no description will always use an empty string.

*NormalIdle*::
    a certain duration has passed since the last keypress in normal mode

*NormalKey* `key`::
    a key is received in normal mode. This hook will not trigger when the user
    presses a key on the left-hand side of a normal-mode mapping (see
    <<mapping#,`:doc mapping`>>), but will trigger for keys on the right-hand
    side. See also `RawKey` below.

*InsertIdle*::
    a certain duration has passed since the last keypress in insert mode

*InsertKey* `key`::
    a key is received in insert mode. This hook will not trigger when the user
    presses a key on the left-hand side of a insert-mode mapping (see
    <<mapping#,`:doc mapping`>>), but will trigger for keys on the right-hand
    side. See also `RawKey` below.

*InsertChar* `char`::
    a character is received in insert mode

*InsertDelete* `deleted char`::
    a character is deleted in insert mode

*InsertMove* `move key`::
    the cursor moved (without inserting) in insert mode

*PromptIdle*::
    a certain duration has passed since the last keypress in prompt mode

*WinCreate* `buffer name`::
    a window was created. This hook is executed in draft context, so any
    changes to selections or input state will be discarded.

*WinClose* `buffer name`::
    a window was destroyed. This hook is executed in a draft context, so any
    changes to selections or input state will be discarded.

*WinResize* `<line>.<column>`::
    a window was resized. This hook is executed in a draft context, so any
    changes to selections or input state will be discarded.

*WinDisplay* `buffer name`::
    a client switched to displaying the given buffer.

*WinSetOption* `<option_name>=<new_value>`::
    an option was set in a window context. This hook is executed in a draft
    context, so any changes to selections or input state will be discarded.

*GlobalSetOption* `<option_name>=<new_value>`::
    an option was set at the global scope

*BufSetOption* `<option_name>=<new_value>`::
    an option was set in a buffer context

*BufNewFile* `filename`::
    a buffer for a new file has been created

*BufOpenFile* `filename`::
    a buffer for an existing file has been created

*BufCreate* `filename`::
    a buffer has been created

*BufWritePre* `filename`::
    executed just before a buffer is written

*BufWritePost* `filename`::
    executed just after a buffer is written

*BufReload* `filename`::
    executed after a buffer reload has been triggered by an external
    modification to its file

*BufClose* `buffer name`::
    executed when a buffer is deleted, while it is still valid

*BufOpenFifo* `buffer name`::
    executed when a buffer opens a fifo

*BufReadFifo* `<start line>.<start column>,<end line>.<end column>`::
    executed after some data has been read from a fifo and inserted in
    the buffer. The hook param contains the range of text that was just
    inserted, in a format compatible with the `select` command.

*BufCloseFifo*::
    executed when a fifo buffer closes its fifo file descriptor either
    because the buffer is being deleted or the writing end has been closed

*ClientCreate* `client name`::
    executed when a new client is created.

*ClientClose* `client name`::
    executed when a client is closed, after it was removed from the client
    list.

*ClientRenamed* `<old name>:<new name>`::
    executed when a client is renamed using the `rename-client` command

*SessionRenamed* `<old name>:<new name>`::
    executed when a session is renamed using the `rename-session` command

*EnterDirectory* `path`::
    executed on startup and when the current working directory is changed
    using the `change-directory` command. The hook param is an absolute path
    to the new working directory.

*RuntimeError* `error message`::
    an error was encountered while executing a user command

*ModeChange* `[push|pop]:<old mode>:<new mode>`::
    Triggered whenever a mode is pushed or removed from the mode stack.
    The mode name can be things like 'normal' or 'insert' for regular
    interactive modes, or 'next-key[<name>]' for sub-modes where Kakoune
    prompts for a key. For example, `g` in normal mode pushes 'next-key[goto]'
    mode, the `enter-user-mode foo` command pushes 'next-key[user.foo]' mode,
    and the `on-key -mode-name bar` command pushes 'next-key[bar]' mode.

*KakBegin* `session name`::
    Kakoune has started, this hook is called just after reading the user
    configuration files

*KakEnd*::
    Kakoune is quitting

*FocusIn* `client name`::
    on supported clients, triggered when the client gets focused

*FocusOut* `client name`::
    on supported clients, triggered when the client gets unfocused

*InsertCompletionShow*::
    Triggered when the insert completion menu gets displayed

*InsertCompletionHide* `completion`::
    Triggered when the insert completion menu gets hidden, the list of
    inserted completions text ranges is passed as filtering text, in the
    same format the `select` command expects.

*RawKey* `key`::
    Triggered whenever a key is pressed by the user, regardless of what mode
    Kakoune is in, or what mappings are present (see
    <<mapping#,`:doc mapping`>>). It cannot be triggered by `execute-keys`,
    even with the `-with-hooks` option (see
    <<execeval#execute-keys-specific-switches,`:doc execeval execute-keys-specific-switches`>>).

*RegisterModified* `register`::
    Triggered after a register has been written to.

*ModuleLoaded* `module`::
    Triggered after a module is evaluated by the first `require-module` call

*User* `param`::
    Triggered  via the `trigger-user-hook` command. Provides a way for plugins
    to introduce custom hooks by specifying what *param* would be.

Note that some hooks will not consider underlying scopes depending on what
context they are bound to be run into, e.g. the `BufWritePost` hook is a buffer
hook, and will not consider the `window` scope.

While defining hook commands with a `%sh{}` block, some additional env
vars are available:

* `kak_hook_param`: filtering text passed to the currently executing hook

* `kak_hook_param_capture_N`: text captured by the hook filter regex capturing
    group N, N can either be the capturing group number, or its name
    (See <<regex#groups,`:doc regex groups`>>).

== Disabling Hooks

Hooks can be disabled temporarily by prefixing any normal mode command by `\`
(see <<keys#,`:doc keys`>>) and permanently by setting the `disabled_hooks` option
which accepts a regex describing which hooks won't be executed. For example
indentation hooks can be disabled with '.*-indent'.

Finally, hook execution can be disabled while using the `execute-keys` or
`evaluate-commands` commands by using the `-no-hooks` switch.
(See <<execeval#,`:doc execeval`>>)

As an exception to these rules, hooks declared with the `-always` switch
are triggered no matter what. A good use case is doing some cleanup on `BufCloseFifo`.