From 5c36d25a4f411bfbe01ced442a186b75c661c1f1 Mon Sep 17 00:00:00 2001 From: Alan Zimmerman Date: Sun, 6 Aug 2023 16:07:10 +0100 Subject: [PATCH] lsp-erlang: Add initial support for erlang-language-platform (#4122) Supports erlang-ls and erlang-language-platform. --- CHANGELOG.org | 1 + clients/lsp-erlang.el | 118 ++++++++++++++++++++++++++++++++++++------ docs/lsp-clients.json | 10 +++- 3 files changed, 113 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.org b/CHANGELOG.org index 0104d00a16..65b54d42b6 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -1,5 +1,6 @@ * Changelog ** Unreleased 8.0.1 + * Add [[https://github.com/WhatsApp/erlang-language-platform][erlang-language-platform]] support in lsp-erlang client. * Add [[https://github.com/elixir-tools/credo-language-server][credo-language-server]] * Add support for clojure-ts-mode in clojure-lsp client * terraform-ls now supports prefill required fields and the ability to validate on save. diff --git a/clients/lsp-erlang.el b/clients/lsp-erlang.el index 2deae834d6..4a6c03fcd5 100644 --- a/clients/lsp-erlang.el +++ b/clients/lsp-erlang.el @@ -1,8 +1,8 @@ ;;; lsp-erlang.el --- Erlang Client settings -*- lexical-binding: t; -*- -;; Copyright (C) 2019 Roberto Aloi +;; Copyright (C) 2019-2023 Roberto Aloi, Alan Zimmerman -;; Author: Roberto Aloi +;; Author: Roberto Aloi, Alan Zimmerman ;; Keywords: erlang lsp ;; This program is free software; you can redistribute it and/or modify @@ -27,40 +27,128 @@ (require 'lsp-mode) (defgroup lsp-erlang nil - "LSP support for the Erlang programming language, using erlang-ls" + "LSP support for the Erlang programming language. +It can use erlang-ls or erlang-language-platform (ELP)." + :group 'lsp-mode) + +(defgroup lsp-erlang-ls nil + "LSP support for the Erlang programming language using erlang-ls." :group 'lsp-mode :link '(url-link "https://github.com/erlang-ls/erlang_ls")) -(defcustom lsp-erlang-server-path +(defgroup lsp-erlang-elp nil + "LSP support for the Erlang programming language using erlang-language-platform (ELP)." + :group 'lsp-mode + :link '(url-link "https://github.com/WhatsApp/erlang-language-platform")) + +(defcustom lsp-erlang-server 'erlang-ls + "Choose LSP server." + :type '(choice (const :tag "erlang-ls" erlang-ls) + (const :tag "erlang-language-platform" erlang-language-platform)) + :group 'lsp-erlang + :package-version '(lsp-mode . "6.2")) + +;; erlang-ls + +(defcustom lsp-erlang-ls-server-path "erlang_ls" "Path to the Erlang Language Server binary." - :group 'lsp-erlang + :group 'lsp-erlang-ls :risky t :type 'file) -(defcustom lsp-erlang-server-connection-type +(defcustom lsp-erlang-ls-server-connection-type 'stdio - "Type of connection to use with the Erlang Language Server: tcp or stdio" - :group 'lsp-erlang + "Type of connection to use with the Erlang Language Server: tcp or stdio." + :group 'lsp-erlang-ls :risky t :type 'symbol) -(defun lsp-erlang-server-start-fun (port) - `(,lsp-erlang-server-path +(defun lsp-erlang-ls-server-start-fun (port) + "Command to start erlang_ls in TCP mode on the given PORT." + `(,lsp-erlang-ls-server-path "--transport" "tcp" "--port" ,(number-to-string port))) -(defun lsp-erlang-server-connection () - (if (eq lsp-erlang-server-connection-type 'tcp) - (lsp-tcp-connection 'lsp-erlang-server-start-fun) - (lsp-stdio-connection `(,lsp-erlang-server-path "--transport" "stdio")))) +(defun lsp-erlang-ls-server-connection () + "Command to start erlang_ls in stdio mode." + (if (eq lsp-erlang-ls-server-connection-type 'tcp) + (lsp-tcp-connection 'lsp-erlang-ls-server-start-fun) + (lsp-stdio-connection `(,lsp-erlang-ls-server-path "--transport" "stdio")))) (lsp-register-client - (make-lsp-client :new-connection (lsp-erlang-server-connection) + (make-lsp-client :new-connection (lsp-erlang-ls-server-connection) :major-modes '(erlang-mode) :priority -1 :server-id 'erlang-ls)) + +;; erlang-language-platform + +(defcustom lsp-erlang-elp-server-command '("elp" "server") + "Command to start erlang-language-platform." + :type '(repeat string) + :group 'lsp-erlang-elp + :package-version '(lsp-mode . "8.0.0")) + +(defcustom lsp-erlang-elp-download-url + (format "https://github.com/WhatsApp/erlang-language-platform/releases/latest/download/%s" + (pcase system-type + ('gnu/linux "elp-linux.tar.gz") + ('darwin "elp-macos.tar.gz"))) + "Automatic download url for erlang-language-platform." + :type 'string + :group 'lsp-erlang-elp + :package-version '(lsp-mode . "8.0.0")) + +(defcustom lsp-erlang-elp-store-path (f-join lsp-server-install-dir + "erlang" + (if (eq system-type 'windows-nt) + "elp.exe" + "elp")) + "The path to the file in which `elp' will be stored." + :type 'file + :group 'lsp-erlang-elp + :package-version '(lsp-mode . "8.0.0")) + +(lsp-dependency + 'erlang-language-platform + `(:download :url lsp-erlang-elp-download-url + :decompress :targz + :store-path lsp-erlang-elp-store-path + :set-executable? t) + '(:system "elp")) + +;; Client + +(lsp-register-client + (make-lsp-client + :new-connection (lsp-stdio-connection + (lambda () + `(,(or (executable-find + (cl-first lsp-erlang-elp-server-command)) + (lsp-package-path 'erlang-language-platform) + "elp") + ,@(cl-rest lsp-erlang-elp-server-command)))) + :activation-fn (lsp-activate-on "erlang") + :priority (if (eq lsp-erlang-server 'erlang-language-platform) 1 -1) + :server-id 'elp + :custom-capabilities `((experimental . ((snippetTextEdit . ,(and lsp-enable-snippet (featurep 'yasnippet)))))) + :download-server-fn (lambda (_client callback error-callback _update?) + (lsp-package-ensure 'erlang-language-platform callback error-callback)))) + +(defun lsp-erlang-switch-server (&optional lsp-server) + "Switch priorities of lsp servers, unless LSP-SERVER is already active." + (interactive) + (let ((current-server (if (> (lsp--client-priority (gethash 'erlang-ls lsp-clients)) 0) + 'erlang-ls + 'erlang-language-platform))) + (unless (eq lsp-server current-server) + (dolist (server '(erlang-ls erlang-language-platform)) + (when (natnump (setf (lsp--client-priority (gethash server lsp-clients)) + (* (lsp--client-priority (gethash server lsp-clients)) -1))) + (message (format "Switched to server %s." server))))))) + (lsp-consistency-check lsp-erlang) (provide 'lsp-erlang) diff --git a/docs/lsp-clients.json b/docs/lsp-clients.json index 8fa3ada7c5..d3902f2022 100644 --- a/docs/lsp-clients.json +++ b/docs/lsp-clients.json @@ -220,13 +220,21 @@ "debugger": "Not available" }, { - "name": "erlang", + "name": "erlang-ls", "full-name": "Erlang", "server-name": "erlang_ls", "server-url": "https://github.com/erlang-ls/erlang_ls", "installation-url": "https://github.com/erlang-ls/erlang_ls", "debugger": "Not available" }, + { + "name": "erlang-elp", + "full-name": "Erlang", + "server-name": "elp", + "server-url": "https://github.com/WhatsApp/erlang-language-platform", + "installation-url": "https://github.com/WhatsApp/erlang-language-platform", + "debugger": "Not available" + }, { "name": "eslint", "full-name": "ESlint",