Skip to content

Instantly share code, notes, and snippets.

@anandkumar89
Last active March 28, 2025 20:16
Show Gist options
  • Select an option

  • Save anandkumar89/d39de188c2d8c6462bc127e2624beffb to your computer and use it in GitHub Desktop.

Select an option

Save anandkumar89/d39de188c2d8c6462bc127e2624beffb to your computer and use it in GitHub Desktop.
`seek.lua` file in zotcite. I've modified it (i) Use betterbibtex citekeys (consistent with vimtex this way) (ii) Use Fzf picker (iii) Use <CR> to open attachments in sioyek. Things are hacked to just work!
local pickers = require("telescope.pickers")
local fzf_lua = require("fzf-lua")
local finders = require("telescope.finders")
local sorters = require("telescope.config").values
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local previewers = require("telescope.previewers")
local entry_display = require("telescope.pickers.entry_display")
local M = {}
local get_match = function(key)
local citeptrn = key:gsub(" .*", "")
local refs = vim.fn.py3eval(
'ZotCite.GetMatch("'
.. citeptrn
.. '", "'
.. vim.fn.escape(vim.fn.expand("%:p"), "\\")
.. '", True)'
)
if #refs == 0 then
vim.schedule(
function() vim.api.nvim_echo({ { "No matches found." } }, false, {}) end
)
end
return refs
end
M.print = function(ref)
local msg = {
{ ref.value.alastnm, "Identifier" },
{ " " },
{ ref.value.year, "Number" },
{ " " },
{ ref.value.title, "Title" },
}
vim.schedule(function() vim.api.nvim_echo(msg, false, {}) end)
end
local format_preview = function(v)
local alist = {}
local authors
if v.author then
if #v.author > 5 then
authors = v.author[1][1] .. ", " .. v.author[1][2] .. " and others"
else
for _, n in pairs(v.author) do
table.insert(alist, n[1] .. ", " .. n[2])
end
authors = table.concat(alist, "; ")
end
else
authors = "?"
end
local preview_text
if v.etype == "journalArticle" then
preview_text = string.format(
"{(%s)}\n{{%s}} {[%s]}. {<%s>}.\n\n%s\n\n{[%s]} {<%s>}",
v.title or "",
authors,
v.year or "",
v.publicationTitle or "",
v.abstract or "No abstract available.",
v.etype, v.cite
)
elseif v.etype == "bookSection" then
preview_text = string.format(
"{(%s)}\n{{%s}} {[%s]}. In: {<%s>}.\n\n%s\n\n{[%s]} {<%s>}",
v.title or "",
authors,
v.year or "",
v.publicationTitle or "",
v.abstract or "",
v.etype, v.cite
)
else
preview_text = string.format(
"{(%s)}\n{{%s}} {[%s]}.\n\n%s\n\n{[%s]} {<%s>}",
v.title or "",
authors,
v.year or "",
v.abstract or "",
v.etype, v.cite
)
end
return preview_text
end
--- Use telescope to find and select a reference
---@param key string Pattern to search
---@param cb function Callback function
M.refs = function(key, cb)
local mtchs = get_match(key)
local references = {}
local awidth = 2
local awlim = vim.o.columns - 140
if awlim < 20 then awlim = 20 end
if awlim > 60 then awlim = 60 end
for _, v in pairs(mtchs) do
if #v.alastnm > awidth then awidth = #v.alastnm end
table.insert(references, {
display = v.alastnm .. " " .. v.year .. " " .. v.title,
etype = v.etype,
adate = v.accessDate or v.date or "0000-00-00 000",
publicationTitle = v.publicationTitle
or v.bookTitle
or v.proceedingsTitle
or v.conferenceName
or v.programTitle
or v.blogTitle
or v.code
or v.dictionaryTitle
or v.encyclopediaTitle
or v.forumTitle
or v.websiteTitle
or v.seriesTitle,
author = v.author
or v.artist
or v.performer
or v.director
or v.composer
or v.sponsor
or v.contributor
or v.interviewee
or v.cartographer
or v.inventor
or v.podcaster
or v.presenter
or v.programmer
or v.recipient
or v.editor
or v.seriesEditor
or v.translator,
alastnm = v.alastnm,
year = v.year,
title = v.title,
abstract = v.abstractNote,
key = v.zotkey,
cite = v.citekey,
})
end
if awidth > awlim then awidth = awlim end
table.sort(references, function(a, b) return (a.adate > b.adate) end)
local entries = {}
local previewtext = {}
for i, ref in ipairs(references) do
local author_str = string.format("%-" .. awidth .. "s", ref.alastnm)
local type_str = string.format("%-10s", ref.etype)
local year_str = string.format("%-4s", ref.year)
local entry_str = string.format("%s\t%s %s %s %s", ref.cite, type_str, author_str, year_str, ref.title)
entries[i] = entry_str
previewtext[ref.cite] = format_preview(ref)
end
-- fzf-lua configuration
fzf_lua.fzf_exec(entries, {
prompt = "Search pattern> ",
fzf_opts = {
['--header'] = "Ctrl-o: Select | Enter: Open Attachment",
['--delimiter'] = '\t',
['--with-nth'] = '2',
['--ansi'] = true,
},
previewer = {
_ctor = function()
local base = require 'fzf-lua.previewer.builtin'.buffer_or_file
local previewer = base:extend()
function previewer:populate_preview_buf(selection)
local citekey = selection:match("([^\t]+)")
local previewLines = previewtext[citekey]
local tmpbuf = self:get_tmp_buffer()
vim.api.nvim_buf_set_lines(tmpbuf, 0, -1, false, vim.split(previewLines, '\n'))
vim.bo[tmpbuf].filetype = "bib"
self:set_preview_buf(tmpbuf)
end
return previewer
end,
},
actions = {
['default'] = function(selected)
local citekey = selected[1]:match("([^\t]+)")
if citekey then
require("zotcite.get").open_attachment(citekey)
end
end,
['ctrl-o'] = function(selected)
local citekey = selected[1]:match("([^\t]+)")
if citekey and cb then
cb(citekey)
end
end,
},
})
-- pickers
-- .new({}, {
-- prompt_title = "Search pattern",
-- results_title = "Zotero references",
-- finder = finders.new_table({
-- results = references,
-- entry_maker = function(entry)
-- local displayer = entry_display.create({
-- separator = " ",
-- items = {
-- { width = awidth }, -- Author
-- { width = 4 }, -- Year
-- { remaining = true }, -- Title
-- },
-- })
-- return {
-- value = entry,
-- display = function(e)
-- return displayer({
-- { e.value.alastnm, "Identifier" },
-- { e.value.year, "Number" },
-- { e.value.title, "Title" },
-- })
-- end,
-- ordinal = entry.display,
-- }
-- end,
-- }),
-- sorter = sorters.generic_sorter({}),
-- previewer = previewers.new_buffer_previewer({
-- define_preview = function(self, entry, _)
-- local bufnr = self.state.bufnr
-- vim.api.nvim_set_option_value(
-- "syntax",
-- "zoteropreview",
-- { buf = bufnr }
-- )
--
-- local preview_text = format_preview(entry.value)
--
-- vim.api.nvim_buf_set_lines(
-- bufnr,
-- 0,
-- -1,
-- false,
-- vim.split(preview_text, "\n")
-- )
-- end,
-- }),
-- attach_mappings = function(prompt_bufnr, map)
-- map("i", "<C-o>", function()
-- local selection = action_state.get_selected_entry()
-- actions.close(prompt_bufnr)
-- -- Handle the selected reference here
-- cb(selection)
-- end)
-- map("i", "<CR>", function()
-- local selection = action_state.get_selected_entry()
-- -- actions.close(prompt_bufnr)
-- print(selection.value)
-- require("zotcite.get").open_attachment(selection.value.cite)
-- end)
-- return true
-- end,
-- })
-- :find()
end
-- text wrapping in the preview window
vim.api.nvim_create_autocmd("User", {
pattern = "TelescopePreviewerLoaded",
callback = function()
vim.wo.wrap = true
vim.wo.linebreak = true
end,
})
return M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment