diff --git a/vim-7.1-ada.patch b/vim-7.1-ada.patch new file mode 100644 index 0000000..ec4e837 --- /dev/null +++ b/vim-7.1-ada.patch @@ -0,0 +1,47357 @@ +diff -urN vim71/1/ada_options.vim vim71_ada/1/ada_options.vim +--- vim71/1/ada_options.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ada_options.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,105 @@ ++"------------------------------------------------------------------------------ ++" Description: Options setable by the Ada plugin ++" $Id: ada_options.vim 774 2007-09-17 09:11:59Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ada_options.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Folding for "gnat pretty" ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested to save on spaces ++" Usage: copy content into your .vimrc and change options to your ++" likeing. ++" Help Page: ft-ada-options ++"------------------------------------------------------------------------------ ++ ++echoerr 'It is suggested to copy the content of ada_options into .vimrc!' ++finish " 1}}} ++ ++" Section: Ada options {{{1 ++ ++ let g:ada_abbrev = 1 ++ let g:ada_default_compiler = 'gnat' ++ let g:ada_extended_tagging = 'list' ++ let g:ada_folding = 'i' ++" let g:ada_folding = 'gibxp' ++" let g:ada_folding = 'spftc' ++ let g:ada_rainbow_color = 1 ++ let g:ada_space_errors = 1 ++ let g:ada_standard_types = 1 ++ let g:ada_with_gnat_project_files = 1 ++" let g:ada_extended_completion = 1 ++" let g:ada_line_errors = 1 ++" let g:ada_omni_with_keywords = 1 ++ ++ let g:Tlist_Exit_OnlyWindow = 1 ++ let g:Tlist_File_Fold_Auto_Close = 1 ++ let g:Tlist_Sort_Type = "name" ++ ++ let g:NERD_use_ada_with_spaces = 1 ++ ++ let g:backup_directory = '.backups' ++ let g:backup_purge = 10 ++ ++ let g:mapleader = "" ++ ++ if &diff ++ let g:Tlist_Auto_Open = 0 ++ else ++ let g:Tlist_Auto_Open = 1 ++ endif ++ ++ filetype plugin indent on ++ syntax enable ++ ++" }}}1 ++ ++" Section: Vimball options {{{1 ++:set expandtab fileformat=unix encoding=utf-8 ++:.+2,.+13 MkVimball ada-4.5.0 ++ ++ada_options.vim ++autoload/ada.vim ++autoload/adacomplete.vim ++autoload/decada.vim ++autoload/gnat.vim ++compiler/decada.vim ++compiler/gnat.vim ++doc/ft_ada.txt ++ftdetect/ada.vim ++ftplugin/ada.vim ++indent/ada.vim ++syntax/ada.vim ++ ++" }}}1 ++ ++" Section: Tar options {{{1 ++ ++tar --create --bzip2 \ ++ --file="ada-4.5.0.tar.bz2" \ ++ autoload/ada.vim \ ++ autoload/adacomplete.vim \ ++ autoload/decada.vim \ ++ autoload/gnat.vim \ ++ compiler/decada.vim \ ++ compiler/gnat.vim \ ++ doc/ft_ada.txt \ ++ ftdetect/ada.vim \ ++ ftplugin/ada.vim \ ++ indent/ada.vim \ ++ syntax/ada.vim ; ++ ++" }}}1 ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: textwidth=0 foldmethod=marker foldmethod=marker +diff -urN vim71/1/autoload/adacomplete.vim vim71_ada/1/autoload/adacomplete.vim +--- vim71/1/autoload/adacomplete.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/adacomplete.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,109 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada omnicompletion file ++" Language: Ada (2005) ++" $Id: adacomplete.vim 825 2007-12-09 13:34:03Z krischik $ ++" Maintainer: Martin Krischik ++" $Author: krischik $ ++" $Date: 2007-12-09 14:34:03 +0100 (So, 09 Dez 2007) $ ++" Version: 4.5 ++" $Revision: 825 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/adacomplete.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK improved search for begin of word. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested agaist using setlocal omnifunc ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: ft-ada-omni ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++" Section: adacomplete#Complete () {{{1 ++" ++" This function is used for the 'omnifunc' option. ++" ++function! adacomplete#Complete (findstart, base) ++ if a:findstart == 1 ++ return ada#User_Complete (a:findstart, a:base) ++ else ++ " ++ " look up matches ++ " ++ if exists ("g:ada_omni_with_keywords") ++ call ada#User_Complete (a:findstart, a:base) ++ endif ++ " ++ " search tag file for matches ++ " ++ let l:Pattern = '^' . a:base . '.*$' ++ let l:Tag_List = taglist (l:Pattern) ++ " ++ " add symbols ++ " ++ for Tag_Item in l:Tag_List ++ if l:Tag_Item['kind'] == '' ++ " ++ " Tag created by gnat xref ++ " ++ let l:Match_Item = { ++ \ 'word': l:Tag_Item['name'], ++ \ 'menu': l:Tag_Item['filename'], ++ \ 'info': "Symbol from file " . l:Tag_Item['filename'] . " line " . l:Tag_Item['cmd'], ++ \ 'kind': 's', ++ \ 'icase': 1} ++ else ++ " ++ " Tag created by ctags ++ " ++ let l:Info = 'Symbol : ' . l:Tag_Item['name'] . "\n" ++ let l:Info .= 'Of type : ' . g:ada#Ctags_Kinds[l:Tag_Item['kind']][1] . "\n" ++ let l:Info .= 'Defined in File : ' . l:Tag_Item['filename'] . "\n" ++ ++ if has_key( l:Tag_Item, 'package') ++ let l:Info .= 'Package : ' . l:Tag_Item['package'] . "\n" ++ let l:Menu = l:Tag_Item['package'] ++ elseif has_key( l:Tag_Item, 'separate') ++ let l:Info .= 'Separate from Package : ' . l:Tag_Item['separate'] . "\n" ++ let l:Menu = l:Tag_Item['separate'] ++ elseif has_key( l:Tag_Item, 'packspec') ++ let l:Info .= 'Package Specification : ' . l:Tag_Item['packspec'] . "\n" ++ let l:Menu = l:Tag_Item['packspec'] ++ elseif has_key( l:Tag_Item, 'type') ++ let l:Info .= 'Datetype : ' . l:Tag_Item['type'] . "\n" ++ let l:Menu = l:Tag_Item['type'] ++ else ++ let l:Menu = l:Tag_Item['filename'] ++ endif ++ ++ let l:Match_Item = { ++ \ 'word': l:Tag_Item['name'], ++ \ 'menu': l:Menu, ++ \ 'info': l:Info, ++ \ 'kind': l:Tag_Item['kind'], ++ \ 'icase': 1} ++ endif ++ if complete_add (l:Match_Item) == 0 ++ return [] ++ endif ++ if complete_check () ++ return [] ++ endif ++ endfor ++ return [] ++ endif ++endfunction adacomplete#Complete ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/autoload/ada.vim vim71_ada/1/autoload/ada.vim +--- vim71/1/autoload/ada.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/ada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,624 @@ ++"------------------------------------------------------------------------------ ++" Description: Perform Ada specific completion & tagging. ++" Language: Ada (2005) ++" $Id: ada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Maintainer: Martin Krischik ++" Taylor Venable ++" Neil Bird ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK ' should not be in iskeyword. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Better folding. ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" 08.07.2007 TV fix mapleader problems. ++" 09.05.2007 MK Session just won't work no matter how much ++" tweaking is done ++" 19.09.2007 NO still some mapleader problems ++" Help Page: ft-ada-functions ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++" Section: Constants {{{1 ++" ++let g:ada#DotWordRegex = '\a\w*\(\_s*\.\_s*\a\w*\)*' ++let g:ada#WordRegex = '\a\w*' ++let g:ada#Comment = "\\v^(\"[^\"]*\"|'.'|[^\"']){-}\\zs\\s*--.*" ++let g:ada#Keywords = [] ++ ++" Section: g:ada#Keywords {{{1 ++" ++" Section: add Ada keywords {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'keyword', ++ \ 'info': 'Ada keyword.', ++ \ 'kind': 'k', ++ \ 'icase': 1}] ++endfor ++ ++" Section: GNAT Project Files {{{3 ++" ++if exists ('g:ada_with_gnat_project_files') ++ for Item in ['project'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'keyword', ++ \ 'info': 'GNAT projectfile keyword.', ++ \ 'kind': 'k', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add standart exception {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'exception', ++ \ 'info': 'Ada standart exception.', ++ \ 'kind': 'x', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT exception {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ for Item in ['Assert_Failure'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'exception', ++ \ 'info': 'GNAT exception.', ++ \ 'kind': 'x', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add Ada buildin types {{{2 ++" ++for Item in ['Boolean', 'Integer', 'Natural', 'Positive', 'Float', 'Character', 'Wide_Character', 'Wide_Wide_Character', 'String', 'Wide_String', 'Wide_Wide_String', 'Duration'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'type', ++ \ 'info': 'Ada buildin type.', ++ \ 'kind': 't', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT buildin types {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ for Item in ['Short_Integer', 'Short_Short_Integer', 'Long_Integer', 'Long_Long_Integer', 'Short_Float', 'Short_Short_Float', 'Long_Float', 'Long_Long_Float'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'type', ++ \ 'info': 'GNAT buildin type.', ++ \ 'kind': 't', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add Ada Attributes {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'attribute', ++ \ 'info': 'Ada attribute.', ++ \ 'kind': 'a', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT Attributes {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'attribute', ++ \ 'info': 'GNAT attribute.', ++ \ 'kind': 'a', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add Ada Pragmas {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'pragma', ++ \ 'info': 'Ada pragma.', ++ \ 'kind': 'p', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT Pragmas {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'pragma', ++ \ 'info': 'GNAT pragma.', ++ \ 'kind': 'p', ++ \ 'icase': 1}] ++ endfor ++endif ++" 1}}} ++ ++" Section: g:ada#Ctags_Kinds {{{1 ++" ++let g:ada#Ctags_Kinds = { ++ \ 'P': ["packspec", "package specifications"], ++ \ 'p': ["package", "packages"], ++ \ 'T': ["typespec", "type specifications"], ++ \ 't': ["type", "types"], ++ \ 'U': ["subspec", "subtype specifications"], ++ \ 'u': ["subtype", "subtypes"], ++ \ 'c': ["component", "record type components"], ++ \ 'l': ["literal", "enum type literals"], ++ \ 'V': ["varspec", "variable specifications"], ++ \ 'v': ["variable", "variables"], ++ \ 'f': ["formal", "generic formal parameters"], ++ \ 'n': ["constant", "constants"], ++ \ 'x': ["exception", "user defined exceptions"], ++ \ 'R': ["subprogspec", "subprogram specifications"], ++ \ 'r': ["subprogram", "subprograms"], ++ \ 'K': ["taskspec", "task specifications"], ++ \ 'k': ["task", "tasks"], ++ \ 'O': ["protectspec", "protected data specifications"], ++ \ 'o': ["protected", "protected data"], ++ \ 'E': ["entryspec", "task/protected data entry specifications"], ++ \ 'e': ["entry", "task/protected data entries"], ++ \ 'b': ["label", "labels"], ++ \ 'i': ["identifier", "loop/declare identifiers"], ++ \ 'a': ["autovar", "automatic variables"], ++ \ 'y': ["annon", "loops and blocks with no identifier"]} ++ ++" Section: ada#Word (...) {{{1 ++" ++" Extract current Ada word across multiple lines ++" AdaWord ([line, column])\ ++" ++function ada#Word (...) ++ if a:0 > 1 ++ let l:Line_Nr = a:1 ++ let l:Column_Nr = a:2 - 1 ++ else ++ let l:Line_Nr = line('.') ++ let l:Column_Nr = col('.') - 1 ++ endif ++ ++ let l:Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' ) ++ ++ " Cope with tag searching for items in comments; if we are, don't loop ++ " backards looking for previous lines ++ if l:Column_Nr > strlen(l:Line) ++ " We were in a comment ++ let l:Line = getline(l:Line_Nr) ++ let l:Search_Prev_Lines = 0 ++ else ++ let l:Search_Prev_Lines = 1 ++ endif ++ ++ " Go backwards until we find a match (Ada ID) that *doesn't* include our ++ " location - i.e., the previous ID. This is because the current 'correct' ++ " match will toggle matching/not matching as we traverse characters ++ " backwards. Thus, we have to find the previous unrelated match, exclude ++ " it, then use the next full match (ours). ++ " Remember to convert vim column 'l:Column_Nr' [1..n] to string offset [0..(n-1)] ++ " ... but start, here, one after the required char. ++ let l:New_Column = l:Column_Nr + 1 ++ while 1 ++ let l:New_Column = l:New_Column - 1 ++ if l:New_Column < 0 ++ " Have to include previous l:Line from file ++ let l:Line_Nr = l:Line_Nr - 1 ++ if l:Line_Nr < 1 || !l:Search_Prev_Lines ++ " Start of file or matching in a comment ++ let l:Line_Nr = 1 ++ let l:New_Column = 0 ++ let l:Our_Match = match (l:Line, g:ada#WordRegex ) ++ break ++ endif ++ " Get previous l:Line, and prepend it to our search string ++ let l:New_Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' ) ++ let l:New_Column = strlen (l:New_Line) - 1 ++ let l:Column_Nr = l:Column_Nr + l:New_Column ++ let l:Line = l:New_Line . l:Line ++ endif ++ " Check to see if this is a match excluding 'us' ++ let l:Match_End = l:New_Column + ++ \ matchend (strpart (l:Line,l:New_Column), g:ada#WordRegex ) - 1 ++ if l:Match_End >= l:New_Column && ++ \ l:Match_End < l:Column_Nr ++ " Yes ++ let l:Our_Match = l:Match_End+1 + ++ \ match (strpart (l:Line,l:Match_End+1), g:ada#WordRegex ) ++ break ++ endif ++ endwhile ++ ++ " Got anything? ++ if l:Our_Match < 0 ++ return '' ++ else ++ let l:Line = strpart (l:Line, l:Our_Match) ++ endif ++ ++ " Now simply add further lines until the match gets no bigger ++ let l:Match_String = matchstr (l:Line, g:ada#WordRegex) ++ let l:Last_Line = line ('$') ++ let l:Line_Nr = line ('.') + 1 ++ while l:Line_Nr <= l:Last_Line ++ let l:Last_Match = l:Match_String ++ let l:Line = l:Line . ++ \ substitute (getline (l:Line_Nr), g:ada#Comment, '', '') ++ let l:Match_String = matchstr (l:Line, g:ada#WordRegex) ++ if l:Match_String == l:Last_Match ++ break ++ endif ++ endwhile ++ ++ " Strip whitespace & return ++ return substitute (l:Match_String, '\s\+', '', 'g') ++endfunction ada#Word ++ ++" Section: ada#List_Tag (...) {{{1 ++" ++" List tags in quickfix window ++" ++function ada#List_Tag (...) ++ if a:0 > 1 ++ let l:Tag_Word = ada#Word (a:1, a:2) ++ elseif a:0 > 0 ++ let l:Tag_Word = a:1 ++ else ++ let l:Tag_Word = ada#Word () ++ endif ++ ++ echo "Searching for" l:Tag_Word ++ ++ let l:Pattern = '^' . l:Tag_Word . '$' ++ let l:Tag_List = taglist (l:Pattern) ++ let l:Error_List = [] ++ " ++ " add symbols ++ " ++ for Tag_Item in l:Tag_List ++ if l:Tag_Item['kind'] == '' ++ let l:Tag_Item['kind'] = 's' ++ endif ++ ++ let l:Error_List += [ ++ \ l:Tag_Item['filename'] . '|' . ++ \ l:Tag_Item['cmd'] . '|' . ++ \ l:Tag_Item['kind'] . "\t" . ++ \ l:Tag_Item['name'] ] ++ endfor ++ set errorformat=%f\|%l\|%m ++ cexpr l:Error_List ++ cwindow ++endfunction ada#List_Tag ++ ++" Section: ada#Jump_Tag (Word, Mode) {{{1 ++" ++" Word tag - include '.' and if Ada make uppercase ++" ++function ada#Jump_Tag (Word, Mode) ++ if a:Word == '' ++ " Get current word ++ let l:Word = ada#Word() ++ if l:Word == '' ++ throw "NOT_FOUND: no identifier found." ++ endif ++ else ++ let l:Word = a:Word ++ endif ++ ++ echo "Searching for " . l:Word ++ ++ try ++ execute a:Mode l:Word ++ catch /.*:E426:.*/ ++ let ignorecase = &ignorecase ++ set ignorecase ++ execute a:Mode l:Word ++ let &ignorecase = ignorecase ++ endtry ++ ++ return ++endfunction ada#Jump_Tag ++ ++" Section: ada#Insert_Backspace () {{{1 ++" ++" Backspace at end of line after auto-inserted commentstring '-- ' wipes it ++" ++function ada#Insert_Backspace () ++ let l:Line = getline ('.') ++ if col ('.') > strlen (l:Line) && ++ \ match (l:Line, '-- $') != -1 && ++ \ match (&comments,'--') != -1 ++ return "\\\" ++ else ++ return "\" ++ endif ++ ++ return ++endfunction ada#InsertBackspace ++ ++" Section: Insert Completions {{{1 ++" ++" Section: ada#User_Complete(findstart, base) {{{2 ++" ++" This function is used for the 'complete' option. ++" ++function! ada#User_Complete(findstart, base) ++ if a:findstart == 1 ++ " ++ " locate the start of the word ++ " ++ let line = getline ('.') ++ let start = col ('.') - 1 ++ while start > 0 && line[start - 1] =~ '\i\|''' ++ let start -= 1 ++ endwhile ++ return start ++ else ++ " ++ " look up matches ++ " ++ let l:Pattern = '^' . a:base . '.*$' ++ " ++ " add keywords ++ " ++ for Tag_Item in g:ada#Keywords ++ if l:Tag_Item['word'] =~? l:Pattern ++ if complete_add (l:Tag_Item) == 0 ++ return [] ++ endif ++ if complete_check () ++ return [] ++ endif ++ endif ++ endfor ++ return [] ++ endif ++endfunction ada#User_Complete ++ ++" Section: ada#Completion (cmd) {{{2 ++" ++" Word completion (^N/^R/^X^]) - force '.' inclusion ++function ada#Completion (cmd) ++ set iskeyword+=46 ++ return a:cmd . "\=ada#Completion_End ()\" ++endfunction ada#Completion ++ ++" Section: ada#Completion_End () {{{2 ++" ++function ada#Completion_End () ++ set iskeyword-=46 ++ return '' ++endfunction ada#Completion_End ++ ++" Section: ada#Create_Tags {{{1 ++" ++function ada#Create_Tags (option) ++ if a:option == 'file' ++ let l:Filename = fnamemodify (bufname ('%'), ':p') ++ elseif a:option == 'dir' ++ let l:Filename = ++ \ fnamemodify (bufname ('%'), ':p:h') . "*.ada " . ++ \ fnamemodify (bufname ('%'), ':p:h') . "*.adb " . ++ \ fnamemodify (bufname ('%'), ':p:h') . "*.ads" ++ else ++ let l:Filename = a:option ++ endif ++ execute '!ctags --excmd=number ' . l:Filename ++endfunction ada#Create_Tags ++ ++" Section: ada#Switch_Session {{{1 ++" ++function ada#Switch_Session (New_Session) ++ " ++ " you should not save to much date into the seession since they will ++ " be sourced ++ " ++ set sessionoptions=buffers,curdir,folds,globals,resize,slash,tabpages,tabpages,unix,winpos,winsize ++ ++ if a:New_Session != v:this_session ++ " ++ " We actualy got a new session - otherwise there ++ " is nothing to do. ++ " ++ if strlen (v:this_session) > 0 ++ execute 'mksession! ' . v:this_session ++ endif ++ ++ let v:this_session = a:New_Session ++ ++ "if filereadable (v:this_session) ++ "execute 'source ' . v:this_session ++ "endif ++ ++ augroup ada_session ++ autocmd! ++ autocmd VimLeavePre * execute 'mksession! ' . v:this_session ++ augroup END ++ " ++ "if exists ("g:Tlist_Auto_Open") && g:Tlist_Auto_Open ++ "TlistOpen ++ "endif ++ ++ endif ++ ++ return ++endfunction ada#Switch_Session ++ ++" Section: GNAT Pretty Printer folding {{{1 ++" ++if exists('g:ada_folding') && g:ada_folding[0] == 'g' ++ " ++ " Lines consisting only of ')' ';' are due to a gnat pretty bug and ++ " have the same level as the line above (can't happen in the first ++ " line). ++ " ++ let s:Fold_Collate = '^\([;)]*$\|' ++ ++ " ++ " some lone statements are folded with the line above ++ " ++ if stridx (g:ada_folding, 'i') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ if stridx (g:ada_folding, 'b') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ if stridx (g:ada_folding, 'p') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ if stridx (g:ada_folding, 'x') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ ++ " We also handle empty lines and ++ " comments here. ++ let s:Fold_Collate .= '--\)' ++ ++ function ada#Pretty_Print_Folding (Line) " {{{2 ++ let l:Text = getline (a:Line) ++ ++ if l:Text =~ s:Fold_Collate ++ " ++ " fold with line above ++ " ++ let l:Level = "=" ++ elseif l:Text =~ '^\s\+(' ++ " ++ " gnat outdents a line which stards with a ( by one characters so ++ " that parameters which follow are aligned. ++ " ++ let l:Level = (indent (a:Line) + 1) / &shiftwidth ++ else ++ let l:Level = indent (a:Line) / &shiftwidth ++ endif ++ ++ return l:Level ++ endfunction ada#Pretty_Print_Folding " }}}2 ++endif ++ ++" Section: Options and Menus {{{1 ++" ++" Section: ada#Switch_Syntax_Options {{{2 ++" ++function ada#Switch_Syntax_Option (option) ++ syntax off ++ if exists ('g:ada_' . a:option) ++ unlet g:ada_{a:option} ++ echo a:option . 'now off' ++ else ++ let g:ada_{a:option}=1 ++ echo a:option . 'now on' ++ endif ++ syntax on ++endfunction ada#Switch_Syntax_Option ++ ++" Section: ada#Map_Menu {{{2 ++" ++function ada#Map_Menu (Text, Keys, Command) ++ if a:Keys[0] == ':' ++ execute ++ \ "50amenu " . ++ \ "Ada." . escape(a:Text, ' ') . ++ \ "" . a:Keys . ++ \ " :" . a:Command . "" ++ execute ++ \ "command -buffer " . ++ \ a:Keys[1:] . ++ \" :" . a:Command . "" ++ elseif a:Keys[0] == '<' ++ execute ++ \ "50amenu " . ++ \ "Ada." . escape(a:Text, ' ') . ++ \ "" . a:Keys . ++ \ " :" . a:Command . "" ++ execute ++ \ "nnoremap " . ++ \ a:Keys . ++ \" :" . a:Command . "" ++ execute ++ \ "inoremap " . ++ \ a:Keys . ++ \" :" . a:Command . "" ++ else ++ if exists("g:mapleader") ++ let l:leader = g:mapleader ++ else ++ let l:leader = '\' ++ endif ++ execute ++ \ "50amenu " . ++ \ "Ada." . escape(a:Text, ' ') . ++ \ "" . escape(l:leader . "a" . a:Keys , '\') . ++ \ " :" . a:Command . "" ++ execute ++ \ "nnoremap " . ++ \ escape(l:leader . "a" . a:Keys , '\') . ++ \" :" . a:Command ++ execute ++ \ "inoremap " . ++ \ escape(l:leader . "a" . a:Keys , '\') . ++ \" :" . a:Command ++ endif ++ return ++endfunction ++ ++" Section: ada#Map_Popup {{{2 ++" ++function ada#Map_Popup (Text, Keys, Command) ++ if exists("g:mapleader") ++ let l:leader = g:mapleader ++ else ++ let l:leader = '\' ++ endif ++ execute ++ \ "50amenu " . ++ \ "PopUp." . escape(a:Text, ' ') . ++ \ "" . escape(l:leader . "a" . a:Keys , '\') . ++ \ " :" . a:Command . "" ++ ++ call ada#Map_Menu (a:Text, a:Keys, a:Command) ++ return ++endfunction ada#Map_Popup ++ ++" }}}1 ++ ++lockvar g:ada#WordRegex ++lockvar g:ada#DotWordRegex ++lockvar g:ada#Comment ++lockvar! g:ada#Keywords ++lockvar! g:ada#Ctags_Kinds ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/autoload/decada.vim vim71_ada/1/autoload/decada.vim +--- vim71/1/autoload/decada.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/decada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,75 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/Dec Ada compiler file ++" Language: Ada (Dec Ada) ++" $Id: decada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/decada.vim $ ++" History: 21.07.2006 MK New Dec Ada ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: compiler-decada ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++function decada#Unit_Name () dict " {{{1 ++ " Convert filename into acs unit: ++ " 1: remove the file extenstion. ++ " 2: replace all double '_' or '-' with an dot (which denotes a separate) ++ " 3: remove a trailing '_' (wich denotes a specification) ++ return substitute (substitute (expand ("%:t:r"), '__\|-', ".", "g"), '_$', "", '') ++endfunction decada#Unit_Name " }}}1 ++ ++function decada#Make () dict " {{{1 ++ let l:make_prg = substitute (g:self.Make_Command, '%<', self.Unit_Name(), '') ++ let &errorformat = g:self.Error_Format ++ let &makeprg = l:make_prg ++ wall ++ make ++ copen ++ set wrap ++ wincmd W ++endfunction decada#Build " }}}1 ++ ++function decada#Set_Session (...) dict " {{{1 ++ if a:0 > 0 ++ call ada#Switch_Session (a:1) ++ elseif argc() == 0 && strlen (v:servername) > 0 ++ call ada#Switch_Session ( ++ \ expand('~')[0:-2] . ".vimfiles.session]decada_" . ++ \ v:servername . ".vim") ++ endif ++ return ++endfunction decada#Set_Session " }}}1 ++ ++function decada#New () " }}}1 ++ let Retval = { ++ \ 'Make' : function ('decada#Make'), ++ \ 'Unit_Name' : function ('decada#Unit_Name'), ++ \ 'Set_Session' : function ('decada#Set_Session'), ++ \ 'Project_Dir' : '', ++ \ 'Make_Command' : 'ACS COMPILE /Wait /Log /NoPreLoad /Optimize=Development /Debug %<', ++ \ 'Error_Format' : '%+A%%ADAC-%t-%m,%C %#%m,%Zat line number %l in file %f,' . ++ \ '%+I%%ada-I-%m,%C %#%m,%Zat line number %l in file %f'} ++ ++ return Retval ++endfunction decada#New " }}}1 ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/autoload/gnat.vim vim71_ada/1/autoload/gnat.vim +--- vim71/1/autoload/gnat.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/gnat.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,147 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/GNAT compiler file ++" Language: Ada (GNAT) ++" $Id: gnat.vim 774 2007-09-17 09:11:59Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischi k ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/gnat.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 05.08.2006 MK Add session support ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" 19.09.2007 NO use project file only when there is a project ++" Help Page: compiler-gnat ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++function gnat#Make () dict " {{{1 ++ let &l:makeprg = self.Get_Command('Make') ++ let &l:errorformat = self.Error_Format ++ wall ++ make ++ copen ++ set wrap ++ wincmd W ++endfunction gnat#Make " }}}1 ++ ++function gnat#Pretty () dict " {{{1 ++ execute "!" . self.Get_Command('Pretty') ++endfunction gnat#Make " }}}1 ++ ++function gnat#Find () dict " {{{1 ++ execute "!" . self.Get_Command('Find') ++endfunction gnat#Find " }}}1 ++ ++function gnat#Tags () dict " {{{1 ++ execute "!" . self.Get_Command('Tags') ++ edit tags ++ call gnat#Insert_Tags_Header () ++ update ++ quit ++endfunction gnat#Tags " }}}1 ++ ++function gnat#Set_Project_File (...) dict " {{{1 ++ if a:0 > 0 ++ let self.Project_File = a:1 ++ ++ if ! filereadable (self.Project_File) ++ let self.Project_File = findfile ( ++ \ fnamemodify (self.Project_File, ':r'), ++ \ $ADA_PROJECT_PATH, ++ \ 1) ++ endif ++ elseif strlen (self.Project_File) > 0 ++ let self.Project_File = browse (0, 'GNAT Project File?', '', self.Project_File) ++ elseif expand ("%:e") == 'gpr' ++ let self.Project_File = browse (0, 'GNAT Project File?', '', expand ("%:e")) ++ else ++ let self.Project_File = browse (0, 'GNAT Project File?', '', 'default.gpr') ++ endif ++ ++ if strlen (v:this_session) > 0 ++ execute 'mksession! ' . v:this_session ++ endif ++ ++ "if strlen (self.Project_File) > 0 ++ "if has("vms") ++ "call ada#Switch_Session ( ++ "\ expand('~')[0:-2] . ".vimfiles.session]gnat_" . ++ "\ fnamemodify (self.Project_File, ":t:r") . ".vim") ++ "else ++ "call ada#Switch_Session ( ++ "\ expand('~') . "/vimfiles/session/gnat_" . ++ "\ fnamemodify (self.Project_File, ":t:r") . ".vim") ++ "endif ++ "else ++ "call ada#Switch_Session ('') ++ "endif ++ ++ return ++endfunction gnat#Set_Project_File " }}}1 ++ ++function gnat#Get_Command (Command) dict " {{{1 ++ let l:Command = eval ('self.' . a:Command . '_Command') ++ return eval (l:Command) ++endfunction gnat#Get_Command " }}}1 ++ ++function gnat#Set_Session (...) dict " {{{1 ++ if argc() == 1 && fnamemodify (argv(0), ':e') == 'gpr' ++ call self.Set_Project_File (argv(0)) ++ elseif strlen (v:servername) > 0 ++ call self.Set_Project_File (v:servername . '.gpr') ++ endif ++endfunction gnat#Set_Session " }}}1 ++ ++function gnat#New () " {{{1 ++ let l:Retval = { ++ \ 'Make' : function ('gnat#Make'), ++ \ 'Pretty' : function ('gnat#Pretty'), ++ \ 'Find' : function ('gnat#Find'), ++ \ 'Tags' : function ('gnat#Tags'), ++ \ 'Set_Project_File' : function ('gnat#Set_Project_File'), ++ \ 'Set_Session' : function ('gnat#Set_Session'), ++ \ 'Get_Command' : function ('gnat#Get_Command'), ++ \ 'Project_File' : '', ++ \ 'Make_Command' : '"gnat make -P " . self.Project_File . " -F -gnatef "', ++ \ 'Pretty_Command' : '"gnat pretty -P " . self.Project_File . " "', ++ \ 'Find_Program' : '"gnat find -P " . self.Project_File . " -F "', ++ \ 'Tags_Command' : '"gnat xref -P " . self.Project_File . " -v *.AD*"', ++ \ 'Error_Format' : '%f:%l:%c: %trror: %m,' . ++ \ '%f:%l:%c: %tarning: %m,' . ++ \ '%f:%l:%c: (%ttyle) %m'} ++ ++ return l:Retval ++endfunction gnat#New " }}}1 ++ ++function gnat#Insert_Tags_Header () " {{{1 ++ 1insert ++!_TAG_FILE_FORMAT 1 /extended format; --format=1 will not append ;" to lines/ ++!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ ++!_TAG_PROGRAM_AUTHOR AdaCore /info@adacore.com/ ++!_TAG_PROGRAM_NAME gnatxref // ++!_TAG_PROGRAM_URL http://www.adacore.com /official site/ ++!_TAG_PROGRAM_VERSION 5.05w // ++. ++ return ++endfunction gnat#Insert_Tags_Header " }}}1 ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=0 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/autoload/.svn/all-wcprops vim71_ada/1/autoload/.svn/all-wcprops +--- vim71/1/autoload/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,29 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 53 ++/svnroot/gnuada/!svn/ver/825/trunk/tools/vim/autoload ++END ++ada.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 61 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/autoload/ada.vim ++END ++gnat.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 62 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/autoload/gnat.vim ++END ++adacomplete.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/svnroot/gnuada/!svn/ver/825/trunk/tools/vim/autoload/adacomplete.vim ++END ++decada.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 64 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/autoload/decada.vim ++END +diff -urN vim71/1/autoload/.svn/dir-prop-base vim71_ada/1/autoload/.svn/dir-prop-base +--- vim71/1/autoload/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/autoload/.svn/entries vim71_ada/1/autoload/.svn/entries +--- vim71/1/autoload/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,80 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-12-09T13:34:03.484664Z ++825 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++ada.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++d052f84bf31bdcf8b2f2e3ad61717ad6 ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++gnat.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++e159890b42c4a6d597df518684074471 ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++adacomplete.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++93cc71b15159672b98a58fafd628840f ++2007-12-09T13:34:03.484664Z ++825 ++krischik ++has-props ++ ++decada.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++4547173c4d23fb524fa6763408c928cf ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ +diff -urN vim71/1/autoload/.svn/format vim71_ada/1/autoload/.svn/format +--- vim71/1/autoload/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/format 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/autoload/.svn/prop-base/adacomplete.vim.svn-base vim71_ada/1/autoload/.svn/prop-base/adacomplete.vim.svn-base +--- vim71/1/autoload/.svn/prop-base/adacomplete.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/prop-base/adacomplete.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/autoload/.svn/prop-base/ada.vim.svn-base vim71_ada/1/autoload/.svn/prop-base/ada.vim.svn-base +--- vim71/1/autoload/.svn/prop-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/prop-base/ada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/autoload/.svn/prop-base/decada.vim.svn-base vim71_ada/1/autoload/.svn/prop-base/decada.vim.svn-base +--- vim71/1/autoload/.svn/prop-base/decada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/prop-base/decada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/autoload/.svn/prop-base/gnat.vim.svn-base vim71_ada/1/autoload/.svn/prop-base/gnat.vim.svn-base +--- vim71/1/autoload/.svn/prop-base/gnat.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/prop-base/gnat.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/autoload/.svn/text-base/adacomplete.vim.svn-base vim71_ada/1/autoload/.svn/text-base/adacomplete.vim.svn-base +--- vim71/1/autoload/.svn/text-base/adacomplete.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/text-base/adacomplete.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,109 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada omnicompletion file ++" Language: Ada (2005) ++" $Id$ ++" Maintainer: Martin Krischik ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK improved search for begin of word. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested agaist using setlocal omnifunc ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: ft-ada-omni ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++" Section: adacomplete#Complete () {{{1 ++" ++" This function is used for the 'omnifunc' option. ++" ++function! adacomplete#Complete (findstart, base) ++ if a:findstart == 1 ++ return ada#User_Complete (a:findstart, a:base) ++ else ++ " ++ " look up matches ++ " ++ if exists ("g:ada_omni_with_keywords") ++ call ada#User_Complete (a:findstart, a:base) ++ endif ++ " ++ " search tag file for matches ++ " ++ let l:Pattern = '^' . a:base . '.*$' ++ let l:Tag_List = taglist (l:Pattern) ++ " ++ " add symbols ++ " ++ for Tag_Item in l:Tag_List ++ if l:Tag_Item['kind'] == '' ++ " ++ " Tag created by gnat xref ++ " ++ let l:Match_Item = { ++ \ 'word': l:Tag_Item['name'], ++ \ 'menu': l:Tag_Item['filename'], ++ \ 'info': "Symbol from file " . l:Tag_Item['filename'] . " line " . l:Tag_Item['cmd'], ++ \ 'kind': 's', ++ \ 'icase': 1} ++ else ++ " ++ " Tag created by ctags ++ " ++ let l:Info = 'Symbol : ' . l:Tag_Item['name'] . "\n" ++ let l:Info .= 'Of type : ' . g:ada#Ctags_Kinds[l:Tag_Item['kind']][1] . "\n" ++ let l:Info .= 'Defined in File : ' . l:Tag_Item['filename'] . "\n" ++ ++ if has_key( l:Tag_Item, 'package') ++ let l:Info .= 'Package : ' . l:Tag_Item['package'] . "\n" ++ let l:Menu = l:Tag_Item['package'] ++ elseif has_key( l:Tag_Item, 'separate') ++ let l:Info .= 'Separate from Package : ' . l:Tag_Item['separate'] . "\n" ++ let l:Menu = l:Tag_Item['separate'] ++ elseif has_key( l:Tag_Item, 'packspec') ++ let l:Info .= 'Package Specification : ' . l:Tag_Item['packspec'] . "\n" ++ let l:Menu = l:Tag_Item['packspec'] ++ elseif has_key( l:Tag_Item, 'type') ++ let l:Info .= 'Datetype : ' . l:Tag_Item['type'] . "\n" ++ let l:Menu = l:Tag_Item['type'] ++ else ++ let l:Menu = l:Tag_Item['filename'] ++ endif ++ ++ let l:Match_Item = { ++ \ 'word': l:Tag_Item['name'], ++ \ 'menu': l:Menu, ++ \ 'info': l:Info, ++ \ 'kind': l:Tag_Item['kind'], ++ \ 'icase': 1} ++ endif ++ if complete_add (l:Match_Item) == 0 ++ return [] ++ endif ++ if complete_check () ++ return [] ++ endif ++ endfor ++ return [] ++ endif ++endfunction adacomplete#Complete ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/autoload/.svn/text-base/ada.vim.svn-base vim71_ada/1/autoload/.svn/text-base/ada.vim.svn-base +--- vim71/1/autoload/.svn/text-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/text-base/ada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,624 @@ ++"------------------------------------------------------------------------------ ++" Description: Perform Ada specific completion & tagging. ++" Language: Ada (2005) ++" $Id$ ++" Maintainer: Martin Krischik ++" Taylor Venable ++" Neil Bird ++" Ned Okie ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK ' should not be in iskeyword. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Better folding. ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" 08.07.2007 TV fix mapleader problems. ++" 09.05.2007 MK Session just won't work no matter how much ++" tweaking is done ++" 19.09.2007 NO still some mapleader problems ++" Help Page: ft-ada-functions ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++" Section: Constants {{{1 ++" ++let g:ada#DotWordRegex = '\a\w*\(\_s*\.\_s*\a\w*\)*' ++let g:ada#WordRegex = '\a\w*' ++let g:ada#Comment = "\\v^(\"[^\"]*\"|'.'|[^\"']){-}\\zs\\s*--.*" ++let g:ada#Keywords = [] ++ ++" Section: g:ada#Keywords {{{1 ++" ++" Section: add Ada keywords {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'keyword', ++ \ 'info': 'Ada keyword.', ++ \ 'kind': 'k', ++ \ 'icase': 1}] ++endfor ++ ++" Section: GNAT Project Files {{{3 ++" ++if exists ('g:ada_with_gnat_project_files') ++ for Item in ['project'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'keyword', ++ \ 'info': 'GNAT projectfile keyword.', ++ \ 'kind': 'k', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add standart exception {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'exception', ++ \ 'info': 'Ada standart exception.', ++ \ 'kind': 'x', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT exception {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ for Item in ['Assert_Failure'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'exception', ++ \ 'info': 'GNAT exception.', ++ \ 'kind': 'x', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add Ada buildin types {{{2 ++" ++for Item in ['Boolean', 'Integer', 'Natural', 'Positive', 'Float', 'Character', 'Wide_Character', 'Wide_Wide_Character', 'String', 'Wide_String', 'Wide_Wide_String', 'Duration'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'type', ++ \ 'info': 'Ada buildin type.', ++ \ 'kind': 't', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT buildin types {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ for Item in ['Short_Integer', 'Short_Short_Integer', 'Long_Integer', 'Long_Long_Integer', 'Short_Float', 'Short_Short_Float', 'Long_Float', 'Long_Long_Float'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'type', ++ \ 'info': 'GNAT buildin type.', ++ \ 'kind': 't', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add Ada Attributes {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'attribute', ++ \ 'info': 'Ada attribute.', ++ \ 'kind': 'a', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT Attributes {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'attribute', ++ \ 'info': 'GNAT attribute.', ++ \ 'kind': 'a', ++ \ 'icase': 1}] ++ endfor ++endif ++ ++" Section: add Ada Pragmas {{{2 ++" ++for 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'pragma', ++ \ 'info': 'Ada pragma.', ++ \ 'kind': 'p', ++ \ 'icase': 1}] ++endfor ++ ++" Section: add GNAT Pragmas {{{3 ++" ++if exists ('g:ada_gnat_extensions') ++ 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'] ++ let g:ada#Keywords += [{ ++ \ 'word': Item, ++ \ 'menu': 'pragma', ++ \ 'info': 'GNAT pragma.', ++ \ 'kind': 'p', ++ \ 'icase': 1}] ++ endfor ++endif ++" 1}}} ++ ++" Section: g:ada#Ctags_Kinds {{{1 ++" ++let g:ada#Ctags_Kinds = { ++ \ 'P': ["packspec", "package specifications"], ++ \ 'p': ["package", "packages"], ++ \ 'T': ["typespec", "type specifications"], ++ \ 't': ["type", "types"], ++ \ 'U': ["subspec", "subtype specifications"], ++ \ 'u': ["subtype", "subtypes"], ++ \ 'c': ["component", "record type components"], ++ \ 'l': ["literal", "enum type literals"], ++ \ 'V': ["varspec", "variable specifications"], ++ \ 'v': ["variable", "variables"], ++ \ 'f': ["formal", "generic formal parameters"], ++ \ 'n': ["constant", "constants"], ++ \ 'x': ["exception", "user defined exceptions"], ++ \ 'R': ["subprogspec", "subprogram specifications"], ++ \ 'r': ["subprogram", "subprograms"], ++ \ 'K': ["taskspec", "task specifications"], ++ \ 'k': ["task", "tasks"], ++ \ 'O': ["protectspec", "protected data specifications"], ++ \ 'o': ["protected", "protected data"], ++ \ 'E': ["entryspec", "task/protected data entry specifications"], ++ \ 'e': ["entry", "task/protected data entries"], ++ \ 'b': ["label", "labels"], ++ \ 'i': ["identifier", "loop/declare identifiers"], ++ \ 'a': ["autovar", "automatic variables"], ++ \ 'y': ["annon", "loops and blocks with no identifier"]} ++ ++" Section: ada#Word (...) {{{1 ++" ++" Extract current Ada word across multiple lines ++" AdaWord ([line, column])\ ++" ++function ada#Word (...) ++ if a:0 > 1 ++ let l:Line_Nr = a:1 ++ let l:Column_Nr = a:2 - 1 ++ else ++ let l:Line_Nr = line('.') ++ let l:Column_Nr = col('.') - 1 ++ endif ++ ++ let l:Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' ) ++ ++ " Cope with tag searching for items in comments; if we are, don't loop ++ " backards looking for previous lines ++ if l:Column_Nr > strlen(l:Line) ++ " We were in a comment ++ let l:Line = getline(l:Line_Nr) ++ let l:Search_Prev_Lines = 0 ++ else ++ let l:Search_Prev_Lines = 1 ++ endif ++ ++ " Go backwards until we find a match (Ada ID) that *doesn't* include our ++ " location - i.e., the previous ID. This is because the current 'correct' ++ " match will toggle matching/not matching as we traverse characters ++ " backwards. Thus, we have to find the previous unrelated match, exclude ++ " it, then use the next full match (ours). ++ " Remember to convert vim column 'l:Column_Nr' [1..n] to string offset [0..(n-1)] ++ " ... but start, here, one after the required char. ++ let l:New_Column = l:Column_Nr + 1 ++ while 1 ++ let l:New_Column = l:New_Column - 1 ++ if l:New_Column < 0 ++ " Have to include previous l:Line from file ++ let l:Line_Nr = l:Line_Nr - 1 ++ if l:Line_Nr < 1 || !l:Search_Prev_Lines ++ " Start of file or matching in a comment ++ let l:Line_Nr = 1 ++ let l:New_Column = 0 ++ let l:Our_Match = match (l:Line, g:ada#WordRegex ) ++ break ++ endif ++ " Get previous l:Line, and prepend it to our search string ++ let l:New_Line = substitute (getline (l:Line_Nr), g:ada#Comment, '', '' ) ++ let l:New_Column = strlen (l:New_Line) - 1 ++ let l:Column_Nr = l:Column_Nr + l:New_Column ++ let l:Line = l:New_Line . l:Line ++ endif ++ " Check to see if this is a match excluding 'us' ++ let l:Match_End = l:New_Column + ++ \ matchend (strpart (l:Line,l:New_Column), g:ada#WordRegex ) - 1 ++ if l:Match_End >= l:New_Column && ++ \ l:Match_End < l:Column_Nr ++ " Yes ++ let l:Our_Match = l:Match_End+1 + ++ \ match (strpart (l:Line,l:Match_End+1), g:ada#WordRegex ) ++ break ++ endif ++ endwhile ++ ++ " Got anything? ++ if l:Our_Match < 0 ++ return '' ++ else ++ let l:Line = strpart (l:Line, l:Our_Match) ++ endif ++ ++ " Now simply add further lines until the match gets no bigger ++ let l:Match_String = matchstr (l:Line, g:ada#WordRegex) ++ let l:Last_Line = line ('$') ++ let l:Line_Nr = line ('.') + 1 ++ while l:Line_Nr <= l:Last_Line ++ let l:Last_Match = l:Match_String ++ let l:Line = l:Line . ++ \ substitute (getline (l:Line_Nr), g:ada#Comment, '', '') ++ let l:Match_String = matchstr (l:Line, g:ada#WordRegex) ++ if l:Match_String == l:Last_Match ++ break ++ endif ++ endwhile ++ ++ " Strip whitespace & return ++ return substitute (l:Match_String, '\s\+', '', 'g') ++endfunction ada#Word ++ ++" Section: ada#List_Tag (...) {{{1 ++" ++" List tags in quickfix window ++" ++function ada#List_Tag (...) ++ if a:0 > 1 ++ let l:Tag_Word = ada#Word (a:1, a:2) ++ elseif a:0 > 0 ++ let l:Tag_Word = a:1 ++ else ++ let l:Tag_Word = ada#Word () ++ endif ++ ++ echo "Searching for" l:Tag_Word ++ ++ let l:Pattern = '^' . l:Tag_Word . '$' ++ let l:Tag_List = taglist (l:Pattern) ++ let l:Error_List = [] ++ " ++ " add symbols ++ " ++ for Tag_Item in l:Tag_List ++ if l:Tag_Item['kind'] == '' ++ let l:Tag_Item['kind'] = 's' ++ endif ++ ++ let l:Error_List += [ ++ \ l:Tag_Item['filename'] . '|' . ++ \ l:Tag_Item['cmd'] . '|' . ++ \ l:Tag_Item['kind'] . "\t" . ++ \ l:Tag_Item['name'] ] ++ endfor ++ set errorformat=%f\|%l\|%m ++ cexpr l:Error_List ++ cwindow ++endfunction ada#List_Tag ++ ++" Section: ada#Jump_Tag (Word, Mode) {{{1 ++" ++" Word tag - include '.' and if Ada make uppercase ++" ++function ada#Jump_Tag (Word, Mode) ++ if a:Word == '' ++ " Get current word ++ let l:Word = ada#Word() ++ if l:Word == '' ++ throw "NOT_FOUND: no identifier found." ++ endif ++ else ++ let l:Word = a:Word ++ endif ++ ++ echo "Searching for " . l:Word ++ ++ try ++ execute a:Mode l:Word ++ catch /.*:E426:.*/ ++ let ignorecase = &ignorecase ++ set ignorecase ++ execute a:Mode l:Word ++ let &ignorecase = ignorecase ++ endtry ++ ++ return ++endfunction ada#Jump_Tag ++ ++" Section: ada#Insert_Backspace () {{{1 ++" ++" Backspace at end of line after auto-inserted commentstring '-- ' wipes it ++" ++function ada#Insert_Backspace () ++ let l:Line = getline ('.') ++ if col ('.') > strlen (l:Line) && ++ \ match (l:Line, '-- $') != -1 && ++ \ match (&comments,'--') != -1 ++ return "\\\" ++ else ++ return "\" ++ endif ++ ++ return ++endfunction ada#InsertBackspace ++ ++" Section: Insert Completions {{{1 ++" ++" Section: ada#User_Complete(findstart, base) {{{2 ++" ++" This function is used for the 'complete' option. ++" ++function! ada#User_Complete(findstart, base) ++ if a:findstart == 1 ++ " ++ " locate the start of the word ++ " ++ let line = getline ('.') ++ let start = col ('.') - 1 ++ while start > 0 && line[start - 1] =~ '\i\|''' ++ let start -= 1 ++ endwhile ++ return start ++ else ++ " ++ " look up matches ++ " ++ let l:Pattern = '^' . a:base . '.*$' ++ " ++ " add keywords ++ " ++ for Tag_Item in g:ada#Keywords ++ if l:Tag_Item['word'] =~? l:Pattern ++ if complete_add (l:Tag_Item) == 0 ++ return [] ++ endif ++ if complete_check () ++ return [] ++ endif ++ endif ++ endfor ++ return [] ++ endif ++endfunction ada#User_Complete ++ ++" Section: ada#Completion (cmd) {{{2 ++" ++" Word completion (^N/^R/^X^]) - force '.' inclusion ++function ada#Completion (cmd) ++ set iskeyword+=46 ++ return a:cmd . "\=ada#Completion_End ()\" ++endfunction ada#Completion ++ ++" Section: ada#Completion_End () {{{2 ++" ++function ada#Completion_End () ++ set iskeyword-=46 ++ return '' ++endfunction ada#Completion_End ++ ++" Section: ada#Create_Tags {{{1 ++" ++function ada#Create_Tags (option) ++ if a:option == 'file' ++ let l:Filename = fnamemodify (bufname ('%'), ':p') ++ elseif a:option == 'dir' ++ let l:Filename = ++ \ fnamemodify (bufname ('%'), ':p:h') . "*.ada " . ++ \ fnamemodify (bufname ('%'), ':p:h') . "*.adb " . ++ \ fnamemodify (bufname ('%'), ':p:h') . "*.ads" ++ else ++ let l:Filename = a:option ++ endif ++ execute '!ctags --excmd=number ' . l:Filename ++endfunction ada#Create_Tags ++ ++" Section: ada#Switch_Session {{{1 ++" ++function ada#Switch_Session (New_Session) ++ " ++ " you should not save to much date into the seession since they will ++ " be sourced ++ " ++ set sessionoptions=buffers,curdir,folds,globals,resize,slash,tabpages,tabpages,unix,winpos,winsize ++ ++ if a:New_Session != v:this_session ++ " ++ " We actualy got a new session - otherwise there ++ " is nothing to do. ++ " ++ if strlen (v:this_session) > 0 ++ execute 'mksession! ' . v:this_session ++ endif ++ ++ let v:this_session = a:New_Session ++ ++ "if filereadable (v:this_session) ++ "execute 'source ' . v:this_session ++ "endif ++ ++ augroup ada_session ++ autocmd! ++ autocmd VimLeavePre * execute 'mksession! ' . v:this_session ++ augroup END ++ " ++ "if exists ("g:Tlist_Auto_Open") && g:Tlist_Auto_Open ++ "TlistOpen ++ "endif ++ ++ endif ++ ++ return ++endfunction ada#Switch_Session ++ ++" Section: GNAT Pretty Printer folding {{{1 ++" ++if exists('g:ada_folding') && g:ada_folding[0] == 'g' ++ " ++ " Lines consisting only of ')' ';' are due to a gnat pretty bug and ++ " have the same level as the line above (can't happen in the first ++ " line). ++ " ++ let s:Fold_Collate = '^\([;)]*$\|' ++ ++ " ++ " some lone statements are folded with the line above ++ " ++ if stridx (g:ada_folding, 'i') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ if stridx (g:ada_folding, 'b') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ if stridx (g:ada_folding, 'p') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ if stridx (g:ada_folding, 'x') >= 0 ++ let s:Fold_Collate .= '\s\+\$\|' ++ endif ++ ++ " We also handle empty lines and ++ " comments here. ++ let s:Fold_Collate .= '--\)' ++ ++ function ada#Pretty_Print_Folding (Line) " {{{2 ++ let l:Text = getline (a:Line) ++ ++ if l:Text =~ s:Fold_Collate ++ " ++ " fold with line above ++ " ++ let l:Level = "=" ++ elseif l:Text =~ '^\s\+(' ++ " ++ " gnat outdents a line which stards with a ( by one characters so ++ " that parameters which follow are aligned. ++ " ++ let l:Level = (indent (a:Line) + 1) / &shiftwidth ++ else ++ let l:Level = indent (a:Line) / &shiftwidth ++ endif ++ ++ return l:Level ++ endfunction ada#Pretty_Print_Folding " }}}2 ++endif ++ ++" Section: Options and Menus {{{1 ++" ++" Section: ada#Switch_Syntax_Options {{{2 ++" ++function ada#Switch_Syntax_Option (option) ++ syntax off ++ if exists ('g:ada_' . a:option) ++ unlet g:ada_{a:option} ++ echo a:option . 'now off' ++ else ++ let g:ada_{a:option}=1 ++ echo a:option . 'now on' ++ endif ++ syntax on ++endfunction ada#Switch_Syntax_Option ++ ++" Section: ada#Map_Menu {{{2 ++" ++function ada#Map_Menu (Text, Keys, Command) ++ if a:Keys[0] == ':' ++ execute ++ \ "50amenu " . ++ \ "Ada." . escape(a:Text, ' ') . ++ \ "" . a:Keys . ++ \ " :" . a:Command . "" ++ execute ++ \ "command -buffer " . ++ \ a:Keys[1:] . ++ \" :" . a:Command . "" ++ elseif a:Keys[0] == '<' ++ execute ++ \ "50amenu " . ++ \ "Ada." . escape(a:Text, ' ') . ++ \ "" . a:Keys . ++ \ " :" . a:Command . "" ++ execute ++ \ "nnoremap " . ++ \ a:Keys . ++ \" :" . a:Command . "" ++ execute ++ \ "inoremap " . ++ \ a:Keys . ++ \" :" . a:Command . "" ++ else ++ if exists("g:mapleader") ++ let l:leader = g:mapleader ++ else ++ let l:leader = '\' ++ endif ++ execute ++ \ "50amenu " . ++ \ "Ada." . escape(a:Text, ' ') . ++ \ "" . escape(l:leader . "a" . a:Keys , '\') . ++ \ " :" . a:Command . "" ++ execute ++ \ "nnoremap " . ++ \ escape(l:leader . "a" . a:Keys , '\') . ++ \" :" . a:Command ++ execute ++ \ "inoremap " . ++ \ escape(l:leader . "a" . a:Keys , '\') . ++ \" :" . a:Command ++ endif ++ return ++endfunction ++ ++" Section: ada#Map_Popup {{{2 ++" ++function ada#Map_Popup (Text, Keys, Command) ++ if exists("g:mapleader") ++ let l:leader = g:mapleader ++ else ++ let l:leader = '\' ++ endif ++ execute ++ \ "50amenu " . ++ \ "PopUp." . escape(a:Text, ' ') . ++ \ "" . escape(l:leader . "a" . a:Keys , '\') . ++ \ " :" . a:Command . "" ++ ++ call ada#Map_Menu (a:Text, a:Keys, a:Command) ++ return ++endfunction ada#Map_Popup ++ ++" }}}1 ++ ++lockvar g:ada#WordRegex ++lockvar g:ada#DotWordRegex ++lockvar g:ada#Comment ++lockvar! g:ada#Keywords ++lockvar! g:ada#Ctags_Kinds ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/autoload/.svn/text-base/decada.vim.svn-base vim71_ada/1/autoload/.svn/text-base/decada.vim.svn-base +--- vim71/1/autoload/.svn/text-base/decada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/text-base/decada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,75 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/Dec Ada compiler file ++" Language: Ada (Dec Ada) ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 21.07.2006 MK New Dec Ada ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: compiler-decada ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++function decada#Unit_Name () dict " {{{1 ++ " Convert filename into acs unit: ++ " 1: remove the file extenstion. ++ " 2: replace all double '_' or '-' with an dot (which denotes a separate) ++ " 3: remove a trailing '_' (wich denotes a specification) ++ return substitute (substitute (expand ("%:t:r"), '__\|-', ".", "g"), '_$', "", '') ++endfunction decada#Unit_Name " }}}1 ++ ++function decada#Make () dict " {{{1 ++ let l:make_prg = substitute (g:self.Make_Command, '%<', self.Unit_Name(), '') ++ let &errorformat = g:self.Error_Format ++ let &makeprg = l:make_prg ++ wall ++ make ++ copen ++ set wrap ++ wincmd W ++endfunction decada#Build " }}}1 ++ ++function decada#Set_Session (...) dict " {{{1 ++ if a:0 > 0 ++ call ada#Switch_Session (a:1) ++ elseif argc() == 0 && strlen (v:servername) > 0 ++ call ada#Switch_Session ( ++ \ expand('~')[0:-2] . ".vimfiles.session]decada_" . ++ \ v:servername . ".vim") ++ endif ++ return ++endfunction decada#Set_Session " }}}1 ++ ++function decada#New () " }}}1 ++ let Retval = { ++ \ 'Make' : function ('decada#Make'), ++ \ 'Unit_Name' : function ('decada#Unit_Name'), ++ \ 'Set_Session' : function ('decada#Set_Session'), ++ \ 'Project_Dir' : '', ++ \ 'Make_Command' : 'ACS COMPILE /Wait /Log /NoPreLoad /Optimize=Development /Debug %<', ++ \ 'Error_Format' : '%+A%%ADAC-%t-%m,%C %#%m,%Zat line number %l in file %f,' . ++ \ '%+I%%ada-I-%m,%C %#%m,%Zat line number %l in file %f'} ++ ++ return Retval ++endfunction decada#New " }}}1 ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/autoload/.svn/text-base/gnat.vim.svn-base vim71_ada/1/autoload/.svn/text-base/gnat.vim.svn-base +--- vim71/1/autoload/.svn/text-base/gnat.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/autoload/.svn/text-base/gnat.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,147 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/GNAT compiler file ++" Language: Ada (GNAT) ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischi k ++" Ned Okie ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 05.08.2006 MK Add session support ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" 19.09.2007 NO use project file only when there is a project ++" Help Page: compiler-gnat ++"------------------------------------------------------------------------------ ++ ++if version < 700 ++ finish ++endif ++ ++function gnat#Make () dict " {{{1 ++ let &l:makeprg = self.Get_Command('Make') ++ let &l:errorformat = self.Error_Format ++ wall ++ make ++ copen ++ set wrap ++ wincmd W ++endfunction gnat#Make " }}}1 ++ ++function gnat#Pretty () dict " {{{1 ++ execute "!" . self.Get_Command('Pretty') ++endfunction gnat#Make " }}}1 ++ ++function gnat#Find () dict " {{{1 ++ execute "!" . self.Get_Command('Find') ++endfunction gnat#Find " }}}1 ++ ++function gnat#Tags () dict " {{{1 ++ execute "!" . self.Get_Command('Tags') ++ edit tags ++ call gnat#Insert_Tags_Header () ++ update ++ quit ++endfunction gnat#Tags " }}}1 ++ ++function gnat#Set_Project_File (...) dict " {{{1 ++ if a:0 > 0 ++ let self.Project_File = a:1 ++ ++ if ! filereadable (self.Project_File) ++ let self.Project_File = findfile ( ++ \ fnamemodify (self.Project_File, ':r'), ++ \ $ADA_PROJECT_PATH, ++ \ 1) ++ endif ++ elseif strlen (self.Project_File) > 0 ++ let self.Project_File = browse (0, 'GNAT Project File?', '', self.Project_File) ++ elseif expand ("%:e") == 'gpr' ++ let self.Project_File = browse (0, 'GNAT Project File?', '', expand ("%:e")) ++ else ++ let self.Project_File = browse (0, 'GNAT Project File?', '', 'default.gpr') ++ endif ++ ++ if strlen (v:this_session) > 0 ++ execute 'mksession! ' . v:this_session ++ endif ++ ++ "if strlen (self.Project_File) > 0 ++ "if has("vms") ++ "call ada#Switch_Session ( ++ "\ expand('~')[0:-2] . ".vimfiles.session]gnat_" . ++ "\ fnamemodify (self.Project_File, ":t:r") . ".vim") ++ "else ++ "call ada#Switch_Session ( ++ "\ expand('~') . "/vimfiles/session/gnat_" . ++ "\ fnamemodify (self.Project_File, ":t:r") . ".vim") ++ "endif ++ "else ++ "call ada#Switch_Session ('') ++ "endif ++ ++ return ++endfunction gnat#Set_Project_File " }}}1 ++ ++function gnat#Get_Command (Command) dict " {{{1 ++ let l:Command = eval ('self.' . a:Command . '_Command') ++ return eval (l:Command) ++endfunction gnat#Get_Command " }}}1 ++ ++function gnat#Set_Session (...) dict " {{{1 ++ if argc() == 1 && fnamemodify (argv(0), ':e') == 'gpr' ++ call self.Set_Project_File (argv(0)) ++ elseif strlen (v:servername) > 0 ++ call self.Set_Project_File (v:servername . '.gpr') ++ endif ++endfunction gnat#Set_Session " }}}1 ++ ++function gnat#New () " {{{1 ++ let l:Retval = { ++ \ 'Make' : function ('gnat#Make'), ++ \ 'Pretty' : function ('gnat#Pretty'), ++ \ 'Find' : function ('gnat#Find'), ++ \ 'Tags' : function ('gnat#Tags'), ++ \ 'Set_Project_File' : function ('gnat#Set_Project_File'), ++ \ 'Set_Session' : function ('gnat#Set_Session'), ++ \ 'Get_Command' : function ('gnat#Get_Command'), ++ \ 'Project_File' : '', ++ \ 'Make_Command' : '"gnat make -P " . self.Project_File . " -F -gnatef "', ++ \ 'Pretty_Command' : '"gnat pretty -P " . self.Project_File . " "', ++ \ 'Find_Program' : '"gnat find -P " . self.Project_File . " -F "', ++ \ 'Tags_Command' : '"gnat xref -P " . self.Project_File . " -v *.AD*"', ++ \ 'Error_Format' : '%f:%l:%c: %trror: %m,' . ++ \ '%f:%l:%c: %tarning: %m,' . ++ \ '%f:%l:%c: (%ttyle) %m'} ++ ++ return l:Retval ++endfunction gnat#New " }}}1 ++ ++function gnat#Insert_Tags_Header () " {{{1 ++ 1insert ++!_TAG_FILE_FORMAT 1 /extended format; --format=1 will not append ;" to lines/ ++!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ ++!_TAG_PROGRAM_AUTHOR AdaCore /info@adacore.com/ ++!_TAG_PROGRAM_NAME gnatxref // ++!_TAG_PROGRAM_URL http://www.adacore.com /official site/ ++!_TAG_PROGRAM_VERSION 5.05w // ++. ++ return ++endfunction gnat#Insert_Tags_Header " }}}1 ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=0 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/colors/.svn/all-wcprops vim71_ada/1/colors/.svn/all-wcprops +--- vim71/1/colors/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/colors/.svn/all-wcprops 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,5 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 51 ++/svnroot/gnuada/!svn/ver/818/trunk/tools/vim/colors ++END +diff -urN vim71/1/colors/.svn/dir-prop-base vim71_ada/1/colors/.svn/dir-prop-base +--- vim71/1/colors/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/colors/.svn/dir-prop-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/colors/.svn/entries vim71_ada/1/colors/.svn/entries +--- vim71/1/colors/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/colors/.svn/entries 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,28 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/colors ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-12-03T21:21:48.223203Z ++818 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ +diff -urN vim71/1/colors/.svn/format vim71_ada/1/colors/.svn/format +--- vim71/1/colors/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/colors/.svn/format 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/compiler/decada.vim vim71_ada/1/compiler/decada.vim +--- vim71/1/compiler/decada.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/decada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,55 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/Dec Ada compiler file ++" Language: Ada (Dec Ada) ++" $Id: decada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/decada.vim $ ++" History: 21.07.2006 MK New Dec Ada ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 08.09.2006 MK Correct double load protection. ++" Help Page: compiler-decada ++"------------------------------------------------------------------------------ ++ ++if (exists("current_compiler") && ++ \ current_compiler == "decada") || ++ \ version < 700 ++ finish ++endif ++ ++let current_compiler = "decada" ++ ++if !exists("g:decada") ++ let g:decada = decada#New () ++ ++ call ada#Map_Menu ( ++ \'Dec Ada.Build', ++ \'', ++ \'call decada.Make ()') ++ ++ call g:decada.Set_Session () ++endif ++ ++if exists(":CompilerSet") != 2 ++ " ++ " plugin loaded by other means then the "compiler" command ++ " ++ command -nargs=* CompilerSet setlocal ++endif ++ ++execute "CompilerSet makeprg=" . escape (g:decada.Make_Command, ' ') ++execute "CompilerSet errorformat=" . escape (g:decada.Error_Format, ' ') ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/compiler/gnat.vim vim71_ada/1/compiler/gnat.vim +--- vim71/1/compiler/gnat.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/gnat.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,73 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/GNAT compiler file ++" Language: Ada (GNAT) ++" $Id: gnat.vim 774 2007-09-17 09:11:59Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischi k ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/gnat.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 19.09.2007 NO use project file only when there is a project ++" Help Page: compiler-gnat ++"------------------------------------------------------------------------------ ++ ++if (exists("current_compiler") && ++ \ current_compiler == "gnat") || ++ \ version < 700 ++ finish ++endif ++ ++let current_compiler = "gnat" ++ ++if !exists("g:gnat") ++ let g:gnat = gnat#New () ++ ++ call ada#Map_Menu ( ++ \ 'GNAT.Build', ++ \ '', ++ \ 'call gnat.Make ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Pretty Print', ++ \ ':GnatPretty', ++ \ 'call gnat.Pretty ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Tags', ++ \ ':GnatTags', ++ \ 'call gnat.Tags ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Find', ++ \ ':GnatFind', ++ \ 'call gnat.Find ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Set Projectfile\.\.\.', ++ \ ':SetProject', ++ \ 'call gnat.Set_Project_File ()') ++ ++ call g:gnat.Set_Session () ++endif ++ ++if exists(":CompilerSet") != 2 ++ " ++ " plugin loaded by other means then the "compiler" command ++ " ++ command -nargs=* CompilerSet setlocal ++endif ++ ++execute "CompilerSet makeprg=" . escape (g:gnat.Get_Command('Make'), ' ') ++execute "CompilerSet errorformat=" . escape (g:gnat.Error_Format, ' ') ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=0 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/compiler/.svn/all-wcprops vim71_ada/1/compiler/.svn/all-wcprops +--- vim71/1/compiler/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 53 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/compiler ++END ++gnat.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 62 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/compiler/gnat.vim ++END ++decada.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 64 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/compiler/decada.vim ++END +diff -urN vim71/1/compiler/.svn/dir-prop-base vim71_ada/1/compiler/.svn/dir-prop-base +--- vim71/1/compiler/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/compiler/.svn/entries vim71_ada/1/compiler/.svn/entries +--- vim71/1/compiler/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,54 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++gnat.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++1429fc395240f10289ac4836746ac1ba ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++decada.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++5c01783740adbd6492b7197377e85d74 ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ +diff -urN vim71/1/compiler/.svn/format vim71_ada/1/compiler/.svn/format +--- vim71/1/compiler/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/format 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/compiler/.svn/prop-base/decada.vim.svn-base vim71_ada/1/compiler/.svn/prop-base/decada.vim.svn-base +--- vim71/1/compiler/.svn/prop-base/decada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/prop-base/decada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/compiler/.svn/prop-base/gnat.vim.svn-base vim71_ada/1/compiler/.svn/prop-base/gnat.vim.svn-base +--- vim71/1/compiler/.svn/prop-base/gnat.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/prop-base/gnat.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/compiler/.svn/text-base/decada.vim.svn-base vim71_ada/1/compiler/.svn/text-base/decada.vim.svn-base +--- vim71/1/compiler/.svn/text-base/decada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/text-base/decada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,55 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/Dec Ada compiler file ++" Language: Ada (Dec Ada) ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 21.07.2006 MK New Dec Ada ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 08.09.2006 MK Correct double load protection. ++" Help Page: compiler-decada ++"------------------------------------------------------------------------------ ++ ++if (exists("current_compiler") && ++ \ current_compiler == "decada") || ++ \ version < 700 ++ finish ++endif ++ ++let current_compiler = "decada" ++ ++if !exists("g:decada") ++ let g:decada = decada#New () ++ ++ call ada#Map_Menu ( ++ \'Dec Ada.Build', ++ \'', ++ \'call decada.Make ()') ++ ++ call g:decada.Set_Session () ++endif ++ ++if exists(":CompilerSet") != 2 ++ " ++ " plugin loaded by other means then the "compiler" command ++ " ++ command -nargs=* CompilerSet setlocal ++endif ++ ++execute "CompilerSet makeprg=" . escape (g:decada.Make_Command, ' ') ++execute "CompilerSet errorformat=" . escape (g:decada.Error_Format, ' ') ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/compiler/.svn/text-base/gnat.vim.svn-base vim71_ada/1/compiler/.svn/text-base/gnat.vim.svn-base +--- vim71/1/compiler/.svn/text-base/gnat.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/compiler/.svn/text-base/gnat.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,73 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada/GNAT compiler file ++" Language: Ada (GNAT) ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischi k ++" Ned Okie ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 19.09.2007 NO use project file only when there is a project ++" Help Page: compiler-gnat ++"------------------------------------------------------------------------------ ++ ++if (exists("current_compiler") && ++ \ current_compiler == "gnat") || ++ \ version < 700 ++ finish ++endif ++ ++let current_compiler = "gnat" ++ ++if !exists("g:gnat") ++ let g:gnat = gnat#New () ++ ++ call ada#Map_Menu ( ++ \ 'GNAT.Build', ++ \ '', ++ \ 'call gnat.Make ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Pretty Print', ++ \ ':GnatPretty', ++ \ 'call gnat.Pretty ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Tags', ++ \ ':GnatTags', ++ \ 'call gnat.Tags ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Find', ++ \ ':GnatFind', ++ \ 'call gnat.Find ()') ++ call ada#Map_Menu ( ++ \ 'GNAT.Set Projectfile\.\.\.', ++ \ ':SetProject', ++ \ 'call gnat.Set_Project_File ()') ++ ++ call g:gnat.Set_Session () ++endif ++ ++if exists(":CompilerSet") != 2 ++ " ++ " plugin loaded by other means then the "compiler" command ++ " ++ command -nargs=* CompilerSet setlocal ++endif ++ ++execute "CompilerSet makeprg=" . escape (g:gnat.Get_Command('Make'), ' ') ++execute "CompilerSet errorformat=" . escape (g:gnat.Error_Format, ' ') ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=0 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/doc/ft_ada.txt vim71_ada/1/doc/ft_ada.txt +--- vim71/1/doc/ft_ada.txt 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/ft_ada.txt 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,516 @@ ++*ft_ada.txt* Ada File type Plug-ins Last change: 2007 Seb 17 ++ ++ ++ ADA FILE TYPE PLUG-INS REFERENCE MANUAL~ ++ ++ADA *ada.vim* ++ ++1. Syntax Highlighting |ft-ada-syntax| ++2. Plug-in |ft-ada-plugin| ++3. Omni Completion |ft-ada-omni| ++ 3.1 Omni Completion with "gnat xref" |gnat-xref| ++ 3.2 Omni Completion with "ctags" |ada-ctags| ++4. Compiler Support |ada-compiler| ++ 4.1 GNAT |compiler-gnat| ++ 4.1 Dec Ada |compiler-decada| ++5. References |ada-reference| ++ 5.1 Options |ft-ada-options| ++ 5.2 Functions |ft-ada-functions| ++ 5.3 Commands |ft-ada-commands| ++ 5.4 Variables |ft-ada-variables| ++ 5.5 Constants |ft-ada-contstants| ++8. Extra Plug-ins |ada-extra-plugins| ++ ++============================================================================== ++1. Syntax Highlighting ~ ++ *ft-ada-syntax* ++ ++This mode is designed for the 2005 edition of Ada ("Ada 2005"), which includes ++support for objected-programming, protected types, and so on. It handles code ++written for the original Ada language ("Ada83", "Ada87", "Ada95") as well, ++though code which uses Ada 2005-only keywords will be wrongly colored (such ++code should be fixed anyway). For more information about Ada, see ++http://www.adapower.com. ++ ++The Ada mode handles a number of situations cleanly. ++ ++For example, it knows that the "-" in "-5" is a number, but the same character ++in "A-5" is an operator. Normally, a "with" or "use" clause referencing ++another compilation unit is coloured the same way as C's "#include" is coloured. ++If you have "Conditional" or "Repeat" groups coloured differently, then "end ++if" and "end loop" will be coloured as part of those respective groups. ++ ++You can set these to different colours using vim's "highlight" command (e.g., ++to change how loops are displayed, enter the command ":hi Repeat" followed by ++the colour specification; on simple terminals the colour specification ++ctermfg=White often shows well). ++ ++There are several options you can select in this Ada mode. See|ft-ada-options| ++for a complete list. ++ ++To enable them, assign a value to the option. For example, to turn one on: ++ > ++ > let g:ada_standard_types = 1 ++> ++To disable them use ":unlet". Example: ++> ++ > unlet g:ada_standard_types ++ ++You can just use ":" and type these into the command line to set these ++temporarily before loading an Ada file. You can make these option settings ++permanent by adding the "let" command(s), without a colon, to your "~/.vimrc" ++file. ++ ++Even on a slow (90Mhz) PC this mode works quickly, but if you find the ++performance unacceptable, turn on |g:ada_withuse_ordinary|. ++ ++Syntax folding instructions (|fold-syntax|) are added when |g:ada_folding| is ++set. ++ ++============================================================================== ++2. File type Plug-in ~ ++ *ft-ada-indent* *ft-ada-plugin* ++ ++The Ada plug-in provides support for: ++ ++ - auto indenting (|indent.txt|) ++ - insert completion (|i_CTRL-N|) ++ - user completion (|i_CTRL-X_CTRL-U|) ++ - tag searches (|tagsrch.txt|) ++ - Quick Fix (|quickfix.txt|) ++ - backspace handling (|'backspace'|) ++ - comment handling (|'comments'|, |'commentstring'|) ++ ++The plug-in only activates the features of the Ada mode whenever an Ada ++files is opened and add adds Ada related entries to the main and pop-up menu. ++ ++============================================================================== ++3. Omni Completion ~ ++ *ft-ada-omni* ++ ++The Ada omni-completions (|i_CTRL-X_CTRL-O|) uses tags database created either ++by "gnat xref -v" or the "exuberant Ctags (http://ctags.sourceforge.net). The ++complete function will automatically detect which tool was used to create the ++tags file. ++ ++------------------------------------------------------------------------------ ++3.1 Omni Completion with "gnat xref" ~ ++ *gnat-xref* ++ ++GNAT XREF uses the compiler internal information (ali-files) to produce the ++tags file. This has the advantage to be 100% correct and the option of deep ++nested analysis. However the code must compile, the generator is quite ++slow and the created tags file contains only the basic Ctags information for ++each entry - not enough for some of the more advanced Vim code browser ++plug-ins. ++ ++NOTE: "gnat xref -v" is very tricky to use as it has almost no diagnostic ++ output - If nothing is printed then usually the parameters are wrong. ++ Here some important tips: ++ ++1) You need to compile your code first and use the "-aO" option to point to ++ your .ali files. ++2) "gnat xref -v ../Include/adacl.ads" won't work - use the "gnat xref -v ++ -aI../Include adacl.ads" instead. ++3) "gnat xref -v -aI../Include *.ad?" won't work - use "cd ../Include" and ++ then "gnat xref -v *.ad?" ++4) Project manager support is completely broken - don't even try "gnat xref ++ -Padacl.gpr". ++5) VIM is faster when the tags file is sorted - use "sort --unique ++ --ignore-case --output=tags tags" . ++6) Remember to insert "!_TAG_FILE_SORTED 2 %sort ui" as first line to mark ++ the file assorted. ++ ++------------------------------------------------------------------------------ ++3.2 Omni Completion with "ctags"~ ++ *ada-ctags* ++ ++Exuberant Ctags uses it's own multi-language code parser. The parser is quite ++fast, produces a lot of extra informations (hence the name "Exuberant Ctags") ++and can run on files which currently do not compile. ++ ++There are also lots of other Vim-tools which use exuberant Ctags. ++ ++You will need to install a version of the Exuberant Ctags which has Ada ++support patched in. Such a version is available from the GNU Ada Project ++(http://gnuada.sourceforge.net). ++ ++The Ada parser for Exuberant Ctags is fairly new - don't expect complete ++support yet. ++ ++============================================================================== ++4. Compiler Support ~ ++ *ada-compiler* ++ ++The Ada mode supports more then one Ada compiler and will automatically load the ++compiler set in|g:ada_default_compiler|whenever an Ada source is opened. The ++provided compiler plug-ins are split into the actual compiler plug-in and a ++collection of support functions and variables. This allows the easy ++development of specialized compiler plug-ins fine tuned to your development ++environment. ++ ++------------------------------------------------------------------------------ ++4.1 GNAT ~ ++ *compiler-gnat* ++ ++GNAT is the only free (beer and speech) Ada compiler available. There are ++several version available which differentiate in the licence terms used. ++ ++The GNAT compiler plug-in will perform a compile on pressing and then ++immediately shows the result. You can set the project file to be used by ++setting: ++ > ++ > call g:gnat.Set_Project_File ('my_project.gpr') ++ ++Setting a project file will also create a Vim session (|views-sessions|) so - ++like with the GPS - opened files, window positions etc. will remembered ++separately for all projects. ++ ++ *gnat_members* ++GNAT OBJECT ~ ++ ++ *g:gnat.Make()* ++g:gnat.Make() ++ Calls|g:gnat.Make_Command|and displays the result inside a ++ |quickfix| window. ++ ++ *g:gnat.Pretty()* ++g:gnat.Pretty() ++ Calls|g:gnat.Pretty_Command| ++ ++ *g:gnat.Find()* ++g:gnat.Find() ++ Calls|g:gnat.Find_Command| ++ ++ *g:gnat.Tags()* ++g:gnat.Tags() ++ Calls|g:gnat.Tags_Command| ++ ++ *g:gnat.Set_Project_File()* ++g:gnat.Set_Project_File([{file}]) ++ Set gnat project file and load associated session. An open ++ project will be closed and the session written. If called ++ without file name the file selector opens for selection of a ++ project file. If called with an empty string then the project ++ and associated session are closed. ++ ++ *g:gnat.Project_File* ++g:gnat.Project_File string ++ Current project file. ++ ++ *g:gnat.Make_Command* ++g:gnat.Make_Command string ++ External command used for|g:gnat.Make()| (|'makeprg'|). ++ ++ *g:gnat.Pretty_Program* ++g:gnat.Pretty_Program string ++ External command used for|g:gnat.Pretty()| ++ ++ *g:gnat.Find_Program* ++g:gnat.Find_Program string ++ External command used for|g:gnat.Find()| ++ ++ *g:gnat.Tags_Command* ++g:gnat.Tags_Command string ++ External command used for|g:gnat.Tags()| ++ ++ *g:gnat.Error_Format* ++g:gnat.Error_Format string ++ Error format (|'errorformat'|) ++ ++------------------------------------------------------------------------------ ++4.2 Dec Ada ~ ++ *compiler-hpada* *compiler-decada* ++ *compiler-vaxada* *compiler-compaqada* ++ ++Dec Ada (also known by - in chronological order - VAX Ada, Dec Ada, Compaq Ada ++and HP Ada) is a fairly dated Ada 83 compiler. Support is basic: will ++compile the current unit. ++ ++The Dec Ada compiler expects the package name and not the file name to be ++passed a parameter. The compiler plug-in supports the usual file name ++convention to convert the file into a unit name. For separates both '-' and ++'__' are allowed. ++ ++ *decada_members* ++DEC ADA OBJECT ~ ++ ++ *g:decada.Make()* ++g:decada.Make() function ++ Calls|g:decada.Make_Command|and displays the result inside a ++ |quickfix| window. ++ ++ *g:decada.Unit_Name()* ++g:decada.Unit_Name() function ++ Get the Unit name for the current file. ++ ++ *g:decada.Make_Command* ++g:decada.Make_Command string ++ External command used for|g:decadat.Make()| (|'makeprg'|). ++ ++ *g:decada.Error_Format* ++g:decada.Error_Format| string ++ Error format (|'errorformat'|). ++ ++============================================================================== ++5. References ~ ++ *ada-reference* ++ ++------------------------------------------------------------------------------ ++5.1 Options ~ ++ *ft-ada-options* ++ ++ *g:ada_standard_types* ++g:ada_standard_types bool (true when exists) ++ Highlight types in package Standard (e.g., "Float") ++ ++ *g:ada_space_errors* ++ *g:ada_no_trail_space_error* ++ *g:ada_no_tab_space_error* ++ *g:ada_all_tab_usage* ++g:ada_space_errors bool (true when exists) ++ Highlight extraneous errors in spaces ... ++ g:ada_no_trail_space_error ++ - but ignore trailing spaces at the end of a line ++ g:ada_no_tab_space_error ++ - but ignore tabs after spaces ++ g:ada_all_tab_usage ++ - highlight all tab use ++ ++ *g:ada_line_errors* ++g:ada_line_errors bool (true when exists) ++ Highlight lines which are to long. Note: This highlighting ++ option is quite CPU intensive. ++ ++ *g:ada_rainbow_color* ++g:ada_rainbow_color bool (true when exists) ++ Use rainbow colours for '(' and ')'. You need the ++ rainbow_parenthesis for this to work ++ ++ *g:ada_folding* ++g:ada_folding set ('sigpft') ++ Use folding for Ada sources. ++ 's': activate syntax folding on load ++ 'p': fold packages ++ 'f': fold functions and procedures ++ 't': fold types ++ 'c': fold conditionals ++ 'g': activate gnat pretty print folding on load ++ 'i': lone 'is' folded with line above ++ 'b': lone 'begin' folded with line above ++ 'p': lone 'private' folded with line above ++ 'x': lone 'exception' folded with line above ++ 'i': activate indent folding on load ++ ++ Note: Syntax folding is in an early (unuseable) stage and ++ indent or gnat pretty folding is suggested. ++ ++ For gnat pretty folding to work the following settings are ++ suggested: -cl3 -M79 -c2 -c3 -c4 -A1 -A2 -A3 -A4 -A5 ++ ++ For indent folding to work the following settings are ++ suggested: shiftwidth=3 softtabstop=3 ++ ++ *g:ada_abbrev* ++g:ada_abbrev bool (true when exists) ++ Add some abbreviations. This feature more or less superseded ++ by the various completion methods. ++ ++ *g:ada_withuse_ordinary* ++g:ada_withuse_ordinary bool (true when exists) ++ Show "with" and "use" as ordinary keywords (when used to ++ reference other compilation units they're normally highlighted ++ specially). ++ ++ *g:ada_begin_preproc* ++g:ada_begin_preproc bool (true when exists) ++ Show all begin-like keywords using the colouring of C ++ preprocessor commands. ++ ++ *g:ada_omni_with_keywords* ++g:ada_omni_with_keywords ++ Add Keywords, Pragmas, Attributes to omni-completions ++ (|compl-omni|). Note: You can always complete then with user ++ completion (|i_CTRL-X_CTRL-U|). ++ ++ *g:ada_extended_tagging* ++g:ada_extended_tagging enum ('jump', 'list') ++ use extended tagging, two options are available ++ 'jump': use tjump to jump. ++ 'list': add tags quick fix list. ++ Normal tagging does not support function or operator ++ overloading as these features are not available in C and ++ tagging was originally developed for C. ++ ++ *g:ada_extended_completion* ++g:ada_extended_completion ++ Uses extended completion for and completions ++ (|i_CTRL-N|). In this mode the '.' is used as part of the ++ identifier so that 'Object.Method' or 'Package.Procedure' are ++ completed together. ++ ++ *g:ada_gnat_extensions* ++g:ada_gnat_extensions bool (true when exists) ++ Support GNAT extensions. ++ ++ *g:ada_with_gnat_project_files* ++g:ada_with_gnat_project_files bool (true when exists) ++ Add gnat project file keywords and Attributes. ++ ++ *g:ada_default_compiler* ++g:ada_default_compiler string ++ set default compiler. Currently supported is 'gnat' and ++ 'decada'. ++ ++An "exists" type is a boolean is considered true when the variable is defined ++and false when the variable is undefined. The value which the variable is ++set makes no difference. ++ ++------------------------------------------------------------------------------ ++5.3 Commands ~ ++ *ft-ada-commands* ++ ++:AdaRainbow *:AdaRainbow* ++ Toggles rainbow colour (|g:ada_rainbow_color|) mode for ++ '(' and ')' ++ ++:AdaLines *:AdaLines* ++ Toggles line error (|g:ada_line_errors|) display ++ ++:AdaSpaces *:AdaSpaces* ++ Toggles space error (|g:ada_space_errors|) display. ++ ++:AdaTagDir *:AdaTagDir* ++ Creates tags file for the directory of the current file. ++ ++:AdaTagFile *:AdaTagFile* ++ Creates tags file for the current file. ++ ++:AdaTypes *:AdaTypes* ++ Toggles standard types (|g:ada_standard_types|) colour. ++ ++:GnatFind *:GnatFind* ++ Calls |g:gnat.Find()| ++ ++:GnatPretty *:GnatPretty* ++ Calls |g:gnat.Pretty()| ++ ++:GnatTags *:GnatTags* ++ Calls |g:gnat.Tags()| ++ ++------------------------------------------------------------------------------ ++5.3 Variables ~ ++ *ft-ada-variables* ++ ++ *g:gnat* ++g:gnat object ++ Control object which manages GNAT compiles. The object ++ is created when the first Ada source code is loaded provided ++ that |g:ada_default_compiler|is set to 'gnat'. See|gnat_members| ++ for details. ++ ++ *g:decada* ++g:decada object ++ Control object which manages Dec Ada compiles. The object ++ is created when the first Ada source code is loaded provided ++ that |g:ada_default_compiler|is set to 'decada'. See ++ |decada_members|for details. ++ ++------------------------------------------------------------------------------ ++5.4 Constants ~ ++ *ft-ada-constants* ++ ft-ada-constants ++ ++All constants are locked. See |:lockvar| for details. ++ ++ *g:ada#WordRegex* ++g:ada#WordRegex string ++ Regular expression to search for Ada words ++ ++ *g:ada#DotWordRegex* ++g:ada#DotWordRegex string ++ Regular expression to search for Ada words separated by dots. ++ ++ *g:ada#Comment* ++g:ada#Comment string ++ Regular expression to search for Ada comments ++ ++ *g:ada#Keywords* ++g:ada#Keywords list of dictionaries ++ List of keywords, attributes etc. pp. in the format used by ++ omni completion. See |complete-items| for details. ++ ++ *g:ada#Ctags_Kinds* ++g:ada#Ctags_Kinds dictionary of lists ++ Dictionary of the various kinds of items which the Ada support ++ for Ctags generates. ++ ++------------------------------------------------------------------------------ ++5.2 Functions ~ ++ *ft-ada-functions* ++ ++ada#Word([{line}, {col}]) *ada#Word()* ++ Return full name of Ada entity under the cursor (or at given ++ line/column), stripping white space/newlines as necessary. ++ ++ada#List_Tag([{line}, {col}]) *ada#Listtags()* ++ List all occurrences of the Ada entity under the cursor (or at ++ given line/column) inside the quick-fix window ++ ++ada#Jump_Tag ({ident}, {mode}) *ada#Jump_Tag()* ++ List all occurrences of the Ada entity under the cursor (or at ++ given line/column) in the tag jump list. Mode can either be ++ 'tjump' or 'stjump'. ++ ++ada#Create_Tags ({option}) *ada#Create_Tags()* ++ Creates tag file using Ctags. The option can either be 'file' ++ for the current file, 'dir' for the directory of the current ++ file or a file name. ++ ++gnat#Insert_Tags_Header() *gnat#Insert_Tags_Header()* ++ Adds the tag file header (!_TAG_) information to the current ++ file which are missing from the GNAT XREF output. ++ ++ada#Switch_Syntax_Option ({option}) *ada#Switch_Syntax_Option()* ++ Toggles highlighting options on or off. Used for the Ada menu. ++ ++ *gnat#New()* ++gnat#New () ++ Create a new gnat object. See |g:gnat| for details. ++ ++ ++============================================================================== ++8. Extra Plugins ~ ++ *ada-extra-plugins* ++ ++You can optionally install the following extra plug-in. They work well with Ada ++and enhance the ability of the Ada mode.: ++ ++backup.vim ++ http://www.vim.org/scripts/script.php?script_id=1537 ++ Keeps as many backups as you like so you don't have to. ++ ++rainbow_parenthsis.vim ++ http://www.vim.org/scripts/script.php?script_id=1561 ++ Very helpful since Ada uses only '(' and ')'. ++ ++nerd_comments.vim ++ http://www.vim.org/scripts/script.php?script_id=1218 ++ Excellent commenting and uncommenting support for almost any ++ programming language. ++ ++matchit.vim ++ http://www.vim.org/scripts/script.php?script_id=39 ++ '%' jumping for any language. The normal '%' jump only works for '{}' ++ style languages. The Ada mode will set the needed search patters. ++ ++taglist.vim ++ http://www.vim.org/scripts/script.php?script_id=273 ++ Source code explorer sidebar. There is a patch for Ada available. ++ ++The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim ++contains all of the above. ++ ++============================================================================== ++vim: textwidth=78 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++vim: filetype=help +diff -urN vim71/1/doc/matchit.txt vim71_ada/1/doc/matchit.txt +--- vim71/1/doc/matchit.txt 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/matchit.txt 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,405 @@ ++*matchit.txt* Extended "%" matching ++ ++For instructions on installing this file, type ++ :help matchit-install ++inside Vim. ++ ++For Vim version 6.3. Last change: 2006 Feb 23 ++ ++ ++ VIM REFERENCE MANUAL by Benji Fisher ++ ++*matchit* *matchit.vim* ++ ++1. Extended matching with "%" |matchit-intro| ++2. Activation |matchit-activate| ++3. Configuration |matchit-configure| ++4. Supporting a New Language |matchit-newlang| ++5. Known Bugs and Limitations |matchit-bugs| ++ ++The functionality mentioned here is a plugin, see |add-plugin|. ++This plugin is only available if 'compatible' is not set. ++You can avoid loading this plugin by setting the "loaded_matchit" variable ++in your |vimrc| file: > ++ :let loaded_matchit = 1 ++ ++{Vi does not have any of this} ++ ++============================================================================== ++1. Extended matching with "%" *matchit-intro* ++ ++ *matchit-%* ++% Cycle forward through matching groups, such as "if", "else", "endif", ++ as specified by |b:match_words|. ++ ++ *g%* *v_g%* *o_g%* ++g% Cycle backwards through matching groups, as specified by ++ |b:match_words|. For example, go from "endif" to "else" to "if". ++ ++ *[%* *v_[%* *o_[%* ++[% Go to [count] previous unmatched group, as specified by ++ |b:match_words|. Similar to |[{|. ++ ++ *]%* *v_]%* *o_]%* ++]% Go to [count] next unmatched group, as specified by ++ |b:match_words|. Similar to |]}|. ++ ++ *v_a%* ++a% In Visual mode, select the matching group, as specified by ++ |b:match_words|, containing the cursor. Similar to |v_a[|. ++ A [count] is ignored, and only the first character of the closing ++ pattern is selected. ++ ++In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, ++bracket, or paren to its match. This can be configured with the 'matchpairs' ++option. The matchit plugin extends this in several ways: ++ ++ You can match whole words, such as "if" and "endif", not just ++ single characters. You can also specify a |regular-expression|. ++ You can define groups with more than two words, such as "if", ++ "else", "endif". Banging on the "%" key will cycle from the "if" to ++ the first "else", the next "else", ..., the closing "endif", and back ++ to the opening "if". Nested structures are skipped. Using |g%| goes ++ in the reverse direction. ++ By default, words inside comments and strings are ignored, unless ++ the cursor is inside a comment or string when you type "%". If the ++ only thing you want to do is modify the behavior of "%" so that it ++ behaves this way, you can > ++ :let b:match_words = &matchpairs ++< ++See |matchit-details| for details on what the script does, and |b:match_words| ++for how to specify matching patterns. ++ ++MODES: *matchit-modes* *matchit-v_%* *matchit-o_%* ++ ++Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in ++|motion| commands in |Operator-pending| and |Visual| modes. However, you ++cannot make these motions |linewise| or |characterwise|, since the |:omap|s ++that define them start with "v" in order to make the default behavior ++inclusive. (See |o_v|.) In other words, "dV%" will not work. The ++work-around is to go through Visual mode: "V%d" will work. ++ ++LANGUAGES: *matchit-languages* ++ ++Currently, the following languages are supported: Ada, ASP with VBS, Csh, ++DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, ++SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via ++|filetype-plugin|s. ++ ++To support a new language, see |matchit-newlang| below. ++ ++DETAILS: *matchit-details* *matchit-parse* ++ ++Here is an outline of what matchit.vim does each time you hit the "%" key. If ++there are |backref|s in |b:match_words| then the first step is to produce a ++version in which these back references have been eliminated; if there are no ++|backref|s then this step is skipped. This step is called parsing. For ++example, "\(foo\|bar\):end\1" is parsed to yield ++"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are ++nested groups. If debugging is turned on, the parsed version is saved as ++|b:match_pat|. ++ ++ *matchit-choose* ++Next, the script looks for a word on the current line that matches the pattern ++just constructed. It includes the patterns from the 'matchpairs' option. ++The goal is to do what you expect, which turns out to be a little complicated. ++The script follows these rules: ++ ++ Insist on a match that ends on or after the cursor. ++ Prefer a match that includes the cursor position (that is, one that ++ starts on or before the cursor). ++ Prefer a match that starts as close to the cursor as possible. ++ Prefer a match in |b:match_words| to a match in 'matchpairs'. ++ If more than one pattern in |b:match_words| matches, choose the one ++ that is listed first. ++ ++Examples: ++ ++ Suppose you > ++ :let b:match_words = '<:>,:' ++< and hit "%" with the cursor on or before the "<" in "a is born". ++ The pattern '<' comes first, so it is preferred over '', which ++ also matches. If the cursor is on the "t", however, then '' is ++ preferred, because this matches a bit of text containing the cursor. ++ If the two groups of patterns were reversed then '<' would never be ++ preferred. ++ ++ Suppose you > ++ :let b:match_words = 'if:end if' ++< (Note the space!) and hit "%" with the cursor at the end of "end if". ++ Then "if" matches, which is probably not what you want, but if the ++ cursor starts on the "end " then "end if" is chosen. (You can avoid ++ this problem by using a more complicated pattern.) ++ ++If there is no match, the script falls back on the usual behavior of |%|. If ++debugging is turned on, the matched bit of text is saved as |b:match_match| ++and the cursor column of the start of the match is saved as |b:match_col|. ++ ++Next, the script looks through |b:match_words| (original and parsed versions) ++for the group and pattern that match. If debugging is turned on, the group is ++saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If ++there are |backref|s then, in addition, the matching pattern is saved as ++|b:match_word| and a table of translations is saved as |b:match_table|. If ++there are |backref|s, these are determined from the matching pattern and ++|b:match_match| and substituted into each pattern in the matching group. ++ ++The script decides whether to search forwards or backwards and chooses ++arguments for the |searchpair()| function. Then, the cursor is moved to the ++start of the match, and |searchpair()| is called. By default, matching ++structures inside strings and comments are ignored. This can be changed by ++setting |b:match_skip|. ++ ++============================================================================== ++2. Activation *matchit-activate* ++ ++You can use this script as a plugin, by copying it to your plugin directory. ++See |add-global-plugin| for instructions. You can also add a line to your ++|vimrc| file, such as > ++ :source $VIMRUNTIME/macros/matchit.vim ++or > ++ :runtime macros/matchit.vim ++Either way, the script should start working the next time you start up Vim. ++ ++The script does nothing unless it finds a |buffer-variable| named ++|b:match_words|. The script contains autocommands that set this variable for ++various file types: see |matchit-languages| above. For a new language, you ++can add autocommands to the script or to your vimrc file, but the recommended ++method is to add a line such as > ++ let b:match_words = '\:\' ++to the |filetype-plugin| for your language. See |b:match_words| below for how ++this variable is interpreted. ++ ++TROUBLESHOOTING *matchit-troubleshoot* ++ ++The script should work in most installations of Vim. It may not work if Vim ++was compiled with a minimal feature set, for example if the |+syntax| option ++was not enabled. If your Vim has support for syntax compiled in, but you do ++not have |syntax| highlighting turned on, matchit.vim should work, but it may ++fail to skip matching groups in comments and strings. If the |filetype| ++mechanism is turned off, the |b:match_words| variable will probably not be ++defined automatically. ++ ++============================================================================== ++3. Configuration *matchit-configure* ++ ++There are several variables that govern the behavior of matchit.vim. Note ++that these are variables local to the buffer, not options, so use |:let| to ++define them, not |:set|. Some of these variables have values that matter; for ++others, it only matters whether the variable has been defined. All of these ++can be defined in the |filetype-plugin| or autocommand that defines ++|b:match_words| or "on the fly." ++ ++The main variable is |b:match_words|. It is described in the section below on ++supporting a new language. ++ ++ *MatchError* *matchit-hl* *matchit-highlight* ++MatchError is the highlight group for error messages from the script. By ++default, it is linked to WarningMsg. If you do not want to be bothered by ++error messages, you can define this to be something invisible. For example, ++if you use the GUI version of Vim and your command line is normally white, you ++can do > ++ :hi MatchError guifg=white guibg=white ++< ++ *b:match_ignorecase* ++If you > ++ :let b:match_ignorecase = 1 ++then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END" ++are equivalent. If you > ++ :let b:match_ignorecase = 0 ++then matchit.vim treats "end" and "END" differently. (There will be no ++b:match_infercase option unless someone requests it.) ++ ++ *b:match_debug* ++Define b:match_debug if you want debugging information to be saved. See ++|matchit-debug|, below. ++ ++ *b:match_skip* ++If b:match_skip is defined, it is passed as the skip argument to ++|searchpair()|. This controls when matching structures are skipped, or ++ignored. By default, they are ignored inside comments and strings, as ++determined by the |syntax| mechanism. (If syntax highlighting is turned off, ++nothing is skipped.) You can set b:match_skip to a string, which evaluates to ++a non-zero, numerical value if the match is to be skipped or zero if the match ++should not be skipped. In addition, the following special values are ++supported by matchit.vim: ++ s:foo becomes (current syntax item) =~ foo ++ S:foo becomes (current syntax item) !~ foo ++ r:foo becomes (line before cursor) =~ foo ++ R:foo becomes (line before cursor) !~ foo ++(The "s" is meant to suggest "syntax", and the "r" is meant to suggest ++"regular expression".) ++ ++Examples: ++ ++ You can get the default behavior with > ++ :let b:match_skip = 's:comment\|string' ++< ++ If you want to skip matching structures unless they are at the start ++ of the line (ignoring whitespace) then you can > ++ :let b:match_skip = 'R:^\s*' ++< Do not do this if strings or comments can span several lines, since ++ the normal syntax checking will not be done if you set b:match_skip. ++ ++ In LaTeX, since "%" is used as the comment character, you can > ++ :let b:match_skip = 'r:%' ++< Unfortunately, this will skip anything after "\%", an escaped "%". To ++ allow for this, and also "\\%" (an excaped backslash followed by the ++ comment character) you can > ++ :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%' ++< ++ See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both ++ syntax and a regular expression. ++ ++============================================================================== ++4. Supporting a New Language *matchit-newlang* ++ *b:match_words* ++In order for matchit.vim to support a new language, you must define a suitable ++pattern for |b:match_words|. You may also want to set some of the ++|matchit-configure| variables, as described above. If your language has a ++complicated syntax, or many keywords, you will need to know something about ++Vim's |regular-expression|s. ++ ++The format for |b:match_words| is similar to that of the 'matchpairs' option: ++it is a comma (,)-separated list of groups; each group is a colon(:)-separated ++list of patterns (regular expressions). Commas and backslashes that are part ++of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to ++have only one group; the effect is undefined if a group has only one pattern. ++A simple example is > ++ :let b:match_words = '\:\,' ++ \ . '\:\:\:\' ++(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" ++matches the end of "endif" but "\" does not.) Then banging on the "%" ++key will bounce the cursor between "if" and the matching "endif"; and from ++"while" to any matching "continue" or "break", then to the matching "endwhile" ++and back to the "while". It is almost always easier to use |literal-string|s ++(single quotes) as above: '\' rather than "\\" and so on. ++ ++Exception: If the ":" character does not appear in b:match_words, then it is ++treated as an expression to be evaluated. For example, > ++ :let b:match_words = 'GetMatchWords()' ++allows you to define a function. This can return a different string depending ++on the current syntax, for example. ++ ++Once you have defined the appropriate value of |b:match_words|, you will ++probably want to have this set automatically each time you edit the ++appropriate file type. The recommended way to do this is by adding the ++definition to a |filetype-plugin| file. ++ ++Tips: Be careful that your initial pattern does not match your final pattern. ++See the example above for the use of word-boundary expressions. It is usually ++better to use ".\{-}" (as many as necessary) instead of ".*" (as many as ++possible). See |\{-|. For example, in the string "label", "<.*>" ++matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "" and ++"". ++ ++ *matchit-spaces* *matchit-s:notend* ++If "if" is to be paired with "end if" (Note the space!) then word boundaries ++are not enough. Instead, define a regular expression s:notend that will match ++anything but "end" and use it as follows: > ++ :let s:notend = '\%(\:\' ++< *matchit-s:sol* ++This is a simplified version of what is done for Ada. The s:notend is a ++|script-variable|. Similarly, you may want to define a start-of-line regular ++expression > ++ :let s:sol = '\%(^\|;\)\s*' ++if keywords are only recognized after the start of a line or after a ++semicolon (;), with optional white space. ++ ++ *matchit-backref* *matchit-\1* ++In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the ++INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred ++to as back references, or backrefs. For example, > ++ :let b:match_words = '\:\(h\)\1\>' ++means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note ++that "\1" does not refer to the "\(h\)" in this example. If you have ++"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything ++up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1" ++refers to everything and "\2" refers to "\(parentheses\)". If you use a ++variable such as |s:notend| or |s:sol| in the previous paragraph then remember ++to count any "\(" patterns in this variable. You do not have to count groups ++defined by |\%(\)|. ++ ++It should be possible to resolve back references from any pattern in the ++group. For example, > ++ :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2' ++would not work because "\2" cannot be determined from "morefoo" and "\1" ++cannot be determined from "andbar". On the other hand, > ++ :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' ++should work (and have the same effect as "foobar:barfoo:endfoobar"), although ++this has not been thoroughly tested. ++ ++You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has ++not been thouroughly tested in matchit.vim.) For example, if the keyword "if" ++must occur at the start of the line, with optional white space, you might use ++the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of ++at the start of the line. For another example, if HTML had only one tag then ++one could > ++ :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>' ++so that "%" can bounce between matching "<" and ">" pairs or (starting on ++"tag" or "/tag") between matching tags. Without the |\@<=|, the script would ++bounce from "tag" to the "<" in "", and another "%" would not take you ++back to where you started. ++ ++DEBUGGING *matchit-debug* *:MatchDebug* ++ ++If you are having trouble figuring out the appropriate definition of ++|b:match_words| then you can take advantage of the same information I use when ++debugging the script. This is especially true if you are not sure whether ++your patterns or my script are at fault! To make this more convenient, I have ++made the command :MatchDebug, which defines the variable |b:match_debug| and ++creates a Matchit menu. This menu makes it convenient to check the values of ++the variables described below. You will probably also want to read ++|matchit-details| above. ++ ++Defining the variable |b:match_debug| causes the script to set the following ++variables, each time you hit the "%" key. Several of these are only defined ++if |b:match_words| includes |backref|s. ++ ++ *b:match_pat* ++The b:match_pat variable is set to |b:match_words| with |backref|s parsed. ++ *b:match_match* ++The b:match_match variable is set to the bit of text that is recognized as a ++match. ++ *b:match_col* ++The b:match_col variable is set to the cursor column of the start of the ++matching text. ++ *b:match_wholeBR* ++The b:match_wholeBR variable is set to the comma-separated group of patterns ++that matches, with |backref|s unparsed. ++ *b:match_iniBR* ++The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|. ++ *b:match_ini* ++The b:match_ini variable is set to the first pattern in |b:match_wholeBR|, ++with |backref|s resolved from |b:match_match|. ++ *b:match_tail* ++The b:match_tail variable is set to the remaining patterns in ++|b:match_wholeBR|, with |backref|s resolved from |b:match_match|. ++ *b:match_word* ++The b:match_word variable is set to the pattern from |b:match_wholeBR| that ++matches |b:match_match|. ++ *b:match_table* ++The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in ++|b:match_word|. ++ ++============================================================================== ++5. Known Bugs and Limitations *matchit-bugs* ++ ++Just because I know about a bug does not mean that it is on my todo list. I ++try to respond to reports of bugs that cause real problems. If it does not ++cause serious problems, or if there is a work-around, a bug may sit there for ++a while. Moral: if a bug (known or not) bothers you, let me know. ++ ++The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may ++have undesired effects in Select mode |Select-mode-mapping|. At least, if you ++want to replace the selection with any character in "ag%[]" there will be a ++pause of |'updatetime'| first. ++ ++It would be nice if "\0" were recognized as the entire pattern. That is, it ++would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may ++try to implement this in a future version. (This is not so easy to arrange as ++you might think!) ++ ++============================================================================== ++vim: filetype=help ++vim:tw=78:fo=tcq2: +diff -urN vim71/1/doc/NERD_commenter.txt vim71_ada/1/doc/NERD_commenter.txt +--- vim71/1/doc/NERD_commenter.txt 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/NERD_commenter.txt 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,1155 @@ ++*NERD_comments.txt* Plugin for commenting code v169 ++ ++ ++ NERD_COMMENTS REFERENCE MANUAL~ ++ ++ ++ ++ ++ ++============================================================================== ++CONTENTS {{{2 *NERD_comments-contents* ++ ++ 1.Intro...................................|NERD_comments| ++ 2.Functionality provided..................|NERD_com-functionality| ++ 2.1 Functionality Summary.............|NERD_com-functionality-summary| ++ 2.2 Functionality Details.............|NERD_com-functionality-details| ++ 2.2.1 Comment map.................|NERD_com-comment| ++ 2.2.2 Nested comment map..........|NERD_com-nested-comment| ++ 2.2.3 Toggle comment map..........|NERD_com-toggle-comment| ++ 2.2.4 Minimal comment map.........|NERD_com-minimal-comment| ++ 2.2.5 Invert comment map..........|NERD_com-invert-comment| ++ 2.2.6 Sexy comment map............|NERD_com-sexy-comment| ++ 2.2.7 Yank comment map............|NERD_com-yank-comment| ++ 2.2.8 Comment to EOL map..........|NERD_com-EOL-comment| ++ 2.2.9 Append com to line map......|NERD_com-append-comment| ++ 2.2.10 Prepend com to line map....|NERD_com-prepend-comment| ++ 2.2.11 Insert comment map.........|NERD_com-insert-comment| ++ 2.2.12 Use alternate delims map...|NERD_com-alt-delim| ++ 2.2.13 Comment aligned maps.......|NERD_com-aligned-comment| ++ 2.2.14 Uncomment line map.........|NERD_com-uncomment-line| ++ 2.3 Supported filetypes...............|NERD_com-filetypes| ++ 2.4 Sexy Comments.....................|NERD_com_sexy_comments| ++ 3.Customisation...........................|NERD_com-customisation| ++ 3.1 Customisation summary.............|NERD_com-cust-summary| ++ 3.2 Customisation details.............|NERD_com-cust-details| ++ 3.3 Default delimiter customisation...|NERD_com-cust-delims| ++ 3.4 Key mapping customisation.........|NERD_com-cust-keys| ++ 3.5 Sample regular expressions........|NERD_com-reg-exps| ++ 4.Issues with the script..................|NERD_com-issues| ++ 4.1 Delimiter detection heuristics....|NERD_com-heuristics| ++ 4.2 Nesting issues....................|NERD_com-nesting| ++ 4.3 Nesting issues....................|NERD_com-nesting| ++ 4.3 Mark clobbering...................|NERD_com-mark-clobbering| ++ 5.TODO list...............................|NERD_com-todo| ++ 6.Credits.................................|NERD_com-credits| ++ ++============================================================================== ++1. Intro {{{2 *NERD_comments* ++ ++NERD_comments provides a set of handy key mappings for commenting code. These ++mappings are consistent across all supported filetypes. ++ ++When writing NERD_comments I have tried to give it as many features/options as ++possible while keeping it so that the plugin can still be used with little or ++no knowledge of these. The average user need only know about a few key ++mappings to use NERD_comments while there are plenty of other features for the ++l33t nerd take advantage of. ++ ++Enjoy :D ++ ++============================================================================== ++2. Functionality provided {{{2 *NERD_com-functionality* ++ ++------------------------------------------------------------------------------ ++2.1 Functionality summary {{{3 *NERD_com-functionality-summary* ++ ++The following key mappings are provided by default (there is also a menu ++provided that contains menu items corresponding to all the below mappings): ++ ++Note: is a user defined key that is used to start keymappings and ++defaults to \. Check out || for details. ++ ++Most of the following mappings are for normal/visual mode only. The ++|NERD_com-insert-comment| mapping is for insert mode only. ++ ++cc |NERD_com-comment-map| ++Comments out the current line or text selected in visual mode. ++ ++ ++cn |NERD_com-nested-comment| ++Same as |NERD_com-comment-map| but enforces nesting. ++ ++ ++c |NERD_com-toggle-comment| ++Toggles the comment state of the selected line(s). If the topmost selected ++line is commented, all selected lines are uncommented and vice versa. ++ ++ ++cm |NERD_com-minimal-comment| ++Comments the given lines using only one set of multipart delimiters if ++possible. ++ ++ ++ci |NERD_com-invert-comment| ++Toggles the comment state of the selected line(s) individually. Each selected ++line that is commented is uncommented and vice versa. ++ ++ ++cs |NERD_com-sexy-comment| ++Comments out the selected lines ``sexually'' ++ ++ ++cy |NERD_com-yank-comment| ++Same as |NERD_com-comment-map| except that the commented line(s) are yanked ++before commenting. ++ ++ ++c$ |NERD_com-EOL-comment| ++Comments the current line from the cursor to the end of line. ++ ++ ++cA |NERD_com-append-comment| ++Adds comment delimiters to the end of line and goes into insert mode between ++them. ++ ++ ++cI |NERD_com-prepend-comment| ++Adds comment delimiters to the start of line and goes into insert mode between ++them. ++ ++ ++ |NERD_com-insert-comment| ++Adds comment delimiters at the current cursor position and inserts between. ++ ++ ++ca |NERD_com-alt-delim| ++Switches to the alternative set of delimiters. ++ ++ ++cl OR cr OR cb |NERD_com-aligned-comment| ++Same as |NERD_com-comment| except that the delimiters are aligned down the ++left side (cl), the right side (cr) or both sides ++(cb). ++ ++ ++cu |NERD_com-uncomment-line| ++Uncomments the selected line(s). ++ ++------------------------------------------------------------------------------ ++2.2 Functionality details {{{3 *NERD_com-functionality-details* ++ ++------------------------------------------------------------------------------ ++2.2.1 Comment map *NERD_com-comment* ++cc ++Comments out the current line. If multiple lines are selected in visual-line ++mode, they are all commented out. If some text is selected in visual or ++visual-block mode then NERD_comments will try to comment out the exact text ++that is selected using multi-part delimiters if they are available. ++ ++Works in normal, visual, visual-line and visual-block mode. ++ ++Change the mapping with: |NERD_com_line_map|. ++ ++Relevant options: ++|NERD_allow_any_visual_delims_regexp| ++|NERD_comment_whole_lines_in_v_mode| ++|NERD_block_com_after_right| ++|NERD_left_align_regexp| ++|NERD_place_holder_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++------------------------------------------------------------------------------ ++2.2.2 Nested comment map *NERD_com-nested-comment* ++cn ++Performs nested commenting. Works the same as cc except that if a ++line is already commented then it will be commented again. ++ ++If the filetype is covered by the |NERD_place_holder_regexp| option ++then the previous comment delimiters will be replaced by place-holder ++delimiters if needed. Otherwise the nested comment will only be added if the ++current commenting delimiters have no right delimiter (to avoid compiler ++errors) ++ ++Works in normal, visual, visual-line, visual-block modes. ++ ++Change the mapping with: |NERD_com_line_nest_map|. ++ ++Relevant options: ++|NERD_allow_any_visual_delims_regexp| ++|NERD_comment_whole_lines_in_v_mode| ++|NERD_block_com_after_right| ++|NERD_left_align_regexp| ++|NERD_place_holder_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++ ++------------------------------------------------------------------------------ ++2.2.3 Toggle comment map *NERD_com-toggle-comment* ++c ++Toggles commenting of the lines selected. The behaviour of this mapping ++depends on whether the first line selected is commented or not. If so, all ++selected lines are uncommented and vice versa. ++ ++With this mapping, lines are only considered to be commented if a left comment ++delimiter is the first non-space/tab char on the line. ++ ++Works in normal, visual-line, modes. ++Using this mapping in visual or visual-block modes will cause it to work like ++|NERD_com-comment| ++ ++Change the mapping with: |NERD_com_line_toggle_map|. ++ ++Relevant options: ++|NERD_left_align_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++------------------------------------------------------------------------------ ++2.2.4 Minimal comment map *NERD_com-minimal-comment* ++cm ++Comments the selected lines using one set of multipart delimiters if possible. ++ ++For example: if you are programming in c and you select 5 lines and press ++cm then a '/*' will be placed at the start of the top line and a '*/' ++will be placed at the end of the last line. ++ ++Sets of multipart comment delimiters that are between the top and bottom ++selected lines are replaced with place holders (see |NERD_lPlace|) if ++NERD_place_holder_regexp is set for the current filetype. If it is not, then ++the comment will be aborted if place holders are required to prevent illegal ++syntax. ++ ++------------------------------------------------------------------------------ ++2.2.5 Invert comment map *NERD_com-invert-comment* ++ci ++Inverts the commented state of each selected line. If the a selected line is ++commented then it is uncommented and vice versa. Each line is examined and ++commented/uncommented individually. ++ ++With this mapping, lines are only considered to be commented if a left comment ++delimiter is the first non-space/tab char on the line. ++ ++Works in normal, visual-line, modes. ++ ++Change the mapping with: |NERD_com_line_invert_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.6 Sexy comment map *NERD_com-sexy-comment* ++cs ++Comments the selected line(s) ``sexily''... see |NERD_com_sexy_commenting| for ++a description of what sexy comments are. Can only be done on filetypes for ++which there is at least one set of multipart comment delimiters specified. ++ ++Sexy comments cannot be nested and lines inside a sexy comment cannot be ++commented again. ++ ++Works in normal, visual-line. ++ ++Change the mapping with: |NERD_com_line_sexy_map| ++ ++Relevant options: ++|NERD_use_compact_sexy_com_regexp| ++ ++------------------------------------------------------------------------------ ++2.2.7 Yank comment map *NERD_com-yank-comment* ++cy ++Same as cc except that it yanks the line(s) that are commented first. ++ ++Works in normal, visual, visual-line, visual-block modes. ++ ++Change the mapping with: |NERD_com_line_yank_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.8 Comment to EOL map *NERD_com-EOL-comment* ++c$ ++Comments the current line from the current cursor position up to the end of ++the line. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_com_to_end_of_line_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.9 Append com to line map *NERD_com-append-comment* ++cA ++Appends comment delimiters to the end of the current line and goes ++to insert mode between the new delimiters. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_append_com_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.10 Prepend com to line map *NERD_com-prepend-comment* ++cI ++Prepends comment delimiters to the start of the current line and goes to ++insert mode between the new delimiters. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_prepend_com_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.11 Insert comment map *NERD_com-insert-comment* ++ ++Adds comment delimiters at the current cursor position and inserts ++between them. ++ ++Works in insert mode. ++ ++Change the mapping with: |NERD_com_in_insert_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.12 Use alternate delims map *NERD_com-alt-delim* ++ca ++Changes to the alternative commenting style if one is available. For example, ++if the user is editing a c++ file using // comments and they hit ca ++then they will be switched over to /**/ comments. ++keys for this mappings can be overridden with the ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_alt_com_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.13 Comment aligned maps *NERD_com-aligned-comment* ++cl cr cb ++Same as cc except that the comment delimiters are aligned on the left ++side, right side or both sides respectively. These comments are always nested ++if the line(s) are already commented. ++ ++Works in normal, visual-line. ++ ++Change the mappings with: |NERD_com_align_left_map|, |NERD_com_align_right_map| ++and |NERD_com_align_both_map|. ++ ++Relevant options: ++|NERD_left_align_regexp| ++|NERD_right_align_regexp| ++ ++ ++------------------------------------------------------------------------------ ++2.2.14 Uncomment line map *NERD_com-uncomment-line* ++cu ++Uncomments the current line. If multiple lines are selected in ++visual mode then they are all uncommented. ++ ++When uncommenting, if the line contains multiple sets of delimiters then the ++``outtermost'' pair of delimiters will be removed. ++ ++The script uses a set of heurisics to distinguish ``real'' delimiters from ++``fake'' ones when uncommenting. See |NERD_com-issues| for details. ++ ++Works in normal, visual, visual-line, visual-block. ++ ++Change the mapping with: |NERD_uncom_line_map|. ++ ++Relevant options: ++|NERD_dont_remove_alt_coms| ++|NERD_dont_remove_spaces_regexp| ++ ++ ++------------------------------------------------------------------------------ ++2.3 Supported filetypes *NERD_com-filetypes* ++ ++Files that can be commented by this plugin: ++abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asm ++asn aspvbs atlas automake ave awk basic b bc bdf bib bindzone btm caos catalog ++c cfg cg ch cl clean clipper conf config cpp crontab cs csc csp css cterm cupl ++cvs dcl def diff dns dosbatch dosini dot dracula dsl dtd dtml dylan ecd eiffel ++elf elmfilt erlang eruby eterm expect exports fgl focexec form fortran foxpro ++fvwm fx gdb gdmo gnuplot gtkrc haskell hb h help hercules hog html htmlos ia64 ++icon idlang idl indent inform inittab ishd iss ist jam java javascript jess ++jgraph jproperties jproperties jsp kix kscript lace lex lftp lifelines lilo ++lisp lite lotos lout lprolog lscript lss lua lynx m4 make maple masm master ++matlab mel mf mib mma model moduala. modula2 modula3 monk mush muttrc named ++nasm nastran natural ncf netrw nqc nsis ocaml omnimark openroad opl ora ox ++pascal pcap pccts perl pfmain php phtml pic pike pilrc pine plm plsql po ++postscr pov povini ppd ppwiz procmail progress prolog psf ptcap python python ++radiance ratpoison r rc readline rebol registry remind rexx robots rpl ruby sa ++samba sas sather scheme scilab screen scsh sdl sed sgml sgmldecl sgmllnx sicad ++simula sinda skill slang sl slrnrc sm smil smith sml snnsnet snnspat snnsres ++snobol4 spec specman spice sql sqlforms sqlj sqr squid st stp strace svn tads ++taglist tags tak tasm tcl terminfo tex texinfo texmf tf tidy tli trasys tsalt ++tsscl tssgm uc uil vb verilog vgrindefs vhdl vim virata vrml vsejcl webmacro ++wget winbatch wml sh wvdial xdefaults xf86conf xhtml xkb xmath xml xmodmap ++xpm2 xpm xslt yacc yaml z8a ++ ++If a language is not in the list of hardcoded supported filetypes then the ++&commentstring vim option is used. ++ ++ ++------------------------------------------------------------------------------ ++2.4 Sexy Comments *NERD_com_sexy_comments* ++These are comments that use one set of multipart comment delimiters as well as ++one other marker symbol. For example: > ++ /* ++ * This is a c style sexy comment ++ * So there! ++ */ ++ ++ /* This is a c style sexy comment ++ * So there! ++ * But this one is ``compact'' style */ ++< ++Here the multipart delimiters are /* and */ and the marker is *. NERD_comments ++is capable of adding and removing comments of this type. ++ ++ ++============================================================================== ++3. Customisation {{{2 *NERD_com-customisation* ++ ++------------------------------------------------------------------------------ ++3.1 Customisation summary *NERD_com-cust-summary* ++ ++|loaded_nerd_comments| Turns off the script. ++|NERD_allow_any_visual_delims_regexp| Allows multipart alternative delims to ++ be used when commenting in ++ visual/visual-block mode. ++|NERD_block_com_after_right| Forces right delims to be placed when ++ doing visual-block comments. ++|NERD_comment_whole_lines_in_v_mode| Changes behaviour of visual comments. ++|NERD_menu_mode| Determines if a NERD comment menu will ++ be made and whether the menu will have a ++ keyboard shortcut. ++|NERD_dont_remove_alt_coms| Causes alternative comments not to be ++ removed when uncommenting. ++|NERD_dont_remove_spaces_regexp| Causes spaces not to be removed when ++ uncommenting if the filetype doesnt ++ match |NERD_space_delim_filetype_regexp| ++|NERD_create_h_filetype| Creates a new filetype for .h files. ++|NERD_lPlace| Specifies what to use as the left ++ delimiter placeholder when nesting ++ comments. ++|NERD_left_align_regexp| Specifies which filetypes to align left ++ delimiters for. ++|NERD_mapleader| Specifies what all the commenting key ++ mappings will begin with. ++|NERD_place_holder_regexp| Specifies which filetypes may use ++ placeholders when nesting comments. ++|NERD_right_align_regexp| Specifies which filetypes to align right ++ delimiters for. ++|NERD_rPlace| Specifies what to use as the right ++ delimiter placeholder when nesting ++ comments. ++|NERD_shut_up| Stops all output from the script. ++|NERD_space_delim_filetype_regexp| Specifies which filetypes to add spaces ++ around the delimiters for. ++|NERD_use_compact_sexy_com_regexp| Specifies which filetypes to use compact ++ sexy comments for. ++|NERD_use_nested_comments_default| Tells the script to use nested comments ++ by default. ++ ++----------------------------------------------------------------------------- ++3.3 Customisation details *NERD_com-cust-details* ++ ++To enable any of the below options you should put the given line in your ++~/.vimrc ++ ++ *loaded_nerd_comments* ++If this script is driving you insane you can turn it off by setting this ++option > ++ let loaded_nerd_comments=1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_allow_any_visual_delims_regexp* ++This option is set to a regular expression that is used to specify which ++filetypes this option should be turned on for. If this covers the current ++filetype then, when NERD_comments is doing a visual or visual-block comment ++(but not a visual-line comment) it will choose the right delimiters to use for ++the comment. This normally means using the current delimiters if they are ++multipart or using the alternative delimiters if THEY are multipart and the ++current delims are not. For example if we are editing the following java ++code: > ++ float foo = 1221; ++ float bar = 324; ++ System.out.println(foo * bar); ++< ++If we are using // comments and select the "foo" and "bar" in visual-block ++mode, as shown left below (where '|'s are used to represent the visual-block ++boundary), and comment it then it will use the alternative delims as shown on ++the right: > ++ float |foo| = 1221; float /*foo*/ = 1221; ++ float |bar| = 324; float /*bar*/ = 324; ++ System.out.println(foo * bar); System.out.println(foo * bar); ++< ++By default this option is set to '.*' i.e is turned on for all filetypes. ++ ++----------------------------------------------------------------------------- ++ *NERD_block_com_after_right* ++This option affects commenting when it is done in visual-block mode. If this ++option is turned on, lines that begin outside the right boundary of the ++selection block will be commented. Enable this option with: > ++ let NERD_block_com_after_right=1 ++< ++For example, if you are commenting this chunk of c code in visual-block mode ++(where the '|'s are used to represent the visual-block boundary) > ++ #include ++ #include ++ #include ++ |int| main(){ ++ | | printf("SUCK THIS\n"); ++ | | while(1){ ++ | | fork(); ++ | | } ++ |} | ++< ++If NERD_block_com_after_right=1 then this code will become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ /* */ printf("SUCK THIS\n"); ++ /* */ while(1){ ++ /* */ fork(); ++ /* */ } ++ /*} */ ++< ++Otherwise, the code block would become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ printf("SUCK THIS\n"); ++ while(1){ ++ fork(); ++ } ++ /*} */ ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_comment_whole_lines_in_v_mode* ++This option can take 2 values. By default NERD_comments tries to comment out ++exactly what is selected in visual mode (v). For example if you select and ++comment the following c code (using | to represent the visual boundary): > ++ in|t foo = 3; ++ int bar =| 9; ++ int baz = foo + bar; ++< ++This will result in: > ++ in/*t foo = 3;*/ ++ /*int bar =*/ 9; ++ int baz = foo + bar; ++< ++But some people prefer it if the whole lines are commented like: > ++ /*int foo = 3;*/ ++ /*int bar = 9;*/ ++ int baz = foo + bar; ++< ++If you prefer the second option then stick this line in your .vimrc: > ++ let NERD_comment_whole_lines_in_v_mode=1 ++< ++ ++If the filetype you are editing only has no multipart delimiters (for example ++a shell script) and you hadnt set this option then the above would become > ++ in#t foo = 3; ++ #int bar = 9; ++< ++(where # is the comment delimiter) as this is the closest NERD_comments can ++come to commenting out exactly what was selected. If you prefer for whole ++lines to be commented out when there is no multipart delimiters but the EXACT ++text that was selected to be commented out if there IS multipart delimiters ++then stick the following line in your .vimrc: > ++ let NERD_comment_whole_lines_in_v_mode=2 ++< ++ ++Note that this option does not affect the behaviour of visual-block mode (). ++ ++----------------------------------------------------------------------------- ++ *NERD_dont_remove_alt_coms* ++When uncommenting a line when there is an alternative commenting style for the ++current filetype, this option tells the script not to look for, and remove, ++comments delimiters of the alternative style. > ++ let NERD_dont_remove_alt_coms=1 ++< ++For example, if you are editing a c++ file using // style comments and you go ++cu on this line: > ++ /* This is a c++ comment baby! */ ++< ++It will not be uncommented if the NERD_dont_remove_alt_coms is set to 1. ++ ++----------------------------------------------------------------------------- ++ *NERD_dont_remove_spaces_regexp* ++By default, the NERD commenter will remove spaces around comment delimiters if ++either: ++1. The current filetype matches the |NERD_space_delim_filetype_regexp| option ++ (which is a regular expression). ++2. The current filtype doesnt match NERD_dont_remove_spaces_regexp option ++ (which is also a reg exp) ++ ++This means that if we have the following lines in a c code file: > ++ /* int foo = 5; */ ++ /* int bar = 10; */ ++ int baz = foo + bar ++< ++If either of the above conditions hold then if these lines are uncommented ++they will become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++Otherwise they would become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++If you want the spaces to be removed only if the current filetype matches ++|NERD_space_delim_filetype_regexp| then set the ++NERD_dont_remove_spaces_regexp option in your vimrc so that it matches the ++desired filetypes. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++Defaults to "^python$" ++ ++----------------------------------------------------------------------------- ++ *NERD_create_h_filetype* ++If this option is set then NERD_comments will create a seperate filetype for h ++files. This could be needed because some versions of vim treat h files as cpp ++files which can be dodgy for commenting because if you are using // to comment ++cpp files then this is invalid when you are commenting h files for a c ++project (unless you arent adhering to the ANSI standard... naughty naughty). ++To enable this option, stick the following line in your .vimrc: > ++ let NERD_create_h_filetype = 1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_lPlace* ++ *NERD_rPlace* ++These options are used to control the strings used as place-holder delimiters. ++Place holder delimiters are used when performing nested commenting when the ++filetype supports commenting styles with both left and right delimiters. ++To set these options use lines like: > ++ let NERD_lPlace="FOO" ++ let NERD_rPlace="BAR" ++< ++Following the above example, if we have line of c code: > ++ /* int horse */ ++< ++and we comment it with cn it will be changed to: > ++ /*FOO int horse BAR*/ ++< ++When we uncomment this line it will go back to what it was. ++NERD_lPlace defaults to '[>', NERD_rPlace defaults to '<]'. ++ ++----------------------------------------------------------------------------- ++ *NERD_left_align_regexp* ++This option is a regular expression which is used to specify which filetypes ++should have their left delimiters aligned when commenting multiple lines. ++ ++For example, consider this chunk of c code: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 while(foo < 50){ ++ 4 foo = foo + bar; ++ 5 printf("i am just making up this code\n"); ++ 6 printf("i have no idea what im writing\n"); ++ 7 } ++< ++If the NERD_left_align_regexp regexp covers c files then if we select lines ++3-7 in visual mode and hit cc the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /*while(foo < 50){*/ ++ 4 /* foo = foo + bar;*/ ++ 5 /* printf("i am just making up this code\n");*/ ++ 6 /* printf("i have no idea what im writing\n");*/ ++ 7 /*}*/ ++< ++If NERD_left_align_regexp doesnt cover c files then the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /* while(foo < 50){ */ ++ 4 /* foo = foo + bar; */ ++ 5 /* printf("i am just making up this code\n"); */ ++ 6 /* printf("i have no idea what im writing\n"); */ ++ 7 /* } */ ++< ++NERD_left_align_regexp defaults to '^$' meaning no filetypes have their left ++delims aligned. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_mapleader* ++NERD_mapleader is used to specify what all the NERD commenter key mappings ++begin with. ++ ++Assuming that == '\', the default key mappings will look like this: > ++ \cc ++ \cu ++ \ca ++ \ci ++ \cs ++ ... ++< ++However, if this line: > ++ let NERD_mapleader = ',x' ++< ++were present in your vimrc then the default mappings would look like this: > ++ ,xc ++ ,xu ++ ,xa ++ ,xi ++ ,xs ++ ... ++< ++This option only affects the mappings that have not been explicitly set ++manually (see |NERD_com-cust-keys|). ++ ++Default is c. ++ ++----------------------------------------------------------------------------- ++ *NERD_menu_mode* ++This option can take 3 values: ++ "0": Turns the NERD commenter menu off completely. ++ "1": Turns the NERD commenter menu on with no menu shortcut. ++ "2": Turns the NERD commenter menu on with -c as the menu shortcut. ++ ++Default is "2". ++ ++----------------------------------------------------------------------------- ++ *NERD_place_holder_regexp* ++This option is a regular expression which is used to specify which filetypes ++place-holder delimiters should be used for when adding nested comments. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_right_align_regexp* ++This option is a regular expression which is used to specify which filetypes ++should have their right delimiters aligned when commenting multiple lines. ++ ++For example, consider this chunk of c code: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 while(foo < 50){ ++ 4 foo = foo + bar; ++ 5 printf("i am just making up this code\n"); ++ 6 printf("i have no idea what im writing\n"); ++ 7 } ++< ++If the NERD_right_align_regexp regexp covers c files then if we select lines ++3-7 in visual mode and hit cc the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /*while(foo < 50){ */ ++ 4 /*foo = foo + bar; */ ++ 5 /*printf("i am just making up this code\n"); */ ++ 6 /*printf("i have no idea what im writing\n");*/ ++ 7 /*} */ ++< ++If NERD_right_align_regexp doesnt cover c files then the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /* while(foo < 50){ */ ++ 4 /* foo = foo + bar; */ ++ 5 /* printf("i am just making up this code\n"); */ ++ 6 /* printf("i have no idea what im writing\n"); */ ++ 7 /* } */ ++< ++NERD_right_align_regexp defaults to '^$' meaning no filetypes have their right ++delims aligned. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_shut_up* ++This option is used to prevent NERD_comments from echoing anything. ++Stick this line in your .vimrc: > ++ let NERD_shut_up=1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_space_delim_filetype_regexp* ++Some people prefer a space after the left delimiter and before the right ++delimiter like this: > ++ /* int foo=2; */ ++< ++as opposed to this: > ++ /*int foo=2;*/ ++< ++This option is a regular expression that is used to specify which filetypes ++NERD_comments should use spaces for (as in the first eg above). ++NERD_space_delim_filetype_regexp defaults to '^$'. ++ ++See also |NERD_dont_remove_spaces_regexp|. ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_use_compact_sexy_com_regexp* ++Some people may want their sexy comments to be like this: > ++ /* Hi There! ++ * This is a sexy comment ++ * in c */ ++< ++As opposed to like this: > ++ /* ++ * Hi There! ++ * This is a sexy comment ++ * in c ++ */ ++< ++The option NERD_use_compact_sexy_com_regexp is a regular expression. If the ++filetype that the user is commenting matches this regular expression then when ++they do sexy comments they will look like the first comment above. ++ ++----------------------------------------------------------------------------- ++ *NERD_use_nested_comments_default* ++When this option is turned on comments are nested automatically. That is, if ++you hit cc on a line that is already commented, or contains comments, ++it will be commented again. > ++ let NERD_use_nested_comments_default=1 ++< ++ ++----------------------------------------------------------------------------- ++3.3 Default delimiter customisation *NERD_com-cust-delims* ++These options are used to tell NERD_comments which delimiters to use for a ++given filetype when it first loads up. To set one of these options just stick ++the corresponding line in your .vimrc. For example: if i want to use /* */ to ++delimit comments in java files instead of // (which is the default) then I ++would stick this line in my .vimrc: > ++ let NERD_use_c_style_java_comments=1 ++< ++ ++Note that if filetype has two commenting styles, which are both supported, you ++can switch between them with ca. See |NERD_com-alt-delim|. These ++options only change which style is used when the script is initialsed. ++ ++NERD_use_ada_with_spaces: use -- instead of -- for ada files. ++NERD_use_c_style_acedb_comments: use /**/ instead of // for acedb files. ++NERD_use_c_style_ch_comments: use /**/ instead of // for ch files. ++NERD_use_c_style_clean_comments: use /**/ instead of // for clean files. ++NERD_use_c_style_clipper_comments: use /**/ instead of // for clipper files. ++NERD_use_c_style_cpp_comments: use /**/ instead of // for c++ files. ++NERD_use_c_style_cs_comments: use /**/ instead of // for c# files. ++NERD_use_c_style_dot_comments: use /**/ instead of // for dot files. ++NERD_use_c_style_dylan_comments: use /**/ instead of // for dylan files. ++NERD_use_c_style_h_comments: use /**/ instead of // for h files. ++NERD_use_c_style_hercules_comments: use /**/ instead of // for hercules files. ++NERD_use_c_style_idl_comments: use /**/ instead of // for idl files. ++NERD_use_c_style_ishd_comments: use /**/ instead of // for ishd files. ++NERD_use_c_style_java_comments: use /**/ instead of // for java files. ++NERD_use_c_style_javascript_comments: use /**/ instead of // for javascript files. ++NERD_use_c_style_kscript_comments: use /**/ instead of // for kscript files. ++NERD_use_c_style_mel_comments: use /**/ instead of // for mel files. ++NERD_use_c_style_named_comments: use /**/ instead of // for named files. ++NERD_use_c_style_pccts_comments: use /**/ instead of // for pccts files. ++NERD_use_c_style_php_comments: use /* */ instead of // for php files. ++NERD_use_c_style_pike_comments: use /**/ instead of // for pike files. ++NERD_use_c_style_pilrc_comments: use /**/ instead of // for pilrc files. ++NERD_use_c_style_plm_comments: use /**/ instead of // for plm files. ++NERD_use_c_style_pov_comments: use /**/ instead of // for pov files. ++NERD_use_c_style_prolog_comments: use /**/ instead of % for prolog files. ++NERD_use_c_style_rc_comments: use /**/ instead of // for rc files. ++NERD_use_c_style_tads_comments: use /**/ instead of // for tads files. ++NERD_use_c_style_tsalt_comments: use /**/ instead of // for tsalt files. ++NERD_use_c_style_uc_comments: use /**/ instead of // for uc files. ++NERD_use_c_style_verilog_comments: use /**/ instead of // for verilog files. ++NERD_use_dash_dash_simula_comments: use -- instead of % for simula files. ++NERD_use_dnl_style_automake_comments: use dnl instead of # for automake files. ++NERD_use_hash_samba_comments: use # instead of ; for samba files. ++NERD_use_long_haskell_comments: use {--} instead of -- for haskell files. ++NERD_use_long_lisp_comments: use #||# instead of ; for lisp files. ++NERD_use_long_lua_comments: use --[[]] instead of -- for lua files. ++NERD_use_paren_star_pascal_comments: use (**) instead of {} for pascal files. ++NERD_use_REM_basic_comments: use REM instead of ' for basic files. ++NERD_use_single_part_c_comments: use // instead of /* */ for c files. ++ ++ ++----------------------------------------------------------------------------- ++3.4 Key mapping customisation *NERD_com-cust-keys* ++ ++These options are used to override the default keys that are used for the ++commenting mappings. Their values must be set to strings. As an example: if ++you wanted to use the mapping foo to uncomment lines of code then ++you would place this line in your vimrc > ++ let NERD_uncom_line_map="foo" ++< ++ ++Check out |NERD_com-functionality| for details about what the following ++mappings do. ++ ++ *NERD_alt_com_map* ++To override the ca mapping, set this option > ++ let NERD_alt_com_map="" ++< ++ *NERD_append_com_map* ++To override the ce mapping, set this option > ++ let NERD_append_com_map="" ++< ++ *NERD_com_align_left_map* ++To override the cl mapping, set this option > ++ let NERD_com_align_left_map="" ++< ++ *NERD_com_align_both_map* ++To override the cb mapping, set this option > ++ let NERD_com_align_both_map="" ++< ++ *NERD_com_align_right_map* ++To override the cr mapping, set this option > ++ let NERD_com_align_right_map="" ++< ++ *NERD_com_in_insert_map* ++To override the mapping, set this option > ++ let NERD_com_in_insert_map="" ++< ++ *NERD_com_line_invert_map* ++To override the ci mapping, set this option > ++ let NERD_com_line_invert_map="" ++< ++ *NERD_com_line_map* ++To override the cc mapping, set this option > ++ let NERD_com_line_map="" ++< ++ *NERD_com_line_nest_map* ++To override the cn mapping, set this option > ++ let NERD_com_line_nest_map="" ++< ++ *NERD_com_line_sexy_map* ++To override the cs mapping, set this option > ++ let NERD_com_line_sexy_map="" ++< ++ *NERD_com_line_toggle_map* ++To override the c mapping, set this option > ++ let NERD_com_line_toggle_map="" ++< ++ *NERD_com_line_minimal_map* ++To override the cm mapping, set this option > ++ let NERD_com_line_minimal_map="" ++< ++ *NERD_com_to_end_of_line_map* ++To override the c$ mapping, set this option > ++ let NERD_com_to_end_of_line_map="" ++< ++ *NERD_com_line_yank_map* ++To override the cy mapping, set this option > ++ let NERD_com_line_yank_map="" ++< ++ *NERD_uncom_line_map* ++To override the cu mapping, set this option > ++ let NERD_uncom_line_map="" ++< ++ ++------------------------------------------------------------------------------ ++3.5 Sample regular expressions *NERD_com-reg-exps* ++ ++Many of the options in the NERD commenter must be set to regular ++expressions... regular expressions can be a bit confusing so i have provided ++some template ones here that you can start from: ++ ++Regexp1: '.*' ++Matches any filetype. This is useful for turning an option on for all files. ++ ++Regexp2: '^$' ++Matches no filetypes. This is useful for turning an option off for all files. ++ ++Regexp3: '^\(java\)$' ++Matches only the java filetype. ++ ++Regexp4: '^\(c\|vim\)$' ++Matches only c and vim filetypes. ++ ++Regexp5: '^\(c.*\|vim\)$' ++Matches filetypes beginning with c (eg c, cpp, cs, etc) as well ++as vim files. ++ ++Regexp6: '^\(c.*\|java\|tex\)$' ++Matches filetypes beginning with c (eg c, cpp, cs, etc) as well as java and ++tex filetypes. ++ ++Regexp7: '^\(python\)\@!' ++Matches anything other than 'python'. ++ ++Regexp8: '^c\(s\)\@!' ++Matches 'c' followed by anything accept an 's'. ++ ++Regexp9: '^\(foo$\|bar$\|baz$\)\@!' ++Matches any strings except 'foo', 'bar' and 'baz'. ++ ++============================================================================== ++4. Issues with the script{{{2 *NERD_com-issues* ++ ++ ++------------------------------------------------------------------------------ ++4.1 Delimiter detection heuristics *NERD_com-heuristics* ++ ++Heuristics are used to distinguish the real comment delimiters ++ ++Because we have comment mappings that place delimiters in the middle of lines, ++removing comment delimiters is a bit tricky. This is because if comment ++delimiters appear in a line doesnt mean they really ARE delimiters. For ++example, Java uses // comments but the line > ++ System.out.println("//"); ++< ++clearly contains no real comment delimiters. ++ ++To distinguish between ``real'' comment delimiters and ``fake'' ones we use a ++set of heuristics. For example, one such heuristic states that any comment ++delimiter that has an odd number of non-escaped " characters both preceding ++and following it on the line is not a comment because it is probably part of a ++string. These heuristics, while usually pretty accurate, will not work for all ++cases. ++ ++------------------------------------------------------------------------------ ++4.2 Nesting issues *NERD_com-nesting* ++ ++If we have some line of code like this: > ++ /*int foo */ = /*5 + 9;*/ ++< ++This will not be uncommented legally. The NERD commenter will remove the ++"outter most" delimiters so the line will become: > ++ int foo */ = /*5 + 9; ++< ++which almost certainly will not be what you want. Nested sets of comments will ++uncomment fine though. Eg: > ++ /*int/* foo =*/ 5 + 9;*/ ++< ++will become: > ++ int/* foo =*/ 5 + 9; ++< ++(Note that in the above examples I have deliberately not used place holders ++for simplicity) ++ ++------------------------------------------------------------------------------ ++4.3 Mark clobbering *NERD_com-mark-clobbering* ++ ++The script clobbers the s and t marks when doing most comments. Im not sure ++how to save and restore the marks yet. ++ ++ ++ ++============================================================================== ++5. TODO list {{{2 *NERD_com-todo* ++ ++Uncommenting of minimal comments needs to be more robust. Currently it is easy ++to get illegal syntax when uncommenting them. ++ ++ ++ ++============================================================================== ++6. Credits {{{2 *NERD_com-credits* ++ ++Thanks and respect to the following people: ++ ++Thanks to Nick Brettell for his many ideas and criticisms. A bloody good ++bastard. ++:normal :.-2s/good// ++ ++Thanks to Matthew Hawkins for his awesome refactoring! ++ ++Thanks to the authors of the vimspell whose documentation ++installation function I stole :) ++ ++Thanks to Greg Searle for the idea of using place-holders for nested comments. ++ ++Thanks to Nguyen for the suggestions and pointing the h file highlighting bug! ++Also, thanks for the idea of doing sexy comments as well as his suggestions ++relating to it :P ++Thanks again to Nguyen for complaining about the NERD_comments menu mapping ++(-c) interfering with another mapping of his... and thus the ++NERD_dont_create_menu_shortcut option was born :P ++(it was then replaced with NERD_menu_mode in version 1.67 :) ++ ++Thanks to Sam R for pointing out some filetypes that NERD_comments could support! ++ ++Cheers to Litchi for the idea of having a mapping that appends a comment to ++the current line :) ++ ++Thanks to jorge scandaliaris and Shufeng Zheng for telling me about some ++problems with commenting in visual mode. Thanks again to Jorge for his ++continued suggestions on this matter :) ++ ++Thanks to Martin Stubenschrott for pointing out a bug with the mapping ++:) Ive gotta stop breaking this mapping! ++ ++Thanks to Markus Erlmann for pointing out a conflict that this script was ++having with the taglist plugin. ++ ++Thanks to Brent Rice for alerting me about, and helping me track down, a bug ++in the script when the "ignorecase" option in vim was set. ++ ++Thanks to Richard Willis for telling me about how line continuation was ++causing problems on cygwin. Also, thanks pointing out a bug in the help file ++and for suggesting // comments for c (its about time SOMEONE did :P). May ANSI ++have mercy on your soul :) ++ ++Thanks to Igor Prischepoff for suggesting that i implement "toggle comments". ++Also, thanks for his suggested improvements about toggle comments after i ++implemented them. ++ ++Thanks to harry for telling me that i broke the cn mapping in 1.53 :), ++and thanks again for telling me about a bug that occurred when editing a file ++in a new tab. ++ ++Thanks to Martin (Krischikim?) for his patch that fixed a bug with the doc ++install function and added support for ada comments with spaces as well as ++making a couple of other small changes. ++ ++Thanks to David Bourgeois for pointing out a bug with when commenting c files ++:)... [a few days later] ok i completely misunderstood what David was talking ++about and ended up fixing a completely different bug to what he was talking ++about :P ++ ++Thanks to David Bourgeois for pointing out a bug when changing buffers. ++ ++Cheers to Eike Von Seggern for sending me a patch to fix a bug in 1.60 that ++was causing spaces to be added to the end of lines with single-part ++delimiters. It's nice when people do my work for me :D ++ ++Thanks to Torsten Blix for telling me about a couple of bugs when uncommenting ++sexy comments. Sexy comments dont look so sexy when they are only half removed ++:P ++ ++Thanks to Alexander "boesi" Bosecke for pointing out a bug that was stopping ++the NERD_space_delim_filetype_regexp option from working with left aligned ++toggle comments. And for pointing out a bug when initialising VB comments. ++ ++Thanks to Stefano Zacchiroli for suggesting the idea of "Minimal comments". ++And for suggested improvements to minimal comments. ++ ++Thanks to Norick Chen for emailing in a patch that fixed the asp delimiters. ++In 1.65 ++ ++Thanks to Jonathan Derque for alerting me to some filetypes that could be ++supported (Namely: context, plaintext and mail). ++ ++Thanks to Joseph Barker for the sugesting that the menu be an optional ++feature. ++ ++Thanks to Gary Church and Tim Carey-Smith for complaining about the ++keymappings and causing me to introduce the NERD_mapleader option :) ++ ++ ++Cheers to myself for being the best looking man on Earth! ++ ++ ++ vim:tw=78:ts=8:ft=help:norl: +diff -urN vim71/1/doc/.svn/all-wcprops vim71_ada/1/doc/.svn/all-wcprops +--- vim71/1/doc/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,29 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 48 ++/svnroot/gnuada/!svn/ver/788/trunk/tools/vim/doc ++END ++NERD_commenter.txt ++K 25 ++svn:wc:ra_dav:version-url ++V 67 ++/svnroot/gnuada/!svn/ver/695/trunk/tools/vim/doc/NERD_commenter.txt ++END ++taglist.txt ++K 25 ++svn:wc:ra_dav:version-url ++V 60 ++/svnroot/gnuada/!svn/ver/695/trunk/tools/vim/doc/taglist.txt ++END ++matchit.txt ++K 25 ++svn:wc:ra_dav:version-url ++V 60 ++/svnroot/gnuada/!svn/ver/637/trunk/tools/vim/doc/matchit.txt ++END ++ft_ada.txt ++K 25 ++svn:wc:ra_dav:version-url ++V 59 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/doc/ft_ada.txt ++END +diff -urN vim71/1/doc/.svn/dir-prop-base vim71_ada/1/doc/.svn/dir-prop-base +--- vim71/1/doc/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/doc/.svn/entries vim71_ada/1/doc/.svn/entries +--- vim71/1/doc/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,80 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/doc ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-10-20T15:07:17.667304Z ++788 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++NERD_commenter.txt ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++67487d5a77170782f3bad494085dedfb ++2007-04-27T17:57:11.151403Z ++695 ++krischik ++has-props ++ ++taglist.txt ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++33a058766478d752e8d1dfe9071a08f3 ++2007-04-27T17:57:11.151403Z ++695 ++krischik ++has-props ++ ++matchit.txt ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++7ee1544d0c37d7a8d699cf0baf0b70f7 ++2007-03-12T16:56:27.566705Z ++637 ++krischik ++has-props ++ ++ft_ada.txt ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++0e59f93e383b93e67cd824c362123989 ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ +diff -urN vim71/1/doc/.svn/format vim71_ada/1/doc/.svn/format +--- vim71/1/doc/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/format 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/doc/.svn/prop-base/ft_ada.txt.svn-base vim71_ada/1/doc/.svn/prop-base/ft_ada.txt.svn-base +--- vim71/1/doc/.svn/prop-base/ft_ada.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/prop-base/ft_ada.txt.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,5 @@ ++K 13 ++svn:mime-type ++V 10 ++text/plain ++END +diff -urN vim71/1/doc/.svn/prop-base/matchit.txt.svn-base vim71_ada/1/doc/.svn/prop-base/matchit.txt.svn-base +--- vim71/1/doc/.svn/prop-base/matchit.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/prop-base/matchit.txt.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,5 @@ ++K 13 ++svn:mime-type ++V 10 ++text/plain ++END +diff -urN vim71/1/doc/.svn/prop-base/NERD_commenter.txt.svn-base vim71_ada/1/doc/.svn/prop-base/NERD_commenter.txt.svn-base +--- vim71/1/doc/.svn/prop-base/NERD_commenter.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/prop-base/NERD_commenter.txt.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,5 @@ ++K 13 ++svn:mime-type ++V 10 ++text/plain ++END +diff -urN vim71/1/doc/.svn/prop-base/taglist.txt.svn-base vim71_ada/1/doc/.svn/prop-base/taglist.txt.svn-base +--- vim71/1/doc/.svn/prop-base/taglist.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/prop-base/taglist.txt.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,5 @@ ++K 13 ++svn:mime-type ++V 10 ++text/plain ++END +diff -urN vim71/1/doc/.svn/text-base/ft_ada.txt.svn-base vim71_ada/1/doc/.svn/text-base/ft_ada.txt.svn-base +--- vim71/1/doc/.svn/text-base/ft_ada.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/text-base/ft_ada.txt.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,516 @@ ++*ft_ada.txt* Ada File type Plug-ins Last change: 2007 Seb 17 ++ ++ ++ ADA FILE TYPE PLUG-INS REFERENCE MANUAL~ ++ ++ADA *ada.vim* ++ ++1. Syntax Highlighting |ft-ada-syntax| ++2. Plug-in |ft-ada-plugin| ++3. Omni Completion |ft-ada-omni| ++ 3.1 Omni Completion with "gnat xref" |gnat-xref| ++ 3.2 Omni Completion with "ctags" |ada-ctags| ++4. Compiler Support |ada-compiler| ++ 4.1 GNAT |compiler-gnat| ++ 4.1 Dec Ada |compiler-decada| ++5. References |ada-reference| ++ 5.1 Options |ft-ada-options| ++ 5.2 Functions |ft-ada-functions| ++ 5.3 Commands |ft-ada-commands| ++ 5.4 Variables |ft-ada-variables| ++ 5.5 Constants |ft-ada-contstants| ++8. Extra Plug-ins |ada-extra-plugins| ++ ++============================================================================== ++1. Syntax Highlighting ~ ++ *ft-ada-syntax* ++ ++This mode is designed for the 2005 edition of Ada ("Ada 2005"), which includes ++support for objected-programming, protected types, and so on. It handles code ++written for the original Ada language ("Ada83", "Ada87", "Ada95") as well, ++though code which uses Ada 2005-only keywords will be wrongly colored (such ++code should be fixed anyway). For more information about Ada, see ++http://www.adapower.com. ++ ++The Ada mode handles a number of situations cleanly. ++ ++For example, it knows that the "-" in "-5" is a number, but the same character ++in "A-5" is an operator. Normally, a "with" or "use" clause referencing ++another compilation unit is coloured the same way as C's "#include" is coloured. ++If you have "Conditional" or "Repeat" groups coloured differently, then "end ++if" and "end loop" will be coloured as part of those respective groups. ++ ++You can set these to different colours using vim's "highlight" command (e.g., ++to change how loops are displayed, enter the command ":hi Repeat" followed by ++the colour specification; on simple terminals the colour specification ++ctermfg=White often shows well). ++ ++There are several options you can select in this Ada mode. See|ft-ada-options| ++for a complete list. ++ ++To enable them, assign a value to the option. For example, to turn one on: ++ > ++ > let g:ada_standard_types = 1 ++> ++To disable them use ":unlet". Example: ++> ++ > unlet g:ada_standard_types ++ ++You can just use ":" and type these into the command line to set these ++temporarily before loading an Ada file. You can make these option settings ++permanent by adding the "let" command(s), without a colon, to your "~/.vimrc" ++file. ++ ++Even on a slow (90Mhz) PC this mode works quickly, but if you find the ++performance unacceptable, turn on |g:ada_withuse_ordinary|. ++ ++Syntax folding instructions (|fold-syntax|) are added when |g:ada_folding| is ++set. ++ ++============================================================================== ++2. File type Plug-in ~ ++ *ft-ada-indent* *ft-ada-plugin* ++ ++The Ada plug-in provides support for: ++ ++ - auto indenting (|indent.txt|) ++ - insert completion (|i_CTRL-N|) ++ - user completion (|i_CTRL-X_CTRL-U|) ++ - tag searches (|tagsrch.txt|) ++ - Quick Fix (|quickfix.txt|) ++ - backspace handling (|'backspace'|) ++ - comment handling (|'comments'|, |'commentstring'|) ++ ++The plug-in only activates the features of the Ada mode whenever an Ada ++files is opened and add adds Ada related entries to the main and pop-up menu. ++ ++============================================================================== ++3. Omni Completion ~ ++ *ft-ada-omni* ++ ++The Ada omni-completions (|i_CTRL-X_CTRL-O|) uses tags database created either ++by "gnat xref -v" or the "exuberant Ctags (http://ctags.sourceforge.net). The ++complete function will automatically detect which tool was used to create the ++tags file. ++ ++------------------------------------------------------------------------------ ++3.1 Omni Completion with "gnat xref" ~ ++ *gnat-xref* ++ ++GNAT XREF uses the compiler internal information (ali-files) to produce the ++tags file. This has the advantage to be 100% correct and the option of deep ++nested analysis. However the code must compile, the generator is quite ++slow and the created tags file contains only the basic Ctags information for ++each entry - not enough for some of the more advanced Vim code browser ++plug-ins. ++ ++NOTE: "gnat xref -v" is very tricky to use as it has almost no diagnostic ++ output - If nothing is printed then usually the parameters are wrong. ++ Here some important tips: ++ ++1) You need to compile your code first and use the "-aO" option to point to ++ your .ali files. ++2) "gnat xref -v ../Include/adacl.ads" won't work - use the "gnat xref -v ++ -aI../Include adacl.ads" instead. ++3) "gnat xref -v -aI../Include *.ad?" won't work - use "cd ../Include" and ++ then "gnat xref -v *.ad?" ++4) Project manager support is completely broken - don't even try "gnat xref ++ -Padacl.gpr". ++5) VIM is faster when the tags file is sorted - use "sort --unique ++ --ignore-case --output=tags tags" . ++6) Remember to insert "!_TAG_FILE_SORTED 2 %sort ui" as first line to mark ++ the file assorted. ++ ++------------------------------------------------------------------------------ ++3.2 Omni Completion with "ctags"~ ++ *ada-ctags* ++ ++Exuberant Ctags uses it's own multi-language code parser. The parser is quite ++fast, produces a lot of extra informations (hence the name "Exuberant Ctags") ++and can run on files which currently do not compile. ++ ++There are also lots of other Vim-tools which use exuberant Ctags. ++ ++You will need to install a version of the Exuberant Ctags which has Ada ++support patched in. Such a version is available from the GNU Ada Project ++(http://gnuada.sourceforge.net). ++ ++The Ada parser for Exuberant Ctags is fairly new - don't expect complete ++support yet. ++ ++============================================================================== ++4. Compiler Support ~ ++ *ada-compiler* ++ ++The Ada mode supports more then one Ada compiler and will automatically load the ++compiler set in|g:ada_default_compiler|whenever an Ada source is opened. The ++provided compiler plug-ins are split into the actual compiler plug-in and a ++collection of support functions and variables. This allows the easy ++development of specialized compiler plug-ins fine tuned to your development ++environment. ++ ++------------------------------------------------------------------------------ ++4.1 GNAT ~ ++ *compiler-gnat* ++ ++GNAT is the only free (beer and speech) Ada compiler available. There are ++several version available which differentiate in the licence terms used. ++ ++The GNAT compiler plug-in will perform a compile on pressing and then ++immediately shows the result. You can set the project file to be used by ++setting: ++ > ++ > call g:gnat.Set_Project_File ('my_project.gpr') ++ ++Setting a project file will also create a Vim session (|views-sessions|) so - ++like with the GPS - opened files, window positions etc. will remembered ++separately for all projects. ++ ++ *gnat_members* ++GNAT OBJECT ~ ++ ++ *g:gnat.Make()* ++g:gnat.Make() ++ Calls|g:gnat.Make_Command|and displays the result inside a ++ |quickfix| window. ++ ++ *g:gnat.Pretty()* ++g:gnat.Pretty() ++ Calls|g:gnat.Pretty_Command| ++ ++ *g:gnat.Find()* ++g:gnat.Find() ++ Calls|g:gnat.Find_Command| ++ ++ *g:gnat.Tags()* ++g:gnat.Tags() ++ Calls|g:gnat.Tags_Command| ++ ++ *g:gnat.Set_Project_File()* ++g:gnat.Set_Project_File([{file}]) ++ Set gnat project file and load associated session. An open ++ project will be closed and the session written. If called ++ without file name the file selector opens for selection of a ++ project file. If called with an empty string then the project ++ and associated session are closed. ++ ++ *g:gnat.Project_File* ++g:gnat.Project_File string ++ Current project file. ++ ++ *g:gnat.Make_Command* ++g:gnat.Make_Command string ++ External command used for|g:gnat.Make()| (|'makeprg'|). ++ ++ *g:gnat.Pretty_Program* ++g:gnat.Pretty_Program string ++ External command used for|g:gnat.Pretty()| ++ ++ *g:gnat.Find_Program* ++g:gnat.Find_Program string ++ External command used for|g:gnat.Find()| ++ ++ *g:gnat.Tags_Command* ++g:gnat.Tags_Command string ++ External command used for|g:gnat.Tags()| ++ ++ *g:gnat.Error_Format* ++g:gnat.Error_Format string ++ Error format (|'errorformat'|) ++ ++------------------------------------------------------------------------------ ++4.2 Dec Ada ~ ++ *compiler-hpada* *compiler-decada* ++ *compiler-vaxada* *compiler-compaqada* ++ ++Dec Ada (also known by - in chronological order - VAX Ada, Dec Ada, Compaq Ada ++and HP Ada) is a fairly dated Ada 83 compiler. Support is basic: will ++compile the current unit. ++ ++The Dec Ada compiler expects the package name and not the file name to be ++passed a parameter. The compiler plug-in supports the usual file name ++convention to convert the file into a unit name. For separates both '-' and ++'__' are allowed. ++ ++ *decada_members* ++DEC ADA OBJECT ~ ++ ++ *g:decada.Make()* ++g:decada.Make() function ++ Calls|g:decada.Make_Command|and displays the result inside a ++ |quickfix| window. ++ ++ *g:decada.Unit_Name()* ++g:decada.Unit_Name() function ++ Get the Unit name for the current file. ++ ++ *g:decada.Make_Command* ++g:decada.Make_Command string ++ External command used for|g:decadat.Make()| (|'makeprg'|). ++ ++ *g:decada.Error_Format* ++g:decada.Error_Format| string ++ Error format (|'errorformat'|). ++ ++============================================================================== ++5. References ~ ++ *ada-reference* ++ ++------------------------------------------------------------------------------ ++5.1 Options ~ ++ *ft-ada-options* ++ ++ *g:ada_standard_types* ++g:ada_standard_types bool (true when exists) ++ Highlight types in package Standard (e.g., "Float") ++ ++ *g:ada_space_errors* ++ *g:ada_no_trail_space_error* ++ *g:ada_no_tab_space_error* ++ *g:ada_all_tab_usage* ++g:ada_space_errors bool (true when exists) ++ Highlight extraneous errors in spaces ... ++ g:ada_no_trail_space_error ++ - but ignore trailing spaces at the end of a line ++ g:ada_no_tab_space_error ++ - but ignore tabs after spaces ++ g:ada_all_tab_usage ++ - highlight all tab use ++ ++ *g:ada_line_errors* ++g:ada_line_errors bool (true when exists) ++ Highlight lines which are to long. Note: This highlighting ++ option is quite CPU intensive. ++ ++ *g:ada_rainbow_color* ++g:ada_rainbow_color bool (true when exists) ++ Use rainbow colours for '(' and ')'. You need the ++ rainbow_parenthesis for this to work ++ ++ *g:ada_folding* ++g:ada_folding set ('sigpft') ++ Use folding for Ada sources. ++ 's': activate syntax folding on load ++ 'p': fold packages ++ 'f': fold functions and procedures ++ 't': fold types ++ 'c': fold conditionals ++ 'g': activate gnat pretty print folding on load ++ 'i': lone 'is' folded with line above ++ 'b': lone 'begin' folded with line above ++ 'p': lone 'private' folded with line above ++ 'x': lone 'exception' folded with line above ++ 'i': activate indent folding on load ++ ++ Note: Syntax folding is in an early (unuseable) stage and ++ indent or gnat pretty folding is suggested. ++ ++ For gnat pretty folding to work the following settings are ++ suggested: -cl3 -M79 -c2 -c3 -c4 -A1 -A2 -A3 -A4 -A5 ++ ++ For indent folding to work the following settings are ++ suggested: shiftwidth=3 softtabstop=3 ++ ++ *g:ada_abbrev* ++g:ada_abbrev bool (true when exists) ++ Add some abbreviations. This feature more or less superseded ++ by the various completion methods. ++ ++ *g:ada_withuse_ordinary* ++g:ada_withuse_ordinary bool (true when exists) ++ Show "with" and "use" as ordinary keywords (when used to ++ reference other compilation units they're normally highlighted ++ specially). ++ ++ *g:ada_begin_preproc* ++g:ada_begin_preproc bool (true when exists) ++ Show all begin-like keywords using the colouring of C ++ preprocessor commands. ++ ++ *g:ada_omni_with_keywords* ++g:ada_omni_with_keywords ++ Add Keywords, Pragmas, Attributes to omni-completions ++ (|compl-omni|). Note: You can always complete then with user ++ completion (|i_CTRL-X_CTRL-U|). ++ ++ *g:ada_extended_tagging* ++g:ada_extended_tagging enum ('jump', 'list') ++ use extended tagging, two options are available ++ 'jump': use tjump to jump. ++ 'list': add tags quick fix list. ++ Normal tagging does not support function or operator ++ overloading as these features are not available in C and ++ tagging was originally developed for C. ++ ++ *g:ada_extended_completion* ++g:ada_extended_completion ++ Uses extended completion for and completions ++ (|i_CTRL-N|). In this mode the '.' is used as part of the ++ identifier so that 'Object.Method' or 'Package.Procedure' are ++ completed together. ++ ++ *g:ada_gnat_extensions* ++g:ada_gnat_extensions bool (true when exists) ++ Support GNAT extensions. ++ ++ *g:ada_with_gnat_project_files* ++g:ada_with_gnat_project_files bool (true when exists) ++ Add gnat project file keywords and Attributes. ++ ++ *g:ada_default_compiler* ++g:ada_default_compiler string ++ set default compiler. Currently supported is 'gnat' and ++ 'decada'. ++ ++An "exists" type is a boolean is considered true when the variable is defined ++and false when the variable is undefined. The value which the variable is ++set makes no difference. ++ ++------------------------------------------------------------------------------ ++5.3 Commands ~ ++ *ft-ada-commands* ++ ++:AdaRainbow *:AdaRainbow* ++ Toggles rainbow colour (|g:ada_rainbow_color|) mode for ++ '(' and ')' ++ ++:AdaLines *:AdaLines* ++ Toggles line error (|g:ada_line_errors|) display ++ ++:AdaSpaces *:AdaSpaces* ++ Toggles space error (|g:ada_space_errors|) display. ++ ++:AdaTagDir *:AdaTagDir* ++ Creates tags file for the directory of the current file. ++ ++:AdaTagFile *:AdaTagFile* ++ Creates tags file for the current file. ++ ++:AdaTypes *:AdaTypes* ++ Toggles standard types (|g:ada_standard_types|) colour. ++ ++:GnatFind *:GnatFind* ++ Calls |g:gnat.Find()| ++ ++:GnatPretty *:GnatPretty* ++ Calls |g:gnat.Pretty()| ++ ++:GnatTags *:GnatTags* ++ Calls |g:gnat.Tags()| ++ ++------------------------------------------------------------------------------ ++5.3 Variables ~ ++ *ft-ada-variables* ++ ++ *g:gnat* ++g:gnat object ++ Control object which manages GNAT compiles. The object ++ is created when the first Ada source code is loaded provided ++ that |g:ada_default_compiler|is set to 'gnat'. See|gnat_members| ++ for details. ++ ++ *g:decada* ++g:decada object ++ Control object which manages Dec Ada compiles. The object ++ is created when the first Ada source code is loaded provided ++ that |g:ada_default_compiler|is set to 'decada'. See ++ |decada_members|for details. ++ ++------------------------------------------------------------------------------ ++5.4 Constants ~ ++ *ft-ada-constants* ++ ft-ada-constants ++ ++All constants are locked. See |:lockvar| for details. ++ ++ *g:ada#WordRegex* ++g:ada#WordRegex string ++ Regular expression to search for Ada words ++ ++ *g:ada#DotWordRegex* ++g:ada#DotWordRegex string ++ Regular expression to search for Ada words separated by dots. ++ ++ *g:ada#Comment* ++g:ada#Comment string ++ Regular expression to search for Ada comments ++ ++ *g:ada#Keywords* ++g:ada#Keywords list of dictionaries ++ List of keywords, attributes etc. pp. in the format used by ++ omni completion. See |complete-items| for details. ++ ++ *g:ada#Ctags_Kinds* ++g:ada#Ctags_Kinds dictionary of lists ++ Dictionary of the various kinds of items which the Ada support ++ for Ctags generates. ++ ++------------------------------------------------------------------------------ ++5.2 Functions ~ ++ *ft-ada-functions* ++ ++ada#Word([{line}, {col}]) *ada#Word()* ++ Return full name of Ada entity under the cursor (or at given ++ line/column), stripping white space/newlines as necessary. ++ ++ada#List_Tag([{line}, {col}]) *ada#Listtags()* ++ List all occurrences of the Ada entity under the cursor (or at ++ given line/column) inside the quick-fix window ++ ++ada#Jump_Tag ({ident}, {mode}) *ada#Jump_Tag()* ++ List all occurrences of the Ada entity under the cursor (or at ++ given line/column) in the tag jump list. Mode can either be ++ 'tjump' or 'stjump'. ++ ++ada#Create_Tags ({option}) *ada#Create_Tags()* ++ Creates tag file using Ctags. The option can either be 'file' ++ for the current file, 'dir' for the directory of the current ++ file or a file name. ++ ++gnat#Insert_Tags_Header() *gnat#Insert_Tags_Header()* ++ Adds the tag file header (!_TAG_) information to the current ++ file which are missing from the GNAT XREF output. ++ ++ada#Switch_Syntax_Option ({option}) *ada#Switch_Syntax_Option()* ++ Toggles highlighting options on or off. Used for the Ada menu. ++ ++ *gnat#New()* ++gnat#New () ++ Create a new gnat object. See |g:gnat| for details. ++ ++ ++============================================================================== ++8. Extra Plugins ~ ++ *ada-extra-plugins* ++ ++You can optionally install the following extra plug-in. They work well with Ada ++and enhance the ability of the Ada mode.: ++ ++backup.vim ++ http://www.vim.org/scripts/script.php?script_id=1537 ++ Keeps as many backups as you like so you don't have to. ++ ++rainbow_parenthsis.vim ++ http://www.vim.org/scripts/script.php?script_id=1561 ++ Very helpful since Ada uses only '(' and ')'. ++ ++nerd_comments.vim ++ http://www.vim.org/scripts/script.php?script_id=1218 ++ Excellent commenting and uncommenting support for almost any ++ programming language. ++ ++matchit.vim ++ http://www.vim.org/scripts/script.php?script_id=39 ++ '%' jumping for any language. The normal '%' jump only works for '{}' ++ style languages. The Ada mode will set the needed search patters. ++ ++taglist.vim ++ http://www.vim.org/scripts/script.php?script_id=273 ++ Source code explorer sidebar. There is a patch for Ada available. ++ ++The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim ++contains all of the above. ++ ++============================================================================== ++vim: textwidth=78 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++vim: filetype=help +diff -urN vim71/1/doc/.svn/text-base/matchit.txt.svn-base vim71_ada/1/doc/.svn/text-base/matchit.txt.svn-base +--- vim71/1/doc/.svn/text-base/matchit.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/text-base/matchit.txt.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,405 @@ ++*matchit.txt* Extended "%" matching ++ ++For instructions on installing this file, type ++ :help matchit-install ++inside Vim. ++ ++For Vim version 6.3. Last change: 2006 Feb 23 ++ ++ ++ VIM REFERENCE MANUAL by Benji Fisher ++ ++*matchit* *matchit.vim* ++ ++1. Extended matching with "%" |matchit-intro| ++2. Activation |matchit-activate| ++3. Configuration |matchit-configure| ++4. Supporting a New Language |matchit-newlang| ++5. Known Bugs and Limitations |matchit-bugs| ++ ++The functionality mentioned here is a plugin, see |add-plugin|. ++This plugin is only available if 'compatible' is not set. ++You can avoid loading this plugin by setting the "loaded_matchit" variable ++in your |vimrc| file: > ++ :let loaded_matchit = 1 ++ ++{Vi does not have any of this} ++ ++============================================================================== ++1. Extended matching with "%" *matchit-intro* ++ ++ *matchit-%* ++% Cycle forward through matching groups, such as "if", "else", "endif", ++ as specified by |b:match_words|. ++ ++ *g%* *v_g%* *o_g%* ++g% Cycle backwards through matching groups, as specified by ++ |b:match_words|. For example, go from "endif" to "else" to "if". ++ ++ *[%* *v_[%* *o_[%* ++[% Go to [count] previous unmatched group, as specified by ++ |b:match_words|. Similar to |[{|. ++ ++ *]%* *v_]%* *o_]%* ++]% Go to [count] next unmatched group, as specified by ++ |b:match_words|. Similar to |]}|. ++ ++ *v_a%* ++a% In Visual mode, select the matching group, as specified by ++ |b:match_words|, containing the cursor. Similar to |v_a[|. ++ A [count] is ignored, and only the first character of the closing ++ pattern is selected. ++ ++In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, ++bracket, or paren to its match. This can be configured with the 'matchpairs' ++option. The matchit plugin extends this in several ways: ++ ++ You can match whole words, such as "if" and "endif", not just ++ single characters. You can also specify a |regular-expression|. ++ You can define groups with more than two words, such as "if", ++ "else", "endif". Banging on the "%" key will cycle from the "if" to ++ the first "else", the next "else", ..., the closing "endif", and back ++ to the opening "if". Nested structures are skipped. Using |g%| goes ++ in the reverse direction. ++ By default, words inside comments and strings are ignored, unless ++ the cursor is inside a comment or string when you type "%". If the ++ only thing you want to do is modify the behavior of "%" so that it ++ behaves this way, you can > ++ :let b:match_words = &matchpairs ++< ++See |matchit-details| for details on what the script does, and |b:match_words| ++for how to specify matching patterns. ++ ++MODES: *matchit-modes* *matchit-v_%* *matchit-o_%* ++ ++Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in ++|motion| commands in |Operator-pending| and |Visual| modes. However, you ++cannot make these motions |linewise| or |characterwise|, since the |:omap|s ++that define them start with "v" in order to make the default behavior ++inclusive. (See |o_v|.) In other words, "dV%" will not work. The ++work-around is to go through Visual mode: "V%d" will work. ++ ++LANGUAGES: *matchit-languages* ++ ++Currently, the following languages are supported: Ada, ASP with VBS, Csh, ++DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, ++SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via ++|filetype-plugin|s. ++ ++To support a new language, see |matchit-newlang| below. ++ ++DETAILS: *matchit-details* *matchit-parse* ++ ++Here is an outline of what matchit.vim does each time you hit the "%" key. If ++there are |backref|s in |b:match_words| then the first step is to produce a ++version in which these back references have been eliminated; if there are no ++|backref|s then this step is skipped. This step is called parsing. For ++example, "\(foo\|bar\):end\1" is parsed to yield ++"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are ++nested groups. If debugging is turned on, the parsed version is saved as ++|b:match_pat|. ++ ++ *matchit-choose* ++Next, the script looks for a word on the current line that matches the pattern ++just constructed. It includes the patterns from the 'matchpairs' option. ++The goal is to do what you expect, which turns out to be a little complicated. ++The script follows these rules: ++ ++ Insist on a match that ends on or after the cursor. ++ Prefer a match that includes the cursor position (that is, one that ++ starts on or before the cursor). ++ Prefer a match that starts as close to the cursor as possible. ++ Prefer a match in |b:match_words| to a match in 'matchpairs'. ++ If more than one pattern in |b:match_words| matches, choose the one ++ that is listed first. ++ ++Examples: ++ ++ Suppose you > ++ :let b:match_words = '<:>,:' ++< and hit "%" with the cursor on or before the "<" in "a is born". ++ The pattern '<' comes first, so it is preferred over '', which ++ also matches. If the cursor is on the "t", however, then '' is ++ preferred, because this matches a bit of text containing the cursor. ++ If the two groups of patterns were reversed then '<' would never be ++ preferred. ++ ++ Suppose you > ++ :let b:match_words = 'if:end if' ++< (Note the space!) and hit "%" with the cursor at the end of "end if". ++ Then "if" matches, which is probably not what you want, but if the ++ cursor starts on the "end " then "end if" is chosen. (You can avoid ++ this problem by using a more complicated pattern.) ++ ++If there is no match, the script falls back on the usual behavior of |%|. If ++debugging is turned on, the matched bit of text is saved as |b:match_match| ++and the cursor column of the start of the match is saved as |b:match_col|. ++ ++Next, the script looks through |b:match_words| (original and parsed versions) ++for the group and pattern that match. If debugging is turned on, the group is ++saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If ++there are |backref|s then, in addition, the matching pattern is saved as ++|b:match_word| and a table of translations is saved as |b:match_table|. If ++there are |backref|s, these are determined from the matching pattern and ++|b:match_match| and substituted into each pattern in the matching group. ++ ++The script decides whether to search forwards or backwards and chooses ++arguments for the |searchpair()| function. Then, the cursor is moved to the ++start of the match, and |searchpair()| is called. By default, matching ++structures inside strings and comments are ignored. This can be changed by ++setting |b:match_skip|. ++ ++============================================================================== ++2. Activation *matchit-activate* ++ ++You can use this script as a plugin, by copying it to your plugin directory. ++See |add-global-plugin| for instructions. You can also add a line to your ++|vimrc| file, such as > ++ :source $VIMRUNTIME/macros/matchit.vim ++or > ++ :runtime macros/matchit.vim ++Either way, the script should start working the next time you start up Vim. ++ ++The script does nothing unless it finds a |buffer-variable| named ++|b:match_words|. The script contains autocommands that set this variable for ++various file types: see |matchit-languages| above. For a new language, you ++can add autocommands to the script or to your vimrc file, but the recommended ++method is to add a line such as > ++ let b:match_words = '\:\' ++to the |filetype-plugin| for your language. See |b:match_words| below for how ++this variable is interpreted. ++ ++TROUBLESHOOTING *matchit-troubleshoot* ++ ++The script should work in most installations of Vim. It may not work if Vim ++was compiled with a minimal feature set, for example if the |+syntax| option ++was not enabled. If your Vim has support for syntax compiled in, but you do ++not have |syntax| highlighting turned on, matchit.vim should work, but it may ++fail to skip matching groups in comments and strings. If the |filetype| ++mechanism is turned off, the |b:match_words| variable will probably not be ++defined automatically. ++ ++============================================================================== ++3. Configuration *matchit-configure* ++ ++There are several variables that govern the behavior of matchit.vim. Note ++that these are variables local to the buffer, not options, so use |:let| to ++define them, not |:set|. Some of these variables have values that matter; for ++others, it only matters whether the variable has been defined. All of these ++can be defined in the |filetype-plugin| or autocommand that defines ++|b:match_words| or "on the fly." ++ ++The main variable is |b:match_words|. It is described in the section below on ++supporting a new language. ++ ++ *MatchError* *matchit-hl* *matchit-highlight* ++MatchError is the highlight group for error messages from the script. By ++default, it is linked to WarningMsg. If you do not want to be bothered by ++error messages, you can define this to be something invisible. For example, ++if you use the GUI version of Vim and your command line is normally white, you ++can do > ++ :hi MatchError guifg=white guibg=white ++< ++ *b:match_ignorecase* ++If you > ++ :let b:match_ignorecase = 1 ++then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END" ++are equivalent. If you > ++ :let b:match_ignorecase = 0 ++then matchit.vim treats "end" and "END" differently. (There will be no ++b:match_infercase option unless someone requests it.) ++ ++ *b:match_debug* ++Define b:match_debug if you want debugging information to be saved. See ++|matchit-debug|, below. ++ ++ *b:match_skip* ++If b:match_skip is defined, it is passed as the skip argument to ++|searchpair()|. This controls when matching structures are skipped, or ++ignored. By default, they are ignored inside comments and strings, as ++determined by the |syntax| mechanism. (If syntax highlighting is turned off, ++nothing is skipped.) You can set b:match_skip to a string, which evaluates to ++a non-zero, numerical value if the match is to be skipped or zero if the match ++should not be skipped. In addition, the following special values are ++supported by matchit.vim: ++ s:foo becomes (current syntax item) =~ foo ++ S:foo becomes (current syntax item) !~ foo ++ r:foo becomes (line before cursor) =~ foo ++ R:foo becomes (line before cursor) !~ foo ++(The "s" is meant to suggest "syntax", and the "r" is meant to suggest ++"regular expression".) ++ ++Examples: ++ ++ You can get the default behavior with > ++ :let b:match_skip = 's:comment\|string' ++< ++ If you want to skip matching structures unless they are at the start ++ of the line (ignoring whitespace) then you can > ++ :let b:match_skip = 'R:^\s*' ++< Do not do this if strings or comments can span several lines, since ++ the normal syntax checking will not be done if you set b:match_skip. ++ ++ In LaTeX, since "%" is used as the comment character, you can > ++ :let b:match_skip = 'r:%' ++< Unfortunately, this will skip anything after "\%", an escaped "%". To ++ allow for this, and also "\\%" (an excaped backslash followed by the ++ comment character) you can > ++ :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%' ++< ++ See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both ++ syntax and a regular expression. ++ ++============================================================================== ++4. Supporting a New Language *matchit-newlang* ++ *b:match_words* ++In order for matchit.vim to support a new language, you must define a suitable ++pattern for |b:match_words|. You may also want to set some of the ++|matchit-configure| variables, as described above. If your language has a ++complicated syntax, or many keywords, you will need to know something about ++Vim's |regular-expression|s. ++ ++The format for |b:match_words| is similar to that of the 'matchpairs' option: ++it is a comma (,)-separated list of groups; each group is a colon(:)-separated ++list of patterns (regular expressions). Commas and backslashes that are part ++of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to ++have only one group; the effect is undefined if a group has only one pattern. ++A simple example is > ++ :let b:match_words = '\:\,' ++ \ . '\:\:\:\' ++(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" ++matches the end of "endif" but "\" does not.) Then banging on the "%" ++key will bounce the cursor between "if" and the matching "endif"; and from ++"while" to any matching "continue" or "break", then to the matching "endwhile" ++and back to the "while". It is almost always easier to use |literal-string|s ++(single quotes) as above: '\' rather than "\\" and so on. ++ ++Exception: If the ":" character does not appear in b:match_words, then it is ++treated as an expression to be evaluated. For example, > ++ :let b:match_words = 'GetMatchWords()' ++allows you to define a function. This can return a different string depending ++on the current syntax, for example. ++ ++Once you have defined the appropriate value of |b:match_words|, you will ++probably want to have this set automatically each time you edit the ++appropriate file type. The recommended way to do this is by adding the ++definition to a |filetype-plugin| file. ++ ++Tips: Be careful that your initial pattern does not match your final pattern. ++See the example above for the use of word-boundary expressions. It is usually ++better to use ".\{-}" (as many as necessary) instead of ".*" (as many as ++possible). See |\{-|. For example, in the string "label", "<.*>" ++matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "" and ++"". ++ ++ *matchit-spaces* *matchit-s:notend* ++If "if" is to be paired with "end if" (Note the space!) then word boundaries ++are not enough. Instead, define a regular expression s:notend that will match ++anything but "end" and use it as follows: > ++ :let s:notend = '\%(\:\' ++< *matchit-s:sol* ++This is a simplified version of what is done for Ada. The s:notend is a ++|script-variable|. Similarly, you may want to define a start-of-line regular ++expression > ++ :let s:sol = '\%(^\|;\)\s*' ++if keywords are only recognized after the start of a line or after a ++semicolon (;), with optional white space. ++ ++ *matchit-backref* *matchit-\1* ++In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the ++INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred ++to as back references, or backrefs. For example, > ++ :let b:match_words = '\:\(h\)\1\>' ++means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note ++that "\1" does not refer to the "\(h\)" in this example. If you have ++"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything ++up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1" ++refers to everything and "\2" refers to "\(parentheses\)". If you use a ++variable such as |s:notend| or |s:sol| in the previous paragraph then remember ++to count any "\(" patterns in this variable. You do not have to count groups ++defined by |\%(\)|. ++ ++It should be possible to resolve back references from any pattern in the ++group. For example, > ++ :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2' ++would not work because "\2" cannot be determined from "morefoo" and "\1" ++cannot be determined from "andbar". On the other hand, > ++ :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' ++should work (and have the same effect as "foobar:barfoo:endfoobar"), although ++this has not been thoroughly tested. ++ ++You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has ++not been thouroughly tested in matchit.vim.) For example, if the keyword "if" ++must occur at the start of the line, with optional white space, you might use ++the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of ++at the start of the line. For another example, if HTML had only one tag then ++one could > ++ :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>' ++so that "%" can bounce between matching "<" and ">" pairs or (starting on ++"tag" or "/tag") between matching tags. Without the |\@<=|, the script would ++bounce from "tag" to the "<" in "", and another "%" would not take you ++back to where you started. ++ ++DEBUGGING *matchit-debug* *:MatchDebug* ++ ++If you are having trouble figuring out the appropriate definition of ++|b:match_words| then you can take advantage of the same information I use when ++debugging the script. This is especially true if you are not sure whether ++your patterns or my script are at fault! To make this more convenient, I have ++made the command :MatchDebug, which defines the variable |b:match_debug| and ++creates a Matchit menu. This menu makes it convenient to check the values of ++the variables described below. You will probably also want to read ++|matchit-details| above. ++ ++Defining the variable |b:match_debug| causes the script to set the following ++variables, each time you hit the "%" key. Several of these are only defined ++if |b:match_words| includes |backref|s. ++ ++ *b:match_pat* ++The b:match_pat variable is set to |b:match_words| with |backref|s parsed. ++ *b:match_match* ++The b:match_match variable is set to the bit of text that is recognized as a ++match. ++ *b:match_col* ++The b:match_col variable is set to the cursor column of the start of the ++matching text. ++ *b:match_wholeBR* ++The b:match_wholeBR variable is set to the comma-separated group of patterns ++that matches, with |backref|s unparsed. ++ *b:match_iniBR* ++The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|. ++ *b:match_ini* ++The b:match_ini variable is set to the first pattern in |b:match_wholeBR|, ++with |backref|s resolved from |b:match_match|. ++ *b:match_tail* ++The b:match_tail variable is set to the remaining patterns in ++|b:match_wholeBR|, with |backref|s resolved from |b:match_match|. ++ *b:match_word* ++The b:match_word variable is set to the pattern from |b:match_wholeBR| that ++matches |b:match_match|. ++ *b:match_table* ++The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in ++|b:match_word|. ++ ++============================================================================== ++5. Known Bugs and Limitations *matchit-bugs* ++ ++Just because I know about a bug does not mean that it is on my todo list. I ++try to respond to reports of bugs that cause real problems. If it does not ++cause serious problems, or if there is a work-around, a bug may sit there for ++a while. Moral: if a bug (known or not) bothers you, let me know. ++ ++The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may ++have undesired effects in Select mode |Select-mode-mapping|. At least, if you ++want to replace the selection with any character in "ag%[]" there will be a ++pause of |'updatetime'| first. ++ ++It would be nice if "\0" were recognized as the entire pattern. That is, it ++would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may ++try to implement this in a future version. (This is not so easy to arrange as ++you might think!) ++ ++============================================================================== ++vim: filetype=help ++vim:tw=78:fo=tcq2: +diff -urN vim71/1/doc/.svn/text-base/NERD_commenter.txt.svn-base vim71_ada/1/doc/.svn/text-base/NERD_commenter.txt.svn-base +--- vim71/1/doc/.svn/text-base/NERD_commenter.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/text-base/NERD_commenter.txt.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,1155 @@ ++*NERD_comments.txt* Plugin for commenting code v169 ++ ++ ++ NERD_COMMENTS REFERENCE MANUAL~ ++ ++ ++ ++ ++ ++============================================================================== ++CONTENTS {{{2 *NERD_comments-contents* ++ ++ 1.Intro...................................|NERD_comments| ++ 2.Functionality provided..................|NERD_com-functionality| ++ 2.1 Functionality Summary.............|NERD_com-functionality-summary| ++ 2.2 Functionality Details.............|NERD_com-functionality-details| ++ 2.2.1 Comment map.................|NERD_com-comment| ++ 2.2.2 Nested comment map..........|NERD_com-nested-comment| ++ 2.2.3 Toggle comment map..........|NERD_com-toggle-comment| ++ 2.2.4 Minimal comment map.........|NERD_com-minimal-comment| ++ 2.2.5 Invert comment map..........|NERD_com-invert-comment| ++ 2.2.6 Sexy comment map............|NERD_com-sexy-comment| ++ 2.2.7 Yank comment map............|NERD_com-yank-comment| ++ 2.2.8 Comment to EOL map..........|NERD_com-EOL-comment| ++ 2.2.9 Append com to line map......|NERD_com-append-comment| ++ 2.2.10 Prepend com to line map....|NERD_com-prepend-comment| ++ 2.2.11 Insert comment map.........|NERD_com-insert-comment| ++ 2.2.12 Use alternate delims map...|NERD_com-alt-delim| ++ 2.2.13 Comment aligned maps.......|NERD_com-aligned-comment| ++ 2.2.14 Uncomment line map.........|NERD_com-uncomment-line| ++ 2.3 Supported filetypes...............|NERD_com-filetypes| ++ 2.4 Sexy Comments.....................|NERD_com_sexy_comments| ++ 3.Customisation...........................|NERD_com-customisation| ++ 3.1 Customisation summary.............|NERD_com-cust-summary| ++ 3.2 Customisation details.............|NERD_com-cust-details| ++ 3.3 Default delimiter customisation...|NERD_com-cust-delims| ++ 3.4 Key mapping customisation.........|NERD_com-cust-keys| ++ 3.5 Sample regular expressions........|NERD_com-reg-exps| ++ 4.Issues with the script..................|NERD_com-issues| ++ 4.1 Delimiter detection heuristics....|NERD_com-heuristics| ++ 4.2 Nesting issues....................|NERD_com-nesting| ++ 4.3 Nesting issues....................|NERD_com-nesting| ++ 4.3 Mark clobbering...................|NERD_com-mark-clobbering| ++ 5.TODO list...............................|NERD_com-todo| ++ 6.Credits.................................|NERD_com-credits| ++ ++============================================================================== ++1. Intro {{{2 *NERD_comments* ++ ++NERD_comments provides a set of handy key mappings for commenting code. These ++mappings are consistent across all supported filetypes. ++ ++When writing NERD_comments I have tried to give it as many features/options as ++possible while keeping it so that the plugin can still be used with little or ++no knowledge of these. The average user need only know about a few key ++mappings to use NERD_comments while there are plenty of other features for the ++l33t nerd take advantage of. ++ ++Enjoy :D ++ ++============================================================================== ++2. Functionality provided {{{2 *NERD_com-functionality* ++ ++------------------------------------------------------------------------------ ++2.1 Functionality summary {{{3 *NERD_com-functionality-summary* ++ ++The following key mappings are provided by default (there is also a menu ++provided that contains menu items corresponding to all the below mappings): ++ ++Note: is a user defined key that is used to start keymappings and ++defaults to \. Check out || for details. ++ ++Most of the following mappings are for normal/visual mode only. The ++|NERD_com-insert-comment| mapping is for insert mode only. ++ ++cc |NERD_com-comment-map| ++Comments out the current line or text selected in visual mode. ++ ++ ++cn |NERD_com-nested-comment| ++Same as |NERD_com-comment-map| but enforces nesting. ++ ++ ++c |NERD_com-toggle-comment| ++Toggles the comment state of the selected line(s). If the topmost selected ++line is commented, all selected lines are uncommented and vice versa. ++ ++ ++cm |NERD_com-minimal-comment| ++Comments the given lines using only one set of multipart delimiters if ++possible. ++ ++ ++ci |NERD_com-invert-comment| ++Toggles the comment state of the selected line(s) individually. Each selected ++line that is commented is uncommented and vice versa. ++ ++ ++cs |NERD_com-sexy-comment| ++Comments out the selected lines ``sexually'' ++ ++ ++cy |NERD_com-yank-comment| ++Same as |NERD_com-comment-map| except that the commented line(s) are yanked ++before commenting. ++ ++ ++c$ |NERD_com-EOL-comment| ++Comments the current line from the cursor to the end of line. ++ ++ ++cA |NERD_com-append-comment| ++Adds comment delimiters to the end of line and goes into insert mode between ++them. ++ ++ ++cI |NERD_com-prepend-comment| ++Adds comment delimiters to the start of line and goes into insert mode between ++them. ++ ++ ++ |NERD_com-insert-comment| ++Adds comment delimiters at the current cursor position and inserts between. ++ ++ ++ca |NERD_com-alt-delim| ++Switches to the alternative set of delimiters. ++ ++ ++cl OR cr OR cb |NERD_com-aligned-comment| ++Same as |NERD_com-comment| except that the delimiters are aligned down the ++left side (cl), the right side (cr) or both sides ++(cb). ++ ++ ++cu |NERD_com-uncomment-line| ++Uncomments the selected line(s). ++ ++------------------------------------------------------------------------------ ++2.2 Functionality details {{{3 *NERD_com-functionality-details* ++ ++------------------------------------------------------------------------------ ++2.2.1 Comment map *NERD_com-comment* ++cc ++Comments out the current line. If multiple lines are selected in visual-line ++mode, they are all commented out. If some text is selected in visual or ++visual-block mode then NERD_comments will try to comment out the exact text ++that is selected using multi-part delimiters if they are available. ++ ++Works in normal, visual, visual-line and visual-block mode. ++ ++Change the mapping with: |NERD_com_line_map|. ++ ++Relevant options: ++|NERD_allow_any_visual_delims_regexp| ++|NERD_comment_whole_lines_in_v_mode| ++|NERD_block_com_after_right| ++|NERD_left_align_regexp| ++|NERD_place_holder_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++------------------------------------------------------------------------------ ++2.2.2 Nested comment map *NERD_com-nested-comment* ++cn ++Performs nested commenting. Works the same as cc except that if a ++line is already commented then it will be commented again. ++ ++If the filetype is covered by the |NERD_place_holder_regexp| option ++then the previous comment delimiters will be replaced by place-holder ++delimiters if needed. Otherwise the nested comment will only be added if the ++current commenting delimiters have no right delimiter (to avoid compiler ++errors) ++ ++Works in normal, visual, visual-line, visual-block modes. ++ ++Change the mapping with: |NERD_com_line_nest_map|. ++ ++Relevant options: ++|NERD_allow_any_visual_delims_regexp| ++|NERD_comment_whole_lines_in_v_mode| ++|NERD_block_com_after_right| ++|NERD_left_align_regexp| ++|NERD_place_holder_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++ ++------------------------------------------------------------------------------ ++2.2.3 Toggle comment map *NERD_com-toggle-comment* ++c ++Toggles commenting of the lines selected. The behaviour of this mapping ++depends on whether the first line selected is commented or not. If so, all ++selected lines are uncommented and vice versa. ++ ++With this mapping, lines are only considered to be commented if a left comment ++delimiter is the first non-space/tab char on the line. ++ ++Works in normal, visual-line, modes. ++Using this mapping in visual or visual-block modes will cause it to work like ++|NERD_com-comment| ++ ++Change the mapping with: |NERD_com_line_toggle_map|. ++ ++Relevant options: ++|NERD_left_align_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++------------------------------------------------------------------------------ ++2.2.4 Minimal comment map *NERD_com-minimal-comment* ++cm ++Comments the selected lines using one set of multipart delimiters if possible. ++ ++For example: if you are programming in c and you select 5 lines and press ++cm then a '/*' will be placed at the start of the top line and a '*/' ++will be placed at the end of the last line. ++ ++Sets of multipart comment delimiters that are between the top and bottom ++selected lines are replaced with place holders (see |NERD_lPlace|) if ++NERD_place_holder_regexp is set for the current filetype. If it is not, then ++the comment will be aborted if place holders are required to prevent illegal ++syntax. ++ ++------------------------------------------------------------------------------ ++2.2.5 Invert comment map *NERD_com-invert-comment* ++ci ++Inverts the commented state of each selected line. If the a selected line is ++commented then it is uncommented and vice versa. Each line is examined and ++commented/uncommented individually. ++ ++With this mapping, lines are only considered to be commented if a left comment ++delimiter is the first non-space/tab char on the line. ++ ++Works in normal, visual-line, modes. ++ ++Change the mapping with: |NERD_com_line_invert_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.6 Sexy comment map *NERD_com-sexy-comment* ++cs ++Comments the selected line(s) ``sexily''... see |NERD_com_sexy_commenting| for ++a description of what sexy comments are. Can only be done on filetypes for ++which there is at least one set of multipart comment delimiters specified. ++ ++Sexy comments cannot be nested and lines inside a sexy comment cannot be ++commented again. ++ ++Works in normal, visual-line. ++ ++Change the mapping with: |NERD_com_line_sexy_map| ++ ++Relevant options: ++|NERD_use_compact_sexy_com_regexp| ++ ++------------------------------------------------------------------------------ ++2.2.7 Yank comment map *NERD_com-yank-comment* ++cy ++Same as cc except that it yanks the line(s) that are commented first. ++ ++Works in normal, visual, visual-line, visual-block modes. ++ ++Change the mapping with: |NERD_com_line_yank_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.8 Comment to EOL map *NERD_com-EOL-comment* ++c$ ++Comments the current line from the current cursor position up to the end of ++the line. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_com_to_end_of_line_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.9 Append com to line map *NERD_com-append-comment* ++cA ++Appends comment delimiters to the end of the current line and goes ++to insert mode between the new delimiters. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_append_com_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.10 Prepend com to line map *NERD_com-prepend-comment* ++cI ++Prepends comment delimiters to the start of the current line and goes to ++insert mode between the new delimiters. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_prepend_com_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.11 Insert comment map *NERD_com-insert-comment* ++ ++Adds comment delimiters at the current cursor position and inserts ++between them. ++ ++Works in insert mode. ++ ++Change the mapping with: |NERD_com_in_insert_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.12 Use alternate delims map *NERD_com-alt-delim* ++ca ++Changes to the alternative commenting style if one is available. For example, ++if the user is editing a c++ file using // comments and they hit ca ++then they will be switched over to /**/ comments. ++keys for this mappings can be overridden with the ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_alt_com_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.13 Comment aligned maps *NERD_com-aligned-comment* ++cl cr cb ++Same as cc except that the comment delimiters are aligned on the left ++side, right side or both sides respectively. These comments are always nested ++if the line(s) are already commented. ++ ++Works in normal, visual-line. ++ ++Change the mappings with: |NERD_com_align_left_map|, |NERD_com_align_right_map| ++and |NERD_com_align_both_map|. ++ ++Relevant options: ++|NERD_left_align_regexp| ++|NERD_right_align_regexp| ++ ++ ++------------------------------------------------------------------------------ ++2.2.14 Uncomment line map *NERD_com-uncomment-line* ++cu ++Uncomments the current line. If multiple lines are selected in ++visual mode then they are all uncommented. ++ ++When uncommenting, if the line contains multiple sets of delimiters then the ++``outtermost'' pair of delimiters will be removed. ++ ++The script uses a set of heurisics to distinguish ``real'' delimiters from ++``fake'' ones when uncommenting. See |NERD_com-issues| for details. ++ ++Works in normal, visual, visual-line, visual-block. ++ ++Change the mapping with: |NERD_uncom_line_map|. ++ ++Relevant options: ++|NERD_dont_remove_alt_coms| ++|NERD_dont_remove_spaces_regexp| ++ ++ ++------------------------------------------------------------------------------ ++2.3 Supported filetypes *NERD_com-filetypes* ++ ++Files that can be commented by this plugin: ++abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asm ++asn aspvbs atlas automake ave awk basic b bc bdf bib bindzone btm caos catalog ++c cfg cg ch cl clean clipper conf config cpp crontab cs csc csp css cterm cupl ++cvs dcl def diff dns dosbatch dosini dot dracula dsl dtd dtml dylan ecd eiffel ++elf elmfilt erlang eruby eterm expect exports fgl focexec form fortran foxpro ++fvwm fx gdb gdmo gnuplot gtkrc haskell hb h help hercules hog html htmlos ia64 ++icon idlang idl indent inform inittab ishd iss ist jam java javascript jess ++jgraph jproperties jproperties jsp kix kscript lace lex lftp lifelines lilo ++lisp lite lotos lout lprolog lscript lss lua lynx m4 make maple masm master ++matlab mel mf mib mma model moduala. modula2 modula3 monk mush muttrc named ++nasm nastran natural ncf netrw nqc nsis ocaml omnimark openroad opl ora ox ++pascal pcap pccts perl pfmain php phtml pic pike pilrc pine plm plsql po ++postscr pov povini ppd ppwiz procmail progress prolog psf ptcap python python ++radiance ratpoison r rc readline rebol registry remind rexx robots rpl ruby sa ++samba sas sather scheme scilab screen scsh sdl sed sgml sgmldecl sgmllnx sicad ++simula sinda skill slang sl slrnrc sm smil smith sml snnsnet snnspat snnsres ++snobol4 spec specman spice sql sqlforms sqlj sqr squid st stp strace svn tads ++taglist tags tak tasm tcl terminfo tex texinfo texmf tf tidy tli trasys tsalt ++tsscl tssgm uc uil vb verilog vgrindefs vhdl vim virata vrml vsejcl webmacro ++wget winbatch wml sh wvdial xdefaults xf86conf xhtml xkb xmath xml xmodmap ++xpm2 xpm xslt yacc yaml z8a ++ ++If a language is not in the list of hardcoded supported filetypes then the ++&commentstring vim option is used. ++ ++ ++------------------------------------------------------------------------------ ++2.4 Sexy Comments *NERD_com_sexy_comments* ++These are comments that use one set of multipart comment delimiters as well as ++one other marker symbol. For example: > ++ /* ++ * This is a c style sexy comment ++ * So there! ++ */ ++ ++ /* This is a c style sexy comment ++ * So there! ++ * But this one is ``compact'' style */ ++< ++Here the multipart delimiters are /* and */ and the marker is *. NERD_comments ++is capable of adding and removing comments of this type. ++ ++ ++============================================================================== ++3. Customisation {{{2 *NERD_com-customisation* ++ ++------------------------------------------------------------------------------ ++3.1 Customisation summary *NERD_com-cust-summary* ++ ++|loaded_nerd_comments| Turns off the script. ++|NERD_allow_any_visual_delims_regexp| Allows multipart alternative delims to ++ be used when commenting in ++ visual/visual-block mode. ++|NERD_block_com_after_right| Forces right delims to be placed when ++ doing visual-block comments. ++|NERD_comment_whole_lines_in_v_mode| Changes behaviour of visual comments. ++|NERD_menu_mode| Determines if a NERD comment menu will ++ be made and whether the menu will have a ++ keyboard shortcut. ++|NERD_dont_remove_alt_coms| Causes alternative comments not to be ++ removed when uncommenting. ++|NERD_dont_remove_spaces_regexp| Causes spaces not to be removed when ++ uncommenting if the filetype doesnt ++ match |NERD_space_delim_filetype_regexp| ++|NERD_create_h_filetype| Creates a new filetype for .h files. ++|NERD_lPlace| Specifies what to use as the left ++ delimiter placeholder when nesting ++ comments. ++|NERD_left_align_regexp| Specifies which filetypes to align left ++ delimiters for. ++|NERD_mapleader| Specifies what all the commenting key ++ mappings will begin with. ++|NERD_place_holder_regexp| Specifies which filetypes may use ++ placeholders when nesting comments. ++|NERD_right_align_regexp| Specifies which filetypes to align right ++ delimiters for. ++|NERD_rPlace| Specifies what to use as the right ++ delimiter placeholder when nesting ++ comments. ++|NERD_shut_up| Stops all output from the script. ++|NERD_space_delim_filetype_regexp| Specifies which filetypes to add spaces ++ around the delimiters for. ++|NERD_use_compact_sexy_com_regexp| Specifies which filetypes to use compact ++ sexy comments for. ++|NERD_use_nested_comments_default| Tells the script to use nested comments ++ by default. ++ ++----------------------------------------------------------------------------- ++3.3 Customisation details *NERD_com-cust-details* ++ ++To enable any of the below options you should put the given line in your ++~/.vimrc ++ ++ *loaded_nerd_comments* ++If this script is driving you insane you can turn it off by setting this ++option > ++ let loaded_nerd_comments=1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_allow_any_visual_delims_regexp* ++This option is set to a regular expression that is used to specify which ++filetypes this option should be turned on for. If this covers the current ++filetype then, when NERD_comments is doing a visual or visual-block comment ++(but not a visual-line comment) it will choose the right delimiters to use for ++the comment. This normally means using the current delimiters if they are ++multipart or using the alternative delimiters if THEY are multipart and the ++current delims are not. For example if we are editing the following java ++code: > ++ float foo = 1221; ++ float bar = 324; ++ System.out.println(foo * bar); ++< ++If we are using // comments and select the "foo" and "bar" in visual-block ++mode, as shown left below (where '|'s are used to represent the visual-block ++boundary), and comment it then it will use the alternative delims as shown on ++the right: > ++ float |foo| = 1221; float /*foo*/ = 1221; ++ float |bar| = 324; float /*bar*/ = 324; ++ System.out.println(foo * bar); System.out.println(foo * bar); ++< ++By default this option is set to '.*' i.e is turned on for all filetypes. ++ ++----------------------------------------------------------------------------- ++ *NERD_block_com_after_right* ++This option affects commenting when it is done in visual-block mode. If this ++option is turned on, lines that begin outside the right boundary of the ++selection block will be commented. Enable this option with: > ++ let NERD_block_com_after_right=1 ++< ++For example, if you are commenting this chunk of c code in visual-block mode ++(where the '|'s are used to represent the visual-block boundary) > ++ #include ++ #include ++ #include ++ |int| main(){ ++ | | printf("SUCK THIS\n"); ++ | | while(1){ ++ | | fork(); ++ | | } ++ |} | ++< ++If NERD_block_com_after_right=1 then this code will become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ /* */ printf("SUCK THIS\n"); ++ /* */ while(1){ ++ /* */ fork(); ++ /* */ } ++ /*} */ ++< ++Otherwise, the code block would become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ printf("SUCK THIS\n"); ++ while(1){ ++ fork(); ++ } ++ /*} */ ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_comment_whole_lines_in_v_mode* ++This option can take 2 values. By default NERD_comments tries to comment out ++exactly what is selected in visual mode (v). For example if you select and ++comment the following c code (using | to represent the visual boundary): > ++ in|t foo = 3; ++ int bar =| 9; ++ int baz = foo + bar; ++< ++This will result in: > ++ in/*t foo = 3;*/ ++ /*int bar =*/ 9; ++ int baz = foo + bar; ++< ++But some people prefer it if the whole lines are commented like: > ++ /*int foo = 3;*/ ++ /*int bar = 9;*/ ++ int baz = foo + bar; ++< ++If you prefer the second option then stick this line in your .vimrc: > ++ let NERD_comment_whole_lines_in_v_mode=1 ++< ++ ++If the filetype you are editing only has no multipart delimiters (for example ++a shell script) and you hadnt set this option then the above would become > ++ in#t foo = 3; ++ #int bar = 9; ++< ++(where # is the comment delimiter) as this is the closest NERD_comments can ++come to commenting out exactly what was selected. If you prefer for whole ++lines to be commented out when there is no multipart delimiters but the EXACT ++text that was selected to be commented out if there IS multipart delimiters ++then stick the following line in your .vimrc: > ++ let NERD_comment_whole_lines_in_v_mode=2 ++< ++ ++Note that this option does not affect the behaviour of visual-block mode (). ++ ++----------------------------------------------------------------------------- ++ *NERD_dont_remove_alt_coms* ++When uncommenting a line when there is an alternative commenting style for the ++current filetype, this option tells the script not to look for, and remove, ++comments delimiters of the alternative style. > ++ let NERD_dont_remove_alt_coms=1 ++< ++For example, if you are editing a c++ file using // style comments and you go ++cu on this line: > ++ /* This is a c++ comment baby! */ ++< ++It will not be uncommented if the NERD_dont_remove_alt_coms is set to 1. ++ ++----------------------------------------------------------------------------- ++ *NERD_dont_remove_spaces_regexp* ++By default, the NERD commenter will remove spaces around comment delimiters if ++either: ++1. The current filetype matches the |NERD_space_delim_filetype_regexp| option ++ (which is a regular expression). ++2. The current filtype doesnt match NERD_dont_remove_spaces_regexp option ++ (which is also a reg exp) ++ ++This means that if we have the following lines in a c code file: > ++ /* int foo = 5; */ ++ /* int bar = 10; */ ++ int baz = foo + bar ++< ++If either of the above conditions hold then if these lines are uncommented ++they will become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++Otherwise they would become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++If you want the spaces to be removed only if the current filetype matches ++|NERD_space_delim_filetype_regexp| then set the ++NERD_dont_remove_spaces_regexp option in your vimrc so that it matches the ++desired filetypes. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++Defaults to "^python$" ++ ++----------------------------------------------------------------------------- ++ *NERD_create_h_filetype* ++If this option is set then NERD_comments will create a seperate filetype for h ++files. This could be needed because some versions of vim treat h files as cpp ++files which can be dodgy for commenting because if you are using // to comment ++cpp files then this is invalid when you are commenting h files for a c ++project (unless you arent adhering to the ANSI standard... naughty naughty). ++To enable this option, stick the following line in your .vimrc: > ++ let NERD_create_h_filetype = 1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_lPlace* ++ *NERD_rPlace* ++These options are used to control the strings used as place-holder delimiters. ++Place holder delimiters are used when performing nested commenting when the ++filetype supports commenting styles with both left and right delimiters. ++To set these options use lines like: > ++ let NERD_lPlace="FOO" ++ let NERD_rPlace="BAR" ++< ++Following the above example, if we have line of c code: > ++ /* int horse */ ++< ++and we comment it with cn it will be changed to: > ++ /*FOO int horse BAR*/ ++< ++When we uncomment this line it will go back to what it was. ++NERD_lPlace defaults to '[>', NERD_rPlace defaults to '<]'. ++ ++----------------------------------------------------------------------------- ++ *NERD_left_align_regexp* ++This option is a regular expression which is used to specify which filetypes ++should have their left delimiters aligned when commenting multiple lines. ++ ++For example, consider this chunk of c code: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 while(foo < 50){ ++ 4 foo = foo + bar; ++ 5 printf("i am just making up this code\n"); ++ 6 printf("i have no idea what im writing\n"); ++ 7 } ++< ++If the NERD_left_align_regexp regexp covers c files then if we select lines ++3-7 in visual mode and hit cc the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /*while(foo < 50){*/ ++ 4 /* foo = foo + bar;*/ ++ 5 /* printf("i am just making up this code\n");*/ ++ 6 /* printf("i have no idea what im writing\n");*/ ++ 7 /*}*/ ++< ++If NERD_left_align_regexp doesnt cover c files then the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /* while(foo < 50){ */ ++ 4 /* foo = foo + bar; */ ++ 5 /* printf("i am just making up this code\n"); */ ++ 6 /* printf("i have no idea what im writing\n"); */ ++ 7 /* } */ ++< ++NERD_left_align_regexp defaults to '^$' meaning no filetypes have their left ++delims aligned. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_mapleader* ++NERD_mapleader is used to specify what all the NERD commenter key mappings ++begin with. ++ ++Assuming that == '\', the default key mappings will look like this: > ++ \cc ++ \cu ++ \ca ++ \ci ++ \cs ++ ... ++< ++However, if this line: > ++ let NERD_mapleader = ',x' ++< ++were present in your vimrc then the default mappings would look like this: > ++ ,xc ++ ,xu ++ ,xa ++ ,xi ++ ,xs ++ ... ++< ++This option only affects the mappings that have not been explicitly set ++manually (see |NERD_com-cust-keys|). ++ ++Default is c. ++ ++----------------------------------------------------------------------------- ++ *NERD_menu_mode* ++This option can take 3 values: ++ "0": Turns the NERD commenter menu off completely. ++ "1": Turns the NERD commenter menu on with no menu shortcut. ++ "2": Turns the NERD commenter menu on with -c as the menu shortcut. ++ ++Default is "2". ++ ++----------------------------------------------------------------------------- ++ *NERD_place_holder_regexp* ++This option is a regular expression which is used to specify which filetypes ++place-holder delimiters should be used for when adding nested comments. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_right_align_regexp* ++This option is a regular expression which is used to specify which filetypes ++should have their right delimiters aligned when commenting multiple lines. ++ ++For example, consider this chunk of c code: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 while(foo < 50){ ++ 4 foo = foo + bar; ++ 5 printf("i am just making up this code\n"); ++ 6 printf("i have no idea what im writing\n"); ++ 7 } ++< ++If the NERD_right_align_regexp regexp covers c files then if we select lines ++3-7 in visual mode and hit cc the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /*while(foo < 50){ */ ++ 4 /*foo = foo + bar; */ ++ 5 /*printf("i am just making up this code\n"); */ ++ 6 /*printf("i have no idea what im writing\n");*/ ++ 7 /*} */ ++< ++If NERD_right_align_regexp doesnt cover c files then the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /* while(foo < 50){ */ ++ 4 /* foo = foo + bar; */ ++ 5 /* printf("i am just making up this code\n"); */ ++ 6 /* printf("i have no idea what im writing\n"); */ ++ 7 /* } */ ++< ++NERD_right_align_regexp defaults to '^$' meaning no filetypes have their right ++delims aligned. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_shut_up* ++This option is used to prevent NERD_comments from echoing anything. ++Stick this line in your .vimrc: > ++ let NERD_shut_up=1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_space_delim_filetype_regexp* ++Some people prefer a space after the left delimiter and before the right ++delimiter like this: > ++ /* int foo=2; */ ++< ++as opposed to this: > ++ /*int foo=2;*/ ++< ++This option is a regular expression that is used to specify which filetypes ++NERD_comments should use spaces for (as in the first eg above). ++NERD_space_delim_filetype_regexp defaults to '^$'. ++ ++See also |NERD_dont_remove_spaces_regexp|. ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_use_compact_sexy_com_regexp* ++Some people may want their sexy comments to be like this: > ++ /* Hi There! ++ * This is a sexy comment ++ * in c */ ++< ++As opposed to like this: > ++ /* ++ * Hi There! ++ * This is a sexy comment ++ * in c ++ */ ++< ++The option NERD_use_compact_sexy_com_regexp is a regular expression. If the ++filetype that the user is commenting matches this regular expression then when ++they do sexy comments they will look like the first comment above. ++ ++----------------------------------------------------------------------------- ++ *NERD_use_nested_comments_default* ++When this option is turned on comments are nested automatically. That is, if ++you hit cc on a line that is already commented, or contains comments, ++it will be commented again. > ++ let NERD_use_nested_comments_default=1 ++< ++ ++----------------------------------------------------------------------------- ++3.3 Default delimiter customisation *NERD_com-cust-delims* ++These options are used to tell NERD_comments which delimiters to use for a ++given filetype when it first loads up. To set one of these options just stick ++the corresponding line in your .vimrc. For example: if i want to use /* */ to ++delimit comments in java files instead of // (which is the default) then I ++would stick this line in my .vimrc: > ++ let NERD_use_c_style_java_comments=1 ++< ++ ++Note that if filetype has two commenting styles, which are both supported, you ++can switch between them with ca. See |NERD_com-alt-delim|. These ++options only change which style is used when the script is initialsed. ++ ++NERD_use_ada_with_spaces: use -- instead of -- for ada files. ++NERD_use_c_style_acedb_comments: use /**/ instead of // for acedb files. ++NERD_use_c_style_ch_comments: use /**/ instead of // for ch files. ++NERD_use_c_style_clean_comments: use /**/ instead of // for clean files. ++NERD_use_c_style_clipper_comments: use /**/ instead of // for clipper files. ++NERD_use_c_style_cpp_comments: use /**/ instead of // for c++ files. ++NERD_use_c_style_cs_comments: use /**/ instead of // for c# files. ++NERD_use_c_style_dot_comments: use /**/ instead of // for dot files. ++NERD_use_c_style_dylan_comments: use /**/ instead of // for dylan files. ++NERD_use_c_style_h_comments: use /**/ instead of // for h files. ++NERD_use_c_style_hercules_comments: use /**/ instead of // for hercules files. ++NERD_use_c_style_idl_comments: use /**/ instead of // for idl files. ++NERD_use_c_style_ishd_comments: use /**/ instead of // for ishd files. ++NERD_use_c_style_java_comments: use /**/ instead of // for java files. ++NERD_use_c_style_javascript_comments: use /**/ instead of // for javascript files. ++NERD_use_c_style_kscript_comments: use /**/ instead of // for kscript files. ++NERD_use_c_style_mel_comments: use /**/ instead of // for mel files. ++NERD_use_c_style_named_comments: use /**/ instead of // for named files. ++NERD_use_c_style_pccts_comments: use /**/ instead of // for pccts files. ++NERD_use_c_style_php_comments: use /* */ instead of // for php files. ++NERD_use_c_style_pike_comments: use /**/ instead of // for pike files. ++NERD_use_c_style_pilrc_comments: use /**/ instead of // for pilrc files. ++NERD_use_c_style_plm_comments: use /**/ instead of // for plm files. ++NERD_use_c_style_pov_comments: use /**/ instead of // for pov files. ++NERD_use_c_style_prolog_comments: use /**/ instead of % for prolog files. ++NERD_use_c_style_rc_comments: use /**/ instead of // for rc files. ++NERD_use_c_style_tads_comments: use /**/ instead of // for tads files. ++NERD_use_c_style_tsalt_comments: use /**/ instead of // for tsalt files. ++NERD_use_c_style_uc_comments: use /**/ instead of // for uc files. ++NERD_use_c_style_verilog_comments: use /**/ instead of // for verilog files. ++NERD_use_dash_dash_simula_comments: use -- instead of % for simula files. ++NERD_use_dnl_style_automake_comments: use dnl instead of # for automake files. ++NERD_use_hash_samba_comments: use # instead of ; for samba files. ++NERD_use_long_haskell_comments: use {--} instead of -- for haskell files. ++NERD_use_long_lisp_comments: use #||# instead of ; for lisp files. ++NERD_use_long_lua_comments: use --[[]] instead of -- for lua files. ++NERD_use_paren_star_pascal_comments: use (**) instead of {} for pascal files. ++NERD_use_REM_basic_comments: use REM instead of ' for basic files. ++NERD_use_single_part_c_comments: use // instead of /* */ for c files. ++ ++ ++----------------------------------------------------------------------------- ++3.4 Key mapping customisation *NERD_com-cust-keys* ++ ++These options are used to override the default keys that are used for the ++commenting mappings. Their values must be set to strings. As an example: if ++you wanted to use the mapping foo to uncomment lines of code then ++you would place this line in your vimrc > ++ let NERD_uncom_line_map="foo" ++< ++ ++Check out |NERD_com-functionality| for details about what the following ++mappings do. ++ ++ *NERD_alt_com_map* ++To override the ca mapping, set this option > ++ let NERD_alt_com_map="" ++< ++ *NERD_append_com_map* ++To override the ce mapping, set this option > ++ let NERD_append_com_map="" ++< ++ *NERD_com_align_left_map* ++To override the cl mapping, set this option > ++ let NERD_com_align_left_map="" ++< ++ *NERD_com_align_both_map* ++To override the cb mapping, set this option > ++ let NERD_com_align_both_map="" ++< ++ *NERD_com_align_right_map* ++To override the cr mapping, set this option > ++ let NERD_com_align_right_map="" ++< ++ *NERD_com_in_insert_map* ++To override the mapping, set this option > ++ let NERD_com_in_insert_map="" ++< ++ *NERD_com_line_invert_map* ++To override the ci mapping, set this option > ++ let NERD_com_line_invert_map="" ++< ++ *NERD_com_line_map* ++To override the cc mapping, set this option > ++ let NERD_com_line_map="" ++< ++ *NERD_com_line_nest_map* ++To override the cn mapping, set this option > ++ let NERD_com_line_nest_map="" ++< ++ *NERD_com_line_sexy_map* ++To override the cs mapping, set this option > ++ let NERD_com_line_sexy_map="" ++< ++ *NERD_com_line_toggle_map* ++To override the c mapping, set this option > ++ let NERD_com_line_toggle_map="" ++< ++ *NERD_com_line_minimal_map* ++To override the cm mapping, set this option > ++ let NERD_com_line_minimal_map="" ++< ++ *NERD_com_to_end_of_line_map* ++To override the c$ mapping, set this option > ++ let NERD_com_to_end_of_line_map="" ++< ++ *NERD_com_line_yank_map* ++To override the cy mapping, set this option > ++ let NERD_com_line_yank_map="" ++< ++ *NERD_uncom_line_map* ++To override the cu mapping, set this option > ++ let NERD_uncom_line_map="" ++< ++ ++------------------------------------------------------------------------------ ++3.5 Sample regular expressions *NERD_com-reg-exps* ++ ++Many of the options in the NERD commenter must be set to regular ++expressions... regular expressions can be a bit confusing so i have provided ++some template ones here that you can start from: ++ ++Regexp1: '.*' ++Matches any filetype. This is useful for turning an option on for all files. ++ ++Regexp2: '^$' ++Matches no filetypes. This is useful for turning an option off for all files. ++ ++Regexp3: '^\(java\)$' ++Matches only the java filetype. ++ ++Regexp4: '^\(c\|vim\)$' ++Matches only c and vim filetypes. ++ ++Regexp5: '^\(c.*\|vim\)$' ++Matches filetypes beginning with c (eg c, cpp, cs, etc) as well ++as vim files. ++ ++Regexp6: '^\(c.*\|java\|tex\)$' ++Matches filetypes beginning with c (eg c, cpp, cs, etc) as well as java and ++tex filetypes. ++ ++Regexp7: '^\(python\)\@!' ++Matches anything other than 'python'. ++ ++Regexp8: '^c\(s\)\@!' ++Matches 'c' followed by anything accept an 's'. ++ ++Regexp9: '^\(foo$\|bar$\|baz$\)\@!' ++Matches any strings except 'foo', 'bar' and 'baz'. ++ ++============================================================================== ++4. Issues with the script{{{2 *NERD_com-issues* ++ ++ ++------------------------------------------------------------------------------ ++4.1 Delimiter detection heuristics *NERD_com-heuristics* ++ ++Heuristics are used to distinguish the real comment delimiters ++ ++Because we have comment mappings that place delimiters in the middle of lines, ++removing comment delimiters is a bit tricky. This is because if comment ++delimiters appear in a line doesnt mean they really ARE delimiters. For ++example, Java uses // comments but the line > ++ System.out.println("//"); ++< ++clearly contains no real comment delimiters. ++ ++To distinguish between ``real'' comment delimiters and ``fake'' ones we use a ++set of heuristics. For example, one such heuristic states that any comment ++delimiter that has an odd number of non-escaped " characters both preceding ++and following it on the line is not a comment because it is probably part of a ++string. These heuristics, while usually pretty accurate, will not work for all ++cases. ++ ++------------------------------------------------------------------------------ ++4.2 Nesting issues *NERD_com-nesting* ++ ++If we have some line of code like this: > ++ /*int foo */ = /*5 + 9;*/ ++< ++This will not be uncommented legally. The NERD commenter will remove the ++"outter most" delimiters so the line will become: > ++ int foo */ = /*5 + 9; ++< ++which almost certainly will not be what you want. Nested sets of comments will ++uncomment fine though. Eg: > ++ /*int/* foo =*/ 5 + 9;*/ ++< ++will become: > ++ int/* foo =*/ 5 + 9; ++< ++(Note that in the above examples I have deliberately not used place holders ++for simplicity) ++ ++------------------------------------------------------------------------------ ++4.3 Mark clobbering *NERD_com-mark-clobbering* ++ ++The script clobbers the s and t marks when doing most comments. Im not sure ++how to save and restore the marks yet. ++ ++ ++ ++============================================================================== ++5. TODO list {{{2 *NERD_com-todo* ++ ++Uncommenting of minimal comments needs to be more robust. Currently it is easy ++to get illegal syntax when uncommenting them. ++ ++ ++ ++============================================================================== ++6. Credits {{{2 *NERD_com-credits* ++ ++Thanks and respect to the following people: ++ ++Thanks to Nick Brettell for his many ideas and criticisms. A bloody good ++bastard. ++:normal :.-2s/good// ++ ++Thanks to Matthew Hawkins for his awesome refactoring! ++ ++Thanks to the authors of the vimspell whose documentation ++installation function I stole :) ++ ++Thanks to Greg Searle for the idea of using place-holders for nested comments. ++ ++Thanks to Nguyen for the suggestions and pointing the h file highlighting bug! ++Also, thanks for the idea of doing sexy comments as well as his suggestions ++relating to it :P ++Thanks again to Nguyen for complaining about the NERD_comments menu mapping ++(-c) interfering with another mapping of his... and thus the ++NERD_dont_create_menu_shortcut option was born :P ++(it was then replaced with NERD_menu_mode in version 1.67 :) ++ ++Thanks to Sam R for pointing out some filetypes that NERD_comments could support! ++ ++Cheers to Litchi for the idea of having a mapping that appends a comment to ++the current line :) ++ ++Thanks to jorge scandaliaris and Shufeng Zheng for telling me about some ++problems with commenting in visual mode. Thanks again to Jorge for his ++continued suggestions on this matter :) ++ ++Thanks to Martin Stubenschrott for pointing out a bug with the mapping ++:) Ive gotta stop breaking this mapping! ++ ++Thanks to Markus Erlmann for pointing out a conflict that this script was ++having with the taglist plugin. ++ ++Thanks to Brent Rice for alerting me about, and helping me track down, a bug ++in the script when the "ignorecase" option in vim was set. ++ ++Thanks to Richard Willis for telling me about how line continuation was ++causing problems on cygwin. Also, thanks pointing out a bug in the help file ++and for suggesting // comments for c (its about time SOMEONE did :P). May ANSI ++have mercy on your soul :) ++ ++Thanks to Igor Prischepoff for suggesting that i implement "toggle comments". ++Also, thanks for his suggested improvements about toggle comments after i ++implemented them. ++ ++Thanks to harry for telling me that i broke the cn mapping in 1.53 :), ++and thanks again for telling me about a bug that occurred when editing a file ++in a new tab. ++ ++Thanks to Martin (Krischikim?) for his patch that fixed a bug with the doc ++install function and added support for ada comments with spaces as well as ++making a couple of other small changes. ++ ++Thanks to David Bourgeois for pointing out a bug with when commenting c files ++:)... [a few days later] ok i completely misunderstood what David was talking ++about and ended up fixing a completely different bug to what he was talking ++about :P ++ ++Thanks to David Bourgeois for pointing out a bug when changing buffers. ++ ++Cheers to Eike Von Seggern for sending me a patch to fix a bug in 1.60 that ++was causing spaces to be added to the end of lines with single-part ++delimiters. It's nice when people do my work for me :D ++ ++Thanks to Torsten Blix for telling me about a couple of bugs when uncommenting ++sexy comments. Sexy comments dont look so sexy when they are only half removed ++:P ++ ++Thanks to Alexander "boesi" Bosecke for pointing out a bug that was stopping ++the NERD_space_delim_filetype_regexp option from working with left aligned ++toggle comments. And for pointing out a bug when initialising VB comments. ++ ++Thanks to Stefano Zacchiroli for suggesting the idea of "Minimal comments". ++And for suggested improvements to minimal comments. ++ ++Thanks to Norick Chen for emailing in a patch that fixed the asp delimiters. ++In 1.65 ++ ++Thanks to Jonathan Derque for alerting me to some filetypes that could be ++supported (Namely: context, plaintext and mail). ++ ++Thanks to Joseph Barker for the sugesting that the menu be an optional ++feature. ++ ++Thanks to Gary Church and Tim Carey-Smith for complaining about the ++keymappings and causing me to introduce the NERD_mapleader option :) ++ ++ ++Cheers to myself for being the best looking man on Earth! ++ ++ ++ vim:tw=78:ts=8:ft=help:norl: +diff -urN vim71/1/doc/.svn/text-base/taglist.txt.svn-base vim71_ada/1/doc/.svn/text-base/taglist.txt.svn-base +--- vim71/1/doc/.svn/text-base/taglist.txt.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/.svn/text-base/taglist.txt.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,1494 @@ ++*taglist.txt* Plugin for browsing source code ++ ++Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) ++For Vim version 6.0 and above ++Last change: 2007 February 18 ++ ++1. Overview |taglist-intro| ++2. Taglist on the internet |taglist-internet| ++3. Requirements |taglist-requirements| ++4. Installation |taglist-install| ++5. Usage |taglist-using| ++6. Options |taglist-options| ++7. Commands |taglist-commands| ++8. Global functions |taglist-functions| ++9. Extending |taglist-extend| ++10. FAQ |taglist-faq| ++11. License |taglist-license| ++12. Todo |taglist-todo| ++ ++============================================================================== ++ *taglist-intro* ++1. Overview~ ++ ++The "Tag List" plugin is a source code browser plugin for Vim. This plugin ++allows you to efficiently browse through source code files for different ++programming languages. The "Tag List" plugin provides the following features: ++ ++ * Displays the tags (functions, classes, structures, variables, etc.) ++ defined in a file in a vertically or horizontally split Vim window. ++ * In GUI Vim, optionally displays the tags in the Tags drop-down menu and ++ in the popup menu. ++ * Automatically updates the taglist window as you switch between ++ files/buffers. As you open new files, the tags defined in the new files ++ are added to the existing file list and the tags defined in all the ++ files are displayed grouped by the filename. ++ * When a tag name is selected from the taglist window, positions the ++ cursor at the definition of the tag in the source file. ++ * Automatically highlights the current tag name. ++ * Groups the tags by their type and displays them in a foldable tree. ++ * Can display the prototype and scope of a tag. ++ * Can optionally display the tag prototype instead of the tag name in the ++ taglist window. ++ * The tag list can be sorted either by name or by chronological order. ++ * Supports the following language files: Assembly, ASP, Awk, Beta, C, ++ C++, C#, Cobol, Eiffel, Erlang, Fortran, HTML, Java, Javascript, Lisp, ++ Lua, Make, Pascal, Perl, PHP, Python, Rexx, Ruby, Scheme, Shell, Slang, ++ SML, Sql, TCL, Verilog, Vim and Yacc. ++ * Can be easily extended to support new languages. Support for ++ existing languages can be modified easily. ++ * Provides functions to display the current tag name in the Vim status ++ line or the window title bar. ++ * The list of tags and files in the taglist can be saved and ++ restored across Vim sessions. ++ * Provides commands to get the name and prototype of the current tag. ++ * Runs in both console/terminal and GUI versions of Vim. ++ * Works with the winmanager plugin. Using the winmanager plugin, you ++ can use Vim plugins like the file explorer, buffer explorer and the ++ taglist plugin at the same time like an IDE. ++ * Can be used in both Unix and MS-Windows systems. ++ ++============================================================================== ++ *taglist-internet* ++2. Taglist on the internet~ ++ ++The home page of the taglist plugin is at: ++> ++ http://vim-taglist.sourceforge.net/ ++< ++You can subscribe to the taglist mailing list to post your questions or ++suggestions for improvement or to send bug reports. Visit the following page ++for subscribing to the mailing list: ++> ++ http://groups.yahoo.com/group/taglist ++< ++============================================================================== ++ *taglist-requirements* ++3. Requirements~ ++ ++The taglist plugin requires the following: ++ ++ * Vim version 6.0 and above ++ * Exuberant ctags 5.0 and above ++ ++The taglist plugin will work on all the platforms where the exuberant ctags ++utility and Vim are supported (this includes MS-Windows and Unix based ++systems). ++ ++The taglist plugin relies on the exuberant ctags utility to dynamically ++generate the tag listing. The exuberant ctags utility must be installed in ++your system to use this plugin. The exuberant ctags utility is shipped with ++most of the Linux distributions. You can download the exuberant ctags utility ++from ++> ++ http://ctags.sourceforge.net ++< ++The taglist plugin doesn't use or create a tags file and there is no need to ++create a tags file to use this plugin. The taglist plugin will not work with ++the GNU ctags or the Unix ctags utility. ++ ++This plugin relies on the Vim "filetype" detection mechanism to determine the ++type of the current file. You have to turn on the Vim filetype detection by ++adding the following line to your .vimrc file: ++> ++ filetype on ++< ++The taglist plugin will not work if you run Vim in the restricted mode (using ++the -Z command-line argument). ++ ++The taglist plugin uses the Vim system() function to invoke the exuberant ++ctags utility. If Vim is compiled without the system() function then you ++cannot use the taglist plugin. Some of the Linux distributions (Suse) compile ++Vim without the system() function for security reasons. ++ ++============================================================================== ++ *taglist-install* ++4. Installation~ ++ ++1. Download the taglist.zip file and unzip the files to the $HOME/.vim or the ++ $HOME/vimfiles or the $VIM/vimfiles directory. After this step, you should ++ have the following two files (the directory structure should be preserved): ++ ++ plugin/taglist.vim - main taglist plugin file ++ doc/taglist.txt - documentation (help) file ++ ++ Refer to the |add-plugin|and |'runtimepath'| Vim help pages for more ++ details about installing Vim plugins. ++2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or $VIM/vimfiles/doc ++ directory, start Vim and run the ":helptags ." command to process the ++ taglist help file. Without this step, you cannot jump to the taglist help ++ topics. ++3. If the exuberant ctags utility is not present in one of the directories in ++ the PATH environment variable, then set the 'Tlist_Ctags_Cmd' variable to ++ point to the location of the exuberant ctags utility (not to the directory) ++ in the .vimrc file. ++4. If you are running a terminal/console version of Vim and the terminal ++ doesn't support changing the window width then set the ++ 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file. ++5. Restart Vim. ++6. You can now use the ":TlistToggle" command to open/close the taglist ++ window. You can use the ":help taglist" command to get more information ++ about using the taglist plugin. ++ ++To uninstall the taglist plugin, remove the plugin/taglist.vim and ++doc/taglist.txt files from the $HOME/.vim or $HOME/vimfiles directory. ++ ++============================================================================== ++ *taglist-using* ++5. Usage~ ++ ++The taglist plugin can be used in several different ways. ++ ++1. You can keep the taglist window open during the entire editing session. On ++ opening the taglist window, the tags defined in all the files in the Vim ++ buffer list will be displayed in the taglist window. As you edit files, the ++ tags defined in them will be added to the taglist window. You can select a ++ tag from the taglist window and jump to it. The current tag will be ++ highlighted in the taglist window. You can close the taglist window when ++ you no longer need the window. ++2. You can configure the taglist plugin to process the tags defined in all the ++ edited files always. In this configuration, even if the taglist window is ++ closed and the taglist menu is not displayed, the taglist plugin will ++ processes the tags defined in newly edited files. You can then open the ++ taglist window only when you need to select a tag and then automatically ++ close the taglist window after selecting the tag. ++3. You can configure the taglist plugin to display only the tags defined in ++ the current file in the taglist window. By default, the taglist plugin ++ displays the tags defined in all the files in the Vim buffer list. As you ++ switch between files, the taglist window will be refreshed to display only ++ the tags defined in the current file. ++4. In GUI Vim, you can use the Tags pull-down and popup menu created by the ++ taglist plugin to display the tags defined in the current file and select a ++ tag to jump to it. You can use the menu without opening the taglist window. ++ By default, the Tags menu is disabled. ++5. You can configure the taglist plugin to display the name of the current tag ++ in the Vim window status line or in the Vim window title bar. For this to ++ work without the taglist window or menu, you need to configure the taglist ++ plugin to process the tags defined in a file always. ++6. You can save the tags defined in multiple files to a taglist session file ++ and load it when needed. You can also configure the taglist plugin to not ++ update the taglist window when editing new files. You can then manually add ++ files to the taglist window. ++ ++Opening the taglist window~ ++You can open the taglist window using the ":TlistOpen" or the ":TlistToggle" ++commands. The ":TlistOpen" command opens the taglist window and jumps to it. ++The ":TlistToggle" command opens or closes (toggle) the taglist window and the ++cursor remains in the current window. If the 'Tlist_GainFocus_On_ToggleOpen' ++variable is set to 1, then the ":TlistToggle" command opens the taglist window ++and moves the cursor to the taglist window. ++ ++You can map a key to invoke these commands. For example, the following command ++creates a normal mode mapping for the key to toggle the taglist window. ++> ++ nnoremap :TlistToggle ++< ++Add the above mapping to your ~/.vimrc or $HOME/_vimrc file. ++ ++To automatically open the taglist window on Vim startup, set the ++'Tlist_Auto_Open' variable to 1. ++ ++You can also open the taglist window on startup using the following command ++line: ++> ++ $ vim +TlistOpen ++< ++Closing the taglist window~ ++You can close the taglist window from the taglist window by pressing 'q' or ++using the Vim ":q" command. You can also use any of the Vim window commands to ++close the taglist window. Invoking the ":TlistToggle" command when the taglist ++window is opened, closes the taglist window. You can also use the ++":TlistClose" command to close the taglist window. ++ ++To automatically close the taglist window when a tag or file is selected, you ++can set the 'Tlist_Close_On_Select' variable to 1. To exit Vim when only the ++taglist window is present, set the 'Tlist_Exit_OnlyWindow' variable to 1. ++ ++Jumping to a tag or a file~ ++You can select a tag in the taglist window either by pressing the key ++or by double clicking the tag name using the mouse. To jump to a tag on a ++single mouse click set the 'Tlist_Use_SingleClick' variable to 1. ++ ++If the selected file is already opened in a window, then the cursor is moved ++to that window. If the file is not currently opened in a window then the file ++is opened in the window used by the taglist plugin to show the previously ++selected file. If there are no usable windows, then the file is opened in a ++new window. The file is not opened in special windows like the quickfix ++window, preview window and windows containing buffer with the 'buftype' option ++set. ++ ++To jump to the tag in a new window, press the 'o' key. To open the file in the ++previous window (Ctrl-W_p) use the 'P' key. You can press the 'p' key to jump ++to the tag but still keep the cursor in the taglist window (preview). ++ ++To open the selected file in a tab, use the 't' key. If the file is already ++present in a tab then the cursor is moved to that tab otherwise the file is ++opened in a new tab. To jump to a tag in a new tab press Ctrl-t. The taglist ++window is automatically opened in the newly created tab. ++ ++Instead of jumping to a tag, you can open a file by pressing the key ++or by double clicking the file name using the mouse. ++ ++In the taglist window, you can use the [[ or key to jump to the ++beginning of the previous file. You can use the ]] or key to jump to the ++beginning of the next file. When you reach the first or last file, the search ++wraps around and the jumps to the next/previous file. ++ ++Highlighting the current tag~ ++The taglist plugin automatically highlights the name of the current tag in the ++taglist window. The Vim |CursorHold| autocmd event is used for this. If the ++current tag name is not visible in the taglist window, then the taglist window ++contents are scrolled to make that tag name visible. You can also use the ++":TlistHighlightTag" command to force the highlighting of the current tag. ++ ++The tag name is highlighted if no activity is performed for |'updatetime'| ++milliseconds. The default value for this Vim option is 4 seconds. To avoid ++unexpected problems, you should not set the |'updatetime'| option to a very ++low value. ++ ++To disable the automatic highlighting of the current tag name in the taglist ++window, set the 'Tlist_Auto_Highlight_Tag' variable to zero. ++ ++When entering a Vim buffer/window, the taglist plugin automatically highlights ++the current tag in that buffer/window. If you like to disable the automatic ++highlighting of the current tag when entering a buffer, set the ++'Tlist_Highlight_Tag_On_BufEnter' variable to zero. ++ ++Adding files to the taglist~ ++When the taglist window is opened, all the files in the Vim buffer list are ++processed and the supported files are added to the taglist. When you edit a ++file in Vim, the taglist plugin automatically processes this file and adds it ++to the taglist. If you close the taglist window, the tag information in the ++taglist is retained. ++ ++To process files even when the taglist window is not open, set the ++'Tlist_Process_File_Always' variable to 1. ++ ++You can manually add multiple files to the taglist without opening them using ++the ":TlistAddFiles" and the ":TlistAddFilesRecursive" commands. ++ ++For example, to add all the C files in the /my/project/dir directory to the ++taglist, you can use the following command: ++> ++ :TlistAddFiles /my/project/dir/*.c ++< ++Note that when adding several files with a large number of tags or a large ++number of files, it will take several seconds to several minutes for the ++taglist plugin to process all the files. You should not interrupt the taglist ++plugin by pressing . ++ ++You can recursively add multiple files from a directory tree using the ++":TlistAddFilesRecursive" command: ++> ++ :TlistAddFilesRecursive /my/project/dir *.c ++< ++This command takes two arguments. The first argument specifies the directory ++from which to recursively add the files. The second optional argument ++specifies the wildcard matching pattern for selecting the files to add. The ++default pattern is * and all the files are added. ++ ++Displaying tags for only one file~ ++The taglist window displays the tags for all the files in the Vim buffer list ++and all the manually added files. To display the tags for only the current ++active buffer, set the 'Tlist_Show_One_File' variable to 1. ++ ++Removing files from the taglist~ ++You can remove a file from the taglist window, by pressing the 'd' key when the ++cursor is on one of the tags listed for the file in the taglist window. The ++removed file will no longer be displayed in the taglist window in the current ++Vim session. To again display the tags for the file, open the file in a Vim ++window and then use the ":TlistUpdate" command or use ":TlistAddFiles" command ++to add the file to the taglist. ++ ++When a buffer is removed from the Vim buffer list using the ":bdelete" or the ++":bwipeout" command, the taglist is updated to remove the stored information ++for this buffer. ++ ++Updating the tags displayed for a file~ ++The taglist plugin keeps track of the modification time of a file. When the ++modification time changes (the file is modified), the taglist plugin ++automatically updates the tags listed for that file. The modification time of ++a file is checked when you enter a window containing that file or when you ++load that file. ++ ++You can also update or refresh the tags displayed for a file by pressing the ++"u" key in the taglist window. If an existing file is modified, after the file ++is saved, the taglist plugin automatically updates the tags displayed for the ++file. ++ ++You can also use the ":TlistUpdate" command to update the tags for the current ++buffer after you made some changes to it. You should save the modified buffer ++before you update the taglist window. Otherwise the listed tags will not ++include the new tags created in the buffer. ++ ++If you have deleted the tags displayed for a file in the taglist window using ++the 'd' key, you can again display the tags for that file using the ++":TlistUpdate" command. ++ ++Controlling the taglist updates~ ++To disable the automatic processing of new files or modified files, you can ++set the 'Tlist_Auto_Update' variable to zero. When this variable is set to ++zero, the taglist is updated only when you use the ":TlistUpdate" command or ++the ":TlistAddFiles" or the ":TlistAddFilesRecursive" commands. You can use ++this option to control which files are added to the taglist. ++ ++You can use the ":TlistLock" command to lock the taglist contents. After this ++command is executed, new files are not automatically added to the taglist. ++When the taglist is locked, you can use the ":TlistUpdate" command to add the ++current file or the ":TlistAddFiles" or ":TlistAddFilesRecursive" commands to ++add new files to the taglist. To unlock the taglist, use the ":TlistUnlock" ++command. ++ ++Displaying the tag prototype~ ++To display the prototype of the tag under the cursor in the taglist window, ++press the space bar. If you place the cursor on a tag name in the taglist ++window, then the tag prototype is displayed at the Vim status line after ++|'updatetime'| milliseconds. The default value for the |'updatetime'| Vim ++option is 4 seconds. ++ ++You can get the name and prototype of a tag without opening the taglist window ++and the taglist menu using the ":TlistShowTag" and the ":TlistShowPrototype" ++commands. These commands will work only if the current file is already present ++in the taglist. To use these commands without opening the taglist window, set ++the 'Tlist_Process_File_Always' variable to 1. ++ ++You can use the ":TlistShowTag" command to display the name of the tag at or ++before the specified line number in the specified file. If the file name and ++line number are not supplied, then this command will display the name of the ++current tag. For example, ++> ++ :TlistShowTag ++ :TlistShowTag myfile.java 100 ++< ++You can use the ":TlistShowPrototype" command to display the prototype of the ++tag at or before the specified line number in the specified file. If the file ++name and the line number are not supplied, then this command will display the ++prototype of the current tag. For example, ++> ++ :TlistShowPrototype ++ :TlistShowPrototype myfile.c 50 ++< ++In the taglist window, when the mouse is moved over a tag name, the tag ++prototype is displayed in a balloon. This works only in GUI versions where ++balloon evaluation is supported. ++ ++Taglist window contents~ ++The taglist window contains the tags defined in various files in the taglist ++grouped by the filename and by the tag type (variable, function, class, etc.). ++For tags with scope information (like class members, structures inside ++structures, etc.), the scope information is displayed in square brackets "[]" ++after the tag name. ++ ++The contents of the taglist buffer/window are managed by the taglist plugin. ++The |'filetype'| for the taglist buffer is set to 'taglist'. The Vim ++|'modifiable'| option is turned off for the taglist buffer. You should not ++manually edit the taglist buffer, by setting the |'modifiable'| flag. If you ++manually edit the taglist buffer contents, then the taglist plugin will be out ++of sync with the taglist buffer contents and the plugin will no longer work ++correctly. To redisplay the taglist buffer contents again, close the taglist ++window and reopen it. ++ ++Opening and closing the tag and file tree~ ++In the taglist window, the tag names are displayed as a foldable tree using ++the Vim folding support. You can collapse the tree using the '-' key or using ++the Vim |zc| fold command. You can open the tree using the '+' key or using ++the Vim |zo| fold command. You can open all the folds using the '*' key or ++using the Vim |zR| fold command. You can also use the mouse to open/close the ++folds. You can close all the folds using the '=' key. You should not manually ++create or delete the folds in the taglist window. ++ ++To automatically close the fold for the inactive files/buffers and open only ++the fold for the current buffer in the taglist window, set the ++'Tlist_File_Fold_Auto_Close' variable to 1. ++ ++Sorting the tags for a file~ ++The tags displayed in the taglist window can be sorted either by their name or ++by their chronological order. The default sorting method is by the order in ++which the tags appear in a file. You can change the default sort method by ++setting the 'Tlist_Sort_Type' variable to either "name" or "order". You can ++sort the tags by their name by pressing the "s" key in the taglist window. You ++can again sort the tags by their chronological order using the "s" key. Each ++file in the taglist window can be sorted using different order. ++ ++Zooming in and out of the taglist window~ ++You can press the 'x' key in the taglist window to maximize the taglist ++window width/height. The window will be maximized to the maximum possible ++width/height without closing the other existing windows. You can again press ++'x' to restore the taglist window to the default width/height. ++ ++ *taglist-session* ++Taglist Session~ ++A taglist session refers to the group of files and their tags stored in the ++taglist in a Vim session. ++ ++You can save and restore a taglist session (and all the displayed tags) using ++the ":TlistSessionSave" and ":TlistSessionLoad" commands. ++ ++To save the information about the tags and files in the taglist to a file, use ++the ":TlistSessionSave" command and specify the filename: ++> ++ :TlistSessionSave ++< ++To load a saved taglist session, use the ":TlistSessionLoad" command: > ++ ++ :TlistSessionLoad ++< ++When you load a taglist session file, the tags stored in the file will be ++added to the tags already stored in the taglist. ++ ++The taglist session feature can be used to save the tags for large files or a ++group of frequently used files (like a project). By using the taglist session ++file, you can minimize the amount to time it takes to load/refresh the taglist ++for multiple files. ++ ++You can create more than one taglist session file for multiple groups of ++files. ++ ++Displaying the tag name in the Vim status line or the window title bar~ ++You can use the Tlist_Get_Tagname_By_Line() function provided by the taglist ++plugin to display the current tag name in the Vim status line or the window ++title bar. Similarly, you can use the Tlist_Get_Tag_Prototype_By_Line() ++function to display the current tag prototype in the Vim status line or the ++window title bar. ++ ++For example, the following command can be used to display the current tag name ++in the status line: ++> ++ :set statusline=%<%f%=%([%{Tlist_Get_Tagname_By_Line()}]%) ++< ++The following command can be used to display the current tag name in the ++window title bar: ++> ++ :set title titlestring=%<%f\ %([%{Tlist_Get_Tagname_By_Line()}]%) ++< ++Note that the current tag name can be displayed only after the file is ++processed by the taglist plugin. For this, you have to either set the ++'Tlist_Process_File_Always' variable to 1 or open the taglist window or use ++the taglist menu. For more information about configuring the Vim status line, ++refer to the documentation for the Vim |'statusline'| option. ++ ++Changing the taglist window highlighting~ ++The following Vim highlight groups are defined and used to highlight the ++various entities in the taglist window: ++ ++ TagListTagName - Used for tag names ++ TagListTagScope - Used for tag scope ++ TagListTitle - Used for tag titles ++ TagListComment - Used for comments ++ TagListFileName - Used for filenames ++ ++By default, these highlight groups are linked to the standard Vim highlight ++groups. If you want to change the colors used for these highlight groups, ++prefix the highlight group name with 'My' and define it in your .vimrc or ++.gvimrc file: MyTagListTagName, MyTagListTagScope, MyTagListTitle, ++MyTagListComment and MyTagListFileName. For example, to change the colors ++used for tag names, you can use the following command: ++> ++ :highlight MyTagListTagName guifg=blue ctermfg=blue ++< ++Controlling the taglist window~ ++To use a horizontally split taglist window, instead of a vertically split ++window, set the 'Tlist_Use_Horiz_Window' variable to 1. ++ ++To use a vertically split taglist window on the rightmost side of the Vim ++window, set the 'Tlist_Use_Right_Window' variable to 1. ++ ++You can specify the width of the vertically split taglist window, by setting ++the 'Tlist_WinWidth' variable. You can specify the height of the horizontally ++split taglist window, by setting the 'Tlist_WinHeight' variable. ++ ++When opening a vertically split taglist window, the Vim window width is ++increased to accommodate the new taglist window. When the taglist window is ++closed, the Vim window is reduced. To disable this, set the ++'Tlist_Inc_Winwidth' variable to zero. ++ ++To reduce the number of empty lines in the taglist window, set the ++'Tlist_Compact_Format' variable to 1. ++ ++To not display the Vim fold column in the taglist window, set the ++'Tlist_Enable_Fold_Column' variable to zero. ++ ++To display the tag prototypes instead of the tag names in the taglist window, ++set the 'Tlist_Display_Prototype' variable to 1. ++ ++To not display the scope of the tags next to the tag names, set the ++'Tlist_Display_Tag_Scope' variable to zero. ++ ++ *taglist-keys* ++Taglist window key list~ ++The following table lists the description of the keys that can be used ++in the taglist window. ++ ++ Key Description~ ++ ++ Jump to the location where the tag under cursor is ++ defined. ++ o Jump to the location where the tag under cursor is ++ defined in a new window. ++ P Jump to the tag in the previous (Ctrl-W_p) window. ++ p Display the tag definition in the file window and ++ keep the cursor in the taglist window itself. ++ t Jump to the tag in a new tab. If the file is already ++ opened in a tab, move to that tab. ++ Ctrl-t Jump to the tag in a new tab. ++ Display the prototype of the tag under the cursor. ++ For file names, display the full path to the file, ++ file type and the number of tags. For tag types, display the ++ tag type and the number of tags. ++ u Update the tags listed in the taglist window ++ s Change the sort order of the tags (by name or by order) ++ d Remove the tags for the file under the cursor ++ x Zoom-in or Zoom-out the taglist window ++ + Open a fold ++ - Close a fold ++ * Open all folds ++ = Close all folds ++ [[ Jump to the beginning of the previous file ++ Jump to the beginning of the previous file ++ ]] Jump to the beginning of the next file ++ Jump to the beginning of the next file ++ q Close the taglist window ++ Display help ++ ++The above keys will work in both the normal mode and the insert mode. ++ ++ *taglist-menu* ++Taglist menu~ ++When using GUI Vim, the taglist plugin can display the tags defined in the ++current file in the drop-down menu and the popup menu. By default, this ++feature is turned off. To turn on this feature, set the 'Tlist_Show_Menu' ++variable to 1. ++ ++You can jump to a tag by selecting the tag name from the menu. You can use the ++taglist menu independent of the taglist window i.e. you don't need to open the ++taglist window to get the taglist menu. ++ ++When you switch between files/buffers, the taglist menu is automatically ++updated to display the tags defined in the current file/buffer. ++ ++The tags are grouped by their type (variables, functions, classes, methods, ++etc.) and displayed as a separate sub-menu for each type. If all the tags ++defined in a file are of the same type (e.g. functions), then the sub-menu is ++not used. ++ ++If the number of items in a tag type submenu exceeds the value specified by ++the 'Tlist_Max_Submenu_Items' variable, then the submenu will be split into ++multiple submenus. The default setting for 'Tlist_Max_Submenu_Items' is 25. ++The first and last tag names in the submenu are used to form the submenu name. ++The menu items are prefixed by alpha-numeric characters for easy selection by ++keyboard. ++ ++If the popup menu support is enabled (the |'mousemodel'| option contains ++"popup"), then the tags menu is added to the popup menu. You can access ++the popup menu by right clicking on the GUI window. ++ ++You can regenerate the tags menu by selecting the 'Tags->Refresh menu' entry. ++You can sort the tags listed in the menu either by name or by order by ++selecting the 'Tags->Sort menu by->Name/Order' menu entry. ++ ++You can tear-off the Tags menu and keep it on the side of the Vim window ++for quickly locating the tags. ++ ++Using the taglist plugin with the winmanager plugin~ ++You can use the taglist plugin with the winmanager plugin. This will allow you ++to use the file explorer, buffer explorer and the taglist plugin at the same ++time in different windows. To use the taglist plugin with the winmanager ++plugin, set 'TagList' in the 'winManagerWindowLayout' variable. For example, ++to use the file explorer plugin and the taglist plugin at the same time, use ++the following setting: > ++ ++ let winManagerWindowLayout = 'FileExplorer|TagList' ++< ++Getting help~ ++If you have installed the taglist help file (this file), then you can use the ++Vim ":help taglist-" command to get help on the various taglist ++topics. ++ ++You can press the key in the taglist window to display the help ++information about using the taglist window. If you again press the key, ++the help information is removed from the taglist window. ++ ++ *taglist-debug* ++Debugging the taglist plugin~ ++You can use the ":TlistDebug" command to enable logging of the debug messages ++from the taglist plugin. To display the logged debug messages, you can use the ++":TlistMessages" command. To disable the logging of the debug messages, use ++the ":TlistUndebug" command. ++ ++You can specify a file name to the ":TlistDebug" command to log the debug ++messages to a file. Otherwise, the debug messages are stored in a script-local ++variable. In the later case, to minimize memory usage, only the last 3000 ++characters from the debug messages are stored. ++ ++============================================================================== ++ *taglist-options* ++6. Options~ ++ ++A number of Vim variables control the behavior of the taglist plugin. These ++variables are initialized to a default value. By changing these variables you ++can change the behavior of the taglist plugin. You need to change these ++settings only if you want to change the behavior of the taglist plugin. You ++should use the |:let| command in your .vimrc file to change the setting of any ++of these variables. ++ ++The configurable taglist variables are listed below. For a detailed ++description of these variables refer to the text below this table. ++ ++|'Tlist_Auto_Highlight_Tag'| Automatically highlight the current tag in the ++ taglist. ++|'Tlist_Auto_Open'| Open the taglist window when Vim starts. ++|'Tlist_Auto_Update'| Automatically update the taglist to include ++ newly edited files. ++|'Tlist_Close_On_Select'| Close the taglist window when a file or tag is ++ selected. ++|'Tlist_Compact_Format'| Remove extra information and blank lines from ++ the taglist window. ++|'Tlist_Ctags_Cmd'| Specifies the path to the ctags utility. ++|'Tlist_Display_Prototype'| Show prototypes and not tags in the taglist ++ window. ++|'Tlist_Display_Tag_Scope'| Show tag scope next to the tag name. ++|'Tlist_Enable_Fold_Column'| Show the fold indicator column in the taglist ++ window. ++|'Tlist_Exit_OnlyWindow'| Close Vim if the taglist is the only window. ++|'Tlist_File_Fold_Auto_Close'| Close tag folds for inactive buffers. ++|'Tlist_GainFocus_On_ToggleOpen'| ++ Jump to taglist window on open. ++|'Tlist_Highlight_Tag_On_BufEnter'| ++ On entering a buffer, automatically highlight ++ the current tag. ++|'Tlist_Inc_Winwidth'| Increase the Vim window width to accommodate ++ the taglist window. ++|'Tlist_Max_Submenu_Items'| Maximum number of items in a tags sub-menu. ++|'Tlist_Max_Tag_Length'| Maximum tag length used in a tag menu entry. ++|'Tlist_Process_File_Always'| Process files even when the taglist window is ++ closed. ++|'Tlist_Show_Menu'| Display the tags menu. ++|'Tlist_Show_One_File'| Show tags for the current buffer only. ++|'Tlist_Sort_Type'| Sort method used for arranging the tags. ++|'Tlist_Use_Horiz_Window'| Use a horizontally split window for the ++ taglist window. ++|'Tlist_Use_Right_Window'| Place the taglist window on the right side. ++|'Tlist_Use_SingleClick'| Single click on a tag jumps to it. ++|'Tlist_WinHeight'| Horizontally split taglist window height. ++|'Tlist_WinWidth'| Vertically split taglist window width. ++ ++ *'Tlist_Auto_Highlight_Tag'* ++Tlist_Auto_Highlight_Tag~ ++The taglist plugin will automatically highlight the current tag in the taglist ++window. If you want to disable this, then you can set the ++'Tlist_Auto_Highlight_Tag' variable to zero. Note that even though the current ++tag highlighting is disabled, the tags for a new file will still be added to ++the taglist window. ++> ++ let Tlist_Auto_Highlight_Tag = 0 ++< ++With the above variable set to 1, you can use the ":TlistHighlightTag" command ++to highlight the current tag. ++ ++ *'Tlist_Auto_Open'* ++Tlist_Auto_Open~ ++To automatically open the taglist window, when you start Vim, you can set the ++'Tlist_Auto_Open' variable to 1. By default, this variable is set to zero and ++the taglist window will not be opened automatically on Vim startup. ++> ++ let Tlist_Auto_Open = 1 ++< ++The taglist window is opened only when a supported type of file is opened on ++Vim startup. For example, if you open text files, then the taglist window will ++not be opened. ++ ++ *'Tlist_Auto_Update'* ++Tlist_Auto_Update~ ++When a new file is edited, the tags defined in the file are automatically ++processed and added to the taglist. To stop adding new files to the taglist, ++set the 'Tlist_Auto_Update' variable to zero. By default, this variable is set ++to 1. ++> ++ let Tlist_Auto_Update = 0 ++< ++With the above variable set to 1, you can use the ":TlistUpdate" command to ++add the tags defined in the current file to the taglist. ++ ++ *'Tlist_Close_On_Select'* ++Tlist_Close_On_Select~ ++If you want to close the taglist window when a file or tag is selected, then ++set the 'Tlist_Close_On_Select' variable to 1. By default, this variable is ++set zero and when you select a tag or file from the taglist window, the window ++is not closed. ++> ++ let Tlist_Close_On_Select = 1 ++< ++ *'Tlist_Compact_Format'* ++Tlist_Compact_Format~ ++By default, empty lines are used to separate different tag types displayed for ++a file and the tags displayed for different files in the taglist window. If ++you want to display as many tags as possible in the taglist window, you can ++set the 'Tlist_Compact_Format' variable to 1 to get a compact display. ++> ++ let Tlist_Compact_Format = 1 ++< ++ *'Tlist_Ctags_Cmd'* ++Tlist_Ctags_Cmd~ ++The 'Tlist_Ctags_Cmd' variable specifies the location (path) of the exuberant ++ctags utility. If exuberant ctags is present in any one of the directories in ++the PATH environment variable, then there is no need to set this variable. ++ ++The exuberant ctags tool can be installed under different names. When the ++taglist plugin starts up, if the 'Tlist_Ctags_Cmd' variable is not set, it ++checks for the names exuberant-ctags, exctags, ctags, ctags.exe and tags in ++the PATH environment variable. If any one of the named executable is found, ++then the Tlist_Ctags_Cmd variable is set to that name. ++ ++If exuberant ctags is not present in one of the directories specified in the ++PATH environment variable, then set this variable to point to the location of ++the ctags utility in your system. Note that this variable should point to the ++fully qualified exuberant ctags location and NOT to the directory in which ++exuberant ctags is installed. If the exuberant ctags tool is not found in ++either PATH or in the specified location, then the taglist plugin will not be ++loaded. Examples: ++> ++ let Tlist_Ctags_Cmd = 'd:\tools\ctags.exe' ++ let Tlist_Ctags_Cmd = '/usr/local/bin/ctags' ++< ++ *'Tlist_Display_Prototype'* ++Tlist_Display_Prototype~ ++By default, only the tag name will be displayed in the taglist window. If you ++like to see tag prototypes instead of names, set the 'Tlist_Display_Prototype' ++variable to 1. By default, this variable is set to zero and only tag names ++will be displayed. ++> ++ let Tlist_Display_Prototype = 1 ++< ++ *'Tlist_Display_Tag_Scope'* ++Tlist_Display_Tag_Scope~ ++By default, the scope of a tag (like a C++ class) will be displayed in ++square brackets next to the tag name. If you don't want the tag scopes ++to be displayed, then set the 'Tlist_Display_Tag_Scope' to zero. By default, ++this variable is set to 1 and the tag scopes will be displayed. ++> ++ let Tlist_Display_Tag_Scope = 0 ++< ++ *'Tlist_Enable_Fold_Column'* ++Tlist_Enable_Fold_Column~ ++By default, the Vim fold column is enabled and displayed in the taglist ++window. If you wish to disable this (for example, when you are working with a ++narrow Vim window or terminal), you can set the 'Tlist_Enable_Fold_Column' ++variable to zero. ++> ++ let Tlist_Enable_Fold_Column = 1 ++< ++ *'Tlist_Exit_OnlyWindow'* ++Tlist_Exit_OnlyWindow~ ++If you want to exit Vim if only the taglist window is currently opened, then ++set the 'Tlist_Exit_OnlyWindow' variable to 1. By default, this variable is ++set to zero and the Vim instance will not be closed if only the taglist window ++is present. ++> ++ let Tlist_Exit_OnlyWindow = 1 ++< ++ *'Tlist_File_Fold_Auto_Close'* ++Tlist_File_Fold_Auto_Close~ ++By default, the tags tree displayed in the taglist window for all the files is ++opened. You can close/fold the tags tree for the files manually. To ++automatically close the tags tree for inactive files, you can set the ++'Tlist_File_Fold_Auto_Close' variable to 1. When this variable is set to 1, ++the tags tree for the current buffer is automatically opened and for all the ++other buffers is closed. ++> ++ let Tlist_File_Fold_Auto_Close = 1 ++< ++ *'Tlist_GainFocus_On_ToggleOpen'* ++Tlist_GainFocus_On_ToggleOpen~ ++When the taglist window is opened using the ':TlistToggle' command, this ++option controls whether the cursor is moved to the taglist window or remains ++in the current window. By default, this option is set to 0 and the cursor ++remains in the current window. When this variable is set to 1, the cursor ++moves to the taglist window after opening the taglist window. ++> ++ let Tlist_GainFocus_On_ToggleOpen = 1 ++< ++ *'Tlist_Highlight_Tag_On_BufEnter'* ++Tlist_Highlight_Tag_On_BufEnter~ ++When you enter a Vim buffer/window, the current tag in that buffer/window is ++automatically highlighted in the taglist window. If the current tag name is ++not visible in the taglist window, then the taglist window contents are ++scrolled to make that tag name visible. If you like to disable the automatic ++highlighting of the current tag when entering a buffer, you can set the ++'Tlist_Highlight_Tag_On_BufEnter' variable to zero. The default setting for ++this variable is 1. ++> ++ let Tlist_Highlight_Tag_On_BufEnter = 0 ++< ++ *'Tlist_Inc_Winwidth'* ++Tlist_Inc_Winwidth~ ++By default, when the width of the window is less than 100 and a new taglist ++window is opened vertically, then the window width is increased by the value ++set in the 'Tlist_WinWidth' variable to accommodate the new window. The value ++of this variable is used only if you are using a vertically split taglist ++window. ++ ++If your terminal doesn't support changing the window width from Vim (older ++version of xterm running in a Unix system) or if you see any weird problems in ++the screen due to the change in the window width or if you prefer not to ++adjust the window width then set the 'Tlist_Inc_Winwidth' variable to zero. ++CAUTION: If you are using the MS-Windows version of Vim in a MS-DOS command ++window then you must set this variable to zero, otherwise the system may hang ++due to a Vim limitation (explained in :help win32-problems) ++> ++ let Tlist_Inc_Winwidth = 0 ++< ++ *'Tlist_Max_Submenu_Items'* ++Tlist_Max_Submenu_Items~ ++If a file contains too many tags of a particular type (function, variable, ++class, etc.), greater than that specified by the 'Tlist_Max_Submenu_Items' ++variable, then the menu for that tag type will be split into multiple ++sub-menus. The default setting for the 'Tlist_Max_Submenu_Items' variable is ++25. This can be changed by setting the 'Tlist_Max_Submenu_Items' variable: ++> ++ let Tlist_Max_Submenu_Items = 20 ++< ++The name of the submenu is formed using the names of the first and the last ++tag entries in that submenu. ++ ++ *'Tlist_Max_Tag_Length'* ++Tlist_Max_Tag_Length~ ++Only the first 'Tlist_Max_Tag_Length' characters from the tag names will be ++used to form the tag type submenu name. The default value for this variable is ++10. Change the 'Tlist_Max_Tag_Length' setting if you want to include more or ++less characters: ++> ++ let Tlist_Max_Tag_Length = 10 ++< ++ *'Tlist_Process_File_Always'* ++Tlist_Process_File_Always~ ++By default, the taglist plugin will generate and process the tags defined in ++the newly opened files only when the taglist window is opened or when the ++taglist menu is enabled. When the taglist window is closed, the taglist plugin ++will stop processing the tags for newly opened files. ++ ++You can set the 'Tlist_Process_File_Always' variable to 1 to generate the list ++of tags for new files even when the taglist window is closed and the taglist ++menu is disabled. ++> ++ let Tlist_Process_File_Always = 1 ++< ++To use the ":TlistShowTag" and the ":TlistShowPrototype" commands without the ++taglist window and the taglist menu, you should set this variable to 1. ++ ++ *'Tlist_Show_Menu'* ++Tlist_Show_Menu~ ++When using GUI Vim, you can display the tags defined in the current file in a ++menu named "Tags". By default, this feature is turned off. To turn on this ++feature, set the 'Tlist_Show_Menu' variable to 1: ++> ++ let Tlist_Show_Menu = 1 ++< ++ *'Tlist_Show_One_File'* ++Tlist_Show_One_File~ ++By default, the taglist plugin will display the tags defined in all the loaded ++buffers in the taglist window. If you prefer to display the tags defined only ++in the current buffer, then you can set the 'Tlist_Show_One_File' to 1. When ++this variable is set to 1, as you switch between buffers, the taglist window ++will be refreshed to display the tags for the current buffer and the tags for ++the previous buffer will be removed. ++> ++ let Tlist_Show_One_File = 1 ++< ++ *'Tlist_Sort_Type'* ++Tlist_Sort_Type~ ++The 'Tlist_Sort_Type' variable specifies the sort order for the tags in the ++taglist window. The tags can be sorted either alphabetically by their name or ++by the order of their appearance in the file (chronological order). By ++default, the tag names will be listed by the order in which they are defined ++in the file. You can change the sort type (from name to order or from order to ++name) by pressing the "s" key in the taglist window. You can also change the ++default sort order by setting 'Tlist_Sort_Type' to "name" or "order": ++> ++ let Tlist_Sort_Type = "name" ++< ++ *'Tlist_Use_Horiz_Window'* ++Tlist_Use_Horiz_Window~ ++Be default, the tag names are displayed in a vertically split window. If you ++prefer a horizontally split window, then set the 'Tlist_Use_Horiz_Window' ++variable to 1. If you are running MS-Windows version of Vim in a MS-DOS ++command window, then you should use a horizontally split window instead of a ++vertically split window. Also, if you are using an older version of xterm in a ++Unix system that doesn't support changing the xterm window width, you should ++use a horizontally split window. ++> ++ let Tlist_Use_Horiz_Window = 1 ++< ++ *'Tlist_Use_Right_Window'* ++Tlist_Use_Right_Window~ ++By default, the vertically split taglist window will appear on the left hand ++side. If you prefer to open the window on the right hand side, you can set the ++'Tlist_Use_Right_Window' variable to 1: ++> ++ let Tlist_Use_Right_Window = 1 ++< ++ *'Tlist_Use_SingleClick'* ++Tlist_Use_SingleClick~ ++By default, when you double click on the tag name using the left mouse ++button, the cursor will be positioned at the definition of the tag. You ++can set the 'Tlist_Use_SingleClick' variable to 1 to jump to a tag when ++you single click on the tag name using the mouse. By default this variable ++is set to zero. ++> ++ let Tlist_Use_SingleClick = 1 ++< ++Due to a bug in Vim, if you set 'Tlist_Use_SingleClick' to 1 and try to resize ++the taglist window using the mouse, then Vim will crash. This problem is fixed ++in Vim 6.3 and above. In the meantime, instead of resizing the taglist window ++using the mouse, you can use normal Vim window resizing commands to resize the ++taglist window. ++ ++ *'Tlist_WinHeight'* ++Tlist_WinHeight~ ++The default height of the horizontally split taglist window is 10. This can be ++changed by modifying the 'Tlist_WinHeight' variable: ++> ++ let Tlist_WinHeight = 20 ++< ++The |'winfixheight'| option is set for the taglist window, to maintain the ++height of the taglist window, when new Vim windows are opened and existing ++windows are closed. ++ ++ *'Tlist_WinWidth'* ++Tlist_WinWidth~ ++The default width of the vertically split taglist window is 30. This can be ++changed by modifying the 'Tlist_WinWidth' variable: ++> ++ let Tlist_WinWidth = 20 ++< ++Note that the value of the |'winwidth'| option setting determines the minimum ++width of the current window. If you set the 'Tlist_WinWidth' variable to a ++value less than that of the |'winwidth'| option setting, then Vim will use the ++value of the |'winwidth'| option. ++ ++When new Vim windows are opened and existing windows are closed, the taglist ++plugin will try to maintain the width of the taglist window to the size ++specified by the 'Tlist_WinWidth' variable. ++ ++============================================================================== ++ *taglist-commands* ++7. Commands~ ++ ++The taglist plugin provides the following ex-mode commands: ++ ++|:TlistAddFiles| Add multiple files to the taglist. ++|:TlistAddFilesRecursive| ++ Add files recursively to the taglist. ++|:TlistClose| Close the taglist window. ++|:TlistDebug| Start logging of taglist debug messages. ++|:TlistLock| Stop adding new files to the taglist. ++|:TlistMessages| Display the logged taglist plugin debug messages. ++|:TlistOpen| Open and jump to the taglist window. ++|:TlistSessionSave| Save the information about files and tags in the ++ taglist to a session file. ++|:TlistSessionLoad| Load the information about files and tags stored ++ in a session file to taglist. ++|:TlistShowPrototype| Display the prototype of the tag at or before the ++ specified line number. ++|:TlistShowTag| Display the name of the tag defined at or before the ++ specified line number. ++|:TlistHighlightTag| Highlight the current tag in the taglist window. ++|:TlistToggle| Open or close (toggle) the taglist window. ++|:TlistUndebug| Stop logging of taglist debug messages. ++|:TlistUnlock| Start adding new files to the taglist. ++|:TlistUpdate| Update the tags for the current buffer. ++ ++ *:TlistAddFiles* ++:TlistAddFiles {file(s)} [file(s) ...] ++ Add one or more specified files to the taglist. You can ++ specify multiple filenames using wildcards. To specify a ++ file name with space character, you should escape the space ++ character with a backslash. ++ Examples: ++> ++ :TlistAddFiles *.c *.cpp ++ :TlistAddFiles file1.html file2.html ++< ++ If you specify a large number of files, then it will take some ++ time for the taglist plugin to process all of them. The ++ specified files will not be edited in a Vim window and will ++ not be added to the Vim buffer list. ++ ++ *:TlistAddFilesRecursive* ++:TlistAddFilesRecursive {directory} [ {pattern} ] ++ Add files matching {pattern} recursively from the specified ++ {directory} to the taglist. If {pattern} is not specified, ++ then '*' is assumed. To specify the current directory, use "." ++ for {directory}. To specify a directory name with space ++ character, you should escape the space character with a ++ backslash. ++ Examples: ++> ++ :TlistAddFilesRecursive myproject *.java ++ :TlistAddFilesRecursive smallproject ++< ++ If large number of files are present in the specified ++ directory tree, then it will take some time for the taglist ++ plugin to process all of them. ++ ++ *:TlistClose* ++:TlistClose Close the taglist window. This command can be used from any ++ one of the Vim windows. ++ ++ *:TlistDebug* ++:TlistDebug [filename] ++ Start logging of debug messages from the taglist plugin. ++ If {filename} is specified, then the debug messages are stored ++ in the specified file. Otherwise, the debug messages are ++ stored in a script local variable. If the file {filename} is ++ already present, then it is overwritten. ++ ++ *:TlistLock* ++:TlistLock ++ Lock the taglist and don't process new files. After this ++ command is executed, newly edited files will not be added to ++ the taglist. ++ ++ *:TlistMessages* ++:TlistMessages ++ Display the logged debug messages from the taglist plugin ++ in a window. This command works only when logging to a ++ script-local variable. ++ ++ *:TlistOpen* ++:TlistOpen Open and jump to the taglist window. Creates the taglist ++ window, if the window is not opened currently. After executing ++ this command, the cursor is moved to the taglist window. When ++ the taglist window is opened for the first time, all the files ++ in the buffer list are processed and the tags defined in them ++ are displayed in the taglist window. ++ ++ *:TlistSessionSave* ++:TlistSessionSave {filename} ++ Saves the information about files and tags in the taglist to ++ the specified file. This command can be used to save and ++ restore the taglist contents across Vim sessions. ++ ++ *:TlistSessionLoad* ++:TlistSessionLoad {filename} ++ Load the information about files and tags stored in the ++ specified session file to the taglist. ++ ++ *:TlistShowPrototype* ++:TlistShowPrototype [filename] [linenumber] ++ Display the prototype of the tag at or before the specified ++ line number. If the file name and the line number are not ++ specified, then the current file name and line number are ++ used. A tag spans multiple lines starting from the line where ++ it is defined to the line before the next tag. This command ++ displays the prototype for the tag for any line number in this ++ range. ++ ++ *:TlistShowTag* ++:TlistShowTag [filename] [linenumber] ++ Display the name of the tag defined at or before the specified ++ line number. If the file name and the line number are not ++ specified, then the current file name and line number are ++ used. A tag spans multiple lines starting from the line where ++ it is defined to the line before the next tag. This command ++ displays the tag name for any line number in this range. ++ ++ *:TlistHighlightTag* ++:TlistHighlightTag ++ Highlight the current tag in the taglist window. By default, ++ the taglist plugin periodically updates the taglist window to ++ highlight the current tag. This command can be used to force ++ the taglist plugin to highlight the current tag. ++ ++ *:TlistToggle* ++:TlistToggle Open or close (toggle) the taglist window. Opens the taglist ++ window, if the window is not opened currently. Closes the ++ taglist window, if the taglist window is already opened. When ++ the taglist window is opened for the first time, all the files ++ in the buffer list are processed and the tags are displayed in ++ the taglist window. After executing this command, the cursor ++ is not moved from the current window to the taglist window. ++ ++ *:TlistUndebug* ++:TlistUndebug ++ Stop logging of debug messages from the taglist plugin. ++ ++ *:TlistUnlock* ++:TlistUnlock ++ Unlock the taglist and start processing newly edited files. ++ ++ *:TlistUpdate* ++:TlistUpdate Update the tags information for the current buffer. This ++ command can be used to re-process the current file/buffer and ++ get the tags information. As the taglist plugin uses the file ++ saved in the disk (instead of the file displayed in a Vim ++ buffer), you should save a modified buffer before you update ++ the taglist. Otherwise the listed tags will not include the ++ new tags created in the buffer. You can use this command even ++ when the taglist window is not opened. ++ ++============================================================================== ++ *taglist-functions* ++8. Global functions~ ++ ++The taglist plugin provides several global functions that can be used from ++other Vim plugins to interact with the taglist plugin. These functions are ++described below. ++ ++|Tlist_Update_File_Tags()| Update the tags for the specified file ++|Tlist_Get_Tag_Prototype_By_Line()| Return the prototype of the tag at or ++ before the specified line number in the ++ specified file. ++|Tlist_Get_Tagname_By_Line()| Return the name of the tag at or ++ before the specified line number in ++ the specified file. ++|Tlist_Set_App()| Set the name of the application ++ controlling the taglist window. ++ ++ *Tlist_Update_File_Tags()* ++Tlist_Update_File_Tags({filename}, {filetype}) ++ Update the tags for the file {filename}. The second argument ++ specifies the Vim filetype for the file. If the taglist plugin ++ has not processed the file previously, then the exuberant ++ ctags tool is invoked to generate the tags for the file. ++ ++ *Tlist_Get_Tag_Prototype_By_Line()* ++Tlist_Get_Tag_Prototype_By_Line([{filename}, {linenumber}]) ++ Return the prototype of the tag at or before the specified ++ line number in the specified file. If the filename and line ++ number are not specified, then the current buffer name and the ++ current line number are used. ++ ++ *Tlist_Get_Tagname_By_Line()* ++Tlist_Get_Tagname_By_Line([{filename}, {linenumber}]) ++ Return the name of the tag at or before the specified line ++ number in the specified file. If the filename and line number ++ are not specified, then the current buffer name and the ++ current line number are used. ++ ++ *Tlist_Set_App()* ++Tlist_Set_App({appname}) ++ Set the name of the plugin that controls the taglist plugin ++ window and buffer. This can be used to integrate the taglist ++ plugin with other Vim plugins. ++ ++ For example, the winmanager plugin and the Cream package use ++ this function and specify the appname as "winmanager" and ++ "cream" respectively. ++ ++ By default, the taglist plugin is a stand-alone plugin and ++ controls the taglist window and buffer. If the taglist window ++ is controlled by an external plugin, then the appname should ++ be set appropriately. ++ ++============================================================================== ++ *taglist-extend* ++9. Extending~ ++ ++The taglist plugin supports all the languages supported by the exuberant ctags ++tool, which includes the following languages: Assembly, ASP, Awk, Beta, C, ++C++, C#, Cobol, Eiffel, Erlang, Fortran, HTML, Java, Javascript, Lisp, Lua, ++Make, Pascal, Perl, PHP, Python, Rexx, Ruby, Scheme, Shell, Slang, SML, Sql, ++TCL, Verilog, Vim and Yacc. ++ ++You can extend the taglist plugin to add support for new languages and also ++modify the support for the above listed languages. ++ ++You should NOT make modifications to the taglist plugin script file to add ++support for new languages. You will lose these changes when you upgrade to the ++next version of the taglist plugin. Instead you should follow the below ++described instructions to extend the taglist plugin. ++ ++You can extend the taglist plugin by setting variables in the .vimrc or _vimrc ++file. The name of these variables depends on the language name and is ++described below. ++ ++Modifying support for an existing language~ ++To modify the support for an already supported language, you have to set the ++tlist_xxx_settings variable in the ~/.vimrc or $HOME/_vimrc file. Replace xxx ++with the Vim filetype name for the language file. For example, to modify the ++support for the perl language files, you have to set the tlist_perl_settings ++variable. To modify the support for java files, you have to set the ++tlist_java_settings variable. ++ ++To determine the filetype name used by Vim for a file, use the following ++command in the buffer containing the file: ++ ++ :set filetype ++ ++The above command will display the Vim filetype for the current buffer. ++ ++The format of the value set in the tlist_xxx_settings variable is ++ ++ ;flag1:name1;flag2:name2;flag3:name3 ++ ++The different fields in the value are separated by the ';' character. ++ ++The first field 'language_name' is the name used by exuberant ctags to refer ++to this language file. This name can be different from the file type name used ++by Vim. For example, for C++, the language name used by ctags is 'c++' but the ++filetype name used by Vim is 'cpp'. To get the list of language names ++supported by exuberant ctags, use the following command: ++ ++ $ ctags --list-maps=all ++ ++The remaining fields follow the format "flag:name". The sub-field 'flag' is ++the language specific flag used by exuberant ctags to generate the ++corresponding tags. For example, for the C language, to list only the ++functions, the 'f' flag is used. To get the list of flags supported by ++exuberant ctags for the various languages use the following command: ++ ++ $ ctags --list-kinds=all ++ ++The sub-field 'name' specifies the title text to use for displaying the tags ++of a particular type. For example, 'name' can be set to 'functions'. This ++field can be set to any text string name. ++ ++For example, to list only the classes and functions defined in a C++ language ++file, add the following line to your .vimrc file: ++ ++ let tlist_cpp_settings = 'c++;c:class;f:function' ++ ++In the above setting, 'cpp' is the Vim filetype name and 'c++' is the name ++used by the exuberant ctags tool. 'c' and 'f' are the flags passed to ++exuberant ctags to list C++ classes and functions and 'class' is the title ++used for the class tags and 'function' is the title used for the function tags ++in the taglist window. ++ ++For example, to display only functions defined in a C file and to use "My ++Functions" as the title for the function tags, use ++ ++ let tlist_c_settings = 'c;f:My Functions' ++ ++When you set the tlist_xxx_settings variable, you will override the default ++setting used by the taglist plugin for the 'xxx' language. You cannot add to ++the default options used by the taglist plugin for a particular file type. To ++add to the options used by the taglist plugin for a language, copy the option ++values from the taglist plugin file to your .vimrc file and modify it. ++ ++Adding support for a new language~ ++If you want to add support for a new language to the taglist plugin, you need ++to first extend the exuberant ctags tool. For more information about extending ++exuberant ctags, visit the following page: ++ ++ http://ctags.sourceforge.net/EXTENDING.html ++ ++To add support for a new language, set the tlist_xxx_settings variable in the ++~/.vimrc file appropriately as described above. Replace 'xxx' in the variable ++name with the Vim filetype name for the new language. ++ ++For example, to extend the taglist plugin to support the latex language, you ++can use the following line (assuming, you have already extended exuberant ++ctags to support the latex language): ++ ++ let tlist_tex_settings='latex;b:bibitem;c:command;l:label' ++ ++With the above line, when you edit files of filetype "tex" in Vim, the taglist ++plugin will invoke the exuberant ctags tool passing the "latex" filetype and ++the flags b, c and l to generate the tags. The text heading 'bibitem', ++'command' and 'label' will be used in the taglist window for the tags which ++are generated for the flags b, c and l respectively. ++ ++============================================================================== ++ *taglist-faq* ++10. Frequently Asked Questions~ ++ ++Q. The taglist plugin doesn't work. The taglist window is empty and the tags ++ defined in a file are not displayed. ++A. Are you using Vim version 6.0 and above? The taglist plugin relies on the ++ features supported by Vim version 6.0 and above. You can use the following ++ command to get the Vim version: ++> ++ $ vim --version ++< ++ Are you using exuberant ctags version 5.0 and above? The taglist plugin ++ relies on the features supported by exuberant ctags and will not work with ++ GNU ctags or the Unix ctags utility. You can use the following command to ++ determine whether the ctags installed in your system is exuberant ctags: ++> ++ $ ctags --version ++< ++ Is exuberant ctags present in one of the directories in your PATH? If not, ++ you need to set the Tlist_Ctags_Cmd variable to point to the location of ++ exuberant ctags. Use the following Vim command to verify that this is setup ++ correctly: ++> ++ :echo system(Tlist_Ctags_Cmd . ' --version') ++< ++ The above command should display the version information for exuberant ++ ctags. ++ ++ Did you turn on the Vim filetype detection? The taglist plugin relies on ++ the filetype detected by Vim and passes the filetype to the exuberant ctags ++ utility to parse the tags. Check the output of the following Vim command: ++> ++ :filetype ++< ++ The output of the above command should contain "filetype detection:ON". ++ To turn on the filetype detection, add the following line to the .vimrc or ++ _vimrc file: ++> ++ filetype on ++< ++ Is your version of Vim compiled with the support for the system() function? ++ The following Vim command should display 1: ++> ++ :echo exists('*system') ++< ++ In some Linux distributions (particularly Suse Linux), the default Vim ++ installation is built without the support for the system() function. The ++ taglist plugin uses the system() function to invoke the exuberant ctags ++ utility. You need to rebuild Vim after enabling the support for the ++ system() function. If you use the default build options, the system() ++ function will be supported. ++ ++ Do you have the |'shellslash'| option set? You can try disabling the ++ |'shellslash'| option. When the taglist plugin invokes the exuberant ctags ++ utility with the path to the file, if the incorrect slashes are used, then ++ you will see errors. ++ ++ Check the shell related Vim options values using the following command: ++> ++ :set shell? shellcmdflag? shellpipe? ++ :set shellquote? shellredir? shellxquote? ++< ++ If these options are set in your .vimrc or _vimrc file, try removing those ++ lines. ++ ++ Are you using a Unix shell in a MS-Windows environment? For example, ++ the Unix shell from the MKS-toolkit. Do you have the SHELL environment ++ set to point to this shell? You can try resetting the SHELL environment ++ variable. ++ ++ If you are using a Unix shell on MS-Windows, you should try to use ++ exuberant ctags that is compiled for Unix-like environments so that ++ exuberant ctags will understand path names with forward slash characters. ++ ++ Is your filetype supported by the exuberant ctags utility? The file types ++ supported by the exuberant ctags utility are listed in the ctags help. If a ++ file type is not supported, you have to extend exuberant ctags. You can use ++ the following command to list the filetypes supported by exuberant ctags: ++> ++ ctags --list-languages ++< ++ Run the following command from the shell prompt and check whether the tags ++ defined in your file are listed in the output from exuberant ctags: ++> ++ ctags -f - --format=2 --excmd=pattern --fields=nks ++< ++ If you see your tags in the output from the above command, then the ++ exuberant ctags utility is properly parsing your file. ++ ++ Do you have the .ctags or _ctags or the ctags.cnf file in your home ++ directory for specifying default options or for extending exuberant ctags? ++ If you do have this file, check the options in this file and make sure ++ these options are not interfering with the operation of the taglist plugin. ++ ++ If you are using MS-Windows, check the value of the TEMP and TMP ++ environment variables. If these environment variables are set to a path ++ with space characters in the name, then try using the DOS 8.3 short name ++ for the path or set them to a path without the space characters in the ++ name. For example, if the temporary directory name is "C:\Documents and ++ Settings\xyz\Local Settings\Temp", then try setting the TEMP variable to ++ the following: ++> ++ set TEMP=C:\DOCUMEN~1\xyz\LOCALS~1\Temp ++< ++ If exuberant ctags is installed in a directory with space characters in the ++ name, then try adding the directory to the PATH environment variable or try ++ setting the 'Tlist_Ctags_Cmd' variable to the shortest path name to ctags ++ or try copying the exuberant ctags to a path without space characters in ++ the name. For example, if exuberant ctags is installed in the directory ++ "C:\Program Files\Ctags", then try setting the 'Tlist_Ctags_Cmd' variable ++ as below: ++> ++ let Tlist_Ctags_Cmd='C:\Progra~1\Ctags\ctags.exe' ++< ++Q. When I try to open the taglist window, I am seeing the following error ++ message. How do I fix this problem? ++ ++ Taglist: Failed to generate tags for /my/path/to/file ++ ctags: illegal option -- -^@usage: ctags [-BFadtuwvx] [-f tagsfile] file ... ++ ++A. The taglist plugin will work only with the exuberant ctags tool. You ++ cannot use the GNU ctags or the Unix ctags program with the taglist plugin. ++ You will see an error message similar to the one shown above, if you try ++ use a non-exuberant ctags program with Vim. To fix this problem, either add ++ the exuberant ctags tool location to the PATH environment variable or set ++ the 'Tlist_Ctags_Cmd' variable. ++ ++Q. A file has more than one tag with the same name. When I select a tag name ++ from the taglist window, the cursor is positioned at the incorrect tag ++ location. ++A. The taglist plugin uses the search pattern generated by the exuberant ctags ++ utility to position the cursor at the location of a tag definition. If a ++ file has more than one tag with the same name and same prototype, then the ++ search pattern will be the same. In this case, when searching for the tag ++ pattern, the cursor may be positioned at the incorrect location. ++ ++Q. I have made some modifications to my file and introduced new ++ functions/classes/variables. I have not yet saved my file. The taglist ++ plugin is not displaying the new tags when I update the taglist window. ++A. The exuberant ctags utility will process only files that are present in the ++ disk. To list the tags defined in a file, you have to save the file and ++ then update the taglist window. ++ ++Q. I have created a ctags file using the exuberant ctags utility for my source ++ tree. How do I configure the taglist plugin to use this tags file? ++A. The taglist plugin doesn't use a tags file stored in disk. For every opened ++ file, the taglist plugin invokes the exuberant ctags utility to get the ++ list of tags dynamically. The Vim system() function is used to invoke ++ exuberant ctags and get the ctags output. This function internally uses a ++ temporary file to store the output. This file is deleted after the output ++ from the command is read. So you will never see the file that contains the ++ output of exuberant ctags. ++ ++Q. When I set the |'updatetime'| option to a low value (less than 1000) and if ++ I keep pressing a key with the taglist window open, the current buffer ++ contents are changed. Why is this? ++A. The taglist plugin uses the |CursorHold| autocmd to highlight the current ++ tag. The CursorHold autocmd triggers for every |'updatetime'| milliseconds. ++ If the |'updatetime'| option is set to a low value, then the CursorHold ++ autocmd will be triggered frequently. As the taglist plugin changes ++ the focus to the taglist window to highlight the current tag, this could ++ interfere with the key movement resulting in changing the contents of ++ the current buffer. The workaround for this problem is to not set the ++ |'updatetime'| option to a low value. ++ ++============================================================================== ++ *taglist-license* ++11. License~ ++Permission is hereby granted to use and distribute the taglist plugin, with or ++without modifications, provided that this copyright notice is copied with it. ++Like anything else that's free, taglist.vim is provided *as is* and comes with ++no warranty of any kind, either expressed or implied. In no event will the ++copyright holder be liable for any damamges resulting from the use of this ++software. ++ ++============================================================================== ++ *taglist-todo* ++12. Todo~ ++ ++1. Group tags according to the scope and display them. For example, ++ group all the tags belonging to a C++/Java class ++2. Support for displaying tags in a modified (not-yet-saved) file. ++3. Automatically open the taglist window only for selected filetypes. ++ For other filetypes, close the taglist window. ++4. When using the shell from the MKS toolkit, the taglist plugin ++ doesn't work. ++5. The taglist plugin doesn't work with files edited remotely using the ++ netrw plugin. The exuberant ctags utility cannot process files over ++ scp/rcp/ftp, etc. ++ ++============================================================================== ++ ++vim:tw=78:ts=8:noet:ft=help: +diff -urN vim71/1/doc/taglist.txt vim71_ada/1/doc/taglist.txt +--- vim71/1/doc/taglist.txt 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/doc/taglist.txt 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,1494 @@ ++*taglist.txt* Plugin for browsing source code ++ ++Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) ++For Vim version 6.0 and above ++Last change: 2007 February 18 ++ ++1. Overview |taglist-intro| ++2. Taglist on the internet |taglist-internet| ++3. Requirements |taglist-requirements| ++4. Installation |taglist-install| ++5. Usage |taglist-using| ++6. Options |taglist-options| ++7. Commands |taglist-commands| ++8. Global functions |taglist-functions| ++9. Extending |taglist-extend| ++10. FAQ |taglist-faq| ++11. License |taglist-license| ++12. Todo |taglist-todo| ++ ++============================================================================== ++ *taglist-intro* ++1. Overview~ ++ ++The "Tag List" plugin is a source code browser plugin for Vim. This plugin ++allows you to efficiently browse through source code files for different ++programming languages. The "Tag List" plugin provides the following features: ++ ++ * Displays the tags (functions, classes, structures, variables, etc.) ++ defined in a file in a vertically or horizontally split Vim window. ++ * In GUI Vim, optionally displays the tags in the Tags drop-down menu and ++ in the popup menu. ++ * Automatically updates the taglist window as you switch between ++ files/buffers. As you open new files, the tags defined in the new files ++ are added to the existing file list and the tags defined in all the ++ files are displayed grouped by the filename. ++ * When a tag name is selected from the taglist window, positions the ++ cursor at the definition of the tag in the source file. ++ * Automatically highlights the current tag name. ++ * Groups the tags by their type and displays them in a foldable tree. ++ * Can display the prototype and scope of a tag. ++ * Can optionally display the tag prototype instead of the tag name in the ++ taglist window. ++ * The tag list can be sorted either by name or by chronological order. ++ * Supports the following language files: Assembly, ASP, Awk, Beta, C, ++ C++, C#, Cobol, Eiffel, Erlang, Fortran, HTML, Java, Javascript, Lisp, ++ Lua, Make, Pascal, Perl, PHP, Python, Rexx, Ruby, Scheme, Shell, Slang, ++ SML, Sql, TCL, Verilog, Vim and Yacc. ++ * Can be easily extended to support new languages. Support for ++ existing languages can be modified easily. ++ * Provides functions to display the current tag name in the Vim status ++ line or the window title bar. ++ * The list of tags and files in the taglist can be saved and ++ restored across Vim sessions. ++ * Provides commands to get the name and prototype of the current tag. ++ * Runs in both console/terminal and GUI versions of Vim. ++ * Works with the winmanager plugin. Using the winmanager plugin, you ++ can use Vim plugins like the file explorer, buffer explorer and the ++ taglist plugin at the same time like an IDE. ++ * Can be used in both Unix and MS-Windows systems. ++ ++============================================================================== ++ *taglist-internet* ++2. Taglist on the internet~ ++ ++The home page of the taglist plugin is at: ++> ++ http://vim-taglist.sourceforge.net/ ++< ++You can subscribe to the taglist mailing list to post your questions or ++suggestions for improvement or to send bug reports. Visit the following page ++for subscribing to the mailing list: ++> ++ http://groups.yahoo.com/group/taglist ++< ++============================================================================== ++ *taglist-requirements* ++3. Requirements~ ++ ++The taglist plugin requires the following: ++ ++ * Vim version 6.0 and above ++ * Exuberant ctags 5.0 and above ++ ++The taglist plugin will work on all the platforms where the exuberant ctags ++utility and Vim are supported (this includes MS-Windows and Unix based ++systems). ++ ++The taglist plugin relies on the exuberant ctags utility to dynamically ++generate the tag listing. The exuberant ctags utility must be installed in ++your system to use this plugin. The exuberant ctags utility is shipped with ++most of the Linux distributions. You can download the exuberant ctags utility ++from ++> ++ http://ctags.sourceforge.net ++< ++The taglist plugin doesn't use or create a tags file and there is no need to ++create a tags file to use this plugin. The taglist plugin will not work with ++the GNU ctags or the Unix ctags utility. ++ ++This plugin relies on the Vim "filetype" detection mechanism to determine the ++type of the current file. You have to turn on the Vim filetype detection by ++adding the following line to your .vimrc file: ++> ++ filetype on ++< ++The taglist plugin will not work if you run Vim in the restricted mode (using ++the -Z command-line argument). ++ ++The taglist plugin uses the Vim system() function to invoke the exuberant ++ctags utility. If Vim is compiled without the system() function then you ++cannot use the taglist plugin. Some of the Linux distributions (Suse) compile ++Vim without the system() function for security reasons. ++ ++============================================================================== ++ *taglist-install* ++4. Installation~ ++ ++1. Download the taglist.zip file and unzip the files to the $HOME/.vim or the ++ $HOME/vimfiles or the $VIM/vimfiles directory. After this step, you should ++ have the following two files (the directory structure should be preserved): ++ ++ plugin/taglist.vim - main taglist plugin file ++ doc/taglist.txt - documentation (help) file ++ ++ Refer to the |add-plugin|and |'runtimepath'| Vim help pages for more ++ details about installing Vim plugins. ++2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or $VIM/vimfiles/doc ++ directory, start Vim and run the ":helptags ." command to process the ++ taglist help file. Without this step, you cannot jump to the taglist help ++ topics. ++3. If the exuberant ctags utility is not present in one of the directories in ++ the PATH environment variable, then set the 'Tlist_Ctags_Cmd' variable to ++ point to the location of the exuberant ctags utility (not to the directory) ++ in the .vimrc file. ++4. If you are running a terminal/console version of Vim and the terminal ++ doesn't support changing the window width then set the ++ 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file. ++5. Restart Vim. ++6. You can now use the ":TlistToggle" command to open/close the taglist ++ window. You can use the ":help taglist" command to get more information ++ about using the taglist plugin. ++ ++To uninstall the taglist plugin, remove the plugin/taglist.vim and ++doc/taglist.txt files from the $HOME/.vim or $HOME/vimfiles directory. ++ ++============================================================================== ++ *taglist-using* ++5. Usage~ ++ ++The taglist plugin can be used in several different ways. ++ ++1. You can keep the taglist window open during the entire editing session. On ++ opening the taglist window, the tags defined in all the files in the Vim ++ buffer list will be displayed in the taglist window. As you edit files, the ++ tags defined in them will be added to the taglist window. You can select a ++ tag from the taglist window and jump to it. The current tag will be ++ highlighted in the taglist window. You can close the taglist window when ++ you no longer need the window. ++2. You can configure the taglist plugin to process the tags defined in all the ++ edited files always. In this configuration, even if the taglist window is ++ closed and the taglist menu is not displayed, the taglist plugin will ++ processes the tags defined in newly edited files. You can then open the ++ taglist window only when you need to select a tag and then automatically ++ close the taglist window after selecting the tag. ++3. You can configure the taglist plugin to display only the tags defined in ++ the current file in the taglist window. By default, the taglist plugin ++ displays the tags defined in all the files in the Vim buffer list. As you ++ switch between files, the taglist window will be refreshed to display only ++ the tags defined in the current file. ++4. In GUI Vim, you can use the Tags pull-down and popup menu created by the ++ taglist plugin to display the tags defined in the current file and select a ++ tag to jump to it. You can use the menu without opening the taglist window. ++ By default, the Tags menu is disabled. ++5. You can configure the taglist plugin to display the name of the current tag ++ in the Vim window status line or in the Vim window title bar. For this to ++ work without the taglist window or menu, you need to configure the taglist ++ plugin to process the tags defined in a file always. ++6. You can save the tags defined in multiple files to a taglist session file ++ and load it when needed. You can also configure the taglist plugin to not ++ update the taglist window when editing new files. You can then manually add ++ files to the taglist window. ++ ++Opening the taglist window~ ++You can open the taglist window using the ":TlistOpen" or the ":TlistToggle" ++commands. The ":TlistOpen" command opens the taglist window and jumps to it. ++The ":TlistToggle" command opens or closes (toggle) the taglist window and the ++cursor remains in the current window. If the 'Tlist_GainFocus_On_ToggleOpen' ++variable is set to 1, then the ":TlistToggle" command opens the taglist window ++and moves the cursor to the taglist window. ++ ++You can map a key to invoke these commands. For example, the following command ++creates a normal mode mapping for the key to toggle the taglist window. ++> ++ nnoremap :TlistToggle ++< ++Add the above mapping to your ~/.vimrc or $HOME/_vimrc file. ++ ++To automatically open the taglist window on Vim startup, set the ++'Tlist_Auto_Open' variable to 1. ++ ++You can also open the taglist window on startup using the following command ++line: ++> ++ $ vim +TlistOpen ++< ++Closing the taglist window~ ++You can close the taglist window from the taglist window by pressing 'q' or ++using the Vim ":q" command. You can also use any of the Vim window commands to ++close the taglist window. Invoking the ":TlistToggle" command when the taglist ++window is opened, closes the taglist window. You can also use the ++":TlistClose" command to close the taglist window. ++ ++To automatically close the taglist window when a tag or file is selected, you ++can set the 'Tlist_Close_On_Select' variable to 1. To exit Vim when only the ++taglist window is present, set the 'Tlist_Exit_OnlyWindow' variable to 1. ++ ++Jumping to a tag or a file~ ++You can select a tag in the taglist window either by pressing the key ++or by double clicking the tag name using the mouse. To jump to a tag on a ++single mouse click set the 'Tlist_Use_SingleClick' variable to 1. ++ ++If the selected file is already opened in a window, then the cursor is moved ++to that window. If the file is not currently opened in a window then the file ++is opened in the window used by the taglist plugin to show the previously ++selected file. If there are no usable windows, then the file is opened in a ++new window. The file is not opened in special windows like the quickfix ++window, preview window and windows containing buffer with the 'buftype' option ++set. ++ ++To jump to the tag in a new window, press the 'o' key. To open the file in the ++previous window (Ctrl-W_p) use the 'P' key. You can press the 'p' key to jump ++to the tag but still keep the cursor in the taglist window (preview). ++ ++To open the selected file in a tab, use the 't' key. If the file is already ++present in a tab then the cursor is moved to that tab otherwise the file is ++opened in a new tab. To jump to a tag in a new tab press Ctrl-t. The taglist ++window is automatically opened in the newly created tab. ++ ++Instead of jumping to a tag, you can open a file by pressing the key ++or by double clicking the file name using the mouse. ++ ++In the taglist window, you can use the [[ or key to jump to the ++beginning of the previous file. You can use the ]] or key to jump to the ++beginning of the next file. When you reach the first or last file, the search ++wraps around and the jumps to the next/previous file. ++ ++Highlighting the current tag~ ++The taglist plugin automatically highlights the name of the current tag in the ++taglist window. The Vim |CursorHold| autocmd event is used for this. If the ++current tag name is not visible in the taglist window, then the taglist window ++contents are scrolled to make that tag name visible. You can also use the ++":TlistHighlightTag" command to force the highlighting of the current tag. ++ ++The tag name is highlighted if no activity is performed for |'updatetime'| ++milliseconds. The default value for this Vim option is 4 seconds. To avoid ++unexpected problems, you should not set the |'updatetime'| option to a very ++low value. ++ ++To disable the automatic highlighting of the current tag name in the taglist ++window, set the 'Tlist_Auto_Highlight_Tag' variable to zero. ++ ++When entering a Vim buffer/window, the taglist plugin automatically highlights ++the current tag in that buffer/window. If you like to disable the automatic ++highlighting of the current tag when entering a buffer, set the ++'Tlist_Highlight_Tag_On_BufEnter' variable to zero. ++ ++Adding files to the taglist~ ++When the taglist window is opened, all the files in the Vim buffer list are ++processed and the supported files are added to the taglist. When you edit a ++file in Vim, the taglist plugin automatically processes this file and adds it ++to the taglist. If you close the taglist window, the tag information in the ++taglist is retained. ++ ++To process files even when the taglist window is not open, set the ++'Tlist_Process_File_Always' variable to 1. ++ ++You can manually add multiple files to the taglist without opening them using ++the ":TlistAddFiles" and the ":TlistAddFilesRecursive" commands. ++ ++For example, to add all the C files in the /my/project/dir directory to the ++taglist, you can use the following command: ++> ++ :TlistAddFiles /my/project/dir/*.c ++< ++Note that when adding several files with a large number of tags or a large ++number of files, it will take several seconds to several minutes for the ++taglist plugin to process all the files. You should not interrupt the taglist ++plugin by pressing . ++ ++You can recursively add multiple files from a directory tree using the ++":TlistAddFilesRecursive" command: ++> ++ :TlistAddFilesRecursive /my/project/dir *.c ++< ++This command takes two arguments. The first argument specifies the directory ++from which to recursively add the files. The second optional argument ++specifies the wildcard matching pattern for selecting the files to add. The ++default pattern is * and all the files are added. ++ ++Displaying tags for only one file~ ++The taglist window displays the tags for all the files in the Vim buffer list ++and all the manually added files. To display the tags for only the current ++active buffer, set the 'Tlist_Show_One_File' variable to 1. ++ ++Removing files from the taglist~ ++You can remove a file from the taglist window, by pressing the 'd' key when the ++cursor is on one of the tags listed for the file in the taglist window. The ++removed file will no longer be displayed in the taglist window in the current ++Vim session. To again display the tags for the file, open the file in a Vim ++window and then use the ":TlistUpdate" command or use ":TlistAddFiles" command ++to add the file to the taglist. ++ ++When a buffer is removed from the Vim buffer list using the ":bdelete" or the ++":bwipeout" command, the taglist is updated to remove the stored information ++for this buffer. ++ ++Updating the tags displayed for a file~ ++The taglist plugin keeps track of the modification time of a file. When the ++modification time changes (the file is modified), the taglist plugin ++automatically updates the tags listed for that file. The modification time of ++a file is checked when you enter a window containing that file or when you ++load that file. ++ ++You can also update or refresh the tags displayed for a file by pressing the ++"u" key in the taglist window. If an existing file is modified, after the file ++is saved, the taglist plugin automatically updates the tags displayed for the ++file. ++ ++You can also use the ":TlistUpdate" command to update the tags for the current ++buffer after you made some changes to it. You should save the modified buffer ++before you update the taglist window. Otherwise the listed tags will not ++include the new tags created in the buffer. ++ ++If you have deleted the tags displayed for a file in the taglist window using ++the 'd' key, you can again display the tags for that file using the ++":TlistUpdate" command. ++ ++Controlling the taglist updates~ ++To disable the automatic processing of new files or modified files, you can ++set the 'Tlist_Auto_Update' variable to zero. When this variable is set to ++zero, the taglist is updated only when you use the ":TlistUpdate" command or ++the ":TlistAddFiles" or the ":TlistAddFilesRecursive" commands. You can use ++this option to control which files are added to the taglist. ++ ++You can use the ":TlistLock" command to lock the taglist contents. After this ++command is executed, new files are not automatically added to the taglist. ++When the taglist is locked, you can use the ":TlistUpdate" command to add the ++current file or the ":TlistAddFiles" or ":TlistAddFilesRecursive" commands to ++add new files to the taglist. To unlock the taglist, use the ":TlistUnlock" ++command. ++ ++Displaying the tag prototype~ ++To display the prototype of the tag under the cursor in the taglist window, ++press the space bar. If you place the cursor on a tag name in the taglist ++window, then the tag prototype is displayed at the Vim status line after ++|'updatetime'| milliseconds. The default value for the |'updatetime'| Vim ++option is 4 seconds. ++ ++You can get the name and prototype of a tag without opening the taglist window ++and the taglist menu using the ":TlistShowTag" and the ":TlistShowPrototype" ++commands. These commands will work only if the current file is already present ++in the taglist. To use these commands without opening the taglist window, set ++the 'Tlist_Process_File_Always' variable to 1. ++ ++You can use the ":TlistShowTag" command to display the name of the tag at or ++before the specified line number in the specified file. If the file name and ++line number are not supplied, then this command will display the name of the ++current tag. For example, ++> ++ :TlistShowTag ++ :TlistShowTag myfile.java 100 ++< ++You can use the ":TlistShowPrototype" command to display the prototype of the ++tag at or before the specified line number in the specified file. If the file ++name and the line number are not supplied, then this command will display the ++prototype of the current tag. For example, ++> ++ :TlistShowPrototype ++ :TlistShowPrototype myfile.c 50 ++< ++In the taglist window, when the mouse is moved over a tag name, the tag ++prototype is displayed in a balloon. This works only in GUI versions where ++balloon evaluation is supported. ++ ++Taglist window contents~ ++The taglist window contains the tags defined in various files in the taglist ++grouped by the filename and by the tag type (variable, function, class, etc.). ++For tags with scope information (like class members, structures inside ++structures, etc.), the scope information is displayed in square brackets "[]" ++after the tag name. ++ ++The contents of the taglist buffer/window are managed by the taglist plugin. ++The |'filetype'| for the taglist buffer is set to 'taglist'. The Vim ++|'modifiable'| option is turned off for the taglist buffer. You should not ++manually edit the taglist buffer, by setting the |'modifiable'| flag. If you ++manually edit the taglist buffer contents, then the taglist plugin will be out ++of sync with the taglist buffer contents and the plugin will no longer work ++correctly. To redisplay the taglist buffer contents again, close the taglist ++window and reopen it. ++ ++Opening and closing the tag and file tree~ ++In the taglist window, the tag names are displayed as a foldable tree using ++the Vim folding support. You can collapse the tree using the '-' key or using ++the Vim |zc| fold command. You can open the tree using the '+' key or using ++the Vim |zo| fold command. You can open all the folds using the '*' key or ++using the Vim |zR| fold command. You can also use the mouse to open/close the ++folds. You can close all the folds using the '=' key. You should not manually ++create or delete the folds in the taglist window. ++ ++To automatically close the fold for the inactive files/buffers and open only ++the fold for the current buffer in the taglist window, set the ++'Tlist_File_Fold_Auto_Close' variable to 1. ++ ++Sorting the tags for a file~ ++The tags displayed in the taglist window can be sorted either by their name or ++by their chronological order. The default sorting method is by the order in ++which the tags appear in a file. You can change the default sort method by ++setting the 'Tlist_Sort_Type' variable to either "name" or "order". You can ++sort the tags by their name by pressing the "s" key in the taglist window. You ++can again sort the tags by their chronological order using the "s" key. Each ++file in the taglist window can be sorted using different order. ++ ++Zooming in and out of the taglist window~ ++You can press the 'x' key in the taglist window to maximize the taglist ++window width/height. The window will be maximized to the maximum possible ++width/height without closing the other existing windows. You can again press ++'x' to restore the taglist window to the default width/height. ++ ++ *taglist-session* ++Taglist Session~ ++A taglist session refers to the group of files and their tags stored in the ++taglist in a Vim session. ++ ++You can save and restore a taglist session (and all the displayed tags) using ++the ":TlistSessionSave" and ":TlistSessionLoad" commands. ++ ++To save the information about the tags and files in the taglist to a file, use ++the ":TlistSessionSave" command and specify the filename: ++> ++ :TlistSessionSave ++< ++To load a saved taglist session, use the ":TlistSessionLoad" command: > ++ ++ :TlistSessionLoad ++< ++When you load a taglist session file, the tags stored in the file will be ++added to the tags already stored in the taglist. ++ ++The taglist session feature can be used to save the tags for large files or a ++group of frequently used files (like a project). By using the taglist session ++file, you can minimize the amount to time it takes to load/refresh the taglist ++for multiple files. ++ ++You can create more than one taglist session file for multiple groups of ++files. ++ ++Displaying the tag name in the Vim status line or the window title bar~ ++You can use the Tlist_Get_Tagname_By_Line() function provided by the taglist ++plugin to display the current tag name in the Vim status line or the window ++title bar. Similarly, you can use the Tlist_Get_Tag_Prototype_By_Line() ++function to display the current tag prototype in the Vim status line or the ++window title bar. ++ ++For example, the following command can be used to display the current tag name ++in the status line: ++> ++ :set statusline=%<%f%=%([%{Tlist_Get_Tagname_By_Line()}]%) ++< ++The following command can be used to display the current tag name in the ++window title bar: ++> ++ :set title titlestring=%<%f\ %([%{Tlist_Get_Tagname_By_Line()}]%) ++< ++Note that the current tag name can be displayed only after the file is ++processed by the taglist plugin. For this, you have to either set the ++'Tlist_Process_File_Always' variable to 1 or open the taglist window or use ++the taglist menu. For more information about configuring the Vim status line, ++refer to the documentation for the Vim |'statusline'| option. ++ ++Changing the taglist window highlighting~ ++The following Vim highlight groups are defined and used to highlight the ++various entities in the taglist window: ++ ++ TagListTagName - Used for tag names ++ TagListTagScope - Used for tag scope ++ TagListTitle - Used for tag titles ++ TagListComment - Used for comments ++ TagListFileName - Used for filenames ++ ++By default, these highlight groups are linked to the standard Vim highlight ++groups. If you want to change the colors used for these highlight groups, ++prefix the highlight group name with 'My' and define it in your .vimrc or ++.gvimrc file: MyTagListTagName, MyTagListTagScope, MyTagListTitle, ++MyTagListComment and MyTagListFileName. For example, to change the colors ++used for tag names, you can use the following command: ++> ++ :highlight MyTagListTagName guifg=blue ctermfg=blue ++< ++Controlling the taglist window~ ++To use a horizontally split taglist window, instead of a vertically split ++window, set the 'Tlist_Use_Horiz_Window' variable to 1. ++ ++To use a vertically split taglist window on the rightmost side of the Vim ++window, set the 'Tlist_Use_Right_Window' variable to 1. ++ ++You can specify the width of the vertically split taglist window, by setting ++the 'Tlist_WinWidth' variable. You can specify the height of the horizontally ++split taglist window, by setting the 'Tlist_WinHeight' variable. ++ ++When opening a vertically split taglist window, the Vim window width is ++increased to accommodate the new taglist window. When the taglist window is ++closed, the Vim window is reduced. To disable this, set the ++'Tlist_Inc_Winwidth' variable to zero. ++ ++To reduce the number of empty lines in the taglist window, set the ++'Tlist_Compact_Format' variable to 1. ++ ++To not display the Vim fold column in the taglist window, set the ++'Tlist_Enable_Fold_Column' variable to zero. ++ ++To display the tag prototypes instead of the tag names in the taglist window, ++set the 'Tlist_Display_Prototype' variable to 1. ++ ++To not display the scope of the tags next to the tag names, set the ++'Tlist_Display_Tag_Scope' variable to zero. ++ ++ *taglist-keys* ++Taglist window key list~ ++The following table lists the description of the keys that can be used ++in the taglist window. ++ ++ Key Description~ ++ ++ Jump to the location where the tag under cursor is ++ defined. ++ o Jump to the location where the tag under cursor is ++ defined in a new window. ++ P Jump to the tag in the previous (Ctrl-W_p) window. ++ p Display the tag definition in the file window and ++ keep the cursor in the taglist window itself. ++ t Jump to the tag in a new tab. If the file is already ++ opened in a tab, move to that tab. ++ Ctrl-t Jump to the tag in a new tab. ++ Display the prototype of the tag under the cursor. ++ For file names, display the full path to the file, ++ file type and the number of tags. For tag types, display the ++ tag type and the number of tags. ++ u Update the tags listed in the taglist window ++ s Change the sort order of the tags (by name or by order) ++ d Remove the tags for the file under the cursor ++ x Zoom-in or Zoom-out the taglist window ++ + Open a fold ++ - Close a fold ++ * Open all folds ++ = Close all folds ++ [[ Jump to the beginning of the previous file ++ Jump to the beginning of the previous file ++ ]] Jump to the beginning of the next file ++ Jump to the beginning of the next file ++ q Close the taglist window ++ Display help ++ ++The above keys will work in both the normal mode and the insert mode. ++ ++ *taglist-menu* ++Taglist menu~ ++When using GUI Vim, the taglist plugin can display the tags defined in the ++current file in the drop-down menu and the popup menu. By default, this ++feature is turned off. To turn on this feature, set the 'Tlist_Show_Menu' ++variable to 1. ++ ++You can jump to a tag by selecting the tag name from the menu. You can use the ++taglist menu independent of the taglist window i.e. you don't need to open the ++taglist window to get the taglist menu. ++ ++When you switch between files/buffers, the taglist menu is automatically ++updated to display the tags defined in the current file/buffer. ++ ++The tags are grouped by their type (variables, functions, classes, methods, ++etc.) and displayed as a separate sub-menu for each type. If all the tags ++defined in a file are of the same type (e.g. functions), then the sub-menu is ++not used. ++ ++If the number of items in a tag type submenu exceeds the value specified by ++the 'Tlist_Max_Submenu_Items' variable, then the submenu will be split into ++multiple submenus. The default setting for 'Tlist_Max_Submenu_Items' is 25. ++The first and last tag names in the submenu are used to form the submenu name. ++The menu items are prefixed by alpha-numeric characters for easy selection by ++keyboard. ++ ++If the popup menu support is enabled (the |'mousemodel'| option contains ++"popup"), then the tags menu is added to the popup menu. You can access ++the popup menu by right clicking on the GUI window. ++ ++You can regenerate the tags menu by selecting the 'Tags->Refresh menu' entry. ++You can sort the tags listed in the menu either by name or by order by ++selecting the 'Tags->Sort menu by->Name/Order' menu entry. ++ ++You can tear-off the Tags menu and keep it on the side of the Vim window ++for quickly locating the tags. ++ ++Using the taglist plugin with the winmanager plugin~ ++You can use the taglist plugin with the winmanager plugin. This will allow you ++to use the file explorer, buffer explorer and the taglist plugin at the same ++time in different windows. To use the taglist plugin with the winmanager ++plugin, set 'TagList' in the 'winManagerWindowLayout' variable. For example, ++to use the file explorer plugin and the taglist plugin at the same time, use ++the following setting: > ++ ++ let winManagerWindowLayout = 'FileExplorer|TagList' ++< ++Getting help~ ++If you have installed the taglist help file (this file), then you can use the ++Vim ":help taglist-" command to get help on the various taglist ++topics. ++ ++You can press the key in the taglist window to display the help ++information about using the taglist window. If you again press the key, ++the help information is removed from the taglist window. ++ ++ *taglist-debug* ++Debugging the taglist plugin~ ++You can use the ":TlistDebug" command to enable logging of the debug messages ++from the taglist plugin. To display the logged debug messages, you can use the ++":TlistMessages" command. To disable the logging of the debug messages, use ++the ":TlistUndebug" command. ++ ++You can specify a file name to the ":TlistDebug" command to log the debug ++messages to a file. Otherwise, the debug messages are stored in a script-local ++variable. In the later case, to minimize memory usage, only the last 3000 ++characters from the debug messages are stored. ++ ++============================================================================== ++ *taglist-options* ++6. Options~ ++ ++A number of Vim variables control the behavior of the taglist plugin. These ++variables are initialized to a default value. By changing these variables you ++can change the behavior of the taglist plugin. You need to change these ++settings only if you want to change the behavior of the taglist plugin. You ++should use the |:let| command in your .vimrc file to change the setting of any ++of these variables. ++ ++The configurable taglist variables are listed below. For a detailed ++description of these variables refer to the text below this table. ++ ++|'Tlist_Auto_Highlight_Tag'| Automatically highlight the current tag in the ++ taglist. ++|'Tlist_Auto_Open'| Open the taglist window when Vim starts. ++|'Tlist_Auto_Update'| Automatically update the taglist to include ++ newly edited files. ++|'Tlist_Close_On_Select'| Close the taglist window when a file or tag is ++ selected. ++|'Tlist_Compact_Format'| Remove extra information and blank lines from ++ the taglist window. ++|'Tlist_Ctags_Cmd'| Specifies the path to the ctags utility. ++|'Tlist_Display_Prototype'| Show prototypes and not tags in the taglist ++ window. ++|'Tlist_Display_Tag_Scope'| Show tag scope next to the tag name. ++|'Tlist_Enable_Fold_Column'| Show the fold indicator column in the taglist ++ window. ++|'Tlist_Exit_OnlyWindow'| Close Vim if the taglist is the only window. ++|'Tlist_File_Fold_Auto_Close'| Close tag folds for inactive buffers. ++|'Tlist_GainFocus_On_ToggleOpen'| ++ Jump to taglist window on open. ++|'Tlist_Highlight_Tag_On_BufEnter'| ++ On entering a buffer, automatically highlight ++ the current tag. ++|'Tlist_Inc_Winwidth'| Increase the Vim window width to accommodate ++ the taglist window. ++|'Tlist_Max_Submenu_Items'| Maximum number of items in a tags sub-menu. ++|'Tlist_Max_Tag_Length'| Maximum tag length used in a tag menu entry. ++|'Tlist_Process_File_Always'| Process files even when the taglist window is ++ closed. ++|'Tlist_Show_Menu'| Display the tags menu. ++|'Tlist_Show_One_File'| Show tags for the current buffer only. ++|'Tlist_Sort_Type'| Sort method used for arranging the tags. ++|'Tlist_Use_Horiz_Window'| Use a horizontally split window for the ++ taglist window. ++|'Tlist_Use_Right_Window'| Place the taglist window on the right side. ++|'Tlist_Use_SingleClick'| Single click on a tag jumps to it. ++|'Tlist_WinHeight'| Horizontally split taglist window height. ++|'Tlist_WinWidth'| Vertically split taglist window width. ++ ++ *'Tlist_Auto_Highlight_Tag'* ++Tlist_Auto_Highlight_Tag~ ++The taglist plugin will automatically highlight the current tag in the taglist ++window. If you want to disable this, then you can set the ++'Tlist_Auto_Highlight_Tag' variable to zero. Note that even though the current ++tag highlighting is disabled, the tags for a new file will still be added to ++the taglist window. ++> ++ let Tlist_Auto_Highlight_Tag = 0 ++< ++With the above variable set to 1, you can use the ":TlistHighlightTag" command ++to highlight the current tag. ++ ++ *'Tlist_Auto_Open'* ++Tlist_Auto_Open~ ++To automatically open the taglist window, when you start Vim, you can set the ++'Tlist_Auto_Open' variable to 1. By default, this variable is set to zero and ++the taglist window will not be opened automatically on Vim startup. ++> ++ let Tlist_Auto_Open = 1 ++< ++The taglist window is opened only when a supported type of file is opened on ++Vim startup. For example, if you open text files, then the taglist window will ++not be opened. ++ ++ *'Tlist_Auto_Update'* ++Tlist_Auto_Update~ ++When a new file is edited, the tags defined in the file are automatically ++processed and added to the taglist. To stop adding new files to the taglist, ++set the 'Tlist_Auto_Update' variable to zero. By default, this variable is set ++to 1. ++> ++ let Tlist_Auto_Update = 0 ++< ++With the above variable set to 1, you can use the ":TlistUpdate" command to ++add the tags defined in the current file to the taglist. ++ ++ *'Tlist_Close_On_Select'* ++Tlist_Close_On_Select~ ++If you want to close the taglist window when a file or tag is selected, then ++set the 'Tlist_Close_On_Select' variable to 1. By default, this variable is ++set zero and when you select a tag or file from the taglist window, the window ++is not closed. ++> ++ let Tlist_Close_On_Select = 1 ++< ++ *'Tlist_Compact_Format'* ++Tlist_Compact_Format~ ++By default, empty lines are used to separate different tag types displayed for ++a file and the tags displayed for different files in the taglist window. If ++you want to display as many tags as possible in the taglist window, you can ++set the 'Tlist_Compact_Format' variable to 1 to get a compact display. ++> ++ let Tlist_Compact_Format = 1 ++< ++ *'Tlist_Ctags_Cmd'* ++Tlist_Ctags_Cmd~ ++The 'Tlist_Ctags_Cmd' variable specifies the location (path) of the exuberant ++ctags utility. If exuberant ctags is present in any one of the directories in ++the PATH environment variable, then there is no need to set this variable. ++ ++The exuberant ctags tool can be installed under different names. When the ++taglist plugin starts up, if the 'Tlist_Ctags_Cmd' variable is not set, it ++checks for the names exuberant-ctags, exctags, ctags, ctags.exe and tags in ++the PATH environment variable. If any one of the named executable is found, ++then the Tlist_Ctags_Cmd variable is set to that name. ++ ++If exuberant ctags is not present in one of the directories specified in the ++PATH environment variable, then set this variable to point to the location of ++the ctags utility in your system. Note that this variable should point to the ++fully qualified exuberant ctags location and NOT to the directory in which ++exuberant ctags is installed. If the exuberant ctags tool is not found in ++either PATH or in the specified location, then the taglist plugin will not be ++loaded. Examples: ++> ++ let Tlist_Ctags_Cmd = 'd:\tools\ctags.exe' ++ let Tlist_Ctags_Cmd = '/usr/local/bin/ctags' ++< ++ *'Tlist_Display_Prototype'* ++Tlist_Display_Prototype~ ++By default, only the tag name will be displayed in the taglist window. If you ++like to see tag prototypes instead of names, set the 'Tlist_Display_Prototype' ++variable to 1. By default, this variable is set to zero and only tag names ++will be displayed. ++> ++ let Tlist_Display_Prototype = 1 ++< ++ *'Tlist_Display_Tag_Scope'* ++Tlist_Display_Tag_Scope~ ++By default, the scope of a tag (like a C++ class) will be displayed in ++square brackets next to the tag name. If you don't want the tag scopes ++to be displayed, then set the 'Tlist_Display_Tag_Scope' to zero. By default, ++this variable is set to 1 and the tag scopes will be displayed. ++> ++ let Tlist_Display_Tag_Scope = 0 ++< ++ *'Tlist_Enable_Fold_Column'* ++Tlist_Enable_Fold_Column~ ++By default, the Vim fold column is enabled and displayed in the taglist ++window. If you wish to disable this (for example, when you are working with a ++narrow Vim window or terminal), you can set the 'Tlist_Enable_Fold_Column' ++variable to zero. ++> ++ let Tlist_Enable_Fold_Column = 1 ++< ++ *'Tlist_Exit_OnlyWindow'* ++Tlist_Exit_OnlyWindow~ ++If you want to exit Vim if only the taglist window is currently opened, then ++set the 'Tlist_Exit_OnlyWindow' variable to 1. By default, this variable is ++set to zero and the Vim instance will not be closed if only the taglist window ++is present. ++> ++ let Tlist_Exit_OnlyWindow = 1 ++< ++ *'Tlist_File_Fold_Auto_Close'* ++Tlist_File_Fold_Auto_Close~ ++By default, the tags tree displayed in the taglist window for all the files is ++opened. You can close/fold the tags tree for the files manually. To ++automatically close the tags tree for inactive files, you can set the ++'Tlist_File_Fold_Auto_Close' variable to 1. When this variable is set to 1, ++the tags tree for the current buffer is automatically opened and for all the ++other buffers is closed. ++> ++ let Tlist_File_Fold_Auto_Close = 1 ++< ++ *'Tlist_GainFocus_On_ToggleOpen'* ++Tlist_GainFocus_On_ToggleOpen~ ++When the taglist window is opened using the ':TlistToggle' command, this ++option controls whether the cursor is moved to the taglist window or remains ++in the current window. By default, this option is set to 0 and the cursor ++remains in the current window. When this variable is set to 1, the cursor ++moves to the taglist window after opening the taglist window. ++> ++ let Tlist_GainFocus_On_ToggleOpen = 1 ++< ++ *'Tlist_Highlight_Tag_On_BufEnter'* ++Tlist_Highlight_Tag_On_BufEnter~ ++When you enter a Vim buffer/window, the current tag in that buffer/window is ++automatically highlighted in the taglist window. If the current tag name is ++not visible in the taglist window, then the taglist window contents are ++scrolled to make that tag name visible. If you like to disable the automatic ++highlighting of the current tag when entering a buffer, you can set the ++'Tlist_Highlight_Tag_On_BufEnter' variable to zero. The default setting for ++this variable is 1. ++> ++ let Tlist_Highlight_Tag_On_BufEnter = 0 ++< ++ *'Tlist_Inc_Winwidth'* ++Tlist_Inc_Winwidth~ ++By default, when the width of the window is less than 100 and a new taglist ++window is opened vertically, then the window width is increased by the value ++set in the 'Tlist_WinWidth' variable to accommodate the new window. The value ++of this variable is used only if you are using a vertically split taglist ++window. ++ ++If your terminal doesn't support changing the window width from Vim (older ++version of xterm running in a Unix system) or if you see any weird problems in ++the screen due to the change in the window width or if you prefer not to ++adjust the window width then set the 'Tlist_Inc_Winwidth' variable to zero. ++CAUTION: If you are using the MS-Windows version of Vim in a MS-DOS command ++window then you must set this variable to zero, otherwise the system may hang ++due to a Vim limitation (explained in :help win32-problems) ++> ++ let Tlist_Inc_Winwidth = 0 ++< ++ *'Tlist_Max_Submenu_Items'* ++Tlist_Max_Submenu_Items~ ++If a file contains too many tags of a particular type (function, variable, ++class, etc.), greater than that specified by the 'Tlist_Max_Submenu_Items' ++variable, then the menu for that tag type will be split into multiple ++sub-menus. The default setting for the 'Tlist_Max_Submenu_Items' variable is ++25. This can be changed by setting the 'Tlist_Max_Submenu_Items' variable: ++> ++ let Tlist_Max_Submenu_Items = 20 ++< ++The name of the submenu is formed using the names of the first and the last ++tag entries in that submenu. ++ ++ *'Tlist_Max_Tag_Length'* ++Tlist_Max_Tag_Length~ ++Only the first 'Tlist_Max_Tag_Length' characters from the tag names will be ++used to form the tag type submenu name. The default value for this variable is ++10. Change the 'Tlist_Max_Tag_Length' setting if you want to include more or ++less characters: ++> ++ let Tlist_Max_Tag_Length = 10 ++< ++ *'Tlist_Process_File_Always'* ++Tlist_Process_File_Always~ ++By default, the taglist plugin will generate and process the tags defined in ++the newly opened files only when the taglist window is opened or when the ++taglist menu is enabled. When the taglist window is closed, the taglist plugin ++will stop processing the tags for newly opened files. ++ ++You can set the 'Tlist_Process_File_Always' variable to 1 to generate the list ++of tags for new files even when the taglist window is closed and the taglist ++menu is disabled. ++> ++ let Tlist_Process_File_Always = 1 ++< ++To use the ":TlistShowTag" and the ":TlistShowPrototype" commands without the ++taglist window and the taglist menu, you should set this variable to 1. ++ ++ *'Tlist_Show_Menu'* ++Tlist_Show_Menu~ ++When using GUI Vim, you can display the tags defined in the current file in a ++menu named "Tags". By default, this feature is turned off. To turn on this ++feature, set the 'Tlist_Show_Menu' variable to 1: ++> ++ let Tlist_Show_Menu = 1 ++< ++ *'Tlist_Show_One_File'* ++Tlist_Show_One_File~ ++By default, the taglist plugin will display the tags defined in all the loaded ++buffers in the taglist window. If you prefer to display the tags defined only ++in the current buffer, then you can set the 'Tlist_Show_One_File' to 1. When ++this variable is set to 1, as you switch between buffers, the taglist window ++will be refreshed to display the tags for the current buffer and the tags for ++the previous buffer will be removed. ++> ++ let Tlist_Show_One_File = 1 ++< ++ *'Tlist_Sort_Type'* ++Tlist_Sort_Type~ ++The 'Tlist_Sort_Type' variable specifies the sort order for the tags in the ++taglist window. The tags can be sorted either alphabetically by their name or ++by the order of their appearance in the file (chronological order). By ++default, the tag names will be listed by the order in which they are defined ++in the file. You can change the sort type (from name to order or from order to ++name) by pressing the "s" key in the taglist window. You can also change the ++default sort order by setting 'Tlist_Sort_Type' to "name" or "order": ++> ++ let Tlist_Sort_Type = "name" ++< ++ *'Tlist_Use_Horiz_Window'* ++Tlist_Use_Horiz_Window~ ++Be default, the tag names are displayed in a vertically split window. If you ++prefer a horizontally split window, then set the 'Tlist_Use_Horiz_Window' ++variable to 1. If you are running MS-Windows version of Vim in a MS-DOS ++command window, then you should use a horizontally split window instead of a ++vertically split window. Also, if you are using an older version of xterm in a ++Unix system that doesn't support changing the xterm window width, you should ++use a horizontally split window. ++> ++ let Tlist_Use_Horiz_Window = 1 ++< ++ *'Tlist_Use_Right_Window'* ++Tlist_Use_Right_Window~ ++By default, the vertically split taglist window will appear on the left hand ++side. If you prefer to open the window on the right hand side, you can set the ++'Tlist_Use_Right_Window' variable to 1: ++> ++ let Tlist_Use_Right_Window = 1 ++< ++ *'Tlist_Use_SingleClick'* ++Tlist_Use_SingleClick~ ++By default, when you double click on the tag name using the left mouse ++button, the cursor will be positioned at the definition of the tag. You ++can set the 'Tlist_Use_SingleClick' variable to 1 to jump to a tag when ++you single click on the tag name using the mouse. By default this variable ++is set to zero. ++> ++ let Tlist_Use_SingleClick = 1 ++< ++Due to a bug in Vim, if you set 'Tlist_Use_SingleClick' to 1 and try to resize ++the taglist window using the mouse, then Vim will crash. This problem is fixed ++in Vim 6.3 and above. In the meantime, instead of resizing the taglist window ++using the mouse, you can use normal Vim window resizing commands to resize the ++taglist window. ++ ++ *'Tlist_WinHeight'* ++Tlist_WinHeight~ ++The default height of the horizontally split taglist window is 10. This can be ++changed by modifying the 'Tlist_WinHeight' variable: ++> ++ let Tlist_WinHeight = 20 ++< ++The |'winfixheight'| option is set for the taglist window, to maintain the ++height of the taglist window, when new Vim windows are opened and existing ++windows are closed. ++ ++ *'Tlist_WinWidth'* ++Tlist_WinWidth~ ++The default width of the vertically split taglist window is 30. This can be ++changed by modifying the 'Tlist_WinWidth' variable: ++> ++ let Tlist_WinWidth = 20 ++< ++Note that the value of the |'winwidth'| option setting determines the minimum ++width of the current window. If you set the 'Tlist_WinWidth' variable to a ++value less than that of the |'winwidth'| option setting, then Vim will use the ++value of the |'winwidth'| option. ++ ++When new Vim windows are opened and existing windows are closed, the taglist ++plugin will try to maintain the width of the taglist window to the size ++specified by the 'Tlist_WinWidth' variable. ++ ++============================================================================== ++ *taglist-commands* ++7. Commands~ ++ ++The taglist plugin provides the following ex-mode commands: ++ ++|:TlistAddFiles| Add multiple files to the taglist. ++|:TlistAddFilesRecursive| ++ Add files recursively to the taglist. ++|:TlistClose| Close the taglist window. ++|:TlistDebug| Start logging of taglist debug messages. ++|:TlistLock| Stop adding new files to the taglist. ++|:TlistMessages| Display the logged taglist plugin debug messages. ++|:TlistOpen| Open and jump to the taglist window. ++|:TlistSessionSave| Save the information about files and tags in the ++ taglist to a session file. ++|:TlistSessionLoad| Load the information about files and tags stored ++ in a session file to taglist. ++|:TlistShowPrototype| Display the prototype of the tag at or before the ++ specified line number. ++|:TlistShowTag| Display the name of the tag defined at or before the ++ specified line number. ++|:TlistHighlightTag| Highlight the current tag in the taglist window. ++|:TlistToggle| Open or close (toggle) the taglist window. ++|:TlistUndebug| Stop logging of taglist debug messages. ++|:TlistUnlock| Start adding new files to the taglist. ++|:TlistUpdate| Update the tags for the current buffer. ++ ++ *:TlistAddFiles* ++:TlistAddFiles {file(s)} [file(s) ...] ++ Add one or more specified files to the taglist. You can ++ specify multiple filenames using wildcards. To specify a ++ file name with space character, you should escape the space ++ character with a backslash. ++ Examples: ++> ++ :TlistAddFiles *.c *.cpp ++ :TlistAddFiles file1.html file2.html ++< ++ If you specify a large number of files, then it will take some ++ time for the taglist plugin to process all of them. The ++ specified files will not be edited in a Vim window and will ++ not be added to the Vim buffer list. ++ ++ *:TlistAddFilesRecursive* ++:TlistAddFilesRecursive {directory} [ {pattern} ] ++ Add files matching {pattern} recursively from the specified ++ {directory} to the taglist. If {pattern} is not specified, ++ then '*' is assumed. To specify the current directory, use "." ++ for {directory}. To specify a directory name with space ++ character, you should escape the space character with a ++ backslash. ++ Examples: ++> ++ :TlistAddFilesRecursive myproject *.java ++ :TlistAddFilesRecursive smallproject ++< ++ If large number of files are present in the specified ++ directory tree, then it will take some time for the taglist ++ plugin to process all of them. ++ ++ *:TlistClose* ++:TlistClose Close the taglist window. This command can be used from any ++ one of the Vim windows. ++ ++ *:TlistDebug* ++:TlistDebug [filename] ++ Start logging of debug messages from the taglist plugin. ++ If {filename} is specified, then the debug messages are stored ++ in the specified file. Otherwise, the debug messages are ++ stored in a script local variable. If the file {filename} is ++ already present, then it is overwritten. ++ ++ *:TlistLock* ++:TlistLock ++ Lock the taglist and don't process new files. After this ++ command is executed, newly edited files will not be added to ++ the taglist. ++ ++ *:TlistMessages* ++:TlistMessages ++ Display the logged debug messages from the taglist plugin ++ in a window. This command works only when logging to a ++ script-local variable. ++ ++ *:TlistOpen* ++:TlistOpen Open and jump to the taglist window. Creates the taglist ++ window, if the window is not opened currently. After executing ++ this command, the cursor is moved to the taglist window. When ++ the taglist window is opened for the first time, all the files ++ in the buffer list are processed and the tags defined in them ++ are displayed in the taglist window. ++ ++ *:TlistSessionSave* ++:TlistSessionSave {filename} ++ Saves the information about files and tags in the taglist to ++ the specified file. This command can be used to save and ++ restore the taglist contents across Vim sessions. ++ ++ *:TlistSessionLoad* ++:TlistSessionLoad {filename} ++ Load the information about files and tags stored in the ++ specified session file to the taglist. ++ ++ *:TlistShowPrototype* ++:TlistShowPrototype [filename] [linenumber] ++ Display the prototype of the tag at or before the specified ++ line number. If the file name and the line number are not ++ specified, then the current file name and line number are ++ used. A tag spans multiple lines starting from the line where ++ it is defined to the line before the next tag. This command ++ displays the prototype for the tag for any line number in this ++ range. ++ ++ *:TlistShowTag* ++:TlistShowTag [filename] [linenumber] ++ Display the name of the tag defined at or before the specified ++ line number. If the file name and the line number are not ++ specified, then the current file name and line number are ++ used. A tag spans multiple lines starting from the line where ++ it is defined to the line before the next tag. This command ++ displays the tag name for any line number in this range. ++ ++ *:TlistHighlightTag* ++:TlistHighlightTag ++ Highlight the current tag in the taglist window. By default, ++ the taglist plugin periodically updates the taglist window to ++ highlight the current tag. This command can be used to force ++ the taglist plugin to highlight the current tag. ++ ++ *:TlistToggle* ++:TlistToggle Open or close (toggle) the taglist window. Opens the taglist ++ window, if the window is not opened currently. Closes the ++ taglist window, if the taglist window is already opened. When ++ the taglist window is opened for the first time, all the files ++ in the buffer list are processed and the tags are displayed in ++ the taglist window. After executing this command, the cursor ++ is not moved from the current window to the taglist window. ++ ++ *:TlistUndebug* ++:TlistUndebug ++ Stop logging of debug messages from the taglist plugin. ++ ++ *:TlistUnlock* ++:TlistUnlock ++ Unlock the taglist and start processing newly edited files. ++ ++ *:TlistUpdate* ++:TlistUpdate Update the tags information for the current buffer. This ++ command can be used to re-process the current file/buffer and ++ get the tags information. As the taglist plugin uses the file ++ saved in the disk (instead of the file displayed in a Vim ++ buffer), you should save a modified buffer before you update ++ the taglist. Otherwise the listed tags will not include the ++ new tags created in the buffer. You can use this command even ++ when the taglist window is not opened. ++ ++============================================================================== ++ *taglist-functions* ++8. Global functions~ ++ ++The taglist plugin provides several global functions that can be used from ++other Vim plugins to interact with the taglist plugin. These functions are ++described below. ++ ++|Tlist_Update_File_Tags()| Update the tags for the specified file ++|Tlist_Get_Tag_Prototype_By_Line()| Return the prototype of the tag at or ++ before the specified line number in the ++ specified file. ++|Tlist_Get_Tagname_By_Line()| Return the name of the tag at or ++ before the specified line number in ++ the specified file. ++|Tlist_Set_App()| Set the name of the application ++ controlling the taglist window. ++ ++ *Tlist_Update_File_Tags()* ++Tlist_Update_File_Tags({filename}, {filetype}) ++ Update the tags for the file {filename}. The second argument ++ specifies the Vim filetype for the file. If the taglist plugin ++ has not processed the file previously, then the exuberant ++ ctags tool is invoked to generate the tags for the file. ++ ++ *Tlist_Get_Tag_Prototype_By_Line()* ++Tlist_Get_Tag_Prototype_By_Line([{filename}, {linenumber}]) ++ Return the prototype of the tag at or before the specified ++ line number in the specified file. If the filename and line ++ number are not specified, then the current buffer name and the ++ current line number are used. ++ ++ *Tlist_Get_Tagname_By_Line()* ++Tlist_Get_Tagname_By_Line([{filename}, {linenumber}]) ++ Return the name of the tag at or before the specified line ++ number in the specified file. If the filename and line number ++ are not specified, then the current buffer name and the ++ current line number are used. ++ ++ *Tlist_Set_App()* ++Tlist_Set_App({appname}) ++ Set the name of the plugin that controls the taglist plugin ++ window and buffer. This can be used to integrate the taglist ++ plugin with other Vim plugins. ++ ++ For example, the winmanager plugin and the Cream package use ++ this function and specify the appname as "winmanager" and ++ "cream" respectively. ++ ++ By default, the taglist plugin is a stand-alone plugin and ++ controls the taglist window and buffer. If the taglist window ++ is controlled by an external plugin, then the appname should ++ be set appropriately. ++ ++============================================================================== ++ *taglist-extend* ++9. Extending~ ++ ++The taglist plugin supports all the languages supported by the exuberant ctags ++tool, which includes the following languages: Assembly, ASP, Awk, Beta, C, ++C++, C#, Cobol, Eiffel, Erlang, Fortran, HTML, Java, Javascript, Lisp, Lua, ++Make, Pascal, Perl, PHP, Python, Rexx, Ruby, Scheme, Shell, Slang, SML, Sql, ++TCL, Verilog, Vim and Yacc. ++ ++You can extend the taglist plugin to add support for new languages and also ++modify the support for the above listed languages. ++ ++You should NOT make modifications to the taglist plugin script file to add ++support for new languages. You will lose these changes when you upgrade to the ++next version of the taglist plugin. Instead you should follow the below ++described instructions to extend the taglist plugin. ++ ++You can extend the taglist plugin by setting variables in the .vimrc or _vimrc ++file. The name of these variables depends on the language name and is ++described below. ++ ++Modifying support for an existing language~ ++To modify the support for an already supported language, you have to set the ++tlist_xxx_settings variable in the ~/.vimrc or $HOME/_vimrc file. Replace xxx ++with the Vim filetype name for the language file. For example, to modify the ++support for the perl language files, you have to set the tlist_perl_settings ++variable. To modify the support for java files, you have to set the ++tlist_java_settings variable. ++ ++To determine the filetype name used by Vim for a file, use the following ++command in the buffer containing the file: ++ ++ :set filetype ++ ++The above command will display the Vim filetype for the current buffer. ++ ++The format of the value set in the tlist_xxx_settings variable is ++ ++ ;flag1:name1;flag2:name2;flag3:name3 ++ ++The different fields in the value are separated by the ';' character. ++ ++The first field 'language_name' is the name used by exuberant ctags to refer ++to this language file. This name can be different from the file type name used ++by Vim. For example, for C++, the language name used by ctags is 'c++' but the ++filetype name used by Vim is 'cpp'. To get the list of language names ++supported by exuberant ctags, use the following command: ++ ++ $ ctags --list-maps=all ++ ++The remaining fields follow the format "flag:name". The sub-field 'flag' is ++the language specific flag used by exuberant ctags to generate the ++corresponding tags. For example, for the C language, to list only the ++functions, the 'f' flag is used. To get the list of flags supported by ++exuberant ctags for the various languages use the following command: ++ ++ $ ctags --list-kinds=all ++ ++The sub-field 'name' specifies the title text to use for displaying the tags ++of a particular type. For example, 'name' can be set to 'functions'. This ++field can be set to any text string name. ++ ++For example, to list only the classes and functions defined in a C++ language ++file, add the following line to your .vimrc file: ++ ++ let tlist_cpp_settings = 'c++;c:class;f:function' ++ ++In the above setting, 'cpp' is the Vim filetype name and 'c++' is the name ++used by the exuberant ctags tool. 'c' and 'f' are the flags passed to ++exuberant ctags to list C++ classes and functions and 'class' is the title ++used for the class tags and 'function' is the title used for the function tags ++in the taglist window. ++ ++For example, to display only functions defined in a C file and to use "My ++Functions" as the title for the function tags, use ++ ++ let tlist_c_settings = 'c;f:My Functions' ++ ++When you set the tlist_xxx_settings variable, you will override the default ++setting used by the taglist plugin for the 'xxx' language. You cannot add to ++the default options used by the taglist plugin for a particular file type. To ++add to the options used by the taglist plugin for a language, copy the option ++values from the taglist plugin file to your .vimrc file and modify it. ++ ++Adding support for a new language~ ++If you want to add support for a new language to the taglist plugin, you need ++to first extend the exuberant ctags tool. For more information about extending ++exuberant ctags, visit the following page: ++ ++ http://ctags.sourceforge.net/EXTENDING.html ++ ++To add support for a new language, set the tlist_xxx_settings variable in the ++~/.vimrc file appropriately as described above. Replace 'xxx' in the variable ++name with the Vim filetype name for the new language. ++ ++For example, to extend the taglist plugin to support the latex language, you ++can use the following line (assuming, you have already extended exuberant ++ctags to support the latex language): ++ ++ let tlist_tex_settings='latex;b:bibitem;c:command;l:label' ++ ++With the above line, when you edit files of filetype "tex" in Vim, the taglist ++plugin will invoke the exuberant ctags tool passing the "latex" filetype and ++the flags b, c and l to generate the tags. The text heading 'bibitem', ++'command' and 'label' will be used in the taglist window for the tags which ++are generated for the flags b, c and l respectively. ++ ++============================================================================== ++ *taglist-faq* ++10. Frequently Asked Questions~ ++ ++Q. The taglist plugin doesn't work. The taglist window is empty and the tags ++ defined in a file are not displayed. ++A. Are you using Vim version 6.0 and above? The taglist plugin relies on the ++ features supported by Vim version 6.0 and above. You can use the following ++ command to get the Vim version: ++> ++ $ vim --version ++< ++ Are you using exuberant ctags version 5.0 and above? The taglist plugin ++ relies on the features supported by exuberant ctags and will not work with ++ GNU ctags or the Unix ctags utility. You can use the following command to ++ determine whether the ctags installed in your system is exuberant ctags: ++> ++ $ ctags --version ++< ++ Is exuberant ctags present in one of the directories in your PATH? If not, ++ you need to set the Tlist_Ctags_Cmd variable to point to the location of ++ exuberant ctags. Use the following Vim command to verify that this is setup ++ correctly: ++> ++ :echo system(Tlist_Ctags_Cmd . ' --version') ++< ++ The above command should display the version information for exuberant ++ ctags. ++ ++ Did you turn on the Vim filetype detection? The taglist plugin relies on ++ the filetype detected by Vim and passes the filetype to the exuberant ctags ++ utility to parse the tags. Check the output of the following Vim command: ++> ++ :filetype ++< ++ The output of the above command should contain "filetype detection:ON". ++ To turn on the filetype detection, add the following line to the .vimrc or ++ _vimrc file: ++> ++ filetype on ++< ++ Is your version of Vim compiled with the support for the system() function? ++ The following Vim command should display 1: ++> ++ :echo exists('*system') ++< ++ In some Linux distributions (particularly Suse Linux), the default Vim ++ installation is built without the support for the system() function. The ++ taglist plugin uses the system() function to invoke the exuberant ctags ++ utility. You need to rebuild Vim after enabling the support for the ++ system() function. If you use the default build options, the system() ++ function will be supported. ++ ++ Do you have the |'shellslash'| option set? You can try disabling the ++ |'shellslash'| option. When the taglist plugin invokes the exuberant ctags ++ utility with the path to the file, if the incorrect slashes are used, then ++ you will see errors. ++ ++ Check the shell related Vim options values using the following command: ++> ++ :set shell? shellcmdflag? shellpipe? ++ :set shellquote? shellredir? shellxquote? ++< ++ If these options are set in your .vimrc or _vimrc file, try removing those ++ lines. ++ ++ Are you using a Unix shell in a MS-Windows environment? For example, ++ the Unix shell from the MKS-toolkit. Do you have the SHELL environment ++ set to point to this shell? You can try resetting the SHELL environment ++ variable. ++ ++ If you are using a Unix shell on MS-Windows, you should try to use ++ exuberant ctags that is compiled for Unix-like environments so that ++ exuberant ctags will understand path names with forward slash characters. ++ ++ Is your filetype supported by the exuberant ctags utility? The file types ++ supported by the exuberant ctags utility are listed in the ctags help. If a ++ file type is not supported, you have to extend exuberant ctags. You can use ++ the following command to list the filetypes supported by exuberant ctags: ++> ++ ctags --list-languages ++< ++ Run the following command from the shell prompt and check whether the tags ++ defined in your file are listed in the output from exuberant ctags: ++> ++ ctags -f - --format=2 --excmd=pattern --fields=nks ++< ++ If you see your tags in the output from the above command, then the ++ exuberant ctags utility is properly parsing your file. ++ ++ Do you have the .ctags or _ctags or the ctags.cnf file in your home ++ directory for specifying default options or for extending exuberant ctags? ++ If you do have this file, check the options in this file and make sure ++ these options are not interfering with the operation of the taglist plugin. ++ ++ If you are using MS-Windows, check the value of the TEMP and TMP ++ environment variables. If these environment variables are set to a path ++ with space characters in the name, then try using the DOS 8.3 short name ++ for the path or set them to a path without the space characters in the ++ name. For example, if the temporary directory name is "C:\Documents and ++ Settings\xyz\Local Settings\Temp", then try setting the TEMP variable to ++ the following: ++> ++ set TEMP=C:\DOCUMEN~1\xyz\LOCALS~1\Temp ++< ++ If exuberant ctags is installed in a directory with space characters in the ++ name, then try adding the directory to the PATH environment variable or try ++ setting the 'Tlist_Ctags_Cmd' variable to the shortest path name to ctags ++ or try copying the exuberant ctags to a path without space characters in ++ the name. For example, if exuberant ctags is installed in the directory ++ "C:\Program Files\Ctags", then try setting the 'Tlist_Ctags_Cmd' variable ++ as below: ++> ++ let Tlist_Ctags_Cmd='C:\Progra~1\Ctags\ctags.exe' ++< ++Q. When I try to open the taglist window, I am seeing the following error ++ message. How do I fix this problem? ++ ++ Taglist: Failed to generate tags for /my/path/to/file ++ ctags: illegal option -- -^@usage: ctags [-BFadtuwvx] [-f tagsfile] file ... ++ ++A. The taglist plugin will work only with the exuberant ctags tool. You ++ cannot use the GNU ctags or the Unix ctags program with the taglist plugin. ++ You will see an error message similar to the one shown above, if you try ++ use a non-exuberant ctags program with Vim. To fix this problem, either add ++ the exuberant ctags tool location to the PATH environment variable or set ++ the 'Tlist_Ctags_Cmd' variable. ++ ++Q. A file has more than one tag with the same name. When I select a tag name ++ from the taglist window, the cursor is positioned at the incorrect tag ++ location. ++A. The taglist plugin uses the search pattern generated by the exuberant ctags ++ utility to position the cursor at the location of a tag definition. If a ++ file has more than one tag with the same name and same prototype, then the ++ search pattern will be the same. In this case, when searching for the tag ++ pattern, the cursor may be positioned at the incorrect location. ++ ++Q. I have made some modifications to my file and introduced new ++ functions/classes/variables. I have not yet saved my file. The taglist ++ plugin is not displaying the new tags when I update the taglist window. ++A. The exuberant ctags utility will process only files that are present in the ++ disk. To list the tags defined in a file, you have to save the file and ++ then update the taglist window. ++ ++Q. I have created a ctags file using the exuberant ctags utility for my source ++ tree. How do I configure the taglist plugin to use this tags file? ++A. The taglist plugin doesn't use a tags file stored in disk. For every opened ++ file, the taglist plugin invokes the exuberant ctags utility to get the ++ list of tags dynamically. The Vim system() function is used to invoke ++ exuberant ctags and get the ctags output. This function internally uses a ++ temporary file to store the output. This file is deleted after the output ++ from the command is read. So you will never see the file that contains the ++ output of exuberant ctags. ++ ++Q. When I set the |'updatetime'| option to a low value (less than 1000) and if ++ I keep pressing a key with the taglist window open, the current buffer ++ contents are changed. Why is this? ++A. The taglist plugin uses the |CursorHold| autocmd to highlight the current ++ tag. The CursorHold autocmd triggers for every |'updatetime'| milliseconds. ++ If the |'updatetime'| option is set to a low value, then the CursorHold ++ autocmd will be triggered frequently. As the taglist plugin changes ++ the focus to the taglist window to highlight the current tag, this could ++ interfere with the key movement resulting in changing the contents of ++ the current buffer. The workaround for this problem is to not set the ++ |'updatetime'| option to a low value. ++ ++============================================================================== ++ *taglist-license* ++11. License~ ++Permission is hereby granted to use and distribute the taglist plugin, with or ++without modifications, provided that this copyright notice is copied with it. ++Like anything else that's free, taglist.vim is provided *as is* and comes with ++no warranty of any kind, either expressed or implied. In no event will the ++copyright holder be liable for any damamges resulting from the use of this ++software. ++ ++============================================================================== ++ *taglist-todo* ++12. Todo~ ++ ++1. Group tags according to the scope and display them. For example, ++ group all the tags belonging to a C++/Java class ++2. Support for displaying tags in a modified (not-yet-saved) file. ++3. Automatically open the taglist window only for selected filetypes. ++ For other filetypes, close the taglist window. ++4. When using the shell from the MKS toolkit, the taglist plugin ++ doesn't work. ++5. The taglist plugin doesn't work with files edited remotely using the ++ netrw plugin. The exuberant ctags utility cannot process files over ++ scp/rcp/ftp, etc. ++ ++============================================================================== ++ ++vim:tw=78:ts=8:noet:ft=help: +diff -urN vim71/1/ftdetect/ada.vim vim71_ada/1/ftdetect/ada.vim +--- vim71/1/ftdetect/ada.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftdetect/ada.vim 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,39 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada detection file ++" Language: Ada (2005) ++" $Id: ada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ftdetect/ada.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: ft-ada-plugin ++"------------------------------------------------------------------------------ ++ ++if exists("s:loaded_ftdetect_ada") ++ finish ++endif ++ ++let s:loaded_ftdetect_ada=45 ++ ++if has("vms") ++ autocmd BufNewFile,BufRead *.gpr,*.ada_m,*.adc setfiletype ada ++else ++ autocmd BufNewFile,BufRead *.gpr setfiletype ada ++endif ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/ftdetect/.svn/all-wcprops vim71_ada/1/ftdetect/.svn/all-wcprops +--- vim71/1/ftdetect/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftdetect/.svn/all-wcprops 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,11 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 53 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/ftdetect ++END ++ada.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 61 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/ftdetect/ada.vim ++END +diff -urN vim71/1/ftdetect/.svn/dir-prop-base vim71_ada/1/ftdetect/.svn/dir-prop-base +--- vim71/1/ftdetect/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftdetect/.svn/dir-prop-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,12 @@ ++K 10 ++svn:ignore ++V 52 ++*.Backup ++*.tgz ++*.tar.bz2 ++*.rpm ++*.swp ++*.log ++.backups ++ ++END +diff -urN vim71/1/ftdetect/.svn/entries vim71_ada/1/ftdetect/.svn/entries +--- vim71/1/ftdetect/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftdetect/.svn/entries 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,41 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ftdetect ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++ada.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:02.000000Z ++3cc0764c406db398377e8d9214445c63 ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ +diff -urN vim71/1/ftdetect/.svn/format vim71_ada/1/ftdetect/.svn/format +--- vim71/1/ftdetect/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftdetect/.svn/format 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/ftdetect/.svn/prop-base/ada.vim.svn-base vim71_ada/1/ftdetect/.svn/prop-base/ada.vim.svn-base +--- vim71/1/ftdetect/.svn/prop-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftdetect/.svn/prop-base/ada.vim.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/ftdetect/.svn/text-base/ada.vim.svn-base vim71_ada/1/ftdetect/.svn/text-base/ada.vim.svn-base +--- vim71/1/ftdetect/.svn/text-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftdetect/.svn/text-base/ada.vim.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,39 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada detection file ++" Language: Ada (2005) ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: ft-ada-plugin ++"------------------------------------------------------------------------------ ++ ++if exists("s:loaded_ftdetect_ada") ++ finish ++endif ++ ++let s:loaded_ftdetect_ada=45 ++ ++if has("vms") ++ autocmd BufNewFile,BufRead *.gpr,*.ada_m,*.adc setfiletype ada ++else ++ autocmd BufNewFile,BufRead *.gpr setfiletype ada ++endif ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/ftplugin/ada.vim vim71_ada/1/ftplugin/ada.vim +--- vim71/1/ftplugin/ada.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftplugin/ada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,201 @@ ++"------------------------------------------------------------------------------ ++" Description: Perform Ada specific completion & tagging. ++" Language: Ada (2005) ++" $Id: ada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Maintainer: Martin Krischik ++" Taylor Venable ++" Neil Bird ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ftplugin/ada.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK ' should not be in iskeyword. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Better folding. ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" 08.07.2007 TV fix default compiler problems. ++" Help Page: ft-ada-plugin ++"------------------------------------------------------------------------------ ++" Provides mapping overrides for tag jumping that figure out the current ++" Ada object and tag jump to that, not the 'simple' vim word. ++" Similarly allows matching of full-length ada entities from tags. ++"------------------------------------------------------------------------------ ++ ++" Only do this when not done yet for this buffer ++if exists ("b:did_ftplugin") || version < 700 ++ finish ++endif ++ ++" Don't load another plugin for this buffer ++let b:did_ftplugin = 45 ++ ++" ++" Temporarily set cpoptions to ensure the script loads OK ++" ++let s:cpoptions = &cpoptions ++set cpoptions-=C ++ ++" Section: Comments {{{1 ++" ++setlocal comments=O:--,:--\ \ ++setlocal commentstring=--\ \ %s ++setlocal complete=.,w,b,u,t,i ++ ++" Section: Tagging {{{1 ++" ++if exists ("g:ada_extended_tagging") ++ " Make local tag mappings for this buffer (if not already set) ++ if g:ada_extended_tagging == 'jump' ++ if mapcheck('','n') == '' ++ nnoremap :call ada#Jump_Tag ('', 'tjump') ++ endif ++ if mapcheck('g','n') == '' ++ nnoremap g :call ada#Jump_Tag ('','stjump') ++ endif ++ elseif g:ada_extended_tagging == 'list' ++ if mapcheck('','n') == '' ++ nnoremap :call ada#List_Tag () ++ endif ++ if mapcheck('g','n') == '' ++ nnoremap g :call ada#List_Tag () ++ endif ++ endif ++endif ++ ++" Section: Completion {{{1 ++" ++setlocal completefunc=ada#User_Complete ++setlocal omnifunc=adacomplete#Complete ++ ++if exists ("g:ada_extended_completion") ++ if mapcheck ('','i') == '' ++ inoremap =ada#Completion("\C-N>") ++ endif ++ if mapcheck ('','i') == '' ++ inoremap =ada#Completion("\C-P>") ++ endif ++ if mapcheck ('','i') == '' ++ inoremap =ada#Completion("\C-X>\C-]>") ++ endif ++ if mapcheck ('','i') == '' ++ inoremap =ada#Insert_Backspace () ++ endif ++endif ++ ++" Section: Matchit {{{1 ++" ++" Only do this when not done yet for this buffer & matchit is used ++" ++if !exists ("b:match_words") && ++ \ exists ("loaded_matchit") ++ " ++ " The following lines enable the macros/matchit.vim plugin for ++ " Ada-specific extended matching with the % key. ++ " ++ let s:notend = '\%(\:\:\:\\s\+\,' . ++ \ s:notend . '\:\:\\s\+\,' . ++ \ '\%(\.*\|\.*\|'.s:notend.'\)\:\\s\+\,' . ++ \ '\%(\\|\\):\:\\s*\%($\|[;A-Z]\),' . ++ \ s:notend . '\:\\s\+\' ++endif ++ ++ ++" Section: Compiler {{{1 ++" ++if ! exists("g:ada_default_compiler") ++ if has("vms") ++ let g:ada_default_compiler = 'decada' ++ else ++ let g:ada_default_compiler = 'gnat' ++ endif ++endif ++ ++if ! exists("current_compiler") || ++ \ current_compiler != g:ada_default_compiler ++ execute "compiler " . g:ada_default_compiler ++endif ++ ++" Section: Folding {{{1 ++" ++if exists("g:ada_folding") ++ if g:ada_folding[0] == 'i' ++ setlocal foldmethod=indent ++ setlocal foldignore=-- ++ setlocal foldnestmax=5 ++ elseif g:ada_folding[0] == 'g' ++ setlocal foldmethod=expr ++ setlocal foldexpr=ada#Pretty_Print_Folding(v:lnum) ++ elseif g:ada_folding[0] == 's' ++ setlocal foldmethod=syntax ++ endif ++ setlocal tabstop=8 ++ setlocal softtabstop=3 ++ setlocal shiftwidth=3 ++endif ++ ++" Section: Abbrev {{{1 ++" ++if exists("g:ada_abbrev") ++ iabbrev ret return ++ iabbrev proc procedure ++ iabbrev pack package ++ iabbrev func function ++endif ++ ++" Section: Commands, Mapping, Menus {{{1 ++" ++call ada#Map_Popup ( ++ \ 'Tag.List', ++ \ 'l', ++ \ 'call ada#List_Tag ()') ++call ada#Map_Popup ( ++ \'Tag.Jump', ++ \'j', ++ \'call ada#Jump_Tag ()') ++call ada#Map_Menu ( ++ \'Tag.Create File', ++ \':AdaTagFile', ++ \'call ada#Create_Tags (''file'')') ++call ada#Map_Menu ( ++ \'Tag.Create Dir', ++ \':AdaTagDir', ++ \'call ada#Create_Tags (''dir'')') ++ ++call ada#Map_Menu ( ++ \'Highlight.Toggle Space Errors', ++ \ ':AdaSpaces', ++ \'call ada#Switch_Syntax_Option (''space_errors'')') ++call ada#Map_Menu ( ++ \'Highlight.Toggle Lines Errors', ++ \ ':AdaLines', ++ \'call ada#Switch_Syntax_Option (''line_errors'')') ++call ada#Map_Menu ( ++ \'Highlight.Toggle Rainbow Color', ++ \ ':AdaRainbow', ++ \'call ada#Switch_Syntax_Option (''rainbow_color'')') ++call ada#Map_Menu ( ++ \'Highlight.Toggle Standard Types', ++ \ ':AdaTypes', ++ \'call ada#Switch_Syntax_Option (''standard_types'')') ++ ++" 1}}} ++" Reset cpoptions ++let &cpoptions = s:cpoptions ++unlet s:cpoptions ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/ftplugin/.svn/all-wcprops vim71_ada/1/ftplugin/.svn/all-wcprops +--- vim71/1/ftplugin/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftplugin/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,11 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 53 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/ftplugin ++END ++ada.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 61 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/ftplugin/ada.vim ++END +diff -urN vim71/1/ftplugin/.svn/dir-prop-base vim71_ada/1/ftplugin/.svn/dir-prop-base +--- vim71/1/ftplugin/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftplugin/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/ftplugin/.svn/entries vim71_ada/1/ftplugin/.svn/entries +--- vim71/1/ftplugin/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftplugin/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,41 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ftplugin ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++ada.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++271552b843be34dd99efdb2e180aa4ec ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ +diff -urN vim71/1/ftplugin/.svn/format vim71_ada/1/ftplugin/.svn/format +--- vim71/1/ftplugin/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftplugin/.svn/format 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/ftplugin/.svn/prop-base/ada.vim.svn-base vim71_ada/1/ftplugin/.svn/prop-base/ada.vim.svn-base +--- vim71/1/ftplugin/.svn/prop-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftplugin/.svn/prop-base/ada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/ftplugin/.svn/text-base/ada.vim.svn-base vim71_ada/1/ftplugin/.svn/text-base/ada.vim.svn-base +--- vim71/1/ftplugin/.svn/text-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/ftplugin/.svn/text-base/ada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,201 @@ ++"------------------------------------------------------------------------------ ++" Description: Perform Ada specific completion & tagging. ++" Language: Ada (2005) ++" $Id$ ++" Maintainer: Martin Krischik ++" Taylor Venable ++" Neil Bird ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK ' should not be in iskeyword. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Better folding. ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested not to use include protection for ++" autoload ++" 05.11.2006 MK Bram suggested to save on spaces ++" 08.07.2007 TV fix default compiler problems. ++" Help Page: ft-ada-plugin ++"------------------------------------------------------------------------------ ++" Provides mapping overrides for tag jumping that figure out the current ++" Ada object and tag jump to that, not the 'simple' vim word. ++" Similarly allows matching of full-length ada entities from tags. ++"------------------------------------------------------------------------------ ++ ++" Only do this when not done yet for this buffer ++if exists ("b:did_ftplugin") || version < 700 ++ finish ++endif ++ ++" Don't load another plugin for this buffer ++let b:did_ftplugin = 45 ++ ++" ++" Temporarily set cpoptions to ensure the script loads OK ++" ++let s:cpoptions = &cpoptions ++set cpoptions-=C ++ ++" Section: Comments {{{1 ++" ++setlocal comments=O:--,:--\ \ ++setlocal commentstring=--\ \ %s ++setlocal complete=.,w,b,u,t,i ++ ++" Section: Tagging {{{1 ++" ++if exists ("g:ada_extended_tagging") ++ " Make local tag mappings for this buffer (if not already set) ++ if g:ada_extended_tagging == 'jump' ++ if mapcheck('','n') == '' ++ nnoremap :call ada#Jump_Tag ('', 'tjump') ++ endif ++ if mapcheck('g','n') == '' ++ nnoremap g :call ada#Jump_Tag ('','stjump') ++ endif ++ elseif g:ada_extended_tagging == 'list' ++ if mapcheck('','n') == '' ++ nnoremap :call ada#List_Tag () ++ endif ++ if mapcheck('g','n') == '' ++ nnoremap g :call ada#List_Tag () ++ endif ++ endif ++endif ++ ++" Section: Completion {{{1 ++" ++setlocal completefunc=ada#User_Complete ++setlocal omnifunc=adacomplete#Complete ++ ++if exists ("g:ada_extended_completion") ++ if mapcheck ('','i') == '' ++ inoremap =ada#Completion("\C-N>") ++ endif ++ if mapcheck ('','i') == '' ++ inoremap =ada#Completion("\C-P>") ++ endif ++ if mapcheck ('','i') == '' ++ inoremap =ada#Completion("\C-X>\C-]>") ++ endif ++ if mapcheck ('','i') == '' ++ inoremap =ada#Insert_Backspace () ++ endif ++endif ++ ++" Section: Matchit {{{1 ++" ++" Only do this when not done yet for this buffer & matchit is used ++" ++if !exists ("b:match_words") && ++ \ exists ("loaded_matchit") ++ " ++ " The following lines enable the macros/matchit.vim plugin for ++ " Ada-specific extended matching with the % key. ++ " ++ let s:notend = '\%(\:\:\:\\s\+\,' . ++ \ s:notend . '\:\:\\s\+\,' . ++ \ '\%(\.*\|\.*\|'.s:notend.'\)\:\\s\+\,' . ++ \ '\%(\\|\\):\:\\s*\%($\|[;A-Z]\),' . ++ \ s:notend . '\:\\s\+\' ++endif ++ ++ ++" Section: Compiler {{{1 ++" ++if ! exists("g:ada_default_compiler") ++ if has("vms") ++ let g:ada_default_compiler = 'decada' ++ else ++ let g:ada_default_compiler = 'gnat' ++ endif ++endif ++ ++if ! exists("current_compiler") || ++ \ current_compiler != g:ada_default_compiler ++ execute "compiler " . g:ada_default_compiler ++endif ++ ++" Section: Folding {{{1 ++" ++if exists("g:ada_folding") ++ if g:ada_folding[0] == 'i' ++ setlocal foldmethod=indent ++ setlocal foldignore=-- ++ setlocal foldnestmax=5 ++ elseif g:ada_folding[0] == 'g' ++ setlocal foldmethod=expr ++ setlocal foldexpr=ada#Pretty_Print_Folding(v:lnum) ++ elseif g:ada_folding[0] == 's' ++ setlocal foldmethod=syntax ++ endif ++ setlocal tabstop=8 ++ setlocal softtabstop=3 ++ setlocal shiftwidth=3 ++endif ++ ++" Section: Abbrev {{{1 ++" ++if exists("g:ada_abbrev") ++ iabbrev ret return ++ iabbrev proc procedure ++ iabbrev pack package ++ iabbrev func function ++endif ++ ++" Section: Commands, Mapping, Menus {{{1 ++" ++call ada#Map_Popup ( ++ \ 'Tag.List', ++ \ 'l', ++ \ 'call ada#List_Tag ()') ++call ada#Map_Popup ( ++ \'Tag.Jump', ++ \'j', ++ \'call ada#Jump_Tag ()') ++call ada#Map_Menu ( ++ \'Tag.Create File', ++ \':AdaTagFile', ++ \'call ada#Create_Tags (''file'')') ++call ada#Map_Menu ( ++ \'Tag.Create Dir', ++ \':AdaTagDir', ++ \'call ada#Create_Tags (''dir'')') ++ ++call ada#Map_Menu ( ++ \'Highlight.Toggle Space Errors', ++ \ ':AdaSpaces', ++ \'call ada#Switch_Syntax_Option (''space_errors'')') ++call ada#Map_Menu ( ++ \'Highlight.Toggle Lines Errors', ++ \ ':AdaLines', ++ \'call ada#Switch_Syntax_Option (''line_errors'')') ++call ada#Map_Menu ( ++ \'Highlight.Toggle Rainbow Color', ++ \ ':AdaRainbow', ++ \'call ada#Switch_Syntax_Option (''rainbow_color'')') ++call ada#Map_Menu ( ++ \'Highlight.Toggle Standard Types', ++ \ ':AdaTypes', ++ \'call ada#Switch_Syntax_Option (''standard_types'')') ++ ++" 1}}} ++" Reset cpoptions ++let &cpoptions = s:cpoptions ++unlet s:cpoptions ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/indent/ada.vim vim71_ada/1/indent/ada.vim +--- vim71/1/indent/ada.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/indent/ada.vim 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,303 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada indent file ++" Language: Ada (2005) ++" $Id: ada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" Neil Bird ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/indent/ada.vim $ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested to save on spaces ++" 19.09.2007 NO g: missing before ada#Comment ++" Help Page: ft-vim-indent ++"------------------------------------------------------------------------------ ++" ToDo: ++" Verify handling of multi-line exprs. and recovery upon the final ';'. ++" Correctly find comments given '"' and "" ==> " syntax. ++" Combine the two large block-indent functions into one? ++"------------------------------------------------------------------------------ ++ ++" Only load this indent file when no other was loaded. ++if exists("b:did_indent") || version < 700 ++ finish ++endif ++ ++let b:did_indent = 45 ++ ++setlocal indentexpr=GetAdaIndent() ++setlocal indentkeys-=0{,0} ++setlocal indentkeys+=0=~then,0=~end,0=~elsif,0=~when,0=~exception,0=~begin,0=~is,0=~record ++ ++" Only define the functions once. ++if exists("*GetAdaIndent") ++ finish ++endif ++ ++if exists("g:ada_with_gnat_project_files") ++ let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\[^;]*$\|\(type\>.*\)\=\\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|project\>\|then\>\|when\>\|is\>\)' ++else ++ let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\[^;]*$\|\(type\>.*\)\=\\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|then\>\|when\>\|is\>\)' ++endif ++ ++" Section: s:MainBlockIndent {{{1 ++" ++" Try to find indent of the block we're in ++" prev_indent = the previous line's indent ++" prev_lnum = previous line (to start looking on) ++" blockstart = expr. that indicates a possible start of this block ++" stop_at = if non-null, if a matching line is found, gives up! ++" No recursive previous block analysis: simply look for a valid line ++" with a lesser or equal indent than we currently (on prev_lnum) have. ++" This shouldn't work as well as it appears to with lines that are currently ++" nowhere near the correct indent (e.g., start of line)! ++" Seems to work OK as it 'starts' with the indent of the /previous/ line. ++function s:MainBlockIndent (prev_indent, prev_lnum, blockstart, stop_at) ++ let lnum = a:prev_lnum ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ while lnum > 1 ++ if a:stop_at != '' && line =~ '^\s*' . a:stop_at && indent(lnum) < a:prev_indent ++ return a:prev_indent ++ elseif line =~ '^\s*' . a:blockstart ++ let ind = indent(lnum) ++ if ind < a:prev_indent ++ return ind ++ endif ++ endif ++ ++ let lnum = prevnonblank(lnum - 1) ++ " Get previous non-blank/non-comment-only line ++ while 1 ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ if line !~ '^\s*$' && line !~ '^\s*#' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return a:prev_indent ++ endif ++ endwhile ++ endwhile ++ " Fallback - just move back one ++ return a:prev_indent - &sw ++endfunction MainBlockIndent ++ ++" Section: s:EndBlockIndent {{{1 ++" ++" Try to find indent of the block we're in (and about to complete), ++" including handling of nested blocks. Works on the 'end' of a block. ++" prev_indent = the previous line's indent ++" prev_lnum = previous line (to start looking on) ++" blockstart = expr. that indicates a possible start of this block ++" blockend = expr. that indicates a possible end of this block ++function s:EndBlockIndent( prev_indent, prev_lnum, blockstart, blockend ) ++ let lnum = a:prev_lnum ++ let line = getline(lnum) ++ let ends = 0 ++ while lnum > 1 ++ if getline(lnum) =~ '^\s*' . a:blockstart ++ let ind = indent(lnum) ++ if ends <= 0 ++ if ind < a:prev_indent ++ return ind ++ endif ++ else ++ let ends = ends - 1 ++ endif ++ elseif getline(lnum) =~ '^\s*' . a:blockend ++ let ends = ends + 1 ++ endif ++ ++ let lnum = prevnonblank(lnum - 1) ++ " Get previous non-blank/non-comment-only line ++ while 1 ++ let line = getline(lnum) ++ let line = substitute( line, g:ada#Comment, '', '' ) ++ if line !~ '^\s*$' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return a:prev_indent ++ endif ++ endwhile ++ endwhile ++ " Fallback - just move back one ++ return a:prev_indent - &sw ++endfunction EndBlockIndent ++ ++" Section: s:StatementIndent {{{1 ++" ++" Return indent of previous statement-start ++" (after we've indented due to multi-line statements). ++" This time, we start searching on the line *before* the one given (which is ++" the end of a statement - we want the previous beginning). ++function s:StatementIndent( current_indent, prev_lnum ) ++ let lnum = a:prev_lnum ++ while lnum > 0 ++ let prev_lnum = lnum ++ let lnum = prevnonblank(lnum - 1) ++ " Get previous non-blank/non-comment-only line ++ while 1 ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ ++ if line !~ '^\s*$' && line !~ '^\s*#' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return a:current_indent ++ endif ++ endwhile ++ " Leave indent alone if our ';' line is part of a ';'-delineated ++ " aggregate (e.g., procedure args.) or first line after a block start. ++ if line =~ s:AdaBlockStart || line =~ '(\s*$' ++ return a:current_indent ++ endif ++ if line !~ '[.=(]\s*$' ++ let ind = indent(prev_lnum) ++ if ind < a:current_indent ++ return ind ++ endif ++ endif ++ endwhile ++ " Fallback - just use current one ++ return a:current_indent ++endfunction StatementIndent ++ ++ ++" Section: GetAdaIndent {{{1 ++" ++" Find correct indent of a new line based upon what went before ++" ++function GetAdaIndent() ++ " Find a non-blank line above the current line. ++ let lnum = prevnonblank(v:lnum - 1) ++ let ind = indent(lnum) ++ let package_line = 0 ++ ++ " Get previous non-blank/non-comment-only/non-cpp line ++ while 1 ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ if line !~ '^\s*$' && line !~ '^\s*#' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return ind ++ endif ++ endwhile ++ ++ " Get default indent (from prev. line) ++ let ind = indent(lnum) ++ let initind = ind ++ ++ " Now check what's on the previous line ++ if line =~ s:AdaBlockStart || line =~ '(\s*$' ++ " Check for false matches to AdaBlockStart ++ let false_match = 0 ++ if line =~ '^\s*\(procedure\|function\|package\)\>.*\' ++ " Generic instantiation ++ let false_match = 1 ++ elseif line =~ ')\s*;\s*$' || line =~ '^\([^(]*([^)]*)\)*[^(]*;\s*$' ++ " forward declaration ++ let false_match = 1 ++ endif ++ " Move indent in ++ if ! false_match ++ let ind = ind + &sw ++ endif ++ elseif line =~ '^\s*\(case\|exception\)\>' ++ " Move indent in twice (next 'when' will move back) ++ let ind = ind + 2 * &sw ++ elseif line =~ '^\s*end\s*record\>' ++ " Move indent back to tallying 'type' preceeding the 'record'. ++ " Allow indent to be equal to 'end record's. ++ let ind = s:MainBlockIndent( ind+&sw, lnum, 'type\>', '' ) ++ elseif line =~ '\(^\s*new\>.*\)\@' ++ " Multiple line generic instantiation ('package blah is\nnew thingy') ++ let ind = s:StatementIndent( ind - &sw, lnum ) ++ elseif line =~ ';\s*$' ++ " Statement end (but not 'end' ) - try to find current statement-start indent ++ let ind = s:StatementIndent( ind, lnum ) ++ endif ++ ++ " Check for potential argument list on next line ++ let continuation = (line =~ '[A-Za-z0-9_]\s*$') ++ ++ ++ " Check current line; search for simplistic matching start-of-block ++ let line = getline(v:lnum) ++ if line =~ '^\s*#' ++ " Start of line for ada-pp ++ let ind = 0 ++ elseif continuation && line =~ '^\s*(' ++ " Don't do this if we've already indented due to the previous line ++ if ind == initind ++ let ind = ind + &sw ++ endif ++ elseif line =~ '^\s*\(begin\|is\)\>' ++ let ind = s:MainBlockIndent( ind, lnum, '\(procedure\|function\|declare\|package\|task\)\>', 'begin\>' ) ++ elseif line =~ '^\s*record\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'type\>\|for\>.*\', '' ) + &sw ++ elseif line =~ '^\s*\(else\|elsif\)\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' ) ++ elseif line =~ '^\s*when\>' ++ " Align 'when' one /in/ from matching block start ++ let ind = s:MainBlockIndent( ind, lnum, '\(case\|exception\)\>', '' ) + &sw ++ elseif line =~ '^\s*end\>\s*\' ++ " End of if statements ++ let ind = s:EndBlockIndent( ind, lnum, 'if\>', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of loops ++ let ind = s:EndBlockIndent( ind, lnum, '\(\(while\|for\)\>.*\)\?\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of records ++ let ind = s:EndBlockIndent( ind, lnum, '\(type\>.*\)\=\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of procedures ++ let ind = s:EndBlockIndent( ind, lnum, 'procedure\>.*\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of case statement ++ let ind = s:EndBlockIndent( ind, lnum, 'case\>.*\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>' ++ " General case for end ++ let ind = s:MainBlockIndent( ind, lnum, '\(if\|while\|for\|loop\|accept\|begin\|record\|case\|exception\|package\)\>', '' ) ++ elseif line =~ '^\s*exception\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'begin\>', '' ) ++ elseif line =~ '^\s*then\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' ) ++ endif ++ ++ return ind ++endfunction GetAdaIndent ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/indent/.svn/all-wcprops vim71_ada/1/indent/.svn/all-wcprops +--- vim71/1/indent/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/indent/.svn/all-wcprops 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,11 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 51 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/indent ++END ++ada.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 59 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/indent/ada.vim ++END +diff -urN vim71/1/indent/.svn/dir-prop-base vim71_ada/1/indent/.svn/dir-prop-base +--- vim71/1/indent/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/indent/.svn/dir-prop-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/indent/.svn/entries vim71_ada/1/indent/.svn/entries +--- vim71/1/indent/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/indent/.svn/entries 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,41 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/indent ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++ada.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:02.000000Z ++0c3e48d95515e29fbb4a8bef5d6d97dc ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ +diff -urN vim71/1/indent/.svn/format vim71_ada/1/indent/.svn/format +--- vim71/1/indent/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/indent/.svn/format 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/indent/.svn/prop-base/ada.vim.svn-base vim71_ada/1/indent/.svn/prop-base/ada.vim.svn-base +--- vim71/1/indent/.svn/prop-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/indent/.svn/prop-base/ada.vim.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/indent/.svn/text-base/ada.vim.svn-base vim71_ada/1/indent/.svn/text-base/ada.vim.svn-base +--- vim71/1/indent/.svn/text-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/indent/.svn/text-base/ada.vim.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,303 @@ ++"------------------------------------------------------------------------------ ++" Description: Vim Ada indent file ++" Language: Ada (2005) ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" Neil Bird ++" Ned Okie ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested to save on spaces ++" 19.09.2007 NO g: missing before ada#Comment ++" Help Page: ft-vim-indent ++"------------------------------------------------------------------------------ ++" ToDo: ++" Verify handling of multi-line exprs. and recovery upon the final ';'. ++" Correctly find comments given '"' and "" ==> " syntax. ++" Combine the two large block-indent functions into one? ++"------------------------------------------------------------------------------ ++ ++" Only load this indent file when no other was loaded. ++if exists("b:did_indent") || version < 700 ++ finish ++endif ++ ++let b:did_indent = 45 ++ ++setlocal indentexpr=GetAdaIndent() ++setlocal indentkeys-=0{,0} ++setlocal indentkeys+=0=~then,0=~end,0=~elsif,0=~when,0=~exception,0=~begin,0=~is,0=~record ++ ++" Only define the functions once. ++if exists("*GetAdaIndent") ++ finish ++endif ++ ++if exists("g:ada_with_gnat_project_files") ++ let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\[^;]*$\|\(type\>.*\)\=\\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|project\>\|then\>\|when\>\|is\>\)' ++else ++ let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\[^;]*$\|\(type\>.*\)\=\\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|then\>\|when\>\|is\>\)' ++endif ++ ++" Section: s:MainBlockIndent {{{1 ++" ++" Try to find indent of the block we're in ++" prev_indent = the previous line's indent ++" prev_lnum = previous line (to start looking on) ++" blockstart = expr. that indicates a possible start of this block ++" stop_at = if non-null, if a matching line is found, gives up! ++" No recursive previous block analysis: simply look for a valid line ++" with a lesser or equal indent than we currently (on prev_lnum) have. ++" This shouldn't work as well as it appears to with lines that are currently ++" nowhere near the correct indent (e.g., start of line)! ++" Seems to work OK as it 'starts' with the indent of the /previous/ line. ++function s:MainBlockIndent (prev_indent, prev_lnum, blockstart, stop_at) ++ let lnum = a:prev_lnum ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ while lnum > 1 ++ if a:stop_at != '' && line =~ '^\s*' . a:stop_at && indent(lnum) < a:prev_indent ++ return a:prev_indent ++ elseif line =~ '^\s*' . a:blockstart ++ let ind = indent(lnum) ++ if ind < a:prev_indent ++ return ind ++ endif ++ endif ++ ++ let lnum = prevnonblank(lnum - 1) ++ " Get previous non-blank/non-comment-only line ++ while 1 ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ if line !~ '^\s*$' && line !~ '^\s*#' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return a:prev_indent ++ endif ++ endwhile ++ endwhile ++ " Fallback - just move back one ++ return a:prev_indent - &sw ++endfunction MainBlockIndent ++ ++" Section: s:EndBlockIndent {{{1 ++" ++" Try to find indent of the block we're in (and about to complete), ++" including handling of nested blocks. Works on the 'end' of a block. ++" prev_indent = the previous line's indent ++" prev_lnum = previous line (to start looking on) ++" blockstart = expr. that indicates a possible start of this block ++" blockend = expr. that indicates a possible end of this block ++function s:EndBlockIndent( prev_indent, prev_lnum, blockstart, blockend ) ++ let lnum = a:prev_lnum ++ let line = getline(lnum) ++ let ends = 0 ++ while lnum > 1 ++ if getline(lnum) =~ '^\s*' . a:blockstart ++ let ind = indent(lnum) ++ if ends <= 0 ++ if ind < a:prev_indent ++ return ind ++ endif ++ else ++ let ends = ends - 1 ++ endif ++ elseif getline(lnum) =~ '^\s*' . a:blockend ++ let ends = ends + 1 ++ endif ++ ++ let lnum = prevnonblank(lnum - 1) ++ " Get previous non-blank/non-comment-only line ++ while 1 ++ let line = getline(lnum) ++ let line = substitute( line, g:ada#Comment, '', '' ) ++ if line !~ '^\s*$' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return a:prev_indent ++ endif ++ endwhile ++ endwhile ++ " Fallback - just move back one ++ return a:prev_indent - &sw ++endfunction EndBlockIndent ++ ++" Section: s:StatementIndent {{{1 ++" ++" Return indent of previous statement-start ++" (after we've indented due to multi-line statements). ++" This time, we start searching on the line *before* the one given (which is ++" the end of a statement - we want the previous beginning). ++function s:StatementIndent( current_indent, prev_lnum ) ++ let lnum = a:prev_lnum ++ while lnum > 0 ++ let prev_lnum = lnum ++ let lnum = prevnonblank(lnum - 1) ++ " Get previous non-blank/non-comment-only line ++ while 1 ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ ++ if line !~ '^\s*$' && line !~ '^\s*#' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return a:current_indent ++ endif ++ endwhile ++ " Leave indent alone if our ';' line is part of a ';'-delineated ++ " aggregate (e.g., procedure args.) or first line after a block start. ++ if line =~ s:AdaBlockStart || line =~ '(\s*$' ++ return a:current_indent ++ endif ++ if line !~ '[.=(]\s*$' ++ let ind = indent(prev_lnum) ++ if ind < a:current_indent ++ return ind ++ endif ++ endif ++ endwhile ++ " Fallback - just use current one ++ return a:current_indent ++endfunction StatementIndent ++ ++ ++" Section: GetAdaIndent {{{1 ++" ++" Find correct indent of a new line based upon what went before ++" ++function GetAdaIndent() ++ " Find a non-blank line above the current line. ++ let lnum = prevnonblank(v:lnum - 1) ++ let ind = indent(lnum) ++ let package_line = 0 ++ ++ " Get previous non-blank/non-comment-only/non-cpp line ++ while 1 ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ if line !~ '^\s*$' && line !~ '^\s*#' ++ break ++ endif ++ let lnum = prevnonblank(lnum - 1) ++ if lnum <= 0 ++ return ind ++ endif ++ endwhile ++ ++ " Get default indent (from prev. line) ++ let ind = indent(lnum) ++ let initind = ind ++ ++ " Now check what's on the previous line ++ if line =~ s:AdaBlockStart || line =~ '(\s*$' ++ " Check for false matches to AdaBlockStart ++ let false_match = 0 ++ if line =~ '^\s*\(procedure\|function\|package\)\>.*\' ++ " Generic instantiation ++ let false_match = 1 ++ elseif line =~ ')\s*;\s*$' || line =~ '^\([^(]*([^)]*)\)*[^(]*;\s*$' ++ " forward declaration ++ let false_match = 1 ++ endif ++ " Move indent in ++ if ! false_match ++ let ind = ind + &sw ++ endif ++ elseif line =~ '^\s*\(case\|exception\)\>' ++ " Move indent in twice (next 'when' will move back) ++ let ind = ind + 2 * &sw ++ elseif line =~ '^\s*end\s*record\>' ++ " Move indent back to tallying 'type' preceeding the 'record'. ++ " Allow indent to be equal to 'end record's. ++ let ind = s:MainBlockIndent( ind+&sw, lnum, 'type\>', '' ) ++ elseif line =~ '\(^\s*new\>.*\)\@' ++ " Multiple line generic instantiation ('package blah is\nnew thingy') ++ let ind = s:StatementIndent( ind - &sw, lnum ) ++ elseif line =~ ';\s*$' ++ " Statement end (but not 'end' ) - try to find current statement-start indent ++ let ind = s:StatementIndent( ind, lnum ) ++ endif ++ ++ " Check for potential argument list on next line ++ let continuation = (line =~ '[A-Za-z0-9_]\s*$') ++ ++ ++ " Check current line; search for simplistic matching start-of-block ++ let line = getline(v:lnum) ++ if line =~ '^\s*#' ++ " Start of line for ada-pp ++ let ind = 0 ++ elseif continuation && line =~ '^\s*(' ++ " Don't do this if we've already indented due to the previous line ++ if ind == initind ++ let ind = ind + &sw ++ endif ++ elseif line =~ '^\s*\(begin\|is\)\>' ++ let ind = s:MainBlockIndent( ind, lnum, '\(procedure\|function\|declare\|package\|task\)\>', 'begin\>' ) ++ elseif line =~ '^\s*record\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'type\>\|for\>.*\', '' ) + &sw ++ elseif line =~ '^\s*\(else\|elsif\)\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' ) ++ elseif line =~ '^\s*when\>' ++ " Align 'when' one /in/ from matching block start ++ let ind = s:MainBlockIndent( ind, lnum, '\(case\|exception\)\>', '' ) + &sw ++ elseif line =~ '^\s*end\>\s*\' ++ " End of if statements ++ let ind = s:EndBlockIndent( ind, lnum, 'if\>', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of loops ++ let ind = s:EndBlockIndent( ind, lnum, '\(\(while\|for\)\>.*\)\?\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of records ++ let ind = s:EndBlockIndent( ind, lnum, '\(type\>.*\)\=\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of procedures ++ let ind = s:EndBlockIndent( ind, lnum, 'procedure\>.*\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>\s*\' ++ " End of case statement ++ let ind = s:EndBlockIndent( ind, lnum, 'case\>.*\', 'end\>\s*\' ) ++ elseif line =~ '^\s*end\>' ++ " General case for end ++ let ind = s:MainBlockIndent( ind, lnum, '\(if\|while\|for\|loop\|accept\|begin\|record\|case\|exception\|package\)\>', '' ) ++ elseif line =~ '^\s*exception\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'begin\>', '' ) ++ elseif line =~ '^\s*then\>' ++ let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' ) ++ endif ++ ++ return ind ++endfunction GetAdaIndent ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: foldmethod=marker +diff -urN vim71/1/macros/.svn/all-wcprops vim71_ada/1/macros/.svn/all-wcprops +--- vim71/1/macros/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/all-wcprops 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,35 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 51 ++/svnroot/gnuada/!svn/ver/820/trunk/tools/vim/macros ++END ++svnignore.bash ++K 25 ++svn:wc:ra_dav:version-url ++V 66 ++/svnroot/gnuada/!svn/ver/467/trunk/tools/vim/macros/svnignore.bash ++END ++vim.bash ++K 25 ++svn:wc:ra_dav:version-url ++V 60 ++/svnroot/gnuada/!svn/ver/820/trunk/tools/vim/macros/vim.bash ++END ++svnignore.btm ++K 25 ++svn:wc:ra_dav:version-url ++V 65 ++/svnroot/gnuada/!svn/ver/806/trunk/tools/vim/macros/svnignore.btm ++END ++svnignore.zsh ++K 25 ++svn:wc:ra_dav:version-url ++V 65 ++/svnroot/gnuada/!svn/ver/818/trunk/tools/vim/macros/svnignore.zsh ++END ++vim.zsh ++K 25 ++svn:wc:ra_dav:version-url ++V 59 ++/svnroot/gnuada/!svn/ver/820/trunk/tools/vim/macros/vim.zsh ++END +diff -urN vim71/1/macros/.svn/dir-prop-base vim71_ada/1/macros/.svn/dir-prop-base +--- vim71/1/macros/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/dir-prop-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/macros/.svn/entries vim71_ada/1/macros/.svn/entries +--- vim71/1/macros/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/entries 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,93 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/macros ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-12-08T11:05:30.504500Z ++820 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++svnignore.bash ++file ++ ++ ++ ++ ++2008-01-16T15:37:02.000000Z ++c642481322f646fd974e97b84ada8dd1 ++2006-11-23T19:22:39.181709Z ++467 ++krischik ++has-props ++ ++vim.bash ++file ++ ++ ++ ++ ++2008-01-16T15:37:02.000000Z ++b727d059d581444336f20c5a98cb38f4 ++2007-12-08T11:05:30.504500Z ++820 ++krischik ++has-props ++ ++svnignore.btm ++file ++ ++ ++ ++ ++2008-01-16T15:37:02.000000Z ++d80c852daa65bf28d8e6f77aa176dcf5 ++2007-11-21T09:35:26.131421Z ++806 ++krischik ++has-props ++ ++svnignore.zsh ++file ++ ++ ++ ++ ++2008-01-16T15:37:02.000000Z ++6eea8120eb524add32e145b4ae2fcd78 ++2007-12-03T21:21:48.223203Z ++818 ++krischik ++has-props ++ ++vim.zsh ++file ++ ++ ++ ++ ++2008-01-16T15:37:02.000000Z ++07a5ffc95ea930774810e3d04144cbff ++2007-12-08T11:05:30.504500Z ++820 ++krischik ++has-props ++ +diff -urN vim71/1/macros/.svn/format vim71_ada/1/macros/.svn/format +--- vim71/1/macros/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/format 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/macros/.svn/prop-base/svnignore.bash.svn-base vim71_ada/1/macros/.svn/prop-base/svnignore.bash.svn-base +--- vim71/1/macros/.svn/prop-base/svnignore.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/prop-base/svnignore.bash.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/macros/.svn/prop-base/svnignore.btm.svn-base vim71_ada/1/macros/.svn/prop-base/svnignore.btm.svn-base +--- vim71/1/macros/.svn/prop-base/svnignore.btm.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/prop-base/svnignore.btm.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 15 ++text/x-dosbatch ++END +diff -urN vim71/1/macros/.svn/prop-base/svnignore.zsh.svn-base vim71_ada/1/macros/.svn/prop-base/svnignore.zsh.svn-base +--- vim71/1/macros/.svn/prop-base/svnignore.zsh.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/prop-base/svnignore.zsh.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/macros/.svn/prop-base/vim.bash.svn-base vim71_ada/1/macros/.svn/prop-base/vim.bash.svn-base +--- vim71/1/macros/.svn/prop-base/vim.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/prop-base/vim.bash.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/macros/.svn/prop-base/vim.zsh.svn-base vim71_ada/1/macros/.svn/prop-base/vim.zsh.svn-base +--- vim71/1/macros/.svn/prop-base/vim.zsh.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/prop-base/vim.zsh.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/macros/.svn/text-base/svnignore.bash.svn-base vim71_ada/1/macros/.svn/text-base/svnignore.bash.svn-base +--- vim71/1/macros/.svn/text-base/svnignore.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/text-base/svnignore.bash.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,9 @@ ++#!/bin/bash ++ ++svn propedit \ ++ --editor-cmd="gvim -f" \ ++ svn:ignore \ ++ "${@}" ; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/macros/.svn/text-base/svnignore.btm.svn-base vim71_ada/1/macros/.svn/text-base/svnignore.btm.svn-base +--- vim71/1/macros/.svn/text-base/svnignore.btm.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/text-base/svnignore.btm.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,27 @@ ++::!C:\Bin\4Portable\App\4\4nt.EXE ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: Description: Works like "tail -f" . ++:: $Id$ ++:: Maintainer: Martin Krischik ++:: Jason Heddings (vim at heddway dot com) ++:: $Author$ ++:: $Date$ ++:: Version: 3.0 ++:: $Revision$ ++:: $HeadURL$ ++:: History: 17.11.2007 Edit svn:ignore data ++:: Help Page: tail.txt ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++ ++svn propedit ^ ++ --editor-cmd="gvim -f" ^ ++ svn:ignore ^ ++ "%[$]" ++ ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: Copyright (C) 2006 Martin Krischik ++:: ++:: Vim is Charityware - see ":help license" or uganda.txt for licence details. ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++:: vim: filetype=btm encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/macros/.svn/text-base/svnignore.zsh.svn-base vim71_ada/1/macros/.svn/text-base/svnignore.zsh.svn-base +--- vim71/1/macros/.svn/text-base/svnignore.zsh.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/text-base/svnignore.zsh.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,29 @@ ++#!/bin/zsh ++#------------------------------------------------------------------------------ ++# Description: Works like "tail -f" . ++# $Id$ ++# Maintainer: Martin Krischik ++# Jason Heddings (vim at heddway dot com) ++# $Author$ ++# $Date$ ++# Version: 3.0 ++# $Revision$ ++# $HeadURL$ ++# History: 17.11.2007 Edit svn:ignore data ++# Help Page: tail.txt ++#------------------------------------------------------------------------------ ++ ++setopt No_X_Trace; ++ ++svn propedit \ ++ --editor-cmd="gvim -f" \ ++ svn:ignore \ ++ "${=@}" ; ++ ++#------------------------------------------------------------------------------ ++# Copyright (C) 2006 Martin Krischik ++# ++# Vim is Charityware - see ":help license" or uganda.txt for licence details. ++#------------------------------------------------------------------------------ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/macros/.svn/text-base/vim.bash.svn-base vim71_ada/1/macros/.svn/text-base/vim.bash.svn-base +--- vim71/1/macros/.svn/text-base/vim.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/text-base/vim.bash.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,191 @@ ++#!/bin/echo usage: source ++########################################################### {{{1 ########### ++# Description: Set alias names for a custom installed vim/ctags. ++# Language: Bash Shell Script ++# $Id$ ++# Maintainer: Martin Krischik ++# $Author$ ++# $Date$ ++# Version: 3.6 ++# $Revision$ ++# $HeadURL$ ++# History: 26.07.2006 MK pretty new ++# Usage: copy to /etc/profile.d and make world executable ++########################################################### }}}1 ########### ++ ++ ++if ! type lxpm 2>/dev/null 1>/dev/null; then ++ ++ # Variablen ++ UName=$(uname) ++ ++ case "${UName}" in # {{{1 ++ (Linux*) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71"; ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}2 ++ (CYGWIN*) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71" ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}2 ++ (SunOS) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71"; ++ elif test -x "${HOME}/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="${HOME}/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71" ++ PATH="${VIM}/bin:${PATH}" ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi ++ ;; # }}}2 ++ (*) # {{{2 ++ ;; # }}}2 ++ esac; # }}}1 ++ ++ # Simple Functions ++ ++ for i in ctags etags eview evim ex gview gvim gvimdiff rgview rgvim rview rvim view vim vimdiff vimtutor xxd; do # {{{1 ++ ++ case "${UName}" in # {{{2 ++ (MINGW*) # {{{3 ++ if test -n "${VIM}"; then ++ declare -x -f ${i}; ++ ++ eval "function ${i} () ++ { ++ ${VIM}/vim71/gvim.exe \"\${@}\" ++ return; ++ }" ++ else ++ unset -f ${i} 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}3 ++ (Linux|CYGWIN*) # {{{3 ++ if test -n "${VIM}"; then ++ declare -x -f ${i}; ++ ++ eval "function ${i} () ++ { ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/${i}\" \"\${@}\" ; ++ return; ++ }" ++ else ++ unset -f ${i} 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}3 ++ (*) # {{{3 ++ ;; # }}}3 ++ esac; # }}}2 ++ done; # }}}1 ++ ++ # Server Functions ++ ++ for i in lxpm med epm; do # {{{1 ++ declare -x -f ${i} ++ ++ case "${UName}" in # {{{2 ++ (MINGW*) # {{{3 ++ if test -n "${VIM}"; then ++ eval "function ${i} () ++ { ++ if test -z "\${1}"; then ++ ${VIM}/vim71/gvim.exe --servername ${i} 1>/dev/null 2>/dev/null & ++ else ++ ${VIM}/vim71/gvim.exe --servername ${i} --remote-silent \"\${@}\" 1>/dev/null 2>/dev/null & ++ fi; ++ return; ++ }" ++ else ++ eval "function ${i} () ++ { ++ if test -z "\${1}"; then ++ gvim.exe --servername ${i} 1>/dev/null 2>/dev/null & ++ else ++ gvim.exe --servername ${i} --remote-silent \"\${@}\" 1>/dev/null 2>/dev/null & ++ fi; ++ return; ++ }" ++ fi; ++ ;; # }}}3 ++ (Linux|CYGWIN*|SunOS) # {{{3 ++ if test -n "${VIM}"; then ++ eval "function ${i} () ++ { ++ if test -z \"\${1}\"; then ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/gvim\" --servername \"${i} ${HOSTNAME}\" \"\${@}\" \ ++ >/dev/null 2>/dev/null & ++ else ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/gvim\" --servername \"${i} ${HOSTNAME}\" --remote-silent \"\${@}\" \ ++ >/dev/null 2>/dev/null & ++ fi ++ return; ++ }" ++ else ++ eval "function ${i} () ++ { ++ if test -z \"\${1}\"; then ++ gvim --servername \"${i} ${HOSTNAME}\" >/dev/null 2>/dev/null & ++ else ++ gvim --servername \"${i} ${HOSTNAME}\" --remote-silent \"\${@}\" >/dev/null 2>/dev/null & ++ fi ++ return; ++ }" ++ fi; ++ ;; # }}}3 ++ (*) # {{{3 ++ ;; # }}}3 ++ esac; # }}}2 ++ done; # }}}1 ++ ++ # Some applications read the EDITOR variable to determine your favourite text ++ # editor. So uncomment the line below and enter the editor of your choice :-) ++ if test -n "${VIM}"; then ++ declare -x EDITOR="${VIM}/bin/gvim -f"; ++ declare -x VISUAL="${VIM}/bin/gvim -f"; ++ else ++ declare -x EDITOR="$(which gvim) -f"; ++ declare -x VISUAL="$(which gvim) -f"; ++ fi; ++ # Unset local Variablen ++ ++ unset UName ++ ++ printf "\e[42m%-30.30s : \e[43m %-40.40s \e[m\n" "$(basename ${BASH_SOURCE:-${0}})" "VIM 7.0 symbols set." ++ ++fi; ++ ++########################################################### {{{1 ########### ++# Copyright (C) 2006 Martin Krischik ++# ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; either version 2 ++# of the License, or (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++########################################################### }}}1 ########### ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix foldmethod=marker +diff -urN vim71/1/macros/.svn/text-base/vim.zsh.svn-base vim71_ada/1/macros/.svn/text-base/vim.zsh.svn-base +--- vim71/1/macros/.svn/text-base/vim.zsh.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/.svn/text-base/vim.zsh.svn-base 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++#!/bin/echo usage: source ++ ++setopt No_Verbose ++setopt No_X_Trace ++setopt Typeset_Silent; ++ ++# ++# Bash script is zsh compatible ++# ++HOSTNAME="${HOSTNAME:-${HOST}}" ++BASH_SOURCE="$(basename ${0} .zsh).bash" ++source "$(dirname ${0})/${BASH_SOURCE}" ++unset BASH_SOURCE; ++ ++############################################################# {{{1 ########### ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/macros/svnignore.bash vim71_ada/1/macros/svnignore.bash +--- vim71/1/macros/svnignore.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/svnignore.bash 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,9 @@ ++#!/bin/bash ++ ++svn propedit \ ++ --editor-cmd="gvim -f" \ ++ svn:ignore \ ++ "${@}" ; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/macros/svnignore.btm vim71_ada/1/macros/svnignore.btm +--- vim71/1/macros/svnignore.btm 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/svnignore.btm 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,27 @@ ++::!C:\Bin\4Portable\App\4\4nt.EXE ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: Description: Works like "tail -f" . ++:: $Id: svnignore.btm 806 2007-11-21 09:35:26Z krischik $ ++:: Maintainer: Martin Krischik ++:: Jason Heddings (vim at heddway dot com) ++:: $Author: krischik $ ++:: $Date: 2007-11-21 10:35:26 +0100 (Mi, 21 Nov 2007) $ ++:: Version: 3.0 ++:: $Revision: 806 $ ++:: $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/macros/svnignore.btm $ ++:: History: 17.11.2007 Edit svn:ignore data ++:: Help Page: tail.txt ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++ ++svn propedit ^ ++ --editor-cmd="gvim -f" ^ ++ svn:ignore ^ ++ "%[$]" ++ ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: Copyright (C) 2006 Martin Krischik ++:: ++:: Vim is Charityware - see ":help license" or uganda.txt for licence details. ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++:: vim: filetype=btm encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/macros/svnignore.zsh vim71_ada/1/macros/svnignore.zsh +--- vim71/1/macros/svnignore.zsh 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/svnignore.zsh 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,29 @@ ++#!/bin/zsh ++#------------------------------------------------------------------------------ ++# Description: Works like "tail -f" . ++# $Id: svnignore.zsh 818 2007-12-03 21:21:48Z krischik $ ++# Maintainer: Martin Krischik ++# Jason Heddings (vim at heddway dot com) ++# $Author: krischik $ ++# $Date: 2007-12-03 22:21:48 +0100 (Mo, 03 Dez 2007) $ ++# Version: 3.0 ++# $Revision: 818 $ ++# $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/macros/svnignore.zsh $ ++# History: 17.11.2007 Edit svn:ignore data ++# Help Page: tail.txt ++#------------------------------------------------------------------------------ ++ ++setopt No_X_Trace; ++ ++svn propedit \ ++ --editor-cmd="gvim -f" \ ++ svn:ignore \ ++ "${=@}" ; ++ ++#------------------------------------------------------------------------------ ++# Copyright (C) 2006 Martin Krischik ++# ++# Vim is Charityware - see ":help license" or uganda.txt for licence details. ++#------------------------------------------------------------------------------ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/macros/vim.bash vim71_ada/1/macros/vim.bash +--- vim71/1/macros/vim.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/vim.bash 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,191 @@ ++#!/bin/echo usage: source ++########################################################### {{{1 ########### ++# Description: Set alias names for a custom installed vim/ctags. ++# Language: Bash Shell Script ++# $Id: vim.bash 820 2007-12-08 11:05:30Z krischik $ ++# Maintainer: Martin Krischik ++# $Author: krischik $ ++# $Date: 2007-12-08 12:05:30 +0100 (Sa, 08 Dez 2007) $ ++# Version: 3.6 ++# $Revision: 820 $ ++# $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/macros/vim.bash $ ++# History: 26.07.2006 MK pretty new ++# Usage: copy to /etc/profile.d and make world executable ++########################################################### }}}1 ########### ++ ++ ++if ! type lxpm 2>/dev/null 1>/dev/null; then ++ ++ # Variablen ++ UName=$(uname) ++ ++ case "${UName}" in # {{{1 ++ (Linux*) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71"; ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}2 ++ (CYGWIN*) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71" ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}2 ++ (SunOS) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71"; ++ elif test -x "${HOME}/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="${HOME}/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71" ++ PATH="${VIM}/bin:${PATH}" ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi ++ ;; # }}}2 ++ (*) # {{{2 ++ ;; # }}}2 ++ esac; # }}}1 ++ ++ # Simple Functions ++ ++ for i in ctags etags eview evim ex gview gvim gvimdiff rgview rgvim rview rvim view vim vimdiff vimtutor xxd; do # {{{1 ++ ++ case "${UName}" in # {{{2 ++ (MINGW*) # {{{3 ++ if test -n "${VIM}"; then ++ declare -x -f ${i}; ++ ++ eval "function ${i} () ++ { ++ ${VIM}/vim71/gvim.exe \"\${@}\" ++ return; ++ }" ++ else ++ unset -f ${i} 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}3 ++ (Linux|CYGWIN*) # {{{3 ++ if test -n "${VIM}"; then ++ declare -x -f ${i}; ++ ++ eval "function ${i} () ++ { ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/${i}\" \"\${@}\" ; ++ return; ++ }" ++ else ++ unset -f ${i} 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}3 ++ (*) # {{{3 ++ ;; # }}}3 ++ esac; # }}}2 ++ done; # }}}1 ++ ++ # Server Functions ++ ++ for i in lxpm med epm; do # {{{1 ++ declare -x -f ${i} ++ ++ case "${UName}" in # {{{2 ++ (MINGW*) # {{{3 ++ if test -n "${VIM}"; then ++ eval "function ${i} () ++ { ++ if test -z "\${1}"; then ++ ${VIM}/vim71/gvim.exe --servername ${i} 1>/dev/null 2>/dev/null & ++ else ++ ${VIM}/vim71/gvim.exe --servername ${i} --remote-silent \"\${@}\" 1>/dev/null 2>/dev/null & ++ fi; ++ return; ++ }" ++ else ++ eval "function ${i} () ++ { ++ if test -z "\${1}"; then ++ gvim.exe --servername ${i} 1>/dev/null 2>/dev/null & ++ else ++ gvim.exe --servername ${i} --remote-silent \"\${@}\" 1>/dev/null 2>/dev/null & ++ fi; ++ return; ++ }" ++ fi; ++ ;; # }}}3 ++ (Linux|CYGWIN*|SunOS) # {{{3 ++ if test -n "${VIM}"; then ++ eval "function ${i} () ++ { ++ if test -z \"\${1}\"; then ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/gvim\" --servername \"${i} ${HOSTNAME}\" \"\${@}\" \ ++ >/dev/null 2>/dev/null & ++ else ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/gvim\" --servername \"${i} ${HOSTNAME}\" --remote-silent \"\${@}\" \ ++ >/dev/null 2>/dev/null & ++ fi ++ return; ++ }" ++ else ++ eval "function ${i} () ++ { ++ if test -z \"\${1}\"; then ++ gvim --servername \"${i} ${HOSTNAME}\" >/dev/null 2>/dev/null & ++ else ++ gvim --servername \"${i} ${HOSTNAME}\" --remote-silent \"\${@}\" >/dev/null 2>/dev/null & ++ fi ++ return; ++ }" ++ fi; ++ ;; # }}}3 ++ (*) # {{{3 ++ ;; # }}}3 ++ esac; # }}}2 ++ done; # }}}1 ++ ++ # Some applications read the EDITOR variable to determine your favourite text ++ # editor. So uncomment the line below and enter the editor of your choice :-) ++ if test -n "${VIM}"; then ++ declare -x EDITOR="${VIM}/bin/gvim -f"; ++ declare -x VISUAL="${VIM}/bin/gvim -f"; ++ else ++ declare -x EDITOR="$(which gvim) -f"; ++ declare -x VISUAL="$(which gvim) -f"; ++ fi; ++ # Unset local Variablen ++ ++ unset UName ++ ++ printf "\e[42m%-30.30s : \e[43m %-40.40s \e[m\n" "$(basename ${BASH_SOURCE:-${0}})" "VIM 7.0 symbols set." ++ ++fi; ++ ++########################################################### {{{1 ########### ++# Copyright (C) 2006 Martin Krischik ++# ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; either version 2 ++# of the License, or (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++########################################################### }}}1 ########### ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix foldmethod=marker +diff -urN vim71/1/macros/vim.zsh vim71_ada/1/macros/vim.zsh +--- vim71/1/macros/vim.zsh 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/macros/vim.zsh 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++#!/bin/echo usage: source ++ ++setopt No_Verbose ++setopt No_X_Trace ++setopt Typeset_Silent; ++ ++# ++# Bash script is zsh compatible ++# ++HOSTNAME="${HOSTNAME:-${HOST}}" ++BASH_SOURCE="$(basename ${0} .zsh).bash" ++source "$(dirname ${0})/${BASH_SOURCE}" ++unset BASH_SOURCE; ++ ++############################################################# {{{1 ########### ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/1/plugin/matchit.vim vim71_ada/1/plugin/matchit.vim +--- vim71/1/plugin/matchit.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/matchit.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,814 @@ ++" matchit.vim: (global plugin) Extended "%" matching ++" Last Change: Tue Oct 24 11:00 AM 2006 EDT ++" Maintainer: Benji Fisher PhD ++" Version: 1.12, for Vim 6.3+ ++" URL: http://www.vim.org/script.php?script_id=39 ++ ++" Documentation: ++" The documentation is in a separate file, matchit.txt . ++ ++" Credits: ++" Vim editor by Bram Moolenaar (Thanks, Bram!) ++" Original script and design by Raul Segura Acevedo ++" Support for comments by Douglas Potts ++" Support for back references and other improvements by Benji Fisher ++" Support for many languages by Johannes Zellner ++" Suggestions for improvement, bug reports, and support for additional ++" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark ++" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner. ++ ++" Debugging: ++" If you'd like to try the built-in debugging commands... ++" :MatchDebug to activate debugging for the current buffer ++" This saves the values of several key script variables as buffer-local ++" variables. See the MatchDebug() function, below, for details. ++ ++" TODO: I should think about multi-line patterns for b:match_words. ++" This would require an option: how many lines to scan (default 1). ++" This would be useful for Python, maybe also for *ML. ++" TODO: Maybe I should add a menu so that people will actually use some of ++" the features that I have implemented. ++" TODO: Eliminate the MultiMatch function. Add yet another argument to ++" Match_wrapper() instead. ++" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' ++" TODO: Make backrefs safer by using '\V' (very no-magic). ++" TODO: Add a level of indirection, so that custom % scripts can use my ++" work but extend it. ++ ++" allow user to prevent loading ++" and prevent duplicate loading ++if exists("loaded_matchit") || &cp ++ finish ++endif ++let loaded_matchit = 1 ++let s:last_mps = "" ++let s:last_words = "" ++ ++let s:save_cpo = &cpo ++set cpo&vim ++ ++nnoremap % :call Match_wrapper('',1,'n') ++nnoremap g% :call Match_wrapper('',0,'n') ++vnoremap % :call Match_wrapper('',1,'v') m'gv`` ++vnoremap g% :call Match_wrapper('',0,'v') m'gv`` ++onoremap % v:call Match_wrapper('',1,'o') ++onoremap g% v:call Match_wrapper('',0,'o') ++ ++" Analogues of [{ and ]} using matching patterns: ++nnoremap [% :call MultiMatch("bW", "n") ++nnoremap ]% :call MultiMatch("W", "n") ++vmap [% [%m'gv`` ++vmap ]% ]%m'gv`` ++" vnoremap [% :call MultiMatch("bW", "v") m'gv`` ++" vnoremap ]% :call MultiMatch("W", "v") m'gv`` ++onoremap [% v:call MultiMatch("bW", "o") ++onoremap ]% v:call MultiMatch("W", "o") ++ ++" text object: ++vmap a% [%v]% ++ ++" Auto-complete mappings: (not yet "ready for prime time") ++" TODO Read :help write-plugin for the "right" way to let the user ++" specify a key binding. ++" let g:match_auto = '' ++" let g:match_autoCR = '' ++" if exists("g:match_auto") ++" execute "inoremap " . g:match_auto . ' x"=Autocomplete()Pls' ++" endif ++" if exists("g:match_autoCR") ++" execute "inoremap " . g:match_autoCR . ' =Autocomplete()' ++" endif ++" if exists("g:match_gthhoh") ++" execute "inoremap " . g:match_gthhoh . ' :call Gthhoh()' ++" endif " gthhoh = "Get the heck out of here!" ++ ++let s:notslash = '\\\@" ++ endif ++ " In s:CleanUp(), we may need to check whether the cursor moved forward. ++ let startline = line(".") ++ let startcol = col(".") ++ " Use default behavior if called with a count or if no patterns are defined. ++ if v:count ++ exe "normal! " . v:count . "%" ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ elseif !exists("b:match_words") || b:match_words == "" ++ silent! normal! % ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ end ++ ++ " First step: if not already done, set the script variables ++ " s:do_BR flag for whether there are backrefs ++ " s:pat parsed version of b:match_words ++ " s:all regexp based on s:pat and the default groups ++ " ++ " Allow b:match_words = "GetVimMatchWords()" . ++ if b:match_words =~ ":" ++ let match_words = b:match_words ++ else ++ execute "let match_words =" b:match_words ++ endif ++" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion! ++ if (match_words != s:last_words) || (&mps != s:last_mps) || ++ \ exists("b:match_debug") ++ let s:last_words = match_words ++ let s:last_mps = &mps ++ if match_words !~ s:notslash . '\\\d' ++ let s:do_BR = 0 ++ let s:pat = match_words ++ else ++ let s:do_BR = 1 ++ let s:pat = s:ParseWords(match_words) ++ endif ++ " The next several lines were here before ++ " BF started messing with this script. ++ " quote the special chars in 'matchpairs', replace [,:] with \| and then ++ " append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif) ++ " let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+', ++ " \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>' ++ let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . ++ \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' ++ " s:all = pattern with all the keywords ++ let s:all = s:pat . (strlen(s:pat) ? "," : "") . default ++ let s:all = substitute(s:all, s:notslash . '\zs[,:]\+', '\\|', 'g') ++ let s:all = '\%(' . s:all . '\)' ++ " let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)' ++ if exists("b:match_debug") ++ let b:match_pat = s:pat ++ endif ++ endif ++ ++ " Second step: set the following local variables: ++ " matchline = line on which the cursor started ++ " curcol = number of characters before match ++ " prefix = regexp for start of line to start of match ++ " suffix = regexp for end of match to end of line ++ " Require match to end on or after the cursor and prefer it to ++ " start on or before the cursor. ++ let matchline = getline(startline) ++ if a:word != '' ++ " word given ++ if a:word !~ s:all ++ echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ endif ++ let matchline = a:word ++ let curcol = 0 ++ let prefix = '^\%(' ++ let suffix = '\)$' ++ " Now the case when "word" is not given ++ else " Find the match that ends on or after the cursor and set curcol. ++ let regexp = s:Wholematch(matchline, s:all, startcol-1) ++ let curcol = match(matchline, regexp) ++ let endcol = matchend(matchline, regexp) ++ let suf = strlen(matchline) - endcol ++ let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(') ++ let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$') ++ " If the match comes from the defaults, bail out. ++ if matchline !~ prefix . ++ \ substitute(s:pat, s:notslash.'\zs[,:]\+', '\\|', 'g') . suffix ++ silent! norm! % ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ endif ++ endif ++ if exists("b:match_debug") ++ let b:match_match = matchstr(matchline, regexp) ++ let b:match_col = curcol+1 ++ endif ++ ++ " Third step: Find the group and single word that match, and the original ++ " (backref) versions of these. Then, resolve the backrefs. ++ " Set the following local variable: ++ " group = colon-separated list of patterns, one of which matches ++ " = ini:mid:fin or ini:fin ++ " ++ " Reconstruct the version with unresolved backrefs. ++ let patBR = substitute(match_words.',', ++ \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g') ++ let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g') ++ " Now, set group and groupBR to the matching group: 'if:endif' or ++ " 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns ++ " group . "," . groupBR, and we pick it apart. ++ let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) ++ let i = matchend(group, s:notslash . ",") ++ let groupBR = strpart(group, i) ++ let group = strpart(group, 0, i-1) ++ " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix ++ if s:do_BR " Do the hard part: resolve those backrefs! ++ let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++ endif ++ if exists("b:match_debug") ++ let b:match_wholeBR = groupBR ++ let i = matchend(groupBR, s:notslash . ":") ++ let b:match_iniBR = strpart(groupBR, 0, i-1) ++ endif ++ ++ " Fourth step: Set the arguments for searchpair(). ++ let i = matchend(group, s:notslash . ":") ++ let j = matchend(group, '.*' . s:notslash . ":") ++ let ini = strpart(group, 0, i-1) ++ let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g') ++ let fin = strpart(group, j) ++ "Un-escape the remaining , and : characters. ++ let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ " searchpair() requires that these patterns avoid \(\) groups. ++ let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g') ++ let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g') ++ let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g') ++ " Set mid. This is optimized for readability, not micro-efficiency! ++ if a:forward && matchline =~ prefix . fin . suffix ++ \ || !a:forward && matchline =~ prefix . ini . suffix ++ let mid = "" ++ endif ++ " Set flag. This is optimized for readability, not micro-efficiency! ++ if a:forward && matchline =~ prefix . fin . suffix ++ \ || !a:forward && matchline !~ prefix . ini . suffix ++ let flag = "bW" ++ else ++ let flag = "W" ++ endif ++ " Set skip. ++ if exists("b:match_skip") ++ let skip = b:match_skip ++ elseif exists("b:match_comment") " backwards compatibility and testing! ++ let skip = "r:" . b:match_comment ++ else ++ let skip = 's:comment\|string' ++ endif ++ let skip = s:ParseSkip(skip) ++ if exists("b:match_debug") ++ let b:match_ini = ini ++ let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin ++ endif ++ ++ " Fifth step: actually start moving the cursor and call searchpair(). ++ " Later, :execute restore_cursor to get to the original screen. ++ let restore_cursor = virtcol(".") . "|" ++ normal! g0 ++ let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor ++ normal! H ++ let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ execute restore_cursor ++ call cursor(0, curcol + 1) ++ " normal! 0 ++ " if curcol ++ " execute "normal!" . curcol . "l" ++ " endif ++ if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) ++ let skip = "0" ++ else ++ execute "if " . skip . "| let skip = '0' | endif" ++ endif ++ let sp_return = searchpair(ini, mid, fin, flag, skip) ++ let final_position = "call cursor(" . line(".") . "," . col(".") . ")" ++ " Restore cursor position and original screen. ++ execute restore_cursor ++ normal! m' ++ if sp_return > 0 ++ execute final_position ++ endif ++ return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin) ++endfun ++ ++" Restore options and do some special handling for Operator-pending mode. ++" The optional argument is the tail of the matching group. ++fun! s:CleanUp(options, mode, startline, startcol, ...) ++ execute "set" a:options ++ " Open folds, if appropriate. ++ if a:mode != "o" ++ if &foldopen =~ "percent" ++ normal! zv ++ endif ++ " In Operator-pending mode, we want to include the whole match ++ " (for example, d%). ++ " This is only a problem if we end up moving in the forward direction. ++ elseif (a:startline < line(".")) || ++ \ (a:startline == line(".") && a:startcol < col(".")) ++ if a:0 ++ " Check whether the match is a single character. If not, move to the ++ " end of the match. ++ let matchline = getline(".") ++ let currcol = col(".") ++ let regexp = s:Wholematch(matchline, a:1, currcol-1) ++ let endcol = matchend(matchline, regexp) ++ if endcol > currcol " This is NOT off by one! ++ execute "normal!" . (endcol - currcol) . "l" ++ endif ++ endif " a:0 ++ endif " a:mode != "o" && etc. ++ return 0 ++endfun ++ ++" Example (simplified HTML patterns): if ++" a:groupBR = '<\(\k\+\)>:' ++" a:prefix = '^.\{3}\(' ++" a:group = '<\(\k\+\)>:' ++" a:suffix = '\).\{2}$' ++" a:matchline = "12312" or "12312" ++" then extract "tag" from a:matchline and return ":" . ++fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++ if a:matchline !~ a:prefix . ++ \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix ++ return a:group ++ endif ++ let i = matchend(a:groupBR, s:notslash . ':') ++ let ini = strpart(a:groupBR, 0, i-1) ++ let tailBR = strpart(a:groupBR, i) ++ let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix, ++ \ a:groupBR) ++ let i = matchend(word, s:notslash . ":") ++ let wordBR = strpart(word, i) ++ let word = strpart(word, 0, i-1) ++ " Now, a:matchline =~ a:prefix . word . a:suffix ++ if wordBR != ini ++ let table = s:Resolve(ini, wordBR, "table") ++ else ++ " let table = "----------" ++ let table = "" ++ let d = 0 ++ while d < 10 ++ if tailBR =~ s:notslash . '\\' . d ++ " let table[d] = d ++ let table = table . d ++ else ++ let table = table . "-" ++ endif ++ let d = d + 1 ++ endwhile ++ endif ++ let d = 9 ++ while d ++ if table[d] != "-" ++ let backref = substitute(a:matchline, a:prefix.word.a:suffix, ++ \ '\'.table[d], "") ++ " Are there any other characters that should be escaped? ++ let backref = escape(backref, '*,:') ++ execute s:Ref(ini, d, "start", "len") ++ let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len) ++ let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d, ++ \ escape(backref, '\\'), 'g') ++ endif ++ let d = d-1 ++ endwhile ++ if exists("b:match_debug") ++ if s:do_BR ++ let b:match_table = table ++ let b:match_word = word ++ else ++ let b:match_table = "" ++ let b:match_word = "" ++ endif ++ endif ++ return ini . ":" . tailBR ++endfun ++ ++" Input a comma-separated list of groups with backrefs, such as ++" a:groups = '\(foo\):end\1,\(bar\):end\1' ++" and return a comma-separated list of groups with backrefs replaced: ++" return '\(foo\):end\(foo\),\(bar\):end\(bar\)' ++fun! s:ParseWords(groups) ++ let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g') ++ let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g') ++ let parsed = "" ++ while groups =~ '[^,:]' ++ let i = matchend(groups, s:notslash . ':') ++ let j = matchend(groups, s:notslash . ',') ++ let ini = strpart(groups, 0, i-1) ++ let tail = strpart(groups, i, j-i-1) . ":" ++ let groups = strpart(groups, j) ++ let parsed = parsed . ini ++ let i = matchend(tail, s:notslash . ':') ++ while i != -1 ++ " In 'if:else:endif', ini='if' and word='else' and then word='endif'. ++ let word = strpart(tail, 0, i-1) ++ let tail = strpart(tail, i) ++ let i = matchend(tail, s:notslash . ':') ++ let parsed = parsed . ":" . s:Resolve(ini, word, "word") ++ endwhile " Now, tail has been used up. ++ let parsed = parsed . "," ++ endwhile " groups =~ '[^,:]' ++ return parsed ++endfun ++ ++" TODO I think this can be simplified and/or made more efficient. ++" TODO What should I do if a:start is out of range? ++" Return a regexp that matches all of a:string, such that ++" matchstr(a:string, regexp) represents the match for a:pat that starts ++" as close to a:start as possible, before being preferred to after, and ++" ends after a:start . ++" Usage: ++" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1) ++" let i = match(getline("."), regexp) ++" let j = matchend(getline("."), regexp) ++" let match = matchstr(getline("."), regexp) ++fun! s:Wholematch(string, pat, start) ++ let group = '\%(' . a:pat . '\)' ++ let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^') ++ let len = strlen(a:string) ++ let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$') ++ if a:string !~ prefix . group . suffix ++ let prefix = '' ++ endif ++ return prefix . group . suffix ++endfun ++ ++" No extra arguments: s:Ref(string, d) will ++" find the d'th occurrence of '\(' and return it, along with everything up ++" to and including the matching '\)'. ++" One argument: s:Ref(string, d, "start") returns the index of the start ++" of the d'th '\(' and any other argument returns the length of the group. ++" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be ++" executed, having the effect of ++" :let foo = s:Ref(string, d, "start") ++" :let bar = s:Ref(string, d, "len") ++fun! s:Ref(string, d, ...) ++ let len = strlen(a:string) ++ if a:d == 0 ++ let start = 0 ++ else ++ let cnt = a:d ++ let match = a:string ++ while cnt ++ let cnt = cnt - 1 ++ let index = matchend(match, s:notslash . '\\(') ++ if index == -1 ++ return "" ++ endif ++ let match = strpart(match, index) ++ endwhile ++ let start = len - strlen(match) ++ if a:0 == 1 && a:1 == "start" ++ return start - 2 ++ endif ++ let cnt = 1 ++ while cnt ++ let index = matchend(match, s:notslash . '\\(\|\\)') - 1 ++ if index == -2 ++ return "" ++ endif ++ " Increment if an open, decrement if a ')': ++ let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')' ++ " let cnt = stridx('0(', match[index]) + cnt ++ let match = strpart(match, index+1) ++ endwhile ++ let start = start - 2 ++ let len = len - start - strlen(match) ++ endif ++ if a:0 == 1 ++ return len ++ elseif a:0 == 2 ++ return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len ++ else ++ return strpart(a:string, start, len) ++ endif ++endfun ++ ++" Count the number of disjoint copies of pattern in string. ++" If the pattern is a literal string and contains no '0' or '1' characters ++" then s:Count(string, pattern, '0', '1') should be faster than ++" s:Count(string, pattern). ++fun! s:Count(string, pattern, ...) ++ let pat = escape(a:pattern, '\\') ++ if a:0 > 1 ++ let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g") ++ let foo = substitute(a:string, pat, a:2, "g") ++ let foo = substitute(foo, '[^' . a:2 . ']', "", "g") ++ return strlen(foo) ++ endif ++ let result = 0 ++ let foo = a:string ++ let index = matchend(foo, pat) ++ while index != -1 ++ let result = result + 1 ++ let foo = strpart(foo, index) ++ let index = matchend(foo, pat) ++ endwhile ++ return result ++endfun ++ ++" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where ++" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first ++" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this ++" indicates that all other instances of '\1' in target are to be replaced ++" by '\3'. The hard part is dealing with nesting... ++" Note that ":" is an illegal character for source and target, ++" unless it is preceded by "\". ++fun! s:Resolve(source, target, output) ++ let word = a:target ++ let i = matchend(word, s:notslash . '\\\d') - 1 ++ let table = "----------" ++ while i != -2 " There are back references to be replaced. ++ let d = word[i] ++ let backref = s:Ref(a:source, d) ++ " The idea is to replace '\d' with backref. Before we do this, ++ " replace any \(\) groups in backref with :1, :2, ... if they ++ " correspond to the first, second, ... group already inserted ++ " into backref. Later, replace :1 with \1 and so on. The group ++ " number w+b within backref corresponds to the group number ++ " s within a:source. ++ " w = number of '\(' in word before the current one ++ let w = s:Count( ++ \ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1') ++ let b = 1 " number of the current '\(' in backref ++ let s = d " number of the current '\(' in a:source ++ while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1') ++ \ && s < 10 ++ if table[s] == "-" ++ if w + b < 10 ++ " let table[s] = w + b ++ let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1) ++ endif ++ let b = b + 1 ++ let s = s + 1 ++ else ++ execute s:Ref(backref, b, "start", "len") ++ let ref = strpart(backref, start, len) ++ let backref = strpart(backref, 0, start) . ":". table[s] ++ \ . strpart(backref, start+len) ++ let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1') ++ endif ++ endwhile ++ let word = strpart(word, 0, i-1) . backref . strpart(word, i+1) ++ let i = matchend(word, s:notslash . '\\\d') - 1 ++ endwhile ++ let word = substitute(word, s:notslash . '\zs:', '\\', 'g') ++ if a:output == "table" ++ return table ++ elseif a:output == "word" ++ return word ++ else ++ return table . word ++ endif ++endfun ++ ++" Assume a:comma = ",". Then the format for a:patterns and a:1 is ++" a:patterns = ",,..." ++" a:1 = ",,..." ++" If is the first pattern that matches a:string then return ++" if no optional arguments are given; return , if a:1 is given. ++fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...) ++ let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma) ++ let i = matchend(tail, s:notslash . a:comma) ++ if a:0 ++ let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma) ++ let j = matchend(alttail, s:notslash . a:comma) ++ endif ++ let current = strpart(tail, 0, i-1) ++ if a:branch == "" ++ let currpat = current ++ else ++ let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') ++ endif ++ while a:string !~ a:prefix . currpat . a:suffix ++ let tail = strpart(tail, i) ++ let i = matchend(tail, s:notslash . a:comma) ++ if i == -1 ++ return -1 ++ endif ++ let current = strpart(tail, 0, i-1) ++ if a:branch == "" ++ let currpat = current ++ else ++ let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') ++ endif ++ if a:0 ++ let alttail = strpart(alttail, j) ++ let j = matchend(alttail, s:notslash . a:comma) ++ endif ++ endwhile ++ if a:0 ++ let current = current . a:comma . strpart(alttail, 0, j-1) ++ endif ++ return current ++endfun ++ ++" Call this function to turn on debugging information. Every time the main ++" script is run, buffer variables will be saved. These can be used directly ++" or viewed using the menu items below. ++if !exists(":MatchDebug") ++ command! -nargs=0 MatchDebug call s:Match_debug() ++endif ++ ++fun! s:Match_debug() ++ let b:match_debug = 1 " Save debugging information. ++ " pat = all of b:match_words with backrefs parsed ++ amenu &Matchit.&pat :echo b:match_pat ++ " match = bit of text that is recognized as a match ++ amenu &Matchit.&match :echo b:match_match ++ " curcol = cursor column of the start of the matching text ++ amenu &Matchit.&curcol :echo b:match_col ++ " wholeBR = matching group, original version ++ amenu &Matchit.wh&oleBR :echo b:match_wholeBR ++ " iniBR = 'if' piece, original version ++ amenu &Matchit.ini&BR :echo b:match_iniBR ++ " ini = 'if' piece, with all backrefs resolved from match ++ amenu &Matchit.&ini :echo b:match_ini ++ " tail = 'else\|endif' piece, with all backrefs resolved from match ++ amenu &Matchit.&tail :echo b:match_tail ++ " fin = 'endif' piece, with all backrefs resolved from match ++ amenu &Matchit.&word :echo b:match_word ++ " '\'.d in ini refers to the same thing as '\'.table[d] in word. ++ amenu &Matchit.t&able :echo '0:' . b:match_table . ':9' ++endfun ++ ++" Jump to the nearest unmatched "(" or "if" or "" if a:spflag == "bW" ++" or the nearest unmatched "" or "endif" or ")" if a:spflag == "W". ++" Return a "mark" for the original position, so that ++" let m = MultiMatch("bW", "n") ... execute m ++" will return to the original position. If there is a problem, do not ++" move the cursor and return "", unless a count is given, in which case ++" go up or down as many levels as possible and again return "". ++" TODO This relies on the same patterns as % matching. It might be a good ++" idea to give it its own matching patterns. ++fun! s:MultiMatch(spflag, mode) ++ if !exists("b:match_words") || b:match_words == "" ++ return "" ++ end ++ let restore_options = (&ic ? "" : "no") . "ignorecase" ++ if exists("b:match_ignorecase") ++ let &ignorecase = b:match_ignorecase ++ endif ++ let startline = line(".") ++ let startcol = col(".") ++ ++ " First step: if not already done, set the script variables ++ " s:do_BR flag for whether there are backrefs ++ " s:pat parsed version of b:match_words ++ " s:all regexp based on s:pat and the default groups ++ " This part is copied and slightly modified from s:Match_wrapper(). ++ let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . ++ \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' ++ " Allow b:match_words = "GetVimMatchWords()" . ++ if b:match_words =~ ":" ++ let match_words = b:match_words ++ else ++ execute "let match_words =" b:match_words ++ endif ++ if (match_words != s:last_words) || (&mps != s:last_mps) || ++ \ exists("b:match_debug") ++ let s:last_words = match_words ++ let s:last_mps = &mps ++ if match_words !~ s:notslash . '\\\d' ++ let s:do_BR = 0 ++ let s:pat = match_words ++ else ++ let s:do_BR = 1 ++ let s:pat = s:ParseWords(match_words) ++ endif ++ let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default, ++ \ '[,:]\+','\\|','g') . '\)' ++ if exists("b:match_debug") ++ let b:match_pat = s:pat ++ endif ++ endif ++ ++ " Second step: figure out the patterns for searchpair() ++ " and save the screen, cursor position, and 'ignorecase'. ++ " - TODO: A lot of this is copied from s:Match_wrapper(). ++ " - maybe even more functionality should be split off ++ " - into separate functions! ++ let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default ++ let open = substitute(s:pat . cdefault, ++ \ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g') ++ let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '') ++ let close = substitute(s:pat . cdefault, ++ \ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g') ++ let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)' ++ if exists("b:match_skip") ++ let skip = b:match_skip ++ elseif exists("b:match_comment") " backwards compatibility and testing! ++ let skip = "r:" . b:match_comment ++ else ++ let skip = 's:comment\|string' ++ endif ++ let skip = s:ParseSkip(skip) ++ " let restore_cursor = line(".") . "G" . virtcol(".") . "|" ++ " normal! H ++ " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ let restore_cursor = virtcol(".") . "|" ++ normal! g0 ++ let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor ++ normal! H ++ let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ execute restore_cursor ++ ++ " Third step: call searchpair(). ++ " Replace '\('--but not '\\('--with '\%(' and ',' with '\|'. ++ let openpat = substitute(open, '\(\\\@" or ... ++" and return "endif" or "endwhile" or "" or ... . ++" For now, this uses b:match_words and the same script variables ++" as s:Match_wrapper() . Later, it may get its own patterns, ++" either from a buffer variable or passed as arguments. ++" fun! s:Autocomplete() ++" echo "autocomplete not yet implemented :-(" ++" if !exists("b:match_words") || b:match_words == "" ++" return "" ++" end ++" let startpos = s:MultiMatch("bW") ++" ++" if startpos == "" ++" return "" ++" endif ++" " - TODO: figure out whether 'if' or '' matched, and construct ++" " - the appropriate closing. ++" let matchline = getline(".") ++" let curcol = col(".") - 1 ++" " - TODO: Change the s:all argument if there is a new set of match pats. ++" let regexp = s:Wholematch(matchline, s:all, curcol) ++" let suf = strlen(matchline) - matchend(matchline, regexp) ++" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(') ++" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$') ++" " Reconstruct the version with unresolved backrefs. ++" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g') ++" let patBR = substitute(patBR, ':\{2,}', ':', "g") ++" " Now, set group and groupBR to the matching group: 'if:endif' or ++" " 'while:endwhile' or whatever. ++" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) ++" let i = matchend(group, s:notslash . ",") ++" let groupBR = strpart(group, i) ++" let group = strpart(group, 0, i-1) ++" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix ++" if s:do_BR ++" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++" endif ++" " let g:group = group ++" ++" " - TODO: Construct the closing from group. ++" let fake = "end" . expand("") ++" execute startpos ++" return fake ++" endfun ++ ++" Close all open structures. "Get the heck out of here!" ++" fun! s:Gthhoh() ++" let close = s:Autocomplete() ++" while strlen(close) ++" put=close ++" let close = s:Autocomplete() ++" endwhile ++" endfun ++ ++" Parse special strings as typical skip arguments for searchpair(): ++" s:foo becomes (current syntax item) =~ foo ++" S:foo becomes (current syntax item) !~ foo ++" r:foo becomes (line before cursor) =~ foo ++" R:foo becomes (line before cursor) !~ foo ++fun! s:ParseSkip(str) ++ let skip = a:str ++ if skip[1] == ":" ++ if skip[0] == "s" ++ let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" . ++ \ strpart(skip,2) . "'" ++ elseif skip[0] == "S" ++ let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" . ++ \ strpart(skip,2) . "'" ++ elseif skip[0] == "r" ++ let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'" ++ elseif skip[0] == "R" ++ let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'" ++ endif ++ endif ++ return skip ++endfun ++ ++let &cpo = s:save_cpo ++ ++" vim:sts=2:sw=2: +diff -urN vim71/1/plugin/NERD_commenter.vim vim71_ada/1/plugin/NERD_commenter.vim +--- vim71/1/plugin/NERD_commenter.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/NERD_commenter.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,4553 @@ ++" vim global plugin that provides easy code commenting for various file types ++" Last Change: 29 sep 2007 ++" Maintainer: Martin Grenfell ++let s:NERD_commenter_version = 2.1.4 ++ ++" For help documentation type :help NERDCommenter. If this fails, Restart vim ++" and try again. If it sill doesnt work... the help page is at the bottom ++" of this file. ++ ++" Section: script init stuff {{{1 ++if exists("loaded_nerd_comments") ++ finish ++endif ++if v:version < 700 ++ echoerr "NERDCommenter: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" ++ finish ++endif ++let loaded_nerd_comments = 1 ++ ++" Section: spaces init {{{2 ++" Occasionally we need to grab a string of spaces so just make one here ++let s:spaces = "" ++while strlen(s:spaces) < 100 ++ let s:spaces = s:spaces . " " ++endwhile ++ ++" Function: s:InitVariable() function {{{2 ++" This function is used to initialise a given variable to a given value. The ++" variable is only initialised if it does not exist prior ++" ++" Args: ++" -var: the name of the var to be initialised ++" -value: the value to initialise var to ++" ++" Returns: ++" 1 if the var is set, 0 otherwise ++function s:InitVariable(var, value) ++ if !exists(a:var) ++ exec 'let ' . a:var . ' = ' . "'" . a:value . "'" ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Section: space string init{{{2 ++" When putting spaces after the left delim and before the right we use ++" s:spaceStr for the space char. This way we can make it add anything after ++" the left and before the right by modifying this variable ++let s:spaceStr = ' ' ++let s:lenSpaceStr = strlen(s:spaceStr) ++ ++" Section: variable init calls {{{2 ++call s:InitVariable("g:NERDAllowAnyVisualDelims", 1) ++call s:InitVariable("g:NERDBlockComIgnoreEmpty", 0) ++call s:InitVariable("g:NERDCommentWholeLinesInVMode", 0) ++call s:InitVariable("g:NERDCompactSexyComs", 0) ++call s:InitVariable("g:NERDDefaultNesting", 0) ++call s:InitVariable("g:NERDMenuMode", 3) ++call s:InitVariable("g:NERDLPlace", "[>") ++call s:InitVariable("g:NERDUsePlaceHolders", 1) ++call s:InitVariable("g:NERDRemoveAltComs", 1) ++call s:InitVariable("g:NERDRemoveExtraSpaces", 0) ++call s:InitVariable("g:NERDRPlace", "<]") ++call s:InitVariable("g:NERDShutUp", '0') ++call s:InitVariable("g:NERDSpaceDelims", 0) ++call s:InitVariable("g:NERDDelimiterRequests", 1) ++ ++call s:InitVariable("g:NERDMapleader", ',c') ++ ++call s:InitVariable("g:NERDAltComMap", g:NERDMapleader . 'a') ++call s:InitVariable("g:NERDAppendComMap", g:NERDMapleader . 'A') ++call s:InitVariable("g:NERDComAlignBothMap", g:NERDMapleader . 'b') ++call s:InitVariable("g:NERDComAlignLeftMap", g:NERDMapleader . 'l') ++call s:InitVariable("g:NERDComAlignRightMap", g:NERDMapleader . 'r') ++call s:InitVariable("g:NERDComInInsertMap", '') ++call s:InitVariable("g:NERDComLineInvertMap", g:NERDMapleader . 'i') ++call s:InitVariable("g:NERDComLineMap", g:NERDMapleader . 'c') ++call s:InitVariable("g:NERDComLineNestMap", g:NERDMapleader . 'n') ++call s:InitVariable("g:NERDComLineSexyMap", g:NERDMapleader . 's') ++call s:InitVariable("g:NERDComLineToggleMap", g:NERDMapleader . '') ++call s:InitVariable("g:NERDComLineMinimalMap", g:NERDMapleader . 'm') ++call s:InitVariable("g:NERDComLineYankMap", g:NERDMapleader . 'y') ++call s:InitVariable("g:NERDComToEOLMap", g:NERDMapleader . '$') ++call s:InitVariable("g:NERDPrependComMap", g:NERDMapleader . 'I') ++call s:InitVariable("g:NERDUncomLineMap", g:NERDMapleader . 'u') ++let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\" ++ ++" Section: Comment mapping functions, autocommands and commands {{{1 ++" ============================================================================ ++" Section: Comment enabler autocommands {{{2 ++" ============================================================================ ++ ++if !exists("nerd_autocmds_loaded") ++ let nerd_autocmds_loaded=1 ++ ++ augroup commentEnablers ++ ++ "if the user enters a buffer or reads a buffer then we gotta set up ++ "the comment delimiters for that new filetype ++ autocmd BufEnter,BufRead * :call s:SetUpForNewFiletype(&filetype, 0) ++ ++ "if the filetype of a buffer changes, force the script to reset the ++ "delims for the buffer ++ autocmd Filetype * :call s:SetUpForNewFiletype(&filetype, 1) ++ augroup END ++ ++endif ++ ++ ++" Function: s:SetUpForNewFiletype(filetype) function {{{2 ++" This function is responsible for setting up buffer scoped variables for the ++" given filetype. ++" ++" These variables include the comment delimiters for the given filetype and calls ++" MapDelimiters or MapDelimitersWithAlternative passing in these delimiters. ++" ++" Args: ++" -filetype: the filetype to set delimiters for ++" -forceReset: 1 if the delimiters should be reset if they have already be ++" set for this buffer. ++" ++function s:SetUpForNewFiletype(filetype, forceReset) ++ "if we have already set the delimiters for this buffer then dont go thru ++ "it again ++ if !a:forceReset && exists("b:left") && b:left != '' ++ return ++ endif ++ ++ let b:sexyComMarker = '' ++ ++ "check the filetype against all known filetypes to see if we have ++ "hardcoded the comment delimiters to use ++ if a:filetype == "" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "abaqus" ++ call s:MapDelimiters('**', '') ++ elseif a:filetype == "abc" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "acedb" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ada" ++ call s:MapDelimitersWithAlternative('--','', '-- ', '') ++ elseif a:filetype == "ahdl" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "ahk" ++ call s:MapDelimitersWithAlternative(';', '', '/*', '*/') ++ elseif a:filetype == "amiga" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "aml" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "ampl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ant" ++ call s:MapDelimiters('') ++ elseif a:filetype == "apache" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "apachestyle" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "asm68k" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "asm" ++ call s:MapDelimitersWithAlternative(';', '', '#', '') ++ elseif a:filetype == "asn" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "aspvbs" ++ call s:MapDelimiters('''', '') ++ elseif a:filetype == "atlas" ++ call s:MapDelimiters('C','$') ++ elseif a:filetype == "autohotkey" ++ call s:MapDelimiters(';','') ++ elseif a:filetype == "autoit" ++ call s:MapDelimiters(';','') ++ elseif a:filetype == "automake" ++ call s:MapDelimitersWithAlternative('#','', 'dnl ', '') ++ elseif a:filetype == "ave" ++ call s:MapDelimiters("'",'') ++ elseif a:filetype == "awk" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "basic" ++ call s:MapDelimitersWithAlternative("'",'', 'REM ', '') ++ elseif a:filetype == "b" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "bc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "bdf" ++ call s:MapDelimiters('COMMENT ', '') ++ elseif a:filetype == "bib" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "bindzone" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "bst" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "btm" ++ call s:MapDelimiters('::', '') ++ elseif a:filetype == "caos" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "catalog" ++ call s:MapDelimiters('--','--') ++ elseif a:filetype == "c" ++ call s:MapDelimitersWithAlternative('/*','*/', '//', '') ++ elseif a:filetype == "cfg" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "cg" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ch" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "changelog" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "cl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "clean" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "clipper" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "cmake" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "conf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "config" ++ call s:MapDelimiters('dnl ', '') ++ elseif a:filetype == "context" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "cpp" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "crontab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "cs" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "csc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "csp" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "css" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "cterm" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "cupl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "csv" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "cvs" ++ call s:MapDelimiters('CVS:','') ++ elseif a:filetype == "dcl" ++ call s:MapDelimiters('$!', '') ++ elseif a:filetype == "debchangelog" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "debcontrol" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "debsources" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "def" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "desktop" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "diff" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "django" ++ call s:MapDelimitersWithAlternative('', '{#', '#}') ++ elseif a:filetype == "docbk" ++ call s:MapDelimiters('') ++ elseif a:filetype == "dns" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dosbatch" ++ call s:MapDelimiters('REM ','') ++ elseif a:filetype == "dosini" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dot" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "dracula" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dsl" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dtd" ++ call s:MapDelimiters('') ++ elseif a:filetype == "dtml" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "dylan" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == 'ebuild' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ecd" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'eclass' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "eiffel" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "elf" ++ call s:MapDelimiters("'", '') ++ elseif a:filetype == "elmfilt" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "erlang" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "eruby" ++ call s:MapDelimitersWithAlternative('', '<%#', '%>') ++ elseif a:filetype == "eterm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "expect" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "exports" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fetchmail" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fgl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "focexec" ++ call s:MapDelimiters('-*', '') ++ elseif a:filetype == "form" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "fortran" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "foxpro" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "fstab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fvwm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fx" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "gams" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "gdb" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "gdmo" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "geek" ++ call s:MapDelimiters('GEEK_COMMENT:', '') ++ elseif a:filetype == 'gentoo-package-keywords' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'gentoo-package-mask' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'gentoo-package-use' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "gnuplot" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "groovy" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "gtkrc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "haskell" ++ call s:MapDelimitersWithAlternative('--','', '{-', '-}') ++ elseif a:filetype == "hb" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "h" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "help" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "hercules" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "hog" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "html" ++ call s:MapDelimitersWithAlternative('', '//', '') ++ elseif a:filetype == "htmldjango" ++ call s:MapDelimitersWithAlternative('', '{#', '#}') ++ elseif a:filetype == "htmlos" ++ call s:MapDelimiters('#','/#') ++ elseif a:filetype == "ia64" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "icon" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "idlang" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "idl" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "indent" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "inform" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "inittab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ishd" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "iss" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "ist" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "jam" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "java" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "javascript" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "jess" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "jgraph" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "jproperties" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "jsp" ++ call s:MapDelimiters('<%--', '--%>') ++ elseif a:filetype == "kconfig" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "kix" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "kscript" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "lace" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "ldif" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lex" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lftp" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lifelines" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lilo" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lisp" ++ call s:MapDelimitersWithAlternative(';','', '#|', '|#') ++ elseif a:filetype == "lite" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lookupfile" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "lotos" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "lout" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lprolog" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "lscript" ++ call s:MapDelimiters("'", '') ++ elseif a:filetype == "lss" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lua" ++ call s:MapDelimitersWithAlternative('--','', '--[[', ']]') ++ elseif a:filetype == "lynx" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "m4" ++ call s:MapDelimiters('dnl ', '') ++ elseif a:filetype == "mail" ++ call s:MapDelimiters('> ','') ++ elseif a:filetype == "make" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "maple" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "masm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "master" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "matlab" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "mel" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "mf" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "mib" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "mma" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "model" ++ call s:MapDelimiters('$','$') ++ elseif a:filetype =~ "moduala." ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "modula2" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "modula3" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "monk" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "mush" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "muttrc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "named" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "nasm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "nastran" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "natural" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "ncf" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "netdict" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "netrw" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "nqc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "nroff" ++ call s:MapDelimiters('\"', '') ++ elseif a:filetype == "nsis" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "objc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ocaml" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "occam" ++ call s:MapDelimiters('--','') ++ elseif a:filetype == "omlet" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "omnimark" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "openroad" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "opl" ++ call s:MapDelimiters("REM", "") ++ elseif a:filetype == "ora" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "otl" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ox" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "pascal" ++ call s:MapDelimitersWithAlternative('{','}', '(*', '*)') ++ elseif a:filetype == "passwd" ++ call s:MapDelimitersWith('','') ++ elseif a:filetype == "pcap" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "pccts" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "perl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "pfmain" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "php" ++ call s:MapDelimitersWithAlternative('//','','/*', '*/') ++ elseif a:filetype == "phtml" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "pic" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "pike" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "pilrc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "pine" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "plaintex" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "plm" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "plsql" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "po" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "postscr" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "pov" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "povini" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "ppd" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "ppwiz" ++ call s:MapDelimiters(';;', '') ++ elseif a:filetype == "procmail" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "progress" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "prolog" ++ call s:MapDelimitersWithAlternative('%','','/*','*/') ++ elseif a:filetype == "psf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ptcap" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "python" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "qf" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "radiance" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "Rails-log" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ratpoison" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "r" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "readline" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rebol" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "registry" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "remind" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rexx" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "robots" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rpl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "rst" ++ call s:MapDelimiters('..', '') ++ elseif a:filetype == "rtf" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ruby" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "sa" ++ call s:MapDelimiters('--','') ++ elseif a:filetype == "samba" ++ call s:MapDelimitersWithAlternative(';','', '#', '') ++ elseif a:filetype == "sas" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "sass" ++ call s:MapDelimitersWithAlternative('//','', '/*', '') ++ elseif a:filetype == "sather" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "scheme" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "scilab" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "screen" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "scsh" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "sdl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "sed" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "selectbuf" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "sgml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "sgmldecl" ++ call s:MapDelimiters('--','--') ++ elseif a:filetype == "sgmllnx" ++ call s:MapDelimiters('') ++ elseif a:filetype == "sicad" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "simula" ++ call s:MapDelimitersWithAlternative('%', '', '--', '') ++ elseif a:filetype == "sinda" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "skill" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "slang" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "sl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "slrnrc" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "sm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "smarty" ++ call s:MapDelimiters('{*', '*}') ++ elseif a:filetype == "smil" ++ call s:MapDelimiters('') ++ elseif a:filetype == "smith" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "sml" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "snnsnet" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snnspat" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snnsres" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snobol4" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "spec" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "specman" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "spice" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "sql" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqlforms" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqlj" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqr" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "squid" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "st" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "stp" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "strace" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "svn" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "SVNcommitlog" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "systemverilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "tads" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "taglist" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "tags" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tak" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "tasm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tcl" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "terminfo" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tex" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "text" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "texinfo" ++ call s:MapDelimiters("@c ", "") ++ elseif a:filetype == "texmf" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "tf" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tidy" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tli" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "trasys" ++ call s:MapDelimiters("$", "") ++ elseif a:filetype == "tsalt" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "tsscl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tssgm" ++ call s:MapDelimiters("comment = '","'") ++ elseif a:filetype == "uc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "uil" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "vb" ++ call s:MapDelimiters("'","") ++ elseif a:filetype == "vcscommit" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "vera" ++ call s:MapDelimitersWithAlternative('/*','*/','//','') ++ elseif a:filetype == "verilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "verilog_systemverilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "vgrindefs" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "vhdl" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "vim" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "viminfo" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "virata" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "vo_base" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "vrml" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "vsejcl" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "webmacro" ++ call s:MapDelimiters('##', '') ++ elseif a:filetype == "wget" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "winbatch" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "wml" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype =~ "[^w]*sh" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "wvdial" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "xdefaults" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xf86conf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "xhtml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xkb" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "xmath" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "xml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xmodmap" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xpm2" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xpm" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "xsd" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xslt" ++ call s:MapDelimiters('') ++ elseif a:filetype == "yacc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "yaml" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "z8a" ++ call s:MapDelimiters(';', '') ++ ++ elseif a:filetype == "" ++ call s:MapDelimitersWithAlternative("","", "", "") ++ ++ "we have not hardcoded the comment delimiters to use for this filetype so ++ "get them from &commentstring. ++ else ++ "print a disclaimer to the user :) ++ if !g:NERDShutUp ++ call s:NerdEcho("Unknown filetype '".a:filetype."', setting delimiters by &commentstring.\nPleeeeease email the author of the NERD commenter with this filetype\nand its delimiters!", 0) ++ endif ++ ++ "extract the delims from &commentstring ++ let left= substitute(&commentstring, '\(.*\)%s.*', '\1', '') ++ let right= substitute(&commentstring, '.*%s\(.*\)', '\1', 'g') ++ ++ call s:MapDelimiters(left,right) ++ endif ++endfunction ++ ++" Function: s:MapDelimiters(left, right) function {{{2 ++" This function is a wrapper for s:MapDelimiters(left, right, leftAlt, rightAlt, useAlt) and is called when there ++" is no alternative comment delimiters for the current filetype ++" ++" Args: ++" -left: the left comment delimiter ++" -right: the right comment delimiter ++function s:MapDelimiters(left, right) ++ call s:MapDelimitersWithAlternative(a:left, a:right, "", "") ++endfunction ++ ++" Function: s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt) function {{{2 ++" this function sets up the comment delimiter buffer variables ++" ++" Args: ++" -left: the string defining the comment start delimiter ++" -right: the string defining the comment end delimiter ++" -leftAlt: the string for the alternative comment style defining the comment start delimiter ++" -rightAlt: the string for the alternative comment style defining the comment end delimiter ++function s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt) ++ if !exists('g:NERD_' . &filetype . '_alt_style') ++ let b:left = a:left ++ let b:right = a:right ++ let b:leftAlt = a:leftAlt ++ let b:rightAlt = a:rightAlt ++ else ++ let b:left = a:leftAlt ++ let b:right = a:rightAlt ++ let b:leftAlt = a:left ++ let b:rightAlt = a:right ++ endif ++endfunction ++ ++" Function: s:SwitchToAlternativeDelimiters(printMsgs) function {{{2 ++" This function is used to swap the delimiters that are being used to the ++" alternative delimiters for that filetype. For example, if a c++ file is ++" being edited and // comments are being used, after this function is called ++" /**/ comments will be used. ++" ++" Args: ++" -printMsgs: if this is 1 then a message is echoed to the user telling them ++" if this function changed the delimiters or not ++function s:SwitchToAlternativeDelimiters(printMsgs) ++ "if both of the alternative delimiters are empty then there is no ++ "alternative comment style so bail out ++ if !s:HasMultipartDelims() ++ if a:printMsgs ++ call s:NerdEcho("Cannot use alternative delimiters, none are specified", 0) ++ endif ++ return 0 ++ endif ++ ++ "save the current delimiters ++ let tempLeft = b:left ++ let tempRight = b:right ++ ++ "swap current delimiters for alternative ++ let b:left = b:leftAlt ++ let b:right = b:rightAlt ++ ++ "set the previously current delimiters to be the new alternative ones ++ let b:leftAlt = tempLeft ++ let b:rightAlt = tempRight ++ ++ "tell the user what comment delimiters they are now using ++ if a:printMsgs ++ let leftNoEsc = b:left ++ let rightNoEsc = b:right ++ call s:NerdEcho("Now using " . leftNoEsc . " " . rightNoEsc . " to delimit comments", 1) ++ endif ++ ++ return 1 ++endfunction ++ ++" Section: Comment delimiter add/removal functions {{{1 ++" ============================================================================ ++" Function: s:AppendCommentToLine(){{{2 ++" This function appends comment delimiters at the EOL and places the cursor in ++" position to start typing the comment ++function s:AppendCommentToLine() ++ let left = s:GetLeft(0,1,0) ++ let right = s:GetRight(0,1,0) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ let isLineEmpty = strlen(getline(".")) == 0 ++ let insOrApp = (isLineEmpty==1 ? 'i' : 'A') ++ ++ "stick the delimiters down at the end of the line. We have to format the ++ "comment with spaces as appropriate ++ execute ":normal " . insOrApp . (isLineEmpty ? '' : ' ') . left . right . " " ++ ++ " if there is a right delimiter then we gotta move the cursor left ++ " by the len of the right delimiter so we insert between the delimiters ++ if lenRight > 0 ++ let leftMoveAmount = lenRight ++ execute ":normal " . leftMoveAmount . "h" ++ endif ++ startinsert ++endfunction ++ ++" Function: s:CommentBlock(top, bottom, lSide, rSide, forceNested ) {{{2 ++" This function is used to comment out a region of code. This region is ++" specified as a bounding box by arguments to the function. ++" ++" Args: ++" -top: the line number for the top line of code in the region ++" -bottom: the line number for the bottom line of code in the region ++" -lSide: the column number for the left most column in the region ++" -rSide: the column number for the right most column in the region ++" -forceNested: a flag indicating whether comments should be nested ++function s:CommentBlock(top, bottom, lSide, rSide, forceNested ) ++ " we need to create local copies of these arguments so we can modify them ++ let top = a:top ++ let bottom = a:bottom ++ let lSide = a:lSide ++ let rSide = a:rSide ++ ++ "if the top or bottom line starts with tabs we have to adjust the left and ++ "right boundaries so that they are set as though the tabs were spaces ++ let topline = getline(top) ++ let bottomline = getline(bottom) ++ if s:HasLeadingTabs(topline, bottomline) ++ ++ "find out how many tabs are in the top line and adjust the left ++ "boundary accordingly ++ let numTabs = s:NumberOfLeadingTabs(topline) ++ if lSide < numTabs ++ let lSide = &ts * lSide ++ else ++ let lSide = (lSide - numTabs) + (&ts * numTabs) ++ endif ++ ++ "find out how many tabs are in the bottom line and adjust the right ++ "boundary accordingly ++ let numTabs = s:NumberOfLeadingTabs(bottomline) ++ let rSide = (rSide - numTabs) + (&ts * numTabs) ++ endif ++ ++ "we must check that bottom IS actually below top, if it is not then we ++ "swap top and bottom. Similarly for left and right. ++ if bottom < top ++ let temp = top ++ let top = bottom ++ let bottom = top ++ endif ++ if rSide < lSide ++ let temp = lSide ++ let lSide = rSide ++ let rSide = temp ++ endif ++ ++ "if the current delimiters arent multipart then we will switch to the ++ "alternative delims (if THEY are) as the comment will be better and more ++ "accurate with multipart delims ++ let switchedDelims = 0 ++ if !s:Multipart() && g:NERDAllowAnyVisualDelims && s:AltMultipart() ++ let switchedDelims = 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++ "start the commenting from the top and keep commenting till we reach the ++ "bottom ++ let currentLine=top ++ while currentLine <= bottom ++ ++ "check if we are allowed to comment this line ++ if s:CanCommentLine(a:forceNested, currentLine) ++ ++ "convert the leading tabs into spaces ++ let theLine = getline(currentLine) ++ let lineHasLeadTabs = s:HasLeadingTabs(theLine) ++ if lineHasLeadTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ ++ "dont comment lines that begin after the right boundary of the ++ "block unless the user has specified to do so ++ if theLine !~ '^ \{' . rSide . '\}' || !g:NERDBlockComIgnoreEmpty ++ ++ "attempt to place the cursor in on the left of the boundary box, ++ "then check if we were successful, if not then we cant comment this ++ "line ++ call setline(currentLine, theLine) ++ if s:CanPlaceCursor(currentLine, lSide) ++ ++ let leftSpaced = s:GetLeft(0,1,0) ++ let rightSpaced = s:GetRight(0,1,0) ++ ++ "stick the left delimiter down ++ let theLine = strpart(theLine, 0, lSide-1) . leftSpaced . strpart(theLine, lSide-1) ++ ++ if s:Multipart() ++ "stick the right delimiter down ++ let theLine = strpart(theLine, 0, rSide+strlen(leftSpaced)) . rightSpaced . strpart(theLine, rSide+strlen(rightSpaced)) ++ ++ let firstLeftDelim = s:FindDelimiterIndex(b:left, theLine) ++ let lastRightDelim = s:LastIndexOfDelim(b:right, theLine) ++ ++ if firstLeftDelim != -1 && lastRightDelim != -1 ++ let searchStr = strpart(theLine, 0, lastRightDelim) ++ let searchStr = strpart(searchStr, firstLeftDelim+strlen(b:left)) ++ ++ "replace the outter most delims in searchStr with ++ "place-holders ++ let theLineWithPlaceHolders = s:ReplaceDelims(b:left, b:right, g:NERDLPlace, g:NERDRPlace, searchStr) ++ ++ "add the right delimiter onto the line ++ let theLine = strpart(theLine, 0, firstLeftDelim+strlen(b:left)) . theLineWithPlaceHolders . strpart(theLine, lastRightDelim) ++ endif ++ endif ++ endif ++ endif ++ ++ "restore tabs if needed ++ if lineHasLeadTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ call setline(currentLine, theLine) ++ endif ++ ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "if we switched delims then we gotta go back to what they were before ++ if switchedDelims == 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++endfunction ++ ++" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2 ++" This function comments a range of lines. ++" ++" Args: ++" -forceNested: a flag indicating whether the called is requesting the comment ++" to be nested if need be ++" -alignRight/alignLeft: 0/1 if the comments delimiters should/shouldnt be ++" aligned left/right ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) ++ " we need to get the left and right indexes of the leftmost char in the ++ " block of of lines and the right most char so that we can do alignment of ++ " the delimiters if the user has specified ++ let leftAlignIndx = s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) ++ let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) ++ ++ " gotta add the length of the left delimiter onto the rightAlignIndx cos ++ " we'll be adding a left delim to the line ++ let rightAlignIndx = rightAlignIndx + strlen(s:GetLeft(0,1,0)) ++ ++ " now we actually comment the lines. Do it line by line ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ ++ " get the next line, check commentability and convert spaces to tabs ++ let theLine = getline(currentLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ if s:CanCommentLine(a:forceNested, currentLine) ++ "if the user has specified forceNesting then we check to see if we ++ "need to switch delimiters for place-holders ++ if a:forceNested && g:NERDUsePlaceHolders ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ endif ++ ++ " find out if the line is commented using normal delims and/or ++ " alternate ones ++ let isCommented = s:IsCommented(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine) ++ ++ " check if we can comment this line ++ if !isCommented || g:NERDUsePlaceHolders || s:Multipart() ++ if a:alignLeft ++ let theLine = s:AddLeftDelimAligned(b:left, theLine, leftAlignIndx) ++ else ++ let theLine = s:AddLeftDelim(s:GetLeft(0,1,0), theLine) ++ endif ++ if a:alignRight ++ let theLine = s:AddRightDelimAligned(b:right, theLine, rightAlignIndx) ++ else ++ let theLine = s:AddRightDelim(s:GetRight(0,1,0), theLine) ++ endif ++ endif ++ endif ++ ++ " restore leading tabs if appropriate ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ " we are done with this line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentLinesMinimal(firstLine, lastLine) {{{2 ++" This function comments a range of lines in a minimal style. I ++" ++" Args: ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLinesMinimal(firstLine, lastLine) ++ "check that minimal comments can be done on this filetype ++ if !s:HasMultipartDelims() ++ throw 'NERDCommenter.Delimiters exception: Minimal comments can only be used for filetypes that have multipart delimiters' ++ endif ++ ++ "if we need to use place holders for the comment, make sure they are ++ "enabled for this filetype ++ if !g:NERDUsePlaceHolders && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine) ++ throw 'NERDCommenter.Settings exception: Placeoholders are required but disabled.' ++ endif ++ ++ "get the left and right delims to smack on ++ let left = s:GetSexyComLeft(g:NERDSpaceDelims,0) ++ let right = s:GetSexyComRight(g:NERDSpaceDelims,0) ++ ++ "make sure all multipart delims on the lines are replaced with ++ "placeholders to prevent illegal syntax ++ let currentLine = a:firstLine ++ while(currentLine <= a:lastLine) ++ let theLine = getline(currentLine) ++ let theLine = s:ReplaceDelims(left, right, g:NERDLPlace, g:NERDRPlace, theLine) ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "add the delim to the top line ++ let theLine = getline(a:firstLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let theLine = s:AddLeftDelim(left, theLine) ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:firstLine, theLine) ++ ++ "add the delim to the bottom line ++ let theLine = getline(a:lastLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let theLine = s:AddRightDelim(right, theLine) ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:lastLine, theLine) ++endfunction ++ ++" Function: s:CommentLinesSexy(topline, bottomline) function {{{2 ++" This function is used to comment lines in the 'Sexy' style. eg in c: ++" /* ++" * This is a sexy comment ++" */ ++" Args: ++" -topline: the line num of the top line in the sexy comment ++" -bottomline: the line num of the bottom line in the sexy comment ++function s:CommentLinesSexy(topline, bottomline) ++ let left = s:GetSexyComLeft(0, 0) ++ let right = s:GetSexyComRight(0, 0) ++ ++ "check if we can do a sexy comment with the available delimiters ++ if left == -1 || right == -1 ++ throw 'NERDCommenter.Delimiters exception: cannot perform sexy comments with available delimiters.' ++ endif ++ ++ "make sure the lines arent already commented sexually ++ if !s:CanSexyCommentLines(a:topline, a:bottomline) ++ throw 'NERDCommenter.Nesting exception: cannot nest sexy comments' ++ endif ++ ++ ++ let sexyComMarker = s:GetSexyComMarker(0,0) ++ let sexyComMarkerSpaced = s:GetSexyComMarker(1,0) ++ ++ ++ " we jam the comment as far to the right as possible ++ let leftAlignIndx = s:LeftMostIndx(1, 1, a:topline, a:bottomline) ++ ++ "check if we should use the compact style i.e that the left/right ++ "delimiters should appear on the first and last lines of the code and not ++ "on separate lines above/below the first/last lines of code ++ if g:NERDCompactSexyComs ++ let spaceString = (g:NERDSpaceDelims ? s:spaceStr : '') ++ ++ "comment the top line ++ let theLine = getline(a:topline) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ let theLine = s:AddLeftDelimAligned(left . spaceString, theLine, leftAlignIndx) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:topline, theLine) ++ ++ "comment the bottom line ++ let theLine = getline(a:bottomline) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ let theLine = s:AddRightDelim(spaceString . right, theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:bottomline, theLine) ++ else ++ ++ " add the left delimiter one line above the lines that are to be commented ++ call cursor(a:topline, 1) ++ execute 'normal! O' ++ call setline(a:topline, strpart(s:spaces, 0, leftAlignIndx) . left ) ++ ++ " add the right delimiter after bottom line (we have to add 1 cos we moved ++ " the lines down when we added the left delim ++ call cursor(a:bottomline+1, 1) ++ execute 'normal! o' ++ call setline(a:bottomline+2, strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, strlen(left)-strlen(sexyComMarker)) . right ) ++ ++ endif ++ ++ " go thru each line adding the sexyComMarker marker to the start of each ++ " line in the appropriate place to align them with the comment delims ++ let currentLine = a:topline+1 ++ while currentLine <= a:bottomline + !g:NERDCompactSexyComs ++ " get the line and convert the tabs to spaces ++ let theLine = getline(currentLine) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ ++ " add the sexyComMarker ++ let theLine = strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, strlen(left)-strlen(sexyComMarker)) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx) ++ ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ ++ " set the line and move onto the next one ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentLinesToggle(forceNested, firstLine, lastLine) {{{2 ++" Applies "toggle" commenting to the given range of lines ++" ++" Args: ++" -forceNested: a flag indicating whether the called is requesting the comment ++" to be nested if need be ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLinesToggle(forceNested, firstLine, lastLine) ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ ++ " get the next line, check commentability and convert spaces to tabs ++ let theLine = getline(currentLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ if s:CanToggleCommentLine(a:forceNested, currentLine) ++ ++ "if the user has specified forceNesting then we check to see if we ++ "need to switch delimiters for place-holders ++ if g:NERDUsePlaceHolders ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ endif ++ ++ let theLine = s:AddLeftDelim(s:GetLeft(0, 1, 0), theLine) ++ let theLine = s:AddRightDelim(s:GetRight(0, 1, 0), theLine) ++ endif ++ ++ " restore leading tabs if appropriate ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ " we are done with this line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentRegion(topline, topCol, bottomLine, bottomCol) function {{{2 ++" This function comments chunks of text selected in visual mode. ++" It will comment exactly the text that they have selected. ++" Args: ++" -topLine: the line num of the top line in the sexy comment ++" -topCol: top left col for this comment ++" -bottomline: the line num of the bottom line in the sexy comment ++" -bottomCol: the bottom right col for this comment ++" -forceNested: whether the caller wants comments to be nested if the ++" line(s) are already commented ++function s:CommentRegion(topLine, topCol, bottomLine, bottomCol, forceNested) ++ ++ "switch delims (if we can) if the current set isnt multipart ++ let switchedDelims = 0 ++ if !s:Multipart() && s:AltMultipart() && !g:NERDAllowAnyVisualDelims ++ let switchedDelims = 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++ "if there is only one line in the comment then just do it ++ if a:topLine == a:bottomLine ++ call s:CommentBlock(a:topLine, a:bottomLine, a:topCol, a:bottomCol, a:forceNested) ++ ++ "there are multiple lines in the comment ++ else ++ "comment the top line ++ call s:CommentBlock(a:topLine, a:topLine, a:topCol, strlen(getline(a:topLine)), a:forceNested) ++ ++ "comment out all the lines in the middle of the comment ++ let topOfRange = a:topLine+1 ++ let bottomOfRange = a:bottomLine-1 ++ if topOfRange <= bottomOfRange ++ call s:CommentLines(a:forceNested, 0, 0, topOfRange, bottomOfRange) ++ endif ++ ++ "comment the bottom line ++ let bottom = getline(a:bottomLine) ++ let numLeadingSpacesTabs = strlen(substitute(bottom, '^\([ \t]*\).*$', '\1', '')) ++ call s:CommentBlock(a:bottomLine, a:bottomLine, numLeadingSpacesTabs+1, a:bottomCol, a:forceNested) ++ ++ endif ++ ++ "stick the cursor back on the char it was on before the comment ++ call cursor(a:topLine, a:topCol + strlen(b:left) + g:NERDSpaceDelims) ++ ++ "if we switched delims then we gotta go back to what they were before ++ if switchedDelims == 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++endfunction ++ ++" Function: s:InvertComment(firstLine, lastLine) function {{{2 ++" Inverts the comments on the lines between and including the given line ++" numbers i.e all commented lines are uncommented and vice versa ++" Args: ++" -firstLine: the top of the range of lines to be inverted ++" -lastLine: the bottom of the range of lines to be inverted ++function s:InvertComment(firstLine, lastLine) ++ ++ " go thru all lines in the given range ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ let theLine = getline(currentLine) ++ ++ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) ++ ++ " if the line is commented normally, uncomment it ++ if s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine) ++ call s:UncommentLines(1, currentLine, currentLine) ++ let currentLine = currentLine + 1 ++ ++ " check if the line is commented sexually ++ elseif !empty(sexyComBounds) ++ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() ++ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) ++ ++ "move to the line after last line of the sexy comment ++ let numLinesAfterSexyComRemoved = s:NumLinesInBuf() ++ let currentLine = bottomBound - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1 ++ ++ " the line isnt commented ++ else ++ call s:CommentLinesToggle(1, currentLine, currentLine) ++ let currentLine = currentLine + 1 ++ endif ++ ++ endwhile ++endfunction ++ ++" Function: NERDComment(isVisual, alignLeft, alignRight, type) function {{{2 ++" This function is a Wrapper for the main commenting functions ++" ++" Args: ++" -isVisual: a flag indicating whether the comment is requested in visual ++" mode or not ++" -type: the type of commenting requested. Can be 'sexy', 'invert', ++" 'minimal', 'toggle', 'alignLeft', 'alignRight', 'alignBoth', 'norm', ++" 'nested', 'toEOL', 'prepend', 'append', 'insert', 'uncomment', 'yank' ++function! NERDComment(isVisual, type) range ++ " we want case sensitivity when commenting ++ let prevIgnoreCase = &ignorecase ++ set noignorecase ++ ++ if a:isVisual ++ let firstLine = line("'<") ++ let lastLine = line("'>") ++ let firstCol = col("'<") ++ let lastCol = col("'>") ++ else ++ let firstLine = a:firstline ++ let lastLine = a:lastline ++ endif ++ ++ let countWasGiven = (a:isVisual == 0 && firstLine != lastLine) ++ ++ let forceNested = (a:type == 'nested' || g:NERDDefaultNesting) ++ ++ if a:type == 'norm' || a:type == 'nested' ++ if a:isVisual && visualmode() == "" ++ call s:CommentBlock(firstLine, lastLine, firstCol, lastCol, forceNested) ++ elseif a:isVisual && visualmode() == "v" && (g:NERDCommentWholeLinesInVMode==0 || (g:NERDCommentWholeLinesInVMode==2 && s:HasMultipartDelims())) ++ call s:CommentRegion(firstLine, firstCol, lastLine, lastCol, forceNested) ++ else ++ call s:CommentLines(forceNested, 0, 0, firstLine, lastLine) ++ endif ++ ++ elseif a:type == 'alignLeft' || a:type == 'alignRight' || a:type == 'alignBoth' ++ let alignLeft = (a:type == 'alignLeft' || a:type == 'alignBoth') ++ let alignRight = (a:type == 'alignRight' || a:type == 'alignBoth') ++ call s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) ++ ++ elseif a:type == 'invert' ++ call s:InvertComment(firstLine, lastLine) ++ ++ elseif a:type == 'sexy' ++ try ++ call s:CommentLinesSexy(firstLine, lastLine) ++ catch /NERDCommenter.Delimiters/ ++ call s:NerdEcho("Sexy comments cannot be done with the available delimiters", 0) ++ catch /NERDCommenter.Nesting/ ++ call s:NerdEcho("Sexy comment aborted. Nested sexy cannot be nested", 0) ++ endtry ++ ++ elseif a:type == 'toggle' ++ let theLine = getline(firstLine) ++ ++ if s:IsInSexyComment(firstLine) || s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine) ++ call s:UncommentLines(1, firstLine, lastLine) ++ else ++ call s:CommentLinesToggle(forceNested, firstLine, lastLine) ++ endif ++ ++ elseif a:type == 'minimal' ++ try ++ call s:CommentLinesMinimal(firstLine, lastLine) ++ catch /NERDCommenter.Delimiters/ ++ call s:NerdEcho("Minimal comments can only be used for filetypes that have multipart delimiters.", 0) ++ catch /NERDCommenter.Settings/ ++ call s:NerdEcho("Place holders are required but disabled.", 0) ++ endtry ++ ++ elseif a:type == 'toEOL' ++ call s:SaveScreenState() ++ call s:CommentBlock(firstLine, firstLine, col("."), col("$")-1, 1) ++ call s:RestoreScreenState() ++ ++ elseif a:type == 'prepend' ++ call s:PrependCommentToLine() ++ ++ elseif a:type == 'append' ++ call s:AppendCommentToLine() ++ ++ elseif a:type == 'insert' ++ call s:PlaceDelimitersAndInsBetween() ++ ++ elseif a:type == 'uncomment' ++ call s:UncommentLines(0, firstLine, lastLine) ++ ++ elseif a:type == 'yank' ++ if a:isVisual ++ normal gvy ++ elseif countWasGiven ++ execute firstLine .','. lastLine .'yank' ++ else ++ normal Y ++ endif ++ execute firstLine .','. lastLine .'call NERDComment('. a:isVisual .', "norm")' ++ endif ++ ++ let &ignorecase = prevIgnoreCase ++endfunction ++ ++" Function: s:PlaceDelimitersAndInsBetween() function {{{2 ++" This is function is called to place comment delimiters down and place the ++" cursor between them ++function s:PlaceDelimitersAndInsBetween() ++ " get the left and right delimiters without any escape chars in them ++ let left = s:GetLeft(0, 1, 0) ++ let right = s:GetRight(0, 1, 0) ++ ++ let theLine = getline(".") ++ let lineHasLeadTabs = s:HasLeadingTabs(theLine) || (theLine =~ '^ *$' && !&expandtab) ++ ++ "convert tabs to spaces and adjust the cursors column to take this into ++ "account ++ let untabbedCol = s:UntabbedCol(theLine, col(".")) ++ call setline(line("."), s:ConvertLeadingTabsToSpaces(theLine)) ++ call cursor(line("."), untabbedCol) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ let isDelimOnEOL = col(".") >= strlen(getline(".")) ++ ++ " if the cursor is in the first col then we gotta insert rather than ++ " append the comment delimiters here ++ let insOrApp = (col(".")==1 ? 'i' : 'a') ++ ++ " place the delimiters down. We do it differently depending on whether ++ " there is a left AND right delimiter ++ if lenRight > 0 ++ execute ":normal " . insOrApp . left . right ++ execute ":normal " . lenRight . "h" ++ else ++ execute ":normal " . insOrApp . left ++ ++ " if we are tacking the delim on the EOL then we gotta add a space ++ " after it cos when we go out of insert mode the cursor will move back ++ " one and the user wont be in position to type the comment. ++ if isDelimOnEOL ++ execute 'normal a ' ++ endif ++ endif ++ normal l ++ ++ "if needed convert spaces back to tabs and adjust the cursors col ++ "accordingly ++ if lineHasLeadTabs ++ let tabbedCol = s:TabbedCol(getline("."), col(".")) ++ call setline(line("."), s:ConvertLeadingSpacesToTabs(getline("."))) ++ call cursor(line("."), tabbedCol) ++ endif ++ ++ startinsert ++endfunction ++ ++" Function: s:PrependCommentToLine(){{{2 ++" This function prepends comment delimiters to the start of line and places ++" the cursor in position to start typing the comment ++function s:PrependCommentToLine() ++ " get the left and right delimiters without any escape chars in them ++ let left = s:GetLeft(0, 1, 0) ++ let right = s:GetRight(0, 1, 0) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ ++ "if the line is empty then we need to know about this later on ++ let isLineEmpty = strlen(getline(".")) == 0 ++ ++ "stick the delimiters down at the start of the line. We have to format the ++ "comment with spaces as appropriate ++ if lenRight > 0 ++ execute ":normal I" . left . right ++ else ++ execute ":normal I" . left ++ endif ++ ++ " if there is a right delimiter then we gotta move the cursor left ++ " by the len of the right delimiter so we insert between the delimiters ++ if lenRight > 0 ++ let leftMoveAmount = lenRight ++ execute ":normal " . leftMoveAmount . "h" ++ endif ++ normal l ++ ++ "if the line was empty then we gotta add an extra space on the end because ++ "the cursor will move back one more at the end of the last "execute" ++ "command ++ if isLineEmpty && lenRight == 0 ++ execute ":normal a " ++ endif ++ ++ startinsert ++endfunction ++" Function: s:RemoveDelimiters(left, right, line) {{{2 ++" this function is called to remove the first left comment delimiter and the ++" last right delimiter of the given line. ++" ++" The args left and right must be strings. If there is no right delimiter (as ++" is the case for e.g vim file comments) them the arg right should be "" ++" ++" Args: ++" -left: the left comment delimiter ++" -right: the right comment delimiter ++" -line: the line to remove the delimiters from ++function s:RemoveDelimiters(left, right, line) ++ ++ let l:left = a:left ++ let l:right = a:right ++ let lenLeft = strlen(left) ++ let lenRight = strlen(right) ++ ++ let delimsSpaced = (g:NERDSpaceDelims || g:NERDRemoveExtraSpaces) ++ ++ let line = a:line ++ ++ "look for the left delimiter, if we find it, remove it. ++ let leftIndx = s:FindDelimiterIndex(a:left, line) ++ if leftIndx != -1 ++ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+lenLeft) ++ ++ "if the user has specified that there is a space after the left delim ++ "then check for the space and remove it if it is there ++ if delimsSpaced && strpart(line, leftIndx, s:lenSpaceStr) == s:spaceStr ++ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+s:lenSpaceStr) ++ endif ++ endif ++ ++ "look for the right delimiter, if we find it, remove it ++ let rightIndx = s:FindDelimiterIndex(a:right, line) ++ if rightIndx != -1 ++ let line = strpart(line, 0, rightIndx) . strpart(line, rightIndx+lenRight) ++ ++ "if the user has specified that there is a space before the right delim ++ "then check for the space and remove it if it is there ++ if delimsSpaced && strpart(line, rightIndx-s:lenSpaceStr, s:lenSpaceStr) == s:spaceStr && s:Multipart() ++ let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx) ++ endif ++ endif ++ ++ return line ++endfunction ++ ++" Function: s:UncommentLines(onlyWholeLineComs, topLine, bottomLine) {{{2 ++" This function uncomments the given lines ++" ++" Args: ++" onlyWholeLineComs: should be 1 for toggle style uncommenting ++" topLine: the top line of the visual selection to uncomment ++" bottomLine: the bottom line of the visual selection to uncomment ++function s:UncommentLines(onlyWholeLineComs, topLine, bottomLine) ++ "make local copies of a:firstline and a:lastline and, if need be, swap ++ "them around if the top line is below the bottom ++ let l:firstline = a:topLine ++ let l:lastline = a:bottomLine ++ if firstline > lastline ++ let firstline = lastline ++ let lastline = a:topLine ++ endif ++ ++ "go thru each line uncommenting each line removing sexy comments ++ let currentLine = firstline ++ while currentLine <= lastline ++ ++ "check the current line to see if it is part of a sexy comment ++ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) ++ if !empty(sexyComBounds) ++ ++ "we need to store the num lines in the buf before the comment is ++ "removed so we know how many lines were removed when the sexy com ++ "was removed ++ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() ++ ++ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) ++ ++ "move to the line after last line of the sexy comment ++ let numLinesAfterSexyComRemoved = s:NumLinesInBuf() ++ let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved ++ let currentLine = sexyComBounds[1] - numLinesRemoved + 1 ++ let lastline = lastline - numLinesRemoved ++ ++ "no sexy com was detected so uncomment the line as normal ++ else ++ let theLine = getline(currentLine) ++ if a:onlyWholeLineComs && (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)) ++ call s:UncommentLinesNormal(currentLine, currentLine) ++ elseif !a:onlyWholeLineComs ++ call s:UncommentLinesNormal(currentLine, currentLine) ++ endif ++ let currentLine = currentLine + 1 ++ endif ++ endwhile ++ ++endfunction ++ ++" Function: s:UncommentLinesSexy(topline, bottomline) {{{2 ++" This function removes all the comment characters associated with the sexy ++" comment spanning the given lines ++" Args: ++" -topline/bottomline: the top/bottom lines of the sexy comment ++function s:UncommentLinesSexy(topline, bottomline) ++ let left = s:GetSexyComLeft(0,1) ++ let right = s:GetSexyComRight(0,1) ++ ++ ++ "check if it is even possible for sexy comments to exist with the ++ "available delimiters ++ if left == -1 || right == -1 ++ throw 'NERDCommenter.Delimiters exception: cannot uncomment sexy comments with available delimiters.' ++ endif ++ ++ let leftUnEsc = s:GetSexyComLeft(0,0) ++ let rightUnEsc = s:GetSexyComRight(0,0) ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ let sexyComMarkerUnEsc = s:GetSexyComMarker(0, 0) ++ ++ "the markerOffset is how far right we need to move the sexyComMarker to ++ "line it up with the end of the left delim ++ let markerOffset = strlen(leftUnEsc)-strlen(sexyComMarkerUnEsc) ++ ++ " go thru the intermediate lines of the sexy comment and remove the ++ " sexy comment markers (eg the '*'s on the start of line in a c sexy ++ " comment) ++ let currentLine = a:topline+1 ++ while currentLine < a:bottomline ++ let theLine = getline(currentLine) ++ ++ " remove the sexy comment marker from the line. We also remove the ++ " space after it if there is one and if appropriate options are set ++ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) ++ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) ++ endif ++ ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ ++ let theLine = s:ConvertLeadingWhiteSpace(theLine) ++ ++ " move onto the next line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ " gotta make a copy of a:bottomline cos we modify the position of the ++ " last line it if we remove the topline ++ let bottomline = a:bottomline ++ ++ " get the first line so we can remove the left delim from it ++ let theLine = getline(a:topline) ++ ++ " if the first line contains only the left delim then just delete it ++ if theLine =~ '^[ \t]*' . left . '[ \t]*$' && !g:NERDCompactSexyComs ++ call cursor(a:topline, 1) ++ normal dd ++ let bottomline = bottomline - 1 ++ ++ " topline contains more than just the left delim ++ else ++ ++ " remove the delim. If there is a space after it ++ " then remove this too if appropriate ++ let delimIndx = stridx(theLine, leftUnEsc) ++ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)) ++ endif ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ call setline(a:topline, theLine) ++ endif ++ ++ " get the last line so we can remove the right delim ++ let theLine = getline(bottomline) ++ ++ " if the bottomline contains only the right delim then just delete it ++ if theLine =~ '^[ \t]*' . right . '[ \t]*$' ++ call cursor(bottomline, 1) ++ normal dd ++ ++ " the last line contains more than the right delim ++ else ++ " remove the right delim. If there is a space after it and ++ " if the appropriate options are set then remove this too. ++ let delimIndx = s:LastIndexOfDelim(rightUnEsc, theLine) ++ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)) ++ endif ++ ++ " if the last line also starts with a sexy comment marker then we ++ " remove this as well ++ if theLine =~ '^[ \t]*' . sexyComMarker ++ ++ " remove the sexyComMarker. If there is a space after it then ++ " remove that too ++ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) ++ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) ++ endif ++ endif ++ ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ call setline(bottomline, theLine) ++ endif ++endfunction ++ ++" Function: s:UncommentLineNormal(line) {{{2 ++" uncomments the given line and returns the result ++" Args: ++" -line: the line to uncomment ++function s:UncommentLineNormal(line) ++ let line = a:line ++ ++ "get the comment status on the line so we know how it is commented ++ let lineCommentStatus = s:IsCommentedOuttermost(b:leftAlt, b:rightAlt, b:left, b:right, line) ++ ++ "it is commented with b:left and b:right so remove these delims ++ if lineCommentStatus == 1 ++ let line = s:RemoveDelimiters(b:leftAlt, b:rightAlt, line) ++ ++ "it is commented with b:leftAlt and b:rightAlt so remove these delims ++ elseif lineCommentStatus == 2 && g:NERDRemoveAltComs ++ let line = s:RemoveDelimiters(b:left, b:right, line) ++ ++ "it is not properly commented with any delims so we check if it has ++ "any random left or right delims on it and remove the outtermost ones ++ else ++ "get the positions of all delim types on the line ++ let indxLeft = s:FindDelimiterIndex(b:left, line) ++ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line) ++ let indxRight = s:FindDelimiterIndex(b:right, line) ++ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line) ++ ++ "remove the outter most left comment delim ++ if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1) ++ let line = s:ReplaceLeftMostDelim(b:left, '', line) ++ elseif indxLeftAlt != -1 ++ let line = s:ReplaceLeftMostDelim(b:leftAlt, '', line) ++ endif ++ ++ "remove the outter most right comment delim ++ if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1) ++ let line = s:ReplaceRightMostDelim(b:right, '', line) ++ elseif indxRightAlt != -1 ++ let line = s:ReplaceRightMostDelim(b:rightAlt, '', line) ++ endif ++ endif ++ ++ ++ let indxLeft = s:FindDelimiterIndex(b:left, line) ++ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line) ++ let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line) ++ ++ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) ++ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line) ++ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) ++ ++ let right = b:right ++ let left = b:left ++ if !s:Multipart() ++ let right = b:rightAlt ++ let left = b:leftAlt ++ endif ++ ++ ++ "if there are place-holders on the line then we check to see if they are ++ "the outtermost delimiters on the line. If so then we replace them with ++ "real delimiters ++ if indxLeftPlace != -1 ++ if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) ++ endif ++ elseif indxRightPlace != -1 ++ if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) ++ endif ++ ++ endif ++ ++ let line = s:ConvertLeadingWhiteSpace(line) ++ ++ return line ++endfunction ++ ++" Function: s:UncommentLinesNormal(topline, bottomline) {{{2 ++" This function is called to uncomment lines that arent a sexy comment ++" Args: ++" -topline/bottomline: the top/bottom line numbers of the comment ++function s:UncommentLinesNormal(topline, bottomline) ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ let line = getline(currentLine) ++ call setline(currentLine, s:UncommentLineNormal(line)) ++ let currentLine = currentLine + 1 ++ endwhile ++endfunction ++ ++ ++" Section: Other helper functions {{{1 ++" ============================================================================ ++ ++" Function: s:AddLeftDelim(delim, theLine) {{{2 ++" Args: ++function s:AddLeftDelim(delim, theLine) ++ return substitute(a:theLine, '^\([ \t]*\)', '\1' . a:delim, '') ++endfunction ++ ++" Function: s:AddLeftDelimAligned(delim, theLine) {{{2 ++" Args: ++function s:AddLeftDelimAligned(delim, theLine, alignIndx) ++ ++ "if the line is not long enough then bung some extra spaces on the front ++ "so we can align the delim properly ++ let theLine = a:theLine ++ if strlen(theLine) < a:alignIndx ++ let theLine = strpart(s:spaces, 0, a:alignIndx - strlen(theLine)) ++ endif ++ ++ return strpart(theLine, 0, a:alignIndx) . a:delim . strpart(theLine, a:alignIndx) ++endfunction ++ ++" Function: s:AddRightDelim(delim, theLine) {{{2 ++" Args: ++function s:AddRightDelim(delim, theLine) ++ if a:delim == '' ++ return a:theLine ++ else ++ return substitute(a:theLine, '$', a:delim, '') ++ endif ++endfunction ++ ++" Function: s:AddRightDelimAligned(delim, theLine, alignIndx) {{{2 ++" Args: ++function s:AddRightDelimAligned(delim, theLine, alignIndx) ++ if a:delim == "" ++ return a:theLine ++ else ++ ++ " when we align the right delim we are just adding spaces ++ " so we get a string containing the needed spaces (it ++ " could be empty) ++ let extraSpaces = '' ++ let extraSpaces = strpart(s:spaces, 0, a:alignIndx-strlen(a:theLine)) ++ ++ " add the right delim ++ return substitute(a:theLine, '$', extraSpaces . a:delim, '') ++ endif ++endfunction ++ ++" Function: s:AltMultipart() {{{2 ++" returns 1 if the alternative delims are multipart ++function s:AltMultipart() ++ return b:rightAlt != '' ++endfunction ++ ++" Function: s:CanCommentLine(forceNested, line) {{{2 ++"This function is used to determine whether the given line can be commented. ++"It returns 1 if it can be and 0 otherwise ++" ++" Args: ++" -forceNested: a flag indicating whether the caller wants comments to be nested ++" if the current line is already commented ++" -lineNum: the line num of the line to check for commentability ++function s:CanCommentLine(forceNested, lineNum) ++ let theLine = getline(a:lineNum) ++ ++ " make sure we don't comment lines that are just spaces or tabs or empty. ++ if theLine =~ "^[ \t]*$" ++ return 0 ++ endif ++ ++ "if the line is part of a sexy comment then just flag it... ++ if s:IsInSexyComment(a:lineNum) ++ return 0 ++ endif ++ ++ let isCommented = s:IsCommentedNormOrSexy(a:lineNum) ++ ++ "if the line isnt commented return true ++ if !isCommented ++ return 1 ++ endif ++ ++ "if the line is commented but nesting is allowed then return true ++ if a:forceNested && (!s:Multipart() || g:NERDUsePlaceHolders) ++ return 1 ++ endif ++ ++ return 0 ++endfunction ++ ++" Function: s:CanPlaceCursor(line, col) {{{2 ++" returns 1 if the cursor can be placed exactly in the given position ++function s:CanPlaceCursor(line, col) ++ let c = col(".") ++ let l = line(".") ++ call cursor(a:line, a:col) ++ let success = (line(".") == a:line && col(".") == a:col) ++ call cursor(l,c) ++ return success ++endfunction ++ ++" Function: s:CanSexyCommentLines(topline, bottomline) {{{2 ++" Return: 1 if the given lines can be commented sexually, 0 otherwise ++function s:CanSexyCommentLines(topline, bottomline) ++ " see if the selected regions have any sexy comments ++ let currentLine = a:topline ++ while(currentLine <= a:bottomline) ++ if s:IsInSexyComment(currentLine) ++ return 0 ++ endif ++ let currentLine = currentLine + 1 ++ endwhile ++ return 1 ++endfunction ++" Function: s:CanToggleCommentLine(forceNested, line) {{{2 ++"This function is used to determine whether the given line can be toggle commented. ++"It returns 1 if it can be and 0 otherwise ++" ++" Args: ++" -lineNum: the line num of the line to check for commentability ++function s:CanToggleCommentLine(forceNested, lineNum) ++ let theLine = getline(a:lineNum) ++ if (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)) && !a:forceNested ++ return 0 ++ endif ++ ++ " make sure we don't comment lines that are just spaces or tabs or empty. ++ if theLine =~ "^[ \t]*$" ++ return 0 ++ endif ++ ++ "if the line is part of a sexy comment then just flag it... ++ if s:IsInSexyComment(a:lineNum) ++ return 0 ++ endif ++ ++ return 1 ++endfunction ++ ++" Function: s:ConvertLeadingSpacesToTabs(line) {{{2 ++" This function takes a line and converts all leading tabs on that line into ++" spaces ++" ++" Args: ++" -line: the line whose leading tabs will be converted ++function s:ConvertLeadingSpacesToTabs(line) ++ let toReturn = a:line ++ while toReturn =~ '^\t*' . s:TabSpace() . '\(.*\)$' ++ let toReturn = substitute(toReturn, '^\(\t*\)' . s:TabSpace() . '\(.*\)$' , '\1\t\2' , "") ++ endwhile ++ ++ return toReturn ++endfunction ++ ++ ++" Function: s:ConvertLeadingTabsToSpaces(line) {{{2 ++" This function takes a line and converts all leading spaces on that line into ++" tabs ++" ++" Args: ++" -line: the line whose leading spaces will be converted ++function s:ConvertLeadingTabsToSpaces(line) ++ let toReturn = a:line ++ while toReturn =~ '^\( *\)\t' ++ let toReturn = substitute(toReturn, '^\( *\)\t', '\1' . s:TabSpace() , "") ++ endwhile ++ ++ return toReturn ++endfunction ++ ++" Function: s:ConvertLeadingWhiteSpace(line) {{{2 ++" Converts the leading white space to tabs/spaces depending on &ts ++" ++" Args: ++" -line: the line to convert ++function s:ConvertLeadingWhiteSpace(line) ++ let toReturn = a:line ++ while toReturn =~ '^ *\t' ++ let toReturn = substitute(toReturn, '^ *\zs\t\ze', s:TabSpace(), "g") ++ endwhile ++ ++ if !&expandtab ++ let toReturn = s:ConvertLeadingSpacesToTabs(toReturn) ++ endif ++ ++ return toReturn ++endfunction ++ ++ ++" Function: s:CountNonESCedOccurances(str, searchstr, escChar) {{{2 ++" This function counts the number of substrings contained in another string. ++" These substrings are only counted if they are not escaped with escChar ++" Args: ++" -str: the string to look for searchstr in ++" -searchstr: the substring to search for in str ++" -escChar: the escape character which, when preceding an instance of ++" searchstr, will cause it not to be counted ++function s:CountNonESCedOccurances(str, searchstr, escChar) ++ "get the index of the first occurrence of searchstr ++ let indx = stridx(a:str, a:searchstr) ++ ++ "if there is an instance of searchstr in str process it ++ if indx != -1 ++ "get the remainder of str after this instance of searchstr is removed ++ let lensearchstr = strlen(a:searchstr) ++ let strLeft = strpart(a:str, indx+lensearchstr) ++ ++ "if this instance of searchstr is not escaped, add one to the count ++ "and recurse. If it is escaped, just recurse ++ if !s:IsEscaped(a:str, indx, a:escChar) ++ return 1 + s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) ++ else ++ return s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) ++ endif ++ endif ++endfunction ++" Function: s:DoesBlockHaveDelim(delim, top, bottom) {{{2 ++" Returns 1 if the given block of lines has a delimiter (a:delim) in it ++" Args: ++" -delim: the comment delimiter to check the block for ++" -top: the top line number of the block ++" -bottom: the bottom line number of the block ++function s:DoesBlockHaveDelim(delim, top, bottom) ++ let currentLine = a:top ++ while currentLine < a:bottom ++ let theline = getline(currentLine) ++ if s:FindDelimiterIndex(a:delim, theline) != -1 ++ return 1 ++ endif ++ let currentLine = currentLine + 1 ++ endwhile ++ return 0 ++endfunction ++ ++" Function: s:DoesBlockHaveMultipartDelim(top, bottom) {{{2 ++" Returns 1 if the given block has a >= 1 multipart delimiter in it ++" Args: ++" -top: the top line number of the block ++" -bottom: the bottom line number of the block ++function s:DoesBlockHaveMultipartDelim(top, bottom) ++ if s:HasMultipartDelims() ++ if s:Multipart() ++ return s:DoesBlockHaveDelim(b:left, a:top, a:bottom) || s:DoesBlockHaveDelim(b:right, a:top, a:bottom) ++ else ++ return s:DoesBlockHaveDelim(b:leftAlt, a:top, a:bottom) || s:DoesBlockHaveDelim(b:rightAlt, a:top, a:bottom) ++ endif ++ endif ++ return 0 ++endfunction ++ ++ ++" Function: s:Esc(str) {{{2 ++" Escapes all the tricky chars in the given string ++function s:Esc(str) ++ let charsToEsc = '*/\."&$+' ++ return escape(a:str, charsToEsc) ++endfunction ++ ++" Function: s:FindDelimiterIndex(delimiter, line) {{{2 ++" This function is used to get the string index of the input comment delimiter ++" on the input line. If no valid comment delimiter is found in the line then ++" -1 is returned ++" Args: ++" -delimiter: the delimiter we are looking to find the index of ++" -line: the line we are looking for delimiter on ++function s:FindDelimiterIndex(delimiter, line) ++ ++ "make sure the delimiter isnt empty otherwise we go into an infinite loop. ++ if a:delimiter == "" ++ return -1 ++ endif ++ ++ ++ let l:delimiter = a:delimiter ++ let lenDel = strlen(l:delimiter) ++ ++ "get the index of the first occurrence of the delimiter ++ let delIndx = stridx(a:line, l:delimiter) ++ ++ "keep looping thru the line till we either find a real comment delimiter ++ "or run off the EOL ++ while delIndx != -1 ++ ++ "if we are not off the EOL get the str before the possible delimiter ++ "in question and check if it really is a delimiter. If it is, return ++ "its position ++ if delIndx != -1 ++ if s:IsDelimValid(l:delimiter, delIndx, a:line) ++ return delIndx ++ endif ++ endif ++ ++ "we have not yet found a real comment delimiter so move past the ++ "current one we are lookin at ++ let restOfLine = strpart(a:line, delIndx + lenDel) ++ let distToNextDelim = stridx(restOfLine , l:delimiter) ++ ++ "if distToNextDelim is -1 then there is no more potential delimiters ++ "on the line so set delIndx to -1. Otherwise, move along the line by ++ "distToNextDelim ++ if distToNextDelim == -1 ++ let delIndx = -1 ++ else ++ let delIndx = delIndx + lenDel + distToNextDelim ++ endif ++ endwhile ++ ++ "there is no comment delimiter on this line ++ return -1 ++endfunction ++ ++" Function: s:FindBoundingLinesOfSexyCom(lineNum) {{{2 ++" This function takes in a line number and tests whether this line number is ++" the top/bottom/middle line of a sexy comment. If it is then the top/bottom ++" lines of the sexy comment are returned ++" Args: ++" -lineNum: the line number that is to be tested whether it is the ++" top/bottom/middle line of a sexy com ++" Returns: ++" A string that has the top/bottom lines of the sexy comment encoded in it. ++" The format is 'topline,bottomline'. If a:lineNum turns out not to be the ++" top/bottom/middle of a sexy comment then -1 is returned ++function s:FindBoundingLinesOfSexyCom(lineNum) ++ ++ "find which delimiters to look for as the start/end delims of the comment ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = s:GetLeft(0,0,1) ++ let right = s:GetRight(0,0,1) ++ elseif s:AltMultipart() ++ let left = s:GetLeft(1,0,1) ++ let right = s:GetRight(1,0,1) ++ else ++ return [] ++ endif ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ ++ "initialise the top/bottom line numbers of the sexy comment to -1 ++ let top = -1 ++ let bottom = -1 ++ ++ let currentLine = a:lineNum ++ while top == -1 || bottom == -1 ++ let theLine = getline(currentLine) ++ ++ "check if the current line is the top of the sexy comment ++ if theLine =~ '^[ \t]*' . left && theLine !~ '.*' . right ++ let top = currentLine ++ let currentLine = a:lineNum ++ ++ "check if the current line is the bottom of the sexy comment ++ elseif theLine =~ '^[ \t]*' . right && theLine !~ '.*' . left ++ let bottom = currentLine ++ ++ "the right delimiter is on the same line as the last sexyComMarker ++ elseif theLine =~ '^[ \t]*' . sexyComMarker . '.*' . right ++ let bottom = currentLine ++ ++ "we have not found the top or bottom line so we assume currentLine is an ++ "intermediate line and look to prove otherwise ++ else ++ ++ "if the line doesnt start with a sexyComMarker then it is not a sexy ++ "comment ++ if theLine !~ '^[ \t]*' . sexyComMarker ++ return [] ++ endif ++ ++ endif ++ ++ "if top is -1 then we havent found the top yet so keep looking up ++ if top == -1 ++ let currentLine = currentLine - 1 ++ "if we have found the top line then go down looking for the bottom ++ else ++ let currentLine = currentLine + 1 ++ endif ++ ++ endwhile ++ ++ return [top, bottom] ++endfunction ++ ++ ++" Function: s:GetLeft(alt, space, esc) {{{2 ++" returns the left/left-alternative delimiter ++" Args: ++" -alt: specifies whether to get left or left-alternative delim ++" -space: specifies whether the delim should be spaced or not ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the delim should be ESCed ++function s:GetLeft(alt, space, esc) ++ let delim = b:left ++ ++ if a:alt ++ if b:leftAlt == '' ++ return '' ++ else ++ let delim = b:leftAlt ++ endif ++ endif ++ if delim == '' ++ return '' ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let delim = delim . s:spaceStr ++ endif ++ ++ if a:esc ++ let delim = s:Esc(delim) ++ endif ++ ++ return delim ++endfunction ++ ++" Function: s:GetRight(alt, space, esc) {{{2 ++" returns the right/right-alternative delimiter ++" Args: ++" -alt: specifies whether to get right or right-alternative delim ++" -space: specifies whether the delim should be spaced or not ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the delim should be ESCed ++function s:GetRight(alt, space, esc) ++ let delim = b:right ++ ++ if a:alt ++ if !s:AltMultipart() ++ return '' ++ else ++ let delim = b:rightAlt ++ endif ++ endif ++ if delim == '' ++ return '' ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let delim = s:spaceStr . delim ++ endif ++ ++ if a:esc ++ let delim = s:Esc(delim) ++ endif ++ ++ return delim ++endfunction ++ ++ ++" Function: s:GetSexyComMarker() {{{2 ++" Returns the sexy comment marker for the current filetype. ++" ++" C style sexy comments are assumed if possible. If not then the sexy comment ++" marker is the last char of the delimiter pair that has both left and right ++" delims and has the longest left delim ++" ++" Args: ++" -space: specifies whether the marker is to have a space string after it ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the marker are to be ESCed ++function s:GetSexyComMarker(space, esc) ++ let sexyComMarker = b:sexyComMarker ++ ++ "if there is no hardcoded marker then we find one ++ if sexyComMarker == '' ++ ++ "if the filetype has c style comments then use standard c sexy ++ "comments ++ if s:HasCStyleComments() ++ let sexyComMarker = '*' ++ else ++ "find a comment marker by getting the longest available left delim ++ "(that has a corresponding right delim) and taking the last char ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let left = '' ++ let right = '' ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let left = b:left ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ else ++ return -1 ++ endif ++ ++ "get the last char of left ++ let sexyComMarker = strpart(left, strlen(left)-1) ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let sexyComMarker = sexyComMarker . s:spaceStr ++ endif ++ ++ if a:esc ++ let sexyComMarker = s:Esc(sexyComMarker) ++ endif ++ ++ return sexyComMarker ++endfunction ++ ++" Function: s:GetSexyComLeft(space, esc) {{{2 ++" Returns the left delimiter for sexy comments for this filetype or -1 if ++" there is none. C style sexy comments are used if possible ++" Args: ++" -space: specifies if the delim has a space string on the end ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the string are ESCed ++function s:GetSexyComLeft(space, esc) ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let left = '' ++ ++ "assume c style sexy comments if possible ++ if s:HasCStyleComments() ++ let left = '/*' ++ else ++ "grab the longest left delim that has a right ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let left = b:left ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ else ++ return -1 ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let left = left . s:spaceStr ++ endif ++ ++ if a:esc ++ let left = s:Esc(left) ++ endif ++ ++ return left ++endfunction ++ ++" Function: s:GetSexyComRight(space, esc) {{{2 ++" Returns the right delimiter for sexy comments for this filetype or -1 if ++" there is none. C style sexy comments are used if possible. ++" Args: ++" -space: specifies if the delim has a space string on the start ++" (the space string will only be added if NERDSpaceDelims ++" is specified for the current filetype) ++" -esc: specifies whether the tricky chars in the string are ESCed ++function s:GetSexyComRight(space, esc) ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let right = '' ++ ++ "assume c style sexy comments if possible ++ if s:HasCStyleComments() ++ let right = '*/' ++ else ++ "grab the right delim that pairs with the longest left delim ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let right = b:right ++ elseif s:AltMultipart() ++ let right = b:rightAlt ++ else ++ return -1 ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let right = s:spaceStr . right ++ endif ++ ++ if a:esc ++ let right = s:Esc(right) ++ endif ++ ++ return right ++endfunction ++ ++" Function: s:HasMultipartDelims() {{{2 ++" Returns 1 iff the current filetype has at least one set of multipart delims ++function s:HasMultipartDelims() ++ return s:Multipart() || s:AltMultipart() ++endfunction ++ ++" Function: s:HasLeadingTabs(...) {{{2 ++" Returns 1 if any of the given strings have leading tabs ++function s:HasLeadingTabs(...) ++ for s in a:000 ++ if s =~ '^\t.*' ++ return 1 ++ end ++ endfor ++ return 0 ++endfunction ++" Function: s:HasCStyleComments() {{{2 ++" Returns 1 iff the current filetype has c style comment delimiters ++function s:HasCStyleComments() ++ return (b:left == '/*' && b:right == '*/') || (b:leftAlt == '/*' && b:rightAlt == '*/') ++endfunction ++ ++" Function: s:InstallDocumentation(full_name, revision) {{{2 ++" Install help documentation. ++" Arguments: ++" full_name: Full name of this vim plugin script, including path name. ++" revision: Revision of the vim script. #version# mark in the document file ++" will be replaced with this string with 'v' prefix. ++" Return: ++" 1 if new document installed, 0 otherwise. ++" Note: Cleaned and generalized by guo-peng Wen. ++" ++" Note about authorship: this function was taken from the vimspell plugin ++" which can be found at http://www.vim.org/scripts/script.php?script_id=465 ++" ++function s:InstallDocumentation(full_name, revision) ++ " Name of the document path based on the system we use: ++ if has("vms") ++ " No chance that this script will work with ++ " VMS - to much pathname juggling here. ++ return 1 ++ elseif (has("unix")) ++ " On UNIX like system, using forward slash: ++ let l:slash_char = '/' ++ let l:mkdir_cmd = ':silent !mkdir -p ' ++ else ++ " On M$ system, use backslash. Also mkdir syntax is different. ++ " This should only work on W2K and up. ++ let l:slash_char = '\' ++ let l:mkdir_cmd = ':silent !mkdir ' ++ endif ++ ++ let l:doc_path = l:slash_char . 'doc' ++ let l:doc_home = l:slash_char . '.vim' . l:slash_char . 'doc' ++ ++ " Figure out document path based on full name of this script: ++ let l:vim_plugin_path = fnamemodify(a:full_name, ':h') ++ let l:vim_doc_path = fnamemodify(a:full_name, ':h:h') . l:doc_path ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ "Doc path: " . l:vim_doc_path ++ call s:NerdEcho("Doc path: " . l:vim_doc_path, 0) ++ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ " Try a default configuration in user home: ++ let l:vim_doc_path = expand("~") . l:doc_home ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ " Put a warning: ++ call s:NerdEcho("Unable to open documentation directory \ntype :help add-local-help for more information.", 0) ++ echo l:vim_doc_path ++ return 0 ++ endif ++ endif ++ endif ++ endif ++ ++ " Exit if we have problem to access the document directory: ++ if (!isdirectory(l:vim_plugin_path) || !isdirectory(l:vim_doc_path) || filewritable(l:vim_doc_path) != 2) ++ return 0 ++ endif ++ ++ " Full name of script and documentation file: ++ let l:script_name = fnamemodify(a:full_name, ':t') ++ let l:doc_name = fnamemodify(a:full_name, ':t:r') . '.txt' ++ let l:plugin_file = l:vim_plugin_path . l:slash_char . l:script_name ++ let l:doc_file = l:vim_doc_path . l:slash_char . l:doc_name ++ ++ " Bail out if document file is still up to date: ++ if (filereadable(l:doc_file) && getftime(l:plugin_file) < getftime(l:doc_file)) ++ return 0 ++ endif ++ ++ " Prepare window position restoring command: ++ if (strlen(@%)) ++ let l:go_back = 'b ' . bufnr("%") ++ else ++ let l:go_back = 'enew!' ++ endif ++ ++ " Create a new buffer & read in the plugin file (me): ++ setl nomodeline ++ exe 'enew!' ++ exe 'r ' . escape(l:plugin_file,s:NERDFileNameEscape) ++ ++ setl modeline ++ let l:buf = bufnr("%") ++ setl noswapfile modifiable ++ ++ norm zR ++ norm gg ++ ++ " Delete from first line to a line starts with ++ " === START_DOC ++ 1,/^=\{3,}\s\+START_DOC\C/ d ++ ++ " Delete from a line starts with ++ " === END_DOC ++ " to the end of the documents: ++ /^=\{3,}\s\+END_DOC\C/,$ d ++ ++ " Remove fold marks: ++ :%s/{\{3}[1-9]/ / ++ ++ " Add modeline for help doc: the modeline string is mangled intentionally ++ " to avoid it be recognized by VIM: ++ call append(line('$'), '') ++ call append(line('$'), ' v' . 'im:tw=78:ts=8:ft=help:norl:') ++ ++ " Replace revision: ++ "exe "normal :1s/#version#/ v" . a:revision . "/\" ++ exe "normal :%s/#version#/ v" . a:revision . "/\" ++ ++ " Save the help document: ++ exe 'w! ' . escape(l:doc_file,s:NERDFileNameEscape) ++ exe l:go_back ++ exe 'bw ' . l:buf ++ ++ " Build help tags: ++ exe 'helptags ' . escape(l:vim_doc_path,s:NERDFileNameEscape) ++ ++ return 1 ++endfunction ++ ++ ++" Function: s:IsCommentedNormOrSexy(lineNum) {{{2 ++"This function is used to determine whether the given line is commented with ++"either set of delimiters or if it is part of a sexy comment ++" ++" Args: ++" -lineNum: the line number of the line to check ++function s:IsCommentedNormOrSexy(lineNum) ++ let theLine = getline(a:lineNum) ++ ++ "if the line is commented normally return 1 ++ if s:IsCommented(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine) ++ return 1 ++ endif ++ ++ "if the line is part of a sexy comment return 1 ++ if s:IsInSexyComment(a:lineNum) ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Function: s:IsCommented(left, right, line) {{{2 ++"This function is used to determine whether the given line is commented with ++"the given delimiters ++" ++" Args: ++" -line: the line that to check if commented ++" -left/right: the left and right delimiters to check for ++function s:IsCommented(left, right, line) ++ "if the line isnt commented return true ++ if s:FindDelimiterIndex(a:left, a:line) != -1 && (s:FindDelimiterIndex(a:right, a:line) != -1 || !s:Multipart()) ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Function: s:IsCommentedFromStartOfLine(left, line) {{{2 ++"This function is used to determine whether the given line is commented with ++"the given delimiters at the start of the line i.e the left delimiter is the ++"first thing on the line (apart from spaces\tabs) ++" ++" Args: ++" -line: the line that to check if commented ++" -left: the left delimiter to check for ++function s:IsCommentedFromStartOfLine(left, line) ++ let theLine = s:ConvertLeadingTabsToSpaces(a:line) ++ let numSpaces = strlen(substitute(theLine, '^\( *\).*$', '\1', '')) ++ let delimIndx = s:FindDelimiterIndex(a:left, theLine) ++ return delimIndx == numSpaces ++endfunction ++ ++" Function: s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) {{{2 ++" Finds the type of the outtermost delims on the line ++" ++" Args: ++" -line: the line that to check if the outtermost comments on it are ++" left/right ++" -left/right: the left and right delimiters to check for ++" -leftAlt/rightAlt: the left and right alternative delimiters to check for ++" ++" Returns: ++" 0 if the line is not commented with either set of delims ++" 1 if the line is commented with the left/right delim set ++" 2 if the line is commented with the leftAlt/rightAlt delim set ++function s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) ++ "get the first positions of the left delims and the last positions of the ++ "right delims ++ let indxLeft = s:FindDelimiterIndex(a:left, a:line) ++ let indxLeftAlt = s:FindDelimiterIndex(a:leftAlt, a:line) ++ let indxRight = s:LastIndexOfDelim(a:right, a:line) ++ let indxRightAlt = s:LastIndexOfDelim(a:rightAlt, a:line) ++ ++ "check if the line has a left delim before a leftAlt delim ++ if (indxLeft <= indxLeftAlt || indxLeftAlt == -1) && indxLeft != -1 ++ "check if the line has a right delim after any rightAlt delim ++ if (indxRight > indxRightAlt && indxRight > indxLeft) || !s:Multipart() ++ return 1 ++ endif ++ ++ "check if the line has a leftAlt delim before a left delim ++ elseif (indxLeftAlt <= indxLeft || indxLeft == -1) && indxLeftAlt != -1 ++ "check if the line has a rightAlt delim after any right delim ++ if (indxRightAlt > indxRight && indxRightAlt > indxLeftAlt) || !s:AltMultipart() ++ return 2 ++ endif ++ else ++ return 0 ++ endif ++ ++ return 0 ++ ++endfunction ++ ++ ++" Function: s:IsDelimValid(delimiter, delIndx, line) {{{2 ++" This function is responsible for determining whether a given instance of a ++" comment delimiter is a real delimiter or not. For example, in java the ++" // string is a comment delimiter but in the line: ++" System.out.println("//"); ++" it does not count as a comment delimiter. This function is responsible for ++" distinguishing between such cases. It does so by applying a set of ++" heuristics that are not fool proof but should work most of the time. ++" ++" Args: ++" -delimiter: the delimiter we are validating ++" -delIndx: the position of delimiter in line ++" -line: the line that delimiter occurs in ++" ++" Returns: ++" 0 if the given delimiter is not a real delimiter (as far as we can tell) , ++" 1 otherwise ++function s:IsDelimValid(delimiter, delIndx, line) ++ "get the delimiter without the escchars ++ let l:delimiter = a:delimiter ++ ++ "get the strings before and after the delimiter ++ let preComStr = strpart(a:line, 0, a:delIndx) ++ let postComStr = strpart(a:line, a:delIndx+strlen(delimiter)) ++ ++ "to check if the delimiter is real, make sure it isnt preceded by ++ "an odd number of quotes and followed by the same (which would indicate ++ "that it is part of a string and therefore is not a comment) ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '"', "\\")) ++ return 0 ++ endif ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "'", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "'", "\\")) ++ return 0 ++ endif ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "`", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "`", "\\")) ++ return 0 ++ endif ++ ++ ++ "if the comment delimiter is escaped, assume it isnt a real delimiter ++ if s:IsEscaped(a:line, a:delIndx, "\\") ++ return 0 ++ endif ++ ++ "vim comments are so fuckin stupid!! Why the hell do they have comment ++ "delimiters that are used elsewhere in the syntax?!?! We need to check ++ "some conditions especially for vim ++ if &filetype == "vim" ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) ++ return 0 ++ endif ++ ++ "if the delimiter is on the very first char of the line or is the ++ "first non-tab/space char on the line then it is a valid comment delimiter ++ if a:delIndx == 0 || a:line =~ "^[ \t]\\{" . a:delIndx . "\\}\".*$" ++ return 1 ++ endif ++ ++ let numLeftParen =s:CountNonESCedOccurances(preComStr, "(", "\\") ++ let numRightParen =s:CountNonESCedOccurances(preComStr, ")", "\\") ++ ++ "if the quote is inside brackets then assume it isnt a comment ++ if numLeftParen > numRightParen ++ return 0 ++ endif ++ ++ "if the line has an even num of unescaped "'s then we can assume that ++ "any given " is not a comment delimiter ++ if s:IsNumEven(s:CountNonESCedOccurances(a:line, "\"", "\\")) ++ return 0 ++ endif ++ endif ++ ++ return 1 ++ ++endfunction ++ ++" Function: s:IsNumEven(num) {{{2 ++" A small function the returns 1 if the input number is even and 0 otherwise ++" Args: ++" -num: the number to check ++function s:IsNumEven(num) ++ return (a:num % 2) == 0 ++endfunction ++ ++" Function: s:IsEscaped(str, indx, escChar) {{{2 ++" This function takes a string, an index into that string and an esc char and ++" returns 1 if the char at the index is escaped (i.e if it is preceded by an ++" odd number of esc chars) ++" Args: ++" -str: the string to check ++" -indx: the index into str that we want to check ++" -escChar: the escape char the char at indx may be ESCed with ++function s:IsEscaped(str, indx, escChar) ++ "initialise numEscChars to 0 and look at the char before indx ++ let numEscChars = 0 ++ let curIndx = a:indx-1 ++ ++ "keep going back thru str until we either reach the start of the str or ++ "run out of esc chars ++ while curIndx >= 0 && strpart(a:str, curIndx, 1) == a:escChar ++ ++ "we have found another esc char so add one to the count and move left ++ "one char ++ let numEscChars = numEscChars + 1 ++ let curIndx = curIndx - 1 ++ ++ endwhile ++ ++ "if there is an odd num of esc chars directly before the char at indx then ++ "the char at indx is escaped ++ return !s:IsNumEven(numEscChars) ++endfunction ++ ++" Function: s:IsInSexyComment(line) {{{2 ++" returns 1 if the given line number is part of a sexy comment ++function s:IsInSexyComment(line) ++ return !empty(s:FindBoundingLinesOfSexyCom(a:line)) ++endfunction ++ ++" Function: s:IsSexyComment(topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns 1 if the lines between and ++" including the given line numbers are a sexy comment. It returns 0 otherwise. ++" Args: ++" -topline: the line that the possible sexy comment starts on ++" -bottomline: the line that the possible sexy comment stops on ++function s:IsSexyComment(topline, bottomline) ++ ++ "get the delim set that would be used for a sexy comment ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = b:left ++ let right = b:right ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ let right = b:rightAlt ++ else ++ return 0 ++ endif ++ ++ "swap the top and bottom line numbers around if need be ++ let topline = a:topline ++ let bottomline = a:bottomline ++ if bottomline < topline ++ topline = bottomline ++ bottomline = a:topline ++ endif ++ ++ "if there is < 2 lines in the comment it cannot be sexy ++ if (bottomline - topline) <= 0 ++ return 0 ++ endif ++ ++ "if the top line doesnt begin with a left delim then the comment isnt sexy ++ if getline(a:topline) !~ '^[ \t]*' . left ++ return 0 ++ endif ++ ++ "if there is a right delim on the top line then this isnt a sexy comment ++ if s:FindDelimiterIndex(right, getline(a:topline)) != -1 ++ return 0 ++ endif ++ ++ "if there is a left delim on the bottom line then this isnt a sexy comment ++ if s:FindDelimiterIndex(left, getline(a:bottomline)) != -1 ++ return 0 ++ endif ++ ++ "if the bottom line doesnt begin with a right delim then the comment isnt ++ "sexy ++ if getline(a:bottomline) !~ '^.*' . right . '$' ++ return 0 ++ endif ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ ++ "check each of the intermediate lines to make sure they start with a ++ "sexyComMarker ++ let currentLine = a:topline+1 ++ while currentLine < a:bottomline ++ let theLine = getline(currentLine) ++ ++ if theLine !~ '^[ \t]*' . sexyComMarker ++ return 0 ++ endif ++ ++ "if there is a right delim in an intermediate line then the block isnt ++ "a sexy comment ++ if s:FindDelimiterIndex(right, theLine) != -1 ++ return 0 ++ endif ++ ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "we have not found anything to suggest that this isnt a sexy comment so ++ return 1 ++ ++endfunction ++ ++" Function: s:LastIndexOfDelim(delim, str) {{{2 ++" This function takes a string and a delimiter and returns the last index of ++" that delimiter in string ++" Args: ++" -delim: the delimiter to look for ++" -str: the string to look for delim in ++function s:LastIndexOfDelim(delim, str) ++ let delim = a:delim ++ let lenDelim = strlen(delim) ++ ++ "set index to the first occurrence of delim. If there is no occurrence then ++ "bail ++ let indx = s:FindDelimiterIndex(delim, a:str) ++ if indx == -1 ++ return -1 ++ endif ++ ++ "keep moving to the next instance of delim in str till there is none left ++ while 1 ++ ++ "search for the next delim after the previous one ++ let searchStr = strpart(a:str, indx+lenDelim) ++ let indx2 = s:FindDelimiterIndex(delim, searchStr) ++ ++ "if we find a delim update indx to record the position of it, if we ++ "dont find another delim then indx is the last one so break out of ++ "this loop ++ if indx2 != -1 ++ let indx = indx + indx2 + lenDelim ++ else ++ break ++ endif ++ endwhile ++ ++ return indx ++ ++endfunction ++ ++" Function: s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns the index of the left most ++" char (that is not a space or a tab) on all of these lines. ++" Args: ++" -countCommentedLines: 1 if lines that are commented are to be checked as ++" well. 0 otherwise ++" -countEmptyLines: 1 if empty lines are to be counted in the search ++" -topline: the top line to be checked ++" -bottomline: the bottom line to be checked ++function s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) ++ ++ " declare the left most index as an extreme value ++ let leftMostIndx = 1000 ++ ++ " go thru the block line by line updating leftMostIndx ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ ++ " get the next line and if it is allowed to be commented, or is not ++ " commented, check it ++ let theLine = getline(currentLine) ++ if a:countEmptyLines || theLine !~ '^[ \t]*$' ++ if a:countCommentedLines || (!s:IsCommented(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, theLine)) ++ " convert spaces to tabs and get the number of leading spaces for ++ " this line and update leftMostIndx if need be ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let leadSpaceOfLine = strlen( substitute(theLine, '\(^[ \t]*\).*$','\1','') ) ++ if leadSpaceOfLine < leftMostIndx ++ let leftMostIndx = leadSpaceOfLine ++ endif ++ endif ++ endif ++ ++ " move on to the next line ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ if leftMostIndx == 1000 ++ return 0 ++ else ++ return leftMostIndx ++ endif ++endfunction ++ ++" Function: s:Multipart() {{{2 ++" returns 1 if the current delims are multipart ++function s:Multipart() ++ return b:right != '' ++endfunction ++ ++" Function: s:NerdEcho(msg, typeOfMsg) {{{2 ++" Args: ++" -msg: the message to echo ++" -typeOfMsg: 0 = warning message ++" 1 = normal message ++function s:NerdEcho(msg, typeOfMsg) ++ if a:typeOfMsg == 0 ++ echohl WarningMsg ++ echo 'NERDCommenter:' . a:msg ++ echohl None ++ elseif a:typeOfMsg == 1 ++ echo 'NERDCommenter:' . a:msg ++ endif ++endfunction ++ ++" Function: s:NumberOfLeadingTabs(s) {{{2 ++" returns the number of leading tabs in the given string ++function s:NumberOfLeadingTabs(s) ++ return strlen(substitute(a:s, '^\(\t*\).*$', '\1', "")) ++endfunction ++ ++" Function: s:NumLinesInBuf() {{{2 ++" Returns the number of lines in the current buffer ++function s:NumLinesInBuf() ++ return line('$') ++endfunction ++ ++" Function: s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) {{{2 ++" This function takes in a string, 2 delimiters in that string and 2 strings ++" to replace these delimiters with. ++" ++" Args: ++" -toReplace1: the first delimiter to replace ++" -toReplace2: the second delimiter to replace ++" -replacor1: the string to replace toReplace1 with ++" -replacor2: the string to replace toReplace2 with ++" -str: the string that the delimiters to be replaced are in ++function s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) ++ let line = s:ReplaceLeftMostDelim(a:toReplace1, a:replacor1, a:str) ++ let line = s:ReplaceRightMostDelim(a:toReplace2, a:replacor2, line) ++ return line ++endfunction ++ ++" Function: s:ReplaceLeftMostDelim(toReplace, replacor, str) {{{2 ++" This function takes a string and a delimiter and replaces the left most ++" occurrence of this delimiter in the string with a given string ++" ++" Args: ++" -toReplace: the delimiter in str that is to be replaced ++" -replacor: the string to replace toReplace with ++" -str: the string that contains toReplace ++function s:ReplaceLeftMostDelim(toReplace, replacor, str) ++ let toReplace = a:toReplace ++ let replacor = a:replacor ++ "get the left most occurrence of toReplace ++ let indxToReplace = s:FindDelimiterIndex(toReplace, a:str) ++ ++ "if there IS an occurrence of toReplace in str then replace it and return ++ "the resulting string ++ if indxToReplace != -1 ++ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) ++ return line ++ endif ++ ++ return a:str ++endfunction ++ ++" Function: s:ReplaceRightMostDelim(toReplace, replacor, str) {{{2 ++" This function takes a string and a delimiter and replaces the right most ++" occurrence of this delimiter in the string with a given string ++" ++" Args: ++" -toReplace: the delimiter in str that is to be replaced ++" -replacor: the string to replace toReplace with ++" -str: the string that contains toReplace ++" ++function s:ReplaceRightMostDelim(toReplace, replacor, str) ++ let toReplace = a:toReplace ++ let replacor = a:replacor ++ let lenToReplace = strlen(toReplace) ++ ++ "get the index of the last delim in str ++ let indxToReplace = s:LastIndexOfDelim(toReplace, a:str) ++ ++ "if there IS a delimiter in str, replace it and return the result ++ let line = a:str ++ if indxToReplace != -1 ++ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) ++ endif ++ return line ++endfunction ++ ++"FUNCTION: s:RestoreScreenState() {{{2 ++" ++"Sets the screen state back to what it was when s:SaveScreenState was last ++"called. ++" ++function s:RestoreScreenState() ++ if !exists("t:NERDComOldTopLine") || !exists("t:NERDComOldPos") ++ throw 'NERDCommenter exception: cannot restore screen' ++ endif ++ ++ call cursor(t:NERDComOldTopLine, 0) ++ normal zt ++ call setpos(".", t:NERDComOldPos) ++endfunction ++ ++" Function: s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns the index of the right most ++" char on all of these lines. ++" Args: ++" -countCommentedLines: 1 if lines that are commented are to be checked as ++" well. 0 otherwise ++" -countEmptyLines: 1 if empty lines are to be counted in the search ++" -topline: the top line to be checked ++" -bottomline: the bottom line to be checked ++function s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) ++ let rightMostIndx = -1 ++ ++ " go thru the block line by line updating rightMostIndx ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ ++ " get the next line and see if it is commentable, otherwise it doesnt ++ " count ++ let theLine = getline(currentLine) ++ if a:countEmptyLines || theLine !~ '^[ \t]*$' ++ ++ if a:countCommentedLines || (!s:IsCommented(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, theLine)) ++ ++ " update rightMostIndx if need be ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let lineLen = strlen(theLine) ++ if lineLen > rightMostIndx ++ let rightMostIndx = lineLen ++ endif ++ endif ++ endif ++ ++ " move on to the next line ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ return rightMostIndx ++endfunction ++ ++"FUNCTION: s:SaveScreenState() {{{2 ++"Saves the current cursor position in the current buffer and the window ++"scroll position ++function s:SaveScreenState() ++ let t:NERDComOldPos = getpos(".") ++ let t:NERDComOldTopLine = line("w0") ++endfunction ++ ++" Function: s:SwapOutterMultiPartDelimsForPlaceHolders(line) {{{2 ++" This function takes a line and swaps the outter most multi-part delims for ++" place holders ++" Args: ++" -line: the line to swap the delims in ++" ++function s:SwapOutterMultiPartDelimsForPlaceHolders(line) ++ " find out if the line is commented using normal delims and/or ++ " alternate ones ++ let isCommented = s:IsCommented(b:left, b:right, a:line) ++ let isCommentedAlt = s:IsCommented(b:leftAlt, b:rightAlt, a:line) ++ ++ let line2 = a:line ++ ++ "if the line is commented and there is a right delimiter, replace ++ "the delims with place-holders ++ if isCommented && s:Multipart() ++ let line2 = s:ReplaceDelims(b:left, b:right, g:NERDLPlace, g:NERDRPlace, a:line) ++ ++ "similarly if the line is commented with the alternative ++ "delimiters ++ elseif isCommentedAlt && s:AltMultipart() ++ let line2 = s:ReplaceDelims(b:leftAlt, b:rightAlt, g:NERDLPlace, g:NERDRPlace, a:line) ++ endif ++ ++ return line2 ++endfunction ++ ++" Function: s:SwapOutterPlaceHoldersForMultiPartDelims(line) {{{2 ++" This function takes a line and swaps the outtermost place holders for ++" multi-part delims ++" Args: ++" -line: the line to swap the delims in ++" ++function s:SwapOutterPlaceHoldersForMultiPartDelims(line) ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = b:left ++ let right = b:right ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ let right = b:rightAlt ++ endif ++ ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, a:line) ++ return line ++endfunction ++" Function: s:TabbedCol(line, col) {{{2 ++" Gets the col number for given line and existing col number. The new col ++" number is the col number when all leading spaces are converted to tabs ++" Args: ++" -line:the line to get the rel col for ++" -col: the abs col ++function s:TabbedCol(line, col) ++ let lineTruncated = strpart(a:line, 0, a:col) ++ let lineSpacesToTabs = substitute(lineTruncated, s:TabSpace(), '\t', 'g') ++ return strlen(lineSpacesToTabs) ++endfunction ++"FUNCTION: s:TabSpace() {{{2 ++"returns a string of spaces equal in length to &tabstop ++function s:TabSpace() ++ let tabSpace = "" ++ let spacesPerTab = &tabstop ++ while spacesPerTab > 0 ++ let tabSpace = tabSpace . " " ++ let spacesPerTab = spacesPerTab - 1 ++ endwhile ++ return tabSpace ++endfunction ++ ++" Function: s:UnEsc(str, escChar) {{{2 ++" This function removes all the escape chars from a string ++" Args: ++" -str: the string to remove esc chars from ++" -escChar: the escape char to be removed ++function s:UnEsc(str, escChar) ++ return substitute(a:str, a:escChar, "", "g") ++endfunction ++ ++" Function: s:UntabbedCol(line, col) {{{2 ++" Takes a line and a col and returns the absolute column of col taking into ++" account that a tab is worth 3 or 4 (or whatever) spaces. ++" Args: ++" -line:the line to get the abs col for ++" -col: the col that doesnt take into account tabs ++function s:UntabbedCol(line, col) ++ let lineTruncated = strpart(a:line, 0, a:col) ++ let lineTabsToSpaces = substitute(lineTruncated, '\t', s:TabSpace(), 'g') ++ return strlen(lineTabsToSpaces) ++endfunction ++" Section: Comment mapping setup {{{1 ++" =========================================================================== ++" This is where the mappings calls are made that set up the commenting key ++" mappings. ++ ++" set up the mapping to switch to/from alternative delimiters ++execute 'nnoremap ' . g:NERDAltComMap . ' :call SwitchToAlternativeDelimiters(1)' ++ ++" set up the mappings to comment out lines ++execute 'nnoremap ' . g:NERDComLineMap . ' :call NERDComment(0, "norm")' ++execute 'vnoremap ' . g:NERDComLineMap . ' :call NERDComment(1, "norm")' ++ ++" set up the mappings to do toggle comments ++execute 'nnoremap ' . g:NERDComLineToggleMap . ' :call NERDComment(0, "toggle")' ++execute 'vnoremap ' . g:NERDComLineToggleMap . ' :call NERDComment(1, "toggle")' ++ ++" set up the mapp to do minimal comments ++execute 'nnoremap ' . g:NERDComLineMinimalMap . ' :call NERDComment(0, "minimal")' ++execute 'vnoremap ' . g:NERDComLineMinimalMap . ' :call NERDComment(1, "minimal")' ++ ++" set up the mappings to comment out lines sexily ++execute 'nnoremap ' . g:NERDComLineSexyMap . ' :call NERDComment(0, "sexy")' ++execute 'vnoremap ' . g:NERDComLineSexyMap . ' :call NERDComment(1, "sexy")' ++ ++" set up the mappings to do invert comments ++execute 'nnoremap ' . g:NERDComLineInvertMap . ' :call NERDComment(0, "invert")' ++execute 'vnoremap ' . g:NERDComLineInvertMap . ' :call NERDComment(1, "invert")' ++ ++" set up the mappings to yank then comment out lines ++execute 'nmap ' . g:NERDComLineYankMap . ' :call NERDComment(0, "yank")' ++execute 'vmap ' . g:NERDComLineYankMap . ' :call NERDComment(1, "yank")' ++ ++" set up the mappings for left aligned comments ++execute 'nnoremap ' . g:NERDComAlignLeftMap . ' :call NERDComment(0, "alignLeft")' ++execute 'vnoremap ' . g:NERDComAlignLeftMap . ' :call NERDComment(1, "alignLeft")' ++ ++" set up the mappings for right aligned comments ++execute 'nnoremap ' . g:NERDComAlignRightMap . ' :call NERDComment(0, "alignRight")' ++execute 'vnoremap ' . g:NERDComAlignRightMap . ' :call NERDComment(1, "alignRight")' ++ ++" set up the mappings for left and right aligned comments ++execute 'nnoremap ' . g:NERDComAlignBothMap . ' :call NERDComment(0, "alignBoth")' ++execute 'vnoremap ' . g:NERDComAlignBothMap . ' :call NERDComment(1, "alignBoth")' ++ ++" set up the mappings to do nested comments ++execute 'nnoremap ' . g:NERDComLineNestMap . ' :call NERDComment(0, "nested")' ++execute 'vnoremap ' . g:NERDComLineNestMap . ' :call NERDComment(1, "nested")' ++ ++" set up the mapping to uncomment a line ++execute 'nnoremap ' . g:NERDUncomLineMap . ' :call NERDComment(0, "uncomment")' ++execute 'vnoremap ' . g:NERDUncomLineMap . ' :call NERDComment(1, "uncomment")' ++ ++" set up the mapping to comment out to the end of the line ++execute 'nnoremap ' . g:NERDComToEOLMap . ' :call NERDComment(0, "toEOL")' ++ ++" set up the mappings to append comments to the line ++execute 'nmap ' . g:NERDAppendComMap . ' :call NERDComment(0, "append")' ++ ++" set up the mappings to append comments to the line ++execute 'nmap ' . g:NERDPrependComMap . ' :call NERDComment(0, "prepend")' ++ ++" set up the mapping to insert comment delims at the cursor position in insert mode ++execute 'inoremap ' . g:NERDComInInsertMap . ' ' . ':call NERDComment(0, "insert")' ++ ++" Section: Menu item setup {{{1 ++" =========================================================================== ++"check if the user wants the menu to be displayed ++if g:NERDMenuMode != 0 ++ ++ let menuRoot = "" ++ if g:NERDMenuMode == 1 ++ let menuRoot = 'comment' ++ elseif g:NERDMenuMode == 2 ++ let menuRoot = '&comment' ++ elseif g:NERDMenuMode == 3 ++ let menuRoot = '&Plugin.&comment' ++ endif ++ ++ execute 'nmenu '. menuRoot .'.Comment' . escape(g:NERDComLineMap, '\') . ' :call NERDComment(0, "norm")' ++ execute 'vmenu '. menuRoot .'.Comment' . escape(g:NERDComLineMap, '\') . ' :call NERDComment(1, "norm")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Toggle' . escape(g:NERDComLineToggleMap, '\') . ' :call NERDComment(0, "toggle")' ++ execute 'vmenu '. menuRoot .'.Comment\ Toggle' . escape(g:NERDComLineToggleMap, '\') . ' :call NERDComment(1, "toggle")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Minimal' . escape(g:NERDComLineMinimalMap, '\') . ' :call NERDComment(0, "minimal")' ++ execute 'vmenu '. menuRoot .'.Comment\ Minimal' . escape(g:NERDComLineMinimalMap, '\') . ' :call NERDComment(1, "minimal")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Nested' . escape(g:NERDComLineNestMap, '\') . ' :call NERDComment(0, "nested")' ++ execute 'vmenu '. menuRoot .'.Comment\ Nested' . escape(g:NERDComLineNestMap, '\') . ' :call NERDComment(1, "nested")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ To\ EOL' . escape(g:NERDComToEOLMap, '\') . ' :call NERDComment(0, "toEOL")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Invert' . escape(g:NERDComLineInvertMap, '\') . ' :call NERDComment(0,"invert")' ++ execute 'vmenu '. menuRoot .'.Comment\ Invert' . escape(g:NERDComLineInvertMap, '\') . ' :call NERDComment(1,"invert")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Sexily' . escape(g:NERDComLineSexyMap, '\') . ' :call NERDComment(0,"sexy")' ++ execute 'vmenu '. menuRoot .'.Comment\ Sexily' . escape(g:NERDComLineSexyMap, '\') . ' :call NERDComment(1,"sexy")' ++ ++ execute 'nmenu '. menuRoot .'.Yank\ line(s)\ then\ comment' . escape(g:NERDComLineYankMap, '\') . ' "0Y' . g:NERDComLineMap ++ execute 'vmenu '. menuRoot .'.Yank\ line(s)\ then\ comment' . escape(g:NERDComLineYankMap, '\') . ' "0ygv' . g:NERDComLineMap ++ ++ execute 'nmenu '. menuRoot .'.Append\ Comment\ to\ Line' . escape(g:NERDAppendComMap, '\') . ' :call NERDComment(0, "append")' ++ execute 'nmenu '. menuRoot .'.Prepend\ Comment\ to\ Line' . escape(g:NERDPrependComMap, '\') . ' :call NERDComment(0, "prepend")' ++ ++ execute 'menu '. menuRoot .'.-Sep- :' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Left\ (nested)' . escape(g:NERDComAlignLeftMap, '\') . ' :call NERDComment(0, "alignLeft")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Left\ (nested)' . escape(g:NERDComAlignLeftMap, '\') . ' :call NERDComment(1, "alignLeft")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Right\ (nested)' . escape(g:NERDComAlignRightMap, '\') . ' :call NERDComment(0, "alignRight")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Right\ (nested)' . escape(g:NERDComAlignRightMap, '\') . ' :call NERDComment(1, "alignRight")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Both\ (nested)' . escape(g:NERDComAlignBothMap, '\') . ' :call NERDComment(0, "alignBoth")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Both\ (nested)' . escape(g:NERDComAlignBothMap, '\') . ' :call NERDComment(1, "alignBoth")' ++ ++ execute 'menu '. menuRoot .'.-Sep2- :' ++ ++ execute 'menu '. menuRoot .'.Uncomment' . escape(g:NERDUncomLineMap, '\') . ' :call NERDComment(0, "uncomment")' ++ execute 'vmenu ' . menuRoot.'.Uncomment' . escape(g:NERDUncomLineMap, '\') . ' :call NERDComment(1, "uncomment")' ++ ++ execute 'menu '. menuRoot .'.-Sep3- :' ++ ++ execute 'nmenu '. menuRoot .'.Use\ Alternative\ Delimiters' . escape(g:NERDAltComMap, '\') . ' :call SwitchToAlternativeDelimiters(1)' ++ ++ ++ execute 'imenu '. menuRoot .'.Insert\ Delims' . escape(g:NERDComInInsertMap, '\') . ' :call NERDComment(0, "insert")' ++ ++ execute 'menu '. menuRoot .'.-Sep4- :' ++ ++ execute 'menu '. menuRoot .'.Help:help\ NERDCommenterContents :help NERDCommenterContents' ++endif ++ ++" Section: Doc installation call {{{1 ++silent call s:InstallDocumentation(expand(':p'), s:NERD_commenter_version) ++ ++finish ++"============================================================================= ++" Section: The help file {{{1 ++" Title {{{2 ++" ============================================================================ ++=== START_DOC ++*NERD_commenter.txt* Plugin for commenting code #version# ++ ++ ++ NERD COMMENTER REFERENCE MANUAL~ ++ ++ ++ ++ ++ ++============================================================================== ++CONTENTS {{{2 *NERDCommenterContents* ++ ++ 1.Intro...................................|NERDCommenter| ++ 2.Functionality provided..................|NERDComFunctionality| ++ 2.1 Functionality Summary.............|NERDComFunctionalitySummary| ++ 2.2 Functionality Details.............|NERDComFunctionalityDetails| ++ 2.2.1 Comment map.................|NERDComComment| ++ 2.2.2 Nested comment map..........|NERDComNestedComment| ++ 2.2.3 Toggle comment map..........|NERDComToggleComment| ++ 2.2.4 Minimal comment map.........|NERDComMinimalComment| ++ 2.2.5 Invert comment map..........|NERDComInvertComment| ++ 2.2.6 Sexy comment map............|NERDComSexyComment| ++ 2.2.7 Yank comment map............|NERDComYankComment| ++ 2.2.8 Comment to EOL map..........|NERDComEOLComment| ++ 2.2.9 Append com to line map......|NERDComAppendComment| ++ 2.2.10 Prepend com to line map....|NERDComPrependComment| ++ 2.2.11 Insert comment map.........|NERDComInsertComment| ++ 2.2.12 Use alternate delims map...|NERDComAltDelim| ++ 2.2.13 Comment aligned maps.......|NERDComAlignedComment| ++ 2.2.14 Uncomment line map.........|NERDComUncommentLine| ++ 2.3 Supported filetypes...............|NERDComFiletypes| ++ 2.4 Sexy Comments.....................|NERDComSexyComments| ++ 2.5 The NERDComment function..........|NERDComNERDComment| ++ 3.Options.................................|NERDComOptions| ++ 3.1 Options summary...................|NERDComOptionsSummary| ++ 3.2 Options details...................|NERDComOptionsDetails| ++ 3.3 Default delimiter Options.........|NERDComDefaultDelims| ++ 3.4 Key mapping Options...............|NERDComMappings| ++ 4.Issues with the script..................|NERDComIssues| ++ 4.1 Delimiter detection heuristics....|NERDComHeuristics| ++ 4.2 Nesting issues....................|NERDComNesting| ++ 5.The author..............................|NERDComAuthor| ++ 6.TODO list...............................|NERDComTodo| ++ 7.Changelog...............................|NERDComChangelog| ++ 8.Credits.................................|NERDComCredits| ++ ++============================================================================== ++1. Intro {{{2 *NERDCommenter* ++ ++The NERD commenter provides many different commenting operations and styles ++which may be invoked via key mappings and a commenting menu. These operations ++are available for most filetypes. ++ ++There are also options available that allow you to tweak the commenting engine ++to you taste. ++ ++============================================================================== ++2. Functionality provided {{{2 *NERDComFunctionality* ++ ++------------------------------------------------------------------------------ ++2.1 Functionality summary {{{3 *NERDComFunctionalitySummary* ++ ++The following key mappings are provided by default (there is also a menu ++provided that contains menu items corresponding to all the below mappings): ++ ++Most of the following mappings are for normal/visual mode only. The ++|NERDComInsertComment| mapping is for insert mode only. ++ ++[count],cc |NERDComComment| ++Comments out the current line or text selected in visual mode. ++ ++ ++[count],cn |NERDComNestedComment| ++Same as |NERDComComment| but forces nesting. ++ ++ ++[count],c |NERDComToggleComment| ++Toggles the comment state of the selected line(s). If the topmost selected ++line is commented, all selected lines are uncommented and vice versa. ++ ++ ++[count],cm |NERDComMinimalComment| ++Comments the given lines using only one set of multipart delimiters if ++possible. ++ ++ ++[count],ci |NERDComInvertComment| ++Toggles the comment state of the selected line(s) individually. Each selected ++line that is commented is uncommented and vice versa. ++ ++ ++[count],cs |NERDComSexyComment| ++Comments out the selected lines ``sexually'' ++ ++ ++[count],cy |NERDComYankComment| ++Same as |NERDComComment| except that the commented line(s) are yanked ++before commenting. ++ ++ ++,c$ |NERDComEOLComment| ++Comments the current line from the cursor to the end of line. ++ ++ ++,cA |NERDComAppendComment| ++Adds comment delimiters to the end of line and goes into insert mode between ++them. ++ ++ ++,cI |NERDComPrependComment| ++Adds comment delimiters to the start of line and goes into insert mode between ++them. ++ ++ ++ |NERDComInsertComment| ++Adds comment delimiters at the current cursor position and inserts between. ++ ++ ++,ca |NERDComAltDelim| ++Switches to the alternative set of delimiters. ++ ++ ++[count],cl ++[count],cr ++[count],cb |NERDComAlignedComment| ++Same as |NERDComComment| except that the delimiters are aligned down the ++left side (,cl), the right side (,cr) or both sides ++(,cb). ++ ++ ++[count],cu |NERDComUncommentLine| ++Uncomments the selected line(s). ++ ++------------------------------------------------------------------------------ ++2.2 Functionality details {{{3 *NERDComFunctionalityDetails* ++ ++------------------------------------------------------------------------------ ++2.2.1 Comment map *NERDComComment* ++ ++Default mapping: [count],cc ++Change the mapping with: NERDComLineMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++ ++Comments out the current line. If multiple lines are selected in visual-line ++mode, they are all commented out. If some text is selected in visual or ++visual-block mode then the script will try to comment out the exact text that ++is selected using multi-part delimiters if they are available. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.2 Nested comment map *NERDComNestedComment* ++ ++Default mapping: [count],cn ++Change the mapping with: NERDComLineNestMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++Performs nested commenting. Works the same as ,cc except that if a ++line is already commented then it will be commented again. ++ ++If |NERDUsePlaceHolders| is set then the previous comment delimiters will ++be replaced by place-holder delimiters if needed. Otherwise the nested ++comment will only be added if the current commenting delimiters have no right ++delimiter (to avoid syntax errors) ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDDefaultNesting| ++ ++------------------------------------------------------------------------------ ++2.2.3 Toggle comment map *NERDComToggleComment* ++ ++Default mapping: [count],c ++Change the mapping with: NERDComLineToggleMap. ++Applicable modes: normal visual-line. ++ ++Toggles commenting of the lines selected. The behaviour of this mapping ++depends on whether the first line selected is commented or not. If so, all ++selected lines are uncommented and vice versa. ++ ++With this mapping, a line is only considered to be commented if it starts with ++a left delimiter. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.4 Minimal comment map *NERDComMinimalComment* ++ ++Default mapping: [count],cm ++Change the mapping with: NERDComLineMinimalMap ++Applicable modes: normal visual-line. ++ ++Comments the selected lines using one set of multipart delimiters if possible. ++ ++For example: if you are programming in c and you select 5 lines and press ++,cm then a '/*' will be placed at the start of the top line and a '*/' ++will be placed at the end of the last line. ++ ++Sets of multipart comment delimiters that are between the top and bottom ++selected lines are replaced with place holders (see |NERDLPlace|) if ++|NERDUsePlaceHolders| is set for the current filetype. If it is not, then ++the comment will be aborted if place holders are required to prevent illegal ++syntax. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.5 Invert comment map *NERDComInvertComment* ++ ++Default mapping: ,ci ++Change the mapping with: NERDComLineInvertMap. ++Applicable modes: normal visual-line. ++ ++Inverts the commented state of each selected line. If the a selected line is ++commented then it is uncommented and vice versa. Each line is examined and ++commented/uncommented individually. ++ ++With this mapping, a line is only considered to be commented if it starts with ++a left delimiter. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.6 Sexy comment map *NERDComSexyComment* ++ ++Default mapping: [count],cs ++Change the mapping with: NERDComLineSexyMap ++Applicable modes: normal, visual-line. ++ ++Comments the selected line(s) ``sexily''... see |NERDComSexyComments| for ++a description of what sexy comments are. Can only be done on filetypes for ++which there is at least one set of multipart comment delimiters specified. ++ ++Sexy comments cannot be nested and lines inside a sexy comment cannot be ++commented again. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDCompactSexyComs| ++ ++------------------------------------------------------------------------------ ++2.2.7 Yank comment map *NERDComYankComment* ++ ++Default mapping: [count],cy ++Change the mapping with: NERDComLineYankMap ++Applicable modes: normal visual visual-line visual-block. ++ ++Same as ,cc except that it yanks the line(s) that are commented first. ++ ++------------------------------------------------------------------------------ ++2.2.8 Comment to EOL map *NERDComEOLComment* ++ ++Default mapping: ,c$ ++Change the mapping with: NERDComToEOLMap ++Applicable modes: normal. ++ ++Comments the current line from the current cursor position up to the end of ++the line. ++ ++------------------------------------------------------------------------------ ++2.2.9 Append com to line map *NERDComAppendComment* ++ ++Default mapping: ,cA ++Change the mapping with: NERDAppendComMap. ++Applicable modes: normal. ++ ++Appends comment delimiters to the end of the current line and goes ++to insert mode between the new delimiters. ++ ++------------------------------------------------------------------------------ ++2.2.10 Prepend com to line map *NERDComPrependComment* ++ ++Default mapping: ,cI ++Change the mapping with: NERDPrependComMap. ++Applicable modes: normal. ++ ++Prepends comment delimiters to the start of the current line and goes to ++insert mode between the new delimiters. ++ ++------------------------------------------------------------------------------ ++2.2.11 Insert comment map *NERDComInsertComment* ++ ++Default mapping: ++Change the mapping with: NERDComInInsertMap. ++Applicable modes: insert. ++ ++Adds comment delimiters at the current cursor position and inserts ++between them. ++ ++------------------------------------------------------------------------------ ++2.2.12 Use alternate delims map *NERDComAltDelim* ++ ++Default mapping: ,ca ++Change the mapping with: NERDAltComMap ++Applicable modes: normal. ++ ++Changes to the alternative commenting style if one is available. For example, ++if the user is editing a c++ file using // comments and they hit ,ca ++then they will be switched over to /**/ comments. ++ ++See also |NERDComDefaultDelims| ++ ++------------------------------------------------------------------------------ ++2.2.13 Comment aligned maps *NERDComAlignedComment* ++ ++Default mappings: [count],cl [count],cr [count],cb ++Change the mappings with: NERDComAlignLeftMap, NERDComAlignRightMap and ++NERDComAlignBothMap. ++Applicable modes: normal visual-line. ++ ++Same as ,cc except that the comment delimiters are aligned on the left ++side, right side or both sides respectively. These comments are always nested ++if the line(s) are already commented. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.14 Uncomment line map *NERDComUncommentLine* ++ ++Default mapping: [count],cu ++Change the mapping with: NERDUncomLineMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++Uncomments the current line. If multiple lines are selected in ++visual mode then they are all uncommented. ++ ++When uncommenting, if the line contains multiple sets of delimiters then the ++``outtermost'' pair of delimiters will be removed. ++ ++The script uses a set of heurisics to distinguish ``real'' delimiters from ++``fake'' ones when uncommenting. See |NERDComIssues| for details. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDRemoveAltComs| ++|NERDRemoveExtraSpaces| ++ ++------------------------------------------------------------------------------ ++2.3 Supported filetypes {{{3 *NERDComFiletypes* ++ ++Filetypes that can be commented by this plugin: ++abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asn ++aspvbs atlas autohotkey autoit automake ave awk basic b bc bdf bib bindzone ++bst btm caos catalog c cfg cg ch changelog cl clean clipper cmake conf config ++context cpp crontab cs csc csp css cterm cupl csv cvs dcl debchangelog ++debcontrol debsources def diff django docbk dns dosbatch dosini dot dracula ++dsl dtd dtml dylan ecd eiffel elf elmfilt erlang eruby eterm expect exports ++fetchmail fgl focexec form fortran foxpro fstab fvwm fx gdb gdmo geek ++gentoo-package-keywords' gentoo-package-mask' gentoo-package-use' gnuplot ++gtkrc haskell hb h help hercules hog html htmldjango htmlos ia64 icon idlang ++idl indent inform inittab ishd iss ist jam java javascript jess jgraph ++jproperties jproperties jsp kconfig kix kscript lace lex lftp lifelines lilo ++lisp lite lotos lout lprolog lscript lss lua lynx m4 mail make maple masm ++master matlab mel mf mib mma model moduala. modula2 modula3 monk mush muttrc ++named nasm nastran natural ncf netdict netrw nqc nroff nsis objc ocaml occam ++omlet omnimark openroad opl ora otl ox pascal passwd pcap pccts perl pfmain ++php phtml pic pike pilrc pine plaintex plm plsql po postscr pov povini ppd ++ppwiz procmail progress prolog psf ptcap python python qf radiance ratpoison r ++rc readline rebol registry remind rexx robots rpl rtf ruby sa samba sas sass ++sather scheme scilab screen scsh sdl sed selectbuf sgml sgmldecl sgmllnx sh ++sicad simula sinda skill slang sl slrnrc sm smarty smil smith sml snnsnet ++snnspat snnsres snobol4 spec specman spice sql sqlforms sqlj sqr squid st stp ++strace svn systemverilog tads taglist tags tak tasm tcl terminfo tex text ++plaintex texinfo texmf tf tidy tli trasys tsalt tsscl tssgm uc uil vb verilog ++verilog_systemverilog vgrindefs vhdl vim viminfo virata vo_base vrml vsejcl ++webmacro wget winbatch wml wvdial xdefaults xf86conf xhtml xkb xmath xml ++xmodmap xpm2 xpm xslt yacc yaml z8a ++ ++If a language is not in the list of hardcoded supported filetypes then the ++&commentstring vim option is used. ++ ++------------------------------------------------------------------------------ ++2.4 Sexy Comments {{{3 *NERDComSexyComments* ++These are comments that use one set of multipart comment delimiters as well as ++one other marker symbol. For example: > ++ /* ++ * This is a c style sexy comment ++ * So there! ++ */ ++ ++ /* This is a c style sexy comment ++ * So there! ++ * But this one is ``compact'' style */ ++< ++Here the multipart delimiters are /* and */ and the marker is *. The NERD ++commenter is capable of adding and removing comments of this type. ++ ++------------------------------------------------------------------------------ ++2.5 The NERDComment function {{{3 *NERDComNERDComment* ++ ++All of the NERD commenter mappings and menu items invoke a single function ++which delegates the commenting work to other functions. This function is ++public and has the prototype: > ++ function! NERDComment(isVisual, type) ++< ++The arguments to this function are simple: ++ - isVisual: if you wish to do any kind of visual comment then set this to ++ 1 and the function will use the '< and '> marks to find the comment ++ boundries. If set to 0 then the function will operate on the current ++ line. ++ - type: is used to specify what type of commenting operation is to be ++ performed, and it can be one of the following: 'sexy', 'invert', ++ 'minimal', 'toggle', 'alignLeft', 'alignRight', 'alignBoth', 'norm', ++ 'nested', 'toEOL', 'prepend', 'append', 'insert', 'uncomment', 'yank' ++ ++For example, if you typed > ++ :call NERDComment(1, 'sexy') ++< ++then the script would do a sexy comment on the last visual selection. ++ ++ ++============================================================================== ++3. Options {{{2 *NERDComOptions* ++ ++------------------------------------------------------------------------------ ++3.1 Options summary *NERDComOptionsSummary* ++ ++|loaded_nerd_comments| Turns off the script. ++|NERDAllowAnyVisualDelims| Allows multipart alternative delims to ++ be used when commenting in ++ visual/visual-block mode. ++|NERDBlockComIgnoreEmpty| Forces right delims to be placed when ++ doing visual-block comments. ++|NERDCommentWholeLinesInVMode| Changes behaviour of visual comments. ++|NERDDefaultNesting| Tells the script to use nested comments ++ by default. ++|NERDMenuMode| Specifies how the NERD commenter menu ++ will appear (if at all). ++|NERDLPlace| Specifies what to use as the left ++ delimiter placeholder when nesting ++ comments. ++|NERDMapleader| Specifies what all the commenting key ++ mappings will begin with. ++|NERDUsePlaceHolders| Specifies which filetypes may use ++ placeholders when nesting comments. ++|NERDRemoveAltComs| Tells the script whether to remove ++ alternative comment delimiters when ++ uncommenting. ++|NERDRemoveExtraSpaces| Tells the script to always remove the ++ extra spaces when uncommenting ++ (regardless of whether NERDSpaceDelims ++ is set) ++|NERDRPlace| Specifies what to use as the right ++ delimiter placeholder when nesting ++ comments. ++|NERDShutUp| Stops "Unknown filetype" output from the ++ script ++|NERDSpaceDelims| Specifies whether to add extra spaces ++ around delimiters when commenting, and ++ whether to remove them when ++ uncommenting. ++|NERDCompactSexyComs| Specifies whether to use the compact ++ style sexy comments. ++ ++------------------------------------------------------------------------------ ++3.3 Options details *NERDComOptionsDetails* ++ ++To enable any of the below options you should put the given line in your ++~/.vimrc ++ ++ *loaded_nerd_comments* ++If this script is driving you insane you can turn it off by setting this ++option > ++ let loaded_nerd_comments=1 ++< ++------------------------------------------------------------------------------ ++ *NERDAllowAnyVisualDelims* ++Values: 0 or 1. ++Default: 1. ++ ++If set to 1 then, when doing a visual or visual-block comment (but not a ++visual-line comment), the script will choose the right delimiters to use for ++the comment. This means either using the current delimiters if they are ++multipart or using the alternative delimiters if THEY are multipart. For ++example if we are editing the following java code: > ++ float foo = 1221; ++ float bar = 324; ++ System.out.println(foo * bar); ++< ++If we are using // comments and select the "foo" and "bar" in visual-block ++mode, as shown left below (where '|'s are used to represent the visual-block ++boundary), and comment it then the script will use the alternative delims as ++shown on the right: > ++ ++ float |foo| = 1221; float /*foo*/ = 1221; ++ float |bar| = 324; float /*bar*/ = 324; ++ System.out.println(foo * bar); System.out.println(foo * bar); ++< ++------------------------------------------------------------------------------ ++ *NERDBlockComIgnoreEmpty* ++Values: 0 or 1. ++Default: 1. ++ ++This option affects visual-block mode commenting. If this option is turned ++on, lines that begin outside the right boundary of the selection block will be ++ignored. ++ ++For example, if you are commenting this chunk of c code in visual-block mode ++(where the '|'s are used to represent the visual-block boundary) > ++ #include ++ #include ++ #include ++ |int| main(){ ++ | | printf("SUCK THIS\n"); ++ | | while(1){ ++ | | fork(); ++ | | } ++ |} | ++< ++If NERDBlockComIgnoreEmpty=0 then this code will become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ /* */ printf("SUCK THIS\n"); ++ /* */ while(1){ ++ /* */ fork(); ++ /* */ } ++ /*} */ ++< ++Otherwise, the code block would become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ printf("SUCK THIS\n"); ++ while(1){ ++ fork(); ++ } ++ /*} */ ++< ++------------------------------------------------------------------------------ ++ *NERDCommentWholeLinesInVMode* ++Values: 0, 1 or 2. ++Default: 0. ++ ++By default the script tries to comment out exactly what is selected in visual ++mode (v). For example if you select and comment the following c code (using | ++to represent the visual boundary): > ++ in|t foo = 3; ++ int bar =| 9; ++ int baz = foo + bar; ++< ++This will result in: > ++ in/*t foo = 3;*/ ++ /*int bar =*/ 9; ++ int baz = foo + bar; ++< ++But some people prefer it if the whole lines are commented like: > ++ /*int foo = 3;*/ ++ /*int bar = 9;*/ ++ int baz = foo + bar; ++< ++If you prefer the second option then stick this line in your vimrc: > ++ let NERDCommentWholeLinesInVMode=1 ++< ++ ++If the filetype you are editing only has no multipart delimiters (for example ++a shell script) and you hadnt set this option then the above would become > ++ in#t foo = 3; ++ #int bar = 9; ++< ++(where # is the comment delimiter) as this is the closest the script can ++come to commenting out exactly what was selected. If you prefer for whole ++lines to be commented out when there is no multipart delimiters but the EXACT ++text that was selected to be commented out if there IS multipart delimiters ++then stick the following line in your vimrc: > ++ let NERDCommentWholeLinesInVMode=2 ++< ++ ++Note that this option does not affect the behaviour of |visual-block| mode. ++ ++------------------------------------------------------------------------------ ++ *NERDRemoveAltComs* ++Values: 0 or 1. ++Default: 1. ++ ++When uncommenting a line (for a filetype with an alternative commenting style) ++this option tells the script whether to look for, and remove, comments ++delimiters of the alternative style. ++ ++For example, if you are editing a c++ file using // style comments and you go ++,cu on this line: > ++ /* This is a c++ comment baby! */ ++< ++It will not be uncommented if the NERDRemoveAltComs is set to 0. ++ ++------------------------------------------------------------------------------ ++ *NERDRemoveExtraSpaces* ++Values: 0 or 1. ++Default: 1. ++ ++By default, the NERD commenter will remove spaces around comment delimiters if ++either: ++1. |NERDSpaceDelims| is set to 1. ++2. NERDRemoveExtraSpaces is set to 1. ++ ++This means that if we have the following lines in a c code file: > ++ /* int foo = 5; */ ++ /* int bar = 10; */ ++ int baz = foo + bar ++< ++If either of the above conditions hold then if these lines are uncommented ++they will become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++Otherwise they would become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++If you want the spaces to be removed only if |NERDSpaceDelims| is set then ++set NERDRemoveExtraSpaces to 0. ++ ++------------------------------------------------------------------------------ ++ *NERDLPlace* ++ *NERDRPlace* ++Values: arbitrary string. ++Default: ++ NERDLPlace: "[>" ++ NERDRPlace: "<]" ++ ++These options are used to control the strings used as place-holder delimiters. ++Place holder delimiters are used when performing nested commenting when the ++filetype supports commenting styles with both left and right delimiters. ++To set these options use lines like: > ++ let NERDLPlace="FOO" ++ let NERDRPlace="BAR" ++< ++Following the above example, if we have line of c code: > ++ /* int horse */ ++< ++and we comment it with ,cn it will be changed to: > ++ /*FOO int horse BAR*/ ++< ++When we uncomment this line it will go back to what it was. ++ ++------------------------------------------------------------------------------ ++ *NERDMapleader* ++Values: arbitrary string. ++Default: \c ++ ++NERDMapleader is used to specify what all the NERD commenter key mappings ++begin with. ++ ++The default key mappings will look like this: > ++ \cc ++ \cu ++ \ca ++ \ci ++ \cs ++ ... ++< ++However, if this line: > ++ let NERDMapleader = ',x' ++< ++were present in your vimrc then the default mappings would look like this: > ++ ,xc ++ ,xu ++ ,xa ++ ,xi ++ ,xs ++ ... ++< ++This option only affects the mappings that have not been explicitly set ++manually (see |NERDComMappings|). ++ ++------------------------------------------------------------------------------ ++ *NERDMenuMode* ++Values: 0, 1, 2, 3. ++Default: 3 ++ ++This option can take 4 values: ++ "0": Turns the menu off. ++ "1": Turns the 'comment' menu on with no menu shortcut. ++ "2": Turns the 'comment 'menu on with -c as the shortcut. ++ "3": Turns the 'Plugin -> comment' menu on with -c as the shortcut. ++ ++------------------------------------------------------------------------------ ++ *NERDUsePlaceHolders* ++Values: 0 or 1. ++Default 1. ++ ++This option is used to specify whether place-holder delimiters should be used ++when adding nested comments. ++ ++------------------------------------------------------------------------------ ++ *NERDShutUp* ++Values: 0 or 1. ++Default 1. ++ ++This option is used to prevent the script from echoing "Unknown filetype" ++messages. Stick this line in your vimrc: > ++ let NERDShutUp=1 ++< ++------------------------------------------------------------------------------ ++ *NERDSpaceDelims* ++Values: 0 or 1. ++Default 0. ++ ++Some people prefer a space after the left delimiter and before the right ++delimiter like this: > ++ /* int foo=2; */ ++< ++as opposed to this: > ++ /*int foo=2;*/ ++< ++If you want spaces to be added then set NERDSpaceDelims to 1 in your vimrc. ++ ++See also |NERDRemoveExtraSpaces|. ++ ++------------------------------------------------------------------------------ ++ *NERDCompactSexyComs* ++Values: 0 or 1. ++Default 0. ++ ++Some people may want their sexy comments to be like this: > ++ /* Hi There! ++ * This is a sexy comment ++ * in c */ ++< ++As opposed to like this: > ++ /* ++ * Hi There! ++ * This is a sexy comment ++ * in c ++ */ ++< ++If this option is set to 1 then the top style will be used. ++ ++------------------------------------------------------------------------------ ++ *NERDDefaultNesting* ++Values: 0 or 1. ++Default 0. ++ ++When this option is set to 1, comments are nested automatically. That is, if ++you hit ,cc on a line that is already commented it will be commented ++again ++ ++------------------------------------------------------------------------------ ++3.3 Default delimiter customisation *NERDComDefaultDelims* ++ ++If you want the NERD commenter to use the alternative delimiters for a ++specific filetype by default then put a line of this form into your vimrc: > ++ let NERD_<&filetype>_alt_style=1 ++< ++Example: java uses // style comments by default, but you want it to default to ++/* */ style comments instead. You would put this line in your vimrc: > ++ let NERD_java_alt_style=1 ++< ++ ++See |NERDComAltDelim| for switching commenting styles at runtime. ++ ++------------------------------------------------------------------------------ ++3.4 Key mapping customisation *NERDComMappings* ++ ++These options are used to override the default keys that are used for the ++commenting mappings. Their values must be set to strings. As an example: if ++you wanted to use the mapping ,foo to uncomment lines of code then ++you would place this line in your vimrc > ++ let NERDUncomLineMap=",foo" ++< ++Check out |NERDComFunctionality| for details about what the following ++mappings do. ++ ++Default Mapping Option to override~ ++ ++,ca NERDAltComMap ++,ce NERDAppendComMap ++,cl NERDComAlignLeftMap ++,cb NERDComAlignBothMap ++,cr NERDComAlignRightMap ++ NERDComInInsertMap ++,ci NERDComLineInvertMap ++,cc NERDComLineMap ++,cn NERDComLineNestMap ++,cs NERDComLineSexyMap ++,c NERDComLineToggleMap ++,cm NERDComLineMinimalMap ++,c$ NERDComToEOLMap ++,cy NERDComLineYankMap ++,cu NERDUncomLineMap ++ ++============================================================================== ++4. Issues with the script{{{2 *NERDComIssues* ++ ++ ++------------------------------------------------------------------------------ ++4.1 Delimiter detection heuristics *NERDComHeuristics* ++ ++Heuristics are used to distinguish the real comment delimiters ++ ++Because we have comment mappings that place delimiters in the middle of lines, ++removing comment delimiters is a bit tricky. This is because if comment ++delimiters appear in a line doesnt mean they really ARE delimiters. For ++example, Java uses // comments but the line > ++ System.out.println("//"); ++< ++clearly contains no real comment delimiters. ++ ++To distinguish between ``real'' comment delimiters and ``fake'' ones we use a ++set of heuristics. For example, one such heuristic states that any comment ++delimiter that has an odd number of non-escaped " characters both preceding ++and following it on the line is not a comment because it is probably part of a ++string. These heuristics, while usually pretty accurate, will not work for all ++cases. ++ ++------------------------------------------------------------------------------ ++4.2 Nesting issues *NERDComNesting* ++ ++If we have some line of code like this: > ++ /*int foo */ = /*5 + 9;*/ ++< ++This will not be uncommented legally. The NERD commenter will remove the ++"outter most" delimiters so the line will become: > ++ int foo */ = /*5 + 9; ++< ++which almost certainly will not be what you want. Nested sets of comments will ++uncomment fine though. Eg: > ++ /*int/* foo =*/ 5 + 9;*/ ++< ++will become: > ++ int/* foo =*/ 5 + 9; ++< ++(Note that in the above examples I have deliberately not used place holders ++for simplicity) ++ ++============================================================================== ++6. The author {{{2 *NERDComAuthor* ++ ++The author of the NERD commenter is Martyzillatron --- the half robot, half ++dinosaur bastard son of Megatron and Godzilla. He enjoys destroying ++metropolises and eating tourist busses. ++ ++Drop him a line at martin_grenfell at msn.com. He would love to hear from you. ++its a lonely life being the worlds premier terror machine. How would you feel ++if your face looked like a toaster and a t-rex put together? :( ++ ++============================================================================== ++7. TODO list {{{2 *NERDComTodo* ++ ++Uncommenting of minimal comments needs to be more robust. Currently it is easy ++to get illegal syntax when uncommenting them. ++ ++ ++ ++============================================================================== ++8. Changelog {{{2 *NERDComChangelog* ++ ++2.1.4 ++ - added support for the ahk filetype. Cheers to Don Hatlestad for the ++ email. ++ - added support for desktop and xsd filetypes. Thanks to Christophe Benz. ++ - added dummy support for Rails-log ++ - fixed a bunch of bugs in the comment delimiter setup process, thanks to ++ Cheng Fang for the email :D ++ - hardcore refactoring and removal of seldomly used, overly-complex ++ functionality. ++ - the script now requires vim 7 ++2.1.3 ++ - fixed numerous bugs that were causing tabs to permanently be converted ++ to spaces, even if noexpandtab was set. Thanks to Heptite on #vim for ++ working with me to track them down :) ++ - added dummy support for "lookupfile". Thanks to David Fishburn for the ++ email. ++ - added support for "rst", thanks to Niels Aan de Brugh for the email. ++ ++2.1.2 ++ - added support for the vera and ldif filetypes. Thanks to Normandie ++ Azucena and Florian Apolloner for the emails. ++ ++2.1.1 ++ - added dummy support for SVNcommitlog and vcscommit. Thanks to John ++ O'Shea for the email. ++ - added support for Groovy. Thanks to Jason Mills for the email. ++2.1.0 ++ - now the script resets the delimiters when the filetype of the buffer ++ changes (thanks to James Hales for the patch) ++ - added formal support/doc for prepending a count to many of the ++ commenting maps so you can go, eg, 5,cc to comment 5 lines from normal ++ mode. Thanks again to James Hales for the patch. ++ - added support for the "gams" filetype that Jorge Rodrigues created. ++ - added support for the "objc" filetype, thanks to Rainer Müller for the ++ email. ++ - added support for the "sass" filetype that Dmitry Ilyashevich created. ++ ++2.0.7 ++ - Added support for eclass and ebuild filetypes. Thanks to Alex Tarkovsky ++ for the email. ++ ++2.0.6 ++ - Changed the default setting of NERDMapleader to ",c", meaning all the ++ maps now start with ,c instead of \c. This is to stop a major mapping ++ clash with the vcscommand plugin. Anyone wanting to keep the \c map ++ leader should read :help NERDMapleader. ++ - Added support for debcontrol and dummy support for debchangelog ++ filetypes, thanks to Stefano Zacchiroli for the email. ++ - Made it so that the NERDShutUp option now only controls the "Pleeease ++ email the delimiters..." requests. It no longer affects the general ++ output of the script. ++ - Simplified the names of the help tags. ++ ++2.0.5 ++ - Added support for autoit, autohotkey and docbk filetypes (thanks to ++ Michael Böhler) ++ - Added support for cmake (thanks to Aaron Small) ++ - Added support for htmldjango and django filetypes (thanks to Ramiro ++ Morales) ++ - Improved the delimiters for eruby again ++ - Applied a patch from Seth Mason to fix some pathing issues with the help ++ file installation. ++ ++2.0.4 ++ - Added support for verilog_systemverilog and systemverilog filetypes ++ (Thanks to Alexey for the email) ++ - Added support for fstab, thanks to Lizendir for the email. ++ - Added support for the smarty filetype. ++ - Improved the delimiters for eruby. ++ - Added dummy support for changelog filetype. ++ ++2.0.3 ++ - Added dummy support for the csv filetype (thx to Mark Woodward for the ++ email) ++ - Added dummy support for vo_base and otl filetypes (thanks to fREW for ++ the email) ++ ++2.0.2: ++ - Minor bug fix that was stopping nested comments from working ++ ++2.0.1: ++ - Fixed the visual bell for the |NERDComToEOLMap| map. ++ - Added another possible value to the NERDMenuMode option which causes the ++ menu to be displayed under 'Plugin -> Comment'. See :h NERDMenuMode. ++ This new menu mode is now the default. ++ - Added support for the occam filetype (thanks to Anders for emailing me) ++ - Made the main commenting function (NERDComment) available outside the ++ script. ++ - bug fixes and refactoring ++ ++2.0.0: ++ - NOTE: renamed the script to NERD_commenter.vim. When you install this ++ version you must delete the old files: NERD_comments.vim and ++ NERD_comments.txt. ++ - Reworked the mappings and main entry point function for the script to ++ avoid causing visual-bells and screen scrolling. ++ - Changes to the script options (see |NERD_com-Customisation| for ++ details): ++ - They are all camel case now instead of underscored. ++ - Converted all of the regular expression options into simple boolean ++ options for simplicity. ++ - All the options are now stated positively, eg. ++ NERD_dont_remove_spaces_regexp has become NERDRemoveExtraSpaces. ++ - Some of the option names have been changed (other than in the above ++ ways) ++ - Some have been removed altogether, namely: NERD_create_h_filetype ++ (why was a commenting script creating a filetype?!), ++ NERD_left_align_regexp, NERD_right_align_regexp, ++ ++ - Removed all the NERD_use_alt_style_XXX_coms options and replaced them ++ with a better system. Now if a filetype has alternative delims, the ++ script will check whether an option of the form ++ "NERD_<&filetype>_alt_style" exists, and if it does then alt delims will ++ be used. See |NERD_com-cust-delims| for details. ++ - The script no longer removes extra spaces for sexy comments for the ++ NERDRemoveExtraSpaces option (it will still remove spaces if ++ NERDSpaceDelims is set). ++ - Added dummy support for viminfo and rtf. ++ - Added support for the "gentoo-package-\(keywords\|mask\|use\)" ++ filetypes. ++ - Added '#' comments as an alternative for the asm filetype ++ ++Thanks to Markus Klinik and Anders for bug reports, and again to Anders ++for his patch. Thanks to John O'Shea and fREW for the filetype ++information. ++ ++============================================================================== ++8. Credits {{{2 *NERDComCredits* ++ ++Thanks and respect to the following people: ++ ++Thanks to Nick Brettell for his many ideas and criticisms. A bloody good ++bastard. ++:normal :.-2s/good// ++ ++Thanks to Matthew Hawkins for his awesome refactoring! ++ ++Thanks to the authors of the vimspell whose documentation ++installation function I stole :) ++ ++Thanks to Greg Searle for the idea of using place-holders for nested comments. ++ ++Thanks to Nguyen for the suggestions and pointing the h file highlighting bug! ++Also, thanks for the idea of doing sexy comments as well as his suggestions ++relating to it :P ++Thanks again to Nguyen for complaining about the NERD_comments menu mapping ++(-c) interfering with another mapping of his... and thus the ++NERD_dont_create_menu_shortcut option was born :P ++(it was then replaced with NERD_menu_mode in version 1.67 :) ++ ++Thanks to Sam R for pointing out some filetypes that NERD_comments could support! ++ ++Cheers to Litchi for the idea of having a mapping that appends a comment to ++the current line :) ++ ++Thanks to jorge scandaliaris and Shufeng Zheng for telling me about some ++problems with commenting in visual mode. Thanks again to Jorge for his ++continued suggestions on this matter :) ++ ++Thanks to Martin Stubenschrott for pointing out a bug with the mapping ++:) Ive gotta stop breaking this mapping! ++ ++Thanks to Markus Erlmann for pointing out a conflict that this script was ++having with the taglist plugin. ++ ++Thanks to Brent Rice for alerting me about, and helping me track down, a bug ++in the script when the "ignorecase" option in vim was set. ++ ++Thanks to Richard Willis for telling me about how line continuation was ++causing problems on cygwin. Also, thanks pointing out a bug in the help file ++and for suggesting // comments for c (its about time SOMEONE did :P). May ANSI ++have mercy on your soul :) ++ ++Thanks to Igor Prischepoff for suggesting that i implement "toggle comments". ++Also, thanks for his suggested improvements about toggle comments after i ++implemented them. ++ ++Thanks to harry for telling me that i broke the cn mapping in 1.53 :), ++and thanks again for telling me about a bug that occurred when editing a file ++in a new tab. ++ ++Thanks to Martin (Krischikim?) for his patch that fixed a bug with the doc ++install function and added support for ada comments with spaces as well as ++making a couple of other small changes. ++ ++Thanks to David Bourgeois for pointing out a bug with when commenting c files ++:)... [a few days later] ok i completely misunderstood what David was talking ++about and ended up fixing a completely different bug to what he was talking ++about :P ++ ++Thanks to David Bourgeois for pointing out a bug when changing buffers. ++ ++Cheers to Eike Von Seggern for sending me a patch to fix a bug in 1.60 that ++was causing spaces to be added to the end of lines with single-part ++delimiters. It's nice when people do my work for me :D ++ ++Thanks to Torsten Blix for telling me about a couple of bugs when uncommenting ++sexy comments. Sexy comments dont look so sexy when they are only half removed ++:P ++ ++Thanks to Alexander "boesi" Bosecke for pointing out a bug that was stopping ++the NERD_space_delim_filetype_regexp option from working with left aligned ++toggle comments. And for pointing out a bug when initialising VB comments. ++ ++Thanks to Stefano Zacchiroli for suggesting the idea of "Minimal comments". ++And for suggested improvements to minimal comments. ++ ++Thanks to Norick Chen for emailing in a patch that fixed the asp delimiters. ++In 1.65 ++ ++Thanks to Jonathan Derque for alerting me to some filetypes that could be ++supported (Namely: context, plaintext and mail). ++ ++Thanks to Joseph Barker for the sugesting that the menu be an optional ++feature. ++ ++Thanks to Gary Church and Tim Carey-Smith for complaining about the ++keymappings and causing me to introduce the NERD_mapleader option :) ++ ++Thanks to Vigil for pointing out that the "fetchmail" filetype was not ++supported and emailing me the delimiters ++ ++Thanks to Michael Brunner for telling me about the kconfig filetype. ++ ++Thanks to Antono Vasiljev for telling me about the netdict filetype. ++ ++Thanks to Melissa Reid for telling me about the omlet filetype. ++ ++Thanks to Ilia N Ternovich for alerting me to the 'qf' (quickfix) filetype. ++ ++Thanks to Markus Klinik for emailing me about a bug for sexy comments where ++spaces were being eaten. ++ ++Thanks to John O'Shea for emailing me about the RTF filetype. Thanks again for ++the SVNcommitlog and vcscommit filetypes. ++ ++Thanks to Anders for emailing me a patch to help get rid of all the visual ++bells and screen scrolling, and for sending me the delimiters for the occam ++filetype. ++ ++Thanks to Anders and Markus Klinik for emailing me about the screen scrolling ++issues and finally getting me off my ass about them :P ++ ++Thanks to Mark Woodward for emailing me about the csv filetype. ++ ++Thanks to fREW for emailing me with the /gentoo-package-(mask|keywords|use)/ ++filetypes the vo_base filetype. ++ ++Thanks to Alexey for emailing me about the verilog_systemverilog/systemverilog ++filetypes. ++ ++Cheers to Lizendir for the email about the fstab filetype ++ ++Thanks to Michael Böhler for emailing me with the autoit, autohotkey and docbk ++filetypes. ++ ++Thanks to Aaron Small for emailing me about the cmake filetype. ++ ++Thanks to Ramiro for emailing me about the htmldjango and django filetypes. ++ ++Thanks to Seth Mason for sending me a patch to fix some pathing issues for the ++help doc installation. ++ ++Thanks to Stefano Zacchiroli for emailing me with the debcontrol and ++debchangelog filetypes. ++ ++Thanks to Alex Tarkovsky for emailing me about the ebuild and eclass ++filetypes. ++ ++Cheers to Jorge Rodrigues for emailing me about the gams filetype. ++ ++Cheers to James Hales for the patch that made the comment maps work better with ++counts, and made the script reset comment delims for a buffer when its ++filetype changes. ++ ++Thank to Rainer Müller for emailing me with the Objective C delimiters. ++ ++Thanks to Jason Mills for emailing me the Groovy filetype. ++ ++Thanks to Normandie Azucena for emailing me about the vera filetype. ++ ++Thanks to Florian Apolloner for emailing me about the ldif filetype. ++ ++Cheers to David Fishburn for emailing me with the lookupfile filetype. ++ ++Thanks to Niels Aan de Brugh for emailing me with the rst filetype. ++ ++Cheers to heptite on #vim for helping me track down some tab-space conversion ++bugs. ++ ++Cheers to Don Hatlestad for telling me about the ahk filetype ++ ++Thanks to Christophe Benz for emailing me with the Desktop and xsd filetypes. ++ ++Cheers to Cheng Fang for the bug reports :D ++ ++Cheers to myself for being the best looking man on Earth! ++=== END_DOC ++" vim: set foldmethod=marker : +diff -urN vim71/1/plugin/.svn/all-wcprops vim71_ada/1/plugin/.svn/all-wcprops +--- vim71/1/plugin/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,23 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 51 ++/svnroot/gnuada/!svn/ver/818/trunk/tools/vim/plugin ++END ++taglist.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 63 ++/svnroot/gnuada/!svn/ver/695/trunk/tools/vim/plugin/taglist.vim ++END ++matchit.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 63 ++/svnroot/gnuada/!svn/ver/695/trunk/tools/vim/plugin/matchit.vim ++END ++NERD_commenter.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/svnroot/gnuada/!svn/ver/782/trunk/tools/vim/plugin/NERD_commenter.vim ++END +diff -urN vim71/1/plugin/.svn/dir-prop-base vim71_ada/1/plugin/.svn/dir-prop-base +--- vim71/1/plugin/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/plugin/.svn/entries vim71_ada/1/plugin/.svn/entries +--- vim71/1/plugin/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,67 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/plugin ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-12-03T21:21:48.223203Z ++818 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++taglist.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++2b4bbfd48d8655d77f21de415fbc444e ++2007-04-27T17:57:11.151403Z ++695 ++krischik ++has-props ++ ++matchit.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++e632c123b83638c701624d105b6dfebf ++2007-04-27T17:57:11.151403Z ++695 ++krischik ++has-props ++ ++NERD_commenter.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++a26e65639bda5a42c1f3e5661839739b ++2007-10-18T14:36:32.640792Z ++782 ++krischik ++has-props ++ +diff -urN vim71/1/plugin/.svn/format vim71_ada/1/plugin/.svn/format +--- vim71/1/plugin/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/format 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/plugin/.svn/prop-base/matchit.vim.svn-base vim71_ada/1/plugin/.svn/prop-base/matchit.vim.svn-base +--- vim71/1/plugin/.svn/prop-base/matchit.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/prop-base/matchit.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/plugin/.svn/prop-base/NERD_commenter.vim.svn-base vim71_ada/1/plugin/.svn/prop-base/NERD_commenter.vim.svn-base +--- vim71/1/plugin/.svn/prop-base/NERD_commenter.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/prop-base/NERD_commenter.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/plugin/.svn/prop-base/taglist.vim.svn-base vim71_ada/1/plugin/.svn/prop-base/taglist.vim.svn-base +--- vim71/1/plugin/.svn/prop-base/taglist.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/prop-base/taglist.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/plugin/.svn/text-base/matchit.vim.svn-base vim71_ada/1/plugin/.svn/text-base/matchit.vim.svn-base +--- vim71/1/plugin/.svn/text-base/matchit.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/text-base/matchit.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,814 @@ ++" matchit.vim: (global plugin) Extended "%" matching ++" Last Change: Tue Oct 24 11:00 AM 2006 EDT ++" Maintainer: Benji Fisher PhD ++" Version: 1.12, for Vim 6.3+ ++" URL: http://www.vim.org/script.php?script_id=39 ++ ++" Documentation: ++" The documentation is in a separate file, matchit.txt . ++ ++" Credits: ++" Vim editor by Bram Moolenaar (Thanks, Bram!) ++" Original script and design by Raul Segura Acevedo ++" Support for comments by Douglas Potts ++" Support for back references and other improvements by Benji Fisher ++" Support for many languages by Johannes Zellner ++" Suggestions for improvement, bug reports, and support for additional ++" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark ++" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner. ++ ++" Debugging: ++" If you'd like to try the built-in debugging commands... ++" :MatchDebug to activate debugging for the current buffer ++" This saves the values of several key script variables as buffer-local ++" variables. See the MatchDebug() function, below, for details. ++ ++" TODO: I should think about multi-line patterns for b:match_words. ++" This would require an option: how many lines to scan (default 1). ++" This would be useful for Python, maybe also for *ML. ++" TODO: Maybe I should add a menu so that people will actually use some of ++" the features that I have implemented. ++" TODO: Eliminate the MultiMatch function. Add yet another argument to ++" Match_wrapper() instead. ++" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' ++" TODO: Make backrefs safer by using '\V' (very no-magic). ++" TODO: Add a level of indirection, so that custom % scripts can use my ++" work but extend it. ++ ++" allow user to prevent loading ++" and prevent duplicate loading ++if exists("loaded_matchit") || &cp ++ finish ++endif ++let loaded_matchit = 1 ++let s:last_mps = "" ++let s:last_words = "" ++ ++let s:save_cpo = &cpo ++set cpo&vim ++ ++nnoremap % :call Match_wrapper('',1,'n') ++nnoremap g% :call Match_wrapper('',0,'n') ++vnoremap % :call Match_wrapper('',1,'v') m'gv`` ++vnoremap g% :call Match_wrapper('',0,'v') m'gv`` ++onoremap % v:call Match_wrapper('',1,'o') ++onoremap g% v:call Match_wrapper('',0,'o') ++ ++" Analogues of [{ and ]} using matching patterns: ++nnoremap [% :call MultiMatch("bW", "n") ++nnoremap ]% :call MultiMatch("W", "n") ++vmap [% [%m'gv`` ++vmap ]% ]%m'gv`` ++" vnoremap [% :call MultiMatch("bW", "v") m'gv`` ++" vnoremap ]% :call MultiMatch("W", "v") m'gv`` ++onoremap [% v:call MultiMatch("bW", "o") ++onoremap ]% v:call MultiMatch("W", "o") ++ ++" text object: ++vmap a% [%v]% ++ ++" Auto-complete mappings: (not yet "ready for prime time") ++" TODO Read :help write-plugin for the "right" way to let the user ++" specify a key binding. ++" let g:match_auto = '' ++" let g:match_autoCR = '' ++" if exists("g:match_auto") ++" execute "inoremap " . g:match_auto . ' x"=Autocomplete()Pls' ++" endif ++" if exists("g:match_autoCR") ++" execute "inoremap " . g:match_autoCR . ' =Autocomplete()' ++" endif ++" if exists("g:match_gthhoh") ++" execute "inoremap " . g:match_gthhoh . ' :call Gthhoh()' ++" endif " gthhoh = "Get the heck out of here!" ++ ++let s:notslash = '\\\@" ++ endif ++ " In s:CleanUp(), we may need to check whether the cursor moved forward. ++ let startline = line(".") ++ let startcol = col(".") ++ " Use default behavior if called with a count or if no patterns are defined. ++ if v:count ++ exe "normal! " . v:count . "%" ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ elseif !exists("b:match_words") || b:match_words == "" ++ silent! normal! % ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ end ++ ++ " First step: if not already done, set the script variables ++ " s:do_BR flag for whether there are backrefs ++ " s:pat parsed version of b:match_words ++ " s:all regexp based on s:pat and the default groups ++ " ++ " Allow b:match_words = "GetVimMatchWords()" . ++ if b:match_words =~ ":" ++ let match_words = b:match_words ++ else ++ execute "let match_words =" b:match_words ++ endif ++" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion! ++ if (match_words != s:last_words) || (&mps != s:last_mps) || ++ \ exists("b:match_debug") ++ let s:last_words = match_words ++ let s:last_mps = &mps ++ if match_words !~ s:notslash . '\\\d' ++ let s:do_BR = 0 ++ let s:pat = match_words ++ else ++ let s:do_BR = 1 ++ let s:pat = s:ParseWords(match_words) ++ endif ++ " The next several lines were here before ++ " BF started messing with this script. ++ " quote the special chars in 'matchpairs', replace [,:] with \| and then ++ " append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif) ++ " let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+', ++ " \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>' ++ let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . ++ \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' ++ " s:all = pattern with all the keywords ++ let s:all = s:pat . (strlen(s:pat) ? "," : "") . default ++ let s:all = substitute(s:all, s:notslash . '\zs[,:]\+', '\\|', 'g') ++ let s:all = '\%(' . s:all . '\)' ++ " let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)' ++ if exists("b:match_debug") ++ let b:match_pat = s:pat ++ endif ++ endif ++ ++ " Second step: set the following local variables: ++ " matchline = line on which the cursor started ++ " curcol = number of characters before match ++ " prefix = regexp for start of line to start of match ++ " suffix = regexp for end of match to end of line ++ " Require match to end on or after the cursor and prefer it to ++ " start on or before the cursor. ++ let matchline = getline(startline) ++ if a:word != '' ++ " word given ++ if a:word !~ s:all ++ echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ endif ++ let matchline = a:word ++ let curcol = 0 ++ let prefix = '^\%(' ++ let suffix = '\)$' ++ " Now the case when "word" is not given ++ else " Find the match that ends on or after the cursor and set curcol. ++ let regexp = s:Wholematch(matchline, s:all, startcol-1) ++ let curcol = match(matchline, regexp) ++ let endcol = matchend(matchline, regexp) ++ let suf = strlen(matchline) - endcol ++ let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(') ++ let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$') ++ " If the match comes from the defaults, bail out. ++ if matchline !~ prefix . ++ \ substitute(s:pat, s:notslash.'\zs[,:]\+', '\\|', 'g') . suffix ++ silent! norm! % ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ endif ++ endif ++ if exists("b:match_debug") ++ let b:match_match = matchstr(matchline, regexp) ++ let b:match_col = curcol+1 ++ endif ++ ++ " Third step: Find the group and single word that match, and the original ++ " (backref) versions of these. Then, resolve the backrefs. ++ " Set the following local variable: ++ " group = colon-separated list of patterns, one of which matches ++ " = ini:mid:fin or ini:fin ++ " ++ " Reconstruct the version with unresolved backrefs. ++ let patBR = substitute(match_words.',', ++ \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g') ++ let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g') ++ " Now, set group and groupBR to the matching group: 'if:endif' or ++ " 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns ++ " group . "," . groupBR, and we pick it apart. ++ let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) ++ let i = matchend(group, s:notslash . ",") ++ let groupBR = strpart(group, i) ++ let group = strpart(group, 0, i-1) ++ " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix ++ if s:do_BR " Do the hard part: resolve those backrefs! ++ let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++ endif ++ if exists("b:match_debug") ++ let b:match_wholeBR = groupBR ++ let i = matchend(groupBR, s:notslash . ":") ++ let b:match_iniBR = strpart(groupBR, 0, i-1) ++ endif ++ ++ " Fourth step: Set the arguments for searchpair(). ++ let i = matchend(group, s:notslash . ":") ++ let j = matchend(group, '.*' . s:notslash . ":") ++ let ini = strpart(group, 0, i-1) ++ let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g') ++ let fin = strpart(group, j) ++ "Un-escape the remaining , and : characters. ++ let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ " searchpair() requires that these patterns avoid \(\) groups. ++ let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g') ++ let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g') ++ let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g') ++ " Set mid. This is optimized for readability, not micro-efficiency! ++ if a:forward && matchline =~ prefix . fin . suffix ++ \ || !a:forward && matchline =~ prefix . ini . suffix ++ let mid = "" ++ endif ++ " Set flag. This is optimized for readability, not micro-efficiency! ++ if a:forward && matchline =~ prefix . fin . suffix ++ \ || !a:forward && matchline !~ prefix . ini . suffix ++ let flag = "bW" ++ else ++ let flag = "W" ++ endif ++ " Set skip. ++ if exists("b:match_skip") ++ let skip = b:match_skip ++ elseif exists("b:match_comment") " backwards compatibility and testing! ++ let skip = "r:" . b:match_comment ++ else ++ let skip = 's:comment\|string' ++ endif ++ let skip = s:ParseSkip(skip) ++ if exists("b:match_debug") ++ let b:match_ini = ini ++ let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin ++ endif ++ ++ " Fifth step: actually start moving the cursor and call searchpair(). ++ " Later, :execute restore_cursor to get to the original screen. ++ let restore_cursor = virtcol(".") . "|" ++ normal! g0 ++ let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor ++ normal! H ++ let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ execute restore_cursor ++ call cursor(0, curcol + 1) ++ " normal! 0 ++ " if curcol ++ " execute "normal!" . curcol . "l" ++ " endif ++ if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) ++ let skip = "0" ++ else ++ execute "if " . skip . "| let skip = '0' | endif" ++ endif ++ let sp_return = searchpair(ini, mid, fin, flag, skip) ++ let final_position = "call cursor(" . line(".") . "," . col(".") . ")" ++ " Restore cursor position and original screen. ++ execute restore_cursor ++ normal! m' ++ if sp_return > 0 ++ execute final_position ++ endif ++ return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin) ++endfun ++ ++" Restore options and do some special handling for Operator-pending mode. ++" The optional argument is the tail of the matching group. ++fun! s:CleanUp(options, mode, startline, startcol, ...) ++ execute "set" a:options ++ " Open folds, if appropriate. ++ if a:mode != "o" ++ if &foldopen =~ "percent" ++ normal! zv ++ endif ++ " In Operator-pending mode, we want to include the whole match ++ " (for example, d%). ++ " This is only a problem if we end up moving in the forward direction. ++ elseif (a:startline < line(".")) || ++ \ (a:startline == line(".") && a:startcol < col(".")) ++ if a:0 ++ " Check whether the match is a single character. If not, move to the ++ " end of the match. ++ let matchline = getline(".") ++ let currcol = col(".") ++ let regexp = s:Wholematch(matchline, a:1, currcol-1) ++ let endcol = matchend(matchline, regexp) ++ if endcol > currcol " This is NOT off by one! ++ execute "normal!" . (endcol - currcol) . "l" ++ endif ++ endif " a:0 ++ endif " a:mode != "o" && etc. ++ return 0 ++endfun ++ ++" Example (simplified HTML patterns): if ++" a:groupBR = '<\(\k\+\)>:' ++" a:prefix = '^.\{3}\(' ++" a:group = '<\(\k\+\)>:' ++" a:suffix = '\).\{2}$' ++" a:matchline = "12312" or "12312" ++" then extract "tag" from a:matchline and return ":" . ++fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++ if a:matchline !~ a:prefix . ++ \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix ++ return a:group ++ endif ++ let i = matchend(a:groupBR, s:notslash . ':') ++ let ini = strpart(a:groupBR, 0, i-1) ++ let tailBR = strpart(a:groupBR, i) ++ let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix, ++ \ a:groupBR) ++ let i = matchend(word, s:notslash . ":") ++ let wordBR = strpart(word, i) ++ let word = strpart(word, 0, i-1) ++ " Now, a:matchline =~ a:prefix . word . a:suffix ++ if wordBR != ini ++ let table = s:Resolve(ini, wordBR, "table") ++ else ++ " let table = "----------" ++ let table = "" ++ let d = 0 ++ while d < 10 ++ if tailBR =~ s:notslash . '\\' . d ++ " let table[d] = d ++ let table = table . d ++ else ++ let table = table . "-" ++ endif ++ let d = d + 1 ++ endwhile ++ endif ++ let d = 9 ++ while d ++ if table[d] != "-" ++ let backref = substitute(a:matchline, a:prefix.word.a:suffix, ++ \ '\'.table[d], "") ++ " Are there any other characters that should be escaped? ++ let backref = escape(backref, '*,:') ++ execute s:Ref(ini, d, "start", "len") ++ let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len) ++ let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d, ++ \ escape(backref, '\\'), 'g') ++ endif ++ let d = d-1 ++ endwhile ++ if exists("b:match_debug") ++ if s:do_BR ++ let b:match_table = table ++ let b:match_word = word ++ else ++ let b:match_table = "" ++ let b:match_word = "" ++ endif ++ endif ++ return ini . ":" . tailBR ++endfun ++ ++" Input a comma-separated list of groups with backrefs, such as ++" a:groups = '\(foo\):end\1,\(bar\):end\1' ++" and return a comma-separated list of groups with backrefs replaced: ++" return '\(foo\):end\(foo\),\(bar\):end\(bar\)' ++fun! s:ParseWords(groups) ++ let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g') ++ let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g') ++ let parsed = "" ++ while groups =~ '[^,:]' ++ let i = matchend(groups, s:notslash . ':') ++ let j = matchend(groups, s:notslash . ',') ++ let ini = strpart(groups, 0, i-1) ++ let tail = strpart(groups, i, j-i-1) . ":" ++ let groups = strpart(groups, j) ++ let parsed = parsed . ini ++ let i = matchend(tail, s:notslash . ':') ++ while i != -1 ++ " In 'if:else:endif', ini='if' and word='else' and then word='endif'. ++ let word = strpart(tail, 0, i-1) ++ let tail = strpart(tail, i) ++ let i = matchend(tail, s:notslash . ':') ++ let parsed = parsed . ":" . s:Resolve(ini, word, "word") ++ endwhile " Now, tail has been used up. ++ let parsed = parsed . "," ++ endwhile " groups =~ '[^,:]' ++ return parsed ++endfun ++ ++" TODO I think this can be simplified and/or made more efficient. ++" TODO What should I do if a:start is out of range? ++" Return a regexp that matches all of a:string, such that ++" matchstr(a:string, regexp) represents the match for a:pat that starts ++" as close to a:start as possible, before being preferred to after, and ++" ends after a:start . ++" Usage: ++" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1) ++" let i = match(getline("."), regexp) ++" let j = matchend(getline("."), regexp) ++" let match = matchstr(getline("."), regexp) ++fun! s:Wholematch(string, pat, start) ++ let group = '\%(' . a:pat . '\)' ++ let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^') ++ let len = strlen(a:string) ++ let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$') ++ if a:string !~ prefix . group . suffix ++ let prefix = '' ++ endif ++ return prefix . group . suffix ++endfun ++ ++" No extra arguments: s:Ref(string, d) will ++" find the d'th occurrence of '\(' and return it, along with everything up ++" to and including the matching '\)'. ++" One argument: s:Ref(string, d, "start") returns the index of the start ++" of the d'th '\(' and any other argument returns the length of the group. ++" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be ++" executed, having the effect of ++" :let foo = s:Ref(string, d, "start") ++" :let bar = s:Ref(string, d, "len") ++fun! s:Ref(string, d, ...) ++ let len = strlen(a:string) ++ if a:d == 0 ++ let start = 0 ++ else ++ let cnt = a:d ++ let match = a:string ++ while cnt ++ let cnt = cnt - 1 ++ let index = matchend(match, s:notslash . '\\(') ++ if index == -1 ++ return "" ++ endif ++ let match = strpart(match, index) ++ endwhile ++ let start = len - strlen(match) ++ if a:0 == 1 && a:1 == "start" ++ return start - 2 ++ endif ++ let cnt = 1 ++ while cnt ++ let index = matchend(match, s:notslash . '\\(\|\\)') - 1 ++ if index == -2 ++ return "" ++ endif ++ " Increment if an open, decrement if a ')': ++ let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')' ++ " let cnt = stridx('0(', match[index]) + cnt ++ let match = strpart(match, index+1) ++ endwhile ++ let start = start - 2 ++ let len = len - start - strlen(match) ++ endif ++ if a:0 == 1 ++ return len ++ elseif a:0 == 2 ++ return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len ++ else ++ return strpart(a:string, start, len) ++ endif ++endfun ++ ++" Count the number of disjoint copies of pattern in string. ++" If the pattern is a literal string and contains no '0' or '1' characters ++" then s:Count(string, pattern, '0', '1') should be faster than ++" s:Count(string, pattern). ++fun! s:Count(string, pattern, ...) ++ let pat = escape(a:pattern, '\\') ++ if a:0 > 1 ++ let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g") ++ let foo = substitute(a:string, pat, a:2, "g") ++ let foo = substitute(foo, '[^' . a:2 . ']', "", "g") ++ return strlen(foo) ++ endif ++ let result = 0 ++ let foo = a:string ++ let index = matchend(foo, pat) ++ while index != -1 ++ let result = result + 1 ++ let foo = strpart(foo, index) ++ let index = matchend(foo, pat) ++ endwhile ++ return result ++endfun ++ ++" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where ++" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first ++" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this ++" indicates that all other instances of '\1' in target are to be replaced ++" by '\3'. The hard part is dealing with nesting... ++" Note that ":" is an illegal character for source and target, ++" unless it is preceded by "\". ++fun! s:Resolve(source, target, output) ++ let word = a:target ++ let i = matchend(word, s:notslash . '\\\d') - 1 ++ let table = "----------" ++ while i != -2 " There are back references to be replaced. ++ let d = word[i] ++ let backref = s:Ref(a:source, d) ++ " The idea is to replace '\d' with backref. Before we do this, ++ " replace any \(\) groups in backref with :1, :2, ... if they ++ " correspond to the first, second, ... group already inserted ++ " into backref. Later, replace :1 with \1 and so on. The group ++ " number w+b within backref corresponds to the group number ++ " s within a:source. ++ " w = number of '\(' in word before the current one ++ let w = s:Count( ++ \ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1') ++ let b = 1 " number of the current '\(' in backref ++ let s = d " number of the current '\(' in a:source ++ while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1') ++ \ && s < 10 ++ if table[s] == "-" ++ if w + b < 10 ++ " let table[s] = w + b ++ let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1) ++ endif ++ let b = b + 1 ++ let s = s + 1 ++ else ++ execute s:Ref(backref, b, "start", "len") ++ let ref = strpart(backref, start, len) ++ let backref = strpart(backref, 0, start) . ":". table[s] ++ \ . strpart(backref, start+len) ++ let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1') ++ endif ++ endwhile ++ let word = strpart(word, 0, i-1) . backref . strpart(word, i+1) ++ let i = matchend(word, s:notslash . '\\\d') - 1 ++ endwhile ++ let word = substitute(word, s:notslash . '\zs:', '\\', 'g') ++ if a:output == "table" ++ return table ++ elseif a:output == "word" ++ return word ++ else ++ return table . word ++ endif ++endfun ++ ++" Assume a:comma = ",". Then the format for a:patterns and a:1 is ++" a:patterns = ",,..." ++" a:1 = ",,..." ++" If is the first pattern that matches a:string then return ++" if no optional arguments are given; return , if a:1 is given. ++fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...) ++ let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma) ++ let i = matchend(tail, s:notslash . a:comma) ++ if a:0 ++ let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma) ++ let j = matchend(alttail, s:notslash . a:comma) ++ endif ++ let current = strpart(tail, 0, i-1) ++ if a:branch == "" ++ let currpat = current ++ else ++ let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') ++ endif ++ while a:string !~ a:prefix . currpat . a:suffix ++ let tail = strpart(tail, i) ++ let i = matchend(tail, s:notslash . a:comma) ++ if i == -1 ++ return -1 ++ endif ++ let current = strpart(tail, 0, i-1) ++ if a:branch == "" ++ let currpat = current ++ else ++ let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') ++ endif ++ if a:0 ++ let alttail = strpart(alttail, j) ++ let j = matchend(alttail, s:notslash . a:comma) ++ endif ++ endwhile ++ if a:0 ++ let current = current . a:comma . strpart(alttail, 0, j-1) ++ endif ++ return current ++endfun ++ ++" Call this function to turn on debugging information. Every time the main ++" script is run, buffer variables will be saved. These can be used directly ++" or viewed using the menu items below. ++if !exists(":MatchDebug") ++ command! -nargs=0 MatchDebug call s:Match_debug() ++endif ++ ++fun! s:Match_debug() ++ let b:match_debug = 1 " Save debugging information. ++ " pat = all of b:match_words with backrefs parsed ++ amenu &Matchit.&pat :echo b:match_pat ++ " match = bit of text that is recognized as a match ++ amenu &Matchit.&match :echo b:match_match ++ " curcol = cursor column of the start of the matching text ++ amenu &Matchit.&curcol :echo b:match_col ++ " wholeBR = matching group, original version ++ amenu &Matchit.wh&oleBR :echo b:match_wholeBR ++ " iniBR = 'if' piece, original version ++ amenu &Matchit.ini&BR :echo b:match_iniBR ++ " ini = 'if' piece, with all backrefs resolved from match ++ amenu &Matchit.&ini :echo b:match_ini ++ " tail = 'else\|endif' piece, with all backrefs resolved from match ++ amenu &Matchit.&tail :echo b:match_tail ++ " fin = 'endif' piece, with all backrefs resolved from match ++ amenu &Matchit.&word :echo b:match_word ++ " '\'.d in ini refers to the same thing as '\'.table[d] in word. ++ amenu &Matchit.t&able :echo '0:' . b:match_table . ':9' ++endfun ++ ++" Jump to the nearest unmatched "(" or "if" or "" if a:spflag == "bW" ++" or the nearest unmatched "" or "endif" or ")" if a:spflag == "W". ++" Return a "mark" for the original position, so that ++" let m = MultiMatch("bW", "n") ... execute m ++" will return to the original position. If there is a problem, do not ++" move the cursor and return "", unless a count is given, in which case ++" go up or down as many levels as possible and again return "". ++" TODO This relies on the same patterns as % matching. It might be a good ++" idea to give it its own matching patterns. ++fun! s:MultiMatch(spflag, mode) ++ if !exists("b:match_words") || b:match_words == "" ++ return "" ++ end ++ let restore_options = (&ic ? "" : "no") . "ignorecase" ++ if exists("b:match_ignorecase") ++ let &ignorecase = b:match_ignorecase ++ endif ++ let startline = line(".") ++ let startcol = col(".") ++ ++ " First step: if not already done, set the script variables ++ " s:do_BR flag for whether there are backrefs ++ " s:pat parsed version of b:match_words ++ " s:all regexp based on s:pat and the default groups ++ " This part is copied and slightly modified from s:Match_wrapper(). ++ let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . ++ \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' ++ " Allow b:match_words = "GetVimMatchWords()" . ++ if b:match_words =~ ":" ++ let match_words = b:match_words ++ else ++ execute "let match_words =" b:match_words ++ endif ++ if (match_words != s:last_words) || (&mps != s:last_mps) || ++ \ exists("b:match_debug") ++ let s:last_words = match_words ++ let s:last_mps = &mps ++ if match_words !~ s:notslash . '\\\d' ++ let s:do_BR = 0 ++ let s:pat = match_words ++ else ++ let s:do_BR = 1 ++ let s:pat = s:ParseWords(match_words) ++ endif ++ let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default, ++ \ '[,:]\+','\\|','g') . '\)' ++ if exists("b:match_debug") ++ let b:match_pat = s:pat ++ endif ++ endif ++ ++ " Second step: figure out the patterns for searchpair() ++ " and save the screen, cursor position, and 'ignorecase'. ++ " - TODO: A lot of this is copied from s:Match_wrapper(). ++ " - maybe even more functionality should be split off ++ " - into separate functions! ++ let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default ++ let open = substitute(s:pat . cdefault, ++ \ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g') ++ let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '') ++ let close = substitute(s:pat . cdefault, ++ \ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g') ++ let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)' ++ if exists("b:match_skip") ++ let skip = b:match_skip ++ elseif exists("b:match_comment") " backwards compatibility and testing! ++ let skip = "r:" . b:match_comment ++ else ++ let skip = 's:comment\|string' ++ endif ++ let skip = s:ParseSkip(skip) ++ " let restore_cursor = line(".") . "G" . virtcol(".") . "|" ++ " normal! H ++ " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ let restore_cursor = virtcol(".") . "|" ++ normal! g0 ++ let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor ++ normal! H ++ let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ execute restore_cursor ++ ++ " Third step: call searchpair(). ++ " Replace '\('--but not '\\('--with '\%(' and ',' with '\|'. ++ let openpat = substitute(open, '\(\\\@" or ... ++" and return "endif" or "endwhile" or "" or ... . ++" For now, this uses b:match_words and the same script variables ++" as s:Match_wrapper() . Later, it may get its own patterns, ++" either from a buffer variable or passed as arguments. ++" fun! s:Autocomplete() ++" echo "autocomplete not yet implemented :-(" ++" if !exists("b:match_words") || b:match_words == "" ++" return "" ++" end ++" let startpos = s:MultiMatch("bW") ++" ++" if startpos == "" ++" return "" ++" endif ++" " - TODO: figure out whether 'if' or '' matched, and construct ++" " - the appropriate closing. ++" let matchline = getline(".") ++" let curcol = col(".") - 1 ++" " - TODO: Change the s:all argument if there is a new set of match pats. ++" let regexp = s:Wholematch(matchline, s:all, curcol) ++" let suf = strlen(matchline) - matchend(matchline, regexp) ++" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(') ++" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$') ++" " Reconstruct the version with unresolved backrefs. ++" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g') ++" let patBR = substitute(patBR, ':\{2,}', ':', "g") ++" " Now, set group and groupBR to the matching group: 'if:endif' or ++" " 'while:endwhile' or whatever. ++" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) ++" let i = matchend(group, s:notslash . ",") ++" let groupBR = strpart(group, i) ++" let group = strpart(group, 0, i-1) ++" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix ++" if s:do_BR ++" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++" endif ++" " let g:group = group ++" ++" " - TODO: Construct the closing from group. ++" let fake = "end" . expand("") ++" execute startpos ++" return fake ++" endfun ++ ++" Close all open structures. "Get the heck out of here!" ++" fun! s:Gthhoh() ++" let close = s:Autocomplete() ++" while strlen(close) ++" put=close ++" let close = s:Autocomplete() ++" endwhile ++" endfun ++ ++" Parse special strings as typical skip arguments for searchpair(): ++" s:foo becomes (current syntax item) =~ foo ++" S:foo becomes (current syntax item) !~ foo ++" r:foo becomes (line before cursor) =~ foo ++" R:foo becomes (line before cursor) !~ foo ++fun! s:ParseSkip(str) ++ let skip = a:str ++ if skip[1] == ":" ++ if skip[0] == "s" ++ let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" . ++ \ strpart(skip,2) . "'" ++ elseif skip[0] == "S" ++ let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" . ++ \ strpart(skip,2) . "'" ++ elseif skip[0] == "r" ++ let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'" ++ elseif skip[0] == "R" ++ let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'" ++ endif ++ endif ++ return skip ++endfun ++ ++let &cpo = s:save_cpo ++ ++" vim:sts=2:sw=2: +diff -urN vim71/1/plugin/.svn/text-base/NERD_commenter.vim.svn-base vim71_ada/1/plugin/.svn/text-base/NERD_commenter.vim.svn-base +--- vim71/1/plugin/.svn/text-base/NERD_commenter.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/text-base/NERD_commenter.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,4553 @@ ++" vim global plugin that provides easy code commenting for various file types ++" Last Change: 29 sep 2007 ++" Maintainer: Martin Grenfell ++let s:NERD_commenter_version = 2.1.4 ++ ++" For help documentation type :help NERDCommenter. If this fails, Restart vim ++" and try again. If it sill doesnt work... the help page is at the bottom ++" of this file. ++ ++" Section: script init stuff {{{1 ++if exists("loaded_nerd_comments") ++ finish ++endif ++if v:version < 700 ++ echoerr "NERDCommenter: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" ++ finish ++endif ++let loaded_nerd_comments = 1 ++ ++" Section: spaces init {{{2 ++" Occasionally we need to grab a string of spaces so just make one here ++let s:spaces = "" ++while strlen(s:spaces) < 100 ++ let s:spaces = s:spaces . " " ++endwhile ++ ++" Function: s:InitVariable() function {{{2 ++" This function is used to initialise a given variable to a given value. The ++" variable is only initialised if it does not exist prior ++" ++" Args: ++" -var: the name of the var to be initialised ++" -value: the value to initialise var to ++" ++" Returns: ++" 1 if the var is set, 0 otherwise ++function s:InitVariable(var, value) ++ if !exists(a:var) ++ exec 'let ' . a:var . ' = ' . "'" . a:value . "'" ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Section: space string init{{{2 ++" When putting spaces after the left delim and before the right we use ++" s:spaceStr for the space char. This way we can make it add anything after ++" the left and before the right by modifying this variable ++let s:spaceStr = ' ' ++let s:lenSpaceStr = strlen(s:spaceStr) ++ ++" Section: variable init calls {{{2 ++call s:InitVariable("g:NERDAllowAnyVisualDelims", 1) ++call s:InitVariable("g:NERDBlockComIgnoreEmpty", 0) ++call s:InitVariable("g:NERDCommentWholeLinesInVMode", 0) ++call s:InitVariable("g:NERDCompactSexyComs", 0) ++call s:InitVariable("g:NERDDefaultNesting", 0) ++call s:InitVariable("g:NERDMenuMode", 3) ++call s:InitVariable("g:NERDLPlace", "[>") ++call s:InitVariable("g:NERDUsePlaceHolders", 1) ++call s:InitVariable("g:NERDRemoveAltComs", 1) ++call s:InitVariable("g:NERDRemoveExtraSpaces", 0) ++call s:InitVariable("g:NERDRPlace", "<]") ++call s:InitVariable("g:NERDShutUp", '0') ++call s:InitVariable("g:NERDSpaceDelims", 0) ++call s:InitVariable("g:NERDDelimiterRequests", 1) ++ ++call s:InitVariable("g:NERDMapleader", ',c') ++ ++call s:InitVariable("g:NERDAltComMap", g:NERDMapleader . 'a') ++call s:InitVariable("g:NERDAppendComMap", g:NERDMapleader . 'A') ++call s:InitVariable("g:NERDComAlignBothMap", g:NERDMapleader . 'b') ++call s:InitVariable("g:NERDComAlignLeftMap", g:NERDMapleader . 'l') ++call s:InitVariable("g:NERDComAlignRightMap", g:NERDMapleader . 'r') ++call s:InitVariable("g:NERDComInInsertMap", '') ++call s:InitVariable("g:NERDComLineInvertMap", g:NERDMapleader . 'i') ++call s:InitVariable("g:NERDComLineMap", g:NERDMapleader . 'c') ++call s:InitVariable("g:NERDComLineNestMap", g:NERDMapleader . 'n') ++call s:InitVariable("g:NERDComLineSexyMap", g:NERDMapleader . 's') ++call s:InitVariable("g:NERDComLineToggleMap", g:NERDMapleader . '') ++call s:InitVariable("g:NERDComLineMinimalMap", g:NERDMapleader . 'm') ++call s:InitVariable("g:NERDComLineYankMap", g:NERDMapleader . 'y') ++call s:InitVariable("g:NERDComToEOLMap", g:NERDMapleader . '$') ++call s:InitVariable("g:NERDPrependComMap", g:NERDMapleader . 'I') ++call s:InitVariable("g:NERDUncomLineMap", g:NERDMapleader . 'u') ++let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\" ++ ++" Section: Comment mapping functions, autocommands and commands {{{1 ++" ============================================================================ ++" Section: Comment enabler autocommands {{{2 ++" ============================================================================ ++ ++if !exists("nerd_autocmds_loaded") ++ let nerd_autocmds_loaded=1 ++ ++ augroup commentEnablers ++ ++ "if the user enters a buffer or reads a buffer then we gotta set up ++ "the comment delimiters for that new filetype ++ autocmd BufEnter,BufRead * :call s:SetUpForNewFiletype(&filetype, 0) ++ ++ "if the filetype of a buffer changes, force the script to reset the ++ "delims for the buffer ++ autocmd Filetype * :call s:SetUpForNewFiletype(&filetype, 1) ++ augroup END ++ ++endif ++ ++ ++" Function: s:SetUpForNewFiletype(filetype) function {{{2 ++" This function is responsible for setting up buffer scoped variables for the ++" given filetype. ++" ++" These variables include the comment delimiters for the given filetype and calls ++" MapDelimiters or MapDelimitersWithAlternative passing in these delimiters. ++" ++" Args: ++" -filetype: the filetype to set delimiters for ++" -forceReset: 1 if the delimiters should be reset if they have already be ++" set for this buffer. ++" ++function s:SetUpForNewFiletype(filetype, forceReset) ++ "if we have already set the delimiters for this buffer then dont go thru ++ "it again ++ if !a:forceReset && exists("b:left") && b:left != '' ++ return ++ endif ++ ++ let b:sexyComMarker = '' ++ ++ "check the filetype against all known filetypes to see if we have ++ "hardcoded the comment delimiters to use ++ if a:filetype == "" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "abaqus" ++ call s:MapDelimiters('**', '') ++ elseif a:filetype == "abc" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "acedb" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ada" ++ call s:MapDelimitersWithAlternative('--','', '-- ', '') ++ elseif a:filetype == "ahdl" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "ahk" ++ call s:MapDelimitersWithAlternative(';', '', '/*', '*/') ++ elseif a:filetype == "amiga" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "aml" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "ampl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ant" ++ call s:MapDelimiters('') ++ elseif a:filetype == "apache" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "apachestyle" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "asm68k" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "asm" ++ call s:MapDelimitersWithAlternative(';', '', '#', '') ++ elseif a:filetype == "asn" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "aspvbs" ++ call s:MapDelimiters('''', '') ++ elseif a:filetype == "atlas" ++ call s:MapDelimiters('C','$') ++ elseif a:filetype == "autohotkey" ++ call s:MapDelimiters(';','') ++ elseif a:filetype == "autoit" ++ call s:MapDelimiters(';','') ++ elseif a:filetype == "automake" ++ call s:MapDelimitersWithAlternative('#','', 'dnl ', '') ++ elseif a:filetype == "ave" ++ call s:MapDelimiters("'",'') ++ elseif a:filetype == "awk" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "basic" ++ call s:MapDelimitersWithAlternative("'",'', 'REM ', '') ++ elseif a:filetype == "b" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "bc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "bdf" ++ call s:MapDelimiters('COMMENT ', '') ++ elseif a:filetype == "bib" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "bindzone" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "bst" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "btm" ++ call s:MapDelimiters('::', '') ++ elseif a:filetype == "caos" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "catalog" ++ call s:MapDelimiters('--','--') ++ elseif a:filetype == "c" ++ call s:MapDelimitersWithAlternative('/*','*/', '//', '') ++ elseif a:filetype == "cfg" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "cg" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ch" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "changelog" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "cl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "clean" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "clipper" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "cmake" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "conf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "config" ++ call s:MapDelimiters('dnl ', '') ++ elseif a:filetype == "context" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "cpp" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "crontab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "cs" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "csc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "csp" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "css" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "cterm" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "cupl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "csv" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "cvs" ++ call s:MapDelimiters('CVS:','') ++ elseif a:filetype == "dcl" ++ call s:MapDelimiters('$!', '') ++ elseif a:filetype == "debchangelog" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "debcontrol" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "debsources" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "def" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "desktop" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "diff" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "django" ++ call s:MapDelimitersWithAlternative('', '{#', '#}') ++ elseif a:filetype == "docbk" ++ call s:MapDelimiters('') ++ elseif a:filetype == "dns" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dosbatch" ++ call s:MapDelimiters('REM ','') ++ elseif a:filetype == "dosini" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dot" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "dracula" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dsl" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dtd" ++ call s:MapDelimiters('') ++ elseif a:filetype == "dtml" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "dylan" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == 'ebuild' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ecd" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'eclass' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "eiffel" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "elf" ++ call s:MapDelimiters("'", '') ++ elseif a:filetype == "elmfilt" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "erlang" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "eruby" ++ call s:MapDelimitersWithAlternative('', '<%#', '%>') ++ elseif a:filetype == "eterm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "expect" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "exports" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fetchmail" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fgl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "focexec" ++ call s:MapDelimiters('-*', '') ++ elseif a:filetype == "form" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "fortran" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "foxpro" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "fstab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fvwm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fx" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "gams" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "gdb" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "gdmo" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "geek" ++ call s:MapDelimiters('GEEK_COMMENT:', '') ++ elseif a:filetype == 'gentoo-package-keywords' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'gentoo-package-mask' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'gentoo-package-use' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "gnuplot" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "groovy" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "gtkrc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "haskell" ++ call s:MapDelimitersWithAlternative('--','', '{-', '-}') ++ elseif a:filetype == "hb" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "h" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "help" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "hercules" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "hog" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "html" ++ call s:MapDelimitersWithAlternative('', '//', '') ++ elseif a:filetype == "htmldjango" ++ call s:MapDelimitersWithAlternative('', '{#', '#}') ++ elseif a:filetype == "htmlos" ++ call s:MapDelimiters('#','/#') ++ elseif a:filetype == "ia64" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "icon" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "idlang" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "idl" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "indent" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "inform" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "inittab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ishd" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "iss" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "ist" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "jam" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "java" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "javascript" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "jess" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "jgraph" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "jproperties" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "jsp" ++ call s:MapDelimiters('<%--', '--%>') ++ elseif a:filetype == "kconfig" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "kix" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "kscript" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "lace" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "ldif" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lex" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lftp" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lifelines" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lilo" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lisp" ++ call s:MapDelimitersWithAlternative(';','', '#|', '|#') ++ elseif a:filetype == "lite" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lookupfile" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "lotos" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "lout" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lprolog" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "lscript" ++ call s:MapDelimiters("'", '') ++ elseif a:filetype == "lss" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lua" ++ call s:MapDelimitersWithAlternative('--','', '--[[', ']]') ++ elseif a:filetype == "lynx" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "m4" ++ call s:MapDelimiters('dnl ', '') ++ elseif a:filetype == "mail" ++ call s:MapDelimiters('> ','') ++ elseif a:filetype == "make" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "maple" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "masm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "master" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "matlab" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "mel" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "mf" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "mib" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "mma" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "model" ++ call s:MapDelimiters('$','$') ++ elseif a:filetype =~ "moduala." ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "modula2" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "modula3" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "monk" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "mush" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "muttrc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "named" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "nasm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "nastran" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "natural" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "ncf" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "netdict" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "netrw" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "nqc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "nroff" ++ call s:MapDelimiters('\"', '') ++ elseif a:filetype == "nsis" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "objc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ocaml" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "occam" ++ call s:MapDelimiters('--','') ++ elseif a:filetype == "omlet" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "omnimark" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "openroad" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "opl" ++ call s:MapDelimiters("REM", "") ++ elseif a:filetype == "ora" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "otl" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ox" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "pascal" ++ call s:MapDelimitersWithAlternative('{','}', '(*', '*)') ++ elseif a:filetype == "passwd" ++ call s:MapDelimitersWith('','') ++ elseif a:filetype == "pcap" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "pccts" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "perl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "pfmain" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "php" ++ call s:MapDelimitersWithAlternative('//','','/*', '*/') ++ elseif a:filetype == "phtml" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "pic" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "pike" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "pilrc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "pine" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "plaintex" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "plm" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "plsql" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "po" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "postscr" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "pov" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "povini" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "ppd" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "ppwiz" ++ call s:MapDelimiters(';;', '') ++ elseif a:filetype == "procmail" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "progress" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "prolog" ++ call s:MapDelimitersWithAlternative('%','','/*','*/') ++ elseif a:filetype == "psf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ptcap" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "python" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "qf" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "radiance" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "Rails-log" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ratpoison" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "r" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "readline" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rebol" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "registry" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "remind" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rexx" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "robots" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rpl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "rst" ++ call s:MapDelimiters('..', '') ++ elseif a:filetype == "rtf" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ruby" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "sa" ++ call s:MapDelimiters('--','') ++ elseif a:filetype == "samba" ++ call s:MapDelimitersWithAlternative(';','', '#', '') ++ elseif a:filetype == "sas" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "sass" ++ call s:MapDelimitersWithAlternative('//','', '/*', '') ++ elseif a:filetype == "sather" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "scheme" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "scilab" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "screen" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "scsh" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "sdl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "sed" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "selectbuf" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "sgml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "sgmldecl" ++ call s:MapDelimiters('--','--') ++ elseif a:filetype == "sgmllnx" ++ call s:MapDelimiters('') ++ elseif a:filetype == "sicad" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "simula" ++ call s:MapDelimitersWithAlternative('%', '', '--', '') ++ elseif a:filetype == "sinda" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "skill" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "slang" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "sl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "slrnrc" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "sm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "smarty" ++ call s:MapDelimiters('{*', '*}') ++ elseif a:filetype == "smil" ++ call s:MapDelimiters('') ++ elseif a:filetype == "smith" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "sml" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "snnsnet" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snnspat" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snnsres" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snobol4" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "spec" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "specman" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "spice" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "sql" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqlforms" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqlj" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqr" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "squid" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "st" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "stp" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "strace" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "svn" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "SVNcommitlog" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "systemverilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "tads" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "taglist" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "tags" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tak" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "tasm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tcl" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "terminfo" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tex" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "text" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "texinfo" ++ call s:MapDelimiters("@c ", "") ++ elseif a:filetype == "texmf" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "tf" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tidy" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tli" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "trasys" ++ call s:MapDelimiters("$", "") ++ elseif a:filetype == "tsalt" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "tsscl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tssgm" ++ call s:MapDelimiters("comment = '","'") ++ elseif a:filetype == "uc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "uil" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "vb" ++ call s:MapDelimiters("'","") ++ elseif a:filetype == "vcscommit" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "vera" ++ call s:MapDelimitersWithAlternative('/*','*/','//','') ++ elseif a:filetype == "verilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "verilog_systemverilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "vgrindefs" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "vhdl" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "vim" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "viminfo" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "virata" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "vo_base" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "vrml" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "vsejcl" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "webmacro" ++ call s:MapDelimiters('##', '') ++ elseif a:filetype == "wget" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "winbatch" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "wml" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype =~ "[^w]*sh" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "wvdial" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "xdefaults" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xf86conf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "xhtml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xkb" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "xmath" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "xml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xmodmap" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xpm2" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xpm" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "xsd" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xslt" ++ call s:MapDelimiters('') ++ elseif a:filetype == "yacc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "yaml" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "z8a" ++ call s:MapDelimiters(';', '') ++ ++ elseif a:filetype == "" ++ call s:MapDelimitersWithAlternative("","", "", "") ++ ++ "we have not hardcoded the comment delimiters to use for this filetype so ++ "get them from &commentstring. ++ else ++ "print a disclaimer to the user :) ++ if !g:NERDShutUp ++ call s:NerdEcho("Unknown filetype '".a:filetype."', setting delimiters by &commentstring.\nPleeeeease email the author of the NERD commenter with this filetype\nand its delimiters!", 0) ++ endif ++ ++ "extract the delims from &commentstring ++ let left= substitute(&commentstring, '\(.*\)%s.*', '\1', '') ++ let right= substitute(&commentstring, '.*%s\(.*\)', '\1', 'g') ++ ++ call s:MapDelimiters(left,right) ++ endif ++endfunction ++ ++" Function: s:MapDelimiters(left, right) function {{{2 ++" This function is a wrapper for s:MapDelimiters(left, right, leftAlt, rightAlt, useAlt) and is called when there ++" is no alternative comment delimiters for the current filetype ++" ++" Args: ++" -left: the left comment delimiter ++" -right: the right comment delimiter ++function s:MapDelimiters(left, right) ++ call s:MapDelimitersWithAlternative(a:left, a:right, "", "") ++endfunction ++ ++" Function: s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt) function {{{2 ++" this function sets up the comment delimiter buffer variables ++" ++" Args: ++" -left: the string defining the comment start delimiter ++" -right: the string defining the comment end delimiter ++" -leftAlt: the string for the alternative comment style defining the comment start delimiter ++" -rightAlt: the string for the alternative comment style defining the comment end delimiter ++function s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt) ++ if !exists('g:NERD_' . &filetype . '_alt_style') ++ let b:left = a:left ++ let b:right = a:right ++ let b:leftAlt = a:leftAlt ++ let b:rightAlt = a:rightAlt ++ else ++ let b:left = a:leftAlt ++ let b:right = a:rightAlt ++ let b:leftAlt = a:left ++ let b:rightAlt = a:right ++ endif ++endfunction ++ ++" Function: s:SwitchToAlternativeDelimiters(printMsgs) function {{{2 ++" This function is used to swap the delimiters that are being used to the ++" alternative delimiters for that filetype. For example, if a c++ file is ++" being edited and // comments are being used, after this function is called ++" /**/ comments will be used. ++" ++" Args: ++" -printMsgs: if this is 1 then a message is echoed to the user telling them ++" if this function changed the delimiters or not ++function s:SwitchToAlternativeDelimiters(printMsgs) ++ "if both of the alternative delimiters are empty then there is no ++ "alternative comment style so bail out ++ if !s:HasMultipartDelims() ++ if a:printMsgs ++ call s:NerdEcho("Cannot use alternative delimiters, none are specified", 0) ++ endif ++ return 0 ++ endif ++ ++ "save the current delimiters ++ let tempLeft = b:left ++ let tempRight = b:right ++ ++ "swap current delimiters for alternative ++ let b:left = b:leftAlt ++ let b:right = b:rightAlt ++ ++ "set the previously current delimiters to be the new alternative ones ++ let b:leftAlt = tempLeft ++ let b:rightAlt = tempRight ++ ++ "tell the user what comment delimiters they are now using ++ if a:printMsgs ++ let leftNoEsc = b:left ++ let rightNoEsc = b:right ++ call s:NerdEcho("Now using " . leftNoEsc . " " . rightNoEsc . " to delimit comments", 1) ++ endif ++ ++ return 1 ++endfunction ++ ++" Section: Comment delimiter add/removal functions {{{1 ++" ============================================================================ ++" Function: s:AppendCommentToLine(){{{2 ++" This function appends comment delimiters at the EOL and places the cursor in ++" position to start typing the comment ++function s:AppendCommentToLine() ++ let left = s:GetLeft(0,1,0) ++ let right = s:GetRight(0,1,0) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ let isLineEmpty = strlen(getline(".")) == 0 ++ let insOrApp = (isLineEmpty==1 ? 'i' : 'A') ++ ++ "stick the delimiters down at the end of the line. We have to format the ++ "comment with spaces as appropriate ++ execute ":normal " . insOrApp . (isLineEmpty ? '' : ' ') . left . right . " " ++ ++ " if there is a right delimiter then we gotta move the cursor left ++ " by the len of the right delimiter so we insert between the delimiters ++ if lenRight > 0 ++ let leftMoveAmount = lenRight ++ execute ":normal " . leftMoveAmount . "h" ++ endif ++ startinsert ++endfunction ++ ++" Function: s:CommentBlock(top, bottom, lSide, rSide, forceNested ) {{{2 ++" This function is used to comment out a region of code. This region is ++" specified as a bounding box by arguments to the function. ++" ++" Args: ++" -top: the line number for the top line of code in the region ++" -bottom: the line number for the bottom line of code in the region ++" -lSide: the column number for the left most column in the region ++" -rSide: the column number for the right most column in the region ++" -forceNested: a flag indicating whether comments should be nested ++function s:CommentBlock(top, bottom, lSide, rSide, forceNested ) ++ " we need to create local copies of these arguments so we can modify them ++ let top = a:top ++ let bottom = a:bottom ++ let lSide = a:lSide ++ let rSide = a:rSide ++ ++ "if the top or bottom line starts with tabs we have to adjust the left and ++ "right boundaries so that they are set as though the tabs were spaces ++ let topline = getline(top) ++ let bottomline = getline(bottom) ++ if s:HasLeadingTabs(topline, bottomline) ++ ++ "find out how many tabs are in the top line and adjust the left ++ "boundary accordingly ++ let numTabs = s:NumberOfLeadingTabs(topline) ++ if lSide < numTabs ++ let lSide = &ts * lSide ++ else ++ let lSide = (lSide - numTabs) + (&ts * numTabs) ++ endif ++ ++ "find out how many tabs are in the bottom line and adjust the right ++ "boundary accordingly ++ let numTabs = s:NumberOfLeadingTabs(bottomline) ++ let rSide = (rSide - numTabs) + (&ts * numTabs) ++ endif ++ ++ "we must check that bottom IS actually below top, if it is not then we ++ "swap top and bottom. Similarly for left and right. ++ if bottom < top ++ let temp = top ++ let top = bottom ++ let bottom = top ++ endif ++ if rSide < lSide ++ let temp = lSide ++ let lSide = rSide ++ let rSide = temp ++ endif ++ ++ "if the current delimiters arent multipart then we will switch to the ++ "alternative delims (if THEY are) as the comment will be better and more ++ "accurate with multipart delims ++ let switchedDelims = 0 ++ if !s:Multipart() && g:NERDAllowAnyVisualDelims && s:AltMultipart() ++ let switchedDelims = 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++ "start the commenting from the top and keep commenting till we reach the ++ "bottom ++ let currentLine=top ++ while currentLine <= bottom ++ ++ "check if we are allowed to comment this line ++ if s:CanCommentLine(a:forceNested, currentLine) ++ ++ "convert the leading tabs into spaces ++ let theLine = getline(currentLine) ++ let lineHasLeadTabs = s:HasLeadingTabs(theLine) ++ if lineHasLeadTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ ++ "dont comment lines that begin after the right boundary of the ++ "block unless the user has specified to do so ++ if theLine !~ '^ \{' . rSide . '\}' || !g:NERDBlockComIgnoreEmpty ++ ++ "attempt to place the cursor in on the left of the boundary box, ++ "then check if we were successful, if not then we cant comment this ++ "line ++ call setline(currentLine, theLine) ++ if s:CanPlaceCursor(currentLine, lSide) ++ ++ let leftSpaced = s:GetLeft(0,1,0) ++ let rightSpaced = s:GetRight(0,1,0) ++ ++ "stick the left delimiter down ++ let theLine = strpart(theLine, 0, lSide-1) . leftSpaced . strpart(theLine, lSide-1) ++ ++ if s:Multipart() ++ "stick the right delimiter down ++ let theLine = strpart(theLine, 0, rSide+strlen(leftSpaced)) . rightSpaced . strpart(theLine, rSide+strlen(rightSpaced)) ++ ++ let firstLeftDelim = s:FindDelimiterIndex(b:left, theLine) ++ let lastRightDelim = s:LastIndexOfDelim(b:right, theLine) ++ ++ if firstLeftDelim != -1 && lastRightDelim != -1 ++ let searchStr = strpart(theLine, 0, lastRightDelim) ++ let searchStr = strpart(searchStr, firstLeftDelim+strlen(b:left)) ++ ++ "replace the outter most delims in searchStr with ++ "place-holders ++ let theLineWithPlaceHolders = s:ReplaceDelims(b:left, b:right, g:NERDLPlace, g:NERDRPlace, searchStr) ++ ++ "add the right delimiter onto the line ++ let theLine = strpart(theLine, 0, firstLeftDelim+strlen(b:left)) . theLineWithPlaceHolders . strpart(theLine, lastRightDelim) ++ endif ++ endif ++ endif ++ endif ++ ++ "restore tabs if needed ++ if lineHasLeadTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ call setline(currentLine, theLine) ++ endif ++ ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "if we switched delims then we gotta go back to what they were before ++ if switchedDelims == 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++endfunction ++ ++" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2 ++" This function comments a range of lines. ++" ++" Args: ++" -forceNested: a flag indicating whether the called is requesting the comment ++" to be nested if need be ++" -alignRight/alignLeft: 0/1 if the comments delimiters should/shouldnt be ++" aligned left/right ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) ++ " we need to get the left and right indexes of the leftmost char in the ++ " block of of lines and the right most char so that we can do alignment of ++ " the delimiters if the user has specified ++ let leftAlignIndx = s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) ++ let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) ++ ++ " gotta add the length of the left delimiter onto the rightAlignIndx cos ++ " we'll be adding a left delim to the line ++ let rightAlignIndx = rightAlignIndx + strlen(s:GetLeft(0,1,0)) ++ ++ " now we actually comment the lines. Do it line by line ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ ++ " get the next line, check commentability and convert spaces to tabs ++ let theLine = getline(currentLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ if s:CanCommentLine(a:forceNested, currentLine) ++ "if the user has specified forceNesting then we check to see if we ++ "need to switch delimiters for place-holders ++ if a:forceNested && g:NERDUsePlaceHolders ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ endif ++ ++ " find out if the line is commented using normal delims and/or ++ " alternate ones ++ let isCommented = s:IsCommented(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine) ++ ++ " check if we can comment this line ++ if !isCommented || g:NERDUsePlaceHolders || s:Multipart() ++ if a:alignLeft ++ let theLine = s:AddLeftDelimAligned(b:left, theLine, leftAlignIndx) ++ else ++ let theLine = s:AddLeftDelim(s:GetLeft(0,1,0), theLine) ++ endif ++ if a:alignRight ++ let theLine = s:AddRightDelimAligned(b:right, theLine, rightAlignIndx) ++ else ++ let theLine = s:AddRightDelim(s:GetRight(0,1,0), theLine) ++ endif ++ endif ++ endif ++ ++ " restore leading tabs if appropriate ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ " we are done with this line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentLinesMinimal(firstLine, lastLine) {{{2 ++" This function comments a range of lines in a minimal style. I ++" ++" Args: ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLinesMinimal(firstLine, lastLine) ++ "check that minimal comments can be done on this filetype ++ if !s:HasMultipartDelims() ++ throw 'NERDCommenter.Delimiters exception: Minimal comments can only be used for filetypes that have multipart delimiters' ++ endif ++ ++ "if we need to use place holders for the comment, make sure they are ++ "enabled for this filetype ++ if !g:NERDUsePlaceHolders && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine) ++ throw 'NERDCommenter.Settings exception: Placeoholders are required but disabled.' ++ endif ++ ++ "get the left and right delims to smack on ++ let left = s:GetSexyComLeft(g:NERDSpaceDelims,0) ++ let right = s:GetSexyComRight(g:NERDSpaceDelims,0) ++ ++ "make sure all multipart delims on the lines are replaced with ++ "placeholders to prevent illegal syntax ++ let currentLine = a:firstLine ++ while(currentLine <= a:lastLine) ++ let theLine = getline(currentLine) ++ let theLine = s:ReplaceDelims(left, right, g:NERDLPlace, g:NERDRPlace, theLine) ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "add the delim to the top line ++ let theLine = getline(a:firstLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let theLine = s:AddLeftDelim(left, theLine) ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:firstLine, theLine) ++ ++ "add the delim to the bottom line ++ let theLine = getline(a:lastLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let theLine = s:AddRightDelim(right, theLine) ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:lastLine, theLine) ++endfunction ++ ++" Function: s:CommentLinesSexy(topline, bottomline) function {{{2 ++" This function is used to comment lines in the 'Sexy' style. eg in c: ++" /* ++" * This is a sexy comment ++" */ ++" Args: ++" -topline: the line num of the top line in the sexy comment ++" -bottomline: the line num of the bottom line in the sexy comment ++function s:CommentLinesSexy(topline, bottomline) ++ let left = s:GetSexyComLeft(0, 0) ++ let right = s:GetSexyComRight(0, 0) ++ ++ "check if we can do a sexy comment with the available delimiters ++ if left == -1 || right == -1 ++ throw 'NERDCommenter.Delimiters exception: cannot perform sexy comments with available delimiters.' ++ endif ++ ++ "make sure the lines arent already commented sexually ++ if !s:CanSexyCommentLines(a:topline, a:bottomline) ++ throw 'NERDCommenter.Nesting exception: cannot nest sexy comments' ++ endif ++ ++ ++ let sexyComMarker = s:GetSexyComMarker(0,0) ++ let sexyComMarkerSpaced = s:GetSexyComMarker(1,0) ++ ++ ++ " we jam the comment as far to the right as possible ++ let leftAlignIndx = s:LeftMostIndx(1, 1, a:topline, a:bottomline) ++ ++ "check if we should use the compact style i.e that the left/right ++ "delimiters should appear on the first and last lines of the code and not ++ "on separate lines above/below the first/last lines of code ++ if g:NERDCompactSexyComs ++ let spaceString = (g:NERDSpaceDelims ? s:spaceStr : '') ++ ++ "comment the top line ++ let theLine = getline(a:topline) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ let theLine = s:AddLeftDelimAligned(left . spaceString, theLine, leftAlignIndx) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:topline, theLine) ++ ++ "comment the bottom line ++ let theLine = getline(a:bottomline) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ let theLine = s:AddRightDelim(spaceString . right, theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:bottomline, theLine) ++ else ++ ++ " add the left delimiter one line above the lines that are to be commented ++ call cursor(a:topline, 1) ++ execute 'normal! O' ++ call setline(a:topline, strpart(s:spaces, 0, leftAlignIndx) . left ) ++ ++ " add the right delimiter after bottom line (we have to add 1 cos we moved ++ " the lines down when we added the left delim ++ call cursor(a:bottomline+1, 1) ++ execute 'normal! o' ++ call setline(a:bottomline+2, strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, strlen(left)-strlen(sexyComMarker)) . right ) ++ ++ endif ++ ++ " go thru each line adding the sexyComMarker marker to the start of each ++ " line in the appropriate place to align them with the comment delims ++ let currentLine = a:topline+1 ++ while currentLine <= a:bottomline + !g:NERDCompactSexyComs ++ " get the line and convert the tabs to spaces ++ let theLine = getline(currentLine) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ ++ " add the sexyComMarker ++ let theLine = strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, strlen(left)-strlen(sexyComMarker)) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx) ++ ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ ++ " set the line and move onto the next one ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentLinesToggle(forceNested, firstLine, lastLine) {{{2 ++" Applies "toggle" commenting to the given range of lines ++" ++" Args: ++" -forceNested: a flag indicating whether the called is requesting the comment ++" to be nested if need be ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLinesToggle(forceNested, firstLine, lastLine) ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ ++ " get the next line, check commentability and convert spaces to tabs ++ let theLine = getline(currentLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ if s:CanToggleCommentLine(a:forceNested, currentLine) ++ ++ "if the user has specified forceNesting then we check to see if we ++ "need to switch delimiters for place-holders ++ if g:NERDUsePlaceHolders ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ endif ++ ++ let theLine = s:AddLeftDelim(s:GetLeft(0, 1, 0), theLine) ++ let theLine = s:AddRightDelim(s:GetRight(0, 1, 0), theLine) ++ endif ++ ++ " restore leading tabs if appropriate ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ " we are done with this line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentRegion(topline, topCol, bottomLine, bottomCol) function {{{2 ++" This function comments chunks of text selected in visual mode. ++" It will comment exactly the text that they have selected. ++" Args: ++" -topLine: the line num of the top line in the sexy comment ++" -topCol: top left col for this comment ++" -bottomline: the line num of the bottom line in the sexy comment ++" -bottomCol: the bottom right col for this comment ++" -forceNested: whether the caller wants comments to be nested if the ++" line(s) are already commented ++function s:CommentRegion(topLine, topCol, bottomLine, bottomCol, forceNested) ++ ++ "switch delims (if we can) if the current set isnt multipart ++ let switchedDelims = 0 ++ if !s:Multipart() && s:AltMultipart() && !g:NERDAllowAnyVisualDelims ++ let switchedDelims = 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++ "if there is only one line in the comment then just do it ++ if a:topLine == a:bottomLine ++ call s:CommentBlock(a:topLine, a:bottomLine, a:topCol, a:bottomCol, a:forceNested) ++ ++ "there are multiple lines in the comment ++ else ++ "comment the top line ++ call s:CommentBlock(a:topLine, a:topLine, a:topCol, strlen(getline(a:topLine)), a:forceNested) ++ ++ "comment out all the lines in the middle of the comment ++ let topOfRange = a:topLine+1 ++ let bottomOfRange = a:bottomLine-1 ++ if topOfRange <= bottomOfRange ++ call s:CommentLines(a:forceNested, 0, 0, topOfRange, bottomOfRange) ++ endif ++ ++ "comment the bottom line ++ let bottom = getline(a:bottomLine) ++ let numLeadingSpacesTabs = strlen(substitute(bottom, '^\([ \t]*\).*$', '\1', '')) ++ call s:CommentBlock(a:bottomLine, a:bottomLine, numLeadingSpacesTabs+1, a:bottomCol, a:forceNested) ++ ++ endif ++ ++ "stick the cursor back on the char it was on before the comment ++ call cursor(a:topLine, a:topCol + strlen(b:left) + g:NERDSpaceDelims) ++ ++ "if we switched delims then we gotta go back to what they were before ++ if switchedDelims == 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++endfunction ++ ++" Function: s:InvertComment(firstLine, lastLine) function {{{2 ++" Inverts the comments on the lines between and including the given line ++" numbers i.e all commented lines are uncommented and vice versa ++" Args: ++" -firstLine: the top of the range of lines to be inverted ++" -lastLine: the bottom of the range of lines to be inverted ++function s:InvertComment(firstLine, lastLine) ++ ++ " go thru all lines in the given range ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ let theLine = getline(currentLine) ++ ++ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) ++ ++ " if the line is commented normally, uncomment it ++ if s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine) ++ call s:UncommentLines(1, currentLine, currentLine) ++ let currentLine = currentLine + 1 ++ ++ " check if the line is commented sexually ++ elseif !empty(sexyComBounds) ++ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() ++ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) ++ ++ "move to the line after last line of the sexy comment ++ let numLinesAfterSexyComRemoved = s:NumLinesInBuf() ++ let currentLine = bottomBound - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1 ++ ++ " the line isnt commented ++ else ++ call s:CommentLinesToggle(1, currentLine, currentLine) ++ let currentLine = currentLine + 1 ++ endif ++ ++ endwhile ++endfunction ++ ++" Function: NERDComment(isVisual, alignLeft, alignRight, type) function {{{2 ++" This function is a Wrapper for the main commenting functions ++" ++" Args: ++" -isVisual: a flag indicating whether the comment is requested in visual ++" mode or not ++" -type: the type of commenting requested. Can be 'sexy', 'invert', ++" 'minimal', 'toggle', 'alignLeft', 'alignRight', 'alignBoth', 'norm', ++" 'nested', 'toEOL', 'prepend', 'append', 'insert', 'uncomment', 'yank' ++function! NERDComment(isVisual, type) range ++ " we want case sensitivity when commenting ++ let prevIgnoreCase = &ignorecase ++ set noignorecase ++ ++ if a:isVisual ++ let firstLine = line("'<") ++ let lastLine = line("'>") ++ let firstCol = col("'<") ++ let lastCol = col("'>") ++ else ++ let firstLine = a:firstline ++ let lastLine = a:lastline ++ endif ++ ++ let countWasGiven = (a:isVisual == 0 && firstLine != lastLine) ++ ++ let forceNested = (a:type == 'nested' || g:NERDDefaultNesting) ++ ++ if a:type == 'norm' || a:type == 'nested' ++ if a:isVisual && visualmode() == "" ++ call s:CommentBlock(firstLine, lastLine, firstCol, lastCol, forceNested) ++ elseif a:isVisual && visualmode() == "v" && (g:NERDCommentWholeLinesInVMode==0 || (g:NERDCommentWholeLinesInVMode==2 && s:HasMultipartDelims())) ++ call s:CommentRegion(firstLine, firstCol, lastLine, lastCol, forceNested) ++ else ++ call s:CommentLines(forceNested, 0, 0, firstLine, lastLine) ++ endif ++ ++ elseif a:type == 'alignLeft' || a:type == 'alignRight' || a:type == 'alignBoth' ++ let alignLeft = (a:type == 'alignLeft' || a:type == 'alignBoth') ++ let alignRight = (a:type == 'alignRight' || a:type == 'alignBoth') ++ call s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) ++ ++ elseif a:type == 'invert' ++ call s:InvertComment(firstLine, lastLine) ++ ++ elseif a:type == 'sexy' ++ try ++ call s:CommentLinesSexy(firstLine, lastLine) ++ catch /NERDCommenter.Delimiters/ ++ call s:NerdEcho("Sexy comments cannot be done with the available delimiters", 0) ++ catch /NERDCommenter.Nesting/ ++ call s:NerdEcho("Sexy comment aborted. Nested sexy cannot be nested", 0) ++ endtry ++ ++ elseif a:type == 'toggle' ++ let theLine = getline(firstLine) ++ ++ if s:IsInSexyComment(firstLine) || s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine) ++ call s:UncommentLines(1, firstLine, lastLine) ++ else ++ call s:CommentLinesToggle(forceNested, firstLine, lastLine) ++ endif ++ ++ elseif a:type == 'minimal' ++ try ++ call s:CommentLinesMinimal(firstLine, lastLine) ++ catch /NERDCommenter.Delimiters/ ++ call s:NerdEcho("Minimal comments can only be used for filetypes that have multipart delimiters.", 0) ++ catch /NERDCommenter.Settings/ ++ call s:NerdEcho("Place holders are required but disabled.", 0) ++ endtry ++ ++ elseif a:type == 'toEOL' ++ call s:SaveScreenState() ++ call s:CommentBlock(firstLine, firstLine, col("."), col("$")-1, 1) ++ call s:RestoreScreenState() ++ ++ elseif a:type == 'prepend' ++ call s:PrependCommentToLine() ++ ++ elseif a:type == 'append' ++ call s:AppendCommentToLine() ++ ++ elseif a:type == 'insert' ++ call s:PlaceDelimitersAndInsBetween() ++ ++ elseif a:type == 'uncomment' ++ call s:UncommentLines(0, firstLine, lastLine) ++ ++ elseif a:type == 'yank' ++ if a:isVisual ++ normal gvy ++ elseif countWasGiven ++ execute firstLine .','. lastLine .'yank' ++ else ++ normal Y ++ endif ++ execute firstLine .','. lastLine .'call NERDComment('. a:isVisual .', "norm")' ++ endif ++ ++ let &ignorecase = prevIgnoreCase ++endfunction ++ ++" Function: s:PlaceDelimitersAndInsBetween() function {{{2 ++" This is function is called to place comment delimiters down and place the ++" cursor between them ++function s:PlaceDelimitersAndInsBetween() ++ " get the left and right delimiters without any escape chars in them ++ let left = s:GetLeft(0, 1, 0) ++ let right = s:GetRight(0, 1, 0) ++ ++ let theLine = getline(".") ++ let lineHasLeadTabs = s:HasLeadingTabs(theLine) || (theLine =~ '^ *$' && !&expandtab) ++ ++ "convert tabs to spaces and adjust the cursors column to take this into ++ "account ++ let untabbedCol = s:UntabbedCol(theLine, col(".")) ++ call setline(line("."), s:ConvertLeadingTabsToSpaces(theLine)) ++ call cursor(line("."), untabbedCol) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ let isDelimOnEOL = col(".") >= strlen(getline(".")) ++ ++ " if the cursor is in the first col then we gotta insert rather than ++ " append the comment delimiters here ++ let insOrApp = (col(".")==1 ? 'i' : 'a') ++ ++ " place the delimiters down. We do it differently depending on whether ++ " there is a left AND right delimiter ++ if lenRight > 0 ++ execute ":normal " . insOrApp . left . right ++ execute ":normal " . lenRight . "h" ++ else ++ execute ":normal " . insOrApp . left ++ ++ " if we are tacking the delim on the EOL then we gotta add a space ++ " after it cos when we go out of insert mode the cursor will move back ++ " one and the user wont be in position to type the comment. ++ if isDelimOnEOL ++ execute 'normal a ' ++ endif ++ endif ++ normal l ++ ++ "if needed convert spaces back to tabs and adjust the cursors col ++ "accordingly ++ if lineHasLeadTabs ++ let tabbedCol = s:TabbedCol(getline("."), col(".")) ++ call setline(line("."), s:ConvertLeadingSpacesToTabs(getline("."))) ++ call cursor(line("."), tabbedCol) ++ endif ++ ++ startinsert ++endfunction ++ ++" Function: s:PrependCommentToLine(){{{2 ++" This function prepends comment delimiters to the start of line and places ++" the cursor in position to start typing the comment ++function s:PrependCommentToLine() ++ " get the left and right delimiters without any escape chars in them ++ let left = s:GetLeft(0, 1, 0) ++ let right = s:GetRight(0, 1, 0) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ ++ "if the line is empty then we need to know about this later on ++ let isLineEmpty = strlen(getline(".")) == 0 ++ ++ "stick the delimiters down at the start of the line. We have to format the ++ "comment with spaces as appropriate ++ if lenRight > 0 ++ execute ":normal I" . left . right ++ else ++ execute ":normal I" . left ++ endif ++ ++ " if there is a right delimiter then we gotta move the cursor left ++ " by the len of the right delimiter so we insert between the delimiters ++ if lenRight > 0 ++ let leftMoveAmount = lenRight ++ execute ":normal " . leftMoveAmount . "h" ++ endif ++ normal l ++ ++ "if the line was empty then we gotta add an extra space on the end because ++ "the cursor will move back one more at the end of the last "execute" ++ "command ++ if isLineEmpty && lenRight == 0 ++ execute ":normal a " ++ endif ++ ++ startinsert ++endfunction ++" Function: s:RemoveDelimiters(left, right, line) {{{2 ++" this function is called to remove the first left comment delimiter and the ++" last right delimiter of the given line. ++" ++" The args left and right must be strings. If there is no right delimiter (as ++" is the case for e.g vim file comments) them the arg right should be "" ++" ++" Args: ++" -left: the left comment delimiter ++" -right: the right comment delimiter ++" -line: the line to remove the delimiters from ++function s:RemoveDelimiters(left, right, line) ++ ++ let l:left = a:left ++ let l:right = a:right ++ let lenLeft = strlen(left) ++ let lenRight = strlen(right) ++ ++ let delimsSpaced = (g:NERDSpaceDelims || g:NERDRemoveExtraSpaces) ++ ++ let line = a:line ++ ++ "look for the left delimiter, if we find it, remove it. ++ let leftIndx = s:FindDelimiterIndex(a:left, line) ++ if leftIndx != -1 ++ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+lenLeft) ++ ++ "if the user has specified that there is a space after the left delim ++ "then check for the space and remove it if it is there ++ if delimsSpaced && strpart(line, leftIndx, s:lenSpaceStr) == s:spaceStr ++ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+s:lenSpaceStr) ++ endif ++ endif ++ ++ "look for the right delimiter, if we find it, remove it ++ let rightIndx = s:FindDelimiterIndex(a:right, line) ++ if rightIndx != -1 ++ let line = strpart(line, 0, rightIndx) . strpart(line, rightIndx+lenRight) ++ ++ "if the user has specified that there is a space before the right delim ++ "then check for the space and remove it if it is there ++ if delimsSpaced && strpart(line, rightIndx-s:lenSpaceStr, s:lenSpaceStr) == s:spaceStr && s:Multipart() ++ let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx) ++ endif ++ endif ++ ++ return line ++endfunction ++ ++" Function: s:UncommentLines(onlyWholeLineComs, topLine, bottomLine) {{{2 ++" This function uncomments the given lines ++" ++" Args: ++" onlyWholeLineComs: should be 1 for toggle style uncommenting ++" topLine: the top line of the visual selection to uncomment ++" bottomLine: the bottom line of the visual selection to uncomment ++function s:UncommentLines(onlyWholeLineComs, topLine, bottomLine) ++ "make local copies of a:firstline and a:lastline and, if need be, swap ++ "them around if the top line is below the bottom ++ let l:firstline = a:topLine ++ let l:lastline = a:bottomLine ++ if firstline > lastline ++ let firstline = lastline ++ let lastline = a:topLine ++ endif ++ ++ "go thru each line uncommenting each line removing sexy comments ++ let currentLine = firstline ++ while currentLine <= lastline ++ ++ "check the current line to see if it is part of a sexy comment ++ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) ++ if !empty(sexyComBounds) ++ ++ "we need to store the num lines in the buf before the comment is ++ "removed so we know how many lines were removed when the sexy com ++ "was removed ++ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() ++ ++ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) ++ ++ "move to the line after last line of the sexy comment ++ let numLinesAfterSexyComRemoved = s:NumLinesInBuf() ++ let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved ++ let currentLine = sexyComBounds[1] - numLinesRemoved + 1 ++ let lastline = lastline - numLinesRemoved ++ ++ "no sexy com was detected so uncomment the line as normal ++ else ++ let theLine = getline(currentLine) ++ if a:onlyWholeLineComs && (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)) ++ call s:UncommentLinesNormal(currentLine, currentLine) ++ elseif !a:onlyWholeLineComs ++ call s:UncommentLinesNormal(currentLine, currentLine) ++ endif ++ let currentLine = currentLine + 1 ++ endif ++ endwhile ++ ++endfunction ++ ++" Function: s:UncommentLinesSexy(topline, bottomline) {{{2 ++" This function removes all the comment characters associated with the sexy ++" comment spanning the given lines ++" Args: ++" -topline/bottomline: the top/bottom lines of the sexy comment ++function s:UncommentLinesSexy(topline, bottomline) ++ let left = s:GetSexyComLeft(0,1) ++ let right = s:GetSexyComRight(0,1) ++ ++ ++ "check if it is even possible for sexy comments to exist with the ++ "available delimiters ++ if left == -1 || right == -1 ++ throw 'NERDCommenter.Delimiters exception: cannot uncomment sexy comments with available delimiters.' ++ endif ++ ++ let leftUnEsc = s:GetSexyComLeft(0,0) ++ let rightUnEsc = s:GetSexyComRight(0,0) ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ let sexyComMarkerUnEsc = s:GetSexyComMarker(0, 0) ++ ++ "the markerOffset is how far right we need to move the sexyComMarker to ++ "line it up with the end of the left delim ++ let markerOffset = strlen(leftUnEsc)-strlen(sexyComMarkerUnEsc) ++ ++ " go thru the intermediate lines of the sexy comment and remove the ++ " sexy comment markers (eg the '*'s on the start of line in a c sexy ++ " comment) ++ let currentLine = a:topline+1 ++ while currentLine < a:bottomline ++ let theLine = getline(currentLine) ++ ++ " remove the sexy comment marker from the line. We also remove the ++ " space after it if there is one and if appropriate options are set ++ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) ++ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) ++ endif ++ ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ ++ let theLine = s:ConvertLeadingWhiteSpace(theLine) ++ ++ " move onto the next line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ " gotta make a copy of a:bottomline cos we modify the position of the ++ " last line it if we remove the topline ++ let bottomline = a:bottomline ++ ++ " get the first line so we can remove the left delim from it ++ let theLine = getline(a:topline) ++ ++ " if the first line contains only the left delim then just delete it ++ if theLine =~ '^[ \t]*' . left . '[ \t]*$' && !g:NERDCompactSexyComs ++ call cursor(a:topline, 1) ++ normal dd ++ let bottomline = bottomline - 1 ++ ++ " topline contains more than just the left delim ++ else ++ ++ " remove the delim. If there is a space after it ++ " then remove this too if appropriate ++ let delimIndx = stridx(theLine, leftUnEsc) ++ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)) ++ endif ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ call setline(a:topline, theLine) ++ endif ++ ++ " get the last line so we can remove the right delim ++ let theLine = getline(bottomline) ++ ++ " if the bottomline contains only the right delim then just delete it ++ if theLine =~ '^[ \t]*' . right . '[ \t]*$' ++ call cursor(bottomline, 1) ++ normal dd ++ ++ " the last line contains more than the right delim ++ else ++ " remove the right delim. If there is a space after it and ++ " if the appropriate options are set then remove this too. ++ let delimIndx = s:LastIndexOfDelim(rightUnEsc, theLine) ++ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)) ++ endif ++ ++ " if the last line also starts with a sexy comment marker then we ++ " remove this as well ++ if theLine =~ '^[ \t]*' . sexyComMarker ++ ++ " remove the sexyComMarker. If there is a space after it then ++ " remove that too ++ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) ++ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) ++ endif ++ endif ++ ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ call setline(bottomline, theLine) ++ endif ++endfunction ++ ++" Function: s:UncommentLineNormal(line) {{{2 ++" uncomments the given line and returns the result ++" Args: ++" -line: the line to uncomment ++function s:UncommentLineNormal(line) ++ let line = a:line ++ ++ "get the comment status on the line so we know how it is commented ++ let lineCommentStatus = s:IsCommentedOuttermost(b:leftAlt, b:rightAlt, b:left, b:right, line) ++ ++ "it is commented with b:left and b:right so remove these delims ++ if lineCommentStatus == 1 ++ let line = s:RemoveDelimiters(b:leftAlt, b:rightAlt, line) ++ ++ "it is commented with b:leftAlt and b:rightAlt so remove these delims ++ elseif lineCommentStatus == 2 && g:NERDRemoveAltComs ++ let line = s:RemoveDelimiters(b:left, b:right, line) ++ ++ "it is not properly commented with any delims so we check if it has ++ "any random left or right delims on it and remove the outtermost ones ++ else ++ "get the positions of all delim types on the line ++ let indxLeft = s:FindDelimiterIndex(b:left, line) ++ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line) ++ let indxRight = s:FindDelimiterIndex(b:right, line) ++ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line) ++ ++ "remove the outter most left comment delim ++ if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1) ++ let line = s:ReplaceLeftMostDelim(b:left, '', line) ++ elseif indxLeftAlt != -1 ++ let line = s:ReplaceLeftMostDelim(b:leftAlt, '', line) ++ endif ++ ++ "remove the outter most right comment delim ++ if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1) ++ let line = s:ReplaceRightMostDelim(b:right, '', line) ++ elseif indxRightAlt != -1 ++ let line = s:ReplaceRightMostDelim(b:rightAlt, '', line) ++ endif ++ endif ++ ++ ++ let indxLeft = s:FindDelimiterIndex(b:left, line) ++ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line) ++ let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line) ++ ++ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) ++ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line) ++ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) ++ ++ let right = b:right ++ let left = b:left ++ if !s:Multipart() ++ let right = b:rightAlt ++ let left = b:leftAlt ++ endif ++ ++ ++ "if there are place-holders on the line then we check to see if they are ++ "the outtermost delimiters on the line. If so then we replace them with ++ "real delimiters ++ if indxLeftPlace != -1 ++ if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) ++ endif ++ elseif indxRightPlace != -1 ++ if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) ++ endif ++ ++ endif ++ ++ let line = s:ConvertLeadingWhiteSpace(line) ++ ++ return line ++endfunction ++ ++" Function: s:UncommentLinesNormal(topline, bottomline) {{{2 ++" This function is called to uncomment lines that arent a sexy comment ++" Args: ++" -topline/bottomline: the top/bottom line numbers of the comment ++function s:UncommentLinesNormal(topline, bottomline) ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ let line = getline(currentLine) ++ call setline(currentLine, s:UncommentLineNormal(line)) ++ let currentLine = currentLine + 1 ++ endwhile ++endfunction ++ ++ ++" Section: Other helper functions {{{1 ++" ============================================================================ ++ ++" Function: s:AddLeftDelim(delim, theLine) {{{2 ++" Args: ++function s:AddLeftDelim(delim, theLine) ++ return substitute(a:theLine, '^\([ \t]*\)', '\1' . a:delim, '') ++endfunction ++ ++" Function: s:AddLeftDelimAligned(delim, theLine) {{{2 ++" Args: ++function s:AddLeftDelimAligned(delim, theLine, alignIndx) ++ ++ "if the line is not long enough then bung some extra spaces on the front ++ "so we can align the delim properly ++ let theLine = a:theLine ++ if strlen(theLine) < a:alignIndx ++ let theLine = strpart(s:spaces, 0, a:alignIndx - strlen(theLine)) ++ endif ++ ++ return strpart(theLine, 0, a:alignIndx) . a:delim . strpart(theLine, a:alignIndx) ++endfunction ++ ++" Function: s:AddRightDelim(delim, theLine) {{{2 ++" Args: ++function s:AddRightDelim(delim, theLine) ++ if a:delim == '' ++ return a:theLine ++ else ++ return substitute(a:theLine, '$', a:delim, '') ++ endif ++endfunction ++ ++" Function: s:AddRightDelimAligned(delim, theLine, alignIndx) {{{2 ++" Args: ++function s:AddRightDelimAligned(delim, theLine, alignIndx) ++ if a:delim == "" ++ return a:theLine ++ else ++ ++ " when we align the right delim we are just adding spaces ++ " so we get a string containing the needed spaces (it ++ " could be empty) ++ let extraSpaces = '' ++ let extraSpaces = strpart(s:spaces, 0, a:alignIndx-strlen(a:theLine)) ++ ++ " add the right delim ++ return substitute(a:theLine, '$', extraSpaces . a:delim, '') ++ endif ++endfunction ++ ++" Function: s:AltMultipart() {{{2 ++" returns 1 if the alternative delims are multipart ++function s:AltMultipart() ++ return b:rightAlt != '' ++endfunction ++ ++" Function: s:CanCommentLine(forceNested, line) {{{2 ++"This function is used to determine whether the given line can be commented. ++"It returns 1 if it can be and 0 otherwise ++" ++" Args: ++" -forceNested: a flag indicating whether the caller wants comments to be nested ++" if the current line is already commented ++" -lineNum: the line num of the line to check for commentability ++function s:CanCommentLine(forceNested, lineNum) ++ let theLine = getline(a:lineNum) ++ ++ " make sure we don't comment lines that are just spaces or tabs or empty. ++ if theLine =~ "^[ \t]*$" ++ return 0 ++ endif ++ ++ "if the line is part of a sexy comment then just flag it... ++ if s:IsInSexyComment(a:lineNum) ++ return 0 ++ endif ++ ++ let isCommented = s:IsCommentedNormOrSexy(a:lineNum) ++ ++ "if the line isnt commented return true ++ if !isCommented ++ return 1 ++ endif ++ ++ "if the line is commented but nesting is allowed then return true ++ if a:forceNested && (!s:Multipart() || g:NERDUsePlaceHolders) ++ return 1 ++ endif ++ ++ return 0 ++endfunction ++ ++" Function: s:CanPlaceCursor(line, col) {{{2 ++" returns 1 if the cursor can be placed exactly in the given position ++function s:CanPlaceCursor(line, col) ++ let c = col(".") ++ let l = line(".") ++ call cursor(a:line, a:col) ++ let success = (line(".") == a:line && col(".") == a:col) ++ call cursor(l,c) ++ return success ++endfunction ++ ++" Function: s:CanSexyCommentLines(topline, bottomline) {{{2 ++" Return: 1 if the given lines can be commented sexually, 0 otherwise ++function s:CanSexyCommentLines(topline, bottomline) ++ " see if the selected regions have any sexy comments ++ let currentLine = a:topline ++ while(currentLine <= a:bottomline) ++ if s:IsInSexyComment(currentLine) ++ return 0 ++ endif ++ let currentLine = currentLine + 1 ++ endwhile ++ return 1 ++endfunction ++" Function: s:CanToggleCommentLine(forceNested, line) {{{2 ++"This function is used to determine whether the given line can be toggle commented. ++"It returns 1 if it can be and 0 otherwise ++" ++" Args: ++" -lineNum: the line num of the line to check for commentability ++function s:CanToggleCommentLine(forceNested, lineNum) ++ let theLine = getline(a:lineNum) ++ if (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)) && !a:forceNested ++ return 0 ++ endif ++ ++ " make sure we don't comment lines that are just spaces or tabs or empty. ++ if theLine =~ "^[ \t]*$" ++ return 0 ++ endif ++ ++ "if the line is part of a sexy comment then just flag it... ++ if s:IsInSexyComment(a:lineNum) ++ return 0 ++ endif ++ ++ return 1 ++endfunction ++ ++" Function: s:ConvertLeadingSpacesToTabs(line) {{{2 ++" This function takes a line and converts all leading tabs on that line into ++" spaces ++" ++" Args: ++" -line: the line whose leading tabs will be converted ++function s:ConvertLeadingSpacesToTabs(line) ++ let toReturn = a:line ++ while toReturn =~ '^\t*' . s:TabSpace() . '\(.*\)$' ++ let toReturn = substitute(toReturn, '^\(\t*\)' . s:TabSpace() . '\(.*\)$' , '\1\t\2' , "") ++ endwhile ++ ++ return toReturn ++endfunction ++ ++ ++" Function: s:ConvertLeadingTabsToSpaces(line) {{{2 ++" This function takes a line and converts all leading spaces on that line into ++" tabs ++" ++" Args: ++" -line: the line whose leading spaces will be converted ++function s:ConvertLeadingTabsToSpaces(line) ++ let toReturn = a:line ++ while toReturn =~ '^\( *\)\t' ++ let toReturn = substitute(toReturn, '^\( *\)\t', '\1' . s:TabSpace() , "") ++ endwhile ++ ++ return toReturn ++endfunction ++ ++" Function: s:ConvertLeadingWhiteSpace(line) {{{2 ++" Converts the leading white space to tabs/spaces depending on &ts ++" ++" Args: ++" -line: the line to convert ++function s:ConvertLeadingWhiteSpace(line) ++ let toReturn = a:line ++ while toReturn =~ '^ *\t' ++ let toReturn = substitute(toReturn, '^ *\zs\t\ze', s:TabSpace(), "g") ++ endwhile ++ ++ if !&expandtab ++ let toReturn = s:ConvertLeadingSpacesToTabs(toReturn) ++ endif ++ ++ return toReturn ++endfunction ++ ++ ++" Function: s:CountNonESCedOccurances(str, searchstr, escChar) {{{2 ++" This function counts the number of substrings contained in another string. ++" These substrings are only counted if they are not escaped with escChar ++" Args: ++" -str: the string to look for searchstr in ++" -searchstr: the substring to search for in str ++" -escChar: the escape character which, when preceding an instance of ++" searchstr, will cause it not to be counted ++function s:CountNonESCedOccurances(str, searchstr, escChar) ++ "get the index of the first occurrence of searchstr ++ let indx = stridx(a:str, a:searchstr) ++ ++ "if there is an instance of searchstr in str process it ++ if indx != -1 ++ "get the remainder of str after this instance of searchstr is removed ++ let lensearchstr = strlen(a:searchstr) ++ let strLeft = strpart(a:str, indx+lensearchstr) ++ ++ "if this instance of searchstr is not escaped, add one to the count ++ "and recurse. If it is escaped, just recurse ++ if !s:IsEscaped(a:str, indx, a:escChar) ++ return 1 + s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) ++ else ++ return s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) ++ endif ++ endif ++endfunction ++" Function: s:DoesBlockHaveDelim(delim, top, bottom) {{{2 ++" Returns 1 if the given block of lines has a delimiter (a:delim) in it ++" Args: ++" -delim: the comment delimiter to check the block for ++" -top: the top line number of the block ++" -bottom: the bottom line number of the block ++function s:DoesBlockHaveDelim(delim, top, bottom) ++ let currentLine = a:top ++ while currentLine < a:bottom ++ let theline = getline(currentLine) ++ if s:FindDelimiterIndex(a:delim, theline) != -1 ++ return 1 ++ endif ++ let currentLine = currentLine + 1 ++ endwhile ++ return 0 ++endfunction ++ ++" Function: s:DoesBlockHaveMultipartDelim(top, bottom) {{{2 ++" Returns 1 if the given block has a >= 1 multipart delimiter in it ++" Args: ++" -top: the top line number of the block ++" -bottom: the bottom line number of the block ++function s:DoesBlockHaveMultipartDelim(top, bottom) ++ if s:HasMultipartDelims() ++ if s:Multipart() ++ return s:DoesBlockHaveDelim(b:left, a:top, a:bottom) || s:DoesBlockHaveDelim(b:right, a:top, a:bottom) ++ else ++ return s:DoesBlockHaveDelim(b:leftAlt, a:top, a:bottom) || s:DoesBlockHaveDelim(b:rightAlt, a:top, a:bottom) ++ endif ++ endif ++ return 0 ++endfunction ++ ++ ++" Function: s:Esc(str) {{{2 ++" Escapes all the tricky chars in the given string ++function s:Esc(str) ++ let charsToEsc = '*/\."&$+' ++ return escape(a:str, charsToEsc) ++endfunction ++ ++" Function: s:FindDelimiterIndex(delimiter, line) {{{2 ++" This function is used to get the string index of the input comment delimiter ++" on the input line. If no valid comment delimiter is found in the line then ++" -1 is returned ++" Args: ++" -delimiter: the delimiter we are looking to find the index of ++" -line: the line we are looking for delimiter on ++function s:FindDelimiterIndex(delimiter, line) ++ ++ "make sure the delimiter isnt empty otherwise we go into an infinite loop. ++ if a:delimiter == "" ++ return -1 ++ endif ++ ++ ++ let l:delimiter = a:delimiter ++ let lenDel = strlen(l:delimiter) ++ ++ "get the index of the first occurrence of the delimiter ++ let delIndx = stridx(a:line, l:delimiter) ++ ++ "keep looping thru the line till we either find a real comment delimiter ++ "or run off the EOL ++ while delIndx != -1 ++ ++ "if we are not off the EOL get the str before the possible delimiter ++ "in question and check if it really is a delimiter. If it is, return ++ "its position ++ if delIndx != -1 ++ if s:IsDelimValid(l:delimiter, delIndx, a:line) ++ return delIndx ++ endif ++ endif ++ ++ "we have not yet found a real comment delimiter so move past the ++ "current one we are lookin at ++ let restOfLine = strpart(a:line, delIndx + lenDel) ++ let distToNextDelim = stridx(restOfLine , l:delimiter) ++ ++ "if distToNextDelim is -1 then there is no more potential delimiters ++ "on the line so set delIndx to -1. Otherwise, move along the line by ++ "distToNextDelim ++ if distToNextDelim == -1 ++ let delIndx = -1 ++ else ++ let delIndx = delIndx + lenDel + distToNextDelim ++ endif ++ endwhile ++ ++ "there is no comment delimiter on this line ++ return -1 ++endfunction ++ ++" Function: s:FindBoundingLinesOfSexyCom(lineNum) {{{2 ++" This function takes in a line number and tests whether this line number is ++" the top/bottom/middle line of a sexy comment. If it is then the top/bottom ++" lines of the sexy comment are returned ++" Args: ++" -lineNum: the line number that is to be tested whether it is the ++" top/bottom/middle line of a sexy com ++" Returns: ++" A string that has the top/bottom lines of the sexy comment encoded in it. ++" The format is 'topline,bottomline'. If a:lineNum turns out not to be the ++" top/bottom/middle of a sexy comment then -1 is returned ++function s:FindBoundingLinesOfSexyCom(lineNum) ++ ++ "find which delimiters to look for as the start/end delims of the comment ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = s:GetLeft(0,0,1) ++ let right = s:GetRight(0,0,1) ++ elseif s:AltMultipart() ++ let left = s:GetLeft(1,0,1) ++ let right = s:GetRight(1,0,1) ++ else ++ return [] ++ endif ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ ++ "initialise the top/bottom line numbers of the sexy comment to -1 ++ let top = -1 ++ let bottom = -1 ++ ++ let currentLine = a:lineNum ++ while top == -1 || bottom == -1 ++ let theLine = getline(currentLine) ++ ++ "check if the current line is the top of the sexy comment ++ if theLine =~ '^[ \t]*' . left && theLine !~ '.*' . right ++ let top = currentLine ++ let currentLine = a:lineNum ++ ++ "check if the current line is the bottom of the sexy comment ++ elseif theLine =~ '^[ \t]*' . right && theLine !~ '.*' . left ++ let bottom = currentLine ++ ++ "the right delimiter is on the same line as the last sexyComMarker ++ elseif theLine =~ '^[ \t]*' . sexyComMarker . '.*' . right ++ let bottom = currentLine ++ ++ "we have not found the top or bottom line so we assume currentLine is an ++ "intermediate line and look to prove otherwise ++ else ++ ++ "if the line doesnt start with a sexyComMarker then it is not a sexy ++ "comment ++ if theLine !~ '^[ \t]*' . sexyComMarker ++ return [] ++ endif ++ ++ endif ++ ++ "if top is -1 then we havent found the top yet so keep looking up ++ if top == -1 ++ let currentLine = currentLine - 1 ++ "if we have found the top line then go down looking for the bottom ++ else ++ let currentLine = currentLine + 1 ++ endif ++ ++ endwhile ++ ++ return [top, bottom] ++endfunction ++ ++ ++" Function: s:GetLeft(alt, space, esc) {{{2 ++" returns the left/left-alternative delimiter ++" Args: ++" -alt: specifies whether to get left or left-alternative delim ++" -space: specifies whether the delim should be spaced or not ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the delim should be ESCed ++function s:GetLeft(alt, space, esc) ++ let delim = b:left ++ ++ if a:alt ++ if b:leftAlt == '' ++ return '' ++ else ++ let delim = b:leftAlt ++ endif ++ endif ++ if delim == '' ++ return '' ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let delim = delim . s:spaceStr ++ endif ++ ++ if a:esc ++ let delim = s:Esc(delim) ++ endif ++ ++ return delim ++endfunction ++ ++" Function: s:GetRight(alt, space, esc) {{{2 ++" returns the right/right-alternative delimiter ++" Args: ++" -alt: specifies whether to get right or right-alternative delim ++" -space: specifies whether the delim should be spaced or not ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the delim should be ESCed ++function s:GetRight(alt, space, esc) ++ let delim = b:right ++ ++ if a:alt ++ if !s:AltMultipart() ++ return '' ++ else ++ let delim = b:rightAlt ++ endif ++ endif ++ if delim == '' ++ return '' ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let delim = s:spaceStr . delim ++ endif ++ ++ if a:esc ++ let delim = s:Esc(delim) ++ endif ++ ++ return delim ++endfunction ++ ++ ++" Function: s:GetSexyComMarker() {{{2 ++" Returns the sexy comment marker for the current filetype. ++" ++" C style sexy comments are assumed if possible. If not then the sexy comment ++" marker is the last char of the delimiter pair that has both left and right ++" delims and has the longest left delim ++" ++" Args: ++" -space: specifies whether the marker is to have a space string after it ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the marker are to be ESCed ++function s:GetSexyComMarker(space, esc) ++ let sexyComMarker = b:sexyComMarker ++ ++ "if there is no hardcoded marker then we find one ++ if sexyComMarker == '' ++ ++ "if the filetype has c style comments then use standard c sexy ++ "comments ++ if s:HasCStyleComments() ++ let sexyComMarker = '*' ++ else ++ "find a comment marker by getting the longest available left delim ++ "(that has a corresponding right delim) and taking the last char ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let left = '' ++ let right = '' ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let left = b:left ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ else ++ return -1 ++ endif ++ ++ "get the last char of left ++ let sexyComMarker = strpart(left, strlen(left)-1) ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let sexyComMarker = sexyComMarker . s:spaceStr ++ endif ++ ++ if a:esc ++ let sexyComMarker = s:Esc(sexyComMarker) ++ endif ++ ++ return sexyComMarker ++endfunction ++ ++" Function: s:GetSexyComLeft(space, esc) {{{2 ++" Returns the left delimiter for sexy comments for this filetype or -1 if ++" there is none. C style sexy comments are used if possible ++" Args: ++" -space: specifies if the delim has a space string on the end ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the string are ESCed ++function s:GetSexyComLeft(space, esc) ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let left = '' ++ ++ "assume c style sexy comments if possible ++ if s:HasCStyleComments() ++ let left = '/*' ++ else ++ "grab the longest left delim that has a right ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let left = b:left ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ else ++ return -1 ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let left = left . s:spaceStr ++ endif ++ ++ if a:esc ++ let left = s:Esc(left) ++ endif ++ ++ return left ++endfunction ++ ++" Function: s:GetSexyComRight(space, esc) {{{2 ++" Returns the right delimiter for sexy comments for this filetype or -1 if ++" there is none. C style sexy comments are used if possible. ++" Args: ++" -space: specifies if the delim has a space string on the start ++" (the space string will only be added if NERDSpaceDelims ++" is specified for the current filetype) ++" -esc: specifies whether the tricky chars in the string are ESCed ++function s:GetSexyComRight(space, esc) ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let right = '' ++ ++ "assume c style sexy comments if possible ++ if s:HasCStyleComments() ++ let right = '*/' ++ else ++ "grab the right delim that pairs with the longest left delim ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let right = b:right ++ elseif s:AltMultipart() ++ let right = b:rightAlt ++ else ++ return -1 ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let right = s:spaceStr . right ++ endif ++ ++ if a:esc ++ let right = s:Esc(right) ++ endif ++ ++ return right ++endfunction ++ ++" Function: s:HasMultipartDelims() {{{2 ++" Returns 1 iff the current filetype has at least one set of multipart delims ++function s:HasMultipartDelims() ++ return s:Multipart() || s:AltMultipart() ++endfunction ++ ++" Function: s:HasLeadingTabs(...) {{{2 ++" Returns 1 if any of the given strings have leading tabs ++function s:HasLeadingTabs(...) ++ for s in a:000 ++ if s =~ '^\t.*' ++ return 1 ++ end ++ endfor ++ return 0 ++endfunction ++" Function: s:HasCStyleComments() {{{2 ++" Returns 1 iff the current filetype has c style comment delimiters ++function s:HasCStyleComments() ++ return (b:left == '/*' && b:right == '*/') || (b:leftAlt == '/*' && b:rightAlt == '*/') ++endfunction ++ ++" Function: s:InstallDocumentation(full_name, revision) {{{2 ++" Install help documentation. ++" Arguments: ++" full_name: Full name of this vim plugin script, including path name. ++" revision: Revision of the vim script. #version# mark in the document file ++" will be replaced with this string with 'v' prefix. ++" Return: ++" 1 if new document installed, 0 otherwise. ++" Note: Cleaned and generalized by guo-peng Wen. ++" ++" Note about authorship: this function was taken from the vimspell plugin ++" which can be found at http://www.vim.org/scripts/script.php?script_id=465 ++" ++function s:InstallDocumentation(full_name, revision) ++ " Name of the document path based on the system we use: ++ if has("vms") ++ " No chance that this script will work with ++ " VMS - to much pathname juggling here. ++ return 1 ++ elseif (has("unix")) ++ " On UNIX like system, using forward slash: ++ let l:slash_char = '/' ++ let l:mkdir_cmd = ':silent !mkdir -p ' ++ else ++ " On M$ system, use backslash. Also mkdir syntax is different. ++ " This should only work on W2K and up. ++ let l:slash_char = '\' ++ let l:mkdir_cmd = ':silent !mkdir ' ++ endif ++ ++ let l:doc_path = l:slash_char . 'doc' ++ let l:doc_home = l:slash_char . '.vim' . l:slash_char . 'doc' ++ ++ " Figure out document path based on full name of this script: ++ let l:vim_plugin_path = fnamemodify(a:full_name, ':h') ++ let l:vim_doc_path = fnamemodify(a:full_name, ':h:h') . l:doc_path ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ "Doc path: " . l:vim_doc_path ++ call s:NerdEcho("Doc path: " . l:vim_doc_path, 0) ++ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ " Try a default configuration in user home: ++ let l:vim_doc_path = expand("~") . l:doc_home ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ " Put a warning: ++ call s:NerdEcho("Unable to open documentation directory \ntype :help add-local-help for more information.", 0) ++ echo l:vim_doc_path ++ return 0 ++ endif ++ endif ++ endif ++ endif ++ ++ " Exit if we have problem to access the document directory: ++ if (!isdirectory(l:vim_plugin_path) || !isdirectory(l:vim_doc_path) || filewritable(l:vim_doc_path) != 2) ++ return 0 ++ endif ++ ++ " Full name of script and documentation file: ++ let l:script_name = fnamemodify(a:full_name, ':t') ++ let l:doc_name = fnamemodify(a:full_name, ':t:r') . '.txt' ++ let l:plugin_file = l:vim_plugin_path . l:slash_char . l:script_name ++ let l:doc_file = l:vim_doc_path . l:slash_char . l:doc_name ++ ++ " Bail out if document file is still up to date: ++ if (filereadable(l:doc_file) && getftime(l:plugin_file) < getftime(l:doc_file)) ++ return 0 ++ endif ++ ++ " Prepare window position restoring command: ++ if (strlen(@%)) ++ let l:go_back = 'b ' . bufnr("%") ++ else ++ let l:go_back = 'enew!' ++ endif ++ ++ " Create a new buffer & read in the plugin file (me): ++ setl nomodeline ++ exe 'enew!' ++ exe 'r ' . escape(l:plugin_file,s:NERDFileNameEscape) ++ ++ setl modeline ++ let l:buf = bufnr("%") ++ setl noswapfile modifiable ++ ++ norm zR ++ norm gg ++ ++ " Delete from first line to a line starts with ++ " === START_DOC ++ 1,/^=\{3,}\s\+START_DOC\C/ d ++ ++ " Delete from a line starts with ++ " === END_DOC ++ " to the end of the documents: ++ /^=\{3,}\s\+END_DOC\C/,$ d ++ ++ " Remove fold marks: ++ :%s/{\{3}[1-9]/ / ++ ++ " Add modeline for help doc: the modeline string is mangled intentionally ++ " to avoid it be recognized by VIM: ++ call append(line('$'), '') ++ call append(line('$'), ' v' . 'im:tw=78:ts=8:ft=help:norl:') ++ ++ " Replace revision: ++ "exe "normal :1s/#version#/ v" . a:revision . "/\" ++ exe "normal :%s/#version#/ v" . a:revision . "/\" ++ ++ " Save the help document: ++ exe 'w! ' . escape(l:doc_file,s:NERDFileNameEscape) ++ exe l:go_back ++ exe 'bw ' . l:buf ++ ++ " Build help tags: ++ exe 'helptags ' . escape(l:vim_doc_path,s:NERDFileNameEscape) ++ ++ return 1 ++endfunction ++ ++ ++" Function: s:IsCommentedNormOrSexy(lineNum) {{{2 ++"This function is used to determine whether the given line is commented with ++"either set of delimiters or if it is part of a sexy comment ++" ++" Args: ++" -lineNum: the line number of the line to check ++function s:IsCommentedNormOrSexy(lineNum) ++ let theLine = getline(a:lineNum) ++ ++ "if the line is commented normally return 1 ++ if s:IsCommented(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine) ++ return 1 ++ endif ++ ++ "if the line is part of a sexy comment return 1 ++ if s:IsInSexyComment(a:lineNum) ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Function: s:IsCommented(left, right, line) {{{2 ++"This function is used to determine whether the given line is commented with ++"the given delimiters ++" ++" Args: ++" -line: the line that to check if commented ++" -left/right: the left and right delimiters to check for ++function s:IsCommented(left, right, line) ++ "if the line isnt commented return true ++ if s:FindDelimiterIndex(a:left, a:line) != -1 && (s:FindDelimiterIndex(a:right, a:line) != -1 || !s:Multipart()) ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Function: s:IsCommentedFromStartOfLine(left, line) {{{2 ++"This function is used to determine whether the given line is commented with ++"the given delimiters at the start of the line i.e the left delimiter is the ++"first thing on the line (apart from spaces\tabs) ++" ++" Args: ++" -line: the line that to check if commented ++" -left: the left delimiter to check for ++function s:IsCommentedFromStartOfLine(left, line) ++ let theLine = s:ConvertLeadingTabsToSpaces(a:line) ++ let numSpaces = strlen(substitute(theLine, '^\( *\).*$', '\1', '')) ++ let delimIndx = s:FindDelimiterIndex(a:left, theLine) ++ return delimIndx == numSpaces ++endfunction ++ ++" Function: s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) {{{2 ++" Finds the type of the outtermost delims on the line ++" ++" Args: ++" -line: the line that to check if the outtermost comments on it are ++" left/right ++" -left/right: the left and right delimiters to check for ++" -leftAlt/rightAlt: the left and right alternative delimiters to check for ++" ++" Returns: ++" 0 if the line is not commented with either set of delims ++" 1 if the line is commented with the left/right delim set ++" 2 if the line is commented with the leftAlt/rightAlt delim set ++function s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) ++ "get the first positions of the left delims and the last positions of the ++ "right delims ++ let indxLeft = s:FindDelimiterIndex(a:left, a:line) ++ let indxLeftAlt = s:FindDelimiterIndex(a:leftAlt, a:line) ++ let indxRight = s:LastIndexOfDelim(a:right, a:line) ++ let indxRightAlt = s:LastIndexOfDelim(a:rightAlt, a:line) ++ ++ "check if the line has a left delim before a leftAlt delim ++ if (indxLeft <= indxLeftAlt || indxLeftAlt == -1) && indxLeft != -1 ++ "check if the line has a right delim after any rightAlt delim ++ if (indxRight > indxRightAlt && indxRight > indxLeft) || !s:Multipart() ++ return 1 ++ endif ++ ++ "check if the line has a leftAlt delim before a left delim ++ elseif (indxLeftAlt <= indxLeft || indxLeft == -1) && indxLeftAlt != -1 ++ "check if the line has a rightAlt delim after any right delim ++ if (indxRightAlt > indxRight && indxRightAlt > indxLeftAlt) || !s:AltMultipart() ++ return 2 ++ endif ++ else ++ return 0 ++ endif ++ ++ return 0 ++ ++endfunction ++ ++ ++" Function: s:IsDelimValid(delimiter, delIndx, line) {{{2 ++" This function is responsible for determining whether a given instance of a ++" comment delimiter is a real delimiter or not. For example, in java the ++" // string is a comment delimiter but in the line: ++" System.out.println("//"); ++" it does not count as a comment delimiter. This function is responsible for ++" distinguishing between such cases. It does so by applying a set of ++" heuristics that are not fool proof but should work most of the time. ++" ++" Args: ++" -delimiter: the delimiter we are validating ++" -delIndx: the position of delimiter in line ++" -line: the line that delimiter occurs in ++" ++" Returns: ++" 0 if the given delimiter is not a real delimiter (as far as we can tell) , ++" 1 otherwise ++function s:IsDelimValid(delimiter, delIndx, line) ++ "get the delimiter without the escchars ++ let l:delimiter = a:delimiter ++ ++ "get the strings before and after the delimiter ++ let preComStr = strpart(a:line, 0, a:delIndx) ++ let postComStr = strpart(a:line, a:delIndx+strlen(delimiter)) ++ ++ "to check if the delimiter is real, make sure it isnt preceded by ++ "an odd number of quotes and followed by the same (which would indicate ++ "that it is part of a string and therefore is not a comment) ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '"', "\\")) ++ return 0 ++ endif ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "'", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "'", "\\")) ++ return 0 ++ endif ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "`", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "`", "\\")) ++ return 0 ++ endif ++ ++ ++ "if the comment delimiter is escaped, assume it isnt a real delimiter ++ if s:IsEscaped(a:line, a:delIndx, "\\") ++ return 0 ++ endif ++ ++ "vim comments are so fuckin stupid!! Why the hell do they have comment ++ "delimiters that are used elsewhere in the syntax?!?! We need to check ++ "some conditions especially for vim ++ if &filetype == "vim" ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) ++ return 0 ++ endif ++ ++ "if the delimiter is on the very first char of the line or is the ++ "first non-tab/space char on the line then it is a valid comment delimiter ++ if a:delIndx == 0 || a:line =~ "^[ \t]\\{" . a:delIndx . "\\}\".*$" ++ return 1 ++ endif ++ ++ let numLeftParen =s:CountNonESCedOccurances(preComStr, "(", "\\") ++ let numRightParen =s:CountNonESCedOccurances(preComStr, ")", "\\") ++ ++ "if the quote is inside brackets then assume it isnt a comment ++ if numLeftParen > numRightParen ++ return 0 ++ endif ++ ++ "if the line has an even num of unescaped "'s then we can assume that ++ "any given " is not a comment delimiter ++ if s:IsNumEven(s:CountNonESCedOccurances(a:line, "\"", "\\")) ++ return 0 ++ endif ++ endif ++ ++ return 1 ++ ++endfunction ++ ++" Function: s:IsNumEven(num) {{{2 ++" A small function the returns 1 if the input number is even and 0 otherwise ++" Args: ++" -num: the number to check ++function s:IsNumEven(num) ++ return (a:num % 2) == 0 ++endfunction ++ ++" Function: s:IsEscaped(str, indx, escChar) {{{2 ++" This function takes a string, an index into that string and an esc char and ++" returns 1 if the char at the index is escaped (i.e if it is preceded by an ++" odd number of esc chars) ++" Args: ++" -str: the string to check ++" -indx: the index into str that we want to check ++" -escChar: the escape char the char at indx may be ESCed with ++function s:IsEscaped(str, indx, escChar) ++ "initialise numEscChars to 0 and look at the char before indx ++ let numEscChars = 0 ++ let curIndx = a:indx-1 ++ ++ "keep going back thru str until we either reach the start of the str or ++ "run out of esc chars ++ while curIndx >= 0 && strpart(a:str, curIndx, 1) == a:escChar ++ ++ "we have found another esc char so add one to the count and move left ++ "one char ++ let numEscChars = numEscChars + 1 ++ let curIndx = curIndx - 1 ++ ++ endwhile ++ ++ "if there is an odd num of esc chars directly before the char at indx then ++ "the char at indx is escaped ++ return !s:IsNumEven(numEscChars) ++endfunction ++ ++" Function: s:IsInSexyComment(line) {{{2 ++" returns 1 if the given line number is part of a sexy comment ++function s:IsInSexyComment(line) ++ return !empty(s:FindBoundingLinesOfSexyCom(a:line)) ++endfunction ++ ++" Function: s:IsSexyComment(topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns 1 if the lines between and ++" including the given line numbers are a sexy comment. It returns 0 otherwise. ++" Args: ++" -topline: the line that the possible sexy comment starts on ++" -bottomline: the line that the possible sexy comment stops on ++function s:IsSexyComment(topline, bottomline) ++ ++ "get the delim set that would be used for a sexy comment ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = b:left ++ let right = b:right ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ let right = b:rightAlt ++ else ++ return 0 ++ endif ++ ++ "swap the top and bottom line numbers around if need be ++ let topline = a:topline ++ let bottomline = a:bottomline ++ if bottomline < topline ++ topline = bottomline ++ bottomline = a:topline ++ endif ++ ++ "if there is < 2 lines in the comment it cannot be sexy ++ if (bottomline - topline) <= 0 ++ return 0 ++ endif ++ ++ "if the top line doesnt begin with a left delim then the comment isnt sexy ++ if getline(a:topline) !~ '^[ \t]*' . left ++ return 0 ++ endif ++ ++ "if there is a right delim on the top line then this isnt a sexy comment ++ if s:FindDelimiterIndex(right, getline(a:topline)) != -1 ++ return 0 ++ endif ++ ++ "if there is a left delim on the bottom line then this isnt a sexy comment ++ if s:FindDelimiterIndex(left, getline(a:bottomline)) != -1 ++ return 0 ++ endif ++ ++ "if the bottom line doesnt begin with a right delim then the comment isnt ++ "sexy ++ if getline(a:bottomline) !~ '^.*' . right . '$' ++ return 0 ++ endif ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ ++ "check each of the intermediate lines to make sure they start with a ++ "sexyComMarker ++ let currentLine = a:topline+1 ++ while currentLine < a:bottomline ++ let theLine = getline(currentLine) ++ ++ if theLine !~ '^[ \t]*' . sexyComMarker ++ return 0 ++ endif ++ ++ "if there is a right delim in an intermediate line then the block isnt ++ "a sexy comment ++ if s:FindDelimiterIndex(right, theLine) != -1 ++ return 0 ++ endif ++ ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "we have not found anything to suggest that this isnt a sexy comment so ++ return 1 ++ ++endfunction ++ ++" Function: s:LastIndexOfDelim(delim, str) {{{2 ++" This function takes a string and a delimiter and returns the last index of ++" that delimiter in string ++" Args: ++" -delim: the delimiter to look for ++" -str: the string to look for delim in ++function s:LastIndexOfDelim(delim, str) ++ let delim = a:delim ++ let lenDelim = strlen(delim) ++ ++ "set index to the first occurrence of delim. If there is no occurrence then ++ "bail ++ let indx = s:FindDelimiterIndex(delim, a:str) ++ if indx == -1 ++ return -1 ++ endif ++ ++ "keep moving to the next instance of delim in str till there is none left ++ while 1 ++ ++ "search for the next delim after the previous one ++ let searchStr = strpart(a:str, indx+lenDelim) ++ let indx2 = s:FindDelimiterIndex(delim, searchStr) ++ ++ "if we find a delim update indx to record the position of it, if we ++ "dont find another delim then indx is the last one so break out of ++ "this loop ++ if indx2 != -1 ++ let indx = indx + indx2 + lenDelim ++ else ++ break ++ endif ++ endwhile ++ ++ return indx ++ ++endfunction ++ ++" Function: s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns the index of the left most ++" char (that is not a space or a tab) on all of these lines. ++" Args: ++" -countCommentedLines: 1 if lines that are commented are to be checked as ++" well. 0 otherwise ++" -countEmptyLines: 1 if empty lines are to be counted in the search ++" -topline: the top line to be checked ++" -bottomline: the bottom line to be checked ++function s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) ++ ++ " declare the left most index as an extreme value ++ let leftMostIndx = 1000 ++ ++ " go thru the block line by line updating leftMostIndx ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ ++ " get the next line and if it is allowed to be commented, or is not ++ " commented, check it ++ let theLine = getline(currentLine) ++ if a:countEmptyLines || theLine !~ '^[ \t]*$' ++ if a:countCommentedLines || (!s:IsCommented(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, theLine)) ++ " convert spaces to tabs and get the number of leading spaces for ++ " this line and update leftMostIndx if need be ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let leadSpaceOfLine = strlen( substitute(theLine, '\(^[ \t]*\).*$','\1','') ) ++ if leadSpaceOfLine < leftMostIndx ++ let leftMostIndx = leadSpaceOfLine ++ endif ++ endif ++ endif ++ ++ " move on to the next line ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ if leftMostIndx == 1000 ++ return 0 ++ else ++ return leftMostIndx ++ endif ++endfunction ++ ++" Function: s:Multipart() {{{2 ++" returns 1 if the current delims are multipart ++function s:Multipart() ++ return b:right != '' ++endfunction ++ ++" Function: s:NerdEcho(msg, typeOfMsg) {{{2 ++" Args: ++" -msg: the message to echo ++" -typeOfMsg: 0 = warning message ++" 1 = normal message ++function s:NerdEcho(msg, typeOfMsg) ++ if a:typeOfMsg == 0 ++ echohl WarningMsg ++ echo 'NERDCommenter:' . a:msg ++ echohl None ++ elseif a:typeOfMsg == 1 ++ echo 'NERDCommenter:' . a:msg ++ endif ++endfunction ++ ++" Function: s:NumberOfLeadingTabs(s) {{{2 ++" returns the number of leading tabs in the given string ++function s:NumberOfLeadingTabs(s) ++ return strlen(substitute(a:s, '^\(\t*\).*$', '\1', "")) ++endfunction ++ ++" Function: s:NumLinesInBuf() {{{2 ++" Returns the number of lines in the current buffer ++function s:NumLinesInBuf() ++ return line('$') ++endfunction ++ ++" Function: s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) {{{2 ++" This function takes in a string, 2 delimiters in that string and 2 strings ++" to replace these delimiters with. ++" ++" Args: ++" -toReplace1: the first delimiter to replace ++" -toReplace2: the second delimiter to replace ++" -replacor1: the string to replace toReplace1 with ++" -replacor2: the string to replace toReplace2 with ++" -str: the string that the delimiters to be replaced are in ++function s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) ++ let line = s:ReplaceLeftMostDelim(a:toReplace1, a:replacor1, a:str) ++ let line = s:ReplaceRightMostDelim(a:toReplace2, a:replacor2, line) ++ return line ++endfunction ++ ++" Function: s:ReplaceLeftMostDelim(toReplace, replacor, str) {{{2 ++" This function takes a string and a delimiter and replaces the left most ++" occurrence of this delimiter in the string with a given string ++" ++" Args: ++" -toReplace: the delimiter in str that is to be replaced ++" -replacor: the string to replace toReplace with ++" -str: the string that contains toReplace ++function s:ReplaceLeftMostDelim(toReplace, replacor, str) ++ let toReplace = a:toReplace ++ let replacor = a:replacor ++ "get the left most occurrence of toReplace ++ let indxToReplace = s:FindDelimiterIndex(toReplace, a:str) ++ ++ "if there IS an occurrence of toReplace in str then replace it and return ++ "the resulting string ++ if indxToReplace != -1 ++ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) ++ return line ++ endif ++ ++ return a:str ++endfunction ++ ++" Function: s:ReplaceRightMostDelim(toReplace, replacor, str) {{{2 ++" This function takes a string and a delimiter and replaces the right most ++" occurrence of this delimiter in the string with a given string ++" ++" Args: ++" -toReplace: the delimiter in str that is to be replaced ++" -replacor: the string to replace toReplace with ++" -str: the string that contains toReplace ++" ++function s:ReplaceRightMostDelim(toReplace, replacor, str) ++ let toReplace = a:toReplace ++ let replacor = a:replacor ++ let lenToReplace = strlen(toReplace) ++ ++ "get the index of the last delim in str ++ let indxToReplace = s:LastIndexOfDelim(toReplace, a:str) ++ ++ "if there IS a delimiter in str, replace it and return the result ++ let line = a:str ++ if indxToReplace != -1 ++ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) ++ endif ++ return line ++endfunction ++ ++"FUNCTION: s:RestoreScreenState() {{{2 ++" ++"Sets the screen state back to what it was when s:SaveScreenState was last ++"called. ++" ++function s:RestoreScreenState() ++ if !exists("t:NERDComOldTopLine") || !exists("t:NERDComOldPos") ++ throw 'NERDCommenter exception: cannot restore screen' ++ endif ++ ++ call cursor(t:NERDComOldTopLine, 0) ++ normal zt ++ call setpos(".", t:NERDComOldPos) ++endfunction ++ ++" Function: s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns the index of the right most ++" char on all of these lines. ++" Args: ++" -countCommentedLines: 1 if lines that are commented are to be checked as ++" well. 0 otherwise ++" -countEmptyLines: 1 if empty lines are to be counted in the search ++" -topline: the top line to be checked ++" -bottomline: the bottom line to be checked ++function s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) ++ let rightMostIndx = -1 ++ ++ " go thru the block line by line updating rightMostIndx ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ ++ " get the next line and see if it is commentable, otherwise it doesnt ++ " count ++ let theLine = getline(currentLine) ++ if a:countEmptyLines || theLine !~ '^[ \t]*$' ++ ++ if a:countCommentedLines || (!s:IsCommented(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, theLine)) ++ ++ " update rightMostIndx if need be ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let lineLen = strlen(theLine) ++ if lineLen > rightMostIndx ++ let rightMostIndx = lineLen ++ endif ++ endif ++ endif ++ ++ " move on to the next line ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ return rightMostIndx ++endfunction ++ ++"FUNCTION: s:SaveScreenState() {{{2 ++"Saves the current cursor position in the current buffer and the window ++"scroll position ++function s:SaveScreenState() ++ let t:NERDComOldPos = getpos(".") ++ let t:NERDComOldTopLine = line("w0") ++endfunction ++ ++" Function: s:SwapOutterMultiPartDelimsForPlaceHolders(line) {{{2 ++" This function takes a line and swaps the outter most multi-part delims for ++" place holders ++" Args: ++" -line: the line to swap the delims in ++" ++function s:SwapOutterMultiPartDelimsForPlaceHolders(line) ++ " find out if the line is commented using normal delims and/or ++ " alternate ones ++ let isCommented = s:IsCommented(b:left, b:right, a:line) ++ let isCommentedAlt = s:IsCommented(b:leftAlt, b:rightAlt, a:line) ++ ++ let line2 = a:line ++ ++ "if the line is commented and there is a right delimiter, replace ++ "the delims with place-holders ++ if isCommented && s:Multipart() ++ let line2 = s:ReplaceDelims(b:left, b:right, g:NERDLPlace, g:NERDRPlace, a:line) ++ ++ "similarly if the line is commented with the alternative ++ "delimiters ++ elseif isCommentedAlt && s:AltMultipart() ++ let line2 = s:ReplaceDelims(b:leftAlt, b:rightAlt, g:NERDLPlace, g:NERDRPlace, a:line) ++ endif ++ ++ return line2 ++endfunction ++ ++" Function: s:SwapOutterPlaceHoldersForMultiPartDelims(line) {{{2 ++" This function takes a line and swaps the outtermost place holders for ++" multi-part delims ++" Args: ++" -line: the line to swap the delims in ++" ++function s:SwapOutterPlaceHoldersForMultiPartDelims(line) ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = b:left ++ let right = b:right ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ let right = b:rightAlt ++ endif ++ ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, a:line) ++ return line ++endfunction ++" Function: s:TabbedCol(line, col) {{{2 ++" Gets the col number for given line and existing col number. The new col ++" number is the col number when all leading spaces are converted to tabs ++" Args: ++" -line:the line to get the rel col for ++" -col: the abs col ++function s:TabbedCol(line, col) ++ let lineTruncated = strpart(a:line, 0, a:col) ++ let lineSpacesToTabs = substitute(lineTruncated, s:TabSpace(), '\t', 'g') ++ return strlen(lineSpacesToTabs) ++endfunction ++"FUNCTION: s:TabSpace() {{{2 ++"returns a string of spaces equal in length to &tabstop ++function s:TabSpace() ++ let tabSpace = "" ++ let spacesPerTab = &tabstop ++ while spacesPerTab > 0 ++ let tabSpace = tabSpace . " " ++ let spacesPerTab = spacesPerTab - 1 ++ endwhile ++ return tabSpace ++endfunction ++ ++" Function: s:UnEsc(str, escChar) {{{2 ++" This function removes all the escape chars from a string ++" Args: ++" -str: the string to remove esc chars from ++" -escChar: the escape char to be removed ++function s:UnEsc(str, escChar) ++ return substitute(a:str, a:escChar, "", "g") ++endfunction ++ ++" Function: s:UntabbedCol(line, col) {{{2 ++" Takes a line and a col and returns the absolute column of col taking into ++" account that a tab is worth 3 or 4 (or whatever) spaces. ++" Args: ++" -line:the line to get the abs col for ++" -col: the col that doesnt take into account tabs ++function s:UntabbedCol(line, col) ++ let lineTruncated = strpart(a:line, 0, a:col) ++ let lineTabsToSpaces = substitute(lineTruncated, '\t', s:TabSpace(), 'g') ++ return strlen(lineTabsToSpaces) ++endfunction ++" Section: Comment mapping setup {{{1 ++" =========================================================================== ++" This is where the mappings calls are made that set up the commenting key ++" mappings. ++ ++" set up the mapping to switch to/from alternative delimiters ++execute 'nnoremap ' . g:NERDAltComMap . ' :call SwitchToAlternativeDelimiters(1)' ++ ++" set up the mappings to comment out lines ++execute 'nnoremap ' . g:NERDComLineMap . ' :call NERDComment(0, "norm")' ++execute 'vnoremap ' . g:NERDComLineMap . ' :call NERDComment(1, "norm")' ++ ++" set up the mappings to do toggle comments ++execute 'nnoremap ' . g:NERDComLineToggleMap . ' :call NERDComment(0, "toggle")' ++execute 'vnoremap ' . g:NERDComLineToggleMap . ' :call NERDComment(1, "toggle")' ++ ++" set up the mapp to do minimal comments ++execute 'nnoremap ' . g:NERDComLineMinimalMap . ' :call NERDComment(0, "minimal")' ++execute 'vnoremap ' . g:NERDComLineMinimalMap . ' :call NERDComment(1, "minimal")' ++ ++" set up the mappings to comment out lines sexily ++execute 'nnoremap ' . g:NERDComLineSexyMap . ' :call NERDComment(0, "sexy")' ++execute 'vnoremap ' . g:NERDComLineSexyMap . ' :call NERDComment(1, "sexy")' ++ ++" set up the mappings to do invert comments ++execute 'nnoremap ' . g:NERDComLineInvertMap . ' :call NERDComment(0, "invert")' ++execute 'vnoremap ' . g:NERDComLineInvertMap . ' :call NERDComment(1, "invert")' ++ ++" set up the mappings to yank then comment out lines ++execute 'nmap ' . g:NERDComLineYankMap . ' :call NERDComment(0, "yank")' ++execute 'vmap ' . g:NERDComLineYankMap . ' :call NERDComment(1, "yank")' ++ ++" set up the mappings for left aligned comments ++execute 'nnoremap ' . g:NERDComAlignLeftMap . ' :call NERDComment(0, "alignLeft")' ++execute 'vnoremap ' . g:NERDComAlignLeftMap . ' :call NERDComment(1, "alignLeft")' ++ ++" set up the mappings for right aligned comments ++execute 'nnoremap ' . g:NERDComAlignRightMap . ' :call NERDComment(0, "alignRight")' ++execute 'vnoremap ' . g:NERDComAlignRightMap . ' :call NERDComment(1, "alignRight")' ++ ++" set up the mappings for left and right aligned comments ++execute 'nnoremap ' . g:NERDComAlignBothMap . ' :call NERDComment(0, "alignBoth")' ++execute 'vnoremap ' . g:NERDComAlignBothMap . ' :call NERDComment(1, "alignBoth")' ++ ++" set up the mappings to do nested comments ++execute 'nnoremap ' . g:NERDComLineNestMap . ' :call NERDComment(0, "nested")' ++execute 'vnoremap ' . g:NERDComLineNestMap . ' :call NERDComment(1, "nested")' ++ ++" set up the mapping to uncomment a line ++execute 'nnoremap ' . g:NERDUncomLineMap . ' :call NERDComment(0, "uncomment")' ++execute 'vnoremap ' . g:NERDUncomLineMap . ' :call NERDComment(1, "uncomment")' ++ ++" set up the mapping to comment out to the end of the line ++execute 'nnoremap ' . g:NERDComToEOLMap . ' :call NERDComment(0, "toEOL")' ++ ++" set up the mappings to append comments to the line ++execute 'nmap ' . g:NERDAppendComMap . ' :call NERDComment(0, "append")' ++ ++" set up the mappings to append comments to the line ++execute 'nmap ' . g:NERDPrependComMap . ' :call NERDComment(0, "prepend")' ++ ++" set up the mapping to insert comment delims at the cursor position in insert mode ++execute 'inoremap ' . g:NERDComInInsertMap . ' ' . ':call NERDComment(0, "insert")' ++ ++" Section: Menu item setup {{{1 ++" =========================================================================== ++"check if the user wants the menu to be displayed ++if g:NERDMenuMode != 0 ++ ++ let menuRoot = "" ++ if g:NERDMenuMode == 1 ++ let menuRoot = 'comment' ++ elseif g:NERDMenuMode == 2 ++ let menuRoot = '&comment' ++ elseif g:NERDMenuMode == 3 ++ let menuRoot = '&Plugin.&comment' ++ endif ++ ++ execute 'nmenu '. menuRoot .'.Comment' . escape(g:NERDComLineMap, '\') . ' :call NERDComment(0, "norm")' ++ execute 'vmenu '. menuRoot .'.Comment' . escape(g:NERDComLineMap, '\') . ' :call NERDComment(1, "norm")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Toggle' . escape(g:NERDComLineToggleMap, '\') . ' :call NERDComment(0, "toggle")' ++ execute 'vmenu '. menuRoot .'.Comment\ Toggle' . escape(g:NERDComLineToggleMap, '\') . ' :call NERDComment(1, "toggle")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Minimal' . escape(g:NERDComLineMinimalMap, '\') . ' :call NERDComment(0, "minimal")' ++ execute 'vmenu '. menuRoot .'.Comment\ Minimal' . escape(g:NERDComLineMinimalMap, '\') . ' :call NERDComment(1, "minimal")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Nested' . escape(g:NERDComLineNestMap, '\') . ' :call NERDComment(0, "nested")' ++ execute 'vmenu '. menuRoot .'.Comment\ Nested' . escape(g:NERDComLineNestMap, '\') . ' :call NERDComment(1, "nested")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ To\ EOL' . escape(g:NERDComToEOLMap, '\') . ' :call NERDComment(0, "toEOL")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Invert' . escape(g:NERDComLineInvertMap, '\') . ' :call NERDComment(0,"invert")' ++ execute 'vmenu '. menuRoot .'.Comment\ Invert' . escape(g:NERDComLineInvertMap, '\') . ' :call NERDComment(1,"invert")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Sexily' . escape(g:NERDComLineSexyMap, '\') . ' :call NERDComment(0,"sexy")' ++ execute 'vmenu '. menuRoot .'.Comment\ Sexily' . escape(g:NERDComLineSexyMap, '\') . ' :call NERDComment(1,"sexy")' ++ ++ execute 'nmenu '. menuRoot .'.Yank\ line(s)\ then\ comment' . escape(g:NERDComLineYankMap, '\') . ' "0Y' . g:NERDComLineMap ++ execute 'vmenu '. menuRoot .'.Yank\ line(s)\ then\ comment' . escape(g:NERDComLineYankMap, '\') . ' "0ygv' . g:NERDComLineMap ++ ++ execute 'nmenu '. menuRoot .'.Append\ Comment\ to\ Line' . escape(g:NERDAppendComMap, '\') . ' :call NERDComment(0, "append")' ++ execute 'nmenu '. menuRoot .'.Prepend\ Comment\ to\ Line' . escape(g:NERDPrependComMap, '\') . ' :call NERDComment(0, "prepend")' ++ ++ execute 'menu '. menuRoot .'.-Sep- :' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Left\ (nested)' . escape(g:NERDComAlignLeftMap, '\') . ' :call NERDComment(0, "alignLeft")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Left\ (nested)' . escape(g:NERDComAlignLeftMap, '\') . ' :call NERDComment(1, "alignLeft")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Right\ (nested)' . escape(g:NERDComAlignRightMap, '\') . ' :call NERDComment(0, "alignRight")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Right\ (nested)' . escape(g:NERDComAlignRightMap, '\') . ' :call NERDComment(1, "alignRight")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Both\ (nested)' . escape(g:NERDComAlignBothMap, '\') . ' :call NERDComment(0, "alignBoth")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Both\ (nested)' . escape(g:NERDComAlignBothMap, '\') . ' :call NERDComment(1, "alignBoth")' ++ ++ execute 'menu '. menuRoot .'.-Sep2- :' ++ ++ execute 'menu '. menuRoot .'.Uncomment' . escape(g:NERDUncomLineMap, '\') . ' :call NERDComment(0, "uncomment")' ++ execute 'vmenu ' . menuRoot.'.Uncomment' . escape(g:NERDUncomLineMap, '\') . ' :call NERDComment(1, "uncomment")' ++ ++ execute 'menu '. menuRoot .'.-Sep3- :' ++ ++ execute 'nmenu '. menuRoot .'.Use\ Alternative\ Delimiters' . escape(g:NERDAltComMap, '\') . ' :call SwitchToAlternativeDelimiters(1)' ++ ++ ++ execute 'imenu '. menuRoot .'.Insert\ Delims' . escape(g:NERDComInInsertMap, '\') . ' :call NERDComment(0, "insert")' ++ ++ execute 'menu '. menuRoot .'.-Sep4- :' ++ ++ execute 'menu '. menuRoot .'.Help:help\ NERDCommenterContents :help NERDCommenterContents' ++endif ++ ++" Section: Doc installation call {{{1 ++silent call s:InstallDocumentation(expand(':p'), s:NERD_commenter_version) ++ ++finish ++"============================================================================= ++" Section: The help file {{{1 ++" Title {{{2 ++" ============================================================================ ++=== START_DOC ++*NERD_commenter.txt* Plugin for commenting code #version# ++ ++ ++ NERD COMMENTER REFERENCE MANUAL~ ++ ++ ++ ++ ++ ++============================================================================== ++CONTENTS {{{2 *NERDCommenterContents* ++ ++ 1.Intro...................................|NERDCommenter| ++ 2.Functionality provided..................|NERDComFunctionality| ++ 2.1 Functionality Summary.............|NERDComFunctionalitySummary| ++ 2.2 Functionality Details.............|NERDComFunctionalityDetails| ++ 2.2.1 Comment map.................|NERDComComment| ++ 2.2.2 Nested comment map..........|NERDComNestedComment| ++ 2.2.3 Toggle comment map..........|NERDComToggleComment| ++ 2.2.4 Minimal comment map.........|NERDComMinimalComment| ++ 2.2.5 Invert comment map..........|NERDComInvertComment| ++ 2.2.6 Sexy comment map............|NERDComSexyComment| ++ 2.2.7 Yank comment map............|NERDComYankComment| ++ 2.2.8 Comment to EOL map..........|NERDComEOLComment| ++ 2.2.9 Append com to line map......|NERDComAppendComment| ++ 2.2.10 Prepend com to line map....|NERDComPrependComment| ++ 2.2.11 Insert comment map.........|NERDComInsertComment| ++ 2.2.12 Use alternate delims map...|NERDComAltDelim| ++ 2.2.13 Comment aligned maps.......|NERDComAlignedComment| ++ 2.2.14 Uncomment line map.........|NERDComUncommentLine| ++ 2.3 Supported filetypes...............|NERDComFiletypes| ++ 2.4 Sexy Comments.....................|NERDComSexyComments| ++ 2.5 The NERDComment function..........|NERDComNERDComment| ++ 3.Options.................................|NERDComOptions| ++ 3.1 Options summary...................|NERDComOptionsSummary| ++ 3.2 Options details...................|NERDComOptionsDetails| ++ 3.3 Default delimiter Options.........|NERDComDefaultDelims| ++ 3.4 Key mapping Options...............|NERDComMappings| ++ 4.Issues with the script..................|NERDComIssues| ++ 4.1 Delimiter detection heuristics....|NERDComHeuristics| ++ 4.2 Nesting issues....................|NERDComNesting| ++ 5.The author..............................|NERDComAuthor| ++ 6.TODO list...............................|NERDComTodo| ++ 7.Changelog...............................|NERDComChangelog| ++ 8.Credits.................................|NERDComCredits| ++ ++============================================================================== ++1. Intro {{{2 *NERDCommenter* ++ ++The NERD commenter provides many different commenting operations and styles ++which may be invoked via key mappings and a commenting menu. These operations ++are available for most filetypes. ++ ++There are also options available that allow you to tweak the commenting engine ++to you taste. ++ ++============================================================================== ++2. Functionality provided {{{2 *NERDComFunctionality* ++ ++------------------------------------------------------------------------------ ++2.1 Functionality summary {{{3 *NERDComFunctionalitySummary* ++ ++The following key mappings are provided by default (there is also a menu ++provided that contains menu items corresponding to all the below mappings): ++ ++Most of the following mappings are for normal/visual mode only. The ++|NERDComInsertComment| mapping is for insert mode only. ++ ++[count],cc |NERDComComment| ++Comments out the current line or text selected in visual mode. ++ ++ ++[count],cn |NERDComNestedComment| ++Same as |NERDComComment| but forces nesting. ++ ++ ++[count],c |NERDComToggleComment| ++Toggles the comment state of the selected line(s). If the topmost selected ++line is commented, all selected lines are uncommented and vice versa. ++ ++ ++[count],cm |NERDComMinimalComment| ++Comments the given lines using only one set of multipart delimiters if ++possible. ++ ++ ++[count],ci |NERDComInvertComment| ++Toggles the comment state of the selected line(s) individually. Each selected ++line that is commented is uncommented and vice versa. ++ ++ ++[count],cs |NERDComSexyComment| ++Comments out the selected lines ``sexually'' ++ ++ ++[count],cy |NERDComYankComment| ++Same as |NERDComComment| except that the commented line(s) are yanked ++before commenting. ++ ++ ++,c$ |NERDComEOLComment| ++Comments the current line from the cursor to the end of line. ++ ++ ++,cA |NERDComAppendComment| ++Adds comment delimiters to the end of line and goes into insert mode between ++them. ++ ++ ++,cI |NERDComPrependComment| ++Adds comment delimiters to the start of line and goes into insert mode between ++them. ++ ++ ++ |NERDComInsertComment| ++Adds comment delimiters at the current cursor position and inserts between. ++ ++ ++,ca |NERDComAltDelim| ++Switches to the alternative set of delimiters. ++ ++ ++[count],cl ++[count],cr ++[count],cb |NERDComAlignedComment| ++Same as |NERDComComment| except that the delimiters are aligned down the ++left side (,cl), the right side (,cr) or both sides ++(,cb). ++ ++ ++[count],cu |NERDComUncommentLine| ++Uncomments the selected line(s). ++ ++------------------------------------------------------------------------------ ++2.2 Functionality details {{{3 *NERDComFunctionalityDetails* ++ ++------------------------------------------------------------------------------ ++2.2.1 Comment map *NERDComComment* ++ ++Default mapping: [count],cc ++Change the mapping with: NERDComLineMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++ ++Comments out the current line. If multiple lines are selected in visual-line ++mode, they are all commented out. If some text is selected in visual or ++visual-block mode then the script will try to comment out the exact text that ++is selected using multi-part delimiters if they are available. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.2 Nested comment map *NERDComNestedComment* ++ ++Default mapping: [count],cn ++Change the mapping with: NERDComLineNestMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++Performs nested commenting. Works the same as ,cc except that if a ++line is already commented then it will be commented again. ++ ++If |NERDUsePlaceHolders| is set then the previous comment delimiters will ++be replaced by place-holder delimiters if needed. Otherwise the nested ++comment will only be added if the current commenting delimiters have no right ++delimiter (to avoid syntax errors) ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDDefaultNesting| ++ ++------------------------------------------------------------------------------ ++2.2.3 Toggle comment map *NERDComToggleComment* ++ ++Default mapping: [count],c ++Change the mapping with: NERDComLineToggleMap. ++Applicable modes: normal visual-line. ++ ++Toggles commenting of the lines selected. The behaviour of this mapping ++depends on whether the first line selected is commented or not. If so, all ++selected lines are uncommented and vice versa. ++ ++With this mapping, a line is only considered to be commented if it starts with ++a left delimiter. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.4 Minimal comment map *NERDComMinimalComment* ++ ++Default mapping: [count],cm ++Change the mapping with: NERDComLineMinimalMap ++Applicable modes: normal visual-line. ++ ++Comments the selected lines using one set of multipart delimiters if possible. ++ ++For example: if you are programming in c and you select 5 lines and press ++,cm then a '/*' will be placed at the start of the top line and a '*/' ++will be placed at the end of the last line. ++ ++Sets of multipart comment delimiters that are between the top and bottom ++selected lines are replaced with place holders (see |NERDLPlace|) if ++|NERDUsePlaceHolders| is set for the current filetype. If it is not, then ++the comment will be aborted if place holders are required to prevent illegal ++syntax. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.5 Invert comment map *NERDComInvertComment* ++ ++Default mapping: ,ci ++Change the mapping with: NERDComLineInvertMap. ++Applicable modes: normal visual-line. ++ ++Inverts the commented state of each selected line. If the a selected line is ++commented then it is uncommented and vice versa. Each line is examined and ++commented/uncommented individually. ++ ++With this mapping, a line is only considered to be commented if it starts with ++a left delimiter. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.6 Sexy comment map *NERDComSexyComment* ++ ++Default mapping: [count],cs ++Change the mapping with: NERDComLineSexyMap ++Applicable modes: normal, visual-line. ++ ++Comments the selected line(s) ``sexily''... see |NERDComSexyComments| for ++a description of what sexy comments are. Can only be done on filetypes for ++which there is at least one set of multipart comment delimiters specified. ++ ++Sexy comments cannot be nested and lines inside a sexy comment cannot be ++commented again. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDCompactSexyComs| ++ ++------------------------------------------------------------------------------ ++2.2.7 Yank comment map *NERDComYankComment* ++ ++Default mapping: [count],cy ++Change the mapping with: NERDComLineYankMap ++Applicable modes: normal visual visual-line visual-block. ++ ++Same as ,cc except that it yanks the line(s) that are commented first. ++ ++------------------------------------------------------------------------------ ++2.2.8 Comment to EOL map *NERDComEOLComment* ++ ++Default mapping: ,c$ ++Change the mapping with: NERDComToEOLMap ++Applicable modes: normal. ++ ++Comments the current line from the current cursor position up to the end of ++the line. ++ ++------------------------------------------------------------------------------ ++2.2.9 Append com to line map *NERDComAppendComment* ++ ++Default mapping: ,cA ++Change the mapping with: NERDAppendComMap. ++Applicable modes: normal. ++ ++Appends comment delimiters to the end of the current line and goes ++to insert mode between the new delimiters. ++ ++------------------------------------------------------------------------------ ++2.2.10 Prepend com to line map *NERDComPrependComment* ++ ++Default mapping: ,cI ++Change the mapping with: NERDPrependComMap. ++Applicable modes: normal. ++ ++Prepends comment delimiters to the start of the current line and goes to ++insert mode between the new delimiters. ++ ++------------------------------------------------------------------------------ ++2.2.11 Insert comment map *NERDComInsertComment* ++ ++Default mapping: ++Change the mapping with: NERDComInInsertMap. ++Applicable modes: insert. ++ ++Adds comment delimiters at the current cursor position and inserts ++between them. ++ ++------------------------------------------------------------------------------ ++2.2.12 Use alternate delims map *NERDComAltDelim* ++ ++Default mapping: ,ca ++Change the mapping with: NERDAltComMap ++Applicable modes: normal. ++ ++Changes to the alternative commenting style if one is available. For example, ++if the user is editing a c++ file using // comments and they hit ,ca ++then they will be switched over to /**/ comments. ++ ++See also |NERDComDefaultDelims| ++ ++------------------------------------------------------------------------------ ++2.2.13 Comment aligned maps *NERDComAlignedComment* ++ ++Default mappings: [count],cl [count],cr [count],cb ++Change the mappings with: NERDComAlignLeftMap, NERDComAlignRightMap and ++NERDComAlignBothMap. ++Applicable modes: normal visual-line. ++ ++Same as ,cc except that the comment delimiters are aligned on the left ++side, right side or both sides respectively. These comments are always nested ++if the line(s) are already commented. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.14 Uncomment line map *NERDComUncommentLine* ++ ++Default mapping: [count],cu ++Change the mapping with: NERDUncomLineMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++Uncomments the current line. If multiple lines are selected in ++visual mode then they are all uncommented. ++ ++When uncommenting, if the line contains multiple sets of delimiters then the ++``outtermost'' pair of delimiters will be removed. ++ ++The script uses a set of heurisics to distinguish ``real'' delimiters from ++``fake'' ones when uncommenting. See |NERDComIssues| for details. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDRemoveAltComs| ++|NERDRemoveExtraSpaces| ++ ++------------------------------------------------------------------------------ ++2.3 Supported filetypes {{{3 *NERDComFiletypes* ++ ++Filetypes that can be commented by this plugin: ++abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asn ++aspvbs atlas autohotkey autoit automake ave awk basic b bc bdf bib bindzone ++bst btm caos catalog c cfg cg ch changelog cl clean clipper cmake conf config ++context cpp crontab cs csc csp css cterm cupl csv cvs dcl debchangelog ++debcontrol debsources def diff django docbk dns dosbatch dosini dot dracula ++dsl dtd dtml dylan ecd eiffel elf elmfilt erlang eruby eterm expect exports ++fetchmail fgl focexec form fortran foxpro fstab fvwm fx gdb gdmo geek ++gentoo-package-keywords' gentoo-package-mask' gentoo-package-use' gnuplot ++gtkrc haskell hb h help hercules hog html htmldjango htmlos ia64 icon idlang ++idl indent inform inittab ishd iss ist jam java javascript jess jgraph ++jproperties jproperties jsp kconfig kix kscript lace lex lftp lifelines lilo ++lisp lite lotos lout lprolog lscript lss lua lynx m4 mail make maple masm ++master matlab mel mf mib mma model moduala. modula2 modula3 monk mush muttrc ++named nasm nastran natural ncf netdict netrw nqc nroff nsis objc ocaml occam ++omlet omnimark openroad opl ora otl ox pascal passwd pcap pccts perl pfmain ++php phtml pic pike pilrc pine plaintex plm plsql po postscr pov povini ppd ++ppwiz procmail progress prolog psf ptcap python python qf radiance ratpoison r ++rc readline rebol registry remind rexx robots rpl rtf ruby sa samba sas sass ++sather scheme scilab screen scsh sdl sed selectbuf sgml sgmldecl sgmllnx sh ++sicad simula sinda skill slang sl slrnrc sm smarty smil smith sml snnsnet ++snnspat snnsres snobol4 spec specman spice sql sqlforms sqlj sqr squid st stp ++strace svn systemverilog tads taglist tags tak tasm tcl terminfo tex text ++plaintex texinfo texmf tf tidy tli trasys tsalt tsscl tssgm uc uil vb verilog ++verilog_systemverilog vgrindefs vhdl vim viminfo virata vo_base vrml vsejcl ++webmacro wget winbatch wml wvdial xdefaults xf86conf xhtml xkb xmath xml ++xmodmap xpm2 xpm xslt yacc yaml z8a ++ ++If a language is not in the list of hardcoded supported filetypes then the ++&commentstring vim option is used. ++ ++------------------------------------------------------------------------------ ++2.4 Sexy Comments {{{3 *NERDComSexyComments* ++These are comments that use one set of multipart comment delimiters as well as ++one other marker symbol. For example: > ++ /* ++ * This is a c style sexy comment ++ * So there! ++ */ ++ ++ /* This is a c style sexy comment ++ * So there! ++ * But this one is ``compact'' style */ ++< ++Here the multipart delimiters are /* and */ and the marker is *. The NERD ++commenter is capable of adding and removing comments of this type. ++ ++------------------------------------------------------------------------------ ++2.5 The NERDComment function {{{3 *NERDComNERDComment* ++ ++All of the NERD commenter mappings and menu items invoke a single function ++which delegates the commenting work to other functions. This function is ++public and has the prototype: > ++ function! NERDComment(isVisual, type) ++< ++The arguments to this function are simple: ++ - isVisual: if you wish to do any kind of visual comment then set this to ++ 1 and the function will use the '< and '> marks to find the comment ++ boundries. If set to 0 then the function will operate on the current ++ line. ++ - type: is used to specify what type of commenting operation is to be ++ performed, and it can be one of the following: 'sexy', 'invert', ++ 'minimal', 'toggle', 'alignLeft', 'alignRight', 'alignBoth', 'norm', ++ 'nested', 'toEOL', 'prepend', 'append', 'insert', 'uncomment', 'yank' ++ ++For example, if you typed > ++ :call NERDComment(1, 'sexy') ++< ++then the script would do a sexy comment on the last visual selection. ++ ++ ++============================================================================== ++3. Options {{{2 *NERDComOptions* ++ ++------------------------------------------------------------------------------ ++3.1 Options summary *NERDComOptionsSummary* ++ ++|loaded_nerd_comments| Turns off the script. ++|NERDAllowAnyVisualDelims| Allows multipart alternative delims to ++ be used when commenting in ++ visual/visual-block mode. ++|NERDBlockComIgnoreEmpty| Forces right delims to be placed when ++ doing visual-block comments. ++|NERDCommentWholeLinesInVMode| Changes behaviour of visual comments. ++|NERDDefaultNesting| Tells the script to use nested comments ++ by default. ++|NERDMenuMode| Specifies how the NERD commenter menu ++ will appear (if at all). ++|NERDLPlace| Specifies what to use as the left ++ delimiter placeholder when nesting ++ comments. ++|NERDMapleader| Specifies what all the commenting key ++ mappings will begin with. ++|NERDUsePlaceHolders| Specifies which filetypes may use ++ placeholders when nesting comments. ++|NERDRemoveAltComs| Tells the script whether to remove ++ alternative comment delimiters when ++ uncommenting. ++|NERDRemoveExtraSpaces| Tells the script to always remove the ++ extra spaces when uncommenting ++ (regardless of whether NERDSpaceDelims ++ is set) ++|NERDRPlace| Specifies what to use as the right ++ delimiter placeholder when nesting ++ comments. ++|NERDShutUp| Stops "Unknown filetype" output from the ++ script ++|NERDSpaceDelims| Specifies whether to add extra spaces ++ around delimiters when commenting, and ++ whether to remove them when ++ uncommenting. ++|NERDCompactSexyComs| Specifies whether to use the compact ++ style sexy comments. ++ ++------------------------------------------------------------------------------ ++3.3 Options details *NERDComOptionsDetails* ++ ++To enable any of the below options you should put the given line in your ++~/.vimrc ++ ++ *loaded_nerd_comments* ++If this script is driving you insane you can turn it off by setting this ++option > ++ let loaded_nerd_comments=1 ++< ++------------------------------------------------------------------------------ ++ *NERDAllowAnyVisualDelims* ++Values: 0 or 1. ++Default: 1. ++ ++If set to 1 then, when doing a visual or visual-block comment (but not a ++visual-line comment), the script will choose the right delimiters to use for ++the comment. This means either using the current delimiters if they are ++multipart or using the alternative delimiters if THEY are multipart. For ++example if we are editing the following java code: > ++ float foo = 1221; ++ float bar = 324; ++ System.out.println(foo * bar); ++< ++If we are using // comments and select the "foo" and "bar" in visual-block ++mode, as shown left below (where '|'s are used to represent the visual-block ++boundary), and comment it then the script will use the alternative delims as ++shown on the right: > ++ ++ float |foo| = 1221; float /*foo*/ = 1221; ++ float |bar| = 324; float /*bar*/ = 324; ++ System.out.println(foo * bar); System.out.println(foo * bar); ++< ++------------------------------------------------------------------------------ ++ *NERDBlockComIgnoreEmpty* ++Values: 0 or 1. ++Default: 1. ++ ++This option affects visual-block mode commenting. If this option is turned ++on, lines that begin outside the right boundary of the selection block will be ++ignored. ++ ++For example, if you are commenting this chunk of c code in visual-block mode ++(where the '|'s are used to represent the visual-block boundary) > ++ #include ++ #include ++ #include ++ |int| main(){ ++ | | printf("SUCK THIS\n"); ++ | | while(1){ ++ | | fork(); ++ | | } ++ |} | ++< ++If NERDBlockComIgnoreEmpty=0 then this code will become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ /* */ printf("SUCK THIS\n"); ++ /* */ while(1){ ++ /* */ fork(); ++ /* */ } ++ /*} */ ++< ++Otherwise, the code block would become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ printf("SUCK THIS\n"); ++ while(1){ ++ fork(); ++ } ++ /*} */ ++< ++------------------------------------------------------------------------------ ++ *NERDCommentWholeLinesInVMode* ++Values: 0, 1 or 2. ++Default: 0. ++ ++By default the script tries to comment out exactly what is selected in visual ++mode (v). For example if you select and comment the following c code (using | ++to represent the visual boundary): > ++ in|t foo = 3; ++ int bar =| 9; ++ int baz = foo + bar; ++< ++This will result in: > ++ in/*t foo = 3;*/ ++ /*int bar =*/ 9; ++ int baz = foo + bar; ++< ++But some people prefer it if the whole lines are commented like: > ++ /*int foo = 3;*/ ++ /*int bar = 9;*/ ++ int baz = foo + bar; ++< ++If you prefer the second option then stick this line in your vimrc: > ++ let NERDCommentWholeLinesInVMode=1 ++< ++ ++If the filetype you are editing only has no multipart delimiters (for example ++a shell script) and you hadnt set this option then the above would become > ++ in#t foo = 3; ++ #int bar = 9; ++< ++(where # is the comment delimiter) as this is the closest the script can ++come to commenting out exactly what was selected. If you prefer for whole ++lines to be commented out when there is no multipart delimiters but the EXACT ++text that was selected to be commented out if there IS multipart delimiters ++then stick the following line in your vimrc: > ++ let NERDCommentWholeLinesInVMode=2 ++< ++ ++Note that this option does not affect the behaviour of |visual-block| mode. ++ ++------------------------------------------------------------------------------ ++ *NERDRemoveAltComs* ++Values: 0 or 1. ++Default: 1. ++ ++When uncommenting a line (for a filetype with an alternative commenting style) ++this option tells the script whether to look for, and remove, comments ++delimiters of the alternative style. ++ ++For example, if you are editing a c++ file using // style comments and you go ++,cu on this line: > ++ /* This is a c++ comment baby! */ ++< ++It will not be uncommented if the NERDRemoveAltComs is set to 0. ++ ++------------------------------------------------------------------------------ ++ *NERDRemoveExtraSpaces* ++Values: 0 or 1. ++Default: 1. ++ ++By default, the NERD commenter will remove spaces around comment delimiters if ++either: ++1. |NERDSpaceDelims| is set to 1. ++2. NERDRemoveExtraSpaces is set to 1. ++ ++This means that if we have the following lines in a c code file: > ++ /* int foo = 5; */ ++ /* int bar = 10; */ ++ int baz = foo + bar ++< ++If either of the above conditions hold then if these lines are uncommented ++they will become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++Otherwise they would become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++If you want the spaces to be removed only if |NERDSpaceDelims| is set then ++set NERDRemoveExtraSpaces to 0. ++ ++------------------------------------------------------------------------------ ++ *NERDLPlace* ++ *NERDRPlace* ++Values: arbitrary string. ++Default: ++ NERDLPlace: "[>" ++ NERDRPlace: "<]" ++ ++These options are used to control the strings used as place-holder delimiters. ++Place holder delimiters are used when performing nested commenting when the ++filetype supports commenting styles with both left and right delimiters. ++To set these options use lines like: > ++ let NERDLPlace="FOO" ++ let NERDRPlace="BAR" ++< ++Following the above example, if we have line of c code: > ++ /* int horse */ ++< ++and we comment it with ,cn it will be changed to: > ++ /*FOO int horse BAR*/ ++< ++When we uncomment this line it will go back to what it was. ++ ++------------------------------------------------------------------------------ ++ *NERDMapleader* ++Values: arbitrary string. ++Default: \c ++ ++NERDMapleader is used to specify what all the NERD commenter key mappings ++begin with. ++ ++The default key mappings will look like this: > ++ \cc ++ \cu ++ \ca ++ \ci ++ \cs ++ ... ++< ++However, if this line: > ++ let NERDMapleader = ',x' ++< ++were present in your vimrc then the default mappings would look like this: > ++ ,xc ++ ,xu ++ ,xa ++ ,xi ++ ,xs ++ ... ++< ++This option only affects the mappings that have not been explicitly set ++manually (see |NERDComMappings|). ++ ++------------------------------------------------------------------------------ ++ *NERDMenuMode* ++Values: 0, 1, 2, 3. ++Default: 3 ++ ++This option can take 4 values: ++ "0": Turns the menu off. ++ "1": Turns the 'comment' menu on with no menu shortcut. ++ "2": Turns the 'comment 'menu on with -c as the shortcut. ++ "3": Turns the 'Plugin -> comment' menu on with -c as the shortcut. ++ ++------------------------------------------------------------------------------ ++ *NERDUsePlaceHolders* ++Values: 0 or 1. ++Default 1. ++ ++This option is used to specify whether place-holder delimiters should be used ++when adding nested comments. ++ ++------------------------------------------------------------------------------ ++ *NERDShutUp* ++Values: 0 or 1. ++Default 1. ++ ++This option is used to prevent the script from echoing "Unknown filetype" ++messages. Stick this line in your vimrc: > ++ let NERDShutUp=1 ++< ++------------------------------------------------------------------------------ ++ *NERDSpaceDelims* ++Values: 0 or 1. ++Default 0. ++ ++Some people prefer a space after the left delimiter and before the right ++delimiter like this: > ++ /* int foo=2; */ ++< ++as opposed to this: > ++ /*int foo=2;*/ ++< ++If you want spaces to be added then set NERDSpaceDelims to 1 in your vimrc. ++ ++See also |NERDRemoveExtraSpaces|. ++ ++------------------------------------------------------------------------------ ++ *NERDCompactSexyComs* ++Values: 0 or 1. ++Default 0. ++ ++Some people may want their sexy comments to be like this: > ++ /* Hi There! ++ * This is a sexy comment ++ * in c */ ++< ++As opposed to like this: > ++ /* ++ * Hi There! ++ * This is a sexy comment ++ * in c ++ */ ++< ++If this option is set to 1 then the top style will be used. ++ ++------------------------------------------------------------------------------ ++ *NERDDefaultNesting* ++Values: 0 or 1. ++Default 0. ++ ++When this option is set to 1, comments are nested automatically. That is, if ++you hit ,cc on a line that is already commented it will be commented ++again ++ ++------------------------------------------------------------------------------ ++3.3 Default delimiter customisation *NERDComDefaultDelims* ++ ++If you want the NERD commenter to use the alternative delimiters for a ++specific filetype by default then put a line of this form into your vimrc: > ++ let NERD_<&filetype>_alt_style=1 ++< ++Example: java uses // style comments by default, but you want it to default to ++/* */ style comments instead. You would put this line in your vimrc: > ++ let NERD_java_alt_style=1 ++< ++ ++See |NERDComAltDelim| for switching commenting styles at runtime. ++ ++------------------------------------------------------------------------------ ++3.4 Key mapping customisation *NERDComMappings* ++ ++These options are used to override the default keys that are used for the ++commenting mappings. Their values must be set to strings. As an example: if ++you wanted to use the mapping ,foo to uncomment lines of code then ++you would place this line in your vimrc > ++ let NERDUncomLineMap=",foo" ++< ++Check out |NERDComFunctionality| for details about what the following ++mappings do. ++ ++Default Mapping Option to override~ ++ ++,ca NERDAltComMap ++,ce NERDAppendComMap ++,cl NERDComAlignLeftMap ++,cb NERDComAlignBothMap ++,cr NERDComAlignRightMap ++ NERDComInInsertMap ++,ci NERDComLineInvertMap ++,cc NERDComLineMap ++,cn NERDComLineNestMap ++,cs NERDComLineSexyMap ++,c NERDComLineToggleMap ++,cm NERDComLineMinimalMap ++,c$ NERDComToEOLMap ++,cy NERDComLineYankMap ++,cu NERDUncomLineMap ++ ++============================================================================== ++4. Issues with the script{{{2 *NERDComIssues* ++ ++ ++------------------------------------------------------------------------------ ++4.1 Delimiter detection heuristics *NERDComHeuristics* ++ ++Heuristics are used to distinguish the real comment delimiters ++ ++Because we have comment mappings that place delimiters in the middle of lines, ++removing comment delimiters is a bit tricky. This is because if comment ++delimiters appear in a line doesnt mean they really ARE delimiters. For ++example, Java uses // comments but the line > ++ System.out.println("//"); ++< ++clearly contains no real comment delimiters. ++ ++To distinguish between ``real'' comment delimiters and ``fake'' ones we use a ++set of heuristics. For example, one such heuristic states that any comment ++delimiter that has an odd number of non-escaped " characters both preceding ++and following it on the line is not a comment because it is probably part of a ++string. These heuristics, while usually pretty accurate, will not work for all ++cases. ++ ++------------------------------------------------------------------------------ ++4.2 Nesting issues *NERDComNesting* ++ ++If we have some line of code like this: > ++ /*int foo */ = /*5 + 9;*/ ++< ++This will not be uncommented legally. The NERD commenter will remove the ++"outter most" delimiters so the line will become: > ++ int foo */ = /*5 + 9; ++< ++which almost certainly will not be what you want. Nested sets of comments will ++uncomment fine though. Eg: > ++ /*int/* foo =*/ 5 + 9;*/ ++< ++will become: > ++ int/* foo =*/ 5 + 9; ++< ++(Note that in the above examples I have deliberately not used place holders ++for simplicity) ++ ++============================================================================== ++6. The author {{{2 *NERDComAuthor* ++ ++The author of the NERD commenter is Martyzillatron --- the half robot, half ++dinosaur bastard son of Megatron and Godzilla. He enjoys destroying ++metropolises and eating tourist busses. ++ ++Drop him a line at martin_grenfell at msn.com. He would love to hear from you. ++its a lonely life being the worlds premier terror machine. How would you feel ++if your face looked like a toaster and a t-rex put together? :( ++ ++============================================================================== ++7. TODO list {{{2 *NERDComTodo* ++ ++Uncommenting of minimal comments needs to be more robust. Currently it is easy ++to get illegal syntax when uncommenting them. ++ ++ ++ ++============================================================================== ++8. Changelog {{{2 *NERDComChangelog* ++ ++2.1.4 ++ - added support for the ahk filetype. Cheers to Don Hatlestad for the ++ email. ++ - added support for desktop and xsd filetypes. Thanks to Christophe Benz. ++ - added dummy support for Rails-log ++ - fixed a bunch of bugs in the comment delimiter setup process, thanks to ++ Cheng Fang for the email :D ++ - hardcore refactoring and removal of seldomly used, overly-complex ++ functionality. ++ - the script now requires vim 7 ++2.1.3 ++ - fixed numerous bugs that were causing tabs to permanently be converted ++ to spaces, even if noexpandtab was set. Thanks to Heptite on #vim for ++ working with me to track them down :) ++ - added dummy support for "lookupfile". Thanks to David Fishburn for the ++ email. ++ - added support for "rst", thanks to Niels Aan de Brugh for the email. ++ ++2.1.2 ++ - added support for the vera and ldif filetypes. Thanks to Normandie ++ Azucena and Florian Apolloner for the emails. ++ ++2.1.1 ++ - added dummy support for SVNcommitlog and vcscommit. Thanks to John ++ O'Shea for the email. ++ - added support for Groovy. Thanks to Jason Mills for the email. ++2.1.0 ++ - now the script resets the delimiters when the filetype of the buffer ++ changes (thanks to James Hales for the patch) ++ - added formal support/doc for prepending a count to many of the ++ commenting maps so you can go, eg, 5,cc to comment 5 lines from normal ++ mode. Thanks again to James Hales for the patch. ++ - added support for the "gams" filetype that Jorge Rodrigues created. ++ - added support for the "objc" filetype, thanks to Rainer Müller for the ++ email. ++ - added support for the "sass" filetype that Dmitry Ilyashevich created. ++ ++2.0.7 ++ - Added support for eclass and ebuild filetypes. Thanks to Alex Tarkovsky ++ for the email. ++ ++2.0.6 ++ - Changed the default setting of NERDMapleader to ",c", meaning all the ++ maps now start with ,c instead of \c. This is to stop a major mapping ++ clash with the vcscommand plugin. Anyone wanting to keep the \c map ++ leader should read :help NERDMapleader. ++ - Added support for debcontrol and dummy support for debchangelog ++ filetypes, thanks to Stefano Zacchiroli for the email. ++ - Made it so that the NERDShutUp option now only controls the "Pleeease ++ email the delimiters..." requests. It no longer affects the general ++ output of the script. ++ - Simplified the names of the help tags. ++ ++2.0.5 ++ - Added support for autoit, autohotkey and docbk filetypes (thanks to ++ Michael Böhler) ++ - Added support for cmake (thanks to Aaron Small) ++ - Added support for htmldjango and django filetypes (thanks to Ramiro ++ Morales) ++ - Improved the delimiters for eruby again ++ - Applied a patch from Seth Mason to fix some pathing issues with the help ++ file installation. ++ ++2.0.4 ++ - Added support for verilog_systemverilog and systemverilog filetypes ++ (Thanks to Alexey for the email) ++ - Added support for fstab, thanks to Lizendir for the email. ++ - Added support for the smarty filetype. ++ - Improved the delimiters for eruby. ++ - Added dummy support for changelog filetype. ++ ++2.0.3 ++ - Added dummy support for the csv filetype (thx to Mark Woodward for the ++ email) ++ - Added dummy support for vo_base and otl filetypes (thanks to fREW for ++ the email) ++ ++2.0.2: ++ - Minor bug fix that was stopping nested comments from working ++ ++2.0.1: ++ - Fixed the visual bell for the |NERDComToEOLMap| map. ++ - Added another possible value to the NERDMenuMode option which causes the ++ menu to be displayed under 'Plugin -> Comment'. See :h NERDMenuMode. ++ This new menu mode is now the default. ++ - Added support for the occam filetype (thanks to Anders for emailing me) ++ - Made the main commenting function (NERDComment) available outside the ++ script. ++ - bug fixes and refactoring ++ ++2.0.0: ++ - NOTE: renamed the script to NERD_commenter.vim. When you install this ++ version you must delete the old files: NERD_comments.vim and ++ NERD_comments.txt. ++ - Reworked the mappings and main entry point function for the script to ++ avoid causing visual-bells and screen scrolling. ++ - Changes to the script options (see |NERD_com-Customisation| for ++ details): ++ - They are all camel case now instead of underscored. ++ - Converted all of the regular expression options into simple boolean ++ options for simplicity. ++ - All the options are now stated positively, eg. ++ NERD_dont_remove_spaces_regexp has become NERDRemoveExtraSpaces. ++ - Some of the option names have been changed (other than in the above ++ ways) ++ - Some have been removed altogether, namely: NERD_create_h_filetype ++ (why was a commenting script creating a filetype?!), ++ NERD_left_align_regexp, NERD_right_align_regexp, ++ ++ - Removed all the NERD_use_alt_style_XXX_coms options and replaced them ++ with a better system. Now if a filetype has alternative delims, the ++ script will check whether an option of the form ++ "NERD_<&filetype>_alt_style" exists, and if it does then alt delims will ++ be used. See |NERD_com-cust-delims| for details. ++ - The script no longer removes extra spaces for sexy comments for the ++ NERDRemoveExtraSpaces option (it will still remove spaces if ++ NERDSpaceDelims is set). ++ - Added dummy support for viminfo and rtf. ++ - Added support for the "gentoo-package-\(keywords\|mask\|use\)" ++ filetypes. ++ - Added '#' comments as an alternative for the asm filetype ++ ++Thanks to Markus Klinik and Anders for bug reports, and again to Anders ++for his patch. Thanks to John O'Shea and fREW for the filetype ++information. ++ ++============================================================================== ++8. Credits {{{2 *NERDComCredits* ++ ++Thanks and respect to the following people: ++ ++Thanks to Nick Brettell for his many ideas and criticisms. A bloody good ++bastard. ++:normal :.-2s/good// ++ ++Thanks to Matthew Hawkins for his awesome refactoring! ++ ++Thanks to the authors of the vimspell whose documentation ++installation function I stole :) ++ ++Thanks to Greg Searle for the idea of using place-holders for nested comments. ++ ++Thanks to Nguyen for the suggestions and pointing the h file highlighting bug! ++Also, thanks for the idea of doing sexy comments as well as his suggestions ++relating to it :P ++Thanks again to Nguyen for complaining about the NERD_comments menu mapping ++(-c) interfering with another mapping of his... and thus the ++NERD_dont_create_menu_shortcut option was born :P ++(it was then replaced with NERD_menu_mode in version 1.67 :) ++ ++Thanks to Sam R for pointing out some filetypes that NERD_comments could support! ++ ++Cheers to Litchi for the idea of having a mapping that appends a comment to ++the current line :) ++ ++Thanks to jorge scandaliaris and Shufeng Zheng for telling me about some ++problems with commenting in visual mode. Thanks again to Jorge for his ++continued suggestions on this matter :) ++ ++Thanks to Martin Stubenschrott for pointing out a bug with the mapping ++:) Ive gotta stop breaking this mapping! ++ ++Thanks to Markus Erlmann for pointing out a conflict that this script was ++having with the taglist plugin. ++ ++Thanks to Brent Rice for alerting me about, and helping me track down, a bug ++in the script when the "ignorecase" option in vim was set. ++ ++Thanks to Richard Willis for telling me about how line continuation was ++causing problems on cygwin. Also, thanks pointing out a bug in the help file ++and for suggesting // comments for c (its about time SOMEONE did :P). May ANSI ++have mercy on your soul :) ++ ++Thanks to Igor Prischepoff for suggesting that i implement "toggle comments". ++Also, thanks for his suggested improvements about toggle comments after i ++implemented them. ++ ++Thanks to harry for telling me that i broke the cn mapping in 1.53 :), ++and thanks again for telling me about a bug that occurred when editing a file ++in a new tab. ++ ++Thanks to Martin (Krischikim?) for his patch that fixed a bug with the doc ++install function and added support for ada comments with spaces as well as ++making a couple of other small changes. ++ ++Thanks to David Bourgeois for pointing out a bug with when commenting c files ++:)... [a few days later] ok i completely misunderstood what David was talking ++about and ended up fixing a completely different bug to what he was talking ++about :P ++ ++Thanks to David Bourgeois for pointing out a bug when changing buffers. ++ ++Cheers to Eike Von Seggern for sending me a patch to fix a bug in 1.60 that ++was causing spaces to be added to the end of lines with single-part ++delimiters. It's nice when people do my work for me :D ++ ++Thanks to Torsten Blix for telling me about a couple of bugs when uncommenting ++sexy comments. Sexy comments dont look so sexy when they are only half removed ++:P ++ ++Thanks to Alexander "boesi" Bosecke for pointing out a bug that was stopping ++the NERD_space_delim_filetype_regexp option from working with left aligned ++toggle comments. And for pointing out a bug when initialising VB comments. ++ ++Thanks to Stefano Zacchiroli for suggesting the idea of "Minimal comments". ++And for suggested improvements to minimal comments. ++ ++Thanks to Norick Chen for emailing in a patch that fixed the asp delimiters. ++In 1.65 ++ ++Thanks to Jonathan Derque for alerting me to some filetypes that could be ++supported (Namely: context, plaintext and mail). ++ ++Thanks to Joseph Barker for the sugesting that the menu be an optional ++feature. ++ ++Thanks to Gary Church and Tim Carey-Smith for complaining about the ++keymappings and causing me to introduce the NERD_mapleader option :) ++ ++Thanks to Vigil for pointing out that the "fetchmail" filetype was not ++supported and emailing me the delimiters ++ ++Thanks to Michael Brunner for telling me about the kconfig filetype. ++ ++Thanks to Antono Vasiljev for telling me about the netdict filetype. ++ ++Thanks to Melissa Reid for telling me about the omlet filetype. ++ ++Thanks to Ilia N Ternovich for alerting me to the 'qf' (quickfix) filetype. ++ ++Thanks to Markus Klinik for emailing me about a bug for sexy comments where ++spaces were being eaten. ++ ++Thanks to John O'Shea for emailing me about the RTF filetype. Thanks again for ++the SVNcommitlog and vcscommit filetypes. ++ ++Thanks to Anders for emailing me a patch to help get rid of all the visual ++bells and screen scrolling, and for sending me the delimiters for the occam ++filetype. ++ ++Thanks to Anders and Markus Klinik for emailing me about the screen scrolling ++issues and finally getting me off my ass about them :P ++ ++Thanks to Mark Woodward for emailing me about the csv filetype. ++ ++Thanks to fREW for emailing me with the /gentoo-package-(mask|keywords|use)/ ++filetypes the vo_base filetype. ++ ++Thanks to Alexey for emailing me about the verilog_systemverilog/systemverilog ++filetypes. ++ ++Cheers to Lizendir for the email about the fstab filetype ++ ++Thanks to Michael Böhler for emailing me with the autoit, autohotkey and docbk ++filetypes. ++ ++Thanks to Aaron Small for emailing me about the cmake filetype. ++ ++Thanks to Ramiro for emailing me about the htmldjango and django filetypes. ++ ++Thanks to Seth Mason for sending me a patch to fix some pathing issues for the ++help doc installation. ++ ++Thanks to Stefano Zacchiroli for emailing me with the debcontrol and ++debchangelog filetypes. ++ ++Thanks to Alex Tarkovsky for emailing me about the ebuild and eclass ++filetypes. ++ ++Cheers to Jorge Rodrigues for emailing me about the gams filetype. ++ ++Cheers to James Hales for the patch that made the comment maps work better with ++counts, and made the script reset comment delims for a buffer when its ++filetype changes. ++ ++Thank to Rainer Müller for emailing me with the Objective C delimiters. ++ ++Thanks to Jason Mills for emailing me the Groovy filetype. ++ ++Thanks to Normandie Azucena for emailing me about the vera filetype. ++ ++Thanks to Florian Apolloner for emailing me about the ldif filetype. ++ ++Cheers to David Fishburn for emailing me with the lookupfile filetype. ++ ++Thanks to Niels Aan de Brugh for emailing me with the rst filetype. ++ ++Cheers to heptite on #vim for helping me track down some tab-space conversion ++bugs. ++ ++Cheers to Don Hatlestad for telling me about the ahk filetype ++ ++Thanks to Christophe Benz for emailing me with the Desktop and xsd filetypes. ++ ++Cheers to Cheng Fang for the bug reports :D ++ ++Cheers to myself for being the best looking man on Earth! ++=== END_DOC ++" vim: set foldmethod=marker : +diff -urN vim71/1/plugin/.svn/text-base/taglist.vim.svn-base vim71_ada/1/plugin/.svn/text-base/taglist.vim.svn-base +--- vim71/1/plugin/.svn/text-base/taglist.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/.svn/text-base/taglist.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,4524 @@ ++" File: taglist.vim ++" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) ++" Version: 4.3 ++" Last Modified: February 18, 2007 ++" Copyright: Copyright (C) 2002-2006 Yegappan Lakshmanan ++" Permission is hereby granted to use and distribute this code, ++" with or without modifications, provided that this copyright ++" notice is copied with it. Like anything else that's free, ++" taglist.vim is provided *as is* and comes with no warranty of any ++" kind, either expressed or implied. In no event will the copyright ++" holder be liable for any damamges resulting from the use of this ++" software. ++" ++" The "Tag List" plugin is a source code browser plugin for Vim and provides ++" an overview of the structure of the programming language files and allows ++" you to efficiently browse through source code files for different ++" programming languages. You can visit the taglist plugin home page for more ++" information: ++" ++" http://vim-taglist.sourceforge.net ++" ++" You can subscribe to the taglist mailing list to post your questions ++" or suggestions for improvement or to report bugs. Visit the following ++" page for subscribing to the mailing list: ++" ++" http://groups.yahoo.com/group/taglist/ ++" ++" For more information about using this plugin, after installing the ++" taglist plugin, use the ":help taglist" command. ++" ++" Installation ++" ------------ ++" 1. Download the taglist.zip file and unzip the files to the $HOME/.vim ++" or the $HOME/vimfiles or the $VIM/vimfiles directory. This should ++" unzip the following two files (the directory structure should be ++" preserved): ++" ++" plugin/taglist.vim - main taglist plugin file ++" doc/taglist.txt - documentation (help) file ++" ++" Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath' ++" Vim help pages for more details about installing Vim plugins. ++" 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or ++" $VIM/vimfiles/doc directory, start Vim and run the ":helptags ." ++" command to process the taglist help file. ++" 3. If the exuberant ctags utility is not present in your PATH, then set the ++" Tlist_Ctags_Cmd variable to point to the location of the exuberant ctags ++" utility (not to the directory) in the .vimrc file. ++" 4. If you are running a terminal/console version of Vim and the ++" terminal doesn't support changing the window width then set the ++" 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file. ++" 5. Restart Vim. ++" 6. You can now use the ":TlistToggle" command to open/close the taglist ++" window. You can use the ":help taglist" command to get more ++" information about using the taglist plugin. ++" ++" ****************** Do not modify after this line ************************ ++ ++" Line continuation used here ++let s:cpo_save = &cpo ++set cpo&vim ++ ++if !exists('loaded_taglist') ++ " First time loading the taglist plugin ++ " ++ " To speed up the loading of Vim, the taglist plugin uses autoload ++ " mechanism to load the taglist functions. ++ " Only define the configuration variables, user commands and some ++ " auto-commands and finish sourcing the file ++ ++ " The taglist plugin requires the built-in Vim system() function. If this ++ " function is not available, then don't load the plugin. ++ if !exists('*system') ++ echomsg 'Taglist: Vim system() built-in function is not available. ' . ++ \ 'Plugin is not loaded.' ++ let loaded_taglist = 'no' ++ let &cpo = s:cpo_save ++ finish ++ endif ++ ++ " Location of the exuberant ctags tool ++ if !exists('Tlist_Ctags_Cmd') ++ if executable('exuberant-ctags') ++ " On Debian Linux, exuberant ctags is installed ++ " as exuberant-ctags ++ let Tlist_Ctags_Cmd = 'exuberant-ctags' ++ elseif executable(' exctags') ++ " On Free-BSD, exuberant ctags is installed as exctags ++ let Tlist_Ctags_ Cmd = 'exctags' ++ elseif executable('ctags') ++ let Tlist_Ctags_Cmd = 'ctags' ++ elseif executable('ctags.exe') ++ let Tlist_Ctags_Cmd = 'ctags.exe' ++ elseif executable('tags') ++ let Tlist_Ctags_Cmd = 'tags' ++ else ++ echomsg 'Taglist: Exuberant ctags (http://ctags.sf.net) ' . ++ \ 'not found in PATH. Plugin is not loaded.' ++ " Skip loading the plugin ++ let loaded_taglist = 'no' ++ let &cpo = s:cpo_save ++ finish ++ endif ++ endif ++ ++ ++ " Automatically open the taglist window on Vim startup ++ if !exists('Tlist_Auto_Open') ++ let Tlist_Auto_Open = 0 ++ endif ++ ++ " When the taglist window is toggle opened, move the cursor to the ++ " taglist window ++ if !exists('Tlist_GainFocus_On_ToggleOpen') ++ let Tlist_GainFocus_On_ToggleOpen = 0 ++ endif ++ ++ " Process files even when the taglist window is not open ++ if !exists('Tlist_Process_File_Always') ++ let Tlist_Process_File_Always = 0 ++ endif ++ ++ if !exists('Tlist_Show_Menu') ++ let Tlist_Show_Menu = 0 ++ endif ++ ++ " Tag listing sort type - 'name' or 'order' ++ if !exists('Tlist_Sort_Type') ++ let Tlist_Sort_Type = 'order' ++ endif ++ ++ " Tag listing window split (horizontal/vertical) control ++ if !exists('Tlist_Use_Horiz_Window') ++ let Tlist_Use_Horiz_Window = 0 ++ endif ++ ++ " Open the vertically split taglist window on the left or on the right ++ " side. This setting is relevant only if Tlist_Use_Horiz_Window is set to ++ " zero (i.e. only for vertically split windows) ++ if !exists('Tlist_Use_Right_Window') ++ let Tlist_Use_Right_Window = 0 ++ endif ++ ++ " Increase Vim window width to display vertically split taglist window. ++ " For MS-Windows version of Vim running in a MS-DOS window, this must be ++ " set to 0 otherwise the system may hang due to a Vim limitation. ++ if !exists('Tlist_Inc_Winwidth') ++ if (has('win16') || has('win95')) && !has('gui_running') ++ let Tlist_Inc_Winwidth = 0 ++ else ++ let Tlist_Inc_Winwidth = 1 ++ endif ++ endif ++ ++ " Vertically split taglist window width setting ++ if !exists('Tlist_WinWidth') ++ let Tlist_WinWidth = 30 ++ endif ++ ++ " Horizontally split taglist window height setting ++ if !exists('Tlist_WinHeight') ++ let Tlist_WinHeight = 10 ++ endif ++ ++ " Display tag prototypes or tag names in the taglist window ++ if !exists('Tlist_Display_Prototype') ++ let Tlist_Display_Prototype = 0 ++ endif ++ ++ " Display tag scopes in the taglist window ++ if !exists('Tlist_Display_Tag_Scope') ++ let Tlist_Display_Tag_Scope = 1 ++ endif ++ ++ " Use single left mouse click to jump to a tag. By default this is disabled. ++ " Only double click using the mouse will be processed. ++ if !exists('Tlist_Use_SingleClick') ++ let Tlist_Use_SingleClick = 0 ++ endif ++ ++ " Control whether additional help is displayed as part of the taglist or ++ " not. Also, controls whether empty lines are used to separate the tag ++ " tree. ++ if !exists('Tlist_Compact_Format') ++ let Tlist_Compact_Format = 0 ++ endif ++ ++ " Exit Vim if only the taglist window is currently open. By default, this is ++ " set to zero. ++ if !exists('Tlist_Exit_OnlyWindow') ++ let Tlist_Exit_OnlyWindow = 0 ++ endif ++ ++ " Automatically close the folds for the non-active files in the taglist ++ " window ++ if !exists('Tlist_File_Fold_Auto_Close') ++ let Tlist_File_Fold_Auto_Close = 0 ++ endif ++ ++ " Close the taglist window when a tag is selected ++ if !exists('Tlist_Close_On_Select') ++ let Tlist_Close_On_Select = 0 ++ endif ++ ++ " Automatically update the taglist window to display tags for newly ++ " edited files ++ if !exists('Tlist_Auto_Update') ++ let Tlist_Auto_Update = 1 ++ endif ++ ++ " Automatically highlight the current tag ++ if !exists('Tlist_Auto_Highlight_Tag') ++ let Tlist_Auto_Highlight_Tag = 1 ++ endif ++ ++ " Automatically highlight the current tag on entering a buffer ++ if !exists('Tlist_Highlight_Tag_On_BufEnter') ++ let Tlist_Highlight_Tag_On_BufEnter = 1 ++ endif ++ ++ " Enable fold column to display the folding for the tag tree ++ if !exists('Tlist_Enable_Fold_Column') ++ let Tlist_Enable_Fold_Column = 1 ++ endif ++ ++ " Display the tags for only one file in the taglist window ++ if !exists('Tlist_Show_One_File') ++ let Tlist_Show_One_File = 0 ++ endif ++ ++ if !exists('Tlist_Max_Submenu_Items') ++ let Tlist_Max_Submenu_Items = 20 ++ endif ++ ++ if !exists('Tlist_Max_Tag_Length') ++ let Tlist_Max_Tag_Length = 10 ++ endif ++ ++ " Do not change the name of the taglist title variable. The winmanager ++ " plugin relies on this name to determine the title for the taglist ++ " plugin. ++ let TagList_title = "__Tag_List__" ++ ++ " Taglist debug messages ++ let s:tlist_msg = '' ++ ++ " Define the taglist autocommand to automatically open the taglist window ++ " on Vim startup ++ if g:Tlist_Auto_Open ++ autocmd VimEnter * nested call s:Tlist_Window_Check_Auto_Open() ++ endif ++ ++ " Refresh the taglist ++ if g:Tlist_Process_File_Always ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ ++ if g:Tlist_Show_Menu ++ autocmd GUIEnter * call s:Tlist_Menu_Init() ++ endif ++ ++ " When the taglist buffer is created when loading a Vim session file, ++ " the taglist buffer needs to be initialized. The BufFilePost event ++ " is used to handle this case. ++ autocmd BufFilePost __Tag_List__ call s:Tlist_Vim_Session_Load() ++ ++ " Define the user commands to manage the taglist window ++ command! -nargs=0 -bar TlistToggle call s:Tlist_Window_Toggle() ++ command! -nargs=0 -bar TlistOpen call s:Tlist_Window_Open() ++ " For backwards compatiblity define the Tlist command ++ command! -nargs=0 -bar Tlist TlistToggle ++ command! -nargs=+ -complete=file TlistAddFiles ++ \ call s:Tlist_Add_Files() ++ command! -nargs=+ -complete=dir TlistAddFilesRecursive ++ \ call s:Tlist_Add_Files_Recursive() ++ command! -nargs=0 -bar TlistClose call s:Tlist_Window_Close() ++ command! -nargs=0 -bar TlistUpdate call s:Tlist_Update_Current_File() ++ command! -nargs=0 -bar TlistHighlightTag call s:Tlist_Window_Highlight_Tag( ++ \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1) ++ " For backwards compatiblity define the TlistSync command ++ command! -nargs=0 -bar TlistSync TlistHighlightTag ++ command! -nargs=* -complete=buffer TlistShowPrototype ++ \ echo Tlist_Get_Tag_Prototype_By_Line() ++ command! -nargs=* -complete=buffer TlistShowTag ++ \ echo Tlist_Get_Tagname_By_Line() ++ command! -nargs=* -complete=file TlistSessionLoad ++ \ call s:Tlist_Session_Load() ++ command! -nargs=* -complete=file TlistSessionSave ++ \ call s:Tlist_Session_Save() ++ command! -bar TlistLock let Tlist_Auto_Update=0 ++ command! -bar TlistUnlock let Tlist_Auto_Update=1 ++ ++ " Commands for enabling/disabling debug and to display debug messages ++ command! -nargs=? -complete=file -bar TlistDebug ++ \ call s:Tlist_Debug_Enable() ++ command! -nargs=0 -bar TlistUndebug call s:Tlist_Debug_Disable() ++ command! -nargs=0 -bar TlistMessages call s:Tlist_Debug_Show() ++ ++ " Define autocommands to autoload the taglist plugin when needed. ++ ++ " Trick to get the current script ID ++ map xx xx ++ let s:tlist_sid = substitute(maparg('xx'), '\(\d\+_\)xx$', ++ \ '\1', '') ++ unmap xx ++ ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Window_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Menu_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined Tlist_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined TagList_* source ' . ++ \ escape(expand(''), ' ') ++ ++ let loaded_taglist = 'fast_load_done' ++ ++ if g:Tlist_Show_Menu && has('gui_running') ++ call s:Tlist_Menu_Init() ++ endif ++ ++ " restore 'cpo' ++ let &cpo = s:cpo_save ++ finish ++endif ++ ++if !exists('s:tlist_sid') ++ " Two or more versions of taglist plugin are installed. Don't ++ " load this version of the plugin. ++ finish ++endif ++ ++unlet! s:tlist_sid ++ ++if loaded_taglist != 'fast_load_done' ++ " restore 'cpo' ++ let &cpo = s:cpo_save ++ finish ++endif ++ ++" Taglist plugin functionality is available ++let loaded_taglist = 'available' ++ ++"------------------- end of user configurable options -------------------- ++ ++" Default language specific settings for supported file types and tag types ++" ++" Variable name format: ++" ++" s:tlist_def_{vim_ftype}_settings ++" ++" vim_ftype - Filetype detected by Vim ++" ++" Value format: ++" ++" ;:;:;... ++" ++" ctags_ftype - File type supported by exuberant ctags ++" flag - Flag supported by exuberant ctags to generate a tag type ++" name - Name of the tag type used in the taglist window to display the ++" tags of this type ++" ++ ++" Ada language ++let s:tlist_def_ada_settings = 'ada;' . ++ \ 'P:package spec;' . ++ \ 'p:package body;' . ++ \ 'T:type spec;' . ++ \ 't:type;' . ++ \ 'U:subtype spec;' . ++ \ 'u:subtype;' . ++ \ 'c:component;' . ++ \ 'l:literal;' . ++ \ 'V:variable spec;' . ++ \ 'v:variable;' . ++ \ 'f:formal;' . ++ \ 'n:constant;' . ++ \ 'x:exception;' . ++ \ 'R:subprogram spec;' . ++ \ 'r:subprogram body;' . ++ \ 'K:task spec;' . ++ \ 'k:task body;' . ++ \ 'O:protected spec;' . ++ \ 'o:protected body;' . ++ \ 'E:entry spec;' . ++ \ 'e:entry body;' . ++ \ 'b:label;' . ++ \ 'i:identifier;' . ++ \ 'a:autovar;' . ++ \ 'y:annon' ++ ++" assembly language ++let s:tlist_def_asm_settings = 'asm;d:define;l:label;m:macro;t:type' ++ ++" aspperl language ++let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable' ++ ++" aspvbs language ++let s:tlist_def_aspvbs_settings = 'asp;f:function;s:sub;v:variable' ++ ++" awk language ++let s:tlist_def_awk_settings = 'awk;f:function' ++ ++" beta language ++let s:tlist_def_beta_settings = 'beta;f:fragment;s:slot;v:pattern' ++ ++" c language ++let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' . ++ \ 'v:variable;f:function' ++ ++" c++ language ++let s:tlist_def_cpp_settings = 'c++;n:namespace;v:variable;d:macro;t:typedef;' . ++ \ 'c:class;g:enum;s:struct;u:union;f:function' ++ ++" c# language ++let s:tlist_def_cs_settings = 'c#;d:macro;t:typedef;n:namespace;c:class;' . ++ \ 'E:event;g:enum;s:struct;i:interface;' . ++ \ 'p:properties;m:method' ++ ++" cobol language ++let s:tlist_def_cobol_settings = 'cobol;d:data;f:file;g:group;p:paragraph;' . ++ \ 'P:program;s:section' ++ ++" eiffel language ++let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature' ++ ++" erlang language ++let s:tlist_def_erlang_settings = 'erlang;d:macro;r:record;m:module;f:function' ++ ++" expect (same as tcl) language ++let s:tlist_def_expect_settings = 'tcl;c:class;f:method;p:procedure' ++ ++" fortran language ++let s:tlist_def_fortran_settings = 'fortran;p:program;b:block data;' . ++ \ 'c:common;e:entry;i:interface;k:type;l:label;m:module;' . ++ \ 'n:namelist;t:derived;v:variable;f:function;s:subroutine' ++ ++" HTML language ++let s:tlist_def_html_settings = 'html;a:anchor;f:javascript function' ++ ++" java language ++let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' . ++ \ 'f:field;m:method' ++ ++" javascript language ++let s:tlist_def_javascript_settings = 'javascript;f:function' ++ ++" lisp language ++let s:tlist_def_lisp_settings = 'lisp;f:function' ++ ++" lua language ++let s:tlist_def_lua_settings = 'lua;f:function' ++ ++" makefiles ++let s:tlist_def_make_settings = 'make;m:macro' ++ ++" pascal language ++let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure' ++ ++" perl language ++let s:tlist_def_perl_settings = 'perl;c:constant;l:label;p:package;s:subroutine' ++ ++" php language ++let s:tlist_def_php_settings = 'php;c:class;d:constant;v:variable;f:function' ++ ++" python language ++let s:tlist_def_python_settings = 'python;c:class;m:member;f:function' ++ ++" rexx language ++let s:tlist_def_rexx_settings = 'rexx;s:subroutine' ++ ++" ruby language ++let s:tlist_def_ruby_settings = 'ruby;c:class;f:method;F:function;' . ++ \ 'm:singleton method' ++ ++" scheme language ++let s:tlist_def_scheme_settings = 'scheme;s:set;f:function' ++ ++" shell language ++let s:tlist_def_sh_settings = 'sh;f:function' ++ ++" C shell language ++let s:tlist_def_csh_settings = 'sh;f:function' ++ ++" Z shell language ++let s:tlist_def_zsh_settings = 'sh;f:function' ++ ++" slang language ++let s:tlist_def_slang_settings = 'slang;n:namespace;f:function' ++ ++" sml language ++let s:tlist_def_sml_settings = 'sml;e:exception;c:functor;s:signature;' . ++ \ 'r:structure;t:type;v:value;f:function' ++ ++" sql language ++let s:tlist_def_sql_settings = 'sql;c:cursor;F:field;P:package;r:record;' . ++ \ 's:subtype;t:table;T:trigger;v:variable;f:function;p:procedure' ++ ++" tcl language ++let s:tlist_def_tcl_settings = 'tcl;c:class;f:method;m:method;p:procedure' ++ ++" vera language ++let s:tlist_def_vera_settings = 'vera;c:class;d:macro;e:enumerator;' . ++ \ 'f:function;g:enum;m:member;p:program;' . ++ \ 'P:prototype;t:task;T:typedef;v:variable;' . ++ \ 'x:externvar' ++ ++"verilog language ++let s:tlist_def_verilog_settings = 'verilog;m:module;c:constant;P:parameter;' . ++ \ 'e:event;r:register;t:task;w:write;p:port;v:variable;f:function' ++ ++" vim language ++let s:tlist_def_vim_settings = 'vim;a:autocmds;v:variable;f:function' ++ ++" yacc language ++let s:tlist_def_yacc_settings = 'yacc;l:label' ++ ++"------------------- end of language specific options -------------------- ++ ++" Vim window size is changed by the taglist plugin or not ++let s:tlist_winsize_chgd = -1 ++" Taglist window is maximized or not ++let s:tlist_win_maximized = 0 ++" Name of files in the taglist ++let s:tlist_file_names='' ++" Number of files in the taglist ++let s:tlist_file_count = 0 ++" Number of filetypes supported by taglist ++let s:tlist_ftype_count = 0 ++" Is taglist part of other plugins like winmanager or cream? ++let s:tlist_app_name = "none" ++" Are we displaying brief help text ++let s:tlist_brief_help = 1 ++" List of files removed on user request ++let s:tlist_removed_flist = "" ++" Index of current file displayed in the taglist window ++let s:tlist_cur_file_idx = -1 ++" Taglist menu is empty or not ++let s:tlist_menu_empty = 1 ++ ++" An autocommand is used to refresh the taglist window when entering any ++" buffer. We don't want to refresh the taglist window if we are entering the ++" file window from one of the taglist functions. The 'Tlist_Skip_Refresh' ++" variable is used to skip the refresh of the taglist window and is set ++" and cleared appropriately. ++let s:Tlist_Skip_Refresh = 0 ++ ++" Tlist_Window_Display_Help() ++function! s:Tlist_Window_Display_Help() ++ if s:tlist_app_name == "winmanager" ++ " To handle a bug in the winmanager plugin, add a space at the ++ " last line ++ call setline('$', ' ') ++ endif ++ ++ if s:tlist_brief_help ++ " Add the brief help ++ call append(0, '" Press to display help text') ++ else ++ " Add the extensive help ++ call append(0, '" : Jump to tag definition') ++ call append(1, '" o : Jump to tag definition in new window') ++ call append(2, '" p : Preview the tag definition') ++ call append(3, '" : Display tag prototype') ++ call append(4, '" u : Update tag list') ++ call append(5, '" s : Select sort field') ++ call append(6, '" d : Remove file from taglist') ++ call append(7, '" x : Zoom-out/Zoom-in taglist window') ++ call append(8, '" + : Open a fold') ++ call append(9, '" - : Close a fold') ++ call append(10, '" * : Open all folds') ++ call append(11, '" = : Close all folds') ++ call append(12, '" [[ : Move to the start of previous file') ++ call append(13, '" ]] : Move to the start of next file') ++ call append(14, '" q : Close the taglist window') ++ call append(15, '" : Remove help text') ++ endif ++endfunction ++ ++" Tlist_Window_Toggle_Help_Text() ++" Toggle taglist plugin help text between the full version and the brief ++" version ++function! s:Tlist_Window_Toggle_Help_Text() ++ if g:Tlist_Compact_Format ++ " In compact display mode, do not display help ++ return ++ endif ++ ++ " Include the empty line displayed after the help text ++ let brief_help_size = 1 ++ let full_help_size = 16 ++ ++ setlocal modifiable ++ ++ " Set report option to a huge value to prevent informational messages ++ " while deleting the lines ++ let old_report = &report ++ set report=99999 ++ ++ " Remove the currently highlighted tag. Otherwise, the help text ++ " might be highlighted by mistake ++ match none ++ ++ " Toggle between brief and full help text ++ if s:tlist_brief_help ++ let s:tlist_brief_help = 0 ++ ++ " Remove the previous help ++ exe '1,' . brief_help_size . ' delete _' ++ ++ " Adjust the start/end line numbers for the files ++ call s:Tlist_Window_Update_Line_Offsets(0, 1, full_help_size - brief_help_size) ++ else ++ let s:tlist_brief_help = 1 ++ ++ " Remove the previous help ++ exe '1,' . full_help_size . ' delete _' ++ ++ " Adjust the start/end line numbers for the files ++ call s:Tlist_Window_Update_Line_Offsets(0, 0, full_help_size - brief_help_size) ++ endif ++ ++ call s:Tlist_Window_Display_Help() ++ ++ " Restore the report option ++ let &report = old_report ++ ++ setlocal nomodifiable ++endfunction ++ ++" Taglist debug support ++let s:tlist_debug = 0 ++ ++" File for storing the debug messages ++let s:tlist_debug_file = '' ++ ++" Tlist_Debug_Enable ++" Enable logging of taglist debug messages. ++function! s:Tlist_Debug_Enable(...) ++ let s:tlist_debug = 1 ++ ++ " Check whether a valid file name is supplied. ++ if a:1 != '' ++ let s:tlist_debug_file = fnamemodify(a:1, ':p') ++ ++ " Empty the log file ++ exe 'redir! > ' . s:tlist_debug_file ++ redir END ++ ++ " Check whether the log file is present/created ++ if !filewritable(s:tlist_debug_file) ++ call s:Tlist_Warning_Msg('Taglist: Unable to create log file ' ++ \ . s:tlist_debug_file) ++ let s:tlist_debug_file = '' ++ endif ++ endif ++endfunction ++ ++" Tlist_Debug_Disable ++" Disable logging of taglist debug messages. ++function! s:Tlist_Debug_Disable(...) ++ let s:tlist_debug = 0 ++ let s:tlist_debug_file = '' ++endfunction ++ ++" Tlist_Debug_Show ++" Display the taglist debug messages in a new window ++function! s:Tlist_Debug_Show() ++ if s:tlist_msg == '' ++ call s:Tlist_Warning_Msg('Taglist: No debug messages') ++ return ++ endif ++ ++ " Open a new window to display the taglist debug messages ++ new taglist_debug.txt ++ " Delete all the lines (if the buffer already exists) ++ silent! %delete _ ++ " Add the messages ++ silent! put =s:tlist_msg ++ " Move the cursor to the first line ++ normal! gg ++endfunction ++ ++" Tlist_Log_Msg ++" Log the supplied debug message along with the time ++function! s:Tlist_Log_Msg(msg) ++ if s:tlist_debug ++ if s:tlist_debug_file != '' ++ exe 'redir >> ' . s:tlist_debug_file ++ silent echon strftime('%H:%M:%S') . ': ' . a:msg . "\n" ++ redir END ++ else ++ " Log the message into a variable ++ " Retain only the last 3000 characters ++ let len = strlen(s:tlist_msg) ++ if len > 3000 ++ let s:tlist_msg = strpart(s:tlist_msg, len - 3000) ++ endif ++ let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' . ++ \ a:msg . "\n" ++ endif ++ endif ++endfunction ++ ++" Tlist_Warning_Msg() ++" Display a message using WarningMsg highlight group ++function! s:Tlist_Warning_Msg(msg) ++ echohl WarningMsg ++ echomsg a:msg ++ echohl None ++endfunction ++ ++" Last returned file index for file name lookup. ++" Used to speed up file lookup ++let s:tlist_file_name_idx_cache = -1 ++ ++" Tlist_Get_File_Index() ++" Return the index of the specified filename ++function! s:Tlist_Get_File_Index(fname) ++ if s:tlist_file_count == 0 || a:fname == '' ++ return -1 ++ endif ++ ++ " If the new filename is same as the last accessed filename, then ++ " return that index ++ if s:tlist_file_name_idx_cache != -1 && ++ \ s:tlist_file_name_idx_cache < s:tlist_file_count ++ if s:tlist_{s:tlist_file_name_idx_cache}_filename == a:fname ++ " Same as the last accessed file ++ return s:tlist_file_name_idx_cache ++ endif ++ endif ++ ++ " First, check whether the filename is present ++ let s_fname = a:fname . "\n" ++ let i = stridx(s:tlist_file_names, s_fname) ++ if i == -1 ++ let s:tlist_file_name_idx_cache = -1 ++ return -1 ++ endif ++ ++ " Second, compute the file name index ++ let nl_txt = substitute(strpart(s:tlist_file_names, 0, i), "[^\n]", '', 'g') ++ let s:tlist_file_name_idx_cache = strlen(nl_txt) ++ return s:tlist_file_name_idx_cache ++endfunction ++ ++" Last returned file index for line number lookup. ++" Used to speed up file lookup ++let s:tlist_file_lnum_idx_cache = -1 ++ ++" Tlist_Window_Get_File_Index_By_Linenum() ++" Return the index of the filename present in the specified line number ++" Line number refers to the line number in the taglist window ++function! s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ call s:Tlist_Log_Msg('Tlist_Window_Get_File_Index_By_Linenum (' . a:lnum . ')') ++ ++ " First try to see whether the new line number is within the range ++ " of the last returned file ++ if s:tlist_file_lnum_idx_cache != -1 && ++ \ s:tlist_file_lnum_idx_cache < s:tlist_file_count ++ if a:lnum >= s:tlist_{s:tlist_file_lnum_idx_cache}_start && ++ \ a:lnum <= s:tlist_{s:tlist_file_lnum_idx_cache}_end ++ return s:tlist_file_lnum_idx_cache ++ endif ++ endif ++ ++ let fidx = -1 ++ ++ if g:Tlist_Show_One_File ++ " Displaying only one file in the taglist window. Check whether ++ " the line is within the tags displayed for that file ++ if s:tlist_cur_file_idx != -1 ++ if a:lnum >= s:tlist_{s:tlist_cur_file_idx}_start ++ \ && a:lnum <= s:tlist_{s:tlist_cur_file_idx}_end ++ let fidx = s:tlist_cur_file_idx ++ endif ++ ++ endif ++ else ++ " Do a binary search in the taglist ++ let left = 0 ++ let right = s:tlist_file_count - 1 ++ ++ while left < right ++ let mid = (left + right) / 2 ++ ++ if a:lnum >= s:tlist_{mid}_start && a:lnum <= s:tlist_{mid}_end ++ let s:tlist_file_lnum_idx_cache = mid ++ return mid ++ endif ++ ++ if a:lnum < s:tlist_{mid}_start ++ let right = mid - 1 ++ else ++ let left = mid + 1 ++ endif ++ endwhile ++ ++ if left >= 0 && left < s:tlist_file_count ++ \ && a:lnum >= s:tlist_{left}_start ++ \ && a:lnum <= s:tlist_{left}_end ++ let fidx = left ++ endif ++ endif ++ ++ let s:tlist_file_lnum_idx_cache = fidx ++ ++ return fidx ++endfunction ++ ++" Tlist_Exe_Cmd_No_Acmds ++" Execute the specified Ex command after disabling autocommands ++function! s:Tlist_Exe_Cmd_No_Acmds(cmd) ++ let old_eventignore = &eventignore ++ set eventignore=all ++ exe a:cmd ++ let &eventignore = old_eventignore ++endfunction ++ ++" Tlist_Skip_File() ++" Check whether tag listing is supported for the specified file ++function! s:Tlist_Skip_File(filename, ftype) ++ " Skip buffers with no names and buffers with filetype not set ++ if a:filename == '' || a:ftype == '' ++ return 1 ++ endif ++ ++ " Skip files which are not supported by exuberant ctags ++ " First check whether default settings for this filetype are available. ++ " If it is not available, then check whether user specified settings are ++ " available. If both are not available, then don't list the tags for this ++ " filetype ++ let var = 's:tlist_def_' . a:ftype . '_settings' ++ if !exists(var) ++ let var = 'g:tlist_' . a:ftype . '_settings' ++ if !exists(var) ++ return 1 ++ endif ++ endif ++ ++ " Skip files which are not readable or files which are not yet stored ++ " to the disk ++ if !filereadable(a:filename) ++ return 1 ++ endif ++ ++ return 0 ++endfunction ++ ++" Tlist_User_Removed_File ++" Returns 1 if a file is removed by a user from the taglist ++function! s:Tlist_User_Removed_File(filename) ++ return stridx(s:tlist_removed_flist, a:filename . "\n") != -1 ++endfunction ++ ++" Tlist_Update_Remove_List ++" Update the list of user removed files from the taglist ++" add == 1, add the file to the removed list ++" add == 0, delete the file from the removed list ++function! s:Tlist_Update_Remove_List(filename, add) ++ if a:add ++ let s:tlist_removed_flist = s:tlist_removed_flist . a:filename . "\n" ++ else ++ let idx = stridx(s:tlist_removed_flist, a:filename . "\n") ++ let text_before = strpart(s:tlist_removed_flist, 0, idx) ++ let rem_text = strpart(s:tlist_removed_flist, idx) ++ let next_idx = stridx(rem_text, "\n") ++ let text_after = strpart(rem_text, next_idx + 1) ++ ++ let s:tlist_removed_flist = text_before . text_after ++ endif ++endfunction ++ ++" Tlist_FileType_Init ++" Initialize the ctags arguments and tag variable for the specified ++" file type ++function! s:Tlist_FileType_Init(ftype) ++ call s:Tlist_Log_Msg('Tlist_FileType_Init (' . a:ftype . ')') ++ " If the user didn't specify any settings, then use the default ++ " ctags args. Otherwise, use the settings specified by the user ++ let var = 'g:tlist_' . a:ftype . '_settings' ++ if exists(var) ++ " User specified ctags arguments ++ let settings = {var} . ';' ++ else ++ " Default ctags arguments ++ let var = 's:tlist_def_' . a:ftype . '_settings' ++ if !exists(var) ++ " No default settings for this file type. This filetype is ++ " not supported ++ return 0 ++ endif ++ let settings = s:tlist_def_{a:ftype}_settings . ';' ++ endif ++ ++ let msg = 'Taglist: Invalid ctags option setting - ' . settings ++ ++ " Format of the option that specifies the filetype and ctags arugments: ++ " ++ " ;flag1:name1;flag2:name2;flag3:name3 ++ " ++ ++ " Extract the file type to pass to ctags. This may be different from the ++ " file type detected by Vim ++ let pos = stridx(settings, ';') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let ctags_ftype = strpart(settings, 0, pos) ++ if ctags_ftype == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ " Make sure a valid filetype is supplied. If the user didn't specify a ++ " valid filetype, then the ctags option settings may be treated as the ++ " filetype ++ if ctags_ftype =~ ':' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ ++ " Remove the file type from settings ++ let settings = strpart(settings, pos + 1) ++ if settings == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ ++ " Process all the specified ctags flags. The format is ++ " flag1:name1;flag2:name2;flag3:name3 ++ let ctags_flags = '' ++ let cnt = 0 ++ while settings != '' ++ " Extract the flag ++ let pos = stridx(settings, ':') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let flag = strpart(settings, 0, pos) ++ if flag == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ " Remove the flag from settings ++ let settings = strpart(settings, pos + 1) ++ ++ " Extract the tag type name ++ let pos = stridx(settings, ';') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let name = strpart(settings, 0, pos) ++ if name == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let settings = strpart(settings, pos + 1) ++ ++ let cnt = cnt + 1 ++ ++ let s:tlist_{a:ftype}_{cnt}_name = flag ++ let s:tlist_{a:ftype}_{cnt}_fullname = name ++ let ctags_flags = ctags_flags . flag ++ endwhile ++ ++ let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype . ++ \ ' --' . ctags_ftype . '-types=' . ctags_flags ++ let s:tlist_{a:ftype}_count = cnt ++ let s:tlist_{a:ftype}_ctags_flags = ctags_flags ++ ++ " Save the filetype name ++ let s:tlist_ftype_{s:tlist_ftype_count}_name = a:ftype ++ let s:tlist_ftype_count = s:tlist_ftype_count + 1 ++ ++ return 1 ++endfunction ++ ++" Tlist_Get_Filetype ++" Determine the filetype for the specified file ++function! s:Tlist_Get_Filetype(fname) ++ " Ignore the filetype autocommands ++ let old_eventignore = &eventignore ++ set eventignore=FileType ++ ++ " Save the 'filetype', as this will be changed temporarily ++ let old_filetype = &filetype ++ ++ " Run the filetypedetect group of autocommands to determine ++ " the filetype ++ exe 'doautocmd filetypedetect BufRead ' . a:fname ++ ++ " Save the detected filetype ++ let ftype = &filetype ++ ++ " Restore the previous state ++ let &filetype = old_filetype ++ let &eventignore = old_eventignore ++ ++ return ftype ++endfunction ++ ++" Tlist_Get_Buffer_Filetype ++" Get the filetype for the specified buffer ++function! s:Tlist_Get_Buffer_Filetype(bnum) ++ if bufloaded(a:bnum) ++ " For loaded buffers, the 'filetype' is already determined ++ return getbufvar(a:bnum, '&filetype') ++ endif ++ ++ " For unloaded buffers, if the 'filetype' option is set, return it ++ let ftype = getbufvar(a:bnum, '&filetype') ++ if ftype != '' ++ return ftype ++ endif ++ ++ " Skip non-existent buffers ++ if !bufexists(a:bnum) ++ return '' ++ endif ++ ++ " For buffers whose filetype is not yet determined, try to determine ++ " the filetype ++ let bname = bufname(a:bnum) ++ ++ return s:Tlist_Get_Filetype(bname) ++endfunction ++ ++" Tlist_Discard_TagInfo ++" Discard the stored tag information for a file ++function! s:Tlist_Discard_TagInfo(fidx) ++ call s:Tlist_Log_Msg('Tlist_Discard_TagInfo (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ " Discard information about the tags defined in the file ++ let i = 1 ++ while i <= s:tlist_{a:fidx}_tag_count ++ let fidx_i = 's:tlist_' . a:fidx . '_' . i ++ unlet! {fidx_i}_tag ++ unlet! {fidx_i}_tag_name ++ unlet! {fidx_i}_tag_type ++ unlet! {fidx_i}_ttype_idx ++ unlet! {fidx_i}_tag_proto ++ unlet! {fidx_i}_tag_searchpat ++ unlet! {fidx_i}_tag_linenum ++ let i = i + 1 ++ endwhile ++ ++ let s:tlist_{a:fidx}_tag_count = 0 ++ ++ " Discard information about tag type groups ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ if s:tlist_{a:fidx}_{ttype} != '' ++ let fidx_ttype = 's:tlist_' . a:fidx . '_' . ttype ++ let {fidx_ttype} = '' ++ let {fidx_ttype}_offset = 0 ++ let cnt = {fidx_ttype}_count ++ let {fidx_ttype}_count = 0 ++ let j = 1 ++ while j <= cnt ++ unlet! {fidx_ttype}_{j} ++ let j = j + 1 ++ endwhile ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Discard the stored menu command also ++ let s:tlist_{a:fidx}_menu_cmd = '' ++endfunction ++ ++" Tlist_Window_Update_Line_Offsets ++" Update the line offsets for tags for files starting from start_idx ++" and displayed in the taglist window by the specified offset ++function! s:Tlist_Window_Update_Line_Offsets(start_idx, increment, offset) ++ let i = a:start_idx ++ ++ while i < s:tlist_file_count ++ if s:tlist_{i}_visible ++ " Update the start/end line number only if the file is visible ++ if a:increment ++ let s:tlist_{i}_start = s:tlist_{i}_start + a:offset ++ let s:tlist_{i}_end = s:tlist_{i}_end + a:offset ++ else ++ let s:tlist_{i}_start = s:tlist_{i}_start - a:offset ++ let s:tlist_{i}_end = s:tlist_{i}_end - a:offset ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++endfunction ++ ++" Tlist_Discard_FileInfo ++" Discard the stored information for a file ++function! s:Tlist_Discard_FileInfo(fidx) ++ call s:Tlist_Log_Msg('Tlist_Discard_FileInfo (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ call s:Tlist_Discard_TagInfo(a:fidx) ++ ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ unlet! s:tlist_{a:fidx}_{ttype} ++ unlet! s:tlist_{a:fidx}_{ttype}_offset ++ unlet! s:tlist_{a:fidx}_{ttype}_count ++ let i = i + 1 ++ endwhile ++ ++ unlet! s:tlist_{a:fidx}_filename ++ unlet! s:tlist_{a:fidx}_sort_type ++ unlet! s:tlist_{a:fidx}_filetype ++ unlet! s:tlist_{a:fidx}_mtime ++ unlet! s:tlist_{a:fidx}_start ++ unlet! s:tlist_{a:fidx}_end ++ unlet! s:tlist_{a:fidx}_valid ++ unlet! s:tlist_{a:fidx}_visible ++ unlet! s:tlist_{a:fidx}_tag_count ++ unlet! s:tlist_{a:fidx}_menu_cmd ++endfunction ++ ++" Tlist_Window_Remove_File_From_Display ++" Remove the specified file from display ++function! s:Tlist_Window_Remove_File_From_Display(fidx) ++ call s:Tlist_Log_Msg('Tlist_Window_Remove_File_From_Display (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ " If the file is not visible then no need to remove it ++ if !s:tlist_{a:fidx}_visible ++ return ++ endif ++ ++ " Remove the tags displayed for the specified file from the window ++ let start = s:tlist_{a:fidx}_start ++ " Include the empty line after the last line also ++ if g:Tlist_Compact_Format ++ let end = s:tlist_{a:fidx}_end ++ else ++ let end = s:tlist_{a:fidx}_end + 1 ++ endif ++ ++ setlocal modifiable ++ exe 'silent! ' . start . ',' . end . 'delete _' ++ setlocal nomodifiable ++ ++ " Correct the start and end line offsets for all the files following ++ " this file, as the tags for this file are removed ++ call s:Tlist_Window_Update_Line_Offsets(a:fidx + 1, 0, end - start + 1) ++endfunction ++ ++" Tlist_Remove_File ++" Remove the file under the cursor or the specified file index ++" user_request - User requested to remove the file from taglist ++function! s:Tlist_Remove_File(file_idx, user_request) ++ let fidx = a:file_idx ++ ++ if fidx == -1 ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ endif ++ call s:Tlist_Log_Msg('Tlist_Remove_File (' . ++ \ s:tlist_{fidx}_filename . ', ' . a:user_request . ')') ++ ++ let save_winnr = winnr() ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Taglist window is open, remove the file from display ++ ++ if save_winnr != winnum ++ let old_eventignore = &eventignore ++ set eventignore=all ++ exe winnum . 'wincmd w' ++ endif ++ ++ call s:Tlist_Window_Remove_File_From_Display(fidx) ++ ++ if save_winnr != winnum ++ exe save_winnr . 'wincmd w' ++ let &eventignore = old_eventignore ++ endif ++ endif ++ ++ let fname = s:tlist_{fidx}_filename ++ ++ if a:user_request ++ " As the user requested to remove the file from taglist, ++ " add it to the removed list ++ call s:Tlist_Update_Remove_List(fname, 1) ++ endif ++ ++ " Remove the file name from the taglist list of filenames ++ let idx = stridx(s:tlist_file_names, fname . "\n") ++ let text_before = strpart(s:tlist_file_names, 0, idx) ++ let rem_text = strpart(s:tlist_file_names, idx) ++ let next_idx = stridx(rem_text, "\n") ++ let text_after = strpart(rem_text, next_idx + 1) ++ let s:tlist_file_names = text_before . text_after ++ ++ call s:Tlist_Discard_FileInfo(fidx) ++ ++ " Shift all the file variables by one index ++ let i = fidx + 1 ++ ++ while i < s:tlist_file_count ++ let j = i - 1 ++ ++ let s:tlist_{j}_filename = s:tlist_{i}_filename ++ let s:tlist_{j}_sort_type = s:tlist_{i}_sort_type ++ let s:tlist_{j}_filetype = s:tlist_{i}_filetype ++ let s:tlist_{j}_mtime = s:tlist_{i}_mtime ++ let s:tlist_{j}_start = s:tlist_{i}_start ++ let s:tlist_{j}_end = s:tlist_{i}_end ++ let s:tlist_{j}_valid = s:tlist_{i}_valid ++ let s:tlist_{j}_visible = s:tlist_{i}_visible ++ let s:tlist_{j}_tag_count = s:tlist_{i}_tag_count ++ let s:tlist_{j}_menu_cmd = s:tlist_{i}_menu_cmd ++ ++ let k = 1 ++ while k <= s:tlist_{j}_tag_count ++ let s:tlist_{j}_{k}_tag = s:tlist_{i}_{k}_tag ++ let s:tlist_{j}_{k}_tag_name = s:tlist_{i}_{k}_tag_name ++ let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type_By_Tag(i, k) ++ let s:tlist_{j}_{k}_ttype_idx = s:tlist_{i}_{k}_ttype_idx ++ let s:tlist_{j}_{k}_tag_proto = s:Tlist_Get_Tag_Prototype(i, k) ++ let s:tlist_{j}_{k}_tag_searchpat = s:Tlist_Get_Tag_SearchPat(i, k) ++ let s:tlist_{j}_{k}_tag_linenum = s:Tlist_Get_Tag_Linenum(i, k) ++ let k = k + 1 ++ endwhile ++ ++ let ftype = s:tlist_{i}_filetype ++ ++ let k = 1 ++ while k <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{k}_name ++ let s:tlist_{j}_{ttype} = s:tlist_{i}_{ttype} ++ let s:tlist_{j}_{ttype}_offset = s:tlist_{i}_{ttype}_offset ++ let s:tlist_{j}_{ttype}_count = s:tlist_{i}_{ttype}_count ++ if s:tlist_{j}_{ttype} != '' ++ let l = 1 ++ while l <= s:tlist_{j}_{ttype}_count ++ let s:tlist_{j}_{ttype}_{l} = s:tlist_{i}_{ttype}_{l} ++ let l = l + 1 ++ endwhile ++ endif ++ let k = k + 1 ++ endwhile ++ ++ " As the file and tag information is copied to the new index, ++ " discard the previous information ++ call s:Tlist_Discard_FileInfo(i) ++ ++ let i = i + 1 ++ endwhile ++ ++ " Reduce the number of files displayed ++ let s:tlist_file_count = s:tlist_file_count - 1 ++ ++ if g:Tlist_Show_One_File ++ " If the tags for only one file is displayed and if we just ++ " now removed that file, then invalidate the current file idx ++ if s:tlist_cur_file_idx == fidx ++ let s:tlist_cur_file_idx = -1 ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Goto_Window ++" Goto the taglist window ++function! s:Tlist_Window_Goto_Window() ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ if winnr() != winnum ++ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Create ++" Create a new taglist window. If it is already open, jump to it ++function! s:Tlist_Window_Create() ++ call s:Tlist_Log_Msg('Tlist_Window_Create()') ++ " If the window is open, jump to it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Jump to the existing window ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ return ++ endif ++ ++ " If used with winmanager don't open windows. Winmanager will handle ++ " the window/buffer management ++ if s:tlist_app_name == "winmanager" ++ return ++ endif ++ ++ " Create a new window. If user prefers a horizontal window, then open ++ " a horizontally split window. Otherwise open a vertically split ++ " window ++ if g:Tlist_Use_Horiz_Window ++ " Open a horizontally split window ++ let win_dir = 'botright' ++ " Horizontal window height ++ let win_size = g:Tlist_WinHeight ++ else ++ if s:tlist_winsize_chgd == -1 ++ " Open a vertically split window. Increase the window size, if ++ " needed, to accomodate the new window ++ if g:Tlist_Inc_Winwidth && ++ \ &columns < (80 + g:Tlist_WinWidth) ++ " Save the original window position ++ let s:tlist_pre_winx = getwinposx() ++ let s:tlist_pre_winy = getwinposy() ++ ++ " one extra column is needed to include the vertical split ++ let &columns= &columns + g:Tlist_WinWidth + 1 ++ ++ let s:tlist_winsize_chgd = 1 ++ else ++ let s:tlist_winsize_chgd = 0 ++ endif ++ endif ++ ++ if g:Tlist_Use_Right_Window ++ " Open the window at the rightmost place ++ let win_dir = 'botright vertical' ++ else ++ " Open the window at the leftmost place ++ let win_dir = 'topleft vertical' ++ endif ++ let win_size = g:Tlist_WinWidth ++ endif ++ ++ " If the tag listing temporary buffer already exists, then reuse it. ++ " Otherwise create a new buffer ++ let bufnum = bufnr(g:TagList_title) ++ if bufnum == -1 ++ " Create a new buffer ++ let wcmd = g:TagList_title ++ else ++ " Edit the existing buffer ++ let wcmd = '+buffer' . bufnum ++ endif ++ ++ " Create the taglist window ++ exe 'silent! ' . win_dir . ' ' . win_size . 'split ' . wcmd ++ ++ " Save the new window position ++ let s:tlist_winx = getwinposx() ++ let s:tlist_winy = getwinposy() ++ ++ " Initialize the taglist window ++ call s:Tlist_Window_Init() ++endfunction ++ ++" Tlist_Window_Zoom ++" Zoom (maximize/minimize) the taglist window ++function! s:Tlist_Window_Zoom() ++ if s:tlist_win_maximized ++ " Restore the window back to the previous size ++ if g:Tlist_Use_Horiz_Window ++ exe 'resize ' . g:Tlist_WinHeight ++ else ++ exe 'vert resize ' . g:Tlist_WinWidth ++ endif ++ let s:tlist_win_maximized = 0 ++ else ++ " Set the window size to the maximum possible without closing other ++ " windows ++ if g:Tlist_Use_Horiz_Window ++ resize ++ else ++ vert resize ++ endif ++ let s:tlist_win_maximized = 1 ++ endif ++endfunction ++ ++" Tlist_Ballon_Expr ++" When the mouse cursor is over a tag in the taglist window, display the ++" tag prototype (balloon) ++function! Tlist_Ballon_Expr() ++ " Get the file index ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(v:beval_lnum) ++ if fidx == -1 ++ return '' ++ endif ++ ++ " Get the tag output line for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, v:beval_lnum) ++ if tidx == 0 ++ return '' ++ endif ++ ++ " Get the tag search pattern and display it ++ return s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Window_Check_Width ++" Check the width of the taglist window. For horizontally split windows, the ++" 'winfixheight' option is used to fix the height of the window. For ++" vertically split windows, Vim doesn't support the 'winfixwidth' option. So ++" need to handle window width changes from this function. ++function! s:Tlist_Window_Check_Width() ++ let tlist_winnr = bufwinnr(g:TagList_title) ++ if tlist_winnr == -1 ++ return ++ endif ++ ++ let width = winwidth(tlist_winnr) ++ if width != g:Tlist_WinWidth ++ call s:Tlist_Log_Msg("Tlist_Window_Check_Width: Changing window " . ++ \ "width from " . width . " to " . g:Tlist_WinWidth) ++ let save_winnr = winnr() ++ if save_winnr != tlist_winnr ++ call s:Tlist_Exe_Cmd_No_Acmds(tlist_winnr . 'wincmd w') ++ endif ++ exe 'vert resize ' . g:Tlist_WinWidth ++ if save_winnr != tlist_winnr ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Exit_Only_Window ++" If the 'Tlist_Exit_OnlyWindow' option is set, then exit Vim if only the ++" taglist window is present. ++function! s:Tlist_Window_Exit_Only_Window() ++ " Before quitting Vim, delete the taglist buffer so that ++ " the '0 mark is correctly set to the previous buffer. ++ if v:version < 700 ++ if winbufnr(2) == -1 ++ bdelete ++ quit ++ endif ++ else ++ if winbufnr(2) == -1 ++ if tabpagenr('$') == 1 ++ " Only one tag page is present ++ bdelete ++ quit ++ else ++ " More than one tab page is present. Close only the current ++ " tab page ++ close ++ endif ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Init ++" Set the default options for the taglist window ++function! s:Tlist_Window_Init() ++ call s:Tlist_Log_Msg('Tlist_Window_Init()') ++ ++ " The 'readonly' option should not be set for the taglist buffer. ++ " If Vim is started as "view/gview" or if the ":view" command is ++ " used, then the 'readonly' option is set for all the buffers. ++ " Unset it for the taglist buffer ++ setlocal noreadonly ++ ++ " Set the taglist buffer filetype to taglist ++ setlocal filetype=taglist ++ ++ " Define taglist window element highlighting ++ syntax match TagListComment '^" .*' ++ syntax match TagListFileName '^[^" ].*$' ++ syntax match TagListTitle '^ \S.*$' ++ syntax match TagListTagScope '\s\[.\{-\}\]$' ++ ++ " Define the highlighting only if colors are supported ++ if has('gui_running') || &t_Co > 2 ++ " Colors to highlight various taglist window elements ++ " If user defined highlighting group exists, then use them. ++ " Otherwise, use default highlight groups. ++ if hlexists('MyTagListTagName') ++ highlight link TagListTagName MyTagListTagName ++ else ++ highlight default link TagListTagName Search ++ endif ++ " Colors to highlight comments and titles ++ if hlexists('MyTagListComment') ++ highlight link TagListComment MyTagListComment ++ else ++ highlight clear TagListComment ++ highlight default link TagListComment Comment ++ endif ++ if hlexists('MyTagListTitle') ++ highlight link TagListTitle MyTagListTitle ++ else ++ highlight clear TagListTitle ++ highlight default link TagListTitle Title ++ endif ++ if hlexists('MyTagListFileName') ++ highlight link TagListFileName MyTagListFileName ++ else ++ highlight clear TagListFileName ++ highlight default TagListFileName guibg=Grey ctermbg=darkgray ++ \ guifg=white ctermfg=white ++ endif ++ if hlexists('MyTagListTagScope') ++ highlight link TagListTagScope MyTagListTagScope ++ else ++ highlight clear TagListTagScope ++ highlight default link TagListTagScope Identifier ++ endif ++ else ++ highlight default TagListTagName term=reverse cterm=reverse ++ endif ++ ++ " Folding related settings ++ setlocal foldenable ++ setlocal foldminlines=0 ++ setlocal foldmethod=manual ++ setlocal foldlevel=9999 ++ if g:Tlist_Enable_Fold_Column ++ setlocal foldcolumn=3 ++ else ++ setlocal foldcolumn=0 ++ endif ++ setlocal foldtext=v:folddashes.getline(v:foldstart) ++ ++ if s:tlist_app_name != "winmanager" ++ " Mark buffer as scratch ++ silent! setlocal buftype=nofile ++ if s:tlist_app_name == "none" ++ silent! setlocal bufhidden=delete ++ endif ++ silent! setlocal noswapfile ++ " Due to a bug in Vim 6.0, the winbufnr() function fails for unlisted ++ " buffers. So if the taglist buffer is unlisted, multiple taglist ++ " windows will be opened. This bug is fixed in Vim 6.1 and above ++ if v:version >= 601 ++ silent! setlocal nobuflisted ++ endif ++ endif ++ ++ silent! setlocal nowrap ++ ++ " If the 'number' option is set in the source window, it will affect the ++ " taglist window. So forcefully disable 'number' option for the taglist ++ " window ++ silent! setlocal nonumber ++ ++ " Use fixed height when horizontally split window is used ++ if g:Tlist_Use_Horiz_Window ++ if v:version >= 602 ++ set winfixheight ++ endif ++ endif ++ if !g:Tlist_Use_Horiz_Window && v:version >= 700 ++ set winfixwidth ++ endif ++ ++ " Setup balloon evaluation to display tag prototype ++ if v:version >= 700 && has('balloon_eval') ++ setlocal balloonexpr=Tlist_Ballon_Expr() ++ set ballooneval ++ endif ++ ++ " Setup the cpoptions properly for the maps to work ++ let old_cpoptions = &cpoptions ++ set cpoptions&vim ++ ++ " Create buffer local mappings for jumping to the tags and sorting the list ++ nnoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ nnoremap o ++ \ :call Tlist_Window_Jump_To_Tag('newwin') ++ nnoremap p ++ \ :call Tlist_Window_Jump_To_Tag('preview') ++ nnoremap P ++ \ :call Tlist_Window_Jump_To_Tag('prevwin') ++ if v:version >= 700 ++ nnoremap t ++ \ :call Tlist_Window_Jump_To_Tag('checktab') ++ nnoremap ++ \ :call Tlist_Window_Jump_To_Tag('newtab') ++ endif ++ nnoremap <2-LeftMouse> ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ nnoremap s ++ \ :call Tlist_Change_Sort('cmd', 'toggle', '') ++ nnoremap + :silent! foldopen ++ nnoremap - :silent! foldclose ++ nnoremap * :silent! %foldopen! ++ nnoremap = :silent! %foldclose ++ nnoremap :silent! foldopen ++ nnoremap :silent! foldclose ++ nnoremap :silent! %foldopen! ++ nnoremap :call Tlist_Window_Show_Info() ++ nnoremap u :call Tlist_Window_Update_File() ++ nnoremap d :call Tlist_Remove_File(-1, 1) ++ nnoremap x :call Tlist_Window_Zoom() ++ nnoremap [[ :call Tlist_Window_Move_To_File(-1) ++ nnoremap :call Tlist_Window_Move_To_File(-1) ++ nnoremap ]] :call Tlist_Window_Move_To_File(1) ++ nnoremap :call Tlist_Window_Move_To_File(1) ++ nnoremap :call Tlist_Window_Toggle_Help_Text() ++ nnoremap q :close ++ ++ " Insert mode mappings ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ " Windows needs return ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ inoremap o ++ \ :call Tlist_Window_Jump_To_Tag('newwin') ++ inoremap p ++ \ :call Tlist_Window_Jump_To_Tag('preview') ++ inoremap P ++ \ :call Tlist_Window_Jump_To_Tag('prevwin') ++ if v:version >= 700 ++ inoremap t ++ \ :call Tlist_Window_Jump_To_Tag('checktab') ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('newtab') ++ endif ++ inoremap <2-LeftMouse> ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ inoremap s ++ \ :call Tlist_Change_Sort('cmd', 'toggle', '') ++ inoremap + :silent! foldopen ++ inoremap - :silent! foldclose ++ inoremap * :silent! %foldopen! ++ inoremap = :silent! %foldclose ++ inoremap :silent! foldopen ++ inoremap :silent! foldclose ++ inoremap :silent! %foldopen! ++ inoremap :call ++ \ Tlist_Window_Show_Info() ++ inoremap u ++ \ :call Tlist_Window_Update_File() ++ inoremap d :call Tlist_Remove_File(-1, 1) ++ inoremap x :call Tlist_Window_Zoom() ++ inoremap [[ :call Tlist_Window_Move_To_File(-1) ++ inoremap :call Tlist_Window_Move_To_File(-1) ++ inoremap ]] :call Tlist_Window_Move_To_File(1) ++ inoremap :call Tlist_Window_Move_To_File(1) ++ inoremap :call Tlist_Window_Toggle_Help_Text() ++ inoremap q :close ++ ++ " Map single left mouse click if the user wants this functionality ++ if g:Tlist_Use_SingleClick == 1 ++ " Contributed by Bindu Wavell ++ " attempt to perform single click mapping, it would be much ++ " nicer if we could nnoremap ... however vim does ++ " not fire the when you use the mouse ++ " to enter a buffer. ++ let clickmap = ':if bufname("%") =~ "__Tag_List__" ' . ++ \ 'call Tlist_Window_Jump_To_Tag("useopen") ' . ++ \ ' endif ' ++ if maparg('', 'n') == '' ++ " no mapping for leftmouse ++ exe ':nnoremap ' . clickmap ++ else ++ " we have a mapping ++ let mapcmd = ':nnoremap ' ++ let mapcmd = mapcmd . substitute(substitute( ++ \ maparg('', 'n'), '|', '', 'g'), ++ \ '\c^', '', '') ++ let mapcmd = mapcmd . clickmap ++ exe mapcmd ++ endif ++ endif ++ ++ " Define the taglist autocommands ++ augroup TagListAutoCmds ++ autocmd! ++ " Display the tag prototype for the tag under the cursor. ++ autocmd CursorHold __Tag_List__ call s:Tlist_Window_Show_Info() ++ " Highlight the current tag periodically ++ autocmd CursorHold * silent call s:Tlist_Window_Highlight_Tag( ++ \ fnamemodify(bufname('%'), ':p'), line('.'), 1, 0) ++ ++ " Adjust the Vim window width when taglist window is closed ++ autocmd BufUnload __Tag_List__ call s:Tlist_Post_Close_Cleanup() ++ " Close the fold for this buffer when leaving the buffer ++ if g:Tlist_File_Fold_Auto_Close ++ autocmd BufEnter * silent ++ \ call s:Tlist_Window_Open_File_Fold(expand('')) ++ endif ++ " Exit Vim itself if only the taglist window is present (optional) ++ if g:Tlist_Exit_OnlyWindow ++ autocmd BufEnter __Tag_List__ nested ++ \ call s:Tlist_Window_Exit_Only_Window() ++ endif ++ if s:tlist_app_name != "winmanager" && ++ \ !g:Tlist_Process_File_Always && ++ \ (!has('gui_running') || !g:Tlist_Show_Menu) ++ " Auto refresh the taglist window ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ ++ if !g:Tlist_Use_Horiz_Window ++ if v:version < 700 ++ autocmd WinEnter * call s:Tlist_Window_Check_Width() ++ endif ++ endif ++ augroup end ++ ++ " Restore the previous cpoptions settings ++ let &cpoptions = old_cpoptions ++endfunction ++ ++" Tlist_Window_Refresh ++" Display the tags for all the files in the taglist window ++function! s:Tlist_Window_Refresh() ++ call s:Tlist_Log_Msg('Tlist_Window_Refresh()') ++ " Set report option to a huge value to prevent informational messages ++ " while deleting the lines ++ let old_report = &report ++ set report=99999 ++ ++ " Mark the buffer as modifiable ++ setlocal modifiable ++ ++ " Delete the contents of the buffer to the black-hole register ++ silent! %delete _ ++ ++ " As we have cleared the taglist window, mark all the files ++ " as not visible ++ let i = 0 ++ while i < s:tlist_file_count ++ let s:tlist_{i}_visible = 0 ++ let i = i + 1 ++ endwhile ++ ++ if g:Tlist_Compact_Format == 0 ++ " Display help in non-compact mode ++ call s:Tlist_Window_Display_Help() ++ endif ++ ++ " Mark the buffer as not modifiable ++ setlocal nomodifiable ++ ++ " Restore the report option ++ let &report = old_report ++ ++ " If the tags for only one file should be displayed in the taglist ++ " window, then no need to add the tags here. The bufenter autocommand ++ " will add the tags for that file. ++ if g:Tlist_Show_One_File ++ return ++ endif ++ ++ " List all the tags for the previously processed files ++ " Do this only if taglist is configured to display tags for more than ++ " one file. Otherwise, when Tlist_Show_One_File is configured, ++ " tags for the wrong file will be displayed. ++ let i = 0 ++ while i < s:tlist_file_count ++ call s:Tlist_Window_Refresh_File(s:tlist_{i}_filename, ++ \ s:tlist_{i}_filetype) ++ let i = i + 1 ++ endwhile ++ ++ if g:Tlist_Auto_Update ++ " Add and list the tags for all buffers in the Vim buffer list ++ let i = 1 ++ let last_bufnum = bufnr('$') ++ while i <= last_bufnum ++ if buflisted(i) ++ let fname = fnamemodify(bufname(i), ':p') ++ let ftype = s:Tlist_Get_Buffer_Filetype(i) ++ " If the file doesn't support tag listing, skip it ++ if !s:Tlist_Skip_File(fname, ftype) ++ call s:Tlist_Window_Refresh_File(fname, ftype) ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++ endif ++ ++ " If Tlist_File_Fold_Auto_Close option is set, then close all the folds ++ if g:Tlist_File_Fold_Auto_Close ++ " Close all the folds ++ silent! %foldclose ++ endif ++ ++ " Move the cursor to the top of the taglist window ++ normal! gg ++endfunction ++ ++" Tlist_Post_Close_Cleanup() ++" Close the taglist window and adjust the Vim window width ++function! s:Tlist_Post_Close_Cleanup() ++ call s:Tlist_Log_Msg('Tlist_Post_Close_Cleanup()') ++ " Mark all the files as not visible ++ let i = 0 ++ while i < s:tlist_file_count ++ let s:tlist_{i}_visible = 0 ++ let i = i + 1 ++ endwhile ++ ++ " Remove the taglist autocommands ++ silent! autocmd! TagListAutoCmds ++ ++ " Clear all the highlights ++ match none ++ ++ silent! syntax clear TagListTitle ++ silent! syntax clear TagListComment ++ silent! syntax clear TagListTagScope ++ ++ " Remove the left mouse click mapping if it was setup initially ++ if g:Tlist_Use_SingleClick ++ if hasmapto('') ++ nunmap ++ endif ++ endif ++ ++ if s:tlist_app_name != "winmanager" ++ if g:Tlist_Use_Horiz_Window || g:Tlist_Inc_Winwidth == 0 || ++ \ s:tlist_winsize_chgd != 1 || ++ \ &columns < (80 + g:Tlist_WinWidth) ++ " No need to adjust window width if using horizontally split taglist ++ " window or if columns is less than 101 or if the user chose not to ++ " adjust the window width ++ else ++ " If the user didn't manually move the window, then restore the window ++ " position to the pre-taglist position ++ if s:tlist_pre_winx != -1 && s:tlist_pre_winy != -1 && ++ \ getwinposx() == s:tlist_winx && ++ \ getwinposy() == s:tlist_winy ++ exe 'winpos ' . s:tlist_pre_winx . ' ' . s:tlist_pre_winy ++ endif ++ ++ " Adjust the Vim window width ++ let &columns= &columns - (g:Tlist_WinWidth + 1) ++ endif ++ endif ++ ++ let s:tlist_winsize_chgd = -1 ++ ++ " Reset taglist state variables ++ if s:tlist_app_name == "winmanager" ++ let s:tlist_app_name = "none" ++ endif ++ let s:tlist_window_initialized = 0 ++endfunction ++ ++" Tlist_Window_Refresh_File() ++" List the tags defined in the specified file in a Vim window ++function! s:Tlist_Window_Refresh_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Window_Refresh_File (' . a:filename . ')') ++ " First check whether the file already exists ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx != -1 ++ let file_listed = 1 ++ else ++ let file_listed = 0 ++ endif ++ ++ if !file_listed ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(a:filename) ++ return ++ endif ++ endif ++ ++ if file_listed && s:tlist_{fidx}_visible ++ " Check whether the file tags are currently valid ++ if s:tlist_{fidx}_valid ++ " Goto the first line in the file ++ exe s:tlist_{fidx}_start ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ endif ++ return ++ endif ++ ++ " Discard and remove the tags for this file from display ++ call s:Tlist_Discard_TagInfo(fidx) ++ call s:Tlist_Window_Remove_File_From_Display(fidx) ++ endif ++ ++ " Process and generate a list of tags defined in the file ++ if !file_listed || !s:tlist_{fidx}_valid ++ let ret_fidx = s:Tlist_Process_File(a:filename, a:ftype) ++ if ret_fidx == -1 ++ return ++ endif ++ let fidx = ret_fidx ++ endif ++ ++ " Set report option to a huge value to prevent informational messages ++ " while adding lines to the taglist window ++ let old_report = &report ++ set report=99999 ++ ++ if g:Tlist_Show_One_File ++ " Remove the previous file ++ if s:tlist_cur_file_idx != -1 ++ call s:Tlist_Window_Remove_File_From_Display(s:tlist_cur_file_idx) ++ let s:tlist_{s:tlist_cur_file_idx}_visible = 0 ++ let s:tlist_{s:tlist_cur_file_idx}_start = 0 ++ let s:tlist_{s:tlist_cur_file_idx}_end = 0 ++ endif ++ let s:tlist_cur_file_idx = fidx ++ endif ++ ++ " Mark the buffer as modifiable ++ setlocal modifiable ++ ++ " Add new files to the end of the window. For existing files, add them at ++ " the same line where they were previously present. If the file is not ++ " visible, then add it at the end ++ if s:tlist_{fidx}_start == 0 || !s:tlist_{fidx}_visible ++ if g:Tlist_Compact_Format ++ let s:tlist_{fidx}_start = line('$') ++ else ++ let s:tlist_{fidx}_start = line('$') + 1 ++ endif ++ endif ++ ++ let s:tlist_{fidx}_visible = 1 ++ ++ " Goto the line where this file should be placed ++ if g:Tlist_Compact_Format ++ exe s:tlist_{fidx}_start ++ else ++ exe s:tlist_{fidx}_start - 1 ++ endif ++ ++ let txt = fnamemodify(s:tlist_{fidx}_filename, ':t') . ' (' . ++ \ fnamemodify(s:tlist_{fidx}_filename, ':p:h') . ')' ++ if g:Tlist_Compact_Format == 0 ++ silent! put =txt ++ else ++ silent! put! =txt ++ " Move to the next line ++ exe line('.') + 1 ++ endif ++ let file_start = s:tlist_{fidx}_start ++ ++ " Add the tag names grouped by tag type to the buffer with a title ++ let i = 1 ++ let ttype_cnt = s:tlist_{a:ftype}_count ++ while i <= ttype_cnt ++ let ttype = s:tlist_{a:ftype}_{i}_name ++ " Add the tag type only if there are tags for that type ++ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype ++ let ttype_txt = {fidx_ttype} ++ if ttype_txt != '' ++ let txt = ' ' . s:tlist_{a:ftype}_{i}_fullname ++ if g:Tlist_Compact_Format == 0 ++ let ttype_start_lnum = line('.') + 1 ++ silent! put =txt ++ else ++ let ttype_start_lnum = line('.') ++ silent! put! =txt ++ endif ++ silent! put =ttype_txt ++ ++ let {fidx_ttype}_offset = ttype_start_lnum - file_start ++ ++ " create a fold for this tag type ++ let fold_start = ttype_start_lnum ++ let fold_end = fold_start + {fidx_ttype}_count ++ exe fold_start . ',' . fold_end . 'fold' ++ ++ " Adjust the cursor position ++ if g:Tlist_Compact_Format == 0 ++ exe ttype_start_lnum + {fidx_ttype}_count ++ else ++ exe ttype_start_lnum + {fidx_ttype}_count + 1 ++ endif ++ ++ if g:Tlist_Compact_Format == 0 ++ " Separate the tag types by a empty line ++ silent! put ='' ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++ ++ if s:tlist_{fidx}_tag_count == 0 ++ if g:Tlist_Compact_Format == 0 ++ silent! put ='' ++ endif ++ endif ++ ++ let s:tlist_{fidx}_end = line('.') - 1 ++ ++ " Create a fold for the entire file ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold' ++ exe 'silent! ' . s:tlist_{fidx}_start . ',' . ++ \ s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Goto the starting line for this file, ++ exe s:tlist_{fidx}_start ++ ++ if s:tlist_app_name == "winmanager" ++ " To handle a bug in the winmanager plugin, add a space at the ++ " last line ++ call setline('$', ' ') ++ endif ++ ++ " Mark the buffer as not modifiable ++ setlocal nomodifiable ++ ++ " Restore the report option ++ let &report = old_report ++ ++ " Update the start and end line numbers for all the files following this ++ " file ++ let start = s:tlist_{fidx}_start ++ " include the empty line after the last line ++ if g:Tlist_Compact_Format ++ let end = s:tlist_{fidx}_end ++ else ++ let end = s:tlist_{fidx}_end + 1 ++ endif ++ call s:Tlist_Window_Update_Line_Offsets(fidx + 1, 1, end - start + 1) ++ ++ " Now that we have updated the taglist window, update the tags ++ " menu (if present) ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(1) ++ endif ++endfunction ++ ++" Tlist_Init_File ++" Initialize the variables for a new file ++function! s:Tlist_Init_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Init_File (' . a:filename . ')') ++ " Add new files at the end of the list ++ let fidx = s:tlist_file_count ++ let s:tlist_file_count = s:tlist_file_count + 1 ++ " Add the new file name to the taglist list of file names ++ let s:tlist_file_names = s:tlist_file_names . a:filename . "\n" ++ ++ " Initialize the file variables ++ let s:tlist_{fidx}_filename = a:filename ++ let s:tlist_{fidx}_sort_type = g:Tlist_Sort_Type ++ let s:tlist_{fidx}_filetype = a:ftype ++ let s:tlist_{fidx}_mtime = -1 ++ let s:tlist_{fidx}_start = 0 ++ let s:tlist_{fidx}_end = 0 ++ let s:tlist_{fidx}_valid = 0 ++ let s:tlist_{fidx}_visible = 0 ++ let s:tlist_{fidx}_tag_count = 0 ++ let s:tlist_{fidx}_menu_cmd = '' ++ ++ " Initialize the tag type variables ++ let i = 1 ++ while i <= s:tlist_{a:ftype}_count ++ let ttype = s:tlist_{a:ftype}_{i}_name ++ let s:tlist_{fidx}_{ttype} = '' ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = 0 ++ let i = i + 1 ++ endwhile ++ ++ return fidx ++endfunction ++ ++" Tlist_Get_Tag_Type_By_Tag ++" Return the tag type for the specified tag index ++function! s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) ++ let ttype_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_type' ++ ++ " Already parsed and have the tag name ++ if exists(ttype_var) ++ return {ttype_var} ++ endif ++ ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let {ttype_var} = s:Tlist_Extract_Tagtype(tag_line) ++ ++ return {ttype_var} ++endfunction ++ ++" Tlist_Get_Tag_Prototype ++function! s:Tlist_Get_Tag_Prototype(fidx, tidx) ++ let tproto_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_proto' ++ ++ " Already parsed and have the tag prototype ++ if exists(tproto_var) ++ return {tproto_var} ++ endif ++ ++ " Parse and extract the tag prototype ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = stridx(tag_line, '/^') + 2 ++ let end = stridx(tag_line, '/;"' . "\t") ++ if tag_line[end - 1] == '$' ++ let end = end -1 ++ endif ++ let tag_proto = strpart(tag_line, start, end - start) ++ let {tproto_var} = substitute(tag_proto, '\s*', '', '') ++ ++ return {tproto_var} ++endfunction ++ ++" Tlist_Get_Tag_SearchPat ++function! s:Tlist_Get_Tag_SearchPat(fidx, tidx) ++ let tpat_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_searchpat' ++ ++ " Already parsed and have the tag search pattern ++ if exists(tpat_var) ++ return {tpat_var} ++ endif ++ ++ " Parse and extract the tag search pattern ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = stridx(tag_line, '/^') + 2 ++ let end = stridx(tag_line, '/;"' . "\t") ++ if tag_line[end - 1] == '$' ++ let end = end -1 ++ endif ++ let {tpat_var} = '\V\^' . strpart(tag_line, start, end - start) . ++ \ (tag_line[end] == '$' ? '\$' : '') ++ ++ return {tpat_var} ++endfunction ++ ++" Tlist_Get_Tag_Linenum ++" Return the tag line number, given the tag index ++function! s:Tlist_Get_Tag_Linenum(fidx, tidx) ++ let tline_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_linenum' ++ ++ " Already parsed and have the tag line number ++ if exists(tline_var) ++ return {tline_var} ++ endif ++ ++ " Parse and extract the tag line number ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = strridx(tag_line, 'line:') + 5 ++ let end = strridx(tag_line, "\t") ++ if end < start ++ let {tline_var} = strpart(tag_line, start) + 0 ++ else ++ let {tline_var} = strpart(tag_line, start, end - start) + 0 ++ endif ++ ++ return {tline_var} ++endfunction ++ ++" Tlist_Parse_Tagline ++" Parse a tag line from the ctags output. Separate the tag output based on the ++" tag type and store it in the tag type variable. ++" The format of each line in the ctags output is: ++" ++" tag_namefile_nameex_cmd;"extension_fields ++" ++function! s:Tlist_Parse_Tagline(tag_line) ++ if a:tag_line == '' ++ " Skip empty lines ++ return ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Extract_Tagtype(a:tag_line) ++ ++ " Make sure the tag type is a valid and supported one ++ if ttype == '' || stridx(s:ctags_flags, ttype) == -1 ++ " Line is not in proper tags format or Tag type is not supported ++ return ++ endif ++ ++ " Update the total tag count ++ let s:tidx = s:tidx + 1 ++ ++ " The following variables are used to optimize this code. Vim is slow in ++ " using curly brace names. To reduce the amount of processing needed, the ++ " curly brace variables are pre-processed here ++ let fidx_tidx = 's:tlist_' . s:fidx . '_' . s:tidx ++ let fidx_ttype = 's:tlist_' . s:fidx . '_' . ttype ++ ++ " Update the count of this tag type ++ let ttype_idx = {fidx_ttype}_count + 1 ++ let {fidx_ttype}_count = ttype_idx ++ ++ " Store the ctags output for this tag ++ let {fidx_tidx}_tag = a:tag_line ++ ++ " Store the tag index and the tag type index (back pointers) ++ let {fidx_ttype}_{ttype_idx} = s:tidx ++ let {fidx_tidx}_ttype_idx = ttype_idx ++ ++ " Extract the tag name ++ let tag_name = strpart(a:tag_line, 0, stridx(a:tag_line, "\t")) ++ ++ " Extract the tag scope/prototype ++ if g:Tlist_Display_Prototype ++ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(s:fidx, s:tidx) ++ else ++ let ttxt = ' ' . tag_name ++ ++ " Add the tag scope, if it is available and is configured. Tag ++ " scope is the last field after the 'line:\t' field ++ if g:Tlist_Display_Tag_Scope ++ let tag_scope = s:Tlist_Extract_Tag_Scope(a:tag_line) ++ if tag_scope != '' ++ let ttxt = ttxt . ' [' . tag_scope . ']' ++ endif ++ endif ++ endif ++ ++ " Add this tag to the tag type variable ++ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n" ++ ++ " Save the tag name ++ let {fidx_tidx}_tag_name = tag_name ++endfunction ++ ++" Tlist_Process_File ++" Get the list of tags defined in the specified file and store them ++" in Vim variables. Returns the file index where the tags are stored. ++function! s:Tlist_Process_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Process_File (' . a:filename . ', ' . ++ \ a:ftype . ')') ++ " Check whether this file is supported ++ if s:Tlist_Skip_File(a:filename, a:ftype) ++ return -1 ++ endif ++ ++ " If the tag types for this filetype are not yet created, then create ++ " them now ++ let var = 's:tlist_' . a:ftype . '_count' ++ if !exists(var) ++ if s:Tlist_FileType_Init(a:ftype) == 0 ++ return -1 ++ endif ++ endif ++ ++ " If this file is already processed, then use the cached values ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ " First time, this file is loaded ++ let fidx = s:Tlist_Init_File(a:filename, a:ftype) ++ else ++ " File was previously processed. Discard the tag information ++ call s:Tlist_Discard_TagInfo(fidx) ++ endif ++ ++ let s:tlist_{fidx}_valid = 1 ++ ++ " Exuberant ctags arguments to generate a tag list ++ let ctags_args = ' -f - --format=2 --excmd=pattern --fields=nks ' ++ ++ " Form the ctags argument depending on the sort type ++ if s:tlist_{fidx}_sort_type == 'name' ++ let ctags_args = ctags_args . '--sort=yes' ++ else ++ let ctags_args = ctags_args . '--sort=no' ++ endif ++ ++ " Add the filetype specific arguments ++ let ctags_args = ctags_args . ' ' . s:tlist_{a:ftype}_ctags_args ++ ++ " Ctags command to produce output with regexp for locating the tags ++ let ctags_cmd = g:Tlist_Ctags_Cmd . ctags_args ++ let ctags_cmd = ctags_cmd . ' "' . a:filename . '"' ++ ++ if &shellxquote == '"' ++ " Double-quotes within double-quotes will not work in the ++ " command-line.If the 'shellxquote' option is set to double-quotes, ++ " then escape the double-quotes in the ctags command-line. ++ let ctags_cmd = escape(ctags_cmd, '"') ++ endif ++ ++ " In Windows 95, if not using cygwin, disable the 'shellslash' ++ " option. Otherwise, this will cause problems when running the ++ " ctags command. ++ if has('win95') && !has('win32unix') ++ let old_shellslash = &shellslash ++ set noshellslash ++ endif ++ ++ if has('win32') && !has('win32unix') && !has('win95') ++ \ && (&shell =~ 'cmd.exe') ++ " Windows does not correctly deal with commands that have more than 1 ++ " set of double quotes. It will strip them all resulting in: ++ " 'C:\Program' is not recognized as an internal or external command ++ " operable program or batch file. To work around this, place the ++ " command inside a batch file and call the batch file. ++ " Do this only on Win2K, WinXP and above. ++ " Contributed by: David Fishburn. ++ let s:taglist_tempfile = fnamemodify(tempname(), ':h') . ++ \ '\taglist.cmd' ++ exe 'redir! > ' . s:taglist_tempfile ++ silent echo ctags_cmd ++ redir END ++ ++ call s:Tlist_Log_Msg('Cmd inside batch file: ' . ctags_cmd) ++ let ctags_cmd = '"' . s:taglist_tempfile . '"' ++ endif ++ ++ call s:Tlist_Log_Msg('Cmd: ' . ctags_cmd) ++ ++ " Run ctags and get the tag list ++ let cmd_output = system(ctags_cmd) ++ ++ " Restore the value of the 'shellslash' option. ++ if has('win95') && !has('win32unix') ++ let &shellslash = old_shellslash ++ endif ++ ++ if exists('s:taglist_tempfile') ++ " Delete the temporary cmd file created on MS-Windows ++ call delete(s:taglist_tempfile) ++ endif ++ ++ " Handle errors ++ if v:shell_error ++ let msg = "Taglist: Failed to generate tags for " . a:filename ++ call s:Tlist_Warning_Msg(msg) ++ if cmd_output != '' ++ call s:Tlist_Warning_Msg(cmd_output) ++ endif ++ return fidx ++ endif ++ ++ " Store the modification time for the file ++ let s:tlist_{fidx}_mtime = getftime(a:filename) ++ ++ " No tags for current file ++ if cmd_output == '' ++ call s:Tlist_Log_Msg('No tags defined in ' . a:filename) ++ return fidx ++ endif ++ ++ call s:Tlist_Log_Msg('Generated tags information for ' . a:filename) ++ ++ if v:version > 601 ++ " The following script local variables are used by the ++ " Tlist_Parse_Tagline() function. ++ let s:ctags_flags = s:tlist_{a:ftype}_ctags_flags ++ let s:fidx = fidx ++ let s:tidx = 0 ++ ++ " Process the ctags output one line at a time. The substitute() ++ " command is used to parse the tag lines instead of using the ++ " matchstr()/stridx()/strpart() functions for performance reason ++ call substitute(cmd_output, "\\([^\n]\\+\\)\n", ++ \ '\=s:Tlist_Parse_Tagline(submatch(1))', 'g') ++ ++ " Save the number of tags for this file ++ let s:tlist_{fidx}_tag_count = s:tidx ++ ++ " The following script local variables are no longer needed ++ unlet! s:ctags_flags ++ unlet! s:tidx ++ unlet! s:fidx ++ else ++ " Due to a bug in Vim earlier than version 6.1, ++ " we cannot use substitute() to parse the ctags output. ++ " Instead the slow str*() functions are used ++ let ctags_flags = s:tlist_{a:ftype}_ctags_flags ++ let tidx = 0 ++ ++ while cmd_output != '' ++ " Extract one line at a time ++ let idx = stridx(cmd_output, "\n") ++ let one_line = strpart(cmd_output, 0, idx) ++ " Remove the line from the tags output ++ let cmd_output = strpart(cmd_output, idx + 1) ++ ++ if one_line == '' ++ " Line is not in proper tags format ++ continue ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Extract_Tagtype(one_line) ++ ++ " Make sure the tag type is a valid and supported one ++ if ttype == '' || stridx(ctags_flags, ttype) == -1 ++ " Line is not in proper tags format or Tag type is not ++ " supported ++ continue ++ endif ++ ++ " Update the total tag count ++ let tidx = tidx + 1 ++ ++ " The following variables are used to optimize this code. Vim is ++ " slow in using curly brace names. To reduce the amount of ++ " processing needed, the curly brace variables are pre-processed ++ " here ++ let fidx_tidx = 's:tlist_' . fidx . '_' . tidx ++ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype ++ ++ " Update the count of this tag type ++ let ttype_idx = {fidx_ttype}_count + 1 ++ let {fidx_ttype}_count = ttype_idx ++ ++ " Store the ctags output for this tag ++ let {fidx_tidx}_tag = one_line ++ ++ " Store the tag index and the tag type index (back pointers) ++ let {fidx_ttype}_{ttype_idx} = tidx ++ let {fidx_tidx}_ttype_idx = ttype_idx ++ ++ " Extract the tag name ++ let tag_name = strpart(one_line, 0, stridx(one_line, "\t")) ++ ++ " Extract the tag scope/prototype ++ if g:Tlist_Display_Prototype ++ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(fidx, tidx) ++ else ++ let ttxt = ' ' . tag_name ++ ++ " Add the tag scope, if it is available and is configured. Tag ++ " scope is the last field after the 'line:\t' field ++ if g:Tlist_Display_Tag_Scope ++ let tag_scope = s:Tlist_Extract_Tag_Scope(one_line) ++ if tag_scope != '' ++ let ttxt = ttxt . ' [' . tag_scope . ']' ++ endif ++ endif ++ endif ++ ++ " Add this tag to the tag type variable ++ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n" ++ ++ " Save the tag name ++ let {fidx_tidx}_tag_name = tag_name ++ endwhile ++ ++ " Save the number of tags for this file ++ let s:tlist_{fidx}_tag_count = tidx ++ endif ++ ++ call s:Tlist_Log_Msg('Processed ' . s:tlist_{fidx}_tag_count . ++ \ ' tags in ' . a:filename) ++ ++ return fidx ++endfunction ++ ++" Tlist_Update_File ++" Update the tags for a file (if needed) ++function! Tlist_Update_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Update_File (' . a:filename . ')') ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(a:filename, a:ftype) ++ return ++ endif ++ ++ " Convert the file name to a full path ++ let fname = fnamemodify(a:filename, ':p') ++ ++ " First check whether the file already exists ++ let fidx = s:Tlist_Get_File_Index(fname) ++ ++ if fidx != -1 && s:tlist_{fidx}_valid ++ " File exists and the tags are valid ++ " Check whether the file was modified after the last tags update ++ " If it is modified, then update the tags ++ if s:tlist_{fidx}_mtime == getftime(fname) ++ return ++ endif ++ else ++ " If the tags were removed previously based on a user request, ++ " as we are going to update the tags (based on the user request), ++ " remove the filename from the deleted list ++ call s:Tlist_Update_Remove_List(fname, 0) ++ endif ++ ++ " If the taglist window is opened, update it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ " Taglist window is not present. Just update the taglist ++ " and return ++ call s:Tlist_Process_File(fname, a:ftype) ++ else ++ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != -1 ++ " If tags for only one file are displayed and we are not ++ " updating the tags for that file, then no need to ++ " refresh the taglist window. Otherwise, the taglist ++ " window should be updated. ++ if s:tlist_{s:tlist_cur_file_idx}_filename != fname ++ call s:Tlist_Process_File(fname, a:ftype) ++ return ++ endif ++ endif ++ ++ " Save the current window number ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ " Save the cursor position ++ let save_line = line('.') ++ let save_col = col('.') ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(fname, a:ftype) ++ ++ " Restore the cursor position ++ if v:version >= 601 ++ call cursor(save_line, save_col) ++ else ++ exe save_line ++ exe 'normal! ' . save_col . '|' ++ endif ++ ++ if winnr() != save_winnr ++ " Go back to the original window ++ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') ++ endif ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(1) ++ endif ++endfunction ++ ++" Tlist_Window_Close ++" Close the taglist window ++function! s:Tlist_Window_Close() ++ call s:Tlist_Log_Msg('Tlist_Window_Close()') ++ " Make sure the taglist window exists ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Error: Taglist window is not open') ++ return ++ endif ++ ++ if winnr() == winnum ++ " Already in the taglist window. Close it and return ++ if winbufnr(2) != -1 ++ " If a window other than the taglist window is open, ++ " then only close the taglist window. ++ close ++ endif ++ else ++ " Goto the taglist window, close it and then come back to the ++ " original window ++ let curbufnr = bufnr('%') ++ exe winnum . 'wincmd w' ++ close ++ " Need to jump back to the original window only if we are not ++ " already in that window ++ let winnum = bufwinnr(curbufnr) ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Mark_File_Window ++" Mark the current window as the file window to use when jumping to a tag. ++" Only if the current window is a non-plugin, non-preview and non-taglist ++" window ++function! s:Tlist_Window_Mark_File_Window() ++ if getbufvar('%', '&buftype') == '' && !&previewwindow ++ let w:tlist_file_window = "yes" ++ endif ++endfunction ++ ++" Tlist_Window_Open ++" Open and refresh the taglist window ++function! s:Tlist_Window_Open() ++ call s:Tlist_Log_Msg('Tlist_Window_Open()') ++ " If the window is open, jump to it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Jump to the existing window ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ return ++ endif ++ ++ if s:tlist_app_name == "winmanager" ++ " Taglist plugin is no longer part of the winmanager app ++ let s:tlist_app_name = "none" ++ endif ++ ++ " Get the filename and filetype for the specified buffer ++ let curbuf_name = fnamemodify(bufname('%'), ':p') ++ let curbuf_ftype = getbufvar('%', '&filetype') ++ let cur_lnum = line('.') ++ ++ " Mark the current window as the desired window to open a file when a tag ++ " is selected. ++ call s:Tlist_Window_Mark_File_Window() ++ ++ " Open the taglist window ++ call s:Tlist_Window_Create() ++ ++ call s:Tlist_Window_Refresh() ++ ++ if g:Tlist_Show_One_File ++ " Add only the current buffer and file ++ " ++ " If the file doesn't support tag listing, skip it ++ if !s:Tlist_Skip_File(curbuf_name, curbuf_ftype) ++ call s:Tlist_Window_Refresh_File(curbuf_name, curbuf_ftype) ++ endif ++ endif ++ ++ if g:Tlist_File_Fold_Auto_Close ++ " Open the fold for the current file, as all the folds in ++ " the taglist window are closed ++ let fidx = s:Tlist_Get_File_Index(curbuf_name) ++ if fidx != -1 ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ endif ++ endif ++ ++ " Highlight the current tag ++ call s:Tlist_Window_Highlight_Tag(curbuf_name, cur_lnum, 1, 1) ++endfunction ++ ++" Tlist_Window_Toggle() ++" Open or close a taglist window ++function! s:Tlist_Window_Toggle() ++ call s:Tlist_Log_Msg('Tlist_Window_Toggle()') ++ " If taglist window is open then close it. ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ call s:Tlist_Window_Close() ++ return ++ endif ++ ++ call s:Tlist_Window_Open() ++ ++ " Go back to the original window, if Tlist_GainFocus_On_ToggleOpen is not ++ " set ++ if !g:Tlist_GainFocus_On_ToggleOpen ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++endfunction ++ ++" Tlist_Process_Filelist ++" Process multiple files. Each filename is separated by "\n" ++" Returns the number of processed files ++function! s:Tlist_Process_Filelist(file_names) ++ let flist = a:file_names ++ ++ " Enable lazy screen updates ++ let old_lazyredraw = &lazyredraw ++ set lazyredraw ++ ++ " Keep track of the number of processed files ++ let fcnt = 0 ++ ++ " Process one file at a time ++ while flist != '' ++ let nl_idx = stridx(flist, "\n") ++ let one_file = strpart(flist, 0, nl_idx) ++ ++ " Remove the filename from the list ++ let flist = strpart(flist, nl_idx + 1) ++ ++ if one_file == '' ++ continue ++ endif ++ ++ " Skip directories ++ if isdirectory(one_file) ++ continue ++ endif ++ ++ let ftype = s:Tlist_Get_Filetype(one_file) ++ ++ echon "\r " ++ echon "\rProcessing tags for " . fnamemodify(one_file, ':p:t') ++ ++ let fcnt = fcnt + 1 ++ ++ call Tlist_Update_File(one_file, ftype) ++ endwhile ++ ++ " Clear the displayed informational messages ++ echon "\r " ++ ++ " Restore the previous state ++ let &lazyredraw = old_lazyredraw ++ ++ return fcnt ++endfunction ++ ++" Tlist_Process_Dir ++" Process the files in a directory matching the specified pattern ++function! s:Tlist_Process_Dir(dir_name, pat) ++ let flist = glob(a:dir_name . '/' . a:pat) . "\n" ++ ++ let fcnt = s:Tlist_Process_Filelist(flist) ++ ++ let len = strlen(a:dir_name) ++ if a:dir_name[len - 1] == '\' || a:dir_name[len - 1] == '/' ++ let glob_expr = a:dir_name . '*' ++ else ++ let glob_expr = a:dir_name . '/*' ++ endif ++ let all_files = glob(glob_expr) . "\n" ++ ++ while all_files != '' ++ let nl_idx = stridx(all_files, "\n") ++ let one_file = strpart(all_files, 0, nl_idx) ++ ++ let all_files = strpart(all_files, nl_idx + 1) ++ if one_file == '' ++ continue ++ endif ++ ++ " Skip non-directory names ++ if !isdirectory(one_file) ++ continue ++ endif ++ ++ echon "\r " ++ echon "\rProcessing files in directory " . fnamemodify(one_file, ':t') ++ let fcnt = fcnt + s:Tlist_Process_Dir(one_file, a:pat) ++ endwhile ++ ++ return fcnt ++endfunction ++ ++" Tlist_Add_Files_Recursive ++" Add files recursively from a directory ++function! s:Tlist_Add_Files_Recursive(dir, ...) ++ let dir_name = fnamemodify(a:dir, ':p') ++ if !isdirectory(dir_name) ++ call s:Tlist_Warning_Msg('Error: ' . dir_name . ' is not a directory') ++ return ++ endif ++ ++ if a:0 == 1 ++ " User specified file pattern ++ let pat = a:1 ++ else ++ " Default file pattern ++ let pat = '*' ++ endif ++ ++ echon "\r " ++ echon "\rProcessing files in directory " . fnamemodify(dir_name, ':t') ++ let fcnt = s:Tlist_Process_Dir(dir_name, pat) ++ ++ echon "\rAdded " . fcnt . " files to the taglist" ++endfunction ++ ++" Tlist_Add_Files ++" Add the specified list of files to the taglist ++function! s:Tlist_Add_Files(...) ++ let flist = '' ++ let i = 1 ++ ++ " Get all the files matching the file patterns supplied as argument ++ while i <= a:0 ++ let flist = flist . glob(a:{i}) . "\n" ++ let i = i + 1 ++ endwhile ++ ++ if flist == '' ++ call s:Tlist_Warning_Msg('Error: No matching files are found') ++ return ++ endif ++ ++ let fcnt = s:Tlist_Process_Filelist(flist) ++ echon "\rAdded " . fcnt . " files to the taglist" ++endfunction ++ ++" Tlist_Extract_Tagtype ++" Extract the tag type from the tag text ++function! s:Tlist_Extract_Tagtype(tag_line) ++ " The tag type is after the tag prototype field. The prototype field ++ " ends with the /;"\t string. We add 4 at the end to skip the characters ++ " in this special string.. ++ let start = strridx(a:tag_line, '/;"' . "\t") + 4 ++ let end = strridx(a:tag_line, 'line:') - 1 ++ let ttype = strpart(a:tag_line, start, end - start) ++ ++ return ttype ++endfunction ++ ++" Tlist_Extract_Tag_Scope ++" Extract the tag scope from the tag text ++function! s:Tlist_Extract_Tag_Scope(tag_line) ++ let start = strridx(a:tag_line, 'line:') ++ let end = strridx(a:tag_line, "\t") ++ if end <= start ++ return '' ++ endif ++ ++ let tag_scope = strpart(a:tag_line, end + 1) ++ let tag_scope = strpart(tag_scope, stridx(tag_scope, ':') + 1) ++ ++ return tag_scope ++endfunction ++ ++" Tlist_Refresh() ++" Refresh the taglist ++function! s:Tlist_Refresh() ++ call s:Tlist_Log_Msg('Tlist_Refresh (Skip_Refresh = ' . ++ \ s:Tlist_Skip_Refresh . ', ' . bufname('%') . ')') ++ " If we are entering the buffer from one of the taglist functions, then ++ " no need to refresh the taglist window again. ++ if s:Tlist_Skip_Refresh ++ " We still need to update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++ return ++ endif ++ ++ " If part of the winmanager plugin and not configured to process ++ " tags always and not configured to display the tags menu, then return ++ if (s:tlist_app_name == 'winmanager') && !g:Tlist_Process_File_Always ++ \ && !g:Tlist_Show_Menu ++ return ++ endif ++ ++ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help ++ if &buftype != '' ++ return ++ endif ++ ++ let filename = fnamemodify(bufname('%'), ':p') ++ let ftype = &filetype ++ ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(filename, ftype) ++ return ++ endif ++ ++ let tlist_win = bufwinnr(g:TagList_title) ++ ++ " If the taglist window is not opened and not configured to process ++ " tags always and not displaying the tags menu, then return ++ if tlist_win == -1 && !g:Tlist_Process_File_Always && !g:Tlist_Show_Menu ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(filename) ++ return ++ endif ++ ++ " If the taglist should not be auto updated, then return ++ if !g:Tlist_Auto_Update ++ return ++ endif ++ endif ++ ++ let cur_lnum = line('.') ++ ++ if fidx == -1 ++ " Update the tags for the file ++ let fidx = s:Tlist_Process_File(filename, ftype) ++ else ++ let mtime = getftime(filename) ++ if s:tlist_{fidx}_mtime != mtime ++ " Invalidate the tags listed for this file ++ let s:tlist_{fidx}_valid = 0 ++ ++ " Update the taglist and the window ++ call Tlist_Update_File(filename, ftype) ++ ++ " Store the new file modification time ++ let s:tlist_{fidx}_mtime = mtime ++ endif ++ endif ++ ++ " Update the taglist window ++ if tlist_win != -1 ++ " Disable screen updates ++ let old_lazyredraw = &lazyredraw ++ set nolazyredraw ++ ++ " Save the current window number ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ if !g:Tlist_Auto_Highlight_Tag || !g:Tlist_Highlight_Tag_On_BufEnter ++ " Save the cursor position ++ let save_line = line('.') ++ let save_col = col('.') ++ endif ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(filename, ftype) ++ ++ " Open the fold for the file ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ ++ if g:Tlist_Highlight_Tag_On_BufEnter && g:Tlist_Auto_Highlight_Tag ++ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != fidx ++ " If displaying tags for only one file in the taglist ++ " window and about to display the tags for a new file, ++ " then center the current tag line for the new file ++ let center_tag_line = 1 ++ else ++ let center_tag_line = 0 ++ endif ++ ++ " Highlight the current tag ++ call s:Tlist_Window_Highlight_Tag(filename, cur_lnum, 1, center_tag_line) ++ else ++ " Restore the cursor position ++ if v:version >= 601 ++ call cursor(save_line, save_col) ++ else ++ exe save_line ++ exe 'normal! ' . save_col . '|' ++ endif ++ endif ++ ++ " Jump back to the original window ++ if save_winnr != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') ++ endif ++ ++ " Restore screen updates ++ let &lazyredraw = old_lazyredraw ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++endfunction ++ ++" Tlist_Change_Sort() ++" Change the sort order of the tag listing ++" caller == 'cmd', command used in the taglist window ++" caller == 'menu', taglist menu ++" action == 'toggle', toggle sort from name to order and vice versa ++" action == 'set', set the sort order to sort_type ++function! s:Tlist_Change_Sort(caller, action, sort_type) ++ call s:Tlist_Log_Msg('Tlist_Change_Sort (caller = ' . a:caller . ++ \ ', action = ' . a:action . ', sort_type = ' . a:sort_type . ')') ++ if a:caller == 'cmd' ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ " Remove the previous highlighting ++ match none ++ elseif a:caller == 'menu' ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx == -1 ++ return ++ endif ++ endif ++ ++ if a:action == 'toggle' ++ let sort_type = s:tlist_{fidx}_sort_type ++ ++ " Toggle the sort order from 'name' to 'order' and vice versa ++ if sort_type == 'name' ++ let s:tlist_{fidx}_sort_type = 'order' ++ else ++ let s:tlist_{fidx}_sort_type = 'name' ++ endif ++ else ++ let s:tlist_{fidx}_sort_type = a:sort_type ++ endif ++ ++ " Invalidate the tags listed for this file ++ let s:tlist_{fidx}_valid = 0 ++ ++ if a:caller == 'cmd' ++ " Save the current line for later restoration ++ let curline = '\V\^' . getline('.') . '\$' ++ ++ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, ++ \ s:tlist_{fidx}_filetype) ++ ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Go back to the cursor line before the tag list is sorted ++ call search(curline, 'w') ++ ++ call s:Tlist_Menu_Update_File(1) ++ else ++ call s:Tlist_Menu_Remove_File() ++ ++ call s:Tlist_Refresh() ++ endif ++endfunction ++ ++" Tlist_Update_Current_File() ++" Update taglist for the current buffer by regenerating the tag list ++" Contributed by WEN Guopeng. ++function! s:Tlist_Update_Current_File() ++ call s:Tlist_Log_Msg('Tlist_Update_Current_File()') ++ if winnr() == bufwinnr(g:TagList_title) ++ " In the taglist window. Update the current file ++ call s:Tlist_Window_Update_File() ++ else ++ " Not in the taglist window. Update the current buffer ++ let filename = fnamemodify(bufname('%'), ':p') ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx != -1 ++ let s:tlist_{fidx}_valid = 0 ++ endif ++ call Tlist_Update_File(filename, &filetype) ++ endif ++endfunction ++ ++" Tlist_Window_Update_File() ++" Update the tags displayed in the taglist window ++function! s:Tlist_Window_Update_File() ++ call s:Tlist_Log_Msg('Tlist_Window_Update_File()') ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ " Remove the previous highlighting ++ match none ++ ++ " Save the current line for later restoration ++ let curline = '\V\^' . getline('.') . '\$' ++ ++ let s:tlist_{fidx}_valid = 0 ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, ++ \ s:tlist_{fidx}_filetype) ++ ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Go back to the tag line before the list is updated ++ call search(curline, 'w') ++endfunction ++ ++" Tlist_Window_Get_Tag_Type_By_Linenum() ++" Return the tag type index for the specified line in the taglist window ++function! s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum) ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ " Determine to which tag type the current line number belongs to using the ++ " tag type start line number and the number of tags in a tag type ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ let start_lnum = ++ \ s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset ++ let end = start_lnum + s:tlist_{a:fidx}_{ttype}_count ++ if a:lnum >= start_lnum && a:lnum <= end ++ break ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Current line doesn't belong to any of the displayed tag types ++ if i > s:tlist_{ftype}_count ++ return '' ++ endif ++ ++ return ttype ++endfunction ++ ++" Tlist_Window_Get_Tag_Index() ++" Return the tag index for the specified line in the taglist window ++function! s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(a:fidx, a:lnum) ++ ++ " Current line doesn't belong to any of the displayed tag types ++ if ttype == '' ++ return 0 ++ endif ++ ++ " Compute the index into the displayed tags for the tag type ++ let ttype_lnum = s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset ++ let tidx = a:lnum - ttype_lnum ++ if tidx == 0 ++ return 0 ++ endif ++ ++ " Get the corresponding tag line and return it ++ return s:tlist_{a:fidx}_{ttype}_{tidx} ++endfunction ++ ++" Tlist_Window_Highlight_Line ++" Highlight the current line ++function! s:Tlist_Window_Highlight_Line() ++ " Clear previously selected name ++ match none ++ ++ " Highlight the current line ++ if g:Tlist_Display_Prototype == 0 ++ let pat = '/\%' . line('.') . 'l\s\+\zs.*/' ++ else ++ let pat = '/\%' . line('.') . 'l.*/' ++ endif ++ ++ exe 'match TagListTagName ' . pat ++endfunction ++ ++" Tlist_Window_Open_File ++" Open the specified file in either a new window or an existing window ++" and place the cursor at the specified tag pattern ++function! s:Tlist_Window_Open_File(win_ctrl, filename, tagpat) ++ call s:Tlist_Log_Msg('Tlist_Window_Open_File (' . a:filename . ',' . ++ \ a:win_ctrl . ')') ++ let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh ++ let s:Tlist_Skip_Refresh = 1 ++ ++ if s:tlist_app_name == "winmanager" ++ " Let the winmanager edit the file ++ call WinManagerFileEdit(a:filename, a:win_ctrl == 'newwin') ++ else ++ ++ if a:win_ctrl == 'newtab' ++ " Create a new tab ++ exe 'tabnew ' . escape(a:filename, ' ') ++ " Open the taglist window in the new tab ++ call s:Tlist_Window_Open() ++ endif ++ ++ if a:win_ctrl == 'checktab' ++ " Check whether the file is present in any of the tabs. ++ " If the file is present in the current tab, then use the ++ " current tab. ++ if bufwinnr(a:filename) != -1 ++ let file_present_in_tab = 1 ++ let i = tabpagenr() ++ else ++ let i = 1 ++ let bnum = bufnr(a:filename) ++ let file_present_in_tab = 0 ++ while i <= tabpagenr('$') ++ if index(tabpagebuflist(i), bnum) != -1 ++ let file_present_in_tab = 1 ++ break ++ endif ++ let i += 1 ++ endwhile ++ endif ++ ++ if file_present_in_tab ++ " Goto the tab containing the file ++ exe 'tabnext ' . i ++ else ++ " Open a new tab ++ exe 'tabnew ' . escape(a:filename, ' ') ++ ++ " Open the taglist window ++ call s:Tlist_Window_Open() ++ endif ++ endif ++ ++ let winnum = -1 ++ if a:win_ctrl == 'prevwin' ++ " Open the file in the previous window, if it is usable ++ let cur_win = winnr() ++ wincmd p ++ if &buftype == '' && !&previewwindow ++ exe "edit " . escape(a:filename, ' ') ++ let winnum = winnr() ++ else ++ " Previous window is not usable ++ exe cur_win . 'wincmd w' ++ endif ++ endif ++ ++ " Goto the window containing the file. If the window is not there, open a ++ " new window ++ if winnum == -1 ++ let winnum = bufwinnr(a:filename) ++ endif ++ ++ if winnum == -1 ++ " Locate the previously used window for opening a file ++ let fwin_num = 0 ++ let first_usable_win = 0 ++ ++ let i = 1 ++ let bnum = winbufnr(i) ++ while bnum != -1 ++ if getwinvar(i, 'tlist_file_window') == 'yes' ++ let fwin_num = i ++ break ++ endif ++ if first_usable_win == 0 && ++ \ getbufvar(bnum, '&buftype') == '' && ++ \ !getwinvar(i, '&previewwindow') ++ " First non-taglist, non-plugin and non-preview window ++ let first_usable_win = i ++ endif ++ let i = i + 1 ++ let bnum = winbufnr(i) ++ endwhile ++ ++ " If a previously used window is not found, then use the first ++ " non-taglist window ++ if fwin_num == 0 ++ let fwin_num = first_usable_win ++ endif ++ ++ if fwin_num != 0 ++ " Jump to the file window ++ exe fwin_num . "wincmd w" ++ ++ " If the user asked to jump to the tag in a new window, then split ++ " the existing window into two. ++ if a:win_ctrl == 'newwin' ++ split ++ endif ++ exe "edit " . escape(a:filename, ' ') ++ else ++ " Open a new window ++ if g:Tlist_Use_Horiz_Window ++ exe 'leftabove split ' . escape(a:filename, ' ') ++ else ++ if winbufnr(2) == -1 ++ " Only the taglist window is present ++ if g:Tlist_Use_Right_Window ++ exe 'leftabove vertical split ' . ++ \ escape(a:filename, ' ') ++ else ++ exe 'rightbelow vertical split ' . ++ \ escape(a:filename, ' ') ++ endif ++ ++ " Go to the taglist window to change the window size to ++ " the user configured value ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ if g:Tlist_Use_Horiz_Window ++ exe 'resize ' . g:Tlist_WinHeight ++ else ++ exe 'vertical resize ' . g:Tlist_WinWidth ++ endif ++ " Go back to the file window ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ else ++ " A plugin or help window is also present ++ wincmd w ++ exe 'leftabove split ' . escape(a:filename, ' ') ++ endif ++ endif ++ endif ++ " Mark the window, so that it can be reused. ++ call s:Tlist_Window_Mark_File_Window() ++ else ++ if v:version >= 700 ++ " If the file is opened in more than one window, then check ++ " whether the last accessed window has the selected file. ++ " If it does, then use that window. ++ let lastwin_bufnum = winbufnr(winnr('#')) ++ if bufnr(a:filename) == lastwin_bufnum ++ let winnum = winnr('#') ++ endif ++ endif ++ exe winnum . 'wincmd w' ++ ++ " If the user asked to jump to the tag in a new window, then split the ++ " existing window into two. ++ if a:win_ctrl == 'newwin' ++ split ++ endif ++ endif ++ endif ++ ++ " Jump to the tag ++ if a:tagpat != '' ++ " Add the current cursor position to the jump list, so that user can ++ " jump back using the ' and ` marks. ++ mark ' ++ silent call search(a:tagpat, 'w') ++ ++ " Bring the line to the middle of the window ++ normal! z. ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ endif ++ ++ " If the user selects to preview the tag then jump back to the ++ " taglist window ++ if a:win_ctrl == 'preview' ++ " Go back to the taglist window ++ let winnum = bufwinnr(g:TagList_title) ++ exe winnum . 'wincmd w' ++ else ++ " If the user has selected to close the taglist window, when a ++ " tag is selected, close the taglist window ++ if g:Tlist_Close_On_Select ++ call s:Tlist_Window_Goto_Window() ++ close ++ ++ " Go back to the window displaying the selected file ++ let wnum = bufwinnr(a:filename) ++ if wnum != -1 && wnum != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds(wnum . 'wincmd w') ++ endif ++ endif ++ endif ++ ++ let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh ++endfunction ++ ++" Tlist_Window_Jump_To_Tag() ++" Jump to the location of the current tag ++" win_ctrl == useopen - Reuse the existing file window ++" win_ctrl == newwin - Open a new window ++" win_ctrl == preview - Preview the tag ++" win_ctrl == prevwin - Open in previous window ++" win_ctrl == newtab - Open in new tab ++function! s:Tlist_Window_Jump_To_Tag(win_ctrl) ++ call s:Tlist_Log_Msg('Tlist_Window_Jump_To_Tag(' . a:win_ctrl . ')') ++ " Do not process comment lines and empty lines ++ let curline = getline('.') ++ if curline =~ '^\s*$' || curline[0] == '"' ++ return ++ endif ++ ++ " If inside a closed fold, then use the first line of the fold ++ " and jump to the file. ++ let lnum = foldclosed('.') ++ if lnum == -1 ++ " Jump to the selected tag or file ++ let lnum = line('.') ++ else ++ " Open the closed fold ++ .foldopen! ++ endif ++ ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ if fidx == -1 ++ return ++ endif ++ ++ " Get the tag output for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ if tidx != 0 ++ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, tidx) ++ ++ " Highlight the tagline ++ call s:Tlist_Window_Highlight_Line() ++ else ++ " Selected a line which is not a tag name. Just edit the file ++ let tagpat = '' ++ endif ++ ++ call s:Tlist_Window_Open_File(a:win_ctrl, s:tlist_{fidx}_filename, tagpat) ++endfunction ++ ++" Tlist_Window_Show_Info() ++" Display information about the entry under the cursor ++function! s:Tlist_Window_Show_Info() ++ call s:Tlist_Log_Msg('Tlist_Window_Show_Info()') ++ ++ " Clear the previously displayed line ++ echo ++ ++ " Do not process comment lines and empty lines ++ let curline = getline('.') ++ if curline =~ '^\s*$' || curline[0] == '"' ++ return ++ endif ++ ++ " If inside a fold, then don't display the prototype ++ if foldclosed('.') != -1 ++ return ++ endif ++ ++ let lnum = line('.') ++ ++ " Get the file index ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ if fidx == -1 ++ return ++ endif ++ ++ if lnum == s:tlist_{fidx}_start ++ " Cursor is on a file name ++ let fname = s:tlist_{fidx}_filename ++ if strlen(fname) > 50 ++ let fname = fnamemodify(fname, ':t') ++ endif ++ echo fname . ', Filetype=' . s:tlist_{fidx}_filetype . ++ \ ', Tag count=' . s:tlist_{fidx}_tag_count ++ return ++ endif ++ ++ " Get the tag output line for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ if tidx == 0 ++ " Cursor is on a tag type ++ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum) ++ if ttype == '' ++ return ++ endif ++ ++ let ttype_name = '' ++ ++ let ftype = s:tlist_{fidx}_filetype ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ if ttype == s:tlist_{ftype}_{i}_name ++ let ttype_name = s:tlist_{ftype}_{i}_fullname ++ break ++ endif ++ let i = i + 1 ++ endwhile ++ ++ echo 'Tag type=' . ttype_name . ++ \ ', Tag count=' . s:tlist_{fidx}_{ttype}_count ++ return ++ endif ++ ++ " Get the tag search pattern and display it ++ echo s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Find_Nearest_Tag_Idx ++" Find the tag idx nearest to the supplied line number ++" Returns -1, if a tag couldn't be found for the specified line number ++function! s:Tlist_Find_Nearest_Tag_Idx(fidx, linenum) ++ let sort_type = s:tlist_{a:fidx}_sort_type ++ ++ let left = 1 ++ let right = s:tlist_{a:fidx}_tag_count ++ ++ if sort_type == 'order' ++ " Tags sorted by order, use a binary search. ++ " The idea behind this function is taken from the ctags.vim script (by ++ " Alexey Marinichev) available at the Vim online website. ++ ++ " If the current line is the less than the first tag, then no need to ++ " search ++ let first_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, 1) ++ ++ if a:linenum < first_lnum ++ return -1 ++ endif ++ ++ while left < right ++ let middle = (right + left + 1) / 2 ++ let middle_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, middle) ++ ++ if middle_lnum == a:linenum ++ let left = middle ++ break ++ endif ++ ++ if middle_lnum > a:linenum ++ let right = middle - 1 ++ else ++ let left = middle ++ endif ++ endwhile ++ else ++ " Tags sorted by name, use a linear search. (contributed by Dave ++ " Eggum). ++ " Look for a tag with a line number less than or equal to the supplied ++ " line number. If multiple tags are found, then use the tag with the ++ " line number closest to the supplied line number. IOW, use the tag ++ " with the highest line number. ++ let closest_lnum = 0 ++ let final_left = 0 ++ while left <= right ++ let lnum = s:Tlist_Get_Tag_Linenum(a:fidx, left) ++ ++ if lnum < a:linenum && lnum > closest_lnum ++ let closest_lnum = lnum ++ let final_left = left ++ elseif lnum == a:linenum ++ let closest_lnum = lnum ++ let final_left = left ++ break ++ else ++ let left = left + 1 ++ endif ++ endwhile ++ if closest_lnum == 0 ++ return -1 ++ endif ++ if left >= right ++ let left = final_left ++ endif ++ endif ++ ++ return left ++endfunction ++ ++" Tlist_Window_Highlight_Tag() ++" Highlight the current tag ++" cntx == 1, Called by the taglist plugin itself ++" cntx == 2, Forced by the user through the TlistHighlightTag command ++" center = 1, move the tag line to the center of the taglist window ++function! s:Tlist_Window_Highlight_Tag(filename, cur_lnum, cntx, center) ++ " Highlight the current tag only if the user configured the ++ " taglist plugin to do so or if the user explictly invoked the ++ " command to highlight the current tag. ++ if !g:Tlist_Auto_Highlight_Tag && a:cntx == 1 ++ return ++ endif ++ ++ if a:filename == '' ++ return ++ endif ++ ++ " Make sure the taglist window is present ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Error: Taglist window is not open') ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ return ++ endif ++ ++ " If the file is currently not displayed in the taglist window, then retrn ++ if !s:tlist_{fidx}_visible ++ return ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return ++ endif ++ ++ " Ignore all autocommands ++ let old_ei = &eventignore ++ set eventignore=all ++ ++ " Save the original window number ++ let org_winnr = winnr() ++ ++ if org_winnr == winnum ++ let in_taglist_window = 1 ++ else ++ let in_taglist_window = 0 ++ endif ++ ++ " Go to the taglist window ++ if !in_taglist_window ++ exe winnum . 'wincmd w' ++ endif ++ ++ " Clear previously selected name ++ match none ++ ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, a:cur_lnum) ++ if tidx == -1 ++ " Make sure the current tag line is visible in the taglist window. ++ " Calling the winline() function makes the line visible. Don't know ++ " of a better way to achieve this. ++ let lnum = line('.') ++ ++ if lnum < s:tlist_{fidx}_start || lnum > s:tlist_{fidx}_end ++ " Move the cursor to the beginning of the file ++ exe s:tlist_{fidx}_start ++ endif ++ ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ ++ call winline() ++ ++ if !in_taglist_window ++ exe org_winnr . 'wincmd w' ++ endif ++ ++ " Restore the autocommands ++ let &eventignore = old_ei ++ return ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) ++ ++ " Compute the line number ++ " Start of file + Start of tag type + offset ++ let lnum = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_offset + ++ \ s:tlist_{fidx}_{tidx}_ttype_idx ++ ++ " Goto the line containing the tag ++ exe lnum ++ ++ " Open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ ++ if a:center ++ " Move the tag line to the center of the taglist window ++ normal! z. ++ else ++ " Make sure the current tag line is visible in the taglist window. ++ " Calling the winline() function makes the line visible. Don't know ++ " of a better way to achieve this. ++ call winline() ++ endif ++ ++ " Highlight the tag name ++ call s:Tlist_Window_Highlight_Line() ++ ++ " Go back to the original window ++ if !in_taglist_window ++ exe org_winnr . 'wincmd w' ++ endif ++ ++ " Restore the autocommands ++ let &eventignore = old_ei ++ return ++endfunction ++ ++" Tlist_Get_Tag_Prototype_By_Line ++" Get the prototype for the tag on or before the specified line number in the ++" current buffer ++function! Tlist_Get_Tag_Prototype_By_Line(...) ++ if a:0 == 0 ++ " Arguments are not supplied. Use the current buffer name ++ " and line number ++ let filename = bufname('%') ++ let linenr = line('.') ++ elseif a:0 == 2 ++ " Filename and line number are specified ++ let filename = a:1 ++ let linenr = a:2 ++ if linenr !~ '\d\+' ++ " Invalid line number ++ return "" ++ endif ++ else ++ " Sufficient arguments are not supplied ++ let msg = 'Usage: Tlist_Get_Tag_Prototype_By_Line ' . ++ \ '' ++ call s:Tlist_Warning_Msg(msg) ++ return "" ++ endif ++ ++ " Expand the file to a fully qualified name ++ let filename = fnamemodify(filename, ':p') ++ if filename == '' ++ return "" ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ return "" ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return "" ++ endif ++ ++ " Get the tag text using the line number ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr) ++ if tidx == -1 ++ return "" ++ endif ++ ++ return s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Get_Tagname_By_Line ++" Get the tag name on or before the specified line number in the ++" current buffer ++function! Tlist_Get_Tagname_By_Line(...) ++ if a:0 == 0 ++ " Arguments are not supplied. Use the current buffer name ++ " and line number ++ let filename = bufname('%') ++ let linenr = line('.') ++ elseif a:0 == 2 ++ " Filename and line number are specified ++ let filename = a:1 ++ let linenr = a:2 ++ if linenr !~ '\d\+' ++ " Invalid line number ++ return "" ++ endif ++ else ++ " Sufficient arguments are not supplied ++ let msg = 'Usage: Tlist_Get_Tagname_By_Line ' ++ call s:Tlist_Warning_Msg(msg) ++ return "" ++ endif ++ ++ " Make sure the current file has a name ++ let filename = fnamemodify(filename, ':p') ++ if filename == '' ++ return "" ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ return "" ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return "" ++ endif ++ ++ " Get the tag name using the line number ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr) ++ if tidx == -1 ++ return "" ++ endif ++ ++ return s:tlist_{fidx}_{tidx}_tag_name ++endfunction ++ ++" Tlist_Window_Move_To_File ++" Move the cursor to the beginning of the current file or the next file ++" or the previous file in the taglist window ++" dir == -1, move to start of current or previous function ++" dir == 1, move to start of next function ++function! s:Tlist_Window_Move_To_File(dir) ++ if foldlevel('.') == 0 ++ " Cursor is on a non-folded line (it is not in any of the files) ++ " Move it to a folded line ++ if a:dir == -1 ++ normal! zk ++ else ++ " While moving down to the start of the next fold, ++ " no need to do go to the start of the next file. ++ normal! zj ++ return ++ endif ++ endif ++ ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ let cur_lnum = line('.') ++ ++ if a:dir == -1 ++ if cur_lnum > s:tlist_{fidx}_start ++ " Move to the beginning of the current file ++ exe s:tlist_{fidx}_start ++ return ++ endif ++ ++ if fidx != 0 ++ " Move to the beginning of the previous file ++ let fidx = fidx - 1 ++ else ++ " Cursor is at the first file, wrap around to the last file ++ let fidx = s:tlist_file_count - 1 ++ endif ++ ++ exe s:tlist_{fidx}_start ++ return ++ else ++ " Move to the beginning of the next file ++ let fidx = fidx + 1 ++ ++ if fidx >= s:tlist_file_count ++ " Cursor is at the last file, wrap around to the first file ++ let fidx = 0 ++ endif ++ ++ if s:tlist_{fidx}_start != 0 ++ exe s:tlist_{fidx}_start ++ endif ++ return ++ endif ++endfunction ++ ++" Tlist_Session_Load ++" Load a taglist session (information about all the displayed files ++" and the tags) from the specified file ++function! s:Tlist_Session_Load(...) ++ if a:0 == 0 || a:1 == '' ++ call s:Tlist_Warning_Msg('Usage: TlistSessionLoad ') ++ return ++ endif ++ ++ let sessionfile = a:1 ++ ++ if !filereadable(sessionfile) ++ let msg = 'Taglist: Error - Unable to open file ' . sessionfile ++ call s:Tlist_Warning_Msg(msg) ++ return ++ endif ++ ++ " Mark the current window as the file window ++ call s:Tlist_Window_Mark_File_Window() ++ ++ " Source the session file ++ exe 'source ' . sessionfile ++ ++ let new_file_count = g:tlist_file_count ++ unlet! g:tlist_file_count ++ ++ let i = 0 ++ while i < new_file_count ++ let ftype = g:tlist_{i}_filetype ++ unlet! g:tlist_{i}_filetype ++ ++ if !exists('s:tlist_' . ftype . '_count') ++ if s:Tlist_FileType_Init(ftype) == 0 ++ let i = i + 1 ++ continue ++ endif ++ endif ++ ++ let fname = g:tlist_{i}_filename ++ unlet! g:tlist_{i}_filename ++ ++ let fidx = s:Tlist_Get_File_Index(fname) ++ if fidx != -1 ++ let s:tlist_{fidx}_visible = 0 ++ let i = i + 1 ++ continue ++ else ++ " As we are loading the tags from the session file, if this ++ " file was previously deleted by the user, now we need to ++ " add it back. So remove the file from the deleted list. ++ call s:Tlist_Update_Remove_List(fname, 0) ++ endif ++ ++ let fidx = s:Tlist_Init_File(fname, ftype) ++ ++ let s:tlist_{fidx}_filename = fname ++ ++ let s:tlist_{fidx}_sort_type = g:tlist_{i}_sort_type ++ unlet! g:tlist_{i}_sort_type ++ ++ let s:tlist_{fidx}_filetype = ftype ++ let s:tlist_{fidx}_mtime = getftime(fname) ++ ++ let s:tlist_{fidx}_start = 0 ++ let s:tlist_{fidx}_end = 0 ++ ++ let s:tlist_{fidx}_valid = 1 ++ ++ let s:tlist_{fidx}_tag_count = g:tlist_{i}_tag_count ++ unlet! g:tlist_{i}_tag_count ++ ++ let j = 1 ++ while j <= s:tlist_{fidx}_tag_count ++ let s:tlist_{fidx}_{j}_tag = g:tlist_{i}_{j}_tag ++ let s:tlist_{fidx}_{j}_tag_name = g:tlist_{i}_{j}_tag_name ++ let s:tlist_{fidx}_{j}_ttype_idx = g:tlist_{i}_{j}_ttype_idx ++ unlet! g:tlist_{i}_{j}_tag ++ unlet! g:tlist_{i}_{j}_tag_name ++ unlet! g:tlist_{i}_{j}_ttype_idx ++ let j = j + 1 ++ endwhile ++ ++ let j = 1 ++ while j <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{j}_name ++ ++ if exists('g:tlist_' . i . '_' . ttype) ++ let s:tlist_{fidx}_{ttype} = g:tlist_{i}_{ttype} ++ unlet! g:tlist_{i}_{ttype} ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = g:tlist_{i}_{ttype}_count ++ unlet! g:tlist_{i}_{ttype}_count ++ ++ let k = 1 ++ while k <= s:tlist_{fidx}_{ttype}_count ++ let s:tlist_{fidx}_{ttype}_{k} = g:tlist_{i}_{ttype}_{k} ++ unlet! g:tlist_{i}_{ttype}_{k} ++ let k = k + 1 ++ endwhile ++ else ++ let s:tlist_{fidx}_{ttype} = '' ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = 0 ++ endif ++ ++ let j = j + 1 ++ endwhile ++ ++ let i = i + 1 ++ endwhile ++ ++ " If the taglist window is open, then update it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ " Refresh the taglist window ++ call s:Tlist_Window_Refresh() ++ ++ " Go back to the original window ++ if save_winnr != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ endif ++endfunction ++ ++" Tlist_Session_Save ++" Save a taglist session (information about all the displayed files ++" and the tags) into the specified file ++function! s:Tlist_Session_Save(...) ++ if a:0 == 0 || a:1 == '' ++ call s:Tlist_Warning_Msg('Usage: TlistSessionSave ') ++ return ++ endif ++ ++ let sessionfile = a:1 ++ ++ if s:tlist_file_count == 0 ++ " There is nothing to save ++ call s:Tlist_Warning_Msg('Warning: Taglist is empty. Nothing to save.') ++ return ++ endif ++ ++ if filereadable(sessionfile) ++ let ans = input('Do you want to overwrite ' . sessionfile . ' (Y/N)?') ++ if ans !=? 'y' ++ return ++ endif ++ ++ echo "\n" ++ endif ++ ++ let old_verbose = &verbose ++ set verbose&vim ++ ++ exe 'redir! > ' . sessionfile ++ ++ silent! echo '" Taglist session file. This file is auto-generated.' ++ silent! echo '" File information' ++ silent! echo 'let tlist_file_count = ' . s:tlist_file_count ++ ++ let i = 0 ++ ++ while i < s:tlist_file_count ++ " Store information about the file ++ silent! echo 'let tlist_' . i . "_filename = '" . ++ \ s:tlist_{i}_filename . "'" ++ silent! echo 'let tlist_' . i . '_sort_type = "' . ++ \ s:tlist_{i}_sort_type . '"' ++ silent! echo 'let tlist_' . i . '_filetype = "' . ++ \ s:tlist_{i}_filetype . '"' ++ silent! echo 'let tlist_' . i . '_tag_count = ' . ++ \ s:tlist_{i}_tag_count ++ " Store information about all the tags ++ let j = 1 ++ while j <= s:tlist_{i}_tag_count ++ let txt = escape(s:tlist_{i}_{j}_tag, '"\\') ++ silent! echo 'let tlist_' . i . '_' . j . '_tag = "' . txt . '"' ++ silent! echo 'let tlist_' . i . '_' . j . '_tag_name = "' . ++ \ s:tlist_{i}_{j}_tag_name . '"' ++ silent! echo 'let tlist_' . i . '_' . j . '_ttype_idx' . ' = ' . ++ \ s:tlist_{i}_{j}_ttype_idx ++ let j = j + 1 ++ endwhile ++ ++ " Store information about all the tags grouped by their type ++ let ftype = s:tlist_{i}_filetype ++ let j = 1 ++ while j <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{j}_name ++ if s:tlist_{i}_{ttype}_count != 0 ++ let txt = substitute(s:tlist_{i}_{ttype}, "\n", "\\\\n", 'g') ++ silent! echo 'let tlist_' . i . '_' . ttype . ' = "' . ++ \ txt . '"' ++ silent! echo 'let tlist_' . i . '_' . ttype . '_count = ' . ++ \ s:tlist_{i}_{ttype}_count ++ let k = 1 ++ while k <= s:tlist_{i}_{ttype}_count ++ silent! echo 'let tlist_' . i . '_' . ttype . '_' . k . ++ \ ' = ' . s:tlist_{i}_{ttype}_{k} ++ let k = k + 1 ++ endwhile ++ endif ++ let j = j + 1 ++ endwhile ++ ++ silent! echo ++ ++ let i = i + 1 ++ endwhile ++ ++ redir END ++ ++ let &verbose = old_verbose ++endfunction ++ ++" Tlist_Buffer_Removed ++" A buffer is removed from the Vim buffer list. Remove the tags defined ++" for that file ++function! s:Tlist_Buffer_Removed(filename) ++ call s:Tlist_Log_Msg('Tlist_Buffer_Removed (' . a:filename . ')') ++ ++ " Make sure a valid filename is supplied ++ if a:filename == '' ++ return ++ endif ++ ++ " Get tag list index of the specified file ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ " File not present in the taglist ++ return ++ endif ++ ++ " Remove the file from the list ++ call s:Tlist_Remove_File(fidx, 0) ++endfunction ++ ++" When a buffer is deleted, remove the file from the taglist ++autocmd BufDelete * silent call s:Tlist_Buffer_Removed(expand(':p')) ++ ++" Tlist_Window_Open_File_Fold ++" Open the fold for the specified file and close the fold for all the ++" other files ++function! s:Tlist_Window_Open_File_Fold(acmd_file) ++ call s:Tlist_Log_Msg('Tlist_Window_Open_File_Fold (' . a:acmd_file . ')') ++ ++ " Make sure the taglist window is present ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Taglist: Error - Taglist window is not open') ++ return ++ endif ++ ++ " Save the original window number ++ let org_winnr = winnr() ++ if org_winnr == winnum ++ let in_taglist_window = 1 ++ else ++ let in_taglist_window = 0 ++ endif ++ ++ if in_taglist_window ++ " When entering the taglist window, no need to update the folds ++ return ++ endif ++ ++ " Go to the taglist window ++ if !in_taglist_window ++ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') ++ endif ++ ++ " Close all the folds ++ silent! %foldclose ++ ++ " Get tag list index of the specified file ++ let fname = fnamemodify(a:acmd_file, ":p") ++ if filereadable(fname) ++ let fidx = s:Tlist_Get_File_Index(fname) ++ if fidx != -1 ++ " Open the fold for the file ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen" ++ endif ++ endif ++ ++ " Go back to the original window ++ if !in_taglist_window ++ call s:Tlist_Exe_Cmd_No_Acmds(org_winnr . 'wincmd w') ++ endif ++endfunction ++ ++" Tlist_Window_Check_Auto_Open ++" Open the taglist window automatically on Vim startup. ++" Open the window only when files present in any of the Vim windows support ++" tags. ++function! s:Tlist_Window_Check_Auto_Open() ++ let open_window = 0 ++ ++ let i = 1 ++ let buf_num = winbufnr(i) ++ while buf_num != -1 ++ let filename = fnamemodify(bufname(buf_num), ':p') ++ if !s:Tlist_Skip_File(filename, getbufvar(buf_num, '&filetype')) ++ let open_window = 1 ++ break ++ endif ++ let i = i + 1 ++ let buf_num = winbufnr(i) ++ endwhile ++ ++ if open_window ++ call s:Tlist_Window_Toggle() ++ endif ++endfunction ++ ++function! s:Tlist_Menu_Add_Base_Menu() ++ call s:Tlist_Log_Msg('Adding the base menu') ++ ++ " Add the menu ++ anoremenu T&ags.Refresh\ menu :call Tlist_Menu_Refresh() ++ anoremenu T&ags.Sort\ menu\ by.Name ++ \ :call Tlist_Change_Sort('menu', 'set', 'name') ++ anoremenu T&ags.Sort\ menu\ by.Order ++ \ :call Tlist_Change_Sort('menu', 'set', 'order') ++ anoremenu T&ags.-SEP1- : ++ ++ if &mousemodel =~ 'popup' ++ anoremenu PopUp.T&ags.Refresh\ menu ++ \ :call Tlist_Menu_Refresh() ++ anoremenu PopUp.T&ags.Sort\ menu\ by.Name ++ \ :call Tlist_Change_Sort('menu', 'set', 'name') ++ anoremenu PopUp.T&ags.Sort\ menu\ by.Order ++ \ :call Tlist_Change_Sort('menu', 'set', 'order') ++ anoremenu PopUp.T&ags.-SEP1- : ++ endif ++endfunction ++ ++let s:menu_char_prefix = ++ \ '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ++ ++" Tlist_Menu_Get_Tag_Type_Cmd ++" Get the menu command for the specified tag type ++" fidx - File type index ++" ftype - File Type ++" add_ttype_name - To add or not to add the tag type name to the menu entries ++" ttype_idx - Tag type index ++function! s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, ttype_idx) ++ " Curly brace variable name optimization ++ let ftype_ttype_idx = a:ftype . '_' . a:ttype_idx ++ ++ let ttype = s:tlist_{ftype_ttype_idx}_name ++ if a:add_ttype_name ++ " If the tag type name contains space characters, escape it. This ++ " will be used to create the menu entries. ++ let ttype_fullname = escape(s:tlist_{ftype_ttype_idx}_fullname, ' ') ++ endif ++ ++ " Curly brace variable name optimization ++ let fidx_ttype = a:fidx . '_' . ttype ++ ++ " Number of tag entries for this tag type ++ let tcnt = s:tlist_{fidx_ttype}_count ++ if tcnt == 0 " No entries for this tag type ++ return '' ++ endif ++ ++ let mcmd = '' ++ ++ " Create the menu items for the tags. ++ " Depending on the number of tags of this type, split the menu into ++ " multiple sub-menus, if needed. ++ if tcnt > g:Tlist_Max_Submenu_Items ++ let j = 1 ++ while j <= tcnt ++ let final_index = j + g:Tlist_Max_Submenu_Items - 1 ++ if final_index > tcnt ++ let final_index = tcnt ++ endif ++ ++ " Extract the first and last tag name and form the ++ " sub-menu name ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ let first_tag = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let tidx = s:tlist_{fidx_ttype}_{final_index} ++ let last_tag = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ " Truncate the names, if they are greater than the ++ " max length ++ let first_tag = strpart(first_tag, 0, g:Tlist_Max_Tag_Length) ++ let last_tag = strpart(last_tag, 0, g:Tlist_Max_Tag_Length) ++ ++ " Form the menu command prefix ++ let m_prefix = 'anoremenu T\&ags.' ++ if a:add_ttype_name ++ let m_prefix = m_prefix . ttype_fullname . '.' ++ endif ++ let m_prefix = m_prefix . first_tag . '\.\.\.' . last_tag . '.' ++ ++ " Character prefix used to number the menu items (hotkey) ++ let m_prefix_idx = 0 ++ ++ while j <= final_index ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ ++ let tname = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let mcmd = mcmd . m_prefix . '\&' . ++ \ s:menu_char_prefix[m_prefix_idx] . '\.' . ++ \ tname . ' :call Tlist_Menu_Jump_To_Tag(' . ++ \ tidx . ')|' ++ ++ let m_prefix_idx = m_prefix_idx + 1 ++ let j = j + 1 ++ endwhile ++ endwhile ++ else ++ " Character prefix used to number the menu items (hotkey) ++ let m_prefix_idx = 0 ++ ++ let m_prefix = 'anoremenu T\&ags.' ++ if a:add_ttype_name ++ let m_prefix = m_prefix . ttype_fullname . '.' ++ endif ++ let j = 1 ++ while j <= tcnt ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ ++ let tname = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let mcmd = mcmd . m_prefix . '\&' . ++ \ s:menu_char_prefix[m_prefix_idx] . '\.' . ++ \ tname . ' :call Tlist_Menu_Jump_To_Tag(' . tidx ++ \ . ')|' ++ ++ let m_prefix_idx = m_prefix_idx + 1 ++ let j = j + 1 ++ endwhile ++ endif ++ ++ return mcmd ++endfunction ++ ++" Update the taglist menu with the tags for the specified file ++function! s:Tlist_Menu_File_Refresh(fidx) ++ call s:Tlist_Log_Msg('Refreshing the tag menu for ' . s:tlist_{a:fidx}_filename) ++ " The 'B' flag is needed in the 'cpoptions' option ++ let old_cpoptions = &cpoptions ++ set cpoptions&vim ++ ++ exe s:tlist_{a:fidx}_menu_cmd ++ ++ " Update the popup menu (if enabled) ++ if &mousemodel =~ 'popup' ++ let cmd = substitute(s:tlist_{a:fidx}_menu_cmd, ' T\\&ags\.', ++ \ ' PopUp.T\\\&ags.', "g") ++ exe cmd ++ endif ++ ++ " The taglist menu is not empty now ++ let s:tlist_menu_empty = 0 ++ ++ " Restore the 'cpoptions' settings ++ let &cpoptions = old_cpoptions ++endfunction ++ ++" Tlist_Menu_Update_File ++" Add the taglist menu ++function! s:Tlist_Menu_Update_File(clear_menu) ++ if !has('gui_running') ++ " Not running in GUI mode ++ return ++ endif ++ ++ call s:Tlist_Log_Msg('Updating the tag menu, clear_menu = ' . a:clear_menu) ++ ++ " Remove the tags menu ++ if a:clear_menu ++ call s:Tlist_Menu_Remove_File() ++ ++ endif ++ ++ let fname = escape(fnamemodify(bufname('%'), ':t'), '.') ++ if fname != '' ++ exe 'anoremenu T&ags.' . fname . ' ' ++ anoremenu T&ags.-SEP2- : ++ endif ++ ++ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help ++ if &buftype != '' ++ return ++ endif ++ ++ let filename = fnamemodify(bufname('%'), ':p') ++ let ftype = &filetype ++ ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(filename, ftype) ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 || !s:tlist_{fidx}_valid ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(filename) ++ return ++ endif ++ ++ " Process the tags for the file ++ let fidx = s:Tlist_Process_File(filename, ftype) ++ if fidx == -1 ++ return ++ endif ++ endif ++ ++ if !s:tlist_{fidx}_tag_count ++ return ++ endif ++ ++ if s:tlist_{fidx}_menu_cmd != '' ++ " Update the menu with the cached command ++ call s:Tlist_Menu_File_Refresh(fidx) ++ ++ return ++ endif ++ ++ " We are going to add entries to the tags menu, so the menu won't be ++ " empty ++ let s:tlist_menu_empty = 0 ++ ++ let cmd = '' ++ ++ " Determine whether the tag type name needs to be added to the menu ++ " If more than one tag type is present in the taglisting for a file, ++ " then the tag type name needs to be present ++ let add_ttype_name = -1 ++ let i = 1 ++ while i <= s:tlist_{ftype}_count && add_ttype_name < 1 ++ let ttype = s:tlist_{ftype}_{i}_name ++ if s:tlist_{fidx}_{ttype}_count ++ let add_ttype_name = add_ttype_name + 1 ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Process the tags by the tag type and get the menu command ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let mcmd = s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, i) ++ if mcmd != '' ++ let cmd = cmd . mcmd ++ endif ++ ++ let i = i + 1 ++ endwhile ++ ++ " Cache the menu command for reuse ++ let s:tlist_{fidx}_menu_cmd = cmd ++ ++ " Update the menu ++ call s:Tlist_Menu_File_Refresh(fidx) ++endfunction ++ ++" Tlist_Menu_Remove_File ++" Remove the tags displayed in the tags menu ++function! s:Tlist_Menu_Remove_File() ++ if !has('gui_running') || s:tlist_menu_empty ++ return ++ endif ++ ++ call s:Tlist_Log_Msg('Removing the tags menu for a file') ++ ++ " Cleanup the Tags menu ++ silent! unmenu T&ags ++ if &mousemodel =~ 'popup' ++ silent! unmenu PopUp.T&ags ++ endif ++ ++ " Add a dummy menu item to retain teared off menu ++ noremenu T&ags.Dummy l ++ ++ silent! unmenu! T&ags ++ if &mousemodel =~ 'popup' ++ silent! unmenu! PopUp.T&ags ++ endif ++ ++ call s:Tlist_Menu_Add_Base_Menu() ++ ++ " Remove the dummy menu item ++ unmenu T&ags.Dummy ++ ++ let s:tlist_menu_empty = 1 ++endfunction ++ ++" Tlist_Menu_Refresh ++" Refresh the taglist menu ++function! s:Tlist_Menu_Refresh() ++ call s:Tlist_Log_Msg('Refreshing the tags menu') ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx != -1 ++ " Invalidate the cached menu command ++ let s:tlist_{fidx}_menu_cmd = '' ++ endif ++ ++ " Update the taglist, menu and window ++ call s:Tlist_Update_Current_File() ++endfunction ++ ++" Tlist_Menu_Jump_To_Tag ++" Jump to the selected tag ++function! s:Tlist_Menu_Jump_To_Tag(tidx) ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx == -1 ++ return ++ endif ++ ++ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, a:tidx) ++ if tagpat == '' ++ return ++ endif ++ ++ " Add the current cursor position to the jump list, so that user can ++ " jump back using the ' and ` marks. ++ mark ' ++ ++ silent call search(tagpat, 'w') ++ ++ " Bring the line to the middle of the window ++ normal! z. ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++endfunction ++ ++" Tlist_Menu_Init ++" Initialize the taglist menu ++function! s:Tlist_Menu_Init() ++ call s:Tlist_Menu_Add_Base_Menu() ++ ++ " Automatically add the tags defined in the current file to the menu ++ augroup TagListMenuCmds ++ autocmd! ++ ++ if !g:Tlist_Process_File_Always ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ autocmd BufLeave * call s:Tlist_Menu_Remove_File() ++ augroup end ++ ++ call s:Tlist_Menu_Update_File(0) ++endfunction ++ ++" Tlist_Vim_Session_Load ++" Initialize the taglist window/buffer, which is created when loading ++" a Vim session file. ++function! s:Tlist_Vim_Session_Load() ++ call s:Tlist_Log_Msg('Tlist_Vim_Session_Load') ++ ++ " Initialize the taglist window ++ call s:Tlist_Window_Init() ++ ++ " Refresh the taglist window ++ call s:Tlist_Window_Refresh() ++endfunction ++ ++" Tlist_Set_App ++" Set the name of the external plugin/application to which taglist ++" belongs. ++" Taglist plugin is part of another plugin like cream or winmanager. ++function! Tlist_Set_App(name) ++ if a:name == "" ++ return ++ endif ++ ++ let s:tlist_app_name = a:name ++endfunction ++ ++" Winmanager integration ++ ++" Initialization required for integration with winmanager ++function! TagList_Start() ++ " If current buffer is not taglist buffer, then don't proceed ++ if bufname('%') != '__Tag_List__' ++ return ++ endif ++ ++ call Tlist_Set_App('winmanager') ++ ++ " Get the current filename from the winmanager plugin ++ let bufnum = WinManagerGetLastEditedFile() ++ if bufnum != -1 ++ let filename = fnamemodify(bufname(bufnum), ':p') ++ let ftype = getbufvar(bufnum, '&filetype') ++ endif ++ ++ " Initialize the taglist window, if it is not already initialized ++ if !exists('s:tlist_window_initialized') || !s:tlist_window_initialized ++ call s:Tlist_Window_Init() ++ call s:Tlist_Window_Refresh() ++ let s:tlist_window_initialized = 1 ++ endif ++ ++ " Update the taglist window ++ if bufnum != -1 ++ if !s:Tlist_Skip_File(filename, ftype) && g:Tlist_Auto_Update ++ call s:Tlist_Window_Refresh_File(filename, ftype) ++ endif ++ endif ++endfunction ++ ++function! TagList_IsValid() ++ return 0 ++endfunction ++ ++function! TagList_WrapUp() ++ return 0 ++endfunction ++ ++" restore 'cpo' ++let &cpo = s:cpo_save ++unlet s:cpo_save ++ +diff -urN vim71/1/plugin/taglist.vim vim71_ada/1/plugin/taglist.vim +--- vim71/1/plugin/taglist.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/plugin/taglist.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,4524 @@ ++" File: taglist.vim ++" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) ++" Version: 4.3 ++" Last Modified: February 18, 2007 ++" Copyright: Copyright (C) 2002-2006 Yegappan Lakshmanan ++" Permission is hereby granted to use and distribute this code, ++" with or without modifications, provided that this copyright ++" notice is copied with it. Like anything else that's free, ++" taglist.vim is provided *as is* and comes with no warranty of any ++" kind, either expressed or implied. In no event will the copyright ++" holder be liable for any damamges resulting from the use of this ++" software. ++" ++" The "Tag List" plugin is a source code browser plugin for Vim and provides ++" an overview of the structure of the programming language files and allows ++" you to efficiently browse through source code files for different ++" programming languages. You can visit the taglist plugin home page for more ++" information: ++" ++" http://vim-taglist.sourceforge.net ++" ++" You can subscribe to the taglist mailing list to post your questions ++" or suggestions for improvement or to report bugs. Visit the following ++" page for subscribing to the mailing list: ++" ++" http://groups.yahoo.com/group/taglist/ ++" ++" For more information about using this plugin, after installing the ++" taglist plugin, use the ":help taglist" command. ++" ++" Installation ++" ------------ ++" 1. Download the taglist.zip file and unzip the files to the $HOME/.vim ++" or the $HOME/vimfiles or the $VIM/vimfiles directory. This should ++" unzip the following two files (the directory structure should be ++" preserved): ++" ++" plugin/taglist.vim - main taglist plugin file ++" doc/taglist.txt - documentation (help) file ++" ++" Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath' ++" Vim help pages for more details about installing Vim plugins. ++" 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or ++" $VIM/vimfiles/doc directory, start Vim and run the ":helptags ." ++" command to process the taglist help file. ++" 3. If the exuberant ctags utility is not present in your PATH, then set the ++" Tlist_Ctags_Cmd variable to point to the location of the exuberant ctags ++" utility (not to the directory) in the .vimrc file. ++" 4. If you are running a terminal/console version of Vim and the ++" terminal doesn't support changing the window width then set the ++" 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file. ++" 5. Restart Vim. ++" 6. You can now use the ":TlistToggle" command to open/close the taglist ++" window. You can use the ":help taglist" command to get more ++" information about using the taglist plugin. ++" ++" ****************** Do not modify after this line ************************ ++ ++" Line continuation used here ++let s:cpo_save = &cpo ++set cpo&vim ++ ++if !exists('loaded_taglist') ++ " First time loading the taglist plugin ++ " ++ " To speed up the loading of Vim, the taglist plugin uses autoload ++ " mechanism to load the taglist functions. ++ " Only define the configuration variables, user commands and some ++ " auto-commands and finish sourcing the file ++ ++ " The taglist plugin requires the built-in Vim system() function. If this ++ " function is not available, then don't load the plugin. ++ if !exists('*system') ++ echomsg 'Taglist: Vim system() built-in function is not available. ' . ++ \ 'Plugin is not loaded.' ++ let loaded_taglist = 'no' ++ let &cpo = s:cpo_save ++ finish ++ endif ++ ++ " Location of the exuberant ctags tool ++ if !exists('Tlist_Ctags_Cmd') ++ if executable('exuberant-ctags') ++ " On Debian Linux, exuberant ctags is installed ++ " as exuberant-ctags ++ let Tlist_Ctags_Cmd = 'exuberant-ctags' ++ elseif executable(' exctags') ++ " On Free-BSD, exuberant ctags is installed as exctags ++ let Tlist_Ctags_ Cmd = 'exctags' ++ elseif executable('ctags') ++ let Tlist_Ctags_Cmd = 'ctags' ++ elseif executable('ctags.exe') ++ let Tlist_Ctags_Cmd = 'ctags.exe' ++ elseif executable('tags') ++ let Tlist_Ctags_Cmd = 'tags' ++ else ++ echomsg 'Taglist: Exuberant ctags (http://ctags.sf.net) ' . ++ \ 'not found in PATH. Plugin is not loaded.' ++ " Skip loading the plugin ++ let loaded_taglist = 'no' ++ let &cpo = s:cpo_save ++ finish ++ endif ++ endif ++ ++ ++ " Automatically open the taglist window on Vim startup ++ if !exists('Tlist_Auto_Open') ++ let Tlist_Auto_Open = 0 ++ endif ++ ++ " When the taglist window is toggle opened, move the cursor to the ++ " taglist window ++ if !exists('Tlist_GainFocus_On_ToggleOpen') ++ let Tlist_GainFocus_On_ToggleOpen = 0 ++ endif ++ ++ " Process files even when the taglist window is not open ++ if !exists('Tlist_Process_File_Always') ++ let Tlist_Process_File_Always = 0 ++ endif ++ ++ if !exists('Tlist_Show_Menu') ++ let Tlist_Show_Menu = 0 ++ endif ++ ++ " Tag listing sort type - 'name' or 'order' ++ if !exists('Tlist_Sort_Type') ++ let Tlist_Sort_Type = 'order' ++ endif ++ ++ " Tag listing window split (horizontal/vertical) control ++ if !exists('Tlist_Use_Horiz_Window') ++ let Tlist_Use_Horiz_Window = 0 ++ endif ++ ++ " Open the vertically split taglist window on the left or on the right ++ " side. This setting is relevant only if Tlist_Use_Horiz_Window is set to ++ " zero (i.e. only for vertically split windows) ++ if !exists('Tlist_Use_Right_Window') ++ let Tlist_Use_Right_Window = 0 ++ endif ++ ++ " Increase Vim window width to display vertically split taglist window. ++ " For MS-Windows version of Vim running in a MS-DOS window, this must be ++ " set to 0 otherwise the system may hang due to a Vim limitation. ++ if !exists('Tlist_Inc_Winwidth') ++ if (has('win16') || has('win95')) && !has('gui_running') ++ let Tlist_Inc_Winwidth = 0 ++ else ++ let Tlist_Inc_Winwidth = 1 ++ endif ++ endif ++ ++ " Vertically split taglist window width setting ++ if !exists('Tlist_WinWidth') ++ let Tlist_WinWidth = 30 ++ endif ++ ++ " Horizontally split taglist window height setting ++ if !exists('Tlist_WinHeight') ++ let Tlist_WinHeight = 10 ++ endif ++ ++ " Display tag prototypes or tag names in the taglist window ++ if !exists('Tlist_Display_Prototype') ++ let Tlist_Display_Prototype = 0 ++ endif ++ ++ " Display tag scopes in the taglist window ++ if !exists('Tlist_Display_Tag_Scope') ++ let Tlist_Display_Tag_Scope = 1 ++ endif ++ ++ " Use single left mouse click to jump to a tag. By default this is disabled. ++ " Only double click using the mouse will be processed. ++ if !exists('Tlist_Use_SingleClick') ++ let Tlist_Use_SingleClick = 0 ++ endif ++ ++ " Control whether additional help is displayed as part of the taglist or ++ " not. Also, controls whether empty lines are used to separate the tag ++ " tree. ++ if !exists('Tlist_Compact_Format') ++ let Tlist_Compact_Format = 0 ++ endif ++ ++ " Exit Vim if only the taglist window is currently open. By default, this is ++ " set to zero. ++ if !exists('Tlist_Exit_OnlyWindow') ++ let Tlist_Exit_OnlyWindow = 0 ++ endif ++ ++ " Automatically close the folds for the non-active files in the taglist ++ " window ++ if !exists('Tlist_File_Fold_Auto_Close') ++ let Tlist_File_Fold_Auto_Close = 0 ++ endif ++ ++ " Close the taglist window when a tag is selected ++ if !exists('Tlist_Close_On_Select') ++ let Tlist_Close_On_Select = 0 ++ endif ++ ++ " Automatically update the taglist window to display tags for newly ++ " edited files ++ if !exists('Tlist_Auto_Update') ++ let Tlist_Auto_Update = 1 ++ endif ++ ++ " Automatically highlight the current tag ++ if !exists('Tlist_Auto_Highlight_Tag') ++ let Tlist_Auto_Highlight_Tag = 1 ++ endif ++ ++ " Automatically highlight the current tag on entering a buffer ++ if !exists('Tlist_Highlight_Tag_On_BufEnter') ++ let Tlist_Highlight_Tag_On_BufEnter = 1 ++ endif ++ ++ " Enable fold column to display the folding for the tag tree ++ if !exists('Tlist_Enable_Fold_Column') ++ let Tlist_Enable_Fold_Column = 1 ++ endif ++ ++ " Display the tags for only one file in the taglist window ++ if !exists('Tlist_Show_One_File') ++ let Tlist_Show_One_File = 0 ++ endif ++ ++ if !exists('Tlist_Max_Submenu_Items') ++ let Tlist_Max_Submenu_Items = 20 ++ endif ++ ++ if !exists('Tlist_Max_Tag_Length') ++ let Tlist_Max_Tag_Length = 10 ++ endif ++ ++ " Do not change the name of the taglist title variable. The winmanager ++ " plugin relies on this name to determine the title for the taglist ++ " plugin. ++ let TagList_title = "__Tag_List__" ++ ++ " Taglist debug messages ++ let s:tlist_msg = '' ++ ++ " Define the taglist autocommand to automatically open the taglist window ++ " on Vim startup ++ if g:Tlist_Auto_Open ++ autocmd VimEnter * nested call s:Tlist_Window_Check_Auto_Open() ++ endif ++ ++ " Refresh the taglist ++ if g:Tlist_Process_File_Always ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ ++ if g:Tlist_Show_Menu ++ autocmd GUIEnter * call s:Tlist_Menu_Init() ++ endif ++ ++ " When the taglist buffer is created when loading a Vim session file, ++ " the taglist buffer needs to be initialized. The BufFilePost event ++ " is used to handle this case. ++ autocmd BufFilePost __Tag_List__ call s:Tlist_Vim_Session_Load() ++ ++ " Define the user commands to manage the taglist window ++ command! -nargs=0 -bar TlistToggle call s:Tlist_Window_Toggle() ++ command! -nargs=0 -bar TlistOpen call s:Tlist_Window_Open() ++ " For backwards compatiblity define the Tlist command ++ command! -nargs=0 -bar Tlist TlistToggle ++ command! -nargs=+ -complete=file TlistAddFiles ++ \ call s:Tlist_Add_Files() ++ command! -nargs=+ -complete=dir TlistAddFilesRecursive ++ \ call s:Tlist_Add_Files_Recursive() ++ command! -nargs=0 -bar TlistClose call s:Tlist_Window_Close() ++ command! -nargs=0 -bar TlistUpdate call s:Tlist_Update_Current_File() ++ command! -nargs=0 -bar TlistHighlightTag call s:Tlist_Window_Highlight_Tag( ++ \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1) ++ " For backwards compatiblity define the TlistSync command ++ command! -nargs=0 -bar TlistSync TlistHighlightTag ++ command! -nargs=* -complete=buffer TlistShowPrototype ++ \ echo Tlist_Get_Tag_Prototype_By_Line() ++ command! -nargs=* -complete=buffer TlistShowTag ++ \ echo Tlist_Get_Tagname_By_Line() ++ command! -nargs=* -complete=file TlistSessionLoad ++ \ call s:Tlist_Session_Load() ++ command! -nargs=* -complete=file TlistSessionSave ++ \ call s:Tlist_Session_Save() ++ command! -bar TlistLock let Tlist_Auto_Update=0 ++ command! -bar TlistUnlock let Tlist_Auto_Update=1 ++ ++ " Commands for enabling/disabling debug and to display debug messages ++ command! -nargs=? -complete=file -bar TlistDebug ++ \ call s:Tlist_Debug_Enable() ++ command! -nargs=0 -bar TlistUndebug call s:Tlist_Debug_Disable() ++ command! -nargs=0 -bar TlistMessages call s:Tlist_Debug_Show() ++ ++ " Define autocommands to autoload the taglist plugin when needed. ++ ++ " Trick to get the current script ID ++ map xx xx ++ let s:tlist_sid = substitute(maparg('xx'), '\(\d\+_\)xx$', ++ \ '\1', '') ++ unmap xx ++ ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Window_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Menu_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined Tlist_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined TagList_* source ' . ++ \ escape(expand(''), ' ') ++ ++ let loaded_taglist = 'fast_load_done' ++ ++ if g:Tlist_Show_Menu && has('gui_running') ++ call s:Tlist_Menu_Init() ++ endif ++ ++ " restore 'cpo' ++ let &cpo = s:cpo_save ++ finish ++endif ++ ++if !exists('s:tlist_sid') ++ " Two or more versions of taglist plugin are installed. Don't ++ " load this version of the plugin. ++ finish ++endif ++ ++unlet! s:tlist_sid ++ ++if loaded_taglist != 'fast_load_done' ++ " restore 'cpo' ++ let &cpo = s:cpo_save ++ finish ++endif ++ ++" Taglist plugin functionality is available ++let loaded_taglist = 'available' ++ ++"------------------- end of user configurable options -------------------- ++ ++" Default language specific settings for supported file types and tag types ++" ++" Variable name format: ++" ++" s:tlist_def_{vim_ftype}_settings ++" ++" vim_ftype - Filetype detected by Vim ++" ++" Value format: ++" ++" ;:;:;... ++" ++" ctags_ftype - File type supported by exuberant ctags ++" flag - Flag supported by exuberant ctags to generate a tag type ++" name - Name of the tag type used in the taglist window to display the ++" tags of this type ++" ++ ++" Ada language ++let s:tlist_def_ada_settings = 'ada;' . ++ \ 'P:package spec;' . ++ \ 'p:package body;' . ++ \ 'T:type spec;' . ++ \ 't:type;' . ++ \ 'U:subtype spec;' . ++ \ 'u:subtype;' . ++ \ 'c:component;' . ++ \ 'l:literal;' . ++ \ 'V:variable spec;' . ++ \ 'v:variable;' . ++ \ 'f:formal;' . ++ \ 'n:constant;' . ++ \ 'x:exception;' . ++ \ 'R:subprogram spec;' . ++ \ 'r:subprogram body;' . ++ \ 'K:task spec;' . ++ \ 'k:task body;' . ++ \ 'O:protected spec;' . ++ \ 'o:protected body;' . ++ \ 'E:entry spec;' . ++ \ 'e:entry body;' . ++ \ 'b:label;' . ++ \ 'i:identifier;' . ++ \ 'a:autovar;' . ++ \ 'y:annon' ++ ++" assembly language ++let s:tlist_def_asm_settings = 'asm;d:define;l:label;m:macro;t:type' ++ ++" aspperl language ++let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable' ++ ++" aspvbs language ++let s:tlist_def_aspvbs_settings = 'asp;f:function;s:sub;v:variable' ++ ++" awk language ++let s:tlist_def_awk_settings = 'awk;f:function' ++ ++" beta language ++let s:tlist_def_beta_settings = 'beta;f:fragment;s:slot;v:pattern' ++ ++" c language ++let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' . ++ \ 'v:variable;f:function' ++ ++" c++ language ++let s:tlist_def_cpp_settings = 'c++;n:namespace;v:variable;d:macro;t:typedef;' . ++ \ 'c:class;g:enum;s:struct;u:union;f:function' ++ ++" c# language ++let s:tlist_def_cs_settings = 'c#;d:macro;t:typedef;n:namespace;c:class;' . ++ \ 'E:event;g:enum;s:struct;i:interface;' . ++ \ 'p:properties;m:method' ++ ++" cobol language ++let s:tlist_def_cobol_settings = 'cobol;d:data;f:file;g:group;p:paragraph;' . ++ \ 'P:program;s:section' ++ ++" eiffel language ++let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature' ++ ++" erlang language ++let s:tlist_def_erlang_settings = 'erlang;d:macro;r:record;m:module;f:function' ++ ++" expect (same as tcl) language ++let s:tlist_def_expect_settings = 'tcl;c:class;f:method;p:procedure' ++ ++" fortran language ++let s:tlist_def_fortran_settings = 'fortran;p:program;b:block data;' . ++ \ 'c:common;e:entry;i:interface;k:type;l:label;m:module;' . ++ \ 'n:namelist;t:derived;v:variable;f:function;s:subroutine' ++ ++" HTML language ++let s:tlist_def_html_settings = 'html;a:anchor;f:javascript function' ++ ++" java language ++let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' . ++ \ 'f:field;m:method' ++ ++" javascript language ++let s:tlist_def_javascript_settings = 'javascript;f:function' ++ ++" lisp language ++let s:tlist_def_lisp_settings = 'lisp;f:function' ++ ++" lua language ++let s:tlist_def_lua_settings = 'lua;f:function' ++ ++" makefiles ++let s:tlist_def_make_settings = 'make;m:macro' ++ ++" pascal language ++let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure' ++ ++" perl language ++let s:tlist_def_perl_settings = 'perl;c:constant;l:label;p:package;s:subroutine' ++ ++" php language ++let s:tlist_def_php_settings = 'php;c:class;d:constant;v:variable;f:function' ++ ++" python language ++let s:tlist_def_python_settings = 'python;c:class;m:member;f:function' ++ ++" rexx language ++let s:tlist_def_rexx_settings = 'rexx;s:subroutine' ++ ++" ruby language ++let s:tlist_def_ruby_settings = 'ruby;c:class;f:method;F:function;' . ++ \ 'm:singleton method' ++ ++" scheme language ++let s:tlist_def_scheme_settings = 'scheme;s:set;f:function' ++ ++" shell language ++let s:tlist_def_sh_settings = 'sh;f:function' ++ ++" C shell language ++let s:tlist_def_csh_settings = 'sh;f:function' ++ ++" Z shell language ++let s:tlist_def_zsh_settings = 'sh;f:function' ++ ++" slang language ++let s:tlist_def_slang_settings = 'slang;n:namespace;f:function' ++ ++" sml language ++let s:tlist_def_sml_settings = 'sml;e:exception;c:functor;s:signature;' . ++ \ 'r:structure;t:type;v:value;f:function' ++ ++" sql language ++let s:tlist_def_sql_settings = 'sql;c:cursor;F:field;P:package;r:record;' . ++ \ 's:subtype;t:table;T:trigger;v:variable;f:function;p:procedure' ++ ++" tcl language ++let s:tlist_def_tcl_settings = 'tcl;c:class;f:method;m:method;p:procedure' ++ ++" vera language ++let s:tlist_def_vera_settings = 'vera;c:class;d:macro;e:enumerator;' . ++ \ 'f:function;g:enum;m:member;p:program;' . ++ \ 'P:prototype;t:task;T:typedef;v:variable;' . ++ \ 'x:externvar' ++ ++"verilog language ++let s:tlist_def_verilog_settings = 'verilog;m:module;c:constant;P:parameter;' . ++ \ 'e:event;r:register;t:task;w:write;p:port;v:variable;f:function' ++ ++" vim language ++let s:tlist_def_vim_settings = 'vim;a:autocmds;v:variable;f:function' ++ ++" yacc language ++let s:tlist_def_yacc_settings = 'yacc;l:label' ++ ++"------------------- end of language specific options -------------------- ++ ++" Vim window size is changed by the taglist plugin or not ++let s:tlist_winsize_chgd = -1 ++" Taglist window is maximized or not ++let s:tlist_win_maximized = 0 ++" Name of files in the taglist ++let s:tlist_file_names='' ++" Number of files in the taglist ++let s:tlist_file_count = 0 ++" Number of filetypes supported by taglist ++let s:tlist_ftype_count = 0 ++" Is taglist part of other plugins like winmanager or cream? ++let s:tlist_app_name = "none" ++" Are we displaying brief help text ++let s:tlist_brief_help = 1 ++" List of files removed on user request ++let s:tlist_removed_flist = "" ++" Index of current file displayed in the taglist window ++let s:tlist_cur_file_idx = -1 ++" Taglist menu is empty or not ++let s:tlist_menu_empty = 1 ++ ++" An autocommand is used to refresh the taglist window when entering any ++" buffer. We don't want to refresh the taglist window if we are entering the ++" file window from one of the taglist functions. The 'Tlist_Skip_Refresh' ++" variable is used to skip the refresh of the taglist window and is set ++" and cleared appropriately. ++let s:Tlist_Skip_Refresh = 0 ++ ++" Tlist_Window_Display_Help() ++function! s:Tlist_Window_Display_Help() ++ if s:tlist_app_name == "winmanager" ++ " To handle a bug in the winmanager plugin, add a space at the ++ " last line ++ call setline('$', ' ') ++ endif ++ ++ if s:tlist_brief_help ++ " Add the brief help ++ call append(0, '" Press to display help text') ++ else ++ " Add the extensive help ++ call append(0, '" : Jump to tag definition') ++ call append(1, '" o : Jump to tag definition in new window') ++ call append(2, '" p : Preview the tag definition') ++ call append(3, '" : Display tag prototype') ++ call append(4, '" u : Update tag list') ++ call append(5, '" s : Select sort field') ++ call append(6, '" d : Remove file from taglist') ++ call append(7, '" x : Zoom-out/Zoom-in taglist window') ++ call append(8, '" + : Open a fold') ++ call append(9, '" - : Close a fold') ++ call append(10, '" * : Open all folds') ++ call append(11, '" = : Close all folds') ++ call append(12, '" [[ : Move to the start of previous file') ++ call append(13, '" ]] : Move to the start of next file') ++ call append(14, '" q : Close the taglist window') ++ call append(15, '" : Remove help text') ++ endif ++endfunction ++ ++" Tlist_Window_Toggle_Help_Text() ++" Toggle taglist plugin help text between the full version and the brief ++" version ++function! s:Tlist_Window_Toggle_Help_Text() ++ if g:Tlist_Compact_Format ++ " In compact display mode, do not display help ++ return ++ endif ++ ++ " Include the empty line displayed after the help text ++ let brief_help_size = 1 ++ let full_help_size = 16 ++ ++ setlocal modifiable ++ ++ " Set report option to a huge value to prevent informational messages ++ " while deleting the lines ++ let old_report = &report ++ set report=99999 ++ ++ " Remove the currently highlighted tag. Otherwise, the help text ++ " might be highlighted by mistake ++ match none ++ ++ " Toggle between brief and full help text ++ if s:tlist_brief_help ++ let s:tlist_brief_help = 0 ++ ++ " Remove the previous help ++ exe '1,' . brief_help_size . ' delete _' ++ ++ " Adjust the start/end line numbers for the files ++ call s:Tlist_Window_Update_Line_Offsets(0, 1, full_help_size - brief_help_size) ++ else ++ let s:tlist_brief_help = 1 ++ ++ " Remove the previous help ++ exe '1,' . full_help_size . ' delete _' ++ ++ " Adjust the start/end line numbers for the files ++ call s:Tlist_Window_Update_Line_Offsets(0, 0, full_help_size - brief_help_size) ++ endif ++ ++ call s:Tlist_Window_Display_Help() ++ ++ " Restore the report option ++ let &report = old_report ++ ++ setlocal nomodifiable ++endfunction ++ ++" Taglist debug support ++let s:tlist_debug = 0 ++ ++" File for storing the debug messages ++let s:tlist_debug_file = '' ++ ++" Tlist_Debug_Enable ++" Enable logging of taglist debug messages. ++function! s:Tlist_Debug_Enable(...) ++ let s:tlist_debug = 1 ++ ++ " Check whether a valid file name is supplied. ++ if a:1 != '' ++ let s:tlist_debug_file = fnamemodify(a:1, ':p') ++ ++ " Empty the log file ++ exe 'redir! > ' . s:tlist_debug_file ++ redir END ++ ++ " Check whether the log file is present/created ++ if !filewritable(s:tlist_debug_file) ++ call s:Tlist_Warning_Msg('Taglist: Unable to create log file ' ++ \ . s:tlist_debug_file) ++ let s:tlist_debug_file = '' ++ endif ++ endif ++endfunction ++ ++" Tlist_Debug_Disable ++" Disable logging of taglist debug messages. ++function! s:Tlist_Debug_Disable(...) ++ let s:tlist_debug = 0 ++ let s:tlist_debug_file = '' ++endfunction ++ ++" Tlist_Debug_Show ++" Display the taglist debug messages in a new window ++function! s:Tlist_Debug_Show() ++ if s:tlist_msg == '' ++ call s:Tlist_Warning_Msg('Taglist: No debug messages') ++ return ++ endif ++ ++ " Open a new window to display the taglist debug messages ++ new taglist_debug.txt ++ " Delete all the lines (if the buffer already exists) ++ silent! %delete _ ++ " Add the messages ++ silent! put =s:tlist_msg ++ " Move the cursor to the first line ++ normal! gg ++endfunction ++ ++" Tlist_Log_Msg ++" Log the supplied debug message along with the time ++function! s:Tlist_Log_Msg(msg) ++ if s:tlist_debug ++ if s:tlist_debug_file != '' ++ exe 'redir >> ' . s:tlist_debug_file ++ silent echon strftime('%H:%M:%S') . ': ' . a:msg . "\n" ++ redir END ++ else ++ " Log the message into a variable ++ " Retain only the last 3000 characters ++ let len = strlen(s:tlist_msg) ++ if len > 3000 ++ let s:tlist_msg = strpart(s:tlist_msg, len - 3000) ++ endif ++ let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' . ++ \ a:msg . "\n" ++ endif ++ endif ++endfunction ++ ++" Tlist_Warning_Msg() ++" Display a message using WarningMsg highlight group ++function! s:Tlist_Warning_Msg(msg) ++ echohl WarningMsg ++ echomsg a:msg ++ echohl None ++endfunction ++ ++" Last returned file index for file name lookup. ++" Used to speed up file lookup ++let s:tlist_file_name_idx_cache = -1 ++ ++" Tlist_Get_File_Index() ++" Return the index of the specified filename ++function! s:Tlist_Get_File_Index(fname) ++ if s:tlist_file_count == 0 || a:fname == '' ++ return -1 ++ endif ++ ++ " If the new filename is same as the last accessed filename, then ++ " return that index ++ if s:tlist_file_name_idx_cache != -1 && ++ \ s:tlist_file_name_idx_cache < s:tlist_file_count ++ if s:tlist_{s:tlist_file_name_idx_cache}_filename == a:fname ++ " Same as the last accessed file ++ return s:tlist_file_name_idx_cache ++ endif ++ endif ++ ++ " First, check whether the filename is present ++ let s_fname = a:fname . "\n" ++ let i = stridx(s:tlist_file_names, s_fname) ++ if i == -1 ++ let s:tlist_file_name_idx_cache = -1 ++ return -1 ++ endif ++ ++ " Second, compute the file name index ++ let nl_txt = substitute(strpart(s:tlist_file_names, 0, i), "[^\n]", '', 'g') ++ let s:tlist_file_name_idx_cache = strlen(nl_txt) ++ return s:tlist_file_name_idx_cache ++endfunction ++ ++" Last returned file index for line number lookup. ++" Used to speed up file lookup ++let s:tlist_file_lnum_idx_cache = -1 ++ ++" Tlist_Window_Get_File_Index_By_Linenum() ++" Return the index of the filename present in the specified line number ++" Line number refers to the line number in the taglist window ++function! s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ call s:Tlist_Log_Msg('Tlist_Window_Get_File_Index_By_Linenum (' . a:lnum . ')') ++ ++ " First try to see whether the new line number is within the range ++ " of the last returned file ++ if s:tlist_file_lnum_idx_cache != -1 && ++ \ s:tlist_file_lnum_idx_cache < s:tlist_file_count ++ if a:lnum >= s:tlist_{s:tlist_file_lnum_idx_cache}_start && ++ \ a:lnum <= s:tlist_{s:tlist_file_lnum_idx_cache}_end ++ return s:tlist_file_lnum_idx_cache ++ endif ++ endif ++ ++ let fidx = -1 ++ ++ if g:Tlist_Show_One_File ++ " Displaying only one file in the taglist window. Check whether ++ " the line is within the tags displayed for that file ++ if s:tlist_cur_file_idx != -1 ++ if a:lnum >= s:tlist_{s:tlist_cur_file_idx}_start ++ \ && a:lnum <= s:tlist_{s:tlist_cur_file_idx}_end ++ let fidx = s:tlist_cur_file_idx ++ endif ++ ++ endif ++ else ++ " Do a binary search in the taglist ++ let left = 0 ++ let right = s:tlist_file_count - 1 ++ ++ while left < right ++ let mid = (left + right) / 2 ++ ++ if a:lnum >= s:tlist_{mid}_start && a:lnum <= s:tlist_{mid}_end ++ let s:tlist_file_lnum_idx_cache = mid ++ return mid ++ endif ++ ++ if a:lnum < s:tlist_{mid}_start ++ let right = mid - 1 ++ else ++ let left = mid + 1 ++ endif ++ endwhile ++ ++ if left >= 0 && left < s:tlist_file_count ++ \ && a:lnum >= s:tlist_{left}_start ++ \ && a:lnum <= s:tlist_{left}_end ++ let fidx = left ++ endif ++ endif ++ ++ let s:tlist_file_lnum_idx_cache = fidx ++ ++ return fidx ++endfunction ++ ++" Tlist_Exe_Cmd_No_Acmds ++" Execute the specified Ex command after disabling autocommands ++function! s:Tlist_Exe_Cmd_No_Acmds(cmd) ++ let old_eventignore = &eventignore ++ set eventignore=all ++ exe a:cmd ++ let &eventignore = old_eventignore ++endfunction ++ ++" Tlist_Skip_File() ++" Check whether tag listing is supported for the specified file ++function! s:Tlist_Skip_File(filename, ftype) ++ " Skip buffers with no names and buffers with filetype not set ++ if a:filename == '' || a:ftype == '' ++ return 1 ++ endif ++ ++ " Skip files which are not supported by exuberant ctags ++ " First check whether default settings for this filetype are available. ++ " If it is not available, then check whether user specified settings are ++ " available. If both are not available, then don't list the tags for this ++ " filetype ++ let var = 's:tlist_def_' . a:ftype . '_settings' ++ if !exists(var) ++ let var = 'g:tlist_' . a:ftype . '_settings' ++ if !exists(var) ++ return 1 ++ endif ++ endif ++ ++ " Skip files which are not readable or files which are not yet stored ++ " to the disk ++ if !filereadable(a:filename) ++ return 1 ++ endif ++ ++ return 0 ++endfunction ++ ++" Tlist_User_Removed_File ++" Returns 1 if a file is removed by a user from the taglist ++function! s:Tlist_User_Removed_File(filename) ++ return stridx(s:tlist_removed_flist, a:filename . "\n") != -1 ++endfunction ++ ++" Tlist_Update_Remove_List ++" Update the list of user removed files from the taglist ++" add == 1, add the file to the removed list ++" add == 0, delete the file from the removed list ++function! s:Tlist_Update_Remove_List(filename, add) ++ if a:add ++ let s:tlist_removed_flist = s:tlist_removed_flist . a:filename . "\n" ++ else ++ let idx = stridx(s:tlist_removed_flist, a:filename . "\n") ++ let text_before = strpart(s:tlist_removed_flist, 0, idx) ++ let rem_text = strpart(s:tlist_removed_flist, idx) ++ let next_idx = stridx(rem_text, "\n") ++ let text_after = strpart(rem_text, next_idx + 1) ++ ++ let s:tlist_removed_flist = text_before . text_after ++ endif ++endfunction ++ ++" Tlist_FileType_Init ++" Initialize the ctags arguments and tag variable for the specified ++" file type ++function! s:Tlist_FileType_Init(ftype) ++ call s:Tlist_Log_Msg('Tlist_FileType_Init (' . a:ftype . ')') ++ " If the user didn't specify any settings, then use the default ++ " ctags args. Otherwise, use the settings specified by the user ++ let var = 'g:tlist_' . a:ftype . '_settings' ++ if exists(var) ++ " User specified ctags arguments ++ let settings = {var} . ';' ++ else ++ " Default ctags arguments ++ let var = 's:tlist_def_' . a:ftype . '_settings' ++ if !exists(var) ++ " No default settings for this file type. This filetype is ++ " not supported ++ return 0 ++ endif ++ let settings = s:tlist_def_{a:ftype}_settings . ';' ++ endif ++ ++ let msg = 'Taglist: Invalid ctags option setting - ' . settings ++ ++ " Format of the option that specifies the filetype and ctags arugments: ++ " ++ " ;flag1:name1;flag2:name2;flag3:name3 ++ " ++ ++ " Extract the file type to pass to ctags. This may be different from the ++ " file type detected by Vim ++ let pos = stridx(settings, ';') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let ctags_ftype = strpart(settings, 0, pos) ++ if ctags_ftype == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ " Make sure a valid filetype is supplied. If the user didn't specify a ++ " valid filetype, then the ctags option settings may be treated as the ++ " filetype ++ if ctags_ftype =~ ':' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ ++ " Remove the file type from settings ++ let settings = strpart(settings, pos + 1) ++ if settings == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ ++ " Process all the specified ctags flags. The format is ++ " flag1:name1;flag2:name2;flag3:name3 ++ let ctags_flags = '' ++ let cnt = 0 ++ while settings != '' ++ " Extract the flag ++ let pos = stridx(settings, ':') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let flag = strpart(settings, 0, pos) ++ if flag == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ " Remove the flag from settings ++ let settings = strpart(settings, pos + 1) ++ ++ " Extract the tag type name ++ let pos = stridx(settings, ';') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let name = strpart(settings, 0, pos) ++ if name == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let settings = strpart(settings, pos + 1) ++ ++ let cnt = cnt + 1 ++ ++ let s:tlist_{a:ftype}_{cnt}_name = flag ++ let s:tlist_{a:ftype}_{cnt}_fullname = name ++ let ctags_flags = ctags_flags . flag ++ endwhile ++ ++ let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype . ++ \ ' --' . ctags_ftype . '-types=' . ctags_flags ++ let s:tlist_{a:ftype}_count = cnt ++ let s:tlist_{a:ftype}_ctags_flags = ctags_flags ++ ++ " Save the filetype name ++ let s:tlist_ftype_{s:tlist_ftype_count}_name = a:ftype ++ let s:tlist_ftype_count = s:tlist_ftype_count + 1 ++ ++ return 1 ++endfunction ++ ++" Tlist_Get_Filetype ++" Determine the filetype for the specified file ++function! s:Tlist_Get_Filetype(fname) ++ " Ignore the filetype autocommands ++ let old_eventignore = &eventignore ++ set eventignore=FileType ++ ++ " Save the 'filetype', as this will be changed temporarily ++ let old_filetype = &filetype ++ ++ " Run the filetypedetect group of autocommands to determine ++ " the filetype ++ exe 'doautocmd filetypedetect BufRead ' . a:fname ++ ++ " Save the detected filetype ++ let ftype = &filetype ++ ++ " Restore the previous state ++ let &filetype = old_filetype ++ let &eventignore = old_eventignore ++ ++ return ftype ++endfunction ++ ++" Tlist_Get_Buffer_Filetype ++" Get the filetype for the specified buffer ++function! s:Tlist_Get_Buffer_Filetype(bnum) ++ if bufloaded(a:bnum) ++ " For loaded buffers, the 'filetype' is already determined ++ return getbufvar(a:bnum, '&filetype') ++ endif ++ ++ " For unloaded buffers, if the 'filetype' option is set, return it ++ let ftype = getbufvar(a:bnum, '&filetype') ++ if ftype != '' ++ return ftype ++ endif ++ ++ " Skip non-existent buffers ++ if !bufexists(a:bnum) ++ return '' ++ endif ++ ++ " For buffers whose filetype is not yet determined, try to determine ++ " the filetype ++ let bname = bufname(a:bnum) ++ ++ return s:Tlist_Get_Filetype(bname) ++endfunction ++ ++" Tlist_Discard_TagInfo ++" Discard the stored tag information for a file ++function! s:Tlist_Discard_TagInfo(fidx) ++ call s:Tlist_Log_Msg('Tlist_Discard_TagInfo (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ " Discard information about the tags defined in the file ++ let i = 1 ++ while i <= s:tlist_{a:fidx}_tag_count ++ let fidx_i = 's:tlist_' . a:fidx . '_' . i ++ unlet! {fidx_i}_tag ++ unlet! {fidx_i}_tag_name ++ unlet! {fidx_i}_tag_type ++ unlet! {fidx_i}_ttype_idx ++ unlet! {fidx_i}_tag_proto ++ unlet! {fidx_i}_tag_searchpat ++ unlet! {fidx_i}_tag_linenum ++ let i = i + 1 ++ endwhile ++ ++ let s:tlist_{a:fidx}_tag_count = 0 ++ ++ " Discard information about tag type groups ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ if s:tlist_{a:fidx}_{ttype} != '' ++ let fidx_ttype = 's:tlist_' . a:fidx . '_' . ttype ++ let {fidx_ttype} = '' ++ let {fidx_ttype}_offset = 0 ++ let cnt = {fidx_ttype}_count ++ let {fidx_ttype}_count = 0 ++ let j = 1 ++ while j <= cnt ++ unlet! {fidx_ttype}_{j} ++ let j = j + 1 ++ endwhile ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Discard the stored menu command also ++ let s:tlist_{a:fidx}_menu_cmd = '' ++endfunction ++ ++" Tlist_Window_Update_Line_Offsets ++" Update the line offsets for tags for files starting from start_idx ++" and displayed in the taglist window by the specified offset ++function! s:Tlist_Window_Update_Line_Offsets(start_idx, increment, offset) ++ let i = a:start_idx ++ ++ while i < s:tlist_file_count ++ if s:tlist_{i}_visible ++ " Update the start/end line number only if the file is visible ++ if a:increment ++ let s:tlist_{i}_start = s:tlist_{i}_start + a:offset ++ let s:tlist_{i}_end = s:tlist_{i}_end + a:offset ++ else ++ let s:tlist_{i}_start = s:tlist_{i}_start - a:offset ++ let s:tlist_{i}_end = s:tlist_{i}_end - a:offset ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++endfunction ++ ++" Tlist_Discard_FileInfo ++" Discard the stored information for a file ++function! s:Tlist_Discard_FileInfo(fidx) ++ call s:Tlist_Log_Msg('Tlist_Discard_FileInfo (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ call s:Tlist_Discard_TagInfo(a:fidx) ++ ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ unlet! s:tlist_{a:fidx}_{ttype} ++ unlet! s:tlist_{a:fidx}_{ttype}_offset ++ unlet! s:tlist_{a:fidx}_{ttype}_count ++ let i = i + 1 ++ endwhile ++ ++ unlet! s:tlist_{a:fidx}_filename ++ unlet! s:tlist_{a:fidx}_sort_type ++ unlet! s:tlist_{a:fidx}_filetype ++ unlet! s:tlist_{a:fidx}_mtime ++ unlet! s:tlist_{a:fidx}_start ++ unlet! s:tlist_{a:fidx}_end ++ unlet! s:tlist_{a:fidx}_valid ++ unlet! s:tlist_{a:fidx}_visible ++ unlet! s:tlist_{a:fidx}_tag_count ++ unlet! s:tlist_{a:fidx}_menu_cmd ++endfunction ++ ++" Tlist_Window_Remove_File_From_Display ++" Remove the specified file from display ++function! s:Tlist_Window_Remove_File_From_Display(fidx) ++ call s:Tlist_Log_Msg('Tlist_Window_Remove_File_From_Display (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ " If the file is not visible then no need to remove it ++ if !s:tlist_{a:fidx}_visible ++ return ++ endif ++ ++ " Remove the tags displayed for the specified file from the window ++ let start = s:tlist_{a:fidx}_start ++ " Include the empty line after the last line also ++ if g:Tlist_Compact_Format ++ let end = s:tlist_{a:fidx}_end ++ else ++ let end = s:tlist_{a:fidx}_end + 1 ++ endif ++ ++ setlocal modifiable ++ exe 'silent! ' . start . ',' . end . 'delete _' ++ setlocal nomodifiable ++ ++ " Correct the start and end line offsets for all the files following ++ " this file, as the tags for this file are removed ++ call s:Tlist_Window_Update_Line_Offsets(a:fidx + 1, 0, end - start + 1) ++endfunction ++ ++" Tlist_Remove_File ++" Remove the file under the cursor or the specified file index ++" user_request - User requested to remove the file from taglist ++function! s:Tlist_Remove_File(file_idx, user_request) ++ let fidx = a:file_idx ++ ++ if fidx == -1 ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ endif ++ call s:Tlist_Log_Msg('Tlist_Remove_File (' . ++ \ s:tlist_{fidx}_filename . ', ' . a:user_request . ')') ++ ++ let save_winnr = winnr() ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Taglist window is open, remove the file from display ++ ++ if save_winnr != winnum ++ let old_eventignore = &eventignore ++ set eventignore=all ++ exe winnum . 'wincmd w' ++ endif ++ ++ call s:Tlist_Window_Remove_File_From_Display(fidx) ++ ++ if save_winnr != winnum ++ exe save_winnr . 'wincmd w' ++ let &eventignore = old_eventignore ++ endif ++ endif ++ ++ let fname = s:tlist_{fidx}_filename ++ ++ if a:user_request ++ " As the user requested to remove the file from taglist, ++ " add it to the removed list ++ call s:Tlist_Update_Remove_List(fname, 1) ++ endif ++ ++ " Remove the file name from the taglist list of filenames ++ let idx = stridx(s:tlist_file_names, fname . "\n") ++ let text_before = strpart(s:tlist_file_names, 0, idx) ++ let rem_text = strpart(s:tlist_file_names, idx) ++ let next_idx = stridx(rem_text, "\n") ++ let text_after = strpart(rem_text, next_idx + 1) ++ let s:tlist_file_names = text_before . text_after ++ ++ call s:Tlist_Discard_FileInfo(fidx) ++ ++ " Shift all the file variables by one index ++ let i = fidx + 1 ++ ++ while i < s:tlist_file_count ++ let j = i - 1 ++ ++ let s:tlist_{j}_filename = s:tlist_{i}_filename ++ let s:tlist_{j}_sort_type = s:tlist_{i}_sort_type ++ let s:tlist_{j}_filetype = s:tlist_{i}_filetype ++ let s:tlist_{j}_mtime = s:tlist_{i}_mtime ++ let s:tlist_{j}_start = s:tlist_{i}_start ++ let s:tlist_{j}_end = s:tlist_{i}_end ++ let s:tlist_{j}_valid = s:tlist_{i}_valid ++ let s:tlist_{j}_visible = s:tlist_{i}_visible ++ let s:tlist_{j}_tag_count = s:tlist_{i}_tag_count ++ let s:tlist_{j}_menu_cmd = s:tlist_{i}_menu_cmd ++ ++ let k = 1 ++ while k <= s:tlist_{j}_tag_count ++ let s:tlist_{j}_{k}_tag = s:tlist_{i}_{k}_tag ++ let s:tlist_{j}_{k}_tag_name = s:tlist_{i}_{k}_tag_name ++ let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type_By_Tag(i, k) ++ let s:tlist_{j}_{k}_ttype_idx = s:tlist_{i}_{k}_ttype_idx ++ let s:tlist_{j}_{k}_tag_proto = s:Tlist_Get_Tag_Prototype(i, k) ++ let s:tlist_{j}_{k}_tag_searchpat = s:Tlist_Get_Tag_SearchPat(i, k) ++ let s:tlist_{j}_{k}_tag_linenum = s:Tlist_Get_Tag_Linenum(i, k) ++ let k = k + 1 ++ endwhile ++ ++ let ftype = s:tlist_{i}_filetype ++ ++ let k = 1 ++ while k <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{k}_name ++ let s:tlist_{j}_{ttype} = s:tlist_{i}_{ttype} ++ let s:tlist_{j}_{ttype}_offset = s:tlist_{i}_{ttype}_offset ++ let s:tlist_{j}_{ttype}_count = s:tlist_{i}_{ttype}_count ++ if s:tlist_{j}_{ttype} != '' ++ let l = 1 ++ while l <= s:tlist_{j}_{ttype}_count ++ let s:tlist_{j}_{ttype}_{l} = s:tlist_{i}_{ttype}_{l} ++ let l = l + 1 ++ endwhile ++ endif ++ let k = k + 1 ++ endwhile ++ ++ " As the file and tag information is copied to the new index, ++ " discard the previous information ++ call s:Tlist_Discard_FileInfo(i) ++ ++ let i = i + 1 ++ endwhile ++ ++ " Reduce the number of files displayed ++ let s:tlist_file_count = s:tlist_file_count - 1 ++ ++ if g:Tlist_Show_One_File ++ " If the tags for only one file is displayed and if we just ++ " now removed that file, then invalidate the current file idx ++ if s:tlist_cur_file_idx == fidx ++ let s:tlist_cur_file_idx = -1 ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Goto_Window ++" Goto the taglist window ++function! s:Tlist_Window_Goto_Window() ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ if winnr() != winnum ++ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Create ++" Create a new taglist window. If it is already open, jump to it ++function! s:Tlist_Window_Create() ++ call s:Tlist_Log_Msg('Tlist_Window_Create()') ++ " If the window is open, jump to it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Jump to the existing window ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ return ++ endif ++ ++ " If used with winmanager don't open windows. Winmanager will handle ++ " the window/buffer management ++ if s:tlist_app_name == "winmanager" ++ return ++ endif ++ ++ " Create a new window. If user prefers a horizontal window, then open ++ " a horizontally split window. Otherwise open a vertically split ++ " window ++ if g:Tlist_Use_Horiz_Window ++ " Open a horizontally split window ++ let win_dir = 'botright' ++ " Horizontal window height ++ let win_size = g:Tlist_WinHeight ++ else ++ if s:tlist_winsize_chgd == -1 ++ " Open a vertically split window. Increase the window size, if ++ " needed, to accomodate the new window ++ if g:Tlist_Inc_Winwidth && ++ \ &columns < (80 + g:Tlist_WinWidth) ++ " Save the original window position ++ let s:tlist_pre_winx = getwinposx() ++ let s:tlist_pre_winy = getwinposy() ++ ++ " one extra column is needed to include the vertical split ++ let &columns= &columns + g:Tlist_WinWidth + 1 ++ ++ let s:tlist_winsize_chgd = 1 ++ else ++ let s:tlist_winsize_chgd = 0 ++ endif ++ endif ++ ++ if g:Tlist_Use_Right_Window ++ " Open the window at the rightmost place ++ let win_dir = 'botright vertical' ++ else ++ " Open the window at the leftmost place ++ let win_dir = 'topleft vertical' ++ endif ++ let win_size = g:Tlist_WinWidth ++ endif ++ ++ " If the tag listing temporary buffer already exists, then reuse it. ++ " Otherwise create a new buffer ++ let bufnum = bufnr(g:TagList_title) ++ if bufnum == -1 ++ " Create a new buffer ++ let wcmd = g:TagList_title ++ else ++ " Edit the existing buffer ++ let wcmd = '+buffer' . bufnum ++ endif ++ ++ " Create the taglist window ++ exe 'silent! ' . win_dir . ' ' . win_size . 'split ' . wcmd ++ ++ " Save the new window position ++ let s:tlist_winx = getwinposx() ++ let s:tlist_winy = getwinposy() ++ ++ " Initialize the taglist window ++ call s:Tlist_Window_Init() ++endfunction ++ ++" Tlist_Window_Zoom ++" Zoom (maximize/minimize) the taglist window ++function! s:Tlist_Window_Zoom() ++ if s:tlist_win_maximized ++ " Restore the window back to the previous size ++ if g:Tlist_Use_Horiz_Window ++ exe 'resize ' . g:Tlist_WinHeight ++ else ++ exe 'vert resize ' . g:Tlist_WinWidth ++ endif ++ let s:tlist_win_maximized = 0 ++ else ++ " Set the window size to the maximum possible without closing other ++ " windows ++ if g:Tlist_Use_Horiz_Window ++ resize ++ else ++ vert resize ++ endif ++ let s:tlist_win_maximized = 1 ++ endif ++endfunction ++ ++" Tlist_Ballon_Expr ++" When the mouse cursor is over a tag in the taglist window, display the ++" tag prototype (balloon) ++function! Tlist_Ballon_Expr() ++ " Get the file index ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(v:beval_lnum) ++ if fidx == -1 ++ return '' ++ endif ++ ++ " Get the tag output line for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, v:beval_lnum) ++ if tidx == 0 ++ return '' ++ endif ++ ++ " Get the tag search pattern and display it ++ return s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Window_Check_Width ++" Check the width of the taglist window. For horizontally split windows, the ++" 'winfixheight' option is used to fix the height of the window. For ++" vertically split windows, Vim doesn't support the 'winfixwidth' option. So ++" need to handle window width changes from this function. ++function! s:Tlist_Window_Check_Width() ++ let tlist_winnr = bufwinnr(g:TagList_title) ++ if tlist_winnr == -1 ++ return ++ endif ++ ++ let width = winwidth(tlist_winnr) ++ if width != g:Tlist_WinWidth ++ call s:Tlist_Log_Msg("Tlist_Window_Check_Width: Changing window " . ++ \ "width from " . width . " to " . g:Tlist_WinWidth) ++ let save_winnr = winnr() ++ if save_winnr != tlist_winnr ++ call s:Tlist_Exe_Cmd_No_Acmds(tlist_winnr . 'wincmd w') ++ endif ++ exe 'vert resize ' . g:Tlist_WinWidth ++ if save_winnr != tlist_winnr ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Exit_Only_Window ++" If the 'Tlist_Exit_OnlyWindow' option is set, then exit Vim if only the ++" taglist window is present. ++function! s:Tlist_Window_Exit_Only_Window() ++ " Before quitting Vim, delete the taglist buffer so that ++ " the '0 mark is correctly set to the previous buffer. ++ if v:version < 700 ++ if winbufnr(2) == -1 ++ bdelete ++ quit ++ endif ++ else ++ if winbufnr(2) == -1 ++ if tabpagenr('$') == 1 ++ " Only one tag page is present ++ bdelete ++ quit ++ else ++ " More than one tab page is present. Close only the current ++ " tab page ++ close ++ endif ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Init ++" Set the default options for the taglist window ++function! s:Tlist_Window_Init() ++ call s:Tlist_Log_Msg('Tlist_Window_Init()') ++ ++ " The 'readonly' option should not be set for the taglist buffer. ++ " If Vim is started as "view/gview" or if the ":view" command is ++ " used, then the 'readonly' option is set for all the buffers. ++ " Unset it for the taglist buffer ++ setlocal noreadonly ++ ++ " Set the taglist buffer filetype to taglist ++ setlocal filetype=taglist ++ ++ " Define taglist window element highlighting ++ syntax match TagListComment '^" .*' ++ syntax match TagListFileName '^[^" ].*$' ++ syntax match TagListTitle '^ \S.*$' ++ syntax match TagListTagScope '\s\[.\{-\}\]$' ++ ++ " Define the highlighting only if colors are supported ++ if has('gui_running') || &t_Co > 2 ++ " Colors to highlight various taglist window elements ++ " If user defined highlighting group exists, then use them. ++ " Otherwise, use default highlight groups. ++ if hlexists('MyTagListTagName') ++ highlight link TagListTagName MyTagListTagName ++ else ++ highlight default link TagListTagName Search ++ endif ++ " Colors to highlight comments and titles ++ if hlexists('MyTagListComment') ++ highlight link TagListComment MyTagListComment ++ else ++ highlight clear TagListComment ++ highlight default link TagListComment Comment ++ endif ++ if hlexists('MyTagListTitle') ++ highlight link TagListTitle MyTagListTitle ++ else ++ highlight clear TagListTitle ++ highlight default link TagListTitle Title ++ endif ++ if hlexists('MyTagListFileName') ++ highlight link TagListFileName MyTagListFileName ++ else ++ highlight clear TagListFileName ++ highlight default TagListFileName guibg=Grey ctermbg=darkgray ++ \ guifg=white ctermfg=white ++ endif ++ if hlexists('MyTagListTagScope') ++ highlight link TagListTagScope MyTagListTagScope ++ else ++ highlight clear TagListTagScope ++ highlight default link TagListTagScope Identifier ++ endif ++ else ++ highlight default TagListTagName term=reverse cterm=reverse ++ endif ++ ++ " Folding related settings ++ setlocal foldenable ++ setlocal foldminlines=0 ++ setlocal foldmethod=manual ++ setlocal foldlevel=9999 ++ if g:Tlist_Enable_Fold_Column ++ setlocal foldcolumn=3 ++ else ++ setlocal foldcolumn=0 ++ endif ++ setlocal foldtext=v:folddashes.getline(v:foldstart) ++ ++ if s:tlist_app_name != "winmanager" ++ " Mark buffer as scratch ++ silent! setlocal buftype=nofile ++ if s:tlist_app_name == "none" ++ silent! setlocal bufhidden=delete ++ endif ++ silent! setlocal noswapfile ++ " Due to a bug in Vim 6.0, the winbufnr() function fails for unlisted ++ " buffers. So if the taglist buffer is unlisted, multiple taglist ++ " windows will be opened. This bug is fixed in Vim 6.1 and above ++ if v:version >= 601 ++ silent! setlocal nobuflisted ++ endif ++ endif ++ ++ silent! setlocal nowrap ++ ++ " If the 'number' option is set in the source window, it will affect the ++ " taglist window. So forcefully disable 'number' option for the taglist ++ " window ++ silent! setlocal nonumber ++ ++ " Use fixed height when horizontally split window is used ++ if g:Tlist_Use_Horiz_Window ++ if v:version >= 602 ++ set winfixheight ++ endif ++ endif ++ if !g:Tlist_Use_Horiz_Window && v:version >= 700 ++ set winfixwidth ++ endif ++ ++ " Setup balloon evaluation to display tag prototype ++ if v:version >= 700 && has('balloon_eval') ++ setlocal balloonexpr=Tlist_Ballon_Expr() ++ set ballooneval ++ endif ++ ++ " Setup the cpoptions properly for the maps to work ++ let old_cpoptions = &cpoptions ++ set cpoptions&vim ++ ++ " Create buffer local mappings for jumping to the tags and sorting the list ++ nnoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ nnoremap o ++ \ :call Tlist_Window_Jump_To_Tag('newwin') ++ nnoremap p ++ \ :call Tlist_Window_Jump_To_Tag('preview') ++ nnoremap P ++ \ :call Tlist_Window_Jump_To_Tag('prevwin') ++ if v:version >= 700 ++ nnoremap t ++ \ :call Tlist_Window_Jump_To_Tag('checktab') ++ nnoremap ++ \ :call Tlist_Window_Jump_To_Tag('newtab') ++ endif ++ nnoremap <2-LeftMouse> ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ nnoremap s ++ \ :call Tlist_Change_Sort('cmd', 'toggle', '') ++ nnoremap + :silent! foldopen ++ nnoremap - :silent! foldclose ++ nnoremap * :silent! %foldopen! ++ nnoremap = :silent! %foldclose ++ nnoremap :silent! foldopen ++ nnoremap :silent! foldclose ++ nnoremap :silent! %foldopen! ++ nnoremap :call Tlist_Window_Show_Info() ++ nnoremap u :call Tlist_Window_Update_File() ++ nnoremap d :call Tlist_Remove_File(-1, 1) ++ nnoremap x :call Tlist_Window_Zoom() ++ nnoremap [[ :call Tlist_Window_Move_To_File(-1) ++ nnoremap :call Tlist_Window_Move_To_File(-1) ++ nnoremap ]] :call Tlist_Window_Move_To_File(1) ++ nnoremap :call Tlist_Window_Move_To_File(1) ++ nnoremap :call Tlist_Window_Toggle_Help_Text() ++ nnoremap q :close ++ ++ " Insert mode mappings ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ " Windows needs return ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ inoremap o ++ \ :call Tlist_Window_Jump_To_Tag('newwin') ++ inoremap p ++ \ :call Tlist_Window_Jump_To_Tag('preview') ++ inoremap P ++ \ :call Tlist_Window_Jump_To_Tag('prevwin') ++ if v:version >= 700 ++ inoremap t ++ \ :call Tlist_Window_Jump_To_Tag('checktab') ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('newtab') ++ endif ++ inoremap <2-LeftMouse> ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ inoremap s ++ \ :call Tlist_Change_Sort('cmd', 'toggle', '') ++ inoremap + :silent! foldopen ++ inoremap - :silent! foldclose ++ inoremap * :silent! %foldopen! ++ inoremap = :silent! %foldclose ++ inoremap :silent! foldopen ++ inoremap :silent! foldclose ++ inoremap :silent! %foldopen! ++ inoremap :call ++ \ Tlist_Window_Show_Info() ++ inoremap u ++ \ :call Tlist_Window_Update_File() ++ inoremap d :call Tlist_Remove_File(-1, 1) ++ inoremap x :call Tlist_Window_Zoom() ++ inoremap [[ :call Tlist_Window_Move_To_File(-1) ++ inoremap :call Tlist_Window_Move_To_File(-1) ++ inoremap ]] :call Tlist_Window_Move_To_File(1) ++ inoremap :call Tlist_Window_Move_To_File(1) ++ inoremap :call Tlist_Window_Toggle_Help_Text() ++ inoremap q :close ++ ++ " Map single left mouse click if the user wants this functionality ++ if g:Tlist_Use_SingleClick == 1 ++ " Contributed by Bindu Wavell ++ " attempt to perform single click mapping, it would be much ++ " nicer if we could nnoremap ... however vim does ++ " not fire the when you use the mouse ++ " to enter a buffer. ++ let clickmap = ':if bufname("%") =~ "__Tag_List__" ' . ++ \ 'call Tlist_Window_Jump_To_Tag("useopen") ' . ++ \ ' endif ' ++ if maparg('', 'n') == '' ++ " no mapping for leftmouse ++ exe ':nnoremap ' . clickmap ++ else ++ " we have a mapping ++ let mapcmd = ':nnoremap ' ++ let mapcmd = mapcmd . substitute(substitute( ++ \ maparg('', 'n'), '|', '', 'g'), ++ \ '\c^', '', '') ++ let mapcmd = mapcmd . clickmap ++ exe mapcmd ++ endif ++ endif ++ ++ " Define the taglist autocommands ++ augroup TagListAutoCmds ++ autocmd! ++ " Display the tag prototype for the tag under the cursor. ++ autocmd CursorHold __Tag_List__ call s:Tlist_Window_Show_Info() ++ " Highlight the current tag periodically ++ autocmd CursorHold * silent call s:Tlist_Window_Highlight_Tag( ++ \ fnamemodify(bufname('%'), ':p'), line('.'), 1, 0) ++ ++ " Adjust the Vim window width when taglist window is closed ++ autocmd BufUnload __Tag_List__ call s:Tlist_Post_Close_Cleanup() ++ " Close the fold for this buffer when leaving the buffer ++ if g:Tlist_File_Fold_Auto_Close ++ autocmd BufEnter * silent ++ \ call s:Tlist_Window_Open_File_Fold(expand('')) ++ endif ++ " Exit Vim itself if only the taglist window is present (optional) ++ if g:Tlist_Exit_OnlyWindow ++ autocmd BufEnter __Tag_List__ nested ++ \ call s:Tlist_Window_Exit_Only_Window() ++ endif ++ if s:tlist_app_name != "winmanager" && ++ \ !g:Tlist_Process_File_Always && ++ \ (!has('gui_running') || !g:Tlist_Show_Menu) ++ " Auto refresh the taglist window ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ ++ if !g:Tlist_Use_Horiz_Window ++ if v:version < 700 ++ autocmd WinEnter * call s:Tlist_Window_Check_Width() ++ endif ++ endif ++ augroup end ++ ++ " Restore the previous cpoptions settings ++ let &cpoptions = old_cpoptions ++endfunction ++ ++" Tlist_Window_Refresh ++" Display the tags for all the files in the taglist window ++function! s:Tlist_Window_Refresh() ++ call s:Tlist_Log_Msg('Tlist_Window_Refresh()') ++ " Set report option to a huge value to prevent informational messages ++ " while deleting the lines ++ let old_report = &report ++ set report=99999 ++ ++ " Mark the buffer as modifiable ++ setlocal modifiable ++ ++ " Delete the contents of the buffer to the black-hole register ++ silent! %delete _ ++ ++ " As we have cleared the taglist window, mark all the files ++ " as not visible ++ let i = 0 ++ while i < s:tlist_file_count ++ let s:tlist_{i}_visible = 0 ++ let i = i + 1 ++ endwhile ++ ++ if g:Tlist_Compact_Format == 0 ++ " Display help in non-compact mode ++ call s:Tlist_Window_Display_Help() ++ endif ++ ++ " Mark the buffer as not modifiable ++ setlocal nomodifiable ++ ++ " Restore the report option ++ let &report = old_report ++ ++ " If the tags for only one file should be displayed in the taglist ++ " window, then no need to add the tags here. The bufenter autocommand ++ " will add the tags for that file. ++ if g:Tlist_Show_One_File ++ return ++ endif ++ ++ " List all the tags for the previously processed files ++ " Do this only if taglist is configured to display tags for more than ++ " one file. Otherwise, when Tlist_Show_One_File is configured, ++ " tags for the wrong file will be displayed. ++ let i = 0 ++ while i < s:tlist_file_count ++ call s:Tlist_Window_Refresh_File(s:tlist_{i}_filename, ++ \ s:tlist_{i}_filetype) ++ let i = i + 1 ++ endwhile ++ ++ if g:Tlist_Auto_Update ++ " Add and list the tags for all buffers in the Vim buffer list ++ let i = 1 ++ let last_bufnum = bufnr('$') ++ while i <= last_bufnum ++ if buflisted(i) ++ let fname = fnamemodify(bufname(i), ':p') ++ let ftype = s:Tlist_Get_Buffer_Filetype(i) ++ " If the file doesn't support tag listing, skip it ++ if !s:Tlist_Skip_File(fname, ftype) ++ call s:Tlist_Window_Refresh_File(fname, ftype) ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++ endif ++ ++ " If Tlist_File_Fold_Auto_Close option is set, then close all the folds ++ if g:Tlist_File_Fold_Auto_Close ++ " Close all the folds ++ silent! %foldclose ++ endif ++ ++ " Move the cursor to the top of the taglist window ++ normal! gg ++endfunction ++ ++" Tlist_Post_Close_Cleanup() ++" Close the taglist window and adjust the Vim window width ++function! s:Tlist_Post_Close_Cleanup() ++ call s:Tlist_Log_Msg('Tlist_Post_Close_Cleanup()') ++ " Mark all the files as not visible ++ let i = 0 ++ while i < s:tlist_file_count ++ let s:tlist_{i}_visible = 0 ++ let i = i + 1 ++ endwhile ++ ++ " Remove the taglist autocommands ++ silent! autocmd! TagListAutoCmds ++ ++ " Clear all the highlights ++ match none ++ ++ silent! syntax clear TagListTitle ++ silent! syntax clear TagListComment ++ silent! syntax clear TagListTagScope ++ ++ " Remove the left mouse click mapping if it was setup initially ++ if g:Tlist_Use_SingleClick ++ if hasmapto('') ++ nunmap ++ endif ++ endif ++ ++ if s:tlist_app_name != "winmanager" ++ if g:Tlist_Use_Horiz_Window || g:Tlist_Inc_Winwidth == 0 || ++ \ s:tlist_winsize_chgd != 1 || ++ \ &columns < (80 + g:Tlist_WinWidth) ++ " No need to adjust window width if using horizontally split taglist ++ " window or if columns is less than 101 or if the user chose not to ++ " adjust the window width ++ else ++ " If the user didn't manually move the window, then restore the window ++ " position to the pre-taglist position ++ if s:tlist_pre_winx != -1 && s:tlist_pre_winy != -1 && ++ \ getwinposx() == s:tlist_winx && ++ \ getwinposy() == s:tlist_winy ++ exe 'winpos ' . s:tlist_pre_winx . ' ' . s:tlist_pre_winy ++ endif ++ ++ " Adjust the Vim window width ++ let &columns= &columns - (g:Tlist_WinWidth + 1) ++ endif ++ endif ++ ++ let s:tlist_winsize_chgd = -1 ++ ++ " Reset taglist state variables ++ if s:tlist_app_name == "winmanager" ++ let s:tlist_app_name = "none" ++ endif ++ let s:tlist_window_initialized = 0 ++endfunction ++ ++" Tlist_Window_Refresh_File() ++" List the tags defined in the specified file in a Vim window ++function! s:Tlist_Window_Refresh_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Window_Refresh_File (' . a:filename . ')') ++ " First check whether the file already exists ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx != -1 ++ let file_listed = 1 ++ else ++ let file_listed = 0 ++ endif ++ ++ if !file_listed ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(a:filename) ++ return ++ endif ++ endif ++ ++ if file_listed && s:tlist_{fidx}_visible ++ " Check whether the file tags are currently valid ++ if s:tlist_{fidx}_valid ++ " Goto the first line in the file ++ exe s:tlist_{fidx}_start ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ endif ++ return ++ endif ++ ++ " Discard and remove the tags for this file from display ++ call s:Tlist_Discard_TagInfo(fidx) ++ call s:Tlist_Window_Remove_File_From_Display(fidx) ++ endif ++ ++ " Process and generate a list of tags defined in the file ++ if !file_listed || !s:tlist_{fidx}_valid ++ let ret_fidx = s:Tlist_Process_File(a:filename, a:ftype) ++ if ret_fidx == -1 ++ return ++ endif ++ let fidx = ret_fidx ++ endif ++ ++ " Set report option to a huge value to prevent informational messages ++ " while adding lines to the taglist window ++ let old_report = &report ++ set report=99999 ++ ++ if g:Tlist_Show_One_File ++ " Remove the previous file ++ if s:tlist_cur_file_idx != -1 ++ call s:Tlist_Window_Remove_File_From_Display(s:tlist_cur_file_idx) ++ let s:tlist_{s:tlist_cur_file_idx}_visible = 0 ++ let s:tlist_{s:tlist_cur_file_idx}_start = 0 ++ let s:tlist_{s:tlist_cur_file_idx}_end = 0 ++ endif ++ let s:tlist_cur_file_idx = fidx ++ endif ++ ++ " Mark the buffer as modifiable ++ setlocal modifiable ++ ++ " Add new files to the end of the window. For existing files, add them at ++ " the same line where they were previously present. If the file is not ++ " visible, then add it at the end ++ if s:tlist_{fidx}_start == 0 || !s:tlist_{fidx}_visible ++ if g:Tlist_Compact_Format ++ let s:tlist_{fidx}_start = line('$') ++ else ++ let s:tlist_{fidx}_start = line('$') + 1 ++ endif ++ endif ++ ++ let s:tlist_{fidx}_visible = 1 ++ ++ " Goto the line where this file should be placed ++ if g:Tlist_Compact_Format ++ exe s:tlist_{fidx}_start ++ else ++ exe s:tlist_{fidx}_start - 1 ++ endif ++ ++ let txt = fnamemodify(s:tlist_{fidx}_filename, ':t') . ' (' . ++ \ fnamemodify(s:tlist_{fidx}_filename, ':p:h') . ')' ++ if g:Tlist_Compact_Format == 0 ++ silent! put =txt ++ else ++ silent! put! =txt ++ " Move to the next line ++ exe line('.') + 1 ++ endif ++ let file_start = s:tlist_{fidx}_start ++ ++ " Add the tag names grouped by tag type to the buffer with a title ++ let i = 1 ++ let ttype_cnt = s:tlist_{a:ftype}_count ++ while i <= ttype_cnt ++ let ttype = s:tlist_{a:ftype}_{i}_name ++ " Add the tag type only if there are tags for that type ++ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype ++ let ttype_txt = {fidx_ttype} ++ if ttype_txt != '' ++ let txt = ' ' . s:tlist_{a:ftype}_{i}_fullname ++ if g:Tlist_Compact_Format == 0 ++ let ttype_start_lnum = line('.') + 1 ++ silent! put =txt ++ else ++ let ttype_start_lnum = line('.') ++ silent! put! =txt ++ endif ++ silent! put =ttype_txt ++ ++ let {fidx_ttype}_offset = ttype_start_lnum - file_start ++ ++ " create a fold for this tag type ++ let fold_start = ttype_start_lnum ++ let fold_end = fold_start + {fidx_ttype}_count ++ exe fold_start . ',' . fold_end . 'fold' ++ ++ " Adjust the cursor position ++ if g:Tlist_Compact_Format == 0 ++ exe ttype_start_lnum + {fidx_ttype}_count ++ else ++ exe ttype_start_lnum + {fidx_ttype}_count + 1 ++ endif ++ ++ if g:Tlist_Compact_Format == 0 ++ " Separate the tag types by a empty line ++ silent! put ='' ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++ ++ if s:tlist_{fidx}_tag_count == 0 ++ if g:Tlist_Compact_Format == 0 ++ silent! put ='' ++ endif ++ endif ++ ++ let s:tlist_{fidx}_end = line('.') - 1 ++ ++ " Create a fold for the entire file ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold' ++ exe 'silent! ' . s:tlist_{fidx}_start . ',' . ++ \ s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Goto the starting line for this file, ++ exe s:tlist_{fidx}_start ++ ++ if s:tlist_app_name == "winmanager" ++ " To handle a bug in the winmanager plugin, add a space at the ++ " last line ++ call setline('$', ' ') ++ endif ++ ++ " Mark the buffer as not modifiable ++ setlocal nomodifiable ++ ++ " Restore the report option ++ let &report = old_report ++ ++ " Update the start and end line numbers for all the files following this ++ " file ++ let start = s:tlist_{fidx}_start ++ " include the empty line after the last line ++ if g:Tlist_Compact_Format ++ let end = s:tlist_{fidx}_end ++ else ++ let end = s:tlist_{fidx}_end + 1 ++ endif ++ call s:Tlist_Window_Update_Line_Offsets(fidx + 1, 1, end - start + 1) ++ ++ " Now that we have updated the taglist window, update the tags ++ " menu (if present) ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(1) ++ endif ++endfunction ++ ++" Tlist_Init_File ++" Initialize the variables for a new file ++function! s:Tlist_Init_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Init_File (' . a:filename . ')') ++ " Add new files at the end of the list ++ let fidx = s:tlist_file_count ++ let s:tlist_file_count = s:tlist_file_count + 1 ++ " Add the new file name to the taglist list of file names ++ let s:tlist_file_names = s:tlist_file_names . a:filename . "\n" ++ ++ " Initialize the file variables ++ let s:tlist_{fidx}_filename = a:filename ++ let s:tlist_{fidx}_sort_type = g:Tlist_Sort_Type ++ let s:tlist_{fidx}_filetype = a:ftype ++ let s:tlist_{fidx}_mtime = -1 ++ let s:tlist_{fidx}_start = 0 ++ let s:tlist_{fidx}_end = 0 ++ let s:tlist_{fidx}_valid = 0 ++ let s:tlist_{fidx}_visible = 0 ++ let s:tlist_{fidx}_tag_count = 0 ++ let s:tlist_{fidx}_menu_cmd = '' ++ ++ " Initialize the tag type variables ++ let i = 1 ++ while i <= s:tlist_{a:ftype}_count ++ let ttype = s:tlist_{a:ftype}_{i}_name ++ let s:tlist_{fidx}_{ttype} = '' ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = 0 ++ let i = i + 1 ++ endwhile ++ ++ return fidx ++endfunction ++ ++" Tlist_Get_Tag_Type_By_Tag ++" Return the tag type for the specified tag index ++function! s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) ++ let ttype_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_type' ++ ++ " Already parsed and have the tag name ++ if exists(ttype_var) ++ return {ttype_var} ++ endif ++ ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let {ttype_var} = s:Tlist_Extract_Tagtype(tag_line) ++ ++ return {ttype_var} ++endfunction ++ ++" Tlist_Get_Tag_Prototype ++function! s:Tlist_Get_Tag_Prototype(fidx, tidx) ++ let tproto_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_proto' ++ ++ " Already parsed and have the tag prototype ++ if exists(tproto_var) ++ return {tproto_var} ++ endif ++ ++ " Parse and extract the tag prototype ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = stridx(tag_line, '/^') + 2 ++ let end = stridx(tag_line, '/;"' . "\t") ++ if tag_line[end - 1] == '$' ++ let end = end -1 ++ endif ++ let tag_proto = strpart(tag_line, start, end - start) ++ let {tproto_var} = substitute(tag_proto, '\s*', '', '') ++ ++ return {tproto_var} ++endfunction ++ ++" Tlist_Get_Tag_SearchPat ++function! s:Tlist_Get_Tag_SearchPat(fidx, tidx) ++ let tpat_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_searchpat' ++ ++ " Already parsed and have the tag search pattern ++ if exists(tpat_var) ++ return {tpat_var} ++ endif ++ ++ " Parse and extract the tag search pattern ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = stridx(tag_line, '/^') + 2 ++ let end = stridx(tag_line, '/;"' . "\t") ++ if tag_line[end - 1] == '$' ++ let end = end -1 ++ endif ++ let {tpat_var} = '\V\^' . strpart(tag_line, start, end - start) . ++ \ (tag_line[end] == '$' ? '\$' : '') ++ ++ return {tpat_var} ++endfunction ++ ++" Tlist_Get_Tag_Linenum ++" Return the tag line number, given the tag index ++function! s:Tlist_Get_Tag_Linenum(fidx, tidx) ++ let tline_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_linenum' ++ ++ " Already parsed and have the tag line number ++ if exists(tline_var) ++ return {tline_var} ++ endif ++ ++ " Parse and extract the tag line number ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = strridx(tag_line, 'line:') + 5 ++ let end = strridx(tag_line, "\t") ++ if end < start ++ let {tline_var} = strpart(tag_line, start) + 0 ++ else ++ let {tline_var} = strpart(tag_line, start, end - start) + 0 ++ endif ++ ++ return {tline_var} ++endfunction ++ ++" Tlist_Parse_Tagline ++" Parse a tag line from the ctags output. Separate the tag output based on the ++" tag type and store it in the tag type variable. ++" The format of each line in the ctags output is: ++" ++" tag_namefile_nameex_cmd;"extension_fields ++" ++function! s:Tlist_Parse_Tagline(tag_line) ++ if a:tag_line == '' ++ " Skip empty lines ++ return ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Extract_Tagtype(a:tag_line) ++ ++ " Make sure the tag type is a valid and supported one ++ if ttype == '' || stridx(s:ctags_flags, ttype) == -1 ++ " Line is not in proper tags format or Tag type is not supported ++ return ++ endif ++ ++ " Update the total tag count ++ let s:tidx = s:tidx + 1 ++ ++ " The following variables are used to optimize this code. Vim is slow in ++ " using curly brace names. To reduce the amount of processing needed, the ++ " curly brace variables are pre-processed here ++ let fidx_tidx = 's:tlist_' . s:fidx . '_' . s:tidx ++ let fidx_ttype = 's:tlist_' . s:fidx . '_' . ttype ++ ++ " Update the count of this tag type ++ let ttype_idx = {fidx_ttype}_count + 1 ++ let {fidx_ttype}_count = ttype_idx ++ ++ " Store the ctags output for this tag ++ let {fidx_tidx}_tag = a:tag_line ++ ++ " Store the tag index and the tag type index (back pointers) ++ let {fidx_ttype}_{ttype_idx} = s:tidx ++ let {fidx_tidx}_ttype_idx = ttype_idx ++ ++ " Extract the tag name ++ let tag_name = strpart(a:tag_line, 0, stridx(a:tag_line, "\t")) ++ ++ " Extract the tag scope/prototype ++ if g:Tlist_Display_Prototype ++ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(s:fidx, s:tidx) ++ else ++ let ttxt = ' ' . tag_name ++ ++ " Add the tag scope, if it is available and is configured. Tag ++ " scope is the last field after the 'line:\t' field ++ if g:Tlist_Display_Tag_Scope ++ let tag_scope = s:Tlist_Extract_Tag_Scope(a:tag_line) ++ if tag_scope != '' ++ let ttxt = ttxt . ' [' . tag_scope . ']' ++ endif ++ endif ++ endif ++ ++ " Add this tag to the tag type variable ++ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n" ++ ++ " Save the tag name ++ let {fidx_tidx}_tag_name = tag_name ++endfunction ++ ++" Tlist_Process_File ++" Get the list of tags defined in the specified file and store them ++" in Vim variables. Returns the file index where the tags are stored. ++function! s:Tlist_Process_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Process_File (' . a:filename . ', ' . ++ \ a:ftype . ')') ++ " Check whether this file is supported ++ if s:Tlist_Skip_File(a:filename, a:ftype) ++ return -1 ++ endif ++ ++ " If the tag types for this filetype are not yet created, then create ++ " them now ++ let var = 's:tlist_' . a:ftype . '_count' ++ if !exists(var) ++ if s:Tlist_FileType_Init(a:ftype) == 0 ++ return -1 ++ endif ++ endif ++ ++ " If this file is already processed, then use the cached values ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ " First time, this file is loaded ++ let fidx = s:Tlist_Init_File(a:filename, a:ftype) ++ else ++ " File was previously processed. Discard the tag information ++ call s:Tlist_Discard_TagInfo(fidx) ++ endif ++ ++ let s:tlist_{fidx}_valid = 1 ++ ++ " Exuberant ctags arguments to generate a tag list ++ let ctags_args = ' -f - --format=2 --excmd=pattern --fields=nks ' ++ ++ " Form the ctags argument depending on the sort type ++ if s:tlist_{fidx}_sort_type == 'name' ++ let ctags_args = ctags_args . '--sort=yes' ++ else ++ let ctags_args = ctags_args . '--sort=no' ++ endif ++ ++ " Add the filetype specific arguments ++ let ctags_args = ctags_args . ' ' . s:tlist_{a:ftype}_ctags_args ++ ++ " Ctags command to produce output with regexp for locating the tags ++ let ctags_cmd = g:Tlist_Ctags_Cmd . ctags_args ++ let ctags_cmd = ctags_cmd . ' "' . a:filename . '"' ++ ++ if &shellxquote == '"' ++ " Double-quotes within double-quotes will not work in the ++ " command-line.If the 'shellxquote' option is set to double-quotes, ++ " then escape the double-quotes in the ctags command-line. ++ let ctags_cmd = escape(ctags_cmd, '"') ++ endif ++ ++ " In Windows 95, if not using cygwin, disable the 'shellslash' ++ " option. Otherwise, this will cause problems when running the ++ " ctags command. ++ if has('win95') && !has('win32unix') ++ let old_shellslash = &shellslash ++ set noshellslash ++ endif ++ ++ if has('win32') && !has('win32unix') && !has('win95') ++ \ && (&shell =~ 'cmd.exe') ++ " Windows does not correctly deal with commands that have more than 1 ++ " set of double quotes. It will strip them all resulting in: ++ " 'C:\Program' is not recognized as an internal or external command ++ " operable program or batch file. To work around this, place the ++ " command inside a batch file and call the batch file. ++ " Do this only on Win2K, WinXP and above. ++ " Contributed by: David Fishburn. ++ let s:taglist_tempfile = fnamemodify(tempname(), ':h') . ++ \ '\taglist.cmd' ++ exe 'redir! > ' . s:taglist_tempfile ++ silent echo ctags_cmd ++ redir END ++ ++ call s:Tlist_Log_Msg('Cmd inside batch file: ' . ctags_cmd) ++ let ctags_cmd = '"' . s:taglist_tempfile . '"' ++ endif ++ ++ call s:Tlist_Log_Msg('Cmd: ' . ctags_cmd) ++ ++ " Run ctags and get the tag list ++ let cmd_output = system(ctags_cmd) ++ ++ " Restore the value of the 'shellslash' option. ++ if has('win95') && !has('win32unix') ++ let &shellslash = old_shellslash ++ endif ++ ++ if exists('s:taglist_tempfile') ++ " Delete the temporary cmd file created on MS-Windows ++ call delete(s:taglist_tempfile) ++ endif ++ ++ " Handle errors ++ if v:shell_error ++ let msg = "Taglist: Failed to generate tags for " . a:filename ++ call s:Tlist_Warning_Msg(msg) ++ if cmd_output != '' ++ call s:Tlist_Warning_Msg(cmd_output) ++ endif ++ return fidx ++ endif ++ ++ " Store the modification time for the file ++ let s:tlist_{fidx}_mtime = getftime(a:filename) ++ ++ " No tags for current file ++ if cmd_output == '' ++ call s:Tlist_Log_Msg('No tags defined in ' . a:filename) ++ return fidx ++ endif ++ ++ call s:Tlist_Log_Msg('Generated tags information for ' . a:filename) ++ ++ if v:version > 601 ++ " The following script local variables are used by the ++ " Tlist_Parse_Tagline() function. ++ let s:ctags_flags = s:tlist_{a:ftype}_ctags_flags ++ let s:fidx = fidx ++ let s:tidx = 0 ++ ++ " Process the ctags output one line at a time. The substitute() ++ " command is used to parse the tag lines instead of using the ++ " matchstr()/stridx()/strpart() functions for performance reason ++ call substitute(cmd_output, "\\([^\n]\\+\\)\n", ++ \ '\=s:Tlist_Parse_Tagline(submatch(1))', 'g') ++ ++ " Save the number of tags for this file ++ let s:tlist_{fidx}_tag_count = s:tidx ++ ++ " The following script local variables are no longer needed ++ unlet! s:ctags_flags ++ unlet! s:tidx ++ unlet! s:fidx ++ else ++ " Due to a bug in Vim earlier than version 6.1, ++ " we cannot use substitute() to parse the ctags output. ++ " Instead the slow str*() functions are used ++ let ctags_flags = s:tlist_{a:ftype}_ctags_flags ++ let tidx = 0 ++ ++ while cmd_output != '' ++ " Extract one line at a time ++ let idx = stridx(cmd_output, "\n") ++ let one_line = strpart(cmd_output, 0, idx) ++ " Remove the line from the tags output ++ let cmd_output = strpart(cmd_output, idx + 1) ++ ++ if one_line == '' ++ " Line is not in proper tags format ++ continue ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Extract_Tagtype(one_line) ++ ++ " Make sure the tag type is a valid and supported one ++ if ttype == '' || stridx(ctags_flags, ttype) == -1 ++ " Line is not in proper tags format or Tag type is not ++ " supported ++ continue ++ endif ++ ++ " Update the total tag count ++ let tidx = tidx + 1 ++ ++ " The following variables are used to optimize this code. Vim is ++ " slow in using curly brace names. To reduce the amount of ++ " processing needed, the curly brace variables are pre-processed ++ " here ++ let fidx_tidx = 's:tlist_' . fidx . '_' . tidx ++ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype ++ ++ " Update the count of this tag type ++ let ttype_idx = {fidx_ttype}_count + 1 ++ let {fidx_ttype}_count = ttype_idx ++ ++ " Store the ctags output for this tag ++ let {fidx_tidx}_tag = one_line ++ ++ " Store the tag index and the tag type index (back pointers) ++ let {fidx_ttype}_{ttype_idx} = tidx ++ let {fidx_tidx}_ttype_idx = ttype_idx ++ ++ " Extract the tag name ++ let tag_name = strpart(one_line, 0, stridx(one_line, "\t")) ++ ++ " Extract the tag scope/prototype ++ if g:Tlist_Display_Prototype ++ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(fidx, tidx) ++ else ++ let ttxt = ' ' . tag_name ++ ++ " Add the tag scope, if it is available and is configured. Tag ++ " scope is the last field after the 'line:\t' field ++ if g:Tlist_Display_Tag_Scope ++ let tag_scope = s:Tlist_Extract_Tag_Scope(one_line) ++ if tag_scope != '' ++ let ttxt = ttxt . ' [' . tag_scope . ']' ++ endif ++ endif ++ endif ++ ++ " Add this tag to the tag type variable ++ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n" ++ ++ " Save the tag name ++ let {fidx_tidx}_tag_name = tag_name ++ endwhile ++ ++ " Save the number of tags for this file ++ let s:tlist_{fidx}_tag_count = tidx ++ endif ++ ++ call s:Tlist_Log_Msg('Processed ' . s:tlist_{fidx}_tag_count . ++ \ ' tags in ' . a:filename) ++ ++ return fidx ++endfunction ++ ++" Tlist_Update_File ++" Update the tags for a file (if needed) ++function! Tlist_Update_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Update_File (' . a:filename . ')') ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(a:filename, a:ftype) ++ return ++ endif ++ ++ " Convert the file name to a full path ++ let fname = fnamemodify(a:filename, ':p') ++ ++ " First check whether the file already exists ++ let fidx = s:Tlist_Get_File_Index(fname) ++ ++ if fidx != -1 && s:tlist_{fidx}_valid ++ " File exists and the tags are valid ++ " Check whether the file was modified after the last tags update ++ " If it is modified, then update the tags ++ if s:tlist_{fidx}_mtime == getftime(fname) ++ return ++ endif ++ else ++ " If the tags were removed previously based on a user request, ++ " as we are going to update the tags (based on the user request), ++ " remove the filename from the deleted list ++ call s:Tlist_Update_Remove_List(fname, 0) ++ endif ++ ++ " If the taglist window is opened, update it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ " Taglist window is not present. Just update the taglist ++ " and return ++ call s:Tlist_Process_File(fname, a:ftype) ++ else ++ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != -1 ++ " If tags for only one file are displayed and we are not ++ " updating the tags for that file, then no need to ++ " refresh the taglist window. Otherwise, the taglist ++ " window should be updated. ++ if s:tlist_{s:tlist_cur_file_idx}_filename != fname ++ call s:Tlist_Process_File(fname, a:ftype) ++ return ++ endif ++ endif ++ ++ " Save the current window number ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ " Save the cursor position ++ let save_line = line('.') ++ let save_col = col('.') ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(fname, a:ftype) ++ ++ " Restore the cursor position ++ if v:version >= 601 ++ call cursor(save_line, save_col) ++ else ++ exe save_line ++ exe 'normal! ' . save_col . '|' ++ endif ++ ++ if winnr() != save_winnr ++ " Go back to the original window ++ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') ++ endif ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(1) ++ endif ++endfunction ++ ++" Tlist_Window_Close ++" Close the taglist window ++function! s:Tlist_Window_Close() ++ call s:Tlist_Log_Msg('Tlist_Window_Close()') ++ " Make sure the taglist window exists ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Error: Taglist window is not open') ++ return ++ endif ++ ++ if winnr() == winnum ++ " Already in the taglist window. Close it and return ++ if winbufnr(2) != -1 ++ " If a window other than the taglist window is open, ++ " then only close the taglist window. ++ close ++ endif ++ else ++ " Goto the taglist window, close it and then come back to the ++ " original window ++ let curbufnr = bufnr('%') ++ exe winnum . 'wincmd w' ++ close ++ " Need to jump back to the original window only if we are not ++ " already in that window ++ let winnum = bufwinnr(curbufnr) ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Mark_File_Window ++" Mark the current window as the file window to use when jumping to a tag. ++" Only if the current window is a non-plugin, non-preview and non-taglist ++" window ++function! s:Tlist_Window_Mark_File_Window() ++ if getbufvar('%', '&buftype') == '' && !&previewwindow ++ let w:tlist_file_window = "yes" ++ endif ++endfunction ++ ++" Tlist_Window_Open ++" Open and refresh the taglist window ++function! s:Tlist_Window_Open() ++ call s:Tlist_Log_Msg('Tlist_Window_Open()') ++ " If the window is open, jump to it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Jump to the existing window ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ return ++ endif ++ ++ if s:tlist_app_name == "winmanager" ++ " Taglist plugin is no longer part of the winmanager app ++ let s:tlist_app_name = "none" ++ endif ++ ++ " Get the filename and filetype for the specified buffer ++ let curbuf_name = fnamemodify(bufname('%'), ':p') ++ let curbuf_ftype = getbufvar('%', '&filetype') ++ let cur_lnum = line('.') ++ ++ " Mark the current window as the desired window to open a file when a tag ++ " is selected. ++ call s:Tlist_Window_Mark_File_Window() ++ ++ " Open the taglist window ++ call s:Tlist_Window_Create() ++ ++ call s:Tlist_Window_Refresh() ++ ++ if g:Tlist_Show_One_File ++ " Add only the current buffer and file ++ " ++ " If the file doesn't support tag listing, skip it ++ if !s:Tlist_Skip_File(curbuf_name, curbuf_ftype) ++ call s:Tlist_Window_Refresh_File(curbuf_name, curbuf_ftype) ++ endif ++ endif ++ ++ if g:Tlist_File_Fold_Auto_Close ++ " Open the fold for the current file, as all the folds in ++ " the taglist window are closed ++ let fidx = s:Tlist_Get_File_Index(curbuf_name) ++ if fidx != -1 ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ endif ++ endif ++ ++ " Highlight the current tag ++ call s:Tlist_Window_Highlight_Tag(curbuf_name, cur_lnum, 1, 1) ++endfunction ++ ++" Tlist_Window_Toggle() ++" Open or close a taglist window ++function! s:Tlist_Window_Toggle() ++ call s:Tlist_Log_Msg('Tlist_Window_Toggle()') ++ " If taglist window is open then close it. ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ call s:Tlist_Window_Close() ++ return ++ endif ++ ++ call s:Tlist_Window_Open() ++ ++ " Go back to the original window, if Tlist_GainFocus_On_ToggleOpen is not ++ " set ++ if !g:Tlist_GainFocus_On_ToggleOpen ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++endfunction ++ ++" Tlist_Process_Filelist ++" Process multiple files. Each filename is separated by "\n" ++" Returns the number of processed files ++function! s:Tlist_Process_Filelist(file_names) ++ let flist = a:file_names ++ ++ " Enable lazy screen updates ++ let old_lazyredraw = &lazyredraw ++ set lazyredraw ++ ++ " Keep track of the number of processed files ++ let fcnt = 0 ++ ++ " Process one file at a time ++ while flist != '' ++ let nl_idx = stridx(flist, "\n") ++ let one_file = strpart(flist, 0, nl_idx) ++ ++ " Remove the filename from the list ++ let flist = strpart(flist, nl_idx + 1) ++ ++ if one_file == '' ++ continue ++ endif ++ ++ " Skip directories ++ if isdirectory(one_file) ++ continue ++ endif ++ ++ let ftype = s:Tlist_Get_Filetype(one_file) ++ ++ echon "\r " ++ echon "\rProcessing tags for " . fnamemodify(one_file, ':p:t') ++ ++ let fcnt = fcnt + 1 ++ ++ call Tlist_Update_File(one_file, ftype) ++ endwhile ++ ++ " Clear the displayed informational messages ++ echon "\r " ++ ++ " Restore the previous state ++ let &lazyredraw = old_lazyredraw ++ ++ return fcnt ++endfunction ++ ++" Tlist_Process_Dir ++" Process the files in a directory matching the specified pattern ++function! s:Tlist_Process_Dir(dir_name, pat) ++ let flist = glob(a:dir_name . '/' . a:pat) . "\n" ++ ++ let fcnt = s:Tlist_Process_Filelist(flist) ++ ++ let len = strlen(a:dir_name) ++ if a:dir_name[len - 1] == '\' || a:dir_name[len - 1] == '/' ++ let glob_expr = a:dir_name . '*' ++ else ++ let glob_expr = a:dir_name . '/*' ++ endif ++ let all_files = glob(glob_expr) . "\n" ++ ++ while all_files != '' ++ let nl_idx = stridx(all_files, "\n") ++ let one_file = strpart(all_files, 0, nl_idx) ++ ++ let all_files = strpart(all_files, nl_idx + 1) ++ if one_file == '' ++ continue ++ endif ++ ++ " Skip non-directory names ++ if !isdirectory(one_file) ++ continue ++ endif ++ ++ echon "\r " ++ echon "\rProcessing files in directory " . fnamemodify(one_file, ':t') ++ let fcnt = fcnt + s:Tlist_Process_Dir(one_file, a:pat) ++ endwhile ++ ++ return fcnt ++endfunction ++ ++" Tlist_Add_Files_Recursive ++" Add files recursively from a directory ++function! s:Tlist_Add_Files_Recursive(dir, ...) ++ let dir_name = fnamemodify(a:dir, ':p') ++ if !isdirectory(dir_name) ++ call s:Tlist_Warning_Msg('Error: ' . dir_name . ' is not a directory') ++ return ++ endif ++ ++ if a:0 == 1 ++ " User specified file pattern ++ let pat = a:1 ++ else ++ " Default file pattern ++ let pat = '*' ++ endif ++ ++ echon "\r " ++ echon "\rProcessing files in directory " . fnamemodify(dir_name, ':t') ++ let fcnt = s:Tlist_Process_Dir(dir_name, pat) ++ ++ echon "\rAdded " . fcnt . " files to the taglist" ++endfunction ++ ++" Tlist_Add_Files ++" Add the specified list of files to the taglist ++function! s:Tlist_Add_Files(...) ++ let flist = '' ++ let i = 1 ++ ++ " Get all the files matching the file patterns supplied as argument ++ while i <= a:0 ++ let flist = flist . glob(a:{i}) . "\n" ++ let i = i + 1 ++ endwhile ++ ++ if flist == '' ++ call s:Tlist_Warning_Msg('Error: No matching files are found') ++ return ++ endif ++ ++ let fcnt = s:Tlist_Process_Filelist(flist) ++ echon "\rAdded " . fcnt . " files to the taglist" ++endfunction ++ ++" Tlist_Extract_Tagtype ++" Extract the tag type from the tag text ++function! s:Tlist_Extract_Tagtype(tag_line) ++ " The tag type is after the tag prototype field. The prototype field ++ " ends with the /;"\t string. We add 4 at the end to skip the characters ++ " in this special string.. ++ let start = strridx(a:tag_line, '/;"' . "\t") + 4 ++ let end = strridx(a:tag_line, 'line:') - 1 ++ let ttype = strpart(a:tag_line, start, end - start) ++ ++ return ttype ++endfunction ++ ++" Tlist_Extract_Tag_Scope ++" Extract the tag scope from the tag text ++function! s:Tlist_Extract_Tag_Scope(tag_line) ++ let start = strridx(a:tag_line, 'line:') ++ let end = strridx(a:tag_line, "\t") ++ if end <= start ++ return '' ++ endif ++ ++ let tag_scope = strpart(a:tag_line, end + 1) ++ let tag_scope = strpart(tag_scope, stridx(tag_scope, ':') + 1) ++ ++ return tag_scope ++endfunction ++ ++" Tlist_Refresh() ++" Refresh the taglist ++function! s:Tlist_Refresh() ++ call s:Tlist_Log_Msg('Tlist_Refresh (Skip_Refresh = ' . ++ \ s:Tlist_Skip_Refresh . ', ' . bufname('%') . ')') ++ " If we are entering the buffer from one of the taglist functions, then ++ " no need to refresh the taglist window again. ++ if s:Tlist_Skip_Refresh ++ " We still need to update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++ return ++ endif ++ ++ " If part of the winmanager plugin and not configured to process ++ " tags always and not configured to display the tags menu, then return ++ if (s:tlist_app_name == 'winmanager') && !g:Tlist_Process_File_Always ++ \ && !g:Tlist_Show_Menu ++ return ++ endif ++ ++ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help ++ if &buftype != '' ++ return ++ endif ++ ++ let filename = fnamemodify(bufname('%'), ':p') ++ let ftype = &filetype ++ ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(filename, ftype) ++ return ++ endif ++ ++ let tlist_win = bufwinnr(g:TagList_title) ++ ++ " If the taglist window is not opened and not configured to process ++ " tags always and not displaying the tags menu, then return ++ if tlist_win == -1 && !g:Tlist_Process_File_Always && !g:Tlist_Show_Menu ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(filename) ++ return ++ endif ++ ++ " If the taglist should not be auto updated, then return ++ if !g:Tlist_Auto_Update ++ return ++ endif ++ endif ++ ++ let cur_lnum = line('.') ++ ++ if fidx == -1 ++ " Update the tags for the file ++ let fidx = s:Tlist_Process_File(filename, ftype) ++ else ++ let mtime = getftime(filename) ++ if s:tlist_{fidx}_mtime != mtime ++ " Invalidate the tags listed for this file ++ let s:tlist_{fidx}_valid = 0 ++ ++ " Update the taglist and the window ++ call Tlist_Update_File(filename, ftype) ++ ++ " Store the new file modification time ++ let s:tlist_{fidx}_mtime = mtime ++ endif ++ endif ++ ++ " Update the taglist window ++ if tlist_win != -1 ++ " Disable screen updates ++ let old_lazyredraw = &lazyredraw ++ set nolazyredraw ++ ++ " Save the current window number ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ if !g:Tlist_Auto_Highlight_Tag || !g:Tlist_Highlight_Tag_On_BufEnter ++ " Save the cursor position ++ let save_line = line('.') ++ let save_col = col('.') ++ endif ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(filename, ftype) ++ ++ " Open the fold for the file ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ ++ if g:Tlist_Highlight_Tag_On_BufEnter && g:Tlist_Auto_Highlight_Tag ++ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != fidx ++ " If displaying tags for only one file in the taglist ++ " window and about to display the tags for a new file, ++ " then center the current tag line for the new file ++ let center_tag_line = 1 ++ else ++ let center_tag_line = 0 ++ endif ++ ++ " Highlight the current tag ++ call s:Tlist_Window_Highlight_Tag(filename, cur_lnum, 1, center_tag_line) ++ else ++ " Restore the cursor position ++ if v:version >= 601 ++ call cursor(save_line, save_col) ++ else ++ exe save_line ++ exe 'normal! ' . save_col . '|' ++ endif ++ endif ++ ++ " Jump back to the original window ++ if save_winnr != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') ++ endif ++ ++ " Restore screen updates ++ let &lazyredraw = old_lazyredraw ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++endfunction ++ ++" Tlist_Change_Sort() ++" Change the sort order of the tag listing ++" caller == 'cmd', command used in the taglist window ++" caller == 'menu', taglist menu ++" action == 'toggle', toggle sort from name to order and vice versa ++" action == 'set', set the sort order to sort_type ++function! s:Tlist_Change_Sort(caller, action, sort_type) ++ call s:Tlist_Log_Msg('Tlist_Change_Sort (caller = ' . a:caller . ++ \ ', action = ' . a:action . ', sort_type = ' . a:sort_type . ')') ++ if a:caller == 'cmd' ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ " Remove the previous highlighting ++ match none ++ elseif a:caller == 'menu' ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx == -1 ++ return ++ endif ++ endif ++ ++ if a:action == 'toggle' ++ let sort_type = s:tlist_{fidx}_sort_type ++ ++ " Toggle the sort order from 'name' to 'order' and vice versa ++ if sort_type == 'name' ++ let s:tlist_{fidx}_sort_type = 'order' ++ else ++ let s:tlist_{fidx}_sort_type = 'name' ++ endif ++ else ++ let s:tlist_{fidx}_sort_type = a:sort_type ++ endif ++ ++ " Invalidate the tags listed for this file ++ let s:tlist_{fidx}_valid = 0 ++ ++ if a:caller == 'cmd' ++ " Save the current line for later restoration ++ let curline = '\V\^' . getline('.') . '\$' ++ ++ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, ++ \ s:tlist_{fidx}_filetype) ++ ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Go back to the cursor line before the tag list is sorted ++ call search(curline, 'w') ++ ++ call s:Tlist_Menu_Update_File(1) ++ else ++ call s:Tlist_Menu_Remove_File() ++ ++ call s:Tlist_Refresh() ++ endif ++endfunction ++ ++" Tlist_Update_Current_File() ++" Update taglist for the current buffer by regenerating the tag list ++" Contributed by WEN Guopeng. ++function! s:Tlist_Update_Current_File() ++ call s:Tlist_Log_Msg('Tlist_Update_Current_File()') ++ if winnr() == bufwinnr(g:TagList_title) ++ " In the taglist window. Update the current file ++ call s:Tlist_Window_Update_File() ++ else ++ " Not in the taglist window. Update the current buffer ++ let filename = fnamemodify(bufname('%'), ':p') ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx != -1 ++ let s:tlist_{fidx}_valid = 0 ++ endif ++ call Tlist_Update_File(filename, &filetype) ++ endif ++endfunction ++ ++" Tlist_Window_Update_File() ++" Update the tags displayed in the taglist window ++function! s:Tlist_Window_Update_File() ++ call s:Tlist_Log_Msg('Tlist_Window_Update_File()') ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ " Remove the previous highlighting ++ match none ++ ++ " Save the current line for later restoration ++ let curline = '\V\^' . getline('.') . '\$' ++ ++ let s:tlist_{fidx}_valid = 0 ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, ++ \ s:tlist_{fidx}_filetype) ++ ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Go back to the tag line before the list is updated ++ call search(curline, 'w') ++endfunction ++ ++" Tlist_Window_Get_Tag_Type_By_Linenum() ++" Return the tag type index for the specified line in the taglist window ++function! s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum) ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ " Determine to which tag type the current line number belongs to using the ++ " tag type start line number and the number of tags in a tag type ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ let start_lnum = ++ \ s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset ++ let end = start_lnum + s:tlist_{a:fidx}_{ttype}_count ++ if a:lnum >= start_lnum && a:lnum <= end ++ break ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Current line doesn't belong to any of the displayed tag types ++ if i > s:tlist_{ftype}_count ++ return '' ++ endif ++ ++ return ttype ++endfunction ++ ++" Tlist_Window_Get_Tag_Index() ++" Return the tag index for the specified line in the taglist window ++function! s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(a:fidx, a:lnum) ++ ++ " Current line doesn't belong to any of the displayed tag types ++ if ttype == '' ++ return 0 ++ endif ++ ++ " Compute the index into the displayed tags for the tag type ++ let ttype_lnum = s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset ++ let tidx = a:lnum - ttype_lnum ++ if tidx == 0 ++ return 0 ++ endif ++ ++ " Get the corresponding tag line and return it ++ return s:tlist_{a:fidx}_{ttype}_{tidx} ++endfunction ++ ++" Tlist_Window_Highlight_Line ++" Highlight the current line ++function! s:Tlist_Window_Highlight_Line() ++ " Clear previously selected name ++ match none ++ ++ " Highlight the current line ++ if g:Tlist_Display_Prototype == 0 ++ let pat = '/\%' . line('.') . 'l\s\+\zs.*/' ++ else ++ let pat = '/\%' . line('.') . 'l.*/' ++ endif ++ ++ exe 'match TagListTagName ' . pat ++endfunction ++ ++" Tlist_Window_Open_File ++" Open the specified file in either a new window or an existing window ++" and place the cursor at the specified tag pattern ++function! s:Tlist_Window_Open_File(win_ctrl, filename, tagpat) ++ call s:Tlist_Log_Msg('Tlist_Window_Open_File (' . a:filename . ',' . ++ \ a:win_ctrl . ')') ++ let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh ++ let s:Tlist_Skip_Refresh = 1 ++ ++ if s:tlist_app_name == "winmanager" ++ " Let the winmanager edit the file ++ call WinManagerFileEdit(a:filename, a:win_ctrl == 'newwin') ++ else ++ ++ if a:win_ctrl == 'newtab' ++ " Create a new tab ++ exe 'tabnew ' . escape(a:filename, ' ') ++ " Open the taglist window in the new tab ++ call s:Tlist_Window_Open() ++ endif ++ ++ if a:win_ctrl == 'checktab' ++ " Check whether the file is present in any of the tabs. ++ " If the file is present in the current tab, then use the ++ " current tab. ++ if bufwinnr(a:filename) != -1 ++ let file_present_in_tab = 1 ++ let i = tabpagenr() ++ else ++ let i = 1 ++ let bnum = bufnr(a:filename) ++ let file_present_in_tab = 0 ++ while i <= tabpagenr('$') ++ if index(tabpagebuflist(i), bnum) != -1 ++ let file_present_in_tab = 1 ++ break ++ endif ++ let i += 1 ++ endwhile ++ endif ++ ++ if file_present_in_tab ++ " Goto the tab containing the file ++ exe 'tabnext ' . i ++ else ++ " Open a new tab ++ exe 'tabnew ' . escape(a:filename, ' ') ++ ++ " Open the taglist window ++ call s:Tlist_Window_Open() ++ endif ++ endif ++ ++ let winnum = -1 ++ if a:win_ctrl == 'prevwin' ++ " Open the file in the previous window, if it is usable ++ let cur_win = winnr() ++ wincmd p ++ if &buftype == '' && !&previewwindow ++ exe "edit " . escape(a:filename, ' ') ++ let winnum = winnr() ++ else ++ " Previous window is not usable ++ exe cur_win . 'wincmd w' ++ endif ++ endif ++ ++ " Goto the window containing the file. If the window is not there, open a ++ " new window ++ if winnum == -1 ++ let winnum = bufwinnr(a:filename) ++ endif ++ ++ if winnum == -1 ++ " Locate the previously used window for opening a file ++ let fwin_num = 0 ++ let first_usable_win = 0 ++ ++ let i = 1 ++ let bnum = winbufnr(i) ++ while bnum != -1 ++ if getwinvar(i, 'tlist_file_window') == 'yes' ++ let fwin_num = i ++ break ++ endif ++ if first_usable_win == 0 && ++ \ getbufvar(bnum, '&buftype') == '' && ++ \ !getwinvar(i, '&previewwindow') ++ " First non-taglist, non-plugin and non-preview window ++ let first_usable_win = i ++ endif ++ let i = i + 1 ++ let bnum = winbufnr(i) ++ endwhile ++ ++ " If a previously used window is not found, then use the first ++ " non-taglist window ++ if fwin_num == 0 ++ let fwin_num = first_usable_win ++ endif ++ ++ if fwin_num != 0 ++ " Jump to the file window ++ exe fwin_num . "wincmd w" ++ ++ " If the user asked to jump to the tag in a new window, then split ++ " the existing window into two. ++ if a:win_ctrl == 'newwin' ++ split ++ endif ++ exe "edit " . escape(a:filename, ' ') ++ else ++ " Open a new window ++ if g:Tlist_Use_Horiz_Window ++ exe 'leftabove split ' . escape(a:filename, ' ') ++ else ++ if winbufnr(2) == -1 ++ " Only the taglist window is present ++ if g:Tlist_Use_Right_Window ++ exe 'leftabove vertical split ' . ++ \ escape(a:filename, ' ') ++ else ++ exe 'rightbelow vertical split ' . ++ \ escape(a:filename, ' ') ++ endif ++ ++ " Go to the taglist window to change the window size to ++ " the user configured value ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ if g:Tlist_Use_Horiz_Window ++ exe 'resize ' . g:Tlist_WinHeight ++ else ++ exe 'vertical resize ' . g:Tlist_WinWidth ++ endif ++ " Go back to the file window ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ else ++ " A plugin or help window is also present ++ wincmd w ++ exe 'leftabove split ' . escape(a:filename, ' ') ++ endif ++ endif ++ endif ++ " Mark the window, so that it can be reused. ++ call s:Tlist_Window_Mark_File_Window() ++ else ++ if v:version >= 700 ++ " If the file is opened in more than one window, then check ++ " whether the last accessed window has the selected file. ++ " If it does, then use that window. ++ let lastwin_bufnum = winbufnr(winnr('#')) ++ if bufnr(a:filename) == lastwin_bufnum ++ let winnum = winnr('#') ++ endif ++ endif ++ exe winnum . 'wincmd w' ++ ++ " If the user asked to jump to the tag in a new window, then split the ++ " existing window into two. ++ if a:win_ctrl == 'newwin' ++ split ++ endif ++ endif ++ endif ++ ++ " Jump to the tag ++ if a:tagpat != '' ++ " Add the current cursor position to the jump list, so that user can ++ " jump back using the ' and ` marks. ++ mark ' ++ silent call search(a:tagpat, 'w') ++ ++ " Bring the line to the middle of the window ++ normal! z. ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ endif ++ ++ " If the user selects to preview the tag then jump back to the ++ " taglist window ++ if a:win_ctrl == 'preview' ++ " Go back to the taglist window ++ let winnum = bufwinnr(g:TagList_title) ++ exe winnum . 'wincmd w' ++ else ++ " If the user has selected to close the taglist window, when a ++ " tag is selected, close the taglist window ++ if g:Tlist_Close_On_Select ++ call s:Tlist_Window_Goto_Window() ++ close ++ ++ " Go back to the window displaying the selected file ++ let wnum = bufwinnr(a:filename) ++ if wnum != -1 && wnum != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds(wnum . 'wincmd w') ++ endif ++ endif ++ endif ++ ++ let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh ++endfunction ++ ++" Tlist_Window_Jump_To_Tag() ++" Jump to the location of the current tag ++" win_ctrl == useopen - Reuse the existing file window ++" win_ctrl == newwin - Open a new window ++" win_ctrl == preview - Preview the tag ++" win_ctrl == prevwin - Open in previous window ++" win_ctrl == newtab - Open in new tab ++function! s:Tlist_Window_Jump_To_Tag(win_ctrl) ++ call s:Tlist_Log_Msg('Tlist_Window_Jump_To_Tag(' . a:win_ctrl . ')') ++ " Do not process comment lines and empty lines ++ let curline = getline('.') ++ if curline =~ '^\s*$' || curline[0] == '"' ++ return ++ endif ++ ++ " If inside a closed fold, then use the first line of the fold ++ " and jump to the file. ++ let lnum = foldclosed('.') ++ if lnum == -1 ++ " Jump to the selected tag or file ++ let lnum = line('.') ++ else ++ " Open the closed fold ++ .foldopen! ++ endif ++ ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ if fidx == -1 ++ return ++ endif ++ ++ " Get the tag output for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ if tidx != 0 ++ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, tidx) ++ ++ " Highlight the tagline ++ call s:Tlist_Window_Highlight_Line() ++ else ++ " Selected a line which is not a tag name. Just edit the file ++ let tagpat = '' ++ endif ++ ++ call s:Tlist_Window_Open_File(a:win_ctrl, s:tlist_{fidx}_filename, tagpat) ++endfunction ++ ++" Tlist_Window_Show_Info() ++" Display information about the entry under the cursor ++function! s:Tlist_Window_Show_Info() ++ call s:Tlist_Log_Msg('Tlist_Window_Show_Info()') ++ ++ " Clear the previously displayed line ++ echo ++ ++ " Do not process comment lines and empty lines ++ let curline = getline('.') ++ if curline =~ '^\s*$' || curline[0] == '"' ++ return ++ endif ++ ++ " If inside a fold, then don't display the prototype ++ if foldclosed('.') != -1 ++ return ++ endif ++ ++ let lnum = line('.') ++ ++ " Get the file index ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ if fidx == -1 ++ return ++ endif ++ ++ if lnum == s:tlist_{fidx}_start ++ " Cursor is on a file name ++ let fname = s:tlist_{fidx}_filename ++ if strlen(fname) > 50 ++ let fname = fnamemodify(fname, ':t') ++ endif ++ echo fname . ', Filetype=' . s:tlist_{fidx}_filetype . ++ \ ', Tag count=' . s:tlist_{fidx}_tag_count ++ return ++ endif ++ ++ " Get the tag output line for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ if tidx == 0 ++ " Cursor is on a tag type ++ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum) ++ if ttype == '' ++ return ++ endif ++ ++ let ttype_name = '' ++ ++ let ftype = s:tlist_{fidx}_filetype ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ if ttype == s:tlist_{ftype}_{i}_name ++ let ttype_name = s:tlist_{ftype}_{i}_fullname ++ break ++ endif ++ let i = i + 1 ++ endwhile ++ ++ echo 'Tag type=' . ttype_name . ++ \ ', Tag count=' . s:tlist_{fidx}_{ttype}_count ++ return ++ endif ++ ++ " Get the tag search pattern and display it ++ echo s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Find_Nearest_Tag_Idx ++" Find the tag idx nearest to the supplied line number ++" Returns -1, if a tag couldn't be found for the specified line number ++function! s:Tlist_Find_Nearest_Tag_Idx(fidx, linenum) ++ let sort_type = s:tlist_{a:fidx}_sort_type ++ ++ let left = 1 ++ let right = s:tlist_{a:fidx}_tag_count ++ ++ if sort_type == 'order' ++ " Tags sorted by order, use a binary search. ++ " The idea behind this function is taken from the ctags.vim script (by ++ " Alexey Marinichev) available at the Vim online website. ++ ++ " If the current line is the less than the first tag, then no need to ++ " search ++ let first_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, 1) ++ ++ if a:linenum < first_lnum ++ return -1 ++ endif ++ ++ while left < right ++ let middle = (right + left + 1) / 2 ++ let middle_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, middle) ++ ++ if middle_lnum == a:linenum ++ let left = middle ++ break ++ endif ++ ++ if middle_lnum > a:linenum ++ let right = middle - 1 ++ else ++ let left = middle ++ endif ++ endwhile ++ else ++ " Tags sorted by name, use a linear search. (contributed by Dave ++ " Eggum). ++ " Look for a tag with a line number less than or equal to the supplied ++ " line number. If multiple tags are found, then use the tag with the ++ " line number closest to the supplied line number. IOW, use the tag ++ " with the highest line number. ++ let closest_lnum = 0 ++ let final_left = 0 ++ while left <= right ++ let lnum = s:Tlist_Get_Tag_Linenum(a:fidx, left) ++ ++ if lnum < a:linenum && lnum > closest_lnum ++ let closest_lnum = lnum ++ let final_left = left ++ elseif lnum == a:linenum ++ let closest_lnum = lnum ++ let final_left = left ++ break ++ else ++ let left = left + 1 ++ endif ++ endwhile ++ if closest_lnum == 0 ++ return -1 ++ endif ++ if left >= right ++ let left = final_left ++ endif ++ endif ++ ++ return left ++endfunction ++ ++" Tlist_Window_Highlight_Tag() ++" Highlight the current tag ++" cntx == 1, Called by the taglist plugin itself ++" cntx == 2, Forced by the user through the TlistHighlightTag command ++" center = 1, move the tag line to the center of the taglist window ++function! s:Tlist_Window_Highlight_Tag(filename, cur_lnum, cntx, center) ++ " Highlight the current tag only if the user configured the ++ " taglist plugin to do so or if the user explictly invoked the ++ " command to highlight the current tag. ++ if !g:Tlist_Auto_Highlight_Tag && a:cntx == 1 ++ return ++ endif ++ ++ if a:filename == '' ++ return ++ endif ++ ++ " Make sure the taglist window is present ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Error: Taglist window is not open') ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ return ++ endif ++ ++ " If the file is currently not displayed in the taglist window, then retrn ++ if !s:tlist_{fidx}_visible ++ return ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return ++ endif ++ ++ " Ignore all autocommands ++ let old_ei = &eventignore ++ set eventignore=all ++ ++ " Save the original window number ++ let org_winnr = winnr() ++ ++ if org_winnr == winnum ++ let in_taglist_window = 1 ++ else ++ let in_taglist_window = 0 ++ endif ++ ++ " Go to the taglist window ++ if !in_taglist_window ++ exe winnum . 'wincmd w' ++ endif ++ ++ " Clear previously selected name ++ match none ++ ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, a:cur_lnum) ++ if tidx == -1 ++ " Make sure the current tag line is visible in the taglist window. ++ " Calling the winline() function makes the line visible. Don't know ++ " of a better way to achieve this. ++ let lnum = line('.') ++ ++ if lnum < s:tlist_{fidx}_start || lnum > s:tlist_{fidx}_end ++ " Move the cursor to the beginning of the file ++ exe s:tlist_{fidx}_start ++ endif ++ ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ ++ call winline() ++ ++ if !in_taglist_window ++ exe org_winnr . 'wincmd w' ++ endif ++ ++ " Restore the autocommands ++ let &eventignore = old_ei ++ return ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) ++ ++ " Compute the line number ++ " Start of file + Start of tag type + offset ++ let lnum = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_offset + ++ \ s:tlist_{fidx}_{tidx}_ttype_idx ++ ++ " Goto the line containing the tag ++ exe lnum ++ ++ " Open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ ++ if a:center ++ " Move the tag line to the center of the taglist window ++ normal! z. ++ else ++ " Make sure the current tag line is visible in the taglist window. ++ " Calling the winline() function makes the line visible. Don't know ++ " of a better way to achieve this. ++ call winline() ++ endif ++ ++ " Highlight the tag name ++ call s:Tlist_Window_Highlight_Line() ++ ++ " Go back to the original window ++ if !in_taglist_window ++ exe org_winnr . 'wincmd w' ++ endif ++ ++ " Restore the autocommands ++ let &eventignore = old_ei ++ return ++endfunction ++ ++" Tlist_Get_Tag_Prototype_By_Line ++" Get the prototype for the tag on or before the specified line number in the ++" current buffer ++function! Tlist_Get_Tag_Prototype_By_Line(...) ++ if a:0 == 0 ++ " Arguments are not supplied. Use the current buffer name ++ " and line number ++ let filename = bufname('%') ++ let linenr = line('.') ++ elseif a:0 == 2 ++ " Filename and line number are specified ++ let filename = a:1 ++ let linenr = a:2 ++ if linenr !~ '\d\+' ++ " Invalid line number ++ return "" ++ endif ++ else ++ " Sufficient arguments are not supplied ++ let msg = 'Usage: Tlist_Get_Tag_Prototype_By_Line ' . ++ \ '' ++ call s:Tlist_Warning_Msg(msg) ++ return "" ++ endif ++ ++ " Expand the file to a fully qualified name ++ let filename = fnamemodify(filename, ':p') ++ if filename == '' ++ return "" ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ return "" ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return "" ++ endif ++ ++ " Get the tag text using the line number ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr) ++ if tidx == -1 ++ return "" ++ endif ++ ++ return s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Get_Tagname_By_Line ++" Get the tag name on or before the specified line number in the ++" current buffer ++function! Tlist_Get_Tagname_By_Line(...) ++ if a:0 == 0 ++ " Arguments are not supplied. Use the current buffer name ++ " and line number ++ let filename = bufname('%') ++ let linenr = line('.') ++ elseif a:0 == 2 ++ " Filename and line number are specified ++ let filename = a:1 ++ let linenr = a:2 ++ if linenr !~ '\d\+' ++ " Invalid line number ++ return "" ++ endif ++ else ++ " Sufficient arguments are not supplied ++ let msg = 'Usage: Tlist_Get_Tagname_By_Line ' ++ call s:Tlist_Warning_Msg(msg) ++ return "" ++ endif ++ ++ " Make sure the current file has a name ++ let filename = fnamemodify(filename, ':p') ++ if filename == '' ++ return "" ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ return "" ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return "" ++ endif ++ ++ " Get the tag name using the line number ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr) ++ if tidx == -1 ++ return "" ++ endif ++ ++ return s:tlist_{fidx}_{tidx}_tag_name ++endfunction ++ ++" Tlist_Window_Move_To_File ++" Move the cursor to the beginning of the current file or the next file ++" or the previous file in the taglist window ++" dir == -1, move to start of current or previous function ++" dir == 1, move to start of next function ++function! s:Tlist_Window_Move_To_File(dir) ++ if foldlevel('.') == 0 ++ " Cursor is on a non-folded line (it is not in any of the files) ++ " Move it to a folded line ++ if a:dir == -1 ++ normal! zk ++ else ++ " While moving down to the start of the next fold, ++ " no need to do go to the start of the next file. ++ normal! zj ++ return ++ endif ++ endif ++ ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ let cur_lnum = line('.') ++ ++ if a:dir == -1 ++ if cur_lnum > s:tlist_{fidx}_start ++ " Move to the beginning of the current file ++ exe s:tlist_{fidx}_start ++ return ++ endif ++ ++ if fidx != 0 ++ " Move to the beginning of the previous file ++ let fidx = fidx - 1 ++ else ++ " Cursor is at the first file, wrap around to the last file ++ let fidx = s:tlist_file_count - 1 ++ endif ++ ++ exe s:tlist_{fidx}_start ++ return ++ else ++ " Move to the beginning of the next file ++ let fidx = fidx + 1 ++ ++ if fidx >= s:tlist_file_count ++ " Cursor is at the last file, wrap around to the first file ++ let fidx = 0 ++ endif ++ ++ if s:tlist_{fidx}_start != 0 ++ exe s:tlist_{fidx}_start ++ endif ++ return ++ endif ++endfunction ++ ++" Tlist_Session_Load ++" Load a taglist session (information about all the displayed files ++" and the tags) from the specified file ++function! s:Tlist_Session_Load(...) ++ if a:0 == 0 || a:1 == '' ++ call s:Tlist_Warning_Msg('Usage: TlistSessionLoad ') ++ return ++ endif ++ ++ let sessionfile = a:1 ++ ++ if !filereadable(sessionfile) ++ let msg = 'Taglist: Error - Unable to open file ' . sessionfile ++ call s:Tlist_Warning_Msg(msg) ++ return ++ endif ++ ++ " Mark the current window as the file window ++ call s:Tlist_Window_Mark_File_Window() ++ ++ " Source the session file ++ exe 'source ' . sessionfile ++ ++ let new_file_count = g:tlist_file_count ++ unlet! g:tlist_file_count ++ ++ let i = 0 ++ while i < new_file_count ++ let ftype = g:tlist_{i}_filetype ++ unlet! g:tlist_{i}_filetype ++ ++ if !exists('s:tlist_' . ftype . '_count') ++ if s:Tlist_FileType_Init(ftype) == 0 ++ let i = i + 1 ++ continue ++ endif ++ endif ++ ++ let fname = g:tlist_{i}_filename ++ unlet! g:tlist_{i}_filename ++ ++ let fidx = s:Tlist_Get_File_Index(fname) ++ if fidx != -1 ++ let s:tlist_{fidx}_visible = 0 ++ let i = i + 1 ++ continue ++ else ++ " As we are loading the tags from the session file, if this ++ " file was previously deleted by the user, now we need to ++ " add it back. So remove the file from the deleted list. ++ call s:Tlist_Update_Remove_List(fname, 0) ++ endif ++ ++ let fidx = s:Tlist_Init_File(fname, ftype) ++ ++ let s:tlist_{fidx}_filename = fname ++ ++ let s:tlist_{fidx}_sort_type = g:tlist_{i}_sort_type ++ unlet! g:tlist_{i}_sort_type ++ ++ let s:tlist_{fidx}_filetype = ftype ++ let s:tlist_{fidx}_mtime = getftime(fname) ++ ++ let s:tlist_{fidx}_start = 0 ++ let s:tlist_{fidx}_end = 0 ++ ++ let s:tlist_{fidx}_valid = 1 ++ ++ let s:tlist_{fidx}_tag_count = g:tlist_{i}_tag_count ++ unlet! g:tlist_{i}_tag_count ++ ++ let j = 1 ++ while j <= s:tlist_{fidx}_tag_count ++ let s:tlist_{fidx}_{j}_tag = g:tlist_{i}_{j}_tag ++ let s:tlist_{fidx}_{j}_tag_name = g:tlist_{i}_{j}_tag_name ++ let s:tlist_{fidx}_{j}_ttype_idx = g:tlist_{i}_{j}_ttype_idx ++ unlet! g:tlist_{i}_{j}_tag ++ unlet! g:tlist_{i}_{j}_tag_name ++ unlet! g:tlist_{i}_{j}_ttype_idx ++ let j = j + 1 ++ endwhile ++ ++ let j = 1 ++ while j <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{j}_name ++ ++ if exists('g:tlist_' . i . '_' . ttype) ++ let s:tlist_{fidx}_{ttype} = g:tlist_{i}_{ttype} ++ unlet! g:tlist_{i}_{ttype} ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = g:tlist_{i}_{ttype}_count ++ unlet! g:tlist_{i}_{ttype}_count ++ ++ let k = 1 ++ while k <= s:tlist_{fidx}_{ttype}_count ++ let s:tlist_{fidx}_{ttype}_{k} = g:tlist_{i}_{ttype}_{k} ++ unlet! g:tlist_{i}_{ttype}_{k} ++ let k = k + 1 ++ endwhile ++ else ++ let s:tlist_{fidx}_{ttype} = '' ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = 0 ++ endif ++ ++ let j = j + 1 ++ endwhile ++ ++ let i = i + 1 ++ endwhile ++ ++ " If the taglist window is open, then update it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ " Refresh the taglist window ++ call s:Tlist_Window_Refresh() ++ ++ " Go back to the original window ++ if save_winnr != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ endif ++endfunction ++ ++" Tlist_Session_Save ++" Save a taglist session (information about all the displayed files ++" and the tags) into the specified file ++function! s:Tlist_Session_Save(...) ++ if a:0 == 0 || a:1 == '' ++ call s:Tlist_Warning_Msg('Usage: TlistSessionSave ') ++ return ++ endif ++ ++ let sessionfile = a:1 ++ ++ if s:tlist_file_count == 0 ++ " There is nothing to save ++ call s:Tlist_Warning_Msg('Warning: Taglist is empty. Nothing to save.') ++ return ++ endif ++ ++ if filereadable(sessionfile) ++ let ans = input('Do you want to overwrite ' . sessionfile . ' (Y/N)?') ++ if ans !=? 'y' ++ return ++ endif ++ ++ echo "\n" ++ endif ++ ++ let old_verbose = &verbose ++ set verbose&vim ++ ++ exe 'redir! > ' . sessionfile ++ ++ silent! echo '" Taglist session file. This file is auto-generated.' ++ silent! echo '" File information' ++ silent! echo 'let tlist_file_count = ' . s:tlist_file_count ++ ++ let i = 0 ++ ++ while i < s:tlist_file_count ++ " Store information about the file ++ silent! echo 'let tlist_' . i . "_filename = '" . ++ \ s:tlist_{i}_filename . "'" ++ silent! echo 'let tlist_' . i . '_sort_type = "' . ++ \ s:tlist_{i}_sort_type . '"' ++ silent! echo 'let tlist_' . i . '_filetype = "' . ++ \ s:tlist_{i}_filetype . '"' ++ silent! echo 'let tlist_' . i . '_tag_count = ' . ++ \ s:tlist_{i}_tag_count ++ " Store information about all the tags ++ let j = 1 ++ while j <= s:tlist_{i}_tag_count ++ let txt = escape(s:tlist_{i}_{j}_tag, '"\\') ++ silent! echo 'let tlist_' . i . '_' . j . '_tag = "' . txt . '"' ++ silent! echo 'let tlist_' . i . '_' . j . '_tag_name = "' . ++ \ s:tlist_{i}_{j}_tag_name . '"' ++ silent! echo 'let tlist_' . i . '_' . j . '_ttype_idx' . ' = ' . ++ \ s:tlist_{i}_{j}_ttype_idx ++ let j = j + 1 ++ endwhile ++ ++ " Store information about all the tags grouped by their type ++ let ftype = s:tlist_{i}_filetype ++ let j = 1 ++ while j <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{j}_name ++ if s:tlist_{i}_{ttype}_count != 0 ++ let txt = substitute(s:tlist_{i}_{ttype}, "\n", "\\\\n", 'g') ++ silent! echo 'let tlist_' . i . '_' . ttype . ' = "' . ++ \ txt . '"' ++ silent! echo 'let tlist_' . i . '_' . ttype . '_count = ' . ++ \ s:tlist_{i}_{ttype}_count ++ let k = 1 ++ while k <= s:tlist_{i}_{ttype}_count ++ silent! echo 'let tlist_' . i . '_' . ttype . '_' . k . ++ \ ' = ' . s:tlist_{i}_{ttype}_{k} ++ let k = k + 1 ++ endwhile ++ endif ++ let j = j + 1 ++ endwhile ++ ++ silent! echo ++ ++ let i = i + 1 ++ endwhile ++ ++ redir END ++ ++ let &verbose = old_verbose ++endfunction ++ ++" Tlist_Buffer_Removed ++" A buffer is removed from the Vim buffer list. Remove the tags defined ++" for that file ++function! s:Tlist_Buffer_Removed(filename) ++ call s:Tlist_Log_Msg('Tlist_Buffer_Removed (' . a:filename . ')') ++ ++ " Make sure a valid filename is supplied ++ if a:filename == '' ++ return ++ endif ++ ++ " Get tag list index of the specified file ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ " File not present in the taglist ++ return ++ endif ++ ++ " Remove the file from the list ++ call s:Tlist_Remove_File(fidx, 0) ++endfunction ++ ++" When a buffer is deleted, remove the file from the taglist ++autocmd BufDelete * silent call s:Tlist_Buffer_Removed(expand(':p')) ++ ++" Tlist_Window_Open_File_Fold ++" Open the fold for the specified file and close the fold for all the ++" other files ++function! s:Tlist_Window_Open_File_Fold(acmd_file) ++ call s:Tlist_Log_Msg('Tlist_Window_Open_File_Fold (' . a:acmd_file . ')') ++ ++ " Make sure the taglist window is present ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Taglist: Error - Taglist window is not open') ++ return ++ endif ++ ++ " Save the original window number ++ let org_winnr = winnr() ++ if org_winnr == winnum ++ let in_taglist_window = 1 ++ else ++ let in_taglist_window = 0 ++ endif ++ ++ if in_taglist_window ++ " When entering the taglist window, no need to update the folds ++ return ++ endif ++ ++ " Go to the taglist window ++ if !in_taglist_window ++ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') ++ endif ++ ++ " Close all the folds ++ silent! %foldclose ++ ++ " Get tag list index of the specified file ++ let fname = fnamemodify(a:acmd_file, ":p") ++ if filereadable(fname) ++ let fidx = s:Tlist_Get_File_Index(fname) ++ if fidx != -1 ++ " Open the fold for the file ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen" ++ endif ++ endif ++ ++ " Go back to the original window ++ if !in_taglist_window ++ call s:Tlist_Exe_Cmd_No_Acmds(org_winnr . 'wincmd w') ++ endif ++endfunction ++ ++" Tlist_Window_Check_Auto_Open ++" Open the taglist window automatically on Vim startup. ++" Open the window only when files present in any of the Vim windows support ++" tags. ++function! s:Tlist_Window_Check_Auto_Open() ++ let open_window = 0 ++ ++ let i = 1 ++ let buf_num = winbufnr(i) ++ while buf_num != -1 ++ let filename = fnamemodify(bufname(buf_num), ':p') ++ if !s:Tlist_Skip_File(filename, getbufvar(buf_num, '&filetype')) ++ let open_window = 1 ++ break ++ endif ++ let i = i + 1 ++ let buf_num = winbufnr(i) ++ endwhile ++ ++ if open_window ++ call s:Tlist_Window_Toggle() ++ endif ++endfunction ++ ++function! s:Tlist_Menu_Add_Base_Menu() ++ call s:Tlist_Log_Msg('Adding the base menu') ++ ++ " Add the menu ++ anoremenu T&ags.Refresh\ menu :call Tlist_Menu_Refresh() ++ anoremenu T&ags.Sort\ menu\ by.Name ++ \ :call Tlist_Change_Sort('menu', 'set', 'name') ++ anoremenu T&ags.Sort\ menu\ by.Order ++ \ :call Tlist_Change_Sort('menu', 'set', 'order') ++ anoremenu T&ags.-SEP1- : ++ ++ if &mousemodel =~ 'popup' ++ anoremenu PopUp.T&ags.Refresh\ menu ++ \ :call Tlist_Menu_Refresh() ++ anoremenu PopUp.T&ags.Sort\ menu\ by.Name ++ \ :call Tlist_Change_Sort('menu', 'set', 'name') ++ anoremenu PopUp.T&ags.Sort\ menu\ by.Order ++ \ :call Tlist_Change_Sort('menu', 'set', 'order') ++ anoremenu PopUp.T&ags.-SEP1- : ++ endif ++endfunction ++ ++let s:menu_char_prefix = ++ \ '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ++ ++" Tlist_Menu_Get_Tag_Type_Cmd ++" Get the menu command for the specified tag type ++" fidx - File type index ++" ftype - File Type ++" add_ttype_name - To add or not to add the tag type name to the menu entries ++" ttype_idx - Tag type index ++function! s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, ttype_idx) ++ " Curly brace variable name optimization ++ let ftype_ttype_idx = a:ftype . '_' . a:ttype_idx ++ ++ let ttype = s:tlist_{ftype_ttype_idx}_name ++ if a:add_ttype_name ++ " If the tag type name contains space characters, escape it. This ++ " will be used to create the menu entries. ++ let ttype_fullname = escape(s:tlist_{ftype_ttype_idx}_fullname, ' ') ++ endif ++ ++ " Curly brace variable name optimization ++ let fidx_ttype = a:fidx . '_' . ttype ++ ++ " Number of tag entries for this tag type ++ let tcnt = s:tlist_{fidx_ttype}_count ++ if tcnt == 0 " No entries for this tag type ++ return '' ++ endif ++ ++ let mcmd = '' ++ ++ " Create the menu items for the tags. ++ " Depending on the number of tags of this type, split the menu into ++ " multiple sub-menus, if needed. ++ if tcnt > g:Tlist_Max_Submenu_Items ++ let j = 1 ++ while j <= tcnt ++ let final_index = j + g:Tlist_Max_Submenu_Items - 1 ++ if final_index > tcnt ++ let final_index = tcnt ++ endif ++ ++ " Extract the first and last tag name and form the ++ " sub-menu name ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ let first_tag = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let tidx = s:tlist_{fidx_ttype}_{final_index} ++ let last_tag = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ " Truncate the names, if they are greater than the ++ " max length ++ let first_tag = strpart(first_tag, 0, g:Tlist_Max_Tag_Length) ++ let last_tag = strpart(last_tag, 0, g:Tlist_Max_Tag_Length) ++ ++ " Form the menu command prefix ++ let m_prefix = 'anoremenu T\&ags.' ++ if a:add_ttype_name ++ let m_prefix = m_prefix . ttype_fullname . '.' ++ endif ++ let m_prefix = m_prefix . first_tag . '\.\.\.' . last_tag . '.' ++ ++ " Character prefix used to number the menu items (hotkey) ++ let m_prefix_idx = 0 ++ ++ while j <= final_index ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ ++ let tname = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let mcmd = mcmd . m_prefix . '\&' . ++ \ s:menu_char_prefix[m_prefix_idx] . '\.' . ++ \ tname . ' :call Tlist_Menu_Jump_To_Tag(' . ++ \ tidx . ')|' ++ ++ let m_prefix_idx = m_prefix_idx + 1 ++ let j = j + 1 ++ endwhile ++ endwhile ++ else ++ " Character prefix used to number the menu items (hotkey) ++ let m_prefix_idx = 0 ++ ++ let m_prefix = 'anoremenu T\&ags.' ++ if a:add_ttype_name ++ let m_prefix = m_prefix . ttype_fullname . '.' ++ endif ++ let j = 1 ++ while j <= tcnt ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ ++ let tname = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let mcmd = mcmd . m_prefix . '\&' . ++ \ s:menu_char_prefix[m_prefix_idx] . '\.' . ++ \ tname . ' :call Tlist_Menu_Jump_To_Tag(' . tidx ++ \ . ')|' ++ ++ let m_prefix_idx = m_prefix_idx + 1 ++ let j = j + 1 ++ endwhile ++ endif ++ ++ return mcmd ++endfunction ++ ++" Update the taglist menu with the tags for the specified file ++function! s:Tlist_Menu_File_Refresh(fidx) ++ call s:Tlist_Log_Msg('Refreshing the tag menu for ' . s:tlist_{a:fidx}_filename) ++ " The 'B' flag is needed in the 'cpoptions' option ++ let old_cpoptions = &cpoptions ++ set cpoptions&vim ++ ++ exe s:tlist_{a:fidx}_menu_cmd ++ ++ " Update the popup menu (if enabled) ++ if &mousemodel =~ 'popup' ++ let cmd = substitute(s:tlist_{a:fidx}_menu_cmd, ' T\\&ags\.', ++ \ ' PopUp.T\\\&ags.', "g") ++ exe cmd ++ endif ++ ++ " The taglist menu is not empty now ++ let s:tlist_menu_empty = 0 ++ ++ " Restore the 'cpoptions' settings ++ let &cpoptions = old_cpoptions ++endfunction ++ ++" Tlist_Menu_Update_File ++" Add the taglist menu ++function! s:Tlist_Menu_Update_File(clear_menu) ++ if !has('gui_running') ++ " Not running in GUI mode ++ return ++ endif ++ ++ call s:Tlist_Log_Msg('Updating the tag menu, clear_menu = ' . a:clear_menu) ++ ++ " Remove the tags menu ++ if a:clear_menu ++ call s:Tlist_Menu_Remove_File() ++ ++ endif ++ ++ let fname = escape(fnamemodify(bufname('%'), ':t'), '.') ++ if fname != '' ++ exe 'anoremenu T&ags.' . fname . ' ' ++ anoremenu T&ags.-SEP2- : ++ endif ++ ++ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help ++ if &buftype != '' ++ return ++ endif ++ ++ let filename = fnamemodify(bufname('%'), ':p') ++ let ftype = &filetype ++ ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(filename, ftype) ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 || !s:tlist_{fidx}_valid ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(filename) ++ return ++ endif ++ ++ " Process the tags for the file ++ let fidx = s:Tlist_Process_File(filename, ftype) ++ if fidx == -1 ++ return ++ endif ++ endif ++ ++ if !s:tlist_{fidx}_tag_count ++ return ++ endif ++ ++ if s:tlist_{fidx}_menu_cmd != '' ++ " Update the menu with the cached command ++ call s:Tlist_Menu_File_Refresh(fidx) ++ ++ return ++ endif ++ ++ " We are going to add entries to the tags menu, so the menu won't be ++ " empty ++ let s:tlist_menu_empty = 0 ++ ++ let cmd = '' ++ ++ " Determine whether the tag type name needs to be added to the menu ++ " If more than one tag type is present in the taglisting for a file, ++ " then the tag type name needs to be present ++ let add_ttype_name = -1 ++ let i = 1 ++ while i <= s:tlist_{ftype}_count && add_ttype_name < 1 ++ let ttype = s:tlist_{ftype}_{i}_name ++ if s:tlist_{fidx}_{ttype}_count ++ let add_ttype_name = add_ttype_name + 1 ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Process the tags by the tag type and get the menu command ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let mcmd = s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, i) ++ if mcmd != '' ++ let cmd = cmd . mcmd ++ endif ++ ++ let i = i + 1 ++ endwhile ++ ++ " Cache the menu command for reuse ++ let s:tlist_{fidx}_menu_cmd = cmd ++ ++ " Update the menu ++ call s:Tlist_Menu_File_Refresh(fidx) ++endfunction ++ ++" Tlist_Menu_Remove_File ++" Remove the tags displayed in the tags menu ++function! s:Tlist_Menu_Remove_File() ++ if !has('gui_running') || s:tlist_menu_empty ++ return ++ endif ++ ++ call s:Tlist_Log_Msg('Removing the tags menu for a file') ++ ++ " Cleanup the Tags menu ++ silent! unmenu T&ags ++ if &mousemodel =~ 'popup' ++ silent! unmenu PopUp.T&ags ++ endif ++ ++ " Add a dummy menu item to retain teared off menu ++ noremenu T&ags.Dummy l ++ ++ silent! unmenu! T&ags ++ if &mousemodel =~ 'popup' ++ silent! unmenu! PopUp.T&ags ++ endif ++ ++ call s:Tlist_Menu_Add_Base_Menu() ++ ++ " Remove the dummy menu item ++ unmenu T&ags.Dummy ++ ++ let s:tlist_menu_empty = 1 ++endfunction ++ ++" Tlist_Menu_Refresh ++" Refresh the taglist menu ++function! s:Tlist_Menu_Refresh() ++ call s:Tlist_Log_Msg('Refreshing the tags menu') ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx != -1 ++ " Invalidate the cached menu command ++ let s:tlist_{fidx}_menu_cmd = '' ++ endif ++ ++ " Update the taglist, menu and window ++ call s:Tlist_Update_Current_File() ++endfunction ++ ++" Tlist_Menu_Jump_To_Tag ++" Jump to the selected tag ++function! s:Tlist_Menu_Jump_To_Tag(tidx) ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx == -1 ++ return ++ endif ++ ++ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, a:tidx) ++ if tagpat == '' ++ return ++ endif ++ ++ " Add the current cursor position to the jump list, so that user can ++ " jump back using the ' and ` marks. ++ mark ' ++ ++ silent call search(tagpat, 'w') ++ ++ " Bring the line to the middle of the window ++ normal! z. ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++endfunction ++ ++" Tlist_Menu_Init ++" Initialize the taglist menu ++function! s:Tlist_Menu_Init() ++ call s:Tlist_Menu_Add_Base_Menu() ++ ++ " Automatically add the tags defined in the current file to the menu ++ augroup TagListMenuCmds ++ autocmd! ++ ++ if !g:Tlist_Process_File_Always ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ autocmd BufLeave * call s:Tlist_Menu_Remove_File() ++ augroup end ++ ++ call s:Tlist_Menu_Update_File(0) ++endfunction ++ ++" Tlist_Vim_Session_Load ++" Initialize the taglist window/buffer, which is created when loading ++" a Vim session file. ++function! s:Tlist_Vim_Session_Load() ++ call s:Tlist_Log_Msg('Tlist_Vim_Session_Load') ++ ++ " Initialize the taglist window ++ call s:Tlist_Window_Init() ++ ++ " Refresh the taglist window ++ call s:Tlist_Window_Refresh() ++endfunction ++ ++" Tlist_Set_App ++" Set the name of the external plugin/application to which taglist ++" belongs. ++" Taglist plugin is part of another plugin like cream or winmanager. ++function! Tlist_Set_App(name) ++ if a:name == "" ++ return ++ endif ++ ++ let s:tlist_app_name = a:name ++endfunction ++ ++" Winmanager integration ++ ++" Initialization required for integration with winmanager ++function! TagList_Start() ++ " If current buffer is not taglist buffer, then don't proceed ++ if bufname('%') != '__Tag_List__' ++ return ++ endif ++ ++ call Tlist_Set_App('winmanager') ++ ++ " Get the current filename from the winmanager plugin ++ let bufnum = WinManagerGetLastEditedFile() ++ if bufnum != -1 ++ let filename = fnamemodify(bufname(bufnum), ':p') ++ let ftype = getbufvar(bufnum, '&filetype') ++ endif ++ ++ " Initialize the taglist window, if it is not already initialized ++ if !exists('s:tlist_window_initialized') || !s:tlist_window_initialized ++ call s:Tlist_Window_Init() ++ call s:Tlist_Window_Refresh() ++ let s:tlist_window_initialized = 1 ++ endif ++ ++ " Update the taglist window ++ if bufnum != -1 ++ if !s:Tlist_Skip_File(filename, ftype) && g:Tlist_Auto_Update ++ call s:Tlist_Window_Refresh_File(filename, ftype) ++ endif ++ endif ++endfunction ++ ++function! TagList_IsValid() ++ return 0 ++endfunction ++ ++function! TagList_WrapUp() ++ return 0 ++endfunction ++ ++" restore 'cpo' ++let &cpo = s:cpo_save ++unlet s:cpo_save ++ +diff -urN vim71/1/SCRIPTS/Diff_All.cmd vim71_ada/1/SCRIPTS/Diff_All.cmd +--- vim71/1/SCRIPTS/Diff_All.cmd 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/Diff_All.cmd 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++C:\bin\Vim\vim70\gvim -g -d --nofork .\indent\ada.vim %HOME%\vimfiles\indent\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\ftdetect\ada.vim %HOME%\vimfiles\ftdetect\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\syntax\ada.vim %HOME%\vimfiles\syntax\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\ftplugin\ada.vim %HOME%\vimfiles\ftplugin\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\compiler\gnat.vim %HOME%\vimfiles\compiler\gnat.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\plugin\rainbow_parenthsis.vim %HOME%\vimfiles\plugin\rainbow_parenthsis.vim +diff -urN vim71/1/SCRIPTS/Diff_Home.zsh vim71_ada/1/SCRIPTS/Diff_Home.zsh +--- vim71/1/SCRIPTS/Diff_Home.zsh 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/Diff_Home.zsh 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,24 @@ ++#!/bin/zsh ++ ++setopt No_X_Trace; ++setopt Glob; ++setopt Extended_Glob; ++setopt Null_Glob; ++ ++pushd ..; ++ for I in \ ++ **/*.vim \ ++ macros/[[:alnum:]]##.bash \ ++ macros/[[:alnum:]]##.zsh \ ++ doc/[[:alnum:]]##.txt ; ++ do ++ if diff --brief --report-identical-files "${I}" ~/vimfiles/"${I}"; then ++ echo "do nothing"; ++ else ++ gvimdiff --nofork "${I}" ~/vimfiles/"${I}" ++ fi; ++ done; unset I; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/Diff_Portable.bash vim71_ada/1/SCRIPTS/Diff_Portable.bash +--- vim71/1/SCRIPTS/Diff_Portable.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/Diff_Portable.bash 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,37 @@ ++#!/bin/bash ++ ++source /etc/profile.d/vim.bash ++set -o xtrace; ++ ++declare -r in_Target_Base="${1}" ++ ++declare -x VIMBIN='/opt/gnat/tools/bin'; ++declare -x VIM='/opt/gnat/tools/share/vim'; ++declare -x VIMRUNTIME='/opt/gnat/tools/share/vim/vim71'; ++declare -x Target="${in_Target_Base}/Bin/GVimPortable/App/vim/vimfiles"; ++ ++function Compare () ++ { ++ local in_File="${0}"; ++ ++ if diff --brief --report-identical-files "${in_File}" "${Target}/${in_File}"; then ++ echo "do nothing"; ++ else ++ ${VIMBIN}/gvim -d --nofork "${in_File}" "${Target}/${in_File}" ++ fi; ++ } ++declare -x -f Compare; ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -iregex ".*/macros/[a-z_0-9]*.bash" -o \ ++ -iregex ".*/doc/[a-z_0-9]*.txt" \ ++ ')' \ ++ -exec \ ++ /bin/bash -c Compare '{}' ';' ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/Diff_Source.bash vim71_ada/1/SCRIPTS/Diff_Source.bash +--- vim71/1/SCRIPTS/Diff_Source.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/Diff_Source.bash 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,43 @@ ++#!/bin/bash ++ ++source /etc/profile.d/vim.bash ++set -o xtrace; ++ ++#declare -x VIMBIN='/cygdrive/c/bin/Vim/vim71'; ++ ++declare -x VIMBIN='/opt/gnat/tools/bin'; ++declare -x VIM='/opt/gnat/tools/share/vim'; ++declare -x VIMRUNTIME='/opt/gnat/tools/share/vim/vim71'; ++declare -x Target="../../rpm/BUILD/vim-runtime-$(date +%d%m%Y)" ++declare -x -f Compare; ++ ++function Compare () ++ { ++ local in_File="${0}"; ++ ++ if test -f ${Target}/${in_File} ; then ++ if diff --brief --report-identical-files "${in_File}" "${Target}/${in_File}" ; then ++ echo "do nothing"; ++ else ++ ${VIMBIN}/gvim -d --nofork "${in_File}" "${Target}/${in_File}"; ++ fi; ++ else ++ echo "${in_File} not part of the main runtime"; ++ fi; ++ ++ return; ++ } ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -iregex ".*/macros/[a-z_0-9]*.bash" -o \ ++ -iregex ".*/doc/[a-z_0-9]*.txt" \ ++ ')' \ ++ -exec \ ++ /bin/bash -c Compare '{}' ';' ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/Edit_All.bash vim71_ada/1/SCRIPTS/Edit_All.bash +--- vim71/1/SCRIPTS/Edit_All.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/Edit_All.bash 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++#!/bin/bash ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -iregex ".*/doc/[a-z_]*.txt" \ ++ ')' \ ++ -print | \ ++ xargs --replace --max-args=64 \ ++ /opt/gnat/tools/bin/gvim \ ++ --servername "Edit All" \ ++ --remote-silent ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/Make_Tar.bash vim71_ada/1/SCRIPTS/Make_Tar.bash +--- vim71/1/SCRIPTS/Make_Tar.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/Make_Tar.bash 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,20 @@ ++#!/bin/bash ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -ipath "./macros/*.bash" -o \ ++ -iregex ".*/doc/[a-z]*.txt" \ ++ ')' \ ++ -print | \ ++ xargs \ ++ tar \ ++ --create \ ++ --bzip2 \ ++ --verbose \ ++ --file=ada_vimfiles.tar-bz2 ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/.svn/all-wcprops vim71_ada/1/SCRIPTS/.svn/all-wcprops +--- vim71/1/SCRIPTS/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,41 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 52 ++/svnroot/gnuada/!svn/ver/773/trunk/tools/vim/SCRIPTS ++END ++Make_Tar.bash ++K 25 ++svn:wc:ra_dav:version-url ++V 66 ++/svnroot/gnuada/!svn/ver/342/trunk/tools/vim/SCRIPTS/Make_Tar.bash ++END ++Diff_All.cmd ++K 25 ++svn:wc:ra_dav:version-url ++V 65 ++/svnroot/gnuada/!svn/ver/773/trunk/tools/vim/SCRIPTS/Diff_All.cmd ++END ++Diff_Home.zsh ++K 25 ++svn:wc:ra_dav:version-url ++V 66 ++/svnroot/gnuada/!svn/ver/695/trunk/tools/vim/SCRIPTS/Diff_Home.zsh ++END ++Diff_Source.bash ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/svnroot/gnuada/!svn/ver/743/trunk/tools/vim/SCRIPTS/Diff_Source.bash ++END ++Edit_All.bash ++K 25 ++svn:wc:ra_dav:version-url ++V 66 ++/svnroot/gnuada/!svn/ver/429/trunk/tools/vim/SCRIPTS/Edit_All.bash ++END ++Diff_Portable.bash ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/svnroot/gnuada/!svn/ver/743/trunk/tools/vim/SCRIPTS/Diff_Portable.bash ++END +diff -urN vim71/1/SCRIPTS/.svn/dir-prop-base vim71_ada/1/SCRIPTS/.svn/dir-prop-base +--- vim71/1/SCRIPTS/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/SCRIPTS/.svn/entries vim71_ada/1/SCRIPTS/.svn/entries +--- vim71/1/SCRIPTS/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,106 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/SCRIPTS ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-09-17T08:58:57.545957Z ++773 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++Make_Tar.bash ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++8fa993957020a567d7d18cf275f79f85 ++2006-07-27T19:03:11.250838Z ++342 ++krischik ++has-props ++ ++Diff_All.cmd ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++e5a39f09b8532487297a2b21ce18539c ++2007-09-17T08:58:57.545957Z ++773 ++krischik ++has-props ++ ++Diff_Home.zsh ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++2467db473cdf6e65848a2f29a33da0dc ++2007-04-27T17:57:11.151403Z ++695 ++krischik ++has-props ++ ++Diff_Source.bash ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++bfe42019807a5f00339c2a577835a52f ++2007-07-08T15:01:50.709462Z ++743 ++krischik ++has-props ++ ++Edit_All.bash ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++386419783256e147810d36e58847f593 ++2006-10-15T17:43:45.084385Z ++429 ++krischik ++has-props ++ ++Diff_Portable.bash ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++6fbd7df3976bc16679aa4dd121ad4723 ++2007-07-08T15:01:50.709462Z ++743 ++krischik ++has-props ++ +diff -urN vim71/1/SCRIPTS/.svn/format vim71_ada/1/SCRIPTS/.svn/format +--- vim71/1/SCRIPTS/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/format 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/SCRIPTS/.svn/prop-base/Diff_All.cmd.svn-base vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_All.cmd.svn-base +--- vim71/1/SCRIPTS/.svn/prop-base/Diff_All.cmd.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_All.cmd.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 15 ++text/x-dosbatch ++END +diff -urN vim71/1/SCRIPTS/.svn/prop-base/Diff_Home.zsh.svn-base vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_Home.zsh.svn-base +--- vim71/1/SCRIPTS/.svn/prop-base/Diff_Home.zsh.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_Home.zsh.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/SCRIPTS/.svn/prop-base/Diff_Portable.bash.svn-base vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_Portable.bash.svn-base +--- vim71/1/SCRIPTS/.svn/prop-base/Diff_Portable.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_Portable.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/SCRIPTS/.svn/prop-base/Diff_Source.bash.svn-base vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_Source.bash.svn-base +--- vim71/1/SCRIPTS/.svn/prop-base/Diff_Source.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/prop-base/Diff_Source.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/SCRIPTS/.svn/prop-base/Edit_All.bash.svn-base vim71_ada/1/SCRIPTS/.svn/prop-base/Edit_All.bash.svn-base +--- vim71/1/SCRIPTS/.svn/prop-base/Edit_All.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/prop-base/Edit_All.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/SCRIPTS/.svn/prop-base/Make_Tar.bash.svn-base vim71_ada/1/SCRIPTS/.svn/prop-base/Make_Tar.bash.svn-base +--- vim71/1/SCRIPTS/.svn/prop-base/Make_Tar.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/prop-base/Make_Tar.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 9 ++text/x-sh ++END +diff -urN vim71/1/SCRIPTS/.svn/text-base/Diff_All.cmd.svn-base vim71_ada/1/SCRIPTS/.svn/text-base/Diff_All.cmd.svn-base +--- vim71/1/SCRIPTS/.svn/text-base/Diff_All.cmd.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/text-base/Diff_All.cmd.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++C:\bin\Vim\vim70\gvim -g -d --nofork .\indent\ada.vim %HOME%\vimfiles\indent\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\ftdetect\ada.vim %HOME%\vimfiles\ftdetect\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\syntax\ada.vim %HOME%\vimfiles\syntax\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\ftplugin\ada.vim %HOME%\vimfiles\ftplugin\ada.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\compiler\gnat.vim %HOME%\vimfiles\compiler\gnat.vim ++C:\bin\Vim\vim70\gvim -g -d --nofork .\plugin\rainbow_parenthsis.vim %HOME%\vimfiles\plugin\rainbow_parenthsis.vim +diff -urN vim71/1/SCRIPTS/.svn/text-base/Diff_Home.zsh.svn-base vim71_ada/1/SCRIPTS/.svn/text-base/Diff_Home.zsh.svn-base +--- vim71/1/SCRIPTS/.svn/text-base/Diff_Home.zsh.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/text-base/Diff_Home.zsh.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,24 @@ ++#!/bin/zsh ++ ++setopt No_X_Trace; ++setopt Glob; ++setopt Extended_Glob; ++setopt Null_Glob; ++ ++pushd ..; ++ for I in \ ++ **/*.vim \ ++ macros/[[:alnum:]]##.bash \ ++ macros/[[:alnum:]]##.zsh \ ++ doc/[[:alnum:]]##.txt ; ++ do ++ if diff --brief --report-identical-files "${I}" ~/vimfiles/"${I}"; then ++ echo "do nothing"; ++ else ++ gvimdiff --nofork "${I}" ~/vimfiles/"${I}" ++ fi; ++ done; unset I; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/.svn/text-base/Diff_Portable.bash.svn-base vim71_ada/1/SCRIPTS/.svn/text-base/Diff_Portable.bash.svn-base +--- vim71/1/SCRIPTS/.svn/text-base/Diff_Portable.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/text-base/Diff_Portable.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,37 @@ ++#!/bin/bash ++ ++source /etc/profile.d/vim.bash ++set -o xtrace; ++ ++declare -r in_Target_Base="${1}" ++ ++declare -x VIMBIN='/opt/gnat/tools/bin'; ++declare -x VIM='/opt/gnat/tools/share/vim'; ++declare -x VIMRUNTIME='/opt/gnat/tools/share/vim/vim71'; ++declare -x Target="${in_Target_Base}/Bin/GVimPortable/App/vim/vimfiles"; ++ ++function Compare () ++ { ++ local in_File="${0}"; ++ ++ if diff --brief --report-identical-files "${in_File}" "${Target}/${in_File}"; then ++ echo "do nothing"; ++ else ++ ${VIMBIN}/gvim -d --nofork "${in_File}" "${Target}/${in_File}" ++ fi; ++ } ++declare -x -f Compare; ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -iregex ".*/macros/[a-z_0-9]*.bash" -o \ ++ -iregex ".*/doc/[a-z_0-9]*.txt" \ ++ ')' \ ++ -exec \ ++ /bin/bash -c Compare '{}' ';' ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/.svn/text-base/Diff_Source.bash.svn-base vim71_ada/1/SCRIPTS/.svn/text-base/Diff_Source.bash.svn-base +--- vim71/1/SCRIPTS/.svn/text-base/Diff_Source.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/text-base/Diff_Source.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,43 @@ ++#!/bin/bash ++ ++source /etc/profile.d/vim.bash ++set -o xtrace; ++ ++#declare -x VIMBIN='/cygdrive/c/bin/Vim/vim71'; ++ ++declare -x VIMBIN='/opt/gnat/tools/bin'; ++declare -x VIM='/opt/gnat/tools/share/vim'; ++declare -x VIMRUNTIME='/opt/gnat/tools/share/vim/vim71'; ++declare -x Target="../../rpm/BUILD/vim-runtime-$(date +%d%m%Y)" ++declare -x -f Compare; ++ ++function Compare () ++ { ++ local in_File="${0}"; ++ ++ if test -f ${Target}/${in_File} ; then ++ if diff --brief --report-identical-files "${in_File}" "${Target}/${in_File}" ; then ++ echo "do nothing"; ++ else ++ ${VIMBIN}/gvim -d --nofork "${in_File}" "${Target}/${in_File}"; ++ fi; ++ else ++ echo "${in_File} not part of the main runtime"; ++ fi; ++ ++ return; ++ } ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -iregex ".*/macros/[a-z_0-9]*.bash" -o \ ++ -iregex ".*/doc/[a-z_0-9]*.txt" \ ++ ')' \ ++ -exec \ ++ /bin/bash -c Compare '{}' ';' ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/.svn/text-base/Edit_All.bash.svn-base vim71_ada/1/SCRIPTS/.svn/text-base/Edit_All.bash.svn-base +--- vim71/1/SCRIPTS/.svn/text-base/Edit_All.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/text-base/Edit_All.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++#!/bin/bash ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -iregex ".*/doc/[a-z_]*.txt" \ ++ ')' \ ++ -print | \ ++ xargs --replace --max-args=64 \ ++ /opt/gnat/tools/bin/gvim \ ++ --servername "Edit All" \ ++ --remote-silent ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/SCRIPTS/.svn/text-base/Make_Tar.bash.svn-base vim71_ada/1/SCRIPTS/.svn/text-base/Make_Tar.bash.svn-base +--- vim71/1/SCRIPTS/.svn/text-base/Make_Tar.bash.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/SCRIPTS/.svn/text-base/Make_Tar.bash.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,20 @@ ++#!/bin/bash ++ ++pushd ..; ++ find . \ ++ '(' \ ++ -iname "*.vim" -o \ ++ -ipath "./macros/*.bash" -o \ ++ -iregex ".*/doc/[a-z]*.txt" \ ++ ')' \ ++ -print | \ ++ xargs \ ++ tar \ ++ --create \ ++ --bzip2 \ ++ --verbose \ ++ --file=ada_vimfiles.tar-bz2 ; ++popd; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix +diff -urN vim71/1/.svn/all-wcprops vim71_ada/1/.svn/all-wcprops +--- vim71/1/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,11 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 44 ++/svnroot/gnuada/!svn/ver/825/trunk/tools/vim ++END ++ada_options.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 60 ++/svnroot/gnuada/!svn/ver/774/trunk/tools/vim/ada_options.vim ++END +diff -urN vim71/1/.svn/dir-prop-base vim71_ada/1/.svn/dir-prop-base +--- vim71/1/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,8 @@ ++K 10 ++svn:ignore ++V 25 ++.backups ++*.tar-bz2 ++*.vba ++ ++END +diff -urN vim71/1/.svn/entries vim71_ada/1/.svn/entries +--- vim71/1/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,74 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-12-09T13:34:03.484664Z ++825 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++colors ++dir ++ ++indent ++dir ++ ++ftdetect ++dir ++ ++macros ++dir ++ ++doc ++dir ++ ++syntax ++dir ++ ++SCRIPTS ++dir ++ ++autoload ++dir ++ ++ftplugin ++dir ++ ++compiler ++dir ++ ++ada_options.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++2ed6ca5b229dcdc415152a2bcb6f1b31 ++2007-09-17T09:11:59.633161Z ++774 ++krischik ++has-props ++ ++plugin ++dir ++ +diff -urN vim71/1/.svn/format vim71_ada/1/.svn/format +--- vim71/1/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/.svn/format 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/.svn/prop-base/ada_options.vim.svn-base vim71_ada/1/.svn/prop-base/ada_options.vim.svn-base +--- vim71/1/.svn/prop-base/ada_options.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/.svn/prop-base/ada_options.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/.svn/text-base/ada_options.vim.svn-base vim71_ada/1/.svn/text-base/ada_options.vim.svn-base +--- vim71/1/.svn/text-base/ada_options.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/.svn/text-base/ada_options.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,105 @@ ++"------------------------------------------------------------------------------ ++" Description: Options setable by the Ada plugin ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" History: 24.05.2006 MK Unified Headers ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Folding for "gnat pretty" ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Bram suggested to save on spaces ++" Usage: copy content into your .vimrc and change options to your ++" likeing. ++" Help Page: ft-ada-options ++"------------------------------------------------------------------------------ ++ ++echoerr 'It is suggested to copy the content of ada_options into .vimrc!' ++finish " 1}}} ++ ++" Section: Ada options {{{1 ++ ++ let g:ada_abbrev = 1 ++ let g:ada_default_compiler = 'gnat' ++ let g:ada_extended_tagging = 'list' ++ let g:ada_folding = 'i' ++" let g:ada_folding = 'gibxp' ++" let g:ada_folding = 'spftc' ++ let g:ada_rainbow_color = 1 ++ let g:ada_space_errors = 1 ++ let g:ada_standard_types = 1 ++ let g:ada_with_gnat_project_files = 1 ++" let g:ada_extended_completion = 1 ++" let g:ada_line_errors = 1 ++" let g:ada_omni_with_keywords = 1 ++ ++ let g:Tlist_Exit_OnlyWindow = 1 ++ let g:Tlist_File_Fold_Auto_Close = 1 ++ let g:Tlist_Sort_Type = "name" ++ ++ let g:NERD_use_ada_with_spaces = 1 ++ ++ let g:backup_directory = '.backups' ++ let g:backup_purge = 10 ++ ++ let g:mapleader = "" ++ ++ if &diff ++ let g:Tlist_Auto_Open = 0 ++ else ++ let g:Tlist_Auto_Open = 1 ++ endif ++ ++ filetype plugin indent on ++ syntax enable ++ ++" }}}1 ++ ++" Section: Vimball options {{{1 ++:set expandtab fileformat=unix encoding=utf-8 ++:.+2,.+13 MkVimball ada-4.5.0 ++ ++ada_options.vim ++autoload/ada.vim ++autoload/adacomplete.vim ++autoload/decada.vim ++autoload/gnat.vim ++compiler/decada.vim ++compiler/gnat.vim ++doc/ft_ada.txt ++ftdetect/ada.vim ++ftplugin/ada.vim ++indent/ada.vim ++syntax/ada.vim ++ ++" }}}1 ++ ++" Section: Tar options {{{1 ++ ++tar --create --bzip2 \ ++ --file="ada-4.5.0.tar.bz2" \ ++ autoload/ada.vim \ ++ autoload/adacomplete.vim \ ++ autoload/decada.vim \ ++ autoload/gnat.vim \ ++ compiler/decada.vim \ ++ compiler/gnat.vim \ ++ doc/ft_ada.txt \ ++ ftdetect/ada.vim \ ++ ftplugin/ada.vim \ ++ indent/ada.vim \ ++ syntax/ada.vim ; ++ ++" }}}1 ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++" vim: nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++" vim: textwidth=0 foldmethod=marker foldmethod=marker +diff -urN vim71/1/syntax/ada.vim vim71_ada/1/syntax/ada.vim +--- vim71/1/syntax/ada.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/ada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,368 @@ ++"---------------------------------------------------------------------------- ++" Description: Vim Ada syntax file ++" Language: Ada (2005) ++" $Id: ada.vim 793 2007-11-01 18:29:58Z krischik $ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" David A. Wheeler ++" Simon Bradley ++" Contributors: Preben Randhol. ++" $Author: krischik $ ++" $Date: 2007-11-01 19:29:58 +0100 (Do, 01 Nov 2007) $ ++" Version: 4.5 ++" $Revision: 793 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/syntax/ada.vim $ ++" http://www.dwheeler.com/vim ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK ' should not be in iskeyword. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Better folding. ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Spell check for comments and strings only ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: help ft-ada-syntax ++"------------------------------------------------------------------------------ ++" The formal spec of Ada 2005 (ARM) is the "Ada 2005 Reference Manual". ++" For more Ada 2005 info, see http://www.gnuada.org and http://www.adapower.com. ++" ++" This vim syntax file works on vim 7.0 only and makes use of most of Voim 7.0 ++" advanced features. ++"------------------------------------------------------------------------------ ++ ++if exists("b:current_syntax") || version < 700 ++ finish ++endif ++ ++let b:current_syntax = "ada" ++ ++" Section: Ada is entirely case-insensitive. {{{1 ++" ++syntax case ignore ++setlocal nosmartcase ++setlocal ignorecase ++ ++" Section: Highlighting commands {{{1 ++" ++" There are 72 reserved words in total in Ada2005. Some keywords are ++" used in more than one way. For example: ++" 1. "end" is a general keyword, but "end if" ends a Conditional. ++" 2. "then" is a conditional, but "and then" is an operator. ++" ++for b:Item in g:ada#Keywords ++ " Standard Exceptions (including I/O). ++ " We'll highlight the standard exceptions, similar to vim's Python mode. ++ " It's possible to redefine the standard exceptions as something else, ++ " but doing so is very bad practice, so simply highlighting them makes sense. ++ if b:Item['kind'] == "x" ++ execute "syntax keyword adaException " . b:Item['word'] ++ endif ++ if b:Item['kind'] == "a" ++ execute 'syntax match adaAttribute "\V' . b:Item['word'] . '"' ++ endif ++ " We don't normally highlight types in package Standard ++ " (Integer, Character, Float, etc.). I don't think it looks good ++ " with the other type keywords, and many Ada programs define ++ " so many of their own types that it looks inconsistent. ++ " However, if you want this highlighting, turn on "ada_standard_types". ++ " For package Standard's definition, see ARM section A.1. ++ if b:Item['kind'] == "t" && exists ("g:ada_standard_types") ++ execute "syntax keyword adaBuiltinType " . b:Item['word'] ++ endif ++endfor ++ ++" Section: others {{{1 ++" ++syntax keyword adaLabel others ++ ++" Section: Operatoren {{{1 ++" ++syntax keyword adaOperator abs mod not rem xor ++syntax match adaOperator "\" ++syntax match adaOperator "\" ++syntax match adaOperator "\" ++syntax match adaOperator "\" ++syntax match adaOperator "[-+*/<>&]" ++syntax keyword adaOperator ** ++syntax match adaOperator "[/<>]=" ++syntax keyword adaOperator => ++syntax match adaOperator "\.\." ++syntax match adaOperator "=" ++ ++" Section: <> {{{1 ++" ++" Handle the box, <>, specially: ++" ++syntax keyword adaSpecial <> ++ ++" Section: rainbow color {{{1 ++" ++if exists("g:ada_rainbow_color") ++ syntax match adaSpecial "[:;.,]" ++ call rainbow_parenthsis#LoadRound () ++ call rainbow_parenthsis#Activate () ++else ++ syntax match adaSpecial "[:;().,]" ++endif ++ ++" Section: := {{{1 ++" ++" We won't map "adaAssignment" by default, but we need to map ":=" to ++" something or the "=" inside it will be mislabelled as an operator. ++" Note that in Ada, assignment (:=) is not considered an operator. ++" ++syntax match adaAssignment ":=" ++ ++" Section: Numbers, including floating point, exponents, and alternate bases. {{{1 ++" ++syntax match adaNumber "\<\d[0-9_]*\(\.\d[0-9_]*\)\=\([Ee][+-]\=\d[0-9_]*\)\=\>" ++syntax match adaNumber "\<\d\d\=#\x[0-9A-Fa-f_]*\(\.\x[0-9A-Fa-f_]*\)\=#\([Ee][+-]\=\d[0-9_]*\)\=" ++ ++" Section: Identify leading numeric signs {{{1 ++" ++" In "A-5" the "-" is an operator, " but in "A:=-5" the "-" is a sign. This ++" handles "A3+-5" (etc.) correctly. " This assumes that if you put a ++" don't put a space after +/- when it's used " as an operator, you won't ++" put a space before it either -- which is true " in code I've seen. ++" ++syntax match adaSign "[[:space:]<>=(,|:;&*/+-][+-]\d"lc=1,hs=s+1,he=e-1,me=e-1 ++ ++" Section: Labels for the goto statement. {{{1 ++" ++syntax region adaLabel start="<<" end=">>" ++ ++" Section: Boolean Constants {{{1 ++" Boolean Constants. ++syntax keyword adaBoolean true false ++ ++" Section: Warn C/C++ {{{1 ++" ++" Warn people who try to use C/C++ notation erroneously: ++" ++syntax match adaError "//" ++syntax match adaError "/\*" ++syntax match adaError "==" ++ ++ ++" Section: Space Errors {{{1 ++" ++if exists("g:ada_space_errors") ++ if !exists("g:ada_no_trail_space_error") ++ syntax match adaSpaceError excludenl "\s\+$" ++ endif ++ if !exists("g:ada_no_tab_space_error") ++ syntax match adaSpaceError " \+\t"me=e-1 ++ endif ++ if !exists("g:ada_all_tab_usage") ++ syntax match adaSpecial "\t" ++ endif ++endif ++ ++" Section: end {{{1 ++" Unless special ("end loop", "end if", etc.), "end" marks the end of a ++" begin, package, task etc. Assiging it to adaEnd. ++syntax match adaEnd /\/ ++ ++syntax keyword adaPreproc pragma ++ ++syntax keyword adaRepeat exit for loop reverse while ++syntax match adaRepeat "\" ++ ++syntax keyword adaStatement accept delay goto raise requeue return ++syntax keyword adaStatement terminate ++syntax match adaStatement "\" ++ ++" Section: Handle Ada's record keywords. {{{1 ++" ++" 'record' usually starts a structure, but "with null record;" does not, ++" and 'end record;' ends a structure. The ordering here is critical - ++" 'record;' matches a "with null record", so make it a keyword (this can ++" match when the 'with' or 'null' is on a previous line). ++" We see the "end" in "end record" before the word record, so we match that ++" pattern as adaStructure (and it won't match the "record;" pattern). ++" ++syntax match adaStructure "\" contains=adaRecord ++syntax match adaStructure "\" contains=adaRecord ++syntax match adaKeyword "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax keyword adaConditional if case select ++syntax keyword adaConditional elsif when ++ ++" Section: other keywords {{{1 ++syntax match adaKeyword "\" contains=adaRecord ++syntax keyword adaKeyword all do exception in new null out ++syntax keyword adaKeyword separate until overriding ++ ++" Section: begin keywords {{{1 ++" ++" These keywords begin various constructs, and you _might_ want to ++" highlight them differently. ++" ++syntax keyword adaBegin begin body declare entry generic ++syntax keyword adaBegin protected renames task ++ ++syntax match adaBegin "\" contains=adaFunction ++syntax match adaBegin "\" contains=adaProcedure ++syntax match adaBegin "\" contains=adaPackage ++ ++if exists("ada_with_gnat_project_files") ++ syntax keyword adaBegin project ++endif ++ ++" Section: with, use {{{1 ++" ++if exists("ada_withuse_ordinary") ++ " Don't be fancy. Display "with" and "use" as ordinary keywords in all cases. ++ syntax keyword adaKeyword with use ++else ++ " Highlight "with" and "use" clauses like C's "#include" when they're used ++ " to reference other compilation units; otherwise they're ordinary keywords. ++ " If we have vim 6.0 or later, we'll use its advanced pattern-matching ++ " capabilities so that we won't match leading spaces. ++ syntax match adaKeyword "\" ++ syntax match adaKeyword "\" ++ syntax match adaBeginWith "^\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syntax match adaSemiWith ";\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syntax match adaInc "\" contained contains=NONE ++ syntax match adaInc "\" contained contains=NONE ++ syntax match adaInc "\" contained contains=NONE ++ " Recognize "with null record" as a keyword (even the "record"). ++ syntax match adaKeyword "\" ++ " Consider generic formal parameters of subprograms and packages as keywords. ++ syntax match adaKeyword ";\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ syntax match adaKeyword "^\s*\zswith\s\+\(function\|procedure\|package\)\>" ++endif ++ ++" Section: String and character constants. {{{1 ++" ++syntax region adaString contains=@Spell start=+"+ skip=+""+ end=+"+ ++syntax match adaCharacter "'.'" ++ ++" Section: Todo (only highlighted in comments) {{{1 ++" ++syntax keyword adaTodo contained TODO FIXME XXX NOTE ++ ++" Section: Comments. {{{1 ++" ++syntax region adaComment ++ \ oneline ++ \ contains=adaTodo,adaLineError,@Spell ++ \ start="--" ++ \ end="$" ++ ++" Section: line errors {{{1 ++" ++" Note: Line errors have become quite slow with Vim 7.0 ++" ++if exists("g:ada_line_errors") ++ syntax match adaLineError "\(^.\{79}\)\@<=." contains=ALL containedin=ALL ++endif ++ ++" Section: syntax folding {{{1 ++" ++" Syntax folding is very tricky - for now I still suggest to use ++" indent folding ++" ++if exists("g:ada_folding") && g:ada_folding[0] == 's' ++ if stridx (g:ada_folding, 'p') >= 0 ++ syntax region adaPackage ++ \ start="\(\\|\\)\s*\z(\k*\)" ++ \ end="end\s\+\z1\s*;" ++ \ keepend extend transparent fold contains=ALL ++ endif ++ if stridx (g:ada_folding, 'f') >= 0 ++ syntax region adaProcedure ++ \ start="\\s*\z(\k*\)" ++ \ end="\\s\+\z1\s*;" ++ \ keepend extend transparent fold contains=ALL ++ syntax region adaFunction ++ \ start="\\s*\z(\k*\)" ++ \ end="end\s\+\z1\s*;" ++ \ keepend extend transparent fold contains=ALL ++ endif ++ if stridx (g:ada_folding, 'f') >= 0 ++ syntax region adaRecord ++ \ start="\" ++ \ end="\" ++ \ keepend extend transparent fold contains=ALL ++ endif ++endif ++ ++" Section: The default methods for highlighting. Can be overridden later. {{{1 ++" ++highlight def link adaCharacter Character ++highlight def link adaComment Comment ++highlight def link adaConditional Conditional ++highlight def link adaKeyword Keyword ++highlight def link adaLabel Label ++highlight def link adaNumber Number ++highlight def link adaSign Number ++highlight def link adaOperator Operator ++highlight def link adaPreproc PreProc ++highlight def link adaRepeat Repeat ++highlight def link adaSpecial Special ++highlight def link adaStatement Statement ++highlight def link adaString String ++highlight def link adaStructure Structure ++highlight def link adaTodo Todo ++highlight def link adaType Type ++highlight def link adaTypedef Typedef ++highlight def link adaStorageClass StorageClass ++highlight def link adaBoolean Boolean ++highlight def link adaException Exception ++highlight def link adaAttribute Tag ++highlight def link adaInc Include ++highlight def link adaError Error ++highlight def link adaSpaceError Error ++highlight def link adaLineError Error ++highlight def link adaBuiltinType Type ++highlight def link adaAssignment Special ++ ++" Subsection: Begin, End {{{2 ++" ++if exists ("ada_begin_preproc") ++ " This is the old default display: ++ highlight def link adaBegin PreProc ++ highlight def link adaEnd PreProc ++else ++ " This is the new default display: ++ highlight def link adaBegin Keyword ++ highlight def link adaEnd Keyword ++endif ++ ++ ++" Section: formatoptions {{{1 ++" ++setlocal formatoptions+=ron ++ ++" Section: sync {{{1 ++" ++" We don't need to look backwards to highlight correctly; ++" this speeds things up greatly. ++syntax sync minlines=1 maxlines=1 ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++"vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++"vim: foldmethod=marker +diff -urN vim71/1/syntax/bush.vim vim71_ada/1/syntax/bush.vim +--- vim71/1/syntax/bush.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/bush.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,309 @@ ++" Vim syntax file ++" Language: BUSH / AdaScript ++" Maintainer: Ken O. Burtch ++" URL: http://www.pegasoft.ca/bush ++" Last Change: 2004-06-29 ++ ++" Former Maintainer: Simon Bradley ++" (was ) ++" Other contributors: Preben Randhol. ++" The formal spec of Ada95 (ARM) is the "Ada95 Reference Manual". ++" For more Ada95 info, see http://www.gnuada.org and http://www.adapower.com. ++ ++" This vim syntax file works on vim 5.6, 5.7, 5.8 and 6.x. ++" It implements Bram Moolenaar's April 25, 2001 recommendations to make ++" the syntax file maximally portable across different versions of vim. ++" If vim 6.0+ is available, ++" this syntax file takes advantage of the vim 6.0 advanced pattern-matching ++" functions to avoid highlighting uninteresting leading spaces in ++" some expressions containing "with" and "use". ++ ++" For version 5.x: Clear all syntax items ++" For version 6.x: Quit when a syntax file was already loaded ++if version < 600 ++ syntax clear ++elseif exists("b:current_syntax") ++ finish ++endif ++ ++" Ada is entirely case-insensitive. ++syn case ignore ++ ++" We don't need to look backwards to highlight correctly; ++" this speeds things up greatly. ++syn sync minlines=1 maxlines=1 ++ ++" Highlighting commands. There are 69 reserved words in total in Ada95. ++" Some keywords are used in more than one way. For example: ++" 1. "end" is a general keyword, but "end if" ends a Conditional. ++" 2. "then" is a conditional, but "and then" is an operator. ++ ++ ++" Standard Exceptions (including I/O). ++" We'll highlight the standard exceptions, similar to vim's Python mode. ++" It's possible to redefine the standard exceptions as something else, ++" but doing so is very bad practice, so simply highlighting them makes sense. ++syn keyword adaException Constraint_Error Program_Error Storage_Error ++syn keyword adaException Tasking_Error ++syn keyword adaException Status_Error Mode_Error Name_Error Use_Error ++syn keyword adaException Device_Error End_Error Data_Error Layout_Error ++syn keyword adaException Length_Error Pattern_Error Index_Error ++syn keyword adaException Translation_Error ++syn keyword adaException Time_Error Argument_Error ++syn keyword adaException Tag_Error ++syn keyword adaException Picture_Error ++" Interfaces ++syn keyword adaException Terminator_Error Conversion_Error ++syn keyword adaException Pointer_Error Dereference_Error Update_Error ++" This isn't in the Ada spec, but a GNAT extension. ++syn keyword adaException Assert_Failure ++" We don't list ALL exceptions defined in particular compilers (e.g., GNAT), ++" because it's quite reasonable to define those phrases as non-exceptions. ++ ++ ++" We don't normally highlight types in package Standard ++" (Integer, Character, Float, etc.). I don't think it looks good ++" with the other type keywords, and many Ada programs define ++" so many of their own types that it looks inconsistent. ++" However, if you want this highlighting, turn on "ada_standard_types". ++" For package Standard's definition, see ARM section A.1. ++ ++if exists("ada_standard_types") ++ syn keyword adaBuiltinType Boolean Integer Natural Positive Float ++ syn keyword adaBuiltinType Character Wide_Character ++ syn keyword adaBuiltinType String Wide_String ++ syn keyword adaBuiltinType Duration ++ " These aren't listed in ARM section A.1's code, but they're noted as ++ " options in ARM sections 3.5.4 and 3.5.7: ++ syn keyword adaBuiltinType Short_Integer Short_Short_Integer ++ syn keyword adaBuiltinType Long_Integer Long_Long_Integer ++ syn keyword adaBuiltinType Short_Float Short_Short_Float ++ syn keyword adaBuiltinType Long_Float Long_Long_Float ++ " BUSH-specific types ++ syn keyword adaBuiltinType command ++ syn keyword adaBuiltinType socket_type ++ syn keyword adaBuiltinType unbounded_string ++ syn keyword adaBuiltinType universal_typeless ++ syn keyword adaBuiltinType universal_string ++ syn keyword adaBuiltinType universal_numeric ++endif ++ ++" There are MANY other predefined types; they've not been added, because ++" determining when they're a type requires context in general. ++" One potential addition would be Unbounded_String. ++ ++ ++syn keyword adaLabel others ++ ++syn keyword adaOperator abs mod not rem xor ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "[-+*/<>&]" ++syn keyword adaOperator ** ++syn match adaOperator "[/<>]=" ++syn keyword adaOperator => ++syn match adaOperator "\.\." ++syn match adaOperator "=" ++ ++" We won't map "adaAssignment" by default, but we need to map ":=" to ++" something or the "=" inside it will be mislabelled as an operator. ++" Note that in Ada, assignment (:=) is not considered an operator. ++syn match adaAssignment ":=" ++ ++" Handle the box, <>, specially: ++syn keyword adaSpecial <> ++ ++" Numbers, including floating point, exponents, and alternate bases. ++syn match adaNumber "\<\d[0-9_]*\(\.\d[0-9_]*\)\=\([Ee][+-]\=\d[0-9_]*\)\=\>" ++syn match adaNumber "\<\d\d\=#\x[0-9A-Fa-f_]*\(\.\x[0-9A-Fa-f_]*\)\=#\([Ee][+-]\=\d[0-9_]*\)\=" ++ ++" Identify leading numeric signs. In "A-5" the "-" is an operator, ++" but in "A:=-5" the "-" is a sign. This handles "A3+-5" (etc.) correctly. ++" This assumes that if you put a don't put a space after +/- when it's used ++" as an operator, you won't put a space before it either -- which is true ++" in code I've seen. ++syn match adaSign "[[:space:]<>=(,|:;&*/+-][+-]\d"lc=1,hs=s+1,he=e-1,me=e-1 ++ ++" Labels for the goto statement. ++syn region adaLabel start="<<" end=">>" ++ ++" Boolean Constants. ++syn keyword adaBoolean true false ++ ++" Warn people who try to use C/C++ notation erroneously: ++syn match adaError "//" ++syn match adaError "/\*" ++syn match adaError "==" ++ ++ ++if exists("ada_space_errors") ++ if !exists("ada_no_trail_space_error") ++ syn match adaSpaceError excludenl "\s\+$" ++ endif ++ if !exists("ada_no_tab_space_error") ++ syn match adaSpaceError " \+\t"me=e-1 ++ endif ++endif ++ ++" Unless special ("end loop", "end if", etc.), "end" marks the end of a ++" begin, package, task etc. Assiging it to adaEnd. ++syn match adaEnd "\" ++ ++syn keyword adaPreproc pragma ++ ++syn keyword adaRepeat exit for loop reverse while ++syn match adaRepeat "\" ++ ++syn keyword adaStatement accept delay goto raise requeue return ++syn keyword adaStatement terminate ++" BUSH-specific statements ++syn keyword adaStatement cd ++syn keyword adaStatement clear ++syn keyword adaStatement env ++syn keyword adaStatement inkey ++syn keyword adaStatement jobs ++syn keyword adaStatement logout ++syn keyword adaStatement pwd ++syn keyword adaStatement step ++syn keyword adaStatement trace ++syn keyword adaStatement typeset ++syn keyword adaStatement unset ++syn keyword adaStatement wait ++syn keyword adaStatement history ++syn keyword adaStatement "?" ++syn match adaStatement "\" ++ ++" Handle Ada's record keywords. ++" 'record' usually starts a structure, but "with null record;" does not, ++" and 'end record;' ends a structure. The ordering here is critical - ++" 'record;' matches a "with null record", so make it a keyword (this can ++" match when the 'with' or 'null' is on a previous line). ++" We see the "end" in "end record" before the word record, so we match that ++" pattern as adaStructure (and it won't match the "record;" pattern). ++syn match adaStructure "\" ++syn match adaStructure "\" ++syn match adaKeyword "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn keyword adaConditional if case select ++syn keyword adaConditional elsif when ++ ++syn keyword adaKeyword all do exception in is new null out ++syn keyword adaKeyword separate until ++ ++" These keywords begin various constructs, and you _might_ want to ++" highlight them differently. ++syn keyword adaBegin begin body declare entry function generic ++syn keyword adaBegin package procedure protected renames task ++ ++ ++if exists("ada_withuse_ordinary") ++" Don't be fancy. Display "with" and "use" as ordinary keywords in all cases. ++ syn keyword adaKeyword with use ++else ++ " Highlight "with" and "use" clauses like C's "#include" when they're used ++ " to reference other compilation units; otherwise they're ordinary keywords. ++ " If we have vim 6.0 or later, we'll use its advanced pattern-matching ++ " capabilities so that we won't match leading spaces. ++ syn match adaKeyword "\" ++ syn match adaKeyword "\" ++ if version < 600 ++ syn match adaBeginWith "^\s*\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syn match adaSemiWith ";\s*\(\(with\(\s\+type\)\=\)\|\(use\)\)\>"lc=1 contains=adaInc ++ else ++ syn match adaBeginWith "^\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syn match adaSemiWith ";\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ endif ++ syn match adaInc "\" contained contains=NONE ++ syn match adaInc "\" contained contains=NONE ++ syn match adaInc "\" contained contains=NONE ++ " Recognize "with null record" as a keyword (even the "record"). ++ syn match adaKeyword "\" ++ " Consider generic formal parameters of subprograms and packages as keywords. ++ if version < 600 ++ syn match adaKeyword ";\s*with\s\+\(function\|procedure\|package\)\>" ++ syn match adaKeyword "^\s*with\s\+\(function\|procedure\|package\)\>" ++ else ++ syn match adaKeyword ";\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ syn match adaKeyword "^\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ endif ++endif ++ ++ ++" String and character constants. ++syn region adaString start=+"+ skip=+""+ end=+"+ ++syn match adaCharacter "'.'" ++ ++" Todo (only highlighted in comments) ++syn keyword adaTodo contained TODO FIXME XXX ++ ++" Comments. ++syn region adaComment oneline contains=adaTodo start="--" end="$" ++ ++ ++ ++" Define the default highlighting. ++" For version 5.7 and earlier: only when not done already ++" For version 5.8 and later: only when an item doesn't have highlighting yet ++if version >= 508 || !exists("did_ada_syn_inits") ++ if version < 508 ++ let did_ada_syn_inits = 1 ++ command -nargs=+ HiLink hi link ++ else ++ command -nargs=+ HiLink hi def link ++ endif ++ ++ " The default methods for highlighting. Can be overridden later. ++ HiLink adaCharacter Character ++ HiLink adaComment Comment ++ HiLink adaConditional Conditional ++ HiLink adaKeyword Keyword ++ HiLink adaLabel Label ++ HiLink adaNumber Number ++ HiLink adaSign Number ++ HiLink adaOperator Operator ++ HiLink adaPreproc PreProc ++ HiLink adaRepeat Repeat ++ HiLink adaSpecial Special ++ HiLink adaStatement Statement ++ HiLink adaString String ++ HiLink adaStructure Structure ++ HiLink adaTodo Todo ++ HiLink adaType Type ++ HiLink adaTypedef Typedef ++ HiLink adaStorageClass StorageClass ++ HiLink adaBoolean Boolean ++ HiLink adaException Exception ++ HiLink adaInc Include ++ HiLink adaError Error ++ HiLink adaSpaceError Error ++ HiLink adaBuiltinType Type ++ ++ if exists("ada_begin_preproc") ++ " This is the old default display: ++ HiLink adaBegin PreProc ++ HiLink adaEnd PreProc ++ else ++ " This is the new default display: ++ HiLink adaBegin Keyword ++ HiLink adaEnd Keyword ++ endif ++ ++ delcommand HiLink ++endif ++ ++let b:current_syntax = "ada" ++ ++" vim: ts=8 +diff -urN vim71/1/syntax/.svn/all-wcprops vim71_ada/1/syntax/.svn/all-wcprops +--- vim71/1/syntax/.svn/all-wcprops 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/all-wcprops 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,17 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 51 ++/svnroot/gnuada/!svn/ver/793/trunk/tools/vim/syntax ++END ++ada.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 59 ++/svnroot/gnuada/!svn/ver/793/trunk/tools/vim/syntax/ada.vim ++END ++bush.vim ++K 25 ++svn:wc:ra_dav:version-url ++V 60 ++/svnroot/gnuada/!svn/ver/746/trunk/tools/vim/syntax/bush.vim ++END +diff -urN vim71/1/syntax/.svn/dir-prop-base vim71_ada/1/syntax/.svn/dir-prop-base +--- vim71/1/syntax/.svn/dir-prop-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/dir-prop-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,6 @@ ++K 10 ++svn:ignore ++V 9 ++.backups ++ ++END +diff -urN vim71/1/syntax/.svn/entries vim71_ada/1/syntax/.svn/entries +--- vim71/1/syntax/.svn/entries 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/entries 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,54 @@ ++8 ++ ++dir ++841 ++https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/syntax ++https://gnuada.svn.sourceforge.net/svnroot/gnuada ++ ++ ++ ++2007-11-01T18:29:58.081603Z ++793 ++krischik ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9b0cb6ef-3e0e-0410-8360-d61ff0ace097 ++ ++ada.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++1f3e27d039a012d7bc96fd9e2b95ff20 ++2007-11-01T18:29:58.081603Z ++793 ++krischik ++has-props ++ ++bush.vim ++file ++ ++ ++ ++ ++2008-01-16T15:37:03.000000Z ++7b0798091c1dad50554c7905c6803cbe ++2007-07-08T16:24:46.571321Z ++746 ++krischik ++has-props ++ +diff -urN vim71/1/syntax/.svn/format vim71_ada/1/syntax/.svn/format +--- vim71/1/syntax/.svn/format 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/format 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1 @@ ++8 +diff -urN vim71/1/syntax/.svn/prop-base/ada.vim.svn-base vim71_ada/1/syntax/.svn/prop-base/ada.vim.svn-base +--- vim71/1/syntax/.svn/prop-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/prop-base/ada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/syntax/.svn/prop-base/bush.vim.svn-base vim71_ada/1/syntax/.svn/prop-base/bush.vim.svn-base +--- vim71/1/syntax/.svn/prop-base/bush.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/prop-base/bush.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 2 ++LF ++K 12 ++svn:keywords ++V 31 ++Author Date Id Revision HeadURL ++K 13 ++svn:mime-type ++V 10 ++text/x-vim ++END +diff -urN vim71/1/syntax/.svn/text-base/ada.vim.svn-base vim71_ada/1/syntax/.svn/text-base/ada.vim.svn-base +--- vim71/1/syntax/.svn/text-base/ada.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/text-base/ada.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,368 @@ ++"---------------------------------------------------------------------------- ++" Description: Vim Ada syntax file ++" Language: Ada (2005) ++" $Id$ ++" Copyright: Copyright (C) 2006 Martin Krischik ++" Maintainer: Martin Krischik ++" David A. Wheeler ++" Simon Bradley ++" Contributors: Preben Randhol. ++" $Author$ ++" $Date$ ++" Version: 4.5 ++" $Revision$ ++" $HeadURL$ ++" http://www.dwheeler.com/vim ++" History: 24.05.2006 MK Unified Headers ++" 26.05.2006 MK ' should not be in iskeyword. ++" 16.07.2006 MK Ada-Mode as vim-ball ++" 02.10.2006 MK Better folding. ++" 15.10.2006 MK Bram's suggestion for runtime integration ++" 05.11.2006 MK Spell check for comments and strings only ++" 05.11.2006 MK Bram suggested to save on spaces ++" Help Page: help ft-ada-syntax ++"------------------------------------------------------------------------------ ++" The formal spec of Ada 2005 (ARM) is the "Ada 2005 Reference Manual". ++" For more Ada 2005 info, see http://www.gnuada.org and http://www.adapower.com. ++" ++" This vim syntax file works on vim 7.0 only and makes use of most of Voim 7.0 ++" advanced features. ++"------------------------------------------------------------------------------ ++ ++if exists("b:current_syntax") || version < 700 ++ finish ++endif ++ ++let b:current_syntax = "ada" ++ ++" Section: Ada is entirely case-insensitive. {{{1 ++" ++syntax case ignore ++setlocal nosmartcase ++setlocal ignorecase ++ ++" Section: Highlighting commands {{{1 ++" ++" There are 72 reserved words in total in Ada2005. Some keywords are ++" used in more than one way. For example: ++" 1. "end" is a general keyword, but "end if" ends a Conditional. ++" 2. "then" is a conditional, but "and then" is an operator. ++" ++for b:Item in g:ada#Keywords ++ " Standard Exceptions (including I/O). ++ " We'll highlight the standard exceptions, similar to vim's Python mode. ++ " It's possible to redefine the standard exceptions as something else, ++ " but doing so is very bad practice, so simply highlighting them makes sense. ++ if b:Item['kind'] == "x" ++ execute "syntax keyword adaException " . b:Item['word'] ++ endif ++ if b:Item['kind'] == "a" ++ execute 'syntax match adaAttribute "\V' . b:Item['word'] . '"' ++ endif ++ " We don't normally highlight types in package Standard ++ " (Integer, Character, Float, etc.). I don't think it looks good ++ " with the other type keywords, and many Ada programs define ++ " so many of their own types that it looks inconsistent. ++ " However, if you want this highlighting, turn on "ada_standard_types". ++ " For package Standard's definition, see ARM section A.1. ++ if b:Item['kind'] == "t" && exists ("g:ada_standard_types") ++ execute "syntax keyword adaBuiltinType " . b:Item['word'] ++ endif ++endfor ++ ++" Section: others {{{1 ++" ++syntax keyword adaLabel others ++ ++" Section: Operatoren {{{1 ++" ++syntax keyword adaOperator abs mod not rem xor ++syntax match adaOperator "\" ++syntax match adaOperator "\" ++syntax match adaOperator "\" ++syntax match adaOperator "\" ++syntax match adaOperator "[-+*/<>&]" ++syntax keyword adaOperator ** ++syntax match adaOperator "[/<>]=" ++syntax keyword adaOperator => ++syntax match adaOperator "\.\." ++syntax match adaOperator "=" ++ ++" Section: <> {{{1 ++" ++" Handle the box, <>, specially: ++" ++syntax keyword adaSpecial <> ++ ++" Section: rainbow color {{{1 ++" ++if exists("g:ada_rainbow_color") ++ syntax match adaSpecial "[:;.,]" ++ call rainbow_parenthsis#LoadRound () ++ call rainbow_parenthsis#Activate () ++else ++ syntax match adaSpecial "[:;().,]" ++endif ++ ++" Section: := {{{1 ++" ++" We won't map "adaAssignment" by default, but we need to map ":=" to ++" something or the "=" inside it will be mislabelled as an operator. ++" Note that in Ada, assignment (:=) is not considered an operator. ++" ++syntax match adaAssignment ":=" ++ ++" Section: Numbers, including floating point, exponents, and alternate bases. {{{1 ++" ++syntax match adaNumber "\<\d[0-9_]*\(\.\d[0-9_]*\)\=\([Ee][+-]\=\d[0-9_]*\)\=\>" ++syntax match adaNumber "\<\d\d\=#\x[0-9A-Fa-f_]*\(\.\x[0-9A-Fa-f_]*\)\=#\([Ee][+-]\=\d[0-9_]*\)\=" ++ ++" Section: Identify leading numeric signs {{{1 ++" ++" In "A-5" the "-" is an operator, " but in "A:=-5" the "-" is a sign. This ++" handles "A3+-5" (etc.) correctly. " This assumes that if you put a ++" don't put a space after +/- when it's used " as an operator, you won't ++" put a space before it either -- which is true " in code I've seen. ++" ++syntax match adaSign "[[:space:]<>=(,|:;&*/+-][+-]\d"lc=1,hs=s+1,he=e-1,me=e-1 ++ ++" Section: Labels for the goto statement. {{{1 ++" ++syntax region adaLabel start="<<" end=">>" ++ ++" Section: Boolean Constants {{{1 ++" Boolean Constants. ++syntax keyword adaBoolean true false ++ ++" Section: Warn C/C++ {{{1 ++" ++" Warn people who try to use C/C++ notation erroneously: ++" ++syntax match adaError "//" ++syntax match adaError "/\*" ++syntax match adaError "==" ++ ++ ++" Section: Space Errors {{{1 ++" ++if exists("g:ada_space_errors") ++ if !exists("g:ada_no_trail_space_error") ++ syntax match adaSpaceError excludenl "\s\+$" ++ endif ++ if !exists("g:ada_no_tab_space_error") ++ syntax match adaSpaceError " \+\t"me=e-1 ++ endif ++ if !exists("g:ada_all_tab_usage") ++ syntax match adaSpecial "\t" ++ endif ++endif ++ ++" Section: end {{{1 ++" Unless special ("end loop", "end if", etc.), "end" marks the end of a ++" begin, package, task etc. Assiging it to adaEnd. ++syntax match adaEnd /\/ ++ ++syntax keyword adaPreproc pragma ++ ++syntax keyword adaRepeat exit for loop reverse while ++syntax match adaRepeat "\" ++ ++syntax keyword adaStatement accept delay goto raise requeue return ++syntax keyword adaStatement terminate ++syntax match adaStatement "\" ++ ++" Section: Handle Ada's record keywords. {{{1 ++" ++" 'record' usually starts a structure, but "with null record;" does not, ++" and 'end record;' ends a structure. The ordering here is critical - ++" 'record;' matches a "with null record", so make it a keyword (this can ++" match when the 'with' or 'null' is on a previous line). ++" We see the "end" in "end record" before the word record, so we match that ++" pattern as adaStructure (and it won't match the "record;" pattern). ++" ++syntax match adaStructure "\" contains=adaRecord ++syntax match adaStructure "\" contains=adaRecord ++syntax match adaKeyword "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax match adaConditional "\" ++syntax keyword adaConditional if case select ++syntax keyword adaConditional elsif when ++ ++" Section: other keywords {{{1 ++syntax match adaKeyword "\" contains=adaRecord ++syntax keyword adaKeyword all do exception in new null out ++syntax keyword adaKeyword separate until overriding ++ ++" Section: begin keywords {{{1 ++" ++" These keywords begin various constructs, and you _might_ want to ++" highlight them differently. ++" ++syntax keyword adaBegin begin body declare entry generic ++syntax keyword adaBegin protected renames task ++ ++syntax match adaBegin "\" contains=adaFunction ++syntax match adaBegin "\" contains=adaProcedure ++syntax match adaBegin "\" contains=adaPackage ++ ++if exists("ada_with_gnat_project_files") ++ syntax keyword adaBegin project ++endif ++ ++" Section: with, use {{{1 ++" ++if exists("ada_withuse_ordinary") ++ " Don't be fancy. Display "with" and "use" as ordinary keywords in all cases. ++ syntax keyword adaKeyword with use ++else ++ " Highlight "with" and "use" clauses like C's "#include" when they're used ++ " to reference other compilation units; otherwise they're ordinary keywords. ++ " If we have vim 6.0 or later, we'll use its advanced pattern-matching ++ " capabilities so that we won't match leading spaces. ++ syntax match adaKeyword "\" ++ syntax match adaKeyword "\" ++ syntax match adaBeginWith "^\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syntax match adaSemiWith ";\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syntax match adaInc "\" contained contains=NONE ++ syntax match adaInc "\" contained contains=NONE ++ syntax match adaInc "\" contained contains=NONE ++ " Recognize "with null record" as a keyword (even the "record"). ++ syntax match adaKeyword "\" ++ " Consider generic formal parameters of subprograms and packages as keywords. ++ syntax match adaKeyword ";\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ syntax match adaKeyword "^\s*\zswith\s\+\(function\|procedure\|package\)\>" ++endif ++ ++" Section: String and character constants. {{{1 ++" ++syntax region adaString contains=@Spell start=+"+ skip=+""+ end=+"+ ++syntax match adaCharacter "'.'" ++ ++" Section: Todo (only highlighted in comments) {{{1 ++" ++syntax keyword adaTodo contained TODO FIXME XXX NOTE ++ ++" Section: Comments. {{{1 ++" ++syntax region adaComment ++ \ oneline ++ \ contains=adaTodo,adaLineError,@Spell ++ \ start="--" ++ \ end="$" ++ ++" Section: line errors {{{1 ++" ++" Note: Line errors have become quite slow with Vim 7.0 ++" ++if exists("g:ada_line_errors") ++ syntax match adaLineError "\(^.\{79}\)\@<=." contains=ALL containedin=ALL ++endif ++ ++" Section: syntax folding {{{1 ++" ++" Syntax folding is very tricky - for now I still suggest to use ++" indent folding ++" ++if exists("g:ada_folding") && g:ada_folding[0] == 's' ++ if stridx (g:ada_folding, 'p') >= 0 ++ syntax region adaPackage ++ \ start="\(\\|\\)\s*\z(\k*\)" ++ \ end="end\s\+\z1\s*;" ++ \ keepend extend transparent fold contains=ALL ++ endif ++ if stridx (g:ada_folding, 'f') >= 0 ++ syntax region adaProcedure ++ \ start="\\s*\z(\k*\)" ++ \ end="\\s\+\z1\s*;" ++ \ keepend extend transparent fold contains=ALL ++ syntax region adaFunction ++ \ start="\\s*\z(\k*\)" ++ \ end="end\s\+\z1\s*;" ++ \ keepend extend transparent fold contains=ALL ++ endif ++ if stridx (g:ada_folding, 'f') >= 0 ++ syntax region adaRecord ++ \ start="\" ++ \ end="\" ++ \ keepend extend transparent fold contains=ALL ++ endif ++endif ++ ++" Section: The default methods for highlighting. Can be overridden later. {{{1 ++" ++highlight def link adaCharacter Character ++highlight def link adaComment Comment ++highlight def link adaConditional Conditional ++highlight def link adaKeyword Keyword ++highlight def link adaLabel Label ++highlight def link adaNumber Number ++highlight def link adaSign Number ++highlight def link adaOperator Operator ++highlight def link adaPreproc PreProc ++highlight def link adaRepeat Repeat ++highlight def link adaSpecial Special ++highlight def link adaStatement Statement ++highlight def link adaString String ++highlight def link adaStructure Structure ++highlight def link adaTodo Todo ++highlight def link adaType Type ++highlight def link adaTypedef Typedef ++highlight def link adaStorageClass StorageClass ++highlight def link adaBoolean Boolean ++highlight def link adaException Exception ++highlight def link adaAttribute Tag ++highlight def link adaInc Include ++highlight def link adaError Error ++highlight def link adaSpaceError Error ++highlight def link adaLineError Error ++highlight def link adaBuiltinType Type ++highlight def link adaAssignment Special ++ ++" Subsection: Begin, End {{{2 ++" ++if exists ("ada_begin_preproc") ++ " This is the old default display: ++ highlight def link adaBegin PreProc ++ highlight def link adaEnd PreProc ++else ++ " This is the new default display: ++ highlight def link adaBegin Keyword ++ highlight def link adaEnd Keyword ++endif ++ ++ ++" Section: formatoptions {{{1 ++" ++setlocal formatoptions+=ron ++ ++" Section: sync {{{1 ++" ++" We don't need to look backwards to highlight correctly; ++" this speeds things up greatly. ++syntax sync minlines=1 maxlines=1 ++ ++finish " 1}}} ++ ++"------------------------------------------------------------------------------ ++" Copyright (C) 2006 Martin Krischik ++" ++" Vim is Charityware - see ":help license" or uganda.txt for licence details. ++"------------------------------------------------------------------------------ ++"vim: textwidth=78 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab ++"vim: foldmethod=marker +diff -urN vim71/1/syntax/.svn/text-base/bush.vim.svn-base vim71_ada/1/syntax/.svn/text-base/bush.vim.svn-base +--- vim71/1/syntax/.svn/text-base/bush.vim.svn-base 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/1/syntax/.svn/text-base/bush.vim.svn-base 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,309 @@ ++" Vim syntax file ++" Language: BUSH / AdaScript ++" Maintainer: Ken O. Burtch ++" URL: http://www.pegasoft.ca/bush ++" Last Change: 2004-06-29 ++ ++" Former Maintainer: Simon Bradley ++" (was ) ++" Other contributors: Preben Randhol. ++" The formal spec of Ada95 (ARM) is the "Ada95 Reference Manual". ++" For more Ada95 info, see http://www.gnuada.org and http://www.adapower.com. ++ ++" This vim syntax file works on vim 5.6, 5.7, 5.8 and 6.x. ++" It implements Bram Moolenaar's April 25, 2001 recommendations to make ++" the syntax file maximally portable across different versions of vim. ++" If vim 6.0+ is available, ++" this syntax file takes advantage of the vim 6.0 advanced pattern-matching ++" functions to avoid highlighting uninteresting leading spaces in ++" some expressions containing "with" and "use". ++ ++" For version 5.x: Clear all syntax items ++" For version 6.x: Quit when a syntax file was already loaded ++if version < 600 ++ syntax clear ++elseif exists("b:current_syntax") ++ finish ++endif ++ ++" Ada is entirely case-insensitive. ++syn case ignore ++ ++" We don't need to look backwards to highlight correctly; ++" this speeds things up greatly. ++syn sync minlines=1 maxlines=1 ++ ++" Highlighting commands. There are 69 reserved words in total in Ada95. ++" Some keywords are used in more than one way. For example: ++" 1. "end" is a general keyword, but "end if" ends a Conditional. ++" 2. "then" is a conditional, but "and then" is an operator. ++ ++ ++" Standard Exceptions (including I/O). ++" We'll highlight the standard exceptions, similar to vim's Python mode. ++" It's possible to redefine the standard exceptions as something else, ++" but doing so is very bad practice, so simply highlighting them makes sense. ++syn keyword adaException Constraint_Error Program_Error Storage_Error ++syn keyword adaException Tasking_Error ++syn keyword adaException Status_Error Mode_Error Name_Error Use_Error ++syn keyword adaException Device_Error End_Error Data_Error Layout_Error ++syn keyword adaException Length_Error Pattern_Error Index_Error ++syn keyword adaException Translation_Error ++syn keyword adaException Time_Error Argument_Error ++syn keyword adaException Tag_Error ++syn keyword adaException Picture_Error ++" Interfaces ++syn keyword adaException Terminator_Error Conversion_Error ++syn keyword adaException Pointer_Error Dereference_Error Update_Error ++" This isn't in the Ada spec, but a GNAT extension. ++syn keyword adaException Assert_Failure ++" We don't list ALL exceptions defined in particular compilers (e.g., GNAT), ++" because it's quite reasonable to define those phrases as non-exceptions. ++ ++ ++" We don't normally highlight types in package Standard ++" (Integer, Character, Float, etc.). I don't think it looks good ++" with the other type keywords, and many Ada programs define ++" so many of their own types that it looks inconsistent. ++" However, if you want this highlighting, turn on "ada_standard_types". ++" For package Standard's definition, see ARM section A.1. ++ ++if exists("ada_standard_types") ++ syn keyword adaBuiltinType Boolean Integer Natural Positive Float ++ syn keyword adaBuiltinType Character Wide_Character ++ syn keyword adaBuiltinType String Wide_String ++ syn keyword adaBuiltinType Duration ++ " These aren't listed in ARM section A.1's code, but they're noted as ++ " options in ARM sections 3.5.4 and 3.5.7: ++ syn keyword adaBuiltinType Short_Integer Short_Short_Integer ++ syn keyword adaBuiltinType Long_Integer Long_Long_Integer ++ syn keyword adaBuiltinType Short_Float Short_Short_Float ++ syn keyword adaBuiltinType Long_Float Long_Long_Float ++ " BUSH-specific types ++ syn keyword adaBuiltinType command ++ syn keyword adaBuiltinType socket_type ++ syn keyword adaBuiltinType unbounded_string ++ syn keyword adaBuiltinType universal_typeless ++ syn keyword adaBuiltinType universal_string ++ syn keyword adaBuiltinType universal_numeric ++endif ++ ++" There are MANY other predefined types; they've not been added, because ++" determining when they're a type requires context in general. ++" One potential addition would be Unbounded_String. ++ ++ ++syn keyword adaLabel others ++ ++syn keyword adaOperator abs mod not rem xor ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "[-+*/<>&]" ++syn keyword adaOperator ** ++syn match adaOperator "[/<>]=" ++syn keyword adaOperator => ++syn match adaOperator "\.\." ++syn match adaOperator "=" ++ ++" We won't map "adaAssignment" by default, but we need to map ":=" to ++" something or the "=" inside it will be mislabelled as an operator. ++" Note that in Ada, assignment (:=) is not considered an operator. ++syn match adaAssignment ":=" ++ ++" Handle the box, <>, specially: ++syn keyword adaSpecial <> ++ ++" Numbers, including floating point, exponents, and alternate bases. ++syn match adaNumber "\<\d[0-9_]*\(\.\d[0-9_]*\)\=\([Ee][+-]\=\d[0-9_]*\)\=\>" ++syn match adaNumber "\<\d\d\=#\x[0-9A-Fa-f_]*\(\.\x[0-9A-Fa-f_]*\)\=#\([Ee][+-]\=\d[0-9_]*\)\=" ++ ++" Identify leading numeric signs. In "A-5" the "-" is an operator, ++" but in "A:=-5" the "-" is a sign. This handles "A3+-5" (etc.) correctly. ++" This assumes that if you put a don't put a space after +/- when it's used ++" as an operator, you won't put a space before it either -- which is true ++" in code I've seen. ++syn match adaSign "[[:space:]<>=(,|:;&*/+-][+-]\d"lc=1,hs=s+1,he=e-1,me=e-1 ++ ++" Labels for the goto statement. ++syn region adaLabel start="<<" end=">>" ++ ++" Boolean Constants. ++syn keyword adaBoolean true false ++ ++" Warn people who try to use C/C++ notation erroneously: ++syn match adaError "//" ++syn match adaError "/\*" ++syn match adaError "==" ++ ++ ++if exists("ada_space_errors") ++ if !exists("ada_no_trail_space_error") ++ syn match adaSpaceError excludenl "\s\+$" ++ endif ++ if !exists("ada_no_tab_space_error") ++ syn match adaSpaceError " \+\t"me=e-1 ++ endif ++endif ++ ++" Unless special ("end loop", "end if", etc.), "end" marks the end of a ++" begin, package, task etc. Assiging it to adaEnd. ++syn match adaEnd "\" ++ ++syn keyword adaPreproc pragma ++ ++syn keyword adaRepeat exit for loop reverse while ++syn match adaRepeat "\" ++ ++syn keyword adaStatement accept delay goto raise requeue return ++syn keyword adaStatement terminate ++" BUSH-specific statements ++syn keyword adaStatement cd ++syn keyword adaStatement clear ++syn keyword adaStatement env ++syn keyword adaStatement inkey ++syn keyword adaStatement jobs ++syn keyword adaStatement logout ++syn keyword adaStatement pwd ++syn keyword adaStatement step ++syn keyword adaStatement trace ++syn keyword adaStatement typeset ++syn keyword adaStatement unset ++syn keyword adaStatement wait ++syn keyword adaStatement history ++syn keyword adaStatement "?" ++syn match adaStatement "\" ++ ++" Handle Ada's record keywords. ++" 'record' usually starts a structure, but "with null record;" does not, ++" and 'end record;' ends a structure. The ordering here is critical - ++" 'record;' matches a "with null record", so make it a keyword (this can ++" match when the 'with' or 'null' is on a previous line). ++" We see the "end" in "end record" before the word record, so we match that ++" pattern as adaStructure (and it won't match the "record;" pattern). ++syn match adaStructure "\" ++syn match adaStructure "\" ++syn match adaKeyword "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn keyword adaConditional if case select ++syn keyword adaConditional elsif when ++ ++syn keyword adaKeyword all do exception in is new null out ++syn keyword adaKeyword separate until ++ ++" These keywords begin various constructs, and you _might_ want to ++" highlight them differently. ++syn keyword adaBegin begin body declare entry function generic ++syn keyword adaBegin package procedure protected renames task ++ ++ ++if exists("ada_withuse_ordinary") ++" Don't be fancy. Display "with" and "use" as ordinary keywords in all cases. ++ syn keyword adaKeyword with use ++else ++ " Highlight "with" and "use" clauses like C's "#include" when they're used ++ " to reference other compilation units; otherwise they're ordinary keywords. ++ " If we have vim 6.0 or later, we'll use its advanced pattern-matching ++ " capabilities so that we won't match leading spaces. ++ syn match adaKeyword "\" ++ syn match adaKeyword "\" ++ if version < 600 ++ syn match adaBeginWith "^\s*\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syn match adaSemiWith ";\s*\(\(with\(\s\+type\)\=\)\|\(use\)\)\>"lc=1 contains=adaInc ++ else ++ syn match adaBeginWith "^\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syn match adaSemiWith ";\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ endif ++ syn match adaInc "\" contained contains=NONE ++ syn match adaInc "\" contained contains=NONE ++ syn match adaInc "\" contained contains=NONE ++ " Recognize "with null record" as a keyword (even the "record"). ++ syn match adaKeyword "\" ++ " Consider generic formal parameters of subprograms and packages as keywords. ++ if version < 600 ++ syn match adaKeyword ";\s*with\s\+\(function\|procedure\|package\)\>" ++ syn match adaKeyword "^\s*with\s\+\(function\|procedure\|package\)\>" ++ else ++ syn match adaKeyword ";\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ syn match adaKeyword "^\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ endif ++endif ++ ++ ++" String and character constants. ++syn region adaString start=+"+ skip=+""+ end=+"+ ++syn match adaCharacter "'.'" ++ ++" Todo (only highlighted in comments) ++syn keyword adaTodo contained TODO FIXME XXX ++ ++" Comments. ++syn region adaComment oneline contains=adaTodo start="--" end="$" ++ ++ ++ ++" Define the default highlighting. ++" For version 5.7 and earlier: only when not done already ++" For version 5.8 and later: only when an item doesn't have highlighting yet ++if version >= 508 || !exists("did_ada_syn_inits") ++ if version < 508 ++ let did_ada_syn_inits = 1 ++ command -nargs=+ HiLink hi link ++ else ++ command -nargs=+ HiLink hi def link ++ endif ++ ++ " The default methods for highlighting. Can be overridden later. ++ HiLink adaCharacter Character ++ HiLink adaComment Comment ++ HiLink adaConditional Conditional ++ HiLink adaKeyword Keyword ++ HiLink adaLabel Label ++ HiLink adaNumber Number ++ HiLink adaSign Number ++ HiLink adaOperator Operator ++ HiLink adaPreproc PreProc ++ HiLink adaRepeat Repeat ++ HiLink adaSpecial Special ++ HiLink adaStatement Statement ++ HiLink adaString String ++ HiLink adaStructure Structure ++ HiLink adaTodo Todo ++ HiLink adaType Type ++ HiLink adaTypedef Typedef ++ HiLink adaStorageClass StorageClass ++ HiLink adaBoolean Boolean ++ HiLink adaException Exception ++ HiLink adaInc Include ++ HiLink adaError Error ++ HiLink adaSpaceError Error ++ HiLink adaBuiltinType Type ++ ++ if exists("ada_begin_preproc") ++ " This is the old default display: ++ HiLink adaBegin PreProc ++ HiLink adaEnd PreProc ++ else ++ " This is the new default display: ++ HiLink adaBegin Keyword ++ HiLink adaEnd Keyword ++ endif ++ ++ delcommand HiLink ++endif ++ ++let b:current_syntax = "ada" ++ ++" vim: ts=8 +diff -urN vim71/runtime/autoload/adacomplete.vim vim71_ada/runtime/autoload/adacomplete.vim +--- vim71/runtime/autoload/adacomplete.vim 2007-05-05 19:34:16.000000000 +0200 ++++ vim71_ada/runtime/autoload/adacomplete.vim 2008-01-16 16:46:40.000000000 +0100 +@@ -1,13 +1,13 @@ + "------------------------------------------------------------------------------ + " Description: Vim Ada omnicompletion file + " Language: Ada (2005) +-" $Id: adacomplete.vim,v 1.1 2007/05/05 17:34:16 vimboss Exp $ ++" $Id: adacomplete.vim 825 2007-12-09 13:34:03Z krischik $ + " Maintainer: Martin Krischik +-" $Author: vimboss $ +-" $Date: 2007/05/05 17:34:16 $ +-" Version: 4.2 +-" $Revision: 1.1 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/adacomplete.vim $ ++" $Author: krischik $ ++" $Date: 2007-12-09 14:34:03 +0100 (So, 09 Dez 2007) $ ++" Version: 4.5 ++" $Revision: 825 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/adacomplete.vim $ + " History: 24.05.2006 MK Unified Headers + " 26.05.2006 MK improved search for begin of word. + " 16.07.2006 MK Ada-Mode as vim-ball +diff -urN vim71/runtime/autoload/ada.vim vim71_ada/runtime/autoload/ada.vim +--- vim71/runtime/autoload/ada.vim 2007-05-05 20:02:22.000000000 +0200 ++++ vim71_ada/runtime/autoload/ada.vim 2008-01-16 16:46:40.000000000 +0100 +@@ -1,14 +1,16 @@ + "------------------------------------------------------------------------------ + " Description: Perform Ada specific completion & tagging. + " Language: Ada (2005) +-" $Id: ada.vim,v 1.1 2007/05/05 18:02:22 vimboss Exp $ +-" Maintainer: Martin Krischik ++" $Id: ada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Maintainer: Martin Krischik ++" Taylor Venable + " Neil Bird +-" $Author: vimboss $ +-" $Date: 2007/05/05 18:02:22 $ +-" Version: 4.2 +-" $Revision: 1.1 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $ ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/ada.vim $ + " History: 24.05.2006 MK Unified Headers + " 26.05.2006 MK ' should not be in iskeyword. + " 16.07.2006 MK Ada-Mode as vim-ball +@@ -17,6 +19,10 @@ + " 05.11.2006 MK Bram suggested not to use include protection for + " autoload + " 05.11.2006 MK Bram suggested to save on spaces ++" 08.07.2007 TV fix mapleader problems. ++" 09.05.2007 MK Session just won't work no matter how much ++" tweaking is done ++" 19.09.2007 NO still some mapleader problems + " Help Page: ft-ada-functions + "------------------------------------------------------------------------------ + +@@ -425,7 +431,15 @@ + execute '!ctags --excmd=number ' . l:Filename + endfunction ada#Create_Tags + +-function ada#Switch_Session (New_Session) "{{{1 ++" Section: ada#Switch_Session {{{1 ++" ++function ada#Switch_Session (New_Session) ++ " ++ " you should not save to much date into the seession since they will ++ " be sourced ++ " ++ set sessionoptions=buffers,curdir,folds,globals,resize,slash,tabpages,tabpages,unix,winpos,winsize ++ + if a:New_Session != v:this_session + " + " We actualy got a new session - otherwise there +@@ -437,18 +451,23 @@ + + let v:this_session = a:New_Session + +- if filereadable (v:this_session) +- execute 'source ' . v:this_session +- endif ++ "if filereadable (v:this_session) ++ "execute 'source ' . v:this_session ++ "endif + + augroup ada_session + autocmd! + autocmd VimLeavePre * execute 'mksession! ' . v:this_session + augroup END ++ " ++ "if exists ("g:Tlist_Auto_Open") && g:Tlist_Auto_Open ++ "TlistOpen ++ "endif ++ + endif + + return +-endfunction ada#Switch_Session "}}}1 ++endfunction ada#Switch_Session + + " Section: GNAT Pretty Printer folding {{{1 + " +@@ -546,18 +565,23 @@ + \ a:Keys . + \" :" . a:Command . "" + else ++ if exists("g:mapleader") ++ let l:leader = g:mapleader ++ else ++ let l:leader = '\' ++ endif + execute + \ "50amenu " . + \ "Ada." . escape(a:Text, ' ') . +- \ "" . escape(g:mapleader . "a" . a:Keys , '\') . ++ \ "" . escape(l:leader . "a" . a:Keys , '\') . + \ " :" . a:Command . "" + execute + \ "nnoremap " . +- \ escape(g:mapleader . "a" . a:Keys , '\') . ++ \ escape(l:leader . "a" . a:Keys , '\') . + \" :" . a:Command + execute + \ "inoremap " . +- \ escape(g:mapleader . "a" . a:Keys , '\') . ++ \ escape(l:leader . "a" . a:Keys , '\') . + \" :" . a:Command + endif + return +@@ -566,10 +590,15 @@ + " Section: ada#Map_Popup {{{2 + " + function ada#Map_Popup (Text, Keys, Command) ++ if exists("g:mapleader") ++ let l:leader = g:mapleader ++ else ++ let l:leader = '\' ++ endif + execute + \ "50amenu " . + \ "PopUp." . escape(a:Text, ' ') . +- \ "" . escape(g:mapleader . "a" . a:Keys , '\') . ++ \ "" . escape(l:leader . "a" . a:Keys , '\') . + \ " :" . a:Command . "" + + call ada#Map_Menu (a:Text, a:Keys, a:Command) +diff -urN vim71/runtime/autoload/decada.vim vim71_ada/runtime/autoload/decada.vim +--- vim71/runtime/autoload/decada.vim 2007-05-05 19:25:32.000000000 +0200 ++++ vim71_ada/runtime/autoload/decada.vim 2008-01-16 16:46:41.000000000 +0100 +@@ -1,14 +1,14 @@ + "------------------------------------------------------------------------------ + " Description: Vim Ada/Dec Ada compiler file + " Language: Ada (Dec Ada) +-" $Id: decada.vim,v 1.1 2007/05/05 17:25:32 vimboss Exp $ ++" $Id: decada.vim 774 2007-09-17 09:11:59Z krischik $ + " Copyright: Copyright (C) 2006 Martin Krischik +-" Maintainer: Martin Krischik +-" $Author: vimboss $ +-" $Date: 2007/05/05 17:25:32 $ +-" Version: 4.2 +-" $Revision: 1.1 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/decada.vim $ ++" Maintainer: Martin Krischik ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/decada.vim $ + " History: 21.07.2006 MK New Dec Ada + " 15.10.2006 MK Bram's suggestion for runtime integration + " 05.11.2006 MK Bram suggested not to use include protection for +@@ -45,7 +45,7 @@ + call ada#Switch_Session (a:1) + elseif argc() == 0 && strlen (v:servername) > 0 + call ada#Switch_Session ( +- \ expand('~')[0:-2] . ".vimfiles.session]" . ++ \ expand('~')[0:-2] . ".vimfiles.session]decada_" . + \ v:servername . ".vim") + endif + return +diff -urN vim71/runtime/autoload/gnat.vim vim71_ada/runtime/autoload/gnat.vim +--- vim71/runtime/autoload/gnat.vim 2007-05-05 20:18:20.000000000 +0200 ++++ vim71_ada/runtime/autoload/gnat.vim 2008-01-16 16:46:46.000000000 +0100 +@@ -1,14 +1,15 @@ + "------------------------------------------------------------------------------ + " Description: Vim Ada/GNAT compiler file + " Language: Ada (GNAT) +-" $Id: gnat.vim,v 1.1 2007/05/05 18:18:20 vimboss Exp $ ++" $Id: gnat.vim 774 2007-09-17 09:11:59Z krischik $ + " Copyright: Copyright (C) 2006 Martin Krischik +-" Maintainer: Martin Krischik +-" $Author: vimboss $ +-" $Date: 2007/05/05 18:18:20 $ +-" Version: 4.2 +-" $Revision: 1.1 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/gnat.vim $ ++" Maintainer: Martin Krischi k ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/gnat.vim $ + " History: 24.05.2006 MK Unified Headers + " 16.07.2006 MK Ada-Mode as vim-ball + " 05.08.2006 MK Add session support +@@ -16,6 +17,7 @@ + " 05.11.2006 MK Bram suggested not to use include protection for + " autoload + " 05.11.2006 MK Bram suggested to save on spaces ++" 19.09.2007 NO use project file only when there is a project + " Help Page: compiler-gnat + "------------------------------------------------------------------------------ + +@@ -71,13 +73,19 @@ + execute 'mksession! ' . v:this_session + endif + +- if strlen (self.Project_File) > 0 +- call ada#Switch_Session ( +- \ expand('~') . "/vimfiles/session/" . +- \ fnamemodify (self.Project_File, ":t:r") . ".vim") +- else +- call ada#Switch_Session ('') +- endif ++ "if strlen (self.Project_File) > 0 ++ "if has("vms") ++ "call ada#Switch_Session ( ++ "\ expand('~')[0:-2] . ".vimfiles.session]gnat_" . ++ "\ fnamemodify (self.Project_File, ":t:r") . ".vim") ++ "else ++ "call ada#Switch_Session ( ++ "\ expand('~') . "/vimfiles/session/gnat_" . ++ "\ fnamemodify (self.Project_File, ":t:r") . ".vim") ++ "endif ++ "else ++ "call ada#Switch_Session ('') ++ "endif + + return + endfunction gnat#Set_Project_File " }}}1 +diff -urN vim71/runtime/compiler/decada.vim vim71_ada/runtime/compiler/decada.vim +--- vim71/runtime/compiler/decada.vim 2007-05-05 20:09:54.000000000 +0200 ++++ vim71_ada/runtime/compiler/decada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -1,16 +1,17 @@ + "------------------------------------------------------------------------------ + " Description: Vim Ada/Dec Ada compiler file + " Language: Ada (Dec Ada) +-" $Id: decada.vim,v 1.1 2007/05/05 18:09:54 vimboss Exp $ ++" $Id: decada.vim 774 2007-09-17 09:11:59Z krischik $ + " Copyright: Copyright (C) 2006 Martin Krischik +-" Maintainer: Martin Krischik +-" $Author: vimboss $ +-" $Date: 2007/05/05 18:09:54 $ +-" Version: 4.2 +-" $Revision: 1.1 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/decada.vim $ ++" Maintainer: Martin Krischik ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/decada.vim $ + " History: 21.07.2006 MK New Dec Ada + " 15.10.2006 MK Bram's suggestion for runtime integration ++" 08.09.2006 MK Correct double load protection. + " Help Page: compiler-decada + "------------------------------------------------------------------------------ + +@@ -24,6 +25,13 @@ + + if !exists("g:decada") + let g:decada = decada#New () ++ ++ call ada#Map_Menu ( ++ \'Dec Ada.Build', ++ \'', ++ \'call decada.Make ()') ++ ++ call g:decada.Set_Session () + endif + + if exists(":CompilerSet") != 2 +@@ -33,16 +41,9 @@ + command -nargs=* CompilerSet setlocal + endif + +-call g:decada.Set_Session () +- + execute "CompilerSet makeprg=" . escape (g:decada.Make_Command, ' ') + execute "CompilerSet errorformat=" . escape (g:decada.Error_Format, ' ') + +-call ada#Map_Menu ( +- \'Dec Ada.Build', +- \'', +- \'call decada.Make ()') +- + finish " 1}}} + + "------------------------------------------------------------------------------ +diff -urN vim71/runtime/compiler/gnat.vim vim71_ada/runtime/compiler/gnat.vim +--- vim71/runtime/compiler/gnat.vim 2007-05-05 20:04:19.000000000 +0200 ++++ vim71_ada/runtime/compiler/gnat.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -1,17 +1,19 @@ + "------------------------------------------------------------------------------ + " Description: Vim Ada/GNAT compiler file + " Language: Ada (GNAT) +-" $Id: gnat.vim,v 1.1 2007/05/05 18:04:19 vimboss Exp $ ++" $Id: gnat.vim 774 2007-09-17 09:11:59Z krischik $ + " Copyright: Copyright (C) 2006 Martin Krischik +-" Maintainer: Martin Krischik +-" $Author: vimboss $ +-" $Date: 2007/05/05 18:04:19 $ +-" Version: 4.2 +-" $Revision: 1.1 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/gnat.vim $ ++" Maintainer: Martin Krischi k ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/compiler/gnat.vim $ + " History: 24.05.2006 MK Unified Headers + " 16.07.2006 MK Ada-Mode as vim-ball + " 15.10.2006 MK Bram's suggestion for runtime integration ++" 19.09.2007 NO use project file only when there is a project + " Help Page: compiler-gnat + "------------------------------------------------------------------------------ + +@@ -46,6 +48,8 @@ + \ 'GNAT.Set Projectfile\.\.\.', + \ ':SetProject', + \ 'call gnat.Set_Project_File ()') ++ ++ call g:gnat.Set_Session () + endif + + if exists(":CompilerSet") != 2 +@@ -55,8 +59,6 @@ + command -nargs=* CompilerSet setlocal + endif + +-call g:gnat.Set_Session () +- + execute "CompilerSet makeprg=" . escape (g:gnat.Get_Command('Make'), ' ') + execute "CompilerSet errorformat=" . escape (g:gnat.Error_Format, ' ') + +diff -urN vim71/runtime/doc/ft_ada.txt vim71_ada/runtime/doc/ft_ada.txt +--- vim71/runtime/doc/ft_ada.txt 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/doc/ft_ada.txt 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,516 @@ ++*ft_ada.txt* Ada File type Plug-ins Last change: 2007 Seb 17 ++ ++ ++ ADA FILE TYPE PLUG-INS REFERENCE MANUAL~ ++ ++ADA *ada.vim* ++ ++1. Syntax Highlighting |ft-ada-syntax| ++2. Plug-in |ft-ada-plugin| ++3. Omni Completion |ft-ada-omni| ++ 3.1 Omni Completion with "gnat xref" |gnat-xref| ++ 3.2 Omni Completion with "ctags" |ada-ctags| ++4. Compiler Support |ada-compiler| ++ 4.1 GNAT |compiler-gnat| ++ 4.1 Dec Ada |compiler-decada| ++5. References |ada-reference| ++ 5.1 Options |ft-ada-options| ++ 5.2 Functions |ft-ada-functions| ++ 5.3 Commands |ft-ada-commands| ++ 5.4 Variables |ft-ada-variables| ++ 5.5 Constants |ft-ada-contstants| ++8. Extra Plug-ins |ada-extra-plugins| ++ ++============================================================================== ++1. Syntax Highlighting ~ ++ *ft-ada-syntax* ++ ++This mode is designed for the 2005 edition of Ada ("Ada 2005"), which includes ++support for objected-programming, protected types, and so on. It handles code ++written for the original Ada language ("Ada83", "Ada87", "Ada95") as well, ++though code which uses Ada 2005-only keywords will be wrongly colored (such ++code should be fixed anyway). For more information about Ada, see ++http://www.adapower.com. ++ ++The Ada mode handles a number of situations cleanly. ++ ++For example, it knows that the "-" in "-5" is a number, but the same character ++in "A-5" is an operator. Normally, a "with" or "use" clause referencing ++another compilation unit is coloured the same way as C's "#include" is coloured. ++If you have "Conditional" or "Repeat" groups coloured differently, then "end ++if" and "end loop" will be coloured as part of those respective groups. ++ ++You can set these to different colours using vim's "highlight" command (e.g., ++to change how loops are displayed, enter the command ":hi Repeat" followed by ++the colour specification; on simple terminals the colour specification ++ctermfg=White often shows well). ++ ++There are several options you can select in this Ada mode. See|ft-ada-options| ++for a complete list. ++ ++To enable them, assign a value to the option. For example, to turn one on: ++ > ++ > let g:ada_standard_types = 1 ++> ++To disable them use ":unlet". Example: ++> ++ > unlet g:ada_standard_types ++ ++You can just use ":" and type these into the command line to set these ++temporarily before loading an Ada file. You can make these option settings ++permanent by adding the "let" command(s), without a colon, to your "~/.vimrc" ++file. ++ ++Even on a slow (90Mhz) PC this mode works quickly, but if you find the ++performance unacceptable, turn on |g:ada_withuse_ordinary|. ++ ++Syntax folding instructions (|fold-syntax|) are added when |g:ada_folding| is ++set. ++ ++============================================================================== ++2. File type Plug-in ~ ++ *ft-ada-indent* *ft-ada-plugin* ++ ++The Ada plug-in provides support for: ++ ++ - auto indenting (|indent.txt|) ++ - insert completion (|i_CTRL-N|) ++ - user completion (|i_CTRL-X_CTRL-U|) ++ - tag searches (|tagsrch.txt|) ++ - Quick Fix (|quickfix.txt|) ++ - backspace handling (|'backspace'|) ++ - comment handling (|'comments'|, |'commentstring'|) ++ ++The plug-in only activates the features of the Ada mode whenever an Ada ++files is opened and add adds Ada related entries to the main and pop-up menu. ++ ++============================================================================== ++3. Omni Completion ~ ++ *ft-ada-omni* ++ ++The Ada omni-completions (|i_CTRL-X_CTRL-O|) uses tags database created either ++by "gnat xref -v" or the "exuberant Ctags (http://ctags.sourceforge.net). The ++complete function will automatically detect which tool was used to create the ++tags file. ++ ++------------------------------------------------------------------------------ ++3.1 Omni Completion with "gnat xref" ~ ++ *gnat-xref* ++ ++GNAT XREF uses the compiler internal information (ali-files) to produce the ++tags file. This has the advantage to be 100% correct and the option of deep ++nested analysis. However the code must compile, the generator is quite ++slow and the created tags file contains only the basic Ctags information for ++each entry - not enough for some of the more advanced Vim code browser ++plug-ins. ++ ++NOTE: "gnat xref -v" is very tricky to use as it has almost no diagnostic ++ output - If nothing is printed then usually the parameters are wrong. ++ Here some important tips: ++ ++1) You need to compile your code first and use the "-aO" option to point to ++ your .ali files. ++2) "gnat xref -v ../Include/adacl.ads" won't work - use the "gnat xref -v ++ -aI../Include adacl.ads" instead. ++3) "gnat xref -v -aI../Include *.ad?" won't work - use "cd ../Include" and ++ then "gnat xref -v *.ad?" ++4) Project manager support is completely broken - don't even try "gnat xref ++ -Padacl.gpr". ++5) VIM is faster when the tags file is sorted - use "sort --unique ++ --ignore-case --output=tags tags" . ++6) Remember to insert "!_TAG_FILE_SORTED 2 %sort ui" as first line to mark ++ the file assorted. ++ ++------------------------------------------------------------------------------ ++3.2 Omni Completion with "ctags"~ ++ *ada-ctags* ++ ++Exuberant Ctags uses it's own multi-language code parser. The parser is quite ++fast, produces a lot of extra informations (hence the name "Exuberant Ctags") ++and can run on files which currently do not compile. ++ ++There are also lots of other Vim-tools which use exuberant Ctags. ++ ++You will need to install a version of the Exuberant Ctags which has Ada ++support patched in. Such a version is available from the GNU Ada Project ++(http://gnuada.sourceforge.net). ++ ++The Ada parser for Exuberant Ctags is fairly new - don't expect complete ++support yet. ++ ++============================================================================== ++4. Compiler Support ~ ++ *ada-compiler* ++ ++The Ada mode supports more then one Ada compiler and will automatically load the ++compiler set in|g:ada_default_compiler|whenever an Ada source is opened. The ++provided compiler plug-ins are split into the actual compiler plug-in and a ++collection of support functions and variables. This allows the easy ++development of specialized compiler plug-ins fine tuned to your development ++environment. ++ ++------------------------------------------------------------------------------ ++4.1 GNAT ~ ++ *compiler-gnat* ++ ++GNAT is the only free (beer and speech) Ada compiler available. There are ++several version available which differentiate in the licence terms used. ++ ++The GNAT compiler plug-in will perform a compile on pressing and then ++immediately shows the result. You can set the project file to be used by ++setting: ++ > ++ > call g:gnat.Set_Project_File ('my_project.gpr') ++ ++Setting a project file will also create a Vim session (|views-sessions|) so - ++like with the GPS - opened files, window positions etc. will remembered ++separately for all projects. ++ ++ *gnat_members* ++GNAT OBJECT ~ ++ ++ *g:gnat.Make()* ++g:gnat.Make() ++ Calls|g:gnat.Make_Command|and displays the result inside a ++ |quickfix| window. ++ ++ *g:gnat.Pretty()* ++g:gnat.Pretty() ++ Calls|g:gnat.Pretty_Command| ++ ++ *g:gnat.Find()* ++g:gnat.Find() ++ Calls|g:gnat.Find_Command| ++ ++ *g:gnat.Tags()* ++g:gnat.Tags() ++ Calls|g:gnat.Tags_Command| ++ ++ *g:gnat.Set_Project_File()* ++g:gnat.Set_Project_File([{file}]) ++ Set gnat project file and load associated session. An open ++ project will be closed and the session written. If called ++ without file name the file selector opens for selection of a ++ project file. If called with an empty string then the project ++ and associated session are closed. ++ ++ *g:gnat.Project_File* ++g:gnat.Project_File string ++ Current project file. ++ ++ *g:gnat.Make_Command* ++g:gnat.Make_Command string ++ External command used for|g:gnat.Make()| (|'makeprg'|). ++ ++ *g:gnat.Pretty_Program* ++g:gnat.Pretty_Program string ++ External command used for|g:gnat.Pretty()| ++ ++ *g:gnat.Find_Program* ++g:gnat.Find_Program string ++ External command used for|g:gnat.Find()| ++ ++ *g:gnat.Tags_Command* ++g:gnat.Tags_Command string ++ External command used for|g:gnat.Tags()| ++ ++ *g:gnat.Error_Format* ++g:gnat.Error_Format string ++ Error format (|'errorformat'|) ++ ++------------------------------------------------------------------------------ ++4.2 Dec Ada ~ ++ *compiler-hpada* *compiler-decada* ++ *compiler-vaxada* *compiler-compaqada* ++ ++Dec Ada (also known by - in chronological order - VAX Ada, Dec Ada, Compaq Ada ++and HP Ada) is a fairly dated Ada 83 compiler. Support is basic: will ++compile the current unit. ++ ++The Dec Ada compiler expects the package name and not the file name to be ++passed a parameter. The compiler plug-in supports the usual file name ++convention to convert the file into a unit name. For separates both '-' and ++'__' are allowed. ++ ++ *decada_members* ++DEC ADA OBJECT ~ ++ ++ *g:decada.Make()* ++g:decada.Make() function ++ Calls|g:decada.Make_Command|and displays the result inside a ++ |quickfix| window. ++ ++ *g:decada.Unit_Name()* ++g:decada.Unit_Name() function ++ Get the Unit name for the current file. ++ ++ *g:decada.Make_Command* ++g:decada.Make_Command string ++ External command used for|g:decadat.Make()| (|'makeprg'|). ++ ++ *g:decada.Error_Format* ++g:decada.Error_Format| string ++ Error format (|'errorformat'|). ++ ++============================================================================== ++5. References ~ ++ *ada-reference* ++ ++------------------------------------------------------------------------------ ++5.1 Options ~ ++ *ft-ada-options* ++ ++ *g:ada_standard_types* ++g:ada_standard_types bool (true when exists) ++ Highlight types in package Standard (e.g., "Float") ++ ++ *g:ada_space_errors* ++ *g:ada_no_trail_space_error* ++ *g:ada_no_tab_space_error* ++ *g:ada_all_tab_usage* ++g:ada_space_errors bool (true when exists) ++ Highlight extraneous errors in spaces ... ++ g:ada_no_trail_space_error ++ - but ignore trailing spaces at the end of a line ++ g:ada_no_tab_space_error ++ - but ignore tabs after spaces ++ g:ada_all_tab_usage ++ - highlight all tab use ++ ++ *g:ada_line_errors* ++g:ada_line_errors bool (true when exists) ++ Highlight lines which are to long. Note: This highlighting ++ option is quite CPU intensive. ++ ++ *g:ada_rainbow_color* ++g:ada_rainbow_color bool (true when exists) ++ Use rainbow colours for '(' and ')'. You need the ++ rainbow_parenthesis for this to work ++ ++ *g:ada_folding* ++g:ada_folding set ('sigpft') ++ Use folding for Ada sources. ++ 's': activate syntax folding on load ++ 'p': fold packages ++ 'f': fold functions and procedures ++ 't': fold types ++ 'c': fold conditionals ++ 'g': activate gnat pretty print folding on load ++ 'i': lone 'is' folded with line above ++ 'b': lone 'begin' folded with line above ++ 'p': lone 'private' folded with line above ++ 'x': lone 'exception' folded with line above ++ 'i': activate indent folding on load ++ ++ Note: Syntax folding is in an early (unuseable) stage and ++ indent or gnat pretty folding is suggested. ++ ++ For gnat pretty folding to work the following settings are ++ suggested: -cl3 -M79 -c2 -c3 -c4 -A1 -A2 -A3 -A4 -A5 ++ ++ For indent folding to work the following settings are ++ suggested: shiftwidth=3 softtabstop=3 ++ ++ *g:ada_abbrev* ++g:ada_abbrev bool (true when exists) ++ Add some abbreviations. This feature more or less superseded ++ by the various completion methods. ++ ++ *g:ada_withuse_ordinary* ++g:ada_withuse_ordinary bool (true when exists) ++ Show "with" and "use" as ordinary keywords (when used to ++ reference other compilation units they're normally highlighted ++ specially). ++ ++ *g:ada_begin_preproc* ++g:ada_begin_preproc bool (true when exists) ++ Show all begin-like keywords using the colouring of C ++ preprocessor commands. ++ ++ *g:ada_omni_with_keywords* ++g:ada_omni_with_keywords ++ Add Keywords, Pragmas, Attributes to omni-completions ++ (|compl-omni|). Note: You can always complete then with user ++ completion (|i_CTRL-X_CTRL-U|). ++ ++ *g:ada_extended_tagging* ++g:ada_extended_tagging enum ('jump', 'list') ++ use extended tagging, two options are available ++ 'jump': use tjump to jump. ++ 'list': add tags quick fix list. ++ Normal tagging does not support function or operator ++ overloading as these features are not available in C and ++ tagging was originally developed for C. ++ ++ *g:ada_extended_completion* ++g:ada_extended_completion ++ Uses extended completion for and completions ++ (|i_CTRL-N|). In this mode the '.' is used as part of the ++ identifier so that 'Object.Method' or 'Package.Procedure' are ++ completed together. ++ ++ *g:ada_gnat_extensions* ++g:ada_gnat_extensions bool (true when exists) ++ Support GNAT extensions. ++ ++ *g:ada_with_gnat_project_files* ++g:ada_with_gnat_project_files bool (true when exists) ++ Add gnat project file keywords and Attributes. ++ ++ *g:ada_default_compiler* ++g:ada_default_compiler string ++ set default compiler. Currently supported is 'gnat' and ++ 'decada'. ++ ++An "exists" type is a boolean is considered true when the variable is defined ++and false when the variable is undefined. The value which the variable is ++set makes no difference. ++ ++------------------------------------------------------------------------------ ++5.3 Commands ~ ++ *ft-ada-commands* ++ ++:AdaRainbow *:AdaRainbow* ++ Toggles rainbow colour (|g:ada_rainbow_color|) mode for ++ '(' and ')' ++ ++:AdaLines *:AdaLines* ++ Toggles line error (|g:ada_line_errors|) display ++ ++:AdaSpaces *:AdaSpaces* ++ Toggles space error (|g:ada_space_errors|) display. ++ ++:AdaTagDir *:AdaTagDir* ++ Creates tags file for the directory of the current file. ++ ++:AdaTagFile *:AdaTagFile* ++ Creates tags file for the current file. ++ ++:AdaTypes *:AdaTypes* ++ Toggles standard types (|g:ada_standard_types|) colour. ++ ++:GnatFind *:GnatFind* ++ Calls |g:gnat.Find()| ++ ++:GnatPretty *:GnatPretty* ++ Calls |g:gnat.Pretty()| ++ ++:GnatTags *:GnatTags* ++ Calls |g:gnat.Tags()| ++ ++------------------------------------------------------------------------------ ++5.3 Variables ~ ++ *ft-ada-variables* ++ ++ *g:gnat* ++g:gnat object ++ Control object which manages GNAT compiles. The object ++ is created when the first Ada source code is loaded provided ++ that |g:ada_default_compiler|is set to 'gnat'. See|gnat_members| ++ for details. ++ ++ *g:decada* ++g:decada object ++ Control object which manages Dec Ada compiles. The object ++ is created when the first Ada source code is loaded provided ++ that |g:ada_default_compiler|is set to 'decada'. See ++ |decada_members|for details. ++ ++------------------------------------------------------------------------------ ++5.4 Constants ~ ++ *ft-ada-constants* ++ ft-ada-constants ++ ++All constants are locked. See |:lockvar| for details. ++ ++ *g:ada#WordRegex* ++g:ada#WordRegex string ++ Regular expression to search for Ada words ++ ++ *g:ada#DotWordRegex* ++g:ada#DotWordRegex string ++ Regular expression to search for Ada words separated by dots. ++ ++ *g:ada#Comment* ++g:ada#Comment string ++ Regular expression to search for Ada comments ++ ++ *g:ada#Keywords* ++g:ada#Keywords list of dictionaries ++ List of keywords, attributes etc. pp. in the format used by ++ omni completion. See |complete-items| for details. ++ ++ *g:ada#Ctags_Kinds* ++g:ada#Ctags_Kinds dictionary of lists ++ Dictionary of the various kinds of items which the Ada support ++ for Ctags generates. ++ ++------------------------------------------------------------------------------ ++5.2 Functions ~ ++ *ft-ada-functions* ++ ++ada#Word([{line}, {col}]) *ada#Word()* ++ Return full name of Ada entity under the cursor (or at given ++ line/column), stripping white space/newlines as necessary. ++ ++ada#List_Tag([{line}, {col}]) *ada#Listtags()* ++ List all occurrences of the Ada entity under the cursor (or at ++ given line/column) inside the quick-fix window ++ ++ada#Jump_Tag ({ident}, {mode}) *ada#Jump_Tag()* ++ List all occurrences of the Ada entity under the cursor (or at ++ given line/column) in the tag jump list. Mode can either be ++ 'tjump' or 'stjump'. ++ ++ada#Create_Tags ({option}) *ada#Create_Tags()* ++ Creates tag file using Ctags. The option can either be 'file' ++ for the current file, 'dir' for the directory of the current ++ file or a file name. ++ ++gnat#Insert_Tags_Header() *gnat#Insert_Tags_Header()* ++ Adds the tag file header (!_TAG_) information to the current ++ file which are missing from the GNAT XREF output. ++ ++ada#Switch_Syntax_Option ({option}) *ada#Switch_Syntax_Option()* ++ Toggles highlighting options on or off. Used for the Ada menu. ++ ++ *gnat#New()* ++gnat#New () ++ Create a new gnat object. See |g:gnat| for details. ++ ++ ++============================================================================== ++8. Extra Plugins ~ ++ *ada-extra-plugins* ++ ++You can optionally install the following extra plug-in. They work well with Ada ++and enhance the ability of the Ada mode.: ++ ++backup.vim ++ http://www.vim.org/scripts/script.php?script_id=1537 ++ Keeps as many backups as you like so you don't have to. ++ ++rainbow_parenthsis.vim ++ http://www.vim.org/scripts/script.php?script_id=1561 ++ Very helpful since Ada uses only '(' and ')'. ++ ++nerd_comments.vim ++ http://www.vim.org/scripts/script.php?script_id=1218 ++ Excellent commenting and uncommenting support for almost any ++ programming language. ++ ++matchit.vim ++ http://www.vim.org/scripts/script.php?script_id=39 ++ '%' jumping for any language. The normal '%' jump only works for '{}' ++ style languages. The Ada mode will set the needed search patters. ++ ++taglist.vim ++ http://www.vim.org/scripts/script.php?script_id=273 ++ Source code explorer sidebar. There is a patch for Ada available. ++ ++The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim ++contains all of the above. ++ ++============================================================================== ++vim: textwidth=78 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++vim: filetype=help +diff -urN vim71/runtime/doc/NERD_commenter.txt vim71_ada/runtime/doc/NERD_commenter.txt +--- vim71/runtime/doc/NERD_commenter.txt 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/doc/NERD_commenter.txt 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,1155 @@ ++*NERD_comments.txt* Plugin for commenting code v169 ++ ++ ++ NERD_COMMENTS REFERENCE MANUAL~ ++ ++ ++ ++ ++ ++============================================================================== ++CONTENTS {{{2 *NERD_comments-contents* ++ ++ 1.Intro...................................|NERD_comments| ++ 2.Functionality provided..................|NERD_com-functionality| ++ 2.1 Functionality Summary.............|NERD_com-functionality-summary| ++ 2.2 Functionality Details.............|NERD_com-functionality-details| ++ 2.2.1 Comment map.................|NERD_com-comment| ++ 2.2.2 Nested comment map..........|NERD_com-nested-comment| ++ 2.2.3 Toggle comment map..........|NERD_com-toggle-comment| ++ 2.2.4 Minimal comment map.........|NERD_com-minimal-comment| ++ 2.2.5 Invert comment map..........|NERD_com-invert-comment| ++ 2.2.6 Sexy comment map............|NERD_com-sexy-comment| ++ 2.2.7 Yank comment map............|NERD_com-yank-comment| ++ 2.2.8 Comment to EOL map..........|NERD_com-EOL-comment| ++ 2.2.9 Append com to line map......|NERD_com-append-comment| ++ 2.2.10 Prepend com to line map....|NERD_com-prepend-comment| ++ 2.2.11 Insert comment map.........|NERD_com-insert-comment| ++ 2.2.12 Use alternate delims map...|NERD_com-alt-delim| ++ 2.2.13 Comment aligned maps.......|NERD_com-aligned-comment| ++ 2.2.14 Uncomment line map.........|NERD_com-uncomment-line| ++ 2.3 Supported filetypes...............|NERD_com-filetypes| ++ 2.4 Sexy Comments.....................|NERD_com_sexy_comments| ++ 3.Customisation...........................|NERD_com-customisation| ++ 3.1 Customisation summary.............|NERD_com-cust-summary| ++ 3.2 Customisation details.............|NERD_com-cust-details| ++ 3.3 Default delimiter customisation...|NERD_com-cust-delims| ++ 3.4 Key mapping customisation.........|NERD_com-cust-keys| ++ 3.5 Sample regular expressions........|NERD_com-reg-exps| ++ 4.Issues with the script..................|NERD_com-issues| ++ 4.1 Delimiter detection heuristics....|NERD_com-heuristics| ++ 4.2 Nesting issues....................|NERD_com-nesting| ++ 4.3 Nesting issues....................|NERD_com-nesting| ++ 4.3 Mark clobbering...................|NERD_com-mark-clobbering| ++ 5.TODO list...............................|NERD_com-todo| ++ 6.Credits.................................|NERD_com-credits| ++ ++============================================================================== ++1. Intro {{{2 *NERD_comments* ++ ++NERD_comments provides a set of handy key mappings for commenting code. These ++mappings are consistent across all supported filetypes. ++ ++When writing NERD_comments I have tried to give it as many features/options as ++possible while keeping it so that the plugin can still be used with little or ++no knowledge of these. The average user need only know about a few key ++mappings to use NERD_comments while there are plenty of other features for the ++l33t nerd take advantage of. ++ ++Enjoy :D ++ ++============================================================================== ++2. Functionality provided {{{2 *NERD_com-functionality* ++ ++------------------------------------------------------------------------------ ++2.1 Functionality summary {{{3 *NERD_com-functionality-summary* ++ ++The following key mappings are provided by default (there is also a menu ++provided that contains menu items corresponding to all the below mappings): ++ ++Note: is a user defined key that is used to start keymappings and ++defaults to \. Check out || for details. ++ ++Most of the following mappings are for normal/visual mode only. The ++|NERD_com-insert-comment| mapping is for insert mode only. ++ ++cc |NERD_com-comment-map| ++Comments out the current line or text selected in visual mode. ++ ++ ++cn |NERD_com-nested-comment| ++Same as |NERD_com-comment-map| but enforces nesting. ++ ++ ++c |NERD_com-toggle-comment| ++Toggles the comment state of the selected line(s). If the topmost selected ++line is commented, all selected lines are uncommented and vice versa. ++ ++ ++cm |NERD_com-minimal-comment| ++Comments the given lines using only one set of multipart delimiters if ++possible. ++ ++ ++ci |NERD_com-invert-comment| ++Toggles the comment state of the selected line(s) individually. Each selected ++line that is commented is uncommented and vice versa. ++ ++ ++cs |NERD_com-sexy-comment| ++Comments out the selected lines ``sexually'' ++ ++ ++cy |NERD_com-yank-comment| ++Same as |NERD_com-comment-map| except that the commented line(s) are yanked ++before commenting. ++ ++ ++c$ |NERD_com-EOL-comment| ++Comments the current line from the cursor to the end of line. ++ ++ ++cA |NERD_com-append-comment| ++Adds comment delimiters to the end of line and goes into insert mode between ++them. ++ ++ ++cI |NERD_com-prepend-comment| ++Adds comment delimiters to the start of line and goes into insert mode between ++them. ++ ++ ++ |NERD_com-insert-comment| ++Adds comment delimiters at the current cursor position and inserts between. ++ ++ ++ca |NERD_com-alt-delim| ++Switches to the alternative set of delimiters. ++ ++ ++cl OR cr OR cb |NERD_com-aligned-comment| ++Same as |NERD_com-comment| except that the delimiters are aligned down the ++left side (cl), the right side (cr) or both sides ++(cb). ++ ++ ++cu |NERD_com-uncomment-line| ++Uncomments the selected line(s). ++ ++------------------------------------------------------------------------------ ++2.2 Functionality details {{{3 *NERD_com-functionality-details* ++ ++------------------------------------------------------------------------------ ++2.2.1 Comment map *NERD_com-comment* ++cc ++Comments out the current line. If multiple lines are selected in visual-line ++mode, they are all commented out. If some text is selected in visual or ++visual-block mode then NERD_comments will try to comment out the exact text ++that is selected using multi-part delimiters if they are available. ++ ++Works in normal, visual, visual-line and visual-block mode. ++ ++Change the mapping with: |NERD_com_line_map|. ++ ++Relevant options: ++|NERD_allow_any_visual_delims_regexp| ++|NERD_comment_whole_lines_in_v_mode| ++|NERD_block_com_after_right| ++|NERD_left_align_regexp| ++|NERD_place_holder_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++------------------------------------------------------------------------------ ++2.2.2 Nested comment map *NERD_com-nested-comment* ++cn ++Performs nested commenting. Works the same as cc except that if a ++line is already commented then it will be commented again. ++ ++If the filetype is covered by the |NERD_place_holder_regexp| option ++then the previous comment delimiters will be replaced by place-holder ++delimiters if needed. Otherwise the nested comment will only be added if the ++current commenting delimiters have no right delimiter (to avoid compiler ++errors) ++ ++Works in normal, visual, visual-line, visual-block modes. ++ ++Change the mapping with: |NERD_com_line_nest_map|. ++ ++Relevant options: ++|NERD_allow_any_visual_delims_regexp| ++|NERD_comment_whole_lines_in_v_mode| ++|NERD_block_com_after_right| ++|NERD_left_align_regexp| ++|NERD_place_holder_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++ ++------------------------------------------------------------------------------ ++2.2.3 Toggle comment map *NERD_com-toggle-comment* ++c ++Toggles commenting of the lines selected. The behaviour of this mapping ++depends on whether the first line selected is commented or not. If so, all ++selected lines are uncommented and vice versa. ++ ++With this mapping, lines are only considered to be commented if a left comment ++delimiter is the first non-space/tab char on the line. ++ ++Works in normal, visual-line, modes. ++Using this mapping in visual or visual-block modes will cause it to work like ++|NERD_com-comment| ++ ++Change the mapping with: |NERD_com_line_toggle_map|. ++ ++Relevant options: ++|NERD_left_align_regexp| ++|NERD_right_align_regexp| ++|NERD_space_delim_filetype_regexp| ++|NERD_use_nested_comments_default| ++ ++------------------------------------------------------------------------------ ++2.2.4 Minimal comment map *NERD_com-minimal-comment* ++cm ++Comments the selected lines using one set of multipart delimiters if possible. ++ ++For example: if you are programming in c and you select 5 lines and press ++cm then a '/*' will be placed at the start of the top line and a '*/' ++will be placed at the end of the last line. ++ ++Sets of multipart comment delimiters that are between the top and bottom ++selected lines are replaced with place holders (see |NERD_lPlace|) if ++NERD_place_holder_regexp is set for the current filetype. If it is not, then ++the comment will be aborted if place holders are required to prevent illegal ++syntax. ++ ++------------------------------------------------------------------------------ ++2.2.5 Invert comment map *NERD_com-invert-comment* ++ci ++Inverts the commented state of each selected line. If the a selected line is ++commented then it is uncommented and vice versa. Each line is examined and ++commented/uncommented individually. ++ ++With this mapping, lines are only considered to be commented if a left comment ++delimiter is the first non-space/tab char on the line. ++ ++Works in normal, visual-line, modes. ++ ++Change the mapping with: |NERD_com_line_invert_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.6 Sexy comment map *NERD_com-sexy-comment* ++cs ++Comments the selected line(s) ``sexily''... see |NERD_com_sexy_commenting| for ++a description of what sexy comments are. Can only be done on filetypes for ++which there is at least one set of multipart comment delimiters specified. ++ ++Sexy comments cannot be nested and lines inside a sexy comment cannot be ++commented again. ++ ++Works in normal, visual-line. ++ ++Change the mapping with: |NERD_com_line_sexy_map| ++ ++Relevant options: ++|NERD_use_compact_sexy_com_regexp| ++ ++------------------------------------------------------------------------------ ++2.2.7 Yank comment map *NERD_com-yank-comment* ++cy ++Same as cc except that it yanks the line(s) that are commented first. ++ ++Works in normal, visual, visual-line, visual-block modes. ++ ++Change the mapping with: |NERD_com_line_yank_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.8 Comment to EOL map *NERD_com-EOL-comment* ++c$ ++Comments the current line from the current cursor position up to the end of ++the line. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_com_to_end_of_line_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.9 Append com to line map *NERD_com-append-comment* ++cA ++Appends comment delimiters to the end of the current line and goes ++to insert mode between the new delimiters. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_append_com_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.10 Prepend com to line map *NERD_com-prepend-comment* ++cI ++Prepends comment delimiters to the start of the current line and goes to ++insert mode between the new delimiters. ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_prepend_com_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.11 Insert comment map *NERD_com-insert-comment* ++ ++Adds comment delimiters at the current cursor position and inserts ++between them. ++ ++Works in insert mode. ++ ++Change the mapping with: |NERD_com_in_insert_map|. ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.12 Use alternate delims map *NERD_com-alt-delim* ++ca ++Changes to the alternative commenting style if one is available. For example, ++if the user is editing a c++ file using // comments and they hit ca ++then they will be switched over to /**/ comments. ++keys for this mappings can be overridden with the ++ ++Works in normal mode. ++ ++Change the mapping with: |NERD_alt_com_map| ++ ++Relevant options: ++ ++ ++------------------------------------------------------------------------------ ++2.2.13 Comment aligned maps *NERD_com-aligned-comment* ++cl cr cb ++Same as cc except that the comment delimiters are aligned on the left ++side, right side or both sides respectively. These comments are always nested ++if the line(s) are already commented. ++ ++Works in normal, visual-line. ++ ++Change the mappings with: |NERD_com_align_left_map|, |NERD_com_align_right_map| ++and |NERD_com_align_both_map|. ++ ++Relevant options: ++|NERD_left_align_regexp| ++|NERD_right_align_regexp| ++ ++ ++------------------------------------------------------------------------------ ++2.2.14 Uncomment line map *NERD_com-uncomment-line* ++cu ++Uncomments the current line. If multiple lines are selected in ++visual mode then they are all uncommented. ++ ++When uncommenting, if the line contains multiple sets of delimiters then the ++``outtermost'' pair of delimiters will be removed. ++ ++The script uses a set of heurisics to distinguish ``real'' delimiters from ++``fake'' ones when uncommenting. See |NERD_com-issues| for details. ++ ++Works in normal, visual, visual-line, visual-block. ++ ++Change the mapping with: |NERD_uncom_line_map|. ++ ++Relevant options: ++|NERD_dont_remove_alt_coms| ++|NERD_dont_remove_spaces_regexp| ++ ++ ++------------------------------------------------------------------------------ ++2.3 Supported filetypes *NERD_com-filetypes* ++ ++Files that can be commented by this plugin: ++abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asm ++asn aspvbs atlas automake ave awk basic b bc bdf bib bindzone btm caos catalog ++c cfg cg ch cl clean clipper conf config cpp crontab cs csc csp css cterm cupl ++cvs dcl def diff dns dosbatch dosini dot dracula dsl dtd dtml dylan ecd eiffel ++elf elmfilt erlang eruby eterm expect exports fgl focexec form fortran foxpro ++fvwm fx gdb gdmo gnuplot gtkrc haskell hb h help hercules hog html htmlos ia64 ++icon idlang idl indent inform inittab ishd iss ist jam java javascript jess ++jgraph jproperties jproperties jsp kix kscript lace lex lftp lifelines lilo ++lisp lite lotos lout lprolog lscript lss lua lynx m4 make maple masm master ++matlab mel mf mib mma model moduala. modula2 modula3 monk mush muttrc named ++nasm nastran natural ncf netrw nqc nsis ocaml omnimark openroad opl ora ox ++pascal pcap pccts perl pfmain php phtml pic pike pilrc pine plm plsql po ++postscr pov povini ppd ppwiz procmail progress prolog psf ptcap python python ++radiance ratpoison r rc readline rebol registry remind rexx robots rpl ruby sa ++samba sas sather scheme scilab screen scsh sdl sed sgml sgmldecl sgmllnx sicad ++simula sinda skill slang sl slrnrc sm smil smith sml snnsnet snnspat snnsres ++snobol4 spec specman spice sql sqlforms sqlj sqr squid st stp strace svn tads ++taglist tags tak tasm tcl terminfo tex texinfo texmf tf tidy tli trasys tsalt ++tsscl tssgm uc uil vb verilog vgrindefs vhdl vim virata vrml vsejcl webmacro ++wget winbatch wml sh wvdial xdefaults xf86conf xhtml xkb xmath xml xmodmap ++xpm2 xpm xslt yacc yaml z8a ++ ++If a language is not in the list of hardcoded supported filetypes then the ++&commentstring vim option is used. ++ ++ ++------------------------------------------------------------------------------ ++2.4 Sexy Comments *NERD_com_sexy_comments* ++These are comments that use one set of multipart comment delimiters as well as ++one other marker symbol. For example: > ++ /* ++ * This is a c style sexy comment ++ * So there! ++ */ ++ ++ /* This is a c style sexy comment ++ * So there! ++ * But this one is ``compact'' style */ ++< ++Here the multipart delimiters are /* and */ and the marker is *. NERD_comments ++is capable of adding and removing comments of this type. ++ ++ ++============================================================================== ++3. Customisation {{{2 *NERD_com-customisation* ++ ++------------------------------------------------------------------------------ ++3.1 Customisation summary *NERD_com-cust-summary* ++ ++|loaded_nerd_comments| Turns off the script. ++|NERD_allow_any_visual_delims_regexp| Allows multipart alternative delims to ++ be used when commenting in ++ visual/visual-block mode. ++|NERD_block_com_after_right| Forces right delims to be placed when ++ doing visual-block comments. ++|NERD_comment_whole_lines_in_v_mode| Changes behaviour of visual comments. ++|NERD_menu_mode| Determines if a NERD comment menu will ++ be made and whether the menu will have a ++ keyboard shortcut. ++|NERD_dont_remove_alt_coms| Causes alternative comments not to be ++ removed when uncommenting. ++|NERD_dont_remove_spaces_regexp| Causes spaces not to be removed when ++ uncommenting if the filetype doesnt ++ match |NERD_space_delim_filetype_regexp| ++|NERD_create_h_filetype| Creates a new filetype for .h files. ++|NERD_lPlace| Specifies what to use as the left ++ delimiter placeholder when nesting ++ comments. ++|NERD_left_align_regexp| Specifies which filetypes to align left ++ delimiters for. ++|NERD_mapleader| Specifies what all the commenting key ++ mappings will begin with. ++|NERD_place_holder_regexp| Specifies which filetypes may use ++ placeholders when nesting comments. ++|NERD_right_align_regexp| Specifies which filetypes to align right ++ delimiters for. ++|NERD_rPlace| Specifies what to use as the right ++ delimiter placeholder when nesting ++ comments. ++|NERD_shut_up| Stops all output from the script. ++|NERD_space_delim_filetype_regexp| Specifies which filetypes to add spaces ++ around the delimiters for. ++|NERD_use_compact_sexy_com_regexp| Specifies which filetypes to use compact ++ sexy comments for. ++|NERD_use_nested_comments_default| Tells the script to use nested comments ++ by default. ++ ++----------------------------------------------------------------------------- ++3.3 Customisation details *NERD_com-cust-details* ++ ++To enable any of the below options you should put the given line in your ++~/.vimrc ++ ++ *loaded_nerd_comments* ++If this script is driving you insane you can turn it off by setting this ++option > ++ let loaded_nerd_comments=1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_allow_any_visual_delims_regexp* ++This option is set to a regular expression that is used to specify which ++filetypes this option should be turned on for. If this covers the current ++filetype then, when NERD_comments is doing a visual or visual-block comment ++(but not a visual-line comment) it will choose the right delimiters to use for ++the comment. This normally means using the current delimiters if they are ++multipart or using the alternative delimiters if THEY are multipart and the ++current delims are not. For example if we are editing the following java ++code: > ++ float foo = 1221; ++ float bar = 324; ++ System.out.println(foo * bar); ++< ++If we are using // comments and select the "foo" and "bar" in visual-block ++mode, as shown left below (where '|'s are used to represent the visual-block ++boundary), and comment it then it will use the alternative delims as shown on ++the right: > ++ float |foo| = 1221; float /*foo*/ = 1221; ++ float |bar| = 324; float /*bar*/ = 324; ++ System.out.println(foo * bar); System.out.println(foo * bar); ++< ++By default this option is set to '.*' i.e is turned on for all filetypes. ++ ++----------------------------------------------------------------------------- ++ *NERD_block_com_after_right* ++This option affects commenting when it is done in visual-block mode. If this ++option is turned on, lines that begin outside the right boundary of the ++selection block will be commented. Enable this option with: > ++ let NERD_block_com_after_right=1 ++< ++For example, if you are commenting this chunk of c code in visual-block mode ++(where the '|'s are used to represent the visual-block boundary) > ++ #include ++ #include ++ #include ++ |int| main(){ ++ | | printf("SUCK THIS\n"); ++ | | while(1){ ++ | | fork(); ++ | | } ++ |} | ++< ++If NERD_block_com_after_right=1 then this code will become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ /* */ printf("SUCK THIS\n"); ++ /* */ while(1){ ++ /* */ fork(); ++ /* */ } ++ /*} */ ++< ++Otherwise, the code block would become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ printf("SUCK THIS\n"); ++ while(1){ ++ fork(); ++ } ++ /*} */ ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_comment_whole_lines_in_v_mode* ++This option can take 2 values. By default NERD_comments tries to comment out ++exactly what is selected in visual mode (v). For example if you select and ++comment the following c code (using | to represent the visual boundary): > ++ in|t foo = 3; ++ int bar =| 9; ++ int baz = foo + bar; ++< ++This will result in: > ++ in/*t foo = 3;*/ ++ /*int bar =*/ 9; ++ int baz = foo + bar; ++< ++But some people prefer it if the whole lines are commented like: > ++ /*int foo = 3;*/ ++ /*int bar = 9;*/ ++ int baz = foo + bar; ++< ++If you prefer the second option then stick this line in your .vimrc: > ++ let NERD_comment_whole_lines_in_v_mode=1 ++< ++ ++If the filetype you are editing only has no multipart delimiters (for example ++a shell script) and you hadnt set this option then the above would become > ++ in#t foo = 3; ++ #int bar = 9; ++< ++(where # is the comment delimiter) as this is the closest NERD_comments can ++come to commenting out exactly what was selected. If you prefer for whole ++lines to be commented out when there is no multipart delimiters but the EXACT ++text that was selected to be commented out if there IS multipart delimiters ++then stick the following line in your .vimrc: > ++ let NERD_comment_whole_lines_in_v_mode=2 ++< ++ ++Note that this option does not affect the behaviour of visual-block mode (). ++ ++----------------------------------------------------------------------------- ++ *NERD_dont_remove_alt_coms* ++When uncommenting a line when there is an alternative commenting style for the ++current filetype, this option tells the script not to look for, and remove, ++comments delimiters of the alternative style. > ++ let NERD_dont_remove_alt_coms=1 ++< ++For example, if you are editing a c++ file using // style comments and you go ++cu on this line: > ++ /* This is a c++ comment baby! */ ++< ++It will not be uncommented if the NERD_dont_remove_alt_coms is set to 1. ++ ++----------------------------------------------------------------------------- ++ *NERD_dont_remove_spaces_regexp* ++By default, the NERD commenter will remove spaces around comment delimiters if ++either: ++1. The current filetype matches the |NERD_space_delim_filetype_regexp| option ++ (which is a regular expression). ++2. The current filtype doesnt match NERD_dont_remove_spaces_regexp option ++ (which is also a reg exp) ++ ++This means that if we have the following lines in a c code file: > ++ /* int foo = 5; */ ++ /* int bar = 10; */ ++ int baz = foo + bar ++< ++If either of the above conditions hold then if these lines are uncommented ++they will become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++Otherwise they would become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++If you want the spaces to be removed only if the current filetype matches ++|NERD_space_delim_filetype_regexp| then set the ++NERD_dont_remove_spaces_regexp option in your vimrc so that it matches the ++desired filetypes. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++Defaults to "^python$" ++ ++----------------------------------------------------------------------------- ++ *NERD_create_h_filetype* ++If this option is set then NERD_comments will create a seperate filetype for h ++files. This could be needed because some versions of vim treat h files as cpp ++files which can be dodgy for commenting because if you are using // to comment ++cpp files then this is invalid when you are commenting h files for a c ++project (unless you arent adhering to the ANSI standard... naughty naughty). ++To enable this option, stick the following line in your .vimrc: > ++ let NERD_create_h_filetype = 1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_lPlace* ++ *NERD_rPlace* ++These options are used to control the strings used as place-holder delimiters. ++Place holder delimiters are used when performing nested commenting when the ++filetype supports commenting styles with both left and right delimiters. ++To set these options use lines like: > ++ let NERD_lPlace="FOO" ++ let NERD_rPlace="BAR" ++< ++Following the above example, if we have line of c code: > ++ /* int horse */ ++< ++and we comment it with cn it will be changed to: > ++ /*FOO int horse BAR*/ ++< ++When we uncomment this line it will go back to what it was. ++NERD_lPlace defaults to '[>', NERD_rPlace defaults to '<]'. ++ ++----------------------------------------------------------------------------- ++ *NERD_left_align_regexp* ++This option is a regular expression which is used to specify which filetypes ++should have their left delimiters aligned when commenting multiple lines. ++ ++For example, consider this chunk of c code: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 while(foo < 50){ ++ 4 foo = foo + bar; ++ 5 printf("i am just making up this code\n"); ++ 6 printf("i have no idea what im writing\n"); ++ 7 } ++< ++If the NERD_left_align_regexp regexp covers c files then if we select lines ++3-7 in visual mode and hit cc the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /*while(foo < 50){*/ ++ 4 /* foo = foo + bar;*/ ++ 5 /* printf("i am just making up this code\n");*/ ++ 6 /* printf("i have no idea what im writing\n");*/ ++ 7 /*}*/ ++< ++If NERD_left_align_regexp doesnt cover c files then the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /* while(foo < 50){ */ ++ 4 /* foo = foo + bar; */ ++ 5 /* printf("i am just making up this code\n"); */ ++ 6 /* printf("i have no idea what im writing\n"); */ ++ 7 /* } */ ++< ++NERD_left_align_regexp defaults to '^$' meaning no filetypes have their left ++delims aligned. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_mapleader* ++NERD_mapleader is used to specify what all the NERD commenter key mappings ++begin with. ++ ++Assuming that == '\', the default key mappings will look like this: > ++ \cc ++ \cu ++ \ca ++ \ci ++ \cs ++ ... ++< ++However, if this line: > ++ let NERD_mapleader = ',x' ++< ++were present in your vimrc then the default mappings would look like this: > ++ ,xc ++ ,xu ++ ,xa ++ ,xi ++ ,xs ++ ... ++< ++This option only affects the mappings that have not been explicitly set ++manually (see |NERD_com-cust-keys|). ++ ++Default is c. ++ ++----------------------------------------------------------------------------- ++ *NERD_menu_mode* ++This option can take 3 values: ++ "0": Turns the NERD commenter menu off completely. ++ "1": Turns the NERD commenter menu on with no menu shortcut. ++ "2": Turns the NERD commenter menu on with -c as the menu shortcut. ++ ++Default is "2". ++ ++----------------------------------------------------------------------------- ++ *NERD_place_holder_regexp* ++This option is a regular expression which is used to specify which filetypes ++place-holder delimiters should be used for when adding nested comments. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_right_align_regexp* ++This option is a regular expression which is used to specify which filetypes ++should have their right delimiters aligned when commenting multiple lines. ++ ++For example, consider this chunk of c code: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 while(foo < 50){ ++ 4 foo = foo + bar; ++ 5 printf("i am just making up this code\n"); ++ 6 printf("i have no idea what im writing\n"); ++ 7 } ++< ++If the NERD_right_align_regexp regexp covers c files then if we select lines ++3-7 in visual mode and hit cc the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /*while(foo < 50){ */ ++ 4 /*foo = foo + bar; */ ++ 5 /*printf("i am just making up this code\n"); */ ++ 6 /*printf("i have no idea what im writing\n");*/ ++ 7 /*} */ ++< ++If NERD_right_align_regexp doesnt cover c files then the code will become: > ++ 1 int foo = 3; ++ 2 int bar = 5; ++ 3 /* while(foo < 50){ */ ++ 4 /* foo = foo + bar; */ ++ 5 /* printf("i am just making up this code\n"); */ ++ 6 /* printf("i have no idea what im writing\n"); */ ++ 7 /* } */ ++< ++NERD_right_align_regexp defaults to '^$' meaning no filetypes have their right ++delims aligned. ++ ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_shut_up* ++This option is used to prevent NERD_comments from echoing anything. ++Stick this line in your .vimrc: > ++ let NERD_shut_up=1 ++< ++ ++----------------------------------------------------------------------------- ++ *NERD_space_delim_filetype_regexp* ++Some people prefer a space after the left delimiter and before the right ++delimiter like this: > ++ /* int foo=2; */ ++< ++as opposed to this: > ++ /*int foo=2;*/ ++< ++This option is a regular expression that is used to specify which filetypes ++NERD_comments should use spaces for (as in the first eg above). ++NERD_space_delim_filetype_regexp defaults to '^$'. ++ ++See also |NERD_dont_remove_spaces_regexp|. ++See |NERD_com-reg-exps| for example reg exps. ++ ++----------------------------------------------------------------------------- ++ *NERD_use_compact_sexy_com_regexp* ++Some people may want their sexy comments to be like this: > ++ /* Hi There! ++ * This is a sexy comment ++ * in c */ ++< ++As opposed to like this: > ++ /* ++ * Hi There! ++ * This is a sexy comment ++ * in c ++ */ ++< ++The option NERD_use_compact_sexy_com_regexp is a regular expression. If the ++filetype that the user is commenting matches this regular expression then when ++they do sexy comments they will look like the first comment above. ++ ++----------------------------------------------------------------------------- ++ *NERD_use_nested_comments_default* ++When this option is turned on comments are nested automatically. That is, if ++you hit cc on a line that is already commented, or contains comments, ++it will be commented again. > ++ let NERD_use_nested_comments_default=1 ++< ++ ++----------------------------------------------------------------------------- ++3.3 Default delimiter customisation *NERD_com-cust-delims* ++These options are used to tell NERD_comments which delimiters to use for a ++given filetype when it first loads up. To set one of these options just stick ++the corresponding line in your .vimrc. For example: if i want to use /* */ to ++delimit comments in java files instead of // (which is the default) then I ++would stick this line in my .vimrc: > ++ let NERD_use_c_style_java_comments=1 ++< ++ ++Note that if filetype has two commenting styles, which are both supported, you ++can switch between them with ca. See |NERD_com-alt-delim|. These ++options only change which style is used when the script is initialsed. ++ ++NERD_use_ada_with_spaces: use -- instead of -- for ada files. ++NERD_use_c_style_acedb_comments: use /**/ instead of // for acedb files. ++NERD_use_c_style_ch_comments: use /**/ instead of // for ch files. ++NERD_use_c_style_clean_comments: use /**/ instead of // for clean files. ++NERD_use_c_style_clipper_comments: use /**/ instead of // for clipper files. ++NERD_use_c_style_cpp_comments: use /**/ instead of // for c++ files. ++NERD_use_c_style_cs_comments: use /**/ instead of // for c# files. ++NERD_use_c_style_dot_comments: use /**/ instead of // for dot files. ++NERD_use_c_style_dylan_comments: use /**/ instead of // for dylan files. ++NERD_use_c_style_h_comments: use /**/ instead of // for h files. ++NERD_use_c_style_hercules_comments: use /**/ instead of // for hercules files. ++NERD_use_c_style_idl_comments: use /**/ instead of // for idl files. ++NERD_use_c_style_ishd_comments: use /**/ instead of // for ishd files. ++NERD_use_c_style_java_comments: use /**/ instead of // for java files. ++NERD_use_c_style_javascript_comments: use /**/ instead of // for javascript files. ++NERD_use_c_style_kscript_comments: use /**/ instead of // for kscript files. ++NERD_use_c_style_mel_comments: use /**/ instead of // for mel files. ++NERD_use_c_style_named_comments: use /**/ instead of // for named files. ++NERD_use_c_style_pccts_comments: use /**/ instead of // for pccts files. ++NERD_use_c_style_php_comments: use /* */ instead of // for php files. ++NERD_use_c_style_pike_comments: use /**/ instead of // for pike files. ++NERD_use_c_style_pilrc_comments: use /**/ instead of // for pilrc files. ++NERD_use_c_style_plm_comments: use /**/ instead of // for plm files. ++NERD_use_c_style_pov_comments: use /**/ instead of // for pov files. ++NERD_use_c_style_prolog_comments: use /**/ instead of % for prolog files. ++NERD_use_c_style_rc_comments: use /**/ instead of // for rc files. ++NERD_use_c_style_tads_comments: use /**/ instead of // for tads files. ++NERD_use_c_style_tsalt_comments: use /**/ instead of // for tsalt files. ++NERD_use_c_style_uc_comments: use /**/ instead of // for uc files. ++NERD_use_c_style_verilog_comments: use /**/ instead of // for verilog files. ++NERD_use_dash_dash_simula_comments: use -- instead of % for simula files. ++NERD_use_dnl_style_automake_comments: use dnl instead of # for automake files. ++NERD_use_hash_samba_comments: use # instead of ; for samba files. ++NERD_use_long_haskell_comments: use {--} instead of -- for haskell files. ++NERD_use_long_lisp_comments: use #||# instead of ; for lisp files. ++NERD_use_long_lua_comments: use --[[]] instead of -- for lua files. ++NERD_use_paren_star_pascal_comments: use (**) instead of {} for pascal files. ++NERD_use_REM_basic_comments: use REM instead of ' for basic files. ++NERD_use_single_part_c_comments: use // instead of /* */ for c files. ++ ++ ++----------------------------------------------------------------------------- ++3.4 Key mapping customisation *NERD_com-cust-keys* ++ ++These options are used to override the default keys that are used for the ++commenting mappings. Their values must be set to strings. As an example: if ++you wanted to use the mapping foo to uncomment lines of code then ++you would place this line in your vimrc > ++ let NERD_uncom_line_map="foo" ++< ++ ++Check out |NERD_com-functionality| for details about what the following ++mappings do. ++ ++ *NERD_alt_com_map* ++To override the ca mapping, set this option > ++ let NERD_alt_com_map="" ++< ++ *NERD_append_com_map* ++To override the ce mapping, set this option > ++ let NERD_append_com_map="" ++< ++ *NERD_com_align_left_map* ++To override the cl mapping, set this option > ++ let NERD_com_align_left_map="" ++< ++ *NERD_com_align_both_map* ++To override the cb mapping, set this option > ++ let NERD_com_align_both_map="" ++< ++ *NERD_com_align_right_map* ++To override the cr mapping, set this option > ++ let NERD_com_align_right_map="" ++< ++ *NERD_com_in_insert_map* ++To override the mapping, set this option > ++ let NERD_com_in_insert_map="" ++< ++ *NERD_com_line_invert_map* ++To override the ci mapping, set this option > ++ let NERD_com_line_invert_map="" ++< ++ *NERD_com_line_map* ++To override the cc mapping, set this option > ++ let NERD_com_line_map="" ++< ++ *NERD_com_line_nest_map* ++To override the cn mapping, set this option > ++ let NERD_com_line_nest_map="" ++< ++ *NERD_com_line_sexy_map* ++To override the cs mapping, set this option > ++ let NERD_com_line_sexy_map="" ++< ++ *NERD_com_line_toggle_map* ++To override the c mapping, set this option > ++ let NERD_com_line_toggle_map="" ++< ++ *NERD_com_line_minimal_map* ++To override the cm mapping, set this option > ++ let NERD_com_line_minimal_map="" ++< ++ *NERD_com_to_end_of_line_map* ++To override the c$ mapping, set this option > ++ let NERD_com_to_end_of_line_map="" ++< ++ *NERD_com_line_yank_map* ++To override the cy mapping, set this option > ++ let NERD_com_line_yank_map="" ++< ++ *NERD_uncom_line_map* ++To override the cu mapping, set this option > ++ let NERD_uncom_line_map="" ++< ++ ++------------------------------------------------------------------------------ ++3.5 Sample regular expressions *NERD_com-reg-exps* ++ ++Many of the options in the NERD commenter must be set to regular ++expressions... regular expressions can be a bit confusing so i have provided ++some template ones here that you can start from: ++ ++Regexp1: '.*' ++Matches any filetype. This is useful for turning an option on for all files. ++ ++Regexp2: '^$' ++Matches no filetypes. This is useful for turning an option off for all files. ++ ++Regexp3: '^\(java\)$' ++Matches only the java filetype. ++ ++Regexp4: '^\(c\|vim\)$' ++Matches only c and vim filetypes. ++ ++Regexp5: '^\(c.*\|vim\)$' ++Matches filetypes beginning with c (eg c, cpp, cs, etc) as well ++as vim files. ++ ++Regexp6: '^\(c.*\|java\|tex\)$' ++Matches filetypes beginning with c (eg c, cpp, cs, etc) as well as java and ++tex filetypes. ++ ++Regexp7: '^\(python\)\@!' ++Matches anything other than 'python'. ++ ++Regexp8: '^c\(s\)\@!' ++Matches 'c' followed by anything accept an 's'. ++ ++Regexp9: '^\(foo$\|bar$\|baz$\)\@!' ++Matches any strings except 'foo', 'bar' and 'baz'. ++ ++============================================================================== ++4. Issues with the script{{{2 *NERD_com-issues* ++ ++ ++------------------------------------------------------------------------------ ++4.1 Delimiter detection heuristics *NERD_com-heuristics* ++ ++Heuristics are used to distinguish the real comment delimiters ++ ++Because we have comment mappings that place delimiters in the middle of lines, ++removing comment delimiters is a bit tricky. This is because if comment ++delimiters appear in a line doesnt mean they really ARE delimiters. For ++example, Java uses // comments but the line > ++ System.out.println("//"); ++< ++clearly contains no real comment delimiters. ++ ++To distinguish between ``real'' comment delimiters and ``fake'' ones we use a ++set of heuristics. For example, one such heuristic states that any comment ++delimiter that has an odd number of non-escaped " characters both preceding ++and following it on the line is not a comment because it is probably part of a ++string. These heuristics, while usually pretty accurate, will not work for all ++cases. ++ ++------------------------------------------------------------------------------ ++4.2 Nesting issues *NERD_com-nesting* ++ ++If we have some line of code like this: > ++ /*int foo */ = /*5 + 9;*/ ++< ++This will not be uncommented legally. The NERD commenter will remove the ++"outter most" delimiters so the line will become: > ++ int foo */ = /*5 + 9; ++< ++which almost certainly will not be what you want. Nested sets of comments will ++uncomment fine though. Eg: > ++ /*int/* foo =*/ 5 + 9;*/ ++< ++will become: > ++ int/* foo =*/ 5 + 9; ++< ++(Note that in the above examples I have deliberately not used place holders ++for simplicity) ++ ++------------------------------------------------------------------------------ ++4.3 Mark clobbering *NERD_com-mark-clobbering* ++ ++The script clobbers the s and t marks when doing most comments. Im not sure ++how to save and restore the marks yet. ++ ++ ++ ++============================================================================== ++5. TODO list {{{2 *NERD_com-todo* ++ ++Uncommenting of minimal comments needs to be more robust. Currently it is easy ++to get illegal syntax when uncommenting them. ++ ++ ++ ++============================================================================== ++6. Credits {{{2 *NERD_com-credits* ++ ++Thanks and respect to the following people: ++ ++Thanks to Nick Brettell for his many ideas and criticisms. A bloody good ++bastard. ++:normal :.-2s/good// ++ ++Thanks to Matthew Hawkins for his awesome refactoring! ++ ++Thanks to the authors of the vimspell whose documentation ++installation function I stole :) ++ ++Thanks to Greg Searle for the idea of using place-holders for nested comments. ++ ++Thanks to Nguyen for the suggestions and pointing the h file highlighting bug! ++Also, thanks for the idea of doing sexy comments as well as his suggestions ++relating to it :P ++Thanks again to Nguyen for complaining about the NERD_comments menu mapping ++(-c) interfering with another mapping of his... and thus the ++NERD_dont_create_menu_shortcut option was born :P ++(it was then replaced with NERD_menu_mode in version 1.67 :) ++ ++Thanks to Sam R for pointing out some filetypes that NERD_comments could support! ++ ++Cheers to Litchi for the idea of having a mapping that appends a comment to ++the current line :) ++ ++Thanks to jorge scandaliaris and Shufeng Zheng for telling me about some ++problems with commenting in visual mode. Thanks again to Jorge for his ++continued suggestions on this matter :) ++ ++Thanks to Martin Stubenschrott for pointing out a bug with the mapping ++:) Ive gotta stop breaking this mapping! ++ ++Thanks to Markus Erlmann for pointing out a conflict that this script was ++having with the taglist plugin. ++ ++Thanks to Brent Rice for alerting me about, and helping me track down, a bug ++in the script when the "ignorecase" option in vim was set. ++ ++Thanks to Richard Willis for telling me about how line continuation was ++causing problems on cygwin. Also, thanks pointing out a bug in the help file ++and for suggesting // comments for c (its about time SOMEONE did :P). May ANSI ++have mercy on your soul :) ++ ++Thanks to Igor Prischepoff for suggesting that i implement "toggle comments". ++Also, thanks for his suggested improvements about toggle comments after i ++implemented them. ++ ++Thanks to harry for telling me that i broke the cn mapping in 1.53 :), ++and thanks again for telling me about a bug that occurred when editing a file ++in a new tab. ++ ++Thanks to Martin (Krischikim?) for his patch that fixed a bug with the doc ++install function and added support for ada comments with spaces as well as ++making a couple of other small changes. ++ ++Thanks to David Bourgeois for pointing out a bug with when commenting c files ++:)... [a few days later] ok i completely misunderstood what David was talking ++about and ended up fixing a completely different bug to what he was talking ++about :P ++ ++Thanks to David Bourgeois for pointing out a bug when changing buffers. ++ ++Cheers to Eike Von Seggern for sending me a patch to fix a bug in 1.60 that ++was causing spaces to be added to the end of lines with single-part ++delimiters. It's nice when people do my work for me :D ++ ++Thanks to Torsten Blix for telling me about a couple of bugs when uncommenting ++sexy comments. Sexy comments dont look so sexy when they are only half removed ++:P ++ ++Thanks to Alexander "boesi" Bosecke for pointing out a bug that was stopping ++the NERD_space_delim_filetype_regexp option from working with left aligned ++toggle comments. And for pointing out a bug when initialising VB comments. ++ ++Thanks to Stefano Zacchiroli for suggesting the idea of "Minimal comments". ++And for suggested improvements to minimal comments. ++ ++Thanks to Norick Chen for emailing in a patch that fixed the asp delimiters. ++In 1.65 ++ ++Thanks to Jonathan Derque for alerting me to some filetypes that could be ++supported (Namely: context, plaintext and mail). ++ ++Thanks to Joseph Barker for the sugesting that the menu be an optional ++feature. ++ ++Thanks to Gary Church and Tim Carey-Smith for complaining about the ++keymappings and causing me to introduce the NERD_mapleader option :) ++ ++ ++Cheers to myself for being the best looking man on Earth! ++ ++ ++ vim:tw=78:ts=8:ft=help:norl: +diff -urN vim71/runtime/ftplugin/ada.vim vim71_ada/runtime/ftplugin/ada.vim +--- vim71/runtime/ftplugin/ada.vim 2007-05-05 19:17:45.000000000 +0200 ++++ vim71_ada/runtime/ftplugin/ada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -1,14 +1,15 @@ + "------------------------------------------------------------------------------ + " Description: Perform Ada specific completion & tagging. + " Language: Ada (2005) +-" $Id: ada.vim,v 1.3 2007/05/05 17:17:45 vimboss Exp $ +-" Maintainer: Martin Krischik ++" $Id: ada.vim 774 2007-09-17 09:11:59Z krischik $ ++" Maintainer: Martin Krischik ++" Taylor Venable + " Neil Bird +-" $Author: vimboss $ +-" $Date: 2007/05/05 17:17:45 $ +-" Version: 4.2 +-" $Revision: 1.3 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ftplugin/ada.vim $ ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/ftplugin/ada.vim $ + " History: 24.05.2006 MK Unified Headers + " 26.05.2006 MK ' should not be in iskeyword. + " 16.07.2006 MK Ada-Mode as vim-ball +@@ -17,6 +18,7 @@ + " 05.11.2006 MK Bram suggested not to use include protection for + " autoload + " 05.11.2006 MK Bram suggested to save on spaces ++" 08.07.2007 TV fix default compiler problems. + " Help Page: ft-ada-plugin + "------------------------------------------------------------------------------ + " Provides mapping overrides for tag jumping that figure out the current +@@ -30,7 +32,7 @@ + endif + + " Don't load another plugin for this buffer +-let b:did_ftplugin = 38 ++let b:did_ftplugin = 45 + + " + " Temporarily set cpoptions to ensure the script loads OK +@@ -104,8 +106,17 @@ + \ s:notend . '\:\\s\+\' + endif + ++ + " Section: Compiler {{{1 + " ++if ! exists("g:ada_default_compiler") ++ if has("vms") ++ let g:ada_default_compiler = 'decada' ++ else ++ let g:ada_default_compiler = 'gnat' ++ endif ++endif ++ + if ! exists("current_compiler") || + \ current_compiler != g:ada_default_compiler + execute "compiler " . g:ada_default_compiler +diff -urN vim71/runtime/indent/ada.vim vim71_ada/runtime/indent/ada.vim +--- vim71/runtime/indent/ada.vim 2007-05-05 19:25:37.000000000 +0200 ++++ vim71_ada/runtime/indent/ada.vim 2008-01-16 16:37:02.000000000 +0100 +@@ -1,19 +1,21 @@ + "------------------------------------------------------------------------------ + " Description: Vim Ada indent file + " Language: Ada (2005) +-" $Id: ada.vim,v 1.4 2007/05/05 17:25:37 vimboss Exp $ ++" $Id: ada.vim 774 2007-09-17 09:11:59Z krischik $ + " Copyright: Copyright (C) 2006 Martin Krischik +-" Maintainer: Martin Krischik ++" Maintainer: Martin Krischik + " Neil Bird +-" $Author: vimboss $ +-" $Date: 2007/05/05 17:25:37 $ +-" Version: 4.2 +-" $Revision: 1.4 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/indent/ada.vim $ ++" Ned Okie ++" $Author: krischik $ ++" $Date: 2007-09-17 11:11:59 +0200 (Mo, 17 Sep 2007) $ ++" Version: 4.5 ++" $Revision: 774 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/indent/ada.vim $ + " History: 24.05.2006 MK Unified Headers + " 16.07.2006 MK Ada-Mode as vim-ball + " 15.10.2006 MK Bram's suggestion for runtime integration + " 05.11.2006 MK Bram suggested to save on spaces ++" 19.09.2007 NO g: missing before ada#Comment + " Help Page: ft-vim-indent + "------------------------------------------------------------------------------ + " ToDo: +@@ -27,7 +29,7 @@ + finish + endif + +-let b:did_indent = 1 ++let b:did_indent = 45 + + setlocal indentexpr=GetAdaIndent() + setlocal indentkeys-=0{,0} +@@ -58,7 +60,7 @@ + " Seems to work OK as it 'starts' with the indent of the /previous/ line. + function s:MainBlockIndent (prev_indent, prev_lnum, blockstart, stop_at) + let lnum = a:prev_lnum +- let line = substitute( getline(lnum), ada#Comment, '', '' ) ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) + while lnum > 1 + if a:stop_at != '' && line =~ '^\s*' . a:stop_at && indent(lnum) < a:prev_indent + return a:prev_indent +@@ -72,7 +74,7 @@ + let lnum = prevnonblank(lnum - 1) + " Get previous non-blank/non-comment-only line + while 1 +- let line = substitute( getline(lnum), ada#Comment, '', '' ) ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) + if line !~ '^\s*$' && line !~ '^\s*#' + break + endif +@@ -116,7 +118,7 @@ + " Get previous non-blank/non-comment-only line + while 1 + let line = getline(lnum) +- let line = substitute( line, ada#Comment, '', '' ) ++ let line = substitute( line, g:ada#Comment, '', '' ) + if line !~ '^\s*$' + break + endif +@@ -143,7 +145,8 @@ + let lnum = prevnonblank(lnum - 1) + " Get previous non-blank/non-comment-only line + while 1 +- let line = substitute( getline(lnum), ada#Comment, '', '' ) ++ let line = substitute( getline(lnum), g:ada#Comment, '', '' ) ++ + if line !~ '^\s*$' && line !~ '^\s*#' + break + endif +@@ -222,7 +225,7 @@ + exe lnum + exe 'normal! $F)%' + if getline('.') =~ '^\s*(' +- " Dire layout - use previous indent (could check for ada#Comment here) ++ " Dire layout - use previous indent (could check for g:ada#Comment here) + let ind = indent( prevnonblank( line('.')-1 ) ) + else + let ind = indent('.') +diff -urN vim71/runtime/macros/svnignore.bash vim71_ada/runtime/macros/svnignore.bash +--- vim71/runtime/macros/svnignore.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/macros/svnignore.bash 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,9 @@ ++#!/bin/bash ++ ++svn propedit \ ++ --editor-cmd="gvim -f" \ ++ svn:ignore \ ++ "${@}" ; ++ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/runtime/macros/svnignore.btm vim71_ada/runtime/macros/svnignore.btm +--- vim71/runtime/macros/svnignore.btm 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/macros/svnignore.btm 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,27 @@ ++::!C:\Bin\4Portable\App\4\4nt.EXE ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: Description: Works like "tail -f" . ++:: $Id: svnignore.btm 806 2007-11-21 09:35:26Z krischik $ ++:: Maintainer: Martin Krischik ++:: Jason Heddings (vim at heddway dot com) ++:: $Author: krischik $ ++:: $Date: 2007-11-21 10:35:26 +0100 (Mi, 21 Nov 2007) $ ++:: Version: 3.0 ++:: $Revision: 806 $ ++:: $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/macros/svnignore.btm $ ++:: History: 17.11.2007 Edit svn:ignore data ++:: Help Page: tail.txt ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++ ++svn propedit ^ ++ --editor-cmd="gvim -f" ^ ++ svn:ignore ^ ++ "%[$]" ++ ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: Copyright (C) 2006 Martin Krischik ++:: ++:: Vim is Charityware - see ":help license" or uganda.txt for licence details. ++:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ++:: vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++:: vim: filetype=btm encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/runtime/macros/svnignore.zsh vim71_ada/runtime/macros/svnignore.zsh +--- vim71/runtime/macros/svnignore.zsh 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/macros/svnignore.zsh 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,29 @@ ++#!/bin/zsh ++#------------------------------------------------------------------------------ ++# Description: Works like "tail -f" . ++# $Id: svnignore.zsh 818 2007-12-03 21:21:48Z krischik $ ++# Maintainer: Martin Krischik ++# Jason Heddings (vim at heddway dot com) ++# $Author: krischik $ ++# $Date: 2007-12-03 22:21:48 +0100 (Mo, 03 Dez 2007) $ ++# Version: 3.0 ++# $Revision: 818 $ ++# $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/macros/svnignore.zsh $ ++# History: 17.11.2007 Edit svn:ignore data ++# Help Page: tail.txt ++#------------------------------------------------------------------------------ ++ ++setopt No_X_Trace; ++ ++svn propedit \ ++ --editor-cmd="gvim -f" \ ++ svn:ignore \ ++ "${=@}" ; ++ ++#------------------------------------------------------------------------------ ++# Copyright (C) 2006 Martin Krischik ++# ++# Vim is Charityware - see ":help license" or uganda.txt for licence details. ++#------------------------------------------------------------------------------ ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/runtime/macros/vim.bash vim71_ada/runtime/macros/vim.bash +--- vim71/runtime/macros/vim.bash 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/macros/vim.bash 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,191 @@ ++#!/bin/echo usage: source ++########################################################### {{{1 ########### ++# Description: Set alias names for a custom installed vim/ctags. ++# Language: Bash Shell Script ++# $Id: vim.bash 820 2007-12-08 11:05:30Z krischik $ ++# Maintainer: Martin Krischik ++# $Author: krischik $ ++# $Date: 2007-12-08 12:05:30 +0100 (Sa, 08 Dez 2007) $ ++# Version: 3.6 ++# $Revision: 820 $ ++# $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/macros/vim.bash $ ++# History: 26.07.2006 MK pretty new ++# Usage: copy to /etc/profile.d and make world executable ++########################################################### }}}1 ########### ++ ++ ++if ! type lxpm 2>/dev/null 1>/dev/null; then ++ ++ # Variablen ++ UName=$(uname) ++ ++ case "${UName}" in # {{{1 ++ (Linux*) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71"; ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}2 ++ (CYGWIN*) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71" ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}2 ++ (SunOS) # {{{2 ++ if test -x "/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71"; ++ elif test -x "${HOME}/opt/gnat/tools/bin/vim"; then ++ declare -x VIM="${HOME}/opt/gnat/tools"; ++ declare -x VIMRUNTIME="${VIM}/share/vim/vim71" ++ PATH="${VIM}/bin:${PATH}" ++ else ++ unset VIM 1>/dev/null 2>/dev/null; ++ unset VIMRUNTIME 1>/dev/null 2>/dev/null; ++ fi ++ ;; # }}}2 ++ (*) # {{{2 ++ ;; # }}}2 ++ esac; # }}}1 ++ ++ # Simple Functions ++ ++ for i in ctags etags eview evim ex gview gvim gvimdiff rgview rgvim rview rvim view vim vimdiff vimtutor xxd; do # {{{1 ++ ++ case "${UName}" in # {{{2 ++ (MINGW*) # {{{3 ++ if test -n "${VIM}"; then ++ declare -x -f ${i}; ++ ++ eval "function ${i} () ++ { ++ ${VIM}/vim71/gvim.exe \"\${@}\" ++ return; ++ }" ++ else ++ unset -f ${i} 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}3 ++ (Linux|CYGWIN*) # {{{3 ++ if test -n "${VIM}"; then ++ declare -x -f ${i}; ++ ++ eval "function ${i} () ++ { ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/${i}\" \"\${@}\" ; ++ return; ++ }" ++ else ++ unset -f ${i} 1>/dev/null 2>/dev/null; ++ fi; ++ ;; # }}}3 ++ (*) # {{{3 ++ ;; # }}}3 ++ esac; # }}}2 ++ done; # }}}1 ++ ++ # Server Functions ++ ++ for i in lxpm med epm; do # {{{1 ++ declare -x -f ${i} ++ ++ case "${UName}" in # {{{2 ++ (MINGW*) # {{{3 ++ if test -n "${VIM}"; then ++ eval "function ${i} () ++ { ++ if test -z "\${1}"; then ++ ${VIM}/vim71/gvim.exe --servername ${i} 1>/dev/null 2>/dev/null & ++ else ++ ${VIM}/vim71/gvim.exe --servername ${i} --remote-silent \"\${@}\" 1>/dev/null 2>/dev/null & ++ fi; ++ return; ++ }" ++ else ++ eval "function ${i} () ++ { ++ if test -z "\${1}"; then ++ gvim.exe --servername ${i} 1>/dev/null 2>/dev/null & ++ else ++ gvim.exe --servername ${i} --remote-silent \"\${@}\" 1>/dev/null 2>/dev/null & ++ fi; ++ return; ++ }" ++ fi; ++ ;; # }}}3 ++ (Linux|CYGWIN*|SunOS) # {{{3 ++ if test -n "${VIM}"; then ++ eval "function ${i} () ++ { ++ if test -z \"\${1}\"; then ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/gvim\" --servername \"${i} ${HOSTNAME}\" \"\${@}\" \ ++ >/dev/null 2>/dev/null & ++ else ++ LD_LIBRARY_PATH=\"\${LD_LIBRARY_PATH}:${VIM}/lib\" \ ++ \"${VIM}/bin/gvim\" --servername \"${i} ${HOSTNAME}\" --remote-silent \"\${@}\" \ ++ >/dev/null 2>/dev/null & ++ fi ++ return; ++ }" ++ else ++ eval "function ${i} () ++ { ++ if test -z \"\${1}\"; then ++ gvim --servername \"${i} ${HOSTNAME}\" >/dev/null 2>/dev/null & ++ else ++ gvim --servername \"${i} ${HOSTNAME}\" --remote-silent \"\${@}\" >/dev/null 2>/dev/null & ++ fi ++ return; ++ }" ++ fi; ++ ;; # }}}3 ++ (*) # {{{3 ++ ;; # }}}3 ++ esac; # }}}2 ++ done; # }}}1 ++ ++ # Some applications read the EDITOR variable to determine your favourite text ++ # editor. So uncomment the line below and enter the editor of your choice :-) ++ if test -n "${VIM}"; then ++ declare -x EDITOR="${VIM}/bin/gvim -f"; ++ declare -x VISUAL="${VIM}/bin/gvim -f"; ++ else ++ declare -x EDITOR="$(which gvim) -f"; ++ declare -x VISUAL="$(which gvim) -f"; ++ fi; ++ # Unset local Variablen ++ ++ unset UName ++ ++ printf "\e[42m%-30.30s : \e[43m %-40.40s \e[m\n" "$(basename ${BASH_SOURCE:-${0}})" "VIM 7.0 symbols set." ++ ++fi; ++ ++########################################################### {{{1 ########### ++# Copyright (C) 2006 Martin Krischik ++# ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; either version 2 ++# of the License, or (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++########################################################### }}}1 ########### ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab ++# vim: filetype=sh encoding=utf-8 fileformat=unix foldmethod=marker +diff -urN vim71/runtime/macros/vim.zsh vim71_ada/runtime/macros/vim.zsh +--- vim71/runtime/macros/vim.zsh 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/macros/vim.zsh 2008-01-16 16:37:02.000000000 +0100 +@@ -0,0 +1,17 @@ ++#!/bin/echo usage: source ++ ++setopt No_Verbose ++setopt No_X_Trace ++setopt Typeset_Silent; ++ ++# ++# Bash script is zsh compatible ++# ++HOSTNAME="${HOSTNAME:-${HOST}}" ++BASH_SOURCE="$(basename ${0} .zsh).bash" ++source "$(dirname ${0})/${BASH_SOURCE}" ++unset BASH_SOURCE; ++ ++############################################################# {{{1 ########### ++# vim: textwidth=0 nowrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab ++# vim: filetype=zsh encoding=utf-8 fileformat=unix foldmethod=marker nospell +diff -urN vim71/runtime/plugin/matchit.vim vim71_ada/runtime/plugin/matchit.vim +--- vim71/runtime/plugin/matchit.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/plugin/matchit.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,814 @@ ++" matchit.vim: (global plugin) Extended "%" matching ++" Last Change: Tue Oct 24 11:00 AM 2006 EDT ++" Maintainer: Benji Fisher PhD ++" Version: 1.12, for Vim 6.3+ ++" URL: http://www.vim.org/script.php?script_id=39 ++ ++" Documentation: ++" The documentation is in a separate file, matchit.txt . ++ ++" Credits: ++" Vim editor by Bram Moolenaar (Thanks, Bram!) ++" Original script and design by Raul Segura Acevedo ++" Support for comments by Douglas Potts ++" Support for back references and other improvements by Benji Fisher ++" Support for many languages by Johannes Zellner ++" Suggestions for improvement, bug reports, and support for additional ++" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark ++" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner. ++ ++" Debugging: ++" If you'd like to try the built-in debugging commands... ++" :MatchDebug to activate debugging for the current buffer ++" This saves the values of several key script variables as buffer-local ++" variables. See the MatchDebug() function, below, for details. ++ ++" TODO: I should think about multi-line patterns for b:match_words. ++" This would require an option: how many lines to scan (default 1). ++" This would be useful for Python, maybe also for *ML. ++" TODO: Maybe I should add a menu so that people will actually use some of ++" the features that I have implemented. ++" TODO: Eliminate the MultiMatch function. Add yet another argument to ++" Match_wrapper() instead. ++" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' ++" TODO: Make backrefs safer by using '\V' (very no-magic). ++" TODO: Add a level of indirection, so that custom % scripts can use my ++" work but extend it. ++ ++" allow user to prevent loading ++" and prevent duplicate loading ++if exists("loaded_matchit") || &cp ++ finish ++endif ++let loaded_matchit = 1 ++let s:last_mps = "" ++let s:last_words = "" ++ ++let s:save_cpo = &cpo ++set cpo&vim ++ ++nnoremap % :call Match_wrapper('',1,'n') ++nnoremap g% :call Match_wrapper('',0,'n') ++vnoremap % :call Match_wrapper('',1,'v') m'gv`` ++vnoremap g% :call Match_wrapper('',0,'v') m'gv`` ++onoremap % v:call Match_wrapper('',1,'o') ++onoremap g% v:call Match_wrapper('',0,'o') ++ ++" Analogues of [{ and ]} using matching patterns: ++nnoremap [% :call MultiMatch("bW", "n") ++nnoremap ]% :call MultiMatch("W", "n") ++vmap [% [%m'gv`` ++vmap ]% ]%m'gv`` ++" vnoremap [% :call MultiMatch("bW", "v") m'gv`` ++" vnoremap ]% :call MultiMatch("W", "v") m'gv`` ++onoremap [% v:call MultiMatch("bW", "o") ++onoremap ]% v:call MultiMatch("W", "o") ++ ++" text object: ++vmap a% [%v]% ++ ++" Auto-complete mappings: (not yet "ready for prime time") ++" TODO Read :help write-plugin for the "right" way to let the user ++" specify a key binding. ++" let g:match_auto = '' ++" let g:match_autoCR = '' ++" if exists("g:match_auto") ++" execute "inoremap " . g:match_auto . ' x"=Autocomplete()Pls' ++" endif ++" if exists("g:match_autoCR") ++" execute "inoremap " . g:match_autoCR . ' =Autocomplete()' ++" endif ++" if exists("g:match_gthhoh") ++" execute "inoremap " . g:match_gthhoh . ' :call Gthhoh()' ++" endif " gthhoh = "Get the heck out of here!" ++ ++let s:notslash = '\\\@" ++ endif ++ " In s:CleanUp(), we may need to check whether the cursor moved forward. ++ let startline = line(".") ++ let startcol = col(".") ++ " Use default behavior if called with a count or if no patterns are defined. ++ if v:count ++ exe "normal! " . v:count . "%" ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ elseif !exists("b:match_words") || b:match_words == "" ++ silent! normal! % ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ end ++ ++ " First step: if not already done, set the script variables ++ " s:do_BR flag for whether there are backrefs ++ " s:pat parsed version of b:match_words ++ " s:all regexp based on s:pat and the default groups ++ " ++ " Allow b:match_words = "GetVimMatchWords()" . ++ if b:match_words =~ ":" ++ let match_words = b:match_words ++ else ++ execute "let match_words =" b:match_words ++ endif ++" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion! ++ if (match_words != s:last_words) || (&mps != s:last_mps) || ++ \ exists("b:match_debug") ++ let s:last_words = match_words ++ let s:last_mps = &mps ++ if match_words !~ s:notslash . '\\\d' ++ let s:do_BR = 0 ++ let s:pat = match_words ++ else ++ let s:do_BR = 1 ++ let s:pat = s:ParseWords(match_words) ++ endif ++ " The next several lines were here before ++ " BF started messing with this script. ++ " quote the special chars in 'matchpairs', replace [,:] with \| and then ++ " append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif) ++ " let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+', ++ " \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>' ++ let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . ++ \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' ++ " s:all = pattern with all the keywords ++ let s:all = s:pat . (strlen(s:pat) ? "," : "") . default ++ let s:all = substitute(s:all, s:notslash . '\zs[,:]\+', '\\|', 'g') ++ let s:all = '\%(' . s:all . '\)' ++ " let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)' ++ if exists("b:match_debug") ++ let b:match_pat = s:pat ++ endif ++ endif ++ ++ " Second step: set the following local variables: ++ " matchline = line on which the cursor started ++ " curcol = number of characters before match ++ " prefix = regexp for start of line to start of match ++ " suffix = regexp for end of match to end of line ++ " Require match to end on or after the cursor and prefer it to ++ " start on or before the cursor. ++ let matchline = getline(startline) ++ if a:word != '' ++ " word given ++ if a:word !~ s:all ++ echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ endif ++ let matchline = a:word ++ let curcol = 0 ++ let prefix = '^\%(' ++ let suffix = '\)$' ++ " Now the case when "word" is not given ++ else " Find the match that ends on or after the cursor and set curcol. ++ let regexp = s:Wholematch(matchline, s:all, startcol-1) ++ let curcol = match(matchline, regexp) ++ let endcol = matchend(matchline, regexp) ++ let suf = strlen(matchline) - endcol ++ let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(') ++ let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$') ++ " If the match comes from the defaults, bail out. ++ if matchline !~ prefix . ++ \ substitute(s:pat, s:notslash.'\zs[,:]\+', '\\|', 'g') . suffix ++ silent! norm! % ++ return s:CleanUp(restore_options, a:mode, startline, startcol) ++ endif ++ endif ++ if exists("b:match_debug") ++ let b:match_match = matchstr(matchline, regexp) ++ let b:match_col = curcol+1 ++ endif ++ ++ " Third step: Find the group and single word that match, and the original ++ " (backref) versions of these. Then, resolve the backrefs. ++ " Set the following local variable: ++ " group = colon-separated list of patterns, one of which matches ++ " = ini:mid:fin or ini:fin ++ " ++ " Reconstruct the version with unresolved backrefs. ++ let patBR = substitute(match_words.',', ++ \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g') ++ let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g') ++ " Now, set group and groupBR to the matching group: 'if:endif' or ++ " 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns ++ " group . "," . groupBR, and we pick it apart. ++ let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) ++ let i = matchend(group, s:notslash . ",") ++ let groupBR = strpart(group, i) ++ let group = strpart(group, 0, i-1) ++ " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix ++ if s:do_BR " Do the hard part: resolve those backrefs! ++ let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++ endif ++ if exists("b:match_debug") ++ let b:match_wholeBR = groupBR ++ let i = matchend(groupBR, s:notslash . ":") ++ let b:match_iniBR = strpart(groupBR, 0, i-1) ++ endif ++ ++ " Fourth step: Set the arguments for searchpair(). ++ let i = matchend(group, s:notslash . ":") ++ let j = matchend(group, '.*' . s:notslash . ":") ++ let ini = strpart(group, 0, i-1) ++ let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g') ++ let fin = strpart(group, j) ++ "Un-escape the remaining , and : characters. ++ let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') ++ " searchpair() requires that these patterns avoid \(\) groups. ++ let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g') ++ let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g') ++ let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g') ++ " Set mid. This is optimized for readability, not micro-efficiency! ++ if a:forward && matchline =~ prefix . fin . suffix ++ \ || !a:forward && matchline =~ prefix . ini . suffix ++ let mid = "" ++ endif ++ " Set flag. This is optimized for readability, not micro-efficiency! ++ if a:forward && matchline =~ prefix . fin . suffix ++ \ || !a:forward && matchline !~ prefix . ini . suffix ++ let flag = "bW" ++ else ++ let flag = "W" ++ endif ++ " Set skip. ++ if exists("b:match_skip") ++ let skip = b:match_skip ++ elseif exists("b:match_comment") " backwards compatibility and testing! ++ let skip = "r:" . b:match_comment ++ else ++ let skip = 's:comment\|string' ++ endif ++ let skip = s:ParseSkip(skip) ++ if exists("b:match_debug") ++ let b:match_ini = ini ++ let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin ++ endif ++ ++ " Fifth step: actually start moving the cursor and call searchpair(). ++ " Later, :execute restore_cursor to get to the original screen. ++ let restore_cursor = virtcol(".") . "|" ++ normal! g0 ++ let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor ++ normal! H ++ let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ execute restore_cursor ++ call cursor(0, curcol + 1) ++ " normal! 0 ++ " if curcol ++ " execute "normal!" . curcol . "l" ++ " endif ++ if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) ++ let skip = "0" ++ else ++ execute "if " . skip . "| let skip = '0' | endif" ++ endif ++ let sp_return = searchpair(ini, mid, fin, flag, skip) ++ let final_position = "call cursor(" . line(".") . "," . col(".") . ")" ++ " Restore cursor position and original screen. ++ execute restore_cursor ++ normal! m' ++ if sp_return > 0 ++ execute final_position ++ endif ++ return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin) ++endfun ++ ++" Restore options and do some special handling for Operator-pending mode. ++" The optional argument is the tail of the matching group. ++fun! s:CleanUp(options, mode, startline, startcol, ...) ++ execute "set" a:options ++ " Open folds, if appropriate. ++ if a:mode != "o" ++ if &foldopen =~ "percent" ++ normal! zv ++ endif ++ " In Operator-pending mode, we want to include the whole match ++ " (for example, d%). ++ " This is only a problem if we end up moving in the forward direction. ++ elseif (a:startline < line(".")) || ++ \ (a:startline == line(".") && a:startcol < col(".")) ++ if a:0 ++ " Check whether the match is a single character. If not, move to the ++ " end of the match. ++ let matchline = getline(".") ++ let currcol = col(".") ++ let regexp = s:Wholematch(matchline, a:1, currcol-1) ++ let endcol = matchend(matchline, regexp) ++ if endcol > currcol " This is NOT off by one! ++ execute "normal!" . (endcol - currcol) . "l" ++ endif ++ endif " a:0 ++ endif " a:mode != "o" && etc. ++ return 0 ++endfun ++ ++" Example (simplified HTML patterns): if ++" a:groupBR = '<\(\k\+\)>:' ++" a:prefix = '^.\{3}\(' ++" a:group = '<\(\k\+\)>:' ++" a:suffix = '\).\{2}$' ++" a:matchline = "12312" or "12312" ++" then extract "tag" from a:matchline and return ":" . ++fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++ if a:matchline !~ a:prefix . ++ \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix ++ return a:group ++ endif ++ let i = matchend(a:groupBR, s:notslash . ':') ++ let ini = strpart(a:groupBR, 0, i-1) ++ let tailBR = strpart(a:groupBR, i) ++ let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix, ++ \ a:groupBR) ++ let i = matchend(word, s:notslash . ":") ++ let wordBR = strpart(word, i) ++ let word = strpart(word, 0, i-1) ++ " Now, a:matchline =~ a:prefix . word . a:suffix ++ if wordBR != ini ++ let table = s:Resolve(ini, wordBR, "table") ++ else ++ " let table = "----------" ++ let table = "" ++ let d = 0 ++ while d < 10 ++ if tailBR =~ s:notslash . '\\' . d ++ " let table[d] = d ++ let table = table . d ++ else ++ let table = table . "-" ++ endif ++ let d = d + 1 ++ endwhile ++ endif ++ let d = 9 ++ while d ++ if table[d] != "-" ++ let backref = substitute(a:matchline, a:prefix.word.a:suffix, ++ \ '\'.table[d], "") ++ " Are there any other characters that should be escaped? ++ let backref = escape(backref, '*,:') ++ execute s:Ref(ini, d, "start", "len") ++ let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len) ++ let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d, ++ \ escape(backref, '\\'), 'g') ++ endif ++ let d = d-1 ++ endwhile ++ if exists("b:match_debug") ++ if s:do_BR ++ let b:match_table = table ++ let b:match_word = word ++ else ++ let b:match_table = "" ++ let b:match_word = "" ++ endif ++ endif ++ return ini . ":" . tailBR ++endfun ++ ++" Input a comma-separated list of groups with backrefs, such as ++" a:groups = '\(foo\):end\1,\(bar\):end\1' ++" and return a comma-separated list of groups with backrefs replaced: ++" return '\(foo\):end\(foo\),\(bar\):end\(bar\)' ++fun! s:ParseWords(groups) ++ let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g') ++ let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g') ++ let parsed = "" ++ while groups =~ '[^,:]' ++ let i = matchend(groups, s:notslash . ':') ++ let j = matchend(groups, s:notslash . ',') ++ let ini = strpart(groups, 0, i-1) ++ let tail = strpart(groups, i, j-i-1) . ":" ++ let groups = strpart(groups, j) ++ let parsed = parsed . ini ++ let i = matchend(tail, s:notslash . ':') ++ while i != -1 ++ " In 'if:else:endif', ini='if' and word='else' and then word='endif'. ++ let word = strpart(tail, 0, i-1) ++ let tail = strpart(tail, i) ++ let i = matchend(tail, s:notslash . ':') ++ let parsed = parsed . ":" . s:Resolve(ini, word, "word") ++ endwhile " Now, tail has been used up. ++ let parsed = parsed . "," ++ endwhile " groups =~ '[^,:]' ++ return parsed ++endfun ++ ++" TODO I think this can be simplified and/or made more efficient. ++" TODO What should I do if a:start is out of range? ++" Return a regexp that matches all of a:string, such that ++" matchstr(a:string, regexp) represents the match for a:pat that starts ++" as close to a:start as possible, before being preferred to after, and ++" ends after a:start . ++" Usage: ++" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1) ++" let i = match(getline("."), regexp) ++" let j = matchend(getline("."), regexp) ++" let match = matchstr(getline("."), regexp) ++fun! s:Wholematch(string, pat, start) ++ let group = '\%(' . a:pat . '\)' ++ let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^') ++ let len = strlen(a:string) ++ let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$') ++ if a:string !~ prefix . group . suffix ++ let prefix = '' ++ endif ++ return prefix . group . suffix ++endfun ++ ++" No extra arguments: s:Ref(string, d) will ++" find the d'th occurrence of '\(' and return it, along with everything up ++" to and including the matching '\)'. ++" One argument: s:Ref(string, d, "start") returns the index of the start ++" of the d'th '\(' and any other argument returns the length of the group. ++" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be ++" executed, having the effect of ++" :let foo = s:Ref(string, d, "start") ++" :let bar = s:Ref(string, d, "len") ++fun! s:Ref(string, d, ...) ++ let len = strlen(a:string) ++ if a:d == 0 ++ let start = 0 ++ else ++ let cnt = a:d ++ let match = a:string ++ while cnt ++ let cnt = cnt - 1 ++ let index = matchend(match, s:notslash . '\\(') ++ if index == -1 ++ return "" ++ endif ++ let match = strpart(match, index) ++ endwhile ++ let start = len - strlen(match) ++ if a:0 == 1 && a:1 == "start" ++ return start - 2 ++ endif ++ let cnt = 1 ++ while cnt ++ let index = matchend(match, s:notslash . '\\(\|\\)') - 1 ++ if index == -2 ++ return "" ++ endif ++ " Increment if an open, decrement if a ')': ++ let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')' ++ " let cnt = stridx('0(', match[index]) + cnt ++ let match = strpart(match, index+1) ++ endwhile ++ let start = start - 2 ++ let len = len - start - strlen(match) ++ endif ++ if a:0 == 1 ++ return len ++ elseif a:0 == 2 ++ return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len ++ else ++ return strpart(a:string, start, len) ++ endif ++endfun ++ ++" Count the number of disjoint copies of pattern in string. ++" If the pattern is a literal string and contains no '0' or '1' characters ++" then s:Count(string, pattern, '0', '1') should be faster than ++" s:Count(string, pattern). ++fun! s:Count(string, pattern, ...) ++ let pat = escape(a:pattern, '\\') ++ if a:0 > 1 ++ let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g") ++ let foo = substitute(a:string, pat, a:2, "g") ++ let foo = substitute(foo, '[^' . a:2 . ']', "", "g") ++ return strlen(foo) ++ endif ++ let result = 0 ++ let foo = a:string ++ let index = matchend(foo, pat) ++ while index != -1 ++ let result = result + 1 ++ let foo = strpart(foo, index) ++ let index = matchend(foo, pat) ++ endwhile ++ return result ++endfun ++ ++" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where ++" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first ++" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this ++" indicates that all other instances of '\1' in target are to be replaced ++" by '\3'. The hard part is dealing with nesting... ++" Note that ":" is an illegal character for source and target, ++" unless it is preceded by "\". ++fun! s:Resolve(source, target, output) ++ let word = a:target ++ let i = matchend(word, s:notslash . '\\\d') - 1 ++ let table = "----------" ++ while i != -2 " There are back references to be replaced. ++ let d = word[i] ++ let backref = s:Ref(a:source, d) ++ " The idea is to replace '\d' with backref. Before we do this, ++ " replace any \(\) groups in backref with :1, :2, ... if they ++ " correspond to the first, second, ... group already inserted ++ " into backref. Later, replace :1 with \1 and so on. The group ++ " number w+b within backref corresponds to the group number ++ " s within a:source. ++ " w = number of '\(' in word before the current one ++ let w = s:Count( ++ \ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1') ++ let b = 1 " number of the current '\(' in backref ++ let s = d " number of the current '\(' in a:source ++ while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1') ++ \ && s < 10 ++ if table[s] == "-" ++ if w + b < 10 ++ " let table[s] = w + b ++ let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1) ++ endif ++ let b = b + 1 ++ let s = s + 1 ++ else ++ execute s:Ref(backref, b, "start", "len") ++ let ref = strpart(backref, start, len) ++ let backref = strpart(backref, 0, start) . ":". table[s] ++ \ . strpart(backref, start+len) ++ let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1') ++ endif ++ endwhile ++ let word = strpart(word, 0, i-1) . backref . strpart(word, i+1) ++ let i = matchend(word, s:notslash . '\\\d') - 1 ++ endwhile ++ let word = substitute(word, s:notslash . '\zs:', '\\', 'g') ++ if a:output == "table" ++ return table ++ elseif a:output == "word" ++ return word ++ else ++ return table . word ++ endif ++endfun ++ ++" Assume a:comma = ",". Then the format for a:patterns and a:1 is ++" a:patterns = ",,..." ++" a:1 = ",,..." ++" If is the first pattern that matches a:string then return ++" if no optional arguments are given; return , if a:1 is given. ++fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...) ++ let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma) ++ let i = matchend(tail, s:notslash . a:comma) ++ if a:0 ++ let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma) ++ let j = matchend(alttail, s:notslash . a:comma) ++ endif ++ let current = strpart(tail, 0, i-1) ++ if a:branch == "" ++ let currpat = current ++ else ++ let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') ++ endif ++ while a:string !~ a:prefix . currpat . a:suffix ++ let tail = strpart(tail, i) ++ let i = matchend(tail, s:notslash . a:comma) ++ if i == -1 ++ return -1 ++ endif ++ let current = strpart(tail, 0, i-1) ++ if a:branch == "" ++ let currpat = current ++ else ++ let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') ++ endif ++ if a:0 ++ let alttail = strpart(alttail, j) ++ let j = matchend(alttail, s:notslash . a:comma) ++ endif ++ endwhile ++ if a:0 ++ let current = current . a:comma . strpart(alttail, 0, j-1) ++ endif ++ return current ++endfun ++ ++" Call this function to turn on debugging information. Every time the main ++" script is run, buffer variables will be saved. These can be used directly ++" or viewed using the menu items below. ++if !exists(":MatchDebug") ++ command! -nargs=0 MatchDebug call s:Match_debug() ++endif ++ ++fun! s:Match_debug() ++ let b:match_debug = 1 " Save debugging information. ++ " pat = all of b:match_words with backrefs parsed ++ amenu &Matchit.&pat :echo b:match_pat ++ " match = bit of text that is recognized as a match ++ amenu &Matchit.&match :echo b:match_match ++ " curcol = cursor column of the start of the matching text ++ amenu &Matchit.&curcol :echo b:match_col ++ " wholeBR = matching group, original version ++ amenu &Matchit.wh&oleBR :echo b:match_wholeBR ++ " iniBR = 'if' piece, original version ++ amenu &Matchit.ini&BR :echo b:match_iniBR ++ " ini = 'if' piece, with all backrefs resolved from match ++ amenu &Matchit.&ini :echo b:match_ini ++ " tail = 'else\|endif' piece, with all backrefs resolved from match ++ amenu &Matchit.&tail :echo b:match_tail ++ " fin = 'endif' piece, with all backrefs resolved from match ++ amenu &Matchit.&word :echo b:match_word ++ " '\'.d in ini refers to the same thing as '\'.table[d] in word. ++ amenu &Matchit.t&able :echo '0:' . b:match_table . ':9' ++endfun ++ ++" Jump to the nearest unmatched "(" or "if" or "" if a:spflag == "bW" ++" or the nearest unmatched "" or "endif" or ")" if a:spflag == "W". ++" Return a "mark" for the original position, so that ++" let m = MultiMatch("bW", "n") ... execute m ++" will return to the original position. If there is a problem, do not ++" move the cursor and return "", unless a count is given, in which case ++" go up or down as many levels as possible and again return "". ++" TODO This relies on the same patterns as % matching. It might be a good ++" idea to give it its own matching patterns. ++fun! s:MultiMatch(spflag, mode) ++ if !exists("b:match_words") || b:match_words == "" ++ return "" ++ end ++ let restore_options = (&ic ? "" : "no") . "ignorecase" ++ if exists("b:match_ignorecase") ++ let &ignorecase = b:match_ignorecase ++ endif ++ let startline = line(".") ++ let startcol = col(".") ++ ++ " First step: if not already done, set the script variables ++ " s:do_BR flag for whether there are backrefs ++ " s:pat parsed version of b:match_words ++ " s:all regexp based on s:pat and the default groups ++ " This part is copied and slightly modified from s:Match_wrapper(). ++ let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . ++ \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' ++ " Allow b:match_words = "GetVimMatchWords()" . ++ if b:match_words =~ ":" ++ let match_words = b:match_words ++ else ++ execute "let match_words =" b:match_words ++ endif ++ if (match_words != s:last_words) || (&mps != s:last_mps) || ++ \ exists("b:match_debug") ++ let s:last_words = match_words ++ let s:last_mps = &mps ++ if match_words !~ s:notslash . '\\\d' ++ let s:do_BR = 0 ++ let s:pat = match_words ++ else ++ let s:do_BR = 1 ++ let s:pat = s:ParseWords(match_words) ++ endif ++ let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default, ++ \ '[,:]\+','\\|','g') . '\)' ++ if exists("b:match_debug") ++ let b:match_pat = s:pat ++ endif ++ endif ++ ++ " Second step: figure out the patterns for searchpair() ++ " and save the screen, cursor position, and 'ignorecase'. ++ " - TODO: A lot of this is copied from s:Match_wrapper(). ++ " - maybe even more functionality should be split off ++ " - into separate functions! ++ let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default ++ let open = substitute(s:pat . cdefault, ++ \ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g') ++ let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '') ++ let close = substitute(s:pat . cdefault, ++ \ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g') ++ let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)' ++ if exists("b:match_skip") ++ let skip = b:match_skip ++ elseif exists("b:match_comment") " backwards compatibility and testing! ++ let skip = "r:" . b:match_comment ++ else ++ let skip = 's:comment\|string' ++ endif ++ let skip = s:ParseSkip(skip) ++ " let restore_cursor = line(".") . "G" . virtcol(".") . "|" ++ " normal! H ++ " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ let restore_cursor = virtcol(".") . "|" ++ normal! g0 ++ let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor ++ normal! H ++ let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor ++ execute restore_cursor ++ ++ " Third step: call searchpair(). ++ " Replace '\('--but not '\\('--with '\%(' and ',' with '\|'. ++ let openpat = substitute(open, '\(\\\@" or ... ++" and return "endif" or "endwhile" or "" or ... . ++" For now, this uses b:match_words and the same script variables ++" as s:Match_wrapper() . Later, it may get its own patterns, ++" either from a buffer variable or passed as arguments. ++" fun! s:Autocomplete() ++" echo "autocomplete not yet implemented :-(" ++" if !exists("b:match_words") || b:match_words == "" ++" return "" ++" end ++" let startpos = s:MultiMatch("bW") ++" ++" if startpos == "" ++" return "" ++" endif ++" " - TODO: figure out whether 'if' or '' matched, and construct ++" " - the appropriate closing. ++" let matchline = getline(".") ++" let curcol = col(".") - 1 ++" " - TODO: Change the s:all argument if there is a new set of match pats. ++" let regexp = s:Wholematch(matchline, s:all, curcol) ++" let suf = strlen(matchline) - matchend(matchline, regexp) ++" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(') ++" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$') ++" " Reconstruct the version with unresolved backrefs. ++" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g') ++" let patBR = substitute(patBR, ':\{2,}', ':', "g") ++" " Now, set group and groupBR to the matching group: 'if:endif' or ++" " 'while:endwhile' or whatever. ++" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) ++" let i = matchend(group, s:notslash . ",") ++" let groupBR = strpart(group, i) ++" let group = strpart(group, 0, i-1) ++" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix ++" if s:do_BR ++" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) ++" endif ++" " let g:group = group ++" ++" " - TODO: Construct the closing from group. ++" let fake = "end" . expand("") ++" execute startpos ++" return fake ++" endfun ++ ++" Close all open structures. "Get the heck out of here!" ++" fun! s:Gthhoh() ++" let close = s:Autocomplete() ++" while strlen(close) ++" put=close ++" let close = s:Autocomplete() ++" endwhile ++" endfun ++ ++" Parse special strings as typical skip arguments for searchpair(): ++" s:foo becomes (current syntax item) =~ foo ++" S:foo becomes (current syntax item) !~ foo ++" r:foo becomes (line before cursor) =~ foo ++" R:foo becomes (line before cursor) !~ foo ++fun! s:ParseSkip(str) ++ let skip = a:str ++ if skip[1] == ":" ++ if skip[0] == "s" ++ let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" . ++ \ strpart(skip,2) . "'" ++ elseif skip[0] == "S" ++ let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" . ++ \ strpart(skip,2) . "'" ++ elseif skip[0] == "r" ++ let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'" ++ elseif skip[0] == "R" ++ let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'" ++ endif ++ endif ++ return skip ++endfun ++ ++let &cpo = s:save_cpo ++ ++" vim:sts=2:sw=2: +diff -urN vim71/runtime/plugin/NERD_commenter.vim vim71_ada/runtime/plugin/NERD_commenter.vim +--- vim71/runtime/plugin/NERD_commenter.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/plugin/NERD_commenter.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,4553 @@ ++" vim global plugin that provides easy code commenting for various file types ++" Last Change: 29 sep 2007 ++" Maintainer: Martin Grenfell ++let s:NERD_commenter_version = 2.1.4 ++ ++" For help documentation type :help NERDCommenter. If this fails, Restart vim ++" and try again. If it sill doesnt work... the help page is at the bottom ++" of this file. ++ ++" Section: script init stuff {{{1 ++if exists("loaded_nerd_comments") ++ finish ++endif ++if v:version < 700 ++ echoerr "NERDCommenter: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" ++ finish ++endif ++let loaded_nerd_comments = 1 ++ ++" Section: spaces init {{{2 ++" Occasionally we need to grab a string of spaces so just make one here ++let s:spaces = "" ++while strlen(s:spaces) < 100 ++ let s:spaces = s:spaces . " " ++endwhile ++ ++" Function: s:InitVariable() function {{{2 ++" This function is used to initialise a given variable to a given value. The ++" variable is only initialised if it does not exist prior ++" ++" Args: ++" -var: the name of the var to be initialised ++" -value: the value to initialise var to ++" ++" Returns: ++" 1 if the var is set, 0 otherwise ++function s:InitVariable(var, value) ++ if !exists(a:var) ++ exec 'let ' . a:var . ' = ' . "'" . a:value . "'" ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Section: space string init{{{2 ++" When putting spaces after the left delim and before the right we use ++" s:spaceStr for the space char. This way we can make it add anything after ++" the left and before the right by modifying this variable ++let s:spaceStr = ' ' ++let s:lenSpaceStr = strlen(s:spaceStr) ++ ++" Section: variable init calls {{{2 ++call s:InitVariable("g:NERDAllowAnyVisualDelims", 1) ++call s:InitVariable("g:NERDBlockComIgnoreEmpty", 0) ++call s:InitVariable("g:NERDCommentWholeLinesInVMode", 0) ++call s:InitVariable("g:NERDCompactSexyComs", 0) ++call s:InitVariable("g:NERDDefaultNesting", 0) ++call s:InitVariable("g:NERDMenuMode", 3) ++call s:InitVariable("g:NERDLPlace", "[>") ++call s:InitVariable("g:NERDUsePlaceHolders", 1) ++call s:InitVariable("g:NERDRemoveAltComs", 1) ++call s:InitVariable("g:NERDRemoveExtraSpaces", 0) ++call s:InitVariable("g:NERDRPlace", "<]") ++call s:InitVariable("g:NERDShutUp", '0') ++call s:InitVariable("g:NERDSpaceDelims", 0) ++call s:InitVariable("g:NERDDelimiterRequests", 1) ++ ++call s:InitVariable("g:NERDMapleader", ',c') ++ ++call s:InitVariable("g:NERDAltComMap", g:NERDMapleader . 'a') ++call s:InitVariable("g:NERDAppendComMap", g:NERDMapleader . 'A') ++call s:InitVariable("g:NERDComAlignBothMap", g:NERDMapleader . 'b') ++call s:InitVariable("g:NERDComAlignLeftMap", g:NERDMapleader . 'l') ++call s:InitVariable("g:NERDComAlignRightMap", g:NERDMapleader . 'r') ++call s:InitVariable("g:NERDComInInsertMap", '') ++call s:InitVariable("g:NERDComLineInvertMap", g:NERDMapleader . 'i') ++call s:InitVariable("g:NERDComLineMap", g:NERDMapleader . 'c') ++call s:InitVariable("g:NERDComLineNestMap", g:NERDMapleader . 'n') ++call s:InitVariable("g:NERDComLineSexyMap", g:NERDMapleader . 's') ++call s:InitVariable("g:NERDComLineToggleMap", g:NERDMapleader . '') ++call s:InitVariable("g:NERDComLineMinimalMap", g:NERDMapleader . 'm') ++call s:InitVariable("g:NERDComLineYankMap", g:NERDMapleader . 'y') ++call s:InitVariable("g:NERDComToEOLMap", g:NERDMapleader . '$') ++call s:InitVariable("g:NERDPrependComMap", g:NERDMapleader . 'I') ++call s:InitVariable("g:NERDUncomLineMap", g:NERDMapleader . 'u') ++let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\" ++ ++" Section: Comment mapping functions, autocommands and commands {{{1 ++" ============================================================================ ++" Section: Comment enabler autocommands {{{2 ++" ============================================================================ ++ ++if !exists("nerd_autocmds_loaded") ++ let nerd_autocmds_loaded=1 ++ ++ augroup commentEnablers ++ ++ "if the user enters a buffer or reads a buffer then we gotta set up ++ "the comment delimiters for that new filetype ++ autocmd BufEnter,BufRead * :call s:SetUpForNewFiletype(&filetype, 0) ++ ++ "if the filetype of a buffer changes, force the script to reset the ++ "delims for the buffer ++ autocmd Filetype * :call s:SetUpForNewFiletype(&filetype, 1) ++ augroup END ++ ++endif ++ ++ ++" Function: s:SetUpForNewFiletype(filetype) function {{{2 ++" This function is responsible for setting up buffer scoped variables for the ++" given filetype. ++" ++" These variables include the comment delimiters for the given filetype and calls ++" MapDelimiters or MapDelimitersWithAlternative passing in these delimiters. ++" ++" Args: ++" -filetype: the filetype to set delimiters for ++" -forceReset: 1 if the delimiters should be reset if they have already be ++" set for this buffer. ++" ++function s:SetUpForNewFiletype(filetype, forceReset) ++ "if we have already set the delimiters for this buffer then dont go thru ++ "it again ++ if !a:forceReset && exists("b:left") && b:left != '' ++ return ++ endif ++ ++ let b:sexyComMarker = '' ++ ++ "check the filetype against all known filetypes to see if we have ++ "hardcoded the comment delimiters to use ++ if a:filetype == "" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "abaqus" ++ call s:MapDelimiters('**', '') ++ elseif a:filetype == "abc" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "acedb" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ada" ++ call s:MapDelimitersWithAlternative('--','', '-- ', '') ++ elseif a:filetype == "ahdl" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "ahk" ++ call s:MapDelimitersWithAlternative(';', '', '/*', '*/') ++ elseif a:filetype == "amiga" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "aml" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "ampl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ant" ++ call s:MapDelimiters('') ++ elseif a:filetype == "apache" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "apachestyle" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "asm68k" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "asm" ++ call s:MapDelimitersWithAlternative(';', '', '#', '') ++ elseif a:filetype == "asn" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "aspvbs" ++ call s:MapDelimiters('''', '') ++ elseif a:filetype == "atlas" ++ call s:MapDelimiters('C','$') ++ elseif a:filetype == "autohotkey" ++ call s:MapDelimiters(';','') ++ elseif a:filetype == "autoit" ++ call s:MapDelimiters(';','') ++ elseif a:filetype == "automake" ++ call s:MapDelimitersWithAlternative('#','', 'dnl ', '') ++ elseif a:filetype == "ave" ++ call s:MapDelimiters("'",'') ++ elseif a:filetype == "awk" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "basic" ++ call s:MapDelimitersWithAlternative("'",'', 'REM ', '') ++ elseif a:filetype == "b" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "bc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "bdf" ++ call s:MapDelimiters('COMMENT ', '') ++ elseif a:filetype == "bib" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "bindzone" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "bst" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "btm" ++ call s:MapDelimiters('::', '') ++ elseif a:filetype == "caos" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "catalog" ++ call s:MapDelimiters('--','--') ++ elseif a:filetype == "c" ++ call s:MapDelimitersWithAlternative('/*','*/', '//', '') ++ elseif a:filetype == "cfg" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "cg" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ch" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "changelog" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "cl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "clean" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "clipper" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "cmake" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "conf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "config" ++ call s:MapDelimiters('dnl ', '') ++ elseif a:filetype == "context" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "cpp" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "crontab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "cs" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "csc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "csp" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "css" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "cterm" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "cupl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "csv" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "cvs" ++ call s:MapDelimiters('CVS:','') ++ elseif a:filetype == "dcl" ++ call s:MapDelimiters('$!', '') ++ elseif a:filetype == "debchangelog" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "debcontrol" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "debsources" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "def" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "desktop" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "diff" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "django" ++ call s:MapDelimitersWithAlternative('', '{#', '#}') ++ elseif a:filetype == "docbk" ++ call s:MapDelimiters('') ++ elseif a:filetype == "dns" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dosbatch" ++ call s:MapDelimiters('REM ','') ++ elseif a:filetype == "dosini" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dot" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "dracula" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dsl" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "dtd" ++ call s:MapDelimiters('') ++ elseif a:filetype == "dtml" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "dylan" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == 'ebuild' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ecd" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'eclass' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "eiffel" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "elf" ++ call s:MapDelimiters("'", '') ++ elseif a:filetype == "elmfilt" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "erlang" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "eruby" ++ call s:MapDelimitersWithAlternative('', '<%#', '%>') ++ elseif a:filetype == "eterm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "expect" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "exports" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fetchmail" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fgl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "focexec" ++ call s:MapDelimiters('-*', '') ++ elseif a:filetype == "form" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "fortran" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "foxpro" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "fstab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fvwm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "fx" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "gams" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "gdb" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "gdmo" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "geek" ++ call s:MapDelimiters('GEEK_COMMENT:', '') ++ elseif a:filetype == 'gentoo-package-keywords' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'gentoo-package-mask' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == 'gentoo-package-use' ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "gnuplot" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "groovy" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "gtkrc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "haskell" ++ call s:MapDelimitersWithAlternative('--','', '{-', '-}') ++ elseif a:filetype == "hb" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "h" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "help" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "hercules" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "hog" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "html" ++ call s:MapDelimitersWithAlternative('', '//', '') ++ elseif a:filetype == "htmldjango" ++ call s:MapDelimitersWithAlternative('', '{#', '#}') ++ elseif a:filetype == "htmlos" ++ call s:MapDelimiters('#','/#') ++ elseif a:filetype == "ia64" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "icon" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "idlang" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "idl" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "indent" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "inform" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "inittab" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ishd" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "iss" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "ist" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "jam" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "java" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "javascript" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "jess" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "jgraph" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "jproperties" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "jsp" ++ call s:MapDelimiters('<%--', '--%>') ++ elseif a:filetype == "kconfig" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "kix" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "kscript" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "lace" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "ldif" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lex" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lftp" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lifelines" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lilo" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lisp" ++ call s:MapDelimitersWithAlternative(';','', '#|', '|#') ++ elseif a:filetype == "lite" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "lookupfile" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "lotos" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "lout" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lprolog" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "lscript" ++ call s:MapDelimiters("'", '') ++ elseif a:filetype == "lss" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "lua" ++ call s:MapDelimitersWithAlternative('--','', '--[[', ']]') ++ elseif a:filetype == "lynx" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "m4" ++ call s:MapDelimiters('dnl ', '') ++ elseif a:filetype == "mail" ++ call s:MapDelimiters('> ','') ++ elseif a:filetype == "make" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "maple" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "masm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "master" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "matlab" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "mel" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "mf" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "mib" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "mma" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "model" ++ call s:MapDelimiters('$','$') ++ elseif a:filetype =~ "moduala." ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "modula2" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "modula3" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "monk" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "mush" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "muttrc" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "named" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "nasm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "nastran" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "natural" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "ncf" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "netdict" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "netrw" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "nqc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "nroff" ++ call s:MapDelimiters('\"', '') ++ elseif a:filetype == "nsis" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "objc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "ocaml" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "occam" ++ call s:MapDelimiters('--','') ++ elseif a:filetype == "omlet" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "omnimark" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "openroad" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "opl" ++ call s:MapDelimiters("REM", "") ++ elseif a:filetype == "ora" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "otl" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ox" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "pascal" ++ call s:MapDelimitersWithAlternative('{','}', '(*', '*)') ++ elseif a:filetype == "passwd" ++ call s:MapDelimitersWith('','') ++ elseif a:filetype == "pcap" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "pccts" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "perl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "pfmain" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "php" ++ call s:MapDelimitersWithAlternative('//','','/*', '*/') ++ elseif a:filetype == "phtml" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "pic" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "pike" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "pilrc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "pine" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "plaintex" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "plm" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "plsql" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "po" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "postscr" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "pov" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "povini" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "ppd" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "ppwiz" ++ call s:MapDelimiters(';;', '') ++ elseif a:filetype == "procmail" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "progress" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "prolog" ++ call s:MapDelimitersWithAlternative('%','','/*','*/') ++ elseif a:filetype == "psf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "ptcap" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "python" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "qf" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "radiance" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "Rails-log" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ratpoison" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "r" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "readline" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rebol" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "registry" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "remind" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rexx" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "robots" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "rpl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "rst" ++ call s:MapDelimiters('..', '') ++ elseif a:filetype == "rtf" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "ruby" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "sa" ++ call s:MapDelimiters('--','') ++ elseif a:filetype == "samba" ++ call s:MapDelimitersWithAlternative(';','', '#', '') ++ elseif a:filetype == "sas" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "sass" ++ call s:MapDelimitersWithAlternative('//','', '/*', '') ++ elseif a:filetype == "sather" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "scheme" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "scilab" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "screen" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "scsh" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "sdl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "sed" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "selectbuf" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "sgml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "sgmldecl" ++ call s:MapDelimiters('--','--') ++ elseif a:filetype == "sgmllnx" ++ call s:MapDelimiters('') ++ elseif a:filetype == "sicad" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "simula" ++ call s:MapDelimitersWithAlternative('%', '', '--', '') ++ elseif a:filetype == "sinda" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "skill" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "slang" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "sl" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "slrnrc" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "sm" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "smarty" ++ call s:MapDelimiters('{*', '*}') ++ elseif a:filetype == "smil" ++ call s:MapDelimiters('') ++ elseif a:filetype == "smith" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "sml" ++ call s:MapDelimiters('(*','*)') ++ elseif a:filetype == "snnsnet" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snnspat" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snnsres" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "snobol4" ++ call s:MapDelimiters('*', '') ++ elseif a:filetype == "spec" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "specman" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "spice" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "sql" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqlforms" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqlj" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "sqr" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "squid" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "st" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "stp" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "strace" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "svn" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "SVNcommitlog" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "systemverilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "tads" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "taglist" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "tags" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tak" ++ call s:MapDelimiters('$', '') ++ elseif a:filetype == "tasm" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tcl" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "terminfo" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tex" ++ call s:MapDelimiters('%','') ++ elseif a:filetype == "text" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "texinfo" ++ call s:MapDelimiters("@c ", "") ++ elseif a:filetype == "texmf" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "tf" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "tidy" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tli" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "trasys" ++ call s:MapDelimiters("$", "") ++ elseif a:filetype == "tsalt" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "tsscl" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "tssgm" ++ call s:MapDelimiters("comment = '","'") ++ elseif a:filetype == "uc" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "uil" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "vb" ++ call s:MapDelimiters("'","") ++ elseif a:filetype == "vcscommit" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "vera" ++ call s:MapDelimitersWithAlternative('/*','*/','//','') ++ elseif a:filetype == "verilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "verilog_systemverilog" ++ call s:MapDelimitersWithAlternative('//','', '/*','*/') ++ elseif a:filetype == "vgrindefs" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "vhdl" ++ call s:MapDelimiters('--', '') ++ elseif a:filetype == "vim" ++ call s:MapDelimiters('"','') ++ elseif a:filetype == "viminfo" ++ call s:MapDelimiters('','') ++ elseif a:filetype == "virata" ++ call s:MapDelimiters('%', '') ++ elseif a:filetype == "vo_base" ++ call s:MapDelimiters('', '') ++ elseif a:filetype == "vrml" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "vsejcl" ++ call s:MapDelimiters('/*', '') ++ elseif a:filetype == "webmacro" ++ call s:MapDelimiters('##', '') ++ elseif a:filetype == "wget" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "winbatch" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "wml" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype =~ "[^w]*sh" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "wvdial" ++ call s:MapDelimiters(';', '') ++ elseif a:filetype == "xdefaults" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xf86conf" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "xhtml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xkb" ++ call s:MapDelimiters('//', '') ++ elseif a:filetype == "xmath" ++ call s:MapDelimiters('#', '') ++ elseif a:filetype == "xml" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xmodmap" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xpm2" ++ call s:MapDelimiters('!', '') ++ elseif a:filetype == "xpm" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "xsd" ++ call s:MapDelimiters('') ++ elseif a:filetype == "xslt" ++ call s:MapDelimiters('') ++ elseif a:filetype == "yacc" ++ call s:MapDelimiters('/*','*/') ++ elseif a:filetype == "yaml" ++ call s:MapDelimiters('#','') ++ elseif a:filetype == "z8a" ++ call s:MapDelimiters(';', '') ++ ++ elseif a:filetype == "" ++ call s:MapDelimitersWithAlternative("","", "", "") ++ ++ "we have not hardcoded the comment delimiters to use for this filetype so ++ "get them from &commentstring. ++ else ++ "print a disclaimer to the user :) ++ if !g:NERDShutUp ++ call s:NerdEcho("Unknown filetype '".a:filetype."', setting delimiters by &commentstring.\nPleeeeease email the author of the NERD commenter with this filetype\nand its delimiters!", 0) ++ endif ++ ++ "extract the delims from &commentstring ++ let left= substitute(&commentstring, '\(.*\)%s.*', '\1', '') ++ let right= substitute(&commentstring, '.*%s\(.*\)', '\1', 'g') ++ ++ call s:MapDelimiters(left,right) ++ endif ++endfunction ++ ++" Function: s:MapDelimiters(left, right) function {{{2 ++" This function is a wrapper for s:MapDelimiters(left, right, leftAlt, rightAlt, useAlt) and is called when there ++" is no alternative comment delimiters for the current filetype ++" ++" Args: ++" -left: the left comment delimiter ++" -right: the right comment delimiter ++function s:MapDelimiters(left, right) ++ call s:MapDelimitersWithAlternative(a:left, a:right, "", "") ++endfunction ++ ++" Function: s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt) function {{{2 ++" this function sets up the comment delimiter buffer variables ++" ++" Args: ++" -left: the string defining the comment start delimiter ++" -right: the string defining the comment end delimiter ++" -leftAlt: the string for the alternative comment style defining the comment start delimiter ++" -rightAlt: the string for the alternative comment style defining the comment end delimiter ++function s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt) ++ if !exists('g:NERD_' . &filetype . '_alt_style') ++ let b:left = a:left ++ let b:right = a:right ++ let b:leftAlt = a:leftAlt ++ let b:rightAlt = a:rightAlt ++ else ++ let b:left = a:leftAlt ++ let b:right = a:rightAlt ++ let b:leftAlt = a:left ++ let b:rightAlt = a:right ++ endif ++endfunction ++ ++" Function: s:SwitchToAlternativeDelimiters(printMsgs) function {{{2 ++" This function is used to swap the delimiters that are being used to the ++" alternative delimiters for that filetype. For example, if a c++ file is ++" being edited and // comments are being used, after this function is called ++" /**/ comments will be used. ++" ++" Args: ++" -printMsgs: if this is 1 then a message is echoed to the user telling them ++" if this function changed the delimiters or not ++function s:SwitchToAlternativeDelimiters(printMsgs) ++ "if both of the alternative delimiters are empty then there is no ++ "alternative comment style so bail out ++ if !s:HasMultipartDelims() ++ if a:printMsgs ++ call s:NerdEcho("Cannot use alternative delimiters, none are specified", 0) ++ endif ++ return 0 ++ endif ++ ++ "save the current delimiters ++ let tempLeft = b:left ++ let tempRight = b:right ++ ++ "swap current delimiters for alternative ++ let b:left = b:leftAlt ++ let b:right = b:rightAlt ++ ++ "set the previously current delimiters to be the new alternative ones ++ let b:leftAlt = tempLeft ++ let b:rightAlt = tempRight ++ ++ "tell the user what comment delimiters they are now using ++ if a:printMsgs ++ let leftNoEsc = b:left ++ let rightNoEsc = b:right ++ call s:NerdEcho("Now using " . leftNoEsc . " " . rightNoEsc . " to delimit comments", 1) ++ endif ++ ++ return 1 ++endfunction ++ ++" Section: Comment delimiter add/removal functions {{{1 ++" ============================================================================ ++" Function: s:AppendCommentToLine(){{{2 ++" This function appends comment delimiters at the EOL and places the cursor in ++" position to start typing the comment ++function s:AppendCommentToLine() ++ let left = s:GetLeft(0,1,0) ++ let right = s:GetRight(0,1,0) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ let isLineEmpty = strlen(getline(".")) == 0 ++ let insOrApp = (isLineEmpty==1 ? 'i' : 'A') ++ ++ "stick the delimiters down at the end of the line. We have to format the ++ "comment with spaces as appropriate ++ execute ":normal " . insOrApp . (isLineEmpty ? '' : ' ') . left . right . " " ++ ++ " if there is a right delimiter then we gotta move the cursor left ++ " by the len of the right delimiter so we insert between the delimiters ++ if lenRight > 0 ++ let leftMoveAmount = lenRight ++ execute ":normal " . leftMoveAmount . "h" ++ endif ++ startinsert ++endfunction ++ ++" Function: s:CommentBlock(top, bottom, lSide, rSide, forceNested ) {{{2 ++" This function is used to comment out a region of code. This region is ++" specified as a bounding box by arguments to the function. ++" ++" Args: ++" -top: the line number for the top line of code in the region ++" -bottom: the line number for the bottom line of code in the region ++" -lSide: the column number for the left most column in the region ++" -rSide: the column number for the right most column in the region ++" -forceNested: a flag indicating whether comments should be nested ++function s:CommentBlock(top, bottom, lSide, rSide, forceNested ) ++ " we need to create local copies of these arguments so we can modify them ++ let top = a:top ++ let bottom = a:bottom ++ let lSide = a:lSide ++ let rSide = a:rSide ++ ++ "if the top or bottom line starts with tabs we have to adjust the left and ++ "right boundaries so that they are set as though the tabs were spaces ++ let topline = getline(top) ++ let bottomline = getline(bottom) ++ if s:HasLeadingTabs(topline, bottomline) ++ ++ "find out how many tabs are in the top line and adjust the left ++ "boundary accordingly ++ let numTabs = s:NumberOfLeadingTabs(topline) ++ if lSide < numTabs ++ let lSide = &ts * lSide ++ else ++ let lSide = (lSide - numTabs) + (&ts * numTabs) ++ endif ++ ++ "find out how many tabs are in the bottom line and adjust the right ++ "boundary accordingly ++ let numTabs = s:NumberOfLeadingTabs(bottomline) ++ let rSide = (rSide - numTabs) + (&ts * numTabs) ++ endif ++ ++ "we must check that bottom IS actually below top, if it is not then we ++ "swap top and bottom. Similarly for left and right. ++ if bottom < top ++ let temp = top ++ let top = bottom ++ let bottom = top ++ endif ++ if rSide < lSide ++ let temp = lSide ++ let lSide = rSide ++ let rSide = temp ++ endif ++ ++ "if the current delimiters arent multipart then we will switch to the ++ "alternative delims (if THEY are) as the comment will be better and more ++ "accurate with multipart delims ++ let switchedDelims = 0 ++ if !s:Multipart() && g:NERDAllowAnyVisualDelims && s:AltMultipart() ++ let switchedDelims = 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++ "start the commenting from the top and keep commenting till we reach the ++ "bottom ++ let currentLine=top ++ while currentLine <= bottom ++ ++ "check if we are allowed to comment this line ++ if s:CanCommentLine(a:forceNested, currentLine) ++ ++ "convert the leading tabs into spaces ++ let theLine = getline(currentLine) ++ let lineHasLeadTabs = s:HasLeadingTabs(theLine) ++ if lineHasLeadTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ ++ "dont comment lines that begin after the right boundary of the ++ "block unless the user has specified to do so ++ if theLine !~ '^ \{' . rSide . '\}' || !g:NERDBlockComIgnoreEmpty ++ ++ "attempt to place the cursor in on the left of the boundary box, ++ "then check if we were successful, if not then we cant comment this ++ "line ++ call setline(currentLine, theLine) ++ if s:CanPlaceCursor(currentLine, lSide) ++ ++ let leftSpaced = s:GetLeft(0,1,0) ++ let rightSpaced = s:GetRight(0,1,0) ++ ++ "stick the left delimiter down ++ let theLine = strpart(theLine, 0, lSide-1) . leftSpaced . strpart(theLine, lSide-1) ++ ++ if s:Multipart() ++ "stick the right delimiter down ++ let theLine = strpart(theLine, 0, rSide+strlen(leftSpaced)) . rightSpaced . strpart(theLine, rSide+strlen(rightSpaced)) ++ ++ let firstLeftDelim = s:FindDelimiterIndex(b:left, theLine) ++ let lastRightDelim = s:LastIndexOfDelim(b:right, theLine) ++ ++ if firstLeftDelim != -1 && lastRightDelim != -1 ++ let searchStr = strpart(theLine, 0, lastRightDelim) ++ let searchStr = strpart(searchStr, firstLeftDelim+strlen(b:left)) ++ ++ "replace the outter most delims in searchStr with ++ "place-holders ++ let theLineWithPlaceHolders = s:ReplaceDelims(b:left, b:right, g:NERDLPlace, g:NERDRPlace, searchStr) ++ ++ "add the right delimiter onto the line ++ let theLine = strpart(theLine, 0, firstLeftDelim+strlen(b:left)) . theLineWithPlaceHolders . strpart(theLine, lastRightDelim) ++ endif ++ endif ++ endif ++ endif ++ ++ "restore tabs if needed ++ if lineHasLeadTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ call setline(currentLine, theLine) ++ endif ++ ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "if we switched delims then we gotta go back to what they were before ++ if switchedDelims == 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++endfunction ++ ++" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2 ++" This function comments a range of lines. ++" ++" Args: ++" -forceNested: a flag indicating whether the called is requesting the comment ++" to be nested if need be ++" -alignRight/alignLeft: 0/1 if the comments delimiters should/shouldnt be ++" aligned left/right ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) ++ " we need to get the left and right indexes of the leftmost char in the ++ " block of of lines and the right most char so that we can do alignment of ++ " the delimiters if the user has specified ++ let leftAlignIndx = s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) ++ let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) ++ ++ " gotta add the length of the left delimiter onto the rightAlignIndx cos ++ " we'll be adding a left delim to the line ++ let rightAlignIndx = rightAlignIndx + strlen(s:GetLeft(0,1,0)) ++ ++ " now we actually comment the lines. Do it line by line ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ ++ " get the next line, check commentability and convert spaces to tabs ++ let theLine = getline(currentLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ if s:CanCommentLine(a:forceNested, currentLine) ++ "if the user has specified forceNesting then we check to see if we ++ "need to switch delimiters for place-holders ++ if a:forceNested && g:NERDUsePlaceHolders ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ endif ++ ++ " find out if the line is commented using normal delims and/or ++ " alternate ones ++ let isCommented = s:IsCommented(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine) ++ ++ " check if we can comment this line ++ if !isCommented || g:NERDUsePlaceHolders || s:Multipart() ++ if a:alignLeft ++ let theLine = s:AddLeftDelimAligned(b:left, theLine, leftAlignIndx) ++ else ++ let theLine = s:AddLeftDelim(s:GetLeft(0,1,0), theLine) ++ endif ++ if a:alignRight ++ let theLine = s:AddRightDelimAligned(b:right, theLine, rightAlignIndx) ++ else ++ let theLine = s:AddRightDelim(s:GetRight(0,1,0), theLine) ++ endif ++ endif ++ endif ++ ++ " restore leading tabs if appropriate ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ " we are done with this line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentLinesMinimal(firstLine, lastLine) {{{2 ++" This function comments a range of lines in a minimal style. I ++" ++" Args: ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLinesMinimal(firstLine, lastLine) ++ "check that minimal comments can be done on this filetype ++ if !s:HasMultipartDelims() ++ throw 'NERDCommenter.Delimiters exception: Minimal comments can only be used for filetypes that have multipart delimiters' ++ endif ++ ++ "if we need to use place holders for the comment, make sure they are ++ "enabled for this filetype ++ if !g:NERDUsePlaceHolders && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine) ++ throw 'NERDCommenter.Settings exception: Placeoholders are required but disabled.' ++ endif ++ ++ "get the left and right delims to smack on ++ let left = s:GetSexyComLeft(g:NERDSpaceDelims,0) ++ let right = s:GetSexyComRight(g:NERDSpaceDelims,0) ++ ++ "make sure all multipart delims on the lines are replaced with ++ "placeholders to prevent illegal syntax ++ let currentLine = a:firstLine ++ while(currentLine <= a:lastLine) ++ let theLine = getline(currentLine) ++ let theLine = s:ReplaceDelims(left, right, g:NERDLPlace, g:NERDRPlace, theLine) ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "add the delim to the top line ++ let theLine = getline(a:firstLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let theLine = s:AddLeftDelim(left, theLine) ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:firstLine, theLine) ++ ++ "add the delim to the bottom line ++ let theLine = getline(a:lastLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let theLine = s:AddRightDelim(right, theLine) ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:lastLine, theLine) ++endfunction ++ ++" Function: s:CommentLinesSexy(topline, bottomline) function {{{2 ++" This function is used to comment lines in the 'Sexy' style. eg in c: ++" /* ++" * This is a sexy comment ++" */ ++" Args: ++" -topline: the line num of the top line in the sexy comment ++" -bottomline: the line num of the bottom line in the sexy comment ++function s:CommentLinesSexy(topline, bottomline) ++ let left = s:GetSexyComLeft(0, 0) ++ let right = s:GetSexyComRight(0, 0) ++ ++ "check if we can do a sexy comment with the available delimiters ++ if left == -1 || right == -1 ++ throw 'NERDCommenter.Delimiters exception: cannot perform sexy comments with available delimiters.' ++ endif ++ ++ "make sure the lines arent already commented sexually ++ if !s:CanSexyCommentLines(a:topline, a:bottomline) ++ throw 'NERDCommenter.Nesting exception: cannot nest sexy comments' ++ endif ++ ++ ++ let sexyComMarker = s:GetSexyComMarker(0,0) ++ let sexyComMarkerSpaced = s:GetSexyComMarker(1,0) ++ ++ ++ " we jam the comment as far to the right as possible ++ let leftAlignIndx = s:LeftMostIndx(1, 1, a:topline, a:bottomline) ++ ++ "check if we should use the compact style i.e that the left/right ++ "delimiters should appear on the first and last lines of the code and not ++ "on separate lines above/below the first/last lines of code ++ if g:NERDCompactSexyComs ++ let spaceString = (g:NERDSpaceDelims ? s:spaceStr : '') ++ ++ "comment the top line ++ let theLine = getline(a:topline) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ let theLine = s:AddLeftDelimAligned(left . spaceString, theLine, leftAlignIndx) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:topline, theLine) ++ ++ "comment the bottom line ++ let theLine = getline(a:bottomline) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ let theLine = s:AddRightDelim(spaceString . right, theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ call setline(a:bottomline, theLine) ++ else ++ ++ " add the left delimiter one line above the lines that are to be commented ++ call cursor(a:topline, 1) ++ execute 'normal! O' ++ call setline(a:topline, strpart(s:spaces, 0, leftAlignIndx) . left ) ++ ++ " add the right delimiter after bottom line (we have to add 1 cos we moved ++ " the lines down when we added the left delim ++ call cursor(a:bottomline+1, 1) ++ execute 'normal! o' ++ call setline(a:bottomline+2, strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, strlen(left)-strlen(sexyComMarker)) . right ) ++ ++ endif ++ ++ " go thru each line adding the sexyComMarker marker to the start of each ++ " line in the appropriate place to align them with the comment delims ++ let currentLine = a:topline+1 ++ while currentLine <= a:bottomline + !g:NERDCompactSexyComs ++ " get the line and convert the tabs to spaces ++ let theLine = getline(currentLine) ++ let lineHasTabs = s:HasLeadingTabs(theLine) ++ if lineHasTabs ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ endif ++ ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ ++ " add the sexyComMarker ++ let theLine = strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, strlen(left)-strlen(sexyComMarker)) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx) ++ ++ if lineHasTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ ++ " set the line and move onto the next one ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentLinesToggle(forceNested, firstLine, lastLine) {{{2 ++" Applies "toggle" commenting to the given range of lines ++" ++" Args: ++" -forceNested: a flag indicating whether the called is requesting the comment ++" to be nested if need be ++" -firstLine/lastLine: the top and bottom lines to comment ++function s:CommentLinesToggle(forceNested, firstLine, lastLine) ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ ++ " get the next line, check commentability and convert spaces to tabs ++ let theLine = getline(currentLine) ++ let lineHasLeadingTabs = s:HasLeadingTabs(theLine) ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ if s:CanToggleCommentLine(a:forceNested, currentLine) ++ ++ "if the user has specified forceNesting then we check to see if we ++ "need to switch delimiters for place-holders ++ if g:NERDUsePlaceHolders ++ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) ++ endif ++ ++ let theLine = s:AddLeftDelim(s:GetLeft(0, 1, 0), theLine) ++ let theLine = s:AddRightDelim(s:GetRight(0, 1, 0), theLine) ++ endif ++ ++ " restore leading tabs if appropriate ++ if lineHasLeadingTabs ++ let theLine = s:ConvertLeadingSpacesToTabs(theLine) ++ endif ++ ++ " we are done with this line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++endfunction ++ ++" Function: s:CommentRegion(topline, topCol, bottomLine, bottomCol) function {{{2 ++" This function comments chunks of text selected in visual mode. ++" It will comment exactly the text that they have selected. ++" Args: ++" -topLine: the line num of the top line in the sexy comment ++" -topCol: top left col for this comment ++" -bottomline: the line num of the bottom line in the sexy comment ++" -bottomCol: the bottom right col for this comment ++" -forceNested: whether the caller wants comments to be nested if the ++" line(s) are already commented ++function s:CommentRegion(topLine, topCol, bottomLine, bottomCol, forceNested) ++ ++ "switch delims (if we can) if the current set isnt multipart ++ let switchedDelims = 0 ++ if !s:Multipart() && s:AltMultipart() && !g:NERDAllowAnyVisualDelims ++ let switchedDelims = 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++ "if there is only one line in the comment then just do it ++ if a:topLine == a:bottomLine ++ call s:CommentBlock(a:topLine, a:bottomLine, a:topCol, a:bottomCol, a:forceNested) ++ ++ "there are multiple lines in the comment ++ else ++ "comment the top line ++ call s:CommentBlock(a:topLine, a:topLine, a:topCol, strlen(getline(a:topLine)), a:forceNested) ++ ++ "comment out all the lines in the middle of the comment ++ let topOfRange = a:topLine+1 ++ let bottomOfRange = a:bottomLine-1 ++ if topOfRange <= bottomOfRange ++ call s:CommentLines(a:forceNested, 0, 0, topOfRange, bottomOfRange) ++ endif ++ ++ "comment the bottom line ++ let bottom = getline(a:bottomLine) ++ let numLeadingSpacesTabs = strlen(substitute(bottom, '^\([ \t]*\).*$', '\1', '')) ++ call s:CommentBlock(a:bottomLine, a:bottomLine, numLeadingSpacesTabs+1, a:bottomCol, a:forceNested) ++ ++ endif ++ ++ "stick the cursor back on the char it was on before the comment ++ call cursor(a:topLine, a:topCol + strlen(b:left) + g:NERDSpaceDelims) ++ ++ "if we switched delims then we gotta go back to what they were before ++ if switchedDelims == 1 ++ call s:SwitchToAlternativeDelimiters(0) ++ endif ++ ++endfunction ++ ++" Function: s:InvertComment(firstLine, lastLine) function {{{2 ++" Inverts the comments on the lines between and including the given line ++" numbers i.e all commented lines are uncommented and vice versa ++" Args: ++" -firstLine: the top of the range of lines to be inverted ++" -lastLine: the bottom of the range of lines to be inverted ++function s:InvertComment(firstLine, lastLine) ++ ++ " go thru all lines in the given range ++ let currentLine = a:firstLine ++ while currentLine <= a:lastLine ++ let theLine = getline(currentLine) ++ ++ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) ++ ++ " if the line is commented normally, uncomment it ++ if s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine) ++ call s:UncommentLines(1, currentLine, currentLine) ++ let currentLine = currentLine + 1 ++ ++ " check if the line is commented sexually ++ elseif !empty(sexyComBounds) ++ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() ++ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) ++ ++ "move to the line after last line of the sexy comment ++ let numLinesAfterSexyComRemoved = s:NumLinesInBuf() ++ let currentLine = bottomBound - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1 ++ ++ " the line isnt commented ++ else ++ call s:CommentLinesToggle(1, currentLine, currentLine) ++ let currentLine = currentLine + 1 ++ endif ++ ++ endwhile ++endfunction ++ ++" Function: NERDComment(isVisual, alignLeft, alignRight, type) function {{{2 ++" This function is a Wrapper for the main commenting functions ++" ++" Args: ++" -isVisual: a flag indicating whether the comment is requested in visual ++" mode or not ++" -type: the type of commenting requested. Can be 'sexy', 'invert', ++" 'minimal', 'toggle', 'alignLeft', 'alignRight', 'alignBoth', 'norm', ++" 'nested', 'toEOL', 'prepend', 'append', 'insert', 'uncomment', 'yank' ++function! NERDComment(isVisual, type) range ++ " we want case sensitivity when commenting ++ let prevIgnoreCase = &ignorecase ++ set noignorecase ++ ++ if a:isVisual ++ let firstLine = line("'<") ++ let lastLine = line("'>") ++ let firstCol = col("'<") ++ let lastCol = col("'>") ++ else ++ let firstLine = a:firstline ++ let lastLine = a:lastline ++ endif ++ ++ let countWasGiven = (a:isVisual == 0 && firstLine != lastLine) ++ ++ let forceNested = (a:type == 'nested' || g:NERDDefaultNesting) ++ ++ if a:type == 'norm' || a:type == 'nested' ++ if a:isVisual && visualmode() == "" ++ call s:CommentBlock(firstLine, lastLine, firstCol, lastCol, forceNested) ++ elseif a:isVisual && visualmode() == "v" && (g:NERDCommentWholeLinesInVMode==0 || (g:NERDCommentWholeLinesInVMode==2 && s:HasMultipartDelims())) ++ call s:CommentRegion(firstLine, firstCol, lastLine, lastCol, forceNested) ++ else ++ call s:CommentLines(forceNested, 0, 0, firstLine, lastLine) ++ endif ++ ++ elseif a:type == 'alignLeft' || a:type == 'alignRight' || a:type == 'alignBoth' ++ let alignLeft = (a:type == 'alignLeft' || a:type == 'alignBoth') ++ let alignRight = (a:type == 'alignRight' || a:type == 'alignBoth') ++ call s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) ++ ++ elseif a:type == 'invert' ++ call s:InvertComment(firstLine, lastLine) ++ ++ elseif a:type == 'sexy' ++ try ++ call s:CommentLinesSexy(firstLine, lastLine) ++ catch /NERDCommenter.Delimiters/ ++ call s:NerdEcho("Sexy comments cannot be done with the available delimiters", 0) ++ catch /NERDCommenter.Nesting/ ++ call s:NerdEcho("Sexy comment aborted. Nested sexy cannot be nested", 0) ++ endtry ++ ++ elseif a:type == 'toggle' ++ let theLine = getline(firstLine) ++ ++ if s:IsInSexyComment(firstLine) || s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine) ++ call s:UncommentLines(1, firstLine, lastLine) ++ else ++ call s:CommentLinesToggle(forceNested, firstLine, lastLine) ++ endif ++ ++ elseif a:type == 'minimal' ++ try ++ call s:CommentLinesMinimal(firstLine, lastLine) ++ catch /NERDCommenter.Delimiters/ ++ call s:NerdEcho("Minimal comments can only be used for filetypes that have multipart delimiters.", 0) ++ catch /NERDCommenter.Settings/ ++ call s:NerdEcho("Place holders are required but disabled.", 0) ++ endtry ++ ++ elseif a:type == 'toEOL' ++ call s:SaveScreenState() ++ call s:CommentBlock(firstLine, firstLine, col("."), col("$")-1, 1) ++ call s:RestoreScreenState() ++ ++ elseif a:type == 'prepend' ++ call s:PrependCommentToLine() ++ ++ elseif a:type == 'append' ++ call s:AppendCommentToLine() ++ ++ elseif a:type == 'insert' ++ call s:PlaceDelimitersAndInsBetween() ++ ++ elseif a:type == 'uncomment' ++ call s:UncommentLines(0, firstLine, lastLine) ++ ++ elseif a:type == 'yank' ++ if a:isVisual ++ normal gvy ++ elseif countWasGiven ++ execute firstLine .','. lastLine .'yank' ++ else ++ normal Y ++ endif ++ execute firstLine .','. lastLine .'call NERDComment('. a:isVisual .', "norm")' ++ endif ++ ++ let &ignorecase = prevIgnoreCase ++endfunction ++ ++" Function: s:PlaceDelimitersAndInsBetween() function {{{2 ++" This is function is called to place comment delimiters down and place the ++" cursor between them ++function s:PlaceDelimitersAndInsBetween() ++ " get the left and right delimiters without any escape chars in them ++ let left = s:GetLeft(0, 1, 0) ++ let right = s:GetRight(0, 1, 0) ++ ++ let theLine = getline(".") ++ let lineHasLeadTabs = s:HasLeadingTabs(theLine) || (theLine =~ '^ *$' && !&expandtab) ++ ++ "convert tabs to spaces and adjust the cursors column to take this into ++ "account ++ let untabbedCol = s:UntabbedCol(theLine, col(".")) ++ call setline(line("."), s:ConvertLeadingTabsToSpaces(theLine)) ++ call cursor(line("."), untabbedCol) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ let isDelimOnEOL = col(".") >= strlen(getline(".")) ++ ++ " if the cursor is in the first col then we gotta insert rather than ++ " append the comment delimiters here ++ let insOrApp = (col(".")==1 ? 'i' : 'a') ++ ++ " place the delimiters down. We do it differently depending on whether ++ " there is a left AND right delimiter ++ if lenRight > 0 ++ execute ":normal " . insOrApp . left . right ++ execute ":normal " . lenRight . "h" ++ else ++ execute ":normal " . insOrApp . left ++ ++ " if we are tacking the delim on the EOL then we gotta add a space ++ " after it cos when we go out of insert mode the cursor will move back ++ " one and the user wont be in position to type the comment. ++ if isDelimOnEOL ++ execute 'normal a ' ++ endif ++ endif ++ normal l ++ ++ "if needed convert spaces back to tabs and adjust the cursors col ++ "accordingly ++ if lineHasLeadTabs ++ let tabbedCol = s:TabbedCol(getline("."), col(".")) ++ call setline(line("."), s:ConvertLeadingSpacesToTabs(getline("."))) ++ call cursor(line("."), tabbedCol) ++ endif ++ ++ startinsert ++endfunction ++ ++" Function: s:PrependCommentToLine(){{{2 ++" This function prepends comment delimiters to the start of line and places ++" the cursor in position to start typing the comment ++function s:PrependCommentToLine() ++ " get the left and right delimiters without any escape chars in them ++ let left = s:GetLeft(0, 1, 0) ++ let right = s:GetRight(0, 1, 0) ++ ++ " get the len of the right delim ++ let lenRight = strlen(right) ++ ++ ++ "if the line is empty then we need to know about this later on ++ let isLineEmpty = strlen(getline(".")) == 0 ++ ++ "stick the delimiters down at the start of the line. We have to format the ++ "comment with spaces as appropriate ++ if lenRight > 0 ++ execute ":normal I" . left . right ++ else ++ execute ":normal I" . left ++ endif ++ ++ " if there is a right delimiter then we gotta move the cursor left ++ " by the len of the right delimiter so we insert between the delimiters ++ if lenRight > 0 ++ let leftMoveAmount = lenRight ++ execute ":normal " . leftMoveAmount . "h" ++ endif ++ normal l ++ ++ "if the line was empty then we gotta add an extra space on the end because ++ "the cursor will move back one more at the end of the last "execute" ++ "command ++ if isLineEmpty && lenRight == 0 ++ execute ":normal a " ++ endif ++ ++ startinsert ++endfunction ++" Function: s:RemoveDelimiters(left, right, line) {{{2 ++" this function is called to remove the first left comment delimiter and the ++" last right delimiter of the given line. ++" ++" The args left and right must be strings. If there is no right delimiter (as ++" is the case for e.g vim file comments) them the arg right should be "" ++" ++" Args: ++" -left: the left comment delimiter ++" -right: the right comment delimiter ++" -line: the line to remove the delimiters from ++function s:RemoveDelimiters(left, right, line) ++ ++ let l:left = a:left ++ let l:right = a:right ++ let lenLeft = strlen(left) ++ let lenRight = strlen(right) ++ ++ let delimsSpaced = (g:NERDSpaceDelims || g:NERDRemoveExtraSpaces) ++ ++ let line = a:line ++ ++ "look for the left delimiter, if we find it, remove it. ++ let leftIndx = s:FindDelimiterIndex(a:left, line) ++ if leftIndx != -1 ++ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+lenLeft) ++ ++ "if the user has specified that there is a space after the left delim ++ "then check for the space and remove it if it is there ++ if delimsSpaced && strpart(line, leftIndx, s:lenSpaceStr) == s:spaceStr ++ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+s:lenSpaceStr) ++ endif ++ endif ++ ++ "look for the right delimiter, if we find it, remove it ++ let rightIndx = s:FindDelimiterIndex(a:right, line) ++ if rightIndx != -1 ++ let line = strpart(line, 0, rightIndx) . strpart(line, rightIndx+lenRight) ++ ++ "if the user has specified that there is a space before the right delim ++ "then check for the space and remove it if it is there ++ if delimsSpaced && strpart(line, rightIndx-s:lenSpaceStr, s:lenSpaceStr) == s:spaceStr && s:Multipart() ++ let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx) ++ endif ++ endif ++ ++ return line ++endfunction ++ ++" Function: s:UncommentLines(onlyWholeLineComs, topLine, bottomLine) {{{2 ++" This function uncomments the given lines ++" ++" Args: ++" onlyWholeLineComs: should be 1 for toggle style uncommenting ++" topLine: the top line of the visual selection to uncomment ++" bottomLine: the bottom line of the visual selection to uncomment ++function s:UncommentLines(onlyWholeLineComs, topLine, bottomLine) ++ "make local copies of a:firstline and a:lastline and, if need be, swap ++ "them around if the top line is below the bottom ++ let l:firstline = a:topLine ++ let l:lastline = a:bottomLine ++ if firstline > lastline ++ let firstline = lastline ++ let lastline = a:topLine ++ endif ++ ++ "go thru each line uncommenting each line removing sexy comments ++ let currentLine = firstline ++ while currentLine <= lastline ++ ++ "check the current line to see if it is part of a sexy comment ++ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) ++ if !empty(sexyComBounds) ++ ++ "we need to store the num lines in the buf before the comment is ++ "removed so we know how many lines were removed when the sexy com ++ "was removed ++ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() ++ ++ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) ++ ++ "move to the line after last line of the sexy comment ++ let numLinesAfterSexyComRemoved = s:NumLinesInBuf() ++ let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved ++ let currentLine = sexyComBounds[1] - numLinesRemoved + 1 ++ let lastline = lastline - numLinesRemoved ++ ++ "no sexy com was detected so uncomment the line as normal ++ else ++ let theLine = getline(currentLine) ++ if a:onlyWholeLineComs && (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)) ++ call s:UncommentLinesNormal(currentLine, currentLine) ++ elseif !a:onlyWholeLineComs ++ call s:UncommentLinesNormal(currentLine, currentLine) ++ endif ++ let currentLine = currentLine + 1 ++ endif ++ endwhile ++ ++endfunction ++ ++" Function: s:UncommentLinesSexy(topline, bottomline) {{{2 ++" This function removes all the comment characters associated with the sexy ++" comment spanning the given lines ++" Args: ++" -topline/bottomline: the top/bottom lines of the sexy comment ++function s:UncommentLinesSexy(topline, bottomline) ++ let left = s:GetSexyComLeft(0,1) ++ let right = s:GetSexyComRight(0,1) ++ ++ ++ "check if it is even possible for sexy comments to exist with the ++ "available delimiters ++ if left == -1 || right == -1 ++ throw 'NERDCommenter.Delimiters exception: cannot uncomment sexy comments with available delimiters.' ++ endif ++ ++ let leftUnEsc = s:GetSexyComLeft(0,0) ++ let rightUnEsc = s:GetSexyComRight(0,0) ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ let sexyComMarkerUnEsc = s:GetSexyComMarker(0, 0) ++ ++ "the markerOffset is how far right we need to move the sexyComMarker to ++ "line it up with the end of the left delim ++ let markerOffset = strlen(leftUnEsc)-strlen(sexyComMarkerUnEsc) ++ ++ " go thru the intermediate lines of the sexy comment and remove the ++ " sexy comment markers (eg the '*'s on the start of line in a c sexy ++ " comment) ++ let currentLine = a:topline+1 ++ while currentLine < a:bottomline ++ let theLine = getline(currentLine) ++ ++ " remove the sexy comment marker from the line. We also remove the ++ " space after it if there is one and if appropriate options are set ++ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) ++ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) ++ endif ++ ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ ++ let theLine = s:ConvertLeadingWhiteSpace(theLine) ++ ++ " move onto the next line ++ call setline(currentLine, theLine) ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ " gotta make a copy of a:bottomline cos we modify the position of the ++ " last line it if we remove the topline ++ let bottomline = a:bottomline ++ ++ " get the first line so we can remove the left delim from it ++ let theLine = getline(a:topline) ++ ++ " if the first line contains only the left delim then just delete it ++ if theLine =~ '^[ \t]*' . left . '[ \t]*$' && !g:NERDCompactSexyComs ++ call cursor(a:topline, 1) ++ normal dd ++ let bottomline = bottomline - 1 ++ ++ " topline contains more than just the left delim ++ else ++ ++ " remove the delim. If there is a space after it ++ " then remove this too if appropriate ++ let delimIndx = stridx(theLine, leftUnEsc) ++ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)) ++ endif ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ call setline(a:topline, theLine) ++ endif ++ ++ " get the last line so we can remove the right delim ++ let theLine = getline(bottomline) ++ ++ " if the bottomline contains only the right delim then just delete it ++ if theLine =~ '^[ \t]*' . right . '[ \t]*$' ++ call cursor(bottomline, 1) ++ normal dd ++ ++ " the last line contains more than the right delim ++ else ++ " remove the right delim. If there is a space after it and ++ " if the appropriate options are set then remove this too. ++ let delimIndx = s:LastIndexOfDelim(rightUnEsc, theLine) ++ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)) ++ endif ++ ++ " if the last line also starts with a sexy comment marker then we ++ " remove this as well ++ if theLine =~ '^[ \t]*' . sexyComMarker ++ ++ " remove the sexyComMarker. If there is a space after it then ++ " remove that too ++ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) ++ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) ++ else ++ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) ++ endif ++ endif ++ ++ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) ++ call setline(bottomline, theLine) ++ endif ++endfunction ++ ++" Function: s:UncommentLineNormal(line) {{{2 ++" uncomments the given line and returns the result ++" Args: ++" -line: the line to uncomment ++function s:UncommentLineNormal(line) ++ let line = a:line ++ ++ "get the comment status on the line so we know how it is commented ++ let lineCommentStatus = s:IsCommentedOuttermost(b:leftAlt, b:rightAlt, b:left, b:right, line) ++ ++ "it is commented with b:left and b:right so remove these delims ++ if lineCommentStatus == 1 ++ let line = s:RemoveDelimiters(b:leftAlt, b:rightAlt, line) ++ ++ "it is commented with b:leftAlt and b:rightAlt so remove these delims ++ elseif lineCommentStatus == 2 && g:NERDRemoveAltComs ++ let line = s:RemoveDelimiters(b:left, b:right, line) ++ ++ "it is not properly commented with any delims so we check if it has ++ "any random left or right delims on it and remove the outtermost ones ++ else ++ "get the positions of all delim types on the line ++ let indxLeft = s:FindDelimiterIndex(b:left, line) ++ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line) ++ let indxRight = s:FindDelimiterIndex(b:right, line) ++ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line) ++ ++ "remove the outter most left comment delim ++ if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1) ++ let line = s:ReplaceLeftMostDelim(b:left, '', line) ++ elseif indxLeftAlt != -1 ++ let line = s:ReplaceLeftMostDelim(b:leftAlt, '', line) ++ endif ++ ++ "remove the outter most right comment delim ++ if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1) ++ let line = s:ReplaceRightMostDelim(b:right, '', line) ++ elseif indxRightAlt != -1 ++ let line = s:ReplaceRightMostDelim(b:rightAlt, '', line) ++ endif ++ endif ++ ++ ++ let indxLeft = s:FindDelimiterIndex(b:left, line) ++ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line) ++ let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line) ++ ++ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) ++ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line) ++ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) ++ ++ let right = b:right ++ let left = b:left ++ if !s:Multipart() ++ let right = b:rightAlt ++ let left = b:leftAlt ++ endif ++ ++ ++ "if there are place-holders on the line then we check to see if they are ++ "the outtermost delimiters on the line. If so then we replace them with ++ "real delimiters ++ if indxLeftPlace != -1 ++ if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) ++ endif ++ elseif indxRightPlace != -1 ++ if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) ++ endif ++ ++ endif ++ ++ let line = s:ConvertLeadingWhiteSpace(line) ++ ++ return line ++endfunction ++ ++" Function: s:UncommentLinesNormal(topline, bottomline) {{{2 ++" This function is called to uncomment lines that arent a sexy comment ++" Args: ++" -topline/bottomline: the top/bottom line numbers of the comment ++function s:UncommentLinesNormal(topline, bottomline) ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ let line = getline(currentLine) ++ call setline(currentLine, s:UncommentLineNormal(line)) ++ let currentLine = currentLine + 1 ++ endwhile ++endfunction ++ ++ ++" Section: Other helper functions {{{1 ++" ============================================================================ ++ ++" Function: s:AddLeftDelim(delim, theLine) {{{2 ++" Args: ++function s:AddLeftDelim(delim, theLine) ++ return substitute(a:theLine, '^\([ \t]*\)', '\1' . a:delim, '') ++endfunction ++ ++" Function: s:AddLeftDelimAligned(delim, theLine) {{{2 ++" Args: ++function s:AddLeftDelimAligned(delim, theLine, alignIndx) ++ ++ "if the line is not long enough then bung some extra spaces on the front ++ "so we can align the delim properly ++ let theLine = a:theLine ++ if strlen(theLine) < a:alignIndx ++ let theLine = strpart(s:spaces, 0, a:alignIndx - strlen(theLine)) ++ endif ++ ++ return strpart(theLine, 0, a:alignIndx) . a:delim . strpart(theLine, a:alignIndx) ++endfunction ++ ++" Function: s:AddRightDelim(delim, theLine) {{{2 ++" Args: ++function s:AddRightDelim(delim, theLine) ++ if a:delim == '' ++ return a:theLine ++ else ++ return substitute(a:theLine, '$', a:delim, '') ++ endif ++endfunction ++ ++" Function: s:AddRightDelimAligned(delim, theLine, alignIndx) {{{2 ++" Args: ++function s:AddRightDelimAligned(delim, theLine, alignIndx) ++ if a:delim == "" ++ return a:theLine ++ else ++ ++ " when we align the right delim we are just adding spaces ++ " so we get a string containing the needed spaces (it ++ " could be empty) ++ let extraSpaces = '' ++ let extraSpaces = strpart(s:spaces, 0, a:alignIndx-strlen(a:theLine)) ++ ++ " add the right delim ++ return substitute(a:theLine, '$', extraSpaces . a:delim, '') ++ endif ++endfunction ++ ++" Function: s:AltMultipart() {{{2 ++" returns 1 if the alternative delims are multipart ++function s:AltMultipart() ++ return b:rightAlt != '' ++endfunction ++ ++" Function: s:CanCommentLine(forceNested, line) {{{2 ++"This function is used to determine whether the given line can be commented. ++"It returns 1 if it can be and 0 otherwise ++" ++" Args: ++" -forceNested: a flag indicating whether the caller wants comments to be nested ++" if the current line is already commented ++" -lineNum: the line num of the line to check for commentability ++function s:CanCommentLine(forceNested, lineNum) ++ let theLine = getline(a:lineNum) ++ ++ " make sure we don't comment lines that are just spaces or tabs or empty. ++ if theLine =~ "^[ \t]*$" ++ return 0 ++ endif ++ ++ "if the line is part of a sexy comment then just flag it... ++ if s:IsInSexyComment(a:lineNum) ++ return 0 ++ endif ++ ++ let isCommented = s:IsCommentedNormOrSexy(a:lineNum) ++ ++ "if the line isnt commented return true ++ if !isCommented ++ return 1 ++ endif ++ ++ "if the line is commented but nesting is allowed then return true ++ if a:forceNested && (!s:Multipart() || g:NERDUsePlaceHolders) ++ return 1 ++ endif ++ ++ return 0 ++endfunction ++ ++" Function: s:CanPlaceCursor(line, col) {{{2 ++" returns 1 if the cursor can be placed exactly in the given position ++function s:CanPlaceCursor(line, col) ++ let c = col(".") ++ let l = line(".") ++ call cursor(a:line, a:col) ++ let success = (line(".") == a:line && col(".") == a:col) ++ call cursor(l,c) ++ return success ++endfunction ++ ++" Function: s:CanSexyCommentLines(topline, bottomline) {{{2 ++" Return: 1 if the given lines can be commented sexually, 0 otherwise ++function s:CanSexyCommentLines(topline, bottomline) ++ " see if the selected regions have any sexy comments ++ let currentLine = a:topline ++ while(currentLine <= a:bottomline) ++ if s:IsInSexyComment(currentLine) ++ return 0 ++ endif ++ let currentLine = currentLine + 1 ++ endwhile ++ return 1 ++endfunction ++" Function: s:CanToggleCommentLine(forceNested, line) {{{2 ++"This function is used to determine whether the given line can be toggle commented. ++"It returns 1 if it can be and 0 otherwise ++" ++" Args: ++" -lineNum: the line num of the line to check for commentability ++function s:CanToggleCommentLine(forceNested, lineNum) ++ let theLine = getline(a:lineNum) ++ if (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)) && !a:forceNested ++ return 0 ++ endif ++ ++ " make sure we don't comment lines that are just spaces or tabs or empty. ++ if theLine =~ "^[ \t]*$" ++ return 0 ++ endif ++ ++ "if the line is part of a sexy comment then just flag it... ++ if s:IsInSexyComment(a:lineNum) ++ return 0 ++ endif ++ ++ return 1 ++endfunction ++ ++" Function: s:ConvertLeadingSpacesToTabs(line) {{{2 ++" This function takes a line and converts all leading tabs on that line into ++" spaces ++" ++" Args: ++" -line: the line whose leading tabs will be converted ++function s:ConvertLeadingSpacesToTabs(line) ++ let toReturn = a:line ++ while toReturn =~ '^\t*' . s:TabSpace() . '\(.*\)$' ++ let toReturn = substitute(toReturn, '^\(\t*\)' . s:TabSpace() . '\(.*\)$' , '\1\t\2' , "") ++ endwhile ++ ++ return toReturn ++endfunction ++ ++ ++" Function: s:ConvertLeadingTabsToSpaces(line) {{{2 ++" This function takes a line and converts all leading spaces on that line into ++" tabs ++" ++" Args: ++" -line: the line whose leading spaces will be converted ++function s:ConvertLeadingTabsToSpaces(line) ++ let toReturn = a:line ++ while toReturn =~ '^\( *\)\t' ++ let toReturn = substitute(toReturn, '^\( *\)\t', '\1' . s:TabSpace() , "") ++ endwhile ++ ++ return toReturn ++endfunction ++ ++" Function: s:ConvertLeadingWhiteSpace(line) {{{2 ++" Converts the leading white space to tabs/spaces depending on &ts ++" ++" Args: ++" -line: the line to convert ++function s:ConvertLeadingWhiteSpace(line) ++ let toReturn = a:line ++ while toReturn =~ '^ *\t' ++ let toReturn = substitute(toReturn, '^ *\zs\t\ze', s:TabSpace(), "g") ++ endwhile ++ ++ if !&expandtab ++ let toReturn = s:ConvertLeadingSpacesToTabs(toReturn) ++ endif ++ ++ return toReturn ++endfunction ++ ++ ++" Function: s:CountNonESCedOccurances(str, searchstr, escChar) {{{2 ++" This function counts the number of substrings contained in another string. ++" These substrings are only counted if they are not escaped with escChar ++" Args: ++" -str: the string to look for searchstr in ++" -searchstr: the substring to search for in str ++" -escChar: the escape character which, when preceding an instance of ++" searchstr, will cause it not to be counted ++function s:CountNonESCedOccurances(str, searchstr, escChar) ++ "get the index of the first occurrence of searchstr ++ let indx = stridx(a:str, a:searchstr) ++ ++ "if there is an instance of searchstr in str process it ++ if indx != -1 ++ "get the remainder of str after this instance of searchstr is removed ++ let lensearchstr = strlen(a:searchstr) ++ let strLeft = strpart(a:str, indx+lensearchstr) ++ ++ "if this instance of searchstr is not escaped, add one to the count ++ "and recurse. If it is escaped, just recurse ++ if !s:IsEscaped(a:str, indx, a:escChar) ++ return 1 + s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) ++ else ++ return s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) ++ endif ++ endif ++endfunction ++" Function: s:DoesBlockHaveDelim(delim, top, bottom) {{{2 ++" Returns 1 if the given block of lines has a delimiter (a:delim) in it ++" Args: ++" -delim: the comment delimiter to check the block for ++" -top: the top line number of the block ++" -bottom: the bottom line number of the block ++function s:DoesBlockHaveDelim(delim, top, bottom) ++ let currentLine = a:top ++ while currentLine < a:bottom ++ let theline = getline(currentLine) ++ if s:FindDelimiterIndex(a:delim, theline) != -1 ++ return 1 ++ endif ++ let currentLine = currentLine + 1 ++ endwhile ++ return 0 ++endfunction ++ ++" Function: s:DoesBlockHaveMultipartDelim(top, bottom) {{{2 ++" Returns 1 if the given block has a >= 1 multipart delimiter in it ++" Args: ++" -top: the top line number of the block ++" -bottom: the bottom line number of the block ++function s:DoesBlockHaveMultipartDelim(top, bottom) ++ if s:HasMultipartDelims() ++ if s:Multipart() ++ return s:DoesBlockHaveDelim(b:left, a:top, a:bottom) || s:DoesBlockHaveDelim(b:right, a:top, a:bottom) ++ else ++ return s:DoesBlockHaveDelim(b:leftAlt, a:top, a:bottom) || s:DoesBlockHaveDelim(b:rightAlt, a:top, a:bottom) ++ endif ++ endif ++ return 0 ++endfunction ++ ++ ++" Function: s:Esc(str) {{{2 ++" Escapes all the tricky chars in the given string ++function s:Esc(str) ++ let charsToEsc = '*/\."&$+' ++ return escape(a:str, charsToEsc) ++endfunction ++ ++" Function: s:FindDelimiterIndex(delimiter, line) {{{2 ++" This function is used to get the string index of the input comment delimiter ++" on the input line. If no valid comment delimiter is found in the line then ++" -1 is returned ++" Args: ++" -delimiter: the delimiter we are looking to find the index of ++" -line: the line we are looking for delimiter on ++function s:FindDelimiterIndex(delimiter, line) ++ ++ "make sure the delimiter isnt empty otherwise we go into an infinite loop. ++ if a:delimiter == "" ++ return -1 ++ endif ++ ++ ++ let l:delimiter = a:delimiter ++ let lenDel = strlen(l:delimiter) ++ ++ "get the index of the first occurrence of the delimiter ++ let delIndx = stridx(a:line, l:delimiter) ++ ++ "keep looping thru the line till we either find a real comment delimiter ++ "or run off the EOL ++ while delIndx != -1 ++ ++ "if we are not off the EOL get the str before the possible delimiter ++ "in question and check if it really is a delimiter. If it is, return ++ "its position ++ if delIndx != -1 ++ if s:IsDelimValid(l:delimiter, delIndx, a:line) ++ return delIndx ++ endif ++ endif ++ ++ "we have not yet found a real comment delimiter so move past the ++ "current one we are lookin at ++ let restOfLine = strpart(a:line, delIndx + lenDel) ++ let distToNextDelim = stridx(restOfLine , l:delimiter) ++ ++ "if distToNextDelim is -1 then there is no more potential delimiters ++ "on the line so set delIndx to -1. Otherwise, move along the line by ++ "distToNextDelim ++ if distToNextDelim == -1 ++ let delIndx = -1 ++ else ++ let delIndx = delIndx + lenDel + distToNextDelim ++ endif ++ endwhile ++ ++ "there is no comment delimiter on this line ++ return -1 ++endfunction ++ ++" Function: s:FindBoundingLinesOfSexyCom(lineNum) {{{2 ++" This function takes in a line number and tests whether this line number is ++" the top/bottom/middle line of a sexy comment. If it is then the top/bottom ++" lines of the sexy comment are returned ++" Args: ++" -lineNum: the line number that is to be tested whether it is the ++" top/bottom/middle line of a sexy com ++" Returns: ++" A string that has the top/bottom lines of the sexy comment encoded in it. ++" The format is 'topline,bottomline'. If a:lineNum turns out not to be the ++" top/bottom/middle of a sexy comment then -1 is returned ++function s:FindBoundingLinesOfSexyCom(lineNum) ++ ++ "find which delimiters to look for as the start/end delims of the comment ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = s:GetLeft(0,0,1) ++ let right = s:GetRight(0,0,1) ++ elseif s:AltMultipart() ++ let left = s:GetLeft(1,0,1) ++ let right = s:GetRight(1,0,1) ++ else ++ return [] ++ endif ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ ++ "initialise the top/bottom line numbers of the sexy comment to -1 ++ let top = -1 ++ let bottom = -1 ++ ++ let currentLine = a:lineNum ++ while top == -1 || bottom == -1 ++ let theLine = getline(currentLine) ++ ++ "check if the current line is the top of the sexy comment ++ if theLine =~ '^[ \t]*' . left && theLine !~ '.*' . right ++ let top = currentLine ++ let currentLine = a:lineNum ++ ++ "check if the current line is the bottom of the sexy comment ++ elseif theLine =~ '^[ \t]*' . right && theLine !~ '.*' . left ++ let bottom = currentLine ++ ++ "the right delimiter is on the same line as the last sexyComMarker ++ elseif theLine =~ '^[ \t]*' . sexyComMarker . '.*' . right ++ let bottom = currentLine ++ ++ "we have not found the top or bottom line so we assume currentLine is an ++ "intermediate line and look to prove otherwise ++ else ++ ++ "if the line doesnt start with a sexyComMarker then it is not a sexy ++ "comment ++ if theLine !~ '^[ \t]*' . sexyComMarker ++ return [] ++ endif ++ ++ endif ++ ++ "if top is -1 then we havent found the top yet so keep looking up ++ if top == -1 ++ let currentLine = currentLine - 1 ++ "if we have found the top line then go down looking for the bottom ++ else ++ let currentLine = currentLine + 1 ++ endif ++ ++ endwhile ++ ++ return [top, bottom] ++endfunction ++ ++ ++" Function: s:GetLeft(alt, space, esc) {{{2 ++" returns the left/left-alternative delimiter ++" Args: ++" -alt: specifies whether to get left or left-alternative delim ++" -space: specifies whether the delim should be spaced or not ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the delim should be ESCed ++function s:GetLeft(alt, space, esc) ++ let delim = b:left ++ ++ if a:alt ++ if b:leftAlt == '' ++ return '' ++ else ++ let delim = b:leftAlt ++ endif ++ endif ++ if delim == '' ++ return '' ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let delim = delim . s:spaceStr ++ endif ++ ++ if a:esc ++ let delim = s:Esc(delim) ++ endif ++ ++ return delim ++endfunction ++ ++" Function: s:GetRight(alt, space, esc) {{{2 ++" returns the right/right-alternative delimiter ++" Args: ++" -alt: specifies whether to get right or right-alternative delim ++" -space: specifies whether the delim should be spaced or not ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the delim should be ESCed ++function s:GetRight(alt, space, esc) ++ let delim = b:right ++ ++ if a:alt ++ if !s:AltMultipart() ++ return '' ++ else ++ let delim = b:rightAlt ++ endif ++ endif ++ if delim == '' ++ return '' ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let delim = s:spaceStr . delim ++ endif ++ ++ if a:esc ++ let delim = s:Esc(delim) ++ endif ++ ++ return delim ++endfunction ++ ++ ++" Function: s:GetSexyComMarker() {{{2 ++" Returns the sexy comment marker for the current filetype. ++" ++" C style sexy comments are assumed if possible. If not then the sexy comment ++" marker is the last char of the delimiter pair that has both left and right ++" delims and has the longest left delim ++" ++" Args: ++" -space: specifies whether the marker is to have a space string after it ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the marker are to be ESCed ++function s:GetSexyComMarker(space, esc) ++ let sexyComMarker = b:sexyComMarker ++ ++ "if there is no hardcoded marker then we find one ++ if sexyComMarker == '' ++ ++ "if the filetype has c style comments then use standard c sexy ++ "comments ++ if s:HasCStyleComments() ++ let sexyComMarker = '*' ++ else ++ "find a comment marker by getting the longest available left delim ++ "(that has a corresponding right delim) and taking the last char ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let left = '' ++ let right = '' ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let left = b:left ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ else ++ return -1 ++ endif ++ ++ "get the last char of left ++ let sexyComMarker = strpart(left, strlen(left)-1) ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let sexyComMarker = sexyComMarker . s:spaceStr ++ endif ++ ++ if a:esc ++ let sexyComMarker = s:Esc(sexyComMarker) ++ endif ++ ++ return sexyComMarker ++endfunction ++ ++" Function: s:GetSexyComLeft(space, esc) {{{2 ++" Returns the left delimiter for sexy comments for this filetype or -1 if ++" there is none. C style sexy comments are used if possible ++" Args: ++" -space: specifies if the delim has a space string on the end ++" (the space string will only be added if NERDSpaceDelims is set) ++" -esc: specifies whether the tricky chars in the string are ESCed ++function s:GetSexyComLeft(space, esc) ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let left = '' ++ ++ "assume c style sexy comments if possible ++ if s:HasCStyleComments() ++ let left = '/*' ++ else ++ "grab the longest left delim that has a right ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let left = b:left ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ else ++ return -1 ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let left = left . s:spaceStr ++ endif ++ ++ if a:esc ++ let left = s:Esc(left) ++ endif ++ ++ return left ++endfunction ++ ++" Function: s:GetSexyComRight(space, esc) {{{2 ++" Returns the right delimiter for sexy comments for this filetype or -1 if ++" there is none. C style sexy comments are used if possible. ++" Args: ++" -space: specifies if the delim has a space string on the start ++" (the space string will only be added if NERDSpaceDelims ++" is specified for the current filetype) ++" -esc: specifies whether the tricky chars in the string are ESCed ++function s:GetSexyComRight(space, esc) ++ let lenLeft = strlen(b:left) ++ let lenLeftAlt = strlen(b:leftAlt) ++ let right = '' ++ ++ "assume c style sexy comments if possible ++ if s:HasCStyleComments() ++ let right = '*/' ++ else ++ "grab the right delim that pairs with the longest left delim ++ if s:Multipart() && lenLeft >= lenLeftAlt ++ let right = b:right ++ elseif s:AltMultipart() ++ let right = b:rightAlt ++ else ++ return -1 ++ endif ++ endif ++ ++ if a:space && g:NERDSpaceDelims ++ let right = s:spaceStr . right ++ endif ++ ++ if a:esc ++ let right = s:Esc(right) ++ endif ++ ++ return right ++endfunction ++ ++" Function: s:HasMultipartDelims() {{{2 ++" Returns 1 iff the current filetype has at least one set of multipart delims ++function s:HasMultipartDelims() ++ return s:Multipart() || s:AltMultipart() ++endfunction ++ ++" Function: s:HasLeadingTabs(...) {{{2 ++" Returns 1 if any of the given strings have leading tabs ++function s:HasLeadingTabs(...) ++ for s in a:000 ++ if s =~ '^\t.*' ++ return 1 ++ end ++ endfor ++ return 0 ++endfunction ++" Function: s:HasCStyleComments() {{{2 ++" Returns 1 iff the current filetype has c style comment delimiters ++function s:HasCStyleComments() ++ return (b:left == '/*' && b:right == '*/') || (b:leftAlt == '/*' && b:rightAlt == '*/') ++endfunction ++ ++" Function: s:InstallDocumentation(full_name, revision) {{{2 ++" Install help documentation. ++" Arguments: ++" full_name: Full name of this vim plugin script, including path name. ++" revision: Revision of the vim script. #version# mark in the document file ++" will be replaced with this string with 'v' prefix. ++" Return: ++" 1 if new document installed, 0 otherwise. ++" Note: Cleaned and generalized by guo-peng Wen. ++" ++" Note about authorship: this function was taken from the vimspell plugin ++" which can be found at http://www.vim.org/scripts/script.php?script_id=465 ++" ++function s:InstallDocumentation(full_name, revision) ++ " Name of the document path based on the system we use: ++ if has("vms") ++ " No chance that this script will work with ++ " VMS - to much pathname juggling here. ++ return 1 ++ elseif (has("unix")) ++ " On UNIX like system, using forward slash: ++ let l:slash_char = '/' ++ let l:mkdir_cmd = ':silent !mkdir -p ' ++ else ++ " On M$ system, use backslash. Also mkdir syntax is different. ++ " This should only work on W2K and up. ++ let l:slash_char = '\' ++ let l:mkdir_cmd = ':silent !mkdir ' ++ endif ++ ++ let l:doc_path = l:slash_char . 'doc' ++ let l:doc_home = l:slash_char . '.vim' . l:slash_char . 'doc' ++ ++ " Figure out document path based on full name of this script: ++ let l:vim_plugin_path = fnamemodify(a:full_name, ':h') ++ let l:vim_doc_path = fnamemodify(a:full_name, ':h:h') . l:doc_path ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ "Doc path: " . l:vim_doc_path ++ call s:NerdEcho("Doc path: " . l:vim_doc_path, 0) ++ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ " Try a default configuration in user home: ++ let l:vim_doc_path = expand("~") . l:doc_home ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' ++ if (!(filewritable(l:vim_doc_path) == 2)) ++ " Put a warning: ++ call s:NerdEcho("Unable to open documentation directory \ntype :help add-local-help for more information.", 0) ++ echo l:vim_doc_path ++ return 0 ++ endif ++ endif ++ endif ++ endif ++ ++ " Exit if we have problem to access the document directory: ++ if (!isdirectory(l:vim_plugin_path) || !isdirectory(l:vim_doc_path) || filewritable(l:vim_doc_path) != 2) ++ return 0 ++ endif ++ ++ " Full name of script and documentation file: ++ let l:script_name = fnamemodify(a:full_name, ':t') ++ let l:doc_name = fnamemodify(a:full_name, ':t:r') . '.txt' ++ let l:plugin_file = l:vim_plugin_path . l:slash_char . l:script_name ++ let l:doc_file = l:vim_doc_path . l:slash_char . l:doc_name ++ ++ " Bail out if document file is still up to date: ++ if (filereadable(l:doc_file) && getftime(l:plugin_file) < getftime(l:doc_file)) ++ return 0 ++ endif ++ ++ " Prepare window position restoring command: ++ if (strlen(@%)) ++ let l:go_back = 'b ' . bufnr("%") ++ else ++ let l:go_back = 'enew!' ++ endif ++ ++ " Create a new buffer & read in the plugin file (me): ++ setl nomodeline ++ exe 'enew!' ++ exe 'r ' . escape(l:plugin_file,s:NERDFileNameEscape) ++ ++ setl modeline ++ let l:buf = bufnr("%") ++ setl noswapfile modifiable ++ ++ norm zR ++ norm gg ++ ++ " Delete from first line to a line starts with ++ " === START_DOC ++ 1,/^=\{3,}\s\+START_DOC\C/ d ++ ++ " Delete from a line starts with ++ " === END_DOC ++ " to the end of the documents: ++ /^=\{3,}\s\+END_DOC\C/,$ d ++ ++ " Remove fold marks: ++ :%s/{\{3}[1-9]/ / ++ ++ " Add modeline for help doc: the modeline string is mangled intentionally ++ " to avoid it be recognized by VIM: ++ call append(line('$'), '') ++ call append(line('$'), ' v' . 'im:tw=78:ts=8:ft=help:norl:') ++ ++ " Replace revision: ++ "exe "normal :1s/#version#/ v" . a:revision . "/\" ++ exe "normal :%s/#version#/ v" . a:revision . "/\" ++ ++ " Save the help document: ++ exe 'w! ' . escape(l:doc_file,s:NERDFileNameEscape) ++ exe l:go_back ++ exe 'bw ' . l:buf ++ ++ " Build help tags: ++ exe 'helptags ' . escape(l:vim_doc_path,s:NERDFileNameEscape) ++ ++ return 1 ++endfunction ++ ++ ++" Function: s:IsCommentedNormOrSexy(lineNum) {{{2 ++"This function is used to determine whether the given line is commented with ++"either set of delimiters or if it is part of a sexy comment ++" ++" Args: ++" -lineNum: the line number of the line to check ++function s:IsCommentedNormOrSexy(lineNum) ++ let theLine = getline(a:lineNum) ++ ++ "if the line is commented normally return 1 ++ if s:IsCommented(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine) ++ return 1 ++ endif ++ ++ "if the line is part of a sexy comment return 1 ++ if s:IsInSexyComment(a:lineNum) ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Function: s:IsCommented(left, right, line) {{{2 ++"This function is used to determine whether the given line is commented with ++"the given delimiters ++" ++" Args: ++" -line: the line that to check if commented ++" -left/right: the left and right delimiters to check for ++function s:IsCommented(left, right, line) ++ "if the line isnt commented return true ++ if s:FindDelimiterIndex(a:left, a:line) != -1 && (s:FindDelimiterIndex(a:right, a:line) != -1 || !s:Multipart()) ++ return 1 ++ endif ++ return 0 ++endfunction ++ ++" Function: s:IsCommentedFromStartOfLine(left, line) {{{2 ++"This function is used to determine whether the given line is commented with ++"the given delimiters at the start of the line i.e the left delimiter is the ++"first thing on the line (apart from spaces\tabs) ++" ++" Args: ++" -line: the line that to check if commented ++" -left: the left delimiter to check for ++function s:IsCommentedFromStartOfLine(left, line) ++ let theLine = s:ConvertLeadingTabsToSpaces(a:line) ++ let numSpaces = strlen(substitute(theLine, '^\( *\).*$', '\1', '')) ++ let delimIndx = s:FindDelimiterIndex(a:left, theLine) ++ return delimIndx == numSpaces ++endfunction ++ ++" Function: s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) {{{2 ++" Finds the type of the outtermost delims on the line ++" ++" Args: ++" -line: the line that to check if the outtermost comments on it are ++" left/right ++" -left/right: the left and right delimiters to check for ++" -leftAlt/rightAlt: the left and right alternative delimiters to check for ++" ++" Returns: ++" 0 if the line is not commented with either set of delims ++" 1 if the line is commented with the left/right delim set ++" 2 if the line is commented with the leftAlt/rightAlt delim set ++function s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) ++ "get the first positions of the left delims and the last positions of the ++ "right delims ++ let indxLeft = s:FindDelimiterIndex(a:left, a:line) ++ let indxLeftAlt = s:FindDelimiterIndex(a:leftAlt, a:line) ++ let indxRight = s:LastIndexOfDelim(a:right, a:line) ++ let indxRightAlt = s:LastIndexOfDelim(a:rightAlt, a:line) ++ ++ "check if the line has a left delim before a leftAlt delim ++ if (indxLeft <= indxLeftAlt || indxLeftAlt == -1) && indxLeft != -1 ++ "check if the line has a right delim after any rightAlt delim ++ if (indxRight > indxRightAlt && indxRight > indxLeft) || !s:Multipart() ++ return 1 ++ endif ++ ++ "check if the line has a leftAlt delim before a left delim ++ elseif (indxLeftAlt <= indxLeft || indxLeft == -1) && indxLeftAlt != -1 ++ "check if the line has a rightAlt delim after any right delim ++ if (indxRightAlt > indxRight && indxRightAlt > indxLeftAlt) || !s:AltMultipart() ++ return 2 ++ endif ++ else ++ return 0 ++ endif ++ ++ return 0 ++ ++endfunction ++ ++ ++" Function: s:IsDelimValid(delimiter, delIndx, line) {{{2 ++" This function is responsible for determining whether a given instance of a ++" comment delimiter is a real delimiter or not. For example, in java the ++" // string is a comment delimiter but in the line: ++" System.out.println("//"); ++" it does not count as a comment delimiter. This function is responsible for ++" distinguishing between such cases. It does so by applying a set of ++" heuristics that are not fool proof but should work most of the time. ++" ++" Args: ++" -delimiter: the delimiter we are validating ++" -delIndx: the position of delimiter in line ++" -line: the line that delimiter occurs in ++" ++" Returns: ++" 0 if the given delimiter is not a real delimiter (as far as we can tell) , ++" 1 otherwise ++function s:IsDelimValid(delimiter, delIndx, line) ++ "get the delimiter without the escchars ++ let l:delimiter = a:delimiter ++ ++ "get the strings before and after the delimiter ++ let preComStr = strpart(a:line, 0, a:delIndx) ++ let postComStr = strpart(a:line, a:delIndx+strlen(delimiter)) ++ ++ "to check if the delimiter is real, make sure it isnt preceded by ++ "an odd number of quotes and followed by the same (which would indicate ++ "that it is part of a string and therefore is not a comment) ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '"', "\\")) ++ return 0 ++ endif ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "'", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "'", "\\")) ++ return 0 ++ endif ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "`", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "`", "\\")) ++ return 0 ++ endif ++ ++ ++ "if the comment delimiter is escaped, assume it isnt a real delimiter ++ if s:IsEscaped(a:line, a:delIndx, "\\") ++ return 0 ++ endif ++ ++ "vim comments are so fuckin stupid!! Why the hell do they have comment ++ "delimiters that are used elsewhere in the syntax?!?! We need to check ++ "some conditions especially for vim ++ if &filetype == "vim" ++ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) ++ return 0 ++ endif ++ ++ "if the delimiter is on the very first char of the line or is the ++ "first non-tab/space char on the line then it is a valid comment delimiter ++ if a:delIndx == 0 || a:line =~ "^[ \t]\\{" . a:delIndx . "\\}\".*$" ++ return 1 ++ endif ++ ++ let numLeftParen =s:CountNonESCedOccurances(preComStr, "(", "\\") ++ let numRightParen =s:CountNonESCedOccurances(preComStr, ")", "\\") ++ ++ "if the quote is inside brackets then assume it isnt a comment ++ if numLeftParen > numRightParen ++ return 0 ++ endif ++ ++ "if the line has an even num of unescaped "'s then we can assume that ++ "any given " is not a comment delimiter ++ if s:IsNumEven(s:CountNonESCedOccurances(a:line, "\"", "\\")) ++ return 0 ++ endif ++ endif ++ ++ return 1 ++ ++endfunction ++ ++" Function: s:IsNumEven(num) {{{2 ++" A small function the returns 1 if the input number is even and 0 otherwise ++" Args: ++" -num: the number to check ++function s:IsNumEven(num) ++ return (a:num % 2) == 0 ++endfunction ++ ++" Function: s:IsEscaped(str, indx, escChar) {{{2 ++" This function takes a string, an index into that string and an esc char and ++" returns 1 if the char at the index is escaped (i.e if it is preceded by an ++" odd number of esc chars) ++" Args: ++" -str: the string to check ++" -indx: the index into str that we want to check ++" -escChar: the escape char the char at indx may be ESCed with ++function s:IsEscaped(str, indx, escChar) ++ "initialise numEscChars to 0 and look at the char before indx ++ let numEscChars = 0 ++ let curIndx = a:indx-1 ++ ++ "keep going back thru str until we either reach the start of the str or ++ "run out of esc chars ++ while curIndx >= 0 && strpart(a:str, curIndx, 1) == a:escChar ++ ++ "we have found another esc char so add one to the count and move left ++ "one char ++ let numEscChars = numEscChars + 1 ++ let curIndx = curIndx - 1 ++ ++ endwhile ++ ++ "if there is an odd num of esc chars directly before the char at indx then ++ "the char at indx is escaped ++ return !s:IsNumEven(numEscChars) ++endfunction ++ ++" Function: s:IsInSexyComment(line) {{{2 ++" returns 1 if the given line number is part of a sexy comment ++function s:IsInSexyComment(line) ++ return !empty(s:FindBoundingLinesOfSexyCom(a:line)) ++endfunction ++ ++" Function: s:IsSexyComment(topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns 1 if the lines between and ++" including the given line numbers are a sexy comment. It returns 0 otherwise. ++" Args: ++" -topline: the line that the possible sexy comment starts on ++" -bottomline: the line that the possible sexy comment stops on ++function s:IsSexyComment(topline, bottomline) ++ ++ "get the delim set that would be used for a sexy comment ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = b:left ++ let right = b:right ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ let right = b:rightAlt ++ else ++ return 0 ++ endif ++ ++ "swap the top and bottom line numbers around if need be ++ let topline = a:topline ++ let bottomline = a:bottomline ++ if bottomline < topline ++ topline = bottomline ++ bottomline = a:topline ++ endif ++ ++ "if there is < 2 lines in the comment it cannot be sexy ++ if (bottomline - topline) <= 0 ++ return 0 ++ endif ++ ++ "if the top line doesnt begin with a left delim then the comment isnt sexy ++ if getline(a:topline) !~ '^[ \t]*' . left ++ return 0 ++ endif ++ ++ "if there is a right delim on the top line then this isnt a sexy comment ++ if s:FindDelimiterIndex(right, getline(a:topline)) != -1 ++ return 0 ++ endif ++ ++ "if there is a left delim on the bottom line then this isnt a sexy comment ++ if s:FindDelimiterIndex(left, getline(a:bottomline)) != -1 ++ return 0 ++ endif ++ ++ "if the bottom line doesnt begin with a right delim then the comment isnt ++ "sexy ++ if getline(a:bottomline) !~ '^.*' . right . '$' ++ return 0 ++ endif ++ ++ let sexyComMarker = s:GetSexyComMarker(0, 1) ++ ++ "check each of the intermediate lines to make sure they start with a ++ "sexyComMarker ++ let currentLine = a:topline+1 ++ while currentLine < a:bottomline ++ let theLine = getline(currentLine) ++ ++ if theLine !~ '^[ \t]*' . sexyComMarker ++ return 0 ++ endif ++ ++ "if there is a right delim in an intermediate line then the block isnt ++ "a sexy comment ++ if s:FindDelimiterIndex(right, theLine) != -1 ++ return 0 ++ endif ++ ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ "we have not found anything to suggest that this isnt a sexy comment so ++ return 1 ++ ++endfunction ++ ++" Function: s:LastIndexOfDelim(delim, str) {{{2 ++" This function takes a string and a delimiter and returns the last index of ++" that delimiter in string ++" Args: ++" -delim: the delimiter to look for ++" -str: the string to look for delim in ++function s:LastIndexOfDelim(delim, str) ++ let delim = a:delim ++ let lenDelim = strlen(delim) ++ ++ "set index to the first occurrence of delim. If there is no occurrence then ++ "bail ++ let indx = s:FindDelimiterIndex(delim, a:str) ++ if indx == -1 ++ return -1 ++ endif ++ ++ "keep moving to the next instance of delim in str till there is none left ++ while 1 ++ ++ "search for the next delim after the previous one ++ let searchStr = strpart(a:str, indx+lenDelim) ++ let indx2 = s:FindDelimiterIndex(delim, searchStr) ++ ++ "if we find a delim update indx to record the position of it, if we ++ "dont find another delim then indx is the last one so break out of ++ "this loop ++ if indx2 != -1 ++ let indx = indx + indx2 + lenDelim ++ else ++ break ++ endif ++ endwhile ++ ++ return indx ++ ++endfunction ++ ++" Function: s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns the index of the left most ++" char (that is not a space or a tab) on all of these lines. ++" Args: ++" -countCommentedLines: 1 if lines that are commented are to be checked as ++" well. 0 otherwise ++" -countEmptyLines: 1 if empty lines are to be counted in the search ++" -topline: the top line to be checked ++" -bottomline: the bottom line to be checked ++function s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) ++ ++ " declare the left most index as an extreme value ++ let leftMostIndx = 1000 ++ ++ " go thru the block line by line updating leftMostIndx ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ ++ " get the next line and if it is allowed to be commented, or is not ++ " commented, check it ++ let theLine = getline(currentLine) ++ if a:countEmptyLines || theLine !~ '^[ \t]*$' ++ if a:countCommentedLines || (!s:IsCommented(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, theLine)) ++ " convert spaces to tabs and get the number of leading spaces for ++ " this line and update leftMostIndx if need be ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let leadSpaceOfLine = strlen( substitute(theLine, '\(^[ \t]*\).*$','\1','') ) ++ if leadSpaceOfLine < leftMostIndx ++ let leftMostIndx = leadSpaceOfLine ++ endif ++ endif ++ endif ++ ++ " move on to the next line ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ if leftMostIndx == 1000 ++ return 0 ++ else ++ return leftMostIndx ++ endif ++endfunction ++ ++" Function: s:Multipart() {{{2 ++" returns 1 if the current delims are multipart ++function s:Multipart() ++ return b:right != '' ++endfunction ++ ++" Function: s:NerdEcho(msg, typeOfMsg) {{{2 ++" Args: ++" -msg: the message to echo ++" -typeOfMsg: 0 = warning message ++" 1 = normal message ++function s:NerdEcho(msg, typeOfMsg) ++ if a:typeOfMsg == 0 ++ echohl WarningMsg ++ echo 'NERDCommenter:' . a:msg ++ echohl None ++ elseif a:typeOfMsg == 1 ++ echo 'NERDCommenter:' . a:msg ++ endif ++endfunction ++ ++" Function: s:NumberOfLeadingTabs(s) {{{2 ++" returns the number of leading tabs in the given string ++function s:NumberOfLeadingTabs(s) ++ return strlen(substitute(a:s, '^\(\t*\).*$', '\1', "")) ++endfunction ++ ++" Function: s:NumLinesInBuf() {{{2 ++" Returns the number of lines in the current buffer ++function s:NumLinesInBuf() ++ return line('$') ++endfunction ++ ++" Function: s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) {{{2 ++" This function takes in a string, 2 delimiters in that string and 2 strings ++" to replace these delimiters with. ++" ++" Args: ++" -toReplace1: the first delimiter to replace ++" -toReplace2: the second delimiter to replace ++" -replacor1: the string to replace toReplace1 with ++" -replacor2: the string to replace toReplace2 with ++" -str: the string that the delimiters to be replaced are in ++function s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) ++ let line = s:ReplaceLeftMostDelim(a:toReplace1, a:replacor1, a:str) ++ let line = s:ReplaceRightMostDelim(a:toReplace2, a:replacor2, line) ++ return line ++endfunction ++ ++" Function: s:ReplaceLeftMostDelim(toReplace, replacor, str) {{{2 ++" This function takes a string and a delimiter and replaces the left most ++" occurrence of this delimiter in the string with a given string ++" ++" Args: ++" -toReplace: the delimiter in str that is to be replaced ++" -replacor: the string to replace toReplace with ++" -str: the string that contains toReplace ++function s:ReplaceLeftMostDelim(toReplace, replacor, str) ++ let toReplace = a:toReplace ++ let replacor = a:replacor ++ "get the left most occurrence of toReplace ++ let indxToReplace = s:FindDelimiterIndex(toReplace, a:str) ++ ++ "if there IS an occurrence of toReplace in str then replace it and return ++ "the resulting string ++ if indxToReplace != -1 ++ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) ++ return line ++ endif ++ ++ return a:str ++endfunction ++ ++" Function: s:ReplaceRightMostDelim(toReplace, replacor, str) {{{2 ++" This function takes a string and a delimiter and replaces the right most ++" occurrence of this delimiter in the string with a given string ++" ++" Args: ++" -toReplace: the delimiter in str that is to be replaced ++" -replacor: the string to replace toReplace with ++" -str: the string that contains toReplace ++" ++function s:ReplaceRightMostDelim(toReplace, replacor, str) ++ let toReplace = a:toReplace ++ let replacor = a:replacor ++ let lenToReplace = strlen(toReplace) ++ ++ "get the index of the last delim in str ++ let indxToReplace = s:LastIndexOfDelim(toReplace, a:str) ++ ++ "if there IS a delimiter in str, replace it and return the result ++ let line = a:str ++ if indxToReplace != -1 ++ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) ++ endif ++ return line ++endfunction ++ ++"FUNCTION: s:RestoreScreenState() {{{2 ++" ++"Sets the screen state back to what it was when s:SaveScreenState was last ++"called. ++" ++function s:RestoreScreenState() ++ if !exists("t:NERDComOldTopLine") || !exists("t:NERDComOldPos") ++ throw 'NERDCommenter exception: cannot restore screen' ++ endif ++ ++ call cursor(t:NERDComOldTopLine, 0) ++ normal zt ++ call setpos(".", t:NERDComOldPos) ++endfunction ++ ++" Function: s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 ++" This function takes in 2 line numbers and returns the index of the right most ++" char on all of these lines. ++" Args: ++" -countCommentedLines: 1 if lines that are commented are to be checked as ++" well. 0 otherwise ++" -countEmptyLines: 1 if empty lines are to be counted in the search ++" -topline: the top line to be checked ++" -bottomline: the bottom line to be checked ++function s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) ++ let rightMostIndx = -1 ++ ++ " go thru the block line by line updating rightMostIndx ++ let currentLine = a:topline ++ while currentLine <= a:bottomline ++ ++ " get the next line and see if it is commentable, otherwise it doesnt ++ " count ++ let theLine = getline(currentLine) ++ if a:countEmptyLines || theLine !~ '^[ \t]*$' ++ ++ if a:countCommentedLines || (!s:IsCommented(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, theLine)) ++ ++ " update rightMostIndx if need be ++ let theLine = s:ConvertLeadingTabsToSpaces(theLine) ++ let lineLen = strlen(theLine) ++ if lineLen > rightMostIndx ++ let rightMostIndx = lineLen ++ endif ++ endif ++ endif ++ ++ " move on to the next line ++ let currentLine = currentLine + 1 ++ endwhile ++ ++ return rightMostIndx ++endfunction ++ ++"FUNCTION: s:SaveScreenState() {{{2 ++"Saves the current cursor position in the current buffer and the window ++"scroll position ++function s:SaveScreenState() ++ let t:NERDComOldPos = getpos(".") ++ let t:NERDComOldTopLine = line("w0") ++endfunction ++ ++" Function: s:SwapOutterMultiPartDelimsForPlaceHolders(line) {{{2 ++" This function takes a line and swaps the outter most multi-part delims for ++" place holders ++" Args: ++" -line: the line to swap the delims in ++" ++function s:SwapOutterMultiPartDelimsForPlaceHolders(line) ++ " find out if the line is commented using normal delims and/or ++ " alternate ones ++ let isCommented = s:IsCommented(b:left, b:right, a:line) ++ let isCommentedAlt = s:IsCommented(b:leftAlt, b:rightAlt, a:line) ++ ++ let line2 = a:line ++ ++ "if the line is commented and there is a right delimiter, replace ++ "the delims with place-holders ++ if isCommented && s:Multipart() ++ let line2 = s:ReplaceDelims(b:left, b:right, g:NERDLPlace, g:NERDRPlace, a:line) ++ ++ "similarly if the line is commented with the alternative ++ "delimiters ++ elseif isCommentedAlt && s:AltMultipart() ++ let line2 = s:ReplaceDelims(b:leftAlt, b:rightAlt, g:NERDLPlace, g:NERDRPlace, a:line) ++ endif ++ ++ return line2 ++endfunction ++ ++" Function: s:SwapOutterPlaceHoldersForMultiPartDelims(line) {{{2 ++" This function takes a line and swaps the outtermost place holders for ++" multi-part delims ++" Args: ++" -line: the line to swap the delims in ++" ++function s:SwapOutterPlaceHoldersForMultiPartDelims(line) ++ let left = '' ++ let right = '' ++ if s:Multipart() ++ let left = b:left ++ let right = b:right ++ elseif s:AltMultipart() ++ let left = b:leftAlt ++ let right = b:rightAlt ++ endif ++ ++ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, a:line) ++ return line ++endfunction ++" Function: s:TabbedCol(line, col) {{{2 ++" Gets the col number for given line and existing col number. The new col ++" number is the col number when all leading spaces are converted to tabs ++" Args: ++" -line:the line to get the rel col for ++" -col: the abs col ++function s:TabbedCol(line, col) ++ let lineTruncated = strpart(a:line, 0, a:col) ++ let lineSpacesToTabs = substitute(lineTruncated, s:TabSpace(), '\t', 'g') ++ return strlen(lineSpacesToTabs) ++endfunction ++"FUNCTION: s:TabSpace() {{{2 ++"returns a string of spaces equal in length to &tabstop ++function s:TabSpace() ++ let tabSpace = "" ++ let spacesPerTab = &tabstop ++ while spacesPerTab > 0 ++ let tabSpace = tabSpace . " " ++ let spacesPerTab = spacesPerTab - 1 ++ endwhile ++ return tabSpace ++endfunction ++ ++" Function: s:UnEsc(str, escChar) {{{2 ++" This function removes all the escape chars from a string ++" Args: ++" -str: the string to remove esc chars from ++" -escChar: the escape char to be removed ++function s:UnEsc(str, escChar) ++ return substitute(a:str, a:escChar, "", "g") ++endfunction ++ ++" Function: s:UntabbedCol(line, col) {{{2 ++" Takes a line and a col and returns the absolute column of col taking into ++" account that a tab is worth 3 or 4 (or whatever) spaces. ++" Args: ++" -line:the line to get the abs col for ++" -col: the col that doesnt take into account tabs ++function s:UntabbedCol(line, col) ++ let lineTruncated = strpart(a:line, 0, a:col) ++ let lineTabsToSpaces = substitute(lineTruncated, '\t', s:TabSpace(), 'g') ++ return strlen(lineTabsToSpaces) ++endfunction ++" Section: Comment mapping setup {{{1 ++" =========================================================================== ++" This is where the mappings calls are made that set up the commenting key ++" mappings. ++ ++" set up the mapping to switch to/from alternative delimiters ++execute 'nnoremap ' . g:NERDAltComMap . ' :call SwitchToAlternativeDelimiters(1)' ++ ++" set up the mappings to comment out lines ++execute 'nnoremap ' . g:NERDComLineMap . ' :call NERDComment(0, "norm")' ++execute 'vnoremap ' . g:NERDComLineMap . ' :call NERDComment(1, "norm")' ++ ++" set up the mappings to do toggle comments ++execute 'nnoremap ' . g:NERDComLineToggleMap . ' :call NERDComment(0, "toggle")' ++execute 'vnoremap ' . g:NERDComLineToggleMap . ' :call NERDComment(1, "toggle")' ++ ++" set up the mapp to do minimal comments ++execute 'nnoremap ' . g:NERDComLineMinimalMap . ' :call NERDComment(0, "minimal")' ++execute 'vnoremap ' . g:NERDComLineMinimalMap . ' :call NERDComment(1, "minimal")' ++ ++" set up the mappings to comment out lines sexily ++execute 'nnoremap ' . g:NERDComLineSexyMap . ' :call NERDComment(0, "sexy")' ++execute 'vnoremap ' . g:NERDComLineSexyMap . ' :call NERDComment(1, "sexy")' ++ ++" set up the mappings to do invert comments ++execute 'nnoremap ' . g:NERDComLineInvertMap . ' :call NERDComment(0, "invert")' ++execute 'vnoremap ' . g:NERDComLineInvertMap . ' :call NERDComment(1, "invert")' ++ ++" set up the mappings to yank then comment out lines ++execute 'nmap ' . g:NERDComLineYankMap . ' :call NERDComment(0, "yank")' ++execute 'vmap ' . g:NERDComLineYankMap . ' :call NERDComment(1, "yank")' ++ ++" set up the mappings for left aligned comments ++execute 'nnoremap ' . g:NERDComAlignLeftMap . ' :call NERDComment(0, "alignLeft")' ++execute 'vnoremap ' . g:NERDComAlignLeftMap . ' :call NERDComment(1, "alignLeft")' ++ ++" set up the mappings for right aligned comments ++execute 'nnoremap ' . g:NERDComAlignRightMap . ' :call NERDComment(0, "alignRight")' ++execute 'vnoremap ' . g:NERDComAlignRightMap . ' :call NERDComment(1, "alignRight")' ++ ++" set up the mappings for left and right aligned comments ++execute 'nnoremap ' . g:NERDComAlignBothMap . ' :call NERDComment(0, "alignBoth")' ++execute 'vnoremap ' . g:NERDComAlignBothMap . ' :call NERDComment(1, "alignBoth")' ++ ++" set up the mappings to do nested comments ++execute 'nnoremap ' . g:NERDComLineNestMap . ' :call NERDComment(0, "nested")' ++execute 'vnoremap ' . g:NERDComLineNestMap . ' :call NERDComment(1, "nested")' ++ ++" set up the mapping to uncomment a line ++execute 'nnoremap ' . g:NERDUncomLineMap . ' :call NERDComment(0, "uncomment")' ++execute 'vnoremap ' . g:NERDUncomLineMap . ' :call NERDComment(1, "uncomment")' ++ ++" set up the mapping to comment out to the end of the line ++execute 'nnoremap ' . g:NERDComToEOLMap . ' :call NERDComment(0, "toEOL")' ++ ++" set up the mappings to append comments to the line ++execute 'nmap ' . g:NERDAppendComMap . ' :call NERDComment(0, "append")' ++ ++" set up the mappings to append comments to the line ++execute 'nmap ' . g:NERDPrependComMap . ' :call NERDComment(0, "prepend")' ++ ++" set up the mapping to insert comment delims at the cursor position in insert mode ++execute 'inoremap ' . g:NERDComInInsertMap . ' ' . ':call NERDComment(0, "insert")' ++ ++" Section: Menu item setup {{{1 ++" =========================================================================== ++"check if the user wants the menu to be displayed ++if g:NERDMenuMode != 0 ++ ++ let menuRoot = "" ++ if g:NERDMenuMode == 1 ++ let menuRoot = 'comment' ++ elseif g:NERDMenuMode == 2 ++ let menuRoot = '&comment' ++ elseif g:NERDMenuMode == 3 ++ let menuRoot = '&Plugin.&comment' ++ endif ++ ++ execute 'nmenu '. menuRoot .'.Comment' . escape(g:NERDComLineMap, '\') . ' :call NERDComment(0, "norm")' ++ execute 'vmenu '. menuRoot .'.Comment' . escape(g:NERDComLineMap, '\') . ' :call NERDComment(1, "norm")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Toggle' . escape(g:NERDComLineToggleMap, '\') . ' :call NERDComment(0, "toggle")' ++ execute 'vmenu '. menuRoot .'.Comment\ Toggle' . escape(g:NERDComLineToggleMap, '\') . ' :call NERDComment(1, "toggle")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Minimal' . escape(g:NERDComLineMinimalMap, '\') . ' :call NERDComment(0, "minimal")' ++ execute 'vmenu '. menuRoot .'.Comment\ Minimal' . escape(g:NERDComLineMinimalMap, '\') . ' :call NERDComment(1, "minimal")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Nested' . escape(g:NERDComLineNestMap, '\') . ' :call NERDComment(0, "nested")' ++ execute 'vmenu '. menuRoot .'.Comment\ Nested' . escape(g:NERDComLineNestMap, '\') . ' :call NERDComment(1, "nested")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ To\ EOL' . escape(g:NERDComToEOLMap, '\') . ' :call NERDComment(0, "toEOL")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Invert' . escape(g:NERDComLineInvertMap, '\') . ' :call NERDComment(0,"invert")' ++ execute 'vmenu '. menuRoot .'.Comment\ Invert' . escape(g:NERDComLineInvertMap, '\') . ' :call NERDComment(1,"invert")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Sexily' . escape(g:NERDComLineSexyMap, '\') . ' :call NERDComment(0,"sexy")' ++ execute 'vmenu '. menuRoot .'.Comment\ Sexily' . escape(g:NERDComLineSexyMap, '\') . ' :call NERDComment(1,"sexy")' ++ ++ execute 'nmenu '. menuRoot .'.Yank\ line(s)\ then\ comment' . escape(g:NERDComLineYankMap, '\') . ' "0Y' . g:NERDComLineMap ++ execute 'vmenu '. menuRoot .'.Yank\ line(s)\ then\ comment' . escape(g:NERDComLineYankMap, '\') . ' "0ygv' . g:NERDComLineMap ++ ++ execute 'nmenu '. menuRoot .'.Append\ Comment\ to\ Line' . escape(g:NERDAppendComMap, '\') . ' :call NERDComment(0, "append")' ++ execute 'nmenu '. menuRoot .'.Prepend\ Comment\ to\ Line' . escape(g:NERDPrependComMap, '\') . ' :call NERDComment(0, "prepend")' ++ ++ execute 'menu '. menuRoot .'.-Sep- :' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Left\ (nested)' . escape(g:NERDComAlignLeftMap, '\') . ' :call NERDComment(0, "alignLeft")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Left\ (nested)' . escape(g:NERDComAlignLeftMap, '\') . ' :call NERDComment(1, "alignLeft")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Right\ (nested)' . escape(g:NERDComAlignRightMap, '\') . ' :call NERDComment(0, "alignRight")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Right\ (nested)' . escape(g:NERDComAlignRightMap, '\') . ' :call NERDComment(1, "alignRight")' ++ ++ execute 'nmenu '. menuRoot .'.Comment\ Align\ Both\ (nested)' . escape(g:NERDComAlignBothMap, '\') . ' :call NERDComment(0, "alignBoth")' ++ execute 'vmenu '. menuRoot .'.Comment\ Align\ Both\ (nested)' . escape(g:NERDComAlignBothMap, '\') . ' :call NERDComment(1, "alignBoth")' ++ ++ execute 'menu '. menuRoot .'.-Sep2- :' ++ ++ execute 'menu '. menuRoot .'.Uncomment' . escape(g:NERDUncomLineMap, '\') . ' :call NERDComment(0, "uncomment")' ++ execute 'vmenu ' . menuRoot.'.Uncomment' . escape(g:NERDUncomLineMap, '\') . ' :call NERDComment(1, "uncomment")' ++ ++ execute 'menu '. menuRoot .'.-Sep3- :' ++ ++ execute 'nmenu '. menuRoot .'.Use\ Alternative\ Delimiters' . escape(g:NERDAltComMap, '\') . ' :call SwitchToAlternativeDelimiters(1)' ++ ++ ++ execute 'imenu '. menuRoot .'.Insert\ Delims' . escape(g:NERDComInInsertMap, '\') . ' :call NERDComment(0, "insert")' ++ ++ execute 'menu '. menuRoot .'.-Sep4- :' ++ ++ execute 'menu '. menuRoot .'.Help:help\ NERDCommenterContents :help NERDCommenterContents' ++endif ++ ++" Section: Doc installation call {{{1 ++silent call s:InstallDocumentation(expand(':p'), s:NERD_commenter_version) ++ ++finish ++"============================================================================= ++" Section: The help file {{{1 ++" Title {{{2 ++" ============================================================================ ++=== START_DOC ++*NERD_commenter.txt* Plugin for commenting code #version# ++ ++ ++ NERD COMMENTER REFERENCE MANUAL~ ++ ++ ++ ++ ++ ++============================================================================== ++CONTENTS {{{2 *NERDCommenterContents* ++ ++ 1.Intro...................................|NERDCommenter| ++ 2.Functionality provided..................|NERDComFunctionality| ++ 2.1 Functionality Summary.............|NERDComFunctionalitySummary| ++ 2.2 Functionality Details.............|NERDComFunctionalityDetails| ++ 2.2.1 Comment map.................|NERDComComment| ++ 2.2.2 Nested comment map..........|NERDComNestedComment| ++ 2.2.3 Toggle comment map..........|NERDComToggleComment| ++ 2.2.4 Minimal comment map.........|NERDComMinimalComment| ++ 2.2.5 Invert comment map..........|NERDComInvertComment| ++ 2.2.6 Sexy comment map............|NERDComSexyComment| ++ 2.2.7 Yank comment map............|NERDComYankComment| ++ 2.2.8 Comment to EOL map..........|NERDComEOLComment| ++ 2.2.9 Append com to line map......|NERDComAppendComment| ++ 2.2.10 Prepend com to line map....|NERDComPrependComment| ++ 2.2.11 Insert comment map.........|NERDComInsertComment| ++ 2.2.12 Use alternate delims map...|NERDComAltDelim| ++ 2.2.13 Comment aligned maps.......|NERDComAlignedComment| ++ 2.2.14 Uncomment line map.........|NERDComUncommentLine| ++ 2.3 Supported filetypes...............|NERDComFiletypes| ++ 2.4 Sexy Comments.....................|NERDComSexyComments| ++ 2.5 The NERDComment function..........|NERDComNERDComment| ++ 3.Options.................................|NERDComOptions| ++ 3.1 Options summary...................|NERDComOptionsSummary| ++ 3.2 Options details...................|NERDComOptionsDetails| ++ 3.3 Default delimiter Options.........|NERDComDefaultDelims| ++ 3.4 Key mapping Options...............|NERDComMappings| ++ 4.Issues with the script..................|NERDComIssues| ++ 4.1 Delimiter detection heuristics....|NERDComHeuristics| ++ 4.2 Nesting issues....................|NERDComNesting| ++ 5.The author..............................|NERDComAuthor| ++ 6.TODO list...............................|NERDComTodo| ++ 7.Changelog...............................|NERDComChangelog| ++ 8.Credits.................................|NERDComCredits| ++ ++============================================================================== ++1. Intro {{{2 *NERDCommenter* ++ ++The NERD commenter provides many different commenting operations and styles ++which may be invoked via key mappings and a commenting menu. These operations ++are available for most filetypes. ++ ++There are also options available that allow you to tweak the commenting engine ++to you taste. ++ ++============================================================================== ++2. Functionality provided {{{2 *NERDComFunctionality* ++ ++------------------------------------------------------------------------------ ++2.1 Functionality summary {{{3 *NERDComFunctionalitySummary* ++ ++The following key mappings are provided by default (there is also a menu ++provided that contains menu items corresponding to all the below mappings): ++ ++Most of the following mappings are for normal/visual mode only. The ++|NERDComInsertComment| mapping is for insert mode only. ++ ++[count],cc |NERDComComment| ++Comments out the current line or text selected in visual mode. ++ ++ ++[count],cn |NERDComNestedComment| ++Same as |NERDComComment| but forces nesting. ++ ++ ++[count],c |NERDComToggleComment| ++Toggles the comment state of the selected line(s). If the topmost selected ++line is commented, all selected lines are uncommented and vice versa. ++ ++ ++[count],cm |NERDComMinimalComment| ++Comments the given lines using only one set of multipart delimiters if ++possible. ++ ++ ++[count],ci |NERDComInvertComment| ++Toggles the comment state of the selected line(s) individually. Each selected ++line that is commented is uncommented and vice versa. ++ ++ ++[count],cs |NERDComSexyComment| ++Comments out the selected lines ``sexually'' ++ ++ ++[count],cy |NERDComYankComment| ++Same as |NERDComComment| except that the commented line(s) are yanked ++before commenting. ++ ++ ++,c$ |NERDComEOLComment| ++Comments the current line from the cursor to the end of line. ++ ++ ++,cA |NERDComAppendComment| ++Adds comment delimiters to the end of line and goes into insert mode between ++them. ++ ++ ++,cI |NERDComPrependComment| ++Adds comment delimiters to the start of line and goes into insert mode between ++them. ++ ++ ++ |NERDComInsertComment| ++Adds comment delimiters at the current cursor position and inserts between. ++ ++ ++,ca |NERDComAltDelim| ++Switches to the alternative set of delimiters. ++ ++ ++[count],cl ++[count],cr ++[count],cb |NERDComAlignedComment| ++Same as |NERDComComment| except that the delimiters are aligned down the ++left side (,cl), the right side (,cr) or both sides ++(,cb). ++ ++ ++[count],cu |NERDComUncommentLine| ++Uncomments the selected line(s). ++ ++------------------------------------------------------------------------------ ++2.2 Functionality details {{{3 *NERDComFunctionalityDetails* ++ ++------------------------------------------------------------------------------ ++2.2.1 Comment map *NERDComComment* ++ ++Default mapping: [count],cc ++Change the mapping with: NERDComLineMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++ ++Comments out the current line. If multiple lines are selected in visual-line ++mode, they are all commented out. If some text is selected in visual or ++visual-block mode then the script will try to comment out the exact text that ++is selected using multi-part delimiters if they are available. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.2 Nested comment map *NERDComNestedComment* ++ ++Default mapping: [count],cn ++Change the mapping with: NERDComLineNestMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++Performs nested commenting. Works the same as ,cc except that if a ++line is already commented then it will be commented again. ++ ++If |NERDUsePlaceHolders| is set then the previous comment delimiters will ++be replaced by place-holder delimiters if needed. Otherwise the nested ++comment will only be added if the current commenting delimiters have no right ++delimiter (to avoid syntax errors) ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDDefaultNesting| ++ ++------------------------------------------------------------------------------ ++2.2.3 Toggle comment map *NERDComToggleComment* ++ ++Default mapping: [count],c ++Change the mapping with: NERDComLineToggleMap. ++Applicable modes: normal visual-line. ++ ++Toggles commenting of the lines selected. The behaviour of this mapping ++depends on whether the first line selected is commented or not. If so, all ++selected lines are uncommented and vice versa. ++ ++With this mapping, a line is only considered to be commented if it starts with ++a left delimiter. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.4 Minimal comment map *NERDComMinimalComment* ++ ++Default mapping: [count],cm ++Change the mapping with: NERDComLineMinimalMap ++Applicable modes: normal visual-line. ++ ++Comments the selected lines using one set of multipart delimiters if possible. ++ ++For example: if you are programming in c and you select 5 lines and press ++,cm then a '/*' will be placed at the start of the top line and a '*/' ++will be placed at the end of the last line. ++ ++Sets of multipart comment delimiters that are between the top and bottom ++selected lines are replaced with place holders (see |NERDLPlace|) if ++|NERDUsePlaceHolders| is set for the current filetype. If it is not, then ++the comment will be aborted if place holders are required to prevent illegal ++syntax. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.5 Invert comment map *NERDComInvertComment* ++ ++Default mapping: ,ci ++Change the mapping with: NERDComLineInvertMap. ++Applicable modes: normal visual-line. ++ ++Inverts the commented state of each selected line. If the a selected line is ++commented then it is uncommented and vice versa. Each line is examined and ++commented/uncommented individually. ++ ++With this mapping, a line is only considered to be commented if it starts with ++a left delimiter. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.6 Sexy comment map *NERDComSexyComment* ++ ++Default mapping: [count],cs ++Change the mapping with: NERDComLineSexyMap ++Applicable modes: normal, visual-line. ++ ++Comments the selected line(s) ``sexily''... see |NERDComSexyComments| for ++a description of what sexy comments are. Can only be done on filetypes for ++which there is at least one set of multipart comment delimiters specified. ++ ++Sexy comments cannot be nested and lines inside a sexy comment cannot be ++commented again. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDCompactSexyComs| ++ ++------------------------------------------------------------------------------ ++2.2.7 Yank comment map *NERDComYankComment* ++ ++Default mapping: [count],cy ++Change the mapping with: NERDComLineYankMap ++Applicable modes: normal visual visual-line visual-block. ++ ++Same as ,cc except that it yanks the line(s) that are commented first. ++ ++------------------------------------------------------------------------------ ++2.2.8 Comment to EOL map *NERDComEOLComment* ++ ++Default mapping: ,c$ ++Change the mapping with: NERDComToEOLMap ++Applicable modes: normal. ++ ++Comments the current line from the current cursor position up to the end of ++the line. ++ ++------------------------------------------------------------------------------ ++2.2.9 Append com to line map *NERDComAppendComment* ++ ++Default mapping: ,cA ++Change the mapping with: NERDAppendComMap. ++Applicable modes: normal. ++ ++Appends comment delimiters to the end of the current line and goes ++to insert mode between the new delimiters. ++ ++------------------------------------------------------------------------------ ++2.2.10 Prepend com to line map *NERDComPrependComment* ++ ++Default mapping: ,cI ++Change the mapping with: NERDPrependComMap. ++Applicable modes: normal. ++ ++Prepends comment delimiters to the start of the current line and goes to ++insert mode between the new delimiters. ++ ++------------------------------------------------------------------------------ ++2.2.11 Insert comment map *NERDComInsertComment* ++ ++Default mapping: ++Change the mapping with: NERDComInInsertMap. ++Applicable modes: insert. ++ ++Adds comment delimiters at the current cursor position and inserts ++between them. ++ ++------------------------------------------------------------------------------ ++2.2.12 Use alternate delims map *NERDComAltDelim* ++ ++Default mapping: ,ca ++Change the mapping with: NERDAltComMap ++Applicable modes: normal. ++ ++Changes to the alternative commenting style if one is available. For example, ++if the user is editing a c++ file using // comments and they hit ,ca ++then they will be switched over to /**/ comments. ++ ++See also |NERDComDefaultDelims| ++ ++------------------------------------------------------------------------------ ++2.2.13 Comment aligned maps *NERDComAlignedComment* ++ ++Default mappings: [count],cl [count],cr [count],cb ++Change the mappings with: NERDComAlignLeftMap, NERDComAlignRightMap and ++NERDComAlignBothMap. ++Applicable modes: normal visual-line. ++ ++Same as ,cc except that the comment delimiters are aligned on the left ++side, right side or both sides respectively. These comments are always nested ++if the line(s) are already commented. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++------------------------------------------------------------------------------ ++2.2.14 Uncomment line map *NERDComUncommentLine* ++ ++Default mapping: [count],cu ++Change the mapping with: NERDUncomLineMap. ++Applicable modes: normal visual visual-line visual-block. ++ ++Uncomments the current line. If multiple lines are selected in ++visual mode then they are all uncommented. ++ ++When uncommenting, if the line contains multiple sets of delimiters then the ++``outtermost'' pair of delimiters will be removed. ++ ++The script uses a set of heurisics to distinguish ``real'' delimiters from ++``fake'' ones when uncommenting. See |NERDComIssues| for details. ++ ++If a [count] is given in normal mode, the mapping works as though that many ++lines were selected in visual-line mode. ++ ++Related options: ++|NERDRemoveAltComs| ++|NERDRemoveExtraSpaces| ++ ++------------------------------------------------------------------------------ ++2.3 Supported filetypes {{{3 *NERDComFiletypes* ++ ++Filetypes that can be commented by this plugin: ++abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asn ++aspvbs atlas autohotkey autoit automake ave awk basic b bc bdf bib bindzone ++bst btm caos catalog c cfg cg ch changelog cl clean clipper cmake conf config ++context cpp crontab cs csc csp css cterm cupl csv cvs dcl debchangelog ++debcontrol debsources def diff django docbk dns dosbatch dosini dot dracula ++dsl dtd dtml dylan ecd eiffel elf elmfilt erlang eruby eterm expect exports ++fetchmail fgl focexec form fortran foxpro fstab fvwm fx gdb gdmo geek ++gentoo-package-keywords' gentoo-package-mask' gentoo-package-use' gnuplot ++gtkrc haskell hb h help hercules hog html htmldjango htmlos ia64 icon idlang ++idl indent inform inittab ishd iss ist jam java javascript jess jgraph ++jproperties jproperties jsp kconfig kix kscript lace lex lftp lifelines lilo ++lisp lite lotos lout lprolog lscript lss lua lynx m4 mail make maple masm ++master matlab mel mf mib mma model moduala. modula2 modula3 monk mush muttrc ++named nasm nastran natural ncf netdict netrw nqc nroff nsis objc ocaml occam ++omlet omnimark openroad opl ora otl ox pascal passwd pcap pccts perl pfmain ++php phtml pic pike pilrc pine plaintex plm plsql po postscr pov povini ppd ++ppwiz procmail progress prolog psf ptcap python python qf radiance ratpoison r ++rc readline rebol registry remind rexx robots rpl rtf ruby sa samba sas sass ++sather scheme scilab screen scsh sdl sed selectbuf sgml sgmldecl sgmllnx sh ++sicad simula sinda skill slang sl slrnrc sm smarty smil smith sml snnsnet ++snnspat snnsres snobol4 spec specman spice sql sqlforms sqlj sqr squid st stp ++strace svn systemverilog tads taglist tags tak tasm tcl terminfo tex text ++plaintex texinfo texmf tf tidy tli trasys tsalt tsscl tssgm uc uil vb verilog ++verilog_systemverilog vgrindefs vhdl vim viminfo virata vo_base vrml vsejcl ++webmacro wget winbatch wml wvdial xdefaults xf86conf xhtml xkb xmath xml ++xmodmap xpm2 xpm xslt yacc yaml z8a ++ ++If a language is not in the list of hardcoded supported filetypes then the ++&commentstring vim option is used. ++ ++------------------------------------------------------------------------------ ++2.4 Sexy Comments {{{3 *NERDComSexyComments* ++These are comments that use one set of multipart comment delimiters as well as ++one other marker symbol. For example: > ++ /* ++ * This is a c style sexy comment ++ * So there! ++ */ ++ ++ /* This is a c style sexy comment ++ * So there! ++ * But this one is ``compact'' style */ ++< ++Here the multipart delimiters are /* and */ and the marker is *. The NERD ++commenter is capable of adding and removing comments of this type. ++ ++------------------------------------------------------------------------------ ++2.5 The NERDComment function {{{3 *NERDComNERDComment* ++ ++All of the NERD commenter mappings and menu items invoke a single function ++which delegates the commenting work to other functions. This function is ++public and has the prototype: > ++ function! NERDComment(isVisual, type) ++< ++The arguments to this function are simple: ++ - isVisual: if you wish to do any kind of visual comment then set this to ++ 1 and the function will use the '< and '> marks to find the comment ++ boundries. If set to 0 then the function will operate on the current ++ line. ++ - type: is used to specify what type of commenting operation is to be ++ performed, and it can be one of the following: 'sexy', 'invert', ++ 'minimal', 'toggle', 'alignLeft', 'alignRight', 'alignBoth', 'norm', ++ 'nested', 'toEOL', 'prepend', 'append', 'insert', 'uncomment', 'yank' ++ ++For example, if you typed > ++ :call NERDComment(1, 'sexy') ++< ++then the script would do a sexy comment on the last visual selection. ++ ++ ++============================================================================== ++3. Options {{{2 *NERDComOptions* ++ ++------------------------------------------------------------------------------ ++3.1 Options summary *NERDComOptionsSummary* ++ ++|loaded_nerd_comments| Turns off the script. ++|NERDAllowAnyVisualDelims| Allows multipart alternative delims to ++ be used when commenting in ++ visual/visual-block mode. ++|NERDBlockComIgnoreEmpty| Forces right delims to be placed when ++ doing visual-block comments. ++|NERDCommentWholeLinesInVMode| Changes behaviour of visual comments. ++|NERDDefaultNesting| Tells the script to use nested comments ++ by default. ++|NERDMenuMode| Specifies how the NERD commenter menu ++ will appear (if at all). ++|NERDLPlace| Specifies what to use as the left ++ delimiter placeholder when nesting ++ comments. ++|NERDMapleader| Specifies what all the commenting key ++ mappings will begin with. ++|NERDUsePlaceHolders| Specifies which filetypes may use ++ placeholders when nesting comments. ++|NERDRemoveAltComs| Tells the script whether to remove ++ alternative comment delimiters when ++ uncommenting. ++|NERDRemoveExtraSpaces| Tells the script to always remove the ++ extra spaces when uncommenting ++ (regardless of whether NERDSpaceDelims ++ is set) ++|NERDRPlace| Specifies what to use as the right ++ delimiter placeholder when nesting ++ comments. ++|NERDShutUp| Stops "Unknown filetype" output from the ++ script ++|NERDSpaceDelims| Specifies whether to add extra spaces ++ around delimiters when commenting, and ++ whether to remove them when ++ uncommenting. ++|NERDCompactSexyComs| Specifies whether to use the compact ++ style sexy comments. ++ ++------------------------------------------------------------------------------ ++3.3 Options details *NERDComOptionsDetails* ++ ++To enable any of the below options you should put the given line in your ++~/.vimrc ++ ++ *loaded_nerd_comments* ++If this script is driving you insane you can turn it off by setting this ++option > ++ let loaded_nerd_comments=1 ++< ++------------------------------------------------------------------------------ ++ *NERDAllowAnyVisualDelims* ++Values: 0 or 1. ++Default: 1. ++ ++If set to 1 then, when doing a visual or visual-block comment (but not a ++visual-line comment), the script will choose the right delimiters to use for ++the comment. This means either using the current delimiters if they are ++multipart or using the alternative delimiters if THEY are multipart. For ++example if we are editing the following java code: > ++ float foo = 1221; ++ float bar = 324; ++ System.out.println(foo * bar); ++< ++If we are using // comments and select the "foo" and "bar" in visual-block ++mode, as shown left below (where '|'s are used to represent the visual-block ++boundary), and comment it then the script will use the alternative delims as ++shown on the right: > ++ ++ float |foo| = 1221; float /*foo*/ = 1221; ++ float |bar| = 324; float /*bar*/ = 324; ++ System.out.println(foo * bar); System.out.println(foo * bar); ++< ++------------------------------------------------------------------------------ ++ *NERDBlockComIgnoreEmpty* ++Values: 0 or 1. ++Default: 1. ++ ++This option affects visual-block mode commenting. If this option is turned ++on, lines that begin outside the right boundary of the selection block will be ++ignored. ++ ++For example, if you are commenting this chunk of c code in visual-block mode ++(where the '|'s are used to represent the visual-block boundary) > ++ #include ++ #include ++ #include ++ |int| main(){ ++ | | printf("SUCK THIS\n"); ++ | | while(1){ ++ | | fork(); ++ | | } ++ |} | ++< ++If NERDBlockComIgnoreEmpty=0 then this code will become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ /* */ printf("SUCK THIS\n"); ++ /* */ while(1){ ++ /* */ fork(); ++ /* */ } ++ /*} */ ++< ++Otherwise, the code block would become: > ++ #include ++ #include ++ #include ++ /*int*/ main(){ ++ printf("SUCK THIS\n"); ++ while(1){ ++ fork(); ++ } ++ /*} */ ++< ++------------------------------------------------------------------------------ ++ *NERDCommentWholeLinesInVMode* ++Values: 0, 1 or 2. ++Default: 0. ++ ++By default the script tries to comment out exactly what is selected in visual ++mode (v). For example if you select and comment the following c code (using | ++to represent the visual boundary): > ++ in|t foo = 3; ++ int bar =| 9; ++ int baz = foo + bar; ++< ++This will result in: > ++ in/*t foo = 3;*/ ++ /*int bar =*/ 9; ++ int baz = foo + bar; ++< ++But some people prefer it if the whole lines are commented like: > ++ /*int foo = 3;*/ ++ /*int bar = 9;*/ ++ int baz = foo + bar; ++< ++If you prefer the second option then stick this line in your vimrc: > ++ let NERDCommentWholeLinesInVMode=1 ++< ++ ++If the filetype you are editing only has no multipart delimiters (for example ++a shell script) and you hadnt set this option then the above would become > ++ in#t foo = 3; ++ #int bar = 9; ++< ++(where # is the comment delimiter) as this is the closest the script can ++come to commenting out exactly what was selected. If you prefer for whole ++lines to be commented out when there is no multipart delimiters but the EXACT ++text that was selected to be commented out if there IS multipart delimiters ++then stick the following line in your vimrc: > ++ let NERDCommentWholeLinesInVMode=2 ++< ++ ++Note that this option does not affect the behaviour of |visual-block| mode. ++ ++------------------------------------------------------------------------------ ++ *NERDRemoveAltComs* ++Values: 0 or 1. ++Default: 1. ++ ++When uncommenting a line (for a filetype with an alternative commenting style) ++this option tells the script whether to look for, and remove, comments ++delimiters of the alternative style. ++ ++For example, if you are editing a c++ file using // style comments and you go ++,cu on this line: > ++ /* This is a c++ comment baby! */ ++< ++It will not be uncommented if the NERDRemoveAltComs is set to 0. ++ ++------------------------------------------------------------------------------ ++ *NERDRemoveExtraSpaces* ++Values: 0 or 1. ++Default: 1. ++ ++By default, the NERD commenter will remove spaces around comment delimiters if ++either: ++1. |NERDSpaceDelims| is set to 1. ++2. NERDRemoveExtraSpaces is set to 1. ++ ++This means that if we have the following lines in a c code file: > ++ /* int foo = 5; */ ++ /* int bar = 10; */ ++ int baz = foo + bar ++< ++If either of the above conditions hold then if these lines are uncommented ++they will become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++Otherwise they would become: > ++ int foo = 5; ++ int bar = 10; ++ int baz = foo + bar ++< ++If you want the spaces to be removed only if |NERDSpaceDelims| is set then ++set NERDRemoveExtraSpaces to 0. ++ ++------------------------------------------------------------------------------ ++ *NERDLPlace* ++ *NERDRPlace* ++Values: arbitrary string. ++Default: ++ NERDLPlace: "[>" ++ NERDRPlace: "<]" ++ ++These options are used to control the strings used as place-holder delimiters. ++Place holder delimiters are used when performing nested commenting when the ++filetype supports commenting styles with both left and right delimiters. ++To set these options use lines like: > ++ let NERDLPlace="FOO" ++ let NERDRPlace="BAR" ++< ++Following the above example, if we have line of c code: > ++ /* int horse */ ++< ++and we comment it with ,cn it will be changed to: > ++ /*FOO int horse BAR*/ ++< ++When we uncomment this line it will go back to what it was. ++ ++------------------------------------------------------------------------------ ++ *NERDMapleader* ++Values: arbitrary string. ++Default: \c ++ ++NERDMapleader is used to specify what all the NERD commenter key mappings ++begin with. ++ ++The default key mappings will look like this: > ++ \cc ++ \cu ++ \ca ++ \ci ++ \cs ++ ... ++< ++However, if this line: > ++ let NERDMapleader = ',x' ++< ++were present in your vimrc then the default mappings would look like this: > ++ ,xc ++ ,xu ++ ,xa ++ ,xi ++ ,xs ++ ... ++< ++This option only affects the mappings that have not been explicitly set ++manually (see |NERDComMappings|). ++ ++------------------------------------------------------------------------------ ++ *NERDMenuMode* ++Values: 0, 1, 2, 3. ++Default: 3 ++ ++This option can take 4 values: ++ "0": Turns the menu off. ++ "1": Turns the 'comment' menu on with no menu shortcut. ++ "2": Turns the 'comment 'menu on with -c as the shortcut. ++ "3": Turns the 'Plugin -> comment' menu on with -c as the shortcut. ++ ++------------------------------------------------------------------------------ ++ *NERDUsePlaceHolders* ++Values: 0 or 1. ++Default 1. ++ ++This option is used to specify whether place-holder delimiters should be used ++when adding nested comments. ++ ++------------------------------------------------------------------------------ ++ *NERDShutUp* ++Values: 0 or 1. ++Default 1. ++ ++This option is used to prevent the script from echoing "Unknown filetype" ++messages. Stick this line in your vimrc: > ++ let NERDShutUp=1 ++< ++------------------------------------------------------------------------------ ++ *NERDSpaceDelims* ++Values: 0 or 1. ++Default 0. ++ ++Some people prefer a space after the left delimiter and before the right ++delimiter like this: > ++ /* int foo=2; */ ++< ++as opposed to this: > ++ /*int foo=2;*/ ++< ++If you want spaces to be added then set NERDSpaceDelims to 1 in your vimrc. ++ ++See also |NERDRemoveExtraSpaces|. ++ ++------------------------------------------------------------------------------ ++ *NERDCompactSexyComs* ++Values: 0 or 1. ++Default 0. ++ ++Some people may want their sexy comments to be like this: > ++ /* Hi There! ++ * This is a sexy comment ++ * in c */ ++< ++As opposed to like this: > ++ /* ++ * Hi There! ++ * This is a sexy comment ++ * in c ++ */ ++< ++If this option is set to 1 then the top style will be used. ++ ++------------------------------------------------------------------------------ ++ *NERDDefaultNesting* ++Values: 0 or 1. ++Default 0. ++ ++When this option is set to 1, comments are nested automatically. That is, if ++you hit ,cc on a line that is already commented it will be commented ++again ++ ++------------------------------------------------------------------------------ ++3.3 Default delimiter customisation *NERDComDefaultDelims* ++ ++If you want the NERD commenter to use the alternative delimiters for a ++specific filetype by default then put a line of this form into your vimrc: > ++ let NERD_<&filetype>_alt_style=1 ++< ++Example: java uses // style comments by default, but you want it to default to ++/* */ style comments instead. You would put this line in your vimrc: > ++ let NERD_java_alt_style=1 ++< ++ ++See |NERDComAltDelim| for switching commenting styles at runtime. ++ ++------------------------------------------------------------------------------ ++3.4 Key mapping customisation *NERDComMappings* ++ ++These options are used to override the default keys that are used for the ++commenting mappings. Their values must be set to strings. As an example: if ++you wanted to use the mapping ,foo to uncomment lines of code then ++you would place this line in your vimrc > ++ let NERDUncomLineMap=",foo" ++< ++Check out |NERDComFunctionality| for details about what the following ++mappings do. ++ ++Default Mapping Option to override~ ++ ++,ca NERDAltComMap ++,ce NERDAppendComMap ++,cl NERDComAlignLeftMap ++,cb NERDComAlignBothMap ++,cr NERDComAlignRightMap ++ NERDComInInsertMap ++,ci NERDComLineInvertMap ++,cc NERDComLineMap ++,cn NERDComLineNestMap ++,cs NERDComLineSexyMap ++,c NERDComLineToggleMap ++,cm NERDComLineMinimalMap ++,c$ NERDComToEOLMap ++,cy NERDComLineYankMap ++,cu NERDUncomLineMap ++ ++============================================================================== ++4. Issues with the script{{{2 *NERDComIssues* ++ ++ ++------------------------------------------------------------------------------ ++4.1 Delimiter detection heuristics *NERDComHeuristics* ++ ++Heuristics are used to distinguish the real comment delimiters ++ ++Because we have comment mappings that place delimiters in the middle of lines, ++removing comment delimiters is a bit tricky. This is because if comment ++delimiters appear in a line doesnt mean they really ARE delimiters. For ++example, Java uses // comments but the line > ++ System.out.println("//"); ++< ++clearly contains no real comment delimiters. ++ ++To distinguish between ``real'' comment delimiters and ``fake'' ones we use a ++set of heuristics. For example, one such heuristic states that any comment ++delimiter that has an odd number of non-escaped " characters both preceding ++and following it on the line is not a comment because it is probably part of a ++string. These heuristics, while usually pretty accurate, will not work for all ++cases. ++ ++------------------------------------------------------------------------------ ++4.2 Nesting issues *NERDComNesting* ++ ++If we have some line of code like this: > ++ /*int foo */ = /*5 + 9;*/ ++< ++This will not be uncommented legally. The NERD commenter will remove the ++"outter most" delimiters so the line will become: > ++ int foo */ = /*5 + 9; ++< ++which almost certainly will not be what you want. Nested sets of comments will ++uncomment fine though. Eg: > ++ /*int/* foo =*/ 5 + 9;*/ ++< ++will become: > ++ int/* foo =*/ 5 + 9; ++< ++(Note that in the above examples I have deliberately not used place holders ++for simplicity) ++ ++============================================================================== ++6. The author {{{2 *NERDComAuthor* ++ ++The author of the NERD commenter is Martyzillatron --- the half robot, half ++dinosaur bastard son of Megatron and Godzilla. He enjoys destroying ++metropolises and eating tourist busses. ++ ++Drop him a line at martin_grenfell at msn.com. He would love to hear from you. ++its a lonely life being the worlds premier terror machine. How would you feel ++if your face looked like a toaster and a t-rex put together? :( ++ ++============================================================================== ++7. TODO list {{{2 *NERDComTodo* ++ ++Uncommenting of minimal comments needs to be more robust. Currently it is easy ++to get illegal syntax when uncommenting them. ++ ++ ++ ++============================================================================== ++8. Changelog {{{2 *NERDComChangelog* ++ ++2.1.4 ++ - added support for the ahk filetype. Cheers to Don Hatlestad for the ++ email. ++ - added support for desktop and xsd filetypes. Thanks to Christophe Benz. ++ - added dummy support for Rails-log ++ - fixed a bunch of bugs in the comment delimiter setup process, thanks to ++ Cheng Fang for the email :D ++ - hardcore refactoring and removal of seldomly used, overly-complex ++ functionality. ++ - the script now requires vim 7 ++2.1.3 ++ - fixed numerous bugs that were causing tabs to permanently be converted ++ to spaces, even if noexpandtab was set. Thanks to Heptite on #vim for ++ working with me to track them down :) ++ - added dummy support for "lookupfile". Thanks to David Fishburn for the ++ email. ++ - added support for "rst", thanks to Niels Aan de Brugh for the email. ++ ++2.1.2 ++ - added support for the vera and ldif filetypes. Thanks to Normandie ++ Azucena and Florian Apolloner for the emails. ++ ++2.1.1 ++ - added dummy support for SVNcommitlog and vcscommit. Thanks to John ++ O'Shea for the email. ++ - added support for Groovy. Thanks to Jason Mills for the email. ++2.1.0 ++ - now the script resets the delimiters when the filetype of the buffer ++ changes (thanks to James Hales for the patch) ++ - added formal support/doc for prepending a count to many of the ++ commenting maps so you can go, eg, 5,cc to comment 5 lines from normal ++ mode. Thanks again to James Hales for the patch. ++ - added support for the "gams" filetype that Jorge Rodrigues created. ++ - added support for the "objc" filetype, thanks to Rainer Müller for the ++ email. ++ - added support for the "sass" filetype that Dmitry Ilyashevich created. ++ ++2.0.7 ++ - Added support for eclass and ebuild filetypes. Thanks to Alex Tarkovsky ++ for the email. ++ ++2.0.6 ++ - Changed the default setting of NERDMapleader to ",c", meaning all the ++ maps now start with ,c instead of \c. This is to stop a major mapping ++ clash with the vcscommand plugin. Anyone wanting to keep the \c map ++ leader should read :help NERDMapleader. ++ - Added support for debcontrol and dummy support for debchangelog ++ filetypes, thanks to Stefano Zacchiroli for the email. ++ - Made it so that the NERDShutUp option now only controls the "Pleeease ++ email the delimiters..." requests. It no longer affects the general ++ output of the script. ++ - Simplified the names of the help tags. ++ ++2.0.5 ++ - Added support for autoit, autohotkey and docbk filetypes (thanks to ++ Michael Böhler) ++ - Added support for cmake (thanks to Aaron Small) ++ - Added support for htmldjango and django filetypes (thanks to Ramiro ++ Morales) ++ - Improved the delimiters for eruby again ++ - Applied a patch from Seth Mason to fix some pathing issues with the help ++ file installation. ++ ++2.0.4 ++ - Added support for verilog_systemverilog and systemverilog filetypes ++ (Thanks to Alexey for the email) ++ - Added support for fstab, thanks to Lizendir for the email. ++ - Added support for the smarty filetype. ++ - Improved the delimiters for eruby. ++ - Added dummy support for changelog filetype. ++ ++2.0.3 ++ - Added dummy support for the csv filetype (thx to Mark Woodward for the ++ email) ++ - Added dummy support for vo_base and otl filetypes (thanks to fREW for ++ the email) ++ ++2.0.2: ++ - Minor bug fix that was stopping nested comments from working ++ ++2.0.1: ++ - Fixed the visual bell for the |NERDComToEOLMap| map. ++ - Added another possible value to the NERDMenuMode option which causes the ++ menu to be displayed under 'Plugin -> Comment'. See :h NERDMenuMode. ++ This new menu mode is now the default. ++ - Added support for the occam filetype (thanks to Anders for emailing me) ++ - Made the main commenting function (NERDComment) available outside the ++ script. ++ - bug fixes and refactoring ++ ++2.0.0: ++ - NOTE: renamed the script to NERD_commenter.vim. When you install this ++ version you must delete the old files: NERD_comments.vim and ++ NERD_comments.txt. ++ - Reworked the mappings and main entry point function for the script to ++ avoid causing visual-bells and screen scrolling. ++ - Changes to the script options (see |NERD_com-Customisation| for ++ details): ++ - They are all camel case now instead of underscored. ++ - Converted all of the regular expression options into simple boolean ++ options for simplicity. ++ - All the options are now stated positively, eg. ++ NERD_dont_remove_spaces_regexp has become NERDRemoveExtraSpaces. ++ - Some of the option names have been changed (other than in the above ++ ways) ++ - Some have been removed altogether, namely: NERD_create_h_filetype ++ (why was a commenting script creating a filetype?!), ++ NERD_left_align_regexp, NERD_right_align_regexp, ++ ++ - Removed all the NERD_use_alt_style_XXX_coms options and replaced them ++ with a better system. Now if a filetype has alternative delims, the ++ script will check whether an option of the form ++ "NERD_<&filetype>_alt_style" exists, and if it does then alt delims will ++ be used. See |NERD_com-cust-delims| for details. ++ - The script no longer removes extra spaces for sexy comments for the ++ NERDRemoveExtraSpaces option (it will still remove spaces if ++ NERDSpaceDelims is set). ++ - Added dummy support for viminfo and rtf. ++ - Added support for the "gentoo-package-\(keywords\|mask\|use\)" ++ filetypes. ++ - Added '#' comments as an alternative for the asm filetype ++ ++Thanks to Markus Klinik and Anders for bug reports, and again to Anders ++for his patch. Thanks to John O'Shea and fREW for the filetype ++information. ++ ++============================================================================== ++8. Credits {{{2 *NERDComCredits* ++ ++Thanks and respect to the following people: ++ ++Thanks to Nick Brettell for his many ideas and criticisms. A bloody good ++bastard. ++:normal :.-2s/good// ++ ++Thanks to Matthew Hawkins for his awesome refactoring! ++ ++Thanks to the authors of the vimspell whose documentation ++installation function I stole :) ++ ++Thanks to Greg Searle for the idea of using place-holders for nested comments. ++ ++Thanks to Nguyen for the suggestions and pointing the h file highlighting bug! ++Also, thanks for the idea of doing sexy comments as well as his suggestions ++relating to it :P ++Thanks again to Nguyen for complaining about the NERD_comments menu mapping ++(-c) interfering with another mapping of his... and thus the ++NERD_dont_create_menu_shortcut option was born :P ++(it was then replaced with NERD_menu_mode in version 1.67 :) ++ ++Thanks to Sam R for pointing out some filetypes that NERD_comments could support! ++ ++Cheers to Litchi for the idea of having a mapping that appends a comment to ++the current line :) ++ ++Thanks to jorge scandaliaris and Shufeng Zheng for telling me about some ++problems with commenting in visual mode. Thanks again to Jorge for his ++continued suggestions on this matter :) ++ ++Thanks to Martin Stubenschrott for pointing out a bug with the mapping ++:) Ive gotta stop breaking this mapping! ++ ++Thanks to Markus Erlmann for pointing out a conflict that this script was ++having with the taglist plugin. ++ ++Thanks to Brent Rice for alerting me about, and helping me track down, a bug ++in the script when the "ignorecase" option in vim was set. ++ ++Thanks to Richard Willis for telling me about how line continuation was ++causing problems on cygwin. Also, thanks pointing out a bug in the help file ++and for suggesting // comments for c (its about time SOMEONE did :P). May ANSI ++have mercy on your soul :) ++ ++Thanks to Igor Prischepoff for suggesting that i implement "toggle comments". ++Also, thanks for his suggested improvements about toggle comments after i ++implemented them. ++ ++Thanks to harry for telling me that i broke the cn mapping in 1.53 :), ++and thanks again for telling me about a bug that occurred when editing a file ++in a new tab. ++ ++Thanks to Martin (Krischikim?) for his patch that fixed a bug with the doc ++install function and added support for ada comments with spaces as well as ++making a couple of other small changes. ++ ++Thanks to David Bourgeois for pointing out a bug with when commenting c files ++:)... [a few days later] ok i completely misunderstood what David was talking ++about and ended up fixing a completely different bug to what he was talking ++about :P ++ ++Thanks to David Bourgeois for pointing out a bug when changing buffers. ++ ++Cheers to Eike Von Seggern for sending me a patch to fix a bug in 1.60 that ++was causing spaces to be added to the end of lines with single-part ++delimiters. It's nice when people do my work for me :D ++ ++Thanks to Torsten Blix for telling me about a couple of bugs when uncommenting ++sexy comments. Sexy comments dont look so sexy when they are only half removed ++:P ++ ++Thanks to Alexander "boesi" Bosecke for pointing out a bug that was stopping ++the NERD_space_delim_filetype_regexp option from working with left aligned ++toggle comments. And for pointing out a bug when initialising VB comments. ++ ++Thanks to Stefano Zacchiroli for suggesting the idea of "Minimal comments". ++And for suggested improvements to minimal comments. ++ ++Thanks to Norick Chen for emailing in a patch that fixed the asp delimiters. ++In 1.65 ++ ++Thanks to Jonathan Derque for alerting me to some filetypes that could be ++supported (Namely: context, plaintext and mail). ++ ++Thanks to Joseph Barker for the sugesting that the menu be an optional ++feature. ++ ++Thanks to Gary Church and Tim Carey-Smith for complaining about the ++keymappings and causing me to introduce the NERD_mapleader option :) ++ ++Thanks to Vigil for pointing out that the "fetchmail" filetype was not ++supported and emailing me the delimiters ++ ++Thanks to Michael Brunner for telling me about the kconfig filetype. ++ ++Thanks to Antono Vasiljev for telling me about the netdict filetype. ++ ++Thanks to Melissa Reid for telling me about the omlet filetype. ++ ++Thanks to Ilia N Ternovich for alerting me to the 'qf' (quickfix) filetype. ++ ++Thanks to Markus Klinik for emailing me about a bug for sexy comments where ++spaces were being eaten. ++ ++Thanks to John O'Shea for emailing me about the RTF filetype. Thanks again for ++the SVNcommitlog and vcscommit filetypes. ++ ++Thanks to Anders for emailing me a patch to help get rid of all the visual ++bells and screen scrolling, and for sending me the delimiters for the occam ++filetype. ++ ++Thanks to Anders and Markus Klinik for emailing me about the screen scrolling ++issues and finally getting me off my ass about them :P ++ ++Thanks to Mark Woodward for emailing me about the csv filetype. ++ ++Thanks to fREW for emailing me with the /gentoo-package-(mask|keywords|use)/ ++filetypes the vo_base filetype. ++ ++Thanks to Alexey for emailing me about the verilog_systemverilog/systemverilog ++filetypes. ++ ++Cheers to Lizendir for the email about the fstab filetype ++ ++Thanks to Michael Böhler for emailing me with the autoit, autohotkey and docbk ++filetypes. ++ ++Thanks to Aaron Small for emailing me about the cmake filetype. ++ ++Thanks to Ramiro for emailing me about the htmldjango and django filetypes. ++ ++Thanks to Seth Mason for sending me a patch to fix some pathing issues for the ++help doc installation. ++ ++Thanks to Stefano Zacchiroli for emailing me with the debcontrol and ++debchangelog filetypes. ++ ++Thanks to Alex Tarkovsky for emailing me about the ebuild and eclass ++filetypes. ++ ++Cheers to Jorge Rodrigues for emailing me about the gams filetype. ++ ++Cheers to James Hales for the patch that made the comment maps work better with ++counts, and made the script reset comment delims for a buffer when its ++filetype changes. ++ ++Thank to Rainer Müller for emailing me with the Objective C delimiters. ++ ++Thanks to Jason Mills for emailing me the Groovy filetype. ++ ++Thanks to Normandie Azucena for emailing me about the vera filetype. ++ ++Thanks to Florian Apolloner for emailing me about the ldif filetype. ++ ++Cheers to David Fishburn for emailing me with the lookupfile filetype. ++ ++Thanks to Niels Aan de Brugh for emailing me with the rst filetype. ++ ++Cheers to heptite on #vim for helping me track down some tab-space conversion ++bugs. ++ ++Cheers to Don Hatlestad for telling me about the ahk filetype ++ ++Thanks to Christophe Benz for emailing me with the Desktop and xsd filetypes. ++ ++Cheers to Cheng Fang for the bug reports :D ++ ++Cheers to myself for being the best looking man on Earth! ++=== END_DOC ++" vim: set foldmethod=marker : +diff -urN vim71/runtime/plugin/taglist.vim vim71_ada/runtime/plugin/taglist.vim +--- vim71/runtime/plugin/taglist.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/plugin/taglist.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,4524 @@ ++" File: taglist.vim ++" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) ++" Version: 4.3 ++" Last Modified: February 18, 2007 ++" Copyright: Copyright (C) 2002-2006 Yegappan Lakshmanan ++" Permission is hereby granted to use and distribute this code, ++" with or without modifications, provided that this copyright ++" notice is copied with it. Like anything else that's free, ++" taglist.vim is provided *as is* and comes with no warranty of any ++" kind, either expressed or implied. In no event will the copyright ++" holder be liable for any damamges resulting from the use of this ++" software. ++" ++" The "Tag List" plugin is a source code browser plugin for Vim and provides ++" an overview of the structure of the programming language files and allows ++" you to efficiently browse through source code files for different ++" programming languages. You can visit the taglist plugin home page for more ++" information: ++" ++" http://vim-taglist.sourceforge.net ++" ++" You can subscribe to the taglist mailing list to post your questions ++" or suggestions for improvement or to report bugs. Visit the following ++" page for subscribing to the mailing list: ++" ++" http://groups.yahoo.com/group/taglist/ ++" ++" For more information about using this plugin, after installing the ++" taglist plugin, use the ":help taglist" command. ++" ++" Installation ++" ------------ ++" 1. Download the taglist.zip file and unzip the files to the $HOME/.vim ++" or the $HOME/vimfiles or the $VIM/vimfiles directory. This should ++" unzip the following two files (the directory structure should be ++" preserved): ++" ++" plugin/taglist.vim - main taglist plugin file ++" doc/taglist.txt - documentation (help) file ++" ++" Refer to the 'add-plugin', 'add-global-plugin' and 'runtimepath' ++" Vim help pages for more details about installing Vim plugins. ++" 2. Change to the $HOME/.vim/doc or $HOME/vimfiles/doc or ++" $VIM/vimfiles/doc directory, start Vim and run the ":helptags ." ++" command to process the taglist help file. ++" 3. If the exuberant ctags utility is not present in your PATH, then set the ++" Tlist_Ctags_Cmd variable to point to the location of the exuberant ctags ++" utility (not to the directory) in the .vimrc file. ++" 4. If you are running a terminal/console version of Vim and the ++" terminal doesn't support changing the window width then set the ++" 'Tlist_Inc_Winwidth' variable to 0 in the .vimrc file. ++" 5. Restart Vim. ++" 6. You can now use the ":TlistToggle" command to open/close the taglist ++" window. You can use the ":help taglist" command to get more ++" information about using the taglist plugin. ++" ++" ****************** Do not modify after this line ************************ ++ ++" Line continuation used here ++let s:cpo_save = &cpo ++set cpo&vim ++ ++if !exists('loaded_taglist') ++ " First time loading the taglist plugin ++ " ++ " To speed up the loading of Vim, the taglist plugin uses autoload ++ " mechanism to load the taglist functions. ++ " Only define the configuration variables, user commands and some ++ " auto-commands and finish sourcing the file ++ ++ " The taglist plugin requires the built-in Vim system() function. If this ++ " function is not available, then don't load the plugin. ++ if !exists('*system') ++ echomsg 'Taglist: Vim system() built-in function is not available. ' . ++ \ 'Plugin is not loaded.' ++ let loaded_taglist = 'no' ++ let &cpo = s:cpo_save ++ finish ++ endif ++ ++ " Location of the exuberant ctags tool ++ if !exists('Tlist_Ctags_Cmd') ++ if executable('exuberant-ctags') ++ " On Debian Linux, exuberant ctags is installed ++ " as exuberant-ctags ++ let Tlist_Ctags_Cmd = 'exuberant-ctags' ++ elseif executable(' exctags') ++ " On Free-BSD, exuberant ctags is installed as exctags ++ let Tlist_Ctags_ Cmd = 'exctags' ++ elseif executable('ctags') ++ let Tlist_Ctags_Cmd = 'ctags' ++ elseif executable('ctags.exe') ++ let Tlist_Ctags_Cmd = 'ctags.exe' ++ elseif executable('tags') ++ let Tlist_Ctags_Cmd = 'tags' ++ else ++ echomsg 'Taglist: Exuberant ctags (http://ctags.sf.net) ' . ++ \ 'not found in PATH. Plugin is not loaded.' ++ " Skip loading the plugin ++ let loaded_taglist = 'no' ++ let &cpo = s:cpo_save ++ finish ++ endif ++ endif ++ ++ ++ " Automatically open the taglist window on Vim startup ++ if !exists('Tlist_Auto_Open') ++ let Tlist_Auto_Open = 0 ++ endif ++ ++ " When the taglist window is toggle opened, move the cursor to the ++ " taglist window ++ if !exists('Tlist_GainFocus_On_ToggleOpen') ++ let Tlist_GainFocus_On_ToggleOpen = 0 ++ endif ++ ++ " Process files even when the taglist window is not open ++ if !exists('Tlist_Process_File_Always') ++ let Tlist_Process_File_Always = 0 ++ endif ++ ++ if !exists('Tlist_Show_Menu') ++ let Tlist_Show_Menu = 0 ++ endif ++ ++ " Tag listing sort type - 'name' or 'order' ++ if !exists('Tlist_Sort_Type') ++ let Tlist_Sort_Type = 'order' ++ endif ++ ++ " Tag listing window split (horizontal/vertical) control ++ if !exists('Tlist_Use_Horiz_Window') ++ let Tlist_Use_Horiz_Window = 0 ++ endif ++ ++ " Open the vertically split taglist window on the left or on the right ++ " side. This setting is relevant only if Tlist_Use_Horiz_Window is set to ++ " zero (i.e. only for vertically split windows) ++ if !exists('Tlist_Use_Right_Window') ++ let Tlist_Use_Right_Window = 0 ++ endif ++ ++ " Increase Vim window width to display vertically split taglist window. ++ " For MS-Windows version of Vim running in a MS-DOS window, this must be ++ " set to 0 otherwise the system may hang due to a Vim limitation. ++ if !exists('Tlist_Inc_Winwidth') ++ if (has('win16') || has('win95')) && !has('gui_running') ++ let Tlist_Inc_Winwidth = 0 ++ else ++ let Tlist_Inc_Winwidth = 1 ++ endif ++ endif ++ ++ " Vertically split taglist window width setting ++ if !exists('Tlist_WinWidth') ++ let Tlist_WinWidth = 30 ++ endif ++ ++ " Horizontally split taglist window height setting ++ if !exists('Tlist_WinHeight') ++ let Tlist_WinHeight = 10 ++ endif ++ ++ " Display tag prototypes or tag names in the taglist window ++ if !exists('Tlist_Display_Prototype') ++ let Tlist_Display_Prototype = 0 ++ endif ++ ++ " Display tag scopes in the taglist window ++ if !exists('Tlist_Display_Tag_Scope') ++ let Tlist_Display_Tag_Scope = 1 ++ endif ++ ++ " Use single left mouse click to jump to a tag. By default this is disabled. ++ " Only double click using the mouse will be processed. ++ if !exists('Tlist_Use_SingleClick') ++ let Tlist_Use_SingleClick = 0 ++ endif ++ ++ " Control whether additional help is displayed as part of the taglist or ++ " not. Also, controls whether empty lines are used to separate the tag ++ " tree. ++ if !exists('Tlist_Compact_Format') ++ let Tlist_Compact_Format = 0 ++ endif ++ ++ " Exit Vim if only the taglist window is currently open. By default, this is ++ " set to zero. ++ if !exists('Tlist_Exit_OnlyWindow') ++ let Tlist_Exit_OnlyWindow = 0 ++ endif ++ ++ " Automatically close the folds for the non-active files in the taglist ++ " window ++ if !exists('Tlist_File_Fold_Auto_Close') ++ let Tlist_File_Fold_Auto_Close = 0 ++ endif ++ ++ " Close the taglist window when a tag is selected ++ if !exists('Tlist_Close_On_Select') ++ let Tlist_Close_On_Select = 0 ++ endif ++ ++ " Automatically update the taglist window to display tags for newly ++ " edited files ++ if !exists('Tlist_Auto_Update') ++ let Tlist_Auto_Update = 1 ++ endif ++ ++ " Automatically highlight the current tag ++ if !exists('Tlist_Auto_Highlight_Tag') ++ let Tlist_Auto_Highlight_Tag = 1 ++ endif ++ ++ " Automatically highlight the current tag on entering a buffer ++ if !exists('Tlist_Highlight_Tag_On_BufEnter') ++ let Tlist_Highlight_Tag_On_BufEnter = 1 ++ endif ++ ++ " Enable fold column to display the folding for the tag tree ++ if !exists('Tlist_Enable_Fold_Column') ++ let Tlist_Enable_Fold_Column = 1 ++ endif ++ ++ " Display the tags for only one file in the taglist window ++ if !exists('Tlist_Show_One_File') ++ let Tlist_Show_One_File = 0 ++ endif ++ ++ if !exists('Tlist_Max_Submenu_Items') ++ let Tlist_Max_Submenu_Items = 20 ++ endif ++ ++ if !exists('Tlist_Max_Tag_Length') ++ let Tlist_Max_Tag_Length = 10 ++ endif ++ ++ " Do not change the name of the taglist title variable. The winmanager ++ " plugin relies on this name to determine the title for the taglist ++ " plugin. ++ let TagList_title = "__Tag_List__" ++ ++ " Taglist debug messages ++ let s:tlist_msg = '' ++ ++ " Define the taglist autocommand to automatically open the taglist window ++ " on Vim startup ++ if g:Tlist_Auto_Open ++ autocmd VimEnter * nested call s:Tlist_Window_Check_Auto_Open() ++ endif ++ ++ " Refresh the taglist ++ if g:Tlist_Process_File_Always ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ ++ if g:Tlist_Show_Menu ++ autocmd GUIEnter * call s:Tlist_Menu_Init() ++ endif ++ ++ " When the taglist buffer is created when loading a Vim session file, ++ " the taglist buffer needs to be initialized. The BufFilePost event ++ " is used to handle this case. ++ autocmd BufFilePost __Tag_List__ call s:Tlist_Vim_Session_Load() ++ ++ " Define the user commands to manage the taglist window ++ command! -nargs=0 -bar TlistToggle call s:Tlist_Window_Toggle() ++ command! -nargs=0 -bar TlistOpen call s:Tlist_Window_Open() ++ " For backwards compatiblity define the Tlist command ++ command! -nargs=0 -bar Tlist TlistToggle ++ command! -nargs=+ -complete=file TlistAddFiles ++ \ call s:Tlist_Add_Files() ++ command! -nargs=+ -complete=dir TlistAddFilesRecursive ++ \ call s:Tlist_Add_Files_Recursive() ++ command! -nargs=0 -bar TlistClose call s:Tlist_Window_Close() ++ command! -nargs=0 -bar TlistUpdate call s:Tlist_Update_Current_File() ++ command! -nargs=0 -bar TlistHighlightTag call s:Tlist_Window_Highlight_Tag( ++ \ fnamemodify(bufname('%'), ':p'), line('.'), 2, 1) ++ " For backwards compatiblity define the TlistSync command ++ command! -nargs=0 -bar TlistSync TlistHighlightTag ++ command! -nargs=* -complete=buffer TlistShowPrototype ++ \ echo Tlist_Get_Tag_Prototype_By_Line() ++ command! -nargs=* -complete=buffer TlistShowTag ++ \ echo Tlist_Get_Tagname_By_Line() ++ command! -nargs=* -complete=file TlistSessionLoad ++ \ call s:Tlist_Session_Load() ++ command! -nargs=* -complete=file TlistSessionSave ++ \ call s:Tlist_Session_Save() ++ command! -bar TlistLock let Tlist_Auto_Update=0 ++ command! -bar TlistUnlock let Tlist_Auto_Update=1 ++ ++ " Commands for enabling/disabling debug and to display debug messages ++ command! -nargs=? -complete=file -bar TlistDebug ++ \ call s:Tlist_Debug_Enable() ++ command! -nargs=0 -bar TlistUndebug call s:Tlist_Debug_Disable() ++ command! -nargs=0 -bar TlistMessages call s:Tlist_Debug_Show() ++ ++ " Define autocommands to autoload the taglist plugin when needed. ++ ++ " Trick to get the current script ID ++ map xx xx ++ let s:tlist_sid = substitute(maparg('xx'), '\(\d\+_\)xx$', ++ \ '\1', '') ++ unmap xx ++ ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Window_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined *' . s:tlist_sid . 'Tlist_Menu_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined Tlist_* source ' . ++ \ escape(expand(''), ' ') ++ exe 'autocmd FuncUndefined TagList_* source ' . ++ \ escape(expand(''), ' ') ++ ++ let loaded_taglist = 'fast_load_done' ++ ++ if g:Tlist_Show_Menu && has('gui_running') ++ call s:Tlist_Menu_Init() ++ endif ++ ++ " restore 'cpo' ++ let &cpo = s:cpo_save ++ finish ++endif ++ ++if !exists('s:tlist_sid') ++ " Two or more versions of taglist plugin are installed. Don't ++ " load this version of the plugin. ++ finish ++endif ++ ++unlet! s:tlist_sid ++ ++if loaded_taglist != 'fast_load_done' ++ " restore 'cpo' ++ let &cpo = s:cpo_save ++ finish ++endif ++ ++" Taglist plugin functionality is available ++let loaded_taglist = 'available' ++ ++"------------------- end of user configurable options -------------------- ++ ++" Default language specific settings for supported file types and tag types ++" ++" Variable name format: ++" ++" s:tlist_def_{vim_ftype}_settings ++" ++" vim_ftype - Filetype detected by Vim ++" ++" Value format: ++" ++" ;:;:;... ++" ++" ctags_ftype - File type supported by exuberant ctags ++" flag - Flag supported by exuberant ctags to generate a tag type ++" name - Name of the tag type used in the taglist window to display the ++" tags of this type ++" ++ ++" Ada language ++let s:tlist_def_ada_settings = 'ada;' . ++ \ 'P:package spec;' . ++ \ 'p:package body;' . ++ \ 'T:type spec;' . ++ \ 't:type;' . ++ \ 'U:subtype spec;' . ++ \ 'u:subtype;' . ++ \ 'c:component;' . ++ \ 'l:literal;' . ++ \ 'V:variable spec;' . ++ \ 'v:variable;' . ++ \ 'f:formal;' . ++ \ 'n:constant;' . ++ \ 'x:exception;' . ++ \ 'R:subprogram spec;' . ++ \ 'r:subprogram body;' . ++ \ 'K:task spec;' . ++ \ 'k:task body;' . ++ \ 'O:protected spec;' . ++ \ 'o:protected body;' . ++ \ 'E:entry spec;' . ++ \ 'e:entry body;' . ++ \ 'b:label;' . ++ \ 'i:identifier;' . ++ \ 'a:autovar;' . ++ \ 'y:annon' ++ ++" assembly language ++let s:tlist_def_asm_settings = 'asm;d:define;l:label;m:macro;t:type' ++ ++" aspperl language ++let s:tlist_def_aspperl_settings = 'asp;f:function;s:sub;v:variable' ++ ++" aspvbs language ++let s:tlist_def_aspvbs_settings = 'asp;f:function;s:sub;v:variable' ++ ++" awk language ++let s:tlist_def_awk_settings = 'awk;f:function' ++ ++" beta language ++let s:tlist_def_beta_settings = 'beta;f:fragment;s:slot;v:pattern' ++ ++" c language ++let s:tlist_def_c_settings = 'c;d:macro;g:enum;s:struct;u:union;t:typedef;' . ++ \ 'v:variable;f:function' ++ ++" c++ language ++let s:tlist_def_cpp_settings = 'c++;n:namespace;v:variable;d:macro;t:typedef;' . ++ \ 'c:class;g:enum;s:struct;u:union;f:function' ++ ++" c# language ++let s:tlist_def_cs_settings = 'c#;d:macro;t:typedef;n:namespace;c:class;' . ++ \ 'E:event;g:enum;s:struct;i:interface;' . ++ \ 'p:properties;m:method' ++ ++" cobol language ++let s:tlist_def_cobol_settings = 'cobol;d:data;f:file;g:group;p:paragraph;' . ++ \ 'P:program;s:section' ++ ++" eiffel language ++let s:tlist_def_eiffel_settings = 'eiffel;c:class;f:feature' ++ ++" erlang language ++let s:tlist_def_erlang_settings = 'erlang;d:macro;r:record;m:module;f:function' ++ ++" expect (same as tcl) language ++let s:tlist_def_expect_settings = 'tcl;c:class;f:method;p:procedure' ++ ++" fortran language ++let s:tlist_def_fortran_settings = 'fortran;p:program;b:block data;' . ++ \ 'c:common;e:entry;i:interface;k:type;l:label;m:module;' . ++ \ 'n:namelist;t:derived;v:variable;f:function;s:subroutine' ++ ++" HTML language ++let s:tlist_def_html_settings = 'html;a:anchor;f:javascript function' ++ ++" java language ++let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' . ++ \ 'f:field;m:method' ++ ++" javascript language ++let s:tlist_def_javascript_settings = 'javascript;f:function' ++ ++" lisp language ++let s:tlist_def_lisp_settings = 'lisp;f:function' ++ ++" lua language ++let s:tlist_def_lua_settings = 'lua;f:function' ++ ++" makefiles ++let s:tlist_def_make_settings = 'make;m:macro' ++ ++" pascal language ++let s:tlist_def_pascal_settings = 'pascal;f:function;p:procedure' ++ ++" perl language ++let s:tlist_def_perl_settings = 'perl;c:constant;l:label;p:package;s:subroutine' ++ ++" php language ++let s:tlist_def_php_settings = 'php;c:class;d:constant;v:variable;f:function' ++ ++" python language ++let s:tlist_def_python_settings = 'python;c:class;m:member;f:function' ++ ++" rexx language ++let s:tlist_def_rexx_settings = 'rexx;s:subroutine' ++ ++" ruby language ++let s:tlist_def_ruby_settings = 'ruby;c:class;f:method;F:function;' . ++ \ 'm:singleton method' ++ ++" scheme language ++let s:tlist_def_scheme_settings = 'scheme;s:set;f:function' ++ ++" shell language ++let s:tlist_def_sh_settings = 'sh;f:function' ++ ++" C shell language ++let s:tlist_def_csh_settings = 'sh;f:function' ++ ++" Z shell language ++let s:tlist_def_zsh_settings = 'sh;f:function' ++ ++" slang language ++let s:tlist_def_slang_settings = 'slang;n:namespace;f:function' ++ ++" sml language ++let s:tlist_def_sml_settings = 'sml;e:exception;c:functor;s:signature;' . ++ \ 'r:structure;t:type;v:value;f:function' ++ ++" sql language ++let s:tlist_def_sql_settings = 'sql;c:cursor;F:field;P:package;r:record;' . ++ \ 's:subtype;t:table;T:trigger;v:variable;f:function;p:procedure' ++ ++" tcl language ++let s:tlist_def_tcl_settings = 'tcl;c:class;f:method;m:method;p:procedure' ++ ++" vera language ++let s:tlist_def_vera_settings = 'vera;c:class;d:macro;e:enumerator;' . ++ \ 'f:function;g:enum;m:member;p:program;' . ++ \ 'P:prototype;t:task;T:typedef;v:variable;' . ++ \ 'x:externvar' ++ ++"verilog language ++let s:tlist_def_verilog_settings = 'verilog;m:module;c:constant;P:parameter;' . ++ \ 'e:event;r:register;t:task;w:write;p:port;v:variable;f:function' ++ ++" vim language ++let s:tlist_def_vim_settings = 'vim;a:autocmds;v:variable;f:function' ++ ++" yacc language ++let s:tlist_def_yacc_settings = 'yacc;l:label' ++ ++"------------------- end of language specific options -------------------- ++ ++" Vim window size is changed by the taglist plugin or not ++let s:tlist_winsize_chgd = -1 ++" Taglist window is maximized or not ++let s:tlist_win_maximized = 0 ++" Name of files in the taglist ++let s:tlist_file_names='' ++" Number of files in the taglist ++let s:tlist_file_count = 0 ++" Number of filetypes supported by taglist ++let s:tlist_ftype_count = 0 ++" Is taglist part of other plugins like winmanager or cream? ++let s:tlist_app_name = "none" ++" Are we displaying brief help text ++let s:tlist_brief_help = 1 ++" List of files removed on user request ++let s:tlist_removed_flist = "" ++" Index of current file displayed in the taglist window ++let s:tlist_cur_file_idx = -1 ++" Taglist menu is empty or not ++let s:tlist_menu_empty = 1 ++ ++" An autocommand is used to refresh the taglist window when entering any ++" buffer. We don't want to refresh the taglist window if we are entering the ++" file window from one of the taglist functions. The 'Tlist_Skip_Refresh' ++" variable is used to skip the refresh of the taglist window and is set ++" and cleared appropriately. ++let s:Tlist_Skip_Refresh = 0 ++ ++" Tlist_Window_Display_Help() ++function! s:Tlist_Window_Display_Help() ++ if s:tlist_app_name == "winmanager" ++ " To handle a bug in the winmanager plugin, add a space at the ++ " last line ++ call setline('$', ' ') ++ endif ++ ++ if s:tlist_brief_help ++ " Add the brief help ++ call append(0, '" Press to display help text') ++ else ++ " Add the extensive help ++ call append(0, '" : Jump to tag definition') ++ call append(1, '" o : Jump to tag definition in new window') ++ call append(2, '" p : Preview the tag definition') ++ call append(3, '" : Display tag prototype') ++ call append(4, '" u : Update tag list') ++ call append(5, '" s : Select sort field') ++ call append(6, '" d : Remove file from taglist') ++ call append(7, '" x : Zoom-out/Zoom-in taglist window') ++ call append(8, '" + : Open a fold') ++ call append(9, '" - : Close a fold') ++ call append(10, '" * : Open all folds') ++ call append(11, '" = : Close all folds') ++ call append(12, '" [[ : Move to the start of previous file') ++ call append(13, '" ]] : Move to the start of next file') ++ call append(14, '" q : Close the taglist window') ++ call append(15, '" : Remove help text') ++ endif ++endfunction ++ ++" Tlist_Window_Toggle_Help_Text() ++" Toggle taglist plugin help text between the full version and the brief ++" version ++function! s:Tlist_Window_Toggle_Help_Text() ++ if g:Tlist_Compact_Format ++ " In compact display mode, do not display help ++ return ++ endif ++ ++ " Include the empty line displayed after the help text ++ let brief_help_size = 1 ++ let full_help_size = 16 ++ ++ setlocal modifiable ++ ++ " Set report option to a huge value to prevent informational messages ++ " while deleting the lines ++ let old_report = &report ++ set report=99999 ++ ++ " Remove the currently highlighted tag. Otherwise, the help text ++ " might be highlighted by mistake ++ match none ++ ++ " Toggle between brief and full help text ++ if s:tlist_brief_help ++ let s:tlist_brief_help = 0 ++ ++ " Remove the previous help ++ exe '1,' . brief_help_size . ' delete _' ++ ++ " Adjust the start/end line numbers for the files ++ call s:Tlist_Window_Update_Line_Offsets(0, 1, full_help_size - brief_help_size) ++ else ++ let s:tlist_brief_help = 1 ++ ++ " Remove the previous help ++ exe '1,' . full_help_size . ' delete _' ++ ++ " Adjust the start/end line numbers for the files ++ call s:Tlist_Window_Update_Line_Offsets(0, 0, full_help_size - brief_help_size) ++ endif ++ ++ call s:Tlist_Window_Display_Help() ++ ++ " Restore the report option ++ let &report = old_report ++ ++ setlocal nomodifiable ++endfunction ++ ++" Taglist debug support ++let s:tlist_debug = 0 ++ ++" File for storing the debug messages ++let s:tlist_debug_file = '' ++ ++" Tlist_Debug_Enable ++" Enable logging of taglist debug messages. ++function! s:Tlist_Debug_Enable(...) ++ let s:tlist_debug = 1 ++ ++ " Check whether a valid file name is supplied. ++ if a:1 != '' ++ let s:tlist_debug_file = fnamemodify(a:1, ':p') ++ ++ " Empty the log file ++ exe 'redir! > ' . s:tlist_debug_file ++ redir END ++ ++ " Check whether the log file is present/created ++ if !filewritable(s:tlist_debug_file) ++ call s:Tlist_Warning_Msg('Taglist: Unable to create log file ' ++ \ . s:tlist_debug_file) ++ let s:tlist_debug_file = '' ++ endif ++ endif ++endfunction ++ ++" Tlist_Debug_Disable ++" Disable logging of taglist debug messages. ++function! s:Tlist_Debug_Disable(...) ++ let s:tlist_debug = 0 ++ let s:tlist_debug_file = '' ++endfunction ++ ++" Tlist_Debug_Show ++" Display the taglist debug messages in a new window ++function! s:Tlist_Debug_Show() ++ if s:tlist_msg == '' ++ call s:Tlist_Warning_Msg('Taglist: No debug messages') ++ return ++ endif ++ ++ " Open a new window to display the taglist debug messages ++ new taglist_debug.txt ++ " Delete all the lines (if the buffer already exists) ++ silent! %delete _ ++ " Add the messages ++ silent! put =s:tlist_msg ++ " Move the cursor to the first line ++ normal! gg ++endfunction ++ ++" Tlist_Log_Msg ++" Log the supplied debug message along with the time ++function! s:Tlist_Log_Msg(msg) ++ if s:tlist_debug ++ if s:tlist_debug_file != '' ++ exe 'redir >> ' . s:tlist_debug_file ++ silent echon strftime('%H:%M:%S') . ': ' . a:msg . "\n" ++ redir END ++ else ++ " Log the message into a variable ++ " Retain only the last 3000 characters ++ let len = strlen(s:tlist_msg) ++ if len > 3000 ++ let s:tlist_msg = strpart(s:tlist_msg, len - 3000) ++ endif ++ let s:tlist_msg = s:tlist_msg . strftime('%H:%M:%S') . ': ' . ++ \ a:msg . "\n" ++ endif ++ endif ++endfunction ++ ++" Tlist_Warning_Msg() ++" Display a message using WarningMsg highlight group ++function! s:Tlist_Warning_Msg(msg) ++ echohl WarningMsg ++ echomsg a:msg ++ echohl None ++endfunction ++ ++" Last returned file index for file name lookup. ++" Used to speed up file lookup ++let s:tlist_file_name_idx_cache = -1 ++ ++" Tlist_Get_File_Index() ++" Return the index of the specified filename ++function! s:Tlist_Get_File_Index(fname) ++ if s:tlist_file_count == 0 || a:fname == '' ++ return -1 ++ endif ++ ++ " If the new filename is same as the last accessed filename, then ++ " return that index ++ if s:tlist_file_name_idx_cache != -1 && ++ \ s:tlist_file_name_idx_cache < s:tlist_file_count ++ if s:tlist_{s:tlist_file_name_idx_cache}_filename == a:fname ++ " Same as the last accessed file ++ return s:tlist_file_name_idx_cache ++ endif ++ endif ++ ++ " First, check whether the filename is present ++ let s_fname = a:fname . "\n" ++ let i = stridx(s:tlist_file_names, s_fname) ++ if i == -1 ++ let s:tlist_file_name_idx_cache = -1 ++ return -1 ++ endif ++ ++ " Second, compute the file name index ++ let nl_txt = substitute(strpart(s:tlist_file_names, 0, i), "[^\n]", '', 'g') ++ let s:tlist_file_name_idx_cache = strlen(nl_txt) ++ return s:tlist_file_name_idx_cache ++endfunction ++ ++" Last returned file index for line number lookup. ++" Used to speed up file lookup ++let s:tlist_file_lnum_idx_cache = -1 ++ ++" Tlist_Window_Get_File_Index_By_Linenum() ++" Return the index of the filename present in the specified line number ++" Line number refers to the line number in the taglist window ++function! s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ call s:Tlist_Log_Msg('Tlist_Window_Get_File_Index_By_Linenum (' . a:lnum . ')') ++ ++ " First try to see whether the new line number is within the range ++ " of the last returned file ++ if s:tlist_file_lnum_idx_cache != -1 && ++ \ s:tlist_file_lnum_idx_cache < s:tlist_file_count ++ if a:lnum >= s:tlist_{s:tlist_file_lnum_idx_cache}_start && ++ \ a:lnum <= s:tlist_{s:tlist_file_lnum_idx_cache}_end ++ return s:tlist_file_lnum_idx_cache ++ endif ++ endif ++ ++ let fidx = -1 ++ ++ if g:Tlist_Show_One_File ++ " Displaying only one file in the taglist window. Check whether ++ " the line is within the tags displayed for that file ++ if s:tlist_cur_file_idx != -1 ++ if a:lnum >= s:tlist_{s:tlist_cur_file_idx}_start ++ \ && a:lnum <= s:tlist_{s:tlist_cur_file_idx}_end ++ let fidx = s:tlist_cur_file_idx ++ endif ++ ++ endif ++ else ++ " Do a binary search in the taglist ++ let left = 0 ++ let right = s:tlist_file_count - 1 ++ ++ while left < right ++ let mid = (left + right) / 2 ++ ++ if a:lnum >= s:tlist_{mid}_start && a:lnum <= s:tlist_{mid}_end ++ let s:tlist_file_lnum_idx_cache = mid ++ return mid ++ endif ++ ++ if a:lnum < s:tlist_{mid}_start ++ let right = mid - 1 ++ else ++ let left = mid + 1 ++ endif ++ endwhile ++ ++ if left >= 0 && left < s:tlist_file_count ++ \ && a:lnum >= s:tlist_{left}_start ++ \ && a:lnum <= s:tlist_{left}_end ++ let fidx = left ++ endif ++ endif ++ ++ let s:tlist_file_lnum_idx_cache = fidx ++ ++ return fidx ++endfunction ++ ++" Tlist_Exe_Cmd_No_Acmds ++" Execute the specified Ex command after disabling autocommands ++function! s:Tlist_Exe_Cmd_No_Acmds(cmd) ++ let old_eventignore = &eventignore ++ set eventignore=all ++ exe a:cmd ++ let &eventignore = old_eventignore ++endfunction ++ ++" Tlist_Skip_File() ++" Check whether tag listing is supported for the specified file ++function! s:Tlist_Skip_File(filename, ftype) ++ " Skip buffers with no names and buffers with filetype not set ++ if a:filename == '' || a:ftype == '' ++ return 1 ++ endif ++ ++ " Skip files which are not supported by exuberant ctags ++ " First check whether default settings for this filetype are available. ++ " If it is not available, then check whether user specified settings are ++ " available. If both are not available, then don't list the tags for this ++ " filetype ++ let var = 's:tlist_def_' . a:ftype . '_settings' ++ if !exists(var) ++ let var = 'g:tlist_' . a:ftype . '_settings' ++ if !exists(var) ++ return 1 ++ endif ++ endif ++ ++ " Skip files which are not readable or files which are not yet stored ++ " to the disk ++ if !filereadable(a:filename) ++ return 1 ++ endif ++ ++ return 0 ++endfunction ++ ++" Tlist_User_Removed_File ++" Returns 1 if a file is removed by a user from the taglist ++function! s:Tlist_User_Removed_File(filename) ++ return stridx(s:tlist_removed_flist, a:filename . "\n") != -1 ++endfunction ++ ++" Tlist_Update_Remove_List ++" Update the list of user removed files from the taglist ++" add == 1, add the file to the removed list ++" add == 0, delete the file from the removed list ++function! s:Tlist_Update_Remove_List(filename, add) ++ if a:add ++ let s:tlist_removed_flist = s:tlist_removed_flist . a:filename . "\n" ++ else ++ let idx = stridx(s:tlist_removed_flist, a:filename . "\n") ++ let text_before = strpart(s:tlist_removed_flist, 0, idx) ++ let rem_text = strpart(s:tlist_removed_flist, idx) ++ let next_idx = stridx(rem_text, "\n") ++ let text_after = strpart(rem_text, next_idx + 1) ++ ++ let s:tlist_removed_flist = text_before . text_after ++ endif ++endfunction ++ ++" Tlist_FileType_Init ++" Initialize the ctags arguments and tag variable for the specified ++" file type ++function! s:Tlist_FileType_Init(ftype) ++ call s:Tlist_Log_Msg('Tlist_FileType_Init (' . a:ftype . ')') ++ " If the user didn't specify any settings, then use the default ++ " ctags args. Otherwise, use the settings specified by the user ++ let var = 'g:tlist_' . a:ftype . '_settings' ++ if exists(var) ++ " User specified ctags arguments ++ let settings = {var} . ';' ++ else ++ " Default ctags arguments ++ let var = 's:tlist_def_' . a:ftype . '_settings' ++ if !exists(var) ++ " No default settings for this file type. This filetype is ++ " not supported ++ return 0 ++ endif ++ let settings = s:tlist_def_{a:ftype}_settings . ';' ++ endif ++ ++ let msg = 'Taglist: Invalid ctags option setting - ' . settings ++ ++ " Format of the option that specifies the filetype and ctags arugments: ++ " ++ " ;flag1:name1;flag2:name2;flag3:name3 ++ " ++ ++ " Extract the file type to pass to ctags. This may be different from the ++ " file type detected by Vim ++ let pos = stridx(settings, ';') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let ctags_ftype = strpart(settings, 0, pos) ++ if ctags_ftype == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ " Make sure a valid filetype is supplied. If the user didn't specify a ++ " valid filetype, then the ctags option settings may be treated as the ++ " filetype ++ if ctags_ftype =~ ':' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ ++ " Remove the file type from settings ++ let settings = strpart(settings, pos + 1) ++ if settings == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ ++ " Process all the specified ctags flags. The format is ++ " flag1:name1;flag2:name2;flag3:name3 ++ let ctags_flags = '' ++ let cnt = 0 ++ while settings != '' ++ " Extract the flag ++ let pos = stridx(settings, ':') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let flag = strpart(settings, 0, pos) ++ if flag == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ " Remove the flag from settings ++ let settings = strpart(settings, pos + 1) ++ ++ " Extract the tag type name ++ let pos = stridx(settings, ';') ++ if pos == -1 ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let name = strpart(settings, 0, pos) ++ if name == '' ++ call s:Tlist_Warning_Msg(msg) ++ return 0 ++ endif ++ let settings = strpart(settings, pos + 1) ++ ++ let cnt = cnt + 1 ++ ++ let s:tlist_{a:ftype}_{cnt}_name = flag ++ let s:tlist_{a:ftype}_{cnt}_fullname = name ++ let ctags_flags = ctags_flags . flag ++ endwhile ++ ++ let s:tlist_{a:ftype}_ctags_args = '--language-force=' . ctags_ftype . ++ \ ' --' . ctags_ftype . '-types=' . ctags_flags ++ let s:tlist_{a:ftype}_count = cnt ++ let s:tlist_{a:ftype}_ctags_flags = ctags_flags ++ ++ " Save the filetype name ++ let s:tlist_ftype_{s:tlist_ftype_count}_name = a:ftype ++ let s:tlist_ftype_count = s:tlist_ftype_count + 1 ++ ++ return 1 ++endfunction ++ ++" Tlist_Get_Filetype ++" Determine the filetype for the specified file ++function! s:Tlist_Get_Filetype(fname) ++ " Ignore the filetype autocommands ++ let old_eventignore = &eventignore ++ set eventignore=FileType ++ ++ " Save the 'filetype', as this will be changed temporarily ++ let old_filetype = &filetype ++ ++ " Run the filetypedetect group of autocommands to determine ++ " the filetype ++ exe 'doautocmd filetypedetect BufRead ' . a:fname ++ ++ " Save the detected filetype ++ let ftype = &filetype ++ ++ " Restore the previous state ++ let &filetype = old_filetype ++ let &eventignore = old_eventignore ++ ++ return ftype ++endfunction ++ ++" Tlist_Get_Buffer_Filetype ++" Get the filetype for the specified buffer ++function! s:Tlist_Get_Buffer_Filetype(bnum) ++ if bufloaded(a:bnum) ++ " For loaded buffers, the 'filetype' is already determined ++ return getbufvar(a:bnum, '&filetype') ++ endif ++ ++ " For unloaded buffers, if the 'filetype' option is set, return it ++ let ftype = getbufvar(a:bnum, '&filetype') ++ if ftype != '' ++ return ftype ++ endif ++ ++ " Skip non-existent buffers ++ if !bufexists(a:bnum) ++ return '' ++ endif ++ ++ " For buffers whose filetype is not yet determined, try to determine ++ " the filetype ++ let bname = bufname(a:bnum) ++ ++ return s:Tlist_Get_Filetype(bname) ++endfunction ++ ++" Tlist_Discard_TagInfo ++" Discard the stored tag information for a file ++function! s:Tlist_Discard_TagInfo(fidx) ++ call s:Tlist_Log_Msg('Tlist_Discard_TagInfo (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ " Discard information about the tags defined in the file ++ let i = 1 ++ while i <= s:tlist_{a:fidx}_tag_count ++ let fidx_i = 's:tlist_' . a:fidx . '_' . i ++ unlet! {fidx_i}_tag ++ unlet! {fidx_i}_tag_name ++ unlet! {fidx_i}_tag_type ++ unlet! {fidx_i}_ttype_idx ++ unlet! {fidx_i}_tag_proto ++ unlet! {fidx_i}_tag_searchpat ++ unlet! {fidx_i}_tag_linenum ++ let i = i + 1 ++ endwhile ++ ++ let s:tlist_{a:fidx}_tag_count = 0 ++ ++ " Discard information about tag type groups ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ if s:tlist_{a:fidx}_{ttype} != '' ++ let fidx_ttype = 's:tlist_' . a:fidx . '_' . ttype ++ let {fidx_ttype} = '' ++ let {fidx_ttype}_offset = 0 ++ let cnt = {fidx_ttype}_count ++ let {fidx_ttype}_count = 0 ++ let j = 1 ++ while j <= cnt ++ unlet! {fidx_ttype}_{j} ++ let j = j + 1 ++ endwhile ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Discard the stored menu command also ++ let s:tlist_{a:fidx}_menu_cmd = '' ++endfunction ++ ++" Tlist_Window_Update_Line_Offsets ++" Update the line offsets for tags for files starting from start_idx ++" and displayed in the taglist window by the specified offset ++function! s:Tlist_Window_Update_Line_Offsets(start_idx, increment, offset) ++ let i = a:start_idx ++ ++ while i < s:tlist_file_count ++ if s:tlist_{i}_visible ++ " Update the start/end line number only if the file is visible ++ if a:increment ++ let s:tlist_{i}_start = s:tlist_{i}_start + a:offset ++ let s:tlist_{i}_end = s:tlist_{i}_end + a:offset ++ else ++ let s:tlist_{i}_start = s:tlist_{i}_start - a:offset ++ let s:tlist_{i}_end = s:tlist_{i}_end - a:offset ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++endfunction ++ ++" Tlist_Discard_FileInfo ++" Discard the stored information for a file ++function! s:Tlist_Discard_FileInfo(fidx) ++ call s:Tlist_Log_Msg('Tlist_Discard_FileInfo (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ call s:Tlist_Discard_TagInfo(a:fidx) ++ ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ unlet! s:tlist_{a:fidx}_{ttype} ++ unlet! s:tlist_{a:fidx}_{ttype}_offset ++ unlet! s:tlist_{a:fidx}_{ttype}_count ++ let i = i + 1 ++ endwhile ++ ++ unlet! s:tlist_{a:fidx}_filename ++ unlet! s:tlist_{a:fidx}_sort_type ++ unlet! s:tlist_{a:fidx}_filetype ++ unlet! s:tlist_{a:fidx}_mtime ++ unlet! s:tlist_{a:fidx}_start ++ unlet! s:tlist_{a:fidx}_end ++ unlet! s:tlist_{a:fidx}_valid ++ unlet! s:tlist_{a:fidx}_visible ++ unlet! s:tlist_{a:fidx}_tag_count ++ unlet! s:tlist_{a:fidx}_menu_cmd ++endfunction ++ ++" Tlist_Window_Remove_File_From_Display ++" Remove the specified file from display ++function! s:Tlist_Window_Remove_File_From_Display(fidx) ++ call s:Tlist_Log_Msg('Tlist_Window_Remove_File_From_Display (' . ++ \ s:tlist_{a:fidx}_filename . ')') ++ " If the file is not visible then no need to remove it ++ if !s:tlist_{a:fidx}_visible ++ return ++ endif ++ ++ " Remove the tags displayed for the specified file from the window ++ let start = s:tlist_{a:fidx}_start ++ " Include the empty line after the last line also ++ if g:Tlist_Compact_Format ++ let end = s:tlist_{a:fidx}_end ++ else ++ let end = s:tlist_{a:fidx}_end + 1 ++ endif ++ ++ setlocal modifiable ++ exe 'silent! ' . start . ',' . end . 'delete _' ++ setlocal nomodifiable ++ ++ " Correct the start and end line offsets for all the files following ++ " this file, as the tags for this file are removed ++ call s:Tlist_Window_Update_Line_Offsets(a:fidx + 1, 0, end - start + 1) ++endfunction ++ ++" Tlist_Remove_File ++" Remove the file under the cursor or the specified file index ++" user_request - User requested to remove the file from taglist ++function! s:Tlist_Remove_File(file_idx, user_request) ++ let fidx = a:file_idx ++ ++ if fidx == -1 ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ endif ++ call s:Tlist_Log_Msg('Tlist_Remove_File (' . ++ \ s:tlist_{fidx}_filename . ', ' . a:user_request . ')') ++ ++ let save_winnr = winnr() ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Taglist window is open, remove the file from display ++ ++ if save_winnr != winnum ++ let old_eventignore = &eventignore ++ set eventignore=all ++ exe winnum . 'wincmd w' ++ endif ++ ++ call s:Tlist_Window_Remove_File_From_Display(fidx) ++ ++ if save_winnr != winnum ++ exe save_winnr . 'wincmd w' ++ let &eventignore = old_eventignore ++ endif ++ endif ++ ++ let fname = s:tlist_{fidx}_filename ++ ++ if a:user_request ++ " As the user requested to remove the file from taglist, ++ " add it to the removed list ++ call s:Tlist_Update_Remove_List(fname, 1) ++ endif ++ ++ " Remove the file name from the taglist list of filenames ++ let idx = stridx(s:tlist_file_names, fname . "\n") ++ let text_before = strpart(s:tlist_file_names, 0, idx) ++ let rem_text = strpart(s:tlist_file_names, idx) ++ let next_idx = stridx(rem_text, "\n") ++ let text_after = strpart(rem_text, next_idx + 1) ++ let s:tlist_file_names = text_before . text_after ++ ++ call s:Tlist_Discard_FileInfo(fidx) ++ ++ " Shift all the file variables by one index ++ let i = fidx + 1 ++ ++ while i < s:tlist_file_count ++ let j = i - 1 ++ ++ let s:tlist_{j}_filename = s:tlist_{i}_filename ++ let s:tlist_{j}_sort_type = s:tlist_{i}_sort_type ++ let s:tlist_{j}_filetype = s:tlist_{i}_filetype ++ let s:tlist_{j}_mtime = s:tlist_{i}_mtime ++ let s:tlist_{j}_start = s:tlist_{i}_start ++ let s:tlist_{j}_end = s:tlist_{i}_end ++ let s:tlist_{j}_valid = s:tlist_{i}_valid ++ let s:tlist_{j}_visible = s:tlist_{i}_visible ++ let s:tlist_{j}_tag_count = s:tlist_{i}_tag_count ++ let s:tlist_{j}_menu_cmd = s:tlist_{i}_menu_cmd ++ ++ let k = 1 ++ while k <= s:tlist_{j}_tag_count ++ let s:tlist_{j}_{k}_tag = s:tlist_{i}_{k}_tag ++ let s:tlist_{j}_{k}_tag_name = s:tlist_{i}_{k}_tag_name ++ let s:tlist_{j}_{k}_tag_type = s:Tlist_Get_Tag_Type_By_Tag(i, k) ++ let s:tlist_{j}_{k}_ttype_idx = s:tlist_{i}_{k}_ttype_idx ++ let s:tlist_{j}_{k}_tag_proto = s:Tlist_Get_Tag_Prototype(i, k) ++ let s:tlist_{j}_{k}_tag_searchpat = s:Tlist_Get_Tag_SearchPat(i, k) ++ let s:tlist_{j}_{k}_tag_linenum = s:Tlist_Get_Tag_Linenum(i, k) ++ let k = k + 1 ++ endwhile ++ ++ let ftype = s:tlist_{i}_filetype ++ ++ let k = 1 ++ while k <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{k}_name ++ let s:tlist_{j}_{ttype} = s:tlist_{i}_{ttype} ++ let s:tlist_{j}_{ttype}_offset = s:tlist_{i}_{ttype}_offset ++ let s:tlist_{j}_{ttype}_count = s:tlist_{i}_{ttype}_count ++ if s:tlist_{j}_{ttype} != '' ++ let l = 1 ++ while l <= s:tlist_{j}_{ttype}_count ++ let s:tlist_{j}_{ttype}_{l} = s:tlist_{i}_{ttype}_{l} ++ let l = l + 1 ++ endwhile ++ endif ++ let k = k + 1 ++ endwhile ++ ++ " As the file and tag information is copied to the new index, ++ " discard the previous information ++ call s:Tlist_Discard_FileInfo(i) ++ ++ let i = i + 1 ++ endwhile ++ ++ " Reduce the number of files displayed ++ let s:tlist_file_count = s:tlist_file_count - 1 ++ ++ if g:Tlist_Show_One_File ++ " If the tags for only one file is displayed and if we just ++ " now removed that file, then invalidate the current file idx ++ if s:tlist_cur_file_idx == fidx ++ let s:tlist_cur_file_idx = -1 ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Goto_Window ++" Goto the taglist window ++function! s:Tlist_Window_Goto_Window() ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ if winnr() != winnum ++ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Create ++" Create a new taglist window. If it is already open, jump to it ++function! s:Tlist_Window_Create() ++ call s:Tlist_Log_Msg('Tlist_Window_Create()') ++ " If the window is open, jump to it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Jump to the existing window ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ return ++ endif ++ ++ " If used with winmanager don't open windows. Winmanager will handle ++ " the window/buffer management ++ if s:tlist_app_name == "winmanager" ++ return ++ endif ++ ++ " Create a new window. If user prefers a horizontal window, then open ++ " a horizontally split window. Otherwise open a vertically split ++ " window ++ if g:Tlist_Use_Horiz_Window ++ " Open a horizontally split window ++ let win_dir = 'botright' ++ " Horizontal window height ++ let win_size = g:Tlist_WinHeight ++ else ++ if s:tlist_winsize_chgd == -1 ++ " Open a vertically split window. Increase the window size, if ++ " needed, to accomodate the new window ++ if g:Tlist_Inc_Winwidth && ++ \ &columns < (80 + g:Tlist_WinWidth) ++ " Save the original window position ++ let s:tlist_pre_winx = getwinposx() ++ let s:tlist_pre_winy = getwinposy() ++ ++ " one extra column is needed to include the vertical split ++ let &columns= &columns + g:Tlist_WinWidth + 1 ++ ++ let s:tlist_winsize_chgd = 1 ++ else ++ let s:tlist_winsize_chgd = 0 ++ endif ++ endif ++ ++ if g:Tlist_Use_Right_Window ++ " Open the window at the rightmost place ++ let win_dir = 'botright vertical' ++ else ++ " Open the window at the leftmost place ++ let win_dir = 'topleft vertical' ++ endif ++ let win_size = g:Tlist_WinWidth ++ endif ++ ++ " If the tag listing temporary buffer already exists, then reuse it. ++ " Otherwise create a new buffer ++ let bufnum = bufnr(g:TagList_title) ++ if bufnum == -1 ++ " Create a new buffer ++ let wcmd = g:TagList_title ++ else ++ " Edit the existing buffer ++ let wcmd = '+buffer' . bufnum ++ endif ++ ++ " Create the taglist window ++ exe 'silent! ' . win_dir . ' ' . win_size . 'split ' . wcmd ++ ++ " Save the new window position ++ let s:tlist_winx = getwinposx() ++ let s:tlist_winy = getwinposy() ++ ++ " Initialize the taglist window ++ call s:Tlist_Window_Init() ++endfunction ++ ++" Tlist_Window_Zoom ++" Zoom (maximize/minimize) the taglist window ++function! s:Tlist_Window_Zoom() ++ if s:tlist_win_maximized ++ " Restore the window back to the previous size ++ if g:Tlist_Use_Horiz_Window ++ exe 'resize ' . g:Tlist_WinHeight ++ else ++ exe 'vert resize ' . g:Tlist_WinWidth ++ endif ++ let s:tlist_win_maximized = 0 ++ else ++ " Set the window size to the maximum possible without closing other ++ " windows ++ if g:Tlist_Use_Horiz_Window ++ resize ++ else ++ vert resize ++ endif ++ let s:tlist_win_maximized = 1 ++ endif ++endfunction ++ ++" Tlist_Ballon_Expr ++" When the mouse cursor is over a tag in the taglist window, display the ++" tag prototype (balloon) ++function! Tlist_Ballon_Expr() ++ " Get the file index ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(v:beval_lnum) ++ if fidx == -1 ++ return '' ++ endif ++ ++ " Get the tag output line for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, v:beval_lnum) ++ if tidx == 0 ++ return '' ++ endif ++ ++ " Get the tag search pattern and display it ++ return s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Window_Check_Width ++" Check the width of the taglist window. For horizontally split windows, the ++" 'winfixheight' option is used to fix the height of the window. For ++" vertically split windows, Vim doesn't support the 'winfixwidth' option. So ++" need to handle window width changes from this function. ++function! s:Tlist_Window_Check_Width() ++ let tlist_winnr = bufwinnr(g:TagList_title) ++ if tlist_winnr == -1 ++ return ++ endif ++ ++ let width = winwidth(tlist_winnr) ++ if width != g:Tlist_WinWidth ++ call s:Tlist_Log_Msg("Tlist_Window_Check_Width: Changing window " . ++ \ "width from " . width . " to " . g:Tlist_WinWidth) ++ let save_winnr = winnr() ++ if save_winnr != tlist_winnr ++ call s:Tlist_Exe_Cmd_No_Acmds(tlist_winnr . 'wincmd w') ++ endif ++ exe 'vert resize ' . g:Tlist_WinWidth ++ if save_winnr != tlist_winnr ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Exit_Only_Window ++" If the 'Tlist_Exit_OnlyWindow' option is set, then exit Vim if only the ++" taglist window is present. ++function! s:Tlist_Window_Exit_Only_Window() ++ " Before quitting Vim, delete the taglist buffer so that ++ " the '0 mark is correctly set to the previous buffer. ++ if v:version < 700 ++ if winbufnr(2) == -1 ++ bdelete ++ quit ++ endif ++ else ++ if winbufnr(2) == -1 ++ if tabpagenr('$') == 1 ++ " Only one tag page is present ++ bdelete ++ quit ++ else ++ " More than one tab page is present. Close only the current ++ " tab page ++ close ++ endif ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Init ++" Set the default options for the taglist window ++function! s:Tlist_Window_Init() ++ call s:Tlist_Log_Msg('Tlist_Window_Init()') ++ ++ " The 'readonly' option should not be set for the taglist buffer. ++ " If Vim is started as "view/gview" or if the ":view" command is ++ " used, then the 'readonly' option is set for all the buffers. ++ " Unset it for the taglist buffer ++ setlocal noreadonly ++ ++ " Set the taglist buffer filetype to taglist ++ setlocal filetype=taglist ++ ++ " Define taglist window element highlighting ++ syntax match TagListComment '^" .*' ++ syntax match TagListFileName '^[^" ].*$' ++ syntax match TagListTitle '^ \S.*$' ++ syntax match TagListTagScope '\s\[.\{-\}\]$' ++ ++ " Define the highlighting only if colors are supported ++ if has('gui_running') || &t_Co > 2 ++ " Colors to highlight various taglist window elements ++ " If user defined highlighting group exists, then use them. ++ " Otherwise, use default highlight groups. ++ if hlexists('MyTagListTagName') ++ highlight link TagListTagName MyTagListTagName ++ else ++ highlight default link TagListTagName Search ++ endif ++ " Colors to highlight comments and titles ++ if hlexists('MyTagListComment') ++ highlight link TagListComment MyTagListComment ++ else ++ highlight clear TagListComment ++ highlight default link TagListComment Comment ++ endif ++ if hlexists('MyTagListTitle') ++ highlight link TagListTitle MyTagListTitle ++ else ++ highlight clear TagListTitle ++ highlight default link TagListTitle Title ++ endif ++ if hlexists('MyTagListFileName') ++ highlight link TagListFileName MyTagListFileName ++ else ++ highlight clear TagListFileName ++ highlight default TagListFileName guibg=Grey ctermbg=darkgray ++ \ guifg=white ctermfg=white ++ endif ++ if hlexists('MyTagListTagScope') ++ highlight link TagListTagScope MyTagListTagScope ++ else ++ highlight clear TagListTagScope ++ highlight default link TagListTagScope Identifier ++ endif ++ else ++ highlight default TagListTagName term=reverse cterm=reverse ++ endif ++ ++ " Folding related settings ++ setlocal foldenable ++ setlocal foldminlines=0 ++ setlocal foldmethod=manual ++ setlocal foldlevel=9999 ++ if g:Tlist_Enable_Fold_Column ++ setlocal foldcolumn=3 ++ else ++ setlocal foldcolumn=0 ++ endif ++ setlocal foldtext=v:folddashes.getline(v:foldstart) ++ ++ if s:tlist_app_name != "winmanager" ++ " Mark buffer as scratch ++ silent! setlocal buftype=nofile ++ if s:tlist_app_name == "none" ++ silent! setlocal bufhidden=delete ++ endif ++ silent! setlocal noswapfile ++ " Due to a bug in Vim 6.0, the winbufnr() function fails for unlisted ++ " buffers. So if the taglist buffer is unlisted, multiple taglist ++ " windows will be opened. This bug is fixed in Vim 6.1 and above ++ if v:version >= 601 ++ silent! setlocal nobuflisted ++ endif ++ endif ++ ++ silent! setlocal nowrap ++ ++ " If the 'number' option is set in the source window, it will affect the ++ " taglist window. So forcefully disable 'number' option for the taglist ++ " window ++ silent! setlocal nonumber ++ ++ " Use fixed height when horizontally split window is used ++ if g:Tlist_Use_Horiz_Window ++ if v:version >= 602 ++ set winfixheight ++ endif ++ endif ++ if !g:Tlist_Use_Horiz_Window && v:version >= 700 ++ set winfixwidth ++ endif ++ ++ " Setup balloon evaluation to display tag prototype ++ if v:version >= 700 && has('balloon_eval') ++ setlocal balloonexpr=Tlist_Ballon_Expr() ++ set ballooneval ++ endif ++ ++ " Setup the cpoptions properly for the maps to work ++ let old_cpoptions = &cpoptions ++ set cpoptions&vim ++ ++ " Create buffer local mappings for jumping to the tags and sorting the list ++ nnoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ nnoremap o ++ \ :call Tlist_Window_Jump_To_Tag('newwin') ++ nnoremap p ++ \ :call Tlist_Window_Jump_To_Tag('preview') ++ nnoremap P ++ \ :call Tlist_Window_Jump_To_Tag('prevwin') ++ if v:version >= 700 ++ nnoremap t ++ \ :call Tlist_Window_Jump_To_Tag('checktab') ++ nnoremap ++ \ :call Tlist_Window_Jump_To_Tag('newtab') ++ endif ++ nnoremap <2-LeftMouse> ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ nnoremap s ++ \ :call Tlist_Change_Sort('cmd', 'toggle', '') ++ nnoremap + :silent! foldopen ++ nnoremap - :silent! foldclose ++ nnoremap * :silent! %foldopen! ++ nnoremap = :silent! %foldclose ++ nnoremap :silent! foldopen ++ nnoremap :silent! foldclose ++ nnoremap :silent! %foldopen! ++ nnoremap :call Tlist_Window_Show_Info() ++ nnoremap u :call Tlist_Window_Update_File() ++ nnoremap d :call Tlist_Remove_File(-1, 1) ++ nnoremap x :call Tlist_Window_Zoom() ++ nnoremap [[ :call Tlist_Window_Move_To_File(-1) ++ nnoremap :call Tlist_Window_Move_To_File(-1) ++ nnoremap ]] :call Tlist_Window_Move_To_File(1) ++ nnoremap :call Tlist_Window_Move_To_File(1) ++ nnoremap :call Tlist_Window_Toggle_Help_Text() ++ nnoremap q :close ++ ++ " Insert mode mappings ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ " Windows needs return ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ inoremap o ++ \ :call Tlist_Window_Jump_To_Tag('newwin') ++ inoremap p ++ \ :call Tlist_Window_Jump_To_Tag('preview') ++ inoremap P ++ \ :call Tlist_Window_Jump_To_Tag('prevwin') ++ if v:version >= 700 ++ inoremap t ++ \ :call Tlist_Window_Jump_To_Tag('checktab') ++ inoremap ++ \ :call Tlist_Window_Jump_To_Tag('newtab') ++ endif ++ inoremap <2-LeftMouse> ++ \ :call Tlist_Window_Jump_To_Tag('useopen') ++ inoremap s ++ \ :call Tlist_Change_Sort('cmd', 'toggle', '') ++ inoremap + :silent! foldopen ++ inoremap - :silent! foldclose ++ inoremap * :silent! %foldopen! ++ inoremap = :silent! %foldclose ++ inoremap :silent! foldopen ++ inoremap :silent! foldclose ++ inoremap :silent! %foldopen! ++ inoremap :call ++ \ Tlist_Window_Show_Info() ++ inoremap u ++ \ :call Tlist_Window_Update_File() ++ inoremap d :call Tlist_Remove_File(-1, 1) ++ inoremap x :call Tlist_Window_Zoom() ++ inoremap [[ :call Tlist_Window_Move_To_File(-1) ++ inoremap :call Tlist_Window_Move_To_File(-1) ++ inoremap ]] :call Tlist_Window_Move_To_File(1) ++ inoremap :call Tlist_Window_Move_To_File(1) ++ inoremap :call Tlist_Window_Toggle_Help_Text() ++ inoremap q :close ++ ++ " Map single left mouse click if the user wants this functionality ++ if g:Tlist_Use_SingleClick == 1 ++ " Contributed by Bindu Wavell ++ " attempt to perform single click mapping, it would be much ++ " nicer if we could nnoremap ... however vim does ++ " not fire the when you use the mouse ++ " to enter a buffer. ++ let clickmap = ':if bufname("%") =~ "__Tag_List__" ' . ++ \ 'call Tlist_Window_Jump_To_Tag("useopen") ' . ++ \ ' endif ' ++ if maparg('', 'n') == '' ++ " no mapping for leftmouse ++ exe ':nnoremap ' . clickmap ++ else ++ " we have a mapping ++ let mapcmd = ':nnoremap ' ++ let mapcmd = mapcmd . substitute(substitute( ++ \ maparg('', 'n'), '|', '', 'g'), ++ \ '\c^', '', '') ++ let mapcmd = mapcmd . clickmap ++ exe mapcmd ++ endif ++ endif ++ ++ " Define the taglist autocommands ++ augroup TagListAutoCmds ++ autocmd! ++ " Display the tag prototype for the tag under the cursor. ++ autocmd CursorHold __Tag_List__ call s:Tlist_Window_Show_Info() ++ " Highlight the current tag periodically ++ autocmd CursorHold * silent call s:Tlist_Window_Highlight_Tag( ++ \ fnamemodify(bufname('%'), ':p'), line('.'), 1, 0) ++ ++ " Adjust the Vim window width when taglist window is closed ++ autocmd BufUnload __Tag_List__ call s:Tlist_Post_Close_Cleanup() ++ " Close the fold for this buffer when leaving the buffer ++ if g:Tlist_File_Fold_Auto_Close ++ autocmd BufEnter * silent ++ \ call s:Tlist_Window_Open_File_Fold(expand('')) ++ endif ++ " Exit Vim itself if only the taglist window is present (optional) ++ if g:Tlist_Exit_OnlyWindow ++ autocmd BufEnter __Tag_List__ nested ++ \ call s:Tlist_Window_Exit_Only_Window() ++ endif ++ if s:tlist_app_name != "winmanager" && ++ \ !g:Tlist_Process_File_Always && ++ \ (!has('gui_running') || !g:Tlist_Show_Menu) ++ " Auto refresh the taglist window ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ ++ if !g:Tlist_Use_Horiz_Window ++ if v:version < 700 ++ autocmd WinEnter * call s:Tlist_Window_Check_Width() ++ endif ++ endif ++ augroup end ++ ++ " Restore the previous cpoptions settings ++ let &cpoptions = old_cpoptions ++endfunction ++ ++" Tlist_Window_Refresh ++" Display the tags for all the files in the taglist window ++function! s:Tlist_Window_Refresh() ++ call s:Tlist_Log_Msg('Tlist_Window_Refresh()') ++ " Set report option to a huge value to prevent informational messages ++ " while deleting the lines ++ let old_report = &report ++ set report=99999 ++ ++ " Mark the buffer as modifiable ++ setlocal modifiable ++ ++ " Delete the contents of the buffer to the black-hole register ++ silent! %delete _ ++ ++ " As we have cleared the taglist window, mark all the files ++ " as not visible ++ let i = 0 ++ while i < s:tlist_file_count ++ let s:tlist_{i}_visible = 0 ++ let i = i + 1 ++ endwhile ++ ++ if g:Tlist_Compact_Format == 0 ++ " Display help in non-compact mode ++ call s:Tlist_Window_Display_Help() ++ endif ++ ++ " Mark the buffer as not modifiable ++ setlocal nomodifiable ++ ++ " Restore the report option ++ let &report = old_report ++ ++ " If the tags for only one file should be displayed in the taglist ++ " window, then no need to add the tags here. The bufenter autocommand ++ " will add the tags for that file. ++ if g:Tlist_Show_One_File ++ return ++ endif ++ ++ " List all the tags for the previously processed files ++ " Do this only if taglist is configured to display tags for more than ++ " one file. Otherwise, when Tlist_Show_One_File is configured, ++ " tags for the wrong file will be displayed. ++ let i = 0 ++ while i < s:tlist_file_count ++ call s:Tlist_Window_Refresh_File(s:tlist_{i}_filename, ++ \ s:tlist_{i}_filetype) ++ let i = i + 1 ++ endwhile ++ ++ if g:Tlist_Auto_Update ++ " Add and list the tags for all buffers in the Vim buffer list ++ let i = 1 ++ let last_bufnum = bufnr('$') ++ while i <= last_bufnum ++ if buflisted(i) ++ let fname = fnamemodify(bufname(i), ':p') ++ let ftype = s:Tlist_Get_Buffer_Filetype(i) ++ " If the file doesn't support tag listing, skip it ++ if !s:Tlist_Skip_File(fname, ftype) ++ call s:Tlist_Window_Refresh_File(fname, ftype) ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++ endif ++ ++ " If Tlist_File_Fold_Auto_Close option is set, then close all the folds ++ if g:Tlist_File_Fold_Auto_Close ++ " Close all the folds ++ silent! %foldclose ++ endif ++ ++ " Move the cursor to the top of the taglist window ++ normal! gg ++endfunction ++ ++" Tlist_Post_Close_Cleanup() ++" Close the taglist window and adjust the Vim window width ++function! s:Tlist_Post_Close_Cleanup() ++ call s:Tlist_Log_Msg('Tlist_Post_Close_Cleanup()') ++ " Mark all the files as not visible ++ let i = 0 ++ while i < s:tlist_file_count ++ let s:tlist_{i}_visible = 0 ++ let i = i + 1 ++ endwhile ++ ++ " Remove the taglist autocommands ++ silent! autocmd! TagListAutoCmds ++ ++ " Clear all the highlights ++ match none ++ ++ silent! syntax clear TagListTitle ++ silent! syntax clear TagListComment ++ silent! syntax clear TagListTagScope ++ ++ " Remove the left mouse click mapping if it was setup initially ++ if g:Tlist_Use_SingleClick ++ if hasmapto('') ++ nunmap ++ endif ++ endif ++ ++ if s:tlist_app_name != "winmanager" ++ if g:Tlist_Use_Horiz_Window || g:Tlist_Inc_Winwidth == 0 || ++ \ s:tlist_winsize_chgd != 1 || ++ \ &columns < (80 + g:Tlist_WinWidth) ++ " No need to adjust window width if using horizontally split taglist ++ " window or if columns is less than 101 or if the user chose not to ++ " adjust the window width ++ else ++ " If the user didn't manually move the window, then restore the window ++ " position to the pre-taglist position ++ if s:tlist_pre_winx != -1 && s:tlist_pre_winy != -1 && ++ \ getwinposx() == s:tlist_winx && ++ \ getwinposy() == s:tlist_winy ++ exe 'winpos ' . s:tlist_pre_winx . ' ' . s:tlist_pre_winy ++ endif ++ ++ " Adjust the Vim window width ++ let &columns= &columns - (g:Tlist_WinWidth + 1) ++ endif ++ endif ++ ++ let s:tlist_winsize_chgd = -1 ++ ++ " Reset taglist state variables ++ if s:tlist_app_name == "winmanager" ++ let s:tlist_app_name = "none" ++ endif ++ let s:tlist_window_initialized = 0 ++endfunction ++ ++" Tlist_Window_Refresh_File() ++" List the tags defined in the specified file in a Vim window ++function! s:Tlist_Window_Refresh_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Window_Refresh_File (' . a:filename . ')') ++ " First check whether the file already exists ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx != -1 ++ let file_listed = 1 ++ else ++ let file_listed = 0 ++ endif ++ ++ if !file_listed ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(a:filename) ++ return ++ endif ++ endif ++ ++ if file_listed && s:tlist_{fidx}_visible ++ " Check whether the file tags are currently valid ++ if s:tlist_{fidx}_valid ++ " Goto the first line in the file ++ exe s:tlist_{fidx}_start ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ endif ++ return ++ endif ++ ++ " Discard and remove the tags for this file from display ++ call s:Tlist_Discard_TagInfo(fidx) ++ call s:Tlist_Window_Remove_File_From_Display(fidx) ++ endif ++ ++ " Process and generate a list of tags defined in the file ++ if !file_listed || !s:tlist_{fidx}_valid ++ let ret_fidx = s:Tlist_Process_File(a:filename, a:ftype) ++ if ret_fidx == -1 ++ return ++ endif ++ let fidx = ret_fidx ++ endif ++ ++ " Set report option to a huge value to prevent informational messages ++ " while adding lines to the taglist window ++ let old_report = &report ++ set report=99999 ++ ++ if g:Tlist_Show_One_File ++ " Remove the previous file ++ if s:tlist_cur_file_idx != -1 ++ call s:Tlist_Window_Remove_File_From_Display(s:tlist_cur_file_idx) ++ let s:tlist_{s:tlist_cur_file_idx}_visible = 0 ++ let s:tlist_{s:tlist_cur_file_idx}_start = 0 ++ let s:tlist_{s:tlist_cur_file_idx}_end = 0 ++ endif ++ let s:tlist_cur_file_idx = fidx ++ endif ++ ++ " Mark the buffer as modifiable ++ setlocal modifiable ++ ++ " Add new files to the end of the window. For existing files, add them at ++ " the same line where they were previously present. If the file is not ++ " visible, then add it at the end ++ if s:tlist_{fidx}_start == 0 || !s:tlist_{fidx}_visible ++ if g:Tlist_Compact_Format ++ let s:tlist_{fidx}_start = line('$') ++ else ++ let s:tlist_{fidx}_start = line('$') + 1 ++ endif ++ endif ++ ++ let s:tlist_{fidx}_visible = 1 ++ ++ " Goto the line where this file should be placed ++ if g:Tlist_Compact_Format ++ exe s:tlist_{fidx}_start ++ else ++ exe s:tlist_{fidx}_start - 1 ++ endif ++ ++ let txt = fnamemodify(s:tlist_{fidx}_filename, ':t') . ' (' . ++ \ fnamemodify(s:tlist_{fidx}_filename, ':p:h') . ')' ++ if g:Tlist_Compact_Format == 0 ++ silent! put =txt ++ else ++ silent! put! =txt ++ " Move to the next line ++ exe line('.') + 1 ++ endif ++ let file_start = s:tlist_{fidx}_start ++ ++ " Add the tag names grouped by tag type to the buffer with a title ++ let i = 1 ++ let ttype_cnt = s:tlist_{a:ftype}_count ++ while i <= ttype_cnt ++ let ttype = s:tlist_{a:ftype}_{i}_name ++ " Add the tag type only if there are tags for that type ++ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype ++ let ttype_txt = {fidx_ttype} ++ if ttype_txt != '' ++ let txt = ' ' . s:tlist_{a:ftype}_{i}_fullname ++ if g:Tlist_Compact_Format == 0 ++ let ttype_start_lnum = line('.') + 1 ++ silent! put =txt ++ else ++ let ttype_start_lnum = line('.') ++ silent! put! =txt ++ endif ++ silent! put =ttype_txt ++ ++ let {fidx_ttype}_offset = ttype_start_lnum - file_start ++ ++ " create a fold for this tag type ++ let fold_start = ttype_start_lnum ++ let fold_end = fold_start + {fidx_ttype}_count ++ exe fold_start . ',' . fold_end . 'fold' ++ ++ " Adjust the cursor position ++ if g:Tlist_Compact_Format == 0 ++ exe ttype_start_lnum + {fidx_ttype}_count ++ else ++ exe ttype_start_lnum + {fidx_ttype}_count + 1 ++ endif ++ ++ if g:Tlist_Compact_Format == 0 ++ " Separate the tag types by a empty line ++ silent! put ='' ++ endif ++ endif ++ let i = i + 1 ++ endwhile ++ ++ if s:tlist_{fidx}_tag_count == 0 ++ if g:Tlist_Compact_Format == 0 ++ silent! put ='' ++ endif ++ endif ++ ++ let s:tlist_{fidx}_end = line('.') - 1 ++ ++ " Create a fold for the entire file ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'fold' ++ exe 'silent! ' . s:tlist_{fidx}_start . ',' . ++ \ s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Goto the starting line for this file, ++ exe s:tlist_{fidx}_start ++ ++ if s:tlist_app_name == "winmanager" ++ " To handle a bug in the winmanager plugin, add a space at the ++ " last line ++ call setline('$', ' ') ++ endif ++ ++ " Mark the buffer as not modifiable ++ setlocal nomodifiable ++ ++ " Restore the report option ++ let &report = old_report ++ ++ " Update the start and end line numbers for all the files following this ++ " file ++ let start = s:tlist_{fidx}_start ++ " include the empty line after the last line ++ if g:Tlist_Compact_Format ++ let end = s:tlist_{fidx}_end ++ else ++ let end = s:tlist_{fidx}_end + 1 ++ endif ++ call s:Tlist_Window_Update_Line_Offsets(fidx + 1, 1, end - start + 1) ++ ++ " Now that we have updated the taglist window, update the tags ++ " menu (if present) ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(1) ++ endif ++endfunction ++ ++" Tlist_Init_File ++" Initialize the variables for a new file ++function! s:Tlist_Init_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Init_File (' . a:filename . ')') ++ " Add new files at the end of the list ++ let fidx = s:tlist_file_count ++ let s:tlist_file_count = s:tlist_file_count + 1 ++ " Add the new file name to the taglist list of file names ++ let s:tlist_file_names = s:tlist_file_names . a:filename . "\n" ++ ++ " Initialize the file variables ++ let s:tlist_{fidx}_filename = a:filename ++ let s:tlist_{fidx}_sort_type = g:Tlist_Sort_Type ++ let s:tlist_{fidx}_filetype = a:ftype ++ let s:tlist_{fidx}_mtime = -1 ++ let s:tlist_{fidx}_start = 0 ++ let s:tlist_{fidx}_end = 0 ++ let s:tlist_{fidx}_valid = 0 ++ let s:tlist_{fidx}_visible = 0 ++ let s:tlist_{fidx}_tag_count = 0 ++ let s:tlist_{fidx}_menu_cmd = '' ++ ++ " Initialize the tag type variables ++ let i = 1 ++ while i <= s:tlist_{a:ftype}_count ++ let ttype = s:tlist_{a:ftype}_{i}_name ++ let s:tlist_{fidx}_{ttype} = '' ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = 0 ++ let i = i + 1 ++ endwhile ++ ++ return fidx ++endfunction ++ ++" Tlist_Get_Tag_Type_By_Tag ++" Return the tag type for the specified tag index ++function! s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) ++ let ttype_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_type' ++ ++ " Already parsed and have the tag name ++ if exists(ttype_var) ++ return {ttype_var} ++ endif ++ ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let {ttype_var} = s:Tlist_Extract_Tagtype(tag_line) ++ ++ return {ttype_var} ++endfunction ++ ++" Tlist_Get_Tag_Prototype ++function! s:Tlist_Get_Tag_Prototype(fidx, tidx) ++ let tproto_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_proto' ++ ++ " Already parsed and have the tag prototype ++ if exists(tproto_var) ++ return {tproto_var} ++ endif ++ ++ " Parse and extract the tag prototype ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = stridx(tag_line, '/^') + 2 ++ let end = stridx(tag_line, '/;"' . "\t") ++ if tag_line[end - 1] == '$' ++ let end = end -1 ++ endif ++ let tag_proto = strpart(tag_line, start, end - start) ++ let {tproto_var} = substitute(tag_proto, '\s*', '', '') ++ ++ return {tproto_var} ++endfunction ++ ++" Tlist_Get_Tag_SearchPat ++function! s:Tlist_Get_Tag_SearchPat(fidx, tidx) ++ let tpat_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_searchpat' ++ ++ " Already parsed and have the tag search pattern ++ if exists(tpat_var) ++ return {tpat_var} ++ endif ++ ++ " Parse and extract the tag search pattern ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = stridx(tag_line, '/^') + 2 ++ let end = stridx(tag_line, '/;"' . "\t") ++ if tag_line[end - 1] == '$' ++ let end = end -1 ++ endif ++ let {tpat_var} = '\V\^' . strpart(tag_line, start, end - start) . ++ \ (tag_line[end] == '$' ? '\$' : '') ++ ++ return {tpat_var} ++endfunction ++ ++" Tlist_Get_Tag_Linenum ++" Return the tag line number, given the tag index ++function! s:Tlist_Get_Tag_Linenum(fidx, tidx) ++ let tline_var = 's:tlist_' . a:fidx . '_' . a:tidx . '_tag_linenum' ++ ++ " Already parsed and have the tag line number ++ if exists(tline_var) ++ return {tline_var} ++ endif ++ ++ " Parse and extract the tag line number ++ let tag_line = s:tlist_{a:fidx}_{a:tidx}_tag ++ let start = strridx(tag_line, 'line:') + 5 ++ let end = strridx(tag_line, "\t") ++ if end < start ++ let {tline_var} = strpart(tag_line, start) + 0 ++ else ++ let {tline_var} = strpart(tag_line, start, end - start) + 0 ++ endif ++ ++ return {tline_var} ++endfunction ++ ++" Tlist_Parse_Tagline ++" Parse a tag line from the ctags output. Separate the tag output based on the ++" tag type and store it in the tag type variable. ++" The format of each line in the ctags output is: ++" ++" tag_namefile_nameex_cmd;"extension_fields ++" ++function! s:Tlist_Parse_Tagline(tag_line) ++ if a:tag_line == '' ++ " Skip empty lines ++ return ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Extract_Tagtype(a:tag_line) ++ ++ " Make sure the tag type is a valid and supported one ++ if ttype == '' || stridx(s:ctags_flags, ttype) == -1 ++ " Line is not in proper tags format or Tag type is not supported ++ return ++ endif ++ ++ " Update the total tag count ++ let s:tidx = s:tidx + 1 ++ ++ " The following variables are used to optimize this code. Vim is slow in ++ " using curly brace names. To reduce the amount of processing needed, the ++ " curly brace variables are pre-processed here ++ let fidx_tidx = 's:tlist_' . s:fidx . '_' . s:tidx ++ let fidx_ttype = 's:tlist_' . s:fidx . '_' . ttype ++ ++ " Update the count of this tag type ++ let ttype_idx = {fidx_ttype}_count + 1 ++ let {fidx_ttype}_count = ttype_idx ++ ++ " Store the ctags output for this tag ++ let {fidx_tidx}_tag = a:tag_line ++ ++ " Store the tag index and the tag type index (back pointers) ++ let {fidx_ttype}_{ttype_idx} = s:tidx ++ let {fidx_tidx}_ttype_idx = ttype_idx ++ ++ " Extract the tag name ++ let tag_name = strpart(a:tag_line, 0, stridx(a:tag_line, "\t")) ++ ++ " Extract the tag scope/prototype ++ if g:Tlist_Display_Prototype ++ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(s:fidx, s:tidx) ++ else ++ let ttxt = ' ' . tag_name ++ ++ " Add the tag scope, if it is available and is configured. Tag ++ " scope is the last field after the 'line:\t' field ++ if g:Tlist_Display_Tag_Scope ++ let tag_scope = s:Tlist_Extract_Tag_Scope(a:tag_line) ++ if tag_scope != '' ++ let ttxt = ttxt . ' [' . tag_scope . ']' ++ endif ++ endif ++ endif ++ ++ " Add this tag to the tag type variable ++ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n" ++ ++ " Save the tag name ++ let {fidx_tidx}_tag_name = tag_name ++endfunction ++ ++" Tlist_Process_File ++" Get the list of tags defined in the specified file and store them ++" in Vim variables. Returns the file index where the tags are stored. ++function! s:Tlist_Process_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Process_File (' . a:filename . ', ' . ++ \ a:ftype . ')') ++ " Check whether this file is supported ++ if s:Tlist_Skip_File(a:filename, a:ftype) ++ return -1 ++ endif ++ ++ " If the tag types for this filetype are not yet created, then create ++ " them now ++ let var = 's:tlist_' . a:ftype . '_count' ++ if !exists(var) ++ if s:Tlist_FileType_Init(a:ftype) == 0 ++ return -1 ++ endif ++ endif ++ ++ " If this file is already processed, then use the cached values ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ " First time, this file is loaded ++ let fidx = s:Tlist_Init_File(a:filename, a:ftype) ++ else ++ " File was previously processed. Discard the tag information ++ call s:Tlist_Discard_TagInfo(fidx) ++ endif ++ ++ let s:tlist_{fidx}_valid = 1 ++ ++ " Exuberant ctags arguments to generate a tag list ++ let ctags_args = ' -f - --format=2 --excmd=pattern --fields=nks ' ++ ++ " Form the ctags argument depending on the sort type ++ if s:tlist_{fidx}_sort_type == 'name' ++ let ctags_args = ctags_args . '--sort=yes' ++ else ++ let ctags_args = ctags_args . '--sort=no' ++ endif ++ ++ " Add the filetype specific arguments ++ let ctags_args = ctags_args . ' ' . s:tlist_{a:ftype}_ctags_args ++ ++ " Ctags command to produce output with regexp for locating the tags ++ let ctags_cmd = g:Tlist_Ctags_Cmd . ctags_args ++ let ctags_cmd = ctags_cmd . ' "' . a:filename . '"' ++ ++ if &shellxquote == '"' ++ " Double-quotes within double-quotes will not work in the ++ " command-line.If the 'shellxquote' option is set to double-quotes, ++ " then escape the double-quotes in the ctags command-line. ++ let ctags_cmd = escape(ctags_cmd, '"') ++ endif ++ ++ " In Windows 95, if not using cygwin, disable the 'shellslash' ++ " option. Otherwise, this will cause problems when running the ++ " ctags command. ++ if has('win95') && !has('win32unix') ++ let old_shellslash = &shellslash ++ set noshellslash ++ endif ++ ++ if has('win32') && !has('win32unix') && !has('win95') ++ \ && (&shell =~ 'cmd.exe') ++ " Windows does not correctly deal with commands that have more than 1 ++ " set of double quotes. It will strip them all resulting in: ++ " 'C:\Program' is not recognized as an internal or external command ++ " operable program or batch file. To work around this, place the ++ " command inside a batch file and call the batch file. ++ " Do this only on Win2K, WinXP and above. ++ " Contributed by: David Fishburn. ++ let s:taglist_tempfile = fnamemodify(tempname(), ':h') . ++ \ '\taglist.cmd' ++ exe 'redir! > ' . s:taglist_tempfile ++ silent echo ctags_cmd ++ redir END ++ ++ call s:Tlist_Log_Msg('Cmd inside batch file: ' . ctags_cmd) ++ let ctags_cmd = '"' . s:taglist_tempfile . '"' ++ endif ++ ++ call s:Tlist_Log_Msg('Cmd: ' . ctags_cmd) ++ ++ " Run ctags and get the tag list ++ let cmd_output = system(ctags_cmd) ++ ++ " Restore the value of the 'shellslash' option. ++ if has('win95') && !has('win32unix') ++ let &shellslash = old_shellslash ++ endif ++ ++ if exists('s:taglist_tempfile') ++ " Delete the temporary cmd file created on MS-Windows ++ call delete(s:taglist_tempfile) ++ endif ++ ++ " Handle errors ++ if v:shell_error ++ let msg = "Taglist: Failed to generate tags for " . a:filename ++ call s:Tlist_Warning_Msg(msg) ++ if cmd_output != '' ++ call s:Tlist_Warning_Msg(cmd_output) ++ endif ++ return fidx ++ endif ++ ++ " Store the modification time for the file ++ let s:tlist_{fidx}_mtime = getftime(a:filename) ++ ++ " No tags for current file ++ if cmd_output == '' ++ call s:Tlist_Log_Msg('No tags defined in ' . a:filename) ++ return fidx ++ endif ++ ++ call s:Tlist_Log_Msg('Generated tags information for ' . a:filename) ++ ++ if v:version > 601 ++ " The following script local variables are used by the ++ " Tlist_Parse_Tagline() function. ++ let s:ctags_flags = s:tlist_{a:ftype}_ctags_flags ++ let s:fidx = fidx ++ let s:tidx = 0 ++ ++ " Process the ctags output one line at a time. The substitute() ++ " command is used to parse the tag lines instead of using the ++ " matchstr()/stridx()/strpart() functions for performance reason ++ call substitute(cmd_output, "\\([^\n]\\+\\)\n", ++ \ '\=s:Tlist_Parse_Tagline(submatch(1))', 'g') ++ ++ " Save the number of tags for this file ++ let s:tlist_{fidx}_tag_count = s:tidx ++ ++ " The following script local variables are no longer needed ++ unlet! s:ctags_flags ++ unlet! s:tidx ++ unlet! s:fidx ++ else ++ " Due to a bug in Vim earlier than version 6.1, ++ " we cannot use substitute() to parse the ctags output. ++ " Instead the slow str*() functions are used ++ let ctags_flags = s:tlist_{a:ftype}_ctags_flags ++ let tidx = 0 ++ ++ while cmd_output != '' ++ " Extract one line at a time ++ let idx = stridx(cmd_output, "\n") ++ let one_line = strpart(cmd_output, 0, idx) ++ " Remove the line from the tags output ++ let cmd_output = strpart(cmd_output, idx + 1) ++ ++ if one_line == '' ++ " Line is not in proper tags format ++ continue ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Extract_Tagtype(one_line) ++ ++ " Make sure the tag type is a valid and supported one ++ if ttype == '' || stridx(ctags_flags, ttype) == -1 ++ " Line is not in proper tags format or Tag type is not ++ " supported ++ continue ++ endif ++ ++ " Update the total tag count ++ let tidx = tidx + 1 ++ ++ " The following variables are used to optimize this code. Vim is ++ " slow in using curly brace names. To reduce the amount of ++ " processing needed, the curly brace variables are pre-processed ++ " here ++ let fidx_tidx = 's:tlist_' . fidx . '_' . tidx ++ let fidx_ttype = 's:tlist_' . fidx . '_' . ttype ++ ++ " Update the count of this tag type ++ let ttype_idx = {fidx_ttype}_count + 1 ++ let {fidx_ttype}_count = ttype_idx ++ ++ " Store the ctags output for this tag ++ let {fidx_tidx}_tag = one_line ++ ++ " Store the tag index and the tag type index (back pointers) ++ let {fidx_ttype}_{ttype_idx} = tidx ++ let {fidx_tidx}_ttype_idx = ttype_idx ++ ++ " Extract the tag name ++ let tag_name = strpart(one_line, 0, stridx(one_line, "\t")) ++ ++ " Extract the tag scope/prototype ++ if g:Tlist_Display_Prototype ++ let ttxt = ' ' . s:Tlist_Get_Tag_Prototype(fidx, tidx) ++ else ++ let ttxt = ' ' . tag_name ++ ++ " Add the tag scope, if it is available and is configured. Tag ++ " scope is the last field after the 'line:\t' field ++ if g:Tlist_Display_Tag_Scope ++ let tag_scope = s:Tlist_Extract_Tag_Scope(one_line) ++ if tag_scope != '' ++ let ttxt = ttxt . ' [' . tag_scope . ']' ++ endif ++ endif ++ endif ++ ++ " Add this tag to the tag type variable ++ let {fidx_ttype} = {fidx_ttype} . ttxt . "\n" ++ ++ " Save the tag name ++ let {fidx_tidx}_tag_name = tag_name ++ endwhile ++ ++ " Save the number of tags for this file ++ let s:tlist_{fidx}_tag_count = tidx ++ endif ++ ++ call s:Tlist_Log_Msg('Processed ' . s:tlist_{fidx}_tag_count . ++ \ ' tags in ' . a:filename) ++ ++ return fidx ++endfunction ++ ++" Tlist_Update_File ++" Update the tags for a file (if needed) ++function! Tlist_Update_File(filename, ftype) ++ call s:Tlist_Log_Msg('Tlist_Update_File (' . a:filename . ')') ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(a:filename, a:ftype) ++ return ++ endif ++ ++ " Convert the file name to a full path ++ let fname = fnamemodify(a:filename, ':p') ++ ++ " First check whether the file already exists ++ let fidx = s:Tlist_Get_File_Index(fname) ++ ++ if fidx != -1 && s:tlist_{fidx}_valid ++ " File exists and the tags are valid ++ " Check whether the file was modified after the last tags update ++ " If it is modified, then update the tags ++ if s:tlist_{fidx}_mtime == getftime(fname) ++ return ++ endif ++ else ++ " If the tags were removed previously based on a user request, ++ " as we are going to update the tags (based on the user request), ++ " remove the filename from the deleted list ++ call s:Tlist_Update_Remove_List(fname, 0) ++ endif ++ ++ " If the taglist window is opened, update it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ " Taglist window is not present. Just update the taglist ++ " and return ++ call s:Tlist_Process_File(fname, a:ftype) ++ else ++ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != -1 ++ " If tags for only one file are displayed and we are not ++ " updating the tags for that file, then no need to ++ " refresh the taglist window. Otherwise, the taglist ++ " window should be updated. ++ if s:tlist_{s:tlist_cur_file_idx}_filename != fname ++ call s:Tlist_Process_File(fname, a:ftype) ++ return ++ endif ++ endif ++ ++ " Save the current window number ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ " Save the cursor position ++ let save_line = line('.') ++ let save_col = col('.') ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(fname, a:ftype) ++ ++ " Restore the cursor position ++ if v:version >= 601 ++ call cursor(save_line, save_col) ++ else ++ exe save_line ++ exe 'normal! ' . save_col . '|' ++ endif ++ ++ if winnr() != save_winnr ++ " Go back to the original window ++ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') ++ endif ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(1) ++ endif ++endfunction ++ ++" Tlist_Window_Close ++" Close the taglist window ++function! s:Tlist_Window_Close() ++ call s:Tlist_Log_Msg('Tlist_Window_Close()') ++ " Make sure the taglist window exists ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Error: Taglist window is not open') ++ return ++ endif ++ ++ if winnr() == winnum ++ " Already in the taglist window. Close it and return ++ if winbufnr(2) != -1 ++ " If a window other than the taglist window is open, ++ " then only close the taglist window. ++ close ++ endif ++ else ++ " Goto the taglist window, close it and then come back to the ++ " original window ++ let curbufnr = bufnr('%') ++ exe winnum . 'wincmd w' ++ close ++ " Need to jump back to the original window only if we are not ++ " already in that window ++ let winnum = bufwinnr(curbufnr) ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ endif ++endfunction ++ ++" Tlist_Window_Mark_File_Window ++" Mark the current window as the file window to use when jumping to a tag. ++" Only if the current window is a non-plugin, non-preview and non-taglist ++" window ++function! s:Tlist_Window_Mark_File_Window() ++ if getbufvar('%', '&buftype') == '' && !&previewwindow ++ let w:tlist_file_window = "yes" ++ endif ++endfunction ++ ++" Tlist_Window_Open ++" Open and refresh the taglist window ++function! s:Tlist_Window_Open() ++ call s:Tlist_Log_Msg('Tlist_Window_Open()') ++ " If the window is open, jump to it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ " Jump to the existing window ++ if winnr() != winnum ++ exe winnum . 'wincmd w' ++ endif ++ return ++ endif ++ ++ if s:tlist_app_name == "winmanager" ++ " Taglist plugin is no longer part of the winmanager app ++ let s:tlist_app_name = "none" ++ endif ++ ++ " Get the filename and filetype for the specified buffer ++ let curbuf_name = fnamemodify(bufname('%'), ':p') ++ let curbuf_ftype = getbufvar('%', '&filetype') ++ let cur_lnum = line('.') ++ ++ " Mark the current window as the desired window to open a file when a tag ++ " is selected. ++ call s:Tlist_Window_Mark_File_Window() ++ ++ " Open the taglist window ++ call s:Tlist_Window_Create() ++ ++ call s:Tlist_Window_Refresh() ++ ++ if g:Tlist_Show_One_File ++ " Add only the current buffer and file ++ " ++ " If the file doesn't support tag listing, skip it ++ if !s:Tlist_Skip_File(curbuf_name, curbuf_ftype) ++ call s:Tlist_Window_Refresh_File(curbuf_name, curbuf_ftype) ++ endif ++ endif ++ ++ if g:Tlist_File_Fold_Auto_Close ++ " Open the fold for the current file, as all the folds in ++ " the taglist window are closed ++ let fidx = s:Tlist_Get_File_Index(curbuf_name) ++ if fidx != -1 ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ endif ++ endif ++ ++ " Highlight the current tag ++ call s:Tlist_Window_Highlight_Tag(curbuf_name, cur_lnum, 1, 1) ++endfunction ++ ++" Tlist_Window_Toggle() ++" Open or close a taglist window ++function! s:Tlist_Window_Toggle() ++ call s:Tlist_Log_Msg('Tlist_Window_Toggle()') ++ " If taglist window is open then close it. ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ call s:Tlist_Window_Close() ++ return ++ endif ++ ++ call s:Tlist_Window_Open() ++ ++ " Go back to the original window, if Tlist_GainFocus_On_ToggleOpen is not ++ " set ++ if !g:Tlist_GainFocus_On_ToggleOpen ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++endfunction ++ ++" Tlist_Process_Filelist ++" Process multiple files. Each filename is separated by "\n" ++" Returns the number of processed files ++function! s:Tlist_Process_Filelist(file_names) ++ let flist = a:file_names ++ ++ " Enable lazy screen updates ++ let old_lazyredraw = &lazyredraw ++ set lazyredraw ++ ++ " Keep track of the number of processed files ++ let fcnt = 0 ++ ++ " Process one file at a time ++ while flist != '' ++ let nl_idx = stridx(flist, "\n") ++ let one_file = strpart(flist, 0, nl_idx) ++ ++ " Remove the filename from the list ++ let flist = strpart(flist, nl_idx + 1) ++ ++ if one_file == '' ++ continue ++ endif ++ ++ " Skip directories ++ if isdirectory(one_file) ++ continue ++ endif ++ ++ let ftype = s:Tlist_Get_Filetype(one_file) ++ ++ echon "\r " ++ echon "\rProcessing tags for " . fnamemodify(one_file, ':p:t') ++ ++ let fcnt = fcnt + 1 ++ ++ call Tlist_Update_File(one_file, ftype) ++ endwhile ++ ++ " Clear the displayed informational messages ++ echon "\r " ++ ++ " Restore the previous state ++ let &lazyredraw = old_lazyredraw ++ ++ return fcnt ++endfunction ++ ++" Tlist_Process_Dir ++" Process the files in a directory matching the specified pattern ++function! s:Tlist_Process_Dir(dir_name, pat) ++ let flist = glob(a:dir_name . '/' . a:pat) . "\n" ++ ++ let fcnt = s:Tlist_Process_Filelist(flist) ++ ++ let len = strlen(a:dir_name) ++ if a:dir_name[len - 1] == '\' || a:dir_name[len - 1] == '/' ++ let glob_expr = a:dir_name . '*' ++ else ++ let glob_expr = a:dir_name . '/*' ++ endif ++ let all_files = glob(glob_expr) . "\n" ++ ++ while all_files != '' ++ let nl_idx = stridx(all_files, "\n") ++ let one_file = strpart(all_files, 0, nl_idx) ++ ++ let all_files = strpart(all_files, nl_idx + 1) ++ if one_file == '' ++ continue ++ endif ++ ++ " Skip non-directory names ++ if !isdirectory(one_file) ++ continue ++ endif ++ ++ echon "\r " ++ echon "\rProcessing files in directory " . fnamemodify(one_file, ':t') ++ let fcnt = fcnt + s:Tlist_Process_Dir(one_file, a:pat) ++ endwhile ++ ++ return fcnt ++endfunction ++ ++" Tlist_Add_Files_Recursive ++" Add files recursively from a directory ++function! s:Tlist_Add_Files_Recursive(dir, ...) ++ let dir_name = fnamemodify(a:dir, ':p') ++ if !isdirectory(dir_name) ++ call s:Tlist_Warning_Msg('Error: ' . dir_name . ' is not a directory') ++ return ++ endif ++ ++ if a:0 == 1 ++ " User specified file pattern ++ let pat = a:1 ++ else ++ " Default file pattern ++ let pat = '*' ++ endif ++ ++ echon "\r " ++ echon "\rProcessing files in directory " . fnamemodify(dir_name, ':t') ++ let fcnt = s:Tlist_Process_Dir(dir_name, pat) ++ ++ echon "\rAdded " . fcnt . " files to the taglist" ++endfunction ++ ++" Tlist_Add_Files ++" Add the specified list of files to the taglist ++function! s:Tlist_Add_Files(...) ++ let flist = '' ++ let i = 1 ++ ++ " Get all the files matching the file patterns supplied as argument ++ while i <= a:0 ++ let flist = flist . glob(a:{i}) . "\n" ++ let i = i + 1 ++ endwhile ++ ++ if flist == '' ++ call s:Tlist_Warning_Msg('Error: No matching files are found') ++ return ++ endif ++ ++ let fcnt = s:Tlist_Process_Filelist(flist) ++ echon "\rAdded " . fcnt . " files to the taglist" ++endfunction ++ ++" Tlist_Extract_Tagtype ++" Extract the tag type from the tag text ++function! s:Tlist_Extract_Tagtype(tag_line) ++ " The tag type is after the tag prototype field. The prototype field ++ " ends with the /;"\t string. We add 4 at the end to skip the characters ++ " in this special string.. ++ let start = strridx(a:tag_line, '/;"' . "\t") + 4 ++ let end = strridx(a:tag_line, 'line:') - 1 ++ let ttype = strpart(a:tag_line, start, end - start) ++ ++ return ttype ++endfunction ++ ++" Tlist_Extract_Tag_Scope ++" Extract the tag scope from the tag text ++function! s:Tlist_Extract_Tag_Scope(tag_line) ++ let start = strridx(a:tag_line, 'line:') ++ let end = strridx(a:tag_line, "\t") ++ if end <= start ++ return '' ++ endif ++ ++ let tag_scope = strpart(a:tag_line, end + 1) ++ let tag_scope = strpart(tag_scope, stridx(tag_scope, ':') + 1) ++ ++ return tag_scope ++endfunction ++ ++" Tlist_Refresh() ++" Refresh the taglist ++function! s:Tlist_Refresh() ++ call s:Tlist_Log_Msg('Tlist_Refresh (Skip_Refresh = ' . ++ \ s:Tlist_Skip_Refresh . ', ' . bufname('%') . ')') ++ " If we are entering the buffer from one of the taglist functions, then ++ " no need to refresh the taglist window again. ++ if s:Tlist_Skip_Refresh ++ " We still need to update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++ return ++ endif ++ ++ " If part of the winmanager plugin and not configured to process ++ " tags always and not configured to display the tags menu, then return ++ if (s:tlist_app_name == 'winmanager') && !g:Tlist_Process_File_Always ++ \ && !g:Tlist_Show_Menu ++ return ++ endif ++ ++ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help ++ if &buftype != '' ++ return ++ endif ++ ++ let filename = fnamemodify(bufname('%'), ':p') ++ let ftype = &filetype ++ ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(filename, ftype) ++ return ++ endif ++ ++ let tlist_win = bufwinnr(g:TagList_title) ++ ++ " If the taglist window is not opened and not configured to process ++ " tags always and not displaying the tags menu, then return ++ if tlist_win == -1 && !g:Tlist_Process_File_Always && !g:Tlist_Show_Menu ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(filename) ++ return ++ endif ++ ++ " If the taglist should not be auto updated, then return ++ if !g:Tlist_Auto_Update ++ return ++ endif ++ endif ++ ++ let cur_lnum = line('.') ++ ++ if fidx == -1 ++ " Update the tags for the file ++ let fidx = s:Tlist_Process_File(filename, ftype) ++ else ++ let mtime = getftime(filename) ++ if s:tlist_{fidx}_mtime != mtime ++ " Invalidate the tags listed for this file ++ let s:tlist_{fidx}_valid = 0 ++ ++ " Update the taglist and the window ++ call Tlist_Update_File(filename, ftype) ++ ++ " Store the new file modification time ++ let s:tlist_{fidx}_mtime = mtime ++ endif ++ endif ++ ++ " Update the taglist window ++ if tlist_win != -1 ++ " Disable screen updates ++ let old_lazyredraw = &lazyredraw ++ set nolazyredraw ++ ++ " Save the current window number ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ if !g:Tlist_Auto_Highlight_Tag || !g:Tlist_Highlight_Tag_On_BufEnter ++ " Save the cursor position ++ let save_line = line('.') ++ let save_col = col('.') ++ endif ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(filename, ftype) ++ ++ " Open the fold for the file ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen!" ++ ++ if g:Tlist_Highlight_Tag_On_BufEnter && g:Tlist_Auto_Highlight_Tag ++ if g:Tlist_Show_One_File && s:tlist_cur_file_idx != fidx ++ " If displaying tags for only one file in the taglist ++ " window and about to display the tags for a new file, ++ " then center the current tag line for the new file ++ let center_tag_line = 1 ++ else ++ let center_tag_line = 0 ++ endif ++ ++ " Highlight the current tag ++ call s:Tlist_Window_Highlight_Tag(filename, cur_lnum, 1, center_tag_line) ++ else ++ " Restore the cursor position ++ if v:version >= 601 ++ call cursor(save_line, save_col) ++ else ++ exe save_line ++ exe 'normal! ' . save_col . '|' ++ endif ++ endif ++ ++ " Jump back to the original window ++ if save_winnr != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds(save_winnr . 'wincmd w') ++ endif ++ ++ " Restore screen updates ++ let &lazyredraw = old_lazyredraw ++ endif ++ ++ " Update the taglist menu ++ if g:Tlist_Show_Menu ++ call s:Tlist_Menu_Update_File(0) ++ endif ++endfunction ++ ++" Tlist_Change_Sort() ++" Change the sort order of the tag listing ++" caller == 'cmd', command used in the taglist window ++" caller == 'menu', taglist menu ++" action == 'toggle', toggle sort from name to order and vice versa ++" action == 'set', set the sort order to sort_type ++function! s:Tlist_Change_Sort(caller, action, sort_type) ++ call s:Tlist_Log_Msg('Tlist_Change_Sort (caller = ' . a:caller . ++ \ ', action = ' . a:action . ', sort_type = ' . a:sort_type . ')') ++ if a:caller == 'cmd' ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ " Remove the previous highlighting ++ match none ++ elseif a:caller == 'menu' ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx == -1 ++ return ++ endif ++ endif ++ ++ if a:action == 'toggle' ++ let sort_type = s:tlist_{fidx}_sort_type ++ ++ " Toggle the sort order from 'name' to 'order' and vice versa ++ if sort_type == 'name' ++ let s:tlist_{fidx}_sort_type = 'order' ++ else ++ let s:tlist_{fidx}_sort_type = 'name' ++ endif ++ else ++ let s:tlist_{fidx}_sort_type = a:sort_type ++ endif ++ ++ " Invalidate the tags listed for this file ++ let s:tlist_{fidx}_valid = 0 ++ ++ if a:caller == 'cmd' ++ " Save the current line for later restoration ++ let curline = '\V\^' . getline('.') . '\$' ++ ++ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, ++ \ s:tlist_{fidx}_filetype) ++ ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Go back to the cursor line before the tag list is sorted ++ call search(curline, 'w') ++ ++ call s:Tlist_Menu_Update_File(1) ++ else ++ call s:Tlist_Menu_Remove_File() ++ ++ call s:Tlist_Refresh() ++ endif ++endfunction ++ ++" Tlist_Update_Current_File() ++" Update taglist for the current buffer by regenerating the tag list ++" Contributed by WEN Guopeng. ++function! s:Tlist_Update_Current_File() ++ call s:Tlist_Log_Msg('Tlist_Update_Current_File()') ++ if winnr() == bufwinnr(g:TagList_title) ++ " In the taglist window. Update the current file ++ call s:Tlist_Window_Update_File() ++ else ++ " Not in the taglist window. Update the current buffer ++ let filename = fnamemodify(bufname('%'), ':p') ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx != -1 ++ let s:tlist_{fidx}_valid = 0 ++ endif ++ call Tlist_Update_File(filename, &filetype) ++ endif ++endfunction ++ ++" Tlist_Window_Update_File() ++" Update the tags displayed in the taglist window ++function! s:Tlist_Window_Update_File() ++ call s:Tlist_Log_Msg('Tlist_Window_Update_File()') ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ " Remove the previous highlighting ++ match none ++ ++ " Save the current line for later restoration ++ let curline = '\V\^' . getline('.') . '\$' ++ ++ let s:tlist_{fidx}_valid = 0 ++ ++ " Update the taglist window ++ call s:Tlist_Window_Refresh_File(s:tlist_{fidx}_filename, ++ \ s:tlist_{fidx}_filetype) ++ ++ exe s:tlist_{fidx}_start . ',' . s:tlist_{fidx}_end . 'foldopen!' ++ ++ " Go back to the tag line before the list is updated ++ call search(curline, 'w') ++endfunction ++ ++" Tlist_Window_Get_Tag_Type_By_Linenum() ++" Return the tag type index for the specified line in the taglist window ++function! s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum) ++ let ftype = s:tlist_{a:fidx}_filetype ++ ++ " Determine to which tag type the current line number belongs to using the ++ " tag type start line number and the number of tags in a tag type ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{i}_name ++ let start_lnum = ++ \ s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset ++ let end = start_lnum + s:tlist_{a:fidx}_{ttype}_count ++ if a:lnum >= start_lnum && a:lnum <= end ++ break ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Current line doesn't belong to any of the displayed tag types ++ if i > s:tlist_{ftype}_count ++ return '' ++ endif ++ ++ return ttype ++endfunction ++ ++" Tlist_Window_Get_Tag_Index() ++" Return the tag index for the specified line in the taglist window ++function! s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(a:fidx, a:lnum) ++ ++ " Current line doesn't belong to any of the displayed tag types ++ if ttype == '' ++ return 0 ++ endif ++ ++ " Compute the index into the displayed tags for the tag type ++ let ttype_lnum = s:tlist_{a:fidx}_start + s:tlist_{a:fidx}_{ttype}_offset ++ let tidx = a:lnum - ttype_lnum ++ if tidx == 0 ++ return 0 ++ endif ++ ++ " Get the corresponding tag line and return it ++ return s:tlist_{a:fidx}_{ttype}_{tidx} ++endfunction ++ ++" Tlist_Window_Highlight_Line ++" Highlight the current line ++function! s:Tlist_Window_Highlight_Line() ++ " Clear previously selected name ++ match none ++ ++ " Highlight the current line ++ if g:Tlist_Display_Prototype == 0 ++ let pat = '/\%' . line('.') . 'l\s\+\zs.*/' ++ else ++ let pat = '/\%' . line('.') . 'l.*/' ++ endif ++ ++ exe 'match TagListTagName ' . pat ++endfunction ++ ++" Tlist_Window_Open_File ++" Open the specified file in either a new window or an existing window ++" and place the cursor at the specified tag pattern ++function! s:Tlist_Window_Open_File(win_ctrl, filename, tagpat) ++ call s:Tlist_Log_Msg('Tlist_Window_Open_File (' . a:filename . ',' . ++ \ a:win_ctrl . ')') ++ let prev_Tlist_Skip_Refresh = s:Tlist_Skip_Refresh ++ let s:Tlist_Skip_Refresh = 1 ++ ++ if s:tlist_app_name == "winmanager" ++ " Let the winmanager edit the file ++ call WinManagerFileEdit(a:filename, a:win_ctrl == 'newwin') ++ else ++ ++ if a:win_ctrl == 'newtab' ++ " Create a new tab ++ exe 'tabnew ' . escape(a:filename, ' ') ++ " Open the taglist window in the new tab ++ call s:Tlist_Window_Open() ++ endif ++ ++ if a:win_ctrl == 'checktab' ++ " Check whether the file is present in any of the tabs. ++ " If the file is present in the current tab, then use the ++ " current tab. ++ if bufwinnr(a:filename) != -1 ++ let file_present_in_tab = 1 ++ let i = tabpagenr() ++ else ++ let i = 1 ++ let bnum = bufnr(a:filename) ++ let file_present_in_tab = 0 ++ while i <= tabpagenr('$') ++ if index(tabpagebuflist(i), bnum) != -1 ++ let file_present_in_tab = 1 ++ break ++ endif ++ let i += 1 ++ endwhile ++ endif ++ ++ if file_present_in_tab ++ " Goto the tab containing the file ++ exe 'tabnext ' . i ++ else ++ " Open a new tab ++ exe 'tabnew ' . escape(a:filename, ' ') ++ ++ " Open the taglist window ++ call s:Tlist_Window_Open() ++ endif ++ endif ++ ++ let winnum = -1 ++ if a:win_ctrl == 'prevwin' ++ " Open the file in the previous window, if it is usable ++ let cur_win = winnr() ++ wincmd p ++ if &buftype == '' && !&previewwindow ++ exe "edit " . escape(a:filename, ' ') ++ let winnum = winnr() ++ else ++ " Previous window is not usable ++ exe cur_win . 'wincmd w' ++ endif ++ endif ++ ++ " Goto the window containing the file. If the window is not there, open a ++ " new window ++ if winnum == -1 ++ let winnum = bufwinnr(a:filename) ++ endif ++ ++ if winnum == -1 ++ " Locate the previously used window for opening a file ++ let fwin_num = 0 ++ let first_usable_win = 0 ++ ++ let i = 1 ++ let bnum = winbufnr(i) ++ while bnum != -1 ++ if getwinvar(i, 'tlist_file_window') == 'yes' ++ let fwin_num = i ++ break ++ endif ++ if first_usable_win == 0 && ++ \ getbufvar(bnum, '&buftype') == '' && ++ \ !getwinvar(i, '&previewwindow') ++ " First non-taglist, non-plugin and non-preview window ++ let first_usable_win = i ++ endif ++ let i = i + 1 ++ let bnum = winbufnr(i) ++ endwhile ++ ++ " If a previously used window is not found, then use the first ++ " non-taglist window ++ if fwin_num == 0 ++ let fwin_num = first_usable_win ++ endif ++ ++ if fwin_num != 0 ++ " Jump to the file window ++ exe fwin_num . "wincmd w" ++ ++ " If the user asked to jump to the tag in a new window, then split ++ " the existing window into two. ++ if a:win_ctrl == 'newwin' ++ split ++ endif ++ exe "edit " . escape(a:filename, ' ') ++ else ++ " Open a new window ++ if g:Tlist_Use_Horiz_Window ++ exe 'leftabove split ' . escape(a:filename, ' ') ++ else ++ if winbufnr(2) == -1 ++ " Only the taglist window is present ++ if g:Tlist_Use_Right_Window ++ exe 'leftabove vertical split ' . ++ \ escape(a:filename, ' ') ++ else ++ exe 'rightbelow vertical split ' . ++ \ escape(a:filename, ' ') ++ endif ++ ++ " Go to the taglist window to change the window size to ++ " the user configured value ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ if g:Tlist_Use_Horiz_Window ++ exe 'resize ' . g:Tlist_WinHeight ++ else ++ exe 'vertical resize ' . g:Tlist_WinWidth ++ endif ++ " Go back to the file window ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ else ++ " A plugin or help window is also present ++ wincmd w ++ exe 'leftabove split ' . escape(a:filename, ' ') ++ endif ++ endif ++ endif ++ " Mark the window, so that it can be reused. ++ call s:Tlist_Window_Mark_File_Window() ++ else ++ if v:version >= 700 ++ " If the file is opened in more than one window, then check ++ " whether the last accessed window has the selected file. ++ " If it does, then use that window. ++ let lastwin_bufnum = winbufnr(winnr('#')) ++ if bufnr(a:filename) == lastwin_bufnum ++ let winnum = winnr('#') ++ endif ++ endif ++ exe winnum . 'wincmd w' ++ ++ " If the user asked to jump to the tag in a new window, then split the ++ " existing window into two. ++ if a:win_ctrl == 'newwin' ++ split ++ endif ++ endif ++ endif ++ ++ " Jump to the tag ++ if a:tagpat != '' ++ " Add the current cursor position to the jump list, so that user can ++ " jump back using the ' and ` marks. ++ mark ' ++ silent call search(a:tagpat, 'w') ++ ++ " Bring the line to the middle of the window ++ normal! z. ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ endif ++ ++ " If the user selects to preview the tag then jump back to the ++ " taglist window ++ if a:win_ctrl == 'preview' ++ " Go back to the taglist window ++ let winnum = bufwinnr(g:TagList_title) ++ exe winnum . 'wincmd w' ++ else ++ " If the user has selected to close the taglist window, when a ++ " tag is selected, close the taglist window ++ if g:Tlist_Close_On_Select ++ call s:Tlist_Window_Goto_Window() ++ close ++ ++ " Go back to the window displaying the selected file ++ let wnum = bufwinnr(a:filename) ++ if wnum != -1 && wnum != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds(wnum . 'wincmd w') ++ endif ++ endif ++ endif ++ ++ let s:Tlist_Skip_Refresh = prev_Tlist_Skip_Refresh ++endfunction ++ ++" Tlist_Window_Jump_To_Tag() ++" Jump to the location of the current tag ++" win_ctrl == useopen - Reuse the existing file window ++" win_ctrl == newwin - Open a new window ++" win_ctrl == preview - Preview the tag ++" win_ctrl == prevwin - Open in previous window ++" win_ctrl == newtab - Open in new tab ++function! s:Tlist_Window_Jump_To_Tag(win_ctrl) ++ call s:Tlist_Log_Msg('Tlist_Window_Jump_To_Tag(' . a:win_ctrl . ')') ++ " Do not process comment lines and empty lines ++ let curline = getline('.') ++ if curline =~ '^\s*$' || curline[0] == '"' ++ return ++ endif ++ ++ " If inside a closed fold, then use the first line of the fold ++ " and jump to the file. ++ let lnum = foldclosed('.') ++ if lnum == -1 ++ " Jump to the selected tag or file ++ let lnum = line('.') ++ else ++ " Open the closed fold ++ .foldopen! ++ endif ++ ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ if fidx == -1 ++ return ++ endif ++ ++ " Get the tag output for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ if tidx != 0 ++ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, tidx) ++ ++ " Highlight the tagline ++ call s:Tlist_Window_Highlight_Line() ++ else ++ " Selected a line which is not a tag name. Just edit the file ++ let tagpat = '' ++ endif ++ ++ call s:Tlist_Window_Open_File(a:win_ctrl, s:tlist_{fidx}_filename, tagpat) ++endfunction ++ ++" Tlist_Window_Show_Info() ++" Display information about the entry under the cursor ++function! s:Tlist_Window_Show_Info() ++ call s:Tlist_Log_Msg('Tlist_Window_Show_Info()') ++ ++ " Clear the previously displayed line ++ echo ++ ++ " Do not process comment lines and empty lines ++ let curline = getline('.') ++ if curline =~ '^\s*$' || curline[0] == '"' ++ return ++ endif ++ ++ " If inside a fold, then don't display the prototype ++ if foldclosed('.') != -1 ++ return ++ endif ++ ++ let lnum = line('.') ++ ++ " Get the file index ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(lnum) ++ if fidx == -1 ++ return ++ endif ++ ++ if lnum == s:tlist_{fidx}_start ++ " Cursor is on a file name ++ let fname = s:tlist_{fidx}_filename ++ if strlen(fname) > 50 ++ let fname = fnamemodify(fname, ':t') ++ endif ++ echo fname . ', Filetype=' . s:tlist_{fidx}_filetype . ++ \ ', Tag count=' . s:tlist_{fidx}_tag_count ++ return ++ endif ++ ++ " Get the tag output line for the current tag ++ let tidx = s:Tlist_Window_Get_Tag_Index(fidx, lnum) ++ if tidx == 0 ++ " Cursor is on a tag type ++ let ttype = s:Tlist_Window_Get_Tag_Type_By_Linenum(fidx, lnum) ++ if ttype == '' ++ return ++ endif ++ ++ let ttype_name = '' ++ ++ let ftype = s:tlist_{fidx}_filetype ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ if ttype == s:tlist_{ftype}_{i}_name ++ let ttype_name = s:tlist_{ftype}_{i}_fullname ++ break ++ endif ++ let i = i + 1 ++ endwhile ++ ++ echo 'Tag type=' . ttype_name . ++ \ ', Tag count=' . s:tlist_{fidx}_{ttype}_count ++ return ++ endif ++ ++ " Get the tag search pattern and display it ++ echo s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Find_Nearest_Tag_Idx ++" Find the tag idx nearest to the supplied line number ++" Returns -1, if a tag couldn't be found for the specified line number ++function! s:Tlist_Find_Nearest_Tag_Idx(fidx, linenum) ++ let sort_type = s:tlist_{a:fidx}_sort_type ++ ++ let left = 1 ++ let right = s:tlist_{a:fidx}_tag_count ++ ++ if sort_type == 'order' ++ " Tags sorted by order, use a binary search. ++ " The idea behind this function is taken from the ctags.vim script (by ++ " Alexey Marinichev) available at the Vim online website. ++ ++ " If the current line is the less than the first tag, then no need to ++ " search ++ let first_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, 1) ++ ++ if a:linenum < first_lnum ++ return -1 ++ endif ++ ++ while left < right ++ let middle = (right + left + 1) / 2 ++ let middle_lnum = s:Tlist_Get_Tag_Linenum(a:fidx, middle) ++ ++ if middle_lnum == a:linenum ++ let left = middle ++ break ++ endif ++ ++ if middle_lnum > a:linenum ++ let right = middle - 1 ++ else ++ let left = middle ++ endif ++ endwhile ++ else ++ " Tags sorted by name, use a linear search. (contributed by Dave ++ " Eggum). ++ " Look for a tag with a line number less than or equal to the supplied ++ " line number. If multiple tags are found, then use the tag with the ++ " line number closest to the supplied line number. IOW, use the tag ++ " with the highest line number. ++ let closest_lnum = 0 ++ let final_left = 0 ++ while left <= right ++ let lnum = s:Tlist_Get_Tag_Linenum(a:fidx, left) ++ ++ if lnum < a:linenum && lnum > closest_lnum ++ let closest_lnum = lnum ++ let final_left = left ++ elseif lnum == a:linenum ++ let closest_lnum = lnum ++ let final_left = left ++ break ++ else ++ let left = left + 1 ++ endif ++ endwhile ++ if closest_lnum == 0 ++ return -1 ++ endif ++ if left >= right ++ let left = final_left ++ endif ++ endif ++ ++ return left ++endfunction ++ ++" Tlist_Window_Highlight_Tag() ++" Highlight the current tag ++" cntx == 1, Called by the taglist plugin itself ++" cntx == 2, Forced by the user through the TlistHighlightTag command ++" center = 1, move the tag line to the center of the taglist window ++function! s:Tlist_Window_Highlight_Tag(filename, cur_lnum, cntx, center) ++ " Highlight the current tag only if the user configured the ++ " taglist plugin to do so or if the user explictly invoked the ++ " command to highlight the current tag. ++ if !g:Tlist_Auto_Highlight_Tag && a:cntx == 1 ++ return ++ endif ++ ++ if a:filename == '' ++ return ++ endif ++ ++ " Make sure the taglist window is present ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Error: Taglist window is not open') ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ return ++ endif ++ ++ " If the file is currently not displayed in the taglist window, then retrn ++ if !s:tlist_{fidx}_visible ++ return ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return ++ endif ++ ++ " Ignore all autocommands ++ let old_ei = &eventignore ++ set eventignore=all ++ ++ " Save the original window number ++ let org_winnr = winnr() ++ ++ if org_winnr == winnum ++ let in_taglist_window = 1 ++ else ++ let in_taglist_window = 0 ++ endif ++ ++ " Go to the taglist window ++ if !in_taglist_window ++ exe winnum . 'wincmd w' ++ endif ++ ++ " Clear previously selected name ++ match none ++ ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, a:cur_lnum) ++ if tidx == -1 ++ " Make sure the current tag line is visible in the taglist window. ++ " Calling the winline() function makes the line visible. Don't know ++ " of a better way to achieve this. ++ let lnum = line('.') ++ ++ if lnum < s:tlist_{fidx}_start || lnum > s:tlist_{fidx}_end ++ " Move the cursor to the beginning of the file ++ exe s:tlist_{fidx}_start ++ endif ++ ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ ++ call winline() ++ ++ if !in_taglist_window ++ exe org_winnr . 'wincmd w' ++ endif ++ ++ " Restore the autocommands ++ let &eventignore = old_ei ++ return ++ endif ++ ++ " Extract the tag type ++ let ttype = s:Tlist_Get_Tag_Type_By_Tag(fidx, tidx) ++ ++ " Compute the line number ++ " Start of file + Start of tag type + offset ++ let lnum = s:tlist_{fidx}_start + s:tlist_{fidx}_{ttype}_offset + ++ \ s:tlist_{fidx}_{tidx}_ttype_idx ++ ++ " Goto the line containing the tag ++ exe lnum ++ ++ " Open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++ ++ if a:center ++ " Move the tag line to the center of the taglist window ++ normal! z. ++ else ++ " Make sure the current tag line is visible in the taglist window. ++ " Calling the winline() function makes the line visible. Don't know ++ " of a better way to achieve this. ++ call winline() ++ endif ++ ++ " Highlight the tag name ++ call s:Tlist_Window_Highlight_Line() ++ ++ " Go back to the original window ++ if !in_taglist_window ++ exe org_winnr . 'wincmd w' ++ endif ++ ++ " Restore the autocommands ++ let &eventignore = old_ei ++ return ++endfunction ++ ++" Tlist_Get_Tag_Prototype_By_Line ++" Get the prototype for the tag on or before the specified line number in the ++" current buffer ++function! Tlist_Get_Tag_Prototype_By_Line(...) ++ if a:0 == 0 ++ " Arguments are not supplied. Use the current buffer name ++ " and line number ++ let filename = bufname('%') ++ let linenr = line('.') ++ elseif a:0 == 2 ++ " Filename and line number are specified ++ let filename = a:1 ++ let linenr = a:2 ++ if linenr !~ '\d\+' ++ " Invalid line number ++ return "" ++ endif ++ else ++ " Sufficient arguments are not supplied ++ let msg = 'Usage: Tlist_Get_Tag_Prototype_By_Line ' . ++ \ '' ++ call s:Tlist_Warning_Msg(msg) ++ return "" ++ endif ++ ++ " Expand the file to a fully qualified name ++ let filename = fnamemodify(filename, ':p') ++ if filename == '' ++ return "" ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ return "" ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return "" ++ endif ++ ++ " Get the tag text using the line number ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr) ++ if tidx == -1 ++ return "" ++ endif ++ ++ return s:Tlist_Get_Tag_Prototype(fidx, tidx) ++endfunction ++ ++" Tlist_Get_Tagname_By_Line ++" Get the tag name on or before the specified line number in the ++" current buffer ++function! Tlist_Get_Tagname_By_Line(...) ++ if a:0 == 0 ++ " Arguments are not supplied. Use the current buffer name ++ " and line number ++ let filename = bufname('%') ++ let linenr = line('.') ++ elseif a:0 == 2 ++ " Filename and line number are specified ++ let filename = a:1 ++ let linenr = a:2 ++ if linenr !~ '\d\+' ++ " Invalid line number ++ return "" ++ endif ++ else ++ " Sufficient arguments are not supplied ++ let msg = 'Usage: Tlist_Get_Tagname_By_Line ' ++ call s:Tlist_Warning_Msg(msg) ++ return "" ++ endif ++ ++ " Make sure the current file has a name ++ let filename = fnamemodify(filename, ':p') ++ if filename == '' ++ return "" ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 ++ return "" ++ endif ++ ++ " If there are no tags for this file, then no need to proceed further ++ if s:tlist_{fidx}_tag_count == 0 ++ return "" ++ endif ++ ++ " Get the tag name using the line number ++ let tidx = s:Tlist_Find_Nearest_Tag_Idx(fidx, linenr) ++ if tidx == -1 ++ return "" ++ endif ++ ++ return s:tlist_{fidx}_{tidx}_tag_name ++endfunction ++ ++" Tlist_Window_Move_To_File ++" Move the cursor to the beginning of the current file or the next file ++" or the previous file in the taglist window ++" dir == -1, move to start of current or previous function ++" dir == 1, move to start of next function ++function! s:Tlist_Window_Move_To_File(dir) ++ if foldlevel('.') == 0 ++ " Cursor is on a non-folded line (it is not in any of the files) ++ " Move it to a folded line ++ if a:dir == -1 ++ normal! zk ++ else ++ " While moving down to the start of the next fold, ++ " no need to do go to the start of the next file. ++ normal! zj ++ return ++ endif ++ endif ++ ++ let fidx = s:Tlist_Window_Get_File_Index_By_Linenum(line('.')) ++ if fidx == -1 ++ return ++ endif ++ ++ let cur_lnum = line('.') ++ ++ if a:dir == -1 ++ if cur_lnum > s:tlist_{fidx}_start ++ " Move to the beginning of the current file ++ exe s:tlist_{fidx}_start ++ return ++ endif ++ ++ if fidx != 0 ++ " Move to the beginning of the previous file ++ let fidx = fidx - 1 ++ else ++ " Cursor is at the first file, wrap around to the last file ++ let fidx = s:tlist_file_count - 1 ++ endif ++ ++ exe s:tlist_{fidx}_start ++ return ++ else ++ " Move to the beginning of the next file ++ let fidx = fidx + 1 ++ ++ if fidx >= s:tlist_file_count ++ " Cursor is at the last file, wrap around to the first file ++ let fidx = 0 ++ endif ++ ++ if s:tlist_{fidx}_start != 0 ++ exe s:tlist_{fidx}_start ++ endif ++ return ++ endif ++endfunction ++ ++" Tlist_Session_Load ++" Load a taglist session (information about all the displayed files ++" and the tags) from the specified file ++function! s:Tlist_Session_Load(...) ++ if a:0 == 0 || a:1 == '' ++ call s:Tlist_Warning_Msg('Usage: TlistSessionLoad ') ++ return ++ endif ++ ++ let sessionfile = a:1 ++ ++ if !filereadable(sessionfile) ++ let msg = 'Taglist: Error - Unable to open file ' . sessionfile ++ call s:Tlist_Warning_Msg(msg) ++ return ++ endif ++ ++ " Mark the current window as the file window ++ call s:Tlist_Window_Mark_File_Window() ++ ++ " Source the session file ++ exe 'source ' . sessionfile ++ ++ let new_file_count = g:tlist_file_count ++ unlet! g:tlist_file_count ++ ++ let i = 0 ++ while i < new_file_count ++ let ftype = g:tlist_{i}_filetype ++ unlet! g:tlist_{i}_filetype ++ ++ if !exists('s:tlist_' . ftype . '_count') ++ if s:Tlist_FileType_Init(ftype) == 0 ++ let i = i + 1 ++ continue ++ endif ++ endif ++ ++ let fname = g:tlist_{i}_filename ++ unlet! g:tlist_{i}_filename ++ ++ let fidx = s:Tlist_Get_File_Index(fname) ++ if fidx != -1 ++ let s:tlist_{fidx}_visible = 0 ++ let i = i + 1 ++ continue ++ else ++ " As we are loading the tags from the session file, if this ++ " file was previously deleted by the user, now we need to ++ " add it back. So remove the file from the deleted list. ++ call s:Tlist_Update_Remove_List(fname, 0) ++ endif ++ ++ let fidx = s:Tlist_Init_File(fname, ftype) ++ ++ let s:tlist_{fidx}_filename = fname ++ ++ let s:tlist_{fidx}_sort_type = g:tlist_{i}_sort_type ++ unlet! g:tlist_{i}_sort_type ++ ++ let s:tlist_{fidx}_filetype = ftype ++ let s:tlist_{fidx}_mtime = getftime(fname) ++ ++ let s:tlist_{fidx}_start = 0 ++ let s:tlist_{fidx}_end = 0 ++ ++ let s:tlist_{fidx}_valid = 1 ++ ++ let s:tlist_{fidx}_tag_count = g:tlist_{i}_tag_count ++ unlet! g:tlist_{i}_tag_count ++ ++ let j = 1 ++ while j <= s:tlist_{fidx}_tag_count ++ let s:tlist_{fidx}_{j}_tag = g:tlist_{i}_{j}_tag ++ let s:tlist_{fidx}_{j}_tag_name = g:tlist_{i}_{j}_tag_name ++ let s:tlist_{fidx}_{j}_ttype_idx = g:tlist_{i}_{j}_ttype_idx ++ unlet! g:tlist_{i}_{j}_tag ++ unlet! g:tlist_{i}_{j}_tag_name ++ unlet! g:tlist_{i}_{j}_ttype_idx ++ let j = j + 1 ++ endwhile ++ ++ let j = 1 ++ while j <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{j}_name ++ ++ if exists('g:tlist_' . i . '_' . ttype) ++ let s:tlist_{fidx}_{ttype} = g:tlist_{i}_{ttype} ++ unlet! g:tlist_{i}_{ttype} ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = g:tlist_{i}_{ttype}_count ++ unlet! g:tlist_{i}_{ttype}_count ++ ++ let k = 1 ++ while k <= s:tlist_{fidx}_{ttype}_count ++ let s:tlist_{fidx}_{ttype}_{k} = g:tlist_{i}_{ttype}_{k} ++ unlet! g:tlist_{i}_{ttype}_{k} ++ let k = k + 1 ++ endwhile ++ else ++ let s:tlist_{fidx}_{ttype} = '' ++ let s:tlist_{fidx}_{ttype}_offset = 0 ++ let s:tlist_{fidx}_{ttype}_count = 0 ++ endif ++ ++ let j = j + 1 ++ endwhile ++ ++ let i = i + 1 ++ endwhile ++ ++ " If the taglist window is open, then update it ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum != -1 ++ let save_winnr = winnr() ++ ++ " Goto the taglist window ++ call s:Tlist_Window_Goto_Window() ++ ++ " Refresh the taglist window ++ call s:Tlist_Window_Refresh() ++ ++ " Go back to the original window ++ if save_winnr != winnr() ++ call s:Tlist_Exe_Cmd_No_Acmds('wincmd p') ++ endif ++ endif ++endfunction ++ ++" Tlist_Session_Save ++" Save a taglist session (information about all the displayed files ++" and the tags) into the specified file ++function! s:Tlist_Session_Save(...) ++ if a:0 == 0 || a:1 == '' ++ call s:Tlist_Warning_Msg('Usage: TlistSessionSave ') ++ return ++ endif ++ ++ let sessionfile = a:1 ++ ++ if s:tlist_file_count == 0 ++ " There is nothing to save ++ call s:Tlist_Warning_Msg('Warning: Taglist is empty. Nothing to save.') ++ return ++ endif ++ ++ if filereadable(sessionfile) ++ let ans = input('Do you want to overwrite ' . sessionfile . ' (Y/N)?') ++ if ans !=? 'y' ++ return ++ endif ++ ++ echo "\n" ++ endif ++ ++ let old_verbose = &verbose ++ set verbose&vim ++ ++ exe 'redir! > ' . sessionfile ++ ++ silent! echo '" Taglist session file. This file is auto-generated.' ++ silent! echo '" File information' ++ silent! echo 'let tlist_file_count = ' . s:tlist_file_count ++ ++ let i = 0 ++ ++ while i < s:tlist_file_count ++ " Store information about the file ++ silent! echo 'let tlist_' . i . "_filename = '" . ++ \ s:tlist_{i}_filename . "'" ++ silent! echo 'let tlist_' . i . '_sort_type = "' . ++ \ s:tlist_{i}_sort_type . '"' ++ silent! echo 'let tlist_' . i . '_filetype = "' . ++ \ s:tlist_{i}_filetype . '"' ++ silent! echo 'let tlist_' . i . '_tag_count = ' . ++ \ s:tlist_{i}_tag_count ++ " Store information about all the tags ++ let j = 1 ++ while j <= s:tlist_{i}_tag_count ++ let txt = escape(s:tlist_{i}_{j}_tag, '"\\') ++ silent! echo 'let tlist_' . i . '_' . j . '_tag = "' . txt . '"' ++ silent! echo 'let tlist_' . i . '_' . j . '_tag_name = "' . ++ \ s:tlist_{i}_{j}_tag_name . '"' ++ silent! echo 'let tlist_' . i . '_' . j . '_ttype_idx' . ' = ' . ++ \ s:tlist_{i}_{j}_ttype_idx ++ let j = j + 1 ++ endwhile ++ ++ " Store information about all the tags grouped by their type ++ let ftype = s:tlist_{i}_filetype ++ let j = 1 ++ while j <= s:tlist_{ftype}_count ++ let ttype = s:tlist_{ftype}_{j}_name ++ if s:tlist_{i}_{ttype}_count != 0 ++ let txt = substitute(s:tlist_{i}_{ttype}, "\n", "\\\\n", 'g') ++ silent! echo 'let tlist_' . i . '_' . ttype . ' = "' . ++ \ txt . '"' ++ silent! echo 'let tlist_' . i . '_' . ttype . '_count = ' . ++ \ s:tlist_{i}_{ttype}_count ++ let k = 1 ++ while k <= s:tlist_{i}_{ttype}_count ++ silent! echo 'let tlist_' . i . '_' . ttype . '_' . k . ++ \ ' = ' . s:tlist_{i}_{ttype}_{k} ++ let k = k + 1 ++ endwhile ++ endif ++ let j = j + 1 ++ endwhile ++ ++ silent! echo ++ ++ let i = i + 1 ++ endwhile ++ ++ redir END ++ ++ let &verbose = old_verbose ++endfunction ++ ++" Tlist_Buffer_Removed ++" A buffer is removed from the Vim buffer list. Remove the tags defined ++" for that file ++function! s:Tlist_Buffer_Removed(filename) ++ call s:Tlist_Log_Msg('Tlist_Buffer_Removed (' . a:filename . ')') ++ ++ " Make sure a valid filename is supplied ++ if a:filename == '' ++ return ++ endif ++ ++ " Get tag list index of the specified file ++ let fidx = s:Tlist_Get_File_Index(a:filename) ++ if fidx == -1 ++ " File not present in the taglist ++ return ++ endif ++ ++ " Remove the file from the list ++ call s:Tlist_Remove_File(fidx, 0) ++endfunction ++ ++" When a buffer is deleted, remove the file from the taglist ++autocmd BufDelete * silent call s:Tlist_Buffer_Removed(expand(':p')) ++ ++" Tlist_Window_Open_File_Fold ++" Open the fold for the specified file and close the fold for all the ++" other files ++function! s:Tlist_Window_Open_File_Fold(acmd_file) ++ call s:Tlist_Log_Msg('Tlist_Window_Open_File_Fold (' . a:acmd_file . ')') ++ ++ " Make sure the taglist window is present ++ let winnum = bufwinnr(g:TagList_title) ++ if winnum == -1 ++ call s:Tlist_Warning_Msg('Taglist: Error - Taglist window is not open') ++ return ++ endif ++ ++ " Save the original window number ++ let org_winnr = winnr() ++ if org_winnr == winnum ++ let in_taglist_window = 1 ++ else ++ let in_taglist_window = 0 ++ endif ++ ++ if in_taglist_window ++ " When entering the taglist window, no need to update the folds ++ return ++ endif ++ ++ " Go to the taglist window ++ if !in_taglist_window ++ call s:Tlist_Exe_Cmd_No_Acmds(winnum . 'wincmd w') ++ endif ++ ++ " Close all the folds ++ silent! %foldclose ++ ++ " Get tag list index of the specified file ++ let fname = fnamemodify(a:acmd_file, ":p") ++ if filereadable(fname) ++ let fidx = s:Tlist_Get_File_Index(fname) ++ if fidx != -1 ++ " Open the fold for the file ++ exe "silent! " . s:tlist_{fidx}_start . "," . ++ \ s:tlist_{fidx}_end . "foldopen" ++ endif ++ endif ++ ++ " Go back to the original window ++ if !in_taglist_window ++ call s:Tlist_Exe_Cmd_No_Acmds(org_winnr . 'wincmd w') ++ endif ++endfunction ++ ++" Tlist_Window_Check_Auto_Open ++" Open the taglist window automatically on Vim startup. ++" Open the window only when files present in any of the Vim windows support ++" tags. ++function! s:Tlist_Window_Check_Auto_Open() ++ let open_window = 0 ++ ++ let i = 1 ++ let buf_num = winbufnr(i) ++ while buf_num != -1 ++ let filename = fnamemodify(bufname(buf_num), ':p') ++ if !s:Tlist_Skip_File(filename, getbufvar(buf_num, '&filetype')) ++ let open_window = 1 ++ break ++ endif ++ let i = i + 1 ++ let buf_num = winbufnr(i) ++ endwhile ++ ++ if open_window ++ call s:Tlist_Window_Toggle() ++ endif ++endfunction ++ ++function! s:Tlist_Menu_Add_Base_Menu() ++ call s:Tlist_Log_Msg('Adding the base menu') ++ ++ " Add the menu ++ anoremenu T&ags.Refresh\ menu :call Tlist_Menu_Refresh() ++ anoremenu T&ags.Sort\ menu\ by.Name ++ \ :call Tlist_Change_Sort('menu', 'set', 'name') ++ anoremenu T&ags.Sort\ menu\ by.Order ++ \ :call Tlist_Change_Sort('menu', 'set', 'order') ++ anoremenu T&ags.-SEP1- : ++ ++ if &mousemodel =~ 'popup' ++ anoremenu PopUp.T&ags.Refresh\ menu ++ \ :call Tlist_Menu_Refresh() ++ anoremenu PopUp.T&ags.Sort\ menu\ by.Name ++ \ :call Tlist_Change_Sort('menu', 'set', 'name') ++ anoremenu PopUp.T&ags.Sort\ menu\ by.Order ++ \ :call Tlist_Change_Sort('menu', 'set', 'order') ++ anoremenu PopUp.T&ags.-SEP1- : ++ endif ++endfunction ++ ++let s:menu_char_prefix = ++ \ '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ++ ++" Tlist_Menu_Get_Tag_Type_Cmd ++" Get the menu command for the specified tag type ++" fidx - File type index ++" ftype - File Type ++" add_ttype_name - To add or not to add the tag type name to the menu entries ++" ttype_idx - Tag type index ++function! s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, ttype_idx) ++ " Curly brace variable name optimization ++ let ftype_ttype_idx = a:ftype . '_' . a:ttype_idx ++ ++ let ttype = s:tlist_{ftype_ttype_idx}_name ++ if a:add_ttype_name ++ " If the tag type name contains space characters, escape it. This ++ " will be used to create the menu entries. ++ let ttype_fullname = escape(s:tlist_{ftype_ttype_idx}_fullname, ' ') ++ endif ++ ++ " Curly brace variable name optimization ++ let fidx_ttype = a:fidx . '_' . ttype ++ ++ " Number of tag entries for this tag type ++ let tcnt = s:tlist_{fidx_ttype}_count ++ if tcnt == 0 " No entries for this tag type ++ return '' ++ endif ++ ++ let mcmd = '' ++ ++ " Create the menu items for the tags. ++ " Depending on the number of tags of this type, split the menu into ++ " multiple sub-menus, if needed. ++ if tcnt > g:Tlist_Max_Submenu_Items ++ let j = 1 ++ while j <= tcnt ++ let final_index = j + g:Tlist_Max_Submenu_Items - 1 ++ if final_index > tcnt ++ let final_index = tcnt ++ endif ++ ++ " Extract the first and last tag name and form the ++ " sub-menu name ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ let first_tag = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let tidx = s:tlist_{fidx_ttype}_{final_index} ++ let last_tag = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ " Truncate the names, if they are greater than the ++ " max length ++ let first_tag = strpart(first_tag, 0, g:Tlist_Max_Tag_Length) ++ let last_tag = strpart(last_tag, 0, g:Tlist_Max_Tag_Length) ++ ++ " Form the menu command prefix ++ let m_prefix = 'anoremenu T\&ags.' ++ if a:add_ttype_name ++ let m_prefix = m_prefix . ttype_fullname . '.' ++ endif ++ let m_prefix = m_prefix . first_tag . '\.\.\.' . last_tag . '.' ++ ++ " Character prefix used to number the menu items (hotkey) ++ let m_prefix_idx = 0 ++ ++ while j <= final_index ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ ++ let tname = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let mcmd = mcmd . m_prefix . '\&' . ++ \ s:menu_char_prefix[m_prefix_idx] . '\.' . ++ \ tname . ' :call Tlist_Menu_Jump_To_Tag(' . ++ \ tidx . ')|' ++ ++ let m_prefix_idx = m_prefix_idx + 1 ++ let j = j + 1 ++ endwhile ++ endwhile ++ else ++ " Character prefix used to number the menu items (hotkey) ++ let m_prefix_idx = 0 ++ ++ let m_prefix = 'anoremenu T\&ags.' ++ if a:add_ttype_name ++ let m_prefix = m_prefix . ttype_fullname . '.' ++ endif ++ let j = 1 ++ while j <= tcnt ++ let tidx = s:tlist_{fidx_ttype}_{j} ++ ++ let tname = s:tlist_{a:fidx}_{tidx}_tag_name ++ ++ let mcmd = mcmd . m_prefix . '\&' . ++ \ s:menu_char_prefix[m_prefix_idx] . '\.' . ++ \ tname . ' :call Tlist_Menu_Jump_To_Tag(' . tidx ++ \ . ')|' ++ ++ let m_prefix_idx = m_prefix_idx + 1 ++ let j = j + 1 ++ endwhile ++ endif ++ ++ return mcmd ++endfunction ++ ++" Update the taglist menu with the tags for the specified file ++function! s:Tlist_Menu_File_Refresh(fidx) ++ call s:Tlist_Log_Msg('Refreshing the tag menu for ' . s:tlist_{a:fidx}_filename) ++ " The 'B' flag is needed in the 'cpoptions' option ++ let old_cpoptions = &cpoptions ++ set cpoptions&vim ++ ++ exe s:tlist_{a:fidx}_menu_cmd ++ ++ " Update the popup menu (if enabled) ++ if &mousemodel =~ 'popup' ++ let cmd = substitute(s:tlist_{a:fidx}_menu_cmd, ' T\\&ags\.', ++ \ ' PopUp.T\\\&ags.', "g") ++ exe cmd ++ endif ++ ++ " The taglist menu is not empty now ++ let s:tlist_menu_empty = 0 ++ ++ " Restore the 'cpoptions' settings ++ let &cpoptions = old_cpoptions ++endfunction ++ ++" Tlist_Menu_Update_File ++" Add the taglist menu ++function! s:Tlist_Menu_Update_File(clear_menu) ++ if !has('gui_running') ++ " Not running in GUI mode ++ return ++ endif ++ ++ call s:Tlist_Log_Msg('Updating the tag menu, clear_menu = ' . a:clear_menu) ++ ++ " Remove the tags menu ++ if a:clear_menu ++ call s:Tlist_Menu_Remove_File() ++ ++ endif ++ ++ let fname = escape(fnamemodify(bufname('%'), ':t'), '.') ++ if fname != '' ++ exe 'anoremenu T&ags.' . fname . ' ' ++ anoremenu T&ags.-SEP2- : ++ endif ++ ++ " Skip buffers with 'buftype' set to nofile, nowrite, quickfix or help ++ if &buftype != '' ++ return ++ endif ++ ++ let filename = fnamemodify(bufname('%'), ':p') ++ let ftype = &filetype ++ ++ " If the file doesn't support tag listing, skip it ++ if s:Tlist_Skip_File(filename, ftype) ++ return ++ endif ++ ++ let fidx = s:Tlist_Get_File_Index(filename) ++ if fidx == -1 || !s:tlist_{fidx}_valid ++ " Check whether this file is removed based on user request ++ " If it is, then don't display the tags for this file ++ if s:Tlist_User_Removed_File(filename) ++ return ++ endif ++ ++ " Process the tags for the file ++ let fidx = s:Tlist_Process_File(filename, ftype) ++ if fidx == -1 ++ return ++ endif ++ endif ++ ++ if !s:tlist_{fidx}_tag_count ++ return ++ endif ++ ++ if s:tlist_{fidx}_menu_cmd != '' ++ " Update the menu with the cached command ++ call s:Tlist_Menu_File_Refresh(fidx) ++ ++ return ++ endif ++ ++ " We are going to add entries to the tags menu, so the menu won't be ++ " empty ++ let s:tlist_menu_empty = 0 ++ ++ let cmd = '' ++ ++ " Determine whether the tag type name needs to be added to the menu ++ " If more than one tag type is present in the taglisting for a file, ++ " then the tag type name needs to be present ++ let add_ttype_name = -1 ++ let i = 1 ++ while i <= s:tlist_{ftype}_count && add_ttype_name < 1 ++ let ttype = s:tlist_{ftype}_{i}_name ++ if s:tlist_{fidx}_{ttype}_count ++ let add_ttype_name = add_ttype_name + 1 ++ endif ++ let i = i + 1 ++ endwhile ++ ++ " Process the tags by the tag type and get the menu command ++ let i = 1 ++ while i <= s:tlist_{ftype}_count ++ let mcmd = s:Tlist_Menu_Get_Tag_Type_Cmd(fidx, ftype, add_ttype_name, i) ++ if mcmd != '' ++ let cmd = cmd . mcmd ++ endif ++ ++ let i = i + 1 ++ endwhile ++ ++ " Cache the menu command for reuse ++ let s:tlist_{fidx}_menu_cmd = cmd ++ ++ " Update the menu ++ call s:Tlist_Menu_File_Refresh(fidx) ++endfunction ++ ++" Tlist_Menu_Remove_File ++" Remove the tags displayed in the tags menu ++function! s:Tlist_Menu_Remove_File() ++ if !has('gui_running') || s:tlist_menu_empty ++ return ++ endif ++ ++ call s:Tlist_Log_Msg('Removing the tags menu for a file') ++ ++ " Cleanup the Tags menu ++ silent! unmenu T&ags ++ if &mousemodel =~ 'popup' ++ silent! unmenu PopUp.T&ags ++ endif ++ ++ " Add a dummy menu item to retain teared off menu ++ noremenu T&ags.Dummy l ++ ++ silent! unmenu! T&ags ++ if &mousemodel =~ 'popup' ++ silent! unmenu! PopUp.T&ags ++ endif ++ ++ call s:Tlist_Menu_Add_Base_Menu() ++ ++ " Remove the dummy menu item ++ unmenu T&ags.Dummy ++ ++ let s:tlist_menu_empty = 1 ++endfunction ++ ++" Tlist_Menu_Refresh ++" Refresh the taglist menu ++function! s:Tlist_Menu_Refresh() ++ call s:Tlist_Log_Msg('Refreshing the tags menu') ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx != -1 ++ " Invalidate the cached menu command ++ let s:tlist_{fidx}_menu_cmd = '' ++ endif ++ ++ " Update the taglist, menu and window ++ call s:Tlist_Update_Current_File() ++endfunction ++ ++" Tlist_Menu_Jump_To_Tag ++" Jump to the selected tag ++function! s:Tlist_Menu_Jump_To_Tag(tidx) ++ let fidx = s:Tlist_Get_File_Index(fnamemodify(bufname('%'), ':p')) ++ if fidx == -1 ++ return ++ endif ++ ++ let tagpat = s:Tlist_Get_Tag_SearchPat(fidx, a:tidx) ++ if tagpat == '' ++ return ++ endif ++ ++ " Add the current cursor position to the jump list, so that user can ++ " jump back using the ' and ` marks. ++ mark ' ++ ++ silent call search(tagpat, 'w') ++ ++ " Bring the line to the middle of the window ++ normal! z. ++ ++ " If the line is inside a fold, open the fold ++ if foldclosed('.') != -1 ++ .foldopen ++ endif ++endfunction ++ ++" Tlist_Menu_Init ++" Initialize the taglist menu ++function! s:Tlist_Menu_Init() ++ call s:Tlist_Menu_Add_Base_Menu() ++ ++ " Automatically add the tags defined in the current file to the menu ++ augroup TagListMenuCmds ++ autocmd! ++ ++ if !g:Tlist_Process_File_Always ++ autocmd BufEnter * call s:Tlist_Refresh() ++ endif ++ autocmd BufLeave * call s:Tlist_Menu_Remove_File() ++ augroup end ++ ++ call s:Tlist_Menu_Update_File(0) ++endfunction ++ ++" Tlist_Vim_Session_Load ++" Initialize the taglist window/buffer, which is created when loading ++" a Vim session file. ++function! s:Tlist_Vim_Session_Load() ++ call s:Tlist_Log_Msg('Tlist_Vim_Session_Load') ++ ++ " Initialize the taglist window ++ call s:Tlist_Window_Init() ++ ++ " Refresh the taglist window ++ call s:Tlist_Window_Refresh() ++endfunction ++ ++" Tlist_Set_App ++" Set the name of the external plugin/application to which taglist ++" belongs. ++" Taglist plugin is part of another plugin like cream or winmanager. ++function! Tlist_Set_App(name) ++ if a:name == "" ++ return ++ endif ++ ++ let s:tlist_app_name = a:name ++endfunction ++ ++" Winmanager integration ++ ++" Initialization required for integration with winmanager ++function! TagList_Start() ++ " If current buffer is not taglist buffer, then don't proceed ++ if bufname('%') != '__Tag_List__' ++ return ++ endif ++ ++ call Tlist_Set_App('winmanager') ++ ++ " Get the current filename from the winmanager plugin ++ let bufnum = WinManagerGetLastEditedFile() ++ if bufnum != -1 ++ let filename = fnamemodify(bufname(bufnum), ':p') ++ let ftype = getbufvar(bufnum, '&filetype') ++ endif ++ ++ " Initialize the taglist window, if it is not already initialized ++ if !exists('s:tlist_window_initialized') || !s:tlist_window_initialized ++ call s:Tlist_Window_Init() ++ call s:Tlist_Window_Refresh() ++ let s:tlist_window_initialized = 1 ++ endif ++ ++ " Update the taglist window ++ if bufnum != -1 ++ if !s:Tlist_Skip_File(filename, ftype) && g:Tlist_Auto_Update ++ call s:Tlist_Window_Refresh_File(filename, ftype) ++ endif ++ endif ++endfunction ++ ++function! TagList_IsValid() ++ return 0 ++endfunction ++ ++function! TagList_WrapUp() ++ return 0 ++endfunction ++ ++" restore 'cpo' ++let &cpo = s:cpo_save ++unlet s:cpo_save ++ +diff -urN vim71/runtime/syntax/ada.vim vim71_ada/runtime/syntax/ada.vim +--- vim71/runtime/syntax/ada.vim 2007-05-05 20:22:26.000000000 +0200 ++++ vim71_ada/runtime/syntax/ada.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -1,17 +1,17 @@ + "---------------------------------------------------------------------------- + " Description: Vim Ada syntax file + " Language: Ada (2005) +-" $Id: ada.vim,v 1.2 2007/05/05 18:22:26 vimboss Exp $ ++" $Id: ada.vim 793 2007-11-01 18:29:58Z krischik $ + " Copyright: Copyright (C) 2006 Martin Krischik + " Maintainer: Martin Krischik + " David A. Wheeler + " Simon Bradley + " Contributors: Preben Randhol. +-" $Author: vimboss $ +-" $Date: 2007/05/05 18:22:26 $ +-" Version: 4.2 +-" $Revision: 1.2 $ +-" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/syntax/ada.vim $ ++" $Author: krischik $ ++" $Date: 2007-11-01 19:29:58 +0100 (Do, 01 Nov 2007) $ ++" Version: 4.5 ++" $Revision: 793 $ ++" $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/syntax/ada.vim $ + " http://www.dwheeler.com/vim + " History: 24.05.2006 MK Unified Headers + " 26.05.2006 MK ' should not be in iskeyword. +@@ -98,7 +98,8 @@ + " + if exists("g:ada_rainbow_color") + syntax match adaSpecial "[:;.,]" +- runtime plugin/Rainbow_Parenthsis.vim ++ call rainbow_parenthsis#LoadRound () ++ call rainbow_parenthsis#Activate () + else + syntax match adaSpecial "[:;().,]" + endif +@@ -159,7 +160,7 @@ + " Section: end {{{1 + " Unless special ("end loop", "end if", etc.), "end" marks the end of a + " begin, package, task etc. Assiging it to adaEnd. +-syntax match adaEnd "\" ++syntax match adaEnd /\/ + + syntax keyword adaPreproc pragma + +diff -urN vim71/runtime/syntax/bush.vim vim71_ada/runtime/syntax/bush.vim +--- vim71/runtime/syntax/bush.vim 1970-01-01 01:00:00.000000000 +0100 ++++ vim71_ada/runtime/syntax/bush.vim 2008-01-16 16:37:03.000000000 +0100 +@@ -0,0 +1,309 @@ ++" Vim syntax file ++" Language: BUSH / AdaScript ++" Maintainer: Ken O. Burtch ++" URL: http://www.pegasoft.ca/bush ++" Last Change: 2004-06-29 ++ ++" Former Maintainer: Simon Bradley ++" (was ) ++" Other contributors: Preben Randhol. ++" The formal spec of Ada95 (ARM) is the "Ada95 Reference Manual". ++" For more Ada95 info, see http://www.gnuada.org and http://www.adapower.com. ++ ++" This vim syntax file works on vim 5.6, 5.7, 5.8 and 6.x. ++" It implements Bram Moolenaar's April 25, 2001 recommendations to make ++" the syntax file maximally portable across different versions of vim. ++" If vim 6.0+ is available, ++" this syntax file takes advantage of the vim 6.0 advanced pattern-matching ++" functions to avoid highlighting uninteresting leading spaces in ++" some expressions containing "with" and "use". ++ ++" For version 5.x: Clear all syntax items ++" For version 6.x: Quit when a syntax file was already loaded ++if version < 600 ++ syntax clear ++elseif exists("b:current_syntax") ++ finish ++endif ++ ++" Ada is entirely case-insensitive. ++syn case ignore ++ ++" We don't need to look backwards to highlight correctly; ++" this speeds things up greatly. ++syn sync minlines=1 maxlines=1 ++ ++" Highlighting commands. There are 69 reserved words in total in Ada95. ++" Some keywords are used in more than one way. For example: ++" 1. "end" is a general keyword, but "end if" ends a Conditional. ++" 2. "then" is a conditional, but "and then" is an operator. ++ ++ ++" Standard Exceptions (including I/O). ++" We'll highlight the standard exceptions, similar to vim's Python mode. ++" It's possible to redefine the standard exceptions as something else, ++" but doing so is very bad practice, so simply highlighting them makes sense. ++syn keyword adaException Constraint_Error Program_Error Storage_Error ++syn keyword adaException Tasking_Error ++syn keyword adaException Status_Error Mode_Error Name_Error Use_Error ++syn keyword adaException Device_Error End_Error Data_Error Layout_Error ++syn keyword adaException Length_Error Pattern_Error Index_Error ++syn keyword adaException Translation_Error ++syn keyword adaException Time_Error Argument_Error ++syn keyword adaException Tag_Error ++syn keyword adaException Picture_Error ++" Interfaces ++syn keyword adaException Terminator_Error Conversion_Error ++syn keyword adaException Pointer_Error Dereference_Error Update_Error ++" This isn't in the Ada spec, but a GNAT extension. ++syn keyword adaException Assert_Failure ++" We don't list ALL exceptions defined in particular compilers (e.g., GNAT), ++" because it's quite reasonable to define those phrases as non-exceptions. ++ ++ ++" We don't normally highlight types in package Standard ++" (Integer, Character, Float, etc.). I don't think it looks good ++" with the other type keywords, and many Ada programs define ++" so many of their own types that it looks inconsistent. ++" However, if you want this highlighting, turn on "ada_standard_types". ++" For package Standard's definition, see ARM section A.1. ++ ++if exists("ada_standard_types") ++ syn keyword adaBuiltinType Boolean Integer Natural Positive Float ++ syn keyword adaBuiltinType Character Wide_Character ++ syn keyword adaBuiltinType String Wide_String ++ syn keyword adaBuiltinType Duration ++ " These aren't listed in ARM section A.1's code, but they're noted as ++ " options in ARM sections 3.5.4 and 3.5.7: ++ syn keyword adaBuiltinType Short_Integer Short_Short_Integer ++ syn keyword adaBuiltinType Long_Integer Long_Long_Integer ++ syn keyword adaBuiltinType Short_Float Short_Short_Float ++ syn keyword adaBuiltinType Long_Float Long_Long_Float ++ " BUSH-specific types ++ syn keyword adaBuiltinType command ++ syn keyword adaBuiltinType socket_type ++ syn keyword adaBuiltinType unbounded_string ++ syn keyword adaBuiltinType universal_typeless ++ syn keyword adaBuiltinType universal_string ++ syn keyword adaBuiltinType universal_numeric ++endif ++ ++" There are MANY other predefined types; they've not been added, because ++" determining when they're a type requires context in general. ++" One potential addition would be Unbounded_String. ++ ++ ++syn keyword adaLabel others ++ ++syn keyword adaOperator abs mod not rem xor ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "\" ++syn match adaOperator "[-+*/<>&]" ++syn keyword adaOperator ** ++syn match adaOperator "[/<>]=" ++syn keyword adaOperator => ++syn match adaOperator "\.\." ++syn match adaOperator "=" ++ ++" We won't map "adaAssignment" by default, but we need to map ":=" to ++" something or the "=" inside it will be mislabelled as an operator. ++" Note that in Ada, assignment (:=) is not considered an operator. ++syn match adaAssignment ":=" ++ ++" Handle the box, <>, specially: ++syn keyword adaSpecial <> ++ ++" Numbers, including floating point, exponents, and alternate bases. ++syn match adaNumber "\<\d[0-9_]*\(\.\d[0-9_]*\)\=\([Ee][+-]\=\d[0-9_]*\)\=\>" ++syn match adaNumber "\<\d\d\=#\x[0-9A-Fa-f_]*\(\.\x[0-9A-Fa-f_]*\)\=#\([Ee][+-]\=\d[0-9_]*\)\=" ++ ++" Identify leading numeric signs. In "A-5" the "-" is an operator, ++" but in "A:=-5" the "-" is a sign. This handles "A3+-5" (etc.) correctly. ++" This assumes that if you put a don't put a space after +/- when it's used ++" as an operator, you won't put a space before it either -- which is true ++" in code I've seen. ++syn match adaSign "[[:space:]<>=(,|:;&*/+-][+-]\d"lc=1,hs=s+1,he=e-1,me=e-1 ++ ++" Labels for the goto statement. ++syn region adaLabel start="<<" end=">>" ++ ++" Boolean Constants. ++syn keyword adaBoolean true false ++ ++" Warn people who try to use C/C++ notation erroneously: ++syn match adaError "//" ++syn match adaError "/\*" ++syn match adaError "==" ++ ++ ++if exists("ada_space_errors") ++ if !exists("ada_no_trail_space_error") ++ syn match adaSpaceError excludenl "\s\+$" ++ endif ++ if !exists("ada_no_tab_space_error") ++ syn match adaSpaceError " \+\t"me=e-1 ++ endif ++endif ++ ++" Unless special ("end loop", "end if", etc.), "end" marks the end of a ++" begin, package, task etc. Assiging it to adaEnd. ++syn match adaEnd "\" ++ ++syn keyword adaPreproc pragma ++ ++syn keyword adaRepeat exit for loop reverse while ++syn match adaRepeat "\" ++ ++syn keyword adaStatement accept delay goto raise requeue return ++syn keyword adaStatement terminate ++" BUSH-specific statements ++syn keyword adaStatement cd ++syn keyword adaStatement clear ++syn keyword adaStatement env ++syn keyword adaStatement inkey ++syn keyword adaStatement jobs ++syn keyword adaStatement logout ++syn keyword adaStatement pwd ++syn keyword adaStatement step ++syn keyword adaStatement trace ++syn keyword adaStatement typeset ++syn keyword adaStatement unset ++syn keyword adaStatement wait ++syn keyword adaStatement history ++syn keyword adaStatement "?" ++syn match adaStatement "\" ++ ++" Handle Ada's record keywords. ++" 'record' usually starts a structure, but "with null record;" does not, ++" and 'end record;' ends a structure. The ordering here is critical - ++" 'record;' matches a "with null record", so make it a keyword (this can ++" match when the 'with' or 'null' is on a previous line). ++" We see the "end" in "end record" before the word record, so we match that ++" pattern as adaStructure (and it won't match the "record;" pattern). ++syn match adaStructure "\" ++syn match adaStructure "\" ++syn match adaKeyword "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn match adaConditional "\" ++syn keyword adaConditional if case select ++syn keyword adaConditional elsif when ++ ++syn keyword adaKeyword all do exception in is new null out ++syn keyword adaKeyword separate until ++ ++" These keywords begin various constructs, and you _might_ want to ++" highlight them differently. ++syn keyword adaBegin begin body declare entry function generic ++syn keyword adaBegin package procedure protected renames task ++ ++ ++if exists("ada_withuse_ordinary") ++" Don't be fancy. Display "with" and "use" as ordinary keywords in all cases. ++ syn keyword adaKeyword with use ++else ++ " Highlight "with" and "use" clauses like C's "#include" when they're used ++ " to reference other compilation units; otherwise they're ordinary keywords. ++ " If we have vim 6.0 or later, we'll use its advanced pattern-matching ++ " capabilities so that we won't match leading spaces. ++ syn match adaKeyword "\" ++ syn match adaKeyword "\" ++ if version < 600 ++ syn match adaBeginWith "^\s*\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syn match adaSemiWith ";\s*\(\(with\(\s\+type\)\=\)\|\(use\)\)\>"lc=1 contains=adaInc ++ else ++ syn match adaBeginWith "^\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ syn match adaSemiWith ";\s*\zs\(\(with\(\s\+type\)\=\)\|\(use\)\)\>" contains=adaInc ++ endif ++ syn match adaInc "\" contained contains=NONE ++ syn match adaInc "\" contained contains=NONE ++ syn match adaInc "\" contained contains=NONE ++ " Recognize "with null record" as a keyword (even the "record"). ++ syn match adaKeyword "\" ++ " Consider generic formal parameters of subprograms and packages as keywords. ++ if version < 600 ++ syn match adaKeyword ";\s*with\s\+\(function\|procedure\|package\)\>" ++ syn match adaKeyword "^\s*with\s\+\(function\|procedure\|package\)\>" ++ else ++ syn match adaKeyword ";\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ syn match adaKeyword "^\s*\zswith\s\+\(function\|procedure\|package\)\>" ++ endif ++endif ++ ++ ++" String and character constants. ++syn region adaString start=+"+ skip=+""+ end=+"+ ++syn match adaCharacter "'.'" ++ ++" Todo (only highlighted in comments) ++syn keyword adaTodo contained TODO FIXME XXX ++ ++" Comments. ++syn region adaComment oneline contains=adaTodo start="--" end="$" ++ ++ ++ ++" Define the default highlighting. ++" For version 5.7 and earlier: only when not done already ++" For version 5.8 and later: only when an item doesn't have highlighting yet ++if version >= 508 || !exists("did_ada_syn_inits") ++ if version < 508 ++ let did_ada_syn_inits = 1 ++ command -nargs=+ HiLink hi link ++ else ++ command -nargs=+ HiLink hi def link ++ endif ++ ++ " The default methods for highlighting. Can be overridden later. ++ HiLink adaCharacter Character ++ HiLink adaComment Comment ++ HiLink adaConditional Conditional ++ HiLink adaKeyword Keyword ++ HiLink adaLabel Label ++ HiLink adaNumber Number ++ HiLink adaSign Number ++ HiLink adaOperator Operator ++ HiLink adaPreproc PreProc ++ HiLink adaRepeat Repeat ++ HiLink adaSpecial Special ++ HiLink adaStatement Statement ++ HiLink adaString String ++ HiLink adaStructure Structure ++ HiLink adaTodo Todo ++ HiLink adaType Type ++ HiLink adaTypedef Typedef ++ HiLink adaStorageClass StorageClass ++ HiLink adaBoolean Boolean ++ HiLink adaException Exception ++ HiLink adaInc Include ++ HiLink adaError Error ++ HiLink adaSpaceError Error ++ HiLink adaBuiltinType Type ++ ++ if exists("ada_begin_preproc") ++ " This is the old default display: ++ HiLink adaBegin PreProc ++ HiLink adaEnd PreProc ++ else ++ " This is the new default display: ++ HiLink adaBegin Keyword ++ HiLink adaEnd Keyword ++ endif ++ ++ delcommand HiLink ++endif ++ ++let b:current_syntax = "ada" ++ ++" vim: ts=8 diff --git a/vim.spec b/vim.spec index c7aee3c..d015a07 100644 --- a/vim.spec +++ b/vim.spec @@ -23,7 +23,7 @@ Summary: The VIM editor URL: http://www.vim.org/ Name: vim Version: %{baseversion}.%{beta}%{patchlevel} -Release: 1%{?dist} +Release: 2%{?dist} License: Vim Group: Applications/Editors Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}%{?beta}%{?CVSDATE}.tar.bz2 @@ -295,6 +295,8 @@ Patch3009: vim-7.0-warning.patch Patch3010: vim-7.0-syncolor.patch Patch3011: vim-7.0-vimspelltypo.patch Patch3012: vim-7.0-specedit.patch +# Remove this one when the runtime files get updated (#246378): +Patch3013: vim-7.1-ada.patch # Patch3100: vim-selinux.patch Patch3101: vim-selinux2.patch @@ -664,6 +666,7 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk %patch3010 -p1 %patch3011 -p1 %patch3012 -p1 +%patch3013 -p1 %if %{WITH_SELINUX} %patch3100 -p1 @@ -1031,6 +1034,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/icons/hicolor/*/apps/* %changelog +* Wed Jan 16 2008 Karsten Hopp 7.1.230-2 +- add newer ada runtime files to fix bugzilla #246378 + * Wed Jan 16 2008 Karsten Hopp 7.1.230-1 - patchlevel 230, fixes memory leak