add files

This commit is contained in:
2026-01-02 11:29:59 +01:00
parent b82be7dec9
commit 9a46317e6c
8 changed files with 734 additions and 0 deletions
+145
View File
@@ -0,0 +1,145 @@
from collections.abc import Callable, Sequence
from pynvim import Nvim, command, plugin
from pynvim.api import Buffer
from .clickup import ClickupSession
from .types import JSONData
from .yaml import load, dump
def usernames_from_objs(objs: JSONData) -> JSONData:
assert isinstance(objs, list)
return [k["username"] for k in objs if isinstance(k, dict)]
@plugin
class MrPyPlugin:
nvim: Nvim
clickup: ClickupSession
frontmatter_keys: dict[str, Callable[[JSONData], JSONData]]
def __init__(self, nvim: Nvim) -> None:
self.nvim = nvim
self.clickup = ClickupSession()
self.frontmatter_keys = {
"id": str,
"name": str,
"assignees": usernames_from_objs,
}
def select_task_id(self) -> None:
tasks = self.clickup.get_tasks()
task_names_by_id = [
{
"idx": tix + 1,
"id": t.id,
"name": t.name,
"status": t.status,
"is_child": bool(t.parent),
"preview": {
"text": f"---\n{dump(t.showables)}---\n{t.markdown_description}",
"ft": "markdown",
},
"action": f":Mrpy {t.id}",
}
for tix, t in enumerate(tasks)
if not t.name.endswith("Absence")
]
self.nvim.exec_lua(
"""require('snacks').picker.pick({
title="Select Task",
format = function(item, _)
local ret = {}
local hl = "SnacksPickerComment"
if item.status == "in progress" then
hl = "@method"
elseif item.status == "selected for development" then
hl = "@constant.builtin"
elseif item.status == "in review" then
hl = "@keyword"
elseif item.status == "done" then
hl = "@variable.builtin"
end
if item.is_child == true then
ret[#ret + 1] = { "󰘍 ", "SnacksPickerComment" }
end
ret[#ret + 1] = { item.name, hl }
ret[#ret + 1] = {
" (#" .. item.id .. ")",
"SnacksPickerComment"
}
return ret
end,
preview="preview",
confirm=function(_, item) vim.cmd(("Mrpy %s"):format(item.id)) end,
items=...
})""",
task_names_by_id,
)
def open_task_buffer(self, task_id: str) -> None:
if " " in task_id:
*_, last = task_id.split(" ")
task_id = last.removeprefix("(#").removesuffix(")")
task = self.clickup.get_task(task_id)
temp_buf: Buffer = self.nvim.api.create_buf(True, False)
self.nvim.api.buf_set_name(temp_buf, f"[ClickUp] {task.name}")
self.nvim.buffers[temp_buf.number].options["filetype"] = "markdown"
self.nvim.api.create_autocmd(
["BufWriteCmd"],
{"buffer": temp_buf.number, "command": "MrpyPush " + str(temp_buf.number)},
)
content = ["---"]
content.extend(
dump(
task.showables,
).splitlines()
)
content.append("---")
content.extend(task.markdown_description.splitlines())
self.nvim.api.buf_set_lines(temp_buf, 0, 0, False, content)
self.nvim.buffers[temp_buf.number].options["modified"] = False
self.nvim.api.win_set_buf(0, temp_buf)
@command("Mrpy", nargs="?")
def entry(self, args: Sequence[str] = ()) -> None:
match args:
case (str() as task_id,):
self.open_task_buffer(task_id)
case ():
self.select_task_id()
case _:
pass
@command("MrpyPush", nargs="?")
def on_vbuf_write(self, args: Sequence[str] = ()) -> None:
match args:
case "0", *_:
return
case buf_no, *_:
buf_no = int(buf_no)
case _:
return
try:
a = self.nvim.buffers[buf_no][0:-1]
_, fm, *text = "\n".join(a).split("---\n")
data = load(fm)
assert isinstance(data, dict)
data["markdown_description"] = "\n\n".join(text)
self.nvim.err_write(str(data) + "\n")
# self.clickup.update(data)
self.nvim.buffers[buf_no].options["modified"] = False
except ValueError:
pass