README: add a paragraph about distribution packages
[vis.git] / README.md
blobda9ccf3edcef633750f4c44a7e7f20a565041a79
1 Vis a vim-like text editor
2 ==========================
4 Vis aims to be a modern, legacy free, simple yet efficient vim-like editor.
6 As an universal editor it has decent Unicode support (including double width
7 and combining characters) and should cope with arbitrary files including:
9  - large (up to a few Gigabytes) ones including
10    - Wikipedia/OpenStreetMap XML / SQL / CVS dumps
11    - amalgamated source trees (e.g. SQLite)
12  - single line ones e.g. minified JavaScript
13  - binary ones e.g. ELF files
15 Efficient syntax highlighting is provided using Parsing Expression Grammars
16 which can be conveniently expressed using Lua in form of LPeg.
18 The editor core is written in a reasonable amount of clean (your mileage
19 may vary), modern and legacy free C code enabling it to run in resource
20 constrained environments. The implementation should be easy to hack on
21 and encourage experimentation (e.g. native built in support for multiple
22 cursors). There also exists a Lua API for in process extensions.
24 Vis strives to be *simple* and focuses on its core task: efficient text
25 management. As an example the file open dialog is provided by an independent
26 utility. There exist plans to use a client/server architecture, delegating
27 window management to your windowing system or favorite terminal multiplexer.
29 The intention is *not* to be bug for bug compatible with vim, instead a 
30 similar editing experience should be provided. The goal could thus be
31 summarized as "80% of vim's features implemented in roughly 1% of the code".
33 ![vis demo](https://raw.githubusercontent.com/martanne/vis/gh-pages/screencast.gif)
35 Getting started / Build instructions
36 ====================================
38 In order to build vis you will need a C99 compiler as well as:
40  * a C library, we recommend [musl](http://www.musl-libc.org/)
41  * [libcurses](http://www.gnu.org/software/ncurses/), preferably in the
42    wide-character version
43  * [libtermkey](http://www.leonerd.org.uk/code/libtermkey/)
44  * [lua](http://www.lua.org/) >= 5.2 (optional)
45  * [LPeg](http://www.inf.puc-rio.br/~roberto/lpeg/) >= 0.12
46    (optional runtime dependency required for syntax highlighting)
48 Assuming these dependencies are met, execute:
50     $ ./configure && make && sudo make install
52 By default the `configure` script will try to auto detect support for
53 Lua. See `configure --help` for a list of supported options. You can
54 also manually tweak the generated `config.mk` file.
56 On Linux based systems `make standalone` will attempt to download,
57 compile and install all of the above dependencies into a subfolder
58 inorder to build a self contained statically linked binary.
60 `make local` will do the same but only for libtermkey, Lua and LPeg
61 (i.e. the system C and curses libraries are used).
63 Or simply use one of the distribution provided packages:
65  * [ArchLinux](http://www.archlinux.org/packages/?q=vis)
67 Editing Features
68 ================
70 The following section gives a quick overview over the currently
71 supported features.
73 ###  Operators
75     d   (delete)
76     c   (change)
77     y   (yank)
78     p   (put)
79     >   (shift-right)
80     <   (shift-left)
81     J   (join)
82     ~   (swap case)
83     gu  (make lowercase)
84     gU  (make uppercase)
85     !   (filter)
86     =   (format using fmt(1))
88 Operators can be forced to work line wise by specifying `V`.
90 ### Movements
92     h        (char left)
93     l        (char right)
94     j        (line down)
95     k        (line up)
96     gj       (display line down)
97     gk       (display line up)
98     0        (start of line)
99     ^        (first non-blank of line)
100     g_       (last non-blank of line)
101     $        (end of line)
102     %        (match bracket)
103     b        (previous start of a word)
104     B        (previous start of a WORD)
105     w        (next start of a word)
106     W        (next start of a WORD)
107     e        (next end of a word)
108     E        (next end of a WORD)
109     ge       (previous end of a word)
110     gE       (previous end of a WORD)
111     {        (previous paragraph)
112     }        (next paragraph)
113     (        (previous sentence)
114     )        (next sentence)
115     [[       (previous start of C-like function)
116     []       (previous end of C-like function)
117     ][       (next start of C-like function)
118     ]]       (next end of C-like function)
119     gg       (begin of file)
120     g0       (begin of display line)
121     gm       (middle of display line)
122     g$       (end of display line)
123     G        (goto line or end of file)
124     |        (goto column)
125     n        (repeat last search forward)
126     N        (repeat last search backwards)
127     H        (goto top/home line of window)
128     M        (goto middle line of window)
129     L        (goto bottom/last line of window)
130     *        (search word under cursor forwards)
131     #        (search word under cursor backwards)
132     f{char}  (to next occurrence of char to the right)
133     t{char}  (till before next occurrence of char to the right)
134     F{char}  (to next occurrence of char to the left)
135     T{char}  (till before next occurrence of char to the left)
136     ;        (repeat last to/till movement)
137     ,        (repeat last to/till movement but in opposite direction)
138     /{text}  (to next match of text in forward direction)
139     ?{text}  (to next match of text in backward direction)
140     `{mark}  (go to mark)
141     '{mark}  (go to start of line containing mark)
143   An empty line is currently neither a word nor a WORD.
145   Some of these commands do not work as in vim when prefixed with a
146   digit i.e. a multiplier. As an example in vim `3$` moves to the end
147   of the 3rd line down. However vis treats it as a move to the end of
148   current line which is repeated 3 times where the last two have no
149   effect.
151 ### Text objects
153   All of the following text objects are implemented in an inner variant
154   (prefixed with `i`) and a normal variant (prefixed with `a`):
156     w  word
157     W  WORD
158     s  sentence
159     p  paragraph
160     [,], (,), {,}, <,>, ", ', `         block enclosed by these symbols
162   For sentence and paragraph there is no difference between the
163   inner and normal variants.
165     gn      matches the last used search term in forward direction
166     gN      matches the last used search term in backward direction
168   Additionally the following text objects, which are not part of stock vim
169   are also supported:
171     ae      entire file content
172     ie      entire file content except for leading and trailing empty lines
173     af      C-like function definition including immediately preceding comments
174     if      C-like function definition only function body
175     al      current line
176     il      current line without leading and trailing white spaces
178 ### Modes
180   Vis implements more or less functional normal, operator-pending, insert,
181   replace and visual (in both line and character wise variants) modes.
182   
183   Visual block mode is not implemented and there exists no immediate
184   plan to do so. Instead vis has built in support for multiple cursors.
186   Command mode is implemented as a regular file. Use the full power of the
187   editor to edit your commands / search terms.
189   Ex mode is deliberately not implemented, use `ssam(1)` if you need a
190   stream editor.
191   
192 ### Multiple Cursors / Selections
194   vis supports multiple cursors with immediate visual feedback (unlike
195   in the visual block mode of vim where for example inserts only become
196   visible upon exit). There always exists one primary cursor located
197   within the current view port. Additional cursors ones can be created
198   as needed. If more than one cursor exists, the primary one is blinking.
199   
200   To manipulate multiple cursors use in normal mode:
201   
202     Ctrl-K       create count new cursors on the lines above
203     Ctrl-Meta-K  create count new cursors on the lines above the first cursor
204     Ctrl-J       create count new cursors on the lines below
205     Ctrl-Meta-J  create count new cursors on the lines below the last cursor
206     Ctrl-P       remove primary cursor
207     Ctrl-N       select word the cursor is currently over, switch to visual mode
208     Ctrl-U       make the count previous cursor primary
209     Ctrl-D       make the count next cursor primary
210     Tab          try to align all cursor on the same column
211     Esc          dispose all but the primary cursor
213   Visual mode was enhanced to recognize:
214     
215     I            create a cursor at the start of every selected line
216     A            create a cursor at the end of every selected line
217     Tab          left align selections by inserting spaces
218     Shift-Tab    right align selections by inserting spaces
219     Ctrl-N       create new cursor and select next word matching current selection
220     Ctrl-X       clear (skip) current selection, but select next matching word
221     Ctrl-P       remove primary cursor
222     Ctrl-U       make the count previous cursor primary
223     Ctrl-D       make the count next cursor primary
224     Esc          clear all selections, switch to normal mode
226   In insert/replace mode
228     Shift-Tab    align all cursors by inserting spaces
230 ### Marks
232     [a-z] general purpose marks
233     <     start of the last selected visual area in current buffer
234     >     end of the last selected visual area in current buffer
236   No marks across files are supported. Marks are not preserved over
237   editing sessions.
239 ### Registers
241   Supported registers include:
243     "a-"z   general purpose registers
244     "A-"Z   append to corresponding general purpose register
245     "*, "+  system clipboard integration via shell script vis-clipboard
246     "0      yank register
247     "/      search register
248     ":      command register
249     "_      black hole (/dev/null) register
251   If no explicit register is specified a default register is used.
253 ### Undo/Redo and Repeat
255   The text is currently snapshotted whenever an operator is completed as
256   well as when insert or replace mode is left. Additionally a snapshot
257   is also taken if in insert or replace mode a certain idle time elapses.
258   
259   Another idea is to snapshot based on the distance between two consecutive
260   editing operations (as they are likely unrelated and thus should be
261   individually reversible).
263   Besides the regular undo functionality, the key bindings `g+` and `g-`
264   traverse the history in chronological order. Further more the `:earlier`
265   and `:later` commands provide means to restore the text to an arbitrary
266   state.
268   The repeat command `.` works for all operators and is able to repeat
269   the last insertion or replacement.
271 ### Macros
273   The general purpose registers `[a-z]` can be used to record macros. Use
274   one of `[A-Z]` to append to an existing macro. `q` starts a recording,
275   `@` plays it back. `@@` refers to the least recently recorded macro.
276   `@:` repeats the last :-command. `@/` is equivalent to `n` in normal mode.
278 ### Command line prompt
280   At the `:`-command prompt only the following commands are recognized, any
281   valid unique prefix can be used:
283     :nnn          go to line nnn
284     :bdelete      close all windows which display the same file as the current one
285     :edit         replace current file with a new one or reload it from disk
286     :open         open a new window
287     :qall         close all windows, exit editor
288     :quit         close currently focused window
289     :read         insert content of another file at current cursor position
290     :split        split window horizontally
291     :vsplit       split window vertically
292     :new          open an empty window, arrange horizontally
293     :vnew         open an empty window, arrange vertically
294     :wq           write changes then close window
295     :xit          like :wq but write only when changes have been made
296     :write        write current buffer content to file
297     :saveas       save file under another name
298     :substitute   search and replace currently implemented in terms of `sed(1)`
299     :earlier      revert to older text state
300     :later        revert to newer text state
301     :map          add a global key mapping
302     :unmap        remove a global key mapping
303     :map-window   add a window local key mapping
304     :unmap-window remove a window local key mapping
305     :langmap      set key equivalents for layout specific key mappings
306     :!            filter range through external command
307     :|            pipe range to external command and display output in a new window
308     :set          set the options below
310      tabwidth   [1-8]           default 8
312        set display width of a tab and number of spaces to use if
313        expandtab is enabled
315      expandtab  (yes|no)        default no
317        whether typed in tabs should be expanded to tabwidth spaces
319      autoindent (yes|no)        default no
321        replicate spaces and tabs at the beginning of the line when
322        starting a new line.
324      number         (yes|no)    default no
325      relativenumber (yes|no)    default no
327        whether absolute or relative line numbers are printed alongside
328        the file content
330      syntax      name           default yes
332        use syntax definition given (e.g. "c") or disable syntax
333        highlighting if no such definition exists (e.g :set syntax off)
335      show
337        show/hide special white space replacement symbols
339        newlines = [0|1]         default 0
340        tabs     = [0|1]         default 0
341        spaces   = [0|1]         default 0
343      cursorline (yes|no)        default no
345        highlight the line on which the cursor currently resides
347      colorcolumn number         default 0
349        highlight the given column
351      theme      name            default dark-16.lua | solarized.lua (16 | 256 color)
353        use the given theme / color scheme for syntax highlighting
355   Each command can be prefixed with a range made up of a start and
356   an end position as in start,end. Valid position specifiers are:
358     .          start of the current line
359     +n and -n  start of the line relative to the current line
360     'm         position of mark m
361     /pattern/  first match after current position
363   If only a start position without a command is given then the cursor
364   is moved to that position. Additionally the following ranges are
365   predefined:
367     %          the whole file, equivalent to 1,$
368     *          the current selection, equivalent to '<,'>
370   History support, tab completion and wildcard expansion are other
371   worthwhile features. However implementing them inside the editor feels
372   wrong. For now you can use the `:edit` command with a pattern or a
373   directory like this.
375     :e *.c
376     :e .
378   vis will call the `vis-open` script which invokes dmenu or slmenu
379   with the files corresponding to the pattern. The file you select in
380   dmenu/slmenu will be opened in vis.
382 ### Runtime Configurable Key Bindings
384 Vis supports run time key bindings via the `:{un,}map{,-window}` set of
385 commands. The basic syntax is:
387     :map <mode> <lhs> <rhs>
389 where mode is one of `normal`, `insert`, `replace`, `visual`,
390 `visual-line` or `operator-pending`. lhs refers to the key to map, rhs is
391 a key action or alias. An existing mapping can be overridden by appending
392 `!` to the map command.
394 Key mappings are always recursive, this means doing something like:
396     :map! normal j 2j
398 will not work because it will enter an endless loop. Instead vis uses
399 pseudo keys referred to as key actions which can be used to invoke a set
400 of available (see :help or <F1> for a list) editor functions. Hence the
401 correct thing to do would be:
403     :map! normal j 2<cursor-line-down>
405 Unmapping works as follows:
407     :unmap <lhs>
409 The commands suffixed with `-window` only affect the currently active window.
411 ### Layout Specific Key Bindings
413 Vis allows to set key equivalents for non-latin keyboard layouts. This
414 facilitates editing non-latin texts. The defined mappings take effect
415 in all non-input modes, i.e. everywhere except in insert and replace mode.
417 For example, the following maps the movement keys in Russian layout:
419     :langmap Ñ€Ð¾Ð»Ð´ hjkl
421 More generally the syntax of the `:langmap` command is:
423     :langmap <sequence of keys in your layout> <sequence of equivalent keys in latin layout>
425 If the key sequences have not the same length, the rest of the longer
426 sequence will be discarded.
428 ### Tab <-> Space conversion and Line endings \n vs \r\n
430   Tabs can optionally be expanded to a configurable number of spaces.
431   The first line ending in the file determines what will be inserted
432   upon a line break (defaults to \n).
434 ### Jump list and change list
436   A per window, file local jump list (navigate with `CTRL+O` and `CTRL+I`)
437   and change list (navigate with `g;` and `g,`) is supported. The jump
438   list is implemented as a fixed sized ring buffer.
440 ### Mouse support
442   The mouse is currently not used at all.
444 ### Non Goals
446   Some of the features of vim which will *not* be implemented:
448    - tabs / multiple workspaces / advanced window management
449    - file and directory browser
450    - support for file archives (tar, zip, ...)
451    - support for network protocols (ftp, http, ssh ...)
452    - encryption
453    - compression
454    - GUIs (neither x11, motif, gtk, win32 ...) although the codebase
455      should make it easy to add them
456    - VimL
457    - plugins (certainly not vimscript, if anything it should be lua based)
458    - right-to-left text
459    - ex mode (if you need a stream editor use `ssam(1)`
460    - diff mode
461    - vimgrep
462    - internal spell checker
463    - compile time configurable features / `#ifdef` mess
465 Lua API for in process extension
466 ================================
468 Vis provides a simple Lua API for in process extension. At startup the
469 `visrc.lua` file is executed, this can be used to register a few event
470 callbacks which will be invoked from the editor core. While executing
471 these user scripts the editor core is blocked, hence it is intended for
472 simple short lived (configuration) tasks.
474 At this time there exists no API stability guarantees.
476  - `vis`
477    - `MODE_NORMAL`, `MODE_OPERATOR_PENDING`, `MODE_INSERT`, `MODE_REPLACE`, `MODE_VISUAL`, `MODE_VISUAL_LINE` mode constants
478    - `lexers` LPeg lexer support module
479    - `events` hooks
480      - `start()`
481      - `quit()`
482      - `win_open(win)`
483      - `win_close(win)`
484    - `files()` iterator
485    - `windows()` iterator
486    - `command(cmd)`
487    - `info(msg)`
488    - `open(filename)`
489    - `textobject_register(function)` register a Lua function as a text object, returns associated `id` or `-1`
490    - `textobject(id)` select/execute a text object
491    - `motion_register(function)` register a Lua function as a motion, returns associated `id` or `-1`
492    - `motion(id)` select/execute a motion
493    - `map(mode, key, function)` map a Lua function to `key` in `mode`
494  - `file`
495    - `content(pos, len)`
496    - `insert(pos, data)`
497    - `delete(pos, len)`
498    - `lines_iterator()`
499    - `name`
500    - `lines[0..#lines+1]` array giving read/write access to lines
501  - `window`
502    - `file`
503    - `syntax` lexer name used for syntax highlighting or `nil`
504    - `cursor`
505      - `line` (1 based), `col` (0 based)
506      - `to(line, col)`
507      - `pos` bytes from start of file (0 based)
509 Most of the exposed objects are managed by the C core. Allthough there
510 is a simple object life time management mechanism in place, it is still
511 recommended to *not* let the Lua objects escape from the event handlers
512 (e.g. by assigning to global Lua variables).
514 Text management using a piece table/chain
515 =========================================
517 The core of this editor is a persistent data structure called a piece
518 table which supports all modifications in `O(m)`, where `m` is the number
519 of non-consecutive editing operations. This bound could be further
520 improved to `O(log m)` by use of a balanced search tree, however the
521 additional complexity doesn't seem to be worth it, for now.
523 The actual data is stored in buffers which are strictly append only.
524 There exist two types of buffers, one fixed-sized holding the original
525 file content and multiple append-only ones storing the modifications.
527 A text, i.e. a sequence of bytes, is represented as a double linked
528 list of pieces each with a pointer into a buffer and an associated
529 length. Pieces are never deleted but instead always kept around for
530 redo/undo support. A span is a range of pieces, consisting of a start
531 and end piece. Changes to the text are always performed by swapping
532 out an existing, possibly empty, span with a new one.
534 An empty document is represented by two special sentinel pieces which
535 always exist:
537     /-+ --> +-\
538     | |     | |
539     \-+ <-- +-/
540      #1     #2
542 Loading a file from disk is as simple as mmap(2)-ing it into a buffer,
543 creating a corresponding piece and adding it to the double linked list.
544 Hence loading a file is a constant time operation i.e. independent of
545 the actual file size (assuming the operating system uses demand paging).
547     /-+ --> +-----------------+ --> +-\
548     | |     | I am an editor! |     | |
549     \-+ <-- +-----------------+ <-- +-/
550      #1             #3              #2
552 Insert
553 ------
555 Inserting a junk of data amounts to appending the new content to a
556 modification buffer. Followed by the creation of new pieces. An insertion
557 in the middle of an existing piece requires the creation of 3 new pieces.
558 Two of them hold references to the text before respectively after the
559 insertion point. While the third one points to the newly added text.
561     /-+ --> +---------------+ --> +----------------+ --> +--+ --> +-\
562     | |     | I am an editor|     |which sucks less|     |! |     | |
563     \-+ <-- +---------------+ <-- +----------------+ <-- +--+ <-- +-/
564      #1            #4                   #5                #6      #2
566            modification buffer content: "which sucks less"
568 During this insertion operation the old span [3,3] has been replaced
569 by the new span [4,6]. Notice that the pieces in the old span were not
570 changed, therefore still point to their predecessors/successors, and can
571 thus be swapped back in.
573 If the insertion point happens to be at a piece boundary, the old span
574 is empty, and the new span only consists of the newly allocated piece.
576 Delete
577 ------
579 Similarly a delete operation splits the pieces at appropriate places.
581     /-+ --> +-----+ --> +--+ --> +-\
582     | |     | I am|     |! |     | |
583     \-+ <-- +-----+ <-- +--+ <-- +-/
584      #1       #7         #6      #2
586 Where the old span [4,5] got replaced by the new span [7,7]. The underlying
587 buffers remain unchanged.
589 Cache
590 -----
592 Notice that the common case of appending text to a given piece is fast
593 since, the new data is simply appended to the buffer and the piece length
594 is increased accordingly. In order to keep the number of pieces down,
595 the least recently edited piece is cached and changes to it are done
596 in place (this is the only time buffers are modified in a non-append
597 only way). As a consequence they can not be undone.
599 Undo/redo
600 ---------
602 Since the buffers are append only and the spans/pieces are never destroyed
603 undo/redo functionality is implemented by swapping the required spans/pieces
604 back in.
606 As illustrated above, each change to the text is recorded by an old and
607 a new span. An action consists of multiple changes which logically belong
608 to each other and should thus also be reverted together. For example
609 a search and replace operation is one action with possibly many changes
610 all over the text.
612 The text states can be marked by means of a snapshotting operation.
613 Snapshotting saves a new node to the history graph and creates a fresh
614 Action to which future changes will be appended until the next snapshot.
616 Actions make up the nodes of a connected digraph, each representing a state
617 of the file at some time during the current editing session. The edges of the
618 digraph represent state transitions that are supported by the editor. The edges
619 are implemented as four Action pointers (`prev`, `next`, `earlier`, and `later`).
621 The editor operations that execute the four aforementioned transitions
622 are `undo`, `redo`,`earlier`, and `later`, respectively. Undo and
623 redo behave in the traditional manner, changing the state one Action
624 at a time. Earlier and later, however, traverse the states in chronological
625 order, which may occasionally involve undoing and redoing many Actions at once.
627 Marks
628 -----
630 Because we are working with a persistent data structure marks can be
631 represented as pointers into the underlying (append only) buffers.
632 To get the position of an existing mark it suffices to traverse the
633 list of pieces and perform a range query on the associated buffer
634 segments. This also nicely integrates with the undo/redo mechanism.
635 If a span is swapped out all contained marks (pointers) become invalid
636 because they are no longer reachable from the piece chain. Once an
637 action is undone, and the corresponding span swapped back in, the
638 marks become visible again. No explicit mark management is necessary.
640 Properties
641 ----------
643 The main advantage of the piece chain as described above is that all
644 operations are performed independent of the file size but instead linear
645 in the number of pieces i.e. editing operations. The original file buffer
646 never changes which means the `mmap(2)` can be performed read only which
647 makes optimal use of the operating system's virtual memory / paging system.
649 The maximum editable file size is limited by the amount of memory a process
650 is allowed to map into its virtual address space, this shouldn't be a problem
651 in practice. The whole process assumes that the file can be used as is.
652 In particular the editor assumes all input and the file itself is encoded
653 as UTF-8. Supporting other encodings would require conversion using `iconv(3)`
654 or similar upon loading and saving the document.
656 Similarly the editor has to cope with the fact that lines can be terminated
657 either by `\n` or `\r\n`. There is no conversion to a line based structure in
658 place. Instead the whole text is exposed as a sequence of bytes. All
659 addressing happens by means of zero based byte offsets from the start of
660 the file.
662 The main disadvantage of the piece chain data structure is that the text
663 is not stored contiguous in memory which makes seeking around somewhat
664 harder. This also implies that standard library calls like the `regex(3)`
665 functions can not be used as is. However this is the case for all but
666 the most simple data structures used in text editors.
668 Syntax Highlighting using Parsing Expression Grammars
669 =====================================================
671 [Parsing Expression Grammars](https://en.wikipedia.org/wiki/Parsing_expression_grammar)
672 (PEG) have the nice property that they are closed under composition.
673 In the context of an editor this is useful because lexers can be
674 embedded into each other, thus simplifying syntax highlighting
675 definitions.
677 Vis reuses the [Lua](http://www.lua.org/) [LPeg](http://www.inf.puc-rio.br/~roberto/lpeg/)
678 based lexers from the [Scintillua](http://foicica.com/scintillua/) project.
680 Future Plans / Ideas
681 ====================
683 This section contains some ideas for further architectural changes.
685 Event loop with asynchronous I/O
686 --------------------------------
688 The editor core should feature a proper main loop mechanism supporting
689 asynchronous non-blocking and always cancelable tasks which could be
690 used for all possibly long lived actions such as:
692  - `!`, `=` operators
693  - `:substitute` and `:write` commands
694  - code completion
695  - compiler integration (similar to vim's quick fix functionality)
697 Client/Server Architecture / RPC interface
698 ------------------------------------------
700 In principle it would be nice to follow a similar client/server approach
701 as [sam/samterm](http://sam.cat-v.org/) i.e. having the main editor as a
702 server and each window as a separate client process with communication
703 over a unix domain socket.
705 That way window management would be taken care of by dwm or dvtm and the
706 different client processes would still share common cut/paste registers
707 etc.
709 This would also enable a language agnostic plugin system.
711 Efficient Search and Replace
712 ----------------------------
714 Currently the editor copies the whole text to a contiguous memory block
715 and then uses the standard regex functions from libc. Clearly this is not
716 a satisfactory solution for large files.
718 The long term solution is to write our own regular expression engine or
719 modify an existing one to make use of the iterator API. This would allow
720 efficient search without having to double memory consumption.
722 The used regex engine should use a non-backtracking algorithm. Useful
723 resources include:
725  - [Russ Cox's regex page](http://swtch.com/~rsc/regexp/)
726  - [TRE](https://github.com/laurikari/tre) as
727    [used by musl](http://git.musl-libc.org/cgit/musl/tree/src/regex)
728    which uses a parallel [TNFA matcher](http://laurikari.net/ville/spire2000-tnfa.ps)
729  - [Plan9's regex library](http://plan9.bell-labs.com/sources/plan9/sys/src/libregexp/)
730    which has its root in Rob Pike's sam text editor
731  - [RE2](https://github.com/google/re2) C++ regex library
733 Developer Overview
734 ==================
736 A quick overview over the code structure to get you started:
738  File(s)             | Description
739  ------------------- | -----------------------------------------------------
740  `text.[ch]`         | low level text / marks / {un,re}do / piece table implementation
741  `text-motions.[ch]` | movement functions take a file position and return a new one
742  `text-objects.[ch]` | functions take a file position and return a file range
743  `text-regex.[ch]`   | text search functionality, designated place for regex engine
744  `text-util.[ch]`    | text related utility functions mostly dealing with file ranges
745  `view.[ch]`         | ui-independent viewport, shows part of a file, syntax highlighting, cursor placement, selection handling
746  `ui.h`              | abstract interface which has to be implemented by ui backends
747  `ui-curses.[ch]`    | a terminal / curses based user interface implementation
748  `buffer.[ch]`       | dynamically growing buffer used for registers and macros
749  `ring-buffer.[ch]`  | fixed size ring buffer used for the jump list
750  `map.[ch]`          | crit-bit tree based map supporting unique prefix lookups and ordered iteration. used to implement `:`-commands
751  `vis.h`             | vi(m) specific editor frontend library public API
752  `vis.c`             | vi(m) specific editor frontend implementation
753  `vis-core.h`        | internal header file, various structs for core editor primitives
754  `vis-cmds.c`        | vi(m) `:`-command implementation
755  `vis-modes.c`       | vi(m) mode switching, enter/leave event handling
756  `vis-motions.c`     | vi(m) cursor motion implementation
757  `vis-operators.c`   | vi(m) operator implementation
758  `vis-lua.c`         | Lua bindings, exposing core vis APIs for in process extension
759  `main.c`            | key action definitions, program entry point
760  `config.def.h`      | definition of default key bindings (mapping of key actions)
761  `visrc.lua`         | Lua startup and configuration script
762  `lexers/`           | Lua LPeg based lexers used for syntax highlighting
764 Testing infrastructure for the [low level text manipulation routines]
765 (https://github.com/martanne/vis/tree/test/test/text), [vim compatibility]
766 (https://github.com/martanne/vis/tree/test/test/vim) and [vis specific features]
767 (https://github.com/martanne/vis/tree/test/test/vis) is in place, but
768 lacks proper test cases.