aboutsummaryrefslogtreecommitdiff
path: root/vim/after/ftplugin/mail.vim
blob: a30b155a8bbfaf048c23b4a845ae7bbb48f2eb07 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
" Extra configuration for mail messages
if &filetype !=# 'mail' || &compatible || v:version < 700
  finish
endif

" If something hasn't already moved the cursor, we'll move to an optimal point
" to start writing
if line('.') == 1 && col('.') == 1

  " Start by trying to move to the first quoted line; this may fail if there's
  " no quote, which is fine
  call search('\m^>', 'c')

  " Check this line to see if it's a generic hello-name greeting that we can
  " just strip out; delete the following line too, if it's blank
  if getline('.') =~? '^>\s*\%(<hello\|hi\)\s\+\S\+\s*$'
    delete
    if getline('.') =~# '^>$'
      delete
    endif
  endif

  " Now move to the first quoted or unquoted blank line
  call search('\m^>\=$', 'c')

endif

" Add a space to the end of wrapped lines for format-flowed mail
setlocal formatoptions+=w
let b:undo_ftplugin .= '|setlocal formatoptions<'

" Stop here if the user doesn't want ftplugin mappings
if exists('g:no_plugin_maps') || exists('g:no_mail_maps')
  finish
endif

" The quote mapping in the stock plugin is a good idea, but I prefer it to
" work as a motion rather than quoting to the end of the buffer
nnoremap <buffer> <expr> <LocalLeader>q quote#Quote()
nnoremap <buffer> <expr> <LocalLeader>qq quote#Quote().'_'
xnoremap <buffer> <expr> <LocalLeader>q quote#Quote()
nnoremap <buffer> <expr> <LocalLeader>Q quote#QuoteReformat()
nnoremap <buffer> <expr> <LocalLeader>QQ quote#QuoteReformat().'_'
xnoremap <buffer> <expr> <LocalLeader>Q quote#QuoteReformat()
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>q'
      \ . '|nunmap <buffer> <LocalLeader>qq'
      \ . '|xunmap <buffer> <LocalLeader>q'
      \ . '|nunmap <buffer> <LocalLeader>Q'
      \ . '|nunmap <buffer> <LocalLeader>QQ'
      \ . '|xunmap <buffer> <LocalLeader>Q'

" Flag a message as unimportant
function! s:FlagUnimportant()
  call cursor(1, 1)
  call search('^$')
  -
  call append(line('.'), 'X-Priority: 5')
  call append(line('.'), 'Importance: Low')
endfunction
nnoremap <buffer>
      \ <LocalLeader>l
      \ <C-U>:call <SID>FlagUnimportant()<CR>
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>l'

" Move through quoted paragraphs like normal-mode `{` and `}`
function! s:NewBlank(count, up, visual) abort

  " Reselect visual selection
  if a:visual
    normal! gv
  endif

  " Flag for whether we've started a block
  let l:block = 0

  " Flag for the number of blocks passed
  let l:blocks = 0

  " Iterate through buffer lines
  let l:num = line('.')
  while a:up ? l:num > 1 : l:num < line('$')

    " If the line is blank
    if getline(l:num) =~# '^[ >]*$'

      " If we'd moved through a non-blank block already, reset that flag and
      " bump up the block count
      if l:block
        let l:block = 0
        let l:blocks += 1
      endif

      " If we've hit the number of blocks, end the loop
      if l:blocks == a:count
        break
      endif

    " If the line is not blank, flag that we're going through a block
    else
      let l:block = 1
    endif

    " Move the line number or up or down depending on direction
    let l:num += a:up ? -1 : 1

  endwhile

  " Move to line if nonzero and not equal to the current line
  if l:num != line('.')
    execute 'normal '.l:num.'G'
  endif

endfunction

" Maps using NewBlank() function above for quoted paragraph movement
nnoremap <buffer> <silent> <LocalLeader>[
      \ :<C-U>call <SID>NewBlank(v:count1, 1, 0)<CR>
nnoremap <buffer> <silent> <LocalLeader>]
      \ :<C-U>call <SID>NewBlank(v:count1, 0, 0)<CR>
onoremap <buffer> <silent> <LocalLeader>[
      \ :<C-U>call <SID>NewBlank(v:count1, 1, 0)<CR>
onoremap <buffer> <silent> <LocalLeader>]
      \ :<C-U>call <SID>NewBlank(v:count1, 0, 0)<CR>
xnoremap <buffer> <silent> <LocalLeader>[
      \ :<C-U>call <SID>NewBlank(v:count1, 1, 1)<CR>
xnoremap <buffer> <silent> <LocalLeader>]
      \ :<C-U>call <SID>NewBlank(v:count1, 0, 1)<CR>
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>['
      \ . '|nunmap <buffer> <LocalLeader>]'
      \ . '|ounmap <buffer> <LocalLeader>['
      \ . '|ounmap <buffer> <LocalLeader>]'
      \ . '|xunmap <buffer> <LocalLeader>['
      \ . '|xunmap <buffer> <LocalLeader>]'