]> git.armaanb.net Git - gen-shell.git/blob - src/main.cpp
move to sr.ht, minor updates
[gen-shell.git] / src / main.cpp
1 // gen-shell - the generic shell
2 // Copyright (c) 2020, Armaan Bhojwani <code@armaanb.net>
3
4 #include <cmake.h>
5 #include <iostream>
6 #include <../Sarge/src/sarge.h>
7 #include <filesystem>
8 #include <vector>
9 #include <string>
10
11 #ifdef HAVE_READLINE
12   #include <readline/readline.h>
13   #include <readline/history.h>
14 #endif
15
16 ////////////////////////////////////////////////////////////////////////////////
17
18 using namespace std;
19 using std::filesystem::exists;
20
21 const std::string getResponse(const std::string & prompt) {
22   std::string response {
23     ""
24   };
25
26   // Display prompt, get input
27   #ifdef HAVE_READLINE
28   char * line_read = readline(prompt.c_str());
29   if (!line_read) {
30     std::cout << "\n";
31     response = "<EOF>";
32   } else {
33     // Save history
34     if ( * line_read)
35       add_history(line_read);
36
37     response = std::string(line_read);
38     free(line_read);
39   }
40   #else
41   std::cout << prompt;
42   std::getline(std::cin, response);
43   if (std::cin.eof() == 1) {
44     std::cout << "\n";
45     response = "<EOF>";
46   }
47   #endif
48
49   return response;
50 }
51
52 ////////////////////////////////////////////////////////////////////////////////
53
54 int main(int argc, char** argv)
55 {
56
57   // Command line arguments
58   Sarge sarge;
59
60         sarge.setArgument("a", "after", "Command to execute before leaving the shell", true);
61   sarge.setArgument("b", "before", "Command to execute before entering the shell", true);
62   sarge.setArgument("c", "command", "Command to convert to shell", true);
63   sarge.setArgument("h", "help", "Get help.", false);
64   sarge.setArgument("p", "prompt", "Define a custom prompt", true);
65   sarge.setArgument("", "no-space", "Dont automatically add spaces after custom prompt and command", true);
66   sarge.setDescription("Make a shell from any executable");
67   sarge.setUsage("gen-shell <options>");
68
69         if (!sarge.parseArguments(argc, argv)) {
70                 std::cerr << "Couldn't parse arguments..." << std::endl;
71                 return 1;
72         }
73
74         if (sarge.exists("help")) {
75                 sarge.printHelp();
76     return 0;
77         }
78
79   bool space = true;
80   if (sarge.exists("no-space")) {
81     space = false;
82         }
83
84   // Define input command
85   string arg_cmd;
86   sarge.getFlag("command", arg_cmd);
87   if ( space )
88     arg_cmd += " ";
89
90   // Define prompt
91   string prompt = "";
92   sarge.getFlag("prompt", prompt);
93   if ( prompt == "" )
94   {
95     prompt = "% ";
96   } else if ( space ) {
97     prompt += " ";
98   }
99
100   // Execute before-command
101   string before_command;
102   sarge.getFlag("before", before_command);
103   system (before_command.c_str ());
104
105   // Execute after-command
106   string after_command;
107   sarge.getFlag("after", after_command);
108
109   string alias_file
110   vector<string> alias_files = {"$XDG_CONFIG_HOME/gen-shell/aliases",
111                                 "$HOME/.config/gen-shell/aliases"};
112   for(const auto &file : alias_files)
113   {
114     if (exists(file))
115     {
116       alias_file = file;
117       break;
118     }
119   }
120
121   // Do the stuffs!
122   while (true) {
123     auto command = getResponse(prompt);
124
125     if (command == "<EOF>" || command == "exit" || command == "quit" )
126     {
127       system (after_command.c_str ());
128       return 0;
129     } else {
130       string whole_command = arg_cmd + command;
131       system (whole_command.c_str ());
132     }
133   }
134 }
135
136 ////////////////////////////////////////////////////////////////////////////////