summaryrefslogtreecommitdiffstats
path: root/sinksh/repl/replStates.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sinksh/repl/replStates.cpp')
-rw-r--r--sinksh/repl/replStates.cpp68
1 files changed, 23 insertions, 45 deletions
diff --git a/sinksh/repl/replStates.cpp b/sinksh/repl/replStates.cpp
index 18081df..c4b08b7 100644
--- a/sinksh/repl/replStates.cpp
+++ b/sinksh/repl/replStates.cpp
@@ -21,46 +21,54 @@
21 21
22#include <iostream> 22#include <iostream>
23 23
24#include <readline/readline.h>
25#include <readline/history.h>
26
27#include <QDebug> 24#include <QDebug>
28#include <QEvent> 25#include <QEvent>
29#include <QStateMachine> 26#include <QStateMachine>
27#include "linenoise.hpp"
30 28
31#include "syntaxtree.h" 29#include "syntaxtree.h"
32 30
33static char *sink_cli_next_tab_complete_match(const char *text, int state);
34static char ** sink_cli_tab_completion(const char *text, int start, int end);
35
36ReadState::ReadState(QState *parent) 31ReadState::ReadState(QState *parent)
37 : QState(parent) 32 : QState(parent)
38{ 33{
39 rl_completion_entry_function = sink_cli_next_tab_complete_match; 34 linenoise::SetCompletionCallback([](const char* editBuffer, std::vector<std::string>& completions) {
40 rl_attempted_completion_function = sink_cli_tab_completion; 35 QStringList words = QString(editBuffer).split(" ", QString::SkipEmptyParts);
36 const QString fragment = words.takeLast();
37 Syntax::List nearest = SyntaxTree::self()->nearestSyntax(words, fragment);
38 if (nearest.isEmpty()) {
39 SyntaxTree::Command command = SyntaxTree::self()->match(words);
40 if (command.first && command.first->completer) {
41 QStringList commandCompletions = command.first->completer(words, fragment, SyntaxTree::self()->state());
42 for (const auto &c : commandCompletions) {
43 completions.push_back(c.toStdString());
44 }
45 }
46 } else {
47 for (const auto &n : nearest) {
48 completions.push_back(n.keyword.toStdString());
49 }
50 }
51 });
41} 52}
42 53
43void ReadState::onEntry(QEvent *event) 54void ReadState::onEntry(QEvent *event)
44{ 55{
45 Q_UNUSED(event) 56 Q_UNUSED(event)
46 char *line = readline(prompt());
47 57
48 if (!line) { 58 std::string line;
59 if (linenoise::Readline(prompt(), line)) {
49 std::cout << std::endl; 60 std::cout << std::endl;
50 emit exitRequested(); 61 emit exitRequested();
51 return; 62 return;
52 } 63 }
53 64
54 // we have actual data, so let's wait for a full line of text 65 // we have actual data, so let's wait for a full line of text
55 QByteArray input(line); 66 const QString text = QString::fromStdString(line).simplified();
56 const QString text = QString(line).simplified();
57 //qDebug() << "Line is ... " << text;
58 67
59 if (text.length() > 0) { 68 if (text.length() > 0) {
60 add_history(line); 69 linenoise::AddHistory(line.c_str());
61 } 70 }
62 71
63 free(line);
64 emit command(text); 72 emit command(text);
65} 73}
66 74
@@ -136,36 +144,6 @@ void PrintState::onEntry(QEvent *event)
136 emit completed(); 144 emit completed();
137} 145}
138 146
139static QStringList tab_completion_full_state;
140static bool tab_completion_at_root = false;
141
142static char **sink_cli_tab_completion(const char *text, int start, int end)
143{
144 tab_completion_at_root = start == 0;
145 tab_completion_full_state = QString(rl_line_buffer).remove(start, end - start).split(" ", QString::SkipEmptyParts);
146 return NULL;
147}
148
149static char *sink_cli_next_tab_complete_match(const char *text, int state)
150{
151 const QString fragment(text);
152 Syntax::List nearest = SyntaxTree::self()->nearestSyntax(tab_completion_full_state, fragment);
153 //for (auto syntax: nearest) { qDebug() << "Nearest: " << syntax.keyword; }
154
155 if (nearest.isEmpty()) {
156 SyntaxTree::Command command = SyntaxTree::self()->match(tab_completion_full_state);
157 if (command.first && command.first->completer) {
158 QStringList commandCompletions = command.first->completer(tab_completion_full_state, fragment, SyntaxTree::self()->state());
159 if (commandCompletions.size() > state) {
160 return qstrdup(commandCompletions[state].toUtf8());
161 }
162 }
163 } else if (nearest.size() > state) {
164 return qstrdup(nearest[state].keyword.toUtf8());
165 }
166
167 return rl_filename_completion_function(text, state);
168}
169 147
170//Ignore warning I don't know how to fix in a moc file 148//Ignore warning I don't know how to fix in a moc file
171#pragma clang diagnostic push 149#pragma clang diagnostic push