| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- -- Lua Mode for Lumacs
- -- Extracted from init.lua
- -- Define highlighting function locally so it can be used in setup
- local function highlight_lua()
- local buf = editor.buffer
- buf:clear_styles()
- -- Keywords to highlight
- local keywords = {
- "function", "local", "end", "if", "then", "else", "elseif",
- "for", "while", "do", "return", "break", "and", "or", "not",
- "true", "false", "nil", "in", "repeat", "until"
- }
- -- Highlight each line
- for line_num = 0, buf:line_count() - 1 do
- local line_text = buf:line(line_num)
- local len = #line_text
- local pos = 1
- -- Parse line to handle priority (Comments > Strings > Keywords)
- while pos <= len do
- -- Find nearest tokens
- local comment_start = string.find(line_text, "--", pos, true)
- local string_dq_start = string.find(line_text, '"', pos, true)
- local string_sq_start = string.find(line_text, "'", pos, true)
- -- Determine the first token
- local mode = "code"
- local token_start = len + 2 -- Sentinel
- if comment_start and comment_start < token_start then
- token_start = comment_start
- mode = "comment"
- end
- if string_dq_start and string_dq_start < token_start then
- token_start = string_dq_start
- mode = "string_dq"
- end
- if string_sq_start and string_sq_start < token_start then
- token_start = string_sq_start
- mode = "string_sq"
- end
- -- 1. Process code/keywords BEFORE the token
- local code_end = token_start - 1
- if code_end >= pos then
- local code_chunk = string.sub(line_text, pos, code_end)
-
- for _, keyword in ipairs(keywords) do
- local s = 1
- while true do
- -- Match whole words only
- local p_start, p_end = string.find(code_chunk, "%f[%w]" .. keyword .. "%f[%W]", s)
- if not p_start then break end
- local abs_start = pos + p_start - 1
- local abs_end = pos + p_end - 1
-
- local range = lumacs.Range(
- lumacs.Position(line_num, abs_start - 1),
- lumacs.Position(line_num, abs_end)
- )
- buf:set_style(range, lumacs.TextAttribute(lumacs.ColorType.Keyword, 0))
- s = p_end + 1
- end
- end
- end
- -- 2. Process the token
- if mode == "comment" then
- -- Comment goes to end of line
- local range = lumacs.Range(
- lumacs.Position(line_num, token_start - 1),
- lumacs.Position(line_num, len)
- )
- buf:set_style(range, lumacs.TextAttribute(lumacs.ColorType.Comment, 0))
- break -- Done with this line
- elseif mode == "string_dq" then
- local _, s_end = string.find(line_text, '"', token_start + 1, true)
- if not s_end then s_end = len end
- local range = lumacs.Range(
- lumacs.Position(line_num, token_start - 1),
- lumacs.Position(line_num, s_end)
- )
- buf:set_style(range, lumacs.TextAttribute(lumacs.ColorType.String, 0))
- pos = s_end + 1
- elseif mode == "string_sq" then
- local _, s_end = string.find(line_text, "'", token_start + 1, true)
- if not s_end then s_end = len end
- local range = lumacs.Range(
- lumacs.Position(line_num, token_start - 1),
- lumacs.Position(line_num, s_end)
- )
- buf:set_style(range, lumacs.TextAttribute(lumacs.ColorType.String, 0))
- pos = s_end + 1
- else
- -- No more tokens
- pos = len + 1
- end
- end
- end
- end
- define_major_mode("lua-mode", {
- file_patterns = {"%.lua$"},
- comment_syntax = "--",
- highlight = highlight_lua,
- setup = function()
- editor:message("[lua-mode] Lua mode activated")
-
- -- Register a hook to re-highlight on change
- -- Note: This adds a listener every time the mode is setup.
- -- Ideally, we'd track and remove it, but for now this ensures responsiveness.
- editor.buffer:on_buffer_event(function(data)
- if data.event == lumacs.BufferEvent.AfterChange then
- -- Only run if we are still in lua-mode (simple check)
- -- Using a protected call in case global state changes
- local status, mode_name = pcall(current_major_mode)
- if status and mode_name == "lua-mode" then
- highlight_lua()
- end
- end
- end)
- end,
- cleanup = function()
- editor:message("[lua-mode] Lua mode deactivated")
- end,
- keybindings = {
- -- Fix: Explicitly bind space since empty keybindings table might be causing issues
- [" "] = function() editor:execute_command("self-insert-command", {" "}) end,
- }
- })
|