Skip to content

Instantly share code, notes, and snippets.

@sedm0784
Last active May 29, 2023 15:43
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sedm0784/dffda43bcfb4728f8e90 to your computer and use it in GitHub Desktop.
Save sedm0784/dffda43bcfb4728f8e90 to your computer and use it in GitHub Desktop.
Vim Automatic List Continuation

Vim Auto List Completion

This snippet makes Vim automatically continue/end lists in insert mode, similar to the way word processors do:

  • It automatically adds the bullet/number for the next list item when you press Return at the end of an existing item,
  • When you press Return on an empty list item, it removes the bullet/number, ending the list.

It supports ordered lists with markers like 1. and unordered lists with - markers (because those are the markers I use.)

(It's particularly useful when using an iOS keyboard where punctuation and numerals are slow to access.)

Installation

If you're not sure how to install, just drop the markdown.vim file itself in ~/vim/after/, or if that file already exists, copy the code into it.

N.B.

  1. I just use this for Markdown, but the code itself doesn't care about the filetype. It should be fairly easy to adjust it for different list styles. Making it a robust, multi-format extension would be a bit more work.
  2. It supports lists with markers like - and 1., because those are the list markers I use, but it would be easy to make it support more types of bullet/numbering.
  3. I've just got it enabled for when I hit Return, but it'd be fairly easy to also enable it for normal mode o and O.

Let me know if you want to tweak it but don't know how to.

" Auto lists: Automatically continue/end lists by adding markers if the
" previous line is a list item, or removing them when they are empty
function! s:auto_list()
let l:preceding_line = getline(line(".") - 1)
if l:preceding_line =~ '\v^\d+\.\s.'
" The previous line matches any number of digits followed by a full-stop
" followed by one character of whitespace followed by one more character
" i.e. it is an ordered list item
" Continue the list
let l:list_index = matchstr(l:preceding_line, '\v^\d*')
call setline(".", l:list_index + 1. ". ")
elseif l:preceding_line =~ '\v^\d+\.\s$'
" The previous line matches any number of digits followed by a full-stop
" followed by one character of whitespace followed by nothing
" i.e. it is an empty ordered list item
" End the list and clear the empty item
call setline(line(".") - 1, "")
elseif l:preceding_line[0] == "-" && l:preceding_line[1] == " "
" The previous line is an unordered list item
if strlen(l:preceding_line) == 2
" ...which is empty: end the list and clear the empty item
call setline(line(".") - 1, "")
else
" ...which is not empty: continue the list
call setline(".", "- ")
endif
endif
endfunction
" N.B. Currently only enabled for return key in insert mode, not for normal
" mode 'o' or 'O'
inoremap <buffer> <CR> <CR><Esc>:call <SID>auto_list()<CR>A
@nhooyr
Copy link

nhooyr commented Mar 5, 2017

Thank you!

@DamienOConnell
Copy link

I love it, thank you.

@Ramkumar47
Copy link

Hey, excellent plugin dude!!.. thanks

@sedm0784
Copy link
Author

sedm0784 commented Sep 3, 2020

Hah... I'd totally forgotten this snippet existed! Glad you all like it :). Keep an eye on my still-in-development List Assist plugin if you're interested in a more robust version with more features.

@K4LCIFER
Copy link

This is exactly what I have been looking for. Thank you so much!

@K4LCIFER
Copy link

K4LCIFER commented Jul 29, 2021

One issue that I am seeing with this is that it doesn't recognize a list item which contains a hard-wrapped block of text. Meaning that if you have a list item that gets hard-wrapped by textwidth, this code snipped will not automatically create a list item when you hit enter.

Another issue that I have just noticed is that it does not recognize nested lists, i.e.

- item 1
- item 2
  - subitem 1
  - subitem 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment