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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
" Autoloads for Vim extline plugin.
if exists("g:autoloaded_extline")
finish
endif
let g:autoloaded_extline = 1
" Save 'cpoptions' and set Vim default to enable line continuations.
let s:save_cpoptions = &cpoptions
set cpoptions&vim
function! extline#lstrip(s)
return substitute(a:s, '^\s*', '', '')
endfunction
function! extline#rstrip(s)
return substitute(a:s, '\s*$', '', '')
endfunction
function! extline#strip(s)
return extline#lstrip(extline#rstrip(a:s))
endfunction
function! extline#leadingWhitespace(s)
return substitute(a:s, '^\s*\zs\(.*\)$', '', '')
endfunction
function! extline#getMonochar(s)
let monochar = substitute(extline#strip(a:s), '^\(\S\)\1*$', '\1', '')
if len(monochar) > 1
let monochar = ''
endif
return monochar
endfunction
" Return monochar that is non-alphanumeric.
function! extline#getPuncMonochar(s)
let monochar = extline#getMonochar(a:s)
if match(monochar, '[:alnum:]') >= 0
let monochar = ''
endif
return monochar
endfunction
function! extline#firstNonEmpty(strings)
for s in a:strings
if s != ''
return s
endif
endfor
return a:strings[0]
endfunction
function! extline#probeTitle(titleLineNum)
let titleText = getline(a:titleLineNum)
let title = extline#strip(titleText)
let titlePrefix = extline#leadingWhitespace(titleText)
if extline#getPuncMonochar(title) != ''
" Title cannot be a line of monochar punctuation characters.
let title = ''
endif
" Title Group
let tg = {
\ 'titleLineNum': a:titleLineNum,
\ 'title': title,
\ 'titlePrefix': titlePrefix,
\ 'overChar': '',
\ 'underChar': '',
\ }
if title != ''
" Consider non-existing line numbers.
let overText = extline#strip(getline(a:titleLineNum - 1))
let underText = extline#strip(getline(a:titleLineNum + 1))
let tg['overChar'] = extline#getPuncMonochar(overText)
let tg['underChar'] = extline#getPuncMonochar(underText)
endif
return tg
endfunction
function! extline#probeTitleNearby()
let lineNum = line('.')
let text = extline#strip(getline(lineNum))
let monochar = extline#getPuncMonochar(text)
if text == '' || monochar != ''
let tg = extline#probeTitle(lineNum - 1)
if tg['title'] == ''
let tg = extline#probeTitle(lineNum + 1)
endif
else
let tg = extline#probeTitle(lineNum)
endif
return tg
endfunction
function! extline#changeTitleLine(tg, lineType, lineTypePresent)
" lineType is 'over' or 'under'
" lineTypePresent is 1 or 0 to use or not use lineType.
let charType = a:lineType . 'Char'
if a:lineTypePresent && a:tg[charType] == ''
if charType == 'overChar'
let otherCharType = 'underChar'
exe a:tg['titleLineNum'] . 'copy ' . (a:tg['titleLineNum'] - 1)
let a:tg['titleLineNum'] = (a:tg['titleLineNum'] + 1)
else
let otherCharType = 'overChar'
exe a:tg['titleLineNum'] . 'copy ' . a:tg['titleLineNum']
endif
let a:tg[charType] = a:tg[otherCharType]
if a:tg[charType] == ''
let a:tg[charType] = '='
endif
endif
if !a:lineTypePresent && a:tg[charType] != ''
if charType == 'overChar'
exe (a:tg['titleLineNum'] - 1) . 'del'
let a:tg['titleLineNum'] = (a:tg['titleLineNum'] - 1)
else
exe (a:tg['titleLineNum'] + 1) . 'del'
endif
let a:tg[charType] = ''
endif
endfunction
function! extline#updateTitle(tg)
let titleLineNum = a:tg['titleLineNum']
let titleLen = len(a:tg['title'])
let underChar = a:tg['underChar']
let overChar = a:tg['overChar']
let titlePrefix = a:tg['titlePrefix']
if overChar != ''
let lineText = titlePrefix . repeat(overChar, titleLen)
exe (titleLineNum - 1) . 's/^.*/\=lineText/g'
endif
exe titleLineNum
normal! $
if underChar != ''
let lineText = titlePrefix . repeat(underChar, titleLen)
exe (titleLineNum + 1) . 's/^.*/\=lineText/g'
normal! $
endif
endfunction
function! extline#makeTitle(forceMonochar, useOver, useUnder)
let tg = extline#probeTitleNearby()
if tg['title'] != ''
" Always add a line before removing the other line.
if a:useOver
call extline#changeTitleLine(tg, 'over', a:useOver)
call extline#changeTitleLine(tg, 'under', a:useUnder)
else
call extline#changeTitleLine(tg, 'under', a:useUnder)
call extline#changeTitleLine(tg, 'over', a:useOver)
endif
if a:forceMonochar != ''
if a:useOver
let tg['overChar'] = a:forceMonochar
endif
if a:useUnder
let tg['underChar'] = a:forceMonochar
endif
endif
call extline#updateTitle(tg)
endif
return tg['title'] != ''
endfunction
function! extline#makeHline()
let lineNum = line('.')
let t = extline#rstrip(getline(lineNum))
let monochar = extline#getMonochar(t)
if monochar != ''
let lineText = (t . repeat(monochar, 80))[:77]
exe 's/^.*/' . escape(lineText, '/') . '/g'
normal! $
endif
endfunction
function! extline#autoTitle()
let tg = extline#probeTitleNearby()
if tg['title'] != ''
if tg['overChar'] == '' && tg['underChar'] == ''
if tg['titleLineNum'] > line(".")
" Title was after cursor line, use overTitle.
call extline#changeTitleLine(tg, 'over', 1)
else
call extline#changeTitleLine(tg, 'under', 1)
endif
endif
call extline#updateTitle(tg)
else
call extline#makeHline()
endif
endfunction
|