utils 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. data/Rakefile +68 -0
  2. data/VERSION +1 -0
  3. data/bin/chroot-exec +12 -0
  4. data/bin/chroot-libs +18 -0
  5. data/bin/classify +37 -0
  6. data/bin/discover +137 -0
  7. data/bin/edit +74 -0
  8. data/bin/errf +32 -0
  9. data/bin/git-empty +8 -0
  10. data/bin/myex +90 -0
  11. data/bin/number_files +26 -0
  12. data/bin/same_files +37 -0
  13. data/bin/search +205 -0
  14. data/bin/sedit +3 -0
  15. data/bin/sshscreen +68 -0
  16. data/bin/term +21 -0
  17. data/bin/unquarantine_apps +8 -0
  18. data/bin/untest +17 -0
  19. data/bin/utils-install-config +10 -0
  20. data/bin/vacuum_firefox_sqlite +22 -0
  21. data/bin/xmp +74 -0
  22. data/lib/utils.rb +8 -0
  23. data/lib/utils/config.rb +23 -0
  24. data/lib/utils/config/gdb/asm +179 -0
  25. data/lib/utils/config/gdb/ruby +528 -0
  26. data/lib/utils/config/gdbinit +8 -0
  27. data/lib/utils/config/irbrc +455 -0
  28. data/lib/utils/config/rdebugrc +2 -0
  29. data/lib/utils/config/screenrc +143 -0
  30. data/lib/utils/config/vim/autoload/Align.vim +1029 -0
  31. data/lib/utils/config/vim/autoload/AlignMaps.vim +330 -0
  32. data/lib/utils/config/vim/autoload/rails.vim +4744 -0
  33. data/lib/utils/config/vim/autoload/rubycomplete.vim +801 -0
  34. data/lib/utils/config/vim/autoload/sqlcomplete.vim +741 -0
  35. data/lib/utils/config/vim/autoload/vimball.vim +750 -0
  36. data/lib/utils/config/vim/colors/flori.vim +113 -0
  37. data/lib/utils/config/vim/compiler/eruby.vim +40 -0
  38. data/lib/utils/config/vim/compiler/ruby.vim +67 -0
  39. data/lib/utils/config/vim/compiler/rubyunit.vim +34 -0
  40. data/lib/utils/config/vim/ftdetect/ragel.vim +2 -0
  41. data/lib/utils/config/vim/ftdetect/ruby.vim +17 -0
  42. data/lib/utils/config/vim/ftplugin/eruby.vim +100 -0
  43. data/lib/utils/config/vim/ftplugin/ruby.vim +260 -0
  44. data/lib/utils/config/vim/ftplugin/xml.vim +941 -0
  45. data/lib/utils/config/vim/indent/IndentAnything_html.vim +35 -0
  46. data/lib/utils/config/vim/indent/eruby.vim +77 -0
  47. data/lib/utils/config/vim/indent/javascript.vim +116 -0
  48. data/lib/utils/config/vim/indent/ruby.vim +377 -0
  49. data/lib/utils/config/vim/plugin/AlignMapsPlugin.vim +242 -0
  50. data/lib/utils/config/vim/plugin/AlignPlugin.vim +41 -0
  51. data/lib/utils/config/vim/plugin/Decho.vim +592 -0
  52. data/lib/utils/config/vim/plugin/IndentAnything.vim +675 -0
  53. data/lib/utils/config/vim/plugin/bufexplorer.vim +1144 -0
  54. data/lib/utils/config/vim/plugin/cecutil.vim +482 -0
  55. data/lib/utils/config/vim/plugin/fugitive.vim +1703 -0
  56. data/lib/utils/config/vim/plugin/lusty-explorer.vim +1509 -0
  57. data/lib/utils/config/vim/plugin/rails.vim +340 -0
  58. data/lib/utils/config/vim/plugin/rubyextra.vim +193 -0
  59. data/lib/utils/config/vim/plugin/surround.vim +628 -0
  60. data/lib/utils/config/vim/plugin/taglist.vim +4546 -0
  61. data/lib/utils/config/vim/plugin/test/IndentAnything/test.js +131 -0
  62. data/lib/utils/config/vim/plugin/vimballPlugin.vim +40 -0
  63. data/lib/utils/config/vim/syntax/Decho.vim +101 -0
  64. data/lib/utils/config/vim/syntax/eruby.vim +73 -0
  65. data/lib/utils/config/vim/syntax/javascript.vim +246 -0
  66. data/lib/utils/config/vim/syntax/ragel.vim +165 -0
  67. data/lib/utils/config/vim/syntax/ruby.vim +367 -0
  68. data/lib/utils/config/vimrc +461 -0
  69. data/lib/utils/file.rb +49 -0
  70. data/lib/utils/find.rb +54 -0
  71. data/lib/utils/md5.rb +23 -0
  72. data/lib/utils/patterns.rb +34 -0
  73. data/lib/utils/version.rb +8 -0
  74. data/utils.gemspec +33 -0
  75. metadata +183 -0
@@ -0,0 +1,2 @@
1
+ set autolist
2
+ set autoreload
@@ -0,0 +1,143 @@
1
+ #
2
+ # Example of a user's .screenrc file
3
+ #
4
+
5
+ # This is how one can set a reattach password:
6
+ # password ODSJQf.4IJN7E # "1234"
7
+
8
+ # no annoying audible bell, please
9
+ vbell on
10
+
11
+ # detach on hangup
12
+ autodetach on
13
+
14
+ # don't display the copyright page
15
+ startup_message off
16
+
17
+ # emulate .logout message
18
+ pow_detach_msg "Screen session of \$LOGNAME \$:cr:\$:nl:ended."
19
+
20
+ # advertise hardstatus support to $TERMCAP
21
+ # termcapinfo * '' 'hs:ts=\E_:fs=\E\\:ds=\E_\E\\'
22
+
23
+ # make the shell in every window a login shell
24
+ #shell -$SHELL
25
+ shell -$SHELL
26
+
27
+ # autoaka testing
28
+ # shellaka '> |tcsh'
29
+ # shellaka '$ |sh'
30
+
31
+ # set every new windows hardstatus line to somenthing descriptive
32
+ # defhstatus "screen: ^En (^Et)"
33
+
34
+ defscrollback 1000
35
+
36
+ # don't kill window after the process died
37
+ # zombie "^["
38
+
39
+ ################
40
+ #
41
+ # xterm tweaks
42
+ #
43
+
44
+ #xterm understands both im/ic and doesn't have a status line.
45
+ #Note: Do not specify im and ic in the real termcap/info file as
46
+ #some programs (e.g. vi) will not work anymore.
47
+ termcap xterm hs@:cs=\E[%i%d;%dr:im=\E[4h:ei=\E[4l
48
+ terminfo xterm hs@:cs=\E[%i%p1%d;%p2%dr:im=\E[4h:ei=\E[4l
49
+
50
+ #80/132 column switching must be enabled for ^AW to work
51
+ #change init sequence to not switch width
52
+ termcapinfo xterm Z0=\E[?3h:Z1=\E[?3l:is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l
53
+
54
+ # Make the output buffer large for (fast) xterms.
55
+ termcapinfo xterm* OL=10000
56
+
57
+ # tell screen that xterm can switch to dark background and has function
58
+ # keys.
59
+ termcapinfo xterm 'VR=\E[?5h:VN=\E[?5l'
60
+ termcapinfo xterm 'k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~'
61
+ termcapinfo xterm 'kh=\E[1~:kI=\E[2~:kD=\E[3~:kH=\E[4~:kP=\E[H:kN=\E[6~'
62
+
63
+ # special xterm hardstatus: use the window title.
64
+ termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007'
65
+
66
+ #terminfo xterm 'vb=\E[?5h$<200/>\E[?5l'
67
+ termcapinfo xterm 'vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l'
68
+
69
+ # emulate part of the 'K' charset
70
+ termcapinfo xterm 'XC=K%,%\E(B,[\304,\\\\\326,]\334,{\344,|\366,}\374,~\337'
71
+
72
+ # xterm-52 tweaks:
73
+ # - uses background color for delete operations
74
+ termcapinfo xterm ut
75
+
76
+ ################
77
+ #
78
+ # wyse terminals
79
+ #
80
+
81
+ #wyse-75-42 must have flow control (xo = "terminal uses xon/xoff")
82
+ #essential to have it here, as this is a slow terminal.
83
+ termcapinfo wy75-42 xo:hs@
84
+
85
+ # New termcap sequences for cursor application mode.
86
+ termcapinfo wy* CS=\E[?1h:CE=\E[?1l:vi=\E[?25l:ve=\E[?25h:VR=\E[?5h:VN=\E[?5l:cb=\E[1K:CD=\E[1J
87
+
88
+ ################
89
+ #
90
+ # other terminals
91
+ #
92
+
93
+ #make hp700 termcap/info better
94
+ termcapinfo hp700 'Z0=\E[?3h:Z1=\E[?3l:hs:ts=\E[62"p\E[0$~\E[2$~\E[1$}:fs=\E[0}\E[61"p:ds=\E[62"p\E[1$~\E[61"p:ic@'
95
+
96
+ # Extend the vt100 desciption by some sequences.
97
+ termcap vt100* ms:AL=\E[%dL:DL=\E[%dM:UP=\E[%dA:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC
98
+ terminfo vt100* ms:AL=\E[%p1%dL:DL=\E[%p1%dM:UP=\E[%p1%dA:DO=\E[%p1%dB:LE=\E[%p1%dD:RI=\E[%p1%dC
99
+
100
+
101
+ ################
102
+ #
103
+ # keybindings
104
+ #
105
+
106
+ #remove some stupid / dangerous key bindings
107
+ bind k
108
+ bind ^k
109
+ bind .
110
+ bind ^\
111
+ bind \\
112
+ bind ^h
113
+ bind h
114
+ #make them better
115
+ bind 'K' kill
116
+ bind 'I' login on
117
+ bind 'O' login off
118
+ bind '}' history
119
+
120
+ # Yet another hack:
121
+ # Prepend/append register [/] to the paste if ^a^] is pressed.
122
+ # This lets me have autoindent mode in vi.
123
+ register [ "\033:se noai\015a"
124
+ register ] "\033:se ai\015a"
125
+ bind ^] paste [.]
126
+
127
+ ################
128
+ #
129
+ # default windows
130
+ #
131
+
132
+ # screen -t local 0
133
+ # screen -t mail 1 elm
134
+ # screen -t 40 2 rlogin faui40
135
+
136
+ # caption always "%3n %t%? @%u%?%? [%h]%?"
137
+ # hardstatus alwaysignore
138
+ # hardstatus alwayslastline "%w"
139
+
140
+ hardstatus on
141
+ hardstatus alwayslastline
142
+ hardstatus string "%{.bw}%-w%{.wr}%n %t%{-}%+w %=%{..g} %H %{..y}%l"
143
+
@@ -0,0 +1,1029 @@
1
+ " Align: tool to align multiple fields based on one or more separators
2
+ " Author: Charles E. Campbell, Jr.
3
+ " Date: Mar 03, 2009
4
+ " Version: 35
5
+ " GetLatestVimScripts: 294 1 :AutoInstall: Align.vim
6
+ " GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim
7
+ " Copyright: Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{1
8
+ " Permission is hereby granted to use and distribute this code,
9
+ " with or without modifications, provided that this copyright
10
+ " notice is copied with it. Like anything else that's free,
11
+ " Align.vim is provided *as is* and comes with no warranty
12
+ " of any kind, either expressed or implied. By using this
13
+ " plugin, you agree that in no event will the copyright
14
+ " holder be liable for any damages resulting from the use
15
+ " of this software.
16
+ "
17
+ " Romans 1:16,17a : For I am not ashamed of the gospel of Christ, for it is {{{1
18
+ " the power of God for salvation for everyone who believes; for the Jew first,
19
+ " and also for the Greek. For in it is revealed God's righteousness from
20
+ " faith to faith.
21
+
22
+ " ---------------------------------------------------------------------
23
+ " Load Once: {{{1
24
+ if exists("g:loaded_Align") || &cp
25
+ finish
26
+ endif
27
+ let g:loaded_Align = "v35"
28
+ if v:version < 700
29
+ echohl WarningMsg
30
+ echo "***warning*** this version of Align needs vim 7.0"
31
+ echohl Normal
32
+ finish
33
+ endif
34
+ let s:keepcpo= &cpo
35
+ set cpo&vim
36
+ "DechoTabOn
37
+
38
+ " ---------------------------------------------------------------------
39
+ " Debugging Support: {{{1
40
+ "if !exists("g:loaded_Decho") | runtime plugin/Decho.vim | endif
41
+
42
+ " ---------------------------------------------------------------------
43
+ " Options: {{{1
44
+ if !exists("g:Align_xstrlen")
45
+ if &enc == "latin1" || $LANG == "en_US.UTF-8" || !has("multi_byte")
46
+ let g:Align_xstrlen= 0
47
+ else
48
+ let g:Align_xstrlen= 1
49
+ endif
50
+ endif
51
+
52
+ " ---------------------------------------------------------------------
53
+ " Align#AlignCtrl: enter alignment patterns here {{{1
54
+ "
55
+ " Styles = all alignment-break patterns are equivalent
56
+ " C cycle through alignment-break pattern(s)
57
+ " l left-justified alignment
58
+ " r right-justified alignment
59
+ " c center alignment
60
+ " - skip separator, treat as part of field
61
+ " : treat rest of line as field
62
+ " + repeat previous [lrc] style
63
+ " < left justify separators
64
+ " > right justify separators
65
+ " | center separators
66
+ "
67
+ " Builds = s:AlignPat s:AlignCtrl s:AlignPatQty
68
+ " C s:AlignPat s:AlignCtrl s:AlignPatQty
69
+ " p s:AlignPrePad
70
+ " P s:AlignPostPad
71
+ " w s:AlignLeadKeep
72
+ " W s:AlignLeadKeep
73
+ " I s:AlignLeadKeep
74
+ " l s:AlignStyle
75
+ " r s:AlignStyle
76
+ " - s:AlignStyle
77
+ " + s:AlignStyle
78
+ " : s:AlignStyle
79
+ " c s:AlignStyle
80
+ " g s:AlignGPat
81
+ " v s:AlignVPat
82
+ " < s:AlignSep
83
+ " > s:AlignSep
84
+ " | s:AlignSep
85
+ fun! Align#AlignCtrl(...)
86
+
87
+ " call Dfunc("AlignCtrl(...) a:0=".a:0)
88
+
89
+ " save options that will be changed
90
+ let keep_search = @/
91
+ let keep_ic = &ic
92
+
93
+ " turn ignorecase off
94
+ set noic
95
+
96
+ " clear visual mode so that old visual-mode selections don't
97
+ " get applied to new invocations of Align().
98
+ if v:version < 602
99
+ if !exists("s:Align_gavemsg")
100
+ let s:Align_gavemsg= 1
101
+ echomsg "Align needs at least Vim version 6.2 to clear visual-mode selection"
102
+ endif
103
+ elseif exists("s:dovisclear")
104
+ " call Decho("clearing visual mode a:0=".a:0." a:1<".a:1.">")
105
+ let clearvmode= visualmode(1)
106
+ endif
107
+
108
+ " set up a list akin to an argument list
109
+ if a:0 > 0
110
+ let A= s:QArgSplitter(a:1)
111
+ else
112
+ let A=[0]
113
+ endif
114
+
115
+ if A[0] > 0
116
+ let style = A[1]
117
+
118
+ " Check for bad separator patterns (zero-length matches)
119
+ " (but zero-length patterns for g/v is ok)
120
+ if style !~# '[gv]'
121
+ let ipat= 2
122
+ while ipat <= A[0]
123
+ if "" =~ A[ipat]
124
+ echoerr "AlignCtrl: separator<".A[ipat]."> matches zero-length string"
125
+ let &ic= keep_ic
126
+ " call Dret("AlignCtrl")
127
+ return
128
+ endif
129
+ let ipat= ipat + 1
130
+ endwhile
131
+ endif
132
+ endif
133
+
134
+ " call Decho("AlignCtrl() A[0]=".A[0])
135
+ if !exists("s:AlignStyle")
136
+ let s:AlignStyle= "l"
137
+ endif
138
+ if !exists("s:AlignPrePad")
139
+ let s:AlignPrePad= 0
140
+ endif
141
+ if !exists("s:AlignPostPad")
142
+ let s:AlignPostPad= 0
143
+ endif
144
+ if !exists("s:AlignLeadKeep")
145
+ let s:AlignLeadKeep= 'w'
146
+ endif
147
+
148
+ if A[0] == 0
149
+ " ----------------------
150
+ " List current selection
151
+ " ----------------------
152
+ if !exists("s:AlignPatQty")
153
+ let s:AlignPatQty= 0
154
+ endif
155
+ echo "AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep
156
+ " call Decho("AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep)
157
+ if exists("s:AlignGPat") && !exists("s:AlignVPat")
158
+ echo "AlignGPat<".s:AlignGPat.">"
159
+ elseif !exists("s:AlignGPat") && exists("s:AlignVPat")
160
+ echo "AlignVPat<".s:AlignVPat.">"
161
+ elseif exists("s:AlignGPat") && exists("s:AlignVPat")
162
+ echo "AlignGPat<".s:AlignGPat."> AlignVPat<".s:AlignVPat.">"
163
+ endif
164
+ let ipat= 1
165
+ while ipat <= s:AlignPatQty
166
+ echo "Pat".ipat."<".s:AlignPat_{ipat}.">"
167
+ " call Decho("Pat".ipat."<".s:AlignPat_{ipat}.">")
168
+ let ipat= ipat + 1
169
+ endwhile
170
+
171
+ else
172
+ " ----------------------------------
173
+ " Process alignment control settings
174
+ " ----------------------------------
175
+ " call Decho("process the alignctrl settings")
176
+ " call Decho("style<".style.">")
177
+
178
+ if style ==? "default"
179
+ " Default: preserve initial leading whitespace, left-justified,
180
+ " alignment on '=', one space padding on both sides
181
+ if exists("s:AlignCtrlStackQty")
182
+ " clear AlignCtrl stack
183
+ while s:AlignCtrlStackQty > 0
184
+ call Align#AlignPop()
185
+ endwhile
186
+ unlet s:AlignCtrlStackQty
187
+ endif
188
+ " Set AlignCtrl to its default value
189
+ call Align#AlignCtrl("Ilp1P1=<",'=')
190
+ call Align#AlignCtrl("g")
191
+ call Align#AlignCtrl("v")
192
+ let s:dovisclear = 1
193
+ let &ic = keep_ic
194
+ let @/ = keep_search
195
+ " call Dret("AlignCtrl")
196
+ return
197
+ endif
198
+
199
+ if style =~# 'm'
200
+ " map support: Do an AlignPush now and the next call to Align()
201
+ " will do an AlignPop at exit
202
+ " call Decho("style case m: do AlignPush")
203
+ call Align#AlignPush()
204
+ let s:DoAlignPop= 1
205
+ endif
206
+
207
+ " = : record a list of alignment patterns that are equivalent
208
+ if style =~# "="
209
+ " call Decho("style case =: record list of equiv alignment patterns")
210
+ let s:AlignCtrl = '='
211
+ if A[0] >= 2
212
+ let s:AlignPatQty= 1
213
+ let s:AlignPat_1 = A[2]
214
+ let ipat = 3
215
+ while ipat <= A[0]
216
+ let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat]
217
+ let ipat = ipat + 1
218
+ endwhile
219
+ let s:AlignPat_1= '\('.s:AlignPat_1.'\)'
220
+ " call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">")
221
+ endif
222
+
223
+ "c : cycle through alignment pattern(s)
224
+ elseif style =~# 'C'
225
+ " call Decho("style case C: cycle through alignment pattern(s)")
226
+ let s:AlignCtrl = 'C'
227
+ if A[0] >= 2
228
+ let s:AlignPatQty= A[0] - 1
229
+ let ipat = 1
230
+ while ipat < A[0]
231
+ let s:AlignPat_{ipat}= A[ipat+1]
232
+ " call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">")
233
+ let ipat= ipat + 1
234
+ endwhile
235
+ endif
236
+ endif
237
+
238
+ if style =~# 'p'
239
+ let s:AlignPrePad= substitute(style,'^.*p\(\d\+\).*$','\1','')
240
+ " call Decho("style case p".s:AlignPrePad.": pre-separator padding")
241
+ if s:AlignPrePad == ""
242
+ echoerr "AlignCtrl: 'p' needs to be followed by a numeric argument'
243
+ let @/ = keep_search
244
+ let &ic= keep_ic
245
+ " call Dret("AlignCtrl")
246
+ return
247
+ endif
248
+ endif
249
+
250
+ if style =~# 'P'
251
+ let s:AlignPostPad= substitute(style,'^.*P\(\d\+\).*$','\1','')
252
+ " call Decho("style case P".s:AlignPostPad.": post-separator padding")
253
+ if s:AlignPostPad == ""
254
+ echoerr "AlignCtrl: 'P' needs to be followed by a numeric argument'
255
+ let @/ = keep_search
256
+ let &ic= keep_ic
257
+ " call Dret("AlignCtrl")
258
+ return
259
+ endif
260
+ endif
261
+
262
+ if style =~# 'w'
263
+ " call Decho("style case w: ignore leading whitespace")
264
+ let s:AlignLeadKeep= 'w'
265
+ elseif style =~# 'W'
266
+ " call Decho("style case w: keep leading whitespace")
267
+ let s:AlignLeadKeep= 'W'
268
+ elseif style =~# 'I'
269
+ " call Decho("style case w: retain initial leading whitespace")
270
+ let s:AlignLeadKeep= 'I'
271
+ endif
272
+
273
+ if style =~# 'g'
274
+ " first list item is a "g" selector pattern
275
+ " call Decho("style case g: global selector pattern")
276
+ if A[0] < 2
277
+ if exists("s:AlignGPat")
278
+ unlet s:AlignGPat
279
+ " call Decho("unlet s:AlignGPat")
280
+ endif
281
+ else
282
+ let s:AlignGPat= A[2]
283
+ " call Decho("s:AlignGPat<".s:AlignGPat.">")
284
+ endif
285
+ elseif style =~# 'v'
286
+ " first list item is a "v" selector pattern
287
+ " call Decho("style case v: global selector anti-pattern")
288
+ if A[0] < 2
289
+ if exists("s:AlignVPat")
290
+ unlet s:AlignVPat
291
+ " call Decho("unlet s:AlignVPat")
292
+ endif
293
+ else
294
+ let s:AlignVPat= A[2]
295
+ " call Decho("s:AlignVPat<".s:AlignVPat.">")
296
+ endif
297
+ endif
298
+
299
+ "[-lrc+:] : set up s:AlignStyle
300
+ if style =~# '[-lrc+:]'
301
+ " call Decho("style case [-lrc+:]: field justification")
302
+ let s:AlignStyle= substitute(style,'[^-lrc:+]','','g')
303
+ " call Decho("AlignStyle<".s:AlignStyle.">")
304
+ endif
305
+
306
+ "[<>|] : set up s:AlignSep
307
+ if style =~# '[<>|]'
308
+ " call Decho("style case [-lrc+:]: separator justification")
309
+ let s:AlignSep= substitute(style,'[^<>|]','','g')
310
+ " call Decho("AlignSep ".s:AlignSep)
311
+ endif
312
+ endif
313
+
314
+ " sanity
315
+ if !exists("s:AlignCtrl")
316
+ let s:AlignCtrl= '='
317
+ endif
318
+
319
+ " restore search and options
320
+ let @/ = keep_search
321
+ let &ic= keep_ic
322
+
323
+ " call Dret("AlignCtrl ".s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle)
324
+ return s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle
325
+ endfun
326
+
327
+ " ---------------------------------------------------------------------
328
+ " s:MakeSpace: returns a string with spacecnt blanks {{{1
329
+ fun! s:MakeSpace(spacecnt)
330
+ " call Dfunc("MakeSpace(spacecnt=".a:spacecnt.")")
331
+ let str = ""
332
+ let spacecnt = a:spacecnt
333
+ while spacecnt > 0
334
+ let str = str . " "
335
+ let spacecnt = spacecnt - 1
336
+ endwhile
337
+ " call Dret("MakeSpace <".str.">")
338
+ return str
339
+ endfun
340
+
341
+ " ---------------------------------------------------------------------
342
+ " Align#Align: align selected text based on alignment pattern(s) {{{1
343
+ fun! Align#Align(hasctrl,...) range
344
+ " call Dfunc("Align#Align(hasctrl=".a:hasctrl.",...) a:0=".a:0)
345
+
346
+ " sanity checks
347
+ if string(a:hasctrl) != "0" && string(a:hasctrl) != "1"
348
+ echohl Error|echo 'usage: Align#Align(hasctrl<'.a:hasctrl.'> (should be 0 or 1),"separator(s)" (you have '.a:0.') )'|echohl None
349
+ " call Dret("Align#Align")
350
+ return
351
+ endif
352
+ if exists("s:AlignStyle") && s:AlignStyle == ":"
353
+ echohl Error |echo '(Align#Align) your AlignStyle is ":", which implies "do-no-alignment"!'|echohl None
354
+ " call Dret("Align#Align")
355
+ return
356
+ endif
357
+
358
+ " set up a list akin to an argument list
359
+ if a:0 > 0
360
+ let A= s:QArgSplitter(a:1)
361
+ else
362
+ let A=[0]
363
+ endif
364
+
365
+ " if :Align! was used, then the first argument is (should be!) an AlignCtrl string
366
+ " Note that any alignment control set this way will be temporary.
367
+ let hasctrl= a:hasctrl
368
+ " call Decho("hasctrl=".hasctrl)
369
+ if a:hasctrl && A[0] >= 1
370
+ " call Decho("Align! : using A[1]<".A[1]."> for AlignCtrl")
371
+ if A[1] =~ '[gv]'
372
+ let hasctrl= hasctrl + 1
373
+ call Align#AlignCtrl('m')
374
+ call Align#AlignCtrl(A[1],A[2])
375
+ " call Decho("Align! : also using A[2]<".A[2]."> for AlignCtrl")
376
+ elseif A[1] !~ 'm'
377
+ call Align#AlignCtrl(A[1]."m")
378
+ else
379
+ call Align#AlignCtrl(A[1])
380
+ endif
381
+ endif
382
+
383
+ " Check for bad separator patterns (zero-length matches)
384
+ let ipat= 1 + hasctrl
385
+ while ipat <= A[0]
386
+ if "" =~ A[ipat]
387
+ echoerr "Align: separator<".A[ipat]."> matches zero-length string"
388
+ " call Dret("Align#Align")
389
+ return
390
+ endif
391
+ let ipat= ipat + 1
392
+ endwhile
393
+
394
+ " record current search pattern for subsequent restoration
395
+ let keep_search= @/
396
+ let keep_ic = &ic
397
+ let keep_report= &report
398
+ set noic report=10000
399
+
400
+ if A[0] > hasctrl
401
+ " Align will accept a list of separator regexps
402
+ " call Decho("A[0]=".A[0].": accepting list of separator regexp")
403
+
404
+ if s:AlignCtrl =~# "="
405
+ "= : consider all separators to be equivalent
406
+ " call Decho("AlignCtrl: record list of equivalent alignment patterns")
407
+ let s:AlignCtrl = '='
408
+ let s:AlignPat_1 = A[1 + hasctrl]
409
+ let s:AlignPatQty= 1
410
+ let ipat = 2 + hasctrl
411
+ while ipat <= A[0]
412
+ let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat]
413
+ let ipat = ipat + 1
414
+ endwhile
415
+ let s:AlignPat_1= '\('.s:AlignPat_1.'\)'
416
+ " call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">")
417
+
418
+ elseif s:AlignCtrl =~# 'C'
419
+ "c : cycle through alignment pattern(s)
420
+ " call Decho("AlignCtrl: cycle through alignment pattern(s)")
421
+ let s:AlignCtrl = 'C'
422
+ let s:AlignPatQty= A[0] - hasctrl
423
+ let ipat = 1
424
+ while ipat <= s:AlignPatQty
425
+ let s:AlignPat_{ipat}= A[(ipat + hasctrl)]
426
+ " call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">")
427
+ let ipat= ipat + 1
428
+ endwhile
429
+ endif
430
+ endif
431
+
432
+ " Initialize so that begline<endline and begcol<endcol.
433
+ " Ragged right: check if the column associated with '< or '>
434
+ " is greater than the line's string length -> ragged right.
435
+ " Have to be careful about visualmode() -- it returns the last visual
436
+ " mode used whether or not it was used currently.
437
+ let begcol = virtcol("'<")-1
438
+ let endcol = virtcol("'>")-1
439
+ if begcol > endcol
440
+ let begcol = virtcol("'>")-1
441
+ let endcol = virtcol("'<")-1
442
+ endif
443
+ " call Decho("begcol=".begcol." endcol=".endcol)
444
+ let begline = a:firstline
445
+ let endline = a:lastline
446
+ if begline > endline
447
+ let begline = a:lastline
448
+ let endline = a:firstline
449
+ endif
450
+ " call Decho("begline=".begline." endline=".endline)
451
+ let fieldcnt = 0
452
+ if (begline == line("'>") && endline == line("'<")) || (begline == line("'<") && endline == line("'>"))
453
+ let vmode= visualmode()
454
+ " call Decho("vmode=".vmode)
455
+ if vmode == "\<c-v>"
456
+ if exists("g:Align_xstrlen") && g:Align_xstrlen
457
+ let ragged = ( col("'>") > s:Strlen(getline("'>")) || col("'<") > s:Strlen(getline("'<")) )
458
+ else
459
+ let ragged = ( col("'>") > strlen(getline("'>")) || col("'<") > strlen(getline("'<")) )
460
+ endif
461
+ else
462
+ let ragged= 1
463
+ endif
464
+ else
465
+ let ragged= 1
466
+ endif
467
+ if ragged
468
+ let begcol= 0
469
+ endif
470
+ " call Decho("lines[".begline.",".endline."] col[".begcol.",".endcol."] ragged=".ragged." AlignCtrl<".s:AlignCtrl.">")
471
+
472
+ " Keep user options
473
+ let etkeep = &l:et
474
+ let pastekeep= &l:paste
475
+ setlocal et paste
476
+
477
+ " convert selected range of lines to use spaces instead of tabs
478
+ " but if first line's initial white spaces are to be retained
479
+ " then use 'em
480
+ if begcol <= 0 && s:AlignLeadKeep == 'I'
481
+ " retain first leading whitespace for all subsequent lines
482
+ let bgntxt= substitute(getline(begline),'^\(\s*\).\{-}$','\1','')
483
+ " call Decho("retaining 1st leading whitespace: bgntxt<".bgntxt.">")
484
+ set noet
485
+ endif
486
+ exe begline.",".endline."ret"
487
+
488
+ " Execute two passes
489
+ " First pass: collect alignment data (max field sizes)
490
+ " Second pass: perform alignment
491
+ let pass= 1
492
+ while pass <= 2
493
+ " call Decho(" ")
494
+ " call Decho("---- Pass ".pass.": ----")
495
+
496
+ let line= begline
497
+ while line <= endline
498
+ " Process each line
499
+ let txt = getline(line)
500
+ " call Decho(" ")
501
+ " call Decho("Pass".pass.": Line ".line." <".txt.">")
502
+
503
+ " AlignGPat support: allows a selector pattern (akin to g/selector/cmd )
504
+ if exists("s:AlignGPat")
505
+ " call Decho("Pass".pass.": AlignGPat<".s:AlignGPat.">")
506
+ if match(txt,s:AlignGPat) == -1
507
+ " call Decho("Pass".pass.": skipping")
508
+ let line= line + 1
509
+ continue
510
+ endif
511
+ endif
512
+
513
+ " AlignVPat support: allows a selector pattern (akin to v/selector/cmd )
514
+ if exists("s:AlignVPat")
515
+ " call Decho("Pass".pass.": AlignVPat<".s:AlignVPat.">")
516
+ if match(txt,s:AlignVPat) != -1
517
+ " call Decho("Pass".pass.": skipping")
518
+ let line= line + 1
519
+ continue
520
+ endif
521
+ endif
522
+
523
+ " Always skip blank lines
524
+ if match(txt,'^\s*$') != -1
525
+ " call Decho("Pass".pass.": skipping")
526
+ let line= line + 1
527
+ continue
528
+ endif
529
+
530
+ " Extract visual-block selected text (init bgntxt, endtxt)
531
+ if exists("g:Align_xstrlen") && g:Align_xstrlen
532
+ let txtlen= s:Strlen(txt)
533
+ else
534
+ let txtlen= strlen(txt)
535
+ endif
536
+ if begcol > 0
537
+ " Record text to left of selected area
538
+ let bgntxt= strpart(txt,0,begcol)
539
+ " call Decho("Pass".pass.": record text to left: bgntxt<".bgntxt.">")
540
+ elseif s:AlignLeadKeep == 'W'
541
+ let bgntxt= substitute(txt,'^\(\s*\).\{-}$','\1','')
542
+ " call Decho("Pass".pass.": retaining all leading ws: bgntxt<".bgntxt.">")
543
+ elseif s:AlignLeadKeep == 'w' || !exists("bgntxt")
544
+ " No beginning text
545
+ let bgntxt= ""
546
+ " call Decho("Pass".pass.": no beginning text")
547
+ endif
548
+ if ragged
549
+ let endtxt= ""
550
+ else
551
+ " Elide any text lying outside selected columnar region
552
+ let endtxt= strpart(txt,endcol+1,txtlen-endcol)
553
+ let txt = strpart(txt,begcol,endcol-begcol+1)
554
+ endif
555
+ " call Decho(" ")
556
+ " call Decho("Pass".pass.": bgntxt<".bgntxt.">")
557
+ " call Decho("Pass".pass.": txt<". txt .">")
558
+ " call Decho("Pass".pass.": endtxt<".endtxt.">")
559
+ if !exists("s:AlignPat_{1}")
560
+ echohl Error|echo "no separators specified!"|echohl None
561
+ " call Dret("Align#Align")
562
+ return
563
+ endif
564
+
565
+ " Initialize for both passes
566
+ let seppat = s:AlignPat_{1}
567
+ let ifield = 1
568
+ let ipat = 1
569
+ let bgnfield = 0
570
+ let endfield = 0
571
+ let alignstyle = s:AlignStyle
572
+ let doend = 1
573
+ let newtxt = ""
574
+ let alignprepad = s:AlignPrePad
575
+ let alignpostpad= s:AlignPostPad
576
+ let alignsep = s:AlignSep
577
+ let alignophold = " "
578
+ let alignop = "l"
579
+ " call Decho("Pass".pass.": initial alignstyle<".alignstyle."> seppat<".seppat.">")
580
+
581
+ " Process each field on the line
582
+ while doend > 0
583
+
584
+ " C-style: cycle through pattern(s)
585
+ if s:AlignCtrl == 'C' && doend == 1
586
+ let seppat = s:AlignPat_{ipat}
587
+ " call Decho("Pass".pass.": processing field: AlignCtrl=".s:AlignCtrl." ipat=".ipat." seppat<".seppat.">")
588
+ let ipat = ipat + 1
589
+ if ipat > s:AlignPatQty
590
+ let ipat = 1
591
+ endif
592
+ endif
593
+
594
+ " cyclic alignment/justification operator handling
595
+ let alignophold = alignop
596
+ let alignop = strpart(alignstyle,0,1)
597
+ if alignop == '+' || doend == 2
598
+ let alignop= alignophold
599
+ else
600
+ let alignstyle = strpart(alignstyle,1).strpart(alignstyle,0,1)
601
+ let alignopnxt = strpart(alignstyle,0,1)
602
+ if alignop == ':'
603
+ let seppat = '$'
604
+ let doend = 2
605
+ " call Decho("Pass".pass.": alignop<:> case: setting seppat<$> doend==2")
606
+ endif
607
+ endif
608
+
609
+ " cylic separator alignment specification handling
610
+ let alignsepop= strpart(alignsep,0,1)
611
+ let alignsep = strpart(alignsep,1).alignsepop
612
+
613
+ " mark end-of-field and the subsequent end-of-separator.
614
+ " Extend field if alignop is '-'
615
+ let endfield = match(txt,seppat,bgnfield)
616
+ let sepfield = matchend(txt,seppat,bgnfield)
617
+ let skipfield= sepfield
618
+ " call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield)
619
+ while alignop == '-' && endfield != -1
620
+ let endfield = match(txt,seppat,skipfield)
621
+ let sepfield = matchend(txt,seppat,skipfield)
622
+ let skipfield = sepfield
623
+ let alignop = strpart(alignstyle,0,1)
624
+ let alignstyle= strpart(alignstyle,1).strpart(alignstyle,0,1)
625
+ " call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">")
626
+ endwhile
627
+ let seplen= sepfield - endfield
628
+ " call Decho("Pass".pass.": seplen=[sepfield=".sepfield."] - [endfield=".endfield."]=".seplen)
629
+
630
+ if endfield != -1
631
+ if pass == 1
632
+ " ---------------------------------------------------------------------
633
+ " Pass 1: Update FieldSize to max
634
+ " call Decho("Pass".pass.": before lead/trail remove: field<".strpart(txt,bgnfield,endfield-bgnfield).">")
635
+ let field = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','')
636
+ if s:AlignLeadKeep == 'W'
637
+ let field = bgntxt.field
638
+ let bgntxt= ""
639
+ endif
640
+ if exists("g:Align_xstrlen") && g:Align_xstrlen
641
+ let fieldlen = s:Strlen(field)
642
+ else
643
+ let fieldlen = strlen(field)
644
+ endif
645
+ let sFieldSize = "FieldSize_".ifield
646
+ if !exists(sFieldSize)
647
+ let FieldSize_{ifield}= fieldlen
648
+ " call Decho("Pass".pass.": set FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field.">")
649
+ elseif fieldlen > FieldSize_{ifield}
650
+ let FieldSize_{ifield}= fieldlen
651
+ " call Decho("Pass".pass.": oset FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field.">")
652
+ endif
653
+ let sSepSize= "SepSize_".ifield
654
+ if !exists(sSepSize)
655
+ let SepSize_{ifield}= seplen
656
+ " call Decho(" set SepSize_{".ifield."}=".SepSize_{ifield}." <".field.">")
657
+ elseif seplen > SepSize_{ifield}
658
+ let SepSize_{ifield}= seplen
659
+ " call Decho("Pass".pass.": oset SepSize_{".ifield."}=".SepSize_{ifield}." <".field.">")
660
+ endif
661
+
662
+ else
663
+ " ---------------------------------------------------------------------
664
+ " Pass 2: Perform Alignment
665
+ let prepad = strpart(alignprepad,0,1)
666
+ let postpad = strpart(alignpostpad,0,1)
667
+ let alignprepad = strpart(alignprepad,1).strpart(alignprepad,0,1)
668
+ let alignpostpad = strpart(alignpostpad,1).strpart(alignpostpad,0,1)
669
+ let field = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','')
670
+ if s:AlignLeadKeep == 'W'
671
+ let field = bgntxt.field
672
+ let bgntxt= ""
673
+ endif
674
+ if doend == 2
675
+ let prepad = 0
676
+ let postpad= 0
677
+ endif
678
+ if exists("g:Align_xstrlen") && g:Align_xstrlen
679
+ let fieldlen = s:Strlen(field)
680
+ else
681
+ let fieldlen = strlen(field)
682
+ endif
683
+ let sep = s:MakeSpace(prepad).strpart(txt,endfield,sepfield-endfield).s:MakeSpace(postpad)
684
+ if seplen < SepSize_{ifield}
685
+ if alignsepop == "<"
686
+ " left-justify separators
687
+ let sep = sep.s:MakeSpace(SepSize_{ifield}-seplen)
688
+ elseif alignsepop == ">"
689
+ " right-justify separators
690
+ let sep = s:MakeSpace(SepSize_{ifield}-seplen).sep
691
+ else
692
+ " center-justify separators
693
+ let sepleft = (SepSize_{ifield} - seplen)/2
694
+ let sepright = SepSize_{ifield} - seplen - sepleft
695
+ let sep = s:MakeSpace(sepleft).sep.s:MakeSpace(sepright)
696
+ endif
697
+ endif
698
+ let spaces = FieldSize_{ifield} - fieldlen
699
+ " call Decho("Pass".pass.": Field #".ifield."<".field."> spaces=".spaces." be[".bgnfield.",".endfield."] pad=".prepad.','.postpad." FS_".ifield."<".FieldSize_{ifield}."> sep<".sep."> ragged=".ragged." doend=".doend." alignop<".alignop.">")
700
+
701
+ " Perform alignment according to alignment style justification
702
+ if spaces > 0
703
+ if alignop == 'c'
704
+ " center the field
705
+ let spaceleft = spaces/2
706
+ let spaceright= FieldSize_{ifield} - spaceleft - fieldlen
707
+ let newtxt = newtxt.s:MakeSpace(spaceleft).field.s:MakeSpace(spaceright).sep
708
+ elseif alignop == 'r'
709
+ " right justify the field
710
+ let newtxt= newtxt.s:MakeSpace(spaces).field.sep
711
+ elseif ragged && doend == 2
712
+ " left justify rightmost field (no trailing blanks needed)
713
+ let newtxt= newtxt.field
714
+ else
715
+ " left justfiy the field
716
+ let newtxt= newtxt.field.s:MakeSpace(spaces).sep
717
+ endif
718
+ elseif ragged && doend == 2
719
+ " field at maximum field size and no trailing blanks needed
720
+ let newtxt= newtxt.field
721
+ else
722
+ " field is at maximum field size already
723
+ let newtxt= newtxt.field.sep
724
+ endif
725
+ " call Decho("Pass".pass.": newtxt<".newtxt.">")
726
+ endif " pass 1/2
727
+
728
+ " bgnfield indexes to end of separator at right of current field
729
+ " Update field counter
730
+ let bgnfield= sepfield
731
+ let ifield = ifield + 1
732
+ if doend == 2
733
+ let doend= 0
734
+ endif
735
+ " handle end-of-text as end-of-field
736
+ elseif doend == 1
737
+ let seppat = '$'
738
+ let doend = 2
739
+ else
740
+ let doend = 0
741
+ endif " endfield != -1
742
+ endwhile " doend loop (as well as regularly separated fields)
743
+
744
+ if pass == 2
745
+ " Write altered line to buffer
746
+ " call Decho("Pass".pass.": bgntxt<".bgntxt."> line=".line)
747
+ " call Decho("Pass".pass.": newtxt<".newtxt.">")
748
+ " call Decho("Pass".pass.": endtxt<".endtxt.">")
749
+ call setline(line,bgntxt.newtxt.endtxt)
750
+ endif
751
+
752
+ let line = line + 1
753
+ endwhile " line loop
754
+
755
+ let pass= pass + 1
756
+ endwhile " pass loop
757
+ " call Decho("end of two pass loop")
758
+
759
+ " Restore user options
760
+ let &l:et = etkeep
761
+ let &l:paste = pastekeep
762
+
763
+ if exists("s:DoAlignPop")
764
+ " AlignCtrl Map support
765
+ call Align#AlignPop()
766
+ unlet s:DoAlignPop
767
+ endif
768
+
769
+ " restore current search pattern
770
+ let @/ = keep_search
771
+ let &ic = keep_ic
772
+ let &report = keep_report
773
+
774
+ " call Dret("Align#Align")
775
+ return
776
+ endfun
777
+
778
+ " ---------------------------------------------------------------------
779
+ " Align#AlignPush: this command/function pushes an alignment control string onto a stack {{{1
780
+ fun! Align#AlignPush()
781
+ " call Dfunc("AlignPush()")
782
+
783
+ " initialize the stack
784
+ if !exists("s:AlignCtrlStackQty")
785
+ let s:AlignCtrlStackQty= 1
786
+ else
787
+ let s:AlignCtrlStackQty= s:AlignCtrlStackQty + 1
788
+ endif
789
+
790
+ " construct an AlignCtrlStack entry
791
+ if !exists("s:AlignSep")
792
+ let s:AlignSep= ''
793
+ endif
794
+ let s:AlignCtrlStack_{s:AlignCtrlStackQty}= s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle.s:AlignSep
795
+ " call Decho("AlignPush: AlignCtrlStack_".s:AlignCtrlStackQty."<".s:AlignCtrlStack_{s:AlignCtrlStackQty}.">")
796
+
797
+ " push [GV] patterns onto their own stack
798
+ if exists("s:AlignGPat")
799
+ let s:AlignGPat_{s:AlignCtrlStackQty}= s:AlignGPat
800
+ else
801
+ let s:AlignGPat_{s:AlignCtrlStackQty}= ""
802
+ endif
803
+ if exists("s:AlignVPat")
804
+ let s:AlignVPat_{s:AlignCtrlStackQty}= s:AlignVPat
805
+ else
806
+ let s:AlignVPat_{s:AlignCtrlStackQty}= ""
807
+ endif
808
+
809
+ " call Dret("AlignPush")
810
+ endfun
811
+
812
+ " ---------------------------------------------------------------------
813
+ " Align#AlignPop: this command/function pops an alignment pattern from a stack {{{1
814
+ " and into the AlignCtrl variables.
815
+ fun! Align#AlignPop()
816
+ " call Dfunc("Align#AlignPop()")
817
+
818
+ " sanity checks
819
+ if !exists("s:AlignCtrlStackQty")
820
+ echoerr "AlignPush needs to be used prior to AlignPop"
821
+ " call Dret("Align#AlignPop <> : AlignPush needs to have been called first")
822
+ return ""
823
+ endif
824
+ if s:AlignCtrlStackQty <= 0
825
+ unlet s:AlignCtrlStackQty
826
+ echoerr "AlignPush needs to be used prior to AlignPop"
827
+ " call Dret("Align#AlignPop <> : AlignPop needs to have been called first")
828
+ return ""
829
+ endif
830
+
831
+ " pop top of AlignCtrlStack and pass value to AlignCtrl
832
+ let retval=s:AlignCtrlStack_{s:AlignCtrlStackQty}
833
+ unlet s:AlignCtrlStack_{s:AlignCtrlStackQty}
834
+ call Align#AlignCtrl(retval)
835
+
836
+ " pop G pattern stack
837
+ if s:AlignGPat_{s:AlignCtrlStackQty} != ""
838
+ call Align#AlignCtrl('g',s:AlignGPat_{s:AlignCtrlStackQty})
839
+ else
840
+ call Align#AlignCtrl('g')
841
+ endif
842
+ unlet s:AlignGPat_{s:AlignCtrlStackQty}
843
+
844
+ " pop V pattern stack
845
+ if s:AlignVPat_{s:AlignCtrlStackQty} != ""
846
+ call Align#AlignCtrl('v',s:AlignVPat_{s:AlignCtrlStackQty})
847
+ else
848
+ call Align#AlignCtrl('v')
849
+ endif
850
+
851
+ unlet s:AlignVPat_{s:AlignCtrlStackQty}
852
+ let s:AlignCtrlStackQty= s:AlignCtrlStackQty - 1
853
+
854
+ " call Dret("Align#AlignPop <".retval."> : AlignCtrlStackQty=".s:AlignCtrlStackQty)
855
+ return retval
856
+ endfun
857
+
858
+ " ---------------------------------------------------------------------
859
+ " Align#AlignReplaceQuotedSpaces: {{{1
860
+ fun! Align#AlignReplaceQuotedSpaces()
861
+ " call Dfunc("AlignReplaceQuotedSpaces()")
862
+
863
+ let l:line = getline(line("."))
864
+ if exists("g:Align_xstrlen") && g:Align_xstrlen
865
+ let l:linelen = s:Strlen(l:line)
866
+ else
867
+ let l:linelen = strlen(l:line)
868
+ endif
869
+ let l:startingPos = 0
870
+ let l:startQuotePos = 0
871
+ let l:endQuotePos = 0
872
+ let l:spacePos = 0
873
+ let l:quoteRe = '\\\@<!"'
874
+
875
+ " "call Decho("in replace spaces. line=" . line('.'))
876
+ while (1)
877
+ let l:startQuotePos = match(l:line, l:quoteRe, l:startingPos)
878
+ if (l:startQuotePos < 0)
879
+ " "call Decho("No more quotes to the end of line")
880
+ break
881
+ endif
882
+ let l:endQuotePos = match(l:line, l:quoteRe, l:startQuotePos + 1)
883
+ if (l:endQuotePos < 0)
884
+ " "call Decho("Mismatched quotes")
885
+ break
886
+ endif
887
+ let l:spaceReplaceRe = '^.\{' . (l:startQuotePos + 1) . '}.\{-}\zs\s\ze.*.\{' . (linelen - l:endQuotePos) . '}$'
888
+ " "call Decho('spaceReplaceRe="' . l:spaceReplaceRe . '"')
889
+ let l:newStr = substitute(l:line, l:spaceReplaceRe, '%', '')
890
+ while (l:newStr != l:line)
891
+ " "call Decho('newstr="' . l:newStr . '"')
892
+ let l:line = l:newStr
893
+ let l:newStr = substitute(l:line, l:spaceReplaceRe, '%', '')
894
+ endwhile
895
+ let l:startingPos = l:endQuotePos + 1
896
+ endwhile
897
+ call setline(line('.'), l:line)
898
+
899
+ " call Dret("AlignReplaceQuotedSpaces")
900
+ endfun
901
+
902
+ " ---------------------------------------------------------------------
903
+ " s:QArgSplitter: to avoid \ processing by <f-args>, <q-args> is needed. {{{1
904
+ " However, <q-args> doesn't split at all, so this function returns a list
905
+ " of arguments which has been:
906
+ " * split at whitespace
907
+ " * unless inside "..."s. One may escape characters with a backslash inside double quotes.
908
+ " along with a leading length-of-list.
909
+ "
910
+ " Examples: %Align "\"" will align on "s
911
+ " %Align " " will align on spaces
912
+ "
913
+ " The resulting list: qarglist[0] corresponds to a:0
914
+ " qarglist[i] corresponds to a:{i}
915
+ fun! s:QArgSplitter(qarg)
916
+ " call Dfunc("s:QArgSplitter(qarg<".a:qarg.">)")
917
+
918
+ if a:qarg =~ '".*"'
919
+ " handle "..." args, which may include whitespace
920
+ let qarglist = []
921
+ let args = a:qarg
922
+ " call Decho("handle quoted arguments: args<".args.">")
923
+ while args != ""
924
+ let iarg = 0
925
+ let arglen = strlen(args)
926
+ " call Decho("args[".iarg."]<".args[iarg]."> arglen=".arglen)
927
+ " find index to first not-escaped '"'
928
+ while args[iarg] != '"' && iarg < arglen
929
+ if args[iarg] == '\'
930
+ let args= strpart(args,1)
931
+ endif
932
+ let iarg= iarg + 1
933
+ endwhile
934
+ " call Decho("args<".args."> iarg=".iarg." arglen=".arglen)
935
+
936
+ if iarg > 0
937
+ " handle left of quote or remaining section
938
+ " call Decho("handle left of quote or remaining section")
939
+ if args[iarg] == '"'
940
+ let qarglist= qarglist + split(strpart(args,0,iarg-1))
941
+ else
942
+ let qarglist= qarglist + split(strpart(args,0,iarg))
943
+ endif
944
+ let args = strpart(args,iarg)
945
+ let arglen = strlen(args)
946
+
947
+ elseif iarg < arglen && args[0] == '"'
948
+ " handle "quoted" section
949
+ " call Decho("handle quoted section")
950
+ let iarg= 1
951
+ while args[iarg] != '"' && iarg < arglen
952
+ if args[iarg] == '\'
953
+ let args= strpart(args,1)
954
+ endif
955
+ let iarg= iarg + 1
956
+ endwhile
957
+ " call Decho("args<".args."> iarg=".iarg." arglen=".arglen)
958
+ if args[iarg] == '"'
959
+ call add(qarglist,strpart(args,1,iarg-1))
960
+ let args= strpart(args,iarg+1)
961
+ else
962
+ let qarglist = qarglist + split(args)
963
+ let args = ""
964
+ endif
965
+ endif
966
+ " call Decho("qarglist".string(qarglist)." iarg=".iarg." args<".args.">")
967
+ endwhile
968
+
969
+ else
970
+ " split at all whitespace
971
+ let qarglist= split(a:qarg)
972
+ endif
973
+
974
+ let qarglistlen= len(qarglist)
975
+ let qarglist = insert(qarglist,qarglistlen)
976
+ " call Dret("s:QArgSplitter ".string(qarglist))
977
+ return qarglist
978
+ endfun
979
+
980
+ " ---------------------------------------------------------------------
981
+ " s:Strlen: this function returns the length of a string, even if its {{{1
982
+ " using two-byte etc characters.
983
+ " Currently, its only used if g:Align_xstrlen is set to a
984
+ " nonzero value. Solution from Nicolai Weibull, vim docs
985
+ " (:help strlen()), Tony Mechelynck, and my own invention.
986
+ fun! s:Strlen(x)
987
+ " call Dfunc("s:Strlen(x<".a:x.">")
988
+ if g:Align_xstrlen == 1
989
+ " number of codepoints (Latin a + combining circumflex is two codepoints)
990
+ " (comment from TM, solution from NW)
991
+ let ret= strlen(substitute(a:x,'.','c','g'))
992
+
993
+ elseif g:Align_xstrlen == 2
994
+ " number of spacing codepoints (Latin a + combining circumflex is one spacing
995
+ " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
996
+ " (comment from TM, solution from TM)
997
+ let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
998
+
999
+ elseif g:Align_xstrlen == 3
1000
+ " virtual length (counting, for instance, tabs as anything between 1 and
1001
+ " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
1002
+ " preceded by lam, one otherwise, etc.)
1003
+ " (comment from TM, solution from me)
1004
+ let modkeep= &l:mod
1005
+ exe "norm! o\<esc>"
1006
+ call setline(line("."),a:x)
1007
+ let ret= virtcol("$") - 1
1008
+ d
1009
+ let &l:mod= modkeep
1010
+
1011
+ else
1012
+ " at least give a decent default
1013
+ ret= strlen(a:x)
1014
+ endif
1015
+ " call Dret("s:Strlen ".ret)
1016
+ return ret
1017
+ endfun
1018
+
1019
+ " ---------------------------------------------------------------------
1020
+ " Set up default values: {{{1
1021
+ "call Decho("-- Begin AlignCtrl Initialization --")
1022
+ call Align#AlignCtrl("default")
1023
+ "call Decho("-- End AlignCtrl Initialization --")
1024
+
1025
+ " ---------------------------------------------------------------------
1026
+ " Restore: {{{1
1027
+ let &cpo= s:keepcpo
1028
+ unlet s:keepcpo
1029
+ " vim: ts=4 fdm=marker