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

Refactor. Maybe something from that will be helpful #42

Closed
wants to merge 43 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b62aaf7
refactor(utils): replace slash to constant, normalize module
AgatZan Sep 1, 2024
4acb0bb
fix(utils): depracated api_nvim_get_option
AgatZan Sep 1, 2024
5a7d13d
refactor(utils): using API instead get_option
AgatZan Sep 1, 2024
2f5d311
refactor(utils): comment lenght(#is default table len), simplify cont…
AgatZan Sep 1, 2024
752d57e
refactor(utils): scandir using luav
AgatZan Sep 1, 2024
98c7778
refactor!: remove vim.g.scratch think about plugin/
AgatZan Sep 1, 2024
4d840d4
revert(global)
AgatZan Sep 1, 2024
727d9a7
fix(utils): remove initDir
AgatZan Sep 1, 2024
facb472
refactor(init): remove vim.g
AgatZan Sep 2, 2024
bb1264b
fix(actor): self.manual_text
AgatZan Sep 2, 2024
a38b49f
fix(api): create using api
AgatZan Sep 3, 2024
1cd36eb
fix(type): compare with exist |\n feat(window): window_cmd -> window_…
AgatZan Sep 3, 2024
ce833e3
refactor! + feat(input,selector)
AgatZan Sep 3, 2024
8be1031
clenup
AgatZan Sep 3, 2024
6ae4390
refactor!, feat(input, select)!
AgatZan Sep 3, 2024
acbf979
fix(actor): miss self
AgatZan Sep 4, 2024
c018570
fix(actor): `scratchByType` miss filename generator name
AgatZan Sep 4, 2024
a04d0b9
fix(actor): `scratchByName` create all subdir
AgatZan Sep 4, 2024
e7e18c6
refactor(actor): beautify condition at scratchBy*
AgatZan Sep 4, 2024
1bec735
refactor(utils): one time get filename
AgatZan Sep 4, 2024
2b68c50
fix(default, types, bugs): default command
AgatZan Sep 6, 2024
36f7652
revert(type): base_dir -> scratch_file_dir,\nfeat(config): filetype_d…
AgatZan Sep 6, 2024
039765a
chore(type): add missed type anotation in `utils.gen_file_path`
AgatZan Sep 6, 2024
c7f6492
fix(utils): open exist file in buffer error
AgatZan Sep 6, 2024
356e87f
Revert "fix(utils): open exist file in buffer error"
AgatZan Sep 6, 2024
c773e9b
fix(actor): all scratch* func with now use opts.arg.
AgatZan Sep 7, 2024
8ed8acc
fix(cmd): correct with current api
AgatZan Sep 7, 2024
f7da5be
fix(utils): scandir \\(now \) before filename
AgatZan Sep 7, 2024
77e8b7f
refactor(config): now default cmd in setup
AgatZan Sep 7, 2024
a0866dc
refactor(api): now api-way actor-way
AgatZan Sep 7, 2024
d7c94e4
fix(config): error with vim.g
AgatZan Sep 7, 2024
bbd6741
fix(config): dumb way but work
AgatZan Sep 7, 2024
7395b8b
refactor(config): remove duplicate in `init.lua`
AgatZan Sep 7, 2024
a3cfb44
refactor(config): remove `plugin/`
AgatZan Sep 7, 2024
5ac8b30
refactor(config): remove log
AgatZan Sep 7, 2024
3b5045d
fix(type): Scratch.ActorConfig now optional
AgatZan Sep 7, 2024
45915ac
refactor(config): move default setup to `plugin/` move default confi…
AgatZan Sep 8, 2024
05eab84
feat-draft(perf): compilation file-finder
AgatZan Sep 8, 2024
b21b0c6
fix(utils):put_cursor not found fix
AgatZan Sep 9, 2024
fa67cfa
fix!: only actor
AgatZan Oct 10, 2024
bd27d16
fix(config): return default `win_cwd` and `file_picker` option at config
AgatZan Oct 10, 2024
36e8fe9
fix(settup): getSelectedText() now work correct
AgatZan Oct 16, 2024
bd21b33
fix(init): get_selected text problem
AgatZan Oct 20, 2024
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
130 changes: 130 additions & 0 deletions lua/scratch/actor.lua
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)
Copy link
Contributor Author

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 or utils.lua in order to separate OOP and proc at every that looks func.

local abs_path = self.base_dir .. filename
local fto = {}
for i in filename:gmatch("([^%.]+)") do
Copy link
Contributor Author

Choose a reason for hiding this comment

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

string.split by separator (in this place it ".")

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 = {}
Copy link
Contributor Author

@AgatZan AgatZan Sep 3, 2024

Choose a reason for hiding this comment

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

Instead of sneaking through all combined_filetypes each time we append an item, just caching with ~O(1)

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)()
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 vim.ui or something else, I don't know a better way.

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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
94 changes: 94 additions & 0 deletions lua/scratch/default_finder.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
local M = {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
49 changes: 49 additions & 0 deletions lua/scratch/default_providers.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
local utils = require("scratch.utils")
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
48 changes: 48 additions & 0 deletions lua/scratch/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
local M = {}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

actor.lua can be placed here without any problems.


---@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
39 changes: 39 additions & 0 deletions lua/scratch/telescope_actions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
local M = {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 })
Copy link
Contributor Author

@AgatZan AgatZan Sep 3, 2024

Choose a reason for hiding this comment

The 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
Loading