Преглед изворни кода

Shell: Auto-completion shouldn't suggest non-executable files for the program name

Gunnar Beutner пре 4 година
родитељ
комит
111ac4b1f4
3 измењених фајлова са 13 додато и 7 уклоњено
  1. 3 3
      Userland/Shell/AST.cpp
  2. 4 3
      Userland/Shell/Shell.cpp
  3. 6 1
      Userland/Shell/Shell.h

+ 3 - 3
Userland/Shell/AST.cpp

@@ -336,7 +336,7 @@ Vector<Line::CompletionSuggestion> 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<Line::CompletionSuggestion> 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<Line::CompletionSuggestion> 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);

+ 4 - 3
Userland/Shell/Shell.cpp

@@ -1304,7 +1304,8 @@ Vector<Line::CompletionSuggestion> Shell::complete()
     return ast->complete_for_editor(*this, line.length());
 }
 
-Vector<Line::CompletionSuggestion> Shell::complete_path(const String& base, const String& part, size_t offset)
+Vector<Line::CompletionSuggestion> 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<Line::CompletionSuggestion> 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<Line::CompletionSuggestion> 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();

+ 6 - 1
Userland/Shell/Shell.h

@@ -178,9 +178,14 @@ public:
     static bool is_glob(const StringView&);
     static Vector<StringView> split_path(const StringView&);
 
+    enum class ExecutableOnly {
+        Yes,
+        No
+    };
+
     void highlight(Line::Editor&) const;
     Vector<Line::CompletionSuggestion> complete();
-    Vector<Line::CompletionSuggestion> complete_path(const String& base, const String&, size_t offset);
+    Vector<Line::CompletionSuggestion> complete_path(const String& base, const String&, size_t offset, ExecutableOnly executable_only);
     Vector<Line::CompletionSuggestion> complete_program_name(const String&, size_t offset);
     Vector<Line::CompletionSuggestion> complete_variable(const String&, size_t offset);
     Vector<Line::CompletionSuggestion> complete_user(const String&, size_t offset);