diff --git a/README.md b/README.md index 64f4502..adb7850 100644 --- a/README.md +++ b/README.md @@ -61,9 +61,19 @@ With [Plug](https://github.com/junegunn/vim-plug) In your ~/.vimrc (or stdpath('config') . '/init.vim' for Neovim) - call plug#begin() - rodjek/vim-puppet - call plug#end() +```vim + call plug#begin() + Plug 'rodjek/vim-puppet' + call plug#end() +``` + +if you want to load only for puppet type use (pay attention to the * for epupet type) + +```vim + call plug#begin() + Plug 'rodjek/vim-puppet', { 'for': ['puppet', '*epuppet'] } + call plug#end() +``` Testing ------- diff --git a/ftdetect/puppet.lua b/ftdetect/puppet.lua index 11b51a5..7074a4f 100644 --- a/ftdetect/puppet.lua +++ b/ftdetect/puppet.lua @@ -1,16 +1,31 @@ --- Some epp files may get marked as "mason" type before this script is reached. --- Vim's own scripts.vim forces the type if it detects a `<%` at the start of --- the file. All files ending in .epp should be epuppet +-- nvim older than 0.7.0 vim.filetype is null, and detection fallback to vimscript +if vim.filetype == nil then + return nil +end vim.filetype.add({ extension = { epp = function(path, bufnr) - local path_wo_epp = path:sub(1,-5) - local matched = vim.filetype.match({ buf = bufnr, filename = path_wo_epp }) - if matched ~= nil and matched ~= 'mason' then - vim.b.epuppet_subtype = matched + local root = vim.fn.fnamemodify(path, ':r') + local matched = vim.filetype.match({ buf = bufnr, filename = root }) + -- subtype not detected in lua file, return nil so detection fallback + -- on ftdetect/*.vim + if matched == nil then + return nil + -- don't loop + elseif string.match(matched, 'epuppet') then + return matched + -- Some epp files may get marked as "mason" type before this script is reached. + -- NVim's own detect.lua forces the type if it detects a `<%` at the start of + -- the file. All files ending in .epp should be epuppet + elseif matched ~= 'mason' then + return matched .. '.epuppet' + end + if vim.g.epuppet_default_subtype ~= nil then + return vim.g.epuppet_default_subtype .. '.epuppet' + else + return 'epuppet' end - return 'epuppet' end, } }) diff --git a/ftdetect/puppet.vim b/ftdetect/puppet.vim index 6c608a0..70397e8 100644 --- a/ftdetect/puppet.vim +++ b/ftdetect/puppet.vim @@ -12,12 +12,35 @@ if !has('patch-8.2.2334') && !has('nvim-0.5.0') " for .pp files. au! BufRead,BufNewFile *.pp setfiletype puppet endif -" Vim now has autodetection for epuppet and Puppetfile. We only need to add -" autocommands for older versions of vim / neovim -if !has('patch-8.2.2402') && !has('nvim-0.5.0') - " Some epp files may get marked as "mason" type before this script is reached. - " Vim's own scripts.vim forces the type if it detects a `<%` at the start of - " the file. All files ending in .epp should be epuppet - au! BufRead,BufNewFile *.epp setf epuppet - au BufRead,BufNewFile Puppetfile setfiletype ruby -endif +au BufRead,BufNewFile Puppetfile setfiletype ruby + +" au! is needed because epuppet already declared in filetype.vim +au! BufNewFile,BufRead *.epp call DetectSubepuppetNativeType() +function! DetectSubepuppetNativeType() + if !exists('g:epuppet_default_subtype') + let g:epuppet_default_subtype = 'sh' + endif + if exists('*fnameescape') + execute 'doautocmd filetypedetect BufRead ' .fnameescape(expand(':r')) + " don't loop + if &filetype =~# 'epuppet' + return + endif + " Some epp files may get marked as "mason" type before this script is reached. + " Vim's own script.vim forces the type if it detects a `<%` at the start of + " the file. All files ending in .epp should be epuppet + if &filetype !=# '' && !( &filetype ==# 'mason' && expand('') !~# 'mason') + let b:epuppet_subtype = &filetype + let &filetype = b:epuppet_subtype . '.epuppet' + else + if exists('g:epuppet_default_subtype') && g:epuppet_default_subtype !=# '' + let &filetype = g:epuppet_default_subtype . '.epuppet' + else + let &filetype = 'epuppet' + endif + endif + elseif &verbose > 0 + echomsg 'Warning: epuppet subtype will not be recognized because this version of Vim does not have fnameescape()' + setf epuppet + endif +endfunction diff --git a/ftplugin/epuppet.vim b/ftplugin/epuppet.vim index 6bbb49c..b672872 100644 --- a/ftplugin/epuppet.vim +++ b/ftplugin/epuppet.vim @@ -4,8 +4,8 @@ " URL: https://github.com/rodjek/vim-puppet " Last Change: 2019-09-01 -" Only do this when not done yet for this buffer -if exists('b:did_ftplugin') +" since this filetype can be loaded along a subtype, don't test with b:did_ftplugin +if (exists('b:did_ftplugin_epuppet')) finish endif @@ -17,48 +17,10 @@ let s:undo_ftplugin = '' if has('win32') let s:browsefilter = "All Files (*.*)\t*.*\n" else - let s:browsefilter = "All Files (*)\t*\n" + let s:browsefilter = "All Files (*)\t*\n" endif let s:match_words = '' -if !exists('g:epuppet_default_subtype') - let g:epuppet_default_subtype = 'sh' -endif - -if &filetype =~# '^epuppet\.' - let b:epuppet_subtype = matchstr(&filetype,'^epuppet\.\zs\w\+') -elseif !exists('b:epuppet_subtype') - let b:epuppet_subtype = matchstr(substitute(expand('%:t'),'\c\%(\.epp\)\+$','',''),'\.\zs\w\+\%(\ze+\w\+\)\=$') - " TODO instead of listing exceptions like this, can we instead recognize - " extension -> type mapping? - if b:epuppet_subtype ==? 'rhtml' - let b:epuppet_subtype = 'html' - elseif b:epuppet_subtype ==? 'rb' - let b:epuppet_subtype = 'ruby' - elseif b:epuppet_subtype ==? 'yml' - let b:epuppet_subtype = 'yaml' - elseif b:epuppet_subtype ==? 'js' - let b:epuppet_subtype = 'javascript' - elseif b:epuppet_subtype ==? 'txt' - " Conventional; not a real file type - let b:epuppet_subtype = 'text' - elseif b:epuppet_subtype ==? 'py' - let b:epuppet_subtype = 'python' - elseif b:epuppet_subtype ==? 'rs' - let b:epuppet_subtype = 'rust' - elseif b:epuppet_subtype ==?'' - let b:epuppet_subtype = g:epuppet_default_subtype - endif -endif - -if exists('b:epuppet_subtype') && b:epuppet_subtype != '' && b:epuppet_subtype !=? 'epuppet' - exe 'runtime! ftplugin/'.b:epuppet_subtype.'.vim ftplugin/'.b:epuppet_subtype.'_*.vim ftplugin/'.b:epuppet_subtype.'/*.vim' -endif -unlet! b:did_ftplugin - -runtime! ftplugin/sh.vim -unlet! b:did_ftplugin - " Override our defaults if these were set by an included ftplugin. if exists('b:undo_ftplugin') let s:undo_ftplugin = b:undo_ftplugin @@ -77,8 +39,11 @@ let s:include = &l:include let s:path = &l:path let s:suffixesadd = &l:suffixesadd +if (exists('b:did_ftplugin')) + unlet b:did_ftplugin +endif runtime! ftplugin/puppet.vim -let b:did_ftplugin = 1 +let b:did_ftplugin_epuppet = 1 " Combine the new set of values with those previously included. if exists('b:undo_ftplugin') diff --git a/syntax/epuppet.vim b/syntax/epuppet.vim index 23ceedf..2d1be63 100644 --- a/syntax/epuppet.vim +++ b/syntax/epuppet.vim @@ -4,46 +4,12 @@ " URL: https://github.com/rodjek/vim-puppet " Last Change: 2019-09-01 -" quit when a syntax file was already loaded {{{1 -if exists('b:current_syntax') +" since this filetype can be loaded along a subtype, don't test with b:current_syntax +if (exists('b:current_syntax') && b:current_syntax ==# 'epuppet') finish endif -if !exists('g:epuppet_default_subtype') - let g:epuppet_default_subtype = 'sh' -endif - -if &filetype =~# '^epuppet\.' - let b:epuppet_subtype = matchstr(&filetype,'^epuppet\.\zs\w\+') -elseif !exists('b:epuppet_subtype') - let b:epuppet_subtype = matchstr(substitute(expand('%:t'),'\c\%(\.epp\)\+$','',''),'\.\zs\w\+\%(\ze+\w\+\)\=$') - " TODO instead of listing exceptions like this, can we instead recognize - " extension -> type mapping? - if b:epuppet_subtype ==? 'rhtml' - let b:epuppet_subtype = 'html' - elseif b:epuppet_subtype ==? 'rb' - let b:epuppet_subtype = 'ruby' - elseif b:epuppet_subtype ==? 'yml' - let b:epuppet_subtype = 'yaml' - elseif b:epuppet_subtype ==? 'js' - let b:epuppet_subtype = 'javascript' - elseif b:epuppet_subtype ==? 'txt' - " Conventional; not a real file type - let b:epuppet_subtype = 'text' - elseif b:epuppet_subtype ==? 'py' - let b:epuppet_subtype = 'python' - elseif b:epuppet_subtype ==? 'rs' - let b:epuppet_subtype = 'rust' - elseif b:epuppet_subtype ==? '' - let b:epuppet_subtype = g:epuppet_default_subtype - endif -endif - -if exists('b:epuppet_subtype') && b:epuppet_subtype != '' && b:epuppet_subtype !=? 'epuppet' - exe 'runtime! syntax/'.b:epuppet_subtype.'.vim' - unlet! b:current_syntax -endif - +unlet! b:current_syntax syn include @puppetTop syntax/puppet.vim syn cluster ePuppetRegions contains=ePuppetBlock,ePuppetExpression,ePuppetComment diff --git a/test/filetype/epuppet.vader b/test/filetype/epuppet.vader index 87a5d56..261c317 100644 --- a/test/filetype/epuppet.vader +++ b/test/filetype/epuppet.vader @@ -1,33 +1,67 @@ -Execute (Filetype detection on a new empty file): +Execute (Setup default subtype to Undefined): + Save g:epuppet_default_subtype + if exists('g:epuppet_default_subtype') + unlet g:epuppet_default_subtype + end + +Execute (Filetype detection on a new empty file without g:epuppet_default_subtype defined by user): + edit foo.epp + AssertEqual &filetype, 'sh.epuppet' + " new is needed before bedelete https://github.com/junegunn/vader.vim/issues/134 + new + " bdelete is needed otherwise g:epuppet_default_subtype is not reseted for the next tests + bdelete foo.epp + +Execute (epuppet test_with_leading_tag without g:epuppet_default_subtype defined by user): + edit test/test-files/test_with_leading_tag.epp + AssertEqual &filetype, 'sh.epuppet' + new + bdelete test/test-files/test_with_leading_tag.epp + +Execute (Setting default subtype to 'conf'): + let g:epuppet_default_subtype = 'conf' + +Execute (Filetype detection on a new empty file with g:epuppet_default_subtype defined by user at 'conf'): edit foo.epp - AssertEqual &filetype, 'epuppet' + AssertEqual &filetype, 'conf.epuppet' -Execute (epuppet test_with_leading_tag): +Execute (epuppet test_with_leading_tag with g:epuppet_default_subtype defined by user at 'conf'): edit test/test-files/test_with_leading_tag.epp - AssertEqual &filetype, 'epuppet' + AssertEqual &filetype, 'conf.epuppet' + +Execute (Restore default subtype): + Restore g:epuppet_default_subtype -Execute (TODO: epuppet perl with shebang): +Execute (epuppet perl with shebang): edit test/test-files/test_perl_with_shebang.epp - AssertEqual &filetype, 'epuppet' - AssertEqual b:epuppet_subtype, 'perl' + AssertEqual &filetype, 'perl.epuppet' # We don't need to parse the shebang for shell since sh is the default subtype Execute (epuppet default to shell): edit test/test-files/test_shell_with_shebang.epp - AssertEqual &filetype, 'epuppet' - AssertEqual b:epuppet_subtype, 'sh' + AssertEqual &filetype, 'sh.epuppet' Execute (epuppet shell with extension): edit test/test-files/test_shell_with_extension.sh.epp - AssertEqual &filetype, 'epuppet' - AssertEqual b:epuppet_subtype, 'sh' + AssertEqual &filetype, 'sh.epuppet' Execute (epuppet php with extension): edit test/test-files/test_php_with_extension.php.epp - AssertEqual &filetype, 'epuppet' - AssertEqual b:epuppet_subtype, 'php' + AssertEqual &filetype, 'php.epuppet' -Execute (TODO: epuppet apache conf with path and extension): +Execute (epuppet apache conf with path and extension): edit test/test-files/etc/apache2/test.conf.epp - AssertEqual &filetype, 'epuppet' - AssertEqual b:epuppet_subtype, 'apache' + AssertEqual &filetype, 'apache.epuppet' + +# non sensical type to test corner caser +Execute (epuppet php with double subtype extension): + edit test/test-files/test.php.php.epp + AssertEqual &filetype, 'php.epuppet' + +Execute (epuppet php with double epuppet extension): + edit test/test-files/test.php.epp.epp + AssertEqual &filetype, 'php.epuppet' + +Execute (epuppet php with reversed extension): + edit test/test-files/test.epp.php + AssertEqual &filetype, 'php' diff --git a/test/syntax/epuppet.vader b/test/syntax/epuppet.vader index 9b6216f..438b442 100644 --- a/test/syntax/epuppet.vader +++ b/test/syntax/epuppet.vader @@ -1,4 +1,4 @@ -Given epuppet (template with litteral content puppet tags): +Given sh.epuppet (template with litteral content puppet tags): # Short litteral comment <% if $variable == '<%%somevalue%%>' { -%> MYVAR=<%= $variable %>