소스 검색

fixing lua major mode

Bernardo Magri 1 개월 전
부모
커밋
3eb8411a20
1개의 변경된 파일113개의 추가작업 그리고 55개의 파일을 삭제
  1. 113 55
      lua/major_modes/lua_mode.lua

+ 113 - 55
lua/major_modes/lua_mode.lua

@@ -1,76 +1,133 @@
 -- Lua Mode for Lumacs
 -- Extracted from init.lua
 
-define_major_mode("lua-mode", {
-    file_patterns = {"%.lua$"},
-    comment_syntax = "--",
+-- 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 = function()
-        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)
-
-            -- Highlight keywords
-            for _, keyword in ipairs(keywords) do
-                local start_pos = 1
-                while true do
-                    local pattern = "%f[%w]" .. keyword .. "%f[%W]"
-                    local pos = string.find(line_text, pattern, start_pos)
-                    if not pos then break end
-
-                    local range = lumacs.Range(
-                        lumacs.Position(line_num, pos - 1),
-                        lumacs.Position(line_num, pos + #keyword - 1)
-                    )
-
-                    buf:set_style(range, lumacs.TextAttribute(lumacs.ColorType.Keyword, 0))
-                    start_pos = pos + #keyword
-                end
+    -- 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
 
-            -- Highlight strings
-            local start_pos = 1
-            while true do
-                local quote_start = string.find(line_text, '"', start_pos, true)
-                if not quote_start then break end
-
-                local quote_end = string.find(line_text, '"', quote_start + 1, true)
-                if not quote_end then break 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, quote_start - 1),
-                    lumacs.Position(line_num, quote_end)
+                    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))
-                start_pos = quote_end + 1
-            end
+                pos = s_end + 1
 
-            -- Highlight comments
-            local comment_pos = string.find(line_text, "--", 1, true)
-            if comment_pos then
+            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, comment_pos - 1),
-                    lumacs.Position(line_num, #line_text)
+                    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
 
-                buf:set_style(range, lumacs.TextAttribute(lumacs.ColorType.Comment, 0))
+            else
+                -- No more tokens
+                pos = len + 1
             end
         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()
@@ -78,6 +135,7 @@ define_major_mode("lua-mode", {
     end,
 
     keybindings = {
-        -- Lua-specific keybindings can go here
+        -- Fix: Explicitly bind space since empty keybindings table might be causing issues
+        [" "] = function() editor:execute_command("self-insert-command", {" "}) end,
     }
-})
+})