1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
// Auto generated {{date}} from nvim API level:{{api_level}}
#include "auto/neovimapi{{api_level}}.h"
#include "neovimconnector.h"
#include "msgpackrequest.h"
#include "msgpackiodevice.h"
#include "util.h"
namespace NeovimQt {
/* Unpack Neovim EXT types Window, Buffer Tabpage which are all
* uint64_t see Neovim:msgpack_rpc_to_
*/
QVariant unpackBufferApi{{api_level}}(MsgpackIODevice *dev, const char* in, quint32 size)
{
msgpack_unpacked result;
msgpack_unpacked_init(&result);
msgpack_unpack_return ret = msgpack_unpack_next(&result, in, size, NULL);
QVariant variant;
if (ret == MSGPACK_UNPACK_SUCCESS) {
switch (result.data.type) {
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
variant = (qint64)result.data.via.i64;
break;
case MSGPACK_OBJECT_POSITIVE_INTEGER:
variant = (quint64)result.data.via.u64;
break;
default:
// TODO it would be nice if we could call back MsgpackIoDevice method or primitive types here
qWarning() << "Unsupported type found for EXT type" << result.data.type << result.data;
}
}
msgpack_unpacked_destroy(&result);
return variant;
}
#define unpackWindowApi{{api_level}} unpackBufferApi{{api_level}}
#define unpackTabpageApi{{api_level}} unpackBufferApi{{api_level}}
NeovimApi{{api_level}}::NeovimApi{{api_level}}(NeovimConnector *c)
:m_c(c)
{
// EXT types
{% for typename in exttypes %}
m_c->m_dev->registerExtType({{exttypes[typename]}}, unpack{{typename}}Api{{api_level}});
{% endfor %}
connect(m_c->m_dev, &MsgpackIODevice::notification,
this, &NeovimApi{{api_level}}::neovimNotification);
}
// Slots
{% for f in functions %}
MsgpackRequest* NeovimApi{{api_level}}::{{f.name}}({{f.argstring}})
{
MsgpackRequest *r = m_c->m_dev->startRequestUnchecked("{{f.name}}", {{f.argcount}});
r->setFunction(NeovimApi{{api_level}}::NEOVIM_FN_{{f.name.upper()}});
connect(r, &MsgpackRequest::finished, this, &NeovimApi{{api_level}}::handleResponse);
connect(r, &MsgpackRequest::error, this, &NeovimApi{{api_level}}::handleResponseError);
{% for param in f.parameters %}
m_c->m_dev->{{param.sendmethod}}({{param.name}});
{% endfor %}
return r;
}
{% endfor %}
// Handlers
void NeovimApi{{api_level}}::handleResponseError(quint32 msgid, quint64 fun, const QVariant& res)
{
// TODO: support Neovim error types Exception/Validation/etc
QString errMsg;
const QVariantList asList = res.toList();
if (asList.size() >= 2) {
if (asList.at(1).canConvert<QByteArray>()) {
errMsg = m_c->m_dev->decode(asList.at(1).toByteArray());
} else {
errMsg = tr("Received unsupported Neovim error type");
}
}
switch(fun) {
{% for f in functions %}
case NeovimApi{{api_level}}::NEOVIM_FN_{{f.name.upper()}}:
emit err_{{f.name}}(errMsg, res);
break;
{% endfor %}
default:
m_c->setError(NeovimConnector::RuntimeMsgpackError, QStringLiteral("Received error for function that should not fail: %s").arg(fun));
}
}
void NeovimApi{{api_level}}::handleResponse(quint32 msgid, quint64 fun, const QVariant& res)
{
switch(fun) {
{% for f in functions %}
case NeovimApi{{api_level}}::NEOVIM_FN_{{f.name.upper()}}:
{
{% if f.return_type.native_type != 'void' %}
{{f.return_type.native_type}} data;
if (decode(res, data)) {
m_c->setError(NeovimConnector::RuntimeMsgpackError, "Error unpacking return type for {{f.name}}");
return;
} else {
emit on_{{f.name}}(data);
}
{% else %}
emit on_{{f.name}}();
{% endif %}
}
break;
{% endfor %}
default:
qWarning() << "Received unexpected response";
}
}
/**
* Check function table from api_metadata[1]
*
* This checks the API metadata build from the bindings against the metadata
* passed as argument.
*
* Returns false if there is an API mismatch
*/
bool NeovimApi{{api_level}}::checkFunctions(const QVariantList& ftable)
{
QList<Function> required;
required
{% for f in functions %}
<< Function("{{f.return_type.neovim_type}}", "{{f.name}}",
QList<QString>()
{% for param in f.parameters %}
<< QStringLiteral("{{param.neovim_type}}")
{% endfor %}
, false)
{% endfor %}
;
QList<Function> supported;
foreach(const QVariant& val, ftable) {
auto f = Function::fromVariant(val);
if (!f.isValid()) {
qDebug() << "Invalid function in metadata" << f;
continue;
}
supported.append(f);
if (!required.contains(f)) {
qDebug() << "Unknown function(api {{api_level}})" << f;
}
}
bool ok = true;
foreach(const Function& f, required) {
if (!supported.contains(f)) {
qDebug() << "- instance DOES NOT support API{{api_level}}:" << f;
ok = false;
}
}
return ok;
}
} // Namespace
|