blob: c184bd032d3ccafb3d78de23af0297b3bf5d7d85 [file] [log] [blame]
Bram Moolenaar299d8e52022-02-13 20:32:02 +00001vim9script
2
3# Vim function for detecting a filetype from the file contents.
4# Invoked from "scripts.vim" in 'runtimepath'
5#
Christian Brabandte978b452023-08-13 10:33:05 +02006# Maintainer: The Vim Project <https://github.com/vim/vim>
Eisuke Kawashimaf102f4c2025-04-24 22:03:21 +02007# Last Change: 2025 Apr 24
Christian Brabandte978b452023-08-13 10:33:05 +02008# Former Maintainer: Bram Moolenaar <Bram@vim.org>
Bram Moolenaar299d8e52022-02-13 20:32:02 +00009
10export def DetectFiletype()
11 var line1 = getline(1)
12 if line1[0] == '#' && line1[1] == '!'
13 # File that starts with "#!".
14 DetectFromHashBang(line1)
15 else
16 # File does not start with "#!".
17 DetectFromText(line1)
18 endif
19enddef
20
21# Called for a script that has "#!" in the first line.
22def DetectFromHashBang(firstline: string)
23 var line1 = firstline
24
25 # Check for a line like "#!/usr/bin/env {options} bash". Turn it into
26 # "#!/usr/bin/bash" to make matching easier.
27 # Recognize only a few {options} that are commonly used.
28 if line1 =~ '^#!\s*\S*\<env\s'
Eisuke Kawashimaf102f4c2025-04-24 22:03:21 +020029 line1 = substitute(line1, '\s\zs--split-string[ \t=]', '', '')
30 line1 = substitute(line1, '\s\zs[A-Za-z0-9_]\+=\S*\ze\s', '', 'g')
31 line1 = substitute(line1, '\s\zs\%(-[iS]\+\|--ignore-environment\)\ze\s', '', 'g')
Bram Moolenaar299d8e52022-02-13 20:32:02 +000032 line1 = substitute(line1, '\<env\s\+', '', '')
33 endif
34
35 # Get the program name.
36 # Only accept spaces in PC style paths: "#!c:/program files/perl [args]".
37 # If the word env is used, use the first word after the space:
38 # "#!/usr/bin/env perl [path/args]"
39 # If there is no path use the first word: "#!perl [path/args]".
40 # Otherwise get the last word after a slash: "#!/usr/bin/perl [path/args]".
41 var name: string
42 if line1 =~ '^#!\s*\a:[/\\]'
43 name = substitute(line1, '^#!.*[/\\]\(\i\+\).*', '\1', '')
44 elseif line1 =~ '^#!.*\<env\>'
45 name = substitute(line1, '^#!.*\<env\>\s\+\(\i\+\).*', '\1', '')
46 elseif line1 =~ '^#!\s*[^/\\ ]*\>\([^/\\]\|$\)'
47 name = substitute(line1, '^#!\s*\([^/\\ ]*\>\).*', '\1', '')
48 else
Bram Moolenaar19548c62023-06-08 21:27:13 +010049 name = substitute(line1, '^#!\s*\S*[/\\]\(\f\+\).*', '\1', '')
Bram Moolenaar299d8e52022-02-13 20:32:02 +000050 endif
51
52 # tcl scripts may have #!/bin/sh in the first line and "exec wish" in the
53 # third line. Suggested by Steven Atkinson.
54 if getline(3) =~ '^exec wish'
55 name = 'wish'
56 endif
57
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010058 var ft = Exe2filetype(name, line1)
59 if ft != ''
60 exe 'setl ft=' .. ft
61 endif
62enddef
63
64# Returns the filetype name associated with program "name".
65# "line1" is the #! line at the top of the file. Use the same as "name" if
66# not available.
67# Returns an empty string when not recognized.
68export def Exe2filetype(name: string, line1: string): string
Eisuke Kawashima24482fb2022-11-24 10:58:10 +000069 # Bourne-like shell scripts: bash bash2 dash ksh ksh93 sh
70 if name =~ '^\(bash\d*\|dash\|ksh\d*\|sh\)\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010071 return dist#ft#SetFileTypeSH(line1, false)
Bram Moolenaar299d8e52022-02-13 20:32:02 +000072
73 # csh scripts
74 elseif name =~ '^csh\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010075 return dist#ft#SetFileTypeShell(exists("g:filetype_csh") ? g:filetype_csh : 'csh', false)
Bram Moolenaar299d8e52022-02-13 20:32:02 +000076
77 # tcsh scripts
78 elseif name =~ '^tcsh\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010079 return dist#ft#SetFileTypeShell("tcsh", false)
Bram Moolenaar299d8e52022-02-13 20:32:02 +000080
81 # Z shell scripts
82 elseif name =~ '^zsh\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010083 return 'zsh'
Bram Moolenaar299d8e52022-02-13 20:32:02 +000084
85 # TCL scripts
86 elseif name =~ '^\(tclsh\|wish\|expectk\|itclsh\|itkwish\)\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010087 return 'tcl'
Bram Moolenaar299d8e52022-02-13 20:32:02 +000088
89 # Expect scripts
90 elseif name =~ '^expect\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010091 return 'expect'
Bram Moolenaar299d8e52022-02-13 20:32:02 +000092
93 # Gnuplot scripts
94 elseif name =~ '^gnuplot\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010095 return 'gnuplot'
Bram Moolenaar299d8e52022-02-13 20:32:02 +000096
97 # Makefiles
98 elseif name =~ 'make\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +010099 return 'make'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000100
101 # Pike
102 elseif name =~ '^pike\%(\>\|[0-9]\)'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100103 return 'pike'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000104
105 # Lua
106 elseif name =~ 'lua'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100107 return 'lua'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000108
109 # Perl
110 elseif name =~ 'perl'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100111 return 'perl'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000112
113 # PHP
114 elseif name =~ 'php'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100115 return 'php'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000116
117 # Python
118 elseif name =~ 'python'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100119 return 'python'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000120
121 # Groovy
122 elseif name =~ '^groovy\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100123 return 'groovy'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000124
125 # Raku
126 elseif name =~ 'raku'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100127 return 'raku'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000128
129 # Ruby
130 elseif name =~ 'ruby'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100131 return 'ruby'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000132
133 # JavaScript
134 elseif name =~ 'node\(js\)\=\>\|js\>' || name =~ 'rhino\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100135 return 'javascript'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000136
Peter Benjamin72755b32025-01-20 21:56:41 +0100137 elseif name =~# 'just'
138 return 'just'
139
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000140 # BC calculator
141 elseif name =~ '^bc\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100142 return 'bc'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000143
144 # sed
145 elseif name =~ 'sed\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100146 return 'sed'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000147
148 # OCaml-scripts
149 elseif name =~ 'ocaml'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100150 return 'ocaml'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000151
152 # Awk scripts; also finds "gawk"
153 elseif name =~ 'awk\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100154 return 'awk'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000155
156 # Website MetaLanguage
157 elseif name =~ 'wml'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100158 return 'wml'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000159
160 # Scheme scripts
161 elseif name =~ 'scheme'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100162 return 'scheme'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000163
164 # CFEngine scripts
165 elseif name =~ 'cfengine'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100166 return 'cfengine'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000167
168 # Erlang scripts
169 elseif name =~ 'escript'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100170 return 'erlang'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000171
172 # Haskell
173 elseif name =~ 'haskell'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100174 return 'haskell'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000175
176 # Scala
177 elseif name =~ 'scala\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100178 return 'scala'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000179
180 # Clojure
181 elseif name =~ 'clojure'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100182 return 'clojure'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000183
184 # Free Pascal
185 elseif name =~ 'instantfpc\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100186 return 'pascal'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000187
188 # Fennel
189 elseif name =~ 'fennel\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100190 return 'fennel'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000191
192 # MikroTik RouterOS script
193 elseif name =~ 'rsc\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100194 return 'routeros'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000195
196 # Fish shell
197 elseif name =~ 'fish\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100198 return 'fish'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000199
200 # Gforth
201 elseif name =~ 'gforth\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100202 return 'forth'
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000203
Bram Moolenaarbf661462022-06-16 13:27:18 +0100204 # Icon
205 elseif name =~ 'icon\>'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100206 return 'icon'
Bram Moolenaarbf661462022-06-16 13:27:18 +0100207
Bram Moolenaar32447802022-07-05 21:56:39 +0100208 # Guile
209 elseif name =~ 'guile'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100210 return 'scheme'
Bram Moolenaar32447802022-07-05 21:56:39 +0100211
Bram Moolenaar19548c62023-06-08 21:27:13 +0100212 # Nix
213 elseif name =~ 'nix-shell'
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100214 return 'nix'
Bram Moolenaar19548c62023-06-08 21:27:13 +0100215
Doug Kearns9b739022023-08-27 19:51:37 +0200216 # Crystal
217 elseif name =~ '^crystal\>'
218 return 'crystal'
219
Doug Kearnse06afb72023-08-29 22:21:35 +0200220 # Rexx
221 elseif name =~ '^\%(rexx\|regina\)\>'
222 return 'rexx'
223
Doug Kearnsc0384272023-10-23 19:24:05 +0200224 # Janet
225 elseif name =~ '^janet\>'
226 return 'janet'
227
Doug Kearnsc1c177a2023-10-28 21:19:54 +0200228 # Dart
229 elseif name =~ '^dart\>'
230 return 'dart'
231
Mazunki Hoksaas63210c22023-12-19 20:44:41 +0100232 # Execline (s6)
233 elseif name =~ '^execlineb\>'
234 return 'execline'
235
Doug Kearns0d4d23d2024-06-16 08:32:15 +0200236 # Vim
237 elseif name =~ '^vim\>'
238 return 'vim'
239
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000240 endif
Bram Moolenaarf07d1a72023-06-09 21:01:47 +0100241
242 return ''
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000243enddef
244
245
246# Called for a script that does not have "#!" in the first line.
247def DetectFromText(line1: string)
248 var line2 = getline(2)
249 var line3 = getline(3)
250 var line4 = getline(4)
251 var line5 = getline(5)
252
253 # Bourne-like shell scripts: sh ksh bash bash2
254 if line1 =~ '^:$'
255 call dist#ft#SetFileTypeSH(line1)
256
257 # Z shell scripts
258 elseif line1 =~ '^#compdef\>'
259 || line1 =~ '^#autoload\>'
260 || "\n" .. line1 .. "\n" .. line2 .. "\n" .. line3 ..
261 "\n" .. line4 .. "\n" .. line5
262 =~ '\n\s*emulate\s\+\%(-[LR]\s\+\)\=[ckz]\=sh\>'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100263 setl ft=zsh
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000264
265 # ELM Mail files
266 elseif line1 =~ '^From \([a-zA-Z][a-zA-Z_0-9\.=-]*\(@[^ ]*\)\=\|-\) .* \(19\|20\)\d\d$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100267 setl ft=mail
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000268
269 # Mason
270 elseif line1 =~ '^<[%&].*>'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100271 setl ft=mason
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000272
273 # Vim scripts (must have '" vim' as the first line to trigger this)
274 elseif line1 =~ '^" *[vV]im$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100275 setl ft=vim
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000276
277 # libcxx and libstdc++ standard library headers like "iostream" do not have
278 # an extension, recognize the Emacs file mode.
279 elseif line1 =~? '-\*-.*C++.*-\*-'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100280 setl ft=cpp
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000281
282 # MOO
283 elseif line1 =~ '^\*\* LambdaMOO Database, Format Version \%([1-3]\>\)\@!\d\+ \*\*$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100284 setl ft=moo
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000285
286 # Diff file:
287 # - "diff" in first line (context diff)
288 # - "Only in " in first line
289 # - "--- " in first line and "+++ " in second line (unified diff).
290 # - "*** " in first line and "--- " in second line (context diff).
291 # - "# It was generated by makepatch " in the second line (makepatch diff).
292 # - "Index: <filename>" in the first line (CVS file)
293 # - "=== ", line of "=", "---", "+++ " (SVK diff)
294 # - "=== ", "--- ", "+++ " (bzr diff, common case)
295 # - "=== (removed|added|renamed|modified)" (bzr diff, alternative)
296 # - "# HG changeset patch" in first line (Mercurial export format)
297 elseif line1 =~ '^\(diff\>\|Only in \|\d\+\(,\d\+\)\=[cda]\d\+\>\|# It was generated by makepatch \|Index:\s\+\f\+\r\=$\|===== \f\+ \d\+\.\d\+ vs edited\|==== //\f\+#\d\+\|# HG changeset patch\)'
298 || (line1 =~ '^--- ' && line2 =~ '^+++ ')
299 || (line1 =~ '^\* looking for ' && line2 =~ '^\* comparing to ')
300 || (line1 =~ '^\*\*\* ' && line2 =~ '^--- ')
301 || (line1 =~ '^=== ' && ((line2 =~ '^=\{66\}' && line3 =~ '^--- ' && line4 =~ '^+++') || (line2 =~ '^--- ' && line3 =~ '^+++ ')))
302 || (line1 =~ '^=== \(removed\|added\|renamed\|modified\)')
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100303 setl ft=diff
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000304
305 # PostScript Files (must have %!PS as the first line, like a2ps output)
306 elseif line1 =~ '^%![ \t]*PS'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100307 setl ft=postscr
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000308
309 # M4 scripts: Guess there is a line that starts with "dnl".
310 elseif line1 =~ '^\s*dnl\>'
311 || line2 =~ '^\s*dnl\>'
312 || line3 =~ '^\s*dnl\>'
313 || line4 =~ '^\s*dnl\>'
314 || line5 =~ '^\s*dnl\>'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100315 setl ft=m4
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000316
317 # AmigaDos scripts
318 elseif $TERM == "amiga" && (line1 =~ "^;" || line1 =~? '^\.bra')
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100319 setl ft=amiga
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000320
321 # SiCAD scripts (must have procn or procd as the first line to trigger this)
322 elseif line1 =~? '^ *proc[nd] *$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100323 setl ft=sicad
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000324
325 # Purify log files start with "**** Purify"
326 elseif line1 =~ '^\*\*\*\* Purify'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100327 setl ft=purifylog
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000328
329 # XML
330 elseif line1 =~ '<?\s*xml.*?>'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100331 setl ft=xml
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000332
333 # XHTML (e.g.: PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN")
334 elseif line1 =~ '\<DTD\s\+XHTML\s'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100335 setl ft=xhtml
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000336
337 # HTML (e.g.: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN")
338 # Avoid "doctype html", used by slim.
339 elseif line1 =~? '<!DOCTYPE\s\+html\>'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100340 setl ft=html
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000341
342 # PDF
343 elseif line1 =~ '^%PDF-'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100344 setl ft=pdf
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000345
346 # XXD output
347 elseif line1 =~ '^\x\{7}: \x\{2} \=\x\{2} \=\x\{2} \=\x\{2} '
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100348 setl ft=xxd
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000349
350 # RCS/CVS log output
351 elseif line1 =~ '^RCS file:' || line2 =~ '^RCS file:'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100352 setl ft=rcslog
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000353
354 # CVS commit
355 elseif line2 =~ '^CVS:' || getline("$") =~ '^CVS: '
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100356 setl ft=cvs
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000357
358 # Prescribe
359 elseif line1 =~ '^!R!'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100360 setl ft=prescribe
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000361
362 # Send-pr
363 elseif line1 =~ '^SEND-PR:'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100364 setl ft=sendpr
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000365
366 # SNNS files
367 elseif line1 =~ '^SNNS network definition file'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100368 setl ft=snnsnet
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000369 elseif line1 =~ '^SNNS pattern definition file'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100370 setl ft=snnspat
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000371 elseif line1 =~ '^SNNS result file'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100372 setl ft=snnsres
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000373
374 # Virata
375 elseif line1 =~ '^%.\{-}[Vv]irata'
376 || line2 =~ '^%.\{-}[Vv]irata'
377 || line3 =~ '^%.\{-}[Vv]irata'
378 || line4 =~ '^%.\{-}[Vv]irata'
379 || line5 =~ '^%.\{-}[Vv]irata'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100380 setl ft=virata
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000381
382 # Strace
Federico Mengozzi6e5a9f92023-04-17 22:31:38 +0100383 # inaccurate fast match first, then use accurate slow match
Jiri Slaby2f54c132023-11-04 09:39:54 +0100384 elseif (line1 =~ 'execve(' && line1 =~ '^[0-9:. ]*execve(')
Federico Mengozzi6e5a9f92023-04-17 22:31:38 +0100385 || line1 =~ '^__libc_start_main'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100386 setl ft=strace
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000387
388 # VSE JCL
389 elseif line1 =~ '^\* $$ JOB\>' || line1 =~ '^// *JOB\>'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100390 setl ft=vsejcl
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000391
392 # TAK and SINDA
393 elseif line4 =~ 'K & K Associates' || line2 =~ 'TAK 2000'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100394 setl ft=takout
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000395 elseif line3 =~ 'S Y S T E M S I M P R O V E D '
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100396 setl ft=sindaout
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000397 elseif getline(6) =~ 'Run Date: '
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100398 setl ft=takcmp
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000399 elseif getline(9) =~ 'Node File 1'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100400 setl ft=sindacmp
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000401
402 # DNS zone files
403 elseif line1 .. line2 .. line3 .. line4 =~ '^; <<>> DiG [0-9.]\+.* <<>>\|$ORIGIN\|$TTL\|IN\s\+SOA'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100404 setl ft=bindzone
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000405
406 # BAAN
407 elseif line1 =~ '|\*\{1,80}' && line2 =~ 'VRC '
408 || line2 =~ '|\*\{1,80}' && line3 =~ 'VRC '
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100409 setl ft=baan
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000410
411 # Valgrind
412 elseif line1 =~ '^==\d\+== valgrind' || line3 =~ '^==\d\+== Using valgrind'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100413 setl ft=valgrind
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000414
415 # Go docs
416 elseif line1 =~ '^PACKAGE DOCUMENTATION$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100417 setl ft=godoc
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000418
419 # Renderman Interface Bytestream
420 elseif line1 =~ '^##RenderMan'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100421 setl ft=rib
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000422
423 # Scheme scripts
424 elseif line1 =~ 'exec\s\+\S*scheme' || line2 =~ 'exec\s\+\S*scheme'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100425 setl ft=scheme
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000426
427 # Git output
428 elseif line1 =~ '^\(commit\|tree\|object\) \x\{40,\}\>\|^tag \S\+$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100429 setl ft=git
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000430
431 # Gprof (gnu profiler)
432 elseif line1 == 'Flat profile:'
433 && line2 == ''
434 && line3 =~ '^Each sample counts as .* seconds.$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100435 setl ft=gprof
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000436
437 # Erlang terms
438 # (See also: http://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html#Choosing-Modes)
439 elseif line1 =~? '-\*-.*erlang.*-\*-'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100440 setl ft=erlang
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000441
442 # YAML
443 elseif line1 =~ '^%YAML'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100444 setl ft=yaml
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000445
446 # MikroTik RouterOS script
447 elseif line1 =~ '^#.*by RouterOS.*$'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100448 setl ft=routeros
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000449
450 # Sed scripts
451 # #ncomment is allowed but most likely a false positive so require a space
452 # before any trailing comment text
453 elseif line1 =~ '^#n\%($\|\s\)'
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100454 setl ft=sed
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000455
456 else
457 var lnum = 1
458 while getline(lnum) =~ "^? " && lnum < line("$")
459 lnum += 1
460 endwhile
461 if getline(lnum) =~ '^Index:\s\+\f\+$'
462 # CVS diff
Bram Moolenaar0b70aeb2023-05-06 21:21:52 +0100463 setl ft=diff
Bram Moolenaar299d8e52022-02-13 20:32:02 +0000464
465 # locale input files: Formal Definitions of Cultural Conventions
466 # filename must be like en_US, fr_FR@euro or en_US.UTF-8
467 elseif expand("%") =~ '\a\a_\a\a\($\|[.@]\)\|i18n$\|POSIX$\|translit_'
468 lnum = 1
469 while lnum < 100 && lnum < line("$")
470 if getline(lnum) =~ '^LC_\(IDENTIFICATION\|CTYPE\|COLLATE\|MONETARY\|NUMERIC\|TIME\|MESSAGES\|PAPER\|TELEPHONE\|MEASUREMENT\|NAME\|ADDRESS\)$'
471 setf fdcc
472 break
473 endif
474 lnum += 1
475 endwhile
476 endif
477 endif
478enddef