Files
nvim-shellspec/.serena/memories/code_style_conventions.md
Ismo Vuorinen ce620cd035 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
2025-09-09 21:13:38 +03:00

204 lines
4.8 KiB
Markdown

# 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
```lua
-- 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_case` for all functions
- Private functions: `local function name()`
- Public functions: `function M.name()` or `M.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
```lua
--- 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 `abort` keyword: `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
```vim
" 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/bash` shebang
- 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
```vim
" 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
-- Lua version
local state = State.NORMAL
if state == State.NORMAL then
-- handle normal formatting
elseif state == State.IN_HEREDOC then
-- preserve heredoc content
end
```
```vim
" VimScript version
let l:state = 'normal'
if l:state ==# 'normal'
" handle normal formatting
elseif l:state ==# 'heredoc'
" preserve heredoc content
endif
```
### Configuration Pattern
```lua
-- Lua: Use vim.tbl_deep_extend for merging
local config = vim.tbl_deep_extend("force", defaults, user_opts)
```
```vim
" VimScript: Use get() with defaults
let l:option = get(g:, 'plugin_option', default_value)
```
## Testing Conventions
- Create test files with `.spec.sh` extension
- 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