|
1 | 1 | ;;; eglot-fsharp.el --- fsharp-mode eglot integration -*- lexical-binding: t; -*-
|
2 | 2 |
|
3 |
| -;; Copyright (C) 2019-2023 Jürgen Hötzel |
| 3 | +;; Copyright (C) 2019-2024 Jürgen Hötzel |
4 | 4 |
|
5 | 5 | ;; Author: Jürgen Hötzel <juergen@hoetzel.info>
|
6 | 6 | ;; Package-Requires: ((emacs "27.1") (eglot "1.4") (fsharp-mode "1.10") (jsonrpc "1.0.14"))
|
|
41 | 41 | "Install directory for FsAutoComplete."
|
42 | 42 | :group 'eglot-fsharp
|
43 | 43 | :risky t
|
44 |
| - :type 'directory) |
| 44 | + :type '(choice directory (const :tag "Use dotnet default for tool-path" nil))) |
45 | 45 |
|
46 | 46 | (defcustom eglot-fsharp-server-version 'latest
|
47 | 47 | "FsAutoComplete version to install or update."
|
|
63 | 63 | :abstractClassStubGenerationObjectIdentifier "this"
|
64 | 64 | :addFsiWatcher nil
|
65 | 65 | :codeLenses (:references (:enabled t)
|
66 |
| - :signature (:enabled t)) |
| 66 | + :signature (:enabled t)) |
67 | 67 | :disableFailedProjectNotifications nil
|
68 | 68 | :dotnetRoot ""
|
69 | 69 | :enableAdaptiveLspServer t
|
|
120 | 120 |
|
121 | 121 | (defun eglot-fsharp--path-to-server ()
|
122 | 122 | "Return FsAutoComplete path."
|
123 |
| - (file-truename (concat eglot-fsharp-server-install-dir "netcore/fsautocomplete" (if (eq system-type 'windows-nt) ".exe" "")))) |
| 123 | + (let ((base (if eglot-fsharp-server-install-dir |
| 124 | + (concat eglot-fsharp-server-install-dir "netcore/") |
| 125 | + "~/.dotnet/tools/"))) |
| 126 | + (expand-file-name (concat base "fsautocomplete" (if (eq system-type 'windows-nt) ".exe" ""))))) |
124 | 127 |
|
125 | 128 | ;; cache to prevent repetitive queries
|
126 | 129 | (defvar eglot-fsharp--latest-version nil "Latest fsautocomplete.exe version string.")
|
|
135 | 138 | (defun eglot-fsharp--installed-version ()
|
136 | 139 | "Return version string of fsautocomplete."
|
137 | 140 | (with-temp-buffer
|
138 |
| - (process-file "dotnet" nil t nil "tool" "list" "--tool-path" (file-name-directory (eglot-fsharp--path-to-server))) |
| 141 | + (if eglot-fsharp-server-install-dir |
| 142 | + (process-file "dotnet" nil t nil "tool" "list" "--tool-path" (file-name-directory (eglot-fsharp--path-to-server))) |
| 143 | + (process-file "dotnet" nil t nil "tool" "list" "-g")) |
139 | 144 | (goto-char (point-min))
|
140 | 145 | (when (search-forward-regexp "^fsautocomplete[[:space:]]+\\([0-9\.]*\\)[[:space:]]+" nil t)
|
141 | 146 | (match-string 1))))
|
|
150 | 155 | (let* ((default-directory (concat (file-remote-p default-directory)
|
151 | 156 | (file-name-directory (eglot-fsharp--path-to-server))))
|
152 | 157 | (stderr-file (make-temp-file "dotnet_stderr"))
|
153 |
| - (local-tool-path (or (file-remote-p default-directory 'localname) default-directory))) |
| 158 | + (local-tool-path (or (file-remote-p default-directory 'localname) default-directory)) |
| 159 | + (process-file-uninstall-args (if eglot-fsharp-server-install-dir |
| 160 | + (list "dotnet" nil `(nil ,stderr-file) nil "tool" "uninstall" "fsautocomplete" "--tool-path" local-tool-path) |
| 161 | + (list "dotnet" nil `(nil ,stderr-file) nil "tool" "uninstall" "-g" "fsautocomplete"))) |
| 162 | + (process-file-install-args (if eglot-fsharp-server-install-dir |
| 163 | + (list "dotnet" nil `(nil ,stderr-file) nil "tool" "install" "fsautocomplete" "--tool-path" local-tool-path "--version" version) |
| 164 | + (list "dotnet" nil `(nil ,stderr-file) nil "tool" "install" "fsautocomplete" "-g" "--version" version)))) |
| 165 | + (unless (file-directory-p default-directory) |
| 166 | + (make-directory default-directory)) |
154 | 167 | (condition-case err
|
155 | 168 | (progn
|
156 |
| - (unless (eglot-fsharp-current-version-p version) |
157 |
| - (message "Installing fsautocomplete version %s" version) |
158 |
| - (when (file-exists-p (concat (file-remote-p default-directory) |
159 |
| - (eglot-fsharp--path-to-server))) |
160 |
| - (unless (zerop (process-file "dotnet" nil `(nil |
161 |
| - ,stderr-file) |
162 |
| - nil "tool" "uninstall" |
163 |
| - "fsautocomplete" "--tool-path" |
164 |
| - local-tool-path)) |
165 |
| - (error "'dotnet tool uninstall fsautocomplete --tool-path %s' failed" default-directory)))) |
166 |
| - (unless (zerop (process-file "dotnet" nil `(nil ,stderr-file) nil |
167 |
| - "tool" "install" "fsautocomplete" |
168 |
| - "--tool-path" local-tool-path "--version" |
169 |
| - version)) |
| 169 | + (unless (or (eglot-fsharp-current-version-p version) (not (eglot-fsharp--installed-version))) |
| 170 | + (message "Uninstalling fsautocomplete version %s" (eglot-fsharp--installed-version)) |
| 171 | + (unless (zerop (apply #'process-file process-file-uninstall-args)) |
| 172 | + (error "'dotnet tool uninstall fsautocomplete ... failed"))) |
| 173 | + (unless (zerop (apply #'process-file process-file-install-args)) |
170 | 174 | (error "'dotnet tool install fsautocomplete --tool-path %s --version %s' failed" default-directory version)))
|
171 | 175 | (error
|
172 | 176 | (let ((stderr (with-temp-buffer
|
173 | 177 | (insert-file-contents stderr-file)
|
174 | 178 | (buffer-string))))
|
175 | 179 | (delete-file stderr-file)
|
176 |
| - (signal (car err) (format "%s: %s" (cdr err) stderr))))))) |
| 180 | + (signal (car err) (format "%s: %s" (cdr err) stderr))))) |
| 181 | + (message "Installed fsautocomplete to %s" (eglot-fsharp--path-to-server)))) |
177 | 182 |
|
178 | 183 | (defun eglot-fsharp--maybe-install (&optional version)
|
179 | 184 | "Downloads F# compiler service, and install in `eglot-fsharp-server-install-dir'."
|
180 |
| - (make-directory (concat (file-remote-p default-directory) |
181 |
| - (file-name-directory (eglot-fsharp--path-to-server))) t) |
| 185 | + (unless eglot-fsharp-server-install-dir |
| 186 | + (make-directory (concat (file-remote-p default-directory) |
| 187 | + (file-name-directory (eglot-fsharp--path-to-server))) t)) |
182 | 188 | (let* ((version (or version (if (eq eglot-fsharp-server-version 'latest)
|
183 | 189 | (eglot-fsharp--latest-version)
|
184 | 190 | eglot-fsharp-server-version))))
|
|
0 commit comments