aboutsummaryrefslogtreecommitdiff
path: root/plugin/commenter.vim
blob: 0681378f263fd721c0c47b731bde5990914cdc81 (plain) (blame)
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
" Function for commenting out blocks of text.

noremap cd <cmd>set operatorfunc=<sid>comment<cr>g@
nnoremap cdd <cmd>set operatorfunc=<sid>comment<cr>g@_
nnoremap cD <cmd>set operatorfunc=<sid>comment<cr>g@$

noremap czd <cmd>set operatorfunc=<sid>uncomment<cr>g@
nnoremap czdd <cmd>set operatorfunc=<sid>uncomment<cr>g@_

      "  filetype, linecomment, block start, block continue, blockend, blockpad,
      "  inline_support
let s:comment_style = {
      \ 'java': ['//', '/*', ' *', '*/', 1, 1],
      \ 'c':    ['//', '/*', ' *', '*/', 1, 1],
      \ 'cpp':  ['//', '/*', ' *', '*/', 1, 1],
      \ 'vim':  ['"',  '"',  '"',  '"',  0, 0]
      \ }


function! s:uncomment(arg, ...) abort

  let [line_com, bstart, bcont, bend, bpad, inl] =
        \ get(s:comment_style, &ft, ['#', '#', '#', '#', 0, 0])
  let l1 = line("'[")
  let l2 = line("']")

  if inl
    silent exec printf(
          \ 'silent! %s,%s s/\V\zs%s\s\?\ze//', l1, l2, escape(bstart, '/'))
    silent exec printf('silent! %s,%s s/\V\zs\s\?%s\ze//', l1, l2, escape(bend, '/'))
  endif

  silent exec printf('silent! %s,%s s/\V\^\s\*\zs%s\s\?\ze//', l1, l2, escape(line_com, '/'))
  silent exec printf('silent! %s,%s s/\V\^\s\*\zs%s\s\?\ze//', l1, l2, escape(bcont, '/'))
endfunction

function! s:comment(arg, ...) abort
  let cb = { 'arg': a:arg }
  normal! m`

  function! cb.operate(ls, t) dict abort
    let [line_com, bstart, bcont, bend, bpad, inl] = get(s:comment_style, &ft, ['#', '#', '#', '#', 0, 0])
    let smallest = 100
    let ls = a:ls

    if self.arg == 'line' || len(ls) > 1
      for l in ls
        if ! (l =~ '^\s*$')
          let sz = match(l, '^\(\s\+\)\zs\S\ze') + 1
          if sz <= 0
            let sz = 1
          endif

          if sz < smallest && sz > 0
            let smallest = sz
          endif
        endif
      endfor

      if self.arg == 'line'
        let i = 0
        while i < len(ls)
          let ls[i] = substitute(ls[i], printf('\%%%dc', smallest), line_com . ' ', '')
          let i += 1
        endwhile
      else
        if self.arg != 'line' && !inl
          throw "Inline comments not allowed"
        endif

        let ls[0] = substitute(ls[0], '^', bstart . ' ', '')
        let ls[-1] = substitute(ls[-1], '$', ' ' . bend, '')
      endif
    else
      let l = getline('.')
      if l[len(l) - len(ls[0]):] ==# ls[0]
        let ls[0] = printf("%s %s", line_com, ls[0])
      else
        if !inl
          throw "Inline comments not allowed"
        endif
        let ls[0] = printf("%s %s %s", bstart, ls[0], bend)
      endif
    endif

    return ls
  endfunction

  call fieldmarshal#modifytext(a:arg, cb)
  norm ``
endfunction