From ce5a55969d2994a07665b423db0aee38add722bd Mon Sep 17 00:00:00 2001 From: Aziz Light Date: Sat, 19 Oct 2013 17:24:00 +0200 Subject: [PATCH 1/4] Add auto-lists This feature lets Vim automatically add a new list item on (or end a list if the list item is blank). In the case of ordered lists, the list item number is incremented. --- ftplugin/markdown.vim | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/ftplugin/markdown.vim b/ftplugin/markdown.vim index 022da06..37dce7a 100644 --- a/ftplugin/markdown.vim +++ b/ftplugin/markdown.vim @@ -18,4 +18,58 @@ else let b:undo_ftplugin = "setl cms< com< fo< flp<" endif +" Markdown auto lists +function! AutoMDList() + let line=getline('.') + + " Potential unordered list match + let umatches=matchstr(line, '^-') + + " Potential ordered list match + let omatches=matchstr(line, '^\d\+\.') + + if empty(umatches) && empty(omatches) + " TODO: Handle the case where a list item spans over several lines. + " + " In that case, a new list item needs to be added. + " + " I don't know (yet) how to do this without going up a line in a loop and + " checking if it's the first line of the list item (that is a terrible + " solution!!) + + " If the user is not in a list, use the default behaviour for + call feedkeys("\", "n") + elseif empty(omatches) + " The case of an unordered list + + if !empty(matchstr(line, '^-\s\?$')) + " If the user is on a blank list item (i.e.: "- ") and presses , end + " the list... + exec ':normal! cc' | call feedkeys("\", "n") + else + " ...otherwise add a list item + exec ':normal! o- ' | exec ':startinsert!' + endif + elseif empty(umatches) + " The case of an ordered list + + if !empty(matchstr(line, '^\d\+\.\s\?$')) + " If the user is on a blank list item (i.e.: "42. ") and presses , + " end the list... + exec ':normal! cc' | call feedkeys("\", "n") + else + " ...otherwise, increment the list item number... + let l:nln=omatches + 1 + + " ...and add a new item + exec ':normal! o' . l:nln . '. ' | exec ':startinsert!' + endif + endif + + return +endf + +" Remap for all .md files +au BufEnter *.md inoremap :call AutoMDList() + " vim:set sw=2: From d58a0a612bdbd46dff25e5a188cb8585e626063a Mon Sep 17 00:00:00 2001 From: Aziz Light Date: Sat, 19 Oct 2013 17:56:18 +0200 Subject: [PATCH 2/4] Add the support the asterisk (`*`) list item character for unordered lists --- ftplugin/markdown.vim | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ftplugin/markdown.vim b/ftplugin/markdown.vim index 37dce7a..6fdedb6 100644 --- a/ftplugin/markdown.vim +++ b/ftplugin/markdown.vim @@ -23,7 +23,7 @@ function! AutoMDList() let line=getline('.') " Potential unordered list match - let umatches=matchstr(line, '^-') + let umatches=matchstr(line, '^[*-]') " Potential ordered list match let omatches=matchstr(line, '^\d\+\.') @@ -42,13 +42,18 @@ function! AutoMDList() elseif empty(omatches) " The case of an unordered list - if !empty(matchstr(line, '^-\s\?$')) + if !empty(matchstr(line, '^[*-]\s\?$')) " If the user is on a blank list item (i.e.: "- ") and presses , end " the list... exec ':normal! cc' | call feedkeys("\", "n") else " ...otherwise add a list item - exec ':normal! o- ' | exec ':startinsert!' + + if !empty(matchstr(line, '^-\s.*')) + exec ':normal! o- ' | exec ':startinsert!' + elseif !empty(matchstr(line, '^\*\s.*')) + exec ':normal! o* ' | exec ':startinsert!' + endif endif elseif empty(umatches) " The case of an ordered list From 01efb47e75fef093e74fc88cbdd09900356c1990 Mon Sep 17 00:00:00 2001 From: Aziz Light Date: Sat, 19 Oct 2013 19:10:04 +0200 Subject: [PATCH 3/4] Add the support for the plus (`+`) list item character for unordered lists and replace useless `if` statements by a single line --- ftplugin/markdown.vim | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ftplugin/markdown.vim b/ftplugin/markdown.vim index 6fdedb6..f19ddf2 100644 --- a/ftplugin/markdown.vim +++ b/ftplugin/markdown.vim @@ -23,7 +23,7 @@ function! AutoMDList() let line=getline('.') " Potential unordered list match - let umatches=matchstr(line, '^[*-]') + let umatches=matchstr(line, '^[*+-]') " Potential ordered list match let omatches=matchstr(line, '^\d\+\.') @@ -42,18 +42,14 @@ function! AutoMDList() elseif empty(omatches) " The case of an unordered list - if !empty(matchstr(line, '^[*-]\s\?$')) + if !empty(matchstr(line, '^[*+-]\s\?$')) " If the user is on a blank list item (i.e.: "- ") and presses , end " the list... exec ':normal! cc' | call feedkeys("\", "n") else " ...otherwise add a list item - if !empty(matchstr(line, '^-\s.*')) - exec ':normal! o- ' | exec ':startinsert!' - elseif !empty(matchstr(line, '^\*\s.*')) - exec ':normal! o* ' | exec ':startinsert!' - endif + exec ':normal! o' . umatches . ' ' | exec ':startinsert!' endif elseif empty(umatches) " The case of an ordered list From 27182ec8e22703e832336f0342f4f89bbe04a2a5 Mon Sep 17 00:00:00 2001 From: Aziz Light Date: Sun, 20 Oct 2013 17:18:08 +0200 Subject: [PATCH 4/4] Temporary fix for a stupid bug. See full commit message for the full details. Bug: ---- When the caret is on a list item, somewhere in the middle of the line, and the user presses ``, then a new list item is added on a new line instead of splitting the current line. This commit partly fixes that bug. Caveat: ------- When the caret is on a list item, at the character previous to the last one (`col('$') - 1`), and the user presses ``, then a new list item will be added on a new line instead of splitting the current line. --- ftplugin/markdown.vim | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ftplugin/markdown.vim b/ftplugin/markdown.vim index f19ddf2..7d82638 100644 --- a/ftplugin/markdown.vim +++ b/ftplugin/markdown.vim @@ -19,6 +19,8 @@ else endif " Markdown auto lists +" BUG: If the cursor is on a list item at `col('$') - 1`, then a new list item +" will be added on a new line instead of splitting the line function! AutoMDList() let line=getline('.') @@ -46,10 +48,15 @@ function! AutoMDList() " If the user is on a blank list item (i.e.: "- ") and presses , end " the list... exec ':normal! cc' | call feedkeys("\", "n") - else - " ...otherwise add a list item + elseif col('.') == len(getline('.')) + " ...otherwise, if the cursor is at the end of the line, add a list + " item... exec ':normal! o' . umatches . ' ' | exec ':startinsert!' + else + " ...and if the cursor is in the middle of a line, use the default + " behaviour for + call feedkeys("\", "n") endif elseif empty(umatches) " The case of an ordered list @@ -58,12 +65,16 @@ function! AutoMDList() " If the user is on a blank list item (i.e.: "42. ") and presses , " end the list... exec ':normal! cc' | call feedkeys("\", "n") - else - " ...otherwise, increment the list item number... + elseif col('.') == len(getline('.')) + " ...otherwise, if the cursor is at the end of the line, increment the list item number... let l:nln=omatches + 1 " ...and add a new item exec ':normal! o' . l:nln . '. ' | exec ':startinsert!' + else + " ...and if the cursor is in the middle of a line, use the default + " behaviour for + call feedkeys("\", "n") endif endif