Add anchor duplicate checking before creation

This commit is contained in:
Marty Oehme 2021-05-04 17:51:32 +02:00
parent 5345b6c345
commit eaa7b589d2
Signed by: Marty
GPG key ID: B7538B8F50A1C800
6 changed files with 85 additions and 5 deletions

View file

@ -2,16 +2,23 @@ local A = {}
local o = require 'zettelkasten.options' local o = require 'zettelkasten.options'
local function deduplicate(anchor, anchorfct)
while A.is_duplicate(anchor, anchorfct) do anchor = anchor - 1 end
return anchor
end
-- Return a valid zettelkasten anchor, -- Return a valid zettelkasten anchor,
-- composed of yymmddHHMM. -- composed of yymmddHHMM.
-- --
-- date can be passed in as a table containing a year, a month, a day, an hour, -- date can be passed in as a table containing a year, a month, a day, an hour,
-- and a minute key. Returns nil if the date passed in is invalid. -- and a minute key. Returns nil if the date passed in is invalid.
-- If no date is passed in, returns Zettel anchor for current moment. -- If no date is passed in, returns Zettel anchor for current moment.
function A.create(date) function A.create(date, anchorfct)
local timestamp local timestamp
if pcall(function() timestamp = os.time(date) end) then if pcall(function() timestamp = os.time(date) end) then
return os.date('%y%m%d%H%M', timestamp) local anchor = os.date('%y%m%d%H%M', timestamp)
if anchorfct then anchor = deduplicate(anchor, anchorfct) end
return tostring(anchor)
else else
return nil return nil
end end
@ -37,4 +44,21 @@ function A.extract(input, regex)
return input:match(regex) return input:match(regex)
end end
-- Returns a set of all anchors created by the function passed in
-- (if argument is set) or all anchors currently in zettel root dir
-- (if no argument passed).
function A.list(anchor_function)
if not anchor_function then return {} end
return anchor_function()
end
-- Returns true if anchor passed in already exists, false otherwise.
-- Takes an optional set of anchors to compare against, will
-- compare against all anchors in zettel root dir otherwise.
function A.is_duplicate(anchor, anchor_function)
local all_anchors = A.list(anchor_function)
if all_anchors[anchor] ~= nil then return true end
return false
end
return A return A

View file

@ -14,6 +14,22 @@ describe("create", function()
it("should return nil if argument passed in is invalid", it("should return nil if argument passed in is invalid",
function() assert.is_nil(A.create("My grandmother is lovely.")) end) function() assert.is_nil(A.create("My grandmother is lovely.")) end)
it(
"should lower timestamps until the first non-duplicated one if valid anchor gathering function passed",
function()
Anchor_fct = function()
return {
["2010261208"] = "/path/to/my/anchor.md",
["1910291645"] = "/path/to/my/other_anchor.md"
}
end
assert.same("1910291644", A.create(Test_date, Anchor_fct))
end)
it(
"should ignore duplicate timestamps if no anchor gathering function passed",
function() assert.same("1910291645", A.create(Test_date)) end)
end) end)
describe("prepend", function() describe("prepend", function()
@ -61,3 +77,33 @@ describe("extract", function()
"[%l][%u][%d][%d][%d][%u]")) "[%l][%u][%d][%d][%d][%u]"))
end) end)
end) end)
describe("list", function()
it("should return a set of anchors", function()
local anchor_fct = function()
return {
["2010261208"] = "/path/to/my/anchor.md",
["2001011212"] = "/path/to/my/other_anchor.md"
}
end
assert.same({
["2010261208"] = "/path/to/my/anchor.md",
["2001011212"] = '/path/to/my/other_anchor.md'
}, A.list(anchor_fct))
end)
end)
describe("check_anchor_exists", function()
before_each(function()
Anchor_fct = function()
return {
["2010261208"] = "/path/to/my/anchor.md",
["2001011212"] = "/path/to/my/other_anchor.md"
}
end
end)
it("returns true if anchor in existing set",
function() assert.is_true(A.is_duplicate('2001011212', Anchor_fct)) end)
it("returns false if anchor not in existing set",
function() assert.is_false(A.is_duplicate('2001011210', Anchor_fct)) end)
end)

View file

@ -24,6 +24,7 @@ end
-- TODO transform paths: -- TODO transform paths:
-- * to ensure / at the end (or no /) gets taken into account -- * to ensure / at the end (or no /) gets taken into account
function ls.get_anchors_and_paths(fileset) function ls.get_anchors_and_paths(fileset)
fileset = fileset or ls.get_all_files(o.zettel().rootdir, true)
-- TODO check for duplicates and warn user -- TODO check for duplicates and warn user
local zettel = {} local zettel = {}
local anchorreg = '^.*/?(' .. o.anchor().regex .. ')[^/]*%' .. local anchorreg = '^.*/?(' .. o.anchor().regex .. ')[^/]*%' ..

View file

@ -2,6 +2,7 @@ local L = {}
local o = require 'zettelkasten.options' local o = require 'zettelkasten.options'
local a = require 'zettelkasten.anchor' local a = require 'zettelkasten.anchor'
local f = require 'zettelkasten.files'
local parsers = { local parsers = {
markdown = { markdown = {
@ -58,7 +59,7 @@ end
-- Takes an optional link text which will be added to the link. -- Takes an optional link text which will be added to the link.
-- Takes an optional style according to which the link will be transformed. -- Takes an optional style according to which the link will be transformed.
function L.new(text, style) function L.new(text, style)
local anchor = a.create() local anchor = a.create(nil, f.get_anchors_and_paths)
return L.create(anchor, text, style) return L.create(anchor, text, style)
end end

View file

@ -1,4 +1,4 @@
link = require 'zettelkasten.link' local link = require 'zettelkasten.link'
Test_date = {year = 2019, month = 10, day = 29, hour = 16, min = 45} Test_date = {year = 2019, month = 10, day = 29, hour = 16, min = 45}
before_each(function() _G.vim = {g = {}, b = {}} end) before_each(function() _G.vim = {g = {}, b = {}} end)
@ -79,6 +79,12 @@ describe("create", function()
end) end)
describe("new", function() describe("new", function()
before_each(function()
vim.loop = {
fs_scandir = function(_) return false end,
fs_scandir_next = function(_) end
}
end)
it("should create a link out of only text input", function() it("should create a link out of only text input", function()
local result = link.new("My FILE NAME") local result = link.new("My FILE NAME")
assert.is_not_nil(result:match( assert.is_not_nil(result:match(

View file

@ -90,7 +90,9 @@ end
--- @param linenr number --- @param linenr number
--- @return string --- @return string
function T.get_line(linenr) function T.get_line(linenr)
if linenr then return vim.api.nvim_buf_get_lines(0, linenr - 1, linenr, false)[1] end if linenr then
return vim.api.nvim_buf_get_lines(0, linenr - 1, linenr, false)[1]
end
return vim.api.nvim_get_current_line() return vim.api.nvim_get_current_line()
end end