Replies: 6 comments 24 replies
-
I'll try to read this later, as one of my holidays projects is resting, but seems very similar to #1336 |
Beta Was this translation helpful? Give feedback.
-
When it came to auto selecting typescript or deno, this worked like a charm! Now I just need to figure out how to parse it in my mind. In particular, I haven't yet grokked this expression: `((js-mode (typescript-ts-base-mode :language-id "typescript")) .
,(my/deno-or-tss)) But I'm keen to figure it out. While the lsp connection worked for individual node and deno projects, I was not able to get the
|
Beta Was this translation helpful? Give feedback.
-
☝🏻 This is actually what caused me to seek help in the first place. Using As far as retaining the ability to have your own concept of an eglot project, I think it's wise. One of the things that emacs-lsp gets right is that it keeps its own conception of what and where a project is and as a result getting started is really straightforward. It just makes on-boarding from wherever a user happens to be much more friction-free. Apart from that, I must say that I am really enjoying eglot thus far. I just love how well it slides into all the other packages which I'm already using rather than maintain its own parallel ecosystem of everything. Nice work! Question: Before I decide on whether to go "bleeding edge. " How often do you release "stable" versions of eglot to ELPA? |
Beta Was this translation helpful? Give feedback.
-
@joaotavora I've finally got around to trying out the bleeding edge and subprojects (I've been limping along and mostly been fine, but enough was enough) I had to adapt it since it wasn't quite working. I had to unquote (defun @cowboyd/deno-lsp-or-typescript-language-server (&optional interactive project)
(let ((marker (and (eq (car project) 'eglot--project)
(plist-get (cddr project) :marker))))
(cond ((string= marker "package.json")
'("typescript-language-server" "--stdio"))
((string= marker "deno.json")
'("deno" "lsp" :initializationOptions '(:enable t :lint t)))
(interactive
(message "Can't guess server invocation for '%s'" (project-root project))
nil))))
(defun @cowboyd/js-project-find-function (dir)
(let* ((marker nil)
(root (catch 'done
(locate-dominating-file
default-directory
(lambda (d)
(dolist (f '("package.json" "deno.json"))
(when (file-exists-p (expand-file-name f d))
(setq marker f)
(throw 'done (file-name-parent-directory (expand-file-name f d))))))))))
(when root
;; Use experimental eglot--project project type which has some
;; space for user-defined props, `:marker' in this case
`(eglot--project ,root :marker ,marker))))
(add-hook 'project-find-functions '@cowboyd/js-project-find-function)
(add-to-list 'eglot-server-programs
`((js-mode (typescript-ts-base-mode :language-id "typescript"))
. @cowboyd/deno-lsp-or-typescript-language-server)) Also, note that I had to rejigger the So far, so good. I'll let you know if anything changes. |
Beta Was this translation helpful? Give feedback.
-
unquoting is obvisouly needed yes. I was going to swear I tested that code, but this means I haven't.
This would need a repro, so we can edebug it.
Does this happen without any subprojects at all? Or only when you plug in your solution? If the former, I can tell you I also work with a (veeery large 600 K files, larger than yours? 🤡 ) and It's not plugged into |
Beta Was this translation helpful? Give feedback.
-
For what it's worth, I've recently bumped into a similar problem, and came up with this refinement of a previous solution in this discussion: (defvar eglot-lsp-context)
(defvar project-find-functions)
(require 'cl-lib)
(defun joaot/eglot-project-find-function (dir)
(when eglot-lsp-context
(let* ((marker nil)
;; We use "dominating files" here, but we could use some
;; other criteria, like an Elisp data structure, or hack in
;; dir-locals for DIR (maybe with
;; `hack-dir-local-variables-non-file-buffer').
(root (locate-dominating-file
dir
(lambda (d)
;; Here, we search for these markers regardless of
;; other state such current major mode. We could
;; fix that easily, but that's out of scope for this small example.
(cl-loop for f in '("pyrightconfig.json" "pyproject.toml")
when (file-exists-p (expand-file-name f d))
do (setq marker f)
and return t)))))
(when root
;; Use the experimental eglot--project project type in latest
;; Eglot which has some space for user-defined props,
;; `:marker' in this case. One could make use of it, say, in a
;; functional entry to `eglot-server-programs', to decide
;; which server to run based on the marker or the type of
;; the project.
`(eglot--project ,root :marker ,marker)))))
(add-to-list 'project-find-functions
#'joaot/eglot-project-find-function) It's just a small iteration on what was already said above, just corrected to use |
Beta Was this translation helpful? Give feedback.
-
Hello,
My Holiday project is to take a stab at migrating from emacs-lsp to eglot for JavaScript development. Unfortunately, I've had a pretty rough go of it so far. The problem I'm having is that the repos I'm operating in have multiple JavaScript projects, some of which use Node as the primary development tool, others which use Deno as the primary development tool.
I need (I think) for Eglot to recognize each individual javascript package as a separate project apart from the main vc-project. Furthermore, if the package has a
deno.json
file, then use thedeno lsp
command, otherwise, use thetypescript-language-server
command.Thus far, I've tried to follow what I can piece together from the documentation and this discussion on using an alternate project root to add a hook to
project-find-functions
. Here's my set up so farHowever, as far as I can tell whenever I switch to the main project and find a file located in the sub-package,
(project-current)
is already computed for the buffer and assigned somewhere, and so my custom find function is never run. As a result, Eglot retrieves the root vc directory instead of the specific directory.It does appear to get the right directory if I open the sub-package file directly.
Finally, given that I have a way to detect between Deno projects and Node projects, what is the best way to get Eglot to select the right language server dynamically?
emacs-lsp solves this problem by letting you explicitly state via a config file that a directory is a workspace root. I haven't seen this as an option in Eglot (I could be wrong). But anyway, I've been looking to migrate over to eglot for some time, and so any insight would be very much appreciated.
Beta Was this translation helpful? Give feedback.
All reactions