{"id":13651008,"url":"https://github.com/msprev/fzf-bibtex","last_synced_at":"2025-08-22T05:32:19.591Z","repository":{"id":39869362,"uuid":"156204010","full_name":"msprev/fzf-bibtex","owner":"msprev","description":"a BibTeX source for fzf","archived":false,"fork":false,"pushed_at":"2023-07-31T12:18:43.000Z","size":63,"stargazers_count":118,"open_issues_count":0,"forks_count":15,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-12T15:06:02.197Z","etag":null,"topics":["bibtex","fzf","neovim","vim"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msprev.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-11-05T11:03:53.000Z","updated_at":"2024-04-02T17:41:35.000Z","dependencies_parsed_at":"2024-01-03T05:41:35.515Z","dependency_job_id":"7353bc25-c1f5-4a11-a2c3-3907419453a1","html_url":"https://github.com/msprev/fzf-bibtex","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msprev%2Ffzf-bibtex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msprev%2Ffzf-bibtex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msprev%2Ffzf-bibtex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msprev%2Ffzf-bibtex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msprev","download_url":"https://codeload.github.com/msprev/fzf-bibtex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230438174,"owners_count":18225870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bibtex","fzf","neovim","vim"],"created_at":"2024-08-02T02:00:43.775Z","updated_at":"2024-12-20T09:07:25.207Z","avatar_url":"https://github.com/msprev.png","language":"Go","funding_links":[],"categories":["Word Processors"],"sub_categories":[],"readme":"![](https://d.pr/i/8uXzLx+ \"screenshot\")\n\n# fzf-bibtex\n\nA BibTeX source for fzf.\n\n- Blazingly fast, even with extremely large BibTeX files\n- Caches results intelligently (hence the speed)\n- Uses a well-understood framework to parse BibTeX ([bibtool](https://ctan.org/pkg/bibtool))\n- vim and neovim integration (with [fzf.vim](https://github.com/junegunn/fzf.vim) or [fzf-lua](https://github.com/ibhagwan/fzf-lua))\n- Supports multiple BibTeX files\n- Supports cross references (thanks to [\\@cao](https://github.com/cao))\n- Supports multiple citation formats\n- BibLaTeX support (thanks to [\\@ashwinvis](https://github.com/ashwinvis))\n\n## Example use\n\nTo select items using fzf from a `.bib` file (as in image above):\n\n```shell\nbibtex-ls references.bib | fzf --multi --ansi\n```\n\nTo cite items (using the pandoc '@' format) from a `.bib` file:\n\n```shell\nbibtex-ls references.bib | fzf --multi --ansi | bibtex-cite\n```\n\nTo pretty print items (in markdown) from a `.bib` file:\n\n```shell\nbibtex-ls references.bib | fzf --multi --ansi | bibtex-markdown references.bib\n```\n\n## Installation\n\n### Requirements\n\n- [fzf](https://github.com/junegunn/fzf)\n- [bibtool](https://ctan.org/pkg/bibtool)\n- [go](https://golang.org/)\n\nOn the Mac, these can be installed by [homebrew](https://brew.sh/):\n\n```shell\nbrew install fzf\nbrew install bib-tool\nbrew install go\n```\n\nIf you want vim/neovim integration, either:\n\n- [fzf.vim](https://github.com/junegunn/fzf.vim)\n\nor, if you prefer lua (for neovim only):\n\n- [fzf-lua](https://github.com/ibhagwan/fzf-lua)\n\nNB.  You only need one or other of these (see mappings below). You can\ninstall both if you really want.\n\n\n### Installation\n\n```shell\ngo install github.com/msprev/fzf-bibtex/cmd/bibtex-ls@latest\ngo install github.com/msprev/fzf-bibtex/cmd/bibtex-markdown@latest\ngo install github.com/msprev/fzf-bibtex/cmd/bibtex-cite@latest\n```\n\n### Why these dependencies?\n\nParsing BibTeX is a non-trivial task.  It is best to do it in a\nwell-understood and reliable way.  fzf-bibtex uses an extremely stable,\nreliable, and widely used parser, `bibtool`.  The goal of fzf-bibtex is\nto have no noticable delay when searching, even for extremely large\nBibTeX files.  Writing it with Go allows the desired responsiveness to\nbe achieved.\n\n## Command line use\n\n### bibtex-ls\n\n```shell\nbibtex-ls [-cache=...] [file1.bib file2.bib ...]\n```\n\nLists to stdout the content of .bib files, one record per line.\n\nIf the following environment variables are set, then these command line arguments can be omitted.\n\n- `FZF_BIBTEX_CACHEDIR`: path to a cache directory\n- `FZF_BIBTEX_SOURCES`: path to bibtex file; multiple items separated by a '`:`'\n\nThe cache directory should be a suitable directory for bibtex-ls temporary files.\nParsing BibTeX databases is computationally intensive, so the command caches the results.\n    The cache is updated if the underlying BibTeX file has been changed.\n    If no cache directory is specified, the operating system's directory for temporary files is used.\n\n(NB. If you are tinkering with fzf-bibtex's codebase, beware of outdated caches.\nCache is *only* updated if the underlying BibTeX file has been changed.\nIf you change the fzf-bibtex codebase, make sure to flush the cache by `touch`ing the BibTeX files, or deleting the cache, before you run new code on them).\n\n### bibtex-cite\n\n```shell\nbibtex-cite [-mode=pandoc|latex] [-prefix=...] [-postfix=...] [-separator=...]\n```\n\nPretty print citations for selected entries passed over stdin.\n\nCitation format may be customised with `-prefix`, `-postfix`, and `-separator` options.\n\nDefault values (suitable for pandoc '@' format):\n\n- `-prefix=\"@\"` `-postfix=\"\"` `-separator=\"; @\"`\n\nLegacy `-mode` option provides presets for pandoc and LaTeX style\ncitations.  `-mode` options:\n\n- `-mode=pandoc` = `-prefix=\"@\"      -postfix=\"\"  -separator=\"; @\"`\n- `-mode=latex`  = `-prefix=\"\\cite{\" -postfix=\"}\" -separator=\", \"`\n\n### bibtex-markdown\n\n```shell\nbibtex-markdown [-cache=...] [file1.bib file2.bib ...]\n```\n\nPretty print items (in markdown) for selected `.bib` entries passed over stdin.\n\nCache directory may be set using the same environment variable as bibtex-ls.\n\n## fzf.vim integration\n\nAssuming the executables installed above are available to Vim in your file path, add the following code to your `vimrc` file (or, for neovim, your `init.vim`):\n\n\u003cdetails\u003e\u003csummary\u003efzf-vim integration (normal mode)\u003c/summary\u003e\n\n```vim\nlet $FZF_BIBTEX_CACHEDIR = 'PATH-TO-CACHE-DIR'\nlet $FZF_BIBTEX_SOURCES = 'PATH-TO-BIBTEX-FILE'\n\nfunction! s:bibtex_cite_sink(lines)\n    let r=system(\"bibtex-cite \", a:lines)\n    execute ':normal! a' . r\nendfunction\n\nfunction! s:bibtex_markdown_sink(lines)\n    let r=system(\"bibtex-markdown \", a:lines)\n    execute ':normal! a' . r\nendfunction\n\nnnoremap \u003csilent\u003e \u003cleader\u003ec :call fzf#run({\n                        \\ 'source': 'bibtex-ls',\n                        \\ 'sink*': function('\u003csid\u003ebibtex_cite_sink'),\n                        \\ 'up': '40%',\n                        \\ 'options': '--ansi --layout=reverse-list --multi --prompt \"Cite\u003e \"'})\u003cCR\u003e\n\nnnoremap \u003csilent\u003e \u003cleader\u003em :call fzf#run({\n                        \\ 'source': 'bibtex-ls',\n                        \\ 'sink*': function('\u003csid\u003ebibtex_markdown_sink'),\n                        \\ 'up': '40%',\n                        \\ 'options': '--ansi --layout=reverse-list --multi --prompt \"Markdown\u003e \"'})\u003cCR\u003e\n```\n\n\u003c/details\u003e\n\n- `\u003cleader\u003ec` will bring up fzf to cite selected items\n- `\u003cleader\u003em` will bring up fzf to markdown pretty print cite selected items\n\n\n\u003cdetails\u003e\u003csummary\u003efzf-vim integration (insert mode)\u003c/summary\u003e\n\n```vim\nfunction! s:bibtex_cite_sink_insert(lines)\n    let r=system(\"bibtex-cite \", a:lines)\n    execute ':normal! a' . r\n    call feedkeys('a', 'n')\nendfunction\n\ninoremap \u003csilent\u003e @@ \u003cc-g\u003eu\u003cc-o\u003e:call fzf#run({\n                        \\ 'source': 'bibtex-ls',\n                        \\ 'sink*': function('\u003csid\u003ebibtex_cite_sink_insert'),\n                        \\ 'up': '40%',\n                        \\ 'options': '--ansi --layout=reverse-list --multi --prompt \"Cite\u003e \"'})\u003cCR\u003e\n```\n\n\u003c/details\u003e\n\n- `@@` will bring up fzf to cite selected items\n\nAlternative insert mode mapping (`@@`) that detects .bib files in parent, current or child directories (thanks to [\\@ashwinvis](https://github.com/ashwinvis)):\n\n\u003cdetails\u003e\u003csummary\u003efzf-vim integration (alternative insert mapping -- automatically reads from nearby .bib files)\u003c/summary\u003e\n\n```vim\nfunction! Bibtex_ls()\n  let bibfiles = (\n      \\ globpath('.', '*.bib', v:true, v:true) +\n      \\ globpath('..', '*.bib', v:true, v:true) +\n      \\ globpath('*/', '*.bib', v:true, v:true)\n      \\ )\n  let bibfiles = join(bibfiles, ' ')\n  let source_cmd = 'bibtex-ls '.bibfiles\n  return source_cmd\nendfunction\n\nfunction! s:bibtex_cite_sink_insert(lines)\n    let r=system(\"bibtex-cite \", a:lines)\n    execute ':normal! a' . r\n    call feedkeys('a', 'n')\nendfunction\n\ninoremap \u003csilent\u003e @@ \u003cc-g\u003eu\u003cc-o\u003e:call fzf#run({\n                        \\ 'source': Bibtex_ls(),\n                        \\ 'sink*': function('\u003csid\u003ebibtex_cite_sink_insert'),\n                        \\ 'up': '40%',\n                        \\ 'options': '--ansi --layout=reverse-list --multi --prompt \"Cite\u003e \"'})\u003cCR\u003e\n```\n\n\u003c/details\u003e\n\n## fzf-lua integration\n\nIf you use [fzf-lua](https://github.com/ibhagwan/fzf-lua) in neovim, you can add the following\ncode inside to your `init.lua` or similar config file.\n\n\u003cdetails\u003e\u003csummary\u003efzf-lua integration\u003c/summary\u003e\n\n```lua\n-- default list of bibfiles\n-- can be overriden by changing vim.b.bibfiles inside buffer\nlocal default_bibfiles = {\n    -- put your default bibfiles here\n    }\n\n-- default cache directory\n-- uses neovim's stdpath to set up a cache - no need to fiddle with this\nlocal cachedir = vim.fn.stdpath(\"state\") .. \"/fzf-bibtex/\"\n\n-- actions\nlocal pandoc = function(selected, opts)\n    local result = vim.fn.system('bibtex-cite', selected)\n    vim.api.nvim_put({ result }, \"c\", false, true)\n    if opts.fzf_bibtex.mode == \"i\" then\n        vim.api.nvim_feedkeys(\"i\", \"n\", true)\n    end\nend\n\nlocal citet = function(selected, opts)\n    local result = vim.fn.system('bibtex-cite -prefix=\"\\\\citet{\" -postfix=\"}\" -separator=\",\"', selected)\n    vim.api.nvim_put({ result }, \"c\", false, true)\n    if opts.fzf_bibtex.mode == \"i\" then\n        vim.api.nvim_feedkeys(\"i\", \"n\", true)\n    end\nend\n\nlocal citep = function(selected, opts)\n    local result = vim.fn.system('bibtex-cite -prefix=\"\\\\citep{\" -postfix=\"}\" -separator=\",\"', selected)\n    vim.api.nvim_put({ result }, \"c\", false, true)\n    if opts.fzf_bibtex.mode == \"i\" then\n        vim.api.nvim_feedkeys(\"i\", \"n\", true)\n    end\nend\n\nlocal markdown_print = function(selected, opts)\n    local result = vim.fn.system(\"bibtex-markdown -cache=\" .. cachedir .. \" \" .. table.concat(vim.b.bibfiles, \" \"),\n        selected)\n    local result_lines = {}\n    for line in result:gmatch('[^\\n]+') do\n        table.insert(result_lines, line)\n    end\n    vim.api.nvim_put(result_lines, \"l\", true, true)\n    if opts.fzf_bibtex.mode == \"i\" then\n        vim.api.nvim_feedkeys(\"i\", \"n\", true)\n    end\nend\n\nlocal fzf_bibtex_menu = function(mode)\n    return function()\n        -- check cache directory hasn't mysteriously disappeared\n        if vim.fn.isdirectory(cachedir) == 0 then\n            vim.fn.mkdir(cachedir, \"p\")\n        end\n\n        require 'fzf-lua'.config.set_action_helpstr(pandoc, \"@-pandoc\")\n        require 'fzf-lua'.config.set_action_helpstr(citet, \"\\\\citet{}\")\n        require 'fzf-lua'.config.set_action_helpstr(citep, \"\\\\citep{}\")\n        require 'fzf-lua'.config.set_action_helpstr(markdown_print, \"markdown-pretty-print\")\n\n        -- header line: the bibtex filenames\n        local filenames = {}\n        for i, fullpath in ipairs(vim.b.bibfiles) do\n            filenames[i] = vim.fn.fnamemodify(fullpath, \":t\")\n        end\n        local header = table.concat(filenames, \"\\\\ \")\n\n        -- set default action\n        local default_action = nil\n        if vim.bo.ft == \"markdown\" then\n            default_action = pandoc\n        elseif\n            vim.bo.ft == \"tex\" then\n            default_action = citet\n        end\n\n        -- run fzf\n        return require 'fzf-lua'.fzf_exec(\n            \"bibtex-ls \"\n            .. \"-cache=\" .. cachedir .. \" \"\n            .. table.concat(vim.b.bibfiles, \" \"), {\n                actions = {\n                        ['default'] = default_action,\n                        ['alt-a'] = pandoc,\n                        ['alt-t'] = citet,\n                        ['alt-p'] = citep,\n                        ['alt-m'] = markdown_print,\n                },\n                fzf_bibtex = { ['mode'] = mode },\n                fzf_opts = { [\"--multi\"] = true, ['--prompt'] = 'BibTeX\u003e ', ['--header'] = header }\n            })\n    end\nend\n\n-- Only enable mapping in tex or markdown\nvim.api.nvim_create_autocmd(\"Filetype\", {\n    desc = \"Set up keymaps for fzf-bibtex\",\n    group = vim.api.nvim_create_augroup(\"fzf-bibtex\", { clear = true }),\n    pattern = { \"markdown\", \"tex\" },\n    callback = function()\n        vim.b.bibfiles = default_bibfiles\n        vim.keymap.set(\"n\", \"\u003cleader\u003ec\", fzf_bibtex_menu(\"n\"), { buffer = true, desc = \"FZF: BibTeX [C]itations\" })\n        vim.keymap.set(\"i\", \"@@\", fzf_bibtex_menu(\"i\"), { buffer = true, desc = \"FZF: BibTeX [C]itations\" })\n    end\n})\n```\n\n\u003c/details\u003e\n\nMappings will only be active for `tex` or `markdown` filetypes:\n\n- `\u003cleader\u003ec` will bring up fzf to cite selected items\n    - `\u003ccr\u003e`: insert with default citation style\n    - `\u003calt-a\u003e`: insert citation with pandoc @ style\n    - `\u003calt-t\u003e`: insert citation with LaTeX \\\\citet{} style\n    - `\u003calt-p\u003e`: insert citation with LaTeX \\\\citep{} style\n    - `\u003calt-m\u003e`: pretty print selected items in markdown\n- `@@` in insert mode brings up the same fzf menu.\n\n\n\n## Errors?\n\nfzf-bibtex uses [bibtool](https://ctan.org/pkg/bibtool) to parse BibTeX\nfiles.  If there is an error, it is likely that your BibTeX file is not\nbeing parsed correctly.  You can locate the cause, and correct it, by\nrunning bibtool directly on your BibTeX file from the command line.  Look\nat any errors reported from:\n\n```shell\nbibtool references.bib -o parsed.bib\n```\n\nThe BibTeX fields that fzf-bibtex asks bibtool to extract from your file\ncan be seen by running bibtool with the `rsc` file specified in [this string](https://github.com/msprev/fzf-bibtex/blob/ae9b939fb30448a85a6b18370bfdab4a451eeba4/bibtex/bibtex.go#L57).\n\n\n## Release notes\n\n- 1.1 (17 February 2020)\n    - support arbitrary citation formats\n- 1.0 (4 November 2018)\n    - first version\n\n## Similar\n\n- [unite-bibtex](https://github.com/msprev/unite-bibtex) -- no longer maintained; this replaces it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsprev%2Ffzf-bibtex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsprev%2Ffzf-bibtex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsprev%2Ffzf-bibtex/lists"}