-------------------------------------------------------------------------------
-- Internal Functions
-------------------------------------------------------------------------------
+local templates = {
+ daily = '%Y-%m-%d',
+ weekly = '%Y-w%V',
+ monthly = '%Y-%m',
+ yearly = '%Y'
+}
+
+local patterns = {
+ daily = '^(%d+)-(%d+)-(%d+).md$',
+ weekly = '^(%d+)-w(%d+).md$',
+ monthly = '^(%d+)-(%d+).md$',
+ seasonal = '^(%d+)-s(%d+).md$',
+ yearly = '^(%d+).md$'
+}
+
local function open_or_create_from_template(type, file_path)
local journal_file = io.open(file_path, 'r')
open_or_create_from_template(type, file_path)
end
+local function find_next(type, filename, go_back_in_time)
+ local multiplier = 1
+ if go_back_in_time then
+ multiplier = -1
+ end
+
+ local pattern = patterns[type]
+ local year, second_match, day = filename:match(pattern)
+ year = tonumber(year)
+
+ -- Depending on context, second_match is either month, week, or season.
+ if second_match then
+ second_match = tonumber(second_match)
+ end
+
+ if day then
+ day = tonumber(day)
+ end
+
+ local next = nil
+
+ if type == 'daily' and year and second_match and day then
+ next = os.date(templates.daily, os.time({
+ year = year,
+ month = second_match,
+ day = day
+ }) + multiplier * 24 * 60 * 60)
+ elseif type == 'weekly' and year and second_match then
+ -- According to ISO, the first week is the one that contains january 4
+ local first_day_of_the_week = os.time({year = year, month = 1, day = 4})
+ if multiplier < 0 then
+ second_match = second_match - 2
+ end
+ next = os.date(templates.weekly, first_day_of_the_week + second_match * 7 * 24 * 60 * 60)
+ elseif type == 'monthly' and year and second_match then
+ next = os.date(templates.monthly, os.time({
+ year = year,
+ month = second_match + multiplier,
+ day = 1
+ }))
+ elseif type == 'seasonal' and year and second_match then
+ if multiplier > 0 and second_match == 4 then
+ year = year + 1
+ end
+ if multiplier < 0 and second_match == 1 then
+ year = year - 1
+ end
+ if multiplier > 0 then
+ second_match = (second_match % 4) + 1
+ else
+ second_match = (second_match + 2) % 4 + 1
+ end
+ next = year .. '-s' .. second_match
+ elseif type == 'yearly' and year then
+ next = os.date(templates.yearly, os.time({
+ year = year + multiplier,
+ month = 1,
+ day = 1
+ }))
+ end
+
+ if next then
+ Notes['open_' .. type](next)
+ end
+end
+
-------------------------------------------------------------------------------
-- Public Interface
-------------------------------------------------------------------------------
--- Opens the daily note
function Notes.open_daily(date)
if not date or date == '' then
- date = os.date('%Y-%m-%d')
+ date = os.date(templates.daily)
end
local filename = date .. '.md'
open_periodic_note('daily', filename)
end
--- Opens the weekly note
-function Notes.open_weekly()
- local filename = os.date('%Y-w%V')
+function Notes.open_weekly(date)
+ if not date or date == '' then
+ date = os.date(templates.weekly)
+ end
+ local filename = date .. '.md'
open_periodic_note('weekly', filename)
end
--- Opens the monthly note
-function Notes.open_monthly()
- local filename = os.date('%Y-%m') .. '.md'
+function Notes.open_monthly(date)
+ if not date or date == '' then
+ date = os.date(templates.monthly)
+ end
+ local filename = date .. '.md'
open_periodic_note('monthly', filename)
end
--- Opens the seasonal note
-function Notes.open_seasonal()
- local year = os.date('%Y')
- local month = tonumber(os.date('%m'))
- local season = math.ceil(month / 3)
+function Notes.open_seasonal(date)
+ if not date or date == '' then
+ local year = os.date('%Y')
+ local month = tonumber(os.date('%m'))
+ local season = math.ceil(month / 3)
+ date = year .. '-s' .. season
+ end
- local filename = year .. '-s' .. season .. '.md'
+ local filename = date .. '.md'
open_periodic_note('seasonal', filename)
end
--- Opens the yearly note
-function Notes.open_yearly()
- local filename = os.date('%Y') .. '.md'
+function Notes.open_yearly(date)
+ if not date or date == '' then
+ date = os.date(templates.yearly)
+ end
+ local filename = date .. '.md'
open_periodic_note('yearly', filename)
end
+--- Opens the next note
+function Notes.open_next()
+ local filename = vim.fn.expand('%:t')
+ for type, pattern in pairs(patterns) do
+ if filename:match(pattern) ~= nil then
+ return find_next(type, filename)
+ end
+ end
+ api.nvim_err_writeln('Opening next only works on periodic notes.')
+end
+
+--- Opens the previous note
+function Notes.open_previous()
+ local filename = vim.fn.expand('%:t')
+ for type, pattern in pairs(patterns) do
+ if filename:match(pattern) ~= nil then
+ return find_next(type, filename, true)
+ end
+ end
+ api.nvim_err_writeln('Opening previous only works on periodic notes.')
+end
+
--- Opens an arbitrary note
function Notes.open()
local success, module = pcall(require, 'fzf-lua')