Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

on_choice trigger and some in-place remodelling. #49

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 33 additions & 39 deletions lua/scratch/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ local MANUAL_INPUT_OPTION = "MANUAL_INPUT"
---@class Scratch.ActionOpts
---@field window_cmd? Scratch.WindowCmd
---@field content? string[] content will be put into the scratch file
---@field hooks? table<Scratch.Trigger, Scratch.Hook|table<string, Scratch.Hook>>
---{[string]: Scratch.Hooks, [Scratch.Trigger]:Scratch.Hook}

---@param abs_path string
---@param opts? Scratch.ActionOpts
Expand All @@ -26,9 +28,9 @@ local function create_and_edit_file(abs_path, opts)
vim.api.nvim_command(cmd .. " " .. abs_path)
end

local hooks = Hooks.get_hooks(vim.g.scratch_config.hooks, Hooks.trigger_points.AFTER)
for _, hook in ipairs(hooks) do
hook.callback()
local hooks = vim.g.scratch_config.hooks[Hooks.trigger_points.AFTER]
for i = 1, #hooks do
hooks[i]()
end
end

Expand Down Expand Up @@ -123,27 +125,27 @@ local function get_all_filetypes()
return combined_filetypes
end

---@param func Scratch.Action
---@param func function
---@param opts? Scratch.ActionOpts
local function select_filetype_then_do(func, opts)
local filetypes = get_all_filetypes()

vim.ui.select(filetypes, {
prompt = "Select filetype",
format_item = function(item)
return item
end,
}, function(choosedFt)
if choosedFt then
if choosedFt == MANUAL_INPUT_OPTION then
vim.ui.input({ prompt = "Input filetype: " }, function(ft)
func(ft, opts)
end)
coroutine.wrap(function()
local filetypes = get_all_filetypes()
if opts and opts.hooks then
local choosedFt = opts.hooks[Hooks.trigger_points.PRE_CHOICE](filetypes)

if
opts.hooks[Hooks.trigger_points.POST_CHOICE]
and opts.hooks[Hooks.trigger_points.POST_CHOICE][choosedFt]
then
---@see: https://github.com/mfussenegger/nvim-dap/blob/7ff6936010b7222fea2caea0f67ed77f1b7c60dd/lua/dap/session.lua#L1582C3-L1607C9
---NOTICE: `ui.pick_one(..)` realisation
local ft = opts.hooks[Hooks.trigger_points.POST_CHOICE][choosedFt]()
func(ft, opts)
else
func(choosedFt, opts)
end
end
end)
end)()
end

local function get_scratch_files()
Expand Down Expand Up @@ -206,41 +208,33 @@ local function open_scratch_telescope()
end,
})
end
---@param opts Scratch.ActionOpts
local function open_scratch_vim_ui(opts)
coroutine.wrap(function()
local files = get_scratch_files()
local config_data = vim.g.scratch_config

local function open_scratch_vim_ui()
local files = get_scratch_files()
local config_data = vim.g.scratch_config

local scratch_file_dir = config_data.scratch_file_dir

-- sort the files by their last modified time in descending order
table.sort(files, function(a, b)
return vim.fn.getftime(scratch_file_dir .. slash .. a)
> vim.fn.getftime(scratch_file_dir .. slash .. b)
end)

vim.ui.select(files, {
prompt = "Select old scratch files",
format_item = function(item)
return item
end,
}, function(chosenFile)
local scratch_file_dir = config_data.scratch_file_dir
local chosenFile = opts.hooks[Hooks.trigger_points.PRE_OPEN]({ files, scratch_file_dir })
if opts.hooks[Hooks.trigger_points.POST_OPEN] then
opts.hooks[Hooks.trigger_points.POST_OPEN].callback(chosenFile)
end
if chosenFile then
create_and_edit_file(scratch_file_dir .. slash .. chosenFile)
register_local_key()
end
end)
end)()
end

local function openScratch()
local function openScratch(opts)
local config_data = vim.g.scratch_config

if config_data.file_picker == "telescope" then
open_scratch_telescope()
elseif config_data.file_picker == "fzflua" then
open_scratch_fzflua()
else
open_scratch_vim_ui()
open_scratch_vim_ui(opts)
end
end

Expand Down
59 changes: 56 additions & 3 deletions lua/scratch/config.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local slash = require("scratch.utils").Slash()
local utils = require("scratch.utils")
local triger = require("scratch.hooks").trigger_points

---@alias mode
---| '"n"'
Expand Down Expand Up @@ -32,6 +33,7 @@ local utils = require("scratch.utils")
---@field subdir? string
---@field content? string[]
---@field cursor? Scratch.Cursor
---@field hooks? table<Scratch.Trigger,Scratch.Hook>
--
---@class Scratch.FiletypeDetails
---@field [string] Scratch.FiletypeDetail
Expand All @@ -46,12 +48,63 @@ local utils = require("scratch.utils")
---@field hooks Scratch.Hook[]
local default_config = {
scratch_file_dir = vim.fn.stdpath("cache") .. slash .. "scratch.nvim", -- where your scratch files will be put
filetypes = { "lua", "js", "py", "sh" }, -- you can simply put filetype here
filetypes = { "lua", "js", "py", "sh", "MANUAL_INPUT" }, -- you can simply put filetype here
window_cmd = "edit", -- 'vsplit' | 'split' | 'edit' | 'tabedit' | 'rightbelow vsplit'
file_picker = "fzflua",
filetype_details = {},
filetype_details = {
["MANUAL_INPUT"] = {
hooks = {
---@see: https://github.com/mfussenegger/nvim-dap/blob/66d33b7585b42b7eac20559f1551524287ded353/lua/dap/ui.lua#L55
[triger.POST_CHOICE] = function()
local co = coroutine.running()
local confirmer = function(input)
coroutine.resume(co, input)
end
confirmer = vim.schedule_wrap(confirmer)
vim.ui.input({ prompt = "Input filetype: " }, confirmer)
return coroutine.yield()
end,
},
},
},
localKeys = {},
hooks = {},
hooks = {
[triger.PRE_CHOICE] = {
function(filetypes)
local co = coroutine.running()
vim.ui.select(filetypes, {
prompt = "Select filetype",
format_item = function(item)
return item
end,
}, function(choosedFt)
coroutine.resume(co, choosedFt)
end)
return coroutine.yield()
end,
},
[triger.PRE_OPEN] = {
function(opts)
local files, scratch_file_dir = opts.files, opts.scratch_file_dir
local co = coroutine.running()

-- sort the files by their last modified time in descending order
table.sort(files, function(a, b)
return vim.fn.getftime(scratch_file_dir .. slash .. a)
> vim.fn.getftime(scratch_file_dir .. slash .. b)
end)
vim.ui.select(files, {
prompt = "Select old scratch files",
format_item = function(item)
return item
end,
}, function(chosenFile)
coroutine.resume(co, chosenFile)
end)
return coroutine.yield()
end,
},
},
}

---@type Scratch.Config
Expand Down
49 changes: 23 additions & 26 deletions lua/scratch/hooks.lua
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
local M = {}

---@class Scratch.Hook
---@field callback fun(param: table?)
---@field name? string
---@field trigger_point? string

---@enum Scratch.Trigger
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

M.trigger_points = {
AFTER = "AFTER",
AFTER = 1,
PRE_CHOICE = 2,
POST_CHOICE = 3,
PRE_OPEN = 4,
POST_OPEN = 5,
}
---@alias Scratch.Hooks table<Scratch.Trigger, Scratch.Hook[]>
---TODO: specify `fun` type per hook
---@alias Scratch.Hook fun(param:table?)

---@param hooks Scratch.Hook[]
---@param target_trigger_point? string
---@return Scratch.Hook[]
M.get_hooks = function(hooks, target_trigger_point)
local matching_hooks = {}
for _, hook in ipairs(hooks) do
local matches = false
local trigger_point = hook.trigger_point or M.trigger_points.AFTER

if trigger_point == target_trigger_point then
matches = true
end

if matches then
table.insert(matching_hooks, hook)
end
end
return matching_hooks
end
-- ---@param hooks Scratch.Hook[]
-- ---@param target_trigger_point? string
-- ---@return Scratch.Hook[]
-- M.get_hooks = function(hooks, target_trigger_point)
-- local matching_hooks = {} ---@type Scratch.Hook[]
-- for i = 1, #hooks do
-- local trigger_point = hooks[i].trigger_point or M.trigger_points.AFTER
--
-- if trigger_point == target_trigger_point then
-- table.insert(matching_hooks, hooks[i])
-- end
-- end
-- return matching_hooks
-- end

return M