utils 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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