Skip to content

Commit 8d88a08

Browse files
committed
Document module conventions and best practices
Add a "Writing a Module" section to the modules index with a template and a list of conventions (hook pattern, subword-mode, LSP, tree-sitter, etc.). Also update the Ruby example to reflect the current code.
1 parent da4f2e8 commit 8d88a08

1 file changed

Lines changed: 81 additions & 16 deletions

File tree

docs/modules/index.md

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,104 @@ packages and provide some sensible baseline configuration for them.
1313
Here's a real example.
1414

1515
``` emacs-lisp
16-
;;; prelude-ruby.el --- Emacs Prelude: A nice setup for Ruby (and Rails) devs.
17-
;;
16+
;;; prelude-ruby.el --- Emacs Prelude: A nice setup for Ruby devs.
1817
;;; Code:
1918
2019
(require 'prelude-programming)
2120
2221
(prelude-require-packages '(inf-ruby yari))
2322
24-
;; We never want to edit Rubinius bytecode
25-
(add-to-list 'completion-ignored-extensions ".rbc")
23+
;; Use ruby-ts-mode when the tree-sitter grammar is available
24+
(when (treesit-ready-p 'ruby t)
25+
(add-to-list 'major-mode-remap-alist
26+
'(ruby-mode . ruby-ts-mode)))
2627
2728
;; Map yari to C-h R
2829
(define-key 'help-command (kbd "R") 'yari)
2930
30-
(with-eval-after-load 'ruby-mode
31-
(defun prelude-ruby-mode-defaults ()
32-
;; Don't auto-insert encoding comments
33-
;; Those are almost never needed in Ruby 2+
34-
(setq ruby-insert-encoding-magic-comment nil)
35-
(inf-ruby-minor-mode +1)
36-
;; CamelCase aware editing operations
37-
(subword-mode +1))
31+
(defun prelude-ruby-mode-defaults ()
32+
(setq ruby-insert-encoding-magic-comment nil)
33+
(inf-ruby-minor-mode +1)
34+
(subword-mode +1)
35+
(prelude-lsp-enable))
3836
39-
(setq prelude-ruby-mode-hook 'prelude-ruby-mode-defaults)
37+
(setq prelude-ruby-mode-hook 'prelude-ruby-mode-defaults)
4038
41-
(add-hook 'ruby-mode-hook (lambda ()
42-
(run-hooks 'prelude-ruby-mode-hook))))
39+
(add-hook 'ruby-mode-hook (lambda ()
40+
(run-hooks 'prelude-ruby-mode-hook)))
41+
(add-hook 'ruby-ts-mode-hook (lambda ()
42+
(run-hooks 'prelude-ruby-mode-hook)))
4343
4444
(provide 'prelude-ruby)
4545
;;; prelude-ruby.el ends here
4646
```
4747

48-
To use a module you simply have to require it. No new concepts. No magic.
48+
To use a module you simply have to require it. No new
49+
concepts. No magic.
50+
51+
## Writing a Module
52+
53+
When writing or modifying a module, follow these conventions
54+
for consistency:
55+
56+
### Structure
57+
58+
A typical programming language module follows this pattern:
59+
60+
``` emacs-lisp
61+
;;; prelude-example.el --- Emacs Prelude: Example config.
62+
;;; Code:
63+
64+
(require 'prelude-programming)
65+
66+
(prelude-require-packages '(example-mode))
67+
68+
;; Use tree-sitter mode when grammar is available
69+
(when (treesit-ready-p 'example t)
70+
(add-to-list 'major-mode-remap-alist
71+
'(example-mode . example-ts-mode)))
72+
73+
(defun prelude-example-mode-defaults ()
74+
(subword-mode +1)
75+
(prelude-lsp-enable))
76+
77+
(setq prelude-example-mode-hook
78+
'prelude-example-mode-defaults)
79+
80+
(add-hook 'example-mode-hook
81+
(lambda ()
82+
(run-hooks 'prelude-example-mode-hook)))
83+
(add-hook 'example-ts-mode-hook
84+
(lambda ()
85+
(run-hooks 'prelude-example-mode-hook)))
86+
87+
(provide 'prelude-example)
88+
;;; prelude-example.el ends here
89+
```
90+
91+
### Conventions
92+
93+
- **Require `prelude-programming`** as the foundation for
94+
all programming language modules. Lisp-family modules
95+
should require `prelude-lisp` instead.
96+
- **Define a `prelude-*-mode-defaults` function** with the
97+
mode-specific setup. This makes it easy for users to
98+
override.
99+
- **Use the `prelude-*-mode-hook` variable pattern** (setq +
100+
add-hook with lambda). This lets users replace the
101+
defaults function entirely via their personal config.
102+
- **Enable `subword-mode`** for CamelCase-aware editing.
103+
- **Call `prelude-lsp-enable`** for LSP support. This
104+
respects the user's `prelude-lsp-client` setting
105+
(Eglot or lsp-mode).
106+
- **Add tree-sitter support** using `treesit-ready-p` with
107+
the `t` argument (silent, no error if grammar missing)
108+
and `major-mode-remap-alist`. Always add hooks for both
109+
the legacy mode and the tree-sitter mode.
110+
- **Use `with-eval-after-load`** to defer configuration
111+
until the relevant package is loaded.
112+
- **Install packages with `prelude-require-packages`**,
113+
not `use-package` or manual `package-install` calls.
49114

50115
## Foundation Modules
51116

0 commit comments

Comments
 (0)