diff options
| author | Adam Stankiewicz <sheerun@sher.pl> | 2020-09-29 21:48:38 +0200 | 
|---|---|---|
| committer | Adam Stankiewicz <sheerun@sher.pl> | 2020-09-29 21:48:38 +0200 | 
| commit | 543e8c917beddea04099ce9fe28e780ef7bda7fa (patch) | |
| tree | 575b5f24e0d0f59b7b550f90f7aabe988178da65 | |
| parent | 2f133372bc19259888036c659cc618299ae5df59 (diff) | |
| download | vim-polyglot-543e8c917beddea04099ce9fe28e780ef7bda7fa.tar.gz vim-polyglot-543e8c917beddea04099ce9fe28e780ef7bda7fa.zip | |
Modularize lazy loading of polyglot parts
Diffstat (limited to '')
| -rw-r--r-- | autoload/polyglot.vim | 705 | ||||
| -rw-r--r-- | autoload/polyglot/detect.vim | 262 | ||||
| -rw-r--r-- | autoload/polyglot/shebang.vim | 129 | ||||
| -rw-r--r-- | autoload/polyglot/sleuth.vim (renamed from autoload/sleuth.vim) | 2 | ||||
| -rw-r--r-- | ftdetect/polyglot.vim | 73 | ||||
| -rw-r--r-- | heuristics.yaml | 6 | ||||
| -rw-r--r-- | polyglot.vim | 34 | ||||
| -rwxr-xr-x | scripts/build | 56 | ||||
| -rw-r--r-- | tests/extensions.vim | 1 | 
9 files changed, 480 insertions, 788 deletions
| diff --git a/autoload/polyglot.vim b/autoload/polyglot.vim deleted file mode 100644 index 33210855..00000000 --- a/autoload/polyglot.vim +++ /dev/null @@ -1,705 +0,0 @@ -" Please do not edit this file directly, instead modify polyglot.vim or scripts/build - -" Line continuation is used here, remove 'C' from 'cpoptions' -let s:cpo_save = &cpo -set cpo&vim - -func! polyglot#Shebang() -  if getline(1) =~# "^#!" -    let ft = polyglot#ShebangFiletype() -    if ft != "" -      let &ft = ft -    endif -  endif - -  if &ft == "" -    runtime! scripts.vim -  endif - -  return &ft != "" -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! polyglot#ShebangFiletype() -  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:script = split(l:path, "/")[-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 - -let s:interpreters = { -  \ 'osascript': 'applescript', -  \ 'tcc': 'c', -  \ 'coffee': 'coffee', -  \ 'crystal': 'crystal', -  \ 'dart': 'dart', -  \ 'elixir': 'elixir', -  \ 'escript': 'erlang', -  \ 'fish': 'fish', -  \ 'gnuplot': 'gnuplot', -  \ 'groovy': 'groovy', -  \ 'runhaskell': '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', -  \ 'ocaml': 'ocaml', -  \ 'ocamlrun': 'ocaml', -  \ 'ocamlscript': 'ocaml', -  \ 'cperl': 'perl', -  \ 'perl': 'perl', -  \ 'php': 'php', -  \ 'swipl': 'prolog', -  \ 'yap': 'prolog', -  \ 'pwsh': 'ps1', -  \ 'python': 'python', -  \ 'python2': 'python', -  \ 'python3': 'python', -  \ 'qmake': 'qmake', -  \ 'Rscript': 'r', -  \ 'racket': 'racket', -  \ 'perl6': 'raku', -  \ 'raku': 'raku', -  \ 'rakudo': 'raku', -  \ 'ruby': 'ruby', -  \ 'macruby': 'ruby', -  \ 'rake': 'ruby', -  \ 'jruby': 'ruby', -  \ 'rbx': 'ruby', -  \ 'scala': 'scala', -  \ 'ash': 'sh', -  \ 'bash': 'sh', -  \ 'dash': 'sh', -  \ 'ksh': 'sh', -  \ 'mksh': 'sh', -  \ 'pdksh': 'sh', -  \ 'rc': 'sh', -  \ 'sh': 'sh', -  \ 'zsh': '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', -\ } - -func! polyglot#DetectInpFiletype() -  let line = getline(nextnonblank(1)) -  if line =~# '^\*' -    set ft=abaqus | return -  endif -  for lnum in range(1, min([line("$"), 500])) -    let line = getline(lnum) -    if line =~? '^header surface data' -      set ft=trasys | return -    endif -  endfor -endfunc - -func! polyglot#DetectAsaFiletype() -  if exists("g:filetype_asa") -    let &ft = g:filetype_asa | return -  endif -  set ft=aspvbs | return -endfunc - -func! polyglot#DetectAspFiletype() -  if exists("g:filetype_asp") -    let &ft = g:filetype_asp | return -  endif -  for lnum in range(1, min([line("$"), 3])) -    let line = getline(lnum) -    if line =~? 'perlscript' -      set ft=aspperl | return -    endif -  endfor -  set ft=aspvbs | return -endfunc - -func! polyglot#DetectHFiletype() -  for lnum in range(1, min([line("$"), 200])) -    let line = getline(lnum) -    if line =~# '^\s*\(@\(interface\|class\|protocol\|property\|end\|synchronised\|selector\|implementation\)\(\<\|\>\)\|#import\s\+.\+\.h[">]\)' -      if exists("g:c_syntax_for_h") -        set ft=objc | return -      endif -      set ft=objcpp | return -    endif -  endfor -  if exists("g:c_syntax_for_h") -    set ft=c | return -  endif -  if exists("g:ch_syntax_for_h") -    set ft=ch | return -  endif -  set ft=cpp | return -endfunc - -func! polyglot#DetectMFiletype() -  let saw_comment = 0 -  for lnum in range(1, min([line("$"), 100])) -    let line = getline(lnum) -    if line =~# '^\s*/\*' -      let saw_comment = 1 -    endif -    if line =~# '^\s*\(@\(interface\|class\|protocol\|property\|end\|synchronised\|selector\|implementation\)\(\<\|\>\)\|#import\s\+.\+\.h[">]\)' -      set ft=objc | return -    endif -    if line =~# '^\s*%' -      set ft=octave | return -    endif -    if line =~# '^\s*(\*' -      set ft=mma | return -    endif -    if line =~? '^\s*\(\(type\|var\)\(\<\|\>\)\|--\)' -      set ft=murphi | return -    endif -  endfor -  if saw_comment -    set ft=objc | return -  endif -  if exists("g:filetype_m") -    let &ft = g:filetype_m | return -  endif -  set ft=octave | return -endfunc - -func! polyglot#DetectFsFiletype() -  for lnum in range(1, min([line("$"), 50])) -    let line = getline(lnum) -    if line =~# '^\(: \|new-device\)' -      set ft=forth | return -    endif -    if line =~# '^\s*\(#light\|import\|let\|module\|namespace\|open\|type\)' -      set ft=fsharp | return -    endif -    if line =~# '\s*\(#version\|precision\|uniform\|varying\|vec[234]\)' -      set ft=glsl | return -    endif -  endfor -  if exists("g:filetype_fs") -    let &ft = g:filetype_fs | return -  endif -  set ft=forth | return -endfunc - -func! polyglot#DetectReFiletype() -  for lnum in range(1, min([line("$"), 50])) -    let line = getline(lnum) -    if line =~# '^\s*#\%(\%(if\|ifdef\|define\|pragma\)\s\+\w\|\s*include\s\+[<"]\|template\s*<\)' -      set ft=cpp | return -    endif -    set ft=reason | return -  endfor -endfunc - -func! polyglot#DetectIdrFiletype() -  for lnum in range(1, min([line("$"), 5])) -    let line = getline(lnum) -    if line =~# '^\s*--.*[Ii]dris \=1' -      set ft=idris | return -    endif -    if line =~# '^\s*--.*[Ii]dris \=2' -      set ft=idris2 | return -    endif -  endfor -  for lnum in range(1, min([line("$"), 30])) -    let line = getline(lnum) -    if line =~# '^pkgs =.*' -      set ft=idris | return -    endif -    if line =~# '^depends =.*' -      set ft=idris2 | return -    endif -    if line =~# '^%language \(TypeProviders\|ElabReflection\)' -      set ft=idris | return -    endif -    if line =~# '^%language PostfixProjections' -      set ft=idris2 | return -    endif -    if line =~# '^%access .*' -      set ft=idris | return -    endif -  endfor -  if exists("g:filetype_idr") -    let &ft = g:filetype_idr | return -  endif -  set ft=idris2 | return -endfunc - -func! polyglot#DetectLidrFiletype() -  for lnum in range(1, min([line("$"), 200])) -    let line = getline(lnum) -    if line =~# '^>\s*--.*[Ii]dris \=1' -      set ft=lidris | return -    endif -  endfor -  set ft=lidris2 | return -endfunc - -func! polyglot#DetectBasFiletype() -  for lnum in range(1, min([line("$"), 5])) -    let line = getline(lnum) -    if line =~? 'VB_Name\|Begin VB\.\(Form\|MDIForm\|UserControl\)' -      set ft=vb | return -    endif -  endfor -  set ft=basic | return -endfunc - -func! polyglot#DetectPmFiletype() -  let line = getline(nextnonblank(1)) -  if line =~# 'XPM2' -    set ft=xpm2 | return -  endif -  if line =~# 'XPM' -    set ft=xpm | return -  endif -  for lnum in range(1, min([line("$"), 50])) -    let line = getline(lnum) -    if line =~# '^\s*\%(use\s\+v6\(\<\|\>\)\|\(\<\|\>\)module\(\<\|\>\)\|\(\<\|\>\)\%(my\s\+\)\=class\(\<\|\>\)\)' -      set ft=raku | return -    endif -    if line =~# '\(\<\|\>\)use\s\+\%(strict\(\<\|\>\)\|v\=5\.\)' -      set ft=perl | return -    endif -  endfor -  if exists("g:filetype_pm") -    let &ft = g:filetype_pm | return -  endif -  set ft=perl | return -endfunc - -func! polyglot#DetectPlFiletype() -  let line = getline(nextnonblank(1)) -  if line =~# '^[^#]*:-' || line =~# '^\s*\%(%\|/\*\)' || line =~# '\.\s*$' -    set ft=prolog | return -  endif -  for lnum in range(1, min([line("$"), 50])) -    let line = getline(lnum) -    if line =~# '^\s*\%(use\s\+v6\(\<\|\>\)\|\(\<\|\>\)module\(\<\|\>\)\|\(\<\|\>\)\%(my\s\+\)\=class\(\<\|\>\)\)' -      set ft=raku | return -    endif -    if line =~# '\(\<\|\>\)use\s\+\%(strict\(\<\|\>\)\|v\=5\.\)' -      set ft=perl | return -    endif -  endfor -  if exists("g:filetype_pl") -    let &ft = g:filetype_pl | return -  endif -  set ft=perl | return -endfunc - -func! polyglot#DetectTFiletype() -  for lnum in range(1, min([line("$"), 5])) -    let line = getline(lnum) -    if line =~# '^\.' -      set ft=nroff | return -    endif -  endfor -  for lnum in range(1, min([line("$"), 50])) -    let line = getline(lnum) -    if line =~# '^\s*\%(use\s\+v6\(\<\|\>\)\|\(\<\|\>\)module\(\<\|\>\)\|\(\<\|\>\)\%(my\s\+\)\=class\(\<\|\>\)\)' -      set ft=raku | return -    endif -    if line =~# '\(\<\|\>\)use\s\+\%(strict\(\<\|\>\)\|v\=5\.\)' -      set ft=perl | return -    endif -  endfor -  if exists("g:filetype_t") -    let &ft = g:filetype_t | return -  endif -  set ft=perl | return -endfunc - -func! polyglot#DetectTt2Filetype() -  for lnum in range(1, min([line("$"), 3])) -    let line = getline(lnum) -    if line =~? '<\%(!DOCTYPE HTML\|[%?]\|html\)' -      set ft=tt2html | return -    endif -  endfor -  set ft=tt2 | return -endfunc - -func! polyglot#DetectHtmlFiletype() -  let line = getline(nextnonblank(1)) -  if line =~# '^\(%\|<[%&].*>\)' -    set ft=mason | return -  endif -  for lnum in range(1, min([line("$"), 50])) -    let line = getline(lnum) -    if line =~# '{%-\=\s*\(end.*\|extends\|block\|macro\|set\|if\|for\|include\|trans\)\(\<\|\>\)\|{#\s\+' -      set ft=htmldjango | return -    endif -    if line =~# '\(\<\|\>\)DTD\s\+XHTML\s' -      set ft=xhtml | return -    endif -  endfor -  set ft=html | au! BufWritePost <buffer> ++once call polyglot#DetectHtmlFiletype() -  return -endfunc - - -" Restore 'cpoptions' -let &cpo = s:cpo_save -unlet s:cpo_save - -""" ftdetect/polyglot.vim - -" don't spam the user when Vim is started in Vi compatibility mode -let s:cpo_save = &cpo -set cpo&vim - -" Disable all native vim ftdetect -if exists('g:polyglot_test') -  autocmd! -endif - -func! s:Observe(fn) -  let b:polyglot_observe = a:fn -  augroup polyglot-observer -    au! CursorHold,CursorHoldI,BufWritePost <buffer> -      \ execute('if polyglot#' . b:polyglot_observe . '() | au! polyglot-observer | endif') -  augroup END -endfunc - -let s:disabled_packages = {} -let s:new_polyglot_disabled = [] - -if exists('g:polyglot_disabled') -  for pkg in g:polyglot_disabled -    let base = split(pkg, '\.') -    if len(base) > 0 -      let s:disabled_packages[pkg] = 1 -      call add(s:new_polyglot_disabled, base[0])  -    endif -  endfor -else -  let g:polyglot_disabled_not_set = 1 -endif - -function! s:SetDefault(name, value) -  if !exists(a:name) -    let {a:name} = a:value -  endif -endfunction - -call s:SetDefault('g:markdown_enable_spell_checking', 0) -call s:SetDefault('g:markdown_enable_input_abbreviations', 0) -call s:SetDefault('g:markdown_enable_mappings', 0) - -" Enable jsx syntax by default -call s:SetDefault('g:jsx_ext_required', 0) - -" Needed for sql highlighting -call s:SetDefault('g:javascript_sql_dialect', 'sql') - -" Make csv loading faster -call s:SetDefault('g:csv_start', 1) -call s:SetDefault('g:csv_end', 2) - -" Disable json concealing by default -call s:SetDefault('g:vim_json_syntax_conceal', 0) - -call s:SetDefault('g:filetype_euphoria', 'elixir') - -if !exists('g:python_highlight_all') -  call s:SetDefault('g:python_highlight_builtins', 1) -  call s:SetDefault('g:python_highlight_builtin_objs', 1) -  call s:SetDefault('g:python_highlight_builtin_types', 1) -  call s:SetDefault('g:python_highlight_builtin_funcs', 1) -  call s:SetDefault('g:python_highlight_builtin_funcs_kwarg', 1) -  call s:SetDefault('g:python_highlight_exceptions', 1) -  call s:SetDefault('g:python_highlight_string_formatting', 1) -  call s:SetDefault('g:python_highlight_string_format', 1) -  call s:SetDefault('g:python_highlight_string_templates', 1) -  call s:SetDefault('g:python_highlight_indent_errors', 1) -  call s:SetDefault('g:python_highlight_space_errors', 1) -  call s:SetDefault('g:python_highlight_doctests', 1) -  call s:SetDefault('g:python_highlight_func_calls', 1) -  call s:SetDefault('g:python_highlight_class_vars', 1) -  call s:SetDefault('g:python_highlight_operators', 1) -  call s:SetDefault('g:python_highlight_file_headers_as_comments', 1) -  call s:SetDefault('g:python_slow_sync', 1) -endif - -" We need it because scripts.vim in vim uses "set ft=" which cannot be -" overridden with setf (and we can't use set ft= so our scripts.vim work) -func! s:Setf(ft) -  if &filetype !~# '\<'.a:ft.'\>' -    let &filetype = a:ft -  endif -endfunc - -" Function used for patterns that end in a star: don't set the filetype if the -" file name matches ft_ignore_pat. -" When using this, the entry should probably be further down below with the -" other StarSetf() calls. -func! s:StarSetf(ft) -  if expand("<amatch>") !~ g:ft_ignore_pat && &filetype !~# '\<'.a:ft.'\>' -    let &filetype = a:ft -  endif -endfunc - -augroup filetypedetect - -" scripts/build inserts here filetype detection autocommands - -au! BufNewFile,BufRead,StdinReadPost * if expand("<afile>") !~ g:ft_ignore_pat | -  \ call polyglot#Shebang() | endif - -au BufEnter * if &ft == "" && expand("<afile>") !~ g:ft_ignore_pat | -      \ call s:Observe('Shebang') | endif - -augroup END - -if !has_key(s:disabled_packages, 'autoindent') -  " Code below re-implements sleuth for vim-polyglot -  let g:loaded_sleuth = 1 -  let g:loaded_foobar = 1 - -  " Makes shiftwidth to be synchronized with tabstop by default -  if &shiftwidth == &tabstop -    let &shiftwidth = 0 -  endif - -  function! s:guess(lines) abort -    let options = {} -    let ccomment = 0 -    let podcomment = 0 -    let triplequote = 0 -    let backtick = 0 -    let xmlcomment = 0 -    let heredoc = '' -    let minindent = 10 -    let spaces_minus_tabs = 0 -    let i = 0 - -    for line in a:lines -      let i += 1 - -      if !len(line) || line =~# '^\W*$' -        continue -      endif - -      if line =~# '^\s*/\*' -        let ccomment = 1 -      endif -      if ccomment -        if line =~# '\*/' -          let ccomment = 0 -        endif -        continue -      endif - -      if line =~# '^=\w' -        let podcomment = 1 -      endif -      if podcomment -        if line =~# '^=\%(end\|cut\)\>' -          let podcomment = 0 -        endif -        continue -      endif - -      if triplequote -        if line =~# '^[^"]*"""[^"]*$' -          let triplequote = 0 -        endif -        continue -      elseif line =~# '^[^"]*"""[^"]*$' -        let triplequote = 1 -      endif - -      if backtick -        if line =~# '^[^`]*`[^`]*$' -          let backtick = 0 -        endif -        continue -      elseif &filetype ==# 'go' && line =~# '^[^`]*`[^`]*$' -        let backtick = 1 -      endif - -      if line =~# '^\s*<\!--' -        let xmlcomment = 1 -      endif -      if xmlcomment -        if line =~# '-->' -          let xmlcomment = 0 -        endif -        continue -      endif - -      " This is correct order because both "<<EOF" and "EOF" matches end -      if heredoc != '' -        if line =~# heredoc -          let heredoc = '' -        endif -        continue -      endif -      let herematch = matchlist(line, '\C<<\W*\([A-Z]\+\)\s*$') -      if len(herematch) > 0 -        let heredoc = herematch[1] . '$' -      endif - -      let spaces_minus_tabs += line[0] == "\t" ? 1 : -1 - -      if line[0] == "\t" -        setlocal noexpandtab -        let &l:shiftwidth=&tabstop -        let b:sleuth_culprit .= ':' . i -        return 1 -      elseif line[0] == " " -        let indent = len(matchstr(line, '^ *')) -        if (indent % 2 == 0 || indent % 3 == 0) && indent < minindent -          let minindent = indent -        endif -      endif -    endfor - -    if minindent < 10 -      setlocal expandtab -      let &l:shiftwidth=minindent -      let b:sleuth_culprit .= ':' . i -      return 1 -    endif - -    return 0 -  endfunction - -  function! s:detect_indent() abort -    if &buftype ==# 'help' -      return -    endif - -    let b:sleuth_culprit = expand("<afile>:p") -    if s:guess(getline(1, 32)) -      return -    endif -    let pattern = sleuth#GlobForFiletype(&filetype) -    if len(pattern) == 0 -      return -    endif -    let pattern = '{' . pattern . ',.git,.svn,.hg}' -    let dir = expand('%:p:h') -    let level = 3 -    while isdirectory(dir) && dir !=# fnamemodify(dir, ':h') && level > 0 -      " Ignore files from homedir and root  -      if dir == expand('~') || dir == '/' -        unlet b:sleuth_culprit -        return -      endif -      for neighbor in glob(dir . '/' . pattern, 0, 1)[0:level] -        let b:sleuth_culprit = neighbor -        " Do not consider directories above .git, .svn or .hg -        if fnamemodify(neighbor, ":h:t")[0] == "." -          let level = 0 -          continue -        endif -        if neighbor !=# expand('%:p') && filereadable(neighbor) -          if s:guess(readfile(neighbor, '', 32)) -            return -          endif -        endif -      endfor - -      let dir = fnamemodify(dir, ':h') -      let level -= 1 -    endwhile - -    unlet b:sleuth_culprit -  endfunction - -  setglobal smarttab - -  function! SleuthIndicator() abort -    let sw = &shiftwidth ? &shiftwidth : &tabstop -    if &expandtab -      return 'sw='.sw -    elseif &tabstop == sw -      return 'ts='.&tabstop -    else -      return 'sw='.sw.',ts='.&tabstop -    endif -  endfunction - -  augroup polyglot-sleuth -    au! -    au FileType * call s:detect_indent() -    au User Flags call Hoist('buffer', 5, 'SleuthIndicator') -  augroup END - -  command! -bar -bang Sleuth call s:detect_indent() -endif - -func! s:verify() -  if exists("g:polyglot_disabled_not_set") -    if exists("g:polyglot_disabled") -      echohl WarningMsg -      echo "vim-polyglot: g:polyglot_disabled should be defined before loading vim-polyglot" -      echohl None -    endif - -    unlet g:polyglot_disabled_not_set -  endif -endfunc - -au VimEnter * call s:verify() - -" Save polyglot_disabled without postfixes -if exists('g:polyglot_disabled') -  let g:polyglot_disabled = s:new_polyglot_disabled -endif - -" restore Vi compatibility settings -let &cpo = s:cpo_save
\ No newline at end of file diff --git a/autoload/polyglot/detect.vim b/autoload/polyglot/detect.vim new file mode 100644 index 00000000..e92d4d12 --- /dev/null +++ b/autoload/polyglot/detect.vim @@ -0,0 +1,262 @@ +func! polyglot#detect#Inp() +  let line = getline(nextnonblank(1)) +  if line =~# '^\*' +    set ft=abaqus | return +  endif +  for lnum in range(1, min([line("$"), 500])) +    let line = getline(lnum) +    if line =~? '^header surface data' +      set ft=trasys | return +    endif +  endfor +endfunc + +func! polyglot#detect#Asa() +  if exists("g:filetype_asa") +    let &ft = g:filetype_asa | return +  endif +  set ft=aspvbs | return +endfunc + +func! polyglot#detect#Asp() +  if exists("g:filetype_asp") +    let &ft = g:filetype_asp | return +  endif +  for lnum in range(1, min([line("$"), 3])) +    let line = getline(lnum) +    if line =~? 'perlscript' +      set ft=aspperl | return +    endif +  endfor +  set ft=aspvbs | return +endfunc + +func! polyglot#detect#H() +  for lnum in range(1, min([line("$"), 200])) +    let line = getline(lnum) +    if line =~# '^\s*\(@\(interface\|class\|protocol\|property\|end\|synchronised\|selector\|implementation\)\(\<\|\>\)\|#import\s\+.\+\.h[">]\)' +      if exists("g:c_syntax_for_h") +        set ft=objc | return +      endif +      set ft=objcpp | return +    endif +  endfor +  if exists("g:c_syntax_for_h") +    set ft=c | return +  endif +  if exists("g:ch_syntax_for_h") +    set ft=ch | return +  endif +  set ft=cpp | return +endfunc + +func! polyglot#detect#M() +  let saw_comment = 0 +  for lnum in range(1, min([line("$"), 100])) +    let line = getline(lnum) +    if line =~# '^\s*/\*' +      let saw_comment = 1 +    endif +    if line =~# '^\s*\(@\(interface\|class\|protocol\|property\|end\|synchronised\|selector\|implementation\)\(\<\|\>\)\|#import\s\+.\+\.h[">]\)' +      set ft=objc | return +    endif +    if line =~# '^\s*%' +      set ft=octave | return +    endif +    if line =~# '^\s*(\*' +      set ft=mma | return +    endif +    if line =~? '^\s*\(\(type\|var\)\(\<\|\>\)\|--\)' +      set ft=murphi | return +    endif +  endfor +  if saw_comment +    set ft=objc | return +  endif +  if exists("g:filetype_m") +    let &ft = g:filetype_m | return +  endif +  set ft=octave | return +endfunc + +func! polyglot#detect#Fs() +  for lnum in range(1, min([line("$"), 50])) +    let line = getline(lnum) +    if line =~# '^\(: \|new-device\)' +      set ft=forth | return +    endif +    if line =~# '^\s*\(#light\|import\|let\|module\|namespace\|open\|type\)' +      set ft=fsharp | return +    endif +    if line =~# '\s*\(#version\|precision\|uniform\|varying\|vec[234]\)' +      set ft=glsl | return +    endif +  endfor +  if exists("g:filetype_fs") +    let &ft = g:filetype_fs | return +  endif +  set ft=forth | return +endfunc + +func! polyglot#detect#Re() +  for lnum in range(1, min([line("$"), 50])) +    let line = getline(lnum) +    if line =~# '^\s*#\%(\%(if\|ifdef\|define\|pragma\)\s\+\w\|\s*include\s\+[<"]\|template\s*<\)' +      set ft=cpp | return +    endif +    set ft=reason | return +  endfor +endfunc + +func! polyglot#detect#Idr() +  for lnum in range(1, min([line("$"), 5])) +    let line = getline(lnum) +    if line =~# '^\s*--.*[Ii]dris \=1' +      set ft=idris | return +    endif +    if line =~# '^\s*--.*[Ii]dris \=2' +      set ft=idris2 | return +    endif +  endfor +  for lnum in range(1, min([line("$"), 30])) +    let line = getline(lnum) +    if line =~# '^pkgs =.*' +      set ft=idris | return +    endif +    if line =~# '^depends =.*' +      set ft=idris2 | return +    endif +    if line =~# '^%language \(TypeProviders\|ElabReflection\)' +      set ft=idris | return +    endif +    if line =~# '^%language PostfixProjections' +      set ft=idris2 | return +    endif +    if line =~# '^%access .*' +      set ft=idris | return +    endif +  endfor +  if exists("g:filetype_idr") +    let &ft = g:filetype_idr | return +  endif +  set ft=idris2 | return +endfunc + +func! polyglot#detect#Lidr() +  for lnum in range(1, min([line("$"), 200])) +    let line = getline(lnum) +    if line =~# '^>\s*--.*[Ii]dris \=1' +      set ft=lidris | return +    endif +  endfor +  set ft=lidris2 | return +endfunc + +func! polyglot#detect#Bas() +  for lnum in range(1, min([line("$"), 5])) +    let line = getline(lnum) +    if line =~? 'VB_Name\|Begin VB\.\(Form\|MDIForm\|UserControl\)' +      set ft=vb | return +    endif +  endfor +  set ft=basic | return +endfunc + +func! polyglot#detect#Pm() +  let line = getline(nextnonblank(1)) +  if line =~# 'XPM2' +    set ft=xpm2 | return +  endif +  if line =~# 'XPM' +    set ft=xpm | return +  endif +  for lnum in range(1, min([line("$"), 50])) +    let line = getline(lnum) +    if line =~# '^\s*\%(use\s\+v6\(\<\|\>\)\|\(\<\|\>\)module\(\<\|\>\)\|\(\<\|\>\)\%(my\s\+\)\=class\(\<\|\>\)\)' +      set ft=raku | return +    endif +    if line =~# '\(\<\|\>\)use\s\+\%(strict\(\<\|\>\)\|v\=5\.\)' +      set ft=perl | return +    endif +  endfor +  if exists("g:filetype_pm") +    let &ft = g:filetype_pm | return +  endif +  if polyglot#shebang#Detect() | return | endif +  set ft=perl | au! BufWritePost <buffer> ++once call polyglot#detect#Pm() +  return +endfunc + +func! polyglot#detect#Pl() +  let line = getline(nextnonblank(1)) +  if line =~# '^[^#]*:-' || line =~# '^\s*\%(%\|/\*\)' || line =~# '\.\s*$' +    set ft=prolog | return +  endif +  for lnum in range(1, min([line("$"), 50])) +    let line = getline(lnum) +    if line =~# '^\s*\%(use\s\+v6\(\<\|\>\)\|\(\<\|\>\)module\(\<\|\>\)\|\(\<\|\>\)\%(my\s\+\)\=class\(\<\|\>\)\)' +      set ft=raku | return +    endif +    if line =~# '\(\<\|\>\)use\s\+\%(strict\(\<\|\>\)\|v\=5\.\)' +      set ft=perl | return +    endif +  endfor +  if exists("g:filetype_pl") +    let &ft = g:filetype_pl | return +  endif +  if polyglot#shebang#Detect() | return | endif +  set ft=perl | au! BufWritePost <buffer> ++once call polyglot#detect#Pl() +  return +endfunc + +func! polyglot#detect#T() +  for lnum in range(1, min([line("$"), 5])) +    let line = getline(lnum) +    if line =~# '^\.' +      set ft=nroff | return +    endif +  endfor +  for lnum in range(1, min([line("$"), 50])) +    let line = getline(lnum) +    if line =~# '^\s*\%(use\s\+v6\(\<\|\>\)\|\(\<\|\>\)module\(\<\|\>\)\|\(\<\|\>\)\%(my\s\+\)\=class\(\<\|\>\)\)' +      set ft=raku | return +    endif +    if line =~# '\(\<\|\>\)use\s\+\%(strict\(\<\|\>\)\|v\=5\.\)' +      set ft=perl | return +    endif +  endfor +  if exists("g:filetype_t") +    let &ft = g:filetype_t | return +  endif +  if polyglot#shebang#Detect() | return | endif +  set ft=perl | au! BufWritePost <buffer> ++once call polyglot#detect#T() +  return +endfunc + +func! polyglot#detect#Tt2() +  for lnum in range(1, min([line("$"), 3])) +    let line = getline(lnum) +    if line =~? '<\%(!DOCTYPE HTML\|[%?]\|html\)' +      set ft=tt2html | return +    endif +  endfor +  set ft=tt2 | return +endfunc + +func! polyglot#detect#Html() +  let line = getline(nextnonblank(1)) +  if line =~# '^\(%\|<[%&].*>\)' +    set ft=mason | return +  endif +  for lnum in range(1, min([line("$"), 50])) +    let line = getline(lnum) +    if line =~# '{%-\=\s*\(end.*\|extends\|block\|macro\|set\|if\|for\|include\|trans\)\(\<\|\>\)\|{#\s\+' +      set ft=htmldjango | return +    endif +    if line =~# '\(\<\|\>\)DTD\s\+XHTML\s' +      set ft=xhtml | return +    endif +  endfor +  set ft=html | au! BufWritePost <buffer> ++once call polyglot#detect#Html() +  return +endfunc diff --git a/autoload/polyglot/shebang.vim b/autoload/polyglot/shebang.vim new file mode 100644 index 00000000..bf2a793a --- /dev/null +++ b/autoload/polyglot/shebang.vim @@ -0,0 +1,129 @@ +" Please do not edit this file directly, instead modify polyglot.vim or scripts/build + +func! polyglot#shebang#Detect() +  let ft = s:Filetype() +  if ft != "" +    let &ft = ft +  endif + +  if &ft == "" +    runtime! scripts.vim +  endif + +  return &ft != "" +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:script = split(l:path, "/")[-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 + + + +let s:interpreters = { +  \ 'osascript': 'applescript', +  \ 'tcc': 'c', +  \ 'coffee': 'coffee', +  \ 'crystal': 'crystal', +  \ 'dart': 'dart', +  \ 'elixir': 'elixir', +  \ 'escript': 'erlang', +  \ 'fish': 'fish', +  \ 'gnuplot': 'gnuplot', +  \ 'groovy': 'groovy', +  \ 'runhaskell': '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', +  \ 'ocaml': 'ocaml', +  \ 'ocamlrun': 'ocaml', +  \ 'ocamlscript': 'ocaml', +  \ 'cperl': 'perl', +  \ 'perl': 'perl', +  \ 'php': 'php', +  \ 'swipl': 'prolog', +  \ 'yap': 'prolog', +  \ 'pwsh': 'ps1', +  \ 'python': 'python', +  \ 'python2': 'python', +  \ 'python3': 'python', +  \ 'qmake': 'qmake', +  \ 'Rscript': 'r', +  \ 'racket': 'racket', +  \ 'perl6': 'raku', +  \ 'raku': 'raku', +  \ 'rakudo': 'raku', +  \ 'ruby': 'ruby', +  \ 'macruby': 'ruby', +  \ 'rake': 'ruby', +  \ 'jruby': 'ruby', +  \ 'rbx': 'ruby', +  \ 'scala': 'scala', +  \ 'ash': 'sh', +  \ 'bash': 'sh', +  \ 'dash': 'sh', +  \ 'ksh': 'sh', +  \ 'mksh': 'sh', +  \ 'pdksh': 'sh', +  \ 'rc': 'sh', +  \ 'sh': 'sh', +  \ 'zsh': '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', +  \ }
\ No newline at end of file diff --git a/autoload/sleuth.vim b/autoload/polyglot/sleuth.vim index 3a41f6f9..d74de687 100644 --- a/autoload/sleuth.vim +++ b/autoload/polyglot/sleuth.vim @@ -232,6 +232,6 @@ let s:globs = {    \ 'zsh': '*.zsh,.zshrc,.zshenv,.zlogin,.zprofile,.zlogout,.zlog*,.zcompdump*,.zfbfmarks,.zsh*',    \} -func! sleuth#GlobForFiletype(type) +func! polyglot#sleuth#GlobForFiletype(type)    return get(s:globs, a:type, '')  endfunc diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index 0d9fd370..c96760a7 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -128,7 +128,7 @@ if !has_key(s:disabled_packages, 'abap')  endif  if !has_key(s:disabled_packages, 'abaqus') -  au! BufNewFile,BufRead *.inp call polyglot#DetectInpFiletype() +  au! BufNewFile,BufRead *.inp call polyglot#detect#Inp()  endif  if !has_key(s:disabled_packages, 'abc') @@ -215,7 +215,7 @@ if !has_key(s:disabled_packages, 'arch')  endif  if !has_key(s:disabled_packages, 'c/c++') -  au! BufNewFile,BufRead *.h call polyglot#DetectHFiletype() +  au! BufNewFile,BufRead *.h call polyglot#detect#H()    au! BufNewFile,BufRead *.c,*.cats,*.idc,*.qc,*enlightenment/*.cfg set ft=c    au! BufNewFile,BufRead *.c++,*.cc,*.cp,*.cpp,*.cxx,*.h++,*.hh,*.hpp,*.hxx,*.inc,*.inl,*.ipp,*.moc,*.tcc,*.tlh,*.tpp set ft=cpp  endif @@ -249,12 +249,12 @@ if !has_key(s:disabled_packages, 'asn')  endif  if !has_key(s:disabled_packages, 'aspvbs') -  au! BufNewFile,BufRead *.asp call polyglot#DetectAspFiletype() -  au! BufNewFile,BufRead *.asa call polyglot#DetectAsaFiletype() +  au! BufNewFile,BufRead *.asp call polyglot#detect#Asp() +  au! BufNewFile,BufRead *.asa call polyglot#detect#Asa()  endif  if !has_key(s:disabled_packages, 'aspperl') -  au! BufNewFile,BufRead *.asp call polyglot#DetectAspFiletype() +  au! BufNewFile,BufRead *.asp call polyglot#detect#Asp()  endif  if !has_key(s:disabled_packages, 'atlas') @@ -381,12 +381,12 @@ if !has_key(s:disabled_packages, 'flatbuffers')  endif  if !has_key(s:disabled_packages, 'forth') -  au! BufNewFile,BufRead *.fs call polyglot#DetectFsFiletype() +  au! BufNewFile,BufRead *.fs call polyglot#detect#Fs()    au! BufNewFile,BufRead *.ft,*.fth set ft=forth  endif  if !has_key(s:disabled_packages, 'fsharp') -  au! BufNewFile,BufRead *.fs call polyglot#DetectFsFiletype() +  au! BufNewFile,BufRead *.fs call polyglot#detect#Fs()    au! BufNewFile,BufRead *.fsi,*.fsx set ft=fsharp  endif @@ -403,7 +403,7 @@ if !has_key(s:disabled_packages, 'git')  endif  if !has_key(s:disabled_packages, 'glsl') -  au! BufNewFile,BufRead *.fs call polyglot#DetectFsFiletype() +  au! BufNewFile,BufRead *.fs call polyglot#detect#Fs()    au! BufNewFile,BufRead *.comp,*.fp,*.frag,*.frg,*.fsh,*.fshader,*.geo,*.geom,*.glsl,*.glslf,*.glslv,*.gs,*.gshader,*.shader,*.tesc,*.tese,*.vert,*.vrx,*.vsh,*.vshader set ft=glsl  endif @@ -471,7 +471,7 @@ if !has_key(s:disabled_packages, 'hive')  endif  if !has_key(s:disabled_packages, 'html5') -  au! BufNewFile,BufRead *.html call polyglot#DetectHtmlFiletype() +  au! BufNewFile,BufRead *.html call polyglot#detect#Html()    au! BufNewFile,BufRead *.htm,*.html.hl,*.inc,*.st,*.xht,*.xhtml set ft=html  endif @@ -484,14 +484,14 @@ if !has_key(s:disabled_packages, 'icalendar')  endif  if !has_key(s:disabled_packages, 'idris') -  au! BufNewFile,BufRead *.lidr call polyglot#DetectLidrFiletype() -  au! BufNewFile,BufRead *.idr call polyglot#DetectIdrFiletype() +  au! BufNewFile,BufRead *.lidr call polyglot#detect#Lidr() +  au! BufNewFile,BufRead *.idr call polyglot#detect#Idr()    au! BufNewFile,BufRead idris-response set ft=idris  endif  if !has_key(s:disabled_packages, 'idris2') -  au! BufNewFile,BufRead *.lidr call polyglot#DetectLidrFiletype() -  au! BufNewFile,BufRead *.idr call polyglot#DetectIdrFiletype() +  au! BufNewFile,BufRead *.lidr call polyglot#detect#Lidr() +  au! BufNewFile,BufRead *.idr call polyglot#detect#Idr()    au! BufNewFile,BufRead *.ipkg,idris-response set ft=idris2  endif @@ -582,7 +582,7 @@ if !has_key(s:disabled_packages, 'mako')  endif  if !has_key(s:disabled_packages, 'mathematica') -  au! BufNewFile,BufRead *.m call polyglot#DetectMFiletype() +  au! BufNewFile,BufRead *.m call polyglot#detect#M()    au! BufNewFile,BufRead *.cdf,*.ma,*.mathematica,*.mma,*.mt,*.nb,*.nbp,*.wl,*.wls,*.wlt set ft=mma  endif @@ -604,7 +604,7 @@ if !has_key(s:disabled_packages, 'moonscript')  endif  if !has_key(s:disabled_packages, 'murphi') -  au! BufNewFile,BufRead *.m call polyglot#DetectMFiletype() +  au! BufNewFile,BufRead *.m call polyglot#detect#M()  endif  if !has_key(s:disabled_packages, 'nginx') @@ -622,8 +622,8 @@ if !has_key(s:disabled_packages, 'nix')  endif  if !has_key(s:disabled_packages, 'objc') -  au! BufNewFile,BufRead *.m call polyglot#DetectMFiletype() -  au! BufNewFile,BufRead *.h call polyglot#DetectHFiletype() +  au! BufNewFile,BufRead *.m call polyglot#detect#M() +  au! BufNewFile,BufRead *.h call polyglot#detect#H()  endif  if !has_key(s:disabled_packages, 'ocaml') @@ -639,7 +639,7 @@ if !has_key(s:disabled_packages, 'ocaml')  endif  if !has_key(s:disabled_packages, 'octave') -  au! BufNewFile,BufRead *.m call polyglot#DetectMFiletype() +  au! BufNewFile,BufRead *.m call polyglot#detect#M()    au! BufNewFile,BufRead *.oct set ft=octave  endif @@ -648,10 +648,10 @@ if !has_key(s:disabled_packages, 'opencl')  endif  if !has_key(s:disabled_packages, 'perl') -  au! BufNewFile,BufRead *.tt2 call polyglot#DetectTt2Filetype() -  au! BufNewFile,BufRead *.t call polyglot#DetectTFiletype() -  au! BufNewFile,BufRead *.pm call polyglot#DetectPmFiletype() -  au! BufNewFile,BufRead *.pl call polyglot#DetectPlFiletype() +  au! BufNewFile,BufRead *.tt2 call polyglot#detect#Tt2() +  au! BufNewFile,BufRead *.t call polyglot#detect#T() +  au! BufNewFile,BufRead *.pm call polyglot#detect#Pm() +  au! BufNewFile,BufRead *.pl call polyglot#detect#Pl()    au! BufNewFile,BufRead *.xs set ft=xs    au! BufNewFile,BufRead *.comp,*.mason,*.mhtml set ft=mason    au! BufNewFile,BufRead *.pod set ft=pod @@ -740,9 +740,9 @@ if !has_key(s:disabled_packages, 'ragel')  endif  if !has_key(s:disabled_packages, 'raku') -  au! BufNewFile,BufRead *.t call polyglot#DetectTFiletype() -  au! BufNewFile,BufRead *.pm call polyglot#DetectPmFiletype() -  au! BufNewFile,BufRead *.pl call polyglot#DetectPlFiletype() +  au! BufNewFile,BufRead *.t call polyglot#detect#T() +  au! BufNewFile,BufRead *.pm call polyglot#detect#Pm() +  au! BufNewFile,BufRead *.pl call polyglot#detect#Pl()    au! BufNewFile,BufRead *.6pl,*.6pm,*.nqp,*.p6,*.p6l,*.p6m,*.pl6,*.pm6,*.pod6,*.raku,*.rakudoc,*.rakumod,*.rakutest,*.t6 set ft=raku  endif @@ -755,7 +755,7 @@ if !has_key(s:disabled_packages, 'razor')  endif  if !has_key(s:disabled_packages, 'reason') -  au! BufNewFile,BufRead *.re call polyglot#DetectReFiletype() +  au! BufNewFile,BufRead *.re call polyglot#detect#Re()    au! BufNewFile,BufRead *.rei set ft=reason  endif @@ -949,7 +949,7 @@ if !has_key(s:disabled_packages, 'zig')  endif  if !has_key(s:disabled_packages, 'trasys') -  au! BufNewFile,BufRead *.inp call polyglot#DetectInpFiletype() +  au! BufNewFile,BufRead *.inp call polyglot#detect#Inp()  endif  if !has_key(s:disabled_packages, 'basic') @@ -957,7 +957,7 @@ if !has_key(s:disabled_packages, 'basic')  endif  if !has_key(s:disabled_packages, 'visual-basic') -  au! BufNewFile,BufRead *.bas call polyglot#DetectBasFiletype() +  au! BufNewFile,BufRead *.bas call polyglot#detect#Bas()    au! BufNewFile,BufRead *.cls,*.ctl,*.dsm,*.frm,*.frx,*.sba,*.vba,*.vbs set ft=vb  endif @@ -976,12 +976,12 @@ if !has_key(s:disabled_packages, 'bzl')  endif  if !has_key(s:disabled_packages, 'prolog') -  au! BufNewFile,BufRead *.pl call polyglot#DetectPlFiletype() +  au! BufNewFile,BufRead *.pl call polyglot#detect#Pl()    au! BufNewFile,BufRead *.pdb,*.pro,*.prolog,*.yap set ft=prolog  endif  if !has_key(s:disabled_packages, 'tads') -  au! BufNewFile,BufRead *.t call polyglot#DetectTFiletype() +  au! BufNewFile,BufRead *.t call polyglot#detect#T()  endif  if !has_key(s:disabled_packages, 'gitignore') @@ -994,11 +994,11 @@ endif -au! BufNewFile,BufRead,StdinReadPost * if expand("<afile>") !~ g:ft_ignore_pat | -  \ call polyglot#Shebang() | endif +au! BufNewFile,BufRead,StdinReadPost * if expand("<afile>:e") == "" | +  \ call polyglot#shebang#Detect() | endif -au BufEnter * if &ft == "" && expand("<afile>") !~ g:ft_ignore_pat | -      \ call s:Observe('Shebang') | endif +au BufEnter * if &ft == "" && expand("<afile>:e") == ""  | +      \ call s:Observe('shebang#Detect') | endif  augroup END @@ -1125,7 +1125,7 @@ if !has_key(s:disabled_packages, 'autoindent')      if s:guess(getline(1, 32))        return      endif -    let pattern = sleuth#GlobForFiletype(&filetype) +    let pattern = polyglot#sleuth#GlobForFiletype(&filetype)      if len(pattern) == 0        return      endif @@ -1201,4 +1201,5 @@ if exists('g:polyglot_disabled')  endif  " restore Vi compatibility settings -let &cpo = s:cpo_save
\ No newline at end of file +let &cpo = s:cpo_save + diff --git a/heuristics.yaml b/heuristics.yaml index 129734f8..4080cbc4 100644 --- a/heuristics.yaml +++ b/heuristics.yaml @@ -132,6 +132,8 @@ rules:      filetype: perl  - override: true  - filetype: perl +  shebang: true +  fallback: true  ---  extensions: [pl]  rules: @@ -149,6 +151,8 @@ rules:      filetype: perl  - override: true  - filetype: perl +  shebang: true +  fallback: true  ---  extensions: [t]  rules: @@ -166,6 +170,8 @@ rules:    #   filetype: turing  - override: true  - filetype: perl +  shebang: true +  fallback: true  ---  extensions: [tt2]  rules: diff --git a/polyglot.vim b/polyglot.vim index e86e62ef..7c922d09 100644 --- a/polyglot.vim +++ b/polyglot.vim @@ -1,15 +1,9 @@ -""" autoload/polyglot.vim +""" autoload/polyglot/shebang.vim -" Line continuation is used here, remove 'C' from 'cpoptions' -let s:cpo_save = &cpo -set cpo&vim - -func! polyglot#Shebang() -  if getline(1) =~# "^#!" -    let ft = polyglot#ShebangFiletype() -    if ft != "" -      let &ft = ft -    endif +func! polyglot#shebang#Detect() +  let ft = s:Filetype() +  if ft != "" +    let &ft = ft    endif    if &ft == "" @@ -23,7 +17,7 @@ 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! polyglot#ShebangFiletype() +func! s:Filetype()    let l:line1 = getline(1)    if l:line1 !~# "^#!" @@ -60,12 +54,6 @@ func! polyglot#ShebangFiletype()    endfor  endfunc -" scripts/build generates heuristics functions here - -" Restore 'cpoptions' -let &cpo = s:cpo_save -unlet s:cpo_save -  """ ftdetect/polyglot.vim  " don't spam the user when Vim is started in Vi compatibility mode @@ -167,11 +155,11 @@ augroup filetypedetect  " scripts/build inserts here filetype detection autocommands -au! BufNewFile,BufRead,StdinReadPost * if expand("<afile>") !~ g:ft_ignore_pat | -  \ call polyglot#Shebang() | endif +au! BufNewFile,BufRead,StdinReadPost * if expand("<afile>:e") == "" | +  \ call polyglot#shebang#Detect() | endif -au BufEnter * if &ft == "" && expand("<afile>") !~ g:ft_ignore_pat | -      \ call s:Observe('Shebang') | endif +au BufEnter * if &ft == "" && expand("<afile>:e") == ""  | +      \ call s:Observe('shebang#Detect') | endif  augroup END @@ -298,7 +286,7 @@ if !has_key(s:disabled_packages, 'autoindent')      if s:guess(getline(1, 32))        return      endif -    let pattern = sleuth#GlobForFiletype(&filetype) +    let pattern = polyglot#sleuth#GlobForFiletype(&filetype)      if len(pattern) == 0        return      endif diff --git a/scripts/build b/scripts/build index 2e767b9b..3ec5b50c 100755 --- a/scripts/build +++ b/scripts/build @@ -13,8 +13,11 @@ Dir.chdir(File.dirname(__dir__))  BASE_URL = 'https://raw.githubusercontent.com/github/linguist/master'  def read_section(name) -  "\" Please do not edit this file directly, instead modify polyglot.vim or scripts/build\n\n" + -  File.read('polyglot.vim').match(/""" #{Regexp.escape(name)}\n*(.*)\n(?=\n""")/m)[1] +  section = File.read('polyglot.vim').split('""" ').find { |e| e.start_with?(name) } +  if section.nil? +    raise StandardError.new("Section not found: #{name}") +  end +  "\" Please do not edit this file directly, instead modify polyglot.vim or scripts/build\n" + section[(section.index("\n") + 1)..-1]  end  def camelize(str) @@ -390,10 +393,17 @@ def rule_to_code(rule)      EOS    end +  if rule.has_key?("shebang") +    return <<~EOS +      if polyglot#shebang#Detect() | return | endif +      #{indent(rule_to_code(except(rule, "shebang")), 0)} +    EOS +  end +    if rule.has_key?("filetype")      if rule.has_key?("fallback")        return <<~EOS -        set ft=#{rule["filetype"]} | au! BufWritePost <buffer> ++once call polyglot#Detect#{camelize(rule["extensions"].first)}Filetype() +        set ft=#{rule["filetype"]} | au! BufWritePost <buffer> ++once call polyglot#detect##{camelize(rule["extensions"].first)}()          return        EOS      end @@ -489,6 +499,8 @@ def extract(packages)  end  def generate_ftdetect(packages, heuristics) +  FileUtils.mkdir_p('autoload/polyglot') +    output = "\n"    all_filetypes = packages.flat_map { |f| f["filetypes"] || [] } @@ -561,7 +573,7 @@ def generate_ftdetect(packages, heuristics)      for heuristic in package_heuristics.uniq        extensions = heuristic["extensions"].map { |e| "*.#{e}" } -      autocommands << "  au! BufNewFile,BufRead #{extensions.join(",")} call polyglot#Detect#{camelize(heuristic["extensions"].first)}Filetype()\n" +      autocommands << "  au! BufNewFile,BufRead #{extensions.join(",")} call polyglot#detect##{camelize(heuristic["extensions"].first)}()\n"      end      if autocommands != "" @@ -580,6 +592,18 @@ def generate_ftdetect(packages, heuristics)       ftdetect.gsub('" scripts/build inserts here filetype detection autocommands') { output }    ) +  output = [] + +  for heuristic in heuristics +    output << <<~EOS +      func! polyglot#detect##{camelize(heuristic["extensions"].first)}() +      #{indent(rules_to_code(heuristic), 2)} +      endfunc +    EOS +  end + +  File.write('autoload/polyglot/detect.vim', output.join("\n")) +    output = <<~EOS      let s:interpreters = {      EOS @@ -590,24 +614,10 @@ def generate_ftdetect(packages, heuristics)        end      end -  output << <<~EOS -      \\ } - -  EOS - -  for heuristic in heuristics -    output << <<~EOS -      func! polyglot#Detect#{camelize(heuristic["extensions"].first)}Filetype() -      #{indent(rules_to_code(heuristic), 2)} -      endfunc - -    EOS -  end - -  autoload_script = read_section('autoload/polyglot.vim') -  autoload_script["\" scripts/build generates heuristics functions here\n"] = output +  output << "  \\ }" -  File.write('autoload/polyglot.vim', autoload_script) +  autoload_script = read_section('autoload/polyglot/shebang.vim') +  File.write('autoload/polyglot/shebang.vim', autoload_script + "\n\n" + output)  end  def generate_tests(packages) @@ -744,13 +754,13 @@ def generate_plugins(packages)    output << <<~EOS -    func! sleuth#GlobForFiletype(type) +    func! polyglot#sleuth#GlobForFiletype(type)        return get(s:globs, a:type, '')      endfunc    EOS -  File.write('autoload/sleuth.vim', output) +  File.write('autoload/polyglot/sleuth.vim', output)  end  def process_list(list, extras) diff --git a/tests/extensions.vim b/tests/extensions.vim index 16548eb8..6492e1ac 100644 --- a/tests/extensions.vim +++ b/tests/extensions.vim @@ -30,6 +30,7 @@ call TestExtension("sh", "bash3", "#! /bin/bash2.3")  call TestExtension("sh", "bash4", "#!/usr/bin/env bash")  call TestExtension("sh", "bash6", "#!/usr/bin/env -i -=split-string foo=bar bash -l foo")  call TestExtension("sh", "bash1", "#!/bin/bash") +call TestExtension("sh", "bash7", ":")  " Vim help file  call TestExtension("help", $VIMRUNTIME . "/doc/foobar.txt", "") | 
