Tinymist Docs

Neovim

Run and configure tinymisttinymist 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.
Work for full parity for all tinymisttinymist 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",
    
                                        
        },
    
                                        
      },
    
                                        
    }
    
                                        
    {
    
                                        
      "williamboman/mason.nvim",
    
                                        
      opts = {
    
                                        
        ensure_installed = {
    
                                        
          "tinymist",
    
                                        
        },
    
                                        
      },
    
                                        
    }
    
                                        
    {
    
                                        
      "williamboman/mason.nvim",
    
                                        
      opts = {
    
                                        
        ensure_installed = {
    
                                        
          "tinymist",
    
                                        
        },
    
                                        
      },
    
                                        
    }
    
                                        
    {
    
                                        
      "williamboman/mason.nvim",
    
                                        
      opts = {
    
                                        
        ensure_installed = {
    
                                        
          "tinymist",
    
                                        
        },
    
                                        
      },
    
                                        
    }
  • Or manually:

    To enable LSP, you must install tinymisttinymist. You can find tinymisttinymist 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-binarytypst-ts-lsp-download-binary to download the latest stable binary of tinymisttinymist at typst-ts-lsp-download-pathtypst-ts-lsp-download-path.

    • Build from source by cargo. You can also compile and install latest tinymisttinymist by Cargo.

      
                                              
      cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist
      
                                              
      cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist
      
                                              
      cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist
      
                                              
      cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist

Configuration

  • With lspconfiglspconfig:

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

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

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

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

Formatting

Either typstyletypstyle or typstfmttypstfmt. Both are now included in tinymisttinymist, you can select the one you prefer with:


                                
formatterMode = "typstyle"

                                
formatterMode = "typstyle"

                                
formatterMode = "typstyle"

                                
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 {}`

                                
}

                                
-- lazy.nvim

                                
{

                                
  'chomosuke/typst-preview.nvim',

                                
  lazy = false, -- or ft = 'typst'

                                
  version = '1.*',

                                
  opts = {}, -- lazy.nvim will implicitly calls `setup {}`

                                
}

                                
-- lazy.nvim

                                
{

                                
  'chomosuke/typst-preview.nvim',

                                
  lazy = false, -- or ft = 'typst'

                                
  version = '1.*',

                                
  opts = {}, -- lazy.nvim will implicitly calls `setup {}`

                                
}

                                
-- 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, {})

                                
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, {})

                                
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, {})

                                
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, {})
For Neovim prior to v0.9.5, os.executeos.execute can be used instead. This is not suggested. See Issue #1606 for more information.

Make sure to change exportPdfexportPdf 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/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>

                                
// in file: /sub.typ

                                
// Error: unknown label 'label-in-main'

                                
@label-in-main

                                
// in file: /main.typ

                                
#include "sub.typ"

                                
= Heading <label-in-main>

                                
// in file: /sub.typ

                                
// Error: unknown label 'label-in-main'

                                
@label-in-main

                                
// in file: /main.typ

                                
#include "sub.typ"

                                
= Heading <label-in-main>

                                
// 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,

                                
}

                                
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,

                                
}

                                
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,

                                
}

                                
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.nullvim.v.null should be used instead of nilnil in the argumentsarguments table when unpinning. See issue #1595.

For Neovim versions prior to 0.11.0, vim.lsp.buf.execute_commandvim.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 } })

                                
-- 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 } })

                                
-- 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 } })

                                
-- 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:mes command. :checkhealth:checkhealth and LspInfoLspInfo can also provide valuable information. Tinymist also creates a debug log that is usually at ~/.local/state/nvim/lsp.log~/.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.typ file extension as a typsttypst source file. In most cases is can be resolved with:


                                
:set filetype=typst

                                
:set filetype=typst

                                
:set filetype=typst

                                
:set filetype=typst

In older versions of Neovim an autocommand may be necessary.


                                
autocmd BufNewFile,BufRead *.typ setfiletype typst

                                
autocmd BufNewFile,BufRead *.typ setfiletype typst

                                
autocmd BufNewFile,BufRead *.typ setfiletype typst

                                
autocmd BufNewFile,BufRead *.typ setfiletype typst

Contributing

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