Skip to content

Instantly share code, notes, and snippets.

@TheVoxcraft
Created January 31, 2024 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheVoxcraft/c6c7a6e1682c95328f1a7e157e784f4c to your computer and use it in GitHub Desktop.
Save TheVoxcraft/c6c7a6e1682c95328f1a7e157e784f4c to your computer and use it in GitHub Desktop.
Simple LSPClient for Python
import os
# Define the path to the Python script you want to analyze
# path of this file
my_path = os.path.dirname(os.path.realpath(__file__))
file_path = os.path.join(my_path, 'main.py')
import subprocess
import json
class LSPClient:
def __init__(self, server_command):
# Start the LSP server process
self.process = subprocess.Popen(server_command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
bufsize=0, # unbuffered
text=True)
def send_request(self, method, params):
# Prepare LSP request payload
request = {
"jsonrpc": "2.0",
"id": 1, # Unique identifier
"method": method,
"params": params
}
request_str = json.dumps(request)
# Construct header
content_length = len(request_str.encode('utf-8'))
header = f"Content-Length: {content_length}\r\n\r\n"
# Send the request to the server's stdin
self.process.stdin.write(header + request_str)
self.process.stdin.flush()
def read_response(self):
# Read the header
header1 = self.process.stdout.readline()
# Extract Content-Length
content_length = int(header1.split(":")[1].strip()) + 1 # +1 for the newline
header2 = self.process.stdout.readline()
# Extract Content-Type
content_type = header2.split(":")[1].strip()
print("Got: ", content_type, f"(length: {content_length})")
# Read the content based on Content-Length
response_str = self.process.stdout.read(content_length).strip()
return json.loads(response_str)
def close(self):
# Close the subprocess
self.process.terminate()
# Example Usage
from pprint import pprint
if __name__ == "__main__":
# Replace with the actual command to start your LSP server
lsp_server_command = ["jedi-language-server"]
client = LSPClient(lsp_server_command)
# Example: Sending an 'initialize' request
init_params = {
"processId": None,
"rootUri": "file:///" + my_path,
"capabilities": { # Client capabilities
},
}
client.send_request("initialize", init_params)
pprint(client.read_response())
client.send_request("textDocument/didOpen", {
"textDocument": {
"uri": "file://" + file_path,
"languageId": "python",
"version": 1,
"text": open(file_path).read()
}
})
pprint(client.read_response())
client.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment