Skip to content

Commit b0ddb54

Browse files
committed
Add tcp communication on auto port in LSP server
1 parent b834662 commit b0ddb54

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

src/finecode/cli.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ def cli(): ...
187187
@click.option(
188188
"--stdio", "stdio", is_flag=True, default=False, help="Use stdio communication"
189189
)
190+
@click.option(
191+
"--tcp", "tcp_auto", is_flag=True, default=False,
192+
help="Start TCP server on a random free port; prints 'port:<N>' to stdout for client discovery"
193+
)
190194
@click.option("--host", "host", default=None, help="Host for TCP and WS server")
191195
@click.option(
192196
"--port", "port", default=None, type=int, help="Port for TCP and WS server"
@@ -197,6 +201,7 @@ def start_lsp(
197201
tcp: int | None,
198202
ws: bool,
199203
stdio: bool,
204+
tcp_auto: bool,
200205
host: str | None,
201206
port: int | None,
202207
):
@@ -212,7 +217,11 @@ def start_lsp(
212217
except Exception as e:
213218
logger.info(e)
214219

215-
if tcp is not None:
220+
if tcp_auto:
221+
comm_type = communication_utils.CommunicationType.TCP
222+
host = "127.0.0.1"
223+
port = None # main.start() will pick a free port and print it
224+
elif tcp is not None:
216225
comm_type = communication_utils.CommunicationType.TCP
217226
port = tcp
218227
host = "127.0.0.1"
@@ -221,7 +230,7 @@ def start_lsp(
221230
elif stdio is True:
222231
comm_type = communication_utils.CommunicationType.STDIO
223232
else:
224-
raise ValueError("Specify either --tcp, --ws or --stdio")
233+
raise ValueError("Specify either --tcp, --socket, --ws or --stdio")
225234

226235
asyncio.run(
227236
wm_lsp_server.start(comm_type=comm_type, host=host, port=port, log_level=log_level)

src/finecode/lsp_server/main.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
# docs: docs/cli.md
22
from __future__ import annotations
33

4+
import socket
5+
import sys
6+
47
from finecode.lsp_server import communication_utils, global_state
58
from finecode import logger_utils
69
from finecode.lsp_server.lsp_server import create_lsp_server
710

811

12+
def _find_free_port() -> int:
13+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
14+
s.bind(("", 0))
15+
return s.getsockname()[1]
16+
17+
918
async def start(
1019
comm_type: communication_utils.CommunicationType,
1120
host: str | None = None,
@@ -16,6 +25,10 @@ async def start(
1625
global_state.wm_log_level = log_level
1726
server = create_lsp_server()
1827
if comm_type == communication_utils.CommunicationType.TCP:
28+
if port is None:
29+
port = _find_free_port()
30+
sys.stdout.write(f"port:{port}\n")
31+
sys.stdout.flush()
1932
await server.start_tcp_async(host, port)
2033
else:
2134
await server.start_io_async()

0 commit comments

Comments
 (0)