]> code.delx.au - gnu-emacs-elpa/blob - packages/names/UsageExample.org
Update packages/yasnippet by merging from its external upstream subtree
[gnu-emacs-elpa] / packages / names / UsageExample.org
1 * Usage Example
2 The following code shows how you can write a package using *Names*.
3 The important items are already listed in the Readme:
4
5 1. List =names= as a dependency.
6 2. Wrap all code that’s to be namespaced inside a =(define-namespace NAME ...)= macro.
7
8
9 #+BEGIN_SRC emacs-lisp
10 ;;; example.el --- Just an example
11
12 ;;; You have to add this requirement!!
13 ;; Package-Requires: ((names "0.5") (emacs "24"))
14
15 ;;; Code:
16
17 ;; `define-namespace' is autoloaded, so there's no need to require `names'.
18
19 ;;;###autoload
20 (define-namespace example-
21
22 (defvar has-courage nil)
23
24 (defmacro with-courage (name &rest body)
25 "Evaluate BODY, don't evaluate NAME."
26 (declare (debug (sexp body-form))
27 (indent defun))
28 ;; `example-has-courage' is inside a quoted form, so it needs to be
29 ;; written explicitly.
30 `(let ((example-has-courage ',name))
31 ,@body))
32
33 ;;; this is how you autoload:
34 :autoload
35 (defun fight (evil)
36 "Fight EVIL!"
37 (with-courage evil
38 (-fight-internal)))
39
40 (defun -fight-internal ()
41 "Called by `example-fight'"
42 (when has-courage
43 ;; `has-courage' here is will be expanded to `example-has-courage'.
44 (let ((has-courage nil))
45 (message "Victory!"))))
46 )
47
48 (provide 'example)
49 ;;; example.el ends here
50
51 #+END_SRC
52
53 ** Expands to this
54 To see this expansion yourself.
55 1. Replace the =define-namespace= above with a =names-print= (a macro designed to help developers like you).
56 2. Make sure you load the /“names-dev.el”/ file included here.
57 3. evaluate the whole thing.
58
59 #+BEGIN_SRC emacs-lisp
60 (defvar example-has-courage nil)
61
62 (defmacro example-with-courage (name &rest body)
63 "Evaluate BODY, don't evaluate NAME."
64 (declare (debug (sexp body))
65 (indent defun))
66 `(let ((example-has-courage ',name))
67 ,@body))
68
69 ;;;###autoload
70 (defun example-fight (evil)
71 "Fight EVIL!"
72 (example-with-courage evil
73 (example--fight-internal)))
74
75 (defun example--fight-internal nil
76 "Called by `example-fight'"
77 (when example-has-courage
78 (let ((has-courage nil))
79 (message "Victory!"))))
80 #+END_SRC
81
82 * Usage Instructions
83
84 Follow these steps:
85
86 1. Remember to list =names= as a dependency.
87 2. Wrap all code that's to be namespaced inside a =(define-namespace NAME ...)= macro.
88 3. Pleasantly remove all that redundant repetition from you code!
89 4. When quoting function names, use =#' = instead of = ' =.
90 5. If you have =;;;###autoload= comments inside your =define-namespace=:
91 1. Replace them with =:autoload= keywords
92 2. Add an =;;;###autoload= tag immediately above your =define-namespace=.
93
94 *What you need to know:* There are essentially three rules that are
95 applied when namespacing.
96 *** 1. Every definition gets namespaced
97 Any definitions inside =BODY= will have =NAME= prepended to the
98 symbol given:
99 #+begin_src emacs-lisp
100 ;;;###autoload
101 (define-namespace foo-
102
103 (defvar bar 1 "docs")
104
105 :autoload
106 (defun free ()
107 "DOC"
108 (message "hi"))
109 )
110 #+end_src
111 expands to
112 #+begin_src emacs-lisp
113 (defvar foo-bar 1 "docs")
114
115 ;;;###autoload
116 (defun foo-free ()
117 "DOC"
118 (message "hi"))
119 #+end_src
120
121 *** 2. Functions and variables are namespaced if defined
122 Any function calls (or variable names) get NAME prepended to them if
123 the symbol in question is defined as a function (or a variable,
124 respectively) inside the current =define-namespace= form. It doesn't
125 matter if the function/variable is called before actually being
126 defined, *Names* will find it.
127
128 In other words, a function call or variable name is /“looked up
129 locally”/. If it is not found, it is assumed /“global”/. You can force
130 a symbol to be global, by preppending it with =::=.
131
132 That is:
133 #+begin_src emacs-lisp
134 (define-namespace foo-
135
136 (defvar var infinite)
137
138 (defun infinite (x)
139 (infinite x))
140
141 (cond
142 ((::infinite 2) (message "Global function call"))
143 ((something-else t) (message "Global function call"))
144 ((infinite var) (message "Local function call."))
145 (infinite (message "Variable.")))
146 )
147 #+end_src
148 expands to
149 #+begin_src emacs-lisp
150 (defvar foo-myvar infinite)
151
152 (defun foo-infinite (x)
153 (foo-infinite x))
154
155 (cond
156 ((infinite 2) (message "Global function call"))
157 ((something-else t) (message "Global function call"))
158 ((foo-infinite foo-var) (message "That was a function call."))
159 (infinite (message "That was a variable.")))
160 #+end_src
161
162 Note how:
163 - The =infinite= symbol gets namespaced only as a function name (/not/
164 when it's used as a variable), because =define-namespace= knowns
165 that =foo-infinite= is not a variable.
166 - The symbol inside =(infinite 2)= is not namespaced, because it had
167 been protected with =::=.
168 - =something-else= is not namespaced, because it is not a locally
169 defined function, so it must be global.
170
171 *** 3. Forms not meant for evaluation are not namespaced.
172 Whenever a form is not meant for evaluation, it is left completely
173 untouched. Some examples where this applies are:
174 - Lists and symbols quoted with a simple quote (e.g. = 'foo=), these are regarded as data, not code;
175 - Any argument of a macro which doesn't get evaluated, e.g, the =KEYLIST= arguments of =cl-case=.
176
177 Some examples of the opposite:
178 - Symbols quoted with a function quote (e.g. =#'foo=) are regarded as
179 function names, and are namespaced as explained in [[#2-functions-and-variables-are-namespaced-if-defined][item 2]]. That's
180 why we recommend you always use function quotes for functions.
181 - Comma forms inside a backtick form (e.g. =`(nothing ,@(function)
182 ,variable)=) *are* meant for evaluation and so *will* be namespaced.
183
184 *** Limitations
185
186 The main effect of [[#3-forms-not-meant-for-evaluation-are-not-namespaced][item 3]] is that the usual way of writing
187 =defalias= and =defvaralias= won't be namespaced. That is
188 #+begin_src emacs-lisp
189 (define-namespace test-
190 (defalias 'yell #'message)
191 )
192 ;; simply expands to this
193 (defalias 'yell #'message)
194 ;; instead of this
195 (defalias 'test-yell #'message)
196 #+end_src
197
198 This is not considered a bug. The =SYMBOL= argument of a defalias
199 could just as well be an arbitrary form whose value isn't even defined
200 until runtime. Therefore, there is no consistent way of handling a
201 defalias, and we choose to just treat it as any other function call.
202
203 Just remember to add the namespace in your defalias and defvaralias forms.
204
205 *** Case-by-case Examples
206 In general, =define-namespace= should work as you expect it to. But if you
207 need to understand why something is or isn't being namespaced, have a
208 look at [[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/TheNittyGritty.org][TheNittyGritty.org]]
209
210
211
212 * Keywords - Customizing the behaviour
213 Immediately after the name of your space you may add keywords which
214 customize the behaviour of =define-namespace=. See the variable
215 =names--keyword-list= for a description of each possible keyword, or
216 visit [[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/TheNittyGritty.org][TheNittyGritty.org]] for a description with examples.