* Usage Example The following code shows how you can write a package using *Names*. The important items are already listed in the Readme: 1. List =names= as a dependency. 2. Wrap all code that’s to be namespaced inside a =(define-namespace NAME ...)= macro. #+BEGIN_SRC emacs-lisp ;;; example.el --- Just an example ;;; You have to add this requirement!! ;; Package-Requires: ((names "0.5") (emacs "24")) ;;; Code: ;; `define-namespace' is autoloaded, so there's no need to require ;; `names'. However, requiring it here means it will also work for ;; people who don't install through package.el. (eval-when-compile (require 'names)) ;;;###autoload (define-namespace example- (defvar has-courage nil) (defmacro with-courage (name &rest body) "Evaluate BODY, don't evaluate NAME." (declare (debug (sexp body-form)) (indent defun)) ;; `example-has-courage' is inside a quoted form, so it needs to be ;; written explicitly. `(let ((example-has-courage ',name)) ,@body)) ;;; this is how you autoload: :autoload (defun fight (evil) "Fight EVIL!" (with-courage evil (-fight-internal))) (defun -fight-internal () "Called by `example-fight'" (when has-courage ;; `has-courage' here is will be expanded to `example-has-courage'. (let ((has-courage nil)) (message "Victory!")))) ) (provide 'example) ;;; example.el ends here #+END_SRC ** Expands to this To see this expansion yourself. 1. Replace the =define-namespace= above with a =names-print= (a macro designed to help developers like you). 2. Make sure you load the /“names-dev.el”/ file included here. 3. evaluate the whole thing. #+BEGIN_SRC emacs-lisp (defvar example-has-courage nil) (defmacro example-with-courage (name &rest body) "Evaluate BODY, don't evaluate NAME." (declare (debug (sexp body)) (indent defun)) `(let ((example-has-courage ',name)) ,@body)) ;;;###autoload (defun example-fight (evil) "Fight EVIL!" (example-with-courage evil (example--fight-internal))) (defun example--fight-internal nil "Called by `example-fight'" (when example-has-courage (let ((has-courage nil)) (message "Victory!")))) #+END_SRC * Usage Instructions Follow these steps: 1. Remember to list =names= as a dependency. 2. Wrap all code that's to be namespaced inside a =(define-namespace NAME ...)= macro. 3. Pleasantly remove all that redundant repetition from you code! 4. When quoting function names, use =#' = instead of = ' =. 5. If you have =;;;###autoload= comments inside your =define-namespace=: 1. Replace them with =:autoload= keywords 2. Add an =;;;###autoload= tag immediately above your =define-namespace=. *What you need to know:* There are essentially three rules that are applied when namespacing. *** 1. Every definition gets namespaced Any definitions inside =BODY= will have =NAME= prepended to the symbol given: #+begin_src emacs-lisp ;;;###autoload (define-namespace foo- (defvar bar 1 "docs") :autoload (defun free () "DOC" (message "hi")) ) #+end_src expands to #+begin_src emacs-lisp (defvar foo-bar 1 "docs") ;;;###autoload (defun foo-free () "DOC" (message "hi")) #+end_src *** 2. Functions and variables are namespaced if defined Any function calls (or variable names) get NAME prepended to them if the symbol in question is defined as a function (or a variable, respectively) inside the current =define-namespace= form. It doesn't matter if the function/variable is called before actually being defined, *Names* will find it. In other words, a function call or variable name is /“looked up locally”/. If it is not found, it is assumed /“global”/. You can force a symbol to be global, by preppending it with =::=. That is: #+begin_src emacs-lisp (define-namespace foo- (defvar var infinite) (defun infinite (x) (infinite x)) (cond ((::infinite 2) (message "Global function call")) ((something-else t) (message "Global function call")) ((infinite var) (message "Local function call.")) (infinite (message "Variable."))) ) #+end_src expands to #+begin_src emacs-lisp (defvar foo-myvar infinite) (defun foo-infinite (x) (foo-infinite x)) (cond ((infinite 2) (message "Global function call")) ((something-else t) (message "Global function call")) ((foo-infinite foo-var) (message "That was a function call.")) (infinite (message "That was a variable."))) #+end_src Note how: - The =infinite= symbol gets namespaced only as a function name (/not/ when it's used as a variable), because =define-namespace= knowns that =foo-infinite= is not a variable. - The symbol inside =(infinite 2)= is not namespaced, because it had been protected with =::=. - =something-else= is not namespaced, because it is not a locally defined function, so it must be global. *** 3. Forms not meant for evaluation are not namespaced. Whenever a form is not meant for evaluation, it is left completely untouched. Some examples where this applies are: - Lists and symbols quoted with a simple quote (e.g. = 'foo=), these are regarded as data, not code; - Any argument of a macro which doesn't get evaluated, e.g, the =KEYLIST= arguments of =cl-case=. Some examples of the opposite: - Symbols quoted with a function quote (e.g. =#'foo=) are regarded as function names, and are namespaced as explained in [[#2-functions-and-variables-are-namespaced-if-defined][item 2]]. That's why we recommend you always use function quotes for functions. - Comma forms inside a backtick form (e.g. =`(nothing ,@(function) ,variable)=) *are* meant for evaluation and so *will* be namespaced. *** Limitations The main effect of [[#3-forms-not-meant-for-evaluation-are-not-namespaced][item 3]] is that the usual way of writing =defalias= and =defvaralias= won't be namespaced. That is #+begin_src emacs-lisp (define-namespace test- (defalias 'yell #'message) ) ;; simply expands to this (defalias 'yell #'message) ;; instead of this (defalias 'test-yell #'message) #+end_src This is not considered a bug. The =SYMBOL= argument of a defalias could just as well be an arbitrary form whose value isn't even defined until runtime. Therefore, there is no consistent way of handling a defalias, and we choose to just treat it as any other function call. Just remember to add the namespace in your defalias and defvaralias forms. *** Case-by-case Examples In general, =define-namespace= should work as you expect it to. But if you need to understand why something is or isn't being namespaced, have a look at [[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/TheNittyGritty.org][TheNittyGritty.org]] * Keywords - Customizing the behaviour Immediately after the name of your space you may add keywords which customize the behaviour of =define-namespace=. See the variable =names--keyword-list= for a description of each possible keyword, or visit [[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/TheNittyGritty.org][TheNittyGritty.org]] for a description with examples.