// 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);
+ if (i->second->isDirectory())
+ completions.push_back(i->first + "/");
+ }
+ 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("."))
+ ;
+ else {
+ if (dir->hasChild(i->value())) {
+ dir = & dir->getDirectory(i->value());
+ basePath += i->value() + "/";
+ } else {
+ DirectoryNode::ChildrenRange cs (dir->completions(i->value()));
+ if (has_one_elt(cs)) {
+ GenericNode * node (cs.begin()->second.get());
+ if (node->isLink())
+ node = & static_cast<LinkNode*>(node)->follow();
+ 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);
+ if (j->second->isDirectory())
+ completions.push_back(basePath + j->first + "/");
+ }
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "LineEditor.mpp"