// Custom includes
#include "../Logger/SenfLog.hh"
+#include "../../Utils/range.hh"
//#include "LineEditor.mpp"
#define prefix_
editor_.prompt(promptString());
editor_.defineKey(senf::term::KeyParser::Ctrl('D'),
senf::membind(&LineEditorClientReader::deleteCharOrExit, this));
+ editor_.defineKey(senf::term::KeyParser::Tab,
+ boost::bind(&term::bindings::complete,
+ _1,
+ senf::membind(&LineEditorClientReader::completePath, this)));
}
prefix_ void senf::console::detail::LineEditorClientReader::v_setupFailed()
term::bindings::deleteChar(editor);
}
+prefix_ void senf::console::detail::LineEditorClientReader::
+completePath(term::LineEditor & editor, unsigned b, unsigned e,
+ std::vector<std::string> & completions)
+{
+ std::string base (editor.text().substr(b,e));
+ CommandParser parser;
+ ParseCommandInfo cmd;
+ try {
+ parser.parsePath(base, cmd);
+ }
+ catch (CommandParser::ParserErrorException & ex) {
+ return;
+ }
+
+ ParseCommandInfo::TokensRange path (cmd.commandPath());
+ if (path.empty()) {
+ DirectoryNode::ChildrenRange cs (client().cwd().children());
+ for (DirectoryNode::ChildrenRange::iterator i (cs.begin()); i != cs.end(); ++i)
+ completions.push_back(i->first + (i->second->followLink().isDirectory() ? "/" : " "));
+ return;
+ }
+
+ ParseCommandInfo::TokensRange::const_iterator i (path.begin());
+ ParseCommandInfo::TokensRange::const_iterator const i_end (boost::prior(path.end()));
+ DirectoryNode * dir (& client().cwd());
+ std::string basePath;
+ for (; i != i_end; ++i)
+ if (*i == NoneToken()) {
+ if (i == path.begin()) {
+ dir = & client().root();
+ basePath = "/";
+ }
+ }
+ else if (*i == WordToken("..")) {
+ DirectoryNode * parent (dir->parent().get());
+ if (parent) dir = parent;
+ basePath += "../";
+ }
+ else if (*i == WordToken("."))
+ basePath += "./";
+ else {
+ if (dir->hasChild(i->value())) {
+ try {
+ dir = & dir->getDirectory(i->value());
+ }
+ catch (std::bad_cast &) {
+ return;
+ }
+ basePath += i->value() + "/";
+ }
+ else {
+ DirectoryNode::ChildrenRange cs (dir->completions(i->value()));
+ if (has_one_elt(cs)) {
+ GenericNode & node (cs.begin()->second->followLink());
+ if (!node.isDirectory())
+ return;
+ dir = static_cast<DirectoryNode*>(&node);
+ basePath += cs.begin()->first + "/";
+ }
+ else
+ return;
+ }
+ }
+
+ DirectoryNode::ChildrenRange cs (dir->completions(i->value()));
+ for (DirectoryNode::ChildrenRange::iterator j (cs.begin()); j != cs.end(); ++j)
+ completions.push_back(basePath + j->first
+ + (j->second->followLink().isDirectory() ? "/" : " "));
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "LineEditor.mpp"