I want to use LSP(Language Server Protocol) in local IDE(VScode) to get line number of specific function

22 Views Asked by At

(First of all, I'm not aware of concept of LSP server in VScode) I want to get the line number of specific function in the local project in IDE.

I'm using mac m2 / Vscode.

I tried 'sudo lsof -iTCP -sTCP:LISTEN -nP | grep :49421' and got 'Code\x20H 4056 123412 42u IPv4 0x93bc3373368d4b7d 0t0 TCP 127.0.0.1:49421 (LISTEN)'. It seems 49421 port is local LSP server in VScode.

I sent request by code below, and doesn't get answer with time running.

import json
import socket

def send_lsp_request(sock, request):
    request_str = json.dumps(request)
    content_length = len(request_str.encode('utf-8'))
    full_message = f"Content-Length: {content_length}\r\n\r\n{request_str}"
    print(f"Sending: {full_message}")  # Logging the request being sent
    sock.sendall(full_message.encode('utf-8'))

def receive_lsp_response(sock):
    headers = ''
    while '\r\n\r\n' not in headers:
        headers += sock.recv(1).decode('utf-8')

    content_length = 0
    for header in headers.split('\r\n'):
        if header.startswith('Content-Length'):
            content_length = int(header.split(': ')[1])
            break

    content = sock.recv(content_length).decode('utf-8')
    print(f"Received: {content}")  # Logging the received response
    return json.loads(content)

# Adjust the timeout as needed
TIMEOUT_SECONDS = 10


def receive_lsp_response(sock):
    """
    Receives a response from the LSP server via a socket.
    Parameters:
        sock (socket.socket): The socket connected to the server.
    Returns:
        dict: The parsed LSP response.
    """
    # Read headers
    headers = ''
    while '\r\n\r\n' not in headers:
        headers += sock.recv(1).decode('utf-8')

    # Extract content length
    content_length = 0
    for header in headers.split('\r\n'):
        if header.startswith('Content-Length'):
            content_length = int(header.split(': ')[1])
            break

    # Read the content
    content = sock.recv(content_length).decode('utf-8')

    return json.loads(content)

# Example LSP initialize request
initialize_request = {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
        "processId": None,
        "rootUri": "file:///Path/to/project/folder",
        "capabilities": {},
    }
}

# Example LSP document symbol request
document_symbol_request = {
    "jsonrpc": "2.0",
    "id": 2,
    "method": "textDocument/documentSymbol",
    "params": {
        "textDocument": {
            "uri": "file:///Path/to/student.py"
        }
    }
}
# Connect to the LSP server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.settimeout(TIMEOUT_SECONDS)  # Setting a timeout for socket operations
    try:
        s.connect(('127.0.0.1', 49421))
        
        # Initialize request (make sure this matches your LSP server's requirements)
        send_lsp_request(s, initialize_request)
        response = receive_lsp_response(s)
        print("Initialize Response:", json.dumps(response, indent=4))

        # Document symbol request (adjust as needed)
        send_lsp_request(s, document_symbol_request)
        response = receive_lsp_response(s)
        print("Document Symbol Response:", json.dumps(response, indent=4))

    except socket.timeout:
        print("The request timed out")
    except Exception as e:
        print(f"An error occurred: {e}")
        

Expected answers are such as

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": [
    {
      "name": "MyClass",
      "kind": 5,  // Class
      "range": {
        "start": { "line": 0, "character": 0 },
        "end": { "line": 10, "character": 1 }
      },
      "children": [
        {
          "name": "myFunction",
          "kind": 6,  // Function
          "range": {
            "start": { "line": 2, "character": 4 },
            "end": { "line": 4, "character": 5 }
          }
        }
      ]
    }
  ]
}
0

There are 0 best solutions below