diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b20c769 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test/issues diff --git a/README.md b/README.md index e0c3d3f..f3ebc22 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,19 @@ following features are provided. The default mappings are indicated. See the * `wlk` and `wlj`: Move list items up or down the list. * `wlu`: Remove repeated entries in a list (recursively) +`lists.vim` is quite minimal and does not have a lot of available +configuration choices. The implementation is based on the idea that list items +are indented consistently. The indentation makes it easy to parse a list to +determine its structure. + +These types of lists are currently supported: +* Bullet lists. Bullets are either "*" or "-". +* Numbered lists formated similar to "1.". +* List items can be decorated with check boxes. Examples: + * [x] checked + * [ ] unchecked +* List items can be decorated with labels like "TODO:" and "DONE:". + # Installation If you use [vim-plug](https://github.com/junegunn/vim-plug), then add the diff --git a/autoload/lists.vim b/autoload/lists.vim index 7ceae9b..53806e6 100644 --- a/autoload/lists.vim +++ b/autoload/lists.vim @@ -5,42 +5,66 @@ " function! lists#init() abort " {{{1 - " Set 'comments' option for lists + " Set 'comments' and 'formatoptions' to work well with lists setlocal comments+=fb:*,f:*\ TODO:,b:*\ [\ ],b:*\ [x] setlocal comments+=fb:-,f:-\ TODO:,b:-\ [\ ],b:-\ [x] - - command! -buffer ListsMoveUp call lists#move(0) - command! -buffer ListsMoveDown call lists#move(1) - command! -buffer ListsToggle call lists#toggle() - command! -buffer ListsUniq call lists#uniq(0) - command! -buffer ListsUniqLocal call lists#uniq(1) - command! -buffer ListsShowItem call lists#show_item() - - nnoremap (lists-moveup) :ListsMoveUp - nnoremap (lists-movedown) :ListsMoveDown - nnoremap (lists-toggle) :ListsToggle - nnoremap (lists-uniq) :ListsUniq - nnoremap (lists-uniq-local) :ListsUniqLocal - nnoremap (lists-show-item) :ListsShowItem - inoremap (lists-toggle) :call lists#new_item() - onoremap (lists-al) :call lists#text_obj#list_element(0, 0) - xnoremap (lists-al) :call lists#text_obj#list_element(0, 1) - onoremap (lists-il) :call lists#text_obj#list_element(1, 0) - xnoremap (lists-il) :call lists#text_obj#list_element(1, 1) - - for [l:rhs, l:lhs] in items({ + setlocal formatoptions+=ron + + command! -buffer ListsMoveUp call lists#move(0) + command! -buffer ListsMoveDown call lists#move(1) + command! -buffer ListsToggle call lists#toggle() + command! -buffer ListsToggleCheckbox call lists#toggle_checkbox() + command! -buffer ListsUniq call lists#uniq(0) + command! -buffer ListsUniqLocal call lists#uniq(1) + command! -buffer ListsShowItem call lists#show_item() + + command! -buffer -bang ListsToggleBullet + \ if empty() | + \ call lists#bullet#toggle_all() | + \ else | + \ call lists#bullet#toggle_local() | + \ endif + + nnoremap (lists-moveup) :ListsMoveUp + nnoremap (lists-movedown) :ListsMoveDown + nnoremap (lists-toggle) :ListsToggle + nnoremap (lists-toggle-checkbox) :ListsToggleCheckbox + nnoremap (lists-uniq) :ListsUniq + nnoremap (lists-uniq-local) :ListsUniqLocal + nnoremap (lists-show-item) :ListsShowItem + inoremap (lists-toggle) :call lists#toggle_insertmode() + inoremap (lists-toggle-checkbox) :call lists#toggle_checkbox_insertmode() + inoremap (lists-new-element) :call lists#new_item() + onoremap (lists-al) :call lists#text_obj#list_element(0, 0) + xnoremap (lists-al) :call lists#text_obj#list_element(0, 1) + onoremap (lists-il) :call lists#text_obj#list_element(1, 0) + xnoremap (lists-il) :call lists#text_obj#list_element(1, 1) + nnoremap (lists-bullet-toggle-all) :call lists#bullet#toggle_all() + nnoremap (lists-bullet-toggle-local) :call lists#bullet#toggle_local() + + " Only apply default maps if desired + if !g:lists_maps_default_enable | return | endif + + for [l:rhs, l:lhs] in items(extend({ \ '(lists-toggle)': '', + \ '(lists-toggle-checkbox)': '', \ '(lists-moveup)': 'wlk', \ '(lists-movedown)': 'wlj', \ '(lists-uniq)': 'wlu', \ '(lists-uniq-local)': 'wlU', \ '(lists-show-item)': 'wls', + \ '(lists-bullet-toggle-all)': 'wlt', + \ '(lists-bullet-toggle-local)': 'wlT', \ 'i_(lists-toggle)': '', + \ 'i_(lists-toggle-checkbox)': '', + \ 'i_(lists-new-element)': '', \ 'o_(lists-al)': 'al', \ 'x_(lists-al)': 'al', \ 'o_(lists-il)': 'il', \ 'x_(lists-il)': 'il', - \}) + \}, g:lists_maps_default_override)) + if empty(l:lhs) | continue | endif + if l:rhs[0] !=# '<' let l:mode = l:rhs[0] let l:rhs = l:rhs[2:] @@ -68,6 +92,73 @@ function! lists#toggle(...) abort "{{{1 endfunction " }}}1 +function! lists#toggle_insertmode() abort "{{{1 + " Go back properly to insert mode + let l:col_lineend = col('$') - 1 + let l:col_cursor = col('.') + normal! l + + " Toggle TODO-state only when cursor inside valid todo list item + if getline('.') !~# '^\s*$' + let [l:root, l:current] = lists#parser#get_current() + + if !empty(l:current) + call l:current.toggle() + endif + endif + + " Go back properly to insert mode + if l:col_cursor == l:col_lineend + startinsert! + else + startinsert + endif +endfunction + +" }}}1 +function! lists#toggle_checkbox(...) abort "{{{1 + let [l:root, l:current] = a:0 > 0 + \ ? lists#parser#get_at(a:1) + \ : lists#parser#get_current() + if empty(l:current) | return | endif + + if l:current.type ==# 'checkbox' + call l:current.toggle() + elseif has_key(l:current, 'to_checkbox') + call l:current.to_checkbox() + endif +endfunction + +" }}}1 +function! lists#toggle_checkbox_insertmode() abort "{{{1 + " Go back properly to insert mode + let l:col_lineend = col('$') - 1 + let l:col_cursor = col('.') + normal! l + + " Toggle checkbox-state only when cursor inside valid list item + if getline('.') !~# '^\s*$' + let [l:root, l:current] = lists#parser#get_current() + + if !empty(l:current) + if l:current.type ==# 'checkbox' + call l:current.toggle() + elseif has_key(l:current, 'to_checkbox') + call l:current.to_checkbox() + endif + endif + endif + + " Go back properly to insert mode + if l:col_cursor == l:col_lineend + startinsert! + else + startinsert + endif +endfunction + +" }}}1 + function! lists#move(direction, ...) abort "{{{1 let [l:root, l:current] = a:0 > 0 \ ? lists#parser#get_at(a:1) @@ -101,15 +192,15 @@ function! lists#move(direction, ...) abort "{{{1 let l:target = -1 let l:next = l:current.next while !empty(l:next) - if l:next.indent > l:current.indent - let l:next = l:next.next - continue + if l:next.indent <= l:current.indent + \ && l:next.indent >= l:current.parent.indent + let l:target = l:next.indent < l:current.indent + \ ? l:next.lnum_end + \ : l:next.lnum_last + break endif - let l:target = l:next.indent < l:current.indent - \ ? l:next.lnum_end - \ : l:next.lnum_last - break + let l:next = l:next.next endwhile let l:target_pos[1] += l:target - l:current.lnum_last @@ -213,45 +304,29 @@ endfunction " }}}1 function! lists#new_item() abort "{{{1 - " Go back properly to insert mode - let l:col_last = col('$') - 1 - let l:col_cur = col('.') - normal! l - - " Toggle TODOstate if cursor inside valid todo list item - let l:line = getline('.') - if l:line !~# '^\s*$' - let [l:root, l:current] = lists#parser#get_current() + " Find last used list item type + let [l:root, l:cur] = lists#parser#get_previous() + if empty(l:root) || l:cur.lnum_start == line('.') + return s:resume() + endif - if !empty(l:current) - call l:current.toggle() - let l:col_new = col('$') - 1 - endif + let l:pos = virtcol('$') - virtcol('.') + let l:line = substitute(getline('.'), '^\s*', '', '') + let l:header = l:cur.next_header() + call setline(line('.'), l:header . l:line) + call cursor(0, max([strchars(l:header), virtcol('$') - l:pos])) - " Go back properly to insert mode - if l:col_cur == l:col_last - startinsert! - else - startinsert - endif + return s:resume() +endfunction - return - endif +function! s:resume() abort + normal! l - " Find last used list item type - let [l:root, l:current] = lists#parser#get_previous() - if empty(l:root) + if virtcol('.') >= virtcol('$') - 1 + startinsert! + else startinsert - return endif - - let l:cur = l:root - while !empty(l:cur.next) - let l:cur = l:cur.next - endwhile - - call setline(line('.'), l:cur.next_header()) - startinsert! endfunction " }}}1 diff --git a/autoload/lists/bullet.vim b/autoload/lists/bullet.vim new file mode 100644 index 0000000..8972d00 --- /dev/null +++ b/autoload/lists/bullet.vim @@ -0,0 +1,70 @@ +" A Vim plugin to handle lists +" +" Maintainer: Karl Yngve LervÄg +" Email: karl.yngve@gmail.com +" + +function! lists#bullet#get(...) abort " {{{1 + let [l:root, l:current] = a:0 > 0 + \ ? lists#parser#get_at(a:1) + \ : lists#parser#get_current() + + return get(l:current, 'bullet', '') +endfunction + +" }}}1 + +function! lists#bullet#toggle_all(...) abort " {{{1 + let [l:_, l:current] = a:0 > 0 + \ ? lists#parser#get_at(a:1) + \ : lists#parser#get_current() + + let l:bullet = get(l:current, 'bullet', '') + if empty(l:bullet) | return | endif + + let l:new = l:bullet ==# '*' ? '-' : '*' + call lists#bullet#change_all(l:new, a:0 > 0 ? a:1 : line('.')) +endfunction + +" }}}1 +function! lists#bullet#change_all(new, ...) abort " {{{1 + let [l:cur, l:_] = a:0 > 0 + \ ? lists#parser#get_at(a:1) + \ : lists#parser#get_current() + + while !empty(l:cur) + let l:cur = l:cur.next + if has_key(l:cur, 'set_bullet') + call l:cur.set_bullet(a:new) + endif + endwhile +endfunction + +" }}}1 + +function! lists#bullet#toggle_local(...) abort " {{{1 + let [l:_, l:current] = a:0 > 0 + \ ? lists#parser#get_at(a:1) + \ : lists#parser#get_current() + + let l:bullet = get(l:current, 'bullet', '') + if empty(l:bullet) | return | endif + + let l:new = l:bullet ==# '*' ? '-' : '*' + call lists#bullet#change_local(l:new, a:0 > 0 ? a:1 : line('.')) +endfunction + +" }}}1 +function! lists#bullet#change_local(new, ...) abort " {{{1 + let [l:_, l:start] = a:0 > 0 + \ ? lists#parser#get_at(a:1) + \ : lists#parser#get_current() + + for l:item in l:start.parent.children + if has_key(l:item, 'set_bullet') + call l:item.set_bullet(a:new) + endif + endfor +endfunction + +" }}}1 diff --git a/autoload/lists/item/checkbox.vim b/autoload/lists/item/checkbox.vim index ca68d63..43e1754 100644 --- a/autoload/lists/item/checkbox.vim +++ b/autoload/lists/item/checkbox.vim @@ -22,6 +22,7 @@ let s:item = extend(lists#item#unordered#new(), { function! s:item.init() abort dict " {{{1 let self.checked = match(self.text[0], self.re_item_checked) >= 0 + let self.bullet = matchstr(self.header, self.re_bullet) endfunction " }}}1 @@ -77,3 +78,10 @@ function! s:item.toggle_parents(status) abort dict "{{{1 endfunction " }}}1 + +function! s:item.next_header() abort dict "{{{1 + return substitute(copy(self.header), '^\s*\zs.*', '', '') + \ . matchstr(self.header, '[*-]') . ' [ ] ' +endfunction + +" }}}1 diff --git a/autoload/lists/item/general.vim b/autoload/lists/item/general.vim index 9782140..a486d0c 100644 --- a/autoload/lists/item/general.vim +++ b/autoload/lists/item/general.vim @@ -24,6 +24,12 @@ let s:item = { \} function! s:item.new(start, end) abort dict " {{{1 + " This is a template and must be combined with a real item type! + if !has_key(self, 're_item') + echoerr 'THIS IS A GENERIC FUNCTION!' + return {} + endif + let l:new = deepcopy(self) unlet l:new.new @@ -33,12 +39,6 @@ function! s:item.new(start, end) abort dict " {{{1 let l:new.text = getline(l:new.lnum_start, l:new.lnum_end) let l:new.indent = indent(a:start) - " This is a template and must be combined with a real item type! - if !has_key(self, 're_item') - echoerr 'THIS IS A GENERIC FUNCTION!' - return {} - endif - let l:new.header = matchstr(l:new.text[0], self.re_item) let l:new.state = index(self.states, matchstr(l:new.text[0], \ self.re_item . '\zs' . join(self.states, '\|') . '\ze:')) @@ -93,6 +93,11 @@ function! s:item.toggle() abort dict "{{{1 \ . (self.state < 0 ? '' : self.states[self.state] . ':') \ . '\s*\ze' + " Edge case: missing space after bullet + if self.text[0] =~# self.re_item . '$' && self.text[0] =~# '\S$' + let self.text[0] .= ' ' + endif + let self.state = ((self.state + 2) % (len(self.states) + 1)) - 1 let l:line = substitute(self.text[0], l:re_old, diff --git a/autoload/lists/item/unordered.vim b/autoload/lists/item/unordered.vim index e826ec7..c2a03ce 100644 --- a/autoload/lists/item/unordered.vim +++ b/autoload/lists/item/unordered.vim @@ -15,11 +15,38 @@ endfunction let s:item = extend(lists#item#general#new(), { \ 'type' : 'unordered', \ 're_item': '^\s*[*-]\(\s\|$\)', + \ 're_bullet': '^\s*\zs[*-]', \}) +function! s:item.init() abort dict "{{{1 + let self.bullet = matchstr(self.header, self.re_bullet) +endfunction + +" }}}1 function! s:item.next_header() abort dict "{{{1 return substitute(copy(self.header), '^\s*\zs.*', '', '') \ . matchstr(self.header, '[*-]') . ' ' endfunction " }}}1 +function! s:item.set_bullet(new) abort dict "{{{1 + if index(['*', '-'], a:new) < 0 | return | endif + if a:new ==# self.bullet | return | endif + + call setline(self.lnum_start, + \ substitute(self.text[0], self.re_bullet, a:new, '')) +endfunction + +" }}}1 +function! s:item.to_checkbox() abort dict "{{{1 + " Edge case: missing space after bullet + if self.text[0] =~# self.re_item . '$' && self.text[0] =~# '\S$' + let self.text[0] .= ' ' + endif + + let l:line = substitute(self.text[0], '^\s*[*-]\s\zs', '[ ] ', '') + + call setline(self.lnum_start, l:line) +endfunction + +" }}}1 diff --git a/autoload/lists/parser.vim b/autoload/lists/parser.vim index 698542c..27f22ae 100644 --- a/autoload/lists/parser.vim +++ b/autoload/lists/parser.vim @@ -51,7 +51,7 @@ function! s:get_list_items(opts) abort " {{{1 let l:save_pos = getcurpos() call setpos('.', [0, l:lnum, l:cnum, 0]) - let l:list_start = search(s:items_re, 'Wn') + let l:list_start = search(s:items_re, 'Wcn') if l:list_start == 0 \ || l:list_start > l:save_pos[1] call setpos('.', l:save_pos) @@ -145,7 +145,7 @@ function! s:get_tree_from_items(items) abort " {{{1 let l:current.counter = l:counter " Update nested counter - if l:prev == l:parent + if l:prev == l:parent || empty(l:current.prev_sibling) let l:counter_nested = 1 else if l:prev.indent > l:current.indent diff --git a/doc/lists.txt b/doc/lists.txt index 0b02cb5..a5a7910 100644 --- a/doc/lists.txt +++ b/doc/lists.txt @@ -16,13 +16,13 @@ License: MIT license {{{ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. + The software is provided "as is", without warranty of any kind, express or + implied, including but not limited to the warranties of merchantability, + fitness for a particular purpose and noninfringement. In no event shall the + authors or copyright holders be liable for any claim, damages or other + liability, whether in an action of contract, tort or otherwise, arising + from, out of or in connection with the software or the use or other dealings + in the software. }}} @@ -42,6 +42,22 @@ is now therefore a separate plugin. [0]: https://github.com/lervag/wiki.vim [1]: https://github.com/lervag/wiki.vim/issues/131 +============================================================================== +LIST TYPES *lists-types* + +|lists.vim| is quite minimal and does not have a lot of available +configuration choices. The implementation is based on the idea that list items +are indented consistently. The indentation makes it easy to parse a list to +determine its structure. + +These types of lists are currently supported: +* Bullet lists. Bullets are either "*" or "-". +* Numbered lists formated similar to "1.". +* List items can be decorated with check boxes. Examples: + * [x] checked + * [ ] unchecked +* List items can be decorated with labels like "TODO:" and "DONE:". + ============================================================================== FEATURES *lists-features* @@ -55,7 +71,28 @@ The following is a list of the commands and mappings provided by |lists.vim|. *:ListsToggle* *(lists-toggle)* - Toggle a list item. The mapping works in both normal and insert mode. + Toggle a list items "status". For checkboxes, this means to toggle the + checkmark on/off. Elsewhere, we toggle between statuses defined in + |g:lists_todos|. This mapping exists in both normal and insert mode. + +*:ListsToggleCheckbox* +*(lists-toggle-checkbox)* + Toggle a checklist item. If the current item does not have a checkbox, it + will be added. This mapping exists in both normal and insert mode. + +*i_(lists-new-element)* + An insert mode mapping to add a new element in the current list. This is + useful after creating a new line below a list element to add the + bullet/dash/number in front, possibly with a checkbox if relevant. + +*:ListsToggleBullet* +*(lists-bullet-toggle-all)* + Toggle the list bullet type between `-` and `*`. for the entire list. + +*:ListsToggleBullet!* +*(lists-bullet-toggle-local)* + Toggle the list bullet type between `-` and `*` for the sibling list + entries. *:ListsMoveUp* *:ListsMoveDown* @@ -79,21 +116,26 @@ The following is a list of the commands and mappings provided by |lists.vim|. The following mappings are available as visual mode and operator mode mappings, i.e. |xmap| and |omap|. -The default mappings are listed in the following table. The map mode is -indicated by the first letters of the various map commands (|nmap|, |imap|, -|omap|, and |xmap|). - - -------------------------------------------------------------------~ - PLUG DEFAULT MODE~ - -------------------------------------------------------------------~ - |(lists-toggle)| `in` - |(lists-moveup)| wlk `n` - |(lists-movedown)| wlj `n` - |(lists-uniq)| wlu `n` - |(lists-uniq-local)| wlU `n` - |(lists-al)| al `ox` - |(lists-il)| il `ox` - -------------------------------------------------------------------~ + *lists-maps-defaults* +The default mappings are listed in the following table. To disable the default +mappings, see |g:lists_maps_default_enable|. They can also be overrided +individually with |g:lists_maps_default_override|. The map mode is indicated +by the first letters of the various map commands (|nmap|, |imap|, |omap|, and +|xmap|). + + PLUG DEFAULT MODE~ + ---- ------- ----~ + |(lists-toggle)| `in` + |(lists-toggle-checkbox)| NONE `in` + |i_(lists-new-element)| `i` + |(lists-moveup)| wlk `n` + |(lists-movedown)| wlj `n` + |(lists-uniq)| wlu `n` + |(lists-uniq-local)| wlU `n` + |(lists-bullet-toggle-local)| wlT `n` + |(lists-bullet-toggle-all)| wlt `n` + |(lists-al)| al `ox` + |(lists-il)| il `ox` ============================================================================== CONFIGURATION *lists-config* @@ -103,6 +145,32 @@ CONFIGURATION *lists-config* Default: [] +*g:lists_maps_default_enable* + Set to |v:false| or 0 to prevent |lists.vim| from applying the default maps. + Useful if you want to create your own mappings. + + Default: |v:true| + +*g:lists_maps_default_override* + A dictionary that allows to override one or more of the default mappings. + The dictionary keys should be one of the available mappings, possibly with + mode indicator. The value should be the desired map target. The available + mappings with default values are listed in |lists-maps-defaults|. + + To disable a map, one can link it to an empty string. + + For example, to remap the insert-mode mapping |(lists-new-element)| to + `` and the normal mode variant of |(lists-toggle)| to ``, as + well as disabling the insert mode variant of the latter, one could do this: > + + let g:lists_maps_default_override = { + \ 'i_(lists-new-element)': '', + \ 'i_(lists-toggle)': '', + \ '(lists-toggle)': '', + \} +< + Default: `{}` + *g:lists_todos* A list of TODO toggles that may be toggled with |(lists-toggle)|, which is by default mapped to ``. diff --git a/plugin/lists.vim b/plugin/lists.vim index acab063..957e3a7 100644 --- a/plugin/lists.vim +++ b/plugin/lists.vim @@ -9,6 +9,8 @@ let g:loaded_lists = 1 call lists#u#init_option('lists_filetypes', []) +call lists#u#init_option('lists_maps_default_enable', v:true) +call lists#u#init_option('lists_maps_default_override', {}) call lists#u#init_option('lists_todos', ['TODO', 'DONE']) command! ListsEnable call lists#init() diff --git a/test/examples/lists.txt b/test/examples/lists.txt index 04751b9..335d013 100644 --- a/test/examples/lists.txt +++ b/test/examples/lists.txt @@ -1,3 +1,5 @@ +- [ ] Top of file list entry + # List examples 1 - [ ] First entry @@ -13,9 +15,9 @@ # List examples 2 -- TODO: Task 1 -- INPROGRESS: Task 2 -- DONE: Task 3 +* TODO: Task 1 +* INPROGRESS: Task 2 +* DONE: Task 3 # List examples 3 diff --git a/test/init.vim b/test/init.vim index 0d90723..077793f 100644 --- a/test/init.vim +++ b/test/init.vim @@ -3,6 +3,7 @@ let &runtimepath = \ simplify(fnamemodify(expand(''), ':h') . '/..') \ . ',' . &runtimepath set noswapfile +set noshowmode set nomore nnoremap q :qall! diff --git a/test/test-change-bullet.vim b/test/test-change-bullet.vim new file mode 100644 index 0000000..5af0f27 --- /dev/null +++ b/test/test-change-bullet.vim @@ -0,0 +1,40 @@ +source init.vim + +silent edit examples/lists.txt + +call assert_equal('-', lists#bullet#get(5)) +call assert_equal('*', lists#bullet#get(19)) + +call lists#bullet#change_all('*', 7) +call assert_equal('*', lists#bullet#get(5)) +call assert_equal('*', lists#bullet#get(12)) +silent undo +call assert_equal('-', lists#bullet#get(5)) +call assert_equal('-', lists#bullet#get(12)) + +call lists#bullet#toggle_all(7) +call assert_equal('*', lists#bullet#get(5)) +call assert_equal('*', lists#bullet#get(12)) +silent undo +call assert_equal('-', lists#bullet#get(5)) +call assert_equal('-', lists#bullet#get(12)) + +call lists#bullet#change_local('*', 7) +call assert_equal('-', lists#bullet#get(5)) +call assert_equal('*', lists#bullet#get(6)) +call assert_equal('*', lists#bullet#get(7)) +call assert_equal('-', lists#bullet#get(8)) +call assert_equal('*', lists#bullet#get(11)) +call assert_equal('-', lists#bullet#get(12)) +silent undo + +call lists#bullet#toggle_local(7) +call assert_equal('-', lists#bullet#get(5)) +call assert_equal('*', lists#bullet#get(6)) +call assert_equal('*', lists#bullet#get(7)) +call assert_equal('-', lists#bullet#get(8)) +call assert_equal('*', lists#bullet#get(11)) +call assert_equal('-', lists#bullet#get(12)) +silent undo + +call lists#test#finished() diff --git a/test/test-move.vim b/test/test-move.vim index 72bd7af..52a6c48 100644 --- a/test/test-move.vim +++ b/test/test-move.vim @@ -2,6 +2,12 @@ source init.vim silent edit examples/move_in.txt +normal! 12G +call lists#move(1) +call lists#move(1) +call lists#move(0) +call lists#move(0) + call lists#move(0, 5) call lists#move(0, 7) call lists#move(0, 7) diff --git a/test/test-newlines.vim b/test/test-newlines.vim new file mode 100644 index 0000000..835990f --- /dev/null +++ b/test/test-newlines.vim @@ -0,0 +1,18 @@ +source init.vim + +silent read examples/lists.txt +ListsEnable + +normal 15GoNew +call assert_equal(' - [x] New', getline(16)) + +normal 10GoNew +call assert_equal(' - [x] New', getline(11)) + +normal 9GoNew +call assert_equal(' - New', getline(10)) + +normal 9GoNew +call assert_equal(' - New', getline(10)) + +call lists#test#finished() diff --git a/test/test-numbered.vim b/test/test-numbered.vim index 270a368..b00faf9 100644 --- a/test/test-numbered.vim +++ b/test/test-numbered.vim @@ -3,14 +3,14 @@ source init.vim silent edit examples/lists.txt " Numbered lists general -let [s:root, s:current] = lists#parser#get_at(22) +let [s:root, s:current] = lists#parser#get_at(24) call assert_equal( \ '1. Ordered lists are also cool', \ s:current.text[0]) " Numbered todo lists -call lists#toggle(23) -let [s:root, s:current] = lists#parser#get_at(23) +call lists#toggle(25) +let [s:root, s:current] = lists#parser#get_at(25) call assert_equal('DONE', s:current.states[s:current.state]) call lists#test#finished() diff --git a/test/test-toggle.vim b/test/test-toggle.vim index b24a6c1..72d78db 100644 --- a/test/test-toggle.vim +++ b/test/test-toggle.vim @@ -5,16 +5,20 @@ let g:lists_todos = ['TODO', 'INPROGRESS', 'DONE'] silent edit examples/lists.txt " Checkbox lists -call lists#toggle(7) -call lists#toggle(10) -let [s:root, s:current] = lists#parser#get_at(3) -call assert_equal(len(s:current.children), 3) +call lists#toggle(1) +let [s:root, s:current] = lists#parser#get_at(1) +call assert_true(s:current.checked) + +call lists#toggle(9) +call lists#toggle(12) +let [s:root, s:current] = lists#parser#get_at(5) +call assert_equal(3, len(s:current.children)) call assert_true(s:current.checked) call assert_true(s:root.children[1].children[0].checked) " Todo lists -call lists#toggle(17) -let [s:root, s:current] = lists#parser#get_at(17) -call assert_equal(s:current.states[s:current.state], 'DONE') +call lists#toggle(19) +let [s:root, s:current] = lists#parser#get_at(19) +call assert_equal('DONE', s:current.states[s:current.state]) call lists#test#finished()