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.
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.
1
{
2
"williamboman/mason.nvim",
3
opts = {
4
ensure_installed = {
5
"tinymist",
6
},
7
},
8
}
1
{
2
"williamboman/mason.nvim",
3
opts = {
4
ensure_installed = {
5
"tinymist",
6
},
7
},
8
}
-
Or manually:
Finding Executable
To enable LSP, you must install
tinymist
. You can findtinymist
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 commandtypst-ts-lsp-download-binary
to download the latest stable binary oftinymist
attypst-ts-lsp-download-path
. -
Build from source by cargo. You can also compile and install latest
tinymist
by Cargo.1
cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist
1
cargo install --git https://github.com/Myriad-Dreamin/tinymist --locked tinymist
-
Configuration
-
With
lspconfig
:1
require("lspconfig")["tinymist"].setup {
2
settings = {
3
formatterMode = "typstyle",
4
exportPdf = "onType",
5
semanticTokens = "disable"
6
}
7
}
1
require("lspconfig")["tinymist"].setup {
2
settings = {
3
formatterMode = "typstyle",
4
exportPdf = "onType",
5
semanticTokens = "disable"
6
}
7
}
-
Or with
Coc.nvim
:1
{
2
"languageserver": {
3
"tinymist": {
4
"command": "tinymist",
5
"filetypes": ["typst"],
6
"settings": { ... }
7
}
8
}
9
}
1
{
2
"languageserver": {
3
"tinymist": {
4
"command": "tinymist",
5
"filetypes": ["typst"],
6
"settings": { ... }
7
}
8
}
9
}
-
Or finally with the builtin lsp protocol:
1
vim.lsp.config['tinymist'] = {
2
cmd = {'tinymist'},
3
filetypes = {'typst'}
4
settings = {
5
-- ...
6
}
7
}
1
vim.lsp.config['tinymist'] = {
2
cmd = {'tinymist'},
3
filetypes = {'typst'}
4
settings = {
5
-- ...
6
}
7
}
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:
1
formatterMode = "typstyle"
1
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
1
-- lazy.nvim
2
{
3
'chomosuke/typst-preview.nvim',
4
lazy = false, -- or ft = 'typst'
5
version = '1.*',
6
opts = {}, -- lazy.nvim will implicitly calls `setup {}`
7
}
1
-- lazy.nvim
2
{
3
'chomosuke/typst-preview.nvim',
4
lazy = false, -- or ft = 'typst'
5
version = '1.*',
6
opts = {}, -- lazy.nvim will implicitly calls `setup {}`
7
}
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.
1
vim.api.nvim_create_user_command("OpenPdf", function()
2
local filepath = vim.api.nvim_buf_get_name(0)
3
if filepath:match("%.typ$") then
4
os.execute("open " .. vim.fn.shellescape(filepath:gsub("%.typ$", ".pdf")))
5
-- replace open with your preferred pdf viewer
6
-- os.execute("zathura " .. vim.fn.shellescape(filepath:gsub("%.typ$", ".pdf")))
7
end
8
end, {})
9
1
vim.api.nvim_create_user_command("OpenPdf", function()
2
local filepath = vim.api.nvim_buf_get_name(0)
3
if filepath:match("%.typ$") then
4
os.execute("open " .. vim.fn.shellescape(filepath:gsub("%.typ$", ".pdf")))
5
-- replace open with your preferred pdf viewer
6
-- os.execute("zathura " .. vim.fn.shellescape(filepath:gsub("%.typ$", ".pdf")))
7
end
8
end, {})
9
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:
1
// in file: /sub.typ
2
// Error: unknown label 'label-in-main'
3
@label-in-main
4
// in file: /main.typ
5
#include "sub.typ"
6
= Heading <label-in-main>
1
// in file: /sub.typ
2
// Error: unknown label 'label-in-main'
3
@label-in-main
4
// in file: /main.typ
5
#include "sub.typ"
6
= Heading <label-in-main>
The solution is a bit internal, which should get further improvement, but you can pin a main file by command.
1
-- pin the main file
2
vim.lsp.buf.execute_command({ command = 'tinymist.pinMain', arguments = { vim.api.nvim_buf_get_name(0) } })
3
-- unpin the main file
4
vim.lsp.buf.execute_command({ command = 'tinymist.pinMain', arguments = { nil } })
1
-- pin the main file
2
vim.lsp.buf.execute_command({ command = 'tinymist.pinMain', arguments = { vim.api.nvim_buf_get_name(0) } })
3
-- unpin the main file
4
vim.lsp.buf.execute_command({ command = 'tinymist.pinMain', arguments = { nil } })
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:
1
:set filetype=typst
1
:set filetype=typst
In older versions of Neovim an autocommand may be necessary.
1
autocmd BufNewFile,BufRead *.typ setfiletype typst
1
autocmd BufNewFile,BufRead *.typ setfiletype typst
Contributing
You can submit issues or make PRs to GitHub.