-
Notifications
You must be signed in to change notification settings - Fork 7
/
libmodal.txt
892 lines (679 loc) · 30.7 KB
/
libmodal.txt
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
*libmodal.txt* Create modes for Neovim
*libmodal*
*nvim-libmodal*
================================================================================
0. Table of Contents *libmodal-toc*
1. About ................ |libmodal-about|
2. Usage ................ |libmodal-usage|
3. Examples ............. |libmodal-examples|
4. Configuration ........ |libmodal-configuration|
5. License .............. |libmodal-license|
6. Bugs ................. |libmodal-bugs|
7. Contributing ......... |libmodal-contributing|
8. Credits .............. |libmodal-credits|
================================================================================
1. About *libmodal-about*
|nvim-libmodal|:
- Author, Iron-E @ https://github.com/Iron-E & https://gitlab.com/Iron_E
- GitHub @ https://github.com/Iron-E/nvim-libmodal
Complete rewrite of |vim-libmodal|:
- Author, Iron-E @ https://github.com/Iron-E & https://gitlab.com/Iron_E
- GitHub @ https://github.com/Iron-E/vim-libmodal
|libmodal| is a Neovim library/|plugin| aimed at simplifying the creation
of new "modes" (e.g. |Insert|, |Normal|). The entrance of modes is
creator-defined, and their exit defaults to <Esc>. The use and name of
modes is also creator-defined, and is outlined in |libmodal-usage|.
See: |vim-modes|
--------------------------------------------------------------------------------
USE CASE *libmodal-use-case-example*
As an |init.vim| configuration grows, it becomes harder to create keybindings
that alphabetically represent the action that they perform. To get around
this, |libmodal| allows users to create a new "layer" of keybindings contained
within a pseudo-|vim-mode|. This layer of keybindings can be bound to a
command which executes `libmodal.mode.enter()` or `libmodal.prompt.enter()`,
and any settings outside of these commands are preserved.
For example, say that a user of Neovim regularly uses |:diffsplit| to merge
changes from `git`. They might define a "DIFF" mode that takes input and
directly translates it into |:diff|* operations. This would allow them to
For instance, perhaps this mode is defined so that `n` goes to the next diff
(like `]c`), and `N` goes to the previous diff (like `[c`). This would make
going from diff to diff more rememberable, as `n` is commonly used because of
`/` searches.
Suppose that the mode also numbers each |:buffer|, so that you don't have
to remember which |:diffsplit| to |:diffget| from. The numbers would disappear
when you leave the mode.
Finally, there could be a help key, `?`, which would show exactly which keys
have been mapped and what they do.
You can see such a mode here:
- https://gist.github.com/Iron-E/f36116e8862ea03fd195e4e0a48cb05d
Outside of the |libmodal-mode|, `n` still searches for the |last-pattern|, and
the buffers are not visibly numbered. Any setup that a |libmodal-mode| does to
inderpret keybindings is undone before the mode ends (while any changes to
buffers persevere).
See: |libmodal-usage|
================================================================================
2. Usage *libmodal-usage*
The |libmodal| interface is designed completely in |Lua|. It is compatable
with Vimscript, and so one may either:
1. Define a |Lua| interface for your mode (see |libmodal-examples|).
- Use |lua-require| as a |user-command|.
- See |lua-require-example| for information about how to do this.
- See `Iron-E/nvim-tabmode` for a complete example.
- See `Iron-E/mode-fugidiff.lua` on GitHub Gists for another example.
2. |call| `libmodal#Enter()` or `libmodal#Prompt()` from Vimscript.
The following is a reference for high-level functions meant to be used by mode
creators. For those who wish to see a low-level specification of |libmodal|,
see |libmodal-lua|.
NOTE: Examples for all topics covered here can be found in the "examples"
folder at the root of the repository.
See: |api|, |lua-api|, https://github.com/Iron-E/nvim-tabmode,
https://gist.github.com/Iron-E/f36116e8862ea03fd195e4e0a48cb05d
--------------------------------------------------------------------------------
VARIABLES *libmodal-usage-variables*
`vim.g`.libmodalActiveModeName *g:libmodalActiveModeName*
The name of the currently active |libmodal-mode|.
Type: ~
`string`
Default Value: ~
`nil`
See also: ~
|g:| For more information about global variables.
|vim.g| For info about accessing |g:| from lua.
MODE *libmodal.Mode-vars*
`Mode`.count *libmodal.Mode.count*
The |v:count| of the mode.
Type: ~
|libmodal-Var| of |lua-number|
Example: ~
>lua
libmodal.mode.enter('Foo', {
G = function(self)
local count = self.count:get()
vim.api.nvim_command('norm! ' .. tostring(count) .. 'G')
end,
})
<
`Mode`.exit *libmodal.Mode.exit*
If `true`, flags the mode to exit. It will read this value before reading
the user's next key.
Type: ~
|libmodal-Var| of `boolean`
Example: ~
>lua
libmodal.mode.enter('Foo', {
q = function(self)
vim.notify('Hello!')
self.exit:set_local(true)
end,
})
<
`Mode`.timeouts *libmodal.Mode.timeouts*
The |libmodal-timeouts| configuration for this mode.
Type: ~
|libmodal-Var| of `boolean`
Example: ~
>lua
libmodal.mode.enter('Foo', {
t = function(self)
local timeouts = self.timeouts:get()
self.timeouts:set_local(not timeouts) -- toggle timeouts
end,
})
<
--------------------------------------------------------------------------------
FUNCTIONS *libmodal-usage-functions*
MODE *libmodal-mode* *libmodal.mode*
`libmodal.mode`.enter(...) *libmodal.mode.enter()*
`libmodal`#Enter(...) *libmodal#Enter()*
Creates a mode (see |libmodal.mode.new()|) and then immediately enters it
(see |libmodal.Mode:enter()|).
For additional notes on how a `Mode` works, see |libmodal.Mode:enter()|.
Parameters: ~
Same as |libmodal.mode.new()|
See also: ~
|libmodal-examples| For examples of this function.
|libmodal.mode.new| For an alternative that allows additional
customization before entering the mode.
`libmodal.mode`.new({name}, {instruction} [, {supress_exit}]) *libmodal.mode.new()*
Create a new |vim-mode| using {instruction} to determine what actions will
be taken upon specific user inputs. To enter the mode use either
|libmodal.Mode:enter()| or |libmodal.mode.enter|.
For additional notes on how a mode works, see |libmodal.Mode:enter()|.
Parameters: ~
{name} The name of the mode (e.g. |INSERT|).
- Case-sensitive. Caps are recommended.
{instruction} What to do when accepting user input.
- If {instruction} is a `dict`/`table`, then it is treated as a
map of user key-chord to Vim |command|s. Example: >lua
local modeInstruction = {
zf = 'split',
zfo = 'vsplit',
-- You can also use lua functions
zfc = function() vim.api.nvim_command 'tabnew' end
}
<>vim
let s:modeInstruction = {
'zf': 'split',
'zfo': 'vsplit',
'zfc': 'tabnew'
}
<
NOTE: If no `?` key is defined, one will be created automatically.
- If {instruction} is a `function`, then it is called every time
that |getchar()| completes. The user input is received through
`g:{name}ModeInput` (see above).
- |v:count| is provided through `g:{name}ModeCount`. For |v:count1|
do: >lua
local count1 = math.max(1, count) -- lua
<>vim
let count1 = max(1, count) " vimscript
<
*Error you cannot pass a funcref to Lua from Vimscript!
- If you want to use a |funcref()| for {instruction}, it
must be the name of the function as a `string`. >
" VIMSCRIPT
function! s:foo() abort
echo 'It works'
call getchar()
endfunction
lua require('libmodal').mode.enter('FOO', 's:foo')
<
NOTE: Some QoL features are available by default when
specifying a `dict` / |lua-table| value for {instruction} that
would otherwise have to be programmed manually if a
`function` is specified.
- Bound |lua-function|s may accept a `self` parameter, which
allows access to |libmodal.Mode-vars|.
- A user's typed characters will show in the
lower right corner when {instruction} is a table.
- If `g:libmodalTimeouts` is enabled, then user input will be
subjected to the |timeoutlen|.
{supress_exit} Whether or not to automatically exit the mode upon an
<Esc> press.
- If |v:false|/`false`, then <Esc> is automatically mapped to
exiting.
- If |v:true|/`true`, then <Esc> is ignored unless specified by
the user. In such cases, when exiting is desired the user should
either:
- set the `g:`{name}`ModeExit` variable to `true`, or
- use |libmodal.Mode:exit()|
See |libmodal-examples|.
Return: ~
A `libmodal.Mode` object
See also: ~
|lua-eval| For type conversions between Vimscript to |Lua|.
|libmodal-examples| For examples of this function.
|libmodal.Mode:enter()| For how to enter a mode using a `libmodal.Mode`
|libmodal.mode.enter| For a convenient way to create and enter a
mode at once.
`libmodal.mode.map`.fn({f}, ...) *libmodal.mode.map.fn()*
Because |libmodal-mode|s expose the `self` parameter to |lua-function|s in
|lua-table|s, mapping certain functions may not work as you expect. For
example: >lua
libmodel.mode.enter('foo', {
a = vim.cmd.undo, -- error!
})
<
This is because some functions accept |lua-nil| as a parameter (e.g.
`vim.cmd.undo()` is OK) but not accept parameters of certain types (e.g.
`vim.cmd.undo('foo')` is an error). In this case (expanding the previous
example to highlight the problem): >lua
libmodel.mode.enter('foo', {
-- equivalent to `a = vim.cmd.undo`
a = function(self) vim.cmd.undo(self) end,
})
< `self` (a |libmodal.Mode|) is not an appropriate parmeter to `vim.cmd.undo`.
To fix this, one can explcitly write the following as mapping: >lua
libmodel.mode.enter('foo', {
a = function() vim.cmd.undo() end, -- error!
})
< However, this is tiresome. To simplify this process, `libmodal.mode.map.fn`
was created.
Parameters: ~
{f} the function to map
... arguments to the function
Example: ~
>lua
local fn = libomdal.mode.map.fn
libmodal.mode.enter('Foo', {
a = fn(vim.cmd.undo),
b = fn(print, 'hello'),
})
`libmodal.mode.map`.switch(...) *libmodal.mode.map.switch()*
Convenience wrapper for |Mode:switch()|.
Parameters: ~
See |Mode:switch()|.
Example: ~
>lua
libmodal.mode.enter('Foo', {
f = libmodal.mode.map.switch('Bar', {
b = function()
vim.notify('Inside Bar mode')
end,
}),
})
<
`libmodal.Mode`:enter() *libmodal.Mode:enter()*
Enters the given mode.
While the mode is entered, user input is taken one character at a time using
|getchar()|. It is passed through a |g:var| determined by the {name} of the
mode. For example, if {name} is "FOO" then the |g:var| is `g:fooModeInput`.
Additionally, this input is reported as a |char2nr| number, and as such
should be decoded with `string.char()` (|nr2char| in |Lua|) if working
with raw characters is desired.
To take input on a line-by-line basis, see |libmodal-prompt|.
NOTE: mode transitions trigger |ModeChanged| events.
NOTE: `libmodal.mode.enter()`/`libmodal#Enter()` may be called from inside
itself. See |libmodal-examples| for an example.
WARN: this function should not be called again while the mode is active!
Either use |libmodal.mode.enter()| or create a new mode with
|libmodal.mode.new()| and enter that instead.
See also: ~
|libmodal.mode.enter()| For a helper to create and enter a function at
once.
|libmodal.mode.new()| For how to create a `Mode`.
`libmodal.Mode`:exit() *libmodal.Mode:exit()*
When the {instruction} parameter to |libmodal.mode.enter()| is a
|lua-table|, one can use |lua-function|s as mappings. When this is done, the
`self` parameter becomes available, and from this the `:exit()` function can
be called.
WARNING: this call will _not_ interrupt |getchar()| (see |libmodal-mode|).
call `exit` only inside a `function` mapping as shown below.
Example: ~
>lua
libmodal.mode.enter('Foo', {
q = function(self)
self:exit()
end,
})
<
`libmodal.Mode`:switch(...) *libmodal.Mode:switch()*
|libmodal.mode.enter()| a new mode, and when it is finished, |Mode:exit()|
the current mode.
Parameters: ~
Either:
- A `libmodal.Mode` to enter
- Parameters to |libmodal.mode.new()|.
Example: ~
>lua
libmodal.mode.enter('Foo', {
f = function(self)
self:switch('Bar', {
b = function()
vim.notify('Inside Bar mode')
end,
})
end,
})
<
`libmodal.Mode`:with_fallback({f}) *libmodal.Mode:with_fallback()*
Set a fallback for the `Mode` such that when keys are entered by a user and
no mapping is defined for them, this function will be called.
Parameters: ~
{f} a |lua-function| with the signature
`fun(mode: libmodal.Mode, keys: string)`
Return: ~
- The same `libmodal.Mode`, but with the fallback applied. The return
value can be safely ignored, as the fallback is applied even without
variable reassignment.
Example: ~
>lua
libmodal.mode
.new('FOO', {--[[your keymaps here]]})
:with_fallback(function (_, keys)
vim.notify(vim.inspect(keys))
end)
:enter()
<
LAYER *libmodal-layer* *libmodal.layer*
`libmodal.layer`.enter({keymap} [, {exit_char}]) *libmodal.layer.enter()*
While a |libmodal-mode| ignores behavior that has not been explicitly
defined, a |libmodal-layer| allows unrecognized |input| to be passed back
into Neovim for analysis.
So, if you have only defined a few keybindings, all of the remaining ones
from a user's configuration would still work— only new keymaps will be
overwritten.
Parameters: ~
{keymap} The keymap for the layer. General template is this: >
{
[<mode>] = {
[<lhs>] = {
rhs = <rhs>,
<opts>
},
…
},
…
}
< Where {mode}, {lhs}, {rhs}, and {opts} are the same as in
|vim.keymap.set()| (except you should not use multiple `<mode>` at
one time, despite |vim.keymap.set()| supporting it).
{exit_char} The character used to exit the layer.
Return: ~
- The `function` used to undo changes made by the layer, or `nil` if
{exit_char} is provided.
See also: ~
|libmodal-examples| For an example.
|vim.keymap.set()| For more information about `opts`.
`libmodal.layer`.new({keymap}) *libmodal.layer.new()*
See |libmodal.layer.enter()| for more information. This function only
differs from |libmodal.layer.enter()| in that instead of entering the layer
immediately, it returns a |libmodal.Layer| object for you to manipulate.
Parameters: ~
{keymap} The keymap for the layer. General template is this: >
{
[<mode>] = {
[<lhs>] = {
rhs = <rhs>,
<opts>
},
…
},
…
}
< Where {mode}, {lhs}, {rhs}, and {opts} are the same as in
|vim.keymap.set()| (except you should not use multiple `<mode>` at
one time, despite |vim.keymap.set()| supporting it).
Return: ~
- A |libmodal.Layer| object.
See also: ~
|libmodal-layer| For more information about layers.
|libmodal-examples| For an example.
|vim.keymap.set()| For more information about `opts`.
*libmodal-Layer* *libmodal.Layer*
`libmodal.Layer`:enter() *libmodal.Layer:enter()*
Applies the {keymap} which was provided by |libmodal.layer.new|. These two
code snippets are equivalent: >
local libmodal = require 'libmodal'
-- enter a layer directly
libmodal.layer.enter({n = gg = {rhs = 'G'}})
-- enter a layer manually
local layer = libmodal.layer.new({n = gg = {rhs = 'G'}})
layer:enter()
<
See also: ~
|libmodal.layer.enter| A shortcut to access this function.
|libmodal.layer.new| How to create a |libmodal.Layer|
`libmodal.Layer`:is_active() *libmodal.Layer:is_active()*
Return: ~
- `true` if the |Layer:enter()| has been called, but not
|Layer:exit()|. `false` otherwise.
See also: ~
|libmodal.Layer:enter()| A shortcut to access this function.
|libmodal.Layer.exit()| How to create a |libmodal.Layer|
`libmodal.Layer`:map({mode}, {lhs}, {rhs}, {opts}) *libmodal.Layer:map()*
{mode}, {lhs}, {rhs}, and {opts} are the same as in |vim.keymap.set()|
except that a {mode} table is not supported.
See also: ~
|libmodal-examples| For an example.
|vim.keymap.set()| For information about the args.
`libmodal.Layer`:unmap({mode}, {lhs}) *libmodal.Layer:unmap()*
{mode} and {lhs} are the same as in |vim.keymap.del()| except that a {mode}
table is not supported.
NOTE: this function cannot be called until after |libmodal.Layer:enter()|
See also: ~
|libmodal-examples| For an example.
|vim.keymap.del()| For information about the args.
PROMPT *libmodal-prompt* *libmodal.prompt*
`libmodal.prompt`.enter({name}, {instruction} [, {completions}]) *libmodal.prompt.enter()*
`libmodal`#Prompt({name}, {instruction} [, {completions}]) *libmodal#Prompt()*
Besides accepting user input like keys in |Normal-mode|, |libmodal| is
also capable of prompting the user for |input| like |Cmdline-mode|. To
define a |Cmdline-mode|-like prompt, use this function rather than
`libmodal.mode.enter()`/`libmodal#Enter()`.
User input is taken using |input()|. It is passed through a |g:var|
determined by the {name} of the mode. For example, if {name} is "FOO"
then the |g:var| is `g:fooModeInput`.
Parameters: ~
{name} The name of the mode (e.g. |INSERT|).
- Case-sensitive. Caps are recommended.
{instruction} What to do when accepting user input.
- If {instruction} is a `dict`/`table`, then it is treated as a
map of user inputs to Vim |command|s. Example: >
-- LUA
local modeInstruction = {
new = 'tabnew',
close = 'tabclose',
last = 'tablast'
}
" VIMSCRIPT
let s:modeInstruction = {
'new': 'tabnew',
'close': 'tabclose',
'last': 'tablast'
}
<
- If {instruction} is a `function`, then it is called
every time that |input()| completes. The user input
is received through `g:{name}ModeInput` (see above).
*Error you cannot pass a funcref to Lua from Vimscript!
- If you want to use a |funcref()| for {instruction}, it
must be the name of the function as a `string`.
" VIMSCRIPT
function! s:foo() abort
echo 'It works'
call getchar()
endfunction
lua require('libmodal').prompt.enter('FOO', 's:foo')
<
NOTE: If you want to create commands with arguments, you will
need to use a `function`.
{completions} An array-like `table` of commands that are offered by
the prompt.
- Automatically generated when {instruction} is a `table`.
- Used to provide auto-completion when the user is typing.
- If unspecified, and {instruction} is not a `table`, then no
completions will be provided.
NOTE: If no `help` command is defined, one will be created
automatically.
NOTE: The user may set the `g:`{name}`ModeExit` variable to
`true` at any time to prematurely exit.
See also: ~
|lua-eval| For type conversions between Vimscript to |Lua|.
|libmodal-examples| For examples of this function.
VAR *libmodal-Var* *libmodal.Var*
Some values mentioned above may be typed `libmodal-Var`. By default, `Var`s
mirror a specific |g:var|, but they may be given instance-local values as
well. In this case, the instance value is preferred to the global value.
`Var`:get() *libmodal.Var:get()*
Return: ~
|libmodal.Var:get_local()| if a local value exists, or
|libmodal.Var:get_global()|.
`Var`:get_global() *libmodal.Var:get_global()*
Return: ~
The global value.
See also: ~
|g:| For more information about global variables.
|vim.g| For info about accessing |g:| from lua.
`Var`:get_local() *libmodal.Var:get_local()*
Return: ~
The local value.
`Var`:set({value}) *libmodal.Var:set()*
|libmodal.Var:set_local()| if a local value exists, otherwise
|libmodal.Var:set_global()|.
Parameters: ~
{value} to set.
`Var`:set_global({value}) *libmodal.Var:set_global()*
Set a {value} locally.
Parameters: ~
{value} to set globally.
See also: ~
|g:| For more information about global variables.
|vim.g| For info about accessing |g:| from lua.
`Var`:set_local({value}) *libmodal.Var:set_local()*
Set a {value} globally.
Parameters: ~
{value} to set locally.
--------------------------------------------------------------------------------
EVENTS *libmodal-usage-events*
|libmodal| fires the |ModeChanged| |autocommand| |{event}| when entering and
exiting |libmodal-mode|s.
================================================================================
3. Examples *libmodal-examples*
See the official examples at the link below:
https://github.com/Iron-E/nvim-libmodal/tree/master/examples
================================================================================
4. Configuration *libmodal-configuration*
The following specifies what settings may be used to configure
|libmodal-mode|s and |libmodal-prompt|s.
--------------------------------------------------------------------------------
HIGHLIGHT GROUPS *libmodal-highlight-groups*
The following |highlight-groups| can be |config|ured to change a mode's |color|s:
Name Default Description
---------------- ------------ --------------------------
`LibmodalPrompt` `ModeMsg` Color for the mode text.
`LibmodalStar` `StatusLine` Color for the prompt text.
NOTE: `LibmodalStar`'s name — while not indicative of its use — is used for
the sake of backwards compatability.
--------------------------------------------------------------------------------
TIMEOUTS *libmodal-timeouts* *g:libmodalTimeouts*
When `libmodal.mode.enter()`'s {instruction} argument is a `table`, mode
creators may also enable the use of Vim's built-in 'timeout' feature.
To enable 'timeout's, one may set the following |variables|:
Lua: ~
>
" Set libmodal modes to turn timeouts on.
vim.g.libmodalTimeouts = true
" Enable timeouts for specific mode.
vim.g[name..'ModeTimeouts'] = true
<
Vimscript: ~
>
" Set libmodal modes to turn timeouts on.
let g:libmodalTimeouts = v:true
" Enable timeouts for specific mode.
let g:{name}ModeTimeouts = v:true
<
Similarly, to disable them, one may set them to `0`.
When `g:libmodalTimeouts` or `g:{name}ModeTimeouts` is set to `1`, |libmodal|
will automatically execute commands that have mappings that might also be
longer mappings. For example:
If a mode specifies `zf` and `zfo` as mappings,
- Turning 'timeout's on will cause `zf` to be executed if the user waits
for 'timeoutlen' without typing another character.
- If 'timeout' were to be off in this case, then the user would either
have to hit <CR> to execute `zf` or hit `o` to execute `zfo`.
NOTE: `g:libmodalTimeouts` defaults to the 'timeout' value.
NOTE: The `g:limbodalTimeouts` variable should NOT be defined by plugins.
- Allow users to decide whether or not they want timeouts to be
enabled globally themselves.
NOTE: Mode-specific timeout variables will override `g:libmodalTimeouts`.
When enabled, |libmodal-timeouts| will reference the mode user's 'timeoutlen'
as specified in their |config|. This way, modes will feel consistent to users
by default.
However, mode creators may change 'timeoutlen' upon entrance of a mode, and
then reset it upon exit. Example:
Vimscript: ~
>
function! s:FooMode() abort
" Get the user's preferred timeout length.
let l:timeoutlen = &timeoutlen
" Set it to something else, like 1500ms
let &timeoutlen = 1500
" Enter a mode
call libmodal#Enter(…)
" Reset the timeout
let &timeoutlen = l:timeoutlen
endfunction
<
Lua: ~
>
local libmodal = require('libmodal')
function fooMode()
-- Get the user's preferred timeout length.
local prevTimeoutLen = vim.go.timeoutlen
-- Set it to something else, like 1500ms.
vim.go.timeoutlen = 1500
-- Enter a mode.
libmodal.mode.enter(…)
-- Restore the `timeoutlen`
vim.go.timeoutlen = prevTimeoutLen
end
<
Mode creators who use `function` {instruction}s may define timeouts manually
using |timers|, which is how |libmodal| implements them internally.
================================================================================
5. License *libmodal-license*
`nvim-libmodal` – Create new "modes" for Neovim.
Copyright © 2020 Iron-E
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
================================================================================
6. Bugs *libmodal-bugs*
- `libmodal#Enter()` does not work when {instruction} is a |funcref|.
- See |E5004|.
- `libmodal#Prompt()` does not work when {instruction} is a |funcref|.
- See |E5004|.
================================================================================
7. Contributing *libmodal-contributing*
The following describes what should be done if an individual wishes to
contribute something to the `Iron-E/nvim-libmodal` repository.
--------------------------------------------------------------------------------
CODE *libmodal-contributing-code*
Bugfixes ~
If you discover a bug and believe you know the solution to fixing it, then
submit a bug report and state that you are working on a fix (and what that
fix might be), and what general timeframe the fix may be completed in
(months, weeks, days, etc.).
When the fix is complete, submit a PR that references the issue you
submitted.
Features ~
If there is a feature you would like to be a part of |libmodal|, the best
thing you can do is submit a feature request, and then state that you are
working on a pull request (PR) so others don't attempt to do the same work
at the same time.
When you believe your feature is complete, write some examples for it in
the `examples/lua` folder, and add them to |libmodal-examples| as
appropriate.
Assure that all existing |libmodal-examples| continue to work with your
feature, unless a breaking change was discussed on the feature request.
If you need help getting them to pass, you can ask for help on the PR.
Reference the issue you submitted on the PR so that the two show up
together when looking back at the history.
Contributing documentation is not necessary but appreciated, since the
person who knows the most about the feature being implemented is most
likely the one implementing it.
--------------------------------------------------------------------------------
DOCUMENTATION *libmodal-contributing-documentation*
If there is a problem with the documentation, or you see an area where it
could be improved, don't hesitate to submit an issue and a PR. At the very
least it will exist in history if such an issue comes up again, and likely it
will serve to help yourself and others with more clear and concise wording, or
with more helpful and practical examples.
--------------------------------------------------------------------------------
ISSUES *libmodal-contributing-issues*
Issues are greatly welcomed on the GitHub repository, whether they are bug
reports, feature requests, documentation improvements, or misunderstandings:
it's all good to have in the archive.
When submitting an issue, please describe the following:
1. Context regarding the issue (how you discovered it, pertinent information,
etc.)
2. Detailed description of the issue.
3. Steps to reproduce (if applicable).
4. Expected behavior (if applicable).
5. Attached media (screenshots, logs, etc.) (if applicable).
================================================================================
8. Credits *libmodal-credits*
Credit Reason
--------------------- ----------------------------------
Daniel Steinberg |vim-win| creator and inspiration.
Iron-E Primary contibuter/maintainer.
neoclide/|coc-nvim| Development environment provider.
r/Neovim |Lua| and Neovim reference.
Roberto Ierusalimschy "Programming In Lua: 5.1".
Steve Losh "Learn Vimscript The Hard Way".
tbastos/vim-lua Syntax highlighting for |Lua|.
u/Mambu38 |Lua| reference.
u/oryiesis Inspiration.
www.lua-users.org |Lua| reference.
www.stackoverflow.com Vimscript and |Lua| reference.
================================================================================
vim:tw=80:ts=4:ft=help:norl: