aboutsummaryrefslogtreecommitdiffhomepage
path: root/.vim/my/ftplugin/todolist.vim
blob: e65faa3e94f2b6f6955f3bbaa3ddec231dcaae9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
scriptencoding utf-8


if exists('b:did_ftplugin_todolist')
    finish
endif



inoremap <silent> <buffer> <expr>  <Space>  <SID>checkbox(0, ' ')
inoremap <silent> <buffer> <expr>  x        <SID>checkbox(1, 'x')

nnoremap <silent> <buffer>  <Plug>(todolist-toggle-checkbox)      :<C-u>call <SID>toggle_checkbox()<CR>
nnoremap <silent> <buffer>  <Plug>(todolist-toggle-checkbox-rec)  :<C-u>call <SID>toggle_checkbox_rec()<CR>


function! s:checkbox(check, char)
    let line = getline('.')
    if line =~# '^\s*$' && len(line) % shiftwidth() == 0
        if a:check
            return '[x] '
        else
            return '[ ] '
        endif
    else
        return a:char
    endif
endfunction


function! s:toggle_checkbox()
    call s:toggle_checkbox_internal(line('.'), -1)
endfunction


function! s:toggle_checkbox_rec()
    let checked = s:toggle_checkbox_internal(line('.'), -1)
    if checked == -1
        return
    endif
    if line('.') == line('$')
        return
    endif

    let indent_lv = indent('.')
    for l in range(line('.') + 1, line('$'))
        if indent(l) <= indent_lv
            break
        end
        call s:toggle_checkbox_internal(l, checked)
    endfor
endfunction


function! s:toggle_checkbox_internal(line_num, ck_force)
    let line = getline(a:line_num)
    let match = matchlist(line, '^\(\s*\)\[\([x ]\)\]\(.*\)')
    if empty(match)
        return -1
    endif

    let [whole, spaces, ck, rest; _] = match
    let checked = a:ck_force == -1 ? ck == 'x' : a:ck_force
    let line = spaces . '[' . (checked ? ' ' : 'x') . ']' . rest
    call setline(a:line_num, line)
    return checked
endfunction



let b:did_ftplugin_todolist = 1