aboutsummaryrefslogblamecommitdiff
path: root/dot_vim/ftplugin/latex-suite/packages.vim
blob: c3bf2b1b029e61d66dd51210187da82e70baa10d (plain) (tree)
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669




























































































































































































































































































































































































































































































































































































































































































                                                                                                                                               
"=============================================================================
" 	     File: packages.vim
"      Author: Mikolaj Machowski
"     Created: Tue Apr 23 06:00 PM 2002 PST
"         CVS: $Id: packages.vim 997 2006-03-20 09:45:45Z srinathava $
" 
"  Description: handling packages from within vim
"=============================================================================

" avoid reinclusion.
if !g:Tex_PackagesMenu || exists('s:doneOnce')
	finish
endif
let s:doneOnce = 1

let s:path = expand("<sfile>:p:h")

let s:menu_div = 20

com! -nargs=0 TPackageUpdate :silent! call Tex_pack_updateall(1)
com! -nargs=0 TPackageUpdateAll :silent! call Tex_pack_updateall(1)

" Custom command-line completion of Tcommands is very useful but this feature
" is available only in Vim 6.2 and above. Check number of version and choose
" proper command and function.
if v:version >= 602
	com! -complete=custom,Tex_CompletePackageName -nargs=* TPackage let s:retVal = Tex_pack_one(<f-args>) <bar> normal! i<C-r>=s:retVal<CR>

	" Tex_CompletePackageName: for completing names in TPackage command {{{
	"	Description: get list of package names with globpath(), remove full path
	"	and return list of names separated with newlines.
	"
	function! Tex_CompletePackageName(A,P,L)
		" Get name of packages from all runtimepath directories
		let packnames = Tex_FindInRtp('', 'packages')
		let packnames = substitute(packnames, '^,', '', 'e')
		" Separate names with \n not ,
		let packnames = substitute(packnames,',','\n','g')
		return packnames
	endfunction
	" }}}
	
else 
	com! -nargs=* TPackage let s:retVal = Tex_pack_one(<f-args>) <bar> normal! i<C-r>=s:retVal<CR>

endif

imap <silent> <plug> <Nop>
nmap <silent> <plug> i

let g:Tex_package_supported = ''
let g:Tex_package_detected = ''
" Remember the defaults because we want g:Tex_PromptedEnvironments to contain
" in addition to the default, \newenvironments, and the \newenvironments might
" change...
let g:Tex_PromptedEnvironmentsDefault = g:Tex_PromptedEnvironments
let g:Tex_PromptedCommandsDefault = g:Tex_PromptedCommands


" Tex_pack_check: creates the package menu and adds to 'dict' setting. {{{
"
function! Tex_pack_check(package)
	" Use Tex_FindInRtp() function to get first name from packages list in all
	" rtp directories conforming with latex-suite directories hierarchy
	" Store names in variables to process functions only once.
	let packname = Tex_FindInRtp(a:package, 'packages')
	if packname != ''
		exe 'runtime! ftplugin/latex-suite/packages/' . a:package
		if has("gui_running")
			call Tex_pack(a:package)
		endif
		if g:Tex_package_supported !~ a:package
			let g:Tex_package_supported = g:Tex_package_supported.','.a:package
		endif
	endif
	" Return full list of dictionaries (separated with ,) for package in &rtp
	call Tex_Debug("Tex_pack_check: searching for ".a:package." in dictionaries/ in &rtp", "pack")
	let dictname = Tex_FindInRtp(a:package, 'dictionaries', ':p')
	if dictname != ''
		exe 'setlocal dict^=' . dictname
		call Tex_Debug('Tex_pack_check: setlocal dict^=' . dictname, 'pack')
		if g:Tex_package_supported !~ a:package
			let g:Tex_package_supported = g:Tex_package_supported.','.a:package
		endif
	endif
	if g:Tex_package_detected !~ '\<'.a:package.'\>'
		let g:Tex_package_detected = g:Tex_package_detected.','.a:package
	endif
	let g:Tex_package_detected = substitute(g:Tex_package_detected, '^,', '', '')
	let g:Tex_package_supported = substitute(g:Tex_package_supported, '^,', '', '')
endfunction

" }}}
" Tex_pack_uncheck: removes package from menu and 'dict' settings. {{{
function! Tex_pack_uncheck(package)
	if has("gui_running") && Tex_FindInRtp(a:package, 'packages') != ''
		exe 'silent! aunmenu '.g:Tex_PackagesMenuLocation.'-sep'.a:package.'-'
		exe 'silent! aunmenu '.g:Tex_PackagesMenuLocation.a:package.'\ Options'
		exe 'silent! aunmenu '.g:Tex_PackagesMenuLocation.a:package.'\ Commands'
	endif
	if Tex_FindInRtp(a:package, 'dictionaries') != ''
		exe 'setlocal dict-='.Tex_FindInRtp(a:package, 'dictionaries')
	endif
endfunction

" }}}
" Tex_pack_updateall: updates the TeX-Packages menu {{{
" Description:
" 	This function first calls Tex_pack_all to scan for \usepackage's etc if
" 	necessary. After that, it 'supports' and 'unsupports' packages as needed
" 	in such a way as to not repeat work.
function! Tex_pack_updateall(force)
	call Tex_Debug('+Tex_pack_updateall', 'pack')

	" Find out which file we need to scan.
	let fname = Tex_GetMainFileName(':p')

	" If this is the same as last time, don't repeat.
	if !a:force && exists('s:lastScannedFile') &&
				\ s:lastScannedFile == fname
		return
	endif
	" Remember which file we scanned for next time.
	let s:lastScannedFile = fname

	" Remember which packages we detected last time.
	if exists('g:Tex_package_detected')
		let oldpackages = g:Tex_package_detected
	else
		let oldpackages = ''
	endif

	" This sets up a global variable of all detected packages.
	let g:Tex_package_detected = ''
	" reset the environments and commands.
	let g:Tex_PromptedEnvironments = g:Tex_PromptedEnvironmentsDefault
	let g:Tex_PromptedCommands = g:Tex_PromptedCommandsDefault

	if expand('%:p') != fname
		call Tex_Debug(':Tex_pack_updateall: sview '.Tex_EscapeSpaces(fname), 'pack')
		exe 'sview '.Tex_EscapeSpaces(fname)
	else
		call Tex_Debug(':Tex_pack_updateall: split', 'pack')
		split
	endif
		
	call Tex_ScanForPackages()
	q

	call Tex_Debug(':Tex_pack_updateall: detected ['.g:Tex_package_detected.'] in first run', 'pack')
	
	" Now for each package find out if this is a custom package and if so,
	" scan that as well. We will use the ':find' command in vim to let vim
	" search through the file paths for us.
	"
	" NOTE: This while loop will also take into account packages included
	"       within packages to any level of recursion as long as
	"       g:Tex_package_detected is always padded with new package names
	"       from the end.
	"
	" First set the &path setting to the user's TEXINPUTS setting.
	let _path = &path
	let _suffixesadd = &suffixesadd

	let &path = '.,'.g:Tex_TEXINPUTS
	let &suffixesadd = '.sty,.tex'

	let scannedPackages = ''

	let i = 1
	let packname = Tex_Strntok(g:Tex_package_detected, ',', i)
	while packname != ''

		call Tex_Debug(':Tex_pack_updateall: scanning package '.packname, 'pack')

		" Scan this package only if we have not scanned it before in this
		" run.
		if scannedPackages =~ '\<'.packname.'\>'
			let i = i + 1

			call Tex_Debug(':Tex_pack_updateall: '.packname.' already scanned', 'pack')
			let packname = Tex_Strntok(g:Tex_package_detected, ',', i)
			continue
		endif 

		" Split this window in two. The packages/files being found will open
		" in this new window and we also need not bother with files being
		" modified etc.
		split

		call Tex_Debug(':Tex_pack_updateall: silent! find '.Tex_EscapeSpaces(packname).'.sty', 'pack')
		let thisbufnum = bufnr('%')
		exec 'silent! find '.Tex_EscapeSpaces(packname).'.sty'
		call Tex_Debug(':Tex_pack_updateall: present file = '.bufname('%'), 'pack')

		" If this file was not found, assume that it means its not a
		" custom package and mark it "scanned".
		" A package is not found if we stay in the same buffer as before and
		" its not the one where we want to go.
		if bufnr('%') == thisbufnum && bufnr('%') != bufnr(packname.'.sty')
			let scannedPackages = scannedPackages.','.packname
			q

			call Tex_Debug(':Tex_pack_updateall: '.packname.' not found anywhere', 'pack')
			let i = i + 1
			let packname = Tex_Strntok(g:Tex_package_detected, ',', i)
			continue
		endif

		" otherwise we are presently editing a custom package, scan it for
		" more \usepackage lines from the first line to the last.
		let packpath = expand('%:p')
		let &complete = &complete.'s'.packpath

		call Tex_Debug(':Tex_pack_updateall: found custom package '.packpath, 'pack')
		call Tex_ScanForPackages(line('$'), line('$'))
		call Tex_Debug(':Tex_pack_updateall: After scanning, g:Tex_package_detected = '.g:Tex_package_detected, 'pack')

		let scannedPackages = scannedPackages.','.packname
		" Do not use bwipe, but that leads to excessive buffer number
		" consumption. Besides, its intuitive for a custom package to remain
		" on the buffer list.
		q

		let i = i + 1
		let packname = Tex_Strntok(g:Tex_package_detected, ',', i)
	endwhile

	let &path = _path
	let &suffixesadd = _suffixesadd

	" Now only support packages we didn't last time.
	" First remove packages which were used last time but are no longer used.
	let i = 1
	let oldPackName = Tex_Strntok(oldpackages, ',', i)
	while oldPackName != ''
		if g:Tex_package_detected !~ oldPackName
			call Tex_pack_uncheck(oldPackName)
		endif
		let i = i + 1
		let oldPackName = Tex_Strntok(oldpackages, ',', i)
	endwhile

	" Then support packages which are used this time but weren't used last
	" time.
	let i = 1
	let newPackName = Tex_Strntok(g:Tex_package_detected, ',', i)
	while newPackName != ''
		if oldpackages !~ newPackName
			call Tex_pack_one(newPackName)
		endif
		let i = i + 1
		let newPackName = Tex_Strntok(g:Tex_package_detected, ',', i)
	endwhile

	" Throw an event that we are done scanning packages. Some packages might
	" use this to change behavior based on which options have been used etc.
	call Tex_Debug(":Tex_pack_updateall: throwing LatexSuiteScannedPackages event", "pack")
	silent! do LatexSuite User LatexSuiteScannedPackages

	call Tex_Debug("-Tex_pack_updateall", "pack")
endfunction

" }}}
" Tex_pack_one: supports each package in the argument list.{{{
" Description:
"   If no arguments are supplied, then the user is asked to choose from the
"   packages found in the packages/ directory
function! Tex_pack_one(...)
	if a:0 == 0 || (a:0 > 0 && a:1 == '')
		let packlist = Tex_FindInRtp('', 'packages')
		let packname = Tex_ChooseFromPrompt(
					\ "Choose a package: \n" . 
					\ Tex_CreatePrompt(packlist, '3', ',') .
					\ "\nEnter number or filename :", 
					\ packlist, ',')
		if packname != ''
			return Tex_pack_one(packname)
		else
			return ''
		endif
	else
		" Support the packages supplied. This function can be called with
		" multiple arguments in which case, support each of them in turn.
		let retVal = ''
		let omega = 1
		while omega <= a:0
			let packname = a:{omega}
			if Tex_FindInRtp(packname, 'packages') != ''
				call Tex_pack_check(packname)
				if exists('g:TeX_package_option_'.packname)
						\ && g:TeX_package_option_{packname} != ''
					let retVal = retVal.'\usepackage[<++>]{'.packname.'}<++>'
				else
					let retVal = retVal.'\usepackage{'.packname.'}'."\<CR>"
				endif
			else
				let retVal = retVal.'\usepackage{'.packname.'}'."\<CR>"
			endif
			let omega = omega + 1
		endwhile
		return IMAP_PutTextWithMovement(substitute(retVal, "\<CR>$", '', ''), '<+', '+>')
	endif
endfunction
" }}}
" Tex_ScanForPackages: scans the current file for \usepackage{} lines {{{
"   and if supported, loads the options and commands found in the
"   corresponding package file. Also scans for \newenvironment and
"   \newcommand lines and adds names to g:Tex_Prompted variables, they can be
"   easy available through <F5> and <F7> shortcuts 
function! Tex_ScanForPackages(...)
	call Tex_Debug("+Tex_ScanForPackages", "pack")

	let pos = line('.').' | normal! '.virtcol('.').'|'

	" For package files without \begin and \end{document}, we might be told to
	" search from beginning to end.
	if a:0 < 2
		0
		let beginline = search('\\begin{document}', 'W')
		let endline = search('\\end{document}', 'W')
		0
	else
		let beginline = a:1
		let endline = a:2
	endif

	call Tex_Debug(":Tex_ScanForPackages: Begining scans in [".bufname('%')."], beginline = ".beginline, "pack")
	

	" Scan the file. First open up all the folds, because the command
	" /somepattern
	" issued in a closed fold _always_ goes to the first match.
	let erm = v:errmsg
	silent! normal! ggVGzO
	let v:errmsg = erm

	call Tex_Debug(":Tex_ScanForPackages: beginning scan for \\usepackage lines", "pack")
	" The wrap trick enables us to match \usepackage on the first line as
	" well.
	let wrap = 'w'
	while search('^\s*\\usepackage\_.\{-}{\_.\+}', wrap)
		let wrap = 'W'

		if line('.') > beginline 
			break
		endif

		let saveA = @a

		" If there are options, then find those.
		if getline('.') =~ '\\usepackage\[.\{-}\]'
			let options = matchstr(getline('.'), '\\usepackage\[\zs.\{-}\ze\]')
		elseif getline('.') =~ '\\usepackage\['
			" Entering here means that the user has split the \usepackage
			" across newlines. Therefore, use yank.
			exec "normal! /{\<CR>\"ayi}"
			let options = @a
		else
			let options = ''
		endif

		" The following statement puts the stuff between the { }'s of a
		" \usepackage{stuff,foo} into @a. Do not use matchstr() and the like
		" because we can have things split across lines and such.
       	exec "normal! /{\<CR>\"ay/}\<CR>"

		" now remove all whitespace from @a. We need to remove \n and \r
		" because we can encounter stuff like
		" \usepackage{pack1,
		"             newpackonanotherline}
		let @a = substitute(@a, "[ \t\n\r]", '', 'g')

		" Now we have something like pack1,pack2,pack3 with possibly commas
		" and stuff before the first package and after the last package name.
		" Remove those.
		let @a = substitute(@a, '\(^\W*\|\W*$\)', '', 'g')

		" This gets us a string like 'pack1,pack2,pack3'
		" TODO: This will contain duplicates if the user has duplicates.
		"       Should we bother taking care of this?
		let g:Tex_package_detected = g:Tex_package_detected.','.@a

		" For each package found, form a global variable of the form
		" g:Tex_{packagename}_options 
		" which contains a list of the options.
		let j = 1
		while Tex_Strntok(@a, ',', j) != ''
			let g:Tex_{Tex_Strntok(@a, ',', j)}_options = options
			let j = j + 1
		endwhile

		" Finally convert @a into something like '"pack1","pack2"'
		let @a = substitute(@a, '^\|$', '"', 'g')
		let @a = substitute(@a, ',', '","', 'g')

		call Tex_Debug(":Tex_ScanForPackages: found package(s) [".@a."] on line ".line('.'), "pack")

		" restore @a
		let @a = saveA
	endwhile
	call Tex_Debug(":Tex_ScanForPackages: End scan \\usepackage, detected packages = ".g:Tex_package_detected, "pack")

	" TODO: This needs to be changed. In the future, we might have
	" functionality to remember the fold-state before opening up all the folds
	" and then re-creating them. Use mkview.vim.
	let erm = v:errmsg
	silent! normal! ggVGzC
	let v:errmsg = erm

	" Because creating list of detected packages gives string
	" ',pack1,pack2,pack3' remove leading ,
	let g:Tex_package_detected = substitute(g:Tex_package_detected, '^,', '', '')

	call Tex_Debug(":Tex_ScanForPackages: Beginning scan for \\newcommand's", "pack")
	" Scans whole file (up to \end{document}) for \newcommand and adds this
	" commands to g:Tex_PromptedCommands variable, it is easily available
	" through <F7>
	0 
	while search('^\s*\\newcommand\*\?{.\{-}}', 'W')

		if line('.') > endline 
			break
		endif

		let newcommand = matchstr(getline('.'), '\\newcommand\*\?{\\\zs.\{-}\ze}')
		let g:Tex_PromptedCommands = g:Tex_PromptedCommands . ',' . newcommand

	endwhile

	" Scans whole file (up to \end{document}) for \newenvironment and adds this
	" environments to g:Tex_PromptedEnvironments variable, it is easily available
	" through <F5>
	0
	call Tex_Debug(":Tex_ScanForPackages: Beginning scan for \\newenvironment's", 'pack')

	while search('^\s*\\newenvironment\*\?{.\{-}}', 'W')
		call Tex_Debug('found newenvironment on '.line('.'), 'pack')

		if line('.') > endline 
			break
		endif

		let newenvironment = matchstr(getline('.'), '\\newenvironment\*\?{\zs.\{-}\ze}')
		let g:Tex_PromptedEnvironments = g:Tex_PromptedEnvironments . ',' . newenvironment

	endwhile

	exe pos
	" first make a random search so that we push at least one item onto the
	" search history. Since vim puts only one item in the history per function
	" call, this way we make sure that one and only item is put into the
	" search history.
	normal! /^<CR>
	" now delete it...
	call histdel('/', -1)

	call Tex_Debug("-Tex_ScanForPackages", "pack")
endfunction
   
" }}}
" Tex_pack_supp_menu: sets up a menu for package files {{{
"   found in the packages directory groups the packages thus found into groups
"   of 20...
function! Tex_pack_supp_menu()
	let suplist = Tex_FindInRtp('', 'packages')

	call Tex_MakeSubmenu(suplist, g:Tex_PackagesMenuLocation.'Supported.', 
		\ '<plug><C-r>=Tex_pack_one("', '")<CR>')
endfunction 

" }}}
" Tex_pack: loads the options (and commands) for the given package {{{
function! Tex_pack(pack)
	if exists('g:TeX_package_'.a:pack)

		let optionList = g:TeX_package_option_{a:pack}.','
		let commandList = g:TeX_package_{a:pack}.','

		" Don't create separator if in package file are only Vim commands. 
		" Rare but possible.
		if !(commandList == ',' && optionList == ',')
			exec 'amenu '.g:Tex_PackagesMenuLocation.'-sep'.a:pack.'- <Nop>'
		endif

		if optionList != ''

			let mainMenuName = g:Tex_PackagesMenuLocation.a:pack.'\ Options.'
			call s:GroupPackageMenuItems(optionList, mainMenuName, 
				\ '<plug><C-r>=IMAP_PutTextWithMovement("', ',")<CR>')

		endif

		if commandList != ''

			let mainMenuName = g:Tex_PackagesMenuLocation.a:pack.'\ Commands.'
			call s:GroupPackageMenuItems(commandList, mainMenuName, 
				\ '<plug><C-r>=Tex_ProcessPackageCommand("', '")<CR>',
				\ '<SID>FilterPackageMenuLHS')
		endif
	endif
endfunction 

" }}}

" ==============================================================================
" Menu Functions
" Creating menu items for the all the package files found in the packages/
" directory as well as creating menus for each supported package found in the
" preamble.
" ============================================================================== 
" Tex_MakeSubmenu: makes a submenu given a list of items {{{
" Description: 
"   This function takes a comma seperated list of menu items and creates a
"   'grouped' menu. i.e, it groups the items into s:menu_div items each and
"   puts them in submenus of the given mainMenu.
"   Each menu item is linked to the HandlerFunc.
"   If an additional argument is supplied, then it is used to filter each of
"   the menu items to generate better names for the menu display.
"
function! Tex_MakeSubmenu(menuList, mainMenuName, 
				\ handlerFuncLHS, handlerFuncRHS, ...)

	let extractFunction = (a:0 > 0 ? a:1 : '' )
	let menuList = substitute(a:menuList, '[^,]$', ',', '')

	let doneMenuSubmenu = 0

	while menuList != ''

		" Extract upto s:menu_div menus at once.
		let menuBunch = matchstr(menuList, '\v(.{-},){,'.s:menu_div.'}')

		" The remaining menus go into the list.
		let menuList = strpart(menuList, strlen(menuBunch))

		let submenu = ''
		" If there is something remaining, then we got s:menu_div items.
		" therefore put these menu items into a submenu.
		if strlen(menuList) || doneMenuSubmenu
			exec 'let firstMenu = '.extractFunction."(matchstr(menuBunch, '\\v^.{-}\\ze,'))"
			exec 'let lastMenu = '.extractFunction."(matchstr(menuBunch, '\\v[^,]{-}\\ze,$'))"

			let submenu = firstMenu.'\ \-\ '.lastMenu.'.'

			let doneMenuSubmenu = 1
		endif

		" Now for each menu create a menu under the submenu
		let i = 1
		let menuName = Tex_Strntok(menuBunch, ',', i)
		while menuName != ''
			exec 'let menuItem = '.extractFunction.'(menuName)'
			execute 'amenu '.a:mainMenuName.submenu.menuItem
				\ '       '.a:handlerFuncLHS.menuName.a:handlerFuncRHS

			let i = i + 1
			let menuName = Tex_Strntok(menuBunch, ',', i)
		endwhile
	endwhile
endfunction 

" }}}
" GroupPackageMenuItems: uses the sbr: to split menus into groups {{{
" Description: 
"   This function first splits up the menuList into groups based on the
"   special sbr: tag and then calls Tex_MakeSubmenu 
" 
function! <SID>GroupPackageMenuItems(menuList, menuName, 
					\ handlerFuncLHS, handlerFuncRHS,...)

	if a:0 > 0
		let extractFunction = a:1
	else
		let extractFunction = ''
	endif
	let menuList = a:menuList

	while matchstr(menuList, 'sbr:') != ''
		let groupName = matchstr(menuList, '\v^sbr:\zs.{-}\ze,')
		let menuList = strpart(menuList, strlen('sbr:'.groupName.','))
		if matchstr(menuList, 'sbr:') != ''
			let menuGroup = matchstr(menuList, '\v^.{-},\zesbr:')
		else
			let menuGroup = menuList
		endif

		call Tex_MakeSubmenu(menuGroup, a:menuName.groupName.'.', 
			\ a:handlerFuncLHS, a:handlerFuncRHS, extractFunction)

		let menuList = strpart(menuList, strlen(menuGroup))
	endwhile

	call Tex_MakeSubmenu(menuList, a:menuName,
		\ a:handlerFuncLHS, a:handlerFuncRHS, extractFunction)

endfunction " }}}
" Definition of what to do for various package commands {{{
let s:CommandSpec_bra = '\<+replace+>{<++>}<++>'
let s:CommandSpec_brs = '\<+replace+><++>'
let s:CommandSpec_brd = '\<+replace+>{<++>}{<++>}<++>'
let s:CommandSpec_env = '\begin{<+replace+>}'."\<CR><++>\<CR>".'\end{<+replace+>}<++>'
let s:CommandSpec_ens = '\begin{<+replace+>}<+extra+>'."\<CR><++>\<CR>".'\end{<+replace+>}<++>'
let s:CommandSpec_eno = '\begin[<++>]{<+replace+>}'."\<CR><++>\<CR>".'\end{<+replace+>}'
let s:CommandSpec_nor = '\<+replace+>'
let s:CommandSpec_noo = '\<+replace+>[<++>]'
let s:CommandSpec_nob = '\<+replace+>[<++>]{<++>}{<++>}<++>'
let s:CommandSpec_spe = '<+replace+>'
let s:CommandSpec_    = '\<+replace+>'

let s:MenuLHS_bra = '\\&<+replace+>{}'
let s:MenuLHS_brs = '\\&<+replace+>{}'
let s:MenuLHS_brd = '\\&<+replace+>{}{}'
let s:MenuLHS_env = '&<+replace+>\ (E)'
let s:MenuLHS_ens = '&<+replace+>\ (E)'
let s:MenuLHS_eno = '&<+replace+>\ (E)'
let s:MenuLHS_nor = '\\&<+replace+>'
let s:MenuLHS_noo = '\\&<+replace+>[]'
let s:MenuLHS_nob = '\\&<+replace+>[]{}{}'
let s:MenuLHS_spe = '&<+replace+>'
let s:MenuLHS_sep = '-sep<+replace+>-'
let s:MenuLHS_    = '\\&<+replace+>'
" }}}
" Tex_ProcessPackageCommand: processes a command from the package menu {{{
" Description: 
function! Tex_ProcessPackageCommand(command)
	if a:command =~ ':'
		let commandType = matchstr(a:command, '^\w\+\ze:')
		let commandName = matchstr(a:command, '^\w\+:\zs[^:]\+\ze:\?')
		let extrapart = strpart(a:command, strlen(commandType.':'.commandName.':'))
	else
		let commandType = ''
		let commandName = a:command
		let extrapart = ''
	endif

	let command = s:CommandSpec_{commandType}
	let command = substitute(command, '<+replace+>', commandName, 'g')
	let command = substitute(command, '<+extra+>', extrapart, 'g')
	return IMAP_PutTextWithMovement(command)
endfunction 
" }}}
" FilterPackageMenuLHS: filters the command description to provide a better menu item {{{
" Description: 
function! <SID>FilterPackageMenuLHS(command)
	let commandType = matchstr(a:command, '^\w\+\ze:')
	if commandType != ''
		let commandName = strpart(a:command, strlen(commandType.':'))
	else
		let commandName = a:command
	endif

	return substitute(s:MenuLHS_{commandType}, '<+replace+>', commandName, 'g')
endfunction " }}}

if g:Tex_Menus
	exe 'amenu '.g:Tex_PackagesMenuLocation.'&UpdatePackage :call Tex_pack(expand("<cword>"))<cr>'
	exe 'amenu '.g:Tex_PackagesMenuLocation.'&UpdateAll :call Tex_pack_updateall(1)<cr>'

 	call Tex_pack_supp_menu()
endif

augroup LatexSuite
	au LatexSuite User LatexSuiteFileType 
		\ call Tex_Debug('packages.vim: Catching LatexSuiteFileType event', 'pack') | 
		\ call Tex_pack_updateall(0)
augroup END

" vim:fdm=marker:ts=4:sw=4:noet:ff=unix