1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 01:00:06 +08:00

feat(todo): rewrite todomanager using lua

This commit is contained in:
Wang Shidong 2022-10-20 19:55:11 +08:00 committed by GitHub
parent 961b65a6c3
commit fb679af13e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 216 additions and 1 deletions

View File

@ -1,4 +1,4 @@
column_width = 80
column_width = 100
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 2

View File

@ -0,0 +1,215 @@
--=============================================================================
-- todo.lua --- todo manager for SpaceVim
-- Copyright (c) 2016-2022 Wang Shidong & Contributors
-- Author: Wang Shidong < wsdjeg@outlook.com >
-- URL: https://spacevim.org
-- License: GPLv3
--=============================================================================
local M = {}
local sys = require('spacevim.api').import('system')
local reg = require('spacevim.api').import('vim.regex')
local bufnr = -1
local todo_jobid = -1
local todos = {}
local todo = {}
local winnr = -1
-- set the default labels for todo manager.
local labels = { 'fixme', 'question', 'todo', 'idea' }
local prefix = '@'
local grep_default_exe, grep_default_opt, grep_default_ropt, grep_default_expr_opt, grep_default_fix_string_opt, grep_default_ignore_case, grep_default_smart_case =
require('spacevim.plugin.search').default_tool()
local logger = require('spacevim.logger').derive('todo')
local jobstart = vim.fn.jobstart
local labels_partten = ''
local labels_regex = ''
local function empty(d) -- {{{
if type(d) == 'string' then
return d == ''
end
end
-- }}}
local function stderr(id, data, event) -- {{{
if id ~= todo_jobid then
return
end
for _, d in ipairs(data) do
logger.info('stderr: ' .. d)
end
end
-- }}}
local function stdout(id, data, event) -- {{{
if id ~= todo_jobid then
return
end
for _, d in ipairs(data) do
if not empty(d) then
logger.info('stdout:' .. d)
local f = vim.split(d, ':%d+:')[1]
local i, j = string.find(d, ':%d+:')
local line = string.sub(d, i + 1, j - 1)
local column = string.sub(vim.fn.matchstr(d, [[\(:\d\+\)\@<=:\d\+:]]), 1, -2)
local label = vim.fn.matchstr(d, labels_partten)
local title = vim.fn.get(vim.fn.split(d, label), 1, '')
table.insert(todos, {
file = f,
line = line,
column = column,
title = title,
label = label,
})
end
end
end
-- }}}
local function open_todo() -- {{{
local t = todos[vim.fn.line('.')]
close_todo_win()
vim.cmd('e ' .. t.file)
vim.fn.cursor(t.line, t.column)
vim.cmd('noautocmd! normal! :')
end
-- }}}
local function indexof(t, v) -- {{{
for i, x in ipairs(t) do
if x == v then
return i
end
return -1
end
end
-- }}}
local function extend(t1, t2) -- {{{
for _, v in ipairs(t2) do
table.insert(t1, v)
end
end
-- }}}
local function compare_todo(a, b) -- {{{
local i = indexof(labels, a)
local j = indexof(labels, b)
if i < j then
return true
else
return false
end
end
-- }}}
function exit(id, data, event) -- {{{
if id ~= todo_jobid then
return
end
logger.info('todomanager job exit with:' .. data)
table.sort(todos, compare_todo)
local lw = 15
local fw = 50
local lines = {}
for _, v in ipairs(todos) do
table.insert(lines,
v.label .. string.rep(' ', lw - #v.label) .. v.file .. string.rep(' ', fw - #v.file) .. v.title
)
end
local ma = vim.fn.getbufvar(bufnr, '&ma')
vim.fn.setbufvar(bufnr,'&ma', 1)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
vim.fn.setbufvar(bufnr,'&ma', ma)
end
-- }}}
local function get_labels_regex() -- {{{
local sep = ''
if grep_default_exe == 'rg' then
sep = '|'
elseif grep_default_exe == 'grep' then
sep = '\\|'
else
sep = '|'
end
local rst = ''
local i = 1
for _, v in ipairs(labels) do
rst = rst .. prefix .. v .. [[\b]]
if i ~= #labels then
rst = rst .. sep
end
i = i + 1
end
return rst
end
-- }}}
local function get_labels_partten() -- {{{
return reg.parser(get_labels_regex(), false)
end
-- }}}
local function update_todo_content() -- {{{
if vim.g.spacevim_todo_labels ~= nil then
labels = vim.g.spacevim_todo_labels
end
if vim.g.spacevim_todo_prefix ~= nil then
prefix = vim.g.spacevim_todo_prefix
end
todos = {}
labels_regex = get_labels_regex()
labels_partten = get_labels_partten()
local argv = { grep_default_exe }
extend(argv, grep_default_opt)
extend(argv, { labels_regex })
if
sys.isWindows
and (grep_default_exe == 'rg' or grep_default_exe == 'ag' or grep_default_exe == 'pt')
then
extend(argv, { '.' })
elseif sys.isWindows and grep_default_exe == 'findstr' then
extend(argv, { '*.*' })
elseif not sys.isWindows and grep_default_exe == 'rg' then
extend(argv, { '.' })
end
extend(argv, grep_default_ropt)
logger.info('cmd:' .. vim.inspect(argv))
logger.info(' labels_partten: ' .. labels_partten)
todo_jobid = jobstart(argv, {
on_stdout = stdout,
on_stderr = stderr,
on_exit = exit,
})
logger.info('jobid:' .. todo_jobid)
end
-- }}}
local function open_win() -- {{{
if bufnr ~= 0 and vim.fn.bufexists(bufnr) == 1 then
vim.cmd('bd ' .. bufnr)
end
vim.cmd('botright split __todo_manager__')
winnr = vim.fn.winnr('#')
local lines = vim.o.lines * 30 / 100
vim.cmd('resize ' .. lines)
vim.cmd([[
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nospell nonu norelativenumber winfixheight nomodifiable
set filetype=SpaceVimTodoManager
]])
bufnr = vim.fn.bufnr('%')
update_todo_content()
end
-- }}}
function M.list() -- {{{
open_win()
end
-- }}}
return M