Created
May 31, 2025 20:04
-
-
Save radgeRayden/ceda2167bb208d8f7aa6af4c208ffe50 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local function search_previous_lines(pattern) | |
return vim.fn.search(pattern, 'znbW') | |
end | |
local block_starting_keywords = { | |
'if', | |
'else', | |
'elseif', | |
'then', | |
'case', | |
'pass', | |
'default', | |
'except', | |
'fn', | |
'fn\\.\\.\\.', | |
'inline\\.\\.\\.', | |
'sugar', | |
'spice', | |
'inline', | |
'label', | |
'do', | |
'embed', | |
'try', | |
'loop', | |
'for', | |
'fold', | |
'while', | |
'spice-quote', | |
'enum', | |
'struct', | |
'::', | |
'static-if', | |
'sugar-if', | |
} | |
local block_ending_keywords = { | |
'return', | |
'break', | |
'repeat', | |
'continue', | |
'merge', | |
} | |
local function re_or(items) | |
return ('\\(%s\\)'):format(table.concat(items, '\\|')) | |
end | |
local block_start_pattern = re_or { '^ *' .. re_or(block_starting_keywords) .. re_or { ' ', '$' }, re_or { '=', ':=' } .. ' *$' } | |
local block_start_regexp = vim.regex(block_start_pattern) | |
local block_end_pattern = '^ *' .. re_or(block_ending_keywords) .. re_or { ';', '\\s\\+\\S\\+.*' } .. '$' | |
local block_end_regexp = vim.regex(block_end_pattern) | |
local blank_line_regexp = vim.regex '^ *$' | |
local indent = vim.fn.indent | |
local getline = vim.fn.getline | |
local function scopes_indent_algorithm() | |
local line_number = vim.v.lnum | |
local prev_line_number = search_previous_lines '[^ \\n]' | |
-- if at the start of the file (no prior non-blank lines), indent to the beginning of the line | |
if prev_line_number == 0 then | |
return 0 | |
end | |
local cur_line = getline(line_number) | |
local prev_line = getline(prev_line_number) | |
local prev_indent = indent(prev_line_number) | |
local cur_indent = indent(line_number) | |
local is_blank_line = not not blank_line_regexp:match_str(cur_line) | |
local max_indent = prev_indent + 4 | |
local next_alignment = cur_indent + (4 - (cur_indent % 4)) | |
local is_aligned = cur_indent + 4 == next_alignment | |
-- are we reindenting a line? | |
if not is_blank_line then | |
if cur_indent >= max_indent then | |
return max_indent | |
elseif is_aligned then | |
return cur_indent + 4 | |
else | |
return next_alignment | |
end | |
-- entirely new line | |
elseif cur_indent == 0 then | |
if block_start_regexp:match_str(prev_line) then | |
return max_indent | |
elseif block_end_regexp:match_str(prev_line) then | |
return math.max(0, prev_indent - 4) | |
else | |
return is_aligned and math.min(prev_indent, cur_indent + 4) or next_alignment | |
end | |
-- adjusting new line | |
else | |
return is_aligned and math.min(max_indent, cur_indent + 4) or next_alignment | |
end | |
end | |
return { | |
scopes_indent_algorithm = scopes_indent_algorithm, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment