17 #if defined(USE_REPLXX)
20 #elif defined(USE_GNU_READLINE)
21 #include <readline/readline.h>
22 #include <readline/history.h>
31 namespace SWC {
namespace Utils {
namespace shell {
39 if(settings->has(
"ranger"))
41 else if(settings->has(
"manager"))
43 else if(settings->has(
"filesystem"))
45 else if(settings->has(
"statistics"))
50 for(std::unique_ptr<Interface> ptr; cli; cli=ptr->run()) {
83 OptCall_t&& a_call,
const char* a_re) noexcept
84 :
name(std::move(a_name)),
85 desc(std::move(a_desc)),
86 call(std::move(a_call)),
99 : err(Error::
OK), _state(state),
100 prompt(std::move(a_prompt)),
101 history(std::move(a_history)),
112 #if defined(USE_REPLXX)
114 rx.install_window_change_handler();
116 rx.set_max_hint_rows(3);
117 rx.set_indent_multiline(
true);
120 std::ifstream history_file(
history.c_str());
121 rx.history_load(history_file);
124 replxx::Replxx::KEY::control(
'C' ),
125 [
this, &rx](char32_t c) {
127 return rx.invoke(replxx::Replxx::ACTION::ABORT_LINE, c);
130 const char* line =
nullptr;
131 const char* ptr =
nullptr;
134 char* line =
nullptr;
138 bool prompt_state =
true;
142 bool cmd_end =
false;
144 bool comment =
false;
145 bool quoted_1 =
false;
146 bool quoted_2 =
false;
147 bool is_quoted =
false;
148 bool next_line =
false;
150 std::queue<std::string> queue;
154 #
if defined(USE_REPLXX)
155 (ptr = line = rx.input(prompt_state ?
prompt : std::string()))
157 (ptr = line = readline(prompt_state ?
prompt.c_str() :
""))
161 prompt_state =
false;
167 if(errtmp != ENOTTY && errtmp != EINTR) {
168 if(errtmp != EAGAIN) {
169 SWC_PRINT <<
"\033[31mERROR\033[00m: unexpected error="
182 if(c ==
'\n' && cmd_end) {
183 while(!queue.empty()) {
184 auto& run_cmd = queue.front();
185 #if defined(USE_REPLXX)
186 rx.history_add(run_cmd);
189 add_history(run_cmd.c_str());
190 write_history(
history.c_str());
201 }
else if(!comment && c ==
'\n' && cmd.empty()) {
205 }
else if(c ==
' ' && cmd.empty()) {
208 }
else if(!is_quoted && !escape) {
212 }
else if(c ==
'\n' && comment) {
224 }
else if(c ==
'\\') {
229 if((!is_quoted || quoted_1) && c ==
'\'')
230 is_quoted = quoted_1 = !quoted_1;
231 else if((!is_quoted || quoted_2) && c ==
'"')
232 is_quoted = quoted_2 = !quoted_2;
233 else if(c ==
';' && !is_quoted) {
241 #if !defined(USE_REPLXX)
254 std::move(a_name), std::move(a_desc), std::move(a_call), a_re));
260 {
"Quit or Exit the Console"},
261 [ptr=
this](std::string& cmd){
return ptr->quit(cmd);},
262 "(?i)^(quit|exit)(\\s+|$)"
266 {
"Commands help information"},
267 [ptr=
this](std::string& cmd){
return ptr->help(cmd);},
268 "(?i)^(help)(\\s+|$)"
272 {
"Switch to other CLI, options: rgr|mngr|fs|stats|client"},
273 [ptr=
this](std::string& cmd){
return ptr->switch_to(cmd);},
274 "(?i)^(switch\\s+to)(\\s+|$)"
287 return error(message);
293 return error(message);
308 return error(
"Bad Interface Option");
314 SWC_PRINT <<
"Usage Help: \033[4m'command' [options];\033[00m\n";
315 size_t offset_name = 0;
316 size_t offset_desc = 0;
318 if(offset_name < opt->name.length())
319 offset_name = opt->name.length();
320 for(
const auto& desc : opt->desc) {
321 if(offset_desc < desc.length())
322 offset_desc = desc.length();
330 << std::left << std::setw(offset_name) << opt->name;
332 for(
const auto& desc : opt->desc) {
335 << std::left << std::setw(offset_name) <<
" ";
346 SWC_PRINT <<
"\033[31mERROR\033[00m: " << message
355 [cmd](
const Option* _opt){
356 return Condition::re(_opt->re, cmd.c_str(), cmd.size());
359 return (*opt)->call(cmd);
360 SWC_PRINT <<
"Unknown command='\033[31m" << cmd <<
";\033[00m'"