mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 04:08:11 +00:00
Shell: highlight runnable commands
And display in red the command which will result in something like "no command, or is directory" (inspired by the fish shell).
This commit is contained in:
parent
e799da1fb6
commit
2b4b9d212e
3 changed files with 23 additions and 1 deletions
|
@ -367,9 +367,15 @@ RefPtr<Value> BarewordLiteral::run(RefPtr<Shell>)
|
||||||
void BarewordLiteral::highlight_in_editor(Line::Editor& editor, Shell& shell, HighlightMetadata metadata)
|
void BarewordLiteral::highlight_in_editor(Line::Editor& editor, Shell& shell, HighlightMetadata metadata)
|
||||||
{
|
{
|
||||||
if (metadata.is_first_in_list) {
|
if (metadata.is_first_in_list) {
|
||||||
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Bold });
|
if (shell.is_runnable(m_text))
|
||||||
|
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Bold });
|
||||||
|
else {
|
||||||
|
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Red) });
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_text.starts_with('-')) {
|
if (m_text.starts_with('-')) {
|
||||||
if (m_text == "--") {
|
if (m_text == "--") {
|
||||||
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Green) });
|
editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Green) });
|
||||||
|
|
|
@ -386,6 +386,21 @@ String Shell::resolve_alias(const String& name) const
|
||||||
return m_aliases.get(name).value_or({});
|
return m_aliases.get(name).value_or({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Shell::is_runnable(const StringView& name)
|
||||||
|
{
|
||||||
|
// FIXME: for now, check aliases manually because cached path doesn't get
|
||||||
|
// updated with aliases. Should it?
|
||||||
|
if (!resolve_alias(name).is_null())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (access(name.to_string().characters(), X_OK) == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return !!binary_search(cached_path.span(), name.to_string(), [](const String& name, const String& program) -> int {
|
||||||
|
return strcmp(name.characters(), program.characters());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
int Shell::run_command(const StringView& cmd)
|
int Shell::run_command(const StringView& cmd)
|
||||||
{
|
{
|
||||||
if (cmd.is_empty())
|
if (cmd.is_empty())
|
||||||
|
|
|
@ -73,6 +73,7 @@ public:
|
||||||
constexpr static auto global_init_file_path = "/etc/shellrc";
|
constexpr static auto global_init_file_path = "/etc/shellrc";
|
||||||
|
|
||||||
int run_command(const StringView&);
|
int run_command(const StringView&);
|
||||||
|
bool is_runnable(const StringView&);
|
||||||
RefPtr<Job> run_command(const AST::Command&);
|
RefPtr<Job> run_command(const AST::Command&);
|
||||||
Vector<RefPtr<Job>> run_commands(Vector<AST::Command>&);
|
Vector<RefPtr<Job>> run_commands(Vector<AST::Command>&);
|
||||||
bool run_file(const String&, bool explicitly_invoked = true);
|
bool run_file(const String&, bool explicitly_invoked = true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue