X-Git-Url: https://git.r.bdr.sh/rbdr/nota.nvim/blobdiff_plain/2cc29448a37001cf90b22d089ab992e93afdd71f..ca10d2a36e3e7d8d28f15f36f0812384606c238d:/lua/notes.lua?ds=inline diff --git a/lua/notes.lua b/lua/notes.lua index f5a4b00..ca61735 100644 --- a/lua/notes.lua +++ b/lua/notes.lua @@ -9,6 +9,21 @@ local api = vim.api ------------------------------------------------------------------------------- -- 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') @@ -31,45 +46,147 @@ local function open_periodic_note(type, filename) 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) - date = date or os.date('%Y-%m-%d') + if not date or date == '' then + 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')