/ src / neovimconnector.h
neovimconnector.h
  1  #ifndef NEOVIM_QT_CONNECTOR
  2  #define NEOVIM_QT_CONNECTOR
  3  
  4  #include <QAbstractSocket>
  5  #include <QObject>
  6  #include <QProcess>
  7  
  8  #include "auto/neovimapi0.h"
  9  #include "auto/neovimapi1.h"
 10  #include "auto/neovimapi2.h"
 11  #include "auto/neovimapi3.h"
 12  #include "auto/neovimapi4.h"
 13  #include "auto/neovimapi5.h"
 14  #include "auto/neovimapi6.h"
 15  #include "msgpackiodevice.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  	Q_ENUM(NeovimError)
 53  
 54  	/** Underlying connection used to read Neovim */
 55          enum NeovimConnectionType {
 56  		OtherConnection,
 57  		SpawnedConnection,
 58  		HostConnection,
 59  		SocketConnection,
 60          };
 61  
 62  	NeovimConnector(QIODevice* s);
 63  	NeovimConnector(MsgpackIODevice* s);
 64  	static NeovimConnector* spawn(const QStringList& params=QStringList(),
 65  									const QString& exe="nvim");
 66  	static NeovimConnector* connectToSocket(const QString&);
 67  	static NeovimConnector* connectToHost(const QString& host, int port);
 68  	static NeovimConnector* connectToNeovim(const QString& server=QString());
 69  	static NeovimConnector* fromStdinOut();
 70  
 71  	bool canReconnect();
 72  	NeovimConnector* reconnect();
 73  
 74  	NeovimError errorCause();
 75  	QString errorString();
 76  
 77  	bool isReady();
 78  	NeovimApi0 * api0();
 79  	NeovimApi1 * neovimObject();
 80  	NeovimApi1 * api1();
 81  	NeovimApi2 * api2();
 82  	NeovimApi3 * api3();
 83  	NeovimApi4 * api4();
 84  	NeovimApi5 * api5();
 85  	NeovimApi6 * api6();
 86  	uint64_t channel();
 87  
 88  	// Decode a byte array as a string according to Neovim string encoding
 89  	inline QString decode(const QByteArray& in) { return m_dev->decode(in); }
 90  
 91  	// Encode a string into the appropriate encoding for Neovim
 92  	inline QByteArray encode(const QString& in) { return m_dev->encode(in); }
 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  	QString connectionDescription();
103  
104  signals:
105  	/** Emitted when Neovim is ready @see ready */
106  	void ready();
107  	void error(NeovimQt::NeovimConnector::NeovimError);
108  	void processExited(int exitCode);
109  	void aboutToClose();
110  
111  public slots:
112  	void fatalTimeout();
113  
114  protected:
115  	void setError(NeovimError err, const QString& msg);
116  	void clearError();
117  
118  protected slots:
119  	void discoverMetadata();
120  	void processError(QProcess::ProcessError);
121  	void socketError();
122  	void msgpackError();
123  
124  private:
125  	MsgpackIODevice *m_dev{ nullptr };
126  	NeovimConnectorHelper *m_helper{ nullptr };
127  	QString m_errorString;
128  	NeovimError m_error{ NoError };
129  
130  	NeovimApi0 *m_api0{ nullptr };
131  	NeovimApi1 *m_api1{ nullptr };
132  	NeovimApi2 *m_api2{ nullptr };
133  	NeovimApi3 *m_api3{ nullptr };
134  	NeovimApi4 *m_api4{ nullptr };
135  	NeovimApi5 *m_api5{ nullptr };
136  	NeovimApi6 *m_api6{ nullptr };
137  	quint64 m_channel{ 0 };
138  	quint64 m_api_compat{ 0 };
139  	quint64 m_api_supported{ 0 };
140  
141  	// Store connection arguments for reconnect()
142  	NeovimConnectionType m_ctype{ OtherConnection };
143  	QStringList m_spawnArgs;
144  	QString m_spawnExe;
145  	QString m_connSocket, m_connHost;
146  	QVariantList m_uiOptions;
147  	int m_connPort;
148  	bool m_ready{ false };
149  	int m_timeout{ 20000 };
150  };
151  } // namespace NeovimQt
152  Q_DECLARE_METATYPE(NeovimQt::NeovimConnector::NeovimError)
153  Q_DECLARE_METATYPE(int64_t)
154  
155  #endif