Skip to content

Instantly share code, notes, and snippets.

@uwiger
Created July 8, 2010 13:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uwiger/468003 to your computer and use it in GitHub Desktop.
Save uwiger/468003 to your computer and use it in GitHub Desktop.
%% Copyright 2010 Erlang Solutions Ltd (ESL). All rights reserved.
%% Redistribution and use in source and binary forms, with or without
%% modification, are permitted provided that the following conditions are met:
%%
%% 1. Redistributions of source code must retain the above copyright notice,
%% this list of conditions and the following disclaimer.
%%
%% 2. Redistributions in binary form must reproduce the above copyright
%% notice, this list of conditions and the following disclaimer in
%% the documentation and/or other materials provided with the distribution.
%%
%% THIS SOFTWARE IS PROVIDED BY ESL ``AS IS'' AND ANY EXPRESS OR IMPLIED
%% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
%% IN NO EVENT SHALL ESL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
%% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
%% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
%% OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
%% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
%% THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%%
%% The views and conclusions contained in the software and documentation are
%% those of the authors and should not be interpreted as representing
%% official policies, either expressed or implied, of ESL.
%% @doc
%% A collection of functions to manage saved shell histories
%% @end
-module(save_shell).
-export([shell/0,
h/0,
cmds/0,
w/1,
r/1]).
%% @spec () -> [Item]
%% Item = {{result,N}, any()} | {{command,N}, [Expr]} | {evaluator,pid()}
%%
%% @doc
%% Returns the shell history from the current shell process.
%% @end
%%
h() ->
shell_req(shell(), get_cmd).
%% @spec () -> {Seq::integer(), Exprs::list()}
%% @doc
%% Returns the shell history as a list of {CmdNo, Command}, where
%% Command is the pretty-printed command (sequence of expressions) entered
%% into the shell.
%% @end
%%
cmds() ->
CmdEs = [{N,Es} || {{command,N},Es} <- h()],
lists:keysort(1,[{N,lists:flatten(erl_pp:exprs(Es))} ||
{N,Es} <- CmdEs]).
%% @spec w(string()) -> ok | {error,Reason}
%% @doc
%% Writes the shell history to the output file F in a form that can be
%% processed by `file:script/1'.
%% @end
%%
w(F) ->
case cmds() of
[] ->
{error, empty_history};
[_|_] = Cmds ->
case file:open(F, [write]) of
{ok, Fd} ->
try [io:fwrite(Fd,"~s.~n", [C]) || {_,C} <- Cmds]
after
file:close(Fd)
end,
ok;
{error,_} = E ->
E
end
end.
%% @spec r(string()) -> any()
%% @doc
%% Reads a saved shell history and returns the value of the last
%% expression.
%% @end
r(F) ->
file:script(F).
%% @spec () -> pid()
%% @doc Returns the Pid of the shell process.
%% @end
%%
%% Modified version of shell:whereis_evaluator()
%%
shell() ->
%% locate top group leader, always registered as user
%% can be implemented by group (normally) or user
%% (if oldshell or noshell)
case whereis(user) of
undefined ->
undefined;
User ->
%% get user_drv pid from group, or shell pid from user
case group:interfaces(User) of
[] -> % old- or noshell
case user:interfaces(User) of
[] ->
undefined;
[{shell,Shell}] ->
Shell
end;
[{user_drv,UserDrv}] ->
%% get current group pid from user_drv
case user_drv:interfaces(UserDrv) of
[] ->
undefined;
[{current_group,Group}] ->
%% get shell pid from group
GrIfs = group:interfaces(Group),
case lists:keyfind(shell, 1, GrIfs) of
{shell, Shell} ->
Shell;
false ->
undefined
end
end
end
end.
shell_req(Shell, Req) ->
Shell ! {shell_req,self(),Req},
receive
{shell_rep,Shell,Rep} -> Rep
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment