To: vim_dev@googlegroups.com Subject: Patch 8.0.1281 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1281 Problem: Loading file type detection slows down startup. Solution: Move functions to an autoload script. Files: runtime/filetype.vim, runtime/autoload/filetype.vim, runtime/scripts.vim *** ../vim-8.0.1280/runtime/filetype.vim 2017-08-11 20:50:00.722908598 +0200 --- runtime/filetype.vim 2017-11-09 20:35:00.182149228 +0100 *************** *** 1,7 **** " Vim support file to detect file types " " Maintainer: Bram Moolenaar ! " Last Change: 2017 Aug 11 " Listen very carefully, I will say this only once if exists("did_load_filetypes") --- 1,7 ---- " Vim support file to detect file types " " Maintainer: Bram Moolenaar ! " Last Change: 2017 Nov 09 " Listen very carefully, I will say this only once if exists("did_load_filetypes") *************** *** 52,78 **** au BufNewFile,BufRead $VIMRUNTIME/doc/*.txt setf help " Abaqus or Trasys ! au BufNewFile,BufRead *.inp call s:Check_inp() ! ! func! s:Check_inp() ! if getline(1) =~ '^\*' ! setf abaqus ! else ! let n = 1 ! if line("$") > 500 ! let nmax = 500 ! else ! let nmax = line("$") ! endif ! while n <= nmax ! if getline(n) =~? "^header surface data" ! setf trasys ! break ! endif ! let n = n + 1 ! endwhile ! endif ! endfunc " A-A-P recipe au BufNewFile,BufRead *.aap setf aap --- 52,58 ---- au BufNewFile,BufRead $VIMRUNTIME/doc/*.txt setf help " Abaqus or Trasys ! au BufNewFile,BufRead *.inp call filetype#Check_inp() " A-A-P recipe au BufNewFile,BufRead *.aap setf aap *************** *** 174,217 **** " Assembly (all kinds) " *.lst is not pure assembly, it has two extra columns (address, byte codes) ! au BufNewFile,BufRead *.asm,*.[sS],*.[aA],*.mac,*.lst call s:FTasm() ! ! " This function checks for the kind of assembly that is wanted by the user, or ! " can be detected from the first five lines of the file. ! func! s:FTasm() ! " make sure b:asmsyntax exists ! if !exists("b:asmsyntax") ! let b:asmsyntax = "" ! endif ! ! if b:asmsyntax == "" ! call s:FTasmsyntax() ! endif ! ! " if b:asmsyntax still isn't set, default to asmsyntax or GNU ! if b:asmsyntax == "" ! if exists("g:asmsyntax") ! let b:asmsyntax = g:asmsyntax ! else ! let b:asmsyntax = "asm" ! endif ! endif ! ! exe "setf " . fnameescape(b:asmsyntax) ! endfunc ! ! func! s:FTasmsyntax() ! " see if file contains any asmsyntax=foo overrides. If so, change ! " b:asmsyntax appropriately ! let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4). ! \" ".getline(5)." " ! let match = matchstr(head, '\sasmsyntax=\zs[a-zA-Z0-9]\+\ze\s') ! if match != '' ! let b:asmsyntax = match ! elseif ((head =~? '\.title') || (head =~? '\.ident') || (head =~? '\.macro') || (head =~? '\.subtitle') || (head =~? '\.library')) ! let b:asmsyntax = "vmasm" ! endif ! endfunc " Macro (VAX) au BufNewFile,BufRead *.mar setf vmasm --- 154,160 ---- " Assembly (all kinds) " *.lst is not pure assembly, it has two extra columns (address, byte codes) ! au BufNewFile,BufRead *.asm,*.[sS],*.[aA],*.mac,*.lst call filetype#FTasm() " Macro (VAX) au BufNewFile,BufRead *.mar setf vmasm *************** *** 241,257 **** au BufNewFile,BufRead *.mch,*.ref,*.imp setf b " BASIC or Visual Basic ! au BufNewFile,BufRead *.bas call s:FTVB("basic") ! ! " Check if one of the first five lines contains "VB_Name". In that case it is ! " probably a Visual Basic file. Otherwise it's assumed to be "alt" filetype. ! func! s:FTVB(alt) ! if getline(1).getline(2).getline(3).getline(4).getline(5) =~? 'VB_Name\|Begin VB\.\(Form\|MDIForm\|UserControl\)' ! setf vb ! else ! exe "setf " . a:alt ! endif ! endfunc " Visual Basic Script (close to Visual Basic) or Visual Basic .NET au BufNewFile,BufRead *.vb,*.vbs,*.dsm,*.ctl setf vb --- 184,190 ---- au BufNewFile,BufRead *.mch,*.ref,*.imp setf b " BASIC or Visual Basic ! au BufNewFile,BufRead *.bas call filetype#FTVB("basic") " Visual Basic Script (close to Visual Basic) or Visual Basic .NET au BufNewFile,BufRead *.vb,*.vbs,*.dsm,*.ctl setf vb *************** *** 269,282 **** \ if getline(1) =~ '^/\*' | setf rexx | else | setf dosbatch | endif " Batch file for 4DOS ! au BufNewFile,BufRead *.btm call s:FTbtm() ! func! s:FTbtm() ! if exists("g:dosbatch_syntax_for_btm") && g:dosbatch_syntax_for_btm ! setf dosbatch ! else ! setf btm ! endif ! endfunc " BC calculator au BufNewFile,BufRead *.bc setf bc --- 202,208 ---- \ if getline(1) =~ '^/\*' | setf rexx | else | setf dosbatch | endif " Batch file for 4DOS ! au BufNewFile,BufRead *.btm call filetype#FTbtm() " BC calculator au BufNewFile,BufRead *.bc setf bc *************** *** 292,310 **** " BIND configuration " sudoedit uses namedXXXX.conf ! au BufNewFile,BufRead named*.conf,rndc*.conf setf named " BIND zone au BufNewFile,BufRead named.root setf bindzone ! au BufNewFile,BufRead *.db call s:BindzoneCheck('') ! ! func! s:BindzoneCheck(default) ! if getline(1).getline(2).getline(3).getline(4) =~ '^; <<>> DiG [0-9.]\+ <<>>\|BIND.*named\|$ORIGIN\|$TTL\|IN\s\+SOA' ! setf bindzone ! elseif a:default != '' ! exe 'setf ' . a:default ! endif ! endfunc " Blank au BufNewFile,BufRead *.bl setf blank --- 218,228 ---- " BIND configuration " sudoedit uses namedXXXX.conf ! au BufNewFile,BufRead named*.conf,rndc*.conf,rndc*.key setf named " BIND zone au BufNewFile,BufRead named.root setf bindzone ! au BufNewFile,BufRead *.db call filetype#BindzoneCheck('') " Blank au BufNewFile,BufRead *.bl setf blank *************** *** 320,340 **** endif " C or lpc ! au BufNewFile,BufRead *.c call s:FTlpc() ! ! func! s:FTlpc() ! if exists("g:lpc_syntax_for_c") ! let lnum = 1 ! while lnum <= 12 ! if getline(lnum) =~# '^\(//\|inherit\|private\|protected\|nosave\|string\|object\|mapping\|mixed\)' ! setf lpc ! return ! endif ! let lnum = lnum + 1 ! endwhile ! endif ! setf c ! endfunc " Calendar au BufNewFile,BufRead calendar setf calendar --- 238,244 ---- endif " C or lpc ! au BufNewFile,BufRead *.c call filetype#FTlpc() " Calendar au BufNewFile,BufRead calendar setf calendar *************** *** 388,410 **** " .h files can be C, Ch C++, ObjC or ObjC++. " Set c_syntax_for_h if you want C, ch_syntax_for_h if you want Ch. ObjC is " detected automatically. ! au BufNewFile,BufRead *.h call s:FTheader() ! ! func! s:FTheader() ! if match(getline(1, min([line("$"), 200])), '^@\(interface\|end\|class\)') > -1 ! if exists("g:c_syntax_for_h") ! setf objc ! else ! setf objcpp ! endif ! elseif exists("g:c_syntax_for_h") ! setf c ! elseif exists("g:ch_syntax_for_h") ! setf ch ! else ! setf cpp ! endif ! endfunc " Ch (CHscript) au BufNewFile,BufRead *.chf setf ch --- 292,298 ---- " .h files can be C, Ch C++, ObjC or ObjC++. " Set c_syntax_for_h if you want C, ch_syntax_for_h if you want Ch. ObjC is " detected automatically. ! au BufNewFile,BufRead *.h call filetype#FTheader() " Ch (CHscript) au BufNewFile,BufRead *.chf setf ch *************** *** 438,473 **** au BufNewFile,BufRead *..ch setf chill " Changes for WEB and CWEB or CHILL ! au BufNewFile,BufRead *.ch call s:FTchange() ! ! " This function checks if one of the first ten lines start with a '@'. In ! " that case it is probably a change file. ! " If the first line starts with # or ! it's probably a ch file. ! " If a line has "main", "include", "//" ir "/*" it's probably ch. ! " Otherwise CHILL is assumed. ! func! s:FTchange() ! let lnum = 1 ! while lnum <= 10 ! if getline(lnum)[0] == '@' ! setf change ! return ! endif ! if lnum == 1 && (getline(1)[0] == '#' || getline(1)[0] == '!') ! setf ch ! return ! endif ! if getline(lnum) =~ "MODULE" ! setf chill ! return ! endif ! if getline(lnum) =~ 'main\s*(\|#\s*include\|//' ! setf ch ! return ! endif ! let lnum = lnum + 1 ! endwhile ! setf chill ! endfunc " ChordPro au BufNewFile,BufRead *.chopro,*.crd,*.cho,*.crdpro,*.chordpro setf chordpro --- 326,332 ---- au BufNewFile,BufRead *..ch setf chill " Changes for WEB and CWEB or CHILL ! au BufNewFile,BufRead *.ch call filetype#FTchange() " ChordPro au BufNewFile,BufRead *.chopro,*.crd,*.cho,*.crdpro,*.chordpro setf chordpro *************** *** 479,505 **** au BufNewFile,BufRead *.eni setf cl " Clever or dtd ! au BufNewFile,BufRead *.ent call s:FTent() ! ! func! s:FTent() ! " This function checks for valid cl syntax in the first five lines. ! " Look for either an opening comment, '#', or a block start, '{". ! " If not found, assume SGML. ! let lnum = 1 ! while lnum < 6 ! let line = getline(lnum) ! if line =~ '^\s*[#{]' ! setf cl ! return ! elseif line !~ '^\s*$' ! " Not a blank line, not a comment, and not a block start, ! " so doesn't look like valid cl code. ! break ! endif ! let lnum = lnum + 1 ! endw ! setf dtd ! endfunc " Clipper (or FoxPro; could also be eviews) au BufNewFile,BufRead *.prg --- 338,344 ---- au BufNewFile,BufRead *.eni setf cl " Clever or dtd ! au BufNewFile,BufRead *.ent call filetype#FTent() " Clipper (or FoxPro; could also be eviews) au BufNewFile,BufRead *.prg *************** *** 554,572 **** au BufNewFile,BufRead *Eterm/*.cfg setf eterm " Euphoria 3 or 4 ! au BufNewFile,BufRead *.eu,*.ew,*.ex,*.exu,*.exw call s:EuphoriaCheck() if has("fname_case") ! au BufNewFile,BufRead *.EU,*.EW,*.EX,*.EXU,*.EXW call s:EuphoriaCheck() endif - func! s:EuphoriaCheck() - if exists('g:filetype_euphoria') - exe 'setf ' . g:filetype_euphoria - else - setf euphoria3 - endif - endfunc - " Lynx config files au BufNewFile,BufRead lynx.cfg setf lynx --- 393,403 ---- au BufNewFile,BufRead *Eterm/*.cfg setf eterm " Euphoria 3 or 4 ! au BufNewFile,BufRead *.eu,*.ew,*.ex,*.exu,*.exw call filetype#EuphoriaCheck() if has("fname_case") ! au BufNewFile,BufRead *.EU,*.EW,*.EX,*.EXU,*.EXW call filetype#EuphoriaCheck() endif " Lynx config files au BufNewFile,BufRead lynx.cfg setf lynx *************** *** 611,629 **** au BufNewFile,BufRead *.desc setf desc " the D language or dtrace ! au BufNewFile,BufRead *.d call s:DtraceCheck() ! ! func! s:DtraceCheck() ! let lines = getline(1, min([line("$"), 100])) ! if match(lines, '^module\>\|^import\>') > -1 ! " D files often start with a module and/or import statement. ! setf d ! elseif match(lines, '^#!\S\+dtrace\|#pragma\s\+D\s\+option\|:\S\{-}:\S\{-}:') > -1 ! setf dtrace ! else ! setf d ! endif ! endfunc " Desktop files au BufNewFile,BufRead *.desktop,.directory setf desktop --- 442,448 ---- au BufNewFile,BufRead *.desc setf desc " the D language or dtrace ! au BufNewFile,BufRead *.d call filetype#DtraceCheck() " Desktop files au BufNewFile,BufRead *.desktop,.directory setf desktop *************** *** 655,661 **** \ endif " DCL (Digital Command Language - vms) or DNS zone file ! au BufNewFile,BufRead *.com call s:BindzoneCheck('dcl') " DOT au BufNewFile,BufRead *.dot setf dot --- 474,480 ---- \ endif " DCL (Digital Command Language - vms) or DNS zone file ! au BufNewFile,BufRead *.com call filetype#BindzoneCheck('dcl') " DOT au BufNewFile,BufRead *.dot setf dot *************** *** 703,729 **** au BufNewFile,BufRead *.ecd setf ecd " Eiffel or Specman or Euphoria ! au BufNewFile,BufRead *.e,*.E call s:FTe() " Elinks configuration au BufNewFile,BufRead */etc/elinks.conf,*/.elinks/elinks.conf setf elinks - func! s:FTe() - if exists('g:filetype_euphoria') - exe 'setf ' . g:filetype_euphoria - else - let n = 1 - while n < 100 && n < line("$") - if getline(n) =~ "^\\s*\\(<'\\|'>\\)\\s*$" - setf specman - return - endif - let n = n + 1 - endwhile - setf eiffel - endif - endfunc - " ERicsson LANGuage; Yaws is erlang too au BufNewFile,BufRead *.erl,*.hrl,*.yaws setf erlang --- 522,532 ---- au BufNewFile,BufRead *.ecd setf ecd " Eiffel or Specman or Euphoria ! au BufNewFile,BufRead *.e,*.E call filetype#FTe() " Elinks configuration au BufNewFile,BufRead */etc/elinks.conf,*/.elinks/elinks.conf setf elinks " ERicsson LANGuage; Yaws is erlang too au BufNewFile,BufRead *.erl,*.hrl,*.yaws setf erlang *************** *** 892,915 **** au BufNewFile,BufRead *.t.html setf tilde " HTML (.shtml and .stm for server side) ! au BufNewFile,BufRead *.html,*.htm,*.shtml,*.stm call s:FThtml() ! ! " Distinguish between HTML, XHTML and Django ! func! s:FThtml() ! let n = 1 ! while n < 10 && n < line("$") ! if getline(n) =~ '\\|{#\s\+' ! setf htmldjango ! return ! endif ! let n = n + 1 ! endwhile ! setf html ! endfunc " HTML with Ruby - eRuby au BufNewFile,BufRead *.erb,*.rhtml setf eruby --- 695,701 ---- au BufNewFile,BufRead *.t.html setf tilde " HTML (.shtml and .stm for server side) ! au BufNewFile,BufRead *.html,*.htm,*.shtml,*.stm call filetype#FThtml() " HTML with Ruby - eRuby au BufNewFile,BufRead *.erb,*.rhtml setf eruby *************** *** 936,955 **** au BufNewFile,BufRead *.icn setf icon " IDL (Interface Description Language) ! au BufNewFile,BufRead *.idl call s:FTidl() ! ! " Distinguish between standard IDL and MS-IDL ! func! s:FTidl() ! let n = 1 ! while n < 50 && n < line("$") ! if getline(n) =~ '^\s*import\s\+"\(unknwn\|objidl\)\.idl"' ! setf msidl ! return ! endif ! let n = n + 1 ! endwhile ! setf idl ! endfunc " Microsoft IDL (Interface Description Language) Also *.idl " MOF = WMI (Windows Management Instrumentation) Managed Object Format --- 722,728 ---- au BufNewFile,BufRead *.icn setf icon " IDL (Interface Description Language) ! au BufNewFile,BufRead *.idl call filetype#FTidl() " Microsoft IDL (Interface Description Language) Also *.idl " MOF = WMI (Windows Management Instrumentation) Managed Object Format *************** *** 960,984 **** " Indent profile (must come before IDL *.pro!) au BufNewFile,BufRead .indent.pro setf indent ! au BufNewFile,BufRead indent.pro call s:ProtoCheck('indent') " IDL (Interactive Data Language) ! au BufNewFile,BufRead *.pro call s:ProtoCheck('idlang') ! ! " Distinguish between "default" and Cproto prototype file. */ ! func! s:ProtoCheck(default) ! " Cproto files have a comment in the first line and a function prototype in ! " the second line, it always ends in ";". Indent files may also have ! " comments, thus we can't match comments to see the difference. ! " IDL files can have a single ';' in the second line, require at least one ! " chacter before the ';'. ! if getline(2) =~ '.;$' ! setf cpp ! else ! exe 'setf ' . a:default ! endif ! endfunc ! " Indent RC au BufNewFile,BufRead indentrc setf indent --- 733,742 ---- " Indent profile (must come before IDL *.pro!) au BufNewFile,BufRead .indent.pro setf indent ! au BufNewFile,BufRead indent.pro call filetype#ProtoCheck('indent') " IDL (Interactive Data Language) ! au BufNewFile,BufRead *.pro call filetype#ProtoCheck('idlang') " Indent RC au BufNewFile,BufRead indentrc setf indent *************** *** 1155,1162 **** " MaGic Point au BufNewFile,BufRead *.mgp setf mgp ! " Mail (for Elm, trn, mutt, muttng, rn, slrn) ! au BufNewFile,BufRead snd.\d\+,.letter,.letter.\d\+,.followup,.article,.article.\d\+,pico.\d\+,mutt{ng,}-*-\w\+,mutt[[:alnum:]_-]\\\{6\},ae\d\+.txt,/tmp/SLRN[0-9A-Z.]\+,*.eml setf mail " Mail aliases au BufNewFile,BufRead */etc/mail/aliases,*/etc/aliases setf mailaliases --- 913,920 ---- " MaGic Point au BufNewFile,BufRead *.mgp setf mgp ! " Mail (for Elm, trn, mutt, muttng, rn, slrn, neomutt) ! au BufNewFile,BufRead snd.\d\+,.letter,.letter.\d\+,.followup,.article,.article.\d\+,pico.\d\+,mutt{ng,}-*-\w\+,mutt[[:alnum:]_-]\\\{6\},neomutt-*-\w\+,neomutt[[:alnum:]_-]\\\{6\},ae\d\+.txt,/tmp/SLRN[0-9A-Z.]\+,*.eml setf mail " Mail aliases au BufNewFile,BufRead */etc/mail/aliases,*/etc/aliases setf mailaliases *************** *** 1192,1242 **** au BufNewFile,BufRead *.mason,*.mhtml,*.comp setf mason " Mathematica, Matlab, Murphi or Objective C ! au BufNewFile,BufRead *.m call s:FTm() ! ! func! s:FTm() ! let n = 1 ! let saw_comment = 0 " Whether we've seen a multiline comment leader. ! while n < 100 ! let line = getline(n) ! if line =~ '^\s*/\*' ! " /* ... */ is a comment in Objective C and Murphi, so we can't conclude ! " it's either of them yet, but track this as a hint in case we don't see ! " anything more definitive. ! let saw_comment = 1 ! endif ! if line =~ '^\s*\(#\s*\(include\|import\)\>\|@import\>\|//\)' ! setf objc ! return ! endif ! if line =~ '^\s*%' ! setf matlab ! return ! endif ! if line =~ '^\s*(\*' ! setf mma ! return ! endif ! if line =~ '^\c\s*\(\(type\|var\)\>\|--\)' ! setf murphi ! return ! endif ! let n = n + 1 ! endwhile ! ! if saw_comment ! " We didn't see anything definitive, but this looks like either Objective C ! " or Murphi based on the comment leader. Assume the former as it is more ! " common. ! setf objc ! elseif exists("g:filetype_m") ! " Use user specified default filetype for .m ! exe "setf " . g:filetype_m ! else ! " Default is matlab ! setf matlab ! endif ! endfunc " Mathematica notebook au BufNewFile,BufRead *.nb setf mma --- 950,956 ---- au BufNewFile,BufRead *.mason,*.mhtml,*.comp setf mason " Mathematica, Matlab, Murphi or Objective C ! au BufNewFile,BufRead *.m call filetype#FTm() " Mathematica notebook au BufNewFile,BufRead *.nb setf mma *************** *** 1266,1294 **** au BufNewFile,BufRead *.mix,*.mixal setf mix " MMIX or VMS makefile ! au BufNewFile,BufRead *.mms call s:FTmms() " Symbian meta-makefile definition (MMP) au BufNewFile,BufRead *.mmp setf mmp - func! s:FTmms() - let n = 1 - while n < 10 - let line = getline(n) - if line =~ '^\s*\(%\|//\)' || line =~ '^\*' - setf mmix - return - endif - if line =~ '^\s*#' - setf make - return - endif - let n = n + 1 - endwhile - setf mmix - endfunc - - " Modsim III (or LambdaProlog) au BufNewFile,BufRead *.mod \ if getline(1) =~ '\' | --- 980,990 ---- au BufNewFile,BufRead *.mix,*.mixal setf mix " MMIX or VMS makefile ! au BufNewFile,BufRead *.mms call filetype#FTmms() " Symbian meta-makefile definition (MMP) au BufNewFile,BufRead *.mmp setf mmp " Modsim III (or LambdaProlog) au BufNewFile,BufRead *.mod \ if getline(1) =~ '\' | *************** *** 1354,1359 **** --- 1050,1058 ---- " Natural au BufNewFile,BufRead *.NS[ACGLMNPS] setf natural + " Noemutt setup file + au BufNewFile,BufRead Neomuttrc setf neomuttrc + " Netrc au BufNewFile,BufRead .netrc setf netrc *************** *** 1369,1401 **** \ setf nroff | \ endif au BufNewFile,BufRead *.tr,*.nr,*.roff,*.tmac,*.mom setf nroff ! au BufNewFile,BufRead *.[1-9] call s:FTnroff() ! ! " This function checks if one of the first five lines start with a dot. In ! " that case it is probably an nroff file: 'filetype' is set and 1 is returned. ! func! s:FTnroff() ! if getline(1)[0] . getline(2)[0] . getline(3)[0] . getline(4)[0] . getline(5)[0] =~ '\.' ! setf nroff ! return 1 ! endif ! return 0 ! endfunc " Nroff or Objective C++ ! au BufNewFile,BufRead *.mm call s:FTmm() ! ! func! s:FTmm() ! let n = 1 ! while n < 10 ! let line = getline(n) ! if line =~ '^\s*\(#\s*\(include\|import\)\>\|@import\>\|/\*\)' ! setf objcpp ! return ! endif ! let n = n + 1 ! endwhile ! setf nroff ! endfunc " Not Quite C au BufNewFile,BufRead *.nqc setf nqc --- 1068,1077 ---- \ setf nroff | \ endif au BufNewFile,BufRead *.tr,*.nr,*.roff,*.tmac,*.mom setf nroff ! au BufNewFile,BufRead *.[1-9] call filetype#FTnroff() " Nroff or Objective C++ ! au BufNewFile,BufRead *.mm call filetype#FTmm() " Not Quite C au BufNewFile,BufRead *.nqc setf nqc *************** *** 1445,1474 **** " PDF au BufNewFile,BufRead *.pdf setf pdf " Perl if has("fname_case") ! au BufNewFile,BufRead *.pl,*.PL call s:FTpl() else ! au BufNewFile,BufRead *.pl call s:FTpl() endif au BufNewFile,BufRead *.plx,*.al,*.psgi setf perl au BufNewFile,BufRead *.p6,*.pm6,*.pl6 setf perl6 - func! s:FTpl() - if exists("g:filetype_pl") - exe "setf " . g:filetype_pl - else - " recognize Prolog by specific text in the first non-empty line - " require a blank after the '%' because Perl uses "%list" and "%translate" - let l = getline(nextnonblank(1)) - if l =~ '\' || l =~ '^\s*\(%\+\(\s\|$\)\|/\*\)' || l =~ ':-' - setf prolog - else - setf perl - endif - endif - endfunc - " Perl, XPM or XPM2 au BufNewFile,BufRead *.pm \ if getline(1) =~ "XPM2" | --- 1121,1138 ---- " PDF au BufNewFile,BufRead *.pdf setf pdf + " PCMK - HAE - crm configure edit + au BufNewFile,BufRead *.pcmk setf pcmk + " Perl if has("fname_case") ! au BufNewFile,BufRead *.pl,*.PL call filetype#FTpl() else ! au BufNewFile,BufRead *.pl call filetype#FTpl() endif au BufNewFile,BufRead *.plx,*.al,*.psgi setf perl au BufNewFile,BufRead *.p6,*.pm6,*.pl6 setf perl6 " Perl, XPM or XPM2 au BufNewFile,BufRead *.pm \ if getline(1) =~ "XPM2" | *************** *** 1531,1559 **** au BufNewFile,BufRead .povrayrc setf povini " Povray, PHP or assembly ! au BufNewFile,BufRead *.inc call s:FTinc() ! ! func! s:FTinc() ! if exists("g:filetype_inc") ! exe "setf " . g:filetype_inc ! else ! let lines = getline(1).getline(2).getline(3) ! if lines =~? "perlscript" ! setf aspperl ! elseif lines =~ "<%" ! setf aspvbs ! elseif lines =~ "' ! \ || line =~ '^\s*{' || line =~ '^\s*(\*' ! setf pascal ! return ! elseif line !~ '^\s*$' || line =~ '^/\*' ! " Not an empty line: Doesn't look like valid Pascal code. ! " Or it looks like a Progress /* comment ! break ! endif ! let lnum = lnum + 1 ! endw ! setf progress ! endfunc ! " Software Distributor Product Specification File (POSIX 1387.2-1995) au BufNewFile,BufRead *.psf setf psf --- 1224,1236 ---- au BufNewFile,BufRead .procmail,.procmailrc setf procmail " Progress or CWEB ! au BufNewFile,BufRead *.w call filetype#FTprogress_cweb() " Progress or assembly ! au BufNewFile,BufRead *.i call filetype#FTprogress_asm() " Progress or Pascal ! au BufNewFile,BufRead *.p call filetype#FTprogress_pascal() " Software Distributor Product Specification File (POSIX 1387.2-1995) au BufNewFile,BufRead *.psf setf psf *************** *** 1735,1774 **** endif " Rexx, Rebol or R ! au BufNewFile,BufRead *.r,*.R call s:FTr() ! ! func! s:FTr() ! let max = line("$") > 50 ? 50 : line("$") ! ! for n in range(1, max) ! " Rebol is easy to recognize, check for that first ! if getline(n) =~? '\' ! setf rebol ! return ! endif ! endfor ! ! for n in range(1, max) ! " R has # comments ! if getline(n) =~ '^\s*#' ! setf r ! return ! endif ! " Rexx has /* comments */ ! if getline(n) =~ '^\s*/\*' ! setf rexx ! return ! endif ! endfor ! ! " Nothing recognized, use user default or assume Rexx ! if exists("g:filetype_r") ! exe "setf " . g:filetype_r ! else ! " Rexx used to be the default, but R appears to be much more popular. ! setf r ! endif ! endfunc " Remind au BufNewFile,BufRead .reminders,*.remind,*.rem setf remind --- 1316,1322 ---- endif " Rexx, Rebol or R ! au BufNewFile,BufRead *.r,*.R call filetype#FTr() " Remind au BufNewFile,BufRead .reminders,*.remind,*.rem setf remind *************** *** 1864,1886 **** au BufNewFile,BufRead sendmail.cf setf sm " Sendmail .mc files are actually m4. Could also be MS Message text file. ! au BufNewFile,BufRead *.mc call s:McSetf() ! ! func! s:McSetf() ! " Rely on the file to start with a comment. ! " MS message text files use ';', Sendmail files use '#' or 'dnl' ! for lnum in range(1, min([line("$"), 20])) ! let line = getline(lnum) ! if line =~ '^\s*\(#\|dnl\)' ! setf m4 " Sendmail .mc file ! return ! elseif line =~ '^\s*;' ! setf msmessages " MS Message text file ! return ! endif ! endfor ! setf m4 " Default: Sendmail .mc file ! endfunc " Services au BufNewFile,BufRead */etc/services setf services --- 1412,1418 ---- au BufNewFile,BufRead sendmail.cf setf sm " Sendmail .mc files are actually m4. Could also be MS Message text file. ! au BufNewFile,BufRead *.mc call filetype#McSetf() " Services au BufNewFile,BufRead */etc/services setf services *************** *** 1921,2021 **** " Shell scripts (sh, ksh, bash, bash2, csh); Allow .profile_foo etc. " Gentoo ebuilds and Arch Linux PKGBUILDs are actually bash scripts ! au BufNewFile,BufRead .bashrc*,bashrc,bash.bashrc,.bash[_-]profile*,.bash[_-]logout*,.bash[_-]aliases*,*.bash,*/{,.}bash[_-]completion{,.d,.sh}{,/*},*.ebuild,*.eclass,PKGBUILD* call SetFileTypeSH("bash") ! au BufNewFile,BufRead .kshrc*,*.ksh call SetFileTypeSH("ksh") ! au BufNewFile,BufRead */etc/profile,.profile*,*.sh,*.env call SetFileTypeSH(getline(1)) " Shell script (Arch Linux) or PHP file (Drupal) au BufNewFile,BufRead *.install \ if getline(1) =~ '") =~ g:ft_ignore_pat - return - endif - if a:name =~ '\' - " Some .sh scripts contain #!/bin/csh. - call SetFileTypeShell("csh") - return - elseif a:name =~ '\' - " Some .sh scripts contain #!/bin/tcsh. - call SetFileTypeShell("tcsh") - return - elseif a:name =~ '\' - " Some .sh scripts contain #!/bin/zsh. - call SetFileTypeShell("zsh") - return - elseif a:name =~ '\' - let b:is_kornshell = 1 - if exists("b:is_bash") - unlet b:is_bash - endif - if exists("b:is_sh") - unlet b:is_sh - endif - elseif exists("g:bash_is_sh") || a:name =~ '\' || a:name =~ '\' - let b:is_bash = 1 - if exists("b:is_kornshell") - unlet b:is_kornshell - endif - if exists("b:is_sh") - unlet b:is_sh - endif - elseif a:name =~ '\' - let b:is_sh = 1 - if exists("b:is_kornshell") - unlet b:is_kornshell - endif - if exists("b:is_bash") - unlet b:is_bash - endif - endif - call SetFileTypeShell("sh") - endfunc - - " For shell-like file types, check for an "exec" command hidden in a comment, - " as used for Tcl. - " Also called from scripts.vim, thus can't be local to this script. - func! SetFileTypeShell(name) - if expand("") =~ g:ft_ignore_pat - return - endif - let l = 2 - while l < 20 && l < line("$") && getline(l) =~ '^\s*\(#\|$\)' - " Skip empty and comment lines. - let l = l + 1 - endwhile - if l < line("$") && getline(l) =~ '\s*exec\s' && getline(l - 1) =~ '^\s*#.*\\$' - " Found an "exec" line after a comment with continuation - let n = substitute(getline(l),'\s*exec\s\+\([^ ]*/\)\=', '', '') - if n =~ '\:p') - if path =~ '^/\(etc/udev/\%(rules\.d/\)\=.*\.rules\|lib/udev/\%(rules\.d/\)\=.*\.rules\)$' - setf udevrules - return - endif - if path =~ '^/etc/ufw/' - setf conf " Better than hog - return - endif - if path =~ '^/\(etc\|usr/share\)/polkit-1/rules\.d' - setf javascript - return - endif - try - let config_lines = readfile('/etc/udev/udev.conf') - catch /^Vim\%((\a\+)\)\=:E484/ - setf hog - return - endtry - let dir = expand(':p:h') - for line in config_lines - if line =~ s:ft_rules_udev_rules_pattern - let udev_rules = substitute(line, s:ft_rules_udev_rules_pattern, '\1', "") - if dir == udev_rules - setf udevrules - endif - break - endif - endfor - setf hog - endfunc - - " Spec (Linux RPM) au BufNewFile,BufRead *.spec setf spec --- 1540,1548 ---- " Snort Configuration au BufNewFile,BufRead *.hog,snort.conf,vision.conf setf hog ! au BufNewFile,BufRead *.rules call filetype#FTRules() let s:ft_rules_udev_rules_pattern = '^\s*\cudev_rules\s*=\s*"\([^"]\{-1,}\)/*".*' " Spec (Linux RPM) au BufNewFile,BufRead *.spec setf spec *************** *** 2145,2159 **** au BufNewFile,BufRead *.tyb,*.typ,*.tyc,*.pkb,*.pks setf sql " SQL ! au BufNewFile,BufRead *.sql call s:SQL() ! ! func! s:SQL() ! if exists("g:filetype_sql") ! exe "setf " . g:filetype_sql ! else ! setf sql ! endif ! endfunc " SQLJ au BufNewFile,BufRead *.sqlj setf sqlj --- 1565,1571 ---- au BufNewFile,BufRead *.tyb,*.typ,*.tyc,*.pkb,*.pks setf sql " SQL ! au BufNewFile,BufRead *.sql call filetype#SQL() " SQLJ au BufNewFile,BufRead *.sqlj setf sqlj *************** *** 2200,2231 **** " SVG (Scalable Vector Graphics) au BufNewFile,BufRead *.svg setf svg - " If the file has an extension of 't' and is in a directory 't' or 'xt' then - " it is almost certainly a Perl test file. - " If the first line starts with '#' and contains 'perl' it's probably a Perl - " file. - " (Slow test) If a file contains a 'use' statement then it is almost certainly - " a Perl file. - func! s:FTperl() - let dirname = expand("%:p:h:t") - if expand("%:e") == 't' && (dirname == 't' || dirname == 'xt') - setf perl - return 1 - endif - if getline(1)[0] == '#' && getline(1) =~ 'perl' - setf perl - return 1 - endif - if search('^use\s\s*\k', 'nc', 30) - setf perl - return 1 - endif - return 0 - endfunc - " Tads (or Nroff or Perl test file) au BufNewFile,BufRead *.t ! \ if !s:FTnroff() && !s:FTperl() | setf tads | endif " Tags au BufNewFile,BufRead tags setf tags --- 1612,1620 ---- " SVG (Scalable Vector Graphics) au BufNewFile,BufRead *.svg setf svg " Tads (or Nroff or Perl test file) au BufNewFile,BufRead *.t ! \ if !filetype#FTnroff() && !filetype#FTperl() | setf tads | endif " Tags au BufNewFile,BufRead tags setf tags *************** *** 2254,2316 **** " TeX au BufNewFile,BufRead *.latex,*.sty,*.dtx,*.ltx,*.bbl setf tex ! au BufNewFile,BufRead *.tex call s:FTtex() ! ! " Choose context, plaintex, or tex (LaTeX) based on these rules: ! " 1. Check the first line of the file for "%&". ! " 2. Check the first 1000 non-comment lines for LaTeX or ConTeXt keywords. ! " 3. Default to "latex" or to g:tex_flavor, can be set in user's vimrc. ! func! s:FTtex() ! let firstline = getline(1) ! if firstline =~ '^%&\s*\a\+' ! let format = tolower(matchstr(firstline, '\a\+')) ! let format = substitute(format, 'pdf', '', '') ! if format == 'tex' ! let format = 'latex' ! elseif format == 'plaintex' ! let format = 'plain' ! endif ! elseif expand('%') =~ 'tex/context/.*/.*.tex' ! let format = 'context' ! else ! " Default value, may be changed later: ! let format = exists("g:tex_flavor") ? g:tex_flavor : 'plain' ! " Save position, go to the top of the file, find first non-comment line. ! let save_cursor = getpos('.') ! call cursor(1,1) ! let firstNC = search('^\s*[^[:space:]%]', 'c', 1000) ! if firstNC " Check the next thousand lines for a LaTeX or ConTeXt keyword. ! let lpat = 'documentclass\>\|usepackage\>\|begin{\|newcommand\>\|renewcommand\>' ! let cpat = 'start\a\+\|setup\a\+\|usemodule\|enablemode\|enableregime\|setvariables\|useencoding\|usesymbols\|stelle\a\+\|verwende\a\+\|stel\a\+\|gebruik\a\+\|usa\a\+\|imposta\a\+\|regle\a\+\|utilisemodule\>' ! let kwline = search('^\s*\\\%(' . lpat . '\)\|^\s*\\\(' . cpat . '\)', ! \ 'cnp', firstNC + 1000) ! if kwline == 1 " lpat matched ! let format = 'latex' ! elseif kwline == 2 " cpat matched ! let format = 'context' ! endif " If neither matched, keep default set above. ! " let lline = search('^\s*\\\%(' . lpat . '\)', 'cn', firstNC + 1000) ! " let cline = search('^\s*\\\%(' . cpat . '\)', 'cn', firstNC + 1000) ! " if cline > 0 ! " let format = 'context' ! " endif ! " if lline > 0 && (cline == 0 || cline > lline) ! " let format = 'tex' ! " endif ! endif " firstNC ! call setpos('.', save_cursor) ! endif " firstline =~ '^%&\s*\a\+' ! ! " Translation from formats to file types. TODO: add AMSTeX, RevTex, others? ! if format == 'plain' ! setf plaintex ! elseif format == 'context' ! setf context ! else " probably LaTeX ! setf tex ! endif ! return ! endfunc " ConTeXt au BufNewFile,BufRead *.mkii,*.mkiv,*.mkvi setf context --- 1643,1649 ---- " TeX au BufNewFile,BufRead *.latex,*.sty,*.dtx,*.ltx,*.bbl setf tex ! au BufNewFile,BufRead *.tex call filetype#FTtex() " ConTeXt au BufNewFile,BufRead *.mkii,*.mkiv,*.mkvi setf context *************** *** 2408,2414 **** \ endif " Visual Basic (also uses *.bas) or FORM ! au BufNewFile,BufRead *.frm call s:FTVB("form") " SaxBasic is close to Visual Basic au BufNewFile,BufRead *.sba setf vb --- 1741,1747 ---- \ endif " Visual Basic (also uses *.bas) or FORM ! au BufNewFile,BufRead *.frm call filetype#FTVB("form") " SaxBasic is close to Visual Basic au BufNewFile,BufRead *.sba setf vb *************** *** 2437,2442 **** --- 1770,1778 ---- " WSML au BufNewFile,BufRead *.wsml setf wsml + " WPL + au BufNewFile,BufRead *.wpl setf xml + " WvDial au BufNewFile,BufRead wvdial.conf,.wvdialrc setf wvdial *************** *** 2495,2530 **** " Xmath au BufNewFile,BufRead *.msc,*.msf setf xmath au BufNewFile,BufRead *.ms ! \ if !s:FTnroff() | setf xmath | endif " XML specific variants: docbk and xbl ! au BufNewFile,BufRead *.xml call s:FTxml() ! ! func! s:FTxml() ! let n = 1 ! while n < 100 && n < line("$") ! let line = getline(n) ! " DocBook 4 or DocBook 5. ! let is_docbook4 = line =~ '\)' && getline(n) !~ '^\s*#\s*include' ! setf racc ! return ! endif ! let n = n + 1 ! endwhile ! setf yacc ! endfunc ! " Yaml au BufNewFile,BufRead *.yaml,*.yml setf yaml --- 1877,1883 ---- au BufNewFile,BufRead *.yy,*.yxx,*.y++ setf yacc " Yacc or racc ! au BufNewFile,BufRead *.y call filetype#FTy() " Yaml au BufNewFile,BufRead *.yaml,*.yml setf yaml *************** *** 2601,2609 **** " Zope " dtml (zope dynamic template markup language), pt (zope page template), " cpt (zope form controller page template) ! au BufNewFile,BufRead *.dtml,*.pt,*.cpt call s:FThtml() " zsql (zope sql method) ! au BufNewFile,BufRead *.zsql call s:SQL() " Z80 assembler asz80 au BufNewFile,BufRead *.z8a setf z8a --- 1893,1901 ---- " Zope " dtml (zope dynamic template markup language), pt (zope page template), " cpt (zope form controller page template) ! au BufNewFile,BufRead *.dtml,*.pt,*.cpt call filetype#FThtml() " zsql (zope sql method) ! au BufNewFile,BufRead *.zsql call filetype#SQL() " Z80 assembler asz80 au BufNewFile,BufRead *.z8a setf z8a *************** *** 2717,2723 **** au BufNewFile,BufRead [rR]akefile* call s:StarSetf('ruby') " Mail (also matches muttrc.vim, so this is below the other checks) ! au BufNewFile,BufRead mutt[[:alnum:]._-]\\\{6\} setf mail au BufNewFile,BufRead reportbug-* call s:StarSetf('mail') --- 2009,2015 ---- au BufNewFile,BufRead [rR]akefile* call s:StarSetf('ruby') " Mail (also matches muttrc.vim, so this is below the other checks) ! au BufNewFile,BufRead {neo,}mutt[[:alnum:]._-]\\\{6\} setf mail au BufNewFile,BufRead reportbug-* call s:StarSetf('mail') *************** *** 2732,2737 **** --- 2024,2033 ---- au BufNewFile,BufRead .mutt{ng,}rc*,*/.mutt{ng,}/mutt{ng,}rc* call s:StarSetf('muttrc') au BufNewFile,BufRead mutt{ng,}rc*,Mutt{ng,}rc* call s:StarSetf('muttrc') + " Neomutt setup file + au BufNewFile,BufRead .neomuttrc*,*/.neomutt/neomuttrc* call s:StarSetf('neomuttrc') + au BufNewFile,BufRead neomuttrc*,Neomuttrc* call s:StarSetf('neomuttrc') + " Nroff macros au BufNewFile,BufRead tmac.* call s:StarSetf('nroff') *************** *** 2753,2769 **** " ReDIF " Only used when the .rdf file was not detected to be XML. ! au BufRead,BufNewFile *.rdf call s:Redif() ! func! s:Redif() ! let lnum = 1 ! while lnum <= 5 && lnum < line('$') ! if getline(lnum) =~ "^\ctemplate-type:" ! setf redif ! return ! endif ! let lnum = lnum + 1 ! endwhile ! endfunc " Remind au BufNewFile,BufRead .reminders* call s:StarSetf('remind') --- 2049,2055 ---- " ReDIF " Only used when the .rdf file was not detected to be XML. ! au BufRead,BufNewFile *.rdf call filetype#Redif() " Remind au BufNewFile,BufRead .reminders* call s:StarSetf('remind') *** ../vim-8.0.1280/runtime/autoload/filetype.vim 2017-11-09 20:43:33.322412809 +0100 --- runtime/autoload/filetype.vim 2017-11-09 20:33:48.539231589 +0100 *************** *** 0 **** --- 1,740 ---- + " Vim functions for file type detection + " + " Maintainer: Bram Moolenaar + " Last Change: 2017 Nov 09 + + " These functions are moved here from runtime/filetype.vim to make startup + " faster. + + " Line continuation is used here, remove 'C' from 'cpoptions' + let s:cpo_save = &cpo + set cpo&vim + + func filetype#Check_inp() + if getline(1) =~ '^\*' + setf abaqus + else + let n = 1 + if line("$") > 500 + let nmax = 500 + else + let nmax = line("$") + endif + while n <= nmax + if getline(n) =~? "^header surface data" + setf trasys + break + endif + let n = n + 1 + endwhile + endif + endfunc + + " This function checks for the kind of assembly that is wanted by the user, or + " can be detected from the first five lines of the file. + func filetype#FTasm() + " make sure b:asmsyntax exists + if !exists("b:asmsyntax") + let b:asmsyntax = "" + endif + + if b:asmsyntax == "" + call filetype#FTasmsyntax() + endif + + " if b:asmsyntax still isn't set, default to asmsyntax or GNU + if b:asmsyntax == "" + if exists("g:asmsyntax") + let b:asmsyntax = g:asmsyntax + else + let b:asmsyntax = "asm" + endif + endif + + exe "setf " . fnameescape(b:asmsyntax) + endfunc + + func filetype#FTasmsyntax() + " see if file contains any asmsyntax=foo overrides. If so, change + " b:asmsyntax appropriately + let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4). + \" ".getline(5)." " + let match = matchstr(head, '\sasmsyntax=\zs[a-zA-Z0-9]\+\ze\s') + if match != '' + let b:asmsyntax = match + elseif ((head =~? '\.title') || (head =~? '\.ident') || (head =~? '\.macro') || (head =~? '\.subtitle') || (head =~? '\.library')) + let b:asmsyntax = "vmasm" + endif + endfunc + + " Check if one of the first five lines contains "VB_Name". In that case it is + " probably a Visual Basic file. Otherwise it's assumed to be "alt" filetype. + func filetype#FTVB(alt) + if getline(1).getline(2).getline(3).getline(4).getline(5) =~? 'VB_Name\|Begin VB\.\(Form\|MDIForm\|UserControl\)' + setf vb + else + exe "setf " . a:alt + endif + endfunc + + func filetype#FTbtm() + if exists("g:dosbatch_syntax_for_btm") && g:dosbatch_syntax_for_btm + setf dosbatch + else + setf btm + endif + endfunc + + func filetype#BindzoneCheck(default) + if getline(1).getline(2).getline(3).getline(4) =~ '^; <<>> DiG [0-9.]\+.* <<>>\|$ORIGIN\|$TTL\|IN\s\+SOA' + setf bindzone + elseif a:default != '' + exe 'setf ' . a:default + endif + endfunc + + func filetype#FTlpc() + if exists("g:lpc_syntax_for_c") + let lnum = 1 + while lnum <= 12 + if getline(lnum) =~# '^\(//\|inherit\|private\|protected\|nosave\|string\|object\|mapping\|mixed\)' + setf lpc + return + endif + let lnum = lnum + 1 + endwhile + endif + setf c + endfunc + + func filetype#FTheader() + if match(getline(1, min([line("$"), 200])), '^@\(interface\|end\|class\)') > -1 + if exists("g:c_syntax_for_h") + setf objc + else + setf objcpp + endif + elseif exists("g:c_syntax_for_h") + setf c + elseif exists("g:ch_syntax_for_h") + setf ch + else + setf cpp + endif + endfunc + + " This function checks if one of the first ten lines start with a '@'. In + " that case it is probably a change file. + " If the first line starts with # or ! it's probably a ch file. + " If a line has "main", "include", "//" ir "/*" it's probably ch. + " Otherwise CHILL is assumed. + func filetype#FTchange() + let lnum = 1 + while lnum <= 10 + if getline(lnum)[0] == '@' + setf change + return + endif + if lnum == 1 && (getline(1)[0] == '#' || getline(1)[0] == '!') + setf ch + return + endif + if getline(lnum) =~ "MODULE" + setf chill + return + endif + if getline(lnum) =~ 'main\s*(\|#\s*include\|//' + setf ch + return + endif + let lnum = lnum + 1 + endwhile + setf chill + endfunc + + func filetype#FTent() + " This function checks for valid cl syntax in the first five lines. + " Look for either an opening comment, '#', or a block start, '{". + " If not found, assume SGML. + let lnum = 1 + while lnum < 6 + let line = getline(lnum) + if line =~ '^\s*[#{]' + setf cl + return + elseif line !~ '^\s*$' + " Not a blank line, not a comment, and not a block start, + " so doesn't look like valid cl code. + break + endif + let lnum = lnum + 1 + endw + setf dtd + endfunc + + func filetype#EuphoriaCheck() + if exists('g:filetype_euphoria') + exe 'setf ' . g:filetype_euphoria + else + setf euphoria3 + endif + endfunc + + func filetype#DtraceCheck() + let lines = getline(1, min([line("$"), 100])) + if match(lines, '^module\>\|^import\>') > -1 + " D files often start with a module and/or import statement. + setf d + elseif match(lines, '^#!\S\+dtrace\|#pragma\s\+D\s\+option\|:\S\{-}:\S\{-}:') > -1 + setf dtrace + else + setf d + endif + endfunc + + func filetype#FTe() + if exists('g:filetype_euphoria') + exe 'setf ' . g:filetype_euphoria + else + let n = 1 + while n < 100 && n < line("$") + if getline(n) =~ "^\\s*\\(<'\\|'>\\)\\s*$" + setf specman + return + endif + let n = n + 1 + endwhile + setf eiffel + endif + endfunc + + " Distinguish between HTML, XHTML and Django + func filetype#FThtml() + let n = 1 + while n < 10 && n < line("$") + if getline(n) =~ '\\|{#\s\+' + setf htmldjango + return + endif + let n = n + 1 + endwhile + setf html + endfunc + + " Distinguish between standard IDL and MS-IDL + func filetype#FTidl() + let n = 1 + while n < 50 && n < line("$") + if getline(n) =~ '^\s*import\s\+"\(unknwn\|objidl\)\.idl"' + setf msidl + return + endif + let n = n + 1 + endwhile + setf idl + endfunc + + " Distinguish between "default" and Cproto prototype file. */ + func filetype#ProtoCheck(default) + " Cproto files have a comment in the first line and a function prototype in + " the second line, it always ends in ";". Indent files may also have + " comments, thus we can't match comments to see the difference. + " IDL files can have a single ';' in the second line, require at least one + " chacter before the ';'. + if getline(2) =~ '.;$' + setf cpp + else + exe 'setf ' . a:default + endif + endfunc + + func filetype#FTm() + let n = 1 + let saw_comment = 0 " Whether we've seen a multiline comment leader. + while n < 100 + let line = getline(n) + if line =~ '^\s*/\*' + " /* ... */ is a comment in Objective C and Murphi, so we can't conclude + " it's either of them yet, but track this as a hint in case we don't see + " anything more definitive. + let saw_comment = 1 + endif + if line =~ '^\s*\(#\s*\(include\|import\)\>\|@import\>\|//\)' + setf objc + return + endif + if line =~ '^\s*%' + setf matlab + return + endif + if line =~ '^\s*(\*' + setf mma + return + endif + if line =~ '^\c\s*\(\(type\|var\)\>\|--\)' + setf murphi + return + endif + let n = n + 1 + endwhile + + if saw_comment + " We didn't see anything definitive, but this looks like either Objective C + " or Murphi based on the comment leader. Assume the former as it is more + " common. + setf objc + elseif exists("g:filetype_m") + " Use user specified default filetype for .m + exe "setf " . g:filetype_m + else + " Default is matlab + setf matlab + endif + endfunc + + func filetype#FTmms() + let n = 1 + while n < 10 + let line = getline(n) + if line =~ '^\s*\(%\|//\)' || line =~ '^\*' + setf mmix + return + endif + if line =~ '^\s*#' + setf make + return + endif + let n = n + 1 + endwhile + setf mmix + endfunc + + " This function checks if one of the first five lines start with a dot. In + " that case it is probably an nroff file: 'filetype' is set and 1 is returned. + func filetype#FTnroff() + if getline(1)[0] . getline(2)[0] . getline(3)[0] . getline(4)[0] . getline(5)[0] =~ '\.' + setf nroff + return 1 + endif + return 0 + endfunc + + func filetype#FTmm() + let n = 1 + while n < 10 + let line = getline(n) + if line =~ '^\s*\(#\s*\(include\|import\)\>\|@import\>\|/\*\)' + setf objcpp + return + endif + let n = n + 1 + endwhile + setf nroff + endfunc + + func filetype#FTpl() + if exists("g:filetype_pl") + exe "setf " . g:filetype_pl + else + " recognize Prolog by specific text in the first non-empty line + " require a blank after the '%' because Perl uses "%list" and "%translate" + let l = getline(nextnonblank(1)) + if l =~ '\' || l =~ '^\s*\(%\+\(\s\|$\)\|/\*\)' || l =~ ':-' + setf prolog + else + setf perl + endif + endif + endfunc + + func filetype#FTinc() + if exists("g:filetype_inc") + exe "setf " . g:filetype_inc + else + let lines = getline(1).getline(2).getline(3) + if lines =~? "perlscript" + setf aspperl + elseif lines =~ "<%" + setf aspvbs + elseif lines =~ "' + \ || line =~ '^\s*{' || line =~ '^\s*(\*' + setf pascal + return + elseif line !~ '^\s*$' || line =~ '^/\*' + " Not an empty line: Doesn't look like valid Pascal code. + " Or it looks like a Progress /* comment + break + endif + let lnum = lnum + 1 + endw + setf progress + endfunc + + func filetype#FTr() + let max = line("$") > 50 ? 50 : line("$") + + for n in range(1, max) + " Rebol is easy to recognize, check for that first + if getline(n) =~? '\' + setf rebol + return + endif + endfor + + for n in range(1, max) + " R has # comments + if getline(n) =~ '^\s*#' + setf r + return + endif + " Rexx has /* comments */ + if getline(n) =~ '^\s*/\*' + setf rexx + return + endif + endfor + + " Nothing recognized, use user default or assume Rexx + if exists("g:filetype_r") + exe "setf " . g:filetype_r + else + " Rexx used to be the default, but R appears to be much more popular. + setf r + endif + endfunc + + func filetype#McSetf() + " Rely on the file to start with a comment. + " MS message text files use ';', Sendmail files use '#' or 'dnl' + for lnum in range(1, min([line("$"), 20])) + let line = getline(lnum) + if line =~ '^\s*\(#\|dnl\)' + setf m4 " Sendmail .mc file + return + elseif line =~ '^\s*;' + setf msmessages " MS Message text file + return + endif + endfor + setf m4 " Default: Sendmail .mc file + endfunc + + " Called from filetype.vim and scripts.vim. + func filetype#SetFileTypeSH(name) + if expand("") =~ g:ft_ignore_pat + return + endif + if a:name =~ '\' + " Some .sh scripts contain #!/bin/csh. + call filetype#SetFileTypeShell("csh") + return + elseif a:name =~ '\' + " Some .sh scripts contain #!/bin/tcsh. + call filetype#SetFileTypeShell("tcsh") + return + elseif a:name =~ '\' + " Some .sh scripts contain #!/bin/zsh. + call filetype#SetFileTypeShell("zsh") + return + elseif a:name =~ '\' + let b:is_kornshell = 1 + if exists("b:is_bash") + unlet b:is_bash + endif + if exists("b:is_sh") + unlet b:is_sh + endif + elseif exists("g:bash_is_sh") || a:name =~ '\' || a:name =~ '\' + let b:is_bash = 1 + if exists("b:is_kornshell") + unlet b:is_kornshell + endif + if exists("b:is_sh") + unlet b:is_sh + endif + elseif a:name =~ '\' + let b:is_sh = 1 + if exists("b:is_kornshell") + unlet b:is_kornshell + endif + if exists("b:is_bash") + unlet b:is_bash + endif + endif + call filetype#SetFileTypeShell("sh") + endfunc + + " For shell-like file types, check for an "exec" command hidden in a comment, + " as used for Tcl. + " Also called from scripts.vim, thus can't be local to this script. + func filetype#SetFileTypeShell(name) + if expand("") =~ g:ft_ignore_pat + return + endif + let l = 2 + while l < 20 && l < line("$") && getline(l) =~ '^\s*\(#\|$\)' + " Skip empty and comment lines. + let l = l + 1 + endwhile + if l < line("$") && getline(l) =~ '\s*exec\s' && getline(l - 1) =~ '^\s*#.*\\$' + " Found an "exec" line after a comment with continuation + let n = substitute(getline(l),'\s*exec\s\+\([^ ]*/\)\=', '', '') + if n =~ '\:p') + if path =~ '^/\(etc/udev/\%(rules\.d/\)\=.*\.rules\|lib/udev/\%(rules\.d/\)\=.*\.rules\)$' + setf udevrules + return + endif + if path =~ '^/etc/ufw/' + setf conf " Better than hog + return + endif + if path =~ '^/\(etc\|usr/share\)/polkit-1/rules\.d' + setf javascript + return + endif + try + let config_lines = readfile('/etc/udev/udev.conf') + catch /^Vim\%((\a\+)\)\=:E484/ + setf hog + return + endtry + let dir = expand(':p:h') + for line in config_lines + if line =~ s:ft_rules_udev_rules_pattern + let udev_rules = substitute(line, s:ft_rules_udev_rules_pattern, '\1', "") + if dir == udev_rules + setf udevrules + endif + break + endif + endfor + setf hog + endfunc + + func filetype#SQL() + if exists("g:filetype_sql") + exe "setf " . g:filetype_sql + else + setf sql + endif + endfunc + + " If the file has an extension of 't' and is in a directory 't' or 'xt' then + " it is almost certainly a Perl test file. + " If the first line starts with '#' and contains 'perl' it's probably a Perl + " file. + " (Slow test) If a file contains a 'use' statement then it is almost certainly + " a Perl file. + func filetype#FTperl() + let dirname = expand("%:p:h:t") + if expand("%:e") == 't' && (dirname == 't' || dirname == 'xt') + setf perl + return 1 + endif + if getline(1)[0] == '#' && getline(1) =~ 'perl' + setf perl + return 1 + endif + if search('^use\s\s*\k', 'nc', 30) + setf perl + return 1 + endif + return 0 + endfunc + + " Choose context, plaintex, or tex (LaTeX) based on these rules: + " 1. Check the first line of the file for "%&". + " 2. Check the first 1000 non-comment lines for LaTeX or ConTeXt keywords. + " 3. Default to "latex" or to g:tex_flavor, can be set in user's vimrc. + func filetype#FTtex() + let firstline = getline(1) + if firstline =~ '^%&\s*\a\+' + let format = tolower(matchstr(firstline, '\a\+')) + let format = substitute(format, 'pdf', '', '') + if format == 'tex' + let format = 'latex' + elseif format == 'plaintex' + let format = 'plain' + endif + elseif expand('%') =~ 'tex/context/.*/.*.tex' + let format = 'context' + else + " Default value, may be changed later: + let format = exists("g:tex_flavor") ? g:tex_flavor : 'plain' + " Save position, go to the top of the file, find first non-comment line. + let save_cursor = getpos('.') + call cursor(1,1) + let firstNC = search('^\s*[^[:space:]%]', 'c', 1000) + if firstNC " Check the next thousand lines for a LaTeX or ConTeXt keyword. + let lpat = 'documentclass\>\|usepackage\>\|begin{\|newcommand\>\|renewcommand\>' + let cpat = 'start\a\+\|setup\a\+\|usemodule\|enablemode\|enableregime\|setvariables\|useencoding\|usesymbols\|stelle\a\+\|verwende\a\+\|stel\a\+\|gebruik\a\+\|usa\a\+\|imposta\a\+\|regle\a\+\|utilisemodule\>' + let kwline = search('^\s*\\\%(' . lpat . '\)\|^\s*\\\(' . cpat . '\)', + \ 'cnp', firstNC + 1000) + if kwline == 1 " lpat matched + let format = 'latex' + elseif kwline == 2 " cpat matched + let format = 'context' + endif " If neither matched, keep default set above. + " let lline = search('^\s*\\\%(' . lpat . '\)', 'cn', firstNC + 1000) + " let cline = search('^\s*\\\%(' . cpat . '\)', 'cn', firstNC + 1000) + " if cline > 0 + " let format = 'context' + " endif + " if lline > 0 && (cline == 0 || cline > lline) + " let format = 'tex' + " endif + endif " firstNC + call setpos('.', save_cursor) + endif " firstline =~ '^%&\s*\a\+' + + " Translation from formats to file types. TODO: add AMSTeX, RevTex, others? + if format == 'plain' + setf plaintex + elseif format == 'context' + setf context + else " probably LaTeX + setf tex + endif + return + endfunc + + func filetype#FTxml() + let n = 1 + while n < 100 && n < line("$") + let line = getline(n) + " DocBook 4 or DocBook 5. + let is_docbook4 = line =~ '\)' && getline(n) !~ '^\s*#\s*include' + setf racc + return + endif + let n = n + 1 + endwhile + setf yacc + endfunc + + func filetype#Redif() + let lnum = 1 + while lnum <= 5 && lnum < line('$') + if getline(lnum) =~ "^\ctemplate-type:" + setf redif + return + endif + let lnum = lnum + 1 + endwhile + endfunc + + + " Restore 'cpoptions' + let &cpo = s:cpo_save + unlet s:cpo_save *** ../vim-8.0.1280/runtime/scripts.vim 2017-08-27 16:53:57.786032946 +0200 --- runtime/scripts.vim 2017-11-09 20:29:52.090810187 +0100 *************** *** 1,7 **** " Vim support file to detect file types in scripts " " Maintainer: Bram Moolenaar ! " Last change: 2017 Aug 27 " This file is called by an autocommand for every file that has just been " loaded into a buffer. It checks if the type of file can be recognized by --- 1,7 ---- " Vim support file to detect file types in scripts " " Maintainer: Bram Moolenaar ! " Last change: 2017 Nov 09 " This file is called by an autocommand for every file that has just been " loaded into a buffer. It checks if the type of file can be recognized by *************** *** 66,84 **** " Bourne-like shell scripts: bash bash2 ksh ksh93 sh if s:name =~# '^\(bash\d*\|\|ksh\d*\|sh\)\>' ! call SetFileTypeSH(s:line1) " defined in filetype.vim " csh scripts elseif s:name =~# '^csh\>' if exists("g:filetype_csh") ! call SetFileTypeShell(g:filetype_csh) else ! call SetFileTypeShell("csh") endif " tcsh scripts elseif s:name =~# '^tcsh\>' ! call SetFileTypeShell("tcsh") " Z shell scripts elseif s:name =~# '^zsh\>' --- 66,84 ---- " Bourne-like shell scripts: bash bash2 ksh ksh93 sh if s:name =~# '^\(bash\d*\|\|ksh\d*\|sh\)\>' ! call filetype#SetFileTypeSH(s:line1) " defined in filetype.vim " csh scripts elseif s:name =~# '^csh\>' if exists("g:filetype_csh") ! call filetype#SetFileTypeShell(g:filetype_csh) else ! call filetype#SetFileTypeShell("csh") endif " tcsh scripts elseif s:name =~# '^tcsh\>' ! call filetype#SetFileTypeShell("tcsh") " Z shell scripts elseif s:name =~# '^zsh\>' *************** *** 185,191 **** " Bourne-like shell scripts: sh ksh bash bash2 if s:line1 =~# '^:$' ! call SetFileTypeSH(s:line1) " defined in filetype.vim " Z shell scripts elseif s:line1 =~# '^#compdef\>' || s:line1 =~# '^#autoload\>' || --- 185,191 ---- " Bourne-like shell scripts: sh ksh bash bash2 if s:line1 =~# '^:$' ! call filetype#SetFileTypeSH(s:line1) " defined in filetype.vim " Z shell scripts elseif s:line1 =~# '^#compdef\>' || s:line1 =~# '^#autoload\>' || *************** *** 324,330 **** set ft=sindacmp " DNS zone files ! elseif s:line1.s:line2.s:line3.s:line4 =~# '^; <<>> DiG [0-9.]\+ <<>>\|BIND.*named\|$ORIGIN\|$TTL\|IN\s\+SOA' set ft=bindzone " BAAN --- 324,330 ---- set ft=sindacmp " DNS zone files ! elseif s:line1.s:line2.s:line3.s:line4 =~# '^; <<>> DiG [0-9.]\+.* <<>>\|$ORIGIN\|$TTL\|IN\s\+SOA' set ft=bindzone " BAAN *** ../vim-8.0.1280/src/version.c 2017-11-09 19:56:00.853332902 +0100 --- src/version.c 2017-11-09 20:12:28.390510940 +0100 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1281, /**/ -- If you don't get everything you want, think of everything you didn't get and don't want. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///