-- Lumacs User Configuration File -- ============================================================================ -- This file runs AFTER defaults.hpp, allowing you to customize and extend -- the default Emacs-like behavior. The mode system, keybindings, and commands -- are already set up - use this file to: -- 1. Load additional major modes -- 2. Load themes -- 3. Add custom keybindings -- 4. Define custom commands -- 5. Override default settings -- ============================================================================ -- ============================================================================ -- PACKAGE SYSTEM INITIALIZATION -- ============================================================================ -- Add lua/ to package path for require() to work package.path = package.path .. ";lua/?.lua;lua/?/init.lua" -- Load the package manager local pkg = dofile("lua/core/package.lua") pkg.setup() -- Make it globally accessible lumacs.package = pkg -- Load package commands (M-x package-install, etc.) dofile("lua/core/package-commands.lua") -- Load user packages from ~/.lumacs/packages.lua local loaded, errors = pkg.load_all() if loaded > 0 or errors > 0 then print(string.format("[package] Loaded %d user packages (%d errors)", loaded, errors)) end -- ============================================================================ -- LOAD MAJOR MODES -- ============================================================================ -- Load individual major mode definitions dofile("lua/major_modes/lua_mode.lua") dofile("lua/major_modes/c_cpp_mode.lua") -- ============================================================================ -- LOAD THEMES -- ============================================================================ -- Load individual theme definitions dofile("lua/themes/default.lua") dofile("lua/themes/dracula.lua") dofile("lua/themes/everforest-dark.lua") dofile("lua/themes/gruvbox-light.lua") dofile("lua/themes/nord.lua") dofile("lua/themes/solarized-dark.lua") dofile("lua/themes/catppuccin-mocha.lua") dofile("lua/themes/tokyo-night.lua") dofile("lua/themes/ayu-dark.lua") -- Load theme switching functions and keybindings dofile("lua/themes/themes_init.lua") -- ============================================================================ -- LOAD PACKAGES -- ============================================================================ -- which-key: Display available keybindings for prefix keys dofile("lua/packages/which-key.lua") -- doom-modeline: Doom Emacs-style modeline customization dofile("lua/packages/doom-modeline.lua") -- smartparens: Auto-pairing of brackets, quotes, etc. dofile("lua/packages/smartparens.lua") -- rainbow-delimiters: Colorize nested delimiters by depth dofile("lua/packages/rainbow-delimiters.lua") -- ido: Enhanced fuzzy completion (optional, provides utilities) dofile("lua/packages/ido.lua") -- projectile: Project management and navigation dofile("lua/packages/projectile.lua") -- company: Text completion framework dofile("lua/packages/company.lua") -- goto-line: Go to a specific line number (M-g g) dofile("lua/packages/goto-line.lua") -- recentf: Track and access recently opened files dofile("lua/packages/recentf.lua") -- bookmarks: Save and jump between named positions dofile("lua/packages/bookmarks.lua") -- visual-line: Soft word wrap mode dofile("lua/packages/visual-line.lua") -- ============================================================================ -- MINOR MODES (User-defined extensions) -- ============================================================================ -- Auto-save minor mode lumacs.define_minor_mode("auto-save-mode", { global = false, setup = function() editor:message("[auto-save-mode] Auto-save enabled") end, cleanup = function() editor:message("[auto-save-mode] Auto-save disabled") end }) -- Line numbers minor mode (toggle control) lumacs.define_minor_mode("line-numbers-mode", { global = true, setup = function() editor.config:set("show_line_numbers", true) editor:message("[line-numbers-mode] Line numbers enabled") end, cleanup = function() editor.config:set("show_line_numbers", false) editor:message("[line-numbers-mode] Line numbers disabled") end }) -- ============================================================================ -- CUSTOM KEYBINDINGS (User overrides) -- ============================================================================ -- Example: Custom keybinding for inserting timestamp editor:bind_key("C-c t", function() local cursor_pos = editor.cursor local timestamp = os.date("%Y-%m-%d %H:%M:%S") editor.buffer:insert(cursor_pos, timestamp) editor:message("Inserted timestamp") end) -- Example: Find TODO comments in buffer editor:bind_key("C-c o", function() local buf = editor.buffer local cursor = editor.cursor local search_start = lumacs.Position(cursor.line, cursor.column + 1) local res = buf:find("TODO", search_start) if res then editor.cursor = res.start editor:message("Found TODO at " .. res.start.line .. ":" .. res.start.column) else editor:message("No more TODOs found") end end) -- Line swapping (like VS Code Alt+Up/Down) local function swap_line_up() local buf = editor.buffer local cursor = editor.cursor if cursor.line == 0 then editor:message("Already at first line") return end local current_line = buf:line(cursor.line) local above_line = buf:line(cursor.line - 1) local delete_start = lumacs.Position(cursor.line - 1, 0) local delete_end = lumacs.Position(cursor.line, #current_line) buf:erase(lumacs.Range(delete_start, delete_end)) local text = current_line .. "\n" .. above_line buf:insert(lumacs.Position(cursor.line - 1, 0), text) editor.cursor = lumacs.Position(cursor.line - 1, cursor.column) editor:message("Swapped line up") end local function swap_line_down() local buf = editor.buffer local cursor = editor.cursor if cursor.line >= buf:line_count() - 1 then editor:message("Already at last line") return end local current_line = buf:line(cursor.line) local below_line = buf:line(cursor.line + 1) local delete_start = lumacs.Position(cursor.line, 0) local delete_end = lumacs.Position(cursor.line + 1, #below_line) buf:erase(lumacs.Range(delete_start, delete_end)) local text = below_line .. "\n" .. current_line buf:insert(lumacs.Position(cursor.line, 0), text) editor.cursor = lumacs.Position(cursor.line + 1, cursor.column) editor:message("Swapped line down") end editor:bind_key("M-ArrowUp", swap_line_up) editor:bind_key("M-ArrowDown", swap_line_down) -- ============================================================================ -- FONT SIZE COMMANDS -- ============================================================================ editor:register_command("text-scale-increase", "Increase font size", function(args) local current = editor:font_size() editor:set_font_size(current + 1) return {success = true, message = "Font size: " .. (current + 1)} end) editor:register_command("text-scale-decrease", "Decrease font size", function(args) local current = editor:font_size() editor:set_font_size(current - 1) return {success = true, message = "Font size: " .. (current - 1)} end) editor:register_command("text-scale-set", "Set font size", function(args) if #args == 0 then return {success = true, message = "Current font size: " .. editor:font_size()} end local size = tonumber(args[1]) if size then editor:set_font_size(size) return {success = true, message = "Font size set to: " .. size} else return {success = false, message = "Invalid size: " .. args[1]} end end, {}, true, "s") -- Emacs-style font size keybindings (C-x C-+ and C-x C-- in Emacs) editor:bind_key("C-x +", "text-scale-increase", "Increase font size") editor:bind_key("C-x -", "text-scale-decrease", "Decrease font size") editor:bind_key("C-x =", "text-scale-set", "Show/set font size") -- ============================================================================ -- CUSTOM COMMANDS -- ============================================================================ -- Auto-theme based on time of day editor:register_command("auto-theme", "Automatically set theme based on time of day", function(args) local hour = tonumber(os.date("%H")) local theme_name if hour >= 6 and hour < 18 then theme_name = "gruvbox-light" elseif hour >= 18 and hour < 22 then theme_name = "everforest-dark" else theme_name = "nord" end local success, message = editor:execute_command("set-theme", {theme_name}) if success then return {success = true, message = string.format("Auto-selected %s theme for %d:00", theme_name, hour)} else return {success = false, message = "Failed to auto-select theme: " .. message} end end, false) -- Theme demo command editor:register_command("theme-demo", "Demonstrate theme switching", function(args) local themes = {"solarized-dark", "nord", "gruvbox-light", "dracula"} local success, message = editor:execute_command("set-theme", {themes[1]}) if success then return {success = true, message = "Theme demo - switched to " .. themes[1]} else return {success = false, message = "Demo failed: " .. message} end end, false) -- Evaluate Lua expression editor:register_command("eval-expression", "Evaluate Lua expression", function(args) if #args == 0 then return {success = false, message = "Lua expression required"} end local expr = table.concat(args, " ") local func, err = load("return " .. expr) if not func then return {success = false, message = "Parse error: " .. err} end local success, result = pcall(func) if success then return {success = true, message = tostring(result)} else return {success = false, message = "Error: " .. tostring(result)} end end, true, "s") -- ============================================================================ -- CONFIGURATION OVERRIDES -- ============================================================================ -- Uncomment to change defaults: -- editor.config:set("tab_width", 2) -- editor.config:set("indent_tabs_mode", true) -- editor.config:set("scroll_margin", 5) -- ============================================================================ -- AUTO-ACTIVATE MAJOR MODE -- ============================================================================ -- This is called after loading to ensure file-specific modes are activated lumacs.auto_activate_major_mode() -- Welcome message (override default) editor:message("Lumacs ready! C-h ? for help, M-x for commands, C-x t for themes")