typst-lsp icon indicating copy to clipboard operation
typst-lsp copied to clipboard

Labels not found in multidocument project

Open yochem opened this issue 2 years ago • 14 comments

  • Component:

    • LSP (used with other editor)
  • Extension version: ?

  • LSP version: Version: 0.11.0, commit cc7bad9bd9764bfea783f2fab415cb3061fd8bff (Typst version 0.9.0)

  • OS version and name: MacOS 14.1.1

  • I am on the latest stable version of the extension/LSP.

  • I have searched the issues of this repo and believe that this is not a duplicate.

Issue

I have a multidocument project with the following structure:

~/thesis/
├── chapters
│   ├── appendix.typ
│   ├── conclusion.typ
│   ├── discussion.typ
│   ├── introduction.typ
│   ├── methodology.typ
│   ├── preface.typ
│   ├── related-work.typ
│   └── results.typ
├── conf.typ
├── references.bib
├── thesis.pdf
└── thesis.typ

With thesis.typ being:

#import "conf.typ": *

#include "chapters/introduction.typ"
#include "chapters/related-work.typ"
#include "chapters/methodology.typ"
#include "chapters/results.typ"
#include "chapters/conclusion.typ"
#include "chapters/discussion.typ"

#bibliography("references.bib", title: [References], style: "apa")

When opening e.g. chapters/introduction.typ, where references are cited (using @camelia2021), I get label does not exist in the document (typst). However, my workspace is set up correctly:

:lua=vim.lsp.list_workspace_folders()
{ "~/thesis" }

yochem avatar Nov 24 '23 10:11 yochem

Potential workaround in vscode: Just open all relevant files. The warnings clear themselves once the file containing the referenced object is open.

Nvm all errors are back once a file is edited.

v411e avatar Dec 18 '23 10:12 v411e

I'm experiencing this error too. I have a large document split in different files. Most of them have cites. These errors make even typst-lsp crash.

jvmonjo avatar Jan 28 '24 08:01 jvmonjo

Is this issue really closed? As far as I understand, #389 only proposed a workaround for editors which allow running custom LSP commands. This does not resolve the issue for me as I am using helix.

So as far as I understand the PR diff, what's missing is to add the Config::main_file as part of the LSP settings. Are there any blockers, or an issue where this is tracked? I'd be happy to contribute if it's not too complicated.

lukasjuhrich avatar Jan 28 '24 11:01 lukasjuhrich

Is this issue really closed? As far as I understand, #389 only proposed a workaround for editors which allow running custom LSP commands. This does not resolve the issue for me as I am using helix.

So as far as I understand the PR diff, what's missing is to add the Config::main_file as part of the LSP settings. Are there any blockers, or an issue where this is tracked? I'd be happy to contribute if it's not too complicated.

I don't think there are major blockers to do that, but it still needs to be done

astrale-sharp avatar Jan 28 '24 15:01 astrale-sharp

Is this issue really closed? As far as I understand, #389 only proposed a workaround for editors which allow running custom LSP commands. This does not resolve the issue for me as I am using helix.

So as far as I understand the PR diff, what's missing is to add the Config::main_file as part of the LSP settings. Are there any blockers, or an issue where this is tracked? I'd be happy to contribute if it's not too complicated.

@lukasjuhrich Could you also check why we cannot invoke typst-lsp.doPinMain in helix? typst-lsp.doPinMain is a command that could be used by all language server host, so may be usable by helix's extension. But currently no helix user tells whether it is usable or what makes it unusable in helix.

Myriad-Dreamin avatar Jan 31 '24 17:01 Myriad-Dreamin

Could you also check why we cannot invoke typst-lsp.doPinMain in helix?

@Myriad-Dreamin I just found out that there is a general-purpose command picker (:lsp-workspace-command), but that just invokes the workspace commands without arguments. Which makes sense, because if I understand the spec correctly, a workspace command is dynamically typed (arguments?: LspAny), so how should the editor know what to pass to this command.

Is this implicit signature knowledge of „the first argument should be a URI pointing to the desired MainFile“ hard-coded to the VSCode extension? Or are there parts of the LSP machinery that communicate this which I am unaware of?

Edit: here is an excerpt of (truncated) helix logs to illustrate the execution via the command picker:

-> {"jsonrpc":"2.0","method":"workspace/executeCommand","params":{"arguments":[],"command":"typst-lsp.doPinMain"},"id":1}
<- {"jsonrpc":"2.0","error":{"code":-32602,"message":"Missing file URI argument"},"id":1}

lukasjuhrich avatar Feb 01 '24 14:02 lukasjuhrich

Could you also check why we cannot invoke typst-lsp.doPinMain in helix?

@Myriad-Dreamin I just found out that there is a general-purpose command picker (:lsp-workspace-command), but that just invokes the workspace commands without arguments. Which makes sense, because if I understand the spec correctly, a workspace command is dynamically typed (arguments?: LspAny), so how should the editor know what to pass to this command.

Is this implicit signature knowledge of „the first argument should be a URI pointing to the desired MainFile“ hard-coded to the VSCode extension? Or are there parts of the LSP machinery that communicate this which I am unaware of?

Edit: here is an excerpt of (truncated) helix logs to illustrate the execution via the command picker:

-> {"jsonrpc":"2.0","method":"workspace/executeCommand","params":{"arguments":[],"command":"typst-lsp.doPinMain"},"id":1}
<- {"jsonrpc":"2.0","error":{"code":-32602,"message":"Missing file URI argument"},"id":1}

This is a key. You can execute typst-lsp.doPinMain in helix manually, which should be a first step.

The second step is to obtain a URL from wherever. In VSCode it is retrieved by getting an editor instance and then getting the current URL of that editor instance. Similarly, we might get a URL from helix.

With above two steps we can customized a new command that executes the command and pins current opened file, which I think of a good supplementary of further automatic solutions.

  • we may pin the first peeked file automatically, this may help the case: vim main.typ
  • we may pin the previewed file automatically like typst-preview.
  • as a supplementary, we can simply run that new command manually to pin some file temporarily.

Myriad-Dreamin avatar Feb 08 '24 07:02 Myriad-Dreamin

Has anyone using NeoVim been able to solve this (and at the same time #402) using the doPinMain functionality?

Joelius300 avatar Feb 26 '24 12:02 Joelius300

Has anyone using NeoVim been able to solve this (and at the same time #402) using the doPinMain functionality?

I have some code that (I think) sets it properly, but it doesn't fix the problem. The labels still aren't found and the language server still can't find the bibliography from my main file.

vim.keymap.set("n", "<Leader>lp", function()
  -- Pin `main.typ` as the main file if it exists
  local main_file = vim.fs.find("main.typ", { path = vim.fn.getcwd(), type = "file" })[1]
  if main_file ~= nil then
    vim.lsp.buf.execute_command({
      command = "typst-lsp.doPinMain",
      arguments = { vim.uri_from_fname(main_file) }
    })
    print("Pinned to " .. vim.uri_from_fname(main_file))
  end
end)

LoganWalls avatar Feb 27 '24 03:02 LoganWalls

Has anyone using NeoVim been able to solve this (and at the same time #402) using the doPinMain functionality?

I have some code that (I think) sets it properly, but it doesn't fix the problem. The labels still aren't found and the language server still can't find the bibliography from my main file.

vim.keymap.set("n", "<Leader>lp", function()
  -- Pin `main.typ` as the main file if it exists
  local main_file = vim.fs.find("main.typ", { path = vim.fn.getcwd(), type = "file" })[1]
  if main_file ~= nil then
    vim.lsp.buf.execute_command({
      command = "typst-lsp.doPinMain",
      arguments = { vim.uri_from_fname(main_file) }
    })
    print("Pinned to " .. vim.uri_from_fname(main_file))
  end
end)

Maybe you can try my version,

lspconfig.typst_lsp.setup({
  on_attach = function()
    vim.lsp.buf_request_sync(0, "workspace/executeCommand", {
      command = "typst-lsp.doPinMain",
      arguments = { vim.uri_from_fname(vim.fn.getcwd() .. "/main.typ") },
    }, 1000)
  end,
})

Using vim.lsp.buf_request_sync instead of vim.lsp.buf.execute_command.

Cheng0Xin avatar Mar 31 '24 02:03 Cheng0Xin

Thanks @Cheng0Xin! That gives me lsp suggestions for all the labels in the document when starting to type with @. Interestingly, it correctly gives these completion suggestions and doesn't show any error while typing, but as soon as I save the document, an error appears saying the label doesn't exist. It's still a big improvement for me but this caveat persists.

Joelius300 avatar Mar 31 '24 18:03 Joelius300

I'm also having this problem with multi-file setups and it's kind of making the extension unusable for me at the moment.

Victor-N-Suadicani avatar May 16 '24 13:05 Victor-N-Suadicani

Is there a way to disable these specific label errors in the meantime?

dmun avatar May 21 '24 07:05 dmun

Has anyone using NeoVim been able to solve this (and at the same time #402) using the doPinMain functionality?

I have some code that (I think) sets it properly, but it doesn't fix the problem. The labels still aren't found and the language server still can't find the bibliography from my main file.

vim.keymap.set("n", "<Leader>lp", function()
  -- Pin `main.typ` as the main file if it exists
  local main_file = vim.fs.find("main.typ", { path = vim.fn.getcwd(), type = "file" })[1]
  if main_file ~= nil then
    vim.lsp.buf.execute_command({
      command = "typst-lsp.doPinMain",
      arguments = { vim.uri_from_fname(main_file) }
    })
    print("Pinned to " .. vim.uri_from_fname(main_file))
  end
end)

Maybe you can try my version,

lspconfig.typst_lsp.setup({
  on_attach = function()
    vim.lsp.buf_request_sync(0, "workspace/executeCommand", {
      command = "typst-lsp.doPinMain",
      arguments = { vim.uri_from_fname(vim.fn.getcwd() .. "/main.typ") },
    }, 1000)
  end,
})

Using vim.lsp.buf_request_sync instead of vim.lsp.buf.execute_command.

This sort of solves the issue on my end.

The errors are showing. However, after opening a buffer to main.typ the errors disappear. They stay gone after closing the buffer.

InvisOn avatar Sep 22 '24 06:09 InvisOn