diff --git a/Shell/AST.cpp b/Shell/AST.cpp index f64a0289c5..551e1fc08b 100644 --- a/Shell/AST.cpp +++ b/Shell/AST.cpp @@ -367,9 +367,15 @@ RefPtr BarewordLiteral::run(RefPtr) void BarewordLiteral::highlight_in_editor(Line::Editor& editor, Shell& shell, HighlightMetadata metadata) { 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; } + if (m_text.starts_with('-')) { if (m_text == "--") { editor.stylize({ m_position.start_offset, m_position.end_offset }, { Line::Style::Foreground(Line::Style::XtermColor::Green) }); diff --git a/Shell/Shell.cpp b/Shell/Shell.cpp index 58a28369f3..104b30c4ed 100644 --- a/Shell/Shell.cpp +++ b/Shell/Shell.cpp @@ -386,6 +386,21 @@ String Shell::resolve_alias(const String& name) const 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) { if (cmd.is_empty()) diff --git a/Shell/Shell.h b/Shell/Shell.h index 6031c080d0..f5c876d097 100644 --- a/Shell/Shell.h +++ b/Shell/Shell.h @@ -73,6 +73,7 @@ public: constexpr static auto global_init_file_path = "/etc/shellrc"; int run_command(const StringView&); + bool is_runnable(const StringView&); RefPtr run_command(const AST::Command&); Vector> run_commands(Vector&); bool run_file(const String&, bool explicitly_invoked = true);