defaults.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #pragma once
  2. namespace lumacs {
  3. constexpr const char* LUA_DEFAULTS = R"(
  4. -- =========================================================
  5. -- Lumacs Embedded Defaults
  6. -- =========================================================
  7. -- This runs BEFORE the user's init.lua.
  8. -- It establishes the core editing environment.
  9. -- 1. Sane Editor Config
  10. editor.config:set("show_line_numbers", true)
  11. editor.config:set("tab_width", 4)
  12. -- 2. Mode Infrastructure
  13. local major_modes = {}
  14. local minor_modes = {}
  15. local buffer_major_modes = {}
  16. local buffer_minor_modes = {}
  17. function define_major_mode(name, config)
  18. major_modes[name] = {
  19. name = name,
  20. file_patterns = config.file_patterns or {},
  21. setup = config.setup or function() end,
  22. cleanup = config.cleanup or function() end,
  23. highlight = config.highlight or nil,
  24. keybindings = config.keybindings or {},
  25. comment_syntax = config.comment_syntax or "--",
  26. }
  27. end
  28. function define_minor_mode(name, config)
  29. minor_modes[name] = {
  30. name = name,
  31. setup = config.setup or function() end,
  32. cleanup = config.cleanup or function() end,
  33. keybindings = config.keybindings or {},
  34. global = config.global or false,
  35. }
  36. end
  37. function activate_major_mode(mode_name)
  38. local buf = editor.buffer
  39. local buf_name = buf:name()
  40. local mode = major_modes[mode_name]
  41. if not mode then return false end
  42. buffer_major_modes[buf_name] = mode_name
  43. if mode.highlight then
  44. buf:on_buffer_event(function(event_data)
  45. if event_data.event == lumacs.BufferEvent.Loaded or
  46. event_data.event == lumacs.BufferEvent.LanguageChanged then
  47. mode.highlight()
  48. end
  49. end)
  50. mode.highlight()
  51. end
  52. -- Register mode-specific keybindings
  53. -- Note: This is a simple implementation that binds globally for now.
  54. -- A proper implementation would use a keymap stack.
  55. for key, func in pairs(mode.keybindings) do
  56. editor:bind_key(key, func)
  57. end
  58. mode.setup()
  59. return true
  60. end
  61. function current_major_mode()
  62. local buf = editor.buffer
  63. local buf_name = buf:name()
  64. return buffer_major_modes[buf_name] or "fundamental-mode"
  65. end
  66. define_major_mode("fundamental-mode", {})
  67. function auto_activate_major_mode()
  68. local buf = editor.buffer
  69. local buf_name = buf:name()
  70. for mode_name, mode in pairs(major_modes) do
  71. for _, pattern in ipairs(mode.file_patterns) do
  72. if string.match(buf_name, pattern) then
  73. activate_major_mode(mode_name)
  74. return
  75. end
  76. end
  77. end
  78. activate_major_mode("fundamental-mode")
  79. end
  80. -- 3. Basic Editing Commands & Registration
  81. -- Navigation
  82. editor:register_command("next-line", "Move cursor down", function() editor:move_down() end, true)
  83. editor:register_command("previous-line", "Move cursor up", function() editor:move_up() end, true)
  84. editor:register_command("forward-char", "Move cursor right", function() editor:move_right() end, true)
  85. editor:register_command("backward-char", "Move cursor left", function() editor:move_left() end, true)
  86. editor:register_command("forward-word", "Move forward one word", function() editor:move_forward_word() end, true)
  87. editor:register_command("backward-word", "Move backward one word", function() editor:move_backward_word() end, true)
  88. editor:register_command("move-beginning-of-line", "Go to beginning of line", function() editor:move_to_line_start() end, true)
  89. editor:register_command("move-end-of-line", "Go to end of line", function() editor:move_to_line_end() end, true)
  90. editor:register_command("beginning-of-buffer", "Go to beginning of buffer", function() editor:goto_beginning() end, true)
  91. editor:register_command("end-of-buffer", "Go to end of buffer", function() editor:goto_end() end, true)
  92. editor:register_command("scroll-up-command", "Page down", function() editor:page_down() end, true)
  93. editor:register_command("scroll-down-command", "Page up", function() editor:page_up() end, true)
  94. -- Insertion / Deletion
  95. function lumacs_insert_newline()
  96. local cursor = editor.cursor
  97. editor.buffer:insert_newline(cursor)
  98. -- Move to start of next line
  99. editor.cursor = lumacs.Position(cursor.line + 1, 0)
  100. end
  101. editor:register_command("insert-newline", "Insert newline", lumacs_insert_newline, true)
  102. function lumacs_backward_delete_char()
  103. local cursor = editor.cursor
  104. if cursor.line == 0 and cursor.column == 0 then return end
  105. editor.buffer:erase_char(cursor)
  106. -- Calculate new cursor position
  107. local new_pos = cursor
  108. if new_pos.column > 0 then
  109. new_pos = lumacs.Position(new_pos.line, new_pos.column - 1)
  110. elseif new_pos.line > 0 then
  111. local prev_line_len = #editor.buffer:line(new_pos.line - 1)
  112. new_pos = lumacs.Position(new_pos.line - 1, prev_line_len)
  113. end
  114. editor.cursor = new_pos
  115. end
  116. editor:register_command("backward-delete-char", "Delete char backward", lumacs_backward_delete_char, true)
  117. function lumacs_delete_char()
  118. local cursor = editor.cursor
  119. editor.buffer:erase_char(lumacs.Position(cursor.line, cursor.column + 1))
  120. end
  121. editor:register_command("delete-char", "Delete char forward", lumacs_delete_char, true)
  122. function self_insert_command(args)
  123. local char_to_insert = args[1]
  124. if not char_to_insert then return end
  125. editor.buffer:insert(editor.cursor, char_to_insert)
  126. editor:move_right()
  127. end
  128. editor:register_command("self-insert-command", "Insert char", self_insert_command, true)
  129. -- Clipboard / Kill Ring
  130. editor:register_command("kill-line", "Kill rest of line", function() editor:kill_line() end, true)
  131. editor:register_command("kill-region", "Kill selected region", function() editor:kill_region() end, true)
  132. editor:register_command("copy-region-as-kill", "Copy region", function() editor:copy_region_as_kill() end, true)
  133. editor:register_command("yank", "Paste", function() editor:yank() end, true)
  134. editor:register_command("yank-pop", "Cycle paste", function() editor:yank_pop() end, true)
  135. -- Undo/Redo
  136. editor:register_command("undo", "Undo", function() editor:undo() end, true)
  137. editor:register_command("redo", "Redo", function() editor:redo() end, true)
  138. -- File/Buffer
  139. editor:register_command("save-buffer", "Save current buffer", function()
  140. if editor.buffer:save() then editor:message("Saved") else editor:message("Failed to save") end
  141. end, true)
  142. editor:register_command("find-file", "Open file", function() editor:find_file_mode() end, true, "f")
  143. editor:register_command("switch-buffer", "Switch buffer", function() editor:buffer_switch_mode() end, true, "b")
  144. editor:register_command("kill-buffer", "Kill buffer", function() editor:kill_buffer_mode() end, true, "b")
  145. editor:register_command("save-buffers-kill-terminal", "Quit", function() editor:quit() end, true)
  146. editor:register_command("execute-extended-command", "M-x", function() editor:command_mode() end, true)
  147. -- Macros
  148. editor:register_command("start-kbd-macro", "Start recording macro", function() editor:start_kbd_macro() end, true)
  149. editor:register_command("end-kbd-macro-or-call", "End recording or call macro", function() editor:end_kbd_macro_or_call() end, true)
  150. -- 4. Default Keybindings
  151. editor:bind_key("Return", "insert-newline")
  152. editor:bind_key("Backspace", "backward-delete-char")
  153. editor:bind_key("Delete", "delete-char")
  154. -- Arrow Keys
  155. editor:bind_key("ArrowUp", "previous-line")
  156. editor:bind_key("ArrowDown", "next-line")
  157. editor:bind_key("ArrowLeft", "backward-char")
  158. editor:bind_key("ArrowRight", "forward-char")
  159. -- Emacs Navigation
  160. editor:bind_key("C-f", "forward-char")
  161. editor:bind_key("C-b", "backward-char")
  162. editor:bind_key("C-n", "next-line")
  163. editor:bind_key("C-p", "previous-line")
  164. editor:bind_key("C-a", "move-beginning-of-line")
  165. editor:bind_key("C-e", "move-end-of-line")
  166. editor:bind_key("M-f", "forward-word")
  167. editor:bind_key("M-b", "backward-word")
  168. editor:bind_key("M-<", "beginning-of-buffer")
  169. editor:bind_key("M->", "end-of-buffer")
  170. editor:bind_key("C-v", "scroll-up-command")
  171. editor:bind_key("M-v", "scroll-down-command")
  172. -- File & Window Ops
  173. editor:bind_key("C-x C-c", "save-buffers-kill-terminal")
  174. editor:bind_key("C-x C-s", "save-buffer")
  175. editor:bind_key("C-x C-f", "find-file")
  176. editor:bind_key("C-x b", "switch-buffer")
  177. editor:bind_key("C-x k", "kill-buffer")
  178. editor:bind_key("C-x 0", "delete-window") -- Need to implement
  179. editor:bind_key("C-x 1", "delete-other-windows") -- Need to implement
  180. editor:bind_key("C-x 2", "split-window-below") -- Need to implement
  181. editor:bind_key("C-x 3", "split-window-right") -- Need to implement
  182. editor:bind_key("C-x o", "other-window") -- Need to implement
  183. editor:bind_key("M-x", "execute-extended-command")
  184. -- Windows Implementation
  185. editor:register_command("delete-window", "Close window", function() editor:close_window() end, true)
  186. editor:register_command("split-window-below", "Split horizontal", function() editor:split_horizontally() end, true)
  187. editor:register_command("split-window-right", "Split vertical", function() editor:split_vertically() end, true)
  188. editor:register_command("other-window", "Next window", function() editor:next_window() end, true)
  189. -- Undo/Redo
  190. editor:bind_key("C-/", "undo")
  191. editor:bind_key("C-_", "undo")
  192. editor:bind_key("C-x u", "redo")
  193. -- Mark & Kill Ring
  194. editor:bind_key("C-@", function() editor.buffer:set_mark(editor.cursor) editor:message("Mark set") end)
  195. editor:bind_key("C-w", "kill-region")
  196. editor:bind_key("M-w", "copy-region-as-kill")
  197. editor:bind_key("C-y", "yank")
  198. editor:bind_key("M-y", "yank-pop")
  199. editor:bind_key("C-k", "kill-line")
  200. -- Macros
  201. editor:bind_key("F3", "start-kbd-macro")
  202. editor:bind_key("F4", "end-kbd-macro-or-call")
  203. -- Theme Management
  204. editor:register_command("set-theme", "Set active theme", function(args)
  205. if #args == 0 then
  206. return {success = false, message = "Theme name required"}
  207. end
  208. local theme_name = args[1]
  209. local theme_manager = editor.theme_manager
  210. local available_themes = theme_manager:theme_names()
  211. -- Check if theme exists
  212. local theme_exists = false
  213. for _, name in ipairs(available_themes) do
  214. if name == theme_name then
  215. theme_exists = true
  216. break
  217. end
  218. end
  219. if not theme_exists then
  220. return {success = false, message = "Theme '" .. theme_name .. "' not found. Available: " .. table.concat(available_themes, ", ")}
  221. end
  222. theme_manager:set_active_theme(theme_name)
  223. editor:message("Switched to theme: " .. theme_name)
  224. return {success = true, message = "Switched to theme: " .. theme_name}
  225. end, true, "s")
  226. -- Auto-activate mode
  227. auto_activate_major_mode()
  228. )";
  229. } // namespace lumacs