Skip to content

Commit

Permalink
Merge pull request #88 from jghauser/search-handle-multiple-entries
Browse files Browse the repository at this point in the history
Telescope: handle multiple selections
  • Loading branch information
jghauser authored Sep 1, 2024
2 parents e1a6e3e + 93c6c67 commit 2e691a1
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 175 deletions.
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 August 18
*papis.txt* For NVIM v0.8.0 Last change: 2024 September 01

==============================================================================
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

0 comments on commit 2e691a1

Please sign in to comment.