Use :Shiki
to effortlessly get a syntax-highlighted HTML code snippet of a selected text or a provided range.
Powered by Shiki.
Important
The HTML snippet requires an additional CSS code to work.
demo.webm
node
shiki.nvim has a default plugin spec (see lazy.lua
). It lazy loads by default!
---@module "lazy"
---@type LazySpec
{
"TymekDev/shiki.nvim"
}
Tip
Annotations above are optional. Use lazydev.nvim to get completions based on them.
:Shiki
command works either on a selection or on a range:Shiki
has a single optional argument—a language to highlight- For example, run
:Shiki css
inside an HTML file to get CSS properly highlighted - If the language argument is not specified, then filetype is passed to Shiki1
- For example, run
- Use
:%Shiki
to generate a snippet from an entire file - Use
:Shiki
to generate a snippet from the current line - Use
:Shiki
with an active selection to generate a snippet from the selection
-- List supported languages
require("shiki").langs()
-- List supported themes
require("shiki").themes()
-- Rebuild Node a shiki.nvim's internal directory
require("shiki").setup({ install = { rebuild = true } })
-- Execute JS code in the shiki.nvim's internal directory
requie("shiki.node").exec('import { bundledThemes } from "shiki/themes"; console.log(bundledThemes)')
---@type shiki.Config
{
-- Create Shiki command?
cmd = true,
highlight = {
-- Shiki configuration (passed to `codeToHTML`)
shiki = {
defaultColor = false,
themes = {
dark = "github-dark",
light = "github-light",
},
},
},
install = {
-- Node package manager to install with
cmd = "npm",
-- Addtional arguments to the package manager
args = { "install", "--save-dev" },
-- Shiki version
version = "1.12.0",
-- Remove and reinitialize a shiki.nvim's internal directory?
rebuild = false,
},
}
Important
If you want to change Shiki version, then run setup()
with rebuild = true
once or run require("shiki.node").purge()
.
Recently, I have switched to writing blog posts directly in HTML (see A New Post Layout). I wanted to keep code snippets with syntax highlighting, though. That's how I came up with a script to create syntax-highlighted code snippets using Shiki:
// Usage:
// node highlight.js FILE [LANG] | pbcopy
import { readFileSync } from "node:fs";
import { codeToHtml } from "shiki";
const fileName = process.argv[2];
const lang = process.argv[3] ?? "text";
const code = readFileSync(fileName, { encoding: "utf-8" }).replace(/\n$/, "");
const result = await codeToHtml(code, {
lang: lang,
themes: {
light: "github-light",
dark: "github-dark",
},
defaultColor: false,
});
console.log(result);
You can read more about it in my HTML Code Snippets with Syntax Highlighting post.
This script is not ideal. It requires the code to be in a file and it does not detect a language. I realized that for the most part, the code I want to share lives in my editor.
Why should it be any more effort than selecting the relevant part and running a single command?—I asked myself.
...and that's how shiki.nvim came to be.
Footnotes
-
This won't always work. There might be filetypes that don't translate to Shiki's lang argument. If you find one, then please raise an issue. ↩