fix #43 via template_handling option, #38 via new_note_location opt, #33 improvements (detecting dailies/weeklies in links)

This commit is contained in:
Rene Schallner
2021-12-25 07:22:30 +01:00
parent c918734602
commit b1593bb4c1
4 changed files with 168 additions and 90 deletions

View File

@@ -69,7 +69,7 @@ local rep = string.rep
local len = string.len -- luacheck: ignore
local sub = string.sub
local gsub = string.gsub
local gmatch = string.gmatch or string.gfind
local gmatch = string.gmatch
local find = string.find
local ostime = os.time
local osdate = os.date
@@ -188,7 +188,7 @@ local function makedaynum(y, m, d)
end
-- date from day number, month is zero base
local function breakdaynum(g)
local g = g + 306
g = g + 306
local y = floor((10000 * g + 14780) / 3652425)
local d = g - dayfromyear(y)
if d < 0 then
@@ -333,8 +333,8 @@ local function getequivyear(y)
and yt[-6]
and yt[-7]
then
getequivyear = function(y)
return yt[(weekday(makedaynum(y, 0, 1)) + 1) * (isleapyear(y) and -1 or 1)]
getequivyear = function(yy)
return yt[(weekday(makedaynum(yy, 0, 1)) + 1) * (isleapyear(y) and -1 or 1)]
end
return getequivyear(y)
end
@@ -565,7 +565,8 @@ local function date_parse(str)
elseif inlist(x, sl_timezone, 2, sw) then
c = fix(sw[0]) -- ignore gmt and utc
if c ~= 0 then
setz(c, x)
-- setz(c, x) -- wtf
setz(c) -- better
end
elseif not inlist(x, sl_weekdays, 2, sw) then
sw:back()
@@ -668,7 +669,8 @@ local tmap = {
}
local function date_getdobj(v)
local o, r = (tmap[type(v)] or fnil)(v)
return (o and o:normalize() or error("invalid date time value")), r -- if r is true then o is a reference to a date obj
return (o and o:normalize() or error("invalid date time value")), r
-- if r is true then o is a reference to a date obj
end
--#end -- not DATE_OBJECT_AFX
local function date_from(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
@@ -1038,7 +1040,7 @@ local tvspec = {
return fmt("%s%.9f", x >= 10 and "" or "0", x)
end,
-- percent character %
["%%"] = function(self)
["%%"] = function(_)
return "%"
end,
-- Group Spec --

View File

@@ -68,6 +68,7 @@ M.date_from_doy = function(year, doy)
return ret -- unreachable if input values are sane
end
-- the algo on wikipedia seems wrong, so we opt for full-blown luadate
M.isoweek_to_date = function(year, isoweek)
local ret = date(year .. "-W" .. string.format("%02d", isoweek) .. "-1")
return {

View File

@@ -17,6 +17,7 @@ local filetype = require("plenary.filetype")
local taglinks = require("taglinks.taglinks")
local tagutils = require("taglinks.tagutils")
local linkutils = require("taglinks.linkutils")
local dateutils = require("taglinks.dateutils")
local Path = require("plenary.path")
-- declare locals for the nvim api stuff to avoid more lsp warnings
@@ -89,9 +90,9 @@ M.Cfg = {
show_tags_theme = "ivy",
-- template_handling
-- - prefer_home: use new_note template for all new notes created via new_note(),
-- new_templated_note(), and follow_link() to non-existing note
-- - smart: if day or week is detected in title, use daily / weekly
-- What to do when creating a new note via `new_note()` or `follow_link()` to a non-existing note
-- - prefer_new_note: use `new_note` template
-- - smart: if day or week is detected in title, use daily / weekly templates (default)
-- - always_ask: always ask before creating a note
template_handling = "smart",
@@ -107,9 +108,15 @@ M.Cfg = {
--
-- Valid options:
-- - smart: put daily-looking notes in daily, weekly-looking ones in weekly,
-- - default: put all notes in home except for goto_today(), goto_thisweek()
-- - same-as-current: put all new notes in the dir of the current note if
-- present or else in home
-- all other ones in home, except for notes/with/subdirs/in/title.
-- (default)
--
-- - prefer_home: put all notes in home except for goto_today(), goto_thisweek()
-- except for notes/with/subdirs/in/title.
--
-- - same_as_current: put all new notes in the dir of the current note if
-- present or else in home
-- except for notes/with/subdirs/in/title.
new_note_location = "smart",
}
@@ -199,6 +206,7 @@ M.note_type_templates = {
}
local function daysuffix(day)
day = tostring(day)
if (day == "1") or (day == "21") or (day == "31") then
return "st"
end
@@ -393,6 +401,7 @@ local Pinfo = {
is_daily = false,
is_weekly = false,
template = "",
calendar_info = nil,
}
function Pinfo:new(opts)
@@ -434,10 +443,14 @@ function Pinfo:resolve_path(p, opts)
end
if vim.startswith(p, M.Cfg.dailies) then
self.root_dir = M.Cfg.dailies
-- TODO: parse "title" into calendarinfo like in resolve_link
-- not really necessary as the file exists anyway and therefore we don't need to instantiate a template
self.is_daily_or_weekly = true
self.is_daily = true
end
if vim.startswith(p, M.Cfg.weeklies) then
-- TODO: parse "title" into calendarinfo like in resolve_link
-- not really necessary as the file exists anyway and therefore we don't need to instantiate a template
self.root_dir = M.Cfg.weeklies
self.is_daily_or_weekly = true
self.is_weekly = true
@@ -463,7 +476,7 @@ local function check_if_daily_or_weekly(title)
local is_daily = false
local is_weekly = false
local dateinfo = {}
local dateinfo = calculate_dates() -- sane default
local start, _, year, month, day = title:find(daily_match)
if start ~= nil then
@@ -473,7 +486,7 @@ local function check_if_daily_or_weekly(title)
dateinfo.year = tonumber(year)
dateinfo.month = tonumber(month)
dateinfo.day = tonumber(day)
-- TODO: calculate_dates() here
dateinfo = calculate_dates(dateinfo)
end
end
end
@@ -483,8 +496,9 @@ local function check_if_daily_or_weekly(title)
if start ~= nil then
if tonumber(week) < 53 then
is_weekly = true
-- TODO: ISO8601 week -> date calculation
dateinfo.year = tonumber(year)
-- ISO8601 week -> date calculation
dateinfo = dateutils.isoweek_to_date(tonumber(year), tonumber(week))
dateinfo = calculate_dates(dateinfo)
end
end
return is_daily, is_weekly, dateinfo
@@ -508,8 +522,12 @@ function Pinfo:resolve_link(title, opts)
self.is_daily = false
self.is_weekly = false
self.template = nil
self.calendar_info = nil
if opts.weeklies and file_exists(opts.weeklies .. "/" .. self.filename) then
-- TODO: parse "title" into calendarinfo like below
-- not really necessary as the file exists anyway and therefore we don't need to instantiate a template
-- if we still want calendar_info, just move the code for it out of `if self.fexists == false`.
self.filepath = opts.weeklies .. "/" .. self.filename
self.fexists = true
self.root_dir = opts.weeklies
@@ -517,6 +535,9 @@ function Pinfo:resolve_link(title, opts)
self.is_weekly = true
end
if opts.dailies and file_exists(opts.dailies .. "/" .. self.filename) then
-- TODO: parse "title" into calendarinfo like below
-- not really necessary as the file exists anyway and therefore we don't need to instantiate a template
-- if we still want calendar_info, just move the code for it out of `if self.fexists == false`.
self.filepath = opts.dailies .. "/" .. self.filename
self.fexists = true
self.root_dir = opts.dailies
@@ -546,24 +567,41 @@ function Pinfo:resolve_link(title, opts)
-- if we just cannot find the note, check if it's a daily or weekly one
if self.fexists == false then
-- TODO: if we're not smart, we also shouldn't need to try to set the calendar info..?
-- I bet someone will want the info in there, so let's put it in if possible
_, _, self.calendar_info = check_if_daily_or_weekly(self.title) -- will set today as default, so leave in!
if opts.new_note_location == "smart" then
self.filepath = opts.home .. "/" .. self.filename -- default
-- TODO: store the date_info somewhere
self.is_daily, self.is_weekly, _ = check_if_daily_or_weekly(
self.title
)
self.is_daily, self.is_weekly, self.calendar_info =
check_if_daily_or_weekly(
self.title
)
if self.is_daily == true then
self.root_dir = opts.dailies
self.filepath = opts.dailies .. "/" .. self.filename
self.is_daily_or_weekly = true
end
if self.is_weekly == true then
self.root_dir = opts.weeklies
self.filepath = opts.weeklies .. "/" .. self.filename
self.is_daily_or_weekly = true
end
elseif opts.new_note_location == "same_as_current" then
local cwd = vim.fn.expand("%:p")
if #cwd > 0 then
self.root_dir = Path:new(cwd):parent():absolute()
if Path:new(self.root_dir):exists() then
-- check if potential subfolders in filename would end up in a non-existing directory
self.filepath = self.root_dir .. "/" .. self.filename
if not Path:new(self.filepath):parent():exists() then
print("Path " .. self.filepath .. " is invalid!")
-- self.filepath = opts.home .. "/" .. self.filename
end
else
print("Path " .. self.root_dir .. " is invalid!")
-- self.filepath = opts.home .. "/" .. self.filename
end
else
self.filepath = opts.home .. "/" .. self.filename
end
@@ -571,6 +609,15 @@ function Pinfo:resolve_link(title, opts)
-- default fn for creation
self.filepath = opts.home .. "/" .. self.filename
end
-- final round, there still can be a subdir mess-up
if not Path:new(self.filepath):parent():exists() then
print("Path " .. self.filepath .. " is invalid!")
-- local fname_only = Path:new(self.filename):_split()
-- fname_only = fname_only[#fname_only]
-- self.filepath = opts.home .. "/" .. fname_only
self.filepath = ""
end
end
-- now work out subdir relative to root
@@ -582,7 +629,7 @@ function Pinfo:resolve_link(title, opts)
-- now suggest a template based on opts
self.template = M.note_type_templates.normal
if opts.template_handling == "prefer_home" then
if opts.template_handling == "prefer_new_note" then
self.template = M.note_type_templates.normal
elseif opts.template_handling == "always_ask" then
self.template = nil
@@ -1507,7 +1554,12 @@ local function on_create_with_template(opts, title)
-- local template = M.Cfg.templates .. "/" .. action_state.get_selected_entry().value
local template = action_state.get_selected_entry().value
-- TODO: pass in the calendar_info returned from the pinfo
create_note_from_template(title, fname, template)
create_note_from_template(
title,
fname,
template,
pinfo.calendar_info
)
-- open the new note
vim.cmd("e " .. fname)
picker_actions.post_open()
@@ -1554,11 +1606,14 @@ local function on_create(opts, title)
local pinfo = Pinfo:new({ title = title, opts })
local fname = pinfo.filepath
print(vim.inspect(pinfo))
if pinfo.fexists ~= true then
-- TODO: pass in the calendar_info returned in pinfo
create_note_from_template(title, fname, pinfo.template)
create_note_from_template(
title,
fname,
pinfo.template,
pinfo.calendar_info
)
opts.erase = true
opts.erase_file = fname
end
@@ -1689,11 +1744,17 @@ local function FollowLink(opts)
if opts.template_handling == "always_ask" then
return on_create_with_template(opts, title)
end
-- TODO: if daily or weekly: derive date opts from filename!!!
-- pass in the info contained in pinfo
create_note_from_template(title, pinfo.filepath, pinfo.template)
opts.erase = true
opts.erase_file = pinfo.filepath
if #pinfo.filepath > 0 then
create_note_from_template(
title,
pinfo.filepath,
pinfo.template,
pinfo.calendar_info
)
opts.erase = true
opts.erase_file = pinfo.filepath
end
end
find_files_sorted({
@@ -2241,7 +2302,7 @@ local function FindAllTags(opts)
actions.select_default:replace(function()
actions._close(prompt_bufnr, true)
-- TODO actions for insert tag, default action: search for tag
-- actions for insert tag, default action: search for tag
local selection = action_state.get_selected_entry().value.tag
local follow_opts = {
follow_tag = selection,