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 ;; In XEmacs `user-mail-address' returns "x@y.z (Foo Bar)" ARGH!
81 ;; What's wrong with that? RFC 822 says it's legal. [sverkerw]
82 ;; This needs to use the customized value. If that's not sane, things like
83 ;; add-log will lose anyhow. Avoid it if there _is_ a paren.
84 (defvar erlang-skel-mail-address
85 (if (or (not user-mail-address
) (string-match "(" user-mail-address
))
86 (concat (user-login-name) "@"
87 (or (and (boundp 'mail-host-address
)
91 "Mail address of the user.")
93 ;; Expression templates:
94 (defvar erlang-skel-case
95 '((erlang-skel-skip-blank) o
>
96 "case " p
" of" n
> p
"_ ->" n
> p
"ok" n
> "end" p
)
97 "*The skeleton of a `case' expression.
98 Please see the function `tempo-define-template'.")
100 (defvar erlang-skel-if
101 '((erlang-skel-skip-blank) o
>
102 "if" n
> p
" ->" n
> p
"ok" n
> "end" p
)
103 "The skeleton of an `if' expression.
104 Please see the function `tempo-define-template'.")
106 (defvar erlang-skel-receive
107 '((erlang-skel-skip-blank) o
>
108 "receive" n
> p
"_ ->" n
> p
"ok" n
> "end" p
)
109 "*The skeleton of a `receive' expression.
110 Please see the function `tempo-define-template'.")
112 (defvar erlang-skel-receive-after
113 '((erlang-skel-skip-blank) o
>
114 "receive" n
> p
"_ ->" n
> p
"ok" n
> "after " p
"T ->" n
>
116 "*The skeleton of a `receive' expression with an `after' clause.
117 Please see the function `tempo-define-template'.")
119 (defvar erlang-skel-receive-loop
120 '(& o
"loop(" p
") ->" n
> "receive" n
> p
"_ ->" n
>
121 "loop(" p
")" n
> "end.")
122 "*The skeleton of a simple `receive' loop.
123 Please see the function `tempo-define-template'.")
126 (defvar erlang-skel-function
127 '((erlang-skel-separator 2)
131 (erlang-skel-separator 2))
132 "*The template of a function skeleton.
133 Please see the function `tempo-define-template'.")
136 ;; Attribute templates
138 (defvar erlang-skel-module
140 (erlang-add-quotes-if-needed (erlang-get-module-from-file-name))
142 "*The skeleton of a `module' attribute.
143 Please see the function `tempo-define-template'.")
145 (defvar erlang-skel-author
146 '(& "-author('" erlang-skel-mail-address
"')." n
)
147 "*The skeleton of a `author' attribute.
148 Please see the function `tempo-define-template'.")
150 (defvar erlang-skel-vc nil
151 "*The skeleton template to generate a version control attribute.
152 The default is to insert nothing. Example of usage:
154 (setq erlang-skel-vc '(& \"-rcs(\\\"$\Id: $ \\\").\") n)
156 Please see the function `tempo-define-template'.")
158 (defvar erlang-skel-export
159 '(& "-export([" n
> "])." n
)
160 "*The skeleton of an `export' attribute.
161 Please see the function `tempo-define-template'.")
163 (defvar erlang-skel-import
164 '(& "%%-import(Module, [Function/Arity, ...])." n
)
165 "*The skeleton of an `import' attribute.
166 Please see the function `tempo-define-template'.")
168 (defvar erlang-skel-compile nil
169 ;; '(& "%%-compile(export_all)." n)
170 "*The skeleton of a `compile' attribute.
171 Please see the function `tempo-define-template'.")
174 ;; Comment templates.
176 (defvar erlang-skel-date-function
'erlang-skel-dd-mmm-yyyy
177 "*Function which returns date string.
178 Look in the module `time-stamp' for a battery of functions.")
180 (defvar erlang-skel-copyright-comment
181 (if (boundp '*copyright-organization
*)
182 '(& "%%% @copyright (C) " (format-time-string "%Y") ", "
183 *copyright-organization
* n
)
184 '(& "%%% @copyright (C) " (format-time-string "%Y") ", "
186 "*The template for a copyright line in the header, normally empty.
187 This variable should be bound to a `tempo' template, for example:
188 '(& \"%%% Copyright (C) 2000, Yoyodyne, Inc.\" n)
189 Please see the function `tempo-define-template'.")
191 (defvar erlang-skel-created-comment
192 '(& "%%% Created : " (funcall erlang-skel-date-function
) " by "
193 (user-full-name) " <" erlang-skel-mail-address
">" n
)
194 "*The template for the \"Created:\" comment line.")
196 (defvar erlang-skel-author-comment
197 '(& "%%% @author " (user-full-name) " <" erlang-skel-mail-address
">" n
)
198 "*The template for creating the \"Author:\" line in the header.
199 Please see the function `tempo-define-template'.")
201 (defvar erlang-skel-small-header
202 '(o (erlang-skel-include erlang-skel-module
)
204 (erlang-skel-include erlang-skel-compile erlang-skel-vc
))
205 "*The template of a small header without any comments.
206 Please see the function `tempo-define-template'.")
208 (defvar erlang-skel-normal-header
209 '(o (erlang-skel-include erlang-skel-author-comment
)
210 (erlang-skel-include erlang-skel-copyright-comment
)
214 (erlang-skel-include erlang-skel-created-comment
) n
215 (erlang-skel-include erlang-skel-small-header
) n
)
216 "*The template of a normal header.
217 Please see the function `tempo-define-template'.")
219 (defvar erlang-skel-large-header
220 '(o (erlang-skel-separator)
221 (erlang-skel-include erlang-skel-author-comment
)
222 (erlang-skel-include erlang-skel-copyright-comment
)
226 (erlang-skel-include erlang-skel-created-comment
)
227 (erlang-skel-separator)
228 (erlang-skel-include erlang-skel-small-header
) )
229 "*The template of a large header.
230 Please see the function `tempo-define-template'.")
234 (defvar erlang-skel-small-server
235 '((erlang-skel-include erlang-skel-large-header
)
236 "-export([start/0,init/1])." n n n
237 "start() ->" n
> "spawn(" (erlang-get-module-from-file-name)
238 ", init, [self()])." n n
247 "*Template of a small server.
248 Please see the function `tempo-define-template'.")
250 ;; Behaviour templates.
251 (defvar erlang-skel-application
252 '((erlang-skel-include erlang-skel-large-header
)
253 "-behaviour(application)." n n
254 "%% Application callbacks" n
255 "-export([start/2, stop/1])." n n
256 (erlang-skel-double-separator 2)
257 "%% Application callbacks" n
258 (erlang-skel-double-separator 2)
259 (erlang-skel-separator 2)
262 "%% This function is called whenever an application is started using" n
263 "%% application:start/[1,2], and should start the processes of the" n
264 "%% application. If the application is structured according to the OTP" n
265 "%% design principles as a supervision tree, this means starting the" n
266 "%% top supervisor of the tree." n
268 "%% @spec start(Type, StartArgs) -> {ok, Pid} |" n
269 "%% {ok, Pid, State} |" n
270 "%% {error, Reason}" n
272 (erlang-skel-separator 2)
273 "start(_Type, StartArgs) ->" n
>
274 "case 'TopSupervisor':start_link(StartArgs) of" n
>
281 (erlang-skel-separator 2)
284 "%% This function is called whenever an application has stopped. It" n
285 "%% is intended to be the opposite of Module:start/2 and should do" n
286 "%% any necessary cleaning up. The return value is ignored." n
288 "%% @spec stop(State) -> void()" n
290 (erlang-skel-separator 2)
294 (erlang-skel-double-separator 2)
295 "%% Internal functions" n
296 (erlang-skel-double-separator 2)
298 "*The template of an application behaviour.
299 Please see the function `tempo-define-template'.")
301 (defvar erlang-skel-supervisor
302 '((erlang-skel-include erlang-skel-large-header
)
303 "-behaviour(supervisor)." n n
306 "-export([start_link/0])." n n
308 "%% Supervisor callbacks" n
309 "-export([init/1])." n n
311 "-define(SERVER, ?MODULE)." n n
313 (erlang-skel-double-separator 2)
315 (erlang-skel-double-separator 2)
316 (erlang-skel-separator 2)
318 "%% Starts the supervisor" n
320 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
322 (erlang-skel-separator 2)
324 "supervisor:start_link({local, ?SERVER}, ?MODULE, [])." n
326 (erlang-skel-double-separator 2)
327 "%% Supervisor callbacks" n
328 (erlang-skel-double-separator 2)
329 (erlang-skel-separator 2)
332 "%% Whenever a supervisor is started using supervisor:start_link/[2,3]," n
333 "%% this function is called by the new process to find out about" n
334 "%% restart strategy, maximum restart frequency and child" n
335 "%% specifications." n
337 "%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |" n
339 "%% {error, Reason}" n
341 (erlang-skel-separator 2)
343 "RestartStrategy = one_for_one," n
>
344 "MaxRestarts = 1000," n
>
345 "MaxSecondsBetweenRestarts = 3600," n
347 "SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}," n
349 "Restart = permanent," n
>
350 "Shutdown = 2000," n
>
353 "AChild = {'AName', {'AModule', start_link, []}," n
>
354 "Restart, Shutdown, Type, ['AModule']}," n
356 "{ok, {SupFlags, [AChild]}}." n
358 (erlang-skel-double-separator 2)
359 "%% Internal functions" n
360 (erlang-skel-double-separator 2)
362 "*The template of an supervisor behaviour.
363 Please see the function `tempo-define-template'.")
365 (defvar erlang-skel-supervisor-bridge
366 '((erlang-skel-include erlang-skel-large-header
)
367 "-behaviour(supervisor_bridge)." n n
370 "-export([start_link/0])." n n
372 "%% supervisor_bridge callbacks" n
373 "-export([init/1, terminate/2])." n n
375 "-define(SERVER, ?MODULE)." n n
377 "-record(state, {})." n n
379 (erlang-skel-double-separator 2)
381 (erlang-skel-double-separator 2)
382 (erlang-skel-separator 2)
384 "%% Starts the supervisor bridge" n
386 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
388 (erlang-skel-separator 2)
390 "supervisor_bridge:start_link({local, ?SERVER}, ?MODULE, [])." n
392 (erlang-skel-double-separator 2)
393 "%% supervisor_bridge callbacks" n
394 (erlang-skel-double-separator 2)
395 (erlang-skel-separator 2)
398 "%% Creates a supervisor_bridge process, linked to the calling process," n
399 "%% which calls Module:init/1 to start the subsystem. To ensure a" n
400 "%% synchronized start-up procedure, this function does not return" n
401 "%% until Module:init/1 has returned." n
403 "%% @spec init(Args) -> {ok, Pid, State} |" n
405 "%% {error, Reason}" n
407 (erlang-skel-separator 2)
409 "case 'AModule':start_link() of" n
>
411 "{ok, Pid, #state{}};" n
>
416 (erlang-skel-separator 2)
419 "%% This function is called by the supervisor_bridge when it is about" n
420 "%% to terminate. It should be the opposite of Module:init/1 and stop" n
421 "%% the subsystem and do any necessary cleaning up.The return value is" n
424 "%% @spec terminate(Reason, State) -> void()" n
426 (erlang-skel-separator 2)
427 "terminate(Reason, State) ->" n
>
428 "'AModule':stop()," n
>
431 (erlang-skel-double-separator 2)
432 "%% Internal functions" n
433 (erlang-skel-double-separator 2)
435 "*The template of an supervisor_bridge behaviour.
436 Please see the function `tempo-define-template'.")
438 (defvar erlang-skel-generic-server
439 '((erlang-skel-include erlang-skel-large-header
)
440 "-behaviour(gen_server)." n n
443 "-export([start_link/0])." n n
445 "%% gen_server callbacks" n
446 "-export([init/1, handle_call/3, handle_cast/2, "
448 "terminate/2, code_change/3])." n n
450 "-define(SERVER, ?MODULE). " n n
452 "-record(state, {})." n n
454 (erlang-skel-double-separator 2)
456 (erlang-skel-double-separator 2)
457 (erlang-skel-separator 2)
459 "%% Starts the server" n
461 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
463 (erlang-skel-separator 2)
465 "gen_server:start_link({local, ?SERVER}, ?MODULE, [], [])." n
467 (erlang-skel-double-separator 2)
468 "%% gen_server callbacks" n
469 (erlang-skel-double-separator 2)
471 (erlang-skel-separator 2)
474 "%% Initiates the server" n
476 "%% @spec init(Args) -> {ok, State} |" n
477 "%% {ok, State, Timeout} |" n
479 "%% {stop, Reason}" n
481 (erlang-skel-separator 2)
485 (erlang-skel-separator 2)
488 "%% Handling call messages" n
490 "%% @spec handle_call(Request, From, State) ->" n
491 "%% {reply, Reply, State} |" n
492 "%% {reply, Reply, State, Timeout} |" n
493 "%% {noreply, State} |" n
494 "%% {noreply, State, Timeout} |" n
495 "%% {stop, Reason, Reply, State} |" n
496 "%% {stop, Reason, State}" n
498 (erlang-skel-separator 2)
499 "handle_call(_Request, _From, State) ->" n
>
501 "{reply, Reply, State}." n
503 (erlang-skel-separator 2)
506 "%% Handling cast messages" n
508 "%% @spec handle_cast(Msg, State) -> {noreply, State} |" n
509 "%% {noreply, State, Timeout} |" n
510 "%% {stop, Reason, State}" n
513 (erlang-skel-separator 2)
514 "handle_cast(_Msg, State) ->" n
>
515 "{noreply, State}." n
517 (erlang-skel-separator 2)
520 "%% Handling all non call/cast messages" n
522 "%% @spec handle_info(Info, State) -> {noreply, State} |" n
523 "%% {noreply, State, Timeout} |" n
524 "%% {stop, Reason, State}" n
526 (erlang-skel-separator 2)
527 "handle_info(_Info, State) ->" n
>
528 "{noreply, State}." n
530 (erlang-skel-separator 2)
533 "%% This function is called by a gen_server when it is about to" n
534 "%% terminate. It should be the opposite of Module:init/1 and do any" n
535 "%% necessary cleaning up. When it returns, the gen_server terminates" n
536 "%% with Reason. The return value is ignored." n
538 "%% @spec terminate(Reason, State) -> void()" n
540 (erlang-skel-separator 2)
541 "terminate(_Reason, _State) ->" n
>
544 (erlang-skel-separator 2)
547 "%% Convert process state when code is changed" n
549 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
551 (erlang-skel-separator 2)
552 "code_change(_OldVsn, State, _Extra) ->" n
>
555 (erlang-skel-double-separator 2)
556 "%%% Internal functions" n
557 (erlang-skel-double-separator 2)
559 "*The template of a generic server.
560 Please see the function `tempo-define-template'.")
562 (defvar erlang-skel-gen-event
563 '((erlang-skel-include erlang-skel-large-header
)
564 "-behaviour(gen_event)." n
567 "-export([start_link/0, add_handler/0])." n n
569 "%% gen_event callbacks" n
570 "-export([init/1, handle_event/2, handle_call/2, " n
>
571 "handle_info/2, terminate/2, code_change/3])." n n
573 "-record(state, {})." n n
575 (erlang-skel-double-separator 2)
576 "%% gen_event callbacks" n
577 (erlang-skel-double-separator 2)
578 (erlang-skel-separator 2)
580 "%% Creates an event manager" n
582 "%% @spec start_link() -> {ok, Pid} | {error, Error}" n
584 (erlang-skel-separator 2)
586 "gen_event:start_link({local, ?SERVER})." n
588 (erlang-skel-separator 2)
590 "%% Adds an event handler" n
592 "%% @spec add_handler() -> ok | {'EXIT', Reason} | term()" n
594 (erlang-skel-separator 2)
595 "add_handler() ->" n
>
596 "gen_event:add_handler(?SERVER, ?MODULE, [])." n
598 (erlang-skel-double-separator 2)
599 "%% gen_event callbacks" n
600 (erlang-skel-double-separator 2)
601 (erlang-skel-separator 2)
604 "%% Whenever a new event handler is added to an event manager," n
605 "%% this function is called to initialize the event handler." n
607 "%% @spec init(Args) -> {ok, State}" n
609 (erlang-skel-separator 2)
613 (erlang-skel-separator 2)
616 "%% Whenever an event manager receives an event sent using" n
617 "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is" n
618 "%% called for each installed event handler to handle the event." n
620 "%% @spec handle_event(Event, State) ->" n
622 "%% {swap_handler, Args1, State1, Mod2, Args2} |"n
623 "%% remove_handler" n
625 (erlang-skel-separator 2)
626 "handle_event(_Event, State) ->" n
>
629 (erlang-skel-separator 2)
632 "%% Whenever an event manager receives a request sent using" n
633 "%% gen_event:call/3,4, this function is called for the specified" n
634 "%% event handler to handle the request." n
636 "%% @spec handle_call(Request, State) ->" n
637 "%% {ok, Reply, State} |" n
638 "%% {swap_handler, Reply, Args1, State1, Mod2, Args2} |" n
639 "%% {remove_handler, Reply}" n
641 (erlang-skel-separator 2)
642 "handle_call(_Request, State) ->" n
>
644 "{ok, Reply, State}." n
646 (erlang-skel-separator 2)
649 "%% This function is called for each installed event handler when" n
650 "%% an event manager receives any other message than an event or a" n
651 "%% synchronous request (or a system message)." n
653 "%% @spec handle_info(Info, State) ->" n
655 "%% {swap_handler, Args1, State1, Mod2, Args2} |" n
656 "%% remove_handler" n
658 (erlang-skel-separator 2)
659 "handle_info(_Info, State) ->" n
>
662 (erlang-skel-separator 2)
665 "%% Whenever an event handler is deleted from an event manager, this" n
666 "%% function is called. It should be the opposite of Module:init/1 and" n
667 "%% do any necessary cleaning up." n
669 "%% @spec terminate(Reason, State) -> void()" n
671 (erlang-skel-separator 2)
672 "terminate(_Reason, _State) ->" n
>
675 (erlang-skel-separator 2)
678 "%% Convert process state when code is changed" n
680 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
682 (erlang-skel-separator 2)
683 "code_change(_OldVsn, State, _Extra) ->" n
>
686 (erlang-skel-double-separator 2)
687 "%%% Internal functions" n
688 (erlang-skel-double-separator 2)
690 "*The template of a gen_event.
691 Please see the function `tempo-define-template'.")
693 (defvar erlang-skel-gen-fsm
694 '((erlang-skel-include erlang-skel-large-header
)
695 "-behaviour(gen_fsm)." n n
698 "-export([start_link/0])." n n
700 "%% gen_fsm callbacks" n
701 "-export([init/1, state_name/2, state_name/3, handle_event/3," n
>
702 "handle_sync_event/4, handle_info/3, terminate/3, code_change/4])." n n
704 "-record(state, {})." n n
706 (erlang-skel-double-separator 2)
708 (erlang-skel-double-separator 2)
709 (erlang-skel-separator 2)
711 "%% Creates a gen_fsm process which calls Module:init/1 to" n
712 "%% initialize. To ensure a synchronized start-up procedure, this" n
713 "%% function does not return until Module:init/1 has returned." n
715 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
717 (erlang-skel-separator 2)
719 "gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], [])." n
721 (erlang-skel-double-separator 2)
722 "%% gen_fsm callbacks" n
723 (erlang-skel-double-separator 2)
724 (erlang-skel-separator 2)
727 "%% Whenever a gen_fsm is started using gen_fsm:start/[3,4] or" n
728 "%% gen_fsm:start_link/[3,4], this function is called by the new" n
729 "%% process to initialize." n
731 "%% @spec init(Args) -> {ok, StateName, State} |" n
732 "%% {ok, StateName, State, Timeout} |" n
734 "%% {stop, StopReason}" n
736 (erlang-skel-separator 2)
738 "{ok, state_name, #state{}}." n
740 (erlang-skel-separator 2)
743 "%% There should be one instance of this function for each possible" n
744 "%% state name. Whenever a gen_fsm receives an event sent using" n
745 "%% gen_fsm:send_event/2, the instance of this function with the same" n
746 "%% name as the current state name StateName is called to handle" n
747 "%% the event. It is also called if a timeout occurs." n
749 "%% @spec state_name(Event, State) ->" n
750 "%% {next_state, NextStateName, NextState} |" n
751 "%% {next_state, NextStateName, NextState, Timeout} |" n
752 "%% {stop, Reason, NewState}" n
754 (erlang-skel-separator 2)
755 "state_name(_Event, State) ->" n
>
756 "{next_state, state_name, State}." n
758 (erlang-skel-separator 2)
761 "%% There should be one instance of this function for each possible" n
762 "%% state name. Whenever a gen_fsm receives an event sent using" n
763 "%% gen_fsm:sync_send_event/[2,3], the instance of this function with" n
764 "%% the same name as the current state name StateName is called to" n
765 "%% handle the event." n
767 "%% @spec state_name(Event, From, State) ->" n
768 "%% {next_state, NextStateName, NextState} |"n
769 "%% {next_state, NextStateName, NextState, Timeout} |" n
770 "%% {reply, Reply, NextStateName, NextState} |" n
771 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
772 "%% {stop, Reason, NewState} |" n
773 "%% {stop, Reason, Reply, NewState}" n
775 (erlang-skel-separator 2)
776 "state_name(_Event, _From, State) ->" n
>
778 "{reply, Reply, state_name, State}." n
780 (erlang-skel-separator 2)
783 "%% Whenever a gen_fsm receives an event sent using" n
784 "%% gen_fsm:send_all_state_event/2, this function is called to handle" n
787 "%% @spec handle_event(Event, StateName, State) ->" n
788 "%% {next_state, NextStateName, NextState} |" n
789 "%% {next_state, NextStateName, NextState, Timeout} |" n
790 "%% {stop, Reason, NewState}" n
792 (erlang-skel-separator 2)
793 "handle_event(_Event, StateName, State) ->" n
>
794 "{next_state, StateName, State}." n
796 (erlang-skel-separator 2)
799 "%% Whenever a gen_fsm receives an event sent using" n
800 "%% gen_fsm:sync_send_all_state_event/[2,3], this function is called" n
801 "%% to handle the event." n
803 "%% @spec handle_sync_event(Event, From, StateName, State) ->" n
804 "%% {next_state, NextStateName, NextState} |" n
805 "%% {next_state, NextStateName, NextState, Timeout} |" n
806 "%% {reply, Reply, NextStateName, NextState} |" n
807 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
808 "%% {stop, Reason, NewState} |" n
809 "%% {stop, Reason, Reply, NewState}" n
811 (erlang-skel-separator 2)
812 "handle_sync_event(Event, From, StateName, State) ->" n
>
814 "{reply, Reply, StateName, State}." n
816 (erlang-skel-separator 2)
819 "%% This function is called by a gen_fsm when it receives any" n
820 "%% message other than a synchronous or asynchronous event" n
821 "%% (or a system message)." n
823 "%% @spec handle_info(Info,StateName,State)->" n
824 "%% {next_state, NextStateName, NextState} |" n
825 "%% {next_state, NextStateName, NextState, Timeout} |" n
826 "%% {stop, Reason, NewState}" n
828 (erlang-skel-separator 2)
829 "handle_info(_Info, StateName, State) ->" n
>
830 "{next_state, StateName, State}." n
832 (erlang-skel-separator 2)
835 "%% This function is called by a gen_fsm when it is about to" n
836 "%% terminate. It should be the opposite of Module:init/1 and do any" n
837 "%% necessary cleaning up. When it returns, the gen_fsm terminates with" n
838 "%% Reason. The return value is ignored." n
840 "%% @spec terminate(Reason, StateName, State) -> void()" n
842 (erlang-skel-separator 2)
843 "terminate(_Reason, _StateName, _State) ->" n
>
846 (erlang-skel-separator 2)
849 "%% Convert process state when code is changed" n
851 "%% @spec code_change(OldVsn, StateName, State, Extra) ->" n
852 "%% {ok, StateName, NewState}" n
854 (erlang-skel-separator 2)
855 "code_change(_OldVsn, StateName, State, _Extra) ->" n
>
856 "{ok, StateName, State}." n
858 (erlang-skel-double-separator 2)
859 "%%% Internal functions" n
860 (erlang-skel-double-separator 2)
862 "*The template of a gen_fsm.
863 Please see the function `tempo-define-template'.")
865 (defvar erlang-skel-lib
866 '((erlang-skel-include erlang-skel-large-header
)
871 (erlang-skel-double-separator 2)
873 (erlang-skel-double-separator 2)
874 (erlang-skel-separator 2)
878 (erlang-skel-separator 2)
880 (erlang-skel-double-separator 2)
881 "%% Internal functions" n
882 (erlang-skel-double-separator 2)
884 "*The template of a library module.
885 Please see the function `tempo-define-template'.")
887 (defvar erlang-skel-corba-callback
888 '((erlang-skel-include erlang-skel-large-header
)
889 "%% Include files" n n
894 "%% Corba callbacks" n
895 "-export([init/1, terminate/2, code_change/3])." n n
897 "-record(state, {})." n n
899 (erlang-skel-double-separator 2)
900 "%% Corba callbacks" n
901 (erlang-skel-double-separator 2)
902 (erlang-skel-separator 2)
905 "%% Initiates the server" n
907 "%% @spec init(Args) -> {ok, State} |" n
908 "%% {ok, State, Timeout} |" n
910 "%% {stop, Reason}" n
912 (erlang-skel-separator 2)
916 (erlang-skel-separator 2)
919 "%% Shutdown the server" n
921 "%% @spec terminate(Reason, State) -> void()" n
923 (erlang-skel-separator 2)
924 "terminate(_Reason, _State) ->" n
>
927 (erlang-skel-separator 2)
930 "%% Convert process state when code is changed" n
932 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
934 (erlang-skel-separator 2)
935 "code_change(_OldVsn, State, _Extra) ->" n
>
938 (erlang-skel-double-separator 2)
939 "%% Internal functions" n
940 (erlang-skel-double-separator 2)
942 "*The template of a library module.
943 Please see the function `tempo-define-template'.")
945 (defvar erlang-skel-ts-test-suite
946 '((erlang-skel-include erlang-skel-large-header
)
947 "%% Note: This directive should only be used in test suites." n
948 "-compile(export_all)." n n
950 "-include(\"test_server.hrl\")." n n
952 "%% Test server callback functions" n
953 (erlang-skel-separator 2)
955 "%% Config - [tuple()]" n
956 "%% A list of key/value pairs, holding the test case configuration." n
958 "%% Initiation before the whole suite" n
960 "%% Note: This function is free to add any key/value pairs to the Config" n
961 "%% variable, but should NOT alter/remove any existing entries." n
963 "%% @spec init_per_suite(Config) -> Config" n
965 (erlang-skel-separator 2)
966 "init_per_suite(Config) ->" n
>
969 (erlang-skel-separator 2)
971 "%% Config - [tuple()]" n
972 "%% A list of key/value pairs, holding the test case configuration." n
974 "%% Cleanup after the whole suite" n
976 "%% @spec end_per_suite(Config) -> _" n
978 (erlang-skel-separator 2)
979 "end_per_suite(_Config) ->" n
>
982 (erlang-skel-separator 2)
985 "%% Name of the test case that is about to be run." n
986 "%% Config - [tuple()]" n
987 "%% A list of key/value pairs, holding the test case configuration." n
989 "%% Initiation before each test case" n
991 "%% Note: This function is free to add any key/value pairs to the Config" n
992 "%% variable, but should NOT alter/remove any existing entries." n
994 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
996 (erlang-skel-separator 2)
997 "init_per_testcase(_TestCase, Config) ->" n
>
1000 (erlang-skel-separator 2)
1002 "%% Case - atom()" n
1003 "%% Name of the test case that is about to be run." n
1004 "%% Config - [tuple()]" n
1005 "%% A list of key/value pairs, holding the test case configuration." n
1007 "%% Cleanup after each test case" n
1009 "%% @spec end_per_testcase(TestCase, Config) -> _" n
1011 (erlang-skel-separator 2)
1012 "end_per_testcase(_TestCase, _Config) ->" n
>
1015 (erlang-skel-separator 2)
1017 "%% Clause - atom() - suite | doc" n
1018 "%% TestCases - [Case]" n
1019 "%% Case - atom()" n
1020 "%% Name of a test case." n
1022 "%% Returns a list of all test cases in this test suite" n
1024 "%% @spec all(Clause) -> TestCases" n
1026 (erlang-skel-separator 2)
1028 "[\"Describe the main purpose of this suite\"];" n n
1032 "%% Test cases starts here." n
1033 (erlang-skel-separator 2)
1034 "test_case(doc) ->" n
>
1035 "[\"Describe the main purpose of test case\"];" n n
1036 "test_case(suite) ->" n
>
1038 "test_case(Config) when is_list(Config) ->" n
>
1041 "*The template of a library module.
1042 Please see the function `tempo-define-template'.")
1044 (defvar erlang-skel-ct-test-suite
1045 '((erlang-skel-include erlang-skel-large-header
)
1046 "-suite_defaults([{timetrap, {minutes, 10}}])." n n
1048 "%% Note: This directive should only be used in test suites." n
1049 "-compile(export_all)." n n
1051 "-include(\"ct.hrl\")." n n
1053 "%% Test server callback functions" n
1054 (erlang-skel-separator 2)
1056 "%% Config - [tuple()]" n
1057 "%% A list of key/value pairs, holding the test case configuration." n
1059 "%% Initiation before the whole suite" 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
1064 "%% @spec init_per_suite(Config) -> Config" n
1066 (erlang-skel-separator 2)
1067 "init_per_suite(Config) ->" n
>
1070 (erlang-skel-separator 2)
1072 "%% Config - [tuple()]" n
1073 "%% A list of key/value pairs, holding the test case configuration." n
1075 "%% Cleanup after the whole suite" n
1077 "%% @spec end_per_suite(Config) -> _" n
1079 (erlang-skel-separator 2)
1080 "end_per_suite(_Config) ->" n
>
1083 (erlang-skel-separator 2)
1085 "%% Case - atom()" n
1086 "%% Name of the test case that is about to be run." n
1087 "%% Config - [tuple()]" n
1088 "%% A list of key/value pairs, holding the test case configuration." n
1090 "%% Initiation before each test case" n
1092 "%% Note: This function is free to add any key/value pairs to the Config" n
1093 "%% variable, but should NOT alter/remove any existing entries." n
1094 "%% Initiation before each test case" n
1096 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
1098 (erlang-skel-separator 2)
1099 "init_per_testcase(_TestCase, Config) ->" n
>
1102 (erlang-skel-separator 2)
1104 "%% Case - atom()" n
1105 "%% Name of the test case that is about to be run." n
1106 "%% Config - [tuple()]" n
1107 "%% A list of key/value pairs, holding the test case configuration." n
1109 "%% Cleanup after each test case" n
1111 "%% @spec end_per_testcase(TestCase, Config) -> _" n
1113 (erlang-skel-separator 2)
1114 "end_per_testcase(_TestCase, _Config) ->" n
>
1117 (erlang-skel-separator 2)
1119 "%% TestCases - [Case]" n
1120 "%% Case - atom()" n
1121 "%% Name of a test case." n
1123 "%% Returns a list of all test cases in this test suite" n
1125 "%% @spec all() -> TestCases" n
1127 (erlang-skel-separator 2)
1131 "%% Test cases starts here." n
1132 (erlang-skel-separator 2)
1133 "test_case() ->" n
>
1134 "[{doc, \"Describe the main purpose of this test case\"}]." n n
1135 "test_case(Config) when is_list(Config) ->" n
>
1138 "*The template of a library module.
1139 Please see the function `tempo-define-template'.")
1143 ;; This code is based on the package `tempo' which is part of modern
1144 ;; Emacsen. (GNU Emacs 19.25 (?) and XEmacs 19.14.)
1146 (defun erlang-skel-init ()
1147 "Generate the skeleton functions and menu items.
1148 The variable `erlang-skel' contains the name and descriptions of
1151 The skeleton routines are based on the `tempo' package. Should this
1152 package not be present, this function does nothing."
1157 (if (featurep 'tempo
)
1158 (let ((skel erlang-skel
)
1161 (cond ((null (car skel
))
1162 (setq menu
(cons nil menu
)))
1164 (funcall (symbol-function 'tempo-define-template
)
1165 (concat "erlang-" (nth 1 (car skel
)))
1166 ;; The tempo template used contains an `include'
1167 ;; function call only, hence changes to the
1168 ;; variables describing the templates take effect
1170 (list (list 'erlang-skel-include
(nth 2 (car skel
))))
1172 (setq menu
(cons (erlang-skel-make-menu-item
1173 (car skel
)) menu
))))
1174 (setq skel
(cdr skel
)))
1175 (setq erlang-menu-skel-items
1176 (list nil
(list "Skeletons" (nreverse menu
))))
1177 (setq erlang-menu-items
1178 (erlang-menu-add-above 'erlang-menu-skel-items
1179 'erlang-menu-version-items
1181 (erlang-menu-init))))
1183 (defun erlang-skel-make-menu-item (skel)
1184 (let ((func (intern (concat "tempo-template-erlang-" (nth 1 skel
)))))
1185 (cond ((null (nth 3 skel
))
1186 (list (car skel
) func
))
1192 (list 'quote
(nth 3 skel
))
1193 (list 'quote func
))))))))
1195 ;; Functions designed to be added to the skeleton menu.
1196 ;; (Not normally used)
1197 (defun erlang-skel-insert (func)
1198 "Insert skeleton generated by FUNC and goto first tempo mark."
1199 (save-excursion (funcall func
))
1200 (funcall (symbol-function 'tempo-forward-mark
)))
1202 (defun erlang-skel-header (func)
1203 "Insert the header generated by FUNC at the beginning of the buffer."
1204 (goto-char (point-min))
1205 (save-excursion (funcall func
))
1206 (funcall (symbol-function 'tempo-forward-mark
)))
1209 ;; Functions used inside the skeleton descriptions.
1210 (defun erlang-skel-skip-blank ()
1211 (skip-chars-backward " \t")
1214 (defun erlang-skel-include (&rest args
)
1215 "Include a template inside another template.
1217 Example of use, assuming that `erlang-skel-func' is defined:
1219 (defvar foo-skeleton '(\"%%% New function:\"
1220 (erlang-skel-include erlang-skel-func)))
1222 Technically, this function returns the `tempo' attribute`(l ...)' which
1223 can contain other `tempo' attributes. Please see the function
1224 `tempo-define-template' for a description of the `(l ...)' attribute."
1228 (setq entry
(car args
))
1230 (setq res
(cons (car entry
) res
))
1231 (setq entry
(cdr entry
)))
1232 (setq args
(cdr args
)))
1233 (cons 'l
(nreverse res
))))
1235 (defun erlang-skel-separator (&optional percent
)
1236 "Return a comment separator."
1237 (let ((percent (or percent
3)))
1238 (concat (make-string percent ?%
)
1239 (make-string (- 70 percent
) ?-
)
1242 (defun erlang-skel-double-separator (&optional percent
)
1243 "Return a comment separator."
1244 (let ((percent (or percent
3)))
1245 (concat (make-string percent ?%
)
1246 (make-string (- 70 percent
) ?
=)
1249 (defun erlang-skel-dd-mmm-yyyy ()
1250 "Return the current date as a string in \"DD Mon YYYY\" form.
1251 The first character of DD is space if the value is less than 10."
1252 (let ((date (current-time-string)))
1254 (string-to-int (substring date
8 10))
1255 (substring date
4 7)
1256 (substring date -
4))))
1259 ;; coding: iso-8859-1
1262 ;;; erlang.el ends here