EmmyLua Formatter Options
June 29, 2026 · View on GitHub
This document describes the public formatter configuration groups and the intended effect of each option.
Configuration File Discovery
luafmt and the library path-aware helpers support nearest-config discovery for:
.luafmt.tomlluafmt.toml
When input comes from stdin and no source path is available, luafmt starts discovery from the current working directory.
Supported explicit config formats are:
- TOML
- JSON
- YAML
syntax
level: Lua grammar level. Supported values areLua51,Lua52,Lua53,Lua54,Lua55,LuaJIT,LuaJITExt,LuaJIT3.
Default:
[syntax]
level = "Lua55"
Notes:
- This option controls which Lua grammar is used during parsing before formatting.
- If
syntax.levelis omitted from the config file, the formatter defaults toLua55. - The CLI
--levelflag overridessyntax.levelfrom config.
indent
kind:SpaceorTabwidth: logical indent width
Default:
[indent]
kind = "Space"
width = 4
layout
max_line_width: preferred print widthmax_blank_lines: maximum consecutive blank lines retainedtable_expand:Never,Always, orAutocall_args_expand:Never,Always, orAutofunc_params_expand:Never,Always, orAutoprefer_call_args_layout_from_source: prefer keeping the source layout goal for explicit multiline call argument listsprefer_table_layout_from_source: prefer keeping the source layout goal for explicit multiline pure-array tablesprefer_chain_break_on_statement_tail: prefer multiline breaking for fluent chains in statement-tail position
Default:
[layout]
max_line_width = 120
max_blank_lines = 1
table_expand = "Auto"
call_args_expand = "Auto"
func_params_expand = "Auto"
prefer_call_args_layout_from_source = false
prefer_table_layout_from_source = false
prefer_chain_break_on_statement_tail = false
Behavior notes:
Autolets the formatter compare flat and broken candidates.prefer_call_args_layout_from_source = trueonly affects call argument lists undercall_args_expand = "Auto".- When a call argument list is already multiline in the source, the formatter keeps it expanded instead of reflowing it back into a compact layout.
prefer_table_layout_from_source = trueonly affects table constructors undertable_expand = "Auto".- It applies only to pure-array tables, meaning tables whose fields are all positional values without keys.
- When such a table is already multiline in the source, the formatter keeps it expanded instead of reflowing it back into a compact layout.
- Sequence-like structures can now choose between fill, packed, aligned, and one-per-line layouts when applicable.
- Binary-expression chains and statement expression lists may prefer a balanced packed layout when it keeps the same line count but avoids ragged trailing lines.
prefer_chain_break_on_statement_tail = trueapplies to the last direct expression in a statement, including standalone call statements, and also to keyed table-field values; when that expression is a long enough fluent chain, the formatter prefers chain-style breaking.- The chain head is defined as the
root, plus any leading namespace or field accesses, plus the first call segment; however, if therootitself already ends in a call, the head stops at that call. For example, the head ofBuilder:new():add():add()isBuilder:new(), the head ofConsoleFormattingBuilder():setColor():build()isConsoleFormattingBuilder(), and the head ofvim.api.nvim_set_keymap(...)is the wholevim.api.nvim_set_keymap(...)call. - The break start is defined as the first continuation segment after that head. In other words, only segments that continue after the first call are eligible for chain-style line breaking; a namespace-qualified terminal call is not treated as a fluent chain by this option.
output
insert_final_newlinetrailing_comma:Never,Multiline, orAlwaystrailing_table_separator:Inherit,Never,Multiline, orAlwaysquote_style:Preserve,Double, orSinglesingle_arg_call_parens:Preserve,Always, orOmitsimple_lambda_single_line:Preserve,Always, orNeverend_of_line:LForCRLF
Default:
[output]
insert_final_newline = true
trailing_comma = "Never"
trailing_table_separator = "Inherit"
quote_style = "Preserve"
single_arg_call_parens = "Preserve"
simple_lambda_single_line = "Preserve"
end_of_line = "LF"
Behavior notes:
trailing_commais the general trailing-comma policy for sequence-like constructs.trailing_table_separatoroverrides that policy for tables only.Inheritkeeps usingtrailing_comma.quote_styleonly rewrites normal short strings when it is safe to do so. Long strings and other string forms are preserved.- Quote rewriting works from the raw token text, checks for unescaped occurrences of the target delimiter, and only adjusts the minimal delimiter escaping needed to preserve semantics.
single_arg_call_parens = "Omit"only removes parentheses for Lua-valid single-string and single-table calls.simple_lambda_single_line = "Preserve"only keeps an eligible simple lambda on one line when the input was already inline.simple_lambda_single_line = "Always"collapses an eligible simple lambda back tofunction(...) return expr endwhen it fits within the configured width.simple_lambda_single_line = "Never"disables the simple inline lambda fast path and always formats the closure body on multiple lines.
spacing
space_before_call_parenspace_before_func_parenspace_before_lambda_func_parenspace_inside_bracesspace_inside_parensspace_inside_bracketsspace_around_math_operatorspace_around_concat_operatorspace_around_assign_operator
These options control token spacing only. They do not override larger layout decisions such as whether an expression list should break.
comments
align_line_commentsalign_in_statementsalign_in_table_fieldsalign_in_call_argsalign_in_paramsalign_across_standalone_commentsalign_same_kind_onlyspace_after_comment_dashline_comment_min_spaces_beforeline_comment_min_column
Default:
[comments]
align_line_comments = true
align_in_statements = false
align_in_table_fields = true
align_in_call_args = true
align_in_params = true
align_across_standalone_comments = false
align_same_kind_only = false
space_after_comment_dash = true
line_comment_min_spaces_before = 1
line_comment_min_column = 0
Behavior notes:
- Statement comment alignment is disabled by default.
- Table, call-arg, and parameter trailing-comment alignment are input-driven. Extra spacing in the original source is treated as alignment intent.
- Standalone comments usually break alignment groups.
- Table-field trailing-comment alignment is scoped to contiguous subgroups rather than the whole table.
space_after_comment_dashonly inserts one space for plain comments such as--commentwhen there is no gap after the prefix already; comments with larger existing gaps are preserved.
emmy_doc
align_tag_columnsalign_declaration_tagsalign_reference_tagsalign_multiline_alias_descriptionsspace_between_tag_columnsspace_after_description_dashcompact_type_or
Default:
[emmy_doc]
align_tag_columns = true
align_declaration_tags = true
align_reference_tags = true
align_multiline_alias_descriptions = true
space_between_tag_columns = false
space_after_description_dash = true
compact_type_or = false
Structured handling currently covers @param, @field, @return, @class, @alias, @type, @generic, and @overload.
align_multiline_alias_descriptionsis enabled by default and aligns the# descriptioncolumn in multiline@aliasblocks such as--- | value # description.space_between_tag_columnscontrols whether EmmyLua tag lines keep a space between---and@, for example--- @enum MyEnumversus---@enum MyEnum. The current default isfalse, so tag lines format as---@tagunless configured otherwise.space_after_description_dashonly affects plain doc description lines such as--- textversus---text, not tag-line prefixes.compact_type_orcontrols whether EmmyLua union types keep spaces around|, for examplestring | integerversusstring|integer. The default isfalse.
align
continuous_assign_statementtable_field
Default:
[align]
continuous_assign_statement = false
table_field = true
Behavior notes:
- Continuous assignment alignment is disabled by default.
- Table-field alignment is enabled, but only activates when the source already shows extra post-
=spacing that indicates alignment intent.
Recommended Starting Point
[layout]
max_line_width = 100
table_expand = "Auto"
call_args_expand = "Auto"
func_params_expand = "Auto"
[comments]
align_in_statements = false
align_in_table_fields = true
align_in_call_args = true
align_in_params = true
[align]
continuous_assign_statement = false
table_field = true
Complete Default Config
[indent]
kind = "Space"
width = 4
[layout]
max_line_width = 120
max_blank_lines = 1
table_expand = "Auto"
call_args_expand = "Auto"
func_params_expand = "Auto"
[output]
insert_final_newline = true
trailing_comma = "Never"
trailing_table_separator = "Inherit"
quote_style = "Preserve"
single_arg_call_parens = "Preserve"
simple_lambda_single_line = "Preserve"
end_of_line = "LF"
[spacing]
space_before_call_paren = false
space_before_func_paren = false
space_before_lambda_func_paren = true
space_inside_braces = true
space_inside_parens = false
space_inside_brackets = false
space_around_math_operator = true
space_around_concat_operator = true
space_around_assign_operator = true
[comments]
align_line_comments = true
align_in_statements = false
align_in_table_fields = true
align_in_call_args = true
align_in_params = true
align_across_standalone_comments = false
align_same_kind_only = false
space_after_comment_dash = true
line_comment_min_spaces_before = 1
line_comment_min_column = 0
[emmy_doc]
align_tag_columns = true
align_declaration_tags = true
align_reference_tags = true
align_multiline_alias_descriptions = true
tag_spacing = 1
space_after_description_dash = true
[align]
continuous_assign_statement = false
table_field = true