| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | #!/usr/bin/python | 
					
						
							| 
									
										
										
										
											2016-02-02 20:47:49 +01:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | # Server that will accept connections from a Vim channel. | 
					
						
							|  |  |  | # Run this server and then in Vim you can open the channel: | 
					
						
							| 
									
										
										
										
											2016-02-20 15:47:01 +01:00
										 |  |  | #  :let handle = ch_open('localhost:8765') | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | # | 
					
						
							|  |  |  | # Then Vim can send requests to the server: | 
					
						
							| 
									
										
										
										
											2016-02-02 20:47:49 +01:00
										 |  |  | #  :let response = ch_sendexpr(handle, 'hello!') | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | # | 
					
						
							|  |  |  | # And you can control Vim by typing a JSON message here, e.g.: | 
					
						
							|  |  |  | #   ["ex","echo 'hi there'"] | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2016-02-02 20:47:49 +01:00
										 |  |  | # There is no prompt, just type a line and press Enter. | 
					
						
							|  |  |  | # To exit cleanly type "quit<Enter>". | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | # See ":help channel-demo" in Vim. | 
					
						
							| 
									
										
										
										
											2016-02-02 20:47:49 +01:00
										 |  |  | # | 
					
						
							|  |  |  | # This requires Python 2.6 or later. | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  | from __future__ import print_function | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | import json | 
					
						
							|  |  |  | import socket | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import threading | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  | try: | 
					
						
							|  |  |  |     # Python 3 | 
					
						
							|  |  |  |     import socketserver | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     # Python 2 | 
					
						
							|  |  |  |     import SocketServer as socketserver | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | thesocket = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  | class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def handle(self): | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |         print("=== socket opened ===") | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |         global thesocket | 
					
						
							|  |  |  |         thesocket = self.request | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |                 data = self.request.recv(4096).decode('utf-8') | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |             except socket.error: | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |                 print("=== socket error ===") | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |                 break | 
					
						
							|  |  |  |             if data == '': | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |                 print("=== socket closed ===") | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |                 break | 
					
						
							| 
									
										
										
										
											2016-03-20 21:08:34 +01:00
										 |  |  |             print("received: {0}".format(data)) | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 decoded = json.loads(data) | 
					
						
							|  |  |  |             except ValueError: | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |                 print("json decoding failed") | 
					
						
							|  |  |  |                 decoded = [-1, ''] | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |             # Send a response if the sequence number is positive. | 
					
						
							|  |  |  |             # Negative numbers are used for "eval" responses. | 
					
						
							|  |  |  |             if decoded[0] >= 0: | 
					
						
							|  |  |  |                 if decoded[1] == 'hello!': | 
					
						
							|  |  |  |                     response = "got it" | 
					
						
							| 
									
										
										
										
											2021-12-05 21:54:04 +00:00
										 |  |  |                     id = decoded[0] | 
					
						
							|  |  |  |                 elif decoded[1] == 'hello channel!': | 
					
						
							|  |  |  |                     response = "got that" | 
					
						
							|  |  |  |                     # response is not to a specific message callback but to the | 
					
						
							|  |  |  |                     # channel callback, need to use ID zero | 
					
						
							|  |  |  |                     id = 0 | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     response = "what?" | 
					
						
							| 
									
										
										
										
											2021-12-05 21:54:04 +00:00
										 |  |  |                     id = decoded[0] | 
					
						
							|  |  |  |                 encoded = json.dumps([id, response]) | 
					
						
							| 
									
										
										
										
											2016-03-20 21:08:34 +01:00
										 |  |  |                 print("sending {0}".format(encoded)) | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |                 self.request.sendall(encoded.encode('utf-8')) | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |         thesocket = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  | class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     HOST, PORT = "localhost", 8765 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) | 
					
						
							|  |  |  |     ip, port = server.server_address | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Start a thread with the server -- that thread will then start one | 
					
						
							|  |  |  |     # more thread for each request | 
					
						
							|  |  |  |     server_thread = threading.Thread(target=server.serve_forever) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Exit the server thread when the main thread terminates | 
					
						
							|  |  |  |     server_thread.daemon = True | 
					
						
							|  |  |  |     server_thread.start() | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |     print("Server loop running in thread: ", server_thread.name) | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-20 21:08:34 +01:00
										 |  |  |     print("Listening on port {0}".format(PORT)) | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |     while True: | 
					
						
							|  |  |  |         typed = sys.stdin.readline() | 
					
						
							|  |  |  |         if "quit" in typed: | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |             print("Goodbye!") | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |             break | 
					
						
							|  |  |  |         if thesocket is None: | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |             print("No socket yet") | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2016-03-20 21:08:34 +01:00
										 |  |  |             print("sending {0}".format(typed)) | 
					
						
							| 
									
										
										
										
											2016-02-01 22:01:10 +01:00
										 |  |  |             thesocket.sendall(typed.encode('utf-8')) | 
					
						
							| 
									
										
										
										
											2016-01-28 22:37:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     server.shutdown() | 
					
						
							|  |  |  |     server.server_close() |