mirror of
https://github.com/ivuorinen/nvim-shellspec.git
synced 2026-01-26 11:34:04 +00:00
- 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
4.8 KiB
4.8 KiB
Code Style and Conventions
EditorConfig Settings
All files follow these rules from .editorconfig:
- Charset: UTF-8
- Line endings: LF (Unix-style)
- Indentation: 2 spaces (no tabs)
- Max line length: 160 characters
- Final newline: Required
- Trim trailing whitespace: Yes
Special Cases
- Markdown files: Don't trim trailing whitespace (for hard line breaks)
- Makefiles: Use tabs with width 4
Lua Code Conventions (New)
Module Structure
-- Module header with description
local M = {}
-- Import dependencies at top
local config = require('shellspec.config')
-- Private functions (local)
local function private_helper() end
-- Public functions (M.function_name)
function M.public_function() end
return M
Function Names
- Use
snake_casefor all functions - Private functions:
local function name() - Public functions:
function M.name()orM.name = function() - Descriptive names, avoid abbreviations
Variable Names
- Local variables:
local variable_name - Constants:
local CONSTANT_NAME(uppercase) - Table keys:
snake_case
Documentation
- Use LuaDoc style comments for public functions
- Include parameter and return type information
--- Format lines with ShellSpec DSL rules
-- @param lines table: Array of strings to format
-- @return table: Array of formatted strings
function M.format_lines(lines) end
Error Handling
- Use
pcall()for operations that might fail - Provide meaningful error messages
- Use
vim.notify()for user-facing messages
Vim Script Conventions (Enhanced)
Function Names
- Use
snake_case#function_name()format - Functions in autoload use namespace prefix:
shellspec#function_name() - Guard clauses with
abortkeyword:function! shellspec#format_buffer() abort - Private functions:
s:function_name()
Variable Names
- Local variables:
l:variable_name - Global variables:
g:variable_name - Buffer-local:
b:variable_name - Script-local:
s:variable_name
State Management
- Use descriptive state names:
'normal','heredoc' - Document state transitions in comments
- Initialize state variables clearly
Code Structure
" File header with description and author
if exists('g:loaded_plugin')
finish
endif
let g:loaded_plugin = 1
" Helper functions (private)
function! s:private_function() abort
endfunction
" Public functions
function! public#function() abort
endfunction
" Commands, autocommands at end
Comments
- Use
"for comments - Include descriptive headers for functions
- Comment complex logic blocks and state changes
- Document HEREDOC patterns and detection logic
Shell Script Style (bin/shellspec-format)
- Use
#!/bin/bashshebang - Double quote variables:
"$variable" - Use
[[ ]]for conditionals instead of[ ] - Proper error handling with exit codes
- Function names in
snake_case
Configuration Files
- YAML: 2-space indentation, 200 character line limit
- JSON: Pretty formatted, no trailing commas
- Markdown: 200 character line limit (relaxed from default 80)
- Lua: Follow Neovim Lua style guide
Naming Conventions
- Files: lowercase with hyphens (
shellspec-format) - Directories: lowercase (
autoload,syntax,ftdetect) - Lua modules: lowercase with dots (
shellspec.format) - Functions: namespace#function_name format (VimScript), snake_case (Lua)
- Variables: descriptive names, avoid abbreviations
Architecture Patterns
Dual Implementation Pattern
" Detect environment and choose implementation
if has('nvim-0.7')
" Use Lua implementation
lua require('module').function()
else
" Fall back to VimScript
call legacy#function()
endif
State Machine Pattern (Both Lua and VimScript)
-- Lua version
local state = State.NORMAL
if state == State.NORMAL then
-- handle normal formatting
elseif state == State.IN_HEREDOC then
-- preserve heredoc content
end
" VimScript version
let l:state = 'normal'
if l:state ==# 'normal'
" handle normal formatting
elseif l:state ==# 'heredoc'
" preserve heredoc content
endif
Configuration Pattern
-- Lua: Use vim.tbl_deep_extend for merging
local config = vim.tbl_deep_extend("force", defaults, user_opts)
" VimScript: Use get() with defaults
let l:option = get(g:, 'plugin_option', default_value)
Testing Conventions
- Create test files with
.spec.shextension - Test both Lua and VimScript implementations
- Include HEREDOC and comment test cases
- Use descriptive test names matching actual ShellSpec patterns
Documentation Standards
- Update README.md with new features
- Include both Lua and VimScript configuration examples
- Provide clear examples of HEREDOC and comment behavior
- Document breaking changes and migration paths