Skip to content

Commit

Permalink
Add few org mappings for changing date.
Browse files Browse the repository at this point in the history
  • Loading branch information
kristijanhusak committed May 26, 2021
1 parent e81650a commit 0e8990f
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 38 deletions.
2 changes: 2 additions & 0 deletions ftplugin/org.vim
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
lua require('orgmode.config'):setup_mappings('org')
inoreabbrev <buffer> :today: <<C-R>=luaeval("require('orgmode.objects.date').today():to_string()")<CR>>
inoreabbrev <buffer> :now: <<C-R>=luaeval("require('orgmode.objects.date').now():to_string()")<CR>>
2 changes: 2 additions & 0 deletions lua/orgmode/config/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ return {
},
org = {
org_capture_refile = '<Leader>or',
org_increase_date = '<C-a>',
org_decrease_date = '<C-x>',
}
}
}
2 changes: 2 additions & 0 deletions lua/orgmode/config/mappings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ return {
},
org = {
org_capture_refile = {'capture.refile_headline_to_destination'},
org_increase_date = {'org_mappings.increase_date'},
org_decrease_date = {'org_mappings.decrease_date'}
}
}
-- org_agenda_goto_date = 'j', -- TODO
Expand Down
58 changes: 58 additions & 0 deletions lua/orgmode/config/org_mappings.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---@class OrgMappings
---@field agenda Agenda
local OrgMappings = {}
local Date = require('orgmode.objects.date')
local utils = require('orgmode.utils')

---@param data table
function OrgMappings:new(data)
local opts = {}
opts.agenda = data.agenda
setmetatable(opts, self)
self.__index = self
return opts
end

function OrgMappings:adjust_date(adjustment, fallback)
local line = vim.fn.getline('.')
local last_col = vim.fn.col('$')
local start = vim.fn.col('.')
local finish = vim.fn.col('.')
while start > 0 do
local c = line:sub(start, start)
if c == '<' or c == '[' then
start = start + 1
break
end
start = start - 1
end

while finish < last_col do
local c = line:sub(finish, finish)
if c == '>' or c == ']' then
finish = finish - 1
break
end
finish = finish + 1
end

if start == 0 or finish == last_col then
return vim.api.nvim_feedkeys(utils.esc(fallback), 'n', true)
end
local selection = line:sub(start, finish)
if not Date.is_valid_date(selection) then return end
local date = Date.from_string(selection):adjust(adjustment):to_string()
local view = vim.fn.winsaveview()
vim.fn.setline(vim.fn.line('.'), string.format('%s%s%s', line:sub(1, start - 1), date, line:sub(finish + 1)))
vim.fn.winrestview(view)
end

function OrgMappings:increase_date()
return self:adjust_date('+1d', '<C-a>')
end

function OrgMappings:decrease_date()
return self:adjust_date('-1d','<C-x>')
end

return OrgMappings
3 changes: 3 additions & 0 deletions lua/orgmode/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ _G.org = _G.org or {}
local Config = require('orgmode.config')
local Agenda = require('orgmode.agenda')
local Capture = require('orgmode.capture')
local OrgMappings = require('orgmode.config.org_mappings')
local instance = nil

---@class Org
Expand All @@ -22,6 +23,7 @@ function Org:init()
if self.initialized then return end
self.agenda = Agenda:new()
self.capture = Capture:new({ agenda = self.agenda })
self.org_mappings = OrgMappings:new({ agenda = self.agenda })
self.initialized = true
end

Expand All @@ -36,6 +38,7 @@ function Org:setup_autocmds()
vim.cmd[[augroup orgmode_nvim]]
vim.cmd[[autocmd!]]
vim.cmd[[autocmd BufWritePost *.org call luaeval('require("orgmode").reload(_A)', expand('<afile>:p'))]]
vim.cmd[[autocmd FileType org call luaeval('require("orgmode").reload(_A)', expand('<afile>:p'))]]
vim.cmd[[augroup END]]
end

Expand Down
10 changes: 7 additions & 3 deletions lua/orgmode/objects/date.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ function Date:new(data)
opts.timestamp = os.time()
local date = os.date('*t', opts.timestamp)
opts = set_date_opts(date, opts)
opts.dayname = os.date('%a', opts.timestamp)
end
opts.date_only = date_only
opts.dayname = opts.dayname or data.dayname
opts.dayname = os.date('%a', opts.timestamp)
opts.adjustments = data.adjustments or {}
setmetatable(opts, self)
self.__index = self
Expand Down Expand Up @@ -137,11 +136,15 @@ local function parse_date(date, dayname, adjustments, data)
return Date:new(opts)
end

local function is_valid_date(datestr)
return datestr:match('^%d%d%d%d%-%d%d%-%d%d%s+') or datestr:match('^%d%d%d%d%-%d%d%-%d%d$')
end

---@param datestr string
---@param opts table
---@return Date
local function from_string(datestr, opts)
if not datestr:match('^%d%d%d%d%-%d%d%-%d%d$') and not datestr:match('^%d%d%d%d%-%d%d%-%d%d%s+') then
if not is_valid_date(datestr) then
return Date:new(opts)
end
local parts = vim.split(datestr, '%s+')
Expand Down Expand Up @@ -607,6 +610,7 @@ return {
now = now,
today = today,
parse_all_from_line = parse_all_from_line,
is_valid_date = is_valid_date,
from_match = from_match,
pattern = pattern
}
4 changes: 4 additions & 0 deletions lua/orgmode/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,8 @@ function utils.buf_keymap(buf, mode, lhs, rhs, opts)
}))
end

function utils.esc(cmd)
return vim.api.nvim_replace_termcodes(cmd, true, false, true)
end

return utils
2 changes: 2 additions & 0 deletions syntax/orgagenda.vim
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
lua require('orgmode.agenda.highlights').define_agenda_colors()
syn match OrgAgendaDay /^\w\+\s\d\+\s\w\+\s\d\d\d\d$/
syn match OrgAgendaTags /:[^\s]*:$/
hi OrgBold gui=bold
hi default link OrgAgendaDay Statement
hi default link OrgAgendaTags OrgBold
70 changes: 35 additions & 35 deletions tests/plenary/object/date_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ describe('Date object', function()
assert.are.same(10, result.day)
assert.are.same(0, result.hour)
assert.are.same(0, result.min)
assert.is.Nil(result.dayname)
assert.are.same('Thu', result.dayname)
assert.are.same(true, result.date_only)
assert.are.same(1623276000, result.timestamp)
assert.are.same(date, result:to_string())
assert.are.same('2021-06-10 Thu', result:to_string())
assert.are.same({}, result.adjustments)

local date_with_dayname = '2021-06-10 Thu'
Expand All @@ -39,7 +39,7 @@ describe('Date object', function()
assert.are.same(0, result.min)
assert.are.same(false, result.date_only)
assert.are.same(1625468400, result.timestamp)
assert.are.same(date, result:to_string())
assert.are.same('2021-07-05 Mon 09:00', result:to_string())
assert.are.same({}, result.adjustments)

local date_with_dayname = '2021-07-05 Mon 09:00'
Expand Down Expand Up @@ -133,10 +133,10 @@ describe('Date object', function()
assert.are.same(10, result.day)
assert.are.same(0, result.hour)
assert.are.same(0, result.min)
assert.is.Nil(result.dayname)
assert.are.same('Thu', result.dayname)
assert.are.same(true, result.date_only)
assert.are.same(1623276000, result.timestamp)
assert.are.same(date, result:to_string())
assert.are.same('2021-06-10 Thu', result:to_string())
assert.are.same({}, result.adjustments)

result = result:adjust('+1d')
Expand All @@ -145,10 +145,10 @@ describe('Date object', function()
assert.are.same(11, result.day)
assert.are.same(0, result.hour)
assert.are.same(0, result.min)
assert.is.Nil(result.dayname)
assert.are.same('Fri', result.dayname)
assert.are.same(true, result.date_only)
assert.are.same(1623362400, result.timestamp)
assert.are.same('2021-06-11', result:to_string())
assert.are.same('2021-06-11 Fri', result:to_string())
assert.are.same({}, result.adjustments)

result = result:adjust('+3m')
Expand All @@ -157,10 +157,10 @@ describe('Date object', function()
assert.are.same(11, result.day)
assert.are.same(0, result.hour)
assert.are.same(0, result.min)
assert.is.Nil(result.dayname)
assert.are.same('Sat', result.dayname)
assert.are.same(true, result.date_only)
assert.are.same(1631311200, result.timestamp)
assert.are.same('2021-09-11', result:to_string())
assert.are.same('2021-09-11 Sat', result:to_string())
assert.are.same({}, result.adjustments)

result = result:adjust('-1w')
Expand All @@ -169,10 +169,10 @@ describe('Date object', function()
assert.are.same(4, result.day)
assert.are.same(0, result.hour)
assert.are.same(0, result.min)
assert.is.Nil(result.dayname)
assert.are.same('Sat', result.dayname)
assert.are.same(true, result.date_only)
assert.are.same(1630706400, result.timestamp)
assert.are.same('2021-09-04', result:to_string())
assert.are.same('2021-09-04 Sat', result:to_string())
assert.are.same({}, result.adjustments)

result = result:adjust('+2y')
Expand All @@ -181,10 +181,10 @@ describe('Date object', function()
assert.are.same(4, result.day)
assert.are.same(0, result.hour)
assert.are.same(0, result.min)
assert.is.Nil(result.dayname)
assert.are.same('Mon', result.dayname)
assert.are.same(true, result.date_only)
assert.are.same(1693778400, result.timestamp)
assert.are.same('2023-09-04', result:to_string())
assert.are.same('2023-09-04 Mon', result:to_string())
assert.are.same({}, result.adjustments)

result = result:adjust('+2')
Expand All @@ -193,10 +193,10 @@ describe('Date object', function()
assert.are.same(6, result.day)
assert.are.same(0, result.hour)
assert.are.same(0, result.min)
assert.is.Nil(result.dayname)
assert.are.same('Wed', result.dayname)
assert.are.same(true, result.date_only)
assert.are.same(1693951200, result.timestamp)
assert.are.same('2023-09-06', result:to_string())
assert.are.same('2023-09-06 Wed', result:to_string())
assert.are.same({}, result.adjustments)
end)

Expand Down Expand Up @@ -272,49 +272,49 @@ describe('Date object', function()
it('should get start of specific range', function()
local date = Date.from_string('2021-05-12 10:30')
date = date:start_of('day')
assert.are.same('2021-05-12 00:00', date:to_string())
assert.are.same('2021-05-12 Wed 00:00', date:to_string())
date = date:start_of('week')
assert.are.same('2021-05-10 00:00', date:to_string())
assert.are.same('2021-05-10 Mon 00:00', date:to_string())
date = date:start_of('month')
assert.are.same('2021-05-01 00:00', date:to_string())
assert.are.same('2021-05-01 Sat 00:00', date:to_string())
date = date:start_of('year')
assert.are.same('2021-01-01 00:00', date:to_string())
assert.are.same('2021-01-01 Fri 00:00', date:to_string())
date = Date.from_string('2021-05-12 10:30')
date = date:start_of('month')
assert.are.same('2021-05-01 00:00', date:to_string())
assert.are.same('2021-05-01 Sat 00:00', date:to_string())
end)

it('should get end of specific range', function()
local date = Date.from_string('2021-05-12 09:00')
date = date:end_of('day')
assert.are.same('2021-05-12 23:59', date:to_string())
assert.are.same('2021-05-12 Wed 23:59', date:to_string())
date = date:end_of('week')
assert.are.same('2021-05-16 23:59', date:to_string())
assert.are.same('2021-05-16 Sun 23:59', date:to_string())
date = date:end_of('month')
assert.are.same('2021-05-31 23:59', date:to_string())
assert.are.same('2021-05-31 Mon 23:59', date:to_string())
date = date:end_of('year')
assert.are.same('2021-12-31 23:59', date:to_string())
assert.are.same('2021-12-31 Fri 23:59', date:to_string())
date = Date.from_string('2021-05-12 09:00')
date = date:end_of('month')
assert.are.same('2021-05-31 23:59', date:to_string())
assert.are.same('2021-05-31 Mon 23:59', date:to_string())
end)

it('should add/subtract/set date', function()
local date = Date.from_string('2021-05-12 14:00')
date = date:add({ week = 2 })
assert.are.same('2021-05-26 14:00', date:to_string())
assert.are.same('2021-05-26 Wed 14:00', date:to_string())
date = date:add({ month = 2 })
assert.are.same('2021-07-26 14:00', date:to_string())
assert.are.same('2021-07-26 Mon 14:00', date:to_string())
date = date:add({ year = 1 })
assert.are.same('2022-07-26 14:00', date:to_string())
assert.are.same('2022-07-26 Tue 14:00', date:to_string())
date = date:subtract({ hour = 1 })
assert.are.same('2022-07-26 13:00', date:to_string())
assert.are.same('2022-07-26 Tue 13:00', date:to_string())
date = date:subtract({ min = 30 })
assert.are.same('2022-07-26 12:30', date:to_string())
assert.are.same('2022-07-26 Tue 12:30', date:to_string())
date = date:subtract({ month = 4 })
assert.are.same('2022-03-26 12:30', date:to_string())
assert.are.same('2022-03-26 Sat 12:30', date:to_string())
date = date:subtract({ year = 2 })
assert.are.same('2020-03-26 12:30', date:to_string())
assert.are.same('2020-03-26 Thu 12:30', date:to_string())
end)

it('should compare dates', function()
Expand Down Expand Up @@ -503,13 +503,13 @@ describe('Date object', function()

monday = monday:set_isoweekday(1)
assert.are.same(1, monday:get_isoweekday())
assert.are.same('2021-05-17', monday:to_string())
assert.are.same('2021-05-17 Mon', monday:to_string())
local thursday = monday:set_isoweekday(4, true)
assert.are.same(4, thursday:get_isoweekday())
assert.are.same('2021-05-20', thursday:to_string())
assert.are.same('2021-05-20 Thu', thursday:to_string())
local previous_saturday = monday:set_isoweekday(6)
assert.are.same(6, previous_saturday:get_isoweekday())
assert.are.same('2021-05-15', previous_saturday:to_string())
assert.are.same('2021-05-15 Sat', previous_saturday:to_string())
end)

it('should handle repeater', function()
Expand Down

0 comments on commit 0e8990f

Please sign in to comment.