Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 1 | " Vim support file to detect file types in scripts |
| 2 | " |
| 3 | " Maintainer: Bram Moolenaar <Bram@vim.org> |
Bram Moolenaar | d4755bb | 2004-09-02 19:12:26 +0000 | [diff] [blame] | 4 | " Last change: 2004 Sep 02 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 5 | |
| 6 | " This file is called by an autocommand for every file that has just been |
| 7 | " loaded into a buffer. It checks if the type of file can be recognized by |
| 8 | " the file contents. The autocommand is in $VIMRUNTIME/filetype.vim. |
| 9 | |
| 10 | |
| 11 | " Only do the rest when the FileType autocommand has not been triggered yet. |
| 12 | if did_filetype() |
| 13 | finish |
| 14 | endif |
| 15 | |
| 16 | " Load the user defined scripts file first |
| 17 | " Only do this when the FileType autocommand has not been triggered yet |
| 18 | if exists("myscriptsfile") && file_readable(expand(myscriptsfile)) |
| 19 | execute "source " . myscriptsfile |
| 20 | if did_filetype() |
| 21 | finish |
| 22 | endif |
| 23 | endif |
| 24 | |
| 25 | " Line continuation is used here, remove 'C' from 'cpoptions' |
| 26 | let s:cpo_save = &cpo |
| 27 | set cpo&vim |
| 28 | |
| 29 | let s:line1 = getline(1) |
| 30 | |
| 31 | if s:line1 =~ "^#!" |
| 32 | " A script that starts with "#!". |
| 33 | |
| 34 | " Check for a line like "#!/usr/bin/env VAR=val bash". Turn it into |
| 35 | " "#!/usr/bin/bash" to make matching easier. |
| 36 | if s:line1 =~ '^#!\s*\S*\<env\s' |
| 37 | let s:line1 = substitute(s:line1, '\S\+=\S\+', '', 'g') |
| 38 | let s:line1 = substitute(s:line1, '\<env\s\+', '', '') |
| 39 | endif |
| 40 | |
| 41 | " Get the program name. |
| 42 | " Only accept spaces in PC style paths: "#!c:/program files/perl [args]". |
| 43 | " If there is no path use the first word: "#!perl [path/args]". |
| 44 | " Otherwise get the last word after a slash: "#!/usr/bin/perl [path/args]". |
| 45 | if s:line1 =~ '^#!\s*\a:[/\\]' |
| 46 | let s:name = substitute(s:line1, '^#!.*[/\\]\(\i\+\).*', '\1', '') |
| 47 | elseif s:line1 =~ '^#!\s*[^/\\ ]*\>\([^/\\]\|$\)' |
| 48 | let s:name = substitute(s:line1, '^#!\s*\([^/\\ ]*\>\).*', '\1', '') |
| 49 | else |
| 50 | let s:name = substitute(s:line1, '^#!\s*\S*[/\\]\(\i\+\).*', '\1', '') |
| 51 | endif |
| 52 | |
Bram Moolenaar | d4755bb | 2004-09-02 19:12:26 +0000 | [diff] [blame] | 53 | " Bourne-like shell scripts: bash bash2 ksh ksh93 sh |
| 54 | if s:name =~ '^\(bash\d*\|\|ksh\d*\|sh\)\>' |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 55 | call SetFileTypeSH(s:line1) " defined in filetype.vim |
| 56 | |
| 57 | " csh scripts |
| 58 | elseif s:name =~ '^csh\>' |
| 59 | if exists("g:filetype_csh") |
| 60 | let &ft = g:filetype_csh |
| 61 | else |
| 62 | set ft=csh |
| 63 | endif |
| 64 | |
| 65 | " tcsh scripts |
| 66 | elseif s:name =~ '^tcsh\>' |
| 67 | set ft=tcsh |
| 68 | |
| 69 | " Z shell scripts |
| 70 | elseif s:name =~ '^zsh\>' |
| 71 | set ft=zsh |
| 72 | |
| 73 | " TCL scripts |
| 74 | elseif s:name =~ '^\(tclsh\|wish\|expectk\|itclsh\|itkwish\)\>' |
| 75 | set ft=tcl |
| 76 | |
| 77 | " Expect scripts |
| 78 | elseif s:name =~ '^expect\>' |
| 79 | set ft=expect |
| 80 | |
| 81 | " Gnuplot scripts |
| 82 | elseif s:name =~ '^gnuplot\>' |
| 83 | set ft=gnuplot |
| 84 | |
| 85 | " Makefiles |
| 86 | elseif s:name =~ 'make\>' |
| 87 | set ft=make |
| 88 | |
| 89 | " Perl |
| 90 | elseif s:name =~ 'perl' |
| 91 | set ft=perl |
| 92 | |
| 93 | " PHP |
| 94 | elseif s:name =~ 'php' |
| 95 | set ft=php |
| 96 | |
| 97 | " Python |
| 98 | elseif s:name =~ 'python' |
| 99 | set ft=python |
| 100 | |
| 101 | " Groovy |
| 102 | elseif s:name =~ '^groovy\>' |
| 103 | set ft=groovy |
| 104 | |
| 105 | " Ruby |
| 106 | elseif s:name =~ 'ruby' |
| 107 | set ft=ruby |
| 108 | |
| 109 | " BC calculator |
| 110 | elseif s:name =~ '^bc\>' |
| 111 | set ft=bc |
| 112 | |
| 113 | " sed |
| 114 | elseif s:name =~ 'sed\>' |
| 115 | set ft=sed |
| 116 | |
| 117 | " OCaml-scripts |
| 118 | elseif s:name =~ 'ocaml' |
| 119 | set ft=ocaml |
| 120 | |
| 121 | " Awk scripts |
| 122 | elseif s:name =~ 'awk\>' |
| 123 | set ft=awk |
| 124 | |
| 125 | " Website MetaLanguage |
| 126 | elseif s:name =~ 'wml' |
| 127 | set ft=wml |
| 128 | |
| 129 | " Scheme scripts |
| 130 | elseif s:name =~ 'scheme' |
| 131 | set ft=scheme |
| 132 | |
| 133 | endif |
| 134 | unlet s:name |
| 135 | |
| 136 | else |
| 137 | " File does not start with "#!". |
| 138 | |
| 139 | let s:line2 = getline(2) |
| 140 | let s:line3 = getline(3) |
| 141 | let s:line4 = getline(4) |
| 142 | let s:line5 = getline(5) |
| 143 | |
| 144 | " Bourne-like shell scripts: sh ksh bash bash2 |
| 145 | if s:line1 =~ '^:$' |
| 146 | call SetFileTypeSH(s:line1) " defined in filetype.vim |
| 147 | |
| 148 | " Z shell scripts |
| 149 | elseif s:line1 =~ '^#compdef\>' || s:line1 =~ '^#autoload\>' |
| 150 | set ft=zsh |
| 151 | |
| 152 | " ELM Mail files |
| 153 | elseif s:line1 =~ '^From [a-zA-Z][a-zA-Z_0-9\.=-]*\(@[^ ]*\)\= .*[12][09]\d\d$' |
| 154 | set ft=mail |
| 155 | |
| 156 | " Mason |
| 157 | elseif s:line1 =~ '^<[%&].*>' |
| 158 | set ft=mason |
| 159 | |
| 160 | " Vim scripts (must have '" vim' as the first line to trigger this) |
| 161 | elseif s:line1 =~ '^" *[vV]im$' |
| 162 | set ft=vim |
| 163 | |
| 164 | " MOO |
| 165 | elseif s:line1 =~ '^\*\* LambdaMOO Database, Format Version \%([1-3]\>\)\@!\d\+ \*\*$' |
| 166 | set ft=moo |
| 167 | |
| 168 | " Diff file: |
| 169 | " - "diff" in first line (context diff) |
| 170 | " - "Only in " in first line |
| 171 | " - "--- " in first line and "+++ " in second line (unified diff). |
| 172 | " - "*** " in first line and "--- " in second line (context diff). |
| 173 | " - "# It was generated by makepatch " in the second line (makepatch diff). |
| 174 | " - "Index: <filename>" in the first line (CVS file) |
| 175 | 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\+\)' |
| 176 | \ || (s:line1 =~ '^--- ' && s:line2 =~ '^+++ ') |
| 177 | \ || (s:line1 =~ '^\*\*\* ' && s:line2 =~ '^--- ') |
| 178 | set ft=diff |
| 179 | |
| 180 | " PostScript Files (must have %!PS as the first line, like a2ps output) |
| 181 | elseif s:line1 =~ '^%![ \t]*PS' |
| 182 | set ft=postscr |
| 183 | |
| 184 | " M4 scripts: Guess there is a line that starts with "dnl". |
| 185 | elseif s:line1 =~ '^\s*dnl\>' |
| 186 | \ || s:line2 =~ '^\s*dnl\>' |
| 187 | \ || s:line3 =~ '^\s*dnl\>' |
| 188 | \ || s:line4 =~ '^\s*dnl\>' |
| 189 | \ || s:line5 =~ '^\s*dnl\>' |
| 190 | set ft=m4 |
| 191 | |
| 192 | " AmigaDos scripts |
| 193 | elseif $TERM == "amiga" |
| 194 | \ && (s:line1 =~ "^;" || s:line1 =~ '^\.[bB][rR][aA]') |
| 195 | set ft=amiga |
| 196 | |
| 197 | " SiCAD scripts (must have procn or procd as the first line to trigger this) |
| 198 | elseif s:line1 =~? '^ *proc[nd] *$' |
| 199 | set ft=sicad |
| 200 | |
| 201 | " Purify log files start with "**** Purify" |
| 202 | elseif s:line1 =~ '^\*\*\*\* Purify' |
| 203 | set ft=purifylog |
| 204 | |
| 205 | " XML |
| 206 | elseif s:line1 =~ '<?\s*xml.*?>' |
| 207 | set ft=xml |
| 208 | |
| 209 | " XHTML (e.g.: PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN") |
| 210 | elseif s:line1 =~ '\<DTD\s\+XHTML\s' |
| 211 | set ft=xhtml |
| 212 | |
| 213 | " XXD output |
| 214 | elseif s:line1 =~ '^\x\{7}: \x\{2} \=\x\{2} \=\x\{2} \=\x\{2} ' |
| 215 | set ft=xxd |
| 216 | |
| 217 | " RCS/CVS log output |
| 218 | elseif s:line1 =~ '^RCS file:' || s:line2 =~ '^RCS file:' |
| 219 | set ft=rcslog |
| 220 | |
| 221 | " CVS commit |
Bram Moolenaar | d4755bb | 2004-09-02 19:12:26 +0000 | [diff] [blame] | 222 | elseif s:line2 =~ '^CVS:' || getline("$") =~ '^CVS: ' |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 223 | set ft=cvs |
| 224 | |
| 225 | " Send-pr |
| 226 | elseif s:line1 =~ '^SEND-PR:' |
| 227 | set ft=sendpr |
| 228 | |
| 229 | " SNNS files |
| 230 | elseif s:line1 =~ '^SNNS network definition file' |
| 231 | set ft=snnsnet |
| 232 | elseif s:line1 =~ '^SNNS pattern definition file' |
| 233 | set ft=snnspat |
| 234 | elseif s:line1 =~ '^SNNS result file' |
| 235 | set ft=snnsres |
| 236 | |
| 237 | " Virata |
| 238 | elseif s:line1 =~ '^%.\{-}[Vv]irata' |
| 239 | \ || s:line2 =~ '^%.\{-}[Vv]irata' |
| 240 | \ || s:line3 =~ '^%.\{-}[Vv]irata' |
| 241 | \ || s:line4 =~ '^%.\{-}[Vv]irata' |
| 242 | \ || s:line5 =~ '^%.\{-}[Vv]irata' |
| 243 | set ft=virata |
| 244 | |
| 245 | " Strace |
| 246 | elseif s:line1 =~ '^[0-9]* *execve(' |
| 247 | set ft=strace |
| 248 | |
| 249 | " VSE JCL |
| 250 | elseif s:line1 =~ '^\* $$ JOB\>' || s:line1 =~ '^// *JOB\>' |
| 251 | set ft=vsejcl |
| 252 | |
| 253 | " TAK and SINDA |
| 254 | elseif s:line4 =~ 'K & K Associates' || s:line2 =~ 'TAK 2000' |
| 255 | set ft=takout |
| 256 | elseif s:line3 =~ 'S Y S T E M S I M P R O V E D ' |
| 257 | set ft=sindaout |
| 258 | elseif getline(6) =~ 'Run Date: ' |
| 259 | set ft=takcmp |
| 260 | elseif getline(9) =~ 'Node File 1' |
| 261 | set ft=sindacmp |
| 262 | |
| 263 | " DNS zone files |
| 264 | elseif s:line1.s:line2 =~ '$ORIGIN\|$TTL\|IN\s*SOA' |
| 265 | \ || s:line1.s:line2.s:line3.s:line4 =~ 'BIND.*named' |
| 266 | set ft=dns |
| 267 | |
| 268 | " BAAN |
| 269 | elseif s:line1 =~ '|\*\{1,80}' && s:line2 =~ 'VRC ' |
| 270 | \ || s:line2 =~ '|\*\{1,80}' && s:line3 =~ 'VRC ' |
| 271 | set ft=baan |
| 272 | |
| 273 | " Valgrind |
| 274 | elseif s:line1 =~ '^==\d\+== valgrind' |
| 275 | set ft=valgrind |
| 276 | |
| 277 | " Renderman Interface Bytestream |
| 278 | elseif s:line1 =~ '^##RenderMan' |
| 279 | set ft=rib |
| 280 | |
| 281 | " Scheme scripts |
| 282 | elseif s:line1 =~ 'exec\s\+\S*scheme' || s:line2 =~ 'exec\s\+\S*scheme' |
| 283 | set ft=scheme |
| 284 | |
| 285 | " CVS diff |
| 286 | else |
| 287 | let lnum = 1 |
| 288 | while getline(lnum) =~ "^? " && lnum < line("$") |
| 289 | let lnum = lnum + 1 |
| 290 | endwhile |
| 291 | if getline(lnum) =~ '^Index:\s\+\f\+$' |
| 292 | set ft=diff |
| 293 | |
| 294 | " locale input files: Formal Definitions of Cultural Conventions |
| 295 | " filename must be like en_US, fr_FR@euro or en_US.UTF-8 |
| 296 | elseif expand("%") =~ '\a\a_\a\a\($\|[.@]\)\|i18n$\|POSIX$\|translit_' |
| 297 | let lnum = 1 |
| 298 | while lnum < 100 && lnum < line("$") |
| 299 | if getline(lnum) =~ '^LC_\(IDENTIFICATION\|CTYPE\|COLLATE\|MONETARY\|NUMERIC\|TIME\|MESSAGES\|PAPER\|TELEPHONE\|MEASUREMENT\|NAME\|ADDRESS\)$' |
| 300 | setf fdcc |
| 301 | break |
| 302 | endif |
| 303 | let lnum = lnum + 1 |
| 304 | endwhile |
| 305 | endif |
| 306 | |
| 307 | endif |
| 308 | |
| 309 | unlet s:line2 s:line3 s:line4 s:line5 |
| 310 | |
| 311 | endif |
| 312 | |
| 313 | " Restore 'cpoptions' |
| 314 | let &cpo = s:cpo_save |
| 315 | |
| 316 | unlet s:cpo_save s:line1 |