scripts.vim 11 KB

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