-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathREADME
1006 lines (855 loc) · 38.8 KB
/
README
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
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Nextvi(1) General Commands Manual Nextvi(1)
NAME
Nextvi - A small vi/ex terminal text editor
SYNOPSIS
vi [-emsv] [file ...]
DESCRIPTION
Nextvi is a modern clone of the command-line text editor vi(1),
initially developed by Bill Joy in 1976 for Unix-based systems.
Nextvi builds upon many standard features from vi(1) including
unique modal interface that allows users to switch between normal,
insert, and command modes, for efficient text manipulation.
Additional enhancements include an unrestricted macro system,
syntax highlighting, keymaps, bidirectional UTF-8 support, and
numerous other features. Nextvi remains highly efficient, portable,
and hackable, ensuring its continued relevance and high quality
for years to come.
OPTIONS
-e Enter Ex mode on startup
-m Disable initial file read message
-s Enter raw Ex mode on startup
-v Enter visual mode on startup (Default)
MANPAGE NOTATION
<x> A closure where x represents character literal
[x] A closure where x represents optional argument
{x} A closure where x represents required argument
"x" A closure where x represents a string
<^X> Represents a ctrl key X
# Represents a positive number in a closure
* Represents any character(s) in a closure
< > Separates alternatives in a closure
x-y Range from x to y
VI NORMAL
[#]j Move # lines down
[#]k Move # lines up
[#]+
[#]<^M>
[#]<Newline>
Move # lines down, cursor after indent
[#]- Move # lines up, cursor after indent
[#]h Move # cols left
[#]l Move # cols right
f{arg} Move to arg character found forward
F{arg} Move to arg character found backward
t{arg} Move until arg character found forward
T{arg} Move until arg character found backward
[#], Repeat last <f F t T> move backward # times
[#]; Repeat last <f F t T> move forward # times
[#]E Move to end of word # times, skip punctuation
[#]e Move to end of word # times
[#]B Move to start of word backward # times, skip punctuation
[#]b Move to start of word backward # times
[#]W Move to start of word forward # times, skip punctuation
[#]w Move to start of word forward # times
vw Toggle line mode for <E e B b W w>
[#]{ Move to next <{> section down # times
[#]} Move to next <{> section up # times
[#][ Move to next <Newline> section down # times
[#]] Move to next <Newline> section up # times
^ Move to start of line after indent
0 Move to start of line
$ Move to end of line
[#]| Goto # col
[#]<Space> Move # characters forward
[#]<^H>
[#]<Backspace>
Move # characters backward
% Move to closest <] ) }><[ ( {> pair
{#}% Move to # percent line number
'{arg} Move to a line mark arg
`{arg} Move to a line mark arg with cursor position
gg Goto first line in buffer
[#]G Move to last line in buffer or # line
H Move to highest line on a screen
L Move to lowest line on a screen
M Move to middle line on a screen
[#]z. Center screen at cursor. # is xtop
[#]z<^M>
[#]z<Newline>
Center screen at top row. # is xtop
[#]z- Center screen at bottom row. # is xtop
[#]<^E> Scroll down 1 or # lines, retain # and cursor position
[#]<^Y> Scroll up 1 or # lines, retain # and cursor position
[#]<^D> Scroll down half a screen size. If [#], set scroll to #
lines
[#]<^U> Scroll up half a screen size. If [#], set scroll to # lines
<^B> Scroll up full screen size
<^F> Scroll down full screen size
# Show global and relative line numbers
2# Toggle show global line numbers permanently
4# Toggle show relative line numbers after indent permanently
8# Toggle show relative line numbers permanently
V Toggle show hidden characters:<Space Tab Newline>
<^C> Toggle show line motion numbers for <l h e b E B w W>
{1-5}<^C> Switch to line motion number mode #
<^V> Loop through line motion number modes
[#]<^R> Redo # times
[#]u Undo # times
<^I>
<Tab>
Open file path from cursor to end of line
<^K> Write current buffer to file. Force write on 2nd attempt
[#]<^W>{arg} Unindent arg region # times
[#]<{arg} Indent left arg region # times
[#]>{arg} Indent right arg region # times
"{arg}{arg1} Operate on arg register according to arg1 motion
R Print registers and their contents
[#]&{arg} Execute arg register macro in non-blocking mode # times
[#]@{arg} Execute arg register macro in blocking mode # times
[#]@@
[#]&&
Execute a last executed register macro # times
[#]. Repeat last normal command # times
[#]v. Repeat last normal command moving down across # lines
: Enter ex prompt
[#]!{arg} Enter pipe ex prompt based on region # or arg
vv Enter ex prompt with the last line from history buffer b-1
[#]vr Enter %s/ ex prompt. Insert # words from cursor
[#]vt[#arg] Enter .,.+0s/ ex prompt. Insert # of lines from cursor.
Insert #arg words from cursor
[#]v/ Enter v/ xkwd ex prompt to set search keyword. Insert #
words from cursor
v; Enter ! ex prompt
[#]vi Enter %s/ ex prompt. Contains regex for changing spaces to
tabs. # modifies tab width
[#]vI Enter %s/ ex prompt. Contains regex for changing tabs to
spaces. # modifies tab width
vo Remove trailing white spaces and <\r> line endings
va Toggle ai ex option
<^G> Print buffer status infos
1<^G> Enable permanent status bar row
2<^G> Disable permanent status bar row
ga Print character info
1ga Enable permanent character info bar row
2ga Disable permanent character info bar row
[#]gw Hard line wrap a line to # col limit. Default: 80
[#]gq Hard line wrap a buffer to # col limit. Default: 80
[#]g~{arg} Switch character case for arg region # times
[#]gu{arg} Switch arg region to lowercase # times
[#]gU{arg} Switch arg region to uppercase # times
[#]~ Switch character case # times forward
i Enter insert mode
I Enter insert mode at start of line after indent
A Enter insert mode at end of line
a Enter insert mode 1 character forward
[#]s Enter insert mode and delete # characters
S Enter insert mode and delete all characters
o Enter insert mode and create a new line down
O Enter insert mode and create a new line up
[#]c{arg} Enter insert mode and delete arg region # times
C Enter insert mode and delete from cursor to end of line
[#]d{arg} Delete arg region # times
D Delete from cursor to end of line
[#]x Delete # characters from cursor forward
[#]X Delete # characters from cursor backward
di{arg} Delete inside arg pairs <( ) ">
ci{arg} Change inside arg pairs <( ) ">
[#]r{arg} Replace # characters with arg from cursor forward
K Split a line
{#}K Split a line without creating blank <Newline>
[#]J Join # lines
vj Toggle space padding when joining lines
[#]y{arg} Yank arg region # times
[#]Y Yank # lines
[#]p Paste default register # times
[#]P Paste default register below current line or behind cursor
position # times
m{arg} Set buffer local line mark arg
<^T> Set global line mark 0. Global marks are always valid
{0 2 4 6 8}<^T>
Set a global line mark #
{1 3 5 7 9}<^T>
Switch to a global line mark #
[#]<^7>{0-9}
[#]<^_>{0-9}
[#]<^/>{0-9}
Show buffer list and switch based on # or 0-9 index when
prompted
<^^>
<^6>
Swap to previous buffer
[#]<^N> Swap to next buffer, # changes direction [forward backward]
\ Swap to /fm/ buffer b-2
{#}\ Swap from /fm/ buffer b-2 and backfill directory listing
vb Recurse into b-1 history buffer. Insert current line into
ex prompt on exit
z1 Set alternative keymap to Farsi keymap
z2 Set alternative keymap to Russian keymap
ze Switch to English keymap
zf Switch to alternative keymap
zL Set td ex option to 2
zl Set td ex option to 1
zr Set td ex option to -1
zR Set td ex option to -2
[#]/ Regex search, move down 1 or # matches
[#]? Regex search, move up 1 or # matches
[#]n
[#]N
Repeat regex search, move [down up] 1 or # matches
<^A> Regex search 1 word from cursor, no center, wraparound move
[up down]
{#}<^A> Regex search, set keyword to # words from cursor
<^]> Filesystem search forward based on directory listing in b-2
{#}<^]> Filesystem search forward, set keyword to # words from
cursor
<^P> Filesystem search backward based on directory listing in
b-2
{#}<^P> Filesystem search backward, set keyword to # words from
cursor
<^Z> Suspend vi
<^L> Force redraw whole screen and update terminal dimensions
qq Exit and clean terminal, force quit in an & macro
zz Exit and submit history command, force quit in an & macro
ZZ Exit and soft write to a file
VI REGIONS
Regions are vi normal commands that define [h v]range for vi motions.
Commands described with the word "move" define a region.
<+ j ^M Newline - k h l f F t T , ; B E b e W w { } [ ] ^ 0 $ Space ^H
Backspace % ' ` G H L M / ? n N ^A>
All regions
VI MOTIONS
Motions are vi normal commands that run in a [h v]range.
Commands described with the word "region" consume a region.
<^W < > ! c d y "> g~ gu gU
All motions
<"> Special motions that consume a motion
dd yy cc g~~ guu gUU >> << <^W><^W> !!
Special motions that can use [#] as number of lines
Examples:
3d/int Delete text until the 3rd instance of "int" keyword
d3w Delete 3 words
"ayl Yank a character into <a> register
"Ayw Append a word to <a> register
VI/EX INSERT
<^H>
<Backspace>
Delete a character
<^U> Delete util <^X> mark or everything
<^W> Delete a word
<^T> Increase indent
<^D> Decrease indent
<^]> Switch default paste register to registers 0-9
<^\>{arg} Select paste register arg. <^\> selects default register
<^P> Paste a register
<^X> Mark autocomplete and <^U> starting position. <^X> resets
the mark
<^G> Index buffer for autocomplete
<^Y> Reset autocomplete data
<^R> Loop through autocomplete options backward
<^N> Loop through autocomplete options forward
<^B> Print autocomplete options when in vi insert
<^B> Recurse into b-1 history buffer when in ex prompt. Insert
current line into ex prompt on exit
<^A> Loop through lines in a history buffer b-1
<^Z> Suspend vi/ex
<^L> Redraw screen in vi mode, clean terminal in ex
<^O> Switch between vi and ex modes recursively
<^E> Switch to english keymap
<^F> Switch to alternative keymap
<^V>{arg} Read a literal character arg
<^K>{arg} Read a digraph sequence arg
<^C>
<ESC>
Exit insert mode
EX
Ex is a powerful line editor for Unix systems, initially developed
by Bill Joy in 1976. This essential tool serves as the backbone
of vi, enabling it to execute commands, macros and even transform
into a purely command-line interface (CLI) when desired.
EX PARSING
Parsing follows the structure:
[<:>][range][sep][cmd][<sep>][args][<:>]
Ex commands are initiated and separated by <:> prefix. Fields
can be separated by <Space> or <Tab>. There can only be one separator
in between [cmd] and [args]. To avoid ambiguity, it is recommended
to always use a separator between [cmd] and [args] in scripts.
Examples:
:evi.c
Evaluates to ":e vi.c"
:eabc
Evaluates to ":ea bc" not ":e abc"
:e vi.c
Edit " vi.c". [<sep>] is required
EX ESCAPES
Special characters in [args] will become regular when escaped
with <\>.
<( ^ ! = [ ] \>
Special characters in regex "[]" bracket exp
<( ) { } + * ? ^ $ [ ] | \< \> . \>
Special characters in regex
<# % ! :>
Special characters in ex
EX EXPANSION
Characters <# %> in [args] substitute the buffer pathname.
<%> substitutes current buffer and <#> last swapped buffer.
It is possible to expand any arbitrary buffer by using <# %>
followed by the buffer number.
Example: print the pathname for buffer 69.
:!echo "%69"
Every ex command is be able to receive data from external process
through a special expansion character <!> which pipes the data
into the command itself. If the closing <!> is not specified,
the end of the line becomes a terminator.
Example: Substitute "int" with the value of $RANDOM
:%s/int/!printf "%s" $RANDOM!
Example: Insert output of ls shell command
:& i!ls
EX RANGES
Some ex commands can be prefixed with ranges.
[. - +][1-9 %][sep][, ;][. - +][1-9 $]
Numeric ranges
</ ?>{kwd}[</ ?>]
Search ranges
<'>{mark}
Mark ranges
Examples:
. current position
, vertical range separator
; horizontal range separator
:1,5p print lines 1,5
:.-5,.+5p
print 5 lines around xrow
:/int/p
print first occurrence of int
:?int?p
print first occurrence of int in reverse
:.,/int/p
print until int is found
:?int?,.p
print until int is found in reverse
:'d,'ap
print lines from mark <d> to mark <a>
:%p print all lines in the buffer
:$p print last line in the buffer
:;50 goto character offset 50
:10;50 goto line 10 character offset 50
:10;.+5
goto line 10 +5 character offset
:'a;'a goto line mark <a> offset mark <a>
:;$ goto end of the line
:5;/int/
search for int on line 5
:.;?int?
search for int in reverse on the current line
EX COMMANDS
[range]f{/?}[kwd]
Ranged search (stands for find)
Example: no range given, current line only
:f/int
Example: reverse
:f?int
Example: range given
:10,100f/int
Subsequent commands within the range will move to the next match
just like vi n/N commands.
b[#] Print currently active buffers state or switch to a buffer
Example: switch to the 5th buffer
:b5
There are two temporary buffers which are separate from
the main buffers.
b-1 = /hist/ ex history buffer
b-2 = /fm/ directory listing buffer
Example: switch to the b-1 buffer
:b-1
Example: switch to the b-2 buffer
:b-2
bp[path]
Set current buffer path
bs[#] Set current buffer saved. If any arg given, reset undo/redo
history
[range]p
Print line(s) from the buffer
Example: utilize character offset ranges
:1,10;5;5p
Example: print current line from offset 5 to 10
:.;5;10p
ea[kwd] [#]
Open file based on filename substring from dir listing in b-2
Requires directory listing in b-2 backfilled prior.
Example: backfill b-2 using :fd
:fd
Example: backfill b-2 using find
:b-2:1,$!find .
If the substring matches more than one filename, a prompt will
be shown. Submit using numbers 0-9 (higher ascii values work
too (<^C> to cancel)). Passing an extra arg to :ea in form of
a number will bypass the prompt and open the corresponding file.
Example: open filename containing "v"
:ea v
Example: open first match containing "v"
:ea v 0
ea![kwd] [#]
Forced version of ea
[#]a[str]
[#]i[str]
[#]c[str]
Enter ex {append insert change} mode
# determines insertion line number.
str determines initial input into the insertion buffer.
Example: insert "hello" in vi/ex
:i hello<^M><ESC>
Example: discard changes in vi/ex
:i hello<^C>
Example: immediately insert "hello"
:i hello<^V><^M><^V><ESC>
Example: insert "hello" in raw ex mode
i hello<^M>.<^M>
[range]d
Delete line(s)
e[path]
Open a file at a path
No argument opens "unnamed" buffer.
e![path]
Force open a file at a path
No argument re-reads the current buffer from the filesystem.
[range]g{*}[kwd]{*}{cmd}
Global command
Execute an ex command on a range of lines that matches an
enclosed regex.
Example: remove all empty lines
:g/^$/d
Multiple ex commands can be chained in one global command.
To chain commands, the ex separator <:> must be escaped once.
Example: yank matches appending to reg 'a' and print them out.
:g/int/ya A\:p
It is possible to nest global commands inside of global commands.
A global command will not be executed on lines that were created
or deleted by a nested global command.
When range not given, a nested global command is executed on
the current line.
Example: Nested global command
Append "has a semicolon" to all lines that contain "int" and
end with <;>.
:g/int/g/;$/& A has a semicolon
Example: extract/print data enclosed in "()"
:g/\(.+\)/;0;/\(.+\)/\:.;.+1k a\:se grp=2\:;/\)*(\))/\:
se nogrp\:k s\:.;'a;'sp
[range]g!{*}[kwd]{*}{cmd}
Inverted global command
[range]=
Print the current range line number
[range]k[mark]
Set a line mark
The character offset is set to the current position.
&{macro}
Global non-blocking macro
Execute raw vi/ex input sequence.
A non-blocking macro shall not wait for input when the end of
the sequence is reached. A non-blocking macro executing other
macros will always reach a terminating point.
Example: execute vi insert statement
:& ihello
Example: execute :hello
:& \:hello<^V><^M>
Example: execute vi ci(int macro
:& ci(int
Example: nest blocking macro inside non-blocking
:& \:@ \\:blocking<^V><^M>i continue in non-blocking
@{macro}
Global blocking macro
Execute raw vi/ex input sequence.
A blocking macro shall wait for input when the end of the sequence
is reached. A blocking macro executing other macros may result
in congestion.
Example: execute vi insert statement
:@ ihello
Example: insert "hello" into <:> vi prompt
:@ \:hello
Example: execute vi ci(int macro
:@ ci(int
Example: execute ci(int exiting insert mode
:@ ci(int<^V><^C>
Example: execute ci)INT as a follow-up
:@ ci(int<^V><^C>ci)INT
Example: execute vi dw command after user exits insert
:@i:@dw
pu[register] [cmd]
Paste a register
To pipe register data to an external process use :pu \![cmd]
Example: copy default register to X11 clipboard
:pu \!xclip -selection clipboard
[range]r[path cmd]
Read a file or a pipe
To read data from a pipe use :[range]r \![cmd]
Example: pipe in only the first line
:r \!ls
Example: pipe in only lines 3,5
:3,5r \!ls
Example: pipe in all data
:%r \!ls
[range]w[path cmd]
Write to a file or a pipe
To pipe buffer data to external process use :[range]w \![cmd]
Example: pipe out all data into less
:w \!less
Example: pipe out only first 10 lines
:1,10w \!less
[range]w![path]
Force write to a file
q Exit
q! Force quit
wq[!]
x[!]
Soft write and exit or force quit
u[# $] Undo # times or all with $
rd[# $]
Redo # times or all with $
se{exp}
Set ex option variable
Example: set using implications
:se hll
:se nohll
Example: set using numeric values
:se hll=1
:se hll=0
Example: set using ascii values
:se hll=a
[range]s{*}[kwd]{*}{str}[*][opts]
Substitute
Find and replace text in a range of lines that matches an
enclosed regex with an enclosed replacement string.
Example: global replacement
:%s/term1/term2/g
Substitution backreference inserts the text of matched group
specified by \x where x is group number.
Example: substitution backreference
this is an example text for subs and has int or void
:%s/(int)|(void)/pre\0after
this is an example text for subs and has preintafter or void
:%s/(int)|(void)/pre\2after/g
this is an example text for subs and has prepreafterafter or prevoidafter
[range]ya[register][append]
Yank a region
To append to the register, pass in its uppercase version.
To append to any of the non-alphabetical registers add any extra
character to the command.
Example: append to register <1>
:ya 1x
ya![register]
Reset register value
[range]![cmd]
Run external program
When ex range specified, pipes the buffer data to an external
process and pipes the output back into current buffer replacing
the affected range.
Example: infamously sort the buffer
:1,$!sort
ft[filetype]
Set a filetype
No argument prints the current file type.
Reloads the highlight ft, which makes it possible to reset dynamic
highlights created by options like "hlw".
cm[keymap]
Set a keymap
No argument prints the current keymap name.
cm![keymap]
Set an alternative keymap
fd[path]
Set a secondary directory (stands for file dir)
Recalculates the directory listing in b-2 buffer.
No argument implies current directory.
fp[path]
Set a directory path for :fd (stands for file path)
cd[path]
Set a working directory (stands for change dir)
Currently open buffers' file paths will be automatically adjusted
to reflect a newly set working directory.
inc[regex]
Include regex for :fd calculation
Example: include only files in submodule directory that end with .c
:inc submodule.*\.c$
Example: exclude the .git and submodule folders
:inc (^[\!.git\!submodule]+[^\/]+$)
No argument disables the filter.
reg[hscroll]
Print registers and their contents
Printing position is determined by xcols / 2 * [hscroll]
bx[#] Set max number of buffers allowed
Buffers will be deallocated if the number specified is lower
than the number of buffers currently in use.
No argument will reset to the default value of 10.
ac[regex]
Set autocomplete filter regex
Example: autocomplete using whole lines from the buffer
:ac .+
No argument resets to the default word filter regex as defined
in led.c.
uc Toggle multibyte utf-8 decoding
This command is particularly useful when editing files with
mixed encodings, binary files, or when the terminal does not
support UTF-8 or lacks the necessary fonts to display UTF-8
characters. It's often paired with :ph command to achieve
hex editor-like functionality.
uz Toggle zero width placeholders
Use only if you need to hide zero width characters.
ub Toggle combining multicodepoint placeholders
Use only if your terminal can render multicodepoint utf-8 (emojis).
ph[#clow] [#chigh] [#width] [#blen][*char]
Redefine placeholders
This command replaces placeholders defined in conf.c
and subsequent :ph commands expand the list of placeholders.
Example: render 8 bit ascii (Extended ASCII) as <~>
:ph 128 255 1 1~
Example: flawless ISO/IEC 8859-1 (latin-1) support
:uc:ph 128 160 1 1~
Example: render control byte 03 as "^C"
:ph 3 3 2 1^C
Example: reset to default as in conf.c
:ph
Example: disable default placeholders in conf.c
:ph:ph0
EX OPTIONS
ai=1 Indent new lines
ic=1 Ignore case in regular expressions
ish=0 Interactive shell
Run every <!> command through an interactive shell.
The shell will source the .rc file before command execution.
This makes it possible to use predefined functions, aliases
and ENV variables from the .rc file.
Precondition 1:
The .rc filename is shell specific, such as .bashrc in Bash
and .zshrc in Zsh.
Precondition 2:
The environment variable $SHELL determines the default
shell, otherwise it defaults to /bin/sh.
Precondition 3:
There must be no stdout output created by .rc file
for <!> commands to return expected results.
grp=0 Regex search group
Defines a target search group for any regex search operation.
This becomes necessary when the result of regex search is to
be based on some group rather than default match group.
Example: ignore tabs at the start of the line
:se grp=2:1,$f/^[ ]+(.+):se nogrp
The value of grp is calculated using (group number * 2).
hl=1 Highlight text based on rules defined in conf.c
hlr=0 Highlight text in reverse direction
hll=0 Highlight current line based on filetype hl
hlp=0 Highlight "[]" "()" "{}" pairs based on filetype hl
hlw=0 Highlight current word based on filetype hl
led=1 Enable all terminal output
vis=0 Control startup flags
Example: disable :e message in ex mode
:se vis=12
Example: disable :e message in vi mode
:se vis=8
Example: enable raw ex mode
:se vis=6
Example: disable raw ex mode
:se vis=4
mpt=0 Control vi prompts
When set to 0 after an ex command is called from vi, disables
the "[any key to continue]" prompt.
If mpt is negative, the prompt will remain disabled.
order=1
Reorder characters based on rules defined in conf.c
shape=1
Perform Arabic script letter shaping
pac=0 Print autocomplete suggestions on the fly
tbs=8 Number of spaces used to represent a tab
td=1 Current text direction context
This option accepts four meaningful values:
+2 Exclusively left-to-right
+1 Follow dircontexts[] (in conf.c), defaulting to left-to-
right
-1 Follow dircontexts[], defaulting to right-to-left
-2 Exclusively right-to-left
pr=0 Print register
Set a special register using a character or a number.
Once the register is set, all data passed into ex_print will
be stored in the register.
If the register is uppercase, <Newline> characters are added
to match the exact output that was printed.
Example: paste current buffer list exactly like from :b command
:se pr=A:ya! a:b:pu a
Example: store a line printed with :p
:se pr=A:ya! a:p
sep=: Ex separator
Set Ex command separator character.
Changing default <:> separator will break some built-in commands/macros.
Example: set separator to <|>
:se sep=|
Example: disable separator
:se nosep
EXINIT ENV VAR
EXINIT defines a sequence of vi/ex commands to be performed
at startup. Consequently, this is the primary way for scripting
and customizing Nextvi outside of C.
Many standard text processing utils such as grep, awk, sed
can be replaced by Nextvi with EXINIT in mind.
Examples:
export EXINIT=$'e ./vi.c:& i\x7\x3:bx 1:bx'
Index vi.c for autocomplete
export EXINIT='b-1:%r ./vi.c:b-1'
Load vi.c into a history buffer
export EXINIT=$'e:& io{\n}\x16\x3kA\x3:& 1G:& 2\"ayy'
Setup @ macro in register <a>
@a macro creates <{> and closing <}> below the cursor leaving
cursor in insert mode in between the braces.
REGEX
Nextvi's regex syntax is akin to that of Plan 9.
Disregard manpage notation for <{ } [ ]> in this section.
. match any single char
^ assert start of the line
$ assert end of the line
{N,M} match N to M times
() grouping
(?:) non capture grouping
[N-M] match a set of alternate ranges N to M
* repeated zero or more times
+ repeated one or more times
| union, alternative branch
\< assert start of the word
\> assert end of the word
? one or zero matches greedy
?? one or zero matches lazy
Additionally, Nextvi supports static lookahead expressions.
/[=abc]
find <a> followed by "bc"
/[!abc]
find anything except <a> followed by "bc"
/[!abc!cda!qwe]
multiple lookahead alternatives in one bracket exp
/[!abc^=123]
disable lookahead after "^=" specifier and match [123] normally
SPECIAL MARKS
* position of the previous change
[ first line of the previous change
] last line of the previous change
' position of the previous line region
` position of the previous line region
SPECIAL REGISTERS
/ previous search keyword
: previous ex command
0 previous value of default register (atomic)
Atomic means the operation did not include a <Newline>.
1-9 previous value(s) of default register (nonatomic)
CODE MAP
+--------------+----------------------+
| 505 vi.h | definitions/aux |
| 537 kmap.h | keymap translation |
+--------------+----------------------+
| 293 conf.c | hl/ft/td config |
| 341 term.c | low level IO |
| 380 ren.c | positioning/syntax |
| 523 lbuf.c | file/line buffer |
| 650 uc.c | UTF-8 support |
| 658 regex.c | extended RE |
| 675 led.c | insert mode/output |
| 1240 ex.c | ex options/commands |
| 1951 vi.c | normal mode/general |
| 6711 total | wc -l *.c|sort |
+--------------+----------------------+
COMPILING
export CC='g++ -x c'
set compiler, g++ example
export CFLAGS='-s'
set CFLAGS, strip example
./cbuild.sh
build once
./cbuild.sh build
build
./cbuild.sh debug
build with -O0 -g
./cbuild.sh pgobuild
PGO build can lead to a significant performance boost on some
application specific tasks
./cbuild.sh install
install vi to $DESTDIR$PREFIX/bin
./cbuild.sh fetch
merge commits from upstream repository
./cbuild.sh bench
performance bench test 2000 word deletions on vi.c
PHILOSOPHY
In most text editors, flexibility is a minor or irrelevant design
goal. Nextvi is designed to be flexible where the editor adapts
to the user needs. This flexibility is achieved by heavily chaining
basic commands and allowing them to create new ones with completely
different functionality. Command reuse keeps the editor small
without infringing on your freedom to quickly get a good grasp
on the code. If you want to customize anything, you should be
able to do it using only core commands or a mix with some specific
C code for more difficult tasks. Simple and flexible design
allows for straight forward solutions to any problem long term
and filters bad inconsistent ideas.
"All software sucks, but some do more than others."
- Kyryl Melekhin
SEE ALSO
New functionality can be obtained through optional patches provided
in the patches branch. If you have a meaningful contribution
and would love to be made public the patch can be submitted
via email or github pull request.
https://github.com/kyx0r/nextvi/tree/patches
Scripts used to generate this manual are located in the manual
branch.
https://github.com/kyx0r/nextvi/tree/manual
Q: What is pikevm?
A: Pikevm is a complete rewrite of Nextvi's regex engine for
the purposes of getting rid of backtracking and severe performance
and memory constraints. Pikevm guarantees that all regular expressions
are computed in constant space and O(n+k) time where n is size
of the string and k is some constant for the complexity of the
regex i.e. number of state transitions. It is important to understand
that it does not mean that we run at O(n) linear speed, but
rather the amount of processing time & memory usage is distributed
evenly and linearly throughout the string, the k constant plays
a big role. If you are familiar with radix sort algorithms this
follows the same idea.
Q: What are the other benefits?
A: For example, now it is possible to compute a C comment
/* x */ where x can be an infinite number of characters. Of course,
this extends to every other valid regular expression.
Q: New features pikevm supports?
A: Additionally, pikevm supports PCRE style non capture group
(?:) and lazy quantifiers like .*? and .+?? because they were
easy to implement and allow for further regex profiling/optimization.
Q: NFA vs DFA (identify)
A: pikevm = NFA backtrack = DFA
Q: What's wrong with original implementation?
A: Nothing except it being slow and limited. My improved version
of Ali's DFA implementation ran 3.5X faster in any case, however
I found a bug with it where zero quantifier "?" nested groups
compute wrong submatch results. To fix this problem, it would
require to undo a lot of optimization work already done, basically
going back to how slow Ali's implementation would be. The reason
this was spotted so late was because this kind of regex wasn't
used before, so I never tested it. Other than that I think submatch
extraction is correct on other cases. Pikevm does not have this
bug, so it will be used as main regex engine from now on, unless
dfa ever finds a proper fix. Honestly, this change isn't so
surprising, as I was working on pikevm a few months prior, to
favor a superior algorithm.
You can still find that code here (likely with no updates):
https://github.com/kyx0r/nextvi/tree/dfa_dead
As a downside, NFA simulation loses the DFA property of being
able to quickly short circuit a match, as everything runs linearly
and at constant speed, incurring match time overhead. Well optimized
DFA engine can outperform pikevm, but that is rather rare as
they got problems of their own. For example as independently
benchmarked, dfa_dead runs only 13% faster than pikevm and that
is stretching the limit of what is physically possible on a
table based matcher. Can't cheat mother nature, and if you dare
to try she's unforgiving at best.
Supplementary reading by Russ Cox:
https://swtch.com/~rsc/regexp/regexp1.html
Original Neatvi repository:
https://github.com/aligrudi/neatvi
Posix vi(1)
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html
Posix ex(1)
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html