From e18ec8007184207be9d3f8d967412fa9d1824457 Mon Sep 17 00:00:00 2001 From: MasouShizuka Date: Wed, 15 May 2024 10:49:06 +0800 Subject: [PATCH] feat: add feature of merging a project to other projects --- README.md | 22 +++++++++++++-- init.lua | 81 +++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 93 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index fc43400..3d6255a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # projects.yazi -A [Yazi](https://github.com/sxyazi/yazi) plugin that adds the functionality to save and load projects. +A [Yazi](https://github.com/sxyazi/yazi) plugin that adds the functionality to save, load and merge projects. A project means all `tabs` and their status, including `cwd` and so on. > [!NOTE] @@ -13,6 +13,7 @@ https://github.com/MasouShizuka/projects.yazi/assets/44764707/79c3559a-7776-48cd - Save/load projects - Load last project - Projects persistence + - Merge a project or its current tab to other projects ## Installation @@ -53,6 +54,16 @@ desc = "Delete project" on = [ "P", "D" ] run = "plugin projects --args=delete_all" desc = "Delete all projects" + +[[manager.prepend_keymap]] +on = [ "P", "m" ] +run = "plugin projects --args='merge current'" +desc = "Merge current tab to other projects" + +[[manager.prepend_keymap]] +on = [ "P", "M" ] +run = "plugin projects --args='merge all'" +desc = "Merge current project to other projects" ``` If you want to save the last project when exiting, map the default `quit` key to: @@ -75,6 +86,9 @@ require("projects"):setup({ update_after_save = true, update_after_load = true, }, + merge = { + quit_after_merge = false, + }, notify = { enable = true, title = "Projects", @@ -91,8 +105,12 @@ The last project is loaded by `load_last` command. When `update_after_save` enabled, the saved project will be saved to last project. When `update_after_load` enabled, the loaded project will be saved to last project. +### `merge` + +When `quit_after_merge` enabled, the merged project will be exited after merging. + ### `notify` -When enabled, notifications will be shown when the user saves/loads/deletes a project and deletes all projects. +When enabled, notifications will be shown when the user saves/loads/deletes/merges a project and deletes all projects. `title`, `timeout`, `level` are the same as [ya.notify](https://yazi-rs.github.io/docs/plugins/utils/#ya.notify). diff --git a/init.lua b/init.lua index 74c589d..7005804 100644 --- a/init.lua +++ b/init.lua @@ -144,12 +144,12 @@ local _get_default_projects = ya.sync(function(state) } end) -local _save_state = ya.sync(function(state, projects) +local _save_projects = ya.sync(function(state, projects) state.projects = projects ps.pub_static(10, "projects", projects) end) -local _load_state = ya.sync(function(state) +local _load_projects = ya.sync(function(state) ps.sub_remote("projects", function(body) if not state.projects and body then state.projects = _get_default_projects() @@ -215,7 +215,7 @@ local save_project = ya.sync(function(state, idx, desc) projects.last = project end - _save_state(projects) + _save_projects(projects) if state.notify.enable then local message = string.format("Project saved to %s", state.projects.list[real_idx].on) @@ -244,7 +244,7 @@ local load_project = ya.sync(function(state, project, desc) if state.last.update_after_load then local projects = _get_projects() projects.last = project - _save_state(projects) + _save_projects(projects) end if state.notify.enable then @@ -259,7 +259,7 @@ local load_project = ya.sync(function(state, project, desc) end) local delete_all_projects = ya.sync(function(state) - _save_state(nil) + _save_projects(nil) if state.notify.enable then local message = "All projects deleted" @@ -273,7 +273,7 @@ local delete_project = ya.sync(function(state, idx) local message = string.format([["%s" deleted]], tostring(projects.list[idx].desc)) table.remove(projects.list, idx) - _save_state(projects) + _save_projects(projects) if state.notify.enable then _notify(message) @@ -284,11 +284,60 @@ local save_last_and_quit = ya.sync(function(state) local projects = _get_projects() projects.last = _get_current_project() - _save_state(projects) + _save_projects(projects) ya.manager_emit("quit", {}) end) +local merge_project = ya.sync(function(state, opt) + local project = _get_current_project() + project.opt = opt or "all" + ps.pub_to(0, "projects-merge", project) + + if state.merge.quit_after_merge then + ya.manager_emit("quit", {}) + end +end) + +local _merge_tab = ya.sync(function(state, tab) + ya.manager_emit("tab_create", { tab.cwd }) +end) + +local _merge_event = ya.sync(function(state) + ps.sub_remote("projects-merge", function(body) + if body then + local active_idx = tonumber(cx.tabs.idx) + + local opt = body.opt + if opt == "all" then + local sorted_tabs = {} + for _, tab in pairs(body.tabs) do + sorted_tabs[tonumber(tab.idx)] = tab + end + + for _, tab in ipairs(sorted_tabs) do + _merge_tab(tab) + end + + if state.notify.enable then + local message = "A project is merged" + _notify(message) + end + elseif opt == "current" then + local tab = body.tabs[tostring(body.active_idx)] + _merge_tab(tab) + + if state.notify.enable then + local message = "A tab is merged" + _notify(message) + end + end + + ya.manager_emit("tab_switch", { active_idx - 1 }) + end + end) +end) + return { entry = function(_, args) local action = args[1] @@ -306,6 +355,12 @@ return { return end + if action == "merge" then + local opt = args[2] + merge_project(opt) + return + end + local projects = _get_projects() if action == "load_last" then @@ -386,6 +441,15 @@ return { end end + state.merge = { + quit_after_merge = false, + } + if type(args.merge) == "table" then + if type(args.merge.quit_after_merge) == "boolean" then + state.merge.quit_after_merge = args.merge.quit_after_merge + end + end + state.notify = { enable = true, title = "Projects", @@ -407,6 +471,7 @@ return { end end - _load_state() + _load_projects() + _merge_event() end, }