Inintal commit
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
-- SCL Formatter - Document formatting for the LSP server
|
||||
local M = {}
|
||||
|
||||
local function position(line, character)
|
||||
return { line = line, character = character }
|
||||
end
|
||||
|
||||
local function range(start_line, start_char, end_line, end_char)
|
||||
return {
|
||||
start = position(start_line, start_char),
|
||||
end = position(end_line, end_char),
|
||||
}
|
||||
end
|
||||
|
||||
function M.format_document(content, options)
|
||||
options = options or {}
|
||||
local indent_size = options.indentSize or 4
|
||||
local indent_char = options.insertSpaces and " " or "\t"
|
||||
|
||||
local lines = {}
|
||||
for line in content:gmatch("([^\n]*)\n") do
|
||||
table.insert(lines, line)
|
||||
end
|
||||
if #lines == 0 or content:sub(-1) ~= "\n" then
|
||||
table.insert(lines, "")
|
||||
end
|
||||
|
||||
local formatted_lines = {}
|
||||
local indent_level = 0
|
||||
|
||||
local function get_indent()
|
||||
return string.rep(indent_char, indent_level * indent_size)
|
||||
end
|
||||
|
||||
local function is_block_keyword(line)
|
||||
local kw = line:match('^%s*(%w+)')
|
||||
if not kw then return false end
|
||||
local block_keywords = {
|
||||
IF = true, ELSIF = true, ELSE = true,
|
||||
FOR = true, WHILE = true, REPEAT = true,
|
||||
CASE = true,
|
||||
FUNCTION = true, FUNCTION_BLOCK = true, ORGANIZATION_BLOCK = true,
|
||||
TYPE = true, STRUCT = true,
|
||||
}
|
||||
return block_keywords[kw]
|
||||
end
|
||||
|
||||
local function is_end_block(line)
|
||||
local kw = line:match('^%s*(%w+)')
|
||||
if not kw then return false end
|
||||
local end_keywords = {
|
||||
END_IF = true, END_FOR = true, END_WHILE = true, END_REPEAT = true,
|
||||
END_CASE = true, END_FUNCTION = true, END_FUNCTION_BLOCK = true,
|
||||
END_ORGANIZATION_BLOCK = true, END_TYPE = true, END_STRUCT = true,
|
||||
}
|
||||
return end_keywords[kw]
|
||||
end
|
||||
|
||||
local function process_line(line)
|
||||
local trimmed = line:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
|
||||
if trimmed == "" or trimmed:match("^//") or trimmed:match("^%(%*") then
|
||||
table.insert(formatted_lines, line)
|
||||
return
|
||||
end
|
||||
|
||||
if is_end_block(trimmed) then
|
||||
indent_level = math.max(0, indent_level - 1)
|
||||
end
|
||||
|
||||
local formatted_line = get_indent() .. trimmed
|
||||
table.insert(formatted_lines, formatted_line)
|
||||
|
||||
if is_block_keyword(trimmed) and not is_end_block(trimmed) then
|
||||
if not trimmed:match("CASE%s+.+OF%s*$") and
|
||||
not trimmed:match("IF%s+.+THEN%s*$") and
|
||||
not trimmed:match("ELSIF%s+.+THEN%s*$") and
|
||||
not trimmed:match("ELSE%s*$") and
|
||||
not trimmed:match("FOR%s+.+DO%s*$") and
|
||||
not trimmed:match("WHILE%s+.+DO%s*$") and
|
||||
not trimmed:match("REPEAT%s*$") then
|
||||
indent_level = indent_level + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, line in ipairs(lines) do
|
||||
process_line(line)
|
||||
end
|
||||
|
||||
local result = table.concat(formatted_lines, "\n")
|
||||
if content:sub(-1) == "\n" then
|
||||
result = result .. "\n"
|
||||
end
|
||||
|
||||
return {
|
||||
{
|
||||
range = range(0, 0, #lines, 0),
|
||||
newText = result,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function M.get_formatting_options()
|
||||
return {
|
||||
insertSpaces = true,
|
||||
tabSize = 4,
|
||||
trimTrailingWhitespace = true,
|
||||
insertFinalNewline = true,
|
||||
trimFinalNewlines = true,
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user