{
    "module header": {
        "prefix" : "erl-module-header",
        "description" : "Insert module header",
        "body" : [
            "%%% @author ${1:Author_Name} <${2:Author_Email}>",
            "%%% @copyright (C) $CURRENT_YEAR, $1",
            "%%% @doc $0",
            "%%%",
            "%%% @end",
            "%%% Created : $CURRENT_DATE $CURRENT_MONTH_NAME_SHORT $CURRENT_YEAR by $1 <$2>",
            "-module(${3:Module_Name}).",
            ""
        ]
    },

    "module header (large)": {
        "prefix" : "erl-module-header-large",
        "description" : "Insert large module header",
        "body" : [
            "%%%-------------------------------------------------------------------",
            "%%% @author ${1:Author_Name} <${2:Author_Email}>",
            "%%% @copyright (C) $CURRENT_YEAR, $1",
            "%%% @doc $0",
            "%%%",
            "%%% @end",
            "%%% Created : $CURRENT_DATE $CURRENT_MONTH_NAME_SHORT $CURRENT_YEAR by $1 <$2>",
            "%%%-------------------------------------------------------------------",
            "-module(${3:Module_Name}).",
            ""
        ]
    },

    "gen_server behavior": {
        "prefix": "erl-gen_server",
        "description": "Insert an empty gen_server",
        "body": [
            "-behaviour(gen_server).",
            "",
            "%% API",
            "-export([start/1, stop/1, start_link/1]).",
            "-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).",
            "-record(state, {dummy}).",
            "start(Name) ->",
            "    $0_sup:start_child(Name).",
            "",
            "stop(Name) ->",
            "    gen_server:call(Name, stop).",
            "",
            "start_link(Name) ->",
            "    gen_server:start_link({local, Name}, ?MODULE, [], []).",
            "",
            "init(_Args) ->",
            "    {ok, #state{dummy=1}}.",
            "",
            "handle_call(stop, _From, State) ->",
            "    {stop, normal, stopped, State};",
            "",
            "handle_call(_Request, _From, State) ->",
            "    {reply, ok, State}.",
            "",
            "handle_cast(_Msg, State) ->",
            "    {noreply, State}.",
            "",
            "handle_info(_Info, State) ->",
            "    {noreply, State}.",
            "",
            "terminate(_Reason, _State) ->",
            "    ok.",
            "",
            "code_change(_OldVsn, State, _Extra) ->",
            "    {ok, State}.",
            ""
        ]
    },

    "gen_server behavior (large)": {
        "prefix": "erl-gen_server-large",
        "description": "Insert an empty gen_server with all the callbacks and decoration",
        "body": [
            "-behaviour(gen_server).",
            "",
            "%% API",
            "-export([start_link/0, stop/0, get_state/0]).",
            "",
            "%% gen_server callbacks",
            "-export([init/1, handle_call/3, handle_cast/2, handle_info/2,",
            "         terminate/2, code_change/3, format_status/2]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-define(SERVER, ?MODULE).",
            "",
            "-record(state, {}).",
            "",
            "%%%===================================================================",
            "%%% API",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc Starts the server",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_link() -> {ok, Pid :: pid()} |",
            "                      {error, Error :: {already_started, pid()}} |",
            "                      {error, Error :: term()} |",
            "                      ignore.",
            "start_link() ->",
            "    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc Stops the server",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec stop() -> ok.",
            "stop() ->",
            "    gen_server:stop(?SERVER).",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc Return the server state as a map",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec get_state() -> map().",
            "get_state() ->",
            "    maps:from_list(lists:zip(record_info(fields, state),",
            "                             tl(tuple_to_list(sys:get_state(?SERVER))))).",
            "",
            "%%%===================================================================",
            "%%% gen_server callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc Initializes the server",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec init(Args :: term()) -> {ok, State :: term()} |",
            "                              {ok, State :: term(), Timeout :: timeout()} |",
            "                              {ok, State :: term(), hibernate} |",
            "                              {stop, Reason :: term()} |",
            "                              ignore.",
            "init([]) ->",
            "    process_flag(trap_exit, true),",
            "    {ok, #state{}}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc Handling call messages",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_call(Request :: term(), From :: {pid(), term()}, State::term()) ->",
            "        {reply, Reply :: term(), NewState :: term()} |",
            "        {reply, Reply :: term(), NewState :: term(), Timeout :: timeout()} |",
            "        {reply, Reply :: term(), NewState :: term(), hibernate} |",
            "        {noreply, NewState :: term()} |",
            "        {noreply, NewState :: term(), Timeout :: timeout()} |",
            "        {noreply, NewState :: term(), hibernate} |",
            "        {stop, Reason :: term(), Reply :: term(), NewState :: term()} |",
            "        {stop, Reason :: term(), NewState :: term()}.",
            "handle_call(_Request, _From, State) ->",
            "    Reply = ok,",
            "    {reply, Reply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc Handling cast messages",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_cast(Request :: term(), State :: term()) ->",
            "        {noreply, NewState :: term()} |",
            "        {noreply, NewState :: term(), Timeout :: timeout()} |",
            "        {noreply, NewState :: term(), hibernate} |",
            "        {stop, Reason :: term(), NewState :: term()}.",
            "handle_cast(_Request, State) ->",
            "    {noreply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc Handling all non call/cast messages",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_info(Info :: timeout | term(), State :: term()) ->",
            "        {noreply, NewState :: term()} |",
            "        {noreply, NewState :: term(), Timeout :: timeout()} |",
            "        {noreply, NewState :: term(), hibernate} |",
            "        {stop, Reason :: normal | term(), NewState :: term()}.",
            "handle_info(_Info, State) ->",
            "    {noreply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc This function is called by a gen_server when it is about to",
            "%% terminate. It should be the opposite of Module:init/1 and do any",
            "%% necessary cleaning up. When it returns, the gen_server terminates",
            "%% with Reason. The return value is ignored.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec terminate(Reason, State :: term()) -> any()",
            "      when Reason :: normal | shutdown | {shutdown, term()} | term().",
            "terminate(_Reason, _State) ->",
            "    ok.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc Convert process state when code is changed",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec code_change(OldVsn, State :: term(), Extra :: term()) ->",
            "        {ok, NewState :: term()} |",
            "        {error, Reason :: term()}",
            "      when OldVsn :: term() | {down, term()}.",
            "code_change(_OldVsn, State, _Extra) ->",
            "    {ok, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc This function is called for changing the form and appearance",
            "%% of gen_server status when it is returned from sys:get_status/1,2",
            "%% or when it appears in termination error logs.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec format_status(Opt :: normal | terminate, Status :: list()) ->",
            "        Status :: term().",
            "format_status(_Opt, Status) ->",
            "    Status.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            "",
        ]
    },

    "application behavior (large)" : {
        "prefix" : "erl-application-large",
        "description" : "Insert an empty application with all the callbacks and decoration",
        "body" : [
            "-behaviour(application).",
            "",
            "%% Application callbacks",
            "-export([start/2, start_phase/3, stop/1, prep_stop/1, config_change/3]).",
            "",
            "%%%===================================================================",
            "%%% Application callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc This function is called whenever an application is started using",
            "%% `application:start/[1,2]', and should start the processes of the",
            "%% application. If the application is structured according to the OTP",
            "%% design principles as a supervision tree, this means starting the",
            "%% top supervisor of the tree.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start(StartType :: normal |",
            "                         {takeover, Node :: node()} |",
            "                         {failover, Node :: node()},",
            "            StartArgs :: term()) ->",
            "          {ok, Pid :: pid()} |",
            "          {ok, Pid :: pid(), State :: term()} |",
            "          {error, Reason :: term()}.",
            "start(_StartType, _StartArgs) ->",
            "    case ${1:Top_Supervisor}:start_link() of",
            "        {ok, Pid} ->",
            "            {ok, Pid};",
            "        Error ->",
            "            Error",
            "    end.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc Top supervisor of the tree.",
            "%% Starts an application with included applications, when",
            "%% synchronization is needed between processes in the different",
            "%% applications during startup.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_phase(Phase :: atom(),",
            "                  StartType :: normal |",
            "                               {takeover, Node :: node()} |",
            "                               {failover, Node :: node()},",
            "                  PhaseArgs :: term()) -> ok | {error, Reason :: term()}.",
            "start_phase(_Phase, _StartType, _PhaseArgs) ->",
            "    ok.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc This function is called whenever an application has stopped. It",
            "%% is intended to be the opposite of `?MODULE:start/2' and should do",
            "%% any necessary cleaning up. The return value is ignored.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec stop(State :: term()) -> any().",
            "stop(_State) ->",
            "    ok.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc This function is called when an application is about to be stopped,",
            "%% before shutting down the processes of the application.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec prep_stop(State :: term()) -> NewState :: term().",
            "prep_stop(State) ->",
            "    State.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc This function is called by an application after a code replacement,",
            "%% if the configuration parameters have changed.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec config_change(Changed :: [{Par :: atom(), Val :: term()}],",
            "                    New :: [{Par :: atom(), Val :: term()}],",
            "                    Removed :: [Par :: atom()]) -> ok.",
            "config_change(_Changed, _New, _Removed) ->",
            "    ok.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            ""
        ]
    },

    "supervisor behavior" : {
        "prefix" : "erl-supervisor",
        "description" : "Insert an example of supervisor",
        "body"  : [
            "-behaviour(supervisor).",
            "",
            "%% API",
            "-export([start_link/0]).",
            "-export([init/1]).",
            "",
            "start_link() ->",
            "    supervisor:start_link({local, ?MODULE}, ?MODULE, []).",
            "",
            "init(_Args) ->",
            "    SupervisorSpecification = #{",
            "        strategy => one_for_one, % one_for_one | one_for_all | rest_for_one | simple_one_for_one",
            "        intensity => 10,",
            "        period => 60},",
            "",
            "    ChildSpecifications = [",
            "        #{",
            "            id => ${1:A_Name},",
            "            start => {${2:A_Worker_Module}, start_link, []},",
            "            restart => permanent, % permanent | transient | temporary",
            "            shutdown => 2000, % use 'infinity' for supervisor child",
            "            type => worker, % worker | supervisor",
            "            modules => [$2]",
            "        }",
            "    ],",
            "",
            "    {ok, {SupervisorSpecification, ChildSpecifications}}.",
            ""
        ]
    },

    "supervisor behavior (large)" : {
        "prefix" : "erl-supervisor-large",
        "description" : "Insert an example of supervisor with all the callbacks and decoration",
        "body"  : [
            "-behaviour(supervisor).",
            "",
            "%% API",
            "-export([start_link/0]).",
            "",
            "%% Supervisor callbacks",
            "-export([init/1]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-define(SERVER, ?MODULE).",
            "",
            "%%%===================================================================",
            "%%% API functions",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc Starts the supervisor",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_link() -> {ok, Pid :: pid()} |",
            "                      {error, {already_started, Pid :: pid()}} |",
            "                      {error, {shutdown, term()}} |",
            "                      {error, term()} |",
            "                      ignore.",
            "start_link() ->",
            "    supervisor:start_link({local, ?SERVER}, ?MODULE, []).",
            "",
            "%%%===================================================================",
            "%%% Supervisor callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Whenever a supervisor is started using supervisor:start_link/[2,3],",
            "%% this function is called by the new process to find out about",
            "%% restart strategy, maximum restart intensity, and child",
            "%% specifications.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec init(Args :: term()) ->",
            "          {ok, {SupFlags :: supervisor:sup_flags(),",
            "                [ChildSpec :: supervisor:child_spec()]}} |",
            "          ignore.",
            "init([]) ->",
            "",
            "    SupFlags = #{",
            "        strategy => one_for_one, % one_for_one | one_for_all | rest_for_one | simple_one_for_one",
            "        intensity => 10,",
            "        period => 60",
            "    },",
            "",
            "    ChildSpecifications = [",
            "        #{id => ${1:A_Name},",
            "          start => {${2:A_Worker_Module}, start_link, []},",
            "          restart => permanent, % permanent | transient | temporary",
            "          shutdown => 5000, % use 'infinity' for supervisor child",
            "          type => worker,",
            "          modules => [$2]}",
            "    ],",
            "",
            "    {ok, {SupFlags, ChildSpecifications}}.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            ""
        ]
    },

    "supervisor_bridge behavior (large)" : {
        "prefix" : "erl-supervisor_bridge-large",
        "description" : "Insert an example of supervisor_bridge with all the callbacks and decoration",
        "body"  : [
            "-behaviour(supervisor_bridge).",
            "",
            "%% API",
            "-export([start_link/0]).",
            "",
            "%% supervisor_bridge callbacks",
            "-export([init/1, terminate/2]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-define(SERVER, ?MODULE).",
            "",
            "-record(state, {}).",
            "",
            "%%%===================================================================",
            "%%% API",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc",
            "%% Starts the supervisor bridge",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_link() -> {ok, Pid :: pid()} |",
            "                      {error, {already_started, Pid :: pid()}} |",
            "                      {error, term()} |",
            "                      ignore.",
            "start_link() ->",
            "    supervisor_bridge:start_link({local, ?SERVER}, ?MODULE, []).",
            "",
            "%%%===================================================================",
            "%%% supervisor_bridge callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Creates a supervisor_bridge process, linked to the calling process,",
            "%% which calls Module:init/1 to start the subsystem. To ensure a",
            "%% synchronized start-up procedure, this function does not return",
            "%% until Module:init/1 has returned.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec init(Args :: term()) -> {ok, Pid :: pid(), State :: term()} |",
            "                              {error, Error :: term()} |",
            "                              ignore.",
            "init([]) ->",
            "    case ${1:A_Worker_Module}:start_link() of",
            "        {ok, Pid} ->",
            "            {ok, Pid, #state{}};",
            "        Error ->",
            "            Error",
            "    end.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% This function is called by the supervisor_bridge when it is about",
            "%% to terminate. It should be the opposite of Module:init/1 and stop",
            "%% the subsystem and do any necessary cleaning up.The return value is",
            "%% ignored.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec terminate(Reason :: shutdown | term(), State :: term()) -> any().",
            "terminate(_Reason, _State) ->",
            "    $1:stop(),",
            "    ok.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            "",
        ]
    },

    "gen_fsm behavior (DEPRECATED)" : {
        "prefix" : "erl-gen_fsm",
        "description" : "DEPRECATED! Insert an empty gen_fsm. Deprecated and replaced by gen_statem.",
        "body" : [
            "-behaviour(gen_fsm).",
            "",
            "%% API",
            "-export([start/1, stop/1, start_link/1]).",
            "-export([init/1, handle_event/3, handle_sync_event/4, handle_info/3,",
            "         terminate/3, code_change/4,",
            "         dummy_state/2, dummy_state/3]).",
            "",
            "-record(state, {dummy}).",
            "",
            "start(Name) ->",
            "    gen_fsm:start(?MODULE, [Name], []).",
            "",
            "stop(FsmRef) ->",
            "    gen_fsm:stop(FsmRef).",
            "",
            "start_link(Name) ->",
            "    gen_fsm:start_link({local, Name}, ?MODULE, [Name], []).",
            "",
            "init(_Args) ->",
            "    {ok, dummy_state, #state{dummy=1}}.",
            "",
            "dummy_state(_Event, StateData) ->",
            "    {next_state, dummy_state, StateData}.",
            "",
            "dummy_state(_Event, From, StateData) ->",
            "    gen_fsm:reply(From, ok),",
            "    {next_state, dummy_state, StateData}.",
            "",
            "handle_event(_Event, _StateName, StateData) ->",
            "    {next_state, dummy_state, StateData}.",
            "",
            "handle_sync_event(_Event, From, _StateName, StateData) ->",
            "    gen_fsm:reply(From, ok),",
            "    {next_state, dummy_state, StateData}.",
            "",
            "handle_info(_Info, _StateName, StateData) ->",
            "    {next_state, dummy_state, StateData}.",
            "",
            "terminate(_Reason, _StateName, _StateData) ->",
            "    ok.",
            "",
            "code_change(_OldVersion, _StateName, StateData, _Extra) ->",
            "    {ok, dummy_state, StateData}.",
            ""
        ]
    },

    "gen_event behavior" : {
        "prefix" : "erl-gen_event",
        "description" : "Insert an empty gen_event",
        "body"  : [
            "-behaviour(gen_event).",
            "",
            "-export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]).",
            "",
            "init(_Args) ->",
            "    {ok, []}.",
            "",
            "handle_event(_Event, State) ->",
            "    {ok, State}.",
            "",
            "handle_call(_Request, State) ->",
            "    {ok, no_reply, State}.",
            "",
            "handle_info(_Info, State) ->",
            "    {ok, State}.",
            "",
            "terminate(_Args, _State) ->",
            "    ok.",
            "",
            "code_change(_OldVsn, State, _Extra) ->",
            "    {ok, State}.",
            ""
        ]
    },

    "gen_event behavior (large)" : {
        "prefix" : "erl-gen_event-large",
        "description" : "Insert an empty gen_event with all the callbacks and decoration",
        "body"  : [
            "-behaviour(gen_event).",
            "",
            "%% API",
            "-export([start_link/0, add_handler/0]).",
            "",
            "%% gen_event callbacks",
            "-export([init/1, handle_event/2, handle_call/2, handle_info/2,",
            "         terminate/2, code_change/3, format_status/2]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-define(SERVER, ?MODULE).",
            "",
            "-record(state, {}).",
            "",
            "%%%===================================================================",
            "%%% API",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc",
            "%% Creates an event manager",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_link() -> {ok, Pid :: pid()} |",
            "                      {error, Error :: {already_started, pid()} | term()}.",
            "start_link() ->",
            "    gen_event:start_link({local, ?SERVER}).",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc",
            "%% Adds an event handler",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec add_handler() -> ok | {'EXIT', Reason :: term()} | term().",
            "add_handler() ->",
            "    gen_event:add_handler(?SERVER, ?MODULE, []).",
            "",
            "%%%===================================================================",
            "%%% gen_event callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Whenever a new event handler is added to an event manager,",
            "%% this function is called to initialize the event handler.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec init(Args :: term() | {Args :: term(), Term :: term()}) ->",
            "        {ok, State :: term()} |",
            "        {ok, State :: term(), hibernate} |",
            "        {error, Reason :: term()}.",
            "init([]) ->",
            "    {ok, #state{}}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Whenever an event manager receives an event sent using",
            "%% gen_event:notify/2 or gen_event:sync_notify/2, this function is",
            "%% called for each installed event handler to handle the event.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_event(Event :: term(), State :: term()) ->",
            "        {ok, NewState :: term()} |",
            "        {ok, NewState :: term(), hibernate} |",
            "        remove_handler |",
            "        {swap_handler, Args1 :: term(), NewState :: term(),",
            "         Handler2 :: atom() | {atom(), term()} , Args2 :: term()}.",
            "handle_event(_Event, State) ->",
            "    {ok, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Whenever an event manager receives a request sent using",
            "%% gen_event:call/3,4, this function is called for the specified",
            "%% event handler to handle the request.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_call(Request :: term(), State :: term()) ->",
            "        {ok, Reply :: term(), NewState :: term()} |",
            "        {ok, Reply :: term(), NewState :: term(), hibernate} |",
            "        {remove_handler, Reply :: term()} |",
            "        {swap_handler, Reply :: term(), Args1 :: term(), NewState :: term(),",
            "         Handler2 :: atom() | {atom(), term()}, Args2 :: term()}.",
            "handle_call(_Request, State) ->",
            "    Reply = ok,",
            "    {ok, Reply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% This function is called for each installed event handler when",
            "%% an event manager receives any other message than an event or a",
            "%% synchronous request (or a system message).",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_info(Info :: term(), State :: term()) ->",
            "        {ok, NewState :: term()} |",
            "        {ok, NewState :: term(), hibernate} |",
            "        remove_handler |",
            "        {swap_handler, Args1 :: term(), NewState :: term(),",
            "         Handler2 :: atom() | {atom(), term()}, Args2 :: term()}.",
            "handle_info(_Info, State) ->",
            "    {ok, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Whenever an event handler is deleted from an event manager, this",
            "%% function is called. It should be the opposite of Module:init/1 and",
            "%% do any necessary cleaning up.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec terminate(Arg :: {stop, Reason :: term()} |",
            "                       stop |",
            "                       remove_handler |",
            "                       {error, {'EXIT', Reason :: term()}} |",
            "                       {error, Term :: term()} |",
            "                       term(),",
            "                State :: term()) -> any().",
            "terminate(_Arg, _State) ->",
            "    ok.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Convert process state when code is changed",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec code_change(OldVsn :: term() | {down, term()},",
            "                  State :: term(),",
            "                  Extra :: term()) -> {ok, NewState :: term()}.",
            "code_change(_OldVsn, State, _Extra) ->",
            "    {ok, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% This function is called for changing the form and appearance",
            "%% of gen_event status when it is returned from sys:get_status/1,2",
            "%% or when it appears in termination error logs.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec format_status(Opt :: normal | terminate,",
            "                    Status :: list()) -> Status :: term().",
            "format_status(_Opt, Status) ->",
            "    Status.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            "",
        ]
    },

    "gen_statem behavior (handle_event/4)" : {
        "prefix" : "erl-gen_statem-handle_event",
        "description" : "Insert an empty gen_statem with handle_event/4 function",
        "body"  : [
            "-behaviour(gen_statem).",
            "",
            "-export([stop/0, start_link/0]).",
            "-export([init/1, callback_mode/0, handle_event/4, terminate/3, code_change/4]).",
            "",
            "stop() ->",
            "    gen_statem:stop(?MODULE).",
            "",
            "start_link() ->",
            "    gen_statem:start_link({local, ?MODULE}, ?MODULE, [], []).",
            "",
            "init(_Args) ->",
            "    {ok, state, []}.",
            "",
            "%% state_functions | handle_event_function | [_, state_enter].",
            "callback_mode() ->",
            "    handle_event_function.",
            "",
            "handle_event(enter, _OldState, _State, _Data) ->",
            "    keep_state_and_data;",
            "",
            "handle_event(_EventType, _EventContent, _State, _Data) ->",
            "    keep_state_and_data.",
            "",
            "terminate(_Reason, _State, _Data) ->",
            "    ok.",
            "",
            "code_change(_OldVsn, State, Data, _Extra) ->",
            "    {ok, State, Data}.",
            ""
        ]
    },

    "gen_statem behavior (handle_event/4, large)" : {
        "prefix" : "erl-gen_statem-handle_event-large",
        "description" : "Insert an empty gen_statem with handle_event/4 function, all the callbacks and decoration",
        "body": [
            "-behaviour(gen_statem).",
            "",
            "%% API",
            "-export([start_link/0]).",
            "",
            "%% gen_statem callbacks",
            "-export([callback_mode/0, init/1, terminate/3, code_change/4]).",
            "-export([handle_event/4]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-define(SERVER, ?MODULE).",
            "",
            "-record(data, {}).",
            "",
            "%%%===================================================================",
            "%%% API",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc",
            "%% Creates a gen_statem process which calls Module:init/1 to",
            "%% initialize. To ensure a synchronized start-up procedure, this",
            "%% function does not return until Module:init/1 has returned.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_link() -> {ok, Pid :: pid()} |",
            "                      ignore |",
            "                      {error, Error :: term()}.",
            "start_link() ->",
            "    gen_statem:start_link({local, ?SERVER}, ?MODULE, [], []).",
            "",
            "%%%===================================================================",
            "%%% gen_statem callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Define the callback_mode() for this callback module.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec callback_mode() -> gen_statem:callback_mode_result().",
            "callback_mode() -> handle_event_function.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Whenever a gen_statem is started using gen_statem:start/[3,4] or",
            "%% gen_statem:start_link/[3,4], this function is called by the new",
            "%% process to initialize.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec init(Args :: term()) -> gen_statem:init_result(term()).",
            "init([]) ->",
            "    process_flag(trap_exit, true),",
            "    {ok, state_name, #data{}}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% This function is called for every event a gen_statem receives.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_event('enter',",
            "                   OldState :: term(),",
            "                   State :: term(),",
            "                   Data :: term()) ->",
            "          gen_statem:state_enter_result(term());",
            "                  (gen_statem:event_type(),",
            "                   Msg :: term(),",
            "                   State :: term(),",
            "                   Data :: term()) ->",
            "          gen_statem:event_handler_result(term()).",
            "handle_event({call,From}, _Msg, State, Data) ->",
            "    {next_state, State, Data, [{reply,From,ok}]}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% This function is called by a gen_statem when it is about to",
            "%% terminate. It should be the opposite of Module:init/1 and do any",
            "%% necessary cleaning up. When it returns, the gen_statem terminates with",
            "%% Reason. The return value is ignored.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec terminate(Reason :: term(), State :: term(), Data :: term()) -> any().",
            "terminate(_Reason, _State, _Data) ->",
            "    void.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Convert process state when code is changed",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec code_change(OldVsn :: term() | {down,term()},",
            "                  State :: term(),",
            "                  Data :: term(),",
            "                  Extra :: term()) ->",
            "          {ok, NewState :: term(), NewData :: term()} |",
            "          (Reason :: term()).",
            "code_change(_OldVsn, State, Data, _Extra) ->",
            "    {ok, State, Data}.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            ""
        ]
    },

    "gen_statem behavior (StateName/3)" : {
        "prefix" : "erl-gen_statem-state-name",
        "description" : "Insert an empty gen_statem with StateName/3 functions",
        "body": [
            "-behaviour(gen_statem).",
            "",
            "-export([start_link/0, stop/0]).",
            "-export([callback_mode/0, init/1, terminate/3, code_change/4]).",
            "-export([$1/3]).",
            "",
            "-define(SERVER, ?MODULE).",
            "",
            "-record(data, {}).",
            "",
            "start_link() ->",
            "    gen_statem:start_link({local, ?SERVER}, ?MODULE, [], []).",
            "",
            "stop() ->",
            "    gen_statem:stop(?MODULE).",
            "",
            "%% state_functions | handle_event_function | [_, state_enter].",
            "callback_mode() -> state_functions.",
            "",
            "init([]) ->",
            "    process_flag(trap_exit, true),",
            "    {ok, ${1:state_name}, #data{}}.",
            "",
            "$1({call,Caller}, _Msg, Data) ->",
            "    {next_state, $1, Data, [{reply,Caller,ok}]}.",
            "",
            "terminate(_Reason, _State, _Data) ->",
            "    void.",
            "",
            "code_change(_OldVsn, State, Data, _Extra) ->",
            "    {ok, State, Data}.",
            "",
        ]
    },

    "gen_statem behavior (StateName/3, large)" : {
        "prefix" : "erl-gen_statem-state-name-large",
        "description" : "Insert an empty gen_statem with StateName/3 functions, all the callbacks and decoration",
        "body": [
            "-behaviour(gen_statem).",
            "",
            "%% API",
            "-export([start_link/0]).",
            "",
            "%% gen_statem callbacks",
            "-export([callback_mode/0, init/1, terminate/3, code_change/4]).",
            "-export([$1/3]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-define(SERVER, ?MODULE).",
            "",
            "-record(data, {}).",
            "",
            "%%%===================================================================",
            "%%% API",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc",
            "%% Creates a gen_statem process which calls Module:init/1 to",
            "%% initialize. To ensure a synchronized start-up procedure, this",
            "%% function does not return until Module:init/1 has returned.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_link() -> {ok, Pid :: pid()} |",
            "                      ignore |",
            "                      {error, Error :: term()}.",
            "start_link() ->",
            "    gen_statem:start_link({local, ?SERVER}, ?MODULE, [], []).",
            "",
            "%%%===================================================================",
            "%%% gen_statem callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Define the callback_mode() for this callback module.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec callback_mode() -> gen_statem:callback_mode_result().",
            "callback_mode() -> state_functions.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Whenever a gen_statem is started using gen_statem:start/[3,4] or",
            "%% gen_statem:start_link/[3,4], this function is called by the new",
            "%% process to initialize.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec init(Args :: term()) -> gen_statem:init_result(atom()).",
            "init([]) ->",
            "    process_flag(trap_exit, true),",
            "    {ok, ${1:state_name}, #data{}}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% There should be one function like this for each state name.",
            "%% Whenever a gen_statem receives an event, the function",
            "%% with the name of the current state (StateName)",
            "%% is called to handle the event.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec $1('enter',",
            "                 OldState :: atom(),",
            "                 Data :: term()) ->",
            "          gen_statem:state_enter_result('$1');",
            "                (gen_statem:event_type(),",
            "                 Msg :: term(),",
            "                 Data :: term()) ->",
            "          gen_statem:event_handler_result(atom()).",
            "$1({call,Caller}, _Msg, Data) ->",
            "    {next_state, $1, Data, [{reply,Caller,ok}]}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% This function is called by a gen_statem when it is about to",
            "%% terminate. It should be the opposite of Module:init/1 and do any",
            "%% necessary cleaning up. When it returns, the gen_statem terminates with",
            "%% Reason. The return value is ignored.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec terminate(Reason :: term(), State :: term(), Data :: term()) ->",
            "          any().",
            "terminate(_Reason, _State, _Data) ->",
            "    void.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Convert process state when code is changed",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec code_change(OldVsn :: term() | {down,term()},",
            "                  State :: term(),",
            "                  Data :: term(),",
            "                  Extra :: term()) ->",
            "          {ok, NewState :: term(), NewData :: term()} |",
            "          (Reason :: term()).",
            "code_change(_OldVsn, State, Data, _Extra) ->",
            "    {ok, State, Data}.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            "",
        ]
    },

    "wx_object behavior (large)" : {
        "prefix" : "erl-wx_object-large",
        "description" : "Insert an empty wx_object with all the callbacks and decoration",
        "body": [
            "-behaviour(wx_object).",
            "",
            "-include_lib(\"wx/include/wx.hrl\").",
            "",
            "%% API",
            "-export([start_link/0]).",
            "",
            "%% wx_object callbacks",
            "-export([init/1, handle_call/3, handle_cast/2, handle_info/2,",
            "         handle_event/2, terminate/2, code_change/3]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-record(state, {}).",
            "",
            "%%%===================================================================",
            "%%% API",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc",
            "%% Starts the server",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec start_link() -> wx:wx_object() | {error, Reason :: term()}.",
            "start_link() ->",
            "    wx_object:start_link(?MODULE, [], []).",
            "",
            "%%%===================================================================",
            "%%% wx_object callbacks",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Initializes the server",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec init(Args :: term()) ->",
            "        {wx:wx_object(), State :: term()} |",
            "        {wx:wx_object(), State :: term(), Timeout :: timeout()} |",
            "        ignore |",
            "        {stop, Reason :: term()}.",
            "init([]) ->",
            "    wx:new(),",
            "    Frame = wxFrame:new(),",
            "    {Frame, #state{}}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Handling events",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_event(wxEvtHandler:wx(), State :: term()) ->",
            "        {noreply, State :: term()} |",
            "        {noreply, State :: term(), Timeout :: timeout()} |",
            "        {stop, Reason :: term(), State :: term()}.",
            "handle_event(#wx{}, State) ->",
            "    {noreply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Handling call messages",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_call(Request :: term(), From :: {pid(), term()}, State :: term()) ->",
            "        {reply, Reply :: term(), State :: term()} |",
            "        {reply, Reply :: term(), State :: term(), Timeout :: timeout()} |",
            "        {noreply, State :: term()} |",
            "        {noreply, State :: term(), Timeout :: timeout()} |",
            "        {stop, Reason :: term(), Reply :: term(), State :: term()} |",
            "        {stop, Reason :: term(), State :: term()}.",
            "handle_call(_Request, _From, State) ->",
            "    Reply = ok,",
            "    {reply, Reply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Handling cast messages",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_cast(Msg :: term(), State :: term()) ->",
            "        {noreply, State :: term()} |",
            "        {noreply, State :: term(), Timeout :: timeout()} |",
            "        {stop, Reason :: term(), State :: term()}.",
            "handle_cast(_Msg, State) ->",
            "    {noreply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Handling all non call/cast messages",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec handle_info(Info :: timeout | term(), State :: term()) ->",
            "        {noreply, State :: term()} |",
            "        {noreply, State :: term(), Timeout :: timeout()} |",
            "        {stop, Reason :: term(), State :: term()}.",
            "handle_info(_Info, State) ->",
            "    {noreply, State}.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% This function is called by a wx_object when it is about to",
            "%% terminate. It should be the opposite of Module:init/1 and do any",
            "%% necessary cleaning up. When it returns, the wx_object terminates",
            "%% with Reason. The return value is ignored.",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec terminate(Reason :: normal | shutdown | {shutdown, term()} | term(),",
            "                State :: term()) -> any().",
            "terminate(_Reason, _State) ->",
            "    ok.",
            "",
            "%%--------------------------------------------------------------------",
            "%% @private",
            "%% @doc",
            "%% Convert process state when code is changed",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec code_change(OldVsn :: term() | {down, term()},",
            "                  State :: term(),",
            "                  Extra :: term()) ->",
            "          {ok, NewState :: term()} |",
            "          {error, Reason :: term()}.",
            "code_change(_OldVsn, State, _Extra) ->",
            "    {ok, State}.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            "",
        ]
    },

    "library module" : {
        "prefix" : "erl-library-module",
        "description" : "Insert an empty library module",
        "body": [
            "%%%-------------------------------------------------------------------",
            "%%% @author ${1:Author_Name} <${2:Author_Email}>",
            "%%% @copyright (C) $CURRENT_YEAR, $1",
            "%%% @doc $0",
            "%%%",
            "%%% @end",
            "%%% Created : $CURRENT_DATE $CURRENT_MONTH_NAME_SHORT $CURRENT_YEAR by $1 <$2>",
            "%%%-------------------------------------------------------------------",
            "-module(${3:Module_Name}).",
            "",
            "%% API",
            "-export([${4:Function_Name}/0]).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "%%%===================================================================",
            "%%% API",
            "%%%===================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% @doc",
            "%% @end",
            "%%--------------------------------------------------------------------",
            "-spec $4() -> ok.",
            "$4() ->",
            "    ok.",
            "",
            "%%%===================================================================",
            "%%% Internal functions",
            "%%%===================================================================",
            "",
        ]
    },

    "Insert EUnit tests": {
        "scope": "erlang",
        "prefix": "erl-eunit-tests",
        "description": "Insert an empty EUnit test",
        "body": [
            "-module(${1:Module_Name}_tests).",
            "",
            "%%%===================================================================",
            "%%% Includes, defines, types and records",
            "%%%===================================================================",
            "",
            "-include_lib(\"eunit/include/eunit.hrl\").",
            "",
            "%%====================================================================",
            "%%  Test descriptions",
            "%%====================================================================",
            "",
            "${2:Test_Group_Name}_test_() ->",
            "    {\"${3:Title of this test group}\",",
            "     {setup,",
            "      fun $2_setup/0,",
            "      fun $2_cleanup/1,",
            "      [{\"${4:Description of test case}\",",
            "        ?_test($2_first_use_case())}",
            "      ]}}.",
            "",
            "%%====================================================================",
            "%%  Setup and cleanup",
            "%%====================================================================",
            "",
            "$2_setup() ->",
            "    ok.",
            "",
            "$2_cleanup(_FromSetup) ->",
            "    ok.",
            "",
            "%%====================================================================",
            "%%  Unit tests",
            "%%====================================================================",
            "",
            "%%--------------------------------------------------------------------",
            "%% Test group: $2",
            "%%",
            "%% $3",
            "%%--------------------------------------------------------------------",
            "",
            "%% $4",
            "$2_first_use_case() ->",
            "    ?assertMatch([_|_], $1:module_info()).",
            "",
            "%%====================================================================",
            "%%  Helper functions",
            "%%====================================================================",
            ""
        ]
    }

}
