BibTeX and Hayagriva completion source for blink.cmp.
It indexes \addbibresource declarations and project bibliography files to offer
citation-key completion together with APA-styled previews in LaTeX, Typst,
Markdown and R Markdown buffers.
Features · Installation · Configuration · Usage · Alternatives
blink-cmp-bibtex was created to bring BibTeX citation completion to blink.cmp users. While excellent alternatives exist, they have different trade-offs:
-
VimTeX is the comprehensive LaTeX plugin with built-in completion, syntax highlighting, compilation, and more. It can integrate with blink.cmp through blink.compat using its
omnisource. However, VimTeX is primarily a full-featured LaTeX environment rather than a focused completion source. -
cmp-bibtex is the established citation source for
nvim-cmp. It's GPL-licensed and tightly coupled to thecmpAPI, making it unsuitable for direct use with blink.cmp.
blink-cmp-bibtex fills the gap by providing a native, MIT-licensed completion source designed specifically for blink.cmp. It focuses solely on citation completion with minimal overhead, making the transition from cmp seamless for users with citation-heavy workflows in LaTeX, Typst, Markdown, and R Markdown.
- Native blink.cmp source implemented in pure Lua (no
blink.compat). - Discovers
.bibfiles (BibTeX) and.yml/.yamlfiles (Hayagriva) from the current buffer, configured search paths or an explicitfileslist. - For Typst files, follows
#importstatements to find bibliography declarations in imported files. - Parses entries lazily, normalizes common LaTeX accents (e.g.
{"a},\aa) and caches the results with modification-time tracking. - Supports common citation commands (
\cite,\parencite,\textcite,\smartcite,\footcite,\nocite, Pandoc[@key], Typst@keyand#cite(<key>), …) including optional pre/post notes. - Generates APA-inspired previews showing author, year, title and container data with selectable templates (APA default, IEEE optional).
- Shows
[L]/[G]source indicators to distinguish local (project) from global (shared) bibliography files. - Ships with sane defaults yet allows overriding behavior via
require("blink-cmp-bibtex").setup()or provider-levelopts.
Example with lazy.nvim:
{
"saghen/blink.cmp",
dependencies = {
"krissen/blink-cmp-bibtex",
},
opts = {
sources = {
default = function(list)
table.insert(list, "bibtex")
return list
end,
providers = {
bibtex = {
module = "blink-cmp-bibtex",
name = "BibTeX",
min_keyword_length = 2,
score_offset = 10,
async = true,
opts = {
-- provider-level overrides (optional)
},
},
},
},
},
}Call require("blink-cmp-bibtex").setup() early in your config to change defaults.
Only values you set will override the built-ins.
require("blink-cmp-bibtex").setup({
filetypes = { "tex", "plaintex", "markdown", "rmd", "typst" },
files = { "references.bib" }, -- Local project files
global_files = { vim.fn.expand("~/research/master.bib") }, -- Global shared files
search_paths = { "bib/*.bib" },
root_markers = { ".git", "texmf.cnf" },
citation_commands = { "cite", "parencite", "textcite" },
preview_style = "ieee", -- or "apa" (default)
source_indicator = true, -- Show source indicators (default: true)
})When you have both local (project) and global (shared) bibliography files, completion items display nuanced indicators showing where each entry comes from and whether local and global versions differ:
| Indicator | Meaning |
|---|---|
[L] |
Entry exists only in local bibliography |
[G] |
Entry exists only in global bibliography |
[L=G] |
Entry exists in both, content is identical |
[L≠G] |
Entry exists in both, content differs |
Indicators only appear when your configuration includes both local and global sources. If all entries come from the same source type (e.g., only local files), no indicators are shown.
When an entry exists in both local and global files, the completion menu shows the local version (deduplication prefers local).
To disable indicators, set source_indicator = false in your configuration.
When working with both global (shared) and local (project) bibliography files, you can automatically copy entries from global files to a local project file. This is useful when you want to maintain a self-contained project bibliography while drawing from a master reference library.
require("blink-cmp-bibtex").setup({
global_files = { vim.fn.expand("~/research/master.bib") },
search_paths = { "references.bib" },
local_bib = {
enabled = true,
target = "plus.bib", -- Local file to copy entries to
auto_add = true, -- Copy on completion accept
create_if_missing = true, -- Create target if it doesn't exist
notify_on_add = true, -- Show notification when entry is added
duplicate_check = true, -- Skip if entry already exists (default: true)
},
})How it works:
- When you accept a completion for a
[G](global-only) entry, the BibTeX entry is automatically copied to yourlocal_bib.targetfile. - The entry appears in future completions as
[L=G](exists in both, identical). - You can also manually copy entries using the
:BibTeXCopyToLocal [key]command.
Configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Enable local bibliography management |
target |
string | nil |
Path to local bib file (relative to project root) |
targets |
table | {} |
Per-directory targets: { ["/path/to/project"] = "refs.bib" } |
patterns |
table | { "local.bib", "references.bib" } |
Fallback patterns to search |
auto_add |
boolean | false |
Automatically copy global entries on accept |
create_if_missing |
boolean | false |
Create target file if it doesn't exist |
notify_on_add |
boolean | true |
Show notification when entry is added |
notify_on_duplicate |
boolean | false |
Show notification for duplicate entries |
duplicate_check |
boolean | true |
Check for existing entries before adding |
preview_style picks the formatter for the completion detail and documentation
pane. The built-in options are:
apa(default) – Author-year summaries with multiline APA documentation.ieee– IEEE-inspired strings using quoted titles plus volume/issue metadata.
Custom styles can be added by extending require("blink-cmp-bibtex").setup() with a
preview_style that matches one of the registered templates.
-
\addbibresource{},\addglobalbib,\addsectionbiband legacy\bibliography{}statements are scanned inside TeX buffers. -
Missing
.bibextensions are appended automatically so classic\bibliography{references}declarations resolve toreferences.bibon disk. -
Buffer-local paths resolve relative to the current file's directory (with the project root as a fallback) so chapter subdirectories can reference sibling bibliographies.
-
Markdown YAML metadata lines such as
bibliography: references.bibare respected. -
Typst
#bibliography()declarations are detected, including those in imported files via#importstatements. -
Both BibTeX (
.bib) and Hayagriva (.yml,.yaml) bibliography files are supported and automatically detected based on file extension. -
opts.search_pathsaccepts either file paths or glob patterns relative to the detected project root (based onopts.root_markers). These are treated as local sources. -
opts.filesis a list of absolute orvim.fn.expand-friendly paths that are always included. These are treated as local sources (shown with[L]indicator when source indicators are enabled). -
opts.global_filesis a list of paths to shared/master bibliography files. These are treated as global sources (shown with[G]indicator).Note: Source indicators (
[L],[G],[L=G],[L≠G]) only appear when you have both local and global sources configured. If you only usefilesandsearch_pathswithoutglobal_files, no indicators are shown since all entries are implicitly local.
Any table supplied as providers.bibtex.opts in the blink.cmp configuration is
merged into the global setup options. This enables per-source overrides for
files, filetypes, preview style, etc.
blink-cmp-bibtex triggers autocompletion as you type citation keys in your documents:
Start typing a citation command followed by an opening brace, then begin typing
the citation key. For example, when you have a BibTeX entry with the key
Niemi2025:
\cite{NieAs you type Nie, blink.cmp will show matching citation keys. The completion
menu displays each key with a concise APA-style summary, and selecting an entry
shows expanded details in the documentation pane.
This works with all supported citation commands: \parencite{, \textcite{,
\footcite{, \smartcite{, \autocite{, \nocite{, \citep{, \citet{, and
more. Optional arguments are also supported (e.g., \cite[see][42]{Nie).
Use Pandoc-style citations with the @ symbol. For the same Niemi2025 entry:
@NieOr within brackets for inline citations:
[@NieMultiple references are supported using semicolons:
[@ref1; @NieAs you type, blink.cmp shows matching keys with the same preview information as in LaTeX mode.
Typst supports both simple @key citations and the more explicit #cite(<key>) syntax:
@NieOr using the cite function:
#cite(<NieTypst supports two bibliography file formats:
- BibTeX (
.bibfiles) - Traditional format used in LaTeX - Hayagriva (
.ymlor.yamlfiles) - Typst's native YAML-based bibliography format
Both formats are automatically detected and parsed. For example:
#bibliography("references.bib") // BibTeX format
#bibliography("references.yml") // Hayagriva formatThe plugin automatically follows Typst #import statements to find bibliography declarations in imported files. For example:
// main.typ
#import "refs.typ": refs
@Nie // Completion works here!
// refs.typ (in the same directory)
#let refs = bibliography("references.bib")The plugin will detect the bibliography() call in refs.typ and index the entries from references.bib, even though it's not directly declared in the main file.
blink.cmp renders two panes for each matched item:
- The completion row shows the citation key with an APA-style summary. Source
indicators (
[L],[G], etc.) appear on the right side of the menu. - The documentation pane (typically shown below or beside the menu) expands the same entry with publisher/journal, place, DOI/URL, etc.
Each completion item exposes:
label: the citation key.detail: APA-like string (Author (Year) – Title).labelDetails.description: source indicator ([L],[G],[L=G],[L≠G]).documentation: multi-line APA preview covering author/editor, year, title, container, publisher and DOI/URL when available.
- API Reference – Detailed API documentation for all modules
- Development Guide – Architecture, coding style, and contribution guidelines
- Specification – High-level feature specification and design goals
If blink-cmp-bibtex doesn't fit your needs, consider these alternatives:
VimTeX is a comprehensive LaTeX plugin offering completion, syntax highlighting, compilation, PDF viewing, and much more. It provides BibTeX completion through multiple methods:
- Native completion: VimTeX has built-in
omnicompletion for citations - blink.cmp integration: Use VimTeX with blink.cmp via blink.compat and its
omnisource (setup guide) - Full LaTeX environment: If you need more than just citations (e.g., compilation, navigation, text objects), VimTeX is the go-to choice
cmp-bibtex is the established BibTeX source for nvim-cmp. If you're using nvim-cmp, this is the recommended option. Note that it's GPL-licensed and not directly compatible with blink.cmp.
The blink.cmp ecosystem has various community sources for different completion needs. Check the documentation for the latest list.
If you're upgrading from the old blink-bibtex name, you'll need to update your configuration in three places:
Before:
{
"saghen/blink.cmp",
dependencies = {
"krissen/blink-bibtex",
},
-- ...
}After:
{
"saghen/blink.cmp",
dependencies = {
"krissen/blink-cmp-bibtex",
},
-- ...
}Before:
providers = {
bibtex = {
module = "blink-bibtex",
-- ...
},
}After:
providers = {
bibtex = {
module = "blink-cmp-bibtex",
-- ...
},
}Before:
require("blink-bibtex").setup({
-- config
})After:
require("blink-cmp-bibtex").setup({
-- config
})After updating your config, remove the old plugin directory and reinstall:
:Lazy clean
:Lazy syncThen restart Neovim.
Issues and pull requests are welcome. Please read
CONTRIBUTING.md for development setup, coding guidelines and
the review process. A high-level specification lives in docs/spec.md
so new features stay consistent with the overall goals.
For detailed technical information, see the Development Guide. For API details, consult the API Reference.
MIT © 2025 Kristian Niemi