11scriptencoding utf- 8
22" Vim plugin for automated bulleted lists
3- " Last Change: Sat Jan 29 06:56:14 PM CST 2022
43" Maintainer: Dorian Karter
54" License: MIT
6- " FileTypes: markdown, text, gitcommit
75
86" Preserve Vim compatibility settings ------------------- {{{
97let s: save_cpo = &cpoptions
@@ -23,7 +21,7 @@ if !exists('g:bullets_enabled_file_types')
2321endif
2422
2523if ! exists (' g:bullets_enable_in_empty_buffers' )
26- let g: bullets_enable_in_empty_buffers = 1
24+ let g: bullets_enable_in_empty_buffers = 0
2725end
2826
2927if ! exists (' g:bullets_set_mappings' )
6159if ! exists (' g:bullets_max_alpha_characters' )
6260 let g: bullets_max_alpha_characters = 2
6361end
62+
63+ if ! exists (' g:bullets_enable_roman_list' )
64+ let g: bullets_enable_roman_list = 1
65+ end
66+
6467" calculate the decimal equivalent to the last alphabetical list item
6568let s: power = g: bullets_max_alpha_characters
6669let s: abc_max = -1
@@ -85,6 +88,10 @@ if !exists('g:bullets_nested_checkboxes')
8588 let g: bullets_nested_checkboxes = 1
8689endif
8790
91+ if ! exists (' g:bullets_enable_wrapped_lines' )
92+ let g: bullets_enable_wrapped_lines = 1
93+ end
94+
8895if ! exists (' g:bullets_checkbox_markers' )
8996 " The ordered series of markers to use in checkboxes
9097 " If only two markers are listed, they represent 'off' and 'on'
@@ -116,7 +123,48 @@ endif
116123" ------------------------------------------------------ }}}
117124
118125" Parse Bullet Type ------------------------------------------- {{{
126+
127+ " A caching mechanism for bullet
128+ " We add a crude 'reference count' for the cache so we can nest calls
129+ let s: bullet_cache = v: null
130+ let s: bullet_cache_depth = 0
131+
132+ fun ! s: enable_bullet_cache ()
133+ if s: bullet_cache_depth == 0
134+ let s: bullet_cache = {}
135+ endif
136+ let s: bullet_cache_depth += 1
137+ endfun
138+
139+ fun ! s: disable_bullet_cache ()
140+ if s: bullet_cache_depth == 1
141+ let s: bullet_cache = v: null
142+ endif
143+
144+ if s: bullet_cache_depth > 0
145+ let s: bullet_cache_depth -= 1
146+ endif
147+ endfun
148+
119149fun ! s: parse_bullet (line_num, line_text)
150+ let l: kinds = s: parse_bullet_text (a: line_text )
151+
152+ for l: data in l: kinds
153+ let l: data .starting_at_line_num = a: line_num
154+ endfor
155+
156+ return l: kinds
157+ endfun
158+
159+ fun ! s: parse_bullet_text (line_text)
160+
161+ if s: bullet_cache isnot v: null
162+ let l: cached = get (s: bullet_cache , a: line_text , v: null )
163+ if l: cached isnot v: null
164+ " Return a copy so as not to break the referene
165+ return copy (l: cached )
166+ endif
167+ endif
120168
121169 let l: bullet = s: match_bullet_list_item (a: line_text )
122170 " Must be a bullet to be a checkbox
@@ -129,13 +177,12 @@ fun! s:parse_bullet(line_num, line_text)
129177 let l: roman = empty (l: bullet ) && empty (l: num ) ? s: match_roman_list_item (a: line_text ) : {}
130178
131179 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-
180+
181+ if s: bullet_cache isnot v: null
182+ let s: bullet_cache [ a: line_text ] = l: kinds
183+ endif
184+
137185 return l: kinds
138-
139186endfun
140187
141188fun ! s: match_numeric_list_item (input_text)
@@ -166,6 +213,10 @@ endfun
166213
167214
168215fun ! s: match_roman_list_item (input_text)
216+ if g: bullets_enable_roman_list == 0
217+ return {}
218+ endif
219+
169220 let l: rom_bullet_regex = join ([
170221 \ ' \v\C' ,
171222 \ ' ^(' ,
@@ -362,17 +413,19 @@ fun! s:closest_bullet_types(from_line_num, max_indent)
362413 " Support for wrapped text bullets, even if the wrapped line is not indented
363414 " It considers a blank line as the end of a bullet
364415 " 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
416+ if g: bullets_enable_wrapped_lines
417+ while l: lnum > 1 && (l: curr_indent != 0 || l: bullet_kinds != [] || ! (l: ltxt = ~# ' \v^(\s+$|$)' ))
418+ \ && (a: max_indent < l: curr_indent || l: bullet_kinds == [])
419+ if l: bullet_kinds != []
420+ let l: lnum = l: lnum - g: bullets_line_spacing
421+ else
422+ let l: lnum = l: lnum - 1
423+ endif
424+ let l: ltxt = getline (l: lnum )
425+ let l: bullet_kinds = s: parse_bullet (l: lnum , l: ltxt )
426+ let l: curr_indent = indent (l: lnum )
427+ endwhile
428+ endif
376429
377430 return l: bullet_kinds
378431endfun
@@ -810,6 +863,7 @@ fun! s:renumber_selection()
810863endfun
811864
812865fun ! s: renumber_lines (start , end )
866+ call s: enable_bullet_cache ()
813867 let l: prev_indent = -1
814868 let l: levels = {} " stores all the info about the current outline/list
815869
@@ -887,15 +941,18 @@ fun! s:renumber_lines(start, end)
887941 endif
888942 endif
889943 endfor
944+ call s: disable_bullet_cache ()
890945endfun
891946
892947" Renumbers the whole list containing the cursor.
893948fun ! s: renumber_whole_list ()
949+ call s: enable_bullet_cache ()
894950 let l: first_line = s: first_bullet_line (line (' .' ))
895951 let l: last_line = s: last_bullet_line (line (' .' ))
896952 if l: first_line > 0 && l: last_line > 0
897953 call s: renumber_lines (l: first_line , l: last_line )
898954 endif
955+ call s: disable_bullet_cache ()
899956endfun
900957
901958command ! -range =% RenumberSelection call <SID> renumber_selection ()
@@ -1067,7 +1124,7 @@ fun! s:add_local_mapping(with_leader, mapping_type, mapping, action)
10671124 \ a: action
10681125
10691126 if g: bullets_enable_in_empty_buffers
1070- execute ' autocmd BufEnter * if bufname("") == "" | ' .
1127+ execute ' autocmd BufNew,BufRead * if empty(&filetype) | ' .
10711128 \ a: mapping_type .
10721129 \ ' <silent> <buffer> ' .
10731130 \ (a: with_leader ? g: bullets_mapping_leader : ' ' ) .
0 commit comments