1071d4279SBram Moolenaar" Vim support file to detect file types in scripts 2071d4279SBram Moolenaar" 3071d4279SBram Moolenaar" Maintainer: Bram Moolenaar <[email protected]> 4*f4630b60SBram Moolenaar" Last change: 2005 May 20 5071d4279SBram Moolenaar 6071d4279SBram Moolenaar" This file is called by an autocommand for every file that has just been 7071d4279SBram Moolenaar" loaded into a buffer. It checks if the type of file can be recognized by 8071d4279SBram Moolenaar" the file contents. The autocommand is in $VIMRUNTIME/filetype.vim. 9071d4279SBram Moolenaar 10071d4279SBram Moolenaar 11071d4279SBram Moolenaar" Only do the rest when the FileType autocommand has not been triggered yet. 12071d4279SBram Moolenaarif did_filetype() 13071d4279SBram Moolenaar finish 14071d4279SBram Moolenaarendif 15071d4279SBram Moolenaar 16071d4279SBram Moolenaar" Load the user defined scripts file first 17071d4279SBram Moolenaar" Only do this when the FileType autocommand has not been triggered yet 18*f4630b60SBram Moolenaarif exists("myscriptsfile") && filereadable(expand(myscriptsfile)) 19071d4279SBram Moolenaar execute "source " . myscriptsfile 20071d4279SBram Moolenaar if did_filetype() 21071d4279SBram Moolenaar finish 22071d4279SBram Moolenaar endif 23071d4279SBram Moolenaarendif 24071d4279SBram Moolenaar 25071d4279SBram Moolenaar" Line continuation is used here, remove 'C' from 'cpoptions' 26071d4279SBram Moolenaarlet s:cpo_save = &cpo 27071d4279SBram Moolenaarset cpo&vim 28071d4279SBram Moolenaar 29071d4279SBram Moolenaarlet s:line1 = getline(1) 30071d4279SBram Moolenaar 31071d4279SBram Moolenaarif s:line1 =~ "^#!" 32071d4279SBram Moolenaar " A script that starts with "#!". 33071d4279SBram Moolenaar 34071d4279SBram Moolenaar " Check for a line like "#!/usr/bin/env VAR=val bash". Turn it into 35071d4279SBram Moolenaar " "#!/usr/bin/bash" to make matching easier. 36071d4279SBram Moolenaar if s:line1 =~ '^#!\s*\S*\<env\s' 37071d4279SBram Moolenaar let s:line1 = substitute(s:line1, '\S\+=\S\+', '', 'g') 38071d4279SBram Moolenaar let s:line1 = substitute(s:line1, '\<env\s\+', '', '') 39071d4279SBram Moolenaar endif 40071d4279SBram Moolenaar 41071d4279SBram Moolenaar " Get the program name. 42071d4279SBram Moolenaar " Only accept spaces in PC style paths: "#!c:/program files/perl [args]". 43*f4630b60SBram Moolenaar " If the word env is used, use the first word after the space: 44*f4630b60SBram Moolenaar " "#!/usr/bin/env perl [path/args]" 45071d4279SBram Moolenaar " If there is no path use the first word: "#!perl [path/args]". 46071d4279SBram Moolenaar " Otherwise get the last word after a slash: "#!/usr/bin/perl [path/args]". 47071d4279SBram Moolenaar if s:line1 =~ '^#!\s*\a:[/\\]' 48071d4279SBram Moolenaar let s:name = substitute(s:line1, '^#!.*[/\\]\(\i\+\).*', '\1', '') 49*f4630b60SBram Moolenaar elseif s:line1 =~ '^#!.*\<env\>' 50*f4630b60SBram Moolenaar let s:name = substitute(s:line1, '^#!.*\<env\>\s\+\(\i\+\).*', '\1', '') 51071d4279SBram Moolenaar elseif s:line1 =~ '^#!\s*[^/\\ ]*\>\([^/\\]\|$\)' 52071d4279SBram Moolenaar let s:name = substitute(s:line1, '^#!\s*\([^/\\ ]*\>\).*', '\1', '') 53071d4279SBram Moolenaar else 54071d4279SBram Moolenaar let s:name = substitute(s:line1, '^#!\s*\S*[/\\]\(\i\+\).*', '\1', '') 55071d4279SBram Moolenaar endif 56071d4279SBram Moolenaar 57d4755bb0SBram Moolenaar " Bourne-like shell scripts: bash bash2 ksh ksh93 sh 58d4755bb0SBram Moolenaar if s:name =~ '^\(bash\d*\|\|ksh\d*\|sh\)\>' 59071d4279SBram Moolenaar call SetFileTypeSH(s:line1) " defined in filetype.vim 60071d4279SBram Moolenaar 61071d4279SBram Moolenaar " csh scripts 62071d4279SBram Moolenaar elseif s:name =~ '^csh\>' 63071d4279SBram Moolenaar if exists("g:filetype_csh") 643fdfa4a9SBram Moolenaar call SetFileTypeShell(g:filetype_csh) 65071d4279SBram Moolenaar else 663fdfa4a9SBram Moolenaar call SetFileTypeShell("csh") 67071d4279SBram Moolenaar endif 68071d4279SBram Moolenaar 69071d4279SBram Moolenaar " tcsh scripts 70071d4279SBram Moolenaar elseif s:name =~ '^tcsh\>' 713fdfa4a9SBram Moolenaar call SetFileTypeShell("tcsh") 72071d4279SBram Moolenaar 73071d4279SBram Moolenaar " Z shell scripts 74071d4279SBram Moolenaar elseif s:name =~ '^zsh\>' 75071d4279SBram Moolenaar set ft=zsh 76071d4279SBram Moolenaar 77071d4279SBram Moolenaar " TCL scripts 78071d4279SBram Moolenaar elseif s:name =~ '^\(tclsh\|wish\|expectk\|itclsh\|itkwish\)\>' 79071d4279SBram Moolenaar set ft=tcl 80071d4279SBram Moolenaar 81071d4279SBram Moolenaar " Expect scripts 82071d4279SBram Moolenaar elseif s:name =~ '^expect\>' 83071d4279SBram Moolenaar set ft=expect 84071d4279SBram Moolenaar 85071d4279SBram Moolenaar " Gnuplot scripts 86071d4279SBram Moolenaar elseif s:name =~ '^gnuplot\>' 87071d4279SBram Moolenaar set ft=gnuplot 88071d4279SBram Moolenaar 89071d4279SBram Moolenaar " Makefiles 90071d4279SBram Moolenaar elseif s:name =~ 'make\>' 91071d4279SBram Moolenaar set ft=make 92071d4279SBram Moolenaar 93*f4630b60SBram Moolenaar " Lua 94*f4630b60SBram Moolenaar elseif s:name =~ 'lua' 95*f4630b60SBram Moolenaar set ft=lua 96*f4630b60SBram Moolenaar 97071d4279SBram Moolenaar " Perl 98071d4279SBram Moolenaar elseif s:name =~ 'perl' 99071d4279SBram Moolenaar set ft=perl 100071d4279SBram Moolenaar 101071d4279SBram Moolenaar " PHP 102071d4279SBram Moolenaar elseif s:name =~ 'php' 103071d4279SBram Moolenaar set ft=php 104071d4279SBram Moolenaar 105071d4279SBram Moolenaar " Python 106071d4279SBram Moolenaar elseif s:name =~ 'python' 107071d4279SBram Moolenaar set ft=python 108071d4279SBram Moolenaar 109071d4279SBram Moolenaar " Groovy 110071d4279SBram Moolenaar elseif s:name =~ '^groovy\>' 111071d4279SBram Moolenaar set ft=groovy 112071d4279SBram Moolenaar 113071d4279SBram Moolenaar " Ruby 114071d4279SBram Moolenaar elseif s:name =~ 'ruby' 115071d4279SBram Moolenaar set ft=ruby 116071d4279SBram Moolenaar 117071d4279SBram Moolenaar " BC calculator 118071d4279SBram Moolenaar elseif s:name =~ '^bc\>' 119071d4279SBram Moolenaar set ft=bc 120071d4279SBram Moolenaar 121071d4279SBram Moolenaar " sed 122071d4279SBram Moolenaar elseif s:name =~ 'sed\>' 123071d4279SBram Moolenaar set ft=sed 124071d4279SBram Moolenaar 125071d4279SBram Moolenaar " OCaml-scripts 126071d4279SBram Moolenaar elseif s:name =~ 'ocaml' 127071d4279SBram Moolenaar set ft=ocaml 128071d4279SBram Moolenaar 129071d4279SBram Moolenaar " Awk scripts 130071d4279SBram Moolenaar elseif s:name =~ 'awk\>' 131071d4279SBram Moolenaar set ft=awk 132071d4279SBram Moolenaar 133071d4279SBram Moolenaar " Website MetaLanguage 134071d4279SBram Moolenaar elseif s:name =~ 'wml' 135071d4279SBram Moolenaar set ft=wml 136071d4279SBram Moolenaar 137071d4279SBram Moolenaar " Scheme scripts 138071d4279SBram Moolenaar elseif s:name =~ 'scheme' 139071d4279SBram Moolenaar set ft=scheme 140071d4279SBram Moolenaar 141071d4279SBram Moolenaar endif 142071d4279SBram Moolenaar unlet s:name 143071d4279SBram Moolenaar 144071d4279SBram Moolenaarelse 145071d4279SBram Moolenaar " File does not start with "#!". 146071d4279SBram Moolenaar 147071d4279SBram Moolenaar let s:line2 = getline(2) 148071d4279SBram Moolenaar let s:line3 = getline(3) 149071d4279SBram Moolenaar let s:line4 = getline(4) 150071d4279SBram Moolenaar let s:line5 = getline(5) 151071d4279SBram Moolenaar 152071d4279SBram Moolenaar " Bourne-like shell scripts: sh ksh bash bash2 153071d4279SBram Moolenaar if s:line1 =~ '^:$' 154071d4279SBram Moolenaar call SetFileTypeSH(s:line1) " defined in filetype.vim 155071d4279SBram Moolenaar 156071d4279SBram Moolenaar " Z shell scripts 157071d4279SBram Moolenaar elseif s:line1 =~ '^#compdef\>' || s:line1 =~ '^#autoload\>' 158071d4279SBram Moolenaar set ft=zsh 159071d4279SBram Moolenaar 160071d4279SBram Moolenaar " ELM Mail files 161071d4279SBram Moolenaar elseif s:line1 =~ '^From [a-zA-Z][a-zA-Z_0-9\.=-]*\(@[^ ]*\)\= .*[12][09]\d\d$' 162071d4279SBram Moolenaar set ft=mail 163071d4279SBram Moolenaar 164071d4279SBram Moolenaar " Mason 165071d4279SBram Moolenaar elseif s:line1 =~ '^<[%&].*>' 166071d4279SBram Moolenaar set ft=mason 167071d4279SBram Moolenaar 168071d4279SBram Moolenaar " Vim scripts (must have '" vim' as the first line to trigger this) 169071d4279SBram Moolenaar elseif s:line1 =~ '^" *[vV]im$' 170071d4279SBram Moolenaar set ft=vim 171071d4279SBram Moolenaar 172071d4279SBram Moolenaar " MOO 173071d4279SBram Moolenaar elseif s:line1 =~ '^\*\* LambdaMOO Database, Format Version \%([1-3]\>\)\@!\d\+ \*\*$' 174071d4279SBram Moolenaar set ft=moo 175071d4279SBram Moolenaar 176071d4279SBram Moolenaar " Diff file: 177071d4279SBram Moolenaar " - "diff" in first line (context diff) 178071d4279SBram Moolenaar " - "Only in " in first line 179071d4279SBram Moolenaar " - "--- " in first line and "+++ " in second line (unified diff). 180071d4279SBram Moolenaar " - "*** " in first line and "--- " in second line (context diff). 181071d4279SBram Moolenaar " - "# It was generated by makepatch " in the second line (makepatch diff). 182071d4279SBram Moolenaar " - "Index: <filename>" in the first line (CVS file) 183071d4279SBram Moolenaar elseif s:line1 =~ '^\(diff\>\|Only in \|\d\+\(,\d\+\)\=[cda]\d\+\>\|# It was generated by makepatch \|Index:\s\+\f\+$\|===== \f\+ \d\+\.\d\+ vs edited\|==== //\f\+#\d\+\)' 184071d4279SBram Moolenaar \ || (s:line1 =~ '^--- ' && s:line2 =~ '^+++ ') 185071d4279SBram Moolenaar \ || (s:line1 =~ '^\*\*\* ' && s:line2 =~ '^--- ') 186071d4279SBram Moolenaar set ft=diff 187071d4279SBram Moolenaar 188071d4279SBram Moolenaar " PostScript Files (must have %!PS as the first line, like a2ps output) 189071d4279SBram Moolenaar elseif s:line1 =~ '^%![ \t]*PS' 190071d4279SBram Moolenaar set ft=postscr 191071d4279SBram Moolenaar 192071d4279SBram Moolenaar " M4 scripts: Guess there is a line that starts with "dnl". 193071d4279SBram Moolenaar elseif s:line1 =~ '^\s*dnl\>' 194071d4279SBram Moolenaar \ || s:line2 =~ '^\s*dnl\>' 195071d4279SBram Moolenaar \ || s:line3 =~ '^\s*dnl\>' 196071d4279SBram Moolenaar \ || s:line4 =~ '^\s*dnl\>' 197071d4279SBram Moolenaar \ || s:line5 =~ '^\s*dnl\>' 198071d4279SBram Moolenaar set ft=m4 199071d4279SBram Moolenaar 200071d4279SBram Moolenaar " AmigaDos scripts 201071d4279SBram Moolenaar elseif $TERM == "amiga" 202071d4279SBram Moolenaar \ && (s:line1 =~ "^;" || s:line1 =~ '^\.[bB][rR][aA]') 203071d4279SBram Moolenaar set ft=amiga 204071d4279SBram Moolenaar 205071d4279SBram Moolenaar " SiCAD scripts (must have procn or procd as the first line to trigger this) 206071d4279SBram Moolenaar elseif s:line1 =~? '^ *proc[nd] *$' 207071d4279SBram Moolenaar set ft=sicad 208071d4279SBram Moolenaar 209071d4279SBram Moolenaar " Purify log files start with "**** Purify" 210071d4279SBram Moolenaar elseif s:line1 =~ '^\*\*\*\* Purify' 211071d4279SBram Moolenaar set ft=purifylog 212071d4279SBram Moolenaar 213071d4279SBram Moolenaar " XML 214071d4279SBram Moolenaar elseif s:line1 =~ '<?\s*xml.*?>' 215071d4279SBram Moolenaar set ft=xml 216071d4279SBram Moolenaar 217071d4279SBram Moolenaar " XHTML (e.g.: PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN") 218071d4279SBram Moolenaar elseif s:line1 =~ '\<DTD\s\+XHTML\s' 219071d4279SBram Moolenaar set ft=xhtml 220071d4279SBram Moolenaar 221071d4279SBram Moolenaar " XXD output 222071d4279SBram Moolenaar elseif s:line1 =~ '^\x\{7}: \x\{2} \=\x\{2} \=\x\{2} \=\x\{2} ' 223071d4279SBram Moolenaar set ft=xxd 224071d4279SBram Moolenaar 225071d4279SBram Moolenaar " RCS/CVS log output 226071d4279SBram Moolenaar elseif s:line1 =~ '^RCS file:' || s:line2 =~ '^RCS file:' 227071d4279SBram Moolenaar set ft=rcslog 228071d4279SBram Moolenaar 229071d4279SBram Moolenaar " CVS commit 230d4755bb0SBram Moolenaar elseif s:line2 =~ '^CVS:' || getline("$") =~ '^CVS: ' 231071d4279SBram Moolenaar set ft=cvs 232071d4279SBram Moolenaar 23319a09a18SBram Moolenaar " Prescribe 23419a09a18SBram Moolenaar elseif s:line1 =~ '^!R!' 23519a09a18SBram Moolenaar set ft=prescribe 23619a09a18SBram Moolenaar 237071d4279SBram Moolenaar " Send-pr 238071d4279SBram Moolenaar elseif s:line1 =~ '^SEND-PR:' 239071d4279SBram Moolenaar set ft=sendpr 240071d4279SBram Moolenaar 241071d4279SBram Moolenaar " SNNS files 242071d4279SBram Moolenaar elseif s:line1 =~ '^SNNS network definition file' 243071d4279SBram Moolenaar set ft=snnsnet 244071d4279SBram Moolenaar elseif s:line1 =~ '^SNNS pattern definition file' 245071d4279SBram Moolenaar set ft=snnspat 246071d4279SBram Moolenaar elseif s:line1 =~ '^SNNS result file' 247071d4279SBram Moolenaar set ft=snnsres 248071d4279SBram Moolenaar 249071d4279SBram Moolenaar " Virata 250071d4279SBram Moolenaar elseif s:line1 =~ '^%.\{-}[Vv]irata' 251071d4279SBram Moolenaar \ || s:line2 =~ '^%.\{-}[Vv]irata' 252071d4279SBram Moolenaar \ || s:line3 =~ '^%.\{-}[Vv]irata' 253071d4279SBram Moolenaar \ || s:line4 =~ '^%.\{-}[Vv]irata' 254071d4279SBram Moolenaar \ || s:line5 =~ '^%.\{-}[Vv]irata' 255071d4279SBram Moolenaar set ft=virata 256071d4279SBram Moolenaar 257071d4279SBram Moolenaar " Strace 258071d4279SBram Moolenaar elseif s:line1 =~ '^[0-9]* *execve(' 259071d4279SBram Moolenaar set ft=strace 260071d4279SBram Moolenaar 261071d4279SBram Moolenaar " VSE JCL 262071d4279SBram Moolenaar elseif s:line1 =~ '^\* $$ JOB\>' || s:line1 =~ '^// *JOB\>' 263071d4279SBram Moolenaar set ft=vsejcl 264071d4279SBram Moolenaar 265071d4279SBram Moolenaar " TAK and SINDA 266071d4279SBram Moolenaar elseif s:line4 =~ 'K & K Associates' || s:line2 =~ 'TAK 2000' 267071d4279SBram Moolenaar set ft=takout 268071d4279SBram Moolenaar elseif s:line3 =~ 'S Y S T E M S I M P R O V E D ' 269071d4279SBram Moolenaar set ft=sindaout 270071d4279SBram Moolenaar elseif getline(6) =~ 'Run Date: ' 271071d4279SBram Moolenaar set ft=takcmp 272071d4279SBram Moolenaar elseif getline(9) =~ 'Node File 1' 273071d4279SBram Moolenaar set ft=sindacmp 274071d4279SBram Moolenaar 275071d4279SBram Moolenaar " DNS zone files 276071d4279SBram Moolenaar elseif s:line1.s:line2 =~ '$ORIGIN\|$TTL\|IN\s*SOA' 277071d4279SBram Moolenaar \ || s:line1.s:line2.s:line3.s:line4 =~ 'BIND.*named' 278071d4279SBram Moolenaar set ft=dns 279071d4279SBram Moolenaar 280071d4279SBram Moolenaar " BAAN 281071d4279SBram Moolenaar elseif s:line1 =~ '|\*\{1,80}' && s:line2 =~ 'VRC ' 282071d4279SBram Moolenaar \ || s:line2 =~ '|\*\{1,80}' && s:line3 =~ 'VRC ' 283071d4279SBram Moolenaar set ft=baan 284071d4279SBram Moolenaar 285071d4279SBram Moolenaar " Valgrind 286071d4279SBram Moolenaar elseif s:line1 =~ '^==\d\+== valgrind' 287071d4279SBram Moolenaar set ft=valgrind 288071d4279SBram Moolenaar 289071d4279SBram Moolenaar " Renderman Interface Bytestream 290071d4279SBram Moolenaar elseif s:line1 =~ '^##RenderMan' 291071d4279SBram Moolenaar set ft=rib 292071d4279SBram Moolenaar 293071d4279SBram Moolenaar " Scheme scripts 294071d4279SBram Moolenaar elseif s:line1 =~ 'exec\s\+\S*scheme' || s:line2 =~ 'exec\s\+\S*scheme' 295071d4279SBram Moolenaar set ft=scheme 296071d4279SBram Moolenaar 297071d4279SBram Moolenaar " CVS diff 298071d4279SBram Moolenaar else 299071d4279SBram Moolenaar let lnum = 1 300071d4279SBram Moolenaar while getline(lnum) =~ "^? " && lnum < line("$") 301071d4279SBram Moolenaar let lnum = lnum + 1 302071d4279SBram Moolenaar endwhile 303071d4279SBram Moolenaar if getline(lnum) =~ '^Index:\s\+\f\+$' 304071d4279SBram Moolenaar set ft=diff 305071d4279SBram Moolenaar 306071d4279SBram Moolenaar " locale input files: Formal Definitions of Cultural Conventions 307071d4279SBram Moolenaar " filename must be like en_US, fr_FR@euro or en_US.UTF-8 308071d4279SBram Moolenaar elseif expand("%") =~ '\a\a_\a\a\($\|[.@]\)\|i18n$\|POSIX$\|translit_' 309071d4279SBram Moolenaar let lnum = 1 310071d4279SBram Moolenaar while lnum < 100 && lnum < line("$") 311071d4279SBram Moolenaar if getline(lnum) =~ '^LC_\(IDENTIFICATION\|CTYPE\|COLLATE\|MONETARY\|NUMERIC\|TIME\|MESSAGES\|PAPER\|TELEPHONE\|MEASUREMENT\|NAME\|ADDRESS\)$' 312071d4279SBram Moolenaar setf fdcc 313071d4279SBram Moolenaar break 314071d4279SBram Moolenaar endif 315071d4279SBram Moolenaar let lnum = lnum + 1 316071d4279SBram Moolenaar endwhile 317071d4279SBram Moolenaar endif 318071d4279SBram Moolenaar 319071d4279SBram Moolenaar endif 320071d4279SBram Moolenaar 321071d4279SBram Moolenaar unlet s:line2 s:line3 s:line4 s:line5 322071d4279SBram Moolenaar 323071d4279SBram Moolenaarendif 324071d4279SBram Moolenaar 325071d4279SBram Moolenaar" Restore 'cpoptions' 326071d4279SBram Moolenaarlet &cpo = s:cpo_save 327071d4279SBram Moolenaar 328071d4279SBram Moolenaarunlet s:cpo_save s:line1 329