mui 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +18 -10
  3. data/CHANGELOG.md +162 -0
  4. data/README.md +309 -6
  5. data/docs/_config.yml +56 -0
  6. data/docs/configuration.md +314 -0
  7. data/docs/getting-started.md +140 -0
  8. data/docs/index.md +55 -0
  9. data/docs/jobs.md +297 -0
  10. data/docs/keybindings.md +229 -0
  11. data/docs/plugins.md +285 -0
  12. data/docs/syntax-highlighting.md +155 -0
  13. data/lib/mui/color_manager.rb +140 -6
  14. data/lib/mui/color_scheme.rb +1 -0
  15. data/lib/mui/command_completer.rb +11 -2
  16. data/lib/mui/command_history.rb +89 -0
  17. data/lib/mui/command_line.rb +32 -2
  18. data/lib/mui/command_registry.rb +21 -2
  19. data/lib/mui/config.rb +3 -1
  20. data/lib/mui/editor.rb +90 -2
  21. data/lib/mui/floating_window.rb +53 -1
  22. data/lib/mui/handler_result.rb +13 -7
  23. data/lib/mui/highlighters/search_highlighter.rb +2 -1
  24. data/lib/mui/highlighters/syntax_highlighter.rb +4 -1
  25. data/lib/mui/insert_completion_state.rb +15 -2
  26. data/lib/mui/key_handler/base.rb +87 -0
  27. data/lib/mui/key_handler/command_mode.rb +68 -0
  28. data/lib/mui/key_handler/insert_mode.rb +10 -41
  29. data/lib/mui/key_handler/normal_mode.rb +24 -51
  30. data/lib/mui/key_handler/operators/paste_operator.rb +9 -3
  31. data/lib/mui/key_handler/search_mode.rb +10 -7
  32. data/lib/mui/key_handler/visual_mode.rb +15 -10
  33. data/lib/mui/key_notation_parser.rb +159 -0
  34. data/lib/mui/key_sequence.rb +67 -0
  35. data/lib/mui/key_sequence_buffer.rb +85 -0
  36. data/lib/mui/key_sequence_handler.rb +163 -0
  37. data/lib/mui/key_sequence_matcher.rb +79 -0
  38. data/lib/mui/line_renderer.rb +52 -1
  39. data/lib/mui/mode_manager.rb +3 -2
  40. data/lib/mui/screen.rb +30 -6
  41. data/lib/mui/search_state.rb +74 -27
  42. data/lib/mui/syntax/language_detector.rb +33 -1
  43. data/lib/mui/syntax/lexers/c_lexer.rb +2 -0
  44. data/lib/mui/syntax/lexers/css_lexer.rb +121 -0
  45. data/lib/mui/syntax/lexers/go_lexer.rb +207 -0
  46. data/lib/mui/syntax/lexers/html_lexer.rb +118 -0
  47. data/lib/mui/syntax/lexers/javascript_lexer.rb +219 -0
  48. data/lib/mui/syntax/lexers/markdown_lexer.rb +210 -0
  49. data/lib/mui/syntax/lexers/ruby_lexer.rb +3 -0
  50. data/lib/mui/syntax/lexers/rust_lexer.rb +150 -0
  51. data/lib/mui/syntax/lexers/typescript_lexer.rb +225 -0
  52. data/lib/mui/terminal_adapter/base.rb +21 -0
  53. data/lib/mui/terminal_adapter/curses.rb +37 -11
  54. data/lib/mui/themes/default.rb +263 -132
  55. data/lib/mui/version.rb +1 -1
  56. data/lib/mui/window.rb +105 -39
  57. data/lib/mui/window_manager.rb +7 -0
  58. data/lib/mui/wrap_cache.rb +40 -0
  59. data/lib/mui/wrap_helper.rb +84 -0
  60. data/lib/mui.rb +15 -0
  61. metadata +26 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9515ecfb14d1a9ea5422a842fd22911c303f2465f35827b879117e3cce4d1551
4
- data.tar.gz: e6daedc45ebb07f1e8b094f590ae9749bfae49e2ced12017cba16f1c1dc255c0
3
+ metadata.gz: fc6a6725223b44bd937314729fc4008b726123dd1624adfdf3adc868b9d4d71d
4
+ data.tar.gz: 1c58af876fa5c06fb9033a9968dd1de012265f3d3b85bb50a46b17a9e24eeca5
5
5
  SHA512:
6
- metadata.gz: 4f493037291b8801dd2fc8a6101fb714110c12653ebb432900eebaa8f135d91597c8c862d5cf2b380e332d689decbada6d06f406e7f8c8eae859819d63887845
7
- data.tar.gz: de2b83ea5a999760a171bb037bc264035ef1b43878b806a2b0577099b5601e6e94bdbf6d711604fd9d5a7df01d381665ed734526e1d0f643f896b40e89954604
6
+ metadata.gz: a7a0d46bdf37d31dd6a475b4c42665462e15ed2eee1cad432eed7dcec13776974cd95ed1853e2856fffae2005d367ae6a78294d30e2343ee25240995e943c5dc
7
+ data.tar.gz: 1f7b17692e0f2349eadbdd38b3687ca661f6d8f6196ba162579e28cc8b7f837d00d36d1ba1533a57d52e3e20f0f1510f51dc5333c2b494bc053c6533e62fd324
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-12-11 15:57:29 UTC using RuboCop version 1.81.7.
3
+ # on 2025-12-18 10:56:40 UTC using RuboCop version 1.81.7.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -12,10 +12,11 @@ Gemspec/RequiredRubyVersion:
12
12
  Exclude:
13
13
  - 'test/fixtures/mui-test-plugin/mui-test-plugin.gemspec'
14
14
 
15
- # Offense count: 3
15
+ # Offense count: 4
16
16
  # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
17
17
  Lint/DuplicateBranch:
18
18
  Exclude:
19
+ - 'lib/mui/editor.rb'
19
20
  - 'lib/mui/key_handler/command_mode.rb'
20
21
  - 'lib/mui/plugin_manager.rb'
21
22
  - 'lib/mui/register.rb'
@@ -33,35 +34,36 @@ Lint/MissingSuper:
33
34
  Exclude:
34
35
  - 'test/test_helper.rb'
35
36
 
36
- # Offense count: 2
37
+ # Offense count: 3
37
38
  # This cop supports safe autocorrection (--autocorrect).
38
39
  # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
39
40
  # NotImplementedExceptions: NotImplementedError
40
41
  Lint/UnusedMethodArgument:
41
42
  Exclude:
42
43
  - 'lib/mui/terminal_adapter/base.rb'
44
+ - 'test/mui/highlighters/test_search_highlighter.rb'
43
45
 
44
46
  # Offense count: 1
45
47
  Lint/UselessConstantScoping:
46
48
  Exclude:
47
49
  - 'lib/mui/buffer_word_cache.rb'
48
50
 
49
- # Offense count: 32
51
+ # Offense count: 35
50
52
  # Configuration parameters: AllowedMethods, AllowedPatterns.
51
53
  Metrics/CyclomaticComplexity:
52
54
  Max: 49
53
55
 
54
- # Offense count: 1
56
+ # Offense count: 2
55
57
  # Configuration parameters: CountComments, CountAsOne.
56
58
  Metrics/ModuleLength:
57
- Max: 284
59
+ Max: 328
58
60
 
59
61
  # Offense count: 10
60
62
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
61
63
  Metrics/ParameterLists:
62
64
  Max: 9
63
65
 
64
- # Offense count: 12
66
+ # Offense count: 15
65
67
  # Configuration parameters: AllowedMethods, AllowedPatterns.
66
68
  Metrics/PerceivedComplexity:
67
69
  Max: 19
@@ -90,7 +92,7 @@ Naming/MethodName:
90
92
  - 'test/mui/key_handler/test_visual_mode.rb'
91
93
  - 'test/mui/key_handler/test_window_command.rb'
92
94
 
93
- # Offense count: 41
95
+ # Offense count: 45
94
96
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
95
97
  # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
96
98
  Naming/MethodParameterName:
@@ -108,17 +110,20 @@ Naming/MethodParameterName:
108
110
  - 'test/e2e/test_helper.rb'
109
111
  - 'test/test_helper.rb'
110
112
 
111
- # Offense count: 6
113
+ # Offense count: 11
112
114
  # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
113
115
  # AllowedMethods: call
114
116
  # WaywardPredicates: nonzero?
115
117
  Naming/PredicateMethod:
116
118
  Exclude:
119
+ - 'lib/mui/command_line.rb'
120
+ - 'lib/mui/editor.rb'
117
121
  - 'lib/mui/key_handler/insert_mode.rb'
122
+ - 'lib/mui/key_sequence_buffer.rb'
118
123
  - 'lib/mui/undo_manager.rb'
119
124
  - 'lib/mui/window_manager.rb'
120
125
 
121
- # Offense count: 1
126
+ # Offense count: 4
122
127
  # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
123
128
  # NamePrefix: is_, has_, have_, does_
124
129
  # ForbiddenPrefixes: is_, has_, have_, does_
@@ -128,6 +133,9 @@ Naming/PredicatePrefix:
128
133
  Exclude:
129
134
  - 'spec/**/*'
130
135
  - 'lib/mui/search_state.rb'
136
+ - 'lib/mui/terminal_adapter/base.rb'
137
+ - 'lib/mui/terminal_adapter/curses.rb'
138
+ - 'test/test_helper.rb'
131
139
 
132
140
  # Offense count: 2
133
141
  # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,167 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] 2025-12-19
4
+
5
+ ### Added
6
+ - `<S-Tab>` (Shift+Tab) notation support in keymap configuration:
7
+ - Added `s-tab` and `btab` to `SPECIAL_KEYS` mapping to `:shift_tab` symbol
8
+ - `normalize_input_key()` now handles `KEY_BTAB` (353) from Curses
9
+ - Enables tab navigation keymaps like:
10
+ ```ruby
11
+ Mui.keymap :normal, "<Tab>", ->(ctx) { ctx.editor.tab_manager.next_tab }
12
+ Mui.keymap :normal, "<S-Tab>", ->(ctx) { ctx.editor.tab_manager.prev_tab }
13
+ ```
14
+ - Function definition name highlighting for 6 languages:
15
+ - Ruby: `def hello` highlights `hello` (lookbehind pattern `(?<=def )`)
16
+ - Go: `func main()` highlights `main` (lookbehind pattern `(?<=func )`)
17
+ - Rust: `fn calculate()` highlights `calculate` (lookbehind pattern `(?<=fn )`)
18
+ - JavaScript: `function add()` highlights `add` (post-process after `function` keyword)
19
+ - TypeScript: `function fetchData()` highlights `fetchData` (post-process after `function` keyword)
20
+ - C: `int main()` highlights `main` (lookahead pattern for identifier before `(`)
21
+ - New token type `:function_definition` mapped to `syntax_function_definition` color scheme element
22
+ - All 8 themes updated with `syntax_function_definition` style (same color as `syntax_method_call`)
23
+ - Improved mui default theme with 256-color palette:
24
+ - Eye-friendly gray-based color scheme using 256-color palette
25
+ - 19 new `mui_*` colors in `EXTENDED_COLOR_MAP` (mui_bg, mui_fg, mui_comment, etc.)
26
+ - Syntax highlighting follows Vim standard highlight groups (Comment, Constant, Identifier, Statement, PreProc, Type, Special)
27
+ - 8-color fallbacks for all mui colors
28
+ - Improved all bundled themes to match their original color schemes:
29
+ - Solarized Dark/Light: Adjusted visual selection, operators, and diff colors
30
+ - Monokai: Fixed comment color to olive gray (#75715e), added `monokai_comment` color
31
+ - Nord: Adjusted status line and constant colors to match Nord palette
32
+ - Gruvbox: Adjusted identifier and keyword colors
33
+ - Dracula: Adjusted visual selection and symbol colors
34
+ - Tokyo Night: Adjusted operator and constant colors
35
+ - Added LSP diagnostics and floating window styles to all themes:
36
+ - `diagnostic_error`, `diagnostic_warning`, `diagnostic_info`, `diagnostic_hint`
37
+ - `floating_window`
38
+ - 256-color support stabilization:
39
+ - Environment capability detection (`Curses.has_colors?`, `Curses.colors`, `Curses.color_pairs`)
40
+ - Automatic 8-color fallback for terminals without 256-color support
41
+ - `FALLBACK_MAP` to map extended colors to nearest basic 8-color equivalents
42
+ - LRU cache for color pairs to prevent pair exhaustion
43
+ - Automatic eviction of oldest pairs when limit is reached
44
+ - Backward compatible: `ColorManager.new` without adapter assumes 256 colors
45
+ - `ColorManager#supports_256_colors` to check color capability
46
+ - `TerminalAdapter::Base#has_colors?`, `#colors`, `#color_pairs` interface methods
47
+
48
+ ### Fixed
49
+ - Fixed text corruption after closing floating window or completion popup:
50
+ - Japanese/CJK multibyte characters were not displaying correctly after popup closed
51
+ - Added `touchwin` method to force complete screen redraw using `Curses.stdscr.redraw`
52
+ - `FloatingWindow` now tracks `last_bounds` and `needs_clear` flag
53
+ - `InsertCompletionState` now tracks `needs_clear` flag
54
+ - Editor calls `touchwin` when popup is closed to restore corrupted characters
55
+
56
+ ### Changed
57
+ - Improved search performance for large files:
58
+ - Added row-based index (`row_index`) to search match cache for O(1) lookup
59
+ - `matches_for_row()` now uses hash lookup instead of linear search
60
+ - Before: O(M × visible_rows) per frame, After: O(visible_rows) per frame
61
+ - Improved navigation performance for large files (G, gg commands):
62
+ - Added smart scroll jump for cursor movements over 100 rows
63
+ - Directly calculates scroll position instead of iterating line by line
64
+ - Before: O(n) where n = cursor distance, After: O(1)
65
+
66
+ ## [0.3.0] - 2025-12-15
67
+
68
+ ### Added
69
+ - Additional syntax highlighting for 7 languages:
70
+ - Go: keywords, types, constants, raw strings (backtick), block comments
71
+ - Rust: macros (`println!`), lifetimes (`'a`), attributes (`#[derive]`), doc comments (`///`), raw strings (`r#"..."#`)
72
+ - JavaScript: template literals, regex literals, BigInt (`123n`), ES6+ keywords (`const`, `let`, `async`, `await`)
73
+ - TypeScript: extends JavaScript with type keywords (`interface`, `type`, `enum`, `declare`, `abstract`)
74
+ - Markdown: headings, emphasis (`*italic*`, `**bold**`), code blocks, links, lists, blockquotes
75
+ - HTML: tags, attributes, comments (`<!-- -->`), DOCTYPE, entities (`&amp;`)
76
+ - CSS: selectors (`.class`, `#id`, `:pseudo`), properties, hex colors, @rules, functions (`calc`, `rgb`, `var`)
77
+ - Supported extensions: `.go`, `.rs`, `.js`/`.mjs`/`.cjs`/`.jsx`, `.ts`/`.tsx`/`.mts`/`.cts`, `.md`/`.markdown`, `.html`/`.htm`/`.xhtml`, `.css`/`.scss`/`.sass`
78
+ - Multi-key sequence and leader key support (Vim-compatible):
79
+ - Leader key: `Mui.set :leader, "\\"` (default: backslash)
80
+ - `<Leader>` notation: `Mui.keymap :normal, "<Leader>gd" do ... end`
81
+ - Multi-key sequences: `<Leader>ff`, `<C-x><C-s>`, etc.
82
+ - Special key notation: `<Space>`, `<Tab>`, `<CR>`, `<Enter>`, `<Esc>`, `<BS>`
83
+ - Control key notation: `<C-x>`, `<Ctrl-x>`, `<C-S-x>` (Ctrl+Shift)
84
+ - Shift key notation: `<S-x>`, `<Shift-x>`
85
+ - Timeout setting: `Mui.set :timeoutlen, 1000` (milliseconds)
86
+ - All modes supported: Normal, Insert, Visual, Command, Search
87
+ - Built-in commands (dd, dw, gg, etc.) take priority over plugin keymaps
88
+ - Partial match waiting: typing `<Leader>g` waits for more keys if `<Leader>gd` is registered
89
+ - Exact match with longer possibilities: waits for timeout before executing
90
+ - Backward compatible with single-key keymaps
91
+ - External shell command execution (`:!cmd`):
92
+ - `:!echo hello` to run shell commands asynchronously
93
+ - Output displayed in `[Shell Output]` scratch buffer (readonly)
94
+ - stdout/stderr/exit status formatted and displayed
95
+ - "Running: cmd" message shown during execution
96
+ - Subsequent `:!cmd` updates existing scratch buffer (doesn't create new windows)
97
+ - Supports pipes, redirects, and all shell features via Open3
98
+ - Empty command (`:!` or `:! `) shows error: "E471: Argument required"
99
+ - Case-insensitive command completion:
100
+ - `:git` now matches `:Git`, `:lsp` matches `:LspHover`, `:LspDefinition`, etc.
101
+ - Original command case is preserved in completion results
102
+ - Only applies to command completion (file path completion remains case-sensitive)
103
+ - Command history with persistence:
104
+ - Up/Down arrow keys navigate through command history in command mode
105
+ - History saved to `~/.mui_history` (persists across sessions)
106
+ - Maximum 100 entries stored
107
+ - Duplicate commands move to most recent position
108
+ - Empty commands are not added to history
109
+ - Current input is preserved when browsing history (restored with Down at end)
110
+
111
+ ### Fixed
112
+ - Fixed long lines not displaying correctly by implementing line wrapping
113
+ - Lines exceeding screen width are now automatically wrapped to next screen line
114
+ - Unicode width aware wrapping (Japanese characters count as 2 width)
115
+ - Removed broken horizontal scrolling (`scroll_col`) in favor of wrap mode
116
+ - Cursor position correctly calculated across wrapped lines
117
+ - Selection and search highlights work correctly across wrap boundaries
118
+ - Added `WrapCache` for performance optimization (content-based caching)
119
+ - Added `WrapHelper` module for wrap calculations
120
+ - Fixed search returning "Pattern not found" after switching buffers via `:e`
121
+ - `execute_search` was using `@buffer` (initial buffer) instead of `buffer` method (current buffer)
122
+ - Now correctly searches in the current buffer after buffer switch
123
+ - Search highlight now recalculates correctly when switching buffers via `:e`
124
+ - Previously, search highlight from old buffer remained visible in new buffer
125
+ - Now calls `find_all_matches` on buffer switch to recalculate matches (Vim-compatible behavior)
126
+ - Search pattern is preserved, only match positions are updated for new buffer content
127
+ - Search highlight now recalculates correctly when opening files via `:sp`, `:vs`, `:tabnew`
128
+ - Previously, search highlight was not calculated for new buffers opened with split/tab commands
129
+ - Now calls `find_all_matches` when path is specified, consistent with `:e` behavior
130
+ - Improved Escape key response time in Insert mode
131
+ - Set `ESCDELAY = 10` to reduce escape sequence detection delay from 1000ms to 10ms
132
+ - Use `timeout = 0` instead of `nodelay` for `getch_nonblock`
133
+ - Insert mode completion now closes when pressing Left/Right arrow keys
134
+ - Previously, arrow keys would move cursor but completion popup remained open
135
+ - Now matches Vim behavior: completion closes on cursor movement
136
+ - Undo/Redo now works correctly for buffers opened via `:e`, `:sp`, `:vs`, `:tabnew`
137
+ - Previously, buffers opened with these commands had no UndoManager set
138
+ - Each buffer now gets its own UndoManager (Vim-compatible: independent undo history per buffer)
139
+ - Handlers now use dynamic `undo_manager` reference to support buffer switching
140
+ - Fixed screen remnants after `:e` command when new file has fewer lines
141
+ - Previously, lines from the old buffer would remain visible below the new content
142
+ - Now explicitly clears lines beyond buffer content during render
143
+ - Fixed background color not applied to lines beyond buffer content
144
+ - Previously, when opening a file with fewer lines than the visible height, lines beyond buffer were rendered without background color (transparent)
145
+ - Now uses `put_with_style` with `:normal` color scheme to ensure consistent background color
146
+ - Plugin commands now appear in command completion suggestions
147
+ - Previously, commands registered via `Mui.command` were not shown in Tab completion
148
+ - `CommandCompleter` now includes plugin commands from `Mui.config.commands`
149
+ - Multi-line paste now undos as a single action (Vim-compatible)
150
+ - Previously, pasting multiple lines would undo one line at a time
151
+ - Now uses `begin_group`/`end_group` to group all paste operations into a single undo unit
152
+ - Fixed direct array assignment to use `replace_line` for proper undo recording
153
+ - Search highlight now works correctly per buffer when switching tabs/windows
154
+ - Previously, search matches from old buffer remained when using `gt`/`gT` or `Ctrl+W` commands
155
+ - `SearchState` now caches matches per buffer (keyed by `object_id`) with lazy evaluation
156
+ - Each buffer maintains its own match positions while sharing the global search pattern
157
+ - Cache automatically invalidates when pattern changes or buffer content is modified
158
+ - Vim-compatible behavior: search pattern is global, highlights are buffer-specific
159
+ - Plugin commands now recognized by CommandRegistry for alias configuration
160
+ - Previously, `CommandRegistry#exists?` and `#find` only checked built-in commands
161
+ - Now also checks `Mui.config.commands` for plugin-registered commands
162
+ - Enables setting command aliases for plugin commands without errors
163
+ - Built-in commands take precedence over plugin commands with the same name
164
+
3
165
  ## [0.2.0] - 2025-12-12
4
166
 
5
167
  ### Added
data/README.md CHANGED
@@ -17,13 +17,316 @@ gem install mui
17
17
  mui [file]
18
18
  ```
19
19
 
20
- ## Features (Planned)
20
+ ## Features
21
21
 
22
- - Vim-like modal editing (Normal, Insert, Visual, Command modes)
23
- - Plugin system via gems
24
- - LSP support (via `mui-lsp` gem)
25
- - Git integration (via `mui-git` gem)
26
- - Configurable via `.muirc`
22
+ ### Modal Editing
23
+
24
+ Vim-like modal editing with five modes:
25
+
26
+ - **Normal mode**: Navigation and text manipulation
27
+ - **Insert mode**: Text input with auto-completion
28
+ - **Command mode**: Ex commands (`:w`, `:q`, `:e`, etc.)
29
+ - **Visual mode** (`v`): Character-wise selection
30
+ - **Visual Line mode** (`V`): Line-wise selection
31
+
32
+ ### Tab Pages and Window Splits
33
+
34
+ - **Tab pages**: `:tabnew`, `:tabclose`, `gt`/`gT` to switch
35
+ - **Horizontal split**: `:sp [file]`
36
+ - **Vertical split**: `:vs [file]`
37
+ - **Window navigation**: `Ctrl-w h/j/k/l` or `Ctrl-w w`
38
+
39
+ ### Syntax Highlighting
40
+
41
+ Supports 9 languages:
42
+
43
+ - Ruby (`.rb`, `.rake`, `.gemspec`)
44
+ - C (`.c`, `.h`, `.y`)
45
+ - Go (`.go`)
46
+ - Rust (`.rs`)
47
+ - JavaScript (`.js`, `.mjs`, `.cjs`, `.jsx`)
48
+ - TypeScript (`.ts`, `.tsx`, `.mts`, `.cts`)
49
+ - Markdown (`.md`, `.markdown`)
50
+ - HTML (`.html`, `.htm`, `.xhtml`)
51
+ - CSS (`.css`, `.scss`, `.sass`)
52
+
53
+ ### Search
54
+
55
+ - Forward search: `/pattern`
56
+ - Backward search: `?pattern`
57
+ - Next/previous match: `n`/`N`
58
+ - Word under cursor: `*` (forward), `#` (backward)
59
+ - Incremental search with real-time highlighting
60
+
61
+ ### Undo/Redo
62
+
63
+ - Undo: `u`
64
+ - Redo: `Ctrl-r`
65
+ - Insert mode changes grouped as single undo unit
66
+
67
+ ### Named Registers
68
+
69
+ - Named registers: `"a` - `"z`
70
+ - Unnamed register: `""`
71
+ - Yank register: `"0`
72
+ - Delete history: `"1` - `"9`
73
+ - Black hole register: `"_`
74
+
75
+ ### Completion
76
+
77
+ - Command-line completion with popup
78
+ - Buffer word completion in Insert mode (`Ctrl-n`/`Ctrl-p`)
79
+ - LSP completion support (via [mui-lsp](https://github.com/S-H-GAMELINKS/mui-lsp) gem)
80
+
81
+ ### Multi-key Sequences and Leader Key
82
+
83
+ ```ruby
84
+ # Set leader key (default: backslash)
85
+ Mui.set :leader, " " # Space as leader
86
+
87
+ # Define multi-key mappings
88
+ Mui.keymap :normal, "<Leader>ff" do |ctx|
89
+ # Find file
90
+ end
91
+ ```
92
+
93
+ Supports:
94
+ - `<Leader>` notation
95
+ - Control keys: `<C-x>`, `<C-S-x>`
96
+ - Special keys: `<Space>`, `<Tab>`, `<CR>`, `<Esc>`, `<BS>`
97
+
98
+ ### Other Features
99
+
100
+ - Japanese and multibyte character support (UTF-8)
101
+ - Floating windows for hover info
102
+ - Asynchronous job execution
103
+ - External shell command execution (`:!cmd`)
104
+ - Command history with persistence
105
+
106
+ ## Key Bindings
107
+
108
+ ### Normal Mode
109
+
110
+ | Key | Action |
111
+ |-----|--------|
112
+ | `h`, `j`, `k`, `l` | Cursor movement |
113
+ | `w`, `b`, `e` | Word movement |
114
+ | `0`, `^`, `$` | Line movement |
115
+ | `gg`, `G` | File start/end |
116
+ | `f{char}`, `t{char}` | Find character |
117
+ | `i`, `a`, `o`, `O` | Enter Insert mode |
118
+ | `v`, `V` | Enter Visual mode |
119
+ | `d`, `c`, `y` | Delete/Change/Yank operators |
120
+ | `p`, `P` | Paste after/before |
121
+ | `u`, `Ctrl-r` | Undo/Redo |
122
+ | `/`, `?` | Search forward/backward |
123
+ | `n`, `N` | Next/previous match |
124
+ | `*`, `#` | Search word under cursor |
125
+ | `gt`, `gT` | Next/previous tab |
126
+ | `gv` | Reselect last visual selection |
127
+ | `Ctrl-w` + `h/j/k/l` | Window navigation |
128
+
129
+ ### Visual Mode
130
+
131
+ | Key | Action |
132
+ |-----|--------|
133
+ | `d` | Delete selection |
134
+ | `c` | Change selection |
135
+ | `y` | Yank selection |
136
+ | `>`, `<` | Indent/unindent |
137
+ | `Esc` | Exit to Normal mode |
138
+
139
+ ### Command Mode
140
+
141
+ | Command | Action |
142
+ |---------|--------|
143
+ | `:w` | Save file |
144
+ | `:q` | Quit |
145
+ | `:wq` | Save and quit |
146
+ | `:e <file>` | Open file |
147
+ | `:sp [file]` | Horizontal split |
148
+ | `:vs [file]` | Vertical split |
149
+ | `:tabnew [file]` | New tab |
150
+ | `:!cmd` | Run shell command |
151
+
152
+ ## Configuration
153
+
154
+ Mui can be configured via `~/.muirc` (global) or `.lmuirc` (project-local).
155
+
156
+ ```ruby
157
+ # ~/.muirc
158
+
159
+ # Color scheme
160
+ Mui.set :colorscheme, "tokyo_night"
161
+
162
+ # Editor settings
163
+ Mui.set :tabstop, 4
164
+ Mui.set :shiftwidth, 4
165
+ Mui.set :expandtab, true
166
+ Mui.set :syntax, true
167
+
168
+ # Leader key
169
+ Mui.set :leader, " "
170
+
171
+ # Custom keymaps
172
+ Mui.keymap :normal, "<Leader>w" do |ctx|
173
+ ctx.editor.execute_command("w")
174
+ end
175
+
176
+ # Custom commands
177
+ Mui.command :hello do |ctx|
178
+ ctx.set_message("Hello, World!")
179
+ end
180
+
181
+ # Autocmd
182
+ Mui.autocmd :BufWritePre, pattern: "*.rb" do |ctx|
183
+ # Before saving Ruby files
184
+ end
185
+ ```
186
+
187
+ ### Available Themes
188
+
189
+ - `mui` (default)
190
+ - `solarized_dark`
191
+ - `solarized_light`
192
+ - `monokai`
193
+ - `nord`
194
+ - `gruvbox_dark`
195
+ - `dracula`
196
+ - `tokyo_night`
197
+
198
+ ## Plugin System
199
+
200
+ Mui supports plugins via Ruby gems.
201
+
202
+ ### Official Plugins
203
+
204
+ - [mui-lsp](https://github.com/S-H-GAMELINKS/mui-lsp) - LSP (Language Server Protocol) support
205
+ - [mui-git](https://github.com/S-H-GAMELINKS/mui-git) - Git integration
206
+ - [mui-fzf](https://github.com/S-H-GAMELINKS/mui-fzf) - Fuzzy finder integration with fzf
207
+
208
+ ### Using Plugins
209
+
210
+ ```ruby
211
+ # ~/.muirc
212
+ Mui.use "mui-lsp"
213
+ Mui.use "mui-git"
214
+ Mui.use "mui-fzf"
215
+ ```
216
+
217
+ ### Creating Plugins
218
+
219
+ ```ruby
220
+ # Class-based plugin
221
+ class MyPlugin < Mui::Plugin
222
+ name :my_plugin
223
+
224
+ def setup
225
+ command :greet do |ctx|
226
+ ctx.set_message("Hello from MyPlugin!")
227
+ end
228
+
229
+ keymap :normal, "<Leader>g" do |ctx|
230
+ ctx.editor.execute_command("greet")
231
+ end
232
+
233
+ autocmd :BufEnter, pattern: "*.txt" do |ctx|
234
+ ctx.set_message("Opened a text file")
235
+ end
236
+ end
237
+ end
238
+ ```
239
+
240
+ ### Asynchronous Job Execution
241
+
242
+ Plugins can run background tasks without blocking the editor:
243
+
244
+ ```ruby
245
+ class MyAsyncPlugin < Mui::Plugin
246
+ name :my_async_plugin
247
+
248
+ def setup
249
+ # Run a shell command asynchronously
250
+ command :run_tests do |ctx|
251
+ ctx.run_shell_command("bundle exec rake test") do |result|
252
+ if result[:success]
253
+ ctx.open_scratch_buffer("[Test Results]", result[:stdout])
254
+ else
255
+ ctx.set_error("Tests failed: #{result[:stderr]}")
256
+ end
257
+ end
258
+ end
259
+
260
+ # Run a Ruby block asynchronously
261
+ command :fetch_data do |ctx|
262
+ ctx.run_async do
263
+ # This runs in a background thread
264
+ sleep 2 # Simulate long operation
265
+ "Data fetched!"
266
+ end
267
+ end
268
+
269
+ # Check if jobs are running
270
+ command :job_status do |ctx|
271
+ if ctx.jobs_running?
272
+ ctx.set_message("Jobs are running...")
273
+ else
274
+ ctx.set_message("No jobs running")
275
+ end
276
+ end
277
+ end
278
+ end
279
+ ```
280
+
281
+ Available job methods:
282
+ - `ctx.run_async { ... }` - Run a Ruby block in background
283
+ - `ctx.run_shell_command(cmd) { |result| ... }` - Run shell command asynchronously
284
+ - `ctx.jobs_running?` - Check if any jobs are active
285
+ - `ctx.cancel_job(id)` - Cancel a running job
286
+ - `ctx.open_scratch_buffer(name, content)` - Display results in a scratch buffer
287
+
288
+ Autocmd events for jobs:
289
+ - `JobStarted` - When a job begins
290
+ - `JobCompleted` - When a job finishes successfully
291
+ - `JobFailed` - When a job fails
292
+ - `JobCancelled` - When a job is cancelled
293
+
294
+ ### Interactive Command Execution
295
+
296
+ Plugins can run interactive external commands:
297
+
298
+ ```ruby
299
+ class FzfPlugin < Mui::Plugin
300
+ name :fzf
301
+
302
+ def setup
303
+ command :Files do |ctx|
304
+ if ctx.command_exists?("fzf")
305
+ result = ctx.run_interactive_command("fzf")
306
+ ctx.editor.execute_command("e #{result}") if result && !result.empty?
307
+ else
308
+ ctx.set_error("fzf is not installed")
309
+ end
310
+ end
311
+ end
312
+ end
313
+ ```
314
+
315
+ ### LSP Configuration
316
+
317
+ ```ruby
318
+ # ~/.muirc
319
+ Mui.use "mui-lsp"
320
+
321
+ Mui.lsp do
322
+ use :ruby # Use preset configuration
323
+
324
+ # Or custom server
325
+ server :custom_lsp,
326
+ command: ["my-lsp", "--stdio"],
327
+ filetypes: ["mylang"]
328
+ end
329
+ ```
27
330
 
28
331
  ## Development
29
332
 
data/docs/_config.yml ADDED
@@ -0,0 +1,56 @@
1
+ title: Mui(無為) Documentation
2
+ description: A Vim-like TUI text editor written in Ruby
3
+ baseurl: "/mui"
4
+ url: "https://s-h-gamelinks.github.io"
5
+
6
+ remote_theme: just-the-docs/just-the-docs
7
+
8
+ color_scheme: dark
9
+
10
+ permalink: pretty
11
+
12
+ aux_links:
13
+ GitHub: https://github.com/S-H-GAMELINKS/mui
14
+ RubyGems: https://rubygems.org/gems/mui
15
+
16
+ nav_external_links:
17
+ - title: GitHub
18
+ url: https://github.com/S-H-GAMELINKS/mui
19
+
20
+ search_enabled: true
21
+ search:
22
+ heading_level: 2
23
+ previews: 3
24
+ preview_words_before: 5
25
+ preview_words_after: 10
26
+ tokenizer_separator: /[\s/]+/
27
+ rel_url: true
28
+ button: false
29
+
30
+ heading_anchors: true
31
+
32
+ back_to_top: true
33
+ back_to_top_text: "Back to top"
34
+
35
+ footer_content: "Copyright &copy; 2025 S-H-GAMELINKS. Distributed under the <a href=\"https://opensource.org/licenses/MIT\">MIT License</a>."
36
+
37
+ last_edit_timestamp: true
38
+ last_edit_time_format: "%Y-%m-%d"
39
+
40
+ gh_edit_link: true
41
+ gh_edit_link_text: "Edit this page on GitHub"
42
+ gh_edit_repository: "https://github.com/S-H-GAMELINKS/mui"
43
+ gh_edit_branch: "master"
44
+ gh_edit_source: docs
45
+ gh_edit_view_mode: "edit"
46
+
47
+ callouts:
48
+ warning:
49
+ title: Warning
50
+ color: yellow
51
+ note:
52
+ title: Note
53
+ color: blue
54
+ tip:
55
+ title: Tip
56
+ color: green