6161if ! exists (' g:bullets_max_alpha_characters' )
6262 let g: bullets_max_alpha_characters = 2
6363end
64+
65+ if ! exists (' g:bullets_enable_roman_list' )
66+ let g: bullets_enable_roman_list = 1
67+ end
68+
6469" calculate the decimal equivalent to the last alphabetical list item
6570let s: power = g: bullets_max_alpha_characters
6671let s: abc_max = -1
@@ -85,6 +90,10 @@ if !exists('g:bullets_nested_checkboxes')
8590 let g: bullets_nested_checkboxes = 1
8691endif
8792
93+ if ! exists (' g:bullets_enable_wrapped_lines' )
94+ let g: bullets_enable_wrapped_lines = 1
95+ end
96+
8897if ! exists (' g:bullets_checkbox_markers' )
8998 " The ordered series of markers to use in checkboxes
9099 " If only two markers are listed, they represent 'off' and 'on'
@@ -116,7 +125,48 @@ endif
116125" ------------------------------------------------------ }}}
117126
118127" 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+
119151fun ! 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
120170
121171 let l: bullet = s: match_bullet_list_item (a: line_text )
122172 " Must be a bullet to be a checkbox
@@ -129,13 +179,12 @@ fun! s:parse_bullet(line_num, line_text)
129179 let l: roman = empty (l: bullet ) && empty (l: num ) ? s: match_roman_list_item (a: line_text ) : {}
130180
131181 let l: kinds = s: filter ([l: bullet , l: check , l: num , l: alpha , l: roman ], ' !empty(v:val)' )
132-
133- for l: data in l: kinds
134- let l: data .starting_at_line_num = a: line_num
135- endfor
136-
182+
183+ if s: bullet_cache isnot v: null
184+ let s: bullet_cache [ a: line_text ] = l: kinds
185+ endif
186+
137187 return l: kinds
138-
139188endfun
140189
141190fun ! s: match_numeric_list_item (input_text)
@@ -166,6 +215,10 @@ endfun
166215
167216
168217fun ! s: match_roman_list_item (input_text)
218+ if g: bullets_enable_roman_list == 0
219+ return {}
220+ endif
221+
169222 let l: rom_bullet_regex = join ([
170223 \ ' \v\C' ,
171224 \ ' ^(' ,
@@ -362,17 +415,19 @@ fun! s:closest_bullet_types(from_line_num, max_indent)
362415 " Support for wrapped text bullets, even if the wrapped line is not indented
363416 " It considers a blank line as the end of a bullet
364417 " DEMO: https://raw.githubusercontent.com/dkarter/bullets.vim/master/img/wrapped-bullets.gif
365- while l: lnum > 1 && (l: curr_indent != 0 || l: bullet_kinds != [] || ! (l: ltxt = ~# ' \v^(\s+$|$)' ))
366- \ && (a: max_indent < l: curr_indent || l: bullet_kinds == [])
367- if l: bullet_kinds != []
368- let l: lnum = l: lnum - g: bullets_line_spacing
369- else
370- let l: lnum = l: lnum - 1
371- endif
372- let l: ltxt = getline (l: lnum )
373- let l: bullet_kinds = s: parse_bullet (l: lnum , l: ltxt )
374- let l: curr_indent = indent (l: lnum )
375- 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
376431
377432 return l: bullet_kinds
378433endfun
@@ -585,8 +640,14 @@ command! InsertNewBullet call <SID>insert_new_bullet()
585640" Helper for Colon Indent
586641" returns 1 if current line ends in a colon, else 0
587642fun ! s: line_ends_in_colon (lnum)
588- let l: last_char_nr = strgetchar (getline (a: lnum ), strcharlen (getline (a: lnum ))-1 )
589- return l: last_char_nr == 65306 || l: last_char_nr == 58
643+ let l: line = getline (a: lnum )
644+ if exists (" *strcharlen" ) && exists (" *strgetchar" )
645+ let l: last_char_nr = strgetchar (l: line , strcharlen (l: line )-1 )
646+ return l: last_char_nr == 65306 || l: last_char_nr == 58
647+ else
648+ " Older versions of vim do not support strchar*
649+ return l: line [strlen (l: line )-1 :] == # ' :'
650+ endif
590651endfun
591652" --------------------------------------------------------- }}}
592653
@@ -804,6 +865,7 @@ fun! s:renumber_selection()
804865endfun
805866
806867fun ! s: renumber_lines (start , end )
868+ call s: enable_bullet_cache ()
807869 let l: prev_indent = -1
808870 let l: levels = {} " stores all the info about the current outline/list
809871
@@ -881,15 +943,18 @@ fun! s:renumber_lines(start, end)
881943 endif
882944 endif
883945 endfor
946+ call s: disable_bullet_cache ()
884947endfun
885948
886949" Renumbers the whole list containing the cursor.
887950fun ! s: renumber_whole_list ()
951+ call s: enable_bullet_cache ()
888952 let l: first_line = s: first_bullet_line (line (' .' ))
889953 let l: last_line = s: last_bullet_line (line (' .' ))
890954 if l: first_line > 0 && l: last_line > 0
891955 call s: renumber_lines (l: first_line , l: last_line )
892956 endif
957+ call s: disable_bullet_cache ()
893958endfun
894959
895960command ! -range =% RenumberSelection call <SID> renumber_selection ()
0 commit comments