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 2)
263 "%% Application callbacks" n
264 (erlang-skel-double-separator 2) 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(Type, StartArgs) -> {ok, Pid} |" n
275 "%% {ok, Pid, State} |" n
276 "%% {error, Reason}" n
277 (erlang-skel-separator-end 2)
278 "start(_Type, StartArgs) ->" n
>
279 "case 'TopSupervisor':start_link(StartArgs) of" n
>
286 (erlang-skel-separator-start 2)
289 "%% This function is called whenever an application has stopped. It" n
290 "%% is intended to be the opposite of Module:start/2 and should do" n
291 "%% any necessary cleaning up. The return value is ignored." n
293 "%% @spec stop(State) -> void()" n
294 (erlang-skel-separator-end 2)
298 (erlang-skel-double-separator 2)
299 "%% Internal functions" n
300 (erlang-skel-double-separator 2)
302 "*The template of an application behaviour.
303 Please see the function `tempo-define-template'.")
305 (defvar erlang-skel-supervisor
306 '((erlang-skel-include erlang-skel-large-header
)
307 "-behaviour(supervisor)." n n
310 "-export([start_link/0])." n n
312 "%% Supervisor callbacks" n
313 "-export([init/1])." n n
315 "-define(SERVER, ?MODULE)." n n
317 (erlang-skel-double-separator 2)
319 (erlang-skel-double-separator 2) n
320 (erlang-skel-separator-start 2)
322 "%% Starts the supervisor" n
324 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
325 (erlang-skel-separator-end 2)
327 "supervisor:start_link({local, ?SERVER}, ?MODULE, [])." n
329 (erlang-skel-double-separator 2)
330 "%% Supervisor callbacks" n
331 (erlang-skel-double-separator 2) n
332 (erlang-skel-separator-start 2)
335 "%% Whenever a supervisor is started using supervisor:start_link/[2,3]," n
336 "%% this function is called by the new process to find out about" n
337 "%% restart strategy, maximum restart frequency and child" n
338 "%% specifications." n
340 "%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |" n
342 "%% {error, Reason}" n
343 (erlang-skel-separator-end 2)
345 "RestartStrategy = one_for_one," n
>
346 "MaxRestarts = 1000," n
>
347 "MaxSecondsBetweenRestarts = 3600," n
349 "SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}," n
351 "Restart = permanent," n
>
352 "Shutdown = 2000," n
>
355 "AChild = {'AName', {'AModule', start_link, []}," n
>
356 "Restart, Shutdown, Type, ['AModule']}," n
358 "{ok, {SupFlags, [AChild]}}." n
360 (erlang-skel-double-separator 2)
361 "%% Internal functions" n
362 (erlang-skel-double-separator 2)
364 "*The template of an supervisor behaviour.
365 Please see the function `tempo-define-template'.")
367 (defvar erlang-skel-supervisor-bridge
368 '((erlang-skel-include erlang-skel-large-header
)
369 "-behaviour(supervisor_bridge)." n n
372 "-export([start_link/0])." n n
374 "%% supervisor_bridge callbacks" n
375 "-export([init/1, terminate/2])." n n
377 "-define(SERVER, ?MODULE)." n n
379 "-record(state, {})." n n
381 (erlang-skel-double-separator 2)
383 (erlang-skel-double-separator 2) n
384 (erlang-skel-separator-start 2)
386 "%% Starts the supervisor bridge" n
388 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
389 (erlang-skel-separator-end 2)
391 "supervisor_bridge:start_link({local, ?SERVER}, ?MODULE, [])." n
393 (erlang-skel-double-separator 2)
394 "%% supervisor_bridge callbacks" n
395 (erlang-skel-double-separator 2) n
396 (erlang-skel-separator-start 2)
399 "%% Creates a supervisor_bridge process, linked to the calling process," n
400 "%% which calls Module:init/1 to start the subsystem. To ensure a" n
401 "%% synchronized start-up procedure, this function does not return" n
402 "%% until Module:init/1 has returned." n
404 "%% @spec init(Args) -> {ok, Pid, State} |" n
406 "%% {error, Reason}" n
407 (erlang-skel-separator-end 2)
409 "case 'AModule':start_link() of" n
>
411 "{ok, Pid, #state{}};" n
>
416 (erlang-skel-separator-start 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
425 (erlang-skel-separator-end 2)
426 "terminate(Reason, State) ->" n
>
427 "'AModule':stop()," n
>
430 (erlang-skel-double-separator 2)
431 "%% Internal functions" n
432 (erlang-skel-double-separator 2)
434 "*The template of an supervisor_bridge behaviour.
435 Please see the function `tempo-define-template'.")
437 (defvar erlang-skel-generic-server
438 '((erlang-skel-include erlang-skel-large-header
)
439 "-behaviour(gen_server)." n n
442 "-export([start_link/0])." n n
444 "%% gen_server callbacks" n
445 "-export([init/1, handle_call/3, handle_cast/2, "
447 "terminate/2, code_change/3])." n n
449 "-define(SERVER, ?MODULE). " n n
451 "-record(state, {})." n n
453 (erlang-skel-double-separator 2)
455 (erlang-skel-double-separator 2) n
456 (erlang-skel-separator-start 2)
458 "%% Starts the server" n
460 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
461 (erlang-skel-separator-end 2)
463 "gen_server:start_link({local, ?SERVER}, ?MODULE, [], [])." n
465 (erlang-skel-double-separator 2)
466 "%% gen_server callbacks" n
467 (erlang-skel-double-separator 2)
469 (erlang-skel-separator-start 2)
472 "%% Initiates the server" n
474 "%% @spec init(Args) -> {ok, State} |" n
475 "%% {ok, State, Timeout} |" n
477 "%% {stop, Reason}" n
478 (erlang-skel-separator-end 2)
482 (erlang-skel-separator-start 2)
485 "%% Handling call messages" n
487 "%% @spec handle_call(Request, From, State) ->" n
488 "%% {reply, Reply, State} |" n
489 "%% {reply, Reply, State, Timeout} |" n
490 "%% {noreply, State} |" n
491 "%% {noreply, State, Timeout} |" n
492 "%% {stop, Reason, Reply, State} |" n
493 "%% {stop, Reason, State}" n
494 (erlang-skel-separator-end 2)
495 "handle_call(_Request, _From, State) ->" n
>
497 "{reply, Reply, State}." n
499 (erlang-skel-separator-start 2)
502 "%% Handling cast messages" n
504 "%% @spec handle_cast(Msg, State) -> {noreply, State} |" n
505 "%% {noreply, State, Timeout} |" n
506 "%% {stop, Reason, State}" n
507 (erlang-skel-separator-end 2)
508 "handle_cast(_Msg, State) ->" n
>
509 "{noreply, State}." n
511 (erlang-skel-separator-start 2)
514 "%% Handling all non call/cast messages" n
516 "%% @spec handle_info(Info, State) -> {noreply, State} |" n
517 "%% {noreply, State, Timeout} |" n
518 "%% {stop, Reason, State}" n
519 (erlang-skel-separator-end 2)
520 "handle_info(_Info, State) ->" n
>
521 "{noreply, State}." n
523 (erlang-skel-separator-start 2)
526 "%% This function is called by a gen_server when it is about to" n
527 "%% terminate. It should be the opposite of Module:init/1 and do any" n
528 "%% necessary cleaning up. When it returns, the gen_server terminates" n
529 "%% with Reason. The return value is ignored." n
531 "%% @spec terminate(Reason, State) -> void()" n
532 (erlang-skel-separator-end 2)
533 "terminate(_Reason, _State) ->" n
>
536 (erlang-skel-separator-start 2)
539 "%% Convert process state when code is changed" n
541 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
542 (erlang-skel-separator-end 2)
543 "code_change(_OldVsn, State, _Extra) ->" n
>
546 (erlang-skel-double-separator 2)
547 "%%% Internal functions" n
548 (erlang-skel-double-separator 2)
550 "*The template of a generic server.
551 Please see the function `tempo-define-template'.")
553 (defvar erlang-skel-gen-event
554 '((erlang-skel-include erlang-skel-large-header
)
555 "-behaviour(gen_event)." n
558 "-export([start_link/0, add_handler/0])." n n
560 "%% gen_event callbacks" n
561 "-export([init/1, handle_event/2, handle_call/2, " n
>
562 "handle_info/2, terminate/2, code_change/3])." n n
564 "-record(state, {})." n n
566 (erlang-skel-double-separator 2)
567 "%% gen_event callbacks" n
568 (erlang-skel-double-separator 2) n
569 (erlang-skel-separator-start 2)
571 "%% Creates an event manager" n
573 "%% @spec start_link() -> {ok, Pid} | {error, Error}" n
574 (erlang-skel-separator-end 2)
576 "gen_event:start_link({local, ?SERVER})." n
578 (erlang-skel-separator-start 2)
580 "%% Adds an event handler" n
582 "%% @spec add_handler() -> ok | {'EXIT', Reason} | term()" n
583 (erlang-skel-separator-end 2)
584 "add_handler() ->" n
>
585 "gen_event:add_handler(?SERVER, ?MODULE, [])." n
587 (erlang-skel-double-separator 2)
588 "%% gen_event callbacks" n
589 (erlang-skel-double-separator 2) n
590 (erlang-skel-separator-start 2)
593 "%% Whenever a new event handler is added to an event manager," n
594 "%% this function is called to initialize the event handler." n
596 "%% @spec init(Args) -> {ok, State}" n
597 (erlang-skel-separator-end 2)
601 (erlang-skel-separator-start 2)
604 "%% Whenever an event manager receives an event sent using" n
605 "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is" n
606 "%% called for each installed event handler to handle the event." n
608 "%% @spec handle_event(Event, State) ->" n
610 "%% {swap_handler, Args1, State1, Mod2, Args2} |"n
611 "%% remove_handler" n
612 (erlang-skel-separator-end 2)
613 "handle_event(_Event, State) ->" n
>
616 (erlang-skel-separator-start 2)
619 "%% Whenever an event manager receives a request sent using" n
620 "%% gen_event:call/3,4, this function is called for the specified" n
621 "%% event handler to handle the request." n
623 "%% @spec handle_call(Request, State) ->" n
624 "%% {ok, Reply, State} |" n
625 "%% {swap_handler, Reply, Args1, State1, Mod2, Args2} |" n
626 "%% {remove_handler, Reply}" n
627 (erlang-skel-separator-end 2)
628 "handle_call(_Request, State) ->" n
>
630 "{ok, Reply, State}." n
632 (erlang-skel-separator-start 2)
635 "%% This function is called for each installed event handler when" n
636 "%% an event manager receives any other message than an event or a" n
637 "%% synchronous request (or a system message)." n
639 "%% @spec handle_info(Info, State) ->" n
641 "%% {swap_handler, Args1, State1, Mod2, Args2} |" n
642 "%% remove_handler" n
643 (erlang-skel-separator-end 2)
644 "handle_info(_Info, State) ->" n
>
647 (erlang-skel-separator-start 2)
650 "%% Whenever an event handler is deleted from an event manager, this" n
651 "%% function is called. It should be the opposite of Module:init/1 and" n
652 "%% do any necessary cleaning up." n
654 "%% @spec terminate(Reason, State) -> void()" n
655 (erlang-skel-separator-end 2)
656 "terminate(_Reason, _State) ->" n
>
659 (erlang-skel-separator-start 2)
662 "%% Convert process state when code is changed" n
664 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
665 (erlang-skel-separator-end 2)
666 "code_change(_OldVsn, State, _Extra) ->" n
>
669 (erlang-skel-double-separator 2)
670 "%%% Internal functions" n
671 (erlang-skel-double-separator 2)
673 "*The template of a gen_event.
674 Please see the function `tempo-define-template'.")
676 (defvar erlang-skel-gen-fsm
677 '((erlang-skel-include erlang-skel-large-header
)
678 "-behaviour(gen_fsm)." n n
681 "-export([start_link/0])." n n
683 "%% gen_fsm callbacks" n
684 "-export([init/1, state_name/2, state_name/3, handle_event/3," n
>
685 "handle_sync_event/4, handle_info/3, terminate/3, code_change/4])." n n
687 "-record(state, {})." n n
689 (erlang-skel-double-separator 2)
691 (erlang-skel-double-separator 2) n
692 (erlang-skel-separator-start 2)
694 "%% Creates a gen_fsm process which calls Module:init/1 to" n
695 "%% initialize. To ensure a synchronized start-up procedure, this" n
696 "%% function does not return until Module:init/1 has returned." n
698 "%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}" n
699 (erlang-skel-separator-end 2)
701 "gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], [])." n
703 (erlang-skel-double-separator 2)
704 "%% gen_fsm callbacks" n
705 (erlang-skel-double-separator 2) n
706 (erlang-skel-separator-start 2)
709 "%% Whenever a gen_fsm is started using gen_fsm:start/[3,4] or" n
710 "%% gen_fsm:start_link/[3,4], this function is called by the new" n
711 "%% process to initialize." n
713 "%% @spec init(Args) -> {ok, StateName, State} |" n
714 "%% {ok, StateName, State, Timeout} |" n
716 "%% {stop, StopReason}" n
717 (erlang-skel-separator-end 2)
719 "{ok, state_name, #state{}}." n
721 (erlang-skel-separator-start 2)
724 "%% There should be one instance of this function for each possible" n
725 "%% state name. Whenever a gen_fsm receives an event sent using" n
726 "%% gen_fsm:send_event/2, the instance of this function with the same" n
727 "%% name as the current state name StateName is called to handle" n
728 "%% the event. It is also called if a timeout occurs." n
730 "%% @spec state_name(Event, State) ->" n
731 "%% {next_state, NextStateName, NextState} |" n
732 "%% {next_state, NextStateName, NextState, Timeout} |" n
733 "%% {stop, Reason, NewState}" n
734 (erlang-skel-separator-end 2)
735 "state_name(_Event, State) ->" n
>
736 "{next_state, state_name, State}." n
738 (erlang-skel-separator-start 2)
741 "%% There should be one instance of this function for each possible" n
742 "%% state name. Whenever a gen_fsm receives an event sent using" n
743 "%% gen_fsm:sync_send_event/[2,3], the instance of this function with" n
744 "%% the same name as the current state name StateName is called to" n
745 "%% handle the event." n
747 "%% @spec state_name(Event, From, State) ->" n
748 "%% {next_state, NextStateName, NextState} |"n
749 "%% {next_state, NextStateName, NextState, Timeout} |" n
750 "%% {reply, Reply, NextStateName, NextState} |" n
751 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
752 "%% {stop, Reason, NewState} |" n
753 "%% {stop, Reason, Reply, NewState}" n
754 (erlang-skel-separator-end 2)
755 "state_name(_Event, _From, State) ->" n
>
757 "{reply, Reply, state_name, State}." n
759 (erlang-skel-separator-start 2)
762 "%% Whenever a gen_fsm receives an event sent using" n
763 "%% gen_fsm:send_all_state_event/2, this function is called to handle" n
766 "%% @spec handle_event(Event, StateName, State) ->" n
767 "%% {next_state, NextStateName, NextState} |" n
768 "%% {next_state, NextStateName, NextState, Timeout} |" n
769 "%% {stop, Reason, NewState}" n
770 (erlang-skel-separator-end 2)
771 "handle_event(_Event, StateName, State) ->" n
>
772 "{next_state, StateName, State}." n
774 (erlang-skel-separator-start 2)
777 "%% Whenever a gen_fsm receives an event sent using" n
778 "%% gen_fsm:sync_send_all_state_event/[2,3], this function is called" n
779 "%% to handle the event." n
781 "%% @spec handle_sync_event(Event, From, StateName, State) ->" n
782 "%% {next_state, NextStateName, NextState} |" n
783 "%% {next_state, NextStateName, NextState, Timeout} |" n
784 "%% {reply, Reply, NextStateName, NextState} |" n
785 "%% {reply, Reply, NextStateName, NextState, Timeout} |" n
786 "%% {stop, Reason, NewState} |" n
787 "%% {stop, Reason, Reply, NewState}" n
788 (erlang-skel-separator-end 2)
789 "handle_sync_event(Event, From, StateName, State) ->" n
>
791 "{reply, Reply, StateName, State}." n
793 (erlang-skel-separator-start 2)
796 "%% This function is called by a gen_fsm when it receives any" n
797 "%% message other than a synchronous or asynchronous event" n
798 "%% (or a system message)." n
800 "%% @spec handle_info(Info,StateName,State)->" n
801 "%% {next_state, NextStateName, NextState} |" n
802 "%% {next_state, NextStateName, NextState, Timeout} |" n
803 "%% {stop, Reason, NewState}" n
804 (erlang-skel-separator-end 2)
805 "handle_info(_Info, StateName, State) ->" n
>
806 "{next_state, StateName, State}." n
808 (erlang-skel-separator-start 2)
811 "%% This function is called by a gen_fsm when it is about to" n
812 "%% terminate. It should be the opposite of Module:init/1 and do any" n
813 "%% necessary cleaning up. When it returns, the gen_fsm terminates with" n
814 "%% Reason. The return value is ignored." n
816 "%% @spec terminate(Reason, StateName, State) -> void()" n
817 (erlang-skel-separator-end 2)
818 "terminate(_Reason, _StateName, _State) ->" n
>
821 (erlang-skel-separator-start 2)
824 "%% Convert process state when code is changed" n
826 "%% @spec code_change(OldVsn, StateName, State, Extra) ->" n
827 "%% {ok, StateName, NewState}" n
828 (erlang-skel-separator-end 2)
829 "code_change(_OldVsn, StateName, State, _Extra) ->" n
>
830 "{ok, StateName, State}." n
832 (erlang-skel-double-separator 2)
833 "%%% Internal functions" n
834 (erlang-skel-double-separator 2)
836 "*The template of a gen_fsm.
837 Please see the function `tempo-define-template'.")
839 (defvar erlang-skel-lib
840 '((erlang-skel-include erlang-skel-large-header
)
845 (erlang-skel-double-separator 2)
847 (erlang-skel-double-separator 2) n
848 (erlang-skel-separator-start 2)
851 (erlang-skel-separator-end 2)
853 (erlang-skel-double-separator 2)
854 "%% Internal functions" n
855 (erlang-skel-double-separator 2)
857 "*The template of a library module.
858 Please see the function `tempo-define-template'.")
860 (defvar erlang-skel-corba-callback
861 '((erlang-skel-include erlang-skel-large-header
)
862 "%% Include files" n n
867 "%% Corba callbacks" n
868 "-export([init/1, terminate/2, code_change/3])." n n
870 "-record(state, {})." n n
872 (erlang-skel-double-separator 2)
873 "%% Corba callbacks" n
874 (erlang-skel-double-separator 2) n
875 (erlang-skel-separator-start 2)
878 "%% Initiates the server" n
880 "%% @spec init(Args) -> {ok, State} |" n
881 "%% {ok, State, Timeout} |" n
883 "%% {stop, Reason}" n
884 (erlang-skel-separator-end 2)
888 (erlang-skel-separator-start 2)
891 "%% Shutdown the server" n
893 "%% @spec terminate(Reason, State) -> void()" n
894 (erlang-skel-separator-end 2)
895 "terminate(_Reason, _State) ->" n
>
898 (erlang-skel-separator-start 2)
901 "%% Convert process state when code is changed" n
903 "%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}" n
904 (erlang-skel-separator-end 2)
905 "code_change(_OldVsn, State, _Extra) ->" n
>
908 (erlang-skel-double-separator 2)
909 "%% Internal functions" n
910 (erlang-skel-double-separator 2)
912 "*The template of a library module.
913 Please see the function `tempo-define-template'.")
915 (defvar erlang-skel-ts-test-suite
916 '((erlang-skel-include erlang-skel-large-header
)
917 "%% Note: This directive should only be used in test suites." n
918 "-compile(export_all)." n n
920 "-include(\"test_server.hrl\")." n n
922 "%% Test server callback functions" n
923 (erlang-skel-separator-start 2)
925 "%% Config - [tuple()]" n
926 "%% A list of key/value pairs, holding the test case configuration." n
928 "%% Initiation before the whole suite" n
930 "%% Note: This function is free to add any key/value pairs to the Config" n
931 "%% variable, but should NOT alter/remove any existing entries." n
933 "%% @spec init_per_suite(Config) -> Config" n
934 (erlang-skel-separator-end 2)
935 "init_per_suite(Config) ->" n
>
938 (erlang-skel-separator-start 2)
940 "%% Config - [tuple()]" n
941 "%% A list of key/value pairs, holding the test case configuration." n
943 "%% Cleanup after the whole suite" n
945 "%% @spec end_per_suite(Config) -> _" n
946 (erlang-skel-separator-end 2)
947 "end_per_suite(_Config) ->" n
>
950 (erlang-skel-separator-start 2)
953 "%% Name of the test case that is about to be run." n
954 "%% Config - [tuple()]" n
955 "%% A list of key/value pairs, holding the test case configuration." n
957 "%% Initiation before each test case" n
959 "%% Note: This function is free to add any key/value pairs to the Config" n
960 "%% variable, but should NOT alter/remove any existing entries." n
962 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
963 (erlang-skel-separator-end 2)
964 "init_per_testcase(_TestCase, Config) ->" n
>
967 (erlang-skel-separator-start 2)
970 "%% Name of the test case that is about to be run." n
971 "%% Config - [tuple()]" n
972 "%% A list of key/value pairs, holding the test case configuration." n
974 "%% Cleanup after each test case" n
976 "%% @spec end_per_testcase(TestCase, Config) -> _" n
977 (erlang-skel-separator-end 2)
978 "end_per_testcase(_TestCase, _Config) ->" n
>
981 (erlang-skel-separator-start 2)
983 "%% Clause - atom() - suite | doc" n
984 "%% TestCases - [Case]" n
986 "%% Name of a test case." n
988 "%% Returns a list of all test cases in this test suite" n
990 "%% @spec all(Clause) -> TestCases" n
991 (erlang-skel-separator-end 2)
993 "[\"Describe the main purpose of this suite\"];" n n
997 "%% Test cases starts here." n
998 (erlang-skel-separator-start 2)
999 "test_case(doc) ->" n
>
1000 "[\"Describe the main purpose of test case\"];" n n
1001 "test_case(suite) ->" n
>
1003 "test_case(Config) when is_list(Config) ->" n
>
1006 "*The template of a library module.
1007 Please see the function `tempo-define-template'.")
1009 (defvar erlang-skel-ct-test-suite
1010 '((erlang-skel-include erlang-skel-large-header
)
1011 "-suite_defaults([{timetrap, {minutes, 10}}])." n n
1013 "%% Note: This directive should only be used in test suites." n
1014 "-compile(export_all)." n n
1016 "-include(\"ct.hrl\")." n n
1018 "%% Test server callback functions" n
1019 (erlang-skel-separator-start 2)
1021 "%% Config - [tuple()]" n
1022 "%% A list of key/value pairs, holding the test case configuration." n
1024 "%% Initiation before the whole suite" n
1026 "%% Note: This function is free to add any key/value pairs to the Config" n
1027 "%% variable, but should NOT alter/remove any existing entries." n
1029 "%% @spec init_per_suite(Config) -> Config" n
1030 (erlang-skel-separator-end 2)
1031 "init_per_suite(Config) ->" n
>
1034 (erlang-skel-separator-start 2)
1036 "%% Config - [tuple()]" n
1037 "%% A list of key/value pairs, holding the test case configuration." n
1039 "%% Cleanup after the whole suite" n
1041 "%% @spec end_per_suite(Config) -> _" n
1042 (erlang-skel-separator-end 2)
1043 "end_per_suite(_Config) ->" n
>
1046 (erlang-skel-separator-start 2)
1048 "%% Case - atom()" n
1049 "%% Name of the test case that is about to be run." n
1050 "%% Config - [tuple()]" n
1051 "%% A list of key/value pairs, holding the test case configuration." n
1053 "%% Initiation before each test case" n
1055 "%% Note: This function is free to add any key/value pairs to the Config" n
1056 "%% variable, but should NOT alter/remove any existing entries." n
1057 "%% Initiation before each test case" n
1059 "%% @spec init_per_testcase(TestCase, Config) -> Config" n
1060 (erlang-skel-separator-end 2)
1061 "init_per_testcase(_TestCase, Config) ->" n
>
1064 (erlang-skel-separator-start 2)
1066 "%% Case - atom()" n
1067 "%% Name of the test case that is about to be run." n
1068 "%% Config - [tuple()]" n
1069 "%% A list of key/value pairs, holding the test case configuration." n
1071 "%% Cleanup after each test case" n
1073 "%% @spec end_per_testcase(TestCase, Config) -> _" n
1074 (erlang-skel-separator-end 2)
1075 "end_per_testcase(_TestCase, _Config) ->" n
>
1078 (erlang-skel-separator-start 2)
1080 "%% TestCases - [Case]" n
1081 "%% Case - atom()" n
1082 "%% Name of a test case." n
1084 "%% Returns a list of all test cases in this test suite" n
1086 "%% @spec all() -> TestCases" n
1087 (erlang-skel-separator-end 2)
1091 "%% Test cases starts here." n
1092 (erlang-skel-separator-start 2)
1093 "test_case() ->" n
>
1094 "[{doc, \"Describe the main purpose of this test case\"}]." n n
1095 "test_case(Config) when is_list(Config) ->" n
>
1098 "*The template of a library module.
1099 Please see the function `tempo-define-template'.")
1103 ;; This code is based on the package `tempo' which is part of modern
1104 ;; Emacsen. (GNU Emacs 19.25 (?) and XEmacs 19.14.)
1106 (defun erlang-skel-init ()
1107 "Generate the skeleton functions and menu items.
1108 The variable `erlang-skel' contains the name and descriptions of
1111 The skeleton routines are based on the `tempo' package. Should this
1112 package not be present, this function does nothing."
1117 (if (featurep 'tempo
)
1118 (let ((skel erlang-skel
)
1121 (cond ((null (car skel
))
1122 (setq menu
(cons nil menu
)))
1124 (funcall (symbol-function 'tempo-define-template
)
1125 (concat "erlang-" (nth 1 (car skel
)))
1126 ;; The tempo template used contains an `include'
1127 ;; function call only, hence changes to the
1128 ;; variables describing the templates take effect
1130 (list (list 'erlang-skel-include
(nth 2 (car skel
))))
1132 (setq menu
(cons (erlang-skel-make-menu-item
1133 (car skel
)) menu
))))
1134 (setq skel
(cdr skel
)))
1135 (setq erlang-menu-skel-items
1136 (list nil
(list "Skeletons" (nreverse menu
))))
1137 (setq erlang-menu-items
1138 (erlang-menu-add-above 'erlang-menu-skel-items
1139 'erlang-menu-version-items
1141 (erlang-menu-init))))
1143 (defun erlang-skel-make-menu-item (skel)
1144 (let ((func (intern (concat "tempo-template-erlang-" (nth 1 skel
)))))
1145 (cond ((null (nth 3 skel
))
1146 (list (car skel
) func
))
1152 (list 'quote
(nth 3 skel
))
1153 (list 'quote func
))))))))
1155 ;; Functions designed to be added to the skeleton menu.
1156 ;; (Not normally used)
1157 (defun erlang-skel-insert (func)
1158 "Insert skeleton generated by FUNC and goto first tempo mark."
1159 (save-excursion (funcall func
))
1160 (funcall (symbol-function 'tempo-forward-mark
)))
1162 (defun erlang-skel-header (func)
1163 "Insert the header generated by FUNC at the beginning of the buffer."
1164 (goto-char (point-min))
1165 (save-excursion (funcall func
))
1166 (funcall (symbol-function 'tempo-forward-mark
)))
1169 ;; Functions used inside the skeleton descriptions.
1170 (defun erlang-skel-skip-blank ()
1171 (skip-chars-backward " \t")
1174 (defun erlang-skel-include (&rest args
)
1175 "Include a template inside another template.
1177 Example of use, assuming that `erlang-skel-func' is defined:
1179 (defvar foo-skeleton '(\"%%% New function:\"
1180 (erlang-skel-include erlang-skel-func)))
1182 Technically, this function returns the `tempo' attribute`(l ...)' which
1183 can contain other `tempo' attributes. Please see the function
1184 `tempo-define-template' for a description of the `(l ...)' attribute."
1188 (setq entry
(car args
))
1190 (setq res
(cons (car entry
) res
))
1191 (setq entry
(cdr entry
)))
1192 (setq args
(cdr args
)))
1193 (cons 'l
(nreverse res
))))
1195 (defun erlang-skel-separator (&optional percent
)
1196 "Return a comment separator."
1197 (let ((percent (or percent
3)))
1198 (concat (make-string percent ?%
)
1199 (make-string (- 70 percent
) ?-
)
1202 (defun erlang-skel-separator-start (&optional percent
)
1203 "Return a comment separator or an empty string if they are configured off."
1204 (if erlang-skel-use-separators
1205 (erlang-skel-separator percent
)
1208 (defun erlang-skel-separator-end (&optional percent
)
1209 "Return a comment separator to end a function comment block or an empty string
1210 if they are configured off."
1211 (if erlang-skel-use-separators
1212 (concat "%% @end\n" (erlang-skel-separator percent
))
1215 (defun erlang-skel-double-separator (&optional percent
)
1216 "Return a comment separator."
1217 (let ((percent (or percent
3)))
1218 (concat (make-string percent ?%
)
1219 (make-string (- 70 percent
) ?
=)
1222 (defun erlang-skel-dd-mmm-yyyy ()
1223 "Return the current date as a string in \"DD Mon YYYY\" form.
1224 The first character of DD is space if the value is less than 10."
1225 (let ((date (current-time-string)))
1227 (string-to-int (substring date
8 10))
1228 (substring date
4 7)
1229 (substring date -
4))))
1232 ;; coding: iso-8859-1
1235 ;;; erlang.el ends here