tinymist/editors/neovim
Myriad-Dreamin 1210b54515
Some checks are pending
tinymist::ci / publish-vscode (push) Blocked by required conditions
tinymist::ci / build-vsc-assets (push) Blocked by required conditions
tinymist::ci / build-vscode (push) Blocked by required conditions
tinymist::ci / build-vscode-others (push) Blocked by required conditions
tinymist::ci / Duplicate Actions Detection (push) Waiting to run
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Waiting to run
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Waiting to run
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Blocked by required conditions
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-2022) (push) Blocked by required conditions
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Blocked by required conditions
tinymist::ci / prepare-build (push) Waiting to run
tinymist::ci / build-binary (push) Blocked by required conditions
tinymist::gh_pages / build-gh-pages (push) Waiting to run
feat: finally directly generate markdown files (#1881)
* feat: finally directly generate markdown files

* fix: trim

* fix: await
2025-07-07 13:11:23 +08:00
..
lua test: ensure pdf export onType to work (#1865) 2025-07-02 02:56:17 +08:00
samples feat: move neovim config files (#1857) 2025-06-30 10:49:42 +08:00
scripts feat: add a neovim plugin as the canonical lsp client implementation (#1842) 2025-06-25 22:12:55 +08:00
spec test: ensure pdf export onType to work (#1865) 2025-07-02 02:56:17 +08:00
.gitignore feat: add a neovim plugin as the canonical lsp client implementation (#1842) 2025-06-25 22:12:55 +08:00
bootstrap.sh feat: move neovim config files (#1857) 2025-06-30 10:49:42 +08:00
Configuration.md fix: read formatterProseWrap from server (#1856) 2025-07-05 21:13:01 +08:00
CONTRIBUTING.md feat: add a neovim plugin as the canonical lsp client implementation (#1842) 2025-06-25 22:12:55 +08:00
LICENSES-LEAN-NVIM feat: add a neovim plugin as the canonical lsp client implementation (#1842) 2025-06-25 22:12:55 +08:00
NOTICE feat: add a neovim plugin as the canonical lsp client implementation (#1842) 2025-06-25 22:12:55 +08:00
README.md feat: finally directly generate markdown files (#1881) 2025-07-07 13:11:23 +08:00

Tinymist Neovim Support for Typst

Run and configure tinymist in Neovim with support for all major distros and package managers.

Feature Integration

  • Language service (completion, definitions, etc.)
  • Code Formatting
  • Live Web Preview with typst-preview.

Note

Work for full parity for all tinymist features is underway. This will include: exporting to different file types, template preview, and multifile support. Neovim integration is behind VS Code currently but should be caught up in the near future.

Installation

  • (Recommended) mason.nvim.
    {
      "williamboman/mason.nvim",
      opts = {
        ensure_installed = {
          "tinymist",
        },
      },
    }
    
  • Or manually: To enable LSP, you must install tinymist. You can find tinymist by:
    • Night versions available at GitHub Actions.
    • Stable versions available at GitHub Releases.
      If you are using the latest version of typst-ts-mode, then you can use command typst-ts-lsp-download-binary to download the latest stable binary of tinymist at typst-ts-lsp-download-path.
    • Build from source by cargo. You can also compile and install latest tinymist by Cargo.
      cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist
      

Configuration

  • With lspconfig:

    require("lspconfig")["tinymist"].setup {
        settings = {
            formatterMode = "typstyle",
            exportPdf = "onType",
            semanticTokens = "disable"
        }
    }
    
  • Or with Coc.nvim:

    {
      "languageserver": {
        "tinymist": {
          "command": "tinymist",
          "filetypes": ["typst"],
          "settings": { ... }
        }
      }
    }
    
  • Or finally with the builtin lsp protocol:

    vim.lsp.config["tinymist"] = {
        cmd = { "tinymist" },
        filetypes = { "typst" },
        settings = {
            -- ...
        }
    }
    

For a full list of available settings see Tinymist Server Configuration.

Formatting

Either typstyle or typstfmt. Both are now included in tinymist, you can select the one you prefer with:

formatterMode = "typstyle"

Live Preview

Live preview can be achieved with either a web preview or a pdf reader that supports automatic reloading (zathura is good).

Web Preview

-- lazy.nvim
{
  'chomosuke/typst-preview.nvim',
  lazy = false, -- or ft = 'typst'
  version = '1.*',
  opts = {}, -- lazy.nvim will implicitly calls `setup {}`
}

See typst-preview for more installation and configuration options.

Pdf Preview

This preview method is slower because of compilation delays, and additional delays in the pdf reader refreshing.

It is often useful to have a command that opens the current file in the reader.

vim.api.nvim_create_user_command("OpenPdf", function()
  local filepath = vim.api.nvim_buf_get_name(0)
  if filepath:match("%.typ$") then
    local pdf_path = filepath:gsub("%.typ$", ".pdf")
    vim.system({ "open", pdf_path })
  end
end, {})

Note

For Neovim prior to v0.9.5, os.execute can be used instead. This is not suggested. See Issue #1606 for more information.

Make sure to change exportPdf to "onType" or "onSave".

Working with Multiple-Files Projects

Tinymist cannot know the main file of a multiple-files project if you don't tell it explicitly. This causes the well-known label error when editing the /sub.typ file in a project like that:

// in file: /sub.typ
// Error: unknown label 'label-in-main'
@label-in-main
// in file: /main.typ
#include "sub.typ"
= Heading <label-in-main>

The solution is a bit internal, which should get further improvement, but you can pin a main file by command.

require("lspconfig")["tinymist"].setup { -- Alternatively, can be used `vim.lsp.config["tinymist"]`
    -- ...
    on_attach = function(client, bufnr)
        vim.keymap.set("n", "<leader>tp", function()
            client:exec_cmd({
                title = "pin",
                command = "tinymist.pinMain",
                arguments = { vim.api.nvim_buf_get_name(0) },
            }, { bufnr = bufnr })
        end, { desc = "[T]inymist [P]in", noremap = true })

        vim.keymap.set("n", "<leader>tu", function()
            client:exec_cmd({
                title = "unpin",
                command = "tinymist.pinMain",
                arguments = { vim.v.null },
            }, { bufnr = bufnr })
        end, { desc = "[T]inymist [U]npin", noremap = true })
    end,
}

Note that vim.v.null should be used instead of nil in the arguments table when unpinning. See issue #1595.

For Neovim versions prior to 0.11.0, vim.lsp.buf.execute_command should be used instead:

-- pin the main file
vim.lsp.buf.execute_command({ command = 'tinymist.pinMain', arguments = { vim.api.nvim_buf_get_name(0) } })
-- unpin the main file
vim.lsp.buf.execute_command({ command = 'tinymist.pinMain', arguments = { vim.v.null } })

It also doesn't remember the pinned main file across sessions, so you may need to run the command again after restarting Neovim.

This could be improved in the future.

Troubleshooting

Generally you can find in depth information via the :mes command. :checkhealth and LspInfo can also provide valuable information. Tinymist also creates a debug log that is usually at ~/.local/state/nvim/lsp.log. Reporting bugs is welcome.

tinymist not starting when creating/opening files

This is most commonly due to nvim not recognizing the .typ file extension as a typst source file. In most cases is can be resolved with:

:set filetype=typst

In older versions of Neovim an autocommand may be necessary.

autocmd BufNewFile,BufRead *.typ setfiletype typst

Contributing

Please check the contributing guide for more information on how to contribute to the project.