-
Notifications
You must be signed in to change notification settings - Fork 10
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
Refactor. Maybe something from that will be helpful #42
Changes from 1 commit
b62aaf7
4acb0bb
5a7d13d
2f5d311
752d57e
98c7778
4d840d4
727d9a7
facb472
bb1264b
a38b49f
1cd36eb
ce833e3
8be1031
6ae4390
acbf979
c018570
a04d0b9
e7e18c6
1bec735
2b68c50
36f7652
039765a
c7f6492
356e87f
c773e9b
8ed8acc
f7da5be
77e8b7f
a0866dc
d7c94e4
bbd6741
7395b8b
a3cfb44
5ac8b30
3b5045d
45915ac
05eab84
b21b0c6
fa67cfa
bd27d16
36e8fe9
bd21b33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
local utils = require("scratch.utils") | ||
-- local MANUAL_INPUT_OPTION = "MANUAL_INPUT" | ||
|
||
---@class Scratch.Actor | ||
---@field base_dir string | ||
---@field win_config vim.api.keyset.win_config @see: nvim_open_win() {config} | ||
---@field filetypes string[] | ||
---@field manual_text string | ||
---@field file_picker? "fzflua" | "telescope" | ||
---@field filetype_details Scratch.FiletypeDetails | ||
---@field localKeys Scratch.LocalKeyConfig[] | ||
local M = {} | ||
|
||
---@class Scratch.ActionOpts | ||
---@field content? string[] content will be put into the scratch file | ||
|
||
---@alias Scratch.Action fun(ft: string, opts?: Scratch.ActionOpts): nil | ||
|
||
---@param filename string | ||
---@param win_conf? vim.api.keyset.win_config | ||
---@param content? string[] | ||
---@param local_keys? Scratch.LocalKeyConfig | ||
---@param cursor? Scratch.Cursor | ||
function M:scratchByName(filename, win_conf, content, local_keys, cursor) | ||
local abs_path = self.base_dir .. filename | ||
local fto = {} | ||
for i in filename:gmatch("([^%.]+)") do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
table.insert(fto, i) | ||
end | ||
local ft = fto[#fto] | ||
content = content or self.filetype_details[ft] and self.filetype_details[ft].content | ||
cursor = cursor or self.filetype_details[ft] and self.filetype_details[ft].cursor | ||
utils.scratch(abs_path, win_conf or self.win_config, content, local_keys, cursor) | ||
end | ||
|
||
---@param ft string | ||
---@param win_conf? vim.api.keyset.win_config | ||
---@param content? string[] | ||
function M:scratchByType(ft, win_conf, content, local_keys, cursor) | ||
local abs_path = self.base_dir .. utils.gen_filename(ft) | ||
content = content or self.filetype_details[ft] and self.filetype_details[ft].content | ||
cursor = cursor or self.filetype_details[ft] and self.filetype_details[ft].cursor | ||
utils.scratch(abs_path, win_conf or self.win_config, content, local_keys, cursor) | ||
end | ||
|
||
---@return string[] | ||
function M:get_all_filetypes() | ||
local combined_filetypes = {} | ||
local cash = {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of sneaking through all |
||
for _, ft in ipairs(self.filetypes or {}) do | ||
if not cash[ft] then | ||
table.insert(combined_filetypes, ft) | ||
cash[ft] = 1 | ||
end | ||
end | ||
for ft, _ in pairs(self.filetype_details or {}) do | ||
if not cash[ft] then | ||
table.insert(combined_filetypes, ft) | ||
cash[ft] = 1 | ||
end | ||
end | ||
|
||
table.insert(combined_filetypes, self.manual_text) | ||
return combined_filetypes | ||
end | ||
|
||
function M.get_scratch_files(base_dir) | ||
local scratch_file_dir = base_dir | ||
local res = {} | ||
res = utils.scandir(scratch_file_dir) | ||
for i, str in ipairs(res) do | ||
res[i] = string.sub(str, #scratch_file_dir + 2) | ||
end | ||
return res | ||
end | ||
|
||
---choose ft by using selector function | ||
---@param selector_filetype fun(filetypes:string[]):string think about last element like about MANUAL or like u prefers | ||
---@param win_conf? vim.api.keyset.win_config | ||
---@param content? string[] | ||
---@param local_keys? Scratch.LocalKeyConfig | ||
---@param cursor? Scratch.Cursor | ||
function M:scratchWithSelectorFT(selector_filetype, win_conf, content, local_keys, cursor) | ||
local filetypes = M:get_all_filetypes() | ||
coroutine.wrap(function() | ||
local ft = selector_filetype(filetypes) | ||
self:scratchByType(ft, win_conf, content, local_keys, cursor) | ||
end)() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inspired by https://github.com/mfussenegger/nvim-dap/blob/66d33b7585b42b7eac20559f1551524287ded353/lua/dap/ui.lua#L55 For situations like |
||
end | ||
|
||
---choose ft by using selector function | ||
---@param input_filename fun():string input filename | ||
---@param win_conf? vim.api.keyset.win_config | ||
---@param content? string[] | ||
---@param local_keys? Scratch.LocalKeyConfig | ||
---@param cursor? Scratch.Cursor | ||
function M:scratchWithInputFN(input_filename, win_conf, content, local_keys, cursor) | ||
coroutine.wrap(function() | ||
local filename = input_filename() | ||
self:scratchByName(filename, win_conf, content, local_keys, cursor) | ||
end)() | ||
end | ||
|
||
---simple input name | ||
---@param win_conf? vim.api.keyset.win_config | ||
---@param content? string[] | ||
---@param local_keys? Scratch.LocalKeyConfig | ||
---@param cursor? Scratch.Cursor | ||
function M:scratchWithName(win_conf, content, local_keys, cursor) | ||
vim.ui.input({ | ||
prompt = "Enter the file name: ", | ||
}, function(filename) | ||
if filename ~= nil and filename ~= "" then | ||
return self:scratchByName(filename, win_conf, content, local_keys, cursor) | ||
end | ||
vim.notify("No file") | ||
end) | ||
end | ||
|
||
-- ---@param opts Scratch.LocalKey[] | ||
-- function M:scratchOpen(opts) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's useless to set up some built-ins this way. If a user wants to use one of them, he must call one of them. And specify these way it's to sign to update this every time u add. In a good way, it would be nice to just give a draft of what to look like without passing unnecessary openers. |
||
-- if self.file_picker == "telescope" then | ||
-- self:open_scratch_telescope(opts) | ||
-- elseif self.file_picker == "fzflua" then | ||
-- self:open_scratch_fzflua() | ||
-- else | ||
-- self:open_scratch_vim_ui() | ||
-- end | ||
-- end | ||
return M |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
local M = {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of this is unnecessary, so it can be commented and put in the doc. |
||
|
||
---@param base_dir string path to scandir | ||
---@param sorter? fun(file_a:string, file_b:string):boolean @see: table.sort | ||
---@param win_conf? vim.api.keyset.win_config | ||
---@param local_keys? Scratch.LocalKeyConfig | ||
function M.findByNative(base_dir, sorter, win_conf, local_keys) | ||
local utils = require("scratch.utils") | ||
local scratch_file_dir = base_dir | ||
local abs_filenames = utils.scandir(scratch_file_dir) | ||
if sorter then | ||
table.sort(abs_filenames, sorter) | ||
end | ||
-- sort the files by their last modified time in descending order | ||
-- Why? | ||
-- table.sort(files, function(a, b) | ||
-- return vim.fn.getftime(scratch_file_dir .. vim.g.os_sep .. a) | ||
-- > vim.fn.getftime(scratch_file_dir .. vim.g.os_sep .. b) | ||
-- end) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The user can want to specify their own comparator or even not sort. |
||
|
||
vim.ui.select(abs_filenames, { | ||
prompt = "Select old scratch files", | ||
format_item = function(item) | ||
return item | ||
end, | ||
}, function(chosenFile) | ||
if chosenFile then | ||
utils.open_(chosenFile, win_conf) | ||
if local_keys then | ||
utils.register_local_key(local_keys) | ||
end | ||
end | ||
end) | ||
end | ||
|
||
---@param base_dir string path to scandir | ||
function M.findByFzf(base_dir) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't use it. So I don't know how it works. |
||
local ok, fzf_lua = pcall(require, "fzf-lua") | ||
if not ok then | ||
return vim.notify( | ||
"Can't find fzf-lua, please check your configuration", | ||
vim.log.levels.ERROR, | ||
{ title = "scratch.nvim" } | ||
) | ||
end | ||
|
||
if vim.fn.executable("rg") ~= 1 then | ||
return vim.notify( | ||
"Can't find fzf-lua, please check your configuration", | ||
vim.log.levels.ERROR, | ||
{ title = "scratch.nvim" } | ||
) | ||
end | ||
fzf_lua.files({ cmd = "rg --files --sortr modified " .. base_dir }) | ||
end | ||
|
||
---@param base_dir string path to scandir | ||
---@param local_keys Scratch.LocalKey[] | ||
function M.findByTelescope(base_dir, local_keys) | ||
local telescope_status, telescope_builtin = pcall(require, "telescope.builtin") | ||
if not telescope_status then | ||
vim.notify( | ||
'ScrachOpen needs telescope.nvim or you can just add `"use_telescope: false"` into your config file ot use native select ui' | ||
) | ||
return | ||
end | ||
|
||
telescope_builtin.find_files({ | ||
cwd = base_dir, | ||
attach_mappings = function(prompt_bufnr, map) | ||
map("n", "dd", function() | ||
require("scratch.telescope_actions").delete_item(prompt_bufnr) | ||
end) | ||
-- TODO: user can customise keybinding | ||
for _, key in ipairs(local_keys) do | ||
map(key.modes, key.key, key.cmd) | ||
end | ||
return true | ||
end, | ||
}) | ||
end | ||
|
||
---@param base_dir string | ||
function M.findByTelescopeGrep(base_dir) | ||
local telescope_status, telescope_builtin = pcall(require, "telescope.builtin") | ||
if not telescope_status then | ||
return vim.notify("ScrachOpenFzf needs telescope.nvim") | ||
end | ||
telescope_builtin.live_grep({ | ||
cwd = base_dir, | ||
}) | ||
end | ||
|
||
return M |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
local utils = require("scratch.utils") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same like default_finder |
||
local M = {} | ||
|
||
--- NOTE: if u want using async choicer inside your own functions with non ( :h api-fast ) | ||
--- wrap these choicer into vim.schedule_wrap | ||
--- dummy async | ||
--- @example | ||
--- function M.dummy(args) | ||
--- local co = coroutine.running() | ||
--- local choicer = function() | ||
--- -- instead return use coroutine.resume(co, your_return) | ||
--- end | ||
--- return coroutine.yield() | ||
--- end | ||
|
||
function M.vim_ui_selector(filetypes) | ||
local co = coroutine.running() | ||
vim.ui.select(filetypes, { | ||
prompt = "Select filetype", | ||
format_item = function(item) | ||
return item | ||
end, | ||
}, function(choosedFt) | ||
if choosedFt then | ||
if choosedFt == filetypes[#filetypes] then | ||
vim.ui.input({ prompt = "Input filetype: " }, function(ft) | ||
coroutine.resume(co, ft) | ||
end) | ||
else | ||
coroutine.resume(co, choosedFt) | ||
end | ||
end | ||
end) | ||
return coroutine.yield() | ||
end | ||
function M.vim_ui_input() | ||
local co = coroutine.running() | ||
vim.ui.input({ | ||
prompt = "Enter the file name: ", | ||
}, function(filename) | ||
if filename ~= nil and filename ~= "" then | ||
coroutine.resume(co, filename) | ||
else | ||
vim.notify("No file") | ||
end | ||
end) | ||
return coroutine.yield() | ||
end | ||
return M |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
local M = {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
---@alias mode | ||
---| '"n"' | ||
---| '"i"' | ||
---| '"v"' | ||
--- | ||
|
||
---@class Scratch.LocalKey | ||
---@field cmd string | ||
---@field key string | ||
---@field modes mode[] | ||
|
||
---@class Scratch.LocalKeyConfig | ||
---@field filenameContains string[] as long as the filename contains any one of the string in the list | ||
---@field LocalKeys Scratch.LocalKey[] | ||
-- | ||
---@class Scratch.Cursor | ||
---@field location number[] | ||
---@field insert_mode boolean | ||
|
||
---@class Scratch.FiletypeDetail | ||
---@field content? string[] | ||
---@field cursor? Scratch.Cursor | ||
-- | ||
---@alias Scratch.FiletypeDetails { [string]:Scratch.FiletypeDetail } | ||
|
||
---@class Scratch.Config | ||
---@field base_dir? string | ||
---@field filetypes? string[] | ||
---@field window? vim.api.keyset.win_config @see nvim_open_window | ||
---@field file_picker? "fzflua" | "telescope" | ||
---@field filetype_details? Scratch.FiletypeDetails | ||
---@field localKeys? Scratch.LocalKeyConfig[] | ||
---@field manual_text? string | ||
|
||
---@param user_config? Scratch.Config | ||
---@return Scratch.Actor | ||
function M.setup(user_config) | ||
user_config = user_config or {} | ||
if user_config.base_dir and not vim.uv.fs_stat(user_config.base_dir).type == "directory" then | ||
vim.uv.fs_mkdir(user_config.base_dir, 666) | ||
end | ||
vim.g.scratch_actor = vim.tbl_deep_extend("force", vim.g.scratch_actor, user_config) | ||
return vim.g.scratch_actor | ||
end | ||
|
||
return M |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
local M = {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't change this it's. My fault and git skill issue |
||
|
||
local action_state = require("telescope.actions.state") | ||
local Path = require("plenary").path | ||
local config = require("scratch.config") | ||
|
||
-- TODO: register buffer local key | ||
function M.delete_item(prompt_bufnr) | ||
local _delelte = function(p) | ||
local flag = false | ||
while p:exists() do | ||
local f = os.remove(p.filename) | ||
if f then | ||
flag = true | ||
vim.notify("delete " .. p.filename) | ||
else | ||
break | ||
end | ||
p = p:parent() | ||
end | ||
return flag | ||
end | ||
|
||
local picker = action_state.get_current_picker(prompt_bufnr) | ||
picker:delete_selection(function(s) | ||
local file_name = s[1] | ||
-- INFO: currently just protect configFilePath from being removed | ||
if file_name == "configFilePath" then | ||
vim.notify("[scratch.nvim] configFilePath cannot be removed", vim.log.levels.WARN) | ||
return false | ||
end | ||
local config_data = config.getConfig() | ||
local scratch_file_dir = config_data.base_dir | ||
local p = Path:new({ scratch_file_dir, file_name, sep = vim.g.os_sep }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think `vim.g.os_sep' is the best way of doing that. I don't know why it is not std const. It can be found in so many ways, but why do even all people need to create a bicycle? Thinking out loud. |
||
return _delelte(p) | ||
end) | ||
end | ||
|
||
return M |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to double this to something like
api.lua
orutils.lua
in order to separate OOP and proc at every that looks func.