2 The following code shows how you can write a package using *Names*.
3 The important items are already listed in the Readme:
5 1. List =names= as a dependency.
6 2. Wrap all code that’s to be namespaced inside a =(define-namespace NAME ...)= macro.
10 ;;; example.el --- Just an example
12 ;;; You have to add this requirement!!
13 ;; Package-Requires: ((names "0.5") (emacs "24"))
17 ;; `define-namespace' is autoloaded, so there's no need to require `names'.
20 (define-namespace example-
22 (defvar has-courage nil)
24 (defmacro with-courage (name &rest body)
25 "Evaluate BODY, don't evaluate NAME."
26 (declare (debug (sexp body-form))
28 ;; `example-has-courage' is inside a quoted form, so it needs to be
29 ;; written explicitly.
30 `(let ((example-has-courage ',name))
33 ;;; this is how you autoload:
40 (defun -fight-internal ()
41 "Called by `example-fight'"
43 ;; `has-courage' here is will be expanded to `example-has-courage'.
44 (let ((has-courage nil))
45 (message "Victory!"))))
49 ;;; example.el ends here
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.
59 #+BEGIN_SRC emacs-lisp
60 (defvar example-has-courage nil)
62 (defmacro example-with-courage (name &rest body)
63 "Evaluate BODY, don't evaluate NAME."
64 (declare (debug (sexp body))
66 `(let ((example-has-courage ',name))
70 (defun example-fight (evil)
72 (example-with-courage evil
73 (example--fight-internal)))
75 (defun example--fight-internal nil
76 "Called by `example-fight'"
77 (when example-has-courage
78 (let ((has-courage nil))
79 (message "Victory!"))))
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=.
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
99 #+begin_src emacs-lisp
101 (define-namespace foo-
103 (defvar bar 1 "docs")
112 #+begin_src emacs-lisp
113 (defvar foo-bar 1 "docs")
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.
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 =::=.
133 #+begin_src emacs-lisp
134 (define-namespace foo-
136 (defvar var infinite)
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.")))
149 #+begin_src emacs-lisp
150 (defvar foo-myvar infinite)
152 (defun foo-infinite (x)
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.")))
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.
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=.
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.
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)
192 ;; simply expands to this
193 (defalias 'yell #'message)
195 (defalias 'test-yell #'message)
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.
203 Just remember to add the namespace in your defalias and defvaralias forms.
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]]
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.