format lua code

Overview

EmmyLuaCodeStyle

项目介绍

该项目是基于C++的lua代码格式化算法库

经过长期实践,发现人们对格式化算法的预期是尽可能少的改动代码的行布局,而列布局符合基本审美就可以了。

基于这样的想法我设计并实现了lua格式化算法

格式化行为介绍

基本语句

该算法的主要特点是分析并对当前代码做出合理的优化,最常见的比如:

local t=123 --local
aaa,bbbb = 1123, 2342

会被格式化为:

local t = 123 --local
aaa, bbbb = 1123, 2342

连续赋值语句

对于连续的赋值或者local语句:

local ttt  = 123 --first
cd        = 345 --second

当算法识别到代码试图对齐到等号的时候,会采取对齐到等号的方式排版:

local ttt  = 123 --first
cd         = 345 --second

识别对齐的基本原则是:

连续的赋值/local/注释语句,当首个赋值/local语句的等号与它左边的元素距离大于1个空格时,该连续的赋值/local语句会对齐到等号。

这里对连续的定义是: 语句之间相距不超过2行则认为是同一连续

表的排版

对常见的表表达式:

local t = {1,2,3}
local c = {
    aaa, bbb, eee
}
local d = {
    aa  =123,
    bbbb = 4353,
    eee  = 131231,
}

默认情况下算法会排版为如下格式:

local t = { 1, 2, 3 }
local c = {
    aaa, bbb, eee
}
local d = {
    aa   = 123,
    bbbb = 4353,
    eee  = 131231,
}

其中对 d 表的排版并非严格对齐到等号,它采取和连续赋值/local语句相似的规则,但是当表内存在处于同一行得表项时,算法不会对齐到等号。

长表达式列表

长表达式列表和长表达式如果不止一行,则除了第一行,其余行会多一个缩进。

local aaa = 13131, bbbb,
    ccc, 123131, ddddd,
    eeee, fff

return aaa, bbb, dddd
    or cccc

if aaa and bbb 
    or ccc() then

end

包含语句块的语句

对于if语句,repeat语句,while语句,do语句,for语句和函数定义语句,都具备保持短语句不会强行换行的特性也就是说,如下语句:

do return end
function f(x,y) return x<y  end

会被格式化为:

do return end
function f(x, y) return x < y end

除此以外,包含语句块的语句,在语句块内会多一个缩进语句。

同时经过长期的实践,包含语句块的语句应与下一个非注释语句保持至少一行的距离:

do 
    if a then
        return 
    end

    local c = 123
end

print("hello world")

函数定义参数与函数调用参数

对于函数定义语句的定义参数,默认采用对齐到首个参数的方式:

function ffff(a, b, c,
              callback)

end

对于函数调用的参数,默认采用换行多一个缩进的策略,

print(aaa, bbbb, eeee, ffff,
    ggggg, hhhhh,
    lllll)

如果函数调用为单参数无括号的方式则函数标识和参数之间会保持一个空格

require "code_format"

注释语句与内联注释

注释语句分为长注释和单行短注释,内联注释包括插入到所有语法元素之后/中间的注释。

注释语句格式化时,短注释不会做任何改变,保持和下一个语句相同的行间距,而长注释的大段空白文本被认为是注释一部分,所以也不会做任何改变,同样保持和下一个语句相同的行间距:

--[[
    这是个注释
]]

--[email protected] f number
--[email protected] number
function ffff(f)
end

对于各种内联注释,采用和前文保持一个空格的原则,如果下一个元素依然在同一行,也会保持一个空格:

local t = 123 --fffff
local c = {
    aaa = 123, --[[ffff]] dddd,
    ccc = 456
}

以上只是默认选项下的格式化结果,该算法依然提供各种细节到每个语法元素的排版控制

格式化选项

通常项目内为了保持代码风格统一需要十分详尽的格式化配置,另一方面默认的格式化选项,可能不符合每个人的审美。这里逐步介绍所有的格式化选项和效果。

该项目支持从editorconfig文件读取配置来配置格式化选项,完整的配置参考本项目自带的template.editorconfig。

use_tab

该选项表示是否使用\t来做缩进,该选项默认为false,如果该选项为true,则选项indent无效,格式化效果如下:

--格式化前
function ff() 
    local t = 123
    local c = 456
end

--格式化后
function ff()
        local t = 123
        local c = 456
end

indent

该选项表示单次缩进的列数,默认值为4,各种常见的选项下的效果如下:

--格式化前
function ff() 
    local t = 123
    local c = 456
end

-- indent = 2
function ff()
  local t = 123
  local c = 456
end

-- indent = 3
function ff()
   local t = 123
   local c = 456
end

-- indent = 4
function ff()
    local t = 123
    local c = 456
end

continuation_indent

该选项表示长表达式或者表达式列表在换行表达时的后续缩进列数,该选项默认值是4,常见的还有8,格式化效果如下:

-- 格式化前
local fff = function(x,y)
end

local ccc = aa + bbb + ccc /
    ddd + eee

if aaa == 123 
or bbb == 456 then
end

-- 值为4时的格式化结果
local fff = function(x, y)
end
local ccc = aa + bbb + ccc /
    ddd + eee

if aaa == 123
    or bbb == 456 then
end

-- 值为8时的格式化结果
local fff = function(x, y)
end
local ccc = aa + bbb + ccc /
        ddd + eee

if aaa == 123
        or bbb == 456 then
end

align_call_args

该参数表示调用参数是否对齐,默认值是false,格式化效果如下:

-- 格式化前
helloWorld(aaa,bbb,ccc,
eee,ddd)

-- 格式化后
-- align_call_args 为true
helloWorld(aaa, bbb, ccc,
           eee, ddd)

-- align_call_args 为false
helloWorld(aaa, bbb, ccc,
    eee, ddd)

keep_one_space_between_call_args_and_bracket

该选项表示函数调用表达式的参数和左右括号之间是否保持一个空格,选项默认值是false,格式化效果如下

-- 格式化前
helloWorld(aaa,bbb,ccc,
eee,ddd)

print(123,456)

-- 该选项为true时
helloWorld( aaa, bbb, ccc,
    eee, ddd )

print( 123, 456 )

align_function_define_params

该选项表示函数定义语句的参数列表是否对齐到第一个参数的位置,选项默认为true,格式化效果如下:

-- 格式化前
function fffff(aaa,bbb,ccc)
end

function ddddd(eeee,ffff,
    ggg,hhh)
end

-- 该选项为true时
function fffff(aaa, bbb, ccc)
end

function ddddd(eeee, ffff,
               ggg, hhh)
end

-- 该选项为false时
function fffff(aaa, bbb, ccc)
end

function ddddd(eeee, ffff,
    ggg, hhh)
end

keep_one_space_between_table_and_bracket

该选项表示表的表项和表的括号之间是否保持一个空格,该选项默认为true,格式化效果如下:

-- 格式化前
local t = {1,2,3}
local cc ={
    4,5,6
}

-- 该选项为true时
local t = { 1, 2, 3 }
local cc = {
    4, 5, 6
}
-- 该选项为false时
local t = {1, 2, 3}
local cc = {
    4, 5, 6
}

align_table_field_to_first_field

该选项表示表的表项是否对齐到首个表项,选项默认值为true,格式化效果如下:

-- 格式化前
local t = {
    aaa,bbbb,ccc,
    ddd,eee,fff
}

local t2 = {aaa,bbbb,
ccc,eee
}


-- 该选项为true
local t = {
    aaa, bbbb, ccc,
    ddd, eee, fff
}
local t2 = { aaa, bbbb,
             ccc, eee
}

-- 该选项为false
local t = {
    aaa, bbbb, ccc,
    ddd, eee, fff
}
local t2 = { aaa, bbbb,
    ccc, eee
}

continuous_assign_statement_align_to_equal_sign

该选项表示连续赋值语句的首行语句如果等号与左边符号相距大于一个空格,则对齐到连续赋值语句的等号最大的位置,该选项默认值为true,效果如下:

-- 格式化前
local t  = 123
local cccc = 456
cccc = 321
-- 这是个注释
eeeeeeeee = 654 -- 这也是个注释


--不连续了
local c =132

-- 选项为true时
local t    = 123
local cccc = 456
cccc       = 321
-- 这是个注释
eeeeeeeee  = 654 -- 这也是个注释


--不连续了
local c = 132

-- 选项为false时
local t = 123
local cccc = 456
cccc = 321
-- 这是个注释
eeeeeeeee = 654 -- 这也是个注释


--不连续了
local c = 132

continuous_assign_table_field_align_to_equal_sign

该选项表示表中各项是否允许对齐到等号,对齐的规则和上面的选项近似,选项默认值为true,格式化效果如下:

-- 格式化前
local t = {
    aadddd  = 123,
    bbb =456,
    ddd =789
}

-- 选项为true时
local t = {
    aadddd  = 123,
    bbb     = 456,
    ddd     = 789
}
-- 选项为false时
local t = {
    aadddd = 123,
    bbb = 456,
    ddd = 789
}

line_separator

该选项表示行尾的符号,默认为CRLF,也可选为LF

语句的行布局

该算法同样支持对不同语句之间的行间距做出设定,可以设定的语句包括if, while, repeat, for,do,local/assign 语句。

这些选项名称和默认值分别是:

keep_line_after_if_statement = minLine:1
keep_line_after_do_statement = minLine:1
keep_line_after_while_statement = minLine:1
keep_line_after_repeat_statement = minLine:1
keep_line_after_for_statement = minLine:1
keep_line_after_local_or_assign_statement = keepLine
keep_line_after_function_define_statement = keepLine:1

所有选项支持三种值表达:

  • minLine:${n}

    表示和下一个语句间距至少n行

  • keepLine

    表示和下一行保持原本的行间距

  • keepLine:${n}

    表示和下一行保持n行间距

代码风格诊断

待续

License

没有License

Comments
  • [enhancement] can we support the following functions?

    [enhancement] can we support the following functions?

    Hello, Can we add support for the following functions? I use them for C/C++ on vscode. It will be pretty handy for me if they are available in Lua also.

    • SpaceBeforeFunctionOpenParenthesis
    • SpaceBeforeOpenSquareBracket
    • SpaceBeforeLambdaOpenParenthesis
    • SpaceWithinExpression

    SpaceBeforeFunctionOpenParenthesis

    Before Formatting:

    function ff()
    end
    

    After Formatting:

    function ff ()
    end
    

    SpaceBeforeOpenSquareBracket

    Before Formatting:

    details["names"] = "ashok"
    

    After Formatting:

    details ["names"] = "ashok"
    

    SpaceBeforeLambdaOpenParenthesis

    Before Formatting:

    local details ={}
    

    After Formatting:

    local details = {}
    
    

    SpaceWithinExpression

    Before Formatting:

    i?"true":"false";
    i>0
    
    

    After Formatting:

    i ? "true" : "false";
    i > 0
    

    Thank You, ashok.

    enhancement good first issue feature request 
    opened by achidipothu 27
  • 多行字符串不对齐,看起来很难受

    多行字符串不对齐,看起来很难受

    local sql = fmt("select a, b, c " ..
        "from table " ..
        "where a > 10 and b < 10")
    

    期待的格式:

    local sql = fmt("select a, b, c " ..
                    "from table " ..
                    "where a > 10 and b < 10")
    
    enhancement discuss feature request 
    opened by sanpoo 19
  • Help removing empty continuous lines?

    Help removing empty continuous lines?

    I'm using sumneko_lua through neovim and testing the new formatting capabilities out using .editorconfig to see if I can't replace stylua as my default formatter but still keep a similar style.

    In my config file I have the line max_continuous_line_distance = 1; My assumption is that this would remove empty lines between statements and would format the examples below, but it doesn't appear to do anything...

    How can I achieve this result? It successfully fixes indentation and providing diagnostics so the rest of the config is clearly working.

    print('hello, world')
    
    
    --- Modules ---
    
    
    
    
    require('lsp.handlers')
    require('lsp.null-ls')
    
    require('lsp.installer').setup({
    
    
      capabilities = capabilities,
            language_servers = language_servers,
    
      on_attach = on_attach,
    })
    
    
    local example1 = 'foo'
    local example2 = 'bar'
    
    print('hello, world')
    
    --- Modules ---
    
    require('lsp.handlers')
    require('lsp.null-ls')
    require('lsp.installer').setup({
      capabilities = capabilities,
      language_servers = language_servers,
      on_attach = on_attach,
    })
    
    local example1 = 'foo'
    local example2 = 'bar'
    
    question 
    opened by daephx 13
  • Use `insertSpaces` in `formattingOptions` instead of `indent_style` in `.editorconfig`

    Use `insertSpaces` in `formattingOptions` instead of `indent_style` in `.editorconfig`

    See https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#formattingOptions

    Since LSP specifies that this field will be included in the formatted request, you should use the LSP field first. You should only use the settings in .editorconfig if formatting is not requested via LSP.

    enhancement discuss diagnostic 
    opened by sumneko 13
  • 格式化时等号对齐应该使用最小长度

    格式化时等号对齐应该使用最小长度

    local aaaaaa = 1
    local b  = 1
    local c        = 1
    

    现在会被格式化为

    local aaaaaa   = 1
    local b        = 1
    local c        = 1
    

    但用户的期望一般是

    local aaaaaa = 1
    local b      = 1
    local c      = 1
    
    enhancement discuss 
    opened by sumneko 13
  • Add support for inner spaces within parentheses and square brackets.

    Add support for inner spaces within parentheses and square brackets.

    First of all, thank you for this project!

    Also fixed one failing test before adding my changes (commits are logically split). See the test files for the expected outcomes of new formatting options.

    enhancement discuss 
    opened by obszczymucha 10
  • 格式化选定内容/粘贴时格式化的问题

    格式化选定内容/粘贴时格式化的问题

    TEST [[
    [email protected] Class
    
    [email protected] k Class
    for <?k?> in pairs(t) do
    end
    ]]
    [[
    parameter k: Class
    ]]
    

    选中倒数第二行的 parameter,选择 格式化选定内容 后,会导致倒数第三行格式改变,变为:

    TEST [[
    [email protected] Class
    
    [email protected] k Class
    for <?k?> in pairs(t) do
    end
    ]]
        [[
    parameter k: Class
    ]]
    
    enhancement feature request 
    opened by sumneko 7
  • Default editorconfig

    Default editorconfig

    Hi, I use neovim and the sumneko LSP server, and I started using the new code formatting feature. BTW, thanks!!! great job :) Even though it works great if I have a .editorconfig file in my project root, I wondered if it's possible to set a default configuration, so I don't need to set it in every project, but only when I want to change something. Thanks!

    enhancement good first issue 
    opened by szaffarano 7
  • [QUESTION] .editorconfig option to put table closing paranthesis to new line.

    [QUESTION] .editorconfig option to put table closing paranthesis to new line.

    I have the following table:

    Data = {
        howToBreakFormation = BreakImmediately,
        faceTargetHorizontal = 1,
        faceTargetVertical = 0,
        RandomActions =
        {
            {
                Type = PickNewTarget,
                Weighting = 1, },
            {
                Type = NoAction,
                Weighting = 9, },
        },
        BeingAttackedActions = {},
        FiringActions = {}, }
    

    What I want is to put closing bracket for each table to new line. Is there a way to force formatter to make it look like this:

    Data = {
        howToBreakFormation = BreakImmediately,
        faceTargetHorizontal = 1,
        faceTargetVertical = 0,
        RandomActions =
        {
            {
                Type = PickNewTarget,
                Weighting = 1,
            },
            {
                Type = NoAction,
                Weighting = 9,
            },
        },
        BeingAttackedActions = {},
        FiringActions = {},
    }
    
    enhancement feature request 
    opened by Real-Gecko 5
  • [Feature request] Add trailing_comma option

    [Feature request] Add trailing_comma option

    trailing_comma option should control how trailing commas are formatted in tables. This feature would make git diffs nicer. The values could be:

    • never
    t1 = { 1, 2 }
    t2 = {
      1,
      2
    }
    
    • smart (only add it when it is the last character on a line)
    t1 = { 1, 2 }
    t2 = {
      1,
      2,
    }
    
    • always
    t1 = { 1, 2, }
    t2 = {
      1,
      2,
    }
    

    Personally I wouldn't use always value, but some people might find it useful.

    enhancement feature request 
    opened by gutyina70 4
  • [Feature request] Add support for insert_final_newline

    [Feature request] Add support for insert_final_newline

    This option should be a boolean value. When it's true, after trimming all the empty lines at the end of a file, one empty line should be inserted. When it's false, trim all empty lines at the end.

    opened by gutyina70 3
  • Option to avoid spaces around string concatenation operator (..)

    Option to avoid spaces around string concatenation operator (..)

    Is there config option to avoid spaces around string concatenation operator (..):

    local esc_clear_line = esc.."[2K"
    

    Now it formats like this:

    local esc_clear_line = esc .. "[2K"
    
    enhancement feature request 
    opened by ltWolfik 1
  • editorconfig file fully cancels Lua.format.defaultConfig

    editorconfig file fully cancels Lua.format.defaultConfig

    I've noticed, that Lua.format.defaultConfig setting works fine if .editorconfig absents, but if .editorconfig exists in project - Lua.format.defaultConfig does nothing. It seems be better if Lua.format.defaultConfig would be merged with .editorconfig (with priority for .editorconfig). For example, if .editorconfig does not have keep_one_space_between_table_and_bracket option - then use the same one from Lua.format.defaultConfig (if present).

    I use the formatter through sumneko LSP in vscode. Thanks a lot.

    enhancement feature request 
    opened by ltWolfik 0
  • Design more reasonable rules to remove call parentheses

    Design more reasonable rules to remove call parentheses

    1. call_arg_parentheses = string_smart_remove_exclude_after_match(".:({")
    2. call_arg_parenthese = smart_remove and setting by json

    any other idea.

    help wanted discuss 
    opened by CppCXY 3
  • 将格式化与风格诊断分离

    将格式化与风格诊断分离

    实践中我们通常希望格式化总是输出出稳定的格式,但是手写代码允许有多种可用的格式,例如:

    if 1
    or 2 then
    elseif 3 then
    end
    
    if     1
    or     2 then
    elseif 3 then
    end
    

    格式化的时候我希望总是可以输出成下面的格式,但是我手写时上面的格式也是允许的。 因此希望可以增加诊断专用的 allow 系列设置,这些设置仅仅是用于抑制风格诊断。

    • 格式化时:根据设置进行格式化,不管 allow 系列设置
    • 诊断时:先根据设置进行诊断,然后根据 allow 系列设置排除掉部分诊断
    enhancement diagnostic 
    opened by sumneko 0
Releases(0.18.0)
Owner
null
(Simple String Format) is an syntax of format and a library for parse this.

SSFMT (Simple String Format) is an syntax of format and a library for parse this. SSFMT != {fmt} SSFMT is NOT an API/library for parse {fmt} syntax !

null 2 Jan 30, 2022
A dependency free, embeddable debugger for Lua in a single file (.lua or .c)

debugger.lua A simple, embedabble debugger for Lua 5.x, and LuaJIT 2.x. debugger.lua is a simple, single file, pure Lua debugger that is easy to integ

Scott Lembcke 585 Oct 2, 2022
The Lua development repository, as seen by the Lua team. Mirrored irregularly

The Lua development repository, as seen by the Lua team. Mirrored irregularly

Lua 6.1k Oct 1, 2022
Standardise code formating for cmake projects with git and clang-format

git-cmake-format This project aims to provide a quick and easy way to integrate clang-format into your CMake project hosted in a git repository, it co

Kenneth Benzie 48 Sep 24, 2022
Code examples used in my Lua talk

LuaTalk Summary Introduction Slide 1 : Introduction slide Slide 2 : Github repository Part 1 : Presentation Slide 3 : Quick Lua Presentation Part 2 :

Sygmei 3 Jun 9, 2022
💉 Source code for creating Lua executor

FiveM Lua Executor This is the ultimate great source code for building the best injectable Exec on FiveM. I'm not going to tell you how to create a pr

Achtzehn 43 Oct 1, 2022
lua binding for Software implementation in C of the FIPS 198 Keyed-Hash Message Authentication Code HMAC

lua-hmac Compute the SHA-224, SHA-256, SHA-384, and SHA-512 message digests and the Hash-based Message Authentication Code (HMAC). this module is Lua

Masatoshi Fukunaga 2 Jul 1, 2022
Converts file formats supported by AdPlug to VGM format.

adlib2vgm Converts file formats supported by AdPlug to VGM format. Notice This tool is originally designed to work with the RetroWave OPL3 Sound Card.

SudoMaker 15 Sep 12, 2022
(R) Efficient methods and operators for the sparse matrix classes in 'Matrix' (esp. CSR format or "RsparseMatrix")

MatrixExtra MatrixExtra is an R package which extends the sparse matrix and sparse vector types in the Matrix package, particularly the CSR or Rsparse

null 15 Aug 29, 2022
A free, open-source compressor for the ZX0 format

salvador -- a fast, near-optimal compressor for the ZX0 format salvador is a command-line tool and a library that compresses bitstreams in the ZX0 for

Emmanuel Marty 32 Aug 10, 2022
Immersive IMM Format and Player

Introduction Immersive media (IMM) is an API-neutral runtime immersive media delivery format. IMM provides an efficient, extensible, interoperable for

null 36 Sep 9, 2022
A format converter for surface mesh intergrated with muli tools.

MeshConverter A format converter for surface mesh intergrated with small tools for fast surface mesh modification in CFD application scenarios. Build

yhf 4 Jul 22, 2022
Quite OK Image (QOI) format encoder/decoder

This project implements encoding and decoding the "Quite OK Image" (QOI) format in the Ć programming language. Ć can be automatically translated to pu

Piotr Fusik 46 Sep 24, 2022
The Leap Motion cross-format, cross-platform declarative serialization library

Introduction to LeapSerial LeapSerial is a cross-format, declarative, serialization and deserialization library written and maintained by Leap Motion.

Leap Motion (Ultraleap) 15 Jan 17, 2022
IconVG is a compact, binary format for simple vector graphics: icons, logos, glyphs and emoji.

IconVG IconVG is a compact, binary format for simple vector graphics: icons, logos, glyphs and emoji. WARNING: THIS FORMAT IS EXPERIMENTAL AND SUBJECT

Google 622 Oct 4, 2022
meters.lv2 is a collection of audio-level meters with GUI in LV2 plugin format

meters.lv2 - Audio Level Meters meters.lv2 is a collection of audio-level meters with GUI in LV2 plugin format. It includes needle style meters (mono

Robin Gareus 141 Oct 2, 2022
A library to handle Apple Property List format in binary or XML

libplist A small portable C library to handle Apple Property List files in binary or XML format. Features The project provides an interface to read an

libimobiledevice 418 Sep 30, 2022
Scripts to help create QUIC version test vectors in RFC 9001 format.

quic-test-vector Scripts to help create QUIC version test vectors in RFC 9001 format. Just type 'make all' to build everything. There are two tools he

null 2 Jan 21, 2022
C++ implementation for a binary data storage format.

bsmlib- A C++ library for loading and writing binary data to and from files. bsmlib provides functions for loading, modifying, and saving BSM (Binary

Colleen 4 Oct 4, 2022