aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.config/nvim/after/ftplugin/leaf.lua18
-rw-r--r--.config/nvim/ftdetect/leaf.vim1
-rw-r--r--.config/nvim/ftplugin/leaf.vim24
-rw-r--r--.config/nvim/indent/leaf.vim7
-rw-r--r--.config/nvim/lua/leaf/calendar.lua43
-rw-r--r--.config/nvim/lua/leaf/fold.lua60
-rw-r--r--.config/nvim/lua/leaf/indent.lua16
-rw-r--r--.config/nvim/lua/leaf/init.lua88
-rw-r--r--.config/nvim/lua/vimrc.lua1
-rw-r--r--.config/nvim/plugin/leaf.vim23
-rw-r--r--.config/nvim/syntax/leaf.vim25
11 files changed, 306 insertions, 0 deletions
diff --git a/.config/nvim/after/ftplugin/leaf.lua b/.config/nvim/after/ftplugin/leaf.lua
new file mode 100644
index 0000000..bf3e9b7
--- /dev/null
+++ b/.config/nvim/after/ftplugin/leaf.lua
@@ -0,0 +1,18 @@
+vimrc.after_ftplugin('leaf', function(conf)
+ vim.wo.foldlevel = 1
+
+ vim.b.caw_oneline_comment = '#'
+
+ if vim.fn.exists(':AutosaveEnable') == 2 then
+ vim.cmd('AutosaveEnable')
+ end
+
+ vim.cmd([=[
+ nmap <buffer> ,t <Plug>(leaf-switch-task-status-to-todo)
+ nmap <buffer> ,T <Plug>(leaf-switch-task-status-to-todo-rec)
+ nmap <buffer> ,d <Plug>(leaf-switch-task-status-to-done)
+ nmap <buffer> ,D <Plug>(leaf-switch-task-status-to-done-rec)
+ nmap <buffer> ,c <Plug>(leaf-switch-task-status-to-canceled)
+ nmap <buffer> ,C <Plug>(leaf-switch-task-status-to-canceled-rec)
+ ]=])
+end)
diff --git a/.config/nvim/ftdetect/leaf.vim b/.config/nvim/ftdetect/leaf.vim
new file mode 100644
index 0000000..e38e202
--- /dev/null
+++ b/.config/nvim/ftdetect/leaf.vim
@@ -0,0 +1 @@
+autocmd BufRead,BufNewFile *.leaf set filetype=leaf
diff --git a/.config/nvim/ftplugin/leaf.vim b/.config/nvim/ftplugin/leaf.vim
new file mode 100644
index 0000000..c25a462
--- /dev/null
+++ b/.config/nvim/ftplugin/leaf.vim
@@ -0,0 +1,24 @@
+scriptencoding utf-8
+
+if exists('b:did_ftplugin_leaf')
+ finish
+endif
+
+
+inoremap <buffer> <expr> <Space> v:lua.require'leaf'.checkbox(v:false, ' ')
+inoremap <buffer> <expr> x v:lua.require'leaf'.checkbox(v:true, 'x')
+
+nnoremap <buffer> <Plug>(leaf-switch-task-status-to-todo) <Cmd>lua require'leaf'.switch_task_status(' ')<CR>
+nnoremap <buffer> <Plug>(leaf-switch-task-status-to-todo-rec) <Cmd>lua require'leaf'.switch_task_status_rec(' ')<CR>
+nnoremap <buffer> <Plug>(leaf-switch-task-status-to-done) <Cmd>lua require'leaf'.switch_task_status('x')<CR>
+nnoremap <buffer> <Plug>(leaf-switch-task-status-to-done-rec) <Cmd>lua require'leaf'.switch_task_status_rec('x')<CR>
+nnoremap <buffer> <Plug>(leaf-switch-task-status-to-canceled) <Cmd>lua require'leaf'.switch_task_status('-')<CR>
+nnoremap <buffer> <Plug>(leaf-switch-task-status-to-canceled-rec) <Cmd>lua require'leaf'.switch_task_status_rec('-')<CR>
+
+
+setlocal foldmethod=expr
+setlocal foldexpr=v:lua.require'leaf.fold'.foldexpr()
+setlocal foldtext=v:lua.require'leaf.fold'.foldtext()
+
+
+let b:did_ftplugin_leaf = 1
diff --git a/.config/nvim/indent/leaf.vim b/.config/nvim/indent/leaf.vim
new file mode 100644
index 0000000..b76dedd
--- /dev/null
+++ b/.config/nvim/indent/leaf.vim
@@ -0,0 +1,7 @@
+if exists('b:did_indent')
+ finish
+endif
+
+setlocal indentexpr=v:lua.require'leaf.indent'.indentexpr()
+
+let b:did_indent = 1
diff --git a/.config/nvim/lua/leaf/calendar.lua b/.config/nvim/lua/leaf/calendar.lua
new file mode 100644
index 0000000..f998785
--- /dev/null
+++ b/.config/nvim/lua/leaf/calendar.lua
@@ -0,0 +1,43 @@
+local M = {}
+
+
+local floor = math.floor
+
+
+M.MON = 1
+M.TUE = 2
+M.WED = 3
+M.THU = 4
+M.FRI = 5
+M.SAT = 6
+M.SUN = 7
+
+
+function M.calc_week_of_day(y, m, d)
+ -- Zeller's congruence
+ if m == 1 or m == 2 then
+ m = m + 12
+ y = y - 1
+ end
+ local C = floor(y / 100)
+ local Y = y % 100
+ local G = 5*C + floor(C/4)
+ return 1 + (d + floor(26 * (m+1) / 10) + Y + floor(Y/4) + G + 5) % 7
+end
+
+
+function M.translate_week_of_day(w, locale)
+ -- assert(locale == 'ja_JP')
+ return ({
+ [M.MON] = '月',
+ [M.TUE] = '火',
+ [M.WED] = '水',
+ [M.THU] = '木',
+ [M.FRI] = '金',
+ [M.SAT] = '土',
+ [M.SUN] = '日',
+ })[w]
+end
+
+
+return M
diff --git a/.config/nvim/lua/leaf/fold.lua b/.config/nvim/lua/leaf/fold.lua
new file mode 100644
index 0000000..6f8a0b5
--- /dev/null
+++ b/.config/nvim/lua/leaf/fold.lua
@@ -0,0 +1,60 @@
+local M = {}
+
+
+local F = vim.fn
+local V = vim.v
+
+
+local function find_plain_string(haystack, needle, start)
+ return haystack:find(needle, start or 1, true)
+end
+
+
+function M.foldexpr()
+ local current_line_indent = F.indent(V.lnum)
+ local task_level = math.floor(current_line_indent / F.shiftwidth())
+ if V.lnum == F.line('$') then
+ return task_level
+ end
+ local next_line_indent = F.indent(V.lnum + 1)
+ if current_line_indent < next_line_indent then
+ return ('>%d'):format(task_level + 1)
+ else
+ return task_level
+ end
+end
+
+
+function M.foldtext()
+ local foldstart = V.foldstart
+ local foldend = V.foldend
+ local shiftwidth = F.shiftwidth()
+ local current_line_indent = F.indent(foldstart)
+
+ local todo = 0
+ local done = 0
+ for i = foldstart + 1, foldend do
+ local line = F.getline(i)
+ local line_indent = F.indent(i)
+ if line_indent == current_line_indent + shiftwidth then
+ if find_plain_string(line, '[x] ') then
+ done = done + 1
+ elseif find_plain_string(line, '[ ] ') then
+ todo = todo + 1
+ elseif find_plain_string(line, '[-] ') then
+ done = done + 1
+ end
+ end
+ end
+
+ local progress
+ if done + todo == 0 then
+ progress = '...'
+ else
+ progress = (' [%d/%d]'):format(done, done + todo)
+ end
+ return F.getline(foldstart) .. progress
+end
+
+
+return M
diff --git a/.config/nvim/lua/leaf/indent.lua b/.config/nvim/lua/leaf/indent.lua
new file mode 100644
index 0000000..d1df34a
--- /dev/null
+++ b/.config/nvim/lua/leaf/indent.lua
@@ -0,0 +1,16 @@
+local M = {}
+
+local F = vim.fn
+local V = vim.v
+
+
+function M.indentexpr()
+ local lnum = V.lnum
+ if lnum == 0 then
+ return 0
+ end
+ return F.indent(lnum - 1)
+end
+
+
+return M
diff --git a/.config/nvim/lua/leaf/init.lua b/.config/nvim/lua/leaf/init.lua
new file mode 100644
index 0000000..c389ffd
--- /dev/null
+++ b/.config/nvim/lua/leaf/init.lua
@@ -0,0 +1,88 @@
+local M = {}
+
+
+local A = vim.api
+local F = vim.fn
+
+local TASK_STATUS_PATTERN = [=[\[[ x-]\] ]=]
+local TASK_STATUS_PATTERN_EXCEPT_DONE = [=[\[[ -]\] ]=]
+local TASK_STATUS_PATTERN_EXCEPT_CANCELED = [=[\[[ x]\] ]=]
+-- op = T
+-- T => T
+-- D => T
+-- C => T
+-- op = D
+-- T => D
+-- D => D
+-- C => C
+-- op = C
+-- T => C
+-- D => D
+-- C => C
+
+
+local function vim_match(s, pattern)
+ return vim.regex(pattern):match_str(s)
+end
+
+local function switch_task_status_internal(line_num, op, is_subtask)
+ local line = F.getline(line_num)
+ local pattern
+ if is_subtask then
+ if op == ' ' then
+ pattern = TASK_STATUS_PATTERN
+ elseif op == 'x' then
+ pattern = TASK_STATUS_PATTERN_EXCEPT_CANCELED
+ elseif op == '-' then
+ pattern = TASK_STATUS_PATTERN_EXCEPT_DONE
+ else
+ assert('unexpected op: ' .. tostring(op))
+ end
+ else
+ pattern = TASK_STATUS_PATTERN
+ end
+ if vim_match(line, pattern) then
+ local replacement = ('[%s] '):format(op)
+ F.setline(line_num, F.substitute(line, pattern, replacement, ''))
+ return true
+ else
+ return false
+ end
+end
+
+
+function M.checkbox(check, char)
+ local line = F.getline('.')
+ if vim_match(line, [[^\s*$]]) and #line % F.shiftwidth() == 0 then
+ return check and '[x] ' or '[ ] '
+ else
+ return char
+ end
+end
+
+function M.switch_task_status(op)
+ switch_task_status_internal(F.line('.'), op)
+end
+
+function M.switch_task_status_rec(op)
+ local current_line_num = F.line('.')
+ local replaced = switch_task_status_internal(current_line_num, op)
+ if not replaced then
+ return
+ end
+ local last_line_num = F.line('$')
+ if current_line_num == last_line_num then
+ return
+ end
+
+ local base_indent_level = F.indent('.')
+ for l = current_line_num + 1, last_line_num do
+ if F.indent(l) <= base_indent_level then
+ break
+ end
+ switch_task_status_internal(l, op, true)
+ end
+end
+
+
+return M
diff --git a/.config/nvim/lua/vimrc.lua b/.config/nvim/lua/vimrc.lua
index b7e21fd..2ad6fd6 100644
--- a/.config/nvim/lua/vimrc.lua
+++ b/.config/nvim/lua/vimrc.lua
@@ -42,6 +42,7 @@ function M.register_filetype_autocmds_for_indentation()
html = { style = SPACE, width = 2 },
javascript = { style = SPACE, width = 2 },
json = { style = SPACE, width = 2 },
+ leaf = { style = SPACE, width = 4 },
lisp = { style = SPACE, width = 2 },
lua = { style = SPACE, width = 3 },
markdown = { style = SPACE, width = 4 },
diff --git a/.config/nvim/plugin/leaf.vim b/.config/nvim/plugin/leaf.vim
new file mode 100644
index 0000000..e4826b3
--- /dev/null
+++ b/.config/nvim/plugin/leaf.vim
@@ -0,0 +1,23 @@
+scriptencoding utf-8
+
+if exists('g:loaded_leaf')
+ finish
+endif
+
+
+nmap <Space> <Nop>
+nmap <Space>l (leaf)
+nnoremap (leaf) <Nop>
+
+nnoremap (leaf)i <Cmd>tabedit ~/leaves/INBOX.leaf<CR>
+nnoremap (leaf)t <Cmd>tabedit ~/leaves/TODO.leaf<CR>
+nnoremap (leaf)c <Cmd>tabedit ~/leaves/CALENDAR.leaf<CR>
+nnoremap (leaf)p <Cmd>tabedit ~/leaves/PROJECTS.leaf<CR>
+nnoremap (leaf)s <Cmd>tabedit ~/leaves/SOMEDAY.leaf<CR>
+nnoremap (leaf)r <Cmd>tabedit ~/leaves/REFS.leaf<CR>
+nnoremap (leaf)A <Cmd>tabedit ~/leaves/ARCHIVES.leaf<CR>
+
+nnoremap (leaf)l <Cmd>tabedit ~/leaves/INBOX.leaf <Bar>normal G<CR>
+
+
+let g:loaded_leaf = 1
diff --git a/.config/nvim/syntax/leaf.vim b/.config/nvim/syntax/leaf.vim
new file mode 100644
index 0000000..d8112fd
--- /dev/null
+++ b/.config/nvim/syntax/leaf.vim
@@ -0,0 +1,25 @@
+scriptencoding utf-8
+
+if exists('b:current_syntax')
+ finish
+endif
+
+
+syn match leafCheckboxTodo /\[ \]/
+syn match leafCheckboxDone /\[x\]/
+syn match leafCheckboxCanceled /\[-\]/
+syn region leafComment start="# " end="$"
+syn match leafTimestamp /<\d\d\d\d-\d\d-\d\d\%( [月火水木金土日]\)\?\%( \d\d:\d\d\)\?>/
+syn match leafTimestamp /<\d\d\d\d-\d\d-\d\d\%( [月火水木金土日]\)\?\%( \d\d:\d\d\)\?>--<\d\d\d\d-\d\d-\d\d\%( [月火水木金土日]\)\?\%( \d\d:\d\d\)\?>/
+syn match leafTag /@\w\+/
+
+
+hi default link leafCheckboxTodo Special
+hi default link leafCheckboxDone Comment
+hi default link leafCheckboxCanceled Comment
+hi default link leafComment Comment
+hi default link leafTimestamp Identifier
+hi default link leafTag String
+
+
+let b:current_syntax = 'leaf'