Skip to content

Commit 7094fce

Browse files
yeshan333huacnlee
andauthored
Add to support Lua. (#281)
Co-authored-by: Jason Lee <huacnlee@gmail.com>
1 parent bf87cf6 commit 7094fce

File tree

5 files changed

+246
-0
lines changed

5 files changed

+246
-0
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
key: ubuntu-test-cargo-${{ hashFiles('**/Cargo.lock') }}
2727
- name: Test
2828
run: |
29+
rustup component add clippy
2930
cargo install cargo-machete
3031
cargo machete
3132
cargo clippy

autocorrect/.autocorrectrc.default

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ fileTypes:
144144
# Shell
145145
sh: ruby
146146
shell: ruby
147+
# Lua
148+
lua: lua
147149
# Text
148150
text: text
149151
plain: text

autocorrect/grammar/lua.pest

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//! Lua Parser
2+
item = _{ SOI ~ line* ~ EOI }
3+
line = _{ block_comment | line_comment | string | other }
4+
other = ${ !(COMMENT | string | "--") ~ ANY }
5+
WHITESPACE = { " " | "\t" | NEWLINE }
6+
7+
/// Comment
8+
COMMENT = ${ block_comment | line_comment }
9+
line_comment = _{ "--" ~ (!(NEWLINE | "[") ~ ANY)* }
10+
block_comment = ${ "--[[" ~ inner_text ~ "]]" }
11+
/// block_comment inner text
12+
inner_text = { (!("]]") ~ ANY)* }
13+
14+
/// String
15+
string = ${ inner_string }
16+
17+
/// Inner string - the core string parsing rule
18+
inner_string = _{
19+
("'" ~ (!(NEWLINE | "'") ~ ANY)* ~ "'")
20+
| ("\"" ~ (!(NEWLINE | "\"") ~ ANY)* ~ "\"")
21+
| ("[[" ~ (!("]]") ~ ANY)* ~ "]]")
22+
}

autocorrect/src/code/lua.rs

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
// autocorrect: false
2+
use super::*;
3+
use autocorrect_derive::GrammarParser;
4+
use pest::Parser as P;
5+
use pest_derive::Parser;
6+
7+
#[derive(GrammarParser, Parser)]
8+
#[grammar = "../grammar/lua.pest"]
9+
struct LuaParser;
10+
11+
#[cfg(test)]
12+
mod tests {
13+
use super::*;
14+
use indoc::indoc;
15+
use pretty_assertions::assert_eq;
16+
17+
#[test]
18+
fn it_format_lua_basic() {
19+
let example = indoc! {r###"
20+
--[[
21+
role上面一些业务自定义 obj 功能测试
22+
对应service/roleagent/mods/init.lua
23+
]]
24+
25+
-- 单行注释role上面测试
26+
function test()
27+
print("hello world")
28+
end
29+
"###};
30+
31+
let expect = indoc! {r###"
32+
--[[
33+
role 上面一些业务自定义 obj 功能测试
34+
对应 service/roleagent/mods/init.lua
35+
]]
36+
37+
-- 单行注释 role 上面测试
38+
function test()
39+
print("hello world")
40+
end
41+
"###};
42+
43+
assert_eq!(expect, format_for(example, "lua").to_string());
44+
}
45+
46+
#[test]
47+
fn it_format_lua() {
48+
let example = indoc! {r###"
49+
-- 第1行注释
50+
-- 第2行注释
51+
function hello(a)
52+
re = string.find("hello你好")
53+
54+
a = "hello世界"
55+
b = '你好hello世界'
56+
c = [[多行
57+
字符串]]
58+
end
59+
"###};
60+
61+
let expect = indoc! {r###"
62+
-- 第 1 行注释
63+
-- 第 2 行注释
64+
function hello(a)
65+
re = string.find("hello 你好")
66+
67+
a = "hello 世界"
68+
b = '你好 hello 世界'
69+
c = [[多行
70+
字符串]]
71+
end
72+
"###};
73+
74+
assert_eq!(expect, format_for(example, "lua").to_string());
75+
}
76+
77+
#[test]
78+
fn it_format_lua_multiline_comment() {
79+
let example = indoc! {r###"
80+
--[[
81+
role上面一些业务自定义 obj 功能测试
82+
对应service/roleagent/mods/init.lua
83+
]]
84+
85+
-- 单行注释role上面测试
86+
function test()
87+
print("hello world")
88+
end
89+
"###};
90+
91+
let expect = indoc! {r###"
92+
--[[
93+
role 上面一些业务自定义 obj 功能测试
94+
对应 service/roleagent/mods/init.lua
95+
]]
96+
97+
-- 单行注释 role 上面测试
98+
function test()
99+
print("hello world")
100+
end
101+
"###};
102+
103+
assert_eq!(expect, format_for(example, "lua").to_string());
104+
}
105+
106+
#[test]
107+
fn it_format_lua_nested_multiline_comments() {
108+
let example = indoc! {r###"
109+
--[[
110+
这是一个Lua多行注释
111+
包含多个中英文混合的内容:
112+
- Hello世界测试
113+
- 123数字测试ABC
114+
]]
115+
116+
function example()
117+
local str = "[[这是Lua字符串,不是注释]]"
118+
return str
119+
end
120+
"###};
121+
122+
let expect = indoc! {r###"
123+
--[[
124+
这是一个 Lua 多行注释
125+
包含多个中英文混合的内容:
126+
- Hello 世界测试
127+
- 123 数字测试 ABC
128+
]]
129+
130+
function example()
131+
local str = "[[这是 Lua 字符串,不是注释]]"
132+
return str
133+
end
134+
"###};
135+
136+
assert_eq!(expect, format_for(example, "lua").to_string());
137+
}
138+
139+
#[test]
140+
fn it_format_lua_edge_cases() {
141+
let example = indoc! {r###"
142+
--[[
143+
普通块注释
144+
包含service/roleagent/mods/init.lua路径
145+
]]
146+
147+
-- 普通单行注释测试
148+
print("hello")
149+
"###};
150+
151+
let expect = indoc! {r###"
152+
--[[
153+
普通块注释
154+
包含 service/roleagent/mods/init.lua 路径
155+
]]
156+
157+
-- 普通单行注释测试
158+
print("hello")
159+
"###};
160+
161+
assert_eq!(expect, format_for(example, "lua").to_string());
162+
}
163+
164+
#[test]
165+
fn it_format_lua_string_functions() {
166+
let example = indoc! {r###"
167+
-- 测试 Lua 字符串模式匹配函数
168+
local text = "Hello世界测试123ABC"
169+
170+
-- string.find 函数
171+
local start_pos, end_pos = string.find(text, "世界")
172+
173+
-- string.match 函数
174+
local matched = string.match(text, "测试(%d+)")
175+
176+
-- string.gmatch 函数
177+
for word in string.gmatch(text, "(%a+)") do
178+
print(word)
179+
end
180+
181+
-- string.gsub 函数
182+
local replaced = string.gsub(text, "测试", "Test")
183+
184+
-- 直接使用函数名(不加 string. 前缀)
185+
local direct_find = find(text, "Hello")
186+
local direct_match = match(text, "(%a+)")
187+
local direct_gsub = gsub(text, "123", "456")
188+
"###};
189+
190+
let expect = indoc! {r###"
191+
-- 测试 Lua 字符串模式匹配函数
192+
local text = "Hello 世界测试 123ABC"
193+
194+
-- string.find 函数
195+
local start_pos, end_pos = string.find(text, "世界")
196+
197+
-- string.match 函数
198+
local matched = string.match(text, "测试 (%d+)")
199+
200+
-- string.gmatch 函数
201+
for word in string.gmatch(text, "(%a+)") do
202+
print(word)
203+
end
204+
205+
-- string.gsub 函数
206+
local replaced = string.gsub(text, "测试", "Test")
207+
208+
-- 直接使用函数名(不加 string. 前缀)
209+
local direct_find = find(text, "Hello")
210+
local direct_match = match(text, "(%a+)")
211+
local direct_gsub = gsub(text, "123", "456")
212+
"###};
213+
214+
// 注意:模式字符串现在会按照普通字符串处理
215+
assert_eq!(expect, format_for(example, "lua").to_string());
216+
}
217+
}

autocorrect/src/code/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod json;
1818
mod jupyter;
1919
mod kotlin;
2020
mod latex;
21+
mod lua;
2122
mod markdown;
2223
mod objective_c;
2324
mod php;
@@ -51,6 +52,7 @@ pub use json::*;
5152
pub use jupyter::*;
5253
pub use kotlin::*;
5354
pub use latex::*;
55+
pub use lua::*;
5456
pub use markdown::*;
5557
pub use objective_c::*;
5658
pub use php::*;
@@ -112,6 +114,7 @@ pub fn lint_for(raw: &str, filename_or_ext: &str) -> LintResult {
112114
"c" => lint_c(raw),
113115
"xml" => lint_xml(raw),
114116
"jupyter" => lint_jupyter(raw),
117+
"lua" => lint_lua(raw),
115118
"zig" => lint_rust(raw),
116119
"text" => lint_markdown(raw),
117120
_ => LintResult::new(raw),
@@ -170,6 +173,7 @@ pub fn format_for(raw: &str, filename_or_ext: &str) -> FormatResult {
170173
"c" => format_c(raw),
171174
"xml" => format_xml(raw),
172175
"jupyter" => format_jupyter(raw),
176+
"lua" => format_lua(raw),
173177
"zig" => format_rust(raw),
174178
"text" => format_markdown(raw),
175179
_ => {

0 commit comments

Comments
 (0)