aboutsummaryrefslogtreecommitdiff
path: root/config/nvim/lua/brain.lua
blob: 23556c6052224a640a35d6d8305c1edcce9954de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
local brain_home = os.getenv('HOME') .. '/brain'
local templates_path = brain_home .. '/1 periodic/99 templates'

local function load_template(template_name)
  local template_path = brain_home .. templates_path .. '/' .. template_name

  local template_file = io.open(template_path, 'r')
  if not template_file then
      print('Template file not found')
      return
  end
  local content = template_file:read('*a')
  template_file:close()
end

local function open_or_create_from_template(template_name, file)
  local journal_file = io.open(file, 'r')
  if not journal_file then
    local template_contents = load_template(template_name)

    journal_file = io.open(file, 'w')
    journal_file:write(template_contents)
    journal_file:close()
  end
  vim.cmd('edit ' .. file)
end

local function get_this_weeks_files()
  local today = os.time()
  local day_of_week = os.date('*t', today).wday
  local week_start = today - (day_of_week - 2) * 86400
  local filenames = {}

  for i = 0, 6 do
    local date = os.date('*t', week_start + i * 86400)
    table.insert(filenames, string.format('%04d-%02d-%02d.md', date.year, date.month, date.day))
  end

  return filenames
end

-------------------------------------------------------------------------------
-- Periodic Notes
-------------------------------------------------------------------------------

function open_daily_note()
    local filename_format = os.date('%Y-%m-%d')
    local template_name = '001 daily.md'

    local daily_note = brain_home .. '/1 periodic/01 journal/' .. filename_format .. '.md'
    open_or_create_from_template(template_name, daily_note)
end

function open_weekly_note()
    local filename_format = os.date('%Y-w%V')
    local template_name = '002 weekly.md'

    local weekly_note = brain_home .. '/1 periodic/02 weeks/' .. filename_format .. '.md'
    open_or_create_from_template(template_name, weekly_note)
end

-------------------------------------------------------------------------------
-- Task Utilities
-------------------------------------------------------------------------------

function toggle_task()
    local line_num = vim.api.nvim_win_get_cursor(0)[1]
    local line = vim.api.nvim_get_current_line()

    local unchecked_pattern = '^%s*%- %[ %]'
    local checked_pattern = '^%s*%- %[x%]'

    if line:match(unchecked_pattern) then
        line = line:gsub(unchecked_pattern, '- [x]', 1)
    elseif line:match(checked_pattern) then
        line = line:gsub(checked_pattern, '- [ ]', 1)
    end

    vim.api.nvim_buf_set_lines(0, line_num - 1, line_num, false, {line})
end

-------------------------------------------------------------------------------
-- Agenda View
-------------------------------------------------------------------------------

function open_agenda()
  local uv = vim.loop
  local week_filenames = get_this_weeks_files()
  local items = {}
  local pattern = '^%s*%- %[[ ]?x?%]'
  print(week_filenames[1])

  for _, filename in ipairs(week_filenames) do
    local daily_note = brain_home .. '/1 periodic/01 journal/' .. filename
    local stat = uv.fs_stat(daily_note)

    if stat then -- File exists
      local file, err = io.open(daily_note, 'r')
      if file then
        local set_header = 0
        local line_number = 0
        for line in file:lines() do
          line_number = line_number + 1
          if line:match(pattern) then
            if set_header == 0 then
              local header = filename:match('([^/\\]+)$')
              table.insert(items, {filename = '', lnum = 0, text = header})
              set_header = 1
            end
            table.insert(items, {filename = daily_note, text = line, lnum = line_number})
          end
        end
        file:close()
      end
    end
  end
  vim.fn.setloclist(0, {}, ' ', {title = 'Weekly Tasks', items = items})
  vim.cmd('lopen')
end

-------------------------------------------------------------------------------
-- Key Bindings
-------------------------------------------------------------------------------
vim.api.nvim_set_keymap('n', '<leader>od', '<cmd>lua open_daily_note()<CR>', { noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<leader>ow', '<cmd>lua open_weekly_note()<CR>', { noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<leader>oa', '<cmd>lua open_agenda()<CR>', { noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<leader>t', '<cmd>lua toggle_task()<CR>', { noremap = true, silent = true })