Skip to content

Instantly share code, notes, and snippets.

@sedm0784
Last active March 28, 2025 20:04
Show Gist options
  • 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
@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

@kipawaa
Copy link

kipawaa commented Jan 15, 2025

I found this really useful but wanted the same functionality for indented lists so I've added that for myself. I'm not sure what the best way is to share my changes to a gist, but if someone could let me know I'd be happy to make them public.

@sedm0784
Copy link
Author

I'm not sure what the best way is to share my changes to a gist, but if someone could let me know I'd be happy to make them public.

I'm also not sure if there's a better way, but mostly people seem to just publish their own gist and paste a link into a comment on the original.

@kipawaa
Copy link

kipawaa commented Mar 28, 2025

I've published my changes in a new gist.

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