lua-projects
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLua Projects
Lua 项目
Scope: Lua 5.4 (with LuaJIT notes where relevant). Targets config-driven projects like Neovim distributions, SketchyBar setups, and general Lua modules.
适用范围:Lua 5.4(相关LuaJIT说明会单独标注)。面向配置驱动型项目,如Neovim发行版、SketchyBar配置及通用Lua模块。
Style and Formatting
编码风格与格式化
Naming
命名规范
- for variables, functions, and file names
snake_case - only for class-like constructor tables (rare)
PascalCase - for true constants
UPPER_SNAKE - Prefix unused variables with (e.g.,
_)for _, v in ipairs(t)
- 变量、函数及文件名使用命名法
snake_case - 仅类构造器表使用命名法(少见场景)
PascalCase - 真正的常量使用命名法
UPPER_SNAKE - 未使用的变量前缀加(例如:
_)for _, v in ipairs(t)
Indentation and Layout
缩进与布局
- Use 2 spaces (common in Neovim/LazyVim ecosystem) or tabs (SketchyBar default) -- be consistent within a project
- Wrap lines at 100 characters; hard limit 120
- Trailing commas in multi-line tables are encouraged
- No spaces inside ,
{}, or(); spaces after commas and around operators[]
- 使用2个空格(Neovim/LazyVim生态通用)或制表符(SketchyBar默认)——同一项目内保持一致
- 行宽限制为100字符,硬上限120字符
- 多行表中建议使用 trailing commas
- 、
{}或()内部不添加空格;逗号后及运算符两侧需添加空格[]
Formatter: StyLua
格式化工具:StyLua
StyLua (v2.4+) is the standard Lua formatter. Configure via at the project root:
stylua.tomltoml
column_width = 100
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferDouble"For SketchyBar configs using tabs:
toml
indent_type = "Tabs"Run: or integrate as a pre-commit hook / editor format-on-save.
stylua .StyLua(v2.4+)是标准的Lua格式化工具。在项目根目录通过配置:
stylua.tomltoml
column_width = 100
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferDouble"对于使用制表符的SketchyBar配置:
toml
indent_type = "Tabs"运行命令: 或集成到pre-commit钩子/编辑器自动格式化功能中。
stylua .Linting
代码检查
Selene (recommended)
Selene(推荐)
Modern Lua linter written in Rust. Actively maintained (v0.30+). Provides rich diagnostics with named lint rules.
Config file :
selene.tomltoml
std = "lua54"For Neovim configs, use the standard library definition so globals like are recognized:
vimvimtoml
std = "lua54+vim"Run:
selene .基于Rust开发的现代Lua代码检查工具,维护活跃(v0.30+),提供带有命名规则的丰富诊断信息。
配置文件:
selene.tomltoml
std = "lua54"对于Neovim配置,使用标准库定义,以便识别等全局变量:
vimvimtoml
std = "lua54+vim"运行命令:
selene .Luacheck (legacy)
Luacheck(遗留工具)
Still detects some things Selene does not (uninitialized vars, unreachable code), but has been unmaintained since 2018. Use as a secondary pass if needed.
Config file :
.luacheckrclua
std = "lua54"
globals = { "vim" }仍能检测部分Selene未覆盖的问题(如未初始化变量、不可达代码),但自2018年起未再维护。必要时可作为二次检查工具。
配置文件:
.luacheckrclua
std = "lua54"
globals = { "vim" }Language Server: LuaLS
语言服务器:LuaLS
lua-language-server () provides diagnostics, completion, hover, and type checking.
LuaLSSettings file at project root:
.luarc.jsonjson
{
"runtime": { "version": "Lua 5.4" },
"diagnostics": { "globals": ["vim"] },
"workspace": {
"library": [],
"checkThirdParty": false
}
}For SketchyBar projects, add the SbarLua install path to so LuaLS resolves the module:
workspace.librarysketchybarjson
"workspace": {
"library": ["~/.local/share/sketchybar_lua"]
}lua-language-server()提供诊断、自动补全、悬停提示及类型检查功能。
LuaLS在项目根目录创建配置文件:
.luarc.jsonjson
{
"runtime": { "version": "Lua 5.4" },
"diagnostics": { "globals": ["vim"] },
"workspace": {
"library": [],
"checkThirdParty": false
}
}对于SketchyBar项目,将SbarLua安装路径添加到,以便LuaLS解析模块:
workspace.librarysketchybarjson
"workspace": {
"library": ["~/.local/share/sketchybar_lua"]
}Type Annotations
类型注解
LuaLS supports EmmyLua-style annotations. Use them for public API surfaces:
lua
---@param name string
---@param opts? { padding?: number, icon?: string }
---@return table item
local function add_item(name, opts)
-- ...
endLuaLS支持EmmyLua风格的类型注解,建议在公共API表面使用:
lua
---@param name string
---@param opts? { padding?: number, icon?: string }
---@return table item
local function add_item(name, opts)
-- ...
endModule Patterns
模块模式
The Return-Table Pattern
返回表模式
Every module file should a table (or a single value). Avoid polluting globals.
returnlua
local M = {}
function M.greet(name)
return "hello " .. name
end
return M每个模块文件应一个表(或单个值),避免污染全局命名空间。
returnlua
local M = {}
function M.greet(name)
return "hello " .. name
end
return MInit Modules
初始化模块
A directory with an is requireable by its directory name. Use to re-export or orchestrate sub-modules:
init.luainit.luaitems/
init.lua -- require("items") loads this
apple.lua
calendar.lualua
-- items/init.lua
require("items.apple")
require("items.calendar")包含的目录可通过目录名直接引用。使用重新导出或协调子模块:
init.luainit.luaitems/
init.lua -- require("items") 会加载此文件
apple.lua
calendar.lualua
-- items/init.lua
require("items.apple")
require("items.calendar")Avoid Globals
避免全局变量
lua
-- BAD: implicit global
sbar = require("sketchybar")
-- GOOD: local binding (use upvalues or pass explicitly)
local sbar = require("sketchybar")Exception: SketchyBar's example config sets as a global in because sub-modules reference it without an explicit require path. If following that convention, document it clearly and configure your linter to allow it:
sbarinit.luatoml
undefinedlua
-- 不良实践:隐式全局变量
sbar = require("sketchybar")
-- 良好实践:局部绑定(使用upvalue或显式传递)
local sbar = require("sketchybar")例外情况:SketchyBar示例配置在中设置为全局变量,因为子模块无需显式引用路径即可访问它。若遵循此约定,需清晰文档说明,并配置代码检查工具允许该全局变量:
init.luasbartoml
undefinedselene.toml
selene.toml
[lints]
global_usage = "allow"
undefined[lints]
global_usage = "allow"
undefinedProject Structure Patterns
项目结构模式
Neovim Config (LazyVim / lazy.nvim)
Neovim 配置(LazyVim / lazy.nvim)
~/.config/nvim/
init.lua -- minimal bootstrap: vim.loader.enable(), require("config.lazy")
lua/
config/
lazy.lua -- lazy.nvim bootstrap and setup
options.lua
keymaps.lua
autocmds.lua
plugins/
lsp.lua
treesitter.lua
ui.lua
editor.luaKey conventions:
- stays minimal -- call
init.luathen require configvim.loader.enable() - One plugin spec per file (or group related specs) in
lua/plugins/ - lazy.nvim auto-loads everything in
lua/plugins/ - Use table merging over
optsfunctions when possibleconfig
Plugin spec pattern:
lua
return {
"author/plugin.nvim",
event = "VeryLazy",
dependencies = { "nvim-lua/plenary.nvim" },
opts = {
setting = true,
},
keys = {
{ "<leader>x", "<cmd>PluginAction<cr>", desc = "Do thing" },
},
}~/.config/nvim/
init.lua -- 最小化启动脚本:vim.loader.enable(), require("config.lazy")
lua/
config/
lazy.lua -- lazy.nvim 启动与设置
options.lua
keymaps.lua
autocmds.lua
plugins/
lsp.lua
treesitter.lua
ui.lua
editor.lua核心约定:
- 保持极简——调用
init.lua后加载配置vim.loader.enable() - 目录下每个文件对应一个插件配置(或一组相关插件)
lua/plugins/ - lazy.nvim 自动加载下的所有内容
lua/plugins/ - 优先使用表合并而非
opts函数config
插件配置示例:
lua
return {
"author/plugin.nvim",
event = "VeryLazy",
dependencies = { "nvim-lua/plenary.nvim" },
opts = {
setting = true,
},
keys = {
{ "<leader>x", "<cmd>PluginAction<cr>", desc = "执行操作" },
},
}SketchyBar Config (SbarLua)
SketchyBar 配置(SbarLua)
~/.config/sketchybar/
sketchybarrc -- shell entry: sketchybar --config init.lua (or similar)
init.lua -- requires sbar, wraps in begin_config/end_config, runs event_loop
bar.lua -- bar-level properties
default.lua -- default item properties
colors.lua -- color palette table
icons.lua -- icon constants (SF Symbols / Nerd Font)
settings.lua -- shared settings (paddings, fonts)
items/
init.lua -- requires each item module
spaces.lua
front_app.lua
media.lua
...
helpers/
init.lua
app_icons.lua
default_font.lua
event_providers/ -- native helpers (C compiled)Key conventions:
- Wrap all setup between /
sbar.begin_config()for batchingsbar.end_config() - Always call at the end of
sbar.event_loop()init.lua - Use instead of
sbar.exec()to avoid blocking the event handleros.execute() - Properties use sub-tables instead of dot notation: not
icon = { y_offset = 10 }icon.y_offset - Color values are hex integers
0xAARRGGBB - Keep color/icon/settings as pure data modules that return a table
~/.config/sketchybar/
sketchybarrc -- Shell入口:sketchybar --config init.lua(或类似命令)
init.lua -- 引入sbar,包裹在begin_config/end_config中,运行事件循环
bar.lua -- 状态栏级属性配置
default.lua -- 项目默认属性配置
colors.lua -- 调色板表
icons.lua -- 图标常量(SF Symbols / Nerd Font)
settings.lua -- 共享设置(内边距、字体)
items/
init.lua -- 引入各个项目模块
spaces.lua
front_app.lua
media.lua
...
helpers/
init.lua
app_icons.lua
default_font.lua
event_providers/ -- 原生辅助工具(C语言编译)核心约定:
- 所有配置代码包裹在/
sbar.begin_config()之间以批量执行sbar.end_config() - 末尾必须调用
init.luasbar.event_loop() - 使用替代
sbar.exec()以避免阻塞事件处理器os.execute() - 属性使用子表而非点语法:而非
icon = { y_offset = 10 }icon.y_offset - 颜色值使用十六进制整数
0xAARRGGBB - 将颜色/图标/设置作为纯数据模块,仅返回表
Common Patterns
通用模式
Safe Require
安全引入模块
lua
local ok, mod = pcall(require, "optional_module")
if not ok then
return
endlua
local ok, mod = pcall(require, "optional_module")
if not ok then
return
endMetatables for OOP-ish Tables
面向对象风格的元表
lua
local Item = {}
Item.__index = Item
function Item.new(name)
return setmetatable({ name = name }, Item)
end
function Item:display()
return self.name
endlua
local Item = {}
Item.__index = Item
function Item.new(name)
return setmetatable({ name = name }, Item)
end
function Item:display()
return self.name
endConfig Merging
配置合并
lua
local defaults = { padding = 4, color = 0xffffffff }
local function apply(user_opts)
local cfg = {}
for k, v in pairs(defaults) do cfg[k] = v end
for k, v in pairs(user_opts or {}) do cfg[k] = v end
return cfg
endFor deep merging in Neovim: .
vim.tbl_deep_extend("force", defaults, user_opts)lua
local defaults = { padding = 4, color = 0xffffffff }
local function apply(user_opts)
local cfg = {}
for k, v in pairs(defaults) do cfg[k] = v end
for k, v in pairs(user_opts or {}) do cfg[k] = v end
return cfg
end在Neovim中进行深度合并:。
vim.tbl_deep_extend("force", defaults, user_opts)Testing
测试
Busted
Busted
The standard Lua test framework. Install via luarocks:
bash
luarocks install bustedlua
-- spec/greet_spec.lua
describe("greet", function()
local mod = require("mymod")
it("returns greeting", function()
assert.are.equal("hello world", mod.greet("world"))
end)
it("handles nil", function()
assert.has_error(function() mod.greet(nil) end)
end)
end)Run: or
bustedbusted spec/标准Lua测试框架,通过luarocks安装:
bash
luarocks install bustedlua
-- spec/greet_spec.lua
describe("greet", function()
local mod = require("mymod")
it("返回问候语", function()
assert.are.equal("hello world", mod.greet("world"))
end)
it("处理nil参数", function()
assert.has_error(function() mod.greet(nil) end)
end)
end)运行命令: 或
bustedbusted spec/Neovim Plugin Testing
Neovim 插件测试
Use 's test harness for Neovim-specific tests:
plenary.nvimbash
nvim --headless -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/init.lua'}"使用的测试框架进行Neovim专属测试:
plenary.nvimbash
nvim --headless -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/init.lua'}"Performance Notes
性能优化提示
- lookups are register-based; global lookups go through
localhash. Always localize hot-path references._ENV - Pre-size tables with known lengths:
local t = table.create and table.create(n) or {} - String concatenation in loops: accumulate in a table and at the end
table.concat() - Prefer over
ipairswhen iterating sequential arrays (faster and order-guaranteed)pairs - In LuaJIT (Neovim): avoid NYI (Not Yet Implemented) operations in tight loops -- check https://wiki.luajit.org/NYI
- 变量查找基于寄存器;全局变量查找需遍历
local哈希表。热路径中的引用始终使用局部变量。_ENV - 已知长度的表提前预分配:
local t = table.create and table.create(n) or {} - 循环中的字符串拼接:先将内容存入表,最后使用合并
table.concat() - 遍历顺序数组时优先使用而非
ipairs(速度更快且保证顺序)pairs - 在LuaJIT(Neovim)中:避免在密集循环中使用NYI(尚未实现)操作——参考https://wiki.luajit.org/NYI
Lua 5.4 Specifics
Lua 5.4 专属特性
Features available in 5.4 that older references may not cover:
- Integer subtype: integers and floats are distinct; is
type(1)but"number"ismath.type(1)"integer" - Bitwise operators: ,
&,|(xor),~(unary not),~,<<-- no need for>>orbit32librariesbit - Integer for-loop: uses native integers
for i = 1, n - Generational GC: for lower-latency collection
collectgarbage("generational") - and
<const>: local attributes for immutability and deterministic cleanup<close>
lua
local path <const> = "/tmp/data"
local f <close> = io.open(path, "r")Note: Neovim uses LuaJIT (Lua 5.1 compatible), so 5.4 features are not available in Neovim configs. Use 5.4 features only in standalone Lua or SketchyBar (if built against Lua 5.4).
5.4版本新增的特性,旧版参考文档可能未覆盖:
- 整数子类型:整数与浮点数是不同类型;返回
type(1)但"number"返回math.type(1)"integer" - 位运算符:、
&、|(异或)、~(一元非)、~、<<——无需使用>>或bit32库bit - 整数for循环:使用原生整数
for i = 1, n - 分代垃圾回收:实现低延迟回收
collectgarbage("generational") - 与
<const>:局部变量属性,用于不可变性和确定性清理<close>
lua
local path <const> = "/tmp/data"
local f <close> = io.open(path, "r")注意:Neovim使用LuaJIT(兼容Lua 5.1),因此Neovim配置中无法使用5.4特性。仅在独立Lua环境或基于Lua 5.4构建的SketchyBar中使用5.4特性。
Debugging
调试
- in Neovim for table inspection
print(vim.inspect(t)) - in standalone Lua (install via luarocks)
print(require("inspect")(t)) - SketchyBar logs to -- check there for Lua errors
~/.local/share/sketchybar/ - LuaLS diagnostics surface most type/require errors before runtime
- Neovim中使用查看表结构
print(vim.inspect(t)) - 独立Lua环境中使用(需通过luarocks安装inspect)
print(require("inspect")(t)) - SketchyBar日志存储于——可在此查看Lua错误
~/.local/share/sketchybar/ - LuaLS诊断可在运行前发现大多数类型/依赖错误
Tooling Summary
工具链汇总
| Tool | Purpose | Config File | Install |
|---|---|---|---|
| StyLua | Formatter | | |
| Selene | Linter | | |
| LuaLS | Language server | | via Mason or package manager |
| Busted | Test framework | | |
| Luarocks | Package manager | | system package manager |
| 工具 | 用途 | 配置文件 | 安装方式 |
|---|---|---|---|
| StyLua | 代码格式化 | | |
| Selene | 代码检查 | | |
| LuaLS | 语言服务器 | | 通过Mason或包管理器安装 |
| Busted | 测试框架 | | |
| Luarocks | 包管理器 | | 系统包管理器 |
Reference Projects
参考项目
| Project | URL | Focus |
|---|---|---|
| LazyVim | https://github.com/LazyVim/LazyVim | Neovim distribution, plugin orchestration |
| lazy.nvim | https://github.com/folke/lazy.nvim | Plugin manager, spec system |
| SbarLua | https://github.com/FelixKratz/SbarLua | SketchyBar Lua bindings |
| SketchyBar | https://github.com/FelixKratz/SketchyBar | macOS bar, config examples |
| nvim-lspconfig | https://github.com/neovim/nvim-lspconfig | LSP client configs |
| plenary.nvim | https://github.com/nvim-lua/plenary.nvim | Neovim Lua utilities and test harness |
| telescope.nvim | https://github.com/nvim-telescope/telescope.nvim | Fuzzy finder, well-structured plugin |
| 项目 | 链接 | 关注点 |
|---|---|---|
| LazyVim | https://github.com/LazyVim/LazyVim | Neovim发行版、插件编排 |
| lazy.nvim | https://github.com/folke/lazy.nvim | 插件管理器、配置规范系统 |
| SbarLua | https://github.com/FelixKratz/SbarLua | SketchyBar Lua绑定 |
| SketchyBar | https://github.com/FelixKratz/SketchyBar | macOS状态栏、配置示例 |
| nvim-lspconfig | https://github.com/neovim/nvim-lspconfig | LSP客户端配置 |
| plenary.nvim | https://github.com/nvim-lua/plenary.nvim | Neovim Lua工具库与测试框架 |
| telescope.nvim | https://github.com/nvim-telescope/telescope.nvim | 模糊查找器、结构良好的插件示例 |
Additional Resources
额外资源
- Lua 5.4 Reference Manual: https://www.lua.org/manual/5.4/
- Programming in Lua (4th ed): https://www.lua.org/pil/
- LuaRocks style guide: https://github.com/luarocks/lua-style-guide
- Neovim Lua guide: https://neovim.io/doc/user/lua-guide.html
- StyLua: https://github.com/JohnnyMorganz/StyLua
- Selene: https://github.com/Kampfkarren/selene
- LuaLS wiki: https://luals.github.io/
- Lua 5.4 参考手册:https://www.lua.org/manual/5.4/
- 《Lua程序设计》(第4版):https://www.lua.org/pil/
- LuaRocks 风格指南:https://github.com/luarocks/lua-style-guide
- Neovim Lua 指南:https://neovim.io/doc/user/lua-guide.html
- StyLua:https://github.com/JohnnyMorganz/StyLua
- Selene:https://github.com/Kampfkarren/selene
- LuaLS 维基:https://luals.github.io/