From 111ac4b1f4be83bba2712aa8341327f785aeaff2 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 20 Apr 2021 16:17:38 +0200 Subject: [PATCH] Shell: Auto-completion shouldn't suggest non-executable files for the program name --- Userland/Shell/AST.cpp | 6 +++--- Userland/Shell/Shell.cpp | 7 ++++--- Userland/Shell/Shell.h | 7 ++++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Userland/Shell/AST.cpp b/Userland/Shell/AST.cpp index 912dd94cb7..3d8e5afaf5 100644 --- a/Userland/Shell/AST.cpp +++ b/Userland/Shell/AST.cpp @@ -336,7 +336,7 @@ Vector Node::complete_for_editor(Shell& shell, size_ // If the literal isn't an option, treat it as a path. if (!(text.starts_with("-") || text == "--" || text == "-")) - return shell.complete_path("", text, corrected_offset); + return shell.complete_path("", text, corrected_offset, Shell::ExecutableOnly::No); // If the literal is an option, we have to know the program name // should we have no way to get that, bail early. @@ -2349,7 +2349,7 @@ Vector PathRedirectionNode::complete_for_editor(Shel if (corrected_offset > node->text().length()) return {}; - return shell.complete_path("", node->text(), corrected_offset); + return shell.complete_path("", node->text(), corrected_offset, Shell::ExecutableOnly::No); } PathRedirectionNode::~PathRedirectionNode() @@ -2895,7 +2895,7 @@ Vector Juxtaposition::complete_for_editor(Shell& she auto text = node->text().substring(1, node->text().length() - 1); - return shell.complete_path(tilde_value, text, corrected_offset - 1); + return shell.complete_path(tilde_value, text, corrected_offset - 1, Shell::ExecutableOnly::No); } return Node::complete_for_editor(shell, offset, hit_test_result); diff --git a/Userland/Shell/Shell.cpp b/Userland/Shell/Shell.cpp index b00fc96fea..aa1ee43812 100644 --- a/Userland/Shell/Shell.cpp +++ b/Userland/Shell/Shell.cpp @@ -1304,7 +1304,8 @@ Vector Shell::complete() return ast->complete_for_editor(*this, line.length()); } -Vector Shell::complete_path(const String& base, const String& part, size_t offset) +Vector Shell::complete_path(const String& base, + const String& part, size_t offset, ExecutableOnly executable_only) { auto token = offset ? part.substring_view(0, offset) : ""; String path; @@ -1358,7 +1359,7 @@ Vector Shell::complete_path(const String& base, cons struct stat program_status; String file_path = String::format("%s/%s", path.characters(), file.characters()); int stat_error = stat(file_path.characters(), &program_status); - if (!stat_error) { + if (!stat_error && (executable_only == ExecutableOnly::No || access(file_path.characters(), X_OK) == 0)) { if (S_ISDIR(program_status.st_mode)) { suggestions.append({ escape_token(file), "/" }); } else { @@ -1381,7 +1382,7 @@ Vector Shell::complete_program_name(const String& na [](auto& name, auto& program) { return strncmp(name.characters(), program.characters(), name.length()); }); if (!match) - return complete_path("", name, offset); + return complete_path("", name, offset, ExecutableOnly::Yes); String completion = *match; auto token_length = escape_token(name).length(); diff --git a/Userland/Shell/Shell.h b/Userland/Shell/Shell.h index 194538f0ae..88160b2a19 100644 --- a/Userland/Shell/Shell.h +++ b/Userland/Shell/Shell.h @@ -178,9 +178,14 @@ public: static bool is_glob(const StringView&); static Vector split_path(const StringView&); + enum class ExecutableOnly { + Yes, + No + }; + void highlight(Line::Editor&) const; Vector complete(); - Vector complete_path(const String& base, const String&, size_t offset); + Vector complete_path(const String& base, const String&, size_t offset, ExecutableOnly executable_only); Vector complete_program_name(const String&, size_t offset); Vector complete_variable(const String&, size_t offset); Vector complete_user(const String&, size_t offset);