digestif
digestif copied to clipboard
Corfu completion error, jsonrpc-error, trying to access unopened document
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?
Thanks for the report. To be sure, $HOME/Documents/test.tex
is the file you're currently editing, right?
Thanks for the report. To be sure,
$HOME/Documents/test.tex
is the file you're currently editing, right?
Yes.
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.
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.
Confirming experiencing the same problem. Eglot+digestif gives me OP's error in auctex, but not in emacs built-in tex mode.
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
@evgeniysharapov In fact, if I go to eglot-events-buffer
I see all my Digestif buffers get the language ID "tex", which seems to be by design, when I look up the definition of eglot--lookup-mode
. So this is a bug in the definiton of eglot-server-programs
.
That said, why do you think this is related to the bug described here?
@ChlorophyII, @skyler544: I can't reproduce this problem, but if you could call M-x eglot-events-buffer
and post the contents here (or send my by email privately) I might be able to understand the issue.
@astoff It could be specific to the eglot
configuration. I have it with default settings and had this issue when used digestif
with AucTeX
. Plain tex-mode
that comes with Emacs works fine. It is not the bug of digestif
and I don't think it's the bug in eglot
either. Perhaps an oddity of AucTeX
. The steps I have described fixed the issue, so I thought I would share it as a workaround
(add-hook 'ConTeXt-mode-hook
(lambda ()
(setq lsp-tex-server 'digestiff)
(put 'ConTeXt-mode 'eglot-language-id "context")
(eglot-ensure))))
I confirm I have the same issue with eglot + digestif. @evgeniysharapov solution doe snot work for me.
@mguzmann Can you post a backtrace? You should get one with M-x toggle-debug-on-error
.
Debugger entered--Lisp error: (jsonrpc-error "request id=71 failed:" (jsonrpc-error-code . 1) (jsonrpc-error-message . "/home/matias/.digestif/digestif/langserver.lua:34:...") (jsonrpc-error-data)) signal(jsonrpc-error ("request id=71 failed:" (jsonrpc-error-code . 1) (jsonrpc-error-message . "/home/matias/.digestif/digestif/langserver.lua:34:...") (jsonrpc-error-data))) #<subr jsonrpc-request>(#<eglot-lsp-server eglot-lsp-server-168a20ee0bbe> :textDocument/completion (:textDocument (:uri "file:///home/matias/Documentos/Uni/classes/cl-typo...") :position (:line 147 :character 6) :context (:triggerKind 1)) :deferred :textDocument/completion :cancel-on-input t) apply(#<subr jsonrpc-request> (#<eglot-lsp-server eglot-lsp-server-168a20ee0bbe> :textDocument/completion (:textDocument (:uri "file:///home/matias/Documentos/Uni/classes/cl-typo...") :position (:line 147 :character 6) :context (:triggerKind 1)) :deferred :textDocument/completion :cancel-on-input t)) jsonrpc-request(#<eglot-lsp-server eglot-lsp-server-168a20ee0bbe> :textDocument/completion (:textDocument (:uri "file:///home/matias/Documentos/Uni/classes/cl-typo...") :position (:line 147 :character 6) :context (:triggerKind 1)) :deferred :textDocument/completion :cancel-on-input t) #f(compiled-function () #<bytecode -0x13f0dc4b1de23531>)() #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>)("" nil t) completion-pcm--all-completions("" (prefix "i") #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>) nil) completion-substring--all-completions("i" #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>) nil 1 completion-flex--make-flex-pattern) completion-flex-all-completions("i" #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>) nil 1) #f(compiled-function (style) #<bytecode -0x1b64e8b274eba5bf>)(flex) completion--some(#f(compiled-function (style) #<bytecode -0x1b64e8b274eba5bf>) (flex basic fuzzy)) completion--nth-completion(2 "i" #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>) nil 1 (metadata (category . eglot) (display-sort-function . #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_145>))) completion-all-completions("i" #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>) nil 1 (metadata (category . eglot) (display-sort-function . #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_145>))) company--capf-completions("i" "" #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>) nil (metadata (category . eglot) (display-sort-function . #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_145>))) company-capf--candidates-1("i" "" #f(compiled-function (probe pred action) #<bytecode 0x1d27e1025dd04780>) nil (metadata (category . eglot) (display-sort-function . #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_145>)) nil) company-capf--candidates("i" "") #<subr company-capf>(candidates "i" "") company-flx-company-capf-advice(#<subr company-capf> candidates "i" "") apply(company-flx-company-capf-advice #<subr company-capf> (candidates "i" "")) company-capf(candidates "i" "") company--multi-backend-adapter-candidates((company-capf company-yasnippet) 2 nil) company--multi-backend-adapter((company-capf :with company-yasnippet) candidates "i" "") apply(company--multi-backend-adapter (company-capf :with company-yasnippet) (candidates "i" "")) company-call-backend-raw(candidates "i" "") company--fetch-candidates("i" "") company-calculate-candidates("i" nil "") company--begin-new() company--perform() company-auto-begin() company-idle-begin(#<buffer main.tex<cl-2>> #<window 3 on main.tex<cl-2>> 898 4041) apply(company-idle-begin (#<buffer main.tex<cl-2>> #<window 3 on main.tex<cl-2>> 898 4041)) timer-event-handler([t 26402 22981 558990 nil company-idle-begin (#<buffer main.tex<cl-2>> #<window 3 on main.tex<cl-2>> 898 4041) nil 65000 nil])