diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2020-09-01 23:38:17 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2020-09-01 23:38:17 +0200 |
commit | 63119f09d1390b61155cc0dc3ff497356d2fc7e5 (patch) | |
tree | 06dd676bd4df62105f24499a9a3398f179f30ff2 | |
parent | f2ef4cedecf554c0c9f0694f93df1d53a57bf70c (diff) | |
download | vim-polyglot-63119f09d1390b61155cc0dc3ff497356d2fc7e5.tar.gz vim-polyglot-63119f09d1390b61155cc0dc3ff497356d2fc7e5.zip |
Automatically detect indentation, closes #529v4.8.0
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | autoload/sleuth.vim | 221 | ||||
-rw-r--r-- | plugin/sleuth.vim | 164 | ||||
-rwxr-xr-x | scripts/build | 34 |
4 files changed, 420 insertions, 1 deletions
@@ -11,7 +11,7 @@ A collection of language packs for Vim. - It is more secure because scripts loaded for all extensions are generated by vim-polyglot (ftdetect). - Solid syntax and indentation support (other features skipped). Only the best language packs. - All unnecessary files are ignored (like enormous documentation from php support). -- No support for esoteric languages, only most popular ones (modern too, like `slim`). +- Automatically detect indentation (includes performance-optimized version of [vim-sleuth](https://github.com/tpope/vim-sleuth)) - Each build is tested by automated vimrunner script on CI. See `spec` directory. \*To be completely honest, optimized `ftdetect` script takes around `19ms` to load. diff --git a/autoload/sleuth.vim b/autoload/sleuth.vim new file mode 100644 index 00000000..1c9fbefb --- /dev/null +++ b/autoload/sleuth.vim @@ -0,0 +1,221 @@ +let s:globs = { + \ '8th': '{*.8th,}', + \ 'Dockerfile': '{*.dockerfile,*.dock,*.Dockerfile,Dockerfile,dockerfile,Dockerfile*,}', + \ 'Jenkinsfile': '{*.jenkinsfile,*.Jenkinsfile,Jenkinsfile,Jenkinsfile*,}', + \ 'a2ps': '{a2psrc,.a2psrc,}', + \ 'a65': '{*.a65,}', + \ 'aap': '{*.aap,}', + \ 'abap': '{*.abap,}', + \ 'abaqus': '{*.inp,}', + \ 'abc': '{*.abc,}', + \ 'abel': '{*.abl,}', + \ 'acedb': '{*.wrm,}', + \ 'ada': '{*.adb,*.ads,*.ada,*.gpr,}', + \ 'ahdl': '{*.tdf,}', + \ 'aidl': '{*.aidl,}', + \ 'alsaconf': '{.asoundrc,}', + \ 'aml': '{*.aml,}', + \ 'ampl': '{*.run,}', + \ 'ant': '{build.xml,}', + \ 'apache': '{.htaccess,}', + \ 'apiblueprint': '{*.apib,}', + \ 'applescript': '{*.applescript,*.scpt,}', + \ 'aptconf': '{apt.conf,}', + \ 'arch': '{.arch-inventory,=tagging-method,}', + \ 'arduino': '{*.pde,*.ino,}', + \ 'art': '{*.art,}', + \ 'asciidoc': '{*.asciidoc,*.adoc,*.asc,}', + \ 'asl': '{*.asl,*.dsl,}', + \ 'asn': '{*.asn,*.asn1,}', + \ 'aspperl': '{*.asp,}', + \ 'aspvbs': '{*.asa,*.asp,}', + \ 'atlas': '{*.atl,*.as,}', + \ 'autohotkey': '{*.ahk,*.ahkl,}', + \ 'autoit': '{*.au3,}', + \ 'automake': '{[Mm]akefile.am,GNUmakefile.am,}', + \ 'ave': '{*.ave,}', + \ 'awk': '{*.awk,}', + \ 'blade': '{*.blade,*.blade.php,}', + \ 'brewfile': '{Brewfile,}', + \ 'c': '{*.c,*.cats,*.h,*.idc,}', + \ 'caddyfile': '{Caddyfile,}', + \ 'carp': '{*.carp,}', + \ 'clojure': '{*.clj,*.boot,*.cl2,*.cljc,*.cljs,*.cljs.hl,*.cljscm,*.cljx,*.hic,*.edn,riemann.config,build.boot,profile.boot,}', + \ 'cmake': '{*.cmake,*.cmake.in,CMakeLists.txt,}', + \ 'coffee': '{*.coffee,*._coffee,*.cake,*.cjsx,*.iced,*.coffeekup,Cakefile,}', + \ 'cpp': '{*.cpp,*.c++,*.cc,*.cp,*.cxx,*.h,*.h++,*.hh,*.hpp,*.hxx,*.inc,*.inl,*.ino,*.ipp,*.re,*.tcc,*.tpp,}', + \ 'cql': '{*.cql,}', + \ 'cryptol': '{*.cry,*.cyl,*.lcry,*.lcyl,}', + \ 'crystal': '{*.cr,Projectfile,}', + \ 'csv': '{*.csv,*.tsv,*.tab,}', + \ 'cucumber': '{*.feature,*.story,}', + \ 'cuesheet': '{*.cue,}', + \ 'd': '{*.d,*.di,}', + \ 'dart': '{*.dart,}', + \ 'dcov': '{*.lst,}', + \ 'dd': '{*.dd,}', + \ 'ddoc': '{*.ddoc,}', + \ 'dhall': '{*.dhall,}', + \ 'dosini': '{*.wrap,}', + \ 'dsdl': '{*.sdl,}', + \ 'dune': '{jbuild,dune,dune-project,dune-workspace,}', + \ 'ecrystal': '{*.ecr,}', + \ 'eelixir': '{*.eex,*.leex,}', + \ 'elf': '{*.am,}', + \ 'elixir': '{*.ex,*.exs,mix.lock,}', + \ 'elm': '{*.elm,}', + \ 'embeddedpuppet': '{*.epp,}', + \ 'ember-script': '{*.em,*.emberscript,}', + \ 'emblem': '{*.emblem,*.em,}', + \ 'erlang': '{*.erl,*.app.src,*.es,*.escript,*.hrl,*.xrl,*.yrl,*.app,*.yaws,Emakefile,rebar.config,rebar.config.lock,rebar.lock,}', + \ 'eruby': '{*.erb,*.erb.deface,*.rhtml,}', + \ 'fbs': '{*.fbs,}', + \ 'fennel': '{*.fnl,}', + \ 'ferm': '{*.ferm,ferm.conf,}', + \ 'fish': '{*.fish,}', + \ 'flow': '{*.flow,}', + \ 'forth': '{*.fs,*.ft,*.fth,}', + \ 'fsharp': '{*.fs,*.fsi,*.fsx,}', + \ 'gdscript3': '{*.gd,}', + \ 'gitcommit': '{,}', + \ 'gitconfig': '{*.gitconfig,.gitconfig,.gitmodules,}', + \ 'gitrebase': '{git-rebase-todo,}', + \ 'gitsendemail': '{.gitsendemail.*,}', + \ 'glsl': '{*.glsl,*.fp,*.frag,*.frg,*.fs,*.fsh,*.fshader,*.geo,*.geom,*.glslf,*.glslv,*.gs,*.gshader,*.shader,*.tesc,*.tese,*.vert,*.vrx,*.vsh,*.vshader,*.comp,}', + \ 'gmpl': '{*.mod,}', + \ 'gnuplot': '{*.gp,*.gnu,*.gnuplot,*.p,*.plot,*.plt,}', + \ 'go': '{*.go,}', + \ 'gohtmltmpl': '{*.tmpl,}', + \ 'gomod': '{go.mod,}', + \ 'graphql': '{*.graphql,*.gql,*.graphqls,}', + \ 'groovy': '{*.gradle,}', + \ 'grub': '{,}', + \ 'haml': '{*.haml,*.haml.deface,*.hamlc,*.hamlbars,}', + \ 'haproxy': '{*.cfg,haproxy.cfg,haproxy*.c*,}', + \ 'haskell': '{*.hs,*.hs-boot,*.hsc,*.bpk,*.hsig,}', + \ 'haxe': '{*.hx,*.hxsl,}', + \ 'hcl': '{*.hcl,*.nomad,*.tf,*.tfvars,*.workflow,Appfile,}', + \ 'helm': '{,}', + \ 'help': '{,}', + \ 'hive': '{*.q,*.hql,*.ql,}', + \ 'html': '{*.html,*.htm,*.html.hl,*.inc,*.st,*.xht,*.xhtml,}', + \ 'html.twig': '{*.twig,}', + \ 'i3config': '{*.i3.config,*.i3config,i3.config,i3config,.i3.config,.i3config,}', + \ 'icalendar': '{*.ics,}', + \ 'idris': '{*.idr,*.lidr,idris-response,}', + \ 'ion': '{*.ion,}', + \ 'javascript': '{*.js,*._js,*.bones,*.cjs,*.es,*.es6,*.frag,*.gs,*.jake,*.jsb,*.jscad,*.jsfl,*.jsm,*.jss,*.mjs,*.njs,*.pac,*.sjs,*.ssjs,*.xsjs,*.xsjslib,Jakefile,}', + \ 'javascriptreact': '{*.jsx,}', + \ 'jinja.html': '{*.jinja,*.j2,*.jinja2,*.njk,}', + \ 'jq': '{*.jq,.jqrc,}', + \ 'json': '{*.json,*.avsc,*.geojson,*.gltf,*.har,*.ice,*.JSON-tmLanguage,*.jsonl,*.mcmeta,*.tfstate,*.tfstate.backup,*.topojson,*.webapp,*.webmanifest,*.yy,*.yyp,*.jsonp,*.template,.arcconfig,.htmlhintrc,.tern-config,.tern-project,.watchmanconfig,composer.lock,mcmod.info,}', + \ 'json5': '{*.json5,}', + \ 'jsonnet': '{*.jsonnet,*.libsonnet,}', + \ 'jst': '{*.ejs,*.ect,*.jst,}', + \ 'julia': '{*.jl,}', + \ 'kotlin': '{*.kt,*.ktm,*.kts,}', + \ 'ledger': '{*.ldg,*.ledger,*.journal,}', + \ 'less': '{*.less,}', + \ 'lilypond': '{*.ly,*.ily,}', + \ 'litcoffee': '{*.litcoffee,*.coffee.md,}', + \ 'livescript': '{*.ls,*._ls,Slakefile,}', + \ 'llvm': '{*.ll,}', + \ 'log': '{*.log,*.LOG,*_log,*_LOG,}', + \ 'lua': '{*.lua,*.fcgi,*.nse,*.p8,*.pd_lua,*.rbxs,*.rockspec,*.wlua,.luacheckrc,}', + \ 'm4': '{*.m4,*.at,}', + \ 'mako': '{*.mako,*.mao,}', + \ 'markdown': '{*.md,*.markdown,*.mdown,*.mdwn,*.mdx,*.mkd,*.mkdn,*.mkdown,*.ronn,*.workbook,contents.lr,}', + \ 'markdown.mdx': '{*.mdx,}', + \ 'meson': '{meson.build,meson_options.txt,}', + \ 'mma': '{*.mathematica,*.cdf,*.m,*.ma,*.mt,*.nb,*.nbp,*.wl,*.wlt,*.wls,}', + \ 'moon': '{*.moon,}', + \ 'murphi': '{*.m,}', + \ 'mustache': '{*.handlebars,*.hbs,*.hulk,*.hjs,*.mustache,*.njk,*.hogan,*.hdbs,*.hb,}', + \ 'nginx': '{*.nginx,*.nginxconf,*.vhost,nginx.conf,nginx*.conf,*nginx.conf,}', + \ 'nim': '{*.nim,*.nim.cfg,*.nimble,*.nimrod,*.nims,nim.cfg,}', + \ 'nix': '{*.nix,}', + \ 'oasis': '{_oasis,}', + \ 'objc': '{*.m,*.h,}', + \ 'ocaml': '{*.ml,*.eliom,*.eliomi,*.ml4,*.mli,*.mll,*.mly,*.mlt,*.mlp,*.mlip,*.mli.cppo,*.ml.cppo,.ocamlinit,}', + \ 'ocamlbuild_tags': '{_tags,}', + \ 'ocpbuild': '{*.ocp,}', + \ 'ocpbuildroot': '{*.root,}', + \ 'octave': '{*.oct,*.m,}', + \ 'omake': '{*.om,OMakefile,OMakeroot,OMakeroot.in,}', + \ 'opam': '{*.opam,*.opam.template,opam,}', + \ 'opencl': '{*.cl,*.opencl,}', + \ 'perl': '{*.pl,*.al,*.cgi,*.fcgi,*.perl,*.ph,*.plx,*.pm,*.psgi,*.t,Makefile.PL,Rexfile,ack,cpanfile,}', + \ 'php': '{*.php,*.aw,*.ctp,*.fcgi,*.inc,*.php3,*.php4,*.php5,*.phps,*.phpt,.php,.php_cs,.php_cs.dist,Phakefile,}', + \ 'plantuml': '{*.puml,*.iuml,*.plantuml,*.uml,*.pu,}', + \ 'pony': '{*.pony,}', + \ 'proto': '{*.proto,}', + \ 'ps1': '{*.ps1,*.psd1,*.psm1,*.pssc,}', + \ 'ps1xml': '{*.ps1xml,}', + \ 'pug': '{*.jade,*.pug,}', + \ 'puppet': '{*.pp,Modulefile,}', + \ 'purescript': '{*.purs,}', + \ 'python': '{*.py,*.cgi,*.fcgi,*.gyp,*.gypi,*.lmi,*.py3,*.pyde,*.pyi,*.pyp,*.pyt,*.pyw,*.rpy,*.smk,*.spec,*.tac,*.wsgi,*.xpy,.gclient,DEPS,SConscript,SConstruct,Snakefile,wscript,}', + \ 'qmake': '{*.pro,*.pri,}', + \ 'qml': '{*.qml,*.qbs,}', + \ 'r': '{*.r,*.rd,*.rsx,*.s,*.S,.Rprofile,expr-dist,}', + \ 'racket': '{*.rkt,*.rktd,*.rktl,*.scrbl,}', + \ 'ragel': '{*.rl,}', + \ 'raku': '{*.6pl,*.6pm,*.nqp,*.p6,*.p6l,*.p6m,*.pl,*.pl6,*.pm,*.pm6,*.t,*.rakudoc,*.rakutest,*.raku,*.rakumod,*.pod6,*.t6,}', + \ 'raml': '{*.raml,}', + \ 'razor': '{*.cshtml,*.razor,}', + \ 'reason': '{*.re,*.rei,}', + \ 'requirements': '{*.pip,*requirements.{txt,in},*require.{txt,in},constraints.{txt,in},}', + \ 'rhelp': '{*.rd,}', + \ 'rst': '{*.rst,*.rest,*.rest.txt,*.rst.txt,}', + \ 'ruby': '{*.rb,*.builder,*.eye,*.fcgi,*.gemspec,*.god,*.jbuilder,*.mspec,*.pluginspec,*.podspec,*.rabl,*.rake,*.rbi,*.rbuild,*.rbw,*.rbx,*.ru,*.ruby,*.spec,*.thor,*.watchr,*.rxml,*.rjs,*.rant,*.axlsx,*.cap,*.opal,.irbrc,.pryrc,.simplecov,Appraisals,Berksfile,Brewfile,Buildfile,Capfile,Dangerfile,Deliverfile,Fastfile,Gemfile,Gemfile.lock,Guardfile,Jarfile,Mavenfile,Podfile,Puppetfile,Rakefile,Snapfile,Thorfile,Vagrantfile,buildfile,Rantfile,.autotest,Cheffile,KitchenSink,Routefile,.Guardfile,.Brewfile,vagrantfile,[Rr]akefile*,*_spec.rb,}', + \ 'rust': '{*.rs,*.rs.in,}', + \ 'sbt.scala': '{*.sbt,}', + \ 'scala': '{*.scala,*.kojo,*.sbt,*.sc,}', + \ 'scss': '{*.scss,}', + \ 'sexplib': '{*.sexp,}', + \ 'sh': '{*.sh,*.bash,*.bats,*.cgi,*.command,*.env,*.fcgi,*.ksh,*.sh.in,*.tmux,*.tool,*.zsh,.bash_aliases,.bash_history,.bash_logout,.bash_profile,.bashrc,.cshrc,.env,.env.example,.flaskenv,.login,.profile,.zlogin,.zlogout,.zprofile,.zshenv,.zshrc,9fs,PKGBUILD,bash_aliases,bash_logout,bash_profile,bashrc,cshrc,gradlew,login,man,profile,zlogin,zlogout,zprofile,zshenv,zshrc,}', + \ 'slim': '{*.slim,}', + \ 'slime': '{*.slime,}', + \ 'smt2': '{*.smt2,*.smt,}', + \ 'solidity': '{*.sol,}', + \ 'sql': '{*.pgsql,*.sql,}', + \ 'stylus': '{*.styl,*.stylus,}', + \ 'svelte': '{*.svelte,}', + \ 'svg': '{*.svg,}', + \ 'swift': '{*.swift,}', + \ 'sxhkdrc': '{*.sxhkdrc,sxhkdrc,}', + \ 'systemd': '{*.automount,*.mount,*.path,*.service,*.socket,*.swap,*.target,*.timer,}', + \ 'tablegen': '{*.td,}', + \ 'terraform': '{*.hcl,*.nomad,*.tf,*.tfvars,*.workflow,}', + \ 'textile': '{*.textile,}', + \ 'thrift': '{*.thrift,}', + \ 'tmux': '{.tmux.conf,}', + \ 'toml': '{*.toml,Cargo.lock,Gopkg.lock,poetry.lock,Pipfile,}', + \ 'tptp': '{*.p,*.tptp,*.ax,}', + \ 'trasys': '{*.inp,}', + \ 'typescript': '{*.ts,}', + \ 'typescriptreact': '{*.tsx,}', + \ 'unison': '{*.u,*.uu,}', + \ 'v': '{*.v,}', + \ 'vala': '{*.vala,*.vapi,*.valadoc,}', + \ 'vbnet': '{*.vb,*.vbhtml,}', + \ 'vcl': '{*.vcl,}', + \ 'velocity': '{*.vm,}', + \ 'vmasm': '{*.mar,}', + \ 'vue': '{*.vue,*.wpy,}', + \ 'xdc': '{*.xdc,}', + \ 'xml': '{*.xml,*.adml,*.admx,*.ant,*.axml,*.builds,*.ccproj,*.ccxml,*.clixml,*.cproject,*.cscfg,*.csdef,*.csl,*.csproj,*.ct,*.depproj,*.dita,*.ditamap,*.ditaval,*.dll.config,*.dotsettings,*.filters,*.fsproj,*.fxml,*.glade,*.gml,*.gmx,*.grxml,*.gst,*.iml,*.ivy,*.jelly,*.jsproj,*.kml,*.launch,*.mdpolicy,*.mjml,*.mm,*.mod,*.mxml,*.natvis,*.ncl,*.ndproj,*.nproj,*.nuspec,*.odd,*.osm,*.pkgproj,*.pluginspec,*.proj,*.props,*.ps1xml,*.psc1,*.pt,*.rdf,*.resx,*.rss,*.sch,*.scxml,*.sfproj,*.shproj,*.srdf,*.storyboard,*.sublime-snippet,*.targets,*.tml,*.ts,*.tsx,*.ui,*.urdf,*.ux,*.vbproj,*.vcxproj,*.vsixmanifest,*.vssettings,*.vstemplate,*.vxml,*.wixproj,*.workflow,*.wsdl,*.wsf,*.wxi,*.wxl,*.wxs,*.x3d,*.xacro,*.xaml,*.xib,*.xlf,*.xliff,*.xmi,*.xml.dist,*.xproj,*.xsd,*.xspec,*.xul,*.zcml,*.cdxml,.classpath,.cproject,.project,App.config,NuGet.config,Settings.StyleCop,Web.Debug.config,Web.Release.config,Web.config,packages.config,}', + \ 'xml.twig': '{*.xml.twig,}', + \ 'xsl': '{*.xslt,*.xsl,}', + \ 'yaml': '{*.yml,*.mir,*.reek,*.rviz,*.sublime-syntax,*.syntax,*.yaml,*.yaml-tmlanguage,*.yaml.sed,*.yml.mysql,.clang-format,.clang-tidy,.gemrc,glide.lock,yarn.lock,fish_history,fish_read_history,}', + \ 'yaml.ansible': '{playbook.y{a,}ml,site.y{a,}ml,main.y{a,}ml,local.y{a,}ml,requirements.y{a,}ml,tasks.*.y{a,}ml,roles.*.y{a,}ml,handlers.*.y{a,}ml,}', + \ 'yaml.docker-compose': '{docker-compose*.yaml,docker-compose*.yml,}', + \ 'zephir': '{*.zep,}', + \ 'zig': '{*.zig,*.zir,}', + \ 'zir': '{*.zir,}', + \ 'zsh': '{*.zsh,.zshrc,.zshenv,.zlogin,.zprofile,.zlogout,}', + \} + +func! sleuth#GlobForFiletype(type) + return get(s:globs, a:type, '') +endfunc diff --git a/plugin/sleuth.vim b/plugin/sleuth.vim new file mode 100644 index 00000000..12086173 --- /dev/null +++ b/plugin/sleuth.vim @@ -0,0 +1,164 @@ +" Heuristically set buffer options +" +" Modified version of vim-sleuth: +" - softtab and tabstop reduced from 8 to 2 +" - number of considered lines reduced from 1024 to 64 +" - maximum 6 other files are checked instead of 20 +" - check maximum of files 2 per directory level instead of 8 +" - maximum of 3 directory levels are checked +" - globs are concatenated for performance + +if exists("g:loaded_sleuth") || v:version < 700 || &cp + finish +endif +let g:loaded_sleuth = 1 + +function! s:guess(lines) abort + let options = {} + let heuristics = {'spaces': 0, 'hard': 0, 'soft': 0} + let ccomment = 0 + let podcomment = 0 + let triplequote = 0 + let backtick = 0 + let xmlcomment = 0 + let softtab = repeat(' ', 2) + + for line in a:lines + if !len(line) || line =~# '^\s*$' + 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 + + if line =~# '^\t' + let heuristics.hard += 1 + elseif line =~# '^' . softtab + let heuristics.soft += 1 + endif + if line =~# '^ ' + let heuristics.spaces += 1 + endif + let indent = len(matchstr(substitute(line, '\t', softtab, 'g'), '^ *')) + if indent > 1 && (indent < 4 || indent % 2 == 0) && + \ get(options, 'shiftwidth', 99) > indent + let options.shiftwidth = indent + endif + endfor + + if heuristics.hard && !heuristics.spaces + return {'expandtab': 0, 'shiftwidth': &tabstop} + elseif heuristics.soft != heuristics.hard + let options.expandtab = heuristics.soft > heuristics.hard + if heuristics.hard + let options.tabstop = 2 + endif + endif + + return options +endfunction + +function! s:apply_if_ready(options) abort + if !has_key(a:options, 'expandtab') || !has_key(a:options, 'shiftwidth') + return 0 + else + for [option, value] in items(a:options) + call setbufvar('', '&'.option, value) + endfor + return 1 + endif +endfunction + +function! s:detect() abort + if &buftype ==# 'help' + return + endif + + let options = s:guess(getline(1, 64)) + if s:apply_if_ready(options) + return + endif + let c = 6 + let pattern = c > 0 ? sleuth#GlobForFiletype(&filetype) : '' + let dir = expand('%:p:h') + let level = 3 + while isdirectory(dir) && dir !=# fnamemodify(dir, ':h') && c > 0 && level > 0 + let level -= 1 + for neighbor in glob(dir.'/'.pattern,0,1)[0:1] + if neighbor !=# expand('%:p') && filereadable(neighbor) + call extend(options, s:guess(readfile(neighbor, '', 32)), 'keep') + let c -= 1 + endif + if s:apply_if_ready(options) + let b:sleuth_culprit = neighbor + return + endif + if c <= 0 + break + endif + endfor + if c <= 0 + break + endif + let dir = fnamemodify(dir, ':h') + endwhile + if has_key(options, 'shiftwidth') + return s:apply_if_ready(extend({'expandtab': 1}, options)) + endif +endfunction + +setglobal smarttab + +if !exists('g:did_indent_on') + filetype indent on +endif + +augroup polyglot + autocmd! + autocmd FileType * call s:detect() +augroup END diff --git a/scripts/build b/scripts/build index 1fe148e7..2fcbe235 100755 --- a/scripts/build +++ b/scripts/build @@ -716,6 +716,39 @@ def detect_filetypes }] end +def generate_plugins(packages) + FileUtils.mkdir_p('autoload/polyglot') + + output = "let s:globs = {\n" + + patterns = Hash.new { |h, k| h[k] = [] } + + for package in packages + for filetype in package["filetypes"] + extensions = (filetype["extensions"] || []).map { |e| "*.#{e}" } + files = (filetype["filenames"] || []).reject { |e| e.match(/\*\*|\//) } + patterns[filetype["name"]].concat(extensions) + patterns[filetype["name"]].concat(files) + end + end + + for filetype in patterns.keys.sort + output << " \\ '#{filetype}': '{#{patterns[filetype].uniq.join(",")},}',\n" + end + output << " \\}\n\n" + + + output << <<~EOS + func! sleuth#GlobForFiletype(type) + return get(s:globs, a:type, '') + endfunc + EOS + + + File.write('autoload/sleuth.vim', output) +end + + if __FILE__ == $0 if !ENV["DEV"] FileUtils.rm_rf("tmp") @@ -725,6 +758,7 @@ if __FILE__ == $0 download(packages) extract(packages) generate_ftdetect(packages, heuristics) + generate_plugins(packages) generate_tests(packages) puts(" Bye! Have a wonderful time!") |