diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 35f99ff..a8b5ab8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,7 @@ jobs: run: | cd elixir-ls mix deps.get + MIX_ENV=prod mix compile - name: Resolve vscode-elixir-ls dependencies run: | npm install diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9a09d7f..414ec7c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,16 +9,9 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - with: - submodules: 'true' - uses: actions/setup-node@v3 with: node-version: 16 - - name: Setup Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: 1.12.x - otp-version: 22.x - name: install jq run: | sudo apt-get install jq diff --git a/.gitignore b/.gitignore index 0859792..5fe00fe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,3 @@ out node_modules .vscode-test/ *.vsix - -# We store the build artifacts from ElixirLS here -/elixir-ls-release diff --git a/elixir-ls b/elixir-ls index 7f7ba8a..910f7b1 160000 --- a/elixir-ls +++ b/elixir-ls @@ -1 +1 @@ -Subproject commit 7f7ba8ac7ad518945f7622369d13c16f48568b30 +Subproject commit 910f7b1644c97e1cbb593863fabea7e8ca7f4d95 diff --git a/elixir-ls-release/debugger.bat b/elixir-ls-release/debugger.bat new file mode 100755 index 0000000..6f26db4 --- /dev/null +++ b/elixir-ls-release/debugger.bat @@ -0,0 +1,17 @@ +@echo off & setlocal enabledelayedexpansion + +SET ELS_MODE=debugger +SET ELS_RELEASE="v0.14.0" +@REM SET ELS_LOCAL="1" +IF EXIST "%APPDATA%\elixir_ls\setup.bat" ( + ECHO "" | CALL "%APPDATA%\elixir_ls\setup.bat" > nul 2>&1 + IF %ERRORLEVEL% NEQ 0 EXIT 1 +) + +SET MIX_ENV=prod +@REM pipe echo to avoid passing protocol messages to quiet install command +@REM intercept stdout and stderr +@REM elixir is a batch script and needs to be called +ECHO "" | CALL elixir "%~dp0quiet_install.exs" > nul 2>&1 +IF %ERRORLEVEL% NEQ 0 EXIT 1 +elixir --erl "+sbwt none +sbwtdcpu none +sbwtdio none" "%~dp0debugger.exs" diff --git a/elixir-ls-release/debugger.exs b/elixir-ls-release/debugger.exs new file mode 100644 index 0000000..2785870 --- /dev/null +++ b/elixir-ls-release/debugger.exs @@ -0,0 +1,16 @@ +if System.get_env("ELS_LOCAL") == "1" do + Mix.install( + [ + {:elixir_ls, path: "#{__DIR__}/../elixir-ls"}, + ], + config_path: "#{__DIR__}/../elixir-ls/config/config.exs", + lockfile: "#{__DIR__}/../elixir-ls/mix.lock" + ) +else + Mix.install([ + {:elixir_ls, github: "elixir-lsp/elixir-ls", tag: System.get_env("ELS_RELEASE")} + ]) +end + + +ElixirLS.Debugger.CLI.main() diff --git a/elixir-ls-release/debugger.sh b/elixir-ls-release/debugger.sh new file mode 100755 index 0000000..b5bc4eb --- /dev/null +++ b/elixir-ls-release/debugger.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Launches the debugger. This script must be in the same directory as mix install launch script. + +readlink_f () { + cd "$(dirname "$1")" > /dev/null || exit 1 + filename="$(basename "$1")" + if [ -h "$filename" ]; then + readlink_f "$(readlink "$filename")" + else + echo "$(pwd -P)/$filename" + fi +} + +if [ -z "${ELS_INSTALL_PREFIX}" ]; then + dir="$(dirname "$(readlink_f "$0")")" +else + dir=${ELS_INSTALL_PREFIX} +fi + +export ELS_MODE=debugger +exec "${dir}/launch.sh" diff --git a/elixir-ls-release/language_server.bat b/elixir-ls-release/language_server.bat new file mode 100755 index 0000000..483efa5 --- /dev/null +++ b/elixir-ls-release/language_server.bat @@ -0,0 +1,17 @@ +@echo off & setlocal enabledelayedexpansion + +SET ELS_MODE=language_server +SET ELS_RELEASE="v0.14.0" +@REM SET ELS_LOCAL="1" +IF EXIST "%APPDATA%\elixir_ls\setup.bat" ( + ECHO "" | CALL "%APPDATA%\elixir_ls\setup.bat" > nul 2>&1 + IF %ERRORLEVEL% NEQ 0 EXIT 1 +) + +SET MIX_ENV=prod +@REM pipe echo to avoid passing protocol messages to quiet install command +@REM intercept stdout and stderr +@REM elixir is a batch script and needs to be called +ECHO "" | CALL elixir "%~dp0quiet_install.exs" > nul 2>&1 +IF %ERRORLEVEL% NEQ 0 EXIT 1 +elixir --erl "+sbwt none +sbwtdcpu none +sbwtdio none" "%~dp0language_server.exs" diff --git a/elixir-ls-release/language_server.exs b/elixir-ls-release/language_server.exs new file mode 100644 index 0000000..26186f7 --- /dev/null +++ b/elixir-ls-release/language_server.exs @@ -0,0 +1,16 @@ +if System.get_env("ELS_LOCAL") == "1" do + Mix.install( + [ + {:elixir_ls, path: "#{__DIR__}/../elixir-ls"}, + ], + config_path: "#{__DIR__}/../elixir-ls/config/config.exs", + lockfile: "#{__DIR__}/../elixir-ls/mix.lock" + ) +else + Mix.install([ + {:elixir_ls, github: "elixir-lsp/elixir-ls", tag: System.get_env("ELS_RELEASE")} + ]) +end + + +ElixirLS.LanguageServer.CLI.main() diff --git a/elixir-ls-release/language_server.sh b/elixir-ls-release/language_server.sh new file mode 100755 index 0000000..e04f162 --- /dev/null +++ b/elixir-ls-release/language_server.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Launches the language server. This script must be in the same directory as mix install launch script. + +readlink_f () { + cd "$(dirname "$1")" > /dev/null || exit 1 + filename="$(basename "$1")" + if [ -h "$filename" ]; then + readlink_f "$(readlink "$filename")" + else + echo "$(pwd -P)/$filename" + fi +} + +if [ -z "${ELS_INSTALL_PREFIX}" ]; then + dir="$(dirname "$(readlink_f "$0")")" +else + dir=${ELS_INSTALL_PREFIX} +fi + +export ELS_MODE=language_server +exec "${dir}/launch.sh" diff --git a/elixir-ls-release/launch.sh b/elixir-ls-release/launch.sh new file mode 100755 index 0000000..3c809c3 --- /dev/null +++ b/elixir-ls-release/launch.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# Actual launcher. This does the hard work of figuring out the best way +# to launch the language server or the debugger. +# + +# Running this script is a one-time action per project launch, so we opt for +# code simplicity instead of performance. Hence some potentially redundant +# moves here. + +# First order of business, see whether we can setup asdf-vm + +did_relaunch=$1 + +ASDF_DIR=${ASDF_DIR:-"${HOME}/.asdf"} + +asdf_vm="${ASDF_DIR}/asdf.sh" +if test -f "${asdf_vm}" +then + # asdf-vm does not support the plain posix shell. Figure out + # which one we need and relaunch ourselves with that. + case "${did_relaunch}" in + "") + if which bash >/dev/null + then + exec "$(which bash)" "$0" relaunch + elif which zsh >/dev/null + then + exec "$(which zsh)" "$0" relaunch + fi + ;; + *) + # We have an arg2, so we got relaunched. Therefore, we're running in a + # shell that supports asdf-vm. + . "${asdf_vm}" + ;; + esac +fi + +export ELS_RELEASE="v0.14.0" +# export ELS_LOCAL="1" + +# In case that people want to tweak the path, which Elixir to use, or +# whatever prior to launching the language server or the debugger, we +# give them the chance here. ELS_MODE will be set for +# the really complex stuff. Use an XDG compliant path. + +els_setup="${XDG_CONFIG_HOME:-$HOME/.config}/elixir_ls/setup.sh" +if test -f "${els_setup}" +then + . "${els_setup}" +fi + +# Setup done. Make sure that we have the proper actual path to this +# script so we can correctly configure the Erlang library path to +# include the local .ez files, and then do what we were asked to do. + +readlink_f () { + cd "$(dirname "$1")" > /dev/null || exit 1 + filename="$(basename "$1")" + if [ -h "$filename" ]; then + readlink_f "$(readlink "$filename")" + else + echo "$(pwd -P)/$filename" + fi +} + +if [ -z "${ELS_INSTALL_PREFIX}" ]; then + SCRIPT=$(readlink_f "$0") + SCRIPTPATH=$(dirname "$SCRIPT") +else + SCRIPTPATH=${ELS_INSTALL_PREFIX} +fi + +export MIX_ENV=prod +# Mix.install prints to stdout and stderr and reads from stdin +# we need to make sure it doesn't interfere with LSP/DAP +elixir "$SCRIPTPATH/quiet_install.exs" 1> /dev/null 2> /dev/null < /dev/zero || exit 1 + +exec elixir --erl "+sbwt none +sbwtdcpu none +sbwtdio none" "$SCRIPTPATH/$ELS_MODE.exs" diff --git a/elixir-ls-release/quiet_install.exs b/elixir-ls-release/quiet_install.exs new file mode 100644 index 0000000..cd7afb1 --- /dev/null +++ b/elixir-ls-release/quiet_install.exs @@ -0,0 +1,13 @@ +if System.get_env("ELS_LOCAL") == "1" do + Mix.install( + [ + {:elixir_ls, path: "#{__DIR__}/../elixir-ls"}, + ], + config_path: "#{__DIR__}/../elixir-ls/config/config.exs", + lockfile: "#{__DIR__}/../elixir-ls/mix.lock" + ) +else + Mix.install([ + {:elixir_ls, github: "elixir-lsp/elixir-ls", tag: System.get_env("ELS_RELEASE")} + ]) +end diff --git a/package-lock.json b/package-lock.json index a53cadd..70de62c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "elixir-ls", - "version": "0.13.0", + "version": "0.14.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "elixir-ls", - "version": "0.13.0", + "version": "0.14.0", "license": "MIT", "dependencies": { "shelljs": "^0.8.5", diff --git a/package.json b/package.json index 470ca1c..b59ab53 100644 --- a/package.json +++ b/package.json @@ -550,9 +550,9 @@ ] }, "scripts": { - "vscode:prepublish": "./prepublish.bash", - "compile": "tsc -b && cd elixir-ls && MIX_ENV=prod mix elixir_ls.release -o ../elixir-ls-release", - "watch": "cd elixir-ls && MIX_ENV=prod mix elixir_ls.release -o ../elixir-ls-release && cd .. && tsc -b -w", + "vscode:prepublish": "npm run compile", + "compile": "tsc -b", + "watch": "tsc -b -w", "update-vscode": "node ./node_modules/vscode/bin/install", "test": "node ./out/test/runTest.js", "lint": "eslint . --ext .js,.ts", diff --git a/prepublish.bash b/prepublish.bash deleted file mode 100755 index 46ddaf2..0000000 --- a/prepublish.bash +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -set -e - -tsc -p ./ -cd elixir-ls -mix deps.get -mix elixir_ls.release -o ../elixir-ls-release diff --git a/src/extension.ts b/src/extension.ts index 212a7b9..a3b5b36 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,6 +12,7 @@ import * as path from "path"; import { workspace, ExtensionContext, WorkspaceFolder, Uri } from "vscode"; import { + Executable, ExecuteCommandParams, LanguageClient, LanguageClientOptions, @@ -453,7 +454,7 @@ function startClient( .getConfiguration("elixirLS", clientOptions.workspaceFolder) .get("languageServerOverridePath")!; - const serverOpts = { + const serverOpts: Executable = { command: lsOverridePath ? path.join(lsOverridePath, command) : context.asAbsolutePath("./elixir-ls-release/" + command),