Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Telescope: handle multiple selections #88

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 45 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,19 +233,42 @@ enable_modules = {
-- troubleshoot and diagnose issues)
},

-- Defines citation formats for various filetypes. When the value is a table, then
-- the first entry is used to insert citations, whereas the second will be used to
-- find references (e.g. by the `at-cursor` module). `%s` stands for the reference.
-- Note that the first entry is a string (where e.g. `\` needs to be excaped as `\\`)
-- and the second a lua pattern (where magic characters need to be escaped with
-- `%`; https://www.lua.org/pil/20.2.html).
-- Defines citation formats for various filetypes. They define how citation strings
-- are parsed and formatted when inserted. For each filetype, we may define:
-- - `start_str`: precedes the citation
-- - `end_str`: appended after the citation
-- - `ref_prefix`: precedes each `ref` in a citation
-- - `separator_str`: gets added between `ref`s if there are multiple in a citation
-- For example, for the `org` filetype if we insert a citation with `Ref1` and `Ref2`,
-- we end up with `[cite:@Ref1;@Ref2]`.
cite_formats = {
tex = { "\\cite{%s}", "\\cite[tp]?%*?{%s}" },
markdown = "@%s",
rmd = "@%s",
plain = "%s",
org = { "[cite:@%s]", "%[cite:@%s]" },
norg = "{= %s}",
tex = {
start_str = [[\cite{]],
end_str = "}",
separator_str = ", ",
},
markdown = {
ref_prefix = "@",
separator_str = "; "
},
rmd = {
ref_prefix = "@",
separator_str = "; "
},
plain = {
separator_str = ", "
},
org = {
start_str = "[cite:",
end_str = "]",
ref_prefix = "@",
separator_str = ";",
},
norg = {
start_str = "{= ",
end_str = "}",
separator_str = "; ",
},
},

-- What citation format to use when none is defined for the current filetype.
Expand Down Expand Up @@ -391,8 +414,9 @@ enable_icons = true,

-- This function runs when first opening a new note. The `entry` arg is a table
-- containing all the information about the entry (see above `data_tbl_schema`).
-- This example is meant to be used with the `markdown` filetype.
format_notes_fn = function(entry)
-- This example is meant to be used with the `markdown` filetype. The function
-- must return a set of lines, specifying the lines to be added to the note.
format_notes = function(entry)
-- Some string formatting templates (see above `results_format` option for
-- more details)
local title_format = {
Expand All @@ -413,14 +437,13 @@ enable_icons = true,
"---",
"",
}
-- Insert the lines
vim.api.nvim_buf_set_lines(0, 0, #lines, false, lines)
-- Move cursor to the bottom
vim.cmd("normal G")
return lines
end,
-- This function runs when inserting a formatted reference (currently by `f/c-f` in
-- Telescope). It works similarly to the `format_notes_fn` above.
format_references_fn = function(entry)
-- Telescope). It works similarly to the `format_notes` above, except that the set
-- of lines should only contain one line (references using multiple lines aren't
-- currently supported).
format_references = function(entry)
local reference_format = {
{ "author", "%s ", "" },
{ "year", "(%s). ", "" },
Expand All @@ -433,7 +456,8 @@ enable_icons = true,
for k, v in ipairs(reference_data) do
reference_data[k] = v[1]
end
return table.concat(reference_data)
local lines = { table.concat(reference_data) }
return lines
end,
},

Expand Down
68 changes: 46 additions & 22 deletions doc/papis.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*papis.txt* For NVIM v0.8.0 Last change: 2024 July 30
*papis.txt* For NVIM v0.8.0 Last change: 2024 August 18

==============================================================================
Table of Contents *papis-table-of-contents*
Expand Down Expand Up @@ -271,19 +271,42 @@ All configuration options (with defaults) ~
-- troubleshoot and diagnose issues)
},

-- Defines citation formats for various filetypes. When the value is a table, then
-- the first entry is used to insert citations, whereas the second will be used to
-- find references (e.g. by the `at-cursor` module). `%s` stands for the reference.
-- Note that the first entry is a string (where e.g. `\` needs to be excaped as `\\`)
-- and the second a lua pattern (where magic characters need to be escaped with
-- `%`; https://www.lua.org/pil/20.2.html).
-- Defines citation formats for various filetypes. They define how citation strings
-- are parsed and formatted when inserted. For each filetype, we may define:
-- - `start_str`: precedes the citation
-- - `end_str`: appended after the citation
-- - `ref_prefix`: precedes each `ref` in a citation
-- - `separator_str`: gets added between `ref`s if there are multiple in a citation
-- For example, for the `org` filetype if we insert a citation with `Ref1` and `Ref2`,
-- we end up with `[cite:@Ref1;@Ref2]`.
cite_formats = {
tex = { "\\cite{%s}", "\\cite[tp]?%*?{%s}" },
markdown = "@%s",
rmd = "@%s",
plain = "%s",
org = { "[cite:@%s]", "%[cite:@%s]" },
norg = "{= %s}",
tex = {
start_str = [[\cite{]],
end_str = "}",
separator_str = ", ",
},
markdown = {
ref_prefix = "@",
separator_str = "; "
},
rmd = {
ref_prefix = "@",
separator_str = "; "
},
plain = {
separator_str = ", "
},
org = {
start_str = "[cite:",
end_str = "]",
ref_prefix = "@",
separator_str = ";",
},
norg = {
start_str = "{= ",
end_str = "}",
separator_str = "; ",
},
},

-- What citation format to use when none is defined for the current filetype.
Expand Down Expand Up @@ -429,8 +452,9 @@ All configuration options (with defaults) ~

-- This function runs when first opening a new note. The `entry` arg is a table
-- containing all the information about the entry (see above `data_tbl_schema`).
-- This example is meant to be used with the `markdown` filetype.
format_notes_fn = function(entry)
-- This example is meant to be used with the `markdown` filetype. The function
-- must return a set of lines, specifying the lines to be added to the note.
format_notes = function(entry)
-- Some string formatting templates (see above `results_format` option for
-- more details)
local title_format = {
Expand All @@ -451,14 +475,13 @@ All configuration options (with defaults) ~
"---",
"",
}
-- Insert the lines
vim.api.nvim_buf_set_lines(0, 0, #lines, false, lines)
-- Move cursor to the bottom
vim.cmd("normal G")
return lines
end,
-- This function runs when inserting a formatted reference (currently by `f/c-f` in
-- Telescope). It works similarly to the `format_notes_fn` above.
format_references_fn = function(entry)
-- Telescope). It works similarly to the `format_notes` above, except that the set
-- of lines should only contain one line (references using multiple lines aren't
-- currently supported).
format_references = function(entry)
local reference_format = {
{ "author", "%s ", "" },
{ "year", "(%s). ", "" },
Expand All @@ -471,7 +494,8 @@ All configuration options (with defaults) ~
for k, v in ipairs(reference_data) do
reference_data[k] = v[1]
end
return table.concat(reference_data)
local lines = { table.concat(reference_data) }
return lines
end,
},

Expand Down
51 changes: 33 additions & 18 deletions lua/papis/at-cursor/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ local NuiPopup = require("nui.popup")
local nuiAutocmd = require("nui.utils.autocmd")
local nuiEvent = require("nui.utils.autocmd").event

local fn = vim.fn

local log = require("papis.log")
local config = require("papis.config")
local popup_format = config["at-cursor"].popup_format
local cite_format = config:get_cite_format()
local utils = require("papis.utils")
local commands = require("papis.commands")
local keymaps = require("papis.keymaps")
Expand All @@ -25,24 +24,40 @@ end
---Tries to identify the ref under cursor
---@return string|nil #Nil if nothing is found, otherwise is the identified ref
local function get_ref_under_cursor()
-- get the word under the cursor
local ref = fn.expand("<cWORD>")
local filetype = vim.bo.filetype
log.debug("The filetype is: " .. filetype)
local cite_format = utils.get_cite_format(filetype)
if type(cite_format) == "table" then
cite_format = cite_format[2]
end
log.debug("The cite_format is: " .. cite_format)
local _, prefix_end = string.find(cite_format, "%%s")
prefix_end = prefix_end - 2
local cite_format_prefix = string.sub(cite_format, 1, prefix_end)
local _, ref_start = string.find(ref, cite_format_prefix)
local start_str = cite_format.start_str
local ref_prefix = cite_format.ref_prefix

-- get current line and cursor position
local current_line = vim.api.nvim_get_current_line()
local _, cursor_col = unpack(vim.api.nvim_win_get_cursor(0))

-- Find the start and end of the word under the cursor
local line_until_cursor = current_line:sub(1, cursor_col)
local word_start_col = line_until_cursor:find("[^%s,;]*$") or 1
local line_after_cursor = current_line:sub(cursor_col)
local word_end_col = cursor_col + (line_after_cursor:find("[%s,;]") or #line_after_cursor) - 1

-- Extract the word
local ref = current_line:sub(word_start_col, word_end_col)

-- if we found the cite_format prefix in the string, we need to strip it
if ref_start then
ref_start = ref_start + 1
ref = string.sub(ref, ref_start)
if start_str then
local escaped_start_str = start_str:gsub("%W", "%%%0")
local _, ref_start = string.find(ref, escaped_start_str)
if ref_start then
ref = string.sub(ref, ref_start + 1)
end
end
-- if we found the ref_prefix in the string, we need to strip it
if ref_prefix then
local escaped_ref_prefix = ref_prefix:gsub("%W", "%%%0")
local _, ref_start = string.find(ref, escaped_ref_prefix)
if ref_start then
ref_start = ref_start + 1
ref = string.sub(ref, ref_start)
end
end

-- remove all punctuation characters at the beginning and end of string
ref = ref:gsub("^[%p]*(.-)[%p]*$", "%1")

Expand Down
64 changes: 53 additions & 11 deletions lua/papis/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,33 @@ local default_config = {
["testing"] = false,
}, -- can be set to nil or false or left out
cite_formats = {
tex = { "\\cite{%s}", "\\cite[tp]?%*?{%s}" },
markdown = "@%s",
rmd = "@%s",
plain = "%s",
org = { "[cite:@%s]", "%[cite:@%s]" },
norg = "{= %s}",
tex = {
start_str = [[\cite{]],
end_str = "}",
separator_str = ", ",
},
markdown = {
ref_prefix = "@",
separator_str = "; "
},
rmd = {
ref_prefix = "@",
separator_str = "; "
},
plain = {
separator_str = ", "
},
org = {
start_str = "[cite:",
end_str = "]",
ref_prefix = "@",
separator_str = ";",
},
norg = {
start_str = "{= ",
end_str = "}",
separator_str = "; ",
},
},
cite_formats_fallback = "plain",
always_use_plain = false,
Expand Down Expand Up @@ -64,7 +85,7 @@ local default_config = {
papis_conf_keys = { "info-name", "notes-name", "dir", "opentool" },
enable_icons = true,
["formatter"] = {
format_notes_fn = function(entry)
format_notes = function(entry)
local title_format = {
{ "author", "%s ", "" },
{ "year", "(%s) ", "" },
Expand All @@ -80,10 +101,9 @@ local default_config = {
"---",
"",
}
vim.api.nvim_buf_set_lines(0, 0, #lines, false, lines)
vim.cmd("normal G")
return lines
end,
format_references_fn = function(entry)
format_references = function(entry)
local reference_format = {
{ "author", "%s ", "" },
{ "year", "(%s). ", "" },
Expand All @@ -96,7 +116,8 @@ local default_config = {
for k, v in ipairs(reference_data) do
reference_data[k] = v[1]
end
return table.concat(reference_data)
local lines = { table.concat(reference_data) }
return lines
end,
},
["at-cursor"] = {
Expand Down Expand Up @@ -145,6 +166,27 @@ local default_config = {

local M = vim.deepcopy(default_config)

---Get the cite_format for the current filetype
---@return table #cite_format to be used for the filetype. If table, then first is for inserting, second for parsing
function M:get_cite_format()
local filetype = vim.bo.filetype

local cite_formats = self.cite_formats
local cite_formats_fallback = self.cite_formats_fallback

local fallback = {
separator_str = ", "
}

if self.always_use_plain then
local cite_format = cite_formats.plain or fallback
return cite_format
else
local cite_format = cite_formats[filetype] or cite_formats[cite_formats_fallback]
return cite_format
end
end

---Updates the default configuration with user supplied options and gets conf from Papis
---@param opts table #Same format as default_config and contains user config
function M:update(opts)
Expand Down
Loading