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

Do not change selection to update lists #145

Merged
merged 12 commits into from
Jan 31, 2024
75 changes: 31 additions & 44 deletions plugin/bullets.vim
Original file line number Diff line number Diff line change
Expand Up @@ -749,21 +749,26 @@ endfun

" Renumbering --------------------------------------------- {{{
fun! s:renumber_selection()
let l:selection_lines = s:get_visual_selection_lines()
let l:start = getpos("'<")[1]
let l:end = getpos("'>")[1]
call s:renumber_lines(l:start, l:end)
endfun

fun! s:renumber_lines(start, end)
let l:prev_indent = -1
let l:levels = {} " stores all the info about the current outline/list

for l:line in l:selection_lines
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are using just the line numbers anyway so a loop is sufficient

let l:indent = indent(l:line.nr)
let l:bullet = s:closest_bullet_types(l:line.nr, l:indent)
for l:nr in range(a:start, a:end)
let l:indent = indent(l:nr)
let l:bullet = s:closest_bullet_types(l:nr, l:indent)
let l:bullet = s:resolve_bullet_type(l:bullet)
let l:curr_level = s:get_level(l:bullet)
if l:curr_level > 1
" then it's an AsciiDoc list and shouldn't be renumbered
break
endif

if !empty(l:bullet) && l:bullet.starting_at_line_num == l:line.nr
if !empty(l:bullet) && l:bullet.starting_at_line_num == l:nr
" skip wrapped lines and lines that aren't bullets
if (l:indent > l:prev_indent || !has_key(l:levels, l:indent))
\ && l:bullet.bullet_type !=# 'chk' && l:bullet.bullet_type !=# 'std'
Expand Down Expand Up @@ -818,36 +823,23 @@ fun! s:renumber_selection()
let l:renumbered_line = l:bullet.leading_space
\ . l:new_bullet
\ . l:bullet.text_after_bullet
call setline(l:line.nr, l:renumbered_line)
call setline(l:nr, l:renumbered_line)
elseif l:bullet.bullet_type ==# 'chk'
" Reset the checkbox marker if it already exists, or blank otherwise
let l:marker = has_key(l:bullet, 'checkbox_marker') ?
\ l:bullet.checkbox_marker : ' '
call s:set_checkbox(l:line.nr, l:marker)
call s:set_checkbox(l:nr, l:marker)
endif
endif
endfor
endfun

fun! s:renumber_whole_list(...)
" Renumbers the whole list containing the cursor.
" Does not renumber across blank lines.
" Takes 2 optional arguments containing starting and ending cursor positions
" so that we can reset the existing visual selection after renumbering.
" Renumbers the whole list containing the cursor.
fun! s:renumber_whole_list()
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
" Create a visual selection around the current list so that we can call
" s:renumber_selection() to do the renumbering.
call setpos("'<", [0, l:first_line, 1, 0])
call setpos("'>", [0, l:last_line, 1, 0])
call s:renumber_selection()
if a:0 == 2
" Reset the starting visual selection
call setpos("'<", [0, a:1[0], a:1[1], 0])
call setpos("'>", [0, a:2[0], a:2[1], 0])
execute 'normal! gv'
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need any of the reset visual selection code

endif
call s:renumber_lines(l:first_line, l:last_line)
endif
endfun

Expand All @@ -856,14 +848,13 @@ command! RenumberList call <SID>renumber_whole_list()
" --------------------------------------------------------- }}}

" Changing outline level ---------------------------------- {{{
fun! s:change_bullet_level(direction)
let l:lnum = line('.')
let l:curr_line = s:parse_bullet(l:lnum, getline(l:lnum))
fun! s:change_bullet_level(direction, lnum)
let l:curr_line = s:parse_bullet(a:lnum, getline(a:lnum))

if a:direction == 1
if l:curr_line != [] && indent(l:lnum) == 0
if l:curr_line != [] && indent(a:lnum) == 0
" Promoting a bullet at the highest level will delete the bullet
call setline(l:lnum, l:curr_line[0].text_after_bullet)
call setline(a:lnum, l:curr_line[0].text_after_bullet)
execute 'normal! $'
return
else
Expand All @@ -878,8 +869,8 @@ fun! s:change_bullet_level(direction)
return
endif

let l:curr_indent = indent(l:lnum)
let l:curr_bullet= s:closest_bullet_types(l:lnum, l:curr_indent)
let l:curr_indent = indent(a:lnum)
let l:curr_bullet= s:closest_bullet_types(a:lnum, l:curr_indent)
let l:curr_bullet = s:resolve_bullet_type(l:curr_bullet)

let l:curr_line = l:curr_bullet.starting_at_line_num
Expand Down Expand Up @@ -963,35 +954,30 @@ fun! s:change_bullet_level(direction)
endif

" Apply the new bullet
call setline(l:lnum, l:next_bullet_str)
call setline(a:lnum, l:next_bullet_str)

execute 'normal! $'
return
endfun

fun! s:change_bullet_level_and_renumber(direction)
" Calls change_bullet_level and then renumber_whole_list if required
call s:change_bullet_level(a:direction)
call s:change_bullet_level(a:direction, line(','))
if g:bullets_renumber_on_change
call s:renumber_whole_list()
endif
endfun

fun! s:visual_change_bullet_level(direction)
" Changes the bullet level for each of the selected lines
let l:start = getpos("'<")[1:2]
let l:end = getpos("'>")[1:2]
let l:selected_lines = range(l:start[0], l:end[0])
for l:lnum in l:selected_lines
" Iterate the cursor position over each line and then call
" s:change_bullet_level for that cursor position.
call setpos('.', [0, l:lnum, 1, 0])
call s:change_bullet_level(a:direction)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pass in the number to save on a lot of unnecessary work

let l:start = getpos("'<")[1]
let l:end = getpos("'>")[1]
for l:lnum in range(l:start, l:end)
call s:change_bullet_level(a:direction, l:lnum)
endfor

if g:bullets_renumber_on_change
" Pass the current visual selection so that it gets reset after
" renumbering the list.
call s:renumber_whole_list(l:start, l:end)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed now!

call s:renumber_whole_list()
endif
endfun

Expand Down Expand Up @@ -1089,9 +1075,10 @@ fun! s:get_visual_selection_lines()
let l:index = l:lnum1
let l:lines_with_index = []
for l:line in l:lines
let l:lines_with_index += [{'text': l:line, 'nr': l:index}]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an optimisation.

However, the entire get_visual_selection_lines() is not needed anymore and perhaps ought to be removed.

call add(l:lines_with_index, {'text': l:line, 'nr': l:index})
let l:index += 1
endfor
echom l:lines_with_index
return l:lines_with_index
endfun

Expand Down
Loading