Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect original filetype ftdetect #156

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------
Expand Down
31 changes: 23 additions & 8 deletions ftdetect/puppet.lua
Original file line number Diff line number Diff line change
@@ -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,
}
})
41 changes: 32 additions & 9 deletions ftdetect/puppet.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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('<afile>: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('<afile>') !~# '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
49 changes: 7 additions & 42 deletions ftplugin/epuppet.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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')
Expand Down
40 changes: 3 additions & 37 deletions syntax/epuppet.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 50 additions & 16 deletions test/filetype/epuppet.vader
Original file line number Diff line number Diff line change
@@ -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'
2 changes: 1 addition & 1 deletion test/syntax/epuppet.vader
Original file line number Diff line number Diff line change
@@ -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 %>
Expand Down