# Extending Lumacs with Lua Lumacs is designed to be deeply extensible via Lua 5.4. Almost every aspect of the editor, from keybindings to major modes, is configured using the Lua API. ## The `editor` Object The global `editor` object is your gateway to the Lumacs core. It represents the editor application state. ### Core Properties - `editor.buffer`: The currently active **Buffer** object (see [Buffer Operations](#buffer-operations)). - `editor.cursor`: The current cursor position (`Position`). - `editor.config`: The configuration object. - `editor.active_theme`: The currently active theme object. - `editor.theme_manager`: The manager for loading/selecting themes. ### Core Methods - `editor:message(msg)`: Display a message in the minibuffer. - `editor:quit()`: Exit the editor. - `editor:load_file(path)`: Open a file in a new buffer. - `editor:new_buffer(name)`: Create a new scratch buffer. - `editor:switch_buffer_in_window(name)`: Switch the current window to a named buffer. - `editor:close_buffer(name)`: Close a buffer. - `editor:split_horizontally()` / `editor:split_vertically()`: Split the active window. - `editor:close_window()`: Close the active window. - `editor:next_window()`: Cycle focus to the next window. ## Buffer Operations The `Buffer` object (accessed via `editor.buffer`) allows you to manipulate text. ```lua local buf = editor.buffer -- Get info print(buf:name()) print(buf:line_count()) print(buf:filepath()) -- Returns path string or nil if not saved print(buf:is_modified()) -- Content Access local line_text = buf:line(0) -- Get text of line 0 (0-indexed) local full_text = buf:content() -- Modification -- Positions are 0-indexed (line, col) local pos = lumacs.Position(0, 0) buf:insert(pos, "Hello World\n") -- Ranges local start_pos = lumacs.Position(0, 0) local end_pos = lumacs.Position(0, 5) local range = lumacs.Range(start_pos, end_pos) buf:erase(range) -- Styling (Syntax Highlighting) -- Apply a 'Keyword' face to the first word local attr = lumacs.TextAttribute(lumacs.ColorType.Keyword, 0) buf:set_style(range, attr) buf:clear_styles() ``` ## Keybindings You can bind keys to Lua functions or named commands. ### Binding to a Function ```lua editor:bind_key("C-c t", function() editor:message("You pressed Ctrl-c t") end, "Test command") ``` ### Binding to a Command ```lua -- Bind F5 to the existing 'save-buffer' command editor:bind_key("F5", function() editor:execute_command("save-buffer") end) ``` **Key Syntax:** - `C-x`: Control + x - `M-x`: Meta (Alt) + x - `S-x`: Shift + x - `Return`, `Space`, `Backspace`, `Tab`, `Escape` - `ArrowUp`, `ArrowDown`, `PageUp`, `PageDown` - Function keys: `F1` ... `F12` ## Creating Commands Commands can be registered and then executed by name (e.g., via `M-x`). ```lua -- Register a command named 'hello-world' editor:register_command( "hello-world", -- Command Name "Prints hello", -- Documentation function(args) -- Function -- args is a table of strings passed to the command local name = args[1] or "World" editor.buffer:insert(editor.cursor, "Hello " .. name) end, true, -- Interactive? (Can show up in M-x) "s" -- Interactive Spec (Optional: 's' prompts for string) ) ``` ## Major Modes Lumacs uses a "Major Mode" system (implemented in `init.lua`) to configure the editor for specific file types. A Major Mode defines syntax highlighting, keybindings, and setup hooks. ### Defining a Mode ```lua define_major_mode("my-lang-mode", { file_patterns = {"%.mylang$"}, comment_syntax = "//", -- Setup: Runs when mode is activated setup = function() editor:message("MyLang Mode Active") end, -- Syntax Highlighting Logic highlight = function() local buf = editor.buffer buf:clear_styles() -- Scan buffer line by line for i = 0, buf:line_count() - 1 do local line = buf:line(i) -- Find keywords (simple example) if string.find(line, "function") then -- Calculate range and apply style... -- (See init.lua 'lua-mode' for a full regex loop example) end end end, -- Mode-specific keybindings keybindings = { ["C-c C-c"] = function() editor:message("Compiling...") end } }) ``` ## Theming Themes control the colors of the UI and syntax highlighting. ### Creating a Theme Themes are defined by setting colors for `ThemeElement`s. ```lua -- Define a new theme function function setup_my_theme() local tm = editor.theme_manager -- Set faces for specific semantic tags editor:define_face("default", lumacs.FaceAttributes({ foreground = lumacs.Color(200, 200, 200), background = lumacs.Color(20, 20, 20) })) editor:define_face("font-lock-keyword-face", lumacs.FaceAttributes({ foreground = lumacs.Color(255, 100, 100), -- Red keywords weight = lumacs.FontWeight.Bold })) end ``` ## Configuration Access editor configuration via `editor.config`. ```lua -- Set line number width editor.config:set("line_number_width", 4) -- Toggle line numbers local current = editor.config:get_bool("show_line_numbers", true) editor.config:set("show_line_numbers", not current) ``` ## Minibuffer and Interaction You can prompt the user for input using the Minibuffer. ```lua -- Prompt for a string via command mode logic editor:command_mode() -- Or use register_command interactive specs for simpler prompts. ``` ## Directory Structure - `~/.config/lumacs/init.lua`: Main user configuration file. - `~/.config/lumacs/themes/`: Place custom theme Lua files here (if supported by loader). - `~/.config/lumacs/plugins/`: Place plugins here. ## Troubleshooting - **Logs**: Check `lumacs.log` or stdout/stderr for Lua errors. - **MobDebug**: Lumacs supports remote debugging via MobDebug. Ensure `mobdebug.lua` is in your path and set `debug_lua = true` in config. ```