mirror of
https://github.com/sheerun/vim-polyglot.git
synced 2025-11-08 11:33:52 -05:00
545 lines
14 KiB
VimL
545 lines
14 KiB
VimL
" Line continuation is used here, remove 'C' from 'cpoptions'
|
|
let s:cpo_save = &cpo
|
|
set cpo&vim
|
|
|
|
func! polyglot#shebang#Detect()
|
|
let ft = s:Filetype()
|
|
if ft != ""
|
|
let &ft = ft
|
|
return 1
|
|
endif
|
|
|
|
let err = polyglot#shebang#VimDetect()
|
|
if err == ""
|
|
return 1
|
|
endif
|
|
|
|
return 0
|
|
endfunc
|
|
|
|
let s:r_hashbang = '^#!\s*\(\S\+\)\s*\(.*\)\s*'
|
|
let s:r_envflag = '%(\S\+=\S\+\|-[iS]\|--ignore-environment\|--split-string\)'
|
|
let s:r_env = '^\%(\' . s:r_envflag . '\s\+\)*\(\S\+\)'
|
|
|
|
func! s:Filetype()
|
|
let l:line1 = getline(1)
|
|
|
|
if l:line1 !~# "^#!"
|
|
return
|
|
endif
|
|
|
|
let l:pathrest = matchlist(l:line1, s:r_hashbang)
|
|
|
|
if len(l:pathrest) == 0
|
|
return
|
|
endif
|
|
|
|
let [_, l:path, l:rest; __] = l:pathrest
|
|
|
|
let l:pathparts = split(l:path, "/")
|
|
|
|
if len(l:pathparts) == 0
|
|
return
|
|
endif
|
|
|
|
let l:script = l:pathparts[-1]
|
|
|
|
if l:script == "env"
|
|
let l:argspath = matchlist(l:rest, s:r_env)
|
|
if len(l:argspath) == 0
|
|
return
|
|
endif
|
|
|
|
let l:script = l:argspath[1]
|
|
endif
|
|
|
|
if has_key(s:interpreters, l:script)
|
|
return s:interpreters[l:script]
|
|
endif
|
|
|
|
for interpreter in keys(s:interpreters)
|
|
if l:script =~# '^' . interpreter
|
|
return s:interpreters[interpreter]
|
|
endif
|
|
endfor
|
|
endfunc
|
|
|
|
func! polyglot#shebang#VimDetect()
|
|
let line1 = getline(1)
|
|
|
|
if line1 =~# "^#!"
|
|
" A script that starts with "#!".
|
|
|
|
" Check for a line like "#!/usr/bin/env {options} bash". Turn it into
|
|
" "#!/usr/bin/bash" to make matching easier.
|
|
" Recognize only a few {options} that are commonly used.
|
|
if line1 =~# '^#!\s*\S*\<env\s'
|
|
let line1 = substitute(line1, '\S\+=\S\+', '', 'g')
|
|
let line1 = substitute(line1, '\(-[iS]\|--ignore-environment\|--split-string\)', '', '')
|
|
let line1 = substitute(line1, '\<env\s\+', '', '')
|
|
endif
|
|
|
|
" Get the program name.
|
|
" Only accept spaces in PC style path "#!c:/program files/perl [args]".
|
|
" If the word env is used, use the first word after the space:
|
|
" "#!/usr/bin/env perl [path/args]"
|
|
" If there is no path use the first word: "#!perl [path/args]".
|
|
" Otherwise get the last word after a slash: "#!/usr/bin/perl [path/args]".
|
|
if line1 =~# '^#!\s*\a:[/\\]'
|
|
let name = substitute(line1, '^#!.*[/\\]\(\i\+\).*', '\1', '')
|
|
elseif line1 =~# '^#!.*\<env\>'
|
|
let name = substitute(line1, '^#!.*\<env\>\s\+\(\i\+\).*', '\1', '')
|
|
elseif line1 =~# '^#!\s*[^/\\ ]*\>\([^/\\]\|$\)'
|
|
let name = substitute(line1, '^#!\s*\([^/\\ ]*\>\).*', '\1', '')
|
|
else
|
|
let name = substitute(line1, '^#!\s*\S*[/\\]\(\i\+\).*', '\1', '')
|
|
endif
|
|
|
|
" tcl scripts may have #!/bin/sh in the first line and "exec wish" in the
|
|
" third line. Suggested by Steven Atkinson.
|
|
if getline(3) =~# '^exec wish'
|
|
let name = 'wish'
|
|
endif
|
|
|
|
" Bourne-like shell script bash bash2 ksh ksh93 sh
|
|
if name =~# '^\(bash\d*\|\|ksh\d*\|sh\)\>'
|
|
call dist#ft#SetFileTypeSH(line1) " defined in filetype.vim
|
|
return
|
|
|
|
" csh scripts
|
|
elseif name =~# '^csh\>'
|
|
if exists("g:filetype_csh")
|
|
call dist#ft#SetFileTypeShell(g:filetype_csh)
|
|
return
|
|
else
|
|
call dist#ft#SetFileTypeShell("csh")
|
|
return
|
|
endif
|
|
|
|
" tcsh scripts
|
|
elseif name =~# '^tcsh\>'
|
|
call dist#ft#SetFileTypeShell("tcsh")
|
|
return
|
|
|
|
" Z shell scripts
|
|
elseif name =~# '^zsh\>'
|
|
set ft=zsh | return
|
|
|
|
" TCL scripts
|
|
elseif name =~# '^\(tclsh\|wish\|expectk\|itclsh\|itkwish\)\>'
|
|
set ft=tcl | return
|
|
|
|
" Expect scripts
|
|
elseif name =~# '^expect\>'
|
|
set ft=expect | return
|
|
|
|
" Gnuplot scripts
|
|
elseif name =~# '^gnuplot\>'
|
|
set ft=gnuplot | return
|
|
|
|
" Makefiles
|
|
elseif name =~# 'make\>'
|
|
set ft=make | return
|
|
|
|
" Pike
|
|
elseif name =~# '^pike\%(\>\|[0-9]\)'
|
|
set ft=pike | return
|
|
|
|
" Lua
|
|
elseif name =~# 'lua'
|
|
set ft=lua | return
|
|
|
|
" Perl 6
|
|
elseif name =~# 'perl6'
|
|
set ft=perl6 | return
|
|
|
|
" Perl
|
|
elseif name =~# 'perl'
|
|
set ft=perl | return
|
|
|
|
" PHP
|
|
elseif name =~# 'php'
|
|
set ft=php | return
|
|
|
|
" Python
|
|
elseif name =~# 'python'
|
|
set ft=python | return
|
|
|
|
" Groovy
|
|
elseif name =~# '^groovy\>'
|
|
set ft=groovy | return
|
|
|
|
" Ruby
|
|
elseif name =~# 'ruby'
|
|
set ft=ruby | return
|
|
|
|
" JavaScript
|
|
elseif name =~# 'node\(js\)\=\>\|js\>' || name =~# 'rhino\>'
|
|
set ft=javascript | return
|
|
|
|
" BC calculator
|
|
elseif name =~# '^bc\>'
|
|
set ft=bc | return
|
|
|
|
" sed
|
|
elseif name =~# 'sed\>'
|
|
set ft=sed | return
|
|
|
|
" OCaml-scripts
|
|
elseif name =~# 'ocaml'
|
|
set ft=ocaml | return
|
|
|
|
" Awk scripts; also finds "gawk"
|
|
elseif name =~# 'awk\>'
|
|
set ft=awk | return
|
|
|
|
" Website MetaLanguage
|
|
elseif name =~# 'wml'
|
|
set ft=wml | return
|
|
|
|
" Scheme scripts
|
|
elseif name =~# 'scheme'
|
|
set ft=scheme | return
|
|
|
|
" CFEngine scripts
|
|
elseif name =~# 'cfengine'
|
|
set ft=cfengine | return
|
|
|
|
" Erlang scripts
|
|
elseif name =~# 'escript'
|
|
set ft=erlang | return
|
|
|
|
" Haskell
|
|
elseif name =~# 'haskell'
|
|
set ft=haskell | return
|
|
|
|
" Scala
|
|
elseif name =~# 'scala\>'
|
|
set ft=scala | return
|
|
|
|
" Clojure
|
|
elseif name =~# 'clojure'
|
|
set ft=clojure | return
|
|
|
|
endif
|
|
unlet name
|
|
|
|
else
|
|
" File does not start with "#!".
|
|
|
|
let line2 = getline(2)
|
|
let line3 = getline(3)
|
|
let line4 = getline(4)
|
|
let line5 = getline(5)
|
|
|
|
" Bourne-like shell script sh ksh bash bash2
|
|
if line1 =~# '^:$'
|
|
call dist#ft#SetFileTypeSH(line1) " defined in filetype.vim
|
|
return
|
|
|
|
" Z shell scripts
|
|
elseif line1 =~# '^#compdef\>' || line1 =~# '^#autoload\>' ||
|
|
\ "\n".line1."\n".line2."\n".line3."\n".line4."\n".line5 =~# '\n\s*emulate\s\+\%(-[LR]\s\+\)\=[ckz]\=sh\>'
|
|
set ft=zsh | return
|
|
|
|
" ELM Mail files
|
|
elseif line1 =~# '^From \([a-zA-Z][a-zA-Z_0-9\.=-]*\(@[^ ]*\)\=\|-\) .* \(19\|20\)\d\d$'
|
|
set ft=mail | return
|
|
|
|
" Mason
|
|
elseif line1 =~# '^<[%&].*>'
|
|
set ft=mason | return
|
|
|
|
" Vim scripts (must have '" vim' as the first line to trigger this)
|
|
elseif line1 =~# '^" *[vV]im$'
|
|
set ft=vim | return
|
|
|
|
" libcxx and libstdc++ standard library headers like "iostream" do not have
|
|
" an extension, recognize the Emacs file mode.
|
|
elseif line1 =~? '-\*-.*C++.*-\*-'
|
|
set ft=cpp | return
|
|
|
|
" MOO
|
|
elseif line1 =~# '^\*\* LambdaMOO Database, Format Version \%([1-3]\>\)\@!\d\+ \*\*$'
|
|
set ft=moo | return
|
|
|
|
" Diff file:
|
|
" - "diff" in first line (context diff)
|
|
" - "Only in " in first line
|
|
" - "--- " in first line and "+++ " in second line (unified diff).
|
|
" - "*** " in first line and "--- " in second line (context diff).
|
|
" - "# It was generated by makepatch " in the second line (makepatch diff).
|
|
" - "Index: <filename>" in the first line (CVS file)
|
|
" - "=== ", line of "=", "---", "+++ " (SVK diff)
|
|
" - "=== ", "--- ", "+++ " (bzr diff, common case)
|
|
" - "=== (removed|added|renamed|modified)" (bzr diff, alternative)
|
|
" - "# HG changeset patch" in first line (Mercurial export format)
|
|
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\)'
|
|
\ || (line1 =~# '^--- ' && line2 =~# '^+++ ')
|
|
\ || (line1 =~# '^\* looking for ' && line2 =~# '^\* comparing to ')
|
|
\ || (line1 =~# '^\*\*\* ' && line2 =~# '^--- ')
|
|
\ || (line1 =~# '^=== ' && ((line2 =~# '^=\{66\}' && line3 =~# '^--- ' && line4 =~# '^+++') || (line2 =~# '^--- ' && line3 =~# '^+++ ')))
|
|
\ || (line1 =~# '^=== \(removed\|added\|renamed\|modified\)')
|
|
set ft=diff | return
|
|
|
|
" PostScript Files (must have %!PS as the first line, like a2ps output)
|
|
elseif line1 =~# '^%![ \t]*PS'
|
|
set ft=postscr | return
|
|
|
|
" M4 script Guess there is a line that starts with "dnl".
|
|
elseif line1 =~# '^\s*dnl\>'
|
|
\ || line2 =~# '^\s*dnl\>'
|
|
\ || line3 =~# '^\s*dnl\>'
|
|
\ || line4 =~# '^\s*dnl\>'
|
|
\ || line5 =~# '^\s*dnl\>'
|
|
set ft=m4 | return
|
|
|
|
" AmigaDos scripts
|
|
elseif $TERM == "amiga"
|
|
\ && (line1 =~# "^;" || line1 =~? '^\.bra')
|
|
set ft=amiga | return
|
|
|
|
" SiCAD scripts (must have procn or procd as the first line to trigger this)
|
|
elseif line1 =~? '^ *proc[nd] *$'
|
|
set ft=sicad | return
|
|
|
|
" Purify log files start with "**** Purify"
|
|
elseif line1 =~# '^\*\*\*\* Purify'
|
|
set ft=purifylog | return
|
|
|
|
" XML
|
|
elseif line1 =~# '<?\s*xml.*?>'
|
|
set ft=xml | return
|
|
|
|
" XHTML (e.g.: PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN")
|
|
elseif line1 =~# '\<DTD\s\+XHTML\s'
|
|
set ft=xhtml | return
|
|
|
|
" HTML (e.g.: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN")
|
|
" Avoid "doctype html", used by slim.
|
|
elseif line1 =~? '<!DOCTYPE\s\+html\>'
|
|
set ft=html | return
|
|
|
|
" PDF
|
|
elseif line1 =~# '^%PDF-'
|
|
set ft=pdf | return
|
|
|
|
" XXD output
|
|
elseif line1 =~# '^\x\{7}: \x\{2} \=\x\{2} \=\x\{2} \=\x\{2} '
|
|
set ft=xxd | return
|
|
|
|
" RCS/CVS log output
|
|
elseif line1 =~# '^RCS file:' || line2 =~# '^RCS file:'
|
|
set ft=rcslog | return
|
|
|
|
" CVS commit
|
|
elseif line2 =~# '^CV' || getline("$") =~# '^CV '
|
|
set ft=cvs | return
|
|
|
|
" Prescribe
|
|
elseif line1 =~# '^!R!'
|
|
set ft=prescribe | return
|
|
|
|
" Send-pr
|
|
elseif line1 =~# '^SEND-PR:'
|
|
set ft=sendpr | return
|
|
|
|
" SNNS files
|
|
elseif line1 =~# '^SNNS network definition file'
|
|
set ft=snnsnet | return
|
|
elseif line1 =~# '^SNNS pattern definition file'
|
|
set ft=snnspat | return
|
|
elseif line1 =~# '^SNNS result file'
|
|
set ft=snnsres | return
|
|
|
|
" Virata
|
|
elseif line1 =~# '^%.\{-}[Vv]irata'
|
|
\ || line2 =~# '^%.\{-}[Vv]irata'
|
|
\ || line3 =~# '^%.\{-}[Vv]irata'
|
|
\ || line4 =~# '^%.\{-}[Vv]irata'
|
|
\ || line5 =~# '^%.\{-}[Vv]irata'
|
|
set ft=virata | return
|
|
|
|
" Strace
|
|
elseif line1 =~# '[0-9:.]* *execve(' || line1 =~# '^__libc_start_main'
|
|
set ft=strace | return
|
|
|
|
" VSE JCL
|
|
elseif line1 =~# '^\* $$ JOB\>' || line1 =~# '^// *JOB\>'
|
|
set ft=vsejcl | return
|
|
|
|
" TAK and SINDA
|
|
elseif line4 =~# 'K & K Associates' || line2 =~# 'TAK 2000'
|
|
set ft=takout | return
|
|
elseif line3 =~# 'S Y S T E M S I M P R O V E D '
|
|
set ft=sindaout | return
|
|
elseif getline(6) =~# 'Run Date: '
|
|
set ft=takcmp | return
|
|
elseif getline(9) =~# 'Node File 1'
|
|
set ft=sindacmp | return
|
|
|
|
" DNS zone files
|
|
elseif line1.line2.line3.line4 =~# '^; <<>> DiG [0-9.]\+.* <<>>\|$ORIGIN\|$TTL\|IN\s\+SOA'
|
|
set ft=bindzone | return
|
|
|
|
" BAAN
|
|
elseif line1 =~# '|\*\{1,80}' && line2 =~# 'VRC '
|
|
\ || line2 =~# '|\*\{1,80}' && line3 =~# 'VRC '
|
|
set ft=baan | return
|
|
|
|
" Valgrind
|
|
elseif line1 =~# '^==\d\+== valgrind' || line3 =~# '^==\d\+== Using valgrind'
|
|
set ft=valgrind | return
|
|
|
|
" Go docs
|
|
elseif line1 =~# '^PACKAGE DOCUMENTATION$'
|
|
set ft=godoc | return
|
|
|
|
" Renderman Interface Bytestream
|
|
elseif line1 =~# '^##RenderMan'
|
|
set ft=rib | return
|
|
|
|
" Scheme scripts
|
|
elseif line1 =~# 'exec\s\+\S*scheme' || line2 =~# 'exec\s\+\S*scheme'
|
|
set ft=scheme | return
|
|
|
|
" Git output
|
|
elseif line1 =~# '^\(commit\|tree\|object\) \x\{40\}\>\|^tag \S\+$'
|
|
set ft=git | return
|
|
|
|
" Gprof (gnu profiler)
|
|
elseif line1 == 'Flat profile:'
|
|
\ && line2 == ''
|
|
\ && line3 =~# '^Each sample counts as .* seconds.$'
|
|
set ft=gprof | return
|
|
|
|
" Erlang terms
|
|
" (See also: http://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html#Choosing-Modes)
|
|
elseif line1 =~? '-\*-.*erlang.*-\*-'
|
|
set ft=erlang | return
|
|
|
|
" YAML
|
|
elseif line1 =~# '^%YAML'
|
|
set ft=yaml | return
|
|
|
|
" CVS diff
|
|
else
|
|
let lnum = 1
|
|
while getline(lnum) =~# "^? " && lnum < line("$")
|
|
let lnum += 1
|
|
endwhile
|
|
if getline(lnum) =~# '^Index:\s\+\f\+$'
|
|
set ft=diff | return
|
|
|
|
" locale input file Formal Definitions of Cultural Conventions
|
|
" filename must be like en_US, fr_FR@euro or en_US.UTF-8
|
|
elseif expand("%") =~# '\a\a_\a\a\($\|[.@]\)\|i18n$\|POSIX$\|translit_'
|
|
let lnum = 1
|
|
while lnum < 100 && lnum < line("$")
|
|
if getline(lnum) =~# '^LC_\(IDENTIFICATION\|CTYPE\|COLLATE\|MONETARY\|NUMERIC\|TIME\|MESSAGES\|PAPER\|TELEPHONE\|MEASUREMENT\|NAME\|ADDRESS\)$'
|
|
setf fdcc | return
|
|
break
|
|
endif
|
|
let lnum += 1
|
|
endwhile
|
|
endif
|
|
unlet lnum
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
if line1 =~ '^# ' || getline(2) =~ '^# ' || getline(3) =~ '^# ' || getline(4) =~ '^# ' || getline(5) =~ '^# '
|
|
setf FALLBACK conf
|
|
return 1
|
|
endif
|
|
|
|
return 1
|
|
endfunc
|
|
|
|
" DO NOT EDIT CODE BELOW, IT IS GENERATED WITH MAKEFILE
|
|
|
|
let s:interpreters = {
|
|
\ 'osascript': 'applescript',
|
|
\ 'tcc': 'c',
|
|
\ 'bb': 'clojure',
|
|
\ 'coffee': 'coffee',
|
|
\ 'crystal': 'crystal',
|
|
\ 'dart': 'dart',
|
|
\ 'elixir': 'elixir',
|
|
\ 'escript': 'erlang',
|
|
\ 'fish': 'fish',
|
|
\ 'gnuplot': 'gnuplot',
|
|
\ 'groovy': 'groovy',
|
|
\ 'runghc': 'haskell',
|
|
\ 'runhaskell': 'haskell',
|
|
\ 'runhugs': 'haskell',
|
|
\ 'chakra': 'javascript',
|
|
\ 'd8': 'javascript',
|
|
\ 'gjs': 'javascript',
|
|
\ 'js': 'javascript',
|
|
\ 'node': 'javascript',
|
|
\ 'nodejs': 'javascript',
|
|
\ 'qjs': 'javascript',
|
|
\ 'rhino': 'javascript',
|
|
\ 'v8': 'javascript',
|
|
\ 'v8-shell': 'javascript',
|
|
\ 'julia': 'julia',
|
|
\ 'lua': 'lua',
|
|
\ 'moon': 'moon',
|
|
\ 'nft': 'nftables',
|
|
\ 'ocaml': 'ocaml',
|
|
\ 'ocamlrun': 'ocaml',
|
|
\ 'ocamlscript': 'ocaml',
|
|
\ 'cperl': 'perl',
|
|
\ 'perl': 'perl',
|
|
\ 'php': 'php',
|
|
\ 'swipl': 'prolog',
|
|
\ 'yap': 'prolog',
|
|
\ 'pwsh': 'ps1',
|
|
\ 'python': 'python',
|
|
\ 'python2': 'python',
|
|
\ 'python3': 'python',
|
|
\ 'py': 'python',
|
|
\ 'pypy': 'python',
|
|
\ 'pypy3': 'python',
|
|
\ 'qmake': 'qmake',
|
|
\ 'Rscript': 'r',
|
|
\ 'racket': 'racket',
|
|
\ 'perl6': 'raku',
|
|
\ 'raku': 'raku',
|
|
\ 'rakudo': 'raku',
|
|
\ 'ruby': 'ruby',
|
|
\ 'macruby': 'ruby',
|
|
\ 'rake': 'ruby',
|
|
\ 'jruby': 'ruby',
|
|
\ 'rbx': 'ruby',
|
|
\ 'rust-script': 'rust',
|
|
\ 'scala': 'scala',
|
|
\ 'ash': 'sh',
|
|
\ 'bash': 'sh',
|
|
\ 'dash': 'sh',
|
|
\ 'ksh': 'sh',
|
|
\ 'mksh': 'sh',
|
|
\ 'pdksh': 'sh',
|
|
\ 'rc': 'sh',
|
|
\ 'sh': 'sh',
|
|
\ 'boolector': 'smt2',
|
|
\ 'cvc4': 'smt2',
|
|
\ 'mathsat5': 'smt2',
|
|
\ 'opensmt': 'smt2',
|
|
\ 'smtinterpol': 'smt2',
|
|
\ 'smt-rat': 'smt2',
|
|
\ 'stp': 'smt2',
|
|
\ 'verit': 'smt2',
|
|
\ 'yices2': 'smt2',
|
|
\ 'z3': 'smt2',
|
|
\ 'deno': 'typescript',
|
|
\ 'ts-node': 'typescript',
|
|
\ 'zsh': 'zsh',
|
|
\ }
|
|
" DO NOT EDIT CODE ABOVE, IT IS GENERATED WITH MAKEFILE
|
|
|
|
let &cpo = s:cpo_save
|
|
unlet s:cpo_save
|