From 61093f4f2aa2748a7d7fcd8ea7a4542f8723cdfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20G=C3=BCnzler?= Date: Sun, 7 Jun 2020 23:03:10 +0000 Subject: [PATCH] Feature: Add option to automatically cycle bullet chars (#907) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the syntax local config `cycle_bullets` is set (currently only markdown has it by default) the indent functions will cycle through the characters defined in `bullet_types` based on the level of indentation. Signed-off-by: Robert Günzler --- autoload/vimwiki/lst.vim | 49 ++++++++++++++++++--------------- syntax/vimwiki_markdown.vim | 3 +- test/independent_runs/map.vader | 49 +++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 23 deletions(-) diff --git a/autoload/vimwiki/lst.vim b/autoload/vimwiki/lst.vim index e87c4ee..e99b76a 100644 --- a/autoload/vimwiki/lst.vim +++ b/autoload/vimwiki/lst.vim @@ -1100,14 +1100,13 @@ function! s:set_indent(lnum, new_indent) abort endfunction -function! s:decrease_level(item) abort +function! s:decrease_level(item, by) abort let removed_indent = 0 if vimwiki#vars#get_syntaxlocal('recurring_bullets') && a:item.type == 1 && \ index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), \ s:first_char(a:item.mrkr)) > -1 if s:string_length(a:item.mrkr) >= 2 call s:substitute_string_in_line(a:item.lnum, s:first_char(a:item.mrkr), '') - let removed_indent = -1 endif else let old_indent = indent(a:item.lnum) @@ -1116,21 +1115,19 @@ function! s:decrease_level(item) abort else let new_indent = old_indent - vimwiki#u#sw() endif - call s:set_indent(a:item.lnum, new_indent) - let removed_indent = new_indent - old_indent + call s:set_indent(a:item.lnum, a:by * new_indent) endif - return removed_indent + call s:indent_cycle_bullets(a:item, -a:by) endfunction -function! s:increase_level(item) abort +function! s:increase_level(item, by) abort let additional_indent = 0 if vimwiki#vars#get_syntaxlocal('recurring_bullets') && a:item.type == 1 && \ index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), \ s:first_char(a:item.mrkr)) > -1 call s:substitute_string_in_line(a:item.lnum, a:item.mrkr, a:item.mrkr . \ s:first_char(a:item.mrkr)) - let additional_indent = 1 else let old_indent = indent(a:item.lnum) if &shiftround @@ -1138,27 +1135,35 @@ function! s:increase_level(item) abort else let new_indent = old_indent + vimwiki#u#sw() endif - call s:set_indent(a:item.lnum, new_indent) - let additional_indent = new_indent - old_indent + call s:set_indent(a:item.lnum, a:by * new_indent) endif - return additional_indent + call s:indent_cycle_bullets(a:item, a:by) endfunction +" s:indent_cycle_bullets cycles through the bullet list markers set in +" `bullet_types` based on the indentation level +" TODO there is potential to merge this with the change_marker* funcs further +" up if we can make them operate on arbitrary lists of characters +function! s:indent_cycle_bullets(item, indent_by) abort + if vimwiki#vars#get_syntaxlocal('cycle_bullets') && a:item.type == 1 + let bullets = vimwiki#vars#get_syntaxlocal('bullet_types') + let i = index(bullets, s:first_char(a:item.mrkr)) + a:indent_by + " calculate the index in a way that wraps around the end of the list + " making it behave like a ring buffer + let new_mrkr = bullets[((i % len(bullets) + len(bullets)) % len(bullets))] + call vimwiki#lst#change_marker(a:item.lnum, a:item.lnum, new_mrkr, 'n') + endif +endfunction "adds a:indent_by to the current indent "a:indent_by can be negative function! s:indent_line_by(lnum, indent_by) abort let item = s:get_item(a:lnum) - if vimwiki#vars#get_syntaxlocal('recurring_bullets') && item.type == 1 && - \ index(vimwiki#vars#get_wikilocal('multiple_bullet_chars'), - \ s:first_char(item.mrkr)) > -1 - if a:indent_by > 0 - call s:substitute_string_in_line(a:lnum, item.mrkr, item.mrkr . s:first_char(item.mrkr)) - elseif a:indent_by < 0 - call s:substitute_string_in_line(a:lnum, s:first_char(item.mrkr), '') - endif - else - call s:set_indent(a:lnum, indent(a:lnum) + a:indent_by) + if a:indent_by > 0 + call s:increase_level(item, a:indent_by) + elseif a:indent_by < 0 + " double negate indent_by here + call s:decrease_level(item, -a:indent_by) endif endfunction @@ -1208,8 +1213,8 @@ function! s:change_level(from_line, to_line, direction, plus_children) abort let first_line_level = s:get_level(from_item.lnum) let more_than_one_level_concerned = 0 - let first_line_indented_by = (a:direction ==# 'increase') ? - \ s:increase_level(from_item) : s:decrease_level(from_item) + let first_line_indented_by = (a:direction ==# 'increase') ? 1 : -1 + call s:indent_line_by(from_item.lnum, first_line_indented_by) let cur_ln = s:get_next_line(from_item.lnum) while cur_ln > 0 && cur_ln <= to_line diff --git a/syntax/vimwiki_markdown.vim b/syntax/vimwiki_markdown.vim index 98249e0..ec811fb 100644 --- a/syntax/vimwiki_markdown.vim +++ b/syntax/vimwiki_markdown.vim @@ -73,8 +73,9 @@ let s:markdown_syntax.rxHR = '\(^---*$\|^___*$\|^\*\*\**$\)' let s:markdown_syntax.rxTableSep = '|' " Lists -let s:markdown_syntax.bullet_types = ['-', '*', '+'] +let s:markdown_syntax.bullet_types = ['*', '-', '+'] let s:markdown_syntax.recurring_bullets = 0 +let s:markdown_syntax.cycle_bullets = 1 let s:markdown_syntax.number_types = ['1.'] let s:markdown_syntax.list_markers = ['-', '*', '+', '1.'] let s:markdown_syntax.rxListDefine = '::\%(\s\|$\)' diff --git a/test/independent_runs/map.vader b/test/independent_runs/map.vader index 62fbfe2..c99d6f9 100644 --- a/test/independent_runs/map.vader +++ b/test/independent_runs/map.vader @@ -402,6 +402,55 @@ Expect (list -> *): 1. Much * You +Given (Bulleted list): + * I + - Relly + * Love + - Very + + Much + * You + +Execute (file .md): + file toto.md + edit! + AssertEqual 'vimwiki', &ft + set sw=2 + +Do (2gll): + gLl + +Expect (Increase): + - I + + Relly + * Love + - Very + + Much + * You + +Do (3glh): + gLh + +Expect (Decrease): + * I + - Relly + * Love + - Very + + Much + * You + +Given (Bulleted list 2): + * Love + - Very + - Much + +Do (Go): + Go + +Expect (New item): + * Love + - Very + - Much + - # 3 Text Object {{{1 ####################