/** context sensitive completion * take current line, give list of completions (both atoms and files) * thanks to Jan for crafting a proper interface wrapping SWI-Prolog available facilities */ QString Completion::initialize(int promptPosition, QTextCursor c, QStringList &strings) { QString rets; SwiPrologEngine::in_thread _int; try { int p = c.position(); Q_ASSERT(p >= promptPosition); c.setPosition(promptPosition, c.KeepAnchor); QString left = c.selectedText(); if (left.length()) { PlString Before(left.toStdWString().data()); c.setPosition(p); c.movePosition(c.EndOfLine, c.KeepAnchor); QString after = c.selectedText(); PlString After(after.toStdWString().data()); PlTerm Completions, Delete, word; if (PlCall("prolog", "complete_input", PlTermv(Before, After, Delete, Completions))) for (PlTail l(Completions); l.next(word); ) strings.append(t2w(word)); c.setPosition(p); rets = t2w(Delete); } } catch(PlException e) { qDebug() << t2w(e); } catch(...) { qDebug() << "..."; } return rets; }
/** initialize and cache all predicates with description */ bool Completion::helpidx() { if (helpidx_status == untried) { helpidx_status = missing; SwiPrologEngine::in_thread _e; try { if ( PlCall("load_files(library(helpidx), [silent(true)])") && PlCall("current_module(help_index)")) { { PlTerm Name, Arity, Descr, Start, Stop; PlQuery q("help_index", "predicate", V(Name, Arity, Descr, Start, Stop)); while (q.next_solution()) { long arity = Arity.type() == PL_INTEGER ? long(Arity) : -1; QString name = t2w(Name); t_pred_docs::iterator x = pred_docs.find(name); if (x == pred_docs.end()) x = pred_docs.insert(name, t_decls()); x.value().append(qMakePair(int(arity), t2w(Descr))); } } if (PlCall("load_files(library(console_input), [silent(true)])")) if (PlCall("current_module(prolog_console_input)")) helpidx_status = available; } /* if (!PlCall("current_module(prolog_console_input)")) { QString ci = "console_input.pl"; QFile f(QString(":/%1").arg(ci)); if (f.open(f.ReadOnly)) { QTextStream s(&f); if (!_e.named_load(ci, s.readAll())) qDebug() << "can't load" << ci; } } */ } catch(PlException e) { qDebug() << CCP(e); } } return helpidx_status == available && !pred_docs.isEmpty(); }
void Completion::initialize(QSet<QString> &strings, bool reload) { Q_UNUSED(reload) T PRED; for (current_predicate cp(PRED); cp; ) { QString p = t2w(PRED); if (p[0].isLetter()) strings.insert(p); } qDebug() << "Completion::initialize loaded" << strings.count(); }
QVariant term2variant(PlTerm t) { switch (t.type()) { case PL_VARIABLE: return QVariant(); case PL_INT: case PL_INTEGER: return QVariant(int(t)); case PL_FLOAT: return double(t); case PL_ATOM: case PL_STRING: return t2w(t); default: throw QObject::tr("term2variant: unknown type %1").arg(t.type()); } }
/** issue a query filling the model storage * this will change when I will learn how to call SWI-Prolog completion interface */ void Completion::initialize(QSet<QString> &strings, bool reload) { /*static QSet<QString> preds;*/ Q_UNUSED(reload) //static QMap<QString, QSet<QString>> cmods; T Mod, Exp, PI; for (module_property mp(Mod, exports(Exp)); mp; ) { for (L exp(Exp); exp.next(PI); ) //preds.insert(t2w(exp)); strings.insert(t2w(PI)); } /* if (curr.isEmpty() || reload) { curr.clear(); SwiPrologEngine::in_thread _int; try { PlTerm p,m,a,l,v; PlQuery q("setof", PlTermv(p, quv(m, quv(a, join(PlCompound("current_predicate", mod(m, arith(p, a))), neg(C("sub_atom", PlTermv(p, zero, one, _V, A("$")))) ))), l)); if (q.next_solution()) for (PlTail x(l); x.next(v); ) curr << t2w(v); PlTerm M, Ms; if (PlCall("setof", PlTermv(M, PlCompound("current_module", M), Ms))) for (PlTail x(Ms); x.next(M); ) curr << t2w(M); } catch(PlException e) { qDebug() << t2w(e); } } strings.unite(curr); */ }
/** polling loop til buffer ready */ ssize_t Swipl_IO::_read_(char *buf, size_t bufsize) { qDebug() << "_read_" << CVP(target); int thid = PL_thread_self(); // handle setup interthread and termination for ( ; ; ) { { QMutexLocker lk(&sync); if (target) { if (!target->thids.contains(thid)) { target->add_thread(thid); int rc = PL_thread_at_exit(eng_at_exit, this, FALSE); qDebug() << "installed" << rc; } break; } } if ( PL_handle_signals() < 0 ) return -1; SwiPrologEngine::msleep(10); } if ( buffer.isEmpty() ) { PL_write_prompt(TRUE); emit user_prompt(thid, SwiPrologEngine::is_tty(this)); } for ( ; ; ) { { QMutexLocker lk(&sync); if (!query.isEmpty()) { try { int rc = PlCall(query.toStdWString().data()); qDebug() << "PlCall" << query << rc; } catch(PlException e) { qDebug() << t2w(e); } query.clear(); } uint n = buffer.length(); Q_ASSERT(bufsize >= n); if (n > 0) { uint l = bufsize < n ? bufsize : n; memcpy(buf, buffer, l); buffer.remove(0, l); return l; } if (target->status == ConsoleEdit::eof) { target->status = ConsoleEdit::running; return 0; } } if ( PL_handle_signals() < 0 ) return -1; SwiPrologEngine::msleep(10); } }
int ToolbarConfig::current() { return t2w(t_current); }