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