HomeAboutPostsTagsProjectsRSS

Updated
Words655
TagsRead2 minutes

Using lsp-bridge for Language Server Protocol in Emacs

Emacs 29 introduced built-in TRAMP Docker support for editing files within containers. However, enabling auto-completion inside a container remains challenging.

After discovering lsp-bridge , I realized the benefit of a Python process interacting with the language server, rather than relying solely on Emacs Lisp.

I added a feature for automatic reconnection to remote SSH servers and started supporting devcontainers. Using nix-darwin to configure my MacBook, I implemented the devcontainer feature to install lsp-bridge and the language server within the devcontainer. This was facilitated by the Nix ecosystem . To make it work, I needed to start with patching the official Nix devcontainer feature and create separate projects — a long journey, but worthwhile.

Container File Buffer Handling

When opening files in a container, lsp-bridge creates an lsp-bridge buffer, inserts the file content, and uses it for editing and rendering diagnostic information. The remote file content on the container is maintained by the lsp-bridge server running inside the container.

I completed the handling of the visited file modification time for the buffer and enabled auto-revert mode to reload file content automatically when the formatter updates the file.

Using the created lsp-bridge buffer, I used set-visited-file-name to associate a buffer with a file path. However, saving the buffer after the first save prompts a warning: “File has been changed since visited.” This occurs due to discrepancies in how file timestamps are handled by Emacs through TRAMP. To resolve this, Emacs’ record of the file’s modification time must be manually updated with something like this:

(defun my-update-file-mod-time ()
  (when buffer-file-name
    (let ((mod-time (file-attribute-modification-time (file-attributes buffer-file-name))))
      (set-visited-file-modtime mod-time))))

(add-hook 'after-save-hook 'my-update-file-mod-time)

Emacs’ “auto-revert” mode, which automatically reverts buffers when the displayed files change externally, is also useful when files are updated by the formatter. Therefore, the file buffer must enable auto-revert-mode.

With these pieces in place, I now have a smooth editing experience with auto-completion inside the devcontainer.

Emacs rocks!