manateelazycat / lsp-bridge

A blazingly fast LSP client for Emacs
GNU General Public License v3.0
1.43k stars 208 forks source link

Connection issues with lsp-bridge-enable-with-tramp and doom emacs #769

Closed Bawaw closed 9 months ago

Bawaw commented 11 months ago

Hey, thank you for this package, it is the best experience I've had with LSP in emacs so far!

However, while trying to integrate lsp-bridge in my daily workflow (doom emacs + remote pyright) I hit a block. When I (setq lsp-bridge-enable-with-tramp 't) I fail to connect to the LSP server when opening a file using tramp (see logs below).

PS: When opening a remote file using lsp-bridge-open-remote-file everything works as expected.

Details:

Eval in Emacs: (lsp-bridge--first-start '60257)
Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/lsp_bridge.py", line 180, in send_message_dispatcher
    client = self.get_socket_client(data["host"], port)
  File "/home/bawaw/.lspbridge/lsp-bridge/lsp_bridge.py", line 398, in get_socket_client
    self.host_names[server_host]["username"],
KeyError: 'remotehostname'

Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/core/remote_file.py", line 63, in connect_ssh
    ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, key_filename=pub_key)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 377, in connect
    to_try = list(self._families_and_addresses(hostname, port))
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 202, in _families_and_addresses
    addrinfos = socket.getaddrinfo(
  File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
OSError: Int or String expected

Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/core/remote_file.py", line 63, in connect_ssh
    ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, key_filename=pub_key)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 377, in connect
    to_try = list(self._families_and_addresses(hostname, port))
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 202, in _families_and_addresses
    addrinfos = socket.getaddrinfo(
  File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
OSError: Int or String expected

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/core/remote_file.py", line 70, in connect_ssh
    ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, password=password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 377, in connect
    to_try = list(self._families_and_addresses(hostname, port))
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 202, in _families_and_addresses
    addrinfos = socket.getaddrinfo(
  File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
OSError: Int or String expected

Exception in thread Thread-11 (sync_tramp_remote):
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/bawaw/.lspbridge/lsp-bridge/lsp_bridge.py", line 278, in sync_tramp_remote
    client = self.get_socket_client(server_host, REMOTE_FILE_ELISP_CHANNEL)
  File "/home/bawaw/.lspbridge/lsp-bridge/lsp_bridge.py", line 396, in get_socket_client
    client = RemoteFileClient(
  File "/home/bawaw/.lspbridge/lsp-bridge/core/remote_file.py", line 47, in __init__
    self.chan = self.transport.open_channel("direct-tcpip", (self.ssh_host, self.server_port), ('0.0.0.0', 0))
AttributeError: 'NoneType' object has no attribute 'open_channel'
werhner commented 11 months ago

The problem seems to be that lsp-bridge cannot get the remote hostname. Are you using the ssh protocol? If so, please provide the tramp path of the file and the ssh config file. Thanks.

Bawaw commented 11 months ago

Yes, I'm using the ssh protocol. The path would look something like this: /ssh:bawaw@remotehostname:/usr/local/project/main.py

My SSH config file would then look like this:

Host remotehostname
  HostName remotehostname
  User bawaw
werhner commented 11 months ago

This question seems similar to issue https://github.com/manateelazycat/lsp-bridge/issues/758. Is the host name defined in .ssh/config in domain name format rather than IP format?

Bawaw commented 11 months ago

The config is indeed defined in name format. However, I also tried using ip format: /ssh:bawaw@x.x.x.x:/usr/local/project/main.py

With config:

Host x.x.x.x
  HostName x.x.x.x
  User bawaw

I get a slightly different error this time:

Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/lsp_bridge.py", line 180, in send_message_dispatcher
    client = self.get_socket_client(data["host"], port)
  File "/home/bawaw/.lspbridge/lsp-bridge/lsp_bridge.py", line 398, in get_socket_client
    self.host_names[server_host]["username"],
KeyError: 'x.x.x.x'

Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/core/remote_file.py", line 63, in connect_ssh
    ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, key_filename=pub_key)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 485, in connect
    self._auth(
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 818, in _auth
    raise saved_exception
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 788, in _auth
    key = self._key_from_filepath(
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 638, in _key_from_filepath
    key = klass.from_private_key_file(key_path, password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/pkey.py", line 421, in from_private_key_file
    key = cls(filename=filename, password=password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/ed25519key.py", line 65, in __init__
    signing_key = self._parse_signing_key_data(data, password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/ed25519key.py", line 98, in _parse_signing_key_data
    raise PasswordRequiredException(
paramiko.ssh_exception.PasswordRequiredException: Private key file is encrypted
werhner commented 11 months ago

Please update to the latest version and then execute lsp-bridge-tramp-show-hostnames function. After that, check if the output of the host configuration options meets expectations. The HostName should be in the IP format.

Bawaw commented 11 months ago

Hm, I'm still getting the error even when using the ipv4 format. Here is the complete stacktrace when I first try to connect to a file and then run lsp-bridge-tramp-show-hostnames:

Eval in Emacs: (lsp-bridge--first-start '50435)
ERROR:epc:ReturnError([Symbol('wrong-type-argument'), Symbol('stringp'), []])
Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/core/remote_file.py", line 70, in connect_ssh
    ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, key_filename=pub_key, sock=proxy)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 485, in connect
    self._auth(
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 818, in _auth
    raise saved_exception
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 788, in _auth
    key = self._key_from_filepath(
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 638, in _key_from_filepath
    key = klass.from_private_key_file(key_path, password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/pkey.py", line 421, in from_private_key_file
    key = cls(filename=filename, password=password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/ed25519key.py", line 65, in __init__
    signing_key = self._parse_signing_key_data(data, password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/ed25519key.py", line 98, in _parse_signing_key_data
    raise PasswordRequiredException(
paramiko.ssh_exception.PasswordRequiredException: Private key file is encrypted

Eval in Emacs: (message '"[LSP-Bridge] Connect bawaw@x.x.x.x#22...")
Eval in Emacs: (lsp-bridge-update-tramp-file-info '"/ssh:bawaw@x.x.x.x:/usr/local/project/main.py"> '"x.x.x.x" '"/usr/local/project/main.py" '"/ssh:bawaw@x.x.x.x:")
Traceback (most recent call last):
  File "/home/bawaw/.lspbridge/lsp-bridge/core/remote_file.py", line 70, in connect_ssh
    ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, key_filename=pub_key, sock=proxy)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 485, in connect
    self._auth(
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 818, in _auth
    raise saved_exception
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 788, in _auth
    key = self._key_from_filepath(
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/client.py", line 638, in _key_from_filepath
    key = klass.from_private_key_file(key_path, password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/pkey.py", line 421, in from_private_key_file
    key = cls(filename=filename, password=password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/ed25519key.py", line 65, in __init__
    signing_key = self._parse_signing_key_data(data, password)
  File "/home/bawaw/.local/lib/python3.10/site-packages/paramiko/ed25519key.py", line 98, in _parse_signing_key_data
    raise PasswordRequiredException(
paramiko.ssh_exception.PasswordRequiredException: Private key file is encrypted

Eval in Emacs: (message '"[LSP-Bridge] host_names:{'x.x.x.x': {'username': 'bawaw', 'ssh_port': 22, 'use_gssapi': False, 'proxy_command': None}}")
werhner commented 11 months ago

According to the provided log, it seems that the issue lies in the encryption of the private key file. Paramiko raised a PasswordRequiredException exception. Is your key file encrypted?

Bawaw commented 11 months ago

Alright so removing the password from my private key circumvented the encryption problems but when I connect I still get the following error: *messages*: or: Wrong type argument: lsp-bridge-epc-manager, nil *lsp-bridge*: ERROR:epc:ReturnError([Symbol('wrong-type-argument'), Symbol('stringp'), []])

With logging enabled I now get:

Eval in Emacs: (lsp-bridge--first-start '46367)
ERROR:epc:ReturnError([Symbol('wrong-type-argument'), Symbol('stringp'), []])
Eval in Emacs: (message '"[LSP-Bridge] Connect bawaw@x.x.x.x#22...")
Eval in Emacs: (lsp-bridge-update-tramp-file-info '"/ssh:bawaw@x.x.x.x:/usr/local/project/main.py"> '"x.x.x.x" '"/usr/local/project/main.py" '"/ssh:bawaw@x.x.x.x:")

I also noticed that in the following 3 scenario's the program behaves differently:

  1. lsp-bridge-open-remote-file I get or: Wrong type argument: lsp-bridge-epc-manager, nil and nothing happens.
  2. When I first enable logging and then use lsp-bridge-open-remote-file I also get the epc error but the file does open.
  3. When I first open a file using tramp and then use lsp-bridge-open-remote-file it also and I also get the epc error

The autocomplete also does not seem to be working when I'm using lsp-bridge-open-remote-file, I'm sorry for not noticing this earlier. I get the [LBR] file-name buffer but the autocomplete only returns some yas-snippets and search words.

werhner commented 11 months ago

In the opening tramp file, will the autocomplete return some yas-snippets or nothing at all? Please provide the log of remote lsp-birdge process.

Bawaw commented 11 months ago

When I open the file using tramp I get the following logs:

Eval in Emacs: (lsp-bridge--first-start '43967)
ERROR:epc:ReturnError([Symbol('wrong-type-argument'), Symbol('stringp'), []])
Eval in Emacs: (message '"[LSP-Bridge] Connect bcroqu0@x.x.x.x#22...")
Eval in Emacs: (lsp-bridge-update-tramp-file-info '"/ssh:bcroqu0@x.x.x.x:/usr/local/main.py" '"x.x.x.x" '"/usr/local/main.py" '"/ssh:bcroqu0@x.x.x.x:")

Autocomplete returns yas-snippets and search words: image

But no real lsp functionality: image

Log of remote lsp on initial file opening:

* Running lsp-bridge in remote server, use command 'lsp-bridge-open-remote-file' to open remote file.

--- [12:10:33.652359] Build connect from x.x.x.x:46196

last two entries of remote lsp after typing np. (I gave up on censoring the server ip and paths):

--- [12:11:30.565109] Recv window/logMessage notification from 'pyright' for project gembed
{
   "jsonrpc": "2.0",
   "method": "window/logMessage",
   "params": {
      "type": 3,
      "message": "Searching for source files"
   }
}

--- [12:11:30.565193] Recv window/logMessage notification from 'pyright' for project gembed
{
   "jsonrpc": "2.0",
   "method": "window/logMessage",
   "params": {
      "type": 3,
      "message": "Found 262 source files"
   }
}

--- [12:11:30.565279] Recv textDocument/signatureHelp response (59906) from 'pyright' for project gembed
{
   "jsonrpc": "2.0",
   "id": 59906,
   "result": null
}

--- [12:11:30.565372] Recv textDocument/publishDiagnostics notification from 'pyright' for project gembed

--- [12:11:30.565419] Record diagnostics from 'pyright' for file main.py
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///usr/local/micapollo01/MIC/DATA/STAFF/bcroqu0/projects/gembed/experiments/skull/1_landmarking/2_experiment/main.py",
      "version": 3,
      "diagnostics": [
         {
            "range": {
               "start": {
                  "line": 3,
                  "character": 2
               },
               "end": {
                  "line": 3,
                  "character": 3
               }
            },
            "message": "Expected member name after \".\"",
            "severity": 1,
            "source": "Pyright"
         }
      ]
   }
}
Eval in Emacs: (lsp-bridge-diagnostic--render '"/usr/local/micapollo01/MIC/DATA/STAFF/bcroqu0/projects/gembed/experiments/skull/1_landmarking/2_experiment/main.py" '"10.225.223.67" '((:range (:start (:line 3 :character 2) :end (:line 3 :character 3)) :message "Expected member name after \".\"" :severity 1 :source "Pyright" :server-name "pyright")) '1)

A more complete stacktrace (as much as my terminal allows): https://pastebin.com/ABm9rjk9

werhner commented 11 months ago
image

It seems that there are no issues with the SSH connection and LSP completion. The only problem is that your Emacs is not displaying the completion results. Can you open a local Python file to see if LSP completion results are displayed correctly?

Perhaps you can submit a new issue explaining the current problem to get more help. I am more familiar with the remote editing part, and apologize for not being able to provide more assistance with the display issue.

Bawaw commented 11 months ago

I think indeed think that this is a problem on the display side of things. I've noticed that sometimes I do get autocomplete, sometimes I get a different autocomplete and sometimes I do not get any completion. I'll play around with it a bit more and if I do not find the cause I'll create a new issue. image image image

There is one more problem on the remote connect side of things though (I think). When I open a file using tramp and I do not set lsp-bridge-enable-log I never get real autocomplete and the server does not build a connection.

image

Sever log: * Running lsp-bridge in remote server, use command 'lsp-bridge-open-remote-file' to open remote file.

manateelazycat commented 11 months ago

I commit https://github.com/manateelazycat/lsp-bridge/commit/a5651303a3b4b7368e08e381dc0e39cd9e8e9742

You can turn on lsp-bridge-enable-log, lsp-bridge will print debug message for completion predicate result, if result is nil, that's why completion menu not popup.

manateelazycat commented 10 months ago

Did you test with emacs -Q?

I guess other package in Doom will conflict with lsp-bridge.