aboutsummaryrefslogtreecommitdiff
path: root/vim/after/ftplugin/mail.vim
blob: fd67bc514e68bc9773f9fe1d3157037bd0153a23 (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
134
135
136
137
138
139
140
141
" Don't append spaces after quote chars, for strict compliance with
" format=flowed
let b:quote_space = 0

" 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')

  " Delete quoted blank lines or quoted greetings until we get to something
  " with substance.  Yes, I like Perl, how could you tell?
  while getline('.') =~? '^> *'
        \ . '\%('
          \ . '\%('
            \ . 'g[''\u2019]\=day'
            \ . '\|\%(good \)\=\%(morning\|afternoon\|evening\)'
            \ . '\|h[eu]\%(ll\|rr\)o\+'
            \ . '\|hey\+'
            \ . '\|hi\+'
            \ . '\|sup'
            \ . '\|what[''\u2019]\=s up'
            \ . '\|yo'
          \ . '\)'
          \ . '[[:punct:] ]*'
          \ . '\%('
            \ . '\a\+'
            \ . '[[:punct:] ]*'
          \ . '\)\='
        \ . '\)\=$'
    delete
  endwhile

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

endif

" Normalise quoting
let body = 0
for lnum in range(1, line('$'))

  " Get current line
  let line = getline(lnum)

  " Skip lines until we hit a blank line, meaning body text
  let body = body || !strlen(line)
  if !body
    continue
  endif

  " Get the leading quote string, if any; skip if there isn't one
  let quote = matchstr(line, '^>[> ]*')
  if strlen(quote) == 0
    continue
  endif

  " Normalise the quote with no spaces
  let quote = substitute(quote, '[^>]', '', 'g')

  " Re-set the line
  let line = substitute(line, '^[> ]\+', quote, '')
  call setline(lnum, line)

endfor

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

" Mail-specific handling for custom vim-squeeze-repeat-blanks plugin
if exists('loaded_squeeze_repeat_blanks')

  " Set the blank line pattern
  let b:squeeze_repeat_blanks_blank = '^[ >]*$'
  let b:undo_ftplugin .= '|unlet b:squeeze_repeat_blanks_blank'

  " If there is anything quoted in this message (i.e. it looks like a reply),
  " squeeze blanks, but don't report lines deleted
  if search('\m^>', 'cnw')
    silent SqueezeRepeatBlanks
  endif

endif

" Spellcheck documents we're actually editing (not just viewing)
if &modifiable && !&readonly
  setlocal spell
  let b:undo_ftplugin .= '|setlocal spell<'
endif

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

" Flag messages as important/unimportant
nnoremap <buffer> <LocalLeader>h
      \ :<C-U>call mail#FlagImportant()<CR>
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>h'
nnoremap <buffer> <LocalLeader>l
      \ :<C-U>call mail#FlagUnimportant()<CR>
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>l'

" Quote operator
nnoremap <buffer> <expr> <LocalLeader>q
      \ quote#Quote()
xnoremap <buffer> <expr> <LocalLeader>q
      \ quote#Quote()
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>q'
      \ . '|xunmap <buffer> <LocalLeader>q'

" Quote operator with reformatting
nnoremap <buffer> <expr> <LocalLeader>Q
      \ quote#QuoteReformat()
xnoremap <buffer> <expr> <LocalLeader>Q
      \ quote#QuoteReformat()
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>Q'
      \ . '|xunmap <buffer> <LocalLeader>Q'

" Maps using autoloaded function for quoted paragraph movement
nnoremap <buffer> <silent> <LocalLeader>[
      \ :<C-U>call mail#NewBlank(v:count1, 1, 0)<CR>
nnoremap <buffer> <silent> <LocalLeader>]
      \ :<C-U>call mail#NewBlank(v:count1, 0, 0)<CR>
onoremap <buffer> <silent> <LocalLeader>[
      \ :<C-U>call mail#NewBlank(v:count1, 1, 0)<CR>
onoremap <buffer> <silent> <LocalLeader>]
      \ :<C-U>call mail#NewBlank(v:count1, 0, 0)<CR>
xnoremap <buffer> <silent> <LocalLeader>[
      \ :<C-U>call mail#NewBlank(v:count1, 1, 1)<CR>
xnoremap <buffer> <silent> <LocalLeader>]
      \ :<C-U>call mail#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>]'