|
|
@@ -0,0 +1,197 @@
|
|
|
+#pragma once
|
|
|
+
|
|
|
+namespace lumacs {
|
|
|
+
|
|
|
+constexpr const char* LUA_DEFAULTS = R"(
|
|
|
+-- =========================================================
|
|
|
+-- Lumacs Embedded Defaults
|
|
|
+-- =========================================================
|
|
|
+-- This runs BEFORE the user's init.lua.
|
|
|
+
|
|
|
+-- 1. Sane Editor Config
|
|
|
+editor.config:set("show_line_numbers", true)
|
|
|
+editor.config:set("tab_width", 4)
|
|
|
+editor.config:set("debug_lua", false)
|
|
|
+
|
|
|
+-- 2. Mode Infrastructure
|
|
|
+local major_modes = {}
|
|
|
+local minor_modes = {}
|
|
|
+local buffer_major_modes = {}
|
|
|
+local buffer_minor_modes = {}
|
|
|
+
|
|
|
+function define_major_mode(name, config)
|
|
|
+ major_modes[name] = {
|
|
|
+ name = name,
|
|
|
+ file_patterns = config.file_patterns or {},
|
|
|
+ setup = config.setup or function() end,
|
|
|
+ cleanup = config.cleanup or function() end,
|
|
|
+ highlight = config.highlight or nil,
|
|
|
+ keybindings = config.keybindings or {},
|
|
|
+ comment_syntax = config.comment_syntax or "--",
|
|
|
+ }
|
|
|
+end
|
|
|
+
|
|
|
+function define_minor_mode(name, config)
|
|
|
+ minor_modes[name] = {
|
|
|
+ name = name,
|
|
|
+ setup = config.setup or function() end,
|
|
|
+ cleanup = config.cleanup or function() end,
|
|
|
+ keybindings = config.keybindings or {},
|
|
|
+ global = config.global or false,
|
|
|
+ }
|
|
|
+end
|
|
|
+
|
|
|
+function activate_major_mode(mode_name)
|
|
|
+ local buf = editor.buffer
|
|
|
+ local buf_name = buf:name()
|
|
|
+ local mode = major_modes[mode_name]
|
|
|
+ if not mode then return false end
|
|
|
+
|
|
|
+ buffer_major_modes[buf_name] = mode_name
|
|
|
+
|
|
|
+ if mode.highlight then
|
|
|
+ buf:on_buffer_event(function(event_data)
|
|
|
+ if event_data.event == lumacs.BufferEvent.Loaded or
|
|
|
+ event_data.event == lumacs.BufferEvent.LanguageChanged then
|
|
|
+ mode.highlight()
|
|
|
+ end
|
|
|
+ end)
|
|
|
+ mode.highlight()
|
|
|
+ end
|
|
|
+
|
|
|
+ for key, func in pairs(mode.keybindings) do
|
|
|
+ editor:bind_key(key, func)
|
|
|
+ end
|
|
|
+
|
|
|
+ mode.setup()
|
|
|
+ return true
|
|
|
+end
|
|
|
+
|
|
|
+function current_major_mode()
|
|
|
+ local buf = editor.buffer
|
|
|
+ local buf_name = buf:name()
|
|
|
+ return buffer_major_modes[buf_name] or "fundamental-mode"
|
|
|
+end
|
|
|
+
|
|
|
+define_major_mode("fundamental-mode", {})
|
|
|
+
|
|
|
+function auto_activate_major_mode()
|
|
|
+ local buf = editor.buffer
|
|
|
+ local buf_name = buf:name()
|
|
|
+ for mode_name, mode in pairs(major_modes) do
|
|
|
+ for _, pattern in ipairs(mode.file_patterns) do
|
|
|
+ if string.match(buf_name, pattern) then
|
|
|
+ activate_major_mode(mode_name)
|
|
|
+ return
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+-- 3. Basic Editing Commands
|
|
|
+function lumacs_insert_newline()
|
|
|
+ local cursor = editor.cursor
|
|
|
+ editor.buffer:insert_newline(cursor)
|
|
|
+ editor:set_cursor(lumacs.Position(cursor.line + 1, 0))
|
|
|
+end
|
|
|
+editor:register_command("insert-newline", "Insert newline", lumacs_insert_newline, true)
|
|
|
+
|
|
|
+function lumacs_backward_delete_char()
|
|
|
+ local cursor = editor.cursor
|
|
|
+ if cursor.line == 0 and cursor.column == 0 then return end
|
|
|
+ editor.buffer:erase_char(cursor)
|
|
|
+ -- Cursor adjustment is handled by buffer logic usually, but let's be safe
|
|
|
+ local new_pos = cursor
|
|
|
+ if new_pos.column > 0 then new_pos = lumacs.Position(new_pos.line, new_pos.column - 1)
|
|
|
+ elseif new_pos.line > 0 then
|
|
|
+ local prev_line_len = #editor.buffer:line(new_pos.line - 1)
|
|
|
+ new_pos = lumacs.Position(new_pos.line - 1, prev_line_len)
|
|
|
+ end
|
|
|
+ editor.cursor = new_pos
|
|
|
+end
|
|
|
+editor:register_command("backward-delete-char", "Delete char backward", lumacs_backward_delete_char, true)
|
|
|
+
|
|
|
+function lumacs_delete_char()
|
|
|
+ local cursor = editor.cursor
|
|
|
+ editor.buffer:erase_char(lumacs.Position(cursor.line, cursor.column + 1))
|
|
|
+end
|
|
|
+editor:register_command("delete-char", "Delete char forward", lumacs_delete_char, true)
|
|
|
+
|
|
|
+function self_insert_command(args)
|
|
|
+ local char_to_insert = args[1]
|
|
|
+ if not char_to_insert then return end
|
|
|
+ editor.buffer:insert(editor.cursor, char_to_insert)
|
|
|
+ editor:move_right()
|
|
|
+end
|
|
|
+editor:register_command("self-insert-command", "Insert char", self_insert_command, true)
|
|
|
+
|
|
|
+-- 4. Keybindings
|
|
|
+editor:bind_key("Return", lumacs_insert_newline)
|
|
|
+editor:bind_key("Backspace", lumacs_backward_delete_char)
|
|
|
+editor:bind_key("Delete", lumacs_delete_char)
|
|
|
+
|
|
|
+-- Arrow Keys
|
|
|
+editor:bind_key("ArrowUp", function() editor:move_up() end)
|
|
|
+editor:bind_key("ArrowDown", function() editor:move_down() end)
|
|
|
+editor:bind_key("ArrowLeft", function() editor:move_left() end)
|
|
|
+editor:bind_key("ArrowRight", function() editor:move_right() end)
|
|
|
+
|
|
|
+-- Emacs Navigation
|
|
|
+editor:bind_key("C-f", "forward-char")
|
|
|
+editor:bind_key("C-b", "backward-char")
|
|
|
+editor:bind_key("C-n", "next-line")
|
|
|
+editor:bind_key("C-p", "previous-line")
|
|
|
+editor:bind_key("C-a", "move-beginning-of-line")
|
|
|
+editor:bind_key("C-e", "move-end-of-line")
|
|
|
+editor:bind_key("M-f", "forward-word")
|
|
|
+editor:bind_key("M-b", "backward-word")
|
|
|
+editor:bind_key("M-<", "beginning-of-buffer")
|
|
|
+editor:bind_key("M->", "end-of-buffer")
|
|
|
+editor:bind_key("C-v", "scroll-up-command")
|
|
|
+editor:bind_key("M-v", "scroll-down-command")
|
|
|
+
|
|
|
+-- File & Window Ops
|
|
|
+editor:bind_key("C-x C-c", "save-buffers-kill-terminal")
|
|
|
+editor:bind_key("C-x C-s", "save-buffer")
|
|
|
+editor:bind_key("C-x C-f", "find-file")
|
|
|
+editor:bind_key("C-x b", "switch-buffer")
|
|
|
+editor:bind_key("C-x k", "kill-buffer")
|
|
|
+editor:bind_key("C-x 0", "delete-window")
|
|
|
+editor:bind_key("C-x 1", "delete-other-windows")
|
|
|
+editor:bind_key("C-x 2", "split-window-below")
|
|
|
+editor:bind_key("C-x 3", "split-window-right")
|
|
|
+editor:bind_key("C-x o", "other-window")
|
|
|
+editor:bind_key("M-x", "execute-extended-command")
|
|
|
+
|
|
|
+-- Undo/Redo
|
|
|
+editor:bind_key("C-/", "undo")
|
|
|
+editor:bind_key("C-_", "undo")
|
|
|
+editor:bind_key("C-x u", "redo")
|
|
|
+
|
|
|
+-- Mark & Kill Ring
|
|
|
+editor:bind_key("C-@", function() editor.buffer:set_mark(editor.cursor) editor:message("Mark set") end)
|
|
|
+editor:bind_key("C-w", "kill-region")
|
|
|
+editor:bind_key("M-w", "copy-region-as-kill")
|
|
|
+editor:bind_key("C-y", "yank")
|
|
|
+editor:bind_key("M-y", "yank-pop")
|
|
|
+editor:bind_key("C-k", "kill-line")
|
|
|
+
|
|
|
+-- Macros
|
|
|
+editor:bind_key("F3", "start-kbd-macro")
|
|
|
+editor:bind_key("F4", "end-kbd-macro-or-call")
|
|
|
+
|
|
|
+-- Register Basic Commands (Wrappers for C++ commands)
|
|
|
+editor:register_command("save-buffer", "Save current buffer", function() if editor.buffer:save() then editor:message("Saved") else editor:message("Failed to save") end end, true, "b")
|
|
|
+editor:register_command("find-file", "Open file", function() editor:find_file_mode() end, true, "f")
|
|
|
+editor:register_command("switch-buffer", "Switch buffer", function() editor:buffer_switch_mode() end, true, "b")
|
|
|
+editor:register_command("kill-buffer", "Kill buffer", function() editor:kill_buffer_mode() end, true, "b")
|
|
|
+editor:register_command("start-kbd-macro", "Start recording macro", function() editor:start_kbd_macro() end, true)
|
|
|
+editor:register_command("end-kbd-macro-or-call", "End recording or call macro", function() editor:end_kbd_macro_or_call() end, true)
|
|
|
+editor:register_command("execute-extended-command", "M-x", function() editor:command_mode() end, true)
|
|
|
+editor:register_command("save-buffers-kill-terminal", "Quit", function() editor:quit() end, true)
|
|
|
+
|
|
|
+-- Auto-activate mode for initial buffer
|
|
|
+auto_activate_major_mode()
|
|
|
+)";
|
|
|
+
|
|
|
+} // namespace lumacs
|