1"------------------------------------------------------------------------------
2"  Description: Perform Ada specific completion & tagging.
3"     Language: Ada (2005)
4"	   $Id: ada.vim 887 2008-07-08 14:29:01Z krischik $
5"   Maintainer: Martin Krischik <krischik@users.sourceforge.net>
6"		Taylor Venable <taylor@metasyntax.net>
7"		Neil Bird <neil@fnxweb.com>
8"		Ned Okie <nokie@radford.edu>
9"      $Author: krischik $
10"	 $Date: 2008-07-08 16:29:01 +0200 (Di, 08 Jul 2008) $
11"      Version: 4.6
12"    $Revision: 887 $
13"     $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $
14"      History: 24.05.2006 MK Unified Headers
15"		26.05.2006 MK ' should not be in iskeyword.
16"		16.07.2006 MK Ada-Mode as vim-ball
17"		02.10.2006 MK Better folding.
18"		15.10.2006 MK Bram's suggestion for runtime integration
19"		05.11.2006 MK Bram suggested not to use include protection for
20"			      autoload
21"		05.11.2006 MK Bram suggested to save on spaces
22"		08.07.2007 TV fix mapleader problems.
23"	        09.05.2007 MK Session just won't work no matter how much
24"			      tweaking is done
25"		19.09.2007 NO still some mapleader problems
26"    Help Page: ft-ada-functions
27"------------------------------------------------------------------------------
28
29if version < 700
30   finish
31endif 
32
33" Section: Constants {{{1
34"
35let g:ada#DotWordRegex	   = '\a\w*\(\_s*\.\_s*\a\w*\)*'
36let g:ada#WordRegex	   = '\a\w*'
37let g:ada#Comment	   = "\\v^(\"[^\"]*\"|'.'|[^\"']){-}\\zs\\s*--.*"
38let g:ada#Keywords	   = []
39
40" Section: g:ada#Keywords {{{1
41"
42" Section: add Ada keywords {{{2
43"
44for Item in ['abort', 'else', 'new', 'return', 'abs', 'elsif', 'not', 'reverse', 'abstract', 'end', 'null', 'accept', 'entry', 'select', 'access', 'exception', 'of', 'separate', 'aliased', 'exit', 'or', 'subtype', 'all', 'others', 'synchronized', 'and', 'for', 'out', 'array', 'function', 'overriding', 'tagged', 'at', 'task', 'generic', 'package', 'terminate', 'begin', 'goto', 'pragma', 'then', 'body', 'private', 'type', 'if', 'procedure', 'case', 'in', 'protected', 'until', 'constant', 'interface', 'use', 'is', 'raise', 'declare', 'range', 'when', 'delay', 'limited', 'record', 'while', 'delta', 'loop', 'rem', 'with', 'digits', 'renames', 'do', 'mod', 'requeue', 'xor']
45    let g:ada#Keywords += [{
46	    \ 'word':  Item,
47	    \ 'menu':  'keyword',
48	    \ 'info':  'Ada keyword.',
49	    \ 'kind':  'k',
50	    \ 'icase': 1}]
51endfor
52
53" Section: GNAT Project Files {{{3
54"
55if exists ('g:ada_with_gnat_project_files')
56    for Item in ['project']
57       let g:ada#Keywords += [{
58	       \ 'word':  Item,
59	       \ 'menu':  'keyword',
60	       \ 'info':  'GNAT projectfile keyword.',
61	       \ 'kind':  'k',
62	       \ 'icase': 1}]
63    endfor
64endif
65
66" Section: add	standart exception {{{2
67"
68for Item in ['Constraint_Error', 'Program_Error', 'Storage_Error', 'Tasking_Error', 'Status_Error', 'Mode_Error', 'Name_Error', 'Use_Error', 'Device_Error', 'End_Error', 'Data_Error', 'Layout_Error', 'Length_Error', 'Pattern_Error', 'Index_Error', 'Translation_Error', 'Time_Error', 'Argument_Error', 'Tag_Error', 'Picture_Error', 'Terminator_Error', 'Conversion_Error', 'Pointer_Error', 'Dereference_Error', 'Update_Error']
69    let g:ada#Keywords += [{
70	    \ 'word':  Item,
71	    \ 'menu':  'exception',
72	    \ 'info':  'Ada standart exception.',
73	    \ 'kind':  'x',
74	    \ 'icase': 1}]
75endfor
76
77" Section: add	GNAT exception {{{3
78"
79if exists ('g:ada_gnat_extensions')
80    for Item in ['Assert_Failure']
81	let g:ada#Keywords += [{
82		\ 'word':  Item,
83		\ 'menu':  'exception',
84		\ 'info':  'GNAT exception.',
85		\ 'kind':  'x',
86		\ 'icase': 1}]
87    endfor
88endif
89
90" Section: add Ada buildin types {{{2
91"
92for Item in ['Boolean', 'Integer', 'Natural', 'Positive', 'Float', 'Character', 'Wide_Character', 'Wide_Wide_Character', 'String', 'Wide_String', 'Wide_Wide_String', 'Duration']
93    let g:ada#Keywords += [{
94	    \ 'word':  Item,
95	    \ 'menu':  'type',
96	    \ 'info':  'Ada buildin type.',
97	    \ 'kind':  't',
98	    \ 'icase': 1}]
99endfor
100
101" Section: add GNAT buildin types {{{3
102"
103if exists ('g:ada_gnat_extensions')
104    for Item in ['Short_Integer', 'Short_Short_Integer', 'Long_Integer', 'Long_Long_Integer', 'Short_Float', 'Short_Short_Float', 'Long_Float', 'Long_Long_Float']
105	let g:ada#Keywords += [{
106		\ 'word':  Item,
107		\ 'menu':  'type',
108		\ 'info':  'GNAT buildin type.',
109		\ 'kind':  't',
110		\ 'icase': 1}]
111    endfor
112endif
113
114" Section: add Ada Attributes {{{2
115"
116for Item in ['''Access', '''Address', '''Adjacent', '''Aft', '''Alignment', '''Base', '''Bit_Order', '''Body_Version', '''Callable', '''Caller', '''Ceiling', '''Class', '''Component_Size', '''Compose', '''Constrained', '''Copy_Sign', '''Count', '''Definite', '''Delta', '''Denorm', '''Digits', '''Emax', '''Exponent', '''External_Tag', '''Epsilon', '''First', '''First_Bit', '''Floor', '''Fore', '''Fraction', '''Identity', '''Image', '''Input', '''Large', '''Last', '''Last_Bit', '''Leading_Part', '''Length', '''Machine', '''Machine_Emax', '''Machine_Emin', '''Machine_Mantissa', '''Machine_Overflows', '''Machine_Radix', '''Machine_Rounding', '''Machine_Rounds', '''Mantissa', '''Max', '''Max_Size_In_Storage_Elements', '''Min', '''Mod', '''Model', '''Model_Emin', '''Model_Epsilon', '''Model_Mantissa', '''Model_Small', '''Modulus', '''Output', '''Partition_ID', '''Pos', '''Position', '''Pred', '''Priority', '''Range', '''Read', '''Remainder', '''Round', '''Rounding', '''Safe_Emax', '''Safe_First', '''Safe_Large', '''Safe_Last', '''Safe_Small', '''Scale', '''Scaling', '''Signed_Zeros', '''Size', '''Small', '''Storage_Pool', '''Storage_Size', '''Stream_Size', '''Succ', '''Tag', '''Terminated', '''Truncation', '''Unbiased_Rounding', '''Unchecked_Access', '''Val', '''Valid', '''Value', '''Version', '''Wide_Image', '''Wide_Value', '''Wide_Wide_Image', '''Wide_Wide_Value', '''Wide_Wide_Width', '''Wide_Width', '''Width', '''Write']
117    let g:ada#Keywords += [{
118	    \ 'word':  Item,
119	    \ 'menu':  'attribute',
120	    \ 'info':  'Ada attribute.',
121	    \ 'kind':  'a',
122	    \ 'icase': 1}]
123endfor
124
125" Section: add GNAT Attributes {{{3
126"
127if exists ('g:ada_gnat_extensions')
128    for Item in ['''Abort_Signal', '''Address_Size', '''Asm_Input', '''Asm_Output', '''AST_Entry', '''Bit', '''Bit_Position', '''Code_Address', '''Default_Bit_Order', '''Elaborated', '''Elab_Body', '''Elab_Spec', '''Emax', '''Enum_Rep', '''Epsilon', '''Fixed_Value', '''Has_Access_Values', '''Has_Discriminants', '''Img', '''Integer_Value', '''Machine_Size', '''Max_Interrupt_Priority', '''Max_Priority', '''Maximum_Alignment', '''Mechanism_Code', '''Null_Parameter', '''Object_Size', '''Passed_By_Reference', '''Range_Length', '''Storage_Unit', '''Target_Name', '''Tick', '''To_Address', '''Type_Class', '''UET_Address', '''Unconstrained_Array', '''Universal_Literal_String', '''Unrestricted_Access', '''VADS_Size', '''Value_Size', '''Wchar_T_Size', '''Word_Size']
129    let g:ada#Keywords += [{
130	    \ 'word':  Item,
131	    \ 'menu':  'attribute',
132	    \ 'info':  'GNAT attribute.',
133	    \ 'kind':  'a',
134	    \ 'icase': 1}]
135    endfor
136endif
137
138" Section: add Ada Pragmas {{{2
139"
140for Item in ['All_Calls_Remote', 'Assert', 'Assertion_Policy', 'Asynchronous', 'Atomic', 'Atomic_Components', 'Attach_Handler', 'Controlled', 'Convention', 'Detect_Blocking', 'Discard_Names', 'Elaborate', 'Elaborate_All', 'Elaborate_Body', 'Export', 'Import', 'Inline', 'Inspection_Point', 'Interface (Obsolescent)', 'Interrupt_Handler', 'Interrupt_Priority', 'Linker_Options', 'List', 'Locking_Policy', 'Memory_Size (Obsolescent)', 'No_Return', 'Normalize_Scalars', 'Optimize', 'Pack', 'Page', 'Partition_Elaboration_Policy', 'Preelaborable_Initialization', 'Preelaborate', 'Priority', 'Priority_Specific_Dispatching', 'Profile', 'Pure', 'Queueing_Policy', 'Relative_Deadline', 'Remote_Call_Interface', 'Remote_Types', 'Restrictions', 'Reviewable', 'Shared (Obsolescent)', 'Shared_Passive', 'Storage_Size', 'Storage_Unit (Obsolescent)', 'Suppress', 'System_Name (Obsolescent)', 'Task_Dispatching_Policy', 'Unchecked_Union', 'Unsuppress', 'Volatile', 'Volatile_Components']
141    let g:ada#Keywords += [{
142	    \ 'word':  Item,
143	    \ 'menu':  'pragma',
144	    \ 'info':  'Ada pragma.',
145	    \ 'kind':  'p',
146	    \ 'icase': 1}]
147endfor
148
149" Section: add GNAT Pragmas {{{3
150"
151if exists ('g:ada_gnat_extensions')
152    for Item in ['Abort_Defer', 'Ada_83', 'Ada_95', 'Ada_05', 'Annotate', 'Ast_Entry', 'C_Pass_By_Copy', 'Comment', 'Common_Object', 'Compile_Time_Warning', 'Complex_Representation', 'Component_Alignment', 'Convention_Identifier', 'CPP_Class', 'CPP_Constructor', 'CPP_Virtual', 'CPP_Vtable', 'Debug', 'Elaboration_Checks', 'Eliminate', 'Export_Exception', 'Export_Function', 'Export_Object', 'Export_Procedure', 'Export_Value', 'Export_Valued_Procedure', 'Extend_System', 'External', 'External_Name_Casing', 'Finalize_Storage_Only', 'Float_Representation', 'Ident', 'Import_Exception', 'Import_Function', 'Import_Object', 'Import_Procedure', 'Import_Valued_Procedure', 'Initialize_Scalars', 'Inline_Always', 'Inline_Generic', 'Interface_Name', 'Interrupt_State', 'Keep_Names', 'License', 'Link_With', 'Linker_Alias', 'Linker_Section', 'Long_Float', 'Machine_Attribute', 'Main_Storage', 'Obsolescent', 'Passive', 'Polling', 'Profile_Warnings', 'Propagate_Exceptions', 'Psect_Object', 'Pure_Function', 'Restriction_Warnings', 'Source_File_Name', 'Source_File_Name_Project', 'Source_Reference', 'Stream_Convert', 'Style_Checks', 'Subtitle', 'Suppress_All', 'Suppress_Exception_Locations', 'Suppress_Initialization', 'Task_Info', 'Task_Name', 'Task_Storage', 'Thread_Body', 'Time_Slice', 'Title', 'Unimplemented_Unit', 'Universal_Data', 'Unreferenced', 'Unreserve_All_Interrupts', 'Use_VADS_Size', 'Validity_Checks', 'Warnings', 'Weak_External']
153	let g:ada#Keywords += [{
154		\ 'word':  Item,
155		\ 'menu':  'pragma',
156		\ 'info':  'GNAT pragma.',
157		\ 'kind':  'p',
158		\ 'icase': 1}]
159    endfor
160endif
161" 1}}}
162
163" Section: g:ada#Ctags_Kinds {{{1
164"
165let g:ada#Ctags_Kinds = {
166   \ 'P': ["packspec",	  "package specifications"],
167   \ 'p': ["package",	  "packages"],
168   \ 'T': ["typespec",	  "type specifications"],
169   \ 't': ["type",	  "types"],
170   \ 'U': ["subspec",	  "subtype specifications"],
171   \ 'u': ["subtype",	  "subtypes"],
172   \ 'c': ["component",   "record type components"],
173   \ 'l': ["literal",	  "enum type literals"],
174   \ 'V': ["varspec",	  "variable specifications"],
175   \ 'v': ["variable",	  "variables"],
176   \ 'f': ["formal",	  "generic formal parameters"],
177   \ 'n': ["constant",	  "constants"],
178   \ 'x': ["exception",   "user defined exceptions"],
179   \ 'R': ["subprogspec", "subprogram specifications"],
180   \ 'r': ["subprogram",  "subprograms"],
181   \ 'K': ["taskspec",	  "task specifications"],
182   \ 'k': ["task",	  "tasks"],
183   \ 'O': ["protectspec", "protected data specifications"],
184   \ 'o': ["protected",   "protected data"],
185   \ 'E': ["entryspec",   "task/protected data entry specifications"],
186   \ 'e': ["entry",	  "task/protected data entries"],
187   \ 'b': ["label",	  "labels"],
188   \ 'i': ["identifier",  "loop/declare identifiers"],
189   \ 'a': ["autovar",	  "automatic variables"],
190   \ 'y': ["annon",	  "loops and blocks with no identifier"]}
191
192" Section: ada#Word (...) {{{1
193"
194" Extract current Ada word across multiple lines
195" AdaWord ([line, column])\
196"
197function ada#Word (...)
198   if a:0 > 1
199      let l:Line_Nr    = a:1
200      let l:Column_Nr  = a:2 - 1
201   else
202      let l:Line_Nr    = line('.')
203      let l:Column_Nr  = col('.') - 1
204   endif
205
206   let l:Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' )
207
208   " Cope with tag searching for items in comments; if we are, don't loop
209   " backards looking for previous lines
210   if l:Column_Nr > strlen(l:Line)
211      " We were in a comment
212      let l:Line = getline(l:Line_Nr)
213      let l:Search_Prev_Lines = 0
214   else
215      let l:Search_Prev_Lines = 1
216   endif
217
218   " Go backwards until we find a match (Ada ID) that *doesn't* include our
219   " location - i.e., the previous ID. This is because the current 'correct'
220   " match will toggle matching/not matching as we traverse characters
221   " backwards. Thus, we have to find the previous unrelated match, exclude
222   " it, then use the next full match (ours).
223   " Remember to convert vim column 'l:Column_Nr' [1..n] to string offset [0..(n-1)]
224   " ... but start, here, one after the required char.
225   let l:New_Column = l:Column_Nr + 1
226   while 1
227      let l:New_Column = l:New_Column - 1
228      if l:New_Column < 0
229	 " Have to include previous l:Line from file
230	 let l:Line_Nr = l:Line_Nr - 1
231	 if l:Line_Nr < 1  ||  !l:Search_Prev_Lines
232	    " Start of file or matching in a comment
233	    let l:Line_Nr     = 1
234	    let l:New_Column  = 0
235	    let l:Our_Match   = match (l:Line, g:ada#WordRegex )
236	    break
237	 endif
238	 " Get previous l:Line, and prepend it to our search string
239	 let l:New_Line    = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' )
240	 let l:New_Column  = strlen (l:New_Line) - 1
241	 let l:Column_Nr   = l:Column_Nr + l:New_Column
242	 let l:Line	   = l:New_Line . l:Line
243      endif
244      " Check to see if this is a match excluding 'us'
245      let l:Match_End = l:New_Column +
246		      \ matchend (strpart (l:Line,l:New_Column), g:ada#WordRegex ) - 1
247      if l:Match_End >= l:New_Column  &&
248       \ l:Match_End < l:Column_Nr
249	 " Yes
250	 let l:Our_Match = l:Match_End+1 +
251			 \ match (strpart (l:Line,l:Match_End+1), g:ada#WordRegex )
252	 break
253      endif
254   endwhile
255
256   " Got anything?
257   if l:Our_Match < 0
258      return ''
259   else
260      let l:Line = strpart (l:Line, l:Our_Match)
261   endif
262
263   " Now simply add further lines until the match gets no bigger
264   let l:Match_String = matchstr (l:Line, g:ada#WordRegex)
265   let l:Last_Line    = line ('$')
266   let l:Line_Nr      = line ('.') + 1
267   while l:Line_Nr <= l:Last_Line
268      let l:Last_Match = l:Match_String
269      let l:Line = l:Line .
270	 \ substitute (getline (l:Line_Nr), g:ada#Comment, '', '')
271      let l:Match_String = matchstr (l:Line, g:ada#WordRegex)
272      if l:Match_String == l:Last_Match
273	 break
274      endif
275   endwhile
276
277   " Strip whitespace & return
278   return substitute (l:Match_String, '\s\+', '', 'g')
279endfunction ada#Word
280
281" Section: ada#List_Tag (...) {{{1
282"
283"  List tags in quickfix window
284"
285function ada#List_Tag (...)
286   if a:0 > 1
287      let l:Tag_Word = ada#Word (a:1, a:2)
288   elseif a:0 > 0
289      let l:Tag_Word = a:1
290   else
291      let l:Tag_Word = ada#Word ()
292   endif
293
294   echo "Searching for" l:Tag_Word
295
296   let l:Pattern = '^' . l:Tag_Word . '$'
297   let l:Tag_List = taglist (l:Pattern)
298   let l:Error_List = []
299   "
300   " add symbols
301   "
302   for Tag_Item in l:Tag_List
303      if l:Tag_Item['kind'] == ''
304	 let l:Tag_Item['kind'] = 's'
305      endif
306
307      let l:Error_List += [
308	 \ l:Tag_Item['filename'] . '|' .
309	 \ l:Tag_Item['cmd']	  . '|' .
310	 \ l:Tag_Item['kind']	  . "\t" .
311	 \ l:Tag_Item['name'] ]
312   endfor
313   set errorformat=%f\|%l\|%m
314   cexpr l:Error_List
315   cwindow
316endfunction ada#List_Tag
317
318" Section: ada#Jump_Tag (Word, Mode) {{{1
319"
320" Word tag - include '.' and if Ada make uppercase
321"
322function ada#Jump_Tag (Word, Mode)
323   if a:Word == ''
324      " Get current word
325      let l:Word = ada#Word()
326      if l:Word == ''
327	 throw "NOT_FOUND: no identifier found."
328      endif
329   else
330      let l:Word = a:Word
331   endif
332
333   echo "Searching for " . l:Word
334
335   try
336      execute a:Mode l:Word
337   catch /.*:E426:.*/
338      let ignorecase = &ignorecase
339      set ignorecase
340      execute a:Mode l:Word
341      let &ignorecase = ignorecase
342   endtry
343
344   return
345endfunction ada#Jump_Tag
346
347" Section: ada#Insert_Backspace () {{{1
348"
349" Backspace at end of line after auto-inserted commentstring '-- ' wipes it
350"
351function ada#Insert_Backspace ()
352   let l:Line = getline ('.')
353   if col ('.') > strlen (l:Line) &&
354    \ match (l:Line, '-- $') != -1 &&
355    \ match (&comments,'--') != -1
356      return "\<bs>\<bs>\<bs>"
357   else
358      return "\<bs>"
359   endif
360
361   return
362endfunction ada#InsertBackspace
363
364" Section: Insert Completions {{{1
365"
366" Section: ada#User_Complete(findstart, base) {{{2
367"
368" This function is used for the 'complete' option.
369"
370function! ada#User_Complete(findstart, base)
371   if a:findstart == 1
372      "
373      " locate the start of the word
374      "
375      let line = getline ('.')
376      let start = col ('.') - 1
377      while start > 0 && line[start - 1] =~ '\i\|'''
378	 let start -= 1
379      endwhile
380      return start
381   else
382      "
383      " look up matches
384      "
385      let l:Pattern = '^' . a:base . '.*$'
386      "
387      " add keywords
388      "
389      for Tag_Item in g:ada#Keywords
390	 if l:Tag_Item['word'] =~? l:Pattern
391	    if complete_add (l:Tag_Item) == 0
392	       return []
393	    endif
394	    if complete_check ()
395	       return []
396	    endif
397	 endif
398      endfor
399      return []
400   endif
401endfunction ada#User_Complete
402
403" Section: ada#Completion (cmd) {{{2
404"
405" Word completion (^N/^R/^X^]) - force '.' inclusion
406function ada#Completion (cmd)
407   set iskeyword+=46
408   return a:cmd . "\<C-R>=ada#Completion_End ()\<CR>"
409endfunction ada#Completion
410
411" Section: ada#Completion_End () {{{2
412"
413function ada#Completion_End ()
414   set iskeyword-=46
415   return ''
416endfunction ada#Completion_End
417
418" Section: ada#Create_Tags {{{1
419"
420function ada#Create_Tags (option)
421   if a:option == 'file'
422      let l:Filename = fnamemodify (bufname ('%'), ':p')
423   elseif a:option == 'dir'
424      let l:Filename =
425	 \ fnamemodify (bufname ('%'), ':p:h') . "*.ada " .
426	 \ fnamemodify (bufname ('%'), ':p:h') . "*.adb " .
427	 \ fnamemodify (bufname ('%'), ':p:h') . "*.ads"
428   else
429      let l:Filename = a:option
430   endif
431   execute '!ctags --excmd=number ' . l:Filename
432endfunction ada#Create_Tags
433
434" Section: ada#Switch_Session {{{1
435"
436function ada#Switch_Session (New_Session)
437   " 
438   " you should not save to much date into the seession since they will
439   " be sourced
440   "
441   let l:sessionoptions=&sessionoptions
442
443   try
444      set sessionoptions=buffers,curdir,folds,globals,resize,slash,tabpages,tabpages,unix,winpos,winsize
445
446      if a:New_Session != v:this_session
447	 "
448	 "  We actualy got a new session - otherwise there
449	 "  is nothing to do.
450	 "
451	 if strlen (v:this_session) > 0
452	    execute 'mksession! ' . v:this_session
453	 endif
454
455	 let v:this_session = a:New_Session
456
457	 "if filereadable (v:this_session)
458	    "execute 'source ' . v:this_session
459	 "endif
460
461	 augroup ada_session
462	    autocmd!
463	    autocmd VimLeavePre * execute 'mksession! ' . v:this_session
464	 augroup END
465	 
466	 "if exists ("g:Tlist_Auto_Open") && g:Tlist_Auto_Open
467	    "TlistOpen
468	 "endif
469
470      endif
471   finally
472      let &sessionoptions=l:sessionoptions
473   endtry
474
475   return
476endfunction ada#Switch_Session	
477
478" Section: GNAT Pretty Printer folding {{{1
479"
480if exists('g:ada_folding') && g:ada_folding[0] == 'g'
481   "
482   " Lines consisting only of ')' ';' are due to a gnat pretty bug and
483   " have the same level as the line above (can't happen in the first
484   " line).
485   "
486   let s:Fold_Collate = '^\([;)]*$\|'
487
488   "
489   " some lone statements are folded with the line above
490   "
491   if stridx (g:ada_folding, 'i') >= 0
492      let s:Fold_Collate .= '\s\+\<is\>$\|'
493   endif
494   if stridx (g:ada_folding, 'b') >= 0
495      let s:Fold_Collate .= '\s\+\<begin\>$\|'
496   endif
497   if stridx (g:ada_folding, 'p') >= 0
498      let s:Fold_Collate .= '\s\+\<private\>$\|'
499   endif
500   if stridx (g:ada_folding, 'x') >= 0
501      let s:Fold_Collate .= '\s\+\<exception\>$\|'
502   endif
503
504   " We also handle empty lines and
505   " comments here.
506   let s:Fold_Collate .= '--\)'
507
508   function ada#Pretty_Print_Folding (Line)			     " {{{2
509      let l:Text = getline (a:Line)
510
511      if l:Text =~ s:Fold_Collate
512	 "
513	 "  fold with line above
514	 "
515	 let l:Level = "="
516      elseif l:Text =~ '^\s\+('
517	 "
518	 " gnat outdents a line which stards with a ( by one characters so
519	 " that parameters which follow are aligned.
520	 "
521	 let l:Level = (indent (a:Line) + 1) / &shiftwidth
522      else
523	 let l:Level = indent (a:Line) / &shiftwidth
524      endif
525
526      return l:Level
527   endfunction ada#Pretty_Print_Folding				     " }}}2
528endif
529
530" Section: Options and Menus {{{1
531"
532" Section: ada#Switch_Syntax_Options {{{2
533"
534function ada#Switch_Syntax_Option (option)
535   syntax off
536   if exists ('g:ada_' . a:option)
537      unlet g:ada_{a:option}
538      echo  a:option . 'now off'
539   else
540      let g:ada_{a:option}=1
541      echo  a:option . 'now on'
542   endif
543   syntax on
544endfunction ada#Switch_Syntax_Option
545
546" Section: ada#Map_Menu {{{2
547"
548function ada#Map_Menu (Text, Keys, Command)
549   if a:Keys[0] == ':'
550      execute
551	\ "50amenu " .
552	\ "Ada."     . escape(a:Text, ' ') .
553	\ "<Tab>"    . a:Keys .
554	\ " :"	     . a:Command . "<CR>"
555      execute
556	\ "command -buffer " .
557	\ a:Keys[1:] .
558	\" :" . a:Command . "<CR>"
559   elseif a:Keys[0] == '<'
560      execute
561	\ "50amenu " .
562	\ "Ada."     . escape(a:Text, ' ') .
563	\ "<Tab>"    . a:Keys .
564	\ " :"	     . a:Command . "<CR>"
565      execute
566	\ "nnoremap <buffer> "	 .
567	\ a:Keys		 .
568	\" :" . a:Command . "<CR>"
569      execute
570	\ "inoremap <buffer> "	 .
571	\ a:Keys		 .
572	\" <C-O>:" . a:Command . "<CR>"
573   else
574      if exists("g:mapleader")
575         let l:leader = g:mapleader
576      else
577         let l:leader = '\'
578      endif
579      execute
580	\ "50amenu " .
581	\ "Ada."  . escape(a:Text, ' ') .
582	\ "<Tab>" . escape(l:leader . "a" . a:Keys , '\') .
583	\ " :"	  . a:Command . "<CR>"
584      execute
585	\ "nnoremap <buffer>" .
586	\ escape(l:leader . "a" . a:Keys , '\') .
587	\" :" . a:Command
588      execute
589	\ "inoremap <buffer>" .
590	\ escape(l:leader . "a" . a:Keys , '\') .
591	\" <C-O>:" . a:Command
592   endif
593   return
594endfunction
595
596" Section: ada#Map_Popup {{{2
597"
598function ada#Map_Popup (Text, Keys, Command)
599   if exists("g:mapleader")
600      let l:leader = g:mapleader
601   else
602      let l:leader = '\'
603   endif
604   execute
605     \ "50amenu " .
606     \ "PopUp."   . escape(a:Text, ' ') .
607     \ "<Tab>"	  . escape(l:leader . "a" . a:Keys , '\') .
608     \ " :"	  . a:Command . "<CR>"
609
610   call ada#Map_Menu (a:Text, a:Keys, a:Command)
611   return
612endfunction ada#Map_Popup
613
614" }}}1
615
616lockvar  g:ada#WordRegex
617lockvar  g:ada#DotWordRegex
618lockvar  g:ada#Comment
619lockvar! g:ada#Keywords
620lockvar! g:ada#Ctags_Kinds
621
622finish " 1}}}
623
624"------------------------------------------------------------------------------
625"   Copyright (C) 2006	Martin Krischik
626"
627"   Vim is Charityware - see ":help license" or uganda.txt for licence details.
628"------------------------------------------------------------------------------
629" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
630" vim: foldmethod=marker
631