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