1 ;; erlang-skels.el --- Erlang code skeletons
3 ;; The contents of this file are subject to the Erlang Public License,
4 ;; Version 1.1, (the "License"); you may not use this file except in
5 ;; compliance with the License. You should have received a copy of the
6 ;; Erlang Public License along with this software. If not, it can be
7 ;; retrieved via the world wide web at http://www.erlang.org/.
9 ;; Software distributed under the License is distributed on an "AS IS"
10 ;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11 ;; the License for the specific language governing rights and limitations
14 ;; The Initial Developer of the Original Code is Ericsson Utvecklings AB.
15 ;; All Rights Reserved.
19 '(("If" "if" erlang-skel-if
)
20 ("Case" "case" erlang-skel-case
)
21 ("Receive" "receive" erlang-skel-receive
)
22 ("Receive After" "after" erlang-skel-receive-after
)
23 ("Receive Loop" "loop" erlang-skel-receive-loop
)
24 ("Module" "module" erlang-skel-module
)
25 ("Author" "author" erlang-skel-author
)
26 ("Function" "function" erlang-skel-function
)
28 ("Small Header" "small-header"
29 erlang-skel-small-header erlang-skel-header
)
30 ("Normal Header" "normal-header"
31 erlang-skel-normal-header erlang-skel-header
)
32 ("Large Header" "large-header"
33 erlang-skel-large-header erlang-skel-header
)
35 ("Small Server" "small-server"
36 erlang-skel-small-server erlang-skel-header
)
38 ("Application" "application"
39 erlang-skel-application erlang-skel-header
)
40 ("Supervisor" "supervisor"
41 erlang-skel-supervisor erlang-skel-header
)
42 ("supervisor_bridge" "supervisor-bridge"
43 erlang-skel-supervisor-bridge erlang-skel-header
)
44 ("gen_server" "generic-server"
45 erlang-skel-generic-server erlang-skel-header
)
46 ("gen_event" "gen-event"
47 erlang-skel-gen-event erlang-skel-header
)
49 erlang-skel-gen-fsm erlang-skel-header
)
50 ("Library module" "gen-lib"
51 erlang-skel-lib erlang-skel-header
)
52 ("Corba callback" "gen-corba-cb"
53 erlang-skel-corba-callback erlang-skel-header
)
54 ("Erlang test suite TS frontend" "ts-test-suite"
55 erlang-skel-ts-test-suite erlang-skel-header
)
56 ("Erlang test suite CT frontend" "ct-test-suite"
57 erlang-skel-ct-test-suite erlang-skel-header
)
59 "*Description of all skeleton templates.
60 Both functions and menu entries will be created.
62 Each entry in `erlang-skel' should be a list with three or four
63 elements, or the empty list.
65 The first element is the name which shows up in the menu. The second
66 is the `tempo' identifier (The string \"erlang-\" will be added in
67 front of it). The third is the skeleton descriptor, a variable
68 containing `tempo' attributes as described in the function
69 `tempo-define-template'. The optional fourth elements denotes a
70 function which should be called when the menu is selected.
72 Functions corresponding to every template will be created. The name
73 of the function will be `tempo-template-erlang-X' where `X' is the
74 tempo identifier as specified in the second argument of the elements
77 A list with zero elements means that the a horizontal line should
78 be placed in the menu.")
80 (defvar erlang-skel-use-separators t
81 "A boolean than determines whether the skeletons include horizontal
84 Should this variable be nil, the documentation for functions will not
85 include separators of the form %%--...")
87 ;; In XEmacs `user-mail-address' returns "x@y.z (Foo Bar)" ARGH!
88 ;; What's wrong with that? RFC 822 says it's legal. [sverkerw]
89 ;; This needs to use the customized value. If that's not sane, things like
90 ;; add-log will lose anyhow. Avoid it if there _is_ a paren.
91 (defvar erlang-skel-mail-address
92 (if (or (not user-mail-address
) (string-match "(" user-mail-address
))
93 (concat (user-login-name) "@"
94 (or (and (boundp 'mail-host-address
)
98 "Mail address of the user.")
100 ;; Expression templates:
101 (defvar erlang-skel-case
102 '((erlang-skel-skip-blank) o
>
103 "case " p
" of" n
> p
"_ ->" n
> p
"ok" n
> "end" p
)
104 "*The skeleton of a `case' expression.
105 Please see the function `tempo-define-template'.")
107 (defvar erlang-skel-if
108 '((erlang-skel-skip-blank) o
>
109 "if" n
> p
" ->" n
> p
"ok" n
> "end" p
)
110 "The skeleton of an `if' expression.
111 Please see the function `tempo-define-template'.")
113 (defvar erlang-skel-receive
114 '((erlang-skel-skip-blank) o
>
115 "receive" n
> p
"_ ->" n
> p
"ok" n
> "end" p
)
116 "*The skeleton of a `receive' expression.
117 Please see the function `tempo-define-template'.")
119 (defvar erlang-skel-receive-after
120 '((erlang-skel-skip-blank) o
>
121 "receive" n
> p
"_ ->" n
> p
"ok" n
> "after " p
"T ->" n
>
123 "*The skeleton of a `receive' expression with an `after' clause.
124 Please see the function `tempo-define-template'.")
126 (defvar erlang-skel-receive-loop
127 '(& o
"loop(" p
") ->" n
> "receive" n
> p
"_ ->" n
>
128 "loop(" p
")" n
> "end.")
129 "*The skeleton of a simple `receive' loop.
130 Please see the function `tempo-define-template'.")
133 (defvar erlang-skel-function
134 '((erlang-skel-separator-start 2)
137 (erlang-skel-separator-end 2))
138 "*The template of a function skeleton.
139 Please see the function `tempo-define-template'.")
142 ;; Attribute templates
144 (defvar erlang-skel-module
146 (erlang-add-quotes-if-needed (erlang-get-module-from-file-name))
148 "*The skeleton of a `module' attribute.
149 Please see the function `tempo-define-template'.")
151 (defvar erlang-skel-author
152 '(& "-author('" erlang-skel-mail-address
"')." n
)
153 "*The skeleton of a `author' attribute.
154 Please see the function `tempo-define-template'.")
156 (defvar erlang-skel-vc nil
157 "*The skeleton template to generate a version control attribute.
158 The default is to insert nothing. Example of usage:
160 (setq erlang-skel-vc '(& \"-rcs(\\\"$\Id: $ \\\").\") n)
162 Please see the function `tempo-define-template'.")
164 (defvar erlang-skel-export
165 '(& "-export([" n
> "])." n
)
166 "*The skeleton of an `export' attribute.
167 Please see the function `tempo-define-template'.")
169 (defvar erlang-skel-import
170 '(& "%%-import(Module, [Function/Arity, ...])." n
)
171 "*The skeleton of an `import' attribute.
172 Please see the function `tempo-define-template'.")
174 (defvar erlang-skel-compile nil
175 ;; '(& "%%-compile(export_all)." n)
176 "*The skeleton of a `compile' attribute.
177 Please see the function `tempo-define-template'.")
180 ;; Comment templates.
182 (defvar erlang-skel-date-function
'erlang-skel-dd-mmm-yyyy
183 "*Function which returns date string.
184 Look in the module `time-stamp' for a battery of functions.")
186 (defvar erlang-skel-copyright-comment
187 (if (boundp '*copyright-organization
*)
188 '(& "%%% @copyright (C) " (format-time-string "%Y") ", "
189 *copyright-organization
* n
)
190 '(& "%%% @copyright (C) " (format-time-string "%Y") ", "
192 "*The template for a copyright line in the header, normally empty.
193 This variable should be bound to a `tempo' template, for example:
194 '(& \"%%% Copyright (C) 2000, Yoyodyne, Inc.\" n)
195 Please see the function `tempo-define-template'.")
197 (defvar erlang-skel-created-comment
198 '(& "%%% Created : " (funcall erlang-skel-date-function
) " by "
199 (user-full-name) " <" erlang-skel-mail-address
">" n
)
200 "*The template for the \"Created:\" comment line.")
202 (defvar erlang-skel-author-comment
203 '(& "%%% @author " (user-full-name) " <" erlang-skel-mail-address
">" n
)
204 "*The template for creating the \"Author:\" line in the header.
205 Please see the function `tempo-define-template'.")
207 (defvar erlang-skel-small-header
208 '(o (erlang-skel-include erlang-skel-module
)
210 (erlang-skel-include erlang-skel-compile erlang-skel-vc
))
211 "*The template of a small header without any comments.
212 Please see the function `tempo-define-template'.")
214 (defvar erlang-skel-normal-header
215 '(o (erlang-skel-include erlang-skel-author-comment
)
216 (erlang-skel-include erlang-skel-copyright-comment
)
220 (erlang-skel-include erlang-skel-created-comment
) n
221 (erlang-skel-include erlang-skel-small-header
) n
)
222 "*The template of a normal header.
223 Please see the function `tempo-define-template'.")
225 (defvar erlang-skel-large-header
226 '(o (erlang-skel-separator)
227 (erlang-skel-include erlang-skel-author-comment
)
228 (erlang-skel-include erlang-skel-copyright-comment
)
232 (erlang-skel-include erlang-skel-created-comment
)
233 (erlang-skel-separator)
234 (erlang-skel-include erlang-skel-small-header
) )
235 "*The template of a large header.
236 Please see the function `tempo-define-template'.")
240 (defvar erlang-skel-small-server
241 '((erlang-skel-include erlang-skel-large-header
)
242 "-export([start/0, init/1])." n n n
243 "start() ->" n
> "spawn(" (erlang-get-module-from-file-name)
244 ", init, [self()])." n n
253 "*Template of a small server.
254 Please see the function `tempo-define-template'.")
256 ;; Behaviour templates.
257 (defvar erlang-skel-application
258 '((erlang-skel-include erlang-skel-large-header
)
259 "-behaviour(application)." n n
260 "%% Application callbacks" n
261 "-export([start/2, stop/1])." n n
262 (erlang-skel-double-separator-start 3)
263 "%%% Application callbacks" n
264 (erlang-skel-double-separator-end 3) n
265 (erlang-skel-separator-start 2)
268 "%% This function is called whenever an application is started using" n
269 "%% application:start/[1,2], and should start the processes of the" n
270 "%% application. If the application is structured according to the OTP" n
271 "%% design principles as a supervision tree, this means starting the" n
272 "%% top supervisor of the tree." n
274 "%% @spec start(StartType, StartArgs) -> {ok, Pid} |" n
275 "%% {ok, Pid, State} |" n
276 "%% {error, Reason}" n
277 "%% StartType = normal | {takeover, Node} | {failover, Node}" n
278 "%% StartArgs = term()" n
279 (erlang-skel-separator-end 2)
280 "start(_StartType, _StartArgs) ->" n
>
281 "case 'TopSupervisor':start_link() of" n
>
288 (erlang-skel-separator-start 2)
291 "%% This function is called whenever an application has stopped. It" n
292 "%% is intended to be the opposite of Module:start/2 and should do" n
293 "%% any necessary cleaning up. The return value is ignored." n
295 "%% @spec stop(State) -> void()" n
296 (erlang-skel-separator-end 2)
300 (erlang-skel-double-separator-start 3)
301 "%%% Internal functions" n
302 (erlang-skel-double-separator-end 3)
304 "*The template of an application behaviour.
305 Please see the function `tempo-define-template'.")
307 (defvar erlang-skel-supervisor
308 '((erlang-skel-include erlang-skel-large-header
)
309 "-behaviour(supervisor)." n n
312 "-export([start_link/0])." n n
314 "%% Supervisor callbacks" n
315 "-export([init/1])." n n
317 "-define(SERVER, ?MODULE)." n n
319 (erlang-skel-double-separator-start 3)
320 "%%% API functions" n
321 (erlang-skel-double-separator-end 3) n
322 (erlang-skel-separator-start 2)
324 "%% Starts the supervisor" n
326 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
327 (erlang-skel-separator-end 2)
329 "supervisor:start_link({local, ?SERVER}, ?MODULE, [])." n
331 (erlang-skel-double-separator-start 3)
332 "%%% Supervisor callbacks" n
333 (erlang-skel-double-separator-end 3) n
334 (erlang-skel-separator-start 2)
337 "%% Whenever a supervisor is started using supervisor:start_link/[2,3]," n
338 "%% this function is called by the new process to find out about" n
339 "%% restart strategy, maximum restart frequency and child" n
340 "%% specifications." n
342 "%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |" n
344 "%% {error, Reason}" n
345 (erlang-skel-separator-end 2)
347 "RestartStrategy = one_for_one," n
>
348 "MaxRestarts = 1000," n
>
349 "MaxSecondsBetweenRestarts = 3600," n
351 "SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}," n
353 "Restart = permanent," n
>
354 "Shutdown = 2000," n
>
357 "AChild = {'AName', {'AModule', start_link, []}," n
>
358 "Restart, Shutdown, Type, ['AModule']}," n
360 "{ok, {SupFlags, [AChild]}}." n
362 (erlang-skel-double-separator-start 3)
363 "%%% Internal functions" n
364 (erlang-skel-double-separator-end 3)
366 "*The template of an supervisor behaviour.
367 Please see the function `tempo-define-template'.")
369 (defvar erlang-skel-supervisor-bridge
370 '((erlang-skel-include erlang-skel-large-header
)
371 "-behaviour(supervisor_bridge)." n n
374 "-export([start_link/0])." n n
376 "%% supervisor_bridge callbacks" n
377 "-export([init/1, terminate/2])." n n
379 "-define(SERVER, ?MODULE)." n n
381 "-record(state, {})." n n
383 (erlang-skel-double-separator-start 3)
385 (erlang-skel-double-separator-end 3) n
386 (erlang-skel-separator-start 2)
388 "%% Starts the supervisor bridge" n
390 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
391 (erlang-skel-separator-end 2)
393 "supervisor_bridge:start_link({local, ?SERVER}, ?MODULE, [])." n
395 (erlang-skel-double-separator-start 3)
396 "%%% supervisor_bridge callbacks" n
397 (erlang-skel-double-separator-end 3) n
398 (erlang-skel-separator-start 2)
401 "%% Creates a supervisor_bridge process, linked to the calling process," n
402 "%% which calls Module:init/1 to start the subsystem. To ensure a" n
403 "%% synchronized start-up procedure, this function does not return" n
404 "%% until Module:init/1 has returned." n
406 "%% @spec init(Args) -> {ok, Pid, State} |" n
408 "%% {error, Reason}" n
409 (erlang-skel-separator-end 2)
411 "case 'AModule':start_link() of" n
>
413 "{ok, Pid, #state{}};" n
>
418 (erlang-skel-separator-start 2)
421 "%% This function is called by the supervisor_bridge when it is about" n
422 "%% to terminate. It should be the opposite of Module:init/1 and stop" n
423 "%% the subsystem and do any necessary cleaning up.The return value is" n
426 "%% @spec terminate(Reason, State) -> void()" n
427 (erlang-skel-separator-end 2)
428 "terminate(Reason, State) ->" n
>
429 "'AModule':stop()," n
>
432 (erlang-skel-double-separator-start 3)
433 "%%% Internal functions" n
434 (erlang-skel-double-separator-end 3)
436 "*The template of an supervisor_bridge behaviour.
437 Please see the function `tempo-define-template'.")
439 (defvar erlang-skel-generic-server
440 '((erlang-skel-include erlang-skel-large-header
)
441 "-behaviour(gen_server)." n n
444 "-export([start_link/0])." n n
446 "%% gen_server callbacks" n
447 "-export([init/1, handle_call/3, handle_cast/2, "
449 "terminate/2, code_change/3])." n n
451 "-define(SERVER, ?MODULE). " n n
453 "-record(state, {})." n n
455 (erlang-skel-double-separator-start 3)
457 (erlang-skel-double-separator-end 3) n
458 (erlang-skel-separator-start 2)
460 "%% Starts the server" n
462 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
463 (erlang-skel-separator-end 2)
465 "gen_server:start_link({local, ?SERVER}, ?MODULE, [], [])." n
467 (erlang-skel-double-separator-start 3)
468 "%%% gen_server callbacks" n
469 (erlang-skel-double-separator-end 3)
471 (erlang-skel-separator-start 2)
474 "%% Initiates the server" n
476 "%% @spec init(Args) -> {ok, State} |" n
477 "%% {ok, State, Timeout} |" n
479 "%% {stop, Reason}" n
480 (erlang-skel-separator-end 2)
484 (erlang-skel-separator-start 2)
487 "%% Handling call messages" n
489 "%% @spec handle_call(Request, From, State) ->" n
490 "%% {reply, Reply, State} |" n
491 "%% {reply, Reply, State, Timeout} |" n
492 "%% {noreply, State} |" n
493 "%% {noreply, State, Timeout} |" n
494 "%% {stop, Reason, Reply, State} |" n
495 "%% {stop, Reason, State}" n
496 (erlang-skel-separator-end 2)
497 "handle_call(_Request, _From, State) ->" n
>
499 "{reply, Reply, State}." n
501 (erlang-skel-separator-start 2)
504 "%% Handling cast messages" n
506 "%% @spec handle_cast(Msg, State) -> {noreply, State} |" n
507 "%% {noreply, State, Timeout} |" n
508 "%% {stop, Reason, State}" n
509 (erlang-skel-separator-end 2)
510 "handle_cast(_Msg, State) ->" n
>
511 "{noreply, State}." n
513 (erlang-skel-separator-start 2)
516 "%% Handling all non call/cast messages" n
518 "%% @spec handle_info(Info, State) -> {noreply, State} |" n
519 "%% {noreply, State, Timeout} |" n
520 "%% {stop, Reason, State}" n
521 (erlang-skel-separator-end 2)
522 "handle_info(_Info, State) ->" n
>
523 "{noreply, State}." n
525 (erlang-skel-separator-start 2)
528 "%% This function is called by a gen_server when it is about to" n
529 "%% terminate. It should be the opposite of Module:init/1 and do any" n
530 "%% necessary cleaning up. When it returns, the gen_server terminates" n
531 "%% with Reason. The return value is ignored." n
533 "%% @spec terminate(Reason, State) -> void()" n
534 (erlang-skel-separator-end 2)
535 "terminate(_Reason, _State) ->" n
>
538 (erlang-skel-separator-start 2)
541 "%% Convert process state when code is changed" n
543 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
544 (erlang-skel-separator-end 2)
545 "code_change(_OldVsn, State, _Extra) ->" n
>
548 (erlang-skel-double-separator-start 3)
549 "%%% Internal functions" n
550 (erlang-skel-double-separator-end 3)
552 "*The template of a generic server.
553 Please see the function `tempo-define-template'.")
555 (defvar erlang-skel-gen-event
556 '((erlang-skel-include erlang-skel-large-header
)
557 "-behaviour(gen_event)." n n
560 "-export([start_link/0, add_handler/0])." n n
562 "%% gen_event callbacks" n
563 "-export([init/1, handle_event/2, handle_call/2, " n
>
564 "handle_info/2, terminate/2, code_change/3])." n n
566 "-define(SERVER, ?MODULE). " n n
568 "-record(state, {})." n n
570 (erlang-skel-double-separator-start 3)
571 "%%% gen_event callbacks" n
572 (erlang-skel-double-separator-end 3) n
573 (erlang-skel-separator-start 2)
575 "%% Creates an event manager" n
577 "%% @spec start_link() -> {ok, Pid} | {error, Error}" n
578 (erlang-skel-separator-end 2)
580 "gen_event:start_link({local, ?SERVER})." n
582 (erlang-skel-separator-start 2)
584 "%% Adds an event handler" n
586 "%% @spec add_handler() -> ok | {'EXIT', Reason} | term()" n
587 (erlang-skel-separator-end 2)
588 "add_handler() ->" n
>
589 "gen_event:add_handler(?SERVER, ?MODULE, [])." n
591 (erlang-skel-double-separator-start 3)
592 "%%% gen_event callbacks" n
593 (erlang-skel-double-separator-end 3) n
594 (erlang-skel-separator-start 2)
597 "%% Whenever a new event handler is added to an event manager," n
598 "%% this function is called to initialize the event handler." n
600 "%% @spec init(Args) -> {ok, State}" n
601 (erlang-skel-separator-end 2)
605 (erlang-skel-separator-start 2)
608 "%% Whenever an event manager receives an event sent using" n
609 "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is" n
610 "%% called for each installed event handler to handle the event." n
612 "%% @spec handle_event(Event, State) ->" n
614 "%% {swap_handler, Args1, State1, Mod2, Args2} |"n
615 "%% remove_handler" n
616 (erlang-skel-separator-end 2)
617 "handle_event(_Event, State) ->" n
>
620 (erlang-skel-separator-start 2)
623 "%% Whenever an event manager receives a request sent using" n
624 "%% gen_event:call/3,4, this function is called for the specified" n
625 "%% event handler to handle the request." n
627 "%% @spec handle_call(Request, State) ->" n
628 "%% {ok, Reply, State} |" n
629 "%% {swap_handler, Reply, Args1, State1, Mod2, Args2} |" n
630 "%% {remove_handler, Reply}" n
631 (erlang-skel-separator-end 2)
632 "handle_call(_Request, State) ->" n
>
634 "{ok, Reply, State}." n
636 (erlang-skel-separator-start 2)
639 "%% This function is called for each installed event handler when" n
640 "%% an event manager receives any other message than an event or a" n
641 "%% synchronous request (or a system message)." n
643 "%% @spec handle_info(Info, State) ->" n
645 "%% {swap_handler, Args1, State1, Mod2, Args2} |" n
646 "%% remove_handler" n
647 (erlang-skel-separator-end 2)
648 "handle_info(_Info, State) ->" n
>
651 (erlang-skel-separator-start 2)
654 "%% Whenever an event handler is deleted from an event manager, this" n
655 "%% function is called. It should be the opposite of Module:init/1 and" n
656 "%% do any necessary cleaning up." n
658 "%% @spec terminate(Reason, State) -> void()" n
659 (erlang-skel-separator-end 2)
660 "terminate(_Reason, _State) ->" n
>
663 (erlang-skel-separator-start 2)
666 "%% Convert process state when code is changed" n
668 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
669 (erlang-skel-separator-end 2)
670 "code_change(_OldVsn, State, _Extra) ->" n
>
673 (erlang-skel-double-separator-start 3)
674 "%%% Internal functions" n
675 (erlang-skel-double-separator-end 3)
677 "*The template of a gen_event.
678 Please see the function `tempo-define-template'.")
680 (defvar erlang-skel-gen-fsm
681 '((erlang-skel-include erlang-skel-large-header
)
682 "-behaviour(gen_fsm)." n n
685 "-export([start_link/0])." n n
687 "%% gen_fsm callbacks" n
688 "-export([init/1, state_name/2, state_name/3, handle_event/3," n
>
689 "handle_sync_event/4, handle_info/3, terminate/3, code_change/4])." n n
691 "-define(SERVER, ?MODULE)." n n
693 "-record(state, {})." n n
695 (erlang-skel-double-separator-start 3)
697 (erlang-skel-double-separator-end 3) n
698 (erlang-skel-separator-start 2)
700 "%% Creates a gen_fsm process which calls Module:init/1 to" n
701 "%% initialize. To ensure a synchronized start-up procedure, this" n
702 "%% function does not return until Module:init/1 has returned." n
704 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
705 (erlang-skel-separator-end 2)
707 "gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], [])." n
709 (erlang-skel-double-separator-start 3)
710 "%%% gen_fsm callbacks" n
711 (erlang-skel-double-separator-end 3) n
712 (erlang-skel-separator-start 2)
715 "%% Whenever a gen_fsm is started using gen_fsm:start/[3,4] or" n
716 "%% gen_fsm:start_link/[3,4], this function is called by the new" n
717 "%% process to initialize." n
719 "%% @spec init(Args) -> {ok, StateName, State} |" n
720 "%% {ok, StateName, State, Timeout} |" n
722 "%% {stop, StopReason}" n
723 (erlang-skel-separator-end 2)
725 "{ok, state_name, #state{}}." n
727 (erlang-skel-separator-start 2)
730 "%% There should be one instance of this function for each possible" n
731 "%% state name. Whenever a gen_fsm receives an event sent using" n
732 "%% gen_fsm:send_event/2, the instance of this function with the same" n
733 "%% name as the current state name StateName is called to handle" n
734 "%% the event. It is also called if a timeout occurs." n
736 "%% @spec state_name(Event, State) ->" n
737 "%% {next_state, NextStateName, NextState} |" n
738 "%% {next_state, NextStateName, NextState, Timeout} |" n
739 "%% {stop, Reason, NewState}" n
740 (erlang-skel-separator-end 2)
741 "state_name(_Event, State) ->" n
>
742 "{next_state, state_name, State}." n
744 (erlang-skel-separator-start 2)
747 "%% There should be one instance of this function for each possible" n
748 "%% state name. Whenever a gen_fsm receives an event sent using" n
749 "%% gen_fsm:sync_send_event/[2,3], the instance of this function with" n
750 "%% the same name as the current state name StateName is called to" n
751 "%% handle the event." n
753 "%% @spec state_name(Event, From, State) ->" n
754 "%% {next_state, NextStateName, NextState} |"n
755 "%% {next_state, NextStateName, NextState, Timeout} |" n
756 "%% {reply, Reply, NextStateName, NextState} |" n
757 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
758 "%% {stop, Reason, NewState} |" n
759 "%% {stop, Reason, Reply, NewState}" n
760 (erlang-skel-separator-end 2)
761 "state_name(_Event, _From, State) ->" n
>
763 "{reply, Reply, state_name, State}." n
765 (erlang-skel-separator-start 2)
768 "%% Whenever a gen_fsm receives an event sent using" n
769 "%% gen_fsm:send_all_state_event/2, this function is called to handle" n
772 "%% @spec handle_event(Event, StateName, State) ->" n
773 "%% {next_state, NextStateName, NextState} |" n
774 "%% {next_state, NextStateName, NextState, Timeout} |" n
775 "%% {stop, Reason, NewState}" n
776 (erlang-skel-separator-end 2)
777 "handle_event(_Event, StateName, State) ->" n
>
778 "{next_state, StateName, State}." n
780 (erlang-skel-separator-start 2)
783 "%% Whenever a gen_fsm receives an event sent using" n
784 "%% gen_fsm:sync_send_all_state_event/[2,3], this function is called" n
785 "%% to handle the event." n
787 "%% @spec handle_sync_event(Event, From, StateName, State) ->" n
788 "%% {next_state, NextStateName, NextState} |" n
789 "%% {next_state, NextStateName, NextState, Timeout} |" n
790 "%% {reply, Reply, NextStateName, NextState} |" n
791 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
792 "%% {stop, Reason, NewState} |" n
793 "%% {stop, Reason, Reply, NewState}" n
794 (erlang-skel-separator-end 2)
795 "handle_sync_event(_Event, _From, StateName, State) ->" n
>
797 "{reply, Reply, StateName, State}." n
799 (erlang-skel-separator-start 2)
802 "%% This function is called by a gen_fsm when it receives any" n
803 "%% message other than a synchronous or asynchronous event" n
804 "%% (or a system message)." n
806 "%% @spec handle_info(Info,StateName,State)->" n
807 "%% {next_state, NextStateName, NextState} |" n
808 "%% {next_state, NextStateName, NextState, Timeout} |" n
809 "%% {stop, Reason, NewState}" n
810 (erlang-skel-separator-end 2)
811 "handle_info(_Info, StateName, State) ->" n
>
812 "{next_state, StateName, State}." n
814 (erlang-skel-separator-start 2)
817 "%% This function is called by a gen_fsm when it is about to" n
818 "%% terminate. It should be the opposite of Module:init/1 and do any" n
819 "%% necessary cleaning up. When it returns, the gen_fsm terminates with" n
820 "%% Reason. The return value is ignored." n
822 "%% @spec terminate(Reason, StateName, State) -> void()" n
823 (erlang-skel-separator-end 2)
824 "terminate(_Reason, _StateName, _State) ->" n
>
827 (erlang-skel-separator-start 2)
830 "%% Convert process state when code is changed" n
832 "%% @spec code_change(OldVsn, StateName, State, Extra) ->" n
833 "%% {ok, StateName, NewState}" n
834 (erlang-skel-separator-end 2)
835 "code_change(_OldVsn, StateName, State, _Extra) ->" n
>
836 "{ok, StateName, State}." n
838 (erlang-skel-double-separator-start 3)
839 "%%% Internal functions" n
840 (erlang-skel-double-separator-end 3)
842 "*The template of a gen_fsm.
843 Please see the function `tempo-define-template'.")
845 (defvar erlang-skel-lib
846 '((erlang-skel-include erlang-skel-large-header
)
851 (erlang-skel-double-separator-start 3)
853 (erlang-skel-double-separator-end 3) n
854 (erlang-skel-separator-start 2)
857 (erlang-skel-separator-end 2)
859 (erlang-skel-double-separator-start 3)
860 "%%% Internal functions" n
861 (erlang-skel-double-separator-end 3)
863 "*The template of a library module.
864 Please see the function `tempo-define-template'.")
866 (defvar erlang-skel-corba-callback
867 '((erlang-skel-include erlang-skel-large-header
)
868 "%% Include files" n n
873 "%% Corba callbacks" n
874 "-export([init/1, terminate/2, code_change/3])." n n
876 "-record(state, {})." n n
878 (erlang-skel-double-separator-start 3)
879 "%%% Corba callbacks" n
880 (erlang-skel-double-separator-end 3) n
881 (erlang-skel-separator-start 2)
884 "%% Initiates the server" n
886 "%% @spec init(Args) -> {ok, State} |" n
887 "%% {ok, State, Timeout} |" n
889 "%% {stop, Reason}" n
890 (erlang-skel-separator-end 2)
894 (erlang-skel-separator-start 2)
897 "%% Shutdown the server" n
899 "%% @spec terminate(Reason, State) -> void()" n
900 (erlang-skel-separator-end 2)
901 "terminate(_Reason, _State) ->" n
>
904 (erlang-skel-separator-start 2)
907 "%% Convert process state when code is changed" n
909 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
910 (erlang-skel-separator-end 2)
911 "code_change(_OldVsn, State, _Extra) ->" n
>
914 (erlang-skel-double-separator-start 3)
915 "%%% Internal functions" n
916 (erlang-skel-double-separator-end 3)
918 "*The template of a library module.
919 Please see the function `tempo-define-template'.")
921 (defvar erlang-skel-ts-test-suite
922 '((erlang-skel-include erlang-skel-large-header
)
923 "%% Note: This directive should only be used in test suites." n
924 "-compile(export_all)." n n
926 "-include(\"test_server.hrl\")." n n
928 "%% Test server callback functions" n
929 (erlang-skel-separator-start 2)
931 "%% Config - [tuple()]" n
932 "%% A list of key/value pairs, holding the test case configuration." n
934 "%% Initiation before the whole suite" n
936 "%% Note: This function is free to add any key/value pairs to the Config" n
937 "%% variable, but should NOT alter/remove any existing entries." n
939 "%% @spec init_per_suite(Config) -> Config" n
940 (erlang-skel-separator-end 2)
941 "init_per_suite(Config) ->" n
>
944 (erlang-skel-separator-start 2)
946 "%% Config - [tuple()]" n
947 "%% A list of key/value pairs, holding the test case configuration." n
949 "%% Cleanup after the whole suite" n
951 "%% @spec end_per_suite(Config) -> _" n
952 (erlang-skel-separator-end 2)
953 "end_per_suite(_Config) ->" n
>
956 (erlang-skel-separator-start 2)
959 "%% Name of the test case that is about to be run." n
960 "%% Config - [tuple()]" n
961 "%% A list of key/value pairs, holding the test case configuration." n
963 "%% Initiation before each test case" n
965 "%% Note: This function is free to add any key/value pairs to the Config" n
966 "%% variable, but should NOT alter/remove any existing entries." n
968 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
969 (erlang-skel-separator-end 2)
970 "init_per_testcase(_TestCase, Config) ->" n
>
973 (erlang-skel-separator-start 2)
976 "%% Name of the test case that is about to be run." n
977 "%% Config - [tuple()]" n
978 "%% A list of key/value pairs, holding the test case configuration." n
980 "%% Cleanup after each test case" n
982 "%% @spec end_per_testcase(TestCase, Config) -> _" n
983 (erlang-skel-separator-end 2)
984 "end_per_testcase(_TestCase, _Config) ->" n
>
987 (erlang-skel-separator-start 2)
989 "%% Clause - atom() - suite | doc" n
990 "%% TestCases - [Case]" n
992 "%% Name of a test case." n
994 "%% Returns a list of all test cases in this test suite" n
996 "%% @spec all(Clause) -> TestCases" n
997 (erlang-skel-separator-end 2)
999 "[\"Describe the main purpose of this suite\"];" n n
1003 "%% Test cases starts here." n
1004 (erlang-skel-separator-start 2)
1005 "test_case(doc) ->" n
>
1006 "[\"Describe the main purpose of test case\"];" n n
1007 "test_case(suite) ->" n
>
1009 "test_case(Config) when is_list(Config) ->" n
>
1012 "*The template of a library module.
1013 Please see the function `tempo-define-template'.")
1015 (defvar erlang-skel-ct-test-suite
1016 '((erlang-skel-include erlang-skel-large-header
)
1017 "-suite_defaults([{timetrap, {minutes, 10}}])." n n
1019 "%% Note: This directive should only be used in test suites." n
1020 "-compile(export_all)." n n
1022 "-include(\"ct.hrl\")." n n
1024 "%% Test server callback functions" n
1025 (erlang-skel-separator-start 2)
1027 "%% Config - [tuple()]" n
1028 "%% A list of key/value pairs, holding the test case configuration." n
1030 "%% Initiation before the whole suite" n
1032 "%% Note: This function is free to add any key/value pairs to the Config" n
1033 "%% variable, but should NOT alter/remove any existing entries." n
1035 "%% @spec init_per_suite(Config) -> Config" n
1036 (erlang-skel-separator-end 2)
1037 "init_per_suite(Config) ->" n
>
1040 (erlang-skel-separator-start 2)
1042 "%% Config - [tuple()]" n
1043 "%% A list of key/value pairs, holding the test case configuration." n
1045 "%% Cleanup after the whole suite" n
1047 "%% @spec end_per_suite(Config) -> _" n
1048 (erlang-skel-separator-end 2)
1049 "end_per_suite(_Config) ->" n
>
1052 (erlang-skel-separator-start 2)
1054 "%% Case - atom()" n
1055 "%% Name of the test case that is about to be run." n
1056 "%% Config - [tuple()]" n
1057 "%% A list of key/value pairs, holding the test case configuration." n
1059 "%% Initiation before each test case" n
1061 "%% Note: This function is free to add any key/value pairs to the Config" n
1062 "%% variable, but should NOT alter/remove any existing entries." n
1063 "%% Initiation before each test case" n
1065 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
1066 (erlang-skel-separator-end 2)
1067 "init_per_testcase(_TestCase, Config) ->" n
>
1070 (erlang-skel-separator-start 2)
1072 "%% Case - atom()" n
1073 "%% Name of the test case that is about to be run." n
1074 "%% Config - [tuple()]" n
1075 "%% A list of key/value pairs, holding the test case configuration." n
1077 "%% Cleanup after each test case" n
1079 "%% @spec end_per_testcase(TestCase, Config) -> _" n
1080 (erlang-skel-separator-end 2)
1081 "end_per_testcase(_TestCase, _Config) ->" n
>
1084 (erlang-skel-separator-start 2)
1086 "%% TestCases - [Case]" n
1087 "%% Case - atom()" n
1088 "%% Name of a test case." n
1090 "%% Returns a list of all test cases in this test suite" n
1092 "%% @spec all() -> TestCases" n
1093 (erlang-skel-separator-end 2)
1097 "%% Test cases starts here." n
1098 (erlang-skel-separator-start 2)
1099 "test_case() ->" n
>
1100 "[{doc, \"Describe the main purpose of this test case\"}]." n n
1101 "test_case(Config) when is_list(Config) ->" n
>
1104 "*The template of a library module.
1105 Please see the function `tempo-define-template'.")
1109 ;; This code is based on the package `tempo' which is part of modern
1110 ;; Emacsen. (GNU Emacs 19.25 (?) and XEmacs 19.14.)
1112 (defun erlang-skel-init ()
1113 "Generate the skeleton functions and menu items.
1114 The variable `erlang-skel' contains the name and descriptions of
1117 The skeleton routines are based on the `tempo' package. Should this
1118 package not be present, this function does nothing."
1123 (if (featurep 'tempo
)
1124 (let ((skel erlang-skel
)
1127 (cond ((null (car skel
))
1128 (setq menu
(cons nil menu
)))
1130 (funcall (symbol-function 'tempo-define-template
)
1131 (concat "erlang-" (nth 1 (car skel
)))
1132 ;; The tempo template used contains an `include'
1133 ;; function call only, hence changes to the
1134 ;; variables describing the templates take effect
1136 (list (list 'erlang-skel-include
(nth 2 (car skel
))))
1138 (setq menu
(cons (erlang-skel-make-menu-item
1139 (car skel
)) menu
))))
1140 (setq skel
(cdr skel
)))
1141 (setq erlang-menu-skel-items
1142 (list nil
(list "Skeletons" (nreverse menu
))))
1143 (setq erlang-menu-items
1144 (erlang-menu-add-above 'erlang-menu-skel-items
1145 'erlang-menu-version-items
1147 (erlang-menu-init))))
1149 (defun erlang-skel-make-menu-item (skel)
1150 (let ((func (intern (concat "tempo-template-erlang-" (nth 1 skel
)))))
1151 (cond ((null (nth 3 skel
))
1152 (list (car skel
) func
))
1158 (list 'quote
(nth 3 skel
))
1159 (list 'quote func
))))))))
1161 ;; Functions designed to be added to the skeleton menu.
1162 ;; (Not normally used)
1163 (defun erlang-skel-insert (func)
1164 "Insert skeleton generated by FUNC and goto first tempo mark."
1165 (save-excursion (funcall func
))
1166 (funcall (symbol-function 'tempo-forward-mark
)))
1168 (defun erlang-skel-header (func)
1169 "Insert the header generated by FUNC at the beginning of the buffer."
1170 (goto-char (point-min))
1171 (save-excursion (funcall func
))
1172 (funcall (symbol-function 'tempo-forward-mark
)))
1175 ;; Functions used inside the skeleton descriptions.
1176 (defun erlang-skel-skip-blank ()
1177 (skip-chars-backward " \t")
1180 (defun erlang-skel-include (&rest args
)
1181 "Include a template inside another template.
1183 Example of use, assuming that `erlang-skel-func' is defined:
1185 (defvar foo-skeleton '(\"%%% New function:\"
1186 (erlang-skel-include erlang-skel-func)))
1188 Technically, this function returns the `tempo' attribute`(l ...)' which
1189 can contain other `tempo' attributes. Please see the function
1190 `tempo-define-template' for a description of the `(l ...)' attribute."
1194 (setq entry
(car args
))
1196 (setq res
(cons (car entry
) res
))
1197 (setq entry
(cdr entry
)))
1198 (setq args
(cdr args
)))
1199 (cons 'l
(nreverse res
))))
1201 (defun erlang-skel-separator (&optional percent
)
1202 "Return a comment separator."
1203 (let ((percent (or percent
3)))
1204 (concat (make-string percent ?%
)
1205 (make-string (- 70 percent
) ?-
)
1208 (defun erlang-skel-separator-start (&optional percent
)
1209 "Return a comment separator or an empty string if separators
1210 are configured off."
1211 (if erlang-skel-use-separators
1212 (erlang-skel-separator percent
)
1215 (defun erlang-skel-separator-end (&optional percent
)
1216 "Return a comment separator to end a function comment block or an
1217 empty string if separators are configured off."
1218 (if erlang-skel-use-separators
1219 (concat "%% @end\n" (erlang-skel-separator percent
))
1222 (defun erlang-skel-double-separator (&optional percent
)
1223 "Return a double line (equals sign) comment separator."
1224 (let ((percent (or percent
3)))
1225 (concat (make-string percent ?%
)
1226 (make-string (- 70 percent
) ?
=)
1229 (defun erlang-skel-double-separator-start (&optional percent
)
1230 "Return a double separator or a newline if separators are configured off."
1231 (if erlang-skel-use-separators
1232 (erlang-skel-double-separator percent
)
1235 (defun erlang-skel-double-separator-end (&optional percent
)
1236 "Return a double separator or an empty string if separators are
1238 (if erlang-skel-use-separators
1239 (erlang-skel-double-separator percent
)
1242 (defun erlang-skel-dd-mmm-yyyy ()
1243 "Return the current date as a string in \"DD Mon YYYY\" form.
1244 The first character of DD is space if the value is less than 10."
1245 (let ((date (current-time-string)))
1247 (string-to-int (substring date
8 10))
1248 (substring date
4 7)
1249 (substring date -
4))))
1252 ;; coding: iso-8859-1
1255 ;;; erlang.el ends here