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
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 "-record(state, {})." n n
568 (erlang-skel-double-separator-start 3)
569 "%%% gen_event callbacks" n
570 (erlang-skel-double-separator-end 3) n
571 (erlang-skel-separator-start 2)
573 "%% Creates an event manager" n
575 "%% @spec start_link() -> {ok, Pid} | {error, Error}" n
576 (erlang-skel-separator-end 2)
578 "gen_event:start_link({local, ?SERVER})." n
580 (erlang-skel-separator-start 2)
582 "%% Adds an event handler" n
584 "%% @spec add_handler() -> ok | {'EXIT', Reason} | term()" n
585 (erlang-skel-separator-end 2)
586 "add_handler() ->" n
>
587 "gen_event:add_handler(?SERVER, ?MODULE, [])." n
589 (erlang-skel-double-separator-start 3)
590 "%%% gen_event callbacks" n
591 (erlang-skel-double-separator-end 3) n
592 (erlang-skel-separator-start 2)
595 "%% Whenever a new event handler is added to an event manager," n
596 "%% this function is called to initialize the event handler." n
598 "%% @spec init(Args) -> {ok, State}" n
599 (erlang-skel-separator-end 2)
603 (erlang-skel-separator-start 2)
606 "%% Whenever an event manager receives an event sent using" n
607 "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is" n
608 "%% called for each installed event handler to handle the event." n
610 "%% @spec handle_event(Event, State) ->" n
612 "%% {swap_handler, Args1, State1, Mod2, Args2} |"n
613 "%% remove_handler" n
614 (erlang-skel-separator-end 2)
615 "handle_event(_Event, State) ->" n
>
618 (erlang-skel-separator-start 2)
621 "%% Whenever an event manager receives a request sent using" n
622 "%% gen_event:call/3,4, this function is called for the specified" n
623 "%% event handler to handle the request." n
625 "%% @spec handle_call(Request, State) ->" n
626 "%% {ok, Reply, State} |" n
627 "%% {swap_handler, Reply, Args1, State1, Mod2, Args2} |" n
628 "%% {remove_handler, Reply}" n
629 (erlang-skel-separator-end 2)
630 "handle_call(_Request, State) ->" n
>
632 "{ok, Reply, State}." n
634 (erlang-skel-separator-start 2)
637 "%% This function is called for each installed event handler when" n
638 "%% an event manager receives any other message than an event or a" n
639 "%% synchronous request (or a system message)." n
641 "%% @spec handle_info(Info, State) ->" n
643 "%% {swap_handler, Args1, State1, Mod2, Args2} |" n
644 "%% remove_handler" n
645 (erlang-skel-separator-end 2)
646 "handle_info(_Info, State) ->" n
>
649 (erlang-skel-separator-start 2)
652 "%% Whenever an event handler is deleted from an event manager, this" n
653 "%% function is called. It should be the opposite of Module:init/1 and" n
654 "%% do any necessary cleaning up." n
656 "%% @spec terminate(Reason, State) -> void()" n
657 (erlang-skel-separator-end 2)
658 "terminate(_Reason, _State) ->" n
>
661 (erlang-skel-separator-start 2)
664 "%% Convert process state when code is changed" n
666 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
667 (erlang-skel-separator-end 2)
668 "code_change(_OldVsn, State, _Extra) ->" n
>
671 (erlang-skel-double-separator-start 3)
672 "%%% Internal functions" n
673 (erlang-skel-double-separator-end 3)
675 "*The template of a gen_event.
676 Please see the function `tempo-define-template'.")
678 (defvar erlang-skel-gen-fsm
679 '((erlang-skel-include erlang-skel-large-header
)
680 "-behaviour(gen_fsm)." n n
683 "-export([start_link/0])." n n
685 "%% gen_fsm callbacks" n
686 "-export([init/1, state_name/2, state_name/3, handle_event/3," n
>
687 "handle_sync_event/4, handle_info/3, terminate/3, code_change/4])." n n
689 "-record(state, {})." n n
691 (erlang-skel-double-separator-start 3)
693 (erlang-skel-double-separator-end 3) n
694 (erlang-skel-separator-start 2)
696 "%% Creates a gen_fsm process which calls Module:init/1 to" n
697 "%% initialize. To ensure a synchronized start-up procedure, this" n
698 "%% function does not return until Module:init/1 has returned." n
700 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
701 (erlang-skel-separator-end 2)
703 "gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], [])." n
705 (erlang-skel-double-separator-start 3)
706 "%%% gen_fsm callbacks" n
707 (erlang-skel-double-separator-end 3) n
708 (erlang-skel-separator-start 2)
711 "%% Whenever a gen_fsm is started using gen_fsm:start/[3,4] or" n
712 "%% gen_fsm:start_link/[3,4], this function is called by the new" n
713 "%% process to initialize." n
715 "%% @spec init(Args) -> {ok, StateName, State} |" n
716 "%% {ok, StateName, State, Timeout} |" n
718 "%% {stop, StopReason}" n
719 (erlang-skel-separator-end 2)
721 "{ok, state_name, #state{}}." n
723 (erlang-skel-separator-start 2)
726 "%% There should be one instance of this function for each possible" n
727 "%% state name. Whenever a gen_fsm receives an event sent using" n
728 "%% gen_fsm:send_event/2, the instance of this function with the same" n
729 "%% name as the current state name StateName is called to handle" n
730 "%% the event. It is also called if a timeout occurs." n
732 "%% @spec state_name(Event, State) ->" n
733 "%% {next_state, NextStateName, NextState} |" n
734 "%% {next_state, NextStateName, NextState, Timeout} |" n
735 "%% {stop, Reason, NewState}" n
736 (erlang-skel-separator-end 2)
737 "state_name(_Event, State) ->" n
>
738 "{next_state, state_name, State}." n
740 (erlang-skel-separator-start 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:sync_send_event/[2,3], the instance of this function with" n
746 "%% the same name as the current state name StateName is called to" n
747 "%% handle the event." n
749 "%% @spec state_name(Event, From, State) ->" n
750 "%% {next_state, NextStateName, NextState} |"n
751 "%% {next_state, NextStateName, NextState, Timeout} |" n
752 "%% {reply, Reply, NextStateName, NextState} |" n
753 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
754 "%% {stop, Reason, NewState} |" n
755 "%% {stop, Reason, Reply, NewState}" n
756 (erlang-skel-separator-end 2)
757 "state_name(_Event, _From, State) ->" n
>
759 "{reply, Reply, state_name, State}." n
761 (erlang-skel-separator-start 2)
764 "%% Whenever a gen_fsm receives an event sent using" n
765 "%% gen_fsm:send_all_state_event/2, this function is called to handle" n
768 "%% @spec handle_event(Event, StateName, State) ->" n
769 "%% {next_state, NextStateName, NextState} |" n
770 "%% {next_state, NextStateName, NextState, Timeout} |" n
771 "%% {stop, Reason, NewState}" n
772 (erlang-skel-separator-end 2)
773 "handle_event(_Event, StateName, State) ->" n
>
774 "{next_state, StateName, State}." n
776 (erlang-skel-separator-start 2)
779 "%% Whenever a gen_fsm receives an event sent using" n
780 "%% gen_fsm:sync_send_all_state_event/[2,3], this function is called" n
781 "%% to handle the event." n
783 "%% @spec handle_sync_event(Event, From, StateName, State) ->" n
784 "%% {next_state, NextStateName, NextState} |" n
785 "%% {next_state, NextStateName, NextState, Timeout} |" n
786 "%% {reply, Reply, NextStateName, NextState} |" n
787 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
788 "%% {stop, Reason, NewState} |" n
789 "%% {stop, Reason, Reply, NewState}" n
790 (erlang-skel-separator-end 2)
791 "handle_sync_event(Event, From, StateName, State) ->" n
>
793 "{reply, Reply, StateName, State}." n
795 (erlang-skel-separator-start 2)
798 "%% This function is called by a gen_fsm when it receives any" n
799 "%% message other than a synchronous or asynchronous event" n
800 "%% (or a system message)." n
802 "%% @spec handle_info(Info,StateName,State)->" n
803 "%% {next_state, NextStateName, NextState} |" n
804 "%% {next_state, NextStateName, NextState, Timeout} |" n
805 "%% {stop, Reason, NewState}" n
806 (erlang-skel-separator-end 2)
807 "handle_info(_Info, StateName, State) ->" n
>
808 "{next_state, StateName, State}." n
810 (erlang-skel-separator-start 2)
813 "%% This function is called by a gen_fsm when it is about to" n
814 "%% terminate. It should be the opposite of Module:init/1 and do any" n
815 "%% necessary cleaning up. When it returns, the gen_fsm terminates with" n
816 "%% Reason. The return value is ignored." n
818 "%% @spec terminate(Reason, StateName, State) -> void()" n
819 (erlang-skel-separator-end 2)
820 "terminate(_Reason, _StateName, _State) ->" n
>
823 (erlang-skel-separator-start 2)
826 "%% Convert process state when code is changed" n
828 "%% @spec code_change(OldVsn, StateName, State, Extra) ->" n
829 "%% {ok, StateName, NewState}" n
830 (erlang-skel-separator-end 2)
831 "code_change(_OldVsn, StateName, State, _Extra) ->" n
>
832 "{ok, StateName, State}." n
834 (erlang-skel-double-separator-start 3)
835 "%%% Internal functions" n
836 (erlang-skel-double-separator-end 3)
838 "*The template of a gen_fsm.
839 Please see the function `tempo-define-template'.")
841 (defvar erlang-skel-lib
842 '((erlang-skel-include erlang-skel-large-header
)
847 (erlang-skel-double-separator-start 3)
849 (erlang-skel-double-separator-end 3) n
850 (erlang-skel-separator-start 2)
853 (erlang-skel-separator-end 2)
855 (erlang-skel-double-separator-start 3)
856 "%%% Internal functions" n
857 (erlang-skel-double-separator-end 3)
859 "*The template of a library module.
860 Please see the function `tempo-define-template'.")
862 (defvar erlang-skel-corba-callback
863 '((erlang-skel-include erlang-skel-large-header
)
864 "%% Include files" n n
869 "%% Corba callbacks" n
870 "-export([init/1, terminate/2, code_change/3])." n n
872 "-record(state, {})." n n
874 (erlang-skel-double-separator-start 3)
875 "%%% Corba callbacks" n
876 (erlang-skel-double-separator-end 3) n
877 (erlang-skel-separator-start 2)
880 "%% Initiates the server" n
882 "%% @spec init(Args) -> {ok, State} |" n
883 "%% {ok, State, Timeout} |" n
885 "%% {stop, Reason}" n
886 (erlang-skel-separator-end 2)
890 (erlang-skel-separator-start 2)
893 "%% Shutdown the server" n
895 "%% @spec terminate(Reason, State) -> void()" n
896 (erlang-skel-separator-end 2)
897 "terminate(_Reason, _State) ->" n
>
900 (erlang-skel-separator-start 2)
903 "%% Convert process state when code is changed" n
905 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
906 (erlang-skel-separator-end 2)
907 "code_change(_OldVsn, State, _Extra) ->" n
>
910 (erlang-skel-double-separator-start 3)
911 "%%% Internal functions" n
912 (erlang-skel-double-separator-end 3)
914 "*The template of a library module.
915 Please see the function `tempo-define-template'.")
917 (defvar erlang-skel-ts-test-suite
918 '((erlang-skel-include erlang-skel-large-header
)
919 "%% Note: This directive should only be used in test suites." n
920 "-compile(export_all)." n n
922 "-include(\"test_server.hrl\")." n n
924 "%% Test server callback functions" n
925 (erlang-skel-separator-start 2)
927 "%% Config - [tuple()]" n
928 "%% A list of key/value pairs, holding the test case configuration." n
930 "%% Initiation before the whole suite" n
932 "%% Note: This function is free to add any key/value pairs to the Config" n
933 "%% variable, but should NOT alter/remove any existing entries." n
935 "%% @spec init_per_suite(Config) -> Config" n
936 (erlang-skel-separator-end 2)
937 "init_per_suite(Config) ->" n
>
940 (erlang-skel-separator-start 2)
942 "%% Config - [tuple()]" n
943 "%% A list of key/value pairs, holding the test case configuration." n
945 "%% Cleanup after the whole suite" n
947 "%% @spec end_per_suite(Config) -> _" n
948 (erlang-skel-separator-end 2)
949 "end_per_suite(_Config) ->" n
>
952 (erlang-skel-separator-start 2)
955 "%% Name of the test case that is about to be run." n
956 "%% Config - [tuple()]" n
957 "%% A list of key/value pairs, holding the test case configuration." n
959 "%% Initiation before each test case" n
961 "%% Note: This function is free to add any key/value pairs to the Config" n
962 "%% variable, but should NOT alter/remove any existing entries." n
964 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
965 (erlang-skel-separator-end 2)
966 "init_per_testcase(_TestCase, Config) ->" n
>
969 (erlang-skel-separator-start 2)
972 "%% Name of the test case that is about to be run." n
973 "%% Config - [tuple()]" n
974 "%% A list of key/value pairs, holding the test case configuration." n
976 "%% Cleanup after each test case" n
978 "%% @spec end_per_testcase(TestCase, Config) -> _" n
979 (erlang-skel-separator-end 2)
980 "end_per_testcase(_TestCase, _Config) ->" n
>
983 (erlang-skel-separator-start 2)
985 "%% Clause - atom() - suite | doc" n
986 "%% TestCases - [Case]" n
988 "%% Name of a test case." n
990 "%% Returns a list of all test cases in this test suite" n
992 "%% @spec all(Clause) -> TestCases" n
993 (erlang-skel-separator-end 2)
995 "[\"Describe the main purpose of this suite\"];" n n
999 "%% Test cases starts here." n
1000 (erlang-skel-separator-start 2)
1001 "test_case(doc) ->" n
>
1002 "[\"Describe the main purpose of test case\"];" n n
1003 "test_case(suite) ->" n
>
1005 "test_case(Config) when is_list(Config) ->" n
>
1008 "*The template of a library module.
1009 Please see the function `tempo-define-template'.")
1011 (defvar erlang-skel-ct-test-suite
1012 '((erlang-skel-include erlang-skel-large-header
)
1013 "-suite_defaults([{timetrap, {minutes, 10}}])." n n
1015 "%% Note: This directive should only be used in test suites." n
1016 "-compile(export_all)." n n
1018 "-include(\"ct.hrl\")." n n
1020 "%% Test server callback functions" n
1021 (erlang-skel-separator-start 2)
1023 "%% Config - [tuple()]" n
1024 "%% A list of key/value pairs, holding the test case configuration." n
1026 "%% Initiation before the whole suite" n
1028 "%% Note: This function is free to add any key/value pairs to the Config" n
1029 "%% variable, but should NOT alter/remove any existing entries." n
1031 "%% @spec init_per_suite(Config) -> Config" n
1032 (erlang-skel-separator-end 2)
1033 "init_per_suite(Config) ->" n
>
1036 (erlang-skel-separator-start 2)
1038 "%% Config - [tuple()]" n
1039 "%% A list of key/value pairs, holding the test case configuration." n
1041 "%% Cleanup after the whole suite" n
1043 "%% @spec end_per_suite(Config) -> _" n
1044 (erlang-skel-separator-end 2)
1045 "end_per_suite(_Config) ->" n
>
1048 (erlang-skel-separator-start 2)
1050 "%% Case - atom()" n
1051 "%% Name of the test case that is about to be run." n
1052 "%% Config - [tuple()]" n
1053 "%% A list of key/value pairs, holding the test case configuration." n
1055 "%% Initiation before each test case" n
1057 "%% Note: This function is free to add any key/value pairs to the Config" n
1058 "%% variable, but should NOT alter/remove any existing entries." n
1059 "%% Initiation before each test case" n
1061 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
1062 (erlang-skel-separator-end 2)
1063 "init_per_testcase(_TestCase, Config) ->" n
>
1066 (erlang-skel-separator-start 2)
1068 "%% Case - atom()" n
1069 "%% Name of the test case that is about to be run." n
1070 "%% Config - [tuple()]" n
1071 "%% A list of key/value pairs, holding the test case configuration." n
1073 "%% Cleanup after each test case" n
1075 "%% @spec end_per_testcase(TestCase, Config) -> _" n
1076 (erlang-skel-separator-end 2)
1077 "end_per_testcase(_TestCase, _Config) ->" n
>
1080 (erlang-skel-separator-start 2)
1082 "%% TestCases - [Case]" n
1083 "%% Case - atom()" n
1084 "%% Name of a test case." n
1086 "%% Returns a list of all test cases in this test suite" n
1088 "%% @spec all() -> TestCases" n
1089 (erlang-skel-separator-end 2)
1093 "%% Test cases starts here." n
1094 (erlang-skel-separator-start 2)
1095 "test_case() ->" n
>
1096 "[{doc, \"Describe the main purpose of this test case\"}]." n n
1097 "test_case(Config) when is_list(Config) ->" n
>
1100 "*The template of a library module.
1101 Please see the function `tempo-define-template'.")
1105 ;; This code is based on the package `tempo' which is part of modern
1106 ;; Emacsen. (GNU Emacs 19.25 (?) and XEmacs 19.14.)
1108 (defun erlang-skel-init ()
1109 "Generate the skeleton functions and menu items.
1110 The variable `erlang-skel' contains the name and descriptions of
1113 The skeleton routines are based on the `tempo' package. Should this
1114 package not be present, this function does nothing."
1119 (if (featurep 'tempo
)
1120 (let ((skel erlang-skel
)
1123 (cond ((null (car skel
))
1124 (setq menu
(cons nil menu
)))
1126 (funcall (symbol-function 'tempo-define-template
)
1127 (concat "erlang-" (nth 1 (car skel
)))
1128 ;; The tempo template used contains an `include'
1129 ;; function call only, hence changes to the
1130 ;; variables describing the templates take effect
1132 (list (list 'erlang-skel-include
(nth 2 (car skel
))))
1134 (setq menu
(cons (erlang-skel-make-menu-item
1135 (car skel
)) menu
))))
1136 (setq skel
(cdr skel
)))
1137 (setq erlang-menu-skel-items
1138 (list nil
(list "Skeletons" (nreverse menu
))))
1139 (setq erlang-menu-items
1140 (erlang-menu-add-above 'erlang-menu-skel-items
1141 'erlang-menu-version-items
1143 (erlang-menu-init))))
1145 (defun erlang-skel-make-menu-item (skel)
1146 (let ((func (intern (concat "tempo-template-erlang-" (nth 1 skel
)))))
1147 (cond ((null (nth 3 skel
))
1148 (list (car skel
) func
))
1154 (list 'quote
(nth 3 skel
))
1155 (list 'quote func
))))))))
1157 ;; Functions designed to be added to the skeleton menu.
1158 ;; (Not normally used)
1159 (defun erlang-skel-insert (func)
1160 "Insert skeleton generated by FUNC and goto first tempo mark."
1161 (save-excursion (funcall func
))
1162 (funcall (symbol-function 'tempo-forward-mark
)))
1164 (defun erlang-skel-header (func)
1165 "Insert the header generated by FUNC at the beginning of the buffer."
1166 (goto-char (point-min))
1167 (save-excursion (funcall func
))
1168 (funcall (symbol-function 'tempo-forward-mark
)))
1171 ;; Functions used inside the skeleton descriptions.
1172 (defun erlang-skel-skip-blank ()
1173 (skip-chars-backward " \t")
1176 (defun erlang-skel-include (&rest args
)
1177 "Include a template inside another template.
1179 Example of use, assuming that `erlang-skel-func' is defined:
1181 (defvar foo-skeleton '(\"%%% New function:\"
1182 (erlang-skel-include erlang-skel-func)))
1184 Technically, this function returns the `tempo' attribute`(l ...)' which
1185 can contain other `tempo' attributes. Please see the function
1186 `tempo-define-template' for a description of the `(l ...)' attribute."
1190 (setq entry
(car args
))
1192 (setq res
(cons (car entry
) res
))
1193 (setq entry
(cdr entry
)))
1194 (setq args
(cdr args
)))
1195 (cons 'l
(nreverse res
))))
1197 (defun erlang-skel-separator (&optional percent
)
1198 "Return a comment separator."
1199 (let ((percent (or percent
3)))
1200 (concat (make-string percent ?%
)
1201 (make-string (- 70 percent
) ?-
)
1204 (defun erlang-skel-separator-start (&optional percent
)
1205 "Return a comment separator or an empty string if separators
1206 are configured off."
1207 (if erlang-skel-use-separators
1208 (erlang-skel-separator percent
)
1211 (defun erlang-skel-separator-end (&optional percent
)
1212 "Return a comment separator to end a function comment block or an
1213 empty string if separators are configured off."
1214 (if erlang-skel-use-separators
1215 (concat "%% @end\n" (erlang-skel-separator percent
))
1218 (defun erlang-skel-double-separator (&optional percent
)
1219 "Return a double line (equals sign) comment separator."
1220 (let ((percent (or percent
3)))
1221 (concat (make-string percent ?%
)
1222 (make-string (- 70 percent
) ?
=)
1225 (defun erlang-skel-double-separator-start (&optional percent
)
1226 "Return a double separator or a newline if separators are configured off."
1227 (if erlang-skel-use-separators
1228 (erlang-skel-double-separator percent
)
1231 (defun erlang-skel-double-separator-end (&optional percent
)
1232 "Return a double separator or an empty string if separators are
1234 (if erlang-skel-use-separators
1235 (erlang-skel-double-separator percent
)
1238 (defun erlang-skel-dd-mmm-yyyy ()
1239 "Return the current date as a string in \"DD Mon YYYY\" form.
1240 The first character of DD is space if the value is less than 10."
1241 (let ((date (current-time-string)))
1243 (string-to-int (substring date
8 10))
1244 (substring date
4 7)
1245 (substring date -
4))))
1248 ;; coding: iso-8859-1
1251 ;;; erlang.el ends here