mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 20:57:35 +00:00
Shell: Add the alias builtin and resolve aliases
This follows the other shells in alias resolution, and resolves the alias only once.
This commit is contained in:
parent
a4627f2439
commit
2915dcfcc3
4 changed files with 66 additions and 1 deletions
|
@ -617,7 +617,30 @@ RefPtr<Value> Execute::run(TheExecutionInputType input_value)
|
||||||
RefPtr<Job> job;
|
RefPtr<Job> job;
|
||||||
|
|
||||||
auto shell = input_value;
|
auto shell = input_value;
|
||||||
auto commands = m_command->run(input_value)->resolve_as_commands(input_value);
|
auto initial_commands = m_command->run(input_value)->resolve_as_commands(input_value);
|
||||||
|
decltype(initial_commands) commands;
|
||||||
|
|
||||||
|
for (auto& command : initial_commands) {
|
||||||
|
if (!command.argv.is_empty()) {
|
||||||
|
auto alias = shell->resolve_alias(command.argv[0]);
|
||||||
|
if (!alias.is_null()) {
|
||||||
|
auto argv0 = command.argv.take_first();
|
||||||
|
auto subcommand_ast = Parser { alias }.parse();
|
||||||
|
if (subcommand_ast) {
|
||||||
|
while (subcommand_ast->is_execute()) {
|
||||||
|
auto* ast = static_cast<Execute*>(subcommand_ast.ptr());
|
||||||
|
subcommand_ast = ast->command();
|
||||||
|
}
|
||||||
|
RefPtr<Node> substitute = adopt(*new Join(position(), move(subcommand_ast), adopt(*new CommandLiteral(position(), command))));
|
||||||
|
commands.append(substitute->run(input_value)->resolve_as_commands(input_value));
|
||||||
|
} else {
|
||||||
|
commands.append(command);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
commands.append(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vector<RefPtr<Job>> jobs_to_wait_for;
|
Vector<RefPtr<Job>> jobs_to_wait_for;
|
||||||
|
|
||||||
auto run_commands = [&](auto& commands) {
|
auto run_commands = [&](auto& commands) {
|
||||||
|
|
|
@ -33,6 +33,40 @@
|
||||||
|
|
||||||
extern RefPtr<Line::Editor> editor;
|
extern RefPtr<Line::Editor> editor;
|
||||||
|
|
||||||
|
int Shell::builtin_alias(int argc, const char** argv)
|
||||||
|
{
|
||||||
|
Vector<const char*> arguments;
|
||||||
|
|
||||||
|
Core::ArgsParser parser;
|
||||||
|
parser.add_positional_argument(arguments, "List of name[=values]'s", "name[=value]", Core::ArgsParser::Required::No);
|
||||||
|
|
||||||
|
if (!parser.parse(argc, const_cast<char**>(argv), false))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (arguments.is_empty()) {
|
||||||
|
for (auto& alias : m_aliases)
|
||||||
|
printf("%s=%s\n", escape_token(alias.key).characters(), escape_token(alias.value).characters());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fail = false;
|
||||||
|
for (auto& argument : arguments) {
|
||||||
|
auto parts = String { argument }.split_limit('=', 2, true);
|
||||||
|
if (parts.size() == 1) {
|
||||||
|
auto alias = m_aliases.get(parts[0]);
|
||||||
|
if (alias.has_value()) {
|
||||||
|
printf("%s=%s\n", escape_token(parts[0]).characters(), escape_token(alias.value()).characters());
|
||||||
|
} else {
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_aliases.set(parts[0], parts[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fail ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
int Shell::builtin_bg(int argc, const char** argv)
|
int Shell::builtin_bg(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
int job_id = -1;
|
int job_id = -1;
|
||||||
|
|
|
@ -306,6 +306,11 @@ void Shell::unset_local_variable(const String& name)
|
||||||
m_local_variables.remove(name);
|
m_local_variables.remove(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String Shell::resolve_alias(const String& name) const
|
||||||
|
{
|
||||||
|
return m_aliases.get(name).value_or({});
|
||||||
|
}
|
||||||
|
|
||||||
int Shell::run_command(const StringView& cmd)
|
int Shell::run_command(const StringView& cmd)
|
||||||
{
|
{
|
||||||
if (cmd.is_empty())
|
if (cmd.is_empty())
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
#define ENUMERATE_SHELL_BUILTINS() \
|
#define ENUMERATE_SHELL_BUILTINS() \
|
||||||
|
__ENUMERATE_SHELL_BUILTIN(alias) \
|
||||||
__ENUMERATE_SHELL_BUILTIN(cd) \
|
__ENUMERATE_SHELL_BUILTIN(cd) \
|
||||||
__ENUMERATE_SHELL_BUILTIN(cdh) \
|
__ENUMERATE_SHELL_BUILTIN(cdh) \
|
||||||
__ENUMERATE_SHELL_BUILTIN(pwd) \
|
__ENUMERATE_SHELL_BUILTIN(pwd) \
|
||||||
|
@ -73,6 +74,7 @@ public:
|
||||||
static Vector<String> expand_globs(const StringView& path, StringView base);
|
static Vector<String> expand_globs(const StringView& path, StringView base);
|
||||||
static Vector<String> expand_globs(Vector<StringView> path_segments, const StringView& base);
|
static Vector<String> expand_globs(Vector<StringView> path_segments, const StringView& base);
|
||||||
String resolve_path(String) const;
|
String resolve_path(String) const;
|
||||||
|
String resolve_alias(const String&) const;
|
||||||
|
|
||||||
RefPtr<AST::Value> lookup_local_variable(const String&);
|
RefPtr<AST::Value> lookup_local_variable(const String&);
|
||||||
String local_variable_or(const String&, const String&);
|
String local_variable_or(const String&, const String&);
|
||||||
|
@ -161,6 +163,7 @@ private:
|
||||||
pid_t m_pid { 0 };
|
pid_t m_pid { 0 };
|
||||||
|
|
||||||
HashMap<String, RefPtr<AST::Value>> m_local_variables;
|
HashMap<String, RefPtr<AST::Value>> m_local_variables;
|
||||||
|
HashMap<String, String> m_aliases;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr bool is_word_character(char c)
|
static constexpr bool is_word_character(char c)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue