Sfoglia il codice sorgente

docs: Add comprehensive Lua extension tutorial and update project roadmap

Bernardo Magri 1 mese fa
parent
commit
7b662d6af4
2 ha cambiato i file con 313 aggiunte e 24 eliminazioni
  1. 66 24
      CONTINUATION_PROMPT.md
  2. 247 0
      documentation/LUA_EXTENSION_TUTORIAL.md

+ 66 - 24
CONTINUATION_PROMPT.md

@@ -9,31 +9,57 @@ I'm working on **Lumacs**, an Emacs-inspired text editor written in C++20 with n
 ## Current Status
 
 **Phase 4: Polish & Advanced Features - COMPLETE ✅**
-- Emacs compatibility: **95/100**
+**Phase 5: Minibuffer & Face System - IN PROGRESS**
+- Emacs compatibility: **~97/100** (Minibuffer & Face System foundations laid)
 - Build: Successful, binary at `./build/lumacs`
 - Registers, Minibuffer History, Keyboard Macros, Rectangles implemented.
+- Minibuffer command input with completion implemented.
+- Initial abstract Face system for styling implemented.
 
 ### What's Been Implemented
 
-#### 1. Phase 4 Features (NEW!)
+#### 1. Phase 5 Features (NEW!)
+
+*   **Minibuffer Command System**:
+    *   Implemented `M-x` (or `:`) for minibuffer command input.
+    *   Created a Lua-based command registry (`define_command`, `execute_extended_command`, `get_command_names`).
+    *   Populated with core commands (`save-buffer`, `find-file`, `next-line`, etc.).
+    *   Added tab completion for commands in the minibuffer.
+    *   Exposed `FindFileMode` to Lua API.
+    *   Removed hardcoded `:` key binding for command mode.
+
+*   **Window Separators**:
+    *   Removed dashed horizontal window borders.
+    *   Added vertical `|` separator for vertical splits.
+
+*   **Line Number Display**:
+    *   Removed `|` separator after line numbers.
+
+*   **Face System (Initial Implementation)**:
+    *   Introduced abstract `Face` and `FaceAttributes` for styling (font, color, weight, slant, etc.).
+    *   Refactored `Theme` to manage faces instead of direct colors.
+    *   Updated `TextAttribute` in `Buffer` to store `face_name`.
+    *   Migrated `NcursesEditor` rendering to use the new face system.
+
+#### 2. Phase 4 Features
 - **C-x r s/i** - Registers: Save/restore text from named registers
 - **M-p/M-n** - Minibuffer History: Navigate command/search history  
 - **F3/F4** - Keyboard Macros: Record and replay key sequences
 - **C-x r k/y/t** - Rectangles: Column-based cut/paste/fill operations
 
-#### 2. Phase 3 Features
+#### 3. Phase 3 Features
 - **C-s/C-r** - Incremental Search with highlighting
 - **M-d/M-DEL** - Kill word / Backward kill word
 - **M-u/M-l/M-c** - Word case conversion
 - **C-x C-u/C-l** - Region case conversion
 - **M-;** - Comment/Uncomment (DWIM)
 
-#### 3. Buffer Management (Phase 2)
+#### 4. Buffer Management (Phase 2)
 - **C-x b** - Switch buffer
 - **C-x k** - Kill buffer
 - **C-x C-b** - List buffers
 
-#### 4. Core (Phase 1)
+#### 5. Core (Phase 1)
 - Kill Ring, Mark/Region
 - Undo/Redo
 - Lua configuration
@@ -42,11 +68,12 @@ I'm working on **Lumacs**, an Emacs-inspired text editor written in C++20 with n
 
 ### C++ Core
 - **EditorCore:** Registers, macros, rectangles, complete feature set.
-- **Buffer:** Advanced text manipulation and region support.
-- **NcursesEditor:** Full minibuffer with history, macro recording.
+- **Buffer:** Advanced text manipulation and region support. Now uses abstract face names for styling.
+- **NcursesEditor:** Full minibuffer with history, macro recording. Now renders using the abstract face system.
+- **Theme/Face System:** Dedicated classes (`Color`, `FaceAttributes`, `Face`) for modular and extensible styling.
 
 ### Lua Configuration
-- **init.lua:** Complete keybinding suite for all Phase 4 features.
+- **init.lua:** Complete keybinding suite for all Phase 4 features. Now also defines editor commands.
 
 ## What Has Been Accomplished
 
@@ -76,14 +103,30 @@ I'm working on **Lumacs**, an Emacs-inspired text editor written in C++20 with n
    - **M-p / M-n** in minibuffer to cycle previous commands/search queries
    - Separate history for each mode with 100-item limit.
 
-## Next Steps (Phase 5)
-
-**Lumacs is now feature-complete for power users!** Phase 4 achieved 95% Emacs compatibility with all major advanced features implemented. Optional future enhancements:
-
-- Performance optimization
-- Additional language modes (Python, C++, JavaScript)  
-- Plugin system expansion
-- Advanced search/replace patterns
+## Next Steps (Phase 5 & Roadmap)
+
+### Phase 5: Face System Completion (Immediate Priority)
+*   **Lua API for Faces**: Expose `define_face` to Lua for user-defined faces.
+*   **Face Inheritance**: Implement face inheritance (e.g., `error` face inherits from `default`).
+*   **Semantic Face Definitions**: Define more semantic faces (e.g., `font-lock-variable-name-face`, `font-lock-builtin-face`, `region`, etc.) in themes.
+*   **Buffer Styling via Faces**: Ensure all buffer styling is done using face names consistently (e.g. major modes).
+
+### Future Roadmap / TODOs
+*   **Performance**:
+    *   Optimize redisplay algorithm (only redraw changed lines).
+    *   Implement gap buffer or piece table for better large file handling.
+*   **UI/UX**:
+    *   **GUI Frontend**: Implement a GTK or SDL frontend using the abstract Face system.
+    *   **Mouse Support**: Add mouse click positioning and scrolling.
+    *   **Menu Bar**: Add a terminal-compatible menu bar (like `emacs -nw`).
+*   **Features**:
+    *   **Auto-Complete Popup**: Implement a popup menu for auto-completion (not just minibuffer).
+    *   **Project Management**: `projectile`-like features (find file in project).
+    *   **LSP Support**: Integrate a Language Server Protocol client for intelligent code intelligence.
+    *   **Tree-sitter**: Replace regex-based highlighting with Tree-sitter for robust parsing.
+*   **Documentation**:
+    *   Add Lua API auto-generated docs.
+    *   Write specific tutorials for writing Major Modes.
 
 ## Testing Instructions
 
@@ -92,19 +135,18 @@ I'm working on **Lumacs**, an Emacs-inspired text editor written in C++20 with n
 cmake --build build
 ```
 
-### Test Phase 4 Features:
-Use the provided `test_phase4.txt` file to test:
-- Registers: Set mark, select text, C-x r s, move cursor, C-x r i
-- Rectangles: Select rectangular region, C-x r k, move cursor, C-x r y  
-- Macros: F3, perform some actions, F4, then F4 again to replay
-- History: Use C-x b several times, then M-p/M-n to navigate history
+### Test Phase 5 Features:
+- **Minibuffer**: Run `./build/lumacs`, press `M-x` (Alt-x), type `list-` then TAB for completion, then Enter. Try `find-file` and load a file.
+- **Window Separator**: Press `M-x split-window-right`.
+- **Face System**: Observe consistent styling as before; changes are architectural.
 
-## Implementation Details
+### Implementation Details
 
 1. "How are registers implemented?" → Check `src/editor_core.cpp` register functions
 2. "Where is minibuffer history?" → `src/main_ncurses.cpp` history management  
 3. "How do macros work?" → `src/editor_core.cpp` macro recording system
 4. "Where are rectangles?" → `src/editor_core.cpp` rectangle operations
+5. "Where is the new Face system?" -> `include/lumacs/face.hpp`, `include/lumacs/theme.hpp`, `src/theme.cpp`, `include/lumacs/buffer.hpp`, `src/main_ncurses.cpp`.
 
 ## Phase 4 Success Criteria - ALL ACHIEVED ✅
 
@@ -115,4 +157,4 @@ Use the provided `test_phase4.txt` file to test:
 
 ---
 
-**Phase 4 Complete! Lumacs now provides 95% Emacs compatibility with all major power-user features implemented.**
+**Phase 4 Complete! Lumacs now provides 95% Emacs compatibility with all major power-user features implemented.**

+ 247 - 0
documentation/LUA_EXTENSION_TUTORIAL.md

@@ -0,0 +1,247 @@
+# Extending Lumacs with Lua: A Comprehensive Tutorial
+
+Lumacs is designed to be highly extensible, similar to Emacs. Almost every aspect of the editor—from keybindings to syntax highlighting and core behavior—can be customized using Lua.
+
+This tutorial will guide you through the process of extending Lumacs, turning it into your own personalized development environment.
+
+## 1. Getting Started
+
+Lumacs loads your configuration from `init.lua`. It searches for this file in the following locations (in order):
+1. `./init.lua` (current working directory)
+2. `~/.config/lumacs/init.lua`
+3. `~/.lumacs/init.lua`
+
+Create your first customization by creating this file and adding a welcome message:
+
+```lua
+-- init.lua
+message("Welcome to my custom Lumacs!")
+```
+
+Restart Lumacs, and you should see the message in the status line.
+
+## 2. Keybindings
+
+The most common customization is defining keybindings. Use the global `bind_key` function.
+
+### Basic Bindings
+
+```lua
+-- Bind F12 to insert a timestamp
+bind_key("F12", function()
+    local timestamp = os.date("%Y-%m-%d %H:%M:%S")
+    editor.buffer:insert(editor.cursor, timestamp)
+    message("Inserted timestamp")
+end)
+```
+
+### Modifier Keys
+
+Lumacs supports Control (`C-`) and Meta/Alt (`M-`) modifiers.
+
+```lua
+bind_key("C-s", function() editor.buffer:save() end) -- Ctrl+s
+bind_key("M-x", function() editor:command_mode() end) -- Alt+x
+```
+
+### Key Sequences
+
+You can define multi-key sequences (chords), similar to Emacs.
+
+```lua
+-- Define 'C-c t' to insert a TODO comment
+bind_key("C-c t", function()
+    editor.buffer:insert(editor.cursor, "-- TODO: ")
+end)
+```
+
+## 3. Defining Commands (M-x)
+
+While keybindings are great for frequent actions, you don't want to bind a key for everything. **Commands** allow you to register functions that can be executed by name via the Minibuffer (`M-x`).
+
+Use `define_command(name, function, documentation)`:
+
+```lua
+define_command("hello-world", function()
+    message("Hello from the Minibuffer!")
+end, "Prints a greeting message")
+
+define_command("delete-current-line", function()
+    editor:move_to_line_start()
+    editor:kill_line()
+    editor:kill_line() -- Kill the newline too
+end, "Deletes the current line")
+```
+
+Now, press `M-x` (or `Alt+x`), type `hello-world`, and press Enter. You can also use TAB for auto-completion.
+
+## 4. Creating Major Modes
+
+Major modes specialize the editor for specific file types (e.g., Lua, C++, Python). A buffer can only have one major mode at a time.
+
+Use `define_major_mode(name, configuration)`:
+
+```lua
+define_major_mode("markdown-mode", {
+    -- Files matching these patterns will auto-activate this mode
+    file_patterns = {"%.md$", "%.markdown$"},
+    
+    -- String used for comments (used by M-;)
+    comment_syntax = "<!--",
+
+    -- Setup function: Run when mode is activated
+    setup = function()
+        print("Markdown mode activated")
+        -- You can set mode-specific keybindings here
+    end,
+
+    -- Cleanup function: Run when switching away from this mode
+    cleanup = function()
+        print("Markdown mode deactivated")
+    end,
+
+    -- Syntax Highlighting Logic
+    highlight = function()
+        local buf = editor.buffer
+        buf:clear_styles()
+        
+        -- Simple example: Highlight headings (# Heading)
+        for line_num = 0, buf:line_count() - 1 do
+            local line_text = buf:line(line_num)
+            
+            -- If line starts with #, color it as a Keyword (often used for headings)
+            if string.match(line_text, "^#") then
+                local range = lumacs.Range(
+                    lumacs.Position(line_num, 0),
+                    lumacs.Position(line_num, #line_text)
+                )
+                -- Apply the 'font-lock-keyword-face'
+                buf:set_style(range, lumacs.TextAttribute("font-lock-keyword-face"))
+            end
+        end
+    end
+})
+```
+
+The editor will now automatically detect `.md` files and apply your highlighting!
+
+## 5. Creating Minor Modes
+
+Minor modes provide optional functionality that can be toggled on/off independently of the major mode (e.g., Auto-Save, Spell Check).
+
+```lua
+define_minor_mode("auto-save-mode", {
+    global = false, -- Can be buffer-local or global
+
+    setup = function()
+        message("Auto-save enabled")
+        -- Start a timer or hook into events (see below)
+    end,
+
+    cleanup = function()
+        message("Auto-save disabled")
+    end
+})
+```
+
+Toggle it via `M-x auto-save-mode`.
+
+## 6. Hooks and Events
+
+Your scripts can react to editor events using `editor.buffer:on_buffer_event`.
+
+**Available Events:**
+*   `lumacs.BufferEvent.Loaded`: A file was loaded.
+*   `lumacs.BufferEvent.BeforeSave` / `AfterSave`.
+*   `lumacs.BufferEvent.BeforeChange` / `AfterChange`: Text was modified.
+*   `lumacs.BufferEvent.LanguageChanged`: Major mode changed.
+
+**Example: Auto-Save on Change**
+
+```lua
+local change_count = 0
+
+editor.buffer:on_buffer_event(function(data)
+    if data.event == lumacs.BufferEvent.AfterChange then
+        change_count = change_count + 1
+        if change_count > 20 then
+            editor.buffer:save()
+            message("Auto-saved!")
+            change_count = 0
+        end
+    end
+end)
+```
+
+## 7. The Face System (Theming)
+
+Lumacs uses a "Face" system to separate logical styles (e.g., "This is a comment") from visual appearance (e.g., "Comments are grey and italic").
+
+### Defining Styles
+
+You can modify the active theme or create new faces.
+
+```lua
+-- Get the theme manager
+local tm = editor.theme_manager
+local theme = tm:active_theme()
+
+-- Customize the 'comment' face
+-- Note: In standard terminal (Ncurses), 'family' and 'height' are ignored,
+-- but 'weight', 'slant', 'underline', and 'inverse' are respected.
+theme:set_face("font-lock-comment-face", {
+    foreground = lumacs.Color(100, 100, 100), -- Grey
+    slant = lumacs.FontSlant.Italic
+})
+
+-- Create a custom face
+theme:set_face("my-custom-face", {
+    foreground = lumacs.Color(255, 0, 0),     -- Red
+    background = lumacs.Color(255, 255, 0),   -- Yellow
+    weight = lumacs.FontWeight.Bold,
+    underline = true
+})
+```
+
+### Applying Faces
+
+In your major mode's `highlight` function, apply these faces:
+
+```lua
+local range = lumacs.Range(start_pos, end_pos)
+-- Apply standard face
+buf:set_style(range, lumacs.TextAttribute("font-lock-comment-face"))
+-- Or your custom face
+buf:set_style(range, lumacs.TextAttribute("my-custom-face"))
+```
+
+## 8. Buffer Manipulation API Reference
+
+Common methods available on `editor.buffer` (accessed via `editor:buffer()`):
+
+*   **Text Access:**
+    *   `line(n)`: Get content of line `n` (0-indexed).
+    *   `line_count()`: Total lines.
+    *   `content()`: Full buffer content.
+
+*   **Editing:**
+    *   `insert(pos, text)`: Insert string at `lumacs.Position(row, col)`.
+    *   `replace(range, text)`: Replace text in `lumacs.Range(start, end)`.
+    *   `erase(range)`: Delete text.
+
+*   **Search:**
+    *   `find(query, pos)`: Returns a `Range` if found, or `nil`.
+
+*   **Cursor:**
+    *   `editor.cursor`: Get/Set current `Position`.
+    *   `editor:set_cursor(pos)`: Move cursor.
+
+## Summary
+
+1.  **Define Commands** for user actions (`define_command`).
+2.  **Bind Keys** to those commands or Lua functions (`bind_key`).
+3.  **Create Modes** to organize functionality (`define_major_mode`).
+4.  **Use Hooks** to automate behavior (`on_buffer_event`).
+5.  **Style Text** using the Face system (`set_face`, `set_style`).
+
+Happy hacking!