A Neovim plugin that previews and manages MLIR .inc files inline — expand the
content of a TableGen-generated #include "...inc" directly into your buffer
(similar to :r path/to/file.inc, but tag-wrapped and reversible), so you can
read the generated declarations without leaving the file.
This is a Lua port of the MLIR Inc Previewer VS Code extension.
- Expand/collapse a single
.incinclude near the cursor, or expand all in the buffer. - Macro-aware mode: drops
#ifdef/#if ...blocks that are not active given the macros defined in the host file. - Macro-unaware mode: expands the full
.inccontent as-is. .incpath resolution via the LSP (clangd) first, then a filesystem fallback.- Expanded blocks are never written to disk (clean-on-save).
- Statusline component showing the number of open preview blocks.
- Neovim >= 0.9 (developed/tested on 0.11)
- An LSP such as
clangdis recommended for accurate.incpath resolution.
lazy.nvim / LazyVim:
{
'ConvolutedDog/mlir-inc-previewer.nvim',
event = { 'BufReadPre', 'BufNewFile' },
-- Register commands so lazy loads the plugin (needed for :help too):
cmd = {
'MlirIncToggle', 'MlirIncToggleFull', 'MlirIncExpandAll',
'MlirIncExpandAllFull', 'MlirIncClean', 'MlirIncCleanAndSave',
'MlirIncNext', 'MlirIncHelp', 'MlirIncRestart',
},
opts = {},
}LazyVim: save the above as ~/.config/nvim/lua/plugins/mlir-inc-previewer.lua.
packer.nvim:
use({
'ConvolutedDog/mlir-inc-previewer.nvim',
config = function() require('mlir-inc-previewer').setup() end,
})setup() is optional for the commands, but required to enable keymaps and
clean-on-save. Defaults shown below:
require('mlir-inc-previewer').setup({
-- File extensions the plugin attaches keymaps / clean-on-save to.
extensions = {
'c', 'cpp', 'cxx', 'h', 'hpp', 'hxx', -- standard
'cc', 'cp', 'c++', 'hh', 'hp', 'h++', -- variants
'inl', 'inc', 'ipp', 'tcc', 'tpp', -- inline / template
'def', -- definitions
'cu', 'cuh', -- CUDA
},
clean_on_save = true, -- clean preview blocks before :write
use_lsp = true, -- resolve .inc paths via the LSP (clangd) when supported
search_range = 3, -- look this many lines above/below the cursor for an include
deep_search = true, -- last-resort recursive project search (disable on huge repos)
omit_marker = true, -- macro-aware: /// summary where code was omitted
hide_inactive_blocks = false, -- true: drop entire inactive #if..#endif blocks
keymaps = {
toggle = '<leader>iu', -- Expand/Collapse (macro-aware)
toggle_full = '<leader>ij', -- Expand/Collapse (macro-unaware)
expand_all = '<leader>iy', -- Expand all (macro-aware)
expand_all_full = '<leader>ih', -- Expand all (macro-unaware)
clean = '<leader>ic', -- Clean all preview blocks
next = '<leader>in', -- Navigate to next preview block
},
})Set any keymap to false or '' to disable it.
Macro-aware inactive blocks — two modes:
| Option | Effect |
|---|---|
hide_inactive_blocks = true |
Entire inactive #ifdef…#endif removed (recommended for MLIR) |
omit_marker = true (default, when hide is false) |
Keep #ifdef/#endif, insert /// [MLIR_INC_PREVIEW: N lines omitted …] |
require('mlir-inc-previewer').setup({ hide_inactive_blocks = true })| Command | Action |
|---|---|
:MlirIncToggle |
Expand/Collapse preview near cursor (macro-aware) |
:MlirIncToggleFull |
Expand/Collapse preview near cursor (macro-unaware) |
:MlirIncExpandAll |
Expand all previews (macro-aware) |
:MlirIncExpandAllFull |
Expand all previews (macro-unaware) |
:MlirIncClean |
Remove all preview blocks |
:MlirIncCleanAndSave |
Clean all preview blocks, then write the file |
:MlirIncNext |
Jump to the next preview block |
:MlirIncRestart |
Restart: clean all previews in every buffer, refresh hooks |
:MlirIncHelp |
Open plugin help |
The cursor does not need to be exactly on the #include line; the plugin
searches +/-3 lines around the cursor and also recognises when the cursor is
inside an expanded preview block.
-- lualine example
sections = {
lualine_x = { function() return require('mlir-inc-previewer').statusline() end },
}A headless smoke test is included:
nvim --headless -u NONE -c "set noswapfile" -c "set rtp+=." -c "luafile scripts/nvim_smoketest.lua".incpaths are resolved via the LSP only when an attached server actually supportstextDocument/definition. If none does (e.g. clangd is not running), no error is shown and a filesystem fallback is used instead. For best accuracy and speed on MLIR projects, run clangd.:MlirIncExpandAllbuilds the whole result in memory and writes the buffer once, so it stays fast even for very large expansions (10k+ lines). The main remaining cost on huge buffers is your LSP/treesitter re-parsing the inserted text, which is outside this plugin's control.- If the filesystem fallback feels slow on a very large repository, set
deep_search = falseand rely on the LSP for resolution.
Lazy-loaded plugins are not in &rtp until loaded, so :help mlir-inc-previewer
may fail with "no help" if the plugin has not started yet. Use either:
:MlirIncHelp
or load the plugin first, then open help:
:Lazy load mlir-inc-previewer.nvim
:help mlir-inc-previewer
Opening a C/C++ file (or any configured extension) also loads the plugin. Helptags are generated automatically when the plugin starts.
MIT — see LICENSE.