diff --git a/autoload/dein/parse.vim b/autoload/dein/parse.vim index 8d091e4..c07a339 100644 --- a/autoload/dein/parse.vim +++ b/autoload/dein/parse.vim @@ -487,48 +487,66 @@ function! dein#parse#_hooks_file(filename) abort let start_marker = g:dein#hooks_file_marker->split(',')[0] let end_marker = g:dein#hooks_file_marker->split(',')[1] - let hook_name = '' let options = {} - for line in path->readfile() - if hook_name ==# '' - let marker_pos = strridx(line, start_marker) - if strridx(line, start_marker) < 0 + let stack = [] + let line_number_pairs = [] + let lines = path->readfile() + + for idx in range(len(lines)) + let line = lines[idx] + + let start_marker_pos = stridx(line, start_marker) + if start_marker_pos >= 0 + let hook_name = line[: start_marker_pos]->matchstr( + \ '\s\+\zs[[:alnum:]_-]\+\ze\s*') + + call add(stack, [idx, hook_name]) + continue + endif + + let end_marker_pos = strridx(line, end_marker) + if end_marker_pos >= 0 + if len(stack) == 0 continue endif - " Get hook_name - let hook_name = line[: marker_pos]->matchstr( - \ '\s\+\zs[[:alnum:]_-]\+\ze\s*') - if hook_name == '' - call dein#util#_error( - \ printf('Invalid hook name %s: %s', a:filename, line)) - return {} + let [start_idx, name] = remove(stack, -1) + " Ignore nested lines + if len(stack) == 0 + call add(line_number_pairs, [name, start_idx, idx]) endif - if hook_name->stridx('hook_') == 0 - \ || hook_name ==# 'lua_add' - \ || hook_name ==# 'lua_source' - \ || hook_name->stridx('lua_done_') == 0 - \ || hook_name->stridx('lua_post_') == 0 - let dest = options - else - if !(options->has_key('ftplugin')) - let options['ftplugin'] = {} - endif - let dest = options['ftplugin'] + endif + endfor + + for [hook_name, start_idx, end_idx] in line_number_pairs + let cur_lines = lines[start_idx + 1: end_idx - 1] + + if hook_name->stridx('hook_') == 0 + \ || hook_name ==# 'lua_add' + \ || hook_name ==# 'lua_source' + \ || hook_name->stridx('lua_done_') == 0 + \ || hook_name->stridx('lua_post_') == 0 + + if !options->has_key(hook_name) + let options[hook_name] = "" endif + + let options[hook_name] ..= cur_lines->join("\n") else - if strridx(line, end_marker) >= 0 - let hook_name = '' + if hook_name == '' continue endif - " Concat - if dest->has_key(hook_name) - let dest[hook_name] ..= "\n" .. line - else - let dest[hook_name] = line + if !(options->has_key('ftplugin')) + let options['ftplugin'] = {} endif + + if !(options.ftplugin->has_key(hook_name)) + let options.ftplugin[hook_name] = "" + endif + + let options['ftplugin'][hook_name] ..= cur_lines->join("\n") endif endfor diff --git a/test/parse.vim b/test/parse.vim index 2fe1fda..2d0746a 100644 --- a/test/parse.vim +++ b/test/parse.vim @@ -292,10 +292,28 @@ function! s:suite.hooks_file() abort " hook_source {{{ piyo }}} -END + END + + call writefile(hooks_file, filename) + + call s:assert.equals(dein#parse#_hooks_file(filename), #{ + \ hook_source: 'piyo', + \ }) + + let hooks_file =<< trim END + " hook_source {{{ + piyo + " {{{ + hogera + " }}} + " }}} + END + call writefile(hooks_file, filename) - call s:assert.equals(dein#parse#_hooks_file(filename), {}) + call s:assert.equals(dein#parse#_hooks_file(filename), #{ + \ hook_source: "piyo\n" . '" {{{' . "\n" . 'hogera' . "\n" . '" }}}', + \ }) let hooks_file =<< trim END -- lua_source {{{