nvim-deck : A plugin for displaying, filtering, and selecting items from customizable lists.
Open project files
CleanShot.2024-12-08.at.11.24.57.mp4
Grep and Replace
CleanShot.2024-12-08.at.11.45.57.mp4
Git integration
CleanShot.2024-12-08.at.12.01.21.mp4
nvim-deck revolves around four core concepts:
- Source:
- A source provides a list of items to display.
- Item:
- An item represents a single entry from the source, containing data and display text.
- Action:
- Actions define what happens when the user interacts with an item.
- Context:
- Context represents the current state, The user can control deck UI via invoke context methods.
- Built-in Git integration.
:Deck git
to open the git launcher.
- Built-in ripgrep integration.
:Deck grep
to start a grep search.
- Built-in file listing.
:Deck files
to show files under the root directory (ripgrep
,PureLua
).
- Highly customizable: sources, actions, previewers, decorators, views, and matchers.
- Use normal-window by default
- IMO, floating-window is fancy but normal window is more handy for edit & preview.
- UX focused
- Use
vim.wait
carefully, it makes a crisp and smooth experience.
- Use
- Configuration over Object control
nvim-deck
does not require huge setup functions- Instead of this, nvim-deck allows you to customize by controlling |deck.Context| object.
Here’s an example of how to set up nvim-deck
:
local deck = require('deck')
-- Apply pre-defined easy settings.
-- For manual configuration, refer to the code in `deck/easy.lua`.
require('deck.easy').setup()
-- Set up buffer-specific key mappings for nvim-deck.
vim.api.nvim_create_autocmd('User', {
pattern = 'DeckStart',
callback = function(e)
local ctx = e.data.ctx --[[@as deck.Context]]
ctx.keymap('n', '<Tab>', deck.action_mapping('choose_action'))
ctx.keymap('n', '<C-l>', deck.action_mapping('refresh'))
ctx.keymap('n', 'i', deck.action_mapping('prompt'))
ctx.keymap('n', 'a', deck.action_mapping('prompt'))
ctx.keymap('n', '@', deck.action_mapping('toggle_select'))
ctx.keymap('n', '*', deck.action_mapping('toggle_select_all'))
ctx.keymap('n', 'p', deck.action_mapping('toggle_preview_mode'))
ctx.keymap('n', 'd', deck.action_mapping('delete'))
ctx.keymap('n', '<CR>', deck.action_mapping('default'))
ctx.keymap('n', 'o', deck.action_mapping('open'))
ctx.keymap('n', 'O', deck.action_mapping('open_keep'))
ctx.keymap('n', 's', deck.action_mapping('open_split'))
ctx.keymap('n', 'v', deck.action_mapping('open_vsplit'))
ctx.keymap('n', 'N', deck.action_mapping('create'))
ctx.keymap('n', 'w', deck.action_mapping('write'))
ctx.keymap('n', '<C-u>', deck.action_mapping('scroll_preview_up'))
ctx.keymap('n', '<C-d>', deck.action_mapping('scroll_preview_down'))
-- If you want to start the filter by default, call ctx.prompt() here
ctx.prompt()
end
})
--key-mapping for explorer source (requires `require('deck.easy').setup()`).
vim.api.nvim_create_autocmd('User', {
pattern = 'DeckStart:explorer',
callback = function(e)
local ctx = e.data.ctx --[[@as deck.Context]]
ctx.keymap('n', 'h', deck.action_mapping('explorer.collapse'))
ctx.keymap('n', 'l', deck.action_mapping('explorer.expand'))
ctx.keymap('n', '.', deck.action_mapping('explorer.toggle_dotfiles'))
ctx.keymap('n', 'c', deck.action_mapping('explorer.clipboard.save_copy'))
ctx.keymap('n', 'm', deck.action_mapping('explorer.clipboard.save_move'))
ctx.keymap('n', 'p', deck.action_mapping('explorer.clipboard.paste'))
ctx.keymap('n', 'x', deck.action_mapping('explorer.clipboard.paste'))
ctx.keymap('n', '<Leader>ff', deck.action_mapping('explorer.dirs'))
ctx.keymap('n', 'P', deck.action_mapping('toggle_preview_mode'))
ctx.keymap('n', '~', function()
ctx.do_action('explorer.get_api').set_cwd(vim.fs.normalize('~'))
end)
ctx.keymap('n', '\\', function()
ctx.do_action('explorer.get_api').set_cwd(vim.fs.normalize('/'))
end)
end
})
-- Example key bindings for launching nvim-deck sources. (These mapping required `deck.easy` calls.)
vim.keymap.set('n', '<Leader>ff', '<Cmd>Deck files<CR>', { desc = 'Show recent files, buffers, and more' })
vim.keymap.set('n', '<Leader>gr', '<Cmd>Deck grep<CR>', { desc = 'Start grep search' })
vim.keymap.set('n', '<Leader>gi', '<Cmd>Deck git<CR>', { desc = 'Open git launcher' })
vim.keymap.set('n', '<Leader>he', '<Cmd>Deck helpgrep<CR>', { desc = 'Live grep all help tags' })
-- Show the latest deck context.
vim.keymap.set('n', '<Leader>;', function()
local context = deck.get_history()[vim.v.count == 0 and 1 or vim.v.count]
if context then
context.show()
end
end)
-- Do default action on next item.
vim.keymap.set('n', '<Leader>n', function()
local ctx = require('deck').get_history()[1]
if ctx then
ctx.set_cursor(ctx.get_cursor() + 1)
ctx.do_action('default')
end
end)
If you create nvim-deck source or action, we recommend to follow guidelines.
nvim-deck supports the concept of duck-typing.
So if your custom source has source-specific actions, you should register alias actions for them.
- default
- create
- delete
- rename
- write
- refresh
- open
- open_split
- open_vsplit
The source definition looks like this:
source = {
...
actions = {
deck.alias_action('default', 'source.default'),
{
name = 'source.default',
execute = ...
}
}
...
}
The source.default
action will be shown in action picker. The user can have a
unified experience across many different sources just by writing
ctx.keymap('n', '<CR>', deck.action_mapping('default'))
.
!!! We strongly recommend using lua-language-server
!!!
You can customize your nvim-deck appearance.
- guicursor
require('deck').setup({
guicursor = 'a:ver25',
})
- winhighlight
vim.api.nvim_create_autocmd('User', {
group = misc.group,
pattern = 'DeckShow',
callback = function()
vim.wo.winhighlight = 'CursorLine:Visual'
end
})
The source is typed as |deck.Source|. The source can be executed by
deck.start()
.
The source can specify source-level actions, decorators, and previewers.
require('deck').start({
name = 'my_source',
execute = function(ctx)
ctx.item({
display_text = 'Hello, World!',
})
ctx.done()
end,
actions = {
...
},
decorators = {
...
},
previewers = {
...
},
})
The action is typed as |deck.Action| and can be registered below three different levels.
- Config Action : Provided by a start configuration.
This level can be registered by start_config.actions
field.
require('deck').start(some_of_the_source, {
actions = {
{
name = 'my_open',
execute = function(ctx)
-- some of the process.
end
}
}
})
- Source Action : Provided by a source.
This level of actions can be registered by source.actions
field.
require('deck').start({
name = 'my_source',
...
actions = {
{
name = 'my_open',
execute = function(ctx)
-- some of the process.
end
}
}
})
- Global Action : Registered globally.
This level of actions can be registered by deck.register_action()
.
require('deck').register_action({
name = 'my_open',
resolve = function(ctx)
-- Action is available only if there is exactly one action item with a filename.
return #ctx.get_action_items() == 1 and ctx.get_action_items()[1].data.filename
end,
execute = function(ctx)
-- Open the file.
vim.cmd.edit(ctx.get_action_items()[1].data.filename)
end
})
Note: The same name actions are choosen in the order of 1 -> 2 -> 3.
The start-preset is typed as |deck.StartPreset| and can be registered globally.
A start-preset in nvim-deck
allows you to define shortcut command. In the
below example, you can use :Deck recent
command.
-- After registration, you can start the preset using the `:Deck recent` command.
require('deck').register_start_preset('recent', {
require('deck').start({
require('deck.builtin.source.recent_files')(),
require('deck.builtin.source.buffers')(),
})
})
nvim-deck
has decorator
concept. It's designed to decorate the deck-buffer
via nvim_buf_set_extmark
. The below example shows how to create your own
decorator.
--- This is example decorator.
--- To display the basename of the file and dirname as a comment.
--- This decorator highlight basename and make dirname less noticeable.
require('deck').register_decorator({
name = 'basename_dirname',
resolve = function(_, item)
-- This decorator is available only if the item has a filename.
return item.data.filename
end,
decorate = function(ctx, item, row)
local dirname = vim.fn.fnamemodify(item.data.filename, ':~:h')
local display_text = item.display_text
local s, e = display_text:find(dirname, 1, true)
if s then
return {
-- Hide the directory part (using conceal)
{
row = row,
col = s - 1,
end_row = row,
end_col = e + 1,
conceal = '',
ephemeral = true,
},
-- Display the directory name as a comment at the end of the line
{
row = row,
col = 0,
virt_text = { { dirname, 'Comment' } },
virt_text_pos = 'eol'
}
}
end
return {}
end
})
nvim-deck
has previewer
concept. It's designed to show the item preview.
require('deck').register_previewer({
name = 'bat',
resolve = function(_, item)
return item.data.filename and vim.fn.filereadable(item.data.filename) == 1
end,
preview = function(_, item, env)
vim.api.nvim_win_call(env.win, function()
vim.fn.termopen(('bat --color=always %s'):format(item.data.filename))
end)
end
})
Show buffers.
Name | Type | Default | Description |
---|---|---|---|
ignore_paths | string[]? | [vim.fn.expand('%:p')] | Ignore paths. The default value is intented to hide current buffer. |
nofile | boolean? | false | Ignore nofile buffers. |
deck.start(require('deck.builtin.source.buffers')({
ignore_paths = { vim.fn.expand('%:p'):gsub('/$', '') },
nofile = false,
}))
Show available actions from |deck.Context|
Name | Type | Default | Description |
---|---|---|---|
context | |deck.Context| |
deck.start(require('deck.builtin.source.deck.actions')({
context = context
}))
Show deck.start history.
No options
deck.start(require('deck.builtin.source.deck.history')())
Show dirs under specified root directory.
Name | Type | Default | Description |
---|---|---|---|
ignore_globs | string[]? | [] | Ignore glob patterns. |
root_dir | string | Target root directory. |
deck.start(require('deck.builtin.source.dirs')({
root_dir = vim.fn.getcwd(),
ignore_globs = { '**/node_modules/', '**/.git/' },
}))
Explorer source.
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target directory. | |
mode | 'drawer' | 'filer' | Mode of explorer. | |
narrow | { enabled?: boolean, ignore_globs?: string[] } | Narrow finder options. | |
reveal | string | Reveal target path. |
To use explorer, you must set `start_preset` or use `require('deck.easy').setup()`.
If you call `require('deck.easy').setup()`, then you can use explorer by `:Deck explorer` command.
Show files under specified root directory.
Name | Type | Default | Description |
---|---|---|---|
ignore_globs | string[]? | [] | Ignore glob patterns. |
root_dir | string | Target root directory. |
deck.start(require('deck.builtin.source.files')({
root_dir = vim.fn.getcwd(),
ignore_globs = { '**/node_modules/', '**/.git/' },
}))
Show git launcher.
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target git root. |
deck.start(require('deck.builtin.source.git.changeset')({
cwd = vim.fn.getcwd(),
}))
Show git branches
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target git root. |
deck.start(require('deck.builtin.source.git.branch')({
cwd = vim.fn.getcwd()
}))
Show git changeset for specified revision.
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target git root. | |
from_rev | string | From revision. | |
to_rev | string? | To revision. If you omit this option, it will be HEAD. |
deck.start(require('deck.builtin.source.git.changeset')({
cwd = vim.fn.getcwd(),
from_rev = 'HEAD~3',
to_rev = 'HEAD'
}))
Show git log.
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target git root. | |
max_count | integer? | Max count for log |
deck.start(require('deck.builtin.source.git.log')({
cwd = vim.fn.getcwd(),
}))
Show git reflog.
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target git root. | |
max_count | integer? | Max count for reflog |
deck.start(require('deck.builtin.source.git.reflog')({
cwd = vim.fn.getcwd(),
}))
Show git remotes.
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target git root. |
deck.start(require('deck.builtin.source.git.remote')({
cwd = vim.fn.getcwd(),
}))
Show git status.
Name | Type | Default | Description |
---|---|---|---|
cwd | string | Target git root. |
deck.start(require('deck.builtin.source.git.status')({
cwd = vim.fn.getcwd(),
}))
Grep files under specified root directory. (required ripgrep
)
Name | Type | Default | Description |
---|---|---|---|
root_dir | string | Target root directory. | |
ignore_globs | string[]? | [] | Ignore glob patterns. |
deck.start(require('deck.builtin.source.grep')({
root_dir = vim.fn.getcwd(),
pattern = vim.fn.input('grep: '),
ignore_globs = { '**/node_modules/', '**/.git/' },
}))
Live grep all helptags. (required ripgrep
)
No options
deck.start(require('deck.builtin.source.helpgrep')())
Listing any provided items.
Name | Type | Default | Description |
---|---|---|---|
items | string[]|deck.ItemSpecifier[] | Items to list. |
deck.start(require('deck.builtin.source.items')({
items = vim.iter(vim.api.nvim_list_bufs()):map(function(buf)
return ('#%s'):format(buf)
end):totable()
}))
Show buffer lines.
No options
deck.start(require('deck.builtin.source.lines')({
bufnrs = { vim.api.nvim_get_current_buf() },
}))
List recent directories.
Name | Type | Default | Description |
---|---|---|---|
ignore_paths | string[]? | [] | Ignore paths. |
require('deck.builtin.source.recent_dirs'):setup({
path = '~/.deck.recent_dirs'
})
vim.api.nvim_create_autocmd('DirChanged', {
callback = function(e)
require('deck.builtin.source.recent_dirs'):add(e.cwd)
end,
})
deck.start(require('deck.builtin.source.recent_dirs')({
ignore_paths = { '**/node_modules/', '**/.git/' },
}))
List recent files.
Name | Type | Default | Description |
---|---|---|---|
ignore_paths | string[]? | [] | Ignore paths. |
require('deck.builtin.source.recent_files'):setup({
path = '~/.deck.recent_files'
})
vim.api.nvim_create_autocmd('BufEnter', {
callback = function()
local bufname = vim.api.nvim_buf_get_name(0)
if vim.fn.filereadable(bufname) == 1 then
require('deck.builtin.source.recent_files'):add(vim.fs.normalize(bufname))
end
end,
})
deck.start(require('deck.builtin.source.recent_files')({
ignore_paths = { '**/node_modules/', '**/.git/' },
}))
-
choose_action
-
Open action source.
The actions listed are filtered by whether they are valid in the current context.
-
-
delete_buffer
-
Delete
item.data.bufnr
from buffers list.If multiple items are selected, they will be deleted in order.
-
-
delete_file
-
Delete
item.data.filename
from filesystem.If multiple items are selected, they will be deleted in order.
-
-
open
-
Open
item.data.filename
oritem.data.bufnr
.Open at the recently normal window.
-
-
open_keep
-
Open
item.data.filename
oritem.data.bufnr
.But keep the deck window and cursor.
-
-
open_split
-
Open
item.data.filename
oritem.data.bufnr
.Open at the recently normal window with split.
-
-
open_split_keep
-
Open
item.data.filename
oritem.data.bufnr
.Open at the recently normal window with split. But keep the deck window and cursor.
-
-
open_tabnew
-
Open
item.data.filename
oritem.data.bufnr
.Open at the new tabpage.
-
-
open_vsplit
-
Open
item.data.filename
oritem.data.bufnr
.Open at the recently normal window with vsplit.
-
-
open_vsplit_keep
-
Open
item.data.filename
oritem.data.bufnr
.Open at the recently normal window with vsplit. But keep the deck window and cursor.
-
-
print
- Print selected items.
-
prompt
- Open filtering prompt
-
refresh
- Re-execute source. (it can be used to refresh the items)
-
scroll_preview_down
- Scroll preview window down.
-
scroll_preview_up
- Scroll preview window up.
-
substitute
-
Open substitute buffer with selected items (
item.data.filename
anditem.data.lnum
are required).You can modify and save the buffer to reflect the changes to the original files.
-
-
toggle_preview_mode
- Toggle preview mode
-
toggle_select
- Toggle selected state of the cursor item.
-
toggle_select_all
- Toggle selected state of all items.
-
write_buffer
- Write modified
item.data.bufnr
oritem.data.filename
that has buffer.
- Write modified
-
yank
- Yank item.display_text field to default register.
-
DeckHide
- Triggered after deck window hidden.
-
DeckShow
- Triggered after deck window shown.
-
DeckStart
- Triggered when deck starts.
-
DeckStart:{source.name}
- Triggered when deck starts for source.
Create action mapping function for ctx.keymap.
Name | Type | Description |
---|---|---|
action_names | string|string[] | action name or action names to use for mappings. |
Create alias action.
Name | Type | Description |
---|---|---|
alias_name | string | new action name. |
alias_action_name | string | existing action name. |
Get all registered actions.
No arguments
Get all registered decorators.
No arguments
Get all history (first history is latest).
No arguments
Get all registered previewers.
No arguments
Get all registered start presets.
No arguments
Register action.
Name | Type | Description |
---|---|---|
action | |deck.Action| | action to register. |
Register decorator.
Name | Type | Description |
---|---|---|
decorator | |deck.Decorator| | decorator to register. |
Register previewer.
Name | Type | Description |
---|---|---|
previewer | |deck.Previewer| | previewer to register. |
Register start_preset.
Name | Type | Description |
---|---|---|
name | string | preset name. |
start_fn | fun() | Start function. |
Register start_preset.
Name | Type | Description |
---|---|---|
start_preset | deck.StartPreset | |deck.StartPreset| |
Remove specific action.
Name | Type | Description |
---|---|---|
predicate | fun(action: |deck.Action|): boolean | Predicate function. If return true, remove action. |
Remove specific decorator.
Name | Type | Description |
---|---|---|
predicate | fun(decorator: |deck.Decorator|): boolean | Predicate function. If return true, remove decorator. |
Remove previewer.
Name | Type | Description |
---|---|---|
predicate | fun(previewer: |deck.Previewer|): boolean | Predicate function. If return true, remove previewer. |
Remove specific start_preset.
Name | Type | Description |
---|---|---|
predicate | fun(start_preset: |deck.StartPreset|): boolean | Predicate function. If return true, remove start_preset. |
Setup deck globally.
Name | Type | Description |
---|---|---|
config | deck.ConfigSpecifier | Setup deck configuration. |
Start deck with given sources.
Name | Type | Description |
---|---|---|
source | deck.Source|deck.Source[] | source or sources to start. |
start_config | deck.StartConfigSpecifier | start configuration. |
*deck.Action*
---@class deck.Action
---@field public name string
---@field public desc? string
---@field public hidden? boolean
---@field public resolve? deck.ActionResolveFunction
---@field public execute deck.ActionExecuteFunction
*deck.Config*
---@class deck.Config: deck.ConfigSpecifier
---@field public guicursor? string
---@field public max_history_size integer
---@field public default_start_config? deck.StartConfigSpecifier
*deck.ConfigSpecifier*
---@class deck.ConfigSpecifier
---@field public guicursor? string
---@field public max_history_size? integer
---@field public default_start_config? deck.StartConfigSpecifier
*deck.Context*
---@class deck.Context
---@field id integer
---@field ns integer
---@field buf integer
---@field name string
---@field get_config fun(): deck.StartConfig
---@field execute fun()
---@field is_visible fun(): boolean
---@field show fun()
---@field hide fun()
---@field focus fun()
---@field prompt fun()
---@field scroll_preview fun(delta: integer)
---@field get_status fun(): deck.Context.Status
---@field is_filtering fun(): boolean
---@field is_syncing fun(): boolean
---@field get_cursor fun(): integer
---@field set_cursor fun(cursor: integer)
---@field get_query fun(): string
---@field set_query fun(query: string)
---@field get_matcher_query fun(): string
---@field get_dynamic_query fun(): string
---@field set_selected fun(item: deck.Item, selected: boolean)
---@field get_selected fun(item: deck.Item): boolean
---@field set_select_all fun(select_all: boolean)
---@field get_select_all fun(): boolean
---@field set_preview_mode fun(preview_mode: boolean)
---@field get_preview_mode fun(): boolean
---@field get_items fun(): deck.Item[]
---@field get_cursor_item fun(): deck.Item?
---@field get_action_items fun(): deck.Item[]
---@field get_filtered_items fun(): deck.Item[]
---@field get_rendered_items fun(): deck.Item[]
---@field get_selected_items fun(): deck.Item[]
---@field get_actions fun(): deck.Action[]
---@field get_decorators fun(): deck.Decorator[]
---@field get_previewer fun(): deck.Previewer?
---@field sync fun()
---@field keymap fun(mode: string|string[], lhs: string, rhs: fun(ctx: deck.Context))
---@field do_action fun(name: string): any
---@field dispose fun()
---@field disposed fun(): boolean
---@field on_show fun(callback: fun())
---@field on_hide fun(callback: fun())
---@field on_dispose fun(callback: fun()): fun()
*deck.Decoration*
---@class deck.Decoration
---@field public col? integer
---@field public end_col? integer
---@field public hl_group? string
---@field public hl_eol? boolean
---@field public virt_text? deck.VirtualText[]
---@field public virt_text_pos? 'eol' | 'overlay' | 'right_align' | 'inline'
---@field public virt_text_win_col? integer
---@field public virt_text_hide? boolean
---@field public virt_text_repeat_linebreak? boolean
---@field public virt_lines? deck.VirtualText[][]
---@field public virt_lines_above? boolean
---@field public ephemeral? boolean
---@field public priority? integer
---@field public sign_text? string
---@field public sign_hl_group? string
---@field public number_hl_group? string
---@field public line_hl_group? string
---@field public conceal? string
*deck.Decorator*
---@class deck.Decorator
---@field public name string
---@field public dynamic? boolean
---@field public resolve? deck.DecoratorResolveFunction
---@field public decorate deck.DecoratorDecorateFunction
*deck.ExecuteContext*
---@class deck.ExecuteContext
---@field public item fun(item: deck.ItemSpecifier)
---@field public done fun( )
---@field public queue fun(task: fun())
---@field public get_query fun(): string
---@field public get_config fun(): deck.StartConfig
---@field public aborted fun(): boolean
---@field public on_abort fun(callback: fun())
*deck.Item*
---@class deck.Item: deck.ItemSpecifier
---@field public display_text string
---@field public data table
*deck.ItemSpecifier*
---@class deck.ItemSpecifier
---@field public display_text string|(deck.VirtualText[])
---@field public highlights? deck.Highlight[]
---@field public filter_text? string
---@field public dedup_id? string
---@field public data? table
*deck.PerformanceConfig*
---@class deck.PerformanceConfig
---@field public sync_timeout_ms integer
---@field public interrupt_ms integer
---@field public gather_budget_ms integer
---@field public gather_batch_size integer
---@field public filter_bugdet_ms integer
---@field public filter_batch_size integer
---@field public render_bugdet_ms integer
---@field public render_batch_size integer
---@field public render_delay_ms integer
*deck.Previewer*
---@class deck.Previewer
---@field public name string
---@field public priority? integer
---@field public resolve? deck.PreviewerResolveFunction
---@field public preview deck.PreviewerPreviewFunction
*deck.Source*
---@class deck.Source
---@field public name string
---@field public dynamic? boolean
---@field public events? { Start?: fun(ctx: deck.Context), BufWinEnter?: fun(ctx: deck.Context, env: { first: boolean }) }
---@field public execute deck.SourceExecuteFunction
---@field public actions? deck.Action[]
---@field public decorators? deck.Decorator[]
---@field public previewers? deck.Previewer[]
---@field public parse_query? deck.ParseQuery
*deck.StartConfig*
---@class deck.StartConfig: deck.StartConfigSpecifier
---@field public name string
---@field public view fun(): deck.View
---@field public matcher deck.Matcher
---@field public history boolean
---@field public performance deck.PerformanceConfig
---@field public disable_actions? string[]
---@field public disable_decorators? string[]
---@field public disable_previewers? string[]
---@field public dedup boolean
---@field public query string
*deck.StartConfigSpecifier*
---@class deck.StartConfigSpecifier
---@field public name? string
---@field public view? fun(): deck.View
---@field public matcher? deck.Matcher
---@field public history? boolean
---@field public actions? deck.Action[]
---@field public decorators? deck.Decorator[]
---@field public previewers? deck.Previewer[]
---@field public performance? deck.PerformanceConfig|{}
---@field public disable_actions? string[]
---@field public disable_decorators? string[]
---@field public disable_previewers? string[]
---@field public dedup? boolean
---@field public query? string
---@field public auto_abort? boolean
*deck.StartPreset*
---@class deck.StartPreset
---@field public name string
---@field public args? table<string|integer, { complete?: (fun(prefix: string):string[]), required?: boolean }>
---@field public start fun(args: table<string|integer, string>)
*deck.View*
---@class deck.View
---@field public get_win fun(): integer?
---@field public is_visible fun(ctx: deck.Context): boolean
---@field public show fun(ctx: deck.Context)
---@field public hide fun(ctx: deck.Context)
---@field public redraw fun(ctx: deck.Context)
---@field public prompt fun(ctx: deck.Context)
---@field public scroll_preview fun(ctx: deck.Context, delta: integer)