refactor(config): replace array preset syntax with preset_name = true (#3)
* refactor(config): replace array preset syntax with preset_name = true Problem: setup() mixed array entries (preset names) and hash entries (custom providers keyed by filetype), requiring verbose vim.tbl_deep_extend boilerplate to override presets. Solution: unify under a single key=value model. Keys are preset names or filetypes; true registers the preset as-is, a table deep-merges with the matching preset (or registers a custom provider if no preset matches), and false is a no-op. Array entries are dropped. Also adds -f gfm to presets.github args so pandoc parses input as GFM. * ci: format * fix(presets): parenthesize gsub output to suppress redundant-return-value
This commit is contained in:
parent
673573044f
commit
2d212aa220
6 changed files with 73 additions and 56 deletions
13
README.md
13
README.md
|
|
@ -55,23 +55,20 @@ require('preview').setup({
|
|||
**Q: How do I override a preset?**
|
||||
|
||||
```lua
|
||||
local presets = require('preview.presets')
|
||||
require('preview').setup({
|
||||
typst = vim.tbl_deep_extend('force', presets.typst, {
|
||||
env = { TYPST_FONT_PATHS = '/usr/share/fonts' },
|
||||
}),
|
||||
typst = { env = { TYPST_FONT_PATHS = '/usr/share/fonts' } },
|
||||
})
|
||||
```
|
||||
|
||||
**Q: How do I automatically open the output file?**
|
||||
|
||||
Set `open = true` on your provider (all built-in presets have this enabled) to
|
||||
open the output with `vim.ui.open()` after the first successful compilation.
|
||||
For a specific application, pass a command table:
|
||||
open the output with `vim.ui.open()` after the first successful compilation. For
|
||||
a specific application, pass a command table:
|
||||
|
||||
```lua
|
||||
typst = vim.tbl_deep_extend('force', presets.typst, {
|
||||
open = { 'sioyek', '--new-instance' },
|
||||
require('preview').setup({
|
||||
typst = { open = { 'sioyek', '--new-instance' } },
|
||||
})
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -42,9 +42,18 @@ Configure via `require('preview').setup()`.
|
|||
*preview.setup()*
|
||||
setup({opts?})
|
||||
|
||||
`opts` is a mixed table. Array entries are preset names (see
|
||||
|preview.nvim-presets|). Hash entries with table values are custom
|
||||
provider configs keyed by filetype.
|
||||
`opts` is a table where keys are preset names or filetypes. For each
|
||||
key `k` with value `v` (excluding `debug`):
|
||||
|
||||
- If `k` is a preset name and `v` is `true`, the preset is registered
|
||||
as-is under its filetype.
|
||||
- If `k` is a preset name and `v` is a table, it is deep-merged with
|
||||
the preset and registered under the preset's filetype.
|
||||
- If `k` is not a preset name and `v` is a table, it is registered
|
||||
directly as a custom provider keyed by filetype `k`.
|
||||
- If `v` is `false`, the entry is skipped (no-op).
|
||||
|
||||
See |preview.nvim-presets| for available preset names.
|
||||
|
||||
Fields:~
|
||||
|
||||
|
|
@ -91,33 +100,28 @@ Context fields:~
|
|||
`root` string Project root (git root or file directory).
|
||||
`ft` string Filetype.
|
||||
|
||||
Example using preset names:~
|
||||
Example enabling presets:~
|
||||
>lua
|
||||
require('preview').setup({ 'typst', 'latex', 'markdown' })
|
||||
require('preview').setup({ typst = true, latex = true, github = true })
|
||||
<
|
||||
|
||||
Example with a custom provider:~
|
||||
Example overriding a preset field:~
|
||||
>lua
|
||||
require('preview').setup({
|
||||
typst = {
|
||||
cmd = { 'typst', 'compile' },
|
||||
typst = { open = { 'sioyek', '--new-instance' } },
|
||||
})
|
||||
<
|
||||
|
||||
Example with a fully custom provider (key is not a preset name):~
|
||||
>lua
|
||||
require('preview').setup({
|
||||
rst = {
|
||||
cmd = { 'rst2html' },
|
||||
args = function(ctx)
|
||||
return { ctx.file }
|
||||
end,
|
||||
output = function(ctx)
|
||||
return ctx.file:gsub('%.typ$', '.pdf')
|
||||
end,
|
||||
error_parser = function(stderr, ctx)
|
||||
local diagnostics = {}
|
||||
for line, col, msg in stderr:gmatch('error:.-(%d+):(%d+):%s*(.-)%\n') do
|
||||
table.insert(diagnostics, {
|
||||
lnum = tonumber(line) - 1,
|
||||
col = tonumber(col) - 1,
|
||||
message = msg,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
})
|
||||
end
|
||||
return diagnostics
|
||||
return ctx.file:gsub('%.rst$', '.html')
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
|
@ -132,20 +136,17 @@ Import them from `preview.presets`:
|
|||
`presets.typst` typst compile → PDF
|
||||
`presets.latex` latexmk -pdf → PDF (with clean support)
|
||||
`presets.markdown` pandoc → HTML (standalone, embedded)
|
||||
`presets.github` pandoc → HTML (GitHub-styled)
|
||||
`presets.github` pandoc → HTML (GitHub-styled, `-f gfm` input)
|
||||
|
||||
Pass preset names as array entries to `setup()`:
|
||||
Enable presets with `preset_name = true`:
|
||||
>lua
|
||||
require('preview').setup({ 'typst', 'latex', 'markdown' })
|
||||
require('preview').setup({ typst = true, latex = true, github = true })
|
||||
<
|
||||
|
||||
Override individual fields using `vim.tbl_deep_extend`:
|
||||
Override individual fields by passing a table instead of `true`:
|
||||
>lua
|
||||
local presets = require('preview.presets')
|
||||
require('preview').setup({
|
||||
typst = vim.tbl_deep_extend('force', presets.typst, {
|
||||
env = { TYPST_FONT_PATHS = '/usr/share/fonts' },
|
||||
}),
|
||||
typst = { env = { TYPST_FONT_PATHS = '/usr/share/fonts' } },
|
||||
})
|
||||
<
|
||||
|
||||
|
|
|
|||
|
|
@ -68,15 +68,17 @@ function M.setup(opts)
|
|||
if k == 'debug' then
|
||||
vim.validate('preview.setup opts.debug', v, { 'boolean', 'string' })
|
||||
debug = v
|
||||
elseif type(k) == 'number' then
|
||||
vim.validate('preview.setup preset name', v, 'string')
|
||||
local preset = presets[v]
|
||||
elseif type(k) ~= 'number' then
|
||||
local preset = presets[k]
|
||||
if preset then
|
||||
providers[preset.ft] = preset
|
||||
if v == true then
|
||||
providers[preset.ft] = preset
|
||||
elseif type(v) == 'table' then
|
||||
providers[preset.ft] = vim.tbl_deep_extend('force', preset, v)
|
||||
end
|
||||
elseif type(v) == 'table' then
|
||||
providers[k] = v
|
||||
end
|
||||
else
|
||||
vim.validate('preview.setup provider config', v, 'table')
|
||||
providers[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ M.typst = {
|
|||
return { ctx.file }
|
||||
end,
|
||||
output = function(ctx)
|
||||
return ctx.file:gsub('%.typ$', '.pdf')
|
||||
return (ctx.file:gsub('%.typ$', '.pdf'))
|
||||
end,
|
||||
open = { 'xdg-open' },
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ M.latex = {
|
|||
return { '-pdf', '-interaction=nonstopmode', ctx.file }
|
||||
end,
|
||||
output = function(ctx)
|
||||
return ctx.file:gsub('%.tex$', '.pdf')
|
||||
return (ctx.file:gsub('%.tex$', '.pdf'))
|
||||
end,
|
||||
clean = function(ctx)
|
||||
return { 'latexmk', '-c', ctx.file }
|
||||
|
|
@ -38,7 +38,7 @@ M.markdown = {
|
|||
return { ctx.file, '-s', '--embed-resources', '-o', output }
|
||||
end,
|
||||
output = function(ctx)
|
||||
return ctx.file:gsub('%.md$', '.html')
|
||||
return (ctx.file:gsub('%.md$', '.html'))
|
||||
end,
|
||||
clean = function(ctx)
|
||||
return { 'rm', '-f', (ctx.file:gsub('%.md$', '.html')) }
|
||||
|
|
@ -53,17 +53,19 @@ M.github = {
|
|||
args = function(ctx)
|
||||
local output = ctx.file:gsub('%.md$', '.html')
|
||||
return {
|
||||
'-f',
|
||||
'gfm',
|
||||
ctx.file,
|
||||
'-s',
|
||||
'--embed-resources',
|
||||
'--css',
|
||||
'https://cdn.jsdelivr.net/gh/pixelbrackets/gfm-stylesheet@master/github.css',
|
||||
'https://cdn.jsdelivr.net/gh/pixelbrackets/gfm-stylesheet@master/dist/gfm.css',
|
||||
'-o',
|
||||
output,
|
||||
}
|
||||
end,
|
||||
output = function(ctx)
|
||||
return ctx.file:gsub('%.md$', '.html')
|
||||
return (ctx.file:gsub('%.md$', '.html'))
|
||||
end,
|
||||
clean = function(ctx)
|
||||
return { 'rm', '-f', (ctx.file:gsub('%.md$', '.html')) }
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ describe('preview', function()
|
|||
assert.are.same({}, config.providers)
|
||||
end)
|
||||
|
||||
it('accepts full provider config via hash entry', function()
|
||||
it('merges override table with matching preset', function()
|
||||
helpers.reset_config({
|
||||
typst = {
|
||||
cmd = { 'typst', 'compile' },
|
||||
|
|
@ -33,8 +33,8 @@ describe('preview', function()
|
|||
assert.is_not_nil(config.providers.typst)
|
||||
end)
|
||||
|
||||
it('resolves array preset names to provider configs', function()
|
||||
helpers.reset_config({ 'typst', 'markdown' })
|
||||
it('resolves preset = true to provider config', function()
|
||||
helpers.reset_config({ typst = true, markdown = true })
|
||||
local config = require('preview').get_config()
|
||||
local presets = require('preview.presets')
|
||||
assert.are.same(presets.typst, config.providers.typst)
|
||||
|
|
@ -42,14 +42,14 @@ describe('preview', function()
|
|||
end)
|
||||
|
||||
it('resolves latex preset under tex filetype', function()
|
||||
helpers.reset_config({ 'latex' })
|
||||
helpers.reset_config({ latex = true })
|
||||
local config = require('preview').get_config()
|
||||
local presets = require('preview.presets')
|
||||
assert.are.same(presets.latex, config.providers.tex)
|
||||
end)
|
||||
|
||||
it('resolves github preset under markdown filetype', function()
|
||||
helpers.reset_config({ 'github' })
|
||||
helpers.reset_config({ github = true })
|
||||
local config = require('preview').get_config()
|
||||
local presets = require('preview.presets')
|
||||
assert.are.same(presets.github, config.providers.markdown)
|
||||
|
|
@ -59,7 +59,7 @@ describe('preview', function()
|
|||
describe('resolve_provider', function()
|
||||
before_each(function()
|
||||
helpers.reset_config({
|
||||
typst = { cmd = { 'typst', 'compile' } },
|
||||
typst = true,
|
||||
})
|
||||
preview = require('preview')
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -139,16 +139,31 @@ describe('presets', function()
|
|||
local args = presets.github.args(md_ctx)
|
||||
assert.is_table(args)
|
||||
assert.are.same({
|
||||
'-f',
|
||||
'gfm',
|
||||
'/tmp/document.md',
|
||||
'-s',
|
||||
'--embed-resources',
|
||||
'--css',
|
||||
'https://cdn.jsdelivr.net/gh/pixelbrackets/gfm-stylesheet@master/github.css',
|
||||
'https://cdn.jsdelivr.net/gh/pixelbrackets/gfm-stylesheet@master/dist/gfm.css',
|
||||
'-o',
|
||||
'/tmp/document.html',
|
||||
}, args)
|
||||
end)
|
||||
|
||||
it('args include -f and gfm flags', function()
|
||||
local args = presets.github.args(md_ctx)
|
||||
local idx = nil
|
||||
for i, v in ipairs(args) do
|
||||
if v == '-f' then
|
||||
idx = i
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_not_nil(idx)
|
||||
assert.are.equal('gfm', args[idx + 1])
|
||||
end)
|
||||
|
||||
it('returns html output path', function()
|
||||
local output = presets.github.output(md_ctx)
|
||||
assert.is_string(output)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue