commit c4b21b498e2896284eb2118e5510d8f07f20a64f
parent bdcfca1e5ce10b571d4ecacc9e2c3527f54fe226
Author: Henry Qin <root@hq6.me>
Date: Mon, 18 Mar 2019 11:42:18 -0700
Convert DesignNotes to Markdown to fix display in GitHub.
Diffstat:
A | DesignNotes.md | | | 186 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
D | DesignNotes.wiki | | | 187 | ------------------------------------------------------------------------------- |
2 files changed, 186 insertions(+), 187 deletions(-)
diff --git a/DesignNotes.md b/DesignNotes.md
@@ -0,0 +1,186 @@
+# Design Notes
+
+This file is meant to document design decisions and algorithms inside vimwiki
+which are too large for code comments, and not necessarily interesting to
+users. Please create a new section to document each behavior.
+
+## Formatting tables
+
+In vimwiki, formatting tables occurs dynamically, when navigating between cells
+and adding new rows in a table in the Insert mode, or statically, when pressing
+`gqq` or `gqw` (which are mappings for commands `VimwikiTableAlignQ` and
+`VimwikiTableAlignW` respectively) in the Normal mode. It also triggers when
+leaving Insert mode, provided variable `g:vimwiki_table_auto_fmt` is set. In
+this section, the original and the newer optimized algorithms of table
+formatting will be described and compared.
+
+### The older table formatting algorithm and why this is not optimal
+
+Let's consider a simple example. Open a new file, say _tmp.wiki_, and create a
+new table with command `VimwikiTable`. This should create a blank table.
+
+```
+| | | | | |
+|---|---|---|---|---|
+| | | | | |
+```
+
+Let's put the cursor in the first header column of the table, enter the Insert
+mode and type a name, say _Col1_. Then press _Tab_: the cursor will move to the
+second column of the header and the table will get aligned (in the context of
+the table formatting story, words _aligned_ and _formatted_ are considered as
+synonyms). Now the table looks as in the following snippet.
+
+```
+| Col1 | | | | |
+|------|---|---|---|---|
+| | | | | |
+```
+
+Then, when moving cursor to the first data row (i.e. to the third line of the
+table below the separator line) and typing anything here and there while
+navigating using _Tab_ or _Enter_ (pressing this creates a new row below the
+current row), the table shall keep formatting. Below is a result of such a
+random edit.
+
+```
+| Col1 | | | | |
+|------|-------|---|-------|----------|
+| | Data1 | | Data2 | |
+| | | | | New data |
+```
+
+The lowest row gets aligned when leaving the Insert mode. Let's copy _Data1_
+(using `viwy` or another keystroke) and paste it (using `p`) in the second data
+row of the first column. Now the table looks mis-aligned (as we did not enter
+the Insert mode).
+
+```
+| Col1 | | | | |
+|------|-------|---|-------|----------|
+| | Data1 | | Data2 | |
+| Data1 | | | | New data |
+```
+
+This is not a big problem though, because we can put the cursor at _any_ place
+in the table and press `gqq`: the table will get aligned.
+
+```
+| Col1 | | | | |
+|-------|-------|---|-------|----------|
+| | Data1 | | Data2 | |
+| Data1 | | | | New data |
+```
+
+Now let's make real problems! Move the cursor to the lowest row and copy it
+with `yy`. Then 500-fold paste it with `500p`. Now the table very long. Move
+the cursor to the lowest row (by pressing `G`), enter the Insert mode, and try
+a new random editing session by typing anything in cells with _Tab_ and _Enter_
+navigation interleaves. The editing got painfully slow, did not?
+
+The reason of the slowing down is the older table formatting algorithm. Every
+time _Tab_ or _Enter_ get pressed down, all rows in the table get visited to
+calculate a new alignment. Moreover, by design it may happen even more than
+once per one press!
+
+```vim
+function! s:kbd_create_new_row(cols, goto_first)
+ let cmd = "\<ESC>o".s:create_empty_row(a:cols)
+ let cmd .= "\<ESC>:call vimwiki#tbl#format(line('.'))\<CR>"
+ let cmd .= "\<ESC>0"
+ if a:goto_first
+ let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'c', line('.'))\<CR>"
+ else
+ let cmd .= (col('.')-1)."l"
+ let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\<CR>"
+ endif
+ let cmd .= "a"
+
+ return cmd
+endfunction
+```
+
+Function `s:kbd_create_new_row()` is called when _Tab_ or _Enter_ get pressed.
+Formatting of the whole table happens in function `vimwiki#tbl#format()`. But
+remember that leaving the Insert mode triggers re-formatting of a table when
+variable `g:vimwiki_table_auto_fmt` is set. This means that formatting of the
+whole table is called on all those multiple interleaves between the Insert and
+the Normal mode in `s:kbd_create_new_row` (notice `\<ESC>`, `o`, etc.).
+
+### The newer table formating algorithm
+
+The newer algorithm was introduced to struggle against performance issues when
+formatting large tables.
+
+Let's take the table from the previous example in an intermediate state.
+
+```
+| Col1 | | | | |
+|------|-------|---|-------|----------|
+| | Data1 | | Data2 | |
+| Data1 | | | | New data |
+```
+
+Then move the cursor to the first data row, copy it with `yy`, go down to the
+mis-aligned line, and press `5p`. Now we have a slightly bigger mis-aligned
+table.
+
+```
+| Col1 | | | | |
+|------|-------|---|-------|----------|
+| | Data1 | | Data2 | |
+| Data1 | | | | New data |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+```
+
+Go down to the lowest, the 7th, data row and press `gq1`. Nothing happened.
+Let's go to the second or the third data row and press `gq1` once again. Now
+the table gets aligned. Let's undo formatting with `u`, go to the fourth row,
+and press `gq1`. Now the table should look like in the following snippet.
+
+```
+| Col1 | | | | |
+|------|-------|---|-------|----------|
+| | Data1 | | Data2 | |
+| Data1 | | | | New data |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+| | Data1 | | Data2 | |
+```
+
+What a peculiar command! Does using it make any sense? Not much, honestly.
+Except it shows how the newer optimized table formatting algorithm works in the
+Insert mode.
+
+Indeed, the newer table formatting algorithm introduces a _viewport_ on a table.
+Now, when pressing _Tab_ or _Enter_ in the Insert mode, only a small part of
+rows are checked for possible formatting: two rows above the current line and
+the current line itself (the latter gets preliminary shrunk with function
+`s:fmt_row()`). If all three lines in the viewport are of the same length, then
+nothing happens (case 1 in the example). If the second or the shrunk current
+line is longer then the topmost line in the viewport, then the algorithm falls
+back to the older formatting algorithm and the whole table gets aligned
+(case 2). If the topmost line in the viewport is longer than the second
+and the shrunk current line, then the two lowest lines get aligned according to
+the topmost line (case 3).
+
+Performance of the newer formatting algorithm should not depend on the height
+of the table. The newer algorithm should also be consistent with respect to
+user editing experience. Indeed, as soon as a table should normally be edited
+row by row from the top to the bottom, dynamic formatting should be both fast
+(watching only three rows in a table, re-formatting only when the shrunk
+current row gets longer than any of the two rows above) and eager (a table
+should look formatted on every press on _Tab_ and _Enter_). However, the newer
+algorithm differs from the older algorithm when starting editing a mis-aligned
+table in an area where mis-aligned rows do not get into the viewport: in this
+case the newer algorithm will format the table partly (in the rows of the
+viewport) until one of the being edited cells grows in length to a value big
+enough to trigger the older algorithm and the whole table gets aligned. When
+partial formatting is not desirable, the whole table can be formatted by
+pressing `gqq` in the Normal mode.
diff --git a/DesignNotes.wiki b/DesignNotes.wiki
@@ -1,187 +0,0 @@
-= Design Notes =
-
-This file is meant to document design decisions and algorithms inside vimwiki
-which are too large for code comments, and not necessarily interesting to
-users. Please create a new section to document each behavior.
-
-== Formatting tables ==
-
-In vimwiki, formatting tables occurs dynamically, when navigating between cells
-and adding new rows in a table in the Insert mode, or statically, when pressing
-`gqq` or `gqw` (which are mappings for commands `VimwikiTableAlignQ` and
-`VimwikiTableAlignW` respectively) in the Normal mode. It also triggers when
-leaving Insert mode, provided variable `g:vimwiki_table_auto_fmt` is set. In
-this section, the original and the newer optimized algorithms of table
-formatting will be described and compared.
-
-=== The older table formatting algorithm and why this is not optimal ===
-
-Let's consider a simple example. Open a new file, say _tmp.wiki_, and create a
-new table with command `VimwikiTable`. This should create a blank table.
-
-{{{
-| | | | | |
-|---|---|---|---|---|
-| | | | | |
-}}}
-
-Let's put the cursor in the first header column of the table, enter the Insert
-mode and type a name, say _Col1_. Then press _Tab_: the cursor will move to the
-second column of the header and the table will get aligned (in the context of
-the table formatting story, words _aligned_ and _formatted_ are considered as
-synonyms). Now the table looks as in the following snippet.
-
-{{{
-| Col1 | | | | |
-|------|---|---|---|---|
-| | | | | |
-}}}
-
-Then, when moving cursor to the first data row (i.e. to the third line of the
-table below the separator line) and typing anything here and there while
-navigating using _Tab_ or _Enter_ (pressing this creates a new row below the
-current row), the table shall keep formatting. Below is a result of such a
-random edit.
-
-{{{
-| Col1 | | | | |
-|------|-------|---|-------|----------|
-| | Data1 | | Data2 | |
-| | | | | New data |
-}}}
-
-The lowest row gets aligned when leaving the Insert mode. Let's copy _Data1_
-(using `viwy` or another keystroke) and paste it (using `p`) in the second data
-row of the first column. Now the table looks mis-aligned (as we did not enter
-the Insert mode).
-
-{{{
-| Col1 | | | | |
-|------|-------|---|-------|----------|
-| | Data1 | | Data2 | |
-| Data1 | | | | New data |
-}}}
-
-This is not a big problem though, because we can put the cursor at _any_ place
-in the table and press `gqq`: the table will get aligned.
-
-{{{
-| Col1 | | | | |
-|-------|-------|---|-------|----------|
-| | Data1 | | Data2 | |
-| Data1 | | | | New data |
-}}}
-
-Now let's make real problems! Move the cursor to the lowest row and copy it
-with `yy`. Then 500-fold paste it with `500p`. Now the table very long. Move
-the cursor to the lowest row (by pressing `G`), enter the Insert mode, and try
-a new random editing session by typing anything in cells with _Tab_ and _Enter_
-navigation interleaves. The editing got painfully slow, did not?
-
-The reason of the slowing down is the older table formatting algorithm. Every
-time _Tab_ or _Enter_ get pressed down, all rows in the table get visited to
-calculate a new alignment. Moreover, by design it may happen even more than
-once per one press!
-
-{{{vim
-function! s:kbd_create_new_row(cols, goto_first)
- let cmd = "\<ESC>o".s:create_empty_row(a:cols)
- let cmd .= "\<ESC>:call vimwiki#tbl#format(line('.'))\<CR>"
- let cmd .= "\<ESC>0"
- if a:goto_first
- let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'c', line('.'))\<CR>"
- else
- let cmd .= (col('.')-1)."l"
- let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\<CR>"
- endif
- let cmd .= "a"
-
- return cmd
-endfunction
-}}}
-
-Function `s:kbd_create_new_row()` is called when _Tab_ or _Enter_ get pressed.
-Formatting of the whole table happens in function `vimwiki#tbl#format()`. But
-remember that leaving the Insert mode triggers re-formatting of a table when
-variable `g:vimwiki_table_auto_fmt` is set. This means that formatting of the
-whole table is called on all those multiple interleaves between the Insert and
-the Normal mode in `s:kbd_create_new_row` (notice `\<ESC>`, `o`, etc.).
-
-=== The newer table formating algorithm ===
-
-The newer algorithm was introduced to struggle against performance issues when
-formatting large tables.
-
-Let's take the table from the previous example in an intermediate state.
-
-{{{
-| Col1 | | | | |
-|------|-------|---|-------|----------|
-| | Data1 | | Data2 | |
-| Data1 | | | | New data |
-}}}
-
-Then move the cursor to the first data row, copy it with `yy`, go down to the
-mis-aligned line, and press `5p`. Now we have a slightly bigger mis-aligned
-table.
-
-{{{
-| Col1 | | | | |
-|------|-------|---|-------|----------|
-| | Data1 | | Data2 | |
-| Data1 | | | | New data |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-}}}
-
-Go down to the lowest, the 7th, data row and press `gq1`. Nothing happened.
-Let's go to the second or the third data row and press `gq1` once again. Now
-the table gets aligned. Let's undo formatting with `u`, go to the fourth row,
-and press `gq1`. Now the table should look like in the following snippet.
-
-{{{
-| Col1 | | | | |
-|------|-------|---|-------|----------|
-| | Data1 | | Data2 | |
-| Data1 | | | | New data |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-| | Data1 | | Data2 | |
-}}}
-
-What a peculiar command! Does using it make any sense? Not much, honestly.
-Except it shows how the newer optimized table formatting algorithm works in the
-Insert mode.
-
-Indeed, the newer table formatting algorithm introduces a _viewport_ on a table.
-Now, when pressing _Tab_ or _Enter_ in the Insert mode, only a small part of
-rows are checked for possible formatting: two rows above the current line and
-the current line itself (the latter gets preliminary shrunk with function
-`s:fmt_row()`). If all three lines in the viewport are of the same length, then
-nothing happens (case 1 in the example). If the second or the shrunk current
-line is longer then the topmost line in the viewport, then the algorithm falls
-back to the older formatting algorithm and the whole table gets aligned
-(case 2). If the topmost line in the viewport is longer than the second
-and the shrunk current line, then the two lowest lines get aligned according to
-the topmost line (case 3).
-
-Performance of the newer formatting algorithm should not depend on the height
-of the table. The newer algorithm should also be consistent with respect to
-user editing experience. Indeed, as soon as a table should normally be edited
-row by row from the top to the bottom, dynamic formatting should be both fast
-(watching only three rows in a table, re-formatting only when the shrunk
-current row gets longer than any of the two rows above) and eager (a table
-should look formatted on every press on _Tab_ and _Enter_). However, the newer
-algorithm differs from the older algorithm when starting editing a mis-aligned
-table in an area where mis-aligned rows do not get into the viewport: in this
-case the newer algorithm will format the table partly (in the rows of the
-viewport) until one of the being edited cells grows in length to a value big
-enough to trigger the older algorithm and the whole table gets aligned. When
-partial formatting is not desirable, the whole table can be formatted by
-pressing `gqq` in the Normal mode.
-