diff --git a/README.md b/README.md index a1501c1..6645ad5 100644 --- a/README.md +++ b/README.md @@ -397,7 +397,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
mykoza

💻 🤔
noodlor

💻 -
Harshad Srinivasan

💻 🐛 +
Harshad Vedartham

💻 🐛
Erick A. Chacón Montalván

🤔
Sam Griesemer

💻 🐛
Charles Pence

💻 diff --git a/plugin/bullets.vim b/plugin/bullets.vim index e5e017f..fd0560e 100644 --- a/plugin/bullets.vim +++ b/plugin/bullets.vim @@ -90,6 +90,10 @@ if !exists('g:bullets_nested_checkboxes') let g:bullets_nested_checkboxes = 1 endif +if !exists('g:bullets_enable_wrapped_lines') + let g:bullets_enable_wrapped_lines = 1 +end + if !exists('g:bullets_checkbox_markers') " The ordered series of markers to use in checkboxes " If only two markers are listed, they represent 'off' and 'on' @@ -121,7 +125,48 @@ endif " ------------------------------------------------------ }}} " Parse Bullet Type ------------------------------------------- {{{ + +" A caching mechanism for bullet +" We add a crude 'reference count' for the cache so we can nest calls +let s:bullet_cache = v:null +let s:bullet_cache_depth = 0 + +fun! s:enable_bullet_cache() + if s:bullet_cache_depth == 0 + let s:bullet_cache = {} + endif + let s:bullet_cache_depth += 1 +endfun + +fun! s:disable_bullet_cache() + if s:bullet_cache_depth == 1 + let s:bullet_cache = v:null + endif + + if s:bullet_cache_depth > 0 + let s:bullet_cache_depth -= 1 + endif +endfun + fun! s:parse_bullet(line_num, line_text) + let l:kinds = s:parse_bullet_text(a:line_text) + + for l:data in l:kinds + let l:data.starting_at_line_num = a:line_num + endfor + + return l:kinds +endfun + +fun! s:parse_bullet_text(line_text) + + if s:bullet_cache isnot v:null + let l:cached = get(s:bullet_cache, a:line_text, v:null) + if l:cached isnot v:null + " Return a copy so as not to break the referene + return copy(l:cached) + endif + endif let l:bullet = s:match_bullet_list_item(a:line_text) " Must be a bullet to be a checkbox @@ -134,13 +179,12 @@ fun! s:parse_bullet(line_num, line_text) let l:roman = empty(l:bullet) && empty(l:num) ? s:match_roman_list_item(a:line_text) : {} let l:kinds = s:filter([l:bullet, l:check, l:num, l:alpha, l:roman], '!empty(v:val)') - - for l:data in l:kinds - let l:data.starting_at_line_num = a:line_num - endfor - + + if s:bullet_cache isnot v:null + let s:bullet_cache[a:line_text] = l:kinds + endif + return l:kinds - endfun fun! s:match_numeric_list_item(input_text) @@ -371,17 +415,19 @@ fun! s:closest_bullet_types(from_line_num, max_indent) " Support for wrapped text bullets, even if the wrapped line is not indented " It considers a blank line as the end of a bullet " DEMO: https://raw.githubusercontent.com/dkarter/bullets.vim/master/img/wrapped-bullets.gif - while l:lnum > 1 && (l:curr_indent != 0 || l:bullet_kinds != [] || !(l:ltxt =~# '\v^(\s+$|$)')) - \ && (a:max_indent < l:curr_indent || l:bullet_kinds == []) - if l:bullet_kinds != [] - let l:lnum = l:lnum - g:bullets_line_spacing - else - let l:lnum = l:lnum - 1 - endif - let l:ltxt = getline(l:lnum) - let l:bullet_kinds = s:parse_bullet(l:lnum, l:ltxt) - let l:curr_indent = indent(l:lnum) - endwhile + if g:bullets_enable_wrapped_lines + while l:lnum > 1 && (l:curr_indent != 0 || l:bullet_kinds != [] || !(l:ltxt =~# '\v^(\s+$|$)')) + \ && (a:max_indent < l:curr_indent || l:bullet_kinds == []) + if l:bullet_kinds != [] + let l:lnum = l:lnum - g:bullets_line_spacing + else + let l:lnum = l:lnum - 1 + endif + let l:ltxt = getline(l:lnum) + let l:bullet_kinds = s:parse_bullet(l:lnum, l:ltxt) + let l:curr_indent = indent(l:lnum) + endwhile + endif return l:bullet_kinds endfun @@ -819,6 +865,7 @@ fun! s:renumber_selection() endfun fun! s:renumber_lines(start, end) + call s:enable_bullet_cache() let l:prev_indent = -1 let l:levels = {} " stores all the info about the current outline/list @@ -896,15 +943,18 @@ fun! s:renumber_lines(start, end) endif endif endfor + call s:disable_bullet_cache() endfun " Renumbers the whole list containing the cursor. fun! s:renumber_whole_list() + call s:enable_bullet_cache() let l:first_line = s:first_bullet_line(line('.')) let l:last_line = s:last_bullet_line(line('.')) if l:first_line > 0 && l:last_line > 0 call s:renumber_lines(l:first_line, l:last_line) endif + call s:disable_bullet_cache() endfun command! -range=% RenumberSelection call renumber_selection()