@@ -90,6 +90,10 @@ if !exists('g:bullets_nested_checkboxes')
9090 let g: bullets_nested_checkboxes = 1
9191endif
9292
93+ if ! exists (' g:bullets_enable_wrapped_lines' )
94+ let g: bullets_enable_wrapped_lines = 1
95+ end
96+
9397if ! exists (' g:bullets_checkbox_markers' )
9498 " The ordered series of markers to use in checkboxes
9599 " If only two markers are listed, they represent 'off' and 'on'
@@ -121,7 +125,48 @@ endif
121125" ------------------------------------------------------ }}}
122126
123127" Parse Bullet Type ------------------------------------------- {{{
128+
129+ " A caching mechanism for bullet
130+ " We add a crude 'reference count' for the cache so we can nest calls
131+ let s: bullet_cache = v: null
132+ let s: bullet_cache_depth = 0
133+
134+ fun ! s: enable_bullet_cache ()
135+ if s: bullet_cache_depth == 0
136+ let s: bullet_cache = {}
137+ endif
138+ let s: bullet_cache_depth += 1
139+ endfun
140+
141+ fun ! s: disable_bullet_cache ()
142+ if s: bullet_cache_depth == 1
143+ let s: bullet_cache = v: null
144+ endif
145+
146+ if s: bullet_cache_depth > 0
147+ let s: bullet_cache_depth -= 1
148+ endif
149+ endfun
150+
124151fun ! s: parse_bullet (line_num, line_text)
152+ let l: kinds = s: parse_bullet_text (a: line_text )
153+
154+ for l: data in l: kinds
155+ let l: data .starting_at_line_num = a: line_num
156+ endfor
157+
158+ return l: kinds
159+ endfun
160+
161+ fun ! s: parse_bullet_text (line_text)
162+
163+ if s: bullet_cache isnot v: null
164+ let l: cached = get (s: bullet_cache , a: line_text , v: null )
165+ if l: cached isnot v: null
166+ " Return a copy so as not to break the referene
167+ return copy (l: cached )
168+ endif
169+ endif
125170
126171 let l: bullet = s: match_bullet_list_item (a: line_text )
127172 " Must be a bullet to be a checkbox
@@ -134,13 +179,12 @@ fun! s:parse_bullet(line_num, line_text)
134179 let l: roman = empty (l: bullet ) && empty (l: num ) ? s: match_roman_list_item (a: line_text ) : {}
135180
136181 let l: kinds = s: filter ([l: bullet , l: check , l: num , l: alpha , l: roman ], ' !empty(v:val)' )
137-
138- for l: data in l: kinds
139- let l: data .starting_at_line_num = a: line_num
140- endfor
141-
182+
183+ if s: bullet_cache isnot v: null
184+ let s: bullet_cache [ a: line_text ] = l: kinds
185+ endif
186+
142187 return l: kinds
143-
144188endfun
145189
146190fun ! s: match_numeric_list_item (input_text)
@@ -371,17 +415,19 @@ fun! s:closest_bullet_types(from_line_num, max_indent)
371415 " Support for wrapped text bullets, even if the wrapped line is not indented
372416 " It considers a blank line as the end of a bullet
373417 " DEMO: https://raw.githubusercontent.com/dkarter/bullets.vim/master/img/wrapped-bullets.gif
374- while l: lnum > 1 && (l: curr_indent != 0 || l: bullet_kinds != [] || ! (l: ltxt = ~# ' \v^(\s+$|$)' ))
375- \ && (a: max_indent < l: curr_indent || l: bullet_kinds == [])
376- if l: bullet_kinds != []
377- let l: lnum = l: lnum - g: bullets_line_spacing
378- else
379- let l: lnum = l: lnum - 1
380- endif
381- let l: ltxt = getline (l: lnum )
382- let l: bullet_kinds = s: parse_bullet (l: lnum , l: ltxt )
383- let l: curr_indent = indent (l: lnum )
384- endwhile
418+ if g: bullets_enable_wrapped_lines
419+ while l: lnum > 1 && (l: curr_indent != 0 || l: bullet_kinds != [] || ! (l: ltxt = ~# ' \v^(\s+$|$)' ))
420+ \ && (a: max_indent < l: curr_indent || l: bullet_kinds == [])
421+ if l: bullet_kinds != []
422+ let l: lnum = l: lnum - g: bullets_line_spacing
423+ else
424+ let l: lnum = l: lnum - 1
425+ endif
426+ let l: ltxt = getline (l: lnum )
427+ let l: bullet_kinds = s: parse_bullet (l: lnum , l: ltxt )
428+ let l: curr_indent = indent (l: lnum )
429+ endwhile
430+ endif
385431
386432 return l: bullet_kinds
387433endfun
@@ -819,6 +865,7 @@ fun! s:renumber_selection()
819865endfun
820866
821867fun ! s: renumber_lines (start , end )
868+ call s: enable_bullet_cache ()
822869 let l: prev_indent = -1
823870 let l: levels = {} " stores all the info about the current outline/list
824871
@@ -896,15 +943,18 @@ fun! s:renumber_lines(start, end)
896943 endif
897944 endif
898945 endfor
946+ call s: disable_bullet_cache ()
899947endfun
900948
901949" Renumbers the whole list containing the cursor.
902950fun ! s: renumber_whole_list ()
951+ call s: enable_bullet_cache ()
903952 let l: first_line = s: first_bullet_line (line (' .' ))
904953 let l: last_line = s: last_bullet_line (line (' .' ))
905954 if l: first_line > 0 && l: last_line > 0
906955 call s: renumber_lines (l: first_line , l: last_line )
907956 endif
957+ call s: disable_bullet_cache ()
908958endfun
909959
910960command ! -range =% RenumberSelection call <SID> renumber_selection ()
0 commit comments