Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
ReadlinePromptCompletion.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <alib/vector>
9#include <set>
10#include <map>
11#include <alib/string>
12
13#include <registry/Registry.h>
15
17#include <prompt/Prompt.h>
18
19#include <readline/readline.h>
20
22 static std::set < std::string > fetchAlgorithmsFullyQualifiedName ( const char *text ) {
23 std::set < std::string > fullyQualifiedNames;
24
25 for ( const ext::pair < std::string, ext::vector < std::string > > & algo : abstraction::Registry::listAlgorithms ( ) ) {
26 fullyQualifiedNames.insert ( algo.first );
27 }
28
29 return filter_completions ( fullyQualifiedNames, text );
30 }
31
32 static std::set < std::string > fetchAlgorithmsLastSegmentName ( const char *text ) {
33 std::map < std::string, unsigned > collisions;
34
35 for ( const ext::pair < std::string, ext::vector < std::string > > & algo : abstraction::Registry::listAlgorithms ( ) ) {
36 size_t pos = algo.first.find_last_of ( ':' );
37 if ( pos != std::string::npos )
38 collisions [ algo.first.substr ( pos + 1 ) ] += 1;
39 }
40
41 std::set < std::string > res;
42 for ( const std::pair < const std::string, unsigned > & kv : collisions )
43 if ( kv.second == 1 )
44 res.insert ( kv.first );
45
46 return filter_completions ( res, text );
47 }
48
49 static std::set < std::string > fetchAlgorithmGroups ( const char *text ) {
50 std::set < std::string > res;
51
52 for ( const ext::pair < std::string, ext::vector < std::string > > & algo : abstraction::Registry::listAlgorithms ( ) ) {
53 std::set < std::string > groups = getGroups ( algo.first );
54 res.insert ( groups.begin ( ), groups.end ( ) );
55 }
56
57 return filter_completions ( res, text );
58 }
59
60 static std::set < std::string > fetchDatatypeGroups ( const char *text ) {
61 std::set < std::string > res;
62
63 for ( const std::string & dtt : abstraction::XmlRegistry::listDataTypes ( ) ) {
64 std::set < std::string > groups = getGroups ( dtt );
65 res.insert ( groups.begin ( ), groups.end ( ) );
66 }
67
68 return filter_completions ( res, text );
69 }
70
71 static std::set < std::string > fetchCommands ( const char *text ) {
72 return filter_completions ( { "print", "execute", "introspect", "quit", "help", "set" }, text );
73 }
74
75 static std::set < std::string > fetchCommandsIntrospect ( const char *text ) {
76 return filter_completions ( { "algorithms", "overloads", "casts", "datatypes", "variables", "bindings" }, text );
77 }
78
79 static std::set < std::string > fetchBindings ( const char *text ) {
80 return filter_completions ( addPrefix ( Prompt::getPrompt ( ).getEnvironment ( ).getBindingNames ( ), "#" ), text );
81 }
82
83 static std::set < std::string > fetchVariables ( const char *text ) {
84 return filter_completions ( addPrefix ( Prompt::getPrompt ( ).getEnvironment ( ).getVariableNames ( ), "$" ), text );
85 }
86
87 static std::set < std::string > fetchSet ( const char *text ) {
88 return filter_completions ( { "verbose", "measure", "optimizeXml", "seed" }, text );
89 }
90
91 static std::set < std::string > fetchFilepath ( const char *text ) {
92 std::set < std::string > res;
93 char *str;
94 int state = 0;
95
96 while ( ( str = rl_filename_completion_function ( text, state++ ) ) != nullptr ) {
97 res.insert ( str );
98 }
99
100 return res;
101 }
102
103public:
104 enum class CompletionContext {
105 COMMAND,
107
108 ALGORITHM,
110
112
113 FILEPATH,
115
116 VARIABLE,
117 BINDING,
118
119 SET,
120 };
121
122 static char** readline_completion ( const char *text, unsigned start, unsigned end );
123 static CompletionContext context ( const char *text, unsigned start, unsigned end );
124
125private:
126 static bool masterCommandCompletionTest ( const std::string & line, unsigned start, const std::string & expectation );
127 static std::set < std::string > addPrefix ( const std::set < std::string > & collection, const std::string & prefix );
128 static std::set < std::string > getGroups ( const std::string & qualified_name );
129 static std::set < std::string > filter_completions ( const std::set < std::string > & choices, const char *text );
130
136 template < typename... CompletionGeneratorFunc >
137 static char * completion_generator ( const char *text, int state, const CompletionGeneratorFunc & ... generators ) {
138 static std::string prefix;
139 static std::set < std::string > choices;
140 static std::set < std::string > :: const_iterator iter;
141
142 /* on first call initialize choices */
143 if ( state == 0 ) {
144 prefix = text;
145
146 choices = std::set < std::string > ( );
147
148 /* merge choices from all generators */
149 const std::vector < std::function < std::set < std::string > ( const char* ) > > gens = { generators... };
150 for ( const auto & gen : gens ) {
151 std::set < std::string > tmpres;
152 std::set < std::string > tmpg = gen ( text );
153
154 std::set_union ( std::begin ( choices ), std::end ( choices ),
155 std::begin ( tmpg ), std::end ( tmpg ),
156 std::inserter ( tmpres, std::begin ( tmpres ) ) );
157 choices = tmpres;
158 }
159
160 iter = choices.begin ( );
161 }
162
163 /* iterate through choices */
164 while ( iter != choices.end ( ) ) {
165 return strdup ( iter ++ -> c_str ( ) );
166 }
167
168 return nullptr;
169 }
170
176 static char * complete_algorithm ( const char *text, int state ) {
177 return completion_generator ( text, state, fetchAlgorithmsFullyQualifiedName, fetchAlgorithmsLastSegmentName );
178 }
179
180 static char * complete_algorithm_group ( const char *text, int state ) {
181 return completion_generator ( text, state, fetchAlgorithmGroups );
182 }
183
184 static char * complete_datatype_group ( const char *text, int state ) {
185 return completion_generator ( text, state, fetchDatatypeGroups );
186 }
187
188 static char * complete_command ( const char *text, int state ) {
189 return completion_generator ( text, state, fetchCommands );
190 }
191
192 static char * complete_command_introspect ( const char *text, int state ) {
193 return completion_generator ( text, state, fetchCommandsIntrospect );
194 }
195
196 static char * complete_variable ( const char *text, int state ) {
197 return completion_generator ( text, state, fetchVariables );
198 }
199
200 static char * complete_binding ( const char *text, int state ) {
201 return completion_generator ( text, state, fetchBindings );
202 }
203
204 static char * complete_filepath ( const char *text, int state ) {
205 return completion_generator ( text, state, fetchFilepath );
206 }
207
208 static char * complete_filepath_or_variable ( const char *text, int state ) {
209 return completion_generator ( text, state, fetchFilepath, fetchVariables );
210 }
211
212 static char * complete_set ( const char *text, int state ) {
213 return completion_generator ( text, state, fetchSet );
214 }
215
216};
217
static Prompt & getPrompt()
Definition: Prompt.h:28
Definition: ReadlinePromptCompletion.h:21
CompletionContext
Definition: ReadlinePromptCompletion.h:104
static ext::set< ext::pair< std::string, ext::vector< std::string > > > listAlgorithms()
Definition: Registry.cpp:21
static ext::set< std::string > listDataTypes()
Definition: XmlRegistry.cpp:14
Class extending the pair class from the standard library. Original reason is to allow printing of the...
Definition: pair.hpp:43
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
static CompletionContext context(const char *text, unsigned start, unsigned end)
Definition: ReadlinePromptCompletion.cpp:59
static char ** readline_completion(const char *text, unsigned start, unsigned end)
Definition: ReadlinePromptCompletion.cpp:113
return res
Definition: MinimizeByPartitioning.h:145
auto begin(Container &&cont) -> decltype(std::forward(cont).begin())
Definition: iterator.hpp:900
void start(measurements::stealth_string name, measurements::Type type)
Definition: measurements.cpp:14
void end()
Definition: measurements.cpp:19