astoff / digestif

A language server for TeX and friends
Other
251 stars 6 forks source link

Corfu completion error, jsonrpc-error, trying to access unopened document #67

Open ChlorophyII opened 4 months ago

ChlorophyII commented 4 months ago

I am not sure whether it is a corfu problem or a digestif problem, but corfu works fine with other languages, together with Eglot. Here is a minimal config and tex file to reproduce the error. The error appears when corfu tries completion, after typing a few characters.

(use-package emacs
  :init
  (add-to-list 'package-archives
               '("melpa" . "https://melpa.org/packages/") t))

(use-package tex :ensure auctex)

(use-package corfu
  :ensure t
  :custom (corfu-auto t)
  :init (global-corfu-mode))

(use-package eglot :hook (LaTeX-mode . eglot-ensure))

(provide 'init)
\documentclass{article}
\begin{document}
tes
\end{document}

Error message:

Corfu completion error: jsonrpc-error: "request id=34 failed:", (jsonrpc-error-code . 1), (jsonrpc-error-message . "/opt/homebrew/share/lua/5.4/digestif/langserver.lua:34: Trying to access unopened document /Users/ChlorophyII/Documents/test.tex"), (jsonrpc-error-data)

With debug-on-error:

Debugger entered--Lisp error: (jsonrpc-error "request id=52 failed:" (jsonrpc-error-code . 1) (jsonrpc-error-message . "/opt/homebrew/share/lua/5.4/digestif/langserver.lu...") (jsonrpc-error-data))
  signal(jsonrpc-error ("request id=52 failed:" (jsonrpc-error-code . 1) (jsonrpc-error-message . "/opt/homebrew/share/lua/5.4/digestif/langserver.lu...") (jsonrpc-error-data)))
  #f(compiled-function (arg1 arg2 arg3 &rest rest) "Make a request to CONNECTION, wait for a reply.\nLike `jsonrpc-async-request' for CONNECTION, METHOD and PARAMS,\nbut synchronous.\n\nExcept in the case of a non-nil CANCEL-ON-INPUT (explained\nbelow), this function doesn't exit until anything interesting\nhappens (success reply, error reply, or timeout).  Furthermore,\nit only exits locally (returning the JSONRPC result object) if\nthe request is successful, otherwise it exits non-locally with an\nerror of type `jsonrpc-error'.\n\nDEFERRED and TIMEOUT as in `jsonrpc-async-request', which see.\n\nIf CANCEL-ON-INPUT is non-nil and the user inputs something while\nthe function is waiting, then it exits immediately, returning\nCANCEL-ON-INPUT-RETVAL.  Any future replies (normal or error) are\nignored." #<bytecode -0x115d77e935cb8352>)(#<eglot-lsp-server eglot-lsp-server-486bc858> :textDocument/completion (:textDocument (:uri "file:///Users/ChlorophyII/Documents/test.tex") :position (:line 3 :character 3) :context (:triggerKind 1)) :deferred :textDocument/completion :cancel-on-input t)
  apply(#f(compiled-function (arg1 arg2 arg3 &rest rest) "Make a request to CONNECTION, wait for a reply.\nLike `jsonrpc-async-request' for CONNECTION, METHOD and PARAMS,\nbut synchronous.\n\nExcept in the case of a non-nil CANCEL-ON-INPUT (explained\nbelow), this function doesn't exit until anything interesting\nhappens (success reply, error reply, or timeout).  Furthermore,\nit only exits locally (returning the JSONRPC result object) if\nthe request is successful, otherwise it exits non-locally with an\nerror of type `jsonrpc-error'.\n\nDEFERRED and TIMEOUT as in `jsonrpc-async-request', which see.\n\nIf CANCEL-ON-INPUT is non-nil and the user inputs something while\nthe function is waiting, then it exits immediately, returning\nCANCEL-ON-INPUT-RETVAL.  Any future replies (normal or error) are\nignored." #<bytecode -0x115d77e935cb8352>) (#<eglot-lsp-server eglot-lsp-server-486bc858> :textDocument/completion (:textDocument (:uri "file:///Users/ChlorophyII/Documents/test.tex") :position (:line 3 :character 3) :context (:triggerKind 1)) :deferred :textDocument/completion :cancel-on-input t))
  jsonrpc-request(#<eglot-lsp-server eglot-lsp-server-486bc858> :textDocument/completion (:textDocument (:uri "file:///Users/ChlorophyII/Documents/test.tex") :position (:line 3 :character 3) :context (:triggerKind 1)) :deferred :textDocument/completion :cancel-on-input t)
  #f(compiled-function () #<bytecode 0xe761b54c9398bdb>)()
  #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>)("" nil t)
  all-completions("" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil)
  completion-pcm--all-completions("" (prefix "t" any "e" any "s") #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil)
  completion-substring--all-completions("tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3 completion-flex--make-flex-pattern)
  #f(compiled-function (string table pred point) "Get flex-completions of STRING in TABLE, given PRED and POINT." #<bytecode 0x14e9e00a60879cc5>)("tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3)
  apply(#f(compiled-function (string table pred point) "Get flex-completions of STRING in TABLE, given PRED and POINT." #<bytecode 0x14e9e00a60879cc5>) ("tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3))
  completion-flex-all-completions("tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3)
  #f(compiled-function (style) #<bytecode -0x18c966dab7576dbf>)(flex)
  completion--some(#f(compiled-function (style) #<bytecode -0x18c966dab7576dbf>) (flex basic partial-completion emacs22))
  completion--nth-completion(2 "tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3 (metadata (category . eglot) (display-sort-function . #f(compiled-function (completions) #<bytecode 0x3905570360e206d>))))
  completion-all-completions("tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3 (metadata (category . eglot) (display-sort-function . #f(compiled-function (completions) #<bytecode 0x3905570360e206d>))))
  apply(completion-all-completions ("tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3 (metadata (category . eglot) (display-sort-function . #f(compiled-function (completions) #<bytecode 0x3905570360e206d>)))))
  corfu--filter-completions("tes" #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil 3 (metadata (category . eglot) (display-sort-function . #f(compiled-function (completions) #<bytecode 0x3905570360e206d>))))
  corfu--recompute("tes" 3 #f(compiled-function (probe pred action) #<bytecode 0xb17b3f04b64391a>) nil)
  corfu--update(interruptible)
  corfu--exhibit(auto)
  corfu--auto-complete-deferred((#<window 6 on test.tex> #<buffer test.tex> 231 46))
  apply(corfu--auto-complete-deferred (#<window 6 on test.tex> #<buffer test.tex> 231 46))
  timer-event-handler([t 26079 30907 817136 nil corfu--auto-complete-deferred ((#<window 6 on test.tex> #<buffer test.tex> 231 46)) nil 0 nil])

Versions: OS: macOS Sonoma 14.3.1 (23D60) Emacs: 29.2 Corfu: 1.2 Eglot: 1.12.29 digestif: 0.5.1-1

Any insight in how this may be resolved?

astoff commented 4 months ago

Thanks for the report. To be sure, $HOME/Documents/test.tex is the file you're currently editing, right?

ChlorophyII commented 4 months ago

Thanks for the report. To be sure, $HOME/Documents/test.tex is the file you're currently editing, right?

Yes.

skyler544 commented 3 months ago

I'm still in the process of debugging a similar problem, but digestif works out-of-the-box with the Emacs builtin tex-mode but not with auctex. I switched to using a Makefile instead of trying to use the auctex build commands; I'll post the Makefile here when I finish it.

skyler544 commented 3 months ago

Here's the Makefile:

LATEX   := latexmk -interaction=nonstopmode

all: clean-all build

build:
    $(LATEX)  -shell-escape -f -pdf

clean:
    $(LATEX) -c

clean-all:
    $(LATEX) -C

I'm no LaTeX whiz; there are probably many situations where this isn't sufficient. However, it works perfectly for the few documents I maintain, including automatic BibTeX and includes of files from subdirectories. The builtin tex-mode plus digestif plus this Makefile seems like a better experience than AUCTeX so far.

coffeemug commented 2 weeks ago

Confirming experiencing the same problem. Eglot+digestif gives me OP's error in auctex, but not in emacs built-in tex mode.

evgeniysharapov commented 4 days ago

The problem here is most likely you use AucTeX, that means that by default major-mode is something like ConTeXt-mode rather than context-mode. Below I am using ConTeXt-mode as an example, but adjust it to your case be it TeX-mode or LaTeX-mode.

If you use eglot it uses major-mode to figure out and to send language id to the LSP server. In fact you can run something like M-x eglot-events-buffer and see what it sends to the LSP server. If you use AucTeX it will send ConTeXt as a language id and thus LSP server throws an error Invalid LSP language id 'ConTeXt.

If we look inside langserver.lua we will see the list of languages it supports

local languageId_translation_table = {
  bibtex = "bibtex",
  context = "context",
  doctex = "doctex",
  latex = "latex",
  plain = "plain",
  plaintex = "plain",
  ["plain-tex"] = "plain",
  tex = "latex", -- this is for vim; maybe "tex" should mean "tex file, undecided format"
  texinfo = "texinfo"
}

The problem could be resolved by sending a correct language id to the LSP server. If you are using eglot you are in luck. You can specify a property for the symbol of the major mode you are in like so

(put 'ConTeXt-mode 'eglot-language-id "context")

Now you can reconnect eglot and it should work