Skip to content

Instantly share code, notes, and snippets.

@davisp

davisp/remsh.erl Secret

Created April 26, 2013 16:16
Show Gist options
  • Save davisp/439e29ced1e6a9d2b108 to your computer and use it in GitHub Desktop.
Save davisp/439e29ced1e6a9d2b108 to your computer and use it in GitHub Desktop.
A remsh that supports tab completion from code on the remote node. The original remsh-from-escript code is pulled from Geoff Cant's Erlang Factory talk. https://github.com/archaelus/egc_examples/blob/master/rescriptmsh
#! /usr/bin/env escript
%%! -hidden -noshell -noinput
main([RemoteNode0]) ->
RemoteNode = list_to_atom(RemoteNode0),
assert_hidden_node(),
case net_kernel:start([local_node(), longnames]) of
{ok, _} -> ok;
{error, {already_started, _}} -> ok;
{error, Reason} -> erlang:error({no_network, Reason})
end,
case net_kernel:connect_node(RemoteNode) of
true -> ok;
_ -> erlang:error({no_connection, RemoteNode})
end,
Shell = user_drv:start(['tty_sl -c -e', {RemoteNode, shell, start, []}]),
spawn_link(fun() -> monitor_group(RemoteNode, Shell) end),
erlang:monitor(process, Shell),
receive
{'DOWN', _Ref, process, Shell, _Reason} ->
ok
end,
init:halt(0);
main(_) ->
io:format("usage: ~s remote_node~n", [escript:script_name()]).
local_node() ->
list_to_atom("escript_" ++ os:getpid()).
assert_hidden_node() ->
% The list of nodes we want to publish our presence
% on. This is symetrical so if its empty we'll also
% not appear on any node that connects to us.
case global_group:publish_on_nodes() of
[] -> ok;
_ -> erlang:error(not_hidden)
end.
monitor_group(RemoteNode, Shell) ->
timer:sleep(250),
case get_group_leader(Shell) of
Pid when is_pid(Pid) ->
set_expand_fun(RemoteNode, Pid),
erlang:monitor(process, Pid),
receive
{'DOWN', _Ref, process, Pid, _Reason} ->
ok
end;
undefined ->
ok
end,
monitor_group(RemoteNode, Shell).
get_group_leader(Pid) ->
{dictionary, Dict} = process_info(Pid, dictionary),
proplists:get_value(current_group, Dict).
set_expand_fun(RemoteNode, GL) ->
ExpFun = fun(B) ->
rpc:call(RemoteNode, edlin_expand, expand, [B])
end,
ok = io:setopts(GL, [{expand_fun, ExpFun}]).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment