Przeglądaj źródła

Shell: Read and evaluate an init file on start

This behaviour is overridable with the `--skip-init' flag.
The default file is at '~/shell-init.sh'
AnotherTest 5 lat temu
rodzic
commit
bc3285abb0
4 zmienionych plików z 38 dodań i 12 usunięć
  1. 5 0
      Base/home/anon/shell-init.sh
  2. 16 0
      Shell/Shell.cpp
  3. 3 0
      Shell/Shell.h
  4. 14 12
      Shell/main.cpp

+ 5 - 0
Base/home/anon/shell-init.sh

@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# IFS controls what $(...) (inline evaluate) would split its captured
+# string with. the default is \x0a (i.e. newline).
+IFS="\x0a"

+ 16 - 0
Shell/Shell.cpp

@@ -460,6 +460,22 @@ RefPtr<Job> Shell::run_command(AST::Command& command)
     return *job;
 }
 
+bool Shell::run_file(const String& filename)
+{
+    auto file_result = Core::File::open(filename, Core::File::ReadOnly);
+    if (file_result.is_error()) {
+        fprintf(stderr, "Failed to open %s: %s\n", filename.characters(), file_result.error().characters());
+        return false;
+    }
+    auto file = file_result.value();
+    for (;;) {
+        auto line = file->read_line(4096);
+        if (line.is_null())
+            break;
+        run_command(String::copy(line, Chomp));
+    }
+    return true;
+}
 void Shell::take_back_stdin()
 {
     tcsetpgrp(0, m_pid);

+ 3 - 0
Shell/Shell.h

@@ -64,8 +64,11 @@ class Shell : public Core::Object {
     C_OBJECT(Shell);
 
 public:
+    constexpr static auto init_file_path = "~/shell-init.sh";
+
     int run_command(const StringView&);
     RefPtr<Job> run_command(AST::Command&);
+    bool run_file(const String&);
     bool run_builtin(int argc, const char** argv, int& retval);
     void block_on_job(RefPtr<Job>);
     String prompt() const;

+ 14 - 12
Shell/main.cpp

@@ -119,13 +119,24 @@ int main(int argc, char** argv)
 
     const char* command_to_run = nullptr;
     const char* file_to_read_from = nullptr;
+    bool skip_init_file = false;
 
     Core::ArgsParser parser;
     parser.add_option(command_to_run, "String to read commands from", "command-string", 'c', "command-string");
     parser.add_positional_argument(file_to_read_from, "File to read commands from", "file", Core::ArgsParser::Required::No);
+    parser.add_option(skip_init_file, "Skip running ~/shell-init.sh", "skip-init", 0);
 
     parser.parse(argc, argv);
 
+    if (!skip_init_file) {
+        String file_path = Shell::init_file_path;
+        if (file_path.starts_with('~'))
+            file_path = shell->expand_tilde(file_path);
+        if (!shell->run_file(file_path)) {
+            fprintf(stderr, "Shell: Failed to execute init file '%s'\n", Shell::init_file_path);
+        }
+    }
+
     if (command_to_run) {
         dbgprintf("sh -c '%s'\n", command_to_run);
         shell->run_command(command_to_run);
@@ -133,18 +144,9 @@ int main(int argc, char** argv)
     }
 
     if (file_to_read_from && StringView { "-" } != file_to_read_from) {
-        auto file = Core::File::construct(file_to_read_from);
-        if (!file->open(Core::IODevice::ReadOnly)) {
-            fprintf(stderr, "Failed to open %s: %s\n", file->filename().characters(), file->error_string());
-            return 1;
-        }
-        for (;;) {
-            auto line = file->read_line(4096);
-            if (line.is_null())
-                break;
-            shell->run_command(String::copy(line, Chomp));
-        }
-        return 0;
+        if (shell->run_file(file_to_read_from))
+            return 0;
+        return 1;
     }
 
     editor->on_interrupt_handled = [&] {