Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caching bullets for performance #146

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr>
<td align="center"><a href="https://github.com/mykoza"><img src="https://avatars1.githubusercontent.com/u/48719773?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mykoza</b></sub></a><br /><a href="https://github.com/bullets-vim/bullets.vim/commits?author=mykoza" title="Code">💻</a> <a href="#ideas-mykoza" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://github.com/noodlor"><img src="https://avatars3.githubusercontent.com/u/49209345?v=4?s=100" width="100px;" alt=""/><br /><sub><b>noodlor</b></sub></a><br /><a href="https://github.com/bullets-vim/bullets.vim/commits?author=noodlor" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/harshad1"><img src="https://avatars0.githubusercontent.com/u/1940940?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Harshad Srinivasan</b></sub></a><br /><a href="https://github.com/bullets-vim/bullets.vim/commits?author=harshad1" title="Code">💻</a> <a href="https://github.com/bullets-vim/bullets.vim/issues?q=author%3Aharshad1" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://github.com/harshad1"><img src="https://avatars0.githubusercontent.com/u/1940940?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Harshad Vedartham</b></sub></a><br /><a href="https://github.com/bullets-vim/bullets.vim/commits?author=harshad1" title="Code">💻</a> <a href="https://github.com/bullets-vim/bullets.vim/issues?q=author%3Aharshad1" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://erickchacon.github.io/"><img src="https://avatars2.githubusercontent.com/u/7862458?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Erick A. Chacón Montalván</b></sub></a><br /><a href="#ideas-ErickChacon" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://samgriesemer.com"><img src="https://avatars.githubusercontent.com/u/19940657?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sam Griesemer</b></sub></a><br /><a href="https://github.com/bullets-vim/bullets.vim/commits?author=samgriesemer" title="Code">💻</a> <a href="https://github.com/bullets-vim/bullets.vim/issues?q=author%3Asamgriesemer" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://codeberg.org/cpence"><img src="https://avatars.githubusercontent.com/u/297075?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Charles Pence</b></sub></a><br /><a href="https://github.com/bullets-vim/bullets.vim/commits?author=cpence" title="Code">💻</a></td>
Expand Down
84 changes: 67 additions & 17 deletions plugin/bullets.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 <SID>renumber_selection()
Expand Down
Loading