mui 0.1.0 → 0.3.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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +163 -0
  3. data/CHANGELOG.md +448 -0
  4. data/README.md +309 -6
  5. data/docs/_config.yml +56 -0
  6. data/docs/configuration.md +301 -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 +149 -0
  13. data/exe/mui +1 -2
  14. data/lib/mui/autocmd.rb +66 -0
  15. data/lib/mui/buffer.rb +275 -0
  16. data/lib/mui/buffer_word_cache.rb +131 -0
  17. data/lib/mui/buffer_word_completer.rb +77 -0
  18. data/lib/mui/color_manager.rb +136 -0
  19. data/lib/mui/color_scheme.rb +63 -0
  20. data/lib/mui/command_completer.rb +30 -0
  21. data/lib/mui/command_context.rb +90 -0
  22. data/lib/mui/command_history.rb +89 -0
  23. data/lib/mui/command_line.rb +167 -0
  24. data/lib/mui/command_registry.rb +44 -0
  25. data/lib/mui/completion_renderer.rb +84 -0
  26. data/lib/mui/completion_state.rb +58 -0
  27. data/lib/mui/config.rb +58 -0
  28. data/lib/mui/editor.rb +395 -0
  29. data/lib/mui/error.rb +29 -0
  30. data/lib/mui/file_completer.rb +51 -0
  31. data/lib/mui/floating_window.rb +161 -0
  32. data/lib/mui/handler_result.rb +107 -0
  33. data/lib/mui/highlight.rb +22 -0
  34. data/lib/mui/highlighters/base.rb +23 -0
  35. data/lib/mui/highlighters/search_highlighter.rb +27 -0
  36. data/lib/mui/highlighters/selection_highlighter.rb +48 -0
  37. data/lib/mui/highlighters/syntax_highlighter.rb +107 -0
  38. data/lib/mui/input.rb +17 -0
  39. data/lib/mui/insert_completion_renderer.rb +92 -0
  40. data/lib/mui/insert_completion_state.rb +77 -0
  41. data/lib/mui/job.rb +81 -0
  42. data/lib/mui/job_manager.rb +113 -0
  43. data/lib/mui/key_code.rb +30 -0
  44. data/lib/mui/key_handler/base.rb +187 -0
  45. data/lib/mui/key_handler/command_mode.rb +511 -0
  46. data/lib/mui/key_handler/insert_mode.rb +323 -0
  47. data/lib/mui/key_handler/motions/motion_handler.rb +56 -0
  48. data/lib/mui/key_handler/normal_mode.rb +552 -0
  49. data/lib/mui/key_handler/operators/base_operator.rb +134 -0
  50. data/lib/mui/key_handler/operators/change_operator.rb +179 -0
  51. data/lib/mui/key_handler/operators/delete_operator.rb +176 -0
  52. data/lib/mui/key_handler/operators/paste_operator.rb +119 -0
  53. data/lib/mui/key_handler/operators/yank_operator.rb +127 -0
  54. data/lib/mui/key_handler/search_mode.rb +191 -0
  55. data/lib/mui/key_handler/visual_line_mode.rb +20 -0
  56. data/lib/mui/key_handler/visual_mode.rb +402 -0
  57. data/lib/mui/key_handler/window_command.rb +112 -0
  58. data/lib/mui/key_handler.rb +16 -0
  59. data/lib/mui/key_notation_parser.rb +152 -0
  60. data/lib/mui/key_sequence.rb +67 -0
  61. data/lib/mui/key_sequence_buffer.rb +85 -0
  62. data/lib/mui/key_sequence_handler.rb +163 -0
  63. data/lib/mui/key_sequence_matcher.rb +79 -0
  64. data/lib/mui/layout/calculator.rb +15 -0
  65. data/lib/mui/layout/leaf_node.rb +33 -0
  66. data/lib/mui/layout/node.rb +29 -0
  67. data/lib/mui/layout/split_node.rb +132 -0
  68. data/lib/mui/line_renderer.rb +173 -0
  69. data/lib/mui/mode.rb +13 -0
  70. data/lib/mui/mode_manager.rb +186 -0
  71. data/lib/mui/motion.rb +139 -0
  72. data/lib/mui/plugin.rb +35 -0
  73. data/lib/mui/plugin_manager.rb +106 -0
  74. data/lib/mui/register.rb +110 -0
  75. data/lib/mui/screen.rb +103 -0
  76. data/lib/mui/search_completer.rb +50 -0
  77. data/lib/mui/search_input.rb +40 -0
  78. data/lib/mui/search_state.rb +121 -0
  79. data/lib/mui/selection.rb +55 -0
  80. data/lib/mui/status_line_renderer.rb +40 -0
  81. data/lib/mui/syntax/language_detector.rb +106 -0
  82. data/lib/mui/syntax/lexer_base.rb +106 -0
  83. data/lib/mui/syntax/lexers/c_lexer.rb +127 -0
  84. data/lib/mui/syntax/lexers/css_lexer.rb +121 -0
  85. data/lib/mui/syntax/lexers/go_lexer.rb +205 -0
  86. data/lib/mui/syntax/lexers/html_lexer.rb +118 -0
  87. data/lib/mui/syntax/lexers/javascript_lexer.rb +197 -0
  88. data/lib/mui/syntax/lexers/markdown_lexer.rb +210 -0
  89. data/lib/mui/syntax/lexers/ruby_lexer.rb +114 -0
  90. data/lib/mui/syntax/lexers/rust_lexer.rb +148 -0
  91. data/lib/mui/syntax/lexers/typescript_lexer.rb +203 -0
  92. data/lib/mui/syntax/token.rb +42 -0
  93. data/lib/mui/syntax/token_cache.rb +91 -0
  94. data/lib/mui/tab_bar_renderer.rb +87 -0
  95. data/lib/mui/tab_manager.rb +96 -0
  96. data/lib/mui/tab_page.rb +35 -0
  97. data/lib/mui/terminal_adapter/base.rb +92 -0
  98. data/lib/mui/terminal_adapter/curses.rb +164 -0
  99. data/lib/mui/terminal_adapter.rb +4 -0
  100. data/lib/mui/themes/default.rb +315 -0
  101. data/lib/mui/undo_manager.rb +83 -0
  102. data/lib/mui/undoable_action.rb +175 -0
  103. data/lib/mui/unicode_width.rb +100 -0
  104. data/lib/mui/version.rb +1 -1
  105. data/lib/mui/window.rb +201 -0
  106. data/lib/mui/window_manager.rb +256 -0
  107. data/lib/mui/wrap_cache.rb +40 -0
  108. data/lib/mui/wrap_helper.rb +84 -0
  109. data/lib/mui.rb +171 -2
  110. metadata +123 -5
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
@@ -0,0 +1,301 @@
1
+ ---
2
+ title: Configuration
3
+ layout: default
4
+ nav_order: 4
5
+ ---
6
+
7
+ # Configuration
8
+ {: .no_toc }
9
+
10
+ ## Table of contents
11
+ {: .no_toc .text-delta }
12
+
13
+ 1. TOC
14
+ {:toc}
15
+
16
+ ---
17
+
18
+ ## Configuration Files
19
+
20
+ Mui supports two configuration files:
21
+
22
+ | File | Scope |
23
+ |------|-------|
24
+ | `~/.muirc` | Global settings (all projects) |
25
+ | `.lmuirc` | Local settings (current directory) |
26
+
27
+ Local settings (`.lmuirc`) override global settings (`~/.muirc`).
28
+
29
+ Configuration files are written in Ruby using Mui's DSL.
30
+
31
+ ## Basic Settings
32
+
33
+ ### Color Scheme
34
+
35
+ ```ruby
36
+ Mui.set :colorscheme, "tokyo_night"
37
+ ```
38
+
39
+ Available themes:
40
+ - `mui` (default)
41
+ - `solarized_dark`
42
+ - `solarized_light`
43
+ - `monokai`
44
+ - `nord`
45
+ - `gruvbox_dark`
46
+ - `dracula`
47
+ - `tokyo_night`
48
+
49
+ ### Indentation
50
+
51
+ ```ruby
52
+ # Number of spaces for Tab display
53
+ Mui.set :tabstop, 4
54
+
55
+ # Number of spaces for indent operations (>, <)
56
+ Mui.set :shiftwidth, 4
57
+
58
+ # Use spaces instead of tabs
59
+ Mui.set :expandtab, true
60
+ ```
61
+
62
+ ### Syntax Highlighting
63
+
64
+ ```ruby
65
+ # Enable/disable syntax highlighting
66
+ Mui.set :syntax, true
67
+ ```
68
+
69
+ ### Leader Key
70
+
71
+ ```ruby
72
+ # Set leader key (default: backslash)
73
+ Mui.set :leader, " " # Space as leader
74
+ ```
75
+
76
+ ### Key Timeout
77
+
78
+ ```ruby
79
+ # Timeout for multi-key sequences (milliseconds)
80
+ Mui.set :timeoutlen, 1000
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Custom Key Mappings
86
+
87
+ Define custom key bindings with `Mui.keymap`:
88
+
89
+ ```ruby
90
+ Mui.keymap :mode, "key" do |ctx|
91
+ # action
92
+ end
93
+ ```
94
+
95
+ ### Modes
96
+
97
+ - `:normal` - Normal mode
98
+ - `:insert` - Insert mode
99
+ - `:visual` - Visual mode
100
+ - `:command` - Command mode
101
+
102
+ ### Examples
103
+
104
+ ```ruby
105
+ # Save with <Leader>w
106
+ Mui.keymap :normal, "<Leader>w" do |ctx|
107
+ ctx.editor.execute_command("w")
108
+ end
109
+
110
+ # Quick escape in Insert mode
111
+ Mui.keymap :insert, "jk" do |ctx|
112
+ ctx.change_mode(:normal)
113
+ end
114
+
115
+ # Close buffer with <Leader>q
116
+ Mui.keymap :normal, "<Leader>q" do |ctx|
117
+ ctx.editor.execute_command("q")
118
+ end
119
+ ```
120
+
121
+ ### Special Key Notation
122
+
123
+ | Notation | Key |
124
+ |----------|-----|
125
+ | `<Leader>` | Leader key |
126
+ | `<Space>` | Space bar |
127
+ | `<Tab>` | Tab key |
128
+ | `<CR>`, `<Enter>` | Enter key |
129
+ | `<Esc>` | Escape key |
130
+ | `<BS>` | Backspace |
131
+ | `<C-x>` | Ctrl+x |
132
+ | `<C-S-x>` | Ctrl+Shift+x |
133
+ | `<S-x>` | Shift+x |
134
+
135
+ ### Multi-key Sequences
136
+
137
+ ```ruby
138
+ # <Leader>ff for find files
139
+ Mui.keymap :normal, "<Leader>ff" do |ctx|
140
+ ctx.editor.execute_command("Files")
141
+ end
142
+
143
+ # <Leader>fg for grep
144
+ Mui.keymap :normal, "<Leader>fg" do |ctx|
145
+ ctx.editor.execute_command("Rg")
146
+ end
147
+
148
+ # Ctrl-x Ctrl-s to save (Emacs style)
149
+ Mui.keymap :normal, "<C-x><C-s>" do |ctx|
150
+ ctx.editor.execute_command("w")
151
+ end
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Custom Commands
157
+
158
+ Define custom Ex commands with `Mui.command`:
159
+
160
+ ```ruby
161
+ Mui.command :name do |ctx|
162
+ # action
163
+ end
164
+ ```
165
+
166
+ ### Examples
167
+
168
+ ```ruby
169
+ # Simple greeting
170
+ Mui.command :hello do |ctx|
171
+ ctx.set_message("Hello, World!")
172
+ end
173
+
174
+ # Command with arguments
175
+ Mui.command :echo do |ctx, *args|
176
+ ctx.set_message(args.join(" "))
177
+ end
178
+
179
+ # Open configuration file
180
+ Mui.command :config do |ctx|
181
+ ctx.editor.execute_command("e ~/.muirc")
182
+ end
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Autocmd Events
188
+
189
+ Execute code when events occur with `Mui.autocmd`:
190
+
191
+ ```ruby
192
+ Mui.autocmd :event, pattern: "*.ext" do |ctx|
193
+ # action
194
+ end
195
+ ```
196
+
197
+ ### Available Events
198
+
199
+ | Event | Trigger |
200
+ |-------|---------|
201
+ | `BufEnter` | When entering a buffer |
202
+ | `BufLeave` | When leaving a buffer |
203
+ | `BufWrite` | When writing a buffer |
204
+ | `BufWritePre` | Before writing a buffer |
205
+ | `BufWritePost` | After writing a buffer |
206
+ | `ModeChanged` | When mode changes |
207
+ | `CursorMoved` | When cursor moves |
208
+ | `TextChanged` | When text is modified |
209
+ | `InsertEnter` | When entering Insert mode |
210
+ | `InsertLeave` | When leaving Insert mode |
211
+ | `InsertCompletion` | When completion is triggered |
212
+ | `JobStarted` | When a job starts |
213
+ | `JobCompleted` | When a job completes |
214
+ | `JobFailed` | When a job fails |
215
+ | `JobCancelled` | When a job is cancelled |
216
+
217
+ ### Examples
218
+
219
+ ```ruby
220
+ # Auto-save on leaving Insert mode
221
+ Mui.autocmd :InsertLeave do |ctx|
222
+ ctx.editor.execute_command("w") if ctx.buffer.modified?
223
+ end
224
+
225
+ # Show message when opening Ruby files
226
+ Mui.autocmd :BufEnter, pattern: "*.rb" do |ctx|
227
+ ctx.set_message("Ruby file loaded")
228
+ end
229
+
230
+ # Format before saving
231
+ Mui.autocmd :BufWritePre, pattern: "*.rb" do |ctx|
232
+ # Run formatter
233
+ end
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Using Plugins
239
+
240
+ Load plugins with `Mui.use`:
241
+
242
+ ```ruby
243
+ Mui.use "mui-lsp"
244
+ Mui.use "mui-git"
245
+ Mui.use "mui-fzf"
246
+ ```
247
+
248
+ See [Plugins]({{ site.baseurl }}/plugins) for more details.
249
+
250
+ ---
251
+
252
+ ## Complete Example
253
+
254
+ ```ruby
255
+ # ~/.muirc
256
+
257
+ # Appearance
258
+ Mui.set :colorscheme, "tokyo_night"
259
+ Mui.set :syntax, true
260
+
261
+ # Indentation
262
+ Mui.set :tabstop, 2
263
+ Mui.set :shiftwidth, 2
264
+ Mui.set :expandtab, true
265
+
266
+ # Leader key
267
+ Mui.set :leader, " "
268
+
269
+ # Plugins
270
+ Mui.use "mui-lsp"
271
+ Mui.use "mui-fzf"
272
+
273
+ # Key mappings
274
+ Mui.keymap :normal, "<Leader>w" do |ctx|
275
+ ctx.editor.execute_command("w")
276
+ end
277
+
278
+ Mui.keymap :normal, "<Leader>q" do |ctx|
279
+ ctx.editor.execute_command("q")
280
+ end
281
+
282
+ Mui.keymap :normal, "<Leader>ff" do |ctx|
283
+ ctx.editor.execute_command("Files")
284
+ end
285
+
286
+ # Custom commands
287
+ Mui.command :reload do |ctx|
288
+ ctx.editor.execute_command("e")
289
+ ctx.set_message("File reloaded")
290
+ end
291
+
292
+ # LSP configuration
293
+ Mui.lsp do
294
+ use :ruby
295
+
296
+ # TypeScript (requires typescript-language-server)
297
+ server :typescript,
298
+ command: ["typescript-language-server", "--stdio"],
299
+ filetypes: ["typescript", "typescriptreact", "javascript", "javascriptreact"]
300
+ end
301
+ ```