diff options
| author | nsfisis <nsfisis@gmail.com> | 2021-11-19 15:57:09 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2022-01-29 17:37:40 +0900 |
| commit | f5986deda1ef0edf984b91792e44c72efbeececc (patch) | |
| tree | ca43da3bd58d1349122a6e55ea9eb4b438d0c344 | |
| parent | 52062894a34a57d5c76b86f842befe5fd98a7773 (diff) | |
| download | dotfiles-f5986deda1ef0edf984b91792e44c72efbeececc.tar.gz dotfiles-f5986deda1ef0edf984b91792e44c72efbeececc.tar.zst dotfiles-f5986deda1ef0edf984b91792e44c72efbeececc.zip | |
neovim:leaf: add leaf plugin
| -rw-r--r-- | .config/nvim/after/ftplugin/leaf.lua | 18 | ||||
| -rw-r--r-- | .config/nvim/ftdetect/leaf.vim | 1 | ||||
| -rw-r--r-- | .config/nvim/ftplugin/leaf.vim | 24 | ||||
| -rw-r--r-- | .config/nvim/indent/leaf.vim | 7 | ||||
| -rw-r--r-- | .config/nvim/lua/leaf/calendar.lua | 43 | ||||
| -rw-r--r-- | .config/nvim/lua/leaf/fold.lua | 60 | ||||
| -rw-r--r-- | .config/nvim/lua/leaf/indent.lua | 16 | ||||
| -rw-r--r-- | .config/nvim/lua/leaf/init.lua | 88 | ||||
| -rw-r--r-- | .config/nvim/lua/vimrc.lua | 1 | ||||
| -rw-r--r-- | .config/nvim/plugin/leaf.vim | 23 | ||||
| -rw-r--r-- | .config/nvim/syntax/leaf.vim | 25 |
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' |
