1 #ifndef NEOVIM_QT_CONNECTOR 2 #define NEOVIM_QT_CONNECTOR 3 4 #include <QObject> 5 #include <QAbstractSocket> 6 #include <QProcess> 7 #include <QTextCodec> 8 #include "msgpackiodevice.h" 9 #include "auto/neovimapi0.h" 10 #include "auto/neovimapi1.h" 11 #include "auto/neovimapi2.h" 12 #include "auto/neovimapi3.h" 13 #include "auto/neovimapi4.h" 14 #include "auto/neovimapi5.h" 15 #include "auto/neovimapi6.h" 16 17 namespace NeovimQt { 18 19 class MsgpackIODevice; 20 class MsgpackRequestHandler; 21 class NeovimConnectorHelper; 22 class NeovimConnector: public QObject 23 { 24 friend class NeovimApi0; 25 friend class NeovimApi1; 26 friend class NeovimApi2; 27 friend class NeovimApi3; 28 friend class NeovimApi4; 29 friend class NeovimApi5; 30 friend class NeovimApi6; 31 friend class NeovimConnectorHelper; 32 Q_OBJECT 33 /** 34 * True if the Neovim instance is ready 35 * @see neovimObject 36 */ 37 Q_PROPERTY(bool ready READ isReady NOTIFY ready) 38 public: 39 enum NeovimError { 40 NoError=0, 41 NoMetadata, 42 MetadataDescriptorError, 43 UnexpectedMsg, 44 APIMisMatch, 45 NoSuchMethod, 46 FailedToStart, 47 Crashed, 48 SocketError, 49 MsgpackError, 50 RuntimeMsgpackError, 51 }; 52 #ifdef Q_ENUM 53 Q_ENUM(NeovimError) 54 #else 55 Q_ENUMS(NeovimError) 56 #endif 57 58 /** Underlying connection used to read Neovim */ 59 enum NeovimConnectionType { 60 OtherConnection, 61 SpawnedConnection, 62 HostConnection, 63 SocketConnection, 64 }; 65 66 NeovimConnector(QIODevice* s); 67 NeovimConnector(MsgpackIODevice* s); 68 static NeovimConnector* spawn(const QStringList& params=QStringList(), 69 const QString& exe="nvim"); 70 static NeovimConnector* connectToSocket(const QString&); 71 static NeovimConnector* connectToHost(const QString& host, int port); 72 static NeovimConnector* connectToNeovim(const QString& server=QString()); 73 static NeovimConnector* fromStdinOut(); 74 75 bool canReconnect(); 76 NeovimConnector* reconnect(); 77 78 NeovimError errorCause(); 79 QString errorString(); 80 81 bool isReady(); 82 NeovimApi0 * api0(); 83 NeovimApi1 * neovimObject(); 84 NeovimApi1 * api1(); 85 NeovimApi2 * api2(); 86 NeovimApi3 * api3(); 87 NeovimApi4 * api4(); 88 NeovimApi5 * api5(); 89 NeovimApi6 * api6(); 90 uint64_t channel(); 91 QString decode(const QByteArray&); 92 QByteArray encode(const QString&); 93 NeovimConnectionType connectionType(); 94 /** Some requests for metadata and ui attachment enforce a timeout in ms */ 95 void setRequestTimeout(int); 96 /** Set a handler for msgpack rpc requests **/ 97 void setRequestHandler(MsgpackRequestHandler *); 98 99 quint64 apiCompatibility(); 100 quint64 apiLevel(); 101 bool hasUIOption(const QByteArray& option); 102 103 signals: 104 /** Emitted when Neovim is ready @see ready */ 105 void ready(); 106 void error(NeovimError); 107 void processExited(int exitCode); 108 109 public slots: 110 void fatalTimeout(); 111 112 protected: 113 void setError(NeovimError err, const QString& msg); 114 void clearError(); 115 116 protected slots: 117 void discoverMetadata(); 118 void processError(QProcess::ProcessError); 119 void socketError(); 120 void msgpackError(); 121 122 private: 123 MsgpackIODevice *m_dev{ nullptr }; 124 NeovimConnectorHelper *m_helper{ nullptr }; 125 QString m_errorString; 126 NeovimError m_error{ NoError }; 127 128 NeovimApi0 *m_api0{ nullptr }; 129 NeovimApi1 *m_api1{ nullptr }; 130 NeovimApi2 *m_api2{ nullptr }; 131 NeovimApi3 *m_api3{ nullptr }; 132 NeovimApi4 *m_api4{ nullptr }; 133 NeovimApi5 *m_api5{ nullptr }; 134 NeovimApi6 *m_api6{ nullptr }; 135 quint64 m_channel{ 0 }; 136 quint64 m_api_compat{ 0 }; 137 quint64 m_api_supported{ 0 }; 138 139 // Store connection arguments for reconnect() 140 NeovimConnectionType m_ctype{ OtherConnection }; 141 QStringList m_spawnArgs; 142 QString m_spawnExe; 143 QString m_connSocket, m_connHost; 144 QVariantList m_uiOptions; 145 int m_connPort; 146 bool m_ready{ false }; 147 int m_timeout{ 20000 }; 148 }; 149 } // namespace NeovimQt 150 Q_DECLARE_METATYPE(NeovimQt::NeovimConnector::NeovimError) 151 Q_DECLARE_METATYPE(int64_t) 152 153 #endif 154