mirror of
https://github.com/ivuorinen/nvim-shellspec.git
synced 2026-01-26 03:24:00 +00:00
feat: add first-class Neovim support with enhanced formatting
- Add modern Lua implementation with modular architecture - Implement HEREDOC preservation and smart comment indentation - Create dual implementation (Neovim Lua + VimScript fallback) - Add comprehensive health check and configuration system - Enhance formatting engine with state machine for context awareness - Update documentation with Lua configuration examples - Add memory files for development workflow and conventions
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
" ShellSpec DSL formatter functions
|
||||
" ShellSpec DSL formatter functions with HEREDOC and comment support
|
||||
|
||||
function! shellspec#format_buffer() abort
|
||||
let l:pos = getpos('.')
|
||||
@@ -10,35 +10,111 @@ function! shellspec#format_buffer() abort
|
||||
call setpos('.', l:pos)
|
||||
endfunction
|
||||
|
||||
" Detect HEREDOC start and return delimiter
|
||||
function! s:detect_heredoc_start(line) abort
|
||||
let l:trimmed = trim(a:line)
|
||||
|
||||
" Check for various HEREDOC patterns
|
||||
let l:patterns = [
|
||||
\ '<<\([A-Z_][A-Z0-9_]*\)',
|
||||
\ "<<'\([^']*\)'",
|
||||
\ '<<"\([^"]*\)"',
|
||||
\ '<<-\([A-Z_][A-Z0-9_]*\)'
|
||||
\ ]
|
||||
|
||||
for l:pattern in l:patterns
|
||||
let l:match = matchlist(l:trimmed, l:pattern)
|
||||
if !empty(l:match)
|
||||
return l:match[1]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Check if line ends a HEREDOC
|
||||
function! s:is_heredoc_end(line, delimiter) abort
|
||||
if empty(a:delimiter)
|
||||
return 0
|
||||
endif
|
||||
return trim(a:line) ==# a:delimiter
|
||||
endfunction
|
||||
|
||||
" Enhanced format_lines with HEREDOC and comment support
|
||||
function! shellspec#format_lines(lines) abort
|
||||
let l:result = []
|
||||
let l:indent = 0
|
||||
let l:state = 'normal' " States: normal, heredoc
|
||||
let l:heredoc_delimiter = ''
|
||||
let l:indent_comments = get(g:, 'shellspec_indent_comments', 1)
|
||||
|
||||
for l:line in a:lines
|
||||
let l:trimmed = trim(l:line)
|
||||
|
||||
" Skip empty lines and comments
|
||||
if l:trimmed == '' || l:trimmed =~ '^#'
|
||||
" Handle empty lines
|
||||
if l:trimmed == ''
|
||||
call add(l:result, l:line)
|
||||
continue
|
||||
endif
|
||||
|
||||
" Decrease indent for End
|
||||
if l:trimmed =~ '^End\s*$'
|
||||
let l:indent = max([0, l:indent - 1])
|
||||
endif
|
||||
" State machine for HEREDOC handling
|
||||
if l:state ==# 'normal'
|
||||
" Check for HEREDOC start
|
||||
let l:delimiter = s:detect_heredoc_start(l:line)
|
||||
if !empty(l:delimiter)
|
||||
let l:state = 'heredoc'
|
||||
let l:heredoc_delimiter = l:delimiter
|
||||
" Apply current indentation to HEREDOC start line
|
||||
let l:formatted = repeat(' ', l:indent) . l:trimmed
|
||||
call add(l:result, l:formatted)
|
||||
continue
|
||||
endif
|
||||
|
||||
" Apply current indentation
|
||||
let l:formatted = repeat(' ', l:indent) . l:trimmed
|
||||
call add(l:result, l:formatted)
|
||||
" Handle comments with proper indentation
|
||||
if l:trimmed =~ '^#' && l:indent_comments
|
||||
let l:formatted = repeat(' ', l:indent) . l:trimmed
|
||||
call add(l:result, l:formatted)
|
||||
continue
|
||||
endif
|
||||
|
||||
" Increase indent after block keywords
|
||||
if l:trimmed =~ '^\(Describe\|Context\|ExampleGroup\|It\|Specify\|Example\)'
|
||||
let l:indent += 1
|
||||
elseif l:trimmed =~ '^\([xf]\)\(Describe\|Context\|ExampleGroup\|It\|Specify\|Example\)'
|
||||
let l:indent += 1
|
||||
elseif l:trimmed =~ '^\(Data\|Parameters\)\s*$'
|
||||
let l:indent += 1
|
||||
" Handle End keyword (decrease indent first)
|
||||
if l:trimmed =~ '^End\s*$'
|
||||
let l:indent = max([0, l:indent - 1])
|
||||
let l:formatted = repeat(' ', l:indent) . l:trimmed
|
||||
call add(l:result, l:formatted)
|
||||
continue
|
||||
endif
|
||||
|
||||
" Apply normal indentation for other lines
|
||||
if l:trimmed !~ '^#' || !l:indent_comments
|
||||
let l:formatted = repeat(' ', l:indent) . l:trimmed
|
||||
call add(l:result, l:formatted)
|
||||
|
||||
" Increase indent after block keywords
|
||||
if l:trimmed =~ '^\(Describe\|Context\|ExampleGroup\|It\|Specify\|Example\)'
|
||||
let l:indent += 1
|
||||
elseif l:trimmed =~ '^\([xf]\)\(Describe\|Context\|ExampleGroup\|It\|Specify\|Example\)'
|
||||
let l:indent += 1
|
||||
elseif l:trimmed =~ '^\(Data\|Parameters\)\s*$'
|
||||
let l:indent += 1
|
||||
endif
|
||||
else
|
||||
" Preserve original comment formatting if indent_comments is false
|
||||
call add(l:result, l:line)
|
||||
endif
|
||||
|
||||
elseif l:state ==# 'heredoc'
|
||||
" Check for HEREDOC end
|
||||
if s:is_heredoc_end(l:line, l:heredoc_delimiter)
|
||||
let l:state = 'normal'
|
||||
let l:heredoc_delimiter = ''
|
||||
" Apply current indentation to HEREDOC end line
|
||||
let l:formatted = repeat(' ', l:indent) . l:trimmed
|
||||
call add(l:result, l:formatted)
|
||||
else
|
||||
" Preserve original indentation within HEREDOC
|
||||
call add(l:result, l:line)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
|
||||
Reference in New Issue
Block a user